java -jar PA6_groupname.jar --two-pass-mips input_fileWhen called with the --two-pass-mips option, the program should generate a MIPS program in the input_file.s file. The generated MIPS program must be capable of being interpreted by the MARS interpreter.
Extra Credit: You can earn up to 10 extra credit points for this assignment by implementing interpretation for function calls. Indicate in your README file if your group implemented function call interpretation. To evaluate your extra credit, we will use the option --two-pass-interpret to perform an interpretation of program execution. The interpretation should be implemented as a visitor that traverses the AST. (Hint: It is possible to do function call interpretation by overriding the caseProgram, outCallExp, caseCallExp, and caseMethodDecl methods in your interpretation visitor as well as keeping track of some extra information in the symbol table).
The input_file to your compiler will contain a legal MiniJava/Java program. For example, the assign2.txt example from PA5 could become the following:
class Assign2 {
public static void main(String[] whatever){
System.out.println( new Foo().testing() );
}
}
class Foo {
public int testing() {
int b;
int a;
a = 56;
b = 20;
System.out.println(a + b * 2);
System.out.println(2 * (6 - 1) + 2);
return 1;
}
}
For this assignment, the testing method will be treated like a function. In other words, the testing function will have no relationship with the class Foo in your PA6 compiler. However, since the above program is legal Java code, you will be able to compare your compiler output in terms of type errors and interpreted code (NOTE: java will interpret java byte code and MARS will interpret your generated MIPS code). See the MJFuncStart/TestCases/regress.sh file for an example of how to compare your compiler with the javac compiler. Note that your error messages will be syntactically different and fewer, but conceptually quite similar. We have also included the reference compiler (MJ.jar) in the MJFuncStart/ directory for use in regression testing.
You also need to be able to handle fuctions that are declared in other classes. For example, the following program:
class ParamClash {
public static void main(String[] whatever){
System.out.println( new Foo().testing() );
}
}
class Foo {
public int testing() {
int b;
int a;
a = 56;
b = 20;
System.out.println(a + b * 2);
System.out.println(2 * (6 - 1) + 2);
System.out.println(new Bar().another(100));
if (new Baz().lotsaParams(10, 20, 30)) {
System.out.println(1);
} else {
System.out.println(0);
}
System.out.println(b);
return 42;
}
}
class Bar {
public int another(int x) {
return 2 + x;
}
}
class Baz {
public boolean lotsaParams(int x, int q, int r) {
int b;
b = 3;
System.out.println(x-q-r+b);
return true;
}
}
should result in the following output from the MARS interpreter:
96 12 102 -37 1 20 42
For this assignment, you need to maintain the semantic analysis from the previous assignment and additionally catch the following errors:
[LINENUM,POSNUM] Invalid type returned from method METHODNAME
// any method declaration
[LINENUM,POSNUM] Method METHODNAME does not exist
[LINENUM,POSNUM] Method METHODNAME requires exactly NUM arguments
[LINENUM,POSNUM] Invalid argument type for method METHODNAME
// any call to a method (note that println is a method)
The above errors are all considered inappropriate type usage errors and therefore it is only necessary to report the first error.
As always you should start this assignment right away. We recommend the following progression:
Exp -> new []
Exp -> Exp . length
Exp -> [ E ]
Type -> INT [ ]
Type -> ID
Stm -> ID [ exp ] = exp ;
The only variable types you need to handle for this assignment are the "int" and "boolean" types.
As in previous assignments, all of the AST nodes needed have been provided in MJFuncStart/src/ast/nodes. Also, the ast/analysis package has been updated.
Method STEs should also contain a scope that can then contain local variables. When local variables are inserted into the symbol table, they should be inserted into the most current scope (i.e. the method being visited). Keep in mind that the formal parameters also need offsets in a methods scope, but those offsets must be calculated differently than the other local variables.
The symbol table data structure needs to be extended to manipulate more than one level of scoping. Here are some additional routines you might want to implement:
void pushScope(String)
void insertAndPushScope(NamedScopeSTE)
void popScope()
Check out the code included in the MJFuncStart/src/symtable/ subdirectory for some ideas.
NOTE: The reference compile generates an error if you attempt to declare a variable with the same name as the function that encloses it. Javac does not. Feel free to make your implementation work either way.
[LINENUM,POSNUM] Invalid type returned from method METHODNAME
// any method declaration
[LINENUM,POSNUM] Method METHODNAME does not exist
[LINENUM,POSNUM] Method METHODNAME requires exactly NUM arguments
[LINENUM,POSNUM] Invalid argument type for method METHODNAME
// any call to a method (note that println is a method)
// Errors from previous assignment that are still relevant
[LINENUM,POSNUM] Undeclared variable VARNAME
// anywhere an id token could be a variable name
[LINENUM,POSNUM] Invalid expression type assigned to variable VARNAME
// assignment statements
[LINENUM,POSNUM] Invalid left operand type for operator OP
[LINENUM,POSNUM] Invalid right operand type for operator OP
[LINENUM,POSNUM] Invalid operand type for operator !
[LINENUM,POSNUM] Invalid condition type for if statement
[LINENUM,POSNUM] Invalid condition type for while statement
where LINENUM is the line number for the symbol, POSNUM is the position number for the symbol, OP is a specific binary operator, and VARNAME is a specific variable name.
To enable easier testing and grading, do not change the phrasing of the error messages.
Method calls in the MiniJava grammar include an expression on the left-hand-side of the ".". Those expressions are going to be completely ignored by your PA6 type checker and code generator. We will handle those in PA7.
For a method call, you need to generate MIPS code that evaluates the actual parameters in the correct order (left-to-right) and make it so that the parameter values will be on the stack as is expected by the Patt and Pattel calling convention (i.e. the one we used in the MIPS assignment). After the jump and link is generated, you then need to generate code that pops the parameters and places the return value back at the top of the runtime stack.
For method declarations, you need to generate prologue code that saves the return address and old frame pointer, sets up the frame pointer, and allocates space for local variables. The epilogue code needs to ensure that the return value is placed in the return value slot according to the calling convention and that the return address and old frame pointer values are restored.
The TestCases directory includes some test cases and an example regression script.
Start working through the phases as outlined above.
svn log
svn info
svnlook tree REPOSITORY_PATH svnlook must be issued on a department machine
~cs453/bin/checkin PA6 PA6_groupname.jar