can now define variables

master
Jordan Orelli 12 years ago
parent 2b9322624f
commit 29677e19e4

@ -20,3 +20,7 @@ func (e environment) get(key symbol) (interface{}, error) {
} }
return nil, UnknownSymbolError{key} return nil, UnknownSymbolError{key}
} }
func (e environment) set(key symbol, val interface{}) {
e[key] = val
}

@ -16,14 +16,12 @@ type sexp []interface{}
type symbol string type symbol string
var universe = environment{ var universe = &environment{
"int": int64(5),
"float": float64(3.14),
"string": "Jordan",
"+": proc(addition), "+": proc(addition),
"-": proc(subtraction), "-": proc(subtraction),
"*": proc(multiplication), "*": proc(multiplication),
"/": proc(division), "/": proc(division),
"define": special(define),
} }
// parses the string lexeme into a value that can be eval'd // parses the string lexeme into a value that can be eval'd
@ -95,7 +93,7 @@ func parse(c chan token) (interface{}, error) {
return nil, io.EOF return nil, io.EOF
} }
func eval(v interface{}, env environment) (interface{}, error) { func eval(v interface{}, env *environment) (interface{}, error) {
switch t := v.(type) { switch t := v.(type) {
case symbol: case symbol:
@ -112,16 +110,26 @@ func eval(v interface{}, env environment) (interface{}, error) {
return nil, errors.New("illegal evaluation of empty sexp ()") return nil, errors.New("illegal evaluation of empty sexp ()")
} }
// get first element as symbol
s, ok := t[0].(symbol) s, ok := t[0].(symbol)
if !ok { if !ok {
return nil, errors.New("expected a symbol") return nil, errors.New("expected a symbol")
} }
// resolve symbol
v, err := env.get(s) v, err := env.get(s)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if spec, ok := v.(special); ok {
if len(t) > 1 {
return spec(env, t[1:]...)
} else {
return spec(env)
}
}
p, ok := v.(proc) p, ok := v.(proc)
if !ok { if !ok {
return nil, fmt.Errorf("expected proc, found %v", reflect.TypeOf(v)) return nil, fmt.Errorf("expected proc, found %v", reflect.TypeOf(v))
@ -156,7 +164,7 @@ func eval(v interface{}, env environment) (interface{}, error) {
return nil, nil return nil, nil
} }
func evalall(c chan token, env environment) { func evalall(c chan token, env *environment) {
for { for {
v, err := parse(c) v, err := parse(c)
switch err { switch err {

Loading…
Cancel
Save