コード例 #1
0
        private static Maybe <IList <Token> > TokenizeParam(EAParser p, IParamNode param)
        {
            switch (param.Type)
            {
            case ParamType.STRING:
                Token     input = ((StringNode)param).MyToken;
                Tokenizer t     = new Tokenizer();
                return(new Just <IList <Token> >(new List <Token>(t.TokenizeLine(input.Content, input.FileName, input.LineNumber, input.ColumnNumber))));

            case ParamType.MACRO:
                try
                {
                    IList <Token> myBody = new List <Token>(((MacroInvocationNode)param).ExpandMacro());
                    return(new Just <IList <Token> >(myBody));
                }
                catch (KeyNotFoundException)
                {
                    MacroInvocationNode asMacro = (MacroInvocationNode)param;
                    p.Error(asMacro.MyLocation, "Undefined macro: " + asMacro.Name);
                }
                break;

            case ParamType.LIST:
                ListNode n = (ListNode)param;
                return(new Just <IList <Token> >(new List <Token>(n.ToTokens())));

            case ParamType.ATOM:
                return(new Just <IList <Token> >(new List <Token>(((IAtomNode)param).ToTokens())));
            }
            return(new Nothing <IList <Token> >());
        }
コード例 #2
0
        public Maybe <ILineNode> Execute(EAParser p, Token self, IList <IParamNode> parameters, MergeableGenerator <Token> tokens)
        {
            if (parameters[0].Type == ParamType.MACRO)
            {
                MacroInvocationNode signature = (MacroInvocationNode)(parameters[0]);
                string        name            = signature.Name;
                IList <Token> myParams        = new List <Token>();
                foreach (IList <Token> l1 in signature.Parameters)
                {
                    if (l1.Count != 1 || l1[0].Type != TokenType.IDENTIFIER)
                    {
                        p.Error(l1[0].Location, "Macro parameters must be identifiers (got " + l1[0].Content + ").");
                    }
                    else
                    {
                        myParams.Add(l1[0]);
                    }
                }

                /* if (!p.IsValidMacroName(name, myParams.Count))
                 * {
                 *  if (p.IsReservedName(name))
                 *  {
                 *      p.Error(signature.MyLocation, "Invalid redefinition: " + name);
                 *  }
                 *  else
                 *      p.Warning(signature.MyLocation, "Redefining " + name + '.');
                 * }*/
                if (p.Macros.HasMacro(name, myParams.Count))
                {
                    p.Warning(signature.MyLocation, "Redefining " + name + '.');
                }
                Maybe <IList <Token> > toRepl;
                if (parameters.Count != 2)
                {
                    toRepl = new Just <IList <Token> >(new List <Token>());
                }
                else
                {
                    toRepl = ExpandParam(p, parameters[1], myParams.Select((Token t) => t.Content));
                }
                if (!toRepl.IsNothing)
                {
                    p.Macros.AddMacro(new Macro(myParams, toRepl.FromJust), name, myParams.Count);
                }
            }
            else
            {
                //Note [mutually] recursive definitions are handled by Parser expansion.
                Maybe <string> maybeIdentifier;
                if (parameters[0].Type == ParamType.ATOM && !(maybeIdentifier = ((IAtomNode)parameters[0]).GetIdentifier()).IsNothing)
                {
                    string name = maybeIdentifier.FromJust;
                    if (p.Definitions.ContainsKey(name))
                    {
                        p.Warning(parameters[0].MyLocation, "Redefining " + name + '.');
                    }
                    if (parameters.Count == 2)
                    {
                        Maybe <IList <Token> > toRepl = ExpandParam(p, parameters[1], Enumerable.Empty <string>());
                        if (!toRepl.IsNothing)
                        {
                            p.Definitions[name] = new Definition(toRepl.FromJust);
                        }
                    }
                    else
                    {
                        p.Definitions[name] = new Definition();
                    }
                }
                else
                {
                    p.Error(parameters[0].MyLocation, "Definition names must be identifiers (got " + parameters[0].ToString() + ").");
                }
            }
            return(new Nothing <ILineNode>());
        }