// Check for the end of an object iteration. public static bool ForNextCheckObj (Object Counter, Object LoopObj, ref Object CounterResult) { if (!(LoopObj is ForInfo)) { Utils.ThrowException(100); // InvalidOperationException. } else if (Counter == null) { throw new ArgumentException (S._("VB_LoopCounterIsNull"), "Counter"); } ForInfo info = (ForInfo)LoopObj; info.counter = CastToType(ObjectType.AddObj(Counter, info.stepValue), info.type); if (info.enumType == null) { CounterResult = info.counter; } else { CounterResult = Enum.ToObject(info.enumType, info.counter); } return(CheckObjForLimit(info)); }
/// <summary> /// 解析循环结束符号 /// </summary> /// <param name="line"></param> /// <param name="i"></param> /// <param name="forInfo"></param> /// <returns></returns> private bool parseForEnd(String line, int i, ref ForInfo forInfo) { if (!line.ToLower().StartsWith("endfor")) { return(false); } forInfo.end = i; return(true); }
// Initialize a "for" loop. public static bool ForLoopInitObj (Object Counter, Object Start, Object Limit, Object StepValue, ref Object LoopForResult, ref Object CounterResult) { // Validate the parameters. if (Start == null) { throw new ArgumentException (S._("VB_ValueIsNull"), "Start"); } if (Limit == null) { throw new ArgumentException (S._("VB_ValueIsNull"), "Limit"); } if (StepValue == null) { throw new ArgumentException (S._("VB_ValueIsNull"), "StepValue"); } // Find a common numeric type between the three arguments. Type enumType; TypeCode type = ObjectType.CommonType(Start, Limit, out enumType); type = ObjectType.CommonType(StepValue, null, type, false); if (type == TypeCode.Empty) { throw new ArgumentException(S._("VB_CommonForType")); } // Create the "for" control object. ForInfo info = new ForInfo(); LoopForResult = info; info.counter = CastToType(Start, type); info.limit = CastToType(Limit, type); info.stepValue = CastToType(StepValue, type); info.type = type; info.enumType = enumType; info.stepIsNegative = ValueIsNegative(info.stepValue, type); // Return the initial counter value. if (enumType == null) { CounterResult = info.counter; } else { CounterResult = Enum.ToObject(enumType, info.counter); } // Determine if we've already exceeded the limit. return(CheckObjForLimit(info)); }
/// <summary> /// command是否是loop中的最后一个命令 /// </summary> /// <param name="loop"></param> /// <param name="command"></param> /// <returns></returns> private bool IsLastCommand(ForInfo loop, CommandInfo command) { for (int i = command.orginLine + 1; i < loop.end; i++) { if (commandInfos.FirstOrDefault(x => x.orginLine == i) != null) { return(false); } } return(true); }
// Check the limit of an object-based "for" loop. private static bool CheckObjForLimit(ForInfo info) { if (!(info.stepIsNegative)) { return(ObjectType.ObjTst(info.counter, info.limit, false) <= 0); } else { return(ObjectType.ObjTst(info.counter, info.limit, false) >= 0); } }
/// <summary> /// 查找for循环后面的有效命令行号 /// </summary> /// <param name="loop"></param> /// <returns></returns> private int getForAfterIndex(ForInfo loop) { int i = loop.end + 1; while (i < orginLines.Length) { for (int k = 0; k < commandInfos.Count; k++) { if (commandInfos[k].orginLine >= i) { return(k); } } i += 1; } return(commandInfos.Count); }
public DynamicMethodBody Next() { ForInfo f = forsField.Pop(); Ldloc(f.Variable) .Ldc(f.Step) .Add() .Stloc(f.Variable) .MarkLabel(f.ComparasionLabel) .Ldloc(f.Variable) .Emit(f.To); if (f.Step > 0) { Ble(f.BeginLabel); } else { Bge(f.BeginLabel); } return(this); }
/// <summary> /// 语法检查 /// </summary> public CommandInterpreter Parse() { Dictionary <String, Object> map = context.ExternalVariable; commandInfos.Clear(); if (map != null && map.Count > 0) { context.SetExternal(map); } ForInfo forInfo = null; for (int i = 0; i < orginLines.Length; i++) { if (orginLines[i] == null) { continue; } String line = orginLines[i].Trim(); if (line == "") { continue; } if (line.StartsWith(COMMENT)) { continue; } int t = line.IndexOf(COMMENT); if (t >= 0) { line = line.Substring(0, t).Trim(); } String variableName = parseVariableName(line, i); if (forInfo == null) { forInfo = parseForBegin(line, i); if (forInfo != null) { continue; } } else if (parseForEnd(line, i, ref forInfo)) { continue; } String commandStr = line; if (variableName != "") { commandStr = line.Substring(line.IndexOf("=") + 1).Trim(); } ICommand command = null; try { command = context.Receive(commandStr); if (command == null) { throw new Exception("第" + i + "行语法错误:无法识别的命令:" + line); } } catch (Exception e) { throw new Exception("第" + i + "行语法错误:" + e.Message); } CommandInfo cmdInfo = new CommandInfo(i, line, command, variableName); this.commandInfos.Add(cmdInfo); } return(this); }
public void Execute() { Dictionary <String, Object> map = context.ExternalVariable; if (map == null) { map = new Dictionary <string, object>(); } if (map != null && map.Count > 0) { context.SetExternal(map); } ForInfo curFor = null; int curForIndex = -1; logger.Info("命令集开始执行..."); for (int i = 0; i < commandInfos.Count; i++) { //取得当前命令 CommandInfo curCommandInfo = commandInfos[i]; //判断当前命令是否在循环内 if (curFor == null) { curFor = getFor(curCommandInfo); curForIndex = curFor == null ? -1 : i; } //如果在循环内,设置循环变量直到结束 if (curFor != null && !curFor.setNextElementVariable(context)) { i = getForAfterIndex(curFor); //调到循环后面 curFor = null; curForIndex = -1; continue; } //执行命令 try { curCommandInfo.command.Execute(context); Object r = curCommandInfo.command.GetResult(); logger.Info("执行" + curCommandInfo.ToString() + "完成" + (r == null?"":":" + r.ToString())); } catch (Exception e) { logger.Error("执行命令失败:" + curCommandInfo.ToString() + ":" + e.Message); return; } //命令结果赋值 if (curCommandInfo.variableName.NotEmpty()) { context.PutVariableValue(curCommandInfo.variableName, curCommandInfo.command.GetResult()); } //当前在循环,且循环体到了最后 if (curFor != null && IsLastCommand(curFor, curCommandInfo)) { i = curForIndex; continue; } } }
// Check the limit of an object-based "for" loop. private static bool CheckObjForLimit(ForInfo info) { if(!(info.stepIsNegative)) { return (ObjectType.ObjTst(info.counter, info.limit, false) <= 0); } else { return (ObjectType.ObjTst(info.counter, info.limit, false) >= 0); } }
// Initialize a "for" loop. public static bool ForLoopInitObj (Object Counter, Object Start, Object Limit, Object StepValue, ref Object LoopForResult, ref Object CounterResult) { // Validate the parameters. if(Start == null) { throw new ArgumentException (S._("VB_ValueIsNull"), "Start"); } if(Limit == null) { throw new ArgumentException (S._("VB_ValueIsNull"), "Limit"); } if(StepValue == null) { throw new ArgumentException (S._("VB_ValueIsNull"), "StepValue"); } // Find a common numeric type between the three arguments. Type enumType; TypeCode type = ObjectType.CommonType(Start, Limit, out enumType); type = ObjectType.CommonType(StepValue, null, type, false); if(type == TypeCode.Empty) { throw new ArgumentException(S._("VB_CommonForType")); } // Create the "for" control object. ForInfo info = new ForInfo(); LoopForResult = info; info.counter = CastToType(Start, type); info.limit = CastToType(Limit, type); info.stepValue = CastToType(StepValue, type); info.type = type; info.enumType = enumType; info.stepIsNegative = ValueIsNegative(info.stepValue, type); // Return the initial counter value. if(enumType == null) { CounterResult = info.counter; } else { CounterResult = Enum.ToObject(enumType, info.counter); } // Determine if we've already exceeded the limit. return CheckObjForLimit(info); }