97 lines
1.8 KiB
Go
97 lines
1.8 KiB
Go
package core
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"fmt"
|
|
|
|
"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 := f.VariableByName(name)
|
|
|
|
if variable != nil {
|
|
f.UseVariable(variable)
|
|
return &variable.Value, nil
|
|
}
|
|
|
|
uniqueName := fmt.Sprintf("%s.%s", f.Package, name)
|
|
function, exists := f.All.Functions[uniqueName]
|
|
|
|
if exists {
|
|
f.Dependencies = append(f.Dependencies, function)
|
|
|
|
value := &eval.Label{
|
|
Typ: types.AnyPointer,
|
|
Label: asm.Label{
|
|
Name: function.UniqueName,
|
|
Type: asm.FunctionLabel,
|
|
},
|
|
}
|
|
|
|
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)
|
|
}
|