Added simple variable lifetimes

This commit is contained in:
2024-06-27 15:23:02 +02:00
parent dc497ba4fb
commit ec5240425b
6 changed files with 107 additions and 39 deletions

View File

@ -4,6 +4,7 @@ import (
"fmt"
"strconv"
"git.akyoto.dev/cli/q/src/build/arch/x64"
"git.akyoto.dev/cli/q/src/build/asm"
"git.akyoto.dev/cli/q/src/build/cpu"
"git.akyoto.dev/cli/q/src/build/expression"
@ -141,17 +142,51 @@ func (f *Function) ExpressionToRegister(root *expression.Expression, register cp
// ExpressionsToRegisters moves multiple expressions into the specified registers.
func (f *Function) ExpressionsToRegisters(expressions []*expression.Expression, registers []cpu.Register) error {
var destinations []cpu.Register
for i := len(expressions) - 1; i >= 0; i-- {
err := f.ExpressionToRegister(expressions[i], registers[i])
original := registers[i]
expression := expressions[i]
if expression.IsLeaf() {
variable, exists := f.Variables[expression.Token.Text()]
if exists && variable.Register == original {
continue
}
}
register := original
save := !f.CPU.IsFree(register)
if save {
register = x64.RAX
}
err := f.ExpressionToRegister(expression, register)
if err != nil {
return err
}
if save {
destinations = append(destinations, original)
f.Assembler.Register(asm.PUSH, x64.RAX)
}
}
for i := len(destinations) - 1; i >= 0; i-- {
f.Assembler.Register(asm.POP, destinations[i])
}
return nil
}
func (f *Function) Log(messages ...any) {
fmt.Printf("[%s] ", f.Name)
fmt.Println(messages...)
}
// TokenToRegister moves a token into a register.
// It only works with identifiers, numbers and strings.
func (f *Function) TokenToRegister(t token.Token, register cpu.Register) error {
@ -168,6 +203,7 @@ func (f *Function) TokenToRegister(t token.Token, register cpu.Register) error {
f.Assembler.RegisterRegister(asm.MOVE, register, variable.Register)
}
f.useVariable(variable)
return nil
case token.Number: