Skip to content

Commit

Permalink
Incremented version to 2.1.1. Macro processor now pays attention to M…
Browse files Browse the repository at this point in the history
…acroMode.MatchIdentifier.
  • Loading branch information
qwertie committed Dec 4, 2016
1 parent 9de8da3 commit 114ec12
Show file tree
Hide file tree
Showing 15 changed files with 139 additions and 52 deletions.
4 changes: 2 additions & 2 deletions Core/AssemblyVersion.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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")]
4 changes: 2 additions & 2 deletions Main/LLLPG/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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")]
8 changes: 4 additions & 4 deletions Main/LeMP.StdMacros/Prelude.Les.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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;
Expand All @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions Main/LeMP.StdMacros/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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")]
2 changes: 1 addition & 1 deletion Main/LeMP.StdMacros/StandardMacros.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
3 changes: 2 additions & 1 deletion Main/LeMP.StdMacros/UseSequenceExpressions.out.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ public static VList<LNode> MaybeRemoveNoOpFromRunSeq(VList<LNode> 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);
Expand Down
2 changes: 1 addition & 1 deletion Main/LeMP.StdMacros/UseSymbolsMacro.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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 => {
Expand Down
2 changes: 1 addition & 1 deletion Main/LeMP/BuiltinMacros.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
90 changes: 75 additions & 15 deletions Main/LeMP/Compiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -217,6 +224,8 @@ public bool ProcessArguments(BMultiMap<string, string> 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)
Expand All @@ -235,8 +244,8 @@ public bool ProcessArguments(BMultiMap<string, string> 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"])
{
Expand All @@ -261,10 +270,12 @@ public bool ProcessArguments(BMultiMap<string, string> 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);
}
Expand All @@ -273,17 +284,13 @@ public bool ProcessArguments(BMultiMap<string, string> 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"])
Expand All @@ -295,6 +302,22 @@ public bool ProcessArguments(BMultiMap<string, string> 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<InputOutput>(OpenSourceFiles(Sink, inputFiles));
if (inputFiles.Count != 0 && Files.Count == 0)
Expand All @@ -304,6 +327,40 @@ public bool ProcessArguments(BMultiMap<string, string> options, bool warnAboutUn
return true;
}

private double? ParseNumericOption(BMultiMap<string, string> 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<string, string> 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;
}

/// <summary>Adds standard macros from LeMP.StdMacros.dll, and adds the
/// namespaces LeMP and LeMP.Prelude to the pre-opened namespace list.</summary>
/// <remarks>Note: prelude macros were already added by the constructor.</remarks>
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion Main/LeMP/DemoWindow/LempDemoPanel.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Main/LeMP/MacroProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<LNode> Output;
public override string ToString()
Expand Down
41 changes: 24 additions & 17 deletions Main/LeMP/MacroProcessorTask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -467,15 +467,17 @@ public void BeforeApplyMacros()

#region Find macros by name: GetApplicableMacros

public int GetApplicableMacros(IReadOnlyCollection<Symbol> openNamespaces, Symbol name, ICollection<MacroInfo> found)
public int GetApplicableMacros(IReadOnlyCollection<Symbol> openNamespaces, Symbol name, ICollection<MacroInfo> found, bool isIdentifier)
{
VList<MacroInfo> 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;
Expand Down Expand Up @@ -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!
Expand All @@ -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 {
Expand Down Expand Up @@ -724,12 +728,12 @@ private void GetApplicableMacros(LNode curNode, List<MacroInfo> 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);
}
}
}
Expand Down Expand Up @@ -897,7 +901,7 @@ private void Add(ref VList<LNode> 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;
Expand All @@ -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<Pair<LNode, int>> _ = 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<Pair<LNode, int>> _ = 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);
Expand Down
4 changes: 2 additions & 2 deletions Main/LeMP/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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")]
Loading

0 comments on commit 114ec12

Please sign in to comment.