Nice/src/bossa/syntax typecheck.nice,1.127,1.128
Artem Gr Kozarezov <[email protected]>
| Newsgroups | gmane.comp.lang.nice.cvs |
|---|---|
| Message-ID | <[email protected]> |
Update of /cvsroot/nice/Nice/src/bossa/syntax
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11965/src/bossa/syntax
Modified Files:
typecheck.nice
Log Message:
RFE 681385 implemented.
Index: typecheck.nice
===================================================================
RCS file: /cvsroot/nice/Nice/src/bossa/syntax/typecheck.nice,v
retrieving revision 1.127
retrieving revision 1.128
diff -C2 -d -r1.127 -r1.128
*** typecheck.nice 7 Mar 2005 17:10:50 -0000 1.127
--- typecheck.nice 7 Mar 2005 20:52:53 -0000 1.128
***************
*** 54,58 ****
// RFE 681385
- // To debug in jdb use "stop at bossa.syntax.fun:LINE".
if( variable != null ){
let valueType = e.value.type, toType = to.type, varType = variable.type;
--- 54,57 ----
***************
*** 534,537 ****
--- 533,557 ----
}
+ /**
+ * Collect inference information from branches,
+ * so that it can be propagated outwards.
+ */
+ class DeepMemoryRec {
+ MonoSymbol variable;
+ mlsub.typing.Monotype type;
+ toString() = "(" variable "," type ")";
+ }
+ var Stack<Stack<DeepMemoryRec>> deepMemory = new Stack();
+ equals( DeepMemoryRec a, DeepMemoryRec b ) = a.variable == b.variable;
+
+ void populateDeepMemory(MonoSymbol variable, mlsub.typing.Monotype type)
+ {
+ if(deepMemory.size() == 0) return;
+ let branch = deepMemory.peek();
+ let rec = new DeepMemoryRec(variable: variable, type: type);
+ while( branch.removeElement( rec ) ){}
+ branch.push(rec);
+ }
+
typecheck(IfExp e)
{
***************
*** 546,549 ****
--- 566,573 ----
enterBlock();
+ let Stack<DeepMemoryRec> ifBranchInference = new Stack();
+ let Stack<DeepMemoryRec> elseBranchInference = new Stack();
+ deepMemory.push( elseBranchInference );
+
try{
?List<MonoSymbol> notNullInThen, notNullInElse;
***************
*** 551,554 ****
--- 575,580 ----
?List<(MonoSymbol, mlsub.typing.Monotype)> instanceofInElse;
+ deepMemory.push( ifBranchInference );
+
try {
(notNullInThen, notNullInElse) = nullnessInfo(condition);
***************
*** 576,579 ****
--- 602,606 ----
// which is good when calling the compiler repeatedly from the same JVM.
enterElse();
+ let got = deepMemory.pop(); assert got == ifBranchInference;
}
***************
*** 598,601 ****
--- 625,629 ----
finally{
exitIf();
+ let got = deepMemory.pop(); assert got == elseBranchInference;
}
***************
*** 605,608 ****
--- 633,656 ----
"\nthen: " + thenExp.getType() +
"\nelse: " + elseExp.getType());
+
+ // Check if we can propagate some of the type inference information outwards.
+ if(ifBranchInference.size() != 0 || elseBranchInference.size() != 0)
+ ifPropagation(e, ifBranchInference, elseBranchInference);
+ }
+
+ void ifPropagation(IfExp e, Stack<DeepMemoryRec> ifBranchInference, Stack<DeepMemoryRec> elseBranchInference){
+ let condition = e.condition;
+ if(! (condition instanceof bossa.syntax.CallExp) || ! condition.isCallTo("==")) return;
+ if(condition.arguments.size() != 2) return;
+ let argle = condition.arguments.get(0); let leNull = argle.value.isNull();
+ let argri = condition.arguments.get(1); let riNull = argri.value.isNull();
+ if((leNull || riNull) && leNull != riNull){
+ if(e.elseExp instanceof bossa.syntax.VoidConstantExp && ifBranchInference.size() != 0){
+ let arg = leNull ? argri.value : argle.value;
+ let variable = localVariable( arg ); if( null == variable ) return;
+ for(rec : ifBranchInference) if(variable == rec.variable)
+ variable.setVarType( rec.type, otherBranch: variable.type, out: variable.type );
+ }
+ }
}
***************
*** 622,625 ****
--- 670,674 ----
{
variable.type = now;
+ populateDeepMemory( variable, now );
if (overrideOut != null)
{
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click