More passing tests, and I haven't even written the evaluator yet.
catseye
12 years ago
96 | 96 |
def __init__(self, text):
|
97 | 97 |
self.scanner = Scanner(text)
|
98 | 98 |
self.defining = None
|
|
99 |
self.defined = set()
|
|
100 |
self.formals = None
|
99 | 101 |
|
100 | 102 |
def program(self):
|
101 | 103 |
fundefs = []
|
|
114 | 116 |
def fundef(self):
|
115 | 117 |
self.scanner.expect('def')
|
116 | 118 |
name = self.ident()
|
|
119 |
if name in self.defined:
|
|
120 |
raise SyntaxError('Function "%s" already defined' % name)
|
117 | 121 |
args = []
|
118 | 122 |
self.scanner.expect('(')
|
119 | 123 |
self.scanner.expect('#')
|
|
124 |
self.formals = {}
|
|
125 |
i = 1
|
120 | 126 |
while self.scanner.consume(','):
|
121 | |
args.append(self.ident())
|
|
127 |
ident = self.ident()
|
|
128 |
args.append(ident)
|
|
129 |
self.formals[ident] = i
|
|
130 |
i += 1
|
122 | 131 |
self.scanner.expect(')')
|
123 | 132 |
self.defining = name
|
124 | 133 |
expr = self.expr()
|
125 | 134 |
self.defining = None
|
|
135 |
self.formals = None
|
|
136 |
self.defined.add(name)
|
126 | 137 |
return AST('FunDef', [expr] + args, value=name)
|
127 | 138 |
|
128 | 139 |
def expr(self):
|
|
181 | 192 |
self.scanner.scan()
|
182 | 193 |
if self.scanner.on('('):
|
183 | 194 |
self.scanner.expect('(')
|
|
195 |
if ident not in self.defined:
|
|
196 |
raise SyntaxError('Undefined function "%s"' % ident)
|
184 | 197 |
args = [self.expr()]
|
185 | 198 |
while self.scanner.consume(','):
|
186 | 199 |
args.append(self.expr())
|
187 | 200 |
self.scanner.expect(')')
|
188 | 201 |
return AST('Call', args, value=ident)
|
189 | 202 |
else:
|
190 | |
return AST('ArgRef', value=ident)
|
|
203 |
if ident not in self.formals:
|
|
204 |
raise SyntaxError('Undefined argument "%s"' % ident)
|
|
205 |
return AST('ArgRef', value=self.formals[ident])
|
191 | 206 |
else:
|
192 | 207 |
return self.smaller()
|
193 | 208 |
|