Improved code generation

This commit is contained in:
Eduard Urbach 2024-07-05 15:51:19 +02:00
parent 099ee729d4
commit 3e92c83c0d
Signed by: akyoto
GPG Key ID: C874F672B1AF20C0
3 changed files with 48 additions and 12 deletions

View File

@ -27,7 +27,7 @@ func (f *Function) ExpressionToRegister(node *expression.Expression, register cp
right := node.Children[1]
final := register
if OverwritesRegister(right, register) {
if f.UsesRegister(right, register) {
register = f.cpu.MustFindFree(f.cpu.General)
}

View File

@ -1,11 +0,0 @@
package core
import (
"git.akyoto.dev/cli/q/src/build/cpu"
"git.akyoto.dev/cli/q/src/build/expression"
)
// OverwritesRegister returns true if evaluating the expression would overwrite the given register.
func OverwritesRegister(expr *expression.Expression, register cpu.Register) bool {
return !expr.IsLeaf()
}

View File

@ -0,0 +1,47 @@
package core
import (
"git.akyoto.dev/cli/q/src/build/ast"
"git.akyoto.dev/cli/q/src/build/cpu"
"git.akyoto.dev/cli/q/src/build/expression"
"git.akyoto.dev/cli/q/src/build/token"
)
// UsesRegister returns true if evaluating the expression would write or read the given register.
func (f *Function) UsesRegister(expr *expression.Expression, register cpu.Register) bool {
if expr.IsLeaf() {
if expr.Token.Kind == token.Number {
return false
}
name := expr.Token.Text()
variable := f.variables[name]
return register == variable.Register
}
if ast.IsFunctionCall(expr) {
if register == f.cpu.Output[0] {
return true
}
for i, parameter := range expr.Children[1:] {
if register == f.cpu.Input[i] {
return true
}
if f.UsesRegister(parameter, register) {
return true
}
}
return false
}
for _, child := range expr.Children {
if f.UsesRegister(child, register) {
return true
}
}
return false
}