// 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; } } }
// 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; } } }
/// <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); }