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
|
|
|
}
|