Skip to content

Commit

Permalink
Improved type inference
Browse files Browse the repository at this point in the history
  • Loading branch information
kevinlano authored Aug 14, 2024
1 parent 0794523 commit 81e666c
Show file tree
Hide file tree
Showing 6 changed files with 336 additions and 36 deletions.
12 changes: 6 additions & 6 deletions BSystemTypes.java
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ else if (ename.equals("boolean"))
res = res + " return _results_" + oldindex + ";\n }\n\n";

// Version for maps:
res = res + " public static Map select_" + oldindex + "(Map _l";
res = res + " public static HashMap select_" + oldindex + "(Map _l";

for (int i = 0; i < pars.size(); i++)
{ Attribute par = (Attribute) pars.get(i);
Expand All @@ -186,7 +186,7 @@ else if (ename.equals("boolean"))
}
res = res + ")\n";
res = res + " { // Implements: " + left + "->select(" + var + " | " + pred + ")\n" +
" Map _results_" + oldindex + " = new java.util.HashMap();\n" +
" HashMap _results_" + oldindex + " = new HashMap();\n" +
" java.util.Set _keys = _l.keySet();\n" +
" for (Object _i : _keys)\n";
if (ename.equals("int") || "Integer".equals(tname))
Expand Down Expand Up @@ -773,15 +773,15 @@ else if (ename.equals("boolean"))
res = res + " return _results_" + oldindex + ";\n }\n\n";

// Also need a Map version:
res = res + " public static Map collect_" + oldindex + "(Map _l";
res = res + " public static HashMap collect_" + oldindex + "(Map _l";
for (int i = 0; i < pars.size(); i++)
{ Attribute par = (Attribute) pars.get(i);
res = res + "," + par.getType().getJava() + " " + par.getName();
}
res = res + ")\n";
res = res +
" { // implements: " + left + "->collect( " + var + " | " + exp + " )\n" +
" Map _results_" + oldindex + " = new HashMap();\n" +
" HashMap _results_" + oldindex + " = new HashMap();\n" +
" java.util.Set _keys = _l.keySet();\n" +
" for (Object _i : _keys)\n" +
" { " + tname + " " + var + " = (" + tname + ") _l.get(_i);\n" +
Expand Down Expand Up @@ -1419,7 +1419,7 @@ else if (ename.equals("boolean"))

/* Version for maps: */

res = res + " public static Map reject_" + oldindex + "(Map _l";
res = res + " public static HashMap reject_" + oldindex + "(Map _l";

for (int i = 0; i < pars.size(); i++)
{ Attribute par = (Attribute) pars.get(i);
Expand All @@ -1429,7 +1429,7 @@ else if (ename.equals("boolean"))
}
res = res + ")\n";
res = res + " { // Implements: " + left + "->reject(" + var + " | " + pred + ")\n" +
" Map _results_" + oldindex + " = new java.util.HashMap();\n" +
" HashMap _results_" + oldindex + " = new HashMap();\n" +
" java.util.Set _keys = _l.keySet();\n" +
" for (Object _i : _keys)\n";
if (ename.equals("int") || "Integer".equals(tname))
Expand Down
190 changes: 169 additions & 21 deletions BinaryExpression.java
Original file line number Diff line number Diff line change
Expand Up @@ -3877,8 +3877,35 @@ else if ("|sortedBy".equals(operator))
elementType = scope.elementType;
multiplicity = ModelElement.MANY;
}
else if (operator.equals("->collect") ||
operator.equals("->unionAll") ||
else if (operator.equals("->collect"))
{ if (left.isCollection() || left.isMap()) { }
else
{ System.err.println("!! Left argument of " + operator +
" must be a collection or map");
left.setType(new Type("Sequence", null));

if (left instanceof BasicExpression)
{ String vname = ((BasicExpression) left).basicString();
vartypes.put(vname, left.getType());
}
}

Type tl = (Type) vartypes.get(left + "");

if (left.isMap() || Type.isMapType(tl))
{ elementType = right.getType();
type = new Type("Map", null);
type.setElementType(elementType);
if (tl == null) { tl = tleft; }
type.setKeyType(tleft.getKeyType());
}
else
{ elementType = right.getType();
type = new Type("Sequence", null);
type.setElementType(elementType);
} // NOT sorted
}
else if (operator.equals("->unionAll") ||
operator.equals("->intersectAll") ||
operator.equals("->concatenateAll") ||
operator.equals("->any"))
Expand Down Expand Up @@ -3910,8 +3937,78 @@ else if (operator.equals("->collect") ||
type = left.elementType;
}
}
else if (operator.equals("|C") ||
"|unionAll".equals(operator) ||
else if (operator.equals("|C"))
{ BinaryExpression lexp = (BinaryExpression) left;
Expression scope = lexp.right;
Expression vbl = lexp.left;

Type vblType = (Type) vartypes.get(vbl + "");

Type scopetype = (Type) vartypes.get(scope + "");

if (scope.isCollection() || scope.isMap())
{ if (Type.isVacuousType(scope.elementType))
{ System.err.println("!! No element type for " + scope);
Type tt = (Type) vartypes.get(scope + "");
if (tt != null &&
!Type.isVacuousType(tt.elementType))
{ scope.setElementType(tt.elementType);
vbl.setType(tt.elementType);
}
else if (vblType != null)
{ scope.setElementType(vblType);
vbl.setType(vblType);
}

System.out.println(">> Set " + scope + " element type to " + scope.getElementType());
}
}
else if (Type.isMapType(scopetype) ||
Type.isCollectionType(scopetype))
{ if (Type.isVacuousType(scope.elementType))
{ System.err.println("!! No element type for " + scope);
if (scopetype != null &&
!Type.isVacuousType(scopetype.elementType))
{ scope.setElementType(scopetype.elementType);
vbl.setType(scopetype.elementType);
}
else if (vblType != null)
{ scope.setElementType(vblType);
vbl.setType(vblType);
}

scope.setType(scopetype);

System.out.println(">> Set " + this + " element type to " + scope.getElementType());
}
}
else
{ System.err.println("!! Left argument of " + operator +
" must be a collection");
scope.setType(new Type("Sequence", null));

if (scope instanceof BasicExpression)
{ String vname = ((BasicExpression) scope).basicString();
vartypes.put(vname, scope.getType());
}
}

if (scope.isMap() || Type.isMapType(scopetype))
{ elementType = right.getType();
type = new Type("Map", null);
type.setElementType(elementType);
if (scopetype == null) { scopetype = scope.getType(); }
type.setKeyType(scopetype.getKeyType());

// JOptionPane.showInputDialog(">> Type of " + this + " is " + type);
}
else
{ elementType = right.getType();
type = new Type("Sequence", null);
type.setElementType(elementType);
} // NOT sorted
}
else if ("|unionAll".equals(operator) ||
"|intersectAll".equals(operator) ||
"|concatenateAll".equals(operator))
{ BinaryExpression lexp = (BinaryExpression) left;
Expand Down Expand Up @@ -4314,7 +4411,7 @@ else if ("->restrict".equals(operator) ||
{ if (tleft != null)
{ type = tleft;
elementType = left.elementType;
}
} // sorted if left is sorted
else
{ type = new Type("Map", null); }

Expand Down Expand Up @@ -4556,7 +4653,45 @@ else if (operator.equals("\\/") ||
Type lftype = left.getType();
Type rtype = right.getType();

if (left.isMap() && !right.isMap())
Type letype = left.getElementType();
Type retype = right.getElementType();

if (left.isMap() && right.isMap())
{ if (operator.equals("\\/") ||
operator.equals("->union") ||
operator.equals("->symmetricDifference") ||
operator.equals("->intersection") ||
operator.equals("/\\"))
{ Vector etypes = new Vector();
etypes.add(left);
etypes.add(right);
elementType = Type.determineElementType(etypes);
type = new Type("Map", null);
type.setSorted(lftype.isSorted());
type.setKeyType(lftype.getKeyType());
type.setElementType(elementType);
}
else
{ type = new Type("boolean", null); }
}
else if (left.isCollection() && right.isCollection())
{ if (operator.equals("\\/") ||
operator.equals("->union") ||
operator.equals("->symmetricDifference") ||
operator.equals("->intersection") ||
operator.equals("/\\"))
{ Vector etypes = new Vector();
etypes.add(left);
etypes.add(right);
elementType = Type.determineElementType(etypes);
type = new Type(lftype.getName(), null);
type.setSorted(lftype.isSorted());
type.setElementType(elementType);
}
else
{ type = new Type("boolean", null); }
}
else if (left.isMap() && !right.isMap())
{ System.err.println("!! RHS of " + this +
" must be map");

Expand All @@ -4566,10 +4701,10 @@ else if (operator.equals("\\/") ||
right.setType(rtype);

if (operator.equals("\\/") ||
operator.equals("->union") ||
operator.equals("->symmetricDifference") ||
operator.equals("->intersection") ||
operator.equals("/\\"))
operator.equals("->union") ||
operator.equals("->symmetricDifference") ||
operator.equals("->intersection") ||
operator.equals("/\\"))
{ type = new Type("Map", null);
elementType = left.elementType;
type.setKeyType(lftype.getKeyType());
Expand Down Expand Up @@ -4658,9 +4793,10 @@ else if (!left.isCollection() && right.isCollection())
vartypes.put(vname, left.getType());
}
}
else
else if (!left.isCollection() &&
!left.isMap())
{ System.err.println("!! Arguments of " + this +
" must be collections");
" must be collections/maps");
Type ltype = left.getType();

if (ltype.getAlias() != null &&
Expand Down Expand Up @@ -5586,8 +5722,8 @@ else if (operator.equals("->includes") ||
{ }
else
{ System.err.println("!! TYPE ERROR: LHS of " + this + " must be a collection");
JOptionPane.showMessageDialog(null, "LHS of " + this + " must be a collection!",
"Type error", JOptionPane.ERROR_MESSAGE);
// JOptionPane.showMessageDialog(null, "LHS of " + this + " must be a collection!",
// "Type error", JOptionPane.ERROR_MESSAGE);
} // deduce type of one side from that of other

if (tright == null && tleft != null)
Expand Down Expand Up @@ -6081,23 +6217,26 @@ private void tcCollect(Type tleft, Type tright, Entity eright)
restype.keyType = tleft.keyType;
restype.elementType = tright;
type = restype;
elementType = tright;
elementType = tright;

// JOptionPane.showInputDialog("Type of " + this +
// " is " + type);
return;
}
else if (collectleft.isMultiple())
{ }
else
{ System.err.println("!!! TYPE ERROR: LHS of collect must be a collection! " + this);
JOptionPane.showMessageDialog(null, "LHS must be a collection: " + this,
"Type error", JOptionPane.ERROR_MESSAGE);
// JOptionPane.showMessageDialog(null, "LHS must be a collection: " + this,
// "Type error", JOptionPane.ERROR_MESSAGE);
// type = null;
// return;
}

if (tright == null)
{ System.err.println("!!! TYPE ERROR: No type for collect RHS: " + this);
JOptionPane.showMessageDialog(null, "ERROR: No type for collect RHS: " + this,
"Type error", JOptionPane.ERROR_MESSAGE);
// JOptionPane.showMessageDialog(null, "ERROR: No type for collect RHS: " + this,
// "Type error", JOptionPane.ERROR_MESSAGE);
return;
}

Expand Down Expand Up @@ -6155,8 +6294,8 @@ private void tcMathOps(Type tleft, Type tright,

System.err.println("! Warning!: arguments must be numeric in: " + this + " Deduced type: " + type);
if (type == null)
{ JOptionPane.showMessageDialog(null, "Arguments not numeric in: " + this,
"Type error", JOptionPane.ERROR_MESSAGE);
{ // JOptionPane.showMessageDialog(null, "Arguments not numeric in: " + this,
// "Type error", JOptionPane.ERROR_MESSAGE);
}
}

Expand Down Expand Up @@ -20088,6 +20227,15 @@ public Expression simplifyOCL()
Expression lexpr = left.simplifyOCL();
Expression rexpr = right.simplifyOCL();

if ("->union".equals(operator) &&
lexpr instanceof SetExpression &&
rexpr instanceof SetExpression)
{ // merge the literal sets/sequences/maps
SetExpression res =
SetExpression.mergeSetExpressions((SetExpression) lexpr,
(SetExpression) rexpr);
return res;
}

if (operator.equals("|"))
{ BinaryExpression arg = (BinaryExpression) left;
Expand Down
14 changes: 13 additions & 1 deletion Compiler2.java
Original file line number Diff line number Diff line change
Expand Up @@ -11116,11 +11116,23 @@ public static void main(String[] args)

// c.nospacelexicalanalysis("(a[i][j]).f(1)");
// c.nospacelexicalanalysis("(!a).f(1)");
c.nospacelexicalanalysis("(OclFile[\"SYSOUT\"]).println(x)");
// c.nospacelexicalanalysis("(OclFile[\"SYSOUT\"]).println(x)");

c.nospacelexicalanalysis("Map{ \"Name\" |-> Sequence{\"Braund, Mr. Owen Harris\"}->union(Sequence{\"Allen, Mr. William Henry\"}->union(Sequence{ \"Bonnell, Miss. Elizabeth\" })) }->union(Map{ \"Age\" |-> Sequence{22}->union(Sequence{35}->union(Sequence{ 58 })) }->union(Map{ \"Sex\" |-> Sequence{\"male\"}->union(Sequence{\"male\"}->union(Sequence{ \"female\" })) }->union(Map{ \"Fare\" |-> Sequence{102.0}->union(Sequence{99.0}->union(Sequence{ 250.0 })) }) ) )");

Expression zz = c.parseExpression();

System.out.println(zz);

zz.typeCheck(new Vector(), new Vector(), new Vector(), new Vector());

Expression pp = zz.simplifyOCL();

System.out.println(pp);

pp.typeCheck(new Vector(), new Vector(), new Vector(), new Vector());

System.out.println(">>> " + pp.getType());

// Compiler2 ccx = new Compiler2();
// ccx.nospacelexicalanalysis("x : int");
Expand Down
Loading

0 comments on commit 81e666c

Please sign in to comment.