From 114ec1295d14dbe8afa04a14c61c217c58956566 Mon Sep 17 00:00:00 2001 From: David Piepgrass Date: Sun, 4 Dec 2016 10:30:07 +0800 Subject: [PATCH] Incremented version to 2.1.1. Macro processor now pays attention to MacroMode.MatchIdentifier. --- Core/AssemblyVersion.cs | 4 +- Main/LLLPG/Properties/AssemblyInfo.cs | 4 +- Main/LeMP.StdMacros/Prelude.Les.cs | 8 +- .../LeMP.StdMacros/Properties/AssemblyInfo.cs | 4 +- Main/LeMP.StdMacros/StandardMacros.cs | 2 +- .../UseSequenceExpressions.out.cs | 3 +- Main/LeMP.StdMacros/UseSymbolsMacro.cs | 2 +- Main/LeMP/BuiltinMacros.cs | 2 +- Main/LeMP/Compiler.cs | 90 +++++++++++++++---- .../LeMP/DemoWindow/LempDemoPanel.Designer.cs | 2 +- Main/LeMP/MacroProcessor.cs | 1 + Main/LeMP/MacroProcessorTask.cs | 41 +++++---- Main/LeMP/Properties/AssemblyInfo.cs | 4 +- Main/LeMP/Tests/MacroProcessorTests.cs | 20 ++++- appveyor.yml | 4 +- 15 files changed, 139 insertions(+), 52 deletions(-) diff --git a/Core/AssemblyVersion.cs b/Core/AssemblyVersion.cs index d013255a5..65414da36 100644 --- a/Core/AssemblyVersion.cs +++ b/Core/AssemblyVersion.cs @@ -13,5 +13,5 @@ // by using '.*' as shown below - but you shouldn't, because it will cause a simple // "Rebuild All" command to produce an incompatible assembly, since the .NET // framework apparently requires an exact match on all four AssemblyVersion numbers. -[assembly: AssemblyVersion("2.1.0.0")] -[assembly: AssemblyFileVersion("2.1.0.0")] +[assembly: AssemblyVersion("2.1.1.0")] +[assembly: AssemblyFileVersion("2.1.1.0")] diff --git a/Main/LLLPG/Properties/AssemblyInfo.cs b/Main/LLLPG/Properties/AssemblyInfo.cs index 72235169a..70129d7a4 100644 --- a/Main/LLLPG/Properties/AssemblyInfo.cs +++ b/Main/LLLPG/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion ("1.9.4.0")] -[assembly: AssemblyFileVersion("1.9.4.0")] +[assembly: AssemblyVersion ("2.1.1.0")] +[assembly: AssemblyFileVersion("2.1.1.0")] diff --git a/Main/LeMP.StdMacros/Prelude.Les.cs b/Main/LeMP.StdMacros/Prelude.Les.cs index 18e727fc2..8be1180dd 100644 --- a/Main/LeMP.StdMacros/Prelude.Les.cs +++ b/Main/LeMP.StdMacros/Prelude.Les.cs @@ -497,7 +497,7 @@ public static LNode @case(LNode node, IMessageSink sink) return null; } - [LexicalMacro("default; default { Code... }", "The default label in a switch statement.", "default")] + [LexicalMacro("default; default { Code... }", "The default label in a switch statement.", "default", Mode = MacroMode.MatchIdentifier)] public static LNode @default1(LNode node, IMessageSink sink) { if (node.IsId) @@ -603,7 +603,7 @@ public static LNode AutoRemoveParens(LNode node) return node; } - [LexicalMacro("return; return Expr", "Returns to the caller of the current method or lambda function.")] + [LexicalMacro("throw; throw Expr", "Returns to the caller of the current method or lambda function.", Mode = MacroMode.MatchIdentifier)] public static LNode @throw(LNode node, IMessageSink sink) { if (node.ArgCount > 1) return null; @@ -626,13 +626,13 @@ public static LNode @using2(LNode node, IMessageSink sink) return null; } - [LexicalMacro("this(Params...)", "Calls a constructor in the same class. Can only be used inside a constructor.")] + [LexicalMacro("this; this(Params...)", "Refers to current object, or calls a constructor in the same class.", Mode = MacroMode.MatchIdentifier)] public static LNode @this(LNode node, IMessageSink sink) { return node.WithName(S.This); } - [LexicalMacro("base(Params...)", "Calls a constructor in the base class. Can only be used inside a constructor.")] + [LexicalMacro("base; base(Params...)", "Refers to base class, or calls a constructor in the base class.", Mode = MacroMode.MatchIdentifier)] public static LNode @base(LNode node, IMessageSink sink) { return node.WithName(S.Base); diff --git a/Main/LeMP.StdMacros/Properties/AssemblyInfo.cs b/Main/LeMP.StdMacros/Properties/AssemblyInfo.cs index 2d94fda6b..2a8c35dac 100644 --- a/Main/LeMP.StdMacros/Properties/AssemblyInfo.cs +++ b/Main/LeMP.StdMacros/Properties/AssemblyInfo.cs @@ -32,7 +32,7 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion ("2.1.0.0")] -[assembly: AssemblyFileVersion("2.1.0.0")] +[assembly: AssemblyVersion ("2.1.1.0")] +[assembly: AssemblyFileVersion("2.1.1.0")] // In case needed by unit tests [assembly: InternalsVisibleTo("LeMP, PublicKey=0024000004800000940000000602000000240000525341310004000001000100adec5c8e52098b94dc60b34ac0916d307eec23b2c285a0beeb7168174fc1f6a71dcae43c88904e2907a12f66861de8d8f130c4f7b57cff0aea92ed06b50d96c63cea2ee19ec5d35a2946ddef3f35f0fbd3ec3a358b46fd05c82837c49d91694c1926935dc83e2a28c1ff077e4d8a5f679f1edb1c8a692aa2913d753ea05f4fba")] diff --git a/Main/LeMP.StdMacros/StandardMacros.cs b/Main/LeMP.StdMacros/StandardMacros.cs index f1351d1a3..f618f22f5 100644 --- a/Main/LeMP.StdMacros/StandardMacros.cs +++ b/Main/LeMP.StdMacros/StandardMacros.cs @@ -250,7 +250,7 @@ public static LNode stringify(LNode node, IMacroContext context) #endregion [LexicalMacro("#ecs;", "Typically used at the top of a file, this macro enable certain EC# features before the EC# compiler is written, by implementing those features as macro. " - +"Currently, `#ecs` expands to `#useSymbols; #useSequenceExpressions`.", "#ecs")] + +"Currently, `#ecs` expands to `#useSymbols; #useSequenceExpressions`.", "#ecs", Mode = MacroMode.MatchIdentifier)] public static LNode ecs(LNode node, IMacroContext context) { if (node.IsCall) diff --git a/Main/LeMP.StdMacros/UseSequenceExpressions.out.cs b/Main/LeMP.StdMacros/UseSequenceExpressions.out.cs index 40e6fbadc..895719b43 100644 --- a/Main/LeMP.StdMacros/UseSequenceExpressions.out.cs +++ b/Main/LeMP.StdMacros/UseSequenceExpressions.out.cs @@ -36,7 +36,8 @@ public static VList MaybeRemoveNoOpFromRunSeq(VList runSeq) return runSeq.WithoutLast(1); return runSeq; } - [LexicalMacro("#useSequenceExpressions; ... if (Foo.Bar()::b.Baz != null) b.Baz.Method(); ...", "Enables the use of variable-declaration and #runSequence expressions, including the quick-binding operator `::` and the `with` expression, in the code that follows." + "Technically this allows any executable code in an expression context, such as while and for-loops, " + "but its name comes from the fact that it is usually used to allow variable declarations. " + "#useSequenceExpressions expects to be used in a declaration context, " + "e.g. at class or namespace level, not within a function.", "#useSequenceExpressions", Mode = MacroMode.NoReprocessing)] + [LexicalMacro("#useSequenceExpressions; ... if (Foo.Bar()::b.Baz != null) b.Baz.Method(); ...", "Enables the use of variable-declaration and #runSequence expressions, including the quick-binding operator `::` and the `with` expression, in the code that follows." + "Technically this allows any executable code in an expression context, such as while and for-loops, " + "but its name comes from the fact that it is usually used to allow variable declarations. " + "#useSequenceExpressions expects to be used in a declaration context, " + "e.g. at class or namespace level, not within a function.", + "#useSequenceExpressions", Mode = MacroMode.NoReprocessing | MacroMode.MatchIdentifier)] public static LNode useSequenceExpressions(LNode node, IMacroContext context) { var tmp_0 = context.GetArgsAndBody(true); diff --git a/Main/LeMP.StdMacros/UseSymbolsMacro.cs b/Main/LeMP.StdMacros/UseSymbolsMacro.cs index cb7ddcfdb..34c7703e5 100644 --- a/Main/LeMP.StdMacros/UseSymbolsMacro.cs +++ b/Main/LeMP.StdMacros/UseSymbolsMacro.cs @@ -16,7 +16,7 @@ partial class StandardMacros [LexicalMacro("#useSymbols; ... @@Foo ...", "Enables @@symbols to be used in the code that follows. A static readonly variable named sy_X will be created for each symbol @@X. " +"The #useSymbols macro can be invoked at global scope, or inside a type definition where static variables are allowed. Cannot be used inside a method.", - "#useSymbols", "use_symbols" /*old name*/, Mode = MacroMode.NoReprocessing)] + "#useSymbols", "use_symbols" /*old name*/, Mode = MacroMode.NoReprocessing | MacroMode.MatchIdentifier)] public static LNode useSymbols(LNode input, IMacroContext context) { bool inType = context.Ancestors.Any(parent => { diff --git a/Main/LeMP/BuiltinMacros.cs b/Main/LeMP/BuiltinMacros.cs index ae905e1b2..77973a0e5 100644 --- a/Main/LeMP/BuiltinMacros.cs +++ b/Main/LeMP/BuiltinMacros.cs @@ -115,7 +115,7 @@ public static LNode printKnownMacros(LNode node, IMacroContext context) descr.Append("\t"); LNode line = mi.Names.Length == 1 ? (LNode)LNode.Id(mi.Names[0]) - : LNode.Call(S.Tuple, LNode.List(mi.Names.Select(name => LNode.Id(name)))); + : LNode.Call(S.Tuple, LNode.List(mi.Names.Select(name => (LNode)LNode.Id(name)))); string methodName = mi.Macro.Method.Name, @class = mi.Macro.Method.DeclaringType.Name; string postComment = " " + @class + "." + methodName; diff --git a/Main/LeMP/Compiler.cs b/Main/LeMP/Compiler.cs index e2b06476a..e17adf892 100644 --- a/Main/LeMP/Compiler.cs +++ b/Main/LeMP/Compiler.cs @@ -53,6 +53,13 @@ public class Compiler { "set", Pair.Create("key=literal", "Associate a value with a key (use #get(key) to read it back)") }, { "snippet", Pair.Create("key=code", "Associate code with a key (use #get(key) to read it back)") }, { "preserve-comments", Pair.Create("bool", "Preserve comments and newlines (where supported)\n Default value: true") }, + { "o-indent-spaces", Pair.Create("count", "Sets number of spaces per indentation level (0 for tabs)") }, + { "o-allow-change-parens", Pair.Create("bool", "Sets ILNodePrintingOptions.AllowChangeParentheses") }, + { "o-omit-comments", Pair.Create("bool", "Sets ILNodePrintingOptions.OmitComments") }, + { "o-omit-unknown-trivia", Pair.Create("bool", "Sets ILNodePrintingOptions.OmitUnknownTrivia") }, + { "o-explicit-trivia", Pair.Create("bool", "Sets ILNodePrintingOptions.PrintTriviaExplicitly") }, + { "o-compatibility-mode", Pair.Create("bool", "Sets ILNodePrintingOptions.CompatibilityMode") }, + { "o-compact-mode", Pair.Create("bool", "Sets ILNodePrintingOptions.CompactMode") }, }; #region Main() @@ -217,6 +224,8 @@ public bool ProcessArguments(BMultiMap options, bool warnAboutUn { Compiler c = this; string value; + bool? flag; + double? num; var filter = c.Sink as SeverityMessageFilter ?? new SeverityMessageFilter(c.Sink, Severity.Note); if (warnAboutUnknownOptions) @@ -235,8 +244,8 @@ public bool ProcessArguments(BMultiMap options, bool warnAboutUn IMessageSink sink = c.Sink = filter; - if (options.TryGetValue("max-expand", out value)) - TryCatch("While parsing max-expand", sink, () => c.MaxExpansions = int.Parse(value)); + if ((num = ParseNumericOption(options, "max-expand", sink, 0, 99999)) != null) + c.MaxExpansions = (int)num.Value; foreach (var macroDll in options["macros"]) { @@ -261,10 +270,12 @@ public bool ProcessArguments(BMultiMap options, bool warnAboutUn c.AddMacros(assembly); }); } - if (options.TryGetValue("noparallel", out value) && (value == null || value == "true")) - c.Parallel = false; - if (options.TryGetValue("outext", out c.OutExt) && c.OutExt != null && !c.OutExt.StartsWith(".")) - c.OutExt = "." + c.OutExt; + if ((flag = ParseBoolOption(options, "noparallel", sink)) != null) + c.Parallel = flag.Value; + if (options.TryGetValue("outext", out c.OutExt)) { + if (c.OutExt != null && !c.OutExt.StartsWith(".")) + c.OutExt = "." + c.OutExt; + } if (options.TryGetValue("inlang", out value)) { ApplyLanguageOption(sink, "--inlang", value, ref c.InLang); } @@ -273,17 +284,13 @@ public bool ProcessArguments(BMultiMap options, bool warnAboutUn ApplyLanguageOption(sink, "--outlang", value, ref lang); c.OutLang = (lang as ILNodePrinter) ?? c.OutLang; } - if (options.TryGetValue("forcelang", out value) && (value == null || value == "true")) - c.ForceInLang = true; + if ((flag = ParseBoolOption(options, "forcelang", sink)) != null) + c.ForceInLang = flag.Value; if (!options.ContainsKey("outlang") && c.OutExt != null && ParsingService.GetServiceForFileName(c.OutExt) == null) sink.Write(Severity.Error, "--outext", "No language was found for extension «{0}»", c.OutExt); - double num; - if (options.TryGetValue("timeout", out value)) { - if (!double.TryParse(value, out num) || !(num >= 0)) - sink.Write(Severity.Error, "--timeout", "Invalid or missing timeout value", c.OutExt); - else - c.AbortTimeout = TimeSpan.FromSeconds(num); - } + if ((num = ParseNumericOption(options, "timeout", sink)) != null) + c.AbortTimeout = TimeSpan.FromSeconds(num.Value); + foreach (string exprStr in options["set"]) SetPropertyHelper(exprStr, quote: false); foreach (string exprStr in options["snippet"]) @@ -295,6 +302,22 @@ public bool ProcessArguments(BMultiMap options, bool warnAboutUn if (options.TryGetValue("preserve-comments", out value)) PreserveComments = value == null || !value.ToString().ToLowerInvariant().IsOneOf("false", "0"); + // Printing options + if ((num = ParseNumericOption(options, "o-indent-spaces", sink, 0, 20)) != null) + OutOptions.IndentString = num.Value <= 0 ? "\t" : new string(' ', (int)num.Value); + if ((flag = ParseBoolOption(options, "o-allow-change-parens", sink)) != null) + OutOptions.AllowChangeParentheses = flag.Value; + if ((flag = ParseBoolOption(options, "o-omit-comments", sink)) != null) + OutOptions.OmitComments = flag.Value; + if ((flag = ParseBoolOption(options, "o-omit-unknown-trivia", sink)) != null) + OutOptions.OmitUnknownTrivia = flag.Value; + if ((flag = ParseBoolOption(options, "o-explicit-trivia", sink)) != null) + OutOptions.PrintTriviaExplicitly = flag.Value; + if ((flag = ParseBoolOption(options, "o-compatibility-mode", sink)) != null) + OutOptions.CompatibilityMode = flag.Value; + if ((flag = ParseBoolOption(options, "o-compact-mode", sink)) != null) + OutOptions.CompactMode = flag.Value; + if (inputFiles != null) { this.Files = new List(OpenSourceFiles(Sink, inputFiles)); if (inputFiles.Count != 0 && Files.Count == 0) @@ -304,6 +327,40 @@ public bool ProcessArguments(BMultiMap options, bool warnAboutUn return true; } + private double? ParseNumericOption(BMultiMap options, string key, IMessageSink sink, double? min = null, double? max = null) + { + string value; + if (!options.TryGetValue(key, out value)) + return null; + double num; + if (double.TryParse(value, out num)) { + if ((min == null || num >= min.Value) && + (max == null || num <= max.Value)) + return num; + } + if (sink != null) { + if (min != null && max != null) + sink.Write(Severity.Error, "--" + key, "Expected numeric value between {0} and {1}", min.Value, max.Value); + else + sink.Write(Severity.Error, "--" + key, "Expected numeric value"); + } + return null; + } + + private bool? ParseBoolOption(BMultiMap options, string key, IMessageSink sink) + { + string value; + if (!options.TryGetValue(key, out value)) + return null; + if (value.Equals("true", StringComparison.InvariantCultureIgnoreCase) || value == "1") + return true; + if (value.Equals("false", StringComparison.InvariantCultureIgnoreCase) || value == "0") + return false; + if (sink != null) + sink.Write(Severity.Error, "--" + key, "Expected boolean `true` or `false`"); + return null; + } + /// Adds standard macros from LeMP.StdMacros.dll, and adds the /// namespaces LeMP and LeMP.Prelude to the pre-opened namespace list. /// Note: prelude macros were already added by the constructor. @@ -377,6 +434,7 @@ public IMessageSink Sink { public bool PreserveComments = true; // whether to preserve comments by default, if supported by input and output lang public ParsingMode ParsingMode = ParsingMode.File; public ILNodePrinter OutLang; // null to use LNode.Printer + public LNodePrinterOptions OutOptions = new LNodePrinterOptions { IndentString = "\t", NewlineString = "\n" }; public string OutExt; // output extension and optional suffix (includes leading '.'); null for same ext public bool ForceInLang; // InLang overrides input file extension @@ -419,6 +477,8 @@ public void CompleteInputOutputOptions(InputOutput file) } file.OutPrinter = outLang ?? LNode.Printer; } + if (file.OutOptions == null) + file.OutOptions = OutOptions; if (file.PreserveComments == null) file.PreserveComments = PreserveComments; if (file.ParsingMode == null) diff --git a/Main/LeMP/DemoWindow/LempDemoPanel.Designer.cs b/Main/LeMP/DemoWindow/LempDemoPanel.Designer.cs index a65543ad0..b8e86cd23 100644 --- a/Main/LeMP/DemoWindow/LempDemoPanel.Designer.cs +++ b/Main/LeMP/DemoWindow/LempDemoPanel.Designer.cs @@ -173,7 +173,7 @@ private void InitializeComponent() this._txtOptions.Name = "_txtOptions"; this._txtOptions.Size = new System.Drawing.Size(282, 20); this._txtOptions.TabIndex = 3; - this._txtOptions.Text = "--timeout=10 --outext=out.cs --inlang=ecs"; + this._txtOptions.Text = "--timeout=10 --outext=out.cs --inlang=ecs --forcelang"; // // LempDemoPanel // diff --git a/Main/LeMP/MacroProcessor.cs b/Main/LeMP/MacroProcessor.cs index ebc1a92c6..d5712c3b2 100644 --- a/Main/LeMP/MacroProcessor.cs +++ b/Main/LeMP/MacroProcessor.cs @@ -28,6 +28,7 @@ public InputOutput(ICharSource text, string fileName, IParsingService input = nu public bool? PreserveComments; // null means unassigned (to use the Compiler default) public ParsingMode ParsingMode; // inputType argument when parsing with IParsingService.Parse public ILNodePrinter OutPrinter; + public ILNodePrinterOptions OutOptions; public string OutFileName; public VList Output; public override string ToString() diff --git a/Main/LeMP/MacroProcessorTask.cs b/Main/LeMP/MacroProcessorTask.cs index b90f0e364..5a802f68c 100644 --- a/Main/LeMP/MacroProcessorTask.cs +++ b/Main/LeMP/MacroProcessorTask.cs @@ -467,15 +467,17 @@ public void BeforeApplyMacros() #region Find macros by name: GetApplicableMacros - public int GetApplicableMacros(IReadOnlyCollection openNamespaces, Symbol name, ICollection found) + public int GetApplicableMacros(IReadOnlyCollection openNamespaces, Symbol name, ICollection found, bool isIdentifier) { VList candidates; if (_curScope._macros.TryGetValue(name, out candidates)) { int count = 0; foreach (var info in candidates) { if (openNamespaces.Contains(info.Namespace) || info.Namespace == null) { - count++; - found.Add(info); + if (!isIdentifier || (info.Mode & MacroMode.MatchIdentifier) != 0) { + count++; + found.Add(info); + } } } return count; @@ -674,7 +676,8 @@ LNode ApplyMacros(LNode input, int maxExpansions, bool isTargetNode, bool isSing try { if (_s.FoundMacros.Count == 0) { nodeQueue = _s.NodeQueue; - return ApplyMacrosToChildrenOf(curNode, maxExpansions) ?? resultNode; + bool skipTarget = curNode.HasSimpleHeadWithoutPAttrs(); + return ApplyMacrosToChildrenOf(curNode, maxExpansions, skipTarget) ?? resultNode; } // USER MACROS RUN HERE! @@ -683,7 +686,8 @@ LNode ApplyMacros(LNode input, int maxExpansions, bool isTargetNode, bool isSing // Macro(s) had no effect (not in this iteration, anyway), // so move on to processing children. nodeQueue = _s.NodeQueue; - return _s.Preprocessed ?? ApplyMacrosToChildrenOf(curNode, maxExpansions) ?? resultNode; + bool skipTarget = curNode.HasSimpleHeadWithoutPAttrs() && !_s.FoundMacros.Any(m => (m.Mode & MacroMode.MatchIdentifier) != 0); + return _s.Preprocessed ?? ApplyMacrosToChildrenOf(curNode, maxExpansions, skipTarget) ?? resultNode; } result = result_.Value; } finally { @@ -724,12 +728,12 @@ private void GetApplicableMacros(LNode curNode, List foundMacros) { LNode target; if (curNode.HasSimpleHead()) { - GetApplicableMacros(_curScope.OpenNamespaces, curNode.Name, foundMacros); + GetApplicableMacros(_curScope.OpenNamespaces, curNode.Name, foundMacros, curNode.IsId); } else if ((target = curNode.Target).Calls(S.Dot, 2) && target.Args[1].IsId) { Symbol name = target.Args[1].Name; if (_macros.ContainsKey(name)) { Symbol @namespace = NamespaceToSymbol(target.Args[0]); - GetApplicableMacros(ListExt.Single(@namespace), name, foundMacros); + GetApplicableMacros(ListExt.Single(@namespace), name, foundMacros, false); } } } @@ -897,7 +901,7 @@ private void Add(ref VList results, LNode result) results.Add(result); } - LNode ApplyMacrosToChildrenOf(LNode node, int maxExpansions) + LNode ApplyMacrosToChildrenOf(LNode node, int maxExpansions, bool skipTarget = false) { if (maxExpansions <= 0) return null; @@ -911,17 +915,20 @@ LNode ApplyMacrosToChildrenOf(LNode node, int maxExpansions) node = node.WithAttrs(newAttrs); changed = true; } - LNode target = node.Target; - if (target != null && target.Kind != LNodeKind.Literal) + if (!skipTarget) { - DList> _ = null; - LNode newTarget = ApplyMacros(target, maxExpansions, true, true, ref _); - if (newTarget != null) + LNode target = node.Target; + if (target != null && target.Kind != LNodeKind.Literal) { - if (newTarget.Calls(S.Splice, 1)) - newTarget = newTarget.Args[0]; - node = node.WithTarget(newTarget); - changed = true; + DList> _ = null; + LNode newTarget = ApplyMacros(target, maxExpansions, true, true, ref _); + if (newTarget != null) + { + if (newTarget.Calls(S.Splice, 1)) + newTarget = newTarget.Args[0]; + node = node.WithTarget(newTarget); + changed = true; + } } } var newArgs = ApplyMacrosToList(old = node.Args, maxExpansions, false); diff --git a/Main/LeMP/Properties/AssemblyInfo.cs b/Main/LeMP/Properties/AssemblyInfo.cs index 655911055..87139db88 100644 --- a/Main/LeMP/Properties/AssemblyInfo.cs +++ b/Main/LeMP/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion ("2.1.0.0")] -[assembly: AssemblyFileVersion("2.1.0.0")] +[assembly: AssemblyVersion ("2.1.1.0")] +[assembly: AssemblyFileVersion("2.1.1.0")] diff --git a/Main/LeMP/Tests/MacroProcessorTests.cs b/Main/LeMP/Tests/MacroProcessorTests.cs index 67167e404..c2e70503c 100644 --- a/Main/LeMP/Tests/MacroProcessorTests.cs +++ b/Main/LeMP/Tests/MacroProcessorTests.cs @@ -43,7 +43,7 @@ public static LNode priorityTestPCB(LNode node, IMessageSink sink) return node.WithArgs(node[1], node[0]); return null; } - [LexicalMacro("braceTheRest", "Put the rest of the statements in braces")] + [LexicalMacro("braceTheRest", "Put the rest of the statements in braces", Mode = MacroMode.MatchIdentifier)] public static LNode braceTheRest(LNode node, IMacroContext context) { context.DropRemainingNodes = true; @@ -76,6 +76,17 @@ public static LNode overrideTarget(LNode outerNode, IMacroContext context1) Mode = MacroMode.PriorityOverride // needed by the unit test }))); } + + [LexicalMacro("bob", "= bobby")] + public static LNode bob(LNode node, IMacroContext context) + { + return LNode.Id("bobby"); + } + [LexicalMacro("tom", "= tommy", Mode = MacroMode.MatchIdentifier)] + public static LNode tom(LNode node, IMacroContext context) + { + return LNode.Id("tommy"); + } } } namespace LeMP @@ -254,6 +265,13 @@ public void RegisterMacros() "{ Hi(1); { Hello(2); Bye(3); } Hello(4); }"); } + [Test] + public void MatchIdentifierTest() + { + Test("import_macros LeMP.Tests; bob(); tom();", "bobby; tommy;"); + Test("import_macros LeMP.Tests; bob; tom;", "bob; tommy;"); + } + SeverityMessageFilter _sink = new SeverityMessageFilter(MessageSink.Console, Severity.Debug); private void Test(string input, string output, int maxExpand = 0xFFFF) diff --git a/appveyor.yml b/appveyor.yml index df97aae13..74f6e95f3 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 2.0.1.{build} +version: 2.1.1.{build} before_build: - nuget restore Loyc-Slim.sln @@ -6,7 +6,7 @@ before_build: build_script: # First, set some environment variables. # SEMVER is set manually. Not sure how this can be automated. - - set SEMVER=2.0.1 + - set SEMVER=2.1.1 - echo %APPVEYOR_REPO_TAG% # Build packages as SEMVER-ci{build} - ps: if ($env:APPVEYOR_REPO_TAG -eq $True) { $env:PKG_VERSION = $env:SEMVER; } else { $env:PKG_VERSION = "$($env:SEMVER)-ci$($env:APPVEYOR_BUILD_NUMBER)"; }