diff --git a/src/SpiceSharpParser.IntegrationTests/Examples/Example01.cs b/src/SpiceSharpParser.IntegrationTests/Examples/Example01.cs
new file mode 100644
index 00000000..5776ac47
--- /dev/null
+++ b/src/SpiceSharpParser.IntegrationTests/Examples/Example01.cs
@@ -0,0 +1,26 @@
+using System.IO;
+using Xunit;
+
+namespace SpiceSharpParser.IntegrationTests.Examples
+{
+ public class Example01 : BaseTests
+ {
+ [Fact]
+ public void When_Simulated_Expect_NoExceptions()
+ {
+ string path = Path.Combine(Directory.GetCurrentDirectory(), "Resources/example01.cir");
+ var netlistContent = File.ReadAllText(path);
+
+ var parser = new SpiceParser();
+ parser.Settings.Lexing.HasTitle = true;
+
+ var parseResult = parser.ParseNetlist(netlistContent);
+
+ double[] exports = RunOpSimulation(parseResult.SpiceSharpModel, new [] { "V(N1)", "V(N2)", "V(N3)" });
+
+ EqualsWithTol(1.0970919064909939, exports[0]);
+ EqualsWithTol(0.014696545624995935, exports[1]);
+ EqualsWithTol(0.014715219080886419, exports[2]);
+ }
+ }
+}
diff --git a/src/SpiceSharpParser.IntegrationTests/Resources/example01.cir b/src/SpiceSharpParser.IntegrationTests/Resources/example01.cir
new file mode 100644
index 00000000..2868a67f
--- /dev/null
+++ b/src/SpiceSharpParser.IntegrationTests/Resources/example01.cir
@@ -0,0 +1,45 @@
+Example 01
+
+.param a0_entry=0.1
+.param b0_entry=0.01
+.param density =850
+.param viscosity =0.000006
+.param rout_entry =0.9
+.param rin_entry =0.8
+.param r1_entry1 =0.8
+.param r2_entry1=0.81
+.param r1_entry2 =0.89
+.param r2_entry2=0.9
+.param FlowRate =0.025
+
+I_M 0 N1 {FlowRate}
+
+X_entry1 N1 0 N2 entry params: a0={a0_entry}, b0={b0_entry}, ro={density}, v={viscosity}, rout={rout_entry},
++rin={rin_entry},r1={r1_entry1},r2={r2_entry1}
+
+X_entry2 N1 0 N3 entry params: a0={a0_entry}, b0={b0_entry}, ro={density}, v={viscosity}, rout={rout_entry},
++rin={rin_entry},r1={r1_entry2},r2={r2_entry2}
+
+.subckt entry m_in m_out v_vel params: a0=1, b0=1, ro=1, v=1, rout=1, rin=1, r1=1, r2=1
+.param D0 = {2*a0*b0/(a0+b0)}
+.param F1 = {(rout-rin)*a0*(rout+rin)/(r2+r1)}
+.param F0 = {(r2-r1)*a0}
+.param fraction = {F0/F1}
+.func Q(m) {m/ro}
+.func vel(m) {Q(m)/(a0*b0)}
+.func R(x) {x*D0/v}
+*Changed function
+.func xi(x) {40*pow(R(x),-0.9) + 90*pow(fraction,-0.003)-80}
+Vmas m_in msx {0}
+Rmas msx msy 1e-6
+*The pressure drop:
+Exm msy m_out value={xi(V(v_vel))*ro*V(v_vel)*V(v_vel)/2}
+Hmss mss 0 Vmas 1
+*Velocity:
+Guv 0 v_vel value={vel(V(mss))}
+Ruv 0 v_vel 1
+.ends
+
+.OP
+.SAVE V(N1) V(N2) V(N3)
+.end
\ No newline at end of file
diff --git a/src/SpiceSharpParser.IntegrationTests/SpiceSharpParser.IntegrationTests.csproj b/src/SpiceSharpParser.IntegrationTests/SpiceSharpParser.IntegrationTests.csproj
index 0c191a18..1dbef3d2 100644
--- a/src/SpiceSharpParser.IntegrationTests/SpiceSharpParser.IntegrationTests.csproj
+++ b/src/SpiceSharpParser.IntegrationTests/SpiceSharpParser.IntegrationTests.csproj
@@ -12,6 +12,10 @@
true
+
+
+
+
@@ -29,6 +33,9 @@
+
+ Always
+
Always
diff --git a/src/SpiceSharpParser.PerformanceTests/ExpressionTests.cs b/src/SpiceSharpParser.PerformanceTests/ExpressionTests.cs
index 5942ee47..1708e052 100644
--- a/src/SpiceSharpParser.PerformanceTests/ExpressionTests.cs
+++ b/src/SpiceSharpParser.PerformanceTests/ExpressionTests.cs
@@ -32,14 +32,16 @@ public void EvaluateDouble()
var randomizer = new Randomizer();
for (var i = 0; i < n; i++)
{
- sum += expressionParser.EvaluateValueExpression(
+ sum += expressionParser.Evaluate(
"1 + 1 + 1 + 1 + 1 + 1 + 1",
new ExpressionContext(
string.Empty,
false,
false,
false,
- randomizer));
+ randomizer),
+ null,
+ null);
}
}
}
diff --git a/src/SpiceSharpParser.Tests/Common/Evaluation/ExpressionRegistryTests.cs b/src/SpiceSharpParser.Tests/Common/Evaluation/ExpressionRegistryTests.cs
index 7a3fed6e..f8e9ccb1 100644
--- a/src/SpiceSharpParser.Tests/Common/Evaluation/ExpressionRegistryTests.cs
+++ b/src/SpiceSharpParser.Tests/Common/Evaluation/ExpressionRegistryTests.cs
@@ -2,6 +2,8 @@
using SpiceSharpParser.Common.Evaluation;
using SpiceSharpParser.Common.Evaluation.Expressions;
using System.Linq;
+using SpiceSharp.Simulations;
+using SpiceSharpParser.ModelReaders.Netlist.Spice.Context;
using Xunit;
namespace SpiceSharpParser.Tests.Common.Evaluation
@@ -13,7 +15,7 @@ public void AddExpressionWithoutParameters()
{
var registry = new ExpressionRegistry(false, false);
var evaluator = Substitute.For();
- evaluator.EvaluateValueExpression(Arg.Any(), Arg.Any()).Returns(1);
+ evaluator.Evaluate(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()).Returns(1);
registry.Add(new NamedExpression("test", "1"), new System.Collections.Generic.List());
@@ -24,7 +26,7 @@ public void AddExpressionWithoutParameters()
public void AddExpressionWithParameters()
{
var registry = new ExpressionRegistry(false, false);
- registry.Add(new Expression("x+1"), new System.Collections.Generic.List() { "x" });
+ registry.Add(new DynamicExpression("x+1"), new System.Collections.Generic.List() { "x" });
Assert.Single(registry.GetDependentExpressions("x"));
}
@@ -33,9 +35,9 @@ public void AddExpressionWithParameters()
public void AddExpressionsWithSingleParameter()
{
var registry = new ExpressionRegistry(false, false);
- registry.Add(new Expression("x+1"), new System.Collections.Generic.List() { "x" });
- registry.Add(new Expression("y+1"), new System.Collections.Generic.List() { "y" });
- registry.Add(new Expression("x+1"), new System.Collections.Generic.List() { "x" });
+ registry.Add(new DynamicExpression("x+1"), new System.Collections.Generic.List() { "x" });
+ registry.Add(new DynamicExpression("y+1"), new System.Collections.Generic.List() { "y" });
+ registry.Add(new DynamicExpression("x+1"), new System.Collections.Generic.List() { "x" });
Assert.Single(registry.GetDependentExpressions("y"));
Assert.Equal(2, registry.GetDependentExpressions("x").Count());
@@ -45,9 +47,9 @@ public void AddExpressionsWithSingleParameter()
public void AddExpressionsWithMultipleParameter()
{
var registry = new ExpressionRegistry(false, false);
- registry.Add(new Expression("x+y+1"), new System.Collections.Generic.List() { "x", "y" });
- registry.Add(new Expression("y+x+1"), new System.Collections.Generic.List() { "y", "x" });
- registry.Add(new Expression("x+1"), new System.Collections.Generic.List() { "x" });
+ registry.Add(new DynamicExpression("x+y+1"), new System.Collections.Generic.List() { "x", "y" });
+ registry.Add(new DynamicExpression("y+x+1"), new System.Collections.Generic.List() { "y", "x" });
+ registry.Add(new DynamicExpression("x+1"), new System.Collections.Generic.List() { "x" });
Assert.Equal(2, registry.GetDependentExpressions("y").Count());
Assert.Equal(3, registry.GetDependentExpressions("x").Count());
diff --git a/src/SpiceSharpParser.Tests/ModelReaders/Spice/Evaluation/SpiceEvaluatorTests.cs b/src/SpiceSharpParser.Tests/ModelReaders/Spice/Evaluation/SpiceEvaluatorTests.cs
index 1cf29243..59740fcd 100644
--- a/src/SpiceSharpParser.Tests/ModelReaders/Spice/Evaluation/SpiceEvaluatorTests.cs
+++ b/src/SpiceSharpParser.Tests/ModelReaders/Spice/Evaluation/SpiceEvaluatorTests.cs
@@ -2,6 +2,7 @@
using SpiceSharpParser.ModelReaders.Netlist.Spice.Evaluation;
using SpiceSharpParser.Parsers.Expression;
using System;
+using SpiceSharpParser.Common.Evaluation.Expressions;
using Xunit;
namespace SpiceSharpParser.Tests.ModelReaders.Spice.Evaluation
@@ -20,11 +21,11 @@ public void ParentEvaluator()
var v = c.CreateChildContext("child", false);
v.SetParameter("xyz", 13.0);
- Assert.Equal(1, v.Parameters["a"].CurrentValue);
+ Assert.Equal(1, ((ConstantExpression)v.Parameters["a"]).Value);
v.SetParameter("a", 2);
- Assert.Equal(2, v.Parameters["a"].CurrentValue);
- Assert.Equal(1, c.Parameters["a"].CurrentValue);
+ Assert.Equal(2, ((ConstantExpression)v.Parameters["a"]).Value);
+ Assert.Equal(1, ((ConstantExpression)c.Parameters["a"]).Value);
}
[Fact]
@@ -34,7 +35,7 @@ public void EvaluateParameter()
var c = new SpiceExpressionContext(SpiceExpressionMode.Spice3f5);
c.SetParameter("xyz", 13.0);
- Assert.Equal(14, v.EvaluateValueExpression("xyz + 1", c));
+ Assert.Equal(14, v.Evaluate("xyz + 1", c, null, null));
}
[Fact]
@@ -42,7 +43,7 @@ public void EvaluateSuffix()
{
Evaluator v = new Evaluator();
var c = new SpiceExpressionContext(SpiceExpressionMode.Spice3f5);
- Assert.Equal(2, v.EvaluateValueExpression("1V + 1", c));
+ Assert.Equal(2, v.Evaluate("1V + 1", c, null, null));
}
[Fact]
@@ -51,7 +52,7 @@ public void TableBasic()
Evaluator v = new Evaluator();
var c = new SpiceExpressionContext(SpiceExpressionMode.Spice3f5);
c.SetParameter("N", 1.0);
- Assert.Equal(10, v.EvaluateValueExpression("table(N, 1, pow(10, 1), 2 + 0, 20, 3, 30)", c));
+ Assert.Equal(10, v.Evaluate("table(N, 1, pow(10, 1), 2 + 0, 20, 3, 30)", c, null, null));
}
[Fact]
@@ -61,16 +62,16 @@ public void TableInterpolation()
var c = new SpiceExpressionContext(SpiceExpressionMode.Spice3f5);
c.SetParameter("N", 1.5);
- Assert.Equal(-5, v.EvaluateValueExpression("table(N, 1, 0, 2, -10)", c));
+ Assert.Equal(-5, v.Evaluate("table(N, 1, 0, 2, -10)", c, null, null));
c.SetParameter("N", 3);
- Assert.Equal(-10, v.EvaluateValueExpression("table(N, 1, 0, 2, -10)", c));
+ Assert.Equal(-10, v.Evaluate("table(N, 1, 0, 2, -10)", c, null, null));
c.SetParameter("N", 0);
- Assert.Equal(0, v.EvaluateValueExpression("table(N, 1, 0, 2, -10)", c));
+ Assert.Equal(0, v.Evaluate("table(N, 1, 0, 2, -10)", c, null, null));
c.SetParameter("N", -1);
- Assert.Equal(0, v.EvaluateValueExpression("table(N, 1, 0, 2, -10)", c));
+ Assert.Equal(0, v.Evaluate("table(N, 1, 0, 2, -10)", c, null, null));
}
[Fact]
@@ -79,7 +80,7 @@ public void TableAdvanced()
Evaluator v = new Evaluator();
var c = new SpiceExpressionContext(SpiceExpressionMode.Spice3f5);
c.SetParameter("N", 1.0);
- Assert.Equal(10, v.EvaluateValueExpression("table(N, 1, pow(10, 1), 2 + 0, 20, 3, 30)", c));
+ Assert.Equal(10, v.Evaluate("table(N, 1, pow(10, 1), 2 + 0, 20, 3, 30)", c, null, null));
}
[Fact]
@@ -89,19 +90,8 @@ public void Round()
var evaluator = new Evaluator();
var c = new SpiceExpressionContext(SpiceExpressionMode.Spice3f5);
// act and assert
- Assert.Equal(1, evaluator.EvaluateValueExpression("round(1.2)", c));
- Assert.Equal(2, evaluator.EvaluateValueExpression("round(1.9)", c));
- }
-
- [Fact]
- public void PowMinusLtSpice()
- {
- // arrange
- var evaluator = new Evaluator();
- var c = new SpiceExpressionContext(SpiceExpressionMode.LtSpice);
-
- // act and assert
- Assert.Equal(0, evaluator.EvaluateValueExpression("pow(-2,1.5)", c));
+ Assert.Equal(1, evaluator.Evaluate("round(1.2)", c, null, null));
+ Assert.Equal(2, evaluator.Evaluate("round(1.9)", c, null, null));
}
[Fact]
@@ -112,7 +102,7 @@ public void PwrLtSpice()
var c = new SpiceExpressionContext(SpiceExpressionMode.LtSpice);
// act and assert
- Assert.Equal(8, evaluator.EvaluateValueExpression("pwr(-2,3)", c));
+ Assert.Equal(8, evaluator.Evaluate("pwr(-2,3)", c, null, null));
}
[Fact]
@@ -123,7 +113,7 @@ public void PwrHSpice()
var c = new SpiceExpressionContext(SpiceExpressionMode.HSpice);
// act and assert
- Assert.Equal(-8, evaluator.EvaluateValueExpression("pwr(-2,3)", c));
+ Assert.Equal(-8, evaluator.Evaluate("pwr(-2,3)", c, null, null));
}
[Fact]
@@ -134,28 +124,7 @@ public void PwrSmartSpice()
var c = new SpiceExpressionContext(SpiceExpressionMode.SmartSpice);
// act and assert
- Assert.Equal(-8, evaluator.EvaluateValueExpression("pwr(-2,3)", c));
- }
-
- [Fact]
- public void PowMinusSmartSpice()
- {
- // arrange
- var evaluator = new Evaluator();
- var c = new SpiceExpressionContext(SpiceExpressionMode.SmartSpice);
-
- // act and assert
- Assert.Equal(Math.Pow(2, (int)1.5), evaluator.EvaluateValueExpression("pow(-2,1.5)", c));
- }
-
- [Fact]
- public void PowMinusHSpice()
- {
- // arrange
- var evaluator = new Evaluator();
- var c = new SpiceExpressionContext(SpiceExpressionMode.HSpice);
- // act and assert
- Assert.Equal(Math.Pow(-2, (int)1.5), evaluator.EvaluateValueExpression("pow(-2,1.5)", c));
+ Assert.Equal(-8, evaluator.Evaluate("pwr(-2,3)", c, null, null));
}
[Fact]
@@ -165,9 +134,9 @@ public void Sgn()
var evaluator = new Evaluator();
var c = new SpiceExpressionContext(SpiceExpressionMode.Spice3f5);
// act and assert
- Assert.Equal(0, evaluator.EvaluateValueExpression("sgn(0)", c));
- Assert.Equal(-1, evaluator.EvaluateValueExpression("sgn(-1)", c));
- Assert.Equal(1, evaluator.EvaluateValueExpression("sgn(0.1)", c));
+ Assert.Equal(0, evaluator.Evaluate("sgn(0)", c, null, null));
+ Assert.Equal(-1, evaluator.Evaluate("sgn(-1)", c, null, null));
+ Assert.Equal(1, evaluator.Evaluate("sgn(0.1)", c, null, null));
}
[Fact]
@@ -178,40 +147,7 @@ public void Sqrt()
var c = new SpiceExpressionContext(SpiceExpressionMode.Spice3f5);
// act and assert
- Assert.Equal(2, evaluator.EvaluateValueExpression("sqrt(4)", c));
- }
-
- [Fact]
- public void SqrtMinusHSpice()
- {
- // arrange
- var evaluator = new Evaluator();
- var c = new SpiceExpressionContext(SpiceExpressionMode.HSpice);
-
- // act and assert
- Assert.Equal(-2, evaluator.EvaluateValueExpression("sqrt(-4)", c));
- }
-
- [Fact]
- public void SqrtMinusSmartSpice()
- {
- // arrange
- var evaluator = new Evaluator();
- var c = new SpiceExpressionContext(SpiceExpressionMode.SmartSpice);
-
- // act and assert
- Assert.Equal(2, evaluator.EvaluateValueExpression("sqrt(-4)", c));
- }
-
- [Fact]
- public void SqrtMinusLtSpice()
- {
- // arrange
- var evaluator = new Evaluator();
- var c = new SpiceExpressionContext(SpiceExpressionMode.LtSpice);
-
- // act and assert
- Assert.Equal(0, evaluator.EvaluateValueExpression("sqrt(-4)", c));
+ Assert.Equal(2, evaluator.Evaluate("sqrt(4)", c, null, null));
}
[Fact]
@@ -223,7 +159,7 @@ public void DefPositive()
c.SetParameter("x1", 1);
// act and assert
- Assert.Equal(1, evaluator.EvaluateValueExpression("def(x1)", c));
+ Assert.Equal(1, evaluator.Evaluate("def(x1)", c, null, null));
}
[Fact]
@@ -234,7 +170,7 @@ public void DefNegative()
var c = new SpiceExpressionContext(SpiceExpressionMode.Spice3f5);
// act and assert
- Assert.Equal(0, evaluator.EvaluateValueExpression("def(x1)", c));
+ Assert.Equal(0, evaluator.Evaluate("def(x1)", c, null, null));
}
[Fact]
@@ -245,7 +181,7 @@ public void Abs()
var c = new SpiceExpressionContext(SpiceExpressionMode.Spice3f5);
// act and assert
- Assert.Equal(1, evaluator.EvaluateValueExpression("abs(-1)", c));
+ Assert.Equal(1, evaluator.Evaluate("abs(-1)", c, null, null));
}
[Fact]
@@ -256,7 +192,7 @@ public void AGauss()
var c = new SpiceExpressionContext(SpiceExpressionMode.Spice3f5);
// act and assert
- evaluator.EvaluateValueExpression("agauss(0, 1, 2)", c);
+ evaluator.Evaluate("agauss(0, 1, 2)", c, null, null);
}
[Fact]
@@ -267,7 +203,7 @@ public void AUnif()
var c = new SpiceExpressionContext(SpiceExpressionMode.Spice3f5);
// act and assert
- evaluator.EvaluateValueExpression("aunif(0, 1)", c);
+ evaluator.Evaluate("aunif(0, 1)", c, null, null);
}
[Fact]
@@ -278,7 +214,7 @@ public void Unif()
var c = new SpiceExpressionContext(SpiceExpressionMode.Spice3f5);
// act and assert
- evaluator.EvaluateValueExpression("unif(1, 0.5)", c);
+ evaluator.Evaluate("unif(1, 0.5)", c, null, null);
}
[Fact]
@@ -289,7 +225,7 @@ public void LimitRandom()
var c = new SpiceExpressionContext(SpiceExpressionMode.Spice3f5);
// act and assert
- evaluator.EvaluateValueExpression("limit(0, 1)", c);
+ evaluator.Evaluate("limit(0, 1)", c, null, null);
}
[Fact]
@@ -300,8 +236,8 @@ public void Buf()
var c = new SpiceExpressionContext(SpiceExpressionMode.Spice3f5);
// act and assert
- Assert.Equal(1, evaluator.EvaluateValueExpression("buf(0.6)", c));
- Assert.Equal(0, evaluator.EvaluateValueExpression("buf(0.3)", c));
+ Assert.Equal(1, evaluator.Evaluate("buf(0.6)", c, null, null));
+ Assert.Equal(0, evaluator.Evaluate("buf(0.3)", c, null, null));
}
[Fact]
@@ -312,7 +248,7 @@ public void Cbrt()
var c = new SpiceExpressionContext(SpiceExpressionMode.Spice3f5);
// act and assert
- Assert.Equal(2, evaluator.EvaluateValueExpression("cbrt(8)", c));
+ Assert.Equal(2, evaluator.Evaluate("cbrt(8)", c, null, null));
}
[Fact]
@@ -323,7 +259,7 @@ public void Ceil()
var c = new SpiceExpressionContext(SpiceExpressionMode.Spice3f5);
// act and assert
- Assert.Equal(3, evaluator.EvaluateValueExpression("ceil(2.9)", c));
+ Assert.Equal(3, evaluator.Evaluate("ceil(2.9)", c, null, null));
}
[Fact]
@@ -334,7 +270,7 @@ public void DbSmartSpice()
var c = new SpiceExpressionContext(SpiceExpressionMode.SmartSpice);
// act and assert
- Assert.Equal(20, evaluator.EvaluateValueExpression("db(-10)", c));
+ Assert.Equal(20, evaluator.Evaluate("db(-10)", c, null, null));
}
[Fact]
@@ -345,7 +281,7 @@ public void Db()
var c = new SpiceExpressionContext(SpiceExpressionMode.Spice3f5);
// act and assert
- Assert.Equal(-20, evaluator.EvaluateValueExpression("db(-10)", c));
+ Assert.Equal(-20, evaluator.Evaluate("db(-10)", c, null, null));
}
[Fact]
@@ -356,18 +292,7 @@ public void Exp()
var c = new SpiceExpressionContext(SpiceExpressionMode.Spice3f5);
// act and assert
- Assert.Equal(Math.Exp(2), evaluator.EvaluateValueExpression("exp(2)", c));
- }
-
- [Fact]
- public void Fabs()
- {
- // arrange
- var evaluator = new Evaluator();
- var c = new SpiceExpressionContext(SpiceExpressionMode.Spice3f5);
-
- // act and assert
- Assert.Equal(3, evaluator.EvaluateValueExpression("fabs(-3)", c));
+ Assert.Equal(Math.Exp(2), evaluator.Evaluate("exp(2)", c, null, null));
}
[Fact]
@@ -378,7 +303,7 @@ public void Flat()
var c = new SpiceExpressionContext(SpiceExpressionMode.Spice3f5);
// act
- var res = evaluator.EvaluateValueExpression("flat(10)", c);
+ var res = evaluator.Evaluate("flat(10)", c, null, null);
// assert
Assert.True(res >= -10 && res <= 10);
@@ -392,7 +317,7 @@ public void Floor()
var c = new SpiceExpressionContext(SpiceExpressionMode.Spice3f5);
// act and assert
- Assert.Equal(2, evaluator.EvaluateValueExpression("floor(2.3)", c));
+ Assert.Equal(2, evaluator.Evaluate("floor(2.3)", c, null, null));
}
[Fact]
@@ -403,7 +328,7 @@ public void Hypot()
var c = new SpiceExpressionContext(SpiceExpressionMode.Spice3f5);
// act and assert
- Assert.Equal(5, evaluator.EvaluateValueExpression("hypot(3,4)", c));
+ Assert.Equal(5, evaluator.Evaluate("hypot(3,4)", c, null, null));
}
[Fact]
@@ -414,7 +339,7 @@ public void Gauss()
var c = new SpiceExpressionContext(SpiceExpressionMode.Spice3f5);
// act and assert
- evaluator.EvaluateValueExpression("gauss(1.2)", c);
+ evaluator.Evaluate("gauss(1.2)", c, null, null);
}
[Fact]
@@ -425,7 +350,7 @@ public void ExtendedGauss()
var c = new SpiceExpressionContext(SpiceExpressionMode.Spice3f5);
// act and assert
- evaluator.EvaluateValueExpression("gauss(1, 2.3, 4.5)", c);
+ evaluator.Evaluate("gauss(1, 2.3, 4.5)", c, null, null);
}
[Fact]
@@ -436,7 +361,7 @@ public void ExtendedGauss_TooManyArguments()
var c = new SpiceExpressionContext(SpiceExpressionMode.Spice3f5);
// act and assert
- Assert.Throws(() => evaluator.EvaluateValueExpression("gauss(1, 2.3, 4.5, 0)", c));
+ Assert.Throws(() => evaluator.Evaluate("gauss(1, 2.3, 4.5, 0)", c, null, null));
}
[Fact]
@@ -447,8 +372,8 @@ public void If()
var c = new SpiceExpressionContext(SpiceExpressionMode.Spice3f5);
// act and assert
- Assert.Equal(3, evaluator.EvaluateValueExpression("if(0.5, 2, 3)", c));
- Assert.Equal(2, evaluator.EvaluateValueExpression("if(0.6, 2, 3)", c));
+ Assert.Equal(3, evaluator.Evaluate("if(0.5, 2, 3)", c, null, null));
+ Assert.Equal(2, evaluator.Evaluate("if(0.6, 2, 3)", c, null, null));
}
[Fact]
@@ -459,7 +384,7 @@ public void Int()
var c = new SpiceExpressionContext(SpiceExpressionMode.Spice3f5);
// act and assert
- Assert.Equal(1, evaluator.EvaluateValueExpression("int(1.3)", c));
+ Assert.Equal(1, evaluator.Evaluate("int(1.3)", c, null, null));
}
[Fact]
@@ -470,8 +395,8 @@ public void Inv()
var c = new SpiceExpressionContext(SpiceExpressionMode.Spice3f5);
// act and assert
- Assert.Equal(0, evaluator.EvaluateValueExpression("inv(0.51)", c));
- Assert.Equal(1, evaluator.EvaluateValueExpression("inv(0.5)", c));
+ Assert.Equal(0, evaluator.Evaluate("inv(0.51)", c, null, null));
+ Assert.Equal(1, evaluator.Evaluate("inv(0.5)", c, null, null));
}
[Fact]
@@ -482,7 +407,7 @@ public void Ln()
var c = new SpiceExpressionContext(SpiceExpressionMode.Spice3f5);
// act and assert
- Assert.Equal(1, evaluator.EvaluateValueExpression("ln(e)", c));
+ Assert.Equal(1, evaluator.Evaluate("ln(e)", c, null, null));
}
[Fact]
@@ -493,9 +418,9 @@ public void Limit()
var c = new SpiceExpressionContext(SpiceExpressionMode.Spice3f5);
// act and assert
- Assert.Equal(8, evaluator.EvaluateValueExpression("limit(10, 1, 8)", c));
- Assert.Equal(1, evaluator.EvaluateValueExpression("limit(-1, 1, 8)", c));
- Assert.Equal(4, evaluator.EvaluateValueExpression("limit(4, 1, 8)", c));
+ Assert.Equal(8, evaluator.Evaluate("limit(10, 1, 8)", c, null, null));
+ Assert.Equal(1, evaluator.Evaluate("limit(-1, 1, 8)", c, null, null));
+ Assert.Equal(4, evaluator.Evaluate("limit(4, 1, 8)", c, null, null));
}
[Fact]
@@ -506,7 +431,7 @@ public void Log()
var c = new SpiceExpressionContext(SpiceExpressionMode.Spice3f5);
// act and assert
- Assert.Equal(1, evaluator.EvaluateValueExpression("log(e)", c));
+ Assert.Equal(1, evaluator.Evaluate("log(e)", c, null, null));
}
[Fact]
@@ -517,7 +442,7 @@ public void Log10()
var c = new SpiceExpressionContext(SpiceExpressionMode.Spice3f5);
// act and assert
- Assert.Equal(1, evaluator.EvaluateValueExpression("log10(10)", c));
+ Assert.Equal(1, evaluator.Evaluate("log10(10)", c, null, null));
}
[Fact]
@@ -528,7 +453,7 @@ public void Max()
var c = new SpiceExpressionContext(SpiceExpressionMode.Spice3f5);
// act and assert
- Assert.Equal(100, evaluator.EvaluateValueExpression("max(10, -10, 1, 20, 100, 2)", c));
+ Assert.Equal(100, evaluator.Evaluate("max(10, -10, 1, 20, 100, 2)", c, null, null));
}
[Fact]
@@ -539,7 +464,7 @@ public void Min()
var c = new SpiceExpressionContext(SpiceExpressionMode.Spice3f5);
// act and assert
- Assert.Equal(-10, evaluator.EvaluateValueExpression("min(10, -10, 1, 20, 100, 2)", c));
+ Assert.Equal(-10, evaluator.Evaluate("min(10, -10, 1, 20, 100, 2)", c, null, null));
}
[Fact]
@@ -550,8 +475,8 @@ public void Nint()
var c = new SpiceExpressionContext(SpiceExpressionMode.Spice3f5);
// act and assert
- Assert.Equal(1, evaluator.EvaluateValueExpression("nint(1.2)", c));
- Assert.Equal(2, evaluator.EvaluateValueExpression("nint(1.9)", c));
+ Assert.Equal(1, evaluator.Evaluate("nint(1.2)", c, null, null));
+ Assert.Equal(2, evaluator.Evaluate("nint(1.9)", c, null, null));
}
[Fact]
@@ -562,8 +487,8 @@ public void URamp()
var c = new SpiceExpressionContext(SpiceExpressionMode.Spice3f5);
// act and assert
- Assert.Equal(1.2, evaluator.EvaluateValueExpression("uramp(1.2)", c));
- Assert.Equal(0, evaluator.EvaluateValueExpression("uramp(-0.1)", c));
+ Assert.Equal(1.2, evaluator.Evaluate("uramp(1.2)", c, null, null));
+ Assert.Equal(0, evaluator.Evaluate("uramp(-0.1)", c, null, null));
}
[Fact]
@@ -573,8 +498,8 @@ public void U()
var evaluator = new Evaluator();
var c = new SpiceExpressionContext(SpiceExpressionMode.Spice3f5);
- Assert.Equal(1, evaluator.EvaluateValueExpression("u(1.2)", c));
- Assert.Equal(0, evaluator.EvaluateValueExpression("u(-1)", c));
+ Assert.Equal(1, evaluator.Evaluate("u(1.2)", c, null, null));
+ Assert.Equal(0, evaluator.Evaluate("u(-1)", c, null, null));
}
[Fact]
@@ -585,7 +510,7 @@ public void UnitInExpression()
var c = new SpiceExpressionContext(SpiceExpressionMode.Spice3f5);
// act and assert
- Assert.Equal(100 * 1000, evaluator.EvaluateValueExpression("300kHz/3", c));
+ Assert.Equal(100 * 1000, evaluator.Evaluate("300kHz/3", c, null, null));
}
[Fact]
@@ -600,13 +525,13 @@ public void Fibonacci()
new System.Collections.Generic.List() { "x" },
"x <= 0 ? 0 : (x == 1 ? 1 : (fib(x-1) + fib(x-2)))"));
- Assert.Equal(0, p.EvaluateValueExpression("fib(0)", c));
- Assert.Equal(1, p.EvaluateValueExpression("fib(1)", c));
- Assert.Equal(1, p.EvaluateValueExpression("fib(2)", c));
- Assert.Equal(2, p.EvaluateValueExpression("fib(3)", c));
- Assert.Equal(3, p.EvaluateValueExpression("fib(4)", c));
- Assert.Equal(5, p.EvaluateValueExpression("fib(5)", c));
- Assert.Equal(8, p.EvaluateValueExpression("fib(6)", c));
+ Assert.Equal(0, p.Evaluate("fib(0)", c, null, null));
+ Assert.Equal(1, p.Evaluate("fib(1)", c, null, null));
+ Assert.Equal(1, p.Evaluate("fib(2)", c, null, null));
+ Assert.Equal(2, p.Evaluate("fib(3)", c, null, null));
+ Assert.Equal(3, p.Evaluate("fib(4)", c, null, null));
+ Assert.Equal(5, p.Evaluate("fib(5)", c, null, null));
+ Assert.Equal(8, p.Evaluate("fib(6)", c, null, null));
}
[Fact]
@@ -614,7 +539,7 @@ public void PolyThreeVariablesSum()
{
var c = new SpiceExpressionContext(SpiceExpressionMode.Spice3f5);
var p = new Evaluator();
- Assert.Equal(15, p.EvaluateValueExpression("poly(3, 3, 5, 7, 0, 1, 1, 1)", c));
+ Assert.Equal(15, p.Evaluate("poly(3, 3, 5, 7, 0, 1, 1, 1)", c, null, null));
}
[Fact]
@@ -622,7 +547,7 @@ public void PolyTwoVariablesSum()
{
var c = new SpiceExpressionContext(SpiceExpressionMode.Spice3f5);
var p = new Evaluator();
- Assert.Equal(3, p.EvaluateValueExpression("poly(2, 1, 2, 0, 1, 1)", c));
+ Assert.Equal(3, p.Evaluate("poly(2, 1, 2, 0, 1, 1)", c, null, null));
}
[Fact]
@@ -631,7 +556,7 @@ public void PolyTwoVariablesMult()
var c = new SpiceExpressionContext(SpiceExpressionMode.Spice3f5);
var p = new Evaluator();
var context = new SpiceExpressionContext(SpiceExpressionMode.Spice3f5);
- Assert.Equal(6, p.EvaluateValueExpression("poly(2, 3, 2, 0, 0, 0, 0, 1)", c));
+ Assert.Equal(6, p.Evaluate("poly(2, 3, 2, 0, 0, 0, 0, 1)", c, null, null));
}
[Fact]
@@ -639,7 +564,7 @@ public void PolyOneVariableSquare()
{
var c = new SpiceExpressionContext(SpiceExpressionMode.Spice3f5);
var p = new Evaluator();
- Assert.Equal(4, p.EvaluateValueExpression("poly(1, 2, 0, 0, 1)", c));
+ Assert.Equal(4, p.Evaluate("poly(1, 2, 0, 0, 1)", c, null, null));
}
[Fact]
@@ -647,7 +572,7 @@ public void PolyOneVariablePowerOfThree()
{
var c = new SpiceExpressionContext(SpiceExpressionMode.Spice3f5);
var p = new Evaluator();
- Assert.Equal(8, p.EvaluateValueExpression("poly(1, 2, 0, 0, 0, 1)", c));
+ Assert.Equal(8, p.Evaluate("poly(1, 2, 0, 0, 0, 1)", c, null, null));
}
[Fact]
@@ -655,7 +580,7 @@ public void PolyOneVariableMultiple()
{
var c = new SpiceExpressionContext(SpiceExpressionMode.Spice3f5);
var p = new Evaluator();
- Assert.Equal(4, p.EvaluateValueExpression("poly(1, 2, 0, 2)", c));
+ Assert.Equal(4, p.Evaluate("poly(1, 2, 0, 2)", c, null, null));
}
[Fact]
@@ -663,7 +588,7 @@ public void PolyOneVariableSquerePlusConstant()
{
var c = new SpiceExpressionContext(SpiceExpressionMode.Spice3f5);
var p = new Evaluator();
- Assert.Equal(14, p.EvaluateValueExpression("poly(1, 2, 10, 0, 1)", c));
+ Assert.Equal(14, p.Evaluate("poly(1, 2, 10, 0, 1)", c, null, null));
}
}
}
diff --git a/src/SpiceSharpParser.Tests/ModelReaders/Spice/Readers/Controls/OptionTests.cs b/src/SpiceSharpParser.Tests/ModelReaders/Spice/Readers/Controls/OptionTests.cs
index 234dd601..05a84458 100644
--- a/src/SpiceSharpParser.Tests/ModelReaders/Spice/Readers/Controls/OptionTests.cs
+++ b/src/SpiceSharpParser.Tests/ModelReaders/Spice/Readers/Controls/OptionTests.cs
@@ -5,12 +5,14 @@
using Xunit;
using SpiceSharpParser.ModelReaders.Netlist.Spice.Readers.Controls;
using SpiceSharp;
+using SpiceSharp.Simulations;
using SpiceSharpParser.ModelReaders.Netlist.Spice;
using SpiceSharpParser.Common.Evaluation;
using SpiceSharpParser.ModelReaders.Netlist.Spice.Context.Names;
using SpiceSharpParser.ModelReaders.Netlist.Spice.Context.Updates;
using SpiceSharpParser.ModelReaders.Netlist.Spice.Evaluation;
-
+using SpiceSharpParser.Common.Evaluation.Expressions;
+
namespace SpiceSharpParser.Tests.ModelReaders.Spice.Readers.Controls.Simulations
{
public class OptionTests
@@ -38,8 +40,8 @@ public void Read()
};
var evaluator = Substitute.For();
- evaluator.EvaluateValueExpression("12.2", Arg.Any()).Returns(12.2);
- evaluator.EvaluateValueExpression("12.3", Arg.Any()).Returns(12.3);
+ evaluator.Evaluate(new ConstantExpression(12.2), Arg.Any(), Arg.Any(), Arg.Any()).Returns(12.2);
+ evaluator.Evaluate(new ConstantExpression(12.3), Arg.Any(), Arg.Any(), Arg.Any()).Returns(12.3);
var resultService = new ResultService(new SpiceNetlistReaderResult(new Circuit(), "title"));
var readingContext = new ReadingContext(
diff --git a/src/SpiceSharpParser.Tests/ModelReaders/Spice/Readers/Controls/StTests.cs b/src/SpiceSharpParser.Tests/ModelReaders/Spice/Readers/Controls/StTests.cs
index a459557d..c84252db 100644
--- a/src/SpiceSharpParser.Tests/ModelReaders/Spice/Readers/Controls/StTests.cs
+++ b/src/SpiceSharpParser.Tests/ModelReaders/Spice/Readers/Controls/StTests.cs
@@ -8,6 +8,7 @@
using SpiceSharp.Simulations;
using SpiceSharpParser.ModelReaders.Netlist.Spice;
using SpiceSharpParser.Common.Evaluation;
+using SpiceSharpParser.Common.Evaluation.Expressions;
using SpiceSharpParser.ModelReaders.Netlist.Spice.Context.Names;
using SpiceSharpParser.ModelReaders.Netlist.Spice.Context.Sweeps;
using SpiceSharpParser.ModelReaders.Netlist.Spice.Context.Updates;
@@ -34,8 +35,8 @@ public void LinDefault()
};
var evaluator = Substitute.For();
- evaluator.EvaluateValueExpression("1", Arg.Any()).Returns(1.0);
- evaluator.EvaluateValueExpression("5", Arg.Any()).Returns(5.0);
+ evaluator.Evaluate(new ConstantExpression(1), Arg.Any(), Arg.Any(), Arg.Any()).Returns(1.0);
+ evaluator.Evaluate(new ConstantExpression(5), Arg.Any(), Arg.Any(), Arg.Any()).Returns(5.0);
var resultService = new ResultService(
new SpiceNetlistReaderResult(new SpiceSharp.Circuit(), "title"));
@@ -90,8 +91,8 @@ public void Lin()
};
var evaluator = Substitute.For();
- evaluator.EvaluateValueExpression("1", Arg.Any()).Returns(1.0);
- evaluator.EvaluateValueExpression("5", Arg.Any()).Returns(5.0);
+ evaluator.Evaluate(new ConstantExpression(1.0), Arg.Any(), Arg.Any(), Arg.Any()).Returns(1.0);
+ evaluator.Evaluate(new ConstantExpression(5), Arg.Any(), Arg.Any(), Arg.Any()).Returns(5.0);
var resultService = new ResultService(
new SpiceNetlistReaderResult(new SpiceSharp.Circuit(), "title"));
@@ -146,8 +147,8 @@ public void Dec()
};
var evaluator = Substitute.For();
- evaluator.EvaluateValueExpression("1", Arg.Any()).Returns(1.0);
- evaluator.EvaluateValueExpression("16", Arg.Any()).Returns(16);
+ evaluator.Evaluate(new ConstantExpression(1), Arg.Any(), Arg.Any(), Arg.Any()).Returns(1.0);
+ evaluator.Evaluate(new ConstantExpression(16.0), Arg.Any(), Arg.Any(), Arg.Any()).Returns(16);
var resultService = new ResultService(
new SpiceNetlistReaderResult(new SpiceSharp.Circuit(), "title"));
@@ -202,8 +203,8 @@ public void Oct()
};
var evaluator = Substitute.For();
- evaluator.EvaluateValueExpression("1", Arg.Any()).Returns(1.0);
- evaluator.EvaluateValueExpression("16", Arg.Any()).Returns(16);
+ evaluator.Evaluate(new ConstantExpression(1.0), Arg.Any(), Arg.Any(), Arg.Any()).Returns(1.0);
+ evaluator.Evaluate(new ConstantExpression(16), Arg.Any(), Arg.Any(), Arg.Any()).Returns(16);
var resultService = new ResultService(
new SpiceNetlistReaderResult(new SpiceSharp.Circuit(), "title"));
@@ -258,7 +259,7 @@ public void List()
};
var evaluator = Substitute.For();
- evaluator.EvaluateValueExpression("1.0", Arg.Any()).Returns(1.0);
+ evaluator.Evaluate(new ConstantExpression(1.0), Arg.Any(), Arg.Any(), Arg.Any()).Returns(1.0);
var resultService = new ResultService(
new SpiceNetlistReaderResult(new SpiceSharp.Circuit(), "title"));
diff --git a/src/SpiceSharpParser.Tests/ModelReaders/Spice/Readers/EntityGenerators/Components/RLCGeneratorTests.cs b/src/SpiceSharpParser.Tests/ModelReaders/Spice/Readers/EntityGenerators/Components/RLCGeneratorTests.cs
index b2eefcc5..354f696b 100644
--- a/src/SpiceSharpParser.Tests/ModelReaders/Spice/Readers/EntityGenerators/Components/RLCGeneratorTests.cs
+++ b/src/SpiceSharpParser.Tests/ModelReaders/Spice/Readers/EntityGenerators/Components/RLCGeneratorTests.cs
@@ -136,7 +136,7 @@ public void GenerateCapacitorWithIC()
true
)).Do(x =>
{
- ((Entity)x[0]).SetParameter(((string)x[1]).ToLower(), evaluator.EvaluateValueExpression((string)x[2], new SpiceSharpParser.Common.Evaluation.ExpressionContext()));
+ ((Entity)x[0]).SetParameter(((string)x[1]).ToLower(), evaluator.Evaluate((string)x[2], new SpiceSharpParser.Common.Evaluation.ExpressionContext(), null, null));
});
var parameters = new ParameterCollection
@@ -171,7 +171,7 @@ public void GenerateSemicondutorCapacitor()
true
)).Do(x =>
{
- ((Entity)x[0]).SetParameter(((string)x[1]).ToLower(), evaluator.EvaluateValueExpression((string)x[2], new SpiceSharpParser.Common.Evaluation.ExpressionContext()));
+ ((Entity)x[0]).SetParameter(((string)x[1]).ToLower(), evaluator.Evaluate((string)x[2], new SpiceSharpParser.Common.Evaluation.ExpressionContext(), null, null));
});
context.ModelsRegistry.FindModel(Arg.Any()).Returns(new CapacitorModel("CModel"));
diff --git a/src/SpiceSharpParser/Common/Evaluation/EvaluatedArgs.cs b/src/SpiceSharpParser/Common/Evaluation/EvaluatedArgs.cs
deleted file mode 100644
index 58a9b790..00000000
--- a/src/SpiceSharpParser/Common/Evaluation/EvaluatedArgs.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-using System;
-
-namespace SpiceSharpParser.Common.Evaluation
-{
- public class EvaluatedArgs : EventArgs
- {
- public double NewValue { get; set; }
- }
-}
diff --git a/src/SpiceSharpParser/Common/Evaluation/Evaluator.cs b/src/SpiceSharpParser/Common/Evaluation/Evaluator.cs
index 0434dc39..dcc2e7c0 100644
--- a/src/SpiceSharpParser/Common/Evaluation/Evaluator.cs
+++ b/src/SpiceSharpParser/Common/Evaluation/Evaluator.cs
@@ -1,5 +1,6 @@
using System;
using SpiceSharp.Simulations;
+using SpiceSharpParser.Common.Evaluation.Expressions;
using SpiceSharpParser.ModelReaders.Netlist.Spice.Context;
using SpiceSharpParser.Parsers.Expression;
@@ -38,7 +39,7 @@ public Evaluator(string name)
///
/// A double value.
///
- public double EvaluateValueExpression(string expression, ExpressionContext context, Simulation simulation = null, IReadingContext readingContext = null)
+ public double Evaluate(string expression, ExpressionContext context, Simulation simulation, IReadingContext readingContext)
{
if (expression == null)
{
@@ -49,13 +50,27 @@ public double EvaluateValueExpression(string expression, ExpressionContext conte
{
throw new ArgumentNullException(nameof(context));
}
+ return ExpressionParserHelpers.GetExpressionValue(expression, context, this, simulation, readingContext, false);
+ }
- if (context.Parameters.TryGetValue(expression, out var parameter))
+ public double Evaluate(Expression expression, ExpressionContext context, Simulation simulation, IReadingContext readingContext)
+ {
+ if (expression == null)
{
- return parameter.Evaluate(this, context, simulation, readingContext);
+ throw new ArgumentNullException(nameof(expression));
}
- return ExpressionParserHelpers.GetExpressionValue(expression, context, this, simulation, readingContext, false);
+ if (context == null)
+ {
+ throw new ArgumentNullException(nameof(context));
+ }
+
+ if (expression is ConstantExpression ce)
+ {
+ return ce.Value;
+ }
+
+ return Evaluate(expression.ValueExpression, context, simulation, readingContext);
}
}
}
diff --git a/src/SpiceSharpParser/Common/Evaluation/Expression.cs b/src/SpiceSharpParser/Common/Evaluation/Expression.cs
index 27f449ed..25ec917a 100644
--- a/src/SpiceSharpParser/Common/Evaluation/Expression.cs
+++ b/src/SpiceSharpParser/Common/Evaluation/Expression.cs
@@ -1,88 +1,32 @@
using System;
-using SpiceSharp.Simulations;
-using SpiceSharpParser.ModelReaders.Netlist.Spice.Context;
namespace SpiceSharpParser.Common.Evaluation
{
///
/// An evaluator expression.
///
- public class Expression
+ public abstract class Expression
{
///
/// Initializes a new instance of the class.
///
/// Expression.
- public Expression(string expression)
+ protected Expression(string expression)
{
ValueExpression = expression ?? throw new ArgumentNullException(nameof(expression));
}
- ///
- /// Thrown when expression is evaluated.
- ///
- public event EventHandler Evaluated;
-
///
/// Gets the expression string.
///
public string ValueExpression { get; }
- ///
- /// Gets or sets the current evaluation value.
- ///
- public double CurrentValue { get; protected set; } = double.NaN;
-
- ///
- /// Evaluates the expression.
- ///
- /// Evaluator.
- /// Context.
- ///
- ///
- ///
- /// The value of the expression.
- ///
- public virtual double Evaluate(IEvaluator evaluator, ExpressionContext context, Simulation simulation, IReadingContext readingContext)
- {
- if (evaluator == null)
- {
- throw new ArgumentNullException(nameof(evaluator));
- }
-
- if (context == null)
- {
- throw new ArgumentNullException(nameof(context));
- }
-
- var newValue = evaluator.EvaluateValueExpression(ValueExpression, context, simulation, readingContext);
- CurrentValue = newValue;
- OnEvaluated(newValue);
- return newValue;
- }
-
- ///
- /// Invalidates the expression.
- ///
- public virtual void Invalidate()
- {
- CurrentValue = double.NaN;
- }
-
///
/// Clones the expression.
///
///
/// A cloned expression.
///
- public virtual Expression Clone()
- {
- return new Expression(ValueExpression);
- }
-
- protected void OnEvaluated(double newValue)
- {
- Evaluated?.Invoke(this, new EvaluatedArgs() { NewValue = newValue });
- }
+ public abstract Expression Clone();
}
}
diff --git a/src/SpiceSharpParser/Common/Evaluation/ExpressionContext.cs b/src/SpiceSharpParser/Common/Evaluation/ExpressionContext.cs
index 574ac657..9a0c2e6a 100644
--- a/src/SpiceSharpParser/Common/Evaluation/ExpressionContext.cs
+++ b/src/SpiceSharpParser/Common/Evaluation/ExpressionContext.cs
@@ -120,8 +120,6 @@ public void SetParameter(string parameterName, double value)
Parameters[parameterName] = parameter;
ExpressionRegistry.AddOrUpdate(parameterName, parameter);
- ExpressionRegistry.InvalidateDependentParameters(parameterName);
- ExpressionRegistry.InvalidateExpressions(parameterName);
foreach (var child in Children)
{
@@ -152,34 +150,7 @@ public void SetParameter(string parameterName, string expression, ICollection
- /// Sets the cached parameter.
- ///
- /// A name of parameter.
- /// An expression of parameter.
- /// Parameters in expression.
- public void SetCachedParameter(string parameterName, string expression, ICollection expressionParameters)
- {
- if (parameterName == null)
- {
- throw new ArgumentNullException(nameof(parameterName));
- }
-
- if (expression == null)
- {
- throw new ArgumentNullException(nameof(expression));
- }
-
- if (expressionParameters == null)
- {
- throw new ArgumentNullException(nameof(expressionParameters));
- }
-
- var parameter = new CachedExpression(expression);
+ var parameter = new DynamicExpression(expression);
SetParameter(parameterName, expression, expressionParameters, parameter);
}
@@ -227,14 +198,14 @@ public void SetNamedExpression(string expressionName, string expression, ICollec
///
/// Expression.
///
- public string GetExpression(string expressionName)
+ public Expression GetExpression(string expressionName)
{
if (expressionName == null)
{
throw new ArgumentNullException(nameof(expressionName));
}
- return ExpressionRegistry.GetExpression(expressionName)?.ValueExpression;
+ return ExpressionRegistry.GetExpression(expressionName);
}
///
@@ -360,15 +331,9 @@ public void AddFunction(string name, IFunction function)
public void CreateCommonFunctions()
{
- AddFunction("acos", MathFunctions.CreateACos());
- AddFunction("asin", MathFunctions.CreateASin());
- AddFunction("atan", MathFunctions.CreateATan());
AddFunction("atan2", MathFunctions.CreateATan2());
- AddFunction("cos", MathFunctions.CreateCos());
AddFunction("cosh", MathFunctions.CreateCosh());
- AddFunction("sin", MathFunctions.CreateSin());
AddFunction("sinh", MathFunctions.CreateSinh());
- AddFunction("tan", MathFunctions.CreateTan());
AddFunction("tanh", MathFunctions.CreateTanh());
}
@@ -378,8 +343,6 @@ protected void SetParameter(string parameterName, string expression, ICollection
ExpressionRegistry.AddOrUpdate(parameterName, parameter);
ExpressionRegistry.AddOrUpdateParameterDependencies(parameterName, expressionParameters);
- ExpressionRegistry.InvalidateDependentParameters(parameterName);
- ExpressionRegistry.InvalidateExpressions(parameterName);
foreach (var child in Children)
{
diff --git a/src/SpiceSharpParser/Common/Evaluation/ExpressionRegistry.cs b/src/SpiceSharpParser/Common/Evaluation/ExpressionRegistry.cs
index dbafee30..e22820e4 100644
--- a/src/SpiceSharpParser/Common/Evaluation/ExpressionRegistry.cs
+++ b/src/SpiceSharpParser/Common/Evaluation/ExpressionRegistry.cs
@@ -211,56 +211,6 @@ public void AddOrUpdateParameterDependencies(string parameterName, ICollection
- /// Refreshes the expressions in the registry that depends on the given parameter.
- ///
- /// Parameter name.
- public void InvalidateDependentParameters(string parameterName)
- {
- if (parameterName == null)
- {
- throw new ArgumentNullException(nameof(parameterName));
- }
-
- if (ParametersDependencies.ContainsKey(parameterName))
- {
- foreach (var parameter in ParametersDependencies[parameterName])
- {
- Parameters[parameter].Invalidate();
-
- InvalidateDependentParameters(parameter);
- }
- }
- }
-
- ///
- /// Refreshes the expressions in the registry that depends on the given parameter.
- ///
- /// Parameter name.
- public void InvalidateExpressions(string parameterName)
- {
- if (parameterName == null)
- {
- throw new ArgumentNullException(nameof(parameterName));
- }
-
- if (ParametersDependencies.ContainsKey(parameterName))
- {
- foreach (var parameter in ParametersDependencies[parameterName])
- {
- InvalidateExpressions(parameter);
- }
- }
-
- if (ParametersExpressionsDependencies.ContainsKey(parameterName))
- {
- foreach (var expression in ParametersExpressionsDependencies[parameterName])
- {
- expression.Invalidate();
- }
- }
- }
-
///
/// Clones the registry.
///
@@ -326,29 +276,5 @@ public ExpressionRegistry Clone()
return result;
}
-
- ///
- /// Invalidates the registry.
- ///
- public void Invalidate()
- {
- foreach (var exprDep in ParametersExpressionsDependencies)
- {
- foreach (var expr in exprDep.Value)
- {
- expr.Invalidate();
- }
- }
-
- foreach (var expression in NamedExpressions.Values)
- {
- expression.Invalidate();
- }
-
- foreach (var expression in UnnamedExpressions)
- {
- expression.Invalidate();
- }
- }
}
}
diff --git a/src/SpiceSharpParser/Common/Evaluation/Expressions/CachedExpression.cs b/src/SpiceSharpParser/Common/Evaluation/Expressions/CachedExpression.cs
deleted file mode 100644
index 6914e41c..00000000
--- a/src/SpiceSharpParser/Common/Evaluation/Expressions/CachedExpression.cs
+++ /dev/null
@@ -1,73 +0,0 @@
-using System;
-using SpiceSharp.Simulations;
-using SpiceSharpParser.ModelReaders.Netlist.Spice.Context;
-
-namespace SpiceSharpParser.Common.Evaluation.Expressions
-{
- public class CachedExpression : Expression
- {
- ///
- /// Initializes a new instance of the class.
- ///
- /// Expression string.
- public CachedExpression(string expression)
- : base(expression)
- {
- }
-
- ///
- /// Gets a value indicating whether value of cached expression has been computed.
- ///
- protected bool IsEvaluated { get; private set; }
-
- ///
- /// Evaluates the expression.
- ///
- /// Evaluator.
- /// Context.
- /// Simulation.
- /// Reading context.
- ///
- /// The value of the expression.
- ///
- public override double Evaluate(IEvaluator evaluator, ExpressionContext context, Simulation sim, IReadingContext readingContext)
- {
- if (evaluator == null)
- {
- throw new ArgumentNullException(nameof(evaluator));
- }
-
- if (context == null)
- {
- throw new ArgumentNullException(nameof(context));
- }
-
- if (!IsEvaluated)
- {
- CurrentValue = evaluator.EvaluateValueExpression(ValueExpression,context, sim, readingContext);
- IsEvaluated = true;
- }
-
- return CurrentValue;
- }
-
- ///
- /// Invalidate the expression.
- ///
- public override void Invalidate()
- {
- IsEvaluated = false;
- }
-
- ///
- /// Clones the cached expression.
- ///
- ///
- /// A cloned cached expression.
- ///
- public override Expression Clone()
- {
- return new CachedExpression(ValueExpression) { CurrentValue = CurrentValue, IsEvaluated = true };
- }
- }
-}
diff --git a/src/SpiceSharpParser/Common/Evaluation/Expressions/ConstantExpression.cs b/src/SpiceSharpParser/Common/Evaluation/Expressions/ConstantExpression.cs
index 955b2555..2783451f 100644
--- a/src/SpiceSharpParser/Common/Evaluation/Expressions/ConstantExpression.cs
+++ b/src/SpiceSharpParser/Common/Evaluation/Expressions/ConstantExpression.cs
@@ -1,8 +1,4 @@
-using System;
-using SpiceSharp.Simulations;
-using SpiceSharpParser.ModelReaders.Netlist.Spice.Context;
-
-namespace SpiceSharpParser.Common.Evaluation.Expressions
+namespace SpiceSharpParser.Common.Evaluation.Expressions
{
public class ConstantExpression : Expression
{
@@ -10,12 +6,13 @@ public class ConstantExpression : Expression
/// Initializes a new instance of the class.
///
/// Value.
- public ConstantExpression(double value)
- : base(string.Empty)
+ public ConstantExpression(double value) : base(string.Empty)
{
- CurrentValue = value;
+ Value = value;
}
+ public double Value { get; }
+
///
/// Clones the named expression.
///
@@ -24,26 +21,7 @@ public ConstantExpression(double value)
///
public override Expression Clone()
{
- return new ConstantExpression(CurrentValue);
- }
-
- public override void Invalidate()
- {
- }
-
- public override double Evaluate(IEvaluator evaluator, ExpressionContext context, Simulation sim, IReadingContext readingContext)
- {
- if (evaluator == null)
- {
- throw new ArgumentNullException(nameof(evaluator));
- }
-
- if (context == null)
- {
- throw new ArgumentNullException(nameof(context));
- }
-
- return CurrentValue;
+ return new ConstantExpression(Value);
}
}
}
diff --git a/src/SpiceSharpParser/Common/Evaluation/Expressions/DynamicExpression.cs b/src/SpiceSharpParser/Common/Evaluation/Expressions/DynamicExpression.cs
new file mode 100644
index 00000000..824cedca
--- /dev/null
+++ b/src/SpiceSharpParser/Common/Evaluation/Expressions/DynamicExpression.cs
@@ -0,0 +1,14 @@
+namespace SpiceSharpParser.Common.Evaluation.Expressions
+{
+ public class DynamicExpression : Expression
+ {
+ public DynamicExpression(string expression) : base(expression)
+ {
+ }
+
+ public override Expression Clone()
+ {
+ return new DynamicExpression(ValueExpression);
+ }
+ }
+}
diff --git a/src/SpiceSharpParser/Common/Evaluation/Function.cs b/src/SpiceSharpParser/Common/Evaluation/Function.cs
index caa9efb3..996404f9 100644
--- a/src/SpiceSharpParser/Common/Evaluation/Function.cs
+++ b/src/SpiceSharpParser/Common/Evaluation/Function.cs
@@ -15,11 +15,6 @@ public abstract class Function : IFunction
public int ArgumentsCount { get; set; }
- ///
- /// Gets or sets a value indicating whether function is infix.
- ///
- public bool Infix { get; set; }
-
///
/// Computes the value of the function for given arguments.
///
diff --git a/src/SpiceSharpParser/Common/Evaluation/Functions/ExpressionFunction.cs b/src/SpiceSharpParser/Common/Evaluation/Functions/ExpressionFunction.cs
index 59251e12..4f7d28a1 100644
--- a/src/SpiceSharpParser/Common/Evaluation/Functions/ExpressionFunction.cs
+++ b/src/SpiceSharpParser/Common/Evaluation/Functions/ExpressionFunction.cs
@@ -76,6 +76,11 @@ public Derivatives> Derivative(string image, double[] args, IEvalua
throw new ArgumentNullException(nameof(context));
}
+ if (readingContext == null)
+ {
+ throw new ArgumentNullException(nameof(readingContext));
+ }
+
var childContext = context.CreateChildContext(string.Empty, false);
for (var i = 0; i < Arguments.Count; i++)
{
@@ -83,7 +88,7 @@ public Derivatives> Derivative(string image, double[] args, IEvalua
childContext.Arguments.Add(Arguments[i], new ConstantExpression(args[i]));
}
- var parser = ExpressionParserHelpers.GetDeriveParser(childContext, readingContext, evaluator, simulation);
+ var parser = ExpressionParserHelpers.GetDeriveParser(childContext, readingContext, evaluator, simulation, readingContext.CaseSensitivity);
var parseResult = parser.Parse(Expression);
return parseResult;
}
diff --git a/src/SpiceSharpParser/Common/Evaluation/Functions/Math/ACosFunction.cs b/src/SpiceSharpParser/Common/Evaluation/Functions/Math/ACosFunction.cs
deleted file mode 100644
index 48cb5f12..00000000
--- a/src/SpiceSharpParser/Common/Evaluation/Functions/Math/ACosFunction.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-using System;
-using SpiceSharp.Simulations;
-using SpiceSharpParser.ModelReaders.Netlist.Spice.Context;
-
-namespace SpiceSharpParser.Common.Evaluation.Functions.Math
-{
- public class ACosFunction : Function
- {
- public ACosFunction()
- {
- Name = "acos";
- ArgumentsCount = 1;
- }
-
- public override double Logic(string image, double[] args, IEvaluator evaluator, ExpressionContext context, Simulation simulation = null, IReadingContext readingContext = null)
- {
- if (args.Length != 1)
- {
- throw new ArgumentException("acos() function expects one argument");
- }
-
- double d = args[0];
- return System.Math.Acos(d);
- }
- }
-}
diff --git a/src/SpiceSharpParser/Common/Evaluation/Functions/Math/ASinFunction.cs b/src/SpiceSharpParser/Common/Evaluation/Functions/Math/ASinFunction.cs
deleted file mode 100644
index 7bfac2b7..00000000
--- a/src/SpiceSharpParser/Common/Evaluation/Functions/Math/ASinFunction.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-using System;
-using SpiceSharp.Simulations;
-using SpiceSharpParser.ModelReaders.Netlist.Spice.Context;
-
-namespace SpiceSharpParser.Common.Evaluation.Functions.Math
-{
- public class ASinFunction : Function
- {
- public ASinFunction()
- {
- Name = "asin";
- ArgumentsCount = 1;
- }
-
- public override double Logic(string image, double[] args, IEvaluator evaluator, ExpressionContext context, Simulation simulation = null, IReadingContext readingContext = null)
- {
- if (args.Length != 1)
- {
- throw new ArgumentException("asin() function expects one argument");
- }
-
- double d = args[0];
- return System.Math.Asin(d);
- }
- }
-}
diff --git a/src/SpiceSharpParser/Common/Evaluation/Functions/Math/ATanFunction.cs b/src/SpiceSharpParser/Common/Evaluation/Functions/Math/ATanFunction.cs
deleted file mode 100644
index 309d5776..00000000
--- a/src/SpiceSharpParser/Common/Evaluation/Functions/Math/ATanFunction.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-using System;
-using SpiceSharp.Simulations;
-using SpiceSharpParser.ModelReaders.Netlist.Spice.Context;
-
-namespace SpiceSharpParser.Common.Evaluation.Functions.Math
-{
- public class ATanFunction : Function
- {
- public ATanFunction()
- {
- Name = "atan";
- ArgumentsCount = 1;
- }
-
- public override double Logic(string image, double[] args, IEvaluator evaluator, ExpressionContext context, Simulation simulation = null, IReadingContext readingContext = null)
- {
- if (args.Length != 1)
- {
- throw new ArgumentException("atan() function expects one argument");
- }
-
- double d = args[0];
- return System.Math.Atan(d);
- }
- }
-}
diff --git a/src/SpiceSharpParser/Common/Evaluation/Functions/Math/CosFunction.cs b/src/SpiceSharpParser/Common/Evaluation/Functions/Math/CosFunction.cs
deleted file mode 100644
index 12f56624..00000000
--- a/src/SpiceSharpParser/Common/Evaluation/Functions/Math/CosFunction.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-using System;
-using SpiceSharp.Simulations;
-using SpiceSharpParser.ModelReaders.Netlist.Spice.Context;
-
-namespace SpiceSharpParser.Common.Evaluation.Functions.Math
-{
- public class CosFunction : Function
- {
- public CosFunction()
- {
- Name = "cos";
- ArgumentsCount = 1;
- }
-
- public override double Logic(string image, double[] args, IEvaluator evaluator, ExpressionContext context, Simulation simulation = null, IReadingContext readingContext = null)
- {
- if (args.Length != 1)
- {
- throw new ArgumentException("cos() function expects one argument");
- }
-
- double d = args[0];
- return System.Math.Cos(d);
- }
- }
-}
diff --git a/src/SpiceSharpParser/Common/Evaluation/Functions/Math/SinFunction.cs b/src/SpiceSharpParser/Common/Evaluation/Functions/Math/SinFunction.cs
deleted file mode 100644
index 67a4e09b..00000000
--- a/src/SpiceSharpParser/Common/Evaluation/Functions/Math/SinFunction.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-using System;
-using SpiceSharp.Simulations;
-using SpiceSharpParser.ModelReaders.Netlist.Spice.Context;
-
-namespace SpiceSharpParser.Common.Evaluation.Functions.Math
-{
- public class SinFunction : Function
- {
- public SinFunction()
- {
- Name = "sin";
- ArgumentsCount = 1;
- }
-
- public override double Logic(string image, double[] args, IEvaluator evaluator, ExpressionContext context, Simulation simulation = null, IReadingContext readingContext = null)
- {
- if (args.Length != 1)
- {
- throw new ArgumentException("sin() function expects one argument");
- }
-
- double d = args[0];
- return System.Math.Sin(d);
- }
- }
-}
diff --git a/src/SpiceSharpParser/Common/Evaluation/Functions/Math/TanFunction.cs b/src/SpiceSharpParser/Common/Evaluation/Functions/Math/TanFunction.cs
deleted file mode 100644
index a14d7165..00000000
--- a/src/SpiceSharpParser/Common/Evaluation/Functions/Math/TanFunction.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-using System;
-using SpiceSharp.Simulations;
-using SpiceSharpParser.ModelReaders.Netlist.Spice.Context;
-
-namespace SpiceSharpParser.Common.Evaluation.Functions.Math
-{
- public class TanFunction : Function
- {
- public TanFunction()
- {
- Name = "tan";
- ArgumentsCount = 1;
- }
-
- public override double Logic(string image, double[] args, IEvaluator evaluator, ExpressionContext context, Simulation simulation = null, IReadingContext readingContext = null)
- {
- if (args.Length != 1)
- {
- throw new ArgumentException("tan() function expects one argument");
- }
-
- double d = args[0];
- return System.Math.Tan(d);
- }
- }
-}
diff --git a/src/SpiceSharpParser/Common/Evaluation/Functions/MathFunctions.cs b/src/SpiceSharpParser/Common/Evaluation/Functions/MathFunctions.cs
index c5c704eb..5352f2f6 100644
--- a/src/SpiceSharpParser/Common/Evaluation/Functions/MathFunctions.cs
+++ b/src/SpiceSharpParser/Common/Evaluation/Functions/MathFunctions.cs
@@ -4,39 +4,6 @@ namespace SpiceSharpParser.Common.Evaluation.Functions
{
public class MathFunctions
{
- ///
- /// Get a cos() function.
- ///
- ///
- /// A new instance of cos() function.
- ///
- public static IFunction CreateCos()
- {
- return new CosFunction();
- }
-
- ///
- /// Get a sin() function.
- ///
- ///
- /// A new instance of sin() function.
- ///
- public static IFunction CreateSin()
- {
- return new SinFunction();
- }
-
- ///
- /// Get a tan() function.
- ///
- ///
- /// A new instance of tan() function.
- ///
- public static IFunction CreateTan()
- {
- return new TanFunction();
- }
-
///
/// Get a cosh() function.
///
@@ -70,39 +37,6 @@ public static IFunction CreateTanh()
return new TanhFunction();
}
- ///
- /// Get a acos() function.
- ///
- ///
- /// A new instance of acos() function.
- ///
- public static IFunction CreateACos()
- {
- return new ACosFunction();
- }
-
- ///
- /// Get a asin() function.
- ///
- ///
- /// A new instance of asin() function.
- ///
- public static IFunction CreateASin()
- {
- return new ASinFunction();
- }
-
- ///
- /// Get a atan() function.
- ///
- ///
- /// A new instance of atan() function.
- ///
- public static IFunction CreateATan()
- {
- return new ATanFunction();
- }
-
///
/// Get a atan() function.
///
diff --git a/src/SpiceSharpParser/Common/Evaluation/IEvaluator.cs b/src/SpiceSharpParser/Common/Evaluation/IEvaluator.cs
index 78ecb02e..96171ebe 100644
--- a/src/SpiceSharpParser/Common/Evaluation/IEvaluator.cs
+++ b/src/SpiceSharpParser/Common/Evaluation/IEvaluator.cs
@@ -8,6 +8,6 @@ namespace SpiceSharpParser.Common.Evaluation
///
public interface IEvaluator
{
- double EvaluateValueExpression(string expression, ExpressionContext context, Simulation simulation = null, IReadingContext readingContext = null);
+ double Evaluate(Expression expression, ExpressionContext context, Simulation simulation, IReadingContext readingContext);
}
}
diff --git a/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Context/ReadingContext.cs b/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Context/ReadingContext.cs
index 1319989e..f1fa780f 100644
--- a/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Context/ReadingContext.cs
+++ b/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Context/ReadingContext.cs
@@ -5,6 +5,7 @@
using SpiceSharp.Circuits;
using SpiceSharpParser.Common;
using SpiceSharpParser.Common.Evaluation;
+using SpiceSharpParser.Common.Evaluation.Expressions;
using SpiceSharpParser.ModelReaders.Netlist.Spice.Context.Models;
using SpiceSharpParser.ModelReaders.Netlist.Spice.Context.Names;
using SpiceSharpParser.ModelReaders.Netlist.Spice.Exceptions;
@@ -210,7 +211,7 @@ public double EvaluateDouble(string expression)
}
try
{
- return ReadingEvaluator.EvaluateValueExpression(expression, ReadingExpressionContext);
+ return ReadingEvaluator.Evaluate(new DynamicExpression(expression), ReadingExpressionContext, null, this);
}
catch (Exception ex)
{
@@ -296,7 +297,8 @@ public void SetParameter(string parameterName, string expression)
throw new ArgumentNullException(nameof(expression));
}
- var parameters = ExpressionParserHelpers.GetExpressionParameters(expression, ReadingExpressionContext, this, false);
+ var parameters = ExpressionParserHelpers.GetExpressionParameters(expression, ReadingExpressionContext, this, CaseSensitivity, false);
+
ReadingExpressionContext.SetParameter(
parameterName,
expression,
@@ -335,7 +337,7 @@ public void SetNamedExpression(string expressionName, string expression)
throw new ArgumentNullException(nameof(expression));
}
- var parameters = ExpressionParserHelpers.GetExpressionParameters(expression, ReadingExpressionContext, this, false);
+ var parameters = ExpressionParserHelpers.GetExpressionParameters(expression, ReadingExpressionContext, this, CaseSensitivity, false);
ReadingExpressionContext.SetNamedExpression(expressionName, expression, parameters);
}
@@ -358,7 +360,7 @@ public void SetParameter(Entity entity, string parameterName, string expression,
IEqualityComparer comparer = StringComparerProvider.Get(CaseSensitivity.IsEntityParameterNameCaseSensitive);
- double value = ReadingEvaluator.EvaluateValueExpression(expression, ReadingExpressionContext, null, this);
+ double value = ReadingEvaluator.Evaluate(new DynamicExpression(expression), ReadingExpressionContext, null, this);
try
{
@@ -370,8 +372,8 @@ public void SetParameter(Entity entity, string parameterName, string expression,
}
bool isDynamic = ExpressionParserHelpers.HaveSpiceProperties(expression, ReadingExpressionContext, this, false)
- || ExpressionParserHelpers.HaveFunctions(expression, ReadingExpressionContext, this, false)
- || ExpressionParserHelpers.GetExpressionParameters(expression, ReadingExpressionContext, this, false).Any();
+ || ExpressionParserHelpers.HaveFunctions(expression, ReadingExpressionContext, this)
+ || ExpressionParserHelpers.GetExpressionParameters(expression, ReadingExpressionContext, this, CaseSensitivity, false).Any();
if (isDynamic)
{
diff --git a/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Context/SimulationPreparations.cs b/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Context/SimulationPreparations.cs
index 6cf22795..59db532b 100644
--- a/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Context/SimulationPreparations.cs
+++ b/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Context/SimulationPreparations.cs
@@ -3,6 +3,7 @@
using SpiceSharp.Behaviors;
using SpiceSharp.Circuits;
using SpiceSharp.Simulations;
+using SpiceSharpParser.Common.Evaluation.Expressions;
using SpiceSharpParser.ModelReaders.Netlist.Spice.Context.Updates;
namespace SpiceSharpParser.ModelReaders.Netlist.Spice.Context
@@ -57,7 +58,7 @@ public void SetNodeSetVoltage(string nodeId, string expression, IReadingContext
{
var simEval = evaluators.GetEvaluator(simulation);
var context = contexts.GetContext(simulation);
- var value = simEval.EvaluateValueExpression(expression, context, simulation, readingContext);
+ var value = simEval.Evaluate(new DynamicExpression(expression), context, simulation, readingContext);
simulation.Configurations.Get().Nodesets[nodeId] = value;
});
@@ -79,7 +80,7 @@ public void SetICVoltage(string nodeId, string expression, IReadingContext readi
{
var simEval = evaluators.GetEvaluator(simulation);
var context = contexts.GetContext(simulation);
- var value = simEval.EvaluateValueExpression(expression, context, simulation, readingContext);
+ var value = simEval.Evaluate(new DynamicExpression(expression), context, simulation, readingContext);
if (simulation is TimeSimulation ts)
{
diff --git a/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Context/Updates/EntityParameterExpressionValueUpdate.cs b/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Context/Updates/EntityParameterExpressionValueUpdate.cs
index 3af6cfd3..c1f6a439 100644
--- a/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Context/Updates/EntityParameterExpressionValueUpdate.cs
+++ b/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Context/Updates/EntityParameterExpressionValueUpdate.cs
@@ -7,7 +7,7 @@ namespace SpiceSharpParser.ModelReaders.Netlist.Spice.Context.Updates
public class EntityParameterExpressionValueUpdate : EntityParameterUpdate
{
private readonly IReadingContext _readingContext;
- public string ValueExpression { get; set; }
+ public Expression Expression { get; set; }
public EntityParameterExpressionValueUpdate(IReadingContext readingContext)
{
@@ -27,7 +27,7 @@ public override double GetValue(IEvaluator evaluator, ExpressionContext context,
throw new ArgumentNullException(nameof(context));
}
- return evaluator.EvaluateValueExpression(ValueExpression, context, simulation, _readingContext);
+ return evaluator.Evaluate(Expression, context, simulation, _readingContext);
}
}
}
diff --git a/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Context/Updates/EntityUpdates.cs b/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Context/Updates/EntityUpdates.cs
index 4ac7bdc8..00f3690b 100644
--- a/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Context/Updates/EntityUpdates.cs
+++ b/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Context/Updates/EntityUpdates.cs
@@ -5,6 +5,7 @@
using SpiceSharp.Circuits;
using SpiceSharp.Simulations;
using SpiceSharpParser.Common;
+using SpiceSharpParser.Common.Evaluation.Expressions;
namespace SpiceSharpParser.ModelReaders.Netlist.Spice.Context.Updates
{
@@ -170,13 +171,17 @@ public void Add(Entity entity, string parameterName, string expression, bool bef
new EntityParameterExpressionValueUpdate(readingContext)
{
ParameterName = parameterName,
- ValueExpression = expression,
+ Expression = new DynamicExpression(expression),
});
}
if (beforeTemperature)
{
- CommonUpdates[entity].ParameterUpdatesBeforeTemperature.Add(new EntityParameterExpressionValueUpdate(readingContext) { ValueExpression = expression, ParameterName = parameterName });
+ CommonUpdates[entity].ParameterUpdatesBeforeTemperature.Add(new EntityParameterExpressionValueUpdate(readingContext)
+ {
+ Expression = new DynamicExpression(expression),
+ ParameterName = parameterName
+ });
}
}
@@ -213,13 +218,17 @@ public void Add(Entity entity, Simulation simulation, string parameterName, stri
new EntityParameterExpressionValueUpdate(readingContext)
{
ParameterName = parameterName,
- ValueExpression = expression,
+ Expression = new DynamicExpression(expression),
});
}
if (beforeTemperature)
{
- SimulationSpecificUpdates[simulation][entity].ParameterUpdatesBeforeTemperature.Add(new EntityParameterExpressionValueUpdate(readingContext) { ValueExpression = expression, ParameterName = parameterName });
+ SimulationSpecificUpdates[simulation][entity].ParameterUpdatesBeforeTemperature.Add(new EntityParameterExpressionValueUpdate(readingContext)
+ {
+ Expression = new DynamicExpression(expression),
+ ParameterName = parameterName
+ });
}
}
diff --git a/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Evaluation/Functions/Math/AbsFunction.cs b/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Evaluation/Functions/Math/AbsFunction.cs
deleted file mode 100644
index e1dc32e5..00000000
--- a/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Evaluation/Functions/Math/AbsFunction.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-using SpiceSharpParser.Common.Evaluation;
-using System;
-using SpiceSharp.Simulations;
-using SpiceSharpParser.ModelReaders.Netlist.Spice.Context;
-
-namespace SpiceSharpParser.ModelReaders.Netlist.Spice.Evaluation.Functions.Math
-{
- public class AbsFunction : Function
- {
- public AbsFunction()
- {
- Name = "abs";
- ArgumentsCount = 1;
- }
-
- public override double Logic(string image, double[] args, IEvaluator evaluator, ExpressionContext context, Simulation simulation = null, IReadingContext readingContext = null)
- {
- if (args.Length != 1)
- {
- throw new ArgumentException("abs() function expects one argument");
- }
-
- double x = args[0];
- return System.Math.Abs(x);
- }
- }
-}
diff --git a/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Evaluation/Functions/Math/ExpFunction.cs b/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Evaluation/Functions/Math/ExpFunction.cs
deleted file mode 100644
index 58014296..00000000
--- a/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Evaluation/Functions/Math/ExpFunction.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-using System;
-using SpiceSharp.Simulations;
-using SpiceSharpParser.Common.Evaluation;
-using SpiceSharpParser.ModelReaders.Netlist.Spice.Context;
-
-namespace SpiceSharpParser.ModelReaders.Netlist.Spice.Evaluation.Functions.Math
-{
- public class ExpFunction : Function
- {
- public ExpFunction()
- {
- Name = "exp";
- ArgumentsCount = 1;
- }
-
- public override double Logic(string image, double[] args, IEvaluator evaluator, ExpressionContext context, Simulation simulation = null, IReadingContext readingContext = null)
- {
- if (args.Length != 1)
- {
- throw new ArgumentException("exp() function expects one argument");
- }
-
- double x = args[0];
- return System.Math.Exp(x);
- }
- }
-}
diff --git a/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Evaluation/Functions/Math/FAbsFunction.cs b/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Evaluation/Functions/Math/FAbsFunction.cs
deleted file mode 100644
index 7e918b13..00000000
--- a/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Evaluation/Functions/Math/FAbsFunction.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-using SpiceSharpParser.Common.Evaluation;
-using System;
-using SpiceSharp.Simulations;
-using SpiceSharpParser.ModelReaders.Netlist.Spice.Context;
-
-namespace SpiceSharpParser.ModelReaders.Netlist.Spice.Evaluation.Functions.Math
-{
- public class FAbsFunction : Function
- {
- public FAbsFunction()
- {
- Name = "fabs";
- ArgumentsCount = 1;
- }
-
- public override double Logic(string image, double[] args, IEvaluator evaluator, ExpressionContext context, Simulation simulation = null, IReadingContext readingContext = null)
- {
- if (args.Length != 1)
- {
- throw new ArgumentException("fabs() function expects one argument");
- }
-
- double x = args[0];
- return System.Math.Abs(x);
- }
- }
-}
diff --git a/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Evaluation/Functions/Math/Log10Function.cs b/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Evaluation/Functions/Math/Log10Function.cs
deleted file mode 100644
index be7daf42..00000000
--- a/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Evaluation/Functions/Math/Log10Function.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-using SpiceSharpParser.Common.Evaluation;
-using System;
-using SpiceSharp.Simulations;
-using SpiceSharpParser.ModelReaders.Netlist.Spice.Context;
-
-namespace SpiceSharpParser.ModelReaders.Netlist.Spice.Evaluation.Functions.Math
-{
- public class Log10Function : Function
- {
- public Log10Function(SpiceExpressionMode mode)
- {
- Name = "log10";
- ArgumentsCount = 1;
- Mode = mode;
- }
-
- public SpiceExpressionMode Mode { get; }
-
- public override double Logic(string image, double[] args, IEvaluator evaluator, ExpressionContext context, Simulation simulation = null, IReadingContext readingContext = null)
- {
- if (args.Length != 1)
- {
- throw new ArgumentException("log10() function expects one argument");
- }
-
- double x = args[0];
-
- if (Mode == SpiceExpressionMode.HSpice)
- {
- return System.Math.Sign(x) * System.Math.Log10(System.Math.Abs(x));
- }
-
- return System.Math.Log10(x);
- }
- }
-}
diff --git a/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Evaluation/Functions/Math/LogFunction.cs b/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Evaluation/Functions/Math/LogFunction.cs
deleted file mode 100644
index 9d16b4da..00000000
--- a/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Evaluation/Functions/Math/LogFunction.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-using SpiceSharpParser.Common.Evaluation;
-using System;
-using SpiceSharp.Simulations;
-using SpiceSharpParser.ModelReaders.Netlist.Spice.Context;
-
-namespace SpiceSharpParser.ModelReaders.Netlist.Spice.Evaluation.Functions.Math
-{
- public class LogFunction : Function
- {
- public LogFunction(SpiceExpressionMode mode)
- {
- Name = "log";
- ArgumentsCount = 1;
- Mode = mode;
- }
-
- public SpiceExpressionMode Mode { get; }
-
- public override double Logic(string image, double[] args, IEvaluator evaluator, ExpressionContext context, Simulation simulation = null, IReadingContext readingContext = null)
- {
- if (args.Length != 1)
- {
- throw new ArgumentException("log() function expects one argument");
- }
-
- double x = args[0];
-
- if (Mode == SpiceExpressionMode.HSpice)
- {
- return System.Math.Sign(x) * System.Math.Log(System.Math.Abs(x));
- }
-
- return System.Math.Log(x);
- }
- }
-}
diff --git a/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Evaluation/Functions/Math/PowFunction.cs b/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Evaluation/Functions/Math/PowFunction.cs
deleted file mode 100644
index c00f123a..00000000
--- a/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Evaluation/Functions/Math/PowFunction.cs
+++ /dev/null
@@ -1,51 +0,0 @@
-using SpiceSharpParser.Common.Evaluation;
-using System.Numerics;
-using SpiceSharp.Simulations;
-using SpiceSharpParser.ModelReaders.Netlist.Spice.Context;
-
-namespace SpiceSharpParser.ModelReaders.Netlist.Spice.Evaluation.Functions.Math
-{
- public class PowFunction : Function
- {
- public PowFunction(SpiceExpressionMode mode)
- {
- Name = "pow";
- ArgumentsCount = 2;
- Mode = mode;
- }
-
- public SpiceExpressionMode Mode { get; }
-
- public override double Logic(string image, double[] args, IEvaluator evaluator, ExpressionContext context, Simulation simulation = null, IReadingContext readingContext = null)
- {
- double x = args[0];
- double y = args[1];
-
- switch (Mode)
- {
- case SpiceExpressionMode.LtSpice:
- if (x < 0)
- {
- var realResult = Complex.Pow(new Complex(x, 0), new Complex(y, 0)).Real;
-
- // TODO: remove a hack below, write a good implementation of Complex numbers for C# ...
- if (System.Math.Abs(realResult) < 1e-15)
- {
- return 0;
- }
- }
-
- return System.Math.Pow(x, y);
-
- case SpiceExpressionMode.SmartSpice:
- return System.Math.Pow(System.Math.Abs(x), (int)y);
-
- case SpiceExpressionMode.HSpice:
- return System.Math.Pow(x, (int)y);
-
- default:
- return System.Math.Pow(x, y);
- }
- }
- }
-}
diff --git a/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Evaluation/Functions/Math/PowInfixFunction.cs b/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Evaluation/Functions/Math/PowInfixFunction.cs
deleted file mode 100644
index 9ee82167..00000000
--- a/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Evaluation/Functions/Math/PowInfixFunction.cs
+++ /dev/null
@@ -1,64 +0,0 @@
-using SpiceSharpParser.Common.Evaluation;
-using System;
-using System.Numerics;
-using SpiceSharp.Simulations;
-using SpiceSharpParser.ModelReaders.Netlist.Spice.Context;
-
-namespace SpiceSharpParser.ModelReaders.Netlist.Spice.Evaluation.Functions.Math
-{
- public class PowInfixFunction : Function
- {
- public PowInfixFunction(SpiceExpressionMode mode)
- {
- Name = "**";
- ArgumentsCount = 2;
- Infix = true;
- Mode = mode;
- }
-
- public SpiceExpressionMode Mode { get; }
-
- public override double Logic(string image, double[] args, IEvaluator evaluator, ExpressionContext context, Simulation simulation = null, IReadingContext readingContext = null)
- {
- double x = args[0];
- double y = args[1];
-
- switch (Mode)
- {
- case SpiceExpressionMode.LtSpice:
- if (x < 0)
- {
- var realResult = Complex.Pow(new Complex(x, 0), new Complex(y, 0)).Real;
-
- // TODO: remove a hack below, write a good implementation of Complex numbers for C# ...
- if (System.Math.Abs(realResult) < 1e-15)
- {
- return 0;
- }
- }
-
- return System.Math.Pow(x, y);
-
- case SpiceExpressionMode.SmartSpice:
- throw new Exception("** is unknown function");
-
- case SpiceExpressionMode.HSpice:
- if (x < 0)
- {
- return System.Math.Pow(x, (int)y);
- }
- else if (x == 0)
- {
- return 0;
- }
- else
- {
- return System.Math.Pow(x, y);
- }
-
- default:
- return System.Math.Pow(x, y);
- }
- }
- }
-}
diff --git a/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Evaluation/Functions/Math/SqrtFunction.cs b/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Evaluation/Functions/Math/SqrtFunction.cs
deleted file mode 100644
index b76f8186..00000000
--- a/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Evaluation/Functions/Math/SqrtFunction.cs
+++ /dev/null
@@ -1,57 +0,0 @@
-using SpiceSharpParser.Common.Evaluation;
-using System.Numerics;
-using SpiceSharp.Simulations;
-using SpiceSharpParser.ModelReaders.Netlist.Spice.Context;
-
-namespace SpiceSharpParser.ModelReaders.Netlist.Spice.Evaluation.Functions.Math
-{
- public class SqrtFunction : Function
- {
- public SqrtFunction(SpiceExpressionMode mode)
- {
- Name = "sqrt";
- ArgumentsCount = 1;
- Mode = mode;
- }
-
- public SpiceExpressionMode Mode { get; }
-
- public override double Logic(string image, double[] args, IEvaluator evaluator, ExpressionContext context, Simulation simulation = null, IReadingContext readingContext = null)
- {
- double x = args[0];
-
- switch (Mode)
- {
- case SpiceExpressionMode.LtSpice:
- if (x < 0)
- {
- var realResult = Complex.Pow(new Complex(x, 0), new Complex(0.5, 0)).Real;
-
- // TODO: remove a hack below, write a good implementation of Complex numbers for C# ...
- if (System.Math.Abs(realResult) < 1e-15)
- {
- return 0;
- }
- }
-
- return System.Math.Sqrt(x);
-
- case SpiceExpressionMode.SmartSpice:
- return System.Math.Sqrt(System.Math.Abs(x));
-
- case SpiceExpressionMode.HSpice:
- if (x < 0)
- {
- return -System.Math.Sqrt(System.Math.Abs(x));
- }
- else
- {
- return System.Math.Sqrt(x);
- }
-
- default:
- return System.Math.Sqrt(x);
- }
- }
- }
-}
diff --git a/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Evaluation/Functions/Math/TableFunction.cs b/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Evaluation/Functions/Math/TableFunction.cs
index cafbd91c..e2ce4a2c 100644
--- a/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Evaluation/Functions/Math/TableFunction.cs
+++ b/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Evaluation/Functions/Math/TableFunction.cs
@@ -1,12 +1,14 @@
using SpiceSharpParser.Common.Evaluation;
using System;
using System.Collections.Generic;
+using System.Linq;
using SpiceSharp.Simulations;
+using SpiceSharpBehavioral.Parsers;
using SpiceSharpParser.ModelReaders.Netlist.Spice.Context;
namespace SpiceSharpParser.ModelReaders.Netlist.Spice.Evaluation.Functions.Math
{
- public class TableFunction : Function
+ public class TableFunction : Function, IDerivativeFunction
{
public TableFunction()
{
@@ -18,13 +20,13 @@ public override double Logic(string image, double[] args, IEvaluator evaluator,
{
var parameterValue = args[0];
- var points = new List>();
+ var points = new List();
for (var i = 1; i < args.Length - 1; i += 2)
{
var pointX = args[i];
var pointY = args[i + 1];
- points.Add(new Tuple(pointX, pointY));
+ points.Add(new Point() {X = pointX, Y = pointY});
if (pointX == parameterValue)
{
@@ -32,7 +34,7 @@ public override double Logic(string image, double[] args, IEvaluator evaluator,
}
}
- points.Sort((x1, x2) => x1.Item1.CompareTo(x2.Item1));
+ points.Sort((p1, p2) => p1.X.CompareTo(p2.X));
if (points.Count == 1)
{
throw new Exception("There is only one point for table interpolation.");
@@ -43,35 +45,35 @@ public override double Logic(string image, double[] args, IEvaluator evaluator,
int index = 0;
- while (index < points.Count && points[index].Item1 < parameterValue)
+ while (index < points.Count && points[index].X < parameterValue)
{
index++;
}
if (index == points.Count)
{
- return points[points.Count - 1].Item2;
+ return points[points.Count - 1].Y;
}
- if (index == 0 && points[0].Item1 > parameterValue)
+ if (index == 0 && points[0].X > parameterValue)
{
- return points[0].Item2;
+ return points[0].Y;
}
return (linesDefinition[index].A * parameterValue) + linesDefinition[index].B;
}
- private static LineDefinition[] CreateLineParameters(List> points)
+ private static LineDefinition[] CreateLineParameters(List points)
{
List result = new List();
for (var i = 0; i < points.Count - 1; i++)
{
- double x1 = points[i].Item1;
- double x2 = points[i + 1].Item1;
- double y1 = points[i].Item2;
- double y2 = points[i + 1].Item2;
+ double x1 = points[i].X;
+ double x2 = points[i + 1].X;
+ double y1 = points[i].Y;
+ double y2 = points[i + 1].Y;
double a = (y2 - y1) / (x2 - x1);
@@ -93,5 +95,72 @@ public class LineDefinition
public double B { get; set; }
}
+
+ public class Point
+ {
+ public double X { get; set; }
+
+ public double Y { get; set; }
+ }
+
+ public Derivatives> Derivative(string image, double[] args, IEvaluator evaluator, ExpressionContext context,
+ Simulation simulation = null, IReadingContext readingContext = null)
+ {
+ var parameterValue = args[0];
+ var points = new List();
+ Derivatives> derivatives;
+
+ for (var i = 1; i < args.Length - 1; i += 2)
+ {
+ var pointX = args[i];
+ var pointY = args[i + 1];
+ points.Add(new Point() { X = pointX, Y = pointY });
+
+ if (pointX == parameterValue)
+ {
+ derivatives = new DoubleDerivatives(1);
+ derivatives[0] = () => pointY;
+ return derivatives;
+ }
+ }
+
+ points.Sort((p1, p2) => p1.X.CompareTo(p2.X));
+ if (points.Count == 1)
+ {
+ throw new Exception("There is only one point for table interpolation.");
+ }
+
+ // Get point + 1 line parameters for each segment of line
+ LineDefinition[] linesDefinition = CreateLineParameters(points);
+
+ int index = 0;
+
+ while (index < points.Count && points[index].X < parameterValue)
+ {
+ index++;
+ }
+
+ if (index == points.Count)
+ {
+ derivatives = new DoubleDerivatives(2);
+ derivatives[0] = () => points[points.Count - 1].Y;
+ derivatives[1] = () => linesDefinition.Last().A;
+
+ return derivatives;
+ }
+
+ if (index == 0 && points[0].X > parameterValue)
+ {
+ derivatives = new DoubleDerivatives(2);
+ derivatives[0] = () => points[0].Y;
+ derivatives[1] = () => linesDefinition.First().A;
+ }
+
+ derivatives = new DoubleDerivatives(2);
+ derivatives[0] = () => linesDefinition[index].A * parameterValue + linesDefinition[index].B;
+ derivatives[1] = () => linesDefinition[index].A;
+
+ return derivatives;
+ }
}
}
diff --git a/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Evaluation/Functions/MathFunctions.cs b/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Evaluation/Functions/MathFunctions.cs
index 7057aa9b..7fce9581 100644
--- a/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Evaluation/Functions/MathFunctions.cs
+++ b/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Evaluation/Functions/MathFunctions.cs
@@ -27,18 +27,6 @@ public static IFunction CreatePoly()
return new PolyFunction();
}
- ///
- /// Get a pow() function.
- ///
- /// Evaluator mode.
- ///
- /// A new instance of pow function.
- ///
- public static IFunction CreatePow(SpiceExpressionMode mode)
- {
- return new PowFunction(mode);
- }
-
///
/// Get a pwr() function.
///
@@ -62,30 +50,6 @@ public static IFunction CreatePwrs()
return new PwrsFunction();
}
- ///
- /// Get a sqrt function.
- ///
- /// Evaluator mode.
- ///
- /// A new instance of pow function.
- ///
- public static IFunction CreateSqrt(SpiceExpressionMode mode)
- {
- return new SqrtFunction(mode);
- }
-
- ///
- /// Get a ** function.
- ///
- /// Evaluator mode.
- ///
- /// A new instance of ** function.
- ///
- public static IFunction CreatePowInfix(SpiceExpressionMode mode)
- {
- return new PowInfixFunction(mode);
- }
-
///
/// Get a min() function.
///
@@ -141,28 +105,6 @@ public static IFunction CreateLn()
return new LnFunction();
}
- ///
- /// Get a log() function.
- ///
- ///
- /// A new instance of log function.
- ///
- public static IFunction CreateLog(SpiceExpressionMode mode)
- {
- return new LogFunction(mode);
- }
-
- ///
- /// Get a log10() function.
- ///
- ///
- /// A new instance of log10 function.
- ///
- public static IFunction CreateLog10(SpiceExpressionMode mode)
- {
- return new Log10Function(mode);
- }
-
///
/// Get a cbrt() function.
///
@@ -196,28 +138,6 @@ public static IFunction CreateCeil()
return new CeilFunction();
}
- ///
- /// Get a abs() function.
- ///
- ///
- /// A new instance of abs function.
- ///
- public static IFunction CreateAbs()
- {
- return new AbsFunction();
- }
-
- ///
- /// Get a fabs() function.
- ///
- ///
- /// A new instance of fabs function.
- ///
- public static IFunction CreateFAbs()
- {
- return new FAbsFunction();
- }
-
///
/// Get a floor() function.
///
@@ -262,17 +182,6 @@ public static IFunction CreateInv()
return new InvFunction();
}
- ///
- /// Get a exp() function.
- ///
- ///
- /// A new instance of exp function.
- ///
- public static IFunction CreateExp()
- {
- return new ExpFunction();
- }
-
///
/// Get a db() function.
///
diff --git a/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Evaluation/SpiceExpressionContext.cs b/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Evaluation/SpiceExpressionContext.cs
index 4a6eb421..bb762f55 100644
--- a/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Evaluation/SpiceExpressionContext.cs
+++ b/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Evaluation/SpiceExpressionContext.cs
@@ -38,8 +38,6 @@ private void CreateSpiceFunctions()
var functions = new List
{
MathFunctions.CreatePos(),
- MathFunctions.CreatePowInfix(Mode),
- MathFunctions.CreateAbs(),
RandomFunctions.CreateAGauss(),
RandomFunctions.CreateAUnif(),
MathFunctions.CreateBuf(),
@@ -47,8 +45,6 @@ private void CreateSpiceFunctions()
MathFunctions.CreateCeil(),
MathFunctions.CreateDb(Mode),
ControlFunctions.CreateDef(),
- MathFunctions.CreateExp(),
- MathFunctions.CreateFAbs(),
RandomFunctions.CreateFlat(),
MathFunctions.CreateFloor(),
RandomFunctions.CreateGauss(),
@@ -60,18 +56,14 @@ private void CreateSpiceFunctions()
MathFunctions.CreateLn(),
MathFunctions.CreateLimit(),
RandomFunctions.CreateLimit(),
- MathFunctions.CreateLog(Mode),
- MathFunctions.CreateLog10(Mode),
MathFunctions.CreateMax(),
RandomFunctions.CreateMc(),
MathFunctions.CreateMin(),
MathFunctions.CreateNint(),
MathFunctions.CreateRound(),
- MathFunctions.CreatePow(Mode),
MathFunctions.CreatePwr(Mode),
MathFunctions.CreatePwrs(),
RandomFunctions.CreateRandom(),
- MathFunctions.CreateSqrt(Mode),
MathFunctions.CreateSgn(),
MathFunctions.CreateTable(),
MathFunctions.CreateU(),
diff --git a/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Processors/IfPreprocessor.cs b/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Processors/IfPreprocessor.cs
index 26690da6..9eec21e8 100644
--- a/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Processors/IfPreprocessor.cs
+++ b/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Processors/IfPreprocessor.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using SpiceSharpParser.Common.Evaluation;
+using SpiceSharpParser.Common.Evaluation.Expressions;
using SpiceSharpParser.ModelReaders.Netlist.Spice.Readers.Controls;
using SpiceSharpParser.Models.Netlist.Spice.Objects;
@@ -121,7 +122,7 @@ private IEnumerable ComputeIfResult(Statements result, int ifIndex, i
elseIfControl = result[elseIfControlIndex] as Control;
}
- if (Evaluator.EvaluateValueExpression(ifCondition.Image, ExpressionContext) >= 1.0)
+ if (Evaluator.Evaluate(new DynamicExpression(ifCondition.Image), ExpressionContext, null, null) >= 1.0)
{
if (elseIfControl != null)
{
diff --git a/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Readers/Controls/Exporters/Exporter.cs b/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Readers/Controls/Exporters/Exporter.cs
index 87ce10c2..77f34bb8 100644
--- a/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Readers/Controls/Exporters/Exporter.cs
+++ b/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Readers/Controls/Exporters/Exporter.cs
@@ -20,11 +20,10 @@ public abstract class Exporter
/// Node name generator.
/// Component name generator.
/// Model name generator.
- /// Result.
/// Case settings.
///
/// A new export.
///
- public abstract Export CreateExport(string name, string type, ParameterCollection parameters, Simulation simulation, INodeNameGenerator nodeNameGenerator, IObjectNameGenerator componentNameGenerator, IObjectNameGenerator modelNameGenerator, IResultService result, SpiceNetlistCaseSensitivitySettings caseSettings);
+ public abstract Export CreateExport(string name, string type, ParameterCollection parameters, Simulation simulation, INodeNameGenerator nodeNameGenerator, IObjectNameGenerator componentNameGenerator, IObjectNameGenerator modelNameGenerator, IResultService resultService, SpiceNetlistCaseSensitivitySettings caseSettings);
}
}
diff --git a/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Readers/Controls/Exporters/ExpressionExport.cs b/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Readers/Controls/Exporters/ExpressionExport.cs
index 40d5079e..77bfbef2 100644
--- a/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Readers/Controls/Exporters/ExpressionExport.cs
+++ b/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Readers/Controls/Exporters/ExpressionExport.cs
@@ -19,7 +19,7 @@ public class ExpressionExport : Export
/// Contexts.
/// Simulation.
/// Reading context.
- public ExpressionExport(string name, string expressionName, string expression, IEvaluator evaluator, SimulationExpressionContexts contexts, Simulation simulation, IReadingContext readingContext)
+ public ExpressionExport(string name, string expressionName, Expression expression, IEvaluator evaluator, SimulationExpressionContexts contexts, Simulation simulation, IReadingContext readingContext)
: base(simulation)
{
Name = name;
@@ -51,12 +51,12 @@ public ExpressionExport(string name, string expressionName, string expression, I
///
/// Gets the expression.
///
- public string Expression { get; }
+ public Expression Expression { get; }
///
/// Gets the type name.
///
- public override string TypeName => Expression;
+ public override string TypeName => Expression.ValueExpression;
///
/// Gets the export unit.
@@ -71,7 +71,7 @@ public ExpressionExport(string name, string expressionName, string expression, I
///
public override double Extract()
{
- return Evaluator.EvaluateValueExpression(Expression, ExpressionContexts.GetContext(Simulation), Simulation, ReadingContext);
+ return Evaluator.Evaluate(Expression, ExpressionContexts.GetContext(Simulation), Simulation, ReadingContext);
}
}
}
diff --git a/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Readers/Controls/ParamControl.cs b/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Readers/Controls/ParamControl.cs
index 95caf35d..47603dac 100644
--- a/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Readers/Controls/ParamControl.cs
+++ b/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Readers/Controls/ParamControl.cs
@@ -12,7 +12,7 @@ public class ParamControl : ParamBaseControl
{
protected override void SetParameter(string parameterName, string parameterExpression, ExpressionContext expressionContext, SpiceNetlistCaseSensitivitySettings caseSettings, IEvaluator evaluator, IReadingContext readingContext)
{
- var parameters = ExpressionParserHelpers.GetExpressionParameters(parameterExpression, expressionContext, readingContext, @throw: false);
+ var parameters = ExpressionParserHelpers.GetExpressionParameters(parameterExpression, expressionContext, readingContext, caseSettings, @throw: false);
expressionContext.SetParameter(parameterName, parameterExpression, parameters);
}
}
diff --git a/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Readers/Controls/SParamControl.cs b/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Readers/Controls/SParamControl.cs
index 575ff6a0..09ef6994 100644
--- a/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Readers/Controls/SParamControl.cs
+++ b/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Readers/Controls/SParamControl.cs
@@ -1,7 +1,7 @@
using SpiceSharpParser.Common.Evaluation;
+using SpiceSharpParser.Common.Evaluation.Expressions;
using SpiceSharpParser.ModelReaders.Netlist.Spice.Context;
using SpiceSharpParser.Models.Netlist.Spice.Objects;
-using SpiceSharpParser.Parsers.Expression;
namespace SpiceSharpParser.ModelReaders.Netlist.Spice.Readers.Controls
{
@@ -12,8 +12,8 @@ public class SParamControl : ParamBaseControl
{
protected override void SetParameter(string parameterName, string parameterExpression, ExpressionContext expressionContext, SpiceNetlistCaseSensitivitySettings caseSettings, IEvaluator evaluator, IReadingContext readingContext)
{
- var parameters = ExpressionParserHelpers.GetExpressionParameters(parameterExpression, expressionContext, readingContext, false);
- expressionContext.SetCachedParameter(parameterName, parameterExpression, parameters);
+ var value = readingContext.ReadingEvaluator.Evaluate(new DynamicExpression(parameterExpression), expressionContext, null, readingContext);
+ expressionContext.SetParameter(parameterName, value);
}
}
}
diff --git a/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Readers/Controls/SaveControl.cs b/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Readers/Controls/SaveControl.cs
index fa9bf5d7..2965bcaf 100644
--- a/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Readers/Controls/SaveControl.cs
+++ b/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Readers/Controls/SaveControl.cs
@@ -218,8 +218,8 @@ private void AddOpPointToSeries(ParameterSweep firstParameterSweep, Export expor
var expressionContext = context.SimulationExpressionContexts.GetContext(export.Simulation);
var firstParameterSweepParameter = expressionContext.Parameters[firstParameterSweep.Parameter.Image];
var evaluator = context.SimulationEvaluators.GetEvaluator(export.Simulation);
- var value = firstParameterSweepParameter.Evaluate(evaluator, context.SimulationExpressionContexts.GetContext(export.Simulation), export.Simulation, context);
-
+
+ var value = evaluator.Evaluate(firstParameterSweepParameter, expressionContext, export.Simulation, context);
series.Points.Add(new Point() { X = value, Y = export.Extract() });
};
}
diff --git a/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Readers/Controls/Simulations/Decorators/EnableStochasticModelsSimulationDecorator.cs b/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Readers/Controls/Simulations/Decorators/EnableStochasticModelsSimulationDecorator.cs
index 71ec511f..9f1f5ab5 100644
--- a/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Readers/Controls/Simulations/Decorators/EnableStochasticModelsSimulationDecorator.cs
+++ b/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Readers/Controls/Simulations/Decorators/EnableStochasticModelsSimulationDecorator.cs
@@ -5,6 +5,7 @@
using SpiceSharp.Simulations;
using SpiceSharpParser.Common;
using SpiceSharpParser.Common.Evaluation;
+using SpiceSharpParser.Common.Evaluation.Expressions;
using SpiceSharpParser.ModelReaders.Netlist.Spice.Context;
using SpiceSharpParser.ModelReaders.Netlist.Spice.Context.Models;
using SpiceSharpParser.Models.Netlist.Spice.Objects;
@@ -73,7 +74,7 @@ private void SetModelLotModelParameters(BaseSimulation sim, Entity baseModel, En
var expressionContext = _context.SimulationExpressionContexts.GetContext(sim);
var currentValue = currentValueParameter.Value;
- var percentValue = evaluator.EvaluateValueExpression(parameterPercent.Tolerance.Image, expressionContext);
+ var percentValue = evaluator.Evaluate(new DynamicExpression(parameterPercent.Tolerance.Image), expressionContext, null, _context);
double newValue = GetValueForLotParameter(expressionContext, baseModel, parameterName, currentValue, percentValue, parameterPercent.RandomDistributionName, comparer);
_context.SimulationPreparations.SetParameter(componentModel, sim, parameterName, newValue, true, false);
@@ -97,7 +98,7 @@ private void SetModelDevModelParameters(BaseSimulation sim, Entity baseModel, En
var currentValueParameter = sim.EntityParameters[componentModel.Name].GetParameter>(parameterName, comparer);
var currentValue = currentValueParameter.Value;
var expressionContext = _context.SimulationExpressionContexts.GetContext(sim);
- var percentValue = evaluator.EvaluateValueExpression(parameterPercent.Tolerance.Image, expressionContext);
+ var percentValue = evaluator.Evaluate(new DynamicExpression(parameterPercent.Tolerance.Image), expressionContext, sim, _context);
double newValue = GetValueForDevParameter(expressionContext, currentValue, percentValue, parameterPercent.RandomDistributionName);
diff --git a/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Readers/EntityGenerators/Components/Sources/ArbitraryBehavioralGenerator.cs b/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Readers/EntityGenerators/Components/Sources/ArbitraryBehavioralGenerator.cs
index 1fa7860c..09fee046 100644
--- a/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Readers/EntityGenerators/Components/Sources/ArbitraryBehavioralGenerator.cs
+++ b/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Readers/EntityGenerators/Components/Sources/ArbitraryBehavioralGenerator.cs
@@ -1,9 +1,7 @@
-using System;
-using System.Collections.Generic;
+using System.Collections.Generic;
using System.Linq;
using SpiceSharp.Components;
using SpiceSharp.Simulations;
-using SpiceSharpBehavioral.Parsers;
using SpiceSharpParser.ModelReaders.Netlist.Spice.Context;
using SpiceSharpParser.Models.Netlist.Spice.Objects;
using SpiceSharpParser.Models.Netlist.Spice.Objects.Parameters;
@@ -29,9 +27,10 @@ public override SpiceSharp.Components.Component Generate(
{
if (parameters.Any(p => p is AssignmentParameter asgParameter && asgParameter.Name.ToLower() == "v"))
{
- var expressionParameter = (AssignmentParameter) parameters.First(p => p is AssignmentParameter asgParameter && asgParameter.Name.ToLower() == "v");
var entity = new BehavioralVoltageSource(componentIdentifier);
context.CreateNodes(entity, parameters);
+
+ var expressionParameter = (AssignmentParameter)parameters.First(p => p is AssignmentParameter asgParameter && asgParameter.Name.ToLower() == "v");
var baseParameters = entity.ParameterSets.Get();
baseParameters.Expression = expressionParameter.Value;
baseParameters.Parser = (Simulation sim) => CreateParser(context, sim);
@@ -40,15 +39,16 @@ public override SpiceSharp.Components.Component Generate(
if (parameters.Any(p => p is AssignmentParameter asgParameter && asgParameter.Name.ToLower() == "i"))
{
- var expressionParameter = (AssignmentParameter) parameters.First(p =>
- p is AssignmentParameter asgParameter && asgParameter.Name.ToLower() == "i");
-
+
var entity = new BehavioralCurrentSource(componentIdentifier);
- entity.SetParameter>>("parser", (Simulation sim) => CreateParser(context, sim), null);
-
context.CreateNodes(entity, parameters);
+
+ var expressionParameter = (AssignmentParameter)parameters.First(p =>
+ p is AssignmentParameter asgParameter && asgParameter.Name.ToLower() == "i");
+
var baseParameters = entity.ParameterSets.Get();
baseParameters.Expression = expressionParameter.Value;
+ baseParameters.Parser = (Simulation sim) => CreateParser(context, sim);
return entity;
}
diff --git a/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Readers/EntityGenerators/Components/Sources/CurrentSourceGenerator.cs b/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Readers/EntityGenerators/Components/Sources/CurrentSourceGenerator.cs
index 84a26da9..7839e68b 100644
--- a/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Readers/EntityGenerators/Components/Sources/CurrentSourceGenerator.cs
+++ b/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Readers/EntityGenerators/Components/Sources/CurrentSourceGenerator.cs
@@ -1,9 +1,6 @@
-using System;
-using System.Collections.Generic;
+using System.Collections.Generic;
using System.Linq;
using SpiceSharp.Components;
-using SpiceSharp.Simulations;
-using SpiceSharpBehavioral.Parsers;
using SpiceSharpParser.Common;
using SpiceSharpParser.ModelReaders.Netlist.Spice.Context;
using SpiceSharpParser.ModelReaders.Netlist.Spice.Exceptions;
@@ -138,11 +135,12 @@ private Component CreateCustomCurrentSource(string name, ParameterCollection par
var valueParameter = (AssignmentParameter)parameters.Single(p => p is AssignmentParameter ap && ap.Name.ToLower() == "value");
var entity = new BehavioralCurrentSource(name);
- entity.SetParameter>>("parser", (sim) => CreateParser(context, sim));
context.CreateNodes(entity, parameters);
+
var baseParameters = entity.ParameterSets.Get();
baseParameters.Expression = valueParameter.Value;
baseParameters.SpicePropertyComparer = StringComparerProvider.Get(context.CaseSensitivity.IsFunctionNameCaseSensitive);
+ baseParameters.Parser = (sim) => CreateParser(context, sim);
return entity;
}
@@ -152,13 +150,12 @@ private Component CreateCustomCurrentSource(string name, ParameterCollection par
if (expressionParameter != null)
{
var entity = new BehavioralCurrentSource(name);
- entity.SetParameter>>("parser", (sim) => CreateParser(context, sim));
-
context.CreateNodes(entity, parameters);
+
var baseParameters = entity.ParameterSets.Get();
baseParameters.Expression = expressionParameter.Image;
baseParameters.SpicePropertyComparer = StringComparerProvider.Get(context.CaseSensitivity.IsFunctionNameCaseSensitive);
-
+ baseParameters.Parser = (sim) => CreateParser(context, sim);
return entity;
}
}
@@ -207,14 +204,13 @@ private Component CreateCustomCurrentSource(string name, ParameterCollection par
if (nextParameter is ExpressionEqualParameter eep)
{
- var entity = new CurrentSource(name);
+ var entity = new BehavioralCurrentSource(name);
context.CreateNodes(entity, parameters);
- parameters = parameters.Skip(CurrentSource.CurrentSourcePinCount);
-
- var tableParameterName = name + "_table_variable";
- context.SetParameter(tableParameterName, eep.Expression);
- string expression = ExpressionFactory.CreateTableExpression(tableParameterName, eep.Points);
- context.SetParameter(entity, "dc", expression);
+
+ var baseParameters = entity.ParameterSets.Get();
+ baseParameters.Expression = ExpressionFactory.CreateTableExpression(eep.Expression, eep.Points);
+ baseParameters.SpicePropertyComparer = StringComparerProvider.Get(context.CaseSensitivity.IsFunctionNameCaseSensitive);
+ baseParameters.Parser = (sim) => CreateParser(context, sim);
return entity;
}
else
diff --git a/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Readers/EntityGenerators/Components/Sources/SourceGenerator.cs b/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Readers/EntityGenerators/Components/Sources/SourceGenerator.cs
index ccecaa0a..6df8f1b1 100644
--- a/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Readers/EntityGenerators/Components/Sources/SourceGenerator.cs
+++ b/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Readers/EntityGenerators/Components/Sources/SourceGenerator.cs
@@ -13,7 +13,7 @@ public abstract class SourceGenerator : ComponentGenerator
{
protected SimpleDerivativeParser CreateParser(IReadingContext context, Simulation simulation)
{
- var parser = Parsers.Expression.ExpressionParserHelpers.GetDeriveParser(context.SimulationExpressionContexts.GetContext(simulation), context, context.ReadingEvaluator, simulation);
+ var parser = Parsers.Expression.ExpressionParserHelpers.GetDeriveParser(context.SimulationExpressionContexts.GetContext(simulation), context, context.ReadingEvaluator, simulation, context.CaseSensitivity);
return parser;
}
diff --git a/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Readers/EntityGenerators/Components/Sources/VoltageSourceGenerator.cs b/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Readers/EntityGenerators/Components/Sources/VoltageSourceGenerator.cs
index 91f590be..58b6b414 100644
--- a/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Readers/EntityGenerators/Components/Sources/VoltageSourceGenerator.cs
+++ b/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Readers/EntityGenerators/Components/Sources/VoltageSourceGenerator.cs
@@ -1,10 +1,7 @@
-using System;
-using System.Collections.Generic;
+using System.Collections.Generic;
using System.Linq;
using SpiceSharp.Components;
-using SpiceSharp.Simulations;
using SpiceSharpBehavioral.Components.BehavioralBehaviors;
-using SpiceSharpBehavioral.Parsers;
using SpiceSharpParser.Common;
using SpiceSharpParser.ModelReaders.Netlist.Spice.Context;
using SpiceSharpParser.ModelReaders.Netlist.Spice.Exceptions;
@@ -151,12 +148,11 @@ protected Component CreateCustomVoltageSource(
{
var entity = new BehavioralVoltageSource(name);
context.CreateNodes(entity, parameters);
- entity.SetParameter>>("parser", (Simulation sim) => CreateParser(context, sim), null);
-
var baseParameters = entity.ParameterSets.Get();
var valueParameter = (AssignmentParameter)parameters.Single(p => p is AssignmentParameter ap && ap.Name.ToLower() == "value");
baseParameters.Expression = valueParameter.Value;
baseParameters.SpicePropertyComparer = StringComparerProvider.Get(context.CaseSensitivity.IsFunctionNameCaseSensitive);
+ baseParameters.Parser = (sim) => CreateParser(context, sim);
return entity;
}
@@ -164,8 +160,8 @@ protected Component CreateCustomVoltageSource(
if (parameters.Any(p => p is WordParameter ap && ap.Image.ToLower() == "value"))
{
var entity = new BehavioralVoltageSource(name);
- entity.SetParameter>>("parser", (Simulation sim) => CreateParser(context, sim), null);
context.CreateNodes(entity, parameters);
+
var baseParameters = entity.ParameterSets.Get();
var expressionParameter = parameters.FirstOrDefault(p => p is ExpressionParameter);
if (expressionParameter != null)
@@ -173,6 +169,7 @@ protected Component CreateCustomVoltageSource(
baseParameters.Expression = expressionParameter.Image;
}
baseParameters.SpicePropertyComparer = StringComparerProvider.Get(context.CaseSensitivity.IsFunctionNameCaseSensitive);
+ baseParameters.Parser = (sim) => CreateParser(context, sim);
return entity;
}
@@ -220,12 +217,14 @@ protected Component CreateCustomVoltageSource(
if (nextParameter is ExpressionEqualParameter eep)
{
- var entity = new VoltageSource(name);
+ var entity = new BehavioralVoltageSource(name);
context.CreateNodes(entity, parameters);
- var tableParameterName = name + "_table_variable";
- context.SetParameter(tableParameterName, eep.Expression);
- string expression = ExpressionFactory.CreateTableExpression(tableParameterName, eep.Points);
- context.SetParameter(entity, "dc", expression);
+
+ var baseParameters = entity.ParameterSets.Get();
+ baseParameters.Parser = (sim) => CreateParser(context, sim);
+ baseParameters.Expression = ExpressionFactory.CreateTableExpression(eep.Expression, eep.Points);
+ baseParameters.SpicePropertyComparer = StringComparerProvider.Get(context.CaseSensitivity.IsFunctionNameCaseSensitive);
+
return entity;
}
else
diff --git a/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Readers/EntityGenerators/Components/SubCircuitGenerator.cs b/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Readers/EntityGenerators/Components/SubCircuitGenerator.cs
index 5776c751..22cb9b6e 100644
--- a/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Readers/EntityGenerators/Components/SubCircuitGenerator.cs
+++ b/src/SpiceSharpParser/ModelReaders/Netlist/Spice/Readers/EntityGenerators/Components/SubCircuitGenerator.cs
@@ -6,6 +6,7 @@
using SpiceSharpBehavioral.Components.BehavioralBehaviors;
using SpiceSharpParser.Common;
using SpiceSharpParser.Common.Evaluation;
+using SpiceSharpParser.Common.Evaluation.Expressions;
using SpiceSharpParser.ModelReaders.Netlist.Spice.Context;
using SpiceSharpParser.ModelReaders.Netlist.Spice.Context.Names;
using SpiceSharpParser.ModelReaders.Netlist.Spice.Exceptions;
@@ -118,7 +119,7 @@ private void CreateSubcircuitComponents(SubCircuit subCircuitDefinition, IReadin
{
foreach (Statement statement in subCircuitDefinition.Statements.Where(s => s is Component))
{
- subCircuitContext.StatementsReader.Read((Component) statement, subCircuitContext);
+ subCircuitContext.StatementsReader.Read((Component)statement, subCircuitContext);
var lastEntity = subCircuitContext.Result.Circuit.Last();
@@ -210,14 +211,15 @@ private ReadingContext CreateSubcircuitContext(string subcircuitFullName, string
subCircuitDefiniton,
subCktParameters,
context.CaseSensitivity,
- context.ReadingEvaluator);
+ context.ReadingEvaluator,
+ context);
var subCircuitExpressionContext = context.ReadingExpressionContext.CreateChildContext(subcircuitFullName, true);
var pp = new Dictionary>();
foreach (var sp in subcircuitParameters)
{
- pp[sp.Key] = ExpressionParserHelpers.GetExpressionParameters(sp.Value, subCircuitExpressionContext, context, false);
+ pp[sp.Key] = ExpressionParserHelpers.GetExpressionParameters(sp.Value, subCircuitExpressionContext, context,context.CaseSensitivity, false);
}
subCircuitExpressionContext.SetParameters(subcircuitParameters, pp);
@@ -278,7 +280,7 @@ private ReadingContext CreateSubcircuitContext(string subcircuitFullName, string
///
/// A dictionary of parameters.
///
- private Dictionary CreateSubcircuitParameters(ExpressionContext rootExpressionContext, SubCircuit subCiruitDefiniton, List subcktParameters, SpiceNetlistCaseSensitivitySettings caseSettings, IEvaluator evaluator)
+ private Dictionary CreateSubcircuitParameters(ExpressionContext rootExpressionContext, SubCircuit subCiruitDefiniton, List subcktParameters, SpiceNetlistCaseSensitivitySettings caseSettings, IEvaluator evaluator, IReadingContext readingContext)
{
var result = new Dictionary(StringComparerProvider.Get(caseSettings.IsParameterNameCaseSensitive));
@@ -296,8 +298,7 @@ private Dictionary CreateSubcircuitParameters(ExpressionContext
{
if (parameterName == result[parameterName])
{
- result[parameterName] = evaluator.EvaluateValueExpression(parameterName, rootExpressionContext)
- .ToString(CultureInfo.InvariantCulture);
+ result[parameterName] = evaluator.Evaluate(new DynamicExpression(parameterName), rootExpressionContext,null, readingContext).ToString(CultureInfo.InvariantCulture);
}
}
diff --git a/src/SpiceSharpParser/Parsers/Expression/ExpressionParser.cs b/src/SpiceSharpParser/Parsers/Expression/ExpressionParser.cs
new file mode 100644
index 00000000..d1162c1d
--- /dev/null
+++ b/src/SpiceSharpParser/Parsers/Expression/ExpressionParser.cs
@@ -0,0 +1,112 @@
+using System;
+using System.Collections.Generic;
+using SpiceSharp;
+using SpiceSharpBehavioral.Parsers;
+using SpiceSharpBehavioral.Parsers.Helper;
+using SpiceSharpParser.Common;
+using SpiceSharpParser.ModelReaders.Netlist.Spice;
+
+namespace SpiceSharpParser.Parsers.Expression
+{
+ public class ExpressionParser : SimpleDerivativeParser
+ {
+ ///
+ /// The default functions.
+ ///
+ public Dictionary DefaultFunctions { get; set; }
+
+ public ExpressionParser(SpiceNetlistCaseSensitivitySettings caseSensitivitySettings)
+ {
+ bool isFunctionCaseSesitive = caseSensitivitySettings?.IsFunctionNameCaseSensitive ?? false;
+
+ DefaultFunctions =
+ new Dictionary(
+ StringComparerProvider.Get(isFunctionCaseSesitive))
+ {
+ { "Exp", SimpleDerivativeParserHelper.ApplyExp },
+ { "Log", SimpleDerivativeParserHelper.ApplyLog },
+ { "Pow", SimpleDerivativeParserHelper.ApplyPow },
+ { "Log10", SimpleDerivativeParserHelper.ApplyLog10 },
+ { "Sqrt", SimpleDerivativeParserHelper.ApplySqrt },
+ { "Sin", SimpleDerivativeParserHelper.ApplySin },
+ { "Cos", ApplyCos },
+ { "Tan", ApplyTan },
+ { "Asin", SimpleDerivativeParserHelper.ApplyAsin },
+ { "Acos", SimpleDerivativeParserHelper.ApplyAcos },
+ { "Atan", SimpleDerivativeParserHelper.ApplyAtan },
+ { "Abs", SimpleDerivativeParserHelper.ApplyAbs },
+ { "Round", SimpleDerivativeParserHelper.ApplyRound },
+ { "Min", SimpleDerivativeParserHelper.ApplyMin },
+ { "Max", SimpleDerivativeParserHelper.ApplyMax }
+ };
+
+ FunctionFound += ExpressionParser_FunctionFound;
+ }
+
+ private void ExpressionParser_FunctionFound(object sender, FunctionFoundEventArgs>> e)
+ {
+ if (DefaultFunctions.TryGetValue(e.Name, out var function))
+ {
+ var arguments = new Derivatives>[e.ArgumentCount];
+ for (var i = 0; i < e.ArgumentCount; i++)
+ arguments[i] = e[i];
+ e.Result = function?.Invoke(arguments);
+ }
+ }
+
+ ///
+ /// Applies the cosine.
+ ///
+ /// The arguments.
+ /// The cosine result.
+ private static Derivatives> ApplyCos(Derivatives>[] arguments)
+ {
+ arguments.ThrowIfNot(nameof(arguments), 1);
+ var arg = arguments[0];
+ var result = new DoubleDerivatives(arg.Count);
+ var a0 = arg[0];
+ result[0] = () => Math.Cos(a0());
+
+ // Apply the chain rule
+ for (var i = 1; i < arg.Count; i++)
+ {
+ if (arg[i] != null)
+ {
+ var ai = arg[i];
+ result[i] = () => -Math.Sin(a0()) * ai();
+ }
+ }
+ return result;
+ }
+
+
+ ///
+ /// Applies the tangent.
+ ///
+ /// The arguments.
+ /// The tangent result.
+ private static Derivatives> ApplyTan(Derivatives>[] arguments)
+ {
+ arguments.ThrowIfNot(nameof(arguments), 1);
+ var arg = arguments[0];
+ var result = new DoubleDerivatives(arg.Count);
+ var a0 = arg[0];
+ result[0] = () => Math.Tan(a0());
+
+ // Apply the chain rule
+ for (var i = 1; i < arg.Count; i++)
+ {
+ if (arg[i] != null)
+ {
+ var ai = arg[i];
+ result[i] = () =>
+ {
+ var tmp = Math.Cos(a0());
+ return ai() / tmp / tmp;
+ };
+ }
+ }
+ return result;
+ }
+ }
+}
diff --git a/src/SpiceSharpParser/Parsers/Expression/ExpressionParserHelpers.cs b/src/SpiceSharpParser/Parsers/Expression/ExpressionParserHelpers.cs
index 8fb64744..b6b50213 100644
--- a/src/SpiceSharpParser/Parsers/Expression/ExpressionParserHelpers.cs
+++ b/src/SpiceSharpParser/Parsers/Expression/ExpressionParserHelpers.cs
@@ -5,6 +5,7 @@
using SpiceSharpBehavioral.Parsers;
using SpiceSharpBehavioral.Parsers.Helper;
using SpiceSharpParser.Common.Evaluation;
+using SpiceSharpParser.ModelReaders.Netlist.Spice;
using SpiceSharpParser.ModelReaders.Netlist.Spice.Context;
using SpiceSharpParser.ModelReaders.Netlist.Spice.Readers.Controls.Exporters;
using SpiceSharpParser.Models.Netlist.Spice.Objects;
@@ -16,14 +17,14 @@ public class ExpressionParserHelpers
{
public static double GetExpressionValue(string expression, ExpressionContext context, IEvaluator evaluator, Simulation simulation, IReadingContext readingContext, bool @throw = true)
{
- var parser = GetDeriveParser(context, readingContext, evaluator, simulation, @throw);
+ var parser = GetDeriveParser(context, readingContext, evaluator, simulation, readingContext?.CaseSensitivity, @throw);
var derivatives = parser.Parse(expression);
return derivatives[0]();
}
- public static List GetExpressionParameters(string expression, ExpressionContext context, IReadingContext readingContext, bool @throw)
+ public static List GetExpressionParameters(string expression, ExpressionContext context, IReadingContext readingContext, SpiceNetlistCaseSensitivitySettings caseSettings, bool @throw)
{
- var parser = GetDeriveParser(context, readingContext, null, null, @throw);
+ var parser = GetDeriveParser(context, readingContext, null, null, caseSettings, @throw);
var parameters = new List();
parser.VariableFound += (sender, e) =>
{
@@ -38,58 +39,17 @@ public static List GetExpressionParameters(string expression, Expression
return parameters;
}
- public static SimpleDerivativeParser GetDeriveParser(ExpressionContext context, IReadingContext readingContext, IEvaluator evaluator, Simulation simulation, bool @throw = true)
+ public static SimpleDerivativeParser GetDeriveParser(ExpressionContext context, IReadingContext readingContext, IEvaluator evaluator, Simulation simulation, SpiceNetlistCaseSensitivitySettings caseSettings, bool @throw = true)
{
- var parser = new SimpleDerivativeParser();
- parser.RegisterDefaultFunctions();
-
- parser.VariableFound += (sender, args) =>
- {
- if (context.Arguments.Any(a => a.Key == args.Name))
- {
- var d = new DoubleDerivatives(2);
- d[0] = () => context.Arguments.First(a => a.Key == args.Name).Value.Evaluate(evaluator, context,simulation, readingContext);
- d[1] = () => 1;
- args.Result = d;
- return;
- }
-
- if (context.Parameters.ContainsKey(args.Name))
- {
- var d = new DoubleDerivatives(2);
- d[0] = () => context.Parameters[args.Name].Evaluate(evaluator, context, simulation, readingContext);
- d[1] = () => 0;
- args.Result = d;
- return;
- }
-
- if (readingContext != null)
- {
- var readingExpressionContext = readingContext.ReadingExpressionContext;
-
- if (readingExpressionContext.Parameters.ContainsKey(args.Name))
- {
- var d = new DoubleDerivatives(2);
- d[0] = () => readingExpressionContext.Parameters[args.Name].Evaluate(evaluator, context,simulation, readingContext);
- d[1] = () => 0;
- args.Result = d;
- return;
- }
- }
-
- if (@throw)
- {
- throw new UnknownParameterException();
- }
- else
- {
- var d = new DoubleDerivatives(1);
- d[0] = () => double.NaN;
- args.Result = d;
- }
- };
- parser.FunctionFound += GetFunctionFound(context, readingContext, evaluator, simulation);
- parser.SpicePropertyFound += (sender, arg) =>
+ var parser = new ExpressionParser(caseSettings);
+ parser.VariableFound += OnVariableFound(context, readingContext, evaluator, simulation, @throw);
+ parser.FunctionFound += OnFunctionFound(context, readingContext, evaluator, simulation);
+ parser.SpicePropertyFound += OnSpicePropertyFound(context, readingContext, evaluator, simulation);
+ return parser;
+ }
+ private static EventHandler> OnSpicePropertyFound(ExpressionContext context, IReadingContext readingContext, IEvaluator evaluator, Simulation simulation)
+ {
+ return (sender, arg) =>
{
if (arg is SimpleDerivativePropertyEventArgs argTyped)
{
@@ -114,12 +74,14 @@ public static SimpleDerivativeParser GetDeriveParser(ExpressionContext context,
if (context.Arguments.ContainsKey(argument))
{
- var argumentValue = context.Arguments[argument].Evaluate(evaluator, context, simulation, readingContext);
+ var expression = context.Arguments[argument];
+ var argumentValue = evaluator.Evaluate(expression, context, simulation, readingContext);
vectorParameter.Elements.Add(new WordParameter(((int)argumentValue).ToString()));
}
else if (context.Parameters.ContainsKey(argument))
{
- var argumentValue = context.Parameters[argument].Evaluate(evaluator, context, simulation, readingContext);
+ var expression = context.Parameters[argument];
+ var argumentValue = evaluator.Evaluate(expression, context, simulation, readingContext);
vectorParameter.Elements.Add(new WordParameter(((int)argumentValue).ToString()));
}
else
@@ -168,10 +130,73 @@ public static SimpleDerivativeParser GetDeriveParser(ExpressionContext context,
arg.Apply(() => export.Extract());
};
- return parser;
}
- private static EventHandler>>> GetFunctionFound(ExpressionContext context, IReadingContext readingContext, IEvaluator evaluator, Simulation simulation)
+ private static EventHandler>>> OnVariableFound(ExpressionContext context, IReadingContext readingContext, IEvaluator evaluator, Simulation simulation, bool @throw)
+ {
+ return (sender, args) =>
+ {
+ if (context.Arguments.Any(a => a.Key == args.Name))
+ {
+ var d = new DoubleDerivatives(2);
+ d[0] = () =>
+ {
+ var expression = context.Arguments.First(a => a.Key == args.Name).Value;
+ var value = evaluator.Evaluate(expression, context, simulation, readingContext);
+ return value;
+ };
+ d[1] = () => 1;
+ args.Result = d;
+ return;
+ }
+
+ if (context.Parameters.ContainsKey(args.Name))
+ {
+ var d = new DoubleDerivatives(2);
+ d[0] = () =>
+ {
+ var parameter = context.Parameters[args.Name];
+ var value = evaluator.Evaluate(parameter, context, simulation, readingContext);
+ return value;
+ };
+ d[1] = () => 0;
+ args.Result = d;
+ return;
+ }
+
+ if (readingContext != null)
+ {
+ var readingExpressionContext = readingContext.ReadingExpressionContext;
+
+ if (readingExpressionContext.Parameters.ContainsKey(args.Name))
+ {
+ var d = new DoubleDerivatives(2);
+ d[0] = () =>
+ {
+ var expression = readingExpressionContext.Parameters[args.Name];
+ var value = evaluator.Evaluate(expression, context, simulation, readingContext);
+ return value;
+ };
+ d[1] = () => 0;
+ args.Result = d;
+ return;
+ }
+ }
+
+ if (@throw)
+ {
+ throw new UnknownParameterException();
+ }
+ else
+ {
+ var d = new DoubleDerivatives(1);
+ d[0] = () => double.NaN;
+ args.Result = d;
+ }
+ };
+ }
+
+ private static EventHandler>>> OnFunctionFound(ExpressionContext context, IReadingContext readingContext, IEvaluator evaluator, Simulation simulation)
{
return (sender, args) =>
{
@@ -366,7 +391,7 @@ private static double GetDerivativeValue(ExpressionContext context, IEvaluator e
public static bool HaveSpiceProperties(string expression, ExpressionContext context, ReadingContext readingContext, bool b)
{
bool present = false;
- var parser = GetDeriveParser(context, readingContext, null, null);
+ var parser = GetDeriveParser(context, readingContext, null, null, readingContext.CaseSensitivity);
parser.SpicePropertyFound += (sender, e) =>
{
present = true;
@@ -377,10 +402,10 @@ public static bool HaveSpiceProperties(string expression, ExpressionContext cont
return present;
}
- public static bool HaveFunctions(string expression, ExpressionContext context, ReadingContext readingContext, bool v)
+ public static bool HaveFunctions(string expression, ExpressionContext context, ReadingContext readingContext)
{
bool present = false;
- var parser = GetDeriveParser(context, readingContext, null, null);
+ var parser = GetDeriveParser(context, readingContext, null, null, readingContext.CaseSensitivity);
parser.FunctionFound += (sender, e) =>
{
present = true;