Skip to content

Commit

Permalink
calyx-py: add line numbers to group enables, similar to Dhalia
Browse files Browse the repository at this point in the history
  • Loading branch information
ekiwi committed Sep 18, 2024
1 parent c66451d commit f05acea
Showing 1 changed file with 45 additions and 1 deletion.
46 changes: 45 additions & 1 deletion calyx-py/calyx/py_ast.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
from dataclasses import dataclass, field
from typing import List, Any, Tuple, Optional
from calyx.utils import block
import inspect
import os


@dataclass
Expand Down Expand Up @@ -461,6 +463,44 @@ def doc(self) -> str:
return f"({self.left.doc()} >= {self.right.doc()})"


@dataclass
class SourceLoc:
line: int
file: str


def frame_to_source_loc(frame: inspect.FrameInfo) -> SourceLoc:
"""builds a SourceLoc object from a Python frame"""
return SourceLoc(frame.lineno, os.path.basename(frame.filename))


def determine_source_loc() -> Optional[SourceLoc]:
"""Inspects the call stack to determine the first call site outside the calyx-py library."""
stacktrace = inspect.stack()

# inspect top frame to determine the path to the calyx-py library
top = stacktrace[0]
assert top.function == "determine_source_loc"
library_path = os.path.dirname(top.filename)
assert os.path.join(library_path, "py_ast.py") == top.filename

# find first stack frame that is not part of the library
user = None
for frame in stacktrace:
print(frame.filename, frame.function, frame)
# skip frames that do not have a real filename
if frame.filename == "<string>":
continue
if not frame.filename.startswith(library_path):
user = frame
break
if user is None:
return None

# build source locator from frame
return frame_to_source_loc(user)


# Control
@dataclass
class Control(Emittable):
Expand All @@ -470,9 +510,13 @@ class Control(Emittable):
@dataclass
class Enable(Control):
stmt: str
loc: Optional[SourceLoc] = field(default_factory=determine_source_loc)

def doc(self) -> str:
return f"{self.stmt};"
if self.loc is None:
return f"{self.stmt};"
else:
return f"@pos({self.loc.line}) {self.stmt};"


@dataclass
Expand Down

0 comments on commit f05acea

Please sign in to comment.