Skip to content

Commit 1a0d36e

Browse files
authored
Merge pull request #2 from rameel/cleanup
Clean up and formatting
2 parents d77289b + e0628eb commit 1a0d36e

File tree

15 files changed

+575
-241
lines changed

15 files changed

+575
-241
lines changed

src/Ramstack.ExpressionParser/Binder.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ public abstract class Binder
1818
/// </summary>
1919
/// <param name="name">The <see cref="Identifier"/> representing the name of the requested type.</param>
2020
/// <returns>
21-
/// The <see cref="Type"/> instance corresponding to the specified <paramref name="name"/>
21+
/// The <see cref="Type"/> instance corresponding to the specified <paramref name="name"/>
2222
/// if resolved successfully; otherwise, <see langword="null"/>.
2323
/// </returns>
2424
public abstract Type? BindToType(Identifier name);

src/Ramstack.ExpressionParser/DefaultBinder.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,9 @@ public void RegisterType(Type type, bool importAsStatic = false)
128128
/// <inheritdoc />
129129
public override MemberInfo? BindToMember(Type? type, Identifier memberName, bool isStatic)
130130
{
131-
var bindingFlags = BindingFlags.Public | (isStatic ? BindingFlags.Static : BindingFlags.Instance);
131+
var bindingFlags = isStatic
132+
? BindingFlags.Public | BindingFlags.Static
133+
: BindingFlags.Public | BindingFlags.Instance;
132134

133135
var q = type?.GetMembers(bindingFlags)
134136
?? PredefinedType
@@ -158,8 +160,9 @@ private static IEnumerable<MethodBase> GetMethods(Type type, string methodName,
158160
? BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Static
159161
: BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Instance;
160162

161-
return type.GetMethods(bindingFlags)
162-
.Where(m => StringComparer.OrdinalIgnoreCase.Equals(m.Name, methodName))
163+
return type
164+
.GetMethods(bindingFlags)
165+
.Where(m => string.Equals(m.Name, methodName, StringComparison.OrdinalIgnoreCase))
163166
.Distinct();
164167
}
165168
}

src/Ramstack.ExpressionParser/ExpressionBuilder.Helpers.cs

Lines changed: 49 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,14 @@ private static List<Expression> CreateInjectingArguments(MethodInfo method, IRea
7171
var paramArrayType = parameter.ParameterType.GetElementType()!;
7272

7373
for (; i < args.Count; i++)
74-
paramArray.Add(Convert(args[i], paramArrayType));
74+
paramArray.Add(
75+
Convert(args[i], paramArrayType));
76+
77+
list.Add(
78+
Expression.NewArrayInit(
79+
paramArrayType,
80+
paramArray));
7581

76-
list.Add(Expression.NewArrayInit(paramArrayType, paramArray));
7782
break;
7883
}
7984

@@ -112,10 +117,8 @@ private static Expression ApplyBinaryExpression(Identifier op, Func<Expression,
112117
if (enumUnderlyingType is not null)
113118
{
114119
if (lhs.Type != rhs.Type)
115-
{
116120
if (lhs.Type.IsEnum ? enumUnderlyingType != rhs.Type : enumUnderlyingType != lhs.Type)
117121
Error.NonApplicableBinaryOperator(op, lhs.Type, rhs.Type);
118-
}
119122

120123
if (lhs.Type.IsEnum)
121124
lhs = Expression.Convert(lhs, enumUnderlyingType);
@@ -128,35 +131,35 @@ private static Expression ApplyBinaryExpression(Identifier op, Func<Expression,
128131
{
129132
if (!TypeUtils.IsInteger(lhs.Type) && TypeUtils.IsInteger(rhs.Type))
130133
Error.NonApplicableBinaryOperator(op, lhs.Type, rhs.Type);
131-
134+
132135
if (rhs.Type == typeof(sbyte)
133136
|| rhs.Type == typeof(byte)
134137
|| rhs.Type == typeof(short)
135138
|| rhs.Type == typeof(ushort))
136139
rhs = Expression.Convert(rhs, typeof(int));
137-
140+
138141
if (rhs.Type != typeof(int))
139142
Error.NonApplicableBinaryOperator(op, lhs.Type, rhs.Type);
140-
143+
141144
if (lhs.Type == typeof(sbyte)
142145
|| lhs.Type == typeof(byte)
143146
|| lhs.Type == typeof(short)
144147
|| lhs.Type == typeof(ushort))
145148
lhs = Expression.Convert(lhs, typeof(int));
146-
149+
147150
if (op.Name == ">>>")
148151
{
149152
if (lhs.Type == typeof(int))
150153
return Expression.Convert(
151154
apply(Expression.Convert(lhs, typeof(uint)), rhs),
152155
typeof(int));
153-
156+
154157
if (lhs.Type == typeof(long))
155158
return Expression.Convert(
156159
apply(Expression.Convert(lhs, typeof(ulong)), rhs),
157160
typeof(long));
158161
}
159-
162+
160163
return apply(lhs, rhs);
161164
}
162165

@@ -183,12 +186,28 @@ private static Expression ApplyBinaryExpression(Identifier op, Func<Expression,
183186
return result;
184187
}
185188

186-
//
187-
// 12.4.7 Numeric promotions
188-
// https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/expressions#1247-numeric-promotions
189-
//
190189
private static void ApplyBinaryNumericPromotions(Identifier op, ref Expression lhs, ref Expression rhs)
191190
{
191+
//
192+
// 12.4.7.3 Binary numeric promotions
193+
// https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/expressions#12473-binary-numeric-promotions
194+
//
195+
// Binary numeric promotion implicitly converts both operands to a common type which,
196+
// in case of the non-relational operators, also becomes the result type of the operation.
197+
// Binary numeric promotion consists of applying the following rules, in the order they appear here:
198+
//
199+
// * If either operand is of type decimal, the other operand is converted to type decimal,
200+
// or a binding-time error occurs if the other operand is of type float or double.
201+
// * Otherwise, if either operand is of type double, the other operand is converted to type double.
202+
// * Otherwise, if either operand is of type float, the other operand is converted to type float.
203+
// * Otherwise, if either operand is of type ulong, the other operand is converted to type ulong,
204+
// or a binding-time error occurs if the other operand is of type sbyte, short, int, or long.
205+
// * Otherwise, if either operand is of type long, the other operand is converted to type long.
206+
// * Otherwise, if either operand is of type uint and the other operand is of type sbyte, short, or int,
207+
// both operands are converted to type long.
208+
// * Otherwise, if either operand is of type uint, the other operand is converted to type uint.
209+
// * Otherwise, both operands are converted to type int.
210+
192211
var lhsType = lhs.Type;
193212
var rhsType = rhs.Type;
194213

@@ -218,8 +237,10 @@ private static void ApplyBinaryNumericPromotions(Identifier op, ref Expression l
218237

219238
if (conversionType == typeof(decimal))
220239
{
240+
//
221241
// If either operand is of type decimal, the other operand is converted to type decimal,
222242
// or a compile-time error occurs if the other operand is of type float or double.
243+
//
223244
if (lhsType == typeof(double)
224245
|| lhsType == typeof(float)
225246
|| rhsType == typeof(double)
@@ -228,8 +249,10 @@ private static void ApplyBinaryNumericPromotions(Identifier op, ref Expression l
228249
}
229250
else if (conversionType == typeof(ulong))
230251
{
231-
// if either operand is of type ulong, the other operand is converted to type ulong,
252+
//
253+
// If either operand is of type ulong, the other operand is converted to type ulong,
232254
// or a compile-time error occurs if the other operand is of type sbyte, short, int, or long.
255+
//
233256
if (lhsType == typeof(sbyte)
234257
|| lhsType == typeof(short)
235258
|| lhsType == typeof(int)
@@ -242,8 +265,10 @@ private static void ApplyBinaryNumericPromotions(Identifier op, ref Expression l
242265
}
243266
else if (conversionType == typeof(uint))
244267
{
245-
// if either operand is of type uint and the other operand is of type sbyte, short, or int,
268+
//
269+
// If either operand is of type uint and the other operand is of type sbyte, short, or int,
246270
// both operands are converted to type long.
271+
//
247272
if (lhsType == typeof(sbyte)
248273
|| lhsType == typeof(short)
249274
|| lhsType == typeof(int)
@@ -263,25 +288,25 @@ private static void ApplyBinaryNumericPromotions(Identifier op, ref Expression l
263288
}
264289
}
265290

266-
private static Func<Expression, Expression, Expression> CreateOperatorFactory(string @operator)
291+
private static Func<Expression, Expression, Expression> ResolveBinaryOperatorFactory(string @operator)
267292
{
268293
return @operator switch
269294
{
270295
"??" => Expression.Coalesce,
271-
"||" => Expression.OrElse,
272296
"&&" => Expression.AndAlso,
273-
"|" => Expression.Or,
274-
"^" => Expression.ExclusiveOr,
275-
"&" => Expression.And,
297+
"||" => Expression.OrElse,
276298
"==" => Expression.Equal,
277299
"!=" => Expression.NotEqual,
278300
"<=" => Expression.LessThanOrEqual,
279-
"<" => Expression.LessThan,
280301
">=" => Expression.GreaterThanOrEqual,
281-
">" => Expression.GreaterThan,
282302
">>" => Expression.RightShift,
283-
">>>" => Expression.RightShift,
284303
"<<" => Expression.LeftShift,
304+
">>>" => Expression.RightShift,
305+
"<" => Expression.LessThan,
306+
">" => Expression.GreaterThan,
307+
"&" => Expression.And,
308+
"|" => Expression.Or,
309+
"^" => Expression.ExclusiveOr,
285310
"+" => Expression.Add,
286311
"-" => Expression.Subtract,
287312
"*" => Expression.Multiply,

src/Ramstack.ExpressionParser/ExpressionBuilder.cs

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -37,38 +37,38 @@ protected internal override Expression VisitBinary(Expr.Binary expr)
3737
var lhs = Visit(expr.Left);
3838
var rhs = Visit(expr.Right);
3939

40-
var factory = CreateOperatorFactory(expr.Operator.Name);
40+
var lhsType = lhs.Type;
41+
var rhsType = rhs.Type;
4142

42-
var l = lhs;
43-
var r = rhs;
43+
var factory = ResolveBinaryOperatorFactory(expr.Operator.Name);
4444

4545
switch (expr.Operator.Name)
4646
{
4747
case "&&":
4848
case "||":
49-
l = ApplyImplicitConversion(lhs, typeof(bool));
50-
r = ApplyImplicitConversion(rhs, typeof(bool));
49+
lhs = ApplyImplicitConversion(lhs, typeof(bool));
50+
rhs = ApplyImplicitConversion(rhs, typeof(bool));
5151

52-
if (l is null)
53-
Error.MissingImplicitConversion(lhs.Type, typeof(bool));
52+
if (lhs is null)
53+
Error.MissingImplicitConversion(lhsType, typeof(bool));
5454

55-
if (r is null)
56-
Error.MissingImplicitConversion(rhs.Type, typeof(bool));
55+
if (rhs is null)
56+
Error.MissingImplicitConversion(rhsType, typeof(bool));
5757

5858
break;
5959

6060
case "??":
61-
if (lhs.Type.IsValueType && !lhs.Type.IsNullable())
62-
Error.NonApplicableBinaryOperator(expr.Operator, lhs.Type, rhs.Type);
61+
if (lhsType.IsValueType && !lhsType.IsNullable())
62+
Error.NonApplicableBinaryOperator(expr.Operator, lhsType, rhsType);
6363

64-
r = ApplyImplicitConversion(rhs, lhs.Type);
65-
if (r is null)
66-
Error.NonApplicableBinaryOperator(expr.Operator, lhs.Type, rhs.Type);
64+
rhs = ApplyImplicitConversion(rhs, lhsType);
65+
if (rhs is null)
66+
Error.NonApplicableBinaryOperator(expr.Operator, lhsType, rhsType);
6767

6868
break;
6969

7070
case "+":
71-
if (lhs.Type != typeof(string) && rhs.Type != typeof(string))
71+
if (lhsType != typeof(string) && rhsType != typeof(string))
7272
break;
7373

7474
var arguments = new List<Expression>();
@@ -137,11 +137,11 @@ void Flatten(Expression e)
137137

138138
try
139139
{
140-
return ApplyBinaryExpression(expr.Operator, factory, l, r);
140+
return ApplyBinaryExpression(expr.Operator, factory, lhs, rhs);
141141
}
142142
catch (Exception e) when (e is not ParseErrorException)
143143
{
144-
Error.NonApplicableBinaryOperator(expr.Operator, lhs.Type, rhs.Type);
144+
Error.NonApplicableBinaryOperator(expr.Operator, lhsType, rhsType);
145145
}
146146

147147
return null!;

src/Ramstack.ExpressionParser/ExpressionParser.Parser.cs

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ private static Parser<Expr> CreateParser()
4242
).Void();
4343

4444
var number_literal =
45-
ConstantNumberParser.NumericLiteral
45+
ConstantNumberParser
46+
.NumericLiteral
4647
.Do(Expr (v) => new Expr.Literal(v));
4748

4849
var string_literal =
@@ -187,57 +188,57 @@ static Expr HijackMemberExpression(Expr result, Expr value)
187188

188189
var mul_expression =
189190
prefix_expression.Fold(
190-
OneOf("*/%").ThenIgnore(S).Map(CreateIdentifier),
191+
OneOf("*/%").ThenIgnore(S).Do(CreateIdentifier),
191192
(lhs, rhs, op) => new Expr.Binary(op, lhs, rhs));
192193

193194
var add_expression =
194195
mul_expression.Fold(
195-
OneOf("+-").ThenIgnore(S).Map(CreateIdentifier),
196+
OneOf("+-").ThenIgnore(S).Do(CreateIdentifier),
196197
(lhs, rhs, op) => new Expr.Binary(op, lhs, rhs));
197198

198199
var shift_expression =
199200
add_expression.Fold(
200-
OneOf(["<<", ">>", ">>>"]).ThenIgnore(S).Map(CreateIdentifier),
201+
OneOf(["<<", ">>", ">>>"]).ThenIgnore(S).Do(CreateIdentifier),
201202
(lhs, rhs, op) => new Expr.Binary(op, lhs, rhs));
202203

203204
var relational_expression =
204205
shift_expression.Fold(
205-
OneOf(["<", ">", "<=", ">="]).ThenIgnore(S).Map(CreateIdentifier),
206+
OneOf(["<", ">", "<=", ">="]).ThenIgnore(S).Do(CreateIdentifier),
206207
(lhs, rhs, op) => new Expr.Binary(op, lhs, rhs));
207208

208209
var equality_expression =
209210
relational_expression.Fold(
210-
OneOf("==", "!=").ThenIgnore(S).Map(CreateIdentifier),
211+
OneOf("==", "!=").ThenIgnore(S).Do(CreateIdentifier),
211212
(lhs, rhs, op) => new Expr.Binary(op, lhs, rhs));
212213

213214
var bitwise_and_expression =
214215
equality_expression.Fold(
215-
L('&').ThenIgnore(S).Map(CreateIdentifier),
216+
L('&').ThenIgnore(S).Do(CreateIdentifier),
216217
(lhs, rhs, op) => new Expr.Binary(op, lhs, rhs));
217218

218219
var bitwise_xor_expression =
219220
bitwise_and_expression.Fold(
220-
L('^').ThenIgnore(S).Map(CreateIdentifier),
221+
L('^').ThenIgnore(S).Do(CreateIdentifier),
221222
(lhs, rhs, op) => new Expr.Binary(op, lhs, rhs));
222223

223224
var bitwise_or_expression =
224225
bitwise_xor_expression.Fold(
225-
L('|').ThenIgnore(S).Map(CreateIdentifier),
226+
L('|').ThenIgnore(S).Do(CreateIdentifier),
226227
(lhs, rhs, op) => new Expr.Binary(op, lhs, rhs));
227228

228229
var logical_and_expression =
229230
bitwise_or_expression.Fold(
230-
L("&&").ThenIgnore(S).Map(CreateIdentifier),
231+
L("&&").ThenIgnore(S).Do(CreateIdentifier),
231232
(lhs, rhs, op) => new Expr.Binary(op, lhs, rhs));
232233

233234
var logical_or_expression =
234235
logical_and_expression.Fold(
235-
L("||").ThenIgnore(S).Map(CreateIdentifier),
236+
L("||").ThenIgnore(S).Do(CreateIdentifier),
236237
(lhs, rhs, op) => new Expr.Binary(op, lhs, rhs));
237238

238239
var null_coalesce_expression =
239240
logical_or_expression.FoldR(
240-
L("??").ThenIgnore(S).Map(CreateIdentifier),
241+
L("??").ThenIgnore(S).Do(CreateIdentifier),
241242
(lhs, rhs, op) => new Expr.Binary(op, lhs, rhs));
242243

243244
var conditional_expression = Deferred<Expr>();
@@ -261,9 +262,9 @@ static Expr HijackMemberExpression(Expr result, Expr value)
261262
return S.Then(expression);
262263
}
263264

264-
private static Identifier CreateIdentifier(Match m, string v) =>
265-
new(v);
265+
private static Identifier CreateIdentifier(string v) =>
266+
new Identifier(v);
266267

267-
private static Identifier CreateIdentifier(Match m, char v) =>
268-
new(new string(v, 1));
268+
private static Identifier CreateIdentifier(char v) =>
269+
new Identifier(v.ToString());
269270
}

src/Ramstack.ExpressionParser/Expressions/Expr.Unary.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ namespace Ramstack.Parsing.Expressions;
33
partial class Expr
44
{
55
/// <summary>
6-
/// Represents an unary operation expression in an expression tree, consisting of an operator and a single operand.
6+
/// Represents a unary operation expression in an expression tree, consisting of an operator and a single operand.
77
/// </summary>
88
/// <param name="operator">The <see cref="Identifier"/> representing the unary operator, e.g., <c>"-"</c> or <c>"int"</c>.</param>
99
/// <param name="unaryType">The <see cref="UnaryType"/> specifying the kind of unary operation (e.g., arithmetic or conversion).</param>

0 commit comments

Comments
 (0)