@grey-ts/transpiler 1.4.4 → 2.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.
- package/dist/index.js +230 -147
- package/package.json +5 -4
package/dist/index.js
CHANGED
|
@@ -45,9 +45,11 @@ class NodeHandler {
|
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
47
|
static addExtraOutput(node, before, after) {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
48
|
+
let extra = this.transpileContext.extraOutput.get(node);
|
|
49
|
+
if (!extra) {
|
|
50
|
+
extra = { before: "", after: "" };
|
|
51
|
+
this.transpileContext.extraOutput.set(node, extra);
|
|
52
|
+
}
|
|
51
53
|
if (before)
|
|
52
54
|
extra.before += before;
|
|
53
55
|
if (after)
|
|
@@ -167,7 +169,6 @@ var apiNameMap = {
|
|
|
167
169
|
"GreyHack.File.setGroup": "set_group",
|
|
168
170
|
"GreyHack.File.setOwner": "set_owner",
|
|
169
171
|
"GreyHack.activeUser": "active_user",
|
|
170
|
-
"GreyHack.clearScreen": "clear_screen",
|
|
171
172
|
"GreyHack.commandInfo": "command_info",
|
|
172
173
|
"GreyHack.currentDate": "current_date",
|
|
173
174
|
"GreyHack.currentPath": "current_path",
|
|
@@ -258,26 +259,11 @@ var apiNameMap = {
|
|
|
258
259
|
"Object.size": "len",
|
|
259
260
|
"Array.length": "len",
|
|
260
261
|
"Array.shift": "pull",
|
|
261
|
-
"Array.push": "push_many"
|
|
262
|
+
"Array.push": "push_many",
|
|
263
|
+
"Map.size": "data.len",
|
|
264
|
+
"Set.size": "data.len"
|
|
262
265
|
};
|
|
263
266
|
var propertyAccessReplacements = {
|
|
264
|
-
"Math.PI": "pi",
|
|
265
|
-
"Math.abs": "abs",
|
|
266
|
-
"Math.acos": "acos",
|
|
267
|
-
"Math.asin": "asin",
|
|
268
|
-
"Math.atan": "atan",
|
|
269
|
-
"Math.ceil": "ceil",
|
|
270
|
-
"Math.floor": "floor",
|
|
271
|
-
"Math.cos": "cos",
|
|
272
|
-
"Math.sin": "sin",
|
|
273
|
-
"Math.tan": "tan",
|
|
274
|
-
"Math.sqrt": "sqrt",
|
|
275
|
-
"Math.sign": "sign",
|
|
276
|
-
"Math.round": "round",
|
|
277
|
-
"Math.random": "rnd",
|
|
278
|
-
"Math.log": "log",
|
|
279
|
-
"console.log": "print",
|
|
280
|
-
"console.clear": "clear_screen",
|
|
281
267
|
"String.prototype": "string",
|
|
282
268
|
"Number.prototype": "number",
|
|
283
269
|
"Boolean.prototype": "number",
|
|
@@ -303,6 +289,7 @@ var knownOperators = new Set([
|
|
|
303
289
|
"!==",
|
|
304
290
|
"??",
|
|
305
291
|
"??=",
|
|
292
|
+
"||=",
|
|
306
293
|
"in",
|
|
307
294
|
"||",
|
|
308
295
|
"<",
|
|
@@ -327,13 +314,13 @@ function getOperatorToken(node) {
|
|
|
327
314
|
return null;
|
|
328
315
|
if (!knownOperators.has(operatorToken))
|
|
329
316
|
throw `Can't handle operator '${operatorToken}' yet`;
|
|
330
|
-
if (operatorToken
|
|
317
|
+
if (operatorToken === "||")
|
|
331
318
|
operatorToken = "or";
|
|
332
|
-
else if (operatorToken
|
|
319
|
+
else if (operatorToken === "&&")
|
|
333
320
|
operatorToken = "and";
|
|
334
|
-
else if (operatorToken
|
|
321
|
+
else if (operatorToken === "===")
|
|
335
322
|
operatorToken = "==";
|
|
336
|
-
else if (operatorToken
|
|
323
|
+
else if (operatorToken === "!==")
|
|
337
324
|
operatorToken = "!=";
|
|
338
325
|
return operatorToken;
|
|
339
326
|
}
|
|
@@ -355,7 +342,7 @@ function nodeIsFunctionReference(node, type) {
|
|
|
355
342
|
function asRef(value) {
|
|
356
343
|
if (value[0] === "@")
|
|
357
344
|
return value;
|
|
358
|
-
return
|
|
345
|
+
return `@${value}`;
|
|
359
346
|
}
|
|
360
347
|
function getSourceFiles(absPath) {
|
|
361
348
|
if (!fs.existsSync(absPath))
|
|
@@ -380,20 +367,16 @@ function getSourceFiles(absPath) {
|
|
|
380
367
|
return output;
|
|
381
368
|
}
|
|
382
369
|
function replaceIdentifier(original, type, propertyName) {
|
|
383
|
-
let symbol;
|
|
384
370
|
if (type.isUnion()) {
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
}
|
|
391
|
-
} else {
|
|
392
|
-
symbol = type.types.find((t) => t.flags !== ts3.TypeFlags.Undefined && t.symbol)?.symbol;
|
|
371
|
+
let result = original;
|
|
372
|
+
for (const t of type.types) {
|
|
373
|
+
result = replaceIdentifier(original, t, propertyName);
|
|
374
|
+
if (result !== original)
|
|
375
|
+
return result;
|
|
393
376
|
}
|
|
394
|
-
|
|
395
|
-
symbol = propertyName ? type.getProperty(propertyName) : type.symbol;
|
|
377
|
+
return result;
|
|
396
378
|
}
|
|
379
|
+
const symbol = propertyName ? type.getProperty(propertyName) : type.symbol;
|
|
397
380
|
if (!symbol)
|
|
398
381
|
return original;
|
|
399
382
|
const symbolFullName = checker.getFullyQualifiedName(symbol);
|
|
@@ -402,7 +385,7 @@ function replaceIdentifier(original, type, propertyName) {
|
|
|
402
385
|
return original;
|
|
403
386
|
const dotIndex = symbolFullName.lastIndexOf(".");
|
|
404
387
|
const strToReplace = dotIndex !== null ? symbolFullName.slice(dotIndex + 1) : symbolFullName;
|
|
405
|
-
if (strToReplace
|
|
388
|
+
if (strToReplace !== original)
|
|
406
389
|
return original;
|
|
407
390
|
return replaceValue;
|
|
408
391
|
}
|
|
@@ -474,7 +457,7 @@ NodeHandler.register(ts5.SyntaxKind.ClassDeclaration, (node) => {
|
|
|
474
457
|
const name = node.name ? node.name.text : "anon";
|
|
475
458
|
const extensions = node.heritageClauses?.filter((h) => h.token === ts5.SyntaxKind.ExtendsKeyword);
|
|
476
459
|
let output = `${name} = {}`;
|
|
477
|
-
if (extensions
|
|
460
|
+
if (extensions?.length && extensions[0].types.length)
|
|
478
461
|
output = `${name} = new ${NodeHandler.handle(extensions[0].types[0].expression)}`;
|
|
479
462
|
const declaredNames = new Set;
|
|
480
463
|
let hasConstructor = false;
|
|
@@ -569,10 +552,23 @@ class CallTransformer {
|
|
|
569
552
|
throw `Handler for '${symbolFullName}' was already registered`;
|
|
570
553
|
this.handlers.set(symbolFullName, handler);
|
|
571
554
|
}
|
|
572
|
-
static handle(
|
|
555
|
+
static handle(type, functionName, callArgs, node, ctx) {
|
|
556
|
+
let symbolFullName = "";
|
|
557
|
+
if (type.isUnion()) {
|
|
558
|
+
let result = null;
|
|
559
|
+
for (const t of type.types) {
|
|
560
|
+
const res = CallTransformer.handle(t, functionName, callArgs, node, ctx);
|
|
561
|
+
result ??= res;
|
|
562
|
+
}
|
|
563
|
+
return result;
|
|
564
|
+
} else if (type.symbol) {
|
|
565
|
+
symbolFullName = checker.getFullyQualifiedName(type.symbol);
|
|
566
|
+
}
|
|
567
|
+
if (!symbolFullName || symbolFullName.startsWith("__")) {
|
|
568
|
+
const symbol = checker.getSymbolAtLocation(node.expression);
|
|
569
|
+
symbolFullName = symbol ? checker.getFullyQualifiedName(symbol) : "";
|
|
570
|
+
}
|
|
573
571
|
if (symbolFullName in extensionFunctions) {
|
|
574
|
-
if (symbolFullName.startsWith("Math"))
|
|
575
|
-
utilitiesToInsert.set("create_math", "Math = {}");
|
|
576
572
|
utilitiesToInsert.set(symbolFullName, extensionFunctions[symbolFullName]);
|
|
577
573
|
const params = callArgs.length ? `(${callArgs.join(",")})` : "";
|
|
578
574
|
return `${functionName}${params}`;
|
|
@@ -583,15 +579,11 @@ class CallTransformer {
|
|
|
583
579
|
return handler(functionName, callArgs, node, ctx);
|
|
584
580
|
}
|
|
585
581
|
}
|
|
586
|
-
CallTransformer.register("Number.toString", (name) => {
|
|
587
|
-
const number = name.slice(0, name.lastIndexOf("."));
|
|
588
|
-
return `str(${number})`;
|
|
589
|
-
});
|
|
590
582
|
CallTransformer.register("Function.toString", (name) => {
|
|
591
583
|
const func = name.slice(0, name.lastIndexOf("."));
|
|
592
584
|
return `str(@${func})`;
|
|
593
585
|
});
|
|
594
|
-
CallTransformer.register("GreyHack.include", (
|
|
586
|
+
CallTransformer.register("GreyHack.include", (_name, _args, node, ctx) => {
|
|
595
587
|
if (!node.arguments.length)
|
|
596
588
|
return "";
|
|
597
589
|
const fileArg = node.arguments[0];
|
|
@@ -604,20 +596,20 @@ CallTransformer.register("GreyHack.include", (name, args, node, ctx) => {
|
|
|
604
596
|
}
|
|
605
597
|
return "";
|
|
606
598
|
});
|
|
607
|
-
CallTransformer.register("GreyHack.isType", (
|
|
599
|
+
CallTransformer.register("GreyHack.isType", (_name, args) => {
|
|
608
600
|
return callUtilFunction("is_type", args.join(","));
|
|
609
601
|
});
|
|
610
|
-
CallTransformer.register("Boolean", (
|
|
602
|
+
CallTransformer.register("Boolean", (_name, args) => {
|
|
611
603
|
if (!args.length)
|
|
612
604
|
return "0";
|
|
613
605
|
return `(not (not ${args[0]}))`;
|
|
614
606
|
});
|
|
615
|
-
CallTransformer.register("Number", (
|
|
607
|
+
CallTransformer.register("Number", (_name, args) => {
|
|
616
608
|
if (!args.length)
|
|
617
609
|
return "0";
|
|
618
610
|
return `str(${args[0]}).val`;
|
|
619
611
|
});
|
|
620
|
-
CallTransformer.register("String", (
|
|
612
|
+
CallTransformer.register("String", (_name, args) => {
|
|
621
613
|
if (!args.length)
|
|
622
614
|
return "";
|
|
623
615
|
return `str(${args[0]})`;
|
|
@@ -710,14 +702,9 @@ function handleCallArgs(callNode, ctx) {
|
|
|
710
702
|
}
|
|
711
703
|
NodeHandler.register(ts7.SyntaxKind.CallExpression, (node, ctx) => {
|
|
712
704
|
const args = handleCallArgs(node, ctx);
|
|
713
|
-
|
|
705
|
+
const name = NodeHandler.handle(node.expression);
|
|
714
706
|
const type = checker.getTypeAtLocation(node.expression);
|
|
715
|
-
|
|
716
|
-
if (!symbolFullName || symbolFullName.startsWith("__")) {
|
|
717
|
-
const symbol = checker.getSymbolAtLocation(node.expression);
|
|
718
|
-
symbolFullName = symbol ? checker.getFullyQualifiedName(symbol) : "";
|
|
719
|
-
}
|
|
720
|
-
const transformed = CallTransformer.handle(symbolFullName, name, args, node, ctx);
|
|
707
|
+
const transformed = CallTransformer.handle(type, name, args, node, ctx);
|
|
721
708
|
if (transformed !== null)
|
|
722
709
|
return transformed;
|
|
723
710
|
if (!args.length && !ts7.isParenthesizedExpression(node.expression))
|
|
@@ -755,7 +742,7 @@ function isAssignmentChain(node, operator) {
|
|
|
755
742
|
return true;
|
|
756
743
|
return false;
|
|
757
744
|
}
|
|
758
|
-
NodeHandler.register(ts7.SyntaxKind.BinaryExpression, (node) => {
|
|
745
|
+
NodeHandler.register(ts7.SyntaxKind.BinaryExpression, (node, ctx) => {
|
|
759
746
|
let operatorToken = getOperatorToken(node.operatorToken) || node.operatorToken.getText();
|
|
760
747
|
if (isAssignmentChain(node, operatorToken))
|
|
761
748
|
throw `Assignment chaining is not supported`;
|
|
@@ -780,7 +767,7 @@ NodeHandler.register(ts7.SyntaxKind.BinaryExpression, (node) => {
|
|
|
780
767
|
}
|
|
781
768
|
let left = NodeHandler.handle(node.left);
|
|
782
769
|
if (shouldHaveOuterPrefix(node, operatorToken))
|
|
783
|
-
left =
|
|
770
|
+
left = `outer.${left}`;
|
|
784
771
|
if (nodeIsFunctionReference(node.left))
|
|
785
772
|
left = asRef(left);
|
|
786
773
|
if (operatorToken === "or" && ts7.hasOnlyExpressionInitializer(node.parent)) {
|
|
@@ -792,7 +779,15 @@ NodeHandler.register(ts7.SyntaxKind.BinaryExpression, (node) => {
|
|
|
792
779
|
case "??":
|
|
793
780
|
return callUtilFunction("nullish_coalescing_op", left, right);
|
|
794
781
|
case "??=":
|
|
795
|
-
|
|
782
|
+
case "||=": {
|
|
783
|
+
const util = operatorToken === "??=" ? "nullish_coalescing_op" : "or_op";
|
|
784
|
+
ctx.forceSafeAccess = true;
|
|
785
|
+
let leftSafe = NodeHandler.handle(node.left);
|
|
786
|
+
ctx.forceSafeAccess = false;
|
|
787
|
+
if (nodeIsFunctionReference(node.left))
|
|
788
|
+
leftSafe = asRef(leftSafe);
|
|
789
|
+
return `${left} = ${callUtilFunction(util, leftSafe, right)}`;
|
|
790
|
+
}
|
|
796
791
|
case "in":
|
|
797
792
|
return `${right}.hasIndex(${left})`;
|
|
798
793
|
case "&":
|
|
@@ -946,7 +941,7 @@ NodeHandler.register(ts8.SyntaxKind.Block, (node) => {
|
|
|
946
941
|
const output = node.statements.map((val) => {
|
|
947
942
|
let statement = NodeHandler.handle(val);
|
|
948
943
|
statement = statement.split(`
|
|
949
|
-
`).filter((s) => !!s).map((line) =>
|
|
944
|
+
`).filter((s) => !!s).map((line) => ` ${line}`).join(`
|
|
950
945
|
`);
|
|
951
946
|
return statement;
|
|
952
947
|
}).filter((s) => !!s).join(`
|
|
@@ -970,11 +965,11 @@ NodeHandler.register(ts8.SyntaxKind.ArrowFunction, (node) => {
|
|
|
970
965
|
if (ts8.isCallOrNewExpression(node.parent) || ts8.isParenthesizedExpression(node.parent)) {
|
|
971
966
|
const mainNode = ts8.findAncestor(node.parent, (n) => n.parent && (ts8.isBlock(n.parent) || ts8.isSourceFile(n.parent)));
|
|
972
967
|
if (!mainNode) {
|
|
973
|
-
return
|
|
968
|
+
return `@${createAnonFunction(body, params).name}`;
|
|
974
969
|
}
|
|
975
970
|
const anon = createAnonFunction(body, params, false);
|
|
976
971
|
NodeHandler.addExtraOutput(mainNode, anon.str, null);
|
|
977
|
-
return
|
|
972
|
+
return `@${anon.name}`;
|
|
978
973
|
}
|
|
979
974
|
if (ts8.hasOnlyExpressionInitializer(node.parent) || ts8.isBinaryExpression(node.parent) || ts8.isReturnStatement(node.parent)) {
|
|
980
975
|
return `function(${params.join(", ")})
|
|
@@ -995,20 +990,15 @@ NodeHandler.register(ts9.SyntaxKind.Identifier, (node, ctx) => {
|
|
|
995
990
|
let name = node.text;
|
|
996
991
|
if (name === "undefined")
|
|
997
992
|
return "null";
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
if (name != original)
|
|
1003
|
-
break;
|
|
1004
|
-
}
|
|
1005
|
-
} else {
|
|
1006
|
-
name = replaceIdentifier(node.text, type);
|
|
993
|
+
name = replaceIdentifier(node.text, type);
|
|
994
|
+
const symbolFullName = type.symbol ? checker.getFullyQualifiedName(type.symbol) : "";
|
|
995
|
+
if (symbolFullName in globalObjects) {
|
|
996
|
+
utilitiesToInsert.set(symbolFullName, globalObjects[symbolFullName]);
|
|
1007
997
|
}
|
|
1008
|
-
if (ctx.namedImports[ctx.currentFilePath]
|
|
998
|
+
if (ctx.namedImports[ctx.currentFilePath] && Object.hasOwn(ctx.namedImports[ctx.currentFilePath], name)) {
|
|
1009
999
|
name = ctx.namedImports[ctx.currentFilePath][name];
|
|
1010
1000
|
}
|
|
1011
|
-
if (ts9.isCallOrNewExpression(node.parent) && node
|
|
1001
|
+
if (ts9.isCallOrNewExpression(node.parent) && node !== node.parent.expression) {
|
|
1012
1002
|
if (nodeIsFunctionReference(node, type))
|
|
1013
1003
|
name = asRef(name);
|
|
1014
1004
|
}
|
|
@@ -1095,37 +1085,38 @@ NodeHandler.register(ts10.SyntaxKind.ImportDeclaration, (node, ctx) => {
|
|
|
1095
1085
|
|
|
1096
1086
|
// src/visitors/objects.ts
|
|
1097
1087
|
import ts11 from "typescript";
|
|
1098
|
-
function shouldGetSafely(node) {
|
|
1088
|
+
function shouldGetSafely(node, ctx) {
|
|
1099
1089
|
if (ts11.isNonNullExpression(node.parent))
|
|
1100
1090
|
return false;
|
|
1091
|
+
const callParent = ts11.findAncestor(node, (n) => n.parent && ts11.isCallExpression(n.parent) && n.parent.expression === n);
|
|
1092
|
+
if (callParent)
|
|
1093
|
+
return false;
|
|
1094
|
+
if (ctx.forceSafeAccess)
|
|
1095
|
+
return true;
|
|
1101
1096
|
if (valueIsBeingAssignedToNode(node))
|
|
1102
1097
|
return false;
|
|
1103
|
-
if (ts11.
|
|
1104
|
-
const rightType = checker.getTypeAtLocation(node.name);
|
|
1105
|
-
if (!rightType.isUnion())
|
|
1106
|
-
return !!node.questionDotToken;
|
|
1107
|
-
const hasUndefined = rightType.types.some((t) => t.flags === ts11.TypeFlags.Undefined);
|
|
1108
|
-
if (!hasUndefined)
|
|
1109
|
-
return false;
|
|
1110
|
-
if (!ts11.isCallExpression(node.parent))
|
|
1111
|
-
return true;
|
|
1112
|
-
if (node.parent.arguments.length)
|
|
1113
|
-
return false;
|
|
1114
|
-
} else {
|
|
1098
|
+
if (ts11.isElementAccessExpression(node)) {
|
|
1115
1099
|
if (ts11.isNumericLiteral(node.argumentExpression) && !node.questionDotToken)
|
|
1116
1100
|
return false;
|
|
1101
|
+
return true;
|
|
1117
1102
|
}
|
|
1103
|
+
const type = checker.getTypeAtLocation(node);
|
|
1104
|
+
if (!type.isUnion())
|
|
1105
|
+
return !!node.questionDotToken;
|
|
1106
|
+
const hasNullish = type.types.some((t) => t.flags === ts11.TypeFlags.Undefined || ts11.TypeFlags.Null);
|
|
1107
|
+
if (!hasNullish)
|
|
1108
|
+
return false;
|
|
1118
1109
|
return true;
|
|
1119
1110
|
}
|
|
1120
1111
|
NodeHandler.register(ts11.SyntaxKind.PropertyAccessExpression, (node, ctx) => {
|
|
1121
1112
|
const left = NodeHandler.handle(node.expression);
|
|
1122
1113
|
let right = NodeHandler.handle(node.name);
|
|
1123
1114
|
right = replaceIdentifier(right, checker.getTypeAtLocation(node.expression), right);
|
|
1124
|
-
const nodeSymbol = checker.getSymbolAtLocation(node);
|
|
1125
1115
|
if (ctx.namespaceImports[ctx.currentFilePath]?.has(left))
|
|
1126
1116
|
return right;
|
|
1127
|
-
if (shouldGetSafely(node))
|
|
1117
|
+
if (shouldGetSafely(node, ctx))
|
|
1128
1118
|
return callUtilFunction("get_property", left, `"${right}"`);
|
|
1119
|
+
const nodeSymbol = checker.getSymbolAtLocation(node);
|
|
1129
1120
|
let output = `${left}.${right}`;
|
|
1130
1121
|
output = replacePropertyAccess(output, nodeSymbol);
|
|
1131
1122
|
if (nodeIsFunctionReference(node))
|
|
@@ -1141,7 +1132,7 @@ NodeHandler.register(ts11.SyntaxKind.ElementAccessExpression, (node, ctx) => {
|
|
|
1141
1132
|
} else {
|
|
1142
1133
|
right = NodeHandler.handle(node.argumentExpression);
|
|
1143
1134
|
}
|
|
1144
|
-
if (shouldGetSafely(node)) {
|
|
1135
|
+
if (shouldGetSafely(node, ctx)) {
|
|
1145
1136
|
return callUtilFunction("get_property", left, `${right}`);
|
|
1146
1137
|
}
|
|
1147
1138
|
return `${left}[${right}]`;
|
|
@@ -1158,7 +1149,7 @@ function handleObjectLiteralExpression(node, ctx, currObj, outObjects, funcs) {
|
|
|
1158
1149
|
function pushObj() {
|
|
1159
1150
|
if (!currObj?.length)
|
|
1160
1151
|
return "";
|
|
1161
|
-
const res = currObj.filter((s) => s
|
|
1152
|
+
const res = currObj.filter((s) => s !== "").join(",");
|
|
1162
1153
|
if (res) {
|
|
1163
1154
|
outObjects?.push(`{ ${res} }`);
|
|
1164
1155
|
}
|
|
@@ -1204,8 +1195,8 @@ function handleObjectLiteralExpression(node, ctx, currObj, outObjects, funcs) {
|
|
|
1204
1195
|
throw "You can't have method declarations inside an object that is not being assigned to a variable";
|
|
1205
1196
|
}
|
|
1206
1197
|
output += `
|
|
1207
|
-
|
|
1208
|
-
`)
|
|
1198
|
+
${funcs.map((func) => `${objectName}.${func}`).join(`
|
|
1199
|
+
`)}`;
|
|
1209
1200
|
}
|
|
1210
1201
|
return output;
|
|
1211
1202
|
}
|
|
@@ -1243,7 +1234,7 @@ NodeHandler.register(ts12.SyntaxKind.ForStatement, (node) => {
|
|
|
1243
1234
|
].join(`
|
|
1244
1235
|
`);
|
|
1245
1236
|
}
|
|
1246
|
-
const incrementedStateVarName =
|
|
1237
|
+
const incrementedStateVarName = `state_${(Date.now() * Math.random()).toFixed(0).slice(0, 6)}`;
|
|
1247
1238
|
const output = [
|
|
1248
1239
|
`${incrementedStateVarName} = 1`,
|
|
1249
1240
|
`${initializer}`,
|
|
@@ -1324,7 +1315,7 @@ else
|
|
|
1324
1315
|
end if`;
|
|
1325
1316
|
return output;
|
|
1326
1317
|
});
|
|
1327
|
-
NodeHandler.register(ts12.SyntaxKind.WhileStatement, (node
|
|
1318
|
+
NodeHandler.register(ts12.SyntaxKind.WhileStatement, (node) => {
|
|
1328
1319
|
const expression = NodeHandler.handle(node.expression);
|
|
1329
1320
|
const labelIf = ts12.isLabeledStatement(node.parent) ? ` if ${node.parent.label.text}Broke then break` : "";
|
|
1330
1321
|
return [
|
|
@@ -1335,7 +1326,7 @@ NodeHandler.register(ts12.SyntaxKind.WhileStatement, (node, ctx) => {
|
|
|
1335
1326
|
].join(`
|
|
1336
1327
|
`);
|
|
1337
1328
|
});
|
|
1338
|
-
NodeHandler.register(ts12.SyntaxKind.DoStatement, (node
|
|
1329
|
+
NodeHandler.register(ts12.SyntaxKind.DoStatement, (node) => {
|
|
1339
1330
|
const expression = NodeHandler.handle(node.expression);
|
|
1340
1331
|
const labelIf = ts12.isLabeledStatement(node.parent) ? ` if ${node.parent.label.text}Broke then break` : "";
|
|
1341
1332
|
return [
|
|
@@ -1348,7 +1339,7 @@ NodeHandler.register(ts12.SyntaxKind.DoStatement, (node, ctx) => {
|
|
|
1348
1339
|
].join(`
|
|
1349
1340
|
`);
|
|
1350
1341
|
});
|
|
1351
|
-
NodeHandler.register(ts12.SyntaxKind.ContinueStatement, (
|
|
1342
|
+
NodeHandler.register(ts12.SyntaxKind.ContinueStatement, (_node) => {
|
|
1352
1343
|
return "continue";
|
|
1353
1344
|
});
|
|
1354
1345
|
NodeHandler.register(ts12.SyntaxKind.BreakStatement, (node) => {
|
|
@@ -1376,7 +1367,7 @@ ${NodeHandler.handle(node.statement)}`;
|
|
|
1376
1367
|
|
|
1377
1368
|
// src/visitors/variables.ts
|
|
1378
1369
|
import ts13 from "typescript";
|
|
1379
|
-
function handleVariableDeclaration(node
|
|
1370
|
+
function handleVariableDeclaration(node) {
|
|
1380
1371
|
const left = NodeHandler.handle(node.name);
|
|
1381
1372
|
const initializerType = node.initializer ? checker.getTypeAtLocation(node.initializer) : undefined;
|
|
1382
1373
|
if (ts13.isPropertyDeclaration(node) && initializerType?.flags === ts13.TypeFlags.Object && !node.modifiers?.some((mod) => mod.kind === ts13.SyntaxKind.StaticKeyword) && !ts13.isFunctionLike(node.initializer)) {
|
|
@@ -1384,16 +1375,16 @@ function handleVariableDeclaration(node, ctx) {
|
|
|
1384
1375
|
Initialize them in the constructor instead`);
|
|
1385
1376
|
}
|
|
1386
1377
|
let right = node.initializer ? NodeHandler.handle(node.initializer) || "null" : "null";
|
|
1387
|
-
if (right
|
|
1378
|
+
if (right !== "null" && nodeIsFunctionReference(node.initializer, initializerType)) {
|
|
1388
1379
|
right = asRef(right);
|
|
1389
1380
|
}
|
|
1390
1381
|
return `${left} = ${right}`;
|
|
1391
1382
|
}
|
|
1392
|
-
NodeHandler.register(ts13.SyntaxKind.VariableDeclarationList, (node
|
|
1393
|
-
return node.declarations.map((decl) => handleVariableDeclaration(decl
|
|
1383
|
+
NodeHandler.register(ts13.SyntaxKind.VariableDeclarationList, (node) => {
|
|
1384
|
+
return node.declarations.map((decl) => handleVariableDeclaration(decl)).join(`
|
|
1394
1385
|
`);
|
|
1395
1386
|
});
|
|
1396
|
-
NodeHandler.register(ts13.SyntaxKind.VariableStatement, (node
|
|
1387
|
+
NodeHandler.register(ts13.SyntaxKind.VariableStatement, (node) => {
|
|
1397
1388
|
if (node.modifiers?.some((modifier) => modifier.kind === ts13.SyntaxKind.DeclareKeyword))
|
|
1398
1389
|
return "";
|
|
1399
1390
|
return NodeHandler.handle(node.declarationList);
|
|
@@ -1404,7 +1395,7 @@ NodeHandler.register(ts13.SyntaxKind.EnumDeclaration, (node) => {
|
|
|
1404
1395
|
const members = [];
|
|
1405
1396
|
function addMember(name, initializer) {
|
|
1406
1397
|
members.push(`${name}: ${initializer}`);
|
|
1407
|
-
if (isNaN(+initializer))
|
|
1398
|
+
if (Number.isNaN(+initializer))
|
|
1408
1399
|
return;
|
|
1409
1400
|
members.push(`${initializer}: ${name}`);
|
|
1410
1401
|
}
|
|
@@ -1426,51 +1417,42 @@ NodeHandler.register(ts13.SyntaxKind.EnumDeclaration, (node) => {
|
|
|
1426
1417
|
return `${node.name.text} = { ${members.join(", ")} }`;
|
|
1427
1418
|
});
|
|
1428
1419
|
|
|
1429
|
-
// src/call_transformers/array.ts
|
|
1430
|
-
CallTransformer.register("Array.slice", (name, args) => {
|
|
1431
|
-
return name.slice(0, name.lastIndexOf(".")) + `[${args[0] ?? ""}:${args[1] ?? ""}]`;
|
|
1432
|
-
});
|
|
1433
|
-
CallTransformer.register("Array.toString", (name) => {
|
|
1434
|
-
const arrayName = name.slice(0, name.lastIndexOf("."));
|
|
1435
|
-
return `str(${arrayName})`;
|
|
1436
|
-
});
|
|
1437
|
-
|
|
1438
1420
|
// src/call_transformers/object.ts
|
|
1439
|
-
CallTransformer.register("ObjectConstructor.hasOwn", (
|
|
1421
|
+
CallTransformer.register("ObjectConstructor.hasOwn", (_name, args) => {
|
|
1440
1422
|
if (args.length < 2)
|
|
1441
1423
|
throw "Invalid argument count";
|
|
1442
1424
|
return `${args[0]}.hasIndex(${args[1]})`;
|
|
1443
1425
|
});
|
|
1444
|
-
CallTransformer.register("ObjectConstructor.assign", (
|
|
1426
|
+
CallTransformer.register("ObjectConstructor.assign", (_name, args) => {
|
|
1445
1427
|
if (args.length < 2)
|
|
1446
1428
|
throw "Invalid argument count";
|
|
1447
1429
|
return callUtilFunction("assign_objects", args.join(","));
|
|
1448
1430
|
});
|
|
1449
|
-
CallTransformer.register("ObjectConstructor.keys", (
|
|
1431
|
+
CallTransformer.register("ObjectConstructor.keys", (_name, args) => {
|
|
1450
1432
|
return `${args[0]}.indexes`;
|
|
1451
1433
|
});
|
|
1452
|
-
CallTransformer.register("ObjectConstructor.values", (
|
|
1434
|
+
CallTransformer.register("ObjectConstructor.values", (_name, args) => {
|
|
1453
1435
|
return `${args[0]}.values`;
|
|
1454
1436
|
});
|
|
1455
|
-
CallTransformer.register("ObjectConstructor.sum", (
|
|
1437
|
+
CallTransformer.register("ObjectConstructor.sum", (_name, args) => {
|
|
1456
1438
|
return `${args[0]}.sum`;
|
|
1457
1439
|
});
|
|
1458
|
-
CallTransformer.register("ObjectConstructor.shuffle", (
|
|
1440
|
+
CallTransformer.register("ObjectConstructor.shuffle", (_name, args) => {
|
|
1459
1441
|
return `${args[0]}.shuffle`;
|
|
1460
1442
|
});
|
|
1461
|
-
CallTransformer.register("ObjectConstructor.replace", (
|
|
1443
|
+
CallTransformer.register("ObjectConstructor.replace", (_name, args) => {
|
|
1462
1444
|
return `${args[0]}.replace(${args.slice(1).join(",")})`;
|
|
1463
1445
|
});
|
|
1464
|
-
CallTransformer.register("ObjectConstructor.remove", (
|
|
1446
|
+
CallTransformer.register("ObjectConstructor.remove", (_name, args) => {
|
|
1465
1447
|
return `${args[0]}.remove(${args[1]})`;
|
|
1466
1448
|
});
|
|
1467
|
-
CallTransformer.register("ObjectConstructor.shift", (
|
|
1449
|
+
CallTransformer.register("ObjectConstructor.shift", (_name, args) => {
|
|
1468
1450
|
return `${args[0]}.pull`;
|
|
1469
1451
|
});
|
|
1470
|
-
CallTransformer.register("ObjectConstructor.size", (
|
|
1452
|
+
CallTransformer.register("ObjectConstructor.size", (_name, args) => {
|
|
1471
1453
|
return `${args[0]}.len`;
|
|
1472
1454
|
});
|
|
1473
|
-
CallTransformer.register("ObjectConstructor.indexOf", (
|
|
1455
|
+
CallTransformer.register("ObjectConstructor.indexOf", (_name, args) => {
|
|
1474
1456
|
return `${args[0]}.indexOf(${args[1]})`;
|
|
1475
1457
|
});
|
|
1476
1458
|
CallTransformer.register("Object.toString", (name) => {
|
|
@@ -1478,14 +1460,6 @@ CallTransformer.register("Object.toString", (name) => {
|
|
|
1478
1460
|
return `str(${objectName})`;
|
|
1479
1461
|
});
|
|
1480
1462
|
|
|
1481
|
-
// src/call_transformers/string.ts
|
|
1482
|
-
CallTransformer.register("String.slice", (name, args) => {
|
|
1483
|
-
return name.slice(0, name.lastIndexOf(".")) + `[${args[0] ?? ""}:${args[1] ?? ""}]`;
|
|
1484
|
-
});
|
|
1485
|
-
CallTransformer.register("String.toString", (name) => {
|
|
1486
|
-
return name.slice(0, name.lastIndexOf("."));
|
|
1487
|
-
});
|
|
1488
|
-
|
|
1489
1463
|
// src/transpiler.ts
|
|
1490
1464
|
var program;
|
|
1491
1465
|
var checker;
|
|
@@ -1628,6 +1602,12 @@ var extensionFunctions = {
|
|
|
1628
1602
|
"end function"
|
|
1629
1603
|
].join(`
|
|
1630
1604
|
`),
|
|
1605
|
+
"Array.toString": `list.toString = function
|
|
1606
|
+
return str(self)
|
|
1607
|
+
end function`,
|
|
1608
|
+
"Array.slice": `list.slice = function(a, b)
|
|
1609
|
+
return self[a:b]
|
|
1610
|
+
end function`,
|
|
1631
1611
|
"String.startsWith": [
|
|
1632
1612
|
"string.startsWith = function(search, pos = 0)",
|
|
1633
1613
|
"\tif pos < 0 then pos = 0",
|
|
@@ -1670,6 +1650,12 @@ var extensionFunctions = {
|
|
|
1670
1650
|
"end function"
|
|
1671
1651
|
].join(`
|
|
1672
1652
|
`),
|
|
1653
|
+
"String.toString": `string.toString = function
|
|
1654
|
+
return str(self)
|
|
1655
|
+
end function`,
|
|
1656
|
+
"String.slice": `string.slice = function(a, b)
|
|
1657
|
+
return self[a:b]
|
|
1658
|
+
end function`,
|
|
1673
1659
|
"Number.toFixed": [
|
|
1674
1660
|
"number.toFixed = function(digits = 0)",
|
|
1675
1661
|
"\tdigits = floor(digits)",
|
|
@@ -1691,23 +1677,120 @@ var extensionFunctions = {
|
|
|
1691
1677
|
"end function"
|
|
1692
1678
|
].join(`
|
|
1693
1679
|
`),
|
|
1694
|
-
"
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1680
|
+
"Number.toString": `number.toString = function
|
|
1681
|
+
return str(self)
|
|
1682
|
+
end function`,
|
|
1683
|
+
"Function.toString": `funcRef.toString = function
|
|
1684
|
+
return str(@self)
|
|
1685
|
+
end function`
|
|
1686
|
+
};
|
|
1687
|
+
var globalObjects = {
|
|
1688
|
+
MapConstructor: [
|
|
1689
|
+
"Map = {}",
|
|
1690
|
+
"Map.constructor = function(entries)",
|
|
1691
|
+
"\tself.data = {}",
|
|
1692
|
+
"\tif not entries then return self",
|
|
1693
|
+
"\tfor entry in entries",
|
|
1694
|
+
"\t\tself.data[entry[0]] = entry[1]",
|
|
1699
1695
|
"\tend for",
|
|
1700
|
-
"\treturn
|
|
1696
|
+
"\treturn self",
|
|
1697
|
+
"end function",
|
|
1698
|
+
"Map.clear = function",
|
|
1699
|
+
"\tfor key in self.data.indexes",
|
|
1700
|
+
"\t\tself.data.remove(@key)",
|
|
1701
|
+
"\tend for",
|
|
1702
|
+
"end function",
|
|
1703
|
+
"Map.delete = function(key)",
|
|
1704
|
+
"\treturn self.data.remove(key)",
|
|
1705
|
+
"end function",
|
|
1706
|
+
"Map.forEach = function(callback)",
|
|
1707
|
+
"\tfor item in self.data",
|
|
1708
|
+
"\t\tcallback(@item.value, @item.key, self)",
|
|
1709
|
+
"\tend for",
|
|
1710
|
+
"end function",
|
|
1711
|
+
"Map.get = function(key)",
|
|
1712
|
+
"\tif not self.data.hasIndex(@key) then retun null",
|
|
1713
|
+
"\treturn self.data[@key]",
|
|
1714
|
+
"end function",
|
|
1715
|
+
"Map.has = function(key)",
|
|
1716
|
+
"\treturn self.data.hasIndex(@key)",
|
|
1717
|
+
"end function",
|
|
1718
|
+
"Map.set = function(key, value)",
|
|
1719
|
+
"\tself.data[@key] = @value",
|
|
1720
|
+
"\treturn self",
|
|
1721
|
+
"end function",
|
|
1722
|
+
"Map.entries = function",
|
|
1723
|
+
"\tentries = []",
|
|
1724
|
+
"\tfor item in self.data",
|
|
1725
|
+
"\t\tentries.push([@item.key, @item.value])",
|
|
1726
|
+
"\tend for",
|
|
1727
|
+
"\treturn entries",
|
|
1728
|
+
"end function",
|
|
1729
|
+
"Map.keys = function",
|
|
1730
|
+
"\treturn self.data.indexes",
|
|
1731
|
+
"end function",
|
|
1732
|
+
"Map.values = function",
|
|
1733
|
+
"\treturn self.data.values",
|
|
1734
|
+
"end function"
|
|
1735
|
+
].join(`
|
|
1736
|
+
`),
|
|
1737
|
+
SetConstructor: [
|
|
1738
|
+
"Set = {}",
|
|
1739
|
+
"Set.constructor = function(values)",
|
|
1740
|
+
"\tself.data = {}",
|
|
1741
|
+
"\tif not values then return self",
|
|
1742
|
+
"\tfor v in values",
|
|
1743
|
+
"\t\tself.data[@v] = 1",
|
|
1744
|
+
"\tend for",
|
|
1745
|
+
"\treturn self",
|
|
1746
|
+
"end function",
|
|
1747
|
+
"Set.add = function(value)",
|
|
1748
|
+
"\tself.data[@value] = 1",
|
|
1749
|
+
"\treturn self",
|
|
1750
|
+
"end function",
|
|
1751
|
+
"Set.clear = function",
|
|
1752
|
+
"\tfor key in self.data.indexes",
|
|
1753
|
+
"\t\tself.data.remove(@key)",
|
|
1754
|
+
"\tend for",
|
|
1755
|
+
"end function",
|
|
1756
|
+
"Set.delete = function(key)",
|
|
1757
|
+
"\treturn self.data.remove(key)",
|
|
1758
|
+
"end function",
|
|
1759
|
+
"Set.forEach = function(callback)",
|
|
1760
|
+
"\tfor key in self.data.indexes",
|
|
1761
|
+
"\t\tcallback(@key, self)",
|
|
1762
|
+
"\tend for",
|
|
1763
|
+
"end function",
|
|
1764
|
+
"Set.has = function(key)",
|
|
1765
|
+
"\treturn self.data.hasIndex(@key)",
|
|
1766
|
+
"end function",
|
|
1767
|
+
"Set.values = function",
|
|
1768
|
+
"\treturn self.data.indexes",
|
|
1701
1769
|
"end function"
|
|
1702
1770
|
].join(`
|
|
1703
1771
|
`),
|
|
1704
|
-
|
|
1772
|
+
Math: [
|
|
1773
|
+
'Math = { "PI": @pi, "abs": @abs, "acos": @acos, "asin": @asin, "atan": @atan, "ceil": @ceil, "floor": @floor, "cos": @cos, "sin": @sin, "tan": @tan, "sqrt": @sqrt, "sign": @sign, "round": @round, "random": @rnd, "log": @log }',
|
|
1705
1774
|
"Math.max = function(numbers)",
|
|
1706
1775
|
"\tcurr_max = null",
|
|
1707
1776
|
"\tfor num in numbers",
|
|
1708
1777
|
"\t\tif curr_max == null or num > curr_max then curr_max = num",
|
|
1709
1778
|
"\tend for",
|
|
1710
1779
|
"\treturn curr_max",
|
|
1780
|
+
"end function",
|
|
1781
|
+
"Math.min = function(numbers)",
|
|
1782
|
+
"\tcurr_min = null",
|
|
1783
|
+
"\tfor num in numbers",
|
|
1784
|
+
"\t\tif curr_min == null or num < curr_min then curr_min = num",
|
|
1785
|
+
"\tend for",
|
|
1786
|
+
"\treturn curr_min",
|
|
1787
|
+
"end function"
|
|
1788
|
+
].join(`
|
|
1789
|
+
`),
|
|
1790
|
+
Console: [
|
|
1791
|
+
'console = { "clear": @clear_screen }',
|
|
1792
|
+
"console.log = function(data)",
|
|
1793
|
+
'\tprint(data.join(", "))',
|
|
1711
1794
|
"end function"
|
|
1712
1795
|
].join(`
|
|
1713
1796
|
`)
|
|
@@ -1777,19 +1860,19 @@ var utilFunctions = {
|
|
|
1777
1860
|
].join(`
|
|
1778
1861
|
`),
|
|
1779
1862
|
nullish_coalescing_op: `nullish_coalescing_op = function(left, right)
|
|
1780
|
-
if left == null then return @right
|
|
1863
|
+
if @left == null then return @right
|
|
1781
1864
|
return @left
|
|
1782
1865
|
end function`,
|
|
1783
1866
|
or_op: `or_op = function(left, right)
|
|
1784
|
-
if not left then return @right
|
|
1867
|
+
if not @left then return @right
|
|
1785
1868
|
return @left
|
|
1786
1869
|
end function`,
|
|
1787
1870
|
is_type: `is_type = function(value, type)
|
|
1788
|
-
return typeof(value) == type
|
|
1871
|
+
return typeof(@value) == type
|
|
1789
1872
|
end function`,
|
|
1790
1873
|
conditional_expr: `conditional_expr = function(cond, when_true, when_false)
|
|
1791
|
-
if cond then return when_true
|
|
1792
|
-
return when_false
|
|
1874
|
+
if cond then return @when_true
|
|
1875
|
+
return @when_false
|
|
1793
1876
|
end function`
|
|
1794
1877
|
};
|
|
1795
1878
|
var anonFunctionsCreated = 0;
|
|
@@ -1825,7 +1908,7 @@ function transpileProgram(entryFileRelativePath) {
|
|
|
1825
1908
|
process.exit(1);
|
|
1826
1909
|
}
|
|
1827
1910
|
let start = Date.now();
|
|
1828
|
-
const tsconfigPath = findProjectRoot(process.cwd(), "tsconfig.json")
|
|
1911
|
+
const tsconfigPath = `${findProjectRoot(process.cwd(), "tsconfig.json")}/tsconfig.json`;
|
|
1829
1912
|
const res = ts14.readConfigFile(tsconfigPath, ts14.sys.readFile);
|
|
1830
1913
|
const parsed = ts14.parseJsonConfigFileContent(res.config, ts14.sys, path5.dirname(tsconfigPath));
|
|
1831
1914
|
if (!parsed.options.types)
|
|
@@ -1912,7 +1995,7 @@ if (command === "transpile") {
|
|
|
1912
1995
|
content = "";
|
|
1913
1996
|
continue;
|
|
1914
1997
|
}
|
|
1915
|
-
content += statement
|
|
1998
|
+
content += `${statement}
|
|
1916
1999
|
`;
|
|
1917
2000
|
}
|
|
1918
2001
|
if (content.length)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@grey-ts/transpiler",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Transpiles TypeScript into GreyScript",
|
|
5
5
|
"author": "Okka",
|
|
6
6
|
"module": "src/index.ts",
|
|
@@ -34,11 +34,12 @@
|
|
|
34
34
|
"build": "bun test --only-failures && bun run scripts/build.ts"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
|
-
"@
|
|
38
|
-
"@grey-ts/types": "
|
|
37
|
+
"@biomejs/biome": "2.3.14",
|
|
38
|
+
"@grey-ts/types": "^3.0.0",
|
|
39
|
+
"@types/bun": "latest"
|
|
39
40
|
},
|
|
40
41
|
"peerDependencies": {
|
|
41
|
-
"typescript": "^5",
|
|
42
|
+
"typescript": "^5.9.3",
|
|
42
43
|
"@grey-ts/types": "^2.2.0"
|
|
43
44
|
}
|
|
44
45
|
}
|