q/src/core/EvaluateCall.go

68 lines
1.4 KiB
Go

package core
import (
"git.urbach.dev/cli/q/src/errors"
"git.urbach.dev/cli/q/src/eval"
"git.urbach.dev/cli/q/src/expression"
"git.urbach.dev/cli/q/src/token"
"git.urbach.dev/cli/q/src/types"
)
// EvaluateCall evaluates a function call.
func (f *Function) EvaluateCall(expr *expression.Expression) (eval.Value, error) {
if expr.Children[0].Token.Kind == token.Identifier {
nameNode := expr.Children[0]
name := nameNode.String(f.File.Bytes)
typ := types.ByName(name, f.Package, f.All.Structs)
if typ != nil {
if len(expr.Children) != 2 {
return nil, errors.New(&errors.ParameterCountMismatch{Function: name, Count: len(expr.Children), ExpectedCount: 1}, f.File, nameNode.Token.End())
}
value, err := f.Evaluate(expr.Children[1])
if err != nil {
return nil, err
}
switch value := value.(type) {
case *eval.Register:
if value.IsAlive() {
value = &eval.Register{
Typ: typ,
Register: value.Register,
Alive: value.Alive,
}
return value, nil
}
value.Typ = typ
case *eval.Number:
value.Typ = typ
case *eval.Memory:
value.Typ = typ
case *eval.Label:
value.Typ = typ
}
return value, nil
}
}
typ, err := f.CompileCall(expr)
if err != nil {
return nil, err
}
value := &eval.Register{Register: f.CPU.Output[0]}
if len(typ) > 0 {
value.Typ = typ[0]
}
return value, nil
}