Compiler construction

Similar documents
Compiler construction

Functions - Lecture 7. Nested functions. Another example. A Nested Function. Josef Svenningsson

Weeks 6&7: Procedures and Parameter Passing

Concepts Introduced in Chapter 7

CA Compiler Construction

Administration CS 412/413. Advanced Language Support. First-class vs. Second-class. First-class functions. Function Types

Lecture08: Scope and Lexical Address

April 2 to April 4, 2018

4 Functional Programming Languages

Topics Covered Thus Far. CMSC 330: Organization of Programming Languages. Language Features Covered Thus Far. Programming Languages Revisited

Every language has its own scoping rules. For example, what is the scope of variable j in this Java program?

Typical Runtime Layout. Tiger Runtime Environments. Example: Nested Functions. Activation Trees. code. Memory Layout

Procedures and Run-Time Storage

CMSC 330: Organization of Programming Languages

Transactional Memory for C/C++ IBM XL C/C++ for Blue Gene/Q, V12.0 (technology preview)

Procedures and Run-Time Storage

Run-time Environments - 2

Scope, Functions, and Storage Management

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

CSE341 Autumn 2017, Final Examination December 12, 2017

Topics Covered Thus Far CMSC 330: Organization of Programming Languages

Programming Languages. Thunks, Laziness, Streams, Memoization. Adapted from Dan Grossman s PL class, U. of Washington

CMSC 330: Organization of Programming Languages. Closures (Implementing Higher Order Functions)

Compilers. 8. Run-time Support. Laszlo Böszörmenyi Compilers Run-time - 1

CMSC 330: Organization of Programming Languages. Closures (Implementing Higher Order Functions)

CSE413: Programming Languages and Implementation Racket structs Implementing languages with interpreters Implementing closures

CSci 4223 Lecture 12 March 4, 2013 Topics: Lexical scope, dynamic scope, closures

Functional Languages and Higher-Order Functions

f() ! " Run a higher-priority task? ! " Yield the processor to another task because our ! " Use the processor for some other activity while

CS 410/510: Advanced Programming

Advances in Programming Languages: Regions

Lectures Basics in Procedural Programming: Machinery

Execution order. main()

Dispatch techniques and closure representations

G Programming Languages - Fall 2012

Anonymous Functions CMSC 330: Organization of Programming Languages

JVM ByteCode Interpreter

Structure and Interpretation of Computer Programs

CS 11 Haskell track: lecture 1

Homework 5. Notes. Turn-In Instructions. Reading. Problems. Handout 19 CSCI 334: Spring (Required) Read Mitchell, Chapters 6 and 7.

QUIZ Friends class Y;

MORE SCHEME. 1 What Would Scheme Print? COMPUTER SCIENCE MENTORS 61A. October 30 to November 3, Solution: Solutions begin on the following page.

CSE 341: Programming Languages

Optimizing Closures in O(0) time

Subroutines. Subroutine. Subroutine design. Control abstraction. If a subroutine does not fit on the screen, it is too long

CSE341: Programming Languages Lecture 17 Implementing Languages Including Closures. Dan Grossman Autumn 2018

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

Functions CHAPTER 5. FIGURE 1. Concrete syntax for the P 2 subset of Python. (In addition to that of P 1.)

CS 415 Midterm Exam Spring 2002

Functions CHAPTER 5. FIGURE 1. Concrete syntax for the P 2 subset of Python. (In addition to that of P 1.)

G Programming Languages Spring 2010 Lecture 4. Robert Grimm, New York University

The Typed Racket Guide

CIT Week13 Lecture

Types and Type Inference

Ozyegin University CS 321 Programming Languages Sample Problems 05

Fall 2018 Lecture N

CSE341 Spring 2017, Final Examination June 8, 2017

CS558 Programming Languages

CS 315 Programming Languages Subprograms

CS457/557 Functional Languages

Scheme. Functional Programming. Lambda Calculus. CSC 4101: Programming Languages 1. Textbook, Sections , 13.7

Test 1 Summer 2014 Multiple Choice. Write your answer to the LEFT of each problem. 5 points each 1. Preprocessor macros are associated with: A. C B.

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

Lecture 5. Announcements: Today: Finish up functions in MIPS

Compiler construction 2009

CS558 Programming Languages

Software System Design and Implementation

CSE 413 Midterm, May 6, 2011 Sample Solution Page 1 of 8

QUIZ on Ch.5. Why is it sometimes not a good idea to place the private part of the interface in a header file?

Defunctionalizing Push Arrays

DO NOT OPEN UNTIL INSTRUCTED

Lecture 13: Complex Types and Garbage Collection

Subprograms. Akim D le Étienne Renault Roland Levillain EPITA École Pour l Informatique et les Techniques Avancées

System Software Assignment 1 Runtime Support for Procedures

Wellesley College CS251 Programming Languages Spring, 2000 FINAL EXAM REVIEW PROBLEM SOLUTIONS

Run-time Environments

Syntax Errors; Static Semantics

Compilers: The goal. Safe. e : ASM

Run-time Environments

CSE341: Programming Languages Lecture 9 Function-Closure Idioms. Dan Grossman Winter 2013

An introduction to C++ template programming

Binghamton University. CS-211 Fall Variable Scope

CS558 Programming Languages

CMSC 330: Organization of Programming Languages. Functional Programming with Lists

Binghamton University. CS-211 Fall Variable Scope

Principles of Programming Languages Topic: Scope and Memory Professor Louis Steinberg Fall 2004

Run Time Environment. Activation Records Procedure Linkage Name Translation and Variable Access

SEMANTIC ANALYSIS TYPES AND DECLARATIONS

Programming Language Concepts Scoping. Janyl Jumadinova January 31, 2017

Names, Bindings, Scopes

Haskell: Lists. CS F331 Programming Languages CSCE A331 Programming Language Concepts Lecture Slides Friday, February 24, Glenn G.

! " Haskell Expressions are treated as: !" Thunks. !" Closures. !" Delayed Computations. !" Suspensions. ! " Expressions are evaluated: !

Programs in memory. The layout of memory is roughly:

CSE341: Programming Languages Lecture 11 Type Inference. Dan Grossman Spring 2016

CSE351 Spring 2018, Final Exam June 6, 2018

Monad Background (3A) Young Won Lim 11/8/17

CSE341 Spring 2017, Final Examination June 8, 2017

Compiler Construction 2012/2013 Functional Programming Languages

Singly linked lists in C.

CSE341, Spring 2013, Final Examination June 13, 2013

Transcription:

Compiler construction Lecture 7: Functions Nested functions Alex Gerdes Vårtermin 2016 Chalmers Uniersity of Technology Gothenburg Uniersity A Nested Function Another example To make nested functions useful we would like to hae lexical scoping. Suppose we extend JaaLette with nested functions. double hypsq(double a, double b) { double square(double d) { return d * d; return square(a) + square(b); This means that we can use ariables in the inner function, defined in the outer function. double sqrt(double s) { double newton(double y) { return (y + s / y) / 2; double x = 0.0; int i = 0; while (i < 10) { x = newton(x); i++; return x; Access links Access links Outline of a quicksort implementation: Access links are a mechanism to access ariables defined in an enclosing procedure An access link is an extra field in a stack frame which points to the closes stack frame of the enclosing procedure An access link is sometimes called a static link oid sort(int[] arr) { oid quicksort(int m, int n) { int =... oid partition(int y, int z) { write(y);... arr......... arr...... partition... quicksort oid write(int x) {... arr... x...... quicksort...

Example stack Following access links S arr q(1,9) q(1,3) p(1,3) When accessing e.g. the ariable arr in p we need to go through the access link to q and then to s. When procedure q calls procedure p there are three cases to consider: 1. p has higher nesting depth than q Then the depth of p must be exactly one larger than q and p s access link must point to q. 2. p and q hae the same nesting depth The access link for p is the same as for q. 3. p has a lower nesting depth than q Let n p be the nesting depth of p and n q be the nesting depth of q. Furthermore, suppose that p is defined immediately within procedure r. The top actiation record for r can be found by following n q n p + 1 access links up the stack. Displays Displays If the nesting depth is ery large, then the link chains may be ery long; traersing these links can be costly Displays were deeloped to speed up access A Display is an stack, separate from the call stack, which maintains pointers to the most recent actiation record of the different nesting depths The display grows and shrinks with the maximum nesting depth of the functions on the call stack d[1] d[2] d[3] S q(1,9) saed d[2] q(1,3) saed d[2] p(1,3) saed d[3] Lambda lifting Lambda lifting - example Another way of implementing nested functions is by lifting them to the top leel Free ariables are handled by adding them as parameters to the lifted function Original sqrt double sqrt(double s) { double newton(double y) { return (y + s / y) / 2; double x = 0.0; int i = 0; while (i < 10) { x = newton(x); return x;

Lambda lifting - example Another lifting example Lambda lifted sqrt double newton(double y, double s) { return (y + s / y) / 2; double sqrt(double s) { double x = 0.0; int i = 0; while (i < 10) { x = newton(x,s); return x; Consider lambda lifting the function below. oid foo() { int c = 0; oid incc() { c++; incc(); incc(); printint(c); Call-by-reference The local function incc modifies its free ariable. In order to lift incc we hae to pass the parameter c by reference. oid incc(int *c) { (*c)++; oid foo() { int c = 0; incc(&c); incc(&c); printint(c); Higher order functions Higher order fuctions in JaaLette Higher order functions in JaaLette Adding higher order functions to JaaLette we need a new form of types: Type(Type,..., Type) Examples: bool(int, int) A function which takes two int arguments and returns a bool oid() A function which takes no arguments and doesn t return anything int main() { int(int) add(int n) { int h(int m) { return n + m; return h; int(int) addfie = add(5); printint(addfie(15));

Higher order functions in JaaLette Implementing higher order functions int main() { int(int) add(int n) {... int(int) addfie = add(5); int(int) twice(int(int) f) { int g(int x) { return f(f(x)); return g; int(int) addten = twice(addfie); printint(twice(twice(addten))(2)); There are seeral ways implementing higher order functions: s can be adapted to also deal with higher order functions Defunctionalization is a method to conert higher order functions to data structures; requires whole program compilation Closures are used to represent functions by a heap allocated record containing a code pointer and the free ariables of the function Using closures is by far the most common implementation method Defunctionalization example 1 Defunctionalization example data Tree a = Leaf a Node (Tree a) (Tree a) cons :: a -> [a] -> [a] cons x xs = x : xs o :: (b -> c) -> (a -> b) -> a -> c o f g x = f (g x) walk :: Tree t -> [t] -> [t] walk (Leaf x) = cons x walk (Node t1 t2) = o (walk t1) (walk t2) flatten :: Tree t -> [t] flatten t = walk t [] 1 Adapted from Oliier Dany / Wikipedia data Lam a = LamCons a LamO (Lam a) (Lam a) LamWalk (Lam a) apply :: Lam a -> [a] -> [a] apply (LamCons x) xs = x : xs apply (LamO f1 f2) xs = apply f1 (apply f2 xs) apply (LamWalk f) xs = apply f xs cons_def :: a -> Lam a cons_def x = LamCons x o_def :: Lam a -> Lam a -> Lam a o_def f1 f2 = LamO f1 f2 walk_def :: Tree t -> Lam t walk_def (Leaf x) = LamWalk (cons_def x) walk_def (Node t1 t2) = LamWalk (o_def (walk_def t1) (walk_def t2)) flatten_def :: Tree t -> [t] flatten_def t = apply (walk_def t) [] Closures Closures and mutable ariables main n code for h What happens with the stack allocated ariable counter once we exit the function makecounter? add A closures is a pair of a code pointer and an enironment containing the free ariables of the function The closure for h inside add contains a pointer to the code for h and the alue for the ariable n The closure is heap allocated int() makecounter(int start) { int counter = start; int inc() { counter++; return counter; return inc;

Closures and mutable ariables Closures and mutable ariables What happens with the stack allocated ariable counter once we exit the function makecounter? Heap allocate part of the stack frame Forbid such programs (example: Jaa) int() makecounter(int start) { int counter = start; int inc() { counter++; return counter; return inc; Functional languages like Haskell and ML deal with the problem of closures and mutability as follows: Eerything is immutable by default Mutation is introduced by references which always lie on the heap makecounter = do r <- newioref 0 let inc = do n <- readioref r writeioref r (n+1) return n return inc Anonymous nested functions Lambda expressions An increasingly popular language feature is to hae anonymous nested functions, so called lambda expressions Compiling lambda expressions works the same way as nested functions with names Lazy ealuation A note on terminology One can often hear the phrase that a language has closures This is a somewhat unfortunate use of the word Closures is an implementation technique for the language feature higher order functions Question Question Is it possible to implement if as a function? Is it possible to implement if as a function? We can fake it by using functions which take no arguments oid if(bool c, oid() th) { if (c) th(); We emulate lazy ealuation with this construct

Example - lazy lists typedef struct Node *lazylist; struct Node { int elem; lazylist() next; lazylist cons(int x, lazylist() xs) { list res = new Node; res->elem = x; res->next = xs; return res; int sum(lazylist xs) { if (xs == (lazylist)null) return 0; else return xs->elem + sum(xs->next()); Example - lazy lists int main() { printint(sum(take(42, enumfrom(1)))); return 0; lazylist enumfrom(int n) { lazylist rec() { return enumfrom(n + 1); return cons(n, rec); lazylist take(int n, lazylist xs) { if (xs == (lazylist)null) return xs; else if (n < 1) return (lazylist)null; else { lazylist rec() { return take(n - 1, xs->next()); return cons(xs->elem, rec); Thunks Lazy ealuation Call-by-name is a calling conention where the arguments are not ealuated until needed Thunks are used to implement call-by-name Thunks are essentially functions which take no arguments They are typically implemented as closures The difference between call-by-name and lazy ealuation is that once an argument is ealuated, it is not reealuated if it is used twice In order to achiee laziness, once the alue is computed we need to remember it This can be done in two ways: Oerwrite the thunk with an indirection pointing to the alue Oerwrite the thunk with the alue directly, if the space allocated for the thunk is big enough to hold the alue A Note Call-by-name and lazy ealuation is ery handy as they allow the programmer to create new control structures Be careful with combining them with side-effects: it can yield ery surprising results An impure language with lazy ealuation as default is a bad idea