Due May 19, 1997 before midnight

Read Exercise 5.5.9 in EOPL. Get a good document on Java and try to understand the precise semantics of statements and expressions.

You are to write a Scheme interpreter for the core of Java. At this point, we are only concerned with statements and expressions. We completely ignore objects, classes, and exceptions for the time being. Furthermore, I made a simplifying assumption to avoid dealing with the semantics of I/O. All our programs in this assignment will have one class with one static method that returns an integer. For example, we can write things like:

 
// silly test
class Test {
  static int main () {
    return 42;
  }
}
and
 
// factorial of 5
class Test { 
  static int main () {
    int x = 1;
    int y = 5;
    while (y > 0) {
      x = x*y;
      y = y-1;
    }
    return x;
  }
}
The beginnings of the interpreter follow:
(define main
  (lambda (file)
    (let* ((ast (java-file-parser file))
	   (block (findMainBody ast))
	   (env emptyEnv)
	   (store emptyStore))
      (call-with-values
       (call/cc (lambda (return)
	 (lambda () 
	   (interpBlock block env store return))))
       (lambda (value newStore) value)))))

(define findMainBody
  (lambda (ast)
    (variant-case ast
     [ast-comp-unit (package imports types) 
      (if (= (length types) 1)
	  (variant-case (car types)
	   [ast-class-decl (modifiers name super implements body)
	    (if (= (length body) 1)
		(variant-case (car body)
		 [ast-method-decl (modifiers type id formal-args throws body)
		  body]
		 [else (error 'interp "~s not method definition" (car body))])
		(error 'interp "Can only handle one method definition"))]
	   [else (error 'interp "~s not a class definition" body)])
	  (error 'interp "Can only handle one class definition"))]
     [else (error 'interp "~s not a compilation unit" ast)])))

(define interpBlock ...)
To run this code use the version of Chez Scheme that includes the Java parser. It is called /local/apps/chez-5.0a/bin/jscheme. The Java parser reads a file and produces an abstract syntax tree defined as follows: (the lines starting with *** are my comments)
block ::= ast-block (statements)
statements ::= () | (cons statement statements)
statement ::= ast-null-statement ()
            | ast-var-decl (type declarators)
            | ast-binary-op (op lhs rhs)
            | ast-if-then-else (condition true-stmt false-stmt)  
                 *** condition is an expr
            | ast-block (statements)
            | ast-return (expr)
            | ast-break (identifier)
                 *** if actual statement is break; then identifier is #f
            | ast-continue (identifier)
                 *** if actual statement is continue; then identifier is #f
            | ast-labeled-statement (label statement)
                 *** label is an identifier
            | ast-while (condition body)
                 *** condition is an expr
declarators ::= () | (cons declarator declarators)
declarator ::= ast-var-declarator (id ndims init)
                 *** ignore ndims as we don't deal with arrays
                 *** init is #f if declaration is not initialized else is an expr
expr ::= ast-literal (type value)
       | ast-name (ids)
            *** use (car ids) to get the name of the identifier as we don't 
            *** have qualified names
       | ast-binary-op (op lhs rhs)
            *** both lhs and rhs are expr
op ::= add | sub | mult | div | eq | gt | assign
            *** there are more ops but these are the ones I implemented
Scheme tip: Use variant-case and call-with-values. Explain and document your decisions: you must tell me what you think the semantics of Java statements and expressions is. This is one case where documentation, comments, and examples are a must.



Amr A Sabry
Tue Apr 1 08:12:00 PST 1997