slowly getting cleaner

master
Jordan Orelli 11 years ago
parent fb3b11d63c
commit 10c674b7f3

@ -2,10 +2,8 @@ package main
import (
"bufio"
"errors"
"fmt"
"io"
"reflect"
)
func eval(v interface{}, env *environment) (interface{}, error) {
@ -14,40 +12,10 @@ func eval(v interface{}, env *environment) (interface{}, error) {
}
switch t := v.(type) {
case symbol:
debugPrint("eval symbol")
s, err := env.get(t)
if err != nil {
return nil, err
}
return eval(s, env)
return t.eval(env)
case *sexp:
debugPrint("eval sexp")
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)
return t.eval(env)
default:
debugPrint("default eval")
return v, nil
@ -83,7 +51,6 @@ func (i interpreter) run(env *environment) {
v, err := parse(i.tokens)
switch err {
case io.EOF:
fmt.Println("EOF lol")
return
case nil:
i.eval(v, env)

@ -6,6 +6,7 @@ import (
"fmt"
"io"
"os"
"reflect"
"strconv"
"strings"
)
@ -17,6 +18,32 @@ type sexp struct {
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 {
call(*environment, []interface{}) (interface{}, error)
}
@ -46,6 +73,15 @@ func (s sexp) len() int {
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{}{
// predefined values
"#t": true,

Loading…
Cancel
Save