From 91e01de3ad3e65bb93090204f4c6fb826306673c Mon Sep 17 00:00:00 2001 From: Eduard Urbach Date: Fri, 21 Feb 2025 17:35:42 +0100 Subject: [PATCH] Implemented environment type --- src/asmc/compiler.go | 4 ++-- src/compiler/Compile.go | 41 ++++++++++++++++++------------------ src/compiler/Result.go | 4 ++-- src/core/CompileCall.go | 2 +- src/core/CompileDelete.go | 2 +- src/core/CompileNew.go | 4 ++-- src/core/Constant.go | 2 +- src/core/CreateLabel.go | 4 ++-- src/core/Environment.go | 14 ++++++++++++ src/core/Fold.go | 2 +- src/core/Function.go | 16 ++------------ src/core/Identifier.go | 2 +- src/core/PeriodToRegister.go | 4 ++-- src/core/ResolveTypes.go | 4 ++-- src/core/count.go | 13 ++++++++++++ 15 files changed, 67 insertions(+), 51 deletions(-) create mode 100644 src/core/Environment.go create mode 100644 src/core/count.go diff --git a/src/asmc/compiler.go b/src/asmc/compiler.go index 0847707..fd17c89 100644 --- a/src/asmc/compiler.go +++ b/src/asmc/compiler.go @@ -9,7 +9,7 @@ type compiler struct { dataLabels map[string]Address codePointers []*pointer dataPointers []*pointer - codeStart Address - dlls dll.List dllPointers []*pointer + dlls dll.List + codeStart Address } diff --git a/src/compiler/Compile.go b/src/compiler/Compile.go index 749b71b..cc56464 100644 --- a/src/compiler/Compile.go +++ b/src/compiler/Compile.go @@ -9,11 +9,14 @@ import ( // Compile waits for the scan to finish and compiles all functions. func Compile(constants <-chan *core.Constant, files <-chan *fs.File, functions <-chan *core.Function, structs <-chan *types.Struct, errs <-chan error) (Result, error) { + all := core.Environment{ + Files: make([]*fs.File, 0, 8), + Functions: make(map[string]*core.Function, 32), + Structs: make(map[string]*types.Struct, 8), + Constants: make(map[string]*core.Constant, 8), + } + result := Result{} - allFiles := make([]*fs.File, 0, 8) - allFunctions := make(map[string]*core.Function, 32) - allStructs := make(map[string]*types.Struct, 8) - allConstants := make(map[string]*core.Constant, 8) for constants != nil || files != nil || functions != nil || structs != nil || errs != nil { select { @@ -23,10 +26,8 @@ func Compile(constants <-chan *core.Constant, files <-chan *fs.File, functions < continue } - function.Functions = allFunctions - function.Structs = allStructs - function.Constants = allConstants - allFunctions[function.UniqueName] = function + function.All = &all + all.Functions[function.UniqueName] = function case structure, ok := <-structs: if !ok { @@ -34,7 +35,7 @@ func Compile(constants <-chan *core.Constant, files <-chan *fs.File, functions < continue } - allStructs[structure.UniqueName] = structure + all.Structs[structure.UniqueName] = structure case file, ok := <-files: if !ok { @@ -42,7 +43,7 @@ func Compile(constants <-chan *core.Constant, files <-chan *fs.File, functions < continue } - allFiles = append(allFiles, file) + all.Files = append(all.Files, file) case constant, ok := <-constants: if !ok { @@ -50,7 +51,7 @@ func Compile(constants <-chan *core.Constant, files <-chan *fs.File, functions < continue } - allConstants[constant.Name] = constant + all.Constants[constant.Name] = constant case err, ok := <-errs: if !ok { @@ -63,12 +64,12 @@ func Compile(constants <-chan *core.Constant, files <-chan *fs.File, functions < } // Calculate size of structs - for _, structure := range allStructs { - structure.Update(allStructs) + for _, structure := range all.Structs { + structure.Update(all.Structs) } // Resolve the types - for _, function := range allFunctions { + for _, function := range all.Functions { err := function.ResolveTypes() if err != nil { @@ -77,10 +78,10 @@ func Compile(constants <-chan *core.Constant, files <-chan *fs.File, functions < } // Start parallel compilation - CompileFunctions(allFunctions) + CompileFunctions(all.Functions) // Report errors if any occurred - for _, function := range allFunctions { + for _, function := range all.Functions { if function.Err != nil { return result, function.Err } @@ -90,7 +91,7 @@ func Compile(constants <-chan *core.Constant, files <-chan *fs.File, functions < } // Check for unused imports in all files - for _, file := range allFiles { + for _, file := range all.Files { for _, pkg := range file.Imports { if !pkg.Used { return result, errors.New(&errors.UnusedImport{Package: pkg.Path}, file, pkg.Position) @@ -99,14 +100,14 @@ func Compile(constants <-chan *core.Constant, files <-chan *fs.File, functions < } // Check for existence of `init` - init, exists := allFunctions["core.init"] + init, exists := all.Functions["core.init"] if !exists { return result, errors.MissingInitFunction } // Check for existence of `main` - main, exists := allFunctions["main.main"] + main, exists := all.Functions["main.main"] if !exists { return result, errors.MissingMainFunction @@ -114,7 +115,7 @@ func Compile(constants <-chan *core.Constant, files <-chan *fs.File, functions < result.Init = init result.Main = main - result.Functions = allFunctions + result.Functions = all.Functions result.finalize() return result, nil } diff --git a/src/compiler/Result.go b/src/compiler/Result.go index 5c96bf3..ce94da8 100644 --- a/src/compiler/Result.go +++ b/src/compiler/Result.go @@ -11,9 +11,9 @@ type Result struct { Main *core.Function Functions map[string]*core.Function Traversed map[*core.Function]bool - InstructionCount int - DataCount int Code []byte Data []byte DLLs dll.List + InstructionCount int + DataCount int } diff --git a/src/core/CompileCall.go b/src/core/CompileCall.go index ee320f2..9089335 100644 --- a/src/core/CompileCall.go +++ b/src/core/CompileCall.go @@ -49,7 +49,7 @@ func (f *Function) CompileCall(root *expression.Expression) ([]types.Type, error return nil, nil } - fn, exists = f.Functions[pkg+"."+name] + fn, exists = f.All.Functions[pkg+"."+name] if !exists { return nil, errors.New(&errors.UnknownFunction{Name: name}, f.File, nameNode.Token.Position) diff --git a/src/core/CompileDelete.go b/src/core/CompileDelete.go index 4792fb0..f768dab 100644 --- a/src/core/CompileDelete.go +++ b/src/core/CompileDelete.go @@ -22,6 +22,6 @@ func (f *Function) CompileDelete(root *expression.Expression) error { f.SaveRegister(f.CPU.Input[1]) f.RegisterRegister(asm.MOVE, f.CPU.Input[0], variable.Register) f.RegisterNumber(asm.MOVE, f.CPU.Input[1], variable.Type.(*types.Pointer).To.Size()) - f.CallSafe(f.Functions["mem.free"], f.CPU.Input[:2]) + f.CallSafe(f.All.Functions["mem.free"], f.CPU.Input[:2]) return nil } diff --git a/src/core/CompileNew.go b/src/core/CompileNew.go index c0925b8..2589f3f 100644 --- a/src/core/CompileNew.go +++ b/src/core/CompileNew.go @@ -37,7 +37,7 @@ func (f *Function) CompileNew(root *expression.Expression) (types.Type, error) { imp.Used = true } - typ, exists := f.Structs[pkg+"."+name] + typ, exists := f.All.Structs[pkg+"."+name] if !exists { return nil, errors.New(&errors.UnknownType{Name: name}, f.File, nameNode.Token.Position) @@ -45,6 +45,6 @@ func (f *Function) CompileNew(root *expression.Expression) (types.Type, error) { f.SaveRegister(f.CPU.Input[0]) f.RegisterNumber(asm.MOVE, f.CPU.Input[0], typ.Size()) - f.CallSafe(f.Functions["mem.alloc"], f.CPU.Input[:1]) + f.CallSafe(f.All.Functions["mem.alloc"], f.CPU.Input[:1]) return &types.Pointer{To: typ}, nil } diff --git a/src/core/Constant.go b/src/core/Constant.go index 5fe78cf..b5bb523 100644 --- a/src/core/Constant.go +++ b/src/core/Constant.go @@ -7,7 +7,7 @@ import ( // Constant registers a single value to be accessible under a descriptive name. type Constant struct { + File *fs.File Name string Token token.Token - File *fs.File } diff --git a/src/core/CreateLabel.go b/src/core/CreateLabel.go index 8ee8eb4..2e874ac 100644 --- a/src/core/CreateLabel.go +++ b/src/core/CreateLabel.go @@ -6,11 +6,11 @@ import ( ) // CreateLabel creates a label that is tied to this function by using a suffix. -func (f *Function) CreateLabel(prefix string, count int) string { +func (f *Function) CreateLabel(prefix string, count uint16) string { tmp := strings.Builder{} tmp.WriteString(prefix) tmp.WriteString(" ") - tmp.WriteString(strconv.Itoa(count)) + tmp.WriteString(strconv.FormatUint(uint64(count), 10)) tmp.WriteString(" [") tmp.WriteString(f.UniqueName) tmp.WriteString("]") diff --git a/src/core/Environment.go b/src/core/Environment.go new file mode 100644 index 0000000..87b1a29 --- /dev/null +++ b/src/core/Environment.go @@ -0,0 +1,14 @@ +package core + +import ( + "git.akyoto.dev/cli/q/src/fs" + "git.akyoto.dev/cli/q/src/types" +) + +// Environment holds information about the entire build. +type Environment struct { + Constants map[string]*Constant + Functions map[string]*Function + Structs map[string]*types.Struct + Files []*fs.File +} diff --git a/src/core/Fold.go b/src/core/Fold.go index 0f610e8..6245114 100644 --- a/src/core/Fold.go +++ b/src/core/Fold.go @@ -32,7 +32,7 @@ func (f *Function) Fold(expr *expression.Expression) error { leftText := left.Token.Text(f.File.Bytes) right := expr.Children[1] rightText := right.Token.Text(f.File.Bytes) - constant, isConst := f.Constants[f.Package+"."+leftText+"."+rightText] + constant, isConst := f.All.Constants[f.Package+"."+leftText+"."+rightText] if !isConst { return nil diff --git a/src/core/Function.go b/src/core/Function.go index 956956c..f159815 100644 --- a/src/core/Function.go +++ b/src/core/Function.go @@ -14,26 +14,14 @@ type Function struct { Package string Name string UniqueName string + All *Environment File *fs.File Body token.List Input []*Parameter Output []*Parameter OutputTypes []types.Type - Functions map[string]*Function - Structs map[string]*types.Struct - Constants map[string]*Constant DLLs dll.List Err error deferred []func() - count counter -} - -// counter stores how often a certain statement appeared so we can generate a unique label from it. -type counter struct { - assert int - branch int - multiBranch int - data int - loop int - subBranch int + count count } diff --git a/src/core/Identifier.go b/src/core/Identifier.go index 0150c56..6a8a148 100644 --- a/src/core/Identifier.go +++ b/src/core/Identifier.go @@ -15,7 +15,7 @@ func (f *Function) Identifier(name string) (*scope.Variable, *Function) { } uniqueName := fmt.Sprintf("%s.%s", f.Package, name) - function, exists := f.Functions[uniqueName] + function, exists := f.All.Functions[uniqueName] if exists { return nil, function diff --git a/src/core/PeriodToRegister.go b/src/core/PeriodToRegister.go index fd2123b..c897853 100644 --- a/src/core/PeriodToRegister.go +++ b/src/core/PeriodToRegister.go @@ -33,7 +33,7 @@ func (f *Function) PeriodToRegister(node *expression.Expression, register cpu.Re return field.Type, nil } - constant, isConst := f.Constants[f.Package+"."+leftText+"."+rightText] + constant, isConst := f.All.Constants[f.Package+"."+leftText+"."+rightText] if isConst { number, err := ToNumber(constant.Token, constant.File) @@ -48,7 +48,7 @@ func (f *Function) PeriodToRegister(node *expression.Expression, register cpu.Re } uniqueName := fmt.Sprintf("%s.%s", leftText, rightText) - function, exists := f.Functions[uniqueName] + function, exists := f.All.Functions[uniqueName] if exists { f.File.Imports[leftText].Used = true diff --git a/src/core/ResolveTypes.go b/src/core/ResolveTypes.go index b885d15..2a5bf08 100644 --- a/src/core/ResolveTypes.go +++ b/src/core/ResolveTypes.go @@ -13,7 +13,7 @@ func (f *Function) ResolveTypes() error { for i, param := range f.Input { param.name = param.tokens[0].Text(f.File.Bytes) typeName := param.tokens[1:].Text(f.File.Bytes) - param.typ = types.ByName(typeName, f.Package, f.Structs) + param.typ = types.ByName(typeName, f.Package, f.All.Structs) if param.typ == nil { return errors.New(&errors.UnknownType{Name: typeName}, f.File, param.tokens[1].Position) @@ -39,7 +39,7 @@ func (f *Function) ResolveTypes() error { for _, param := range f.Output { typeName := param.tokens.Text(f.File.Bytes) - param.typ = types.ByName(typeName, f.Package, f.Structs) + param.typ = types.ByName(typeName, f.Package, f.All.Structs) if param.typ == nil { return errors.New(&errors.UnknownType{Name: typeName}, f.File, param.tokens[0].Position) diff --git a/src/core/count.go b/src/core/count.go new file mode 100644 index 0000000..f200d7e --- /dev/null +++ b/src/core/count.go @@ -0,0 +1,13 @@ +package core + +type counter = uint16 + +// count stores how often a certain statement appeared so we can generate a unique label from it. +type count struct { + assert counter + branch counter + multiBranch counter + data counter + loop counter + subBranch counter +}