Project #3: Native Code Generation for Pyth 1. FILES IN THIS DISTRIBUTION: Makefile.common, Makefile: Top-level makefiles for your project. Be sure to keep them up to date. pyc/codegen: A subdirectory containing the pyc.codegen package. You may alter these files however you wish. However, the pyc.ast package depends on the current methods in pyc.codegen.CodeGen, including those inherited from pyc.semantics.CodeBase. CodeGen.java: The top-level public code-generation class. Any new code-generating delegate classes you define (see below) should inherit from this class. Feel free to add all the methods you want. DefaultCodeGen.java: A default class used as the default for any code-generating delegate of an AST class, pyc.ast.xxxNode, for which there is no class named pyc.semantics.xxxGen. Again, feel free to change this as you see fit (if you need it at all). CodeDecl.java: The base type for attaching any additional information you need to Decls. Do whatever you want with it (I've made it abstract to suggest that might want different subtypes to go with different kinds of Decl). Makefile Should compile the classes in this directory. Out of exasperation, I've made it simply compile all the .java files in the directory. runtime-extra.c: If you find that it would be convenient to have a few more run-time functions precompiled, add them to this file. But probably you won't need it, and can just leave it alone. pythc: This is a script that calls the staff-provided driver program. The simplest invocation is ./pythc Foo.py which runs our parser and semantic analyzer on Foo.py, sends the resulting tree to your code generator, and then assembles and links the result with gcc to produce an executable file named Foo. Change the name of the executable to Bar with ./pythc -o Bar Foo.py Produce assembly language from your code generator without assembling it with ./pythc -S Foo.py # Output in Foo.s and produce an AST without running your program with ./pythc --nocode Foo.py # Output in Foo.ast To run your program "bare" on an AST, use java pyc.codegen.Main Foo.ast Foo.s (you'll need this to use gjdb, for example). 2. STUFF WE PROVIDE: On the instructional machines, the following classes should be included in your default classpath, if you use our class setup. You will find the class files, object files, and sources under ~cs164/lib/proj3/ on the instructional machines. On your home machine, define the PYTHDIR environment variable to contain the directory where you've put those things. Package pyc.ast: The package pyc.ast is as for Project #2. It has been expanded to include a new class CastNode, inserted by static semantic analysis to indicate places where a value is "downcast" to a subtype, and must be checked for membership in that subtype. AST classes now also provide "code-generating delegates". Each node (of type pyc.ast.xxxNode) has a "partner" object (which you define) from the package pyc.codegen, accessed via the codeGenDelegate () method in AST. When a new node is created, the software will look for a class called pyc.codegen.xxxGen. If you have provided such a class, the AST constructor will instantiate an object of that type and store it as the code-generating delegate of the node (if you haven't provided a class of that name, it will instantiate a default class instead). The job of these delegates is to generate code; the codeGen() method on AST nodes delegates its work to them, just as doSemantics did for static semantics in Project #2. Package pyc.ast.semantics: Code generation sometimes requires that you attach additional information to the declarations of identifiers. For example, once you decide the offset at which a variable attributes will be stored in an object, you must get that information to all places where the attribute is used. Perhaps the most convenient way to do so is to attach the offset information to the Decl for that attribute. For this purpose, we've provided two new methods on Decls (and therefore on Types as well): d.setCode (info) attaches INFO to the Decl d, and d.getCode () retrieves it. INFO is a value of type pyc.codegen.CodeDecl, a type that you may define and extend however you see fit (see above). Package pyc.codegen: Class CodeBase The parent type of your class CodeGen. Here, we provide lots of convenience items (see the documentation). In particular, CodeBase provides a family of 'emit' routines for writing instructions conveniently, so that you don't end up writing horrendous statements like out.println ("\tmovl " + offset + "(" + baseReg + "), " + reg2 + "\n"); all the time. It also generates new local labels when needed. Class Operand Represents instruction operands. Used by the emit methods. Class Label A subtype of Operand that represents assembler labels (static storage addresses). Used by the emit methods. The driver will start the whole semantic process by calling the codeGen method of the ProgramNode that contains the translation of the source program. File prelude.py: This is aforementioned standard prelude. You can find it in lib/proj3/prelude.py on the instructional machines. We will be updating it frequently for a while, so don't copy it. It has changed from Project #2. Most notably, the methods List, Tuple, and String now inherit from an abstract supertype Sequence. This will give you a simple way to write the code for 'for' loops. File runtime.o Our runtime routines, linked in by the driver program. The source is in the same directory for those who need to recompile it. File pyth.h A file you'll probably want to include in your runtime-extra.c file if you use it. Contains C declarations of Pyth runtime structures and functions. File driver.py Runs all the pieces of the parser. We've kept it to ourselves this time because it's complicated.