CS 451-651 Class Notes - Wed Oct 7, 2009
1. showed ILOC machine in operation
(will make the compiler.jar file available for exploration)
Discussed API's (interfaces):
Reg()
Opcode.<val>
IlocInstr.MakeInstr( ...)
todo: post relevant APIs
2. Showed BinOp node: not surprising, emit() does pretty
much what
one would expect, what we discussed on Monday.
Small/interesting item: declaring a variable vs creating an
object.
Compare these two:
Reg leftReg = left.emit()
Reg resultReg = new Reg();
In the first statement, the Reg object is created somewhere else -- as
a result of the call to left.emit() or functions that it calls.
"leftReg" is a local variable (pointer) to that object.
resultReg is also a local pointer; but in addition we create an
object
for it to point to.
(Yes, of course you knew all that)
--> also see below for issue with BinOp construction (not
discussed in class yet)
3. Discussed decls, their role as a repository for info about the
variable.
That will include the address of the memory slots which will be
allocated to hold the runtime value.
Simple program:
int apple; // decl
apple = 3; // give valu
print apple; // retreive val.
Each VblRef node is a separate object -- one for each
reference. So
we'll want to link to decl, which is common point with info
(type,
address, etc) That will happen during the second pass (Semantic
Analysis).
(todo next class: show "const" handling)
Our compiler has Three "passes"
- Lexer/Parser -> builds tree
- "semantic analysis": walk tree,find decls, do type checking etc.
- generate code : walk tree, emit ILOC instructions
and then we can execute the code
3b. To find the corresponding declaration, we'll need some kind
of Map
to go from String to DeclNode.
Happily, Java provides a HashMap ... in particular,
HashMap<String,
DeclNode>
((may need to explain Java generics...))
Perhaps: make MapTable implementation avail to class.
Suggested use of class Main.
-----
For Mon, not nec that things work smoothly, but need to have put in a
bunch of work!
Potential Problem with BinOp node construction
A BinOp node constructor needs to know which operation is desired,
supplied probably as an 'int' argument. There are different ways
to do this. Here are two possibilities:
expr ::= expr:e PLUS term:t
{:
RESULT =
new BinOpNode(sym.PLUS, e, t);
System.out.println("expr ::= expr PLUS term: " +
RESULT);
:}
expr ::= expr:e PLUS:op term:t
{:
RESULT =
new BinOpNode((int)op, e, t);
System.out.println("expr ::= expr PLUS term: " +
RESULT);
:}
In the first example, since we know it's a PLUS operation, we don't
bother with the token value, and supply a literal value sym.PLUS to the
constructor.
In the second, which seems more general, we just pass along a value
[presumably] supplied by the scanner. More general, in that the
constructor invocation is now the same for all the operators.
(One can even imagine somehow merging the productions...)
However, in the second case, we need to be a little careful with that
value. Firstly, we need to make sure that the scanner actually
returns a "value", as well as a node type: that's the third
argument to newSymbol, and you'll need to make sure it's there.
(otherwise, the value is null and you get a null deref error!)
Here's a line from my scanner that seems to work:
"+" { System.out.println(" Scan:
'"+yytext()+"'"); return
sf.newSymbol("Plus",
sym.PLUS, sym.PLUS);
It might also be helpful to declare "terminal Integer PLUS, MINUS .."
so we know the data types.