Skip to content

Commit 2627145

Browse files
committed
Moved nested Expression types to their own files.
1 parent 5118883 commit 2627145

17 files changed

Lines changed: 249 additions & 231 deletions
Lines changed: 2 additions & 231 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using SqlServerSimulator.Parser.Tokens;
1+
using SqlServerSimulator.Parser.Expressions;
2+
using SqlServerSimulator.Parser.Tokens;
23

34
namespace SqlServerSimulator.Parser;
45

@@ -150,20 +151,6 @@ public static Expression Parse(ParserContext context)
150151
public abstract override string ToString();
151152
#endif
152153

153-
/// <summary>
154-
/// An expression that's wrapped in parentheses, potentially affecting the order of operations.
155-
/// </summary>
156-
private sealed class Parenthesized(Expression wrapped) : Expression
157-
{
158-
private readonly Expression wrapped = wrapped;
159-
160-
public override DataValue Run(Func<List<string>, DataValue> getColumnValue) => wrapped.Run(getColumnValue);
161-
162-
#if DEBUG
163-
public override string ToString() => $"( {wrapped} )";
164-
#endif
165-
}
166-
167154
private static Expression ResolveBuiltIn(string name, ParserContext context)
168155
{
169156
Span<char> uppercaseName = stackalloc char[name.Length];
@@ -182,220 +169,4 @@ private static Expression ResolveBuiltIn(string name, ParserContext context)
182169
_ => (Expression?)null
183170
} ?? throw SimulatedSqlException.UnrecognizedBuiltInFunction(name);
184171
}
185-
186-
/// <summary>
187-
/// An expression that has been given a name, such as with `as`.
188-
/// </summary>
189-
/// <param name="expression">The expression to be named.</param>
190-
/// <param name="name">The name of the expression, exposed via the <see cref="Name"/> property.</param>
191-
private sealed class NamedExpression(Expression expression, string name) : Expression
192-
{
193-
private readonly Expression expression = expression;
194-
private readonly string name = name;
195-
196-
public override string Name => this.name;
197-
198-
public override byte Precedence => expression.Precedence;
199-
200-
public override DataValue Run(Func<List<string>, DataValue> getColumnValue) => this.expression.Run(getColumnValue);
201-
202-
#if DEBUG
203-
public override string ToString() => $"{expression} {name}";
204-
#endif
205-
}
206-
207-
/// <summary>
208-
/// Values are resolved at parse time.
209-
/// </summary>
210-
private sealed class Value : Expression
211-
{
212-
private readonly DataValue value;
213-
214-
public Value()
215-
{
216-
}
217-
218-
public Value(DataValue value) => this.value = value;
219-
220-
public Value(AtPrefixedString atPrefixed, ParserContext context)
221-
{
222-
this.value = context.GetVariableValue(atPrefixed.Value);
223-
}
224-
225-
public Value(DoubleAtPrefixedString doubleAtPrefixedString)
226-
{
227-
switch (doubleAtPrefixedString.Parse())
228-
{
229-
case AtAtKeyword.Version:
230-
this.value = new("SQL Server Simulator", DataType.BuiltInDbString);
231-
return;
232-
}
233-
234-
throw new NotSupportedException($"Simulator doesn't recognize {doubleAtPrefixedString}.");
235-
}
236-
237-
public override DataValue Run(Func<List<string>, DataValue> getColumnValue) => value;
238-
239-
#if DEBUG
240-
public override string ToString() => value.Value?.ToString() ?? "null";
241-
#endif
242-
}
243-
244-
private abstract class TwoSidedExpression(Expression left, Expression right) : Expression
245-
{
246-
private Expression right = right, left = left;
247-
248-
public TwoSidedExpression AdjustForPrecedence()
249-
{
250-
if (this.right is not TwoSidedExpression rightTwo || rightTwo.Precedence < this.Precedence)
251-
return this;
252-
253-
(rightTwo.left, this.right) = (this, rightTwo.left);
254-
return rightTwo;
255-
}
256-
257-
public sealed override DataValue Run(Func<List<string>, DataValue> getColumnValue)
258-
=> Run(left.Run(getColumnValue), right.Run(getColumnValue));
259-
260-
protected abstract DataValue Run(DataValue left, DataValue right);
261-
protected abstract char Operator { get; }
262-
263-
#if DEBUG
264-
public sealed override string ToString() => $"{left} {Operator} {right}";
265-
#endif
266-
}
267-
268-
private abstract class MathExpression(Expression left, Expression right) : TwoSidedExpression(left, right)
269-
{
270-
protected abstract DataValue Run(DataType.NumericCompatibleDataType common, DataValue left, DataValue right);
271-
272-
protected sealed override DataValue Run(DataValue left, DataValue right) => Run(DataType.CommonNumeric(left, right, this.Operator), left, right);
273-
}
274-
275-
private sealed class Add(Expression left, Expression right) : MathExpression(left, right)
276-
{
277-
public override byte Precedence => 3;
278-
279-
protected override DataValue Run(DataType.NumericCompatibleDataType common, DataValue left, DataValue right) => common.Add(left, right);
280-
281-
protected override char Operator => '+';
282-
}
283-
284-
private sealed class Subtract(Expression left, Expression right) : MathExpression(left, right)
285-
{
286-
public override byte Precedence => 3;
287-
288-
protected override DataValue Run(DataType.NumericCompatibleDataType common, DataValue left, DataValue right) => common.Subtract(left, right);
289-
290-
protected override char Operator => '-';
291-
}
292-
293-
private sealed class Multiply(Expression left, Expression right) : MathExpression(left, right)
294-
{
295-
public override byte Precedence => 2;
296-
297-
protected override DataValue Run(DataType.NumericCompatibleDataType common, DataValue left, DataValue right) => common.Multiply(left, right);
298-
299-
protected override char Operator => '*';
300-
}
301-
302-
private sealed class Divide(Expression left, Expression right) : MathExpression(left, right)
303-
{
304-
public override byte Precedence => 2;
305-
306-
protected override DataValue Run(DataType.NumericCompatibleDataType common, DataValue left, DataValue right) => common.Divide(left, right);
307-
308-
protected override char Operator => '/';
309-
}
310-
311-
private abstract class BitwiseExpression(Expression left, Expression right) : TwoSidedExpression(left, right)
312-
{
313-
protected abstract DataValue Run(DataType.BitwiseCompatibleDataType common, DataValue left, DataValue right);
314-
315-
protected sealed override DataValue Run(DataValue left, DataValue right) => Run(DataType.CommonInteger(left, right, this.Operator), left, right);
316-
}
317-
318-
private sealed class BitwiseAnd(Expression left, Expression right) : BitwiseExpression(left, right)
319-
{
320-
public override byte Precedence => 3;
321-
322-
protected override DataValue Run(DataType.BitwiseCompatibleDataType common, DataValue left, DataValue right) => common.BitwiseAnd(left, right);
323-
324-
protected override char Operator => '&';
325-
}
326-
327-
private sealed class BitwiseOr(Expression left, Expression right) : BitwiseExpression(left, right)
328-
{
329-
public override byte Precedence => 3;
330-
331-
protected override DataValue Run(DataType.BitwiseCompatibleDataType common, DataValue left, DataValue right) => common.BitwiseOr(left, right);
332-
333-
protected override char Operator => '|';
334-
}
335-
336-
private sealed class BitwiseExclusiveOr(Expression left, Expression right) : BitwiseExpression(left, right)
337-
{
338-
public override byte Precedence => 3;
339-
340-
protected override DataValue Run(DataType.BitwiseCompatibleDataType common, DataValue left, DataValue right) => common.BitwiseExclusiveOr(left, right);
341-
342-
protected override char Operator => '^';
343-
}
344-
345-
private sealed class Reference(Name name) : Expression
346-
{
347-
private readonly List<string> name = [name.Value];
348-
349-
public override string Name => this.name[^1];
350-
351-
public void AddMultiPartComponent(Name name) => this.name.Add(name.Value);
352-
353-
public override DataValue Run(Func<List<string>, DataValue> getColumnValue) => getColumnValue(this.name);
354-
355-
#if DEBUG
356-
public override string ToString() => string.Join('.', name);
357-
#endif
358-
}
359-
360-
/// <summary>
361-
/// Encapsulates the SQL DATALENGTH command: https://learn.microsoft.com/en-us/sql/t-sql/functions/datalength-transact-sql
362-
/// </summary>
363-
private sealed class DataLength(ParserContext context) : Expression
364-
{
365-
private readonly Expression source = Parse(context);
366-
367-
public override DataValue Run(Func<List<string>, DataValue> getColumnValue)
368-
{
369-
var value = source.Run(getColumnValue);
370-
return value.Value is null ? default : new(value.Type.DataLength(value));
371-
}
372-
373-
#if DEBUG
374-
public override string ToString() => $"DATALENGTH({source})";
375-
#endif
376-
}
377-
378-
/// <summary>
379-
/// Encapsulates the SQL ABS command: https://learn.microsoft.com/en-us/sql/t-sql/functions/abs-transact-sql
380-
/// </summary>
381-
private sealed class AbsoluteValue(ParserContext context) : Expression
382-
{
383-
private readonly Expression source = Parse(context);
384-
385-
public override DataValue Run(Func<List<string>, DataValue> getColumnValue)
386-
{
387-
var value = source.Run(getColumnValue);
388-
389-
return new(value.Value switch
390-
{
391-
null => value.Value,
392-
int v => Math.Abs(v),
393-
_ => throw new NotSupportedException($"Simulation unable to to run ABS function on the provided expression."),
394-
}, value.Type);
395-
}
396-
397-
#if DEBUG
398-
public override string ToString() => $"ABS({source})";
399-
#endif
400-
}
401172
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
namespace SqlServerSimulator.Parser.Expressions;
2+
3+
/// <summary>
4+
/// Encapsulates the SQL ABS command: https://learn.microsoft.com/en-us/sql/t-sql/functions/abs-transact-sql
5+
/// </summary>
6+
internal sealed class AbsoluteValue(ParserContext context) : Expression
7+
{
8+
private readonly Expression source = Parse(context);
9+
10+
public override DataValue Run(Func<List<string>, DataValue> getColumnValue)
11+
{
12+
var value = source.Run(getColumnValue);
13+
14+
return new(value.Value switch
15+
{
16+
null => value.Value,
17+
int v => Math.Abs(v),
18+
_ => throw new NotSupportedException($"Simulation unable to to run ABS function on the provided expression."),
19+
}, value.Type);
20+
}
21+
22+
#if DEBUG
23+
public override string ToString() => $"ABS({source})";
24+
#endif
25+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
namespace SqlServerSimulator.Parser.Expressions;
2+
3+
internal sealed class Add(Expression left, Expression right) : MathExpression(left, right)
4+
{
5+
public override byte Precedence => 3;
6+
7+
protected override DataValue Run(DataType.NumericCompatibleDataType common, DataValue left, DataValue right) => common.Add(left, right);
8+
9+
protected override char Operator => '+';
10+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
namespace SqlServerSimulator.Parser.Expressions;
2+
3+
internal sealed class BitwiseAnd(Expression left, Expression right) : BitwiseExpression(left, right)
4+
{
5+
public override byte Precedence => 3;
6+
7+
protected override DataValue Run(DataType.BitwiseCompatibleDataType common, DataValue left, DataValue right) => common.BitwiseAnd(left, right);
8+
9+
protected override char Operator => '&';
10+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
namespace SqlServerSimulator.Parser.Expressions;
2+
3+
internal sealed class BitwiseExclusiveOr(Expression left, Expression right) : BitwiseExpression(left, right)
4+
{
5+
public override byte Precedence => 3;
6+
7+
protected override DataValue Run(DataType.BitwiseCompatibleDataType common, DataValue left, DataValue right) => common.BitwiseExclusiveOr(left, right);
8+
9+
protected override char Operator => '^';
10+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
namespace SqlServerSimulator.Parser.Expressions;
2+
3+
internal abstract class BitwiseExpression(Expression left, Expression right) : TwoSidedExpression(left, right)
4+
{
5+
protected abstract DataValue Run(DataType.BitwiseCompatibleDataType common, DataValue left, DataValue right);
6+
7+
protected sealed override DataValue Run(DataValue left, DataValue right) => Run(DataType.CommonInteger(left, right, this.Operator), left, right);
8+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
namespace SqlServerSimulator.Parser.Expressions;
2+
3+
internal sealed class BitwiseOr(Expression left, Expression right) : BitwiseExpression(left, right)
4+
{
5+
public override byte Precedence => 3;
6+
7+
protected override DataValue Run(DataType.BitwiseCompatibleDataType common, DataValue left, DataValue right) => common.BitwiseOr(left, right);
8+
9+
protected override char Operator => '|';
10+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
namespace SqlServerSimulator.Parser.Expressions;
2+
3+
/// <summary>
4+
/// Encapsulates the SQL DATALENGTH command: https://learn.microsoft.com/en-us/sql/t-sql/functions/datalength-transact-sql
5+
/// </summary>
6+
internal sealed class DataLength(ParserContext context) : Expression
7+
{
8+
private readonly Expression source = Parse(context);
9+
10+
public override DataValue Run(Func<List<string>, DataValue> getColumnValue)
11+
{
12+
var value = source.Run(getColumnValue);
13+
return value.Value is null ? default : new(value.Type.DataLength(value));
14+
}
15+
16+
#if DEBUG
17+
public override string ToString() => $"DATALENGTH({source})";
18+
#endif
19+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
namespace SqlServerSimulator.Parser.Expressions;
2+
3+
internal sealed class Divide(Expression left, Expression right) : MathExpression(left, right)
4+
{
5+
public override byte Precedence => 2;
6+
7+
protected override DataValue Run(DataType.NumericCompatibleDataType common, DataValue left, DataValue right) => common.Divide(left, right);
8+
9+
protected override char Operator => '/';
10+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
namespace SqlServerSimulator.Parser.Expressions;
2+
3+
internal abstract class MathExpression(Expression left, Expression right) : TwoSidedExpression(left, right)
4+
{
5+
protected abstract DataValue Run(DataType.NumericCompatibleDataType common, DataValue left, DataValue right);
6+
7+
protected sealed override DataValue Run(DataValue left, DataValue right) => Run(DataType.CommonNumeric(left, right, this.Operator), left, right);
8+
}

0 commit comments

Comments
 (0)