/*     ____ ____  ____ ____  ______                                     *\
**    / __// __ \/ __// __ \/ ____/    SOcos COmpiles Scala             **
**  __\_ \/ /_/ / /__/ /_/ /\_ \       (c) 2002, LAMP/EPFL              **
** /_____/\____/\___/\____/____/                                        **
\*                                                                      */

// $Id$

package scalac.transformer.matching;

import ch.epfl.lamp.util.Position;

import scalac.*;
import scalac.ast.Tree;
import scalac.ast.TreeGen;
import scalac.symtab.Type;
import scalac.symtab.Symbol;
import scalac.transformer.TransMatch.Matcher;
//import scalac.typechecker.*;
import Tree.*;

import java.util.*;


/** translates a recognizer to scala code
 */
public class WordAutomInScala extends Autom2Scala {

    Tree theDefDef ;

    Tree getMatcherSwitch(Tree selector,
                          Tree failTree,
                          Tree body[],
                          Type resultType) {

        Tree run = callFun( new Tree[] {
            cf.newIterator( selector ),
            gen.mkIntLit( cf.pos, 0 ) } );

        /* return code `var <swres>: scala.Int = <init>' */

        run = gen.ValDef( resultSym, run );

        Tree result;

        // conditions
        Tree cond[] = new Tree[body.length];
        //Tree bbody[] = new Tree[body.length];
        for( int i = body.length - 1; i >= 0; i-- )
            cond[i] = cf.Equals(_swres(), gen.mkIntLit( cf.pos, i ));

        result = cf.Switch( selector, cond, body, failTree );

        result = cf.gen.mkBlock( cf.pos, new Tree[] { theDefDef, run, result } );
        //unit.global.debugPrinter.print( result );
        return result;
    }

    /** do the translation
     */
    public void translate() {
        initializeSyms();
        Tree tb = code_body_NEW();
        theDefDef = gen.DefDef(this.funSym, tb);
    }

    /** ...
     * @return 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) {
        Integer target = dfa.delta(i, label);

        if (target == null)
            switch (label) {
            case DefaultLabel:
                return code_error(); // this may not happen !
            default:
                return null; // not good
            }
        else if (target.intValue() == dfa.nstates - 1) // that one is a dead state
            return code_fail();

        return callFun(new Tree[] { _iter(),
                                    gen.mkIntLit( cf.pos, target.intValue() )} );
    }

    /** constructor
     * @param dfa         the dfa that is to be translated
     * @param elementType type of the objects in the sequence
     * @param owner       the owner of the pattern match
     * @param cf          code factory
     * @param optim       flag that indicates whether to optimize
     * @return            an object that translates the dfa
     */
    public WordAutomInScala(DetWordAutom dfa,
                            Type elementType,
                            Symbol owner,
                            CodeFactory cf,
                            boolean optim) {
        super(dfa, elementType, owner, cf);
        this.optimize &= optim;

    }

}

@@ -1254,16 +1254,61 @@
 ditions%0A
+        //int tags%5B%5D = new int%5Bbody.length%5D;%0A
         
@@ -1443,16 +1443,45 @@
 0; i-- )
+ %7B%0A            //tags%5Bi%5D = i;
 %0A       
@@ -1543,16 +1543,25 @@
 , i ));%0A
+        %7D
 %0A       
@@ -1612,24 +1612,90 @@
 ailTree );%0A%0A
+        //result = gen.Switch( _swres(), tags, body, failTree );%0A%0A
         resu

replace if's with switch (but is commented out ...