Esempio n. 1
0
        //Iterator実装テスト
        //TODO:try finallyを入れる必要がある
        private void _foreachUseIterator(NakoNodeForeach node)
        {
            int labelId = GetLableId();
            int loopVarNo = node.loopVarNo;
            int valueVarNo = node.valueVarNo;
            int taisyouVarNo = node.taisyouVarNo;
            int kaisuVarNo = node.kaisuVarNo;
            int enumeratorVarNo = node.enumeratorVarNo;
            int enumeratorFuncNo = node.enumeratorFuncNo;
            int moveresultFuncNo = node.moveresultFuncNo;
            int getcurrentFuncNo = node.getcurrentFuncNo;
            int getdisposeFuncNo = node.getdisposeFuncNo;

            // (0)
            NakoILCode label_for_begin = createLABEL("ITERATOR_BEGIN" + labelId.ToString());
            NakoILCode label_for_end = createLABEL("ITERATOR_END" + labelId.ToString());
            NakoILCode label_for_continue = createLABEL("ITERATOR_CONTINUE" + labelId.ToString());

            // (1) 変数を初期化する
            result.Add(label_for_begin);
            // カウンタ変数を初期化
            addNewILCode(NakoILType.LD_CONST_INT, 0L);
            addNewILCode(NakoILType.ST_LOCAL, loopVarNo);
            // 反復要素の評価
            //TODO:反復要素のGetEnumerator()を評価
            //GetEnumerator(); addNewILCode(NakoILType.CALL,"GetEnumerator")?
            //addNewILCode(NakoILType.ST_LOCAL, valueVarNo);
            Write_r(node.nodeValue); // 値を評価
            addNewILCode(NakoILType.ST_LOCAL, valueVarNo);
            addNewILCode(NakoILType.LD_LOCAL_REF, valueVarNo);
            addNewILCode(NakoILType.SYSCALL, enumeratorFuncNo);
            addNewILCode(NakoILType.ST_LOCAL, enumeratorVarNo);

            // (2) 条件をコードにする
            //TODO: MoveNext()=true
            NakoILCode label_for_cond = createLABEL("ITERATOR_COND" + labelId.ToString());
            result.Add(label_for_cond);
            // L
            //MoveNext()に変更
            addNewILCode(NakoILType.LD_LOCAL_REF, enumeratorVarNo);
            addNewILCode(NakoILType.SYSCALL, moveresultFuncNo);
            // R
            addNewILCode(NakoILType.LD_CONST_INT, true);//TODO:実際にコンパイルする時にこれはまずいはずなので、何か考える
            // LT
            addNewILCode(NakoILType.EQ);
            // IF BRANCH FALSE
            addNewILCode(NakoILType.BRANCH_FALSE, label_for_end);
            // 反復する値を変数「対象」にセット
            // ** 対象=値\(ループカウンタ)
            //TODO:対象=オブジェクト.Currentに変更
            addNewILCode(NakoILType.LD_LOCAL_REF, enumeratorVarNo);
            addNewILCode(NakoILType.SYSCALL,getcurrentFuncNo);
            //addNewILCode(NakoILType.NOP, "let-taisyou"); // for DEBUG
            addNewILCode(NakoILType.ST_LOCAL, taisyouVarNo);
            //TODO:key
            // ** 回数=ループカウンタ+1
            addNewILCode(NakoILType.LD_LOCAL, loopVarNo);
            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.INC_LOCAL, loopVarNo);

            // (5) 手順2に戻る
            result.Add(createJUMP(label_for_cond));
            result.Add(label_for_end);
            addNewILCode(NakoILType.LD_LOCAL_REF, enumeratorVarNo);
            addNewILCode(NakoILType.SYSCALL,getdisposeFuncNo);
            //TODO: EnumeratorをDisposeする
        }
Esempio n. 2
0
        //> _foreach : _value FOREACH _scope_or_statement
        //>          ;
        private bool _foreachUseIterator()
        {
            TokenTry();
            if (!_value()) return false;
            if (!Accept(NakoTokenType.FOREACH))
            {
                TokenBack();
                return false;
            }
            TokenFinally();
            tok.MoveNext(); // skip FOREACH

            NakoNodeForeach repnode = new NakoNodeForeach();
            // ローカル変数の領域を確保
            repnode.taisyouVarNo = localVar.GetIndex(NakoReservedWord.TAISYOU, true); // 変数「対象」の変数番号を取得
            repnode.kaisuVarNo = localVar.GetIndex(NakoReservedWord.KAISU, true); // カウンタ変数「回数」の変数番号を取得
            repnode.loopVarNo = localVar.CreateVarNameless(); // ループカウンタ
            repnode.lenVarNo = localVar.CreateVarNameless(); // 要素サイズを記録
            repnode.valueVarNo = localVar.CreateVarNameless(); // valueを評価した値を保持
            //下二行を追加(9-23)
            repnode.enumeratorVarNo = localVar.CreateVarNameless(); // valueのGetEnumeratorを保持
            repnode.enumeratorFuncNo = (int)globalVar.GetVar("GetEnumerator").Body;
            repnode.moveresultFuncNo = (int)globalVar.GetVar("MoveNext").Body;
            repnode.getcurrentFuncNo = (int)globalVar.GetVar("Current").Body;
            repnode.getdisposeFuncNo = (int)globalVar.GetVar("Dispose").Body;
            // ノードの取得
            repnode.nodeValue = calcStack.Pop();
            repnode.nodeBlocks = _scope_or_statement();

            this.parentNode.AddChild(repnode);
            lastNode = repnode;
            return true;
        }
Esempio n. 3
0
        //TODO:_foreachUseIteratorがOKならば消す
        private void _foreach(NakoNodeForeach node)
        {
            int labelId = GetLableId();
            int loopVarNo = node.loopVarNo;
            int lenVarNo = node.lenVarNo;
            int valueVarNo = node.valueVarNo;
            int taisyouVarNo = node.taisyouVarNo;
            int kaisuVarNo = node.kaisuVarNo;

            // (0)
            NakoILCode label_for_begin = createLABEL("FOREACH_BEGIN" + labelId.ToString());
            NakoILCode label_for_end = createLABEL("FOREACH_END" + labelId.ToString());

            // (1) 変数を初期化する
            result.Add(label_for_begin);
            // カウンタ変数を初期化
            addNewILCode(NakoILType.LD_CONST_INT, 0L);
            addNewILCode(NakoILType.ST_LOCAL, loopVarNo);
            // 反復要素の評価
            Write_r(node.nodeValue); // 値を評価
            addNewILCode(NakoILType.ST_LOCAL, valueVarNo);
            // 要素数を得る
            addNewILCode(NakoILType.LD_LOCAL, valueVarNo);
            addNewILCode(NakoILType.ARR_LENGTH);
            addNewILCode(NakoILType.ST_LOCAL, lenVarNo);

            // (2) 条件をコードにする
            // i < iTo
            NakoILCode label_for_cond = createLABEL("FOREACH_COND" + labelId.ToString());
            result.Add(label_for_cond);
            // L
            addNewILCode(NakoILType.LD_LOCAL, loopVarNo);
            // R
            addNewILCode(NakoILType.LD_LOCAL, lenVarNo);
            // LT
            addNewILCode(NakoILType.LT);
            // IF BRANCH FALSE
            addNewILCode(NakoILType.BRANCH_FALSE, label_for_end);
            // 反復する値を変数「対象」にセット
            // ** 対象=値\(ループカウンタ)
            addNewILCode(NakoILType.LD_LOCAL, valueVarNo);
            addNewILCode(NakoILType.LD_LOCAL, loopVarNo);
            addNewILCode(NakoILType.LD_ELEM_REF);
            //addNewILCode(NakoILType.NOP, "let-taisyou"); // for DEBUG
            addNewILCode(NakoILType.ST_LOCAL, taisyouVarNo);
            // ** 回数=ループカウンタ+1
            addNewILCode(NakoILType.LD_LOCAL, loopVarNo);
            addNewILCode(NakoILType.INC);
            addNewILCode(NakoILType.ST_LOCAL, kaisuVarNo);

            // (3) 繰り返し文を実行する
            _loop_check_break_continue(node.nodeBlocks, label_for_end, label_for_begin);
            Write_r(node.nodeBlocks);

            // (4) 変数を加算する
            addNewILCode(NakoILType.INC_LOCAL, loopVarNo);

            // (5) 手順2に戻る
            result.Add(createJUMP(label_for_cond));
            result.Add(label_for_end);
        }
Esempio n. 4
0
        //TODO:foreachUseIteratorがOKならば消す
        //> _foreach : _value FOREACH _scope_or_statement
        //>          ;
        private bool _foreach()
        {
            TokenTry();
            if (!_value()) return false;
            if (!Accept(NakoTokenType.FOREACH))
            {
                TokenBack();
                return false;
            }
            TokenFinally();
            tok.MoveNext(); // skip FOREACH

            NakoNodeForeach repnode = new NakoNodeForeach();
            // ローカル変数の領域を確保
            repnode.taisyouVarNo = localVar.GetIndex(NakoReservedWord.TAISYOU, true); // 変数「対象」の変数番号を取得
            repnode.kaisuVarNo = localVar.GetIndex(NakoReservedWord.KAISU, true); // カウンタ変数「回数」の変数番号を取得
            repnode.loopVarNo = localVar.CreateVarNameless(); // ループカウンタ
            repnode.lenVarNo = localVar.CreateVarNameless(); // 要素サイズを記録
            repnode.valueVarNo = localVar.CreateVarNameless(); // valueを評価した値を保持
            // ノードの取得
            repnode.nodeValue = calcStack.Pop();
            repnode.nodeBlocks = _scope_or_statement();

            this.parentNode.AddChild(repnode);
            lastNode = repnode;
            return true;
        }