Add support for the IF special form

This commit is contained in:
Sameer Rahmani 2020-11-25 13:15:19 +00:00
parent 90888a7bcd
commit c2326ae546
2 changed files with 29 additions and 3 deletions

View File

@ -161,9 +161,9 @@ tco:
ret, err = Fn(rt, scope, list.Rest().(*List))
break tco // return
// case "if":
// ret, err = If(rt, scope, list.Rest().(*List))
// break tco // return
case "if":
ret, err = If(rt, scope, list.Rest().(*List))
break tco // return
// list evaluation rules:
// * The first element of the list has to be an expression which is callable

View File

@ -79,3 +79,29 @@ func Fn(rt *Runtime, scope IScope, args *List) (IExpr, IError) {
return MakeFunction(scope, params, body), nil
}
// If defines a conditional expression which evaluates the first
// element of the given `args` as the conditional and if the result
// is truthy evaluates and returns the second arg otherwise does the
// same for the third arg.
func If(rt *Runtime, scope IScope, args *List) (IExpr, IError) {
if args.Count() != 3 {
return nil, MakeError(rt, "'if' needs exactly 3 aruments")
}
pred, err := EvalForms(rt, scope, args.First())
result := pred.GetType()
if err != nil {
return nil, err
}
if result != ast.False && result != ast.Nil {
// Truthy clause
return EvalForms(rt, scope, args.Rest().First())
}
// Falsy clause
return EvalForms(rt, scope, args.Rest().Rest().First())
}