From fbb6cebf1dffff37067518b765cc2ee6e8d19a62 Mon Sep 17 00:00:00 2001 From: buraq Date: Tue, 2 Sep 2003 14:42:58 +0000 Subject: using Switch in translation of automata code cleanup, removed many obsoleted methods. --- .../scalac/transformer/matching/Autom2Scala.java | 234 ++----- .../scalac/transformer/matching/CodeFactory.java | 2 +- .../transformer/matching/LeftTracerInScala.java | 69 +- .../transformer/matching/PatternNodeCreator.java | 82 +-- .../transformer/matching/RightTracerInScala.java | 780 ++++++++++----------- .../transformer/matching/SequenceMatcher.java | 3 +- .../transformer/matching/WordAutomInScala.java | 8 +- 7 files changed, 530 insertions(+), 648 deletions(-) diff --git a/sources/scalac/transformer/matching/Autom2Scala.java b/sources/scalac/transformer/matching/Autom2Scala.java index 734ee8b59c..abe5a6b35a 100644 --- a/sources/scalac/transformer/matching/Autom2Scala.java +++ b/sources/scalac/transformer/matching/Autom2Scala.java @@ -19,6 +19,8 @@ import ch.epfl.lamp.util.Position; public class Autom2Scala { + protected boolean optimize = true; + static final Name HASNEXT = Name.fromString("hasnext"); static final Name CURRENT_ELEM = Name.fromString("cur"); @@ -27,32 +29,25 @@ public class Autom2Scala { DetWordAutom dfa; protected CodeFactory cf; - Vector freeVars; - Vector mdefs; - //Tree matcherDef; - //Tree matcherSwitch; + //Vector freeVars; + //Vector mdefs; Definitions defs; TreeGen gen; - /** owner of the pattern matching expression - */ + /** owner of the pattern matching expression */ protected Symbol owner; - /** symbol of the matcher fun - */ + /** symbol of the matcher fun */ Symbol funSym; - /** symbol of the iterator ( scala.SequenceIterator ) - */ + /** symbol of the iterator ( scala.SequenceIterator ) */ Symbol iterSym; - /** symbol of the switching result ( scala.Int ) - */ + /** symbol of the switching result ( scala.Int ) */ Symbol resultSym; - /** symbol of the state variable ( scala.Int ) - */ + /** symbol of the state variable ( scala.Int ) */ Symbol stateSym; protected Type elementType; @@ -62,11 +57,10 @@ public class Autom2Scala { String funSymName; Symbol newFunSym( String prefix ) { - return new TermSymbol( /*Kinds.FUN, */ - pos, - cf.fresh.newName( prefix ), - owner, - 0); + return new TermSymbol( pos, + cf.fresh.newName( prefix ), + owner, + 0); } Symbol newParam( String prefix ) { @@ -110,29 +104,26 @@ public class Autom2Scala { this.stateSym = newParam("q") .setType( defs.INT_TYPE ) ; - this.resultSym = new TermSymbol( /*Kinds.VAR,*/ - pos, - cf.fresh.newName("swRes"), - owner, - 0 ) + this.resultSym = new TermSymbol( pos, + cf.fresh.newName("swRes"), + owner, + 0 ) .setType( defs.INT_TYPE ) ; this.funSym .setType( new Type.MethodType( new Symbol[] { iterSym, stateSym }, defs.INT_TYPE )); - this.curSym = new TermSymbol( /*Kinds.VAL, */ - pos, + this.curSym = new TermSymbol( pos, CURRENT_ELEM, - funSym,//clazzOwner, + funSym, 0) .setType( elementType ); - this.hasnSym = new TermSymbol( /*Kinds.VAL, */ - pos, - HASNEXT, - funSym,//clazzOwner, - 0) + this.hasnSym = new TermSymbol( pos, + HASNEXT, + funSym, + 0) .setType( defs.BOOLEAN_TYPE ); } @@ -150,9 +141,9 @@ public class Autom2Scala { this.pos = Position.FIRSTPOS; this.cf = cf; this.am = new AlgebraicMatcher( cf.unit, cf.infer ); - this.mdefs = new Vector(); + //this.mdefs = new Vector(); - this.freeVars = new Vector(); + //this.freeVars = new Vector(); } public Tree theDefDef; @@ -161,23 +152,23 @@ public class Autom2Scala { Symbol hasnSym; // overridden in TracerInScala - Tree loadCurrentElem( Tree body ) { - return cf.Block( Position.FIRSTPOS, new Tree[] { - cf.gen.ValDef( Position.FIRSTPOS, - this.hasnSym, - cf._hasNext( _iter() ) ), - cf.gen.ValDef( Position.FIRSTPOS, - this.curSym, - cf.If( _ref( hasnSym ),//cf._hasNext( _iter() ), - cf._next( _iter() ), - cf.ignoreValue( curSym.type() ))), - body }, - body.type() ); - } + Tree loadCurrentElem( Tree body ) { + return cf.Block( Position.FIRSTPOS, new Tree[] { + cf.gen.ValDef( Position.FIRSTPOS, + this.hasnSym, + cf._hasNext( _iter() ) ), + cf.gen.ValDef( Position.FIRSTPOS, + this.curSym, + cf.If( _ref( hasnSym ),//cf._hasNext( _iter() ), + cf._next( _iter() ), + cf.ignoreValue( curSym.type() ))), + body }, + body.type() ); + } - Tree currentElem() { - return gen.Ident(Position.FIRSTPOS, curSym); - } + Tree currentElem() { + return gen.Ident(Position.FIRSTPOS, curSym); + } Tree currentMatches( Label label ) { return _cur_eq( _iter(), label ); @@ -191,45 +182,17 @@ public class Autom2Scala { /** creates an int variable */ Tree _intvar( Symbol sym, Tree init ) { - return gen.ValDef( pos, sym, init ); - /* - Kinds.VAR, - 0, - sym.name, - gen.mkType(pos, defs.INT_TYPE), - init) - .setType( defs.UNIT_TYPE ) - .symbol( sym );*/ + return gen.ValDef( pos, sym, init ); } - /** ` = val' - Tree code_assignInt( Symbol sym, Integer val ){ - return make.Assign(pos, - code_ref( sym ), - gen.mkIntLit(Position.FIRSTPOS, val )) - .setType( defs.UNIT_TYPE ); - } - */ - - - // the caller needs to set the type ! Tree _applyNone( Tree arg ) { return cf.make.Apply(pos, arg, Tree.EMPTY_ARRAY/*None*/ ); } - - - - - - - Tree _scala() { - // return gen.mkId( defs.SCALA ) // try this - return gen.Ident(pos, defs.SCALA ); /*make.Ident( pos, - SCALA_N ) - .setType( defs.SCALA.type() ).symbol( defs.SCALA );*/ - } + Tree _scala() { + return gen.Ident(pos, defs.SCALA ); + } /** `' @@ -246,21 +209,34 @@ public class Autom2Scala { /** body of the matcherDefFun */ - public Tree code_body() { - Tree body = code_fail(); // never reached at runtime. - - // state [ nstates-1 ] is the dead state, so we skip it - - //`if( state == q ) else {...}' - for( int i = dfa.nstates-2; i >= 0; i-- ) { - body = code_state( i, body ); - } + public Tree code_body_NEW() { + int[] tags = new int[dfa.nstates]; + Tree[] bodies = new Tree[dfa.nstates]; + for( int i = 0; i= 0; i-- ) + res = cf.If( cf.Equals( _state(), gen.mkIntLit( cf.pos, i )), + bodies[ i ] , + res ); - return loadCurrentElem( body ); + return loadCurrentElem( res ); - } + } Tree _cur_eq( Tree iter, Label label ) { switch( label ) { @@ -274,15 +250,10 @@ public class Autom2Scala { AlgebraicMatcher am; + /* void handleVars( ) { } - - // returns a Tree whose type is boolean. - Tree handleBody( Object help ) { - // don't care about free vars - return gen.mkBooleanLit( Position.FIRSTPOS, true ); - } - + */ // calling the /*AlgebraicMatcher*/PatternMatcher here Tree _cur_match( Tree pat ) { //System.out.println("calling algebraic matcher on type:"+pat.type); @@ -295,7 +266,7 @@ public class Autom2Scala { (CaseDef) cf.make.CaseDef( pat.pos, pat, Tree.Empty, - handleBody( freeVars )), + gen.mkBooleanLit( Position.FIRSTPOS, true )), (CaseDef) cf.make.CaseDef( pat.pos, cf.make.Ident(pat.pos, Names.WILDCARD) //.setSymbol( Symbol.NONE ) @@ -336,60 +307,8 @@ public class Autom2Scala { } */ - Tree wrapStateBody0( Tree stateBody, - Tree elseBody, - int i ) { - return cf.If( cf.Equals( _state(), gen.mkIntLit(Position.FIRSTPOS, i )), - stateBody , - elseBody ); - } - - // `val cur := iter.next()' - - Tree wrapStateBody( Tree stateBody, - Tree elseBody, - Tree runFinished, int i ) { - stateBody = cf.If( cf.Negate( _ref( hasnSym )),//cf._not_hasNext( _iter() ), - runFinished, - stateBody);/* - cf.Block( stateBody.pos, - new Tree[] { - loadCurrentElem(), - stateBody}, - stateBody.type()) );*/ - - return wrapStateBody0( stateBody , elseBody, i ); - } - - /** return code for state i of the dfa - */ - Tree code_state( int i, Tree elseBody ) { - - Tree runFinished; // holds result of the run - int finalSwRes; - - runFinished = run_finished( i ); - - - if( dfa.isSink( i ) ) // state won't change anymore (binding?) - return cf.If( cf.Equals( _state(), gen.mkIntLit(Position.FIRSTPOS, i )), - runFinished, - elseBody ); - - - Tree stateBody ; // action(delta) for one particular label/test - - // default action (fail if there is none) - - stateBody = code_delta( i, Label.DefaultLabel); - - /* - if( stateBody == null ) - stateBody = code_fail(); - */ - - // transitions of state i - + Tree code_state_NEW( int i ) { + Tree stateBody = code_delta(i, Label.DefaultLabel ); HashMap trans = ((HashMap[])dfa.deltaq)[ i ]; for( Iterator labs = dfa.labels.iterator(); labs.hasNext() ; ) { @@ -406,10 +325,7 @@ public class Autom2Scala { stateBody); } } - return wrapStateBody( stateBody, - elseBody, - runFinished, - i ); + return stateBody; } /** code to reference a variable diff --git a/sources/scalac/transformer/matching/CodeFactory.java b/sources/scalac/transformer/matching/CodeFactory.java index 3fc83f9a17..96c3cd66ee 100644 --- a/sources/scalac/transformer/matching/CodeFactory.java +++ b/sources/scalac/transformer/matching/CodeFactory.java @@ -20,7 +20,7 @@ import Tree.*; class CodeFactory extends PatternTool { - private int pos = Position.FIRSTPOS ; + public int pos = Position.FIRSTPOS ; static final Name TUPLE2_N = Name.fromString("scala.Tuple2"); diff --git a/sources/scalac/transformer/matching/LeftTracerInScala.java b/sources/scalac/transformer/matching/LeftTracerInScala.java index 12db42297d..c79fa113e3 100644 --- a/sources/scalac/transformer/matching/LeftTracerInScala.java +++ b/sources/scalac/transformer/matching/LeftTracerInScala.java @@ -21,7 +21,6 @@ public class LeftTracerInScala extends TracerInScala { */ Symbol accumSym; - Type _accumType( Type elemType ) { return cf.SeqTraceType( elemType ); } @@ -41,9 +40,6 @@ public class LeftTracerInScala extends TracerInScala { } - - // move WordAutom down. - Vector helpVarDefs; Symbol makeHelpVar( Symbol realVar ) { @@ -77,33 +73,6 @@ public class LeftTracerInScala extends TracerInScala { return helpVar; } - void handleVars( Vector freeVars ) { - for(Iterator it = freeVars.iterator(); it.hasNext(); ) { - makeHelpVar( (Symbol) it.next() ); - } - } - - /** returns a Tree whose type is boolean. - * now we care about free vars - */ - /* - Tree handleBody( HashMap helpMap ) { - Tree res[] = new Tree[ helpMap.keySet().size() + 1 ]; - int j = 0; - for( Iterator it = helpMap.keySet().iterator(); it.hasNext(); ) { - Symbol vsym = (Symbol) it.next(); - Symbol hv = (Symbol) helpMap.get( vsym ); - hv.type( cf.SeqListType( elementType ) ) ; - Tree refv = gen.Ident(Position.FIRSTPOS, vsym); - Tree refhv = gen.Ident(Position.FIRSTPOS, hv); - res[ j++ ] = gen.Assign( refhv, refv ); - } - - res[ j ] = super.handleBody( freeVars ); // just `true' - - return cf.Block(Position.FIRSTPOS, res, res[j].type() ); - } - */ protected void initializeSyms() { funSymName = "leftTracer"; @@ -127,7 +96,6 @@ public class LeftTracerInScala extends TracerInScala { owner, 0 ) .setType( _accumType( elementType ) ) ; - } // should throw an exception here really, e.g. MatchError @@ -136,8 +104,6 @@ public class LeftTracerInScala extends TracerInScala { } - - /** returns translation of transition with label from i. * returns null if there is no such transition(no translation needed) */ @@ -163,6 +129,21 @@ public class LeftTracerInScala extends TracerInScala { } + public Tree code_body() { + + Tree body = code_fail(); // never reached at runtime. + + // state [ nstates-1 ] is the dead state, so we skip it + + //`if( state == q ) else {...}' + for( int i = dfa.nstates-2; i >= 0; i-- ) { + body = code_state( i, body ); + } + + return loadCurrentElem( body ); + + } + /** return code for state i of the dfa SAME AS IN SUPER, ONLY SINK IS GONE */ Tree code_state( int i, Tree elseBody ) { @@ -189,22 +170,20 @@ public class LeftTracerInScala extends TracerInScala { Object label = labs.next(); Integer next = (Integer) trans.get( label ); - Tree action = code_delta( i, (Label) label ); if( action != null ) { - stateBody = cf.If( _cur_eq( _iter(), (Label) label ), action, stateBody); } } - - return wrapStateBody( stateBody, - elseBody, - runFinished, - i ); - + stateBody = cf.If( cf.Negate( _ref( hasnSym )), + runFinished, + stateBody ); + return cf.If( cf.Equals( _state(), gen.mkIntLit(cf.pos, i )), + stateBody , + elseBody ); } Tree[] getTrace() { @@ -302,18 +281,16 @@ public class LeftTracerInScala extends TracerInScala { (CaseDef) cf.make.CaseDef( pat.pos, pat, Tree.Empty, - handleBody( helpMap )), + gen.mkBooleanLit( cf.pos, true )), (CaseDef) cf.make.CaseDef( pat.pos, cf.make.Ident(pat.pos, Names.WILDCARD) //DON'T .setSymbol( Symbol.NONE ) ! .setType(pat.type()), Tree.Empty, - gen.mkBooleanLit(Position.FIRSTPOS, false)) }, + gen.mkBooleanLit( cf.pos, false)) }, false ); Tree res = am.toTree().setType( defs.BOOLEAN_TYPE ); - //System.out.println("freeVars: "+freeVars); - return res; } diff --git a/sources/scalac/transformer/matching/PatternNodeCreator.java b/sources/scalac/transformer/matching/PatternNodeCreator.java index 6e62f54751..909f44a7ee 100644 --- a/sources/scalac/transformer/matching/PatternNodeCreator.java +++ b/sources/scalac/transformer/matching/PatternNodeCreator.java @@ -13,7 +13,7 @@ import Tree.*; import java.util.Vector ; /** PatternNode factory. - * we inherit the globals from PatternTool + * we inherit the globals from PatternTool. */ public class PatternNodeCreator extends PatternTool { @@ -26,46 +26,36 @@ public class PatternNodeCreator extends PatternTool { return node; } public SeqContainerPat SeqContainerPat(int pos, Type type, Tree seqpat) { - Symbol sym = newVar(Position.FIRSTPOS, type); + Symbol sym = newVar(Position.NOPOS, type); SeqContainerPat node = new SeqContainerPat(sym, seqpat); node.pos = pos; node.type = type; return node; } - /* MY CODE - public static SequencePat SequencePat(int pos, Tree seqpat, int case_ix) { - SequencePat node = new SequencePat( seqpat, case_ix ); - node.pos = pos; - return node; - } - */ - public static DefaultPat DefaultPat(int pos, Type type) { - DefaultPat node = new DefaultPat(); - node.pos = pos; - node.type = type; - return node; - } - - public ConstrPat ConstrPat(int pos, Type type) { - ConstrPat node = new ConstrPat(newVar(pos, type)); - node.pos = pos; - node.type = type; - return node; - } - - public static ConstantPat ConstantPat(int pos, Type type, Object value) { - ConstantPat node = new ConstantPat( value ); - node.pos = pos; - node.type = type; - return node; - } - - public static VariablePat VariablePat(int pos, Tree tree) { - VariablePat node = new VariablePat( tree ); - node.pos = pos; - node.type = tree.type; - return node; - } + public static DefaultPat DefaultPat(int pos, Type type) { + DefaultPat node = new DefaultPat(); + node.pos = pos; + node.type = type; + return node; + } + public ConstrPat ConstrPat(int pos, Type type) { + ConstrPat node = new ConstrPat(newVar(pos, type)); + node.pos = pos; + node.type = type; + return node; + } + public static ConstantPat ConstantPat(int pos, Type type, Object value) { + ConstantPat node = new ConstantPat( value ); + node.pos = pos; + node.type = type; + return node; + } + public static VariablePat VariablePat(int pos, Tree tree) { + VariablePat node = new VariablePat( tree ); + node.pos = pos; + node.type = tree.type; + return node; + } // factories @@ -75,13 +65,11 @@ public class PatternNodeCreator extends PatternTool { node.type = type; return node; } - public Body Body(int pos, ValDef[] bound, Tree guard, Tree body) { Body node = new Body(new ValDef[][]{bound}, new Tree[]{guard}, new Tree[]{body}); node.pos = pos; return node; } - public TermSymbol newVar(int pos, Name name, Type type) { TermSymbol sym = new TermSymbol(pos, name, owner, 0); sym.setType(type); @@ -89,20 +77,16 @@ public class PatternNodeCreator extends PatternTool { //System.out.println("owner: "+sym.owner()); return sym; } - public TermSymbol newVar(int pos, Type type) { return newVar(pos, fresh.newName("temp"), type); } - /** the owner of the variable symbols that might be create - */ - Symbol owner; - - public PatternNodeCreator( Unit unit, Infer infer, Symbol owner ) { - super( unit, infer ); - assert owner != null; - this.owner = owner; - } - + /** the owner of the variable symbols that might be created */ + Symbol owner; + public PatternNodeCreator( Unit unit, Infer infer, Symbol owner ) { + super( unit, infer ); + assert owner != null; + this.owner = owner; + } } diff --git a/sources/scalac/transformer/matching/RightTracerInScala.java b/sources/scalac/transformer/matching/RightTracerInScala.java index 0911f7990e..38797368c5 100644 --- a/sources/scalac/transformer/matching/RightTracerInScala.java +++ b/sources/scalac/transformer/matching/RightTracerInScala.java @@ -19,468 +19,468 @@ import ch.epfl.lamp.util.Position; public class RightTracerInScala extends TracerInScala { - //Scope scp; - //Symbol vars[]; + //Scope scp; + //Symbol vars[]; - Vector seqVars; - Vector allVars; + Vector seqVars; + Vector allVars; - Matcher _m; + Matcher _m; - // Symbol funSym; + // Symbol funSym; - Symbol elemSym; - Symbol targetSym; + Symbol elemSym; + Symbol targetSym; HashMap helpMap2 ; - Vector helpVarDefs; - - - /** translate right tracer to code - * @param dfa determinized left tracer - * @param left nondeterm. left tracer - * @param cf ... - * @param pat ? - * @param elementType ... - */ - public RightTracerInScala( DetWordAutom dfa, - NondetWordAutom left, - Matcher m, - CodeFactory cf, - Tree pat, - Type elementType ) { - super( dfa, elementType, m.owner, cf ); - this._m = m; - - Vector seqVars = new Vector(); - - for( int j = 0; j < left.nstates; j++ ) { - if( left.qbinders[ j ] != null ) - for( Iterator it = left.qbinders[ j ].iterator(); - it.hasNext() ; ) { - Symbol varSym = (Symbol) it.next(); - - if( !seqVars.contains( varSym ) ) - seqVars.add( varSym ); - } - } - - this.seqVars = seqVars; - this.allVars = CollectVariableTraverser.collectVars( pat ); - - helpMap2 = new HashMap(); - helpVarDefs = new Vector(); - - for( Iterator it = seqVars.iterator(); it.hasNext(); ) { - makeHelpVar( (Symbol) it.next() ); - } - - for( Iterator it = allVars.iterator(); it.hasNext(); ) { - Symbol varSym = (Symbol) it.next(); - if( !seqVars.contains( varSym )) { - makeHelpVar( varSym, true ); - } - } - - initializeSyms(); - } - - void makeHelpVar( Symbol realVar ) { - makeHelpVar( realVar, false ); - } + Vector helpVarDefs; + + + /** translate right tracer to code + * @param dfa determinized left tracer + * @param left nondeterm. left tracer + * @param cf ... + * @param pat ? + * @param elementType ... + */ + public RightTracerInScala( DetWordAutom dfa, + NondetWordAutom left, + Matcher m, + CodeFactory cf, + Tree pat, + Type elementType ) { + super( dfa, elementType, m.owner, cf ); + this._m = m; + + Vector seqVars = new Vector(); + + for( int j = 0; j < left.nstates; j++ ) { + if( left.qbinders[ j ] != null ) + for( Iterator it = left.qbinders[ j ].iterator(); + it.hasNext() ; ) { + Symbol varSym = (Symbol) it.next(); + + if( !seqVars.contains( varSym ) ) + seqVars.add( varSym ); + } + } + + this.seqVars = seqVars; + this.allVars = CollectVariableTraverser.collectVars( pat ); + + helpMap2 = new HashMap(); + helpVarDefs = new Vector(); + + for( Iterator it = seqVars.iterator(); it.hasNext(); ) { + makeHelpVar( (Symbol) it.next() ); + } + + for( Iterator it = allVars.iterator(); it.hasNext(); ) { + Symbol varSym = (Symbol) it.next(); + if( !seqVars.contains( varSym )) { + makeHelpVar( varSym, true ); + } + } + + initializeSyms(); + } + + void makeHelpVar( Symbol realVar ) { + makeHelpVar( realVar, false ); + } /** makes a helpvar and puts mapping into helpMap, ValDef into helpVarDefs */ - void makeHelpVar( Symbol realVar, boolean keepType ) { - Symbol helpVar = new TermSymbol( pos, - cf.fresh.newName( realVar.name - .toString() ), - owner, - 0); + void makeHelpVar( Symbol realVar, boolean keepType ) { + Symbol helpVar = new TermSymbol( pos, + cf.fresh.newName( realVar.name + .toString() ), + owner, + 0); - //System.out.println("making helpvar : "+realVar+" -> "+helpVar); + //System.out.println("making helpvar : "+realVar+" -> "+helpVar); - if( keepType ) - helpVar.setType( realVar.type() ); - else - helpVar.setType( cf.SeqListType( elementType ) ); + if( keepType ) + helpVar.setType( realVar.type() ); + else + helpVar.setType( cf.SeqListType( elementType ) ); - helpMap.put( realVar, helpVar ); + helpMap.put( realVar, helpVar ); - Tree rhs; - if( keepType ) - rhs = cf.ignoreValue( realVar.type() ); - else - rhs = /* cf.newRef( */ cf.newSeqNil( elementType ) /* ) */; - helpVar.flags |= Modifiers.MUTABLE; - Tree varDef = gen.ValDef( helpVar, rhs ); - //((ValDef) varDef).kind = Kinds.VAR; - helpVarDefs.add( varDef ); + Tree rhs; + if( keepType ) + rhs = cf.ignoreValue( realVar.type() ); + else + rhs = /* cf.newRef( */ cf.newSeqNil( elementType ) /* ) */; + helpVar.flags |= Modifiers.MUTABLE; + Tree varDef = gen.ValDef( helpVar, rhs ); + //((ValDef) varDef).kind = Kinds.VAR; + helpVarDefs.add( varDef ); - } + } - Tree prependToHelpVar( Symbol realVar, Tree elem ) { - Tree hv = refHelpVar( realVar ); - return gen.Assign( hv, cf.newSeqCons( elem, hv )); - /* - return cf.Block(pos, - new Tree [] { - cf.debugPrintRuntime( "ASSIGN" ), - gen.Assign( hv, cf.newSeqCons( elem, hv )) - }, defs.UNIT_TYPE); - */ - } + Tree prependToHelpVar( Symbol realVar, Tree elem ) { + Tree hv = refHelpVar( realVar ); + return gen.Assign( hv, cf.newSeqCons( elem, hv )); + /* + return cf.Block(pos, + new Tree [] { + cf.debugPrintRuntime( "ASSIGN" ), + gen.Assign( hv, cf.newSeqCons( elem, hv )) + }, defs.UNIT_TYPE); + */ + } - protected void initializeSyms() { - - this.funSym = newFunSym( "binder" ); + protected void initializeSyms() { - this.iterSym = new TermSymbol( pos, - cf.fresh.newName("iter"), - funSym, - 0) - .setType( cf.SeqTraceType( elementType )); + this.funSym = newFunSym( "binder" ); - this.stateSym = new TermSymbol( pos, - cf.fresh.newName("q"), - funSym, - 0 ) - .setType( defs.INT_TYPE ) ; + this.iterSym = new TermSymbol( pos, + cf.fresh.newName("iter"), + funSym, + 0) + .setType( cf.SeqTraceType( elementType )); - this.elemSym = new TermSymbol( pos, - cf.fresh.newName("elem"), - funSym, - 0) - .setType( elementType ) ; + this.stateSym = new TermSymbol( pos, + cf.fresh.newName("q"), + funSym, + 0 ) + .setType( defs.INT_TYPE ) ; - this.targetSym = new TermSymbol( pos, - cf.fresh.newName("trgt"), - funSym, - 0) - .setType( defs.INT_TYPE ) ; + this.elemSym = new TermSymbol( pos, + cf.fresh.newName("elem"), + funSym, + 0) + .setType( elementType ) ; + this.targetSym = new TermSymbol( pos, + cf.fresh.newName("trgt"), + funSym, + 0) + .setType( defs.INT_TYPE ) ; - funSym.setType( new Type.MethodType( new Symbol[] { - iterSym, stateSym }, defs.UNIT_TYPE )); - } + funSym.setType( new Type.MethodType( new Symbol[] { + iterSym, stateSym }, defs.UNIT_TYPE )); - // same as in LeftTracer - Tree code_fail() { + } - return cf.ThrowMatchError( _m.pos, defs.UNIT_TYPE ); + // same as in LeftTracer + Tree code_fail() { - } + return cf.ThrowMatchError( _m.pos, defs.UNIT_TYPE ); - public Tree code_body() { + } - Tree body = code_fail(); // never reached at runtime. + public Tree code_body() { - // state [ nstates-1 ] is the dead state, so we skip it + Tree body = code_fail(); // never reached at runtime. - //`if( state == q ) else {...}' - for( int i = dfa.nstates-1; i >= 0; i-- ) { - body = code_state( i, body ); - } + // state [ nstates-1 ] is the dead state, so we skip it + //`if( state == q ) else {...}' + for( int i = dfa.nstates-1; i >= 0; i-- ) { + body = code_state( i, body ); + } - Tree t3 = cf.If( cf.isEmpty( _iter() ), - run_finished( 0 ), - gen.Block( new Tree[] { - gen.ValDef( targetSym, - cf.SeqTrace_headState( gen.Ident( pos, iterSym))), - gen.ValDef( elemSym, - cf.SeqTrace_headElem( gen.Ident( pos, iterSym))), - body })); + Tree t3 = cf.If( cf.isEmpty( _iter() ), + run_finished( 0 ), + gen.Block( new Tree[] { + gen.ValDef( targetSym, + cf.SeqTrace_headState( gen.Ident( pos, iterSym))), + gen.ValDef( elemSym, + cf.SeqTrace_headElem( gen.Ident( pos, iterSym))), + + body })); - /* - t3 = gen.Block( new Tree[] { - cf.debugPrintRuntime("enter binderFun"), - cf.debugPrintRuntime(" state:"), - cf.debugPrintRuntime( gen.Ident( pos, stateSym )), - cf.debugPrintRuntime(" iter:"), - cf.debugPrintRuntime(_iter()), - cf.debugPrintNewlineRuntime(""), - t3 }); - */ + /* + t3 = gen.Block( new Tree[] { + cf.debugPrintRuntime("enter binderFun"), + cf.debugPrintRuntime(" state:"), + cf.debugPrintRuntime( gen.Ident( pos, stateSym )), + cf.debugPrintRuntime(" iter:"), + cf.debugPrintRuntime(_iter()), + cf.debugPrintNewlineRuntime(""), + t3 }); + */ + + //System.out.println("enter RightTracerInScala:code_body()");// DEBUG + //System.out.println("dfa.nstates"+dfa.nstates);// DEBUG + return t3; + } + + /** this one is special, we check the first element of the trace + * and choose the next state depending only on the state part + */ + Tree code_state0( Tree elseBody ) { // careful, map Int to Int - //System.out.println("enter RightTracerInScala:code_body()");// DEBUG - //System.out.println("dfa.nstates"+dfa.nstates);// DEBUG - return t3; - } + HashMap hmap = (HashMap) dfa.deltaq( 0 ); // all the initial states - /** this one is special, we check the first element of the trace - * and choose the next state depending only on the state part - */ - Tree code_state0( Tree elseBody ) { // careful, map Int to Int + Tree stateBody = code_fail(); // never happens - HashMap hmap = (HashMap) dfa.deltaq( 0 ); // all the initial states + for( Iterator it = hmap.keySet().iterator(); it.hasNext(); ) { + Integer targetL = (Integer) it.next(); + Integer targetR = (Integer) hmap.get( targetL ); - Tree stateBody = code_fail(); // never happens + stateBody = cf.If( cf.Equals( gen.Ident( pos, targetSym ), + cf.Int( targetL )), + callFun( new Tree[] { + cf.SeqTrace_tail( _iter() ), + cf.Int( targetR ) }), + stateBody ); + } - for( Iterator it = hmap.keySet().iterator(); it.hasNext(); ) { - Integer targetL = (Integer) it.next(); - Integer targetR = (Integer) hmap.get( targetL ); + return cf.If( cf.Equals( _state(), cf.Int( 0 )), + stateBody , + elseBody ); - stateBody = cf.If( cf.Equals( gen.Ident( pos, targetSym ), - cf.Int( targetL )), - callFun( new Tree[] { - cf.SeqTrace_tail( _iter() ), - cf.Int( targetR ) }), - stateBody ); - } + } - return cf.If( cf.Equals( _state(), cf.Int( 0 )), - stateBody , - elseBody ); + Tree code_state( int i, Tree elseBody ) { - } + if( i == 0 ) + return code_state0( elseBody ); - Tree code_state( int i, Tree elseBody ) { + int finalSwRes; + Tree stateBody ; // action(delta) for one particular label/test - if( i == 0 ) - return code_state0( elseBody ); + // default action (fail if there is none) - int finalSwRes; - Tree stateBody ; // action(delta) for one particular label/test + stateBody = code_delta( i, Label.DefaultLabel); - // default action (fail if there is none) + if( stateBody == null ) + stateBody = code_fail(); - stateBody = code_delta( i, Label.DefaultLabel); + // transitions of state i - if( stateBody == null ) - stateBody = code_fail(); + HashMap trans = ((HashMap[])dfa.deltaq)[ i ]; - // transitions of state i + for( Iterator labs = dfa.labels.iterator(); labs.hasNext() ; ) { + Object label = labs.next(); + Integer next = (Integer) trans.get( label ); - HashMap trans = ((HashMap[])dfa.deltaq)[ i ]; + Tree action = code_delta( i, (Label) label ); - for( Iterator labs = dfa.labels.iterator(); labs.hasNext() ; ) { - Object label = labs.next(); - Integer next = (Integer) trans.get( label ); + if( action != null ) { - Tree action = code_delta( i, (Label) label ); + stateBody = cf.If( _cur_eq( _iter(), (Label) label ), + action, + stateBody); + } + } - if( action != null ) { + return cf.If( cf.Equals( _state(), gen.mkIntLit( cf.pos, i )), + stateBody , + elseBody ); + } - stateBody = cf.If( _cur_eq( _iter(), (Label) label ), - action, - stateBody); - } - } + /** returns a Tree whose type is boolean. + * now we care about free vars + */ - return wrapStateBody0( stateBody, - elseBody, - i ); - } + Tree handleBody1( HashMap helpMap3 ) { + //System.out.println("Rtis.handleBody ... helpMap = " + helpMap ); + // todo: change helpMap s.t. symbols are not reused. - /** returns a Tree whose type is boolean. - * now we care about free vars - */ + Tree res[] = new Tree[ helpMap3.keySet().size() + 1 ]; + int j = 0; + for( Iterator it = helpMap3.keySet().iterator(); it.hasNext(); ) { + Symbol vsym = (Symbol) it.next(); + Symbol hv = (Symbol) helpMap3.get( vsym ); + hv.setType( cf.SeqListType( elementType ) ) ; + Tree refv = gen.Ident(Position.FIRSTPOS, vsym); + Tree refhv = gen.Ident(Position.FIRSTPOS, hv); + res[ j++ ] = gen.Assign( refhv, refv ); + } - Tree handleBody1( HashMap helpMap3 ) { - //System.out.println("Rtis.handleBody ... helpMap = " + helpMap ); - // todo: change helpMap s.t. symbols are not reused. - - Tree res[] = new Tree[ helpMap3.keySet().size() + 1 ]; - int j = 0; - for( Iterator it = helpMap3.keySet().iterator(); it.hasNext(); ) { - Symbol vsym = (Symbol) it.next(); - Symbol hv = (Symbol) helpMap3.get( vsym ); - hv.setType( cf.SeqListType( elementType ) ) ; - Tree refv = gen.Ident(Position.FIRSTPOS, vsym); - Tree refhv = gen.Ident(Position.FIRSTPOS, hv); - res[ j++ ] = gen.Assign( refhv, refv ); - } + res[ j ] = gen.mkBooleanLit( Position.FIRSTPOS, true ); // just `true' - res[ j ] = super.handleBody( freeVars ); // just `true' + return cf.Block(Position.FIRSTPOS, res, res[j].type() ); + } - return cf.Block(Position.FIRSTPOS, res, res[j].type() ); - } + // calling the AlgebraicMatcher here + Tree _cur_match( Tree pat ) { - // calling the AlgebraicMatcher here - Tree _cur_match( Tree pat ) { + //System.out.println("RTiS._cur_match("+TextTreePrinter.toString(pat)+")"); - //System.out.println("RTiS._cur_match("+TextTreePrinter.toString(pat)+")"); + //System.out.println("calling algebraic matcher on type:"+pat.type); - //System.out.println("calling algebraic matcher on type:"+pat.type); + Matcher m = new Matcher( funSym,//this.funSym, + currentElem(), + defs.BOOLEAN_TYPE ); - Matcher m = new Matcher( funSym,//this.funSym, - currentElem(), - defs.BOOLEAN_TYPE ); + // there could be regular expressions under Sequence node, export those later + Vector varsToExport = NoSeqVariableTraverser.varsNoSeq( pat ); + HashMap freshenMap = new HashMap(); - // there could be regular expressions under Sequence node, export those later - Vector varsToExport = NoSeqVariableTraverser.varsNoSeq( pat ); - HashMap freshenMap = new HashMap(); + HashMap helpMap3 = new HashMap(); - HashMap helpMap3 = new HashMap(); + // "freshening": never use the same symbol more than once (in later invocations of _cur_match) - // "freshening": never use the same symbol more than once (in later invocations of _cur_match) + for( Iterator it = varsToExport.iterator(); it.hasNext(); ) { + Symbol key = (Symbol) it.next(); + this.helpMap2.put( key, helpMap.get( key )); + // "freshening" + Symbol newSym = key.cloneSymbol(); + newSym.name = key.name.append( Name.fromString("gu234") ); // is fresh now :-) + freshenMap.put( key, newSym ); + helpMap3.put( newSym, helpMap.get( key )); + } + + //System.out.println("RightTracerInScala:: -pat :"+pat); + //System.out.println("RightTracerInScala::varsToExport :"+varsToExport); + //System.out.println("RightTracerInScala::freshenMap :"+freshenMap); + + + // "freshening" + TreeCloner st = new TreeCloner(cf.unit.global, freshenMap, Type.IdMap ); + pat = st.transform( pat ); + //System.out.println("RightTracerInScala:: -pat( after subst ) :"+pat); + + // val match { case => { ; true } + // case _ => false + + am.construct( m, new CaseDef[] { + (CaseDef) cf.make.CaseDef( pat.pos, + pat, // if tree val matches pat -> update vars, return true + Tree.Empty, + handleBody1( helpMap3 )/* "freshening */), + (CaseDef) cf.make.CaseDef( pat.pos, + cf.make.Ident( pat.pos, Names.WILDCARD ) + //DON'T .setSymbol( Symbol.NONE ) !!FIXED + .setType( pat.type() ), + Tree.Empty, + gen.mkBooleanLit( pat.pos, false )) }, // else return false + true // do binding please + ); + + return am.toTree().setType( defs.BOOLEAN_TYPE ); + } + + + /** returns translation of transition with label from i. + * returns null if there is no such transition(no translation needed) + */ + Tree code_delta( int i, Label label ) { + HashMap hmap = (HashMap) dfa.deltaq( i ); + Integer ntarget = (Integer) hmap.get( label ); + Tree algMatchTree = null; + if( ntarget == null ) + return null; + //System.out.println("delta("+i+","+label+")" ); + Label theLab = null; + switch(label) { + case Label.Pair( Integer state, Label lab2 ): + //assert ntarget == state; + theLab = lab2; + switch( lab2 ) { + case TreeLabel( Tree pat ): + algMatchTree = _cur_match( pat ); + break; + } + break; + case DefaultLabel: + throw new ApplicationError(); // should not happen + } + assert dfa.qbinders != null : "qbinders ?"; + + Vector vars = dfa.qbinders[ i ]; + + if( vars == null ) vars = new Vector(); // TODO: make this more consistent + assert vars != null; + + //System.out.println("delta: theLab: " + theLab + " vars in current ="+ vars ); + + if( ntarget == null ) + return code_fail(); + + Tree stms[] = new Tree[ vars.size() + + ((algMatchTree != null )? 1 : 0 ) + + 1 ]; + int j = 0; + for( Iterator it = vars.iterator(); it.hasNext(); ) { + Symbol var = (Symbol) it.next(); + + Tree rhs = gen.Ident( pos, elemSym ); + + stms[ j++ ] = prependToHelpVar( var , rhs); + } + + if( algMatchTree != null ) + stms[ j++ ] = algMatchTree ; + + stms[ j ] = callFun( new Tree[] { cf.SeqTrace_tail( _iter() ), + cf.Int( ntarget ) } ); + + return cf.Block( pos, stms, funRetType() ); + } + + /* returns statements that do the work of the right-transducer + */ + Tree[] getStms( Tree trace ) { - for( Iterator it = varsToExport.iterator(); it.hasNext(); ) { - Symbol key = (Symbol) it.next(); - this.helpMap2.put( key, helpMap.get( key )); - // "freshening" - Symbol newSym = key.cloneSymbol(); - newSym.name = key.name.append( Name.fromString("gu234") ); // is fresh now :-) - freshenMap.put( key, newSym ); - helpMap3.put( newSym, helpMap.get( key )); - } + //System.out.println( "!!getStms.helpVarDefs: "+helpVarDefs); - //System.out.println("RightTracerInScala:: -pat :"+pat); - //System.out.println("RightTracerInScala::varsToExport :"+varsToExport); - //System.out.println("RightTracerInScala::freshenMap :"+freshenMap); + Vector v = new Vector(); + for( Iterator it = helpVarDefs.iterator(); it.hasNext(); ) + v.add( (Tree) it.next() ); - // "freshening" - TreeCloner st = new TreeCloner(cf.unit.global, freshenMap, Type.IdMap ); - pat = st.transform( pat ); - //System.out.println("RightTracerInScala:: -pat( after subst ) :"+pat); - - // val match { case => { ; true } - // case _ => false - - am.construct( m, new CaseDef[] { - (CaseDef) cf.make.CaseDef( pat.pos, - pat, // if tree val matches pat -> update vars, return true - Tree.Empty, - /*st.transform( */handleBody1( helpMap3 )/*)*//* "freshening */), - (CaseDef) cf.make.CaseDef( pat.pos, - cf.make.Ident( pat.pos, Names.WILDCARD ) - //DON'T .setSymbol( Symbol.NONE ) !!FIXED - .setType( pat.type() ), - Tree.Empty, - gen.mkBooleanLit( pat.pos, false )) }, // else return false - true // do binding please - ); - - return am.toTree().setType( defs.BOOLEAN_TYPE ); - } - - - /** returns translation of transition with label from i. - * returns null if there is no such transition(no translation needed) - */ - Tree code_delta( int i, Label label ) { - HashMap hmap = (HashMap) dfa.deltaq( i ); - Integer ntarget = (Integer) hmap.get( label ); - Tree algMatchTree = null; - if( ntarget == null ) - return null; - //System.out.println("delta("+i+","+label+")" ); - Label theLab = null; - switch(label) { - case Label.Pair( Integer state, Label lab2 ): - //assert ntarget == state; - theLab = lab2; - switch( lab2 ) { - case TreeLabel( Tree pat ): - algMatchTree = _cur_match( pat ); - break; - } - break; - case DefaultLabel: - throw new ApplicationError(); // should not happen - } - assert dfa.qbinders != null : "qbinders ?"; - - Vector vars = dfa.qbinders[ i ]; - - if( vars == null ) vars = new Vector(); // TODO: make this more consistent - assert vars != null; - - //System.out.println("delta: theLab: " + theLab + " vars in current ="+ vars ); - - if( ntarget == null ) - return code_fail(); - - Tree stms[] = new Tree[ vars.size() - + ((algMatchTree != null )? 1 : 0 ) - + 1 ]; - int j = 0; - for( Iterator it = vars.iterator(); it.hasNext(); ) { - Symbol var = (Symbol) it.next(); - - Tree rhs = gen.Ident( pos, elemSym ); - - stms[ j++ ] = prependToHelpVar( var , rhs); - } - - if( algMatchTree != null ) - stms[ j++ ] = algMatchTree ; - - stms[ j ] = callFun( new Tree[] { cf.SeqTrace_tail( _iter() ), - cf.Int( ntarget ) } ); - - return cf.Block( pos, stms, funRetType() ); - } - - /* returns statements that do the work of the right-transducer - */ - Tree[] getStms( Tree trace ) { - - //System.out.println( "!!getStms.helpVarDefs: "+helpVarDefs); - - Vector v = new Vector(); - - for( Iterator it = helpVarDefs.iterator(); it.hasNext(); ) - v.add( (Tree) it.next() ); - - v.add( gen.DefDef( this.funSym, code_body() ) ); - v.add( callFun( new Tree[] { trace, cf.Int( 0 ) } ) ); - - /* - for(Iterator it = helpMap.keySet().iterator(); it.hasNext(); ) { - // DEBUG - Symbol var = (Symbol)it.next(); - v.add( cf.debugPrintRuntime( var.name.toString() )); - v.add( cf.debugPrintRuntime( refHelpVar( var )) ); - } - */ - - for( Iterator it = seqVars.iterator(); it.hasNext(); ) { - v.add( bindVar( (Symbol) it.next() ) ); - } - - Tree result[] = new Tree[ v.size() ]; - int j = 0; - for( Iterator it = v.iterator(); it.hasNext(); ) { - result[ j++ ] = (Tree) it.next(); - } - - // helpvarSEQ via _m.varMap - - return result; - - } - - /** return the accumulator. (same as in LeftTracerInScala) - * todo: move tree generation of Unit somewhere else - */ - Tree run_finished( int state ) { - return gen.Block(Position.FIRSTPOS, Tree.EMPTY_ARRAY).setType( defs.UNIT_TYPE ); - } - - Tree current() { - return gen.Ident( pos, targetSym ); - } - - Tree currentElem() { - return gen.Ident( pos, elemSym ); - } - - Tree _cur_eq( Tree iter, Label label ) { - //System.out.println("_cur_eq, thelab: "+label); - switch( label ) { - case Pair( Integer target, Label theLab ): - return cf.Equals( cf.Int( target ), - current() ); - } - throw new ApplicationError("expected Pair label"); - } + v.add( gen.DefDef( this.funSym, code_body() ) ); + v.add( callFun( new Tree[] { trace, cf.Int( 0 ) } ) ); + + /* + for(Iterator it = helpMap.keySet().iterator(); it.hasNext(); ) { + // DEBUG + Symbol var = (Symbol)it.next(); + v.add( cf.debugPrintRuntime( var.name.toString() )); + v.add( cf.debugPrintRuntime( refHelpVar( var )) ); + } + */ + + for( Iterator it = seqVars.iterator(); it.hasNext(); ) { + v.add( bindVar( (Symbol) it.next() ) ); + } + + Tree result[] = new Tree[ v.size() ]; + int j = 0; + for( Iterator it = v.iterator(); it.hasNext(); ) { + result[ j++ ] = (Tree) it.next(); + } + + // helpvarSEQ via _m.varMap + + return result; + + } + + /** return the accumulator. (same as in LeftTracerInScala) + * todo: move tree generation of Unit somewhere else + */ + Tree run_finished( int state ) { + return gen.Block(Position.FIRSTPOS, Tree.EMPTY_ARRAY).setType( defs.UNIT_TYPE ); + } + + Tree current() { + return gen.Ident( pos, targetSym ); + } + + Tree currentElem() { + return gen.Ident( pos, elemSym ); + } + + Tree _cur_eq( Tree iter, Label label ) { + //System.out.println("_cur_eq, thelab: "+label); + switch( label ) { + case Pair( Integer target, Label theLab ): + return cf.Equals( cf.Int( target ), + current() ); + } + throw new ApplicationError("expected Pair label"); + } } diff --git a/sources/scalac/transformer/matching/SequenceMatcher.java b/sources/scalac/transformer/matching/SequenceMatcher.java index c85ec7589a..f921d94a37 100644 --- a/sources/scalac/transformer/matching/SequenceMatcher.java +++ b/sources/scalac/transformer/matching/SequenceMatcher.java @@ -256,7 +256,8 @@ public class SequenceMatcher extends PatternTool { WordAutomInScala scalaAut = new WordAutomInScala( dfa, elementType, _m.owner, - cf); + cf, + unit.global.target == Global.TARGET_JVM ); scalaAut.translate(); if( defaultCase == null ) diff --git a/sources/scalac/transformer/matching/WordAutomInScala.java b/sources/scalac/transformer/matching/WordAutomInScala.java index 04ebf52114..1654f69161 100644 --- a/sources/scalac/transformer/matching/WordAutomInScala.java +++ b/sources/scalac/transformer/matching/WordAutomInScala.java @@ -59,7 +59,7 @@ public class WordAutomInScala extends Autom2Scala { */ public void translate() { initializeSyms(); - Tree tb = code_body(); + Tree tb = code_body_NEW(); theDefDef = gen.DefDef(this.funSym, tb); } @@ -95,8 +95,12 @@ public class WordAutomInScala extends Autom2Scala { public WordAutomInScala(DetWordAutom dfa, Type elementType, Symbol owner, - CodeFactory cf) { + CodeFactory cf, + boolean optim) { super(dfa, elementType, owner, cf); + + this.optimize &= optim; + } } -- cgit v1.2.3