summaryrefslogtreecommitdiff
path: root/chapter04/src
diff options
context:
space:
mode:
authorCliff Click <cliffc@acm.org>2026-09-22 09:32:07 -0700
committerCliff Click <cliffc@acm.org>2026-09-22 09:32:07 -0700
commit1d961838cff168a101069d08a8ab6594f49f0911 (patch)
treef832576181cc396c033707508a50e3d72120b8c6 /chapter04/src
parent92e3013a4cab12747af9d5484e7caad6fc454b1e (diff)
downloadSimple-1d961838cff168a101069d08a8ab6594f49f0911.tar.gz
Simple-1d961838cff168a101069d08a8ab6594f49f0911.zip
Graph viewer on ch4 and25
Diffstat (limited to 'chapter04/src')
-rw-r--r--chapter04/src/main/java/com/seaofnodes/simple/Parser.java9
-rw-r--r--chapter04/src/main/java/com/seaofnodes/simple/node/Node.java17
-rw-r--r--chapter04/src/main/java/com/seaofnodes/simple/print/JSViewer.java26
-rw-r--r--chapter04/src/main/java/com/seaofnodes/simple/print/SimpleGraphAdapter.java1
-rw-r--r--chapter04/src/main/java/com/seaofnodes/simple/print/SimpleGraphObserver.java20
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);
+ }
+}