@grey-ts/transpiler 1.1.2 → 1.3.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 +280 -222
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -25,7 +25,7 @@ class NodeHandler {
25
25
  if (!handler) {
26
26
  console.log(`Unsupported syntax ${ts.SyntaxKind[node.kind]} (kind ${node.kind}) was not transpiled: ${node.getText()}`);
27
27
  this.printLineAndCol(node);
28
- return "null";
28
+ return ts.isBlock(node.parent) || ts.isSourceFile(node.parent) ? "" : "null";
29
29
  }
30
30
  try {
31
31
  const result = handler(node, this.transpileContext);
@@ -33,7 +33,7 @@ class NodeHandler {
33
33
  } catch (error) {
34
34
  console.error(error);
35
35
  this.printLineAndCol(node);
36
- return "null";
36
+ return ts.isBlock(node.parent) || ts.isSourceFile(node.parent) ? "" : "null";
37
37
  }
38
38
  }
39
39
  static printLineAndCol(node) {
@@ -44,6 +44,7 @@ class NodeHandler {
44
44
  }
45
45
  NodeHandler.register(ts.SyntaxKind.TypeAliasDeclaration, () => "");
46
46
  NodeHandler.register(ts.SyntaxKind.InterfaceDeclaration, () => "");
47
+ NodeHandler.register(ts.SyntaxKind.ModuleDeclaration, () => "");
47
48
  NodeHandler.register(ts.SyntaxKind.EndOfFileToken, () => "");
48
49
  NodeHandler.register(ts.SyntaxKind.EmptyStatement, () => "");
49
50
 
@@ -214,9 +215,11 @@ var apiNameMap = {
214
215
  "String.length": "len",
215
216
  "String.toLowerCase": "lower",
216
217
  "String.toUpperCase": "upper",
218
+ "String.repeat": "repeatSelf",
217
219
  "Object.size": "len",
218
220
  "Array.length": "len",
219
- "Array.shift": "pull"
221
+ "Array.shift": "pull",
222
+ "Array.push": "push_many"
220
223
  };
221
224
  var propertyAccessReplacements = {
222
225
  "Math.PI": "pi",
@@ -383,7 +386,7 @@ function findProjectRoot(dir, fileToSearch = "package.json") {
383
386
  return dir;
384
387
  }
385
388
  function callUtilFunction(functionName, ...params) {
386
- calledUtilFunctions.add(functionName);
389
+ utilitiesToInsert.set(functionName, utilFunctions[functionName]);
387
390
  return `${functionName}(${params.join(", ")})`;
388
391
  }
389
392
 
@@ -507,6 +510,13 @@ class CallTransformer {
507
510
  this.handlers.set(symbolFullName, handler);
508
511
  }
509
512
  static handle(symbolFullName, functionName, callArgs, node, ctx) {
513
+ if (symbolFullName in utilFunctions) {
514
+ if (symbolFullName.startsWith("Math"))
515
+ utilitiesToInsert.set("create_math", "Math = {}");
516
+ utilitiesToInsert.set(symbolFullName, utilFunctions[symbolFullName]);
517
+ const params = callArgs.length ? `(${callArgs.join(",")})` : "";
518
+ return `${functionName}${params}`;
519
+ }
510
520
  const handler = this.handlers.get(symbolFullName);
511
521
  if (!handler)
512
522
  return null;
@@ -521,12 +531,6 @@ CallTransformer.register("Function.toString", (name) => {
521
531
  const func = name.slice(0, name.lastIndexOf("."));
522
532
  return `str(@${func})`;
523
533
  });
524
- CallTransformer.register("Math.min", (name, args) => {
525
- return callUtilFunction("math_min", `${args.join(",")}`);
526
- });
527
- CallTransformer.register("Math.max", (name, args) => {
528
- return callUtilFunction("math_max", `${args.join(",")}`);
529
- });
530
534
  CallTransformer.register("GreyHack.include", (name, args, node, ctx) => {
531
535
  if (!node.arguments.length)
532
536
  return "";
@@ -770,8 +774,8 @@ NodeHandler.register(ts8.SyntaxKind.CallExpression, (node, ctx) => {
770
774
  const transformed = CallTransformer.handle(symbolFullName, name, args, node, ctx);
771
775
  if (transformed !== null)
772
776
  return transformed;
773
- if (name === "is_type" && !calledUtilFunctions.has("is_type")) {
774
- calledUtilFunctions.add("is_type");
777
+ if (name === "is_type" && !utilitiesToInsert.has("is_type")) {
778
+ utilitiesToInsert.set("is_type", utilFunctions["is_type"]);
775
779
  }
776
780
  if (!args.length)
777
781
  return name;
@@ -971,13 +975,26 @@ NodeHandler.register(ts8.SyntaxKind.AsExpression, (node) => {
971
975
  return NodeHandler.handle(node.expression);
972
976
  });
973
977
  NodeHandler.register(ts8.SyntaxKind.DeleteExpression, (node) => {
974
- if (!ts8.isPropertyAccessExpression(node.expression))
975
- throw `Cant handle delete expression for ${ts8.SyntaxKind[node.expression.kind]}`;
976
- const pnode = node.expression;
977
- const left = NodeHandler.handle(pnode.expression);
978
- const leftType = checker.getTypeAtLocation(pnode.expression);
979
- const right = replaceIdentifier(NodeHandler.handle(pnode.name), leftType, pnode.name.text);
980
- return `${left}.remove(${right})`;
978
+ if (ts8.isPropertyAccessExpression(node.expression)) {
979
+ const pnode = node.expression;
980
+ const left = NodeHandler.handle(pnode.expression);
981
+ const leftType = checker.getTypeAtLocation(pnode.expression);
982
+ const right = replaceIdentifier(NodeHandler.handle(pnode.name), leftType, pnode.name.text);
983
+ return `${left}.remove("${right}")`;
984
+ }
985
+ if (ts8.isElementAccessExpression(node.expression)) {
986
+ const pnode = node.expression;
987
+ const left = NodeHandler.handle(pnode.expression);
988
+ let right;
989
+ if (ts8.isStringLiteral(pnode.argumentExpression)) {
990
+ const leftType = checker.getTypeAtLocation(pnode.expression);
991
+ right = `"${replaceIdentifier(pnode.argumentExpression.text, leftType, pnode.argumentExpression.text)}"`;
992
+ } else {
993
+ right = NodeHandler.handle(pnode.argumentExpression);
994
+ }
995
+ return `${left}.remove(${right})`;
996
+ }
997
+ throw `Cant handle delete expression for ${ts8.SyntaxKind[node.expression.kind]}`;
981
998
  });
982
999
 
983
1000
  // src/visitors/functions.ts
@@ -1166,11 +1183,13 @@ NodeHandler.register(ts12.SyntaxKind.ForStatement, (node) => {
1166
1183
  }
1167
1184
  return false;
1168
1185
  }
1186
+ const labelIf = ts12.isLabeledStatement(node.parent) ? ` if ${node.parent.label.text}Broke then break` : "";
1169
1187
  if (!hasContinue(node)) {
1170
1188
  return [
1171
1189
  `${initializer}`,
1172
1190
  `while ${condition}`,
1173
1191
  ` ${statement.trimStart()}`,
1192
+ ...labelIf ? [labelIf] : [],
1174
1193
  ` ${incrementor}`,
1175
1194
  `end while`
1176
1195
  ].join(`
@@ -1187,6 +1206,7 @@ NodeHandler.register(ts12.SyntaxKind.ForStatement, (node) => {
1187
1206
  ` end if`,
1188
1207
  ` ${incrementedStateVarName} = 0`,
1189
1208
  ` ${statement.trimStart()}`,
1209
+ ...labelIf ? [labelIf] : [],
1190
1210
  ` ${incrementor}`,
1191
1211
  ` ${incrementedStateVarName} = 1`,
1192
1212
  `end while`
@@ -1203,9 +1223,14 @@ NodeHandler.register(ts12.SyntaxKind.ForOfStatement, (node) => {
1203
1223
  }
1204
1224
  const varName = NodeHandler.handle(node.initializer.declarations[0].name);
1205
1225
  const objToLoop = NodeHandler.handle(node.expression);
1206
- return `for ${varName} in ${objToLoop}
1207
- ${NodeHandler.handle(node.statement)}
1208
- end for`;
1226
+ const labelIf = ts12.isLabeledStatement(node.parent) ? ` if ${node.parent.label.text}Broke then break` : "";
1227
+ return [
1228
+ `for ${varName} in ${objToLoop}`,
1229
+ `${NodeHandler.handle(node.statement)}`,
1230
+ ...labelIf ? [labelIf] : [],
1231
+ `end for`
1232
+ ].join(`
1233
+ `);
1209
1234
  });
1210
1235
  NodeHandler.register(ts12.SyntaxKind.ForInStatement, (node) => {
1211
1236
  if (!ts12.isVariableDeclarationList(node.initializer)) {
@@ -1216,9 +1241,14 @@ NodeHandler.register(ts12.SyntaxKind.ForInStatement, (node) => {
1216
1241
  }
1217
1242
  const varName = NodeHandler.handle(node.initializer.declarations[0].name);
1218
1243
  const objToLoop = NodeHandler.handle(node.expression);
1219
- return `for ${varName} in ${objToLoop}.indexes
1220
- ${NodeHandler.handle(node.statement)}
1221
- end for`;
1244
+ const labelIf = ts12.isLabeledStatement(node.parent) ? ` if ${node.parent.label.text}Broke then break` : "";
1245
+ return [
1246
+ `for ${varName} in ${objToLoop}.indexes`,
1247
+ `${NodeHandler.handle(node.statement)}`,
1248
+ ...labelIf ? [labelIf] : [],
1249
+ `end for`
1250
+ ].join(`
1251
+ `);
1222
1252
  });
1223
1253
  NodeHandler.register(ts12.SyntaxKind.IfStatement, (node) => {
1224
1254
  const condition = NodeHandler.handle(node.expression);
@@ -1248,20 +1278,24 @@ end if`;
1248
1278
  });
1249
1279
  NodeHandler.register(ts12.SyntaxKind.WhileStatement, (node, ctx) => {
1250
1280
  const expression = NodeHandler.handle(node.expression);
1281
+ const labelIf = ts12.isLabeledStatement(node.parent) ? ` if ${node.parent.label.text}Broke then break` : "";
1251
1282
  return [
1252
1283
  `while ${expression}`,
1253
1284
  ` ${NodeHandler.handle(node.statement).trimStart()}`,
1285
+ ...labelIf ? [labelIf] : [],
1254
1286
  `end while`
1255
1287
  ].join(`
1256
1288
  `);
1257
1289
  });
1258
1290
  NodeHandler.register(ts12.SyntaxKind.DoStatement, (node, ctx) => {
1259
1291
  const expression = NodeHandler.handle(node.expression);
1292
+ const labelIf = ts12.isLabeledStatement(node.parent) ? ` if ${node.parent.label.text}Broke then break` : "";
1260
1293
  return [
1261
1294
  `did_once = 0`,
1262
1295
  `while not did_once or ${expression}`,
1263
1296
  ` did_once = 1`,
1264
1297
  ` ${NodeHandler.handle(node.statement).trimStart()}`,
1298
+ ...labelIf ? [labelIf] : [],
1265
1299
  `end while`
1266
1300
  ].join(`
1267
1301
  `);
@@ -1270,6 +1304,12 @@ NodeHandler.register(ts12.SyntaxKind.ContinueStatement, (node) => {
1270
1304
  return "continue";
1271
1305
  });
1272
1306
  NodeHandler.register(ts12.SyntaxKind.BreakStatement, (node) => {
1307
+ if (node.label) {
1308
+ if (!ts12.isBlock(node.parent))
1309
+ throw "A break statement with a label must be in a block";
1310
+ return `${NodeHandler.handle(node.label)}Broke = 1
1311
+ break`;
1312
+ }
1273
1313
  return "break";
1274
1314
  });
1275
1315
  NodeHandler.register(ts12.SyntaxKind.ReturnStatement, (node) => {
@@ -1281,6 +1321,10 @@ NodeHandler.register(ts12.SyntaxKind.ReturnStatement, (node) => {
1281
1321
  }
1282
1322
  return `return ${NodeHandler.handle(node.expression)}`;
1283
1323
  });
1324
+ NodeHandler.register(ts12.SyntaxKind.LabeledStatement, (node) => {
1325
+ return `${NodeHandler.handle(node.label)}Broke = 0
1326
+ ${NodeHandler.handle(node.statement)}`;
1327
+ });
1284
1328
 
1285
1329
  // src/visitors/variables.ts
1286
1330
  import ts13 from "typescript";
@@ -1309,71 +1353,39 @@ NodeHandler.register(ts13.SyntaxKind.VariableStatement, (node, ctx) => {
1309
1353
  NodeHandler.register(ts13.SyntaxKind.VariableDeclaration, handleVariableDeclaration);
1310
1354
  NodeHandler.register(ts13.SyntaxKind.PropertyDeclaration, handleVariableDeclaration);
1311
1355
  NodeHandler.register(ts13.SyntaxKind.EnumDeclaration, (node) => {
1312
- const members = node.members.map((member, index) => {
1313
- const name = NodeHandler.handle(member.name);
1356
+ const members = [];
1357
+ function addMember(name, initializer) {
1358
+ members.push(`${name}: ${initializer}`);
1359
+ if (isNaN(+initializer))
1360
+ return;
1361
+ members.push(`${initializer}: ${name}`);
1362
+ }
1363
+ node.members.forEach((member, index) => {
1364
+ let name = NodeHandler.handle(member.name);
1365
+ if (!ts13.isStringLiteral(member.name))
1366
+ name = `"${name}"`;
1314
1367
  if (member.initializer) {
1315
- return `${name}: ${NodeHandler.handle(member.initializer)}`;
1368
+ addMember(name, NodeHandler.handle(member.initializer));
1369
+ return;
1316
1370
  }
1317
1371
  const type = checker.getTypeAtLocation(member);
1318
1372
  if ("value" in type) {
1319
- return `${name}: ${type.value}`;
1373
+ addMember(name, String(type.value));
1374
+ return;
1320
1375
  }
1321
- return `${name}: ${index}`;
1376
+ addMember(name, index.toString());
1322
1377
  });
1323
1378
  return `${node.name.text} = { ${members.join(", ")} }`;
1324
1379
  });
1325
1380
 
1326
1381
  // src/call_transformers/array.ts
1327
- CallTransformer.register("Array.concat", (name, args) => {
1328
- const dotI = name.lastIndexOf(".");
1329
- const arrayName = name.slice(0, dotI);
1330
- return callUtilFunction("array_concat", arrayName, args.join(","));
1331
- });
1332
- CallTransformer.register("Array.map", (name, args) => {
1333
- if (!args.length)
1334
- throw "Invalid argument count";
1335
- return callUtilFunction("array_map", name.slice(0, name.lastIndexOf(".")), args[0]);
1336
- });
1337
- CallTransformer.register("Array.filter", (name, args) => {
1338
- if (!args.length)
1339
- throw "Invalid argument count";
1340
- return callUtilFunction("array_filter", name.slice(0, name.lastIndexOf(".")), args[0]);
1341
- });
1342
- CallTransformer.register("Array.find", (name, args) => {
1343
- if (!args.length)
1344
- throw "Invalid argument count";
1345
- return callUtilFunction("array_find", name.slice(0, name.lastIndexOf(".")), args[0]);
1346
- });
1347
- CallTransformer.register("Array.some", (name, args) => {
1348
- if (!args.length)
1349
- throw "Invalid argument count";
1350
- return callUtilFunction("array_some", name.slice(0, name.lastIndexOf(".")), args[0]);
1351
- });
1352
- CallTransformer.register("Array.every", (name, args) => {
1353
- if (!args.length)
1354
- throw "Invalid argument count";
1355
- return callUtilFunction("array_every", name.slice(0, name.lastIndexOf(".")), args[0]);
1356
- });
1357
1382
  CallTransformer.register("Array.slice", (name, args) => {
1358
1383
  return name.slice(0, name.lastIndexOf(".")) + `[${args[0] ?? ""}:${args[1] ?? ""}]`;
1359
1384
  });
1360
- CallTransformer.register("Array.push", (name, args) => {
1361
- if (!args.length)
1362
- throw "Invalid argument count";
1363
- return callUtilFunction("array_push", name.slice(0, name.lastIndexOf(".")), args[0]);
1364
- });
1365
- CallTransformer.register("Array.unshift", (name, args) => {
1366
- if (!args.length)
1367
- throw "Invalid argument count";
1368
- return callUtilFunction("array_unshift", name.slice(0, name.lastIndexOf(".")), args[0]);
1369
- });
1370
1385
  CallTransformer.register("Array.toString", (name) => {
1371
1386
  const arrayName = name.slice(0, name.lastIndexOf("."));
1372
1387
  return `str(${arrayName})`;
1373
1388
  });
1374
- CallTransformer.register("Array.reverse", (name) => {
1375
- return callUtilFunction("array_reverse", name.slice(0, name.lastIndexOf(".")));
1376
- });
1377
1389
 
1378
1390
  // src/call_transformers/object.ts
1379
1391
  CallTransformer.register("ObjectConstructor.hasOwn", (name, args) => {
@@ -1419,21 +1431,6 @@ CallTransformer.register("Object.toString", (name) => {
1419
1431
  });
1420
1432
 
1421
1433
  // src/call_transformers/string.ts
1422
- CallTransformer.register("String.startsWith", (name, args) => {
1423
- if (!args.length)
1424
- throw "Invalid argument count";
1425
- return callUtilFunction("str_starts_with", name.slice(0, name.lastIndexOf(".")), ...args);
1426
- });
1427
- CallTransformer.register("String.endsWith", (name, args) => {
1428
- if (!args.length)
1429
- throw "Invalid argument count";
1430
- return callUtilFunction("str_ends_with", name.slice(0, name.lastIndexOf(".")), ...args);
1431
- });
1432
- CallTransformer.register("String.repeat", (name, args) => {
1433
- if (!args.length)
1434
- throw "Invalid argument count";
1435
- return callUtilFunction("str_repeat", name.slice(0, name.lastIndexOf(".")), ...args);
1436
- });
1437
1434
  CallTransformer.register("String.slice", (name, args) => {
1438
1435
  return name.slice(0, name.lastIndexOf(".")) + `[${args[0] ?? ""}:${args[1] ?? ""}]`;
1439
1436
  });
@@ -1444,132 +1441,68 @@ CallTransformer.register("String.toString", (name) => {
1444
1441
  // src/transpiler.ts
1445
1442
  var program;
1446
1443
  var checker;
1447
- var anonFunctions = new Map;
1448
- var calledUtilFunctions = new Set;
1449
- var utilFunctions2 = {
1450
- get_property: [
1451
- "get_property = function(obj, key)",
1452
- "\tif not obj then return null",
1453
- "\tif obj.hasIndex(key) then return obj[key]",
1454
- "\tisaobj = obj",
1455
- '\twhile isaobj.hasIndex("__isa")',
1456
- '\t\tisaobj = obj["__isa"]',
1457
- "\t\tif isaobj.hasIndex(key) then",
1458
- "\t\t\tres = obj[key]",
1459
- '\t\t\tif typeof(@res) == "function" and str(@res)[8:][1:-1].indexOf("self") == 0 then return res(obj)',
1460
- "\t\t\treturn obj[key]",
1461
- "\t\tend if",
1462
- "\tend while",
1463
- "\treturn null",
1464
- "end function"
1465
- ].join(`
1466
- `),
1467
- assign_objects: [
1468
- "assign_objects = function(target, source1, source2, source3)",
1469
- "\tassign_to_list = function(target, source)",
1470
- "\t\tif source isa list then",
1471
- "\t\t\tfor i in range(0, source.len - 1, 1)",
1472
- "\t\t\t\tif target.len <= i then target.push(null)",
1473
- "\t\t\t\ttarget[i] = source[i]",
1474
- "\t\t\tend for",
1475
- "\t\telse if source isa map then",
1476
- "\t\t\tfor item in source",
1477
- "\t\t\t\tkey = str(item.key).to_int",
1478
- "\t\t\t\tif key isa number then target[key] = item.value",
1479
- "\t\t\tend for",
1480
- "\t\tend if",
1481
- "\t\treturn target",
1482
- "\tend function",
1483
- "\tcounter = 0",
1484
- "\tassign_object = function(target, source)",
1485
- "\t\tif target isa list then return assign_to_list(target, source)",
1486
- "\t\tif source isa list then",
1487
- "\t\t\tfor i in range(0, source.len - 1, 1)",
1488
- "\t\t\t\ttarget[str(i)] = source[i]",
1489
- "\t\t\tend for",
1490
- "\t\telse if source isa map then",
1491
- "\t\t\tfor item in source",
1492
- "\t\t\t\ttarget[item.key] = item.value",
1493
- "\t\t\tend for",
1494
- "\t\telse",
1495
- "\t\t\ttarget[str(outer.counter)] = source",
1496
- "\t\t\touter.counter = outer.counter + 1",
1497
- "\t\tend if",
1498
- "\tend function",
1499
- "\tif source1 isa list then",
1500
- "\t\tif target isa list then return assign_to_list(target, source1)",
1501
- "\t\tfor source in source1",
1502
- "\t\t\tassign_object(target, source)",
1503
- "\t\tend for",
1504
- "\t\treturn target",
1505
- "\tend if",
1506
- "\tif source1 then assign_object(target, source1)",
1507
- "\tif source2 then assign_object(target, source2)",
1508
- "\tif source3 then assign_object(target, source3)",
1509
- "\treturn target",
1510
- "end function"
1511
- ].join(`
1512
- `),
1513
- array_map: [
1514
- "array_map = function(array, callback)",
1444
+ var utilitiesToInsert = new Map;
1445
+ var extensionFunctions = {
1446
+ "Array.map": [
1447
+ "list.map = function(callback)",
1515
1448
  "\tindex = 0",
1516
1449
  "\tout = []",
1517
- "\tfor item in array",
1518
- "\t\tout.push(callback(item, index, array))",
1450
+ "\tfor item in self",
1451
+ "\t\tout.push(callback(item, index, self))",
1519
1452
  "\t\tindex = index + 1",
1520
1453
  "\tend for",
1521
1454
  "\treturn out",
1522
1455
  "end function"
1523
1456
  ].join(`
1524
1457
  `),
1525
- array_filter: [
1526
- "array_filter = function(array, predicate)",
1458
+ "Array.filter": [
1459
+ "list.filter = function(predicate)",
1527
1460
  "\tindex = 0",
1528
1461
  "\tout = []",
1529
- "\tfor item in array",
1530
- "\t\tif predicate(item, index, array) then out.push(item)",
1462
+ "\tfor item in self",
1463
+ "\t\tif predicate(item, index, self) then out.push(item)",
1531
1464
  "\t\tindex = index + 1",
1532
1465
  "\tend for",
1533
1466
  "\treturn out",
1534
1467
  "end function"
1535
1468
  ].join(`
1536
1469
  `),
1537
- array_find: [
1538
- "array_find = function(array, predicate)",
1470
+ "Array.find": [
1471
+ "list.find = function(predicate)",
1539
1472
  "\tindex = 0",
1540
- "\tfor item in array",
1541
- "\t\tif predicate(item, index, array) then return item",
1473
+ "\tfor item in self",
1474
+ "\t\tif predicate(item, index, self) then return item",
1542
1475
  "\t\tindex = index + 1",
1543
1476
  "\tend for",
1544
1477
  "\treturn null",
1545
1478
  "end function"
1546
1479
  ].join(`
1547
1480
  `),
1548
- array_some: [
1549
- "array_some = function(array, predicate)",
1481
+ "Array.some": [
1482
+ "list.some = function(predicate)",
1550
1483
  "\tindex = 0",
1551
- "\tfor item in array",
1552
- "\t\tif predicate(item, index, array) then return 1",
1484
+ "\tfor item in self",
1485
+ "\t\tif predicate(item, index, self) then return 1",
1553
1486
  "\t\tindex = index + 1",
1554
1487
  "\tend for",
1555
1488
  "\treturn 0",
1556
1489
  "end function"
1557
1490
  ].join(`
1558
1491
  `),
1559
- array_every: [
1560
- "array_every = function(array, predicate)",
1492
+ "Array.every": [
1493
+ "list.every = function(predicate)",
1561
1494
  "\tindex = 0",
1562
- "\tfor item in array",
1563
- "\t\tif not predicate(item, index, array) then return 0",
1495
+ "\tfor item in self",
1496
+ "\t\tif not predicate(item, index, self) then return 0",
1564
1497
  "\t\tindex = index + 1",
1565
1498
  "\tend for",
1566
1499
  "\treturn 1",
1567
1500
  "end function"
1568
1501
  ].join(`
1569
1502
  `),
1570
- array_concat: [
1571
- "array_concat = function(target, items)",
1572
- "\tout = target[0:]",
1503
+ "Array.concat": [
1504
+ "list.concat = function(items)",
1505
+ "\tout = self[0:]",
1573
1506
  "\tfor item in items",
1574
1507
  "\t\tif item isa list then out = out + item else out.push(item)",
1575
1508
  "\tend for",
@@ -1577,58 +1510,123 @@ var utilFunctions2 = {
1577
1510
  "end function"
1578
1511
  ].join(`
1579
1512
  `),
1580
- array_push: [
1581
- "array_push = function(target, items)",
1513
+ "Array.push": [
1514
+ "list.push_many = function(items)",
1582
1515
  "\tfor item in items[:]",
1583
- "\t\ttarget.push(@item)",
1516
+ "\t\tself.push(@item)",
1584
1517
  "\tend for",
1585
- "\treturn target.len",
1518
+ "\treturn self.len",
1586
1519
  "end function"
1587
1520
  ].join(`
1588
1521
  `),
1589
- array_unshift: [
1590
- "array_unshift = function(target, items)",
1591
- "\tif not items.len then return target.len",
1522
+ "Array.unshift": [
1523
+ "list.unshift = function(items)",
1524
+ "\tif not items.len then return self.len",
1592
1525
  "\tfor i in range(items.len-1)",
1593
- "\t\ttarget.insert(0, @items[i])",
1526
+ "\t\tself.insert(0, items[i])",
1594
1527
  "\tend for",
1595
- "\treturn target.len",
1528
+ "\treturn self.len",
1596
1529
  "end function"
1597
1530
  ].join(`
1598
1531
  `),
1599
- array_reverse: `array_reverse = function(arr)
1600
- arr.reverse
1601
- return arr
1602
- end function`,
1603
- str_starts_with: [
1604
- "str_starts_with = function(str, search, pos = 0)",
1532
+ "Array.reverse": [
1533
+ "list.old_reverse = @list.reverse",
1534
+ "list.reverse = function",
1535
+ "\tself.old_reverse",
1536
+ "\treturn self",
1537
+ "end function"
1538
+ ].join(`
1539
+ `),
1540
+ "Array.includes": [
1541
+ "list.includes = function(value, pos = 0)",
1542
+ "\tindex = self.indexOf(value)",
1543
+ "\tif index == null then return false",
1605
1544
  "\tif pos < 0 then pos = 0",
1606
- "\treturn str.indexOf(search) == pos",
1545
+ "\treturn index >= pos",
1607
1546
  "end function"
1608
1547
  ].join(`
1609
1548
  `),
1610
- str_ends_with: [
1611
- "str_ends_with = function(str, search, pos = null)",
1612
- "\tif pos == null then pos = str.len",
1549
+ "Array.splice": [
1550
+ "list.splice = function(start, count)",
1551
+ "\tdeleted = []",
1552
+ "\tif start < 0 then start = self.len + start",
1553
+ "\tif start < 0 then start = 0",
1554
+ "\tif count == null then count = self.len - start",
1555
+ "\tif count <= 0 then return deleted",
1556
+ "\twhile deleted.len < count",
1557
+ "\t\tif not self.hasIndex(start) then return deleted",
1558
+ "\t\tdeleted.push(self[start])",
1559
+ "\t\tself.remove(start)",
1560
+ "\tend while",
1561
+ "\treturn deleted",
1562
+ "end function"
1563
+ ].join(`
1564
+ `),
1565
+ "String.startsWith": [
1566
+ "string.startsWith = function(search, pos = 0)",
1613
1567
  "\tif pos < 0 then pos = 0",
1614
- "\treturn str.indexOf(search) + search.len == pos",
1568
+ "\treturn self.indexOf(search) == pos",
1615
1569
  "end function"
1616
1570
  ].join(`
1617
1571
  `),
1618
- str_repeat: [
1619
- "str_repeat = function(str, count = 0)",
1620
- '\tif count <= 0 then return ""',
1621
- "\tif count == 1 then return str",
1622
- "\tout = str",
1623
- "\tfor i in range(count-2)",
1624
- "\t\tout = out + str",
1625
- "\tend for",
1626
- "\treturn out",
1572
+ "String.endsWith": [
1573
+ "string.endsWith = function(search, pos = null)",
1574
+ "\tif pos == null then pos = self.len",
1575
+ "\tif pos < 0 then pos = 0",
1576
+ "\treturn self.indexOf(search) + search.len == pos",
1577
+ "end function"
1578
+ ].join(`
1579
+ `),
1580
+ "String.repeat": [
1581
+ "string.repeatSelf = function(count = 0)",
1582
+ "\treturn self * count",
1583
+ "end function"
1584
+ ].join(`
1585
+ `),
1586
+ "String.includes": [
1587
+ "string.includes = function(search, pos = 0)",
1588
+ "\tindex = self.indexOf(search)",
1589
+ "\tif index == null then return false",
1590
+ "\tif pos < 0 then pos = 0",
1591
+ "\treturn index >= pos",
1592
+ "end function"
1593
+ ].join(`
1594
+ `),
1595
+ "String.trimStart": [
1596
+ "string.trimStart = function()",
1597
+ '\treturn self.replace("^\\s+", "")',
1598
+ "end function"
1599
+ ].join(`
1600
+ `),
1601
+ "String.trimEnd": [
1602
+ "string.trimEnd = function()",
1603
+ '\treturn self.replace("\\s+$", "")',
1604
+ "end function"
1605
+ ].join(`
1606
+ `),
1607
+ "Number.toFixed": [
1608
+ "number.toFixed = function(digits = 0)",
1609
+ "\tdigits = floor(digits)",
1610
+ "\tif digits <= 0 then return str(round(self))",
1611
+ "\tvalue = self",
1612
+ "\tvalue = value * (10 ^ digits)",
1613
+ "\tvalue = round(value)",
1614
+ "\tvalue = value / (10 ^ digits)",
1615
+ "\t",
1616
+ "\tstr_value = str(value)",
1617
+ '\tdot_index = str_value.indexOf(".")',
1618
+ "\tif dot_index == null then",
1619
+ '\t\tstr_value = str_value + "." + ("0" * digits)',
1620
+ "\telse if str_value[dot_index + 1:].len < digits then",
1621
+ "\t\trepeat_count = digits - str_value[dot_index + 1:].len",
1622
+ '\t\tstr_value = str_value + ("0" * repeat_count)',
1623
+ "\tend if",
1624
+ "\treturn str_value",
1627
1625
  "end function"
1628
1626
  ].join(`
1629
1627
  `),
1630
- math_min: [
1631
- "math_min = function(numbers)",
1628
+ "Math.min": [
1629
+ "Math.min = function(numbers)",
1632
1630
  "\tcurr_min = null",
1633
1631
  "\tfor num in numbers",
1634
1632
  "\t\tif curr_min == null or num < curr_min then curr_min = num",
@@ -1637,8 +1635,8 @@ end function`,
1637
1635
  "end function"
1638
1636
  ].join(`
1639
1637
  `),
1640
- math_max: [
1641
- "math_max = function(numbers)",
1638
+ "Math.max": [
1639
+ "Math.max = function(numbers)",
1642
1640
  "\tcurr_max = null",
1643
1641
  "\tfor num in numbers",
1644
1642
  "\t\tif curr_max == null or num > curr_max then curr_max = num",
@@ -1646,6 +1644,71 @@ end function`,
1646
1644
  "\treturn curr_max",
1647
1645
  "end function"
1648
1646
  ].join(`
1647
+ `)
1648
+ };
1649
+ var utilFunctions = {
1650
+ get_property: [
1651
+ "get_property = function(obj, key)",
1652
+ "\tif not obj then return null",
1653
+ "\tif obj.hasIndex(key) then return obj[key]",
1654
+ "\tisaobj = obj",
1655
+ '\twhile isaobj.hasIndex("__isa")',
1656
+ '\t\tisaobj = obj["__isa"]',
1657
+ "\t\tif isaobj.hasIndex(key) then",
1658
+ "\t\t\tres = obj[key]",
1659
+ '\t\t\tif typeof(@res) == "function" and str(@res)[8:][1:-1].indexOf("self") == 0 then return res(obj)',
1660
+ "\t\t\treturn obj[key]",
1661
+ "\t\tend if",
1662
+ "\tend while",
1663
+ "\treturn null",
1664
+ "end function"
1665
+ ].join(`
1666
+ `),
1667
+ assign_objects: [
1668
+ "assign_objects = function(target, source1, source2, source3)",
1669
+ "\tassign_to_list = function(target, source)",
1670
+ "\t\tif source isa list then",
1671
+ "\t\t\tfor i in range(0, source.len - 1, 1)",
1672
+ "\t\t\t\tif target.len <= i then target.push(null)",
1673
+ "\t\t\t\ttarget[i] = source[i]",
1674
+ "\t\t\tend for",
1675
+ "\t\telse if source isa map then",
1676
+ "\t\t\tfor item in source",
1677
+ "\t\t\t\tkey = str(item.key).to_int",
1678
+ "\t\t\t\tif key isa number then target[key] = item.value",
1679
+ "\t\t\tend for",
1680
+ "\t\tend if",
1681
+ "\t\treturn target",
1682
+ "\tend function",
1683
+ "\tcounter = 0",
1684
+ "\tassign_object = function(target, source)",
1685
+ "\t\tif target isa list then return assign_to_list(target, source)",
1686
+ "\t\tif source isa list then",
1687
+ "\t\t\tfor i in range(0, source.len - 1, 1)",
1688
+ "\t\t\t\ttarget[str(i)] = source[i]",
1689
+ "\t\t\tend for",
1690
+ "\t\telse if source isa map then",
1691
+ "\t\t\tfor item in source",
1692
+ "\t\t\t\ttarget[item.key] = item.value",
1693
+ "\t\t\tend for",
1694
+ "\t\telse",
1695
+ "\t\t\ttarget[str(outer.counter)] = source",
1696
+ "\t\t\touter.counter = outer.counter + 1",
1697
+ "\t\tend if",
1698
+ "\tend function",
1699
+ "\tif source1 isa list then",
1700
+ "\t\tif target isa list then return assign_to_list(target, source1)",
1701
+ "\t\tfor source in source1",
1702
+ "\t\t\tassign_object(target, source)",
1703
+ "\t\tend for",
1704
+ "\t\treturn target",
1705
+ "\tend if",
1706
+ "\tif source1 then assign_object(target, source1)",
1707
+ "\tif source2 then assign_object(target, source2)",
1708
+ "\tif source3 then assign_object(target, source3)",
1709
+ "\treturn target",
1710
+ "end function"
1711
+ ].join(`
1649
1712
  `),
1650
1713
  nullish_coalescing_op: `nullish_coalescing_op = function(left, right)
1651
1714
  if left == null then return @right
@@ -1662,16 +1725,17 @@ end function`,
1662
1725
  conditional_expr: `conditional_expr = function(cond, when_true, when_false)
1663
1726
  if cond then return when_true
1664
1727
  return when_false
1665
- end function`
1728
+ end function`,
1729
+ ...extensionFunctions
1666
1730
  };
1667
1731
  function createAnonFunction(body, params) {
1668
1732
  const defaultParams = new Array(3).fill(0).map((_, i) => `param${i}`);
1669
- const nextName = `func_${anonFunctions.size}`;
1733
+ const nextName = `func_${utilitiesToInsert.size}`;
1670
1734
  const paramString = Object.assign(defaultParams, params).join(",");
1671
1735
  const result = `${nextName} = function(${paramString})
1672
1736
  ${body}
1673
1737
  end function`;
1674
- anonFunctions.set(nextName, result);
1738
+ utilitiesToInsert.set(nextName, result);
1675
1739
  return { name: nextName, str: result };
1676
1740
  }
1677
1741
  function transpileProgram(entryFileRelativePath) {
@@ -1712,15 +1776,9 @@ function transpileProgram(entryFileRelativePath) {
1712
1776
  process.exit(1);
1713
1777
  }
1714
1778
  transpileSourceFile(entry, ctx);
1715
- if (anonFunctions.size) {
1716
- for (const declaration of anonFunctions.values())
1717
- ctx.output.unshift(declaration);
1718
- anonFunctions.clear();
1719
- }
1720
- if (calledUtilFunctions.size) {
1721
- for (const call of calledUtilFunctions.keys())
1722
- ctx.output.unshift(utilFunctions2[call]);
1723
- calledUtilFunctions.clear();
1779
+ if (utilitiesToInsert.size) {
1780
+ ctx.output.unshift(...utilitiesToInsert.values());
1781
+ utilitiesToInsert.clear();
1724
1782
  }
1725
1783
  console.log(`Transpiling took ${Date.now() - start} ms`);
1726
1784
  return ctx.output.join(`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@grey-ts/transpiler",
3
- "version": "1.1.2",
3
+ "version": "1.3.0",
4
4
  "description": "Transpiles TypeScript into GreyScript",
5
5
  "author": "Okka",
6
6
  "module": "src/index.ts",
@@ -40,6 +40,6 @@
40
40
  "typescript": "^5"
41
41
  },
42
42
  "dependencies": {
43
- "@grey-ts/types": "^2.0.1"
43
+ "@grey-ts/types": "^2.1.0"
44
44
  }
45
45
  }