added *if*

master
Jordan Orelli 12 years ago
parent 107565dc04
commit ec5cbdcaab

@ -11,6 +11,10 @@
; string ; string
"jordan" "jordan"
; booleans. I don't like the look of #t and #f. They're dumb.
true
false
; ------------------------------------------------------------------------------ ; ------------------------------------------------------------------------------
; basic math ; basic math
; ------------------------------------------------------------------------------ ; ------------------------------------------------------------------------------
@ -28,3 +32,7 @@
x x
(quote 1 2 3) (quote 1 2 3)
(if 1 2 3)
(if false 2 3)
(if true 2 3)

@ -21,12 +21,15 @@ func (s sexp) String() string {
type symbol string type symbol string
var universe = &environment{ var universe = &environment{
"true": true,
"false": false,
"+": proc(addition), "+": proc(addition),
"-": proc(subtraction), "-": proc(subtraction),
"*": proc(multiplication), "*": proc(multiplication),
"/": proc(division), "/": proc(division),
"define": special(define), "define": special(define),
"quote": special(quote), "quote": special(quote),
"if": special(_if),
} }
// parses the string lexeme into a value that can be eval'd // parses the string lexeme into a value that can be eval'd
@ -178,6 +181,7 @@ func evalall(c chan token, env *environment) {
case nil: case nil:
if v, err := eval(v, env); err != nil { if v, err := eval(v, env); err != nil {
fmt.Println("error:", err) fmt.Println("error:", err)
return
} else { } else {
fmt.Println(v) fmt.Println(v)
} }

@ -22,3 +22,17 @@ func define(env *environment, args ...interface{}) (interface{}, error) {
func quote(_ *environment, args ...interface{}) (interface{}, error) { func quote(_ *environment, args ...interface{}) (interface{}, error) {
return sexp(args), nil return sexp(args), nil
} }
func _if(env *environment, args ...interface{}) (interface{}, error) {
if len(args) != 3 {
return nil, fmt.Errorf(`received %d arguments in *if*, expected exactly 3`, len(args))
}
v, err := eval(args[0], env)
if err != nil {
return nil, err
}
if b, ok := v.(bool); ok && !b {
return eval(args[2], env)
}
return eval(args[1], env)
}

Loading…
Cancel
Save