Пример #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
        // 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;
                }
            }
        }
Пример #3
0
        //> _if_stmt : IF _value THEN [EOL] _scope_or_statement [ ELSE _scope_or_statement ]
        //>          ;
        private bool _if_stmt()
        {
            if (!Accept(NakoTokenType.IF))
            {
                return(false);
            }
            tok.MoveNext(); // skip IF

            NakoNodeIf ifnode = new NakoNodeIf();

            // _value
            NakoToken t = tok.CurrentToken;

            if (!_value())
            {
                throw new NakoParserException("もし文で比較式がありません。", t);
            }
            ifnode.nodeCond = calcStack.Pop();

            // THEN (日本語では、助詞なのでたぶんないはずだが...)
            if (Accept(NakoTokenType.THEN))
            {
                tok.MoveNext();
            }
            while (Accept(NakoTokenType.EOL))
            {
                tok.MoveNext();
            }

            // TRUE
            ifnode.nodeTrue = _scope_or_statement();
            while (Accept(NakoTokenType.EOL))
            {
                tok.MoveNext();
            }

            // FALSE
            if (Accept(NakoTokenType.ELSE))
            {
                tok.MoveNext(); // skip ELSE
                while (Accept(NakoTokenType.EOL))
                {
                    tok.MoveNext();
                }
                ifnode.nodeFalse = _scope_or_statement();
            }
            this.parentNode.AddChild(ifnode);
            this.lastNode = ifnode;
            return(true);
        }
Пример #4
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;
                }
            }
        }