@cloudpss/expression 0.6.0-alpha.12 → 0.6.0-alpha.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/dist/eval.d.ts +2 -2
  2. package/dist/eval.d.ts.map +1 -1
  3. package/dist/eval.js +1 -1
  4. package/dist/eval.js.map +1 -1
  5. package/dist/migrator/function.d.ts +6 -0
  6. package/dist/migrator/function.d.ts.map +1 -0
  7. package/dist/migrator/function.js +25 -0
  8. package/dist/migrator/function.js.map +1 -0
  9. package/dist/migrator/node.d.ts.map +1 -1
  10. package/dist/migrator/node.js +12 -21
  11. package/dist/migrator/node.js.map +1 -1
  12. package/dist/migrator/operator.d.ts.map +1 -1
  13. package/dist/migrator/operator.js +2 -1
  14. package/dist/migrator/operator.js.map +1 -1
  15. package/dist/migrator/serialize.d.ts +4 -0
  16. package/dist/migrator/serialize.d.ts.map +1 -0
  17. package/dist/migrator/serialize.js +21 -0
  18. package/dist/migrator/serialize.js.map +1 -0
  19. package/dist/migrator/state.d.ts.map +1 -1
  20. package/dist/migrator/state.js +9 -25
  21. package/dist/migrator/state.js.map +1 -1
  22. package/dist/migrator/symbol.d.ts.map +1 -1
  23. package/dist/migrator/symbol.js +4 -3
  24. package/dist/migrator/symbol.js.map +1 -1
  25. package/dist/migrator/to-type.js +1 -1
  26. package/dist/migrator/to-type.js.map +1 -1
  27. package/dist/migrator/utils.d.ts +2 -0
  28. package/dist/migrator/utils.d.ts.map +1 -1
  29. package/dist/migrator/utils.js +10 -0
  30. package/dist/migrator/utils.js.map +1 -1
  31. package/dist/parser.d.ts +1 -1
  32. package/dist/parser.d.ts.map +1 -1
  33. package/dist/parser.js +4 -2
  34. package/dist/parser.js.map +1 -1
  35. package/dist/scope.d.ts +4 -0
  36. package/dist/scope.d.ts.map +1 -1
  37. package/dist/scope.js +29 -5
  38. package/dist/scope.js.map +1 -1
  39. package/package.json +2 -2
  40. package/src/eval.ts +7 -3
  41. package/src/migrator/function.ts +27 -0
  42. package/src/migrator/node.ts +12 -19
  43. package/src/migrator/operator.ts +2 -1
  44. package/src/migrator/serialize.ts +21 -0
  45. package/src/migrator/state.ts +9 -26
  46. package/src/migrator/symbol.ts +4 -3
  47. package/src/migrator/to-type.ts +1 -1
  48. package/src/migrator/utils.ts +9 -0
  49. package/src/parser.ts +10 -4
  50. package/src/scope.ts +27 -5
  51. package/tests/migrate.ts +30 -0
package/dist/scope.d.ts CHANGED
@@ -18,6 +18,10 @@ export declare class Scope {
18
18
  throws?: boolean,
19
19
  /** 执行环境名称 */
20
20
  name?: string);
21
+ /** 枚举环境中的值 */
22
+ enumerator: (() => Iterable<string>) | null | undefined;
23
+ /** 描述环境中的值 */
24
+ describer: ((key: string) => string | undefined) | null | undefined;
21
25
  /** 执行器上下文 */
22
26
  protected evaluator: Evaluator | null;
23
27
  /** 求值计数 */
@@ -1 +1 @@
1
- {"version":3,"file":"scope.d.ts","sourceRoot":"","sources":["../src/scope.ts"],"names":[],"mappings":"AAAA,OAAO,EAKH,KAAK,SAAS,EAEd,KAAK,OAAO,EAEf,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACH,KAAK,kBAAkB,EACvB,KAAK,UAAU,EACf,KAAK,iBAAiB,EAGzB,MAAM,iBAAiB,CAAC;AAIzB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AA8D3C,cAAc;AACd,qBAAa,KAAK;IAIV,gBAAgB;IAChB,QAAQ,CAAC,KAAK,EACR,CAAC,CAAC,GAAG,EAAE,MAAM,KAAK,iBAAiB,GAAG,SAAS,CAAC,GAChD,MAAM,CAAC,MAAM,EAAE,iBAAiB,GAAG,SAAS,CAAC,GAC7C,IAAI;IACV,gBAAgB;IAChB,QAAQ,CAAC,MAAM;IACf,aAAa;IACb,QAAQ,CAAC,IAAI;IAXjB,aAAa;IACb,MAAM,CAAC,QAAQ,CAAC,aAAa,OAAO;;IAEhC,gBAAgB;IACP,KAAK,GACR,CAAC,CAAC,GAAG,EAAE,MAAM,KAAK,iBAAiB,GAAG,SAAS,CAAC,GAChD,MAAM,CAAC,MAAM,EAAE,iBAAiB,GAAG,SAAS,CAAC,GAC7C,IAAW;IACjB,gBAAgB;IACP,MAAM,UAAO;IACtB,aAAa;IACJ,IAAI,SAAgB;IAGjC,aAAa;IACb,SAAS,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI,CAAQ;IAC7C,WAAW;IACX,SAAS,CAAC,WAAW,SAAK;IAC1B,YAAY;IACZ,KAAK,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI,GAAG,MAAM,IAAI;IAU9C,mBAAmB;IACnB,SAAS,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAAQ;IAC1C,mBAAmB;IACnB,IAAI,KAAK,IAAI,SAAS,CAwBrB;IAED,oDAAoD;IACpD,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAYzB,kDAAkD;IAClD,GAAG,CAAC,CAAC,SAAS,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS;IAalD,cAAc;IACd,IAAI,CAAC,UAAU,EAAE,UAAU,GAAG,kBAAkB,EAAE,IAAI,EAAE,SAAS,WAAW,EAAE,GAAG,OAAO;CA6B3F;AAmBD,eAAe;AACf,wBAAgB,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAErC"}
1
+ {"version":3,"file":"scope.d.ts","sourceRoot":"","sources":["../src/scope.ts"],"names":[],"mappings":"AAAA,OAAO,EAKH,KAAK,SAAS,EAEd,KAAK,OAAO,EAEf,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACH,KAAK,kBAAkB,EACvB,KAAK,UAAU,EACf,KAAK,iBAAiB,EAGzB,MAAM,iBAAiB,CAAC;AAIzB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AA8D3C,cAAc;AACd,qBAAa,KAAK;IAIV,gBAAgB;IAChB,QAAQ,CAAC,KAAK,EACR,CAAC,CAAC,GAAG,EAAE,MAAM,KAAK,iBAAiB,GAAG,SAAS,CAAC,GAChD,MAAM,CAAC,MAAM,EAAE,iBAAiB,GAAG,SAAS,CAAC,GAC7C,IAAI;IACV,gBAAgB;IAChB,QAAQ,CAAC,MAAM;IACf,aAAa;IACb,QAAQ,CAAC,IAAI;IAXjB,aAAa;IACb,MAAM,CAAC,QAAQ,CAAC,aAAa,OAAO;;IAEhC,gBAAgB;IACP,KAAK,GACR,CAAC,CAAC,GAAG,EAAE,MAAM,KAAK,iBAAiB,GAAG,SAAS,CAAC,GAChD,MAAM,CAAC,MAAM,EAAE,iBAAiB,GAAG,SAAS,CAAC,GAC7C,IAAW;IACjB,gBAAgB;IACP,MAAM,UAAO;IACtB,aAAa;IACJ,IAAI,SAAgB;IAEjC,cAAc;IACd,UAAU,EAAE,CAAC,MAAM,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,CAAQ;IAC/D,cAAc;IACd,SAAS,EAAE,CAAC,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC,GAAG,IAAI,GAAG,SAAS,CAAQ;IAE3E,aAAa;IACb,SAAS,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI,CAAQ;IAC7C,WAAW;IACX,SAAS,CAAC,WAAW,SAAK;IAC1B,YAAY;IACZ,KAAK,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI,GAAG,MAAM,IAAI;IAU9C,mBAAmB;IACnB,SAAS,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAAQ;IAC1C,mBAAmB;IACnB,IAAI,KAAK,IAAI,SAAS,CA4CrB;IAED,oDAAoD;IACpD,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAYzB,kDAAkD;IAClD,GAAG,CAAC,CAAC,SAAS,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS;IAalD,cAAc;IACd,IAAI,CAAC,UAAU,EAAE,UAAU,GAAG,kBAAkB,EAAE,IAAI,EAAE,SAAS,WAAW,EAAE,GAAG,OAAO;CA2B3F;AAmBD,eAAe;AACf,wBAAgB,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAErC"}
package/dist/scope.js CHANGED
@@ -72,6 +72,10 @@ export class Scope {
72
72
  this.scope = scope;
73
73
  this.throws = throws;
74
74
  this.name = name;
75
+ /** 枚举环境中的值 */
76
+ this.enumerator = null;
77
+ /** 描述环境中的值 */
78
+ this.describer = null;
75
79
  /** 执行器上下文 */
76
80
  this.evaluator = null;
77
81
  /** 求值计数 */
@@ -95,9 +99,13 @@ export class Scope {
95
99
  if (this._proxy != null)
96
100
  return this._proxy;
97
101
  let getter;
98
- const { scope } = this;
102
+ let enumerate;
103
+ let describe;
104
+ const { scope, enumerator, describer } = this;
99
105
  if (scope == null) {
100
106
  getter = (key) => this.evaluator?.imported.get(key);
107
+ enumerate = () => this.evaluator?.imported.keys() ?? [];
108
+ describe = () => undefined;
101
109
  }
102
110
  else if (typeof scope == 'function') {
103
111
  getter = (key) => {
@@ -119,7 +127,25 @@ export class Scope {
119
127
  return createProxy(v, this, [key]);
120
128
  };
121
129
  }
122
- const proxy = createVmContext(getter);
130
+ if (typeof enumerator == 'function') {
131
+ enumerate = () => {
132
+ const keys = enumerator();
133
+ const imported = this.evaluator?.imported.keys() ?? [];
134
+ return [...keys, ...imported];
135
+ };
136
+ }
137
+ else {
138
+ enumerate = () => this.evaluator?.imported.keys() ?? [];
139
+ }
140
+ if (typeof describer == 'function') {
141
+ describe = (key) => {
142
+ const d = describer(key);
143
+ if (d)
144
+ return d;
145
+ return undefined;
146
+ };
147
+ }
148
+ const proxy = createVmContext(getter, enumerate, describe);
123
149
  this._proxy = proxy;
124
150
  return proxy;
125
151
  }
@@ -156,6 +182,7 @@ export class Scope {
156
182
  /** 表达式递归求值 */
157
183
  eval(expression, path) {
158
184
  if (this.evalCounter >= Scope.MAX_RECURSION) {
185
+ this.evalCounter = 0;
159
186
  throw new Error(`Execution recursion exceeds limit`);
160
187
  }
161
188
  this.evalCounter++;
@@ -166,9 +193,6 @@ export class Scope {
166
193
  }
167
194
  else {
168
195
  const { evaluator } = this;
169
- if (!evaluator) {
170
- throw new Error(`Undefined evaluator`);
171
- }
172
196
  const exp = parse(evaluator, expression.source, this.throws, false);
173
197
  if (exp.func != null) {
174
198
  result = evaluateEval(evaluator, exp, this);
package/dist/scope.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"scope.js","sourceRoot":"","sources":["../src/scope.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"scope.js","sourceRoot":"","sources":["../src/scope.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloudpss/expression",
3
- "version": "0.6.0-alpha.12",
3
+ "version": "0.6.0-alpha.14",
4
4
  "author": "CloudPSS",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -12,7 +12,7 @@
12
12
  "./*": "./dist/*.js"
13
13
  },
14
14
  "dependencies": {
15
- "@mirascript/mirascript": "^0.1.9",
15
+ "@mirascript/mirascript": "^0.1.13",
16
16
  "klona": "^2.0.6",
17
17
  "lru-cache": "^11.2.2",
18
18
  "mathjs": "^15.1.0",
package/src/eval.ts CHANGED
@@ -7,7 +7,7 @@ import type { Evaluator } from './main.js';
7
7
  * 表达式求值
8
8
  */
9
9
  export function evaluateEval<T extends VmValue>(
10
- evaluator: Evaluator,
10
+ evaluator: Evaluator | null,
11
11
  expression: EvalExpressionCache,
12
12
  scope: Scope,
13
13
  ): T | null {
@@ -17,7 +17,7 @@ export function evaluateEval<T extends VmValue>(
17
17
  return unwrap(result as T);
18
18
  } catch (error: unknown) {
19
19
  if (scope.throws) throw error;
20
- evaluator.logger.warn(
20
+ (evaluator?.logger ?? console).warn(
21
21
  `Failed to execute expression "${expression.source}": ${(error as Error).message || String(error)}.`,
22
22
  {
23
23
  error,
@@ -31,7 +31,11 @@ export function evaluateEval<T extends VmValue>(
31
31
  /**
32
32
  * 表达式求值
33
33
  */
34
- export function evaluate<T extends VmValue>(evaluator: Evaluator, expression: ExpressionCache, scope: Scope): T | null {
34
+ export function evaluate<T extends VmValue>(
35
+ evaluator: Evaluator | null,
36
+ expression: ExpressionCache,
37
+ scope: Scope,
38
+ ): T | null {
35
39
  let ret: T | null = null;
36
40
  if (expression.func != null) {
37
41
  scope ??= new Scope();
@@ -0,0 +1,27 @@
1
+ import type { FunctionAssignmentNode } from 'mathjs';
2
+ import type { Result } from './interface.js';
3
+ import { migrateAtomic } from './node.js';
4
+ import { type State, FunctionState } from './state.js';
5
+ import { migrateSymbolName } from './utils.js';
6
+
7
+ /** 转换函数定义语句 */
8
+ export function migrateFunctionAssignment(state: State, node: FunctionAssignmentNode): Result {
9
+ state.loose();
10
+ const { name, params, expr } = node;
11
+ const fState = new FunctionState(state, params);
12
+ let body = migrateAtomic(fState, expr);
13
+ if (!(body.code.startsWith('{') && body.code.endsWith('}'))) {
14
+ body = { ...body, code: `{ ${body.code} }` };
15
+ }
16
+ if (state.locals.has(name)) {
17
+ state.err(`重复定义函数: '${name}'`);
18
+ }
19
+ state.locals.set(name, {
20
+ type: 'function',
21
+ code: body.code,
22
+ });
23
+ return {
24
+ type: 'function',
25
+ code: `fn ${migrateSymbolName(name, true)}(${params.join(', ')}) ${body.code}`,
26
+ };
27
+ }
@@ -1,4 +1,4 @@
1
- import { serialize, serializePropName } from '@mirascript/mirascript/subtle';
1
+ import { serializePropName } from '@mirascript/mirascript/subtle';
2
2
  import {
3
3
  type MathNode,
4
4
  isAccessorNode,
@@ -12,6 +12,7 @@ import {
12
12
  isRelationalNode,
13
13
  type OperatorNodeFn,
14
14
  isSymbolNode,
15
+ isFunctionAssignmentNode,
15
16
  } from 'mathjs';
16
17
  import type { State } from './state.js';
17
18
  import type { Options, Result } from './interface.js';
@@ -22,6 +23,8 @@ import { migrateCall } from './call.js';
22
23
  import { migrateOperator } from './operator.js';
23
24
  import { migrateSymbol } from './symbol.js';
24
25
  import { migrateCondition } from './condition.js';
26
+ import { migrateFunctionAssignment } from './function.js';
27
+ import { serialize } from './serialize.js';
25
28
 
26
29
  /** 转换 AST */
27
30
  export function migrateAtomic(state: State, node: MathNode): Result {
@@ -41,23 +44,6 @@ export function migrateNode(state: State, node: MathNode, options: Options): Res
41
44
  if (isConstantNode(node)) {
42
45
  const { value } = node;
43
46
  if (value == null) return { code: 'nil', literal: null, type: 'nil' };
44
- if (typeof value === 'number' && Number.isFinite(value) && value !== 0) {
45
- const p1 = value.toString();
46
- const p2 = value.toExponential();
47
- if (p2.length < p1.length) {
48
- return {
49
- code: p2,
50
- literal: value,
51
- type: 'number',
52
- };
53
- } else {
54
- return {
55
- code: p1,
56
- literal: value,
57
- type: 'number',
58
- };
59
- }
60
- }
61
47
  return {
62
48
  code: serialize(value),
63
49
  literal: value,
@@ -141,8 +127,15 @@ export function migrateNode(state: State, node: MathNode, options: Options): Res
141
127
  code,
142
128
  };
143
129
  }
130
+ if (isFunctionAssignmentNode(node)) {
131
+ const result = migrateFunctionAssignment(state, node);
132
+ state.helper(result.code);
133
+ return {
134
+ type: 'function',
135
+ code: node.name,
136
+ };
137
+ }
144
138
  // if (isRangeNode(node)) {
145
139
  // if (isIndexNode(node)) {
146
- // if (isFunctionAssignmentNode(node)) {
147
140
  return unsupportedNode(state, node);
148
141
  }
@@ -8,13 +8,14 @@ import {
8
8
  isOperatorNode,
9
9
  isNode,
10
10
  } from 'mathjs';
11
+ import { operations } from '@mirascript/mirascript/subtle';
11
12
  import { symbolName, constantValue, equalText, scalar, globalFnName } from './utils.js';
12
13
  import type { State } from './state.js';
13
14
  import type { Options, Result } from './interface.js';
14
15
  import { migrateAtomic, migrateExpr } from './node.js';
15
16
  import { toBoolean, toNumber } from './to-type.js';
16
17
  import { migrateSymbol } from './symbol.js';
17
- import { operations, serialize } from '@mirascript/mirascript/subtle';
18
+ import { serialize } from './serialize.js';
18
19
 
19
20
  const BINARY_MATH_OPERATORS = {
20
21
  add: [
@@ -0,0 +1,21 @@
1
+ import type { VmValue } from '@mirascript/mirascript';
2
+ import { serialize as s, serializeNumber } from '@mirascript/mirascript/subtle';
3
+
4
+ /** 序列化 */
5
+ export function serialize(value: VmValue): string {
6
+ return s(value, {
7
+ serializeNumber: (value: number): string => {
8
+ if (!Number.isFinite(value) || value === 0) {
9
+ return serializeNumber(value);
10
+ }
11
+ const p1 = value.toString();
12
+ const p2 = value.toExponential();
13
+ // 还是优先选择默认的形式,除非指数形式更短很多
14
+ if (p2.length + 2 < p1.length) {
15
+ return p2;
16
+ } else {
17
+ return p1;
18
+ }
19
+ },
20
+ });
21
+ }
@@ -2,7 +2,6 @@ import type { VmContext } from '@mirascript/mirascript';
2
2
  import { parse } from './parser.js';
3
3
  import {
4
4
  type AssignmentNode,
5
- type FunctionAssignmentNode,
6
5
  isAssignmentNode,
7
6
  isBlockNode,
8
7
  isFunctionAssignmentNode,
@@ -12,9 +11,10 @@ import {
12
11
  import type { Result } from './interface.js';
13
12
  import { migrateAtomic } from './node.js';
14
13
  import { toBoolean } from './to-type.js';
15
- import { constantValue, symbolName, unsupportedNode } from './utils.js';
14
+ import { constantValue, migrateSymbolName, symbolName, unsupportedNode } from './utils.js';
16
15
  import { migrateAccess } from './access.js';
17
16
  import { specialMigrate } from './special.js';
17
+ import { migrateFunctionAssignment } from './function.js';
18
18
 
19
19
  /** 转换 AST */
20
20
  function migrateLast(state: State, node: MathNode): Result {
@@ -38,17 +38,20 @@ function migrateAssignment(state: State, node: AssignmentNode): Result {
38
38
  const { object, index, value } = node;
39
39
  const name = symbolName(object);
40
40
  if (name && index == null) {
41
- // name = xxx;
41
+ const localName = migrateSymbolName(name, true);
42
42
  if (state.locals.has(name)) {
43
- state.err(`不支持局部变量重新赋值: ${name}'`);
43
+ state.err(`不支持局部变量重新赋值: '${name}'`);
44
44
  return {
45
- code: `${name} = ${migrateAtomic(state, value).code}`,
45
+ code: `${localName} = ${migrateAtomic(state, value).code}`,
46
46
  };
47
47
  }
48
48
  const expr = migrateAtomic(state, value);
49
49
  state.locals.set(name, expr);
50
+ if (name !== localName) {
51
+ state.warn(`变量名 '${name}' 是 MiraScript 关键字,已转换为 '${localName}'`);
52
+ }
50
53
  return {
51
- code: `let ${name} = ${expr.code};`,
54
+ code: `let ${localName} = ${expr.code};`,
52
55
  };
53
56
  }
54
57
  if (index != null) {
@@ -60,26 +63,6 @@ function migrateAssignment(state: State, node: AssignmentNode): Result {
60
63
  }
61
64
  return unsupportedNode(state, node);
62
65
  }
63
- /** 转换函数定义语句 */
64
- function migrateFunctionAssignment(state: State, node: FunctionAssignmentNode): Result {
65
- state.loose();
66
- const { name, params, expr } = node;
67
- if (state.locals.has(name)) {
68
- state.err(`重复定义函数: ${name}`);
69
- }
70
- const fState = new FunctionState(state, params);
71
- let body = migrateAtomic(fState, expr);
72
- if (!(body.code.startsWith('{') && body.code.endsWith('}'))) {
73
- body = { ...body, code: `{ ${body.code} }` };
74
- }
75
- state.locals.set(name, {
76
- type: 'function',
77
- code: body.code,
78
- });
79
- return {
80
- code: `fn ${name}(${params.join(', ')}) ${body.code}`,
81
- };
82
- }
83
66
 
84
67
  /** 转换状态 */
85
68
  export class BaseState {
@@ -2,6 +2,7 @@ import type { SymbolNode } from 'mathjs';
2
2
  import type { Result } from './interface.js';
3
3
  import type { State } from './state.js';
4
4
  import { operations } from '@mirascript/mirascript/subtle';
5
+ import { migrateSymbolName } from './utils.js';
5
6
 
6
7
  /** 处理符号名称 */
7
8
  export function migrateSymbol(state: State, node: SymbolNode, migrateConst: boolean): Result {
@@ -10,14 +11,14 @@ export function migrateSymbol(state: State, node: SymbolNode, migrateConst: bool
10
11
  if (local) {
11
12
  return {
12
13
  ...local,
13
- code: name,
14
+ code: migrateSymbolName(name, true),
14
15
  };
15
16
  }
16
17
  const global = state.globals.get(name);
17
18
  if (global != null) {
18
19
  return {
19
20
  type: operations.$Type(global),
20
- code: name,
21
+ code: migrateSymbolName(name, false),
21
22
  global,
22
23
  };
23
24
  }
@@ -61,6 +62,6 @@ export function migrateSymbol(state: State, node: SymbolNode, migrateConst: bool
61
62
  }
62
63
  state.warn(`符号 '${name}' 未定义`);
63
64
  return {
64
- code: name,
65
+ code: migrateSymbolName(name, false),
65
66
  };
66
67
  }
@@ -1,6 +1,6 @@
1
1
  import { isConstantNode, isNode, type MathNode } from 'mathjs';
2
2
  import type { Result } from './interface.js';
3
- import { serialize } from '@mirascript/mirascript/subtle';
3
+ import { serialize } from './serialize.js';
4
4
  import type { State } from './state.js';
5
5
  import { migrateNode } from './node.js';
6
6
  import { globalFnName } from './utils.js';
@@ -1,4 +1,5 @@
1
1
  import { type MathNode, isSymbolNode, isConstantNode } from 'mathjs';
2
+ import { keywords } from '@mirascript/mirascript/subtle';
2
3
  import type { Result } from './interface.js';
3
4
  import type { State } from './state.js';
4
5
  import { toString } from './to-type.js';
@@ -18,6 +19,14 @@ export function symbolName(node: MathNode): string | undefined {
18
19
  return node.name;
19
20
  }
20
21
 
22
+ const kw = new Set(keywords());
23
+ /** 转换为 mirascript 符号 */
24
+ export function migrateSymbolName(name: string, local: boolean): string {
25
+ if (!kw.has(name)) return name;
26
+ if (local) return `__${name}__`;
27
+ return `global.${name}`;
28
+ }
29
+
21
30
  /** 获取 constant value */
22
31
  export function constantValue(node: MathNode): number | string | boolean | null | undefined {
23
32
  if (!isConstantNode(node)) return undefined;
package/src/parser.ts CHANGED
@@ -57,7 +57,8 @@ const kTemplateCache = Symbol('cloudpss.expression.templateCache');
57
57
  const kExpressionCache = Symbol('cloudpss.expression.expressionCache');
58
58
 
59
59
  /** 获取编译缓存 */
60
- function getCache(evaluator: Evaluator, template: boolean): LRUCache<string, EvalExpressionCache> {
60
+ function getCache(evaluator: Evaluator | null, template: boolean): LRUCache<string, EvalExpressionCache> | null {
61
+ if (evaluator == null) return null;
61
62
  const key = template ? kTemplateCache : kExpressionCache;
62
63
  if (!(key in evaluator)) {
63
64
  const size = template ? evaluator.options.templateCacheSize : evaluator.options.expressionCacheSize;
@@ -71,18 +72,23 @@ function getCache(evaluator: Evaluator, template: boolean): LRUCache<string, Eva
71
72
  /**
72
73
  * 解析表达式
73
74
  */
74
- export function parse(evaluator: Evaluator, expression: string, throws: boolean, template: boolean): ExpressionCache {
75
+ export function parse(
76
+ evaluator: Evaluator | null,
77
+ expression: string,
78
+ throws: boolean,
79
+ template: boolean,
80
+ ): ExpressionCache {
75
81
  if (typeof expression != 'string') {
76
82
  throw new TypeError(`${String(expression)} is not a valid expression`);
77
83
  }
78
84
  const cache = getCache(evaluator, template);
79
- const cached = cache.get(expression);
85
+ const cached = cache?.get(expression);
80
86
  if (cached != null) return cached;
81
87
  const complied = compile(expression, template);
82
88
  if (complied.error) {
83
89
  if (throws) throw complied.error;
84
90
  } else {
85
- cache.set(expression, complied);
91
+ cache?.set(expression, complied);
86
92
  }
87
93
  return complied;
88
94
  }
package/src/scope.ts CHANGED
@@ -95,6 +95,10 @@ export class Scope {
95
95
  /** 执行环境名称 */
96
96
  readonly name = '<anonymous>',
97
97
  ) {}
98
+ /** 枚举环境中的值 */
99
+ enumerator: (() => Iterable<string>) | null | undefined = null;
100
+ /** 描述环境中的值 */
101
+ describer: ((key: string) => string | undefined) | null | undefined = null;
98
102
 
99
103
  /** 执行器上下文 */
100
104
  protected evaluator: Evaluator | null = null;
@@ -117,9 +121,13 @@ export class Scope {
117
121
  get proxy(): VmContext {
118
122
  if (this._proxy != null) return this._proxy;
119
123
  let getter: (key: string) => VmAny;
120
- const { scope } = this;
124
+ let enumerate: () => Iterable<string>;
125
+ let describe: ((key: string) => string | undefined) | undefined;
126
+ const { scope, enumerator, describer } = this;
121
127
  if (scope == null) {
122
128
  getter = (key) => this.evaluator?.imported.get(key);
129
+ enumerate = () => this.evaluator?.imported.keys() ?? [];
130
+ describe = () => undefined;
123
131
  } else if (typeof scope == 'function') {
124
132
  getter = (key) => {
125
133
  const v = scope(key);
@@ -135,7 +143,23 @@ export class Scope {
135
143
  return createProxy(v, this, [key]) as VmValue;
136
144
  };
137
145
  }
138
- const proxy = createVmContext(getter);
146
+ if (typeof enumerator == 'function') {
147
+ enumerate = () => {
148
+ const keys = enumerator();
149
+ const imported = this.evaluator?.imported.keys() ?? [];
150
+ return [...keys, ...imported];
151
+ };
152
+ } else {
153
+ enumerate = () => this.evaluator?.imported.keys() ?? [];
154
+ }
155
+ if (typeof describer == 'function') {
156
+ describe = (key) => {
157
+ const d = describer(key);
158
+ if (d) return d;
159
+ return undefined;
160
+ };
161
+ }
162
+ const proxy = createVmContext(getter, enumerate, describe);
139
163
  this._proxy = proxy;
140
164
  return proxy;
141
165
  }
@@ -170,6 +194,7 @@ export class Scope {
170
194
  /** 表达式递归求值 */
171
195
  eval(expression: Expression | CompiledExpression, path: readonly PropertyKey[]): VmValue {
172
196
  if (this.evalCounter >= Scope.MAX_RECURSION) {
197
+ this.evalCounter = 0;
173
198
  throw new Error(`Execution recursion exceeds limit`);
174
199
  }
175
200
 
@@ -180,9 +205,6 @@ export class Scope {
180
205
  result = expression(this, this.evaluator!);
181
206
  } else {
182
207
  const { evaluator } = this;
183
- if (!evaluator) {
184
- throw new Error(`Undefined evaluator`);
185
- }
186
208
  const exp = parse(evaluator, expression.source, this.throws, false);
187
209
  if (exp.func != null) {
188
210
  result = evaluateEval(evaluator, exp, this);
package/tests/migrate.ts CHANGED
@@ -17,6 +17,7 @@ const s = new Scope({
17
17
  x: 1,
18
18
  y: 2,
19
19
  },
20
+ type: 'keyword',
20
21
  });
21
22
  const e = new Evaluator();
22
23
 
@@ -194,6 +195,35 @@ describe('migrate', () => {
194
195
  `,
195
196
  [1, 1, 2, 3],
196
197
  ],
198
+ [`equalText(type, "keyword")`, `global.type == 'keyword'`, true],
199
+ [
200
+ `type = { "a": [1,2,3] }; type.a[1]`,
201
+ dedent`
202
+ let __type__ = (a: [1, 2, 3]);
203
+ return @@maybe_chars(__type__.a)[0];
204
+ // # 帮助函数
205
+ fn @@maybe_chars(x) { if type(x) == 'string' { chars(x) } else { x } }
206
+ // # 转换日志
207
+ // - W: 变量名 'type' 是 MiraScript 关键字,已转换为 '__type__'
208
+ // # 原始 math.js 表达式
209
+ // type = { "a": [1,2,3] }; type.a[1]
210
+ `,
211
+ 1,
212
+ ],
213
+ [
214
+ '[1,2,3].map(f(x,y,z) = x^2)',
215
+ dedent`
216
+ return [1, 2, 3]::map(f);
217
+ // # 帮助函数
218
+ fn f(x, y, z) { x^2 }
219
+ // # 转换日志
220
+ // - W: 使用了非精确转换的语法或函数,结果可能不准确
221
+ // - W: '^' 不支持矩阵,计算结果可能不一致
222
+ // # 原始 math.js 表达式
223
+ // [1,2,3].map(f(x,y,z) = x^2)
224
+ `,
225
+ [1, 4, 9],
226
+ ],
197
227
  ])('should migrate expression: %s', (f, t, r) => {
198
228
  const migrated = migrateMathJs(f as ExpressionSource, false, s);
199
229
  expect(migrated).toBe(t);