-
Notifications
You must be signed in to change notification settings - Fork 2
/
TODO
17 lines (16 loc) · 4.92 KB
/
TODO
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
To do for Sombrero:
- Change the layout system so that we can display two nodes without having to show everything in between them. A good way to start on this is to add the ability to delete nodes, while readjusting their containing layouts and handling their child layouts nicely - started
- Update: a good way to start? Those two things aren't related. Both are worth having, though.
- Integrate the trace generation part with the trace viewing part - started
- There's a new Python library called ctypes that might be better than SWIG. Check it out.
- Update: the version in Python 2.5 is pretty hackish, but it might get better. And SWIG is pretty hackish too. This is worth looking at more.
- When the tracing interpreter evaluates an expression, it writes a partial trace and then returns a thunk to evaluate the expression and write the rest of the trace. This is important because in the case that an exception occurs within a nested expression, all of the parents of the expression that throws the exception should already be written to the trace when it is executed, so that the trace file will contain all of the information on the location of the exception. However, the current method of doing this is somewhat inconvenient. It might be worthwhile to consider others, and maybe switch to one if it seems better enough. Here are some ideas.
- The theoretically ideal algorithm is (seems to be) this: when traversing the AST, make recursive calls to each nested expression as usual. When you get to the bottom and need to evaluate something, you *leave the entire stack in place* and just move execution back up and then back down again to write all the necessary traces before executing. This should be extremely fast.
- I believe in Scheme you could express the ideal algorithm directly using continuations.
- In Python, one option would be to pass unwritten trace nodes down instead of up by giving each eval procedure a procedure to call to write all parent nodes.
- A more interesting option would be to change the order trace nodes are written and actually write the parent trace nodes before the children. This would be straightforward, since the parents would just be on the parent stack, and could be done quickly if you only wrote the trace nodes in memory, rather than to disk - which would be fairly simple since we write nodes to a memory buffer anyway before dumping them to disk. This would, however, require a few more primitive operations.
- Think about the trace file format, and consider possible improvements. For instance, what if we want to look at traces of multiple related expressions simultaneously? Can they share trace structure? Maybe trace files should be able to reference other trace files, although that would make references bigger. What if we statically analyzed a program somehow to determine what possible traces it might have, and then made the actual trace file a series of references to that?
- Idea: cross-file references could be implemented efficiently if they were limited to one or two special cross-file reference nodes. Top-level variables and constdefs might be the only things needed - they would either be the way they are now, or they would be alternate node variations which would refer to constdefs or variables in other files.
- Make children appear more intuitively in the trace by changing the algorithm we use to find them. The current way is essentially this: the children of an expression E are all of the arguments of its result whose parent is E, or whose parents' parent is E, or so forth, and all of *their* arguments with the same condition. The new way should be to take all of the old-style children and filter them so that in addition to having a parent chain that somehow points back to E, a node must appear in the trace file before E's result. This deals with a problem we currently have with duplication of effort in the case of lazy evaluation (for instance, the trace of 'and') - a function might create a subexpression, but its result might cause that expression to be evaluated. Under the current system, the subexpression appears as a child of the function, correctly, but then its result is also shown as a child (nonintuitively). It would be better if we noticed this and drew an arrow on the graph to indicate that this new result was made by the result function.
- Wish-list feature: if you have a function that operates on every element of some large data structure, make a view that draws the data structure on the canvas and annotates its nodes with the result of the function at every part of the data structure. (Question: would this ever actually be useful? If the data structure is self-similar, and it's processed by recursion, then showing all recursive calls to the processing function will have the same effect anyway. Possible answer: what if the data structure isn't a tree?)
- Split trace_interpret.py into three files: environment stuff, main driver functions, and the functions that handle each AST element.