summaryrefslogtreecommitdiff
path: root/sources/scalac/transformer/matching/WordAutomInScala.java
blob: 04ebf52114000bcaa174b3aaf933dca520175a61 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
/*     ____ ____  ____ ____  ______                                     *\
**    / __// __ \/ __// __ \/ ____/    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.*;


/**
 */
public class WordAutomInScala extends Autom2Scala {

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

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

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

        run = _intvar(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(Position.FIRSTPOS, i));

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

        result = cf.make.Block( pos, new Tree[] { theDefDef, run, result } )
                  .setType( resultType );
        //unit.global.debugPrinter.print( result );
        return result;
    }

    /** do the translation
     */
    public void translate() {
        initializeSyms();
        Tree tb = code_body();
        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_fail(); // 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(Position.FIRSTPOS, target.intValue())} );
    }

    /** ...
     * @param dfa ...
     * @param elementType ...
     * @param owner ...
     * @param cf ...
     * @return ...
     */
    public WordAutomInScala(DetWordAutom dfa,
                            Type elementType,
                            Symbol owner,
                            CodeFactory cf) {
        super(dfa, elementType, owner, cf);
    }

}