@ugo-studio/jspp 0.2.5 → 0.2.6
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.
- package/README.md +51 -36
- package/dist/analysis/scope.js +7 -0
- package/dist/analysis/typeAnalyzer.js +40 -19
- package/dist/ast/symbols.js +9 -8
- package/dist/cli/args.js +59 -0
- package/dist/cli/colors.js +9 -0
- package/dist/cli/file-utils.js +20 -0
- package/dist/cli/index.js +160 -0
- package/dist/cli/spinner.js +55 -0
- package/dist/core/codegen/control-flow-handlers.js +2 -2
- package/dist/core/codegen/declaration-handlers.js +9 -1
- package/dist/core/codegen/expression-handlers.js +101 -45
- package/dist/core/codegen/function-handlers.js +14 -3
- package/dist/core/codegen/helpers.js +33 -7
- package/dist/core/codegen/index.js +7 -5
- package/dist/core/codegen/statement-handlers.js +109 -37
- package/dist/core/codegen/visitor.js +22 -2
- package/dist/core/constants.js +16 -0
- package/dist/core/error.js +58 -0
- package/dist/index.js +6 -3
- package/package.json +3 -3
- package/src/prelude/scheduler.hpp +144 -144
- package/src/prelude/utils/log_any_value/object.hpp +12 -10
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import ts from "typescript";
|
|
2
2
|
import { DeclaredSymbols } from "../../ast/symbols.js";
|
|
3
|
-
import {
|
|
3
|
+
import { constants } from "../constants.js";
|
|
4
|
+
import { CompilerError } from "../error.js";
|
|
5
|
+
import { collectBlockScopedDeclarations, collectFunctionScopedDeclarations, shouldIgnoreStatement, } from "./helpers.js";
|
|
4
6
|
import { CodeGenerator } from "./index.js";
|
|
5
7
|
export function visitSourceFile(node, context) {
|
|
6
8
|
const sourceFile = node;
|
|
@@ -8,8 +10,9 @@ export function visitSourceFile(node, context) {
|
|
|
8
10
|
// 1. Collect all var declarations (recursively) + top-level let/const
|
|
9
11
|
const varDecls = collectFunctionScopedDeclarations(sourceFile);
|
|
10
12
|
const topLevelLetConst = collectBlockScopedDeclarations(sourceFile.statements);
|
|
11
|
-
const funcDecls = sourceFile.statements.filter(ts.isFunctionDeclaration);
|
|
13
|
+
const funcDecls = sourceFile.statements.filter((s) => ts.isFunctionDeclaration(s) && !!s.body);
|
|
12
14
|
const classDecls = sourceFile.statements.filter(ts.isClassDeclaration);
|
|
15
|
+
const enumDecls = sourceFile.statements.filter(ts.isEnumDeclaration);
|
|
13
16
|
const hoistedSymbols = new DeclaredSymbols();
|
|
14
17
|
// Hoist function declarations
|
|
15
18
|
funcDecls.forEach((func) => {
|
|
@@ -19,6 +22,10 @@ export function visitSourceFile(node, context) {
|
|
|
19
22
|
classDecls.forEach((cls) => {
|
|
20
23
|
code += this.hoistDeclaration(cls, hoistedSymbols, node);
|
|
21
24
|
});
|
|
25
|
+
// Hoist enum declarations
|
|
26
|
+
enumDecls.forEach((enm) => {
|
|
27
|
+
code += this.hoistDeclaration(enm, hoistedSymbols, node);
|
|
28
|
+
});
|
|
22
29
|
// Hoist variable declarations (var)
|
|
23
30
|
varDecls.forEach((decl) => {
|
|
24
31
|
code += this.hoistDeclaration(decl, hoistedSymbols, node);
|
|
@@ -68,19 +75,11 @@ export function visitSourceFile(node, context) {
|
|
|
68
75
|
// Already handled
|
|
69
76
|
}
|
|
70
77
|
else if (ts.isVariableStatement(stmt)) {
|
|
71
|
-
|
|
72
|
-
(ts.NodeFlags.Let | ts.NodeFlags.Const)) !==
|
|
73
|
-
0;
|
|
74
|
-
const contextForVisit = {
|
|
78
|
+
code += this.visit(stmt, {
|
|
75
79
|
...context,
|
|
76
80
|
globalScopeSymbols,
|
|
77
81
|
localScopeSymbols,
|
|
78
|
-
|
|
79
|
-
};
|
|
80
|
-
const assignments = this.visit(stmt.declarationList, contextForVisit);
|
|
81
|
-
if (assignments) {
|
|
82
|
-
code += `${this.indent()}${assignments};\n`;
|
|
83
|
-
}
|
|
82
|
+
});
|
|
84
83
|
}
|
|
85
84
|
else {
|
|
86
85
|
code += this.visit(stmt, {
|
|
@@ -100,8 +99,9 @@ export function visitBlock(node, context) {
|
|
|
100
99
|
const block = node;
|
|
101
100
|
// Collect ONLY block-scoped declarations (let/const)
|
|
102
101
|
const blockScopedDecls = collectBlockScopedDeclarations(block.statements);
|
|
103
|
-
const funcDecls = block.statements.filter(ts.isFunctionDeclaration);
|
|
102
|
+
const funcDecls = block.statements.filter((s) => ts.isFunctionDeclaration(s) && !!s.body);
|
|
104
103
|
const classDecls = block.statements.filter(ts.isClassDeclaration);
|
|
104
|
+
const enumDecls = block.statements.filter(ts.isEnumDeclaration);
|
|
105
105
|
const hoistedSymbols = new DeclaredSymbols();
|
|
106
106
|
// 1. Hoist all function declarations
|
|
107
107
|
funcDecls.forEach((func) => {
|
|
@@ -111,6 +111,10 @@ export function visitBlock(node, context) {
|
|
|
111
111
|
classDecls.forEach((cls) => {
|
|
112
112
|
code += this.hoistDeclaration(cls, hoistedSymbols, node);
|
|
113
113
|
});
|
|
114
|
+
// Hoist enum declarations
|
|
115
|
+
enumDecls.forEach((enm) => {
|
|
116
|
+
code += this.hoistDeclaration(enm, hoistedSymbols, node);
|
|
117
|
+
});
|
|
114
118
|
// Hoist variable declarations (let/const only)
|
|
115
119
|
blockScopedDecls.forEach((decl) => {
|
|
116
120
|
code += this.hoistDeclaration(decl, hoistedSymbols, node);
|
|
@@ -156,19 +160,11 @@ export function visitBlock(node, context) {
|
|
|
156
160
|
// Do nothing, already handled
|
|
157
161
|
}
|
|
158
162
|
else if (ts.isVariableStatement(stmt)) {
|
|
159
|
-
|
|
160
|
-
(ts.NodeFlags.Let | ts.NodeFlags.Const)) !==
|
|
161
|
-
0;
|
|
162
|
-
const contextForVisit = {
|
|
163
|
+
code += this.visit(stmt, {
|
|
163
164
|
...context,
|
|
164
165
|
globalScopeSymbols,
|
|
165
166
|
localScopeSymbols,
|
|
166
|
-
|
|
167
|
-
};
|
|
168
|
-
const assignments = this.visit(stmt.declarationList, contextForVisit);
|
|
169
|
-
if (assignments) {
|
|
170
|
-
code += `${this.indent()}${assignments};\n`;
|
|
171
|
-
}
|
|
167
|
+
});
|
|
172
168
|
}
|
|
173
169
|
else {
|
|
174
170
|
code += this.visit(stmt, {
|
|
@@ -190,9 +186,87 @@ export function visitBlock(node, context) {
|
|
|
190
186
|
return code;
|
|
191
187
|
}
|
|
192
188
|
export function visitVariableStatement(node, context) {
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
189
|
+
if (shouldIgnoreStatement(node)) {
|
|
190
|
+
return "";
|
|
191
|
+
}
|
|
192
|
+
const isLetOrConst = (node.declarationList.flags &
|
|
193
|
+
(ts.NodeFlags.Let | ts.NodeFlags.Const)) !==
|
|
194
|
+
0;
|
|
195
|
+
const visitContext = {
|
|
196
|
+
...context,
|
|
197
|
+
isAssignmentOnly: !isLetOrConst,
|
|
198
|
+
};
|
|
199
|
+
const assignments = this.visit(node.declarationList, visitContext);
|
|
200
|
+
if (assignments) {
|
|
201
|
+
return `${this.indent()}${assignments};\n`;
|
|
202
|
+
}
|
|
203
|
+
return "";
|
|
204
|
+
}
|
|
205
|
+
export function visitTypeAliasDeclaration(node, context) {
|
|
206
|
+
return "";
|
|
207
|
+
}
|
|
208
|
+
export function visitInterfaceDeclaration(node, context) {
|
|
209
|
+
return "";
|
|
210
|
+
}
|
|
211
|
+
export function visitEnumDeclaration(node, context) {
|
|
212
|
+
const name = node.name.getText();
|
|
213
|
+
const scope = this.getScopeForNode(node);
|
|
214
|
+
const typeInfo = this.typeAnalyzer.scopeManager.lookupFromScope(name, scope);
|
|
215
|
+
// Mark as initialized
|
|
216
|
+
this.markSymbolAsInitialized(name, context.globalScopeSymbols, context.localScopeSymbols);
|
|
217
|
+
const enumVar = typeInfo.needsHeapAllocation ? `(*${name})` : name;
|
|
218
|
+
let code = `${this.indent()}${enumVar} = jspp::AnyValue::make_object({});\n`;
|
|
219
|
+
code += `${this.indent()}{\n`;
|
|
220
|
+
this.indentationLevel++;
|
|
221
|
+
code +=
|
|
222
|
+
`${this.indent()}jspp::AnyValue lastVal = jspp::AnyValue::make_number(-1);\n`; // Previous value tracker
|
|
223
|
+
for (const member of node.members) {
|
|
224
|
+
const memberName = member.name.getText();
|
|
225
|
+
let valueCode = "";
|
|
226
|
+
// Handle member name (it could be a string literal or identifier)
|
|
227
|
+
let key = "";
|
|
228
|
+
if (ts.isIdentifier(member.name)) {
|
|
229
|
+
key = `"${memberName}"`;
|
|
230
|
+
}
|
|
231
|
+
else if (ts.isStringLiteral(member.name)) {
|
|
232
|
+
key = member.name.getText(); // Includes quotes
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
// Computed property names or numeric literals in enums are rarer but possible
|
|
236
|
+
// For now assume simple enum
|
|
237
|
+
key = `"${memberName}"`;
|
|
238
|
+
}
|
|
239
|
+
if (member.initializer) {
|
|
240
|
+
// Visit initializer
|
|
241
|
+
valueCode = this.visit(member.initializer, context);
|
|
242
|
+
}
|
|
243
|
+
else {
|
|
244
|
+
// Auto-increment
|
|
245
|
+
valueCode = `lastVal + 1`;
|
|
246
|
+
}
|
|
247
|
+
code += `${this.indent()}lastVal = ${valueCode};\n`;
|
|
248
|
+
code +=
|
|
249
|
+
`${this.indent()}${enumVar}.set_own_property(${key}, lastVal);\n`;
|
|
250
|
+
// Reverse mapping for numeric enums
|
|
251
|
+
code += `${this.indent()}if (lastVal.is_number()) {\n`;
|
|
252
|
+
this.indentationLevel++;
|
|
253
|
+
code +=
|
|
254
|
+
`${this.indent()}${enumVar}.set_own_property(lastVal, jspp::AnyValue::make_string(${key}));\n`;
|
|
255
|
+
this.indentationLevel--;
|
|
256
|
+
code += `${this.indent()}}\n`;
|
|
257
|
+
}
|
|
258
|
+
this.indentationLevel--;
|
|
259
|
+
code += `${this.indent()}}\n`;
|
|
260
|
+
return code;
|
|
261
|
+
}
|
|
262
|
+
export function visitModuleDeclaration(node, context) {
|
|
263
|
+
return "";
|
|
264
|
+
}
|
|
265
|
+
export function visitImportDeclaration(node, context) {
|
|
266
|
+
return "";
|
|
267
|
+
}
|
|
268
|
+
export function visitImportEqualsDeclaration(node, context) {
|
|
269
|
+
return "";
|
|
196
270
|
}
|
|
197
271
|
export function visitBreakStatement(node, context) {
|
|
198
272
|
if (node.label) {
|
|
@@ -237,7 +311,12 @@ export function visitLabeledStatement(node, context) {
|
|
|
237
311
|
}
|
|
238
312
|
export function visitIfStatement(node, context) {
|
|
239
313
|
const ifStmt = node;
|
|
240
|
-
const
|
|
314
|
+
const isBinaryExpression = ts.isBinaryExpression(ifStmt.expression) &&
|
|
315
|
+
constants.booleanOperators.includes(ifStmt.expression.operatorToken.kind);
|
|
316
|
+
const condition = this.visit(ifStmt.expression, {
|
|
317
|
+
...context,
|
|
318
|
+
supportedNativeLiterals: isBinaryExpression ? ["boolean"] : undefined,
|
|
319
|
+
});
|
|
241
320
|
const thenStmt = this.visit(ifStmt.thenStatement, {
|
|
242
321
|
...context,
|
|
243
322
|
isFunctionBody: false,
|
|
@@ -250,15 +329,8 @@ export function visitIfStatement(node, context) {
|
|
|
250
329
|
isFunctionBody: false,
|
|
251
330
|
});
|
|
252
331
|
}
|
|
253
|
-
if (
|
|
254
|
-
|
|
255
|
-
const op = binExpr.operatorToken.getText();
|
|
256
|
-
const isBoolean = op === "==" || op === "!=" || op === "===" ||
|
|
257
|
-
op === "!==" || op === "<" || op === ">" || op === "<=" ||
|
|
258
|
-
op === ">=" || op === "instanceof" || op === "in";
|
|
259
|
-
if (isBoolean) {
|
|
260
|
-
return `${this.indent()}if ((${condition}).as_boolean()) ${thenStmt}${elseStmt}`;
|
|
261
|
-
}
|
|
332
|
+
if (isBinaryExpression) {
|
|
333
|
+
return `${this.indent()}if (${condition}) ${thenStmt}${elseStmt}`;
|
|
262
334
|
}
|
|
263
335
|
return `${this.indent()}if (jspp::is_truthy(${condition})) ${thenStmt}${elseStmt}`;
|
|
264
336
|
}
|
|
@@ -540,7 +612,7 @@ export function visitCatchClause(node, context) {
|
|
|
540
612
|
const exceptionName = context.exceptionName;
|
|
541
613
|
if (!exceptionName) {
|
|
542
614
|
// This should not happen if it's coming from a TryStatement
|
|
543
|
-
throw new
|
|
615
|
+
throw new CompilerError("exceptionName not found in context for CatchClause", node, "CompilerBug");
|
|
544
616
|
}
|
|
545
617
|
if (catchClause.variableDeclaration) {
|
|
546
618
|
const varName = catchClause.variableDeclaration.name.getText();
|
|
@@ -2,11 +2,11 @@ import ts from "typescript";
|
|
|
2
2
|
import { visitClassDeclaration } from "./class-handlers.js";
|
|
3
3
|
import { visitCaseClause, visitDefaultClause, visitDoStatement, visitForInStatement, visitForOfStatement, visitForStatement, visitSwitchStatement, visitWhileStatement, } from "./control-flow-handlers.js";
|
|
4
4
|
import { visitVariableDeclaration, visitVariableDeclarationList, } from "./declaration-handlers.js";
|
|
5
|
-
import { visitArrayLiteralExpression, visitAwaitExpression, visitBinaryExpression, visitCallExpression, visitConditionalExpression, visitDeleteExpression, visitElementAccessExpression, visitNewExpression, visitObjectLiteralExpression, visitParenthesizedExpression, visitPostfixUnaryExpression, visitPrefixUnaryExpression, visitPropertyAccessExpression, visitTemplateExpression, visitTypeOfExpression, visitVoidExpression, } from "./expression-handlers.js";
|
|
5
|
+
import { visitArrayLiteralExpression, visitAsExpression, visitAwaitExpression, visitBinaryExpression, visitCallExpression, visitConditionalExpression, visitDeleteExpression, visitElementAccessExpression, visitNewExpression, visitNonNullExpression, visitObjectLiteralExpression, visitParenthesizedExpression, visitPostfixUnaryExpression, visitPrefixUnaryExpression, visitPropertyAccessExpression, visitSatisfiesExpression, visitTemplateExpression, visitTypeAssertionExpression, visitTypeOfExpression, visitVoidExpression, } from "./expression-handlers.js";
|
|
6
6
|
import { visitArrowFunction, visitFunctionDeclaration, visitFunctionExpression, } from "./function-handlers.js";
|
|
7
7
|
import { CodeGenerator } from "./index.js";
|
|
8
8
|
import { visitFalseKeyword, visitIdentifier, visitNoSubstitutionTemplateLiteral, visitNullKeyword, visitNumericLiteral, visitStringLiteral, visitThisKeyword, visitTrueKeyword, visitUndefinedKeyword, } from "./literal-handlers.js";
|
|
9
|
-
import { visitBlock, visitBreakStatement, visitCatchClause, visitContinueStatement, visitExpressionStatement, visitIfStatement, visitLabeledStatement, visitReturnStatement, visitSourceFile, visitThrowStatement, visitTryStatement, visitVariableStatement, visitYieldExpression, } from "./statement-handlers.js";
|
|
9
|
+
import { visitBlock, visitBreakStatement, visitCatchClause, visitContinueStatement, visitEnumDeclaration, visitExpressionStatement, visitIfStatement, visitImportDeclaration, visitImportEqualsDeclaration, visitInterfaceDeclaration, visitLabeledStatement, visitModuleDeclaration, visitReturnStatement, visitSourceFile, visitThrowStatement, visitTryStatement, visitTypeAliasDeclaration, visitVariableStatement, visitYieldExpression, } from "./statement-handlers.js";
|
|
10
10
|
export function visit(node, context) {
|
|
11
11
|
if (ts.isFunctionDeclaration(node)) {
|
|
12
12
|
return visitFunctionDeclaration.call(this, node, context);
|
|
@@ -114,6 +114,26 @@ export function visit(node, context) {
|
|
|
114
114
|
return visitNullKeyword.call(this);
|
|
115
115
|
case ts.SyntaxKind.ThisKeyword:
|
|
116
116
|
return visitThisKeyword.call(this);
|
|
117
|
+
case ts.SyntaxKind.AsExpression:
|
|
118
|
+
return visitAsExpression.call(this, node, context);
|
|
119
|
+
case ts.SyntaxKind.TypeAssertionExpression:
|
|
120
|
+
return visitTypeAssertionExpression.call(this, node, context);
|
|
121
|
+
case ts.SyntaxKind.NonNullExpression:
|
|
122
|
+
return visitNonNullExpression.call(this, node, context);
|
|
123
|
+
case ts.SyntaxKind.SatisfiesExpression:
|
|
124
|
+
return visitSatisfiesExpression.call(this, node, context);
|
|
125
|
+
case ts.SyntaxKind.TypeAliasDeclaration:
|
|
126
|
+
return visitTypeAliasDeclaration.call(this, node, context);
|
|
127
|
+
case ts.SyntaxKind.InterfaceDeclaration:
|
|
128
|
+
return visitInterfaceDeclaration.call(this, node, context);
|
|
129
|
+
case ts.SyntaxKind.EnumDeclaration:
|
|
130
|
+
return visitEnumDeclaration.call(this, node, context);
|
|
131
|
+
case ts.SyntaxKind.ModuleDeclaration:
|
|
132
|
+
return visitModuleDeclaration.call(this, node, context);
|
|
133
|
+
case ts.SyntaxKind.ImportDeclaration:
|
|
134
|
+
return visitImportDeclaration.call(this, node, context);
|
|
135
|
+
case ts.SyntaxKind.ImportEqualsDeclaration:
|
|
136
|
+
return visitImportEqualsDeclaration.call(this, node, context);
|
|
117
137
|
default:
|
|
118
138
|
return `/* Unhandled node: ${ts.SyntaxKind[node.kind]} */`;
|
|
119
139
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import ts from "typescript";
|
|
2
|
+
const booleanOperators = [
|
|
3
|
+
ts.SyntaxKind.EqualsEqualsEqualsToken,
|
|
4
|
+
ts.SyntaxKind.EqualsEqualsToken,
|
|
5
|
+
ts.SyntaxKind.ExclamationEqualsEqualsToken,
|
|
6
|
+
ts.SyntaxKind.ExclamationEqualsToken,
|
|
7
|
+
ts.SyntaxKind.InstanceOfKeyword,
|
|
8
|
+
ts.SyntaxKind.InKeyword,
|
|
9
|
+
ts.SyntaxKind.LessThanToken,
|
|
10
|
+
ts.SyntaxKind.LessThanEqualsToken,
|
|
11
|
+
ts.SyntaxKind.GreaterThanToken,
|
|
12
|
+
ts.SyntaxKind.GreaterThanEqualsToken,
|
|
13
|
+
];
|
|
14
|
+
export const constants = Object.freeze({
|
|
15
|
+
booleanOperators,
|
|
16
|
+
});
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import ts from "typescript";
|
|
2
|
+
const COLORS = {
|
|
3
|
+
reset: "\x1b[0m",
|
|
4
|
+
red: "\x1b[31m",
|
|
5
|
+
yellow: "\x1b[33m",
|
|
6
|
+
cyan: "\x1b[36m",
|
|
7
|
+
bold: "\x1b[1m",
|
|
8
|
+
dim: "\x1b[2m",
|
|
9
|
+
};
|
|
10
|
+
export class CompilerError extends Error {
|
|
11
|
+
node;
|
|
12
|
+
type;
|
|
13
|
+
constructor(message, node, type = "SyntaxError") {
|
|
14
|
+
super(message);
|
|
15
|
+
this.node = node;
|
|
16
|
+
this.type = type;
|
|
17
|
+
Object.setPrototypeOf(this, CompilerError.prototype);
|
|
18
|
+
}
|
|
19
|
+
getFormattedError() {
|
|
20
|
+
const sourceFile = this.node.getSourceFile();
|
|
21
|
+
if (!sourceFile) {
|
|
22
|
+
return `${COLORS.red}${this.type}: ${this.message}${COLORS.reset}`;
|
|
23
|
+
}
|
|
24
|
+
const start = this.node.getStart();
|
|
25
|
+
const { line, character } = sourceFile.getLineAndCharacterOfPosition(start);
|
|
26
|
+
// Get the full line content safely
|
|
27
|
+
const lineStartPos = sourceFile.getPositionOfLineAndCharacter(line, 0);
|
|
28
|
+
let lineEndPos;
|
|
29
|
+
try {
|
|
30
|
+
lineEndPos = sourceFile.getLineEndOfPosition(start);
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
lineEndPos = sourceFile.text.length;
|
|
34
|
+
}
|
|
35
|
+
const lineContent = sourceFile.text.substring(lineStartPos, lineEndPos).replace(/\r/g, ''); // Remove CR
|
|
36
|
+
const fileName = sourceFile.fileName;
|
|
37
|
+
const lineNum = line + 1;
|
|
38
|
+
const charNum = character + 1;
|
|
39
|
+
let output = `\n${COLORS.red}${COLORS.bold}${this.type}:${COLORS.reset} ${this.message}\n`;
|
|
40
|
+
output += ` ${COLORS.dim}at ${fileName}:${lineNum}:${charNum}${COLORS.reset}\n\n`;
|
|
41
|
+
// Code frame
|
|
42
|
+
const lineNumStr = `${lineNum} | `;
|
|
43
|
+
output += `${COLORS.dim}${lineNumStr}${COLORS.reset}${lineContent}\n`;
|
|
44
|
+
// Adjust pointer position if there are tabs
|
|
45
|
+
let pointerPadding = "";
|
|
46
|
+
for (let i = 0; i < character; i++) {
|
|
47
|
+
if (lineContent[i] === '\t') {
|
|
48
|
+
pointerPadding += "\t";
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
pointerPadding += " ";
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
const padding = " ".repeat(lineNumStr.length) + pointerPadding;
|
|
55
|
+
output += `${padding}${COLORS.red}^${COLORS.reset}\n`;
|
|
56
|
+
return output;
|
|
57
|
+
}
|
|
58
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -6,10 +6,13 @@ export class Interpreter {
|
|
|
6
6
|
parser = new Parser();
|
|
7
7
|
analyzer = new TypeAnalyzer();
|
|
8
8
|
generator = new CodeGenerator();
|
|
9
|
-
interpret(
|
|
10
|
-
const ast = this.parser.parse(
|
|
9
|
+
interpret(code, fileName) {
|
|
10
|
+
const ast = this.parser.parse(code, fileName);
|
|
11
11
|
this.analyzer.analyze(ast);
|
|
12
|
-
const
|
|
12
|
+
const isTypescript = fileName
|
|
13
|
+
? path.extname(fileName) === ".ts"
|
|
14
|
+
: false;
|
|
15
|
+
const cppCode = this.generator.generate(ast, this.analyzer, isTypescript);
|
|
13
16
|
const preludePath = path.resolve(import.meta.dirname, "..", "src", "prelude");
|
|
14
17
|
return { cppCode, preludePath };
|
|
15
18
|
}
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ugo-studio/jspp",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.6",
|
|
4
4
|
"description": "A modern transpiler that converts JavaScript code into high-performance, standard C++23.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "src/index.ts",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"bin": {
|
|
9
|
-
"jspp": "dist/cli.js"
|
|
9
|
+
"jspp": "dist/cli/index.js"
|
|
10
10
|
},
|
|
11
11
|
"files": [
|
|
12
12
|
"dist",
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
],
|
|
16
16
|
"scripts": {
|
|
17
17
|
"postinstall": "bun run scripts/setup-compiler.ts",
|
|
18
|
-
"dev": "bun run src/cli.ts",
|
|
18
|
+
"dev": "bun run src/cli/index.ts",
|
|
19
19
|
"typecheck": "tsc --noEmit",
|
|
20
20
|
"precompile": "bun run scripts/precompile-headers.ts",
|
|
21
21
|
"test": "bun test",
|