internal static void AddMacro(MMap <Symbol, VList <MacroInfo> > macros, MacroInfo info) { var cases = macros[info.Name, VList <MacroInfo> .Empty]; if (!cases.Any(existing => existing.Macro == info.Macro)) { macros[info.Name] = cases.Add(info); } }
private static LNode RegisterSimpleMacro(LNodeList attrs, LNode pattern, LNode body, IMacroContext context) { if (DecodeSubstitutionExpr(pattern, out _, out _, out _) != null) { return(Reject(context, pattern, "Defining a macro that could match everything is not allowed.")); } MacroMode modes = GetMacroMode(ref attrs, pattern); LNode macroName = pattern.Target ?? pattern; LNode replacement = body.AsList(S.Braces).AsLNode(S.Splice); if (pattern.IsCall) { WarnAboutMissingDollarSigns(pattern.Args, context, pattern, replacement); } // Note: we could fill out the macro's Syntax and Description with the // pattern and replacement converted to strings, but it's generally a // waste of CPU time as those strings are usually not requested. // Compromise: provide syntax pattern only var syntax = pattern.ToString(); var lma = new LexicalMacroAttribute(syntax, "User-defined macro at {0}".Localized(pattern.Range.Start), macroName.Name.Name) { Mode = modes }; if ((modes & (MacroMode.MatchEveryLiteral | MacroMode.MatchEveryCall | MacroMode.MatchEveryIdentifier)) != 0) { lma = new LexicalMacroAttribute(syntax, lma.Description) { Mode = modes } } ; var macroInfo = new MacroInfo(null, lma, UserDefinedMacro); macroInfo.Mode |= MacroMode.UseLogicalNameInErrorMessages; context.RegisterMacro(macroInfo); return(F.Splice()); // delete the `define` node from the output LNode UserDefinedMacro(LNode candidate, IMacroContext context2) { MMap <Symbol, LNode> captures = new MMap <Symbol, LNode>(); if (candidate.MatchesPattern(pattern, ref captures, out LNodeList unmatchedAttrs)) { LNode replacement2 = WithUniqueIdentifiers(replacement, context.IncrementTempCounter, out _); return(ReplaceCaptures(replacement2, captures).PlusAttrsBefore(unmatchedAttrs)); } return(null); } }
public static LNode replaceFn(LNode node, IMacroContext context1) { var retType = node.Args[0, LNode.Missing].Name; if (retType != _replace && retType != _define) { return(null); } LNode replaceKw, macroName, args, body; if (EcsValidators.MethodDefinitionKind(node, out replaceKw, out macroName, out args, out body, allowDelegate: false) != S.Fn || body == null) { return(null); } MacroMode mode, modes = 0; var leftoverAttrs = node.Attrs.SmartWhere(attr => { if (attr.IsId && Loyc.Compatibility.EnumStatic.TryParse(attr.Name.Name, out mode)) { modes |= mode; return(false); } return(true); }); LNode pattern = F.Call(macroName, args.Args).PlusAttrs(leftoverAttrs); LNode replacement = body.AsList(S.Braces).AsLNode(S.Splice).PlusAttrs(replaceKw.Attrs); replacement.Style &= ~NodeStyle.OneLiner; WarnAboutMissingDollarSigns(args, context1, pattern, replacement); // Note: we could fill out the macro's Syntax and Description with the // pattern and replacement converted to strings, but it's generally a // waste of CPU time as those strings are usually not requested. var lma = new LexicalMacroAttribute( string.Concat(macroName.Name, "(", args.Args.Count.ToString(), " args)"), "", macroName.Name.Name); var macroInfo = new MacroInfo(null, lma, (candidate, context2) => { MMap <Symbol, LNode> captures = new MMap <Symbol, LNode>(); VList <LNode> unmatchedAttrs; if (candidate.MatchesPattern(pattern, ref captures, out unmatchedAttrs)) { return(ReplaceCaptures(replacement, captures).PlusAttrsBefore(unmatchedAttrs)); } return(null); }) { Mode = modes }; context1.RegisterMacro(macroInfo); return(F.Splice()); }
internal static void AddMacro(MMap <Symbol, VList <MacroInfo> > macros, MacroInfo info) { foreach (string name in info.Names) { var nameS = (Symbol)name; var cases = macros[nameS, VList <MacroInfo> .Empty]; if (!cases.Any(existing => existing.Macro == info.Macro)) { macros[nameS] = cases.Add(info); } } }
internal static void AddMacro(MMap <Symbol, List <MacroInfo> > macros, MacroInfo info) { List <MacroInfo> cases; if (!macros.TryGetValue(info.Name, out cases)) { macros[info.Name] = cases = new List <MacroInfo>(); cases.Add(info); } else { if (!cases.Any(existing => existing.Macro == info.Macro)) { cases.Add(info); } } }
internal static void AddMacro(MMap<Symbol, List<MacroInfo>> macros, MacroInfo info) { List<MacroInfo> cases; if (!macros.TryGetValue(info.Name, out cases)) { macros[info.Name] = cases = new List<MacroInfo>(); cases.Add(info); } else { if (!cases.Any(existing => existing.Macro == info.Macro)) cases.Add(info); } }
public MacroResult(MacroInfo macro, LNode newNode, ListSlice <MessageHolder.Message> msgs, bool dropRemaining) { Macro = macro; NewNode = newNode; Msgs = msgs; DropRemainingNodes = dropRemaining; }
public static LNode replaceFn(LNode node, IMacroContext context1) { var retType = node.Args[0, LNode.Missing].Name; if (retType != _replace && retType != _define) return null; LNode replaceKw, macroName, args, body; if (EcsValidators.MethodDefinitionKind(node, out replaceKw, out macroName, out args, out body, allowDelegate: false) != S.Fn || body == null) return null; MacroMode mode, modes = 0; var leftoverAttrs = node.Attrs.SmartWhere(attr => { if (attr.IsId && Loyc.Compatibility.EnumStatic.TryParse(attr.Name.Name, out mode)) { modes |= mode; return false; } return true; }); LNode pattern = F.Call(macroName, args.Args).PlusAttrs(leftoverAttrs); LNode replacement = body.AsList(S.Braces).AsLNode(S.Splice).PlusAttrs(replaceKw.Attrs); replacement.Style &= ~NodeStyle.OneLiner; WarnAboutMissingDollarSigns(args, context1, pattern, replacement); // Note: we could fill out the macro's Syntax and Description with the // pattern and replacement converted to strings, but it's generally a // waste of CPU time as those strings are usually not requested. var lma = new LexicalMacroAttribute( string.Concat(macroName.Name, "(", args.Args.Count.ToString(), " args)"), "", macroName.Name.Name); var macroInfo = new MacroInfo(null, lma, (candidate, context2) => { MMap<Symbol, LNode> captures = new MMap<Symbol, LNode>(); VList<LNode> unmatchedAttrs; if (candidate.MatchesPattern(pattern, ref captures, out unmatchedAttrs)) { return ReplaceCaptures(replacement, captures).PlusAttrsBefore(unmatchedAttrs); } return null; }) { Mode = modes }; context1.RegisterMacro(macroInfo); return F.Splice(); }
internal static void AddMacro(MMap<Symbol, VList<MacroInfo>> macros, MacroInfo info) { foreach (string name in info.Names) { var nameS = (Symbol)name; var cases = macros[nameS, VList<MacroInfo>.Empty]; if (!cases.Any(existing => existing.Macro == info.Macro)) macros[nameS] = cases.Add(info); } }
public Result(MacroInfo macro, LNode node, ListSlice <MessageHolder.Message> msgs) { Macro = macro; Node = node; Msgs = msgs; }
private static void AddMacroByName(MMap <Symbol, InternalList <InternalMacroInfo> > macros, Symbol name, bool isDeprecatedName, MacroInfo newMacro) { var macrosWithThisName = macros[name, InternalList <InternalMacroInfo> .Empty]; // Check if the same macro was added earlier, possibly in a different namespace foreach (var macro in macrosWithThisName) { if (macro.Macro.Equals(newMacro.Macro)) { if (!macro.Namespaces.Select(p => p.A).Contains(newMacro.Namespace)) { macro.Namespaces.Add(Pair.Create(newMacro.Namespace, isDeprecatedName)); } return; } } // It's a new macro, add it var imi = new InternalMacroInfo { Name = name, Attr = newMacro, Macro = newMacro.Macro, Namespaces = new InternalList <Pair <Symbol, bool> >(new [] { Pair.Create(newMacro.Namespace, isDeprecatedName) }) }; macrosWithThisName.Add(imi); macros[name] = macrosWithThisName; }