From 1ee105dce9c32460feed5c3a20c42abbaa7c1896 Mon Sep 17 00:00:00 2001 From: Cliff Click Date: Sat, 12 Oct 2024 14:02:06 -0700 Subject: Chapter 16: Constructors and Final fields Co-authored-by: Thalia Archibald --- .../com/seaofnodes/simple/GraphVisualizer.java | 71 ++++++++++++---------- 1 file changed, 39 insertions(+), 32 deletions(-) (limited to 'src/main/java/com/seaofnodes/simple/GraphVisualizer.java') diff --git a/src/main/java/com/seaofnodes/simple/GraphVisualizer.java b/src/main/java/com/seaofnodes/simple/GraphVisualizer.java index f5fa1350..de6d65a3 100644 --- a/src/main/java/com/seaofnodes/simple/GraphVisualizer.java +++ b/src/main/java/com/seaofnodes/simple/GraphVisualizer.java @@ -1,10 +1,11 @@ package com.seaofnodes.simple; -import com.seaofnodes.simple.Parser; import com.seaofnodes.simple.node.*; import java.util.*; +import static com.seaofnodes.simple.Utils.TODO; + /** * Simple visualizer that outputs GraphViz dot format. * The dot output must be saved to a file and run manually via dot to generate the SVG output. @@ -80,7 +81,7 @@ public class GraphVisualizer { // Just the Nodes first, in a cluster no edges sb.append(doCtrl ? "\tsubgraph cluster_Controls {\n" : "\tsubgraph cluster_Nodes {\n"); // Magic "cluster_" in the subgraph name for (Node n : all) { - if (n instanceof ProjNode || n instanceof CProjNode || n instanceof ScopeNode || n==Parser.XCTRL) + if (n instanceof ProjNode || n instanceof CProjNode || n instanceof ScopeMinNode || n==Parser.XCTRL) continue; // Do not emit, rolled into MultiNode or Scope cluster already if( _separateControlCluster && doCtrl && !(n instanceof CFGNode) ) continue; if( _separateControlCluster && !doCtrl && (n instanceof CFGNode) ) continue; @@ -154,26 +155,34 @@ public class GraphVisualizer { // Build a nested scope display, walking the _prev edge private void scope( StringBuilder sb, ScopeNode scope ) { sb.append("\tnode [shape=plaintext];\n"); - int level=1; - for( int idx = scope._idxs.size()-1; idx>=0; idx-- ) { - var syms = scope._idxs.get(idx); + int last = scope.nIns(); + int max = scope._lexSize.size(); + for( int i = 0; i < max; i++ ) { + int level = max-i-1; String scopeName = makeScopeName(scope, level); sb.append("\tsubgraph cluster_").append(scopeName).append(" {\n"); // Magic "cluster_" in the subgraph name + // Special for memory ScopeMinNode + if( level==0 ) { + ScopeMinNode n = scope.mem(); + sb.append("\t\t").append(n.uniqueName()).append(" [label=\"").append(n.glabel()).append("\"];\n"); + } sb.append("\t\t").append(scopeName).append(" [label=<\n"); sb.append("\t\t\t\n"); // Add the scope level - int scopeLevel = scope._idxs.size()-level; - sb.append("\t\t\t"); - for(String name: syms.keySet()) - sb.append(""); + sb.append("\t\t\t"); + int lexStart=scope._lexSize.at(level); + for( int j=lexStart; j").append(v._name).append(""); + } + last = lexStart; sb.append("\n"); sb.append("\t\t\t
").append(scopeLevel).append("").append(name).append("
").append(level).append("
>];\n"); - level++; } // Scope clusters nest, so the graphics shows the nested scopes, so // they are not closed as they are printed; so they just keep nesting. // We close them all at once here. - sb.append( "\t}\n".repeat( level-1 ) ); // End all Scope clusters + sb.append( "\t}\n".repeat( max ) ); // End all Scope clusters } private String makeScopeName(ScopeNode sn, int level) { return sn.uniqueName() + "_" + level; } @@ -229,27 +238,25 @@ public class GraphVisualizer { // Walk the scope edges private void scopeEdges( StringBuilder sb, ScopeNode scope ) { sb.append("\tedge [style=dashed color=cornflowerblue];\n"); - int level=1; - for( int i = scope._idxs.size()-1; i>=0; i-- ) { - var syms = scope._idxs.get(i); - String scopeName = makeScopeName(scope, level); - for( String name : syms.keySet() ) { - int idx = syms.get(name); - Node def = scope.in(idx); - while( def instanceof ScopeNode lazy ) - def = lazy.in(idx); - if( def==null ) continue; - sb.append("\t") - .append(scopeName).append(":") - .append('"').append(makePortName(scopeName, name)).append('"') // wrap port name with quotes because $ctrl is not valid unquoted - .append(" -> "); - if( def instanceof CProjNode proj ) { - String mname = proj.ctrl().uniqueName(); - sb.append(mname).append(":p").append(proj._idx); - } else sb.append(def.uniqueName()); - sb.append(";\n"); - } - level++; + int level=0; + for( var v : scope._vars ) { + Node def = scope.in(v._idx); + while( def instanceof ScopeNode lazy ) + def = lazy.in(v._idx); + if( def==null ) continue; + while( level < scope._lexSize.size() && v._idx >= scope._lexSize.at(level) ) + level++; + String scopeName = makeScopeName(scope, level-1); + sb.append("\t") + .append(scopeName).append(":") + .append('"').append(makePortName(scopeName, v._name)).append('"') // wrap port name with quotes because $ctrl is not valid unquoted + .append(" -> "); + if( def instanceof CProjNode proj ) { + sb.append(def.in(0).uniqueName()).append(":p").append(proj._idx); + } else if( def instanceof ProjNode proj ) { + sb.append(def.in(0).uniqueName()).append(":p").append(proj._idx); + } else sb.append(def.uniqueName()); + sb.append(";\n"); } } -- cgit v1.2.3