Upgrade to Pro — share decks privately, control downloads, hide ads and more …

A Toy Language Interpreter

A Toy Language Interpreter

Ionuț G. Stan

December 18, 2014
Tweet

More Decks by Ionuț G. Stan

Other Decks in Programming

Transcript

  1. Ionuț G. Stan · [email protected] · igstan.ro Plan ‣ Interpreters

    and Compilers ‣ Why Learn Compilers ‣ Why Scala for Today ‣ Coding Part
  2. Ionuț G. Stan · [email protected] · igstan.ro Many Other Phases

    Lexer Parser Type Checker Source Target ...
  3. 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!
  4. 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!
  5. 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!
  6. 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!
  7. 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!
  8. 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!
  9. 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!
  10. 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!
  11. 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 :-)
  12. 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 :-)
  13. 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 :-)
  14. 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! }
  15. 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! }
  16. 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! }
  17. 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! }
  18. 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! }
  19. 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 :-)
  20. 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;! }! }
  21. 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;! }! }
  22. 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;! }! }
  23. Ionuț G. Stan · [email protected] · igstan.ro Traversing an AST

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

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

    in Java public class Add implements Node {! // fields and constructor omitted! ! @Override! public <R> R match(Matcher<R> matcher) {! return matcher.matchAdd(this);! }! }
  26. 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<Integer> {! @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;! }! });
  27. 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<Integer> {! @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;! }! });
  28. 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<Integer> {! @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;! }! });
  29. 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<Integer> {! @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;! }! });
  30. Ionuț G. Stan · [email protected] · igstan.ro Traversing an AST

    in Java public interface Node {! public <R> R match(Matcher<R> matcher);! }! ! public interface Matcher<R> {! public R matchNum(Num n);! public R matchAdd(Add a);! }
  31. Ionuț G. Stan · [email protected] · igstan.ro The Visitor Pattern

    public interface Node {! public <R> R visit(NodeVisitor<R> visitor);! }! ! public interface NodeVisitor<R> {! public R visitNum(Num n);! public R visitAdd(Add a);! }
  32. 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
  33. 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<LexicalContext> {! final class Splitter extends NodeVisitor<LexicalContext> {! public final class JSONWriter extends NodeVisitor<LexicalContext> {! public final class PrintVisitor extends NodeVisitor<LexicalContext> {! public class NodeOperatorVisitor<T extends LexicalContext> extends NodeVisitor<T> {
  34. Ionuț G. Stan · [email protected] · igstan.ro Example Interpreter in

    Java https://github.com/igstan/tree-interpreter-visitor
  35. 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 :-)
  36. 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 :-)
  37. 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 :-)