diff --git a/lib/calculator.dart b/lib/calculator.dart index c2792b2..e29e5f9 100644 --- a/lib/calculator.dart +++ b/lib/calculator.dart @@ -7,6 +7,9 @@ abstract class Expr { /// 新增:对表达式进行“求值/数值化”——尽可能把可算的部分算出来 Expr evaluate(); + /// Substitute variable with value + Expr substitute(String varName, Expr value); + @override String toString(); @@ -27,6 +30,9 @@ class IntExpr extends Expr { @override Expr evaluate() => this; + @override + Expr substitute(String varName, Expr value) => this; + @override String toString() => value.toString(); } @@ -42,10 +48,31 @@ class DoubleExpr extends Expr { @override Expr evaluate() => this; + @override + Expr substitute(String varName, Expr value) => this; + @override String toString() => value.toString(); } +// === VarExpr === +class VarExpr extends Expr { + final String name; + VarExpr(this.name); + + @override + Expr simplify() => this; + + @override + Expr evaluate() => this; + + @override + Expr substitute(String varName, Expr value) => name == varName ? value : this; + + @override + String toString() => name; +} + // === FractionExpr.evaluate === class FractionExpr extends Expr { final int numerator; @@ -74,6 +101,9 @@ class FractionExpr extends Expr { @override Expr evaluate() => simplify(); + @override + Expr substitute(String varName, Expr value) => this; + @override String toString() => "$numerator/$denominator"; } @@ -150,6 +180,12 @@ class AddExpr extends Expr { return AddExpr(l, r); } + @override + Expr substitute(String varName, Expr value) => AddExpr( + left.substitute(varName, value), + right.substitute(varName, value), + ); + @override String toString() => "($left + $right)"; } @@ -213,6 +249,12 @@ class SubExpr extends Expr { return SubExpr(l, r); } + @override + Expr substitute(String varName, Expr value) => SubExpr( + left.substitute(varName, value), + right.substitute(varName, value), + ); + @override String toString() => "($left - $right)"; } @@ -296,6 +338,12 @@ class MulExpr extends Expr { return MulExpr(l, r); } + @override + Expr substitute(String varName, Expr value) => MulExpr( + left.substitute(varName, value), + right.substitute(varName, value), + ); + @override String toString() => "($left * $right)"; } @@ -378,6 +426,12 @@ class DivExpr extends Expr { return DivExpr(l, r); } + @override + Expr substitute(String varName, Expr value) => DivExpr( + left.substitute(varName, value), + right.substitute(varName, value), + ); + @override String toString() => "($left / $right)"; } @@ -429,6 +483,10 @@ class SqrtExpr extends Expr { return SqrtExpr(i); } + @override + Expr substitute(String varName, Expr value) => + SqrtExpr(inner.substitute(varName, value)); + @override String toString() => "sqrt($inner)"; } @@ -456,6 +514,10 @@ class CosExpr extends Expr { return CosExpr(i); } + @override + Expr substitute(String varName, Expr value) => + CosExpr(inner.substitute(varName, value)); + @override String toString() => "cos($inner)"; } @@ -483,6 +545,10 @@ class SinExpr extends Expr { return SinExpr(i); } + @override + Expr substitute(String varName, Expr value) => + SinExpr(inner.substitute(varName, value)); + @override String toString() => "sin($inner)"; } @@ -510,6 +576,10 @@ class TanExpr extends Expr { return TanExpr(i); } + @override + Expr substitute(String varName, Expr value) => + TanExpr(inner.substitute(varName, value)); + @override String toString() => "tan($inner)"; } diff --git a/lib/parser.dart b/lib/parser.dart index f280afc..39555ae 100644 --- a/lib/parser.dart +++ b/lib/parser.dart @@ -99,6 +99,13 @@ class Parser { return TanExpr(inner); } + // 解析变量 (单个字母) + if (RegExp(r'[a-zA-Z]').hasMatch(current)) { + var varName = current; + eat(); + return VarExpr(varName); + } + // 解析整数 var buf = ''; while (!isEnd && RegExp(r'\d').hasMatch(current)) { diff --git a/lib/screens/calculator_home_page.dart b/lib/screens/calculator_home_page.dart index 8c744aa..d3cd51e 100644 --- a/lib/screens/calculator_home_page.dart +++ b/lib/screens/calculator_home_page.dart @@ -3,7 +3,8 @@ import 'package:latext/latext.dart'; import 'package:simple_math_calc/models/calculation_step.dart'; import 'package:simple_math_calc/solver.dart'; import 'package:fl_chart/fl_chart.dart'; -import 'package:math_expressions/math_expressions.dart' as math_expressions; +import 'package:simple_math_calc/calculator.dart'; +import 'package:simple_math_calc/parser.dart'; import 'dart:math'; class CalculatorHomePage extends StatefulWidget { @@ -70,11 +71,8 @@ class _CalculatorHomePageState extends State { ); // 解析表达式 - final parser = math_expressions.ShuntingYardParser(); - final expr = parser.parse(functionExpr); - - // 创建变量 x - final x = math_expressions.Variable('x'); + final parser = Parser(functionExpr); + final expr = parser.parse(); // 根据缩放因子动态调整范围和步长 final range = 10.0 * zoomFactor; @@ -84,13 +82,15 @@ class _CalculatorHomePageState extends State { List points = []; for (double i = -range; i <= range; i += step) { try { - final context = math_expressions.ContextModel() - ..bindVariable(x, math_expressions.Number(i)); - final evaluator = math_expressions.RealEvaluator(context); - final y = evaluator.evaluate(expr); + // 替换变量 x 为当前值 + final substituted = expr.substitute('x', DoubleExpr(i)); + final evaluated = substituted.evaluate(); - if (y.isFinite && !y.isNaN) { - points.add(FlSpot(i, y.toDouble())); + if (evaluated is DoubleExpr) { + final y = evaluated.value; + if (y.isFinite && !y.isNaN) { + points.add(FlSpot(i, y)); + } } } catch (e) { // 跳过无法计算的点 diff --git a/web/index.html b/web/index.html index 9b07bee..33b95b3 100644 --- a/web/index.html +++ b/web/index.html @@ -16,7 +16,7 @@ - +