This repository has been archived by the owner on Apr 23, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
errors.py
74 lines (59 loc) · 2.35 KB
/
errors.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
def string_with_arrows(text, pos_start, pos_end):
result = ''
# Calculate indices
idx_start = max(text.rfind('\n', 0, pos_start.idx), 0)
idx_end = text.find('\n', idx_start + 1)
if idx_end < 0: idx_end = len(text)
# Generate each line
line_count = pos_end.ln - pos_start.ln + 1
for i in range(line_count):
# Calculate line columns
line = text[idx_start:idx_end]
col_start = pos_start.col if i == 0 else 0
col_end = pos_end.col if i == line_count - 1 else len(line) - 1
# Append to result
result += line + '\n'
result += ' ' * col_start + '^' * (col_end - col_start)
# Re-calculate indices
idx_start = idx_end
idx_end = text.find('\n', idx_start + 1)
if idx_end < 0: idx_end = len(text)
return result.replace('\t', '')
class Error:
def __init__(self, pos_start, pos_end, error_name, details):
self.pos_start = pos_start
self.pos_end = pos_end
self.error_name = error_name
self.details = details
def as_string(self):
result = f'{self.error_name}: {self.details}\n'
result += f'File {self.pos_start.fn}, line {self.pos_start.ln + 1}'
result += '\n\n' + string_with_arrows(self.pos_start.ftxt, self.pos_start, self.pos_end)
return result
class IllegalCharError(Error):
def __init__(self, pos_start, pos_end, details):
super().__init__(pos_start, pos_end, 'Illegal Character', details)
class ExpectedCharError(Error):
def __init__(self, pos_start, pos_end, details):
super().__init__(pos_start, pos_end, 'Expected Character', details)
class InvalidSyntaxError(Error):
def __init__(self, pos_start, pos_end, details=''):
super().__init__(pos_start, pos_end, 'Invalid Syntax', details)
class RTError(Error):
def __init__(self, pos_start, pos_end, details, context):
super().__init__(pos_start, pos_end, 'Runtime Error', details)
self.context = context
def as_string(self):
result = self.generate_traceback()
result += f'{self.error_name}: {self.details}'
result += '\n\n' + string_with_arrows(self.pos_start.ftxt, self.pos_start, self.pos_end)
return result
def generate_traceback(self):
result = ''
pos = self.pos_start
ctx = self.context
while ctx:
result = f' File {pos.fn}, line {str(pos.ln + 1)}, in {ctx.display_name}\n' + result
pos = ctx.parent_entry_pos
ctx = ctx.parent
return 'Traceback (most recent call last):\n' + result