@stevenvo780/st-lang 2.8.0 → 3.0.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 (39) hide show
  1. package/dist/ast/nodes.d.ts +35 -2
  2. package/dist/ast/nodes.d.ts.map +1 -1
  3. package/dist/index.d.ts +1 -1
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/index.js +4 -1
  6. package/dist/index.js.map +1 -1
  7. package/dist/lexer/lexer.d.ts.map +1 -1
  8. package/dist/lexer/lexer.js +4 -0
  9. package/dist/lexer/lexer.js.map +1 -1
  10. package/dist/lexer/tokens.d.ts +8 -0
  11. package/dist/lexer/tokens.d.ts.map +1 -1
  12. package/dist/lexer/tokens.js +23 -0
  13. package/dist/lexer/tokens.js.map +1 -1
  14. package/dist/parser/parser.d.ts +6 -0
  15. package/dist/parser/parser.d.ts.map +1 -1
  16. package/dist/parser/parser.js +171 -6
  17. package/dist/parser/parser.js.map +1 -1
  18. package/dist/protocol/handler.d.ts.map +1 -1
  19. package/dist/protocol/handler.js +327 -88
  20. package/dist/protocol/handler.js.map +1 -1
  21. package/dist/runtime/interpreter.d.ts +24 -0
  22. package/dist/runtime/interpreter.d.ts.map +1 -1
  23. package/dist/runtime/interpreter.js +409 -1
  24. package/dist/runtime/interpreter.js.map +1 -1
  25. package/dist/tests/v3-features.test.d.ts +2 -0
  26. package/dist/tests/v3-features.test.d.ts.map +1 -0
  27. package/dist/tests/v3-features.test.js +529 -0
  28. package/dist/tests/v3-features.test.js.map +1 -0
  29. package/dist/tests/v3-stress.test.d.ts +2 -0
  30. package/dist/tests/v3-stress.test.d.ts.map +1 -0
  31. package/dist/tests/v3-stress.test.js +755 -0
  32. package/dist/tests/v3-stress.test.js.map +1 -0
  33. package/dist/text-layer/compiler.d.ts +4 -1
  34. package/dist/text-layer/compiler.d.ts.map +1 -1
  35. package/dist/text-layer/compiler.js +35 -0
  36. package/dist/text-layer/compiler.js.map +1 -1
  37. package/dist/types/index.d.ts +27 -1
  38. package/dist/types/index.d.ts.map +1 -1
  39. package/package.json +1 -1
@@ -54,6 +54,10 @@ export declare class Interpreter {
54
54
  /** Memoización automática para funciones con argumentos numéricos (fibonacci, factorial, etc.) */
55
55
  private fnMemoCache;
56
56
  private static readonly MEMO_CACHE_MAX;
57
+ /** v3: Formal definitions (define Name(params?) := body) */
58
+ private definitions;
59
+ /** v3: Bibliographic sources */
60
+ private sources;
57
61
  constructor();
58
62
  /** Registra funciones nativas (Built-ins) para metaprogramación e interactividad */
59
63
  private registerBuiltins;
@@ -115,6 +119,10 @@ export declare class Interpreter {
115
119
  private execConfidenceDecl;
116
120
  private execContextDecl;
117
121
  private execRenderCmd;
122
+ /** Render glossary in the specified format */
123
+ private renderGlossary;
124
+ /** Render full analysis document */
125
+ private renderAnalysis;
118
126
  private execAnalyzeCmd;
119
127
  private execProofBlock;
120
128
  private execTheoryDecl;
@@ -126,6 +134,22 @@ export declare class Interpreter {
126
134
  private execWhileStmt;
127
135
  private execFnDecl;
128
136
  private execReturnStmt;
137
+ private execDefineDecl;
138
+ /** Detect circular definitions (A := ... A ...) */
139
+ private checkCircularDefinition;
140
+ /** Expand a definition by name with given arguments */
141
+ private expandDefinition;
142
+ /** Recursively substitute parameter names with actual argument formulas */
143
+ private substituteParams;
144
+ /** Expand all definitions in a formula (one level) */
145
+ private expandDefinitionsInFormula;
146
+ /** Try to fold a formula back into a definition reference */
147
+ private foldFormula;
148
+ private execUnfoldCmd;
149
+ private execFoldCmd;
150
+ private execSourceDecl;
151
+ private execInterpretCmd;
152
+ private execGlossaryCmd;
129
153
  private executeFnCall;
130
154
  private startFunctionFrame;
131
155
  private createFunctionFrame;
@@ -1 +1 @@
1
- {"version":3,"file":"interpreter.d.ts","sourceRoot":"","sources":["../../src/runtime/interpreter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"interpreter.d.ts","sourceRoot":"","sources":["../../src/runtime/interpreter.ts"],"names":[],"mappings":"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"}
@@ -56,6 +56,10 @@ class Interpreter {
56
56
  /** Memoización automática para funciones con argumentos numéricos (fibonacci, factorial, etc.) */
57
57
  fnMemoCache = new Map();
58
58
  static MEMO_CACHE_MAX = 50000;
59
+ /** v3: Formal definitions (define Name(params?) := body) */
60
+ definitions = new Map();
61
+ /** v3: Bibliographic sources */
62
+ sources = new Map();
59
63
  constructor() {
60
64
  this.theory = this.createEmptyTheory();
61
65
  this.textLayer = (0, compiler_1.createTextLayerState)();
@@ -120,6 +124,8 @@ class Interpreter {
120
124
  this.runtimeStepCount = 0;
121
125
  this.runtimeCallCount = 0;
122
126
  this.fnMemoCache.clear();
127
+ this.definitions.clear();
128
+ this.sources.clear();
123
129
  }
124
130
  // ── Memoización de funciones ──────────────────────────────
125
131
  /** Serializa una fórmula a una cadena para usar como clave de cache */
@@ -159,6 +165,9 @@ class Interpreter {
159
165
  case 'import_decl':
160
166
  case 'export_decl':
161
167
  case 'logic_decl':
168
+ case 'glossary_cmd':
169
+ case 'unfold_cmd':
170
+ case 'fold_cmd':
162
171
  return false;
163
172
  case 'if_stmt': {
164
173
  const ifS = s;
@@ -449,6 +458,18 @@ class Interpreter {
449
458
  return;
450
459
  case 'export_decl':
451
460
  return this.execExportDecl(stmt);
461
+ case 'define_decl':
462
+ return this.execDefineDecl(stmt);
463
+ case 'unfold_cmd':
464
+ return this.execUnfoldCmd(stmt);
465
+ case 'fold_cmd':
466
+ return this.execFoldCmd(stmt);
467
+ case 'source_decl':
468
+ return this.execSourceDecl(stmt);
469
+ case 'interpret_cmd':
470
+ return this.execInterpretCmd(stmt);
471
+ case 'glossary_cmd':
472
+ return this.execGlossaryCmd(stmt);
452
473
  }
453
474
  }
454
475
  executeStatementsIterative(statements, fallbackFile) {
@@ -617,6 +638,18 @@ class Interpreter {
617
638
  return;
618
639
  case 'export_decl':
619
640
  return this.execExportDecl(stmt);
641
+ case 'define_decl':
642
+ return this.execDefineDecl(stmt);
643
+ case 'unfold_cmd':
644
+ return this.execUnfoldCmd(stmt);
645
+ case 'fold_cmd':
646
+ return this.execFoldCmd(stmt);
647
+ case 'source_decl':
648
+ return this.execSourceDecl(stmt);
649
+ case 'interpret_cmd':
650
+ return this.execInterpretCmd(stmt);
651
+ case 'glossary_cmd':
652
+ return this.execGlossaryCmd(stmt);
620
653
  }
621
654
  }
622
655
  selectIfBody(stmt) {
@@ -734,6 +767,13 @@ class Interpreter {
734
767
  case 'theory_decl':
735
768
  this.exportedTheories.set(s.name, this.theories.get(s.name));
736
769
  break;
770
+ case 'define_decl': {
771
+ const defEntry = this.definitions.get(s.name);
772
+ if (defEntry) {
773
+ this.exportedBindings.set(s.name, defEntry.body);
774
+ }
775
+ break;
776
+ }
737
777
  }
738
778
  }
739
779
  requireProfile() {
@@ -832,6 +872,32 @@ class Interpreter {
832
872
  visited.delete(f.name);
833
873
  return result;
834
874
  }
875
+ // v3: Expand definitions (no-param definitions referenced as atoms)
876
+ const def = this.definitions.get(f.name);
877
+ if (def && (!def.params || def.params.length === 0)) {
878
+ if (visited.has(f.name))
879
+ return f;
880
+ visited.add(f.name);
881
+ const result = this.resolveFormulaRecursive(def.body, visited);
882
+ visited.delete(f.name);
883
+ return result;
884
+ }
885
+ }
886
+ // v3: Expand parametric definitions used as predicates: F(a, b)
887
+ if (f.kind === 'predicate' && f.name) {
888
+ const def = this.definitions.get(f.name);
889
+ if (def && def.params && def.params.length > 0) {
890
+ // Predicates store arguments as params (string[]) or args (Formula[])
891
+ let argFormulas;
892
+ if (f.args && f.args.length > 0) {
893
+ argFormulas = f.args.map((a) => (a ? this.resolveFormulaRecursive(a, visited) : a));
894
+ }
895
+ else {
896
+ argFormulas = (f.params ?? []).map((p) => ({ kind: 'atom', name: p, source: f.source }));
897
+ }
898
+ const expanded = this.substituteParams(def.body, def.params, argFormulas);
899
+ return this.resolveFormulaRecursive(expanded, visited);
900
+ }
835
901
  }
836
902
  // Llamada a función como expresión
837
903
  if (f.kind === 'fn_call' && f.name) {
@@ -937,6 +1003,9 @@ class Interpreter {
937
1003
  let isSatisfiable = false;
938
1004
  let count = 0;
939
1005
  let satCount = 0;
1006
+ // Accumulate rows for graphic view (cap at 512 to avoid OOM on huge tables)
1007
+ const MAX_GRAPHIC_ROWS = 512;
1008
+ const rows = [];
940
1009
  for (const v of (0, propositional_1.generateValuationsLazy)(atoms)) {
941
1010
  const res = (0, propositional_1.evaluateClassical)(formula, v);
942
1011
  if (res) {
@@ -947,6 +1016,10 @@ class Interpreter {
947
1016
  isTautology = false;
948
1017
  }
949
1018
  count++;
1019
+ // Accumulate rows for the graphic table (capped)
1020
+ if (count <= MAX_GRAPHIC_ROWS) {
1021
+ rows.push({ valuation: { ...v }, result: res });
1022
+ }
950
1023
  // Solo imprimir las primeras 64 filas para no saturar el stdout en tablas masivas
951
1024
  if (count <= 64) {
952
1025
  const row = atoms.map((a) => (v[a] ? 'V' : 'F')).join(' | ');
@@ -963,13 +1036,14 @@ class Interpreter {
963
1036
  output: `Tabla de verdad de ${count} filas procesada.`,
964
1037
  truthTable: {
965
1038
  variables: atoms,
966
- rows: [],
1039
+ rows,
967
1040
  subFormulas: [],
968
1041
  subFormulaValues: [],
969
1042
  isTautology,
970
1043
  isContradiction: !isSatisfiable,
971
1044
  isSatisfiable,
972
1045
  satisfyingCount: satCount,
1046
+ totalCount: count,
973
1047
  },
974
1048
  diagnostics: [],
975
1049
  formula: formula,
@@ -1070,6 +1144,12 @@ class Interpreter {
1070
1144
  execRenderCmd(stmt) {
1071
1145
  const diags = (0, compiler_1.compileClaimsToTheory)(this.textLayer, this.theory);
1072
1146
  this.diagnostics.push(...diags);
1147
+ if (stmt.target === 'glossary') {
1148
+ return this.renderGlossary(stmt.format);
1149
+ }
1150
+ if (stmt.target === 'analysis') {
1151
+ return this.renderAnalysis(stmt.format);
1152
+ }
1073
1153
  if (stmt.target === 'claims' || stmt.target === 'all') {
1074
1154
  this.emit(`── Render: ${stmt.target} (${stmt.format}) ──`);
1075
1155
  for (const [name, claim] of this.theory.claims) {
@@ -1113,6 +1193,98 @@ class Interpreter {
1113
1193
  this.emit(`Render: ${stmt.target} (${stmt.format})`);
1114
1194
  }
1115
1195
  }
1196
+ /** Render glossary in the specified format */
1197
+ renderGlossary(format) {
1198
+ if (format === 'json') {
1199
+ const obj = {};
1200
+ for (const [name, def] of this.definitions) {
1201
+ obj[name] = {
1202
+ params: def.params ?? [],
1203
+ body: (0, propositional_1.formulaToString)(def.body),
1204
+ description: def.description ?? null,
1205
+ };
1206
+ }
1207
+ this.emit(JSON.stringify(obj, null, 2));
1208
+ return;
1209
+ }
1210
+ // markdown or default
1211
+ if (this.definitions.size === 0) {
1212
+ this.emit('(sin definiciones)');
1213
+ return;
1214
+ }
1215
+ for (const [name, def] of this.definitions) {
1216
+ const paramsStr = def.params?.length ? `(${def.params.join(', ')})` : '';
1217
+ const bodyStr = format === 'latex' ? (0, format_1.formulaToLaTeX)(def.body) : (0, format_1.formulaToUnicode)(def.body);
1218
+ if (format === 'latex') {
1219
+ this.emit(`\\newcommand{\\${name}}{${bodyStr}} % ${def.description ?? ''}`);
1220
+ }
1221
+ else {
1222
+ this.emit(`- **${name}${paramsStr}** := ${bodyStr}`);
1223
+ if (def.description)
1224
+ this.emit(` > ${def.description}`);
1225
+ }
1226
+ }
1227
+ }
1228
+ /** Render full analysis document */
1229
+ renderAnalysis(format) {
1230
+ const isLatex = format === 'latex';
1231
+ const heading = (level, text) => {
1232
+ if (isLatex)
1233
+ return `${'\\'.repeat(1)}${'sub'.repeat(level - 1)}section{${text}}`;
1234
+ return `${'#'.repeat(level)} ${text}`;
1235
+ };
1236
+ this.emit(heading(1, 'Análisis'));
1237
+ this.emit('');
1238
+ // Sources
1239
+ if (this.sources.size > 0) {
1240
+ this.emit(heading(2, 'Fuentes'));
1241
+ for (const [, src] of this.sources) {
1242
+ const yearStr = src.year ? ` (${src.year})` : '';
1243
+ this.emit(`- ${src.author ?? ''}${yearStr} *${src.work ?? ''}*`);
1244
+ }
1245
+ this.emit('');
1246
+ }
1247
+ // Definitions
1248
+ if (this.definitions.size > 0) {
1249
+ this.emit(heading(2, 'Definiciones'));
1250
+ this.renderGlossary(format);
1251
+ this.emit('');
1252
+ }
1253
+ // Axioms
1254
+ if (this.theory.axioms.size > 0) {
1255
+ this.emit(heading(2, 'Axiomas'));
1256
+ for (const [name, formula] of this.theory.axioms) {
1257
+ this.emit(`- **${name}**: ${(0, format_1.formulaToUnicode)(formula)}`);
1258
+ }
1259
+ this.emit('');
1260
+ }
1261
+ // Theorems
1262
+ if (this.theory.theorems.size > 0) {
1263
+ this.emit(heading(2, 'Teoremas'));
1264
+ for (const [name, formula] of this.theory.theorems) {
1265
+ this.emit(`- **${name}**: ${(0, format_1.formulaToUnicode)(formula)}`);
1266
+ }
1267
+ this.emit('');
1268
+ }
1269
+ // Claims
1270
+ if (this.theory.claims.size > 0) {
1271
+ this.emit(heading(2, 'Claims'));
1272
+ for (const [name, claim] of this.theory.claims) {
1273
+ const fStr = claim.formula ? (0, format_1.formulaToUnicode)(claim.formula) : '(sin fórmula)';
1274
+ this.emit(`- **${name}**: ${fStr}`);
1275
+ }
1276
+ this.emit('');
1277
+ }
1278
+ // Results summary
1279
+ if (this.results.length > 0) {
1280
+ this.emit(heading(2, 'Verificaciones'));
1281
+ for (const r of this.results) {
1282
+ const status = r.status === 'valid' ? '✓' : r.status === 'satisfiable' ? '~' : '✗';
1283
+ const fStr = r.formula ? (0, format_1.formulaToUnicode)(r.formula) : '';
1284
+ this.emit(`- ${fStr}: ${r.status} ${status}`);
1285
+ }
1286
+ }
1287
+ }
1116
1288
  execAnalyzeCmd(stmt) {
1117
1289
  const profile = this.requireProfile();
1118
1290
  const premises = stmt.premises.map((p) => this.resolveFormula(p));
@@ -1341,6 +1513,242 @@ class Interpreter {
1341
1513
  this.returnValue = undefined;
1342
1514
  this.returnSignal = true;
1343
1515
  }
1516
+ // ── v3: Definitions, sources, glossary ──────────────────────────
1517
+ execDefineDecl(stmt) {
1518
+ // Check for circular definitions
1519
+ this.checkCircularDefinition(stmt.name, stmt.body, new Set());
1520
+ const entry = {
1521
+ name: stmt.name,
1522
+ params: stmt.params,
1523
+ body: stmt.body,
1524
+ description: stmt.description,
1525
+ };
1526
+ this.definitions.set(stmt.name, entry);
1527
+ const diags = (0, compiler_1.registerDefinition)(this.textLayer, entry);
1528
+ this.diagnostics.push(...diags);
1529
+ this.invalidateResolveCache();
1530
+ const paramsStr = stmt.params?.length ? `(${stmt.params.join(', ')})` : '';
1531
+ const bodyStr = (0, format_1.formulaToUnicode)(stmt.body);
1532
+ this.emit(`Define ${stmt.name}${paramsStr} := ${bodyStr}`);
1533
+ if (stmt.description) {
1534
+ this.emit(` → "${stmt.description}"`);
1535
+ }
1536
+ }
1537
+ /** Detect circular definitions (A := ... A ...) */
1538
+ checkCircularDefinition(name, body, visited) {
1539
+ if (!body)
1540
+ return;
1541
+ if (body.kind === 'atom' && body.name) {
1542
+ if (body.name === name) {
1543
+ throw new Error(`Definición circular detectada: '${name}' se refiere a sí mismo`);
1544
+ }
1545
+ if (visited.has(body.name))
1546
+ return;
1547
+ visited.add(body.name);
1548
+ const dep = this.definitions.get(body.name);
1549
+ if (dep) {
1550
+ this.checkCircularDefinition(name, dep.body, visited);
1551
+ }
1552
+ }
1553
+ if (body.args) {
1554
+ for (const arg of body.args) {
1555
+ if (arg)
1556
+ this.checkCircularDefinition(name, arg, visited);
1557
+ }
1558
+ }
1559
+ }
1560
+ /** Expand a definition by name with given arguments */
1561
+ expandDefinition(name, args) {
1562
+ const def = this.definitions.get(name);
1563
+ if (!def)
1564
+ return null;
1565
+ // If definition has no params, return body directly
1566
+ if (!def.params || def.params.length === 0) {
1567
+ return def.body;
1568
+ }
1569
+ // Substitute params with args
1570
+ const actualArgs = args ?? [];
1571
+ return this.substituteParams(def.body, def.params, actualArgs);
1572
+ }
1573
+ /** Recursively substitute parameter names with actual argument formulas */
1574
+ substituteParams(formula, params, args) {
1575
+ if (!formula)
1576
+ return formula;
1577
+ if (formula.kind === 'atom' && formula.name) {
1578
+ const idx = params.indexOf(formula.name);
1579
+ if (idx >= 0 && idx < args.length) {
1580
+ return args[idx];
1581
+ }
1582
+ return formula;
1583
+ }
1584
+ if (formula.args && formula.args.length > 0) {
1585
+ const newArgs = formula.args.map((a) => (a ? this.substituteParams(a, params, args) : a));
1586
+ let changed = false;
1587
+ for (let i = 0; i < formula.args.length; i++) {
1588
+ if (formula.args[i] !== newArgs[i]) {
1589
+ changed = true;
1590
+ break;
1591
+ }
1592
+ }
1593
+ return changed ? { ...formula, args: newArgs } : formula;
1594
+ }
1595
+ return formula;
1596
+ }
1597
+ /** Expand all definitions in a formula (one level) */
1598
+ expandDefinitionsInFormula(f) {
1599
+ if (!f)
1600
+ return f;
1601
+ // If atom matches a definition name (no params), expand it
1602
+ if (f.kind === 'atom' && f.name) {
1603
+ const expanded = this.expandDefinition(f.name);
1604
+ if (expanded)
1605
+ return expanded;
1606
+ }
1607
+ // If it's a predicate-like call (name with args), try to expand parametric definition
1608
+ if (f.kind === 'predicate' && f.name) {
1609
+ const def = this.definitions.get(f.name);
1610
+ if (def && def.params && def.params.length > 0 && f.args) {
1611
+ const expanded = this.expandDefinition(f.name, f.args);
1612
+ if (expanded)
1613
+ return expanded;
1614
+ }
1615
+ }
1616
+ // Recurse into sub-formulas
1617
+ if (f.args && f.args.length > 0) {
1618
+ const newArgs = f.args.map((a) => (a ? this.expandDefinitionsInFormula(a) : a));
1619
+ let changed = false;
1620
+ for (let i = 0; i < f.args.length; i++) {
1621
+ if (f.args[i] !== newArgs[i]) {
1622
+ changed = true;
1623
+ break;
1624
+ }
1625
+ }
1626
+ return changed ? { ...f, args: newArgs } : f;
1627
+ }
1628
+ return f;
1629
+ }
1630
+ /** Try to fold a formula back into a definition reference */
1631
+ foldFormula(f) {
1632
+ const fStr = (0, propositional_1.formulaToString)(f);
1633
+ for (const [name, def] of this.definitions) {
1634
+ if (!def.params || def.params.length === 0) {
1635
+ const defStr = (0, propositional_1.formulaToString)(def.body);
1636
+ if (fStr === defStr) {
1637
+ return { kind: 'atom', name, source: f.source };
1638
+ }
1639
+ }
1640
+ }
1641
+ return f;
1642
+ }
1643
+ execUnfoldCmd(stmt) {
1644
+ const resolved = this.resolveFormulaRecursive(stmt.formula, new Set());
1645
+ const expanded = this.expandDefinitionsInFormula(resolved);
1646
+ const expandedStr = (0, format_1.formulaToUnicode)(expanded);
1647
+ this.emit(`Unfold: ${(0, format_1.formulaToUnicode)(resolved)} → ${expandedStr}`);
1648
+ this.results.push({
1649
+ status: 'valid',
1650
+ output: expandedStr,
1651
+ diagnostics: [],
1652
+ formula: expanded,
1653
+ });
1654
+ }
1655
+ execFoldCmd(stmt) {
1656
+ const resolved = this.resolveFormulaRecursive(stmt.formula, new Set());
1657
+ const folded = this.foldFormula(resolved);
1658
+ const foldedStr = (0, format_1.formulaToUnicode)(folded);
1659
+ this.emit(`Fold: ${(0, format_1.formulaToUnicode)(resolved)} → ${foldedStr}`);
1660
+ this.results.push({
1661
+ status: 'valid',
1662
+ output: foldedStr,
1663
+ diagnostics: [],
1664
+ formula: folded,
1665
+ });
1666
+ }
1667
+ execSourceDecl(stmt) {
1668
+ const info = { id: stmt.name };
1669
+ for (const field of stmt.fields) {
1670
+ switch (field.key) {
1671
+ case 'author':
1672
+ info.author = String(field.value);
1673
+ break;
1674
+ case 'work':
1675
+ info.work = String(field.value);
1676
+ break;
1677
+ case 'year':
1678
+ info.year = typeof field.value === 'number' ? field.value : parseInt(String(field.value));
1679
+ break;
1680
+ case 'section':
1681
+ info.section = String(field.value);
1682
+ break;
1683
+ case 'edition':
1684
+ info.edition = String(field.value);
1685
+ break;
1686
+ case 'url':
1687
+ info.url = String(field.value);
1688
+ break;
1689
+ }
1690
+ }
1691
+ this.sources.set(stmt.name, info);
1692
+ const diags = (0, compiler_1.registerSource)(this.textLayer, info);
1693
+ this.diagnostics.push(...diags);
1694
+ const yearStr = info.year ? ` (${info.year})` : '';
1695
+ this.emit(`Source ${stmt.name}: ${info.author ?? ''}${yearStr} — ${info.work ?? ''}`);
1696
+ }
1697
+ execInterpretCmd(stmt) {
1698
+ const formula = this.resolveFormula(stmt.formula);
1699
+ const key = stmt.passageRef ?? stmt.text;
1700
+ const diags = (0, compiler_1.registerInterpretation)(this.textLayer, key, {
1701
+ text: stmt.text,
1702
+ passageRef: stmt.passageRef,
1703
+ formula,
1704
+ });
1705
+ this.diagnostics.push(...diags);
1706
+ // Also register as a let binding so the interpretation is available as a named formula
1707
+ const bindingName = stmt.text.replace(/\s+/g, '_').replace(/[^a-zA-Z0-9_]/g, '');
1708
+ if (bindingName) {
1709
+ this.defineBinding(bindingName, formula);
1710
+ }
1711
+ this.emit(`Interpret: "${stmt.text}" → ${(0, format_1.formulaToUnicode)(formula)}`);
1712
+ }
1713
+ execGlossaryCmd(_stmt) {
1714
+ this.emit('');
1715
+ this.emit('══════════════════════════════════════');
1716
+ this.emit(' GLOSARIO');
1717
+ this.emit('══════════════════════════════════════');
1718
+ if (this.definitions.size === 0) {
1719
+ this.emit(' (sin definiciones registradas)');
1720
+ }
1721
+ else {
1722
+ for (const [name, def] of this.definitions) {
1723
+ const paramsStr = def.params?.length ? `(${def.params.join(', ')})` : '';
1724
+ const bodyStr = (0, format_1.formulaToUnicode)(def.body);
1725
+ this.emit(` ${name}${paramsStr} := ${bodyStr}`);
1726
+ if (def.description) {
1727
+ this.emit(` "${def.description}"`);
1728
+ }
1729
+ }
1730
+ }
1731
+ // Also show sources if any
1732
+ if (this.sources.size > 0) {
1733
+ this.emit('');
1734
+ this.emit('── Fuentes ──');
1735
+ for (const [, src] of this.sources) {
1736
+ const yearStr = src.year ? ` (${src.year})` : '';
1737
+ this.emit(` ${src.id}: ${src.author ?? ''}${yearStr} — ${src.work ?? ''}`);
1738
+ }
1739
+ }
1740
+ // Show interpretations if any
1741
+ if (this.textLayer.interpretations.size > 0) {
1742
+ this.emit('');
1743
+ this.emit('── Interpretaciones ──');
1744
+ for (const [, interp] of this.textLayer.interpretations) {
1745
+ this.emit(` "${interp.text}" → ${(0, format_1.formulaToUnicode)(interp.formula)}`);
1746
+ }
1747
+ }
1748
+ this.emit('══════════════════════════════════════');
1749
+ this.emit('');
1750
+ }
1751
+ // ── End v3 ─────────────────────────────────────────────────
1344
1752
  executeFnCall(stmt) {
1345
1753
  // ── Memoización: verificar cache antes de ejecutar ──
1346
1754
  const evaluatedArgs = stmt.args.map((a) => this.evaluateFormulaValue(a));