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)
|
memory.Offset = int8(index.Number)
|
||||||
case eval.Register:
|
case eval.Register:
|
||||||
memory.OffsetRegister = index.Register
|
memory.OffsetRegister = index.Register
|
||||||
defer f.FreeRegister(index.Register)
|
|
||||||
default:
|
default:
|
||||||
panic(fmt.Errorf("%s: not implemented: %v", f.UniqueName, index))
|
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)
|
f.RegisterNumber(asm.MOVE, x86.RAX, dividend.Number)
|
||||||
err = f.Execute(division.Token, x86.RAX, divisor)
|
err = f.Execute(division.Token, x86.RAX, divisor)
|
||||||
case eval.Register:
|
case eval.Register:
|
||||||
err = f.Execute(division.Token, dividend.Register, divisor)
|
if dividend.Register != quotientVariable.Value.Register && dividend.IsAlive() {
|
||||||
defer f.FreeRegister(dividend.Register)
|
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:
|
default:
|
||||||
panic(fmt.Errorf("%s: not implemented: %v", f.UniqueName, dividend))
|
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:
|
case eval.Register:
|
||||||
f.RegisterNumber(asm.COMPARE, value.Register, 0)
|
f.RegisterNumber(asm.COMPARE, value.Register, 0)
|
||||||
f.FreeRegister(value.Register)
|
|
||||||
f.Jump(asm.JE, failLabel)
|
f.Jump(asm.JE, failLabel)
|
||||||
default:
|
default:
|
||||||
panic(fmt.Errorf("%s: not implemented: %v", f.UniqueName, value))
|
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
|
to *expression.Expression
|
||||||
)
|
)
|
||||||
|
|
||||||
scope := f.PushScope(loop.Body, f.File.Bytes)
|
|
||||||
scope.InLoop = true
|
|
||||||
|
|
||||||
switch loop.Head.Token.Kind {
|
switch loop.Head.Token.Kind {
|
||||||
case token.Define:
|
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]
|
from = loop.Head.Children[1].Children[0]
|
||||||
to = loop.Head.Children[1].Children[1]
|
to = loop.Head.Children[1].Children[1]
|
||||||
f.AddVariable(variable)
|
|
||||||
|
|
||||||
case token.Range:
|
case token.Range:
|
||||||
counter = f.NewRegister()
|
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)
|
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) {
|
switch value := value.(type) {
|
||||||
case eval.Number:
|
case eval.Number:
|
||||||
|
f.AddLabel(label)
|
||||||
f.RegisterNumber(asm.COMPARE, counter, value.Number)
|
f.RegisterNumber(asm.COMPARE, counter, value.Number)
|
||||||
case eval.Register:
|
case eval.Register:
|
||||||
f.RegisterRegister(asm.COMPARE, counter, value.Register)
|
if value.IsAlive() {
|
||||||
defer f.FreeRegister(value.Register)
|
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:
|
default:
|
||||||
panic(fmt.Errorf("%s: not implemented: %v", f.UniqueName, value))
|
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) {
|
switch value := value.(type) {
|
||||||
case eval.Register:
|
case eval.Register:
|
||||||
memory.Base = value.Register
|
memory.Base = value.Register
|
||||||
defer f.FreeRegister(value.Register)
|
|
||||||
case eval.Label:
|
case eval.Label:
|
||||||
f.RegisterLabel(asm.MOVE, output, value.Label)
|
f.RegisterLabel(asm.MOVE, output, value.Label)
|
||||||
memory.Base = output
|
memory.Base = output
|
||||||
|
@ -45,7 +45,6 @@ func (f *Function) EvaluateArray(expr *expression.Expression) (eval.Memory, erro
|
|||||||
memory.Offset = int8(index.Number)
|
memory.Offset = int8(index.Number)
|
||||||
case eval.Register:
|
case eval.Register:
|
||||||
memory.OffsetRegister = index.Register
|
memory.OffsetRegister = index.Register
|
||||||
defer f.FreeRegister(index.Register)
|
|
||||||
default:
|
default:
|
||||||
panic(fmt.Errorf("%s: not implemented: %v", f.UniqueName, index))
|
panic(fmt.Errorf("%s: not implemented: %v", f.UniqueName, index))
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,6 @@ package core
|
|||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
|
||||||
"git.urbach.dev/cli/q/src/asm"
|
|
||||||
"git.urbach.dev/cli/q/src/errors"
|
"git.urbach.dev/cli/q/src/errors"
|
||||||
"git.urbach.dev/cli/q/src/eval"
|
"git.urbach.dev/cli/q/src/eval"
|
||||||
"git.urbach.dev/cli/q/src/token"
|
"git.urbach.dev/cli/q/src/token"
|
||||||
@ -38,20 +37,7 @@ func (f *Function) EvaluateToken(t token.Token) (eval.Value, error) {
|
|||||||
|
|
||||||
if variable != nil {
|
if variable != nil {
|
||||||
f.UseVariable(variable)
|
f.UseVariable(variable)
|
||||||
|
return variable.Value, nil
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if function != 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)
|
f.MemoryNumber(asm.STORE, memory, value.Number)
|
||||||
case eval.Register:
|
case eval.Register:
|
||||||
f.MemoryRegister(asm.STORE, memory, value.Register)
|
f.MemoryRegister(asm.STORE, memory, value.Register)
|
||||||
f.FreeRegister(value.Register)
|
|
||||||
case eval.Memory:
|
case eval.Memory:
|
||||||
tmp := f.NewRegister()
|
tmp := f.NewRegister()
|
||||||
f.MemoryRegister(asm.LOAD, value.Memory, tmp)
|
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)
|
f.RegisterNumber(asm.MOVE, register, value.Number)
|
||||||
case eval.Register:
|
case eval.Register:
|
||||||
f.RegisterRegister(asm.MOVE, register, value.Register)
|
f.RegisterRegister(asm.MOVE, register, value.Register)
|
||||||
f.FreeRegister(value.Register)
|
|
||||||
case eval.Memory:
|
case eval.Memory:
|
||||||
f.MemoryRegister(asm.LOAD, value.Memory, register)
|
f.MemoryRegister(asm.LOAD, value.Memory, register)
|
||||||
case eval.Label:
|
case eval.Label:
|
||||||
|
@ -17,4 +17,12 @@ main() {
|
|||||||
assert i >= 0
|
assert i >= 0
|
||||||
assert i < 10
|
assert i < 10
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ten := 10
|
||||||
|
|
||||||
|
for 0..ten {
|
||||||
|
total += 1
|
||||||
|
}
|
||||||
|
|
||||||
|
assert total == ten
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user