diff options
Diffstat (limited to 'chapter04/src/main/java')
5 files changed, 70 insertions, 3 deletions
diff --git a/chapter04/src/main/java/com/seaofnodes/simple/Parser.java b/chapter04/src/main/java/com/seaofnodes/simple/Parser.java index ff2c0504..360a7be9 100644 --- a/chapter04/src/main/java/com/seaofnodes/simple/Parser.java +++ b/chapter04/src/main/java/com/seaofnodes/simple/Parser.java @@ -1,5 +1,6 @@ package com.seaofnodes.simple; +import com.seaofnodes.graph.GraphObserver; import com.seaofnodes.simple.node.*; import com.seaofnodes.simple.type.*; @@ -23,6 +24,11 @@ public class Parser { * To make the compiler multithreaded, this field will have to move into a TLS. */ public static StartNode START; + // Current compilation context, like START; the observer belongs to the parser. + public static Parser PARSER; + public GraphObserver<Node> _obs; + public ReturnNode _ret; + public int pos() { return _lexer._position; } // The Lexer. Thin wrapper over a byte[] buffer with a cursor. private final Lexer _lexer; @@ -43,6 +49,7 @@ public class Parser { public Parser(String source, TypeInteger arg) { + PARSER = this; Node.reset(); _lexer = new Lexer(source); _scope = new ScopeNode(); @@ -76,6 +83,8 @@ public class Parser { _scope.pop(); if (!_lexer.isEOF()) throw error("Syntax error, unexpected " + _lexer.getAnyNextToken()); if( show ) showGraph(); + _ret = ret; + if( _obs != null ) _obs.phase("Parse"); return ret; } diff --git a/chapter04/src/main/java/com/seaofnodes/simple/node/Node.java b/chapter04/src/main/java/com/seaofnodes/simple/node/Node.java index 2c0e3832..58516151 100644 --- a/chapter04/src/main/java/com/seaofnodes/simple/node/Node.java +++ b/chapter04/src/main/java/com/seaofnodes/simple/node/Node.java @@ -1,6 +1,7 @@ package com.seaofnodes.simple.node; import com.seaofnodes.simple.Utils; +import com.seaofnodes.simple.Parser; import com.seaofnodes.simple.type.Type; import java.util.*; @@ -202,7 +203,7 @@ public abstract class Node { } // Mostly used for asserts and printing. - boolean isDead() { return isUnused() && nIns()==0 && _type==null; } + public boolean isDead() { return isUnused() && nIns()==0 && _type==null; } // Shortcuts to stop DCE mid-parse // Add bogus null use to keep node alive @@ -234,11 +235,21 @@ public abstract class Node { * </ul> */ public final Node peephole( ) { + var obs = Parser.PARSER == null ? null : Parser.PARSER._obs; + Type old = _type; + if( obs != null ) obs.before(this); + Node n = peepholeOpt(); + Node rez = n == null ? this : n; + if( obs != null ) obs.after(this, n != null || old != _type ? rez : null, false); + return rez; + } + + private Node peepholeOpt() { // Compute initial or improved Type Type type = _type = compute(); if (_disablePeephole) - return this; // Peephole optimizations turned off + return null; // Peephole optimizations turned off // Replace constant computations from non-constants with a constant node if (!(this instanceof ConstantNode) && type.isConstant()) @@ -252,7 +263,7 @@ public abstract class Node { // Recursively optimize return deadCodeElim(n.peephole()); - return this; // No progress + return null; // No progress } // m is the new Node, self is the old. diff --git a/chapter04/src/main/java/com/seaofnodes/simple/print/JSViewer.java b/chapter04/src/main/java/com/seaofnodes/simple/print/JSViewer.java new file mode 100644 index 00000000..43b0be2f --- /dev/null +++ b/chapter04/src/main/java/com/seaofnodes/simple/print/JSViewer.java @@ -0,0 +1,26 @@ +package com.seaofnodes.simple.print; + +import com.seaofnodes.graph.*; +import com.seaofnodes.simple.Parser; +import java.io.IOException; + +public class JSViewer extends GraphViewer { + public static void main(String[] args) throws IOException { + try( var view = new JSViewer() ) { view.run(); } + } + JSViewer() throws IOException {} + + @Override protected void compile(String src) { + Parser parser = new Parser(src); + parser._obs = new SimpleGraphObserver(parser) { + @Override protected void frame(GraphSnapshot snap, int pos, GraphEvent evt) throws IOException { + JSViewer.this.frame(snap, pos, evt); + } + }; + try { + parser.parse(); + } finally { + parser._obs = null; + } + } +} diff --git a/chapter04/src/main/java/com/seaofnodes/simple/print/SimpleGraphAdapter.java b/chapter04/src/main/java/com/seaofnodes/simple/print/SimpleGraphAdapter.java index 0755613b..72a11a87 100644 --- a/chapter04/src/main/java/com/seaofnodes/simple/print/SimpleGraphAdapter.java +++ b/chapter04/src/main/java/com/seaofnodes/simple/print/SimpleGraphAdapter.java @@ -9,6 +9,7 @@ import java.util.ArrayList; /** Chapter 4's view of the IR; no knowledge of browser, transport or layout. */ public class SimpleGraphAdapter extends GraphAdapter<Node> { + @Override protected boolean dead(Node n) { return n.isDead(); } @Override protected int id(Node n) { return n._nid; } @Override protected int nIns(Node n) { return n.nIns(); } @Override protected Node in(Node n, int idx) { return n.in(idx); } diff --git a/chapter04/src/main/java/com/seaofnodes/simple/print/SimpleGraphObserver.java b/chapter04/src/main/java/com/seaofnodes/simple/print/SimpleGraphObserver.java new file mode 100644 index 00000000..865d1e20 --- /dev/null +++ b/chapter04/src/main/java/com/seaofnodes/simple/print/SimpleGraphObserver.java @@ -0,0 +1,20 @@ +package com.seaofnodes.simple.print; + +import com.seaofnodes.graph.GraphCapture; +import com.seaofnodes.simple.Parser; +import com.seaofnodes.simple.node.Node; +import java.util.ArrayList; + +/** Chapter 4 needs only a parser; it has no worklist or distant dependencies. */ +public abstract class SimpleGraphObserver extends GraphCapture<Node> { + private final Parser _parser; + protected SimpleGraphObserver(Parser parser) { super(new SimpleGraphAdapter()); _parser = parser; } + @Override protected String phase() { return "Parse"; } + @Override protected int pos() { return _parser.pos(); } + @Override protected void detach() { _parser._obs = null; } + @Override protected void roots(ArrayList<Node> roots) { + roots.add(Parser.START); + roots.add(_parser._scope); + roots.add(_parser._ret); + } +} |
