ranger-compiler 3.0.3 → 3.0.5
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/CHANGELOG.md +27 -0
- package/README.md +1 -1
- package/dist/Lang.rgr +158 -9
- package/dist/lib/JSON.rgr +31 -4
- package/dist/lib/RangerProcess.rgr +273 -0
- package/dist/lib/stdlib.rgr +33 -3
- package/dist/package.json +1 -1
- package/dist/rgrc.js +1139 -47
- package/package.json +2 -2
- package/dist/lib/lib/ACEEditor.rgr +0 -5
- package/dist/lib/lib/Ajax.rgr +0 -196
- package/dist/lib/lib/CmdParams.rgr +0 -72
- package/dist/lib/lib/Crypto.rgr +0 -90
- package/dist/lib/lib/DOMLib.rgr +0 -307
- package/dist/lib/lib/Engine3D.rgr +0 -870
- package/dist/lib/lib/ImmutableVector.rgr +0 -364
- package/dist/lib/lib/IndexedDB.rgr +0 -32
- package/dist/lib/lib/JSON.rgr +0 -702
- package/dist/lib/lib/JinxProcess.rgr +0 -838
- package/dist/lib/lib/SQL.rgr +0 -44
- package/dist/lib/lib/ServiceLib.rgr +0 -9
- package/dist/lib/lib/Storage.rgr +0 -89
- package/dist/lib/lib/Time.rgr +0 -75
- package/dist/lib/lib/Timers.rgr +0 -176
- package/dist/lib/lib/TypedArrays.rgr +0 -14
- package/dist/lib/lib/ViewLib.rgr +0 -851
- package/dist/lib/lib/WebLib.rgr +0 -47
- package/dist/lib/lib/WebServerLib.rgr +0 -137
- package/dist/lib/lib/ranger-dir.rgr +0 -175
- package/dist/lib/lib/stdlib.rgr +0 -665
- package/dist/lib/lib/stdops.rgr +0 -168
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,33 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [3.0.5] - 2026-05-29
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **`@process` messaging** — `proc_send` operator; `receiveMessage` on `RangerProcessBase`; `find_process` / `ProcessNameRegistry.findProcess`
|
|
15
|
+
- **TypeScript named paths** — `-typescript` emits `ProcessPath`, `findProcess` on registry, singleton `new` returns shared instance
|
|
16
|
+
- **`RangerProcess.rgr` in npm lib** — included under `dist/lib/` when running `npm run build:dist`
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
|
|
20
|
+
- **`build:dist:copy`** — `rm -rf dist/lib` before copy so new lib files (e.g. `RangerProcess.rgr`) land in `dist/lib/` instead of nested `dist/lib/lib/`
|
|
21
|
+
|
|
22
|
+
### Changed
|
|
23
|
+
|
|
24
|
+
- Version bumped from `3.0.4` to `3.0.5`
|
|
25
|
+
|
|
26
|
+
## [3.0.4] - 2026-05-12
|
|
27
|
+
|
|
28
|
+
### Fixed
|
|
29
|
+
|
|
30
|
+
- **Installed npm package library lookup** — The published compiler now also searches `./lib` relative to the compiler binary, so locally installed `ranger-compiler` packages can resolve `stdlib.rgr` and related bundled libraries correctly
|
|
31
|
+
- **Virtual compiler bundled file loading** — Bundled library files are now loaded from `./lib/` inside the packaged distribution instead of assuming a development-only `../lib/` layout
|
|
32
|
+
|
|
33
|
+
### Changed
|
|
34
|
+
|
|
35
|
+
- Version bumped from `3.0.3` to `3.0.4`
|
|
36
|
+
|
|
10
37
|
## [3.0.3] - 2026-05-12
|
|
11
38
|
|
|
12
39
|
### Fixed
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Ranger cross language compiler
|
|
2
2
|
|
|
3
|
-
**Version 3.0.
|
|
3
|
+
**Version 3.0.5** | Status: `experimental`
|
|
4
4
|
|
|
5
5
|
Ranger is a self-hosting cross-language compiler for writing portable algorithms, parsers, generators, and small tools once and compiling them to multiple target languages.
|
|
6
6
|
|
package/dist/Lang.rgr
CHANGED
|
@@ -493,6 +493,7 @@ func r_io_get_env( name string) *GoNullable {
|
|
|
493
493
|
swift6 ("CommandLine.arguments[" (e 1) " + 1]")
|
|
494
494
|
es6 ( "process.argv[ 2 + " (e 1) "]")
|
|
495
495
|
rust ( "std::env::args().nth((" (e 1) " + 1) as usize).unwrap_or_default()")
|
|
496
|
+
kotlin ( "args[" (e 1) "]")
|
|
496
497
|
ranger ("( shell_arg " (e 1) " )")
|
|
497
498
|
}
|
|
498
499
|
}
|
|
@@ -508,6 +509,7 @@ func r_io_get_env( name string) *GoNullable {
|
|
|
508
509
|
go ( "int64( len( os.Args) - 1 )" (imp "os"))
|
|
509
510
|
es6 ( "(process.argv.length - 2)" )
|
|
510
511
|
rust ( "(std::env::args().len() as i64 - 1)")
|
|
512
|
+
kotlin ( "(args.size - 1)")
|
|
511
513
|
ranger ("( shell_arg_cnt )")
|
|
512
514
|
}
|
|
513
515
|
}
|
|
@@ -930,6 +932,7 @@ fn r_read_file(path: &str, filename: &str) -> Option<String> {
|
|
|
930
932
|
}
|
|
931
933
|
"))
|
|
932
934
|
es6 ( "(require('fs').readFileSync( " (e 1) " + '/' + " (e 2) " , 'utf8'))" )
|
|
935
|
+
kotlin ( "try { java.io.File(if (" (e 1) ".isEmpty()) " (e 2) " else " (e 1) " + \"/\" + " (e 2) ").readText() } catch (_: Exception) { null }" (imp "java.io.File") )
|
|
933
936
|
}
|
|
934
937
|
}
|
|
935
938
|
|
|
@@ -2716,6 +2719,7 @@ std::vector<uint8_t> r_buffer_read_file(const std::string& path, const std::stri
|
|
|
2716
2719
|
ranger ( "(to_int " (e 1) ")")
|
|
2717
2720
|
csharp ( "(int)" (e 1 ) "" )
|
|
2718
2721
|
swift3 ( "Int(" (e 1 ) ")" )
|
|
2722
|
+
swift6 ( "Int(" (e 1 ) ")" )
|
|
2719
2723
|
kotlin ( (e 1 ) ".toInt()" )
|
|
2720
2724
|
scala ( (e 1 ) ".toInt" )
|
|
2721
2725
|
rust ( (e 1 ) " as i64 " )
|
|
@@ -3165,9 +3169,50 @@ func r_str_2_i64(s string) *GoNullable {
|
|
|
3165
3169
|
)
|
|
3166
3170
|
php ( "is_numeric(" (e 1) ") ? intval(" (e 1) ") : NULL ")
|
|
3167
3171
|
scala ( "Try(" (e 1) ".toInt).toOption" (imp "scala.util.Try"))
|
|
3168
|
-
kotlin (
|
|
3169
|
-
|
|
3170
|
-
|
|
3172
|
+
kotlin ( "rangerStr2IntPrefix(" (e 1) ")"
|
|
3173
|
+
(create_polyfill "
|
|
3174
|
+
fun rangerStr2IntPrefix(s: String): Int? {
|
|
3175
|
+
val m = Regex(\"^-?\\\\d+\").find(s) ?: return null
|
|
3176
|
+
return m.value.toIntOrNull()
|
|
3177
|
+
}
|
|
3178
|
+
")
|
|
3179
|
+
)
|
|
3180
|
+
swift3 ("rangerStr2IntPrefix(" (e 1) ")"
|
|
3181
|
+
(create_polyfill "
|
|
3182
|
+
func rangerStr2IntPrefix(_ s: String) -> Int? {
|
|
3183
|
+
var i = s.startIndex
|
|
3184
|
+
if i < s.endIndex && s[i] == \"-\" {
|
|
3185
|
+
i = s.index(after: i)
|
|
3186
|
+
}
|
|
3187
|
+
var end = i
|
|
3188
|
+
while end < s.endIndex && s[end].isNumber {
|
|
3189
|
+
end = s.index(after: end)
|
|
3190
|
+
}
|
|
3191
|
+
if end == i {
|
|
3192
|
+
return nil
|
|
3193
|
+
}
|
|
3194
|
+
return Int(s[i..<end])
|
|
3195
|
+
}
|
|
3196
|
+
")
|
|
3197
|
+
)
|
|
3198
|
+
swift6 ("rangerStr2IntPrefix(" (e 1) ")"
|
|
3199
|
+
(create_polyfill "
|
|
3200
|
+
func rangerStr2IntPrefix(_ s: String) -> Int? {
|
|
3201
|
+
var i = s.startIndex
|
|
3202
|
+
if i < s.endIndex && s[i] == \"-\" {
|
|
3203
|
+
i = s.index(after: i)
|
|
3204
|
+
}
|
|
3205
|
+
var end = i
|
|
3206
|
+
while end < s.endIndex && s[end].isNumber {
|
|
3207
|
+
end = s.index(after: end)
|
|
3208
|
+
}
|
|
3209
|
+
if end == i {
|
|
3210
|
+
return nil
|
|
3211
|
+
}
|
|
3212
|
+
return Int(s[i..<end])
|
|
3213
|
+
}
|
|
3214
|
+
")
|
|
3215
|
+
)
|
|
3171
3216
|
csharp( "Int32.Parse(" (e 1) ")" )
|
|
3172
3217
|
rust ( (e 1) ".parse::<i64>().ok()" )
|
|
3173
3218
|
* ( "isNaN( parseInt(" (e 1) ") ) ? undefined : parseInt(" (e 1) ")")
|
|
@@ -3247,7 +3292,7 @@ Double _getDoubleOrNull ( String str ) {
|
|
|
3247
3292
|
scala ( "Try(" (e 1) ".toDouble).toOption" (imp "scala.util.Try"))
|
|
3248
3293
|
kotlin ( (e 1) ".toDoubleOrNull()")
|
|
3249
3294
|
swift3 ("Double(" (e 1) ")")
|
|
3250
|
-
|
|
3295
|
+
swift6 ("Double(" (e 1) ")")
|
|
3251
3296
|
* ( "isNaN( parseFloat(" (e 1) ") ) ? undefined : parseFloat(" (e 1) ")")
|
|
3252
3297
|
}
|
|
3253
3298
|
}
|
|
@@ -4090,9 +4135,12 @@ public <T> T _arr_extract( ArrayList<T> list, Integer i ) {
|
|
|
4090
4135
|
"const readline = require('readline');" nl
|
|
4091
4136
|
"readline.emitKeypressEvents(process.stdin);" nl
|
|
4092
4137
|
"if (process.stdin.isTTY) { process.stdin.setRawMode(true); }" nl
|
|
4093
|
-
"process.stdin.
|
|
4094
|
-
"
|
|
4095
|
-
"if (
|
|
4138
|
+
"process.stdin.resume();" nl
|
|
4139
|
+
"process.stdin.on('keypress', (str, key) => {" nl I
|
|
4140
|
+
"if (key && key.ctrl && key.name === 'c') { process.stdout.write('\\x1b[?25h'); process.exit(); }" nl
|
|
4141
|
+
"var __rgr_k = \"\";" nl
|
|
4142
|
+
"if (key && key.name) { __rgr_k = key.name; } else if (str && str.length > 0) { __rgr_k = str; } else if (key && key.sequence) { __rgr_k = key.sequence; }" nl
|
|
4143
|
+
"if (__rgr_k !== \"\") { " (e 1) " = __rgr_k; global.r_key_queue.push(__rgr_k); }" nl
|
|
4096
4144
|
(block 2)
|
|
4097
4145
|
i nl "});" nl
|
|
4098
4146
|
)
|
|
@@ -4519,7 +4567,11 @@ var r_key_queue: [String] = []
|
|
|
4519
4567
|
var r_key_queue_lock = NSLock()
|
|
4520
4568
|
|
|
4521
4569
|
func r_setup_raw_mode() {
|
|
4522
|
-
let
|
|
4570
|
+
let p = Process()
|
|
4571
|
+
p.executableURL = URL(fileURLWithPath: \"/bin/stty\")
|
|
4572
|
+
p.arguments = [\"-F\", \"/dev/tty\", \"cbreak\", \"min\", \"1\", \"-echo\"]
|
|
4573
|
+
try? p.run()
|
|
4574
|
+
p.waitUntilExit()
|
|
4523
4575
|
}
|
|
4524
4576
|
|
|
4525
4577
|
func r_read_key() -> String? {
|
|
@@ -4609,7 +4661,11 @@ func r_read_key() -> String? {
|
|
|
4609
4661
|
}
|
|
4610
4662
|
#else
|
|
4611
4663
|
func r_setup_raw_mode() {
|
|
4612
|
-
let
|
|
4664
|
+
let p = Process()
|
|
4665
|
+
p.executableURL = URL(fileURLWithPath: \"/bin/stty\")
|
|
4666
|
+
p.arguments = [\"-F\", \"/dev/tty\", \"cbreak\", \"min\", \"1\", \"-echo\"]
|
|
4667
|
+
try? p.run()
|
|
4668
|
+
p.waitUntilExit()
|
|
4613
4669
|
}
|
|
4614
4670
|
|
|
4615
4671
|
func r_read_key() -> String? {
|
|
@@ -4863,8 +4919,10 @@ std::string r_cpp_str_to_uppercase(std::string original)
|
|
|
4863
4919
|
go ("float64( " (e 1) " )")
|
|
4864
4920
|
es6 ( (e 1) )
|
|
4865
4921
|
swift3 ("Double(" (e 1) ")")
|
|
4922
|
+
swift6 ("Double(" (e 1) ")")
|
|
4866
4923
|
scala ( (e 1) '.toDouble')
|
|
4867
4924
|
java7 ("Double.valueOf(" (e 1) ")")
|
|
4925
|
+
kotlin ( (e 1) ".toDouble()" )
|
|
4868
4926
|
cpp ("(double)(" (e 1) ")")
|
|
4869
4927
|
php ( (e 1) )
|
|
4870
4928
|
rust ("(" (e 1) " as f64)")
|
|
@@ -5280,6 +5338,97 @@ std::string r_cpp_str_to_uppercase(std::string original)
|
|
|
5280
5338
|
}
|
|
5281
5339
|
}
|
|
5282
5340
|
|
|
5341
|
+
; Process lifecycle operators (distinct from HttpServer start/stop)
|
|
5342
|
+
find_process@(moves@( 1 )) cmdFindProcess:RangerProcessBase@(optional) (path:string) {
|
|
5343
|
+
templates {
|
|
5344
|
+
es6 ( "ProcessNameRegistry.__singleton().findByPath(" (e 1) ")" )
|
|
5345
|
+
kotlin ( "ProcessNameRegistry.__singleton().findByPath(" (e 1) ")" )
|
|
5346
|
+
swift6 ( "ProcessNameRegistry.__singleton().findByPath(" (e 1) ")" )
|
|
5347
|
+
swift3 ( "ProcessNameRegistry.__singleton().findByPath(" (e 1) ")" )
|
|
5348
|
+
* ( "/* find_process not implemented */" )
|
|
5349
|
+
}
|
|
5350
|
+
}
|
|
5351
|
+
|
|
5352
|
+
proc_send@(moves@( 2 )) cmdProcSendPath:void (path:string msg:Any) {
|
|
5353
|
+
templates {
|
|
5354
|
+
es6 ( "(() => { const __rgrP = ProcessNameRegistry.__singleton().findByPath(" (e 1) "); if (!__rgrP || __rgrP.__rangerId === 0) return; __rgrP.receiveMessage(" (e 2) "); })()" )
|
|
5355
|
+
kotlin ( "run { val __rgrP = ProcessNameRegistry.__singleton().findByPath(" (e 1) "); if (__rgrP == null || __rgrP.__rangerId == 0) return@run; __rgrP.receiveMessage(" (e 2) ") }" )
|
|
5356
|
+
swift6 ( "{ let __rgrP = ProcessNameRegistry.__singleton().findByPath(" (e 1) "); guard let p = __rgrP, p.__rangerId != 0 else { return }; p.receiveMessage(" (e 2) ") }" )
|
|
5357
|
+
swift3 ( "{ let __rgrP = ProcessNameRegistry.__singleton().findByPath(" (e 1) "); guard let p = __rgrP, p.__rangerId != 0 else { return }; p.receiveMessage(" (e 2) ") }" )
|
|
5358
|
+
* ( "/* proc_send path not implemented */" )
|
|
5359
|
+
}
|
|
5360
|
+
}
|
|
5361
|
+
|
|
5362
|
+
proc_send@(moves@( 2 )) cmdProcSendProc:void (proc:RangerProcessBase msg:Any) {
|
|
5363
|
+
templates {
|
|
5364
|
+
es6 ( "(() => { const __rgrP = " (e 1) "; if (!__rgrP || __rgrP.__rangerId === 0) return; __rgrP.receiveMessage(" (e 2) "); })()" )
|
|
5365
|
+
kotlin ( "run { val __rgrP = " (e 1) "; if (__rgrP.__rangerId == 0) return@run; __rgrP.receiveMessage(" (e 2) ") }" )
|
|
5366
|
+
swift6 ( "{ let __rgrP = " (e 1) "; guard __rgrP.__rangerId != 0 else { return }; __rgrP.receiveMessage(" (e 2) ") }" )
|
|
5367
|
+
swift3 ( "{ let __rgrP = " (e 1) "; guard __rgrP.__rangerId != 0 else { return }; __rgrP.receiveMessage(" (e 2) ") }" )
|
|
5368
|
+
* ( "/* proc_send proc not implemented */" )
|
|
5369
|
+
}
|
|
5370
|
+
}
|
|
5371
|
+
|
|
5372
|
+
proc_start@(moves@( 1 )) cmdProcStart:void (proc:RangerProcessBase) {
|
|
5373
|
+
templates {
|
|
5374
|
+
es6 ( "ProcessRuntime.startInstance(" (e 1) ")" )
|
|
5375
|
+
kotlin ( "ProcessRuntime.startInstance(" (e 1) ")" )
|
|
5376
|
+
swift6 ( "ProcessRuntime.startInstance(proc: " (e 1) ")" )
|
|
5377
|
+
swift3 ( "ProcessRuntime.startInstance(proc: " (e 1) ")" )
|
|
5378
|
+
* ( "/* proc_start not implemented */" )
|
|
5379
|
+
}
|
|
5380
|
+
}
|
|
5381
|
+
|
|
5382
|
+
proc_stop@(moves@( 1 )) cmdProcStopInst:void (proc:RangerProcessBase) {
|
|
5383
|
+
templates {
|
|
5384
|
+
es6 ( "ProcessRuntime.stopInstance(" (e 1) ")" )
|
|
5385
|
+
kotlin ( "ProcessRuntime.stopInstance(" (e 1) ")" )
|
|
5386
|
+
swift6 ( "ProcessRuntime.stopInstance(proc: " (e 1) ")" )
|
|
5387
|
+
swift3 ( "ProcessRuntime.stopInstance(proc: " (e 1) ")" )
|
|
5388
|
+
* ( "/* proc_stop instance not implemented */" )
|
|
5389
|
+
}
|
|
5390
|
+
}
|
|
5391
|
+
|
|
5392
|
+
proc_stop@(moves@( 1 )) cmdProcStopProcessId:void (processId:int) {
|
|
5393
|
+
templates {
|
|
5394
|
+
es6 ( "ProcessRuntime.stopByProcessId(" (e 1) ")" )
|
|
5395
|
+
kotlin ( "ProcessRuntime.stopByProcessId(" (e 1) ")" )
|
|
5396
|
+
swift6 ( "ProcessRuntime.stopByProcessId(" (e 1) ")" )
|
|
5397
|
+
swift3 ( "ProcessRuntime.stopByProcessId(" (e 1) ")" )
|
|
5398
|
+
* ( "/* proc_stop processId not implemented */" )
|
|
5399
|
+
}
|
|
5400
|
+
}
|
|
5401
|
+
|
|
5402
|
+
proc_stop@(moves@( 1 )) cmdProcStopClass:void (className:string) {
|
|
5403
|
+
templates {
|
|
5404
|
+
es6 ( "ProcessRuntime.stopByClassName(" (e 1) ")" )
|
|
5405
|
+
kotlin ( "ProcessRuntime.stopByClassName(" (e 1) ")" )
|
|
5406
|
+
swift6 ( "ProcessRuntime.stopByClassName(" (e 1) ")" )
|
|
5407
|
+
swift3 ( "ProcessRuntime.stopByClassName(" (e 1) ")" )
|
|
5408
|
+
* ( "/* proc_stop class not implemented */" )
|
|
5409
|
+
}
|
|
5410
|
+
}
|
|
5411
|
+
|
|
5412
|
+
proc_hibernate@(moves@( 1 )) cmdProcHibernate:string (proc:RangerProcessBase) {
|
|
5413
|
+
templates {
|
|
5414
|
+
es6 ( "ProcessRuntime.hibernateInstance(" (e 1) ")" )
|
|
5415
|
+
kotlin ( "ProcessRuntime.hibernateInstance(" (e 1) ")" )
|
|
5416
|
+
swift6 ( "ProcessRuntime.hibernateInstance(proc: " (e 1) ")" )
|
|
5417
|
+
swift3 ( "ProcessRuntime.hibernateInstance(proc: " (e 1) ")" )
|
|
5418
|
+
* ( "\"\"" )
|
|
5419
|
+
}
|
|
5420
|
+
}
|
|
5421
|
+
|
|
5422
|
+
proc_wakeup@(moves@( 2 )) cmdProcWakeup:void (proc:RangerProcessBase state:string) {
|
|
5423
|
+
templates {
|
|
5424
|
+
es6 ( "ProcessRuntime.wakeupInstance(" (e 1) ", " (e 2) ")" )
|
|
5425
|
+
kotlin ( "ProcessRuntime.wakeupInstance(" (e 1) ", " (e 2) ")" )
|
|
5426
|
+
swift6 ( "ProcessRuntime.wakeupInstance(proc: " (e 1) ", state: " (e 2) ")" )
|
|
5427
|
+
swift3 ( "ProcessRuntime.wakeupInstance(proc: " (e 1) ", state: " (e 2) ")" )
|
|
5428
|
+
* ( "/* proc_wakeup not implemented */" )
|
|
5429
|
+
}
|
|
5430
|
+
}
|
|
5431
|
+
|
|
5283
5432
|
}
|
|
5284
5433
|
|
|
5285
5434
|
|
package/dist/lib/JSON.rgr
CHANGED
|
@@ -90,10 +90,37 @@ operators {
|
|
|
90
90
|
java7 ( (e 1) ".isNull( " (e 2) " ) ? null : " (e 1) ".optString(" (e 2) ") " )
|
|
91
91
|
kotlin ( "(if (" (e 1) ".isNull(" (e 2) ")) null else " (e 1) ".optString(" (e 2) "))"
|
|
92
92
|
(create_polyfill "
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
93
|
+
open class JSONObject {
|
|
94
|
+
protected open val values: MutableMap<String, Any?> = mutableMapOf()
|
|
95
|
+
open fun isNull(key: String): Boolean = !values.containsKey(key) || values[key] == null
|
|
96
|
+
open fun optString(key: String): String? = values[key]?.toString()
|
|
97
|
+
open fun optInt(key: String): Int? = when (val v = values[key]) {
|
|
98
|
+
is Int -> v
|
|
99
|
+
is Double -> v.toInt()
|
|
100
|
+
is String -> v.toIntOrNull()
|
|
101
|
+
else -> null
|
|
102
|
+
}
|
|
103
|
+
open fun optDouble(key: String): Double? = when (val v = values[key]) {
|
|
104
|
+
is Double -> v
|
|
105
|
+
is Int -> v.toDouble()
|
|
106
|
+
is String -> v.toDoubleOrNull()
|
|
107
|
+
else -> null
|
|
108
|
+
}
|
|
109
|
+
open fun optBoolean(key: String): Boolean? = values[key] as? Boolean
|
|
110
|
+
open fun getJSONObject(key: String): JSONObject? = values[key] as? JSONObject
|
|
111
|
+
open fun getJSONArray(key: String): JSONArray? = values[key] as? JSONArray
|
|
112
|
+
open fun put(key: String, value: Any?): JSONObject { values[key] = value; return this }
|
|
113
|
+
override fun toString(): String = values.toString()
|
|
114
|
+
constructor(source: String) : this() {}
|
|
115
|
+
constructor()
|
|
116
|
+
}
|
|
117
|
+
open class JSONArray : ArrayList<Any?>() {
|
|
118
|
+
open fun length(): Int = size
|
|
119
|
+
override fun get(index: Int): Any? = if (index in indices) super.get(index) else null
|
|
120
|
+
override fun toString(): String = joinToString(prefix = \"[\", postfix = \"]\")
|
|
121
|
+
}
|
|
122
|
+
typealias JSONDataObject = JSONObject
|
|
123
|
+
typealias JSONArrayObject = JSONArray
|
|
97
124
|
")
|
|
98
125
|
)
|
|
99
126
|
go ( "r_get_opt_json_string(" (e 1) ", " (e 2) ")"
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
|
|
2
|
+
Import "stdops.rgr"
|
|
3
|
+
|
|
4
|
+
class RangerProcessBase {
|
|
5
|
+
def __rangerId:int 0
|
|
6
|
+
def __rangerParentId:int 0
|
|
7
|
+
def __rangerTypeId:int 0
|
|
8
|
+
def __rangerClassName:string ""
|
|
9
|
+
def __rangerPath:string ""
|
|
10
|
+
def __rangerStateGeneration:int 0
|
|
11
|
+
def __rangerParent:RangerProcessBase@(optional)
|
|
12
|
+
def __rangerChildren:[RangerProcessBase]
|
|
13
|
+
|
|
14
|
+
fn markStateDirty:void () {
|
|
15
|
+
__rangerStateGeneration = __rangerStateGeneration + 1
|
|
16
|
+
if ((strlen __rangerPath) > 0) {
|
|
17
|
+
ProcessUiHost.__singleton().notifyPath(__rangerPath)
|
|
18
|
+
}
|
|
19
|
+
if (__rangerId != 0) {
|
|
20
|
+
ProcessUiHost.__singleton().notifyId(__rangerId)
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
fn __rangerOnDescendantUiChanged:void (child:RangerProcessBase hint:string) {
|
|
25
|
+
this.markStateDirty()
|
|
26
|
+
def parent@(optional):RangerProcessBase (__rangerParent)
|
|
27
|
+
if ((null? parent) == false) {
|
|
28
|
+
def p:RangerProcessBase (unwrap parent)
|
|
29
|
+
if (p.__rangerId != 0) {
|
|
30
|
+
p.__rangerOnDescendantUiChanged(child hint)
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
fn __rangerTrackChild:void (child:RangerProcessBase) {
|
|
36
|
+
push __rangerChildren child
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
fn __rangerClearChildren:void () {
|
|
40
|
+
def empty:[RangerProcessBase]
|
|
41
|
+
__rangerChildren = empty
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
fn __rangerInvokeStart:void () {
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
fn __rangerInvokeStop:void () {
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
fn __rangerInvokeHibernate:string () {
|
|
51
|
+
return ""
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
fn __rangerInvokeWakeup:void (state:string) {
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
fn __rangerStopSubtree:void () {
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
; Optional inbound messaging hook; override on @process classes. proc_send calls this.
|
|
61
|
+
fn receiveMessage:void (msg:Any) {
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
; Single app-wide ID space for all @process instances (roots and children).
|
|
66
|
+
class ProcessIdRegistry @singleton(true) {
|
|
67
|
+
def next:int 1
|
|
68
|
+
|
|
69
|
+
fn allocate:int () {
|
|
70
|
+
def id (this.next)
|
|
71
|
+
this.next = id + 1
|
|
72
|
+
return id
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
class ProcessNameRegistry @singleton(true) {
|
|
77
|
+
def byPath:[string:RangerProcessBase]
|
|
78
|
+
|
|
79
|
+
fn register:void (path:string proc:RangerProcessBase) {
|
|
80
|
+
if ((strlen path) == 0) {
|
|
81
|
+
return
|
|
82
|
+
}
|
|
83
|
+
if (proc.__rangerId == 0) {
|
|
84
|
+
return
|
|
85
|
+
}
|
|
86
|
+
def existing@(optional):RangerProcessBase (get byPath path)
|
|
87
|
+
if ((null? existing) == false) {
|
|
88
|
+
def old:RangerProcessBase (unwrap existing)
|
|
89
|
+
if (old.__rangerId != 0 && old.__rangerId != proc.__rangerId) {
|
|
90
|
+
print ("ERROR: duplicate live @name process path: " + path)
|
|
91
|
+
return
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
set byPath path proc
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
fn unregister:void (path:string) {
|
|
98
|
+
; Map entry may remain until overwritten; hasLive/findByPath check __rangerId.
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
fn findByPath@(optional):RangerProcessBase (path:string) {
|
|
102
|
+
return (get byPath path)
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
fn hasLive:boolean (path:string) {
|
|
106
|
+
def found@(optional):RangerProcessBase (get byPath path)
|
|
107
|
+
if (null? found) {
|
|
108
|
+
return false
|
|
109
|
+
}
|
|
110
|
+
def inst:RangerProcessBase (unwrap found)
|
|
111
|
+
if (inst.__rangerId == 0) {
|
|
112
|
+
return false
|
|
113
|
+
}
|
|
114
|
+
return true
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
fn unbindIfConfigured:void (proc:RangerProcessBase) {
|
|
118
|
+
if ((strlen proc.__rangerPath) > 0) {
|
|
119
|
+
this.unregister(proc.__rangerPath)
|
|
120
|
+
proc.__rangerPath = ""
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
; Host-side UI subscriptions (React useProcess wires listeners in TS).
|
|
126
|
+
class ProcessUiHost @singleton(true) {
|
|
127
|
+
fn notifyPath:void (path:string) {
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
fn notifyId:void (processId:int) {
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
class ProcessRuntime @singleton(true) {
|
|
135
|
+
|
|
136
|
+
sfn stopInstance:void (proc:RangerProcessBase) {
|
|
137
|
+
ProcessNameRegistry.__singleton().unbindIfConfigured(proc)
|
|
138
|
+
proc.__rangerStopSubtree()
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
sfn startInstance:void (proc:RangerProcessBase) {
|
|
142
|
+
ProcessNameRegistry.__singleton().bindIfConfigured(proc)
|
|
143
|
+
proc.__rangerInvokeStart()
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
sfn hibernateInstance:string (proc:RangerProcessBase) {
|
|
147
|
+
def res:string (proc.__rangerInvokeHibernate())
|
|
148
|
+
return res
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
sfn wakeupInstance:void (proc:RangerProcessBase state:string) {
|
|
152
|
+
proc.__rangerInvokeWakeup(state)
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
class RangerFieldDescriptor {
|
|
157
|
+
def name:string ""
|
|
158
|
+
def typeName:string ""
|
|
159
|
+
def isOptional:boolean false
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
class RangerClassDescriptor {
|
|
163
|
+
def className:string ""
|
|
164
|
+
def fields:[RangerFieldDescriptor]
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
; CLI tree renderer for @process hierarchies (__rangerChildren). Root list:
|
|
168
|
+
; ProcessRuntime.collectAllLiveRoots() (generated when the app has @process classes).
|
|
169
|
+
class ProcessTreeView {
|
|
170
|
+
def showParentId:boolean true
|
|
171
|
+
|
|
172
|
+
fn isLive:boolean (proc:RangerProcessBase) {
|
|
173
|
+
if (proc.__rangerId == 0) {
|
|
174
|
+
return false
|
|
175
|
+
}
|
|
176
|
+
return true
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
fn nodeLabel:string (proc:RangerProcessBase) {
|
|
180
|
+
def label:string ""
|
|
181
|
+
label = proc.__rangerClassName
|
|
182
|
+
label = label + " #"
|
|
183
|
+
label = label + (to_string proc.__rangerId)
|
|
184
|
+
if (showParentId) {
|
|
185
|
+
label = label + " parent="
|
|
186
|
+
label = label + (to_string proc.__rangerParentId)
|
|
187
|
+
}
|
|
188
|
+
return label
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
fn countLiveChildren:int (proc:RangerProcessBase) {
|
|
192
|
+
def n:int 0
|
|
193
|
+
for proc.__rangerChildren ch:RangerProcessBase i {
|
|
194
|
+
if (this.isLive(ch)) {
|
|
195
|
+
n = n + 1
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
return n
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
fn renderSubtree:void (proc:RangerProcessBase indent:string) {
|
|
202
|
+
def liveIdx:int 0
|
|
203
|
+
def total:int (this.countLiveChildren(proc))
|
|
204
|
+
for proc.__rangerChildren ch:RangerProcessBase i {
|
|
205
|
+
if ((this.isLive(ch)) == false) {
|
|
206
|
+
continue
|
|
207
|
+
}
|
|
208
|
+
def branch:string "|-> "
|
|
209
|
+
def childIndent:string " "
|
|
210
|
+
if (liveIdx == (total - 1)) {
|
|
211
|
+
branch = "L-> "
|
|
212
|
+
}
|
|
213
|
+
def line:string ""
|
|
214
|
+
line = indent + branch
|
|
215
|
+
def nodeText:string (this.nodeLabel(ch))
|
|
216
|
+
line = line + nodeText
|
|
217
|
+
print line
|
|
218
|
+
def nextIndent:string ""
|
|
219
|
+
nextIndent = indent + childIndent
|
|
220
|
+
this.renderSubtree(ch nextIndent)
|
|
221
|
+
liveIdx = liveIdx + 1
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
fn countLiveRoots:int (roots:[RangerProcessBase]) {
|
|
226
|
+
def c:int 0
|
|
227
|
+
for roots r:RangerProcessBase i {
|
|
228
|
+
if (this.isLive(r)) {
|
|
229
|
+
c = c + 1
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
return c
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
fn renderRoots:void (roots:[RangerProcessBase] title:string) {
|
|
236
|
+
print ""
|
|
237
|
+
if (title != "") {
|
|
238
|
+
print title
|
|
239
|
+
} {
|
|
240
|
+
print "Process tree"
|
|
241
|
+
}
|
|
242
|
+
def n:int (size roots)
|
|
243
|
+
if (n == 0) {
|
|
244
|
+
print " (no live root processes)"
|
|
245
|
+
return
|
|
246
|
+
}
|
|
247
|
+
def liveTotal:int (this.countLiveRoots(roots))
|
|
248
|
+
if (liveTotal == 0) {
|
|
249
|
+
print " (no live root processes)"
|
|
250
|
+
return
|
|
251
|
+
}
|
|
252
|
+
def shown:int 0
|
|
253
|
+
def i:int 0
|
|
254
|
+
while (i < n) {
|
|
255
|
+
def root:RangerProcessBase (at roots i)
|
|
256
|
+
if (this.isLive(root)) {
|
|
257
|
+
def branch:string "|-> "
|
|
258
|
+
def childIndent:string " "
|
|
259
|
+
if (shown == (liveTotal - 1)) {
|
|
260
|
+
branch = "L-> "
|
|
261
|
+
}
|
|
262
|
+
def line:string ""
|
|
263
|
+
line = " " + branch
|
|
264
|
+
def rootText:string (this.nodeLabel(root))
|
|
265
|
+
line = line + rootText
|
|
266
|
+
print line
|
|
267
|
+
this.renderSubtree(root childIndent)
|
|
268
|
+
shown = shown + 1
|
|
269
|
+
}
|
|
270
|
+
i = i + 1
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
package/dist/lib/stdlib.rgr
CHANGED
|
@@ -19,7 +19,13 @@ operators {
|
|
|
19
19
|
"var " (e 2) " = " (e 1) ";" nl
|
|
20
20
|
(block 3)
|
|
21
21
|
nl i "}"
|
|
22
|
-
)
|
|
22
|
+
)
|
|
23
|
+
kotlin (
|
|
24
|
+
(forkctx _ ) (def 2) "if( " (e 1) " is Boolean ) /* union case for boolean */ {" nl I
|
|
25
|
+
"val " (e 2) " : Boolean = " (e 1) " as Boolean;" nl
|
|
26
|
+
(block 3)
|
|
27
|
+
nl i "}"
|
|
28
|
+
)
|
|
23
29
|
}
|
|
24
30
|
}
|
|
25
31
|
case _@(newcontext):void ( arg@(union):T item2@(define):int code:block ) {
|
|
@@ -35,7 +41,13 @@ operators {
|
|
|
35
41
|
(e 2) " = " (e 1) ";" nl
|
|
36
42
|
(block 3)
|
|
37
43
|
nl i "}"
|
|
38
|
-
)
|
|
44
|
+
)
|
|
45
|
+
kotlin (
|
|
46
|
+
(forkctx _ ) (def 2) "if( " (e 1) " is Int ) /* union case for int */ {" nl I
|
|
47
|
+
"val " (e 2) " : Int = " (e 1) " as Int;" nl
|
|
48
|
+
(block 3)
|
|
49
|
+
nl i "}"
|
|
50
|
+
)
|
|
39
51
|
}
|
|
40
52
|
}
|
|
41
53
|
case _@(newcontext):void ( arg@(union):T item2@(define):double code:block ) {
|
|
@@ -51,7 +63,13 @@ operators {
|
|
|
51
63
|
(e 2) " = " (e 1) ";" nl
|
|
52
64
|
(block 3)
|
|
53
65
|
nl i "}"
|
|
54
|
-
)
|
|
66
|
+
)
|
|
67
|
+
kotlin (
|
|
68
|
+
(forkctx _ ) (def 2) "if( " (e 1) " is Double ) /* union case for double */ {" nl I
|
|
69
|
+
"val " (e 2) " : Double = " (e 1) " as Double;" nl
|
|
70
|
+
(block 3)
|
|
71
|
+
nl i "}"
|
|
72
|
+
)
|
|
55
73
|
}
|
|
56
74
|
}
|
|
57
75
|
|
|
@@ -69,6 +87,12 @@ operators {
|
|
|
69
87
|
(block 3)
|
|
70
88
|
nl i "}"
|
|
71
89
|
)
|
|
90
|
+
kotlin (
|
|
91
|
+
(forkctx _ ) (def 2) "if( " (e 1) " is String ) /* union case for string */ {" nl I
|
|
92
|
+
"val " (e 2) " : String = " (e 1) " as String;" nl
|
|
93
|
+
(block 3)
|
|
94
|
+
nl i "}"
|
|
95
|
+
)
|
|
72
96
|
ranger ( 'case ' (e 1) " " (e 2) ":" (typeof 2) " {" nl
|
|
73
97
|
I (block 3) i nl "}" nl
|
|
74
98
|
)
|
|
@@ -119,6 +143,12 @@ operators {
|
|
|
119
143
|
(typeof 2) " " (e 2) " = (" (typeof 2) ") " (e 1) ";" nl
|
|
120
144
|
(block 3)
|
|
121
145
|
|
|
146
|
+
nl i "}"
|
|
147
|
+
)
|
|
148
|
+
kotlin (
|
|
149
|
+
(forkctx _ ) (def 2) "if( " (e 1) " is " (typeof 2) " ) /* union case */ {" nl I
|
|
150
|
+
"val " (e 2) " : " (typeof 2) " = " (e 1) " as " (typeof 2) ";" nl
|
|
151
|
+
(block 3)
|
|
122
152
|
nl i "}"
|
|
123
153
|
)
|
|
124
154
|
cpp (
|
package/dist/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ranger-compiler",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.5",
|
|
4
4
|
"description": "Ranger cross-language compiler - compile once, run anywhere. Write code in Ranger and compile to JavaScript, TypeScript, Python, Go, Rust, Swift, C++, Java, Kotlin, C#, PHP, and Scala.",
|
|
5
5
|
"main": "api.js",
|
|
6
6
|
"types": "api.d.ts",
|