Notes on Code Generation - Programming Languages and Compilers | CS 421, Assignments of Computer Science

Material Type: Assignment; Professor: Mechitov; Class: Progrmg Languages & Compilers; Subject: Computer Science; University: University of Illinois - Urbana-Champaign; Term: Summer 2009;

Typology: Assignments

Pre 2010

Uploaded on 02/24/2010

koofers-user-2gu-1
koofers-user-2gu-1 🇺🇸

10 documents

1 / 8

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
MP6 Code Generation
CS 421 Summer 2009
Revision 1.0
Assigned July 7, 2009
Due July 15, 2009, 1:00 PM
Extension 48 hours (penalty 20% of total points possible)
Total points 50 (+10 extra credit)
1 Change Log
1.0 Initial release.
2 Overview
In this MP you will generate executable “machine code” for MiniJava programs.
3 Collaboration
Collaboration in two-person groups is allowed.
4 What to submit
You will submit your mp6.ml file via Compass. Rename mp6-skeleton.ml to mp6.ml and start working from
there.
5 AST Structure
The input to the function you write will be the abstract syntax of a MiniJava program. The AST structure is the one
we have been working on since MP3 (see Figure 1).
You will not be generating code for the entire abstract syntax; instead, we impose a number of restrictions:
The input program is type-correct; there are no ill-typed statements or expressions. There are no dangling break
or continue statements.
The program consists of exactly one class, and that class contains a method named main.
There are no fields in the input class.
Only integer variables and values exist. There are no strings, floats, or booleans. Boolean values will be
represented by integers (as in C): 1 will stand for true, and 0 for false.
Every function has exactly one argument (of type int), and has a result of type int.
No arrays or objects. In particular, programs will not include array assignment statements, and will not include
expressions involving array references, the length operator, this,new, or null.
No switch statement.
1
pf3
pf4
pf5
pf8

Partial preview of the text

Download Notes on Code Generation - Programming Languages and Compilers | CS 421 and more Assignments Computer Science in PDF only on Docsity!

MP6 – Code Generation

CS 421 – Summer 2009

Revision 1.

Assigned July 7, 2009

Due July 15, 2009, 1:00 PM

Extension 48 hours (penalty 20% of total points possible)

Total points 50 (+10 extra credit)

1 Change Log

1.0 Initial release.

2 Overview

In this MP you will generate executable “machine code” for MiniJava programs.

3 Collaboration

Collaboration in two-person groups is allowed.

4 What to submit

You will submit your mp6.ml file via Compass. Rename mp6-skeleton.ml to mp6.ml and start working from there.

5 AST Structure

The input to the function you write will be the abstract syntax of a MiniJava program. The AST structure is the one we have been working on since MP3 (see Figure 1).

You will not be generating code for the entire abstract syntax; instead, we impose a number of restrictions:

  • The input program is type-correct; there are no ill-typed statements or expressions. There are no dangling break or continue statements.
  • The program consists of exactly one class, and that class contains a method named main.
  • There are no fields in the input class.
  • Only integer variables and values exist. There are no strings, floats, or booleans. Boolean values will be represented by integers (as in C): 1 will stand for true, and 0 for false.
  • Every function has exactly one argument (of type int), and has a result of type int.
  • No arrays or objects. In particular, programs will not include array assignment statements, and will not include expressions involving array references, the length operator, this, new, or null.
  • No switch statement.

type program = Program of (class_decl list) and class_decl = Class of id (^) * id

  • (var_decl^ list)^ * (method_decl list) and method_decl = Method of exp_type (^) * id

  • ((exp_type^ * id)^ list)^ * (var_decl list)

  • (statement^ list)^ * exp and var_decl = Var of var_kind (^) * exp_type (^) * id and var_kind = Static | NonStatic and statement = Block of (statement list) | If of exp (^) * statement (^) * statement | While of exp (^) * statement | Println of exp | Assignment of id (^) * exp | ArrayAssignment of id (^) * exp (^) * exp | Break | Continue | Switch of exp

  • ((int^ * (statement^ list)) list)^ (* cases^ *)

  • (statement^ list)^ (* default^ *) and exp = Operation of exp (^) * binary_operation (^) * exp | Array of exp (^) * exp | Length of exp | MethodCall of exp (^) * id (^) * (exp list) | Integer of int | True | False | Id of id | This | NewArray of exp_type (^) * exp | NewId of id | Not of exp | Null | String of string | Float of float and binary_operation = And | Or | LessThan | Plus | Minus | Multiplication | Division and exp_type = ArrayType of exp_type | BoolType | IntType | ObjectType of id | StringType | FloatType and id = string

Figure 1: MiniJava AST type definition.

BINOP(p, m1,m2): The binary operation p as applied to the values kept in the locations m 1 and m 2.

CALL(f,m): Execute the instructions of the method f with the argument of f bound to the value kept in location m.

LOAD(m): Read the value kept in the location m.

You will be provided with an emulator for LowLevel. The emulator gets an input of type prog, which is a list of methods (i.e., list of triples).

type methodLL = name (^) * memloc list (^) * instr list and prog = methodLL list

Note that parameters are also memory locations. Methods are assumed to have only one parameter. The emulator starts execution from the method named “main” by giving it the argument 0.

Example

Consider the program

class A {public int main(int i){ System.out.println(i); return i;}}

The following code may be generated for the main method:

let insts = [MOVE (LOAD "i", "t1"); PRINT "t1"; RET "t1"];;

val insts : Mp6common.instr list = [MOVE (LOAD "i", "t1"); PRINT "t1"; RET "t1"

This list of instructions has the meaning “Put the value kept in the location i into the location t1, print t1, and return t1.” We can put this code together with the argument list (["i"]) into a program:

let prog = [("main", ["i"], insts)];;

val prog : (string (^) * string list (^) * Mp6common.instr list) list = [("main", ["i"], [MOVE (LOAD "i", "t1"); PRINT "t1"; RET "t1"])]

Now, execute the program. (Recall that the execution starts with the main method, passing 0 as the argument.) execProg is the execution function provided by the emulator.

execProg prog;;

0

  • : int = 0

You do not need to worry about how the emulator works. However, you need to understand the meanings of the instructions.

7 Instructions

  • Download mp6grader.tar.gz. This tarball contains all the files you need, including the MiniJava lexer and parser.
  • As always, extract the tarball, rename mp6-skeleton.ml to mp6.ml, and start modifying the file. You will modify only the mp6.ml file, and submit this file only.
  • Compile your solution with make. Run the ./grader to see how well you do.
  • Make sure to add several more test cases to the tests file.
  • The following will allow you to run the solution parser interactively:

#load "mp6common.cmo";;

#load "minijavaparse.cmo";;

#load "minijavalex.cmo";;

#load "solution.cmo";;

open Mp6common;;

let parse s = Minijavaparse.program Minijavalex.tokenize

(Lexing.from_string s);; val parse : string -> Mp6common.program =

let compile s = Solution.compile (parse s);;

val compile : string -> Mp6common.prog =

let eval s = Mp6common.execProg (compile s);;

val eval : string -> int =

Now, to execute a program:

eval "class A {public int main(int i){ return i;}};;"

  • : int 0

To see the LowLevel code generated for methods, compile the program and obtain the prog list.

compile "class A {public int main(int i){ return i;}}";;

  • : Mp6common.prog = [("main", ["i"], [LABEL "label1"; MOVE (LOAD "i", "t1"); RET "t1"])]

These commands have been provided for you in a file named testing.ml on the MP6 web page. You may #use "testing.ml" from the OCaml interactive environment for your convenience. If you replace “solution” with “student,” you will be able to do the same for your own code. Note that in this case, each time you change your code, you will have to first make, then re-load the student.cmo file and re-define the compile and eval functions.

The common file

You are provided with two helper functions in the common file: genloc and newlabel. These functions take unit as their argument, and return a fresh string that you can use as a memory location or a label, respectively.

genloc;;

  • : unit -> string =

genloc();;

8 The Assignment

Step 1

Implement the compExpr : Mp6common.exp -> Mp6common.memloc (^) * Mp6common.instr list function. You may generate new locations and labels if needed. The following expressions will not occur: array access, array creation, length, this, object creation (with new), null, String and float literals. You do not need to handle them.

You should handle the boolean true as the constant 1, and false as the constant 0. Because there is only one class with no fields, the target object of a method invocation is ignored. So, effectively a.m() is considered just like m() (which would fail parsing with our parser). What you should return is the list of LowLevel instructions that would calculate the input expression when executed, and the name of the location of the expressions value.

Step 2

Implement the compStmt : Mp6common.statement -> Mp6common.label -> Mp6common.label -> Mp6common.instr list function. You may generate new locations and labels if needed. The following statements will not occur: array assignment, switch. You do not need to handle them.

Step 3

Implement the compMethod : Mp6common.method decl -> Mp6common.methodLL function. You may generate new locations and labels if needed. Assume that all the methods return int, and that they have exactly one parameter which is of type int. You do not need to look at variable declarations; any variables that occur in the program can be assumed to have declared with type int.

In this function, you might need to convert Mp6common.id into Mp6common.name and Mp6common.id into Mp6common.memloc. You can use id to name and id to memloc, which are defined in mp6common.ml.

Step 4

Implement the compClass : Mp6common.class decl -> Mp6common.prog function. This func- tion simply generates code for each method, puts the method representations in a list, and returns the list

Extra Credit

Implement logical AND and OR operations with short-circuit evaluation. When testing for extra credit, you need to put cases in the extra rubric list. Normal rubric does not perform short-circuiting. Also, to check the solution interactively, short-cirtuiting must be turned on:

Mp6common.turnOnShortCircuit();;

  • : unit = ()

Similarly you may go back to normal evaluation:

Mp6common.turnOffShortCircuit();;

  • : unit = ()

Grading

Your solution will be graded based on what it can parse. Below is a tentative point schema:

Code generation for Approx. points

  • expression
  • statement
  • method and class
  • Total
  • Total