Improved performance

This commit is contained in:
Eduard Urbach 2024-08-02 11:41:21 +02:00
parent 548e3475fb
commit b0c568e616
Signed by: akyoto
GPG Key ID: C874F672B1AF20C0
11 changed files with 29 additions and 32 deletions

View File

@ -23,7 +23,7 @@ func Compile(files <-chan *fs.File, functions <-chan *core.Function, errs <-chan
} }
function.Functions = allFunctions function.Functions = allFunctions
allFunctions[function.Name] = function allFunctions[function.UniqueName] = function
case file, ok := <-files: case file, ok := <-files:
if !ok { if !ok {

View File

@ -7,7 +7,7 @@ import (
// AddBytes adds a sequence of bytes and returns its address as a label. // AddBytes adds a sequence of bytes and returns its address as a label.
func (f *Function) AddBytes(value []byte) string { func (f *Function) AddBytes(value []byte) string {
f.count.data++ f.count.data++
label := fmt.Sprintf("%s_data_%d", f.Name, f.count.data) label := fmt.Sprintf("%s_data_%d", f.UniqueName, f.count.data)
f.Assembler.SetData(label, value) f.Assembler.SetData(label, value)
return label return label
} }

View File

@ -2,7 +2,7 @@ package core
// Compile turns a function into machine code. // Compile turns a function into machine code.
func (f *Function) Compile() { func (f *Function) Compile() {
f.AddLabel(f.Name) f.AddLabel(f.UniqueName)
f.Err = f.CompileTokens(f.Body) f.Err = f.CompileTokens(f.Body)
f.Return() f.Return()

View File

@ -10,8 +10,8 @@ import (
// CompileAssert compiles an assertion. // CompileAssert compiles an assertion.
func (f *Function) CompileAssert(assert *ast.Assert) error { func (f *Function) CompileAssert(assert *ast.Assert) error {
f.count.assert++ f.count.assert++
success := fmt.Sprintf("%s_assert_%d_true", f.Name, f.count.assert) success := fmt.Sprintf("%s_assert_%d_true", f.UniqueName, f.count.assert)
fail := fmt.Sprintf("%s_assert_%d_false", f.Name, f.count.assert) fail := fmt.Sprintf("%s_assert_%d_false", f.UniqueName, f.count.assert)
err := f.CompileCondition(assert.Condition, success, fail) err := f.CompileCondition(assert.Condition, success, fail)
if err != nil { if err != nil {

View File

@ -12,7 +12,7 @@ func (f *Function) CompileCondition(condition *expression.Expression, successLab
switch condition.Token.Kind { switch condition.Token.Kind {
case token.LogicalOr: case token.LogicalOr:
f.count.subBranch++ f.count.subBranch++
leftFailLabel := fmt.Sprintf("%s_false_%d", f.Name, f.count.subBranch) leftFailLabel := fmt.Sprintf("%s_false_%d", f.UniqueName, f.count.subBranch)
// Left // Left
left := condition.Children[0] left := condition.Children[0]
@ -39,7 +39,7 @@ func (f *Function) CompileCondition(condition *expression.Expression, successLab
case token.LogicalAnd: case token.LogicalAnd:
f.count.subBranch++ f.count.subBranch++
leftSuccessLabel := fmt.Sprintf("%s_true_%d", f.Name, f.count.subBranch) leftSuccessLabel := fmt.Sprintf("%s_true_%d", f.UniqueName, f.count.subBranch)
// Left // Left
left := condition.Children[0] left := condition.Children[0]

View File

@ -13,8 +13,8 @@ func (f *Function) CompileIf(branch *ast.If) error {
var ( var (
end string end string
success = fmt.Sprintf("%s_if_%d_true", f.Name, f.count.branch) success = fmt.Sprintf("%s_if_%d_true", f.UniqueName, f.count.branch)
fail = fmt.Sprintf("%s_if_%d_false", f.Name, f.count.branch) fail = fmt.Sprintf("%s_if_%d_false", f.UniqueName, f.count.branch)
err = f.CompileCondition(branch.Condition, success, fail) err = f.CompileCondition(branch.Condition, success, fail)
) )
@ -31,7 +31,7 @@ func (f *Function) CompileIf(branch *ast.If) error {
} }
if branch.Else != nil { if branch.Else != nil {
end = fmt.Sprintf("%s_if_%d_end", f.Name, f.count.branch) end = fmt.Sprintf("%s_if_%d_end", f.UniqueName, f.count.branch)
f.Jump(asm.JUMP, end) f.Jump(asm.JUMP, end)
} }

View File

@ -10,7 +10,7 @@ import (
// CompileLoop compiles a loop instruction. // CompileLoop compiles a loop instruction.
func (f *Function) CompileLoop(loop *ast.Loop) error { func (f *Function) CompileLoop(loop *ast.Loop) error {
f.count.loop++ f.count.loop++
label := fmt.Sprintf("%s_loop_%d", f.Name, f.count.loop) label := fmt.Sprintf("%s_loop_%d", f.UniqueName, f.count.loop)
f.AddLabel(label) f.AddLabel(label)
scope := f.PushScope(loop.Body, f.File.Bytes) scope := f.PushScope(loop.Body, f.File.Bytes)
scope.InLoop = true scope.InLoop = true

View File

@ -9,14 +9,15 @@ import (
// Function represents the smallest unit of code. // Function represents the smallest unit of code.
type Function struct { type Function struct {
register.Machine register.Machine
Package string Package string
Name string Name string
File *fs.File UniqueName string
Body []token.Token File *fs.File
Functions map[string]*Function Body []token.Token
Err error Functions map[string]*Function
deferred []func() Err error
count counter deferred []func()
count counter
} }
// counter stores how often a certain statement appeared so we can generate a unique label from it. // counter stores how often a certain statement appeared so we can generate a unique label from it.

View File

@ -13,10 +13,11 @@ import (
// NewFunction creates a new function. // NewFunction creates a new function.
func NewFunction(pkg string, name string, file *fs.File, body []token.Token) *Function { func NewFunction(pkg string, name string, file *fs.File, body []token.Token) *Function {
return &Function{ return &Function{
Package: pkg, Package: pkg,
Name: name, Name: name,
File: file, UniqueName: pkg + "." + name,
Body: body, File: file,
Body: body,
Machine: register.Machine{ Machine: register.Machine{
Assembler: asm.Assembler{ Assembler: asm.Assembler{
Instructions: make([]asm.Instruction, 0, 8), Instructions: make([]asm.Instruction, 0, 8),

View File

@ -1,6 +1,8 @@
package register package register
import ( import (
"slices"
"git.akyoto.dev/cli/q/src/build/asm" "git.akyoto.dev/cli/q/src/build/asm"
"git.akyoto.dev/cli/q/src/build/cpu" "git.akyoto.dev/cli/q/src/build/cpu"
) )
@ -11,10 +13,8 @@ func (f *Machine) SaveRegister(register cpu.Register) {
return return
} }
for _, general := range f.CPU.General { if slices.Contains(f.CPU.General, register) {
if register == general { return
return
}
} }
variable := f.VariableByRegister(register) variable := f.VariableByRegister(register)

View File

@ -1,7 +1,6 @@
package scanner package scanner
import ( import (
"fmt"
"os" "os"
"path/filepath" "path/filepath"
@ -209,10 +208,6 @@ func (s *Scanner) scanFile(path string, pkg string) error {
name := tokens[nameStart].Text(contents) name := tokens[nameStart].Text(contents)
body := tokens[bodyStart:i] body := tokens[bodyStart:i]
if pkg != "" {
name = fmt.Sprintf("%s.%s", pkg, name)
}
function := core.NewFunction(pkg, name, file, body) function := core.NewFunction(pkg, name, file, body)
parameters := tokens[paramsStart:paramsEnd] parameters := tokens[paramsStart:paramsEnd]
count := 0 count := 0