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> >()); }
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>()); }