|
@@ -0,0 +1,48 @@
|
|
|
+/**
|
|
|
+ * 公式编译
|
|
|
+ */
|
|
|
+class Formula {
|
|
|
+ private formula = "";
|
|
|
+ private watchers: string[] = [];
|
|
|
+ private ast: string[] = [];
|
|
|
+ constructor(_formula) {
|
|
|
+ this.formula = _formula;
|
|
|
+ this.compile();
|
|
|
+ }
|
|
|
+ private compile() {
|
|
|
+ // eslint-disable-next-line no-useless-escape
|
|
|
+ const ast = this.formula.split(/([\+\-\*\/\(\)])/);
|
|
|
+ this.ast = ast.filter((it) => it !== "");
|
|
|
+ this.ast.forEach((char) => {
|
|
|
+ if (this.isSymbol(char) || this.isStatic(char)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ this.watchers.push(char.split(/[\.\[]/)[0]);
|
|
|
+ });
|
|
|
+ }
|
|
|
+ private isSymbol(char: string) {
|
|
|
+ return /^[\+\-\*\/\(\)]{1}$/g.test(char);
|
|
|
+ }
|
|
|
+ private isStatic(char: string) {
|
|
|
+ return /[\"\']/.test(char) || /^\d+$/.test(char);
|
|
|
+ }
|
|
|
+ shouldUpdate(watcher: string) {
|
|
|
+ return this.watchers.includes(watcher);
|
|
|
+ }
|
|
|
+ result(_context: NonNullable<unknown>) {
|
|
|
+ const ast = this.ast.map((char) => {
|
|
|
+ if (this.isSymbol(char) || this.isStatic(char)) {
|
|
|
+ return char;
|
|
|
+ }
|
|
|
+ return char.replace(/(^[\.\[]*)/, "_context.$1");
|
|
|
+ });
|
|
|
+ return eval(ast.join(""));
|
|
|
+ }
|
|
|
+ destroy() {
|
|
|
+ this.formula = "";
|
|
|
+ this.watchers = [];
|
|
|
+ this.ast = [];
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+export { Formula };
|