Skip to content

Commit 161517d

Browse files
committed
added stacktrace for error message
1 parent fd66c6f commit 161517d

File tree

2 files changed

+45
-24
lines changed

2 files changed

+45
-24
lines changed

luisa_lang/hir.py

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1166,12 +1166,15 @@ def __str__(self) -> str:
11661166
return f"Template matching error:\n\t{self.message}"
11671167
return f"Template matching error at {self.span}:\n\t{self.message}"
11681168

1169+
11691170
class ComptimeCallStack:
11701171
pass
11711172

1173+
11721174
class SpannedError(Exception):
11731175
span: Span | None
11741176
message: str
1177+
stack_trace: str | None
11751178

11761179
def __init__(self, node: Node | Span | ast.AST | None, message: str) -> None:
11771180
if node is not None:
@@ -1185,27 +1188,32 @@ def __init__(self, node: Node | Span | ast.AST | None, message: str) -> None:
11851188
else:
11861189
self.span = None
11871190
self.message = message
1191+
self.stack_trace = None
1192+
1193+
1194+
def _pretty_print_error(err_kind: str, stack_trace: Optional[str], span: Optional[Span], message: str) -> str:
1195+
s = f"{err_kind} error"
1196+
if span is not None:
1197+
s += f" at {span}"
1198+
s += f":\n\t{message}"
1199+
if stack_trace is not None:
1200+
s += f"\n{stack_trace}"
1201+
return s
11881202

11891203

11901204
class ParsingError(SpannedError):
11911205
def __str__(self) -> str:
1192-
if self.span is None:
1193-
return f"Parsing error:\n\t{self.message}"
1194-
return f"Parsing error at {self.span}:\n\t{self.message}"
1206+
return _pretty_print_error("Parsing", self.stack_trace, self.span, self.message)
11951207

11961208

11971209
class InlineError(SpannedError):
11981210
def __str__(self) -> str:
1199-
if self.span is None:
1200-
return f"Inline error:\n\t{self.message}"
1201-
return f"Inline error at {self.span}:\n\t{self.message}"
1211+
return _pretty_print_error("Inline", self.stack_trace, self.span, self.message)
12021212

12031213

12041214
class TypeInferenceError(SpannedError):
12051215
def __str__(self) -> str:
1206-
if self.span is None:
1207-
return f"Type inference error:\n\t{self.message}"
1208-
return f"Type inference error at {self.span}:\n\t{self.message}"
1216+
return _pretty_print_error("Type inference", self.stack_trace, self.span, self.message)
12091217

12101218

12111219
class Assign(Node):

luisa_lang/parse.py

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,13 @@ def push(self, f: 'FuncParser') -> None:
251251

252252
def pop(self) -> 'FuncParser':
253253
return self.st.pop()
254+
255+
def dump_stack(self)->str:
256+
trace = []
257+
for i, f in enumerate(reversed(self.st)):
258+
span = hir.Span.from_ast(f.func_def)
259+
trace.append(f"{i}: {f.name} at {span if span else 'unknown'}")
260+
return '\n'.join(trace)
254261

255262

256263
FUNC_STACK = FuncStack()
@@ -1371,21 +1378,27 @@ def parse_anno_ty() -> hir.Type:
13711378

13721379
def parse_body(self):
13731380
FUNC_STACK.push(self)
1374-
assert self.parsed_func is not None
1375-
body = self.func_def.body
1376-
entry = hir.BasicBlock(hir.Span.from_ast(self.func_def))
1377-
self.bb_stack.append(entry)
1378-
for stmt in body:
1379-
self.parse_stmt(stmt)
1380-
assert len(self.bb_stack) == 1
1381-
self.parsed_func.body = entry
1382-
self.parsed_func.locals = list(
1383-
[x for x in self.vars.values() if isinstance(x, hir.Var)])
1384-
if not self.parsed_func.return_type:
1385-
self.parsed_func.return_type = hir.UnitType()
1386-
self.parsed_func.complete = True
1387-
assert FUNC_STACK.pop() is self
1388-
return self.parsed_func
1381+
try:
1382+
assert self.parsed_func is not None
1383+
body = self.func_def.body
1384+
entry = hir.BasicBlock(hir.Span.from_ast(self.func_def))
1385+
self.bb_stack.append(entry)
1386+
for stmt in body:
1387+
self.parse_stmt(stmt)
1388+
assert len(self.bb_stack) == 1
1389+
self.parsed_func.body = entry
1390+
self.parsed_func.locals = list(
1391+
[x for x in self.vars.values() if isinstance(x, hir.Var)])
1392+
if not self.parsed_func.return_type:
1393+
self.parsed_func.return_type = hir.UnitType()
1394+
self.parsed_func.complete = True
1395+
assert FUNC_STACK.pop() is self
1396+
return self.parsed_func
1397+
except hir.SpannedError as e:
1398+
if e.stack_trace is None:
1399+
e.stack_trace = FUNC_STACK.dump_stack()
1400+
raise e from e
1401+
13891402

13901403

13911404
UNARY_OP_TO_METHOD_NAMES: Dict[type, str] = {

0 commit comments

Comments
 (0)