56 lines
1.2 KiB
Go
Raw Normal View History

2024-07-03 16:37:59 +02:00
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"
2024-07-05 17:11:30 +02:00
"git.akyoto.dev/cli/q/src/build/errors"
2024-07-03 16:37:59 +02:00
"git.akyoto.dev/cli/q/src/build/expression"
)
// ExpressionToRegister puts the result of an expression into the specified register.
2024-07-04 12:32:56 +02:00
func (f *Function) ExpressionToRegister(node *expression.Expression, register cpu.Register) error {
if node.IsLeaf() {
return f.TokenToRegister(node.Token, register)
2024-07-03 16:37:59 +02:00
}
2024-07-04 12:32:56 +02:00
if ast.IsFunctionCall(node) {
err := f.CompileCall(node)
if register != f.cpu.Output[0] {
f.assembler.RegisterRegister(asm.MOVE, register, f.cpu.Output[0])
}
2024-07-03 16:37:59 +02:00
return err
}
2024-07-05 17:11:30 +02:00
if len(node.Children) < 2 {
return errors.New(errors.MissingOperand, f.File, node.Token.End())
}
2024-07-04 12:32:56 +02:00
left := node.Children[0]
right := node.Children[1]
final := register
2024-07-05 15:51:19 +02:00
if f.UsesRegister(right, register) {
2024-07-04 12:32:56 +02:00
register = f.cpu.MustFindFree(f.cpu.General)
}
2024-07-03 16:37:59 +02:00
2024-07-09 10:28:14 +02:00
f.cpu.Reserve(register)
2024-07-03 16:37:59 +02:00
err := f.ExpressionToRegister(left, register)
if err != nil {
return err
}
2024-07-04 12:32:56 +02:00
f.cpu.Use(register)
err = f.Execute(node.Token, register, right)
if register != final {
f.assembler.RegisterRegister(asm.MOVE, final, register)
2024-07-09 10:28:14 +02:00
f.cpu.Free(register)
2024-07-04 12:32:56 +02:00
}
return err
2024-07-03 16:37:59 +02:00
}