q/src/build/TokenToRegister.go

60 lines
1.3 KiB
Go

package build
import (
"strconv"
"git.akyoto.dev/cli/q/src/build/asm"
"git.akyoto.dev/cli/q/src/build/config"
"git.akyoto.dev/cli/q/src/build/cpu"
"git.akyoto.dev/cli/q/src/build/token"
"git.akyoto.dev/cli/q/src/errors"
)
// TokenToRegister moves a token into a register.
// It only works with identifiers, numbers and strings.
func (f *Function) TokenToRegister(t token.Token, register cpu.Register) error {
switch t.Kind {
case token.Identifier:
name := t.Text()
constant, exists := f.definitions[name]
if exists {
if config.Verbose {
f.Logf("constant %s = %s", constant.Name, constant.Value)
}
return f.ExpressionToRegister(constant.Value, register)
}
variable, exists := f.variables[name]
if !exists {
return errors.New(&errors.UnknownIdentifier{Name: name}, f.File, t.Position)
}
if register != variable.Register {
f.assembler.RegisterRegister(asm.MOVE, register, variable.Register)
}
f.useVariable(variable)
return nil
case token.Number:
value := t.Text()
n, err := strconv.Atoi(value)
if err != nil {
return err
}
f.assembler.RegisterNumber(asm.MOVE, register, n)
return nil
case token.String:
return errors.New(errors.NotImplemented, f.File, t.Position)
default:
return errors.New(errors.InvalidExpression, f.File, t.Position)
}
}