Skip to content

Commit

Permalink
Compile function once, during the registration.
Browse files Browse the repository at this point in the history
  • Loading branch information
yallie committed Mar 8, 2019
1 parent 9d67c08 commit 3d0907f
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 12 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
Sprache.Calc
============

[![Appveyor build status](https://ci.appveyor.com/api/projects/status/qswh0wj2uv3w502v?svg=true)](https://ci.appveyor.com/project/yallie/sprache-calc)
[![Tests](https://img.shields.io/appveyor/tests/yallie/sprache-calc.svg)](https://ci.appveyor.com/project/yallie/sprache-calc/build/tests)

This library provides easy to use extensible expression evaluator based on [LinqyCalculator sample](https://github.com/sprache/Sprache/blob/master/samples/LinqyCalculator/ExpressionParser.cs).
The evaluator supports arithmetic operations, custom functions and parameters. It takes string
representation of an expression and converts it to a structured LINQ expression instance
Expand Down
5 changes: 1 addition & 4 deletions Sprache.Calc.Tests/XtensibleCalculatorFacts.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,9 @@ protected override object[] LambdaArguments
public void UserFunctionCanWork()
{
var calc = (XtensibleCalculator) CreateCalculator();

calc.RegisterFunction("User", (aU,bU,cU) => calc.ParseExpression("Min(a,b,c)", new Dictionary<string,double>(){{"a",aU},{"b",bU},{"c",cU}}).Compile().Invoke());


var func = calc.ParseExpression("User(a,b,c)", new Dictionary<string,double>(){{"a",1},{"b",2},{"c",3}}).Compile();

Assert.Equal(1, func());
}

Expand All @@ -48,7 +45,7 @@ public void StringUserFunctionCanWork()
calc.RegisterFunction("UserB", "Min(a,b,c)", "a", "b", "c");
var func = calc.ParseExpression("UserB(a,b,c)",
new Dictionary<string, double>() {{"a", 1}, {"b", 2}, {"c", 3}}).Compile();

Assert.Equal(1, func());
}

Expand Down
7 changes: 5 additions & 2 deletions Sprache.Calc/Sprache.Calc.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard1.6</TargetFramework>
<TargetFrameworks>netstandard1.6;netstandard2.0</TargetFrameworks>
<PackageVersion></PackageVersion>
<Title>Sprache Calculator</Title>
<Authors>Alexey Yakovlev, Andrey Leskov</Authors>
Expand All @@ -13,11 +13,14 @@
<RepositoryUrl>https://github.com/yallie/Sprache.Calc</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageTags>sprache expression expressions evaluator calculator parser parsers linq monad</PackageTags>
<PackageReleaseNotes>Sprache toolkit grammar inheritance sample. Updated for .Net Standart 1.6 and added functionality to add user-defined functions from strings. For more details, see https://github.com/yallie/Sprache.Calc</PackageReleaseNotes>
<PackageReleaseNotes>Sprache toolkit grammar inheritance sample. Updated for .Net Standard 1.6 and added functionality to add user-defined functions from strings. For more details, see https://github.com/yallie/Sprache.Calc</PackageReleaseNotes>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Sprache" Version="2.2.0" />
</ItemGroup>

<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard1.6' ">
<PackageReference Include="System.Reflection.TypeExtensions" Version="4.5.1" />
</ItemGroup>

Expand Down
19 changes: 13 additions & 6 deletions Sprache.Calc/XtensibleCalculator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -151,18 +151,25 @@ public XtensibleCalculator RegisterFunction(string name, Func<double, double, do
CustomFuctions[MangleName(name, 5)] = x => function(x[0], x[1], x[2], x[3], x[4]);
return this;
}

public XtensibleCalculator RegisterFunction(string name, string functionExpression, params string[] parameters)
{
// Func<Dictionary, double>
var compiledFunction = ParseFunction(functionExpression).Compile();

//syntactic sugar: ParseExpression("a + b / c", "a","b","c")
CustomFuctions[MangleName(name, parameters.Length)] = x =>
{
var parametersDictionary = new Dictionary<string,double>();
for(int paramSeq = 0;paramSeq < parameters.Length; paramSeq++)
parametersDictionary.Add(parameters[paramSeq],x[paramSeq]);

return this.ParseExpression(functionExpression,parametersDictionary).Compile().Invoke();
// convert double[] to Dictionary
var parametersDictionary = new Dictionary<string, double>();
for (int paramSeq = 0; paramSeq < parameters.Length; paramSeq++)
{
parametersDictionary.Add(parameters[paramSeq], x[paramSeq]);
}

return compiledFunction(parametersDictionary);
};

return this;
}
}
Expand Down

0 comments on commit 3d0907f

Please sign in to comment.