Slide 1

Slide 1 text

A Toy Language Interpreter Ionuț G. Stan · BJUG #28 · December 2014

Slide 2

Slide 2 text

Ionuț G. Stan · [email protected] · igstan.ro Plan ‣ Interpreters and Compilers ‣ Why Learn Compilers ‣ Why Scala for Today ‣ Coding Part

Slide 3

Slide 3 text

Ionuț G. Stan · [email protected] · igstan.ro Interpreters and Compilers

Slide 4

Slide 4 text

Ionuț G. Stan · [email protected] · igstan.ro Interpreters Interpreter Result Source

Slide 5

Slide 5 text

Ionuț G. Stan · [email protected] · igstan.ro Interpreters Parser Interpreter Result Source

Slide 6

Slide 6 text

Ionuț G. Stan · [email protected] · igstan.ro Interpreters Parser Interpreter Result Source AST (Abstract Syntax Tree)

Slide 7

Slide 7 text

Ionuț G. Stan · [email protected] · igstan.ro Interpreters Lexer Parser Interpreter Result Source

Slide 8

Slide 8 text

Ionuț G. Stan · [email protected] · igstan.ro Interpreters Lexer Parser Type Checker Interpreter Source Result

Slide 9

Slide 9 text

Ionuț G. Stan · [email protected] · igstan.ro Compilers Compiler Target Source

Slide 10

Slide 10 text

Ionuț G. Stan · [email protected] · igstan.ro Compilers Compiler Target Interpreter Result Source

Slide 11

Slide 11 text

Ionuț G. Stan · [email protected] · igstan.ro Compilers Lexer Parser Type Checker Code Emitter Source Target

Slide 12

Slide 12 text

Ionuț G. Stan · [email protected] · igstan.ro Many Other Phases Lexer Parser Type Checker Source Target ...

Slide 13

Slide 13 text

Ionuț G. Stan · [email protected] · igstan.ro Today Parser Interpreter Result Source AST (Abstract Syntax Tree)

Slide 14

Slide 14 text

Ionuț G. Stan · [email protected] · igstan.ro Why Learn Compilers

Slide 15

Slide 15 text

Ionuț G. Stan · [email protected] · igstan.ro Why Learn Compilers ‣ This is my motivation ‣ I like looking under the hood ‣ A compiler's hood is like a starship's hood ‣ Compilers are really well documented ‣ You get to understand tricky language concepts ‣ You get to understand modular architecture ‣ Useful for (E)DSLs development ‣ It's fun!

Slide 16

Slide 16 text

Ionuț G. Stan · [email protected] · igstan.ro Why Learn Compilers ‣ This is my motivation ‣ I like looking under the hood ‣ A compiler's hood is like a starship's hood ‣ Compilers are really well documented ‣ You get to understand tricky language concepts ‣ You get to understand modular architecture ‣ Useful for (E)DSLs development ‣ It's fun!

Slide 17

Slide 17 text

Ionuț G. Stan · [email protected] · igstan.ro Why Learn Compilers ‣ This is my motivation ‣ I like looking under the hood ‣ A compiler's hood is like a starship's hood ‣ Compilers are really well documented ‣ You get to understand tricky language concepts ‣ You get to understand modular architecture ‣ Useful for (E)DSLs development ‣ It's fun!

Slide 18

Slide 18 text

Ionuț G. Stan · [email protected] · igstan.ro Why Learn Compilers ‣ This is my motivation ‣ I like looking under the hood ‣ A compiler's hood is like a starship's hood ‣ Compilers are really well documented ‣ You get to understand tricky language concepts ‣ You get to understand modular architecture ‣ Useful for (E)DSLs development ‣ It's fun!

Slide 19

Slide 19 text

Ionuț G. Stan · [email protected] · igstan.ro Why Learn Compilers ‣ This is my motivation ‣ I like looking under the hood ‣ A compiler's hood is like a starship's hood ‣ Compilers are really well documented ‣ You get to understand tricky language concepts ‣ You get to understand modular architecture ‣ Useful for (E)DSLs development ‣ It's fun!

Slide 20

Slide 20 text

Ionuț G. Stan · [email protected] · igstan.ro Why Learn Compilers ‣ This is my motivation ‣ I like looking under the hood ‣ A compiler's hood is like a starship's hood ‣ Compilers are really well documented ‣ You get to understand tricky language concepts ‣ You get to understand modular architecture ‣ Useful for (E)DSLs development ‣ It's fun!

Slide 21

Slide 21 text

Ionuț G. Stan · [email protected] · igstan.ro Why Learn Compilers ‣ This is my motivation ‣ I like looking under the hood ‣ A compiler's hood is like a starship's hood ‣ Compilers are really well documented ‣ You get to understand tricky language concepts ‣ You get to understand modular architecture ‣ Useful for (E)DSLs development ‣ It's fun!

Slide 22

Slide 22 text

Ionuț G. Stan · [email protected] · igstan.ro Why Learn Compilers ‣ This is my motivation ‣ I like looking under the hood ‣ A compiler's hood is like a starship's hood ‣ Compilers are really well documented ‣ You get to understand tricky language concepts ‣ You get to understand modular architecture ‣ Useful for (E)DSLs development ‣ It's fun!

Slide 23

Slide 23 text

Ionuț G. Stan · [email protected] · igstan.ro Why Scala

Slide 24

Slide 24 text

Ionuț G. Stan · [email protected] · igstan.ro Why Scala ‣ I could have used Java 8 ‣ But... there's one missing feature in Java 8 ‣ The closest alternative is the Visitor pattern ‣ But that's a cumbersome pattern ‣ Last, but not least, I write Scala daily :-)

Slide 25

Slide 25 text

Ionuț G. Stan · [email protected] · igstan.ro Why Scala ‣ I could have used Java 8 ‣ One missing feature, though ‣ The closest alternative is the Visitor pattern ‣ But that's a cumbersome pattern ‣ Last, but not least, I write Scala daily :-)

Slide 26

Slide 26 text

Ionuț G. Stan · [email protected] · igstan.ro Why Scala ‣ I could have used Java 8 ‣ One missing feature, though: pattern matching ‣ The closest alternative is the Visitor pattern ‣ But that's a cumbersome pattern ‣ Last, but not least, I write Scala daily :-)

Slide 27

Slide 27 text

Ionuț G. Stan · [email protected] · igstan.ro Representing an AST in Scala trait Node! case class Num(value: Int) extends Node! case class Add(left: Node, right: Node) extends Node! ! val ast = Add(Num(1), Num(2))! ! val sum = ast match {! case Add(Num(a), Num(b)) => a + b! }

Slide 28

Slide 28 text

Ionuț G. Stan · [email protected] · igstan.ro Representing an AST in Scala trait Node! case class Num(value: Int) extends Node! case class Add(left: Node, right: Node) extends Node! ! val ast = Add(Num(1), Num(2))! ! val sum = ast match {! case Add(Num(a), Num(b)) => a + b! }

Slide 29

Slide 29 text

Ionuț G. Stan · [email protected] · igstan.ro Representing an AST in Scala trait Node! case class Num(value: Int) extends Node! case class Add(left: Node, right: Node) extends Node! ! val ast = Add(Num(1), Num(2))! ! val sum = ast match {! case Add(Num(a), Num(b)) => a + b! }

Slide 30

Slide 30 text

Ionuț G. Stan · [email protected] · igstan.ro Representing an AST in Scala trait Node! case class Num(value: Int) extends Node! case class Add(left: Node, right: Node) extends Node! ! val ast = Add(Num(1), Num(2))! ! val sum = ast match {! case Add(Num(a), Num(b)) => a + b! }

Slide 31

Slide 31 text

Ionuț G. Stan · [email protected] · igstan.ro Traversing an AST in Scala trait Node! case class Num(value: Int) extends Node! case class Add(left: Node, right: Node) extends Node! ! val ast = Add(Num(1), Num(2))! ! val sum = ast match {! case Add(Num(a), Num(b)) => a + b! }

Slide 32

Slide 32 text

Ionuț G. Stan · [email protected] · igstan.ro Why Scala ‣ I could have used Java 8 ‣ One missing feature, though: pattern matching ‣ The closest alternative is the Visitor pattern ‣ But that's a cumbersome pattern ‣ Last, but not least, I write Scala daily :-)

Slide 33

Slide 33 text

Ionuț G. Stan · [email protected] · igstan.ro Representing an AST in Java public interface Node {}! ! public class Num implements Node {! public final int value;! public Num(int value) { this.value = value; }! }! ! public class Add implements Node {! public final Node left, right;! public Add(Node left, Node right) {! this.left = left;! this.right = right;! }! }

Slide 34

Slide 34 text

Ionuț G. Stan · [email protected] · igstan.ro Representing an AST in Java public interface Node {}! ! public class Num implements Node {! public final int value;! public Num(int value) { this.value = value; }! }! ! public class Add implements Node {! public final Node left, right;! public Add(Node left, Node right) {! this.left = left;! this.right = right;! }! }

Slide 35

Slide 35 text

Ionuț G. Stan · [email protected] · igstan.ro Representing an AST in Java public interface Node {}! ! public class Num implements Node {! public final int value;! public Num(int value) { this.value = value; }! }! ! public class Add implements Node {! public final Node left, right;! public Add(Node left, Node right) {! this.left = left;! this.right = right;! }! }

Slide 36

Slide 36 text

Ionuț G. Stan · [email protected] · igstan.ro Traversing an AST in Java public interface Node {! public R match(Matcher matcher);! }! ! public interface Matcher {! public R matchNum(Num n);! public R matchAdd(Add a);! }

Slide 37

Slide 37 text

Ionuț G. Stan · [email protected] · igstan.ro Traversing an AST in Java public class Num implements Node {! // fields and constructor omitted! ! @Override! public R match(Matcher matcher) {! return matcher.matchNum(this);! }! }

Slide 38

Slide 38 text

Ionuț G. Stan · [email protected] · igstan.ro Traversing an AST in Java public class Add implements Node {! // fields and constructor omitted! ! @Override! public R match(Matcher matcher) {! return matcher.matchAdd(this);! }! }

Slide 39

Slide 39 text

Ionuț G. Stan · [email protected] · igstan.ro Traversing an AST in Java int ast = new Add(new Num(1), new Num(2));! ! int sum = ast.match(new Matcher {! @Override! public R matchNum(Num n) {! return n.value;! }! ! @Override! public R matchAdd(Add a) {! int left = a.left.match(this);! int right = a.right.match(this);! return left + right;! }! });

Slide 40

Slide 40 text

Ionuț G. Stan · [email protected] · igstan.ro Traversing an AST in Java int ast = new Add(new Num(1), new Num(2));! ! int sum = ast.match(new Matcher {! @Override! public R matchNum(Num n) {! return n.value;! }! ! @Override! public R matchAdd(Add a) {! int left = a.left.match(this);! int right = a.right.match(this);! return left + right;! }! });

Slide 41

Slide 41 text

Ionuț G. Stan · [email protected] · igstan.ro Traversing an AST in Java int ast = new Add(new Num(1), new Num(2));! ! int sum = ast.match(new Matcher {! @Override! public Integer matchNum(Num n) {! return n.value;! }! ! @Override! public R matchAdd(Add a) {! int left = a.left.match(this);! int right = a.right.match(this);! return left + right;! }! });

Slide 42

Slide 42 text

Ionuț G. Stan · [email protected] · igstan.ro Traversing an AST in Java int ast = new Add(new Num(1), new Num(2));! ! int sum = ast.match(new Matcher {! @Override! public Integer matchNum(Num n) {! return n.value;! }! ! @Override! public Integer matchAdd(Add a) {! int left = a.left.match(this);! int right = a.right.match(this);! return left + right;! }! });

Slide 43

Slide 43 text

Ionuț G. Stan · [email protected] · igstan.ro Traversing an AST in Java public interface Node {! public R match(Matcher matcher);! }! ! public interface Matcher {! public R matchNum(Num n);! public R matchAdd(Add a);! }

Slide 44

Slide 44 text

Ionuț G. Stan · [email protected] · igstan.ro The Visitor Pattern public interface Node {! public R visit(NodeVisitor visitor);! }! ! public interface NodeVisitor {! public R visitNum(Num n);! public R visitAdd(Add a);! }

Slide 45

Slide 45 text

Ionuț G. Stan · [email protected] · igstan.ro Nashorn $ nashorn: cd nashorn/src/jdk/nashorn/internal/ir/! $ ir: ls *Node.java! AccessNode.java FunctionNode.java ReturnNode.java! BaseNode.java IdentNode.java RuntimeNode.java! BinaryNode.java IfNode.java SplitNode.java! BreakNode.java IndexNode.java SwitchNode.java! BreakableNode.java LabelNode.java TernaryNode.java! CallNode.java LexicalContextNode.java ThrowNode.java! CaseNode.java LiteralNode.java TryNode.java! CatchNode.java LoopNode.java UnaryNode.java! ContinueNode.java Node.java VarNode.java! EmptyNode.java ObjectNode.java WhileNode.java! ForNode.java PropertyNode.java WithNode.java

Slide 46

Slide 46 text

Ionuț G. Stan · [email protected] · igstan.ro Nashorn $ ir: cd ..! $ internal: find . -name *Visitor*! ./ir/debug/PrintVisitor.java! ./ir/visitor/NodeOperatorVisitor.java! ./ir/visitor/NodeVisitor.java! $ internal: grep -hR 'extends NodeVisitor' .! final class FoldConstants extends NodeVisitor {! final class Splitter extends NodeVisitor {! public final class JSONWriter extends NodeVisitor {! public final class PrintVisitor extends NodeVisitor {! public class NodeOperatorVisitor extends NodeVisitor {

Slide 47

Slide 47 text

Ionuț G. Stan · [email protected] · igstan.ro Example Interpreter in Java https://github.com/igstan/tree-interpreter-visitor

Slide 48

Slide 48 text

Ionuț G. Stan · [email protected] · igstan.ro Why Scala ‣ I could have used Java 8 ‣ One missing feature, though: pattern matching ‣ The closest alternative is the Visitor pattern ‣ Cumbersome pattern, for me ‣ Last, but not least, I write Scala daily :-)

Slide 49

Slide 49 text

Ionuț G. Stan · [email protected] · igstan.ro Why Scala ‣ I could have used Java 8 ‣ One missing feature, though: pattern matching ‣ The closest alternative is the Visitor pattern ‣ Cumbersome pattern, for me ‣ Last, but not least, I write Scala daily :-)

Slide 50

Slide 50 text

Ionuț G. Stan · [email protected] · igstan.ro Why Scala ‣ I could have used Java 8 ‣ One missing feature, though: pattern matching ‣ The closest alternative is the Visitor pattern ‣ Cumbersome pattern, for me ‣ Last, but not least, I write Scala daily :-)

Slide 51

Slide 51 text

Ionuț G. Stan · [email protected] · igstan.ro Coding Part