60 lines
1.3 KiB
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)
|
|
}
|
|
}
|