lumos-language 1.1.2 → 2.0.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 (63) hide show
  1. package/.github/FUNDING.yml +1 -0
  2. package/.npmrc.ci-backup +3 -0
  3. package/LICENSE +0 -29
  4. package/Lumos.png +0 -0
  5. package/README.md +284 -126
  6. package/STRUCTURE.md +216 -0
  7. package/examples/hello.lumos +5 -0
  8. package/index.cjs +125 -125
  9. package/index.html +120 -274
  10. package/package.json +20 -10
  11. package/src/backends/assembly/arm.js +39 -0
  12. package/src/backends/assembly/wasm.js +39 -0
  13. package/src/backends/assembly/x86.js +39 -0
  14. package/src/backends/compiled/c.js +39 -0
  15. package/src/backends/compiled/cpp.js +39 -0
  16. package/src/backends/compiled/csharp.js +39 -0
  17. package/src/backends/compiled/go.js +39 -0
  18. package/src/backends/compiled/java.js +39 -0
  19. package/src/backends/compiled/rust.js +39 -0
  20. package/src/backends/compiled/swift.js +39 -0
  21. package/src/backends/database/mongodb.js +39 -0
  22. package/src/backends/database/mysql.js +39 -0
  23. package/src/backends/database/postgresql.js +39 -0
  24. package/src/backends/database/sql.js +39 -0
  25. package/src/backends/database/sqlite.js +39 -0
  26. package/src/backends/functional/clojure.js +39 -0
  27. package/src/backends/functional/elixir.js +39 -0
  28. package/src/backends/functional/erlang.js +39 -0
  29. package/src/backends/functional/fsharp.js +39 -0
  30. package/src/backends/functional/haskell.js +39 -0
  31. package/src/backends/functional/scala.js +39 -0
  32. package/src/backends/interpreted/lua.js +39 -0
  33. package/src/backends/interpreted/perl.js +39 -0
  34. package/src/backends/interpreted/php.js +39 -0
  35. package/src/backends/interpreted/python.js +356 -0
  36. package/src/backends/interpreted/ruby.js +222 -0
  37. package/src/backends/scripting/bash.js +39 -0
  38. package/src/backends/scripting/javascript.js +39 -0
  39. package/src/backends/scripting/powershell.js +39 -0
  40. package/src/backends/scripting/typescript.js +39 -0
  41. package/src/backends/scripting/vbscript.js +39 -0
  42. package/src/backends/specialized/ada.js +39 -0
  43. package/src/backends/specialized/cobol.js +39 -0
  44. package/src/backends/specialized/fortran.js +39 -0
  45. package/src/backends/specialized/lisp.js +39 -0
  46. package/src/backends/specialized/mlang.js +39 -0
  47. package/src/backends/specialized/prolog.js +39 -0
  48. package/src/backends/web/css.js +39 -0
  49. package/src/backends/web/html.js +39 -0
  50. package/src/backends/web/jsx.js +39 -0
  51. package/src/backends/web/vue.js +39 -0
  52. package/src/cli/fileRunner.js +82 -0
  53. package/src/cli/repl.js +244 -0
  54. package/src/compiler/core/compiler.js +1350 -0
  55. package/src/compiler/framework-integrator.js +846 -0
  56. package/src/compiler/generators/dynamic-languages.js +620 -0
  57. package/src/compiler/generators/system-languages.js +1184 -0
  58. package/src/core/compiler.js +181 -0
  59. package/src/core/evaluator.js +408 -0
  60. package/src/core/lexer.js +251 -0
  61. package/src/core/parser.js +452 -0
  62. package/src/core/runtime.js +173 -0
  63. package/tests/run-tests.js +243 -0
@@ -0,0 +1,39 @@
1
+ class Backend {
2
+ generate(ast, options = {}) {
3
+ this.output = [];
4
+ this.indent = 0;
5
+ this.generateNode(ast);
6
+ return this.output.join('\n');
7
+ }
8
+
9
+ generateNode(node) {
10
+ if (!node) return '';
11
+ switch (node.type) {
12
+ case 'Program': return this.generateProgram(node);
13
+ case 'VariableDeclaration': return this.generateVariableDeclaration(node);
14
+ case 'FunctionDeclaration': return this.generateFunctionDeclaration(node);
15
+ default: return '';
16
+ }
17
+ }
18
+
19
+ generateProgram(node) {
20
+ for (const stmt of node.statements) {
21
+ this.generateNode(stmt);
22
+ }
23
+ }
24
+
25
+ generateVariableDeclaration(node) {
26
+ const value = node.initializer ? this.generateNode(node.initializer) : 'null';
27
+ this.write(`var ${node.name} = ${value};`);
28
+ }
29
+
30
+ generateFunctionDeclaration(node) {
31
+ this.write(`function ${node.name}() {}`);
32
+ }
33
+
34
+ write(line) {
35
+ this.output.push(' '.repeat(this.indent) + line);
36
+ }
37
+ }
38
+
39
+ module.exports = new Backend();
@@ -0,0 +1,39 @@
1
+ class Backend {
2
+ generate(ast, options = {}) {
3
+ this.output = [];
4
+ this.indent = 0;
5
+ this.generateNode(ast);
6
+ return this.output.join('\n');
7
+ }
8
+
9
+ generateNode(node) {
10
+ if (!node) return '';
11
+ switch (node.type) {
12
+ case 'Program': return this.generateProgram(node);
13
+ case 'VariableDeclaration': return this.generateVariableDeclaration(node);
14
+ case 'FunctionDeclaration': return this.generateFunctionDeclaration(node);
15
+ default: return '';
16
+ }
17
+ }
18
+
19
+ generateProgram(node) {
20
+ for (const stmt of node.statements) {
21
+ this.generateNode(stmt);
22
+ }
23
+ }
24
+
25
+ generateVariableDeclaration(node) {
26
+ const value = node.initializer ? this.generateNode(node.initializer) : 'null';
27
+ this.write(`var ${node.name} = ${value};`);
28
+ }
29
+
30
+ generateFunctionDeclaration(node) {
31
+ this.write(`function ${node.name}() {}`);
32
+ }
33
+
34
+ write(line) {
35
+ this.output.push(' '.repeat(this.indent) + line);
36
+ }
37
+ }
38
+
39
+ module.exports = new Backend();
@@ -0,0 +1,356 @@
1
+ class PythonBackend {
2
+ generate(ast, options = {}) {
3
+ this.indent = 0;
4
+ this.indentStr = ' ';
5
+ this.output = [];
6
+
7
+ this.generateNode(ast);
8
+ return this.output.join('\n');
9
+ }
10
+
11
+ generateNode(node) {
12
+ if (!node) return '';
13
+
14
+ switch (node.type) {
15
+ case 'Program':
16
+ return this.generateProgram(node);
17
+ case 'VariableDeclaration':
18
+ return this.generateVariableDeclaration(node);
19
+ case 'FunctionDeclaration':
20
+ return this.generateFunctionDeclaration(node);
21
+ case 'ClassDeclaration':
22
+ return this.generateClassDeclaration(node);
23
+ case 'ImportStatement':
24
+ return this.generateImportStatement(node);
25
+ case 'TryStatement':
26
+ return this.generateTryStatement(node);
27
+ case 'IfStatement':
28
+ return this.generateIfStatement(node);
29
+ case 'WhileStatement':
30
+ return this.generateWhileStatement(node);
31
+ case 'ForStatement':
32
+ return this.generateForStatement(node);
33
+ case 'ReturnStatement':
34
+ return this.generateReturnStatement(node);
35
+ case 'Break':
36
+ return this.write('break');
37
+ case 'Continue':
38
+ return this.write('continue');
39
+ case 'ExpressionStatement':
40
+ return this.generateNode(node.expression);
41
+ case 'Assignment':
42
+ return this.generateAssignment(node);
43
+ case 'BinaryExpression':
44
+ return this.generateBinaryExpression(node);
45
+ case 'UnaryExpression':
46
+ return this.generateUnaryExpression(node);
47
+ case 'CallExpression':
48
+ return this.generateCallExpression(node);
49
+ case 'IndexExpression':
50
+ return this.generateIndexExpression(node);
51
+ case 'MemberExpression':
52
+ return this.generateMemberExpression(node);
53
+ case 'Identifier':
54
+ return node.name;
55
+ case 'Literal':
56
+ return this.generateLiteral(node.value);
57
+ case 'ArrayLiteral':
58
+ return this.generateArrayLiteral(node);
59
+ case 'ObjectLiteral':
60
+ return this.generateObjectLiteral(node);
61
+ default:
62
+ throw new Error(`Unknown node type: ${node.type}`);
63
+ }
64
+ }
65
+
66
+ generateProgram(node) {
67
+ this.write('#!/usr/bin/env python3');
68
+ this.write('');
69
+
70
+ for (const statement of node.statements) {
71
+ this.generateNode(statement);
72
+ }
73
+ }
74
+
75
+ generateVariableDeclaration(node) {
76
+ const value = node.initializer ? this.generateNode(node.initializer) : 'None';
77
+ this.write(`${node.name} = ${value}`);
78
+ }
79
+
80
+ generateFunctionDeclaration(node) {
81
+ const params = node.parameters.join(', ');
82
+ this.write(`def ${node.name}(${params}):`);
83
+ this.indent++;
84
+
85
+ if (node.body.length === 0) {
86
+ this.write('pass');
87
+ } else {
88
+ for (const statement of node.body) {
89
+ this.generateNode(statement);
90
+ }
91
+ }
92
+
93
+ this.indent--;
94
+ this.write('');
95
+ }
96
+
97
+ generateClassDeclaration(node) {
98
+ const superclass = node.superclass ? `(${node.superclass})` : '';
99
+ this.write(`class ${node.name}${superclass}:`);
100
+ this.indent++;
101
+
102
+ if (node.properties.length === 0 && node.methods.length === 0) {
103
+ this.write('pass');
104
+ } else {
105
+ this.write('def __init__(self):');
106
+ this.indent++;
107
+ for (const prop of node.properties) {
108
+ const value = prop.initializer ? this.generateNode(prop.initializer) : 'None';
109
+ this.write(`self.${prop.name} = ${value}`);
110
+ }
111
+ if (node.properties.length === 0) {
112
+ this.write('pass');
113
+ }
114
+ this.indent--;
115
+ this.write('');
116
+
117
+ for (const method of node.methods) {
118
+ const params = ['self', ...method.parameters].join(', ');
119
+ this.write(`def ${method.name}(${params}):`);
120
+ this.indent++;
121
+ for (const statement of method.body) {
122
+ this.generateNode(statement);
123
+ }
124
+ if (method.body.length === 0) {
125
+ this.write('pass');
126
+ }
127
+ this.indent--;
128
+ this.write('');
129
+ }
130
+ }
131
+
132
+ this.indent--;
133
+ }
134
+
135
+ generateImportStatement(node) {
136
+ const modulePath = node.source.replace(/\//g, '.');
137
+
138
+ for (const spec of node.specifiers) {
139
+ if (spec.name === '*') {
140
+ this.write(`from ${modulePath} import *`);
141
+ } else if (spec.name === spec.alias) {
142
+ this.write(`from ${modulePath} import ${spec.name}`);
143
+ } else {
144
+ this.write(`from ${modulePath} import ${spec.name} as ${spec.alias}`);
145
+ }
146
+ }
147
+ }
148
+
149
+ generateTryStatement(node) {
150
+ this.write('try:');
151
+ this.indent++;
152
+ for (const statement of node.tryBlock) {
153
+ this.generateNode(statement);
154
+ }
155
+ if (node.tryBlock.length === 0) {
156
+ this.write('pass');
157
+ }
158
+ this.indent--;
159
+
160
+ if (node.catchClause) {
161
+ const param = node.catchClause.parameter || 'e';
162
+ this.write(`except Exception as ${param}:`);
163
+ this.indent++;
164
+ for (const statement of node.catchClause.body) {
165
+ this.generateNode(statement);
166
+ }
167
+ if (node.catchClause.body.length === 0) {
168
+ this.write('pass');
169
+ }
170
+ this.indent--;
171
+ }
172
+
173
+ if (node.finallyBlock) {
174
+ this.write('finally:');
175
+ this.indent++;
176
+ for (const statement of node.finallyBlock) {
177
+ this.generateNode(statement);
178
+ }
179
+ if (node.finallyBlock.length === 0) {
180
+ this.write('pass');
181
+ }
182
+ this.indent--;
183
+ }
184
+ }
185
+
186
+ generateIfStatement(node) {
187
+ const condition = this.generateNode(node.condition);
188
+ this.write(`if ${condition}:`);
189
+ this.indent++;
190
+ for (const statement of node.thenBranch) {
191
+ this.generateNode(statement);
192
+ }
193
+ if (node.thenBranch.length === 0) {
194
+ this.write('pass');
195
+ }
196
+ this.indent--;
197
+
198
+ for (const elif of node.elifBranches || []) {
199
+ const elifCond = this.generateNode(elif.condition);
200
+ this.write(`elif ${elifCond}:`);
201
+ this.indent++;
202
+ for (const statement of elif.body) {
203
+ this.generateNode(statement);
204
+ }
205
+ if (elif.body.length === 0) {
206
+ this.write('pass');
207
+ }
208
+ this.indent--;
209
+ }
210
+
211
+ if (node.elseBranch) {
212
+ this.write('else:');
213
+ this.indent++;
214
+ for (const statement of node.elseBranch) {
215
+ this.generateNode(statement);
216
+ }
217
+ if (node.elseBranch.length === 0) {
218
+ this.write('pass');
219
+ }
220
+ this.indent--;
221
+ }
222
+ }
223
+
224
+ generateWhileStatement(node) {
225
+ const condition = this.generateNode(node.condition);
226
+ this.write(`while ${condition}:`);
227
+ this.indent++;
228
+ for (const statement of node.body) {
229
+ this.generateNode(statement);
230
+ }
231
+ if (node.body.length === 0) {
232
+ this.write('pass');
233
+ }
234
+ this.indent--;
235
+ }
236
+
237
+ generateForStatement(node) {
238
+ const start = this.generateNode(node.start);
239
+ const end = this.generateNode(node.end);
240
+ const step = this.generateNode(node.step);
241
+
242
+ if (step === '1') {
243
+ this.write(`for ${node.iterator} in range(${start}, ${end} + 1):`);
244
+ } else {
245
+ this.write(`for ${node.iterator} in range(${start}, ${end} + 1, ${step}):`);
246
+ }
247
+
248
+ this.indent++;
249
+ for (const statement of node.body) {
250
+ this.generateNode(statement);
251
+ }
252
+ if (node.body.length === 0) {
253
+ this.write('pass');
254
+ }
255
+ this.indent--;
256
+ }
257
+
258
+ generateReturnStatement(node) {
259
+ if (node.value) {
260
+ const value = this.generateNode(node.value);
261
+ this.write(`return ${value}`);
262
+ } else {
263
+ this.write('return');
264
+ }
265
+ }
266
+
267
+ generateAssignment(node) {
268
+ const target = this.generateNode(node.target);
269
+ const value = this.generateNode(node.value);
270
+
271
+ if (node.operator === '=') {
272
+ this.write(`${target} = ${value}`);
273
+ } else {
274
+ this.write(`${target} ${node.operator} ${value}`);
275
+ }
276
+ }
277
+
278
+ generateBinaryExpression(node) {
279
+ const left = this.generateNode(node.left);
280
+ const right = this.generateNode(node.right);
281
+
282
+ const operatorMap = {
283
+ '==': '==',
284
+ '!=': '!=',
285
+ '<': '<',
286
+ '<=': '<=',
287
+ '>': '>',
288
+ '>=': '>=',
289
+ 'and': 'and',
290
+ '&&': 'and',
291
+ 'or': 'or',
292
+ '||': 'or'
293
+ };
294
+
295
+ const op = operatorMap[node.operator] || node.operator;
296
+ return `(${left} ${op} ${right})`;
297
+ }
298
+
299
+ generateUnaryExpression(node) {
300
+ const operand = this.generateNode(node.operand);
301
+
302
+ const operatorMap = {
303
+ 'not': 'not',
304
+ '!': 'not'
305
+ };
306
+
307
+ const op = operatorMap[node.operator] || node.operator;
308
+ return `${op} ${operand}`;
309
+ }
310
+
311
+ generateCallExpression(node) {
312
+ const callee = this.generateNode(node.callee);
313
+ const args = node.arguments.map(arg => this.generateNode(arg)).join(', ');
314
+ return `${callee}(${args})`;
315
+ }
316
+
317
+ generateIndexExpression(node) {
318
+ const object = this.generateNode(node.object);
319
+ const index = this.generateNode(node.index);
320
+ return `${object}[${index}]`;
321
+ }
322
+
323
+ generateMemberExpression(node) {
324
+ const object = this.generateNode(node.object);
325
+ return `${object}.${node.property}`;
326
+ }
327
+
328
+ generateLiteral(value) {
329
+ if (value === null) return 'None';
330
+ if (value === true) return 'True';
331
+ if (value === false) return 'False';
332
+ if (typeof value === 'string') return `"${value.replace(/"/g, '\\"')}"`;
333
+ return String(value);
334
+ }
335
+
336
+ generateArrayLiteral(node) {
337
+ const elements = node.elements.map(el => this.generateNode(el)).join(', ');
338
+ return `[${elements}]`;
339
+ }
340
+
341
+ generateObjectLiteral(node) {
342
+ const props = node.properties.map(prop => {
343
+ const key = `"${prop.key}"`;
344
+ const value = this.generateNode(prop.value);
345
+ return `${key}: ${value}`;
346
+ }).join(', ');
347
+ return `{${props}}`;
348
+ }
349
+
350
+ write(line) {
351
+ const indentation = this.indentStr.repeat(this.indent);
352
+ this.output.push(indentation + line);
353
+ }
354
+ }
355
+
356
+ module.exports = new PythonBackend();
@@ -0,0 +1,222 @@
1
+ class RubyBackend {
2
+ generate(ast, options = {}) {
3
+ this.output = [];
4
+ this.indent = 0;
5
+ this.generateNode(ast);
6
+ return this.output.join('\n');
7
+ }
8
+
9
+ generateNode(node) {
10
+ if (!node) return '';
11
+
12
+ switch (node.type) {
13
+ case 'Program':
14
+ return this.generateProgram(node);
15
+ case 'VariableDeclaration':
16
+ return this.generateVariableDeclaration(node);
17
+ case 'FunctionDeclaration':
18
+ return this.generateFunctionDeclaration(node);
19
+ case 'ClassDeclaration':
20
+ return this.generateClassDeclaration(node);
21
+ case 'IfStatement':
22
+ return this.generateIfStatement(node);
23
+ case 'WhileStatement':
24
+ return this.generateWhileStatement(node);
25
+ case 'ForStatement':
26
+ return this.generateForStatement(node);
27
+ case 'ReturnStatement':
28
+ return this.generateReturnStatement(node);
29
+ case 'Break':
30
+ this.write('break');
31
+ return;
32
+ case 'Continue':
33
+ this.write('next');
34
+ return;
35
+ case 'Assignment':
36
+ return this.generateAssignment(node);
37
+ case 'BinaryExpression':
38
+ return this.generateBinaryExpression(node);
39
+ case 'CallExpression':
40
+ return this.generateCallExpression(node);
41
+ case 'Identifier':
42
+ return node.name;
43
+ case 'Literal':
44
+ return this.generateLiteral(node.value);
45
+ case 'ArrayLiteral':
46
+ return this.generateArrayLiteral(node);
47
+ case 'ObjectLiteral':
48
+ return this.generateObjectLiteral(node);
49
+ default:
50
+ return '';
51
+ }
52
+ }
53
+
54
+ generateProgram(node) {
55
+ this.write('#!/usr/bin/env ruby');
56
+ this.write('');
57
+ for (const stmt of node.statements) {
58
+ this.generateNode(stmt);
59
+ }
60
+ }
61
+
62
+ generateVariableDeclaration(node) {
63
+ const value = node.initializer ? this.generateNode(node.initializer) : 'nil';
64
+ this.write(`${node.name} = ${value}`);
65
+ }
66
+
67
+ generateFunctionDeclaration(node) {
68
+ const params = node.parameters.join(', ');
69
+ this.write(`def ${node.name}(${params})`);
70
+ this.indent++;
71
+ for (const stmt of node.body) {
72
+ this.generateNode(stmt);
73
+ }
74
+ this.indent--;
75
+ this.write('end');
76
+ this.write('');
77
+ }
78
+
79
+ generateClassDeclaration(node) {
80
+ const superclass = node.superclass ? ` < ${node.superclass}` : '';
81
+ this.write(`class ${node.name}${superclass}`);
82
+ this.indent++;
83
+
84
+ if (node.properties.length > 0) {
85
+ this.write('def initialize');
86
+ this.indent++;
87
+ for (const prop of node.properties) {
88
+ const value = prop.initializer ? this.generateNode(prop.initializer) : 'nil';
89
+ this.write(`@${prop.name} = ${value}`);
90
+ }
91
+ this.indent--;
92
+ this.write('end');
93
+ this.write('');
94
+ }
95
+
96
+ for (const method of node.methods) {
97
+ this.generateFunctionDeclaration(method);
98
+ }
99
+
100
+ this.indent--;
101
+ this.write('end');
102
+ this.write('');
103
+ }
104
+
105
+ generateIfStatement(node) {
106
+ const cond = this.generateNode(node.condition);
107
+ this.write(`if ${cond}`);
108
+ this.indent++;
109
+ for (const stmt of node.thenBranch) {
110
+ this.generateNode(stmt);
111
+ }
112
+ this.indent--;
113
+
114
+ for (const elif of node.elifBranches || []) {
115
+ const elifCond = this.generateNode(elif.condition);
116
+ this.write(`elsif ${elifCond}`);
117
+ this.indent++;
118
+ for (const stmt of elif.body) {
119
+ this.generateNode(stmt);
120
+ }
121
+ this.indent--;
122
+ }
123
+
124
+ if (node.elseBranch) {
125
+ this.write('else');
126
+ this.indent++;
127
+ for (const stmt of node.elseBranch) {
128
+ this.generateNode(stmt);
129
+ }
130
+ this.indent--;
131
+ }
132
+
133
+ this.write('end');
134
+ }
135
+
136
+ generateWhileStatement(node) {
137
+ const cond = this.generateNode(node.condition);
138
+ this.write(`while ${cond}`);
139
+ this.indent++;
140
+ for (const stmt of node.body) {
141
+ this.generateNode(stmt);
142
+ }
143
+ this.indent--;
144
+ this.write('end');
145
+ }
146
+
147
+ generateForStatement(node) {
148
+ const start = this.generateNode(node.start);
149
+ const end = this.generateNode(node.end);
150
+ this.write(`(${start}..${end}).each do |${node.iterator}|`);
151
+ this.indent++;
152
+ for (const stmt of node.body) {
153
+ this.generateNode(stmt);
154
+ }
155
+ this.indent--;
156
+ this.write('end');
157
+ }
158
+
159
+ generateReturnStatement(node) {
160
+ if (node.value) {
161
+ const value = this.generateNode(node.value);
162
+ this.write(`return ${value}`);
163
+ } else {
164
+ this.write('return');
165
+ }
166
+ }
167
+
168
+ generateAssignment(node) {
169
+ const target = this.generateNode(node.target);
170
+ const value = this.generateNode(node.value);
171
+ this.write(`${target} ${node.operator} ${value}`);
172
+ }
173
+
174
+ generateBinaryExpression(node) {
175
+ const left = this.generateNode(node.left);
176
+ const right = this.generateNode(node.right);
177
+
178
+ const operatorMap = {
179
+ '&&': 'and',
180
+ '||': 'or',
181
+ '!': 'not'
182
+ };
183
+
184
+ const op = operatorMap[node.operator] || node.operator;
185
+ return `(${left} ${op} ${right})`;
186
+ }
187
+
188
+ generateCallExpression(node) {
189
+ const callee = this.generateNode(node.callee);
190
+ const args = node.arguments.map(arg => this.generateNode(arg)).join(', ');
191
+ return `${callee}(${args})`;
192
+ }
193
+
194
+ generateArrayLiteral(node) {
195
+ const elements = node.elements.map(el => this.generateNode(el)).join(', ');
196
+ return `[${elements}]`;
197
+ }
198
+
199
+ generateObjectLiteral(node) {
200
+ const props = node.properties.map(prop => {
201
+ const key = prop.key;
202
+ const value = this.generateNode(prop.value);
203
+ return `${key}: ${value}`;
204
+ }).join(', ');
205
+ return `{${props}}`;
206
+ }
207
+
208
+ generateLiteral(value) {
209
+ if (value === null) return 'nil';
210
+ if (value === true) return 'true';
211
+ if (value === false) return 'false';
212
+ if (typeof value === 'string') return `"${value.replace(/"/g, '\\"')}"`;
213
+ return String(value);
214
+ }
215
+
216
+ write(line) {
217
+ const indentation = ' '.repeat(this.indent);
218
+ this.output.push(indentation + line);
219
+ }
220
+ }
221
+
222
+ module.exports = new RubyBackend();
@@ -0,0 +1,39 @@
1
+ class Backend {
2
+ generate(ast, options = {}) {
3
+ this.output = [];
4
+ this.indent = 0;
5
+ this.generateNode(ast);
6
+ return this.output.join('\n');
7
+ }
8
+
9
+ generateNode(node) {
10
+ if (!node) return '';
11
+ switch (node.type) {
12
+ case 'Program': return this.generateProgram(node);
13
+ case 'VariableDeclaration': return this.generateVariableDeclaration(node);
14
+ case 'FunctionDeclaration': return this.generateFunctionDeclaration(node);
15
+ default: return '';
16
+ }
17
+ }
18
+
19
+ generateProgram(node) {
20
+ for (const stmt of node.statements) {
21
+ this.generateNode(stmt);
22
+ }
23
+ }
24
+
25
+ generateVariableDeclaration(node) {
26
+ const value = node.initializer ? this.generateNode(node.initializer) : 'null';
27
+ this.write(`var ${node.name} = ${value};`);
28
+ }
29
+
30
+ generateFunctionDeclaration(node) {
31
+ this.write(`function ${node.name}() {}`);
32
+ }
33
+
34
+ write(line) {
35
+ this.output.push(' '.repeat(this.indent) + line);
36
+ }
37
+ }
38
+
39
+ module.exports = new Backend();