Fixed inconsistent lifetimes
This commit is contained in:
parent
a5a8f0f503
commit
be6eafddf5
@ -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))
|
||||
}
|
||||
|
@ -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))
|
||||
}
|
||||
|
@ -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))
|
||||
|
@ -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))
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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))
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
||||
|
@ -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:
|
||||
|
@ -17,4 +17,12 @@ main() {
|
||||
assert i >= 0
|
||||
assert i < 10
|
||||
}
|
||||
|
||||
ten := 10
|
||||
|
||||
for 0..ten {
|
||||
total += 1
|
||||
}
|
||||
|
||||
assert total == ten
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user