Download presentation
Presentation is loading. Please wait.
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
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.