Skip to content

Commit febdbb4

Browse files
Various fixes:
1. We do need lexical scopes - so the idea that we could just create unique names for all vars doesn't work because then it means that all vars are available in scopes where they are not supposed to be, leading to creation of phi's that reference undefined vars. 2. The type conversion from EeZee to SON Types had many bugs. 3. The definition of ARY in TypeStruct meant that int[] ended up with incorrect aliases. Additional fixes.
1 parent b19c4a0 commit febdbb4

File tree

12 files changed

+281
-73
lines changed

12 files changed

+281
-73
lines changed

seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/Compiler.java

+46-46
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,12 @@ public TypeDictionary createAST(String src) {
9090

9191

9292
private void populateDefaultTypes(Map<String,SONType> types) {
93+
// Pre-create int, [int] and *[int] types
9394
types.put(typeDictionary.INT.name(), SONTypeInteger.BOT);
95+
var intArrayType = SONTypeStruct.makeAry(SONTypeInteger.U32, _code.getALIAS(), SONTypeInteger.BOT, _code.getALIAS());
96+
var ptrIntArrayType = SONTypeMemPtr.make(intArrayType);
97+
types.put("[" + typeDictionary.INT.name() + "]", ptrIntArrayType);
98+
// Also get the types created by default
9499
for (SONType t: SONType.gather()) {
95100
types.put(t.str(), t);
96101
}
@@ -145,26 +150,31 @@ private void createSONStructType(Map<String, SONType> structTypes, String typeNa
145150
Type type = typeStruct.getField(name); // FIXME
146151
fs.push(new Field(name,getSONType(structTypes,type),_code.getALIAS(),false));
147152
}
153+
// A Struct type may have been created before because of
154+
// reference from itself; in which case we need to update that
148155
SONType fref = structTypes.get(typeName);
149156
if (fref != null) {
150-
if (fref instanceof SONTypeStruct ts) {
157+
if (fref instanceof SONTypeMemPtr ptr &&
158+
ptr._obj instanceof SONTypeStruct ts) {
159+
assert ts._fields.length == 0;
160+
// Add the fields to the existing type
151161
ts._fields = fs.asAry();
152162
}
153-
else throw new CompilerException("");
163+
else throw new CompilerException("Expected struct type " + typeName + " but got " + fref);
154164
}
155165
else {
156-
structTypes.put(typeName, new SONTypeStruct(typeName, fs.asAry()));
166+
var ts = SONTypeStruct.make(typeName, fs.asAry());
167+
var ptr = SONTypeMemPtr.make((byte)2,ts);
168+
structTypes.put(typeName,ptr);
157169
}
158-
// SONTypeStruct ts = SONTypeStruct.make(typeName, fs.asAry());
159-
// TYPES.put(typeName, SONTypeMemPtr.make(ts));
160170
}
161171

162172
private String getSONTypeName(Type type) {
163173
if (type instanceof Type.TypeFunction typeFunction) {
164174
return typeFunction.name;
165175
}
166176
else if (type instanceof Type.TypeArray typeArray) {
167-
return typeArray.name();
177+
return "*[" + getSONTypeName(typeArray.getElementType()) + "]";
168178
}
169179
else if (type instanceof Type.TypeStruct typeStruct) {
170180
return "*" + typeStruct.name;
@@ -183,36 +193,25 @@ else if (type instanceof Type.TypeNullable typeNullable) {
183193
}
184194

185195
private SONType getSONType(Map<String, SONType> structTypes, Type type) {
186-
String tname = getSONTypeName(type);
187-
SONType t = structTypes.get(tname);
196+
SONType t = structTypes.get(type.name());
188197
if (t != null) return t;
189198
if (type instanceof Type.TypeStruct) {
190-
SONType existing = structTypes.get(type.name);
191-
SONTypeStruct ts;
192-
if (existing instanceof SONTypeStruct tsExisting)
193-
ts = tsExisting;
194-
else {
195-
ts = new SONTypeStruct(type.name, new Field[0]);
196-
structTypes.put(ts.str(), ts);
197-
}
198-
SONTypeMemPtr ptr = new SONTypeMemPtr((byte)2,ts);
199-
if (type.name().equals(ts.str())) {
200-
structTypes.put(ptr.str(), ptr);
201-
return ptr;
202-
}
203-
else throw new CompilerException("Unexpected error");
199+
// For struct types in EeZee language a reference
200+
// to T means *T in SoN
201+
// Create SON struct type
202+
SONTypeStruct ts = SONTypeStruct.make(type.name, new Field[0]);
203+
// Now create *T
204+
SONTypeMemPtr ptr = SONTypeMemPtr.make((byte)2,ts);
205+
// EeZee T maps to SoN *T
206+
structTypes.put(type.name(), ptr);
207+
return ptr;
204208
}
205209
else if (type instanceof Type.TypeArray typeArray) {
210+
// A reference to array in EeZee means
211+
// *array in SoN
206212
SONType elementType = getSONType(structTypes,typeArray.getElementType());
207-
SONTypeStruct ts = null;
208-
SONType existing = structTypes.get(typeArray.name());
209-
if (existing instanceof SONTypeStruct tsExisting)
210-
ts = tsExisting;
211-
else {
212-
ts = SONTypeStruct.makeArray(SONTypeInteger.U32, _code.getALIAS(), elementType, _code.getALIAS());
213-
structTypes.put(ts.str(), ts);
214-
}
215-
SONTypeMemPtr ptr = new SONTypeMemPtr((byte)2,ts);
213+
SONTypeStruct ts = SONTypeStruct.makeArray(SONTypeInteger.U32, _code.getALIAS(), elementType, _code.getALIAS());
214+
SONTypeMemPtr ptr = SONTypeMemPtr.make((byte)2,ts);
216215
structTypes.put(typeArray.name(), ptr); // Array type name is not same as ptr str()
217216
return ptr;
218217
}
@@ -223,11 +222,11 @@ else if (type instanceof Type.TypeNullable typeNullable) {
223222
if (ptr1.nullable())
224223
ptr = ptr1;
225224
else
226-
ptr = new SONTypeMemPtr((byte)3,ptr1._obj);
225+
ptr = SONTypeMemPtr.make((byte)3,ptr1._obj);
227226
}
228227
else
229-
ptr = new SONTypeMemPtr((byte)2,(SONTypeStruct) baseType);
230-
structTypes.put(ptr.str(), ptr);
228+
ptr = SONTypeMemPtr.make((byte)2,(SONTypeStruct) baseType);
229+
structTypes.put(typeNullable.name(), ptr);
231230
return ptr;
232231
}
233232
else if (type instanceof Type.TypeVoid) {
@@ -241,13 +240,13 @@ else if (type instanceof Type.TypeVoid) {
241240

242241
// TODO because first two slots are MEM and RPC
243242
private int REGNUM = 2;
244-
private void setVarIds(Scope scope, ScopeNode scopeNode, FunNode fun) {
243+
private void defineScopedVars(Scope scope, ScopeNode scopeNode, FunNode fun) {
245244
for (Symbol symbol: scope.getLocalSymbols()) {
246245
if (symbol instanceof Symbol.VarSymbol varSymbol) {
247246
varSymbol.regNumber = REGNUM++;
248-
String sonTypeName = getSONTypeName(varSymbol.type);
249-
SONType sonType = TYPES.get(sonTypeName);
250-
if (sonType == null) throw new CompilerException("Unknown SON Type "+sonTypeName);
247+
SONType sonType = TYPES.get(varSymbol.type.name());
248+
if (sonType == null)
249+
throw new CompilerException("Unknown SON Type "+varSymbol.type.name());
251250
Node init = null;
252251

253252
if (varSymbol instanceof Symbol.ParameterSymbol) {
@@ -256,9 +255,6 @@ private void setVarIds(Scope scope, ScopeNode scopeNode, FunNode fun) {
256255
scopeNode.define(makeVarName(varSymbol), sonType, false, init);
257256
}
258257
}
259-
for (Scope childScope: scope.children) {
260-
setVarIds(childScope, scopeNode, fun);
261-
}
262258
}
263259

264260
private void generateFunction(Symbol.FunctionTypeSymbol functionTypeSymbol) {
@@ -338,7 +334,8 @@ private ReturnNode generateFunctionBody(Symbol.FunctionTypeSymbol functionTypeSy
338334
_scope.mem(mem);
339335
// All args, "as-if" called externally
340336
AST.FuncDecl funcDecl = (AST.FuncDecl) functionTypeSymbol.functionDecl;
341-
setVarIds(funcDecl.scope,_scope,fun);
337+
REGNUM = 2;
338+
defineScopedVars(funcDecl.scope,_scope,fun);
342339

343340
// Parse the body
344341
Node last = compileStatement(funcDecl.block);
@@ -556,12 +553,12 @@ private Node newStruct( SONTypeStruct obj, Node size) {
556553
private Node compileNewExpr(AST.NewExpr newExpr) {
557554
Type type = newExpr.type;
558555
if (type instanceof Type.TypeArray typeArray) {
559-
SONTypeMemPtr tarray = (SONTypeMemPtr) TYPES.get(getSONTypeName(typeArray));
556+
SONTypeMemPtr tarray = (SONTypeMemPtr) TYPES.get(typeArray.name());
560557
return newArray(tarray._obj,ZERO);
561558
}
562559
else if (type instanceof Type.TypeStruct typeStruct) {
563-
SONTypeStruct tstruct = (SONTypeStruct) TYPES.get(typeStruct.name());
564-
return newStruct(tstruct,con(tstruct.offset(tstruct._fields.length)));
560+
SONTypeMemPtr tptr = (SONTypeMemPtr) TYPES.get(typeStruct.name());
561+
return newStruct(tptr._obj,con(tptr._obj.offset(tptr._obj._fields.length)));
565562
}
566563
else
567564
throw new CompilerException("Unexpected type: " + type);
@@ -701,7 +698,7 @@ private Node compileCallExpr(AST.CallExpr callExpr) {
701698
}
702699

703700
private String makeVarName(Symbol.VarSymbol varSymbol) {
704-
return varSymbol.name + "$" + varSymbol.regNumber;
701+
return varSymbol.name; // + "$" + varSymbol.regNumber;
705702
}
706703

707704
private Node compileStatement(AST.Stmt statement) {
@@ -955,9 +952,12 @@ private Node compileReturn(AST.ReturnStmt returnStmt) {
955952

956953
private Node compileBlock(AST.BlockStmt block) {
957954
Node last = ZERO;
955+
_scope.push(ScopeNode.Kind.Block);
956+
defineScopedVars(block.scope, _scope, _fun);
958957
for (AST.Stmt stmt: block.stmtList) {
959958
last = compileStatement(stmt);
960959
}
960+
_scope.pop();
961961
return last;
962962
}
963963

seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/sontypes/SONTypeFunPtr.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,10 @@ public SONTypeFunPtr(byte nil, SONTypeTuple sig, SONType ret, long fidxs) {
4141
public SONTypeFunPtr makeFrom(int fidx ) { return make((byte)2, _sig,_ret,1L<<fidx ); }
4242

4343
public static SONTypeFunPtr BOT = make((byte)3, SONTypeTuple.BOT, SONType.BOTTOM,-1);
44-
public static SONTypeFunPtr TEST = make((byte)2, SONTypeTuple.TEST, SONTypeInteger.BOT,1);
45-
public static SONTypeFunPtr TEST0 = make((byte)3, SONTypeTuple.TEST, SONTypeInteger.BOT,3);
44+
// public static SONTypeFunPtr TEST = make((byte)2, SONTypeTuple.TEST, SONTypeInteger.BOT,1);
45+
// public static SONTypeFunPtr TEST0 = make((byte)3, SONTypeTuple.TEST, SONTypeInteger.BOT,3);
4646
public static SONTypeFunPtr MAIN = make((byte)3, SONTypeTuple.MAIN, SONTypeInteger.BOT,-1);
47-
public static void gather(ArrayList<SONType> ts) { ts.add(TEST); ts.add(TEST0); ts.add(BOT); ts.add(MAIN); }
47+
public static void gather(ArrayList<SONType> ts) { /* ts.add(TEST); ts.add(TEST0); */ ts.add(BOT); ts.add(MAIN); }
4848

4949
@Override
5050
SONType xmeet(SONType t) {

seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/sontypes/SONTypeMemPtr.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public SONTypeMemPtr(byte nil, SONTypeStruct obj) {
3131
assert obj!=null;
3232
_obj = obj;
3333
}
34-
static SONTypeMemPtr make(byte nil, SONTypeStruct obj) { return new SONTypeMemPtr(nil, obj).intern(); }
34+
public static SONTypeMemPtr make(byte nil, SONTypeStruct obj) { return new SONTypeMemPtr(nil, obj).intern(); }
3535
public static SONTypeMemPtr makeNullable(SONTypeStruct obj) { return make((byte)3, obj); }
3636
public static SONTypeMemPtr make(SONTypeStruct obj) { return new SONTypeMemPtr((byte)2, obj).intern(); }
3737
public SONTypeMemPtr makeFrom(SONTypeStruct obj) { return obj==_obj ? this : make(_nil, obj); }
@@ -47,8 +47,8 @@ public SONTypeMemPtr(byte nil, SONTypeStruct obj) {
4747
public static SONTypeMemPtr TOP = BOT.dual();
4848
public static SONTypeMemPtr NOTBOT = make((byte)2, SONTypeStruct.BOT);
4949

50-
public static SONTypeMemPtr TEST= make((byte)2, SONTypeStruct.TEST);
51-
public static void gather(ArrayList<SONType> ts) { ts.add(NOTBOT); ts.add(BOT); ts.add(TEST); }
50+
//public static SONTypeMemPtr TEST= make((byte)2, SONTypeStruct.TEST);
51+
public static void gather(ArrayList<SONType> ts) { ts.add(NOTBOT); ts.add(BOT); /* ts.add(TEST); */ }
5252

5353
@Override
5454
public SONTypeNil xmeet(SONType t) {

seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/sontypes/SONTypeStruct.java

+8-8
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public SONTypeStruct(String name, Field[] fields) {
3535
public static SONTypeStruct make(String name, Field... fields) { return new SONTypeStruct(name, fields).intern(); }
3636
public static final SONTypeStruct TOP = make("$TOP",new Field[0]);
3737
public static final SONTypeStruct BOT = make("$BOT",new Field[0]);
38-
public static final SONTypeStruct TEST = make("test",new Field[]{Field.TEST});
38+
//public static final SONTypeStruct TEST = make("test",new Field[]{Field.TEST});
3939
// Forward-ref version
4040
public static SONTypeStruct makeFRef(String name) { return make(name, (Field[])null); }
4141
// Make a read-only version
@@ -66,14 +66,14 @@ public static SONTypeStruct makeArray(SONTypeInteger len, int lenAlias, SONType
6666
}
6767

6868
// A pair of self-cyclic types
69-
private static final SONTypeStruct S1F = makeFRef("S1");
70-
private static final SONTypeStruct S2F = makeFRef("S2");
71-
public static final SONTypeStruct S1 = make("S1", Field.make("a", SONTypeInteger.BOT, -1, false), Field.make("s2", SONTypeMemPtr.make((byte)2,S2F),-2, false) );
72-
private static final SONTypeStruct S2 = make("S2", Field.make("b", SONTypeFloat.F64, -3, false), Field.make("s1", SONTypeMemPtr.make((byte)2,S1F),-4, false) );
69+
// private static final SONTypeStruct S1F = makeFRef("S1");
70+
// private static final SONTypeStruct S2F = makeFRef("S2");
71+
// public static final SONTypeStruct S1 = make("S1", Field.make("a", SONTypeInteger.BOT, -1, false), Field.make("s2", SONTypeMemPtr.make((byte)2,S2F),-2, false) );
72+
// private static final SONTypeStruct S2 = make("S2", Field.make("b", SONTypeFloat.F64, -3, false), Field.make("s1", SONTypeMemPtr.make((byte)2,S1F),-4, false) );
73+
//
74+
// private static final SONTypeStruct ARY = makeAry(SONTypeInteger.U32,-1, SONTypeInteger.BOT,-2);
7375

74-
private static final SONTypeStruct ARY = makeAry(SONTypeInteger.U32,-1, SONTypeInteger.BOT,-2);
75-
76-
public static void gather(ArrayList<SONType> ts) { ts.add(TEST); ts.add(BOT); ts.add(S1); ts.add(S2); ts.add(ARY); }
76+
public static void gather(ArrayList<SONType> ts) { /* ts.add(TEST); ts.add(BOT); ts.add(S1); ts.add(S2); ts.add(ARY); */ }
7777

7878
// Find field index by name
7979
public int find(String fname) {

seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/sontypes/SONTypeTuple.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public class SONTypeTuple extends SONType {
1313
public static final SONTypeTuple BOT = new SONTypeTuple(new SONType[0]).intern();
1414
public static final SONTypeTuple TOP = new SONTypeTuple(null).intern();
1515

16-
public static final SONTypeTuple TEST = make(SONTypeInteger.BOT, SONTypeMemPtr.TEST);
16+
//public static final SONTypeTuple TEST = make(SONTypeInteger.BOT, SONTypeMemPtr.TEST);
1717
public static final SONTypeTuple START= make(SONType.CONTROL, SONTypeMem.TOP, SONTypeInteger.BOT);
1818
public static final SONTypeTuple MAIN = make(SONTypeInteger.BOT);
1919
public static final SONTypeTuple RET = make(SONType.CONTROL, SONTypeMem.BOT, SONType.BOTTOM);
@@ -23,7 +23,7 @@ public class SONTypeTuple extends SONType {
2323
public static final SONTypeTuple IF_TRUE = make(new SONType[]{SONType. CONTROL, SONType.XCONTROL});
2424
public static final SONTypeTuple IF_FALSE = make(new SONType[]{SONType.XCONTROL, SONType. CONTROL});
2525

26-
public static void gather(ArrayList<SONType> ts) { ts.add(BOT); ts.add(TEST); ts.add(START); ts.add(MAIN); ts.add(IF_TRUE); }
26+
public static void gather(ArrayList<SONType> ts) { ts.add(BOT); /* ts.add(TEST); */ ts.add(START); ts.add(MAIN); ts.add(IF_TRUE); }
2727

2828
@Override
2929
SONType xmeet(SONType other) {

seaofnodes/src/test/cases/fib/fib.ez

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
func fib(n: Int)->Int {
2+
var i: Int;
3+
var temp=0;
4+
var f1=1;
5+
var f2=1;
6+
i=n;
7+
while( i>1 ){
8+
temp = f1+f2;
9+
f1=f2;
10+
f2=temp;
11+
i=i-1;
12+
}
13+
return f2;
14+
}
15+
16+
func foo()->Int {
17+
return fib(10);
18+
}

seaofnodes/src/test/cases/fib/fib.ir

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
START: [[ ]]
2+
1 Start ____ ____ ____ [[ 3 4 9 16 18 8 5 46 ]] [ Ctrl, #TOP, int]
3+
4+
L8: [[ START ]]
5+
8 fib ____ 1 [[ 10 17 19 20 22 ]] Ctrl
6+
10 $rpc 8 9 [[ 14 ]] $[ALL]
7+
17 $mem 8 16 [[ 14 ]] #BOT
8+
19 n$2 8 18 [[ 25 ]] int
9+
20 #1 8 [[ 37 39 26 41 ]] 1
10+
11+
L46: [[ START ]]
12+
46 foo ____ 1 [[ 48 55 56 57 59 ]] Ctrl
13+
48 $rpc 46 9 [[ 52 ]] $[ALL]
14+
55 $mem 46 16 [[ 59 ]] #BOT
15+
57 #10 46 [[ 59 ]] 10
16+
56 #{ int 46 [[ 59 ]] { int -> int #1}
17+
59 Call 46 55 57 56 [[ 60 ]] Ctrl
18+
19+
LOOP22: [[ L8 L29 ]]
20+
22 Loop ____ 8 29 [[ 39 25 37 26 28 ]] Ctrl
21+
39 Phi_f2$ 22 20 38 [[ 37 14 38 ]] int
22+
25 Phi_i$3 22 19 41 [[ 26 41 ]] int
23+
37 Phi_f1$ 22 20 39 [[ 38 ]] int
24+
26 LT 22 20 25 [[ 28 ]] bool
25+
28 If 22 26 [[ 29 30 ]] [ Ctrl, Ctrl]
26+
27+
L60: [[ L46 ]]
28+
60 CallEnd 59 [[ 61 63 64 ]] [ Ctrl, #BOT, int]
29+
63 $mem 60 [[ 52 ]] #BOT
30+
64 #2 60 [[ 52 ]] int
31+
32+
L30: [[ LOOP22 ]]
33+
30 False 28 [[ 14 ]] Ctrl
34+
14 Return 30 17 39 10 [[ 2 ]] [ Ctrl, #BOT, int]
35+
36+
L29: [[ LOOP22 ]]
37+
29 True 28 [[ 38 41 22 ]] Ctrl
38+
41 Sub 29 25 20 [[ 25 ]] int
39+
38 Add 29 39 37 [[ 39 ]] int
40+
41+
L61: [[ L60 ]]
42+
61 $ctrl 60 [[ 52 ]] Ctrl
43+
52 Return 61 63 64 48 [[ 2 ]] [ Ctrl, #BOT, int]
44+
45+
L2: [[ ]]
46+
2 Stop 14 52 [[ ]] Bot
+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
val fib = {int n ->
2+
int temp=0;
3+
int f1=1;
4+
int f2=1;
5+
int i=n;
6+
while( i>1 ){
7+
temp = f1+f2;
8+
f1=f2;
9+
f2=temp;
10+
i=i-1;
11+
}
12+
return f2;
13+
};
14+
15+
fib(10);

0 commit comments

Comments
 (0)