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"
  1. Lexer/Parser -> builds tree
  2. "semantic analysis": walk tree,find decls, do type checking etc.
  3. 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.