q/src/build/core/ExpressionToRegister.go

54 lines
1.2 KiB
Go

package core
import (
"git.akyoto.dev/cli/q/src/build/asm"
"git.akyoto.dev/cli/q/src/build/ast"
"git.akyoto.dev/cli/q/src/build/cpu"
"git.akyoto.dev/cli/q/src/build/errors"
"git.akyoto.dev/cli/q/src/build/expression"
)
// ExpressionToRegister puts the result of an expression into the specified register.
func (f *Function) ExpressionToRegister(node *expression.Expression, register cpu.Register) error {
if node.IsLeaf() {
return f.TokenToRegister(node.Token, register)
}
if ast.IsFunctionCall(node) {
err := f.CompileCall(node)
if register != f.cpu.Output[0] {
f.RegisterRegister(asm.MOVE, register, f.cpu.Output[0])
}
return err
}
if len(node.Children) < 2 {
return errors.New(errors.MissingOperand, f.File, node.Token.End())
}
left := node.Children[0]
right := node.Children[1]
final := register
if f.UsesRegister(right, register) {
register = f.cpu.MustFindFree(f.cpu.General)
}
f.cpu.Reserve(register)
err := f.ExpressionToRegister(left, register)
if err != nil {
return err
}
err = f.Execute(node.Token, register, right)
if register != final {
f.RegisterRegister(asm.MOVE, final, register)
f.cpu.Free(register)
}
return err
}