Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
python goto with system trace function
import sys
def j(lineno):
frame = sys._getframe().f_back
called_from = frame
def hook(frame, event, arg):
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
while frame:
frame.f_trace = hook
frame = frame.f_back
sys.settrace(hook)
def foo():
a = 1
j(30)
a = 2
print 1
print 2
if a == 1:
j(28)
print 4
foo()
2
1
2
4
@seisvelas

This comment has been minimized.

Copy link

@seisvelas seisvelas commented May 5, 2020

If code were painting, then software engineering is portraiture and this is Dalí.

@initbar

This comment has been minimized.

Copy link

@initbar initbar commented May 5, 2020

@jgentil

This comment has been minimized.

Copy link

@jgentil jgentil commented May 5, 2020

I love to hate this so much. Thank you.

@stuaxo

This comment has been minimized.

Copy link

@stuaxo stuaxo commented May 5, 2020

Hehe, should consider renaming "j" to "goto" for full effect.

@satishgoda

This comment has been minimized.

Copy link

@satishgoda satishgoda commented May 5, 2020

Great :) Going to study this. Thank you.

@toombs-caeman

This comment has been minimized.

Copy link

@toombs-caeman toombs-caeman commented May 5, 2020

I added labels lol

import ast
import sys
def label(name):
    pass

def j(lineno):
    frame = sys._getframe().f_back
    called_from = frame

    if isinstance(lineno, str):
        with open(called_from.f_code.co_filename) as f:
            for node in ast.walk(ast.parse(f.read())):
                if isinstance(node, ast.Call) \
                    and isinstance(node.func, ast.Name) \
                    and node.func.id == 'label' \
                    and lineno == ast.literal_eval(node.args[0]):
                   lineno = node.lineno

    def hook(frame, event, arg):
        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

    while frame:
        frame.f_trace = hook
        frame = frame.f_back
    sys.settrace(hook)


def foo():
    a = 1
    j('l1')
    label('l2')
    a = 2
    print 1
    label('l1')
    print 2
    if a == 1:
        j('l2')
    print 4


foo()
@hazkaz

This comment has been minimized.

Copy link

@hazkaz hazkaz commented May 5, 2020

could someone explain what the hook function is for and who calls it?

@ropg

This comment has been minimized.

Copy link

@ropg ropg commented May 5, 2020

Meh... "goto" is already taken on PyPI... :(

@jsbueno-geru

This comment has been minimized.

Copy link

@jsbueno-geru jsbueno-geru commented May 5, 2020

The "goto" on pypi follows the same idea, and was made for an April first a couple years ago. It is actually "production quality" and implements labels and a comefrom statement as well as the goto.

@stuaxo

This comment has been minimized.

Copy link

@stuaxo stuaxo commented May 5, 2020

Can this at GOSUB too ?

@onequbit

This comment has been minimized.

Copy link

@onequbit onequbit commented May 5, 2020

How about making a BASIC interpreter, and then a transpiler to convert Python code into BASIC?
Yo DAWG! Now you can throw up in your mouth while you die a little inside!

@Kyuuhachi

This comment has been minimized.

Copy link

@Kyuuhachi Kyuuhachi commented May 6, 2020

I made a py3 port. This one uses relative line numbers though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment