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!

@Caagr98

This comment has been minimized.

Copy link

@Caagr98 Caagr98 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
You can’t perform that action at this time.