naider 1.15.0 → 1.17.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.
- package/README.md +161 -7
- package/SPEC.naide +102 -0
- package/lsp/server.js +48 -0
- package/package.json +2 -2
- package/src/generator-c.js +48 -0
- package/src/generator-cpp.js +53 -0
- package/src/generator-csharp.js +67 -0
- package/src/generator-dart.js +69 -0
- package/src/generator-go.js +62 -0
- package/src/generator-java.js +61 -0
- package/src/generator-kotlin.js +67 -0
- package/src/generator-php.js +69 -0
- package/src/generator-python.js +73 -0
- package/src/generator-ruby.js +69 -0
- package/src/generator-rust.js +61 -0
- package/src/generator-swift.js +67 -0
- package/src/generator.js +73 -0
- package/src/parser.js +111 -4
- package/src/tokens.js +15 -0
- package/vscode-naide/syntaxes/naide.tmLanguage.json +6 -2
package/src/generator-dart.js
CHANGED
|
@@ -162,6 +162,8 @@ export class DartGenerator {
|
|
|
162
162
|
case 'GrpcDecl': return this.visitGrpc(node);
|
|
163
163
|
case 'WebrtcDecl': return this.visitWebrtc(node);
|
|
164
164
|
case 'BlockchainDecl': return this.visitBlockchain(node);
|
|
165
|
+
case 'EnumDecl': return this.visitEnum(node);
|
|
166
|
+
case 'Swap': return this.visitSwap(node);
|
|
165
167
|
default:
|
|
166
168
|
this.emit(`// unknown: ${node.type}`);
|
|
167
169
|
}
|
|
@@ -1364,6 +1366,12 @@ export class DartGenerator {
|
|
|
1364
1366
|
generateCall(node) {
|
|
1365
1367
|
const args = node.args.map(a => this.expr(a)).join(', ');
|
|
1366
1368
|
|
|
1369
|
+
if (node.callee.type === 'Identifier') {
|
|
1370
|
+
const argList = node.args.map(a => this.expr(a));
|
|
1371
|
+
const b = this.generateBuiltin(node.callee.name, argList);
|
|
1372
|
+
if (b) return b;
|
|
1373
|
+
}
|
|
1374
|
+
|
|
1367
1375
|
if (node.callee.type === 'Identifier') {
|
|
1368
1376
|
const name = node.callee.name;
|
|
1369
1377
|
if (name === 'parseInt') return `int.parse(${args})`;
|
|
@@ -1566,4 +1574,65 @@ export class DartGenerator {
|
|
|
1566
1574
|
this.inFunction = wasInFunction;
|
|
1567
1575
|
return result;
|
|
1568
1576
|
}
|
|
1577
|
+
|
|
1578
|
+
visitEnum(node) {
|
|
1579
|
+
this.emit(`enum ${node.name} {`);
|
|
1580
|
+
this.indent++;
|
|
1581
|
+
node.values.forEach(v => {
|
|
1582
|
+
this.emit(`${v.toLowerCase()},`);
|
|
1583
|
+
});
|
|
1584
|
+
this.indent--;
|
|
1585
|
+
this.emit(`}`);
|
|
1586
|
+
this.emitRaw('');
|
|
1587
|
+
}
|
|
1588
|
+
|
|
1589
|
+
visitSwap(node) {
|
|
1590
|
+
const a = this.expr(node.a);
|
|
1591
|
+
const b = this.expr(node.b);
|
|
1592
|
+
this.emit(`{ final _tmp = ${a}; ${a} = ${b}; ${b} = _tmp; }`);
|
|
1593
|
+
}
|
|
1594
|
+
|
|
1595
|
+
generateBuiltin(name, args) {
|
|
1596
|
+
switch (name) {
|
|
1597
|
+
case 'len': return `${args[0]}.length`;
|
|
1598
|
+
case 'sort': return `(List.from(${args[0]})..sort())`;
|
|
1599
|
+
case 'reverse': return `${args[0]}.reversed.toList()`;
|
|
1600
|
+
case 'unique': return `${args[0]}.toSet().toList()`;
|
|
1601
|
+
case 'upper': return `${args[0]}.toUpperCase()`;
|
|
1602
|
+
case 'lower': return `${args[0]}.toLowerCase()`;
|
|
1603
|
+
case 'trim': return `${args[0]}.trim()`;
|
|
1604
|
+
case 'split': return `${args[0]}.split(${args[1] || '","'})`;
|
|
1605
|
+
case 'join': return `${args[0]}.join(${args[1] || '","'})`;
|
|
1606
|
+
case 'contains': return `${args[0]}.contains(${args[1]})`;
|
|
1607
|
+
case 'replace': return `${args[0]}.replaceAll(${args[1]}, ${args[2]})`;
|
|
1608
|
+
case 'keys': return `${args[0]}.keys.toList()`;
|
|
1609
|
+
case 'values': return `${args[0]}.values.toList()`;
|
|
1610
|
+
case 'entries': return `${args[0]}.entries.toList()`;
|
|
1611
|
+
case 'range': return args.length >= 2 ? `List.generate(${args[1]} - ${args[0]}, (i) => i + ${args[0]})` : `List.generate(${args[0]}, (i) => i)`;
|
|
1612
|
+
case 'abs': return `${args[0]}.abs()`;
|
|
1613
|
+
case 'sqrt': { this.addImport('dart:math'); return `sqrt(${args[0]}.toDouble())`; }
|
|
1614
|
+
case 'pow': { this.addImport('dart:math'); return `pow(${args[0]}, ${args[1]})`; }
|
|
1615
|
+
case 'ceil': return `${args[0]}.ceil()`;
|
|
1616
|
+
case 'floor': return `${args[0]}.floor()`;
|
|
1617
|
+
case 'round': return `${args[0]}.round()`;
|
|
1618
|
+
case 'sum': return `${args[0]}.reduce((a, b) => a + b)`;
|
|
1619
|
+
case 'flat': return `${args[0]}.expand((x) => x).toList()`;
|
|
1620
|
+
case 'zip': return `List.generate(${args[0]}.length, (i) => [${args[0]}[i], ${args[1]}[i]])`;
|
|
1621
|
+
case 'chunk': return `[for (var i = 0; i < ${args[0]}.length; i += ${args[1]}) ${args[0]}.sublist(i, i + ${args[1]} > ${args[0]}.length ? ${args[0]}.length : i + ${args[1]})]`;
|
|
1622
|
+
case 'str': return `${args[0]}.toString()`;
|
|
1623
|
+
case 'int': return `int.parse(${args[0]})`;
|
|
1624
|
+
case 'float': return `double.parse(${args[0]})`;
|
|
1625
|
+
case 'json_parse': { this.addImport('dart:convert'); return `jsonDecode(${args[0]})`; }
|
|
1626
|
+
case 'json_str': { this.addImport('dart:convert'); return `jsonEncode(${args[0]})`; }
|
|
1627
|
+
case 'now': return `DateTime.now().millisecondsSinceEpoch`;
|
|
1628
|
+
case 'time': return `DateTime.now().toIso8601String()`;
|
|
1629
|
+
case 'exit': return `exit(${args[0] || '0'})`;
|
|
1630
|
+
case 'sleep': return `await Future.delayed(Duration(milliseconds: ${args[0]}))`;
|
|
1631
|
+
case 'random': { this.addImport('dart:math'); return args.length >= 2 ? `(Random().nextInt(${args[1]} - ${args[0]} + 1) + ${args[0]})` : `Random().nextDouble()`; }
|
|
1632
|
+
case 'read': { this.addImport('dart:io'); return `File(${args[0]}).readAsStringSync()`; }
|
|
1633
|
+
case 'write': { this.addImport('dart:io'); return `File(${args[0]}).writeAsStringSync(${args[1]})`; }
|
|
1634
|
+
case 'ask': { this.addImport('dart:io'); return `((){stdout.write(${args[0] || '""'}); return stdin.readLineSync() ?? "";}())`; }
|
|
1635
|
+
default: return null;
|
|
1636
|
+
}
|
|
1637
|
+
}
|
|
1569
1638
|
}
|
package/src/generator-go.js
CHANGED
|
@@ -116,6 +116,8 @@ export class GoGenerator {
|
|
|
116
116
|
case 'GrpcDecl': return this.visitGrpc(node);
|
|
117
117
|
case 'WebrtcDecl': return this.visitWebrtc(node);
|
|
118
118
|
case 'BlockchainDecl': return this.visitBlockchain(node);
|
|
119
|
+
case 'EnumDecl': return this.visitEnum(node);
|
|
120
|
+
case 'Swap': return this.visitSwap(node);
|
|
119
121
|
default:
|
|
120
122
|
this.emit(`// unknown: ${node.type}`);
|
|
121
123
|
}
|
|
@@ -1614,6 +1616,12 @@ export class GoGenerator {
|
|
|
1614
1616
|
}
|
|
1615
1617
|
|
|
1616
1618
|
generateCall(node) {
|
|
1619
|
+
if (node.callee.type === 'Identifier') {
|
|
1620
|
+
const argList = node.args.map(a => this.expr(a));
|
|
1621
|
+
const b = this.generateBuiltin(node.callee.name, argList);
|
|
1622
|
+
if (b) return b;
|
|
1623
|
+
}
|
|
1624
|
+
|
|
1617
1625
|
const args = node.args.map(a => this.expr(a)).join(', ');
|
|
1618
1626
|
|
|
1619
1627
|
// Map common JS global functions to Go
|
|
@@ -1778,4 +1786,58 @@ export class GoGenerator {
|
|
|
1778
1786
|
this.indent = savedIndent;
|
|
1779
1787
|
return result;
|
|
1780
1788
|
}
|
|
1789
|
+
|
|
1790
|
+
visitEnum(node) {
|
|
1791
|
+
this.emit(`type ${node.name} int`);
|
|
1792
|
+
this.emit(`const (`);
|
|
1793
|
+
this.indent++;
|
|
1794
|
+
node.values.forEach((v, i) => {
|
|
1795
|
+
if (i === 0) {
|
|
1796
|
+
this.emit(`${v} ${node.name} = iota`);
|
|
1797
|
+
} else {
|
|
1798
|
+
this.emit(`${v}`);
|
|
1799
|
+
}
|
|
1800
|
+
});
|
|
1801
|
+
this.indent--;
|
|
1802
|
+
this.emit(`)`);
|
|
1803
|
+
this.emitRaw('');
|
|
1804
|
+
}
|
|
1805
|
+
|
|
1806
|
+
visitSwap(node) {
|
|
1807
|
+
const a = this.expr(node.a);
|
|
1808
|
+
const b = this.expr(node.b);
|
|
1809
|
+
this.emit(`${a}, ${b} = ${b}, ${a}`);
|
|
1810
|
+
}
|
|
1811
|
+
|
|
1812
|
+
generateBuiltin(name, args) {
|
|
1813
|
+
switch (name) {
|
|
1814
|
+
case 'len': return `len(${args[0]})`;
|
|
1815
|
+
case 'str': { this.addImport('strconv'); return `strconv.Itoa(${args[0]})`; }
|
|
1816
|
+
case 'int': { this.addImport('strconv'); return `func() int { v, _ := strconv.Atoi(${args[0]}); return v }()`; }
|
|
1817
|
+
case 'float': { this.addImport('strconv'); return `func() float64 { v, _ := strconv.ParseFloat(${args[0]}, 64); return v }()`; }
|
|
1818
|
+
case 'upper': { this.addImport('strings'); return `strings.ToUpper(${args[0]})`; }
|
|
1819
|
+
case 'lower': { this.addImport('strings'); return `strings.ToLower(${args[0]})`; }
|
|
1820
|
+
case 'trim': { this.addImport('strings'); return `strings.TrimSpace(${args[0]})`; }
|
|
1821
|
+
case 'split': { this.addImport('strings'); return `strings.Split(${args[0]}, ${args[1] || '","'})`; }
|
|
1822
|
+
case 'join': { this.addImport('strings'); return `strings.Join(${args[0]}, ${args[1] || '","'})`; }
|
|
1823
|
+
case 'contains': { this.addImport('strings'); return `strings.Contains(${args[0]}, ${args[1]})`; }
|
|
1824
|
+
case 'replace': { this.addImport('strings'); return `strings.ReplaceAll(${args[0]}, ${args[1]}, ${args[2]})`; }
|
|
1825
|
+
case 'abs': { this.addImport('math'); return `math.Abs(${args[0]})`; }
|
|
1826
|
+
case 'sqrt': { this.addImport('math'); return `math.Sqrt(${args[0]})`; }
|
|
1827
|
+
case 'pow': { this.addImport('math'); return `math.Pow(${args[0]}, ${args[1]})`; }
|
|
1828
|
+
case 'ceil': { this.addImport('math'); return `math.Ceil(${args[0]})`; }
|
|
1829
|
+
case 'floor': { this.addImport('math'); return `math.Floor(${args[0]})`; }
|
|
1830
|
+
case 'round': { this.addImport('math'); return `math.Round(${args[0]})`; }
|
|
1831
|
+
case 'exit': { this.addImport('os'); return `os.Exit(${args[0] || '0'})`; }
|
|
1832
|
+
case 'sleep': { this.addImport('time'); return `time.Sleep(time.Duration(${args[0]}) * time.Millisecond)`; }
|
|
1833
|
+
case 'now': { this.addImport('time'); return `time.Now().UnixMilli()`; }
|
|
1834
|
+
case 'time': { this.addImport('time'); return `time.Now().Format(time.RFC3339)`; }
|
|
1835
|
+
case 'json_parse': { this.addImport('encoding/json'); return `func() interface{} { var v interface{}; json.Unmarshal([]byte(${args[0]}), &v); return v }()`; }
|
|
1836
|
+
case 'json_str': { this.addImport('encoding/json'); return `func() string { b, _ := json.Marshal(${args[0]}); return string(b) }()`; }
|
|
1837
|
+
case 'random': { this.addImport('math/rand'); return args.length >= 2 ? `rand.Intn(${args[1]}-${args[0]}+1)+${args[0]}` : `rand.Float64()`; }
|
|
1838
|
+
case 'sort': { this.addImport('sort'); return `func() []int { s := make([]int, len(${args[0]})); copy(s, ${args[0]}); sort.Ints(s); return s }()`; }
|
|
1839
|
+
case 'reverse': return `func() []interface{} { s := make([]interface{}, len(${args[0]})); copy(s, ${args[0]}); for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 { s[i], s[j] = s[j], s[i] }; return s }()`;
|
|
1840
|
+
default: return null;
|
|
1841
|
+
}
|
|
1842
|
+
}
|
|
1781
1843
|
}
|
package/src/generator-java.js
CHANGED
|
@@ -226,6 +226,8 @@ export class JavaGenerator {
|
|
|
226
226
|
case 'GrpcDecl': return this.visitGrpc(node);
|
|
227
227
|
case 'WebrtcDecl': return this.visitWebrtc(node);
|
|
228
228
|
case 'BlockchainDecl': return this.visitBlockchain(node);
|
|
229
|
+
case 'EnumDecl': return this.visitEnum(node);
|
|
230
|
+
case 'Swap': return this.visitSwap(node);
|
|
229
231
|
default:
|
|
230
232
|
this.emit(`/* unknown: ${node.type} */`);
|
|
231
233
|
}
|
|
@@ -1598,6 +1600,12 @@ export class JavaGenerator {
|
|
|
1598
1600
|
}
|
|
1599
1601
|
|
|
1600
1602
|
generateCall(node) {
|
|
1603
|
+
if (node.callee.type === 'Identifier') {
|
|
1604
|
+
const argList = node.args.map(a => this.expr(a));
|
|
1605
|
+
const b = this.generateBuiltin(node.callee.name, argList);
|
|
1606
|
+
if (b) return b;
|
|
1607
|
+
}
|
|
1608
|
+
|
|
1601
1609
|
const args = node.args.map(a => this.expr(a)).join(', ');
|
|
1602
1610
|
|
|
1603
1611
|
if (node.callee.type === 'Identifier') {
|
|
@@ -1811,4 +1819,57 @@ export class JavaGenerator {
|
|
|
1811
1819
|
this.indent = savedIndent;
|
|
1812
1820
|
return result;
|
|
1813
1821
|
}
|
|
1822
|
+
|
|
1823
|
+
visitEnum(node) {
|
|
1824
|
+
this.emit(`enum ${node.name} {`);
|
|
1825
|
+
this.indent++;
|
|
1826
|
+
this.emit(node.values.join(', ') + ';');
|
|
1827
|
+
this.indent--;
|
|
1828
|
+
this.emit(`}`);
|
|
1829
|
+
this.emitRaw('');
|
|
1830
|
+
}
|
|
1831
|
+
|
|
1832
|
+
visitSwap(node) {
|
|
1833
|
+
const a = this.expr(node.a);
|
|
1834
|
+
const b = this.expr(node.b);
|
|
1835
|
+
this.emit(`{ var _tmp = ${a}; ${a} = ${b}; ${b} = _tmp; }`);
|
|
1836
|
+
}
|
|
1837
|
+
|
|
1838
|
+
generateBuiltin(name, args) {
|
|
1839
|
+
switch (name) {
|
|
1840
|
+
case 'len': return `${args[0]}.size()`;
|
|
1841
|
+
case 'sort': return `${args[0]}.stream().sorted().collect(java.util.stream.Collectors.toList())`;
|
|
1842
|
+
case 'reverse': return `{ var _l = new java.util.ArrayList<>(${args[0]}); java.util.Collections.reverse(_l); return _l; }`;
|
|
1843
|
+
case 'contains': return `${args[0]}.contains(${args[1]})`;
|
|
1844
|
+
case 'keys': return `new java.util.ArrayList<>(${args[0]}.keySet())`;
|
|
1845
|
+
case 'values': return `new java.util.ArrayList<>(${args[0]}.values())`;
|
|
1846
|
+
case 'entries': return `new java.util.ArrayList<>(${args[0]}.entrySet())`;
|
|
1847
|
+
case 'abs': return `Math.abs(${args[0]})`;
|
|
1848
|
+
case 'sqrt': return `Math.sqrt(${args[0]})`;
|
|
1849
|
+
case 'pow': return `Math.pow(${args[0]}, ${args[1]})`;
|
|
1850
|
+
case 'ceil': return `Math.ceil(${args[0]})`;
|
|
1851
|
+
case 'floor': return `Math.floor(${args[0]})`;
|
|
1852
|
+
case 'round': return `Math.round(${args[0]})`;
|
|
1853
|
+
case 'random': return args.length >= 2 ? `new java.util.Random().nextInt(${args[1]} - ${args[0]} + 1) + ${args[0]}` : `Math.random()`;
|
|
1854
|
+
case 'str': return `String.valueOf(${args[0]})`;
|
|
1855
|
+
case 'int': return `Integer.parseInt(${args[0]})`;
|
|
1856
|
+
case 'float': return `Double.parseDouble(${args[0]})`;
|
|
1857
|
+
case 'upper': return `${args[0]}.toUpperCase()`;
|
|
1858
|
+
case 'lower': return `${args[0]}.toLowerCase()`;
|
|
1859
|
+
case 'trim': return `${args[0]}.trim()`;
|
|
1860
|
+
case 'split': return `java.util.Arrays.asList(${args[0]}.split(${args[1] || '","'}))`;
|
|
1861
|
+
case 'join': return `String.join(${args[1] || '","'}, ${args[0]})`;
|
|
1862
|
+
case 'replace': return `${args[0]}.replace(${args[1]}, ${args[2]})`;
|
|
1863
|
+
case 'sum': return `${args[0]}.stream().mapToInt(Integer::intValue).sum()`;
|
|
1864
|
+
case 'unique': return `new java.util.ArrayList<>(new java.util.LinkedHashSet<>(${args[0]}))`;
|
|
1865
|
+
case 'exit': return `System.exit(${args[0] || '0'})`;
|
|
1866
|
+
case 'sleep': return `Thread.sleep(${args[0]})`;
|
|
1867
|
+
case 'now': return `System.currentTimeMillis()`;
|
|
1868
|
+
case 'time': return `java.time.LocalDateTime.now().toString()`;
|
|
1869
|
+
case 'json_parse': return `new com.google.gson.Gson().fromJson(${args[0]}, Object.class)`;
|
|
1870
|
+
case 'json_str': return `new com.google.gson.Gson().toJson(${args[0]})`;
|
|
1871
|
+
case 'range': return args.length >= 2 ? `java.util.stream.IntStream.range(${args[0]}, ${args[1]}).boxed().collect(java.util.stream.Collectors.toList())` : `java.util.stream.IntStream.range(0, ${args[0]}).boxed().collect(java.util.stream.Collectors.toList())`;
|
|
1872
|
+
default: return null;
|
|
1873
|
+
}
|
|
1874
|
+
}
|
|
1814
1875
|
}
|
package/src/generator-kotlin.js
CHANGED
|
@@ -137,6 +137,8 @@ export class KotlinGenerator {
|
|
|
137
137
|
case 'GrpcDecl': return this.visitGrpc(node);
|
|
138
138
|
case 'WebrtcDecl': return this.visitWebrtc(node);
|
|
139
139
|
case 'BlockchainDecl': return this.visitBlockchain(node);
|
|
140
|
+
case 'EnumDecl': return this.visitEnum(node);
|
|
141
|
+
case 'Swap': return this.visitSwap(node);
|
|
140
142
|
default:
|
|
141
143
|
this.emit(`// unknown: ${node.type}`);
|
|
142
144
|
}
|
|
@@ -1641,6 +1643,12 @@ export class KotlinGenerator {
|
|
|
1641
1643
|
generateCall(node) {
|
|
1642
1644
|
const args = node.args.map(a => this.expr(a)).join(', ');
|
|
1643
1645
|
|
|
1646
|
+
if (node.callee.type === 'Identifier') {
|
|
1647
|
+
const argList = node.args.map(a => this.expr(a));
|
|
1648
|
+
const b = this.generateBuiltin(node.callee.name, argList);
|
|
1649
|
+
if (b) return b;
|
|
1650
|
+
}
|
|
1651
|
+
|
|
1644
1652
|
if (node.callee.type === 'Identifier') {
|
|
1645
1653
|
const name = node.callee.name;
|
|
1646
1654
|
if (name === 'parseInt') return `(${args}).toInt()`;
|
|
@@ -1816,4 +1824,63 @@ export class KotlinGenerator {
|
|
|
1816
1824
|
this.indent = savedIndent;
|
|
1817
1825
|
return result;
|
|
1818
1826
|
}
|
|
1827
|
+
|
|
1828
|
+
visitEnum(node) {
|
|
1829
|
+
this.emit(`enum class ${node.name} {`);
|
|
1830
|
+
this.indent++;
|
|
1831
|
+
this.emit(node.values.join(', '));
|
|
1832
|
+
this.indent--;
|
|
1833
|
+
this.emit(`}`);
|
|
1834
|
+
this.emitRaw('');
|
|
1835
|
+
}
|
|
1836
|
+
|
|
1837
|
+
visitSwap(node) {
|
|
1838
|
+
const a = this.expr(node.a);
|
|
1839
|
+
const b = this.expr(node.b);
|
|
1840
|
+
this.emit(`${a} = ${b}.also { ${b} = ${a} }`);
|
|
1841
|
+
}
|
|
1842
|
+
|
|
1843
|
+
generateBuiltin(name, args) {
|
|
1844
|
+
switch (name) {
|
|
1845
|
+
case 'len': return `${args[0]}.size`;
|
|
1846
|
+
case 'sort': return `${args[0]}.sorted()`;
|
|
1847
|
+
case 'reverse': return `${args[0]}.reversed()`;
|
|
1848
|
+
case 'unique': return `${args[0]}.distinct()`;
|
|
1849
|
+
case 'upper': return `${args[0]}.uppercase()`;
|
|
1850
|
+
case 'lower': return `${args[0]}.lowercase()`;
|
|
1851
|
+
case 'trim': return `${args[0]}.trim()`;
|
|
1852
|
+
case 'split': return `${args[0]}.split(${args[1] || '","'})`;
|
|
1853
|
+
case 'join': return `${args[0]}.joinToString(${args[1] || '","'})`;
|
|
1854
|
+
case 'contains': return `${args[0]}.contains(${args[1]})`;
|
|
1855
|
+
case 'replace': return `${args[0]}.replace(${args[1]}, ${args[2]})`;
|
|
1856
|
+
case 'keys': return `${args[0]}.keys.toList()`;
|
|
1857
|
+
case 'values': return `${args[0]}.values.toList()`;
|
|
1858
|
+
case 'entries': return `${args[0]}.entries.toList()`;
|
|
1859
|
+
case 'range': return args.length >= 2 ? `(${args[0]} until ${args[1]}).toList()` : `(0 until ${args[0]}).toList()`;
|
|
1860
|
+
case 'abs': return `kotlin.math.abs(${args[0]})`;
|
|
1861
|
+
case 'sqrt': return `kotlin.math.sqrt(${args[0]}.toDouble())`;
|
|
1862
|
+
case 'pow': return `kotlin.math.pow(${args[0]}.toDouble(), ${args[1]}.toDouble())`;
|
|
1863
|
+
case 'ceil': return `kotlin.math.ceil(${args[0]}.toDouble())`;
|
|
1864
|
+
case 'floor': return `kotlin.math.floor(${args[0]}.toDouble())`;
|
|
1865
|
+
case 'round': return `kotlin.math.round(${args[0]}.toDouble())`;
|
|
1866
|
+
case 'sum': return `${args[0]}.sum()`;
|
|
1867
|
+
case 'flat': return `${args[0]}.flatten()`;
|
|
1868
|
+
case 'zip': return `${args[0]}.zip(${args[1]})`;
|
|
1869
|
+
case 'chunk': return `${args[0]}.chunked(${args[1]})`;
|
|
1870
|
+
case 'str': return `${args[0]}.toString()`;
|
|
1871
|
+
case 'int': return `${args[0]}.toInt()`;
|
|
1872
|
+
case 'float': return `${args[0]}.toDouble()`;
|
|
1873
|
+
case 'json_parse': return `com.google.gson.Gson().fromJson(${args[0]}, Any::class.java)`;
|
|
1874
|
+
case 'json_str': return `com.google.gson.Gson().toJson(${args[0]})`;
|
|
1875
|
+
case 'now': return `System.currentTimeMillis()`;
|
|
1876
|
+
case 'time': return `java.time.LocalDateTime.now().toString()`;
|
|
1877
|
+
case 'exit': return `kotlin.system.exitProcess(${args[0] || '0'})`;
|
|
1878
|
+
case 'sleep': return `Thread.sleep(${args[0]}.toLong())`;
|
|
1879
|
+
case 'random': return args.length >= 2 ? `(${args[0]}..${args[1]}).random()` : `kotlin.random.Random.nextDouble()`;
|
|
1880
|
+
case 'read': return `java.io.File(${args[0]}).readText()`;
|
|
1881
|
+
case 'write': return `java.io.File(${args[0]}).writeText(${args[1]})`;
|
|
1882
|
+
case 'ask': return `(print(${args[0] || '""'}); readLine() ?: "")`;
|
|
1883
|
+
default: return null;
|
|
1884
|
+
}
|
|
1885
|
+
}
|
|
1819
1886
|
}
|
package/src/generator-php.js
CHANGED
|
@@ -103,6 +103,8 @@ export class PhpGenerator {
|
|
|
103
103
|
case 'GrpcDecl': return this.visitGrpc(node);
|
|
104
104
|
case 'WebrtcDecl': return this.visitWebrtc(node);
|
|
105
105
|
case 'BlockchainDecl': return this.visitBlockchain(node);
|
|
106
|
+
case 'EnumDecl': return this.visitEnum(node);
|
|
107
|
+
case 'Swap': return this.visitSwap(node);
|
|
106
108
|
default:
|
|
107
109
|
this.emit(`/* unknown: ${node.type} */`);
|
|
108
110
|
}
|
|
@@ -1366,6 +1368,12 @@ export class PhpGenerator {
|
|
|
1366
1368
|
}
|
|
1367
1369
|
|
|
1368
1370
|
generateCall(node) {
|
|
1371
|
+
if (node.callee.type === 'Identifier') {
|
|
1372
|
+
const argList = node.args.map(a => this.expr(a));
|
|
1373
|
+
const b = this.generateBuiltin(node.callee.name, argList);
|
|
1374
|
+
if (b) return b;
|
|
1375
|
+
}
|
|
1376
|
+
|
|
1369
1377
|
const args = node.args.map(a => this.expr(a)).join(', ');
|
|
1370
1378
|
|
|
1371
1379
|
// Map global function calls
|
|
@@ -1573,4 +1581,65 @@ export class PhpGenerator {
|
|
|
1573
1581
|
this.indent = savedIndent;
|
|
1574
1582
|
return result;
|
|
1575
1583
|
}
|
|
1584
|
+
|
|
1585
|
+
visitEnum(node) {
|
|
1586
|
+
this.emit(`class ${node.name} {`);
|
|
1587
|
+
this.indent++;
|
|
1588
|
+
node.values.forEach((v, i) => {
|
|
1589
|
+
this.emit(`const ${v} = ${i};`);
|
|
1590
|
+
});
|
|
1591
|
+
this.indent--;
|
|
1592
|
+
this.emit(`}`);
|
|
1593
|
+
this.emitRaw('');
|
|
1594
|
+
}
|
|
1595
|
+
|
|
1596
|
+
visitSwap(node) {
|
|
1597
|
+
const a = this.expr(node.a);
|
|
1598
|
+
const b = this.expr(node.b);
|
|
1599
|
+
this.emit(`[$${a.replace('$','')}, $${b.replace('$','')}] = [$${b.replace('$','')}, $${a.replace('$','')}];`);
|
|
1600
|
+
}
|
|
1601
|
+
|
|
1602
|
+
generateBuiltin(name, args) {
|
|
1603
|
+
switch (name) {
|
|
1604
|
+
case 'len': return `count(${args[0]})`;
|
|
1605
|
+
case 'sort': return `(function($a) { sort($a); return $a; })(${args[0]})`;
|
|
1606
|
+
case 'reverse': return `array_reverse(${args[0]})`;
|
|
1607
|
+
case 'unique': return `array_values(array_unique(${args[0]}))`;
|
|
1608
|
+
case 'upper': return `strtoupper(${args[0]})`;
|
|
1609
|
+
case 'lower': return `strtolower(${args[0]})`;
|
|
1610
|
+
case 'trim': return `trim(${args[0]})`;
|
|
1611
|
+
case 'split': return `explode(${args[1] || '","'}, ${args[0]})`;
|
|
1612
|
+
case 'join': return `implode(${args[1] || '","'}, ${args[0]})`;
|
|
1613
|
+
case 'contains': return `in_array(${args[1]}, ${args[0]})`;
|
|
1614
|
+
case 'replace': return `str_replace(${args[1]}, ${args[2]}, ${args[0]})`;
|
|
1615
|
+
case 'keys': return `array_keys(${args[0]})`;
|
|
1616
|
+
case 'values': return `array_values(${args[0]})`;
|
|
1617
|
+
case 'entries': return `array_map(null, array_keys(${args[0]}), array_values(${args[0]}))`;
|
|
1618
|
+
case 'range': return args.length >= 2 ? `range(${args[0]}, ${args[1]} - 1)` : `range(0, ${args[0]} - 1)`;
|
|
1619
|
+
case 'abs': return `abs(${args[0]})`;
|
|
1620
|
+
case 'round': return `round(${args[0]})`;
|
|
1621
|
+
case 'ceil': return `ceil(${args[0]})`;
|
|
1622
|
+
case 'floor': return `floor(${args[0]})`;
|
|
1623
|
+
case 'sqrt': return `sqrt(${args[0]})`;
|
|
1624
|
+
case 'pow': return `pow(${args[0]}, ${args[1]})`;
|
|
1625
|
+
case 'sum': return `array_sum(${args[0]})`;
|
|
1626
|
+
case 'flat': return `array_merge(...${args[0]})`;
|
|
1627
|
+
case 'str': return `strval(${args[0]})`;
|
|
1628
|
+
case 'int': return `intval(${args[0]})`;
|
|
1629
|
+
case 'float': return `floatval(${args[0]})`;
|
|
1630
|
+
case 'json_parse': return `json_decode(${args[0]}, true)`;
|
|
1631
|
+
case 'json_str': return `json_encode(${args[0]})`;
|
|
1632
|
+
case 'now': return `(int)(microtime(true) * 1000)`;
|
|
1633
|
+
case 'time': return `date('c')`;
|
|
1634
|
+
case 'exit': return `exit(${args[0] || '0'})`;
|
|
1635
|
+
case 'sleep': return `usleep(${args[0]} * 1000)`;
|
|
1636
|
+
case 'random': return args.length >= 2 ? `random_int(${args[0]}, ${args[1]})` : `(mt_rand() / mt_getrandmax())`;
|
|
1637
|
+
case 'read': return `file_get_contents(${args[0]})`;
|
|
1638
|
+
case 'write': return `file_put_contents(${args[0]}, ${args[1]})`;
|
|
1639
|
+
case 'ask': return `readline(${args[0] || '""'})`;
|
|
1640
|
+
case 'chunk': return `array_chunk(${args[0]}, ${args[1]})`;
|
|
1641
|
+
case 'zip': return `array_map(null, ${args[0]}, ${args[1]})`;
|
|
1642
|
+
default: return null;
|
|
1643
|
+
}
|
|
1644
|
+
}
|
|
1576
1645
|
}
|
package/src/generator-python.js
CHANGED
|
@@ -162,6 +162,8 @@ export class PythonGenerator {
|
|
|
162
162
|
case 'GrpcDecl': return this.visitGrpc(node);
|
|
163
163
|
case 'WebrtcDecl': return this.visitWebrtc(node);
|
|
164
164
|
case 'BlockchainDecl': return this.visitBlockchain(node);
|
|
165
|
+
case 'EnumDecl': return this.visitEnum(node);
|
|
166
|
+
case 'Swap': return this.visitSwap(node);
|
|
165
167
|
default:
|
|
166
168
|
this.emit(`# unknown: ${node.type}`);
|
|
167
169
|
}
|
|
@@ -1068,6 +1070,12 @@ export class PythonGenerator {
|
|
|
1068
1070
|
generateCall(node) {
|
|
1069
1071
|
const args = node.args.map(a => this.expr(a)).join(', ');
|
|
1070
1072
|
|
|
1073
|
+
if (node.callee.type === 'Identifier') {
|
|
1074
|
+
const argList = node.args.map(a => this.expr(a));
|
|
1075
|
+
const b = this.generateBuiltin(node.callee.name, argList);
|
|
1076
|
+
if (b !== null) return b;
|
|
1077
|
+
}
|
|
1078
|
+
|
|
1071
1079
|
// Map common JS global functions to Python
|
|
1072
1080
|
if (node.callee.type === 'Identifier') {
|
|
1073
1081
|
const name = node.callee.name;
|
|
@@ -2466,4 +2474,69 @@ export class PythonGenerator {
|
|
|
2466
2474
|
this.emit(`${name.replace(/\W/g, '_')} = ${name.charAt(0).toUpperCase() + name.slice(1).replace(/\W/g, '_')}()`);
|
|
2467
2475
|
this.emitRaw('');
|
|
2468
2476
|
}
|
|
2477
|
+
|
|
2478
|
+
// ===== Enum =====
|
|
2479
|
+
visitEnum(node) {
|
|
2480
|
+
this.addFromImport('enum', 'Enum');
|
|
2481
|
+
this.emit(`class ${node.name}(Enum):`);
|
|
2482
|
+
this.indent++;
|
|
2483
|
+
node.values.forEach((v, i) => {
|
|
2484
|
+
this.emit(`${v} = ${i}`);
|
|
2485
|
+
});
|
|
2486
|
+
this.indent--;
|
|
2487
|
+
this.emitRaw('');
|
|
2488
|
+
}
|
|
2489
|
+
|
|
2490
|
+
// ===== Swap =====
|
|
2491
|
+
visitSwap(node) {
|
|
2492
|
+
const a = this.expr(node.a);
|
|
2493
|
+
const b = this.expr(node.b);
|
|
2494
|
+
this.emit(`${a}, ${b} = ${b}, ${a}`);
|
|
2495
|
+
}
|
|
2496
|
+
|
|
2497
|
+
// ===== Builtins =====
|
|
2498
|
+
generateBuiltin(name, args) {
|
|
2499
|
+
switch (name) {
|
|
2500
|
+
case 'ask': return `input(${args[0] || '""'})`;
|
|
2501
|
+
case 'sleep': { this.addImport('time'); return `time.sleep(${args[0]} / 1000)`; }
|
|
2502
|
+
case 'exit': { this.addImport('sys'); return `sys.exit(${args[0] || '0'})`; }
|
|
2503
|
+
case 'read': return `open(${args[0]}).read()`;
|
|
2504
|
+
case 'write': return `open(${args[0]}, 'w').write(${args[1]})`;
|
|
2505
|
+
case 'fetch_json': { this.addImport('requests'); return `requests.get(${args[0]}).json()`; }
|
|
2506
|
+
case 'random': { this.addImport('random'); return args.length >= 2 ? `random.randint(${args[0]}, ${args[1]})` : `random.random()`; }
|
|
2507
|
+
case 'sort': return `sorted(${args[0]})`;
|
|
2508
|
+
case 'reverse': return `list(reversed(${args[0]}))`;
|
|
2509
|
+
case 'unique': return `list(set(${args[0]}))`;
|
|
2510
|
+
case 'len': return `len(${args[0]})`;
|
|
2511
|
+
case 'upper': return `${args[0]}.upper()`;
|
|
2512
|
+
case 'lower': return `${args[0]}.lower()`;
|
|
2513
|
+
case 'trim': return `${args[0]}.strip()`;
|
|
2514
|
+
case 'split': return `${args[0]}.split(${args[1] || ''})`;
|
|
2515
|
+
case 'join': return `${args[1] || '","'}.join(${args[0]})`;
|
|
2516
|
+
case 'contains': return `(${args[1]} in ${args[0]})`;
|
|
2517
|
+
case 'replace': return `${args[0]}.replace(${args[1]}, ${args[2]})`;
|
|
2518
|
+
case 'keys': return `list(${args[0]}.keys())`;
|
|
2519
|
+
case 'values': return `list(${args[0]}.values())`;
|
|
2520
|
+
case 'entries': return `list(${args[0]}.items())`;
|
|
2521
|
+
case 'range': return args.length >= 2 ? `list(range(${args[0]}, ${args[1]}))` : `list(range(${args[0]}))`;
|
|
2522
|
+
case 'abs': return `abs(${args[0]})`;
|
|
2523
|
+
case 'round': return `round(${args[0]})`;
|
|
2524
|
+
case 'ceil': { this.addImport('math'); return `math.ceil(${args[0]})`; }
|
|
2525
|
+
case 'floor': { this.addImport('math'); return `math.floor(${args[0]})`; }
|
|
2526
|
+
case 'sqrt': { this.addImport('math'); return `math.sqrt(${args[0]})`; }
|
|
2527
|
+
case 'pow': return `${args[0]} ** ${args[1]}`;
|
|
2528
|
+
case 'sum': return `sum(${args[0]})`;
|
|
2529
|
+
case 'flat': return `[x for sub in ${args[0]} for x in sub]`;
|
|
2530
|
+
case 'zip': return `list(zip(${args[0]}, ${args[1]}))`;
|
|
2531
|
+
case 'str': return `str(${args[0]})`;
|
|
2532
|
+
case 'int': return `int(${args[0]})`;
|
|
2533
|
+
case 'float': return `float(${args[0]})`;
|
|
2534
|
+
case 'json_parse': { this.addImport('json'); return `json.loads(${args[0]})`; }
|
|
2535
|
+
case 'json_str': { this.addImport('json'); return `json.dumps(${args[0]})`; }
|
|
2536
|
+
case 'now': { this.addImport('time'); return `int(time.time() * 1000)`; }
|
|
2537
|
+
case 'time': { this.addFromImport('datetime', 'datetime'); return `datetime.now().isoformat()`; }
|
|
2538
|
+
case 'chunk': return `[${args[0]}[i:i+${args[1]}] for i in range(0, len(${args[0]}), ${args[1]})]`;
|
|
2539
|
+
default: return null;
|
|
2540
|
+
}
|
|
2541
|
+
}
|
|
2469
2542
|
}
|
package/src/generator-ruby.js
CHANGED
|
@@ -111,6 +111,8 @@ export class RubyGenerator {
|
|
|
111
111
|
case 'GrpcDecl': return this.visitGrpc(node);
|
|
112
112
|
case 'WebrtcDecl': return this.visitWebrtc(node);
|
|
113
113
|
case 'BlockchainDecl': return this.visitBlockchain(node);
|
|
114
|
+
case 'EnumDecl': return this.visitEnum(node);
|
|
115
|
+
case 'Swap': return this.visitSwap(node);
|
|
114
116
|
default:
|
|
115
117
|
this.emit(`# unknown: ${node.type}`);
|
|
116
118
|
}
|
|
@@ -1330,6 +1332,12 @@ export class RubyGenerator {
|
|
|
1330
1332
|
}
|
|
1331
1333
|
|
|
1332
1334
|
generateCall(node) {
|
|
1335
|
+
if (node.callee.type === 'Identifier') {
|
|
1336
|
+
const argList = node.args.map(a => this.expr(a));
|
|
1337
|
+
const b = this.generateBuiltin(node.callee.name, argList);
|
|
1338
|
+
if (b) return b;
|
|
1339
|
+
}
|
|
1340
|
+
|
|
1333
1341
|
const args = node.args.map(a => this.expr(a)).join(', ');
|
|
1334
1342
|
|
|
1335
1343
|
// Map global function calls
|
|
@@ -1527,4 +1535,65 @@ export class RubyGenerator {
|
|
|
1527
1535
|
this.indent = savedIndent;
|
|
1528
1536
|
return result;
|
|
1529
1537
|
}
|
|
1538
|
+
|
|
1539
|
+
visitEnum(node) {
|
|
1540
|
+
this.emit(`module ${node.name}`);
|
|
1541
|
+
this.indent++;
|
|
1542
|
+
node.values.forEach((v, i) => {
|
|
1543
|
+
this.emit(`${v} = ${i}`);
|
|
1544
|
+
});
|
|
1545
|
+
this.indent--;
|
|
1546
|
+
this.emit(`end`);
|
|
1547
|
+
this.emitRaw('');
|
|
1548
|
+
}
|
|
1549
|
+
|
|
1550
|
+
visitSwap(node) {
|
|
1551
|
+
const a = this.expr(node.a);
|
|
1552
|
+
const b = this.expr(node.b);
|
|
1553
|
+
this.emit(`${a}, ${b} = ${b}, ${a}`);
|
|
1554
|
+
}
|
|
1555
|
+
|
|
1556
|
+
generateBuiltin(name, args) {
|
|
1557
|
+
switch (name) {
|
|
1558
|
+
case 'len': return `${args[0]}.length`;
|
|
1559
|
+
case 'sort': return `${args[0]}.sort`;
|
|
1560
|
+
case 'reverse': return `${args[0]}.reverse`;
|
|
1561
|
+
case 'unique': return `${args[0]}.uniq`;
|
|
1562
|
+
case 'upper': return `${args[0]}.upcase`;
|
|
1563
|
+
case 'lower': return `${args[0]}.downcase`;
|
|
1564
|
+
case 'trim': return `${args[0]}.strip`;
|
|
1565
|
+
case 'split': return `${args[0]}.split(${args[1] || '","'})`;
|
|
1566
|
+
case 'join': return `${args[0]}.join(${args[1] || '","'})`;
|
|
1567
|
+
case 'contains': return `${args[0]}.include?(${args[1]})`;
|
|
1568
|
+
case 'replace': return `${args[0]}.gsub(${args[1]}, ${args[2]})`;
|
|
1569
|
+
case 'keys': return `${args[0]}.keys`;
|
|
1570
|
+
case 'values': return `${args[0]}.values`;
|
|
1571
|
+
case 'entries': return `${args[0]}.to_a`;
|
|
1572
|
+
case 'range': return args.length >= 2 ? `(${args[0]}...${args[1]}).to_a` : `(0...${args[0]}).to_a`;
|
|
1573
|
+
case 'abs': return `${args[0]}.abs`;
|
|
1574
|
+
case 'round': return `${args[0]}.round`;
|
|
1575
|
+
case 'ceil': return `${args[0]}.ceil`;
|
|
1576
|
+
case 'floor': return `${args[0]}.floor`;
|
|
1577
|
+
case 'sqrt': return `Math.sqrt(${args[0]})`;
|
|
1578
|
+
case 'pow': return `${args[0]} ** ${args[1]}`;
|
|
1579
|
+
case 'sum': return `${args[0]}.sum`;
|
|
1580
|
+
case 'flat': return `${args[0]}.flatten`;
|
|
1581
|
+
case 'zip': return `${args[0]}.zip(${args[1]})`;
|
|
1582
|
+
case 'chunk': return `${args[0]}.each_slice(${args[1]}).to_a`;
|
|
1583
|
+
case 'str': return `${args[0]}.to_s`;
|
|
1584
|
+
case 'int': return `${args[0]}.to_i`;
|
|
1585
|
+
case 'float': return `${args[0]}.to_f`;
|
|
1586
|
+
case 'json_parse': return `JSON.parse(${args[0]})`;
|
|
1587
|
+
case 'json_str': return `JSON.generate(${args[0]})`;
|
|
1588
|
+
case 'now': return `(Time.now.to_f * 1000).to_i`;
|
|
1589
|
+
case 'time': return `Time.now.iso8601`;
|
|
1590
|
+
case 'exit': return `exit(${args[0] || '0'})`;
|
|
1591
|
+
case 'sleep': return `sleep(${args[0]} / 1000.0)`;
|
|
1592
|
+
case 'random': return args.length >= 2 ? `rand(${args[0]}..${args[1]})` : `rand`;
|
|
1593
|
+
case 'read': return `File.read(${args[0]})`;
|
|
1594
|
+
case 'write': return `File.write(${args[0]}, ${args[1]})`;
|
|
1595
|
+
case 'ask': return `(print(${args[0] || '""'}); gets.chomp)`;
|
|
1596
|
+
default: return null;
|
|
1597
|
+
}
|
|
1598
|
+
}
|
|
1530
1599
|
}
|