Simplified expression evaluation
This commit is contained in:
100
src/core/EvaluateToken.go
Normal file
100
src/core/EvaluateToken.go
Normal file
@ -0,0 +1,100 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
|
||||
"git.urbach.dev/cli/q/src/asm"
|
||||
"git.urbach.dev/cli/q/src/errors"
|
||||
"git.urbach.dev/cli/q/src/eval"
|
||||
"git.urbach.dev/cli/q/src/token"
|
||||
"git.urbach.dev/cli/q/src/types"
|
||||
)
|
||||
|
||||
// EvaluateToken evaluates a single token.
|
||||
func (f *Function) EvaluateToken(t token.Token) (eval.Value, error) {
|
||||
switch t.Kind {
|
||||
case token.Identifier:
|
||||
name := t.Text(f.File.Bytes)
|
||||
|
||||
if name == "true" {
|
||||
value := eval.Number{
|
||||
Typ: types.Bool,
|
||||
Number: 1,
|
||||
}
|
||||
|
||||
return value, nil
|
||||
}
|
||||
|
||||
if name == "false" {
|
||||
value := eval.Number{
|
||||
Typ: types.Bool,
|
||||
Number: 0,
|
||||
}
|
||||
|
||||
return value, nil
|
||||
}
|
||||
|
||||
variable, function := f.Identifier(name)
|
||||
|
||||
if variable != nil {
|
||||
f.UseVariable(variable)
|
||||
|
||||
if variable.Value.Alive == 0 {
|
||||
return variable.Value, nil
|
||||
}
|
||||
|
||||
tmp := f.NewRegister()
|
||||
f.RegisterRegister(asm.MOVE, tmp, variable.Value.Register)
|
||||
|
||||
value := eval.Register{
|
||||
Typ: variable.Value.Typ,
|
||||
Register: tmp,
|
||||
}
|
||||
|
||||
return value, nil
|
||||
}
|
||||
|
||||
if function != nil {
|
||||
value := eval.Label{
|
||||
Typ: types.AnyPointer,
|
||||
Label: function.UniqueName,
|
||||
}
|
||||
|
||||
return value, nil
|
||||
}
|
||||
|
||||
return nil, errors.New(&errors.UnknownIdentifier{Name: name}, f.File, t.Position)
|
||||
|
||||
case token.Number, token.Rune:
|
||||
number, err := f.ToNumber(t)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
value := eval.Number{
|
||||
Typ: types.AnyInt,
|
||||
Number: number,
|
||||
}
|
||||
|
||||
return value, nil
|
||||
|
||||
case token.String:
|
||||
data := t.Bytes(f.File.Bytes)
|
||||
data = String(data)
|
||||
|
||||
slice := make([]byte, len(data)+8+1)
|
||||
binary.LittleEndian.PutUint64(slice, uint64(len(data)))
|
||||
copy(slice[8:], data)
|
||||
label := f.AddBytes(slice)
|
||||
|
||||
value := eval.Label{
|
||||
Typ: types.String,
|
||||
Label: label,
|
||||
}
|
||||
|
||||
return value, nil
|
||||
}
|
||||
|
||||
return nil, errors.New(errors.InvalidExpression, f.File, t.Position)
|
||||
}
|
Reference in New Issue
Block a user