java | project | assignment作业 | IT | the Principles of Compilers – CSC 413 Fall 2019 assignment 4 – Interpreter

CSC 413 Fall 2019 assignment 4 – Interpreter

java | project | assignment作业 | IT  | 编译原理代写 | the Principles of Compilers – 这是一个关于编译原理的题目, 主要考察了关于编译原理Interpreter的内容,是一个比较经典的题目, 涵盖了java等程序代做方面

project代写 代写project

CSC 413

Fall 2019

assignment 4 – Interpreter

Due Date

Tuesday, December 3, BEFORE MIDNIGHT Thursday, December 5, before midnight, is the late submission deadline (for 75% credit)

Note that the due date applies both to the iLearn submission timestamp and the last comm IT timestamp into the main branch of your repository.

Overview

The purpose of this assignment is to continue our work in the large compiler codebase, and implement an Interpreter.

You are provided with the code for the Interpreter class, which will be automatically cloned into your github repository when you begin the assignment via this assignment link.

Submission

You are required to submit your source code via the github assignment, and documentation in PDF format as described in Documentation Guidelines (ilearn link). An example of project documentation is provided at this link – please be sure to include all required sections, clearly labeled.

Implementation Requirements

You may create additional classes as needed to implement the requirements defined here, but must implement at least these classes. If you decide to add additional classes, they must follow object oriented design principles – proper encapsulation and data hiding, and implementing a single responsibility.

  1. You must be able to execute your program by typing: javac interpreter/bytecode/*. java javac interpreter/Interpreter.java java interpreter.Interpreter
You may assume that the bytecode programs that are used for testing are generated
correctly, and therefore should not contain any errors. You should check for stack underflow
errors, or popping past a frame boundary.
  1. You must provide implementations for each of the byte codes discussed in class. Byte codes should inherit from an abstract base class. a. The byte code classes should all contain parameterless constructors. b. The byte code classes should contain any member data necessary for that byte code to function properly. Note that this data should not be placed in the abstract base class! c. The byte code classes should provide some method that allows for the creator of that byte code to provide any data necessary for that byte code to function properly. One way to do this would be to create an abstract method in the base class, for example init, that takes a variable number of parameters (Ill leave it to you to consider how to pass in a variable number of parameters, and what the type should be.) d. Byte codes must be placed in a sub package of interpreter, i.e. interpreter.bytecode.
  1. You must create a CodeTable class that stores the mapping between byte codes and the
class that implements that byte code behavior.
  1. You must create a ByteCodeLoader that reads each line from the specified byte code file.
a. The ByteCodeLoader is responsible for creating byte code instances from each line by
instantiating the byte code instance based on the information provided by the
CodeTable. (See the Reflection notes in the slides.)
  1. You must create a Program class that holds the byte codes generated by the ByteCodeLoader. a. The Program class must provide a method to resolve symbolic addresses to a numeric byte code address.
  2. You must create a RuntimeStack to manage the runtime stack.
a. The RuntimeStack must record the actual data stored in the current runtime stack in a
runStack Vector.
b. The RuntimeStack must track the activation records in a framePointers Stack.
  1. You must add a new byte code, DUMP, to the set of byte codes we are implementing.
Dumping will allow us to dump the current state of the runtime stack to the shell.
a. The DUMP byte code will take a flag of on or off, and the current dump state should be
stored in the VirtualMachine. The initial dump state is off. Setting the flag to on will
set an interpreter switch that will cause dumping AFTER execution of each bytecode.
b. The byte code instruction that is output should be left aligned in 25 columns, and any
additional information should begin at column 26.
c. The following dumping actions are taken for the indicated bytecodes, other bytecodes do
not have special treatment when being dumped (see example in Appendix):
i. LIT 0 <id> int <id>
e.g. LIT 0 j
For simplicity, ALWAYS assume this LIT is an int declaration
ii. LOAD c <id> <load<id>>
e.g.
LOAD 2 a <load a>
iii. STORE c <id> <id> = <top-of-stack>
e.g. if the stack has:
[ 0, 1, 2, 3 ]
and we execute STORE 1 k
then we will dump
STORE 1 k k = 3
iv. RETURN <id> exit <base-id>: <value>
<value> is the value being returned from the function
<base-id> is the actual id of the function; e.g. for RETURN f<<2>>, the <base-id> is f
Assuming a return value of 0 from the function call:
RETURN f<<2>> exit f: 0
v. CALL <id> <base-id>(<args>)
e.g. if the stack has:
[ 0, 1, 2, 3 ]
and we execute CALL f<<3>>
after executing ARGS 2, then we will dump
CALL f<<3>> f(2,3)
we strip out any brackets ( <, > ); the ARGS bytecode just seen tells us that we have
a function with 2 args, which are on the top 2 levels of the stack - the first arg was
pushed first, etc.
d. A dump() method should be added to the RuntimeStack that takes no parameters to
allow the object to dump the current state of the stack.
e. When dumping is turned on you should print the following information JUST AFTER
executing the next bytecode
i. print the bytecode that was just executed (DO NOT PRINT the DUMP bytecodes)
ii. print the runtime stack with spaces separating frames (just after the bytecode was
executed)
iii. if dump is not on then do not print the bytecode, nor dump the runtime stack

Testing Requirements

You must test your program with a variety of cases to ensure your project is working correctly! The Compiler.java class can be used to generate additional byte code files.

Appendix A: Sample Input and Output

Consider the following bytecode program (highlighting the segments that should be dumped):

GOTO start<<1>> LABEL Read READ RETURN LABEL Write LOAD 0 dummyFormal WRITE RETURN LABEL start<<1>> LIT 0 i LIT 0 j GOTO continue<<3>> LABEL f<<2>> LIT 0 j LIT 0 k LOAD 0 i LOAD 1 j DUMP OFF BOP + LOAD 2 k BOP + LIT 2 BOP + RETURN f<<2>> POP 2 LIT 0 GRATIS-RETURN-VALUE RETURN f<<2>> LABEL continue<<3>> DUMP ON LIT 0 m LIT 3 ARGS 1 CALL f<<2>> DUMP ON STORE 2 m DUMP OFF LOAD 1 j LOAD 2 m BOP + ARGS 1 CALL Write STORE 0 i POP 3 HALT

Following is an example of the expected printout from the program given above (we only give a portion of the printout as an illustrative example, and note that the column alignment in this example is not correct – please follow the requirements above):

LIT 0 m int m [0,0,0] LIT 3 [0,0,0,3] ARGS 1 [0,0,0] [3] CALL f<<2>> f(3) [0,0,0] [3]

LABEL f<<2>> [0,0,0] [3] LIT 0 j int j [0,0,0] [3,0] LIT 0 k int k [0,0,0] [3,0,0] LOAD 0 i [0,0,0] [3,0,0,3] LOAD 1 j [0,0,0] [3,0,0,3,0] … STORE 2 m m = 5 [0,0,5]