adapting scheme like macros to a c like language
play

Adapting Scheme-Like Macros to a C-Like Language Kevin Atkinson, - PowerPoint PPT Presentation

Adapting Scheme-Like Macros to a C-Like Language Kevin Atkinson, Matthew Flatt University of Utah 1 ZL Adopts a Scheme-like approach to build C++ from a C like core Why C? The system's programming language Want to make life


  1. Adapting Scheme-Like Macros to a C-Like Language Kevin Atkinson, Matthew Flatt University of Utah 1

  2. ZL ● Adopts a Scheme-like approach to build C++ from a C like core ● Why C? ● The system's programming language ● Want to make life better in that world 2

  3. Challenges 1.Parsing C Idiosyncratic Syntax While Also Allowing The Syntax to be Extensible 2.Finding Right Hygiene Model 3.Finding Right Reflective Operations 3

  4. How to Parse This Expression? f(x/2, y) Function Call? Macro Invocation? x/2 + y ? f(x/2, y) ? int y = x/2 4

  5. Parsing Overview ● ZL doesn't parse in a single linear pass ● Iterative-deepening approach Syntax Syntax Parse Partly Expand Object Object Raw Text Raw Text Raw Text e s r a p e R Compile AST Node Raw Text 5

  6. Parsing "inline int f() {int x = 10; return x;} int main() {return f();}" Details Parse (@ (stmt inline int f ('()' "") ('{}' "int x = 10; return x;") (stmt int main ('()' "") ('{}' "return f();"))) Expand & Compile Top-Level Environment (stmt inline int f ...) ... (stmt int main ...) ... 6

  7. Top-Level Environment (stmt inline int f ...) ... Expand (fun f (.) (int) :inline ('{}' "int x = 10; return x;")) Compile Function ('{}' "int x = 10; return x;") ... (stmt int main ...) ... 7

  8. Function ('{}' "int x = 10; return x;") ... Expand & Reparse (block (stmt int x = 10) (return (exp x))) Compile Block (stmt int x = 10)) ... (return (exp x)) ... 8

  9. Pattern Macros macro or( x , y ) { ({typeof( x ) t = x ; t ? t : y ;}); } ({typeof(0.0) t 0 = 0.0; t 0 ? t 0 : t;}); or(0.0,t) 9

  10. Syntax Macros Add to PEG Grammer: <foreach> "foreach" "(" {ID} "in" {EXP} ")" {STMT} In Source Code: smacro foreach (id, container, body) {...} "foreach (x in con) printf("%d\n", x);" Parse (foreach x con ('{}' "printf("%d\n", x);")) Expand 10

  11. Procedural Macros Syntax * or(Syntax * syn, Environ *) { Match * m = match(NULL, syntax (_, x, y), syn); return replace(syntax {({typeof(x) t = x; t ? t : y;});}, m, new_mark()); } make_macro or; Syntax Forms: syntax Callbacks: match make_macro replace new_mark error 11

  12. Procedural Macro Example float pi = 3.14159; Syntax * area_circle(Syntax * syn, Environ *) { Mark * mark = new_mark(); Match * m = match(NULL, syntax (_, R ), syn); UnmarkedSyntax * r = syntax { ({float r = R ; pi*r*r;}); }; return replace (r, m, mark); } make_macro area_circle; int main() { float pi = 3.14; float r = 10; ... area_circle(r) ... } 12

  13. Expansion of area_circle(r) float pi = 3.14159; Syntax * area_circle(Syntax * syn, Environ *) { Mark * mark = new_mark(); ('0, ) pi => ... Match * m = match(NULL, syntax (_, R ), syn); UnmarkedSyntax * r = syntax { ({float r = R ; pi*r*r;}); }; return replace (r, m, mark); } make_macro area_circle; int main() { ... ... area_circle(r) ... } 13

  14. Expansion of area_circle(r) float pi = 3.14159; Syntax * area_circle(Syntax * syn, Environ *) { Mark * mark = pi => ... ('0, ) Match * m = match(NULL, syntax (_, R ), syn); [ R => r] UnmarkedSyntax * r = syntax { ({float r = R ; pi*r*r;}); }; return replace (r, m, mark); } make_macro area_circle; int main() { ... ... area_circle(r) ... } 14

  15. Expansion of area_circle(r) float pi = 3.14159; Syntax * area_circle(Syntax * syn, Environ *) { Mark * mark = pi => ... ('0, ) Match * m = [ R => r] UnmarkedSyntax * r = syntax { ({float r = R ; pi*r*r;}); }; return replace (r, m, mark); } make_macro area_circle; int main() { ... area_circle(r) ... } 15

  16. Expansion of area_circle(r) float pi = 3.14159; Syntax * area_circle(Syntax * syn, Environ *) { Mark * mark = pi => ... ('0, ) Match * m = [ R => r] UnmarkedSyntax * r = syntax { ({float r = R ; pi*r*r;}); }; return replace (r, m, mark); (syntax { ({float r = R ; pi*r*r;}); }, [ R => r], ); pi => ... ('0, ) } make_macro area_circle; int main() { ... area_circle(r) ... } 16

  17. Expansion of area_circle(r) float pi = 3.14159; Syntax * area_circle(Syntax * syn, Environ *) { ... return replace (syntax { ({float r = R ; pi*r*r;}); }, [ R => r], ); pi => ... ('0, ) } make_macro area_circle; int main() { ... ... area_circle(r) ... ... ({ float r'0 = r; pi'0 * r'0 * r'0; }) ... } 17

  18. Hygiene System float pi = 3.14159; Syntax * area_circle(Syntax * syn, Environ *) { Mark * mark = new_mark(); Match * m = match(NULL, syntax (_, R ), syn); UnmarkedSyntax * r = syntax { ({float r = R ; pi*r*r;}); }; return replace (r, m, mark); } make_macro area_circle; int main() { float pi = 3.14; ({float r = r; pi * r * r;}) float r = 10; ... area_circle(r) ... } 18

  19. float pi $pi0 = 3.14159; pi => $pi0 19

  20. float pi $pi0 = 3.14159; pi => $pi0 Syntax * area_circle(Syntax * syn, Environ *) { Mark * mark = new_mark(); ... } make_macro area_circle; 20

  21. float pi $pi0 = 3.14159; pi => $pi0 Syntax * area_circle(Syntax * syn, Environ *) {...} int main() { float pi $pi1 = 3.14; float r $r0 = 10; r => $r0, pi => $pi1, area_circle => ... ... area_circle(r) ... } 21

  22. float pi $pi0 = 3.14159; pi => $pi0 Syntax * area_circle(Syntax * syn, Environ *) {...} int main() { float pi $pi1 = 3.14; float r $r0 = 10; r => $r0, pi => $pi1, area_circle => ... ... area_circle(r) ... ... ({ float r'0 = r; pi'0 * r'0 * r'0; }) ... } '0 => pi => $pi0 22

  23. float pi $pi0 = 3.14159; pi => $pi0 pi => $pi0 Syntax * area_circle(Syntax * syn, Environ *) {...} int main() { float pi $pi1 = 3.14; float r $r0 = 10; r'0 => $r1, r => $r0, pi => $pi1, area_circle => ... ... area_circle(r) ... ... ({ float r'0 $r1 = r; pi'0 * r'0 * r'0; }) ... } Mark Becomes Part of The Name '0 => pi => $pi0 23

  24. float pi $pi0 = 3.14159; pi => $pi0 pi => $pi0 Syntax * area_circle(Syntax * syn, Environ *) {...} int main() { float pi $pi1 = 3.14; float r $r0 = 10; r'0 => $r1, r => $r0, pi => $pi1, area_circle => ... ... area_circle(r) ... ... ({ float r'0 $r1 = r $r0; pi'0 * r'0 * r'0; }) ... } '0 => pi => $pi0 24

  25. float pi $pi0 = 3.14159; pi => $pi0 pi => $pi0 Syntax * area_circle(Syntax * syn, Environ *) {...} int main() { float pi $pi1 = 3.14; float r $r0 = 10; r'0 => $r1, r => $r0, pi => $pi1, area_circle => ... ... area_circle(r) ... ... ({ float r'0 $r1 = r $r0; pi'0 * r'0 * r'0; }) ... } Look Inside the Mark '0 => pi => $pi0 25

  26. float pi $pi0 = 3.14159; pi => $pi0 pi => $pi0 Syntax * area_circle(Syntax * syn, Environ *) {...} int main() { float pi $pi1 = 3.14; float r $r0 = 10; r'0 => $r1, r => $r0, pi => $pi1, area_circle => ... ... area_circle(r) ... ... ({ float r'0 $r1 = r $r0; pi'0 $pi0 * r'0 * r'0; }) ... } Strip Mark pi '0 => pi => $pi0 26

  27. float pi $pi0 = 3.14159; pi => $pi0 pi => $pi0 Syntax * area_circle(Syntax * syn, Environ *) {...} int main() { float pi $pi1 = 3.14; float r $r0 = 10; r'0 => $r1, r => $r0, pi => $pi1, area_circle => ... ... area_circle(r) ... ... ({ float r'0 $r1 = r $r0; pi'0 $pi0 * r'0 $r1 * r'0 $r1; })... } '0 => pi => $pi0 27

  28. float $pi0 = 3.14159; ... int main() { float $pi1 = 3.14; float $r0 = 10; ... ({ float $r1 = $r0; $pi0 * $r1 * $r1; }) ... } Everything Resolves Correctly 28

  29. Bending Hygiene: Replace Context ● datum->syntax-object => ● Contex * get_context(Syntax *) ● Syntax * replace_context (UnmarkedSyntax *, Context *) 29

  30. Bending Hygiene: Fluid Binding ● define-syntax-parameter => fluid_binding ● syntax-parameterize => fluid fluid_binding this; macro m() {f(this);} int main() {X * fluid this = ...; return m();} 30

  31. Other API Functions Syntax * foreach (Syntax * syn, Environ * env) { Syntax * con = ...; if (!symbol_exists(syntax begin, con, mark, env) || ... return error(con, "Container lacks proper method."); ... } make_syntax_macro foreach; int main() { ... foreach(x in container) {printf("%d\n", x);}); ... } ● Additional API Functions and Examples in Paper 31

  32. Results ● Used ZL to Mitigate Problems of: ● Adding and Removing C++ fields and methods ● Incomparable ABI's Due to Compiler Changes (See GPCE'10 Paper) ● Compile Time Only 2-3 slower than G++ ● No Impact on Run-time Performance 32

  33. Conclusion ● Presented Macro System that: ● Handle C’s rich syntax ● Preserves Lexical Scope ● Offers power of Scheme's syntax-case ● Parts of ZL Also Presented in GPCE'10: ABI Compatibility Through a Customizable Language ● Additional Parts Presented in my Dissertation ● Implementation Available: http://www.cs.utah.edu/~kevina/zl 33

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend