Switched to pointer receivers for values

This commit is contained in:
Eduard Urbach 2025-03-01 18:38:00 +01:00
parent 8ff6faa310
commit 4428b09de2
Signed by: akyoto
GPG Key ID: C874F672B1AF20C0
17 changed files with 62 additions and 62 deletions

View File

@ -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)

View File

@ -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)

View File

@ -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:

View File

@ -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)

View File

@ -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:

View File

@ -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,
}

View File

@ -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,
}

View File

@ -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]

View File

@ -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,
}

View File

@ -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,
}

View File

@ -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)
}
}

View File

@ -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)
}
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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--
}

View File

@ -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--
}