Skip to content

Commit aabf130

Browse files
committed
Allow digits in variable names
1 parent 3e9a765 commit aabf130

File tree

3 files changed

+25
-6
lines changed

3 files changed

+25
-6
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,9 @@ Create your own `ExpressionParser` implementation to support other data types
6363

6464
#### Variables
6565

66-
Creation of custom variables is supported. Variable name may contains only english letters and an underscore.
66+
Creation of custom variables is supported.
67+
Variable name must starts with english letter or underscore.
68+
The rest of the variable name may also contains digits.
6769

6870
#### Functions
6971

Runtime/ExpressionParser.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,11 @@ select apply(f, l, r)
6262

6363
private Parser<ExprBuilder> CreateParser()
6464
{
65+
var letterOrUnderscore = Char(c => char.IsLetter(c) || c == '_',
66+
"letter or underscore");
67+
var letterOrDigitOrUnderscore = Char(c => char.IsLetterOrDigit(c) || c == '_',
68+
"letter or digit or underscore");
69+
6570
var constant = (
6671
from number in DecimalInvariant
6772
select MakeConstant(number, Parse)
@@ -84,8 +89,9 @@ select MakeConstant(number, Parse)
8489

8590
var variable =
8691
(
87-
from name in Letter.Or(Char('_')).AtLeastOnce().Text()
88-
select MakeVariable(name)
92+
from nameHead in letterOrUnderscore.Once().Text()
93+
from nameTail in letterOrDigitOrUnderscore.Many().Text()
94+
select MakeVariable(nameHead + nameTail)
8995
).Named("variable");
9096

9197
Parser<ExprBuilder> expression = null;

Tests/ParserTests.cs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -136,11 +136,22 @@ public void ReadmeSample()
136136
}
137137

138138
[Test]
139-
public void Parse_Variable_Invalid()
139+
public void Parse_Variable_Names()
140140
{
141141
var context = new ExpresionContext<float>();
142-
context.RegisterVariable("a", () => 1);
143-
Assert.AreEqual(1, Execute("a", context));
142+
context.RegisterVariable("o", () => 1);
143+
context.RegisterVariable("one", () => 1);
144+
context.RegisterVariable("one123", () => 1);
145+
context.RegisterVariable("_one123", () => 1);
146+
context.RegisterVariable("one_123", () => 1);
147+
context.RegisterVariable("one123_", () => 1);
148+
Assert.AreEqual(1, Execute("o", context));
149+
Assert.AreEqual(1, Execute("one", context));
150+
Assert.AreEqual(1, Execute("one123", context));
151+
Assert.AreEqual(1, Execute("_one123", context));
152+
Assert.AreEqual(1, Execute("one_123", context));
153+
Assert.AreEqual(1, Execute("one123_", context));
154+
Assert.Throws<ParseException>(() => Compile("123one", context));
144155
Assert.Throws<VariableNotDefinedException>(() => Compile("b", context));
145156
}
146157

0 commit comments

Comments
 (0)