implemented set!

master
Jordan Orelli 12 years ago
parent ec5cbdcaab
commit ba1bab1e39

@ -24,3 +24,8 @@ func (e environment) get(key symbol) (interface{}, error) {
func (e environment) set(key symbol, val interface{}) {
e[key] = val
}
func (e environment) defined(key symbol) bool {
_, ok := e[key]
return ok
}

@ -12,8 +12,8 @@
"jordan"
; booleans. I don't like the look of #t and #f. They're dumb.
true
false
#t
#f
; ------------------------------------------------------------------------------
; basic math
@ -30,9 +30,10 @@ false
(define x 5)
x
(set! x "steve")
x
(quote 1 2 3)
(if 1 2 3)
(if false 2 3)
(if true 2 3)
(if #f (quote "true-value") (quote "false-value"))
(if #t (quote "true-value") (quote "false-value"))

@ -21,8 +21,8 @@ func (s sexp) String() string {
type symbol string
var universe = &environment{
"true": true,
"false": false,
"#t": true,
"#f": false,
"+": proc(addition),
"-": proc(subtraction),
"*": proc(multiplication),
@ -30,6 +30,7 @@ var universe = &environment{
"define": special(define),
"quote": special(quote),
"if": special(_if),
"set!": special(set),
}
// parses the string lexeme into a value that can be eval'd
@ -183,7 +184,9 @@ func evalall(c chan token, env *environment) {
fmt.Println("error:", err)
return
} else {
fmt.Println(v)
if v != nil {
fmt.Println(v)
}
}
default:
fmt.Println("error in eval: %v", err)

@ -15,7 +15,11 @@ func define(env *environment, args ...interface{}) (interface{}, error) {
if !ok {
return nil, fmt.Errorf(`first argument to *define* must be symbol, received %v`, reflect.TypeOf(args[0]))
}
env.set(s, args[1])
v, err := eval(args[1], env)
if err != nil {
return nil, err
}
env.set(s, v)
return nil, nil
}
@ -36,3 +40,22 @@ func _if(env *environment, args ...interface{}) (interface{}, error) {
}
return eval(args[1], env)
}
func set(env *environment, args ...interface{}) (interface{}, error) {
if len(args) != 2 {
return nil, fmt.Errorf(`received %d arguments in *set!*, expected exactly 2`, len(args))
}
s, ok := args[0].(symbol)
if !ok {
return nil, fmt.Errorf(`first argument to *set!* must be symbol, received %v`, reflect.TypeOf(args[0]))
}
if !env.defined(s) {
return nil, fmt.Errorf(`cannot *set!* undefined symbol %v`, s)
}
v, err := eval(args[1], env)
if err != nil {
return nil, err
}
env.set(s, v)
return nil, nil
}

Loading…
Cancel
Save