[Nice-commit] Nice/src/bossa/syntax typecheck.nice,1.127,1.128
Brought to you by:
bonniot
|
From: Artem Gr K. <ar...@us...> - 2005-03-07 20:53:36
|
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) { |