May 14, 2002 Macro Languages AoPL, S'02 Macro Languages Claus Brabrand Michael I. Schwartzbach BRICS, University of Aarhus, Denmark.

Slides:



Advertisements
Similar presentations
Semantics Static semantics Dynamic semantics attribute grammars
Advertisements

COS 320 Compilers David Walker. Outline Last Week –Introduction to ML Today: –Lexical Analysis –Reading: Chapter 2 of Appel.
Control Structures Any mechanism that departs from straight-line execution: –Selection: if-statements –Multiway-selection: case statements –Unbounded iteration:
CSE341: Programming Languages Lecture 16 Datatype-Style Programming With Lists or Structs Dan Grossman Winter 2013.
Getting started with ML ML is a functional programming language. ML is statically typed: The types of literals, values, expressions and functions in a.
9/27/2006Prof. Hilfinger, Lecture 141 Syntax-Directed Translation Lecture 14 (adapted from slides by R. Bodik)
Maya: Multiple-Dispatch Syntax Extension in Java Jason Baker and Wilson C. Hsieh University of Utah.
CS 330 Programming Languages 09 / 13 / 2007 Instructor: Michael Eckmann.
Chapter 3 Describing Syntax and Semantics Sections 1-3.
Compilation 2007 Domain-Specific Languages Syntax Extensions Michael I. Schwartzbach BRICS, University of Aarhus.
May 21, 2002 The metafront Tool AoPL, S'02 Language Transformation: The metafront Tool Claus Brabrand Michael I. Schwartzbach BRICS, University of Aarhus,
Outline Java program structure Basic program elements
Chapter 3 Describing Syntax and Semantics Sections 1-3.
) y + 1 * => square ( January 31, 2005MacrosClaus Brabrand y + 1 Widespread … ……… … ……... Dylan Dylan Macro Mechamism M4 Unix Macro Preprocessor L A T.
Chapter 3 Program translation1 Chapt. 3 Language Translation Syntax and Semantics Translation phases Formal translation models.
1 Foundations of Software Design Lecture 23: Finite Automata and Context-Free Grammars Marti Hearst Fall 2002.
Chapter 3 Describing Syntax and Semantics Sections 1-3.
The Structure of the GNAT Compiler. A target-independent Ada95 front-end for GCC Ada components C components SyntaxSemExpandgigiGCC AST Annotated AST.
Maya: Multiple-Dispatch Syntax Extension in Java Jason Baker and Wilson C. Hsieh University of Utah.
CS 330 Programming Languages 09 / 16 / 2008 Instructor: Michael Eckmann.
Introduction to C Programming
Abstract Data Types and Encapsulation Concepts
CSC 8310 Programming Languages Meeting 2 September 2/3, 2014.
1 Syntax and Semantics The Purpose of Syntax Problem of Describing Syntax Formal Methods of Describing Syntax Derivations and Parse Trees Sebesta Chapter.
2.2 A Simple Syntax-Directed Translator Syntax-Directed Translation 2.4 Parsing 2.5 A Translator for Simple Expressions 2.6 Lexical Analysis.
Syntax & Semantic Introduction Organization of Language Description Abstract Syntax Formal Syntax The Way of Writing Grammars Formal Semantic.
Imperative Programming
CPSC 388 – Compiler Design and Construction Parsers – Context Free Grammars.
The Java Programming Language
CS 326 Programming Languages, Concepts and Implementation Instructor: Mircea Nicolescu Lecture 2.
Introduction to Scheme CS 480/680 – Comparative Languages “And now for something completely different…” – Monty Python “And now for something completely.
PART I: overview material
Lesson 3 CDT301 – Compiler Theory, Spring 2011 Teacher: Linus Källberg.
Hello.java Program Output 1 public class Hello { 2 public static void main( String [] args ) 3 { 4 System.out.println( “Hello!" ); 5 } // end method main.
C H A P T E R TWO Syntax and Semantic.
TextBook Concepts of Programming Languages, Robert W. Sebesta, (10th edition), Addison-Wesley Publishing Company CSCI18 - Concepts of Programming languages.
COP 4620 / 5625 Programming Language Translation / Compiler Writing Fall 2003 Lecture 3, 09/11/2003 Prof. Roy Levow.
Formal Semantics Chapter Twenty-ThreeModern Programming Languages, 2nd ed.1.
1 Syntax In Text: Chapter 3. 2 Chapter 3: Syntax and Semantics Outline Syntax: Recognizer vs. generator BNF EBNF.
CPS120: Introduction to Computer Science Decision Making in Programs.
CPS 506 Comparative Programming Languages Syntax Specification.
Comp 248 Introduction to Programming Chapter 4 & 5 Defining Classes Part B Dr. Aiman Hanna Department of Computer Science & Software Engineering Concordia.
CS412/413 Introduction to Compilers and Translators Spring ’99 Lecture 3: Introduction to Syntactic Analysis.
ISBN Chapter 3 Describing Syntax and Semantics.
Syntax and Grammars.
 2003 Prentice Hall, Inc. All rights reserved. 1 IS 0020 Program Design and Software Tools Preprocessor Midterm Review Lecture 7 Feb 17, 2004.
CMSC 330: Organization of Programming Languages Operational Semantics a.k.a. “WTF is Project 4, Part 3?”
1 A Simple Syntax-Directed Translator CS308 Compiler Theory.
1 Introduction to Parsing. 2 Outline l Regular languages revisited l Parser overview Context-free grammars (CFG ’ s) l Derivations.
CMSC 330: Organization of Programming Languages Operational Semantics.
C H A P T E R T W O Syntax and Semantic. 2 Introduction Who must use language definitions? Other language designers Implementors Programmers (the users.
Comp 311 Principles of Programming Languages Lecture 2 Syntax Corky Cartwright August 26, 2009.
CS 404Ahmed Ezzat 1 CS 404 Introduction to Compiler Design Lecture 1 Ahmed Ezzat.
PEPM 2002 Growing Languages with Metamorphic Syntax Macros January 14, 2002 Growing Languages with Metamorphic Syntax Macros Claus Brabrand Michael Schwartzbach.
Chapter 3 – Describing Syntax
CS 326 Programming Languages, Concepts and Implementation
A Simple Syntax-Directed Translator
Introduction to Parsing (adapted from CS 164 at Berkeley)
Interpreters Study Semantics of Programming Languages through interpreters (Executable Specifications) cs7100(Prasad) L8Interp.
Representation, Syntax, Paradigms, Types
Lecture 15 (Notes by P. N. Hilfinger and R. Bodik)
The Metacircular Evaluator
Representation, Syntax, Paradigms, Types
Representation, Syntax, Paradigms, Types
6.001 SICP Further Variations on a Scheme
Representation, Syntax, Paradigms, Types
6.001 SICP Interpretation Parts of an interpreter
COMPILER CONSTRUCTION
SPL – PS1 Introduction to C++.
Presentation transcript:

May 14, 2002 Macro Languages AoPL, S'02 Macro Languages Claus Brabrand Michael I. Schwartzbach BRICS, University of Aarhus, Denmark

May 14, 2002 Macro Languages AoPL, S'02 Outline Introduction Macro survey: Lexical macros: CPP, M4, T E X, ( Dylan ) Syntax macros: C++ templates, Scheme, JTS, MS 2 The macro language Metamorphic syntax macros Next week: The metafront Tool Specificity parsing Language transformation

May 14, 2002 Macro Languages AoPL, S'02 Introduction

May 14, 2002 Macro Languages AoPL, S'02 “Macro” Webster’s(“macro”) = Main Entry: 2 macro Pronunciation: 'ma-(")krO Function: noun Inflected Form(s): plural macros Etymology: short for macroinstruction Date: 1959 “a single computer instruction that stands for a sequence of operations”

May 14, 2002 Macro Languages AoPL, S'02 Motivation (#1) Abstraction (language extension): Iterator iterator = list.iterator(); while (iterator.hasNext()) { String s = (String) iterator.next(); System.out.println(s); } Iterator iterator = list.iterator(); while (iterator.hasNext()) { String s = (String) iterator.next(); System.out.println(s); } foreach (String s in list) { System.out.println(s); } foreach (String s in list) { System.out.println(s); } vs.

May 14, 2002 Macro Languages AoPL, S'02 Motivation (#2) Genericity (uniform abstraction mechanism): Generic abstraction mechanism for all syntactic categories: …whereas functions only “take” and “give” expressions:  ( ) Principle of Abstraction: “Any semantically meaningful syntactic class can in principle be used as the body of an abstraction” - Robert Tennent, 1981 Principle of Abstraction: “Any semantically meaningful syntactic class can in principle be used as the body of an abstraction” - Robert Tennent, 1981

May 14, 2002 Macro Languages AoPL, S'02 Motivation (#3) Consistency: Object[] strings = list.toArray(); for (int i=0; i<strings.length; i++) { String s = (String) strings[i]; System.out.println(s); } Object[] strings = list.toArray(); for (int i=0; i<strings.length; i++) { String s = (String) strings[i]; System.out.println(s); } Iterator iterator = list.iterator(); while (iterator.hasNext()) { String s = (String) iterator.next(); System.out.println(s); } Iterator iterator = list.iterator(); while (iterator.hasNext()) { String s = (String) iterator.next(); System.out.println(s); } vs.

May 14, 2002 Macro Languages AoPL, S'02 Motivation (#4) Laziness (abbreviation): vs. Iterator iterator = list.iterator(); while (iterator.hasNext()) { String s = (String) iterator.next(); System.out.println(s); } Iterator iterator = list.iterator(); while (iterator.hasNext()) { String s = (String) iterator.next(); System.out.println(s); } foreach (String s in list) { System.out.println(s); } foreach (String s in list) { System.out.println(s); }

May 14, 2002 Macro Languages AoPL, S'02 Motivation (#5) Encapsulation (hide complexity): vs. foreach (String s in list) { System.out.println(s); } foreach (String s in list) { System.out.println(s); } Iterator iterator = list.iterator(); while (iterator.hasNext()) { String s = (String) iterator.next(); System.out.println(s); } Iterator iterator = list.iterator(); while (iterator.hasNext()) { String s = (String) iterator.next(); System.out.println(s); }

May 14, 2002 Macro Languages AoPL, S'02 Macro Survey

May 14, 2002 Macro Languages AoPL, S'02 Many Macro Languages CPP M4 TEXTEX Scheme C++ templates MS 2...and many more Dylan JTS

May 14, 2002 Macro Languages AoPL, S'02 Non-Alphabetical Characters CPP M4 TEXTEX Scheme C++ templates MS 2...and many more Dylan JTS

May 14, 2002 Macro Languages AoPL, S'02 Level of Operation CPP M4 TEXTEX Scheme C++ templates Dylan JTS LexicalSyntactic...and many more MS 2

May 14, 2002 Macro Languages AoPL, S'02 Lexical Macros Operate on token sequences: M LEX : (T OKEN S EQ ) n  T OKEN S EQ Precede actual compilation (conceptually) –i.e. a preprocessor Independent of host language syntax Languages: CPP:“The C Preprocessor” M4: “The Unix Macro Preprocessor” TEX: TEX’s macro mechanism Dylan: Dylan’s macro mechanism (hybrid)

May 14, 2002 Macro Languages AoPL, S'02 Lexical Macro Example Square (CPP): #define square(X) X * X

May 14, 2002 Macro Languages AoPL, S'02 Lexical Macro Example Square (CPP): #define square(X) X * X square(z + 1) #define square(X) X * X square(z + 1) ()z + 1square

May 14, 2002 Macro Languages AoPL, S'02 Lexical Macro Example Square (CPP): #define square(X) X * X square(z + 1) => z + 1 * z + 1 #define square(X) X * X square(z + 1) => z + 1 * z + 1 ()z + 1 * => square

May 14, 2002 Macro Languages AoPL, S'02 Lexical Macro Example Square (CPP): #define square(X) X * X square(z + 1) => z +(1 * z)+ 1 #define square(X) X * X square(z + 1) => z +(1 * z)+ 1 ()z + 1 * => square

May 14, 2002 Macro Languages AoPL, S'02 Lexical Macro Example Square (CPP): Work-around: Explicitly add parentheses #define square(X) X * X square(z + 1) => z +(1 * z)+ 1 #define square(X) X * X square(z + 1) => z +(1 * z)+ 1 #define square(X) (X) * (X) ()z + 1 * => square

May 14, 2002 Macro Languages AoPL, S'02 Lexical Macro Example Square (CPP): Work-around: Explicitly add parentheses #define square(X) X * X square(z + 1) => z +(1 * z)+ 1 #define square(X) X * X square(z + 1) => z +(1 * z)+ 1 #define square(X) (X) * (X) square(z + 1) => (z + 1)*(z + 1) #define square(X) (X) * (X) square(z + 1) => (z + 1)*(z + 1) ()z + 1 * => square

May 14, 2002 Macro Languages AoPL, S'02 Lexical Macro Example Square (CPP): Work-around: Explicitly add parentheses –Problem: Independent of host language syntax Unsafe: parse errors discovered at invocation-time #define square(X) X * X square(z + 1) => z +(1 * z)+ 1 #define square(X) X * X square(z + 1) => z +(1 * z)+ 1 #define square(X) (X) * (X) square(z + 1) => (z + 1)*(z + 1) #define square(X) (X) * (X) square(z + 1) => (z + 1)*(z + 1) ()z + 1 * => square

May 14, 2002 Macro Languages AoPL, S'02 Syntactic Macros Operate on abstract syntax trees: M SYN : (A ST ) n  A ST Integrated with host language –typed with host language nonterminals Languages: C++: The C++ template mechanism Scheme: Scheme’s define-syntax mechanism JTS:“Jakarta Tool Suite” macro mechanism MS 2 : “Meta Syntactic Macro System” : The macro language

May 14, 2002 Macro Languages AoPL, S'02 Syntactic Macro Example Square ( ): macro  square ( ) ::= { * } macro  square ( ) ::= { * }

May 14, 2002 Macro Languages AoPL, S'02 Syntactic Macro Example Square ( ): * * exp E exp E macro  square ( ) ::= { * } macro  square ( ) ::= { * } ~

May 14, 2002 Macro Languages AoPL, S'02 Syntactic Macro Example Square ( ): * * exp E exp E y + 1y + 1 y + 1y + 1 exp macro  square ( ) ::= { * } macro  square ( ) ::= { * } square( ) ~

May 14, 2002 Macro Languages AoPL, S'02 Syntactic Macro Example Square ( ): * * exp E exp E * * exp y + 1y + 1 y + 1y + 1 y + 1y + 1 y + 1y + 1 E exp E y + 1y + 1 y + 1y + 1 exp macro  square ( ) ::= { * } macro  square ( ) ::= { * } square( ) => ~

May 14, 2002 Macro Languages AoPL, S'02 Lexical Macros CPP, M4, T E X, (Dylan) ()z + 1 * => square

May 14, 2002 Macro Languages AoPL, S'02 CPP CPP (“The C Preprocessor”): Also as a stand-alone expander: gcc –E program cpp program Intercepts preprocessor directives “ # ”: #define, #undef, #ifdef, #if, #include, #line, ##, … #define square(X) (X) * (X) square(z + 1) => (z + 1)*(z + 1) #define square(X) (X) * (X) square(z + 1) => (z + 1)*(z + 1)

May 14, 2002 Macro Languages AoPL, S'02 Fixed Invocation Syntax #define swap(X,Y) { int t=X; X=Y; Y=t; }

May 14, 2002 Macro Languages AoPL, S'02 Fixed Invocation Syntax #define swap(X,Y) { int t=X; X=Y; Y=t; } if (a>b) swap(a,b); else b = 0; #define swap(X,Y) { int t=X; X=Y; Y=t; } if (a>b) swap(a,b); else b = 0;

May 14, 2002 Macro Languages AoPL, S'02 Fixed Invocation Syntax #define swap(X,Y) { int t=X; X=Y; Y=t; } if (a>b) swap(a,b); else b = 0; #define swap(X,Y) { int t=X; X=Y; Y=t; } if (a>b) swap(a,b); else b = 0; *** test.c:3: parse error before ‘else’

May 14, 2002 Macro Languages AoPL, S'02 Fixed Invocation Syntax #define swap(X,Y) { int t=X; X=Y; Y=t; } if (a>b) swap(a,b); else b = 0; #define swap(X,Y) { int t=X; X=Y; Y=t; } if (a>b) swap(a,b); else b = 0; *** test.c:3: parse error before ‘else’

May 14, 2002 Macro Languages AoPL, S'02 Fixed Invocation Syntax #define swap(X,Y) { int t=X; X=Y; Y=t; } if (a>b) swap(a,b); else b = 0; #define swap(X,Y) { int t=X; X=Y; Y=t; } if (a>b) swap(a,b); else b = 0; *** test.c:3: parse error before ‘else’ #define swap(X,Y) do { int t=X; X=Y; Y=t; } while(0) if (a>b) swap(a,b); else b = 0; #define swap(X,Y) do { int t=X; X=Y; Y=t; } while(0) if (a>b) swap(a,b); else b = 0;

May 14, 2002 Macro Languages AoPL, S'02 Fixed Invocation Syntax –Problem: fixed invocation syntax same for exp, stm, … M(x,y,z) #define swap(X,Y) { int t=X; X=Y; Y=t; } if (a>b) swap(a,b); else b = 0; #define swap(X,Y) { int t=X; X=Y; Y=t; } if (a>b) swap(a,b); else b = 0; *** test.c:3: parse error before ‘else’ #define swap(X,Y) do { int t=X; X=Y; Y=t; } while(0) if (a>b) swap(a,b); else b = 0; #define swap(X,Y) do { int t=X; X=Y; Y=t; } while(0) if (a>b) swap(a,b); else b = 0;

May 14, 2002 Macro Languages AoPL, S'02 Body Expansion Consider: #define A 87 #define B A #undef A #define A 42 B => ??? #define A 87 #define B A #undef A #define A 42 B => ???

May 14, 2002 Macro Languages AoPL, S'02 Body Expansion Consider: Eager expansion (definition-time): #define A 87 #define B A #undef A #define A 42 B => ??? #define A 87 #define B A #undef A #define A 42 B => ??? B => 87

May 14, 2002 Macro Languages AoPL, S'02 Body Expansion Consider: Eager expansion (definition-time): Lazy expansion (invocation-time): #define A 87 #define B A #undef A #define A 42 B => ??? #define A 87 #define B A #undef A #define A 42 B => ??? B => 87 B => A CPP

May 14, 2002 Macro Languages AoPL, S'02 Body Expansion Consider: Eager expansion (definition-time): Lazy expansion (invocation-time): #define A 87 #define B A #undef A #define A 42 B => ??? #define A 87 #define B A #undef A #define A 42 B => ??? B => 87 B => A => 42 CPP

May 14, 2002 Macro Languages AoPL, S'02 Order of Expansion Consider: #define id(X) X #define one(X) id(X) #define two a,b one(two) => ??? #define id(X) X #define one(X) id(X) #define two a,b one(two) => ???

May 14, 2002 Macro Languages AoPL, S'02 Order of Expansion Consider: Inner (aka. “AOR”, call-by-value): #define id(X) X #define one(X) id(X) #define two a,b one(two) => ??? #define id(X) X #define one(X) id(X) #define two a,b one(two) => ??? one(two) => one(a,b) => *** arity error ‘one’

May 14, 2002 Macro Languages AoPL, S'02 Order of Expansion Consider: Inner (aka. “AOR”, call-by-value): Outer (aka. “NOR”, call-by-name): #define id(X) X #define one(X) id(X) #define two a,b one(two) => ??? #define id(X) X #define one(X) id(X) #define two a,b one(two) => ??? one(two) => one(a,b) => *** arity error ‘one’ one(two) => id(two) => two => a,b

May 14, 2002 Macro Languages AoPL, S'02 CPP: Order of Expansion “Argument prescan”: one(two) #define id(X) X #define one(X) id(X) #define two a,b #define id(X) X #define one(X) id(X) #define two a,b CPP

May 14, 2002 Macro Languages AoPL, S'02 CPP: Order of Expansion “Argument prescan”: one(two) => id(a,b) #define id(X) X #define one(X) id(X) #define two a,b #define id(X) X #define one(X) id(X) #define two a,b CPP

May 14, 2002 Macro Languages AoPL, S'02 CPP: Order of Expansion “Argument prescan”: one(two) => id(a,b) => *** arity error ‘id’ #define id(X) X #define one(X) id(X) #define two a,b #define id(X) X #define one(X) id(X) #define two a,b CPP

May 14, 2002 Macro Languages AoPL, S'02 CPP: Order of Expansion “Argument prescan”: For piecing together new macro invocations partly from the arguments, partly from the body: one(two) => id(a,b) => *** arity error ‘id’ #define succ(X) ((X) + 1) #define call7(X) X(7) call7(succ) => succ(7) => ((7) + 1) #define succ(X) ((X) + 1) #define call7(X) X(7) call7(succ) => succ(7) => ((7) + 1) #define id(X) X #define one(X) id(X) #define two a,b #define id(X) X #define one(X) id(X) #define two a,b CPP

May 14, 2002 Macro Languages AoPL, S'02 Recursion Consider: #define x 1+x x => ??? #define x 1+x x => ???

May 14, 2002 Macro Languages AoPL, S'02 Recursion Consider: Definition-time (static intercept-and-reject): #define x 1+x x => ??? #define x 1+x x => ??? #define x 1*x *** definition-time error!

May 14, 2002 Macro Languages AoPL, S'02 Recursion Consider: Definition-time (static intercept-and-reject): Invocation-time (non-termination): #define x 1+x x => ??? #define x 1+x x => ??? #define x 1*x *** definition-time error! x => 1+x => 1+1+x => … // loop at compile-time!

May 14, 2002 Macro Languages AoPL, S'02 CPP: Recursion “Dynamic intercept-and-ignore”: Keep stack of macro invocations Ignore invocations of already invoked macros: x => 1+x int x = 2; #define x 1+x x => ??? int x = 2; #define x 1+x x => ??? CPP

May 14, 2002 Macro Languages AoPL, S'02 CPP: Recursion “Dynamic intercept-and-ignore”: Keep stack of macro invocations Ignore invocations of already invoked macros: x => 1+x // intercept-and-ignore: (at runtime x  3) int x = 2; #define x 1+x x => ??? int x = 2; #define x 1+x x => ??? CPP

May 14, 2002 Macro Languages AoPL, S'02 M4 M4 (Unix Macro Preprocessor): Originally called “ratfor”: –“The Rational Fortran Preprocessor” Not tailored for a particular language universal preprocessor 30+ built-in constructions: macro definition, arithmetic evaluation, string operations, file and system interfacing, …

May 14, 2002 Macro Languages AoPL, S'02 M4 Example Implicit arguments (named: $1, …, $9) Excess arguments ignored Missing arguments default to “” Quoting: –Expansion removes one layer of quotes Controls expansion-time (eager by default): define(‘square’, ‘ eval($1 * $1) ’ )

May 14, 2002 Macro Languages AoPL, S'02 M4 Example Implicit arguments (named: $1, …, $9) Excess arguments ignored Missing arguments default to “” Quoting: –Expansion removes one layer of quotes Controls expansion-time (eager by default): define(‘square’, ‘ eval($1 * $1) ’ ) square(3) define(‘square’, ‘ eval($1 * $1) ’ ) square(3)

May 14, 2002 Macro Languages AoPL, S'02 M4 Example Implicit arguments (named: $1, …, $9) Excess arguments ignored Missing arguments default to “” Quoting: –Expansion removes one layer of quotes Controls expansion-time (eager by default): define(‘square’, ‘ eval($1 * $1) ’ ) square(3) => eval(3 * 3) define(‘square’, ‘ eval($1 * $1) ’ ) square(3) => eval(3 * 3)

May 14, 2002 Macro Languages AoPL, S'02 M4 Example Implicit arguments (named: $1, …, $9) Excess arguments ignored Missing arguments default to “” Quoting: –Expansion removes one layer of quotes Controls expansion-time (eager by default): define(‘square’, ‘ eval($1 * $1) ’ ) square(3) => eval(3 * 3) => 9 define(‘square’, ‘ eval($1 * $1) ’ ) square(3) => eval(3 * 3) => 9

May 14, 2002 Macro Languages AoPL, S'02 TEXTEX Flexible invocation syntax: Designed by macro programmer \def \vector #1[#2..#3]{ // header $({#1}_{#2},\ldots,{#1}_{#3})$ // body } \def \vector #1[#2..#3]{ // header $({#1}_{#2},\ldots,{#1}_{#3})$ // body }

May 14, 2002 Macro Languages AoPL, S'02 TEXTEX Flexible invocation syntax: Designed by macro programmer \def \vector #1[#2..#3]{ // header $({#1}_{#2},\ldots,{#1}_{#3})$ // body } \vector x’[0..n-1] \def \vector #1[#2..#3]{ // header $({#1}_{#2},\ldots,{#1}_{#3})$ // body } \vector x’[0..n-1]

May 14, 2002 Macro Languages AoPL, S'02 TEXTEX Flexible invocation syntax: Designed by macro programmer \def \vector #1[#2..#3]{ // header $({#1}_{#2},\ldots,{#1}_{#3})$ // body } \vector x’[0..n-1] => $({x’}_{0},\ldots,{x’}_{n-1})$ \def \vector #1[#2..#3]{ // header $({#1}_{#2},\ldots,{#1}_{#3})$ // body } \vector x’[0..n-1] => $({x’}_{0},\ldots,{x’}_{n-1})$

May 14, 2002 Macro Languages AoPL, S'02 TEXTEX Flexible invocation syntax: Designed by macro programmer \def \vector #1[#2..#3]{ // header $({#1}_{#2},\ldots,{#1}_{#3})$ // body } \vector x’[0..n-1] => $({x’}_{0},\ldots,{x’}_{n-1})$ \def \vector #1[#2..#3]{ // header $({#1}_{#2},\ldots,{#1}_{#3})$ // body } \vector x’[0..n-1] => $({x’}_{0},\ldots,{x’}_{n-1})$ (x’ 0, …, x’ n-1 )

May 14, 2002 Macro Languages AoPL, S'02 TEXTEX Flexible invocation syntax: Designed by macro programmer Parsing ambiguities (chooses shortest invocation) \def \vector #1[#2..#3]{ // header $({#1}_{#2},\ldots,{#1}_{#3})$ // body } \vector x’[0..n-1] => $({x’}_{0},\ldots,{x’}_{n-1})$ \def \vector #1[#2..#3]{ // header $({#1}_{#2},\ldots,{#1}_{#3})$ // body } \vector x’[0..n-1] => $({x’}_{0},\ldots,{x’}_{n-1})$ (x’ 0, …, x’ n-1 )

May 14, 2002 Macro Languages AoPL, S'02 TEXTEX Flexible invocation syntax: Designed by macro programmer Parsing ambiguities (chooses shortest invocation) –Implies: \def \vector #1[#2..#3]{ // header $({#1}_{#2},\ldots,{#1}_{#3})$ // body } \vector x’[0..n-1] => $({x’}_{0},\ldots,{x’}_{n-1})$ \def \vector #1[#2..#3]{ // header $({#1}_{#2},\ldots,{#1}_{#3})$ // body } \vector x’[0..n-1] => $({x’}_{0},\ldots,{x’}_{n-1})$ (x’ 0, …, x’ n-1 ) M M x // invokes M(M), not M(M(x))

May 14, 2002 Macro Languages AoPL, S'02 TEXTEX Flexible invocation syntax: Designed by macro programmer Parsing ambiguities (chooses shortest invocation) –Implies: Recursion permitted: TC compile-time language to “break the recursion” \def \vector #1[#2..#3]{ // header $({#1}_{#2},\ldots,{#1}_{#3})$ // body } \vector x’[0..n-1] => $({x’}_{0},\ldots,{x’}_{n-1})$ \def \vector #1[#2..#3]{ // header $({#1}_{#2},\ldots,{#1}_{#3})$ // body } \vector x’[0..n-1] => $({x’}_{0},\ldots,{x’}_{n-1})$ (x’ 0, …, x’ n-1 ) M M x // invokes M(M), not M(M(x))

May 14, 2002 Macro Languages AoPL, S'02 Syntax Macros C++ templates, Scheme, JTS, MS 2

May 14, 2002 Macro Languages AoPL, S'02 C++ Templates Intended as a genericity mechanism But often used as a macro language

May 14, 2002 Macro Languages AoPL, S'02 C++ Templates Intended as a genericity mechanism But often used as a macro language Syntax types: Arguments: id, const, all types (e.g. int ) The result is always a declaration

May 14, 2002 Macro Languages AoPL, S'02 C++ Templates Intended as a genericity mechanism But often used as a macro language Syntax types: Arguments: id, const, all types (e.g. int ) The result is always a declaration Multiple definitions: template struct M { … }

May 14, 2002 Macro Languages AoPL, S'02 C++ Templates Intended as a genericity mechanism But often used as a macro language Syntax types: Arguments: id, const, all types (e.g. int ) The result is always a declaration Multiple definitions: Constant folding: template struct M { … } (1 + 2)  3 // at compile-time

May 14, 2002 Macro Languages AoPL, S'02 However… template struct ct_pow { static const int res = 1; }; template struct ct_pow { static const int res = X * ct_pow ::res; }; const int z = ct_pow ::res; // c-time z  125 template struct ct_pow { static const int res = 1; }; template struct ct_pow { static const int res = X * ct_pow ::res; }; const int z = ct_pow ::res; // c-time z  125

May 14, 2002 Macro Languages AoPL, S'02 However… Constant folding + multiple definition = Turing complete (at compile-time)! template struct ct_pow { static const int res = 1; }; template struct ct_pow { static const int res = X * ct_pow ::res; }; const int z = ct_pow ::res; // c-time z  125 template struct ct_pow { static const int res = 1; }; template struct ct_pow { static const int res = X * ct_pow ::res; }; const int z = ct_pow ::res; // c-time z  125

May 14, 2002 Macro Languages AoPL, S'02 Scheme Convenient pattern matching (define-syntax and (syntax-rules () ((and) #t) ((and b) b) ((and b …) (if b (and …) #f)))))))))))))))))) :) (define-syntax and (syntax-rules () ((and) #t) ((and b) b) ((and b …) (if b (and …) #f)))))))))))))))))) :)

May 14, 2002 Macro Languages AoPL, S'02 Scheme Convenient pattern matching (define-syntax and (syntax-rules () ((and) #t) ((and b) b) ((and b …) (if b (and …) #f)))))))))))))))))) :) (and a (if x y z) c) => (if...) (define-syntax and (syntax-rules () ((and) #t) ((and b) b) ((and b …) (if b (and …) #f)))))))))))))))))) :) (and a (if x y z) c) => (if...)

May 14, 2002 Macro Languages AoPL, S'02 Scheme Convenient pattern matching Multiple definitions: –Selection: first match in order listed (define-syntax and (syntax-rules () ((and) #t) ((and b) b) ((and b …) (if b (and …) #f)))))))))))))))))) :) (and a (if x y z) c) => (if...) (define-syntax and (syntax-rules () ((and) #t) ((and b) b) ((and b …) (if b (and …) #f)))))))))))))))))) :) (and a (if x y z) c) => (if...)

May 14, 2002 Macro Languages AoPL, S'02 Scheme Convenient pattern matching Multiple definitions: –Selection: first match in order listed Ellipsis list constructor: “ … ” –More on this later… (define-syntax and (syntax-rules () ((and) #t) ((and b) b) ((and b …) (if b (and …) #f)))))))))))))))))) :) (and a (if x y z) c) => (if...) (define-syntax and (syntax-rules () ((and) #t) ((and b) b) ((and b …) (if b (and …) #f)))))))))))))))))) :) (and a (if x y z) c) => (if...)

May 14, 2002 Macro Languages AoPL, S'02 Hygienic Macro Expansion Scheme has automatic  -conversion: Identifier renaming to avoid name capture (define-syntax gen-inc (syntax-rules () ((gen-inc i) (lambda (x) (+ x i)))) (define-syntax gen-inc (syntax-rules () ((gen-inc i) (lambda (x) (+ x i))))

May 14, 2002 Macro Languages AoPL, S'02 Hygienic Macro Expansion Scheme has automatic  -conversion: Identifier renaming to avoid name capture let ((x 3)) ( (define-syntax gen-inc (syntax-rules () ((gen-inc i) (lambda (x) (+ x i)))) (define-syntax gen-inc (syntax-rules () ((gen-inc i) (lambda (x) (+ x i)))) )

May 14, 2002 Macro Languages AoPL, S'02 Hygienic Macro Expansion Scheme has automatic  -conversion: Identifier renaming to avoid name capture let ((x 3)) ( Without  -conversion (define-syntax gen-inc (syntax-rules () ((gen-inc i) (lambda (x) (+ x i)))) (define-syntax gen-inc (syntax-rules () ((gen-inc i) (lambda (x) (+ x i)))) ((gen-inc x) 5) )

May 14, 2002 Macro Languages AoPL, S'02 Hygienic Macro Expansion Scheme has automatic  -conversion: Identifier renaming to avoid name capture let ((x 3)) ( Without  -conversion (define-syntax gen-inc (syntax-rules () ((gen-inc i) (lambda (x) (+ x i)))) (define-syntax gen-inc (syntax-rules () ((gen-inc i) (lambda (x) (+ x i)))) ((gen-inc x) 5) => ((lambda (x) (+ x x)) 5) )

May 14, 2002 Macro Languages AoPL, S'02 Hygienic Macro Expansion Scheme has automatic  -conversion: Identifier renaming to avoid name capture let ((x 3)) ( Without  -conversion (define-syntax gen-inc (syntax-rules () ((gen-inc i) (lambda (x) (+ x i)))) (define-syntax gen-inc (syntax-rules () ((gen-inc i) (lambda (x) (+ x i)))) ((gen-inc x) 5) => ((lambda (x) (+ x x)) 5) => 10 )

May 14, 2002 Macro Languages AoPL, S'02 Hygienic Macro Expansion Scheme has automatic  -conversion: Identifier renaming to avoid name capture let ((x 3)) ( Without  -conversion With  -conversion: (define-syntax gen-inc (syntax-rules () ((gen-inc i) (lambda (x) (+ x i)))) (define-syntax gen-inc (syntax-rules () ((gen-inc i) (lambda (x) (+ x i)))) ((gen-inc x) 5) => ((lambda (x) (+ x x)) 5) => 10 ((gen-inc x) 5) )

May 14, 2002 Macro Languages AoPL, S'02 Hygienic Macro Expansion Scheme has automatic  -conversion: Identifier renaming to avoid name capture let ((x 3)) ( Without  -conversion With  -conversion: (define-syntax gen-inc (syntax-rules () ((gen-inc i) (lambda (x) (+ x i)))) (define-syntax gen-inc (syntax-rules () ((gen-inc i) (lambda (x) (+ x i)))) ((gen-inc x) 5) => ((lambda (x) (+ x x)) 5) => 10 ((gen-inc x) 5) => ((lambda (x’) (+ x’ x)) 5) )

May 14, 2002 Macro Languages AoPL, S'02 Hygienic Macro Expansion Scheme has automatic  -conversion: Identifier renaming to avoid name capture let ((x 3)) ( Without  -conversion With  -conversion: (define-syntax gen-inc (syntax-rules () ((gen-inc i) (lambda (x) (+ x i)))) (define-syntax gen-inc (syntax-rules () ((gen-inc i) (lambda (x) (+ x i)))) ((gen-inc x) 5) => ((lambda (x) (+ x x)) 5) => 10 ((gen-inc x) 5) => ((lambda (x’) (+ x’ x)) 5) => 8 )

May 14, 2002 Macro Languages AoPL, S'02 Compile-Time Programming Basically compile-time functions on S-exps Lazy (inv.-time) body expansion (  evaluation): (define-syntax m (syntax-rules () ((m) (if )))) (m) => // *** parse error: too many arg’s to if (define-syntax m (syntax-rules () ((m) (if )))) (m) => // *** parse error: too many arg’s to if

May 14, 2002 Macro Languages AoPL, S'02 Compile-Time Programming Basically compile-time functions on S-exps Lazy (inv.-time) body expansion (  evaluation): Non-termination possible: (define-syntax ct-loop (syntax-rules () ((ct-loop) (ct-loop)))) (define-syntax ct-loop (syntax-rules () ((ct-loop) (ct-loop)))) (define-syntax m (syntax-rules () ((m) (if )))) (m) => // *** parse error: too many arg’s to if (define-syntax m (syntax-rules () ((m) (if )))) (m) => // *** parse error: too many arg’s to if

May 14, 2002 Macro Languages AoPL, S'02 Compile-Time Programming Basically compile-time functions on S-exps Lazy (inv.-time) body expansion (  evaluation): Non-termination possible: (define-syntax ct-loop (syntax-rules () ((ct-loop) (ct-loop)))) (ct-loop) => // c-time loop (define-syntax ct-loop (syntax-rules () ((ct-loop) (ct-loop)))) (ct-loop) => // c-time loop (define-syntax m (syntax-rules () ((m) (if )))) (m) => // *** parse error: too many arg’s to if (define-syntax m (syntax-rules () ((m) (if )))) (m) => // *** parse error: too many arg’s to if

May 14, 2002 Macro Languages AoPL, S'02 JTS JTS (“Jakarta Tool Suite”): macro swap(AST_QualifiedName x, AST_QualifiedName y) local temp // explicit  -conversion stm{ // body constructor: stm integer temp = x; x = y; y = temp; }stm macro swap(AST_QualifiedName x, AST_QualifiedName y) local temp // explicit  -conversion stm{ // body constructor: stm integer temp = x; x = y; y = temp; }stm

May 14, 2002 Macro Languages AoPL, S'02 JTS JTS (“Jakarta Tool Suite”): Argument types: name, exp, stm, decl, class, type Result types: “ exp ”, “ stm ”, “ mth ”, “ cls ”, “ prg ” macro swap(AST_QualifiedName x, AST_QualifiedName y) local temp // explicit  -conversion stm{ // body constructor: stm integer temp = x; x = y; y = temp; }stm macro swap(AST_QualifiedName x, AST_QualifiedName y) local temp // explicit  -conversion stm{ // body constructor: stm integer temp = x; x = y; y = temp; }stm

May 14, 2002 Macro Languages AoPL, S'02 JTS JTS (“Jakarta Tool Suite”): Argument types: name, exp, stm, decl, class, type Result types: “ exp ”, “ stm ”, “ mth ”, “ cls ”, “ prg ” –Fixed invocation syntax: macro swap(AST_QualifiedName x, AST_QualifiedName y) local temp // explicit  -conversion stm{ // body constructor: stm integer temp = x; x = y; y = temp; }stm macro swap(AST_QualifiedName x, AST_QualifiedName y) local temp // explicit  -conversion stm{ // body constructor: stm integer temp = x; x = y; y = temp; }stm #swap(C.x, y);

May 14, 2002 Macro Languages AoPL, S'02 JTS JTS (“Jakarta Tool Suite”): Argument types: name, exp, stm, decl, class, type Result types: “ exp ”, “ stm ”, “ mth ”, “ cls ”, “ prg ” –Fixed invocation syntax: –Safe: Guaranteed termination, only generate legal syntax macro swap(AST_QualifiedName x, AST_QualifiedName y) local temp // explicit  -conversion stm{ // body constructor: stm integer temp = x; x = y; y = temp; }stm macro swap(AST_QualifiedName x, AST_QualifiedName y) local temp // explicit  -conversion stm{ // body constructor: stm integer temp = x; x = y; y = temp; }stm #swap(C.x, y);

May 14, 2002 Macro Languages AoPL, S'02 MS 2 MS 2 (“Meta Syntactic Macro System”): Turing complete AST programming language –for computing C parse trees at compile-time syntax decl myenum[] {| $$id::name { $$+\,id::ids }; |} { return (list(`[enum $name $ids;], `[$(symbolconc(“print_”,name))(arg) { switch (arg) id; `{ case $id: printf(“%s”, $(pstring(id)));}), ids))})); } syntax decl myenum[] {| $$id::name { $$+\,id::ids }; |} { return (list(`[enum $name $ids;], `[$(symbolconc(“print_”,name))(arg) { switch (arg) id; `{ case $id: printf(“%s”, $(pstring(id)));}), ids))})); }

May 14, 2002 Macro Languages AoPL, S'02 MS 2 MS 2 (“Meta Syntactic Macro System”): Turing complete AST programming language –for computing C parse trees at compile-time syntax decl myenum[] {| $$id::name { $$+\,id::ids }; |} { return (list(`[enum $name $ids;], `[$(symbolconc(“print_”,name))(arg) { switch (arg) id; `{ case $id: printf(“%s”, $(pstring(id)));}), ids))})); } myenum fruit { apple, orange }; print_fruit(apple); syntax decl myenum[] {| $$id::name { $$+\,id::ids }; |} { return (list(`[enum $name $ids;], `[$(symbolconc(“print_”,name))(arg) { switch (arg) id; `{ case $id: printf(“%s”, $(pstring(id)));}), ids))})); } myenum fruit { apple, orange }; print_fruit(apple);

May 14, 2002 Macro Languages AoPL, S'02 8 Languages: { CPP, M4, T E X, Dylan, C++ Templates, Scheme, JTS, MS 2 } Macro Survey

May 14, 2002 Macro Languages AoPL, S'02 8 Languages: { CPP, M4, T E X, Dylan, C++ Templates, Scheme, JTS, MS 2 } 31 Properties: { Level of operation, body expansion, order of expansion, … } Macro Survey

May 14, 2002 Macro Languages AoPL, S'02 8 Languages: { CPP, M4, T E X, Dylan, C++ Templates, Scheme, JTS, MS 2 } 31 Properties: { Level of operation, body expansion, order of expansion, … } Macro Survey

May 14, 2002 Macro Languages AoPL, S'02 Declarative: Based entirely on simple concepts: grammars and substitution Safe: Guaranteed termination Only generate legal (and  -converted) syntax Flexible: All (55) nonterminals may be arg and return types Invocation syntax design (guides parsing)

May 14, 2002 Macro Languages AoPL, S'02 On all (55) Nonterminals : macro  pi ::= { }

May 14, 2002 Macro Languages AoPL, S'02 On all (55) Nonterminals : macro  pi ::= { } macro  maybe ::= { if (random(2)==0) } macro  maybe ::= { if (random(2)==0) }

May 14, 2002 Macro Languages AoPL, S'02 On all (55) Nonterminals : macro  pi ::= { } macro  maybe ::= { if (random(2)==0) } macro  maybe ::= { if (random(2)==0) } macro  plus ( ) ::= { concat(star( ), ) } macro  plus ( ) ::= { concat(star( ), ) }

May 14, 2002 Macro Languages AoPL, S'02 Example: repeat Invocation syntax design: Guides the parser macro  repeat until ( ) ; ::= { { while ( ) } macro  repeat until ( ) ; ::= { { while ( ) }

May 14, 2002 Macro Languages AoPL, S'02 Example: repeat Invocation syntax design: Guides the parser Code duplication: Worst-case: O(2 n ) macro  repeat until ( ) ; ::= { { while ( ) } macro  repeat until ( ) ; ::= { { while ( ) }

May 14, 2002 Macro Languages AoPL, S'02 Example: repeat macro  repeat until ( ) ; ::= { { bool first = true; while (first || ! ) { first = false; } macro  repeat until ( ) ; ::= { { bool first = true; while (first || ! ) { first = false; }

May 14, 2002 Macro Languages AoPL, S'02 Example: repeat  -Conversion: first => first_87 macro  repeat until ( ) ; ::= { { bool first = true; while (first || ! ) { first = false; } macro  repeat until ( ) ; ::= { { bool first = true; while (first || ! ) { first = false; }

May 14, 2002 Macro Languages AoPL, S'02 Multiple Definitions Macros with same name: si/si-sinon : Parsing: Which macro to select? macro  si ( ) ::= { if ( ) } macro  si ( ) sinon ::= { if ( ) else } macro  si ( ) ::= { if ( ) } macro  si ( ) sinon ::= { if ( ) else }

May 14, 2002 Macro Languages AoPL, S'02 Specificity Parsing macro  select from where macro  select all from where macro  select from where macro  select all from where

May 14, 2002 Macro Languages AoPL, S'02 Specificity Parsing Challenge rounds: –Select most specific productions (wrt. FIRST sets) Resolves many ambiguities Independent of definition-order Overloading Avoids keywordification Commit  no branch explosion, no backtracking macro  select from where macro  select all from where macro  select from where macro  select all from where

May 14, 2002 Macro Languages AoPL, S'02 Pretty Print and Error Reporting Pretty Printing: Terminal printers: ASCII, L A E X, HTML ( +/- expansion) T

May 14, 2002 Macro Languages AoPL, S'02 Pretty Print and Error Reporting Pretty Printing: Terminal printers: ASCII, L A E X, HTML ( +/- expansion) Error Reporting: stdout, HTML *** symbol errors: *** test.wig:7: Identifier ‘inf’ not declared in macro argument ‘S’ in macro invocation ‘reader’ (test.wig:7) defined in [std.wigmac:44] *** symbol errors: *** test.wig:7: Identifier ‘inf’ not declared in macro argument ‘S’ in macro invocation ‘reader’ (test.wig:7) defined in [std.wigmac:44] T

May 14, 2002 Macro Languages AoPL, S'02 Concurrency Stack

May 14, 2002 Macro Languages AoPL, S'02 Representation macro  M XY ( ) ::= { X,, Y } A, M XY (B, C), D  A, X, B, C, Y, D macro  M XY ( ) ::= { X,, Y } A, M XY (B, C), D  A, X, B, C, Y, D

May 14, 2002 Macro Languages AoPL, S'02 Representation macro  M XY ( ) ::= { X,, Y } A, M XY (B, C), D  A, X, B, C, Y, D macro  M XY ( ) ::= { X,, Y } A, M XY (B, C), D  A, X, B, C, Y, D

May 14, 2002 Macro Languages AoPL, S'02 Representation macro  M XY ( ) ::= { X,, Y } A, M XY (B, C), D  A, X, B, C, Y, D macro  M XY ( ) ::= { X,, Y } A, M XY (B, C), D  A, X, B, C, Y, D “Weaving” yields transparency! weave

May 14, 2002 Macro Languages AoPL, S'02 Metamorphic Syntax Macros

May 14, 2002 Macro Languages AoPL, S'02 Argument Structure Many variants of an abstraction? enum { zero }; enum { zero, one }; enum { zero, one, two }; … enum { zero }; enum { zero, one }; enum { zero, one, two }; …

May 14, 2002 Macro Languages AoPL, S'02 Argument Structure Many variants of an abstraction? –Syntax: Argument structure? –Transformation: Specification? enum { zero }; enum { zero, one }; enum { zero, one, two }; … enum { zero }; enum { zero, one }; enum { zero, one, two }; …

May 14, 2002 Macro Languages AoPL, S'02 Argument Structure Many variants of an abstraction? –Syntax: Argument structure? –Transformation: Specification? enum { zero }; enum { zero, one }; enum { zero, one, two }; … enum { zero }; enum { zero, one }; enum { zero, one, two }; … Safety?

May 14, 2002 Macro Languages AoPL, S'02 Multiple Definitions macro  enum { }; ::= { const int = 0; } macro  enum {, }; ::= { const int = 0; const int = 1; } macro  enum {,, }; ::= { const int = 0; const int = 1; const int = 2; } macro  enum { }; ::= { const int = 0; } macro  enum {, }; ::= { const int = 0; const int = 1; } macro  enum {,, }; ::= { const int = 0; const int = 1; const int = 2; }

May 14, 2002 Macro Languages AoPL, S'02 Multiple Definitions macro  enum { }; ::= {…} macro  enum {, }; ::= {…} macro  enum {,, }; ::= {…} macro  enum { }; ::= {…} macro  enum {, }; ::= {…} macro  enum {,, }; ::= {…}

May 14, 2002 Macro Languages AoPL, S'02 Multiple Definitions decls  enum { id } ;  enum { id, id } ;  enum { id, id, id } ; decls  enum { id } ;  enum { id, id } ;  enum { id, id, id } ; macro  enum { }; ::= {…} macro  enum {, }; ::= {…} macro  enum {,, }; ::= {…} macro  enum { }; ::= {…} macro  enum {, }; ::= {…} macro  enum {,, }; ::= {…} Corresponds to grammar extension:

May 14, 2002 Macro Languages AoPL, S'02 Multiple Definitions decls  enum { id } ;  enum { id, id } ;  enum { id, id, id } ; decls  enum { id } ;  enum { id, id } ;  enum { id, id, id } ; macro  enum { }; ::= {…} macro  enum {, }; ::= {…} macro  enum {,, }; ::= {…} macro  enum { }; ::= {…} macro  enum {, }; ::= {…} macro  enum {,, }; ::= {…} Corresponds to grammar extension: Three unrelated productions

May 14, 2002 Macro Languages AoPL, S'02 Multiple Definitions decls  enum { id } ;  enum { id, id } ;  enum { id, id, id } ; decls  enum { id } ;  enum { id, id } ;  enum { id, id, id } ; macro  enum { }; ::= {…} macro  enum {, }; ::= {…} macro  enum {,, }; ::= {…} macro  enum { }; ::= {…} macro  enum {, }; ::= {…} macro  enum {,, }; ::= {…} Corresponds to grammar extension: Problems: Only fixed (finite) extent Three unrelated productions

May 14, 2002 Macro Languages AoPL, S'02 Multiple Definitions decls  enum { id } ;  enum { id, id } ;  enum { id, id, id } ; decls  enum { id } ;  enum { id, id } ;  enum { id, id, id } ; macro  enum { }; ::= {…} macro  enum {, }; ::= {…} macro  enum {,, }; ::= {…} macro  enum { }; ::= {…} macro  enum {, }; ::= {…} macro  enum {,, }; ::= {…} Corresponds to grammar extension: Problems: Only fixed (finite) extent Highly redundant Three unrelated productions

May 14, 2002 Macro Languages AoPL, S'02 Lists Scheme: Special list constructor: “... ” decls  ( enum id * ) (define-syntax and (syntax-rules () ((and) #t) ((and b) b) ((and b...) (if b (and...) #f)))) (define-syntax and (syntax-rules () ((and) #t) ((and b) b) ((and b...) (if b (and...) #f)))) (enum x y z)

May 14, 2002 Macro Languages AoPL, S'02 e-BNF MS 2 : Regular expressions: –Optionals “ ? ”, lists “ +, * ”, tuples “ {…} ”, t -sep. lists “ \+t ” syntax decl myenum[] {| $$id::name { $$+\,id::ids }; |} { return (list(`[enum $name $ids;], `[$(symbolconc(“print_”,name))(arg) { switch (arg) id; `{ case $id: printf(“%s”, $(pstring(id)));}), ids))})); syntax decl myenum[] {| $$id::name { $$+\,id::ids }; |} { return (list(`[enum $name $ids;], `[$(symbolconc(“print_”,name))(arg) { switch (arg) id; `{ case $id: printf(“%s”, $(pstring(id)));}), ids))})); decls  enum { id , } ; myenum fruit { apple, orange }; print_fruit(apple);

May 14, 2002 Macro Languages AoPL, S'02 Grammar Dylan (and JSE, a Java adaptation): Describe argument syntax via user-defined nonterminals decls  enum { id enums } ; enums , id enums   decls  enum { id enums } ; enums , id enums  

May 14, 2002 Macro Languages AoPL, S'02 Grammar Dylan (and JSE, a Java adaptation): Describe argument syntax via user-defined nonterminals –Unsafe: Transformations return lexical token sequences Return user defined abstract syntax trees? decls  enum { id enums } ; enums , id enums   decls  enum { id enums } ; enums , id enums  

May 14, 2002 Macro Languages AoPL, S'02 Metamorphisms : Attach host nonterminals to user def’d nonterminals Specify morphing (into host syntax) inductively metamorph enums; macro  … … ::= { … … } morph  … ::= { … } metamorph enums; macro  … … ::= { … … } morph  … ::= { … } decls  enum { id enums } ; enums , id enums   decls  enum { id enums } ; enums , id enums  

May 14, 2002 Macro Languages AoPL, S'02 Example: enum Ideally: enum { a, b, c }; const int a = 0; const int b = 1; const int c = 2; const int a = 0; const int b = 1; const int c = 2; =>

May 14, 2002 Macro Languages AoPL, S'02 Example: enum Ideally: But requires compile-time evaluation: 0, 1, 2, … enum { a, b, c }; const int a = 0; const int b = 1; const int c = 2; const int a = 0; const int b = 1; const int c = 2; =>

May 14, 2002 Macro Languages AoPL, S'02 Example: enum Ideally: But requires compile-time evaluation: 0, 1, 2, … Instead generate: enum { a, b, c }; const int a = 0; const int b = 1; const int c = 2; const int a = 0; const int b = 1; const int c = 2; => enum { a, b, c }; const int e = 0; const int a = e++; const int b = e++; const int c = e++; const int e = 0; const int a = e++; const int b = e++; const int c = e++; =>

May 14, 2002 Macro Languages AoPL, S'02 Example: enum metamorph enums; decls  enum { id enums } ; enums , id enums   decls  enum { id enums } ; enums , id enums  

May 14, 2002 Macro Languages AoPL, S'02 Example: enum metamorph enums; macro  enum { } ; ::= { int e = 0; const int = e++; } metamorph enums; macro  enum { } ; ::= { int e = 0; const int = e++; } decls  enum { id enums } ; enums , id enums   decls  enum { id enums } ; enums , id enums  

May 14, 2002 Macro Languages AoPL, S'02 Example: enum metamorph enums; macro  enum { } ; ::= { int e = 0; const int = e++; } morph , ::= { const int = e++; } metamorph enums; macro  enum { } ; ::= { int e = 0; const int = e++; } morph , ::= { const int = e++; } decls  enum { id enums } ; enums , id enums   decls  enum { id enums } ; enums , id enums  

May 14, 2002 Macro Languages AoPL, S'02 Example: enum metamorph enums; macro  enum { } ; ::= { int e = 0; const int = e++; } morph , ::= { const int = e++; } morph  ::= { } metamorph enums; macro  enum { } ; ::= { int e = 0; const int = e++; } morph , ::= { const int = e++; } morph  ::= { } decls  enum { id enums } ; enums , id enums   decls  enum { id enums } ; enums , id enums  

May 14, 2002 Macro Languages AoPL, S'02 Guaranteed Termination Termination proof: Transition system + termination function  0   1   2  …  (  0 ) >  (  1 ) >  (  2 ) > …  0   1   2  …  (  0 ) >  (  1 ) >  (  2 ) > …

May 14, 2002 Macro Languages AoPL, S'02 Guaranteed Termination Termination proof: Transition system + termination function –States: ( ,  ) –   (T  N)* sentential form –   T* input string  0   1   2  …  (  0 ) >  (  1 ) >  (  2 ) > …  0   1   2  …  (  0 ) >  (  1 ) >  (  2 ) > …

May 14, 2002 Macro Languages AoPL, S'02 Guaranteed Termination Termination proof: Transition system + termination function –States: ( ,  ) –   (T  N)* sentential form –   T* input string –Transitions: –(t , t  )  ( ,  ) –(N ,  )  (  ,  ), if N    0   1   2  …  (  0 ) >  (  1 ) >  (  2 ) > …  0   1   2  …  (  0 ) >  (  1 ) >  (  2 ) > …

May 14, 2002 Macro Languages AoPL, S'02 Guaranteed Termination Termination proof: Transition system + termination function –Termination function:  ( ,  ) =  0   1   2  …  (  0 ) >  (  1 ) >  (  2 ) > …  0   1   2  …  (  0 ) >  (  1 ) >  (  2 ) > …

May 14, 2002 Macro Languages AoPL, S'02 Guaranteed Termination Termination proof: Transition system + termination function –Termination function:  ( ,  ) =  0   1   2  …  (  0 ) >  (  1 ) >  (  2 ) > …  0   1   2  …  (  0 ) >  (  1 ) >  (  2 ) > …

May 14, 2002 Macro Languages AoPL, S'02 Guaranteed Termination Termination proof: Transition system + termination function –Termination function:  ( ,  ) = –|| t  || = 0  0   1   2  …  (  0 ) >  (  1 ) >  (  2 ) > …  0   1   2  …  (  0 ) >  (  1 ) >  (  2 ) > …

May 14, 2002 Macro Languages AoPL, S'02 Guaranteed Termination Termination proof: Transition system + termination function –Termination function:  ( ,  ) = –|| t  || = 0 –|| N 0  || = k+1  0   1   2  …  (  0 ) >  (  1 ) >  (  2 ) > …  0   1   2  …  (  0 ) >  (  1 ) >  (  2 ) > … N 0  N 1  1  N 2  2  1  …  N k  k …  1 longest

May 14, 2002 Macro Languages AoPL, S'02 Guaranteed Termination Termination proof: Transition system + termination function –Termination function:  ( ,  ) = lexicographically ordered –|| t  || = 0 –|| N 0  || = k+1  0   1   2  …  (  0 ) >  (  1 ) >  (  2 ) > …  0   1   2  …  (  0 ) >  (  1 ) >  (  2 ) > … N 0  N 1  1  N 2  2  1  …  N k  k …  1 longest

May 14, 2002 Macro Languages AoPL, S'02 Metamorph Wellformedness Check at definition time: No left-recursion –guarantees parser termination:  xlist  xlist X   xlist  xlist X   xlist  X xlist   xlist  X xlist  

May 14, 2002 Macro Languages AoPL, S'02 Metamorph Wellformedness Check at definition time: No left-recursion –guarantees parser termination:  Derivability –metamorphisms must derive something finite :  xlist  xlist X   xlist  xlist X   xlist  X xlist   xlist  X xlist   xlist  X xlist   xlist  X xlist   xlist  X xlist

May 14, 2002 Macro Languages AoPL, S'02 Example: switch metamorph swb; metamorph swb; stm  switch ( exp ) { swb } swb  case exp : stms break; swb  case exp : stms break; stm  switch ( exp ) { swb } swb  case exp : stms break; swb  case exp : stms break;

May 14, 2002 Macro Languages AoPL, S'02 Example: switch metamorph swb; macro  switch ( ) { } ::= { { var x = ; } metamorph swb; macro  switch ( ) { } ::= { { var x = ; } stm  switch ( exp ) { swb } swb  case exp : stms break; swb  case exp : stms break; stm  switch ( exp ) { swb } swb  case exp : stms break; swb  case exp : stms break;

May 14, 2002 Macro Languages AoPL, S'02 Example: switch metamorph swb; macro  switch ( ) { } ::= { { var x = ; } morph  case : break; ::= { if (x == ) { } else } metamorph swb; macro  switch ( ) { } ::= { { var x = ; } morph  case : break; ::= { if (x == ) { } else } stm  switch ( exp ) { swb } swb  case exp : stms break; swb  case exp : stms break; stm  switch ( exp ) { swb } swb  case exp : stms break; swb  case exp : stms break;

May 14, 2002 Macro Languages AoPL, S'02 Example: switch metamorph swb; macro  switch ( ) { } ::= { { var x = ; } morph  case : break; ::= { if (x == ) { } else } morph  case : break; ::= { if (x == ) { } } metamorph swb; macro  switch ( ) { } ::= { { var x = ; } morph  case : break; ::= { if (x == ) { } else } morph  case : break; ::= { if (x == ) { } } stm  switch ( exp ) { swb } swb  case exp : stms break; swb  case exp : stms break; stm  switch ( exp ) { swb } swb  case exp : stms break; swb  case exp : stms break;

May 14, 2002 Macro Languages AoPL, S'02 Example: reserve => stm  reserve ( res ) stm res  id res   stm  reserve ( res ) stm res  id res   reserve ( a b c )...; acquire(a); acquire(b); acquire(c);...; release(c); release(b); release(a); acquire(a); acquire(b); acquire(c);...; release(c); release(b); release(a);

May 14, 2002 Macro Languages AoPL, S'02 Example: reserve Requires non-local transformations e.g. “ b ” must generate both “ acquire(b) ” and “ release(b) ” at different locations => stm  reserve ( res ) stm res  id res   stm  reserve ( res ) stm res  id res   reserve ( a b c )...; acquire(a); acquire(b); acquire(c);...; release(c); release(b); release(a); acquire(a); acquire(b); acquire(c);...; release(c); release(b); release(a);

May 14, 2002 Macro Languages AoPL, S'02 Multiple Results Extend metamorphisms: Attach host nonterminals to user def’d nonterminals metamorph res; macro  … … ::= { … … … } morph  … ::= { … } { … } metamorph res; macro  … … ::= { … … … } morph  … ::= { … } { … } stm  reserve ( res ) stm res  id res   stm  reserve ( res ) stm res  id res  

May 14, 2002 Macro Languages AoPL, S'02 Example: reserve metamorph res; macro  reserve ( ) ::= { { } } morph  ::= { acquire( ); } { release( ); } morph  ::= { } { } metamorph res; macro  reserve ( ) ::= { { } } morph  ::= { acquire( ); } { release( ); } morph  ::= { } { } stm  reserve ( res ) stm res  id res   stm  reserve ( res ) stm res  id res  

May 14, 2002 Macro Languages AoPL, S'02 Example: enum (cont’d) enum { a, b, c }; const int e = 0; const int a = e++; const int b = e++; const int c = e++; const int e = 0; const int a = e++; const int b = e++; const int c = e++; =>

May 14, 2002 Macro Languages AoPL, S'02 Example: enum (cont’d) Suppose no initialization expressions Instead generate: –CPS Style: Send initialization expression to metamorphism enum { a, b, c }; const int e = 0; const int a = e++; const int b = e++; const int c = e++; const int e = 0; const int a = e++; const int b = e++; const int c = e++; => enum { a, b, c }; const int a = 0; const int b = 1; const int c = 1+1; const int a = 0; const int b = 1; const int c = 1+1; =>

May 14, 2002 Macro Languages AoPL, S'02 Metamorph Arguments metamorph enums( ); macro  enum { ({1}) }; … { const int = 0; } morph , ({ +1}) ::= { const int = ; } morph  ::= { } metamorph enums( ); macro  enum { ({1}) }; … { const int = 0; } morph , ({ +1}) ::= { const int = ; } morph  ::= { } decls  enum { id enums } ; enums , id enums   decls  enum { id enums } ; enums , id enums  

May 14, 2002 Macro Languages AoPL, S'02 Metamorph Arguments metamorph enums( ); macro  enum { ({1}) }; … { const int = 0; } morph , ({ +1}) ::= { const int = ; } morph  ::= { } metamorph enums( ); macro  enum { ({1}) }; … { const int = 0; } morph , ({ +1}) ::= { const int = ; } morph  ::= { } decls  enum { id enums } ; enums , id enums   decls  enum { id enums } ; enums , id enums   enum {…x…}; => … const int x = ; …

May 14, 2002 Macro Languages AoPL, S'02 Metamorph Advantages Flexibility: Tree structures Non-local transformations (multiple results) Safety: No parse errors as a conseq. of macro expansion Guaranteed termination Simplicity: Based entirely on declarative concepts: grammars and substitution

May 14, 2002 Macro Languages AoPL, S'02 vDSL: very Domain-Specific Language studies course Math101 title “Mathematics 101” 2 point fall term … exclusions Math101 <> MathA Math102 <> MathB prerequisites Math101, Math102 < Math201, Math202, Math203 Math101, CS101 < CS202 studies course Math101 title “Mathematics 101” 2 point fall term … exclusions Math101 <> MathA Math102 <> MathB prerequisites Math101, Math102 < Math201, Math202, Math203 Math101, CS101 < CS202

May 14, 2002 Macro Languages AoPL, S'02 FIN

May 14, 2002 Macro Languages AoPL, S'02 Next Week: metafront Macros are just a special case usage: A is an extension of B: m: L+ => L Make sure only need to write delta:  = L+ \ L metafront x: A => B AB program.a program.b transformation input language input program(s)output program(s) output language