Example #1
0
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        private string[] ParseParameterList(CTokenReader Tokens, bool JustIdentifiers = false)
        {
            //Console.WriteLine("++++++++");
            var Params = new List <string>();

            Tokens.ExpectCurrentAndMoveNextSpace("(");
            while (Tokens.HasMore && Tokens.Current.Raw != ")")
            {
                string Param = "";

                if (JustIdentifiers)
                {
                    Param = Tokens.Current.Raw;
                    Tokens.MoveNextNoSpace();
                    if (Tokens.Current.Raw == ",")
                    {
                        Tokens.ExpectCurrentAndMoveNextNoSpace(",");
                    }
                }
                else
                {
                    int OpenCount = 0;
                    while (Tokens.HasMore)
                    {
                        if (Tokens.Current.Raw == ")")
                        {
                            if (OpenCount <= 0)
                            {
                                break;
                            }
                            else
                            {
                                OpenCount--;
                            }
                        }
                        Param += Tokens.Current.Raw;
                        if (Tokens.Current.Raw == "(")
                        {
                            OpenCount++;
                        }
                        Tokens.MoveNextSpace();
                        if (Tokens.Current.Raw == "," && OpenCount == 0)
                        {
                            Tokens.ExpectCurrentAndMoveNextNoSpace(",");
                            break;
                        }
                    }
                }

                //Console.WriteLine("aa: {0} : {1}", Param, Tokens.Current);
                Params.Add(Param);
            }
            //Console.WriteLine("--------");
            Tokens.ExpectCurrentAndMoveNextSpace(")");
            return(Params.ToArray());
        }
Example #2
0
        /// <summary>
        /// TODO: Have to refactor ParseIdentifier + Expact. They have repeated code!!!
        /// </summary>
        private void ParseIdentifier(CTokenReader Tokens)
        {
            Tokens.ExpectCurrentType(CTokenType.Identifier);

            var Identifier = Tokens.Current.Raw;

            Tokens.MoveNextSpace();

            if (Context.Macros.ContainsKey(Identifier))
            {
                var Macro         = Context.Macros[Identifier];
                var MacroFunction = Context.Macros[Identifier] as MacroFunction;

                if (MacroFunction != null)
                {
                    if (Tokens.Current.Type == CTokenType.Space)
                    {
                        Tokens.MoveNextNoSpace();
                    }

                    if (Tokens.Current.Raw != "(")
                    {
                        throw (new Exception(String.Format("Trying to use a function-like macro without calling it? MACRO: {0}, Token: {1}", Identifier, Tokens.Current)));
                    }
                }

                if (MacroFunction != null)
                {
                    var Parameters = ParseParameterList(Tokens, JustIdentifiers: false);
                    for (int n = 0; n < Parameters.Length; n++)
                    {
                        //Console.WriteLine("  {0}", Parameters[n]);
                        Parameters[n] = Expand(Parameters[n], null, null);
                        //Console.WriteLine("    -> {0}", Parameters[n]);
                    }
                    var Map = MapFunctionParameters(MacroFunction.Parameters, Parameters);

                    Identifier = Expand(MacroFunction.Replacement, Map, new HashSet <string>(new[] { Identifier }));
                }
                else
                {
                    var MacroConstant = Macro as MacroConstant;

                    Identifier = Expand(MacroConstant.Replacement, null, new HashSet <string>(new[] { Identifier }));
                    //Console.WriteLine("a: {0}", MacroConstant.Replacement);
                }
            }
            else
            {
                //Identifier = Identifier;
            }

            Context.TextWriter.Write(ReplaceSimpleVariable(Identifier));
        }
Example #3
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="Process"></param>
        public void ParseFile(bool Process = true)
        {
            //OutputLine();
            Context.SetText(this.CurrentFileName, this.Text, () =>
            {
                while (Tokens.HasMore)
                {
                    //Console.WriteLine("pp: {0} : {1}", Tokens.Current, Tokens.Current.Position);

                    //Console.WriteLine("TOKEN: {0}", Tokens.Current);

                    switch (Tokens.Current.Type)
                    {
                    case CTokenType.Identifier:
                        if (Process)
                        {
                            ParseIdentifier(Tokens);
                        }
                        else
                        {
                            Tokens.MoveNextSpace();
                        }
                        break;

                    case CTokenType.Operator:
                        switch (Tokens.Current.Raw)
                        {
                        case "#":
                            // Preprocessor directive
                            if (Tokens.Current.Position.ColumnNoSpaces == 0)
                            {
                                if (!ParseDirective(Process))
                                {
                                    return;
                                }
                            }
                            break;

                        default:
                            if (Process)
                            {
                                Context.TextWriter.Write(Tokens.Current.Raw);
                            }
                            this.Tokens.MoveNextSpace();
                            break;
                        }
                        break;

                    case CTokenType.Integer:
                    case CTokenType.Float:
                    case CTokenType.String:
                    case CTokenType.Char:
                    case CTokenType.NewLine:
                    case CTokenType.Space:
                        {
                            if (Process)
                            {
                                Context.TextWriter.Write(Tokens.Current.Raw);
                            }
                            this.Tokens.MoveNextSpace();
                        }
                        break;

                    case CTokenType.End:
                        this.Tokens.MoveNextSpace();
                        break;

                    default:
                        throw (new NotImplementedException(String.Format("Can't handle token '{0}'", Tokens.Current)));
                    }
                }
            });
        }
Example #4
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="Texts"></param>
        /// <returns></returns>
        private string Expand(string Text, Dictionary <string, string> Locals = null, HashSet <string> Used = null)
        {
            if (Used == null)
            {
                Used = new HashSet <string>();
            }
            string Output = "";
            var    Tokens = new CTokenReader(new CTokenizer(Text, TokenizeSpaces: true).Tokenize());

            Tokens.MoveNextSpace();
            while (Tokens.HasMore)
            {
                bool Stringify = false;

                if (Locals != null && Tokens.Current.Raw == "##")
                {
                    Tokens.MoveNextSpace();
                }

                if (Tokens.Current.Raw == "#")
                {
                    Tokens.MoveNextSpace();
                    if (Tokens.Current.Type == CTokenType.Identifier)
                    {
                        Stringify = true;
                    }
                    else
                    {
                        Stringify = false;
                        Output   += "#";
                    }
                }

                if (Tokens.Current.Type == CTokenType.Identifier)
                {
                    var CurrentIdentifier = Tokens.Current.Raw;
                    var UpdatedIdentifier = ReplaceSimpleVariable(CurrentIdentifier);
                    if (UpdatedIdentifier != CurrentIdentifier)
                    {
                        Output += UpdatedIdentifier;
                        Tokens.MoveNextSpace();
                        continue;
                    }
                    switch (CurrentIdentifier)
                    {
                    case "__VA_ARGS__":
                        CurrentIdentifier = "...";
                        break;
                    }

                    if (Locals != null && Locals.ContainsKey(CurrentIdentifier))
                    {
                        CurrentIdentifier = Locals[CurrentIdentifier];
                        if (Stringify)
                        {
                            CurrentIdentifier = CToken.Stringify(CurrentIdentifier);
                        }
                        Output += CurrentIdentifier;
                        Tokens.MoveNextSpace();
                    }
                    else if (!Used.Contains(CurrentIdentifier) && Context.Macros.ContainsKey(CurrentIdentifier))
                    {
                        var Macro = Context.Macros[CurrentIdentifier];

                        // Constant
                        if (Macro is MacroConstant)
                        {
                            Output += Expand(Macro.Replacement, null, new HashSet <string>(Used.Concat(new[] { CurrentIdentifier })));
                            Tokens.MoveNextSpace();
                        }
                        // Function
                        else
                        {
                            Tokens.MoveNextNoSpace();
                            Tokens.ExpectCurrent("(");
                            var MacroFunction = Context.Macros[CurrentIdentifier] as MacroFunction;

                            if (MacroFunction == null)
                            {
                                throw (new Exception("Trying to call a non-function macro"));
                            }

                            //Console.WriteLine(":: {0} :: ", Text);

                            var Parameters = ParseParameterList(Tokens, JustIdentifiers: false);
                            for (int n = 0; n < Parameters.Length; n++)
                            {
                                //Console.WriteLine("  {0}", Parameters[n]);
                                Parameters[n] = Expand(Parameters[n], Locals, Used);
                                //Console.WriteLine("    -> {0}", Parameters[n]);
                            }
                            var Map = MapFunctionParameters(MacroFunction.Parameters, Parameters);

                            //foreach (var Item in Map) Console.WriteLine("{0} -> {1}", Item.Key, Item.Value);

                            Output += Expand(MacroFunction.Replacement, Map, new HashSet <string>(new[] { CurrentIdentifier }));
                        }
                    }
                    else
                    {
                        Output += CurrentIdentifier;
                        Tokens.MoveNextSpace();
                    }
                }
                else
                {
                    Output += Tokens.Current.Raw;
                    Tokens.MoveNextSpace();
                }
            }
            return(Output);
        }