@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.
Files changed (2) hide show
  1. package/dist/index.js +230 -147
  2. 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
- if (!this.transpileContext.extraOutput.has(node))
49
- this.transpileContext.extraOutput.set(node, { before: "", after: "" });
50
- const extra = this.transpileContext.extraOutput.get(node);
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 "@" + value;
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
- if (propertyName) {
386
- for (const t of type.types) {
387
- symbol = t.getProperty(propertyName);
388
- if (symbol)
389
- break;
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
- } else {
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 != original)
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 && extensions.length && extensions[0].types.length)
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(symbolFullName, functionName, callArgs, node, ctx) {
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", (name, args, node, ctx) => {
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", (name, args) => {
599
+ CallTransformer.register("GreyHack.isType", (_name, args) => {
608
600
  return callUtilFunction("is_type", args.join(","));
609
601
  });
610
- CallTransformer.register("Boolean", (name, args) => {
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", (name, args) => {
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", (name, args) => {
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
- let name = NodeHandler.handle(node.expression);
705
+ const name = NodeHandler.handle(node.expression);
714
706
  const type = checker.getTypeAtLocation(node.expression);
715
- let symbolFullName = type.symbol ? checker.getFullyQualifiedName(type.symbol) : "";
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 = "outer." + 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
- return `${left} = ${callUtilFunction("nullish_coalescing_op", left, right)}`;
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) => "\t" + line).join(`
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 "@" + createAnonFunction(body, params).name;
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 "@" + anon.name;
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
- if (type.isUnion()) {
999
- const original = node.text;
1000
- for (const t of type.types) {
1001
- name = replaceIdentifier(node.text, t);
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]?.[name]) {
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 != node.parent.expression) {
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.isPropertyAccessExpression(node)) {
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 != "").join(",");
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
- ` + funcs.map((func) => `${objectName}.${func}`).join(`
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 = "state_" + (Date.now() * Math.random()).toFixed(0).slice(0, 6);
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, ctx) => {
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, ctx) => {
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, (node) => {
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, ctx) {
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 != "null" && nodeIsFunctionReference(node.initializer, initializerType)) {
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, ctx) => {
1393
- return node.declarations.map((decl) => handleVariableDeclaration(decl, ctx)).join(`
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, ctx) => {
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", (name, args) => {
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", (name, args) => {
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", (name, args) => {
1431
+ CallTransformer.register("ObjectConstructor.keys", (_name, args) => {
1450
1432
  return `${args[0]}.indexes`;
1451
1433
  });
1452
- CallTransformer.register("ObjectConstructor.values", (name, args) => {
1434
+ CallTransformer.register("ObjectConstructor.values", (_name, args) => {
1453
1435
  return `${args[0]}.values`;
1454
1436
  });
1455
- CallTransformer.register("ObjectConstructor.sum", (name, args) => {
1437
+ CallTransformer.register("ObjectConstructor.sum", (_name, args) => {
1456
1438
  return `${args[0]}.sum`;
1457
1439
  });
1458
- CallTransformer.register("ObjectConstructor.shuffle", (name, args) => {
1440
+ CallTransformer.register("ObjectConstructor.shuffle", (_name, args) => {
1459
1441
  return `${args[0]}.shuffle`;
1460
1442
  });
1461
- CallTransformer.register("ObjectConstructor.replace", (name, args) => {
1443
+ CallTransformer.register("ObjectConstructor.replace", (_name, args) => {
1462
1444
  return `${args[0]}.replace(${args.slice(1).join(",")})`;
1463
1445
  });
1464
- CallTransformer.register("ObjectConstructor.remove", (name, args) => {
1446
+ CallTransformer.register("ObjectConstructor.remove", (_name, args) => {
1465
1447
  return `${args[0]}.remove(${args[1]})`;
1466
1448
  });
1467
- CallTransformer.register("ObjectConstructor.shift", (name, args) => {
1449
+ CallTransformer.register("ObjectConstructor.shift", (_name, args) => {
1468
1450
  return `${args[0]}.pull`;
1469
1451
  });
1470
- CallTransformer.register("ObjectConstructor.size", (name, args) => {
1452
+ CallTransformer.register("ObjectConstructor.size", (_name, args) => {
1471
1453
  return `${args[0]}.len`;
1472
1454
  });
1473
- CallTransformer.register("ObjectConstructor.indexOf", (name, args) => {
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
- "Math.min": [
1695
- "Math.min = function(numbers)",
1696
- "\tcurr_min = null",
1697
- "\tfor num in numbers",
1698
- "\t\tif curr_min == null or num < curr_min then curr_min = num",
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 curr_min",
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
- "Math.max": [
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") + "/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": "1.4.4",
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
- "@types/bun": "latest",
38
- "@grey-ts/types": "latest"
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
  }