novac 2.2.0 → 2.2.2

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 (122) hide show
  1. package/LICENSE +0 -0
  2. package/README.md +0 -0
  3. package/bin/novac +6 -3
  4. package/bin/nvc +0 -0
  5. package/bin/nvml +0 -0
  6. package/demo.nv +0 -0
  7. package/demo_builtins.nv +0 -0
  8. package/demo_http.nv +0 -0
  9. package/examples/bf.nv +5 -13
  10. package/examples/math.nv +2 -2
  11. package/kits/kitffmpeg/kitdef.js +1174 -0
  12. package/kits/libos/kitdef.js +3135 -0
  13. package/kits/libtasker/kitdef.js +125 -0
  14. package/package.json +1 -1
  15. package/scripts/update-bin.js +0 -0
  16. package/src/core/executor.js +7 -4
  17. package/src/core/lexer.js +2 -2
  18. package/src/index.js +0 -0
  19. package/novac/LICENSE +0 -21
  20. package/novac/README.md +0 -1823
  21. package/novac/bin/novac +0 -950
  22. package/novac/bin/nvc +0 -522
  23. package/novac/bin/nvml +0 -542
  24. package/novac/demo.nv +0 -245
  25. package/novac/demo_builtins.nv +0 -209
  26. package/novac/demo_http.nv +0 -62
  27. package/novac/examples/bf.nv +0 -69
  28. package/novac/examples/math.nv +0 -21
  29. package/novac/kits/kitai/kitdef.js +0 -2185
  30. package/novac/kits/kitansi/kitdef.js +0 -1402
  31. package/novac/kits/kitformat/kitdef.js +0 -1485
  32. package/novac/kits/kitgps/kitdef.js +0 -1862
  33. package/novac/kits/kitlibfs/kitdef.js +0 -231
  34. package/novac/kits/kitlibproc/kitdef.js +0 -78
  35. package/novac/kits/kitmatrix/ex.js +0 -19
  36. package/novac/kits/kitmatrix/kitdef.js +0 -960
  37. package/novac/kits/kitmpatch/kitdef.js +0 -906
  38. package/novac/kits/kitnovacweb/README.md +0 -1572
  39. package/novac/kits/kitnovacweb/demo.nv +0 -12
  40. package/novac/kits/kitnovacweb/demo.nvml +0 -71
  41. package/novac/kits/kitnovacweb/index.nova +0 -12
  42. package/novac/kits/kitnovacweb/kitdef.js +0 -692
  43. package/novac/kits/kitnovacweb/nova.kit.json +0 -8
  44. package/novac/kits/kitnovacweb/nvml/executor.js +0 -739
  45. package/novac/kits/kitnovacweb/nvml/index.js +0 -67
  46. package/novac/kits/kitnovacweb/nvml/lexer.js +0 -263
  47. package/novac/kits/kitnovacweb/nvml/parser.js +0 -508
  48. package/novac/kits/kitnovacweb/nvml/renderer.js +0 -924
  49. package/novac/kits/kitparse/kitdef.js +0 -1688
  50. package/novac/kits/kitregex++/kitdef.js +0 -1353
  51. package/novac/kits/kitrequire/kitdef.js +0 -1599
  52. package/novac/kits/kitx11/kitdef.js +0 -1
  53. package/novac/kits/kitx11/kitx11.js +0 -2472
  54. package/novac/kits/kitx11/kitx11_conn.js +0 -948
  55. package/novac/kits/kitx11/kitx11_worker.js +0 -121
  56. package/novac/kits/libtea/tf.js +0 -2691
  57. package/novac/kits/libterm/ex.js +0 -285
  58. package/novac/kits/libterm/kitdef.js +0 -1927
  59. package/novac/node_modules/chalk/license +0 -9
  60. package/novac/node_modules/chalk/package.json +0 -83
  61. package/novac/node_modules/chalk/readme.md +0 -297
  62. package/novac/node_modules/chalk/source/index.d.ts +0 -325
  63. package/novac/node_modules/chalk/source/index.js +0 -225
  64. package/novac/node_modules/chalk/source/utilities.js +0 -33
  65. package/novac/node_modules/chalk/source/vendor/ansi-styles/index.d.ts +0 -236
  66. package/novac/node_modules/chalk/source/vendor/ansi-styles/index.js +0 -223
  67. package/novac/node_modules/chalk/source/vendor/supports-color/browser.d.ts +0 -1
  68. package/novac/node_modules/chalk/source/vendor/supports-color/browser.js +0 -34
  69. package/novac/node_modules/chalk/source/vendor/supports-color/index.d.ts +0 -55
  70. package/novac/node_modules/chalk/source/vendor/supports-color/index.js +0 -190
  71. package/novac/node_modules/commander/LICENSE +0 -22
  72. package/novac/node_modules/commander/Readme.md +0 -1176
  73. package/novac/node_modules/commander/esm.mjs +0 -16
  74. package/novac/node_modules/commander/index.js +0 -24
  75. package/novac/node_modules/commander/lib/argument.js +0 -150
  76. package/novac/node_modules/commander/lib/command.js +0 -2777
  77. package/novac/node_modules/commander/lib/error.js +0 -39
  78. package/novac/node_modules/commander/lib/help.js +0 -747
  79. package/novac/node_modules/commander/lib/option.js +0 -380
  80. package/novac/node_modules/commander/lib/suggestSimilar.js +0 -101
  81. package/novac/node_modules/commander/package-support.json +0 -19
  82. package/novac/node_modules/commander/package.json +0 -82
  83. package/novac/node_modules/commander/typings/esm.d.mts +0 -3
  84. package/novac/node_modules/commander/typings/index.d.ts +0 -1113
  85. package/novac/node_modules/node-addon-api/LICENSE.md +0 -9
  86. package/novac/node_modules/node-addon-api/README.md +0 -95
  87. package/novac/node_modules/node-addon-api/common.gypi +0 -21
  88. package/novac/node_modules/node-addon-api/except.gypi +0 -25
  89. package/novac/node_modules/node-addon-api/index.js +0 -14
  90. package/novac/node_modules/node-addon-api/napi-inl.deprecated.h +0 -186
  91. package/novac/node_modules/node-addon-api/napi-inl.h +0 -7165
  92. package/novac/node_modules/node-addon-api/napi.h +0 -3364
  93. package/novac/node_modules/node-addon-api/node_addon_api.gyp +0 -42
  94. package/novac/node_modules/node-addon-api/node_api.gyp +0 -9
  95. package/novac/node_modules/node-addon-api/noexcept.gypi +0 -26
  96. package/novac/node_modules/node-addon-api/nothing.c +0 -0
  97. package/novac/node_modules/node-addon-api/package-support.json +0 -21
  98. package/novac/node_modules/node-addon-api/package.json +0 -480
  99. package/novac/node_modules/node-addon-api/tools/README.md +0 -73
  100. package/novac/node_modules/node-addon-api/tools/check-napi.js +0 -99
  101. package/novac/node_modules/node-addon-api/tools/clang-format.js +0 -71
  102. package/novac/node_modules/node-addon-api/tools/conversion.js +0 -301
  103. package/novac/node_modules/serialize-javascript/LICENSE +0 -27
  104. package/novac/node_modules/serialize-javascript/README.md +0 -149
  105. package/novac/node_modules/serialize-javascript/index.js +0 -297
  106. package/novac/node_modules/serialize-javascript/package.json +0 -33
  107. package/novac/package.json +0 -27
  108. package/novac/scripts/update-bin.js +0 -24
  109. package/novac/src/core/bstd.js +0 -1035
  110. package/novac/src/core/config.js +0 -155
  111. package/novac/src/core/describe.js +0 -187
  112. package/novac/src/core/emitter.js +0 -499
  113. package/novac/src/core/error.js +0 -86
  114. package/novac/src/core/executor.js +0 -5606
  115. package/novac/src/core/formatter.js +0 -686
  116. package/novac/src/core/lexer.js +0 -1026
  117. package/novac/src/core/nova_builtins.js +0 -717
  118. package/novac/src/core/nova_thread_worker.js +0 -166
  119. package/novac/src/core/parser.js +0 -2181
  120. package/novac/src/core/types.js +0 -112
  121. package/novac/src/index.js +0 -28
  122. package/novac/src/runtime/stdlib.js +0 -244
@@ -1,686 +0,0 @@
1
- /**
2
- * Nova Formatter
3
- * Converts AST back to formatted source code
4
- */
5
-
6
- const { Parser } = require('./parser');
7
-
8
- class Formatter {
9
- constructor(source) {
10
- this.source = source;
11
- this.indentLevel = 0;
12
- this.indentStr = ' '; // 2 spaces
13
- }
14
-
15
- format() {
16
- try {
17
- const parser = new Parser(this.source);
18
- const ast = parser.parse();
19
- return this.formatProgram(ast);
20
- } catch (e) {
21
- // If parsing fails, return original source
22
- return this.source;
23
- }
24
- }
25
-
26
- indent() {
27
- return this.indentStr.repeat(this.indentLevel);
28
- }
29
-
30
- // ══════════════════════════ PROGRAM ══════════════════════════
31
-
32
- formatProgram(node) {
33
- if (!node || !node.nodes) return '';
34
- return node.nodes.map(n => this.formatStatement(n)).filter(x => x).join('\n\n');
35
- }
36
-
37
- // ══════════════════════════ STATEMENTS ══════════════════════════
38
-
39
- formatStatement(node) {
40
- if (!node) return '';
41
-
42
- const ind = this.indent();
43
- switch (node.kind) {
44
- // ── type declarations ──
45
- case 'type_decl':
46
- return ind + `type ${node.name}${this.formatTypeParams(node.params)} = ${this.formatTypeExpr(node.def)};`;
47
-
48
- case 'struct_decl':
49
- return ind + `struct ${node.name}${this.formatTypeParams(node.params)} {` +
50
- (node.fields.length > 0 ? '\n' + node.fields.map((f, i) =>
51
- this.indent() + this.indentStr + `${f.name}: ${this.formatTypeExpr(f.type)}${f.defaultValue ? ' = ' + this.formatExpr(f.defaultValue) : ''}${i < node.fields.length - 1 ? ',' : ''}`
52
- ).join('\n') + '\n' + ind : '') + `}`;
53
-
54
- case 'interface_decl':
55
- return ind + `interface ${node.name}${this.formatTypeParams(node.params)}${node.extends && node.extends.length ? ' extends ' + node.extends.join(', ') : ''} {` +
56
- (node.members.length > 0 ? '\n' + node.members.map((m, i) =>
57
- this.indent() + this.indentStr + `${m.name}${m.isOptional ? '?' : ''}${m.isMethod ? '(' + m.params.map(p => p.name + (p.type ? ': ' + this.formatTypeExpr(p.type) : '')).join(', ') + ')' + (m.returnType ? ': ' + this.formatTypeExpr(m.returnType) : '') : m.returnType ? ': ' + this.formatTypeExpr(m.returnType) : ''}${i < node.members.length - 1 ? ',' : ''}`
58
- ).join('\n') + '\n' + ind : '') + `}`;
59
-
60
- case 'enum_decl':
61
- return ind + `enum ${node.name} {` +
62
- (node.variants.length > 0 ? '\n' + node.variants.map((v, i) =>
63
- this.indent() + this.indentStr + `${v.name}${v.value ? (v.value.kind === 'tuple' ? '(' + v.value.types.map(t => this.formatTypeExpr(t)).join(', ') + ')' : ' = ' + this.formatExpr(v.value)) : ''}${i < node.variants.length - 1 ? ',' : ''}`
64
- ).join('\n') + '\n' + ind : '') + `}`;
65
-
66
- case 'trait_decl':
67
- return ind + `trait ${node.name}${this.formatTypeParams(node.params)} {` +
68
- (node.methods.length > 0 ? '\n' + node.methods.map(m =>
69
- this.indent() + this.indentStr + `${m.name}(${m.args.map(a => this.formatFuncArg(a)).join(', ')}) {${m.body.length > 0 ? '\n' + this.formatBody(m.body) + '\n' + this.indent() + this.indentStr : ''}}`
70
- ).join('\n') + '\n' + ind : '') + `}`;
71
-
72
- case 'impl_decl':
73
- return ind + `impl ${node.trait}${node.for ? ' for ' + node.for : ''} {` +
74
- (node.methods.length > 0 ? '\n' + node.methods.map(m =>
75
- this.indent() + this.indentStr + `${m.name}(${m.args.map(a => this.formatFuncArg(a)).join(', ')}) {${m.body.length > 0 ? '\n' + this.formatBody(m.body) + '\n' + this.indent() + this.indentStr : ''}}`
76
- ).join('\n') + '\n' + ind : '') + `}`;
77
-
78
- // ── variables ──
79
- case 'declare': {
80
- const prefix = node.isConst ? 'const' : 'let';
81
- if (node.destructure) {
82
- const destr = node.destructure.kind === 'objpattern'
83
- ? '{' + node.destructure.props.map(p => p.key + (p.alias !== p.key ? ': ' + p.alias : '') + (p.defaultValue ? ' = ' + this.formatExpr(p.defaultValue) : '')).join(', ') + '}'
84
- : '[' + node.destructure.elements.map(e => (e.rest ? '...' : '') + e.name + (e.defaultValue ? ' = ' + this.formatExpr(e.defaultValue) : '')).join(', ') + ']';
85
- return ind + `${prefix} ${node.isPointer ? '*' : ''}${destr}${node.value ? ' = ' + this.formatExpr(node.value) : ''};`;
86
- }
87
- return ind + `${prefix} ${node.isPointer ? '*' : ''}${node.name}${node.explicitType ? ': ' + this.formatTypeExpr(node.explicitType) : ''}${node.value ? ' = ' + this.formatExpr(node.value) : ''};`;
88
- }
89
-
90
- // ── functions ──
91
- case 'function':
92
- return ind + `function ${node.name}(${node.args.map(a => this.formatFuncArg(a)).join(', ')})${node.returnType ? ': ' + this.formatTypeExpr(node.returnType) : ''} {` +
93
- (node.body.length > 0 ? '\n' + this.formatBody(node.body) + '\n' + ind : '') + `}`;
94
-
95
- // ── classes ──
96
- case 'class':
97
- return ind + `class ${node.name}${node.superClass ? ' extends ' + this.formatExpr(node.superClass) : ''}${node.impls && node.impls.length ? ' implements ' + node.impls.join(', ') : ''} {` +
98
- (node.members.length > 0 ? '\n' + node.members.map(m => {
99
- const mind = this.indent() + this.indentStr;
100
- if (m.kind === 'declare') return mind + `${m.name}: ${this.formatExpr(m.value)}`;
101
- if (m.kind === 'function') {
102
- return mind + (m.accessor ? m.accessor + ' ' : '') + `${m.name}(${m.args.map(a => this.formatFuncArg(a)).join(', ')})${m.returnType ? ': ' + this.formatTypeExpr(m.returnType) : ''} {` +
103
- (m.body.length > 0 ? '\n' + this.formatBody(m.body, this.indentLevel + 2) + '\n' + mind : '') + `}`;
104
- }
105
- return mind + this.formatStatement(m);
106
- }).join('\n') + '\n' + ind : '') + `}`;
107
-
108
- // ── control flow ──
109
- case 'branch':
110
- return this.formatBranch(node, ind);
111
-
112
- case 'for_of':
113
- return ind + `for (${node.varName} of ${this.formatExpr(node.iterable)}) {` +
114
- (node.body.length > 0 ? '\n' + this.formatBody(node.body) + '\n' + ind : '') + `}`;
115
-
116
- case 'for_in':
117
- return ind + `for (${node.varName} in ${this.formatExpr(node.object)}) {` +
118
- (node.body.length > 0 ? '\n' + this.formatBody(node.body) + '\n' + ind : '') + `}`;
119
-
120
- case 'each':
121
- return ind + `each ${node.varName}${node.indexName ? ', ' + node.indexName : ''} of ${this.formatExpr(node.iterable)} {` +
122
- (node.body.length > 0 ? '\n' + this.formatBody(node.body) + '\n' + ind : '') + `}`;
123
-
124
- case 'switch':
125
- return ind + `switch (${this.formatExpr(node.subject)}) {` +
126
- (node.cases.length > 0 ? '\n' + node.cases.map(c => {
127
- const mind = this.indent() + this.indentStr;
128
- if (c.kind === 'default_case') return mind + `default:` + (c.body.length > 0 ? '\n' + this.formatBody(c.body, this.indentLevel + 2) : '');
129
- return mind + `case ${this.formatExpr(c.value)}:` + (c.body.length > 0 ? '\n' + this.formatBody(c.body, this.indentLevel + 2) : '');
130
- }).join('\n') + '\n' + ind : '') + `}`;
131
-
132
- case 'match':
133
- return ind + `match (${this.formatExpr(node.subject)}) {` +
134
- (node.cases.length > 0 ? '\n' + node.cases.map(c => {
135
- const mind = this.indent() + this.indentStr;
136
- if (c.kind === 'default_when') return mind + `default {` + (c.body.length > 0 ? '\n' + this.formatBody(c.body, this.indentLevel + 2) + '\n' + mind : '') + `}`;
137
- return mind + `when ${c.patterns.map(p => this.formatExpr(p)).join(', ')}${c.guard ? ' where ' + this.formatExpr(c.guard) : ''} {` +
138
- (c.body.length > 0 ? '\n' + this.formatBody(c.body, this.indentLevel + 2) + '\n' + mind : '') + `}`;
139
- }).join('\n') + '\n' + ind : '') + `}`;
140
-
141
- case 'try':
142
- return ind + `try {` + (node.tryBody.length > 0 ? '\n' + this.formatBody(node.tryBody) + '\n' + ind : '') + `}` +
143
- (node.catchBody ? ' catch' + (node.catchName ? `(${node.catchName})` : '') + ` {` +
144
- (node.catchBody.length > 0 ? '\n' + this.formatBody(node.catchBody) + '\n' + ind : '') + `}` : '') +
145
- (node.finallyBody ? ' finally {' + (node.finallyBody.length > 0 ? '\n' + this.formatBody(node.finallyBody) + '\n' + ind : '') + `}` : '');
146
-
147
- case 'return':
148
- return ind + `return${node.value ? ' ' + this.formatExpr(node.value) : ''};`;
149
-
150
- case 'break':
151
- return ind + `break;`;
152
-
153
- case 'continue':
154
- return ind + `continue;`;
155
-
156
- case 'throw':
157
- return ind + `throw ${this.formatExpr(node.value)};`;
158
-
159
- case 'assert':
160
- return ind + `assert ${this.formatExpr(node.condition)}${node.message ? ', ' + this.formatExpr(node.message) : ''};`;
161
-
162
- case 'emit_event':
163
- return ind + `emit ${this.formatExpr(node.event)}${node.value ? ', ' + this.formatExpr(node.value) : ''};`;
164
-
165
- case 'on_event':
166
- return ind + `on ${this.formatExpr(node.event)}${node.param ? `(${node.param})` : ''} {` +
167
- (node.body.length > 0 ? '\n' + this.formatBody(node.body) + '\n' + ind : '') + `}`;
168
-
169
- case 'where':
170
- return ind + `where (${node.bindings.map(b => `${b.name} = ${this.formatExpr(b.value)}`).join(', ')}) {` +
171
- (node.body.length > 0 ? '\n' + this.formatBody(node.body) + '\n' + ind : '') + `}`;
172
-
173
- case 'exec':
174
- return ind + `${this.formatExpr(node.expr)};`;
175
-
176
- // ── Nova Classic statements ──
177
- case 'foreach':
178
- return ind + `foreach (${this.formatExpr(node.iterable)}) (${node.vars.join(', ')}) {` +
179
- (node.body.length > 0 ? '\n' + this.formatBody(node.body) + '\n' + ind : '') + `}`;
180
-
181
- case 'temp':
182
- return ind + `temp ${node.name} = ${this.formatExpr(node.value)} => {` +
183
- (node.body.length > 0 ? '\n' + this.formatBody(node.body) + '\n' + ind : '') + `}`;
184
-
185
- case 'keep':
186
- return ind + `keep ${node.name} = ${this.formatExpr(node.value)};`;
187
-
188
- case 'echo':
189
- return ind + `echo ${this.formatExpr(node.value)};`;
190
-
191
- case 'gear_decl':
192
- return ind + `gear${node.wait && node.wait.value !== 0 ? `(${this.formatExpr(node.wait)})` : ''} ${node.name} {` +
193
- (node.body.length > 0 ? '\n' + this.formatBody(node.body) + '\n' + ind : '') + `}`;
194
-
195
- case 'engage':
196
- return ind + `engage ${node.gears.join(' >> ')};`;
197
-
198
- case 'sandbox':
199
- return ind + `sandbox {${node.code ? ' ' + node.code + ' ' : ''}}`;
200
-
201
- case 'infer':
202
- return ind + `infer(${this.formatExpr(node.model)}) => ${node.varName}: ${this.formatExpr(node.prompt)};`;
203
-
204
- case 'addto':
205
- return ind + `addto ${node.name} ${this.formatExpr(node.value)}${node.key ? ': ' + this.formatExpr(node.key) : ''};`;
206
-
207
- case 'macro_decl':
208
- return ind + `macro ${node.name} = ${this.formatExpr(node.value)};`;
209
-
210
- case 'block_decl':
211
- return ind + `block ${node.name} {` +
212
- (node.body.length > 0 ? '\n' + this.formatBody(node.body) + '\n' + ind : '') + `}`;
213
-
214
- case 'snippet_decl':
215
- return ind + `snippet ${node.name} {` +
216
- (node.body.length > 0 ? '\n' + this.formatBody(node.body) + '\n' + ind : '') + `}`;
217
-
218
- case 'defunc_decl':
219
- return ind + `defunc ${node.name}(${node.args.map(a => this.formatFuncArg(a)).join(', ')}) => {` +
220
- (node.body.length > 0 ? '\n' + this.formatBody(node.body) + '\n' + ind : '') + `}`;
221
-
222
- case 'lambda_decl':
223
- return ind + `lambda ${node.name} = ${this.formatExpr(node.fn)};`;
224
-
225
- case 'compose_decl':
226
- return ind + `compose ${node.name} = ${node.fns.map(f => this.formatExpr(f)).join(' >> ')};`;
227
-
228
- case 'partial_decl':
229
- return ind + `partial ${node.name} = ${this.formatExpr(node.callee)};`;
230
-
231
- case 'backup_val':
232
- return ind + `backup ${node.name} = ${this.formatExpr(node.value)};`;
233
-
234
- case 'retrieve_val':
235
- return ind + `retrieve ${node.name};`;
236
-
237
- case 'describe':
238
- return ind + `describe ${this.formatExpr(node.text)};`;
239
-
240
- case 'using_flag':
241
- return ind + `using ${node.flag};`;
242
-
243
- case 'unuse_flag':
244
- return ind + `unuse ${node.flag};`;
245
-
246
- case 'classify':
247
- return ind + `classify ${this.formatExpr(node.value)}${node.targetType ? ' as ' + this.formatTypeExpr(node.targetType) : ''};`;
248
-
249
- case 'rate_cast':
250
- return ind + `rate(${this.formatExpr(node.value)}) ${node.cast_type};`;
251
-
252
- // ── Nova Classic (ported) ──
253
- case 'guard':
254
- return ind + `guard (${this.formatExpr(node.cond)}) {` + (node.body.length > 0 ? '\n' + this.formatBody(node.body) + '\n' + ind : '') + `}` +
255
- (node.elseBody ? ` else {` + (node.elseBody.length > 0 ? '\n' + this.formatBody(node.elseBody, this.indentLevel + 1) + '\n' + ind : '') + `}` : '');
256
-
257
- case 'when_stmt':
258
- return ind + `when ${this.formatExpr(node.cond)} do {` +
259
- (node.body.length > 0 ? '\n' + this.formatBody(node.body) + '\n' + ind : '') + `}`;
260
-
261
- case 'with_ctx':
262
- return ind + `with (${this.formatExpr(node.target)}) {` +
263
- (node.body.length > 0 ? '\n' + this.formatBody(node.body) + '\n' + ind : '') + `}`;
264
-
265
- case 'with_option':
266
- return ind + `with option ${node.flag} {` +
267
- (node.body.length > 0 ? '\n' + this.formatBody(node.body) + '\n' + ind : '') + `}`;
268
-
269
- case 'loop_in':
270
- return ind + `loop ${node.varName} in ${this.formatExpr(node.iterable)} {` +
271
- (node.body.length > 0 ? '\n' + this.formatBody(node.body) + '\n' + ind : '') + `}`;
272
-
273
- case 'wait_stmt':
274
- return ind + `wait(${this.formatExpr(node.ms)});`;
275
-
276
- case 'lend_fn':
277
- return ind + `lend fn ${node.source} to ${node.target};`;
278
-
279
- case 'lend_m':
280
- return ind + `lend m ${node.mapName} with ${node.funcName};`;
281
-
282
- case 'sstream_decl':
283
- return ind + `sstream ${node.name} => {` +
284
- (node.body.length > 0 ? '\n' + this.formatBody(node.body) + '\n' + ind : '') + `}`;
285
-
286
- case 'declare_stmt':
287
- return ind + `declare (${this.formatExpr(node.value)}) ${node.mode} ${node.name}${node.flags.length > 0 ? ' ' + node.flags.join(' ') : ''};`;
288
-
289
- case 'session_decl':
290
- return ind + `session (${this.formatExpr(node.name)}) { ${node.body} }`;
291
-
292
- case 'enter_stmt':
293
- return ind + `enter ${node.key} ${node.type};`;
294
-
295
- case 'namespace_decl':
296
- return ind + `namespace ${this.formatExpr(node.path)};`;
297
-
298
- case 'resu_decl':
299
- return ind + `resu ${node.name}(${node.params.join(', ')}) => { ${node.body} },`;
300
-
301
- case 'warn_stmt':
302
- return ind + `warn ${this.formatExpr(node.msg)};`;
303
-
304
- case 'info_stmt':
305
- return ind + `info ${this.formatExpr(node.msg)};`;
306
-
307
- case 'time_block':
308
- return ind + `time {` +
309
- (node.body.length > 0 ? '\n' + this.formatBody(node.body) + '\n' + ind : '') + `}`;
310
-
311
- case 'keyfunc_decl':
312
- return ind + `keyfunc ${node.name}(${node.params.join(', ')}) { ${node.matchBody} } { ${node.logic} }`;
313
-
314
- case 'print_stmt':
315
- return ind + `print(${node.args.map(a => this.formatExpr(a)).join(', ')});`;
316
-
317
- case 'log_stmt':
318
- return ind + `log(${node.args.map(a => this.formatExpr(a)).join(', ')});`;
319
-
320
- case 'println_stmt':
321
- return ind + `println(${this.formatExpr(node.value)});`;
322
-
323
- case 'logln_stmt':
324
- return ind + `logln(${this.formatExpr(node.value)});`;
325
-
326
- case 'banner_stmt':
327
- return ind + `banner${node.args.length > 0 ? '(' + node.args.map(a => this.formatExpr(a)).join(', ') + ')' : ''};`;
328
-
329
- case 'readfile_stmt':
330
- return ind + `readFile ${node.varName} = (${this.formatExpr(node.path)});`;
331
-
332
- case 'execfile_stmt':
333
- return ind + `execFile(${this.formatExpr(node.path)});`;
334
-
335
- case 'createfile_stmt':
336
- return ind + `createFile(${this.formatExpr(node.path)}, ${this.formatExpr(node.content)});`;
337
-
338
- case 'deletefile_stmt':
339
- return ind + `deleteFile(${this.formatExpr(node.path)});`;
340
-
341
- case 'listfiles_stmt':
342
- return ind + `listFiles(${this.formatExpr(node.dir)})${node.varName ? ' => ' + node.varName : ''};`;
343
-
344
- case 'term_stmt':
345
- return ind + `term(${this.formatExpr(node.cmd)}) ${node.shell};`;
346
-
347
- case 'sh_stmt':
348
- return ind + `sh { ${node.code} }`;
349
-
350
- case 'exec_stmt':
351
- return ind + `exec(${this.formatExpr(node.code)});`;
352
-
353
- case 'notify_stmt':
354
- return ind + `notify(${this.formatExpr(node.title)}${node.content ? ', ' + this.formatExpr(node.content) : ''});`;
355
-
356
- case 'toast_stmt':
357
- return ind + `toast(${this.formatExpr(node.msg)});`;
358
-
359
- case 'vibrate_stmt':
360
- return ind + `vibrate(${this.formatExpr(node.ms)});`;
361
-
362
- case 'clipboard_stmt':
363
- return ind + `clipboard(${this.formatExpr(node.text)});`;
364
-
365
- case 'camera_stmt':
366
- return ind + `camera(${this.formatExpr(node.path)});`;
367
-
368
- case 'share_stmt':
369
- return ind + `share(${this.formatExpr(node.path)});`;
370
-
371
- case 'open_stmt':
372
- return ind + `open(${this.formatExpr(node.path)});`;
373
-
374
- case 'sysinfo_stmt':
375
- return ind + `${node.info}${node.varName ? ' => ' + node.varName : ''};`;
376
-
377
- case 'path_stmt':
378
- return ind + `path${node.sub}(${this.formatExpr(node.target)});`;
379
-
380
- case 'crypto_stmt':
381
- return ind + `${node.fn}(${this.formatExpr(node.arg)})${node.varName ? ' => ' + node.varName : ''};`;
382
-
383
- case 'parseurl_stmt':
384
- return ind + `parseURL(${this.formatExpr(node.url)})${node.varName ? ' => ' + node.varName : ''};`;
385
-
386
- case 'exists_stmt':
387
- return ind + `exists(${this.formatExpr(node.path)})${node.varName ? ' => ' + node.varName : ''};`;
388
-
389
- case 'expt_stmt':
390
- return ind + `expt ${node.expected} from {` +
391
- (node.body.length > 0 ? '\n' + this.formatBody(node.body) + '\n' + ind : '') + `}`;
392
-
393
- case 'option_stmt':
394
- return ind + `option ${node.name} = ${this.formatExpr(node.value)};`;
395
-
396
- case 'env':
397
- return ind + `env ${node.varName};`;
398
-
399
- case 'hello':
400
- return ind + `hello ${node.args.map(a => this.formatExpr(a)).join(', ')};`;
401
-
402
- case 'eval':
403
- return ind + `eval ${this.formatStatement(node.code)};`;
404
-
405
- case 'import':
406
- return ind + `import ${this.formatExpr(node.source)}${node.names && node.names.length ? ' as ' + node.names.join(', ') : ''};`;
407
-
408
- case 'import_builtin':
409
- return ind + `import_builtin ${node.names.join(', ')};`;
410
-
411
- case 'from_import':
412
- return ind + `from ${this.formatExpr(node.source)} import ${node.names.join(', ')};`;
413
-
414
- case 'export':
415
- return ind + `export ${node.value ? this.formatExpr(node.value) : ''};`;
416
-
417
- case 'default_export':
418
- return ind + `export default ${node.value ? this.formatExpr(node.value) : ''};`;
419
-
420
- case 'namespace':
421
- return ind + `namespace ${node.name} {` +
422
- (node.body.length > 0 ? '\n' + this.formatBody(node.body) + '\n' + ind : '') + `}`;
423
-
424
- case 'server_decl':
425
- return ind + `server(${this.formatExpr(node.port)}) {` +
426
- (node.routes.length > 0 ? '\n' + node.routes.map(r =>
427
- this.indent() + this.indentStr + `${r.method} ${this.formatExpr(r.path)}${r.params.length > 0 ? '(' + r.params.join(', ') + ')' : ''} {` +
428
- (r.body.length > 0 ? '\n' + this.formatBody(r.body, this.indentLevel + 2) + '\n' + this.indent() + this.indentStr : '') + `}`
429
- ).join('\n') + '\n' + ind : '') + `}`;
430
-
431
- case 'fetch_stmt':
432
- return ind + `fetch(${this.formatExpr(node.url)}${node.options ? ', ' + this.formatExpr(node.options) : ''})${node.varName ? ' => ' + node.varName : ''};`;
433
-
434
- case 'skip':
435
- return ind + `skip;`;
436
-
437
- case 'end_stmt':
438
- return ind + `end;`;
439
-
440
- case 'clear_env':
441
- return ind + `clear;`;
442
-
443
- case 'exec_comment':
444
- return ind + `/?/${node.code}`;
445
-
446
- default:
447
- return ind + `/* unknown node kind: ${node.kind} */`;
448
- }
449
- }
450
-
451
- formatBranch(node, ind) {
452
- let result = '';
453
- let current = node;
454
- while (current) {
455
- switch (current.type) {
456
- case 'if': {
457
- result += ind + `if (${this.formatExpr(current.args)}) {` +
458
- (current.body.length > 0 ? '\n' + this.formatBody(current.body) + '\n' + ind : '') + `}`;
459
- current = current.next;
460
- if (current) result += ' ';
461
- break;
462
- }
463
- case 'else': {
464
- result += `else {` + (current.body.length > 0 ? '\n' + this.formatBody(current.body) + '\n' + ind : '') + `}`;
465
- current = current.next;
466
- break;
467
- }
468
- case 'while': {
469
- const c = Array.isArray(current.args) ? current.args[0] : current.args;
470
- result += ind + `while (${this.formatExpr(c)}) {` +
471
- (current.body.length > 0 ? '\n' + this.formatBody(current.body) + '\n' + ind : '') + `}`;
472
- current = current.next;
473
- break;
474
- }
475
- case 'until': {
476
- const c = Array.isArray(current.args) ? current.args[0] : current.args;
477
- result += ind + `until (${this.formatExpr(c)}) {` +
478
- (current.body.length > 0 ? '\n' + this.formatBody(current.body) + '\n' + ind : '') + `}`;
479
- current = current.next;
480
- break;
481
- }
482
- case 'unless': {
483
- result += ind + `unless (${this.formatExpr(current.args)}) {` +
484
- (current.body.length > 0 ? '\n' + this.formatBody(current.body) + '\n' + ind : '') + `}`;
485
- current = current.next;
486
- break;
487
- }
488
- case 'do': {
489
- const c = Array.isArray(current.args) ? current.args[0] : current.args;
490
- result += ind + `do {` + (current.body.length > 0 ? '\n' + this.formatBody(current.body) + '\n' + ind : '') + `} while (${this.formatExpr(c)})`;
491
- current = current.next;
492
- break;
493
- }
494
- case 'repeat': {
495
- const t = Array.isArray(current.args) ? current.args[0] : current.args;
496
- result += ind + `repeat (${this.formatExpr(t)}) {` +
497
- (current.body.length > 0 ? '\n' + this.formatBody(current.body) + '\n' + ind : '') + `}`;
498
- current = current.next;
499
- break;
500
- }
501
- case 'for': {
502
- const [init, cond, upd] = current.args;
503
- result += ind + `for (${this.formatStatement(init)}${cond ? ' ' + this.formatExpr(cond) : ''}; ${upd ? this.formatStatement(upd) : ''}) {` +
504
- (current.body.length > 0 ? '\n' + this.formatBody(current.body) + '\n' + ind : '') + `}`;
505
- current = current.next;
506
- break;
507
- }
508
- default:
509
- current = null;
510
- }
511
- }
512
- return result;
513
- }
514
-
515
- formatBody(body, indentLevel) {
516
- const prevIndent = this.indentLevel;
517
- this.indentLevel = indentLevel !== undefined ? indentLevel : this.indentLevel + 1;
518
- const result = body.map(stmt => this.formatStatement(stmt)).filter(x => x).join('\n');
519
- this.indentLevel = prevIndent;
520
- return result;
521
- }
522
-
523
- // ══════════════════════════ EXPRESSIONS ══════════════════════════
524
-
525
- formatExpr(node) {
526
- if (!node) return '';
527
-
528
- switch (node.kind) {
529
- case 'EOF':
530
- return '';
531
-
532
- case 'value': {
533
- const v = node.value;
534
- if (typeof v === 'string') return JSON.stringify(v);
535
- if (typeof v === 'number') return String(v);
536
- if (typeof v === 'symbol') {
537
- const s = v.toString();
538
- if (s === 'Symbol(NOVA_TRUE)') return 'true';
539
- if (s === 'Symbol(NOVA_FALSE)') return 'false';
540
- if (s === 'Symbol(NOVA_NULL)') return 'null';
541
- }
542
- return String(v);
543
- }
544
-
545
- case 'ref':
546
- return node.name;
547
-
548
- case 'url_literal':
549
- return node.value;
550
-
551
- case 'array':
552
- return '[' + node.elements.map(e => this.formatExpr(e)).join(', ') + ']';
553
-
554
- case 'object':
555
- return '{' + node.props.map(p => {
556
- if (p.kind === 'spread') return '...' + this.formatExpr(p.value);
557
- if (p.kind === 'computed') return '[' + this.formatExpr(p.key) + ']: ' + this.formatExpr(p.value);
558
- const val = p.value;
559
- if (val && val.kind === 'function') return `${p.accessor ? p.accessor + ' ' : ''}${p.key}(${val.args.map(a => this.formatFuncArg(a)).join(', ')}) { ... }`;
560
- return `${p.key}: ${this.formatExpr(val)}`;
561
- }).join(', ') + '}';
562
-
563
- case 'call':
564
- return `${this.formatExpr(node.name)}(${node.args.map(a => this.formatExpr(a)).join(', ')})`;
565
-
566
- case 'prop':
567
- return `${this.formatExpr(node.object)}.${node.name}`;
568
-
569
- case 'subscript':
570
- return `${this.formatExpr(node.object)}[${this.formatExpr(node.index)}]`;
571
-
572
- case 'optional_call':
573
- return `${this.formatExpr(node.callee)}?.(${node.args.map(a => this.formatExpr(a)).join(', ')})`;
574
-
575
- case 'optional_prop':
576
- return `${this.formatExpr(node.object)}?.${node.name}`;
577
-
578
- case 'optional_subscript':
579
- return `${this.formatExpr(node.object)}?.[${this.formatExpr(node.index)}]`;
580
-
581
- case 'binary':
582
- return `${this.formatExpr(node.left)} ${node.operator} ${this.formatExpr(node.right)}`;
583
-
584
- case 'unary':
585
- return `${node.operator}${this.formatExpr(node.operand)}`;
586
-
587
- case 'prefix':
588
- return `${node.operator}${this.formatExpr(node.operand)}`;
589
-
590
- case 'postfix':
591
- return `${this.formatExpr(node.operand)}${node.operator}`;
592
-
593
- case 'ternary':
594
- return `${this.formatExpr(node.condition)} ? ${this.formatExpr(node.consequent)} : ${this.formatExpr(node.alternate)}`;
595
-
596
- case 'assign':
597
- return `${this.formatExpr(node.name)} = ${this.formatExpr(node.value)}`;
598
-
599
- case 'compound_assign':
600
- return `${this.formatExpr(node.name)} ${node.operator} ${this.formatExpr(node.value)}`;
601
-
602
- case 'fstring':
603
- return `f"${node.parts.map(p => p.kind === 'value' ? p.value : '${' + this.formatExpr(p) + '}').join('')}"`;
604
-
605
- case 'function': {
606
- const fn = node;
607
- return `function ${fn.name}(${fn.args.map(a => this.formatFuncArg(a)).join(', ')}) { ... }`;
608
- }
609
-
610
- case 'arrowfunc':
611
- return `(${node.args.join(', ')}) => { ... }`;
612
-
613
- case 'cast':
614
- return `${this.formatExpr(node.value)} as ${this.formatTypeExpr(node.type)}`;
615
-
616
- case 'new_expr':
617
- return `new ${this.formatExpr(node.callee)}`;
618
-
619
- case 'deref':
620
- return `*${this.formatExpr(node.operand)}`;
621
-
622
- case 'spread':
623
- return `...${this.formatExpr(node.value)}`;
624
-
625
- case 'await':
626
- return `await ${this.formatExpr(node.operand)}`;
627
-
628
- case 'http_request':
629
- return `${node.method} ${this.formatExpr(node.url)}(${node.args.map(a => this.formatExpr(a)).join(', ')})`;
630
-
631
- case 'fetch_expr':
632
- return `fetch(${this.formatExpr(node.url)}${node.options ? ', ' + this.formatExpr(node.options) : ''})`;
633
-
634
- case 'classify':
635
- return `classify ${this.formatExpr(node.value)}${node.targetType ? ' as ' + this.formatTypeExpr(node.targetType) : ''}`;
636
-
637
- case 'rate_cast':
638
- return `rate(${this.formatExpr(node.value)}) ${node.cast_type}`;
639
-
640
- default:
641
- return `/* unknown expr kind: ${node.kind} */`;
642
- }
643
- }
644
-
645
- formatFuncArg(arg) {
646
- if (typeof arg === 'string') return arg;
647
- return (arg.rest ? '...' : '') + arg.name + (arg.type ? ': ' + this.formatTypeExpr(arg.type) : '') +
648
- (arg.defaultValue ? ' = ' + this.formatExpr(arg.defaultValue) : '');
649
- }
650
-
651
- formatTypeExpr(type) {
652
- if (!type) return 'any';
653
- if (typeof type === 'string') return type;
654
-
655
- switch (type.kind) {
656
- case 'named_type':
657
- return type.name + (type.args && type.args.length ? '<' + type.args.map(a => this.formatTypeExpr(a)).join(', ') + '>' : '');
658
-
659
- case 'array_type':
660
- return this.formatTypeExpr(type.of) + '[]';
661
-
662
- case 'union_type':
663
- return type.variants.map(v => this.formatTypeExpr(v)).join(' | ');
664
-
665
- case 'intersect_type':
666
- return type.parts.map(p => this.formatTypeExpr(p)).join(' & ');
667
-
668
- case 'shape_type':
669
- return '{' + Object.entries(type.fields || {}).map(([k, f]) =>
670
- k + (f.optional ? '?' : '') + ': ' + this.formatTypeExpr(f.type)
671
- ).join(', ') + '}';
672
-
673
- case 'tuple':
674
- return '(' + (type.types ? type.types.map(t => this.formatTypeExpr(t)).join(', ') : '') + ')';
675
-
676
- default:
677
- return String(type);
678
- }
679
- }
680
-
681
- formatTypeParams(params) {
682
- return params && params.length ? '<' + params.join(', ') + '>' : '';
683
- }
684
- }
685
-
686
- module.exports = { Formatter };