@grey-ts/transpiler 1.3.0 → 1.4.1
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 +290 -235
- package/package.json +5 -6
package/dist/index.js
CHANGED
|
@@ -149,7 +149,6 @@ var apiNameMap = {
|
|
|
149
149
|
"GreyHack.programPath": "program_path",
|
|
150
150
|
"GreyHack.resetCtfPassword": "reset_ctf_password",
|
|
151
151
|
"GreyHack.getType": "typeof",
|
|
152
|
-
"GreyHack.isType": "is_type",
|
|
153
152
|
"GreyHack.userBankNumber": "user_bank_number",
|
|
154
153
|
"GreyHack.userInput": "user_input",
|
|
155
154
|
"GreyHack.userMailAddress": "user_mail_address",
|
|
@@ -389,6 +388,25 @@ function callUtilFunction(functionName, ...params) {
|
|
|
389
388
|
utilitiesToInsert.set(functionName, utilFunctions[functionName]);
|
|
390
389
|
return `${functionName}(${params.join(", ")})`;
|
|
391
390
|
}
|
|
391
|
+
var assignmentOperators = new Set([
|
|
392
|
+
"=",
|
|
393
|
+
"??=",
|
|
394
|
+
"||=",
|
|
395
|
+
"-=",
|
|
396
|
+
"+="
|
|
397
|
+
]);
|
|
398
|
+
function valueIsBeingAssignedToNode(node) {
|
|
399
|
+
if (ts3.hasOnlyExpressionInitializer(node.parent) && node === node.parent.name)
|
|
400
|
+
return true;
|
|
401
|
+
const assignAncestor = ts3.findAncestor(node, (ancestor) => {
|
|
402
|
+
if (ancestor.parent && ts3.isBinaryExpression(ancestor.parent) && ancestor === ancestor.parent.left) {
|
|
403
|
+
const token = ts3.tokenToString(ancestor.parent.operatorToken.kind) || ancestor.parent.operatorToken.getText();
|
|
404
|
+
return assignmentOperators.has(token);
|
|
405
|
+
}
|
|
406
|
+
return false;
|
|
407
|
+
});
|
|
408
|
+
return !!assignAncestor;
|
|
409
|
+
}
|
|
392
410
|
|
|
393
411
|
// src/visitors/assignments.ts
|
|
394
412
|
import ts4 from "typescript";
|
|
@@ -497,7 +515,7 @@ end function`;
|
|
|
497
515
|
});
|
|
498
516
|
|
|
499
517
|
// src/visitors/expressions.ts
|
|
500
|
-
import
|
|
518
|
+
import ts7 from "typescript";
|
|
501
519
|
|
|
502
520
|
// src/call_transformers/callTransformer.ts
|
|
503
521
|
import path2 from "node:path";
|
|
@@ -510,10 +528,10 @@ class CallTransformer {
|
|
|
510
528
|
this.handlers.set(symbolFullName, handler);
|
|
511
529
|
}
|
|
512
530
|
static handle(symbolFullName, functionName, callArgs, node, ctx) {
|
|
513
|
-
if (symbolFullName in
|
|
531
|
+
if (symbolFullName in extensionFunctions) {
|
|
514
532
|
if (symbolFullName.startsWith("Math"))
|
|
515
533
|
utilitiesToInsert.set("create_math", "Math = {}");
|
|
516
|
-
utilitiesToInsert.set(symbolFullName,
|
|
534
|
+
utilitiesToInsert.set(symbolFullName, extensionFunctions[symbolFullName]);
|
|
517
535
|
const params = callArgs.length ? `(${callArgs.join(",")})` : "";
|
|
518
536
|
return `${functionName}${params}`;
|
|
519
537
|
}
|
|
@@ -544,6 +562,9 @@ CallTransformer.register("GreyHack.include", (name, args, node, ctx) => {
|
|
|
544
562
|
}
|
|
545
563
|
return "";
|
|
546
564
|
});
|
|
565
|
+
CallTransformer.register("GreyHack.isType", (name, args) => {
|
|
566
|
+
return callUtilFunction("is_type", args.join(","));
|
|
567
|
+
});
|
|
547
568
|
CallTransformer.register("Boolean", (name, args) => {
|
|
548
569
|
if (!args.length)
|
|
549
570
|
return "0";
|
|
@@ -560,129 +581,12 @@ CallTransformer.register("String", (name, args) => {
|
|
|
560
581
|
return `str(${args[0]})`;
|
|
561
582
|
});
|
|
562
583
|
|
|
563
|
-
// src/visitors/objects.ts
|
|
564
|
-
import ts7 from "typescript";
|
|
565
|
-
var assignmentOperators = new Set([
|
|
566
|
-
"=",
|
|
567
|
-
"??=",
|
|
568
|
-
"||=",
|
|
569
|
-
"-=",
|
|
570
|
-
"+="
|
|
571
|
-
]);
|
|
572
|
-
function valueIsBeingAssignedToNode(node) {
|
|
573
|
-
const assignAncestor = ts7.findAncestor(node, (ancestor) => {
|
|
574
|
-
if (ancestor.parent && ts7.isBinaryExpression(ancestor.parent) && ancestor === ancestor.parent.left) {
|
|
575
|
-
const token = ts7.tokenToString(ancestor.parent.operatorToken.kind) || ancestor.parent.operatorToken.getText();
|
|
576
|
-
return assignmentOperators.has(token);
|
|
577
|
-
}
|
|
578
|
-
return false;
|
|
579
|
-
});
|
|
580
|
-
return !!assignAncestor;
|
|
581
|
-
}
|
|
582
|
-
NodeHandler.register(ts7.SyntaxKind.PropertyAccessExpression, (node, ctx) => {
|
|
583
|
-
const left = NodeHandler.handle(node.expression);
|
|
584
|
-
let right = NodeHandler.handle(node.name);
|
|
585
|
-
right = replaceIdentifier(right, checker.getTypeAtLocation(node.expression), right);
|
|
586
|
-
const nodeSymbol = checker.getSymbolAtLocation(node);
|
|
587
|
-
if (ctx.namespaceImports[ctx.currentFilePath]?.has(left))
|
|
588
|
-
return right;
|
|
589
|
-
let getSafely = !!node.questionDotToken && !ts7.isNonNullExpression(node.parent);
|
|
590
|
-
const rightType = checker.getTypeAtLocation(node.name);
|
|
591
|
-
if (rightType.isUnion()) {
|
|
592
|
-
const hasUndefined = rightType.types.some((t) => t.flags === ts7.TypeFlags.Undefined);
|
|
593
|
-
if (hasUndefined)
|
|
594
|
-
getSafely = true;
|
|
595
|
-
}
|
|
596
|
-
if (!valueIsBeingAssignedToNode(node) && getSafely)
|
|
597
|
-
return callUtilFunction("get_property", left, `"${right}"`);
|
|
598
|
-
let output = `${left}.${right}`;
|
|
599
|
-
output = replacePropertyAccess(output, nodeSymbol);
|
|
600
|
-
if (nodeIsFunctionReference(node))
|
|
601
|
-
output = asRef(output);
|
|
602
|
-
return output;
|
|
603
|
-
});
|
|
604
|
-
NodeHandler.register(ts7.SyntaxKind.ElementAccessExpression, (node, ctx) => {
|
|
605
|
-
const left = NodeHandler.handle(node.expression);
|
|
606
|
-
let right;
|
|
607
|
-
if (ts7.isStringLiteral(node.argumentExpression)) {
|
|
608
|
-
const leftType = checker.getTypeAtLocation(node.expression);
|
|
609
|
-
right = `"${replaceIdentifier(node.argumentExpression.text, leftType, node.argumentExpression.text)}"`;
|
|
610
|
-
} else {
|
|
611
|
-
right = NodeHandler.handle(node.argumentExpression);
|
|
612
|
-
}
|
|
613
|
-
if (!valueIsBeingAssignedToNode(node) && !ts7.isNumericLiteral(node.argumentExpression)) {
|
|
614
|
-
return callUtilFunction("get_property", left, `${right}`);
|
|
615
|
-
}
|
|
616
|
-
return `${left}[${right}]`;
|
|
617
|
-
});
|
|
618
|
-
function handleObjectLiteralExpression(node, ctx, currObj, outObjects, funcs) {
|
|
619
|
-
currObj ??= [];
|
|
620
|
-
outObjects ??= [];
|
|
621
|
-
funcs ??= [];
|
|
622
|
-
const objectName = ts7.hasOnlyExpressionInitializer(node.parent) ? NodeHandler.handle(node.parent.name) : ts7.isBinaryExpression(node.parent) && node === node.parent.right ? NodeHandler.handle(node.parent.left) : "";
|
|
623
|
-
function pushObj() {
|
|
624
|
-
if (!currObj?.length)
|
|
625
|
-
return "";
|
|
626
|
-
const res = currObj.filter((s) => s != "").join(",");
|
|
627
|
-
if (res) {
|
|
628
|
-
outObjects?.push(`{ ${res} }`);
|
|
629
|
-
}
|
|
630
|
-
currObj.length = 0;
|
|
631
|
-
return res;
|
|
632
|
-
}
|
|
633
|
-
for (const item of node.properties) {
|
|
634
|
-
if (ts7.isFunctionLike(item)) {
|
|
635
|
-
if (!objectName)
|
|
636
|
-
throw "You can't have method declarations inside an object that is not being assigned to a variable";
|
|
637
|
-
funcs.push(`${objectName}.${NodeHandler.handle(item)}`);
|
|
638
|
-
continue;
|
|
639
|
-
}
|
|
640
|
-
if (ts7.isPropertyAssignment(item) && ts7.isFunctionLike(item.initializer)) {
|
|
641
|
-
if (!objectName)
|
|
642
|
-
throw "You can't have method declarations inside an object that is not being assigned to a variable";
|
|
643
|
-
funcs.push(`${objectName}.${NodeHandler.handle(item.name)} = ${NodeHandler.handle(item.initializer)}`);
|
|
644
|
-
continue;
|
|
645
|
-
}
|
|
646
|
-
if (ts7.isSpreadAssignment(item)) {
|
|
647
|
-
if (ts7.isObjectLiteralExpression(item.expression)) {
|
|
648
|
-
handleObjectLiteralExpression(item.expression, ctx, currObj, outObjects);
|
|
649
|
-
continue;
|
|
650
|
-
}
|
|
651
|
-
if (ts7.isIdentifier(item.expression)) {
|
|
652
|
-
pushObj();
|
|
653
|
-
outObjects.push(NodeHandler.handle(item.expression));
|
|
654
|
-
continue;
|
|
655
|
-
}
|
|
656
|
-
if (ts7.isArrayLiteralExpression(item.expression)) {
|
|
657
|
-
pushObj();
|
|
658
|
-
outObjects.push(NodeHandler.handle(item.expression));
|
|
659
|
-
continue;
|
|
660
|
-
}
|
|
661
|
-
}
|
|
662
|
-
currObj.push(NodeHandler.handle(item));
|
|
663
|
-
}
|
|
664
|
-
pushObj();
|
|
665
|
-
if (!outObjects.length)
|
|
666
|
-
outObjects.push("{}");
|
|
667
|
-
let output = outObjects[0];
|
|
668
|
-
if (outObjects.length > 1) {
|
|
669
|
-
output = callUtilFunction("assign_objects", output, `[${outObjects.slice(1).join(",")}]`);
|
|
670
|
-
}
|
|
671
|
-
if (funcs.length) {
|
|
672
|
-
output += `
|
|
673
|
-
` + funcs.join(`
|
|
674
|
-
`);
|
|
675
|
-
}
|
|
676
|
-
return output;
|
|
677
|
-
}
|
|
678
|
-
NodeHandler.register(ts7.SyntaxKind.ObjectLiteralExpression, handleObjectLiteralExpression);
|
|
679
|
-
|
|
680
584
|
// src/visitors/expressions.ts
|
|
681
585
|
function hasRestParam(params) {
|
|
682
586
|
if (!params.length)
|
|
683
587
|
return false;
|
|
684
588
|
const lastParam = params[params.length - 1];
|
|
685
|
-
return !!(lastParam.valueDeclaration &&
|
|
589
|
+
return !!(lastParam.valueDeclaration && ts7.isParameter(lastParam.valueDeclaration) && lastParam.valueDeclaration.dotDotDotToken);
|
|
686
590
|
}
|
|
687
591
|
function handleCallArgs(callNode, ctx) {
|
|
688
592
|
const args = callNode.arguments;
|
|
@@ -706,11 +610,11 @@ function handleCallArgs(callNode, ctx) {
|
|
|
706
610
|
}
|
|
707
611
|
}
|
|
708
612
|
for (const arg of args) {
|
|
709
|
-
if (!
|
|
613
|
+
if (!ts7.isSpreadElement(arg)) {
|
|
710
614
|
pushArgs(false, NodeHandler.handle(arg));
|
|
711
615
|
continue;
|
|
712
616
|
}
|
|
713
|
-
if (
|
|
617
|
+
if (ts7.isArrayLiteralExpression(arg.expression)) {
|
|
714
618
|
const arrayItems = [];
|
|
715
619
|
const outArrs = [];
|
|
716
620
|
handleArrayLiteralExpression(arg.expression, ctx, arrayItems, outArrs);
|
|
@@ -762,7 +666,7 @@ function handleCallArgs(callNode, ctx) {
|
|
|
762
666
|
result.push("[]");
|
|
763
667
|
return result;
|
|
764
668
|
}
|
|
765
|
-
NodeHandler.register(
|
|
669
|
+
NodeHandler.register(ts7.SyntaxKind.CallExpression, (node, ctx) => {
|
|
766
670
|
const args = handleCallArgs(node, ctx);
|
|
767
671
|
let name = NodeHandler.handle(node.expression);
|
|
768
672
|
const type = checker.getTypeAtLocation(node.expression);
|
|
@@ -774,14 +678,11 @@ NodeHandler.register(ts8.SyntaxKind.CallExpression, (node, ctx) => {
|
|
|
774
678
|
const transformed = CallTransformer.handle(symbolFullName, name, args, node, ctx);
|
|
775
679
|
if (transformed !== null)
|
|
776
680
|
return transformed;
|
|
777
|
-
if (name === "is_type" && !utilitiesToInsert.has("is_type")) {
|
|
778
|
-
utilitiesToInsert.set("is_type", utilFunctions["is_type"]);
|
|
779
|
-
}
|
|
780
681
|
if (!args.length)
|
|
781
682
|
return name;
|
|
782
683
|
return `${name}(${args.join(", ")})`;
|
|
783
684
|
});
|
|
784
|
-
NodeHandler.register(
|
|
685
|
+
NodeHandler.register(ts7.SyntaxKind.NewExpression, (node, ctx) => {
|
|
785
686
|
const args = handleCallArgs(node, ctx);
|
|
786
687
|
let output = `(new ${NodeHandler.handle(node.expression)}).constructor`;
|
|
787
688
|
if (args.length)
|
|
@@ -791,12 +692,12 @@ NodeHandler.register(ts8.SyntaxKind.NewExpression, (node, ctx) => {
|
|
|
791
692
|
function shouldHaveOuterPrefix(node, operator) {
|
|
792
693
|
if (!assignmentOperators.has(operator))
|
|
793
694
|
return false;
|
|
794
|
-
if (!
|
|
695
|
+
if (!ts7.isIdentifier(node.left))
|
|
795
696
|
return false;
|
|
796
|
-
const functionAncestor =
|
|
697
|
+
const functionAncestor = ts7.findAncestor(node.parent, (n) => ts7.isFunctionLike(n));
|
|
797
698
|
if (!functionAncestor)
|
|
798
699
|
return false;
|
|
799
|
-
if (!
|
|
700
|
+
if (!ts7.findAncestor(functionAncestor.parent, (n) => ts7.isFunctionLike(n)))
|
|
800
701
|
return false;
|
|
801
702
|
const leftSymbol = checker.getSymbolAtLocation(node.left);
|
|
802
703
|
if (!leftSymbol?.valueDeclaration)
|
|
@@ -806,26 +707,26 @@ function shouldHaveOuterPrefix(node, operator) {
|
|
|
806
707
|
function isAssignmentChain(node, operator) {
|
|
807
708
|
if (!assignmentOperators.has(operator))
|
|
808
709
|
return false;
|
|
809
|
-
if (
|
|
710
|
+
if (ts7.isBinaryExpression(node.right) && assignmentOperators.has(ts7.tokenToString(node.right.operatorToken.kind) || ""))
|
|
810
711
|
return true;
|
|
811
|
-
if (
|
|
712
|
+
if (ts7.hasOnlyExpressionInitializer(node.parent))
|
|
812
713
|
return true;
|
|
813
714
|
return false;
|
|
814
715
|
}
|
|
815
|
-
NodeHandler.register(
|
|
716
|
+
NodeHandler.register(ts7.SyntaxKind.BinaryExpression, (node) => {
|
|
816
717
|
let operatorToken = getOperatorToken(node.operatorToken) || node.operatorToken.getText();
|
|
817
718
|
if (isAssignmentChain(node, operatorToken))
|
|
818
719
|
throw `Assignment chaining is not supported`;
|
|
819
720
|
let right = NodeHandler.handle(node.right);
|
|
820
721
|
if (nodeIsFunctionReference(node.right))
|
|
821
722
|
right = asRef(right);
|
|
822
|
-
if (
|
|
723
|
+
if (ts7.isPropertyAccessExpression(node.left)) {
|
|
823
724
|
const leftType = checker.getTypeAtLocation(node.left.expression);
|
|
824
725
|
const symbol = leftType.getProperty(node.left.name.text);
|
|
825
|
-
if (symbol?.declarations?.some((decl) =>
|
|
726
|
+
if (symbol?.declarations?.some((decl) => ts7.isSetAccessor(decl))) {
|
|
826
727
|
const objName = NodeHandler.handle(node.left.expression);
|
|
827
728
|
const key = node.left.name.text;
|
|
828
|
-
if (operatorToken !== "=" && symbol.declarations.some((decl) =>
|
|
729
|
+
if (operatorToken !== "=" && symbol.declarations.some((decl) => ts7.isGetAccessor(decl)))
|
|
829
730
|
throw `Can't handle '${operatorToken}' because '${objName}' doesn't have a getter '${key}'`;
|
|
830
731
|
if (operatorToken === "+=" || operatorToken === "-=") {
|
|
831
732
|
right = `${objName}.${key} ${operatorToken[0]} ${right}`;
|
|
@@ -840,22 +741,12 @@ NodeHandler.register(ts8.SyntaxKind.BinaryExpression, (node) => {
|
|
|
840
741
|
left = "outer." + left;
|
|
841
742
|
if (nodeIsFunctionReference(node.left))
|
|
842
743
|
left = asRef(left);
|
|
843
|
-
if (operatorToken === "or" &&
|
|
744
|
+
if (operatorToken === "or" && ts7.hasOnlyExpressionInitializer(node.parent)) {
|
|
844
745
|
return callUtilFunction("or_op", left, right);
|
|
845
746
|
}
|
|
846
|
-
if (operatorToken === "instanceof") {
|
|
847
|
-
const rightSymbol = checker.getSymbolAtLocation(node.right);
|
|
848
|
-
const classIdMember = rightSymbol?.members?.get(ts8.escapeLeadingUnderscores("classID"));
|
|
849
|
-
if (!classIdMember) {
|
|
850
|
-
throw `Can't handle this 'instanceof' operator because '${right}' doesn't have a 'classID' member, which is needed in GreyScript to check a type`;
|
|
851
|
-
}
|
|
852
|
-
const declaration = classIdMember.valueDeclaration;
|
|
853
|
-
if (!declaration || !("initializer" in declaration) || !declaration.initializer) {
|
|
854
|
-
throw `The 'classID' property of '${right}' isn't initialized`;
|
|
855
|
-
}
|
|
856
|
-
return `${left}.classID == typeof(${right})`;
|
|
857
|
-
}
|
|
858
747
|
switch (operatorToken) {
|
|
748
|
+
case "instanceof":
|
|
749
|
+
return `${left} isa ${right}`;
|
|
859
750
|
case "??":
|
|
860
751
|
return callUtilFunction("nullish_coalescing_op", left, right);
|
|
861
752
|
case "??=":
|
|
@@ -882,41 +773,44 @@ NodeHandler.register(ts8.SyntaxKind.BinaryExpression, (node) => {
|
|
|
882
773
|
operatorToken = "^";
|
|
883
774
|
return `${left} ${operatorToken} ${right}`;
|
|
884
775
|
});
|
|
885
|
-
NodeHandler.register(
|
|
776
|
+
NodeHandler.register(ts7.SyntaxKind.ParenthesizedExpression, (node) => {
|
|
886
777
|
return `(${NodeHandler.handle(node.expression)})`;
|
|
887
778
|
});
|
|
888
779
|
function handleUnaryExpression(node) {
|
|
889
780
|
const operand = NodeHandler.handle(node.operand);
|
|
890
|
-
const operator =
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
781
|
+
const operator = ts7.tokenToString(node.operator);
|
|
782
|
+
switch (operator) {
|
|
783
|
+
case "++":
|
|
784
|
+
case "--":
|
|
785
|
+
if (ts7.hasOnlyExpressionInitializer(node.parent) || ts7.isBinaryExpression(node.parent))
|
|
786
|
+
throw `Operator ${operator} is not supported for this kind of expression yet`;
|
|
787
|
+
return `${operand} = ${operand} ${operator[0]} 1`;
|
|
788
|
+
case "!":
|
|
789
|
+
if (ts7.isPrefixUnaryExpression(node.parent) && ts7.tokenToString(node.parent.operator) === "!") {
|
|
790
|
+
return `(not ${operand})`;
|
|
791
|
+
}
|
|
792
|
+
return `not ${operand}`;
|
|
793
|
+
case "-":
|
|
794
|
+
return `-${operand}`;
|
|
795
|
+
case "+":
|
|
796
|
+
return `str(${operand}).val`;
|
|
797
|
+
case "~":
|
|
798
|
+
return `bitwise("~", ${operand})`;
|
|
799
|
+
default:
|
|
800
|
+
throw `Couldn't handle this UnaryExpression: ${node.getText()}`;
|
|
801
|
+
}
|
|
908
802
|
}
|
|
909
|
-
NodeHandler.register(
|
|
910
|
-
NodeHandler.register(
|
|
803
|
+
NodeHandler.register(ts7.SyntaxKind.PrefixUnaryExpression, handleUnaryExpression);
|
|
804
|
+
NodeHandler.register(ts7.SyntaxKind.PostfixUnaryExpression, handleUnaryExpression);
|
|
911
805
|
function handleArrayLiteralExpression(node, ctx, itemStrings, out) {
|
|
912
806
|
itemStrings ??= [];
|
|
913
807
|
out ??= [];
|
|
914
808
|
for (const item of node.elements) {
|
|
915
|
-
if (!
|
|
809
|
+
if (!ts7.isSpreadElement(item)) {
|
|
916
810
|
itemStrings.push(NodeHandler.handle(item));
|
|
917
811
|
continue;
|
|
918
812
|
}
|
|
919
|
-
if (
|
|
813
|
+
if (ts7.isArrayLiteralExpression(item.expression)) {
|
|
920
814
|
handleArrayLiteralExpression(item.expression, ctx, itemStrings, out);
|
|
921
815
|
continue;
|
|
922
816
|
}
|
|
@@ -926,14 +820,14 @@ function handleArrayLiteralExpression(node, ctx, itemStrings, out) {
|
|
|
926
820
|
}
|
|
927
821
|
out.push(NodeHandler.handle(item.expression));
|
|
928
822
|
}
|
|
929
|
-
if ((!out.length || itemStrings.length) && !
|
|
823
|
+
if ((!out.length || itemStrings.length) && !ts7.isSpreadElement(node.parent)) {
|
|
930
824
|
out.push(`[${itemStrings.join(",")}]`);
|
|
931
825
|
itemStrings.length = 0;
|
|
932
826
|
}
|
|
933
827
|
return out.join(" + ");
|
|
934
828
|
}
|
|
935
|
-
NodeHandler.register(
|
|
936
|
-
NodeHandler.register(
|
|
829
|
+
NodeHandler.register(ts7.SyntaxKind.ArrayLiteralExpression, handleArrayLiteralExpression);
|
|
830
|
+
NodeHandler.register(ts7.SyntaxKind.TemplateExpression, (node) => {
|
|
937
831
|
const head = NodeHandler.handle(node.head);
|
|
938
832
|
const strings = [
|
|
939
833
|
...head ? [`"${head}"`] : [],
|
|
@@ -942,22 +836,22 @@ NodeHandler.register(ts8.SyntaxKind.TemplateExpression, (node) => {
|
|
|
942
836
|
const output = strings.join(" + ");
|
|
943
837
|
return output;
|
|
944
838
|
});
|
|
945
|
-
NodeHandler.register(
|
|
839
|
+
NodeHandler.register(ts7.SyntaxKind.TemplateHead, (node) => {
|
|
946
840
|
return transformString(node.text);
|
|
947
841
|
});
|
|
948
|
-
NodeHandler.register(
|
|
842
|
+
NodeHandler.register(ts7.SyntaxKind.TemplateSpan, (node) => {
|
|
949
843
|
let output = NodeHandler.handle(node.expression);
|
|
950
|
-
if (
|
|
844
|
+
if (ts7.isBinaryExpression(node.expression))
|
|
951
845
|
output = `str(${output})`;
|
|
952
846
|
if (node.literal.text)
|
|
953
847
|
output += ` + "${transformString(node.literal.text)}"`;
|
|
954
848
|
return output;
|
|
955
849
|
});
|
|
956
|
-
NodeHandler.register(
|
|
850
|
+
NodeHandler.register(ts7.SyntaxKind.NoSubstitutionTemplateLiteral, (node) => {
|
|
957
851
|
return `"${transformString(node.text)}"`;
|
|
958
852
|
});
|
|
959
|
-
NodeHandler.register(
|
|
960
|
-
if (
|
|
853
|
+
NodeHandler.register(ts7.SyntaxKind.ConditionalExpression, (node) => {
|
|
854
|
+
if (ts7.isCallExpression(node.whenTrue) || ts7.isCallExpression(node.whenFalse)) {
|
|
961
855
|
throw "Call expressions are not supported inside conditional expressions yet";
|
|
962
856
|
}
|
|
963
857
|
const condition = NodeHandler.handle(node.condition);
|
|
@@ -965,28 +859,28 @@ NodeHandler.register(ts8.SyntaxKind.ConditionalExpression, (node) => {
|
|
|
965
859
|
const whenFalse = NodeHandler.handle(node.whenFalse);
|
|
966
860
|
return callUtilFunction("conditional_expr", condition, whenTrue, whenFalse);
|
|
967
861
|
});
|
|
968
|
-
NodeHandler.register(
|
|
862
|
+
NodeHandler.register(ts7.SyntaxKind.ExpressionStatement, (node) => {
|
|
969
863
|
return NodeHandler.handle(node.expression);
|
|
970
864
|
});
|
|
971
|
-
NodeHandler.register(
|
|
865
|
+
NodeHandler.register(ts7.SyntaxKind.NonNullExpression, (node) => {
|
|
972
866
|
return NodeHandler.handle(node.expression);
|
|
973
867
|
});
|
|
974
|
-
NodeHandler.register(
|
|
868
|
+
NodeHandler.register(ts7.SyntaxKind.AsExpression, (node) => {
|
|
975
869
|
return NodeHandler.handle(node.expression);
|
|
976
870
|
});
|
|
977
|
-
NodeHandler.register(
|
|
978
|
-
if (
|
|
871
|
+
NodeHandler.register(ts7.SyntaxKind.DeleteExpression, (node) => {
|
|
872
|
+
if (ts7.isPropertyAccessExpression(node.expression)) {
|
|
979
873
|
const pnode = node.expression;
|
|
980
874
|
const left = NodeHandler.handle(pnode.expression);
|
|
981
875
|
const leftType = checker.getTypeAtLocation(pnode.expression);
|
|
982
876
|
const right = replaceIdentifier(NodeHandler.handle(pnode.name), leftType, pnode.name.text);
|
|
983
877
|
return `${left}.remove("${right}")`;
|
|
984
878
|
}
|
|
985
|
-
if (
|
|
879
|
+
if (ts7.isElementAccessExpression(node.expression)) {
|
|
986
880
|
const pnode = node.expression;
|
|
987
881
|
const left = NodeHandler.handle(pnode.expression);
|
|
988
882
|
let right;
|
|
989
|
-
if (
|
|
883
|
+
if (ts7.isStringLiteral(pnode.argumentExpression)) {
|
|
990
884
|
const leftType = checker.getTypeAtLocation(pnode.expression);
|
|
991
885
|
right = `"${replaceIdentifier(pnode.argumentExpression.text, leftType, pnode.argumentExpression.text)}"`;
|
|
992
886
|
} else {
|
|
@@ -994,11 +888,11 @@ NodeHandler.register(ts8.SyntaxKind.DeleteExpression, (node) => {
|
|
|
994
888
|
}
|
|
995
889
|
return `${left}.remove(${right})`;
|
|
996
890
|
}
|
|
997
|
-
throw `Cant handle delete expression for ${
|
|
891
|
+
throw `Cant handle delete expression for ${ts7.SyntaxKind[node.expression.kind]}`;
|
|
998
892
|
});
|
|
999
893
|
|
|
1000
894
|
// src/visitors/functions.ts
|
|
1001
|
-
import
|
|
895
|
+
import ts8 from "typescript";
|
|
1002
896
|
function transpileFunctionBody(node) {
|
|
1003
897
|
const params = node.parameters.map((param) => NodeHandler.handle(param)).join(", ");
|
|
1004
898
|
const body = node.body ? NodeHandler.handle(node.body) : "";
|
|
@@ -1006,7 +900,7 @@ function transpileFunctionBody(node) {
|
|
|
1006
900
|
${body}
|
|
1007
901
|
end function`;
|
|
1008
902
|
}
|
|
1009
|
-
NodeHandler.register(
|
|
903
|
+
NodeHandler.register(ts8.SyntaxKind.Block, (node) => {
|
|
1010
904
|
const output = node.statements.map((val) => {
|
|
1011
905
|
let statement = NodeHandler.handle(val);
|
|
1012
906
|
statement = statement.split(`
|
|
@@ -1017,38 +911,38 @@ NodeHandler.register(ts9.SyntaxKind.Block, (node) => {
|
|
|
1017
911
|
`);
|
|
1018
912
|
return output;
|
|
1019
913
|
});
|
|
1020
|
-
NodeHandler.register(
|
|
914
|
+
NodeHandler.register(ts8.SyntaxKind.MethodDeclaration, (node) => {
|
|
1021
915
|
return `${NodeHandler.handle(node.name)} = ${transpileFunctionBody(node)}`;
|
|
1022
916
|
});
|
|
1023
|
-
NodeHandler.register(
|
|
917
|
+
NodeHandler.register(ts8.SyntaxKind.FunctionDeclaration, (node) => {
|
|
1024
918
|
if (!node.body)
|
|
1025
919
|
return "";
|
|
1026
|
-
if (node.modifiers?.some((m) => m.kind ===
|
|
920
|
+
if (node.modifiers?.some((m) => m.kind === ts8.SyntaxKind.DeclareKeyword))
|
|
1027
921
|
return "";
|
|
1028
922
|
const name = node.name ? node.name.text : "anon";
|
|
1029
923
|
return `${name} = ${transpileFunctionBody(node)}`;
|
|
1030
924
|
});
|
|
1031
|
-
NodeHandler.register(
|
|
925
|
+
NodeHandler.register(ts8.SyntaxKind.ArrowFunction, (node) => {
|
|
1032
926
|
const params = node.parameters.map((param) => NodeHandler.handle(param));
|
|
1033
|
-
const body =
|
|
1034
|
-
if (
|
|
927
|
+
const body = ts8.isBlock(node.body) ? NodeHandler.handle(node.body) : ` return ${NodeHandler.handle(node.body)}`;
|
|
928
|
+
if (ts8.isCallOrNewExpression(node.parent) || ts8.isParenthesizedExpression(node.parent)) {
|
|
1035
929
|
return "@" + createAnonFunction(body, params).name;
|
|
1036
930
|
}
|
|
1037
|
-
if (
|
|
931
|
+
if (ts8.hasOnlyExpressionInitializer(node.parent) || ts8.isBinaryExpression(node.parent) || ts8.isReturnStatement(node.parent)) {
|
|
1038
932
|
return `function(${params.join(", ")})
|
|
1039
933
|
${body}
|
|
1040
934
|
end function`;
|
|
1041
935
|
}
|
|
1042
|
-
const kind =
|
|
936
|
+
const kind = ts8.SyntaxKind[node.parent.kind];
|
|
1043
937
|
throw `This kind of arrow function is not yet supported (parent: ${kind} (${node.parent.kind}))`;
|
|
1044
938
|
});
|
|
1045
|
-
NodeHandler.register(
|
|
939
|
+
NodeHandler.register(ts8.SyntaxKind.FunctionExpression, (node) => {
|
|
1046
940
|
return transpileFunctionBody(node);
|
|
1047
941
|
});
|
|
1048
942
|
|
|
1049
943
|
// src/visitors/identifiers.ts
|
|
1050
|
-
import
|
|
1051
|
-
NodeHandler.register(
|
|
944
|
+
import ts9 from "typescript";
|
|
945
|
+
NodeHandler.register(ts9.SyntaxKind.Identifier, (node, ctx) => {
|
|
1052
946
|
const type = checker.getTypeAtLocation(node);
|
|
1053
947
|
let name = node.text;
|
|
1054
948
|
if (name === "undefined")
|
|
@@ -1066,31 +960,31 @@ NodeHandler.register(ts10.SyntaxKind.Identifier, (node, ctx) => {
|
|
|
1066
960
|
if (ctx.namedImports[ctx.currentFilePath]?.[name]) {
|
|
1067
961
|
name = ctx.namedImports[ctx.currentFilePath][name];
|
|
1068
962
|
}
|
|
1069
|
-
if (
|
|
963
|
+
if (ts9.isCallOrNewExpression(node.parent) && node != node.parent.expression) {
|
|
1070
964
|
if (nodeIsFunctionReference(node, type))
|
|
1071
965
|
name = asRef(name);
|
|
1072
966
|
}
|
|
1073
967
|
return name;
|
|
1074
968
|
});
|
|
1075
|
-
NodeHandler.register(
|
|
969
|
+
NodeHandler.register(ts9.SyntaxKind.Parameter, (node) => {
|
|
1076
970
|
const name = NodeHandler.handle(node.name);
|
|
1077
971
|
if (!node.initializer)
|
|
1078
972
|
return name;
|
|
1079
973
|
const initializer = NodeHandler.handle(node.initializer);
|
|
1080
974
|
const initializerType = checker.getTypeAtLocation(node.initializer);
|
|
1081
|
-
if (initializerType.flags ===
|
|
975
|
+
if (initializerType.flags === ts9.TypeFlags.Object) {
|
|
1082
976
|
throw `You can't initialize parameter '${name}' with an Array or an Object as that won't work in GreyScript and it would be null`;
|
|
1083
977
|
}
|
|
1084
978
|
return `${name} = ${initializer}`;
|
|
1085
979
|
});
|
|
1086
|
-
NodeHandler.register(
|
|
1087
|
-
NodeHandler.register(
|
|
1088
|
-
NodeHandler.register(
|
|
1089
|
-
NodeHandler.register(
|
|
1090
|
-
NodeHandler.register(
|
|
1091
|
-
NodeHandler.register(
|
|
1092
|
-
NodeHandler.register(
|
|
1093
|
-
const propDeclarationAncestor =
|
|
980
|
+
NodeHandler.register(ts9.SyntaxKind.NumericLiteral, (node) => node.text);
|
|
981
|
+
NodeHandler.register(ts9.SyntaxKind.StringLiteral, (node) => `"${transformString(node.text)}"`);
|
|
982
|
+
NodeHandler.register(ts9.SyntaxKind.NullKeyword, () => "null");
|
|
983
|
+
NodeHandler.register(ts9.SyntaxKind.UndefinedKeyword, () => "null");
|
|
984
|
+
NodeHandler.register(ts9.SyntaxKind.FalseKeyword, () => "0");
|
|
985
|
+
NodeHandler.register(ts9.SyntaxKind.TrueKeyword, () => "1");
|
|
986
|
+
NodeHandler.register(ts9.SyntaxKind.ThisKeyword, (node) => {
|
|
987
|
+
const propDeclarationAncestor = ts9.findAncestor(node.parent, (n) => ts9.isPropertyDeclaration(n));
|
|
1094
988
|
if (propDeclarationAncestor) {
|
|
1095
989
|
if (!propDeclarationAncestor.parent.name)
|
|
1096
990
|
throw `Can't handle this 'this' keyword becuase the class doesn't have a name and it's needed for this case`;
|
|
@@ -1098,12 +992,12 @@ NodeHandler.register(ts10.SyntaxKind.ThisKeyword, (node) => {
|
|
|
1098
992
|
}
|
|
1099
993
|
return "self";
|
|
1100
994
|
});
|
|
1101
|
-
NodeHandler.register(
|
|
1102
|
-
if (
|
|
995
|
+
NodeHandler.register(ts9.SyntaxKind.SuperKeyword, (node) => {
|
|
996
|
+
if (ts9.isPropertyAccessExpression(node.parent) || ts9.isElementAccessExpression(node.parent))
|
|
1103
997
|
return "super";
|
|
1104
998
|
return "super.constructor";
|
|
1105
999
|
});
|
|
1106
|
-
NodeHandler.register(
|
|
1000
|
+
NodeHandler.register(ts9.SyntaxKind.RegularExpressionLiteral, (node) => {
|
|
1107
1001
|
const start = node.text.indexOf("/") + 1;
|
|
1108
1002
|
const end = node.text.lastIndexOf("/");
|
|
1109
1003
|
const flags = node.text.slice(end + 1);
|
|
@@ -1114,7 +1008,7 @@ NodeHandler.register(ts10.SyntaxKind.RegularExpressionLiteral, (node) => {
|
|
|
1114
1008
|
|
|
1115
1009
|
// src/visitors/imports.ts
|
|
1116
1010
|
import path3 from "node:path";
|
|
1117
|
-
import
|
|
1011
|
+
import ts10 from "typescript";
|
|
1118
1012
|
function importFile(filePath, ctx, returnResult) {
|
|
1119
1013
|
let srcPath = path3.resolve(ctx.currentFolder, filePath);
|
|
1120
1014
|
if (!path3.extname(srcPath))
|
|
@@ -1126,7 +1020,7 @@ function importFile(filePath, ctx, returnResult) {
|
|
|
1126
1020
|
}
|
|
1127
1021
|
return transpileSourceFile(source, ctx, returnResult);
|
|
1128
1022
|
}
|
|
1129
|
-
NodeHandler.register(
|
|
1023
|
+
NodeHandler.register(ts10.SyntaxKind.ImportDeclaration, (node, ctx) => {
|
|
1130
1024
|
if (!node.importClause) {
|
|
1131
1025
|
const moduleName = node.moduleSpecifier.text;
|
|
1132
1026
|
const transpiledFile = importFile(moduleName, ctx, true);
|
|
@@ -1149,7 +1043,7 @@ NodeHandler.register(ts11.SyntaxKind.ImportDeclaration, (node, ctx) => {
|
|
|
1149
1043
|
throw `Can't import default exports yet (imported as ${node.importClause.name.text})`;
|
|
1150
1044
|
const bindings = node.importClause.namedBindings;
|
|
1151
1045
|
if (bindings) {
|
|
1152
|
-
if (
|
|
1046
|
+
if (ts10.isNamespaceImport(bindings)) {
|
|
1153
1047
|
ctx.namespaceImports[ctx.currentFilePath]?.add(bindings.name.text);
|
|
1154
1048
|
} else {
|
|
1155
1049
|
bindings.elements.forEach((el) => {
|
|
@@ -1163,6 +1057,125 @@ NodeHandler.register(ts11.SyntaxKind.ImportDeclaration, (node, ctx) => {
|
|
|
1163
1057
|
return importFile(moduleSpecifier, ctx);
|
|
1164
1058
|
});
|
|
1165
1059
|
|
|
1060
|
+
// src/visitors/objects.ts
|
|
1061
|
+
import ts11 from "typescript";
|
|
1062
|
+
function shouldGetSafely(node) {
|
|
1063
|
+
if (ts11.isNonNullExpression(node.parent))
|
|
1064
|
+
return false;
|
|
1065
|
+
if (valueIsBeingAssignedToNode(node))
|
|
1066
|
+
return false;
|
|
1067
|
+
const hasQuestionDot = !!node.questionDotToken;
|
|
1068
|
+
if (ts11.isPropertyAccessExpression(node)) {
|
|
1069
|
+
const rightType = checker.getTypeAtLocation(node.name);
|
|
1070
|
+
if (!rightType.isUnion())
|
|
1071
|
+
return hasQuestionDot;
|
|
1072
|
+
const hasUndefined = rightType.types.some((t) => t.flags === ts11.TypeFlags.Undefined);
|
|
1073
|
+
if (!hasUndefined)
|
|
1074
|
+
return false;
|
|
1075
|
+
if (!ts11.isCallExpression(node.parent))
|
|
1076
|
+
return true;
|
|
1077
|
+
if (node.parent.arguments.length)
|
|
1078
|
+
return false;
|
|
1079
|
+
} else {
|
|
1080
|
+
if (ts11.isNumericLiteral(node.argumentExpression))
|
|
1081
|
+
return false;
|
|
1082
|
+
}
|
|
1083
|
+
return hasQuestionDot;
|
|
1084
|
+
}
|
|
1085
|
+
NodeHandler.register(ts11.SyntaxKind.PropertyAccessExpression, (node, ctx) => {
|
|
1086
|
+
const left = NodeHandler.handle(node.expression);
|
|
1087
|
+
let right = NodeHandler.handle(node.name);
|
|
1088
|
+
right = replaceIdentifier(right, checker.getTypeAtLocation(node.expression), right);
|
|
1089
|
+
const nodeSymbol = checker.getSymbolAtLocation(node);
|
|
1090
|
+
if (ctx.namespaceImports[ctx.currentFilePath]?.has(left))
|
|
1091
|
+
return right;
|
|
1092
|
+
if (shouldGetSafely(node))
|
|
1093
|
+
return callUtilFunction("get_property", left, `"${right}"`);
|
|
1094
|
+
let output = `${left}.${right}`;
|
|
1095
|
+
output = replacePropertyAccess(output, nodeSymbol);
|
|
1096
|
+
if (nodeIsFunctionReference(node))
|
|
1097
|
+
output = asRef(output);
|
|
1098
|
+
return output;
|
|
1099
|
+
});
|
|
1100
|
+
NodeHandler.register(ts11.SyntaxKind.ElementAccessExpression, (node, ctx) => {
|
|
1101
|
+
const left = NodeHandler.handle(node.expression);
|
|
1102
|
+
let right;
|
|
1103
|
+
if (ts11.isStringLiteral(node.argumentExpression)) {
|
|
1104
|
+
const leftType = checker.getTypeAtLocation(node.expression);
|
|
1105
|
+
right = `"${replaceIdentifier(node.argumentExpression.text, leftType, node.argumentExpression.text)}"`;
|
|
1106
|
+
} else {
|
|
1107
|
+
right = NodeHandler.handle(node.argumentExpression);
|
|
1108
|
+
}
|
|
1109
|
+
if (shouldGetSafely(node)) {
|
|
1110
|
+
return callUtilFunction("get_property", left, `${right}`);
|
|
1111
|
+
}
|
|
1112
|
+
return `${left}[${right}]`;
|
|
1113
|
+
});
|
|
1114
|
+
function handleObjectLiteralExpression(node, ctx, currObj, outObjects, funcs) {
|
|
1115
|
+
currObj ??= [];
|
|
1116
|
+
outObjects ??= [];
|
|
1117
|
+
funcs ??= [];
|
|
1118
|
+
let objectName = "";
|
|
1119
|
+
if (ts11.hasOnlyExpressionInitializer(node.parent))
|
|
1120
|
+
objectName = NodeHandler.handle(node.parent.name);
|
|
1121
|
+
else if (ts11.isBinaryExpression(node.parent) && node === node.parent.right)
|
|
1122
|
+
objectName = NodeHandler.handle(node.parent.left);
|
|
1123
|
+
function pushObj() {
|
|
1124
|
+
if (!currObj?.length)
|
|
1125
|
+
return "";
|
|
1126
|
+
const res = currObj.filter((s) => s != "").join(",");
|
|
1127
|
+
if (res) {
|
|
1128
|
+
outObjects?.push(`{ ${res} }`);
|
|
1129
|
+
}
|
|
1130
|
+
currObj.length = 0;
|
|
1131
|
+
return res;
|
|
1132
|
+
}
|
|
1133
|
+
for (const item of node.properties) {
|
|
1134
|
+
if (ts11.isFunctionLike(item)) {
|
|
1135
|
+
funcs.push(NodeHandler.handle(item));
|
|
1136
|
+
continue;
|
|
1137
|
+
}
|
|
1138
|
+
if (ts11.isPropertyAssignment(item) && ts11.isFunctionLike(item.initializer)) {
|
|
1139
|
+
funcs.push(`${NodeHandler.handle(item.name)} = ${NodeHandler.handle(item.initializer)}`);
|
|
1140
|
+
continue;
|
|
1141
|
+
}
|
|
1142
|
+
if (ts11.isSpreadAssignment(item)) {
|
|
1143
|
+
if (ts11.isObjectLiteralExpression(item.expression)) {
|
|
1144
|
+
handleObjectLiteralExpression(item.expression, ctx, currObj, outObjects);
|
|
1145
|
+
continue;
|
|
1146
|
+
}
|
|
1147
|
+
if (ts11.isIdentifier(item.expression)) {
|
|
1148
|
+
pushObj();
|
|
1149
|
+
outObjects.push(NodeHandler.handle(item.expression));
|
|
1150
|
+
continue;
|
|
1151
|
+
}
|
|
1152
|
+
if (ts11.isArrayLiteralExpression(item.expression)) {
|
|
1153
|
+
pushObj();
|
|
1154
|
+
outObjects.push(NodeHandler.handle(item.expression));
|
|
1155
|
+
continue;
|
|
1156
|
+
}
|
|
1157
|
+
}
|
|
1158
|
+
currObj.push(NodeHandler.handle(item));
|
|
1159
|
+
}
|
|
1160
|
+
pushObj();
|
|
1161
|
+
if (!outObjects.length)
|
|
1162
|
+
outObjects.push("{}");
|
|
1163
|
+
let output = outObjects[0];
|
|
1164
|
+
if (outObjects.length > 1) {
|
|
1165
|
+
output = callUtilFunction("assign_objects", output, `[${outObjects.slice(1).join(",")}]`);
|
|
1166
|
+
}
|
|
1167
|
+
if (funcs.length) {
|
|
1168
|
+
if (ts11.isPropertyAssignment(node.parent) || !objectName) {
|
|
1169
|
+
throw "You can't have method declarations inside an object that is not being assigned to a variable";
|
|
1170
|
+
}
|
|
1171
|
+
output += `
|
|
1172
|
+
` + funcs.map((func) => `${objectName}.${func}`).join(`
|
|
1173
|
+
`);
|
|
1174
|
+
}
|
|
1175
|
+
return output;
|
|
1176
|
+
}
|
|
1177
|
+
NodeHandler.register(ts11.SyntaxKind.ObjectLiteralExpression, handleObjectLiteralExpression);
|
|
1178
|
+
|
|
1166
1179
|
// src/visitors/statements.ts
|
|
1167
1180
|
import ts12 from "typescript";
|
|
1168
1181
|
NodeHandler.register(ts12.SyntaxKind.ForStatement, (node) => {
|
|
@@ -1540,7 +1553,7 @@ var extensionFunctions = {
|
|
|
1540
1553
|
"Array.includes": [
|
|
1541
1554
|
"list.includes = function(value, pos = 0)",
|
|
1542
1555
|
"\tindex = self.indexOf(value)",
|
|
1543
|
-
"\tif index == null then return
|
|
1556
|
+
"\tif index == null then return 0",
|
|
1544
1557
|
"\tif pos < 0 then pos = 0",
|
|
1545
1558
|
"\treturn index >= pos",
|
|
1546
1559
|
"end function"
|
|
@@ -1561,6 +1574,24 @@ var extensionFunctions = {
|
|
|
1561
1574
|
"\treturn deleted",
|
|
1562
1575
|
"end function"
|
|
1563
1576
|
].join(`
|
|
1577
|
+
`),
|
|
1578
|
+
"Array.fill": [
|
|
1579
|
+
"list.fill = function(value, start, endI)",
|
|
1580
|
+
"\tlen = self.len",
|
|
1581
|
+
"\tif not len then return self",
|
|
1582
|
+
"\tif start == null then start = 0",
|
|
1583
|
+
"\tif endI == null then endI = len - 1",
|
|
1584
|
+
"\tif start < 0 then start = len + start",
|
|
1585
|
+
"\tif start < 0 then start = 0",
|
|
1586
|
+
"\tif endI < 0 then endI = len + endI",
|
|
1587
|
+
"\tif endI < 0 then endI = 0",
|
|
1588
|
+
"\tfor i in range(start, endI-1, 1)",
|
|
1589
|
+
"\t\tif i >= len then break",
|
|
1590
|
+
"\t\tself[i] = value",
|
|
1591
|
+
"\tend for",
|
|
1592
|
+
"\treturn self",
|
|
1593
|
+
"end function"
|
|
1594
|
+
].join(`
|
|
1564
1595
|
`),
|
|
1565
1596
|
"String.startsWith": [
|
|
1566
1597
|
"string.startsWith = function(search, pos = 0)",
|
|
@@ -1586,7 +1617,7 @@ var extensionFunctions = {
|
|
|
1586
1617
|
"String.includes": [
|
|
1587
1618
|
"string.includes = function(search, pos = 0)",
|
|
1588
1619
|
"\tindex = self.indexOf(search)",
|
|
1589
|
-
"\tif index == null then return
|
|
1620
|
+
"\tif index == null then return 0",
|
|
1590
1621
|
"\tif pos < 0 then pos = 0",
|
|
1591
1622
|
"\treturn index >= pos",
|
|
1592
1623
|
"end function"
|
|
@@ -1719,14 +1750,12 @@ end function`,
|
|
|
1719
1750
|
return @left
|
|
1720
1751
|
end function`,
|
|
1721
1752
|
is_type: `is_type = function(value, type)
|
|
1722
|
-
|
|
1723
|
-
return 0
|
|
1753
|
+
return typeof(value) == type
|
|
1724
1754
|
end function`,
|
|
1725
1755
|
conditional_expr: `conditional_expr = function(cond, when_true, when_false)
|
|
1726
1756
|
if cond then return when_true
|
|
1727
1757
|
return when_false
|
|
1728
|
-
end function
|
|
1729
|
-
...extensionFunctions
|
|
1758
|
+
end function`
|
|
1730
1759
|
};
|
|
1731
1760
|
function createAnonFunction(body, params) {
|
|
1732
1761
|
const defaultParams = new Array(3).fill(0).map((_, i) => `param${i}`);
|
|
@@ -1781,8 +1810,7 @@ function transpileProgram(entryFileRelativePath) {
|
|
|
1781
1810
|
utilitiesToInsert.clear();
|
|
1782
1811
|
}
|
|
1783
1812
|
console.log(`Transpiling took ${Date.now() - start} ms`);
|
|
1784
|
-
return ctx.output
|
|
1785
|
-
`);
|
|
1813
|
+
return ctx.output;
|
|
1786
1814
|
}
|
|
1787
1815
|
function transpileSourceFile(sourceFile, ctx, returnResult) {
|
|
1788
1816
|
if (ctx.visitedFiles[sourceFile.fileName])
|
|
@@ -1834,27 +1862,54 @@ for (let i = 2;i < process.argv.length; i++) {
|
|
|
1834
1862
|
args.push(arg);
|
|
1835
1863
|
}
|
|
1836
1864
|
var root = findProjectRoot(process.cwd());
|
|
1865
|
+
var outDirPath = `${root}/out`;
|
|
1837
1866
|
if (!command) {
|
|
1838
1867
|
console.error("No command specified.");
|
|
1839
1868
|
process.exit(2);
|
|
1840
1869
|
}
|
|
1870
|
+
function createOutputFile(fileIndex, basename, content) {
|
|
1871
|
+
if (fileIndex > 0)
|
|
1872
|
+
basename = `${basename}-${fileIndex}`;
|
|
1873
|
+
const outFileName = args.length > 1 ? args[1] : `${basename}.src`;
|
|
1874
|
+
const outFilePath = path5.join(outDirPath, outFileName);
|
|
1875
|
+
fs3.writeFileSync(outFilePath, content);
|
|
1876
|
+
}
|
|
1841
1877
|
if (command === "transpile") {
|
|
1842
1878
|
if (!args.length) {
|
|
1843
1879
|
console.error("No entry file specified.");
|
|
1844
1880
|
process.exit(2);
|
|
1845
1881
|
}
|
|
1846
1882
|
const entryFile = args[0];
|
|
1847
|
-
const
|
|
1883
|
+
const basename = path5.basename(entryFile, ".ts");
|
|
1884
|
+
const transpiledStatements = transpileProgram(entryFile);
|
|
1848
1885
|
if (flags.includes("--print") || flags.includes("-p")) {
|
|
1849
|
-
console.log(
|
|
1886
|
+
console.log(transpiledStatements.join(`
|
|
1887
|
+
`));
|
|
1850
1888
|
process.exit(0);
|
|
1851
1889
|
}
|
|
1852
|
-
const outDirPath = `${root}/out`;
|
|
1853
1890
|
if (!fs3.existsSync(outDirPath))
|
|
1854
1891
|
fs3.mkdirSync(outDirPath);
|
|
1855
|
-
|
|
1856
|
-
const
|
|
1857
|
-
|
|
1892
|
+
let content = "";
|
|
1893
|
+
const fileContents = [];
|
|
1894
|
+
while (transpiledStatements.length) {
|
|
1895
|
+
const statement = transpiledStatements.shift();
|
|
1896
|
+
if (content.length + statement.length > 155000 && content.length) {
|
|
1897
|
+
fileContents.push(content);
|
|
1898
|
+
content = "";
|
|
1899
|
+
continue;
|
|
1900
|
+
}
|
|
1901
|
+
content += statement + `
|
|
1902
|
+
`;
|
|
1903
|
+
}
|
|
1904
|
+
if (content.length)
|
|
1905
|
+
fileContents.push(content);
|
|
1906
|
+
for (let i = 0;i < fileContents.length; i++) {
|
|
1907
|
+
if (i + 1 < fileContents.length) {
|
|
1908
|
+
const nextFileName = `${basename}-${i + 1}.src`;
|
|
1909
|
+
fileContents[i] += `import_code("${nextFileName}")`;
|
|
1910
|
+
}
|
|
1911
|
+
createOutputFile(i, basename, fileContents[i]);
|
|
1912
|
+
}
|
|
1858
1913
|
} else {
|
|
1859
1914
|
console.log(`Invalid command: ${command}`);
|
|
1860
1915
|
process.exit(127);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@grey-ts/transpiler",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.1",
|
|
4
4
|
"description": "Transpiles TypeScript into GreyScript",
|
|
5
5
|
"author": "Okka",
|
|
6
6
|
"module": "src/index.ts",
|
|
@@ -34,12 +34,11 @@
|
|
|
34
34
|
"build": "bun run scripts/build.ts"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
|
-
"@types/bun": "latest"
|
|
37
|
+
"@types/bun": "latest",
|
|
38
|
+
"@grey-ts/types": "latest"
|
|
38
39
|
},
|
|
39
40
|
"peerDependencies": {
|
|
40
|
-
"typescript": "^5"
|
|
41
|
-
|
|
42
|
-
"dependencies": {
|
|
43
|
-
"@grey-ts/types": "^2.1.0"
|
|
41
|
+
"typescript": "^5",
|
|
42
|
+
"@grey-ts/types": "^2.2.0"
|
|
44
43
|
}
|
|
45
44
|
}
|