@stevenvo780/st-lang 2.8.0 → 3.0.0

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 +400 -0
  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) {
@@ -1070,6 +1136,12 @@ class Interpreter {
1070
1136
  execRenderCmd(stmt) {
1071
1137
  const diags = (0, compiler_1.compileClaimsToTheory)(this.textLayer, this.theory);
1072
1138
  this.diagnostics.push(...diags);
1139
+ if (stmt.target === 'glossary') {
1140
+ return this.renderGlossary(stmt.format);
1141
+ }
1142
+ if (stmt.target === 'analysis') {
1143
+ return this.renderAnalysis(stmt.format);
1144
+ }
1073
1145
  if (stmt.target === 'claims' || stmt.target === 'all') {
1074
1146
  this.emit(`── Render: ${stmt.target} (${stmt.format}) ──`);
1075
1147
  for (const [name, claim] of this.theory.claims) {
@@ -1113,6 +1185,98 @@ class Interpreter {
1113
1185
  this.emit(`Render: ${stmt.target} (${stmt.format})`);
1114
1186
  }
1115
1187
  }
1188
+ /** Render glossary in the specified format */
1189
+ renderGlossary(format) {
1190
+ if (format === 'json') {
1191
+ const obj = {};
1192
+ for (const [name, def] of this.definitions) {
1193
+ obj[name] = {
1194
+ params: def.params ?? [],
1195
+ body: (0, propositional_1.formulaToString)(def.body),
1196
+ description: def.description ?? null,
1197
+ };
1198
+ }
1199
+ this.emit(JSON.stringify(obj, null, 2));
1200
+ return;
1201
+ }
1202
+ // markdown or default
1203
+ if (this.definitions.size === 0) {
1204
+ this.emit('(sin definiciones)');
1205
+ return;
1206
+ }
1207
+ for (const [name, def] of this.definitions) {
1208
+ const paramsStr = def.params?.length ? `(${def.params.join(', ')})` : '';
1209
+ const bodyStr = format === 'latex' ? (0, format_1.formulaToLaTeX)(def.body) : (0, format_1.formulaToUnicode)(def.body);
1210
+ if (format === 'latex') {
1211
+ this.emit(`\\newcommand{\\${name}}{${bodyStr}} % ${def.description ?? ''}`);
1212
+ }
1213
+ else {
1214
+ this.emit(`- **${name}${paramsStr}** := ${bodyStr}`);
1215
+ if (def.description)
1216
+ this.emit(` > ${def.description}`);
1217
+ }
1218
+ }
1219
+ }
1220
+ /** Render full analysis document */
1221
+ renderAnalysis(format) {
1222
+ const isLatex = format === 'latex';
1223
+ const heading = (level, text) => {
1224
+ if (isLatex)
1225
+ return `${'\\'.repeat(1)}${'sub'.repeat(level - 1)}section{${text}}`;
1226
+ return `${'#'.repeat(level)} ${text}`;
1227
+ };
1228
+ this.emit(heading(1, 'Análisis'));
1229
+ this.emit('');
1230
+ // Sources
1231
+ if (this.sources.size > 0) {
1232
+ this.emit(heading(2, 'Fuentes'));
1233
+ for (const [, src] of this.sources) {
1234
+ const yearStr = src.year ? ` (${src.year})` : '';
1235
+ this.emit(`- ${src.author ?? ''}${yearStr} *${src.work ?? ''}*`);
1236
+ }
1237
+ this.emit('');
1238
+ }
1239
+ // Definitions
1240
+ if (this.definitions.size > 0) {
1241
+ this.emit(heading(2, 'Definiciones'));
1242
+ this.renderGlossary(format);
1243
+ this.emit('');
1244
+ }
1245
+ // Axioms
1246
+ if (this.theory.axioms.size > 0) {
1247
+ this.emit(heading(2, 'Axiomas'));
1248
+ for (const [name, formula] of this.theory.axioms) {
1249
+ this.emit(`- **${name}**: ${(0, format_1.formulaToUnicode)(formula)}`);
1250
+ }
1251
+ this.emit('');
1252
+ }
1253
+ // Theorems
1254
+ if (this.theory.theorems.size > 0) {
1255
+ this.emit(heading(2, 'Teoremas'));
1256
+ for (const [name, formula] of this.theory.theorems) {
1257
+ this.emit(`- **${name}**: ${(0, format_1.formulaToUnicode)(formula)}`);
1258
+ }
1259
+ this.emit('');
1260
+ }
1261
+ // Claims
1262
+ if (this.theory.claims.size > 0) {
1263
+ this.emit(heading(2, 'Claims'));
1264
+ for (const [name, claim] of this.theory.claims) {
1265
+ const fStr = claim.formula ? (0, format_1.formulaToUnicode)(claim.formula) : '(sin fórmula)';
1266
+ this.emit(`- **${name}**: ${fStr}`);
1267
+ }
1268
+ this.emit('');
1269
+ }
1270
+ // Results summary
1271
+ if (this.results.length > 0) {
1272
+ this.emit(heading(2, 'Verificaciones'));
1273
+ for (const r of this.results) {
1274
+ const status = r.status === 'valid' ? '✓' : r.status === 'satisfiable' ? '~' : '✗';
1275
+ const fStr = r.formula ? (0, format_1.formulaToUnicode)(r.formula) : '';
1276
+ this.emit(`- ${fStr}: ${r.status} ${status}`);
1277
+ }
1278
+ }
1279
+ }
1116
1280
  execAnalyzeCmd(stmt) {
1117
1281
  const profile = this.requireProfile();
1118
1282
  const premises = stmt.premises.map((p) => this.resolveFormula(p));
@@ -1341,6 +1505,242 @@ class Interpreter {
1341
1505
  this.returnValue = undefined;
1342
1506
  this.returnSignal = true;
1343
1507
  }
1508
+ // ── v3: Definitions, sources, glossary ──────────────────────────
1509
+ execDefineDecl(stmt) {
1510
+ // Check for circular definitions
1511
+ this.checkCircularDefinition(stmt.name, stmt.body, new Set());
1512
+ const entry = {
1513
+ name: stmt.name,
1514
+ params: stmt.params,
1515
+ body: stmt.body,
1516
+ description: stmt.description,
1517
+ };
1518
+ this.definitions.set(stmt.name, entry);
1519
+ const diags = (0, compiler_1.registerDefinition)(this.textLayer, entry);
1520
+ this.diagnostics.push(...diags);
1521
+ this.invalidateResolveCache();
1522
+ const paramsStr = stmt.params?.length ? `(${stmt.params.join(', ')})` : '';
1523
+ const bodyStr = (0, format_1.formulaToUnicode)(stmt.body);
1524
+ this.emit(`Define ${stmt.name}${paramsStr} := ${bodyStr}`);
1525
+ if (stmt.description) {
1526
+ this.emit(` → "${stmt.description}"`);
1527
+ }
1528
+ }
1529
+ /** Detect circular definitions (A := ... A ...) */
1530
+ checkCircularDefinition(name, body, visited) {
1531
+ if (!body)
1532
+ return;
1533
+ if (body.kind === 'atom' && body.name) {
1534
+ if (body.name === name) {
1535
+ throw new Error(`Definición circular detectada: '${name}' se refiere a sí mismo`);
1536
+ }
1537
+ if (visited.has(body.name))
1538
+ return;
1539
+ visited.add(body.name);
1540
+ const dep = this.definitions.get(body.name);
1541
+ if (dep) {
1542
+ this.checkCircularDefinition(name, dep.body, visited);
1543
+ }
1544
+ }
1545
+ if (body.args) {
1546
+ for (const arg of body.args) {
1547
+ if (arg)
1548
+ this.checkCircularDefinition(name, arg, visited);
1549
+ }
1550
+ }
1551
+ }
1552
+ /** Expand a definition by name with given arguments */
1553
+ expandDefinition(name, args) {
1554
+ const def = this.definitions.get(name);
1555
+ if (!def)
1556
+ return null;
1557
+ // If definition has no params, return body directly
1558
+ if (!def.params || def.params.length === 0) {
1559
+ return def.body;
1560
+ }
1561
+ // Substitute params with args
1562
+ const actualArgs = args ?? [];
1563
+ return this.substituteParams(def.body, def.params, actualArgs);
1564
+ }
1565
+ /** Recursively substitute parameter names with actual argument formulas */
1566
+ substituteParams(formula, params, args) {
1567
+ if (!formula)
1568
+ return formula;
1569
+ if (formula.kind === 'atom' && formula.name) {
1570
+ const idx = params.indexOf(formula.name);
1571
+ if (idx >= 0 && idx < args.length) {
1572
+ return args[idx];
1573
+ }
1574
+ return formula;
1575
+ }
1576
+ if (formula.args && formula.args.length > 0) {
1577
+ const newArgs = formula.args.map((a) => (a ? this.substituteParams(a, params, args) : a));
1578
+ let changed = false;
1579
+ for (let i = 0; i < formula.args.length; i++) {
1580
+ if (formula.args[i] !== newArgs[i]) {
1581
+ changed = true;
1582
+ break;
1583
+ }
1584
+ }
1585
+ return changed ? { ...formula, args: newArgs } : formula;
1586
+ }
1587
+ return formula;
1588
+ }
1589
+ /** Expand all definitions in a formula (one level) */
1590
+ expandDefinitionsInFormula(f) {
1591
+ if (!f)
1592
+ return f;
1593
+ // If atom matches a definition name (no params), expand it
1594
+ if (f.kind === 'atom' && f.name) {
1595
+ const expanded = this.expandDefinition(f.name);
1596
+ if (expanded)
1597
+ return expanded;
1598
+ }
1599
+ // If it's a predicate-like call (name with args), try to expand parametric definition
1600
+ if (f.kind === 'predicate' && f.name) {
1601
+ const def = this.definitions.get(f.name);
1602
+ if (def && def.params && def.params.length > 0 && f.args) {
1603
+ const expanded = this.expandDefinition(f.name, f.args);
1604
+ if (expanded)
1605
+ return expanded;
1606
+ }
1607
+ }
1608
+ // Recurse into sub-formulas
1609
+ if (f.args && f.args.length > 0) {
1610
+ const newArgs = f.args.map((a) => (a ? this.expandDefinitionsInFormula(a) : a));
1611
+ let changed = false;
1612
+ for (let i = 0; i < f.args.length; i++) {
1613
+ if (f.args[i] !== newArgs[i]) {
1614
+ changed = true;
1615
+ break;
1616
+ }
1617
+ }
1618
+ return changed ? { ...f, args: newArgs } : f;
1619
+ }
1620
+ return f;
1621
+ }
1622
+ /** Try to fold a formula back into a definition reference */
1623
+ foldFormula(f) {
1624
+ const fStr = (0, propositional_1.formulaToString)(f);
1625
+ for (const [name, def] of this.definitions) {
1626
+ if (!def.params || def.params.length === 0) {
1627
+ const defStr = (0, propositional_1.formulaToString)(def.body);
1628
+ if (fStr === defStr) {
1629
+ return { kind: 'atom', name, source: f.source };
1630
+ }
1631
+ }
1632
+ }
1633
+ return f;
1634
+ }
1635
+ execUnfoldCmd(stmt) {
1636
+ const resolved = this.resolveFormulaRecursive(stmt.formula, new Set());
1637
+ const expanded = this.expandDefinitionsInFormula(resolved);
1638
+ const expandedStr = (0, format_1.formulaToUnicode)(expanded);
1639
+ this.emit(`Unfold: ${(0, format_1.formulaToUnicode)(resolved)} → ${expandedStr}`);
1640
+ this.results.push({
1641
+ status: 'valid',
1642
+ output: expandedStr,
1643
+ diagnostics: [],
1644
+ formula: expanded,
1645
+ });
1646
+ }
1647
+ execFoldCmd(stmt) {
1648
+ const resolved = this.resolveFormulaRecursive(stmt.formula, new Set());
1649
+ const folded = this.foldFormula(resolved);
1650
+ const foldedStr = (0, format_1.formulaToUnicode)(folded);
1651
+ this.emit(`Fold: ${(0, format_1.formulaToUnicode)(resolved)} → ${foldedStr}`);
1652
+ this.results.push({
1653
+ status: 'valid',
1654
+ output: foldedStr,
1655
+ diagnostics: [],
1656
+ formula: folded,
1657
+ });
1658
+ }
1659
+ execSourceDecl(stmt) {
1660
+ const info = { id: stmt.name };
1661
+ for (const field of stmt.fields) {
1662
+ switch (field.key) {
1663
+ case 'author':
1664
+ info.author = String(field.value);
1665
+ break;
1666
+ case 'work':
1667
+ info.work = String(field.value);
1668
+ break;
1669
+ case 'year':
1670
+ info.year = typeof field.value === 'number' ? field.value : parseInt(String(field.value));
1671
+ break;
1672
+ case 'section':
1673
+ info.section = String(field.value);
1674
+ break;
1675
+ case 'edition':
1676
+ info.edition = String(field.value);
1677
+ break;
1678
+ case 'url':
1679
+ info.url = String(field.value);
1680
+ break;
1681
+ }
1682
+ }
1683
+ this.sources.set(stmt.name, info);
1684
+ const diags = (0, compiler_1.registerSource)(this.textLayer, info);
1685
+ this.diagnostics.push(...diags);
1686
+ const yearStr = info.year ? ` (${info.year})` : '';
1687
+ this.emit(`Source ${stmt.name}: ${info.author ?? ''}${yearStr} — ${info.work ?? ''}`);
1688
+ }
1689
+ execInterpretCmd(stmt) {
1690
+ const formula = this.resolveFormula(stmt.formula);
1691
+ const key = stmt.passageRef ?? stmt.text;
1692
+ const diags = (0, compiler_1.registerInterpretation)(this.textLayer, key, {
1693
+ text: stmt.text,
1694
+ passageRef: stmt.passageRef,
1695
+ formula,
1696
+ });
1697
+ this.diagnostics.push(...diags);
1698
+ // Also register as a let binding so the interpretation is available as a named formula
1699
+ const bindingName = stmt.text.replace(/\s+/g, '_').replace(/[^a-zA-Z0-9_]/g, '');
1700
+ if (bindingName) {
1701
+ this.defineBinding(bindingName, formula);
1702
+ }
1703
+ this.emit(`Interpret: "${stmt.text}" → ${(0, format_1.formulaToUnicode)(formula)}`);
1704
+ }
1705
+ execGlossaryCmd(_stmt) {
1706
+ this.emit('');
1707
+ this.emit('══════════════════════════════════════');
1708
+ this.emit(' GLOSARIO');
1709
+ this.emit('══════════════════════════════════════');
1710
+ if (this.definitions.size === 0) {
1711
+ this.emit(' (sin definiciones registradas)');
1712
+ }
1713
+ else {
1714
+ for (const [name, def] of this.definitions) {
1715
+ const paramsStr = def.params?.length ? `(${def.params.join(', ')})` : '';
1716
+ const bodyStr = (0, format_1.formulaToUnicode)(def.body);
1717
+ this.emit(` ${name}${paramsStr} := ${bodyStr}`);
1718
+ if (def.description) {
1719
+ this.emit(` "${def.description}"`);
1720
+ }
1721
+ }
1722
+ }
1723
+ // Also show sources if any
1724
+ if (this.sources.size > 0) {
1725
+ this.emit('');
1726
+ this.emit('── Fuentes ──');
1727
+ for (const [, src] of this.sources) {
1728
+ const yearStr = src.year ? ` (${src.year})` : '';
1729
+ this.emit(` ${src.id}: ${src.author ?? ''}${yearStr} — ${src.work ?? ''}`);
1730
+ }
1731
+ }
1732
+ // Show interpretations if any
1733
+ if (this.textLayer.interpretations.size > 0) {
1734
+ this.emit('');
1735
+ this.emit('── Interpretaciones ──');
1736
+ for (const [, interp] of this.textLayer.interpretations) {
1737
+ this.emit(` "${interp.text}" → ${(0, format_1.formulaToUnicode)(interp.formula)}`);
1738
+ }
1739
+ }
1740
+ this.emit('══════════════════════════════════════');
1741
+ this.emit('');
1742
+ }
1743
+ // ── End v3 ─────────────────────────────────────────────────
1344
1744
  executeFnCall(stmt) {
1345
1745
  // ── Memoización: verificar cache antes de ejecutar ──
1346
1746
  const evaluatedArgs = stmt.args.map((a) => this.evaluateFormulaValue(a));