Add support for the IF special form
This commit is contained in:
parent
90888a7bcd
commit
c2326ae546
|
@ -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
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue