added `and`, `or`, and `=`

the equality implementation is probably wrong.
master
Jordan Orelli 11 years ago
parent db4c1a5e58
commit 688c880065

@ -99,3 +99,13 @@ var lte = builtin{
return cmp_left(vals, fni, fnf)
},
}
var equals = builtin{
name: "=",
variadic: true,
fn: func(vals []interface{}) (interface{}, error) {
fni := func(x, y int64) bool { return x == y }
fnf := func(x, y float64) bool { return x == y }
return cmp_left(vals, fni, fnf)
},
}

@ -63,6 +63,9 @@ var universe = &environment{map[symbol]interface{}{
symbol(gte.name): gte,
symbol(lt.name): lt,
symbol(lte.name): lte,
symbol(equals.name): equals,
symbol(and.name): and,
symbol(or.name): or,
symbol(cons.name): cons,
symbol(car.name): car,
symbol(cdr.name): cdr,

@ -141,9 +141,18 @@ func booleanize(v interface{}) bool {
//
// would evaluate to "bar"
var _if = special{
name: "if",
arity: 3,
name: "if",
arity: 2,
variadic: true,
fn: func(env *environment, args []interface{}) (interface{}, error) {
if len(args) > 3 {
return nil, arityError{
expected: 3,
received: len(args),
name: "ifpooop",
variadic: false,
}
}
v, err := eval(args[0], env)
if err != nil {
return nil, err
@ -152,7 +161,10 @@ var _if = special{
if booleanize(v) {
return eval(args[1], env)
}
return eval(args[2], env)
if len(args) == 3 {
return eval(args[2], env)
}
return nil, nil
},
}
@ -281,3 +293,39 @@ var names = special{
return env.keys(), nil
},
}
var and = special{
name: "and",
arity: 1,
variadic: true,
fn: func(env *environment, args []interface{}) (interface{}, error) {
for _, v := range args {
t, err := eval(v, env)
if err != nil {
return false, err
}
if !booleanize(t) {
return false, nil
}
}
return true, nil
},
}
var or = special{
name: "or",
arity: 1,
variadic: true,
fn: func(env *environment, args []interface{}) (interface{}, error) {
for _, v := range args {
t, err := eval(v, env)
if err != nil {
return false, err
}
if booleanize(t) {
return true, nil
}
}
return false, nil
},
}

Loading…
Cancel
Save