From 4428b09de2dc897a967de758cce602450887da09 Mon Sep 17 00:00:00 2001 From: Eduard Urbach Date: Sat, 1 Mar 2025 18:38:00 +0100 Subject: [PATCH] Switched to pointer receivers for values --- src/core/CompileAssign.go | 4 ++-- src/core/CompileAssignDivision.go | 4 ++-- src/core/CompileCondition.go | 4 ++-- src/core/CompileFor.go | 4 ++-- src/core/CompileLen.go | 4 ++-- src/core/Evaluate.go | 4 ++-- src/core/EvaluateArray.go | 16 ++++++++-------- src/core/EvaluateCall.go | 6 +++--- src/core/EvaluateDot.go | 6 +++--- src/core/EvaluateToken.go | 12 ++++++------ src/core/ValueToMemory.go | 8 ++++---- src/core/ValueToRegister.go | 8 ++++---- src/eval/Label.go | 4 ++-- src/eval/Memory.go | 4 ++-- src/eval/Number.go | 4 ++-- src/eval/Register.go | 18 ++++++++++++++++-- src/eval/Value.go | 14 -------------- 17 files changed, 62 insertions(+), 62 deletions(-) diff --git a/src/core/CompileAssign.go b/src/core/CompileAssign.go index 5d2263b..25b3c0a 100644 --- a/src/core/CompileAssign.go +++ b/src/core/CompileAssign.go @@ -36,9 +36,9 @@ func (f *Function) CompileAssign(node *ast.Assign) error { operation := node.Expression.Token switch leftValue := leftValue.(type) { - case eval.Register: + case *eval.Register: f.Execute(operation, leftValue.Register, right) - case eval.Memory: + case *eval.Memory: if operation.Kind == token.Assign { rightValue, err := f.Evaluate(right) diff --git a/src/core/CompileAssignDivision.go b/src/core/CompileAssignDivision.go index 1569ae1..c75026a 100644 --- a/src/core/CompileAssignDivision.go +++ b/src/core/CompileAssignDivision.go @@ -75,11 +75,11 @@ func (f *Function) CompileAssignDivision(expr *expression.Expression) error { divisor := division.Children[1] switch dividend := dividend.(type) { - case eval.Number: + case *eval.Number: f.SaveRegister(x86.RAX) f.RegisterNumber(asm.MOVE, x86.RAX, dividend.Number) err = f.Execute(division.Token, x86.RAX, divisor) - case eval.Register: + case *eval.Register: if dividend.Register != quotientVariable.Value.Register && dividend.IsAlive() { tmp := f.NewRegister() f.RegisterRegister(asm.MOVE, tmp, dividend.Register) diff --git a/src/core/CompileCondition.go b/src/core/CompileCondition.go index 983c275..3e14d57 100644 --- a/src/core/CompileCondition.go +++ b/src/core/CompileCondition.go @@ -80,11 +80,11 @@ func (f *Function) CompileCondition(condition *expression.Expression, successLab } switch value := value.(type) { - case eval.Number: + case *eval.Number: if value.Number == 0 { f.Jump(asm.JUMP, failLabel) } - case eval.Register: + case *eval.Register: f.RegisterNumber(asm.COMPARE, value.Register, 0) f.Jump(asm.JE, failLabel) default: diff --git a/src/core/CompileFor.go b/src/core/CompileFor.go index a07702b..973c6f6 100644 --- a/src/core/CompileFor.go +++ b/src/core/CompileFor.go @@ -75,10 +75,10 @@ func (f *Function) CompileFor(loop *ast.For) error { } switch value := value.(type) { - case eval.Number: + case *eval.Number: f.AddLabel(label) f.RegisterNumber(asm.COMPARE, counter, value.Number) - case eval.Register: + case *eval.Register: if value.IsAlive() { tmp := f.NewRegister() f.RegisterRegister(asm.MOVE, tmp, value.Register) diff --git a/src/core/CompileLen.go b/src/core/CompileLen.go index bf44e1a..64f3cf5 100644 --- a/src/core/CompileLen.go +++ b/src/core/CompileLen.go @@ -35,9 +35,9 @@ func (f *Function) CompileLen(root *expression.Expression) error { f.SaveRegister(output) switch value := value.(type) { - case eval.Register: + case *eval.Register: memory.Base = value.Register - case eval.Label: + case *eval.Label: f.RegisterLabel(asm.MOVE, output, value.Label) memory.Base = output default: diff --git a/src/core/Evaluate.go b/src/core/Evaluate.go index e13f741..112da15 100644 --- a/src/core/Evaluate.go +++ b/src/core/Evaluate.go @@ -10,7 +10,7 @@ import ( // Evaluate evaluates an expression and returns a value. func (f *Function) Evaluate(expr *expression.Expression) (eval.Value, error) { if expr.IsFolded { - value := eval.Number{ + value := &eval.Number{ Typ: types.AnyInt, Number: expr.Value, } @@ -36,7 +36,7 @@ func (f *Function) Evaluate(expr *expression.Expression) (eval.Value, error) { tmp := f.NewRegister() typ, err := f.ExpressionToRegister(expr, tmp) - value := eval.Register{ + value := &eval.Register{ Typ: typ, Register: tmp, } diff --git a/src/core/EvaluateArray.go b/src/core/EvaluateArray.go index 5844015..39cb01a 100644 --- a/src/core/EvaluateArray.go +++ b/src/core/EvaluateArray.go @@ -12,12 +12,12 @@ import ( ) // EvaluateArray evaluates an array access. -func (f *Function) EvaluateArray(expr *expression.Expression) (eval.Memory, error) { +func (f *Function) EvaluateArray(expr *expression.Expression) (*eval.Memory, error) { name := expr.Children[0].Token.Text(f.File.Bytes) base := f.VariableByName(name) if base == nil { - return eval.Memory{}, errors.New(&errors.UnknownIdentifier{Name: name}, f.File, expr.Children[0].Token.Position) + return nil, errors.New(&errors.UnknownIdentifier{Name: name}, f.File, expr.Children[0].Token.Position) } defer f.UseVariable(base) @@ -33,17 +33,17 @@ func (f *Function) EvaluateArray(expr *expression.Expression) (eval.Memory, erro index, err := f.Evaluate(indexExpr) if err != nil { - return eval.Memory{}, err + return nil, err } if !types.Is(index.Type(), types.AnyInt) { - return eval.Memory{}, errors.New(&errors.TypeMismatch{Encountered: index.Type().Name(), Expected: types.AnyInt.Name()}, f.File, indexExpr.Token.Position) + return nil, errors.New(&errors.TypeMismatch{Encountered: index.Type().Name(), Expected: types.AnyInt.Name()}, f.File, indexExpr.Token.Position) } switch index := index.(type) { - case eval.Number: + case *eval.Number: memory.Offset = int8(index.Number) - case eval.Register: + case *eval.Register: memory.OffsetRegister = index.Register default: panic(fmt.Errorf("%s: not implemented: %v", f.UniqueName, index)) @@ -52,7 +52,7 @@ func (f *Function) EvaluateArray(expr *expression.Expression) (eval.Memory, erro array, isArray := base.Value.Typ.(*types.Array) if isArray { - value := eval.Memory{ + value := &eval.Memory{ Typ: array.Of, Memory: memory, } @@ -63,7 +63,7 @@ func (f *Function) EvaluateArray(expr *expression.Expression) (eval.Memory, erro pointer, isPointer := base.Value.Typ.(*types.Pointer) if isPointer { - value := eval.Memory{ + value := &eval.Memory{ Typ: pointer.To, Memory: memory, } diff --git a/src/core/EvaluateCall.go b/src/core/EvaluateCall.go index 3f338b1..6defe4f 100644 --- a/src/core/EvaluateCall.go +++ b/src/core/EvaluateCall.go @@ -6,14 +6,14 @@ import ( ) // EvaluateCall evaluates a function call. -func (f *Function) EvaluateCall(expr *expression.Expression) (eval.Register, error) { +func (f *Function) EvaluateCall(expr *expression.Expression) (*eval.Register, error) { typ, err := f.CompileCall(expr) if err != nil { - return eval.Register{}, err + return nil, err } - value := eval.Register{Register: f.CPU.Output[0]} + value := &eval.Register{Register: f.CPU.Output[0]} if len(typ) > 0 { value.Typ = typ[0] diff --git a/src/core/EvaluateDot.go b/src/core/EvaluateDot.go index ca73d88..944ea02 100644 --- a/src/core/EvaluateDot.go +++ b/src/core/EvaluateDot.go @@ -29,7 +29,7 @@ func (f *Function) EvaluateDot(expr *expression.Expression) (eval.Value, error) return nil, errors.New(&errors.UnknownStructField{StructName: structure.Name(), FieldName: rightText}, f.File, right.Token.Position) } - value := eval.Memory{ + value := &eval.Memory{ Typ: field.Type, Memory: asm.Memory{ Base: variable.Value.Register, @@ -51,7 +51,7 @@ func (f *Function) EvaluateDot(expr *expression.Expression) (eval.Value, error) return nil, err } - value := eval.Number{ + value := &eval.Number{ Typ: types.AnyInt, Number: number, } @@ -65,7 +65,7 @@ func (f *Function) EvaluateDot(expr *expression.Expression) (eval.Value, error) if exists { f.File.Imports[leftText].Used = true - value := eval.Label{ + value := &eval.Label{ Typ: types.AnyPointer, Label: function.UniqueName, } diff --git a/src/core/EvaluateToken.go b/src/core/EvaluateToken.go index 3d5d18f..f2e7c9d 100644 --- a/src/core/EvaluateToken.go +++ b/src/core/EvaluateToken.go @@ -16,7 +16,7 @@ func (f *Function) EvaluateToken(t token.Token) (eval.Value, error) { name := t.Text(f.File.Bytes) if name == "true" { - value := eval.Number{ + value := &eval.Number{ Typ: types.Bool, Number: 1, } @@ -25,7 +25,7 @@ func (f *Function) EvaluateToken(t token.Token) (eval.Value, error) { } if name == "false" { - value := eval.Number{ + value := &eval.Number{ Typ: types.Bool, Number: 0, } @@ -37,11 +37,11 @@ func (f *Function) EvaluateToken(t token.Token) (eval.Value, error) { if variable != nil { f.UseVariable(variable) - return variable.Value, nil + return &variable.Value, nil } if function != nil { - value := eval.Label{ + value := &eval.Label{ Typ: types.AnyPointer, Label: function.UniqueName, } @@ -58,7 +58,7 @@ func (f *Function) EvaluateToken(t token.Token) (eval.Value, error) { return nil, err } - value := eval.Number{ + value := &eval.Number{ Typ: types.AnyInt, Number: number, } @@ -74,7 +74,7 @@ func (f *Function) EvaluateToken(t token.Token) (eval.Value, error) { copy(slice[8:], data) label := f.AddBytes(slice) - value := eval.Label{ + value := &eval.Label{ Typ: types.String, Label: label, } diff --git a/src/core/ValueToMemory.go b/src/core/ValueToMemory.go index 07c30e3..36831a9 100644 --- a/src/core/ValueToMemory.go +++ b/src/core/ValueToMemory.go @@ -8,16 +8,16 @@ import ( // ValueToMemory moves a value into a memory region. func (f *Function) ValueToMemory(value eval.Value, memory asm.Memory) { switch value := value.(type) { - case eval.Number: + case *eval.Number: f.MemoryNumber(asm.STORE, memory, value.Number) - case eval.Register: + case *eval.Register: f.MemoryRegister(asm.STORE, memory, value.Register) - case eval.Memory: + case *eval.Memory: tmp := f.NewRegister() f.MemoryRegister(asm.LOAD, value.Memory, tmp) f.MemoryRegister(asm.STORE, memory, tmp) f.FreeRegister(tmp) - case eval.Label: + case *eval.Label: f.MemoryLabel(asm.STORE, memory, value.Label) } } diff --git a/src/core/ValueToRegister.go b/src/core/ValueToRegister.go index 51d0656..811fc34 100644 --- a/src/core/ValueToRegister.go +++ b/src/core/ValueToRegister.go @@ -9,13 +9,13 @@ import ( // ValueToRegister moves a value into a register. func (f *Function) ValueToRegister(value eval.Value, register cpu.Register) { switch value := value.(type) { - case eval.Number: + case *eval.Number: f.RegisterNumber(asm.MOVE, register, value.Number) - case eval.Register: + case *eval.Register: f.RegisterRegister(asm.MOVE, register, value.Register) - case eval.Memory: + case *eval.Memory: f.MemoryRegister(asm.LOAD, value.Memory, register) - case eval.Label: + case *eval.Label: f.RegisterLabel(asm.MOVE, register, value.Label) } } diff --git a/src/eval/Label.go b/src/eval/Label.go index a74afe0..e88dbd3 100644 --- a/src/eval/Label.go +++ b/src/eval/Label.go @@ -8,10 +8,10 @@ type Label struct { Label string } -func (v Label) String() string { +func (v *Label) String() string { return "Label" } -func (v Label) Type() types.Type { +func (v *Label) Type() types.Type { return v.Typ } diff --git a/src/eval/Memory.go b/src/eval/Memory.go index 0afd09e..4b53711 100644 --- a/src/eval/Memory.go +++ b/src/eval/Memory.go @@ -11,10 +11,10 @@ type Memory struct { Memory asm.Memory } -func (v Memory) String() string { +func (v *Memory) String() string { return "Memory" } -func (v Memory) Type() types.Type { +func (v *Memory) Type() types.Type { return v.Typ } diff --git a/src/eval/Number.go b/src/eval/Number.go index e9dc2d7..e525a9e 100644 --- a/src/eval/Number.go +++ b/src/eval/Number.go @@ -8,10 +8,10 @@ type Number struct { Number int } -func (v Number) String() string { +func (v *Number) String() string { return "Number" } -func (v Number) Type() types.Type { +func (v *Number) Type() types.Type { return v.Typ } diff --git a/src/eval/Register.go b/src/eval/Register.go index 088593f..b31547e 100644 --- a/src/eval/Register.go +++ b/src/eval/Register.go @@ -12,10 +12,24 @@ type Register struct { Register cpu.Register } -func (v Register) String() string { +func (v *Register) String() string { return "Register" } -func (v Register) Type() types.Type { +func (v *Register) Type() types.Type { return v.Typ } + +// IsAlive returns true if the register value is still alive. +func (v *Register) IsAlive() bool { + return v.Alive > 0 +} + +// Use reduces the lifetime counter by one. +func (v *Register) Use() { + if v.Alive == 0 { + panic("incorrect number of value use calls") + } + + v.Alive-- +} diff --git a/src/eval/Value.go b/src/eval/Value.go index 681cc18..33b6db6 100644 --- a/src/eval/Value.go +++ b/src/eval/Value.go @@ -9,17 +9,3 @@ type Value interface { String() string Type() types.Type } - -// IsAlive returns true if the register value is still alive. -func (v *Register) IsAlive() bool { - return v.Alive > 0 -} - -// Use reduces the lifetime counter by one. -func (v *Register) Use() { - if v.Alive == 0 { - panic("incorrect number of value use calls") - } - - v.Alive-- -}