Implemented if statements

This commit is contained in:
2024-07-07 12:30:57 +02:00
parent 6fc234c700
commit 91e300e49a
16 changed files with 280 additions and 14 deletions

View File

@ -0,0 +1,48 @@
package core
import (
"fmt"
"git.akyoto.dev/cli/q/src/build/asm"
"git.akyoto.dev/cli/q/src/build/ast"
)
// CompileIf compiles a branch instruction.
func (f *Function) CompileIf(branch *ast.If) error {
condition := branch.Condition
tmpRight := f.cpu.Input[1]
err := f.ExpressionToRegister(condition.Children[1], tmpRight)
if err != nil {
return err
}
tmpLeft := f.cpu.Input[0]
err = f.ExpressionToRegister(condition.Children[0], tmpLeft)
if err != nil {
return err
}
f.assembler.RegisterRegister(asm.COMPARE, tmpLeft, tmpRight)
elseLabel := fmt.Sprintf("%s_if_%d_else", f.Name, f.count.branch)
switch condition.Token.Text() {
case "==":
f.assembler.Label(asm.JNE, elseLabel)
case "!=":
f.assembler.Label(asm.JE, elseLabel)
case ">":
f.assembler.Label(asm.JLE, elseLabel)
case "<":
f.assembler.Label(asm.JGE, elseLabel)
case ">=":
f.assembler.Label(asm.JL, elseLabel)
case "<=":
f.assembler.Label(asm.JG, elseLabel)
}
defer f.assembler.Label(asm.LABEL, elseLabel)
f.count.branch++
return f.CompileAST(branch.Body)
}

View File

@ -3,13 +3,14 @@ package core
import (
"fmt"
"git.akyoto.dev/cli/q/src/build/asm"
"git.akyoto.dev/cli/q/src/build/ast"
)
// CompileLoop compiles a loop instruction.
func (f *Function) CompileLoop(loop *ast.Loop) error {
label := fmt.Sprintf("%s_loop_%d", f.Name, f.count.loop)
f.assembler.Label(label)
f.assembler.Label(asm.LABEL, label)
defer f.assembler.Jump(label)
f.count.loop++
return f.CompileAST(loop.Body)

View File

@ -45,7 +45,7 @@ func NewFunction(name string, file *fs.File, body token.List) *Function {
// Compile turns a function into machine code.
func (f *Function) Compile() {
defer close(f.finished)
f.assembler.Label(f.Name)
f.assembler.Label(asm.LABEL, f.Name)
f.err = f.CompileTokens(f.Body)
f.assembler.Return()
}
@ -90,6 +90,9 @@ func (f *Function) CompileASTNode(node ast.Node) error {
case *ast.Return:
return f.CompileReturn(node)
case *ast.If:
return f.CompileIf(node)
case *ast.Loop:
return f.CompileLoop(node)

View File

@ -21,7 +21,8 @@ type state struct {
// counter stores how often a certain statement appeared so we can generate a unique label from it.
type counter struct {
loop int
loop int
branch int
}
// PrintInstructions shows the assembly instructions.