Presentation is loading. Please wait.

Presentation is loading. Please wait.

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

Similar presentations


Presentation on theme: "May 14, 2002 Macro Languages AoPL, S'02 Macro Languages Claus Brabrand Michael I. Schwartzbach BRICS, University of Aarhus, Denmark."— Presentation transcript:

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

2 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

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

4 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”

5 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.

6 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

7 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.

8 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); }

9 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); }

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

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

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

13 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

14 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)

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

16 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

17 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

18 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

19 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

20 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

21 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

22 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

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

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

25 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( ) ~

26 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( ) => ~

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

28 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)

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

30 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;

31 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’

32 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’

33 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;

34 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;

35 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 => ???

36 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

37 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

38 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

39 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) => ???

40 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’

41 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

42 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

43 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

44 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

45 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

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

47 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!

48 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!

49 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

50 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

51 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, …

52 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) ’ )

53 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)

54 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)

55 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

56 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 }

57 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]

58 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})$

59 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 )

60 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 )

61 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))

62 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))

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

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

65 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

66 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 { … }

67 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

68 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

69 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

70 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)))))))))))))))))) :)

71 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...)

72 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...)

73 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...)

74 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))))

75 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)))) )

76 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) )

77 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) )

78 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 )

79 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) )

80 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) )

81 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 )

82 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 1 2 3 4)))) (m) => // *** parse error: too many arg’s to if (define-syntax m (syntax-rules () ((m) (if 1 2 3 4)))) (m) => // *** parse error: too many arg’s to if

83 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 1 2 3 4)))) (m) => // *** parse error: too many arg’s to if (define-syntax m (syntax-rules () ((m) (if 1 2 3 4)))) (m) => // *** parse error: too many arg’s to if

84 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 1 2 3 4)))) (m) => // *** parse error: too many arg’s to if (define-syntax m (syntax-rules () ((m) (if 1 2 3 4)))) (m) => // *** parse error: too many arg’s to if

85 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

86 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

87 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);

88 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);

89 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) $(map((| @id 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) $(map((| @id id; `{ case $id: printf(“%s”, $(pstring(id)));}), ids))})); }

90 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) $(map((| @id 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) $(map((| @id id; `{ case $id: printf(“%s”, $(pstring(id)));}), ids))})); } myenum fruit { apple, orange }; print_fruit(apple);

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

92 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

93 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

94 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)

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

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

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

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

99 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 ( ) }

100 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; }

101 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; }

102 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 }

103 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

104 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

105 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

106 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

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

108 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

109 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

110 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

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

112 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 }; …

113 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 }; …

114 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?

115 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; }

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

117 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:

118 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

119 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

120 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

121 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)

122 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) $(map((| @id 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) $(map((| @id id; `{ case $id: printf(“%s”, $(pstring(id)));}), ids))})); decls  enum { id , } ; myenum fruit { apple, orange }; print_fruit(apple);

123 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  

124 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  

125 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  

126 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; =>

127 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; =>

128 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++; =>

129 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  

130 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  

131 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  

132 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  

133 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 ) > …

134 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 ) > …

135 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 ) > …

136 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 ) > …

137 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 ) > …

138 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 ) > …

139 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

140 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

141 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  

142 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

143 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;

144 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;

145 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;

146 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;

147 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);

148 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);

149 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  

150 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  

151 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++; =>

152 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; =>

153 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  

154 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 = 1+1+1+1; …

155 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

156 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

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

158 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


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

Similar presentations


Ads by Google