Rascal Tutorial - CWIhomepages.cwi.nl/~storm/rascal-tutorial/intro.pdf · •...

42
Rascal Tutorial Tijs van der Storm [email protected] / @tvdstorm Wednesday, May 23, 12

Transcript of Rascal Tutorial - CWIhomepages.cwi.nl/~storm/rascal-tutorial/intro.pdf · •...

Page 1: Rascal Tutorial - CWIhomepages.cwi.nl/~storm/rascal-tutorial/intro.pdf · • storm/rascal-tutorial/ miss-grant.zip • Import in Eclipse • Have a look at the Rascal modules

Rascal TutorialTijs van der Storm

[email protected] / @tvdstorm

Wednesday, May 23, 12

Page 2: Rascal Tutorial - CWIhomepages.cwi.nl/~storm/rascal-tutorial/intro.pdf · • storm/rascal-tutorial/ miss-grant.zip • Import in Eclipse • Have a look at the Rascal modules

About me

• Researcher at Centrum Wiskunde & Informatica (CWI), Amsterdam, NL

• Co-designer of Rascal

• Teacher at Universiteit van Amsterdam (UvA)

• Master Software Engineering

• Interests: DSLs, MDE, Meta-programming, PL

Wednesday, May 23, 12

Page 3: Rascal Tutorial - CWIhomepages.cwi.nl/~storm/rascal-tutorial/intro.pdf · • storm/rascal-tutorial/ miss-grant.zip • Import in Eclipse • Have a look at the Rascal modules

Today

• 09:00-10:00: intro + warming up

• 10:15-11:15: syntax + transformation

• 11:30-12:30: extraction + analysis

• lunch

• 14:00-15:00: code generation + closing

Wednesday, May 23, 12

Page 4: Rascal Tutorial - CWIhomepages.cwi.nl/~storm/rascal-tutorial/intro.pdf · • storm/rascal-tutorial/ miss-grant.zip • Import in Eclipse • Have a look at the Rascal modules

More information

• Handout: describes exercises in detail

• http://www.cwi.nl/~storm/rascal-tutorial

• Cheat sheet: quick ref for Rascal language

• http://tutor.rascal-mpl.org

• (also in Eclipse, under Rascal menu)

• http://ask.rascal-mpl.org

Wednesday, May 23, 12

Page 5: Rascal Tutorial - CWIhomepages.cwi.nl/~storm/rascal-tutorial/intro.pdf · • storm/rascal-tutorial/ miss-grant.zip • Import in Eclipse • Have a look at the Rascal modules

Project template

• Download the project:

• http://www.cwi.nl/~storm/rascal-tutorial/miss-grant.zip

• Import in Eclipse

• Have a look at the Rascal modules

• (More info in the hand out)

Wednesday, May 23, 12

Page 6: Rascal Tutorial - CWIhomepages.cwi.nl/~storm/rascal-tutorial/intro.pdf · • storm/rascal-tutorial/ miss-grant.zip • Import in Eclipse • Have a look at the Rascal modules

Rascal

Wednesday, May 23, 12

Page 7: Rascal Tutorial - CWIhomepages.cwi.nl/~storm/rascal-tutorial/intro.pdf · • storm/rascal-tutorial/ miss-grant.zip • Import in Eclipse • Have a look at the Rascal modules

Rascal TeamPaulKlint

JurgenVinju

Tijsv/d Storm

ArnoldLankamp

BertLisser Bas

BastenMarkHills

Jeroenvan den Bos

BobFuhrer

Google

EmilieBalland

INRIACWI/INRIA

Atzev/d Ploeg

NFI

Wednesday, May 23, 12

Page 8: Rascal Tutorial - CWIhomepages.cwi.nl/~storm/rascal-tutorial/intro.pdf · • storm/rascal-tutorial/ miss-grant.zip • Import in Eclipse • Have a look at the Rascal modules

Rascal is a DSL

• Domain: Meta Programming

• Rascal programs...

• analyze,

• transform,

• visualize,

• or generate

• and nothing less, and nothing more

...other programs

Wednesday, May 23, 12

Page 9: Rascal Tutorial - CWIhomepages.cwi.nl/~storm/rascal-tutorial/intro.pdf · • storm/rascal-tutorial/ miss-grant.zip • Import in Eclipse • Have a look at the Rascal modules

Rascal is a DSL

• Domain: Meta Programming

• Rascal programs...

• analyze,

• transform,

• visualize,

• or generate

• and nothing less, and nothing more

...other programs

Wednesday, May 23, 12

Page 10: Rascal Tutorial - CWIhomepages.cwi.nl/~storm/rascal-tutorial/intro.pdf · • storm/rascal-tutorial/ miss-grant.zip • Import in Eclipse • Have a look at the Rascal modules

Meta Software

• Dead code detection

• Slicing/Dependence

• Metrics

• Reverse engineering

• Verification

• Architecture recovery

• Code-to-model

• ...

• Goto elimination

• Dialect transformation

• Aspect weaving

• DSL compilers

• API migration

• Model-to-code

• Model-to-model

• ...

(Static)Analysis Program Transformation

Wednesday, May 23, 12

Page 11: Rascal Tutorial - CWIhomepages.cwi.nl/~storm/rascal-tutorial/intro.pdf · • storm/rascal-tutorial/ miss-grant.zip • Import in Eclipse • Have a look at the Rascal modules

Metaprogramming

Source Code

Models

Pictures

GenerationExtraction

FormalizationVisualization

Transformation

Conversion

Analysis

Input

Abstraction

Output

Extract

Analyze

Synthesize

EASY

Wednesday, May 23, 12

Page 12: Rascal Tutorial - CWIhomepages.cwi.nl/~storm/rascal-tutorial/intro.pdf · • storm/rascal-tutorial/ miss-grant.zip • Import in Eclipse • Have a look at the Rascal modules

Use

• File extension: .rsc

• Open “Rascal Perspective”

• Use “New Rascal Project” wizard

• Use “New Rascal File” wizard

• Context-menu on Rascal editors

• Start Console

Wednesday, May 23, 12

Page 13: Rascal Tutorial - CWIhomepages.cwi.nl/~storm/rascal-tutorial/intro.pdf · • storm/rascal-tutorial/ miss-grant.zip • Import in Eclipse • Have a look at the Rascal modules

Read-Eval-Print

rascal>1 + 1int: 2rascal>[1,2,3]list[int]: [1,2,3]rascal>{1,1,1}set[int]: {1}rascal>{ <i,i*i> | i <- [1..10]}rel[int,int]: {<1,1>,<2,4>,<3,9>,...

Wednesday, May 23, 12

Page 14: Rascal Tutorial - CWIhomepages.cwi.nl/~storm/rascal-tutorial/intro.pdf · • storm/rascal-tutorial/ miss-grant.zip • Import in Eclipse • Have a look at the Rascal modules

Read-Eval-Printrascal>import IO;okrascal>for (i <- [1..10]) {>>>>>>> println("<i> * <i> = <i * i>");>>>>>>>}1 * 1 = 12 * 2 = 43 * 3 = 94 * 4 = 165 * 5 = 256 * 6 = 367 * 7 = 498 * 8 = 649 * 9 = 8110 * 10 = 100list[void]: []rascal>

Wednesday, May 23, 12

Page 15: Rascal Tutorial - CWIhomepages.cwi.nl/~storm/rascal-tutorial/intro.pdf · • storm/rascal-tutorial/ miss-grant.zip • Import in Eclipse • Have a look at the Rascal modules

module path::to::Examplesimport IO;

public int fac(int n) { if (n == 0) { return 1; } return n * fac(n - 1);}

Modules

Wednesday, May 23, 12

Page 16: Rascal Tutorial - CWIhomepages.cwi.nl/~storm/rascal-tutorial/intro.pdf · • storm/rascal-tutorial/ miss-grant.zip • Import in Eclipse • Have a look at the Rascal modules

list[int] even(int max) { list[int] result = []; for (int i <- [0..max]) { if (i % 2 == 0) { result += i; } } return result;}

From coding to declaring

Wednesday, May 23, 12

Page 17: Rascal Tutorial - CWIhomepages.cwi.nl/~storm/rascal-tutorial/intro.pdf · • storm/rascal-tutorial/ miss-grant.zip • Import in Eclipse • Have a look at the Rascal modules

list[int] even(int max) { list[int] result = []; for (int i <- [0..max], i%2 == 0) { result += i; } return result;}

From coding to declaring

Wednesday, May 23, 12

Page 18: Rascal Tutorial - CWIhomepages.cwi.nl/~storm/rascal-tutorial/intro.pdf · • storm/rascal-tutorial/ miss-grant.zip • Import in Eclipse • Have a look at the Rascal modules

list[int] even(int max) { result = []; for (i <- [0..max], i%2 == 0) { result += i; } return result;}

From coding to declaring

Wednesday, May 23, 12

Page 19: Rascal Tutorial - CWIhomepages.cwi.nl/~storm/rascal-tutorial/intro.pdf · • storm/rascal-tutorial/ miss-grant.zip • Import in Eclipse • Have a look at the Rascal modules

list[int] even(int max) { return for (i <- [0..max], i%2 == 0) append i;}

From coding to declaring

Wednesday, May 23, 12

Page 20: Rascal Tutorial - CWIhomepages.cwi.nl/~storm/rascal-tutorial/intro.pdf · • storm/rascal-tutorial/ miss-grant.zip • Import in Eclipse • Have a look at the Rascal modules

list[int] even(int max) { return [i | i <- [0..max], i%2 == 0];}

From coding to declaring

Wednesday, May 23, 12

Page 21: Rascal Tutorial - CWIhomepages.cwi.nl/~storm/rascal-tutorial/intro.pdf · • storm/rascal-tutorial/ miss-grant.zip • Import in Eclipse • Have a look at the Rascal modules

list[int] even(int max) = [i | i <- [0..max], i%2 == 0];

From coding to declaring

Wednesday, May 23, 12

Page 22: Rascal Tutorial - CWIhomepages.cwi.nl/~storm/rascal-tutorial/intro.pdf · • storm/rascal-tutorial/ miss-grant.zip • Import in Eclipse • Have a look at the Rascal modules

Immutable values

• WYSIWYG values

• true, false

• 1, 2, 3, ...

• 1.0, 1.1, 1.11111111

• [1,2,3]

• {1,2,3}

(“1”:1, “2”:2)

name(“Y.T.”)

<1,2>, <1,2,1.0>

{<1,2>,2,1>}

Nest any way you like

Wednesday, May 23, 12

Page 23: Rascal Tutorial - CWIhomepages.cwi.nl/~storm/rascal-tutorial/intro.pdf · • storm/rascal-tutorial/ miss-grant.zip • Import in Eclipse • Have a look at the Rascal modules

Types

• list[void]: []

• list[int]: [1]

• list[value]: [1, “1”]

• set[int]: {1}

• set[value]: {1,”1”}

value

void

int str list[value] ...

Wednesday, May 23, 12

Page 24: Rascal Tutorial - CWIhomepages.cwi.nl/~storm/rascal-tutorial/intro.pdf · • storm/rascal-tutorial/ miss-grant.zip • Import in Eclipse • Have a look at the Rascal modules

Sub-typesvalue

int

real

bool

list[value]

list[int] list[real]

“A sub-type is a sub-set”

Wednesday, May 23, 12

Page 25: Rascal Tutorial - CWIhomepages.cwi.nl/~storm/rascal-tutorial/intro.pdf · • storm/rascal-tutorial/ miss-grant.zip • Import in Eclipse • Have a look at the Rascal modules

node myNode = “person”(“Y.T”, 18);

data Person = person(str name, int age) | person(str first, str last);

Person YT = person(“Y.T”, 18);Person MC = person(“Hiro”, “Protagonist”);

Trees and Data

Wednesday, May 23, 12

Page 26: Rascal Tutorial - CWIhomepages.cwi.nl/~storm/rascal-tutorial/intro.pdf · • storm/rascal-tutorial/ miss-grant.zip • Import in Eclipse • Have a look at the Rascal modules

node myNode = “person”(“Y.T”, 18);

data Person = person(str name, int age) | person(str first, str last);

Person YT = person(“Y.T”, 18);Person MC = person(“Hiro”, “Protagonist”);

node

Person

Trees and Data

Wednesday, May 23, 12

Page 27: Rascal Tutorial - CWIhomepages.cwi.nl/~storm/rascal-tutorial/intro.pdf · • storm/rascal-tutorial/ miss-grant.zip • Import in Eclipse • Have a look at the Rascal modules

Notable features• Switch-case

• Visit

• Pattern matching

• Solve

• Comprehensions

• Grammars

• String templates

• Eclipse JDT interface

• IDE generation

• Concrete syntax

• ....

Wednesday, May 23, 12

Page 28: Rascal Tutorial - CWIhomepages.cwi.nl/~storm/rascal-tutorial/intro.pdf · • storm/rascal-tutorial/ miss-grant.zip • Import in Eclipse • Have a look at the Rascal modules

Warm-up (1)• 1 + 1, 4 / 2, 2 * 2

• int a = 1;

• b = 2;

• import Set;

• max({1,2,3})

• { i | i <- [0..100]}

• int a := b

• <a,b> = <1,2>;

• if (1 > 2) println(“x”);

• int fac(int n) { if (n == 0 ) return 1; return n * f(n - 1); }

• [ p | p <- [1..100], all(i <- [2..10], i != p ==> p % i != 0)]

Wednesday, May 23, 12

Page 29: Rascal Tutorial - CWIhomepages.cwi.nl/~storm/rascal-tutorial/intro.pdf · • storm/rascal-tutorial/ miss-grant.zip • Import in Eclipse • Have a look at the Rascal modules

Warm-up (2)

• Create new module Exp

• Add ADT for expressions: add, mul, const

• Write interpreter using switch

Wednesday, May 23, 12

Page 30: Rascal Tutorial - CWIhomepages.cwi.nl/~storm/rascal-tutorial/intro.pdf · • storm/rascal-tutorial/ miss-grant.zip • Import in Eclipse • Have a look at the Rascal modules

Domain-specific languages in Rascal

Wednesday, May 23, 12

Page 31: Rascal Tutorial - CWIhomepages.cwi.nl/~storm/rascal-tutorial/intro.pdf · • storm/rascal-tutorial/ miss-grant.zip • Import in Eclipse • Have a look at the Rascal modules

State machines

Wednesday, May 23, 12

Page 32: Rascal Tutorial - CWIhomepages.cwi.nl/~storm/rascal-tutorial/intro.pdf · • storm/rascal-tutorial/ miss-grant.zip • Import in Eclipse • Have a look at the Rascal modules

Textual notationevents doorClosed D1CL drawerOpened D2OP lightOn L1ON doorOpened D1OP panelClosed PNCL end

resetEvents doorOpened end

commands unlockPanel PNUL lockPanel PNLK lockDoor D1LK unlockDoor D1ULend

state idle actions {unlockDoor lockPanel} doorClosed => activeend

state active drawerOpened => waitingForLight lightOn => waitingForDrawer end

state waitingForLight lightOn => unlockedPanel end

state waitingForDrawer drawerOpened => unlockedPanel end

state unlockedPanel actions {unlockPanel lockDoor} panelClosed => idle end

Wednesday, May 23, 12

Page 33: Rascal Tutorial - CWIhomepages.cwi.nl/~storm/rascal-tutorial/intro.pdf · • storm/rascal-tutorial/ miss-grant.zip • Import in Eclipse • Have a look at the Rascal modules

Aspects of DSL implementation

• Syntax

• Transformation

• Analysis

• Visualization

• Code generation

Wednesday, May 23, 12

Page 34: Rascal Tutorial - CWIhomepages.cwi.nl/~storm/rascal-tutorial/intro.pdf · • storm/rascal-tutorial/ miss-grant.zip • Import in Eclipse • Have a look at the Rascal modules

Syntax

• Lexical syntax

• Context-free syntax

• Abstract syntax

• Parsing

Wednesday, May 23, 12

Page 35: Rascal Tutorial - CWIhomepages.cwi.nl/~storm/rascal-tutorial/intro.pdf · • storm/rascal-tutorial/ miss-grant.zip • Import in Eclipse • Have a look at the Rascal modules

Parsingcontroller( [ event("doorClosed","D1CL"), event("drawerOpened","D2OP"), event("lightOn","L1ON"), event("doorOpened","D1OP"), event("panelClosed","PNCL") ], ["doorOpened"], [ command("unlockPanel","PNUL"), command("lockPanel","PNLK"), command("lockDoor","D1LK"), command("unlockDoor","D1UL") ], [ state( "idle", ["unlockDoor","lockPanel"], [transition("doorClosed","active")]), state( "active", [], [ transition("drawerOpened","waitingForLight"), transition("lightOn","waitingForDrawer") ]), state( "waitingForLight", [], [transition("lightOn","unlockedPanel")]), state( "waitingForDrawer", [], [transition("drawerOpened","unlockedPanel")]), state( "unlockedPanel", ["unlockPanel","lockDoor"], [transition("panelClosed","idle")]) ])

events doorClosed D1CL drawerOpened D2OP lightOn L1ON doorOpened D1OP panelClosed PNCL end

resetEvents doorOpened end

commands unlockPanel PNUL lockPanel PNLK lockDoor D1LK unlockDoor D1ULend

state idle actions {unlockDoor lockPanel} doorClosed => activeend

state active drawerOpened => waitingForLight lightOn => waitingForDrawer end

state waitingForLight lightOn => unlockedPanel end

state waitingForDrawer drawerOpened => unlockedPanel end

state unlockedPanel actions {unlockPanel lockDoor} panelClosed => idle end

Wednesday, May 23, 12

Page 36: Rascal Tutorial - CWIhomepages.cwi.nl/~storm/rascal-tutorial/intro.pdf · • storm/rascal-tutorial/ miss-grant.zip • Import in Eclipse • Have a look at the Rascal modules

Transformation

• Desugaring

• Optimization

• Normalization

• Refactoring

• ...

Wednesday, May 23, 12

Page 37: Rascal Tutorial - CWIhomepages.cwi.nl/~storm/rascal-tutorial/intro.pdf · • storm/rascal-tutorial/ miss-grant.zip • Import in Eclipse • Have a look at the Rascal modules

events DOORCLOSED D1CL drawerOpened D2OP lightOn L1ON doorOpened D1OP panelClosed PNCL end

resetEvents doorOpened end

commands unlockPanel PNUL lockPanel PNLK lockDoor D1LK unlockDoor D1ULend

state idle actions {unlockDoor lockPanel} DOORCLOSED => activeend

Wednesday, May 23, 12

Page 38: Rascal Tutorial - CWIhomepages.cwi.nl/~storm/rascal-tutorial/intro.pdf · • storm/rascal-tutorial/ miss-grant.zip • Import in Eclipse • Have a look at the Rascal modules

Analysis

• Type checking

• Verification

• Model checking

• Metrics

• Smell detection

• ...

Wednesday, May 23, 12

Page 39: Rascal Tutorial - CWIhomepages.cwi.nl/~storm/rascal-tutorial/intro.pdf · • storm/rascal-tutorial/ miss-grant.zip • Import in Eclipse • Have a look at the Rascal modules

Wednesday, May 23, 12

Page 40: Rascal Tutorial - CWIhomepages.cwi.nl/~storm/rascal-tutorial/intro.pdf · • storm/rascal-tutorial/ miss-grant.zip • Import in Eclipse • Have a look at the Rascal modules

Visualization

Wednesday, May 23, 12

Page 41: Rascal Tutorial - CWIhomepages.cwi.nl/~storm/rascal-tutorial/intro.pdf · • storm/rascal-tutorial/ miss-grant.zip • Import in Eclipse • Have a look at the Rascal modules

Code generationevents doorClosed D1CL drawerOpened D2OP lightOn L1ON doorOpened D1OP panelClosed PNCL end

resetEvents doorOpened end

commands unlockPanel PNUL lockPanel PNLK lockDoor D1LK unlockDoor D1ULend

state idle actions {unlockDoor lockPanel} doorClosed => activeend

state active drawerOpened => waitingForLight lightOn => waitingForDrawer end

state waitingForLight lightOn => unlockedPanel end

state waitingForDrawer drawerOpened => unlockedPanel end

state unlockedPanel actions {unlockPanel lockDoor} panelClosed => idle end

public class missgrant { public static void main(String args[]) throws java.io.IOException { new missgrant().run(new java.util.Scanner(System.in), new java.io.PrintWriter(System.out)); } private static final int state$idle = 0; private static final int state$active = 1; private static final int state$waitingForLight = 2; private static final int state$waitingForDrawer = 3; private static final int state$unlockedPanel = 4; public void run(java.util.Scanner input, java.io.Writer output) throws java.io.IOException { int state = state$idle; while (true) { String token = input.nextLine(); switch (state) { case state$idle: { unlockDoor(output); lockPanel(output); if (doorClosed(token)) { state = state$active; } if (doorOpened(token)) { state = state$idle; } break; } case state$active: { if (drawerOpened(token)) { state = state$waitingForLight; } if (lightOn(token)) { state = state$waitingForDrawer; } if (doorOpened(token)) { state = state$idle; } break; } case state$waitingForLight: { if (lightOn(token)) { state = state$unlockedPanel; } if (doorOpened(token)) { state = state$idle; } break; } case state$waitingForDrawer: { if (drawerOpened(token)) { state = state$unlockedPanel; } if (doorOpened(token)) { state = state$idle; } break; } case state$unlockedPanel: { unlockPanel(output); lockDoor(output); if (panelClosed(token)) { state = state$idle; } if (doorOpened(token)) { state = state$idle; } break; } } } } private boolean doorClosed(String token) { return token.equals("D1CL"); } private boolean drawerOpened(String token) { return token.equals("D2OP"); } private boolean lightOn(String token) { return token.equals("L1ON"); } private boolean doorOpened(String token) { return token.equals("D1OP"); } private boolean panelClosed(String token) { return token.equals("PNCL"); } private void unlockPanel(java.io.Writer output) throws java.io.IOException { output.write("PNUL\n"); output.flush(); } private void lockPanel(java.io.Writer output) throws java.io.IOException { output.write("PNLK\n"); output.flush(); } private void lockDoor(java.io.Writer output) throws java.io.IOException { output.write("D1LK\n"); output.flush(); } private void unlockDoor(java.io.Writer output) throws java.io.IOException { output.write("D1UL\n"); output.flush(); } }

Wednesday, May 23, 12

Page 42: Rascal Tutorial - CWIhomepages.cwi.nl/~storm/rascal-tutorial/intro.pdf · • storm/rascal-tutorial/ miss-grant.zip • Import in Eclipse • Have a look at the Rascal modules

Outlook

• Next three hours:

• 1: syntax + transformation

• 2: extraction + analysis

• 3: code generation

Wednesday, May 23, 12