private SpokeSwitch evaluateSwitch(TokenEnumerator enumerator, int tabIndex, evalInformation inf) { enumerator.MoveNext(); SpokeSwitch sw = new SpokeSwitch((SpokeItem) eval(enumerator, tabIndex,new evalInformation(inf){ResetCurrentVal=true})); List<SpokeSwitch.Case> als = new List<SpokeSwitch.Case>(); while (true) { if (enumerator.PeakNext() is TokenTab) { enumerator.MoveNext(); if (((TokenTab) enumerator.Current).TabIndex == tabIndex + 1) { enumerator.MoveNext(); SpokeItem jf = (SpokeItem) eval(enumerator, tabIndex, new evalInformation(inf){ResetCurrentVal=true}); Debug.Assert(enumerator.Current is TokenColon,"case bad"); enumerator.MoveNext(); enumerator.MoveNext(); List<SpokeLine> gc = getLines(enumerator, tabIndex + 2, new evalInformation(inf)); als.Add(new SpokeSwitch.Case(jf,gc.ToArray())); Debug .Assert(enumerator.Current.Type == Token.NewLine || enumerator.Current.Type == Token.EndOfCodez, enumerator.Current.Type + " Isnt Newline"); } continue; } break; } sw.Cases = als.ToArray(); if (enumerator.Current.Type == Token.Tab && inf.EatTab) enumerator.MoveNext(); return sw; }
private void evaluateSwitch(SpokeMethodParse currentObject, SpokeVariableInfo variables, SpokeSwitch spokeLine) { SpokeType df; SpokeType b = evaluateItem(spokeLine.Condition, currentObject, variables); for (int i = 0; i < spokeLine.Cases.Length; i++) { SpokeSwitch.Case c = spokeLine.Cases[i]; if (i != 0) { new SpokeInstruction(SpokeInstructionType.Label, "Case" + i + "_" + spokeLine.Guid); } SpokeType curCase = evaluateItem(c.Item, currentObject, variables); if (b.Type != curCase.Type) { throw new Exception("Expected " + b.Type); } if ((i + 1 == spokeLine.Cases.Length)) { new SpokeInstruction(SpokeInstructionType.Equal); new SpokeInstruction( SpokeInstructionType.IfTrueContinueElse, "EndSwitch" + spokeLine.Guid); } else { new SpokeInstruction( SpokeInstructionType.IfEqualsContinueAndPopElseGoto, "Case" + (i + 1) + "_" + spokeLine.Guid); if (c.Lines.Length == 0) { for (int j = i + 1; j < spokeLine.Cases.Length; j++) { SpokeSwitch.Case cj = spokeLine.Cases[j]; if (cj.Lines.Length > 0) { cj.NeedsTop = true; new SpokeInstruction(SpokeInstructionType.Goto, "top" + "Case" + (j) + "_" + spokeLine.Guid); break; } } } } if (c.NeedsTop) { new SpokeInstruction(SpokeInstructionType.Label, "top" + "Case" + (i) + "_" + spokeLine.Guid); } variables.IncreaseState(); df = evaluateLines(ref c.Lines, currentObject, variables); variables.DecreaseState(); if (currentObject.ReturnType != null && !currentObject.ReturnType.CompareTo(df, true)) { throw new Exception("for return: Expected " + currentObject.ReturnType.Type + " Got" + df.Type); } new SpokeInstruction(SpokeInstructionType.Goto, "EndSwitch" + spokeLine.Guid); } new SpokeInstruction(SpokeInstructionType.Label, "EndSwitch" + spokeLine.Guid); }