fixed quote bug

master
Jordan Orelli 12 years ago
parent c4fed38dd9
commit b387d909b5

@ -144,13 +144,11 @@ var length = builtin{
name: "length", name: "length",
arity: 1, arity: 1,
fn: func(vals []interface{}) (interface{}, error) { fn: func(vals []interface{}) (interface{}, error) {
switch t := vals[0].(type) { s, ok := vals[0].(*sexp)
case sexp: if !ok {
return len(t), nil return nil, fmt.Errorf("first argument must be sexp, received %v", reflect.TypeOf(vals[0]))
case list:
return len(t.sexp), nil
} }
return nil, fmt.Errorf("first argument must be sexp, received %v", reflect.TypeOf(vals[0])) return len(s.items), nil
}, },
} }
@ -158,7 +156,7 @@ var lst = builtin{
name: "list", name: "list",
variadic: true, variadic: true,
fn: func(vals []interface{}) (interface{}, error) { fn: func(vals []interface{}) (interface{}, error) {
return list{sexp(vals), 1}, nil return &sexp{items: vals, quotelvl: 1}, nil
}, },
} }
@ -166,11 +164,8 @@ var islist = builtin{
name: "list?", name: "list?",
arity: 1, arity: 1,
fn: func(vals []interface{}) (interface{}, error) { fn: func(vals []interface{}) (interface{}, error) {
switch vals[0].(type) { _, ok := vals[0].(*sexp)
case list, sexp: return ok, nil
return true, nil
}
return false, nil
}, },
} }
@ -178,11 +173,11 @@ var isnull = builtin{
name: "null?", name: "null?",
arity: 1, arity: 1,
fn: func(vals []interface{}) (interface{}, error) { fn: func(vals []interface{}) (interface{}, error) {
s, ok := vals[0].(sexp) s, ok := vals[0].(*sexp)
if !ok { if !ok {
return false, nil return false, nil
} }
return len(s) == 0, nil return len(s.items) == 0, nil
}, },
} }
@ -199,14 +194,14 @@ var cons = builtin{
name: "cons", name: "cons",
arity: 2, arity: 2,
fn: func(vals []interface{}) (interface{}, error) { fn: func(vals []interface{}) (interface{}, error) {
s := sexp{vals[0]} s := &sexp{items: vals[0:1]}
switch t := vals[1].(type) { switch t := vals[1].(type) {
case sexp: case *sexp:
return append(s, t...), nil s.items = append(s.items, t.items...)
default: default:
return append(s, t), nil s.items = append(s.items, t)
} }
panic("not reached") return s, nil
}, },
} }
@ -214,11 +209,11 @@ var car = builtin{
name: "car", name: "car",
arity: 1, arity: 1,
fn: func(vals []interface{}) (interface{}, error) { fn: func(vals []interface{}) (interface{}, error) {
s, ok := vals[0].(sexp) s, ok := vals[0].(*sexp)
if !ok { if !ok {
return nil, errors.New("expected list") return nil, errors.New("expected list")
} }
return s[0], nil return s.items[0], nil
}, },
} }
@ -226,10 +221,10 @@ var cdr = builtin{
name: "cdr", name: "cdr",
arity: 1, arity: 1,
fn: func(vals []interface{}) (interface{}, error) { fn: func(vals []interface{}) (interface{}, error) {
s, ok := vals[0].(sexp) s, ok := vals[0].(*sexp)
if !ok { if !ok {
return nil, errors.New("expected list") return nil, errors.New("expected list")
} }
return s[1:], nil return s.items[1:], nil
}, },
} }

@ -13,23 +13,32 @@ import (
var DEBUG = false var DEBUG = false
type sexp []interface{} type sexp struct {
items []interface{}
quotelvl int
}
func newSexp() *sexp {
return &sexp{
items: make([]interface{}, 0, 8),
quotelvl: 0,
}
}
func (s sexp) String() string { func (s sexp) String() string {
parts := make([]string, len(s)) parts := make([]string, len(s.items))
for i, _ := range s { for i, _ := range s.items {
parts[i] = fmt.Sprint(s[i]) parts[i] = fmt.Sprint(s.items[i])
} }
return "(" + strings.Join(parts, " ") + ")" return "(" + strings.Join(parts, " ") + ")"
} }
type list struct { func (s *sexp) append(item interface{}) {
sexp s.items = append(s.items, item)
quotelevel int
} }
func (l list) String() string { func (s sexp) len() int {
return l.sexp.String() return len(s.items)
} }
type symbol string type symbol string
@ -106,17 +115,17 @@ func (s *sexp) readIn(c chan token) error {
case closeParenToken: case closeParenToken:
return nil return nil
case openParenToken: case openParenToken:
child := make(sexp, 0) child := newSexp()
if err := child.readIn(c); err != nil { if err := child.readIn(c); err != nil {
return err return err
} }
*s = append(*s, child) s.append(child)
default: default:
v, err := atom(t) v, err := atom(t)
if err != nil { if err != nil {
return err return err
} }
*s = append(*s, v) s.append(v)
} }
} }
return errors.New("unexpected EOF in sexp.readIn") return errors.New("unexpected EOF in sexp.readIn")
@ -129,7 +138,7 @@ func parse(c chan token) (interface{}, error) {
case closeParenToken: case closeParenToken:
return nil, errors.New("unexpected EOF in read") return nil, errors.New("unexpected EOF in read")
case openParenToken: case openParenToken:
s := make(sexp, 0) s := newSexp()
if err := s.readIn(c); err != nil { if err := s.readIn(c); err != nil {
return nil, err return nil, err
} }
@ -143,7 +152,7 @@ func parse(c chan token) (interface{}, error) {
func eval(v interface{}, env *environment) (interface{}, error) { func eval(v interface{}, env *environment) (interface{}, error) {
if v == nil { if v == nil {
return sexp{}, nil return &sexp{}, nil
} }
switch t := v.(type) { switch t := v.(type) {
@ -156,22 +165,27 @@ func eval(v interface{}, env *environment) (interface{}, error) {
} }
return eval(s, env) return eval(s, env)
case sexp: case *sexp:
debugPrint("eval sexp") debugPrint("eval sexp")
if len(t) == 0 { if t.len() == 0 {
return nil, errors.New("illegal evaluation of empty sexp ()") return nil, errors.New("illegal evaluation of empty sexp ()")
} }
if t.quotelvl > 0 {
return t, nil
}
// eval the first item // eval the first item
v, err := eval(t[0], env) v, err := eval(t.items[0], env)
if err != nil { if err != nil {
return nil, err return nil, err
} }
// check to see if this is a special form // check to see if this is a special form
if spec, ok := v.(special); ok { if spec, ok := v.(special); ok {
if len(t) > 1 { debugPrint("special!")
return spec(env, t[1:]...) if len(t.items) > 1 {
return spec(env, t.items[1:]...)
} else { } else {
return spec(env) return spec(env)
} }
@ -179,8 +193,8 @@ func eval(v interface{}, env *environment) (interface{}, error) {
// exec builtin func if one exists // exec builtin func if one exists
if b, ok := v.(builtin); ok { if b, ok := v.(builtin); ok {
if len(t) > 1 { if len(t.items) > 1 {
return b.call(env, t[1:]) return b.call(env, t.items[1:])
} else { } else {
return b.call(env, nil) return b.call(env, nil)
} }
@ -188,8 +202,8 @@ func eval(v interface{}, env *environment) (interface{}, error) {
// exec lambda if possible // exec lambda if possible
if l, ok := v.(lambda); ok { if l, ok := v.(lambda); ok {
if len(t) > 1 { if len(t.items) > 1 {
return l.call(env, t[1:]) return l.call(env, t.items[1:])
} else { } else {
return l.call(env, nil) return l.call(env, nil)
} }
@ -198,6 +212,7 @@ func eval(v interface{}, env *environment) (interface{}, error) {
return nil, fmt.Errorf(`expected special form or builtin procedure, received %v`, reflect.TypeOf(v)) return nil, fmt.Errorf(`expected special form or builtin procedure, received %v`, reflect.TypeOf(v))
default: default:
debugPrint("default eval")
return v, nil return v, nil
} }

@ -82,14 +82,11 @@ func quote(_ *environment, args ...interface{}) (interface{}, error) {
} }
switch t := args[0].(type) { switch t := args[0].(type) {
case list: case *sexp:
fmt.Println("got a list...") t.quotelvl++
t.quotelevel++
return t, nil return t, nil
case sexp:
return list{t, 1}, nil
default: default:
return t, nil return &sexp{items: []interface{}{t}, quotelvl: 1}, nil
} }
panic("not reached") panic("not reached")
} }
@ -162,7 +159,7 @@ func set(env *environment, args ...interface{}) (interface{}, error) {
type lambda struct { type lambda struct {
env *environment env *environment
arglabels []symbol arglabels []symbol
body sexp body *sexp
} }
func (l lambda) call(env *environment, rawArgs []interface{}) (interface{}, error) { func (l lambda) call(env *environment, rawArgs []interface{}) (interface{}, error) {
@ -199,13 +196,13 @@ func mklambda(env *environment, args ...interface{}) (interface{}, error) {
return nil, err return nil, err
} }
params, ok := args[0].(sexp) params, ok := args[0].(*sexp)
if !ok { if !ok {
return nil, fmt.Errorf(`first argument to *lambda* must be sexp, received %v`, reflect.TypeOf(args[0])) return nil, fmt.Errorf(`first argument to *lambda* must be sexp, received %v`, reflect.TypeOf(args[0]))
} }
arglabels := make([]symbol, 0, len(params)) arglabels := make([]symbol, 0, len(params.items))
for _, v := range params { for _, v := range params.items {
s, ok := v.(symbol) s, ok := v.(symbol)
if !ok { if !ok {
return nil, fmt.Errorf(`lambda args must all be symbols; received invalid %v`, reflect.TypeOf(v)) return nil, fmt.Errorf(`lambda args must all be symbols; received invalid %v`, reflect.TypeOf(v))
@ -213,7 +210,7 @@ func mklambda(env *environment, args ...interface{}) (interface{}, error) {
arglabels = append(arglabels, s) arglabels = append(arglabels, s)
} }
body, ok := args[1].(sexp) body, ok := args[1].(*sexp)
if !ok { if !ok {
return nil, fmt.Errorf(`second argument to *lambda* must be sexp, received %v`, reflect.TypeOf(args[1])) return nil, fmt.Errorf(`second argument to *lambda* must be sexp, received %v`, reflect.TypeOf(args[1]))
} }

Loading…
Cancel
Save