@mintplayer/polyglot-target-php 0.5.2 → 0.6.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/package.json +1 -1
  2. package/polyglot-plugin.json +1059 -104
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mintplayer/polyglot-target-php",
3
- "version": "0.5.2",
3
+ "version": "0.6.0",
4
4
  "description": "MintPlayer Polyglot PHP target — a pure-JSON language plugin (spec + emission rules + capabilities + std bindings) for the polyglot transpiler.",
5
5
  "keywords": [
6
6
  "polyglot",
@@ -2,14 +2,15 @@
2
2
  "schema": 1,
3
3
  "name": "php",
4
4
  "capabilities": {
5
- "patternMatching": false,
6
- "withExpressions": false,
5
+ "patternMatching": "native",
6
+ "withExpressions": "native",
7
+ "properties": "emulated",
7
8
  "async": false,
8
9
  "closures": "native",
9
- "exceptions": false,
10
- "interfaces": false,
10
+ "exceptions": "native",
11
+ "interfaces": "native",
11
12
  "blockLambdas": "native",
12
- "extensionMethods": false,
13
+ "extensionMethods": "emulated",
13
14
  "operatorOverloading": false
14
15
  },
15
16
  "spec": {
@@ -28,6 +29,7 @@
28
29
  "stmtEnd": ";",
29
30
  "throwKeyword": "throw",
30
31
  "rethrow": "throw $__e;",
32
+ "memberOp": "->",
31
33
  "trueLit": "true",
32
34
  "falseLit": "false",
33
35
  "nullLit": "null",
@@ -140,6 +142,10 @@
140
142
  "strategy": "suffix",
141
143
  "with": "_"
142
144
  },
145
+ "mangle": {
146
+ "replace": "$",
147
+ "with": "_"
148
+ },
143
149
  "reserved": [
144
150
  "__e",
145
151
  "__opt*",
@@ -149,11 +155,46 @@
149
155
  "preludes": {}
150
156
  },
151
157
  "std": {
158
+ "std.collections": {
159
+ "List.type": "array",
160
+ "List.init": "[]",
161
+ "List.count": "count($this)",
162
+ "List.add": "$this[] = $0",
163
+ "List.clear": "$this = []",
164
+ "List.removeAll": "$this = array_values(array_filter($this, fn($__e) => !(($0)($__e))))",
165
+ "List.removeAt": "array_splice($this, $0, 1)"
166
+ },
152
167
  "std.io": {
153
- "print": "echo is_bool($x) ? ($x ? \"true\" : \"false\") : $x, \"\\n\""
168
+ "print": "echo is_bool($x) ? ($x ? \"true\" : \"false\") : $x, \"\\n\"",
169
+ "readText": "file_get_contents($path)",
170
+ "writeText": "file_put_contents($path, $content)",
171
+ "appendText": "file_put_contents($path, $content, FILE_APPEND)",
172
+ "fileExists": "file_exists($path)",
173
+ "deleteFile": "unlink($path)"
174
+ },
175
+ "std.strings": {
176
+ "string.isEmpty": "($this === '')",
177
+ "string.len": "strlen($this)",
178
+ "string.toUpper": "strtoupper($this)",
179
+ "string.toLower": "strtolower($this)",
180
+ "string.charAt": "substr($this, $0, 1)",
181
+ "string.codePoints": "str_split($this)",
182
+ "string.toI32": "intval($this)"
154
183
  },
155
184
  "std.core": {
156
- "i32.parse": "(intval($0) & 0xffffffff)",
185
+ "Error.type": "\\Exception",
186
+ "Error.init": "new $T($0)",
187
+ "Error.message": "$this->getMessage()",
188
+ "Iterable.type": "iterable",
189
+ "i8.parse": "intval($0)",
190
+ "i16.parse": "intval($0)",
191
+ "i32.parse": "intval($0)",
192
+ "i64.parse": "intval($0)",
193
+ "u8.parse": "intval($0)",
194
+ "u16.parse": "intval($0)",
195
+ "u32.parse": "intval($0)",
196
+ "u64.parse": "intval($0)",
197
+ "f32.parse": "floatval($0)",
157
198
  "f64.parse": "floatval($0)"
158
199
  },
159
200
  "std.math": {
@@ -176,12 +217,17 @@
176
217
  "Math.sinh": "sinh($0)",
177
218
  "Math.cosh": "cosh($0)",
178
219
  "Math.tanh": "tanh($0)",
220
+ "Math.asinh": "asinh($0)",
221
+ "Math.acosh": "acosh($0)",
222
+ "Math.atanh": "atanh($0)",
179
223
  "Math.trunc": "(float)(int)($0)",
180
224
  "Math.floor": "floor($0)",
181
225
  "Math.ceil": "ceil($0)",
182
226
  "Math.min": "min($0, $1)",
183
227
  "Math.max": "max($0, $1)",
184
228
  "Math.abs": "abs($0)",
229
+ "Math.sign": "(fn($a) => $a > 0 ? 1 : ($a < 0 ? -1 : $a - $a))($0)",
230
+ "Math.clamp": "(fn($x, $lo, $hi) => $x < $lo ? $lo : ($x > $hi ? $hi : $x))($0, $1, $2)",
185
231
  "Math.round": "round($0)"
186
232
  }
187
233
  },
@@ -251,10 +297,15 @@
251
297
  }
252
298
  },
253
299
  {
254
- "fn": "ident",
300
+ "fn": "mangleName",
255
301
  "args": [
256
302
  {
257
- "get": "node.mangledCallee"
303
+ "fn": "ident",
304
+ "args": [
305
+ {
306
+ "get": "node.mangledCallee"
307
+ }
308
+ ]
258
309
  }
259
310
  ]
260
311
  },
@@ -318,12 +369,76 @@
318
369
  "get": "node.field"
319
370
  }
320
371
  ]
372
+ },
373
+ {
374
+ "case": {
375
+ "when": [
376
+ [
377
+ {
378
+ "eq": [
379
+ "node.isProperty",
380
+ "true"
381
+ ]
382
+ },
383
+ "()"
384
+ ]
385
+ ]
386
+ }
321
387
  }
322
388
  ]
323
389
  },
324
390
  "MethodCall": {
325
391
  "case": {
326
392
  "when": [
393
+ [
394
+ {
395
+ "eq": [
396
+ "node.isExtension",
397
+ "true"
398
+ ]
399
+ },
400
+ {
401
+ "tmpl": [
402
+ {
403
+ "fn": "ident",
404
+ "args": [
405
+ {
406
+ "get": "node.method"
407
+ }
408
+ ]
409
+ },
410
+ "(",
411
+ {
412
+ "emit": "node.object"
413
+ },
414
+ {
415
+ "case": {
416
+ "when": [
417
+ [
418
+ {
419
+ "eq": [
420
+ "node.args.count",
421
+ "0"
422
+ ]
423
+ },
424
+ ""
425
+ ]
426
+ ],
427
+ "else": {
428
+ "tmpl": [
429
+ ", ",
430
+ {
431
+ "map": "node.args",
432
+ "sep": ", "
433
+ }
434
+ ]
435
+ }
436
+ }
437
+ },
438
+ ")"
439
+ ]
440
+ }
441
+ ],
327
442
  [
328
443
  {
329
444
  "has": "node.staticType"
@@ -869,73 +984,716 @@
869
984
  }
870
985
  }
871
986
  },
872
- "Type": {
873
- "case": {
874
- "when": [
875
- [
876
- {
877
- "has": "type.externTemplate"
878
- },
879
- {
880
- "fn": "substExtern"
987
+ "TryStmt": {
988
+ "seq": [
989
+ {
990
+ "block": {
991
+ "head": "try",
992
+ "body": [
993
+ {
994
+ "stmts": "stmt.body"
995
+ }
996
+ ]
997
+ }
998
+ },
999
+ {
1000
+ "mapDecl": "stmt.catches",
1001
+ "each": {
1002
+ "block": {
1003
+ "head": {
1004
+ "tmpl": [
1005
+ "catch (",
1006
+ {
1007
+ "case": {
1008
+ "when": [
1009
+ [
1010
+ {
1011
+ "eq": [
1012
+ "item.hasType",
1013
+ "true"
1014
+ ]
1015
+ },
1016
+ {
1017
+ "type": "item.type"
1018
+ }
1019
+ ]
1020
+ ],
1021
+ "else": "\\Throwable"
1022
+ }
1023
+ },
1024
+ " $__e)"
1025
+ ]
1026
+ },
1027
+ "body": [
1028
+ {
1029
+ "case": {
1030
+ "when": [
1031
+ [
1032
+ {
1033
+ "eq": [
1034
+ "item.hasBinding",
1035
+ "true"
1036
+ ]
1037
+ },
1038
+ {
1039
+ "line": {
1040
+ "tmpl": [
1041
+ "$",
1042
+ {
1043
+ "fn": "ident",
1044
+ "args": [
1045
+ {
1046
+ "get": "item.binding"
1047
+ }
1048
+ ]
1049
+ },
1050
+ " = $__e;"
1051
+ ]
1052
+ }
1053
+ }
1054
+ ]
1055
+ ]
1056
+ }
1057
+ },
1058
+ {
1059
+ "case": {
1060
+ "when": [
1061
+ [
1062
+ {
1063
+ "eq": [
1064
+ "item.hasGuard",
1065
+ "true"
1066
+ ]
1067
+ },
1068
+ {
1069
+ "line": {
1070
+ "tmpl": [
1071
+ "if (!(",
1072
+ {
1073
+ "emit": "item.guard"
1074
+ },
1075
+ ")) { throw $__e; }"
1076
+ ]
1077
+ }
1078
+ }
1079
+ ]
1080
+ ]
1081
+ }
1082
+ },
1083
+ {
1084
+ "stmts": "item.body"
1085
+ }
1086
+ ]
881
1087
  }
882
- ]
883
- ],
884
- "else": {
885
- "fn": "ident",
1088
+ }
1089
+ },
1090
+ {
1091
+ "case": {
1092
+ "when": [
1093
+ [
1094
+ {
1095
+ "eq": [
1096
+ "stmt.hasFinally",
1097
+ "true"
1098
+ ]
1099
+ },
1100
+ {
1101
+ "block": {
1102
+ "head": "finally",
1103
+ "body": [
1104
+ {
1105
+ "stmts": "stmt.finallyBody"
1106
+ }
1107
+ ]
1108
+ }
1109
+ }
1110
+ ]
1111
+ ]
1112
+ }
1113
+ }
1114
+ ]
1115
+ },
1116
+ "MakeCase": {
1117
+ "tmpl": [
1118
+ "[\"tag\" => ",
1119
+ {
1120
+ "fn": "escapeString",
886
1121
  "args": [
887
1122
  {
888
- "get": "type.name"
1123
+ "get": "node.caseName"
889
1124
  }
890
1125
  ]
891
- }
1126
+ },
1127
+ {
1128
+ "map": "node.fields",
1129
+ "sep": "",
1130
+ "item": {
1131
+ "tmpl": [
1132
+ ", ",
1133
+ {
1134
+ "fn": "escapeString",
1135
+ "args": [
1136
+ {
1137
+ "get": "item.name"
1138
+ }
1139
+ ]
1140
+ },
1141
+ " => ",
1142
+ {
1143
+ "emit": "item.value"
1144
+ }
1145
+ ]
1146
+ }
1147
+ },
1148
+ "]"
1149
+ ]
1150
+ },
1151
+ "UnionDecl": {
1152
+ "line": {
1153
+ "tmpl": [
1154
+ "// union ",
1155
+ {
1156
+ "fn": "ident",
1157
+ "args": [
1158
+ {
1159
+ "get": "decl.name"
1160
+ }
1161
+ ]
1162
+ },
1163
+ " -> tagged arrays: [\"tag\" => <case>, <field> => <value>, ...]"
1164
+ ]
892
1165
  }
893
1166
  },
894
- "ForStmt": {
1167
+ "Match": {
1168
+ "tmpl": [
1169
+ "(fn($_m) => match (true) { ",
1170
+ {
1171
+ "map": "node.arms",
1172
+ "sep": ", ",
1173
+ "item": {
1174
+ "tmpl": [
1175
+ {
1176
+ "call": "phpArmCond"
1177
+ },
1178
+ " => ",
1179
+ {
1180
+ "call": "phpArmValue"
1181
+ }
1182
+ ]
1183
+ }
1184
+ },
1185
+ " })(",
1186
+ {
1187
+ "emit": "node.scrutinee"
1188
+ },
1189
+ ")"
1190
+ ]
1191
+ },
1192
+ "phpArmValue": {
895
1193
  "case": {
896
1194
  "when": [
897
1195
  [
898
1196
  {
899
1197
  "eq": [
900
- "stmt.isRange",
901
- "true"
1198
+ "item.pattern.kind",
1199
+ "binding"
902
1200
  ]
903
1201
  },
904
1202
  {
905
- "block": {
906
- "head": {
907
- "tmpl": [
908
- "for ($",
909
- {
910
- "fn": "ident",
911
- "args": [
912
- {
913
- "get": "stmt.binding"
914
- }
915
- ]
916
- },
917
- " = ",
918
- {
919
- "emit": "stmt.rangeStart"
920
- },
921
- "; $",
922
- {
923
- "fn": "ident",
924
- "args": [
925
- {
926
- "get": "stmt.binding"
927
- }
928
- ]
929
- },
1203
+ "tmpl": [
1204
+ "(fn($",
1205
+ {
1206
+ "fn": "ident",
1207
+ "args": [
930
1208
  {
931
- "case": {
932
- "when": [
933
- [
934
- {
935
- "eq": [
936
- "stmt.inclusive",
937
- "true"
938
- ]
1209
+ "get": "item.pattern.binding"
1210
+ }
1211
+ ]
1212
+ },
1213
+ ") => ",
1214
+ {
1215
+ "emit": "item.body"
1216
+ },
1217
+ ")($_m)"
1218
+ ]
1219
+ }
1220
+ ],
1221
+ [
1222
+ {
1223
+ "and": [
1224
+ {
1225
+ "eq": [
1226
+ "item.pattern.kind",
1227
+ "ctor"
1228
+ ]
1229
+ },
1230
+ {
1231
+ "not": {
1232
+ "eq": [
1233
+ "item.pattern.binders.count",
1234
+ "0"
1235
+ ]
1236
+ }
1237
+ }
1238
+ ]
1239
+ },
1240
+ {
1241
+ "tmpl": [
1242
+ "(fn(",
1243
+ {
1244
+ "map": "item.pattern.binders",
1245
+ "sep": ", ",
1246
+ "item": {
1247
+ "tmpl": [
1248
+ "$",
1249
+ {
1250
+ "fn": "ident",
1251
+ "args": [
1252
+ {
1253
+ "get": "item.binding"
1254
+ }
1255
+ ]
1256
+ }
1257
+ ]
1258
+ }
1259
+ },
1260
+ ") => ",
1261
+ {
1262
+ "emit": "item.body"
1263
+ },
1264
+ ")(",
1265
+ {
1266
+ "map": "item.pattern.binders",
1267
+ "sep": ", ",
1268
+ "item": {
1269
+ "tmpl": [
1270
+ "$_m[",
1271
+ {
1272
+ "fn": "escapeString",
1273
+ "args": [
1274
+ {
1275
+ "get": "item.field"
1276
+ }
1277
+ ]
1278
+ },
1279
+ "]"
1280
+ ]
1281
+ }
1282
+ },
1283
+ ")"
1284
+ ]
1285
+ }
1286
+ ]
1287
+ ],
1288
+ "else": {
1289
+ "emit": "item.body"
1290
+ }
1291
+ }
1292
+ },
1293
+ "phpArmGuard": {
1294
+ "case": {
1295
+ "when": [
1296
+ [
1297
+ {
1298
+ "eq": [
1299
+ "item.pattern.kind",
1300
+ "binding"
1301
+ ]
1302
+ },
1303
+ {
1304
+ "tmpl": [
1305
+ "(fn($",
1306
+ {
1307
+ "fn": "ident",
1308
+ "args": [
1309
+ {
1310
+ "get": "item.pattern.binding"
1311
+ }
1312
+ ]
1313
+ },
1314
+ ") => ",
1315
+ {
1316
+ "emit": "item.guard"
1317
+ },
1318
+ ")($_m)"
1319
+ ]
1320
+ }
1321
+ ],
1322
+ [
1323
+ {
1324
+ "and": [
1325
+ {
1326
+ "eq": [
1327
+ "item.pattern.kind",
1328
+ "ctor"
1329
+ ]
1330
+ },
1331
+ {
1332
+ "not": {
1333
+ "eq": [
1334
+ "item.pattern.binders.count",
1335
+ "0"
1336
+ ]
1337
+ }
1338
+ }
1339
+ ]
1340
+ },
1341
+ {
1342
+ "tmpl": [
1343
+ "(fn(",
1344
+ {
1345
+ "map": "item.pattern.binders",
1346
+ "sep": ", ",
1347
+ "item": {
1348
+ "tmpl": [
1349
+ "$",
1350
+ {
1351
+ "fn": "ident",
1352
+ "args": [
1353
+ {
1354
+ "get": "item.binding"
1355
+ }
1356
+ ]
1357
+ }
1358
+ ]
1359
+ }
1360
+ },
1361
+ ") => ",
1362
+ {
1363
+ "emit": "item.guard"
1364
+ },
1365
+ ")(",
1366
+ {
1367
+ "map": "item.pattern.binders",
1368
+ "sep": ", ",
1369
+ "item": {
1370
+ "tmpl": [
1371
+ "$_m[",
1372
+ {
1373
+ "fn": "escapeString",
1374
+ "args": [
1375
+ {
1376
+ "get": "item.field"
1377
+ }
1378
+ ]
1379
+ },
1380
+ "]"
1381
+ ]
1382
+ }
1383
+ },
1384
+ ")"
1385
+ ]
1386
+ }
1387
+ ]
1388
+ ],
1389
+ "else": {
1390
+ "emit": "item.guard"
1391
+ }
1392
+ }
1393
+ },
1394
+ "phpArmBase": {
1395
+ "case": {
1396
+ "when": [
1397
+ [
1398
+ {
1399
+ "eq": [
1400
+ "item.pattern.kind",
1401
+ "literal"
1402
+ ]
1403
+ },
1404
+ {
1405
+ "tmpl": [
1406
+ "$_m == ",
1407
+ {
1408
+ "emit": "item.pattern.literal"
1409
+ }
1410
+ ]
1411
+ }
1412
+ ],
1413
+ [
1414
+ {
1415
+ "eq": [
1416
+ "item.pattern.kind",
1417
+ "enumCase"
1418
+ ]
1419
+ },
1420
+ {
1421
+ "tmpl": [
1422
+ "$_m == ",
1423
+ {
1424
+ "get": "item.pattern.enumType"
1425
+ },
1426
+ "::",
1427
+ {
1428
+ "get": "item.pattern.enumCase"
1429
+ }
1430
+ ]
1431
+ }
1432
+ ],
1433
+ [
1434
+ {
1435
+ "eq": [
1436
+ "item.pattern.kind",
1437
+ "ctor"
1438
+ ]
1439
+ },
1440
+ {
1441
+ "tmpl": [
1442
+ "$_m[\"tag\"] == ",
1443
+ {
1444
+ "fn": "escapeString",
1445
+ "args": [
1446
+ {
1447
+ "get": "item.pattern.ctorCase"
1448
+ }
1449
+ ]
1450
+ }
1451
+ ]
1452
+ }
1453
+ ]
1454
+ ],
1455
+ "else": "true"
1456
+ }
1457
+ },
1458
+ "phpArmCond": {
1459
+ "case": {
1460
+ "when": [
1461
+ [
1462
+ {
1463
+ "eq": [
1464
+ "item.hasGuard",
1465
+ "false"
1466
+ ]
1467
+ },
1468
+ {
1469
+ "call": "phpArmBase"
1470
+ }
1471
+ ],
1472
+ [
1473
+ {
1474
+ "or": [
1475
+ {
1476
+ "eq": [
1477
+ "item.pattern.kind",
1478
+ "wildcard"
1479
+ ]
1480
+ },
1481
+ {
1482
+ "eq": [
1483
+ "item.pattern.kind",
1484
+ "binding"
1485
+ ]
1486
+ }
1487
+ ]
1488
+ },
1489
+ {
1490
+ "call": "phpArmGuard"
1491
+ }
1492
+ ]
1493
+ ],
1494
+ "else": {
1495
+ "tmpl": [
1496
+ {
1497
+ "call": "phpArmBase"
1498
+ },
1499
+ " && ",
1500
+ {
1501
+ "call": "phpArmGuard"
1502
+ }
1503
+ ]
1504
+ }
1505
+ }
1506
+ },
1507
+ "InterfaceDecl": {
1508
+ "block": {
1509
+ "head": {
1510
+ "tmpl": [
1511
+ "interface ",
1512
+ {
1513
+ "fn": "ident",
1514
+ "args": [
1515
+ {
1516
+ "get": "decl.name"
1517
+ }
1518
+ ]
1519
+ },
1520
+ {
1521
+ "case": {
1522
+ "when": [
1523
+ [
1524
+ {
1525
+ "eq": [
1526
+ "decl.bases.count",
1527
+ "0"
1528
+ ]
1529
+ },
1530
+ ""
1531
+ ]
1532
+ ],
1533
+ "else": {
1534
+ "tmpl": [
1535
+ " extends ",
1536
+ {
1537
+ "map": "decl.bases",
1538
+ "sep": ", ",
1539
+ "item": {
1540
+ "type": "item"
1541
+ }
1542
+ }
1543
+ ]
1544
+ }
1545
+ }
1546
+ }
1547
+ ]
1548
+ },
1549
+ "body": [
1550
+ {
1551
+ "mapDecl": "decl.methods",
1552
+ "each": {
1553
+ "line": {
1554
+ "tmpl": [
1555
+ "public function ",
1556
+ {
1557
+ "fn": "ident",
1558
+ "args": [
1559
+ {
1560
+ "get": "item.name"
1561
+ }
1562
+ ]
1563
+ },
1564
+ "(",
1565
+ {
1566
+ "map": "item.params",
1567
+ "sep": ", ",
1568
+ "item": {
1569
+ "call": "phpParam"
1570
+ }
1571
+ },
1572
+ ");"
1573
+ ]
1574
+ }
1575
+ }
1576
+ }
1577
+ ]
1578
+ }
1579
+ },
1580
+ "With": {
1581
+ "case": {
1582
+ "when": [
1583
+ [
1584
+ {
1585
+ "eq": [
1586
+ "node.baseIsSimple",
1587
+ "true"
1588
+ ]
1589
+ },
1590
+ {
1591
+ "tmpl": [
1592
+ "new ",
1593
+ {
1594
+ "get": "node.type"
1595
+ },
1596
+ "(",
1597
+ {
1598
+ "map": "node.ctorArgs",
1599
+ "sep": ", "
1600
+ },
1601
+ ")"
1602
+ ]
1603
+ }
1604
+ ]
1605
+ ],
1606
+ "else": {
1607
+ "tmpl": [
1608
+ "(fn($",
1609
+ {
1610
+ "get": "node.tempName"
1611
+ },
1612
+ ") => new ",
1613
+ {
1614
+ "get": "node.type"
1615
+ },
1616
+ "(",
1617
+ {
1618
+ "map": "node.ctorArgs",
1619
+ "sep": ", "
1620
+ },
1621
+ "))(",
1622
+ {
1623
+ "emit": "node.base"
1624
+ },
1625
+ ")"
1626
+ ]
1627
+ }
1628
+ }
1629
+ },
1630
+ "Type": {
1631
+ "case": {
1632
+ "when": [
1633
+ [
1634
+ {
1635
+ "has": "type.externTemplate"
1636
+ },
1637
+ {
1638
+ "fn": "substExtern"
1639
+ }
1640
+ ]
1641
+ ],
1642
+ "else": {
1643
+ "fn": "ident",
1644
+ "args": [
1645
+ {
1646
+ "get": "type.name"
1647
+ }
1648
+ ]
1649
+ }
1650
+ }
1651
+ },
1652
+ "ForStmt": {
1653
+ "case": {
1654
+ "when": [
1655
+ [
1656
+ {
1657
+ "eq": [
1658
+ "stmt.isRange",
1659
+ "true"
1660
+ ]
1661
+ },
1662
+ {
1663
+ "block": {
1664
+ "head": {
1665
+ "tmpl": [
1666
+ "for ($",
1667
+ {
1668
+ "fn": "ident",
1669
+ "args": [
1670
+ {
1671
+ "get": "stmt.binding"
1672
+ }
1673
+ ]
1674
+ },
1675
+ " = ",
1676
+ {
1677
+ "emit": "stmt.rangeStart"
1678
+ },
1679
+ "; $",
1680
+ {
1681
+ "fn": "ident",
1682
+ "args": [
1683
+ {
1684
+ "get": "stmt.binding"
1685
+ }
1686
+ ]
1687
+ },
1688
+ {
1689
+ "case": {
1690
+ "when": [
1691
+ [
1692
+ {
1693
+ "eq": [
1694
+ "stmt.inclusive",
1695
+ "true"
1696
+ ]
939
1697
  },
940
1698
  " <= "
941
1699
  ]
@@ -1076,10 +1834,15 @@
1076
1834
  "tmpl": [
1077
1835
  "function ",
1078
1836
  {
1079
- "fn": "ident",
1837
+ "fn": "mangle",
1080
1838
  "args": [
1081
1839
  {
1082
- "get": "decl.emitName"
1840
+ "fn": "ident",
1841
+ "args": [
1842
+ {
1843
+ "get": "decl.emitName"
1844
+ }
1845
+ ]
1083
1846
  }
1084
1847
  ]
1085
1848
  },
@@ -1094,16 +1857,130 @@
1094
1857
  ")"
1095
1858
  ]
1096
1859
  },
1097
- "FunctionDecl": {
1098
- "block": {
1099
- "head": {
1100
- "call": "phpFnSig"
1860
+ "phpFnBody": {
1861
+ "seq": [
1862
+ {
1863
+ "case": {
1864
+ "when": [
1865
+ [
1866
+ {
1867
+ "not": {
1868
+ "eq": [
1869
+ "decl.globalRefs.count",
1870
+ "0"
1871
+ ]
1872
+ }
1873
+ },
1874
+ {
1875
+ "line": {
1876
+ "tmpl": [
1877
+ "global ",
1878
+ {
1879
+ "map": "decl.globalRefs",
1880
+ "sep": ", ",
1881
+ "item": {
1882
+ "tmpl": [
1883
+ "$",
1884
+ {
1885
+ "get": "item"
1886
+ }
1887
+ ]
1888
+ }
1889
+ },
1890
+ ";"
1891
+ ]
1892
+ }
1893
+ }
1894
+ ]
1895
+ ]
1896
+ }
1101
1897
  },
1102
- "body": [
1103
- {
1104
- "stmts": "decl.body"
1898
+ {
1899
+ "case": {
1900
+ "when": [
1901
+ [
1902
+ {
1903
+ "eq": [
1904
+ "decl.exprBodied",
1905
+ "true"
1906
+ ]
1907
+ },
1908
+ {
1909
+ "line": {
1910
+ "tmpl": [
1911
+ "return ",
1912
+ {
1913
+ "emit": "decl.exprBody"
1914
+ },
1915
+ ";"
1916
+ ]
1917
+ }
1918
+ }
1919
+ ]
1920
+ ],
1921
+ "else": {
1922
+ "stmts": "decl.body"
1923
+ }
1105
1924
  }
1106
- ]
1925
+ }
1926
+ ]
1927
+ },
1928
+ "FunctionDecl": {
1929
+ "case": {
1930
+ "when": [
1931
+ [
1932
+ {
1933
+ "eq": [
1934
+ "decl.isPrelude",
1935
+ "true"
1936
+ ]
1937
+ },
1938
+ {
1939
+ "block": {
1940
+ "head": {
1941
+ "tmpl": [
1942
+ "if (!function_exists('",
1943
+ {
1944
+ "fn": "ident",
1945
+ "args": [
1946
+ {
1947
+ "get": "decl.emitName"
1948
+ }
1949
+ ]
1950
+ },
1951
+ "'))"
1952
+ ]
1953
+ },
1954
+ "body": [
1955
+ {
1956
+ "block": {
1957
+ "head": {
1958
+ "call": "phpFnSig"
1959
+ },
1960
+ "body": [
1961
+ {
1962
+ "call": "phpFnBody"
1963
+ }
1964
+ ]
1965
+ }
1966
+ }
1967
+ ]
1968
+ }
1969
+ }
1970
+ ]
1971
+ ],
1972
+ "else": {
1973
+ "block": {
1974
+ "head": {
1975
+ "call": "phpFnSig"
1976
+ },
1977
+ "body": [
1978
+ {
1979
+ "call": "phpFnBody"
1980
+ }
1981
+ ]
1982
+ }
1983
+ }
1107
1984
  }
1108
1985
  },
1109
1986
  "phpMethodSig": {
@@ -1356,6 +2233,34 @@
1356
2233
  ]
1357
2234
  ]
1358
2235
  }
2236
+ },
2237
+ {
2238
+ "case": {
2239
+ "when": [
2240
+ [
2241
+ {
2242
+ "not": {
2243
+ "eq": [
2244
+ "decl.ifaceBases.count",
2245
+ "0"
2246
+ ]
2247
+ }
2248
+ },
2249
+ {
2250
+ "tmpl": [
2251
+ " implements ",
2252
+ {
2253
+ "map": "decl.ifaceBases",
2254
+ "sep": ", ",
2255
+ "item": {
2256
+ "type": "item"
2257
+ }
2258
+ }
2259
+ ]
2260
+ }
2261
+ ]
2262
+ ]
2263
+ }
1359
2264
  }
1360
2265
  ]
1361
2266
  },
@@ -1364,56 +2269,98 @@
1364
2269
  "mapDecl": "decl.fields",
1365
2270
  "each": {
1366
2271
  "line": {
1367
- "tmpl": [
1368
- "public ",
1369
- {
1370
- "case": {
1371
- "when": [
1372
- [
2272
+ "case": {
2273
+ "when": [
2274
+ [
2275
+ {
2276
+ "and": [
1373
2277
  {
1374
2278
  "eq": [
1375
2279
  "item.isStatic",
1376
2280
  "true"
1377
2281
  ]
1378
2282
  },
1379
- "static "
2283
+ {
2284
+ "eq": [
2285
+ "item.isMutable",
2286
+ "false"
2287
+ ]
2288
+ }
1380
2289
  ]
1381
- ]
1382
- }
1383
- },
1384
- "$",
1385
- {
1386
- "fn": "ident",
1387
- "args": [
2290
+ },
1388
2291
  {
1389
- "get": "item.name"
1390
- }
1391
- ]
1392
- },
1393
- {
1394
- "case": {
1395
- "when": [
1396
- [
2292
+ "tmpl": [
2293
+ "const ",
1397
2294
  {
1398
- "eq": [
1399
- "item.hasInit",
1400
- "true"
2295
+ "fn": "ident",
2296
+ "args": [
2297
+ {
2298
+ "get": "item.name"
2299
+ }
1401
2300
  ]
1402
2301
  },
2302
+ " = ",
1403
2303
  {
1404
- "tmpl": [
1405
- " = ",
2304
+ "emit": "item.init"
2305
+ },
2306
+ ";"
2307
+ ]
2308
+ }
2309
+ ]
2310
+ ],
2311
+ "else": {
2312
+ "tmpl": [
2313
+ "public ",
2314
+ {
2315
+ "case": {
2316
+ "when": [
2317
+ [
1406
2318
  {
1407
- "emit": "item.init"
1408
- }
2319
+ "eq": [
2320
+ "item.isStatic",
2321
+ "true"
2322
+ ]
2323
+ },
2324
+ "static "
1409
2325
  ]
2326
+ ]
2327
+ }
2328
+ },
2329
+ "$",
2330
+ {
2331
+ "fn": "ident",
2332
+ "args": [
2333
+ {
2334
+ "get": "item.name"
1410
2335
  }
1411
2336
  ]
1412
- ]
1413
- }
1414
- },
1415
- ";"
1416
- ]
2337
+ },
2338
+ {
2339
+ "case": {
2340
+ "when": [
2341
+ [
2342
+ {
2343
+ "eq": [
2344
+ "item.hasInit",
2345
+ "true"
2346
+ ]
2347
+ },
2348
+ {
2349
+ "tmpl": [
2350
+ " = ",
2351
+ {
2352
+ "emit": "item.init"
2353
+ }
2354
+ ]
2355
+ }
2356
+ ]
2357
+ ]
2358
+ }
2359
+ },
2360
+ ";"
2361
+ ]
2362
+ }
2363
+ }
1417
2364
  }
1418
2365
  }
1419
2366
  },
@@ -1510,6 +2457,10 @@
1510
2457
  "mapMembers": "module.records",
1511
2458
  "rule": "RecordDecl"
1512
2459
  },
2460
+ {
2461
+ "mapMembers": "module.interfaces",
2462
+ "rule": "InterfaceDecl"
2463
+ },
1513
2464
  {
1514
2465
  "mapMembers": "module.classes",
1515
2466
  "rule": "ClassDecl"
@@ -1556,6 +2507,10 @@
1556
2507
  "mapMembers": "module.functions",
1557
2508
  "rule": "FunctionDecl"
1558
2509
  },
2510
+ {
2511
+ "mapMembers": "module.extensions",
2512
+ "rule": "FunctionDecl"
2513
+ },
1559
2514
  {
1560
2515
  "case": {
1561
2516
  "when": [