diff --git a/src/core/CompileAssignArray.go b/src/core/CompileAssignArray.go index 46a02e0..05244e0 100644 --- a/src/core/CompileAssignArray.go +++ b/src/core/CompileAssignArray.go @@ -47,7 +47,6 @@ func (f *Function) CompileAssignArray(node *ast.Assign) error { memory.Offset = int8(index.Number) case eval.Register: memory.OffsetRegister = index.Register - defer f.FreeRegister(index.Register) default: panic(fmt.Errorf("%s: not implemented: %v", f.UniqueName, index)) } diff --git a/src/core/CompileAssignDivision.go b/src/core/CompileAssignDivision.go index cf4be7b..1569ae1 100644 --- a/src/core/CompileAssignDivision.go +++ b/src/core/CompileAssignDivision.go @@ -80,8 +80,14 @@ func (f *Function) CompileAssignDivision(expr *expression.Expression) error { f.RegisterNumber(asm.MOVE, x86.RAX, dividend.Number) err = f.Execute(division.Token, x86.RAX, divisor) case eval.Register: - err = f.Execute(division.Token, dividend.Register, divisor) - defer f.FreeRegister(dividend.Register) + if dividend.Register != quotientVariable.Value.Register && dividend.IsAlive() { + tmp := f.NewRegister() + f.RegisterRegister(asm.MOVE, tmp, dividend.Register) + err = f.Execute(division.Token, tmp, divisor) + f.FreeRegister(tmp) + } else { + err = f.Execute(division.Token, dividend.Register, divisor) + } default: panic(fmt.Errorf("%s: not implemented: %v", f.UniqueName, dividend)) } diff --git a/src/core/CompileCondition.go b/src/core/CompileCondition.go index 19451a9..983c275 100644 --- a/src/core/CompileCondition.go +++ b/src/core/CompileCondition.go @@ -86,7 +86,6 @@ func (f *Function) CompileCondition(condition *expression.Expression, successLab } case eval.Register: f.RegisterNumber(asm.COMPARE, value.Register, 0) - f.FreeRegister(value.Register) f.Jump(asm.JE, failLabel) default: panic(fmt.Errorf("%s: not implemented: %v", f.UniqueName, value)) diff --git a/src/core/CompileFor.go b/src/core/CompileFor.go index 414a166..a07702b 100644 --- a/src/core/CompileFor.go +++ b/src/core/CompileFor.go @@ -29,21 +29,10 @@ func (f *Function) CompileFor(loop *ast.For) error { to *expression.Expression ) - scope := f.PushScope(loop.Body, f.File.Bytes) - scope.InLoop = true - switch loop.Head.Token.Kind { case token.Define: - variable, err := f.Define(loop.Head.Children[0]) - - if err != nil { - return err - } - - counter = variable.Value.Register from = loop.Head.Children[1].Children[0] to = loop.Head.Children[1].Children[1] - f.AddVariable(variable) case token.Range: counter = f.NewRegister() @@ -71,14 +60,35 @@ func (f *Function) CompileFor(loop *ast.For) error { return errors.New(&errors.TypeMismatch{Encountered: value.Type().Name(), Expected: types.AnyInt.Name()}, f.File, to.Token.Position) } - f.AddLabel(label) + scope := f.PushScope(loop.Body, f.File.Bytes) + scope.InLoop = true + + if loop.Head.Token.Kind == token.Define { + variable, err := f.Define(loop.Head.Children[0]) + + if err != nil { + return err + } + + counter = variable.Value.Register + f.AddVariable(variable) + } switch value := value.(type) { case eval.Number: + f.AddLabel(label) f.RegisterNumber(asm.COMPARE, counter, value.Number) case eval.Register: - f.RegisterRegister(asm.COMPARE, counter, value.Register) - defer f.FreeRegister(value.Register) + if value.IsAlive() { + tmp := f.NewRegister() + f.RegisterRegister(asm.MOVE, tmp, value.Register) + defer f.FreeRegister(tmp) + f.AddLabel(label) + f.RegisterRegister(asm.COMPARE, counter, tmp) + } else { + f.AddLabel(label) + f.RegisterRegister(asm.COMPARE, counter, value.Register) + } default: panic(fmt.Errorf("%s: not implemented: %v", f.UniqueName, value)) } diff --git a/src/core/CompileLen.go b/src/core/CompileLen.go index 3a0fb79..bf44e1a 100644 --- a/src/core/CompileLen.go +++ b/src/core/CompileLen.go @@ -37,7 +37,6 @@ func (f *Function) CompileLen(root *expression.Expression) error { switch value := value.(type) { case eval.Register: memory.Base = value.Register - defer f.FreeRegister(value.Register) case eval.Label: f.RegisterLabel(asm.MOVE, output, value.Label) memory.Base = output diff --git a/src/core/EvaluateArray.go b/src/core/EvaluateArray.go index bd32ebd..72ef764 100644 --- a/src/core/EvaluateArray.go +++ b/src/core/EvaluateArray.go @@ -45,7 +45,6 @@ func (f *Function) EvaluateArray(expr *expression.Expression) (eval.Memory, erro memory.Offset = int8(index.Number) case eval.Register: memory.OffsetRegister = index.Register - defer f.FreeRegister(index.Register) default: panic(fmt.Errorf("%s: not implemented: %v", f.UniqueName, index)) } diff --git a/src/core/EvaluateToken.go b/src/core/EvaluateToken.go index 6a14446..3d5d18f 100644 --- a/src/core/EvaluateToken.go +++ b/src/core/EvaluateToken.go @@ -3,7 +3,6 @@ package core import ( "encoding/binary" - "git.urbach.dev/cli/q/src/asm" "git.urbach.dev/cli/q/src/errors" "git.urbach.dev/cli/q/src/eval" "git.urbach.dev/cli/q/src/token" @@ -38,20 +37,7 @@ func (f *Function) EvaluateToken(t token.Token) (eval.Value, error) { if variable != nil { f.UseVariable(variable) - - if variable.Value.Alive == 0 { - return variable.Value, nil - } - - tmp := f.NewRegister() - f.RegisterRegister(asm.MOVE, tmp, variable.Value.Register) - - value := eval.Register{ - Typ: variable.Value.Typ, - Register: tmp, - } - - return value, nil + return variable.Value, nil } if function != nil { diff --git a/src/core/ValueToMemory.go b/src/core/ValueToMemory.go index 7380b73..07c30e3 100644 --- a/src/core/ValueToMemory.go +++ b/src/core/ValueToMemory.go @@ -12,7 +12,6 @@ func (f *Function) ValueToMemory(value eval.Value, memory asm.Memory) { f.MemoryNumber(asm.STORE, memory, value.Number) case eval.Register: f.MemoryRegister(asm.STORE, memory, value.Register) - f.FreeRegister(value.Register) case eval.Memory: tmp := f.NewRegister() f.MemoryRegister(asm.LOAD, value.Memory, tmp) diff --git a/src/core/ValueToRegister.go b/src/core/ValueToRegister.go index 94da6cd..51d0656 100644 --- a/src/core/ValueToRegister.go +++ b/src/core/ValueToRegister.go @@ -13,7 +13,6 @@ func (f *Function) ValueToRegister(value eval.Value, register cpu.Register) { f.RegisterNumber(asm.MOVE, register, value.Number) case eval.Register: f.RegisterRegister(asm.MOVE, register, value.Register) - f.FreeRegister(value.Register) case eval.Memory: f.MemoryRegister(asm.LOAD, value.Memory, register) case eval.Label: diff --git a/tests/programs/for.q b/tests/programs/for.q index 894751f..a8f5256 100644 --- a/tests/programs/for.q +++ b/tests/programs/for.q @@ -17,4 +17,12 @@ main() { assert i >= 0 assert i < 10 } + + ten := 10 + + for 0..ten { + total += 1 + } + + assert total == ten } \ No newline at end of file