previously it was impossible to do the following: (define dave (quote (x y z))) dave the interpreter would incorrectly try to evaluate the (x y z), because there was no quote level being recorded, and it was seen as being the same as a regular sexp.
@ -107,7 +107,7 @@ func length(vals []interface{}) (interface{}, error) {
return len(x), nil
}
func list(vals []interface{}) (interface{}, error) {
func lst(vals []interface{}) (interface{}, error) {
return sexp(vals), nil
@ -8,6 +8,7 @@ import (
"os"
"reflect"
"strconv"
"strings"
)
var DEBUG = false
@ -15,7 +16,20 @@ var DEBUG = false
type sexp []interface{}
func (s sexp) String() string {
return "(" + fmt.Sprint(s...) + ")"
parts := make([]string, len(s))
for i, _ := range s {
parts[i] = fmt.Sprint(s[i])
return "(" + strings.Join(parts, " ") + ")"
type list struct {
sexp
quotelevel int
func (l list) String() string {
return l.sexp.String()
type symbol string
@ -39,7 +53,7 @@ var universe = &environment{map[symbol]interface{}{
"car": builtin(car),
"cdr": builtin(cdr),
"length": builtin(length),
"list": builtin(list),
"list": builtin(lst),
"list?": builtin(islist),
"not": builtin(not),
"null?": builtin(isnull),
@ -75,7 +75,17 @@ func quote(_ *environment, args ...interface{}) (interface{}, error) {
return nil, err
return args[0], nil
switch t := args[0].(type) {
case list:
fmt.Println("got a list...")
t.quotelevel++
return t, nil
case sexp:
return list{t, 1}, nil
default:
panic("not reached")
// turns an arbitrary lisp value into a boolean. Apparently the sematics of