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) }