Added simple variable lifetimes
This commit is contained in:
@ -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:
|
||||
|
Reference in New Issue
Block a user