Improved label consistency

This commit is contained in:
Eduard Urbach 2025-02-21 17:04:13 +01:00
parent 08436c31c0
commit 4caac57210
Signed by: akyoto
GPG Key ID: C874F672B1AF20C0
11 changed files with 36 additions and 31 deletions

View File

@ -23,7 +23,7 @@ func (c *compiler) move(x asm.Instruction) {
opSize := len(c.code) - size - start opSize := len(c.code) - size - start
regLabel := x.Data.(*asm.RegisterLabel) regLabel := x.Data.(*asm.RegisterLabel)
if strings.HasPrefix(regLabel.Label, "data_") { if strings.HasPrefix(regLabel.Label, "data ") {
c.dataPointers = append(c.dataPointers, &pointer{ c.dataPointers = append(c.dataPointers, &pointer{
Position: Address(len(c.code) - size), Position: Address(len(c.code) - size),
OpSize: uint8(opSize), OpSize: uint8(opSize),

View File

@ -1,13 +1,9 @@
package core package core
import (
"fmt"
)
// 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("data_%s_%d", f.UniqueName, f.count.data) label := f.CreateLabel("data", f.count.data)
f.Assembler.SetData(label, value) f.Assembler.SetData(label, value)
return label return label
} }

View File

@ -20,6 +20,7 @@ func (f *Function) ArrayElementToRegister(node *expression.Expression, register
return nil, errors.New(&errors.UnknownIdentifier{Name: name}, f.File, node.Children[0].Token.Position) return nil, errors.New(&errors.UnknownIdentifier{Name: name}, f.File, node.Children[0].Token.Position)
} }
defer f.UseVariable(array)
index := node.Children[1] index := node.Children[1]
memory := asm.Memory{ memory := asm.Memory{

View File

@ -1,8 +1,6 @@
package core package core
import ( import (
"fmt"
"git.akyoto.dev/cli/q/src/asm" "git.akyoto.dev/cli/q/src/asm"
"git.akyoto.dev/cli/q/src/ast" "git.akyoto.dev/cli/q/src/ast"
) )
@ -10,8 +8,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.UniqueName, f.count.assert) success := f.CreateLabel("assert true", f.count.assert)
fail := fmt.Sprintf("%s_assert_%d_false", f.UniqueName, f.count.assert) fail := f.CreateLabel("assert false", 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

@ -38,7 +38,9 @@ func (f *Function) CompileAssignDivision(node *ast.Assign) error {
divisor := right.Children[1] divisor := right.Children[1]
err = f.Execute(right.Token, dividendRegister, divisor) err = f.Execute(right.Token, dividendRegister, divisor)
f.RegisterRegister(asm.MOVE, quotientVariable.Register, x86.RAX) f.RegisterRegister(asm.MOVE, quotientVariable.Register, x86.RAX)
f.UseVariable(quotientVariable)
f.RegisterRegister(asm.MOVE, remainderVariable.Register, x86.RDX) f.RegisterRegister(asm.MOVE, remainderVariable.Register, x86.RDX)
f.UseVariable(remainderVariable)
if isTemporary { if isTemporary {
f.FreeRegister(dividendRegister) f.FreeRegister(dividendRegister)

View File

@ -1,8 +1,6 @@
package core package core
import ( import (
"fmt"
"git.akyoto.dev/cli/q/src/expression" "git.akyoto.dev/cli/q/src/expression"
"git.akyoto.dev/cli/q/src/token" "git.akyoto.dev/cli/q/src/token"
) )
@ -12,7 +10,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.UniqueName, f.count.subBranch) leftFailLabel := f.CreateLabel("false", f.count.subBranch)
// Left // Left
left := condition.Children[0] left := condition.Children[0]
@ -39,7 +37,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.UniqueName, f.count.subBranch) leftSuccessLabel := f.CreateLabel("true", f.count.subBranch)
// Left // Left
left := condition.Children[0] left := condition.Children[0]

View File

@ -1,8 +1,6 @@
package core package core
import ( import (
"fmt"
"git.akyoto.dev/cli/q/src/asm" "git.akyoto.dev/cli/q/src/asm"
"git.akyoto.dev/cli/q/src/ast" "git.akyoto.dev/cli/q/src/ast"
"git.akyoto.dev/cli/q/src/cpu" "git.akyoto.dev/cli/q/src/cpu"
@ -19,8 +17,8 @@ func (f *Function) CompileFor(loop *ast.For) error {
f.count.loop++ f.count.loop++
var ( var (
label = fmt.Sprintf("%s_loop_%d", f.UniqueName, f.count.loop) label = f.CreateLabel("for", f.count.loop)
labelEnd = fmt.Sprintf("%s_loop_%d_end", f.UniqueName, f.count.loop) labelEnd = f.CreateLabel("for end", f.count.loop)
counter cpu.Register counter cpu.Register
from *expression.Expression from *expression.Expression
to *expression.Expression to *expression.Expression

View File

@ -1,8 +1,6 @@
package core package core
import ( import (
"fmt"
"git.akyoto.dev/cli/q/src/asm" "git.akyoto.dev/cli/q/src/asm"
"git.akyoto.dev/cli/q/src/ast" "git.akyoto.dev/cli/q/src/ast"
) )
@ -17,8 +15,8 @@ func (f *Function) CompileIf(branch *ast.If) error {
var ( var (
end string end string
success = fmt.Sprintf("%s_if_%d_true", f.UniqueName, f.count.branch) success = f.CreateLabel("if true", f.count.branch)
fail = fmt.Sprintf("%s_if_%d_false", f.UniqueName, f.count.branch) fail = f.CreateLabel("if false", f.count.branch)
err = f.CompileCondition(branch.Condition, success, fail) err = f.CompileCondition(branch.Condition, success, fail)
) )
@ -35,7 +33,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.UniqueName, f.count.branch) end = f.CreateLabel("if end", f.count.branch)
f.Jump(asm.JUMP, end) f.Jump(asm.JUMP, end)
} }

View File

@ -1,8 +1,6 @@
package core package core
import ( import (
"fmt"
"git.akyoto.dev/cli/q/src/asm" "git.akyoto.dev/cli/q/src/asm"
"git.akyoto.dev/cli/q/src/ast" "git.akyoto.dev/cli/q/src/ast"
) )
@ -14,7 +12,7 @@ func (f *Function) CompileLoop(loop *ast.Loop) error {
} }
f.count.loop++ f.count.loop++
label := fmt.Sprintf("%s_loop_%d", f.UniqueName, f.count.loop) label := f.CreateLabel("loop", 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

@ -1,8 +1,6 @@
package core package core
import ( import (
"fmt"
"git.akyoto.dev/cli/q/src/asm" "git.akyoto.dev/cli/q/src/asm"
"git.akyoto.dev/cli/q/src/ast" "git.akyoto.dev/cli/q/src/ast"
) )
@ -10,7 +8,7 @@ import (
// CompileSwitch compiles a multi-branch instruction. // CompileSwitch compiles a multi-branch instruction.
func (f *Function) CompileSwitch(s *ast.Switch) error { func (f *Function) CompileSwitch(s *ast.Switch) error {
f.count.multiBranch++ f.count.multiBranch++
end := fmt.Sprintf("%s_switch_%d_end", f.UniqueName, f.count.multiBranch) end := f.CreateLabel("switch end", f.count.multiBranch)
for _, branch := range s.Cases { for _, branch := range s.Cases {
if branch.Condition == nil { if branch.Condition == nil {
@ -28,8 +26,8 @@ func (f *Function) CompileSwitch(s *ast.Switch) error {
f.count.branch++ f.count.branch++
var ( var (
success = fmt.Sprintf("%s_case_%d_true", f.UniqueName, f.count.branch) success = f.CreateLabel("case true", f.count.branch)
fail = fmt.Sprintf("%s_case_%d_false", f.UniqueName, f.count.branch) fail = f.CreateLabel("case false", f.count.branch)
err = f.CompileCondition(branch.Condition, success, fail) err = f.CompileCondition(branch.Condition, success, fail)
) )

18
src/core/CreateLabel.go Normal file
View File

@ -0,0 +1,18 @@
package core
import (
"strconv"
"strings"
)
// CreateLabel creates a label that is tied to this function by using a suffix.
func (f *Function) CreateLabel(prefix string, count int) string {
tmp := strings.Builder{}
tmp.WriteString(prefix)
tmp.WriteString(" ")
tmp.WriteString(strconv.Itoa(count))
tmp.WriteString(" [")
tmp.WriteString(f.UniqueName)
tmp.WriteString("]")
return tmp.String()
}