Implemented data labels
This commit is contained in:
@ -31,6 +31,11 @@ func (f *Function) ExecuteLeaf(operation token.Token, register cpu.Register, ope
|
||||
}
|
||||
|
||||
return f.ExecuteRegisterNumber(operation, register, number)
|
||||
|
||||
case token.String:
|
||||
if operation.Text() == "=" {
|
||||
return f.TokenToRegister(operand, register)
|
||||
}
|
||||
}
|
||||
|
||||
return errors.New(errors.NotImplemented, f.File, operation.Position)
|
||||
|
@ -27,6 +27,7 @@ func NewFunction(name string, file *fs.File, body token.List) *Function {
|
||||
state: state{
|
||||
assembler: asm.Assembler{
|
||||
Instructions: make([]asm.Instruction, 0, 32),
|
||||
Data: map[string][]byte{},
|
||||
},
|
||||
cpu: cpu.CPU{
|
||||
All: x64.AllRegisters,
|
||||
|
@ -53,6 +53,20 @@ func (f *Function) RegisterNumber(mnemonic asm.Mnemonic, a cpu.Register, b int)
|
||||
f.postInstruction()
|
||||
}
|
||||
|
||||
func (f *Function) RegisterLabel(mnemonic asm.Mnemonic, register cpu.Register, label string) {
|
||||
if f.cpu.IsUsed(register) && isDestructive(mnemonic) {
|
||||
f.SaveRegister(register)
|
||||
}
|
||||
|
||||
f.assembler.RegisterLabel(mnemonic, register, label)
|
||||
|
||||
if mnemonic == asm.MOVE {
|
||||
f.cpu.Use(register)
|
||||
}
|
||||
|
||||
f.postInstruction()
|
||||
}
|
||||
|
||||
func (f *Function) RegisterRegister(mnemonic asm.Mnemonic, a cpu.Register, b cpu.Register) {
|
||||
if mnemonic == asm.MOVE && a == b {
|
||||
return
|
||||
|
@ -25,6 +25,7 @@ func (r *Result) finalize() ([]byte, []byte) {
|
||||
// a return address on the stack, which allows return statements in `main`.
|
||||
final := asm.Assembler{
|
||||
Instructions: make([]asm.Instruction, 0, r.InstructionCount+4),
|
||||
Data: map[string][]byte{},
|
||||
}
|
||||
|
||||
final.Call("main")
|
||||
|
@ -1,6 +1,7 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"git.akyoto.dev/cli/q/src/build/asm"
|
||||
@ -37,7 +38,12 @@ func (f *Function) TokenToRegister(t token.Token, register cpu.Register) error {
|
||||
return nil
|
||||
|
||||
case token.String:
|
||||
return errors.New(errors.NotImplemented, f.File, t.Position)
|
||||
value := t.Text()[1 : len(t.Bytes)-1]
|
||||
label := fmt.Sprintf("%s_data_%d", f.Name, f.count.data)
|
||||
f.assembler.Data[label] = []byte(value)
|
||||
f.RegisterLabel(asm.MOVE, register, label)
|
||||
f.count.data++
|
||||
return nil
|
||||
|
||||
default:
|
||||
return errors.New(errors.InvalidExpression, f.File, t.Position)
|
||||
|
@ -23,8 +23,9 @@ 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
|
||||
branch int
|
||||
data int
|
||||
loop int
|
||||
subBranch int
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user