Download Interpretation - CS 434/534 Home Page

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
Course Overview
PART I: overview material
1
2
3
Introduction
Language processors (tombstone diagrams, bootstrapping)
Architecture of a compiler
PART II: inside a compiler
4
5
6
7
Syntax analysis
Contextual analysis
Runtime organization
Code generation
PART III: conclusion
8
9
Interpretation
Review
Interpretation (Chapter 8)
1
Why Interpretation?
• Compiler: Large overhead before the code can be run
• Alternative: Direct interpretation of the code (immediate
execution, no time-consuming compilation)
• Applications:
–
–
–
–
Interactive systems (SQL, shell, etc)
Simple programming languages (Basic, etc)
Scripting languages (Perl, Python, etc)
Programming languages with special requirements (Scheme,
Prolog, Smalltalk, etc)
– Write once, run once
Interpretation (Chapter 8)
2
Two Kinds of Interpreters
• Iterative interpretation: Well suited for quite simple
languages, and fast (at most 10 times slower than
compiled languages)
• Recursive interpretation: Well suited for more complex
languages, but slower (up to 100 times slower than
compiled languages)
Interpretation (Chapter 8)
3
Compilation and Interpretation
• Due to the slow speed of recursive interpretation,
complex languages (such as Java) are often compiled to
simpler languages (such as JVM) that can be interpreted
iteratively
Tetris
Tetris
Java Java-->JVM JVM
x86
x86
Interpretation (Chapter 8)
Tetris
JVM
JVM
PPC
PPC
4
Iterative Interpretation of Machine Code
• General pattern for iterative interpreters:
while (true) {
fetch( );
analyze( );
execute( );
}
• Simulate machine with:
– Memory (use arrays for storing code and data)
– I/O (directly)
– CPU (use variables for registers)
Interpretation (Chapter 8)
5
Iterative Interpretation of Machine Code
• Fetch: get the next instruction from the code store array
at the position pointed to by the instruction pointer; also
increment instruction pointer
• Analyze: separate the instruction into an opcode and its
operands
• Execute: use a switch statement with one case per each
opcode; update memory and registers as specified by the
particular instruction
Interpretation (Chapter 8)
6
Hypo: a Hypothetical Abstract Machine
•
•
•
•
•
4096-word code store and 4096-word data store
PC: program counter (register), initially 0
ACC: general purpose accumulator (register), initially 0
4-bit opcode and 12-bit operand
Instruction set:
Opcode
0
1
2
3
4
5
6
7
Instruction
Meaning
STORE d
LOAD d
LOADL d
ADD d
SUB d
JUMP d
JUMPZ d
HALT
word at address d := ACC
ACC := word at address d
ACC := d
ACC := ACC + word at address d
ACC := ACC – word at address d
PC := d
if ACC = 0 then PC := d
stop execution
Interpretation (Chapter 8)
7
Implementation of Hypo in Java
public class HypoInstruction {
public byte op;
// opcode field
public short d;
// operand field
public static final byte
// possible opcodes
STOREop=0, LOADop=1,
LOADLop=2, ADDop =3,
SUBop =4, JUMPop=5,
JUMPZop=6, HALTop=7;
}
Interpretation (Chapter 8)
8
Implementation of Hypo in Java
public class HypoState {
public static final short CODESIZE=4096;
public static final short DATASIZE=4096;
public HypoInstruction[ ]
code=new HypoInstruction[CODESIZE];
public short[ ] data=new short[DATASIZE];
public short PC;
public short ACC;
public byte status;
public static final byte
RUNNING=0, HALTED=1, FAILED=2;
}
Interpretation (Chapter 8)
9
Implementation of Hypo in Java
public class HypoInterpreter extends HypoState {
public void load( ) {...} // load program into memory
public void emulate( ) {
PC=0; ACC=0; status=RUNNING;
do { // fetch:
HypoInstruction instr=code[PC++];
// analyze:
byte op=instr.op; byte d=instr.d;
// execute:
switch (op) { ... // see details on next page
}
} while (status==RUNNING);
}
}
Interpretation (Chapter 8)
10
Implementation of Hypo in Java
// execute
switch (op) {
case STOREop:
case LOADop:
case LOADLop:
case ADDop:
case SUBop:
case JUMPop:
case JUMPZop:
case HALTop:
default:
}
Interpretation (Chapter 8)
data[d]=ACC; break;
ACC=data[d]; break;
ACC=d; break;
ACC+=data[d]; break;
ACC-=data[d]; break;
PC=d; break;
if (ACC==0) PC=d; break;
status=HALTED; break;
status=FAILED;
11
Iterative Interpretation of Mini-Basic
• Programming languages can be interpreted iteratively
unless they have recursive syntactic structures such as
Command ::= if Expression then Command else Command
• EBNF for Mini-Basic:
Program ::=
Command ::=
|
|
|
|
|
Interpretation (Chapter 8)
Command*
Variable = Expression
read Variable
write Variable
go Label
if Expression RelationalOp Expression
go Label
stop
12
Iterative Interpretation of Mini-Basic
• EBNF for Mini-Basic (continued):
Expression ::=
PrimaryExpression
|
Expression ArithmeticOp PrimaryExpression
PrimaryExpression ::=
Numeral
|
Variable
|
( Expression )
ArithmeticOp
::=
+ | – | * | /
RelationalOp
::=
= | \= | < | > | =< | >=
Variable
::=
a | b | c | … | z
Label
::=
Digit Digit*
Numeral
::=
• The symbol Numeral denotes floating-point literals
• 26 predefined variables: a, b, c, …, z
Interpretation (Chapter 8)
13
Mini-Basic Interpreter
•
Mini-Basic example code:
0
1
2
3
4
5
6
7
8
9
read a
b=a/2
go 4
b=(a/b+b)/2
d=b*b–a
if d>=0 go 7
d=0–d
if d>=0.01 go 3
write b
stop
Interpretation (Chapter 8)
14
Mini-Basic Interpreter
• Mini-Basic abstract machine:
– Data store: array of 26 floating-point values
– Code store: array of commands
– Possible representations for each command:
• Character string (yields slowest execution)
• Sequence of tokens (good compromise)
• AST (yields slowest response time)
Interpretation (Chapter 8)
15
Implementing a Mini-Basic Interpreter in Java
class Token {
byte kind;
String spelling;
}
class ScannedCommand {
Token[ ] tokens;
}
public abstract class Command {
public void execute (MiniBasicState state);
}
Interpretation (Chapter 8)
16
Implementing a Mini-Basic Interpreter in Java
public class MiniBasicState {
public static final short CODESIZE=4096;
public static final short DATASIZE=26;
public ScannedCommand[ ]
code=new ScannedCommand[CODESIZE];
public float[ ] data=new float[DATASIZE];
public short PC;
public byte status;
public static final byte
RUNNING=0, HALTED=1, FAILED=2;
}
Interpretation (Chapter 8)
17
Implementing a Mini-Basic Interpreter in Java
public class MiniBasicInterpreter
extends MiniBasicState {
public void load( ) {...} // load program into memory
public static Command parse(ScannedCommand scannedCom)
{...} // return a Command AST
public void run( ) {
PC=0; status=RUNNING;
do { // fetch:
ScannedCommand scannedCom=code[PC++];
// analyze:
Command analyzedCom=parse(scannedCom);
// execute:
analyzedCom.execute((MiniBasicState) this);
} while (status==RUNNING);
}
}
Interpretation (Chapter 8)
18
Implementing a Mini-Basic Interpreter in Java
public class AssignCommand extends Command {
byte V;
// left side
Expression E;
// right side
public void Execute(MiniBasicState state) {
state.data[V]=E.evaluate(state);
}
}
public class GoCommand extends Command {
short L;
// destination label
public void Execute(MiniBasicState state) {
state.PC=L;
}
}
// ReadCommand, WriteCommand, IfCommand, StopCommand, Expression, etc.
Interpretation (Chapter 8)
19
Recursive Interpretation
• Recursively defined languages cannot be interpreted
iteratively (fetch-analyze-execute), because each
command can contain any number of other commands
• Both analysis and execution must be recursive (similar to
the parsing phase when compiling a high-level language)
• Hence, the entire analysis must precede the entire
execution:
– Step 1: Fetch and analyze (recursively)
– Step 2: Execute (recursively)
• Execution is a traversal of the decorated AST, hence we
can use a new visitor class
• Values (variables and constants) are handled internally
Interpretation (Chapter 8)
20
Recursive Interpretation of Mini-Triangle
public abstract class Value { }
public class IntValue extends Value {
public short i;
}
public class BoolValue extends Value {
public boolean b;
}
public class UndefinedValue extends Value {
}
Interpretation (Chapter 8)
21
Recursive Interpretation of Mini-Triangle
public class MiniTriangleState {
public static final short DATASIZE=...;
Program program; // code store is the decorated AST
Value[ ] data=new Value[DATASIZE];
public byte status;
public static final byte
RUNNING=0, HALTED=1, FAILED=2;
}
Interpretation (Chapter 8)
22
Recursive Interpretation of Mini-Triangle
public class MiniTriangleProcessor extends
MiniTriangleState implements Visitor {
public void fetchAnalyze( ) {
Parser parser=new Parser(...);
Checker checker=new Checker(...);
StorageAllocator allocator=
new StorageAllocator( );
program=parser.parse( );
checker.check(program);
allocator.allocateAddresses(program);
}
public void run( )
{ program.C.visit(this,null); }
}
Interpretation (Chapter 8)
23
Recursive Interpretation of Mini-Triangle
public Object visitIfCommand(
IfCommand com, Object arg) {
BoolValue val=(BoolValue)
com.E.visit(this,null);
if (val.b) com.C1.visit(this,null);
else com.C2.visit(this,null);
return null;
}
Interpretation (Chapter 8)
24
Recursive Interpretation of Mini-Triangle
public Object visitConstDeclaration(
ConstDeclaration decl,
Object arg) {
KnownAddress entity=(KnownAddress)
decl.entity;
Value val=(Value)decl.E.visit(this,null);
data[entity.address]=val;
return null;
}
Interpretation (Chapter 8)
25
Case Study: TAM Interpreter
•
•
•
•
•
Variable for each register
Array for code store (Instruction data type)
Array for data store (short type; used for both stack and heap)
Iterative interpretation similar to Hypo
Addressing:
private static short relative (
short d, byte r) {
switch(r) {
case SBr: return d+SB;
case LBr: return d+LB;
case L1r: return d+data[LB];
case L2r: return d+data[data[LB]];
...
}
Interpretation (Chapter 8)
26
Case Study: TAM Interpreter
• Use of addressing:
switch(op) {
case LOADop: {
// push onto stack
short addr=relative(d,r);
data[ST++]=data[addr];
break; }
case STOREop: {
// pop from stack
short addr=relative(d,r);
data[addr]=data[––ST];
break; }
...
}
Interpretation (Chapter 8)
27
Usage of the TAM Interpreter
• First write a Triangle program. Assume it is stored
in a file “example.tri” within the same folder
that contains the Triangle and TAM subfolders.
• Next compile your Triangle program. The command
shown below produces an equivalent TAM program
in the default file “obj.tam”:
java Triangle/Compiler example.tri
• To run this TAM program:
java TAM/Interpreter obj.tam
• To view the TAM program in human-readable form:
java TAM/Disassembler obj.tam
Interpretation (Chapter 8)
28
For further information
• More details about all these interpreters (Hypo,
Mini-Basic, Mini-Triangle, TAM) can be found in
the textbook
Interpretation (Chapter 8)
29
Related documents