forked from nat/natalieee.net
add blog posts: dollcode, python-goto
This commit is contained in:
46
www/src/data/thoughts/python-goto/goto_label.py
Normal file
46
www/src/data/thoughts/python-goto/goto_label.py
Normal file
@ -0,0 +1,46 @@
|
||||
import sys, inspect
|
||||
|
||||
label = lambda lineno: type(
|
||||
'label',
|
||||
(object,),
|
||||
dict(line=lineno)
|
||||
)
|
||||
|
||||
def prepare_labels(fp, scope):
|
||||
with open(fp, 'r') as f:
|
||||
lines = f.readlines()
|
||||
|
||||
for lineno, line in enumerate(lines):
|
||||
if line.startswith('#LABEL'):
|
||||
# 1 + 1, first to account for 0 index then to account for comment line
|
||||
scope.__setitem__(line.split(' ')[1].strip(), label(lineno+2))
|
||||
|
||||
_goto = type('goto', (object,), dict(__and__=lambda _, other: (_goto(other.line))))
|
||||
|
||||
goto = _goto()
|
||||
|
||||
def _goto(lineno):
|
||||
frame = sys._getframe().f_back.f_back
|
||||
called_from = frame
|
||||
|
||||
def hook(frame, event, _):
|
||||
if event == 'line' and frame == called_from:
|
||||
try:
|
||||
frame.f_lineno = lineno
|
||||
except ValueError as e:
|
||||
print("jump failed:", e)
|
||||
while frame:
|
||||
frame.f_trace = None
|
||||
frame = frame.f_back
|
||||
return None
|
||||
return hook
|
||||
|
||||
# it doesn't think we actually need to set the hook for each frame
|
||||
# while frame:
|
||||
# frame.f_trace = hook
|
||||
# frame = frame.f_back
|
||||
|
||||
called_from.f_trace = hook
|
||||
sys.settrace(hook)
|
||||
|
||||
prepare_labels(inspect.stack()[-1].frame.f_code.co_filename, inspect.stack()[-1].frame.f_globals)
|
Reference in New Issue
Block a user