Exemple #1
0
        /// <summary>
        /// パース
        /// </summary>
        public void ParseOnlyValue()
        {
            var paser = new NakoParser(tokens);

            paser.ParseOnlyValue();
            this.topNode = paser.topNode;
        }
Exemple #2
0
        private bool _minus_flag()
        {
            tok.MoveNext();
            if (Accept(NakoTokenType.INT) || Accept(NakoTokenType.NUMBER))
            {
                _const();
                NakoNodeConst c = (NakoNodeConst)calcStack.Pop();
                if (c.value is long)
                {
                    c.value = ((long)(c.value) * -1);
                }
                else
                {
                    c.value = ((double)(c.value) * -1);
                }
                calcStack.Push(c);
                lastNode = c;
                return(true);
            }
            NakoNodeCalc nc = new NakoNodeCalc();

            nc.calc_type = CalcType.MUL;
            NakoNodeConst m1 = new NakoNodeConst();

            m1.value = -1;
            m1.type  = NakoNodeType.INT;
            NakoNode v = calcStack.Pop();

            nc.nodeL = v;
            nc.nodeR = m1;
            calcStack.Push(nc);
            return(true);
        }
Exemple #3
0
        /// <summary>
        /// 状態をポップ
        /// </summary>
        protected void PopNodeState()
        {
            NakoParserNodeState s = stateStack.Pop();

            this.lastNode   = s.lastNode;
            this.parentNode = s.parentNode;
        }
Exemple #4
0
        private void _print(NakoNode node)
        {
            NakoNode v = node.Children[0];

            Write_r(v);
            result.Add(new NakoILCode(NakoILType.PRINT, null));
        }
Exemple #5
0
 /// <summary>
 /// 指定したリストを書く
 /// </summary>
 /// <param name="list"></param>
 protected void Write_list(NakoNodeList list)
 {
     for (int i = 0; i < list.Count; i++)
     {
         NakoNode node = list[i];
         Write_r(node);
     }
 }
Exemple #6
0
        /// <summary>
        /// フレームの復元
        /// </summary>
        protected void PopFrame()
        {
            NakoParserFrame f = frameStack.Pop();

            lastNode   = f.lastNode;
            parentNode = f.parentNode;
            localVar   = f.localVar;
        }
Exemple #7
0
        /// <summary>
        /// トークンの分割が行われた Tokens に対して、構文解析を行う
        /// 結果は TopNode に得られる
        /// </summary>
        public void Parse()
        {
            NakoParser parser = new NakoParser(tokens);

            parser.DebugMode = this.DebugMode;
            parser.globalVar = this.GlobalVar;
            parser.Parse();
            this.topNode = parser.topNode;
        }
Exemple #8
0
 /// <summary>
 /// 中間コードを書き出す
 /// </summary>
 /// <param name="topNode"></param>
 public void Write(NakoNode topNode)
 {
     if (topNode != null)
     {
         this.topNode = topNode;
     }
     Write_r(this.topNode);
     FixLabel();
     SetExceptionTables();
 }
Exemple #9
0
        //> _callfunc : { [{_value}] FUNCTION_NAME }
        //>           ;
        private bool _callfunc_stmt()
        {
            NakoToken startToken = tok.CurrentToken;

            TokenTry();
            while (!tok.IsEOF())
            {
                WriteLog(tok.CurrentToken.ToStringForDebug());
                if (Accept(NakoTokenType.EOL))
                {
                    tok.MoveNext();
                    break;
                }
                if (!_value())
                {
                    TokenBack();
                    return(false);
                }
            }
            TokenFinally();
            //TODO: _callfunc_stmt
            // 計算用スタックの管理
            if (calcStack.Count > 0)
            {
                while (calcStack.Count > 0)
                {
                    NakoNode n = calcStack.Shift();
                    if (!(n is NakoNodeCallFunction))
                    {
                        // 余剰スタックの値を得る
                        string r = "";
                        for (int i = 0; i < calcStack.Count; i++)
                        {
                            if (i != 0)
                            {
                                r += ",";
                            }
                            NakoNode n0 = calcStack[i];
                            r += n0.ToTypeString();
                        }
                        throw new NakoParserException(
                                  "無効な式か値があります。(余剰スタックのチェック):" + r,
                                  startToken);
                    }
                    parentNode.AddChild(n);
                    parentNode.AddChild(new NakoNodePop());
                }
            }
            // ここで本来ならば
            // スタックを空にする or 余剰なスタックがあればエラーにするのが筋だが...
            // 連続関数呼び出しに対応するためエラーにしない
            return(true);
        }
Exemple #10
0
 /// <summary>
 /// コンストラクタ
 /// </summary>
 /// <param name="tokens"></param>
 public NakoParserBase(NakoTokenList tokens)
 {
     this.tok = tokens;
     tokens.MoveTop();
     parentNode        = topNode = new NakoNode();
     frameStack        = new Stack <NakoParserFrame>();
     stateStack        = new Stack <NakoParserNodeState>();
     calcStack         = new NakoNodeList();
     calcStackCounters = new Stack <int>();
     lastNode          = null;
     localVar          = new NakoVariableManager(NakoVariableScope.Local);
 }
Exemple #11
0
 /// <summary>
 /// 値を1つだけ解析したい場合
 /// </summary>
 /// <returns></returns>
 public bool ParseOnlyValue()
 {
     lastNode = null;
     if (tok.IsEOF())
     {
         return(false);
     }
     if (!_value())
     {
         return(false);
     }
     topNode.AddChild(lastNode);
     return(true);
 }
Exemple #12
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;
                }
            }
        }
Exemple #13
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);
                    }
                }
            }
        }
Exemple #14
0
        private bool _try_stmt()
        {
            if (!Accept(NakoTokenType.TRY))
            {
                return(false);
            }
            tok.MoveNext();             // skip IF

            NakoNodeTry trynode = new NakoNodeTry();

            NakoToken t = tok.CurrentToken;

            while (Accept(NakoTokenType.EOL))
            {
                tok.MoveNext();
            }

            // TRY
            trynode.nodeTry = _scope_or_statement();
            while (Accept(NakoTokenType.EOL))
            {
                tok.MoveNext();
            }

            // CATCH
            //TODO ○○のエラーならば〜☆☆のエラーならば〜への対応
            //TODO ○○や☆☆のエラーならばへの対応
            while (Accept(NakoTokenType.CATCH))
            {
                //TODO:catchの例外種別を取得
                tok.MoveNext();                //skip catch
                while (Accept(NakoTokenType.EOL))
                {
                    tok.MoveNext();
                }
                //while (calcStack.Count > 0) {
                //	calcStack.Pop ();
                //}
                NakoNode nodeCatch = _scope_or_statement();                //TODO Add
                trynode.nodeCatch = nodeCatch;
            }
            //TODO set finally
            this.parentNode.AddChild(trynode);
            this.lastNode = trynode;
            return(true);
        }
Exemple #15
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;
                }
            }
        }
Exemple #16
0
        //> _print : PRINT _value
        private bool _print()
        {
            if (tok.CurrentTokenType != NakoTokenType.PRINT)
            {
                return(false);
            }
            NakoNode n = new NakoNode();

            n.Token = tok.CurrentToken;
            tok.MoveNext();
            if (!_value())
            {
                throw new NakoParserException("PRINT の後に値がありません。", n.Token);
            }
            n.type = NakoNodeType.PRINT;
            n.AddChild(calcStack.Pop());
            lastNode = n;
            this.parentNode.AddChild(n);
            return(true);
        }
Exemple #17
0
        //> _scope_or_statement : _scope
        //>                     | _statement
        //>                     ;
        private NakoNode _scope_or_statement()
        {
            while (Accept(NakoTokenType.EOL))
            {
                tok.MoveNext();
            }

            this.PushNodeState();
            NakoNode n = this.parentNode = this.lastNode = new NakoNode();

            if (Accept(NakoTokenType.SCOPE_BEGIN))
            {
                _scope();
            }
            else
            {
                _statement();
            }
            this.PopNodeState();
            return(n);
        }
Exemple #18
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);
        }
Exemple #19
0
 /// <summary>
 /// constructor
 /// </summary>
 /// <param name="topNode"></param>
 public NakoILWriter(NakoNode topNode)
 {
     this.topNode = topNode;
     Init();
 }