Eval complete

This commit is contained in:
Chuck Smith
2024-01-20 11:16:56 -05:00
parent 581573486c
commit 10821fc88a
4 changed files with 183 additions and 4 deletions

View File

@@ -52,6 +52,11 @@ func Eval(node ast.Node, env *object.Environment) object.Object {
case *ast.Identifier:
return evalIdentifier(node, env)
case *ast.FunctionLiteral:
params := node.Parameters
body := node.Body
return &object.Function{Parameters: params, Env: env, Body: body}
// Expressions
case *ast.IntegerLiteral:
return &object.Integer{Value: node.Value}
@@ -77,6 +82,18 @@ func Eval(node ast.Node, env *object.Environment) object.Object {
}
return evalInfixExpression(node.Operator, left, right)
case *ast.CallExpression:
function := Eval(node.Function, env)
if isError(function) {
return function
}
args := evalExpressions(node.Arguments, env)
if len(args) == 1 && isError(args[0]) {
return args[0]
}
return applyFunction(function, args)
}
return nil
@@ -237,3 +254,46 @@ func evalIdentifier(node *ast.Identifier, env *object.Environment) object.Object
}
return val
}
func evalExpressions(exps []ast.Expression, env *object.Environment) []object.Object {
var result []object.Object
for _, e := range exps {
evaluated := Eval(e, env)
if isError(evaluated) {
return []object.Object{evaluated}
}
result = append(result, evaluated)
}
return result
}
func applyFunction(fn object.Object, args []object.Object) object.Object {
function, ok := fn.(*object.Function)
if !ok {
newError("not a function: %s", fn.Type())
}
extendedEnv := extendFunctionEnv(function, args)
evaluated := Eval(function.Body, extendedEnv)
return unwrapReturnValue(evaluated)
}
func extendFunctionEnv(fn *object.Function, args []object.Object) *object.Environment {
env := object.NewEnclosedEnvironment(fn.Env)
for paramIdx, param := range fn.Parameters {
env.Set(param.Value, args[paramIdx])
}
return env
}
func unwrapReturnValue(obj object.Object) object.Object {
if returnValue, ok := obj.(*object.ReturnValue); ok {
return returnValue.Value
}
return obj
}