diff --git a/src/asm/Instruction.go b/src/asm/Instruction.go index 5990c20..d8f9889 100644 --- a/src/asm/Instruction.go +++ b/src/asm/Instruction.go @@ -4,6 +4,12 @@ import "git.urbach.dev/cli/q/src/cpu" type Instruction interface{} +type AddRegisterRegister struct { + Destination cpu.Register + Source cpu.Register + Operand cpu.Register +} + type AndRegisterNumber struct { Destination cpu.Register Source cpu.Register diff --git a/src/asm/compilerARM.go b/src/asm/compilerARM.go index 46d3462..c6604c8 100644 --- a/src/asm/compilerARM.go +++ b/src/asm/compilerARM.go @@ -16,6 +16,8 @@ func (c *compiler) append(code uint32) { func (c *compilerARM) Compile(instr Instruction) { switch instr := instr.(type) { + case *AddRegisterRegister: + c.append(arm.AddRegisterRegister(instr.Destination, instr.Source, instr.Operand)) case *Call: start := len(c.code) c.append(arm.Call(0)) diff --git a/src/asm/compilerX86.go b/src/asm/compilerX86.go index 1eb7a10..61977f4 100644 --- a/src/asm/compilerX86.go +++ b/src/asm/compilerX86.go @@ -14,18 +14,18 @@ type compilerX86 struct { func (c *compilerX86) Compile(instr Instruction) { switch instr := instr.(type) { + case *AddRegisterRegister: + if instr.Destination != instr.Source { + c.code = x86.MoveRegisterRegister(c.code, instr.Destination, instr.Source) + } + + c.code = x86.AddRegisterRegister(c.code, instr.Destination, instr.Operand) case *AndRegisterNumber: if instr.Destination != instr.Source { c.code = x86.MoveRegisterRegister(c.code, instr.Destination, instr.Source) } c.code = x86.AndRegisterNumber(c.code, instr.Destination, instr.Number) - case *SubRegisterNumber: - if instr.Destination != instr.Source { - c.code = x86.MoveRegisterRegister(c.code, instr.Destination, instr.Source) - } - - c.code = x86.SubRegisterNumber(c.code, instr.Destination, instr.Number) case *Call: c.code = x86.Call(c.code, 0) end := len(c.code) @@ -102,6 +102,12 @@ func (c *compilerX86) Compile(instr Instruction) { c.code = x86.MoveRegisterRegister(c.code, instr.Destination, instr.Source) case *Return: c.code = x86.Return(c.code) + case *SubRegisterNumber: + if instr.Destination != instr.Source { + c.code = x86.MoveRegisterRegister(c.code, instr.Destination, instr.Source) + } + + c.code = x86.SubRegisterNumber(c.code, instr.Destination, instr.Number) case *Syscall: c.code = x86.Syscall(c.code) default: diff --git a/src/core/Evaluate.go b/src/core/Evaluate.go index 1af8a0f..2e75bd1 100644 --- a/src/core/Evaluate.go +++ b/src/core/Evaluate.go @@ -211,6 +211,32 @@ func (f *Function) Evaluate(expr *expression.Expression) (ssa.Value, error) { return nil, errors.New(&UnknownIdentifier{Name: label}, f.File, left.Token.Position) default: + if expr.Token.IsOperator() { + left := expr.Children[0] + right := expr.Children[1] + + leftValue, err := f.Evaluate(left) + + if err != nil { + return nil, err + } + + rightValue, err := f.Evaluate(right) + + if err != nil { + return nil, err + } + + v := f.Append(&ssa.BinaryOp{ + Left: leftValue, + Right: rightValue, + Op: expr.Token.Kind, + Source: ssa.Source(expr.Source), + }) + + return v, nil + } + panic("not implemented") } } \ No newline at end of file diff --git a/src/ssa2asm/ValueToRegister.go b/src/ssa2asm/ValueToRegister.go index 850074d..89c4d51 100644 --- a/src/ssa2asm/ValueToRegister.go +++ b/src/ssa2asm/ValueToRegister.go @@ -12,6 +12,16 @@ import ( // ValueToRegister moves a value into the given `destination` register. func (f *Compiler) ValueToRegister(instr ssa.Value, destination cpu.Register) { switch instr := instr.(type) { + case *ssa.BinaryOp: + f.ValueToRegister(instr.Left, destination) + f.ValueToRegister(instr.Right, 7) + + f.Assembler.Append(&asm.AddRegisterRegister{ + Destination: destination, + Source: destination, + Operand: 7, + }) + case *ssa.Bytes: f.Count.Data++ label := f.CreateLabel("data", f.Count.Data) diff --git a/tests/sum.q b/tests/sum.q new file mode 100644 index 0000000..abd95d6 --- /dev/null +++ b/tests/sum.q @@ -0,0 +1,10 @@ +main() { + t1 := sum(1, 2) + t2 := sum(3, 4) + t3 := sum(t1, t2) + syscall(60, t3) +} + +sum(a int, b int) -> int { + return a + b +} \ No newline at end of file