Пример #1
0
        //> _for     : WORD _value _value FOR _scope_or_statement
        //>          ;
        private bool _for()
        {
            NakoToken tokVar = null;

            TokenTry();

            // local variable
            if (!Accept(NakoTokenType.WORD))
            {
                return(false);
            }
            tokVar = tok.CurrentToken;
            if (!(tokVar.Josi == "を" || tokVar.Josi == "で"))
            {
                return(false);
            }
            tok.MoveNext();

            // get argument * 2
            if (!_value())
            {
                TokenBack();
                return(false);
            }
            if (!_value())
            {
                TokenBack();
                return(false);
            }

            NakoNodeFor      fornode = new NakoNodeFor();
            NakoNodeVariable v       = new NakoNodeVariable();

            fornode.loopVar = v;
            v.scope         = NakoVariableScope.Local;
            v.Token         = tokVar;
            v.varNo         = localVar.CreateVar(tokVar.Value);

            fornode.nodeTo   = calcStack.Pop();
            fornode.nodeFrom = calcStack.Pop();

            if (!Accept(NakoTokenType.FOR))
            {
                TokenBack();
                return(false);
            }
            TokenFinally();
            tok.MoveNext();

            fornode.nodeBlocks = _scope_or_statement();
            this.parentNode.AddChild(fornode);
            lastNode = fornode;
            return(true);
        }
Пример #2
0
        private void _for(NakoNodeFor node)
        {
            int loopVarNo  = node.loopVar.varNo;
            int labelId    = GetLableId();
            int kaisuVarNo = node.kaisuVarNo;

            // (0)
            NakoILCode label_for_begin    = createLABEL("FOR_BEGIN" + labelId.ToString());
            NakoILCode label_for_end      = createLABEL("FOR_END" + labelId.ToString());
            NakoILCode label_for_continue = createLABEL("FOR_CONTINUE" + labelId.ToString());

            // (1) 変数を初期化する
            result.Add(label_for_begin);
            Write_r(node.nodeFrom);
            addNewILCode(NakoILType.ST_LOCAL, loopVarNo);
            addNewILCode(NakoILType.LD_CONST_INT, 0L);
            addNewILCode(NakoILType.ST_LOCAL, kaisuVarNo);

            // (2) 条件をコードにする
            // i <= iTo
            NakoILCode label_for_cond = createLABEL("FOR_COND" + labelId.ToString());

            result.Add(label_for_cond);
            // L
            addNewILCode(NakoILType.LD_LOCAL, loopVarNo);
            // R
            Write_r(node.nodeTo); // TODO:最適化
            // LT_EQ
            addNewILCode(NakoILType.LT_EQ);
            // IF BRANCH FALSE
            addNewILCode(NakoILType.BRANCH_FALSE, label_for_end);

            //回数設定
            addNewILCode(NakoILType.LD_LOCAL, kaisuVarNo);
            addNewILCode(NakoILType.INC);
            addNewILCode(NakoILType.ST_LOCAL, kaisuVarNo);

            // (3) 繰り返し文を実行する
            _loop_check_break_continue(node.nodeBlocks, label_for_end, label_for_continue);
            Write_r(node.nodeBlocks);
            //continue時には変数の加算が必要なので、ここに飛ばす必要がある
            result.Add(label_for_continue);

            // (4) 変数を加算する (ここ最適化できそう)
            addNewILCode(NakoILType.LD_LOCAL, loopVarNo);
            addNewILCode(NakoILType.INC);
            addNewILCode(NakoILType.ST_LOCAL, loopVarNo);

            // (5) 手順2に戻る
            result.Add(createJUMP(label_for_cond));
            result.Add(label_for_end);
        }