Assorted Project 3 Notes

We'll be collecting interesting newsgroup responses, assorted hints, and various documentation in this file.

  1. Features not to worry about
  2. Implementing for loops
  3. Jury-rigging your classes
  4. Exceptions caused by library updates
  5. Debugging with GDB
  6. Differences in attribute handling between Pyth and Python

Notes

Features not to worry about

At least for this first offering of the project, there are a number of Pyth features that we'll leave unimplemented and untested (unless, of course, you feel like it):

Implementing for loops

The front end will guarantee that the expression in a for loop has a type that is a subtype of Sequenceable (a new primitive type). Thus, method calls on __len__() and __get__(i) are defined, and these are all you need to implement for.

Jury-rigging your classes

If you'd like to work on, say, literals, plain and native function calls, and print statements first, without having to generate lots of native-class-related stuff, you'll need to do something to allow your program to link (since the runtime library expects to see definitions for the native classes). You can get around this by putting a placeholder at the end of file runtime-extras.c, like this:
    PythDescriptor __typ_Dict,
      __typ_List,
      __typ_String,
      __typ_Tuple,
      __typ_Any,
      __typ_Unit,
      __typ_Int;
That will satisfy the linker and allow you to compile simple programs that don't use methods of the native classes. Be sure to remember to remove these definitions when you do implement NativeClassDeclGen!

Exceptions caused by library updates

Certain updates to the library (pyc.ast, pyc.semantics, etc.) may cause your compiler to give you this message:
      Exception in thread "main" java.lang.IncompatibleClassChangeError
      ...
which can happen when you compile your .java files against version N of our software and run it against version M > N.

To fix it, just do a 'gmake clean' and then plain 'gmake' to recompile your .java files.

Debugging with GDB

Thanks to a nice feature of our assembler, you can step through the code that your code-generator produces, set breakpoints at specific lines, etc. First, compile your test file with -S:
   pythc -S mytest.py
This produces a file mytest.s. Now assemble that file into a runnable executable:
   pythc -o mytest mytest.s
Finally run GDB on the result. While you can do this on the command line with
   gdb mytest
I do not recommend this approach. Use Emacs instead (M-x gdb, and then enter mytest when prompted). The commands in Emacs are essentially the same as for gjdb. You can set breakpoints on lines (C-x ) or at external (.globl) labels :
   (gdb) b __pyth_main
(but not, .e.g., .L42 or other local labels). You can print registers:
   (gdb) p $ebp
You can step the program or go up or down stack frames (on the instructional accounts, the same function keys work as for GJDB: F3 for up, F4 for down, F5 for step one instruction (step), F6 for step one instruction skipping calls (next), F7 for step out to end of function (finish), F8 for continue.

Differences in attribute handling between Pyth and Python

Q:
I noticed some corner cases in Attribute Assignments. First, consider the case:
  class A:
     x = 3

  class B(A):
     pass
 
  A.x = 4
In Python, when we access B.x, we also get 4. Do we need to handle this case by keeping a list of all the subtypes of some class in order to modify its exemplars?
A:
No. This is a departure of Pyth from Python. In Pyth, the child class inherits copies of parental attributes. So B.x at that point would be 3, not 4. If you move the assignment of A.x to before the definition of class B, then the value of B.x would be 4.
Q:
Second, in the instantiation:
    class A:
	x = 3
    r = A()
    print r.x   # Python prints 3 
    A.x = 4
    print r.x   # Python prints 4
    r.x = 5
    A.x = 4
    print r.x   # Python prints 5
Do we need to worry about this case? This will require we memorize which attributes we have assigned so far.
A:
No. Again, Pyth behaves differently. The attributes of an instance are initialized at the time the instance is created, and are thenceforth independent of those of the class. Thus, Pyth prints 3, 3, and 5.

Comparisons

Q:
What do we do with
   E1 < E2 < E3
which looks exactly like
   (E1 < E2) < E3
but has different semantics in Python?
A:
We'll just worry about the simple special case. That is,
  1. If the types of E1, E2, and E3 are all statically known (and not Any), so that all the comparisons are plain CompareOps, then treat this as
       temp = E2
       E1 < temp and temp < E3
    
    as in Python.
  2. Otherwise, just treat the comparisons as if they were ordinary calls or native calls (which they will look like in the tree anyway).

[CS164 Home Page]

Page was last modified on Fri May 6 13:20:04 2005.
Address comments and questions to cs164@eecs.berkeley.edu