@mintplayer/polyglot-target-csharp 0.10.0 → 0.10.2

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 +595 -127
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mintplayer/polyglot-target-csharp",
3
- "version": "0.10.0",
3
+ "version": "0.10.2",
4
4
  "description": "MintPlayer Polyglot C# / .NET target — a pure-JSON language plugin (spec + emission rules + capabilities + std bindings) for the polyglot transpiler.",
5
5
  "keywords": [
6
6
  "polyglot",
@@ -1,6 +1,30 @@
1
1
  {
2
- "schema": 1,
2
+ "schema": 2,
3
3
  "name": "csharp",
4
+ "sharedPreludeFile": true,
5
+ "options": {
6
+ "namespace": {
7
+ "default": "",
8
+ "pattern": "^([A-Za-z_][A-Za-z0-9_]*(\\.[A-Za-z_][A-Za-z0-9_]*)*)?$",
9
+ "scope": "closure"
10
+ },
11
+ "class": {
12
+ "default": "PolyglotProgram",
13
+ "pattern": "^[A-Za-z_][A-Za-z0-9_]*$",
14
+ "scope": "closure",
15
+ "reserve": true
16
+ },
17
+ "access": {
18
+ "default": "",
19
+ "pattern": "^(public|internal)?$",
20
+ "scope": "closure"
21
+ },
22
+ "entryPoint": {
23
+ "default": "true",
24
+ "pattern": "^(true|false)$",
25
+ "scope": "closure"
26
+ }
27
+ },
4
28
  "originMapping": {
5
29
  "style": "directive",
6
30
  "line": "#line $n \"$f\"",
@@ -39,17 +63,43 @@
39
63
  "u16": "(ushort)($x)"
40
64
  },
41
65
  "wrapAtom": {
42
- "recv": [
43
- "binary",
44
- "unary",
45
- "cast"
46
- ],
47
- "unary": [
48
- "binary"
66
+ "recvPrimary": [
67
+ "var",
68
+ "this",
69
+ "call",
70
+ "methodCall",
71
+ "member",
72
+ "index",
73
+ "str",
74
+ "char",
75
+ "bool",
76
+ "null",
77
+ "extern",
78
+ "nullAssert",
79
+ "int",
80
+ "float",
81
+ "listLit",
82
+ "tuple",
83
+ "new",
84
+ "makeCase",
85
+ "interp"
49
86
  ]
50
87
  },
51
88
  "rethrow": "throw;",
89
+ "preludes": {
90
+ "pgStrInt": " internal static string Str(sbyte x) => x.ToString(global::System.Globalization.CultureInfo.InvariantCulture);\n internal static string Str(byte x) => x.ToString(global::System.Globalization.CultureInfo.InvariantCulture);\n internal static string Str(short x) => x.ToString(global::System.Globalization.CultureInfo.InvariantCulture);\n internal static string Str(ushort x) => x.ToString(global::System.Globalization.CultureInfo.InvariantCulture);\n internal static string Str(int x) => x.ToString(global::System.Globalization.CultureInfo.InvariantCulture);\n internal static string Str(uint x) => x.ToString(global::System.Globalization.CultureInfo.InvariantCulture);\n internal static string Str(long x) => x.ToString(global::System.Globalization.CultureInfo.InvariantCulture);\n internal static string Str(ulong x) => x.ToString(global::System.Globalization.CultureInfo.InvariantCulture);\n",
91
+ "pgStrFloat": " // f32 text is the f32's exact value widened to f64, printed under the f64 rule.\n internal static string Str(float x) => Str((double)x);\n // ECMAScript Number::toString: exact shortest digits (Burger-Dybvig over BigInteger, ties to even), then\n // the ECMAScript layout. Never \"R\": its digits are wrong on .NET Framework and on some .NET 10 patches.\n internal static string Str(double x)\n {\n if (double.IsNaN(x)) return \"NaN\";\n if (double.IsPositiveInfinity(x)) return \"Infinity\";\n if (double.IsNegativeInfinity(x)) return \"-Infinity\";\n if (x == 0) return \"0\";\n bool neg = x < 0;\n if (neg) x = -x;\n long bits = global::System.BitConverter.DoubleToInt64Bits(x);\n int be = (int)((bits >> 52) & 0x7FF);\n long f = bits & 0xFFFFFFFFFFFFFL;\n int e;\n if (be == 0) e = -1074; else { f |= 1L << 52; e = be - 1075; }\n bool even = (f & 1) == 0;\n bool asym = f == (1L << 52) && be > 1;\n global::System.Numerics.BigInteger r, s, mp, mm;\n if (e >= 0)\n {\n global::System.Numerics.BigInteger b = global::System.Numerics.BigInteger.One << e;\n if (!asym) { r = f * b * 2; s = 2; mp = b; mm = b; }\n else { r = f * b * 4; s = 4; mp = b * 2; mm = b; }\n }\n else\n {\n if (!asym) { r = (global::System.Numerics.BigInteger)f * 2; s = global::System.Numerics.BigInteger.One << (1 - e); mp = 1; mm = 1; }\n else { r = (global::System.Numerics.BigInteger)f * 4; s = global::System.Numerics.BigInteger.One << (2 - e); mp = 2; mm = 1; }\n }\n int k = (int)global::System.Math.Ceiling(global::System.Math.Log10(x) - 1e-10);\n if (k >= 0) s *= global::System.Numerics.BigInteger.Pow(10, k);\n else { global::System.Numerics.BigInteger p = global::System.Numerics.BigInteger.Pow(10, -k); r *= p; mp *= p; mm *= p; }\n while (even ? r + mp >= s : r + mp > s) { s *= 10; k++; }\n while (even ? (r + mp) * 10 < s : (r + mp) * 10 <= s) { r *= 10; mp *= 10; mm *= 10; k--; }\n global::System.Text.StringBuilder dg = new global::System.Text.StringBuilder(20);\n while (true)\n {\n r *= 10; mp *= 10; mm *= 10;\n int d = (int)global::System.Numerics.BigInteger.DivRem(r, s, out r);\n bool low = even ? r <= mm : r < mm;\n bool high = even ? r + mp >= s : r + mp > s;\n if (!low && !high) { dg.Append((char)('0' + d)); continue; }\n if (low && high) { int c = (r * 2).CompareTo(s); if (c > 0 || (c == 0 && (d & 1) == 1)) d++; }\n else if (high) d++;\n dg.Append((char)('0' + d));\n break;\n }\n string digits = dg.ToString();\n int n = k, len = digits.Length;\n global::System.Text.StringBuilder sb = new global::System.Text.StringBuilder(32);\n if (neg) sb.Append('-');\n if (len <= n && n <= 21) { sb.Append(digits); sb.Append('0', n - len); }\n else if (0 < n && n <= 21) { sb.Append(digits, 0, n); sb.Append('.'); sb.Append(digits, n, len - n); }\n else if (-6 < n && n <= 0) { sb.Append(\"0.\"); sb.Append('0', -n); sb.Append(digits); }\n else\n {\n sb.Append(digits[0]);\n if (len > 1) { sb.Append('.'); sb.Append(digits, 1, len - 1); }\n sb.Append('e'); sb.Append(n - 1 >= 0 ? '+' : '-');\n sb.Append(global::System.Math.Abs(n - 1).ToString(global::System.Globalization.CultureInfo.InvariantCulture));\n }\n return sb.ToString();\n }\n",
92
+ "pgShow": " // The one stringification rule for a value whose static type is not known here (print, a T-typed hole).\n internal static string Show(object? x) => x switch\n {\n null => \"null\",\n bool b => b ? \"true\" : \"false\",\n string s => s,\n double d => Str(d),\n float f => Str(f),\n int i => Str(i),\n long l => Str(l),\n sbyte i8 => Str(i8),\n byte u8 => Str(u8),\n short i16 => Str(i16),\n ushort u16 => Str(u16),\n uint u32 => Str(u32),\n ulong u64 => Str(u64),\n global::System.IFormattable fm => fm.ToString(null, global::System.Globalization.CultureInfo.InvariantCulture),\n _ => x.ToString() ?? \"\",\n };\n",
93
+ "pgAscii": " // ASCII-only case mapping: every other character is kept as is (System.Text.Ascii stops at the first one).\n internal static string UpperAscii(string s)\n {\n char[]? buf = null;\n for (int i = 0; i < s.Length; i++)\n if (s[i] >= 'a' && s[i] <= 'z') { buf ??= s.ToCharArray(); buf[i] = (char)(s[i] - 32); }\n return buf == null ? s : new string(buf);\n }\n internal static string LowerAscii(string s)\n {\n char[]? buf = null;\n for (int i = 0; i < s.Length; i++)\n if (s[i] >= 'A' && s[i] <= 'Z') { buf ??= s.ToCharArray(); buf[i] = (char)(s[i] + 32); }\n return buf == null ? s : new string(buf);\n }\n"
94
+ },
52
95
  "tables": {
96
+ "rangeWideType": {
97
+ "i8": "long", "i16": "long", "i32": "long", "u8": "long", "u16": "long", "u32": "long",
98
+ "i64": "global::System.Int128", "u64": "global::System.UInt128"
99
+ },
100
+ "floatSuffix": {
101
+ "f32": "f"
102
+ },
53
103
  "localDecl": {
54
104
  "mutable": "var $x",
55
105
  "const": "var $x"
@@ -88,22 +138,47 @@
88
138
  "constArrayClose": "}",
89
139
  "linksWithoutImports": true,
90
140
  "forbidsShadowedLocals": true,
91
- "escapes": {
141
+ "nativeCompoundAssign": true,
142
+ "nativeCoalesceAssign": true,
143
+ "assignmentOrder": "targetFirst",
144
+ "exprStmt": { "discardPrefix": "_ = " },
145
+ "literals": {
146
+ "string": {
147
+ "quote": "\"",
148
+ "map": {
149
+ "\\": "\\\\",
150
+ "\"": "\\\"",
151
+ "\n": "\\n",
152
+ "\t": "\\t",
153
+ "\r": "\\r"
154
+ },
155
+ "codepoint": "\\u$H4",
156
+ "astral": "\\U$H8"
157
+ },
92
158
  "interp": {
93
- "\"": "\\\"",
94
- "\\": "\\\\",
95
- "\n": "\\n",
96
- "\t": "\\t",
97
- "\r": "\\r",
98
- "{": "{{",
99
- "}": "}}"
159
+ "quote": "\"",
160
+ "map": {
161
+ "\\": "\\\\",
162
+ "\"": "\\\"",
163
+ "\n": "\\n",
164
+ "\t": "\\t",
165
+ "\r": "\\r",
166
+ "{": "{{",
167
+ "}": "}}"
168
+ },
169
+ "codepoint": "\\u$H4",
170
+ "astral": "\\U$H8"
100
171
  },
101
172
  "char": {
102
- "'": "\\'",
103
- "\\": "\\\\",
104
- "\n": "\\n",
105
- "\t": "\\t",
106
- "\r": "\\r"
173
+ "quote": "'",
174
+ "map": {
175
+ "\\": "\\\\",
176
+ "'": "\\'",
177
+ "\n": "\\n",
178
+ "\t": "\\t",
179
+ "\r": "\\r"
180
+ },
181
+ "codepoint": "\\u$H4"
107
182
  }
108
183
  },
109
184
  "identifiers": {
@@ -190,14 +265,19 @@
190
265
  "strategy": "prefix",
191
266
  "with": "@"
192
267
  },
268
+ "mangle": {
269
+ "replace": "$",
270
+ "with": "__"
271
+ },
193
272
  "reserved": [
194
- "PolyglotProgram",
195
273
  "PolyglotExtensions",
274
+ "__PgRt",
196
275
  "Main",
197
276
  "lhs",
198
277
  "__opt*",
199
278
  "__w*"
200
- ]
279
+ ],
280
+ "renames": { "_": "__u" }
201
281
  }
202
282
  },
203
283
  "rules": {
@@ -217,7 +297,20 @@
217
297
  ]
218
298
  },
219
299
  "Float": {
220
- "get": "node.text"
300
+ "tmpl": [
301
+ {
302
+ "get": "node.text"
303
+ },
304
+ {
305
+ "fn": "table",
306
+ "args": [
307
+ "floatSuffix",
308
+ {
309
+ "get": "node.type"
310
+ }
311
+ ]
312
+ }
313
+ ]
221
314
  },
222
315
  "Bool": {
223
316
  "case": {
@@ -243,8 +336,9 @@
243
336
  "get": "spec.nullLit"
244
337
  },
245
338
  "Str": {
246
- "fn": "escapeString",
339
+ "fn": "quoted",
247
340
  "args": [
341
+ "string",
248
342
  {
249
343
  "get": "node.value"
250
344
  }
@@ -285,6 +379,18 @@
285
379
  {
286
380
  "case": {
287
381
  "when": [
382
+ [
383
+ { "eq": ["node.calleeKind", "lambda"] },
384
+ { "tmpl": [ "((", { "type": "node.calleeType" }, ")", { "emitChild": "node.calleeExpr", "side": "recv" }, ")" ] }
385
+ ],
386
+ [
387
+ { "has": "node.hasCalleeExpr" },
388
+ { "emitChild": "node.calleeExpr", "side": "recv" }
389
+ ],
390
+ [
391
+ { "has": "node.linkCallee" },
392
+ { "tmpl": [ { "get": "option.class" }, ".", { "fn": "mangleName", "args": [ { "fn": "ident", "args": [ { "get": "node.linkCallee" } ] } ] } ] }
393
+ ],
288
394
  [
289
395
  {
290
396
  "eq": [
@@ -294,7 +400,8 @@
294
400
  },
295
401
  {
296
402
  "tmpl": [
297
- "PolyglotProgram.",
403
+ { "get": "option.class" },
404
+ ".",
298
405
  {
299
406
  "fn": "ident",
300
407
  "args": [
@@ -317,12 +424,12 @@
317
424
  }
318
425
  }
319
426
  },
320
- "(",
321
427
  {
322
- "map": "node.args",
323
- "sep": ", "
324
- },
325
- ")"
428
+ "case": {
429
+ "when": [[ { "eq": ["node.isRef", "true"] }, "" ]],
430
+ "else": { "tmpl": [ { "call": "typeArgsSuffix" }, "(", { "map": "node.args", "sep": ", " }, ")" ] }
431
+ }
432
+ }
326
433
  ]
327
434
  },
328
435
  "Member": {
@@ -646,6 +753,25 @@
646
753
  { "type": "node.castType" }
647
754
  ]
648
755
  },
756
+ "NullAssert": {
757
+ "case": {
758
+ "when": [
759
+ [
760
+ { "eq": ["node.isFail", "true"] },
761
+ { "tmpl": ["throw new global::System.NullReferenceException(", { "fn": "quoted", "args": ["string", { "get": "node.message" }] }, ")"] }
762
+ ]
763
+ ],
764
+ "else": {
765
+ "tmpl": [
766
+ "(",
767
+ { "emitChild": "node.operand", "side": "recv" },
768
+ " ?? throw new global::System.NullReferenceException(",
769
+ { "fn": "quoted", "args": ["string", { "get": "node.message" }] },
770
+ "))"
771
+ ]
772
+ }
773
+ }
774
+ },
649
775
  "Unary": {
650
776
  "tmpl": [
651
777
  {
@@ -665,7 +791,7 @@
665
791
  "lits": "node.chunks",
666
792
  "holes": "node.holes",
667
793
  "lit": {
668
- "fn": "escape",
794
+ "fn": "literal",
669
795
  "args": [
670
796
  "interp",
671
797
  {
@@ -692,15 +818,50 @@
692
818
  " ? \"true\" : \"false\")}"
693
819
  ]
694
820
  }
821
+ ],
822
+ [
823
+ { "eq": ["item.typeIsInt", "true"] },
824
+ {
825
+ "tmpl": [
826
+ { "fn": "require", "args": ["pgStrInt"] },
827
+ "{__PgRt.Str(",
828
+ { "emit": "item" },
829
+ ")}"
830
+ ]
831
+ }
832
+ ],
833
+ [
834
+ { "eq": ["item.typeIsFloat", "true"] },
835
+ {
836
+ "tmpl": [
837
+ { "fn": "require", "args": ["pgStrFloat"] },
838
+ "{__PgRt.Str(",
839
+ { "emit": "item" },
840
+ ")}"
841
+ ]
842
+ }
843
+ ],
844
+ [
845
+ { "or": [{ "eq": ["item.typeIsString", "true"] }, { "eq": ["item.typeIsChar", "true"] }] },
846
+ {
847
+ "tmpl": [
848
+ "{",
849
+ { "fn": "parenIfContains", "args": [":", { "emit": "item" }] },
850
+ "}"
851
+ ]
852
+ }
695
853
  ]
696
854
  ],
697
855
  "else": {
698
856
  "tmpl": [
699
- "{",
857
+ { "fn": "require", "args": ["pgShow"] },
858
+ { "fn": "require", "args": ["pgStrInt"] },
859
+ { "fn": "require", "args": ["pgStrFloat"] },
860
+ "{__PgRt.Show(",
700
861
  {
701
862
  "emit": "item"
702
863
  },
703
- "}"
864
+ ")}"
704
865
  ]
705
866
  }
706
867
  }
@@ -714,7 +875,7 @@
714
875
  "tmpl": [
715
876
  "'",
716
877
  {
717
- "fn": "escape",
878
+ "fn": "literal",
718
879
  "args": [
719
880
  "char",
720
881
  {
@@ -1126,7 +1287,7 @@
1126
1287
  "EnumDecl": {
1127
1288
  "line": {
1128
1289
  "tmpl": [
1129
- { "fn": "access" },
1290
+ { "call": "csAccess" },
1130
1291
  "enum ",
1131
1292
  {
1132
1293
  "fn": "ident",
@@ -1325,6 +1486,7 @@
1325
1486
  {
1326
1487
  "case": {
1327
1488
  "when": [
1489
+ [ { "eq": [ "decl.isAbstract", "true" ] }, "abstract " ],
1328
1490
  [
1329
1491
  {
1330
1492
  "eq": [
@@ -1383,12 +1545,22 @@
1383
1545
  },
1384
1546
  " ",
1385
1547
  {
1386
- "fn": "ident",
1387
- "args": [
1388
- {
1389
- "get": "decl.name"
1548
+ "case": {
1549
+ "when": [
1550
+ [
1551
+ { "has": "decl.linkName" },
1552
+ { "fn": "mangle", "args": [ { "fn": "ident", "args": [ { "get": "decl.linkName" } ] } ] }
1553
+ ]
1554
+ ],
1555
+ "else": {
1556
+ "fn": "ident",
1557
+ "args": [
1558
+ {
1559
+ "get": "decl.name"
1560
+ }
1561
+ ]
1390
1562
  }
1391
- ]
1563
+ }
1392
1564
  },
1393
1565
  {
1394
1566
  "fn": "generics"
@@ -1433,6 +1605,7 @@
1433
1605
  "line": {
1434
1606
  "tmpl": [
1435
1607
  "public ",
1608
+ { "case": { "when": [ [ { "eq": [ "decl.isStatic", "true" ] }, "static " ] ] } },
1436
1609
  {
1437
1610
  "type": "decl.returnType"
1438
1611
  },
@@ -1556,6 +1729,7 @@
1556
1729
  "line": {
1557
1730
  "tmpl": [
1558
1731
  "public ",
1732
+ { "case": { "when": [ [ { "eq": [ "decl.isStatic", "true" ] }, "static " ] ] } },
1559
1733
  {
1560
1734
  "type": "decl.returnType"
1561
1735
  },
@@ -1584,6 +1758,7 @@
1584
1758
  "line": {
1585
1759
  "tmpl": [
1586
1760
  "public ",
1761
+ { "case": { "when": [ [ { "eq": [ "decl.isStatic", "true" ] }, "static " ] ] } },
1587
1762
  {
1588
1763
  "type": "decl.returnType"
1589
1764
  },
@@ -1714,19 +1889,24 @@
1714
1889
  {
1715
1890
  "indent": [
1716
1891
  {
1717
- "line": {
1718
- "tmpl": [
1719
- "var ",
1720
- {
1721
- "fn": "ident",
1722
- "args": [
1892
+ "case": {
1893
+ "when": [ [ { "eq": [ "decl.setterValueParam", "value" ] }, "" ] ],
1894
+ "else": {
1895
+ "line": {
1896
+ "tmpl": [
1897
+ "var ",
1723
1898
  {
1724
- "get": "decl.setterValueParam"
1725
- }
1899
+ "fn": "ident",
1900
+ "args": [
1901
+ {
1902
+ "get": "decl.setterValueParam"
1903
+ }
1904
+ ]
1905
+ },
1906
+ " = value;"
1726
1907
  ]
1727
- },
1728
- " = value;"
1729
- ]
1908
+ }
1909
+ }
1730
1910
  }
1731
1911
  },
1732
1912
  {
@@ -1854,17 +2034,31 @@
1854
2034
  "tmpl": [
1855
2035
  "public virtual bool Equals(",
1856
2036
  {
1857
- "map": "decl.params",
1858
- "sep": ", ",
1859
- "item": {
1860
- "call": "csParam"
1861
- }
2037
+ "type": "decl.params.0.type"
2038
+ },
2039
+ "? ",
2040
+ {
2041
+ "fn": "ident",
2042
+ "args": [
2043
+ {
2044
+ "get": "decl.params.0.name"
2045
+ }
2046
+ ]
1862
2047
  },
1863
2048
  ") => ",
2049
+ {
2050
+ "fn": "ident",
2051
+ "args": [
2052
+ {
2053
+ "get": "decl.params.0.name"
2054
+ }
2055
+ ]
2056
+ },
2057
+ " is not null && (",
1864
2058
  {
1865
2059
  "emit": "decl.exprBody"
1866
2060
  },
1867
- ";"
2061
+ ");"
1868
2062
  ]
1869
2063
  }
1870
2064
  }
@@ -1876,16 +2070,37 @@
1876
2070
  "tmpl": [
1877
2071
  "public virtual bool Equals(",
1878
2072
  {
1879
- "map": "decl.params",
1880
- "sep": ", ",
1881
- "item": {
1882
- "call": "csParam"
1883
- }
2073
+ "type": "decl.params.0.type"
2074
+ },
2075
+ "? ",
2076
+ {
2077
+ "fn": "ident",
2078
+ "args": [
2079
+ {
2080
+ "get": "decl.params.0.name"
2081
+ }
2082
+ ]
1884
2083
  },
1885
2084
  ")"
1886
2085
  ]
1887
2086
  },
1888
2087
  "body": [
2088
+ {
2089
+ "line": {
2090
+ "tmpl": [
2091
+ "if (",
2092
+ {
2093
+ "fn": "ident",
2094
+ "args": [
2095
+ {
2096
+ "get": "decl.params.0.name"
2097
+ }
2098
+ ]
2099
+ },
2100
+ " is null) return false;"
2101
+ ]
2102
+ }
2103
+ },
1889
2104
  {
1890
2105
  "stmts": "decl.body"
1891
2106
  }
@@ -1918,7 +2133,7 @@
1918
2133
  }
1919
2134
  ]
1920
2135
  },
1921
- " a, ",
2136
+ "? a, ",
1922
2137
  {
1923
2138
  "fn": "ident",
1924
2139
  "args": [
@@ -1927,7 +2142,7 @@
1927
2142
  }
1928
2143
  ]
1929
2144
  },
1930
- " b) => a is null || b is null ? ReferenceEquals(a, b) : a.Equals(b);"
2145
+ "? b) => a is null || b is null ? ReferenceEquals(a, b) : a.Equals(b);"
1931
2146
  ]
1932
2147
  }
1933
2148
  },
@@ -1943,7 +2158,7 @@
1943
2158
  }
1944
2159
  ]
1945
2160
  },
1946
- " a, ",
2161
+ "? a, ",
1947
2162
  {
1948
2163
  "fn": "ident",
1949
2164
  "args": [
@@ -1952,7 +2167,7 @@
1952
2167
  }
1953
2168
  ]
1954
2169
  },
1955
- " b) => !(a == b);"
2170
+ "? b) => !(a == b);"
1956
2171
  ]
1957
2172
  }
1958
2173
  },
@@ -1971,9 +2186,6 @@
1971
2186
  " __o && this.Equals(__o);"
1972
2187
  ]
1973
2188
  }
1974
- },
1975
- {
1976
- "line": "public override int GetHashCode() => 0;"
1977
2189
  }
1978
2190
  ]
1979
2191
  }
@@ -1985,6 +2197,59 @@
1985
2197
  ]
1986
2198
  }
1987
2199
  ],
2200
+ [
2201
+ {
2202
+ "and": [
2203
+ {
2204
+ "eq": [
2205
+ "decl.kind",
2206
+ "operator"
2207
+ ]
2208
+ },
2209
+ {
2210
+ "eq": [
2211
+ "decl.opSymbol",
2212
+ "hash"
2213
+ ]
2214
+ }
2215
+ ]
2216
+ },
2217
+ {
2218
+ "case": {
2219
+ "when": [
2220
+ [
2221
+ {
2222
+ "eq": [
2223
+ "decl.exprBodied",
2224
+ "true"
2225
+ ]
2226
+ },
2227
+ {
2228
+ "line": {
2229
+ "tmpl": [
2230
+ "public override int GetHashCode() => ",
2231
+ {
2232
+ "emit": "decl.exprBody"
2233
+ },
2234
+ ";"
2235
+ ]
2236
+ }
2237
+ }
2238
+ ]
2239
+ ],
2240
+ "else": {
2241
+ "block": {
2242
+ "head": "public override int GetHashCode()",
2243
+ "body": [
2244
+ {
2245
+ "stmts": "decl.body"
2246
+ }
2247
+ ]
2248
+ }
2249
+ }
2250
+ }
2251
+ }
2252
+ ],
1988
2253
  [
1989
2254
  {
1990
2255
  "and": [
@@ -2107,6 +2372,10 @@
2107
2372
  "else": {
2108
2373
  "case": {
2109
2374
  "when": [
2375
+ [
2376
+ { "eq": [ "decl.isAbstract", "true" ] },
2377
+ { "line": { "tmpl": [ { "call": "csMethodSig" }, ";" ] } }
2378
+ ],
2110
2379
  [
2111
2380
  {
2112
2381
  "eq": [
@@ -2148,7 +2417,7 @@
2148
2417
  },
2149
2418
  "csRecordHead": {
2150
2419
  "tmpl": [
2151
- { "fn": "access" },
2420
+ { "call": "csAccess" },
2152
2421
  "record ",
2153
2422
  {
2154
2423
  "fn": "ident",
@@ -2380,6 +2649,25 @@
2380
2649
  }
2381
2650
  ]
2382
2651
  },
2652
+ "csRangeDecl": {
2653
+ "case": {
2654
+ "when": [ [ { "eq": [ "stmt.rangeEndSimple", "true" ] }, "var " ] ],
2655
+ "else": { "tmpl": [ { "type": "stmt.rangeType" }, " " ] }
2656
+ }
2657
+ },
2658
+ "rangeEndDecl": {
2659
+ "case": {
2660
+ "when": [ [ { "eq": [ "stmt.rangeEndSimple", "false" ] },
2661
+ { "tmpl": [ ", ", { "fn": "ident", "args": [ { "get": "stmt.rangeEndTemp" } ] }, " = ", { "emit": "stmt.rangeEnd" } ] } ] ],
2662
+ "else": ""
2663
+ }
2664
+ },
2665
+ "rangeEndRead": {
2666
+ "case": {
2667
+ "when": [ [ { "eq": [ "stmt.rangeEndSimple", "true" ] }, { "emit": "stmt.rangeEnd" } ] ],
2668
+ "else": { "fn": "ident", "args": [ { "get": "stmt.rangeEndTemp" } ] }
2669
+ }
2670
+ },
2383
2671
  "ForStmt": {
2384
2672
  "case": {
2385
2673
  "when": [
@@ -2393,16 +2681,59 @@
2393
2681
  {
2394
2682
  "case": {
2395
2683
  "when": [
2684
+ [
2685
+ { "eq": [ "stmt.inclusiveMayWrap", "true" ] },
2686
+ {
2687
+ "block": {
2688
+ "head": {
2689
+ "tmpl": [
2690
+ "for (",
2691
+ { "fn": "table", "args": [ "rangeWideType", { "get": "stmt.rangeTypeName" } ] },
2692
+ " ",
2693
+ { "get": "stmt.driver" },
2694
+ " = ",
2695
+ { "emit": "stmt.rangeStart" },
2696
+ { "call": "rangeEndDecl" },
2697
+ "; ",
2698
+ { "get": "stmt.driver" },
2699
+ " <= ",
2700
+ { "call": "rangeEndRead" },
2701
+ "; ",
2702
+ { "get": "stmt.driver" },
2703
+ "++)"
2704
+ ]
2705
+ },
2706
+ "body": [
2707
+ {
2708
+ "line": {
2709
+ "tmpl": [
2710
+ "var ",
2711
+ { "fn": "ident", "args": [ { "get": "stmt.binding" } ] },
2712
+ " = (",
2713
+ { "type": "stmt.rangeType" },
2714
+ ")",
2715
+ { "get": "stmt.driver" },
2716
+ ";"
2717
+ ]
2718
+ }
2719
+ },
2720
+ { "stmts": "stmt.body" }
2721
+ ]
2722
+ }
2723
+ }
2724
+ ],
2396
2725
  [
2397
2726
  { "eq": [ "stmt.captured", "true" ] },
2398
2727
  {
2399
2728
  "block": {
2400
2729
  "head": {
2401
2730
  "tmpl": [
2402
- "for (var ",
2731
+ "for (",
2732
+ { "call": "csRangeDecl" },
2403
2733
  { "get": "stmt.driver" },
2404
2734
  " = ",
2405
2735
  { "emit": "stmt.rangeStart" },
2736
+ { "call": "rangeEndDecl" },
2406
2737
  "; ",
2407
2738
  { "get": "stmt.driver" },
2408
2739
  {
@@ -2411,7 +2742,7 @@
2411
2742
  "else": " < "
2412
2743
  }
2413
2744
  },
2414
- { "emit": "stmt.rangeEnd" },
2745
+ { "call": "rangeEndRead" },
2415
2746
  "; ",
2416
2747
  { "get": "stmt.driver" },
2417
2748
  "++)"
@@ -2439,7 +2770,8 @@
2439
2770
  "block": {
2440
2771
  "head": {
2441
2772
  "tmpl": [
2442
- "for (var ",
2773
+ "for (",
2774
+ { "call": "csRangeDecl" },
2443
2775
  {
2444
2776
  "fn": "ident",
2445
2777
  "args": [
@@ -2452,6 +2784,7 @@
2452
2784
  {
2453
2785
  "emit": "stmt.rangeStart"
2454
2786
  },
2787
+ { "call": "rangeEndDecl" },
2455
2788
  "; ",
2456
2789
  {
2457
2790
  "fn": "ident",
@@ -2477,9 +2810,7 @@
2477
2810
  "else": " < "
2478
2811
  }
2479
2812
  },
2480
- {
2481
- "emit": "stmt.rangeEnd"
2482
- },
2813
+ { "call": "rangeEndRead" },
2483
2814
  "; ",
2484
2815
  {
2485
2816
  "fn": "ident",
@@ -2570,9 +2901,35 @@
2570
2901
  },
2571
2902
  "Program": {
2572
2903
  "seq": [
2904
+ {
2905
+ "line": "// <auto-generated/>"
2906
+ },
2907
+ {
2908
+ "line": "// Generated by Polyglot. Do not edit: regenerate with `polyglot build`."
2909
+ },
2573
2910
  {
2574
2911
  "line": "#nullable enable"
2575
2912
  },
2913
+ {
2914
+ "case": {
2915
+ "when": [
2916
+ [
2917
+ { "not": { "eq": ["module.allLowercaseTypeNames.count", "0"] } },
2918
+ { "line": "#pragma warning disable CS8981 // a .pg type name may be all lowercase" }
2919
+ ]
2920
+ ]
2921
+ }
2922
+ },
2923
+ {
2924
+ "case": {
2925
+ "when": [
2926
+ [
2927
+ { "not": { "eq": ["option.namespace", ""] } },
2928
+ { "line": { "tmpl": ["namespace ", { "get": "option.namespace" }, ";"] } }
2929
+ ]
2930
+ ]
2931
+ }
2932
+ },
2576
2933
  {
2577
2934
  "case": {
2578
2935
  "when": [
@@ -2607,12 +2964,19 @@
2607
2964
  }
2608
2965
  },
2609
2966
  {
2610
- "line": "using static PolyglotProgram;"
2967
+ "line": { "tmpl": ["using static ", { "get": "option.class" }, ";"] }
2611
2968
  }
2612
2969
  ]
2613
2970
  ]
2614
2971
  }
2615
2972
  },
2973
+ {
2974
+ "fn": "preludeSlot",
2975
+ "args": [
2976
+ "file static class __PgRt\n{\n",
2977
+ "}\n"
2978
+ ]
2979
+ },
2616
2980
  {
2617
2981
  "line": ""
2618
2982
  },
@@ -2652,9 +3016,7 @@
2652
3016
  "block": {
2653
3017
  "head": {
2654
3018
  "tmpl": [
2655
- {
2656
- "fn": "access"
2657
- },
3019
+ { "call": "csAccess" },
2658
3020
  "static ",
2659
3021
  {
2660
3022
  "case": {
@@ -2691,7 +3053,7 @@
2691
3053
  "case": {
2692
3054
  "when": [
2693
3055
  [
2694
- {
3056
+ { "and": [{
2695
3057
  "or": [
2696
3058
  {
2697
3059
  "not": {
@@ -2734,7 +3096,7 @@
2734
3096
  }
2735
3097
  }
2736
3098
  ]
2737
- },
3099
+ }, { "or": [{ "not": { "eq": ["module.globals.count", "0"] } }, { "not": { "eq": ["module.functions.count", "0"] } }] }] },
2738
3100
  {
2739
3101
  "line": ""
2740
3102
  }
@@ -2743,12 +3105,15 @@
2743
3105
  }
2744
3106
  },
2745
3107
  {
3108
+ "case": {
3109
+ "when": [
3110
+ [
3111
+ { "or": [{ "not": { "eq": ["module.globals.count", "0"] } }, { "not": { "eq": ["module.functions.count", "0"] } }] },
3112
+ {
2746
3113
  "block": {
2747
3114
  "head": {
2748
3115
  "tmpl": [
2749
- {
2750
- "fn": "access"
2751
- },
3116
+ { "call": "csAccess" },
2752
3117
  "static ",
2753
3118
  {
2754
3119
  "case": {
@@ -2766,7 +3131,8 @@
2766
3131
  "else": ""
2767
3132
  }
2768
3133
  },
2769
- "class PolyglotProgram"
3134
+ "class ",
3135
+ { "get": "option.class" }
2770
3136
  ]
2771
3137
  },
2772
3138
  "body": [
@@ -2824,9 +3190,19 @@
2824
3190
  "when": [
2825
3191
  [
2826
3192
  {
2827
- "eq": [
2828
- "module.hasEntry",
2829
- "true"
3193
+ "and": [
3194
+ {
3195
+ "eq": [
3196
+ "module.hasEntry",
3197
+ "true"
3198
+ ]
3199
+ },
3200
+ {
3201
+ "eq": [
3202
+ "option.entryPoint",
3203
+ "true"
3204
+ ]
3205
+ }
2830
3206
  ]
2831
3207
  },
2832
3208
  {
@@ -2845,12 +3221,12 @@
2845
3221
  ]
2846
3222
  },
2847
3223
  {
2848
- "line": "static void Main() { global::System.Globalization.CultureInfo.CurrentCulture = global::System.Globalization.CultureInfo.InvariantCulture; main().GetAwaiter().GetResult(); }"
3224
+ "line": "static void Main() { main().GetAwaiter().GetResult(); }"
2849
3225
  }
2850
3226
  ]
2851
3227
  ],
2852
3228
  "else": {
2853
- "line": "static void Main() { global::System.Globalization.CultureInfo.CurrentCulture = global::System.Globalization.CultureInfo.InvariantCulture; main(); }"
3229
+ "line": "static void Main() { main(); }"
2854
3230
  }
2855
3231
  }
2856
3232
  }
@@ -2862,12 +3238,31 @@
2862
3238
  }
2863
3239
  ]
2864
3240
  }
3241
+ }
3242
+ ]
3243
+ ]
3244
+ }
2865
3245
  }
2866
3246
  ]
2867
3247
  },
3248
+ "csAccess": {
3249
+ "case": {
3250
+ "when": [
3251
+ [
3252
+ { "not": { "eq": ["option.access", ""] } },
3253
+ { "tmpl": [{ "get": "option.access" }, " "] }
3254
+ ]
3255
+ ]
3256
+ }
3257
+ },
2868
3258
  "csFnSig": {
2869
3259
  "tmpl": [
2870
- "public static ",
3260
+ {
3261
+ "case": {
3262
+ "when": [[{ "eq": ["decl.isPrelude", "true"] }, "internal static "]],
3263
+ "else": "public static "
3264
+ }
3265
+ },
2871
3266
  {
2872
3267
  "case": {
2873
3268
  "when": [
@@ -2905,12 +3300,22 @@
2905
3300
  },
2906
3301
  " ",
2907
3302
  {
2908
- "fn": "ident",
2909
- "args": [
2910
- {
2911
- "get": "decl.name"
3303
+ "case": {
3304
+ "when": [
3305
+ [
3306
+ { "has": "decl.linkName" },
3307
+ { "fn": "mangle", "args": [ { "fn": "ident", "args": [ { "get": "decl.linkName" } ] } ] }
3308
+ ]
3309
+ ],
3310
+ "else": {
3311
+ "fn": "ident",
3312
+ "args": [
3313
+ {
3314
+ "get": "decl.name"
3315
+ }
3316
+ ]
2912
3317
  }
2913
- ]
3318
+ }
2914
3319
  },
2915
3320
  {
2916
3321
  "fn": "generics"
@@ -2943,7 +3348,12 @@
2943
3348
  },
2944
3349
  "csExtSig": {
2945
3350
  "tmpl": [
2946
- "public static ",
3351
+ {
3352
+ "case": {
3353
+ "when": [[{ "eq": ["decl.isPrelude", "true"] }, "internal static "]],
3354
+ "else": "public static "
3355
+ }
3356
+ },
2947
3357
  {
2948
3358
  "type": "decl.returnType"
2949
3359
  },
@@ -3041,7 +3451,8 @@
3041
3451
  },
3042
3452
  "csClassHead": {
3043
3453
  "tmpl": [
3044
- { "fn": "access" },
3454
+ { "call": "csAccess" },
3455
+ { "case": { "when": [ [ { "eq": [ "decl.isAbstract", "true" ] }, "abstract " ] ] } },
3045
3456
  "class ",
3046
3457
  {
3047
3458
  "fn": "ident",
@@ -3159,9 +3570,9 @@
3159
3570
  "when": [
3160
3571
  [
3161
3572
  {
3162
- "eq": [
3163
- "item.hasInit",
3164
- "true"
3573
+ "and": [
3574
+ { "eq": [ "item.hasInit", "true" ] },
3575
+ { "eq": [ "item.deferInit", "false" ] }
3165
3576
  ]
3166
3577
  },
3167
3578
  {
@@ -3186,9 +3597,9 @@
3186
3597
  "when": [
3187
3598
  [
3188
3599
  {
3189
- "eq": [
3190
- "decl.hasInit",
3191
- "true"
3600
+ "or": [
3601
+ { "eq": [ "decl.hasInit", "true" ] },
3602
+ { "not": { "eq": [ "decl.deferredInitFields.count", "0" ] } }
3192
3603
  ]
3193
3604
  },
3194
3605
  {
@@ -3243,6 +3654,12 @@
3243
3654
  ]
3244
3655
  },
3245
3656
  "body": [
3657
+ {
3658
+ "mapDecl": "decl.deferredInitFields",
3659
+ "each": { "line": { "tmpl": [
3660
+ "this.", { "fn": "ident", "args": [ { "get": "item.name" } ] }, " = ", { "emit": "item.init" }, ";"
3661
+ ] } }
3662
+ },
3246
3663
  {
3247
3664
  "stmts": "decl.initBody"
3248
3665
  }
@@ -3264,7 +3681,7 @@
3264
3681
  "block": {
3265
3682
  "head": {
3266
3683
  "tmpl": [
3267
- { "fn": "access" },
3684
+ { "call": "csAccess" },
3268
3685
  "interface ",
3269
3686
  {
3270
3687
  "fn": "ident",
@@ -3391,7 +3808,7 @@
3391
3808
  {
3392
3809
  "line": {
3393
3810
  "tmpl": [
3394
- { "fn": "access" },
3811
+ { "call": "csAccess" },
3395
3812
  "abstract record ",
3396
3813
  {
3397
3814
  "fn": "ident",
@@ -3413,7 +3830,7 @@
3413
3830
  "each": {
3414
3831
  "line": {
3415
3832
  "tmpl": [
3416
- { "fn": "access" },
3833
+ { "call": "csAccess" },
3417
3834
  "sealed record ",
3418
3835
  {
3419
3836
  "fn": "ident",
@@ -3469,6 +3886,32 @@
3469
3886
  "Type": {
3470
3887
  "case": {
3471
3888
  "when": [
3889
+ [
3890
+ {
3891
+ "and": [
3892
+ {
3893
+ "eq": [
3894
+ "type.kind",
3895
+ "function"
3896
+ ]
3897
+ },
3898
+ {
3899
+ "eq": [
3900
+ "type.nullable",
3901
+ "true"
3902
+ ]
3903
+ }
3904
+ ]
3905
+ },
3906
+ {
3907
+ "tmpl": [
3908
+ {
3909
+ "type": "type.base"
3910
+ },
3911
+ "?"
3912
+ ]
3913
+ }
3914
+ ],
3472
3915
  [
3473
3916
  {
3474
3917
  "eq": [
@@ -3658,10 +4101,20 @@
3658
4101
  "List.add": "$this.Add($0)",
3659
4102
  "List.clear": "$this.Clear()",
3660
4103
  "List.removeAll": "$this.RemoveAll($0)",
3661
- "List.removeAt": "$this.RemoveAt($0)"
4104
+ "List.removeAt": "$this.RemoveAt($0)",
4105
+ "IMapKey.type": "notnull",
4106
+ "Map.type": "global::System.Collections.Generic.OrderedDictionary<$0, $1>",
4107
+ "Map.constructor": "new $T()",
4108
+ "Map.count": "$this.Count",
4109
+ "Map.get": "($this.TryGetValue($0, out var $tmp) ? $tmp : ($T)null)",
4110
+ "Map.set": "$this[$0] = $1",
4111
+ "Map.has": "$this.ContainsKey($0)",
4112
+ "Map.remove": "$this.Remove($0)",
4113
+ "Map.keys": "new $T($this.Keys)",
4114
+ "Map.values": "new $T($this.Values)"
3662
4115
  },
3663
4116
  "std.io": {
3664
- "print": "global::System.Console.WriteLine(x is bool __pb ? (__pb ? \"true\" : \"false\") : (object?)x)",
4117
+ "print": { "template": "global::System.Console.WriteLine(__PgRt.Show(x))", "requires": ["pgShow", "pgStrInt", "pgStrFloat"] },
3665
4118
  "readText": "global::System.IO.File.ReadAllText(path)",
3666
4119
  "writeText": "global::System.IO.File.WriteAllText(path, content)",
3667
4120
  "appendText": "global::System.IO.File.AppendAllText(path, content)",
@@ -3672,6 +4125,7 @@
3672
4125
  "Math.PI": "global::System.Math.PI",
3673
4126
  "Math.E": "global::System.Math.E",
3674
4127
  "Math.sqrt": "global::System.Math.Sqrt($0)",
4128
+ "Math.isNaN": "double.IsNaN($0)",
3675
4129
  "Math.ln": "global::System.Math.Log($0)",
3676
4130
  "Math.log": "global::System.Math.Log($0)",
3677
4131
  "Math.log2": "global::System.Math.Log2($0)",
@@ -3704,12 +4158,23 @@
3704
4158
  "std.strings": {
3705
4159
  "string.isEmpty": "($this.Length == 0)",
3706
4160
  "string.len": "$this.Length",
3707
- "string.toUpper": "$this.ToUpper()",
3708
- "string.toLower": "$this.ToLower()",
3709
- "string.charAt": "$this[$0].ToString()",
3710
- "string.codePointAt": "char.ConvertToUtf32($this, $0)",
4161
+ "string.toUpper": "$this.ToUpperInvariant()",
4162
+ "string.toLower": "$this.ToLowerInvariant()",
4163
+ "string.toUpperAscii": { "template": "__PgRt.UpperAscii($this)", "requires": ["pgAscii"] },
4164
+ "string.toLowerAscii": { "template": "__PgRt.LowerAscii($this)", "requires": ["pgAscii"] },
3711
4165
  "string.codePoints": "global::System.Linq.Enumerable.Select($this.EnumerateRunes(), __r => __r.ToString())",
3712
- "string.toI32": "global::System.Int32.Parse($this)"
4166
+ "string.startsWith": "$this.StartsWith($0, global::System.StringComparison.Ordinal)",
4167
+ "string.endsWith": "$this.EndsWith($0, global::System.StringComparison.Ordinal)",
4168
+ "string.contains": "$this.Contains($0)",
4169
+ "string.trimAscii": "$this.Trim('\\t', '\\n', '\\v', '\\f', '\\r', ' ')",
4170
+ "compareOrdinal": "global::System.Math.Sign(string.CompareOrdinal(a, b))",
4171
+ "string.__pgCharAt": "$this[$0].ToString()",
4172
+ "string.__pgCodePointAt": "(char.IsSurrogatePair($this, $0) ? char.ConvertToUtf32($this, $0) : (int)$this[$0])",
4173
+ "string.__pgSubstring": "$this.Substring($0, $1 - $0)",
4174
+ "string.__pgIndexOf": "$this.IndexOf($0, $1, global::System.StringComparison.Ordinal)",
4175
+ "string.__pgReplaceAll": "$this.Replace($0, $1)",
4176
+ "string.__pgSplit": "new global::System.Collections.Generic.List<string>($this.Split($0))",
4177
+ "string.__pgFromCodePoint": "char.ConvertFromUtf32($0)"
3713
4178
  },
3714
4179
  "std.core": {
3715
4180
  "Error.type": "global::System.Exception",
@@ -3719,17 +4184,20 @@
3719
4184
  "Array.type": "$0[]",
3720
4185
  "Array.constructor": "global::System.Array.Empty<$0>()",
3721
4186
  "Array.count": "$this.Length",
3722
- "i8.parse": "sbyte.Parse($0)",
3723
- "i16.parse": "short.Parse($0)",
3724
- "i32.parse": "int.Parse($0)",
3725
- "i64.parse": "long.Parse($0)",
3726
- "u8.parse": "byte.Parse($0)",
3727
- "u16.parse": "ushort.Parse($0)",
3728
- "u32.parse": "uint.Parse($0)",
3729
- "u64.parse": "ulong.Parse($0)",
3730
- "f32.parse": "float.Parse($0, global::System.Globalization.CultureInfo.InvariantCulture)",
3731
- "f64.parse": "double.Parse($0, global::System.Globalization.CultureInfo.InvariantCulture)"
4187
+ "__pgText.rawLen": "$0.Length",
4188
+ "__pgText.rawCode": "((int)$0[$1])",
4189
+ "i8.__pgParse": "sbyte.Parse($0, global::System.Globalization.NumberStyles.Integer, global::System.Globalization.CultureInfo.InvariantCulture)",
4190
+ "i16.__pgParse": "short.Parse($0, global::System.Globalization.NumberStyles.Integer, global::System.Globalization.CultureInfo.InvariantCulture)",
4191
+ "i32.__pgParse": "int.Parse($0, global::System.Globalization.NumberStyles.Integer, global::System.Globalization.CultureInfo.InvariantCulture)",
4192
+ "i64.__pgParse": "long.Parse($0, global::System.Globalization.NumberStyles.Integer, global::System.Globalization.CultureInfo.InvariantCulture)",
4193
+ "u8.__pgParse": "byte.Parse($0, global::System.Globalization.NumberStyles.Integer, global::System.Globalization.CultureInfo.InvariantCulture)",
4194
+ "u16.__pgParse": "ushort.Parse($0, global::System.Globalization.NumberStyles.Integer, global::System.Globalization.CultureInfo.InvariantCulture)",
4195
+ "u32.__pgParse": "uint.Parse($0, global::System.Globalization.NumberStyles.Integer, global::System.Globalization.CultureInfo.InvariantCulture)",
4196
+ "u64.__pgParse": "ulong.Parse($0, global::System.Globalization.NumberStyles.Integer, global::System.Globalization.CultureInfo.InvariantCulture)",
4197
+ "f32.__pgParse": "float.Parse($0, global::System.Globalization.NumberStyles.Float, global::System.Globalization.CultureInfo.InvariantCulture)",
4198
+ "f64.__pgParse": "double.Parse($0, global::System.Globalization.NumberStyles.Float, global::System.Globalization.CultureInfo.InvariantCulture)"
3732
4199
  }
3733
4200
  },
3734
- "fileExtension": ".cs"
4201
+ "fileExtension": ".cs",
4202
+ "lineComment": "//"
3735
4203
  }