Compiler II: Code Generation Human Thought

Similar documents
Chapter 11: Compiler II: Code Generation

Virtual Machine Where we are at: Part I: Stack Arithmetic. Motivation. Compilation models. direct compilation:... 2-tier compilation:

Virtual Machine. Part I: Stack Arithmetic. Building a Modern Computer From First Principles.

Compiler I: Syntax Analysis

10. The Compiler II: Code Generation 1

Virtual Machine. Part II: Program Control. Building a Modern Computer From First Principles.

Chapter 10: Compiler I: Syntax Analysis

Compiler I: Sytnax Analysis

Chapter 8: Virtual Machine II: Program Control

Assembler Human Thought

Assembler. Building a Modern Computer From First Principles.

Motivation. Compiler. Our ultimate goal: Hack code. Jack code (example) Translate high-level programs into executable code. return; } } return

Introduction: From Nand to Tetris

Introduction: Hello, World Below

Chapter 9: High Level Language

Virtual Machine (Part II)

Chapter 6: Assembler

Machine (Assembly) Language Human Thought

Course overview. Introduction to Computer Yung-Yu Chuang. with slides by Nisan & Schocken (

9. The Compiler I Syntax Analysis 1

IWKS 3300: NAND to Tetris Spring John K. Bennett. Assembler

Machine (Assembly) Language

Course overview. Introduction to Computer Yung-Yu Chuang. with slides by Nisan & Schocken (

Course overview. Introduction to Computer Yung-Yu Chuang. with slides by Nisan & Schocken (

7. The Virtual Machine II: Flow Control 1

Introduction to Programming Using Java (98-388)

Today's Topics. CISC 458 Winter J.R. Cordy

Chapter 6: The Assembler The Assembler Hack Assembly-to-Binary Translation Specification

Virtual Machine (Part II)

High Level Language (Jack)

Computer Architecture

An Overview to Compiler Design. 2008/2/14 \course\cpeg421-08s\topic-1a.ppt 1

CSE P 501 Compilers. Static Semantics Hal Perkins Winter /22/ Hal Perkins & UW CSE I-1

CS1622. Semantic Analysis. The Compiler So Far. Lecture 15 Semantic Analysis. How to build symbol tables How to use them to find

Compiler construction

ECS 142 Project: Code generation hints

Design Issues. Subroutines and Control Abstraction. Subroutines and Control Abstraction. CSC 4101: Programming Languages 1. Textbook, Chapter 8

SEMANTIC ANALYSIS TYPES AND DECLARATIONS

The role of semantic analysis in a compiler

High-Level Language. Building a Modern Computer From First Principles.

Semantic actions for declarations and expressions

Run-time Environments. Lecture 13. Prof. Alex Aiken Original Slides (Modified by Prof. Vijay Ganesh) Lecture 13

Semantic actions for declarations and expressions. Monday, September 28, 15

High-Level Language. Where we are at: Some milestones in the evolution of programming languages. Programming languages

//converts a string to a non-negative number string2int(string s){

Computer Architecture

Semantic Analysis. Outline. The role of semantic analysis in a compiler. Scope. Types. Where we are. The Compiler Front-End

Compilers and computer architecture: A realistic compiler to MIPS

CIT Week13 Lecture

Programming Language Concepts Scoping. Janyl Jumadinova January 31, 2017

Intermediate Code Generation

Homework #3: CMPT-379 Distributed on Oct 23; due on Nov 6 Anoop Sarkar

Compilers. Type checking. Yannis Smaragdakis, U. Athens (original slides by Sam

Anatomy of a Compiler. Overview of Semantic Analysis. The Compiler So Far. Why a Separate Semantic Analysis?

CSC 2400: Computing Systems. X86 Assembly: Function Calls"

MIPS Functions and the Runtime Stack

Lexical Considerations

Boolean Arithmetic. From Nand to Tetris Building a Modern Computer from First Principles. Chapter 2

1 Lexical Considerations

Calling Conventions. Hakim Weatherspoon CS 3410, Spring 2012 Computer Science Cornell University. See P&H 2.8 and 2.12

IWKS 2300/5300 Fall John K. Bennett. Machine Language

Compiler Theory. (Semantic Analysis and Run-Time Environments)

Intermediate Representations & Symbol Tables

Run-time Environments

Run-time Environments

Symbol Tables. ASU Textbook Chapter 7.6, 6.5 and 6.3. Tsan-sheng Hsu.

Protection Levels and Constructors The 'const' Keyword


Run-time Environment

EP1200 Introduktion till datorsystemteknik Tentamen tisdagen den 3 juni 2014, till 18.00

Lexical Considerations

7. The Virtual Machine

The Compiler So Far. CSC 4181 Compiler Construction. Semantic Analysis. Beyond Syntax. Goals of a Semantic Analyzer.

Compilers CS S-05 Semantic Analysis

CSC 2400: Computing Systems. X86 Assembly: Function Calls

Semantic actions for declarations and expressions

Prof. Kavita Bala and Prof. Hakim Weatherspoon CS 3410, Spring 2014 Computer Science Cornell University. See P&H 2.8 and 2.12, and A.

Naming in OOLs and Storage Layout Comp 412

Time : 1 Hour Max Marks : 30

Computer Science Department Carlos III University of Madrid Leganés (Spain) David Griol Barres

CA Compiler Construction

Static Checking and Intermediate Code Generation Pat Morin COMP 3002

Intermediate Code Generation

Intermediate Code Generation

SISTEMI EMBEDDED. Stack, Subroutine, Parameter Passing C Storage Classes and Scope. Federico Baronti Last version:

Basic memory model Using functions Writing functions. Basics Prototypes Parameters Return types Functions and memory Names and namespaces

CS 415 Midterm Exam Spring SOLUTION

Smalltalk Implementation

Type Checking. Chapter 6, Section 6.3, 6.5

CSE P 501 Exam 8/5/04

CSE 582 Autumn 2002 Exam 11/26/02

Short Notes of CS201

Static Semantics. Winter /3/ Hal Perkins & UW CSE I-1

CSC 2400: Computer Systems. Using the Stack for Function Calls

Tail Calls. CMSC 330: Organization of Programming Languages. Tail Recursion. Tail Recursion (cont d) Names and Binding. Tail Recursion (cont d)

Wednesday, October 15, 14. Functions

Parsing Scheme (+ (* 2 3) 1) * 1

Procedure and Object- Oriented Abstraction

G Programming Languages - Fall 2012

High-Level Language. Where we are at:

Transcription:

Course map Compiler II: Code Generation Human Thought Abstract design Chapters 9, 12 abstract interface H.L. Language & Operating Sys. Compiler Chapters 1-11 abstract interface Virtual Machine Software hierarchy VM Translator Chapters 7-8 abstract interface Assembly Language Assembler Chapter 6 Building a Modern Computer From First Principles www.nand2tetris.org abstract interface Machine Language Computer Architecture Chapters 4-5 Hardware hierarchy abstract interface Hardware Platform Gate Logic Chapters 1-3 abstract interface Chips & Logic Gates Electrical Engineering Physics Elements of Computing Systems, Nisan & Schocken, MIT Press, www.nand2tetris.org, Chapter 1: Compiler II: Code Generation slide 1 Elements of Computing Systems, Nisan & Schocken, MIT Press, www.nand2tetris.org, Chapter 1: Compiler II: Code Generation slide 2 The big picture Syntax analysis (review) 1. Syntax analysis: extracting the semantics from the source code 2. Code generation: expressing the semantics using the target language Jack Program Jack Compiler Syntax Analyzer Tokenizer Parser (Chapter 1) Code Gene -ration (Chapter 11) previous chapter This chapter XML code VM code Class Bar { method Fraction foo(int y) { var int temp; // a variable let temp = (xxx+12)* 63; Syntax analyzer The code generation challenge: Program = a series of operations that manipulate data Compiler: converts each understood (parsed) source operation and data item into corresponding operations and data items in the target language <vardec> <keyword> var </keyword> <keyword> int </keyword> <identifier> temp </identifier> <symbol> ; </symbol> </vardec> <statements> <letstatement> <keyword> let </keyword> <identifier> temp </identifier> <symbol> = </symbol> <expression> <symbol> ( </symbol> <expression> <identifier> xxx </identifier> </term> <symbol> + </symbol> <int.const.> 12 </int.const.> </term> </expression> Elements of Computing Systems, Nisan & Schocken, MIT Press, www.nand2tetris.org, Chapter 1: Compiler II: Code Generation slide 3 Elements of Computing Systems, Nisan & Schocken, MIT Press, www.nand2tetris.org, Chapter 1: Compiler II: Code Generation slide 4

Syntax analysis (review) Class Bar { method Fraction foo(int y) { var int temp; // a variable let temp = (xxx+12)* 63; Syntax analyzer The code generation challenge: Thus, we have to generate code for o handling data o handling operations Our approach: morph the syntax analyzer (project 1) into a full-blown compiler: instead of generating XML, we ll make it generate VM code. <vardec> <keyword> var </keyword> <keyword> int </keyword> <identifier> temp </identifier> <symbol> ; </symbol> </vardec> <statements> <letstatement> <keyword> let </keyword> <identifier> temp </identifier> <symbol> = </symbol> <expression> <symbol> ( </symbol> <expression> <identifier> xxx </identifier> </term> <symbol> + </symbol> <int.const.> 12 </int.const.> </term> </expression> Memory segments (review) VM memory Commands: pop segment i push segment i Where i is a non-negative integer and segment is one of the following: static: holds values of global variables, shared by all functions in the same class argument: holds values of the argument variables of the current function local: holds values of the local variables of the current function this: holds values of the private ( object ) variables of the current object that: holds array values (silly name, sorry) constant: holds all the constants in the range 32767 (pseudo memory segment) pointer: used to anchor this and that to various areas in the heap temp: fixed 8-entry segment that holds temporary variables for general use; Shared by all VM functions in the program. Elements of Computing Systems, Nisan & Schocken, MIT Press, www.nand2tetris.org, Chapter 1: Compiler II: Code Generation slide 5 Elements of Computing Systems, Nisan & Schocken, MIT Press, www.nand2tetris.org, Chapter 1: Compiler II: Code Generation slide 6 Memory segments (review) VM implementation on the Hack platform (review) TEMP General purpose SP LCL ARG THIS THAT 1 2 3 4 5 12 13 14 15 16 255 256 247 248 Host RAM Statics Stack Heap Basic idea: the mapping of the stack and the global segments on the RAM is easy (fixed); the mapping of the function-level segments is dynamic, using pointers The stack: mapped on RAM[256.. 247]; The stack pointer is kept in RAM address SP static: mapped on RAM[16 255]; each segment reference static i appearing in a VM file named f is compiled to the assembly language symbol f.i (recall that the assembler further maps such symbols to the RAM, from address 16 onward) Elements of Computing Systems, Nisan & Schocken, MIT Press, www.nand2tetris.org, Chapter 1: Compiler II: Code Generation slide 7 Elements of Computing Systems, Nisan & Schocken, MIT Press, www.nand2tetris.org, Chapter 1: Compiler II: Code Generation slide 8

VM implementation on the Hack platform (review) TEMP General purpose SP LCL ARG THIS THAT 1 2 3 4 5 12 13 14 15 16 255 256 247 248 Host RAM Statics Stack Heap local,argument: these method-level segments are stored in the stack, The base addresses of these segments are kept in RAM addresses LCL and ARG. Access to the i-th entry of any of these segments is implemented by accessing RAM[segmentBase + i] this,that: these dynamically allocated segments are mapped somewhere from address 248 onward, in an area called heap. The base addresses of these segments are kept in RAM addresses THIS, and THAT. constant: a truly a virtual segment: access to constant i is implemented by supplying the constant i. pointer: contains this and that. VM implementation on the Hack platform (review) Global stack: the entire RAM area dedicated for holding the stack Working stack: The stack that the current function sees Elements of Computing Systems, Nisan & Schocken, MIT Press, www.nand2tetris.org, Chapter 1: Compiler II: Code Generation slide 9 Elements of Computing Systems, Nisan & Schocken, MIT Press, www.nand2tetris.org, Chapter 1: Compiler II: Code Generation slide 1 VM implementation on the Hack platform (review) At any point of time, only one function (the current function) is executing; other functions may be waiting up the calling chain Shaded areas: irrelevant to the current function The current function sees only the working stack, and has access only to its memory segments The rest of the stack holds the frozen states of all the functions up the calling hierarchy. Code generation example method int foo() { var int x; let x = x + 1; Syntax analysis (note that x is the first local variable declared in the method) <letstatement> <keyword> let </keyword> <identifier> x </identifier> <symbol> = </symbol> <expression> <identifier> x </identifier> </term> <symbol> + </symbol> <constant> 1 </constant> </term> </expression> </letstatement> Code generation push local push constant 1 add pop local Elements of Computing Systems, Nisan & Schocken, MIT Press, www.nand2tetris.org, Chapter 1: Compiler II: Code Generation slide 11 Elements of Computing Systems, Nisan & Schocken, MIT Press, www.nand2tetris.org, Chapter 1: Compiler II: Code Generation slide 12

Handling variables When the compiler encounters a variable, say x, in the source code, it has to know: What is x s data type? Primitive, or ADT (class name)? (Need to know in order to properly allocate RAM resources for its representation) What kind of variable is x? static, field, local, argument? ( We need to know in order to properly allocate it to the right memory segment; this also implies the variable s life cycle ). Elements of Computing Systems, Nisan & Schocken, MIT Press, www.nand2tetris.org, Chapter 1: Compiler II: Code Generation slide 13 Handling variables: mapping them on memory segments (example) class BankAccount { // class variables static int naccounts; static int bankcommission; // account propetrties field int id; field String owner; field int balance; method void transfer(int sum, BankAccount from, Date when){ var int i, j; // some local variables var Date due; // Date is a user-define type let balance = (balance + sum) commission(sum * 5); // More code The target language uses 8 memory segments Each memory segment, e.g. static, is an indexed sequence of 16-bit values that can be referred to as static, static 1, static 2, etc. Elements of Computing Systems, Nisan & Schocken, MIT Press, www.nand2tetris.org, Chapter 1: Compiler II: Code Generation slide 14 Handling variables: mapping them on memory segments (example) class BankAccount { // class variables static int naccounts; static int bankcommission; // account propetrties field int id; field String owner; field int balance; When compiling this class, we have to create the following mappings: The class variables naccounts, bankcommission are mapped on static,1 The object fields id, owner, balance are mapped on this,1,2 Elements of Computing Systems, Nisan & Schocken, MIT Press, www.nand2tetris.org, Chapter 1: Compiler II: Code Generation slide 15 Handling variables: mapping them on memory segments (example) method void transfer(int sum, BankAccount from, Date when){ var int i, j; // some local variables var Date due; // Date is a user-define type let balance = (balance + sum) commission(sum * 5); // More code When compiling this class, we have to create the following mappings: The class variables naccounts, bankcommission are mapped on static,1 The object fields id, owner, balance are mapped on this,1,2 The argument variables sum, bankaccount, when are mapped on argument,1,2 The local variables i, j, due are mapped on local,1,2. Elements of Computing Systems, Nisan & Schocken, MIT Press, www.nand2tetris.org, Chapter 1: Compiler II: Code Generation slide 16

Handling variables: symbol tables class BankAccount { static int naccounts; static int bankcommission; field int id; field String owner; field int balance; method void transfer(int sum, BankAccount from, Date when){ var int i, j; var Date due; let balance = (balance + sum) commission(sum * 5); // More code How the compiler uses symbol tables: The compiler builds and maintains a linked list of hash tables, each reflecting a single scope nested within the next one in the list Identifier lookup works from the current symbol table back to the list s head (a classical implementation). Elements of Computing Systems, Nisan & Schocken, MIT Press, www.nand2tetris.org, Chapter 1: Compiler II: Code Generation slide 17 Handling variables: managing their life cycle Variables life cycle static variables: single copy must be kept alive throughout the program duration field variables: different copies must be kept for each object local variables: created on subroutine entry, killed on exit argument variables: similar to local variables. Good news: the VM implementation already handles all these details! Elements of Computing Systems, Nisan & Schocken, MIT Press, www.nand2tetris.org, Chapter 1: Compiler II: Code Generation slide 18 Handling objects: establishing access to the object s fields Handling objects: establishing access to the object s fields Background: Suppose we have an object named b of type Ball. A Ball has x, y coordinates, a radius, and a color. Class Ball { field int x, y, radius, color; method void SetR(int r) { radius = r; Ball b; b=ball.new(); b.setr(17); Class Ball { void SetR(int r) { radius = r; Ball b; b.setr(17); b object High level program view x: y: radius: color: 12 8 5 3 following compilation (Actual RAM locations of program variables are run-time dependent, and thus the addresses shown here are arbitrary examples.) 412 312 312 313 314 315 RAM view 12 8 5 3 b b object Elements of Computing Systems, Nisan & Schocken, MIT Press, www.nand2tetris.org, Chapter 1: Compiler II: Code Generation slide 19 Elements of Computing Systems, Nisan & Schocken, MIT Press, www.nand2tetris.org, Chapter 1: Compiler II: Code Generation slide 2

Handling objects: establishing access to the object s fields need to know which Class Ball { instance it is working on void SetR(int r) { radius = r; need to pass the object Ball b; into the function b.setr(17); => Ball.SetR(b, 17) // Get b's base address: push argument Virtual memory segments just before // Point the the operation this b.radius=17: segment to b: pop pointer argument pointer this // Get r's 312value push 1argument 17 1 // Set b's third field to r: pop this 2 1 1 Virtual memory segments just before the operation b.radius=17: argument pointer this 312 Virtual memory segments just after the operation b.radius=17: argument pointer this 312 17 17 1 1 this is now aligned with RAM[312] 312 1 2 3 12 8 17 3 R Handling objects: construction / memory allocation class Complex { // Fields (properties): int re; // Real part int im; // Imaginary part /** Constructs a new Complex number */ public Complex (int re, int im) { this.re = re; this.im = im; Elements of Computing Systems, Nisan & Schocken, MIT Press, www.nand2tetris.org, Chapter 1: Compiler II: Code Generation slide 21 Elements of Computing Systems, Nisan & Schocken, MIT Press, www.nand2tetris.org, Chapter 1: Compiler II: Code Generation slide 22 Handling objects: construction / memory allocation class Foo { public void bla() { Complex a, b, c; a = new Complex(5,17); b = new Complex(12,192); // Only the reference is copied c = a; Following execution: Handling objects: construction / memory allocation class Foo { public void bla() { Complex a, b, c; a = new Complex(5,17); b = new Complex(12,192); // Only the reference is copied c = a; How to compile: foo = new ClassName( ) The compiler generates code affecting: foo = Memory.alloc(n) Where n is the number of words necessary to represent the object in question, and Memory.alloc is an OS method that returns the base address of a free memory block of size n words. Elements of Computing Systems, Nisan & Schocken, MIT Press, www.nand2tetris.org, Chapter 1: Compiler II: Code Generation slide 23 Elements of Computing Systems, Nisan & Schocken, MIT Press, www.nand2tetris.org, Chapter 1: Compiler II: Code Generation slide 24

Handling objects: accessing fields class Complex { // Fields (properties): int re; // Real part int im; // Imaginary part /** Constructs a new Complex number */ public Complex (int re, int im) { this.re = re; this.im = im; /** Multiplies this Complex number by the given scalar */ public void mult (int c) { re = re * c; im = im * c; How to compile: im = im * c? 1. look up the two variables in the symbol table 2. Generate the code: *(this + 1) = *(this + 1) times (argument ) This pseudo-code should be expressed in the target language. Handling objects: method calls class Complex { public void mult (int c) { re = re * c; im = im * c; class Foo { public void bla() { Complex x; x = new Complex(1,2); x.mult(5); How to compile: x.mult(5)? This method call can also be viewed as: mult(x,5) Generate the following code: push x push 5 call mult Elements of Computing Systems, Nisan & Schocken, MIT Press, www.nand2tetris.org, Chapter 1: Compiler II: Code Generation slide 25 Elements of Computing Systems, Nisan & Schocken, MIT Press, www.nand2tetris.org, Chapter 1: Compiler II: Code Generation slide 26 Handling objects: method calls class Complex { public void mult (int c) { re = re * c; im = im * c; class Foo { public void bla() { Complex x; x = new Complex(1,2); x.mult(5); General rule: each method call foo.bar(v1,v2,) is translated into: push foo push v1 push v2 call bar Handling array int foo() { // some language, not Jack int bar[1]; bar[2] = 19; Elements of Computing Systems, Nisan & Schocken, MIT Press, www.nand2tetris.org, Chapter 1: Compiler II: Code Generation slide 27 Elements of Computing Systems, Nisan & Schocken, MIT Press, www.nand2tetris.org, Chapter 1: Compiler II: Code Generation slide 28

Handling array Elements of Computing Systems, Nisan & Schocken, MIT Press, www.nand2tetris.org, Chapter 1: Compiler II: Code Generation slide 29 Handling arrays: declaration / construction class Bla { void foo(int k) { int x, y; int[] bar; // declare an array // Construct the array: bar = new int[1]; bar[k]=19; Main.foo(2); // Call the foo method How to compile: Following compilation: bar = new int(n)? Generate code affecting: bar = Memory.alloc(n) Elements of Computing Systems, Nisan & Schocken, MIT Press, www.nand2tetris.org, Chapter 1: Compiler II: Code Generation slide 3 275 276 277 54 4315 4316 4317 4318 4324 RAM state 4315 x y 2 k bar (local ) (local 1) (local 2) (argument ) (bar array) Handling arrays: accessing an array entry by its index class Bla { void foo(int k) { int x, y; int[] bar; // declare an array // Construct the array: bar = new int[1]; bar[k]=19; Main.foo(2); // Call the foo method How to compile: bar[k] = 19? Following compilation: RAM state, just after executing bar[k] = 19 275 276 277 54 4315 4316 4317 4318 4324 RAM state 4315 19 x y 2 k bar (local ) (local 1) (local 2) (argument ) (bar array) Handling arrays: accessing an array entry by its index How to compile: bar[k] = 19? VM Code (pseudo) // bar[k]=19, // or *(bar+k)=19 push bar push k add // Use a pointer to // access x[k] // addr points to bar[k] pop addr push 19 // Set bar[k] to 19 pop *addr VM Code (actual) // bar[k]=19, // or *(bar+k)=19 push local 2 push argument add // Use a pointer to // access x[k] pop pointer 1 push constant 19 pop that Elements of Computing Systems, Nisan & Schocken, MIT Press, www.nand2tetris.org, Chapter 1: Compiler II: Code Generation slide 31 Elements of Computing Systems, Nisan & Schocken, MIT Press, www.nand2tetris.org, Chapter 1: Compiler II: Code Generation slide 32

Handling expressions High-level code ((5+z)/-8)*(4^2) VM code Handling expressions (Jack grammar) term binary term syntax analysis parse tree code generation push 5 push z add push 8 neg call div push 4 push 2 call power call mult x : x appears verbatim x: x is a language construct x?: x appears or 1 times x*: x appears or more times x y: either x or y appears (x,y): x appears, then y. Elements of Computing Systems, Nisan & Schocken, MIT Press, www.nand2tetris.org, Chapter 1: Compiler II: Code Generation slide 33 Elements of Computing Systems, Nisan & Schocken, MIT Press, www.nand2tetris.org, Chapter 1: Compiler II: Code Generation slide 34 Handling expressions (Jack grammar) term constant function variable unary op x : x appears verbatim x: x is a language construct x?: x appears or 1 times x*: x appears or more times x y: either x or y appears (x,y): x appears, then y. Elements of Computing Systems, Nisan & Schocken, MIT Press, www.nand2tetris.org, Chapter 1: Compiler II: Code Generation slide 35 Handling expressions To generate VM code from a parse tree exp, use the following logic: The codewrite(exp) algorithm: if exp is a constant n then output "push n" if exp is a variable v then output "push v" if exp is op(exp 1 ) then codewrite(exp 1 ); output "op"; if exp is f (exp 1,, exp n ) then codewrite(exp1); codewrite(expn); output "call f"; if exp is (exp 1 op exp 2 ) then codewrite(exp 1 ); codewrite(exp 2 ); output "op"; Elements of Computing Systems, Nisan & Schocken, MIT Press, www.nand2tetris.org, Chapter 1: Compiler II: Code Generation slide 36

The Jack grammar (Expression) From parsing to code generation (simplified expression) EXP TERM (OP TERM)* TERM integer variable OP + - * / Elements of Computing Systems, Nisan & Schocken, MIT Press, www.nand2tetris.org, Chapter 1: Compiler II: Code Generation slide 37 Elements of Computing Systems, Nisan & Schocken, MIT Press, www.nand2tetris.org, Chapter 1: Compiler II: Code Generation slide 38 From parsing to code generation From parsing to code generation EXP TERM (OP TERM)* TERM integer variable OP + - * / EXP() : while (next()==op) OP(); EXP TERM (OP TERM)* TERM integer variable OP + - * / EXP() : while (next()==op) OP(); TERM(): case INT: eat(int); case VAR: eat(var); Elements of Computing Systems, Nisan & Schocken, MIT Press, www.nand2tetris.org, Chapter 1: Compiler II: Code Generation slide 39 Elements of Computing Systems, Nisan & Schocken, MIT Press, www.nand2tetris.org, Chapter 1: Compiler II: Code Generation slide 4

From parsing to code generation From parsing to code generation EXP TERM (OP TERM)* TERM integer variable OP + - * / EXP() : while (next()==op) OP(); EXP TERM (OP TERM)* TERM integer variable OP + - * / EXP() : while (next()==op) OP(); OP(): OP(): case +: eat(add); TERM(): case +: eat(add); TERM(): case -: eat(sub); case INT: case -: eat(sub); case INT: case *: eat(mul); case VAR: eat(int); case *: eat(mul); case VAR: eat(int); case /: eat(div); eat(var); case /: eat(div); eat(var); Elements of Computing Systems, Nisan & Schocken, MIT Press, www.nand2tetris.org, Chapter 1: Compiler II: Code Generation slide 41 Elements of Computing Systems, Nisan & Schocken, MIT Press, www.nand2tetris.org, Chapter 1: Compiler II: Code Generation slide 42 From parsing to code generation The Jack grammar (Expression) EXP TERM (OP TERM)* TERM integer variable OP + - * / OP(): case +: eat(add); return add ; case -: eat(sub); return sub ; case *: eat(mul); return call Math.mul ; case /: eat(div); return call Math.div ; EXP() : while (next()==op) op=op(); write(op); TERM(): case INT: write( push constant +next()); eat(int); case VAR: write( push +lookup(next())); eat(var); Elements of Computing Systems, Nisan & Schocken, MIT Press, www.nand2tetris.org, Chapter 1: Compiler II: Code Generation slide 43 Elements of Computing Systems, Nisan & Schocken, MIT Press, www.nand2tetris.org, Chapter 1: Compiler II: Code Generation slide 44

The Jack grammar (statement) The Jack grammar (statement) STATEMENTS() : while (next() in {let, if, while, do, return) STATEMENT(); STATEMENT() : case LET: case IF: case WHILE: case DO: case RETURN: LET_STAT(); IF_STAT(); WHILE_STAT(); DO_STAT(); RETURN_STAT(); Elements of Computing Systems, Nisan & Schocken, MIT Press, www.nand2tetris.org, Chapter 1: Compiler II: Code Generation slide 45 Elements of Computing Systems, Nisan & Schocken, MIT Press, www.nand2tetris.org, Chapter 1: Compiler II: Code Generation slide 46 let statement Handling program flow Parsing LET_STAT(): eat(let); eat(var); eat(eq); EXP(); eat(semi); Parsing with code generation LET_STAT(): eat(let); variable=lookup(next()); eat(var); eat(eq); EXP(); eat(semi); write( pop + variable) if (cond) s1 else s2 code generation High-level code VM code VM code to compute and push!(cond) if goto L1 VM code for executing s1 goto L2 label L1 VM code for executing s2 label L2 Elements of Computing Systems, Nisan & Schocken, MIT Press, www.nand2tetris.org, Chapter 1: Compiler II: Code Generation slide 47 Elements of Computing Systems, Nisan & Schocken, MIT Press, www.nand2tetris.org, Chapter 1: Compiler II: Code Generation slide 48

Handling program flow The Jack grammar (class) while (cond) s code generation High-level code VM code label L1 VM code to compute and push!(cond) if goto L2 VM code for executing s goto L1 label L2 Elements of Computing Systems, Nisan & Schocken, MIT Press, www.nand2tetris.org, Chapter 1: Compiler II: Code Generation slide 49 CLASS() : eat(class); eat(id); eat( { ); while (next() in {static, field) CLASSVARDEC(); while (next() in {constructor, function, method) SUBROUTINEDEC(); eat( ); Elements of Computing Systems, Nisan & Schocken, MIT Press, www.nand2tetris.org, Chapter 1: Compiler II: Code Generation slide 5 The Jack grammar (class) The Jack grammar (class) CLASS() : eat(class); class=registerclass(next()); eat(id); eat( { ); while (next() in {static, field) CLASSVARDEC(class); while (next() in {constructor, function, method) SUBROUTINEDEC(class); CLASSVARDEC(class) : case static: eat(static); kind=static; case field: eat(field); kind=field; case int: type=int; eat(int); case char: type=char; eat(char); case boolean: type=boolean; eat(boolean); case ID: type=lookup(next()); eat(id); registerclassvar(class, next(), kind, type); eat(id); while (next()=comma) registerclassvar(class, next(), kind, type); eat(id); Elements of Computing Systems, Nisan & Schocken, eat( ); MIT Press, www.nand2tetris.org, Chapter 1: Compiler II: Code Generation slide 51 Elements of Computing Systems, Nisan & Schocken, MIT Press, www.nand2tetris.org, Chapter 1: Compiler II: Code Generation slide 52

Put them together class BankAccount { static int naccounts; static int bankcommission; field int id; field String owner; field int balance; method void transfer(int sum, BankAccount from, Date when){ var int i, j; var Date due; let balance = (balance + sum) commission(sum * 5); // More code let balance = (balance + sum) commission(sum * 5) Elements of Computing Systems, Nisan & Schocken, MIT Press, www.nand2tetris.org, Chapter 1: Compiler II: Code Generation slide 53 Perspective Jack simplifications that are challenging to extend: Limited primitive type system No inheritance No public class fields, e.g. must use r = c.getradius() rather than r = c.radius Jack simplifications that are easy to extend: : Limited control structures, e.g. no for, switch, Cumbersome handling of char types, e.g. cannot use let x= c Optimization For example, c=c+1 is translated inefficiently into push c, push 1, add, pop c. Parallel processing Many other examples of possible improvements Elements of Computing Systems, Nisan & Schocken, MIT Press, www.nand2tetris.org, Chapter 1: Compiler II: Code Generation slide 55