Commits

catseye  committed 44115c6

More passing tests, and I haven't even written the evaluator yet.

  • Participants
  • Parent commits f746b04

Comments (0)

Files changed (2)

File README.markdown

     | def id(#)
     |     woo
     | id(WOO)
-    ? Undefined argument 'woo'
+    ? Undefined argument "woo"
 
     | def wat(#, woo)
     |     woo(#)
     | wat(WOO)
-    ? Undefined function 'woo'
+    ? Undefined function "woo"
+
+    | def wat(#)
+    |     THERE
+    | def wat(#)
+    |     HI
+    | wat(WOO)
+    ? Function "wat" already defined
+
+    | def WAT(#)
+    |     #
+    | WAT(WOO)
+    ? Expected identifier, but found atom ('WAT')
+
+    | def wat(meow)
+    |     meow
+    | wat(WOO)
+    ? Expected '#', but found 'meow'
 
     | def snd(#, another)
     |     another
     | def double(#)
     |     cons(#, #)
     | MEOW
-    ? Undefined function 'double'
+    ? Undefined function "double"
 
     | def urff(#)
     |     self(cons(#, #))

File script/exanoke

     def __init__(self, text):
         self.scanner = Scanner(text)
         self.defining = None
+        self.defined = set()
+        self.formals = None
 
     def program(self):
         fundefs = []
     def fundef(self):
         self.scanner.expect('def')
         name = self.ident()
+        if name in self.defined:
+            raise SyntaxError('Function "%s" already defined' % name)
         args = []
         self.scanner.expect('(')
         self.scanner.expect('#')
+        self.formals = {}
+        i = 1
         while self.scanner.consume(','):
-            args.append(self.ident())
+            ident = self.ident()
+            args.append(ident)
+            self.formals[ident] = i
+            i += 1
         self.scanner.expect(')')
         self.defining = name
         expr = self.expr()
         self.defining = None
+        self.formals = None
+        self.defined.add(name)
         return AST('FunDef', [expr] + args, value=name)
 
     def expr(self):
             self.scanner.scan()
             if self.scanner.on('('):
                 self.scanner.expect('(')
+                if ident not in self.defined:
+                    raise SyntaxError('Undefined function "%s"' % ident)
                 args = [self.expr()]
                 while self.scanner.consume(','):
                     args.append(self.expr())
                 self.scanner.expect(')')
                 return AST('Call', args, value=ident)
             else:
-                return AST('ArgRef', value=ident)
+                if ident not in self.formals:
+                    raise SyntaxError('Undefined argument "%s"' % ident)
+                return AST('ArgRef', value=self.formals[ident])
         else:
             return self.smaller()