@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.
Files changed (73) hide show
  1. package/dist/{analyzer-CzFaWR7w.d.ts → analyzer-B35QsI3L.d.ts} +2 -2
  2. package/dist/{ast-annotations-x4PJ_Lhc.d.ts → ast-annotations-DclU1Ser.d.ts} +2 -2
  3. package/dist/{calculator-uPaTV3hc.d.ts → calculator-B-1p712X.d.ts} +2 -2
  4. package/dist/{diagnostics-DKyMf6q-.d.ts → diagnostics-D4_B7rt2.d.ts} +3 -3
  5. package/dist/{diagnostics-D1Cp21nP.js → diagnostics-D_4TpAH4.js} +4 -5
  6. package/dist/{diagnostics-D1Cp21nP.js.map → diagnostics-D_4TpAH4.js.map} +1 -1
  7. package/dist/{error-B0EkIx4K.d.ts → error-S1JghCNN.d.ts} +30 -2
  8. package/dist/{index-CnuO4w8e.d.ts → index-D-w-bgei.d.ts} +4 -4
  9. package/dist/{index-DCO4mxiO.d.ts → index-DzvllU3P.d.ts} +4 -4
  10. package/dist/index.d.ts +6 -6
  11. package/dist/index.js +4 -4
  12. package/dist/library/diagnostics.d.ts +1 -1
  13. package/dist/library/diagnostics.js +1 -1
  14. package/dist/library/index.d.ts +2 -2
  15. package/dist/library/index.js +1 -1
  16. package/dist/library/oss-api.d.ts +1 -1
  17. package/dist/library/oss-api.js +2 -4
  18. package/dist/library/oss-api.js.map +1 -1
  19. package/dist/library/oss.js +1 -1
  20. package/dist/library/rsengine.d.ts +3 -3
  21. package/dist/library/rsengine.js +4 -3
  22. package/dist/library/rsengine.js.map +1 -1
  23. package/dist/library/rsform-api/index.d.ts +1 -1
  24. package/dist/library/rsform-api/index.js +1 -1
  25. package/dist/library/rsform.d.ts +1 -1
  26. package/dist/library/rsmodel-api.d.ts +3 -3
  27. package/dist/library/rsmodel-api.js +20 -4
  28. package/dist/library/rsmodel-api.js.map +1 -1
  29. package/dist/library/rsmodel.d.ts +1 -1
  30. package/dist/library/structure-planner.d.ts +2 -2
  31. package/dist/library/structure-planner.js +1 -1
  32. package/dist/parsing/lezer-tree.js.map +1 -1
  33. package/dist/rslang/api.js +9 -6
  34. package/dist/rslang/api.js.map +1 -1
  35. package/dist/rslang/ast-annotations.d.ts +1 -1
  36. package/dist/rslang/error.d.ts +2 -2
  37. package/dist/rslang/error.js +16 -1
  38. package/dist/rslang/error.js.map +1 -1
  39. package/dist/rslang/eval/calculator.d.ts +1 -1
  40. package/dist/rslang/eval/calculator.js +1 -1
  41. package/dist/rslang/eval/evaluation-cache.js +1 -3
  42. package/dist/rslang/eval/evaluation-cache.js.map +1 -1
  43. package/dist/rslang/eval/evaluator.d.ts +12 -2
  44. package/dist/rslang/eval/evaluator.js +42 -8
  45. package/dist/rslang/eval/evaluator.js.map +1 -1
  46. package/dist/rslang/eval/value-api.js +1 -1
  47. package/dist/rslang/eval/value.js +1 -1
  48. package/dist/rslang/index.d.ts +6 -6
  49. package/dist/rslang/index.js +3 -3
  50. package/dist/rslang/parser/normalize.js.map +1 -1
  51. package/dist/rslang/parser/parser.terms.js.map +1 -1
  52. package/dist/rslang/parser/syntax-errors/index.d.ts +1 -1
  53. package/dist/rslang/semantic/analyzer.d.ts +1 -1
  54. package/dist/rslang/semantic/arguments-extractor.js +6 -4
  55. package/dist/rslang/semantic/arguments-extractor.js.map +1 -1
  56. package/dist/rslang/semantic/type-auditor.d.ts +1 -1
  57. package/dist/rslang/semantic/type-auditor.js +20 -16
  58. package/dist/rslang/semantic/type-auditor.js.map +1 -1
  59. package/dist/rslang/semantic/typification-api.js +10 -9
  60. package/dist/rslang/semantic/typification-api.js.map +1 -1
  61. package/dist/rslang/semantic/typification-parser.js +4 -1
  62. package/dist/rslang/semantic/typification-parser.js.map +1 -1
  63. package/dist/rslang/semantic/value-auditor.d.ts +1 -1
  64. package/dist/{value-COprb2Je.js → value-BDISzQqI.js} +3 -2
  65. package/dist/{value-COprb2Je.js.map → value-BDISzQqI.js.map} +1 -1
  66. package/package.json +23 -22
  67. package/src/index.ts +1 -1
  68. package/src/library/rsmodel-api.ts +27 -0
  69. package/src/rslang/error.test.ts +23 -0
  70. package/src/rslang/error.ts +42 -0
  71. package/src/rslang/eval/evaluator.test.ts +56 -1
  72. package/src/rslang/eval/evaluator.ts +50 -7
  73. package/src/rslang/index.ts +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"rsmodel-api.js","names":[],"sources":["../../src/library/rsmodel-api.ts"],"sourcesContent":["import { type ExpressionType, TypeID, type Typification, type Value } from '../rslang';\nimport { compare, set, tuple, TUPLE_ID, VALUE_TRUE, type ValuePath } from '../rslang/eval/value';\nimport { extractValue, isTupleValue, makeDefaultValue, setNestedValue } from '../rslang/eval/value-api';\nimport { type EchelonCollection } from '../rslang/semantic/typification';\n\nimport { modelStatusCstDiagnostic } from './diagnostics';\nimport { type RSEngine } from './rsengine';\nimport { CstType, type RSForm } from './rsform';\nimport { calculateSchemaStats, isBaseSet, isBasicConcept, type ModelEvalFields } from './rsform-api';\nimport { type BasicBinding, EvalStatus, type RSModelStats } from './rsmodel';\n\nconst RANDOM_INTEGER_MIN = -100;\nconst RANDOM_INTEGER_MAX = 100;\nconst DEFAULT_RANDOM_SET_ELEMENTS_COUNT = 5;\n\n/** Evaluate if parsed data is a basic binding data. */\nexport function validateBasicBindingData(data: unknown): data is Record<string, string> {\n if (!data || typeof data !== 'object' || Array.isArray(data)) {\n return false;\n }\n return Object.entries(data).every(([key, value]) => typeof value === 'string' && Number.isInteger(Number(key)));\n}\n\n/** Convert parsed data to a basic binding. */\nexport function toBasicBinding(data: Record<string | number, string>): BasicBinding {\n const result: BasicBinding = {};\n for (const [k, v] of Object.entries(data)) {\n result[Number(k)] = v;\n }\n return result;\n}\n\n/** Evaluate if parsed data is a {@link Value} data. */\nexport function validateValueData(data: unknown): data is Value {\n if (typeof data === 'number') {\n return Number.isFinite(data);\n }\n if (!Array.isArray(data)) {\n return false;\n }\n return data.every(item => validateValueData(item));\n}\n\nexport function generateRandomValue(\n type: Typification,\n basics: Map<number, BasicBinding>,\n cstByAlias: Map<string, { id: number }>,\n setElementsCount: number = DEFAULT_RANDOM_SET_ELEMENTS_COUNT\n): Value | null {\n switch (type.typeID) {\n case TypeID.integer:\n return Math.floor(Math.random() * (RANDOM_INTEGER_MAX - RANDOM_INTEGER_MIN + 1)) + RANDOM_INTEGER_MIN;\n case TypeID.basic: {\n const cst = cstByAlias.get(type.baseID);\n const binding = cst ? basics.get(cst.id) : undefined;\n const ids = Object.keys(binding ?? {}).map(Number);\n if (ids.length === 0) {\n return null;\n }\n return ids[Math.floor(Math.random() * ids.length)];\n }\n case TypeID.tuple: {\n const factors: Value[] = [];\n for (const factor of type.factors) {\n const sample = generateRandomValue(factor, basics, cstByAlias, setElementsCount);\n if (sample === null) {\n return null;\n }\n factors.push(sample);\n }\n return tuple(factors);\n }\n case TypeID.collection: {\n const result: Value[] = [];\n const randomElementsCount = Math.floor(Math.random() * (setElementsCount + 1));\n for (let i = 0; i < randomElementsCount; i++) {\n const sample = generateRandomValue(type.base, basics, cstByAlias, setElementsCount);\n if (sample === null) {\n return null;\n }\n result.push(sample);\n }\n // Sets must be unique; sampling with replacement can produce duplicates.\n return set(result);\n }\n case TypeID.anyTypification:\n return null;\n }\n}\n\n/** Calculate statistics for {@link RSModel}. */\nexport function calculateModelStats(schema: RSForm, engine: RSEngine, _engineGeneration?: number): RSModelStats {\n const items = schema.items;\n const statusByID = new Map<number, EvalStatus>();\n for (const cst of items) {\n statusByID.set(cst.id, engine.getCstStatus(cst.id));\n }\n return {\n ...calculateSchemaStats(schema),\n base_elements: items.reduce((sum, cst) => sum + countBaseElements(cst, engine), 0),\n count_missing_base: items.reduce(\n (sum, cst) => sum + (statusByID.get(cst.id) === EvalStatus.EMPTY && isBasicConcept(cst.cst_type) ? 1 : 0),\n 0\n ),\n count_false_axioms: items.reduce(\n (sum, cst) => sum + (statusByID.get(cst.id) === EvalStatus.AXIOM_FALSE ? 1 : 0),\n 0\n ),\n count_invalid_data: items.reduce(\n (sum, cst) => sum + (statusByID.get(cst.id) === EvalStatus.INVALID_DATA ? 1 : 0),\n 0\n ),\n count_invalid_calculations: items.reduce(\n (sum, cst) =>\n sum +\n (statusByID.get(cst.id) === EvalStatus.EVAL_FAIL || statusByID.get(cst.id) === EvalStatus.NOT_PROCESSED\n ? 1\n : 0),\n 0\n ),\n count_empty_terms: items.reduce(\n (sum, cst) => sum + (statusByID.get(cst.id) === EvalStatus.EMPTY && cst.cst_type === CstType.TERM ? 1 : 0),\n 0\n )\n };\n}\n\n/** Checks whether evaluation status contributes to model status issues. */\nexport function isModelIssue(engine: RSEngine, cst: ModelEvalFields): boolean {\n return modelStatusCstDiagnostic(engine.getCstStatus(cst.id), cst.cst_type) !== null;\n}\n\n/** Filters items whose evaluation status contributes to model issues. */\nexport function getEvalIssueItems(items: readonly ModelEvalFields[], engine: RSEngine): ModelEvalFields[] {\n return items.filter(cst => isModelIssue(engine, cst));\n}\n\n/** Evaluate if {@link CstType} is interpretable. */\nexport function isInterpretable(type: CstType): boolean {\n switch (type) {\n case CstType.BASE:\n case CstType.CONSTANT:\n case CstType.STRUCTURED:\n case CstType.AXIOM:\n case CstType.TERM:\n case CstType.STATEMENT:\n return true;\n\n case CstType.NOMINAL:\n case CstType.FUNCTION:\n case CstType.PREDICATE:\n return false;\n }\n}\n\n/** Evaluate if {@link CstType} is inferrable. */\nexport function isInferrable(type: CstType): boolean {\n switch (type) {\n case CstType.AXIOM:\n case CstType.STATEMENT:\n case CstType.TERM:\n return true;\n\n case CstType.NOMINAL:\n case CstType.BASE:\n case CstType.CONSTANT:\n case CstType.STRUCTURED:\n case CstType.FUNCTION:\n case CstType.PREDICATE:\n return false;\n }\n}\n\n/** Infers status of a given {@link Value} and {@link CstType}. */\nexport function inferEvalStatus(\n value: Value | null,\n cstType: CstType,\n wasCalculated: boolean = true,\n isInvalid: boolean = false\n): EvalStatus {\n if (isBaseSet(cstType) || cstType === CstType.STRUCTURED) {\n if (isInvalid) {\n return EvalStatus.INVALID_DATA;\n }\n if (value === null || (Array.isArray(value) && value.length === 0)) {\n return EvalStatus.EMPTY;\n }\n return EvalStatus.HAS_DATA;\n }\n if (!isInferrable(cstType)) {\n return EvalStatus.NO_EVAL;\n }\n if (!wasCalculated) {\n return EvalStatus.NOT_PROCESSED;\n }\n if (value === null) {\n return EvalStatus.EVAL_FAIL;\n }\n if (cstType === CstType.AXIOM && value !== VALUE_TRUE) {\n return EvalStatus.AXIOM_FALSE;\n }\n if (Array.isArray(value) && value.length === 0) {\n return EvalStatus.EMPTY;\n }\n return EvalStatus.HAS_DATA;\n}\n\n/** Tries to fix value removing invalid base elements not present in the target value.\n * returns null if no fixing is possible.\n * returns true if fixing was successful.\n * returns false if fixing was not needed.\n */\nexport function tryFixValue(\n value: Value,\n type: ExpressionType,\n targetAlias: string,\n targetValue: Value[]\n): boolean | null {\n switch (type.typeID) {\n case TypeID.integer:\n return false;\n case TypeID.basic:\n if (type.baseID !== targetAlias) {\n return false;\n }\n if (typeof value !== 'number') {\n return null;\n }\n if (!targetValue.includes(value)) {\n return null;\n }\n return false;\n case TypeID.tuple: {\n if (!isTupleValue(value)) {\n return null;\n }\n let wasChanged = false;\n for (let i = 0; i < type.factors.length; i++) {\n const componentChanged = tryFixValue(value[i + 1], type.factors[i], targetAlias, targetValue);\n if (componentChanged === null) {\n return null;\n }\n if (componentChanged) {\n wasChanged = true;\n }\n }\n return wasChanged;\n }\n case TypeID.collection:\n if (!Array.isArray(value) || (value.length > 1 && value[0] === TUPLE_ID)) {\n return null;\n }\n let wasChanged = false;\n const removeElements: Value[] = [];\n for (const item of value) {\n const elementChanged = tryFixValue(item, type.base, targetAlias, targetValue);\n if (elementChanged === null || elementChanged === true) {\n wasChanged = true;\n if (elementChanged === null) {\n removeElements.push(item);\n }\n }\n }\n for (const item of removeElements) {\n const index = value.indexOf(item);\n if (index !== -1) {\n value.splice(index, 1);\n }\n }\n if (wasChanged) {\n value.sort((a, b) => compare(a, b));\n let i = 1;\n while (i < value.length) {\n if (compare(value[i], value[i - 1]) === 0) {\n value.splice(i, 1);\n } else {\n i++;\n }\n }\n }\n return wasChanged;\n\n case TypeID.logic:\n case TypeID.anyTypification:\n case TypeID.predicate:\n case TypeID.function:\n return null;\n }\n}\n\nexport function updateValueElement(value: Value | null, path: ValuePath, newValue: number): Value | null {\n return setNestedValue(value, path, newValue);\n}\n\nexport function deleteValueElement(\n value: Value | null,\n path: ValuePath,\n type: Typification,\n target: number\n): Value | null {\n if (value === null) {\n return null;\n }\n if (path.length === 0 && type.typeID !== TypeID.collection) {\n return null;\n }\n\n const arrayValue = extractValue(value, path);\n if (!Array.isArray(arrayValue)) {\n return null;\n }\n const updatedArray = [...arrayValue.slice(0, target), ...arrayValue.slice(target + 1)];\n return setNestedValue(value, path, updatedArray);\n}\n\nexport function addValueElement(\n value: Value | null,\n path: ValuePath,\n type: Typification,\n currentType: Typification\n): Value | null {\n if (path.length === 0 && type.typeID !== TypeID.collection) {\n return makeDefaultValue(type);\n }\n\n const newElem = makeDefaultValue((currentType as EchelonCollection).base);\n const arrayValue = (extractValue(value!, path) as Value[] | null) ?? [];\n const updatedArray = [newElem, ...arrayValue];\n return setNestedValue(value, path, updatedArray);\n}\n\n// ========= Internal functions ==========\n\nfunction countBaseElements(cst: ModelEvalFields, engine: RSEngine): number {\n if (!isBasicConcept(cst.cst_type)) {\n return 0;\n }\n const value = engine.getCstValue(cst.id);\n if (value === null) {\n return 0;\n }\n if (!Array.isArray(value) || value[0] === TUPLE_ID) {\n return 1;\n }\n return value.length;\n}\n"],"mappings":";;;;;;;AAWA,MAAM,qBAAqB;AAE3B,MAAM,oCAAoC;;AAG1C,SAAgB,yBAAyB,MAA+C;CACtF,IAAI,CAAC,QAAQ,OAAO,SAAS,YAAY,MAAM,QAAQ,IAAI,GACzD,OAAO;CAET,OAAO,OAAO,QAAQ,IAAI,CAAC,CAAC,OAAO,CAAC,KAAK,WAAW,OAAO,UAAU,YAAY,OAAO,UAAU,OAAO,GAAG,CAAC,CAAC;AAChH;;AAGA,SAAgB,eAAe,MAAqD;CAClF,MAAM,SAAuB,CAAC;CAC9B,KAAK,MAAM,CAAC,GAAG,MAAM,OAAO,QAAQ,IAAI,GACtC,OAAO,OAAO,CAAC,KAAK;CAEtB,OAAO;AACT;;AAGA,SAAgB,kBAAkB,MAA8B;CAC9D,IAAI,OAAO,SAAS,UAClB,OAAO,OAAO,SAAS,IAAI;CAE7B,IAAI,CAAC,MAAM,QAAQ,IAAI,GACrB,OAAO;CAET,OAAO,KAAK,OAAM,SAAQ,kBAAkB,IAAI,CAAC;AACnD;AAEA,SAAgB,oBACd,MACA,QACA,YACA,mBAA2B,mCACb;CACd,QAAQ,KAAK,QAAb;EACE,KAAK,OAAO,SACV,OAAO,KAAK,MAAM,KAAK,OAAO,IAAK,GAA4C,IAAI;EACrF,KAAK,OAAO,OAAO;GACjB,MAAM,MAAM,WAAW,IAAI,KAAK,MAAM;GACtC,MAAM,UAAU,MAAM,OAAO,IAAI,IAAI,EAAE,IAAI;GAC3C,MAAM,MAAM,OAAO,KAAK,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,MAAM;GACjD,IAAI,IAAI,WAAW,GACjB,OAAO;GAET,OAAO,IAAI,KAAK,MAAM,KAAK,OAAO,IAAI,IAAI,MAAM;EAClD;EACA,KAAK,OAAO,OAAO;GACjB,MAAM,UAAmB,CAAC;GAC1B,KAAK,MAAM,UAAU,KAAK,SAAS;IACjC,MAAM,SAAS,oBAAoB,QAAQ,QAAQ,YAAY,gBAAgB;IAC/E,IAAI,WAAW,MACb,OAAO;IAET,QAAQ,KAAK,MAAM;GACrB;GACA,OAAO,MAAM,OAAO;EACtB;EACA,KAAK,OAAO,YAAY;GACtB,MAAM,SAAkB,CAAC;GACzB,MAAM,sBAAsB,KAAK,MAAM,KAAK,OAAO,KAAK,mBAAmB,EAAE;GAC7E,KAAK,IAAI,IAAI,GAAG,IAAI,qBAAqB,KAAK;IAC5C,MAAM,SAAS,oBAAoB,KAAK,MAAM,QAAQ,YAAY,gBAAgB;IAClF,IAAI,WAAW,MACb,OAAO;IAET,OAAO,KAAK,MAAM;GACpB;GAEA,OAAO,IAAI,MAAM;EACnB;EACA,KAAK,OAAO,iBACV,OAAO;CACX;AACF;;AAGA,SAAgB,oBAAoB,QAAgB,QAAkB,mBAA0C;CAC9G,MAAM,QAAQ,OAAO;CACrB,MAAM,6BAAa,IAAI,IAAwB;CAC/C,KAAK,MAAM,OAAO,OAChB,WAAW,IAAI,IAAI,IAAI,OAAO,aAAa,IAAI,EAAE,CAAC;CAEpD,OAAO;EACL,GAAG,qBAAqB,MAAM;EAC9B,eAAe,MAAM,QAAQ,KAAK,QAAQ,MAAM,kBAAkB,KAAK,MAAM,GAAG,CAAC;EACjF,oBAAoB,MAAM,QACvB,KAAK,QAAQ,OAAO,WAAW,IAAI,IAAI,EAAE,MAAM,WAAW,SAAS,eAAe,IAAI,QAAQ,IAAI,IAAI,IACvG,CACF;EACA,oBAAoB,MAAM,QACvB,KAAK,QAAQ,OAAO,WAAW,IAAI,IAAI,EAAE,MAAM,WAAW,cAAc,IAAI,IAC7E,CACF;EACA,oBAAoB,MAAM,QACvB,KAAK,QAAQ,OAAO,WAAW,IAAI,IAAI,EAAE,MAAM,WAAW,eAAe,IAAI,IAC9E,CACF;EACA,4BAA4B,MAAM,QAC/B,KAAK,QACJ,OACC,WAAW,IAAI,IAAI,EAAE,MAAM,WAAW,aAAa,WAAW,IAAI,IAAI,EAAE,MAAM,WAAW,gBACtF,IACA,IACN,CACF;EACA,mBAAmB,MAAM,QACtB,KAAK,QAAQ,OAAO,WAAW,IAAI,IAAI,EAAE,MAAM,WAAW,SAAS,IAAI,aAAa,QAAQ,OAAO,IAAI,IACxG,CACF;CACF;AACF;;AAGA,SAAgB,aAAa,QAAkB,KAA+B;CAC5E,OAAO,yBAAyB,OAAO,aAAa,IAAI,EAAE,GAAG,IAAI,QAAQ,MAAM;AACjF;;AAGA,SAAgB,kBAAkB,OAAmC,QAAqC;CACxG,OAAO,MAAM,QAAO,QAAO,aAAa,QAAQ,GAAG,CAAC;AACtD;;AAGA,SAAgB,gBAAgB,MAAwB;CACtD,QAAQ,MAAR;EACE,KAAK,QAAQ;EACb,KAAK,QAAQ;EACb,KAAK,QAAQ;EACb,KAAK,QAAQ;EACb,KAAK,QAAQ;EACb,KAAK,QAAQ,WACX,OAAO;EAET,KAAK,QAAQ;EACb,KAAK,QAAQ;EACb,KAAK,QAAQ,WACX,OAAO;CACX;AACF;;AAGA,SAAgB,aAAa,MAAwB;CACnD,QAAQ,MAAR;EACE,KAAK,QAAQ;EACb,KAAK,QAAQ;EACb,KAAK,QAAQ,MACX,OAAO;EAET,KAAK,QAAQ;EACb,KAAK,QAAQ;EACb,KAAK,QAAQ;EACb,KAAK,QAAQ;EACb,KAAK,QAAQ;EACb,KAAK,QAAQ,WACX,OAAO;CACX;AACF;;AAGA,SAAgB,gBACd,OACA,SACA,gBAAyB,MACzB,YAAqB,OACT;CACZ,IAAI,UAAU,OAAO,KAAK,YAAY,QAAQ,YAAY;EACxD,IAAI,WACF,OAAO,WAAW;EAEpB,IAAI,UAAU,QAAS,MAAM,QAAQ,KAAK,KAAK,MAAM,WAAW,GAC9D,OAAO,WAAW;EAEpB,OAAO,WAAW;CACpB;CACA,IAAI,CAAC,aAAa,OAAO,GACvB,OAAO,WAAW;CAEpB,IAAI,CAAC,eACH,OAAO,WAAW;CAEpB,IAAI,UAAU,MACZ,OAAO,WAAW;CAEpB,IAAI,YAAY,QAAQ,SAAS,UAAA,GAC/B,OAAO,WAAW;CAEpB,IAAI,MAAM,QAAQ,KAAK,KAAK,MAAM,WAAW,GAC3C,OAAO,WAAW;CAEpB,OAAO,WAAW;AACpB;;;;;;AAOA,SAAgB,YACd,OACA,MACA,aACA,aACgB;CAChB,QAAQ,KAAK,QAAb;EACE,KAAK,OAAO,SACV,OAAO;EACT,KAAK,OAAO;GACV,IAAI,KAAK,WAAW,aAClB,OAAO;GAET,IAAI,OAAO,UAAU,UACnB,OAAO;GAET,IAAI,CAAC,YAAY,SAAS,KAAK,GAC7B,OAAO;GAET,OAAO;EACT,KAAK,OAAO,OAAO;GACjB,IAAI,CAAC,aAAa,KAAK,GACrB,OAAO;GAET,IAAI,aAAa;GACjB,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,QAAQ,KAAK;IAC5C,MAAM,mBAAmB,YAAY,MAAM,IAAI,IAAI,KAAK,QAAQ,IAAI,aAAa,WAAW;IAC5F,IAAI,qBAAqB,MACvB,OAAO;IAET,IAAI,kBACF,aAAa;GAEjB;GACA,OAAO;EACT;EACA,KAAK,OAAO;GACV,IAAI,CAAC,MAAM,QAAQ,KAAK,KAAM,MAAM,SAAS,KAAK,MAAM,OAAA,MACtD,OAAO;GAET,IAAI,aAAa;GACjB,MAAM,iBAA0B,CAAC;GACjC,KAAK,MAAM,QAAQ,OAAO;IACxB,MAAM,iBAAiB,YAAY,MAAM,KAAK,MAAM,aAAa,WAAW;IAC5E,IAAI,mBAAmB,QAAQ,mBAAmB,MAAM;KACtD,aAAa;KACb,IAAI,mBAAmB,MACrB,eAAe,KAAK,IAAI;IAE5B;GACF;GACA,KAAK,MAAM,QAAQ,gBAAgB;IACjC,MAAM,QAAQ,MAAM,QAAQ,IAAI;IAChC,IAAI,UAAU,IACZ,MAAM,OAAO,OAAO,CAAC;GAEzB;GACA,IAAI,YAAY;IACd,MAAM,MAAM,GAAG,MAAM,QAAQ,GAAG,CAAC,CAAC;IAClC,IAAI,IAAI;IACR,OAAO,IAAI,MAAM,QACf,IAAI,QAAQ,MAAM,IAAI,MAAM,IAAI,EAAE,MAAM,GACtC,MAAM,OAAO,GAAG,CAAC;SAEjB;GAGN;GACA,OAAO;EAET,KAAK,OAAO;EACZ,KAAK,OAAO;EACZ,KAAK,OAAO;EACZ,KAAK,OAAO,UACV,OAAO;CACX;AACF;AAEA,SAAgB,mBAAmB,OAAqB,MAAiB,UAAgC;CACvG,OAAO,eAAe,OAAO,MAAM,QAAQ;AAC7C;AAEA,SAAgB,mBACd,OACA,MACA,MACA,QACc;CACd,IAAI,UAAU,MACZ,OAAO;CAET,IAAI,KAAK,WAAW,KAAK,KAAK,WAAW,OAAO,YAC9C,OAAO;CAGT,MAAM,aAAa,aAAa,OAAO,IAAI;CAC3C,IAAI,CAAC,MAAM,QAAQ,UAAU,GAC3B,OAAO;CAGT,OAAO,eAAe,OAAO,MAAM,CADb,GAAG,WAAW,MAAM,GAAG,MAAM,GAAG,GAAG,WAAW,MAAM,SAAS,CAAC,CACjD,CAAY;AACjD;AAEA,SAAgB,gBACd,OACA,MACA,MACA,aACc;CACd,IAAI,KAAK,WAAW,KAAK,KAAK,WAAW,OAAO,YAC9C,OAAO,iBAAiB,IAAI;CAM9B,OAAO,eAAe,OAAO,MAAM,CAHnB,iBAAkB,YAAkC,IAE9C,GAAS,GADX,aAAa,OAAQ,IAAI,KAAwB,CAAC,CAEnC,CAAY;AACjD;AAIA,SAAS,kBAAkB,KAAsB,QAA0B;CACzE,IAAI,CAAC,eAAe,IAAI,QAAQ,GAC9B,OAAO;CAET,MAAM,QAAQ,OAAO,YAAY,IAAI,EAAE;CACvC,IAAI,UAAU,MACZ,OAAO;CAET,IAAI,CAAC,MAAM,QAAQ,KAAK,KAAK,MAAM,OAAA,MACjC,OAAO;CAET,OAAO,MAAM;AACf"}
1
+ {"version":3,"file":"rsmodel-api.js","names":[],"sources":["../../src/library/rsmodel-api.ts"],"sourcesContent":["import { type ExpressionType, TypeID, type Typification, type Value } from '../rslang';\nimport { compare, set, tuple, TUPLE_ID, VALUE_TRUE, type ValuePath } from '../rslang/eval/value';\nimport { extractValue, isTupleValue, makeDefaultValue, setNestedValue } from '../rslang/eval/value-api';\nimport { type EchelonCollection } from '../rslang/semantic/typification';\n\nimport { modelStatusCstDiagnostic } from './diagnostics';\nimport { type RSEngine } from './rsengine';\nimport { CstType, type RSForm } from './rsform';\nimport { calculateSchemaStats, isBaseSet, isBasicConcept, type ModelEvalFields } from './rsform-api';\nimport { type BasicBinding, EvalStatus, type RSModelStats } from './rsmodel';\n\nconst RANDOM_INTEGER_MIN = -100;\nconst RANDOM_INTEGER_MAX = 100;\nconst DEFAULT_RANDOM_SET_ELEMENTS_COUNT = 5;\n\n/** Evaluate if parsed data is a basic binding data. */\nexport function validateBasicBindingData(data: unknown): data is Record<string, string> {\n if (!data || typeof data !== 'object' || Array.isArray(data)) {\n return false;\n }\n return Object.entries(data).every(([key, value]) => typeof value === 'string' && Number.isInteger(Number(key)));\n}\n\n/** Convert parsed data to a basic binding. */\nexport function toBasicBinding(data: Record<string | number, string>): BasicBinding {\n const result: BasicBinding = {};\n for (const [k, v] of Object.entries(data)) {\n result[Number(k)] = v;\n }\n return result;\n}\n\n/** Evaluate if parsed data is a {@link Value} data. */\nexport function validateValueData(data: unknown): data is Value {\n if (typeof data === 'number') {\n return Number.isFinite(data);\n }\n if (!Array.isArray(data)) {\n return false;\n }\n return data.every(item => validateValueData(item));\n}\n\nexport function generateRandomValue(\n type: Typification,\n basics: Map<number, BasicBinding>,\n cstByAlias: Map<string, { id: number }>,\n setElementsCount: number = DEFAULT_RANDOM_SET_ELEMENTS_COUNT\n): Value | null {\n switch (type.typeID) {\n case TypeID.integer:\n return Math.floor(Math.random() * (RANDOM_INTEGER_MAX - RANDOM_INTEGER_MIN + 1)) + RANDOM_INTEGER_MIN;\n case TypeID.basic: {\n const cst = cstByAlias.get(type.baseID);\n const binding = cst ? basics.get(cst.id) : undefined;\n const ids = Object.keys(binding ?? {}).map(Number);\n if (ids.length === 0) {\n return null;\n }\n return ids[Math.floor(Math.random() * ids.length)];\n }\n case TypeID.tuple: {\n const factors: Value[] = [];\n for (const factor of type.factors) {\n const sample = generateRandomValue(factor, basics, cstByAlias, setElementsCount);\n if (sample === null) {\n return null;\n }\n factors.push(sample);\n }\n return tuple(factors);\n }\n case TypeID.collection: {\n // Empty set is a valid sample only when the element domain itself is generatable.\n // When the count happens to be 0 we would otherwise skip sampling and miss empty basics.\n if (!canGenerateRandomValue(type.base, basics, cstByAlias)) {\n return null;\n }\n const result: Value[] = [];\n const randomElementsCount = Math.floor(Math.random() * (setElementsCount + 1));\n for (let i = 0; i < randomElementsCount; i++) {\n const sample = generateRandomValue(type.base, basics, cstByAlias, setElementsCount);\n if (sample === null) {\n return null;\n }\n result.push(sample);\n }\n // Sets must be unique; sampling with replacement can produce duplicates.\n return set(result);\n }\n case TypeID.anyTypification:\n return null;\n }\n}\n\n/** Calculate statistics for {@link RSModel}. */\nexport function calculateModelStats(schema: RSForm, engine: RSEngine, _engineGeneration?: number): RSModelStats {\n const items = schema.items;\n const statusByID = new Map<number, EvalStatus>();\n for (const cst of items) {\n statusByID.set(cst.id, engine.getCstStatus(cst.id));\n }\n return {\n ...calculateSchemaStats(schema),\n base_elements: items.reduce((sum, cst) => sum + countBaseElements(cst, engine), 0),\n count_missing_base: items.reduce(\n (sum, cst) => sum + (statusByID.get(cst.id) === EvalStatus.EMPTY && isBasicConcept(cst.cst_type) ? 1 : 0),\n 0\n ),\n count_false_axioms: items.reduce(\n (sum, cst) => sum + (statusByID.get(cst.id) === EvalStatus.AXIOM_FALSE ? 1 : 0),\n 0\n ),\n count_invalid_data: items.reduce(\n (sum, cst) => sum + (statusByID.get(cst.id) === EvalStatus.INVALID_DATA ? 1 : 0),\n 0\n ),\n count_invalid_calculations: items.reduce(\n (sum, cst) =>\n sum +\n (statusByID.get(cst.id) === EvalStatus.EVAL_FAIL || statusByID.get(cst.id) === EvalStatus.NOT_PROCESSED\n ? 1\n : 0),\n 0\n ),\n count_empty_terms: items.reduce(\n (sum, cst) => sum + (statusByID.get(cst.id) === EvalStatus.EMPTY && cst.cst_type === CstType.TERM ? 1 : 0),\n 0\n )\n };\n}\n\n/** Checks whether evaluation status contributes to model status issues. */\nexport function isModelIssue(engine: RSEngine, cst: ModelEvalFields): boolean {\n return modelStatusCstDiagnostic(engine.getCstStatus(cst.id), cst.cst_type) !== null;\n}\n\n/** Filters items whose evaluation status contributes to model issues. */\nexport function getEvalIssueItems(items: readonly ModelEvalFields[], engine: RSEngine): ModelEvalFields[] {\n return items.filter(cst => isModelIssue(engine, cst));\n}\n\n/** Evaluate if {@link CstType} is interpretable. */\nexport function isInterpretable(type: CstType): boolean {\n switch (type) {\n case CstType.BASE:\n case CstType.CONSTANT:\n case CstType.STRUCTURED:\n case CstType.AXIOM:\n case CstType.TERM:\n case CstType.STATEMENT:\n return true;\n\n case CstType.NOMINAL:\n case CstType.FUNCTION:\n case CstType.PREDICATE:\n return false;\n }\n}\n\n/** Evaluate if {@link CstType} is inferrable. */\nexport function isInferrable(type: CstType): boolean {\n switch (type) {\n case CstType.AXIOM:\n case CstType.STATEMENT:\n case CstType.TERM:\n return true;\n\n case CstType.NOMINAL:\n case CstType.BASE:\n case CstType.CONSTANT:\n case CstType.STRUCTURED:\n case CstType.FUNCTION:\n case CstType.PREDICATE:\n return false;\n }\n}\n\n/** Infers status of a given {@link Value} and {@link CstType}. */\nexport function inferEvalStatus(\n value: Value | null,\n cstType: CstType,\n wasCalculated: boolean = true,\n isInvalid: boolean = false\n): EvalStatus {\n if (isBaseSet(cstType) || cstType === CstType.STRUCTURED) {\n if (isInvalid) {\n return EvalStatus.INVALID_DATA;\n }\n if (value === null || (Array.isArray(value) && value.length === 0)) {\n return EvalStatus.EMPTY;\n }\n return EvalStatus.HAS_DATA;\n }\n if (!isInferrable(cstType)) {\n return EvalStatus.NO_EVAL;\n }\n if (!wasCalculated) {\n return EvalStatus.NOT_PROCESSED;\n }\n if (value === null) {\n return EvalStatus.EVAL_FAIL;\n }\n if (cstType === CstType.AXIOM && value !== VALUE_TRUE) {\n return EvalStatus.AXIOM_FALSE;\n }\n if (Array.isArray(value) && value.length === 0) {\n return EvalStatus.EMPTY;\n }\n return EvalStatus.HAS_DATA;\n}\n\n/** Tries to fix value removing invalid base elements not present in the target value.\n * returns null if no fixing is possible.\n * returns true if fixing was successful.\n * returns false if fixing was not needed.\n */\nexport function tryFixValue(\n value: Value,\n type: ExpressionType,\n targetAlias: string,\n targetValue: Value[]\n): boolean | null {\n switch (type.typeID) {\n case TypeID.integer:\n return false;\n case TypeID.basic:\n if (type.baseID !== targetAlias) {\n return false;\n }\n if (typeof value !== 'number') {\n return null;\n }\n if (!targetValue.includes(value)) {\n return null;\n }\n return false;\n case TypeID.tuple: {\n if (!isTupleValue(value)) {\n return null;\n }\n let wasChanged = false;\n for (let i = 0; i < type.factors.length; i++) {\n const componentChanged = tryFixValue(value[i + 1], type.factors[i], targetAlias, targetValue);\n if (componentChanged === null) {\n return null;\n }\n if (componentChanged) {\n wasChanged = true;\n }\n }\n return wasChanged;\n }\n case TypeID.collection:\n if (!Array.isArray(value) || (value.length > 1 && value[0] === TUPLE_ID)) {\n return null;\n }\n let wasChanged = false;\n const removeElements: Value[] = [];\n for (const item of value) {\n const elementChanged = tryFixValue(item, type.base, targetAlias, targetValue);\n if (elementChanged === null || elementChanged === true) {\n wasChanged = true;\n if (elementChanged === null) {\n removeElements.push(item);\n }\n }\n }\n for (const item of removeElements) {\n const index = value.indexOf(item);\n if (index !== -1) {\n value.splice(index, 1);\n }\n }\n if (wasChanged) {\n value.sort((a, b) => compare(a, b));\n let i = 1;\n while (i < value.length) {\n if (compare(value[i], value[i - 1]) === 0) {\n value.splice(i, 1);\n } else {\n i++;\n }\n }\n }\n return wasChanged;\n\n case TypeID.logic:\n case TypeID.anyTypification:\n case TypeID.predicate:\n case TypeID.function:\n return null;\n }\n}\n\nexport function updateValueElement(value: Value | null, path: ValuePath, newValue: number): Value | null {\n return setNestedValue(value, path, newValue);\n}\n\nexport function deleteValueElement(\n value: Value | null,\n path: ValuePath,\n type: Typification,\n target: number\n): Value | null {\n if (value === null) {\n return null;\n }\n if (path.length === 0 && type.typeID !== TypeID.collection) {\n return null;\n }\n\n const arrayValue = extractValue(value, path);\n if (!Array.isArray(arrayValue)) {\n return null;\n }\n const updatedArray = [...arrayValue.slice(0, target), ...arrayValue.slice(target + 1)];\n return setNestedValue(value, path, updatedArray);\n}\n\nexport function addValueElement(\n value: Value | null,\n path: ValuePath,\n type: Typification,\n currentType: Typification\n): Value | null {\n if (path.length === 0 && type.typeID !== TypeID.collection) {\n return makeDefaultValue(type);\n }\n\n const newElem = makeDefaultValue((currentType as EchelonCollection).base);\n const arrayValue = (extractValue(value!, path) as Value[] | null) ?? [];\n const updatedArray = [newElem, ...arrayValue];\n return setNestedValue(value, path, updatedArray);\n}\n\n// ========= Internal functions ==========\n\nfunction canGenerateRandomValue(\n type: Typification,\n basics: Map<number, BasicBinding>,\n cstByAlias: Map<string, { id: number }>\n): boolean {\n switch (type.typeID) {\n case TypeID.integer:\n return true;\n case TypeID.basic: {\n const cst = cstByAlias.get(type.baseID);\n const binding = cst ? basics.get(cst.id) : undefined;\n return Object.keys(binding ?? {}).length > 0;\n }\n case TypeID.tuple:\n return type.factors.every(factor => canGenerateRandomValue(factor, basics, cstByAlias));\n case TypeID.collection:\n return canGenerateRandomValue(type.base, basics, cstByAlias);\n case TypeID.anyTypification:\n return false;\n }\n}\n\nfunction countBaseElements(cst: ModelEvalFields, engine: RSEngine): number {\n if (!isBasicConcept(cst.cst_type)) {\n return 0;\n }\n const value = engine.getCstValue(cst.id);\n if (value === null) {\n return 0;\n }\n if (!Array.isArray(value) || value[0] === TUPLE_ID) {\n return 1;\n }\n return value.length;\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import { d as DEFAULT_VALUE_TEXT, f as EvalStatus, h as TYPE_BASIC, l as BasicBinding, m as RSModelStats, p as RSModel, u as BasicsContext } from "../diagnostics-DKyMf6q-.js";
1
+ import { d as DEFAULT_VALUE_TEXT, f as EvalStatus, h as TYPE_BASIC, l as BasicBinding, m as RSModelStats, p as RSModel, u as BasicsContext } from "../diagnostics-D4_B7rt2.js";
2
2
  export { BasicBinding, BasicsContext, DEFAULT_VALUE_TEXT, EvalStatus, RSModel, RSModelStats, TYPE_BASIC };
@@ -1,6 +1,6 @@
1
1
  import { b as Typification, y as TypePath } from "../typification-hWUoWCba.js";
2
- import "../index-CnuO4w8e.js";
3
- import { S as RSForm, v as Constituenta } from "../diagnostics-DKyMf6q-.js";
2
+ import "../index-D-w-bgei.js";
3
+ import { S as RSForm, v as Constituenta } from "../diagnostics-D4_B7rt2.js";
4
4
  //#region src/library/structure-planner.d.ts
5
5
  /** Represents a node in the structure planner. */
6
6
  interface SPNode {
@@ -3,7 +3,7 @@ import { labelType } from "../rslang/labels.js";
3
3
  import { splitTemplateDefinition } from "../rslang/api.js";
4
4
  import { CstType } from "./rsform.js";
5
5
  import "../rslang/index.js";
6
- import { y as findCstByStructure } from "../diagnostics-D1Cp21nP.js";
6
+ import { y as findCstByStructure } from "../diagnostics-D_4TpAH4.js";
7
7
  //#region src/library/structure-planner.ts
8
8
  /** Structure planner for {@link Constituenta}. */
9
9
  var StructurePlanner = class {
@@ -1 +1 @@
1
- {"version":3,"file":"lezer-tree.js","names":[],"sources":["../../src/parsing/lezer-tree.ts"],"sourcesContent":["import { type NodeType, type Tree, type TreeCursor } from '@lezer/common';\nexport { type TreeCursor } from '@lezer/common';\n\n/** Represents syntax tree node data. */\nexport interface CMSyntaxNode {\n type: NodeType;\n from: number;\n to: number;\n}\n\n/** Prints tree to compact string. */\nexport function printTree(tree: Tree): string {\n const state = {\n output: '',\n prefixes: [] as string[]\n };\n traverseTree(tree, {\n onEnter: node => {\n state.output += '[';\n state.output += node.type.name;\n },\n onLeave: () => {\n state.output += ']';\n }\n });\n return state.output;\n}\n\n// ======== Internals ========\n\ninterface CursorNode extends CMSyntaxNode {\n isLeaf: boolean;\n}\n\nfunction cursorNode({ type, from, to }: TreeCursor, isLeaf = false): CursorNode {\n return { type, from, to, isLeaf };\n}\n\ninterface TreeTraversalOptions {\n beforeEnter?: (cursor: TreeCursor) => void;\n onEnter: (node: CursorNode) => false | void;\n onLeave?: (node: CursorNode) => false | void;\n}\n\n/** Implements depth-first traversal. */\nfunction traverseTree(tree: Tree, { beforeEnter, onEnter, onLeave }: TreeTraversalOptions) {\n const cursor = tree.cursor();\n for (;;) {\n let node = cursorNode(cursor);\n let leave = false;\n const enter = !node.type.isAnonymous;\n if (enter && beforeEnter) beforeEnter(cursor);\n node.isLeaf = !cursor.firstChild();\n if (enter) {\n leave = true;\n if (onEnter(node) === false) return;\n }\n if (!node.isLeaf) continue;\n for (;;) {\n node = cursorNode(cursor, node.isLeaf);\n if (leave && onLeave) if (onLeave(node) === false) return;\n leave = cursor.type.isAnonymous;\n node.isLeaf = false;\n if (cursor.nextSibling()) break;\n if (!cursor.parent()) return;\n leave = true;\n }\n }\n}\n"],"mappings":";;AAWA,SAAgB,UAAU,MAAoB;CAC5C,MAAM,QAAQ;EACZ,QAAQ;EACR,UAAU,CAAC;CACb;CACA,aAAa,MAAM;EACjB,UAAS,SAAQ;GACf,MAAM,UAAU;GAChB,MAAM,UAAU,KAAK,KAAK;EAC5B;EACA,eAAe;GACb,MAAM,UAAU;EAClB;CACF,CAAC;CACD,OAAO,MAAM;AACf;AAQA,SAAS,WAAW,EAAE,MAAM,MAAM,MAAkB,SAAS,OAAmB;CAC9E,OAAO;EAAE;EAAM;EAAM;EAAI;CAAO;AAClC;;AASA,SAAS,aAAa,MAAY,EAAE,aAAa,SAAS,WAAiC;CACzF,MAAM,SAAS,KAAK,OAAO;CAC3B,SAAS;EACP,IAAI,OAAO,WAAW,MAAM;EAC5B,IAAI,QAAQ;EACZ,MAAM,QAAQ,CAAC,KAAK,KAAK;EACzB,IAAI,SAAS,aAAa,YAAY,MAAM;EAC5C,KAAK,SAAS,CAAC,OAAO,WAAW;EACjC,IAAI,OAAO;GACT,QAAQ;GACR,IAAI,QAAQ,IAAI,MAAM,OAAO;EAC/B;EACA,IAAI,CAAC,KAAK,QAAQ;EAClB,SAAS;GACP,OAAO,WAAW,QAAQ,KAAK,MAAM;GACrC,IAAI,SAAS;QAAa,QAAQ,IAAI,MAAM,OAAO;GAAA;GACnD,QAAQ,OAAO,KAAK;GACpB,KAAK,SAAS;GACd,IAAI,OAAO,YAAY,GAAG;GAC1B,IAAI,CAAC,OAAO,OAAO,GAAG;GACtB,QAAQ;EACV;CACF;AACF"}
1
+ {"version":3,"file":"lezer-tree.js","names":[],"sources":["../../src/parsing/lezer-tree.ts"],"sourcesContent":["import { type NodeType, type Tree, type TreeCursor } from '@lezer/common';\nexport { type TreeCursor } from '@lezer/common';\n\n/** Represents syntax tree node data. */\nexport interface CMSyntaxNode {\n type: NodeType;\n from: number;\n to: number;\n}\n\n/** Prints tree to compact string. */\nexport function printTree(tree: Tree): string {\n const state = {\n output: '',\n prefixes: [] as string[]\n };\n traverseTree(tree, {\n onEnter: node => {\n state.output += '[';\n state.output += node.type.name;\n },\n onLeave: () => {\n state.output += ']';\n }\n });\n return state.output;\n}\n\n// ======== Internals ========\n\ninterface CursorNode extends CMSyntaxNode {\n isLeaf: boolean;\n}\n\nfunction cursorNode({ type, from, to }: TreeCursor, isLeaf = false): CursorNode {\n return { type, from, to, isLeaf };\n}\n\ninterface TreeTraversalOptions {\n beforeEnter?: (cursor: TreeCursor) => void;\n onEnter: (node: CursorNode) => false | void;\n onLeave?: (node: CursorNode) => false | void;\n}\n\n/** Implements depth-first traversal. */\nfunction traverseTree(tree: Tree, { beforeEnter, onEnter, onLeave }: TreeTraversalOptions) {\n const cursor = tree.cursor();\n for (;;) {\n let node = cursorNode(cursor);\n let leave = false;\n const enter = !node.type.isAnonymous;\n if (enter && beforeEnter) beforeEnter(cursor);\n node.isLeaf = !cursor.firstChild();\n if (enter) {\n leave = true;\n if (onEnter(node) === false) return;\n }\n if (!node.isLeaf) continue;\n for (;;) {\n node = cursorNode(cursor, node.isLeaf);\n if (leave && onLeave) if (onLeave(node) === false) return;\n leave = cursor.type.isAnonymous;\n node.isLeaf = false;\n if (cursor.nextSibling()) break;\n if (!cursor.parent()) return;\n leave = true;\n }\n }\n}\n"],"mappings":";;AAWA,SAAgB,UAAU,MAAoB;CAC5C,MAAM,QAAQ;EACZ,QAAQ;EACR,UAAU,CAAC;CACb;CACA,aAAa,MAAM;EACjB,UAAS,SAAQ;GACf,MAAM,UAAU;GAChB,MAAM,UAAU,KAAK,KAAK;EAC5B;EACA,eAAe;GACb,MAAM,UAAU;EAClB;CACF,CAAC;CACD,OAAO,MAAM;AACf;AAQA,SAAS,WAAW,EAAE,MAAM,MAAM,MAAkB,SAAS,OAAmB;CAC9E,OAAO;EAAE;EAAM;EAAM;EAAI;CAAO;AAClC;;AASA,SAAS,aAAa,MAAY,EAAE,aAAa,SAAS,WAAiC;CACzF,MAAM,SAAS,KAAK,OAAO;CAC3B,SAAS;EACP,IAAI,OAAO,WAAW,MAAM;EAC5B,IAAI,QAAQ;EACZ,MAAM,QAAQ,CAAC,KAAK,KAAK;EACzB,IAAI,SAAS,aAAa,YAAY,MAAM;EAC5C,KAAK,SAAS,CAAC,OAAO,WAAW;EACjC,IAAI,OAAO;GACT,QAAQ;GACR,IAAI,QAAQ,IAAI,MAAM,OAAO;EAC/B;EACA,IAAI,CAAC,KAAK,QAAQ;EAClB,SAAS;GACP,OAAO,WAAW,QAAQ,KAAK,MAAM;GACrC,IAAI,SAAS,SAAa;QAAA,QAAQ,IAAI,MAAM,OAAO;GAAA;GACnD,QAAQ,OAAO,KAAK;GACpB,KAAK,SAAS;GACd,IAAI,OAAO,YAAY,GAAG;GAC1B,IAAI,CAAC,OAAO,OAAO,GAAG;GACtB,QAAQ;EACV;CACF;AACF"}
@@ -26,7 +26,8 @@ function isGlobalAlias(value) {
26
26
  */
27
27
  function parseRSLangExpression(expression) {
28
28
  if (!expression.trim()) return null;
29
- const ast = buildTree(parser.parse(expression).cursor());
29
+ const tree = parser.parse(expression);
30
+ const ast = buildTree(tree.cursor());
30
31
  normalizeAST(ast, expression);
31
32
  return ast;
32
33
  }
@@ -65,11 +66,13 @@ function splitTemplateDefinition(target) {
65
66
  for (; start < target.length && target[start] !== "["; ++start);
66
67
  if (start < target.length) {
67
68
  for (let counter = 0, end = start + 1; end < target.length; ++end) if (target[end] === "[") ++counter;
68
- else if (target[end] === "]") if (counter !== 0) --counter;
69
- else return {
70
- head: target.substring(start + 1, end).trim(),
71
- body: target.substring(end + 1).trim()
72
- };
69
+ else if (target[end] === "]") {
70
+ if (counter !== 0) --counter;
71
+ else return {
72
+ head: target.substring(start + 1, end).trim(),
73
+ body: target.substring(end + 1).trim()
74
+ };
75
+ }
73
76
  }
74
77
  return {
75
78
  head: "",
@@ -1 +1 @@
1
- {"version":3,"file":"api.js","names":["rslangParser"],"sources":["../../src/rslang/api.ts"],"sourcesContent":["/**\n * Module: API for RSLanguage.\n */\nimport { type AstNode, buildTree } from '../parsing';\n\nimport { normalizeAST } from './parser/normalize';\nimport { parser as rslangParser } from './parser/parser';\nimport { ArgumentsExtractor, type ArgumentsType } from './semantic/arguments-extractor';\nexport { generateExpressionFromAst } from './parser/expression-generator';\n\n/** Represents alias mapping. */\nexport type AliasMapping = Record<string, string>;\n\n// cspell:disable\nconst LOCALS_REGEXP = /[_a-zα-ω][a-zα-ω]*\\d*/g;\nconst GLOBAL_ALIAS_SOURCE = '[XCSADFPTN]\\\\d+';\nconst GLOBALS_REGEXP = new RegExp(GLOBAL_ALIAS_SOURCE, 'g');\nconst GLOBAL_ALIAS_ANCHORED_REGEXP = new RegExp(`^${GLOBAL_ALIAS_SOURCE}$`);\nconst COMPLEX_SYMBOLS_REGEXP = /[∀∃×ℬ;|:]/g;\nconst TYPIFICATION_SET = /^ℬ+\\([ℬ\\(((X|C)\\d+|Z)\\)×]*\\)$/g;\n// cspell:enable\n\n/** Whether {@link value} is a single schema global alias (e.g. `X1`, `F42`). */\nexport function isGlobalAlias(value: string): boolean {\n return GLOBAL_ALIAS_ANCHORED_REGEXP.test(value);\n}\n\n/**\n * Parse a RSLang expression into a normalized AST.\n *\n * Returns `null` for blank input. Parses the original `expression` string so node\n * offsets match the source text (required for slice-based AST walks).\n */\nexport function parseRSLangExpression(expression: string): AstNode | null {\n if (!expression.trim()) {\n return null;\n }\n const tree = rslangParser.parse(expression);\n const ast = buildTree(tree.cursor());\n normalizeAST(ast, expression);\n return ast;\n}\n\n/** Extract arguments from AST. */\nexport function extractArguments(ast: AstNode): ArgumentsType[] {\n return new ArgumentsExtractor().run(ast);\n}\n\n/** Extracts global variable names from a given expression. */\nexport function extractGlobals(expression: string): Set<string> {\n return new Set(expression.match(GLOBALS_REGEXP) ?? []);\n}\n\n/** Check if expression is simple derivation. */\nexport function isSimpleExpression(text: string): boolean {\n return !text.match(COMPLEX_SYMBOLS_REGEXP);\n}\n\n/** Check if expression is set typification. */\nexport function isSetTypification(text: string): boolean {\n return !!text.match(TYPIFICATION_SET);\n}\n\n/**\n * Splits a string containing a template definition into its head and body parts.\n *\n * A template definition is expected to have the following format: `[head] body`.\n * If the input string does not contain the opening square bracket '[', the entire\n * string is treated as the body, and an empty string is assigned to the head.\n * If the opening bracket is present, the function attempts to find the matching\n * closing bracket ']' to determine the head and body parts.\n *\n * @example\n * const template = '[header] body content';\n * const result = splitTemplateDefinition(template);\n * // result: `{ head: 'header', body: 'body content' }`\n */\nexport function splitTemplateDefinition(target: string) {\n let start = 0;\n for (; start < target.length && target[start] !== '['; ++start);\n if (start < target.length) {\n for (let counter = 0, end = start + 1; end < target.length; ++end) {\n if (target[end] === '[') {\n ++counter;\n } else if (target[end] === ']') {\n if (counter !== 0) {\n --counter;\n } else {\n return {\n head: target.substring(start + 1, end).trim(),\n body: target.substring(end + 1).trim()\n };\n }\n }\n }\n }\n return {\n head: '',\n body: target\n };\n}\n\n/**\n * Substitutes values for template arguments in a given expression.\n *\n * This function takes an input mathematical expression and a list of argument values.\n * It replaces template argument placeholders in the expression with their corresponding values\n * from the provided arguments.\n */\nexport function substituteTemplateArgs(expression: string, mapping: AliasMapping): string {\n if (Object.keys(mapping).length === 0) {\n return expression;\n }\n let { head, body } = splitTemplateDefinition(expression);\n body = applyPattern(body, mapping, LOCALS_REGEXP);\n const argTexts = head.split(',').map(text => text.trim());\n head = argTexts\n .filter(arg => [...arg.matchAll(LOCALS_REGEXP)].every(local => local.every(match => !(match in mapping))))\n .join(', ');\n\n if (!head) {\n return body;\n } else {\n return `[${head}] ${body}`;\n }\n}\n\n/** Substitute local parameter aliases in an expression fragment. */\nexport function substituteLocalAliases(expression: string, mapping: AliasMapping): string {\n return applyPattern(expression, mapping, LOCALS_REGEXP);\n}\n\n/** Apply alias mapping. */\nexport function applyAliasMapping(target: string, mapping: AliasMapping): string {\n return applyPattern(target, mapping, GLOBALS_REGEXP);\n}\n\n/** Apply alias typification mapping. */\nexport function applyTypificationMapping(target: string, mapping: AliasMapping): string {\n const modified = applyAliasMapping(target, mapping);\n if (modified === target) {\n return target;\n }\n\n const deleteBrackets: number[] = [];\n const positions: number[] = [];\n const booleans: number[] = [];\n let boolCount: number = 0;\n let stackSize: number = 0;\n\n for (let i = 0; i < modified.length; i++) {\n const char = modified[i];\n if (char === 'ℬ') {\n boolCount++;\n continue;\n }\n if (char === '(') {\n stackSize++;\n positions.push(i);\n booleans.push(boolCount);\n }\n boolCount = 0;\n if (char === ')') {\n if (\n i < modified.length - 1 &&\n modified[i + 1] === ')' &&\n stackSize > 1 &&\n positions[stackSize - 2] + booleans[stackSize - 1] + 1 === positions[stackSize - 1]\n ) {\n deleteBrackets.push(i);\n deleteBrackets.push(positions[stackSize - 2]);\n }\n if (i === modified.length - 1 && stackSize === 1 && positions[0] === 0) {\n deleteBrackets.push(i);\n deleteBrackets.push(positions[0]);\n }\n stackSize--;\n positions.pop();\n booleans.pop();\n }\n }\n\n let result = '';\n for (let i = 0; i < modified.length; i++) {\n if (!deleteBrackets.includes(i)) {\n result += modified[i];\n }\n }\n\n return result;\n}\n\n// ====== Internals =========\n/** Text substitution guided by mapping and regular expression. */\nfunction applyPattern(text: string, mapping: AliasMapping, pattern: RegExp): string {\n if (text === '' || pattern === null) {\n return text;\n }\n let posInput = 0;\n let output = '';\n const patternMatches = text.matchAll(pattern);\n for (const segment of patternMatches) {\n const entity = segment[0];\n const start = segment.index ?? 0;\n if (entity in mapping) {\n output += text.substring(posInput, start);\n output += mapping[entity];\n posInput = start + segment[0].length;\n }\n }\n output += text.substring(posInput);\n return output;\n}\n"],"mappings":";;;;;;;;;;AAcA,MAAM,gBAAgB;AACtB,MAAM,sBAAsB;AAC5B,MAAM,iBAAiB,IAAI,OAAO,qBAAqB,GAAG;AAC1D,MAAM,+BAA+B,IAAI,OAAO,IAAI,oBAAoB,EAAE;AAC1E,MAAM,yBAAyB;AAC/B,MAAM,mBAAmB;;AAIzB,SAAgB,cAAc,OAAwB;CACpD,OAAO,6BAA6B,KAAK,KAAK;AAChD;;;;;;;AAQA,SAAgB,sBAAsB,YAAoC;CACxE,IAAI,CAAC,WAAW,KAAK,GACnB,OAAO;CAGT,MAAM,MAAM,UADCA,OAAa,MAAM,UACV,CAAA,CAAK,OAAO,CAAC;CACnC,aAAa,KAAK,UAAU;CAC5B,OAAO;AACT;;AAGA,SAAgB,iBAAiB,KAA+B;CAC9D,OAAO,IAAI,mBAAmB,CAAC,CAAC,IAAI,GAAG;AACzC;;AAGA,SAAgB,eAAe,YAAiC;CAC9D,OAAO,IAAI,IAAI,WAAW,MAAM,cAAc,KAAK,CAAC,CAAC;AACvD;;AAGA,SAAgB,mBAAmB,MAAuB;CACxD,OAAO,CAAC,KAAK,MAAM,sBAAsB;AAC3C;;AAGA,SAAgB,kBAAkB,MAAuB;CACvD,OAAO,CAAC,CAAC,KAAK,MAAM,gBAAgB;AACtC;;;;;;;;;;;;;;;AAgBA,SAAgB,wBAAwB,QAAgB;CACtD,IAAI,QAAQ;CACZ,OAAO,QAAQ,OAAO,UAAU,OAAO,WAAW,KAAK,EAAE;CACzD,IAAI,QAAQ,OAAO,QACjB;OAAK,IAAI,UAAU,GAAG,MAAM,QAAQ,GAAG,MAAM,OAAO,QAAQ,EAAE,KAC5D,IAAI,OAAO,SAAS,KAClB,EAAE;OACG,IAAI,OAAO,SAAS,KACzB,IAAI,YAAY,GACd,EAAE;OAEF,OAAO;GACL,MAAM,OAAO,UAAU,QAAQ,GAAG,GAAG,CAAC,CAAC,KAAK;GAC5C,MAAM,OAAO,UAAU,MAAM,CAAC,CAAC,CAAC,KAAK;EACvC;CAGN;CAEF,OAAO;EACL,MAAM;EACN,MAAM;CACR;AACF;;;;;;;;AASA,SAAgB,uBAAuB,YAAoB,SAA+B;CACxF,IAAI,OAAO,KAAK,OAAO,CAAC,CAAC,WAAW,GAClC,OAAO;CAET,IAAI,EAAE,MAAM,SAAS,wBAAwB,UAAU;CACvD,OAAO,aAAa,MAAM,SAAS,aAAa;CAEhD,OADiB,KAAK,MAAM,GAAG,CAAC,CAAC,KAAI,SAAQ,KAAK,KAAK,CAChD,CAAA,CACJ,QAAO,QAAO,CAAC,GAAG,IAAI,SAAS,aAAa,CAAC,CAAC,CAAC,OAAM,UAAS,MAAM,OAAM,UAAS,EAAE,SAAS,QAAQ,CAAC,CAAC,CAAC,CACzG,KAAK,IAAI;CAEZ,IAAI,CAAC,MACH,OAAO;MAEP,OAAO,IAAI,KAAK,IAAI;AAExB;;AAGA,SAAgB,uBAAuB,YAAoB,SAA+B;CACxF,OAAO,aAAa,YAAY,SAAS,aAAa;AACxD;;AAGA,SAAgB,kBAAkB,QAAgB,SAA+B;CAC/E,OAAO,aAAa,QAAQ,SAAS,cAAc;AACrD;;AAGA,SAAgB,yBAAyB,QAAgB,SAA+B;CACtF,MAAM,WAAW,kBAAkB,QAAQ,OAAO;CAClD,IAAI,aAAa,QACf,OAAO;CAGT,MAAM,iBAA2B,CAAC;CAClC,MAAM,YAAsB,CAAC;CAC7B,MAAM,WAAqB,CAAC;CAC5B,IAAI,YAAoB;CACxB,IAAI,YAAoB;CAExB,KAAK,IAAI,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;EACxC,MAAM,OAAO,SAAS;EACtB,IAAI,SAAS,KAAK;GAChB;GACA;EACF;EACA,IAAI,SAAS,KAAK;GAChB;GACA,UAAU,KAAK,CAAC;GAChB,SAAS,KAAK,SAAS;EACzB;EACA,YAAY;EACZ,IAAI,SAAS,KAAK;GAChB,IACE,IAAI,SAAS,SAAS,KACtB,SAAS,IAAI,OAAO,OACpB,YAAY,KACZ,UAAU,YAAY,KAAK,SAAS,YAAY,KAAK,MAAM,UAAU,YAAY,IACjF;IACA,eAAe,KAAK,CAAC;IACrB,eAAe,KAAK,UAAU,YAAY,EAAE;GAC9C;GACA,IAAI,MAAM,SAAS,SAAS,KAAK,cAAc,KAAK,UAAU,OAAO,GAAG;IACtE,eAAe,KAAK,CAAC;IACrB,eAAe,KAAK,UAAU,EAAE;GAClC;GACA;GACA,UAAU,IAAI;GACd,SAAS,IAAI;EACf;CACF;CAEA,IAAI,SAAS;CACb,KAAK,IAAI,IAAI,GAAG,IAAI,SAAS,QAAQ,KACnC,IAAI,CAAC,eAAe,SAAS,CAAC,GAC5B,UAAU,SAAS;CAIvB,OAAO;AACT;;AAIA,SAAS,aAAa,MAAc,SAAuB,SAAyB;CAClF,IAAI,SAAS,MAAM,YAAY,MAC7B,OAAO;CAET,IAAI,WAAW;CACf,IAAI,SAAS;CACb,MAAM,iBAAiB,KAAK,SAAS,OAAO;CAC5C,KAAK,MAAM,WAAW,gBAAgB;EACpC,MAAM,SAAS,QAAQ;EACvB,MAAM,QAAQ,QAAQ,SAAS;EAC/B,IAAI,UAAU,SAAS;GACrB,UAAU,KAAK,UAAU,UAAU,KAAK;GACxC,UAAU,QAAQ;GAClB,WAAW,QAAQ,QAAQ,EAAE,CAAC;EAChC;CACF;CACA,UAAU,KAAK,UAAU,QAAQ;CACjC,OAAO;AACT"}
1
+ {"version":3,"file":"api.js","names":["rslangParser"],"sources":["../../src/rslang/api.ts"],"sourcesContent":["/**\n * Module: API for RSLanguage.\n */\nimport { type AstNode, buildTree } from '../parsing';\n\nimport { normalizeAST } from './parser/normalize';\nimport { parser as rslangParser } from './parser/parser';\nimport { ArgumentsExtractor, type ArgumentsType } from './semantic/arguments-extractor';\nexport { generateExpressionFromAst } from './parser/expression-generator';\n\n/** Represents alias mapping. */\nexport type AliasMapping = Record<string, string>;\n\n// cspell:disable\nconst LOCALS_REGEXP = /[_a-zα-ω][a-zα-ω]*\\d*/g;\nconst GLOBAL_ALIAS_SOURCE = '[XCSADFPTN]\\\\d+';\nconst GLOBALS_REGEXP = new RegExp(GLOBAL_ALIAS_SOURCE, 'g');\nconst GLOBAL_ALIAS_ANCHORED_REGEXP = new RegExp(`^${GLOBAL_ALIAS_SOURCE}$`);\nconst COMPLEX_SYMBOLS_REGEXP = /[∀∃×ℬ;|:]/g;\nconst TYPIFICATION_SET = /^ℬ+\\([ℬ\\(((X|C)\\d+|Z)\\)×]*\\)$/g;\n// cspell:enable\n\n/** Whether {@link value} is a single schema global alias (e.g. `X1`, `F42`). */\nexport function isGlobalAlias(value: string): boolean {\n return GLOBAL_ALIAS_ANCHORED_REGEXP.test(value);\n}\n\n/**\n * Parse a RSLang expression into a normalized AST.\n *\n * Returns `null` for blank input. Parses the original `expression` string so node\n * offsets match the source text (required for slice-based AST walks).\n */\nexport function parseRSLangExpression(expression: string): AstNode | null {\n if (!expression.trim()) {\n return null;\n }\n const tree = rslangParser.parse(expression);\n const ast = buildTree(tree.cursor());\n normalizeAST(ast, expression);\n return ast;\n}\n\n/** Extract arguments from AST. */\nexport function extractArguments(ast: AstNode): ArgumentsType[] {\n return new ArgumentsExtractor().run(ast);\n}\n\n/** Extracts global variable names from a given expression. */\nexport function extractGlobals(expression: string): Set<string> {\n return new Set(expression.match(GLOBALS_REGEXP) ?? []);\n}\n\n/** Check if expression is simple derivation. */\nexport function isSimpleExpression(text: string): boolean {\n return !text.match(COMPLEX_SYMBOLS_REGEXP);\n}\n\n/** Check if expression is set typification. */\nexport function isSetTypification(text: string): boolean {\n return !!text.match(TYPIFICATION_SET);\n}\n\n/**\n * Splits a string containing a template definition into its head and body parts.\n *\n * A template definition is expected to have the following format: `[head] body`.\n * If the input string does not contain the opening square bracket '[', the entire\n * string is treated as the body, and an empty string is assigned to the head.\n * If the opening bracket is present, the function attempts to find the matching\n * closing bracket ']' to determine the head and body parts.\n *\n * @example\n * const template = '[header] body content';\n * const result = splitTemplateDefinition(template);\n * // result: `{ head: 'header', body: 'body content' }`\n */\nexport function splitTemplateDefinition(target: string) {\n let start = 0;\n for (; start < target.length && target[start] !== '['; ++start);\n if (start < target.length) {\n for (let counter = 0, end = start + 1; end < target.length; ++end) {\n if (target[end] === '[') {\n ++counter;\n } else if (target[end] === ']') {\n if (counter !== 0) {\n --counter;\n } else {\n return {\n head: target.substring(start + 1, end).trim(),\n body: target.substring(end + 1).trim()\n };\n }\n }\n }\n }\n return {\n head: '',\n body: target\n };\n}\n\n/**\n * Substitutes values for template arguments in a given expression.\n *\n * This function takes an input mathematical expression and a list of argument values.\n * It replaces template argument placeholders in the expression with their corresponding values\n * from the provided arguments.\n */\nexport function substituteTemplateArgs(expression: string, mapping: AliasMapping): string {\n if (Object.keys(mapping).length === 0) {\n return expression;\n }\n let { head, body } = splitTemplateDefinition(expression);\n body = applyPattern(body, mapping, LOCALS_REGEXP);\n const argTexts = head.split(',').map(text => text.trim());\n head = argTexts\n .filter(arg => [...arg.matchAll(LOCALS_REGEXP)].every(local => local.every(match => !(match in mapping))))\n .join(', ');\n\n if (!head) {\n return body;\n } else {\n return `[${head}] ${body}`;\n }\n}\n\n/** Substitute local parameter aliases in an expression fragment. */\nexport function substituteLocalAliases(expression: string, mapping: AliasMapping): string {\n return applyPattern(expression, mapping, LOCALS_REGEXP);\n}\n\n/** Apply alias mapping. */\nexport function applyAliasMapping(target: string, mapping: AliasMapping): string {\n return applyPattern(target, mapping, GLOBALS_REGEXP);\n}\n\n/** Apply alias typification mapping. */\nexport function applyTypificationMapping(target: string, mapping: AliasMapping): string {\n const modified = applyAliasMapping(target, mapping);\n if (modified === target) {\n return target;\n }\n\n const deleteBrackets: number[] = [];\n const positions: number[] = [];\n const booleans: number[] = [];\n let boolCount: number = 0;\n let stackSize: number = 0;\n\n for (let i = 0; i < modified.length; i++) {\n const char = modified[i];\n if (char === 'ℬ') {\n boolCount++;\n continue;\n }\n if (char === '(') {\n stackSize++;\n positions.push(i);\n booleans.push(boolCount);\n }\n boolCount = 0;\n if (char === ')') {\n if (\n i < modified.length - 1 &&\n modified[i + 1] === ')' &&\n stackSize > 1 &&\n positions[stackSize - 2] + booleans[stackSize - 1] + 1 === positions[stackSize - 1]\n ) {\n deleteBrackets.push(i);\n deleteBrackets.push(positions[stackSize - 2]);\n }\n if (i === modified.length - 1 && stackSize === 1 && positions[0] === 0) {\n deleteBrackets.push(i);\n deleteBrackets.push(positions[0]);\n }\n stackSize--;\n positions.pop();\n booleans.pop();\n }\n }\n\n let result = '';\n for (let i = 0; i < modified.length; i++) {\n if (!deleteBrackets.includes(i)) {\n result += modified[i];\n }\n }\n\n return result;\n}\n\n// ====== Internals =========\n/** Text substitution guided by mapping and regular expression. */\nfunction applyPattern(text: string, mapping: AliasMapping, pattern: RegExp): string {\n if (text === '' || pattern === null) {\n return text;\n }\n let posInput = 0;\n let output = '';\n const patternMatches = text.matchAll(pattern);\n for (const segment of patternMatches) {\n const entity = segment[0];\n const start = segment.index ?? 0;\n if (entity in mapping) {\n output += text.substring(posInput, start);\n output += mapping[entity];\n posInput = start + segment[0].length;\n }\n }\n output += text.substring(posInput);\n return output;\n}\n"],"mappings":";;;;;;;;;;AAcA,MAAM,gBAAgB;AACtB,MAAM,sBAAsB;AAC5B,MAAM,iBAAiB,IAAI,OAAO,qBAAqB,GAAG;AAC1D,MAAM,+BAA+B,IAAI,OAAO,IAAI,oBAAoB,EAAE;AAC1E,MAAM,yBAAyB;AAC/B,MAAM,mBAAmB;;AAIzB,SAAgB,cAAc,OAAwB;CACpD,OAAO,6BAA6B,KAAK,KAAK;AAChD;;;;;;;AAQA,SAAgB,sBAAsB,YAAoC;CACxE,IAAI,CAAC,WAAW,KAAK,GACnB,OAAO;CAET,MAAM,OAAOA,OAAa,MAAM,UAAU;CAC1C,MAAM,MAAM,UAAU,KAAK,OAAO,CAAC;CACnC,aAAa,KAAK,UAAU;CAC5B,OAAO;AACT;;AAGA,SAAgB,iBAAiB,KAA+B;CAC9D,OAAO,IAAI,mBAAmB,CAAC,CAAC,IAAI,GAAG;AACzC;;AAGA,SAAgB,eAAe,YAAiC;CAC9D,OAAO,IAAI,IAAI,WAAW,MAAM,cAAc,KAAK,CAAC,CAAC;AACvD;;AAGA,SAAgB,mBAAmB,MAAuB;CACxD,OAAO,CAAC,KAAK,MAAM,sBAAsB;AAC3C;;AAGA,SAAgB,kBAAkB,MAAuB;CACvD,OAAO,CAAC,CAAC,KAAK,MAAM,gBAAgB;AACtC;;;;;;;;;;;;;;;AAgBA,SAAgB,wBAAwB,QAAgB;CACtD,IAAI,QAAQ;CACZ,OAAO,QAAQ,OAAO,UAAU,OAAO,WAAW,KAAK,EAAE;CACzD,IAAI,QAAQ,OAAO,QACjB;OAAK,IAAI,UAAU,GAAG,MAAM,QAAQ,GAAG,MAAM,OAAO,QAAQ,EAAE,KAC5D,IAAI,OAAO,SAAS,KAClB,EAAE;OACG,IAAI,OAAO,SAAS,KAAK;GAC9B,IAAI,YAAY,GACd,EAAE;QAEF,OAAO;IACL,MAAM,OAAO,UAAU,QAAQ,GAAG,GAAG,CAAC,CAAC,KAAK;IAC5C,MAAM,OAAO,UAAU,MAAM,CAAC,CAAC,CAAC,KAAK;GACvC;EAEJ;CACF;CAEF,OAAO;EACL,MAAM;EACN,MAAM;CACR;AACF;;;;;;;;AASA,SAAgB,uBAAuB,YAAoB,SAA+B;CACxF,IAAI,OAAO,KAAK,OAAO,CAAC,CAAC,WAAW,GAClC,OAAO;CAET,IAAI,EAAE,MAAM,SAAS,wBAAwB,UAAU;CACvD,OAAO,aAAa,MAAM,SAAS,aAAa;CAEhD,OADiB,KAAK,MAAM,GAAG,CAAC,CAAC,KAAI,SAAQ,KAAK,KAAK,CAChD,CAAA,CACJ,QAAO,QAAO,CAAC,GAAG,IAAI,SAAS,aAAa,CAAC,CAAC,CAAC,OAAM,UAAS,MAAM,OAAM,UAAS,EAAE,SAAS,QAAQ,CAAC,CAAC,CAAC,CACzG,KAAK,IAAI;CAEZ,IAAI,CAAC,MACH,OAAO;MAEP,OAAO,IAAI,KAAK,IAAI;AAExB;;AAGA,SAAgB,uBAAuB,YAAoB,SAA+B;CACxF,OAAO,aAAa,YAAY,SAAS,aAAa;AACxD;;AAGA,SAAgB,kBAAkB,QAAgB,SAA+B;CAC/E,OAAO,aAAa,QAAQ,SAAS,cAAc;AACrD;;AAGA,SAAgB,yBAAyB,QAAgB,SAA+B;CACtF,MAAM,WAAW,kBAAkB,QAAQ,OAAO;CAClD,IAAI,aAAa,QACf,OAAO;CAGT,MAAM,iBAA2B,CAAC;CAClC,MAAM,YAAsB,CAAC;CAC7B,MAAM,WAAqB,CAAC;CAC5B,IAAI,YAAoB;CACxB,IAAI,YAAoB;CAExB,KAAK,IAAI,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;EACxC,MAAM,OAAO,SAAS;EACtB,IAAI,SAAS,KAAK;GAChB;GACA;EACF;EACA,IAAI,SAAS,KAAK;GAChB;GACA,UAAU,KAAK,CAAC;GAChB,SAAS,KAAK,SAAS;EACzB;EACA,YAAY;EACZ,IAAI,SAAS,KAAK;GAChB,IACE,IAAI,SAAS,SAAS,KACtB,SAAS,IAAI,OAAO,OACpB,YAAY,KACZ,UAAU,YAAY,KAAK,SAAS,YAAY,KAAK,MAAM,UAAU,YAAY,IACjF;IACA,eAAe,KAAK,CAAC;IACrB,eAAe,KAAK,UAAU,YAAY,EAAE;GAC9C;GACA,IAAI,MAAM,SAAS,SAAS,KAAK,cAAc,KAAK,UAAU,OAAO,GAAG;IACtE,eAAe,KAAK,CAAC;IACrB,eAAe,KAAK,UAAU,EAAE;GAClC;GACA;GACA,UAAU,IAAI;GACd,SAAS,IAAI;EACf;CACF;CAEA,IAAI,SAAS;CACb,KAAK,IAAI,IAAI,GAAG,IAAI,SAAS,QAAQ,KACnC,IAAI,CAAC,eAAe,SAAS,CAAC,GAC5B,UAAU,SAAS;CAIvB,OAAO;AACT;;AAIA,SAAS,aAAa,MAAc,SAAuB,SAAyB;CAClF,IAAI,SAAS,MAAM,YAAY,MAC7B,OAAO;CAET,IAAI,WAAW;CACf,IAAI,SAAS;CACb,MAAM,iBAAiB,KAAK,SAAS,OAAO;CAC5C,KAAK,MAAM,WAAW,gBAAgB;EACpC,MAAM,SAAS,QAAQ;EACvB,MAAM,QAAQ,QAAQ,SAAS;EAC/B,IAAI,UAAU,SAAS;GACrB,UAAU,KAAK,UAAU,UAAU,KAAK;GACxC,UAAU,QAAQ;GAClB,WAAW,QAAQ,QAAQ,EAAE,CAAC;EAChC;CACF;CACA,UAAU,KAAK,UAAU,QAAQ;CACjC,OAAO;AACT"}
@@ -1,2 +1,2 @@
1
- import { i as readTypeAnnotation, n as annotateType, r as readErrorAnnotation, t as annotateError } from "../ast-annotations-x4PJ_Lhc.js";
1
+ import { i as readTypeAnnotation, n as annotateType, r as readErrorAnnotation, t as annotateError } from "../ast-annotations-DclU1Ser.js";
2
2
  export { annotateError, annotateType, readErrorAnnotation, readTypeAnnotation };
@@ -1,2 +1,2 @@
1
- import { a as RSErrorInfo, i as RSErrorDescription, n as RSErrorClass, o as getRSErrorPrefix, r as RSErrorCode, s as isCritical, t as ErrorReporter } from "../error-B0EkIx4K.js";
2
- export { ErrorReporter, RSErrorClass, RSErrorCode, RSErrorDescription, RSErrorInfo, getRSErrorPrefix, isCritical };
1
+ import { a as RSErrorDescription, c as getRSErrorPrefix, i as RSErrorCode, l as isCritical, n as EvalStackFrame, o as RSErrorInfo, r as RSErrorClass, s as formatEvalCallStack, t as ErrorReporter } from "../error-S1JghCNN.js";
2
+ export { ErrorReporter, EvalStackFrame, RSErrorClass, RSErrorCode, RSErrorDescription, RSErrorInfo, formatEvalCallStack, getRSErrorPrefix, isCritical };
@@ -8,6 +8,21 @@ const RSErrorClass = {
8
8
  EVALUATION: 3,
9
9
  UNKNOWN: 4
10
10
  };
11
+ /**
12
+ * Formats an evaluation call chain for display (`F5 → F12`).
13
+ *
14
+ * Uses callee aliases from outermost call to innermost fault container.
15
+ * Returns an empty string when there is no nested call to show.
16
+ */
17
+ function formatEvalCallStack(stack) {
18
+ if (!stack || stack.length === 0) return "";
19
+ const aliases = [];
20
+ for (let index = stack.length - 1; index >= 0; index--) {
21
+ const frame = stack[index];
22
+ if (frame) aliases.push(frame.alias);
23
+ }
24
+ return aliases.join(" → ");
25
+ }
11
26
  /** Represents RSLang expression error types. */
12
27
  const RSErrorCode = {
13
28
  unknownSyntax: 33792,
@@ -116,6 +131,6 @@ function isCritical(code) {
116
131
  return true;
117
132
  }
118
133
  //#endregion
119
- export { RSErrorClass, RSErrorCode, getRSErrorPrefix, isCritical };
134
+ export { RSErrorClass, RSErrorCode, formatEvalCallStack, getRSErrorPrefix, isCritical };
120
135
 
121
136
  //# sourceMappingURL=error.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"error.js","names":[],"sources":["../../src/rslang/error.ts"],"sourcesContent":["/** Module: Error types and functions. */\n\n/** Represents error class. */\nexport const RSErrorClass = {\n LEXER: 0,\n PARSER: 1,\n SEMANTIC: 2,\n EVALUATION: 3,\n UNKNOWN: 4\n} as const;\nexport type RSErrorClass = (typeof RSErrorClass)[keyof typeof RSErrorClass];\n\n/** Represents RSLang expression error information. */\nexport interface RSErrorInfo {\n code: RSErrorCode;\n params?: readonly string[];\n}\n\n/** Represents RSLang expression error description. */\nexport interface RSErrorDescription extends RSErrorInfo {\n from: number;\n to: number;\n}\n\n/** Error reporter function type. */\nexport type ErrorReporter = (error: RSErrorDescription) => void;\n\n/** Represents RSLang expression error types. */\nexport const RSErrorCode = {\n unknownSyntax: 0x8400, // 33792\n forbiddenCharacter: 0x8401, // 33793\n bracketMismatch: 0x8409, // 33801\n doubleParenthesis: 0x840a, // 33802\n missingOpenBracket: 0x840b, // 33803\n missingCloseBracket: 0x840c, // 33804\n invalidFilterSyntax: 0x8417, // 33815\n expectedFunctionBody: 0x8418, // 33816\n expectedExpressionBody: 0x8419, // 33817\n expectedLogicBody: 0x841a, // 33818\n expectedQuantifierBody: 0x841b, // 33819\n expectedDeclarativeBody: 0x841c, // 33820\n expectedImperativeBody: 0x841d, // 33821\n expectedRecursiveBody: 0x841e, // 33822\n expectedQuantifierDomain: 0x841f, // 33823\n expectedRightOperand: 0x8420, // 33824\n expectedUnaryOperand: 0x8421, // 33825\n globalFuncParenCall: 0x8422, // 33826\n expectedArgument: 0x8423, // 33827\n expectedLocal: 0x8415, // 33813\n expectedType: 0x8416, // 33814\n\n localNotUsed: 0x2802, // 10242\n\n localUndeclared: 0x8801, // 34817\n localShadowing: 0x8802, // 34818\n localDoubleDeclare: 0x8803, // 34819\n\n typesNotEqual: 0x880a, // 34826\n globalNotTyped: 0x8804, // 34820\n invalidDecart: 0x8805, // 34821\n invalidBoolean: 0x8806, // 34822\n invalidTypeOperation: 0x8807, // 34823\n invalidCard: 0x8808, // 34824\n invalidDebool: 0x8809, // 34825\n globalFuncWithoutArgs: 0x880b, // 34827\n invalidReduce: 0x8810, // 34832\n invalidEnumeration: 0x8813, // 34835\n projectionSetArgumentNotSet: 0x8830, // 34864\n projectionSetArgumentNotTupleSet: 0x8831, // 34865\n projectionSetIndexOutOfRange: 0x8832, // 34866\n projectionTupleArgumentNotTuple: 0x8833, // 34867\n projectionTupleIndexOutOfRange: 0x8834, // 34868\n invalidCortegeDeclare: 0x8814, // 34836\n localOutOfScope: 0x8815, // 34837\n invalidElementPredicate: 0x8816, // 34838\n invalidEmptySetUsage: 0x8817, // 34839\n invalidArgsArity: 0x8818, // 34840\n invalidArgumentType: 0x8819, // 34841\n globalStructure: 0x881c, // 34844\n radicalUsage: 0x8821, // 34849\n invalidFilterArgumentType: 0x8822, // 34850\n invalidFilterArity: 0x8823, // 34851\n arithmeticNotSupported: 0x8824, // 34852\n typesNotCompatible: 0x8825, // 34853\n orderingNotSupported: 0x8826, // 34854\n expectedLogic: 0x8827, // 34855\n expectedSetexpr: 0x8828, // 34856\n invalidArgumentCortegeDeclare: 0x8829, // 34857\n invalidQuantifierDomain: 0x882a, // 34858\n invalidFilterParameterType: 0x882b, // 34859\n invalidFilterIndex: 0x882c, // 34860\n invalidFilterBooleanEchelon: 0x882d, // 34861\n localOutOfScopeParentheses: 0x882e, // 34862\n localUndeclaredInSubexpr: 0x882f, // 34863\n\n globalNoValue: 0x8840, // 34880\n invalidPropertyUsage: 0x8841, // 34881\n\n // Value evaluation (runtime)\n calcUnknownError: 0x8100, // 35328\n setOverflow: 0x8101, // 35329\n booleanBaseLimit: 0x8102, // 35330\n calcGlobalMissing: 0x8103, // 35331\n iterationsLimit: 0x8104, // 35332\n calcInvalidDebool: 0x8105, // 35333\n iterateInfinity: 0x8106, // 35334\n calculationNotSupported: 0x8107, // 35335\n calcInvalidData: 0x8108, // 35336\n\n cstEmptyDerived: 0x8861, // 34913\n definitionNotAllowed: 0x8862, // 34914\n\n // Schema diagnostics surfaced in expression analysis (same value as RSDiagnosticCode.schemaDependencyCycle).\n schemaDependencyCycle: 0x8906 // 35078\n} as const;\nexport type RSErrorCode = (typeof RSErrorCode)[keyof typeof RSErrorCode];\n\nconst ERROR_EVALUATION_MASK = 0x0100;\nconst ERROR_LEXER_MASK = 0x0200;\nconst ERROR_PARSER_MASK = 0x0400;\nconst ERROR_SEMANTIC_MASK = 0x0800;\n\n/** Infers error class from error type (code). */\nfunction inferErrorClass(error: RSErrorCode): RSErrorClass {\n if ((error & ERROR_EVALUATION_MASK) !== 0) {\n return RSErrorClass.EVALUATION;\n } else if ((error & ERROR_LEXER_MASK) !== 0) {\n return RSErrorClass.LEXER;\n } else if ((error & ERROR_PARSER_MASK) !== 0) {\n return RSErrorClass.PARSER;\n } else if ((error & ERROR_SEMANTIC_MASK) !== 0) {\n return RSErrorClass.SEMANTIC;\n } else {\n return RSErrorClass.UNKNOWN;\n }\n}\n\n/** Generate ErrorID label. */\nexport function getRSErrorPrefix(code: RSErrorCode): string {\n const id = code.toString(16).toUpperCase();\n // prettier-ignore\n switch (inferErrorClass(code)) {\n case RSErrorClass.LEXER: return 'L' + id;\n case RSErrorClass.PARSER: return 'P' + id;\n case RSErrorClass.SEMANTIC: return 'S' + id;\n case RSErrorClass.EVALUATION: return 'E' + id;\n case RSErrorClass.UNKNOWN: return 'U' + id;\n }\n}\n\n/** Checks if error is critical. */\nexport function isCritical(code: RSErrorCode): boolean {\n if ((code & 0xf000) === 0x2000) {\n return false;\n }\n return true;\n}\n"],"mappings":";;;AAGA,MAAa,eAAe;CAC1B,OAAO;CACP,QAAQ;CACR,UAAU;CACV,YAAY;CACZ,SAAS;AACX;;AAmBA,MAAa,cAAc;CACzB,eAAe;CACf,oBAAoB;CACpB,iBAAiB;CACjB,mBAAmB;CACnB,oBAAoB;CACpB,qBAAqB;CACrB,qBAAqB;CACrB,sBAAsB;CACtB,wBAAwB;CACxB,mBAAmB;CACnB,wBAAwB;CACxB,yBAAyB;CACzB,wBAAwB;CACxB,uBAAuB;CACvB,0BAA0B;CAC1B,sBAAsB;CACtB,sBAAsB;CACtB,qBAAqB;CACrB,kBAAkB;CAClB,eAAe;CACf,cAAc;CAEd,cAAc;CAEd,iBAAiB;CACjB,gBAAgB;CAChB,oBAAoB;CAEpB,eAAe;CACf,gBAAgB;CAChB,eAAe;CACf,gBAAgB;CAChB,sBAAsB;CACtB,aAAa;CACb,eAAe;CACf,uBAAuB;CACvB,eAAe;CACf,oBAAoB;CACpB,6BAA6B;CAC7B,kCAAkC;CAClC,8BAA8B;CAC9B,iCAAiC;CACjC,gCAAgC;CAChC,uBAAuB;CACvB,iBAAiB;CACjB,yBAAyB;CACzB,sBAAsB;CACtB,kBAAkB;CAClB,qBAAqB;CACrB,iBAAiB;CACjB,cAAc;CACd,2BAA2B;CAC3B,oBAAoB;CACpB,wBAAwB;CACxB,oBAAoB;CACpB,sBAAsB;CACtB,eAAe;CACf,iBAAiB;CACjB,+BAA+B;CAC/B,yBAAyB;CACzB,4BAA4B;CAC5B,oBAAoB;CACpB,6BAA6B;CAC7B,4BAA4B;CAC5B,0BAA0B;CAE1B,eAAe;CACf,sBAAsB;CAGtB,kBAAkB;CAClB,aAAa;CACb,kBAAkB;CAClB,mBAAmB;CACnB,iBAAiB;CACjB,mBAAmB;CACnB,iBAAiB;CACjB,yBAAyB;CACzB,iBAAiB;CAEjB,iBAAiB;CACjB,sBAAsB;CAGtB,uBAAuB;AACzB;AAGA,MAAM,wBAAwB;AAC9B,MAAM,mBAAmB;AACzB,MAAM,oBAAoB;AAC1B,MAAM,sBAAsB;;AAG5B,SAAS,gBAAgB,OAAkC;CACzD,KAAK,QAAQ,2BAA2B,GACtC,OAAO,aAAa;MACf,KAAK,QAAQ,sBAAsB,GACxC,OAAO,aAAa;MACf,KAAK,QAAQ,uBAAuB,GACzC,OAAO,aAAa;MACf,KAAK,QAAQ,yBAAyB,GAC3C,OAAO,aAAa;MAEpB,OAAO,aAAa;AAExB;;AAGA,SAAgB,iBAAiB,MAA2B;CAC1D,MAAM,KAAK,KAAK,SAAS,EAAE,CAAC,CAAC,YAAY;CAEzC,QAAQ,gBAAgB,IAAI,GAA5B;EACE,KAAK,aAAa,OAAO,OAAO,MAAM;EACtC,KAAK,aAAa,QAAQ,OAAO,MAAM;EACvC,KAAK,aAAa,UAAU,OAAO,MAAM;EACzC,KAAK,aAAa,YAAY,OAAO,MAAM;EAC3C,KAAK,aAAa,SAAS,OAAO,MAAM;CAC1C;AACF;;AAGA,SAAgB,WAAW,MAA4B;CACrD,KAAK,OAAO,WAAY,MACtB,OAAO;CAET,OAAO;AACT"}
1
+ {"version":3,"file":"error.js","names":[],"sources":["../../src/rslang/error.ts"],"sourcesContent":["/** Module: Error types and functions. */\n\n/** Represents error class. */\nexport const RSErrorClass = {\n LEXER: 0,\n PARSER: 1,\n SEMANTIC: 2,\n EVALUATION: 3,\n UNKNOWN: 4\n} as const;\nexport type RSErrorClass = (typeof RSErrorClass)[keyof typeof RSErrorClass];\n\n/** Represents RSLang expression error information. */\nexport interface RSErrorInfo {\n code: RSErrorCode;\n params?: readonly string[];\n}\n\n/**\n * One frame of an evaluation call chain.\n *\n * Spans are relative to the formal definition of {@link alias}.\n * Frames are ordered innermost-first: fault locus, then each caller outward.\n * The root expression under evaluation is not a frame — its highlight is\n * {@link RSErrorDescription.from}/{@link RSErrorDescription.to}; {@link RSErrorDescription.stack}\n * is absent when the fault is in that root expression.\n */\nexport interface EvalStackFrame {\n /** Constituent whose formal definition contains this span. */\n alias: string;\n /** Half-open span `[from, to)` in that definition. */\n from: number;\n to: number;\n}\n\n/** Represents RSLang expression error description. */\nexport interface RSErrorDescription extends RSErrorInfo {\n from: number;\n to: number;\n /**\n * Evaluation call chain when the fault is inside a called `F#`/`P#` body.\n * Absent for parse/semantic errors and for evaluation errors in the root expression.\n */\n stack?: readonly EvalStackFrame[];\n}\n\n/** Error reporter function type. */\nexport type ErrorReporter = (error: RSErrorDescription) => void;\n\n/**\n * Formats an evaluation call chain for display (`F5 → F12`).\n *\n * Uses callee aliases from outermost call to innermost fault container.\n * Returns an empty string when there is no nested call to show.\n */\nexport function formatEvalCallStack(stack: readonly EvalStackFrame[] | undefined): string {\n if (!stack || stack.length === 0) {\n return '';\n }\n const aliases: string[] = [];\n for (let index = stack.length - 1; index >= 0; index--) {\n const frame = stack[index];\n if (frame) {\n aliases.push(frame.alias);\n }\n }\n return aliases.join(' → ');\n}\n\n/** Represents RSLang expression error types. */\nexport const RSErrorCode = {\n unknownSyntax: 0x8400, // 33792\n forbiddenCharacter: 0x8401, // 33793\n bracketMismatch: 0x8409, // 33801\n doubleParenthesis: 0x840a, // 33802\n missingOpenBracket: 0x840b, // 33803\n missingCloseBracket: 0x840c, // 33804\n invalidFilterSyntax: 0x8417, // 33815\n expectedFunctionBody: 0x8418, // 33816\n expectedExpressionBody: 0x8419, // 33817\n expectedLogicBody: 0x841a, // 33818\n expectedQuantifierBody: 0x841b, // 33819\n expectedDeclarativeBody: 0x841c, // 33820\n expectedImperativeBody: 0x841d, // 33821\n expectedRecursiveBody: 0x841e, // 33822\n expectedQuantifierDomain: 0x841f, // 33823\n expectedRightOperand: 0x8420, // 33824\n expectedUnaryOperand: 0x8421, // 33825\n globalFuncParenCall: 0x8422, // 33826\n expectedArgument: 0x8423, // 33827\n expectedLocal: 0x8415, // 33813\n expectedType: 0x8416, // 33814\n\n localNotUsed: 0x2802, // 10242\n\n localUndeclared: 0x8801, // 34817\n localShadowing: 0x8802, // 34818\n localDoubleDeclare: 0x8803, // 34819\n\n typesNotEqual: 0x880a, // 34826\n globalNotTyped: 0x8804, // 34820\n invalidDecart: 0x8805, // 34821\n invalidBoolean: 0x8806, // 34822\n invalidTypeOperation: 0x8807, // 34823\n invalidCard: 0x8808, // 34824\n invalidDebool: 0x8809, // 34825\n globalFuncWithoutArgs: 0x880b, // 34827\n invalidReduce: 0x8810, // 34832\n invalidEnumeration: 0x8813, // 34835\n projectionSetArgumentNotSet: 0x8830, // 34864\n projectionSetArgumentNotTupleSet: 0x8831, // 34865\n projectionSetIndexOutOfRange: 0x8832, // 34866\n projectionTupleArgumentNotTuple: 0x8833, // 34867\n projectionTupleIndexOutOfRange: 0x8834, // 34868\n invalidCortegeDeclare: 0x8814, // 34836\n localOutOfScope: 0x8815, // 34837\n invalidElementPredicate: 0x8816, // 34838\n invalidEmptySetUsage: 0x8817, // 34839\n invalidArgsArity: 0x8818, // 34840\n invalidArgumentType: 0x8819, // 34841\n globalStructure: 0x881c, // 34844\n radicalUsage: 0x8821, // 34849\n invalidFilterArgumentType: 0x8822, // 34850\n invalidFilterArity: 0x8823, // 34851\n arithmeticNotSupported: 0x8824, // 34852\n typesNotCompatible: 0x8825, // 34853\n orderingNotSupported: 0x8826, // 34854\n expectedLogic: 0x8827, // 34855\n expectedSetexpr: 0x8828, // 34856\n invalidArgumentCortegeDeclare: 0x8829, // 34857\n invalidQuantifierDomain: 0x882a, // 34858\n invalidFilterParameterType: 0x882b, // 34859\n invalidFilterIndex: 0x882c, // 34860\n invalidFilterBooleanEchelon: 0x882d, // 34861\n localOutOfScopeParentheses: 0x882e, // 34862\n localUndeclaredInSubexpr: 0x882f, // 34863\n\n globalNoValue: 0x8840, // 34880\n invalidPropertyUsage: 0x8841, // 34881\n\n // Value evaluation (runtime)\n calcUnknownError: 0x8100, // 35328\n setOverflow: 0x8101, // 35329\n booleanBaseLimit: 0x8102, // 35330\n calcGlobalMissing: 0x8103, // 35331\n iterationsLimit: 0x8104, // 35332\n calcInvalidDebool: 0x8105, // 35333\n iterateInfinity: 0x8106, // 35334\n calculationNotSupported: 0x8107, // 35335\n calcInvalidData: 0x8108, // 35336\n\n cstEmptyDerived: 0x8861, // 34913\n definitionNotAllowed: 0x8862, // 34914\n\n // Schema diagnostics surfaced in expression analysis (same value as RSDiagnosticCode.schemaDependencyCycle).\n schemaDependencyCycle: 0x8906 // 35078\n} as const;\nexport type RSErrorCode = (typeof RSErrorCode)[keyof typeof RSErrorCode];\n\nconst ERROR_EVALUATION_MASK = 0x0100;\nconst ERROR_LEXER_MASK = 0x0200;\nconst ERROR_PARSER_MASK = 0x0400;\nconst ERROR_SEMANTIC_MASK = 0x0800;\n\n/** Infers error class from error type (code). */\nfunction inferErrorClass(error: RSErrorCode): RSErrorClass {\n if ((error & ERROR_EVALUATION_MASK) !== 0) {\n return RSErrorClass.EVALUATION;\n } else if ((error & ERROR_LEXER_MASK) !== 0) {\n return RSErrorClass.LEXER;\n } else if ((error & ERROR_PARSER_MASK) !== 0) {\n return RSErrorClass.PARSER;\n } else if ((error & ERROR_SEMANTIC_MASK) !== 0) {\n return RSErrorClass.SEMANTIC;\n } else {\n return RSErrorClass.UNKNOWN;\n }\n}\n\n/** Generate ErrorID label. */\nexport function getRSErrorPrefix(code: RSErrorCode): string {\n const id = code.toString(16).toUpperCase();\n // prettier-ignore\n switch (inferErrorClass(code)) {\n case RSErrorClass.LEXER: return 'L' + id;\n case RSErrorClass.PARSER: return 'P' + id;\n case RSErrorClass.SEMANTIC: return 'S' + id;\n case RSErrorClass.EVALUATION: return 'E' + id;\n case RSErrorClass.UNKNOWN: return 'U' + id;\n }\n}\n\n/** Checks if error is critical. */\nexport function isCritical(code: RSErrorCode): boolean {\n if ((code & 0xf000) === 0x2000) {\n return false;\n }\n return true;\n}\n"],"mappings":";;;AAGA,MAAa,eAAe;CAC1B,OAAO;CACP,QAAQ;CACR,UAAU;CACV,YAAY;CACZ,SAAS;AACX;;;;;;;AA8CA,SAAgB,oBAAoB,OAAsD;CACxF,IAAI,CAAC,SAAS,MAAM,WAAW,GAC7B,OAAO;CAET,MAAM,UAAoB,CAAC;CAC3B,KAAK,IAAI,QAAQ,MAAM,SAAS,GAAG,SAAS,GAAG,SAAS;EACtD,MAAM,QAAQ,MAAM;EACpB,IAAI,OACF,QAAQ,KAAK,MAAM,KAAK;CAE5B;CACA,OAAO,QAAQ,KAAK,KAAK;AAC3B;;AAGA,MAAa,cAAc;CACzB,eAAe;CACf,oBAAoB;CACpB,iBAAiB;CACjB,mBAAmB;CACnB,oBAAoB;CACpB,qBAAqB;CACrB,qBAAqB;CACrB,sBAAsB;CACtB,wBAAwB;CACxB,mBAAmB;CACnB,wBAAwB;CACxB,yBAAyB;CACzB,wBAAwB;CACxB,uBAAuB;CACvB,0BAA0B;CAC1B,sBAAsB;CACtB,sBAAsB;CACtB,qBAAqB;CACrB,kBAAkB;CAClB,eAAe;CACf,cAAc;CAEd,cAAc;CAEd,iBAAiB;CACjB,gBAAgB;CAChB,oBAAoB;CAEpB,eAAe;CACf,gBAAgB;CAChB,eAAe;CACf,gBAAgB;CAChB,sBAAsB;CACtB,aAAa;CACb,eAAe;CACf,uBAAuB;CACvB,eAAe;CACf,oBAAoB;CACpB,6BAA6B;CAC7B,kCAAkC;CAClC,8BAA8B;CAC9B,iCAAiC;CACjC,gCAAgC;CAChC,uBAAuB;CACvB,iBAAiB;CACjB,yBAAyB;CACzB,sBAAsB;CACtB,kBAAkB;CAClB,qBAAqB;CACrB,iBAAiB;CACjB,cAAc;CACd,2BAA2B;CAC3B,oBAAoB;CACpB,wBAAwB;CACxB,oBAAoB;CACpB,sBAAsB;CACtB,eAAe;CACf,iBAAiB;CACjB,+BAA+B;CAC/B,yBAAyB;CACzB,4BAA4B;CAC5B,oBAAoB;CACpB,6BAA6B;CAC7B,4BAA4B;CAC5B,0BAA0B;CAE1B,eAAe;CACf,sBAAsB;CAGtB,kBAAkB;CAClB,aAAa;CACb,kBAAkB;CAClB,mBAAmB;CACnB,iBAAiB;CACjB,mBAAmB;CACnB,iBAAiB;CACjB,yBAAyB;CACzB,iBAAiB;CAEjB,iBAAiB;CACjB,sBAAsB;CAGtB,uBAAuB;AACzB;AAGA,MAAM,wBAAwB;AAC9B,MAAM,mBAAmB;AACzB,MAAM,oBAAoB;AAC1B,MAAM,sBAAsB;;AAG5B,SAAS,gBAAgB,OAAkC;CACzD,KAAK,QAAQ,2BAA2B,GACtC,OAAO,aAAa;MACf,KAAK,QAAQ,sBAAsB,GACxC,OAAO,aAAa;MACf,KAAK,QAAQ,uBAAuB,GACzC,OAAO,aAAa;MACf,KAAK,QAAQ,yBAAyB,GAC3C,OAAO,aAAa;MAEpB,OAAO,aAAa;AAExB;;AAGA,SAAgB,iBAAiB,MAA2B;CAC1D,MAAM,KAAK,KAAK,SAAS,EAAE,CAAC,CAAC,YAAY;CAEzC,QAAQ,gBAAgB,IAAI,GAA5B;EACE,KAAK,aAAa,OAAO,OAAO,MAAM;EACtC,KAAK,aAAa,QAAQ,OAAO,MAAM;EACvC,KAAK,aAAa,UAAU,OAAO,MAAM;EACzC,KAAK,aAAa,YAAY,OAAO,MAAM;EAC3C,KAAK,aAAa,SAAS,OAAO,MAAM;CAC1C;AACF;;AAGA,SAAgB,WAAW,MAA4B;CACrD,KAAK,OAAO,WAAY,MACtB,OAAO;CAET,OAAO;AACT"}
@@ -1,2 +1,2 @@
1
- import { n as CalculatorResult, r as RSCalculator, t as CalculatorEvaluateOptions } from "../../calculator-uPaTV3hc.js";
1
+ import { n as CalculatorResult, r as RSCalculator, t as CalculatorEvaluateOptions } from "../../calculator-B-1p712X.js";
2
2
  export { CalculatorEvaluateOptions, CalculatorResult, RSCalculator };
@@ -1,6 +1,6 @@
1
1
  import { annotateError } from "../ast-annotations.js";
2
2
  import { RSErrorCode } from "../error.js";
3
- import { M as validateValue } from "../../value-COprb2Je.js";
3
+ import { M as validateValue } from "../../value-BDISzQqI.js";
4
4
  import { Evaluator } from "./evaluator.js";
5
5
  //#region src/rslang/eval/calculator.ts
6
6
  /** AST calculator - evaluates RS expressions via visitor pattern and provides updates via listeners. */
@@ -180,9 +180,7 @@ function extendBoundInPlace(bound, declNode) {
180
180
  case TokenID.NT_ENUM_DECL:
181
181
  for (const child of declNode.children) extendBoundInPlace(bound, child);
182
182
  break;
183
- case TokenID.NT_ARG_DECL:
184
- extendBoundInPlace(bound, declNode.children[0]);
185
- break;
183
+ case TokenID.NT_ARG_DECL: extendBoundInPlace(bound, declNode.children[0]);
186
184
  }
187
185
  }
188
186
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"evaluation-cache.js","names":[],"sources":["../../../src/rslang/eval/evaluation-cache.ts"],"sourcesContent":["/**\n * Module: Dependency metadata and per-run memoization for RSLang evaluation.\n */\n\nimport { type AstNode, getNodeIndices, getNodeText } from '../../parsing';\nimport { TokenID } from '../parser/token';\n\nimport { type Value } from './value';\n\n/** Static metadata for one AST node. */\nexport interface EvalNodeInfo {\n /** Local aliases this expression reads (for dependency stamping). */\n reads: ReadonlySet<string>;\n /** Stable key shared by structurally equivalent expressions. */\n structuralKey: string;\n /** Whether the node may be memoized for the current evaluation run. */\n cacheable: boolean;\n}\n\n/** Per-evaluator cache of immutable AST dependency metadata (no runtime values). */\nexport class EvaluationMetadata {\n private readonly byNode = new WeakMap<AstNode, EvalNodeInfo>();\n\n get(node: AstNode): EvalNodeInfo {\n let info = this.byNode.get(node);\n if (!info) {\n info = analyzeNode(node, new Set());\n this.byNode.set(node, info);\n }\n return info;\n }\n}\n\n/** Per-run memo of computed values (cleared on each {@link Evaluator.run}). */\nexport class EvaluationCache {\n private entries = new Map<string, CacheEntry>();\n\n /** Cache hits in the current evaluation run (for tests/diagnostics). */\n hits = 0;\n\n /** Returns cached value, or `undefined` on miss or stamp mismatch. */\n lookup(structuralKey: string, stamp: string): Value | undefined {\n const entry = this.entries.get(structuralKey);\n if (entry?.stamp !== stamp) {\n return undefined;\n }\n this.hits++;\n return entry.value;\n }\n\n /** Stores one value per structural key (replaces previous stamp). */\n store(structuralKey: string, stamp: string, value: Value): void {\n this.entries.set(structuralKey, { stamp, value });\n }\n\n clear(): void {\n this.entries.clear();\n this.hits = 0;\n }\n}\n\ninterface CacheEntry {\n stamp: string;\n value: Value;\n}\n\nfunction analyzeNode(node: AstNode, bound: Set<string>): EvalNodeInfo {\n const reads = collectReads(node, bound);\n const structuralKey = buildStructuralKey(node);\n const cacheable = isCacheableNode(node);\n return { reads, structuralKey, cacheable };\n}\n\nfunction isCacheableNode(node: AstNode): boolean {\n switch (node.typeID) {\n case TokenID.ASSIGN:\n case TokenID.ITERATE:\n case TokenID.NT_IMPERATIVE_EXPR:\n case TokenID.NT_DECLARATIVE_EXPR:\n case TokenID.NT_RECURSIVE_FULL:\n case TokenID.NT_RECURSIVE_SHORT:\n case TokenID.QUANTOR_UNIVERSAL:\n case TokenID.QUANTOR_EXISTS:\n case TokenID.LOGIC_AND:\n case TokenID.LOGIC_OR:\n case TokenID.LOGIC_IMPLICATION:\n case TokenID.NT_FUNC_DEFINITION:\n case TokenID.LIT_INTEGER:\n case TokenID.LIT_EMPTYSET:\n case TokenID.LIT_WHOLE_NUMBERS:\n case TokenID.ID_LOCAL:\n case TokenID.ID_RADICAL:\n case TokenID.ID_GLOBAL:\n return false;\n default:\n return !node.hasError;\n }\n}\n\nfunction buildStructuralKey(node: AstNode): string {\n switch (node.typeID) {\n case TokenID.ID_GLOBAL:\n case TokenID.ID_LOCAL:\n case TokenID.ID_RADICAL:\n case TokenID.LIT_INTEGER:\n case TokenID.LIT_EMPTYSET:\n case TokenID.LIT_WHOLE_NUMBERS:\n return `${node.typeID}:${nodeTextKey(node)}`;\n\n case TokenID.NT_FUNC_CALL:\n return `${node.typeID}:${nodeTextKey(node.children[0])}(${node.children\n .slice(1)\n .map(buildStructuralKey)\n .join(',')})`;\n\n case TokenID.BIGPR:\n case TokenID.SMALLPR:\n case TokenID.FILTER:\n return `${node.typeID}:${indicesKey(node)}(${node.children.map(buildStructuralKey).join(',')})`;\n\n default:\n return `${node.typeID}(${node.children.map(buildStructuralKey).join(',')})`;\n }\n}\n\nfunction nodeTextKey(node: AstNode): string {\n if (node.data.dataType === 'number') {\n return String(node.data.value);\n }\n return getNodeText(node);\n}\n\nfunction indicesKey(node: AstNode): string {\n return getNodeIndices(node).join('.');\n}\n\nfunction collectReads(node: AstNode, bound: Set<string>): Set<string> {\n const reads = new Set<string>();\n collectReadsImpl(node, bound, reads);\n return reads;\n}\n\nfunction collectReadsImpl(node: AstNode, bound: Set<string>, reads: Set<string>): void {\n switch (node.typeID) {\n case TokenID.ID_LOCAL:\n case TokenID.ID_RADICAL: {\n reads.add(getNodeText(node));\n return;\n }\n\n case TokenID.QUANTOR_UNIVERSAL:\n case TokenID.QUANTOR_EXISTS: {\n collectReadsImpl(node.children[1], bound, reads);\n const innerBound = extendBound(bound, node.children[0]);\n collectReadsImpl(node.children[2], innerBound, reads);\n return;\n }\n\n case TokenID.NT_DECLARATIVE_EXPR: {\n collectReadsImpl(node.children[1], bound, reads);\n const innerBound = extendBound(bound, node.children[0]);\n collectReadsImpl(node.children[2], innerBound, reads);\n return;\n }\n\n case TokenID.ITERATE: {\n collectReadsImpl(node.children[1], bound, reads);\n return;\n }\n\n case TokenID.ASSIGN: {\n collectReadsImpl(node.children[1], bound, reads);\n return;\n }\n\n case TokenID.NT_IMPERATIVE_EXPR: {\n const innerBound = new Set(bound);\n collectReadsImpl(node.children[0], innerBound, reads);\n for (let i = 1; i < node.children.length; i++) {\n const child = node.children[i];\n if (child.typeID === TokenID.ITERATE) {\n extendBoundInPlace(innerBound, child.children[0]);\n collectReadsImpl(child.children[1], innerBound, reads);\n } else if (child.typeID === TokenID.ASSIGN) {\n collectReadsImpl(child.children[1], innerBound, reads);\n extendBoundInPlace(innerBound, child.children[0]);\n } else {\n collectReadsImpl(child, innerBound, reads);\n }\n }\n return;\n }\n\n case TokenID.NT_RECURSIVE_FULL:\n case TokenID.NT_RECURSIVE_SHORT: {\n collectReadsImpl(node.children[1], bound, reads);\n const innerBound = extendBound(bound, node.children[0]);\n if (node.typeID === TokenID.NT_RECURSIVE_FULL) {\n collectReadsImpl(node.children[2], innerBound, reads);\n collectReadsImpl(node.children[3], innerBound, reads);\n } else {\n collectReadsImpl(node.children[2], innerBound, reads);\n }\n return;\n }\n\n case TokenID.NT_FUNC_DEFINITION: {\n const innerBound = extendBound(bound, node.children[0]);\n collectReadsImpl(node.children[1], innerBound, reads);\n return;\n }\n\n case TokenID.NT_FUNC_CALL: {\n for (let i = 1; i < node.children.length; i++) {\n collectReadsImpl(node.children[i], bound, reads);\n }\n return;\n }\n\n case TokenID.LOGIC_AND:\n case TokenID.LOGIC_OR:\n case TokenID.LOGIC_IMPLICATION: {\n collectReadsImpl(node.children[0], bound, reads);\n collectReadsImpl(node.children[1], bound, reads);\n return;\n }\n\n default:\n for (const child of node.children) {\n collectReadsImpl(child, bound, reads);\n }\n }\n}\n\nfunction extendBound(bound: Set<string>, declNode: AstNode): Set<string> {\n const next = new Set(bound);\n extendBoundInPlace(next, declNode);\n return next;\n}\n\nfunction extendBoundInPlace(bound: Set<string>, declNode: AstNode): void {\n switch (declNode.typeID) {\n case TokenID.ID_LOCAL:\n case TokenID.ID_RADICAL:\n bound.add(getNodeText(declNode));\n break;\n case TokenID.NT_TUPLE_DECL:\n case TokenID.NT_ENUM_DECL:\n for (const child of declNode.children) {\n extendBoundInPlace(bound, child);\n }\n break;\n case TokenID.NT_ARG_DECL:\n extendBoundInPlace(bound, declNode.children[0]);\n break;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"evaluation-cache.js","names":[],"sources":["../../../src/rslang/eval/evaluation-cache.ts"],"sourcesContent":["/**\n * Module: Dependency metadata and per-run memoization for RSLang evaluation.\n */\n\nimport { type AstNode, getNodeIndices, getNodeText } from '../../parsing';\nimport { TokenID } from '../parser/token';\n\nimport { type Value } from './value';\n\n/** Static metadata for one AST node. */\nexport interface EvalNodeInfo {\n /** Local aliases this expression reads (for dependency stamping). */\n reads: ReadonlySet<string>;\n /** Stable key shared by structurally equivalent expressions. */\n structuralKey: string;\n /** Whether the node may be memoized for the current evaluation run. */\n cacheable: boolean;\n}\n\n/** Per-evaluator cache of immutable AST dependency metadata (no runtime values). */\nexport class EvaluationMetadata {\n private readonly byNode = new WeakMap<AstNode, EvalNodeInfo>();\n\n get(node: AstNode): EvalNodeInfo {\n let info = this.byNode.get(node);\n if (!info) {\n info = analyzeNode(node, new Set());\n this.byNode.set(node, info);\n }\n return info;\n }\n}\n\n/** Per-run memo of computed values (cleared on each {@link Evaluator.run}). */\nexport class EvaluationCache {\n private entries = new Map<string, CacheEntry>();\n\n /** Cache hits in the current evaluation run (for tests/diagnostics). */\n hits = 0;\n\n /** Returns cached value, or `undefined` on miss or stamp mismatch. */\n lookup(structuralKey: string, stamp: string): Value | undefined {\n const entry = this.entries.get(structuralKey);\n if (entry?.stamp !== stamp) {\n return undefined;\n }\n this.hits++;\n return entry.value;\n }\n\n /** Stores one value per structural key (replaces previous stamp). */\n store(structuralKey: string, stamp: string, value: Value): void {\n this.entries.set(structuralKey, { stamp, value });\n }\n\n clear(): void {\n this.entries.clear();\n this.hits = 0;\n }\n}\n\ninterface CacheEntry {\n stamp: string;\n value: Value;\n}\n\nfunction analyzeNode(node: AstNode, bound: Set<string>): EvalNodeInfo {\n const reads = collectReads(node, bound);\n const structuralKey = buildStructuralKey(node);\n const cacheable = isCacheableNode(node);\n return { reads, structuralKey, cacheable };\n}\n\nfunction isCacheableNode(node: AstNode): boolean {\n switch (node.typeID) {\n case TokenID.ASSIGN:\n case TokenID.ITERATE:\n case TokenID.NT_IMPERATIVE_EXPR:\n case TokenID.NT_DECLARATIVE_EXPR:\n case TokenID.NT_RECURSIVE_FULL:\n case TokenID.NT_RECURSIVE_SHORT:\n case TokenID.QUANTOR_UNIVERSAL:\n case TokenID.QUANTOR_EXISTS:\n case TokenID.LOGIC_AND:\n case TokenID.LOGIC_OR:\n case TokenID.LOGIC_IMPLICATION:\n case TokenID.NT_FUNC_DEFINITION:\n case TokenID.LIT_INTEGER:\n case TokenID.LIT_EMPTYSET:\n case TokenID.LIT_WHOLE_NUMBERS:\n case TokenID.ID_LOCAL:\n case TokenID.ID_RADICAL:\n case TokenID.ID_GLOBAL:\n return false;\n default:\n return !node.hasError;\n }\n}\n\nfunction buildStructuralKey(node: AstNode): string {\n switch (node.typeID) {\n case TokenID.ID_GLOBAL:\n case TokenID.ID_LOCAL:\n case TokenID.ID_RADICAL:\n case TokenID.LIT_INTEGER:\n case TokenID.LIT_EMPTYSET:\n case TokenID.LIT_WHOLE_NUMBERS:\n return `${node.typeID}:${nodeTextKey(node)}`;\n\n case TokenID.NT_FUNC_CALL:\n return `${node.typeID}:${nodeTextKey(node.children[0])}(${node.children\n .slice(1)\n .map(buildStructuralKey)\n .join(',')})`;\n\n case TokenID.BIGPR:\n case TokenID.SMALLPR:\n case TokenID.FILTER:\n return `${node.typeID}:${indicesKey(node)}(${node.children.map(buildStructuralKey).join(',')})`;\n\n default:\n return `${node.typeID}(${node.children.map(buildStructuralKey).join(',')})`;\n }\n}\n\nfunction nodeTextKey(node: AstNode): string {\n if (node.data.dataType === 'number') {\n return String(node.data.value);\n }\n return getNodeText(node);\n}\n\nfunction indicesKey(node: AstNode): string {\n return getNodeIndices(node).join('.');\n}\n\nfunction collectReads(node: AstNode, bound: Set<string>): Set<string> {\n const reads = new Set<string>();\n collectReadsImpl(node, bound, reads);\n return reads;\n}\n\nfunction collectReadsImpl(node: AstNode, bound: Set<string>, reads: Set<string>): void {\n switch (node.typeID) {\n case TokenID.ID_LOCAL:\n case TokenID.ID_RADICAL: {\n reads.add(getNodeText(node));\n return;\n }\n\n case TokenID.QUANTOR_UNIVERSAL:\n case TokenID.QUANTOR_EXISTS: {\n collectReadsImpl(node.children[1], bound, reads);\n const innerBound = extendBound(bound, node.children[0]);\n collectReadsImpl(node.children[2], innerBound, reads);\n return;\n }\n\n case TokenID.NT_DECLARATIVE_EXPR: {\n collectReadsImpl(node.children[1], bound, reads);\n const innerBound = extendBound(bound, node.children[0]);\n collectReadsImpl(node.children[2], innerBound, reads);\n return;\n }\n\n case TokenID.ITERATE: {\n collectReadsImpl(node.children[1], bound, reads);\n return;\n }\n\n case TokenID.ASSIGN: {\n collectReadsImpl(node.children[1], bound, reads);\n return;\n }\n\n case TokenID.NT_IMPERATIVE_EXPR: {\n const innerBound = new Set(bound);\n collectReadsImpl(node.children[0], innerBound, reads);\n for (let i = 1; i < node.children.length; i++) {\n const child = node.children[i];\n if (child.typeID === TokenID.ITERATE) {\n extendBoundInPlace(innerBound, child.children[0]);\n collectReadsImpl(child.children[1], innerBound, reads);\n } else if (child.typeID === TokenID.ASSIGN) {\n collectReadsImpl(child.children[1], innerBound, reads);\n extendBoundInPlace(innerBound, child.children[0]);\n } else {\n collectReadsImpl(child, innerBound, reads);\n }\n }\n return;\n }\n\n case TokenID.NT_RECURSIVE_FULL:\n case TokenID.NT_RECURSIVE_SHORT: {\n collectReadsImpl(node.children[1], bound, reads);\n const innerBound = extendBound(bound, node.children[0]);\n if (node.typeID === TokenID.NT_RECURSIVE_FULL) {\n collectReadsImpl(node.children[2], innerBound, reads);\n collectReadsImpl(node.children[3], innerBound, reads);\n } else {\n collectReadsImpl(node.children[2], innerBound, reads);\n }\n return;\n }\n\n case TokenID.NT_FUNC_DEFINITION: {\n const innerBound = extendBound(bound, node.children[0]);\n collectReadsImpl(node.children[1], innerBound, reads);\n return;\n }\n\n case TokenID.NT_FUNC_CALL: {\n for (let i = 1; i < node.children.length; i++) {\n collectReadsImpl(node.children[i], bound, reads);\n }\n return;\n }\n\n case TokenID.LOGIC_AND:\n case TokenID.LOGIC_OR:\n case TokenID.LOGIC_IMPLICATION: {\n collectReadsImpl(node.children[0], bound, reads);\n collectReadsImpl(node.children[1], bound, reads);\n return;\n }\n\n default:\n for (const child of node.children) {\n collectReadsImpl(child, bound, reads);\n }\n }\n}\n\nfunction extendBound(bound: Set<string>, declNode: AstNode): Set<string> {\n const next = new Set(bound);\n extendBoundInPlace(next, declNode);\n return next;\n}\n\nfunction extendBoundInPlace(bound: Set<string>, declNode: AstNode): void {\n switch (declNode.typeID) {\n case TokenID.ID_LOCAL:\n case TokenID.ID_RADICAL:\n bound.add(getNodeText(declNode));\n break;\n case TokenID.NT_TUPLE_DECL:\n case TokenID.NT_ENUM_DECL:\n for (const child of declNode.children) {\n extendBoundInPlace(bound, child);\n }\n break;\n case TokenID.NT_ARG_DECL:\n extendBoundInPlace(bound, declNode.children[0]);\n break;\n }\n}\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { t as AstNode } from "../../ast-D-D6Rq3T.js";
2
2
  import "../../index-D5RahF1K.js";
3
- import { t as ErrorReporter } from "../../error-B0EkIx4K.js";
3
+ import { t as ErrorReporter } from "../../error-S1JghCNN.js";
4
4
  import { l as Value, u as ValueContext } from "../../value-XpJOVzMP.js";
5
5
  //#region src/rslang/eval/evaluator.d.ts
6
6
  /** AST context. */
@@ -23,7 +23,17 @@ declare class Evaluator {
23
23
  constructor(context: ValueContext, astContext: ASTContext);
24
24
  run(ast: AstNode, reporter?: ErrorReporter, annotateErrors?: boolean, disableCache?: boolean): Value | null;
25
25
  private clear;
26
- private errorNode;
26
+ /**
27
+ * Surface highlight target in the root expression under evaluation.
28
+ * Nested call sites live in callee ASTs — only the outermost call is in the root.
29
+ */
30
+ private surfaceErrorNode;
31
+ /**
32
+ * Builds innermost-first frames for called `F#`/`P#` bodies only.
33
+ * The root expression is represented by the surface `from`/`to`, not a stack frame.
34
+ * Returns `undefined` when the fault is in the root expression (no function call).
35
+ */
36
+ private buildEvalStack;
27
37
  private onError;
28
38
  private tick;
29
39
  private dispatchDeclare;
@@ -5,7 +5,7 @@ import { labelRSLangNode } from "../labels.js";
5
5
  import { annotateError } from "../ast-annotations.js";
6
6
  import { RSErrorCode } from "../error.js";
7
7
  import { EvaluationCache, EvaluationMetadata } from "./evaluation-cache.js";
8
- import { A as setUnion, D as setIntersection, E as setDiff, T as reduce, a as SET_INFINITY, d as set, f as tuple, h as contains, k as setSymDiff, l as compare, m as cartesianProduct, n as CalcInvalidDataError, p as boolean, r as EmptySetV, w as projection, y as isSubsetOrEq } from "../../value-COprb2Je.js";
8
+ import { A as setUnion, D as setIntersection, E as setDiff, T as reduce, a as SET_INFINITY, d as set, f as tuple, h as contains, k as setSymDiff, l as compare, m as cartesianProduct, n as CalcInvalidDataError, p as boolean, r as EmptySetV, w as projection, y as isSubsetOrEq } from "../../value-BDISzQqI.js";
9
9
  //#region src/rslang/eval/evaluator.ts
10
10
  /**
11
11
  * Module: AST evaluation - visitor-pattern evaluator for RS expressions.
@@ -52,17 +52,49 @@ var Evaluator = class {
52
52
  this.callSiteStack = [];
53
53
  this.iterationCounter = 0;
54
54
  }
55
- errorNode(node) {
56
- if (this.callSiteStack.length > 0) return this.callSiteStack[this.callSiteStack.length - 1];
57
- return node;
55
+ /**
56
+ * Surface highlight target in the root expression under evaluation.
57
+ * Nested call sites live in callee ASTs — only the outermost call is in the root.
58
+ */
59
+ surfaceErrorNode(fault) {
60
+ return this.callSiteStack[0] ?? fault;
61
+ }
62
+ /**
63
+ * Builds innermost-first frames for called `F#`/`P#` bodies only.
64
+ * The root expression is represented by the surface `from`/`to`, not a stack frame.
65
+ * Returns `undefined` when the fault is in the root expression (no function call).
66
+ */
67
+ buildEvalStack(fault) {
68
+ if (this.callSiteStack.length === 0) return;
69
+ const frames = [];
70
+ const innermostCall = this.callSiteStack[this.callSiteStack.length - 1];
71
+ if (!innermostCall) return;
72
+ frames.push({
73
+ alias: getNodeText(innermostCall.children[0]),
74
+ from: fault.from,
75
+ to: fault.to
76
+ });
77
+ for (let index = this.callSiteStack.length - 1; index >= 1; index--) {
78
+ const callSite = this.callSiteStack[index];
79
+ const outerCall = this.callSiteStack[index - 1];
80
+ if (!callSite || !outerCall) continue;
81
+ frames.push({
82
+ alias: getNodeText(outerCall.children[0]),
83
+ from: callSite.from,
84
+ to: callSite.to
85
+ });
86
+ }
87
+ return frames;
58
88
  }
59
89
  onError(code, node, params) {
60
- const target = this.errorNode(node);
90
+ const target = this.surfaceErrorNode(node);
91
+ const stack = this.buildEvalStack(node);
61
92
  this.reporter?.({
62
93
  code,
63
94
  from: target.from,
64
95
  to: target.to,
65
- params
96
+ ...params !== void 0 ? { params } : {},
97
+ ...stack !== void 0 ? { stack } : {}
66
98
  });
67
99
  if (this.annotateErrors) annotateError(target, code, params);
68
100
  return null;
@@ -427,7 +459,8 @@ var Evaluator = class {
427
459
  visitProjectSet(node) {
428
460
  const target = this.visitChild(node, 0);
429
461
  if (target === null) return null;
430
- return projection(target, getNodeIndices(node));
462
+ const indices = getNodeIndices(node);
463
+ return projection(target, indices);
431
464
  }
432
465
  visitProjectTuple(node) {
433
466
  const target = this.visitChild(node, 0);
@@ -470,7 +503,8 @@ var Evaluator = class {
470
503
  const result = [];
471
504
  for (const element of argVal) {
472
505
  const comps = indices.map((i) => element[i]);
473
- if (contains(paramVal, comps.length === 1 ? comps[0] : tuple(comps))) result.push(element);
506
+ const testElement = comps.length === 1 ? comps[0] : tuple(comps);
507
+ if (contains(paramVal, testElement)) result.push(element);
474
508
  }
475
509
  return result;
476
510
  }