예제 #1
0
        private void _if(NakoNodeIf node)
        {
            int labelId = GetLableId();

            // (1) 条件文をコードにする
            Write_r(node.nodeCond);
            // (2) コードの結果により分岐する
            // 分岐先をラベルとして作成
            NakoILCode label_endif = createLABEL("ENDIF" + labelId.ToString());
            NakoILCode label_else  = createLABEL("ELSE" + labelId.ToString());

            result.Add(new NakoILCode(NakoILType.BRANCH_FALSE, label_else));
            // (3) TRUE
            if (node.nodeTrue != null)
            {
                Write_r(node.nodeTrue);
                result.Add(createJUMP(label_endif));
            }
            // (4) FALSE
            result.Add(label_else);
            if (node.nodeFalse != null)
            {
                Write_r(node.nodeFalse);
            }
            result.Add(label_endif);
        }
예제 #2
0
 /// <summary>
 /// Sets the exception tables.
 /// </summary>
 public void SetExceptionTables()
 {
     for (int i = 0; i < result.Count; i++)
     {
         NakoILCode code = result[i];
         if (code.type != NakoILType.EXCEPTIONTABLE)
         {
             continue;
         }
         if (!(code.value is NakoException))
         {
             continue;
         }
         if (code.value is NakoException)
         {
             NakoException e = (NakoException)code.value;
             if (labels.ContainsKey(e.fromLabel))
             {
                 e.from   = (int)labels[e.fromLabel];
                 e.to     = (int)labels[e.targetLabel] - 1;                  //endTry?
                 e.target = (int)labels [e.targetLabel];
                 continue;
             }
             throw new NakoILWriterException("ExceptionTableが解決できません");
         }
     }
 }
예제 #3
0
        private void _def_function(NakoNodeDefFunction node)
        {
            // 必要なラベルを定義
            NakoILCode end_of_def_func = createLABEL("END_OF_DEF_FUNC_" + node.func.name);
            NakoILCode ret_of_def_func = createLABEL("RETURN_OF_DEF_FUNC_" + node.func.name);
            NakoILCode begin_def_func  = createLABEL("FUNC_" + node.func.name);

            node.defLabel = begin_def_func;

            // 関数の定義は実行しないので、end_of_def_func へ飛ぶ
            result.Add(createJUMP(end_of_def_func));
            // 関数の始まりラベルを定義
            result.Add(begin_def_func);
            // 引数をPOPする処理
            NakoFunc func = node.func;

            for (int i = 0; i < func.ArgCount; i++)
            {
                NakoFuncArg arg = func.args[i];
                NakoILCode  c   = new NakoILCode(NakoILType.ST_LOCAL, i);
                result.Add(c);
            }
            // 本文を定義
            _func_check_return(node.funcBody, ret_of_def_func);
            Write_r(node.funcBody);
            // 戻り値(変数「それ」)をスタックに載せる
            result.Add(ret_of_def_func);
            result.Add(new NakoILCode(NakoILType.LD_GLOBAL, (int)0));
            result.Add(new NakoILCode(NakoILType.RET, func.updateSore));
            // 関数の終わりを定義
            result.Add(end_of_def_func);
        }
예제 #4
0
        private void _call_function(NakoNodeCallFunction node)
        {
            // push args values
            if (node.argNodes != null)
            {
                for (int i = 0; i < node.argNodes.Count; i++)
                {
                    Write_r(node.argNodes[i]);
                }
            }
            NakoILCode code = new NakoILCode();

            if (node.func.funcType == Function.NakoFuncType.SysCall)
            {
                // NakoAPIFunc f = (NakoAPIFunc)node.func;
                code.type  = NakoILType.SYSCALL;
                code.value = node.func.varNo;
                result.Add(code);
            }
            else // UserCall
            {
                NakoILCode defLabel = ((NakoNodeDefFunction)node.value).defLabel;
                code.type  = NakoILType.USRCALL;
                code.value = defLabel;
                if (code.value == null)
                {
                    //一旦ラベルを設定出来なかったユーザー関数には定義のオブジェクトそのものを入れて、FixLabel内で設定しなおす
                    code.value = node.value;
                }
                result.Add(code);
            }
        }
예제 #5
0
        /// <summary>
        /// 構文解析の行われた TopNode に対して、ILコードの発行を行う
        /// 結果は、Codes に得られる
        /// </summary>
        public NakoILCodeList WriteIL()
        {
            var writer = new NakoILWriter();

            writer.Write(this.topNode);
            codes = writer.Result;
            for (int i = 0; i < this.GlobalVar.Count(); i++)  //interpreterで使えるように関数定義が保存されている変数をアドレスに変換
            {
                NakoVariable v = this.GlobalVar.GetVar(i);
                if (v.Body is NakoNodeDefFunction)
                {
                    NakoVariable   setVar = new NakoVariable();
                    string         label  = "FUNC_" + ((NakoNodeDefFunction)v.Body).func.name;
                    NakoILCodeList cl     = writer.Result;
                    for (int j = 0; j < cl.Count; j++)
                    {
                        NakoILCode c = cl [j];
                        if (c.value is string && (string)c.value == label)
                        {
                            setVar.SetBody(j, NakoVarType.Int);
                            break;
                        }
                    }
                    this.GlobalVar.SetVar(i, setVar);
                }
            }
            codes.globalVar = this.GlobalVar;
            return(Codes);
        }
예제 #6
0
//TODO:まだ実装できてない
        private void _try(NakoNodeTry node)
        {
            int        labelId       = GetLableId();
            NakoILCode label_try     = createLABEL("TRY" + labelId.ToString());
            NakoILCode label_catch   = createLABEL("CATCH" + labelId.ToString());
            NakoILCode label_finally = createLABEL("FINALLY" + labelId.ToString());

            // (0) Tryを埋め込む
            result.Add(label_try);
            // (1) 通常実行をコードにする
            Write_r(node.nodeTry);
            result.Add(createJUMP(label_finally));
            // (2) 例外処理
            result.Add(label_catch);
            //TODO ○○のエラーならば〜☆☆のエラーならば〜への対応
            //TODO ○○や☆☆のエラーならばへの対応
            if (node.nodeCatch != null)
            {
                Write_r(node.nodeCatch);
                result.Add(createJUMP(label_finally));
                NakoILCode c = new NakoILCode();
                c.type  = NakoILType.EXCEPTIONTABLE;
                c.value = new NakoException(label_try, label_catch, new Exception());
                result.Insert(0, c);
            }
            // (3) 最後に必ず実行する処理
            result.Add(label_finally);
            if (node.nodeFinally != null)
            {
                Write_r(node.nodeFinally);
            }
        }
예제 #7
0
        /// <summary>
        /// ラベルを生成する
        /// </summary>
        /// <param name="labelName"></param>
        /// <returns></returns>
        protected NakoILCode createLABEL(string labelName)
        {
            NakoILCode r = NakoILCode.newNop();

            r.value   = labelName;
            labels[r] = -1;
            return(r);
        }
예제 #8
0
        private void _branch_false(NakoILCode code)
        {
            object v = calcStack.Pop();

            if (NakoValueConveter.ToLong(v) == 0)
            {
                autoIncPos = false;
                runpos     = Convert.ToInt32((long)code.value);
            }
        }
예제 #9
0
        /// <summary>
        /// ILコードのタイプを参照型に直す
        /// </summary>
        /// <param name="c">変更したいコード</param>
        private void _varBy_change_ref(NakoILCode c)
        {
            switch (c.type)
            {
            case NakoILType.LD_LOCAL: c.type = NakoILType.LD_LOCAL_REF; break;

            case NakoILType.LD_GLOBAL: c.type = NakoILType.LD_GLOBAL_REF; break;

            case NakoILType.LD_ELEM: c.type = NakoILType.LD_ELEM_REF; break;
            }
        }
예제 #10
0
        private void exec_ret(NakoILCode code)
        {
            autoIncPos = false;
            NakoCallStack c = callStack.Pop();

            this.runpos = c.nextpos;
            if (((bool)code.value) == false)
            {
                globalVar.SetValue(0, c.sore);                // "それ"を関数実行前に戻す
            }
            this.localVar = c.localVar;
        }
예제 #11
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);
        }
예제 #12
0
        private void exec_usrcall(NakoILCode code)
        {
            NakoCallStack c = new NakoCallStack();

            c.localVar    = localVar;
            c.nextpos     = runpos + 1;
            c.sore        = globalVar.GetValue(0);
            this.localVar = new NakoVariableManager(NakoVariableScope.Local);
            callStack.Push(c);
            // JUMP
            autoIncPos = false;
            runpos     = Convert.ToInt32((long)code.value);
        }
예제 #13
0
        private void exec_syscall(NakoILCode code)
        {
            int              funcNo = (int)code.value;
            NakoAPIFunc      s      = NakoAPIFuncBank.Instance.FuncList[funcNo];
            NakoFuncCallInfo f      = new NakoFuncCallInfo(this);
            object           result = s.FuncDl(f);

            if (s.updateSore)
            {
                globalVar.SetValue(0, result); // 変数「それ」に値をセット
            }
            StackPush(result);                 // 関数の結果を PUSH する
        }
예제 #14
0
        /// <summary>
        /// ラベルを解決する
        /// </summary>
        public void FixLabel()
        {
            // 現在のラベル位置を調べる
            for (int i = 0; i < result.Count; i++)
            {
                NakoILCode code = result[i];
                if (code.type != NakoILType.NOP)
                {
                    continue;
                }
                if (labels.ContainsKey(code))
                {
                    labels[code] = i;
                }
            }
            // JUMP/BRANCH_TRUE/BRANCH_FALSE/CALL/USRCALL を解決する
            for (int i = 0; i < result.Count; i++)
            {
                NakoILCode code = result[i];
                switch (code.type)
                {
                case NakoILType.JUMP:
                case NakoILType.BRANCH_TRUE:
                case NakoILType.BRANCH_FALSE:
                case NakoILType.USRCALL:
                    break;

                default:
                    continue;
                }
                if (code.type == NakoILType.USRCALL && code.value is NakoNodeDefFunction)
                {
                    //一旦ラベルを設定出来なかったユーザー関数呼び出しコードには定義のオブジェクトそのものを入れたので、ラベルを張り替える
                    NakoNodeDefFunction def = (NakoNodeDefFunction)code.value;
                    code.value = def.defLabel;
                }
                if (!(code.value is NakoILCode))
                {
                    continue;
                }
                if (code.value is NakoILCode)
                {
                    if (labels.ContainsKey((NakoILCode)code.value))
                    {
                        code.value = (object)labels[(NakoILCode)code.value];
                        continue;
                    }
                    throw new NakoILWriterException("ラベルが解決できません");
                }
            }
        }
예제 #15
0
        // BREAK/CONTINUE文を解決する
        private void _loop_check_break_continue(NakoNode block, NakoILCode break_label, NakoILCode continue_label)
        {
            if (block == null)
            {
                return;
            }
            if (!block.hasChildren())
            {
                return;
            }
            for (int i = 0; i < block.Children.Count; i++)
            {
                NakoNode item = block.Children[i];

                switch (item.type)
                {
                case NakoNodeType.BREAK:
                    item.type = NakoNodeType.JUMP;
                    ((NakoNodeBreak)item).label = break_label;
                    break;

                case NakoNodeType.CONTINUE:
                    item.type = NakoNodeType.JUMP;
                    ((NakoNodeContinue)item).label = continue_label;
                    break;

                // ジャンプポイントが変わる構文があれば、その下層ブロックは処理しない
                case NakoNodeType.FOR: break;

                case NakoNodeType.WHILE: break;

                case NakoNodeType.REPEAT_TIMES: break;

                case NakoNodeType.FOREACH: break;

                case NakoNodeType.IF:
                    NakoNodeIf ifnode = (NakoNodeIf)item;
                    _loop_check_break_continue(ifnode.nodeTrue, break_label, continue_label);
                    _loop_check_break_continue(ifnode.nodeFalse, break_label, continue_label);
                    break;

                default:
                    if (item.hasChildren())
                    {
                        _loop_check_break_continue(item, break_label, continue_label);
                    }
                    break;
                }
            }
        }
예제 #16
0
        private void _let(NakoNodeLet node)
        {
            NakoNodeVariable varNode   = node.VarNode;
            NakoNode         valueNode = node.ValueNode;

            // 配列要素があるか確認
            if (!varNode.useElement)
            {
                // + 要素なしの代入処理
                // - 代入する値を書き込んで...
                Write_r(valueNode);
                // - セットする
                NakoILCode st = new NakoILCode();
                st.value = varNode.varNo;
                st.type  = (varNode.scope == NakoVariableScope.Global)
                    ? NakoILType.ST_GLOBAL
                    : NakoILType.ST_LOCAL;
                result.Add(st);
            }
            else // 配列要素があるとき
            {
                // + 配列への代入処理
                // - 基本となる変数をセット
                NakoILCode ldvar = new NakoILCode();
                ldvar.value = varNode.varNo;
                ldvar.type  = (varNode.scope == NakoVariableScope.Global)
                    ? NakoILType.LD_GLOBAL_REF
                    : NakoILType.LD_LOCAL_REF;
                result.Add(ldvar);
                // - アクセス要素をセット
                int count = varNode.Children.Count;
                for (int i = 0; i < count; i++)
                {
                    NakoNode n = varNode.Children[i];
                    Write_r(n); // ノードの値

                    if (i < count - 1)
                    {
                        result.Add(new NakoILCode(NakoILType.LD_ELEM_REF)); // 要素
                    }
                    else
                    {
                        // 値ノード
                        Write_r(valueNode);
                        addNewILCode(NakoILType.ST_ELEM);
                    }
                }
            }
        }
예제 #17
0
        private void newCalc(NakoNodeCalc node)
        {
            NakoILCode c = new NakoILCode();

            //
            Write_r(node.nodeL);
            Write_r(node.nodeR);
            //
            switch (node.calc_type)
            {
            case CalcType.NOP: c.type = NakoILType.NOP; break;     // ( ... )

            case CalcType.ADD: c.type = NakoILType.ADD; break;

            case CalcType.SUB: c.type = NakoILType.SUB; break;

            case CalcType.MUL: c.type = NakoILType.MUL; break;

            case CalcType.DIV: c.type = NakoILType.DIV; break;

            case CalcType.MOD: c.type = NakoILType.MOD; break;

            case CalcType.ADD_STR: c.type = NakoILType.ADD_STR; break;

            case CalcType.POWER: c.type = NakoILType.POWER; break;

            case CalcType.EQ: c.type = NakoILType.EQ; break;

            case CalcType.NOT_EQ: c.type = NakoILType.NOT_EQ; break;

            case CalcType.GT: c.type = NakoILType.GT; break;

            case CalcType.GT_EQ: c.type = NakoILType.GT_EQ; break;

            case CalcType.LT: c.type = NakoILType.LT; break;

            case CalcType.LT_EQ: c.type = NakoILType.LT_EQ; break;

            case CalcType.AND: c.type = NakoILType.AND; break;

            case CalcType.OR: c.type = NakoILType.OR; break;

            case CalcType.XOR: c.type = NakoILType.XOR; break;

            case CalcType.NEG: c.type = NakoILType.NEG; break;
            }
            result.Add(c);
        }
예제 #18
0
        private void _repeat_times(NakoNodeRepeatTimes node)
        {
            int labelId    = GetLableId();
            int kaisuVarNo = node.kaisuVarNo;

            // (0)
            NakoILCode label_for_begin = createLABEL("TIMES_BEGIN" + labelId.ToString());
            NakoILCode label_for_end   = createLABEL("TIMES_END" + labelId.ToString());

            // (1) 変数を初期化する
            result.Add(label_for_begin);
            addNewILCode(NakoILType.LD_CONST_INT, 1L);
            addNewILCode(NakoILType.ST_LOCAL, node.loopVarNo);
            // 何回実行するか回数を評価する
            Write_r(node.nodeTimes);
            addNewILCode(NakoILType.ST_LOCAL, node.timesVarNo);

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

            result.Add(label_for_cond);
            // L
            addNewILCode(NakoILType.LD_LOCAL, node.loopVarNo);
            // R
            addNewILCode(NakoILType.LD_LOCAL, node.timesVarNo);
            // LT_EQ
            addNewILCode(NakoILType.LT_EQ);
            // IF BRANCH FALSE
            addNewILCode(NakoILType.BRANCH_FALSE, label_for_end);

            //回数設定
            addNewILCode(NakoILType.LD_LOCAL, node.loopVarNo);
            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, node.loopVarNo);

            // (5) 手順2に戻る
            result.Add(createJUMP(label_for_cond));
            result.Add(label_for_end);
        }
예제 #19
0
 /// <summary>
 /// 実行
 /// </summary>
 /// <returns></returns>
 protected bool _run()
 {
     while (runpos < list.Count)
     {
         NakoILCode code = this.list[runpos];
         Run_NakoIL(code);
         if (autoIncPos)
         {
             runpos++;
         }
         else
         {
             autoIncPos = true;
         }
     }
     return(true);
 }
예제 #20
0
        // RETURN文を解決する
        private void _func_check_return(NakoNode block, NakoILCode return_label)
        {
            if (block == null)
            {
                return;
            }
            if (!block.hasChildren())
            {
                return;
            }
            for (int i = 0; i < block.Children.Count; i++)
            {
                NakoNode item = block.Children[i];

                switch (item.type)
                {
                case NakoNodeType.RETURN:
                    item.type = NakoNodeType.JUMP;
                    ((NakoNodeReturn)item).label = return_label;
                    break;

                // ジャンプポイントが変わる構文があれば、その下層ブロックは処理しない
                case NakoNodeType.FOR: break;

                case NakoNodeType.WHILE: break;

                case NakoNodeType.REPEAT_TIMES: break;

                case NakoNodeType.FOREACH: break;

                case NakoNodeType.IF:
                    NakoNodeIf ifnode = (NakoNodeIf)item;
                    _func_check_return(ifnode.nodeTrue, return_label);
                    _func_check_return(ifnode.nodeFalse, return_label);
                    break;

                default:
                    if (item.hasChildren())
                    {
                        _func_check_return(item, return_label);
                    }
                    break;
                }
            }
        }
예제 #21
0
        private void _throw(NakoILCode code)
        {
            //TODO:check exception table which include runpos and jump if not throw NakoException
            int catchpos = (exceptionTable == null)? -1 : exceptionTable.GetCatchLine(runpos, code.value);

            if (catchpos == this.runpos)
            {
                thrownCode = code;
            }
            else
            {
                thrownCode  = null;
                this.runpos = catchpos;
            }
            if (this.runpos == -1)
            {
                throw new NakoInterpreterException("例外");
            }
        }
예제 #22
0
        private void _while(NakoNodeWhile node)
        {
            int labelId = GetLableId();
            // (1) 条件をコードにする
            NakoILCode label_while_begin = createLABEL("WHILE_BEGIN" + labelId.ToString());

            result.Add(label_while_begin);
            Write_r(node.nodeCond);
            // (2) コードの結果により分岐する
            // 分岐先をラベルとして作成
            NakoILCode label_while_end = createLABEL("WHILE_END" + labelId.ToString());

            addNewILCode(NakoILType.BRANCH_FALSE, label_while_end);
            // (3) ループブロックを書き込む
            _loop_check_break_continue(node.nodeBlocks, label_while_end, label_while_begin);
            Write_r(node.nodeBlocks);
            result.Add(createJUMP(label_while_begin));
            result.Add(label_while_end);
        }
예제 #23
0
        private void _getVariable(NakoNodeVariable node)
        {
            NakoILCode ld = new NakoILCode();

            if (!node.useElement)
            {
                // + 変数アクセス
                ld.type = (node.scope == NakoVariableScope.Global)
                    ? NakoILType.LD_GLOBAL
                    : NakoILType.LD_LOCAL;
                if (node.varBy == VarByType.ByRef)
                {
                    _varBy_change_ref(ld);
                }
                ld.value = node.varNo;
                result.Add(ld);
            }
            else
            {
                // + 配列変数アクセス
                // - 変数
                ld.type = (node.scope == NakoVariableScope.Global)
                    ? NakoILType.LD_GLOBAL
                    : NakoILType.LD_LOCAL;
                ld.value = node.varNo;
                result.Add(ld);
                // - 要素
                NakoNodeList c = node.Children;
                for (int i = 0; i < c.Count; i++)
                {
                    Write_r(c[i]);
                    NakoILCode code = new NakoILCode();

                    /*
                     * code.type = ((c.Count - 1) == i)
                     *  ? NakoILType.LD_ELEM
                     *  : NakoILType.LD_ELEM_REF;
                     */
                    code.type = NakoILType.LD_ELEM;
                    result.Add(code);
                }
            }
        }
예제 #24
0
        /// <summary>
        /// Callback the specified sender, func_name and args.
        /// </summary>
        /// <param name="sender">Sender.</param>
        /// <param name="func_name">Func name.</param>
        /// <param name="args">Arguments.</param>
        public void CallUserFunc(string func_name, params object[] args)
        {
            NakoILCode c = null;

            foreach (NakoILCode tmp in this.list)
            {
                if (tmp.type == NakoILType.NOP && (string)tmp.value == "FUNC_" + func_name)
                {
                    c = tmp;
                    break;
                }
            }
            if (c == null)
            {
                return;// _nop;
            }
            currentIL = c;
            //StackPush (sender);
            foreach (object o in args)
            {
                StackPush(o);
            }
            NakoCallStack stack = new NakoCallStack();
            //escape
            int    currentPos        = runpos;
            bool   currentAutoIncPos = autoIncPos;
            object currentSore       = globalVar.GetValue(0);

            stack.localVar = localVar;
            stack.nextpos  = list.Count + 1; // ストッパー
            stack.sore     = globalVar.GetValue(0);
            //prepare
            this.localVar = new NakoVariableManager(NakoVariableScope.Local);
            autoIncPos    = true;
            runpos        = this.list.IndexOf(currentIL);
            callStack.Push(stack);
            //int baseStackCount=callStack.Count;
            _run();
            runpos     = currentPos;
            autoIncPos = currentAutoIncPos;
            globalVar.SetValue(0, currentSore);
        }
예제 #25
0
        private void _call_function(NakoNodeCallFunction node)
        {
            // push args values
            if (node.argNodes != null)
            {
                for (int i = 0; i < node.argNodes.Count; i++)
                {
                    Write_r(node.argNodes[i]);
                }
            }
            NakoILCode code = new NakoILCode();

            if (node.func.funcType == Function.NakoFuncType.SysCall)
            {
                // NakoAPIFunc f = (NakoAPIFunc)node.func;
                code.type  = NakoILType.SYSCALL;
                code.value = node.func.varNo;
                result.Add(code);
            }
            else // UserCall
            {
                NakoILCode defLabel = ((NakoNodeDefFunction)node.value).defLabel;
                code.type  = NakoILType.USRCALL;
                code.value = defLabel;
                if (code.value == null)
                {
                    //一旦ラベルを設定出来なかったユーザー関数には定義のオブジェクトそのものを入れて、FixLabel内で設定しなおす
                    if (node.func.name != null)
                    {
                        code.value = node.value;
                    }
                    else
                    {
                        //ユーザー関数名がないもの(引数が関数定義だった場合)は、呼び出し先の情報が入った変数を取り出すILを書く
                        addNewILCode(NakoILType.LD_LOCAL, node.func.varNo);
                    }
                }
                result.Add(code);
            }
        }
예제 #26
0
 /// <summary>
 /// ILコードのタイプを参照型に直す
 /// </summary>
 /// <param name="c">変更したいコード</param>
 private void _varBy_change_ref(NakoILCode c)
 {
     switch (c.type)
     {
         case NakoILType.LD_LOCAL: c.type = NakoILType.LD_LOCAL_REF; break;
         case NakoILType.LD_GLOBAL: c.type = NakoILType.LD_GLOBAL_REF; break;
         case NakoILType.LD_ELEM: c.type = NakoILType.LD_ELEM_REF; break;
     }
 }
예제 #27
0
 private void exec_usrcall(NakoILCode code)
 {
     NakoCallStack c = new NakoCallStack();
     c.localVar = localVar;
     c.nextpos = runpos + 1;
     c.sore = globalVar.GetValue(0);
     this.localVar = new NakoVariableManager(NakoVariableScope.Local);
     callStack.Push(c);
     // JUMP
     autoIncPos = false;
     runpos = Convert.ToInt32((long)code.value);
 }
예제 #28
0
        // BREAK/CONTINUE文を解決する
        private void _loop_check_break_continue(NakoNode block, NakoILCode break_label, NakoILCode continue_label)
        {
            if (block == null) return;
            if (!block.hasChildren()) return;
            for (int i = 0; i < block.Children.Count; i++)
            {
                NakoNode item = block.Children[i];

                switch (item.type)
                {
                    case NakoNodeType.BREAK:
                        item.type = NakoNodeType.JUMP;
                        ((NakoNodeBreak)item).label = break_label;
                        break;
                    case NakoNodeType.CONTINUE:
                        item.type = NakoNodeType.JUMP;
                        ((NakoNodeContinue)item).label = continue_label;
                        break;

                    // ジャンプポイントが変わる構文があれば、その下層ブロックは処理しない
                    case NakoNodeType.FOR: break;
                    case NakoNodeType.WHILE: break;
                    case NakoNodeType.REPEAT_TIMES: break;
                    case NakoNodeType.FOREACH: break;
                    case NakoNodeType.IF:
                        NakoNodeIf ifnode = (NakoNodeIf)item;
                        _loop_check_break_continue(ifnode.nodeTrue,  break_label, continue_label);
                        _loop_check_break_continue(ifnode.nodeFalse, break_label, continue_label);
                        break;
                    default:
                        if (item.hasChildren())
                        {
                            _loop_check_break_continue(item, break_label, continue_label);
                        }
                        break;
                }
            }
        }
예제 #29
0
 //TODO:まだ実装できてない
 private void _try(NakoNodeTry node)
 {
     int labelId = GetLableId();
     NakoILCode label_try = createLABEL("TRY" + labelId.ToString());
     NakoILCode label_catch = createLABEL("CATCH" + labelId.ToString());
     NakoILCode label_finally = createLABEL("FINALLY" + labelId.ToString());
     // (0) Tryを埋め込む
     result.Add(label_try);
     // (1) 通常実行をコードにする
     Write_r(node.nodeTry);
     result.Add(createJUMP(label_finally));
     // (2) 例外処理
     result.Add(label_catch);
     //TODO ○○のエラーならば〜☆☆のエラーならば〜への対応
     //TODO ○○や☆☆のエラーならばへの対応
        if (node.nodeCatch != null)
     {
         Write_r(node.nodeCatch);
         result.Add(createJUMP(label_finally));
         NakoILCode c = new NakoILCode ();
         c.type = NakoILType.EXCEPTIONTABLE;
         c.value = new NakoException (label_try,label_catch,new Exception());
         result.Insert (0, c);
        }
     // (3) 最後に必ず実行する処理
     result.Add(label_finally);
     if (node.nodeFinally != null)
     {
         Write_r(node.nodeFinally);
     }
 }
예제 #30
0
 private void _jump(NakoNodeJump node)
 {
     NakoILCode jmp = new NakoILCode(NakoILType.JUMP, node.label);
     result.Add(jmp);
 }
예제 #31
0
        private void _let(NakoNodeLet node)
        {
            NakoNodeVariable varNode = node.VarNode;
            NakoNode valueNode = node.ValueNode;

            // 配列要素があるか確認
            if (!varNode.useElement)
            {
                // + 要素なしの代入処理
                // - 代入する値を書き込んで...
                Write_r(valueNode);
                // - セットする
                NakoILCode st = new NakoILCode();
                st.value = varNode.varNo;
                st.type = (varNode.scope == NakoVariableScope.Global)
                    ? NakoILType.ST_GLOBAL
                    : NakoILType.ST_LOCAL;
                result.Add(st);
            }
            else // 配列要素があるとき
            {
                // + 配列への代入処理
                // - 基本となる変数をセット
                NakoILCode ldvar = new NakoILCode();
                ldvar.value = varNode.varNo;
                ldvar.type = (varNode.scope == NakoVariableScope.Global)
                    ? NakoILType.LD_GLOBAL_REF
                    : NakoILType.LD_LOCAL_REF;
                result.Add(ldvar);
                // - アクセス要素をセット
                int count = varNode.Children.Count;
                for (int i = 0; i < count; i++)
                {
                    NakoNode n = varNode.Children[i];
                    Write_r(n); // ノードの値

                    if (i < count - 1)
                    {
                        result.Add(new NakoILCode(NakoILType.LD_ELEM_REF)); // 要素
                    }
                    else
                    {
                        // 値ノード
                        Write_r(valueNode);
                        addNewILCode(NakoILType.ST_ELEM);
                    }
                }
            }
        }
예제 #32
0
 private void _jump(NakoILCode code)
 {
     autoIncPos = false;
     runpos     = Convert.ToInt32((long)(code.value));
 }
예제 #33
0
 private void _branch_true(NakoILCode code)
 {
     object v = calcStack.Pop();
     if (NakoValueConveter.ToLong(v) > 0)
     {
         autoIncPos = false;
         runpos = Convert.ToInt32((long)code.value);
     }
 }
예제 #34
0
 private void exec_syscall(NakoILCode code)
 {
     int funcNo = (int)code.value;
     NakoAPIFunc s = NakoAPIFuncBank.Instance.FuncList[funcNo];
     NakoFuncCallInfo f = new NakoFuncCallInfo(this);
     object result = s.FuncDl(f);
     if (s.updateSore)
         globalVar.SetValue(0, result); // 変数「それ」に値をセット
     StackPush(result); // 関数の結果を PUSH する
 }
예제 #35
0
 private void _exceptionTable(NakoILCode code)
 {
     exceptionTable.Add ((NakoException)code.value);
 }
예제 #36
0
        /// <summary>
        /// ILを実行する
        /// </summary>
        /// <param name="code"></param>
        protected void Run_NakoIL(NakoILCode code)
        {
            if (debugMode)
            {
                int    i = runpos;
                string s = "";
                s += String.Format("{0,4:X4}:", i);
                s += String.Format("{0,-14}", code.type.ToString());
                s += code.GetDescription();
                Console.WriteLine(s);
            }

            if (thrownCode != null)
            {
                if (code.type == NakoILType.JUMP)
                {
                    _jump(code);
                    _throw(thrownCode);
                }
                else if (code.type == NakoILType.RET)
                {
                    exec_ret(code);
                    _throw(thrownCode);
                }
                else if (code.type == NakoILType.LD_GLOBAL)
                {
                    ld_global((int)code.value);
                }
                return;
            }

            switch (code.type)
            {
            case NakoILType.NOP:
                /* do nothing */
                break;

            case NakoILType.POP:            StackPop(); break;

            // 定数をスタックに乗せる
            case NakoILType.LD_CONST_INT:   StackPush(code.value); break;

            case NakoILType.LD_CONST_REAL:  StackPush(code.value); break;

            case NakoILType.LD_CONST_STR:   StackPush(code.value); break;

            // 変数の値をスタックに乗せる
            case NakoILType.LD_GLOBAL:      ld_global((int)code.value); break;

            case NakoILType.LD_LOCAL:       ld_local((int)code.value); break;

            case NakoILType.LD_GLOBAL_REF:  ld_global_ref((int)code.value); break;

            case NakoILType.LD_LOCAL_REF:   ld_local_ref((int)code.value); break;

            case NakoILType.ST_GLOBAL:      st_global((int)code.value); break;

            case NakoILType.ST_LOCAL:       st_local((int)code.value); break;

            case NakoILType.LD_ELEM:        ld_elem(); break;

            case NakoILType.LD_ELEM_REF:    ld_elem_ref(); break;

            case NakoILType.ST_ELEM:        st_elem(); break;

            case NakoILType.ARR_LENGTH:     arr_length(); break;

            // 計算処理
            case NakoILType.ADD:        exec_calc(calc_method_add); break;

            case NakoILType.SUB:        exec_calc(calc_method_sub); break;

            case NakoILType.MUL:        exec_calc(calc_method_mul); break;

            case NakoILType.DIV:        exec_calc(calc_method_div); break;

            case NakoILType.MOD:        exec_calc(calc_method_mod); break;

            case NakoILType.POWER:      exec_calc(calc_method_power); break;

            case NakoILType.ADD_STR:    exec_calc(calc_method_add_str); break;

            case NakoILType.EQ:         exec_calc(calc_method_eq); break;

            case NakoILType.NOT_EQ:     exec_calc(calc_method_not_eq); break;

            case NakoILType.GT:         exec_calc(calc_method_gt); break;

            case NakoILType.GT_EQ:      exec_calc(calc_method_gteq); break;

            case NakoILType.LT:         exec_calc(calc_method_lt); break;

            case NakoILType.LT_EQ:      exec_calc(calc_method_lteq); break;

            case NakoILType.INC:        _inc(); break;

            case NakoILType.DEC:        _dec(); break;

            case NakoILType.NEG:        _neg(); break;

            case NakoILType.AND:        exec_calc(calc_method_and); break;

            case NakoILType.OR:         exec_calc(calc_method_or); break;

            case NakoILType.XOR:        exec_calc(calc_method_xor); break;

            case NakoILType.NOT:        _not(); break;

            // ジャンプ
            case NakoILType.JUMP:           _jump(code); break;

            // 条件ジャンプ
            case NakoILType.BRANCH_TRUE:    _branch_true(code); break;

            case NakoILType.BRANCH_FALSE:   _branch_false(code); break;

            // 関数コール
            case NakoILType.SYSCALL:        exec_syscall(code); break;

            case NakoILType.USRCALL:        exec_usrcall(code); break;

            case NakoILType.RET:            exec_ret(code); break;

            // デバッグ用
            case NakoILType.PRINT:          exec_print(); break;

            // ローカル変数に対する操作
            case NakoILType.INC_LOCAL: inc_local(code); break;

            case NakoILType.DEC_LOCAL: dec_local(code); break;

            case NakoILType.DUP: dup(); break;

            //exception
            case NakoILType.THROW:            _throw(code); break;

            //exceptionTable
            case NakoILType.EXCEPTIONTABLE:         _exceptionTable(code); break;

            //
            default:
                throw new NakoInterpreterException("未実装のILコード");
            }
        }
예제 #37
0
 /// <summary>
 /// ラベルジャンプを生成する
 /// </summary>
 /// <param name="label"></param>
 /// <returns></returns>
 protected NakoILCode createJUMP(NakoILCode label)
 {
     NakoILCode r = new NakoILCode(NakoILType.JUMP, label);
     return r;
 }
예제 #38
0
 private void inc_local(NakoILCode code)
 {
     NakoVariable v = localVar.GetVar((int)code.value);
     v.AsInt++;
 }
예제 #39
0
        /// <summary>
        /// 中間コードを書き出す
        /// </summary>
        /// <param name="node"></param>
        protected void Write_r(NakoNode node)
        {
            if (node == null)
            {
                return;
            }
            switch (node.type)
            {
            case NakoNodeType.NOP:
                result.Add(NakoILCode.newNop());
                break;

            case NakoNodeType.CALC:
                newCalc((NakoNodeCalc)node);
                return;

            case NakoNodeType.INT:
                result.Add(new NakoILCode(NakoILType.LD_CONST_INT, node.value));
                return;

            case NakoNodeType.NUMBER:
                result.Add(new NakoILCode(NakoILType.LD_CONST_REAL, node.value));
                return;

            case NakoNodeType.STRING:
                result.Add(new NakoILCode(NakoILType.LD_CONST_STR, node.value));
                return;

            case NakoNodeType.POP:
                result.Add(new NakoILCode(NakoILType.POP));
                return;

            case NakoNodeType.PRINT:
                _print(node);
                return;

            case NakoNodeType.ST_VARIABLE:
                _setVariable((NakoNodeVariable)node);
                return;

            case NakoNodeType.LET:
                _let((NakoNodeLet)node);
                return;

            case NakoNodeType.LD_VARIABLE:
                _getVariable((NakoNodeVariable)node);
                return;

            case NakoNodeType.IF:
                _if((NakoNodeIf)node);
                return;

            case NakoNodeType.WHILE:
                _while((NakoNodeWhile)node);
                return;

            case NakoNodeType.FOR:
                _for((NakoNodeFor)node);
                return;

            case NakoNodeType.BREAK:
                addNewILCode(NakoILType.NOP, "BREAK");
                return;

            case NakoNodeType.CONTINUE:
                addNewILCode(NakoILType.NOP, "CONTINUE");
                return;

            case NakoNodeType.RETURN:
                addNewILCode(NakoILType.NOP, "RETURN");
                return;

            case NakoNodeType.REPEAT_TIMES:
                _repeat_times((NakoNodeRepeatTimes)node);
                return;

            case NakoNodeType.FOREACH:
                _foreachUseIterator((NakoNodeForeach)node);
                //_foreach((NakoNodeForeach)node);
                return;

            case NakoNodeType.CALL_FUNCTION:
                _call_function((NakoNodeCallFunction)node);
                return;

            case NakoNodeType.DEF_FUNCTION:
                _def_function((NakoNodeDefFunction)node);
                return;

            case NakoNodeType.JUMP:
                _jump((NakoNodeJump)node);
                return;

            //TODO
            case NakoNodeType.LET_VALUE:
                addNewILCode(NakoILType.NOP, "LET_VALUE");
                break;

            case NakoNodeType.TRY:
                _try((NakoNodeTry)node);
                return;

            case NakoNodeType.THROW:
                _throw((NakoNodeThrow)node);
                return;

            default:
                throw new NakoCompilerException("未定義のノードタイプ: " + node.type.ToString());
            }
            // ---
            if (!node.hasChildren())
            {
                return;
            }
            Write_list(node.Children);
        }
예제 #40
0
 private void _jump(NakoILCode code)
 {
     autoIncPos = false;
     runpos = Convert.ToInt32((long)(code.value));
 }
예제 #41
0
 private void newCalc(NakoNodeCalc node)
 {
     NakoILCode c = new NakoILCode();
     //
     Write_r(node.nodeL);
     Write_r(node.nodeR);
     //
     switch (node.calc_type)
     {
         case CalcType.NOP: c.type = NakoILType.NOP; break; // ( ... )
         case CalcType.ADD: c.type = NakoILType.ADD; break;
         case CalcType.SUB: c.type = NakoILType.SUB; break;
         case CalcType.MUL: c.type = NakoILType.MUL; break;
         case CalcType.DIV: c.type = NakoILType.DIV; break;
         case CalcType.MOD: c.type = NakoILType.MOD; break;
         case CalcType.ADD_STR: c.type = NakoILType.ADD_STR; break;
         case CalcType.POWER: c.type = NakoILType.POWER; break;
         case CalcType.EQ: c.type = NakoILType.EQ; break;
         case CalcType.NOT_EQ: c.type = NakoILType.NOT_EQ; break;
         case CalcType.GT: c.type = NakoILType.GT; break;
         case CalcType.GT_EQ: c.type = NakoILType.GT_EQ; break;
         case CalcType.LT: c.type = NakoILType.LT; break;
         case CalcType.LT_EQ: c.type = NakoILType.LT_EQ; break;
         case CalcType.AND: c.type = NakoILType.AND; break;
         case CalcType.OR: c.type = NakoILType.OR; break;
         case CalcType.XOR: c.type = NakoILType.XOR; break;
         case CalcType.NEG: c.type = NakoILType.NEG; break;
     }
     result.Add(c);
 }
예제 #42
0
        /// <summary>
        /// ILを実行する
        /// </summary>
        /// <param name="code"></param>
        protected void Run_NakoIL(NakoILCode code)
        {
            if (debugMode)
            {
                int i = runpos;
                string s = "";
                s += String.Format("{0,4:X4}:", i);
                s += String.Format("{0,-14}", code.type.ToString());
                s += code.GetDescription();
                Console.WriteLine(s);
            }

            if (thrownCode != null) {
                if (code.type == NakoILType.JUMP) {
                    _jump (code);
                    _throw (thrownCode);
                } else if (code.type == NakoILType.RET) {
                    exec_ret (code);
                    _throw (thrownCode);
                } else if (code.type == NakoILType.LD_GLOBAL) {
                    ld_global((int)code.value);
                }
                return;
            }

            switch (code.type)
            {
                case NakoILType.NOP:
                    /* do nothing */
                    break;
                case NakoILType.POP:            StackPop(); break;
                // 定数をスタックに乗せる
                case NakoILType.LD_CONST_INT:   StackPush(code.value); break;
                case NakoILType.LD_CONST_REAL:  StackPush(code.value); break;
                case NakoILType.LD_CONST_STR:   StackPush(code.value); break;
                // 変数の値をスタックに乗せる
                case NakoILType.LD_GLOBAL:      ld_global((int)code.value); break;
                case NakoILType.LD_LOCAL:       ld_local((int)code.value); break;
                case NakoILType.LD_GLOBAL_REF:  ld_global_ref((int)code.value); break;
                case NakoILType.LD_LOCAL_REF:   ld_local_ref((int)code.value); break;
                case NakoILType.ST_GLOBAL:      st_global((int)code.value); break;
                case NakoILType.ST_LOCAL:       st_local((int)code.value); break;
                case NakoILType.LD_ELEM:        ld_elem(); break;
                case NakoILType.LD_ELEM_REF:    ld_elem_ref(); break;
                case NakoILType.ST_ELEM:        st_elem(); break;
                case NakoILType.ARR_LENGTH:     arr_length(); break;
                // 計算処理
                case NakoILType.ADD:        exec_calc(calc_method_add); break;
                case NakoILType.SUB:        exec_calc(calc_method_sub); break;
                case NakoILType.MUL:        exec_calc(calc_method_mul); break;
                case NakoILType.DIV:        exec_calc(calc_method_div); break;
                case NakoILType.MOD:        exec_calc(calc_method_mod); break;
                case NakoILType.POWER:      exec_calc(calc_method_power); break;
                case NakoILType.ADD_STR:    exec_calc(calc_method_add_str); break;
                case NakoILType.EQ:         exec_calc(calc_method_eq); break;
                case NakoILType.NOT_EQ:     exec_calc(calc_method_not_eq); break;
                case NakoILType.GT:         exec_calc(calc_method_gt); break;
                case NakoILType.GT_EQ:      exec_calc(calc_method_gteq); break;
                case NakoILType.LT:         exec_calc(calc_method_lt); break;
                case NakoILType.LT_EQ:      exec_calc(calc_method_lteq); break;
                case NakoILType.INC:        _inc(); break;
                case NakoILType.DEC:        _dec(); break;
                case NakoILType.NEG:        _neg(); break;
                case NakoILType.AND:        exec_calc(calc_method_and); break;
                case NakoILType.OR:         exec_calc(calc_method_or); break;
                case NakoILType.XOR:        exec_calc(calc_method_xor); break;
                case NakoILType.NOT:        _not(); break;
                // ジャンプ
                case NakoILType.JUMP:           _jump(code); break;
                // 条件ジャンプ
                case NakoILType.BRANCH_TRUE:    _branch_true(code); break;
                case NakoILType.BRANCH_FALSE:   _branch_false(code); break;
                // 関数コール
                case NakoILType.SYSCALL:        exec_syscall(code); break;
                case NakoILType.USRCALL:        exec_usrcall(code); break;
                case NakoILType.RET:            exec_ret(code); break;
                // デバッグ用
                case NakoILType.PRINT:          exec_print(); break;
                // ローカル変数に対する操作
                case NakoILType.INC_LOCAL: inc_local(code); break;
                case NakoILType.DEC_LOCAL: dec_local(code); break;
                case NakoILType.DUP: dup(); break;
                //exception
                case NakoILType.THROW:            _throw(code); break;
                //exceptionTable
                case NakoILType.EXCEPTIONTABLE:		_exceptionTable(code); break;
                //
                default:
                    throw new NakoInterpreterException("未実装のILコード");
            }
        }
예제 #43
0
        private void dec_local(NakoILCode code)
        {
            NakoVariable v = localVar.GetVar((int)code.value);

            v.AsInt--;
        }
예제 #44
0
 private void _call_function(NakoNodeCallFunction node)
 {
     // push args values
     if (node.argNodes != null)
     {
         for (int i = 0; i < node.argNodes.Count; i++)
         {
             Write_r(node.argNodes[i]);
         }
     }
     NakoILCode code = new NakoILCode();
     if (node.func.funcType == Function.NakoFuncType.SysCall)
     {
         // NakoAPIFunc f = (NakoAPIFunc)node.func;
         code.type = NakoILType.SYSCALL;
         code.value = node.func.varNo;
         result.Add(code);
     }
     else // UserCall
     {
         NakoILCode defLabel = ((NakoNodeDefFunction)node.value).defLabel;
         code.type = NakoILType.USRCALL;
         code.value = defLabel;
         if (code.value == null) {
             //一旦ラベルを設定出来なかったユーザー関数には定義のオブジェクトそのものを入れて、FixLabel内で設定しなおす
             code.value = node.value;
         }
         result.Add(code);
     }
 }
예제 #45
0
 private void _exceptionTable(NakoILCode code)
 {
     exceptionTable.Add((NakoException)code.value);
 }
예제 #46
0
        private void _def_function(NakoNodeDefFunction node)
        {
            // 必要なラベルを定義
            NakoILCode end_of_def_func = createLABEL("END_OF_DEF_FUNC_" + node.func.name);
            NakoILCode ret_of_def_func = createLABEL("RETURN_OF_DEF_FUNC_" + node.func.name);
            NakoILCode begin_def_func = createLABEL("FUNC_" + node.func.name);
            node.defLabel = begin_def_func;

            // 関数の定義は実行しないので、end_of_def_func へ飛ぶ
            result.Add(createJUMP(end_of_def_func));
            // 関数の始まりラベルを定義
            result.Add(begin_def_func);
            // 引数をPOPする処理
            NakoFunc func = node.func;
            for (int i = 0; i < func.ArgCount; i++)
            {
                NakoFuncArg arg = func.args[i];
                NakoILCode c = new NakoILCode(NakoILType.ST_LOCAL, i);
                result.Add(c);
            }
            // 本文を定義
            _func_check_return(node.funcBody, ret_of_def_func);
            Write_r(node.funcBody);
            // 戻り値(変数「それ」)をスタックに載せる
            result.Add(ret_of_def_func);
            result.Add(new NakoILCode(NakoILType.LD_GLOBAL, (int)0));
            result.Add(new NakoILCode(NakoILType.RET, func.updateSore));
            // 関数の終わりを定義
            result.Add(end_of_def_func);
        }
예제 #47
0
 private void exec_ret(NakoILCode code)
 {
     autoIncPos = false;
     NakoCallStack c = callStack.Pop();
     this.runpos = c.nextpos;
     if (((bool)code.value) == false)
         globalVar.SetValue(0, c.sore);// "それ"を関数実行前に戻す
     this.localVar = c.localVar;
 }
예제 #48
0
        // RETURN文を解決する
        private void _func_check_return(NakoNode block, NakoILCode return_label)
        {
            if (block == null) return;
            if (!block.hasChildren()) return;
            for (int i = 0; i < block.Children.Count; i++)
            {
                NakoNode item = block.Children[i];

                switch (item.type)
                {
                    case NakoNodeType.RETURN:
                       item.type = NakoNodeType.JUMP;
                        ((NakoNodeReturn)item).label = return_label;
                        break;

                    // ジャンプポイントが変わる構文があれば、その下層ブロックは処理しない
                    case NakoNodeType.FOR: break;
                    case NakoNodeType.WHILE: break;
                    case NakoNodeType.REPEAT_TIMES: break;
                    case NakoNodeType.FOREACH: break;
                    case NakoNodeType.IF:
                        NakoNodeIf ifnode = (NakoNodeIf)item;
                        _func_check_return(ifnode.nodeTrue, return_label);
                        _func_check_return(ifnode.nodeFalse, return_label);
                        break;
                    default:
                        if (item.hasChildren())
                        {
                            _func_check_return(item, return_label);
                        }
                        break;
                }
            }
        }
예제 #49
0
 private void _throw(NakoILCode code)
 {
     //TODO:check exception table which include runpos and jump if not throw NakoException
     int catchpos = (exceptionTable==null)? -1 : exceptionTable.GetCatchLine (runpos, code.value);
     if (catchpos == this.runpos) {
         thrownCode = code;
     } else {
         thrownCode = null;
         this.runpos = catchpos;
     }
     if (this.runpos == -1) {
         throw new NakoInterpreterException ("例外");
     }
 }
예제 #50
0
 private void _getVariable(NakoNodeVariable node)
 {
     NakoILCode ld = new NakoILCode();
     if (!node.useElement)
     {
         // + 変数アクセス
         ld.type = (node.scope == NakoVariableScope.Global)
             ? NakoILType.LD_GLOBAL
             : NakoILType.LD_LOCAL;
         if (node.varBy == VarByType.ByRef) _varBy_change_ref(ld);
         ld.value = node.varNo;
         result.Add(ld);
     }
     else
     {
         // + 配列変数アクセス
         // - 変数
         ld.type = (node.scope == NakoVariableScope.Global)
             ? NakoILType.LD_GLOBAL
             : NakoILType.LD_LOCAL;
         ld.value = node.varNo;
         result.Add(ld);
         // - 要素
         NakoNodeList c = node.Children;
         for (int i = 0; i < c.Count; i++)
         {
             Write_r(c[i]);
             NakoILCode code = new NakoILCode();
             /*
             code.type = ((c.Count - 1) == i)
                 ? NakoILType.LD_ELEM
                 : NakoILType.LD_ELEM_REF;
              */
             code.type = NakoILType.LD_ELEM;
             result.Add(code);
         }
     }
 }