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)); }
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>(); var lm = macro[0]; TokenEnumerator en = new TokenEnumerator(new[] { lm }); StaticMethods.Assert(en.Current.Type == Token.Macro, "notMacro?"); en.MoveNext(); StaticMethods.Assert(en.Current.Type == Token.SemiColon, ""); en.MoveNext(); List<IToken> mps = new List<IToken>(); 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(); for (int i = 1; i < macro.Count; i++) { mp.Lines.Add(macro[i]); } } } 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); }