Skip to content

Commit cdef728

Browse files
committed
indexing assignation
1 parent d20a7af commit cdef728

File tree

1 file changed

+57
-13
lines changed

1 file changed

+57
-13
lines changed

CodingSeb.ExpressionEvaluator/ExpressionEvaluator.cs

Lines changed: 57 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,19 @@ public class ExpressionEvaluator
1616
{
1717
#region Regex declarations
1818

19-
private static Regex varOrFunctionRegEx = new Regex(@"^((?<sign>[+-])|(?<inObject>(?<nullConditional>[?])?\.)?)(?<name>[a-zA-Z_][a-zA-Z0-9_]*)\s*((?<assignationOperator>(?<assignmentPrefix>[+\-*/%&|^]|<<|>>)?=(?![=>]))|(?<postfixOperator>([+][+]|--)(?![a-zA-Z0-9_]))|((?<isgeneric>[<](?>[^<>]+|(?<gentag>[<])|(?<-gentag>[>]))*(?(gentag)(?!))[>])?(?<isfunction>[(])?))", RegexOptions.IgnoreCase | RegexOptions.Compiled);
20-
private static Regex numberRegex = new Regex(@"^(?<sign>[+-])?\d+(?<hasdecimal>\.?\d+(e[+-]?\d+)?)?(?<type>ul|[fdulm])?", RegexOptions.IgnoreCase);
21-
private static Regex stringBeginningRegex = new Regex("^(?<interpolated>[$])?(?<escaped>[@])?[\"]");
22-
private static Regex internalCharRegex = new Regex(@"^['](\\[']|[^'])*[']");
23-
private static Regex castRegex = new Regex(@"^\(\s*(?<typeName>[a-zA-Z_][a-zA-Z0-9_\.\[\]<>]*[?]?)\s*\)");
24-
private static Regex indexingBeginningRegex = new Regex(@"^[?]?\[");
25-
private static Regex endOfStringWithDollar = new Regex("^[^\"{]*[\"{]");
26-
private static Regex endOfStringWithoutDollar = new Regex("^[^\"]*[\"]");
27-
private static Regex endOfStringInterpolationRegex = new Regex("^[^}\"]*[}\"]");
28-
private static Regex stringBeginningForEndBlockRegex = new Regex("[$]?[@]?[\"]$");
29-
private static Regex lambdaExpressionRegex = new Regex(@"^\s*(?<args>(\s*[(]\s*([a-zA-Z_][a-zA-Z0-9_]*\s*([,]\s*[a-zA-Z_][a-zA-Z0-9_]*\s*)*)?[)])|[a-zA-Z_][a-zA-Z0-9_]*)\s*=>(?<expression>.*)$", RegexOptions.Singleline);
30-
private static Regex lambdaArgRegex = new Regex(@"[a-zA-Z_][a-zA-Z0-9_]*");
19+
private static readonly Regex varOrFunctionRegEx = new Regex(@"^((?<sign>[+-])|(?<inObject>(?<nullConditional>[?])?\.)?)(?<name>[a-zA-Z_][a-zA-Z0-9_]*)\s*((?<assignationOperator>(?<assignmentPrefix>[+\-*/%&|^]|<<|>>)?=(?![=>]))|(?<postfixOperator>([+][+]|--)(?![a-zA-Z0-9_]))|((?<isgeneric>[<](?>[^<>]+|(?<gentag>[<])|(?<-gentag>[>]))*(?(gentag)(?!))[>])?(?<isfunction>[(])?))", RegexOptions.IgnoreCase | RegexOptions.Compiled);
20+
private static readonly Regex numberRegex = new Regex(@"^(?<sign>[+-])?\d+(?<hasdecimal>\.?\d+(e[+-]?\d+)?)?(?<type>ul|[fdulm])?", RegexOptions.IgnoreCase);
21+
private static readonly Regex stringBeginningRegex = new Regex("^(?<interpolated>[$])?(?<escaped>[@])?[\"]");
22+
private static readonly Regex internalCharRegex = new Regex(@"^['](\\[']|[^'])*[']");
23+
private static readonly Regex castRegex = new Regex(@"^\(\s*(?<typeName>[a-zA-Z_][a-zA-Z0-9_\.\[\]<>]*[?]?)\s*\)");
24+
private static readonly Regex indexingBeginningRegex = new Regex(@"^[?]?\[");
25+
private static readonly Regex assignationOperatorRegex = new Regex(@"^\s*(?<assignmentPrefix>[+\-*/%&|^]|<<|>>)?=(?![=>])");
26+
private static readonly Regex endOfStringWithDollar = new Regex("^[^\"{]*[\"{]");
27+
private static readonly Regex endOfStringWithoutDollar = new Regex("^[^\"]*[\"]");
28+
private static readonly Regex endOfStringInterpolationRegex = new Regex("^[^}\"]*[}\"]");
29+
private static readonly Regex stringBeginningForEndBlockRegex = new Regex("[$]?[@]?[\"]$");
30+
private static readonly Regex lambdaExpressionRegex = new Regex(@"^\s*(?<args>(\s*[(]\s*([a-zA-Z_][a-zA-Z0-9_]*\s*([,]\s*[a-zA-Z_][a-zA-Z0-9_]*\s*)*)?[)])|[a-zA-Z_][a-zA-Z0-9_]*)\s*=>(?<expression>.*)$", RegexOptions.Singleline);
31+
private static readonly Regex lambdaArgRegex = new Regex(@"[a-zA-Z_][a-zA-Z0-9_]*");
3132

3233
private static readonly string instanceCreationWithNewKeywordRegexPattern = @"^new\s+(?<name>[a-zA-Z_][a-zA-Z0-9_.]*)\s*(?<isgeneric>[<](?>[^<>]+|(?<gentag>[<])|(?<-gentag>[>]))*(?(gentag)(?!))[>])?(?<isfunction>[(])?";
3334
private Regex instanceCreationWithNewKeywordRegex = new Regex(instanceCreationWithNewKeywordRegexPattern);
@@ -1641,9 +1642,52 @@ private bool EvaluateIndexing(string expr, string s, Stack<object> stack, ref in
16411642
ExpressionOperator op = indexingBeginningMatch.Length == 2 ? ExpressionOperator.IndexingWithNullConditional : ExpressionOperator.Indexing;
16421643
dynamic left = stack.Pop();
16431644

1644-
stack.Push(operatorsEvaluations[0][op](left, right));
1645+
Match assignationOperatorMatch;
1646+
1647+
object valueToPush = null;
1648+
1649+
if ((assignationOperatorMatch = assignationOperatorRegex.Match(expr.Substring(i + 1))).Success)
1650+
{
1651+
i += assignationOperatorMatch.Length + 1;
1652+
1653+
if (stack.Count > 1)
1654+
throw new ExpressionEvaluatorSyntaxErrorException("The left part of an assignation must be a variable, a property or an indexer.");
1655+
1656+
string rightExpression = expr.Substring(i);
1657+
i = expr.Length;
1658+
1659+
if (op == ExpressionOperator.IndexingWithNullConditional)
1660+
throw new ExpressionEvaluatorSyntaxErrorException("Null coalescing is not usable left to an assignation");
1661+
1662+
if (rightExpression.Trim().Equals(string.Empty))
1663+
throw new ExpressionEvaluatorSyntaxErrorException("Right part is missing in assignation");
1664+
1665+
if (assignationOperatorMatch.Groups["assignmentPrefix"].Success)
1666+
{
1667+
ExpressionOperator prefixOp = operatorsDictionary[assignationOperatorMatch.Groups["assignmentPrefix"].Value];
1668+
1669+
valueToPush = operatorsEvaluations[0][op](left, right);
1670+
1671+
valueToPush = operatorsEvaluations.Find(dict => dict.ContainsKey(prefixOp))[prefixOp](valueToPush, Evaluate(rightExpression));
1672+
}
1673+
else
1674+
{
1675+
valueToPush = Evaluate(rightExpression);
1676+
}
1677+
1678+
left[right] = valueToPush;
1679+
1680+
stack.Clear();
1681+
}
1682+
else
1683+
{
1684+
valueToPush = operatorsEvaluations[0][op](left, right);
1685+
}
1686+
1687+
stack.Push(valueToPush);
16451688

16461689
return true;
1690+
16471691
}
16481692

16491693
return false;

0 commit comments

Comments
 (0)