public static bool CanBeJumpedWith(this ControlType controlType, Jumper jumper) { switch (controlType) { case ControlType.Method: switch (jumper.GetJumperType()) { case JumperType.VoidReturn: return(true); default: return(false); } case ControlType.Function: switch (jumper.GetJumperType()) { case JumperType.Return: return(true); default: return(false); } case ControlType.Switch: switch (jumper.GetJumperType()) { case JumperType.Breaker: return(true); default: return(false); } case ControlType.Loop: switch (jumper.GetJumperType()) { case JumperType.Breaker: case JumperType.Continue: return(true); default: return(false); } default: throw new Exception("Control type no valido"); } }
/// <summary> /// Retorna verdadero si contiene algun elemento en el stack al que se le pueda hacer pop /// con el jumper y le hace pop a todos esos elementos. De no ser posible retorna false /// y no se hace ningun pop /// </summary> /// <returns></returns> public static bool PopUntil(Jumper jumper) { //Chapuz medio alto. Performance wise deberiamos de ver como usamos el iterador para //revisar que contenga algo que se pueda popear con el jumper y luego con ese iterador //ir a la direccion contraria popeando cada uno var stackArray = new ControlType[Stack.Count]; Stack.CopyTo(stackArray, 0); for (int i = stackArray.Length - 1; i > -1; i--) { if (stackArray[i].CanBeJumpedWith(jumper)) { if (jumper.GetJumperType() == JumperType.Continue)//porque si es continue no hace pop al loop.//Chapus medio bajo { i++; } PopNTimes(stackArray.Length - i); jumper.Popped = true; return(true); } if (stackArray[i] == ControlType.Method || stackArray[i] == ControlType.Function)//Lo obliga a terminar el ciclo { break; } } return(false); }
public static MyError NotValidJumper(AstNode node, Jumper jumper) { MyError error = new MyError(node.Span.Location.Line, node.Span.Location.Column, node.NodePath.StringValue, "Jumper tipo: " + jumper.GetJumperType().ToString() + ". No es valido el call stack actual: " + ControlStack.MyToString(), MyError.ErrorType.Semantic, MyError.ErrorLevel.Fatal); AddError(error); return(error); }