Skip to content

Commit

Permalink
Merge pull request #635 from sys27/feature/lambda
Browse files Browse the repository at this point in the history
#628 - Create CallExpression / High-Order Functions.
  • Loading branch information
sys27 authored Jun 5, 2023
2 parents 790899c + e012f36 commit 07967b8
Show file tree
Hide file tree
Showing 166 changed files with 2,518 additions and 1,174 deletions.
13 changes: 8 additions & 5 deletions xFunc Grammar.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
// It's just a reference grammar for xFunc (The implementaion is not completely equal to grammar).

statement = unaryAssign
/ binaryAssign
/ assign
statement = assign
/ def
/ undef
/ if
Expand All @@ -26,7 +24,7 @@ binaryAssign = variable ('+=' / '-=' / '*=' / '/=' / '<<=' / '>>=') exp
ternary = conditional ('?' exp ':' exp)*

conditional = bitwise (('&&' / '||') bitwise)*
bitwise = equality (('&' / 'and' / '|' / 'or' / 'xor' / '=>' / '->' / 'impl' / '<=>' / '<->' / 'eq' / 'nor' / 'nand') equality)*
bitwise = equality (('&' / 'and' / '|' / 'or' / 'xor' / 'impl' / 'eq' / 'nor' / 'nand') equality)*
equality = shift (('==' / '!=' / '<' / '<=' / '>' / '>=') shift)*
shift = addSub (('<<' / '>>') addSub)*
addSub = mulDivMod (('+' / '-') mulDivMod)*
Expand All @@ -48,6 +46,8 @@ operand = complexnumber /
variable /
boolean /
bracketExp /
callExp /
lambda /
matrix /
vector

Expand All @@ -70,4 +70,7 @@ parameters = (statement (',' statement)*)*
vector = ('{' / '(') parameters ('}' / ')')
matrix = ('{' / '(') vector (',' vector) ('}' / ')')

functionDeclaration = id '(' (variable (',' variable)* / '') ')'
functionDeclaration = id '(' (variable (',' variable)* / '') ')'

lambda = '(' (id (',' id) / '') ')' '=>' exp
callExp = '(' lambda ')' '(' parameters ')'
2 changes: 1 addition & 1 deletion xFunc.Benchmark/Benchmarks/ProcessorBenchmark.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public void Setup()

[Benchmark]
public IExpression Parse()
=> processor.Parse("(100.1 + 2(3sin(4cos(5tan(6ctg(10x)))) * 3) / (func(a, b, c) ^ 2)) - (cos(y) - 111.3) & (true | false -> true <-> false eq true) + (det({{1, 2}, {3, 4}}) * 10log(2, 3)) + re(3 + 2i) - im(2 - 9i) + (9 + 2i)");
=> processor.Parse("(100.1 + 2(3sin(4cos(5tan(6ctg(10x)))) * 3) / (func(a, b, c) ^ 2)) - (cos(y) - 111.3) & (true | false impl true eq false) + (det({{1, 2}, {3, 4}}) * 10log(2, 3)) + re(3 + 2i) - im(2 - 9i) + (9 + 2i)");

[Benchmark]
public NumberResult Solve()
Expand Down
1 change: 1 addition & 0 deletions xFunc.DotnetTool/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using xFunc.DotnetTool.Options;
using xFunc.Maths.Expressions.Parameters;

namespace xFunc.DotnetTool;

Expand Down
2 changes: 1 addition & 1 deletion xFunc.DotnetTool/xFunc.DotnetTool.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
<Using Include="xFunc.Maths.Analyzers" />
<Using Include="xFunc.Maths.Analyzers.TypeAnalyzers" />
<Using Include="xFunc.Maths.Expressions" />
<Using Include="xFunc.Maths.Expressions.Collections" />
<Using Include="xFunc.Maths.Expressions.Parameters" />
<Using Include="xFunc.Maths.Expressions.Matrices" />
<Using Include="xFunc.Maths.Expressions.Units" />
<Using Include="xFunc.Maths.Results" />
Expand Down
6 changes: 5 additions & 1 deletion xFunc.Maths/Analyzers/Analyzer{TResult,TContext}.cs
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,11 @@ public virtual TResult Analyze(Undefine exp, TContext context)
=> Analyze(exp as IExpression, context);

/// <inheritdoc />
public virtual TResult Analyze(UserFunction exp, TContext context)
public virtual TResult Analyze(CallExpression exp, TContext context)
=> Analyze(exp as IExpression, context);

/// <inheritdoc />
public virtual TResult Analyze(LambdaExpression exp, TContext context)
=> Analyze(exp as IExpression, context);

/// <inheritdoc />
Expand Down
6 changes: 5 additions & 1 deletion xFunc.Maths/Analyzers/Analyzer{TResult}.cs
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,11 @@ public virtual TResult Analyze(Undefine exp)
=> Analyze(exp as IExpression);

/// <inheritdoc />
public virtual TResult Analyze(UserFunction exp)
public virtual TResult Analyze(CallExpression exp)
=> Analyze(exp as IExpression);

/// <inheritdoc />
public virtual TResult Analyze(LambdaExpression exp)
=> Analyze(exp as IExpression);

/// <inheritdoc />
Expand Down
11 changes: 0 additions & 11 deletions xFunc.Maths/Analyzers/Differentiator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -371,17 +371,6 @@ public override IExpression Analyze(UnaryMinus exp, DifferentiatorContext contex
return new UnaryMinus(exp.Argument.Analyze(this, context));
}

/// <inheritdoc />
public override IExpression Analyze(UserFunction exp, DifferentiatorContext context)
{
ValidateArguments(exp, context);

if (context.Parameters is null)
throw new InvalidOperationException();

return context.Parameters.Functions[exp].Analyze(this, context);
}

/// <inheritdoc />
public override IExpression Analyze(Variable exp, DifferentiatorContext context)
{
Expand Down
26 changes: 13 additions & 13 deletions xFunc.Maths/Analyzers/Formatters/CommonFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ namespace xFunc.Maths.Analyzers.Formatters;
/// <seealso cref="IFormatter" />
public class CommonFormatter : IFormatter
{
/// <summary>
/// Gets the instance of <see cref="CommonFormatter"/>.
/// </summary>
public static CommonFormatter Instance { get; } = new CommonFormatter();

private string ToString(UnaryExpression exp, string format)
{
var arg = exp.Argument.Analyze(this);
Expand Down Expand Up @@ -235,23 +240,18 @@ public virtual string Analyze(Undefine exp)
=> $"undef({exp.Key.Analyze(this)})";

/// <inheritdoc />
public virtual string Analyze(UserFunction exp)
public virtual string Analyze(CallExpression exp)
{
var sb = new StringBuilder();

sb.Append(exp.Function).Append('(');
if (exp.ParametersCount > 0)
{
foreach (var item in exp.Arguments)
sb.Append(item).Append(", ");
sb.Remove(sb.Length - 2, 2);
}

sb.Append(')');
if (exp.Function is LambdaExpression)
return $"({exp.Function})({string.Join(", ", exp.Parameters)})";

return sb.ToString();
return $"{exp.Function}({string.Join(", ", exp.Parameters)})";
}

/// <inheritdoc />
public virtual string Analyze(LambdaExpression exp)
=> $"{exp.Lambda}";

/// <inheritdoc />
public virtual string Analyze(Variable exp) => exp.Name;

Expand Down
10 changes: 9 additions & 1 deletion xFunc.Maths/Analyzers/IAnalyzer{TResult,TContext}.cs
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,15 @@ public interface IAnalyzer<out TResult, in TContext>
/// <param name="exp">The expression.</param>
/// <param name="context">The context.</param>
/// <returns>The result of analysis.</returns>
TResult Analyze(UserFunction exp, TContext context);
TResult Analyze(CallExpression exp, TContext context);

/// <summary>
/// Analyzes the specified expression.
/// </summary>
/// <param name="exp">The expression.</param>
/// <param name="context">The context.</param>
/// <returns>The result of analysis.</returns>
TResult Analyze(LambdaExpression exp, TContext context);

/// <summary>
/// Analyzes the specified expression.
Expand Down
9 changes: 8 additions & 1 deletion xFunc.Maths/Analyzers/IAnalyzer{TResult}.cs
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,14 @@ public interface IAnalyzer<out TResult>
/// </summary>
/// <param name="exp">The expression.</param>
/// <returns>The result of analysis.</returns>
TResult Analyze(UserFunction exp);
TResult Analyze(CallExpression exp);

/// <summary>
/// Analyzes the specified expression.
/// </summary>
/// <param name="exp">The expression.</param>
/// <returns>The result of analysis.</returns>
TResult Analyze(LambdaExpression exp);

/// <summary>
/// Analyzes the specified expression.
Expand Down
37 changes: 27 additions & 10 deletions xFunc.Maths/Analyzers/Simplifier.cs
Original file line number Diff line number Diff line change
Expand Up @@ -938,26 +938,43 @@ public override IExpression Analyze(UnaryMinus exp)
}

/// <inheritdoc />
public override IExpression Analyze(UserFunction exp)
public override IExpression Analyze(CallExpression exp)
{
if (exp is null)
ArgNull(ExceptionArgument.exp);

var arguments = exp.Arguments;
var isExpChanged = false;
var function = exp.Function.Analyze(this);
var isChanged = IsChanged(exp.Function, function);
var parameters = exp.Parameters;

for (var i = 0; i < exp.ParametersCount; i++)
for (var i = 0; i < exp.Parameters.Length; i++)
{
var expression = exp[i].Analyze(this);
if (IsChanged(exp[i], expression))
var parameter = exp.Parameters[i];
var simplified = parameter.Analyze(this);
if (IsChanged(parameter, simplified))
{
isExpChanged = true;
arguments = arguments.SetItem(i, expression);
parameters = parameters.SetItem(i, simplified);
isChanged = true;
}
}

if (isExpChanged)
return exp.Clone(arguments);
if (isChanged)
return exp.Clone(function, parameters);

return exp;
}

/// <inheritdoc />
public override IExpression Analyze(LambdaExpression exp)
{
if (exp is null)
ArgNull(ExceptionArgument.exp);

var body = exp.Lambda.Body.Analyze(this);
if (IsChanged(exp.Lambda.Body, body))
{
return exp.Clone(new Lambda(exp.Lambda.Parameters, body));
}

return exp;
}
Expand Down
5 changes: 5 additions & 0 deletions xFunc.Maths/Analyzers/TypeAnalyzers/ResultTypes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -95,4 +95,9 @@ public enum ResultTypes
/// The expression returns a volume number.
/// </summary>
VolumeNumber = 1 << 15,

/// <summary>
/// The expression return a function.
/// </summary>
Function = 1 << 16,
}
6 changes: 5 additions & 1 deletion xFunc.Maths/Analyzers/TypeAnalyzers/TypeAnalyzer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1311,9 +1311,13 @@ public virtual ResultTypes Analyze(Undefine exp)
=> CheckArgument(exp, ResultTypes.String);

/// <inheritdoc />
public virtual ResultTypes Analyze(UserFunction exp)
public virtual ResultTypes Analyze(CallExpression exp)
=> CheckArgument(exp, ResultTypes.Undefined);

/// <inheritdoc />
public virtual ResultTypes Analyze(LambdaExpression exp)
=> CheckArgument(exp, ResultTypes.Function);

/// <inheritdoc />
public virtual ResultTypes Analyze(Variable exp)
=> CheckArgument(exp, ResultTypes.Undefined);
Expand Down
5 changes: 5 additions & 0 deletions xFunc.Maths/Expressions/Abs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ namespace xFunc.Maths.Expressions;
/// </summary>
public class Abs : UnaryExpression
{
/// <summary>
/// Gets the lambda for the current expression.
/// </summary>
internal static Lambda Lambda { get; } = new Lambda(new[] { Variable.X.Name }, new Abs(Variable.X));

/// <summary>
/// Initializes a new instance of the <see cref="Abs"/> class.
/// </summary>
Expand Down
7 changes: 7 additions & 0 deletions xFunc.Maths/Expressions/Add.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ namespace xFunc.Maths.Expressions;
/// </summary>
public class Add : BinaryExpression
{
/// <summary>
/// Gets the lambda for the current expression.
/// </summary>
internal static Lambda Lambda { get; } = new Lambda(
new[] { Variable.X.Name, Variable.Y.Name },
new Add(Variable.X, Variable.Y));

/// <summary>
/// Initializes a new instance of the <see cref="Add"/> class.
/// </summary>
Expand Down
2 changes: 1 addition & 1 deletion xFunc.Maths/Expressions/BinaryExpression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public override bool Equals(object? obj)
public string ToString(IFormatter formatter) => Analyze(formatter);

/// <inheritdoc />
public override string ToString() => ToString(new CommonFormatter());
public override string ToString() => ToString(CommonFormatter.Instance);

/// <inheritdoc />
public object Execute() => Execute(null);
Expand Down
Loading

0 comments on commit 07967b8

Please sign in to comment.