summaryrefslogtreecommitdiff
path: root/chapter15/src/main/java/com
diff options
context:
space:
mode:
authorCliff Click <cliffc@acm.org>2024-10-01 10:36:59 -0700
committerCliff Click <cliffc@acm.org>2024-10-06 08:56:22 -0700
commitbd4c0c8d9fd33b35a0c4d98ca2dd641e3fafbfd3 (patch)
tree9f3a191348482bc6942cb1f256d112059a122776 /chapter15/src/main/java/com
parente315432bbd1ffa4e2dd562c4f4fc454ea1ba2464 (diff)
downloadSimple-bd4c0c8d9fd33b35a0c4d98ca2dd641e3fafbfd3.tar.gz
Simple-bd4c0c8d9fd33b35a0c4d98ca2dd641e3fafbfd3.zip
Fix parsing forward ref arrays
Diffstat (limited to 'chapter15/src/main/java/com')
-rw-r--r--chapter15/src/main/java/com/seaofnodes/simple/Parser.java65
-rw-r--r--chapter15/src/main/java/com/seaofnodes/simple/type/TypeStruct.java5
2 files changed, 40 insertions, 30 deletions
diff --git a/chapter15/src/main/java/com/seaofnodes/simple/Parser.java b/chapter15/src/main/java/com/seaofnodes/simple/Parser.java
index b503bf15..e0077102 100644
--- a/chapter15/src/main/java/com/seaofnodes/simple/Parser.java
+++ b/chapter15/src/main/java/com/seaofnodes/simple/Parser.java
@@ -92,7 +92,9 @@ public class Parser {
ScopeNode _continueScope;
ScopeNode _breakScope;
- // Mapping from a type name to a Type.
+ // Mapping from a type name to a Type. The string name matches
+ // `type.str()` call. No TypeMemPtrs are in here, because Simple does not
+ // have C-style '*ptr' references.
public static HashMap<String, Type> TYPES = new HashMap<>();
public Parser(String source, TypeInteger arg) {
@@ -488,17 +490,10 @@ public class Parser {
if( tname==null ) return null;
// Convert the type name to a type.
Type t0 = TYPES.get(tname);
- Type t1 = t0==null ? TypeStruct.BOT : t0; // Null: assume a forward ref type
+ Type t1 = t0 == null ? TypeStruct.make(tname) : t0; // Null: assume a forward ref type
// Nest arrays as needed
- while( match("[]") ) {
- Type t2 = TYPES.get("[]"+tname);
- if( t2==null ) {
- TYPES.put("[]"+tname,t1 = TypeStruct.makeAry(TypeInteger.BOT,ALIAS++,t1,ALIAS++));
- START.addMemProj((TypeStruct)t1, _scope); // Insert memory edges
- } else {
- t1 = t2;
- }
- }
+ while( match("[]") )
+ t1 = typeAry(t1);
// Handle trailing '?' for nullable
Type t2 = t1 instanceof TypeStruct obj ? TypeMemPtr.make(obj,match("?")) : t1;
@@ -514,8 +509,23 @@ public class Parser {
return null; // Not a type
}
// Yes a forward ref, so declare it
- TYPES.put(tname, t0 = TypeStruct.make(tname));
- return ((TypeMemPtr)t2).makeFrom((TypeStruct)t0);
+ TYPES.put(tname,t1);
+ return t2;
+ }
+
+ // Make an array type of t
+ private TypeStruct typeAry( Type t ) {
+ assert !(t instanceof TypeMemPtr); // Arrays of references, not inlined structs
+ String tname = t.str()+"[]";
+ Type ta = TYPES.get(tname);
+ if( ta != null ) return (TypeStruct)ta;
+ // Need make an array type. If the base type is a struct, wrap it.
+ if( t instanceof TypeStruct obj )
+ t = TypeMemPtr.make(obj,true);
+ TypeStruct ts = TypeStruct.makeAry(TypeInteger.BOT,ALIAS++,t,ALIAS++);
+ TYPES.put(tname,ts);
+ START.addMemProj(ts, _scope); // Insert memory alias edges
+ return ts;
}
@@ -677,14 +687,21 @@ public class Parser {
String typeName = _lexer.matchId();
if( typeName==null ) throw error("Expected a type");
Type t = TYPES.get(typeName);
- if( match("[") )
- return require(newArray(t),"]");
- if( t instanceof TypeStruct obj ) {
- if( obj._fields==null )
- throw error("Unknown struct type '" + typeName + "'");
+ if( t instanceof TypeStruct obj && obj._fields==null )
+ throw error("Unknown struct type '" + typeName + "'");
+ if( t!=null && match("[") ) {
+ Node len = parseExpression().keep();
+ if( !(len._type instanceof TypeInteger) )
+ throw error("Cannot allocate an array with length "+len._type);
+ require("]");
+ TypeStruct ary = typeAry(t);
+ while( match("[]") )
+ ary = typeAry(ary);
+ return newArray(ary,len);
+ } else if( t instanceof TypeStruct obj ) {
return newStruct(obj,con(obj.offset(obj._fields.length)));
}
- throw error("Cannot allocate a "+t);
+ throw error("Cannot allocate a "+typeName);
}
String name = _lexer.matchId();
if( name == null) throw errorSyntax("an identifier or expression");
@@ -709,15 +726,7 @@ public class Parser {
return new ProjNode(nnn,1,obj._name).peephole();
}
- private Node newArray(Type t) {
- Node len = parseExpression().keep();
- if( !(len._type instanceof TypeInteger) )
- throw error("Cannot allocate an array with length "+len._type);
- TypeStruct ary = (TypeStruct)TYPES.get("[]"+t.str());
- if( ary == null ) {
- TYPES.put("[]"+t.str(), ary = TypeStruct.makeAry(TypeInteger.BOT,ALIAS++,t,ALIAS++));
- START.addMemProj(ary, _scope); // Insert memory edges
- }
+ private Node newArray(TypeStruct ary, Node len) {
int base = ary.aryBase ();
int scale= ary.aryScale();
Node size = new AddNode(con(base),new ShlNode(len,con(scale)).peephole()).peephole();
diff --git a/chapter15/src/main/java/com/seaofnodes/simple/type/TypeStruct.java b/chapter15/src/main/java/com/seaofnodes/simple/type/TypeStruct.java
index 9e38e025..b3a8f867 100644
--- a/chapter15/src/main/java/com/seaofnodes/simple/type/TypeStruct.java
+++ b/chapter15/src/main/java/com/seaofnodes/simple/type/TypeStruct.java
@@ -40,8 +40,9 @@ public class TypeStruct extends Type {
// Array
public static TypeStruct makeAry(TypeInteger len, int lenAlias, Type body, int bodyAlias) {
- String name = "[]" + body.str();
- return make("[]" + body.str(),
+ Type t = body;
+ if( t instanceof TypeMemPtr tmp ) { assert tmp._nil; t = tmp._obj; }
+ return make(t.str() + "[]",
Field.make("#" , lenAlias,len ),
Field.make("[]",bodyAlias,body));
}