Skip to content

Commit c6df2d4

Browse files
committed
Implement pair
1 parent 89ac56b commit c6df2d4

File tree

1 file changed

+93
-2
lines changed

1 file changed

+93
-2
lines changed

lispy.go

Lines changed: 93 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ var (
167167
)
168168

169169
func eval(expr Data, env *Env) (Data, error) {
170-
log.Printf("%T: %v\n", expr, expr)
170+
log.Printf("eval: %T: %v\n", expr, expr)
171171
switch e := expr.(type) {
172172
case Symbol:
173173
return env.FindVar(e)
@@ -422,7 +422,6 @@ func EmptyEnv() *Env {
422422
func DefaultEnv() *Env {
423423
env := EmptyEnv()
424424
// env.Bind(internSymbol("#t"), T)
425-
env.Bind(internSymbol("nil"), Nil)
426425
env.BindName("*", ApplyNumeric(func(x, y Number) Number {
427426
return x * y
428427
}))
@@ -497,6 +496,98 @@ func DefaultEnv() *Env {
497496
env.BindName("equal?", InternalFunc(func(a ...Data) (Data, error) {
498497
return Boolean(reflect.DeepEqual(a[0], a[1])), nil
499498
}))
499+
env.BindName("null?", InternalFunc(func(a ...Data) (Data, error) {
500+
if len(a) != 1 {
501+
return nil, fmt.Errorf("wrong number of arguments passed")
502+
}
503+
if a[0] == nil {
504+
return T, nil
505+
}
506+
507+
if l, ok := a[0].(DataList); ok {
508+
if len(l) == 0 {
509+
return T, nil
510+
}
511+
}
512+
return False, nil
513+
}))
500514
env.BindName("pi", Number(math.Pi))
515+
env.BindName("mcons", Apply2(cons))
516+
env.BindName("mcar", Primitive(car))
517+
env.BindName("mcdr", Primitive(cdr))
518+
env.Bind(internSymbol("nil"), nil)
501519
return env
502520
}
521+
522+
func Primitive(f func(Data) Data) InternalFunc {
523+
return func(a ...Data) (Data, error) {
524+
return f(a[0]), nil
525+
}
526+
}
527+
528+
type Pair struct {
529+
car Data
530+
cdr Data
531+
}
532+
533+
func cons(car, cdr Data) (Data, error) {
534+
return &Pair{car, cdr}, nil
535+
}
536+
537+
func PairP(d Data) bool {
538+
_, ok := d.(*Pair)
539+
if !ok {
540+
log.Printf("consp %T %v %v", d, d, ok)
541+
}
542+
return ok
543+
}
544+
545+
func car(l Data) Data {
546+
if isNil(l) {
547+
return Nil
548+
}
549+
if PairP(l) {
550+
return l.(*Pair).car
551+
}
552+
log.Fatalf("Not a list: %T", l)
553+
return Nil
554+
}
555+
556+
func isNil(l Data) bool {
557+
// log.Printf("isNil %T %v", l, l == nil)
558+
return l == nil
559+
}
560+
561+
func cdr(l Data) Data {
562+
if isNil(l) {
563+
return Nil
564+
}
565+
if PairP(l) {
566+
return l.(*Pair).cdr
567+
}
568+
log.Fatalf("Not a list: %T", l)
569+
return Nil
570+
}
571+
572+
func (p *Pair) String() string {
573+
ret := "("
574+
// var d Data = p
575+
// log.Printf("Pair.String: %T %v %v\n", d, car(d), cdr(d))
576+
for {
577+
ret += fmt.Sprintf("%v", p.car)
578+
if isNil(p.cdr) {
579+
break
580+
}
581+
if PairP(p.cdr) {
582+
ret += " "
583+
p = p.cdr.(*Pair)
584+
continue
585+
} else {
586+
ret += " . " + fmt.Sprintf("%v", p.cdr)
587+
break
588+
}
589+
break
590+
}
591+
ret = ret + ")"
592+
return ret
593+
}

0 commit comments

Comments
 (0)