ranger-compiler 2.1.70 → 3.0.4
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 +114 -0
- package/README.md +956 -133
- package/{compiler/Lang.clj → dist/Lang.rgr} +2345 -75
- package/dist/README.md +116 -0
- package/dist/{bin/api.d.ts → api.d.ts} +430 -154
- package/dist/api.js +34345 -0
- package/{lib/Ajax.clj → dist/lib/Ajax.rgr} +1 -1
- package/{lib/CmdParams.clj → dist/lib/CmdParams.rgr} +72 -72
- package/{lib/Crypto.clj → dist/lib/Crypto.rgr} +1 -1
- package/{lib/DOMLib.clj → dist/lib/DOMLib.rgr} +2 -2
- package/{lib/Engine3D.clj → dist/lib/Engine3D.rgr} +1 -1
- package/{lib/ImmutableVector.clj → dist/lib/ImmutableVector.rgr} +364 -364
- package/{lib/IndexedDB.clj → dist/lib/IndexedDB.rgr} +1 -1
- package/{lib/JSON.clj → dist/lib/JSON.rgr} +105 -2
- package/{lib/JinxProcess.clj → dist/lib/JinxProcess.rgr} +3 -3
- package/{lib/Storage.clj → dist/lib/Storage.rgr} +1 -1
- package/{lib/Timers.clj → dist/lib/Timers.rgr} +176 -170
- package/{lib/ViewLib.clj → dist/lib/ViewLib.rgr} +1 -1
- package/dist/lib/lib/ACEEditor.rgr +5 -0
- package/dist/lib/lib/Ajax.rgr +196 -0
- package/dist/lib/lib/CmdParams.rgr +72 -0
- package/dist/lib/lib/Crypto.rgr +90 -0
- package/dist/lib/lib/DOMLib.rgr +307 -0
- package/{examples/3D/Engine3D.clj → dist/lib/lib/Engine3D.rgr} +870 -857
- package/dist/lib/lib/ImmutableVector.rgr +364 -0
- package/dist/lib/lib/IndexedDB.rgr +32 -0
- package/{compiler/JSON.clj → dist/lib/lib/JSON.rgr} +106 -3
- package/dist/lib/lib/JinxProcess.rgr +838 -0
- package/dist/lib/lib/SQL.rgr +44 -0
- package/dist/lib/lib/ServiceLib.rgr +9 -0
- package/dist/lib/lib/Storage.rgr +89 -0
- package/dist/lib/lib/Time.rgr +75 -0
- package/dist/lib/lib/Timers.rgr +176 -0
- package/dist/lib/lib/TypedArrays.rgr +14 -0
- package/dist/lib/lib/ViewLib.rgr +851 -0
- package/dist/lib/lib/WebLib.rgr +47 -0
- package/dist/lib/lib/WebServerLib.rgr +137 -0
- package/{lib/ranger-dir.clj → dist/lib/lib/ranger-dir.rgr} +1 -1
- package/{compiler/stdlib.clj → dist/lib/lib/stdlib.rgr} +42 -19
- package/{lib/stdops.clj → dist/lib/lib/stdops.rgr} +1 -1
- package/dist/lib/ranger-dir.rgr +175 -0
- package/{lib/stdlib.clj → dist/lib/stdlib.rgr} +2 -2
- package/dist/lib/stdops.rgr +168 -0
- package/dist/package.json +47 -0
- package/{compiler/bin/output.js → dist/rgrc.js} +15377 -7936
- package/dist/stdops.rgr +168 -0
- package/package.json +196 -39
- package/adventofcode/day1/bin/LambdaSignature1.java +0 -3
- package/adventofcode/day1/bin/LambdaSignature2.java +0 -3
- package/adventofcode/day1/bin/LambdaSignature3.java +0 -3
- package/adventofcode/day1/bin/day1.cpp +0 -124
- package/adventofcode/day1/bin/day1.go +0 -75
- package/adventofcode/day1/bin/day1.js +0 -45
- package/adventofcode/day1/bin/day1.php +0 -46
- package/adventofcode/day1/bin/day1.scala +0 -48
- package/adventofcode/day1/bin/day1.swift +0 -48
- package/adventofcode/day1/bin/day1_part2.cpp +0 -180
- package/adventofcode/day1/bin/day1_part2.go +0 -123
- package/adventofcode/day1/bin/day1_part2.js +0 -76
- package/adventofcode/day1/bin/day1_part2.php +0 -88
- package/adventofcode/day1/bin/day1_part2.scala +0 -81
- package/adventofcode/day1/bin/day1_part2.swift +0 -91
- package/adventofcode/day1/bin/day_one.java +0 -38
- package/adventofcode/day1/bin/day_one_part_two.java +0 -57
- package/adventofcode/day1/bin/operatorsOf.java +0 -37
- package/adventofcode/day1/bin/operatorsOf_5.java +0 -10
- package/adventofcode/day1/bin/operatorsOfboolean_5.java +0 -10
- package/adventofcode/day1/bin/variant.hpp +0 -2416
- package/adventofcode/day1/compile.bat +0 -7
- package/adventofcode/day1/compile2.bat +0 -7
- package/adventofcode/day1/day1.clj +0 -19
- package/adventofcode/day1/day1_part2.clj +0 -43
- package/adventofcode/day1/input1.txt +0 -1
- package/adventofcode/day2/bin/LambdaSignature1.class +0 -0
- package/adventofcode/day2/bin/LambdaSignature1.java +0 -3
- package/adventofcode/day2/bin/LambdaSignature2.class +0 -0
- package/adventofcode/day2/bin/LambdaSignature2.java +0 -3
- package/adventofcode/day2/bin/day2.cpp +0 -133
- package/adventofcode/day2/bin/day2.go +0 -85
- package/adventofcode/day2/bin/day2.js +0 -45
- package/adventofcode/day2/bin/day2.php +0 -59
- package/adventofcode/day2/bin/day2.scala +0 -54
- package/adventofcode/day2/bin/day2.swift +0 -62
- package/adventofcode/day2/bin/day2_part2.cpp +0 -150
- package/adventofcode/day2/bin/day2_part2.go +0 -101
- package/adventofcode/day2/bin/day2_part2.js +0 -54
- package/adventofcode/day2/bin/day2_part2.php +0 -80
- package/adventofcode/day2/bin/day2_part2.scala +0 -68
- package/adventofcode/day2/bin/day2_part2.swift +0 -82
- package/adventofcode/day2/bin/day_two.java +0 -61
- package/adventofcode/day2/bin/day_two_part_two$1$1$1.class +0 -0
- package/adventofcode/day2/bin/day_two_part_two$1$1.class +0 -0
- package/adventofcode/day2/bin/day_two_part_two$1.class +0 -0
- package/adventofcode/day2/bin/day_two_part_two.class +0 -0
- package/adventofcode/day2/bin/day_two_part_two.java +0 -80
- package/adventofcode/day2/bin/operatorsOf.class +0 -0
- package/adventofcode/day2/bin/operatorsOf.java +0 -18
- package/adventofcode/day2/bin/variant.hpp +0 -2416
- package/adventofcode/day2/compile.bat +0 -7
- package/adventofcode/day2/compile2.bat +0 -7
- package/adventofcode/day2/day2.clj +0 -60
- package/adventofcode/day2/day2_part2.clj +0 -69
- package/adventofcode/day2/input1.txt +0 -1
- package/adventofcode/day3/bin/Grid.java +0 -92
- package/adventofcode/day3/bin/GridRow.java +0 -5
- package/adventofcode/day3/bin/LambdaSignature1.java +0 -3
- package/adventofcode/day3/bin/LambdaSignature2.java +0 -3
- package/adventofcode/day3/bin/LambdaSignature3.java +0 -3
- package/adventofcode/day3/bin/day3.cpp +0 -64
- package/adventofcode/day3/bin/day3.go +0 -55
- package/adventofcode/day3/bin/day3.js +0 -42
- package/adventofcode/day3/bin/day3.php +0 -41
- package/adventofcode/day3/bin/day3.scala +0 -52
- package/adventofcode/day3/bin/day3.swift +0 -43
- package/adventofcode/day3/bin/day3_part2.cpp +0 -216
- package/adventofcode/day3/bin/day3_part2.go +0 -188
- package/adventofcode/day3/bin/day3_part2.js +0 -123
- package/adventofcode/day3/bin/day3_part2.php +0 -135
- package/adventofcode/day3/bin/day3_part2.swift +0 -131
- package/adventofcode/day3/bin/day_three_part_two.java +0 -43
- package/adventofcode/day3/bin/day_two.java +0 -42
- package/adventofcode/day3/bin/operatorsOf.java +0 -14
- package/adventofcode/day3/bin/variant.hpp +0 -2416
- package/adventofcode/day3/compile.bat +0 -7
- package/adventofcode/day3/compile2.bat +0 -7
- package/adventofcode/day3/day3.clj +0 -42
- package/adventofcode/day3/day3_part2.clj +0 -112
- package/adventofcode/day4/bin/LambdaSignature1.java +0 -3
- package/adventofcode/day4/bin/day4.cpp +0 -118
- package/adventofcode/day4/bin/day4.go +0 -75
- package/adventofcode/day4/bin/day4.js +0 -40
- package/adventofcode/day4/bin/day4.php +0 -52
- package/adventofcode/day4/bin/day4.scala +0 -47
- package/adventofcode/day4/bin/day4.swift +0 -56
- package/adventofcode/day4/bin/day4_part2.go +0 -129
- package/adventofcode/day4/bin/day4_part2.js +0 -72
- package/adventofcode/day4/bin/day_four.java +0 -41
- package/adventofcode/day4/bin/inputData.java +0 -7
- package/adventofcode/day4/bin/operatorsOf.java +0 -11
- package/adventofcode/day4/bin/variant.hpp +0 -2416
- package/adventofcode/day4/compile.bat +0 -7
- package/adventofcode/day4/compile2.bat +0 -7
- package/adventofcode/day4/day4.clj +0 -32
- package/adventofcode/day4/day4_part2.clj +0 -44
- package/adventofcode/day4/input.clj +0 -519
- package/adventofcode/day4/input.txt +0 -512
- package/bin/api.ts +0 -24471
- package/bin/compiler.ts +0 -24482
- package/bin/output.js +0 -23819
- package/compiler/ColorConsole.clj +0 -22
- package/compiler/ContextOperators.clj +0 -75
- package/compiler/FlowEnterVarDef.clj +0 -223
- package/compiler/InputFileSystem.clj +0 -276
- package/compiler/RangerDocs.clj +0 -7
- package/compiler/TFactory.clj +0 -146
- package/compiler/TFiles.clj +0 -23
- package/compiler/TFlow.clj +0 -39
- package/compiler/TNodeFactory.clj +0 -84
- package/compiler/TTypes.clj +0 -188
- package/compiler/VirtualCompiler.clj +0 -807
- package/compiler/bin/ng_Compiler.js +0 -23779
- package/compiler/commonmark_plugin.clj +0 -359
- package/compiler/feat2.bat +0 -2
- package/compiler/feats.bat +0 -9
- package/compiler/feature_tests.clj +0 -192
- package/compiler/index.js +0 -2
- package/compiler/issue_57.clj +0 -25
- package/compiler/makefile_plugin.clj +0 -135
- package/compiler/markdown_plugin.clj +0 -386
- package/compiler/maven_plugin.clj +0 -162
- package/compiler/ng_AndroidPageWriter.clj +0 -299
- package/compiler/ng_CodeNode.clj +0 -756
- package/compiler/ng_CodeNodeCompilerExtensions.clj +0 -839
- package/compiler/ng_Compiler.clj +0 -49
- package/compiler/ng_CompilerGeneric.clj +0 -260
- package/compiler/ng_CompilerOrig.clj +0 -854
- package/compiler/ng_DictNode.clj +0 -346
- package/compiler/ng_DictNode2.clj +0 -316
- package/compiler/ng_Execute.clj +0 -138
- package/compiler/ng_Execute1.clj +0 -129
- package/compiler/ng_FlowWork.clj +0 -3951
- package/compiler/ng_LiveCompiler.clj +0 -1109
- package/compiler/ng_RagnerJavaScriptClassWriter.clj +0 -402
- package/compiler/ng_RangerActiveOperators.clj +0 -86
- package/compiler/ng_RangerAppClassDesc.clj +0 -400
- package/compiler/ng_RangerAppEnums.clj +0 -86
- package/compiler/ng_RangerAppFunctionDesc.clj +0 -127
- package/compiler/ng_RangerAppMessages.clj +0 -15
- package/compiler/ng_RangerAppOperatorDesc.clj +0 -20
- package/compiler/ng_RangerAppParamDesc.clj +0 -388
- package/compiler/ng_RangerAppWriterContext.clj +0 -1793
- package/compiler/ng_RangerArgMatch.clj +0 -638
- package/compiler/ng_RangerCSharpClassWriter.clj +0 -484
- package/compiler/ng_RangerCppClassWriter.clj +0 -1023
- package/compiler/ng_RangerDocGenerator.clj +0 -305
- package/compiler/ng_RangerFlowParser.clj +0 -4992
- package/compiler/ng_RangerFlowParserOrig.clj +0 -4002
- package/compiler/ng_RangerGenericClassWriter.clj +0 -573
- package/compiler/ng_RangerGolangClassWriter.clj +0 -1766
- package/compiler/ng_RangerImmutableExtension.clj +0 -77
- package/compiler/ng_RangerJava7ClassWriter.clj +0 -961
- package/compiler/ng_RangerJavaScriptClassWriter.clj +0 -1040
- package/compiler/ng_RangerKotlinClassWriter.clj +0 -372
- package/compiler/ng_RangerLanguageWriters.clj +0 -14
- package/compiler/ng_RangerLispParser.clj +0 -873
- package/compiler/ng_RangerPHPClassWriter.clj +0 -643
- package/compiler/ng_RangerPlugin.clj +0 -41
- package/compiler/ng_RangerRangerClassWriter.clj +0 -357
- package/compiler/ng_RangerRustClassWriter.clj +0 -420
- package/compiler/ng_RangerScalaClassWriter.clj +0 -818
- package/compiler/ng_RangerSerializeClass.clj +0 -502
- package/compiler/ng_RangerServiceBuilder.clj +0 -63
- package/compiler/ng_RangerSwift3ClassWriter.clj +0 -809
- package/compiler/ng_RangerSwiftClassWriter.clj +0 -0
- package/compiler/ng_RangerTypeClass.clj +0 -45
- package/compiler/ng_SourceParser.clj +0 -241
- package/compiler/ng_SourceParser2.clj +0 -214
- package/compiler/ng_WebPageWriter.clj +0 -39
- package/compiler/ng_jsonParser.clj +0 -340
- package/compiler/ng_p_test.clj +0 -1711
- package/compiler/ng_parser.clj +0 -911
- package/compiler/ng_parser2.clj +0 -735
- package/compiler/ng_parser2_backup.clj +0 -1679
- package/compiler/ng_parser_backup.clj +0 -886
- package/compiler/ng_parser_ok.clj +0 -1718
- package/compiler/ng_parser_ok2.clj +0 -1717
- package/compiler/ng_parser_std_match.clj +0 -687
- package/compiler/ng_parser_std_match2.clj +0 -1012
- package/compiler/ng_parser_v2.clj +0 -1251
- package/compiler/ng_ui.clj +0 -403
- package/compiler/ng_ui_test.clj +0 -18
- package/compiler/ng_writer.clj +0 -338
- package/compiler/ng_xmlParser.clj +0 -472
- package/compiler/ng_xmlParser2.clj +0 -317
- package/compiler/ng_xmlParser3.clj +0 -251
- package/compiler/opdoc.bat +0 -4
- package/compiler/operators.md +0 -290
- package/compiler/p.bat +0 -4
- package/compiler/package.json +0 -10
- package/compiler/pcmd.bat +0 -4
- package/compiler/pcmd2.bat +0 -3
- package/compiler/plaintext_plugin.clj +0 -69
- package/compiler/plugin.bat +0 -19
- package/compiler/plugin2.bat +0 -4
- package/compiler/plugin_app.bat +0 -3
- package/compiler/plugin_apps.clj +0 -27
- package/compiler/plugins.bat +0 -10
- package/compiler/reveal_plugin.clj +0 -409
- package/compiler/simplePlugin.clj +0 -780
- package/compiler/t.bat +0 -3
- package/compiler/test_any.clj +0 -43
- package/compiler/test_call.clj +0 -141
- package/compiler/test_chain.clj +0 -79
- package/compiler/test_json.clj +0 -10
- package/compiler/test_lambda.clj +0 -153
- package/compiler/test_pcmd.clj +0 -32
- package/compiler/test_pcmd2.clj +0 -29
- package/compiler/test_plugin.clj +0 -237
- package/compiler/test_readfile.clj +0 -13
- package/compiler/test_reveal.clj +0 -19
- package/compiler/test_slides.clj +0 -312
- package/compiler/test_types.clj +0 -143
- package/compiler/test_types2.clj +0 -49
- package/compiler/test_types3.clj +0 -53
- package/compiler/test_var.clj +0 -40
- package/compiler/tonpm.bat +0 -14
- package/compiler/tonpm2.bat +0 -12
- package/compiler/ui_plugin.clj +0 -507
- package/compiler/ui_plugin2.clj +0 -427
- package/compiler/update-git.bat +0 -3
- package/compiler/vcomp.bat +0 -4
- package/compiler/viewbuilder_Android.clj +0 -176
- package/compiler/viewbuilder_Web.clj +0 -105
- package/dist/bin/api.js +0 -32422
- package/dist/bin/compiler.d.ts +0 -1638
- package/dist/bin/compiler.js +0 -32444
- package/examples/3D/bin/test_3d.js +0 -329
- package/examples/3D/test_3d.clj +0 -385
- package/examples/EVGColor/EVGColor.clj +0 -310
- package/examples/EVGColor/EVGColorContext.clj +0 -176
- package/examples/EVGColor/bin/EVGColor.js +0 -286
- package/examples/EVGColor/bin/minimized.js +0 -286
- package/examples/SVGPath/SVGPath.clj +0 -625
- package/examples/SVGPath/Vec2.clj +0 -103
- package/examples/SVGPath/bin/SVGPath.cpp +0 -887
- package/examples/SVGPath/bin/SVGPath.js +0 -682
- package/examples/SVGPath/bin/SVGPath.ts +0 -711
- package/examples/SVGPath/bin/minimized.js +0 -578
- package/examples/SVGPath/bin/variant.hpp +0 -2416
- package/examples/minification/Vec2.clj +0 -103
- package/examples/minification/bin/minified.js +0 -44
- package/examples/minification/bin/test.js +0 -117
- package/examples/minification/test.clj +0 -13
- package/fiddle/VirtualCompiler.js +0 -23495
- package/fiddle/browser_editor.js +0 -13240
- package/fiddle/compileEnv.js +0 -1
- package/fiddle/compileEnv.json +0 -1
- package/fiddle/lang_data.js +0 -1
- package/index.html +0 -18
- package/native/httpd/HttpTester.clj +0 -33
- package/native/httpd/RangerWebService.clj +0 -81
- package/operators.md +0 -290
- package/tsconfig.json +0 -29
- package/versions/cpp/compiler.cpp +0 -15032
- package/versions/es6/compiler.js +0 -12860
- package/versions/go/compiler.go +0 -21338
- package/versions/java/AfterCodeNode.java +0 -4
- package/versions/java/ClassJoinPoint.java +0 -6
- package/versions/java/CodeFile.java +0 -42
- package/versions/java/CodeFileSystem.java +0 -72
- package/versions/java/CodeNode.java +0 -807
- package/versions/java/CodeSlice.java +0 -13
- package/versions/java/CodeWriter.java +0 -185
- package/versions/java/ColorConsole.java +0 -8
- package/versions/java/CompilerInterface.java +0 -213
- package/versions/java/DictNode.java +0 -353
- package/versions/java/LiveCompiler.java +0 -772
- package/versions/java/NodeEvalState.java +0 -24
- package/versions/java/OpFindResult.java +0 -6
- package/versions/java/RangerAppArrayValue.java +0 -7
- package/versions/java/RangerAppClassDesc.java +0 -217
- package/versions/java/RangerAppEnum.java +0 -14
- package/versions/java/RangerAppFunctionDesc.java +0 -20
- package/versions/java/RangerAppHashValue.java +0 -11
- package/versions/java/RangerAppInterfaceImpl.java +0 -6
- package/versions/java/RangerAppMethodVariants.java +0 -6
- package/versions/java/RangerAppParamDesc.java +0 -321
- package/versions/java/RangerAppTodo.java +0 -6
- package/versions/java/RangerAppValue.java +0 -10
- package/versions/java/RangerAppWriterContext.java +0 -800
- package/versions/java/RangerArgMatch.java +0 -317
- package/versions/java/RangerBackReference.java +0 -7
- package/versions/java/RangerCSharpClassWriter.java +0 -287
- package/versions/java/RangerCompilerMessage.java +0 -9
- package/versions/java/RangerCppClassWriter.java +0 -725
- package/versions/java/RangerFlowParser.java +0 -2142
- package/versions/java/RangerGenericClassWriter.java +0 -367
- package/versions/java/RangerGolangClassWriter.java +0 -1379
- package/versions/java/RangerJava7ClassWriter.java +0 -652
- package/versions/java/RangerJavaScriptClassWriter.java +0 -305
- package/versions/java/RangerKotlinClassWriter.java +0 -380
- package/versions/java/RangerLispParser.java +0 -845
- package/versions/java/RangerNodeValue.java +0 -9
- package/versions/java/RangerPHPClassWriter.java +0 -527
- package/versions/java/RangerParamEventHandler.java +0 -6
- package/versions/java/RangerParamEventList.java +0 -5
- package/versions/java/RangerParamEventMap.java +0 -27
- package/versions/java/RangerRangerClassWriter.java +0 -268
- package/versions/java/RangerRefForce.java +0 -7
- package/versions/java/RangerScalaClassWriter.java +0 -365
- package/versions/java/RangerSerializeClass.java +0 -148
- package/versions/java/RangerSwift3ClassWriter.java +0 -548
- package/versions/java/RangerTypeClass.java +0 -17
- package/versions/java/SourceCode.java +0 -65
- package/versions/php/compiler.php +0 -13830
- package/versions/swift3/compiler.swift +0 -12542
- /package/{lib/ACEEditor.clj → dist/lib/ACEEditor.rgr} +0 -0
- /package/{lib/SQL.clj → dist/lib/SQL.rgr} +0 -0
- /package/{lib/ServiceLib.clj → dist/lib/ServiceLib.rgr} +0 -0
- /package/{lib/Time.clj → dist/lib/Time.rgr} +0 -0
- /package/{lib/TypedArrays.clj → dist/lib/TypedArrays.rgr} +0 -0
- /package/{lib/WebLib.clj → dist/lib/WebLib.rgr} +0 -0
- /package/{lib/WebServerLib.clj → dist/lib/WebServerLib.rgr} +0 -0
package/README.md
CHANGED
|
@@ -1,24 +1,709 @@
|
|
|
1
|
-
|
|
2
1
|
# Ranger cross language compiler
|
|
3
2
|
|
|
4
|
-
Status: `experimental`
|
|
3
|
+
**Version 3.0.4** | Status: `experimental`
|
|
4
|
+
|
|
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
|
+
|
|
7
|
+
It includes a compact typed language with classes, inheritance, traits, lambdas, type inference, extension methods, custom operators, and host integration through system classes.
|
|
8
|
+
|
|
9
|
+
Ranger is best approached today as a compiler and language lab with practical multi-target output, not as a polished general-purpose language ecosystem.
|
|
10
|
+
|
|
11
|
+
## What Ranger Is Good At
|
|
12
|
+
|
|
13
|
+
- Writing one algorithm or tool and emitting several target languages from the same source
|
|
14
|
+
- Building parsers, analyzers, generators, and DSL-like tooling with a small runtime surface
|
|
15
|
+
- Experimenting with language design, operator templates, and code generation strategies
|
|
16
|
+
- Studying a self-hosting compiler that is actively used to compile itself
|
|
17
|
+
|
|
18
|
+
## Word of Warning
|
|
19
|
+
|
|
20
|
+
- Ranger is still `experimental`, which means: be ready to fix bugs or add new capabilities when needed
|
|
21
|
+
- Target quality varies by language and by feature area
|
|
22
|
+
- The compiler is self-hosting, but the official and best-supported host is Node.js
|
|
23
|
+
- Not every example in this repository works fully out of the box on every machine
|
|
24
|
+
- Several examples in `gallery/` are research or showcase projects and may require extra toolchains, platform-specific commands, or manual setup
|
|
25
|
+
|
|
26
|
+
If you want one sentence of positioning: Ranger is currently more convincing as a portable algorithm compiler / DSL toolchain than as a drop-in replacement for mainstream application languages.
|
|
27
|
+
|
|
28
|
+
## Where To Start
|
|
29
|
+
|
|
30
|
+
- `README.md` - language overview, installation, and syntax notes
|
|
31
|
+
- `ai/QUICKREF.md` - fast reference for syntax and core concepts
|
|
32
|
+
- `ai/INSTRUCTIONS.md` - fuller language guide for operators, templates, and compiler concepts
|
|
33
|
+
- `ai/EXAMPLES.md` - short focused language examples
|
|
34
|
+
- `gallery/` - larger examples and experiments such as parsers, EVG/TSX tooling, and games
|
|
35
|
+
- `gallery/js_parser` - substantial parser example with benchmarks and README
|
|
36
|
+
- `gallery/pdf_writer` - EVG / TSX document tooling and preview server
|
|
37
|
+
- `gallery/invaders` - cross-target demo game
|
|
38
|
+
|
|
39
|
+
## Compatibility Snapshot
|
|
40
|
+
|
|
41
|
+
The project can target `JavaScript`, `Java`, `Go`, `Swift`, `PHP`, `C++`, `C#`, `Scala`, `Python`, `Kotlin`, and `Rust`, but support is uneven.
|
|
42
|
+
|
|
43
|
+
| Area | Current expectation |
|
|
44
|
+
| --- | --- |
|
|
45
|
+
| Host/runtime | Node.js is the primary supported host for the compiler |
|
|
46
|
+
| Self-hosting | Actively used, but full compiler generation quality is strongest in JavaScript |
|
|
47
|
+
| JavaScript / ES6 | Best baseline target and most reliable place to start |
|
|
48
|
+
| Go / Swift / Rust / Kotlin / C++ | Useful and increasingly capable, but expect edge cases and target-specific gaps |
|
|
49
|
+
| Gallery examples | Good for understanding direction and capability, but some require manual setup or platform-specific tooling |
|
|
50
|
+
|
|
51
|
+
## What's New in Version 3.0
|
|
52
|
+
|
|
53
|
+
- **New File Extension** - Transitioning from `.clj` to `.rgr` for Ranger identity
|
|
54
|
+
- **Simplified CLI** - Use `rgrc` command for shorter invocations
|
|
55
|
+
- **VSCode Extension** - Language server with syntax highlighting (in development)
|
|
56
|
+
- **CI/CD Pipeline** - Automated testing and NPM publishing
|
|
57
|
+
- **Unit Test Suite** - Comprehensive test coverage with Vitest
|
|
58
|
+
|
|
59
|
+
### Quick Start
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
# Install globally
|
|
63
|
+
npm install -g ranger-compiler
|
|
64
|
+
|
|
65
|
+
# Compile to JavaScript
|
|
66
|
+
rgrc -l=es6 myfile.rgr -o=output.js
|
|
67
|
+
|
|
68
|
+
# Compile to TypeScript
|
|
69
|
+
rgrc -l=es6 -typescript myfile.rgr -o=output.ts
|
|
70
|
+
|
|
71
|
+
# Compile to Python
|
|
72
|
+
rgrc -l=python myfile.rgr -o=output.py
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
See [CHANGELOG.md](CHANGELOG.md) for full version history and [PLAN_3.md](PLAN_3.md) for the roadmap.
|
|
5
76
|
|
|
6
|
-
|
|
7
|
-
The language has type safety, classes, inheritance, operator overloading, lambda functions, generic traits,
|
|
8
|
-
class extensions, type inference and can integrate with host system API's using system classes.
|
|
77
|
+
---
|
|
9
78
|
|
|
10
79
|
## Host platforms and target languages
|
|
11
80
|
|
|
12
|
-
The compiler is
|
|
81
|
+
The compiler is _self hosting_ which means that it has been written using the compiler itself and thus it can be hosted
|
|
13
82
|
on several platforms. At the moment the official platform is node.js, because external plugins are only available as npm packages.
|
|
14
83
|
|
|
15
|
-
The target languages supported are `JavaScript`, `Java`, `Go`, `Swift`, `PHP`, `C++`, `C
|
|
16
|
-
of the target translation still varies and at the moment of this writing the compiler can only be compiled fully to
|
|
17
|
-
target. However, most targets already can compile reasonably good code.
|
|
84
|
+
The target languages supported are `JavaScript`, `Java`, `Go`, `Swift`, `PHP`, `C++`, `C#`, `Scala`, `Python`, and `Rust`. The quality
|
|
85
|
+
of the target translation still varies and at the moment of this writing the compiler can only be compiled fully to JavaScript
|
|
86
|
+
target. However, most targets already can compile reasonably good code.
|
|
87
|
+
|
|
88
|
+
## Recent Updates (December 2025)
|
|
89
|
+
|
|
90
|
+
### TypeScript Parser (TSParser) Enhancements
|
|
91
|
+
|
|
92
|
+
The TSParser (`gallery/ts_parser`) now supports additional JavaScript/TypeScript syntax features:
|
|
93
|
+
|
|
94
|
+
**New Operators:**
|
|
95
|
+
- **UpdateExpression**: `i++`, `++i`, `i--`, `--i` with proper prefix/postfix semantics
|
|
96
|
+
- **Compound Assignment**: `+=`, `-=`, `*=`, `/=`, `%=` operators
|
|
97
|
+
- **Computed Member Access**: Array indexing `arr[i]` now correctly sets the `computed` flag
|
|
98
|
+
|
|
99
|
+
These enhancements enable the EVG ComponentEngine to evaluate for loops and dynamic array operations in TSX files.
|
|
100
|
+
|
|
101
|
+
### Swift 6 Target Support
|
|
102
|
+
|
|
103
|
+
The Swift 6 target (`-l=swift6`) has been significantly enhanced with the following features:
|
|
104
|
+
|
|
105
|
+
- Modern Swift 6 compatible code generation
|
|
106
|
+
- Simple `main()` function entry point (avoids @main conflicts with operator overloads)
|
|
107
|
+
- Proper integer-to-string conversion using `String()`
|
|
108
|
+
- Array operations using `.append()` instead of `.push()`
|
|
109
|
+
- File I/O with `Foundation` framework integration
|
|
110
|
+
- String operations: `substring`, `indexOf`, `startsWith`, `endsWith`, `contains`, `split`, `trim`
|
|
111
|
+
- Optional handling with `unwrap` and `!!` operators
|
|
112
|
+
- Command-line argument access
|
|
113
|
+
- CRLF grapheme cluster handling for cross-platform string compatibility
|
|
114
|
+
|
|
115
|
+
**Successfully compiled projects:**
|
|
116
|
+
|
|
117
|
+
- ✅ JavaScript ES6+ Parser (`gallery/js_parser`) - 4500+ lines, parses and pretty-prints ES6+ code
|
|
118
|
+
- ✅ Space Invaders game (`gallery/invaders`)
|
|
119
|
+
|
|
120
|
+
Example compilation:
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
node bin/output.js myfile.rgr -l=swift6 -o=myfile.swift
|
|
124
|
+
sed -i '' $'s/\r$//' myfile.swift # Fix line endings on macOS
|
|
125
|
+
swiftc myfile.swift -o myfile
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Rust Target Support (Preliminary)
|
|
129
|
+
|
|
130
|
+
The Rust target (`-l=rust`) now has preliminary support with the following features:
|
|
131
|
+
|
|
132
|
+
- Classes compiled to structs with `impl` blocks
|
|
133
|
+
- Constructors as `pub fn new()` returning owned structs
|
|
134
|
+
- Static factory methods
|
|
135
|
+
- Instance methods with `&mut self`
|
|
136
|
+
- Proper String handling with `.to_string()` for literals
|
|
137
|
+
- Array operations (`push`, `itemAt`, `set`) with `Vec<T>`
|
|
138
|
+
- String concatenation using `format!` macro
|
|
139
|
+
- Ternary expressions as `if/else` expressions
|
|
140
|
+
- Automatic `#[derive(Clone)]` for structs
|
|
141
|
+
- Smart mutability detection (`let` vs `let mut`)
|
|
142
|
+
|
|
143
|
+
Example compilation:
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
node bin/output.js myfile.rgr -l=rust -o=myfile.rs
|
|
147
|
+
rustc myfile.rs -o myfile
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### C++ Static Analysis Optimizer (New)
|
|
151
|
+
|
|
152
|
+
The C++ target (`-l=cpp`) now includes a static analysis pass that automatically detects mutation patterns and generates proper C++ references. This solves a common issue where local variables assigned from member fields were incorrectly copied instead of referenced.
|
|
153
|
+
|
|
154
|
+
**The Problem:**
|
|
155
|
+
|
|
156
|
+
```ranger
|
|
157
|
+
fn writeByte:void (b:int) {
|
|
158
|
+
def buf:buffer currentChunk.data ; Assigned from member field
|
|
159
|
+
buffer_set buf 0 b ; Mutates the buffer
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Without static analysis, this would generate:
|
|
164
|
+
|
|
165
|
+
```cpp
|
|
166
|
+
void writeByte(int b) {
|
|
167
|
+
std::vector<uint8_t> buf = currentChunk->data; // COPY!
|
|
168
|
+
buf[0] = static_cast<uint8_t>(b); // Modifies copy, not original!
|
|
169
|
+
}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
**The Solution:**
|
|
173
|
+
|
|
174
|
+
The static analyzer detects when:
|
|
175
|
+
|
|
176
|
+
1. A local variable is assigned from a member field (e.g., `obj.field`)
|
|
177
|
+
2. That variable is later mutated with in-place operations (`buffer_set`, `push`, `set`, etc.)
|
|
178
|
+
|
|
179
|
+
When both conditions are met, it generates a C++ reference:
|
|
180
|
+
|
|
181
|
+
```cpp
|
|
182
|
+
void writeByte(int b) {
|
|
183
|
+
std::vector<uint8_t>& buf = currentChunk->data; // REFERENCE!
|
|
184
|
+
buf[0] = static_cast<uint8_t>(b); // Modifies original
|
|
185
|
+
}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
**Mutating Operations Detected:**
|
|
189
|
+
|
|
190
|
+
| Category | Operators |
|
|
191
|
+
| ---------- | ------------------------------------------------------------- |
|
|
192
|
+
| Buffer | `buffer_set`, `int_buffer_set`, `double_buffer_set`, `*_fill` |
|
|
193
|
+
| Array | `push`, `set`, `clear`, `remove`, `removeIndex` |
|
|
194
|
+
| Dictionary | `put` |
|
|
195
|
+
|
|
196
|
+
This optimization is automatically applied when compiling to C++ - no source code changes required.
|
|
197
|
+
|
|
198
|
+
### HTTP Server Support (New - December 2025)
|
|
199
|
+
|
|
200
|
+
Ranger now supports defining HTTP servers using **annotation-based type aliasing**. Classes marked with `@(HttpServer)` can use HTTP operators and route annotations.
|
|
201
|
+
|
|
202
|
+
**Example HTTP Server:**
|
|
203
|
+
|
|
204
|
+
```ranger
|
|
205
|
+
Import "stdlib.rgr"
|
|
206
|
+
|
|
207
|
+
class MyServer@(HttpServer) {
|
|
208
|
+
fn handleIndex@(GET "/"):void (req:HttpRequest res:HttpResponse) {
|
|
209
|
+
http_set_header res "Content-Type" "text/html"
|
|
210
|
+
http_set_status res 200
|
|
211
|
+
http_send res "<h1>Hello from Ranger!</h1>"
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
fn handleEvents@(SSE "/events"):void (client:SSEClient) {
|
|
215
|
+
sse_send client "message" "Welcome!"
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
sfn main@(main):void () {
|
|
220
|
+
def server:MyServer (new MyServer())
|
|
221
|
+
start server 3000
|
|
222
|
+
}
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
**Key Features:**
|
|
226
|
+
|
|
227
|
+
- **Systemclass types**: `HttpRequest`, `HttpResponse`, `SSEClient`, `HttpServer`
|
|
228
|
+
- **HTTP operators**: `http_get_method`, `http_get_path`, `http_set_status`, `http_set_header`, `http_send`
|
|
229
|
+
- **SSE operators**: `sse_send`, `sse_is_connected`
|
|
230
|
+
- **Route annotations**: `@(GET "/path")`, `@(POST "/path")`, `@(SSE "/path")`
|
|
231
|
+
- **Server lifecycle**: `start server port`, `stop server`
|
|
232
|
+
|
|
233
|
+
**Compilation:**
|
|
234
|
+
|
|
235
|
+
```bash
|
|
236
|
+
# Compile to Go
|
|
237
|
+
RANGER_LIB=./compiler/Lang.rgr node bin/output.js -l=go ./myserver.rgr -d=./bin -o=myserver.go -nodecli
|
|
238
|
+
|
|
239
|
+
# Run the server
|
|
240
|
+
cd bin && go run myserver.go
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
Currently supports **Go** target. See `tests/fixtures/http_server.rgr` for a complete example.
|
|
244
|
+
|
|
245
|
+
### EVG Document Preview Tools (New - December 2025)
|
|
246
|
+
|
|
247
|
+
Ranger includes tools for creating and previewing documents using a React-like TSX syntax. The EVG (Extensible Vector Graphics) system supports multi-page documents with flexbox layout.
|
|
248
|
+
|
|
249
|
+
**Live Preview Server:**
|
|
250
|
+
|
|
251
|
+
```bash
|
|
252
|
+
# Build the preview server (one-time)
|
|
253
|
+
npm run evgpreview:build
|
|
254
|
+
|
|
255
|
+
# Start live preview with auto-reload
|
|
256
|
+
cd gallery/pdf_writer
|
|
257
|
+
./bin/evg_preview_server examples/test_gallery.tsx 3006
|
|
258
|
+
|
|
259
|
+
# Open http://localhost:3006 - auto-refreshes on file save!
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
**HTML Generation:**
|
|
263
|
+
|
|
264
|
+
```bash
|
|
265
|
+
# Build the HTML tool (one-time)
|
|
266
|
+
npm run evg:tool:build:go
|
|
267
|
+
|
|
268
|
+
# Convert TSX to HTML
|
|
269
|
+
cd gallery/pdf_writer
|
|
270
|
+
./bin/evg_tool examples/test_gallery.tsx output.html
|
|
271
|
+
|
|
272
|
+
# With component imports
|
|
273
|
+
./bin/evg_tool document.tsx --assets=../components;../assets
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
**Features:**
|
|
277
|
+
|
|
278
|
+
- **Live reload** - Browser auto-refreshes when you save
|
|
279
|
+
- **Component imports** - Reusable TSX components
|
|
280
|
+
- **Multi-page documents** - Print, Section, Page elements
|
|
281
|
+
- **Flexbox layout** - CSS-like positioning
|
|
282
|
+
- **Images & fonts** - Asset serving from configurable paths
|
|
283
|
+
|
|
284
|
+
See `gallery/pdf_writer/README.md` for full documentation and TSX syntax reference.
|
|
285
|
+
|
|
286
|
+
### EVG ComponentEngine TypeScript Evaluation (New - December 2025)
|
|
287
|
+
|
|
288
|
+
The EVG ComponentEngine now supports **full TypeScript control flow evaluation**, enabling dynamic document generation with loops and conditionals. Functions defined in TSX files can use for loops, array operations, and return arrays of elements.
|
|
289
|
+
|
|
290
|
+
**Supported Features:**
|
|
291
|
+
|
|
292
|
+
| Feature | Syntax | Description |
|
|
293
|
+
|---------|--------|-------------|
|
|
294
|
+
| For loops | `for (let i = 0; i < n; i++)` | Standard for loop with init/test/update |
|
|
295
|
+
| Decrement loops | `for (let i = 5; i > 0; i--)` | Countdown loops |
|
|
296
|
+
| Step loops | `for (let i = 0; i < n; i += 2)` | Custom step increments |
|
|
297
|
+
| Array.push | `arr.push(<Element />)` | Build arrays of JSX elements |
|
|
298
|
+
| Array indexing | `colors[i]` | Access array elements by index |
|
|
299
|
+
| Compound assignment | `total += value` | `+=`, `-=`, `*=`, `/=`, `%=` operators |
|
|
300
|
+
| Update expressions | `i++`, `++i`, `i--`, `--i` | Pre/post increment/decrement |
|
|
301
|
+
| Function calls in JSX | `{buildItems()}` | Call functions that return element arrays |
|
|
302
|
+
|
|
303
|
+
**Example - Dynamic List Generation:**
|
|
304
|
+
|
|
305
|
+
```tsx
|
|
306
|
+
const colors = ["#ef4444", "#f97316", "#eab308", "#22c55e", "#3b82f6"];
|
|
307
|
+
|
|
308
|
+
function buildColorBoxes() {
|
|
309
|
+
const boxes: any[] = [];
|
|
310
|
+
|
|
311
|
+
for (let i = 0; i < colors.length; i++) {
|
|
312
|
+
const color = colors[i];
|
|
313
|
+
boxes.push(
|
|
314
|
+
<View backgroundColor={color} padding={8}>
|
|
315
|
+
<Label color="#ffffff">Box {i + 1}: {color}</Label>
|
|
316
|
+
</View>
|
|
317
|
+
);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
return boxes;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
function render() {
|
|
324
|
+
return (
|
|
325
|
+
<Print>
|
|
326
|
+
<Section>
|
|
327
|
+
<Page>
|
|
328
|
+
<View padding={16}>
|
|
329
|
+
<Label fontSize={20} fontWeight="bold">Color Boxes</Label>
|
|
330
|
+
{buildColorBoxes()}
|
|
331
|
+
</View>
|
|
332
|
+
</Page>
|
|
333
|
+
</Section>
|
|
334
|
+
</Print>
|
|
335
|
+
);
|
|
336
|
+
}
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
**Example - Progressive Widths with Accumulator:**
|
|
340
|
+
|
|
341
|
+
```tsx
|
|
342
|
+
function buildProgressBars() {
|
|
343
|
+
const bars: any[] = [];
|
|
344
|
+
let totalWidth = 0;
|
|
345
|
+
|
|
346
|
+
for (let i = 1; i <= 5; i++) {
|
|
347
|
+
totalWidth += i * 20; // 20, 60, 120, 200, 300
|
|
348
|
+
bars.push(
|
|
349
|
+
<View width={totalWidth} backgroundColor="#0ea5e9" padding={4}>
|
|
350
|
+
<Label color="#ffffff">Width: {totalWidth}px</Label>
|
|
351
|
+
</View>
|
|
352
|
+
);
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
return bars;
|
|
356
|
+
}
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
See `gallery/pdf_writer/examples/test_for_loop.tsx` for a complete demonstration.
|
|
360
|
+
|
|
361
|
+
### Space Invaders Demo Game
|
|
362
|
+
|
|
363
|
+
A complete terminal-based Space Invaders game demonstrating Ranger's cross-language capabilities. The same source code compiles to **4 different targets**:
|
|
364
|
+
|
|
365
|
+
| Target | Executable | Build Command |
|
|
366
|
+
| -------------- | ------------------- | --------------------------- |
|
|
367
|
+
| ES6/JavaScript | `invaders.js` | `npm run game:compile` |
|
|
368
|
+
| Rust | `invaders_rust.exe` | `npm run game:build:rust` |
|
|
369
|
+
| Go | `invaders_go.exe` | `npm run game:build:go` |
|
|
370
|
+
| Kotlin | `invaders.jar` | `npm run game:build:kotlin` |
|
|
371
|
+
| C++ | `invaders_cpp.exe` | Cross-compile via WSL |
|
|
372
|
+
| Swift | `invaders_swift` | macOS/Linux only |
|
|
373
|
+
|
|
374
|
+
> **Note:** Kotlin target renders correctly but keyboard input has issues on Windows (uses PowerShell subprocess for key reading which is slow).
|
|
375
|
+
|
|
376
|
+
```bash
|
|
377
|
+
# Build all targets at once
|
|
378
|
+
npm run game:build:all
|
|
379
|
+
|
|
380
|
+
# Run the game
|
|
381
|
+
npm run game:run # JavaScript
|
|
382
|
+
npm run game:run:rust # Rust
|
|
383
|
+
npm run game:run:go # Go
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
#### Cross-Compiling the Game
|
|
387
|
+
|
|
388
|
+
The Space Invaders game demonstrates cross-platform compilation from a single source file.
|
|
389
|
+
|
|
390
|
+
**JavaScript (ES6)**
|
|
391
|
+
|
|
392
|
+
```bash
|
|
393
|
+
npm run game:compile # Generates invaders.js
|
|
394
|
+
node gallery/invaders/invaders.js
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
**Rust**
|
|
398
|
+
|
|
399
|
+
```bash
|
|
400
|
+
npm run game:compile:rust # Generates invaders.rs
|
|
401
|
+
cd gallery/invaders && rustc invaders.rs -o invaders_rust.exe
|
|
402
|
+
# Or use the combined command:
|
|
403
|
+
npm run game:build:rust
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
**Go**
|
|
407
|
+
|
|
408
|
+
```bash
|
|
409
|
+
npm run game:compile:go # Generates invaders.go
|
|
410
|
+
cd gallery/invaders && go build -o invaders_go.exe invaders.go
|
|
411
|
+
# Or use the combined command:
|
|
412
|
+
npm run game:build:go
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
**C++ (Windows via WSL)**
|
|
416
|
+
|
|
417
|
+
C++ compilation requires POSIX-threaded MinGW for `std::thread` and `std::mutex` support:
|
|
418
|
+
|
|
419
|
+
```bash
|
|
420
|
+
npm run game:compile:cpp # Generates invaders.cpp
|
|
421
|
+
|
|
422
|
+
# Cross-compile from WSL to Windows:
|
|
423
|
+
wsl -d Ubuntu -- bash -c "
|
|
424
|
+
cd /mnt/c/path/to/Ranger/gallery/invaders && \
|
|
425
|
+
sed -i 's/\r$//' invaders.cpp && \
|
|
426
|
+
x86_64-w64-mingw32-g++-posix -std=c++17 -static -pthread invaders.cpp -o invaders_cpp.exe
|
|
427
|
+
"
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
> **Note:** The standard MinGW compiler (`x86_64-w64-mingw32-g++`) uses win32 threads which don't support `<mutex>` and `<thread>`. You must use the POSIX variant (`g++-posix`).
|
|
431
|
+
|
|
432
|
+
**Swift (macOS/Linux only)**
|
|
433
|
+
|
|
434
|
+
```bash
|
|
435
|
+
npm run game:compile:swift # Generates invaders.swift
|
|
436
|
+
swiftc invaders.swift -o invaders_swift
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
#### Platform-Specific Keyboard Input
|
|
440
|
+
|
|
441
|
+
The game uses `on_keypress` and `poll_keypress` operators with platform-specific implementations:
|
|
442
|
+
|
|
443
|
+
| Platform | Windows | Unix/Linux/macOS |
|
|
444
|
+
| -------- | --------------------------------- | -------------------------- |
|
|
445
|
+
| Rust | `windows-sys` crate | `termios` + `libc` |
|
|
446
|
+
| Go | `msvcrt.dll` (`_kbhit`, `_getch`) | `stty` + `os.Stdin` |
|
|
447
|
+
| C++ | `<conio.h>` (`_kbhit`, `_getch`) | `<termios.h>` + `read()` |
|
|
448
|
+
| Swift | `_kbhit` / `_getch` via C interop | `Darwin` / `Glibc` termios |
|
|
449
|
+
|
|
450
|
+
The game uses terminal control operators (`clear_screen`, `move_cursor`, `hide_cursor`, etc.) and keyboard input (`on_keypress`, `poll_keypress`) that have platform-specific implementations for Windows and Unix.
|
|
451
|
+
|
|
452
|
+
#### Target Comparison: Code Size and Executable Size
|
|
453
|
+
|
|
454
|
+
The Space Invaders game provides an interesting comparison of how the same Ranger source code translates to different targets.
|
|
455
|
+
|
|
456
|
+
**Source Code Sizes:**
|
|
457
|
+
|
|
458
|
+
| Target | Generated File | Size (bytes) | Lines | Notes |
|
|
459
|
+
| ---------- | ---------------- | ------------ | ----- | ------------------------------- |
|
|
460
|
+
| **Ranger** | `invaders.rgr` | 11,289 | ~400 | Original source |
|
|
461
|
+
| Python | `invaders.py` | 9,271 | ~330 | Most compact generated code |
|
|
462
|
+
| JavaScript | `invaders.js` | 10,301 | ~350 | Clean, readable output |
|
|
463
|
+
| Swift | `invaders.swift` | 12,554 | ~470 | Verbose type annotations |
|
|
464
|
+
| Go | `invaders.go` | 13,701 | ~480 | Explicit error handling |
|
|
465
|
+
| C++ | `invaders.cpp` | 14,148 | ~500 | Headers and type declarations |
|
|
466
|
+
| Rust | `invaders.rs` | 17,918 | ~600 | Most verbose (ownership, types) |
|
|
467
|
+
|
|
468
|
+
**Executable Sizes (Windows):**
|
|
469
|
+
|
|
470
|
+
| Target | Executable | Size | Notes |
|
|
471
|
+
| ------ | -------------------- | ------ | --------------------------------- |
|
|
472
|
+
| Swift | `invaders_swift.exe` | 76 KB | Smallest native binary |
|
|
473
|
+
| Rust | `invaders_rust.exe` | 291 KB | Optimized, statically linked |
|
|
474
|
+
| Go | `invaders_go.exe` | 2.3 MB | Includes Go runtime |
|
|
475
|
+
| C++ | `invaders_cpp.exe` | 3.0 MB | Static linking with MinGW/pthread |
|
|
476
|
+
|
|
477
|
+
**Analysis:**
|
|
478
|
+
|
|
479
|
+
- **Python** generates the most compact code due to its concise syntax (no type annotations, no braces)
|
|
480
|
+
- **Rust** generates the most verbose code because of explicit ownership (`clone()`, `&mut`), type annotations, and safety features
|
|
481
|
+
- **Swift** produces the smallest native executable because it links dynamically to system libraries
|
|
482
|
+
- **Go** and **C++** have large executables due to static linking of their runtimes
|
|
483
|
+
- **JavaScript** runs on Node.js, so there's no standalone executable (interpreter required)
|
|
484
|
+
|
|
485
|
+
The ~11KB Ranger source compiles to native executables ranging from 76KB to 3MB, demonstrating the trade-offs between different target languages' runtime requirements and linking strategies.
|
|
486
|
+
|
|
487
|
+
**Known Issues:**
|
|
488
|
+
|
|
489
|
+
- Console rendering may have timing artifacts on some terminals
|
|
490
|
+
- Swift target requires macOS or Linux (not available on Windows)
|
|
491
|
+
|
|
492
|
+
### JavaScript ES6+ Parser
|
|
493
|
+
|
|
494
|
+
A comprehensive JavaScript ES6+ parser written entirely in Ranger, demonstrating the language's capability to build complex tools. The parser includes a full lexer, recursive descent parser, and pretty-printer.
|
|
495
|
+
|
|
496
|
+
**Features:**
|
|
497
|
+
|
|
498
|
+
- **Full ES6+ support** - Classes, arrow functions, async/await, generators, destructuring, spread operators, template literals
|
|
499
|
+
- **Pretty-printer** - Parses JavaScript and outputs formatted code
|
|
500
|
+
- **Comment preservation** - Line comments, block comments, and JSDoc are attached to AST nodes
|
|
501
|
+
- **Multi-target** - Parser compiles to JavaScript, Swift, Go, Python, etc.
|
|
502
|
+
|
|
503
|
+
**Quick Start (JavaScript):**
|
|
504
|
+
|
|
505
|
+
```bash
|
|
506
|
+
# Compile the parser
|
|
507
|
+
node bin/output.js gallery/js_parser/js_parser_main.rgr -o=js_parser.js -d=gallery/js_parser
|
|
508
|
+
|
|
509
|
+
# Parse and pretty-print a JavaScript file
|
|
510
|
+
node gallery/js_parser/js_parser.js -i input.js -o output.js
|
|
511
|
+
|
|
512
|
+
# Show AST structure
|
|
513
|
+
node gallery/js_parser/js_parser.js -i input.js --ast
|
|
514
|
+
```
|
|
515
|
+
|
|
516
|
+
**Quick Start (Swift):**
|
|
517
|
+
|
|
518
|
+
```bash
|
|
519
|
+
# Compile to Swift (from gallery/js_parser directory)
|
|
520
|
+
cd gallery/js_parser
|
|
521
|
+
node ../../bin/output.js js_parser_main.rgr -l=swift6 -o js_parser.swift
|
|
522
|
+
|
|
523
|
+
# Fix line endings and compile
|
|
524
|
+
sed -i '' $'s/\r$//' bin/js_parser_main.swift
|
|
525
|
+
swiftc -o js_parser_swift bin/js_parser_main.swift
|
|
526
|
+
|
|
527
|
+
# Run the native Swift binary
|
|
528
|
+
./js_parser_swift -i input.js --ast
|
|
529
|
+
./js_parser_swift -d
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
**Quick Start (C++ on Windows via WSL):**
|
|
533
|
+
|
|
534
|
+
```bash
|
|
535
|
+
# Compile to C++ (from Ranger root)
|
|
536
|
+
node bin/output.js gallery/js_parser/js_parser_main.rgr -l=cpp -d=gallery/js_parser -o=js_parser.cpp
|
|
537
|
+
|
|
538
|
+
# Cross-compile from WSL to Windows
|
|
539
|
+
wsl -d Ubuntu -- bash -c "
|
|
540
|
+
cd /mnt/c/path/to/Ranger/gallery/js_parser && \
|
|
541
|
+
sed -i 's/\r$//' js_parser.cpp && \
|
|
542
|
+
x86_64-w64-mingw32-g++-posix -std=c++17 -static -o js_parser_cpp.exe js_parser.cpp
|
|
543
|
+
"
|
|
544
|
+
|
|
545
|
+
# Run the native Windows binary
|
|
546
|
+
./js_parser_cpp.exe -i input.js --ast
|
|
547
|
+
./js_parser_cpp.exe -d
|
|
548
|
+
```
|
|
549
|
+
|
|
550
|
+
**Supported ES6+ Features:**
|
|
551
|
+
|
|
552
|
+
| Category | Features |
|
|
553
|
+
| ------------ | ---------------------------------------------------------------------- |
|
|
554
|
+
| Declarations | `let`, `const`, `var`, function declarations/expressions |
|
|
555
|
+
| Classes | `class`, `extends`, `constructor`, `static`, getters, `super` |
|
|
556
|
+
| Functions | Arrow functions (`=>`), async/await, generators (`function*`, `yield`) |
|
|
557
|
+
| Operators | Spread (`...`), rest parameters, destructuring (array/object) |
|
|
558
|
+
| Literals | Template literals with interpolation, computed property names |
|
|
559
|
+
| Control Flow | `for-of`, `for-in`, `while`, `if/else`, `switch`, `try/catch` |
|
|
560
|
+
|
|
561
|
+
**Performance Benchmark (vs popular parsers):**
|
|
562
|
+
|
|
563
|
+
The Ranger js_parser was benchmarked against popular JavaScript parsers. All parsers run in-process with warm-up:
|
|
564
|
+
|
|
565
|
+
| Rank | Parser | Large (17KB) | XL (35KB) |
|
|
566
|
+
| ------ | -------------------- | ------------ | ----------- |
|
|
567
|
+
| #1 | meriyah | 0.51 ms | 0.84 ms |
|
|
568
|
+
| **#2** | **Ranger js_parser** | **0.88 ms** | **1.39 ms** |
|
|
569
|
+
| #3 | acorn | 1.41 ms | 2.70 ms |
|
|
570
|
+
| #4 | esprima | 1.41 ms | 2.33 ms |
|
|
571
|
+
| #5 | espree (ESLint) | 1.58 ms | 3.47 ms |
|
|
572
|
+
| #6 | @babel/parser | 2.63 ms | 3.06 ms |
|
|
573
|
+
|
|
574
|
+
🥈 **Ranger ranks #2**, outperforming espree, acorn, esprima, and @babel/parser by **2-4x**.
|
|
575
|
+
|
|
576
|
+
```bash
|
|
577
|
+
# Run the benchmark yourself
|
|
578
|
+
cd gallery/js_parser/benchmark
|
|
579
|
+
npm install
|
|
580
|
+
npm run benchmark:large
|
|
581
|
+
```
|
|
582
|
+
|
|
583
|
+
See [gallery/js_parser/benchmark](gallery/js_parser/benchmark) for the full benchmark suite.
|
|
584
|
+
|
|
585
|
+
**Example transformation:**
|
|
586
|
+
|
|
587
|
+
```javascript
|
|
588
|
+
// Input
|
|
589
|
+
const greet = async (name) => {
|
|
590
|
+
const msg = `Hello, ${name}!`;
|
|
591
|
+
return msg;
|
|
592
|
+
};
|
|
593
|
+
|
|
594
|
+
// Output (pretty-printed)
|
|
595
|
+
const greet = async (name) => {
|
|
596
|
+
const msg = `Hello, ${name}!`;
|
|
597
|
+
return msg;
|
|
598
|
+
};
|
|
599
|
+
```
|
|
600
|
+
|
|
601
|
+
See [gallery/js_parser/README.md](gallery/js_parser/README.md) for complete documentation.
|
|
602
|
+
|
|
603
|
+
### Polyfill System
|
|
604
|
+
|
|
605
|
+
Ranger supports automatic polyfill generation for operators that require helper functions in the target language. Polyfills are utility functions, types, or constants that are automatically added to the generated output when an operator needs them.
|
|
606
|
+
|
|
607
|
+
Key features:
|
|
608
|
+
|
|
609
|
+
- **Automatic deduplication** - Polyfills are only generated once even if the operator is used multiple times
|
|
610
|
+
- **Per-target definitions** - Each target language can have its own polyfill implementation
|
|
611
|
+
- **Platform-specific code** - Polyfills can contain platform conditionals (e.g., `#[cfg(windows)]` in Rust)
|
|
612
|
+
|
|
613
|
+
Example: The `on_keypress` operator in Rust generates polyfill functions for raw terminal input handling that work on both Windows and Unix platforms.
|
|
614
|
+
|
|
615
|
+
See the `ai/INSTRUCTIONS.md` file for details on creating operators with polyfills.
|
|
616
|
+
|
|
617
|
+
### Unit Test Suite
|
|
618
|
+
|
|
619
|
+
A comprehensive test suite has been added using Vitest:
|
|
620
|
+
|
|
621
|
+
```bash
|
|
622
|
+
npm test # Run all tests
|
|
623
|
+
npm run test:es6 # JavaScript/ES6 tests only
|
|
624
|
+
npm run test:python # Python target tests
|
|
625
|
+
npm run test:go # Go target tests
|
|
626
|
+
npm run test:rust # Rust target tests
|
|
627
|
+
```
|
|
628
|
+
|
|
629
|
+
Test coverage includes:
|
|
630
|
+
|
|
631
|
+
- **ES6/JavaScript**: Full runtime tests (array operations, classes, inheritance, string operations, math, etc.)
|
|
632
|
+
- **Python**: Compilation and runtime tests with pytest
|
|
633
|
+
- **Go**: Compilation and runtime tests
|
|
634
|
+
- **Rust**: Compilation tests (runtime tests in progress)
|
|
635
|
+
|
|
636
|
+
### Known Issues
|
|
637
|
+
|
|
638
|
+
See `ISSUES.md` for a comprehensive list of known issues and their status. Key issues include:
|
|
639
|
+
|
|
640
|
+
- `toString` method name causes compiler crash (use `getSymbol` or similar instead)
|
|
641
|
+
- Go target has integer division type conversion issues
|
|
642
|
+
- Python target has inheritance constructor argument issues
|
|
643
|
+
|
|
644
|
+
### AI Documentation
|
|
645
|
+
|
|
646
|
+
The `ai/` folder contains documentation optimized for AI assistants:
|
|
647
|
+
|
|
648
|
+
- `INSTRUCTIONS.md` - Complete language guide
|
|
649
|
+
- `EXAMPLES.md` - Code examples for common patterns
|
|
650
|
+
- `GRAMMAR.md` - Formal grammar reference
|
|
651
|
+
- `QUICKREF.md` - Quick reference card
|
|
652
|
+
- `INTROSPECTION.md` - Compiler introspection API for IDE/AI integration
|
|
653
|
+
|
|
654
|
+
These files are also useful for human readers who want the shortest path to understanding Ranger without reading the whole README front to back.
|
|
655
|
+
|
|
656
|
+
### Compiler Introspection API (New)
|
|
657
|
+
|
|
658
|
+
The compiler now exposes powerful introspection capabilities for IDE integration and AI-assisted development:
|
|
659
|
+
|
|
660
|
+
**Position-Based Type Querying**
|
|
661
|
+
|
|
662
|
+
- Query what type is at any line/column position in source code
|
|
663
|
+
- Convert between line/column and byte offsets
|
|
664
|
+
- Find all typed nodes in a source file
|
|
665
|
+
|
|
666
|
+
**Class Structure Introspection**
|
|
667
|
+
|
|
668
|
+
- Check if classes have specific properties with optional type verification
|
|
669
|
+
- Check if classes have specific methods with optional return type verification
|
|
670
|
+
- Get all properties and methods with full signatures
|
|
671
|
+
- Track inheritance relationships
|
|
672
|
+
|
|
673
|
+
**Use Cases**
|
|
674
|
+
|
|
675
|
+
- IDE autocomplete and hover information
|
|
676
|
+
- AI code generation with type-safe suggestions
|
|
677
|
+
- Incremental compilation planning
|
|
678
|
+
- Codebase analysis and documentation
|
|
679
|
+
|
|
680
|
+
Example usage:
|
|
681
|
+
|
|
682
|
+
```typescript
|
|
683
|
+
import {
|
|
684
|
+
compileForIntrospection,
|
|
685
|
+
classHasProperty,
|
|
686
|
+
getTypeAtPosition,
|
|
687
|
+
} from "./tests/helpers/introspection";
|
|
688
|
+
|
|
689
|
+
// Compile source code
|
|
690
|
+
const result = await compileForIntrospection(sourceCode);
|
|
691
|
+
|
|
692
|
+
// Check class structure
|
|
693
|
+
if (classHasProperty(result, "Person", "name", "string")) {
|
|
694
|
+
// Safe to reference person.name
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
// Query type at cursor position (1-based line/column)
|
|
698
|
+
const typeInfo = getTypeAtPosition(result.rootNode, sourceCode, 5, 12);
|
|
699
|
+
console.log(typeInfo.evalTypeName); // e.g., "int"
|
|
700
|
+
```
|
|
701
|
+
|
|
702
|
+
See `ai/INTROSPECTION.md` for complete API documentation.
|
|
18
703
|
|
|
19
704
|
## Installing the compiler
|
|
20
705
|
|
|
21
|
-
|
|
706
|
+
Install the compiler from npm:
|
|
22
707
|
|
|
23
708
|
```
|
|
24
709
|
npm install -g ranger-compiler
|
|
@@ -27,11 +712,11 @@ To install the latest test version of the compiler using npm run
|
|
|
27
712
|
Running `ranger-compiler` without arguments shows available command-line options:
|
|
28
713
|
|
|
29
714
|
```
|
|
30
|
-
Ranger
|
|
31
|
-
|
|
32
|
-
Usage: <file>
|
|
715
|
+
Ranger Compiler v3.0.1
|
|
716
|
+
|
|
717
|
+
Usage: rgrc <file> [options] [flags]
|
|
33
718
|
Options: -<option>=<value>
|
|
34
|
-
|
|
719
|
+
-l=<value> Selected language, one of es6, go, scala, java7, swift3, swift6, kotlin, cpp, php, csharp, python, rust
|
|
35
720
|
-d=<value> output directory, default directory is "bin/"
|
|
36
721
|
-o=<value> output file, default is "output.<language>"
|
|
37
722
|
-classdoc=<value> write class documentation .md file
|
|
@@ -45,7 +730,8 @@ Flags: -<flag>
|
|
|
45
730
|
-typescript Writes JavaScript code with TypeScript annotations
|
|
46
731
|
-npm Write the package.json to the output directory
|
|
47
732
|
-nodecli Insert node.js command line header #!/usr/bin/env node to the beginning of the JavaScript file
|
|
48
|
-
-nodemodule Export
|
|
733
|
+
-nodemodule Export classes as CommonJS modules using module.exports (disables static main function)
|
|
734
|
+
-esm Export classes as ES6/ESM modules using export keyword (disables static main function)
|
|
49
735
|
-client the code is ment to be run in the client environment
|
|
50
736
|
-scalafiddle scalafiddle.io compatible output
|
|
51
737
|
-compiler recompile the compiler
|
|
@@ -54,95 +740,127 @@ Pragmas: (inside the source code files)
|
|
|
54
740
|
@noinfix(true) disable operator infix parsing and automatic type definition checking
|
|
55
741
|
```
|
|
56
742
|
|
|
743
|
+
### JavaScript Module Formats
|
|
744
|
+
|
|
745
|
+
The compiler supports three JavaScript module output formats:
|
|
746
|
+
|
|
747
|
+
| Flag | Format | Output | Use Case |
|
|
748
|
+
| ------------- | -------- | ------------------------- | -------------------------------- |
|
|
749
|
+
| (none) | Plain JS | No exports, runs `main()` | Standalone scripts |
|
|
750
|
+
| `-nodemodule` | CommonJS | `module.exports.X = X;` | Node.js require() |
|
|
751
|
+
| `-esm` | ES6/ESM | `export class X` | Modern ES modules, import/export |
|
|
752
|
+
|
|
753
|
+
**Examples:**
|
|
754
|
+
|
|
755
|
+
```bash
|
|
756
|
+
# Standalone JavaScript (runs main function)
|
|
757
|
+
node bin/output.js -es6 myfile.rgr -o=myfile.js
|
|
758
|
+
|
|
759
|
+
# CommonJS module (.cjs)
|
|
760
|
+
node bin/output.js -es6 -nodemodule myfile.rgr -o=myfile.cjs
|
|
761
|
+
|
|
762
|
+
# ES6/ESM module (.mjs)
|
|
763
|
+
node bin/output.js -es6 -esm myfile.rgr -o=myfile.mjs
|
|
764
|
+
```
|
|
765
|
+
|
|
766
|
+
**File Extensions:**
|
|
767
|
+
The compiler automatically detects JavaScript-related extensions (`.js`, `.ts`, `.mjs`, `.cjs`) and won't double-add them. You can safely specify the full filename with extension.
|
|
768
|
+
|
|
57
769
|
## Getting started with Hello World
|
|
58
770
|
|
|
59
|
-
Create file `hello.
|
|
60
|
-
|
|
771
|
+
Create file `hello.rgr`
|
|
772
|
+
|
|
773
|
+
```
|
|
61
774
|
class Hello {
|
|
62
|
-
|
|
775
|
+
sfn m@(main):void () {
|
|
63
776
|
print "Hello World"
|
|
64
777
|
}
|
|
65
778
|
}
|
|
66
779
|
|
|
67
780
|
```
|
|
68
|
-
|
|
781
|
+
|
|
782
|
+
Then compile it using `ranger-compiler` from the command line:
|
|
69
783
|
|
|
70
784
|
```
|
|
71
|
-
ranger-compiler hello.
|
|
785
|
+
ranger-compiler hello.rgr
|
|
72
786
|
```
|
|
73
787
|
|
|
74
|
-
The result will be
|
|
788
|
+
The result will be written to `bin/output.js` by default, or you can choose the output name explicitly:
|
|
789
|
+
|
|
790
|
+
```
|
|
791
|
+
ranger-compiler hello.rgr -o=hello.js
|
|
792
|
+
```
|
|
75
793
|
|
|
76
794
|
## Compiling using TypeScript
|
|
77
795
|
|
|
78
796
|
The compiler can be used from TypeScript, which makes possible to create new versions of the
|
|
79
797
|
compiler just using TypeScript.
|
|
80
798
|
|
|
81
|
-
Note: the example requires
|
|
799
|
+
Note: the example requires `Lang`, `stdlib`, `stdops`, and `JSON` to be loaded for the compiler. In this example they are loaded from the filesystem using `readFileSync`.
|
|
82
800
|
|
|
83
801
|
```typescript
|
|
84
802
|
// Notice this part of example is required:
|
|
85
|
-
addFile(
|
|
86
|
-
addFile(
|
|
87
|
-
addFile(
|
|
88
|
-
addFile(
|
|
803
|
+
addFile("Lang.rgr", fs.readFileSync("./libs/Lang.rgr", "utf8"));
|
|
804
|
+
addFile("stdlib.rgr", fs.readFileSync("./libs/stdlib.rgr", "utf8"));
|
|
805
|
+
addFile("stdops.clj", fs.readFileSync("./libs/stdops.clj", "utf8"));
|
|
806
|
+
addFile("JSON.clj", fs.readFileSync("./libs/JSON.clj", "utf8"));
|
|
89
807
|
```
|
|
90
808
|
|
|
91
809
|
The full compiler code:
|
|
92
810
|
|
|
93
811
|
```typescript
|
|
812
|
+
import * as R from "ranger-compiler";
|
|
813
|
+
import { CodeNode } from "ranger-compiler";
|
|
94
814
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
const compilerInput = new R.InputEnv()
|
|
99
|
-
compilerInput.use_real = false
|
|
815
|
+
const compilerInput = new R.InputEnv();
|
|
816
|
+
compilerInput.use_real = false;
|
|
100
817
|
|
|
101
818
|
// manually create a filesystem
|
|
102
|
-
const folder = new R.InputFSFolder()
|
|
103
|
-
const addFile = (name:string, contents:string) => {
|
|
104
|
-
const newFile = new R.InputFSFile()
|
|
105
|
-
newFile.name = name
|
|
106
|
-
newFile.data = contents
|
|
107
|
-
folder.files.push(
|
|
108
|
-
}
|
|
109
|
-
addFile(
|
|
110
|
-
|
|
819
|
+
const folder = new R.InputFSFolder();
|
|
820
|
+
const addFile = (name: string, contents: string) => {
|
|
821
|
+
const newFile = new R.InputFSFile();
|
|
822
|
+
newFile.name = name;
|
|
823
|
+
newFile.data = contents;
|
|
824
|
+
folder.files.push(newFile);
|
|
825
|
+
};
|
|
826
|
+
addFile(
|
|
827
|
+
"hello.clj",
|
|
828
|
+
`
|
|
111
829
|
class hello {
|
|
112
830
|
static fn main() {
|
|
113
831
|
print "Hello World"
|
|
114
832
|
}
|
|
115
833
|
}
|
|
116
|
-
`
|
|
834
|
+
`
|
|
835
|
+
);
|
|
117
836
|
|
|
118
837
|
// compiler requires language definition and libraries to work
|
|
119
|
-
const fs = require(
|
|
120
|
-
addFile(
|
|
121
|
-
addFile(
|
|
122
|
-
addFile(
|
|
123
|
-
addFile(
|
|
838
|
+
const fs = require("fs");
|
|
839
|
+
addFile("Lang.clj", fs.readFileSync("./libs/Lang.clj", "utf8"));
|
|
840
|
+
addFile("stdlib.clj", fs.readFileSync("./libs/stdlib.clj", "utf8"));
|
|
841
|
+
addFile("stdops.clj", fs.readFileSync("./libs/stdops.clj", "utf8"));
|
|
842
|
+
addFile("JSON.clj", fs.readFileSync("./libs/JSON.clj", "utf8"));
|
|
124
843
|
|
|
125
|
-
compilerInput.filesystem = folder
|
|
844
|
+
compilerInput.filesystem = folder;
|
|
126
845
|
|
|
127
846
|
// set compiler options -l=es6 -typescript
|
|
128
|
-
const params = new R.CmdParams()
|
|
847
|
+
const params = new R.CmdParams();
|
|
129
848
|
// target language is Go
|
|
130
|
-
params.params[
|
|
131
|
-
params.params[
|
|
132
|
-
params.values.push(
|
|
133
|
-
compilerInput.commandLine = params
|
|
849
|
+
params.params["l"] = "go";
|
|
850
|
+
params.params["o"] = "hello.go";
|
|
851
|
+
params.values.push("hello.clj");
|
|
852
|
+
compilerInput.commandLine = params;
|
|
134
853
|
|
|
135
854
|
// Run compiler
|
|
136
|
-
const vComp = new R.VirtualCompiler()
|
|
855
|
+
const vComp = new R.VirtualCompiler();
|
|
137
856
|
|
|
138
857
|
// Check results...
|
|
139
|
-
const res = await vComp.run(compilerInput)
|
|
858
|
+
const res = await vComp.run(compilerInput);
|
|
140
859
|
|
|
141
860
|
// browse through the target compiler file system
|
|
142
|
-
res.fileSystem.files.forEach(
|
|
143
|
-
|
|
144
|
-
})
|
|
145
|
-
|
|
861
|
+
res.fileSystem.files.forEach((file) => {
|
|
862
|
+
console.log(file.getCode());
|
|
863
|
+
});
|
|
146
864
|
```
|
|
147
865
|
|
|
148
866
|
## Switching to different target language
|
|
@@ -157,48 +875,49 @@ Currently the compiler supports at least following language versions:
|
|
|
157
875
|
- JavaScript ES2015
|
|
158
876
|
- PHP versions 5.4 and above
|
|
159
877
|
- C++ version C++14
|
|
160
|
-
- Java version 7
|
|
878
|
+
- Java version 7
|
|
161
879
|
- Swift version 3
|
|
162
880
|
- Golang version 1.8
|
|
163
|
-
- Scala 2.xx
|
|
164
|
-
- CSharp 7.0
|
|
881
|
+
- Scala 2.xx
|
|
882
|
+
- CSharp 7.0
|
|
883
|
+
- Python 3.x
|
|
884
|
+
- Rust (preliminary support)
|
|
165
885
|
|
|
166
886
|
However, it is possible to add support for older versions by implementing custom operators, which target to certain compiler flags.
|
|
167
887
|
|
|
168
888
|
Additionally, JavaScript has '-typescript' flag, which will add typescript annotations to the source file.
|
|
169
889
|
|
|
170
|
-
|
|
171
890
|
# Operators
|
|
172
891
|
|
|
173
892
|
Operators enable creating short, funtional commands like 'get' or 'push' that operate on certain, typed parameters. Whenever there is
|
|
174
|
-
need for some functionality it is woth considering whether it is best implemented using operator or a function or a class method. A
|
|
893
|
+
need for some functionality it is woth considering whether it is best implemented using operator or a function or a class method. A
|
|
175
894
|
simple operator definition would be `M_PI` which is defined in the Compilers internal Lang.clj file as
|
|
176
895
|
|
|
177
896
|
```
|
|
178
897
|
M_PI mathPi:double () {
|
|
179
898
|
templates {
|
|
180
899
|
es6 ("Math.PI")
|
|
181
|
-
go ( "math.Pi" (imp "math"))
|
|
182
|
-
swift3 ( "Double.pi" (imp "Foundation"))
|
|
183
|
-
java7 ( "Math.PI" (imp "java.lang.Math"))
|
|
184
|
-
php ("pi()")
|
|
185
|
-
cpp ("M_PI" (imp "<math.h>"))
|
|
900
|
+
go ( "math.Pi" (imp "math"))
|
|
901
|
+
swift3 ( "Double.pi" (imp "Foundation"))
|
|
902
|
+
java7 ( "Math.PI" (imp "java.lang.Math"))
|
|
903
|
+
php ("pi()")
|
|
904
|
+
cpp ("M_PI" (imp "<math.h>"))
|
|
186
905
|
}
|
|
187
906
|
}
|
|
188
907
|
```
|
|
189
908
|
|
|
190
|
-
Oops! Looks like C# defintion is missing! It should be `Math.PI` and it requires `System`. We can add that easily to Lang.clj
|
|
909
|
+
Oops! Looks like C# defintion is missing! It should be `Math.PI` and it requires `System`. We can add that easily to Lang.clj
|
|
191
910
|
|
|
192
911
|
```
|
|
193
912
|
M_PI mathPi:double () {
|
|
194
913
|
templates {
|
|
195
914
|
es6 ("Math.PI")
|
|
196
|
-
go ( "math.Pi" (imp "math"))
|
|
197
|
-
swift3 ( "Double.pi" (imp "Foundation"))
|
|
198
|
-
java7 ( "Math.PI" (imp "java.lang.Math"))
|
|
199
|
-
php ("pi()")
|
|
200
|
-
cpp ("M_PI" (imp "<math.h>"))
|
|
201
|
-
csharp ("Math.PI" (imp "System"))
|
|
915
|
+
go ( "math.Pi" (imp "math"))
|
|
916
|
+
swift3 ( "Double.pi" (imp "Foundation"))
|
|
917
|
+
java7 ( "Math.PI" (imp "java.lang.Math"))
|
|
918
|
+
php ("pi()")
|
|
919
|
+
cpp ("M_PI" (imp "<math.h>"))
|
|
920
|
+
csharp ("Math.PI" (imp "System"))
|
|
202
921
|
}
|
|
203
922
|
}
|
|
204
923
|
```
|
|
@@ -211,9 +930,16 @@ For a quick reference of available basic operators see [Operators doc](operators
|
|
|
211
930
|
|
|
212
931
|
# Plugins
|
|
213
932
|
|
|
214
|
-
Compiling
|
|
933
|
+
Compiling as CommonJS module:
|
|
934
|
+
|
|
215
935
|
```
|
|
216
|
-
ranger-compiler hello.clj -npm
|
|
936
|
+
ranger-compiler hello.clj -npm -nodemodule
|
|
937
|
+
```
|
|
938
|
+
|
|
939
|
+
Compiling as ES6/ESM module:
|
|
940
|
+
|
|
941
|
+
```
|
|
942
|
+
ranger-compiler hello.clj -npm -esm
|
|
217
943
|
```
|
|
218
944
|
|
|
219
945
|
Example
|
|
@@ -233,13 +959,12 @@ class Plugin {
|
|
|
233
959
|
fn features:[string] () {
|
|
234
960
|
return ([] "postprocess")
|
|
235
961
|
}
|
|
236
|
-
fn postprocess (root:CodeNode ctx:RangerAppWriterContext wr:CodeWriter) {
|
|
962
|
+
fn postprocess (root:CodeNode ctx:RangerAppWriterContext wr:CodeWriter) {
|
|
237
963
|
print "*** plugin postprocess was called ***"
|
|
238
964
|
}
|
|
239
965
|
}
|
|
240
966
|
```
|
|
241
967
|
|
|
242
|
-
|
|
243
968
|
# Notes about the syntax
|
|
244
969
|
|
|
245
970
|
Ranger syntax is originally based on Lisp -language syntax and most operators will use prefix notation. However, the Ranger modifies
|
|
@@ -254,14 +979,15 @@ class Hello {
|
|
|
254
979
|
print "x < 10"
|
|
255
980
|
} {
|
|
256
981
|
print "x >= 10"
|
|
257
|
-
}
|
|
982
|
+
}
|
|
258
983
|
}
|
|
259
984
|
}
|
|
260
985
|
```
|
|
261
986
|
|
|
262
987
|
However, when you go deeper in the expression you may have to include the parenthesis, for example when invoking object you have to write
|
|
988
|
+
|
|
263
989
|
```
|
|
264
|
-
def obj (new Hello)
|
|
990
|
+
def obj (new Hello)
|
|
265
991
|
```
|
|
266
992
|
|
|
267
993
|
For most common mathematical symbols and boolean operators infix notation can be used and they are automatically converted to lisp expressions.
|
|
@@ -270,41 +996,45 @@ Thus you can write expressions such as `(x + y * z)` instead of `(+ x (* y z))`
|
|
|
270
996
|
```
|
|
271
997
|
def x 100
|
|
272
998
|
def y 200
|
|
273
|
-
def z ( x + y * 10)
|
|
999
|
+
def z ( x + y * 10)
|
|
274
1000
|
if ( x < 20 || y == 0 ) {
|
|
275
1001
|
|
|
276
1002
|
}
|
|
277
1003
|
```
|
|
1004
|
+
|
|
278
1005
|
The assigment operator is also automatically prefixed from infix notation so you can say
|
|
1006
|
+
|
|
279
1007
|
```
|
|
280
1008
|
x = y
|
|
281
1009
|
```
|
|
1010
|
+
|
|
282
1011
|
Instead of common lisp syntax `(= x y)`
|
|
283
1012
|
|
|
284
1013
|
## Main function
|
|
285
1014
|
|
|
286
1015
|
Each file can have a static main function, which is executed as the main program.
|
|
287
1016
|
|
|
288
|
-
```
|
|
1017
|
+
```
|
|
289
1018
|
class Hello {
|
|
290
1019
|
static fn main() {
|
|
291
|
-
}
|
|
1020
|
+
}
|
|
292
1021
|
}
|
|
293
1022
|
|
|
294
1023
|
```
|
|
1024
|
+
|
|
295
1025
|
This is a static function which marks the start of execution for the program.
|
|
296
1026
|
|
|
297
1027
|
## Functions and Static functions
|
|
298
1028
|
|
|
299
|
-
```
|
|
1029
|
+
```
|
|
300
1030
|
class Hello {
|
|
301
1031
|
fn SomeNonStaticFn () {
|
|
302
|
-
}
|
|
1032
|
+
}
|
|
303
1033
|
sfn SomeStaticFn () {
|
|
304
1034
|
; static function which instantiates Hello and calls non-static
|
|
305
1035
|
def o (new Hello)
|
|
306
1036
|
o.SomeNonStaticFn()
|
|
307
|
-
}
|
|
1037
|
+
}
|
|
308
1038
|
}
|
|
309
1039
|
|
|
310
1040
|
```
|
|
@@ -319,8 +1049,8 @@ Hello.SomeStaticFn()
|
|
|
319
1049
|
|
|
320
1050
|
Function not inferred or declared as `void` should always return value with `return` statement.
|
|
321
1051
|
|
|
322
|
-
|
|
323
1052
|
## Comments
|
|
1053
|
+
|
|
324
1054
|
```
|
|
325
1055
|
; here is a comment
|
|
326
1056
|
class Hello {
|
|
@@ -346,18 +1076,21 @@ Basic primitive types are
|
|
|
346
1076
|
- boolean
|
|
347
1077
|
- string
|
|
348
1078
|
- double
|
|
349
|
-
- char
|
|
1079
|
+
- char
|
|
350
1080
|
- charbuffer
|
|
351
1081
|
|
|
352
1082
|
Type of function returning nothing is
|
|
1083
|
+
|
|
353
1084
|
- void
|
|
354
1085
|
|
|
355
1086
|
Type which can be used as variable types, but require signature are
|
|
1087
|
+
|
|
356
1088
|
- Arrays
|
|
357
1089
|
- Hashes
|
|
358
1090
|
- Anonymous functions
|
|
359
1091
|
|
|
360
1092
|
Types which require type declaration are
|
|
1093
|
+
|
|
361
1094
|
- Enum
|
|
362
1095
|
- class
|
|
363
1096
|
- systemclass
|
|
@@ -375,9 +1108,39 @@ def long_string "
|
|
|
375
1108
|
"
|
|
376
1109
|
```
|
|
377
1110
|
|
|
1111
|
+
## String Operations
|
|
1112
|
+
|
|
1113
|
+
Ranger provides a comprehensive set of string manipulation operators. Here are some commonly used ones:
|
|
1114
|
+
|
|
1115
|
+
```
|
|
1116
|
+
def text "Hello World"
|
|
1117
|
+
|
|
1118
|
+
; Length and substring operations
|
|
1119
|
+
def len (strlen text) ; returns 11
|
|
1120
|
+
def sub (substring text 0 5) ; returns "Hello"
|
|
1121
|
+
|
|
1122
|
+
; Case conversion
|
|
1123
|
+
def lower (to_lowercase text) ; returns "hello world"
|
|
1124
|
+
def upper (to_uppercase text) ; returns "HELLO WORLD"
|
|
1125
|
+
|
|
1126
|
+
; Search operations
|
|
1127
|
+
def idx (indexOf text "World") ; returns 6
|
|
1128
|
+
def hasWorld (contains text "World") ; returns true
|
|
1129
|
+
def starts (startsWith text "Hello") ; returns true
|
|
1130
|
+
def ends (endsWith text "World") ; returns true
|
|
1131
|
+
|
|
1132
|
+
; String manipulation
|
|
1133
|
+
def replaced (replace text "World" "Ranger") ; returns "Hello Ranger"
|
|
1134
|
+
def parts (strsplit text " ") ; returns ["Hello", "World"]
|
|
1135
|
+
def trimmed (trim " hello ") ; returns "hello"
|
|
1136
|
+
```
|
|
1137
|
+
|
|
1138
|
+
For the complete list of string operators, see [Operators doc](operators.md).
|
|
1139
|
+
|
|
378
1140
|
## Enums
|
|
379
1141
|
|
|
380
1142
|
Enums will be compiled to type `int` but are type checked by the Ranger preprosessor
|
|
1143
|
+
|
|
381
1144
|
```
|
|
382
1145
|
Enum LineJoin (
|
|
383
1146
|
Undefined
|
|
@@ -393,6 +1156,7 @@ class foo {
|
|
|
393
1156
|
## Arrays and Hashes
|
|
394
1157
|
|
|
395
1158
|
Arrays and hashes are automatically initialized and are ready to be used after their declaration
|
|
1159
|
+
|
|
396
1160
|
```
|
|
397
1161
|
def list:[string]
|
|
398
1162
|
def usedKeywords:[string:string]
|
|
@@ -402,20 +1166,27 @@ def classMap:[string:myClass]
|
|
|
402
1166
|
### Operators for hashes
|
|
403
1167
|
|
|
404
1168
|
if we have a hashmap
|
|
1169
|
+
|
|
405
1170
|
```
|
|
406
1171
|
def someMap:[string:string]
|
|
407
1172
|
```
|
|
1173
|
+
|
|
408
1174
|
Operator `set` can be used to set key/value pair
|
|
1175
|
+
|
|
409
1176
|
```
|
|
410
1177
|
set someMap "foo" "bar"
|
|
411
1178
|
```
|
|
1179
|
+
|
|
412
1180
|
Operator `has` can be used to check if a key exists in the hash
|
|
1181
|
+
|
|
413
1182
|
```
|
|
414
1183
|
if (has someMap "a key") {
|
|
415
|
-
|
|
1184
|
+
|
|
416
1185
|
}
|
|
417
1186
|
```
|
|
1187
|
+
|
|
418
1188
|
Get is used to read the value associated with a key. The result is `@(optional)`
|
|
1189
|
+
|
|
419
1190
|
```
|
|
420
1191
|
(get someMap "foo")
|
|
421
1192
|
```
|
|
@@ -423,6 +1194,7 @@ Get is used to read the value associated with a key. The result is `@(optional)`
|
|
|
423
1194
|
## Anonymous functions / lambdas
|
|
424
1195
|
|
|
425
1196
|
Anonymous function type declaration is automatically inferred
|
|
1197
|
+
|
|
426
1198
|
```
|
|
427
1199
|
def name "foo"
|
|
428
1200
|
def myFilter (fn:boolean (param:string) {
|
|
@@ -451,9 +1223,7 @@ this.foo({
|
|
|
451
1223
|
})
|
|
452
1224
|
```
|
|
453
1225
|
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
# Automatically infixed math support
|
|
1226
|
+
# Automatically infixed math support
|
|
457
1227
|
|
|
458
1228
|
It is easy to define new mathematical operations in the Lang.clj file or in modules. However, some mathematical operations are automatically infixed
|
|
459
1229
|
for easier usage. Thus, instead of using common lips notation `(* 4 10)` you can use easier to read infixed `4 * 10` -syntax
|
|
@@ -484,7 +1254,6 @@ a >= b
|
|
|
484
1254
|
a != b
|
|
485
1255
|
```
|
|
486
1256
|
|
|
487
|
-
|
|
488
1257
|
# Common set of Operators and the Grammar file
|
|
489
1258
|
|
|
490
1259
|
The file `Lang.clj` is used by the compiler for the common set of operators and compilation rules. The
|
|
@@ -501,13 +1270,57 @@ modifications, rather it describes common set of rules used and thus should be e
|
|
|
501
1270
|
The file has couple of sections, but the `reserved_words` and `commands`. The Reserved words section declares (surprise!)
|
|
502
1271
|
the reserved words and their transformation. This is required because for example in Go the word `map` is a keyword and can
|
|
503
1272
|
not be used unless it is conveted to some other name, for example to `FnMap`.
|
|
1273
|
+
|
|
504
1274
|
```
|
|
505
1275
|
reserved_words {
|
|
506
|
-
|
|
507
|
-
|
|
1276
|
+
* {
|
|
1277
|
+
map FnMap
|
|
1278
|
+
forEach forEachItem
|
|
1279
|
+
self _self
|
|
1280
|
+
func _func
|
|
1281
|
+
}
|
|
1282
|
+
cpp {
|
|
1283
|
+
operator _operator
|
|
1284
|
+
static _static
|
|
1285
|
+
union _union
|
|
1286
|
+
bool _bool
|
|
1287
|
+
ref _ref
|
|
1288
|
+
class _class
|
|
1289
|
+
new _new
|
|
1290
|
+
delete _delete
|
|
1291
|
+
template _template
|
|
1292
|
+
namespace _namespace
|
|
1293
|
+
virtual _virtual
|
|
1294
|
+
public _public
|
|
1295
|
+
private _private
|
|
1296
|
+
protected _protected
|
|
1297
|
+
}
|
|
1298
|
+
go {
|
|
1299
|
+
type _type
|
|
1300
|
+
}
|
|
1301
|
+
rust {
|
|
1302
|
+
type r#type
|
|
1303
|
+
static r#static
|
|
1304
|
+
ref r#ref
|
|
1305
|
+
union r#union
|
|
1306
|
+
bool r#bool
|
|
1307
|
+
}
|
|
1308
|
+
swift3 {
|
|
1309
|
+
operator _operator
|
|
1310
|
+
static _static
|
|
1311
|
+
init _init
|
|
1312
|
+
}
|
|
1313
|
+
swift6 {
|
|
1314
|
+
operator _operator
|
|
1315
|
+
static _static
|
|
1316
|
+
init _init
|
|
1317
|
+
}
|
|
508
1318
|
}
|
|
509
1319
|
```
|
|
510
|
-
|
|
1320
|
+
|
|
1321
|
+
The `*` section defines global mappings that apply to all target languages. Language-specific sections (like `cpp`, `rust`, `go`, `swift3`, `swift6`) define additional reserved word mappings for that particular target. For Rust, the `r#` prefix is used to escape keywords (raw identifiers).
|
|
1322
|
+
|
|
1323
|
+
What the result should be is of course highly opinionated. In this example, the line `map FnMap` means that if possible the
|
|
511
1324
|
compiler will transform anything named `map` to `fnMap` if possible. If transformation is not possible, compiler error is
|
|
512
1325
|
generated.
|
|
513
1326
|
|
|
@@ -516,16 +1329,17 @@ and return values and rules on how they should be compiled into the target langu
|
|
|
516
1329
|
and possible macros or helper function which should be created if the operator is used.
|
|
517
1330
|
|
|
518
1331
|
Example of simple operator is `(M_PI)` which will return double value of mathematical symbol "pi".
|
|
1332
|
+
|
|
519
1333
|
```
|
|
520
1334
|
commands {
|
|
521
1335
|
M_PI mathPi:double () {
|
|
522
1336
|
templates {
|
|
523
1337
|
es6 ("Math.PI")
|
|
524
|
-
go ( "math.Pi" (imp "math"))
|
|
525
|
-
swift3 ( "Double.pi" (imp "Foundation"))
|
|
526
|
-
java7 ( "Math.PI" (imp "java.lang.Math"))
|
|
527
|
-
php ("pi()")
|
|
528
|
-
cpp ("M_PI" (imp "<math.h>"))
|
|
1338
|
+
go ( "math.Pi" (imp "math"))
|
|
1339
|
+
swift3 ( "Double.pi" (imp "Foundation"))
|
|
1340
|
+
java7 ( "Math.PI" (imp "java.lang.Math"))
|
|
1341
|
+
php ("pi()")
|
|
1342
|
+
cpp ("M_PI" (imp "<math.h>"))
|
|
529
1343
|
}
|
|
530
1344
|
}
|
|
531
1345
|
...
|
|
@@ -534,15 +1348,15 @@ Example of simple operator is `(M_PI)` which will return double value of mathema
|
|
|
534
1348
|
Most operators are simple, but some require creating custom macros, helpoer functions and some of them are so complex
|
|
535
1349
|
that they may be implemented in the compiler core.
|
|
536
1350
|
|
|
537
|
-
|
|
538
1351
|
# Modules, classes and operators
|
|
539
1352
|
|
|
540
1353
|
The basic unit of the program is class. The functions of classes can not be overloaded at the moment, which means that you can not
|
|
541
|
-
have two functions with different parameters or different return values.
|
|
1354
|
+
have two functions with different parameters or different return values.
|
|
1355
|
+
|
|
1356
|
+
Each source file can import other files using `Import` command.
|
|
542
1357
|
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
Import "Vec2.clj"
|
|
1358
|
+
```
|
|
1359
|
+
Import "Vec2.clj"
|
|
546
1360
|
|
|
547
1361
|
class vectorTest {
|
|
548
1362
|
fn testVectors () {
|
|
@@ -553,7 +1367,7 @@ class vectorTest {
|
|
|
553
1367
|
|
|
554
1368
|
## Class declaration
|
|
555
1369
|
|
|
556
|
-
```
|
|
1370
|
+
```
|
|
557
1371
|
class fatherClass {
|
|
558
1372
|
def msg "Hello "
|
|
559
1373
|
fn foo:string ( txt:string ) {
|
|
@@ -575,7 +1389,7 @@ class mainProgram {
|
|
|
575
1389
|
|
|
576
1390
|
## Class constructor
|
|
577
1391
|
|
|
578
|
-
```
|
|
1392
|
+
```
|
|
579
1393
|
class myClass {
|
|
580
1394
|
def name:string ""
|
|
581
1395
|
Constructor (n:string) {
|
|
@@ -585,13 +1399,16 @@ class myClass {
|
|
|
585
1399
|
```
|
|
586
1400
|
|
|
587
1401
|
Notes:
|
|
588
|
-
|
|
1402
|
+
|
|
1403
|
+
1. currently only a single variant of the constructor is possible.
|
|
589
1404
|
2. as of this writing calling the parent class constructor does not work properly
|
|
590
1405
|
|
|
591
1406
|
## Class invocation
|
|
1407
|
+
|
|
592
1408
|
```
|
|
593
1409
|
def obj (new myClass ("name"))
|
|
594
1410
|
```
|
|
1411
|
+
|
|
595
1412
|
classes without constructor can be invocated without arguments
|
|
596
1413
|
|
|
597
1414
|
```
|
|
@@ -608,7 +1425,7 @@ Extension can
|
|
|
608
1425
|
- add new functions to the class
|
|
609
1426
|
- add new member variables to the class
|
|
610
1427
|
|
|
611
|
-
```
|
|
1428
|
+
```
|
|
612
1429
|
extension childClass {
|
|
613
1430
|
def name:string ""
|
|
614
1431
|
fn bar:string ( txt:string ) {
|
|
@@ -625,26 +1442,28 @@ non-nullable value should cause compiler error. In Ranger any variable which is
|
|
|
625
1442
|
This corresponds to Swift `?` optional type.
|
|
626
1443
|
|
|
627
1444
|
You can also declare variables optional using @optional annotation
|
|
1445
|
+
|
|
628
1446
|
```
|
|
629
1447
|
def item@(optional):myClass
|
|
630
1448
|
```
|
|
631
1449
|
|
|
632
1450
|
Some operators also return optional values, for example `(get <hash> <key>)` operator is returning always optional value. To use
|
|
633
1451
|
the value you must use `(unwrap <value>)` operator
|
|
1452
|
+
|
|
634
1453
|
```
|
|
635
1454
|
def strMap:[string:string]
|
|
636
1455
|
def str (get strMap "myKey")
|
|
637
1456
|
if(!null? str) {
|
|
638
1457
|
print (unwrap str)
|
|
639
1458
|
}
|
|
640
|
-
```
|
|
1459
|
+
```
|
|
641
1460
|
|
|
642
|
-
**Warning
|
|
1461
|
+
**Warning\*** currently optinal variables in Ranger are not "safe" in the sense the language makes sure that you can not make
|
|
643
1462
|
programming errors - it is possible to create programming mistake by using a variable which automatically unwrapped. The plan
|
|
644
|
-
is to try to make them safer in the future, and options are considered how to enable them
|
|
1463
|
+
is to try to make them safer in the future, and options are considered how to enable them
|
|
645
1464
|
|
|
646
1465
|
Another warning: Ranger does not protect you from mistakes when automatically unwrapping long reference chains like
|
|
647
|
-
`obj.property.subProperty.foo` where `property` and `subProperty ` are optional variables.
|
|
1466
|
+
`obj.property.subProperty.foo` where `property` and `subProperty ` are optional variables.
|
|
648
1467
|
|
|
649
1468
|
## Control flow
|
|
650
1469
|
|
|
@@ -661,7 +1480,7 @@ if ( x < 10 ) {
|
|
|
661
1480
|
}
|
|
662
1481
|
```
|
|
663
1482
|
|
|
664
|
-
### switch - case
|
|
1483
|
+
### switch - case
|
|
665
1484
|
|
|
666
1485
|
Note: currently case statement does not support multiple matching values, it is planned to add support for that later.
|
|
667
1486
|
|
|
@@ -683,15 +1502,18 @@ switch name {
|
|
|
683
1502
|
## Loops
|
|
684
1503
|
|
|
685
1504
|
### for -loop
|
|
1505
|
+
|
|
686
1506
|
```
|
|
687
1507
|
def list:[string]
|
|
688
1508
|
for list s:string i {
|
|
689
1509
|
print s
|
|
690
1510
|
}
|
|
691
1511
|
```
|
|
1512
|
+
|
|
692
1513
|
You can use `break` and `continue` to control the for -loop.
|
|
693
1514
|
|
|
694
1515
|
### while -loop
|
|
1516
|
+
|
|
695
1517
|
```
|
|
696
1518
|
def cnt 10
|
|
697
1519
|
while (cnt > 0 ) {
|
|
@@ -708,6 +1530,7 @@ using macros. Together with `systemclass` they allow the system to integrate to
|
|
|
708
1530
|
native API's.
|
|
709
1531
|
|
|
710
1532
|
Operators allow type matching against
|
|
1533
|
+
|
|
711
1534
|
- defined primitive types
|
|
712
1535
|
- defined classes
|
|
713
1536
|
- Enums
|
|
@@ -749,17 +1572,17 @@ operators {
|
|
|
749
1572
|
* base:Mat2 ( a:Mat2 b:Mat2) {
|
|
750
1573
|
templates {
|
|
751
1574
|
* @macro(true) ( (e 1 ) ".multiply(" (e 2) " )" )
|
|
752
|
-
}
|
|
1575
|
+
}
|
|
753
1576
|
}
|
|
754
1577
|
}
|
|
755
1578
|
|
|
756
1579
|
```
|
|
757
|
-
The `* @macro(true)` means that we target all languages and this is a macro, not actual target language construct.
|
|
758
1580
|
|
|
1581
|
+
The `* @macro(true)` means that we target all languages and this is a macro, not actual target language construct.
|
|
759
1582
|
|
|
760
1583
|
## Custom operators and System classes
|
|
761
1584
|
|
|
762
|
-
To integrate with the target languages running environment,
|
|
1585
|
+
To integrate with the target languages running environment, Ranger modules can declare `systemclass` which can be used
|
|
763
1586
|
together with the code.
|
|
764
1587
|
|
|
765
1588
|
```
|
|
@@ -771,12 +1594,12 @@ operators {
|
|
|
771
1594
|
find base:DOMElement ( id:string) {
|
|
772
1595
|
templates {
|
|
773
1596
|
es6 ("document.getElementById( " (e 1) " )")
|
|
774
|
-
}
|
|
1597
|
+
}
|
|
775
1598
|
}
|
|
776
1599
|
setAttribute _:void ( elem:DOMElement name:string value:string) {
|
|
777
1600
|
templates {
|
|
778
1601
|
es6 ( (e 1) ".setAttribute(" (e 2) ", " (e 3) ")" )
|
|
779
|
-
}
|
|
1602
|
+
}
|
|
780
1603
|
}
|
|
781
1604
|
}
|
|
782
1605
|
|
|
@@ -788,25 +1611,25 @@ class tester {
|
|
|
788
1611
|
}
|
|
789
1612
|
```
|
|
790
1613
|
|
|
791
|
-
|
|
792
1614
|
Note: Definition of system classes will be revisited in near future and there will be potentially small changes to it.
|
|
793
1615
|
|
|
794
1616
|
## Unions of system classes
|
|
795
1617
|
|
|
796
|
-
Sometimes the system class can be of union type. This means that the traget language can accept multiple types in place of
|
|
1618
|
+
Sometimes the system class can be of union type. This means that the traget language can accept multiple types in place of
|
|
797
1619
|
a single type.
|
|
798
1620
|
|
|
799
1621
|
```
|
|
800
1622
|
systemunion DOMElementUnion ( DOMElement string )
|
|
801
1623
|
```
|
|
802
|
-
The you can create operator which accepts either `DOMElement` or `string` and reduces that to a single type.
|
|
803
1624
|
|
|
1625
|
+
The you can create operator which accepts either `DOMElement` or `string` and reduces that to a single type.
|
|
804
1626
|
|
|
805
1627
|
## Traits
|
|
806
1628
|
|
|
807
1629
|
Traits are like extensions, which can be plugged into several classes using `does` keyword.
|
|
808
1630
|
|
|
809
|
-
Traits
|
|
1631
|
+
Traits
|
|
1632
|
+
|
|
810
1633
|
```
|
|
811
1634
|
trait bar {
|
|
812
1635
|
fn hello() {
|
|
@@ -814,7 +1637,7 @@ trait bar {
|
|
|
814
1637
|
}
|
|
815
1638
|
}
|
|
816
1639
|
|
|
817
|
-
; foo implements "bar" trait
|
|
1640
|
+
; foo implements "bar" trait
|
|
818
1641
|
class foo {
|
|
819
1642
|
does bar
|
|
820
1643
|
}
|
|
@@ -855,14 +1678,14 @@ class Main {
|
|
|
855
1678
|
def n (coll.map({
|
|
856
1679
|
return ("item = " + item)
|
|
857
1680
|
}))
|
|
858
|
-
print (join n.items " ")
|
|
1681
|
+
print (join n.items " ")
|
|
859
1682
|
}
|
|
860
1683
|
sfn hello@(main):void () {
|
|
861
1684
|
def hello (new Main ())
|
|
862
1685
|
hello.testCollection()
|
|
863
|
-
}
|
|
1686
|
+
}
|
|
864
1687
|
}
|
|
865
|
-
```
|
|
1688
|
+
```
|
|
866
1689
|
|
|
867
1690
|
## Variable definitions
|
|
868
1691
|
|
|
@@ -879,15 +1702,15 @@ def strObjMap:[string:someClass] ; map of string -> object of type someClass
|
|
|
879
1702
|
|
|
880
1703
|
# Advanced topics
|
|
881
1704
|
|
|
882
|
-
|
|
883
1705
|
## Compiling a new version of the compiler
|
|
884
1706
|
|
|
885
1707
|
Then run command
|
|
1708
|
+
|
|
886
1709
|
```
|
|
887
1710
|
ranger-compiler -compiler -copysrc
|
|
888
1711
|
```
|
|
889
|
-
The result will be written to directory `bin/ng_Compiler.js`.
|
|
890
1712
|
|
|
1713
|
+
The result will be written to directory `bin/ng_Compiler.js`.
|
|
891
1714
|
|
|
892
1715
|
# Annotations
|
|
893
1716
|
|
|
@@ -917,7 +1740,7 @@ trait GenericCollection @paras(T V) {
|
|
|
917
1740
|
class StringCollection {
|
|
918
1741
|
does GenericCollection @params(string StringCollection)
|
|
919
1742
|
}
|
|
920
|
-
```
|
|
1743
|
+
```
|
|
921
1744
|
|
|
922
1745
|
## def variableName@(optional)
|
|
923
1746
|
|
|
@@ -943,4 +1766,4 @@ the lifetime calculations.
|
|
|
943
1766
|
## def variableName@(temp)
|
|
944
1767
|
|
|
945
1768
|
@(temp) annotation can be used to note the compiler that it should not worry about freeing the variable, in case the
|
|
946
|
-
target language has option to release the variable.
|
|
1769
|
+
target language has option to release the variable.
|