|
|
@@ -84,14 +84,16 @@ func Eval(node ast.Node, env *object.Environment) object.Object {
|
|
|
}
|
|
|
|
|
|
func applyFunction(fn object.Object, args []object.Object) object.Object {
|
|
|
- function, ok := fn.(*object.Function)
|
|
|
- if !ok {
|
|
|
+ switch fn := fn.(type) {
|
|
|
+ case *object.Function:
|
|
|
+ extendEnv := extendFunctionEnv(fn, args)
|
|
|
+ evaluated := Eval(fn.Body, extendEnv)
|
|
|
+ return unwrapReturnValue(evaluated)
|
|
|
+ case *object.Builtin:
|
|
|
+ return fn.Fn(args...)
|
|
|
+ default:
|
|
|
return newError("not a function: %s", fn.Type())
|
|
|
}
|
|
|
-
|
|
|
- extendEnv := extendFunctionEnv(function, args)
|
|
|
- evaluated := Eval(function.Body, extendEnv)
|
|
|
- return unwrapReturnValue(evaluated)
|
|
|
}
|
|
|
|
|
|
func extendFunctionEnv(fn *object.Function, args []object.Object) *object.Environment {
|
|
|
@@ -249,11 +251,14 @@ func evalBangOperatorExpression(right object.Object) object.Object {
|
|
|
}
|
|
|
|
|
|
func evalIdentifier(node *ast.Identifier, env *object.Environment) object.Object {
|
|
|
- val, ok := env.Get(node.Value)
|
|
|
- if !ok {
|
|
|
- return newError("identifier not found: " + node.Value)
|
|
|
+ if val, ok := env.Get(node.Value); ok {
|
|
|
+ return val
|
|
|
+ }
|
|
|
+
|
|
|
+ if builtin, ok := builtins[node.Value]; ok {
|
|
|
+ return builtin
|
|
|
}
|
|
|
- return val
|
|
|
+ return newError("identifier not found: " + node.Value)
|
|
|
}
|
|
|
|
|
|
func evalExpressions(exps []ast.Expression, env *object.Environment) []object.Object {
|