public static string evalute(SpokeItem condition, int tabIndex) { StringBuilder sb = new StringBuilder(); if (condition == null) { return(sb.ToString()); } switch (condition.IType) { case ISpokeItem.Array: sb.Append("["); for (int index = 0; index < ((SpokeArray)condition).Parameters.Length; index++) { var spokeItem = ((SpokeArray)condition).Parameters[index]; sb.Append(evalute(spokeItem, tabIndex)); if (index < ((SpokeArray)condition).Parameters.Length - 1) { sb.Append(","); } } sb.Append("]"); break; case ISpokeItem.Float: sb.Append(((SpokeFloat)condition).Value); break; case ISpokeItem.Int: sb.Append(((SpokeInt)condition).Value); break; case ISpokeItem.Variable: if (((SpokeVariable)condition).Parent != null) { sb.Append(evalute(((SpokeVariable)condition).Parent, tabIndex)); if (myShowIndex) { sb.Append("." + ((SpokeVariable)condition).VariableIndex); } else { sb.Append("." + ((SpokeVariable)condition).VariableName); } return(sb.ToString()); } if (myShowIndex) { sb.Append(((SpokeVariable)condition).VariableIndex); } else { sb.Append(((SpokeVariable)condition).VariableName); } break; case ISpokeItem.ArrayIndex: sb.Append(evalute(((SpokeArrayIndex)condition).Parent, tabIndex)); sb.Append("["); sb.Append(evalute(((SpokeArrayIndex)condition).Index, tabIndex)); sb.Append("]"); break; case ISpokeItem.Current: sb.Append("this"); break; case ISpokeItem.Null: sb.Append("null"); break; case ISpokeItem.AnonMethod: if (((SpokeAnonMethod)condition).Parent != null) { sb.Append("("); sb.Append("("); sb.Append(evalute(((SpokeAnonMethod)condition).Parent, tabIndex)); sb.Append(")=>"); if (((SpokeAnonMethod)condition).RunOnVar != null) { evalute(((SpokeAnonMethod)condition).RunOnVar, tabIndex); // sb.Append("."); } if (((SpokeAnonMethod)condition).Parameters != null) { sb.Append("|("); for (int index = 0; index < ((SpokeAnonMethod)condition).Parameters.Length; index++) { var p = ((SpokeAnonMethod)condition).Parameters[index]; if (p.ByRef) { sb.Append("ref "); } sb.Append(p.Name); if (index < ((SpokeAnonMethod)condition).Parameters.Length - 1) { sb.Append(","); } } sb.Append(")"); } sb.Append(evaluateLines(((SpokeAnonMethod)condition).Lines, tabIndex + 1)); sb.AppendLine(); for (int i = 0; i < tabIndex; i++) { sb.Append(" \t"); } sb.Append(")"); } else { sb.Append("("); if (((SpokeAnonMethod)condition).Parameters != null) { sb.Append("|("); for (int index = 0; index < ((SpokeAnonMethod)condition).Parameters.Length; index++) { var p = ((SpokeAnonMethod)condition).Parameters[index]; if (p.ByRef) { sb.Append("ref "); } sb.Append(p.Name); if (index < ((SpokeAnonMethod)condition).Parameters.Length - 1) { sb.Append(","); } } sb.Append(")=>"); } sb.Append(evaluateLines(((SpokeAnonMethod)condition).Lines, tabIndex + 1)); sb.AppendLine(); for (int i = 0; i < tabIndex; i++) { sb.Append(" \t"); } sb.Append(")"); } break; case ISpokeItem.MethodCall: var gf = ((SpokeMethodCall)condition); if (gf.Parent is SpokeAnonMethod) { sb.Append("("); sb.Append("|("); var ds = ((SpokeAnonMethod)gf.Parent); for (int index = 0; index < ds.Parameters.Length; index++) { ParamEter p = ds.Parameters[index]; if (p.ByRef) { sb.Append("ref "); } sb.Append(p.Name + " = "); sb.Append(evalute(gf.Parameters[index + 1], tabIndex)); if (index < ds.Parameters.Length - 1) { sb.Append(","); } } sb.Append(")"); sb.Append(evaluateLines(((SpokeAnonMethod)gf.Parent).Lines, tabIndex + 1)); sb.AppendLine(); for (int i = 0; i < tabIndex; i++) { sb.Append(" \t"); } sb.Append(")"); } else { var d = ((SpokeVariable)gf.Parent); if (d.Parent == null) { sb.Append(d.VariableName + "("); for (int index = 0; index < gf.Parameters.Length; index++) { var spokeItem = gf.Parameters[index]; sb.Append(evalute(spokeItem, tabIndex)); if (index < gf.Parameters.Length - 1) { sb.Append(","); } } sb.Append(")"); } else { sb.Append(evalute(d.Parent, tabIndex)); sb.Append("." + d.VariableName + "("); for (int index = 0; index < gf.Parameters.Length; index++) { var spokeItem = gf.Parameters[index]; sb.Append(evalute(spokeItem, tabIndex)); if (index < gf.Parameters.Length - 1) { sb.Append(","); } } sb.Append(")"); } } break; case ISpokeItem.String: sb.Append("\"" + ((SpokeString)condition).Value + "\""); break; case ISpokeItem.Bool: sb.Append(((SpokeBool)condition).Value); break; case ISpokeItem.Construct: var rf = (SpokeConstruct)condition; sb.Append("Create "); if (rf.ClassName != null) { sb.Append(rf.ClassName); } sb.Append("("); for (int index = 0; index < rf.Parameters.Length; index++) { var spokeItem = rf.Parameters[index]; sb.Append(evalute(spokeItem, tabIndex)); if (index < rf.Parameters.Length - 1) { sb.Append(","); } } sb.Append(")"); sb.Append("{"); for (int index = 0; index < rf.SetVars.Length; index++) { var spokeItem = rf.SetVars[index]; sb.Append(spokeItem.Name + ":"); sb.Append(evalute(spokeItem.Item, tabIndex)); if (index < rf.SetVars.Length - 1) { sb.Append(","); } } sb.Append("}"); break; case ISpokeItem.Addition: sb.Append("("); sb.Append(evalute(((SpokeAddition)condition).LeftSide, tabIndex)); sb.Append("+"); sb.Append(evalute(((SpokeAddition)condition).RightSide, tabIndex)); sb.Append(")"); break; case ISpokeItem.Subtraction: sb.Append("("); sb.Append(evalute(((SpokeSubtraction)condition).LeftSide, tabIndex)); sb.Append("-"); sb.Append(evalute(((SpokeSubtraction)condition).RightSide, tabIndex)); sb.Append(")"); break; case ISpokeItem.Multiplication: sb.Append("("); sb.Append(evalute(((SpokeMultiplication)condition).LeftSide, tabIndex)); sb.Append("*"); sb.Append(evalute(((SpokeMultiplication)condition).RightSide, tabIndex)); sb.Append(")"); break; case ISpokeItem.Division: sb.Append("("); sb.Append(evalute(((SpokeDivision)condition).LeftSide, tabIndex)); sb.Append("/"); sb.Append(evalute(((SpokeDivision)condition).RightSide, tabIndex)); sb.Append(")"); break; case ISpokeItem.Greater: sb.Append(evalute(((SpokeGreaterThan)condition).LeftSide, tabIndex)); sb.Append(">"); sb.Append(evalute(((SpokeGreaterThan)condition).RightSide, tabIndex)); break; case ISpokeItem.Less: sb.Append(evalute(((SpokeLessThan)condition).LeftSide, tabIndex)); sb.Append(">"); sb.Append(evalute(((SpokeLessThan)condition).RightSide, tabIndex)); break; case ISpokeItem.And: sb.Append(evalute(((SpokeAnd)condition).LeftSide, tabIndex)); sb.Append("&&"); sb.Append(evalute(((SpokeAnd)condition).RightSide, tabIndex)); break; case ISpokeItem.Or: sb.Append(evalute(((SpokeOr)condition).LeftSide, tabIndex)); sb.Append("||"); sb.Append(evalute(((SpokeOr)condition).RightSide, tabIndex)); break; case ISpokeItem.GreaterEqual: sb.Append(evalute(((SpokeGreaterThanOrEqual)condition).LeftSide, tabIndex)); sb.Append(">="); sb.Append(evalute(((SpokeGreaterThanOrEqual)condition).RightSide, tabIndex)); break; case ISpokeItem.LessEqual: sb.Append(evalute(((SpokeLessThanOrEqual)condition).LeftSide, tabIndex)); sb.Append("<="); sb.Append(evalute(((SpokeLessThanOrEqual)condition).RightSide, tabIndex)); break; case ISpokeItem.Equality: sb.Append(evalute(((SpokeEquality)condition).LeftSide, tabIndex)); sb.Append("=="); sb.Append(evalute(((SpokeEquality)condition).RightSide, tabIndex)); break; case ISpokeItem.NotEqual: sb.Append(evalute(((SpokeNotEqual)condition).LeftSide, tabIndex)); sb.Append("!="); sb.Append(evalute(((SpokeNotEqual)condition).RightSide, tabIndex)); break; default: throw new ArgumentOutOfRangeException(); } return(sb.ToString()); }
public Tuple <List <Class>, List <TokenMacroPiece> > Run(string fs) { var words = getWords(fs); var lines = words.Aggregate(new List <LineToken>() { new LineToken() }, (old, n) => { old.Last().Tokens.Add(n); if (n.Type == Token.NewLine) { if (old.Any() && (old.Last().Tokens.Count == 0)) { return(old); } if (old.Any() && ((old.Last().Tokens.First().Type == Token.Tab || old.Last().Tokens.First().Type == Token.NewLine) && old.Last().Tokens.Count == 1)) { old.Last().Tokens.Clear(); return(old); } old.Add(new LineToken()); return(old); } return(old); }); foreach (var a in lines) { if (!(!a.Tokens.Any() || (a.Tokens[0].Type == Token.Class || a.Tokens[0].Type == Token.Macro || a.Tokens[0].Type == Token.Tab))) { } } for (int index = lines.Count - 1; index >= 0; index--) { var lineToken = lines[index]; if (lineToken.Tokens.Count == 0) { lines.RemoveAt(index); continue; } if (lineToken.Tokens[0].Type == Token.Tab) { if (lineToken.Tokens.Count == 1) { lines.RemoveAt(index); continue; } if (lineToken.Tokens[1].Type == Token.NewLine) { lines.RemoveAt(index); continue; } back: if (lineToken.Tokens[1].Type == Token.Tab) { ((TokenTab)lineToken.Tokens[0]).TabIndex += ((TokenTab)lineToken.Tokens[1]).TabIndex; lineToken.Tokens.RemoveAt(1); goto back; } } } int done = 0; int indes = 0; List <List <LineToken> > macros; List <TokenMacroPiece> allMacros = new List <TokenMacroPiece>(); if (lines.Any() && lines[0].Tokens[0].Type == Token.Macro) { macros = lines.Aggregate(new List <List <LineToken> >() { }, delegate(List <List <LineToken> > old, LineToken n) { if (n.Tokens.Count == 0) { return(old); } indes = indes + 1; if (done > 0 || n.Tokens[0].Type == Token.Class) { if (done == 0) { done = indes - 2; } return(old); } if (n.Tokens[0].Type == Token.Macro) { old.Add(new List <LineToken>()); } old.Last().Add(n); return(old); }); for (int i = done; i >= 0; i--) { lines.RemoveAt(i); } foreach (List <LineToken> macro in macros) { TokenMacroPiece mp = new TokenMacroPiece(); allMacros.Add(mp); mp.Lines = new List <LineToken>(); TokenEnumerator en = new TokenEnumerator(macro.ToArray()); StaticMethods.Assert(en.Current.Type == Token.Macro, "notMacro?"); en.MoveNext(); List <IToken> mps = new List <IToken>(); int curLine = 0; if (en.Current.Type == Token.SemiColon) { StaticMethods.Assert(en.Current.Type == Token.SemiColon, ""); en.MoveNext(); while (en.Current.Type != Token.SemiColon) { mps.Add(en.Current); en.MoveNext(); } mp.Macro = mps.ToArray(); StaticMethods.Assert(en.Current.Type == Token.SemiColon, ""); en.MoveNext(); StaticMethods.Assert(en.Current.Type == Token.AnonMethodStart, ""); en.MoveNext(); StaticMethods.Assert(en.Current.Type == Token.Bar, ""); en.MoveNext(); StaticMethods.Assert(en.Current.Type == Token.OpenParen, ""); en.MoveNext(); List <ParamEter> parameters_ = new List <ParamEter>(); if (en.Current.Type != Token.CloseParen) { pback2: bool byRef = false; if (((TokenWord)en.Current).Word.ToLower() == "ref") { byRef = true; en.MoveNext(); } parameters_.Add(new ParamEter() { ByRef = byRef, Name = ((TokenWord)en.Current).Word }); en.MoveNext(); switch (en.Current.Type) { case Token.CloseParen: en.MoveNext(); break; case Token.Comma: en.MoveNext(); goto pback2; break; default: throw new ArgumentOutOfRangeException(); } } mp.Parameters = parameters_.ToArray(); curLine = 1; } else if (en.Current.Type == Token.OpenCurly) { en.MoveNext(); while (!(en.Current.Type == Token.CloseCurly && en.PeakNext().Type != Token.CloseCurly)) { if (en.Current.Type == Token.OpenCurly && en.PeakNext().Type == Token.OpenCurly) { en.MoveNext(); } if (en.Current.Type == Token.CloseCurly && en.PeakNext().Type == Token.CloseCurly) { en.MoveNext(); } mps.Add(en.Current); en.MoveNext(); } en.MoveNext(); mp.Macro = mps.ToArray().Trim((a) => a.Type == Token.NewLine, (a) => a.Type == Token.Tab); StaticMethods.Assert(en.Current.Type == Token.Colon, ""); en.MoveNext(); StaticMethods.Assert(en.Current.Type == Token.OpenParen, ""); en.MoveNext(); List <ParamEter> parameters_ = new List <ParamEter>(); if (en.Current.Type != Token.CloseParen) { pback2: ParamEter pm; parameters_.Add(pm = new ParamEter() { ByRef = true, Name = ((TokenWord)en.Current).Word }); if (!pm.Name.StartsWith("$")) { throw new Exception("Bad macro param"); } en.MoveNext(); if (en.Current.Type != Token.Equal) { throw new Exception("Bad macro param equals"); } en.MoveNext(); pm.Type = consumeMacroParamValue(en); switch (en.Current.Type) { case Token.CloseParen: en.MoveNext(); break; case Token.Comma: en.MoveNext(); goto pback2; break; default: throw new ArgumentOutOfRangeException(); } } mp.Parameters = parameters_.ToArray(); curLine = en.LineIndex + 1; } else { throw new Exception("Cannot find macro"); } for (int i = curLine; i < macro.Count; i++) { mp.Lines.Add(macro[i]); } if (mp.Lines[0].Tokens.Count > 1 && mp.Lines[0].Tokens[0].Type == Token.Tab && mp.Lines[0].Tokens[1].Type == Token.OpenCurly) { mp.Lines.RemoveAt(0); } if (mp.Lines[mp.Lines.Count - 1].Tokens.Count > 1 && mp.Lines[mp.Lines.Count - 1].Tokens[0].Type == Token.Tab && mp.Lines[mp.Lines.Count - 1].Tokens[1].Type == Token.CloseCurly) { mp.Lines.RemoveAt(mp.Lines.Count - 1); } } } var classes = lines.Aggregate(new List <List <LineToken> >() { }, (old, n) => { if (n.Tokens.Count == 0) { return(old); } if (n.Tokens[0].Type == Token.Class) { old.Add(new List <LineToken>()); } old.Last().Add(n); return(old); }); List <Class> someClasses = new List <Class>(); foreach (List <LineToken> @class in classes) { Class c = new Class(); someClasses.Add(c); c.Name = ((TokenWord)@class[0].Tokens[1]).Word; for (int index = 1; index < @class.Count; index++) { LineToken v = @class[index]; if (v.Tokens[0].Type != Token.Tab) { throw new AbandonedMutexException(); } if (v.Tokens[1].Type != Token.Def) { c.Variables.Add(v); } else { var m = new Method(); if (v.Tokens[2] is TokenOpenParen) { m.Name = ".ctor"; } else { m.Name = ((TokenWord)v.Tokens[2]).Word; } if (v.Tokens.Count != 5 + (v.Tokens[2] is TokenOpenParen ? 0 : 1))//tab def name openP closeP newline { for (int i = 3 + (v.Tokens[2] is TokenOpenParen ? 0 : 1); i < v.Tokens.Count - 2; i++) { m.paramNames.Add(((TokenWord)v.Tokens[i]).Word); i++; } } int tabl = ((TokenTab)v.Tokens[0]).TabIndex + 1; index++; for (; index < @class.Count; index++) { if (((TokenTab)@class[index].Tokens[0]).TabIndex < tabl) { index--; break; } m.Lines.Add(@class[index]); } //index++; c.Methods.Add(m); } } } StringBuilder sb = new StringBuilder(); foreach (var tokenMacroPiece in allMacros) { sb.Append(tokenMacroPiece.ToString()); } sb.AppendLine(); foreach (var someClass in someClasses) { Method ctor = someClass.Methods.FirstOrDefault(a => a.Name == ".ctor"); if (ctor == null) { someClass.Methods.Add(ctor = new Method()); ctor.Name = ".ctor"; } for (int index = 0; index < someClass.Variables.Count; index++) { var lineToken = someClass.Variables[index]; ((TokenTab)lineToken.Tokens[0]).TabIndex++; someClass.VariableNames.Add(((TokenWord)lineToken.Tokens[1]).Word); ctor.Lines.Insert(index, lineToken); } someClass.Variables.Clear(); sb.AppendLine(someClass.ToString()); } File.WriteAllText("C:\\spoke.txt", sb.ToString()); //Console.WriteLine(sb); return(new Tuple <List <Class>, List <TokenMacroPiece> >(someClasses, allMacros)); }