Exemplo n.º 1
0
        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));
        }