You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: v3/docs/project-ideas.md
+8-49Lines changed: 8 additions & 49 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -73,6 +73,7 @@ such as:
73
73
- DSL components such as logic gates for a logic simulator written in Python, or proof trees for formal logic courses
74
74
- compiler data structures such as parser states, parse tables, AST construction, code generators, etc.
75
75
- relational algebra diagrams for database courses
76
+
- embedded image files (e.g., inline PNG images) to visualize Guzdial et al.'s [Media Computation](http://coweb.cc.gatech.edu/mediaComp-teach) algorithms online
76
77
77
78
These renderers will make Online Python Tutor useful in a far larger variety of CS courses and online textbooks
78
79
beyond CS0/CS1 sorts of intro classes.
@@ -336,60 +337,18 @@ intrusive enough to preclude C module object compatibility. But that's not a big
336
337
337
338
#### Early Prototype (July 2013)
338
339
339
-
In early July 2013, I made some initial steps toward this goal as a proof-of-concept and am fairly encouraged by
340
-
my findings so far.
340
+
In early July 2013, I made some initial steps toward this goal as a proof-of-concept and am
341
+
encouraged by my findings so far.
341
342
342
343
[**Try the prototype now**](http://pythontutor.com/visualize.html#py=2crazy) by selecting
343
-
"2.crazy" as the Python version. (And see the accompanying [Py2crazy](https://github.com/pgbovine/Py2crazy/) project for more details.)
344
+
"2.crazy" as the Python version.
344
345
345
346
Specifically, try the prototype on a <ahref="http://pythontutor.com/visualize.html#code=def+foo()%3A%0A++return+True%0A%0Ax+%3D+3%0Ay+%3D+5%0A%0Aif+foo()+and+(x+%2B+y+%3E+7)%3A%0A++print+'YES'%0Aelse%3A%0A++print+'NO'&mode=display&cumulative=false&heapPrimitives=false&drawParentPointers=false&textReferences=false&showOnlyOutputs=false&py=2crazy&curInstr=0"><b>simple example</b></a>.
346
347
347
-
Note that the (approximate) column of the currently-executing bytecode instruction is highlighed in yellow.
348
-
349
-
To support this finer-grained intra-line stepping, I hacked CPython 2.7.5 to:
350
-
351
-
1. call the trace function at each bytecode rather than each time a new line is executed, which turns it into a bytecode-level stepper
352
-
2. disable the peephole optimizer so that bytecodes match source code more closely
353
-
3. insert column number information along with line numbers in bytecode
354
-
355
-
The trickest part was getting column number information into the code object.
356
-
It turns out that the tokenizer, parser, and AST all keep column numbers,
357
-
but only line numbers show up in bytecode (encoded in the cryptic lnotab string).
358
-
After some hair-pulling, I managed to add a new code.co_coltab dict that maps each
359
-
bytecode instruction to a (line number, column number) pair.
360
-
361
-
Here's example disassembly from the following line (line 7 in source code) with line/column number mappings,
362
-
and the corresponding point in the source code.
363
-
364
-
Source code line 7:
365
-
"if foo() and (x + y > 7):"
366
-
367
-
(7, 3) 21 LOAD_NAME 0 (foo) if foo() and (x + y > 7):
368
-
^
369
-
(7, 3) 24 CALL_FUNCTION 0 if foo() and (x + y > 7):
370
-
^
371
-
(7, 3) 27 JUMP_IF_FALSE_OR_POP 43 if foo() and (x + y > 7):
372
-
^
373
-
(7, 14) 30 LOAD_NAME 1 (x) if foo() and (x + y > 7):
374
-
^
375
-
(7, 18) 33 LOAD_NAME 2 (y) if foo() and (x + y > 7):
376
-
^
377
-
(7, 16) 36 BINARY_ADD if foo() and (x + y > 7):
378
-
^
379
-
(7, 22) 37 LOAD_CONST 3 (7) if foo() and (x + y > 7):
380
-
^
381
-
(7, 20) 40 COMPARE_OP 4 (>) if foo() and (x + y > 7):
382
-
^
383
-
(7, 20) >> 43 POP_JUMP_IF_FALSE 54 if foo() and (x + y > 7):
384
-
^
385
-
386
-
387
-
With this extended bytecode format, I can extend Online Python Tutor to point
388
-
not only to the line being executed, but also to the column, which gives finer-grained tracing for instructors.
389
-
390
-
The column number precision isn't perfect for all kinds of expressions, but it's still better than having
391
-
no column numbers. For instance, it's not precise for chained comparisons (`x < y < z < w`),
392
-
field accesses (`foo.bar.baz`), and probably subscripting.
348
+
And see the underlying [Py2crazy](https://github.com/pgbovine/Py2crazy/) project for more details.
349
+
350
+
Note that the (approximate) tokens corresponding to the
351
+
currently-executing bytecode instruction is highlighed are yellow.
393
352
394
353
In short, I think that with enough elbow grease to hack on CPython innards,
395
354
you can get pretty good line/column number information into bytecodes;
0 commit comments