slowly getting cleaner

master
Jordan Orelli 11 years ago
parent fb3b11d63c
commit 10c674b7f3

@ -2,10 +2,8 @@ package main
import ( import (
"bufio" "bufio"
"errors"
"fmt" "fmt"
"io" "io"
"reflect"
) )
func eval(v interface{}, env *environment) (interface{}, error) { func eval(v interface{}, env *environment) (interface{}, error) {
@ -14,40 +12,10 @@ func eval(v interface{}, env *environment) (interface{}, error) {
} }
switch t := v.(type) { switch t := v.(type) {
case symbol: case symbol:
debugPrint("eval symbol") return t.eval(env)
s, err := env.get(t)
if err != nil {
return nil, err
}
return eval(s, env)
case *sexp: case *sexp:
debugPrint("eval sexp") return t.eval(env)
if t.len() == 0 {
return nil, errors.New("illegal evaluation of empty sexp ()")
}
if t.quotelvl > 0 {
return t, nil
}
// eval the first item
v, err := eval(t.items[0], env)
if err != nil {
return nil, err
}
c, ok := v.(callable)
if !ok {
return nil, fmt.Errorf(`expected special form or builtin procedure, received %v`, reflect.TypeOf(v))
}
if len(t.items) > 1 {
return c.call(env, t.items[1:])
}
return c.call(env, nil)
default: default:
debugPrint("default eval") debugPrint("default eval")
return v, nil return v, nil
@ -83,7 +51,6 @@ func (i interpreter) run(env *environment) {
v, err := parse(i.tokens) v, err := parse(i.tokens)
switch err { switch err {
case io.EOF: case io.EOF:
fmt.Println("EOF lol")
return return
case nil: case nil:
i.eval(v, env) i.eval(v, env)

@ -6,6 +6,7 @@ import (
"fmt" "fmt"
"io" "io"
"os" "os"
"reflect"
"strconv" "strconv"
"strings" "strings"
) )
@ -17,6 +18,32 @@ type sexp struct {
quotelvl int quotelvl int
} }
func (s *sexp) eval(env *environment) (interface{}, error) {
debugPrint("eval sexp")
if s.len() == 0 {
return nil, errors.New("illegal evaluation of empty sexp ()")
}
if s.quotelvl > 0 {
return s, nil
}
// eval the first item
v, err := eval(s.items[0], env)
if err != nil {
return nil, err
}
c, ok := v.(callable)
if !ok {
return nil, fmt.Errorf(`expected special form or builtin procedure, received %v`, reflect.TypeOf(v))
}
if len(s.items) > 1 {
return c.call(env, s.items[1:])
}
return c.call(env, nil)
}
type callable interface { type callable interface {
call(*environment, []interface{}) (interface{}, error) call(*environment, []interface{}) (interface{}, error)
} }
@ -46,6 +73,15 @@ func (s sexp) len() int {
type symbol string type symbol string
func (s symbol) eval(env *environment) (interface{}, error) {
debugPrint("eval symbol")
v, err := env.get(s)
if err != nil {
return nil, err
}
return eval(v, env)
}
var universe = &environment{map[symbol]interface{}{ var universe = &environment{map[symbol]interface{}{
// predefined values // predefined values
"#t": true, "#t": true,

Loading…
Cancel
Save