private void _repeat_times(NakoNodeRepeatTimes node) { int labelId = GetLableId(); // (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); // (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); }
//> _repeat_times : _value REPEAT_TIMES _scope_or_statement //> ; private bool _repeat_times() { TokenTry(); if (!_value()) return false; if (!Accept(NakoTokenType.REPEAT_TIMES)) { TokenBack(); return false; } TokenFinally(); tok.MoveNext(); // skip REPEAT_TIMES NakoNodeRepeatTimes repnode = new NakoNodeRepeatTimes(); repnode.nodeTimes = calcStack.Pop(); repnode.nodeBlocks = _scope_or_statement(); repnode.loopVarNo = localVar.CreateVarNameless(); repnode.timesVarNo = localVar.CreateVarNameless(); this.parentNode.AddChild(repnode); lastNode = repnode; return true; }