Skip to content

Commit 7a674a7

Browse files
Merge pull request #37 from delegateas/thygesteffensen/async
Thygesteffensen/async
2 parents d343b07 + 19644a9 commit 7a674a7

60 files changed

Lines changed: 826 additions & 648 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1-
namespace ExpressionEngine
1+
using System.Threading.Tasks;
2+
3+
namespace ExpressionEngine
24
{
35
public interface IExpressionEngine
46
{
5-
string Parse(string input);
6-
ValueContainer ParseToValueContainer(string input);
7+
ValueTask<string> Parse(string input);
8+
ValueTask<ValueContainer> ParseToValueContainer(string input);
79
}
810

911
public class ExpressionEngine : IExpressionEngine
@@ -15,14 +17,14 @@ public ExpressionEngine(ExpressionGrammar grammar)
1517
_expressionGrammar = grammar;
1618
}
1719

18-
public string Parse(string input)
20+
public async ValueTask<string> Parse(string input)
1921
{
20-
return _expressionGrammar.EvaluateToString(input);
22+
return await _expressionGrammar.EvaluateToString(input);
2123
}
2224

23-
public ValueContainer ParseToValueContainer(string input)
25+
public async ValueTask<ValueContainer> ParseToValueContainer(string input)
2426
{
25-
return _expressionGrammar.EvaluateToValueContainer(input);
27+
return await _expressionGrammar.EvaluateToValueContainer(input);
2628
}
2729
}
2830
}

ExpressionEngine/ExpressionGrammar.cs

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Threading.Tasks;
35
using ExpressionEngine.Functions.Base;
46
using ExpressionEngine.Rules;
57
using Sprache;
@@ -9,7 +11,7 @@ namespace ExpressionEngine
911
public class ExpressionGrammar
1012
{
1113
private readonly Parser<IRule> _method;
12-
private readonly Parser<ValueContainer> _input;
14+
private readonly Parser<ValueTask<ValueContainer>> _input;
1315

1416
public ExpressionGrammar(IEnumerable<IFunction> functions)
1517
{
@@ -93,15 +95,15 @@ from args in arguments.Contained(lParenthesis, rParenthesis)
9395
Parse.Ref(() =>
9496
from func in function
9597
from indexes in bracketIndices.Or(dotIndices).Many()
96-
select (IRule) new AccessValueRule(func, indexes));
98+
select indexes.Aggregate(func,(acc, next) => new AccessValueRule(acc, next)));
9799

98-
Parser<ValueContainer> enclosedExpression =
100+
Parser<ValueTask<ValueContainer>> enclosedExpression =
99101
_method.Contained(
100102
Parse.String("@{"),
101103
Parse.Char('}'))
102104
.Select(x => x.Evaluate());
103105

104-
Parser<ValueContainer> expression =
106+
Parser<ValueTask<ValueContainer>> expression =
105107
from at in Parse.Char('@')
106108
from method in _method
107109
select method.Evaluate();
@@ -110,32 +112,32 @@ from method in _method
110112
from t in simpleString.Or(allowedCharacters).Many()
111113
select string.Concat(t);
112114

113-
Parser<ValueContainer> joinedString =
115+
Parser<ValueTask<ValueContainer>> joinedString =
114116
from e in (
115117
from preFix in allowedString
116118
from exp in enclosedExpression.Optional()
117119
select exp.IsEmpty ? preFix : preFix + exp.Get())
118120
.Many()
119-
select new ValueContainer(string.Concat(e));
121+
select new ValueTask<ValueContainer>(new ValueContainer(string.Concat(e)));
120122

121-
Parser<ValueContainer> charPrefixedString =
123+
Parser<ValueTask<ValueContainer>> charPrefixedString =
122124
from at in Parse.Char('@')
123125
from str in Parse.LetterOrDigit.Many().Text().Except(Parse.Chars('{', '@'))
124-
select new ValueContainer(str);
126+
select new ValueTask<ValueContainer>(new ValueContainer(str));
125127

126128
_input = expression.Or(charPrefixedString).Or(joinedString);
127129
}
128130

129-
public string EvaluateToString(string input)
131+
public async ValueTask<string> EvaluateToString(string input)
130132
{
131-
var output = _input.Parse(input);
133+
var output = await _input.Parse(input);
132134

133135
return output.GetValue<string>();
134136
}
135137

136-
public ValueContainer EvaluateToValueContainer(string input)
138+
public async ValueTask<ValueContainer> EvaluateToValueContainer(string input)
137139
{
138-
return _input.Parse(input);
140+
return await _input.Parse(input);
139141
}
140142
}
141143
}

ExpressionEngine/Functions/Base/IFunction.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
using System;
2+
using System.Threading.Tasks;
23

34
namespace ExpressionEngine.Functions.Base
45
{
56
public interface IFunction
67
{
78
string FunctionName { get; }
8-
ValueContainer ExecuteFunction(ValueContainer[] strings);
9+
ValueTask<ValueContainer> ExecuteFunction(ValueContainer[] strings);
910
}
1011

1112
public abstract class Function : IFunction
@@ -17,6 +18,6 @@ protected Function(string functionName)
1718
FunctionName = functionName ?? throw new ArgumentNullException(nameof(functionName));
1819
}
1920

20-
public abstract ValueContainer ExecuteFunction(params ValueContainer[] parameters);
21+
public abstract ValueTask<ValueContainer> ExecuteFunction(params ValueContainer[] parameters);
2122
}
2223
}

ExpressionEngine/Functions/Implementations/CollectionFunctions/ContainsFunction.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Linq;
4+
using System.Threading.Tasks;
45
using ExpressionEngine.Functions.Base;
56

67
namespace ExpressionEngine.Functions.Implementations.CollectionFunctions
@@ -11,7 +12,7 @@ public ContainsFunction() : base("contains")
1112
{
1213
}
1314

14-
public override ValueContainer ExecuteFunction(params ValueContainer[] parameters)
15+
public override ValueTask<ValueContainer> ExecuteFunction(params ValueContainer[] parameters)
1516
{
1617
var collection = parameters[0];
1718
var value = parameters[1];
@@ -28,20 +29,20 @@ public override ValueContainer ExecuteFunction(params ValueContainer[] parameter
2829
case ValueContainer.ValueType.String:
2930
case ValueContainer.ValueType.Boolean:
3031
case ValueContainer.ValueType.Null:
31-
return new ValueContainer(array.Contains(value));
32+
return new ValueTask<ValueContainer>(new ValueContainer(array.Contains(value)));
3233
case ValueContainer.ValueType.Array:
3334
case ValueContainer.ValueType.Object:
34-
return new ValueContainer(false);
35+
return new ValueTask<ValueContainer>(new ValueContainer(false));
3536
default:
3637
throw new ArgumentOutOfRangeException();
3738
}
3839
case ValueContainer.ValueType.Object:
3940
var key = value.GetValue<string>();
40-
return new ValueContainer(collection.AsDict().ContainsKey(key));
41+
return new ValueTask<ValueContainer>(new ValueContainer(collection.AsDict().ContainsKey(key)));
4142
case ValueContainer.ValueType.String:
4243
var text = collection.GetValue<string>();
4344
var substring = value.GetValue<string>();
44-
return new ValueContainer(text.Contains(substring));
45+
return new ValueTask<ValueContainer>(new ValueContainer(text.Contains(substring)));
4546
default:
4647
throw new PowerAutomateMockUpException($"Cannot perform contains on {collection.Type()}.");
4748
}

ExpressionEngine/Functions/Implementations/CollectionFunctions/EmptyFunction.cs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.Collections.Generic;
22
using System.Linq;
3+
using System.Threading.Tasks;
34
using ExpressionEngine.Functions.Base;
45

56
namespace ExpressionEngine.Functions.Implementations.CollectionFunctions
@@ -10,18 +11,19 @@ public EmptyFunction() : base("empty")
1011
{
1112
}
1213

13-
public override ValueContainer ExecuteFunction(params ValueContainer[] parameters)
14+
public override ValueTask<ValueContainer> ExecuteFunction(params ValueContainer[] parameters)
1415
{
1516
var value = parameters[0];
1617

1718
return value.Type() switch
1819
{
19-
ValueContainer.ValueType.String => new ValueContainer(string.IsNullOrEmpty(value.GetValue<string>())),
20-
ValueContainer.ValueType.Array => new ValueContainer(
21-
!value.GetValue<IEnumerable<ValueContainer>>().Any()),
22-
ValueContainer.ValueType.Object => new ValueContainer(
23-
value.GetValue<Dictionary<string, ValueContainer>>().Count == 0),
24-
ValueContainer.ValueType.Null => new ValueContainer(true),
20+
ValueContainer.ValueType.String => new ValueTask<ValueContainer>(
21+
new ValueContainer(string.IsNullOrEmpty(value.GetValue<string>()))),
22+
ValueContainer.ValueType.Array => new ValueTask<ValueContainer>(new ValueContainer(
23+
!value.GetValue<IEnumerable<ValueContainer>>().Any())),
24+
ValueContainer.ValueType.Object => new ValueTask<ValueContainer>(new ValueContainer(
25+
value.GetValue<Dictionary<string, ValueContainer>>().Count == 0)),
26+
ValueContainer.ValueType.Null => new ValueTask<ValueContainer>(new ValueContainer(true)),
2527
_ => throw new PowerAutomateMockUpException(
2628
$"Empty expression can only operate on String, Array or Object types, not {value.Type()}.")
2729
};

ExpressionEngine/Functions/Implementations/CollectionFunctions/FirstFunction.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.Collections.Generic;
22
using System.Linq;
3+
using System.Threading.Tasks;
34
using ExpressionEngine.Functions.Base;
45

56
namespace ExpressionEngine.Functions.Implementations.CollectionFunctions
@@ -10,16 +11,16 @@ public FirstFunction() : base("first")
1011
{
1112
}
1213

13-
public override ValueContainer ExecuteFunction(params ValueContainer[] parameters)
14+
public override ValueTask<ValueContainer> ExecuteFunction(params ValueContainer[] parameters)
1415
{
1516
var value = parameters[0];
1617

1718
return value.Type() switch
1819
{
19-
ValueContainer.ValueType.String => new ValueContainer(
20-
value.GetValue<string>().Substring(0, 1)),
21-
ValueContainer.ValueType.Array => new ValueContainer(
22-
value.GetValue<IEnumerable<ValueContainer>>().First()),
20+
ValueContainer.ValueType.String => new ValueTask<ValueContainer>(new ValueContainer(
21+
value.GetValue<string>().Substring(0, 1))),
22+
ValueContainer.ValueType.Array => new ValueTask<ValueContainer>(new ValueContainer(
23+
value.GetValue<IEnumerable<ValueContainer>>().First())),
2324
_ => throw new PowerAutomateMockUpException(
2425
$"Empty expression can only operate on String or Array types, not {value.Type()}.")
2526
};

ExpressionEngine/Functions/Implementations/CollectionFunctions/IntersectionFunction.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.Collections.Generic;
22
using System.Linq;
3+
using System.Threading.Tasks;
34
using ExpressionEngine.Functions.Base;
45

56
namespace ExpressionEngine.Functions.Implementations.CollectionFunctions
@@ -10,7 +11,7 @@ public InterSectionFunction() : base("intersection")
1011
{
1112
}
1213

13-
public override ValueContainer ExecuteFunction(params ValueContainer[] parameters)
14+
public override ValueTask<ValueContainer> ExecuteFunction(params ValueContainer[] parameters)
1415
{
1516
return parameters[0].Type() switch
1617
{
@@ -21,11 +22,11 @@ public override ValueContainer ExecuteFunction(params ValueContainer[] parameter
2122
};
2223
}
2324

24-
private ValueContainer IntersectDict(IReadOnlyList<ValueContainer> parameters)
25+
private ValueTask<ValueContainer> IntersectDict(IReadOnlyList<ValueContainer> parameters)
2526
{
2627
var first = parameters[0].GetValue<Dictionary<string, ValueContainer>>();
2728

28-
return new ValueContainer(parameters.Skip(1).Aggregate(first, ToDictionary));
29+
return new ValueTask<ValueContainer>(new ValueContainer(parameters.Skip(1).Aggregate(first, ToDictionary)));
2930
}
3031

3132
private Dictionary<string, ValueContainer> ToDictionary(Dictionary<string, ValueContainer> first,
@@ -37,15 +38,15 @@ private Dictionary<string, ValueContainer> ToDictionary(Dictionary<string, Value
3738
.ToDictionary(x => x.Key, x => second[x.Key]);
3839
}
3940

40-
private ValueContainer IntersectList(IReadOnlyList<ValueContainer> parameters)
41+
private ValueTask<ValueContainer> IntersectList(IReadOnlyList<ValueContainer> parameters)
4142
{
4243
var first = parameters[0].GetValue<IEnumerable<ValueContainer>>();
4344

4445
var intersection = parameters.Skip(1)
4546
.Select(valueContainer => valueContainer.GetValue<IEnumerable<ValueContainer>>())
4647
.Aggregate(first, (current, collection) => current.Intersect(collection));
4748

48-
return new ValueContainer(intersection);
49+
return new ValueTask<ValueContainer>(new ValueContainer(intersection));
4950
}
5051
}
5152
}
Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.Collections.Generic;
22
using System.Linq;
3+
using System.Threading.Tasks;
34
using ExpressionEngine.Functions.Base;
45

56
namespace ExpressionEngine.Functions.Implementations.CollectionFunctions
@@ -10,13 +11,13 @@ public JoinFunction() : base("join")
1011
{
1112
}
1213

13-
public override ValueContainer ExecuteFunction(params ValueContainer[] parameters)
14+
public override ValueTask<ValueContainer> ExecuteFunction(params ValueContainer[] parameters)
1415
{
1516
var collection = parameters[0].GetValue<IEnumerable<ValueContainer>>();
1617
var delimiter = parameters[1].GetValue<string>();
1718

18-
return new ValueContainer(collection.Skip(1)
19-
.Aggregate(collection.First().ToString(), (s, currentVc) => s + delimiter + currentVc));
19+
return new ValueTask<ValueContainer>(new ValueContainer(collection.Skip(1)
20+
.Aggregate(collection.First().ToString(), (s, currentVc) => s + delimiter + currentVc)));
2021
}
2122
}
2223
}

ExpressionEngine/Functions/Implementations/CollectionFunctions/LastFunction.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.Collections.Generic;
22
using System.Linq;
3+
using System.Threading.Tasks;
34
using ExpressionEngine.Functions.Base;
45

56
namespace ExpressionEngine.Functions.Implementations.CollectionFunctions
@@ -10,16 +11,16 @@ public LastFunction() : base("last")
1011
{
1112
}
1213

13-
public override ValueContainer ExecuteFunction(params ValueContainer[] parameters)
14+
public override ValueTask<ValueContainer> ExecuteFunction(params ValueContainer[] parameters)
1415
{
1516
var value = parameters[0];
1617

1718
return value.Type() switch
1819
{
19-
ValueContainer.ValueType.String => new ValueContainer(
20-
value.GetValue<string>().ToCharArray().Last().ToString()),
21-
ValueContainer.ValueType.Array => new ValueContainer(
22-
value.GetValue<IEnumerable<ValueContainer>>().Last()),
20+
ValueContainer.ValueType.String => new ValueTask<ValueContainer>(new ValueContainer(
21+
value.GetValue<string>().ToCharArray().Last().ToString())),
22+
ValueContainer.ValueType.Array => new ValueTask<ValueContainer>(new ValueContainer(
23+
value.GetValue<IEnumerable<ValueContainer>>().Last())),
2324
_ => throw new PowerAutomateMockUpException(
2425
$"Empty expression can only operate on String or Array types, not {value.Type()}.")
2526
};

ExpressionEngine/Functions/Implementations/CollectionFunctions/SkipFunction.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.Collections.Generic;
22
using System.Linq;
3+
using System.Threading.Tasks;
34
using ExpressionEngine.Functions.Base;
45

56
namespace ExpressionEngine.Functions.Implementations.CollectionFunctions
@@ -10,15 +11,15 @@ public SkipFunction() : base("skip")
1011
{
1112
}
1213

13-
public override ValueContainer ExecuteFunction(params ValueContainer[] parameters)
14+
public override ValueTask<ValueContainer> ExecuteFunction(params ValueContainer[] parameters)
1415
{
1516
var value = parameters[0];
1617
var count = parameters[1].GetValue<int>();
1718

1819
return value.Type() switch
1920
{
20-
ValueContainer.ValueType.Array => new ValueContainer(
21-
value.GetValue<IEnumerable<ValueContainer>>().Skip(count)),
21+
ValueContainer.ValueType.Array => new ValueTask<ValueContainer>(new ValueContainer(
22+
value.GetValue<IEnumerable<ValueContainer>>().Skip(count))),
2223
_ => throw new PowerAutomateMockUpException(
2324
$"Empty expression can only operate on String or Array types, not {value.Type()}.")
2425
};

0 commit comments

Comments
 (0)