git @ Cat's Eye Technologies Tamsin / fb2d379
Make error reporting more consistent and shared. Chris Pressey 10 years ago
5 changed file(s) with 36 addition(s) and 29 deletion(s). Raw diff Collapse all Expand all
1212
1313 | hello = "h".
1414 | %
15 ? expected 'identifiable character' but found '%' at line 2, column 5 in '/tmp/tmp
15 ? expected identifiable character but found '%' at line 2, column 5 in '/tmp/tmp
1616
1717 When a parsing error occurs in a Tamsin source, the filename, line number,
1818 and column number are reported.
2020 | slough = "h" & ("o" | "p").
2121 | maidenhead = "h" & ("o" | "p").
2222 | reading = "h" ("o" | "p").
23 ? expected ''.'' but found '(' at line 3, column 16 in '/tmp/tmp
23 ? expected '.' but found '(' at line 3, column 16 in '/tmp/tmp
24
25 | pasta = "h" & «hop() & "p".
26 ? expected '>>' but found '&' at line 1, column 22 in '/tmp/tmp
27
28 | pasta = "h" & «hop()
29 ? expected '>>' but found EOF at line 1, column 22 in '/tmp/tmp
2430
2531 When a scanning error occurs in the input to a Tamsin program, the filename,
2632 line number, and column number are reported.
2733
2834 | main = "h" & "o" & "x".
2935 + hop
30 ? expected 'x' found 'p' at line 1, column 3 in '<stdin>'
36 ? expected 'x' but found 'p' at line 1, column 3 in '<stdin>'
3137
3238 | main = "h" & "o" & {"\n"} & "0" & "x".
3339 + ho
3440 +
3541 + 0p
36 ? expected 'x' found 'p' at line 3, column 2 in '<stdin>'
42 ? expected 'x' but found 'p' at line 3, column 2 in '<stdin>'
43
44 | main = "h" & "o" & "x".
45 + ho
46 ? expected 'x' but found EOF at line 1, column 3 in '<stdin>'
154154 if prodref.module == '$':
155155 return tamsin.sysmod.call(name, self, args)
156156 prod = self.program.find_production(prodref)
157 if prod is None:
158 raise ValueError("internal error: unresolved: " + repr(prodref))
157 assert prod is not None, "unresolved: " + repr(prodref)
159158 self.event('call_candidates', prod)
160159 return self.interpret(prod, args=args)
161160 elif isinstance(ast, Send):
4646 def isalnum(self):
4747 return self.scanner.isalnum()
4848 def error(self, expected):
49 return self.scanner.error(expected)
49 return self.scanner.error(expected, self.peek())
5050 def peek(self):
5151 return self.scanner.peek()
5252 def consume(self, t):
203203 """
204204 return self.state.report_buffer(position, length)
205205
206 def error_message(self, expected, found):
207 if found is EOF:
208 found = 'EOF'
209 else:
210 found = "'%s'" % found
211 return (
212 "expected %s but found %s at line %s, column %s in '%s'" %
213 (expected, found,
214 self.state.line_number,
215 self.state.column_number,
216 self.state.filename)
217 )
218
206219 def error(self, expected, found):
207 raise ValueError(u"expected '%s' but found '%s' at "
208 "line %s, column %s in '%s'" %
209 (expected, found,
210 self.state.line_number,
211 self.state.column_number,
212 self.state.filename))
220 raise ValueError(self.error_message(expected, found))
213221
214222 def scan(self):
215223 """Returns the next token from the buffer.
379387 def scan_impl(self, scanner):
380388 if scanner.is_at_eof():
381389 return EOF
382 # if we ever go back to exceptions, we would have a try/catch here
383
384 # this will cause the scanner to have another engine pushed onto
385 # it. we rely on that engine to actually get us the token, and it
390
391 # This will cause the scanner to have another engine pushed onto
392 # it. We rely on that engine to actually get us the token, and it
386393 # will update the scanner for us.
387 #
388 # BUT the subsidiary scanner may have commited, while WE want to
389 # leave the scanner in a divergent state. So we save the reset
390 # position, and restore it when the subsidiary scan is done.
391394
392395 assert scanner is self.interpreter.scanner
393396
4444 if self.scanner.consume(token):
4545 return (True, term)
4646 else:
47 if upcoming_token is EOF:
48 upcoming_token = 'EOF'
49 s = ("expected '%s' found '%s' at line %s, column %s in '%s'" %
50 (token, upcoming_token,
51 self.scanner.state.line_number,
52 self.scanner.state.column_number,
53 self.scanner.state.filename))
54 return (False, Atom(s))
47 return (False,
48 Atom(self.scanner.error_message("'%s'" % token, upcoming_token))
49 )
5550 expect.arity = 1
5651
5752