+ All Categories
Home > Documents > Macros & Sweet · 2017. 11. 13. · •Text substitution macros –text is converted to text....

Macros & Sweet · 2017. 11. 13. · •Text substitution macros –text is converted to text....

Date post: 31-Jul-2021
Category:
Upload: others
View: 6 times
Download: 0 times
Share this document with a friend
37
CS 252: Advanced Programming Language Principles Prof. Tom Austin San José State University Macros & Sweet.js
Transcript
Page 1: Macros & Sweet · 2017. 11. 13. · •Text substitution macros –text is converted to text. •Embedded languages are similar –PHP, Ruby's erb, etc. Lexer/ Tokenizer Parser source

CS 252:Advanced Programming Language Principles

Prof. Tom AustinSan José State University

Macros & Sweet.js

Page 2: Macros & Sweet · 2017. 11. 13. · •Text substitution macros –text is converted to text. •Embedded languages are similar –PHP, Ruby's erb, etc. Lexer/ Tokenizer Parser source

Let's say we want to add classes to JavaScript…

Page 3: Macros & Sweet · 2017. 11. 13. · •Text substitution macros –text is converted to text. •Embedded languages are similar –PHP, Ruby's erb, etc. Lexer/ Tokenizer Parser source

We'd like to have something like:

class Person {constructor(name) {

this.name = name;}

say(msg) {console.log(this.name +

" says: " + msg);}

}

Page 4: Macros & Sweet · 2017. 11. 13. · •Text substitution macros –text is converted to text. •Embedded languages are similar –PHP, Ruby's erb, etc. Lexer/ Tokenizer Parser source

But what we have to type is:

function Person(name) {

this.name = name;}

Person.prototype.say = function(msg) {

console.log(this.name +

" says: " + msg);}

Page 5: Macros & Sweet · 2017. 11. 13. · •Text substitution macros –text is converted to text. •Embedded languages are similar –PHP, Ruby's erb, etc. Lexer/ Tokenizer Parser source

We want to expand our code with classes to a version of JavaScript understood by the interpreter.

Introducing macros…

Page 6: Macros & Sweet · 2017. 11. 13. · •Text substitution macros –text is converted to text. •Embedded languages are similar –PHP, Ruby's erb, etc. Lexer/ Tokenizer Parser source

What is a macro?

• Short for macroinstruction.• Rule specifies how input sequence

maps to a replacement sequence.

Page 7: Macros & Sweet · 2017. 11. 13. · •Text substitution macros –text is converted to text. •Embedded languages are similar –PHP, Ruby's erb, etc. Lexer/ Tokenizer Parser source

A Review of Compilers

Lexer/ Tokenizer

Parsersource code

tokens

AbstractSyntax Tree

(AST)

Compiler

Machine code

Interpreter

Commands

Page 8: Macros & Sweet · 2017. 11. 13. · •Text substitution macros –text is converted to text. •Embedded languages are similar –PHP, Ruby's erb, etc. Lexer/ Tokenizer Parser source

Macros in C

• C preprocessor• Text substitution macros–text is converted to text.

• Embedded languages are similar– PHP, Ruby's erb, etc.

Page 9: Macros & Sweet · 2017. 11. 13. · •Text substitution macros –text is converted to text. •Embedded languages are similar –PHP, Ruby's erb, etc. Lexer/ Tokenizer Parser source

Lexer/Tokenizer Parsersource

codetokens

AbstractSyntax Tree

(AST)

Compiler

Machine code

Interpreter

Commands

Pre-processor

expandedcode

Some variants work at the token level, but the

concept is the same.

Page 10: Macros & Sweet · 2017. 11. 13. · •Text substitution macros –text is converted to text. •Embedded languages are similar –PHP, Ruby's erb, etc. Lexer/ Tokenizer Parser source

C preprocessor example#define PI 3.14159

#define SWAP(a,b) {int tmp=a;a=b;b=tmp;}

int main(void) {

int x=4, y=5, diam=7, circum=diam*PI;

SWAP(x,y);

}

Page 11: Macros & Sweet · 2017. 11. 13. · •Text substitution macros –text is converted to text. •Embedded languages are similar –PHP, Ruby's erb, etc. Lexer/ Tokenizer Parser source

int main(void) {

int x=4, y=5, diam=7, circum=diam*PI;

SWAP(x,y);

}

int main(void) {

int x=4, y=5, diam=7,

circum=diam*3.14159;

{int tmp=x;x=y;y=tmp;};

}

Page 12: Macros & Sweet · 2017. 11. 13. · •Text substitution macros –text is converted to text. •Embedded languages are similar –PHP, Ruby's erb, etc. Lexer/ Tokenizer Parser source

Problems with C macros(in class)

Page 13: Macros & Sweet · 2017. 11. 13. · •Text substitution macros –text is converted to text. •Embedded languages are similar –PHP, Ruby's erb, etc. Lexer/ Tokenizer Parser source

Many macro systems suffer frominadvertent variable capture.

Let's look at an example…

Page 14: Macros & Sweet · 2017. 11. 13. · •Text substitution macros –text is converted to text. •Embedded languages are similar –PHP, Ruby's erb, etc. Lexer/ Tokenizer Parser source

Hygiene

Hygienic macros are macros whose expansion is guaranteed not to cause the accidental capture of identifiers.

Page 15: Macros & Sweet · 2017. 11. 13. · •Text substitution macros –text is converted to text. •Embedded languages are similar –PHP, Ruby's erb, etc. Lexer/ Tokenizer Parser source

//macro should be on one line

#define SWAP(a,b) { int tmp=a;

a=b; b=tmp; }int main(void) {

int x=4, y=5, tmp=7;

SWAP(x,y); // Swaps x&y

SWAP(x,tmp); // tmp unchanged

}Why?

Page 16: Macros & Sweet · 2017. 11. 13. · •Text substitution macros –text is converted to text. •Embedded languages are similar –PHP, Ruby's erb, etc. Lexer/ Tokenizer Parser source

Syntactic macros

• Work at the level of abstract syntax trees• From the Lisp family–Why Lisp? Because Lisp programs are

ASTs• Powerful, but expensive• Hygiene is still a major concern, but is

perhaps easier to address at that level

Page 17: Macros & Sweet · 2017. 11. 13. · •Text substitution macros –text is converted to text. •Embedded languages are similar –PHP, Ruby's erb, etc. Lexer/ Tokenizer Parser source

Macro expansion process

AbstractSyntax Tree

(AST)

AbstractSyntax Tree

(AST)Macro

Expander

Essentially this is a source-to-source

compiler

Page 18: Macros & Sweet · 2017. 11. 13. · •Text substitution macros –text is converted to text. •Embedded languages are similar –PHP, Ruby's erb, etc. Lexer/ Tokenizer Parser source

(define-syntax-rule (swap x y)

(let ([tmp x])(set! x y)

(set! y tmp)))

Macros in Racket

Page 19: Macros & Sweet · 2017. 11. 13. · •Text substitution macros –text is converted to text. •Embedded languages are similar –PHP, Ruby's erb, etc. Lexer/ Tokenizer Parser source

(define-syntax-rule (swap x y)(let ([tmp x])(set! x y)

(set! y tmp)))

Macros in Racket

Pattern

Page 20: Macros & Sweet · 2017. 11. 13. · •Text substitution macros –text is converted to text. •Embedded languages are similar –PHP, Ruby's erb, etc. Lexer/ Tokenizer Parser source

(define-syntax-rule (swap x y)

(let ([tmp x])(set! x y)(set! y tmp)))

Macros in Racket

Template

Page 21: Macros & Sweet · 2017. 11. 13. · •Text substitution macros –text is converted to text. •Embedded languages are similar –PHP, Ruby's erb, etc. Lexer/ Tokenizer Parser source

(define-syntax-rule (swap x y)

(let ([tmp x])(set! x y)

(set! y tmp)))

(let ([a 7][b 3])

(swap a b)(displayln a)(displayln b))

Macros in Racket

Page 22: Macros & Sweet · 2017. 11. 13. · •Text substitution macros –text is converted to text. •Embedded languages are similar –PHP, Ruby's erb, etc. Lexer/ Tokenizer Parser source

(define-syntax-rule (swap x y)

(let ([tmp x])(set! x y)

(set! y tmp)))

(let ([a 7][b 3])

(let ([tmp a])(set! a b)(set! b tmp))

(displayln a)

(displayln b))

Expanded code

Page 23: Macros & Sweet · 2017. 11. 13. · •Text substitution macros –text is converted to text. •Embedded languages are similar –PHP, Ruby's erb, etc. Lexer/ Tokenizer Parser source

Macros for JavaScript

• No standard macrosystem for JavaScript.

• Sweet.js has beengaining interest.

• Recent redesign.• http://sweetjs.org/• https://www.sweetjs.org/doc/tutorial.html

Page 24: Macros & Sweet · 2017. 11. 13. · •Text substitution macros –text is converted to text. •Embedded languages are similar –PHP, Ruby's erb, etc. Lexer/ Tokenizer Parser source

Sweet.js high-level

• Source-to-source compiler for JavaScript.–Other s2s compilers for JS:• TypeScript• CoffeeScript• Dart (though also has a VM)

• Project backed by Mozilla• Concepts borrowed from Racket

Page 25: Macros & Sweet · 2017. 11. 13. · •Text substitution macros –text is converted to text. •Embedded languages are similar –PHP, Ruby's erb, etc. Lexer/ Tokenizer Parser source

Prototypal Inheritance

var Droid = {speak: function() {console.log(">>Beep, boop<<, " +

"I am " + this.name);},create: function(name) {var clone = Object.create(this);clone.name = name;return clone;

},};

Page 26: Macros & Sweet · 2017. 11. 13. · •Text substitution macros –text is converted to text. •Embedded languages are similar –PHP, Ruby's erb, etc. Lexer/ Tokenizer Parser source

var areToo =Droid.create('R2-D2');

but we are used to calling:

var bb8 = new Droid('BB8');

We create new droids like so:

Page 27: Macros & Sweet · 2017. 11. 13. · •Text substitution macros –text is converted to text. •Embedded languages are similar –PHP, Ruby's erb, etc. Lexer/ Tokenizer Parser source

Macro

syntax new = function (ctx) {

let ident = ctx.next().value;let params = ctx.next().value;

return #`${ident}.create ${params}`;}

var bb8 = new Droid('BB8');

Page 28: Macros & Sweet · 2017. 11. 13. · •Text substitution macros –text is converted to text. •Embedded languages are similar –PHP, Ruby's erb, etc. Lexer/ Tokenizer Parser source

Translated versionvar Droid_0 = { speak: function speak() {

console.log(">>Beep, boop<<, I am "+ this.name);

}, create: function create(name_8) {var clone_9 = Object.create(this);clone_9.name = name_8;return clone_9;

} };var bb8_7 = Droid_0.create("BB8");

Page 29: Macros & Sweet · 2017. 11. 13. · •Text substitution macros –text is converted to text. •Embedded languages are similar –PHP, Ruby's erb, etc. Lexer/ Tokenizer Parser source

Installing Sweet.js

From a Unix/Dos command line:

$npm install -g @sweet-js/cli$npm install @sweet-js/helpers

Page 30: Macros & Sweet · 2017. 11. 13. · •Text substitution macros –text is converted to text. •Embedded languages are similar –PHP, Ruby's erb, etc. Lexer/ Tokenizer Parser source

Invoking Sweet.js

• Compile your code:$sjs myfile.js -d out/

• Then you may run the output file normally:$node out/myfile.js

Page 31: Macros & Sweet · 2017. 11. 13. · •Text substitution macros –text is converted to text. •Embedded languages are similar –PHP, Ruby's erb, etc. Lexer/ Tokenizer Parser source

syntax swap = function (ctx) {

var a = ctx.next().value;

var b = ctx.next().value;

return #`var tmp =${a}; ${a}=${b}; ${b}=tmp;`;

}

var a = 10; var b = 20;

console.log("a:" + a + " b:" + b);

swap a b;console.log("a:" + a + " b:" + b);

Page 32: Macros & Sweet · 2017. 11. 13. · •Text substitution macros –text is converted to text. •Embedded languages are similar –PHP, Ruby's erb, etc. Lexer/ Tokenizer Parser source

Iterating over syntax

Page 33: Macros & Sweet · 2017. 11. 13. · •Text substitution macros –text is converted to text. •Embedded languages are similar –PHP, Ruby's erb, etc. Lexer/ Tokenizer Parser source

syntax square = function (ctx) {

var inCtx = ctx.contextify(ctx.next().value);

var result = #``;

var stx;

for (stx of inCtx) {

result = result.concat(

#`${stx} = ${stx}*${stx};`);

inCtx.next(); // Eating comma

}

return result;

}

var a = 1; var b = 2; var c = 3;

square(a, b, c);

console.log("a:"+a+" b:"+b+" c:"+c);

Page 34: Macros & Sweet · 2017. 11. 13. · •Text substitution macros –text is converted to text. •Embedded languages are similar –PHP, Ruby's erb, etc. Lexer/ Tokenizer Parser source

Output

var a_5 = 1;var b_6 = 2;var c_7 = 3;a_5 = a_5 * a_5;b_6 = b_6 * b_6;c_7 = c_7 * c_7;console.log("a:" + a_5 + " b:" +

b_6 + " c:" + c_7);

Page 35: Macros & Sweet · 2017. 11. 13. · •Text substitution macros –text is converted to text. •Embedded languages are similar –PHP, Ruby's erb, etc. Lexer/ Tokenizer Parser source

Sweet.js helper functions

import { isStringLiteral }from '@sweet-js/helpers' for syntax;

syntax m = function(ctx) {if (isStringLiteral(ctx.next().value))

return #`'a string'`;else

return #`'not a string'`;}m 'foo';m 42;var s = "hello";m s;

Page 36: Macros & Sweet · 2017. 11. 13. · •Text substitution macros –text is converted to text. •Embedded languages are similar –PHP, Ruby's erb, etc. Lexer/ Tokenizer Parser source

Adding classes to JavaScript.(in class)

Page 37: Macros & Sweet · 2017. 11. 13. · •Text substitution macros –text is converted to text. •Embedded languages are similar –PHP, Ruby's erb, etc. Lexer/ Tokenizer Parser source

Lab

Create a rotate macro in Sweet.jsthat works like the swap macro, except that it takes an arbitrary number of arguments.

There is no starter code for this lab.


Recommended