9/16/14

CS152 – Advanced Principles Prof. Tom Austin, Fall 2014 For next class, install LaTeX Macros (pronounced "LAH-tech")

What is a ? Types of macros • Short for macroinstruction. • A rule or pattern that specifies how a Text substitution certain input sequence should be mapped to a replacement sequence. Procedural macros Syntactic macros

Text Substitution Macros A Review of Compilers

This type of macro works by expanding text. Fast, but limited power. Some examples: source Lexer/ tokens Parser code Tokenizer • • Embedded languages (PHP, Ruby's erb, etc.) Abstract are similar, but more powerful Compiler Interpreter Syntax Tree (AST)

Machine code Commands

1 9/16/14

Some variants work at the token level, but the C preprocessor example concept is the same. #define PI 3.14159 expanded source Pre- code Lexer/ tokens code Parser processor Tokenizer #define SWAP(a,b) {int tmp=a;a=b;b=tmp;}

int main(void) { Abstract Compiler Interpreter int x=4, y=5, diam=7, circum=diam*PI; Syntax Tree SWAP(x,y); (AST) } Machine code Commands

int main(void) { Procedural macros int x=4, y=5, diam=7, circum=diam*PI; SWAP(x,y); Preprocessor Procedural macros execute preprocessor } statements at compilation time. • Allows macros to be written in a procedural language. int main(void) { int x=4, y=5, diam=7, • More powerful than text substitution… circum=diam*3.14159; • …but slower and more complex compiler. {int tmp=x;x=y;y=tmp;}; }

Syntactic macros Macro expansion process

• Work at the level of abstract syntax trees Abstract Abstract Macro • From the Lisp family (including Scheme) Syntax Tree Syntax Tree Expander – Why Lisp? Because Lisp programs are ASTs (AST) (AST) • Powerful, but expensive

• Where our attention will be focused Essentially this is a source-to-source compiler

2 9/16/14

Many macro systems suffer from a problem with inadvertent variable capture. Accidental Capture Example (in class) Let's look at an example…

Hygiene Macros in Scheme

Hygienic macros are macros whose • Scheme is noted for its powerful (and expansion is guaranteed not to cause hygienic) macro system. the accidental capture of identifiers. • Is it needed? Aren't lambdas enough?

Pattern Based Macros (define (swap x y) (let ([tmp x]) • Preserves hygiene (set! x y) • define-syntax-rule matches the given pattern and transforms is into the specified (set! y tmp))) template (let ([tmp 7][b 3]) • define-syntax is allows you to specify multiple patters, including those with a (swap tmp b) What is the result? variable number of arguments (using the … (cons tmp b)) syntax)

3 9/16/14

(define-syntax-rule Define-syntax swap function (swap x y) (let ([tmp x]) (define-syntax swap (set! x y) (syntax-rules () (set! y tmp))) [(swap x y) (let ([tmp x]) (let ([tmp 7][b 3]) (set! x y) (swap tmp b) What is the result (set! y tmp))])) now? (cons tmp b))

Lab For more reading on macros: • Matthew Flatt, "Pattern-based macros", section Using define-syntax, create a switch statement. 16.1 of "The Racket Guide". Sample usage: http://docs.racket-lang.org/guide/pattern- (define x 99) macros.html (switch x • [3 (displayln "x is 3")] Greg Hendershott, "Fear of Macros". http://www.greghendershott.com/fear-of- [4 (displayln "x is 4")] macros/index.html [5 (displayln "x is 5")] ['default (displayln "none of the above")])

4