‣ 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!
‣ 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!
‣ 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!
‣ 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!
‣ 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!
‣ 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!
‣ 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!
‣ 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!
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 :-)
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 :-)
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 :-)
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! }
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! }
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! }
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! }
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! }
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 :-)
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;! }! }
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;! }! }
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;! }! }
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);! }
in Java public class Num implements Node {! // fields and constructor omitted! ! @Override! public <R> R match(Matcher<R> matcher) {! return matcher.matchNum(this);! }! }
in Java public class Add implements Node {! // fields and constructor omitted! ! @Override! public <R> R match(Matcher<R> matcher) {! return matcher.matchAdd(this);! }! }
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;! }! });
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;! }! });
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;! }! });
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;! }! });
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);! }
public interface Node {! public <R> R visit(NodeVisitor<R> visitor);! }! ! public interface NodeVisitor<R> {! public R visitNum(Num n);! public R visitAdd(Add a);! }
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> {
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 :-)
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 :-)
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 :-)