Example #1
0
        public Combination Successor()
        {
            if (this.data[0] == this.n - this.k)
                return null;

            Combination ans = new Combination(this.n, this.k);

            long i;
            for (i = 0; i < this.k; ++i)
                ans.data[i] = this.data[i];

            for (i = this.k - 1; i > 0 && ans.data[i] == this.n - this.k + i; --i)
                ;

            ++ans.data[i];

            for (long j = i; j < this.k - 1; ++j)
                ans.data[j + 1] = ans.data[j] + 1;

            return ans;
        }
Example #2
0
        // unroll文はmacro扱い。
        public SyntaxTree UnrollStatement()
        {
            var tree = CreateSyntaxTree(Syntax.Unroll); // 一応、構文解析をする。
            var treeNew = CreateSyntaxTree(Syntax.Macro); // 実際は、変換後のソースを保持する。

            tree.Append(Token);				// "unroll"

            var token = Token;

            switch(token)
            {
                case Token.CASE:
                    {
                        /*
                    unroll case
                    {
                        case 1: AAA
                        case 2: BBB
                        case 4: CCC
                    }
                */
                        tree.Append(Token.CASE); // "case"
                        tree.Append(Token.LBRACE); // "{"

                        var caselist = new List<SyntaxTree>();
                        while (Token == Token.CASE || Token == Token.DEFAULT)
                        {
                            var t = CaseStatement();
                            tree.Append(t);
                            caselist.Add(t);
                        }
                        tree.Append(Token.RBRACE); // "}"

                        // このあとMacroに変換してそれを返す

                        // caselistのなかですべての順列組み合わせ
                        int n = caselist.Count;
                        for (int i = 1; i <= n; ++i)
                        {
                            var c = new Combination(n, i);
                            var m = Combination.Choose(n, i);
                            for (int j = 0; j < m; ++j)
                            {
                                var e = c.Element(j);

                                // これですべての順列組み合わせが得られた。

                                treeNew.Append(Token.CASE, "case");
                                for (int k = 0; k < e.data.Length; ++k)
                                {
                                    if (k != 0)
                                        treeNew.Append(Token.PLUS, "+");

                                    // case 1: case 2: みたいになっていないことを仮定しているので
                                    // まあここは決め打ちでいいや
                                    treeNew.Append(Token.IDENT, caselist[(int) e.data[k]].elms[0].elms[1].ToString());
                                }
                                treeNew.Append(Token.COLON, ":");
                                for (int k = 0; k < e.data.Length; ++k)
                                {
                                    treeNew.Append(Token.IDENT, caselist[(int) e.data[k]].elms[1].ToString());
                                }
                                treeNew.Append(Token.BREAK, "break");
                                treeNew.Append(Token.SEMICOLON, ";");
                            }
                        }

                        return treeNew;

                    }
                case Token.FOREACH:
                    {
                        // unroll foreach ident in range_parameters StatementSequence
                        tree.Append(Token);	// "foreach"
                        tree.Append(Token.IDENT);
                        tree.Append(Token.IN);
                        tree.Append(RangeParameters());
                        tree.Append(StatementSequence());

                        // 解析が終わったので並べ替えて出力する。

                        var ss = tree.elms[5].ToString();
                        var target = tree.elms[2].ToString();

                        foreach (var t0 in RangeParameters2Enumerator(tree.elms[4]))
                        {
                            var ss_string = ss.Replace(target, t0);
                            treeNew.Append(Token.SOMETHING, ss_string);
                        }

                        return treeNew;
                    }

                default:
                    // それ以外のなんかのunroll
                    throw new UnrollerException("使えないunroll");
            }
        }