private void HandleQuit(ActionBase action) { if (m_bQuitIsHandled) { return; } if (0 == m_listOnQuit.Count) { return; } m_bQuitIsHandled = true; int pos = m_script.Actions.IndexOf(action) + 1; // insert before foreach (string funcName in m_listOnQuit) { if (m_FnNameStack.Count > 0) { string fn = m_FnNameStack.Peek(); if (fn == funcName) // do not insert calls inside our function { continue; } } Actioncall call = new Actioncall(); call.FunctionName = funcName; m_script.Actions.Insert(pos, call); ++pos; } Actionsys actSys = new Actionsys(); actSys.AddParams(new List <string>() { "sys.quit" }); m_script.Actions.Insert(pos, actSys); m_Status = VMStatus.IN_PLAYBACK; }
private int StepFlow(ActionBase action) { // function if (action is Actionfunction) { return(++m_IP); } // return if (action is Actionreturn) { m_IP = m_InstrStack.Pop(); m_CallStack.Pop(); m_variables.RemoveLocals(m_FnNameStack.Pop()); return(++m_IP); } // call if (action is Actioncall) { Actioncall call = (Actioncall)action; Debug.Assert(null != call); m_InstrStack.Push(m_IP); m_IP = m_script.GetFuncEntryIndex(call.FunctionName); m_CallStack.Push(m_IP); if (-1 == m_IP) { string errMsg = "Function: '" + call.FunctionName + "' NOT found."; m_Status = VMStatus.ERROR; m_ErrStack.Push(errMsg); host.MarkCurrentLine(m_IP, action.LineNumber, Color.Red, action.Path2Script); action.Result = EnumActionResult.ERROR; throw new Exception(errMsg); } Actionfunction fn = (Actionfunction)m_script.GetAction(m_IP); Debug.Assert(null != fn); Dictionary <string, string> vars = new Dictionary <string, string>(); if (call.Parameters.Count > 0) { for (int i = 0; i < call.Parameters.Count; ++i) { string key = fn.Parameters[i]; string value = m_variables.Get(call.Parameters[i]); vars.Add(key, value); } } m_variables.AddLocals(fn.Name, vars); // create a new scope as well m_FnNameStack.Push(fn.Name); return(m_IP); } // Label if (action is ActionLabel) { return(++m_IP); } // goto if (action is ActionGoto) { ActionGoto actGoto = (ActionGoto)action; int jump2Index = -1; int i = 0; foreach (ActionBase item in m_script.Actions) // locate position where to goto { if (item is ActionLabel) { ActionLabel actLabel = (ActionLabel)item; if (actLabel.GetLabel == actGoto.label) { jump2Index = i; break; } } ++i; } if (-1 == jump2Index) { throw new Exception("Error locating label '" + actGoto.label + "' for GOTO command."); } if ("0" != actGoto.jumpCount) // not a FOR-EVER kind of goto { if (!m_dicGotoCounts.ContainsKey(actGoto.label)) { m_dicGotoCounts.Add(actGoto.label, Convert.ToInt32(actGoto.jumpCount)); // init } if (m_dicGotoCounts[actGoto.label] > 0) { --m_dicGotoCounts[actGoto.label]; } else { m_dicGotoCounts.Remove(actGoto.label); m_script.Actions.IndexOf(actGoto); return(m_IP); } } m_IP = jump2Index; return(m_IP); } // foreach // for // while if (action is ActionFlowIterator) { ActionFlowIterator act = (ActionFlowIterator)action; Debug.Assert(null != act); if (0 == m_LoopStack.Count) { m_LoopStack.Push(m_IP); } else if (m_LoopStack.Peek() != m_IP) { m_LoopStack.Push(m_IP); } if (act.IsDone) { m_LoopStack.Pop(); m_IP = GetMatchingLoopStatement(m_IP); } return(++m_IP); } // break if (action is Actionbreak) { int ip = m_LoopStack.Pop(); ActionFlowIterator act = (ActionFlowIterator)m_script.Actions[ip]; act.Done(); // probably it will cleanup itself from the vm m_IP = GetClosestLoopStatement(m_IP); return(++m_IP); } // loop // continue if (action is Actionloop || action is Actioncontinue) { m_IP = m_LoopStack.Peek(); return(m_IP); } // if if (action is Actionif) { Actionif actIF = (Actionif)action; m_IfStack.Push(m_IP); if (actIF.result == true) { return(++m_IP); // go inside if block } else // bypass if block (find else or endif statement (matching! nested if satetement are skipped as well) { m_IP = GetMatchingIfStatement(m_IP); return(m_IP); } } // endif if (action is Actionendif) { m_IfStack.Pop(); return(++m_IP); } // else if (action is Actionelse) { int index = m_IfStack.Peek(); Actionif actIF = (Actionif)script.Actions[index]; if (actIF.result == true) // then skip the else part { m_IP = GetMatchingIfStatement(m_IP); return(m_IP); } else { return(++m_IP); } } // unknown command throw new Exception("Player::StepFlow Unknown FlowCommand [" + action.RawCmdLine.Trim() + "]"); }
private bool HandleError(ActionBase action) { if (null == m_actionError) { m_actionError = action; } m_variables.UpdateSystem("$ERROR", "True"); int tmpInstPtr = m_IP; ++tmpInstPtr; if (tmpInstPtr < script.Actions.Count) // peek ahead one instruction is it a if statement? { ActionBase actTmp = m_script.GetAction(tmpInstPtr);; if (actTmp is Actionif) { Actionif actIF = (Actionif)actTmp; Debug.Assert(null != actIF); if (actIF.Params[1] == "$ERROR" || actIF.Params[3] == "$ERROR") { return(true); // error is handled (do not let the playback to be stopped) } } } // unhandled error... if (!m_bErrorIsHandled && m_listOnError.Count > 0) { m_bErrorIsHandled = true; int pos = m_script.Actions.IndexOf(action) + 1; foreach (string funcName in m_listOnError) { if (m_FnNameStack.Count > 0) { string fn = m_FnNameStack.Peek(); if (fn == funcName) // do not insert calls inside our function { continue; } } Actioncall call = new Actioncall(); call.FunctionName = funcName; m_script.Actions.Insert(pos, call); ++pos; } ActionError err = new ActionError(); m_script.Actions.Insert(pos, err); return(true); // show must go on } else { m_Status = VMStatus.ERROR; return(false); // we stop the playback } }