diff --git a/.idea/.idea.Calyx/.idea/.gitignore b/.idea/.idea.Calyx/.idea/.gitignore
new file mode 100644
index 0000000..a4c0e03
--- /dev/null
+++ b/.idea/.idea.Calyx/.idea/.gitignore
@@ -0,0 +1,13 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Rider ignored files
+/projectSettingsUpdater.xml
+/modules.xml
+/.idea.Calyx.iml
+/contentModel.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/.idea.Calyx/.idea/.name b/.idea/.idea.Calyx/.idea/.name
new file mode 100644
index 0000000..6ea682b
--- /dev/null
+++ b/.idea/.idea.Calyx/.idea/.name
@@ -0,0 +1 @@
+Calyx
\ No newline at end of file
diff --git a/.idea/.idea.Calyx/.idea/encodings.xml b/.idea/.idea.Calyx/.idea/encodings.xml
new file mode 100644
index 0000000..df87cf9
--- /dev/null
+++ b/.idea/.idea.Calyx/.idea/encodings.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/.idea/.idea.Calyx/.idea/indexLayout.xml b/.idea/.idea.Calyx/.idea/indexLayout.xml
new file mode 100644
index 0000000..7b08163
--- /dev/null
+++ b/.idea/.idea.Calyx/.idea/indexLayout.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/.idea.Calyx/.idea/misc.xml b/.idea/.idea.Calyx/.idea/misc.xml
new file mode 100644
index 0000000..da6640e
--- /dev/null
+++ b/.idea/.idea.Calyx/.idea/misc.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/.idea.Calyx/.idea/sonarlint/issuestore/index.pb b/.idea/.idea.Calyx/.idea/sonarlint/issuestore/index.pb
new file mode 100644
index 0000000..e69de29
diff --git a/.idea/.idea.Calyx/.idea/sonarlint/securityhotspotstore/index.pb b/.idea/.idea.Calyx/.idea/sonarlint/securityhotspotstore/index.pb
new file mode 100644
index 0000000..e69de29
diff --git a/.idea/.idea.Calyx/.idea/vcs.xml b/.idea/.idea.Calyx/.idea/vcs.xml
new file mode 100644
index 0000000..35eb1dd
--- /dev/null
+++ b/.idea/.idea.Calyx/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Calyx.sln.DotSettings.user b/Calyx.sln.DotSettings.user
new file mode 100644
index 0000000..3298afa
--- /dev/null
+++ b/Calyx.sln.DotSettings.user
@@ -0,0 +1,6 @@
+
+ <SessionState ContinuousTestingMode="0" IsActive="True" Name="FiltersApplyToMemoizedRules" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session">
+ <TestAncestor>
+ <TestId>NUnit3x::7A4CD3DB-F115-4731-B257-EFBC32D8D3C3::net6.0::Calyx.Test.FilterTest.FiltersApplyToMemoizedRules</TestId>
+ </TestAncestor>
+</SessionState>
\ No newline at end of file
diff --git a/Calyx/Syntax/ExpressionChain.cs b/Calyx/Syntax/ExpressionChain.cs
index 45b2ad9..cdc8272 100644
--- a/Calyx/Syntax/ExpressionChain.cs
+++ b/Calyx/Syntax/ExpressionChain.cs
@@ -7,23 +7,25 @@ namespace Calyx.Syntax
{
public class ExpressionChain : IProduction
{
+ private string ruleName;
private string[] components;
private Registry registry;
- public ExpressionChain(string[] components, Registry registry)
+ public ExpressionChain(string ruleName, string[] components, Registry registry)
{
+ RemoveSigil(ref ruleName);
+ this.ruleName = ruleName;
this.registry = registry;
- this.components = components;
+ this.components = components.Skip(1).ToArray();
}
public Expansion Evaluate(Options options)
{
- Expansion eval = registry.Expand(components[0]).Evaluate(options);
+ Expansion eval = registry.Expand(ruleName).Evaluate(options);
string initial = new Expansion(Exp.Expression, eval.Tail).Flatten().ToString();
// Dynamic dispatch to string modifiers one after another
string modified = components
- .Skip(1)
.Aggregate(initial, (accumulator, filterName) => {
try {
return registry.GetFilterComponent(filterName).Invoke(accumulator);
@@ -40,5 +42,13 @@ public Expansion Evaluate(Options options)
return new Expansion(Exp.Expression, new Expansion(Exp.Atom, modified));
}
+
+ private static void RemoveSigil(ref string ruleName)
+ {
+ if (ExpressionNode.IsSigil(ruleName[0]))
+ {
+ ruleName = ruleName.Substring(1);
+ }
+ }
}
}
diff --git a/Calyx/Syntax/ExpressionNode.cs b/Calyx/Syntax/ExpressionNode.cs
index e0a994d..30c79cf 100644
--- a/Calyx/Syntax/ExpressionNode.cs
+++ b/Calyx/Syntax/ExpressionNode.cs
@@ -35,5 +35,10 @@ public Expansion Evaluate(Options options)
Expansion eval = registry.Expand(reference).Evaluate(options);
return new Expansion(Exp.Expression, eval.Tail);
}
+
+ public static bool IsSigil(char character)
+ {
+ return character == MEMO_SIGIL || character == UNIQUE_SIGIL;
+ }
}
}
diff --git a/Calyx/Syntax/TemplateNode.cs b/Calyx/Syntax/TemplateNode.cs
index 6dc72e2..0705814 100644
--- a/Calyx/Syntax/TemplateNode.cs
+++ b/Calyx/Syntax/TemplateNode.cs
@@ -33,7 +33,7 @@ public static TemplateNode Parse(string raw, Registry registry)
// Check if we have a post-processing chain
if (components.Length > 1) {
// Generate a chained expression headed by a non-terminal
- concatNodes.Add(new ExpressionChain(components, registry));
+ concatNodes.Add(new ExpressionChain(components[0], components, registry));
} else {
// Generate a standalone non-terminal expression
concatNodes.Add(ExpressionNode.Parse(components[0], registry));
diff --git a/Tests/FilterTest.cs b/Tests/FilterTest.cs
index 17694f7..7e40eea 100644
--- a/Tests/FilterTest.cs
+++ b/Tests/FilterTest.cs
@@ -99,6 +99,16 @@ public void IncorrectFilterParameterCountThrowsException() {
Assert.Throws(() => registry.Evaluate("start"));
}
+ [Test]
+ public void FiltersApplyToMemoizedRules() {
+ Registry registry = new Registry(new Options(seed: 1234));
+
+ registry.DefineRule("start", new [] { "{$names.uppercase}" });
+ registry.DefineRule("names", new [] { "Jewels" } );
+
+ Assert.That(registry.Evaluate("start").Flatten().ToString(), Is.EqualTo("JEWELS"));
+ }
+
internal static class TestFilter {
[FilterName("backwards")]
public static string Backwards(string input, Options options) {