private SpokeMethodCall checkRunMacro(TokenEnumerator enumerator, int tabIndex, evalInformation inf) { //tm. for (int index = 0; ; index++) { gombo: if (index >= allMacros_.Count) break; var tokenMacroPiece = allMacros_[index]; List<SpokeItem> parameters = new List<SpokeItem>(); var tm = enumerator.Clone(); var outs = tm.OutstandingLine; bool bad = false; for (int i = 0; i < tokenMacroPiece.Macro.Length; i++) { var mp = tokenMacroPiece.Macro[i]; if (mp.Type == Token.Ampersand) { for (int j = i + 1; j < tokenMacroPiece.Macro.Length; j++) { var r = tokenMacroPiece.Macro[j]; if (!outs.Any(a => r.Type == Token.Ampersand || (a.Type == r.Type && (a.Type == Token.Word && r.Type == Token.Word ? ((TokenWord)a).Word == ((TokenWord)r).Word : true)))) { bad = true; break; } } if (bad) { break; } var frf = tokenMacroPiece.Macro.Length == i + 1 ? new TokenNewLine() : tokenMacroPiece.Macro[i + 1]; int selectedLine = 0; IToken tp = null; int selectedToken = tm.tokenIndex; if (frf.Type != Token.NewLine) { for (int j = 0; j < tm.CurrentLines.Count; j++) { for (int ic = selectedToken; ic < tm.CurrentLines[j].Tokens.Count; ic++) { var a = tm.CurrentLines[j].Tokens[ic]; if (tm.CurrentLines[j].Tokens[ic].Type == frf.Type && (a.Type == frf.Type && (a.Type == Token.Word && frf.Type == Token.Word ? ((TokenWord)a).Word == ((TokenWord)frf).Word : true))) { tp = tm.CurrentLines[j].Tokens[ic]; break; } } if (tp != null) { selectedLine = j; break; } else { selectedToken = 0; } } var bf = new TokenAmpersand(); tm.CurrentLines[selectedLine].Tokens.Insert(tm.CurrentLines[selectedLine].Tokens.IndexOf(tp), bf); try { CurrentItem = null; var d = eval(tm, tabIndex, new evalInformation(inf) { CheckMacs = inf.CheckMacs + 1, DontEvalEquals = true, BreakBeforeEqual = true }); parameters.Add((SpokeItem)d); if (d == null || (!(tm.Current.Type == Token.Ampersand || tokenMacroPiece.Macro.Length == i + 1))) { index++; goto gombo; } } catch (Exception e) { index++; goto gombo; } tm.CurrentLine.Tokens.Remove(bf); } else { try { CurrentItem = null; var d = eval(tm, tabIndex, new evalInformation(inf) { CheckMacs = inf.CheckMacs + 1, DontEvalEquals = true, BreakBeforeEqual = true }); parameters.Add((SpokeItem)d); if (d == null) { index++; goto gombo; } } catch (Exception e) { index++; goto gombo; } } } else { if (mp.Type == tm.Current.Type && (mp.Type == Token.Word && tm.Current.Type == Token.Word ? ((TokenWord)mp).Word == ((TokenWord)tm.Current).Word : true)) { tm.MoveNext(); } else { bad = true; break; } } } if (!bad) { SpokeMethodCall ambe = new SpokeMethodCall(); SpokeAnonMethod me = new SpokeAnonMethod(); me.SpecAnon = true; me.Parameters = tokenMacroPiece.Parameters; me.Lines = getLines(new TokenEnumerator(tokenMacroPiece.Lines.ToArray()), 1, inf).ToArray(); me.HasYieldReturn = linesHave(me.Lines, ISpokeLine.YieldReturn); me.HasYield = linesHave(me.Lines, ISpokeLine.Yield); me.HasReturn = linesHave(me.Lines, ISpokeLine.Return); ambe.Parent = me; parameters.Insert(0, new SpokeCurrent()); ambe.Parameters = parameters.ToArray(); enumerator.Set(tm); return ambe; } } return null; }
public Spoke eval(TokenEnumerator enumerator, int tabIndex, evalInformation inf) { if (inf.ResetCurrentVal) { CurrentItem = null; } #if DEBUGs sb.AppendLine("Starting Eval " + enumerator.Current.Type); #endif if (inf.CheckMacs < 2) { var df = CurrentItem; CurrentItem = null; var rm = checkRunMacro(enumerator, tabIndex, inf); if (rm != null) { CurrentItem = rm; } else CurrentItem = df; } switch (enumerator.Current.Type) { case Token.Word: if (((TokenWord)enumerator.Current).Word.ToLower() == "null") { CurrentItem = new SpokeNull(); } else CurrentItem = new SpokeVariable() { Parent = CurrentItem, VariableName = ((TokenWord)enumerator.Current).Word }; enumerator.MoveNext(); break; case Token.Int: CurrentItem = new SpokeInt() { Value = ((TokenInt)enumerator.Current)._value }; enumerator.MoveNext(); break; case Token.Float: CurrentItem = new SpokeFloat() { Value = ((TokenFloat)enumerator.Current)._value }; enumerator.MoveNext(); break; case Token.String: CurrentItem = new SpokeString() { Value = ((TokenString)enumerator.Current)._value }; enumerator.MoveNext(); break; case Token.False: CurrentItem = new SpokeBool() { Value = false }; enumerator.MoveNext(); break; case Token.True: CurrentItem = new SpokeBool() { Value = true }; enumerator.MoveNext(); break; case Token.OpenParen: enumerator.MoveNext(); CurrentItem = (SpokeItem)eval(enumerator, tabIndex, new evalInformation(inf)); if (enumerator.Current.Type == Token.Tab) { enumerator.MoveNext(); } if (enumerator.Current.Type != Token.CloseParen) { throw new AbandonedMutexException(); } enumerator.MoveNext(); break; case Token.Switch: return (SpokeLine)evaluateSwitch(enumerator, tabIndex, inf); case Token.If: enumerator.MoveNext(); var i_f = new SpokeIf() { Condition = (SpokeItem)eval(enumerator, tabIndex, new evalInformation(inf)) }; enumerator.MoveNext(); i_f.IfLines = getLines(enumerator, tabIndex + 1, new evalInformation(inf)).ToArray(); StaticMethods.Assert(enumerator.Current.Type == Token.NewLine || enumerator.Current.Type == Token.EndOfCodez, enumerator.Current.Type + " Isnt Newline"); enumerator.MoveNext(); if (enumerator.Current.Type == Token.Tab && enumerator.PeakNext().Type == Token.Else) { enumerator.MoveNext(); enumerator.MoveNext(); i_f.ElseLines = getLines(enumerator, tabIndex + 1, new evalInformation(inf)).ToArray(); StaticMethods.Assert(enumerator.Current.Type == Token.NewLine || enumerator.Current.Type == Token.EndOfCodez, enumerator.Current.Type + " Isnt Newline"); enumerator.MoveNext(); } if (enumerator.Current.Type == Token.Tab && inf.EatTab) enumerator.MoveNext(); return i_f; break; case Token.Bar: var an = new SpokeAnonMethod() { Parent = CurrentItem }; enumerator.MoveNext(); StaticMethods.Assert(enumerator.Current.Type == Token.OpenParen, enumerator.Current.Type + " Isnt OpenParen"); List<ParamEter> parameters_ = new List<ParamEter>(); enumerator.MoveNext(); if (enumerator.Current.Type != Token.CloseParen) { pback2: bool byRe_f = false; if (((TokenWord)enumerator.Current).Word.ToLower() == "ref") { byRe_f = true; enumerator.MoveNext(); } parameters_.Add(new ParamEter() { ByRef = byRe_f, Name = ((TokenWord)enumerator.Current).Word }); enumerator.MoveNext(); switch (enumerator.Current.Type) { case Token.CloseParen: enumerator.MoveNext(); break; case Token.Comma: enumerator.MoveNext(); goto pback2; break; default: throw new ArgumentOutOfRangeException(); } } an.Parameters = parameters_.ToArray(); StaticMethods.Assert(enumerator.Current.Type == Token.AnonMethodStart, enumerator.Current.Type + " Isnt anonmethodstart"); enumerator.MoveNext(); StaticMethods.Assert(enumerator.Current.Type == Token.NewLine, enumerator.Current.Type + " Isnt Newline"); enumerator.MoveNext(); an.Lines = getLines(enumerator, tabIndex + 1, new evalInformation(inf)).ToArray(); StaticMethods.Assert(enumerator.Current.Type == Token.NewLine || enumerator.Current.Type == Token.EndOfCodez, enumerator.Current.Type + " Isnt Newline"); enumerator.MoveNext(); an.HasYield = linesHave(an.Lines, ISpokeLine.Yield); an.HasReturn = linesHave(an.Lines, ISpokeLine.Return); an.HasYieldReturn = linesHave(an.Lines, ISpokeLine.YieldReturn); StaticMethods.Assert(enumerator.Current.Type == Token.Tab && ((TokenTab)enumerator.Current).TabIndex == tabIndex, "Bad tabindex"); if (enumerator.Current.Type == Token.Tab && inf.EatTab) enumerator.MoveNext(); if (enumerator.PeakNext().Type != Token.CloseParen) { return an; } else { enumerator.MoveNext(); CurrentItem = an; } break; case Token.OpenSquare: CurrentItem = dyanmicArray(enumerator, tabIndex, inf); break; case Token.OpenCurly: CurrentItem = new SpokeConstruct(); CurrentItem = dynamicObject(enumerator, tabIndex, inf); break; case Token.Create: return createObject(enumerator, tabIndex, inf); break; case Token.Return: enumerator.MoveNext(); var r = new SpokeReturn() { Return = (SpokeItem)eval(enumerator, tabIndex, new evalInformation(inf)) }; enumerator.MoveNext(); return r; case Token.Yield: enumerator.MoveNext(); if (enumerator.Current.Type == Token.Return) { enumerator.MoveNext(); var y = new SpokeYieldReturn() { YieldReturn = (SpokeItem)eval(enumerator, tabIndex, new evalInformation(inf)) }; enumerator.MoveNext(); return y; } else { var y = new SpokeYield() { Yield = (SpokeItem)eval(enumerator, tabIndex, new evalInformation(inf)) }; enumerator.MoveNext(); return y; } } #if DEBUGs sb.AppendLine("Checking Eval 1" + enumerator.Current.Type); #endif switch (enumerator.Current.Type) { case Token.OpenSquare: var ar = new SpokeArrayIndex(); ar.Parent = CurrentItem; enumerator.MoveNext(); ar.Index = (SpokeItem)eval(enumerator, tabIndex, new evalInformation(inf) { BreakBeforeEqual = false, ResetCurrentVal = true }); StaticMethods.Assert(enumerator.Current.Type == Token.CloseSquare, enumerator.Current.Type + " Isnt closesquare"); enumerator.MoveNext(); if (enumerator.Current.Type == Token.OpenSquare) { } CurrentItem = ar; break; case Token.OpenParen: var meth = new SpokeMethodCall() { Parent = CurrentItem }; enumerator.MoveNext(); List<SpokeItem> param_ = new List<SpokeItem>(); param_.Add(new SpokeCurrent()); CurrentItem = null; if (enumerator.Current.Type != Token.CloseParen) { g: param_.Add((SpokeItem)eval(enumerator, tabIndex, new evalInformation(inf) { ResetCurrentVal = true })); if (enumerator.Current.Type == Token.Comma) { enumerator.MoveNext(); goto g; } } enumerator.MoveNext();//closeparen meth.Parameters = param_.ToArray(); CurrentItem = meth; //loop params break; case Token.Period: var t = CurrentItem; enumerator.MoveNext(); SpokeParent g; Spoke c; CurrentItem = g = (SpokeParent)(c = eval(enumerator, tabIndex, new evalInformation(inf) { BreakBeforeEvaler = true })); //g.Parent = t; //enumerator.MoveNext(); break; } switch (enumerator.Current.Type) { case Token.Period: var t = CurrentItem; enumerator.MoveNext(); SpokeParent g; Spoke c; CurrentItem = g = (SpokeParent)(c = eval(enumerator, tabIndex, new evalInformation(inf) { BreakBeforeEvaler = true })); //g.Parent = t; //enumerator.MoveNext(); break; } #if DEBUGs sb.AppendLine("Checking Eval 2" + enumerator.Current.Type); #endif forMethods: switch (enumerator.Current.Type) { case Token.OpenParen: var meth = new SpokeMethodCall() { Parent = CurrentItem }; enumerator.MoveNext(); List<SpokeItem> param_ = new List<SpokeItem>(); param_.Add(new SpokeCurrent()); g: param_.Add((SpokeItem)eval(enumerator, tabIndex, new evalInformation(inf) { ResetCurrentVal = true })); if (enumerator.Current.Type == Token.Comma) { enumerator.MoveNext(); goto g; } enumerator.MoveNext();//closeparen meth.Parameters = param_.ToArray(); CurrentItem = meth; goto forMethods; } #if DEBUGs sb.AppendLine("Checking Eval 3" + enumerator.Current.Type); #endif if (inf.BreakBeforeEvaler) { return CurrentItem; } if (!inf.DontEvalEquals) { if (enumerator.Current.Type == Token.Equal) { var equ = new SpokeEqual() { LeftSide = CurrentItem }; enumerator.MoveNext(); equ.RightSide = (SpokeItem)eval(enumerator, tabIndex, new evalInformation(inf) { EatTab = false, ResetCurrentVal = true }); if (enumerator.Current.Type == Token.NewLine) { // enumerator.MoveNext(); //newline } return equ; } } switch (enumerator.Current.Type) { case Token.AnonMethodStart: //checkparams //getlines var an = new SpokeAnonMethod() { Parent = CurrentItem }; enumerator.MoveNext(); if (enumerator.Current.Type == Token.Bar) { enumerator.MoveNext(); StaticMethods.Assert(enumerator.Current.Type == Token.OpenParen, enumerator.Current.Type + " Isnt openparen"); List<ParamEter> parameters_ = new List<ParamEter>(); enumerator.MoveNext(); pback2: bool byRe_f = false; if (((TokenWord)enumerator.Current).Word.ToLower() == "ref") { byRe_f = true; enumerator.MoveNext(); } parameters_.Add(new ParamEter() { ByRef = byRe_f, Name = ((TokenWord)enumerator.Current).Word }); enumerator.MoveNext(); switch (enumerator.Current.Type) { case Token.CloseParen: enumerator.MoveNext(); break; case Token.Comma: enumerator.MoveNext(); goto pback2; break; default: throw new ArgumentOutOfRangeException(); } an.Parameters = parameters_.ToArray(); } else { an.RunOnVar = (SpokeItem)eval(enumerator, tabIndex, new evalInformation(inf) { ResetCurrentVal = true, BreakBeforeEqual = false, BreakBeforeEvaler = true }); } StaticMethods.Assert(enumerator.Current.Type == Token.NewLine, enumerator.Current.Type + " Isnt Newline"); enumerator.MoveNext(); CurrentItem = null; an.Lines = getLines(enumerator, tabIndex + 1, new evalInformation(inf)).ToArray(); an.HasYield = linesHave(an.Lines, ISpokeLine.Yield); an.HasReturn = linesHave(an.Lines, ISpokeLine.Return); an.HasYieldReturn = linesHave(an.Lines, ISpokeLine.YieldReturn); StaticMethods.Assert(enumerator.Current.Type == Token.NewLine || enumerator.Current.Type == Token.EndOfCodez, enumerator.Current.Type + " Isnt Newline"); enumerator.MoveNext(); if (enumerator.Current.Type == Token.Tab && inf.EatTab) enumerator.MoveNext(); CurrentItem = an; break; } // 5*6-7+8/9+10 switch (enumerator.Current.Type) { case Token.Plus: enumerator.MoveNext(); CurrentItem = new SpokeAddition() { LeftSide = CurrentItem, RightSide = (SpokeItem)eval(enumerator, tabIndex, new evalInformation(inf) { BreakBeforeEqual = true, ResetCurrentVal = true }) }; break; case Token.Minus: enumerator.MoveNext(); CurrentItem = new SpokeSubtraction() { LeftSide = CurrentItem, RightSide = (SpokeItem)eval(enumerator, tabIndex, new evalInformation(inf) { BreakBeforeEqual = true, ResetCurrentVal = true }) }; break; case Token.Divide: enumerator.MoveNext(); CurrentItem = new SpokeDivision() { LeftSide = CurrentItem, RightSide = (SpokeItem)eval(enumerator, tabIndex, new evalInformation(inf) { BreakBeforeEqual = true, ResetCurrentVal = true }) }; break; case Token.Mulitply: enumerator.MoveNext(); CurrentItem = new SpokeMultiplication() { LeftSide = CurrentItem, RightSide = (SpokeItem)eval(enumerator, tabIndex, new evalInformation(inf) { BreakBeforeEqual = true, ResetCurrentVal = true }) }; break; } if (inf.BreakBeforeEqual) { return CurrentItem; } switch (enumerator.Current.Type) { case Token.DoubleOr: enumerator.MoveNext(); CurrentItem = new SpokeOr() { LeftSide = CurrentItem, RightSide = (SpokeItem)eval(enumerator, tabIndex, new evalInformation(inf) { ResetCurrentVal = true }) }; break; case Token.DoubleAnd: enumerator.MoveNext(); CurrentItem = new SpokeAnd() { LeftSide = CurrentItem, RightSide = (SpokeItem)eval(enumerator, tabIndex, new evalInformation(inf) { ResetCurrentVal = true }) }; break; } #if DEBUGs sb.AppendLine("Checking Eval 4" + enumerator.Current.Type); #endif SpokeItem e; switch (enumerator.Current.Type) { case Token.DoubleEqual: enumerator.MoveNext(); e = new SpokeEquality() { LeftSide = CurrentItem, RightSide = (SpokeItem)eval(enumerator, tabIndex, new evalInformation(inf) { BreakBeforeEqual = true, ResetCurrentVal = true }) }; CurrentItem = e; break; case Token.NotEqual: enumerator.MoveNext(); e = new SpokeNotEqual() { LeftSide = CurrentItem, RightSide = (SpokeItem)eval(enumerator, tabIndex, new evalInformation(inf) { BreakBeforeEqual = true, ResetCurrentVal = true }) }; CurrentItem = e; break; case Token.Less: enumerator.MoveNext(); if (enumerator.Current.Type == Token.Equal) { enumerator.MoveNext(); e = new SpokeLessThanOrEqual() { LeftSide = CurrentItem, RightSide = (SpokeItem)eval(enumerator, tabIndex, new evalInformation(inf) { BreakBeforeEqual = true, ResetCurrentVal = true }) }; CurrentItem = e; break; } e = new SpokeLessThan() { LeftSide = CurrentItem, RightSide = (SpokeItem)eval(enumerator, tabIndex, new evalInformation(inf) { BreakBeforeEqual = true, ResetCurrentVal = true }) }; CurrentItem = e; break; case Token.Greater: enumerator.MoveNext(); if (enumerator.Current.Type == Token.Equal) { enumerator.MoveNext(); e = new SpokeGreaterThanOrEqual() { LeftSide = CurrentItem, RightSide = (SpokeItem)eval(enumerator, tabIndex, new evalInformation(inf) { BreakBeforeEqual = true, ResetCurrentVal = true }) }; CurrentItem = e; break; } e = new SpokeGreaterThan() { LeftSide = CurrentItem, RightSide = (SpokeItem)eval(enumerator, tabIndex, new evalInformation(inf) { BreakBeforeEqual = true, ResetCurrentVal = true }) }; CurrentItem = e; break; } switch (enumerator.Current.Type) { case Token.DoubleOr: enumerator.MoveNext(); CurrentItem = new SpokeOr() { LeftSide = CurrentItem, RightSide = (SpokeItem)eval(enumerator, tabIndex, new evalInformation(inf) { ResetCurrentVal = true }) }; break; case Token.DoubleAnd: enumerator.MoveNext(); CurrentItem = new SpokeAnd() { LeftSide = CurrentItem, RightSide = (SpokeItem)eval(enumerator, tabIndex, new evalInformation(inf) { ResetCurrentVal = true }) }; break; } return CurrentItem; }