From 63a2752c56ce0d2619931aa7ba59e1b1753e0456 Mon Sep 17 00:00:00 2001 From: Eduard Urbach Date: Fri, 7 Feb 2025 16:26:24 +0100 Subject: [PATCH] Implemented struct size calculation after a scan --- src/compiler/Compile.go | 11 +++++++++++ src/scanner/scanStruct.go | 17 +---------------- src/types/Base.go | 17 +++++++++++++++++ src/types/Field.go | 3 ++- src/types/Float.go | 4 ++-- src/types/Int.go | 8 ++++---- src/types/Struct.go | 12 +++++++++++- 7 files changed, 48 insertions(+), 24 deletions(-) create mode 100644 src/types/Base.go diff --git a/src/compiler/Compile.go b/src/compiler/Compile.go index ca3ef28..328c9f2 100644 --- a/src/compiler/Compile.go +++ b/src/compiler/Compile.go @@ -65,6 +65,17 @@ func Compile(files <-chan *fs.File, functions <-chan *core.Function, structs <-c } } + // Calculate size of structs + for _, typ := range allTypes { + structure, isStruct := typ.(*types.Struct) + + if !isStruct { + continue + } + + structure.Update(allTypes) + } + // Resolve the types for _, function := range allFunctions { err := function.ResolveTypes() diff --git a/src/scanner/scanStruct.go b/src/scanner/scanStruct.go index 3f9e74d..d5fe98f 100644 --- a/src/scanner/scanStruct.go +++ b/src/scanner/scanStruct.go @@ -33,27 +33,12 @@ func (s *Scanner) scanStruct(file *fs.File, tokens token.List, i int) (int, erro fieldName := tokens[i].Text(file.Bytes) i++ fieldTypeName := tokens[i].Text(file.Bytes) - fieldType := types.Int - - switch fieldTypeName { - case "Int", "Int64": - case "Int32": - fieldType = types.Int32 - case "Int16": - fieldType = types.Int16 - case "Int8": - fieldType = types.Int8 - default: - panic("not implemented") - } - i++ structure.AddField(&types.Field{ - Type: fieldType, Name: fieldName, + TypeName: fieldTypeName, Position: token.Position(fieldPosition), - Offset: structure.Size(), }) } diff --git a/src/types/Base.go b/src/types/Base.go new file mode 100644 index 0000000..fb9e4c8 --- /dev/null +++ b/src/types/Base.go @@ -0,0 +1,17 @@ +package types + +// Base is used to describe basic types like integers and floats. +type Base struct { + name string + size int +} + +// Name returns the name of the type. +func (s *Base) Name() string { + return s.name +} + +// Size returns the total size in bytes. +func (s *Base) Size() int { + return s.size +} diff --git a/src/types/Field.go b/src/types/Field.go index e486878..c8d4fce 100644 --- a/src/types/Field.go +++ b/src/types/Field.go @@ -4,8 +4,9 @@ import "git.akyoto.dev/cli/q/src/token" // Field is a memory region in a data structure. type Field struct { - Type Type Name string + Type Type + TypeName string Position token.Position Offset int } diff --git a/src/types/Float.go b/src/types/Float.go index 1fedd30..cbfc638 100644 --- a/src/types/Float.go +++ b/src/types/Float.go @@ -1,7 +1,7 @@ package types var ( - Float64 = &Struct{name: "Float64", size: 8} - Float32 = &Struct{name: "Float32", size: 4} + Float64 = &Base{name: "Float64", size: 8} + Float32 = &Base{name: "Float32", size: 4} Float = Float64 ) diff --git a/src/types/Int.go b/src/types/Int.go index 73fa22c..f07d7c6 100644 --- a/src/types/Int.go +++ b/src/types/Int.go @@ -1,9 +1,9 @@ package types var ( - Int64 = &Struct{name: "Int64", size: 8} - Int32 = &Struct{name: "Int32", size: 4} - Int16 = &Struct{name: "Int16", size: 2} - Int8 = &Struct{name: "Int8", size: 1} + Int64 = &Base{name: "Int64", size: 8} + Int32 = &Base{name: "Int32", size: 4} + Int16 = &Base{name: "Int16", size: 2} + Int8 = &Base{name: "Int8", size: 1} Int = Int64 ) diff --git a/src/types/Struct.go b/src/types/Struct.go index 1e80517..ac3d20e 100644 --- a/src/types/Struct.go +++ b/src/types/Struct.go @@ -15,7 +15,6 @@ func NewStruct(name string) *Struct { // AddField adds a new field to the end of the struct. func (s *Struct) AddField(field *Field) { s.fields = append(s.fields, field) - s.size += field.Type.Size() } // FieldByName returns the field with the given name if it exists. @@ -38,3 +37,14 @@ func (s *Struct) Name() string { func (s *Struct) Size() int { return s.size } + +// Update updates the offsets and structure size. +func (s *Struct) Update(types map[string]Type) { + s.size = 0 + + for _, field := range s.fields { + field.Type = types[field.TypeName] + field.Offset = s.size + s.size += field.Type.Size() + } +}