@rsconcept/domain 3.0.2 → 3.1.1
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.
- package/dist/{analyzer-CzFaWR7w.d.ts → analyzer-B35QsI3L.d.ts} +2 -2
- package/dist/{ast-annotations-x4PJ_Lhc.d.ts → ast-annotations-DclU1Ser.d.ts} +2 -2
- package/dist/{calculator-uPaTV3hc.d.ts → calculator-B-1p712X.d.ts} +2 -2
- package/dist/{diagnostics-DKyMf6q-.d.ts → diagnostics-D4_B7rt2.d.ts} +3 -3
- package/dist/{diagnostics-D1Cp21nP.js → diagnostics-D_4TpAH4.js} +4 -5
- package/dist/{diagnostics-D1Cp21nP.js.map → diagnostics-D_4TpAH4.js.map} +1 -1
- package/dist/{error-B0EkIx4K.d.ts → error-S1JghCNN.d.ts} +30 -2
- package/dist/{index-CnuO4w8e.d.ts → index-D-w-bgei.d.ts} +4 -4
- package/dist/{index-DCO4mxiO.d.ts → index-DzvllU3P.d.ts} +4 -4
- package/dist/index.d.ts +6 -6
- package/dist/index.js +4 -4
- package/dist/library/diagnostics.d.ts +1 -1
- package/dist/library/diagnostics.js +1 -1
- package/dist/library/index.d.ts +2 -2
- package/dist/library/index.js +1 -1
- package/dist/library/oss-api.d.ts +1 -1
- package/dist/library/oss-api.js +2 -4
- package/dist/library/oss-api.js.map +1 -1
- package/dist/library/oss.js +1 -1
- package/dist/library/rsengine.d.ts +3 -3
- package/dist/library/rsengine.js +4 -3
- package/dist/library/rsengine.js.map +1 -1
- package/dist/library/rsform-api/index.d.ts +1 -1
- package/dist/library/rsform-api/index.js +1 -1
- package/dist/library/rsform.d.ts +1 -1
- package/dist/library/rsmodel-api.d.ts +3 -3
- package/dist/library/rsmodel-api.js +20 -4
- package/dist/library/rsmodel-api.js.map +1 -1
- package/dist/library/rsmodel.d.ts +1 -1
- package/dist/library/structure-planner.d.ts +2 -2
- package/dist/library/structure-planner.js +1 -1
- package/dist/parsing/lezer-tree.js.map +1 -1
- package/dist/rslang/api.js +9 -6
- package/dist/rslang/api.js.map +1 -1
- package/dist/rslang/ast-annotations.d.ts +1 -1
- package/dist/rslang/error.d.ts +2 -2
- package/dist/rslang/error.js +16 -1
- package/dist/rslang/error.js.map +1 -1
- package/dist/rslang/eval/calculator.d.ts +1 -1
- package/dist/rslang/eval/calculator.js +1 -1
- package/dist/rslang/eval/evaluation-cache.js +1 -3
- package/dist/rslang/eval/evaluation-cache.js.map +1 -1
- package/dist/rslang/eval/evaluator.d.ts +12 -2
- package/dist/rslang/eval/evaluator.js +42 -8
- package/dist/rslang/eval/evaluator.js.map +1 -1
- package/dist/rslang/eval/value-api.js +1 -1
- package/dist/rslang/eval/value.js +1 -1
- package/dist/rslang/index.d.ts +6 -6
- package/dist/rslang/index.js +3 -3
- package/dist/rslang/parser/normalize.js.map +1 -1
- package/dist/rslang/parser/parser.terms.js.map +1 -1
- package/dist/rslang/parser/syntax-errors/index.d.ts +1 -1
- package/dist/rslang/semantic/analyzer.d.ts +1 -1
- package/dist/rslang/semantic/arguments-extractor.js +6 -4
- package/dist/rslang/semantic/arguments-extractor.js.map +1 -1
- package/dist/rslang/semantic/type-auditor.d.ts +1 -1
- package/dist/rslang/semantic/type-auditor.js +20 -16
- package/dist/rslang/semantic/type-auditor.js.map +1 -1
- package/dist/rslang/semantic/typification-api.js +10 -9
- package/dist/rslang/semantic/typification-api.js.map +1 -1
- package/dist/rslang/semantic/typification-parser.js +4 -1
- package/dist/rslang/semantic/typification-parser.js.map +1 -1
- package/dist/rslang/semantic/value-auditor.d.ts +1 -1
- package/dist/{value-COprb2Je.js → value-BDISzQqI.js} +3 -2
- package/dist/{value-COprb2Je.js.map → value-BDISzQqI.js.map} +1 -1
- package/package.json +23 -22
- package/src/index.ts +1 -1
- package/src/library/rsmodel-api.ts +27 -0
- package/src/rslang/error.test.ts +23 -0
- package/src/rslang/error.ts +42 -0
- package/src/rslang/eval/evaluator.test.ts +56 -1
- package/src/rslang/eval/evaluator.ts +50 -7
- package/src/rslang/index.ts +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rsconcept/domain",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.1.1",
|
|
4
4
|
"description": "Shared TypeScript domain for RS language, RSForm, RSModel, RSEngine, OSS, and concept-text helpers.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "IRBorisov",
|
|
@@ -154,36 +154,37 @@
|
|
|
154
154
|
"README.md",
|
|
155
155
|
"LICENSE"
|
|
156
156
|
],
|
|
157
|
+
"scripts": {
|
|
158
|
+
"generate": "lezer-generator src/rslang/parser/rslang.grammar -o src/rslang/parser/parser.ts",
|
|
159
|
+
"build": "tsdown",
|
|
160
|
+
"dev": "tsdown --watch",
|
|
161
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
162
|
+
"test": "vitest run",
|
|
163
|
+
"lint": "eslint . --report-unused-disable-directives --max-warnings 0",
|
|
164
|
+
"lintFix": "eslint . --report-unused-disable-directives --max-warnings 0 --fix",
|
|
165
|
+
"format": "prettier --write \"src/**/*.ts\" \"*.{ts,js}\"",
|
|
166
|
+
"format:check": "prettier --check \"src/**/*.ts\" \"*.{ts,js}\"",
|
|
167
|
+
"prepublishOnly": "pnpm run build"
|
|
168
|
+
},
|
|
157
169
|
"dependencies": {
|
|
158
170
|
"@lezer/common": "^1.5.2",
|
|
159
171
|
"@lezer/lr": "^1.4.10"
|
|
160
172
|
},
|
|
161
173
|
"devDependencies": {
|
|
162
174
|
"@lezer/generator": "^1.8.0",
|
|
163
|
-
"@types/node": "^26.
|
|
164
|
-
"@typescript-eslint/parser": "^8.
|
|
165
|
-
"eslint": "^9.
|
|
166
|
-
"eslint-plugin-simple-import-sort": "^
|
|
167
|
-
"globals": "^17.
|
|
168
|
-
"prettier": "^3.9.
|
|
169
|
-
"tsdown": "^0.22.
|
|
175
|
+
"@types/node": "^26.4.0",
|
|
176
|
+
"@typescript-eslint/parser": "^8.69.0",
|
|
177
|
+
"eslint": "^10.9.1",
|
|
178
|
+
"eslint-plugin-simple-import-sort": "^14.0.0",
|
|
179
|
+
"globals": "^17.11.0",
|
|
180
|
+
"prettier": "^3.9.6",
|
|
181
|
+
"tsdown": "^0.22.14",
|
|
170
182
|
"typescript": "^6.0.3",
|
|
171
|
-
"typescript-eslint": "^8.
|
|
183
|
+
"typescript-eslint": "^8.69.0",
|
|
172
184
|
"unrun": "^0.3.1",
|
|
173
|
-
"vitest": "^4.1.
|
|
185
|
+
"vitest": "^4.1.11"
|
|
174
186
|
},
|
|
175
187
|
"publishConfig": {
|
|
176
188
|
"access": "public"
|
|
177
|
-
},
|
|
178
|
-
"scripts": {
|
|
179
|
-
"generate": "lezer-generator src/rslang/parser/rslang.grammar -o src/rslang/parser/parser.ts",
|
|
180
|
-
"build": "tsdown",
|
|
181
|
-
"dev": "tsdown --watch",
|
|
182
|
-
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
183
|
-
"test": "vitest run",
|
|
184
|
-
"lint": "eslint . --report-unused-disable-directives --max-warnings 0",
|
|
185
|
-
"lintFix": "eslint . --report-unused-disable-directives --max-warnings 0 --fix",
|
|
186
|
-
"format": "prettier --write \"src/**/*.ts\" \"*.{ts,js}\"",
|
|
187
|
-
"format:check": "prettier --check \"src/**/*.ts\" \"*.{ts,js}\""
|
|
188
189
|
}
|
|
189
|
-
}
|
|
190
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -81,7 +81,7 @@ export {
|
|
|
81
81
|
} from './parsing/ast';
|
|
82
82
|
export { type CMSyntaxNode, printTree } from './parsing/lezer-tree';
|
|
83
83
|
export { readErrorAnnotation, readTypeAnnotation } from './rslang/ast-annotations';
|
|
84
|
-
export { RSErrorCode, type RSErrorDescription } from './rslang/error';
|
|
84
|
+
export { type EvalStackFrame, formatEvalCallStack,RSErrorCode, type RSErrorDescription } from './rslang/error';
|
|
85
85
|
export { type CalculatorEvaluateOptions, type CalculatorResult, RSCalculator } from './rslang/eval/calculator';
|
|
86
86
|
export { makeValuePath, TUPLE_ID, type Value, type ValuePath } from './rslang/eval/value';
|
|
87
87
|
export { printValue } from './rslang/eval/value-api';
|
|
@@ -71,6 +71,11 @@ export function generateRandomValue(
|
|
|
71
71
|
return tuple(factors);
|
|
72
72
|
}
|
|
73
73
|
case TypeID.collection: {
|
|
74
|
+
// Empty set is a valid sample only when the element domain itself is generatable.
|
|
75
|
+
// When the count happens to be 0 we would otherwise skip sampling and miss empty basics.
|
|
76
|
+
if (!canGenerateRandomValue(type.base, basics, cstByAlias)) {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
74
79
|
const result: Value[] = [];
|
|
75
80
|
const randomElementsCount = Math.floor(Math.random() * (setElementsCount + 1));
|
|
76
81
|
for (let i = 0; i < randomElementsCount; i++) {
|
|
@@ -331,6 +336,28 @@ export function addValueElement(
|
|
|
331
336
|
|
|
332
337
|
// ========= Internal functions ==========
|
|
333
338
|
|
|
339
|
+
function canGenerateRandomValue(
|
|
340
|
+
type: Typification,
|
|
341
|
+
basics: Map<number, BasicBinding>,
|
|
342
|
+
cstByAlias: Map<string, { id: number }>
|
|
343
|
+
): boolean {
|
|
344
|
+
switch (type.typeID) {
|
|
345
|
+
case TypeID.integer:
|
|
346
|
+
return true;
|
|
347
|
+
case TypeID.basic: {
|
|
348
|
+
const cst = cstByAlias.get(type.baseID);
|
|
349
|
+
const binding = cst ? basics.get(cst.id) : undefined;
|
|
350
|
+
return Object.keys(binding ?? {}).length > 0;
|
|
351
|
+
}
|
|
352
|
+
case TypeID.tuple:
|
|
353
|
+
return type.factors.every(factor => canGenerateRandomValue(factor, basics, cstByAlias));
|
|
354
|
+
case TypeID.collection:
|
|
355
|
+
return canGenerateRandomValue(type.base, basics, cstByAlias);
|
|
356
|
+
case TypeID.anyTypification:
|
|
357
|
+
return false;
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
|
|
334
361
|
function countBaseElements(cst: ModelEvalFields, engine: RSEngine): number {
|
|
335
362
|
if (!isBasicConcept(cst.cst_type)) {
|
|
336
363
|
return 0;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
|
|
3
|
+
import { type EvalStackFrame,formatEvalCallStack } from './error';
|
|
4
|
+
|
|
5
|
+
describe('formatEvalCallStack', () => {
|
|
6
|
+
it('returns empty string for missing or empty stack', () => {
|
|
7
|
+
expect(formatEvalCallStack(undefined)).toBe('');
|
|
8
|
+
expect(formatEvalCallStack([])).toBe('');
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
it('formats callee aliases from outermost call to innermost fault', () => {
|
|
12
|
+
const stack: EvalStackFrame[] = [
|
|
13
|
+
{ alias: 'F12', from: 10, to: 12 },
|
|
14
|
+
{ alias: 'F5', from: 8, to: 14 }
|
|
15
|
+
];
|
|
16
|
+
expect(formatEvalCallStack(stack)).toBe('F5 → F12');
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it('formats a single nested call', () => {
|
|
20
|
+
const stack: EvalStackFrame[] = [{ alias: 'F9', from: 7, to: 8 }];
|
|
21
|
+
expect(formatEvalCallStack(stack)).toBe('F9');
|
|
22
|
+
});
|
|
23
|
+
});
|
package/src/rslang/error.ts
CHANGED
|
@@ -16,15 +16,57 @@ export interface RSErrorInfo {
|
|
|
16
16
|
params?: readonly string[];
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
+
/**
|
|
20
|
+
* One frame of an evaluation call chain.
|
|
21
|
+
*
|
|
22
|
+
* Spans are relative to the formal definition of {@link alias}.
|
|
23
|
+
* Frames are ordered innermost-first: fault locus, then each caller outward.
|
|
24
|
+
* The root expression under evaluation is not a frame — its highlight is
|
|
25
|
+
* {@link RSErrorDescription.from}/{@link RSErrorDescription.to}; {@link RSErrorDescription.stack}
|
|
26
|
+
* is absent when the fault is in that root expression.
|
|
27
|
+
*/
|
|
28
|
+
export interface EvalStackFrame {
|
|
29
|
+
/** Constituent whose formal definition contains this span. */
|
|
30
|
+
alias: string;
|
|
31
|
+
/** Half-open span `[from, to)` in that definition. */
|
|
32
|
+
from: number;
|
|
33
|
+
to: number;
|
|
34
|
+
}
|
|
35
|
+
|
|
19
36
|
/** Represents RSLang expression error description. */
|
|
20
37
|
export interface RSErrorDescription extends RSErrorInfo {
|
|
21
38
|
from: number;
|
|
22
39
|
to: number;
|
|
40
|
+
/**
|
|
41
|
+
* Evaluation call chain when the fault is inside a called `F#`/`P#` body.
|
|
42
|
+
* Absent for parse/semantic errors and for evaluation errors in the root expression.
|
|
43
|
+
*/
|
|
44
|
+
stack?: readonly EvalStackFrame[];
|
|
23
45
|
}
|
|
24
46
|
|
|
25
47
|
/** Error reporter function type. */
|
|
26
48
|
export type ErrorReporter = (error: RSErrorDescription) => void;
|
|
27
49
|
|
|
50
|
+
/**
|
|
51
|
+
* Formats an evaluation call chain for display (`F5 → F12`).
|
|
52
|
+
*
|
|
53
|
+
* Uses callee aliases from outermost call to innermost fault container.
|
|
54
|
+
* Returns an empty string when there is no nested call to show.
|
|
55
|
+
*/
|
|
56
|
+
export function formatEvalCallStack(stack: readonly EvalStackFrame[] | undefined): string {
|
|
57
|
+
if (!stack || stack.length === 0) {
|
|
58
|
+
return '';
|
|
59
|
+
}
|
|
60
|
+
const aliases: string[] = [];
|
|
61
|
+
for (let index = stack.length - 1; index >= 0; index--) {
|
|
62
|
+
const frame = stack[index];
|
|
63
|
+
if (frame) {
|
|
64
|
+
aliases.push(frame.alias);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return aliases.join(' → ');
|
|
68
|
+
}
|
|
69
|
+
|
|
28
70
|
/** Represents RSLang expression error types. */
|
|
29
71
|
export const RSErrorCode = {
|
|
30
72
|
unknownSyntax: 0x8400, // 33792
|
|
@@ -308,11 +308,66 @@ describe('Calculator', () => {
|
|
|
308
308
|
expect(errors[0]).toMatchObject({
|
|
309
309
|
code: RSErrorCode.iterateInfinity,
|
|
310
310
|
from: callSite!.from,
|
|
311
|
-
to: callSite!.to
|
|
311
|
+
to: callSite!.to,
|
|
312
|
+
stack: [{ alias: 'F9', from: zOffset, to: zOffset + 1 }]
|
|
312
313
|
});
|
|
314
|
+
expect(errors[0]?.stack).toHaveLength(1);
|
|
313
315
|
expect(readErrorAnnotation(callSite!)).toMatchObject({ code: RSErrorCode.iterateInfinity });
|
|
314
316
|
expect(readErrorAnnotation(innerErrorNode!)).toBeNull();
|
|
315
317
|
});
|
|
318
|
+
|
|
319
|
+
it('keeps nested call surface span in the root expression and records the full stack', () => {
|
|
320
|
+
const innerExpr = '[a∈X1] debool(∅)';
|
|
321
|
+
const midExpr = '[a∈X1] F8[a]';
|
|
322
|
+
treeContext.set('F8', buildAST(innerExpr));
|
|
323
|
+
treeContext.set('F7', buildAST(midExpr));
|
|
324
|
+
const mainAst = buildAST('F7[X1]');
|
|
325
|
+
const outerCall = findFirstNode(mainAst, TokenID.NT_FUNC_CALL);
|
|
326
|
+
expect(outerCall).not.toBeNull();
|
|
327
|
+
|
|
328
|
+
const midAst = treeContext.get('F7')!;
|
|
329
|
+
const midCall = findFirstNode(midAst, TokenID.NT_FUNC_CALL);
|
|
330
|
+
expect(midCall).not.toBeNull();
|
|
331
|
+
|
|
332
|
+
const deboolArgFrom = innerExpr.indexOf('∅');
|
|
333
|
+
calculator.run(mainAst, error => errors.push(error), true);
|
|
334
|
+
|
|
335
|
+
expect(errors).toHaveLength(1);
|
|
336
|
+
expect(errors[0]).toMatchObject({
|
|
337
|
+
code: RSErrorCode.calcInvalidDebool,
|
|
338
|
+
from: outerCall!.from,
|
|
339
|
+
to: outerCall!.to,
|
|
340
|
+
stack: [
|
|
341
|
+
{ alias: 'F8', from: deboolArgFrom, to: deboolArgFrom + 1 },
|
|
342
|
+
{ alias: 'F7', from: midCall!.from, to: midCall!.to }
|
|
343
|
+
]
|
|
344
|
+
});
|
|
345
|
+
expect(errors[0]?.stack).toHaveLength(2);
|
|
346
|
+
expect(readErrorAnnotation(outerCall!)).toMatchObject({ code: RSErrorCode.calcInvalidDebool });
|
|
347
|
+
});
|
|
348
|
+
|
|
349
|
+
it('distinguishes which call site failed when the same function is used twice', () => {
|
|
350
|
+
treeContext.set('F8', buildAST('[a∈ℬ(X1)] debool(a)'));
|
|
351
|
+
const mainAst = buildAST('F8[{1}] ∪ F8[X1]');
|
|
352
|
+
const callSites: AstNode[] = [];
|
|
353
|
+
visitAstDFS(mainAst, node => {
|
|
354
|
+
if (node.typeID === TokenID.NT_FUNC_CALL) {
|
|
355
|
+
callSites.push(node);
|
|
356
|
+
}
|
|
357
|
+
});
|
|
358
|
+
expect(callSites).toHaveLength(2);
|
|
359
|
+
|
|
360
|
+
calculator.run(mainAst, error => errors.push(error));
|
|
361
|
+
|
|
362
|
+
expect(errors).toHaveLength(1);
|
|
363
|
+
expect(errors[0]).toMatchObject({
|
|
364
|
+
code: RSErrorCode.calcInvalidDebool,
|
|
365
|
+
from: callSites[1].from,
|
|
366
|
+
to: callSites[1].to,
|
|
367
|
+
stack: [{ alias: 'F8' }]
|
|
368
|
+
});
|
|
369
|
+
expect(errors[0]?.stack).toHaveLength(1);
|
|
370
|
+
});
|
|
316
371
|
});
|
|
317
372
|
|
|
318
373
|
describe('evaluation cache', () => {
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import { type AstNode, getNodeIndices, getNodeText } from '../../parsing';
|
|
6
6
|
import { annotateError } from '../ast-annotations';
|
|
7
|
-
import { type ErrorReporter, RSErrorCode } from '../error';
|
|
7
|
+
import { type ErrorReporter, type EvalStackFrame, RSErrorCode } from '../error';
|
|
8
8
|
import { labelRSLangNode } from '../labels';
|
|
9
9
|
import { TokenID } from '../parser/token';
|
|
10
10
|
|
|
@@ -95,16 +95,59 @@ export class Evaluator {
|
|
|
95
95
|
this.iterationCounter = 0;
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
98
|
+
/**
|
|
99
|
+
* Surface highlight target in the root expression under evaluation.
|
|
100
|
+
* Nested call sites live in callee ASTs — only the outermost call is in the root.
|
|
101
|
+
*/
|
|
102
|
+
private surfaceErrorNode(fault: AstNode): AstNode {
|
|
103
|
+
return this.callSiteStack[0] ?? fault;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Builds innermost-first frames for called `F#`/`P#` bodies only.
|
|
108
|
+
* The root expression is represented by the surface `from`/`to`, not a stack frame.
|
|
109
|
+
* Returns `undefined` when the fault is in the root expression (no function call).
|
|
110
|
+
*/
|
|
111
|
+
private buildEvalStack(fault: AstNode): readonly EvalStackFrame[] | undefined {
|
|
112
|
+
if (this.callSiteStack.length === 0) {
|
|
113
|
+
return undefined;
|
|
114
|
+
}
|
|
115
|
+
const frames: EvalStackFrame[] = [];
|
|
116
|
+
const innermostCall = this.callSiteStack[this.callSiteStack.length - 1];
|
|
117
|
+
if (!innermostCall) {
|
|
118
|
+
return undefined;
|
|
119
|
+
}
|
|
120
|
+
frames.push({
|
|
121
|
+
alias: getNodeText(innermostCall.children[0]),
|
|
122
|
+
from: fault.from,
|
|
123
|
+
to: fault.to
|
|
124
|
+
});
|
|
125
|
+
// Call sites at index ≥ 1 live in a callee body; index 0 is the root call site.
|
|
126
|
+
for (let index = this.callSiteStack.length - 1; index >= 1; index--) {
|
|
127
|
+
const callSite = this.callSiteStack[index];
|
|
128
|
+
const outerCall = this.callSiteStack[index - 1];
|
|
129
|
+
if (!callSite || !outerCall) {
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
frames.push({
|
|
133
|
+
alias: getNodeText(outerCall.children[0]),
|
|
134
|
+
from: callSite.from,
|
|
135
|
+
to: callSite.to
|
|
136
|
+
});
|
|
101
137
|
}
|
|
102
|
-
return
|
|
138
|
+
return frames;
|
|
103
139
|
}
|
|
104
140
|
|
|
105
141
|
private onError(code: RSErrorCode, node: AstNode, params?: string[]): null {
|
|
106
|
-
const target = this.
|
|
107
|
-
|
|
142
|
+
const target = this.surfaceErrorNode(node);
|
|
143
|
+
const stack = this.buildEvalStack(node);
|
|
144
|
+
this.reporter?.({
|
|
145
|
+
code,
|
|
146
|
+
from: target.from,
|
|
147
|
+
to: target.to,
|
|
148
|
+
...(params !== undefined ? { params } : {}),
|
|
149
|
+
...(stack !== undefined ? { stack } : {})
|
|
150
|
+
});
|
|
108
151
|
if (this.annotateErrors) {
|
|
109
152
|
annotateError(target, code, params);
|
|
110
153
|
}
|
package/src/rslang/index.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { readErrorAnnotation, readTypeAnnotation } from './ast-annotations';
|
|
2
|
-
export { RSErrorCode, type RSErrorDescription } from './error';
|
|
2
|
+
export { type EvalStackFrame, formatEvalCallStack,RSErrorCode, type RSErrorDescription } from './error';
|
|
3
3
|
export { type CalculatorEvaluateOptions, type CalculatorResult, RSCalculator } from './eval/calculator';
|
|
4
4
|
export { makeValuePath, type Value, type ValuePath } from './eval/value';
|
|
5
5
|
export { printValue } from './eval/value-api';
|