Commits

Anonymous committed b6c2523

Add non-shrinking head and tail. Just need to eval functions now.

Comments (0)

Files changed (2)

     Exanoke     ::= {FunDef} Expr.
     FunDef      ::= "def" Ident "(" "#" {"," Ident} ")" Expr.
     Expr        ::= "cons" "(" Expr "," Expr ")"
+                  | "head" "(" Expr ")"
+                  | "tail" "(" Expr ")"
                   | "if" Expr "then" Expr "else" Expr
                   | "self" "(" Smaller {"," Expr} ")"
                   | "eq?" "(" Expr "," Expr")"
     | cons(HI, cons(THERE, NIL))
     = (HI (THERE NIL))
 
-    | <head cons(HI, THERE)
+    | head(cons(HI, THERE))
     = HI
 
-    | <tail cons(HI, THERE)
+    | tail(cons(HI, THERE))
     = THERE
 
-    | <tail <tail (cons(HI, cons(THERE, NIL)))
+    | tail(tail(cons(HI, cons(THERE, NIL))))
     = NIL
 
-    | <tail FOO
+    | tail(FOO)
     ? tail: Not a cons cell
 
-    | <head BAR
+    | head(BAR)
     ? head: Not a cons cell
 
+    | <head cons(HI, THERE)
+    ? Expected <smaller>, found "cons"
+
+    | <tail HI
+    ? Expected <smaller>, found "HI"
+
     | if TRUE then HI else THERE
     = HI
 
             e2 = self.expr()
             self.scanner.expect(")")
             return AST('Cons', [e1, e2])
+        elif self.scanner.consume("head"):
+            self.scanner.expect("(")
+            e1 = self.expr()
+            self.scanner.expect(")")
+            return AST('Head', [e1])
+        elif self.scanner.consume("tail"):
+            self.scanner.expect("(")
+            e1 = self.expr()
+            self.scanner.expect(")")
+            return AST('Tail', [e1])
         elif self.scanner.consume("if"):
             e1 = self.expr()
             self.scanner.expect("then")
             return v1.tail
         except AttributeError:
             raise TypeError("tail: Not a cons cell")
+    elif ast.type == 'If':
+        v1 = eval(ast.children[0])
+        if v1 == 'TRUE':
+            return eval(ast.children[1])
+        else:
+            return eval(ast.children[2])
     elif ast.type == 'Eq?':
         v1 = eval(ast.children[0])
         v2 = eval(ast.children[1])