commit 0c531ffff929a6019bc02bb7bd40e55c7dec5e22 Author: atusa17 Date: Mon Oct 15 12:47:14 2018 -0600 Initial Commit diff --git a/Corgi/Basic.java b/Corgi/Basic.java new file mode 100755 index 0000000..6ce2d6d --- /dev/null +++ b/Corgi/Basic.java @@ -0,0 +1,271 @@ +/* basic application to be extended +*/ + +import javax.swing.*; +import java.awt.*; +import java.awt.event.*; +import java.util.ArrayList; + +public class Basic extends JFrame implements Runnable, KeyListener, + MouseListener, + MouseMotionListener, + WindowListener +{ + protected static int FPS = 50; // desired frames per second + + private int stepNumber; + + // part of the basic framework + private Thread theThread; //to control the animation + + private boolean waiting; + + protected int pixelWidth, pixelHeight; // dimensions of window in pixels + private int ulcX, ulcY; // location of upper left corner of window on screen + + private Color backgroundColor; // background color of entire window + + private double mouseX, mouseY; // maintain correct mouse location + private int whichCamera; // maintain which camera's pixel grid region mouse is in + + private Graphics dbg; + private Image dbImage = null; + + protected ArrayList cameras; + + public Basic( String title, int ulx, int uly, int pw, int ph ) + { + super( title ); // call JFrame + + ulcX = ulx; ulcY = uly; + pixelWidth = pw; pixelHeight = ph; + + setBounds(ulcX, ulcY, pixelWidth, pixelHeight ); + setResizable( false ); + + addKeyListener(this); + // setFocusable(true); +// requestFocus(); + addMouseListener(this); + addMouseMotionListener(this); + addWindowListener(this); + + cameras = new ArrayList(); + + stepNumber = 0; + + // force mouse to be in center of window at start + mouseX = pixelWidth/2; + mouseY = pixelHeight/2; + + } + + public void start() + { + setVisible(true); + + // physically draw the mouse cursor where we want it + try{ + Robot rob = new Robot(); + rob.mouseMove( ulcX+pixelWidth/2, ulcY+pixelHeight/2 ); + }catch(Exception e){} + + if (theThread == null) + theThread = new Thread(this); + theThread.start(); + } + + public void run() + { + while (true) + { + stepNumber++; + + long startTime = System.nanoTime(); + + render(); + paintScreen(); + + long stopTime = System.nanoTime(); + + double elapsed = (stopTime-startTime)/1000000.0; // milliseconds + + int waitTime = 1000/FPS - (int) Math.round( elapsed ); + if( waitTime < 1 ) + waitTime = 1; + + try { + Thread.sleep(waitTime); + } + catch (InterruptedException ie) + {System.err.println("OOPS");} + } + } + + private void render() + { + if( dbImage == null ) + {// create the buffer + dbImage = createImage( pixelWidth, pixelHeight ); + if( dbImage == null ) + { + System.out.println("dbImage is null???"); + return; + } + else + {// dbg is created, tell Camera + dbg = dbImage.getGraphics(); + Camera.setGraphicsContext( dbg ); + } + } + + // clear the background of entire window + dbg.setColor( backgroundColor ); + dbg.fillRect(0,0,pixelWidth,pixelHeight); + + // give app a chance to update its instance variables + // and then draw stuff to dbg + + step(); + } + + private void paintScreen() + { + Graphics gr; + try{ + gr = this.getGraphics(); + if( gr != null && dbImage != null ) + gr.drawImage(dbImage,0,0,null); + Toolkit.getDefaultToolkit().sync(); // maybe not needed? + gr.dispose(); + } + catch(Exception e) + { + System.out.println("graphics context error" + e ); + System.exit(1); + } + } + + // override this method with code to display stuff + // and update app instance variables + public void step() + { + System.out.println("Step number: " + getStepNumber() ); + } + + public int getStepNumber() + { + return stepNumber; + } + + // implement KeyListener: + // ****************************************************************** + public void keyPressed(KeyEvent e){} + public void keyReleased(KeyEvent e){} + public void keyTyped(KeyEvent e){} + + // implement MouseListener: + // ****************************************************************** + public void mouseClicked(MouseEvent e) + { + updateMouse(e); + } + public void mouseEntered(MouseEvent e) + { + updateMouse(e); + } + public void mouseExited(MouseEvent e) + { + updateMouse(e); + } + public void mousePressed(MouseEvent e) + { + updateMouse(e); + } + public void mouseReleased(MouseEvent e) + { + updateMouse(e); + } + + // implement MouseMotionListener: + // ****************************************************************** + public void mouseDragged(MouseEvent e) + { + updateMouse(e); + } + public void mouseMoved(MouseEvent e) + { + updateMouse(e); + } + + private void updateMouse( MouseEvent e ) + { + int ix = e.getX(), iy = e.getY(); + + // determine which camera this mouse event hits + // and compute mouseX, mouseY in that camera's graph paper coords + + whichCamera = -1; + Camera ac=null, temp; + + for( int k=0; k + Node root = parser.parseProgram(); + + // display parse tree for debugging/testing: + TreeViewer viewer = new TreeViewer("Parse Tree", 0, 0, 800, 500, root ); + + // execute the parse tree +// root.execute(); + + }// main + +} diff --git a/Corgi/Lexer.java b/Corgi/Lexer.java new file mode 100755 index 0000000..94f4840 --- /dev/null +++ b/Corgi/Lexer.java @@ -0,0 +1,275 @@ +import java.io.BufferedReader; +import java.io.FileReader; +import java.util.Scanner; +import java.util.Stack; +public class Lexer { + + public static String margin = ""; + + // holds any number of tokens that have been put back + private Stack stack; + + // the source of physical symbols + // (use BufferedReader instead of Scanner because it can + // read a single physical symbol) + private BufferedReader input; + + // one lookahead physical symbol + private int lookahead; + + // construct a Lexer ready to produce tokens from a file + public Lexer( String fileName ) { + try { + input = new BufferedReader( new FileReader( fileName ) ); + } + catch(Exception e) { + error("Problem opening file named [" + fileName + "]" ); + } + stack = new Stack(); + lookahead = 0; // indicates no lookahead symbol present + }// constructor + + // produce the next token + private Token getNext() { + if( ! stack.empty() ) { + // produce the most recently putback token + Token token = stack.pop(); + return token; + } + else { + // produce a token from the input source + + int state = 1; // state of FA + String data = ""; // specific info for the token + boolean done = false; + int sym; // holds current symbol + + do { + sym = getNextSymbol(); + +// System.out.println("current symbol: " + sym + " state = " + state ); + + if ( state == 1 ) { + if ( sym == 9 || sym == 10 || sym == 13 || + sym == 32 ) {// whitespace + state = 1; + } + else if ( 'a'<=sym && sym<='z' ) {// lowercase + data += (char) sym; + state = 2; + } + else if ( digit( sym ) ) { + data += (char) sym; + state = 3; + } + else if ( sym == '.' ) { + data += (char) sym; + state = 5; + } + else if ( sym == '\"' ) { + state = 6; + } + else if ( sym == '+' || sym == '-' || sym == '*' || + sym == '/' || sym == '(' || sym == ')' || + sym == ',' || sym == '=' + ) { + data += (char) sym; + state = 8; + done = true; + } + else if ( sym == -1 ) {// end of file + state = 9; + done = true; + } + else { + error("Error in lexical analysis phase with symbol " + + sym + " in state " + state ); + } + } + + else if ( state == 2 ) { + if ( letter(sym) || digit(sym) ) { + data += (char) sym; + state = 2; + } + else {// done with variable token + putBackSymbol( sym ); + done = true; + } + } + + else if ( state == 3 ) { + if ( digit(sym) ) { + data += (char) sym; + state = 3; + } + else if ( sym == '.' ) { + data += (char) sym; + state = 4; + } + else {// done with number token + putBackSymbol( sym ); + done = true; + } + + } + + else if ( state == 4 ) { + if ( digit(sym) ) { + data += (char) sym; + state = 4; + } + else {// done with number token + putBackSymbol( sym ); + done = true; + } + } + + else if ( state == 5 ) { + if ( digit(sym) ) { + data += (char) sym; + state = 4; + } + else { + error("Error in lexical analysis phase with symbol " + + sym + " in state " + state ); + } + } + + else if ( state == 6 ) { + if ( (' '<=sym && sym<='~') && sym != '\"' ) { + data += (char) sym; + state = 6; + } + else if ( sym == '\"' ) { + state = 7; + done = true; + } + } + + // note: states 7, 8, and 9 are accepting states with + // no arcs out of them, so they are handled + // in the arc going into them + }while( !done ); + + // generate token depending on stopping state + Token token; + + if ( state == 2 ) { + // see if data matches any special words + if ( data.equals("input") ) { + return new Token( "bif0", data ); + } + else if ( data.equals("sqrt") || data.equals("cos") || + data.equals("sin") || data.equals("atan") + ) { + return new Token( "bif1", data ); + } + else if ( data.equals("pow") ) { + return new Token( "bif2", data ); + } + else if ( data.equals("print") ) { + return new Token( "print", "" ); + } + else if ( data.equals("newline") ) { + return new Token( "newline", "" ); + } + else {// is just a variable + return new Token( "var", data ); + } + } + else if ( state == 3 || state == 4 ) { + return new Token( "num", data ); + } + else if ( state == 7 ) { + return new Token( "string", data ); + } + else if ( state == 8 ) { + return new Token( "single", data ); + } + else if ( state == 9 ) { + return new Token( "eof", data ); + } + + else {// Lexer error + error("somehow Lexer FA halted in bad state " + state ); + return null; + } + + }// else generate token from input + + }// getNext + + public Token getNextToken() { + Token token = getNext(); + System.out.println(" got token: " + token ); + return token; + } + + public void putBackToken( Token token ) + { + System.out.println( margin + "put back token " + token.toString() ); + stack.push( token ); + } + + // next physical symbol is the lookahead symbol if there is one, + // otherwise is next symbol from file + private int getNextSymbol() { + int result = -1; + + if( lookahead == 0 ) {// is no lookahead, use input + try{ result = input.read(); } + catch(Exception e){} + } + else {// use the lookahead and consume it + result = lookahead; + lookahead = 0; + } + return result; + } + + private void putBackSymbol( int sym ) { + if( lookahead == 0 ) {// sensible to put one back + lookahead = sym; + } + else { + System.out.println("Oops, already have a lookahead " + lookahead + + " when trying to put back symbol " + sym ); + System.exit(1); + } + }// putBackSymbol + + private boolean letter( int code ) { + return 'a'<=code && code<='z' || + 'A'<=code && code<='Z'; + } + + private boolean digit( int code ) { + return '0'<=code && code<='9'; + } + + private boolean printable( int code ) { + return ' '<=code && code<='~'; + } + + private static void error( String message ) { + System.out.println( message ); + System.exit(1); + } + + public static void main(String[] args) { + System.out.print("Enter file name: "); + Scanner keys = new Scanner( System.in ); + String name = keys.nextLine(); + + Lexer lex = new Lexer( name ); + Token token; + + do{ + token = lex.getNext(); + System.out.println( token.toString() ); + }while( ! token.getKind().equals( "eof" ) ); + + } + +} diff --git a/Corgi/MemTable.java b/Corgi/MemTable.java new file mode 100755 index 0000000..5837e15 --- /dev/null +++ b/Corgi/MemTable.java @@ -0,0 +1,75 @@ +/* + store variable names with stored value +*/ + +import java.util.ArrayList; + +public class MemTable { + + private ArrayList names; + private ArrayList values; + + public MemTable() { + names = new ArrayList(); + values = new ArrayList(); + } + + public String toString() { + String s = "----\n"; + for( int k=0; k= 0 ) {// add new pair + return values.get( loc ); + } + else { + System.out.println("variable [" + name + "] not found"); + System.exit(1); + return 0; + } + + }// retrieve + + // return index of name in names, or -1 if + // not found + private int findName( String name ) { + // locate name + int loc = -1; + for (int k=0; k"; + } + + public String nice( Node node ) { + if ( node == null ) { + return ""; + } + else { + return "" + node.id; + } + } + + // produce array with the non-null children + // in order + private Node[] getChildren() { + int count = 0; + if( first != null ) count++; + if( second != null ) count++; + if( third != null ) count++; + Node[] children = new Node[count]; + int k=0; + if( first != null ) { children[k] = first; k++; } + if( second != null ) { children[k] = second; k++; } + if( third != null ) { children[k] = third; k++; } + + return children; + } + + //****************************************************** + // graphical display of this node and its subtree + // in given camera, with specified location (x,y) of this + // node, and specified distances horizontally and vertically + // to children + public void draw( Camera cam, double x, double y, double h, double v ) { + +System.out.println("draw node " + id ); + + // set drawing color + cam.setColor( Color.black ); + + String text = kind; + if( ! info.equals("") ) text += "(" + info + ")"; + cam.drawHorizCenteredText( text, x, y ); + + // positioning of children depends on how many + // in a nice, uniform manner + Node[] children = getChildren(); + int number = children.length; +System.out.println("has " + number + " children"); + + double top = y - 0.75*v; + + if( number == 0 ) { + return; + } + else if( number == 1 ) { + children[0].draw( cam, x, y-v, h/2, v ); cam.drawLine( x, y, x, top ); + } + else if( number == 2 ) { + children[0].draw( cam, x-h/2, y-v, h/2, v ); cam.drawLine( x, y, x-h/2, top ); + children[1].draw( cam, x+h/2, y-v, h/2, v ); cam.drawLine( x, y, x+h/2, top ); + } + else if( number == 3 ) { + children[0].draw( cam, x-h, y-v, h/2, v ); cam.drawLine( x, y, x-h, top ); + children[1].draw( cam, x, y-v, h/2, v ); cam.drawLine( x, y, x, top ); + children[2].draw( cam, x+h, y-v, h/2, v ); cam.drawLine( x, y, x+h, top ); + } + else { + System.out.println("no Node kind has more than 3 children???"); + System.exit(1); + } + + }// draw + + public static void error( String message ) { + System.out.println( message ); + System.exit(1); + } + + // ask this node to execute itself + // (for nodes that don't return a value) + public void execute() { + + if ( kind.equals("stmts") ) { + // insert code here for Exercise 15 + } + + else if ( kind.equals("prtstr") ) { + System.out.print( info ); + } + + else if ( kind.equals("prtexp") ) { + // insert code here for Exercise 15 + } + + else if ( kind.equals("nl") ) { + System.out.print( "\n" ); + } + + else if ( kind.equals("sto") ) { + // insert code here for Exercise 15 + } + + else { + error("Unknown kind of node [" + kind + "]"); + } + + }// execute + + // compute and return value produced by this node + public double evaluate() { + + if ( kind.equals("num") ) { + return Double.parseDouble( info ); + } + + else if ( kind.equals("var") ) { + // insert code here for Exercise 15 + } + + else if ( kind.equals("+") || kind.equals("-") ) { + // insert code here for Exercise 15 + } + + else if ( kind.equals("*") || kind.equals("/") ) { + // insert code here for Exercise 15 + } + + else if ( kind.equals("input") ) { + return keys.nextDouble(); + } + + else if ( kind.equals("sqrt") || kind.equals("cos") || + kind.equals("sin") || kind.equals("atan") + ) { + double value = first.evaluate(); + + if ( kind.equals("sqrt") ) + return Math.sqrt(value); + else if ( kind.equals("cos") ) + return Math.cos( Math.toRadians( value ) ); + else if ( kind.equals("sin") ) + return Math.sin( Math.toRadians( value ) ); + else if ( kind.equals("atan") ) + return Math.toDegrees( Math.atan( value ) ); + else { + error("unknown function name [" + kind + "]"); + return 0; + } + + } + + else if ( kind.equals("pow") ) { + // insert code here for Exercise 15 + } + + else if ( kind.equals("opp") ) { + // insert code here for Exercise 15 + } + + else { + error("Unknown node kind [" + kind + "]"); + return 0; + } + + }// evaluate + +}// Node diff --git a/Corgi/Parser.java b/Corgi/Parser.java new file mode 100755 index 0000000..73935d4 --- /dev/null +++ b/Corgi/Parser.java @@ -0,0 +1,202 @@ +/* + This class provides a recursive descent parser + for Corgi (a simple calculator language), + creating a parse tree which can be interpreted + to simulate execution of a Corgi program +*/ + +public class Parser { + + private Lexer lex; + + public Parser( Lexer lexer ) { + lex = lexer; + } + + public Node parseProgram() { + return parseStatements(); + } + + private Node parseStatements() { + System.out.println("-----> parsing :"); + + Node first = parseStatement(); + + // look ahead to see if there are more statement's + Token token = lex.getNextToken(); + + if ( token.isKind("eof") ) { + return new Node( "stmts", first, null, null ); + } + else { + lex.putBackToken( token ); + Node second = parseStatements(); + return new Node( "stmts", first, second, null ); + } + }// + + private Node parseStatement() { + System.out.println("-----> parsing :"); + + Token token = lex.getNextToken(); + + // ---------------->>> print or print + if ( token.isKind("print") ) { + token = lex.getNextToken(); + + if ( token.isKind("string") ) {// print + return new Node( "prtstr", token.getDetails(), + null, null, null ); + } + else {// must be first token in + // put back the token we looked ahead at + lex.putBackToken( token ); + Node first = parseExpr(); + return new Node( "prtexp", first, null, null ); + } + // ---------------->>> newline + } + else if ( token.isKind("newline") ) { + return new Node( "nl", null, null, null ); + } + // --------------->>> = + else if ( token.isKind("var") ) { + String varName = token.getDetails(); + token = lex.getNextToken(); + errorCheck( token, "single", "=" ); + Node first = parseExpr(); + return new Node( "sto", varName, first, null, null ); + } + else { + System.out.println("Token " + token + + " can't begin a statement"); + System.exit(1); + return null; + } + + }// + + private Node parseExpr() { + System.out.println("-----> parsing "); + + Node first = parseTerm(); + + // look ahead to see if there's an addop + Token token = lex.getNextToken(); + + if ( token.matches("single", "+") || + token.matches("single", "-") + ) { + Node second = parseExpr(); + return new Node( token.getDetails(), first, second, null ); + } + else {// is just one term + lex.putBackToken( token ); + return first; + } + + }// + + private Node parseTerm() { + System.out.println("-----> parsing "); + + Node first = parseFactor(); + + // look ahead to see if there's a multop + Token token = lex.getNextToken(); + + if ( token.matches("single", "*") || + token.matches("single", "/") + ) { + Node second = parseTerm(); + return new Node( token.getDetails(), first, second, null ); + } + else {// is just one factor + lex.putBackToken( token ); + return first; + } + + }// + + private Node parseFactor() { + System.out.println("-----> parsing "); + + Token token = lex.getNextToken(); + + if ( token.isKind("num") ) { + return new Node("num", token.getDetails(), null, null, null ); + } + else if ( token.isKind("var") ) { + return new Node("var", token.getDetails(), null, null, null ); + } + else if ( token.matches("single","(") ) { + Node first = parseExpr(); + token = lex.getNextToken(); + errorCheck( token, "single", ")" ); + return first; + } + else if ( token.isKind("bif0") ) { + String bifName = token.getDetails(); + token = lex.getNextToken(); + errorCheck( token, "single", "(" ); + token = lex.getNextToken(); + errorCheck( token, "single", ")" ); + + return new Node( bifName, null, null, null ); + } + else if ( token.isKind("bif1") ) { + String bifName = token.getDetails(); + token = lex.getNextToken(); + errorCheck( token, "single", "(" ); + Node first = parseExpr(); + token = lex.getNextToken(); + errorCheck( token, "single", ")" ); + + return new Node( bifName, first, null, null ); + } + else if ( token.isKind("bif2") ) { + String bifName = token.getDetails(); + token = lex.getNextToken(); + errorCheck( token, "single", "(" ); + Node first = parseExpr(); + token = lex.getNextToken(); + errorCheck( token, "single", "," ); + Node second = parseExpr(); + token = lex.getNextToken(); + errorCheck( token, "single", ")" ); + + return new Node( bifName, first, second, null ); + } + else if ( token.matches("single","-") ) { + Node first = parseFactor(); + return new Node("opp", first, null, null ); + } + else { + System.out.println("Can't have factor starting with " + token ); + System.exit(1); + return null; + } + + }// + + // check whether token is correct kind + private void errorCheck( Token token, String kind ) { + if( ! token.isKind( kind ) ) { + System.out.println("Error: expected " + token + + " to be of kind " + kind ); + System.exit(1); + } + } + + // check whether token is correct kind and details + private void errorCheck( Token token, String kind, String details ) { + if( ! token.isKind( kind ) || + ! token.getDetails().equals( details ) ) { + System.out.println("Error: expected " + token + + " to be kind=" + kind + + " and details=" + details ); + System.exit(1); + } + } + +} diff --git a/Corgi/Tests/factorial b/Corgi/Tests/factorial new file mode 100755 index 0000000..e9a70bb --- /dev/null +++ b/Corgi/Tests/factorial @@ -0,0 +1,20 @@ +main() + +def fact( n ) + + if lt(n 1) + return 1 + else + temp = fact( n-1 ) + return n * temp + end + +end + +def main() + + "enter n: " + n = input() + print( fact(n) ) + +end diff --git a/Corgi/Tests/quadroots b/Corgi/Tests/quadroots new file mode 100755 index 0000000..66c1d32 --- /dev/null +++ b/Corgi/Tests/quadroots @@ -0,0 +1,23 @@ +main() + +def main() + + "enter a:" + + a = input() + + "enter b:" + b = input() + + "enter c:" + c = input() + + disc = pow(b,2) - 4*a*c + + x1 = (-b - sqrt(disc) ) / (2*a) + x2 = (-b + sqrt(disc) ) / (2*a) + + "x1: " print(x1) "\n" + "x2: " print(x2 ) "\n" + +end diff --git a/Corgi/Token.java b/Corgi/Token.java new file mode 100755 index 0000000..6a8c813 --- /dev/null +++ b/Corgi/Token.java @@ -0,0 +1,31 @@ +public class Token +{ + private String kind; + private String details; + + public Token( String k, String d ) + { + kind = k; details = d; + } + + public boolean isKind( String s ) + { + return kind.equals( s ); + } + + public String getKind() + { return kind; } + + public String getDetails() + { return details; } + + public boolean matches( String k, String d ) { + return kind.equals(k) && details.equals(d); + } + + public String toString() + { + return "[" + kind + "," + details + "]"; + } + +} diff --git a/Corgi/TreeViewer.java b/Corgi/TreeViewer.java new file mode 100755 index 0000000..d92058e --- /dev/null +++ b/Corgi/TreeViewer.java @@ -0,0 +1,78 @@ +/* this class allows interactive + viewing of a tree built from + Node instances +*/ + +import java.awt.*; +import java.awt.event.KeyEvent; + +public class TreeViewer extends Basic +{ + // instance variables for the application: + // vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + + private Node root; // root of tree to be viewed + + private String keyInput; + private double horizGap = 2, vertGap = .5; + + // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + public TreeViewer( String title, int ulx, int uly, int pw, int ph, + Node tree ) + { + super(title,ulx,uly,pw,ph); + + setBackgroundColor( new Color( 128, 128, 200 ) ); + + // tree display + cameras.add( new Camera( 25, 45, pw-55, ph-75, + 0, 10, 0, 5, + new Color( 200, 200, 200 ) ) ); + + root = tree; + + super.start(); + } + + public void step() + { + // tree display + Camera cam = cameras.get(0); + cam.activate(); + cam.setColor( Color.black ); + + root.draw( cam, 5.0, 4.0, horizGap, vertGap ); + + }// step + + public void keyTyped( KeyEvent e ) { + char key = e.getKeyChar(); + + if( key == 'w' ){ + horizGap *= 1.2; + } + else if( key == 'n' ){ + horizGap /= 1.2; + } + + }// keyTyped + + public void keyPressed( KeyEvent e ) { + int code = e.getKeyCode(); + + if( code == KeyEvent.VK_LEFT ){ + cameras.get(0).shiftRegion( -0.25, 0 ); + } + else if( code == KeyEvent.VK_RIGHT ){ + cameras.get(0).shiftRegion( 0.25, 0 ); + } + else if( code == KeyEvent.VK_UP ){ + cameras.get(0).shiftRegion( 0, 0.25 ); + } + else if( code == KeyEvent.VK_DOWN ){ + cameras.get(0).shiftRegion( 0, -0.25 ); + } + }// keyPressed + +}// TreeViewer diff --git a/Corgi/corgiCFG.txt b/Corgi/corgiCFG.txt new file mode 100755 index 0000000..3fe78b1 --- /dev/null +++ b/Corgi/corgiCFG.txt @@ -0,0 +1,66 @@ +Note: this is the draft grammar, with notes and some thoughts, + for the Project 2 version of Corgi +------------------ + + -> + + -> | + + -> def ( ) end | + def ( ) end | + def ( ) end + def ( ) end + + -> + + -> | + + -> | + + + -> ( ) | + ( ) + + -> | + + -> | + = | + | + if else end | + if else end | + if else end | + if else end | + return + + -> | + | - + -> | * | / + + -> | | + ( ) | + - | + + + +Notes: + + slightly bizarre but cool: in Corgi you can just type a string anywhere + as a statement and it gets sent to the console (still have to use + print( ) to send a number) + + no boolean type---use "non-zero is true, 0 is false" + + there's only the if-else---always have to use it + + no loop statements---use recursion! + + the built-in functions fit the grammar just like user-defined functions--- + will execute differently + + change the Lexer to remove /* ..... */ type of comments---no tokens + produced + + change Lexer to allow \n inside a string---put \\ in the Java string + + +Need to agree on names for all the many BIF's---see upcoming document + diff --git a/Corgi/oldCorgi.txt b/Corgi/oldCorgi.txt new file mode 100755 index 0000000..e89fceb --- /dev/null +++ b/Corgi/oldCorgi.txt @@ -0,0 +1,19 @@ + -> + + -> | + + + -> print | + print | + newline | + = + + -> | + -> | + + -> | | + ( ) | + () | + ( ) | + ( , ) | + - diff --git a/Corgi/partialNode.java b/Corgi/partialNode.java new file mode 100755 index 0000000..e40b782 --- /dev/null +++ b/Corgi/partialNode.java @@ -0,0 +1,87 @@ + // ask this node to execute itself + // (for nodes that don't return a value) + public void execute() { + + if ( kind.equals("stmts") ) { + // insert code here for Exercise 15 + } + + else if ( kind.equals("prtstr") ) { + System.out.print( info ); + } + + else if ( kind.equals("prtexp") ) { + // insert code here for Exercise 15 + } + + else if ( kind.equals("nl") ) { + System.out.print( "\n" ); + } + + else if ( kind.equals("sto") ) { + // insert code here for Exercise 15 + } + + else { + error("Unknown kind of node [" + kind + "]"); + } + + }// execute + + // compute and return value produced by this node + public double evaluate() { + + if ( kind.equals("num") ) { + return Double.parseDouble( info ); + } + + else if ( kind.equals("var") ) { + // insert code here for Exercise 15 + } + + else if ( kind.equals("+") || kind.equals("-") ) { + // insert code here for Exercise 15 + } + + else if ( kind.equals("*") || kind.equals("/") ) { + // insert code here for Exercise 15 + } + + else if ( kind.equals("input") ) { + return keys.nextDouble(); + } + + else if ( kind.equals("sqrt") || kind.equals("cos") || + kind.equals("sin") || kind.equals("atan") + ) { + double value = first.evaluate(); + + if ( kind.equals("sqrt") ) + return Math.sqrt(value); + else if ( kind.equals("cos") ) + return Math.cos( Math.toRadians( value ) ); + else if ( kind.equals("sin") ) + return Math.sin( Math.toRadians( value ) ); + else if ( kind.equals("atan") ) + return Math.toDegrees( Math.atan( value ) ); + else { + error("unknown function name [" + kind + "]"); + return 0; + } + + } + + else if ( kind.equals("pow") ) { + // insert code here for Exercise 15 + } + + else if ( kind.equals("opp") ) { + // insert code here for Exercise 15 + } + + else { + error("Unknown node kind [" + kind + "]"); + return 0; + } + + }// evaluate diff --git a/Corgi/quadroots b/Corgi/quadroots new file mode 100755 index 0000000..3a11018 --- /dev/null +++ b/Corgi/quadroots @@ -0,0 +1,16 @@ +print "enter a:" + +a = input() + +print "enter b:" +b = input() +print "enter c:" +c = input() + +disc = pow(b,2) - 4*a*c + +x1 = (-b - sqrt(disc) ) / (2*a) +x2 = (-b + sqrt(disc) ) / (2*a) + +print "x1: " print x1 newline +print "x2: " print x2 newline diff --git a/Documents/announcements b/Documents/announcements new file mode 100755 index 0000000..52b038b --- /dev/null +++ b/Documents/announcements @@ -0,0 +1,25 @@ +Announcements + (I'll try to keep this file current with any due dates, corrections to + the course notes, corrections to + Exercises and Projects, and so on) +======================================= + +Exercise 2: + + The command (occurring two places): + + 2 1001 1 + + is misleading, because the "1" is a conceptual error + (in an earlier version of VPL, I though the call had + to speciy how many arguments had been passed, but now + we just say that the command 3's have to immediately + precede the command 2) + but I didn't notice this issue because the loader + sees opcode 2, reads one further argument (1001), and + tosses the rest of the line---it's just as if the "1" + is a comment. +--------------------------------------- + +Project 1 is due September 10 (target) + diff --git a/Documents/implementation.pdf b/Documents/implementation.pdf new file mode 100755 index 0000000..c895e47 Binary files /dev/null and b/Documents/implementation.pdf differ diff --git a/Documents/implementation.tex b/Documents/implementation.tex new file mode 100755 index 0000000..a4e5500 --- /dev/null +++ b/Documents/implementation.tex @@ -0,0 +1,757 @@ +\input pictex +\input /Users/Shared/TeX/defs + +\advance \hoffset 0.25 true in + +\def\inclassexercise{\item{$\Rightarrow$\quad\quad} {\bf In-Class Exercise:}\quad} +\def\borderline{\medskip\hrule\bigskip} + +\startDoc{CS 3210 Fall 2018}{25}{Implementing a Programming Language} + +{\bigboldfont A Brief Look at More Serious Language Implementation} +\bigskip + +We have already played some with language design and implementation---you were asked in Project 1 +to implement VPL, and I suffered greatly implementing Jive. But, those languages have relatively simple +structure and can be described just +using finite automata. Now we want to learn a little about implementing a language that is described using +a {\it context free grammar}. It turns out that if a language is described using a finite automaton to describe +its meaningful chunks, and a context free grammar of the right form to describe its main structure, +then we can implement the language using {\it recursive descent parsing}. +\bigskip + +\Indent{.5} + Not that long ago, + probably every computer science program had a rather nasty required course known as + ``the compiler course.'' As this technology became more well-known and accepted, this + course gradually disappeared from the curriculum, but scraps of it remain in this course. + \medskip + + We will make our work much easier by mostly + ignoring issues of {\it efficiency}, both in space and time. + For example, a real compiler tries to recover from errors and go on to report other errors, but + we will be happy to detect one error and stop. And, a real compiler tries to generate code that + uses as little memory as is reasonable, and runs as quickly as is reasonable. + We won't be crazy about it in our upcoming work, but we will compromise efficiency whenever it saves us + work. + \medskip + \Outdent + +{\bigboldfont Language Specification} +\bigskip + +To specify a programming language, we have to specify its {\it grammar}---what sequences of symbols +(or diagrammatic elements, if it's a non-textual language) form a syntactically legal program, and its +{\it semantics}---the meaning of those sequences of symbols. +\medskip + +To precisely specify the grammar of our language, we need to do some fairly abstract work (all of which overlaps the +CS 3240 course, but with a more practical focus). +\medskip + +We have already seen a little of both finite automata and context free grammars, but the following will be +more detailed and organized. +\medskip + +As we do the abstract stuff, we will have in mind two languages. The first will be a +simple calculator language. The second will be the language that you will be asked to +implement in Project 2. Both of these languages will be designed and specified in the +upcoming work. The implementation of the simple calculator language through +a lexical phase and +recursive descent parsing will be worked out fully as an example, leaving you to do +the same things on Project 2. +\border + +{\bf Definition of a Language} +\medskip + +Given a finite set, which is known as an {\it alphabet} (and can be thought of as some set +of ordinary symbols), we define a {\it string\/} +to be any finite sequence of members of the alphabet, and we define a {\it language\/} to +be any set of strings over the alphabet. +\medskip + +\In + For this course, we are interested in situations where a single string is a program in some + programming language, and the language is the set of all syntactically legal programs. +\medskip +\Out +\border + +{\bf Finite Automata} +\medskip + +We already introduced finite automata, so let's do some examples that will +be used in the simple calculator language. +\border + +{\bf Exercise 9} +\medskip + +Working in your small group, draw a finite automaton for each of the following languages: +\medskip + +\Indent{1} +\item{a.} all strings that start with a lowercase letter, followed by zero or more letters or digits +\medskip + +\item{b.} all strings that represent a real number in the way usually +used by humans (no scientific notation allowed), say in a math class. + +\border +\Outdent + +{\bf The Concept of Lexical Analysis as Just a First Step in Parsing} +\medskip + +It turns out that the FA technique is not expressive enough to describe the syntax we want +to have for a typical programming language. +\medskip + +\In + Here's a proof of this fact: we clearly want to have, in a typical + imperative language, the ability to write expressions + such as $((((((a))))))$, where the number of extra parentheses is unlimited. Our parser needs + to be able to check whether there are as many left parentheses as right. But, the FA technique + can't say this. Suppose to the contrary that we have an FA that accepts all strings that + have $n$ left parentheses followed by {\tt a} followed by $n$ right parentheses. Imagine that + you are looking at this wonderful diagram. Since it is a {\it finite\/} state automaton, it has a + finite number of states, say $M$. Now, feed this machine a string that has more than $M$ + left parentheses, followed by an {\tt a}, followed by the same number of right parentheses. + Since there are only $M$ states, in processing the left parentheses, we will visit some state + twice, and there will be a loop in the machine that processes just one or more left parentheses. + Clearly this loop means that the machine will accept strings that it shouldn't accept. +\medskip +\Out + +Since the FA technique can't describe all the syntactic features we want in a programming +language, we will be forced to develop a more powerful approach. But, the FA technique +is still useful, because we will use it for the first phase of parsing, known as {\it lexical analysis}. +This is a very simple idea: we take the stream of physical symbols and use an FA to +process them, producing either an error message or a stream of {\it tokens}. A token is simply +a higher-level symbol that is composed of one or more physical symbols. Then the +remaining parsing takes place on the sequence of tokens. This is done purely as a +matter of convenience and efficiency, because the technique we will develop to do the parsing +is fully capable of doing the tokenizing part as well. +\border + +\vfil\eject + +{\bigboldfont Formal Grammars and Parsing} +\medskip + +We will now learn a technique for specifying the syntax of a language that is more powerful +than the FA approach. One limited version of this approach will let us specify most of the +syntax of a typical programming language. +\bigskip + +A {\it formal grammar\/} consists of a set of {\it non-terminal symbols}, a set of {\it terminal symbols}, +and a set of {\it production rules}. One non-terminal symbol is designated as the {\it start symbol}. +\medskip + +\Indent{1} + As we saw in my specification of Jive, we will often use symbols written between angle brackets, + like {\tt }, to represent + non-terminal symbols. + Terminal symbols will be tokens produced by the lexical analysis phase. + \medskip + + For our early example we will tend to use uppercase letters for non-terminal symbols and + lowercase letters for terminal symbols. +\Outdent + +A production rule has one or more symbols (both terminal and non-terminal allowed) known +as the ``left hand side,'' followed +by a right arrow, followed by one or more symbols known as the ``right hand side.'' +\medskip + +A {\it derivation\/} starts with the start symbol and proceeds by replacing any substring of +the current string that occurs as the left hand side of a rule by the right hand side of that rule, +continuing until a string is reached that has only terminal symbols in it. At this point, that +string of terminal symbols has been proven to be in the language accepted by the grammar. +\medskip + +{\bf A Simple Example} +\medskip + +Here is a simple grammar, where the non-terminals are $S$, $A$, and $B$, and the +$S$ is the start symbol, +and the terminal symbols are $a$, $b$, $c$, and $d$. +\medskip + +$ S \rightarrow AB $ + +$ A \rightarrow a A b $ + +$ A \rightarrow c $ + +$ B \rightarrow d $ + +$ B \rightarrow d B $ +\medskip + +Here is a sample derivation of a string from this grammar, where each line +involves one substitution: +\medskip + +$S$ + +$AB$ + +$ a A b B$ + +$ a a A b b B$ + +$ a a c b b B $ + +$ a a c b b d B $ + +$ a a c b b d d B $ + +$ a a c b b d d d $ + +\medskip + +This derivation shows that {\tt aacbbddd} is in the language accepted by this grammar. +\medskip + +\doit Determine the language accepted by this grammar. Note that it +has parts that could have been accomplished by the FA technique, and parts that +could not. +\border + +{\bf Context Free Grammars} +\medskip + +This formal grammar technique +is a very general tool, but we will focus on a special version known as a +{\it context free grammar} where the left hand side of a rule can only be a single non-terminal +symbol. +\medskip + +Context free grammars are nice because on each step of a derivation, the only question is, +which non-terminal symbol in the current string should we replace by using a rule where +it occurs as the left hand side. +\medskip + +We can now think of what we really mean by parsing. For a context free grammar, the +challenge is to take a given string---an alleged program---and try to find a derivation. +\medskip + +Context free grammars are used because they are powerful enough to specify most of +what we want in the syntax of a language, but are still amenable to being parsed {\it efficiently}. +\medskip + +It is also important to note that for the languages people tend to use, apparently, the +semantics (meaning) of a program are closely related to the syntactic structure. +\medskip + +\Indent{1} +Here is a feature of a typical programming language that isn't captured, typically, by the +context free grammar that specifies the syntax of the language: local variables in Java +have to be defined before they are used. Typically the context free grammar +says that the body of a method consists of a sequence of one or more statements, and +statements are things like {\tt int x;} and {\tt x = 3;}, but the grammar doesn't specify that +one has to occur before the other. Those rules of the language have to be handled in +some other way. +\medskip +\Outdent + +For context free grammars, we can improve on the notation of a derivation a lot by +the {\it parse tree\/} concept. Instead of recopying the current string on each step, we +show the replacement of a left hand side non-terminal symbol by writing a child in the +tree for each symbol in the right hand side. Here is a parse tree for the first example +given: +\medskip + +$$ +\beginpicture +\setcoordinatesystem units <1true pt,1true pt> + \put {S} at 150.0 120.0 + \put {A} at 60.0 90.0 + \put {B} at 210.0 90.0 + \put {a} at 0.0 60.0 + \put {A} at 60.0 60.0 + \put {b} at 120.0 60.0 + \put {d} at 180.0 60.0 + \put {B} at 270.0 60.0 + \put {a} at 30.0 30.0 + \put {A} at 60.0 30.0 + \put {b} at 90.0 30.0 + \put {d} at 240.0 30.0 + \put {B} at 300.0 30.0 + \put {c} at 60.0 0.0 + \put {d} at 300.0 0.0 +% Edge from 1 to 2: + \plot 141.0 117.0 68.0 92.0 / + \put {} at 141.0 117.0 +% Edge from 1 to 3: + \plot 158.0 115.0 201.0 94.0 / + \put {} at 158.0 115.0 +% Edge from 2 to 4: + \plot 51.0 85.0 8.0 64.0 / + \put {} at 51.0 85.0 +% Edge from 2 to 5: + \plot 60.0 81.0 60.0 69.0 / + \put {} at 60.0 81.0 +% Edge from 2 to 6: + \plot 68.0 85.0 111.0 64.0 / + \put {} at 68.0 85.0 +% Edge from 3 to 7: + \plot 203.0 83.0 186.0 66.0 / + \put {} at 203.0 83.0 +% Edge from 3 to 8: + \plot 218.0 85.0 261.0 64.0 / + \put {} at 218.0 85.0 +% Edge from 5 to 9: + \plot 53.0 53.0 36.0 36.0 / + \put {} at 53.0 53.0 +% Edge from 5 to 10: + \plot 60.0 51.0 60.0 39.0 / + \put {} at 60.0 51.0 +% Edge from 5 to 11: + \plot 66.0 53.0 83.0 36.0 / + \put {} at 66.0 53.0 +% Edge from 8 to 12: + \plot 263.0 53.0 246.0 36.0 / + \put {} at 263.0 53.0 +% Edge from 8 to 13: + \plot 276.0 53.0 293.0 36.0 / + \put {} at 276.0 53.0 +% Edge from 10 to 14: + \plot 60.0 21.0 60.0 9.0 / + \put {} at 60.0 21.0 +% Edge from 13 to 15: + \plot 300.0 21.0 300.0 9.0 / + \put {} at 300.0 21.0 +\endpicture +$$ +\border + +\vfil\eject + +{\bf A Bad Way to Try to Express Expressions} +\medskip + +Consider the following grammar, where $E$ is the start symbol, and +$V$ and $N$ are viewed as terminal symbols namely tokens representing +variables and numeric literals, and other symbols that are not uppercase letters +are viewed as tokens. +\medskip + +$ E \rightarrow N$ + +$ E \rightarrow V$ + +$ E \rightarrow E + E $ + +$ E \rightarrow E * E $ + +$ E \rightarrow (E)$ +\medskip + +This grammar seems reasonable, but it turns out to be a rather poor way to specify +a language consisting of all mathematical expressions using variables, numeric literals, +addition, multiplication, and parentheses. For one thing, the grammar is ambiguous---there +are strings that have significantly different parse trees. For another, the grammar has no +concept of operator precedence. +\medskip + +\doit Come up with some expressions and produce parse trees for them. +Verify the complaints just made. +\border + +{\bf A Classic Example of a Context Free Grammar} +\medskip + +Now consider this grammar for the language of simple expressions, +where $E$ is the start symbol, and +$V$ and $N$ are viewed as terminal symbols, namely tokens representing +variables and numeric literals, and other symbols that are not uppercase letters +are viewed as tokens. +\medskip + +$E \rightarrow T$ + +$E \rightarrow T+E$ + +$T \rightarrow F$ + +$ T \rightarrow F * T$ + +$F \rightarrow V$ + +$F \rightarrow N$ + +$F \rightarrow (E)$ +\medskip + +\doit This grammar captures the syntax of an {\it expression} involving two +binary operators with different precedence. Produce parse trees for some expressions and +note that the grammar is not ambiguous and enforces operator precedence. +\border + +{\bf Parse Trees as Code} +\medskip + +The previous example suggests a powerful idea: if someone gives you a parse tree for an +expression, and values for all the variables occurring, you can easily compute the value +of the expression---and you can easily write code that interprets the parse tree. +\medskip + +Thus, in a very real sense, the tree structure is a better programming language than +the language described by the context free grammar, except for one big catch: it's hard to +read and write parse trees, compared to reading and writing strings. +\border + +{\bf Exercise 10} +\medskip + +Working in your small group, produce a parse tree for the following expression, using the good +expression grammar. +Then, assuming that $a=12$, $b=7$, and $c=2$, show how the parse tree can be used to +compute the value of the expression---note how the value of each node in the parse tree +is obtained from the values of its children. +\medskip + +Use this expression: + +$$ 7*a + (c*a*c+4*a)*b $$ +\border + +{\bf Designing and Specifying the Simple Calculator Language} +\medskip + +Now we want to design (and then implement) a language that allows the user to +perform a sequence of computations such as a person could do on a calculator. +But, we want the language to allow use of expressions and assignment statements. +\medskip + +\doit As a whole group, invent a name for this language, and write some example programs +so everyone will see the sorts of things we want to allow, and the sorts of things we don't want +to allow. +\border + +{\bf Exercise 11} +\medskip + +Working in your small group, specify the simple calculator language by determining its +tokens (categories of conceptual symbols, such as probably {\tt } for variable), +drawing an FA for each kind of token, and writing a context free grammar for the +language. +\medskip + +Use {\tt } for the start variable, which should produce any possible program in the +language. +\border + +\doit Working back together as a whole group, write down the final specification +for the simple calculator language. +\border + +{\bf Implementing the Lexical Phase} +\medskip + +\doit As a whole group, produce a Java class named {\tt Lexer} that +will take a file containing a program in the simple calculator language as input and produce a sequence of tokens. +In addition to producing this stream of tokens, {\tt Lexer} should have the ability to ``put back'' a token, for convenience +in the recursive descent parsing phase. The point is that we will produce a grammar that will allow us to +look ahead at the next token, thinking it will be part of the entity we are producing, and then realize from that next token +that we are done with the entity we were producing, so it is convenient to put back the look ahead token. + +\vfil\eject +%\bye + +{\bf Implementing The Simple Calculator Language} +\medskip + +\doit + Working as a whole group, + finish the draft design of the simple calculator language, +and write down a context free grammar to specify it. +\medskip + +\Indent{1} +As we do this, we want to try to write the rules so that they process symbols on the +left, leaving the recursive parts on the right. +For example, if we want to say ``1 or more {\tt a}'s'' we could either use the +rules +$$ A \rightarrow Aa \; \vert \; a $$ +or we could say +$$ A \rightarrow aA \; \vert \; a $$ + +with the same result from a theoretical perspective. +But, because we want to use the {\it recursive descent parsing\/} technique (there are other +parsing techniques that we will not study that like grammars in different forms), +we will want to use the second approach. +\medskip +\Outdent + +\border + +\doit Working as a whole group, begin work on a class {\tt Parser} that will take +a {\tt Lexer} as a source of tokens and produce a {\it parse tree\/} that represents a simple calculator +language program in a way that it can be directly executed. +\medskip + +\Indent{1} +As a practical matter, to save some time +we will begin with some old code that I produced for a different language and modify it massively +to do the job for our new language. +\medskip + +Note that along with the {\tt Lexer} and {\tt Parser} classes, this old code includes {\tt Token} and +{\tt Node} classes that will be used extensively in our work. +\medskip + +The classes {\tt Basic}, {\tt Camera}, and {\tt TreeViewer} support visualizing a parse tree for +debugging and testing purposes. +\medskip +\Outdent + +As we will see, the recursive descent parsing technique involves writing a method for every non-terminal +symbol in the grammar. Each of these methods will consume a sequence of tokens and produce a +node that is the root of a tree that is the translation of the corresponding chunk of code. +\medskip + +Also, these methods will return {\tt null} if they realize that the next few tokens don't fit what they are +expecting to see. +\medskip + +We will not take the time to be very careful about detecting and reporting errors in the source code. +We will basically assume that the source code is correct. But, when it makes sense to do so, we will +notice errors and halt the parsing process with some error message to the programmer. +\border + +\vfil\eject + +{\bf Final (?) Finite Automata for Lexer for Corgi} +\bigskip + +\epsfbox{../Secret/Corgi/Figures/corgiFA.1} +\border + +\doit Instructor will briefly discuss {\tt Lexer} and {\tt Parser} in preparation for Exercises 12 and 13. +\border + +{\bf Exercise 12} +Working in your small group, write the code for state 3, 4, and 5 in the {\tt Lexer.java} file for Corgi. +To help you understand {\tt Lexer} and do this Exercise effectively, a number of trees have been +killed to provide you with a printout of the existing code on the next pages. +\vfil\eject + +\count255 1 +\numberedListing{../Corgi/Lexer.java}{\tt} +\border + +{\bf Exercise 13} +Working in your small group, write the code for {\tt parseFactor} in +the class {\tt Parser}, listed on the next few pages. +\bigskip + +Here is the draft context free grammar for Corgi (note some changes from our earlier version): +\medskip + +{\baselineskip 0.95 \baselineskip +\listing{../Corgi/corgiCFG.txt} + +\border} + +\count255 1 +\numberedListing{../Corgi/Parser.java}{\tt} + +\vfil\eject + +\doit Instructor will discuss the minor changes to {\tt Parser} (listed in its entirety below) +and draw a parse tree for +a Corgi program. +\border + +{\bf Exercise 14} +Working in your small groups, construct the parse tree for {\tt quadroots} following the final (I hope!) +version of {\tt Parser}. +\border + +{\baselineskip 0.75\baselineskip +\count255 1 +\font \smalltt cmtt10 scaled 800 +\numberedListing{../Corgi/Parser.java}{\smalltt} +\border +} + +{\bf Exercise 15} +Below you will find a partial listing of the {\tt Node} class, namely the partially completed +{\tt execute} and {\tt evaluate} methods. +Working in your small groups, +write the missing code. +\medskip + +Note that nodes have instance variables {\tt kind}, {\tt info} (both strings), and +{\tt first} and {\tt second} (both nodes). +\medskip + +Also, there is a {\tt MemTable} class that has public methods + + {\tt void store( String name, double value)} + +and + +{\tt double retrieve( String name)} +\medskip + +If you need further details about any of the classes in the {\tt Corgi} project +(namely {\tt Corgi}, {\tt Token}, {\tt Lexer}, {\tt Parser}, {\tt Node}, and {\tt MemTable}, +you should look at them online (assuming someone in your group has a computer in class). + +\vfil\eject + +\count255 136 +\numberedListing{../Corgi/partialNode.java}{\tt} + +\vfil\eject + +{\bigboldfont Designing Project 2} +\medskip + +To keep Project 2 manageable (a first serious submission for Project 2 must be submitted by the time of Test 2---October 29), +I have decided to make this project be to simply (we hope!) add some +features to Corgi as follows. +\medskip + +\Indent{1} +First, we want to give the Corgi programmer the ability to define functions, and of course to call them. +\medskip + +Second, we want to add branching to Corgi. +\medskip +\Outdent + +\doit Working as a whole group, design the finite automata for the Corgi {\tt Lexer}, and the +context free grammar for the Corgi {\tt Parser}. +Discuss the features we are not adding to Corgi, and perhaps decide to add some of them. +As part of this design process, write some sample Corgi programs (these will also provide a +starting point for testing your Project 2 work). +\medskip + +\doit Once the syntax of the language is specified, try to specify the {\it semantics\/} of the language, +and think about how execution/evaluation of the parse tree will be done. +\bigskip + +{\bf Note:} after we have made decisions about the new and improved Corgi, +henceforth to be known as ``Corgi,'' I will document them. +But, you should be able to start working on Project 2 right away, based on the informal +documentation recorded during this class session. +\border + +{\bigboldfont Project 2} [10 points] [first serious submission absolutely due by October 29] +\medskip + +Implement the extended Corgi language as specified in class and in upcoming documents. +Be alert for corrections to the Corgi specification that may need to be made as work proceeds. +\medskip + +Be sure to test your implementation thoroughly. +\medskip + +Email me your group's submission with a single {\tt zip} or {\tt jar} file attached, named either +{\tt corgi.jar} or {\tt corgi.zip}. This single file must contain all the source code files. +Be sure to CC all group members on the email that submits your work. +\medskip + +I must be able to extract all the Java source files from your submitted file into a folder, and then simply +type at the command prompt: +\medskip + +{\tt javac Corgi.java} + +{\tt java Corgi test3} +\medskip + +in order to run the Corgi program in the file named {\tt test3}. +\border + +\vfil\eject + +\bye + +{\bf Designing Project 2} +\medskip + +\doit Discuss possibilities for Project 2 and decide what it should be. +% Then, we'll apply CYK and/or recursive descent to it +\vfil\eject + +{\bigboldfont Course Policy Change} +\medskip +Test 2 is canceled, due to the facts that we haven't covered enough material suitable for fair assessment, +and we have just barely gotten to the main topics of language implementation. +\medskip + +The test scheduled for April 13 will cover the material we have been and are still working on, along +with some functional programming topics, about equally weighted. The test at the time of the final exam +will cover Clojure and Prolog topics. +\medskip + +Your course grade will be figured with the 68\% for Tests divided either into 3 or 4, with the next test counting +as two tests or one, and taking the maximum of the two calculations. +\border + +{\bigboldfont Otter} +\medskip + +I had been thinking Project 2 would be to finish implementing Otter, but now I'm thinking Project 2 will be +to implement the ``simple example'' we started on February 28th. We will spend a few more class periods +working through implementation of Otter together (with me, unfortunately, doing most of the work outside of +class). +\border + +{\bigboldfont Project 2} +\medskip + +Implement the simple calculator language (let's call it ``CalcLang'') designed in class, with that design +documented (including the finite automaton for the lexical part of the language, the context free grammar, +and an informal description of the language semantics) in the folder {\tt Project2} at the course web stie. +\medskip + +When you are done, you will have an application consisting of several Java classes. You must submit your +work to me as follows: +\medskip + +\In + Make sure that the main class---the one that contains the {\tt main} method at which execution starts---is + named exactly {\tt CalcLang}. + \medskip + + Clean up your source files for submission by removing all non-portable {\tt package} statements and + all extraneous output. + \medskip + + Put all your source files in a folder, named {\tt Project2}. + Create a {\tt jar} file from the command line by moving into the folder that contains the folder {\tt Project2} + and entering + \smallskip + {\tt jar cvfM proj2.jar Project2} + \medskip + + Test your work by making a temporary folder somewhere, copying {\tt proj2.jar} into it, moving into it, + and entering + \smallskip + {\tt jar xf proj2.jar} + \smallskip + This should make a folder {\tt Project2} that contains all your source code. Move into it and compile and + run your application. + \medskip + + Email me your submission with {\tt proj2.jar} attached at {\tt shultzj@msudenver.edu} + \bigskip + + If you are somehow incapable of doing the previous work, you may as a slightly irritating (to me) alternative + make a {\tt zip} file of the folder containing your source code instead of a {\tt jar} file. +\medskip +\Out + + + +\vfil\eject +\bye + diff --git a/Documents/intro.pdf b/Documents/intro.pdf new file mode 100755 index 0000000..7ebb4e8 Binary files /dev/null and b/Documents/intro.pdf differ diff --git a/Documents/intro.tex b/Documents/intro.tex new file mode 100755 index 0000000..b018979 --- /dev/null +++ b/Documents/intro.tex @@ -0,0 +1,1945 @@ +\input pictex +\input /Users/Shared/TeX/defs + +\advance \hoffset 0.25 true in + +\startDoc{CS 3210 Fall 2018}{1}{Introduction} + +{\bigboldfont Introduction to the Course} +\medskip + +This course will cover four main themes: +techniques for specifying programming languages, +implementation of programming languages, +exposure to alternative programming language paradigms, and +issues in the design of programming languages. +\medskip + +{\bf Note:} frequently in these course notes you will find this symbol: $\Rightarrow$ in the +margin. Wherever this occurs, we will do this work during a mini-lecture, +recording our results either in a snapshot of the board or a text file. +\bigskip + +{\bf Some Introductory Questions} +\medskip + +\doit What is a programming language? +\medskip + +\doit +In the Web search for {\tt programming paradigms} and note the main four that +we will study. +\medskip + +\doit +In the Web, search for {\tt history of programming languages} and specifically look for +a timeline, and ponder the list, including noting the paradigm(s) some of them belong to. +\medskip + +\doit Go to {\tt www.tiobe.com/tiobe-index} and observe the popularity of various +programming languages at this moment in time. +\border + +{\bigboldfont A Very Primitive Language} +\medskip + +For the rest of our introduction to the course (including in-depth study of a number of important +issues relating to designing and implementing imperative programming languages), we will +study a toy language known as VPL (for ``very primitive language''). +\medskip + +To begin, we will specify the syntax and semantics of VPL, and then +you will have a project to implement VPL (which will turn out to be fairly easy). +\medskip + +The main requirement for this language is that it be very easy to specify and implement. +One major consequence of this requirement is that we will only work with integer values, +and input/output operations and other utility functions that could easily be provided are +kept to a minimum. +\medskip + +This work provides a first example of specification of +a programming language, +begins our study of implementation of programming languages, +will be used later as the platform for discussing all sorts of imperative language +implementation issues, and will provide a very gentle introduction to language design +issues. +\medskip + +In a sense, all procedural + languages are just spiffed up versions of a language such +as this. +\medskip + +The following description of VPL +mostly only makes sense in the context of the implementation we +have in mind, so implementation suggestions will be integrated with +the language description. This makes sense, since we are sort of +creating a virtual processor as we describe the language. + +\vfil\eject + +{\bf The VPL Memory Model} +\medskip + +The memory model consists of a rather large one-dimensional array, +named {\tt mem} in the following discussion, together with a number +of individual variables, including ones named {\tt ip}, {\tt sp}, {\tt bp}, {\tt rv}, +{\tt hp}, and {\tt gp} that are referred to as {\it registers}. +\medskip + +Each location in this +array is known as a memory cell, or just cell. +This array holds the stored program, starting in cell 0 and continuing as +needed. The global memory area begins where +the stored program ends. The system stack begins where the global memory area ends. +The area for dynamic memory, known as the ``heap,'' +begins at the upper end of the array and continues downward. +\medskip + +While the program is executing, the instruction pointer register {\tt ip} +will hold the index of the cell containing the operation code for the +instruction that is currently executing. +\medskip + +The ``global pointer'' register {\tt gp} holds the first index after the stored +program. +\medskip + +At all times the base pointer register {\tt bp} will hold the index of the +smallest cell in the region of memory used for the currently active +subprogram, which is known as the ``stack frame,'' +and the stack pointer register {\tt sp} will hold the index +of the first cell above the stack frame. +\medskip + +The heap pointer register {\tt hp} will point to the first cell of the +most recently allocated chunk of memory, so that the region with +indices smaller than {\tt hp} will be available for allocation. +\medskip + +The return value register {\tt rv} is used to hold the single +value being returned by a subprogram. +\medskip + +Here is a picture of the memory layout: +\medskip + +\beginpicture +\setcoordinatesystem units <1 true cm,1true cm> +\putrectangle corners at 0 0 and 16 1 +\put {\tinytt MEM} [b] at 16.2 1.2 +\putrule from 5 0 to 5 1 +\put {\tt code} at 2.5 0.5 +\putrule from 7 0 to 7 1 +\put {\tt globals} at 6 0.5 +\put {\tt stack} at 8.5 0.5 +\put {$\rightarrow$} at 10 0.5 +\put {$\cdots$} at 12 0.5 +\put {$\leftarrow$} at 13.5 0.5 +\put {\tt heap} at 15 0.5 +\put {\tinytt 0} at 0.2 1.2 +\put {\tinytt ip} at 3 1.2 +\put {\tinytt gp} at 5.2 1.2 +\put {\tinytt bp} at 8.5 1.2 +\put {\tinytt sp} at 9.2 1.2 +\put {\tinytt hp} at 14 1.2 +\endpicture + +\bigskip + +{\bf The Instructions and Execution Semantics} +\medskip + +We will now see our first example of specifying a programming language---we will +specify the {\it syntax}---the rules for what sequences of symbols constitute a legal +program in VPL---and the {\it semantics}---the meaning of a VPL program. +For this very simple language, we will be able to specify these things quite easily. +In fact, the previous ``memory model'' discussion has begun the description of the +semantics of VPL. +\bigskip + +Execution starts with {\tt ip} set to 0. Note that all the registers +need to be properly initialized. +After each instruction has executed, {\tt ip} has either been moved +to a different value, or it moves to the sequentially next instruction. +\medskip + +When input arguments are passed, a subprogram is called, +or a subprogram is returned from, we will need to manage the +details of the stack frame to make recursion possible. +In particular, in addition to allocating space in a stack frame +for the input arguments and local variables, we will need to have +space for storing the values of any registers that need to be +restored when you return from a subprogram. However we do this +we want to set things up so that all ``variables'' in a subprogram, +including arguments and locals, will be named 0, 1, 2, and so on, with +the input arguments being 0, 1, 2, and so on. +\medskip + +We will assume that arguments are always passed immediately before +calling a subprogram. +\medskip + +Here are the draft details of the operations. +In this description, the syntax of each instruction is given +implicitly through an abstract example. In the abstract +examples, every symbol represents an integer, +but as an aid to understanding the semantics, +integer literals are operation codes, {\tt n} represents +an integer literal, +{\tt a}, {\tt b}, and {\tt c} represent offsets in the current +stack from {\tt bp} (and ``cell a'' actually means the +array location with index {\tt bp+2+a}), +and +{\tt L} represents a label. +\medskip + +\halign{\tabskip 0.25true in +{\tt #}\hfil& #\hfil& \vtop{\hsize 3.5true in \baselineskip 0.8\baselineskip #}\hfil\cr +\noalign{\smallskip\hrule\smallskip} +Instruction& Mnemonic& Semantic Description\cr +\noalign{\smallskip\hrule\smallskip} +0& no op& Do nothing.\cr +\noalign{\medskip} +1 L& label& During program loading this instruction disappears, and all + occurrences of {\tt L} are replaced by the actual index in {\tt mem} + where the opcode {\tt 1} would have been stored.\cr +\noalign{\medskip} +2 L& call& Do all the steps necessary to set up for execution of the subprogram + that begins at label {\tt L}.\cr +\noalign{\medskip} +3 a& pass& Push the contents of cell {\tt a} on the stack.\cr +\noalign{\medskip} +4 n& locals& Increase {\tt sp} by {\tt n} to make space for local variables in + the current stack frame.\cr +\noalign{\medskip} +5 a& return& Do all the steps necessary to return from the current subprogram, + including putting the value stored in cell {\tt a} in {\tt rv}.\cr +\noalign{\medskip} +6 a& get retval& Copy the value stored in {\tt rv} into cell {\tt a}.\cr +\noalign{\medskip} +7 L& jump& Change {\tt ip} to {\tt L}.\cr +\noalign{\medskip} +8 L a& cond& If the value stored in cell {\tt a} is non-zero, change {\tt ip} to {\tt L} + (otherwise, move {\tt ip} to the next instruction).\cr +\noalign{\medskip} +9 a b c& add& Add the values in cell {\tt b} and cell {\tt c} and store the result + in cell {\tt a}.\cr +\noalign{\medskip} +10 a b c& subtract& Same as 9, but do cell {\tt b} $-$ cell {\tt c}.\cr +\noalign{\medskip} +11 a b c& multiply& Same as 9, but do cell {\tt b} $*$ cell {\tt c}.\cr +\noalign{\medskip} +12 a b c& divide& Same as 9, but do cell {\tt b} $/$ cell {\tt c}.\cr +\noalign{\medskip} +13 a b c& remainder& Same as 9, but do cell {\tt b} \% cell {\tt c}.\cr +\noalign{\medskip} +14 a b c& equal& Same as 9, but do cell {\tt b} {\tt ==} cell {\tt c}.\cr +\noalign{\medskip} +15 a b c& not equal& Same as 9, but do cell {\tt b} {\tt !=} cell {\tt c}.\cr +\noalign{\medskip} +16 a b c& less than& Same as 9, but do cell {\tt b} {\tt <} cell {\tt c}.\cr +\noalign{\medskip} +17 a b c& less than or equal& Same as 9, but do cell {\tt b} {\tt <=} cell {\tt c}.\cr +\noalign{\medskip} +18 a b c& and& Same as 9, but do cell {\tt b} $\&\&$ cell {\tt c}.\cr +\noalign{\medskip} +19 a b c& or& Same as 9, but do cell {\tt b} {\tt ||} cell {\tt c}.\cr +\noalign{\medskip} +20 a b& not& If cell {\tt b} holds zero, put 1 in cell {\tt a}, + otherwise put 0 in cell {\tt a}.\cr +\noalign{\medskip} +21 a b& opposite& Put the opposite of the contents of cell {\tt b} in cell {\tt a}.\cr +\noalign{\medskip} +22 a n& literal& Put {\tt n} in cell {\tt a}.\cr +\noalign{\medskip} +23 a b& copy& Copy the value in cell {\tt b} into cell {\tt a}.\cr +\noalign{\medskip} +24 a b c& get& Get the value stored in the heap at the index obtained by adding + the value of cell {\tt b} and the value of cell {\tt c} and copy + it into cell {\tt a}.\cr +\noalign{\medskip} +25 a b c& put& Take the value from cell {\tt c} and store it in the heap at the + location with index computed as the value in cell {\tt a} plus + the value in cell {\tt b}.\cr +\noalign{\medskip} +26& halt& Halt execution.\cr +\noalign{\medskip} +27 a& input& Print a {\tt ?} and a space in the console and wait for an + integer value to be typed by the user, and then store it in cell + {\tt a}.\cr +\noalign{\medskip} +28 a& output& Display the value stored in cell {\tt a} in the console.\cr +\noalign{\medskip} +29& newline& Move the console cursor to the beginning of the next line\cr +\noalign{\medskip} +30 a& symbol& If the value stored in cell {\tt a} is between 32 and 126, display + the corresponding symbol at the console cursor, otherwise + do nothing.\cr +\noalign{\medskip} + 31 a b& new& Let the value stored in cell {\tt b} be denoted by $m$. + Decrease {\tt hp} by $m$ and put the new value of {\tt hp} + in cell {\tt a}.\cr +\noalign{\medskip} +32 n& allocate global space& This instruction must occur first in any program that +uses it. It simply sets the initial value of {\tt sp} to {\tt n} cells beyond the end of stored +program memory, and sets {\tt gp} to the end of stored program memory.\cr +\noalign{\medskip} +33 n a& Copy to global& Copy the contents of cell {\tt a} to the global memory area at index {\tt gp+n}.\cr +\noalign{\medskip} +34 a n& Copy from global& Copy the contents of the global memory cell at index {\tt gp+n} into cell {\tt a}.\cr +\noalign{\smallskip\hrule\smallskip} +} +\medskip + +The C strategy of ``non-zero is true, zero is false'' is used where appropriate. +C style psuedo-code is used to describe the various operations 9--19. +\medskip +\hrule +\bigskip + +\vfil\eject + +{\bf Exercise 1} +\medskip + +Working in whiteboard groups (ideally 4 or 5 people), write the following simple programs in VPL. +\medskip + +\item{a.} Create a single global variable and store 17 in it. +Display a question mark in the console, get input from the keyboard, and store it in a local cell. +Add that input value to the global variable value and display the result in the console. +\medskip + +\item{b.} Create a VPL program that asks the user for an input value and +displays 1 if that input is an odd number, and 2 if it is an even number. +\medskip + +\item{c.} Create a VPL program that asks the user for a value of {\tt number} and then +displays on-screen (in the console) the values 1, 2, $\ldots$, {\tt number}, one per line. +\medskip + +\item{d.} Create a VPL program that gets an input value, say $x$, and repeatedly +divides $x$ by 2 if $x$ is even or multiplies $x$ by 3 and adds 1, until $x$ reaches $1$. +\border + +{\bf The Stack Frame Model} +\medskip + +In order to implement subprograms in the usual way (later we will discuss +simpler memory models) we need to give each subprogram call its own memory area, +known as a {\it stack frame} (or ``activation record''). +\medskip + +Here is a picture of the layout of a {\it stack frame} the way we will do it +in VPL. This layout, combined with commands 2--6, +allows the VPL programmer to use {\it modularity}---to be able to use subprograms. +\bigskip + +\beginpicture +\setcoordinatesystem units <1.25 true cm,1true cm> +\putrule from 0 0 to 11 0 +\putrule from 0 1 to 11 1 +\putrule from 1 0 to 1 1 +\putrule from 2 -0.5 to 2 1.5 \put {\tinytt bp} [b] at 2.5 1.2 +\putrule from 3 0 to 3 1 \put {\tinytt return} at 2.5 0.66 \put {\tinytt ip} at 2.5 0.33 +\putrule from 4 0 to 4 1 \put {\tinytt return} at 3.5 0.66 \put {\tinytt bp} at 3.5 0.33 +\putrule from 5 0 to 5 1 \put {\tinytt 0} [t] at 4.5 -0.2 +\putrule from 6 0 to 6 1 \put {\tinytt 1} [t] at 5.5 -0.2 +\putrule from 7 0 to 7 1 \put {\tinytt 2} [t] at 6.5 -0.2 +\put {$\cdots$} at 8 0.5 + \put {\tinytt sp} [b] at 9.5 1.2 +\putrule from 10 0 to 10 1 +\linethickness 2true pt +\putrule from 2 -0.5 to 2 1.5 +\putrule from 9 -0.5 to 9 1.5 \endpicture +\bigskip + +With this model, a {\it stack frame\/} consists of all the memory cells from index {\tt bp} up to +but not including index {\tt sp}. +\medskip + +To call a subprogram, first we have to use command 3 once for each value that we want to +pass over to the next stack frame. +Then we use command 2 to call the desired subprogram. +This command stores the correct values of the current base pointer and instruction pointer in the +first two cells of the new stack frame. +Note that the arguments passed by command 3 sit just to the right of those two cells. +\medskip + +And, command 2 has to change the instruction pointer to the starting point in the code segment +of the subprogram being called. +\medskip + +The first command in the subprogram must be command 4, which simply moves the stack pointer +to the right to make space for the local variables in the stack frame. +So, if for example we passed two arguments, then the cells conceptually labeled (underneath) 0 and +1 will hold the values of those parameters (to use Java terminology), while cells conceptually +labeled 2, 3, and so on, will be local variables for the subprogram. +\medskip + +When command 5 executes, it puts the value to be returned in the return value register, and +then restores the base pointer, the stack pointer, and the instruction pointer, thus returning both in +code and in the stack to the stack frame from which the call was made. +\medskip + +Then in the calling stack frame, command 6 moves the returned value into a local cell. +\border + +{\bf Exercise 2} +\medskip + +Here is a VPL program (a very bad one in the sense that it has no comments!): +\medskip + +\verbatim +4 3 +27 0 +3 0 +2 1001 +6 1 +28 1 +29 +26 + +1 1001 +4 6 +22 2 2 +22 1 1 +16 6 0 2 +8 2001 6 +10 3 0 1 +3 3 +2 1001 +6 4 +11 5 0 4 +5 5 +1 2001 +5 1 +|endverbatim +\medskip +\bigskip + +Trace the execution of this program. +Your group will need to draw a bunch of memory cells. +Since you have a narrow piece of whiteboard, break the long strip of +cells into convenient horizontal pieces, say using 10 cells per piece. +\medskip + +As you write the numbers for the code in the code section, be sure to +remove the label commands and to change all the ``jump'' commands to +use the index where the label command would be. +\medskip + +As you trace the commands, keep track of the {\tt ip}, {\tt bp}, and {\tt sp} +by writing them in above the correct memory cells and erasing the previous +values. +\medskip + +And, of course, trace what is written in the console. +\vfil\eject + +{\bf Wrap-Up Exercise 1} +\medskip + +My solutions to Exercise 1 are in the VPL folder. +Make sure that you finish Exercise 1 on your own time, +as needed, with these to help. +\medskip + +Also, use these programs as some of your test cases for Project 1. +\border + +{\bf Exercise 3} +\medskip + +Working in whiteboard groups (ideally 4 or 5 people), +write this program, which includes two useful subprograms: +\medskip + +\Indent{.5} +Write a subprogram, starting with label 100000, + that takes as its single input argument a positive integer $n$, and then + allocates $n+1$ cells in the heap, stores $n$ in the first of these + cells, and then asks the user for $n$ numbers, storing them in the remaining $n$ cells, + and returns the address in memory where the list begins. + \medskip + + Write a subprogram, starting with label 200000, + that takes as its single input argument the index in memory of the + starting point of a list, stored as for subprogram 100000, + and then displays the list on a single line, with items separated by spaces. + \medskip + +Then write a main program that will call the list input subprogram and then call the +list display subprogram. +\medskip + +Someone in your group should record your final work in a computer file and email it +to everyone in the group, because you will want to use this program as a test case +for your Project 1 work. +\border +\Outdent + +\vfil\eject + +{\bf Exercise 4} +\medskip + +Trace the execution of the code shown below. +Draw on the whiteboard memory cells from 70 on, and trace +all the operations, assuming the user inputs 4 and then 2. +\medskip + +\beginpicture +\setcoordinatesystem units <0.4true in, 0.3true in> +\putrectangle corners at 0.0 15.75 and 1.0 16.75 +\put {$\scriptstyle 27$} at 0.5 16.25 +\put {$\scriptstyle 0$} [b] at 0.5 16.83 +\put {\tt ip} [b] at 0.5 17.15 +\putrectangle corners at 1.0 15.75 and 2.0 16.75 +\put {$\scriptstyle 0$} at 1.5 16.25 +\put {$\scriptstyle 1$} [b] at 1.5 16.83 +\putrectangle corners at 2.0 15.75 and 3.0 16.75 +\put {$\scriptstyle 27$} at 2.5 16.25 +\put {$\scriptstyle 2$} [b] at 2.5 16.83 +\putrectangle corners at 3.0 15.75 and 4.0 16.75 +\put {$\scriptstyle 1$} at 3.5 16.25 +\put {$\scriptstyle 3$} [b] at 3.5 16.83 +\putrectangle corners at 4.0 15.75 and 5.0 16.75 +\put {$\scriptstyle 3$} at 4.5 16.25 +\put {$\scriptstyle 4$} [b] at 4.5 16.83 +\putrectangle corners at 5.0 15.75 and 6.0 16.75 +\put {$\scriptstyle 0$} at 5.5 16.25 +\put {$\scriptstyle 5$} [b] at 5.5 16.83 +\putrectangle corners at 6.0 15.75 and 7.0 16.75 +\put {$\scriptstyle 3$} at 6.5 16.25 +\put {$\scriptstyle 6$} [b] at 6.5 16.83 +\putrectangle corners at 7.0 15.75 and 8.0 16.75 +\put {$\scriptstyle 1$} at 7.5 16.25 +\put {$\scriptstyle 7$} [b] at 7.5 16.83 +\putrectangle corners at 8.0 15.75 and 9.0 16.75 +\put {$\scriptstyle 2$} at 8.5 16.25 +\put {$\scriptstyle 8$} [b] at 8.5 16.83 +\putrectangle corners at 9.0 15.75 and 10.0 16.75 +\put {$\scriptstyle 16$} at 9.5 16.25 +\put {$\scriptstyle 9$} [b] at 9.5 16.83 +\putrectangle corners at 0.0 13.5 and 1.0 14.5 +\put {$\scriptstyle 6$} at 0.5 14.0 +\put {$\scriptstyle 10$} [b] at 0.5 14.58 +\putrectangle corners at 1.0 13.5 and 2.0 14.5 +\put {$\scriptstyle 2$} at 1.5 14.0 +\put {$\scriptstyle 11$} [b] at 1.5 14.58 +\putrectangle corners at 2.0 13.5 and 3.0 14.5 +\put {$\scriptstyle 28$} at 2.5 14.0 +\put {$\scriptstyle 12$} [b] at 2.5 14.58 +\putrectangle corners at 3.0 13.5 and 4.0 14.5 +\put {$\scriptstyle 2$} at 3.5 14.0 +\put {$\scriptstyle 13$} [b] at 3.5 14.58 +\putrectangle corners at 4.0 13.5 and 5.0 14.5 +\put {$\scriptstyle 29$} at 4.5 14.0 +\put {$\scriptstyle 14$} [b] at 4.5 14.58 +\putrectangle corners at 5.0 13.5 and 6.0 14.5 +\put {$\scriptstyle 26$} at 5.5 14.0 +\put {$\scriptstyle 15$} [b] at 5.5 14.58 +\putrectangle corners at 6.0 13.5 and 7.0 14.5 +\put {$\scriptstyle 4$} at 6.5 14.0 +\put {$\scriptstyle 16$} [b] at 6.5 14.58 +\putrectangle corners at 7.0 13.5 and 8.0 14.5 +\put {$\scriptstyle 5$} at 7.5 14.0 +\put {$\scriptstyle 17$} [b] at 7.5 14.58 +\putrectangle corners at 8.0 13.5 and 9.0 14.5 +\put {$\scriptstyle 22$} at 8.5 14.0 +\put {$\scriptstyle 18$} [b] at 8.5 14.58 +\putrectangle corners at 9.0 13.5 and 10.0 14.5 +\put {$\scriptstyle 2$} at 9.5 14.0 +\put {$\scriptstyle 19$} [b] at 9.5 14.58 +\putrectangle corners at 0.0 11.25 and 1.0 12.25 +\put {$\scriptstyle 1$} at 0.5 11.75 +\put {$\scriptstyle 20$} [b] at 0.5 12.33 +\putrectangle corners at 1.0 11.25 and 2.0 12.25 +\put {$\scriptstyle 22$} at 1.5 11.75 +\put {$\scriptstyle 21$} [b] at 1.5 12.33 +\putrectangle corners at 2.0 11.25 and 3.0 12.25 +\put {$\scriptstyle 5$} at 2.5 11.75 +\put {$\scriptstyle 22$} [b] at 2.5 12.33 +\putrectangle corners at 3.0 11.25 and 4.0 12.25 +\put {$\scriptstyle 0$} at 3.5 11.75 +\put {$\scriptstyle 23$} [b] at 3.5 12.33 +\putrectangle corners at 4.0 11.25 and 5.0 12.25 +\put {$\scriptstyle 14$} at 4.5 11.75 +\put {$\scriptstyle 24$} [b] at 4.5 12.33 +\putrectangle corners at 5.0 11.25 and 6.0 12.25 +\put {$\scriptstyle 6$} at 5.5 11.75 +\put {$\scriptstyle 25$} [b] at 5.5 12.33 +\putrectangle corners at 6.0 11.25 and 7.0 12.25 +\put {$\scriptstyle 1$} at 6.5 11.75 +\put {$\scriptstyle 26$} [b] at 6.5 12.33 +\putrectangle corners at 7.0 11.25 and 8.0 12.25 +\put {$\scriptstyle 5$} at 7.5 11.75 +\put {$\scriptstyle 27$} [b] at 7.5 12.33 +\putrectangle corners at 8.0 11.25 and 9.0 12.25 +\put {$\scriptstyle 8$} at 8.5 11.75 +\put {$\scriptstyle 28$} [b] at 8.5 12.33 +\putrectangle corners at 9.0 11.25 and 10.0 12.25 +\put {$\scriptstyle 68$} at 9.5 11.75 +\put {$\scriptstyle 29$} [b] at 9.5 12.33 +\putrectangle corners at 0.0 9.0 and 1.0 10.0 +\put {$\scriptstyle 6$} at 0.5 9.5 +\put {$\scriptstyle 30$} [b] at 0.5 10.08 +\putrectangle corners at 1.0 9.0 and 2.0 10.0 +\put {$\scriptstyle 14$} at 1.5 9.5 +\put {$\scriptstyle 31$} [b] at 1.5 10.08 +\putrectangle corners at 2.0 9.0 and 3.0 10.0 +\put {$\scriptstyle 6$} at 2.5 9.5 +\put {$\scriptstyle 32$} [b] at 2.5 10.08 +\putrectangle corners at 3.0 9.0 and 4.0 10.0 +\put {$\scriptstyle 1$} at 3.5 9.5 +\put {$\scriptstyle 33$} [b] at 3.5 10.08 +\putrectangle corners at 4.0 9.0 and 5.0 10.0 +\put {$\scriptstyle 0$} at 4.5 9.5 +\put {$\scriptstyle 34$} [b] at 4.5 10.08 +\putrectangle corners at 5.0 9.0 and 6.0 10.0 +\put {$\scriptstyle 8$} at 5.5 9.5 +\put {$\scriptstyle 35$} [b] at 5.5 10.08 +\putrectangle corners at 6.0 9.0 and 7.0 10.0 +\put {$\scriptstyle 68$} at 6.5 9.5 +\put {$\scriptstyle 36$} [b] at 6.5 10.08 +\putrectangle corners at 7.0 9.0 and 8.0 10.0 +\put {$\scriptstyle 6$} at 7.5 9.5 +\put {$\scriptstyle 37$} [b] at 7.5 10.08 +\putrectangle corners at 8.0 9.0 and 9.0 10.0 +\put {$\scriptstyle 10$} at 8.5 9.5 +\put {$\scriptstyle 38$} [b] at 8.5 10.08 +\putrectangle corners at 9.0 9.0 and 10.0 10.0 +\put {$\scriptstyle 3$} at 9.5 9.5 +\put {$\scriptstyle 39$} [b] at 9.5 10.08 +\putrectangle corners at 0.0 6.75 and 1.0 7.75 +\put {$\scriptstyle 0$} at 0.5 7.25 +\put {$\scriptstyle 40$} [b] at 0.5 7.83 +\putrectangle corners at 1.0 6.75 and 2.0 7.75 +\put {$\scriptstyle 2$} at 1.5 7.25 +\put {$\scriptstyle 41$} [b] at 1.5 7.83 +\putrectangle corners at 2.0 6.75 and 3.0 7.75 +\put {$\scriptstyle 10$} at 2.5 7.25 +\put {$\scriptstyle 42$} [b] at 2.5 7.83 +\putrectangle corners at 3.0 6.75 and 4.0 7.75 +\put {$\scriptstyle 4$} at 3.5 7.25 +\put {$\scriptstyle 43$} [b] at 3.5 7.83 +\putrectangle corners at 4.0 6.75 and 5.0 7.75 +\put {$\scriptstyle 1$} at 4.5 7.25 +\put {$\scriptstyle 44$} [b] at 4.5 7.83 +\putrectangle corners at 5.0 6.75 and 6.0 7.75 +\put {$\scriptstyle 2$} at 5.5 7.25 +\put {$\scriptstyle 45$} [b] at 5.5 7.83 +\putrectangle corners at 6.0 6.75 and 7.0 7.75 +\put {$\scriptstyle 3$} at 6.5 7.25 +\put {$\scriptstyle 46$} [b] at 6.5 7.83 +\putrectangle corners at 7.0 6.75 and 8.0 7.75 +\put {$\scriptstyle 3$} at 7.5 7.25 +\put {$\scriptstyle 47$} [b] at 7.5 7.83 +\putrectangle corners at 8.0 6.75 and 9.0 7.75 +\put {$\scriptstyle 3$} at 8.5 7.25 +\put {$\scriptstyle 48$} [b] at 8.5 7.83 +\putrectangle corners at 9.0 6.75 and 10.0 7.75 +\put {$\scriptstyle 4$} at 9.5 7.25 +\put {$\scriptstyle 49$} [b] at 9.5 7.83 +\putrectangle corners at 0.0 4.5 and 1.0 5.5 +\put {$\scriptstyle 2$} at 0.5 5.0 +\put {$\scriptstyle 50$} [b] at 0.5 5.58 +\putrectangle corners at 1.0 4.5 and 2.0 5.5 +\put {$\scriptstyle 16$} at 1.5 5.0 +\put {$\scriptstyle 51$} [b] at 1.5 5.58 +\putrectangle corners at 2.0 4.5 and 3.0 5.5 +\put {$\scriptstyle 6$} at 2.5 5.0 +\put {$\scriptstyle 52$} [b] at 2.5 5.58 +\putrectangle corners at 3.0 4.5 and 4.0 5.5 +\put {$\scriptstyle 6$} at 3.5 5.0 +\put {$\scriptstyle 53$} [b] at 3.5 5.58 +\putrectangle corners at 4.0 4.5 and 5.0 5.5 +\put {$\scriptstyle 3$} at 4.5 5.0 +\put {$\scriptstyle 54$} [b] at 4.5 5.58 +\putrectangle corners at 5.0 4.5 and 6.0 5.5 +\put {$\scriptstyle 3$} at 5.5 5.0 +\put {$\scriptstyle 55$} [b] at 5.5 5.58 +\putrectangle corners at 6.0 4.5 and 7.0 5.5 +\put {$\scriptstyle 3$} at 6.5 5.0 +\put {$\scriptstyle 56$} [b] at 6.5 5.58 +\putrectangle corners at 7.0 4.5 and 8.0 5.5 +\put {$\scriptstyle 1$} at 7.5 5.0 +\put {$\scriptstyle 57$} [b] at 7.5 5.58 +\putrectangle corners at 8.0 4.5 and 9.0 5.5 +\put {$\scriptstyle 2$} at 8.5 5.0 +\put {$\scriptstyle 58$} [b] at 8.5 5.58 +\putrectangle corners at 9.0 4.5 and 10.0 5.5 +\put {$\scriptstyle 16$} at 9.5 5.0 +\put {$\scriptstyle 59$} [b] at 9.5 5.58 +\putrectangle corners at 0.0 2.25 and 1.0 3.25 +\put {$\scriptstyle 6$} at 0.5 2.75 +\put {$\scriptstyle 60$} [b] at 0.5 3.33 +\putrectangle corners at 1.0 2.25 and 2.0 3.25 +\put {$\scriptstyle 7$} at 1.5 2.75 +\put {$\scriptstyle 61$} [b] at 1.5 3.33 +\putrectangle corners at 2.0 2.25 and 3.0 3.25 +\put {$\scriptstyle 9$} at 2.5 2.75 +\put {$\scriptstyle 62$} [b] at 2.5 3.33 +\putrectangle corners at 3.0 2.25 and 4.0 3.25 +\put {$\scriptstyle 6$} at 3.5 2.75 +\put {$\scriptstyle 63$} [b] at 3.5 3.33 +\putrectangle corners at 4.0 2.25 and 5.0 3.25 +\put {$\scriptstyle 6$} at 4.5 2.75 +\put {$\scriptstyle 64$} [b] at 4.5 3.33 +\putrectangle corners at 5.0 2.25 and 6.0 3.25 +\put {$\scriptstyle 7$} at 5.5 2.75 +\put {$\scriptstyle 65$} [b] at 5.5 3.33 +\putrectangle corners at 6.0 2.25 and 7.0 3.25 +\put {$\scriptstyle 5$} at 6.5 2.75 +\put {$\scriptstyle 66$} [b] at 6.5 3.33 +\putrectangle corners at 7.0 2.25 and 8.0 3.25 +\put {$\scriptstyle 6$} at 7.5 2.75 +\put {$\scriptstyle 67$} [b] at 7.5 3.33 +\putrectangle corners at 8.0 2.25 and 9.0 3.25 +\put {$\scriptstyle 5$} at 8.5 2.75 +\put {$\scriptstyle 68$} [b] at 8.5 3.33 +\putrectangle corners at 9.0 2.25 and 10.0 3.25 +\put {$\scriptstyle 2$} at 9.5 2.75 +\put {$\scriptstyle 69$} [b] at 9.5 3.33 +\endpicture +\border + +\vfil\eject + +{\bigboldfont Project 1} [first serious submission due by Monday, September 10] +\medskip + +Implement VPL by starting from the given file {\tt VPL.java} found in the {\tt VPL} folder at the course web site + (supported by the little class {\tt IntPair.java}), +which (along with some other useful stuff) does the irritating task of replacing +symbolic labels by memory indices. +\medskip + +To begin, download {\tt VPL.java} and {\tt IntPair.java} to your working folder. +\medskip + +The given code assumes you are calling it from the command line. If you aren't, you'll need to +change the code in obvious ways. +\medskip + +Put in code to implement all the operations. The +Be sure to test your program thoroughly. + At a minimum, run it on all the programs given in the {\tt VPL} folder, + plus your program from Exercise 3. The file {\tt someUnitTests} + does a sequence of simple tests of some commands, and you should be able to easily + determine the output it should produce to compare to what your program actually does produce. + If you submit your work when it is not working as desired on these VPL programs, + you should also explain which ones have problems and describe what you are planning to + do next to fix your program. + \medskip + +As you're working on this project, remember that this work will directly help you to +prepare for Test 1, +which will ask you to read, write, and execute VPL code, as well as to +add new features to the VPL language. +\medskip + +When you are ready to submit your work (and recall that a serious first submission must be done by the due date or +you will never be allowed to submit it) +email\hfil\break + {\tt shultzj@msudenver.edu} with your file {\tt VPL.java} as an attachment. +And, yes, you must do this program in Java, purely for my and your convenience. If there is +any feature of the program that you find difficult to do in Java, then you are probably +doing things wrong! In other words, implementing a language this primitive should only +require very primitive features of Java. +\border + +\vfil\eject + +% mini-lecture --- introduce idea of higher level language that will translate to VPL + +{\bf An Assembler for VPL?} +\medskip + +\doit Let's discuss for a while what is so horribly wrong with VPL (even assuming we only want to +be able to work with integer values). +\medskip + +Your next Project, following some background work and Exercises to get ready, will be to implement, in Java, a +translator that will take a program written in a language that is nicer to use than VPL and +translate it to a VPL program. +\medskip + +To keep things from getting out of hand at this point, we will make the following crucial language design +decision: +\medskip + +{\advance \leftskip .5true in + \it The new language should translate line-by-line to a VPL program, where each line of the + new language can be translated to some VPL code as we go. +\border +} + +{\bf Exercise 5} +\medskip + +Working in groups, ideally of size four or five, {\it design\/} this new language. +After you work on this a while, we will have a whole group discussion and come up with +the draft (we might decide something which turns out later to be bad) design for our +joint language. +\medskip + +Note that part of the design is the {\it name\/} of the language. +\border + +{\bigboldfont The First Step in Language Implementation: Lexical Analysis} +\bigskip + +Because the new language is simple enough, the only interesting issue in its implementation +will be turning sequences of physical symbols---actual single symbols---into conceptual symbols known as +{\it tokens\/} or {\it lexemes}. +\medskip + +To do this, we will first study some ides in what is known as {\it lexical analysis}. +\border + +{\bf Finite Automata} +\medskip + + A {\it finite automaton} (FA) consists of a directed graph, where the vertices +are known as {\it states\/} +and are typically drawn as circles, and each edge of the graph is labeled with a list of one or more +symbols belonging to the alphabet. +Each symbol in the alphabet can only occur on at most one edge leading out of any state. +One state is marked by an arrow out of nowhere pointing to it as the {\it start state}, and one or +more states are marked, typically by ``double circling,'' as {\it accepting states}. +\medskip + +For example, here is an FA using the alphabet $\{ a, b\}$: +\medskip + +$$ +\beginpicture +\setcoordinatesystem units <1true pt,1true pt> +% epsilon + \circulararc 360 degrees from 9.0 80.0 center at 0.0 80.0 + \put {1} at 0.0 80.0 +% b + \circulararc 360 degrees from 89.0 80.0 center at 80.0 80.0 + \put {2} at 80.0 80.0 +% bb + \circulararc 360 degrees from 169.0 80.0 center at 160.0 80.0 + \put {3} at 160.0 80.0 + \circulararc 360 degrees from 168.0 80.0 center at 160.0 80.0 +% ba + \circulararc 360 degrees from 89.0 0.0 center at 80.0 0.0 + \put {4} at 80.0 0.0 + \circulararc 360 degrees from 88.0 0.0 center at 80.0 0.0 +% Arrow from epsilon to b: + \arrow <0.1in> [0.2,0.67] from 9.0 80.0 to 71.0 80.0 + \put {b} at 40.0 86.0 +% Arrow from b to bb: + \arrow <0.1in> [0.2,0.67] from 89.0 80.0 to 151.0 80.0 + \put {b} at 120.0 86.0 +% Arrow from ba to epsilon: + \arrow <0.1in> [0.2,0.67] from 73.0 6.0 to 6.0 73.0 + \put {a} at 40.0 34.0 +% Arrow from bb to ba: + \arrow <0.1in> [0.2,0.67] from 153.0 73.0 to 86.0 6.0 + \put {a} at 120.0 34.0 +% Arrow from b to ba: + \arrow <0.1in> [0.2,0.67] from 75.0 71.0 to 75.0 9.0 + \put {a} at 69.0 40.0 +% Arrow from ba to b: + \arrow <0.1in> [0.2,0.67] from 85.0 9.0 to 85.0 71.0 + \put {b} at 91.0 40.0 +% Loop about epsilon: + \circulararc 298.0 degrees from 3.0 88.0 center at 0.0 93.0 + \put {a} at 0.0 105.0 +% Loop about bb: + \circulararc 298.0 degrees from 163.0 88.0 center at 160.0 93.0 + \put {b} at 160.0 105.0 +% start arrow: +\arrow <0.1in> [0.2,0.67] from -29 80 to -9 80 +\endpicture +$$ +\bigskip + +Here is how an FA is used to decide whether a given string is legal: +\medskip +\In +starting from the start state, process each symbol of the input string in turn, until +you reach the end of the string, or detect an error. To process a symbol, look at the +edges leading out of the current state. If the symbol is listed on one of them, follow that +edge to the state on the other end and make that the current state. If the symbol is not +listed on any edge, then the string is rejected. Finally, if all the symbols of the +input string are successfully processed, then check the state that you end up in---if it +is an accepting state, then the input string is accepted as legal, otherwise it is rejected. +\bigskip +\Out + +For example, in the FA given above, the string {\tt ababbba} is accepted, moving from +1 to 1 to 2 to 4 to 2 to 3 to 3 to 4, and state 4 is an accepting state. On the other hand, +the string {\tt bbbab} is not accepted, because it moves from 1 to 2 to 3 to 3 to 4 to 2, +and state 2 is not an accepting state. And, the string {\tt abc} is rejected because it moves +from 1 to 1 to 2 and then detects no edge out of state 2 that processes a {\tt c}. +\bigskip + +\doit Create an FA for the language of legal identifiers in our new language. +\border + +{\bf Exercise 6} +\medskip + +Working in your small group, create an FA for the language of integer literals. +\medskip + +Then look at the new language design and see all the different kinds of tokens. +Make sure that you can create an FA for each kind of token. +\border + +\vfil\eject + +{\bigboldfont Announcement} +\medskip + +The Learning Assistants (Peter and Jimmy) have settled on {\bf Office Hours} from +2--3:50 on Tuesday and Thursday, in AES 237 (check the board if they aren't there to see if +they moved to another room for more quiet). +Barring emergencies, one or the other of them will be available during these times +to talk with you about the +course material, Exercises, and Projects. +\medskip + +They provide another resource, which is + not at all to say that I won't be happy to talk with you. +\border + +{\bf Practice Problems for Test 1} +\medskip + +Test 1 will cover, among other things, +our VPL-based introduction to the study of programming languages. +You should be able to execute given VPL code by hand, write short chunks of VPL code to +do certain things, and write Java code to add commands to the language. +\medskip + +The practice problems below are not intended to cover all issues. For example, any +translation of Java-like code to VPL is ``fair game.'' +\border + +\item{$\bullet$} +Here is a fairly simple VPL program, shown (with no documentation and labels +replaced by actual array indices) after the code has loaded. Trace execution of the program, +beginning with {\tt ip} at 0, +writing in the correct values in all the memory cells until the program halts. +When a value is replaced by another value, draw a line through the first value and write +the second value in the cell. You will need to track the values of the registers yourself, +but you do not need to show them formally. +\medskip + +You should draw boundaries between the code segment, global +segment, and stack segment, and between the various stack frames. +\medskip + +Also, show what will be displayed on screen. + +\vfil\eject + +\vbox{ +\beginpicture +\setcoordinatesystem units <0.4true in, 0.35true in> +\putrectangle corners at 0.0 11.25 and 1.0 12.25 +\put {$32$} at 0.5 11.75 +\put {$0$} [b] at 0.5 12.33 +\put {\tt ip} [b] at 0.5 12.65 +\putrectangle corners at 1.0 11.25 and 2.0 12.25 +\put {$1$} at 1.5 11.75 +\put {$1$} [b] at 1.5 12.33 +\putrectangle corners at 2.0 11.25 and 3.0 12.25 +\put {$4$} at 2.5 11.75 +\put {$2$} [b] at 2.5 12.33 +\putrectangle corners at 3.0 11.25 and 4.0 12.25 +\put {$3$} at 3.5 11.75 +\put {$3$} [b] at 3.5 12.33 +\putrectangle corners at 4.0 11.25 and 5.0 12.25 +\put {$22$} at 4.5 11.75 +\put {$4$} [b] at 4.5 12.33 +\putrectangle corners at 5.0 11.25 and 6.0 12.25 +\put {$0$} at 5.5 11.75 +\put {$5$} [b] at 5.5 12.33 +\putrectangle corners at 6.0 11.25 and 7.0 12.25 +\put {$17$} at 6.5 11.75 +\put {$6$} [b] at 6.5 12.33 +\putrectangle corners at 7.0 11.25 and 8.0 12.25 +\put {$22$} at 7.5 11.75 +\put {$7$} [b] at 7.5 12.33 +\putrectangle corners at 8.0 11.25 and 9.0 12.25 +\put {$1$} at 8.5 11.75 +\put {$8$} [b] at 8.5 12.33 +\putrectangle corners at 9.0 11.25 and 10.0 12.25 +\put {$3$} at 9.5 11.75 +\put {$9$} [b] at 9.5 12.33 +\putrectangle corners at 0.0 9.0 and 1.0 10.0 +\put {$3$} at 0.5 9.5 +\put {$10$} [b] at 0.5 10.08 +\putrectangle corners at 1.0 9.0 and 2.0 10.0 +\put {$1$} at 1.5 9.5 +\put {$11$} [b] at 1.5 10.08 +\putrectangle corners at 2.0 9.0 and 3.0 10.0 +\put {$3$} at 2.5 9.5 +\put {$12$} [b] at 2.5 10.08 +\putrectangle corners at 3.0 9.0 and 4.0 10.0 +\put {$0$} at 3.5 9.5 +\put {$13$} [b] at 3.5 10.08 +\putrectangle corners at 4.0 9.0 and 5.0 10.0 +\put {$2$} at 4.5 9.5 +\put {$14$} [b] at 4.5 10.08 +\putrectangle corners at 5.0 9.0 and 6.0 10.0 +\put {$24$} at 5.5 9.5 +\put {$15$} [b] at 5.5 10.08 +\putrectangle corners at 6.0 9.0 and 7.0 10.0 +\put {$6$} at 6.5 9.5 +\put {$16$} [b] at 6.5 10.08 +\putrectangle corners at 7.0 9.0 and 8.0 10.0 +\put {$2$} at 7.5 9.5 +\put {$17$} [b] at 7.5 10.08 +\putrectangle corners at 8.0 9.0 and 9.0 10.0 +\put {$28$} at 8.5 9.5 +\put {$18$} [b] at 8.5 10.08 +\putrectangle corners at 9.0 9.0 and 10.0 10.0 +\put {$2$} at 9.5 9.5 +\put {$19$} [b] at 9.5 10.08 +\putrectangle corners at 0.0 6.75 and 1.0 7.75 +\put {$33$} at 0.5 7.25 +\put {$20$} [b] at 0.5 7.83 +\putrectangle corners at 1.0 6.75 and 2.0 7.75 +\put {$0$} at 1.5 7.25 +\put {$21$} [b] at 1.5 7.83 +\putrectangle corners at 2.0 6.75 and 3.0 7.75 +\put {$2$} at 2.5 7.25 +\put {$22$} [b] at 2.5 7.83 +\putrectangle corners at 3.0 6.75 and 4.0 7.75 +\put {$26$} at 3.5 7.25 +\put {$23$} [b] at 3.5 7.83 +\putrectangle corners at 4.0 6.75 and 5.0 7.75 +\put {$4$} at 4.5 7.25 +\put {$24$} [b] at 4.5 7.83 +\putrectangle corners at 5.0 6.75 and 6.0 7.75 +\put {$1$} at 5.5 7.25 +\put {$25$} [b] at 5.5 7.83 +\putrectangle corners at 6.0 6.75 and 7.0 7.75 +\put {$9$} at 6.5 7.25 +\put {$26$} [b] at 6.5 7.83 +\putrectangle corners at 7.0 6.75 and 8.0 7.75 +\put {$2$} at 7.5 7.25 +\put {$27$} [b] at 7.5 7.83 +\putrectangle corners at 8.0 6.75 and 9.0 7.75 +\put {$0$} at 8.5 7.25 +\put {$28$} [b] at 8.5 7.83 +\putrectangle corners at 9.0 6.75 and 10.0 7.75 +\put {$1$} at 9.5 7.25 +\put {$29$} [b] at 9.5 7.83 +\putrectangle corners at 0.0 4.5 and 1.0 5.5 +\put {$5$} at 0.5 5.0 +\put {$30$} [b] at 0.5 5.58 +\putrectangle corners at 1.0 4.5 and 2.0 5.5 +\put {$2$} at 1.5 5.0 +\put {$31$} [b] at 1.5 5.58 +\putrectangle corners at 2.0 4.5 and 3.0 5.5 +%\put {$0$} at 2.5 5.0 +\put {$32$} [b] at 2.5 5.58 +%\put {\tt bp} [b] at 2.5 5.9 +\putrectangle corners at 3.0 4.5 and 4.0 5.5 +%\put {$0$} at 3.5 5.0 +\put {$33$} [b] at 3.5 5.58 +\putrectangle corners at 4.0 4.5 and 5.0 5.5 +\put {$34$} [b] at 4.5 5.58 +%\put {\tt sp} [b] at 4.5 5.9 +\putrectangle corners at 5.0 4.5 and 6.0 5.5 +\put {$35$} [b] at 5.5 5.58 +\putrectangle corners at 6.0 4.5 and 7.0 5.5 +\put {$36$} [b] at 6.5 5.58 +\putrectangle corners at 7.0 4.5 and 8.0 5.5 +\put {$37$} [b] at 7.5 5.58 +\putrectangle corners at 8.0 4.5 and 9.0 5.5 +\put {$38$} [b] at 8.5 5.58 +\putrectangle corners at 9.0 4.5 and 10.0 5.5 +\put {$39$} [b] at 9.5 5.58 +\putrectangle corners at 0.0 2.25 and 1.0 3.25 +\put {$40$} [b] at 0.5 3.33 +\putrectangle corners at 1.0 2.25 and 2.0 3.25 +\put {$41$} [b] at 1.5 3.33 +\putrectangle corners at 2.0 2.25 and 3.0 3.25 +\put {$42$} [b] at 2.5 3.33 +\putrectangle corners at 3.0 2.25 and 4.0 3.25 +\put {$43$} [b] at 3.5 3.33 +\putrectangle corners at 4.0 2.25 and 5.0 3.25 +\put {$44$} [b] at 4.5 3.33 +\putrectangle corners at 5.0 2.25 and 6.0 3.25 +\put {$45$} [b] at 5.5 3.33 +\putrectangle corners at 6.0 2.25 and 7.0 3.25 +\put {$46$} [b] at 6.5 3.33 +\putrectangle corners at 7.0 2.25 and 8.0 3.25 +\put {$47$} [b] at 7.5 3.33 +\putrectangle corners at 8.0 2.25 and 9.0 3.25 +\put {$48$} [b] at 8.5 3.33 +\putrectangle corners at 9.0 2.25 and 10.0 3.25 +\put {$49$} [b] at 9.5 3.33 +\putrectangle corners at 0.0 0.0 and 1.0 1.0 +\put {$50$} [b] at 0.5 1.08 +\putrectangle corners at 1.0 0.0 and 2.0 1.0 +\put {$51$} [b] at 1.5 1.08 +\putrectangle corners at 2.0 0.0 and 3.0 1.0 +\put {$52$} [b] at 2.5 1.08 +\putrectangle corners at 3.0 0.0 and 4.0 1.0 +\put {$53$} [b] at 3.5 1.08 +\endpicture} + +\vfil\eject + +\item{$\bullet$} +Here is a snapshot of VPL memory at a point of execution where {\tt bp}, {\tt sp}, +and +{\tt ip} are as shown. Demonstrate your +understanding of VPL by explaining this snapshot as follows. +Figure out where the code segment ends and draw a clearly visible vertical line +between the last cell of the VPL program and the first cell of the stack segment (there is +no global segment in this program). +Draw clearly visible boundary lines showing the various stack frames existing at +this moment. Finally, fill in memory cells as you +execution for another function call---start with +{\tt ip} at 10---and continue up to but not including the next function call after that. +\medskip + +\beginpicture +\setcoordinatesystem units <0.4true in, 0.4true in> +\putrectangle corners at 0.0 15.75 and 1.0 16.75 +\put {$4$} at 0.5 16.25 +\put {$0$} [b] at 0.5 16.83 +\putrectangle corners at 1.0 15.75 and 2.0 16.75 +\put {$1$} at 1.5 16.25 +\put {$1$} [b] at 1.5 16.83 +\putrectangle corners at 2.0 15.75 and 3.0 16.75 +\put {$22$} at 2.5 16.25 +\put {$2$} [b] at 2.5 16.83 +\putrectangle corners at 3.0 15.75 and 4.0 16.75 +\put {$0$} at 3.5 16.25 +\put {$3$} [b] at 3.5 16.83 +\putrectangle corners at 4.0 15.75 and 5.0 16.75 +\put {$1$} at 4.5 16.25 +\put {$4$} [b] at 4.5 16.83 +\putrectangle corners at 5.0 15.75 and 6.0 16.75 +\put {$3$} at 5.5 16.25 +\put {$5$} [b] at 5.5 16.83 +\putrectangle corners at 6.0 15.75 and 7.0 16.75 +\put {$0$} at 6.5 16.25 +\put {$6$} [b] at 6.5 16.83 +\putrectangle corners at 7.0 15.75 and 8.0 16.75 +\put {$2$} at 7.5 16.25 +\put {$7$} [b] at 7.5 16.83 +\putrectangle corners at 8.0 15.75 and 9.0 16.75 +\put {$10$} at 8.5 16.25 +\put {$8$} [b] at 8.5 16.83 +\putrectangle corners at 9.0 15.75 and 10.0 16.75 +\put {$26$} at 9.5 16.25 +\put {$9$} [b] at 9.5 16.83 +\putrectangle corners at 0.0 13.5 and 1.0 14.5 +\put {$4$} at 0.5 14.0 +\put {$10$} [b] at 0.5 14.58 +\put {\tt ip} [b] at .5 14.88 +\putrectangle corners at 1.0 13.5 and 2.0 14.5 +\put {$3$} at 1.5 14.0 +\put {$11$} [b] at 1.5 14.58 +\putrectangle corners at 2.0 13.5 and 3.0 14.5 +\put {$28$} at 2.5 14.0 +\put {$12$} [b] at 2.5 14.58 +\putrectangle corners at 3.0 13.5 and 4.0 14.5 +\put {$0$} at 3.5 14.0 +\put {$13$} [b] at 3.5 14.58 +\putrectangle corners at 4.0 13.5 and 5.0 14.5 +\put {$29$} at 4.5 14.0 +\put {$14$} [b] at 4.5 14.58 +\putrectangle corners at 5.0 13.5 and 6.0 14.5 +\put {$22$} at 5.5 14.0 +\put {$15$} [b] at 5.5 14.58 +\putrectangle corners at 6.0 13.5 and 7.0 14.5 +\put {$3$} at 6.5 14.0 +\put {$16$} [b] at 6.5 14.58 +\putrectangle corners at 7.0 13.5 and 8.0 14.5 +\put {$2$} at 7.5 14.0 +\put {$17$} [b] at 7.5 14.58 +\putrectangle corners at 8.0 13.5 and 9.0 14.5 +\put {$11$} at 8.5 14.0 +\put {$18$} [b] at 8.5 14.58 +\putrectangle corners at 9.0 13.5 and 10.0 14.5 +\put {$1$} at 9.5 14.0 +\put {$19$} [b] at 9.5 14.58 +\putrectangle corners at 0.0 11.25 and 1.0 12.25 +\put {$3$} at 0.5 11.75 +\put {$20$} [b] at 0.5 12.33 +\putrectangle corners at 1.0 11.25 and 2.0 12.25 +\put {$0$} at 1.5 11.75 +\put {$21$} [b] at 1.5 12.33 +\putrectangle corners at 2.0 11.25 and 3.0 12.25 +\put {$3$} at 2.5 11.75 +\put {$22$} [b] at 2.5 12.33 +\putrectangle corners at 3.0 11.25 and 4.0 12.25 +\put {$1$} at 3.5 11.75 +\put {$23$} [b] at 3.5 12.33 +\putrectangle corners at 4.0 11.25 and 5.0 12.25 +\put {$2$} at 4.5 11.75 +\put {$24$} [b] at 4.5 12.33 +\putrectangle corners at 5.0 11.25 and 6.0 12.25 +\put {$10$} at 5.5 11.75 +\put {$25$} [b] at 5.5 12.33 +\putrectangle corners at 6.0 11.25 and 7.0 12.25 +\put {$6$} at 6.5 11.75 +\put {$26$} [b] at 6.5 12.33 +%\put {\tt ip} [b] at 6.5 12.65 +\putrectangle corners at 7.0 11.25 and 8.0 12.25 +\put {$2$} at 7.5 11.75 +\put {$27$} [b] at 7.5 12.33 +\putrectangle corners at 8.0 11.25 and 9.0 12.25 +\put {$5$} at 8.5 11.75 +\put {$28$} [b] at 8.5 12.33 +\putrectangle corners at 9.0 11.25 and 10.0 12.25 +\put {$2$} at 9.5 11.75 +\put {$29$} [b] at 9.5 12.33 +\putrectangle corners at 0.0 9.0 and 1.0 10.0 +\put {$0$} at 0.5 9.5 +\put {$30$} [b] at 0.5 10.08 +\putrectangle corners at 1.0 9.0 and 2.0 10.0 +\put {$0$} at 1.5 9.5 +\put {$31$} [b] at 1.5 10.08 +\putrectangle corners at 2.0 9.0 and 3.0 10.0 +\put {$1$} at 2.5 9.5 +\put {$32$} [b] at 2.5 10.08 +\putrectangle corners at 3.0 9.0 and 4.0 10.0 +\put {$30$} at 3.5 9.5 +\put {$33$} [b] at 3.5 10.08 +\putrectangle corners at 4.0 9.0 and 5.0 10.0 +\put {$9$} at 4.5 9.5 +\put {$34$} [b] at 4.5 10.08 +\putrectangle corners at 5.0 9.0 and 6.0 10.0 +\put {$1$} at 5.5 9.5 +\put {$35$} [b] at 5.5 10.08 +\putrectangle corners at 6.0 9.0 and 7.0 10.0 +\put {$2$} at 6.5 9.5 +\put {$36$} [b] at 6.5 10.08 +\putrectangle corners at 7.0 9.0 and 8.0 10.0 +\put {$0$} at 7.5 9.5 +\put {$37$} [b] at 7.5 10.08 +\putrectangle corners at 8.0 9.0 and 9.0 10.0 +\put {$2$} at 8.5 9.5 +\put {$38$} [b] at 8.5 10.08 +\putrectangle corners at 9.0 9.0 and 10.0 10.0 +\put {$33$} at 9.5 9.5 +\put {$39$} [b] at 9.5 10.08 +\putrectangle corners at 0.0 6.75 and 1.0 7.75 +\put {$26$} at 0.5 7.25 +\put {$40$} [b] at 0.5 7.83 +\putrectangle corners at 1.0 6.75 and 2.0 7.75 +\put {$2$} at 1.5 7.25 +\put {$41$} [b] at 1.5 7.83 +\putrectangle corners at 2.0 6.75 and 3.0 7.75 +\put {$4$} at 2.5 7.25 +\put {$42$} [b] at 2.5 7.83 +\putrectangle corners at 3.0 6.75 and 4.0 7.75 +\put {$0$} at 3.5 7.25 +\put {$43$} [b] at 3.5 7.83 +\putrectangle corners at 4.0 6.75 and 5.0 7.75 +\put {$2$} at 4.5 7.25 +\put {$44$} [b] at 4.5 7.83 +\putrectangle corners at 5.0 6.75 and 6.0 7.75 +\put {$39$} at 5.5 7.25 +\put {$45$} [b] at 5.5 7.83 +\putrectangle corners at 6.0 6.75 and 7.0 7.75 +\put {$26$} at 6.5 7.25 +\put {$46$} [b] at 6.5 7.83 +\putrectangle corners at 7.0 6.75 and 8.0 7.75 +\put {$4$} at 7.5 7.25 +\put {$47$} [b] at 7.5 7.83 +\putrectangle corners at 8.0 6.75 and 9.0 7.75 +\put {$8$} at 8.5 7.25 +\put {$48$} [b] at 8.5 7.83 +\putrectangle corners at 9.0 6.75 and 10.0 7.75 +\put {$0$} at 9.5 7.25 +\put {$49$} [b] at 9.5 7.83 +\putrectangle corners at 0.0 4.5 and 1.0 5.5 +\put {$2$} at 0.5 5.0 +\put {$50$} [b] at 0.5 5.58 +\putrectangle corners at 1.0 4.5 and 2.0 5.5 +\put {$45$} at 1.5 5.0 +\put {$51$} [b] at 1.5 5.58 +\putrectangle corners at 2.0 4.5 and 3.0 5.5 +\put {$26$} at 2.5 5.0 +\put {$52$} [b] at 2.5 5.58 +\putrectangle corners at 3.0 4.5 and 4.0 5.5 +\put {$8$} at 3.5 5.0 +\put {$53$} [b] at 3.5 5.58 +\putrectangle corners at 4.0 4.5 and 5.0 5.5 +\put {$16$} at 4.5 5.0 +\put {$54$} [b] at 4.5 5.58 +\putrectangle corners at 5.0 4.5 and 6.0 5.5 +\put {$0$} at 5.5 5.0 +\put {$55$} [b] at 5.5 5.58 +\putrectangle corners at 6.0 4.5 and 7.0 5.5 +\put {$2$} at 6.5 5.0 +\put {$56$} [b] at 6.5 5.58 +\putrectangle corners at 7.0 4.5 and 8.0 5.5 +\put {$51$} at 7.5 5.0 +\put {$57$} [b] at 7.5 5.58 +\putrectangle corners at 8.0 4.5 and 9.0 5.5 +\put {$26$} at 8.5 5.0 +\put {$58$} [b] at 8.5 5.58 +\putrectangle corners at 9.0 4.5 and 10.0 5.5 +\put {$16$} at 9.5 5.0 +\put {$59$} [b] at 9.5 5.58 +\putrectangle corners at 0.0 2.25 and 1.0 3.25 +\put {$32$} at 0.5 2.75 +\put {$60$} [b] at 0.5 3.33 +\putrectangle corners at 1.0 2.25 and 2.0 3.25 +\put {$0$} at 1.5 2.75 +\put {$61$} [b] at 1.5 3.33 +\putrectangle corners at 2.0 2.25 and 3.0 3.25 +\put {$2$} at 2.5 2.75 +\put {$62$} [b] at 2.5 3.33 +\putrectangle corners at 3.0 2.25 and 4.0 3.25 +\put {$57$} at 3.5 2.75 +\put {$63$} [b] at 3.5 3.33 +\put {\tt bp} [b] at 3.5 3.65 +\putrectangle corners at 4.0 2.25 and 5.0 3.25 +\put {$26$} at 4.5 2.75 +\put {$64$} [b] at 4.5 3.33 +\putrectangle corners at 5.0 2.25 and 6.0 3.25 +\put {$32$} at 5.5 2.75 +\put {$65$} [b] at 5.5 3.33 +\putrectangle corners at 6.0 2.25 and 7.0 3.25 +\put {$64$} at 6.5 2.75 +\put {$66$} [b] at 6.5 3.33 +\putrectangle corners at 7.0 2.25 and 8.0 3.25 +\put {$0$} at 7.5 2.75 +\put {$67$} [b] at 7.5 3.33 +\putrectangle corners at 8.0 2.25 and 9.0 3.25 +\put {$2$} at 8.5 2.75 +\put {$68$} [b] at 8.5 3.33 +\putrectangle corners at 9.0 2.25 and 10.0 3.25 +\put {$69$} [b] at 9.5 3.33 +\put {\tt sp} [b] at 9.5 3.65 +\putrectangle corners at 0.0 0.0 and 1.0 1.0 +\put {$70$} [b] at 0.5 1.08 +\putrectangle corners at 1.0 0.0 and 2.0 1.0 +\put {$71$} [b] at 1.5 1.08 +\putrectangle corners at 2.0 0.0 and 3.0 1.0 +\put {$72$} [b] at 2.5 1.08 +\putrectangle corners at 3.0 0.0 and 4.0 1.0 +\put {$73$} [b] at 3.5 1.08 +\putrectangle corners at 4.0 0.0 and 5.0 1.0 +\put {$74$} [b] at 4.5 1.08 +\putrectangle corners at 5.0 0.0 and 6.0 1.0 +\put {$75$} [b] at 5.5 1.08 +\putrectangle corners at 6.0 0.0 and 7.0 1.0 +\put {$76$} [b] at 6.5 1.08 +\putrectangle corners at 7.0 0.0 and 8.0 1.0 +\put {$77$} [b] at 7.5 1.08 +\putrectangle corners at 8.0 0.0 and 9.0 1.0 +\put {$78$} [b] at 8.5 1.08 +\endpicture + +\vfil\eject + +\item{$\bullet$} +Write a fragment of VPL code that is a reasonable translation of each fragment +of Java-like code shown below. Assume that {\tt A} and {\tt B} are sequences of 0 or +more statements in the Java-like language, and denote the translation of a sequence of 0 or more +statements {\tt A} to VPL by the function call {\tt v(A)}---so {\tt v(A)} is +the sequence of VPL statements that {\tt A} translates to. +Also assume that the variable {\tt x} translates to local cell 7 in the +function where this fragment occurs, and that +the variable {\tt y} translates to global cell 3. +If you need any additional memory cells, assume that you can freely +use local cells +10, 11, and so on, as needed. +Use labels starting with 1000 in the code you generate. +\bigskip + +\verbatim +if( x < y ) +{ + A +} +else +{ + B +} +|endverbatim + +\vfil + +\verbatim +for( x=1; x<10; x++ ){ + A +} +|endverbatim + +\vfil\eject + +\item{$\bullet$} +Suppose we want to add a command to VPL that will allow us to +get the physical address---the index in the memory array---of a local cell +in the currently active stack frame +and store it in some local cell. +This would be useful, for example, if we wanted to implement pass-by-reference. +\medskip + +Specifically, +suppose we want to add a command with this specification: + +\halign{\tabskip 0.25true in +{\tt #}\hfil& #\hfil& \vtop{\hsize 3.5true in \baselineskip 0.8\baselineskip #}\hfil\cr +\noalign{\smallskip\hrule\smallskip} +Instruction& Mnemonic& Semantic Description\cr +\noalign{\smallskip\hrule\smallskip} +42 a b& get address& Get the index in the memory array of local cell {\tt b} and store it +in local cell {\tt a}.\cr +\noalign{\smallskip\hrule\smallskip} +} +\medskip + +Your job is to write code that will implement this new command. +Your code must fit in with the fragments of code shown. Specifically, assume that +{\tt op} holds the current operation number, which is stored in +{\tt mem[ip]}, and the variables {\tt a}, {\tt b}, and {\tt c} +hold the arguments to the command, from cells {\tt mem[ip+1]}, {\tt mem[ip+2]}, and +{\tt mem[ip+3]}. +\medskip + +Note that you have to write code that will cause the desired behavior {\it and\/} +correctly update {\tt ip}. +\medskip + +{\baselineskip 0.8\baselineskip + +\verbatim + do{ + op = mem[ ip ]; ip++; + // code to extract op and the args into a, b, c + // for convenience omitted + ... (lots of code omitted) .... + else if( op == 22 ) // literal + { + mem[ bp+2+a ] = b; + ip += 3; + } + else if( op == 23 ) // copy + { + mem[ bp+2+a ] = mem[ bp+2+b ]; + ip += 3; + } + else if( op == 24 ) // add + { + mem[ bp+2+a ] = mem[ mem[ bp+2+b] + mem[ bp+2+c ] ]; + ip += 4; + } + ... (lots more code omitted )... + // write your code to implement command 42 here: +|endverbatim +\vfil +\verbatim + else + { + System.out.println("Fatal error: unknown opcode [" + op + "]" ); + System.exit(1); + } + + }while( !done ); +|endverbatim +\par +} +\eject + + +{\bigboldfont A Survey of Memory Issues in Some Early Imperative Languages} +\medskip + +We will now look at a number of memory models used in early imperative languages that differ from +VPL. +\medskip + +\Indent{1} + The VPL memory model is actually closest to the non-object-oriented parts of Java, + which is pretty much the same as C, except C had powerful features---discussed later---that + were eliminated from Java. +\medskip +\Outdent + +In this discussion we will refer to various memory +models by the language that more or +less follows that model, but we don't care about the details, +just the main ideas. +\medskip + +In all this work, we will imagine that a Java program, with its own +vast memory, is used to translate the source code into VPL-like +language, using whatever memory resources and data structures it +needs, but then at run-time the program is executed using just the +single memory array, together with a fixed set of Java variables +acting as ``registers.'' This is identical to how we implemented VPL. +\medskip + +We will only look at features of these languages that correspond to +VPL abilities, namely working with integers only. +\medskip + + {\bf Some Terminology} + \medskip + + People talking about programming languages (including us in the following material) often use terms related to + the {\it semantics\/} of a language, including: + \medskip + + \Indent{1} + {\it scope (also known as ``visibility''):} the region of code in which a particular variable has the same meaning, + in the sense that it refers to the same cell in memory + \medskip + + {\it binding time:} the time in the entire process when the meaning of an entity (usually a variable, sometimes + other things) in the + code is ``bound'' to its meaning (memory cell for a variable). + Some things (e.g. {\tt int} literals in Java) are bound at {\it language design time}. + Other things (e.g. {\tt final static} variables in Java) are bound at compile time + + \Indent{1} + (probably---as the assembly language code is produced from the Java code, every occurrence of + such a variable might be replaced by its value). + \medskip + \Outdent + Other things (e.g. the location of a local variable in a method in Java, which will be somewhere on the + stack which is unknowable until the code is executed) are bound at {\it run time}. + \bigskip + \Outdent + + We will tend in the following to be more precise, as we present memory models for the various languages + at a level like we have done for VPL. + \medskip + + Language implementations fall into two main categories, namely {\it translated\/} (old timey word for this + was ``compiled'') or {\it interpreted}. This distinction actually only refers to the typical + approach for + a given + language---any language can in principle be translated---have the entire + source code for some program in the language translated to code in + some other language which can then somehow be executed---or interpreted---have individual statements + be processed and executed---but it might be more common or convenient to do one or the other. + \medskip + + Java is typically translated---from Java source code for a class to Java virtual machine language code + for that same class---with the Java ``byte code''---the {\tt .class} files---being interpreted. + But, there are Java compilers that translate from Java source code to assembly language code for a + particular platform (CPU and operating system). + \border + +{\bigboldfont The Basic Model} +\medskip + +By ``Basic' here we mean the old-time programming language ``Beginner's +All-Purpose Symbolic Instruction Code.'' +\medskip + +Here are the core features of this memory model: +\medskip + + \In + + \item{$\bullet$} The language is best thought of as interpreted. + \medskip + + \item{$\bullet$} All variables have global scope---they +can be accessed anywhere in the program, with the same +meaning. As each identifier (for a ``variable'') + is encountered for the first time during execution of the +code, it is assigned to a memory cell. Later occurrences of the same identifier +mean the same memory cell. + \medskip + + \item{$\bullet$} Support for subprograms is minimal---just + the {\tt gosub} and {\tt return} + commands, with no named subprograms, no + parameters, and no local variables. + \medskip + + \item{$\bullet$} No dynamic memory features, except sort of for + arrays. + \medskip + + \item{$\bullet$} Arrays are created in the global memory space, + and are allowed to have the size of an array only known at + run-time. Arrays are created by the {\tt dim} command, + such as {\tt dim a(6)} meaning to create an array named {\tt a} + that has 6 memory cells allocated. + \medskip +\Out + +\doit Develop a scheme for memory usage for this model, +in the spirit of the memory pictures we drew for VPL. +\medskip + +\doit Is recursion supported by this model? +\medskip + +\doit Could Basic really be implemented by translation in the sense +of scanning the code and mapping variables to memory cells before +actually executing the translated code? +\border + +{\bigboldfont The Pre-90 Fortran Model} +\medskip + +Note: the following is discussing Fortran as it was in the early days (Fortran 77, maybe?). Apparently modern +Fortran (Fortran 90 and up) has lots of further features, including recursion and objects. +This reminds me of the old joke: ``what will the language of the future be like?'' +``I don't know, but it will be called `Fortran' .'' +\medskip + + \In + \item{$\bullet$} All variables have local scope---they can only be accessed in the + subprogram where they occur. + \medskip + + \item{$\bullet$} Parameter passing is done by ``pass by reference.'' This means that + the address of an argument is passed to the subprogram, and the compiler translates + all occurrences of parameters to use the memory location with the address stored + in the parameter. + \medskip + + \item{$\bullet$} No dynamic memory. Array declarations must have a size that can + be determined statically---that is, at compile time. + \medskip + + \item{$\bullet$} No recursion. + \medskip +\Out + +\doit Develop a scheme for memory usage for +this model, in the spirit of the + memory pictures we drew for VPL. Think about how a translator for this language would + deal with variables. Note that with this model, values of local variables can have a lifetime + that is the lifetime of the program execution. +\medskip + +\doit Be careful to understand exactly how pass-by-reference works. +\medskip + +\doit Why is recursion not allowed? Why must arrays have +their size known at compile-time? +\border + +{\bigboldfont The Pascal Model} +\medskip + + \In + + \item{$\bullet$} Parameter passing is done by pass by value or pass by reference, depending + on whether the parameter has a special key word ({\tt var}, in case you care) occurring in its + declaration to specify pass by reference. + \medskip + + \item{$\bullet$} Dynamic memory is allowed, through the ability to + allocate any number of bytes on the heap during execution. + \medskip + + \item{$\bullet$} Scoping of variables is very complicated, because {\it nested subprograms\/} + are allowed. In other words, subprograms are declared within subprogram bodies, much like + local variables. + \medskip + + \doit Consider why this seems like a good idea. Programming language experts + speak of the idea of ``orthogonality'' in programming language design. The following discussion + will indicate why this is not such a good idea, maybe---is the additional complexity worth it? + \medskip + + \item{$\bullet$} In fact, there are two different ideas for scoping in such a language, known + as static (or lexical) scoping and dynamic scoping. Pascal actually uses static scoping, but we will + ponder both approaches here. + \medskip + + \item{$\bullet$} To deal with the semantics of nested subprograms, we will use the + following execution model: + \medskip + \In + Instead of stack frames on a linear strip of memory like we have been doing, + we will use a 2D picture. A rectangle is drawn to represent the local variables and + subprograms for a subprogram. Each such rectangle is labeled in its upper right + corner by the name of the subprogram. + In the upper left corner of each + rectangle we write all the identifiers---variables and subprogram names---that are + declared within the subprogram. + \medskip + + Start with a large box representing the entire program, and + start executing the body of the program in this context. When a subprogram is called, + draw a box for it either inside the active box (that's dynamic scoping) or immediately + inside the box where the subprogram name is declared (that's static scoping). + \medskip + + The meaning of an identifier---both variables and subprograms---is determined + by first looking at the upper left corner of + the current box, and then scanning {\it outward\/} until the identifier is first located. + \medskip + + \item{$\Rightarrow$\quad} Find or write some Pascal code and execute it according to these + rules. Execute the same code with both scoping models. + \medskip + + \item{$\Rightarrow$\quad} Draw a possible memory picture for this model, in the spirit of the + memory pictures we drew for VPL. Note that the boxes we draw are essentially + stack frames, + and try to figure out how a stack frame could hold the + information necessary to implement each scoping model. + \border + \Out + +{\bigboldfont The C Model} +\medskip + + C was invented in an era when + Pascal-like languages (actually as we read online the first day, Niiklaus Wirth + invented Pascal as a simpler language reacting to the complexity of Algol 68) + were dominant and represented a step toward + simplicity. + \medskip + + \item{$\bullet$} C has variables and functions similar to Java's {\tt static} fields and + methods. Variables declared outside any function are visible to any function (there are + lots of details about occurrence within files, but we don't care much). + \medskip + + \item{$\bullet$} C only implements pass-by-value, but it has operators + * (with {\tt int * x} meaning {\tt x} holds an address, and {\tt *x} used in an + expression meaning the cell(s) that {\tt x}'s address points to), and + \& (the ``address of'' operator) + \medskip + + \item{$\bullet$} Dynamic memory is allowed. + \medskip + + \item{$\bullet$} C only has functions. Earlier languages (notably Fortran and Pascal) had both + functions (subprograms that return a value) and subroutines/procedures (subprograms that + don't return a value). + \medskip + \item{$\Rightarrow$\quad} Draw a possible memory picture for the C model, in the spirit of the + memory pictures we drew for VPL. Be sure to include the fact that C allows arbitrarily + large arrays and {\tt struct} variables to be local variables. + \medskip + \Out + +\vfil\eject + +{\bigboldfont Official Announcement of Policy Change} +\medskip + +Some people have asked to work in groups of size larger than three on the Projects, so I +am somewhat reluctantly changing the course policy to allow groups of up to five students submitting +Projects together. If you want to have six people in a group, you must ask for permission. +Larger groups will not be allowed. +\border + +{\bigboldfont Follow-up to Exercise 5 and 6} +\medskip + +After the whole group discussion during +class session 5, Jimmy and I (Peter was flooded out), but I'll take most of the blame, designed +the new language to be named {\tt Jive}. +\medskip + +I then proceeded over the weekend to begin implementing a Jive to VPL translator, as a sanity check before +assigning the same work as Project 2. To avoid burying the lede (yes, that's not the word ``lead'' as +I thought my whole life until recently), I'm not going to assign this work for Project 2, because it seemed +too much. Instead, you will be responsible (on Test 1) +for the concepts of this work: being able to hand-execute +a given Jive program, being able to write a Jive program to perform a specified task, and, most importantly, +being able to translate a given Jive program into VPL. +\medskip + +You can find the code I'm writing in the {\tt Jive} folder at the course web site. I hope to finish it by 9/11/2018. +\medskip + +\doit I will present the draft design for Jive, driven by the draft finite automata hand-written on the next page. +Feedback will be considered (but I've done a fair amount of the implementation work, so I won't +be too open to changes other than correcting problems. +\medskip + +\doit Write a Jive program that will get a positive integer $n$ from the user and will then compute and +report $n!$. +\medskip + +\doit Hand-translate this program to VPL, demonstrating the ideas of my partially-completed code. +\border + +{\bigboldfont Exercise 7} +\medskip + +Working in your small group, write the following Jive programs, and translate each into VPL: +\medskip + +\Indent{1} +\item{$\bullet$} The same goal as Exercise 1, part c. +\medskip + +\item{$\bullet$} The same goal as Exercise 1, part d. +\medskip + +\item{$\bullet$} The same goal as Exercise 3. + +\medskip +\Outdent + +\vfil\eject + +{\bigboldfont Exercise 8} +\medskip + +Note: do this before Exercise 7! +\medskip + +I've been working as time allows on the Jive implementation (current version available at the course web site). +You can help me debug it! +\medskip + +Here is the {\tt factorial.jive} program next to the translated VPL version: +\bigskip\bigskip + +\hbox to \hsize{% +\hfil% +\vbox{\hsize 2.5true in +\listing{../Jive/Tests/factorial}{\tt} +} +\hfil +\vbox{\hsize 1.5true in +\listing{../Jive/Tests/factorial.vpl}{\tt} +}% +\hfil} + +\vfil\eject + +{\bigboldfont The Jive Manual} +\bigskip + +In the following, quantities in angle brackets, like {\tt }, represent single +non-terminal symbols in the given grammar (we'll talk more carefully about context free grammars later). +Other symbols represent physical symbols that can be typed in a Jive program file. +\medskip + +A context free grammar is basically a collection of rules that say the quantity on the left can be +replaced by the quantities on the right of the arrow (the arrow used in CFG's is +different from the two physical symbols {\tt ->} that appear in Jive code). +\medskip + +Note that I'm using a CFG to specify Jive, instead of a finite automaton like I gave you earlier, + because it is easier to type grammar rules than to typeset diagrams. + \medskip + + Quantities that appear in square brackets, like {\tt [ ]}, are optional. + \medskip + +Here are the {\it syntax\/} rules ( with some English mixed in to the rules, purely +for convenience). +\medskip + +{\baselineskip 1.5 \baselineskip + +{\tt } $\rightarrow$ {\tt [ ]
[ ] } + +{\tt } $\rightarrow$ {\tt Globs [ ] .} + +{\tt } $\rightarrow$ zero or more {\tt } + +{\tt } $\rightarrow$ zero or more {\tt } + +{\tt
} $\rightarrow$ zero or more {\tt } + +{\tt } $\rightarrow$ zero or more {\tt } + +{\tt } $\rightarrow$ {\tt Def [ ] . } +\bigskip + +{\tt } $\rightarrow$ {\tt /* } any words that are not */ {\tt */} + +{\tt } $\rightarrow$ {\tt Halt} + +{\tt } $\rightarrow$ {\tt NL} + +{\tt } $\rightarrow$ {\tt