ranger-compiler 2.1.69 → 3.0.3
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 +103 -0
- package/README.md +991 -96
- 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/{bin/output.js → dist/rgrc.js} +15377 -7935
- package/dist/stdops.rgr +168 -0
- package/package.json +196 -38
- 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/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 -800
- 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 -1042
- 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/api.js.map +0 -1
- package/dist/bin/compiler.d.ts +0 -1638
- package/dist/bin/compiler.js +0 -32444
- package/dist/bin/compiler.js.map +0 -1
- 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/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.3** | 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,24 +740,128 @@ 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
|
+
```
|
|
793
|
+
|
|
794
|
+
## Compiling using TypeScript
|
|
795
|
+
|
|
796
|
+
The compiler can be used from TypeScript, which makes possible to create new versions of the
|
|
797
|
+
compiler just using TypeScript.
|
|
798
|
+
|
|
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`.
|
|
800
|
+
|
|
801
|
+
```typescript
|
|
802
|
+
// Notice this part of example is required:
|
|
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"));
|
|
807
|
+
```
|
|
808
|
+
|
|
809
|
+
The full compiler code:
|
|
810
|
+
|
|
811
|
+
```typescript
|
|
812
|
+
import * as R from "ranger-compiler";
|
|
813
|
+
import { CodeNode } from "ranger-compiler";
|
|
814
|
+
|
|
815
|
+
const compilerInput = new R.InputEnv();
|
|
816
|
+
compilerInput.use_real = false;
|
|
817
|
+
|
|
818
|
+
// manually create a filesystem
|
|
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
|
+
`
|
|
829
|
+
class hello {
|
|
830
|
+
static fn main() {
|
|
831
|
+
print "Hello World"
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
`
|
|
835
|
+
);
|
|
836
|
+
|
|
837
|
+
// compiler requires language definition and libraries to work
|
|
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"));
|
|
843
|
+
|
|
844
|
+
compilerInput.filesystem = folder;
|
|
845
|
+
|
|
846
|
+
// set compiler options -l=es6 -typescript
|
|
847
|
+
const params = new R.CmdParams();
|
|
848
|
+
// target language is Go
|
|
849
|
+
params.params["l"] = "go";
|
|
850
|
+
params.params["o"] = "hello.go";
|
|
851
|
+
params.values.push("hello.clj");
|
|
852
|
+
compilerInput.commandLine = params;
|
|
853
|
+
|
|
854
|
+
// Run compiler
|
|
855
|
+
const vComp = new R.VirtualCompiler();
|
|
856
|
+
|
|
857
|
+
// Check results...
|
|
858
|
+
const res = await vComp.run(compilerInput);
|
|
859
|
+
|
|
860
|
+
// browse through the target compiler file system
|
|
861
|
+
res.fileSystem.files.forEach((file) => {
|
|
862
|
+
console.log(file.getCode());
|
|
863
|
+
});
|
|
864
|
+
```
|
|
75
865
|
|
|
76
866
|
## Switching to different target language
|
|
77
867
|
|
|
@@ -85,48 +875,49 @@ Currently the compiler supports at least following language versions:
|
|
|
85
875
|
- JavaScript ES2015
|
|
86
876
|
- PHP versions 5.4 and above
|
|
87
877
|
- C++ version C++14
|
|
88
|
-
- Java version 7
|
|
878
|
+
- Java version 7
|
|
89
879
|
- Swift version 3
|
|
90
880
|
- Golang version 1.8
|
|
91
|
-
- Scala 2.xx
|
|
92
|
-
- CSharp 7.0
|
|
881
|
+
- Scala 2.xx
|
|
882
|
+
- CSharp 7.0
|
|
883
|
+
- Python 3.x
|
|
884
|
+
- Rust (preliminary support)
|
|
93
885
|
|
|
94
886
|
However, it is possible to add support for older versions by implementing custom operators, which target to certain compiler flags.
|
|
95
887
|
|
|
96
888
|
Additionally, JavaScript has '-typescript' flag, which will add typescript annotations to the source file.
|
|
97
889
|
|
|
98
|
-
|
|
99
890
|
# Operators
|
|
100
891
|
|
|
101
892
|
Operators enable creating short, funtional commands like 'get' or 'push' that operate on certain, typed parameters. Whenever there is
|
|
102
|
-
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
|
|
103
894
|
simple operator definition would be `M_PI` which is defined in the Compilers internal Lang.clj file as
|
|
104
895
|
|
|
105
896
|
```
|
|
106
897
|
M_PI mathPi:double () {
|
|
107
898
|
templates {
|
|
108
899
|
es6 ("Math.PI")
|
|
109
|
-
go ( "math.Pi" (imp "math"))
|
|
110
|
-
swift3 ( "Double.pi" (imp "Foundation"))
|
|
111
|
-
java7 ( "Math.PI" (imp "java.lang.Math"))
|
|
112
|
-
php ("pi()")
|
|
113
|
-
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>"))
|
|
114
905
|
}
|
|
115
906
|
}
|
|
116
907
|
```
|
|
117
908
|
|
|
118
|
-
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
|
|
119
910
|
|
|
120
911
|
```
|
|
121
912
|
M_PI mathPi:double () {
|
|
122
913
|
templates {
|
|
123
914
|
es6 ("Math.PI")
|
|
124
|
-
go ( "math.Pi" (imp "math"))
|
|
125
|
-
swift3 ( "Double.pi" (imp "Foundation"))
|
|
126
|
-
java7 ( "Math.PI" (imp "java.lang.Math"))
|
|
127
|
-
php ("pi()")
|
|
128
|
-
cpp ("M_PI" (imp "<math.h>"))
|
|
129
|
-
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"))
|
|
130
921
|
}
|
|
131
922
|
}
|
|
132
923
|
```
|
|
@@ -139,9 +930,16 @@ For a quick reference of available basic operators see [Operators doc](operators
|
|
|
139
930
|
|
|
140
931
|
# Plugins
|
|
141
932
|
|
|
142
|
-
Compiling
|
|
933
|
+
Compiling as CommonJS module:
|
|
934
|
+
|
|
935
|
+
```
|
|
936
|
+
ranger-compiler hello.clj -npm -nodemodule
|
|
937
|
+
```
|
|
938
|
+
|
|
939
|
+
Compiling as ES6/ESM module:
|
|
940
|
+
|
|
143
941
|
```
|
|
144
|
-
ranger-compiler hello.clj -npm
|
|
942
|
+
ranger-compiler hello.clj -npm -esm
|
|
145
943
|
```
|
|
146
944
|
|
|
147
945
|
Example
|
|
@@ -161,13 +959,12 @@ class Plugin {
|
|
|
161
959
|
fn features:[string] () {
|
|
162
960
|
return ([] "postprocess")
|
|
163
961
|
}
|
|
164
|
-
fn postprocess (root:CodeNode ctx:RangerAppWriterContext wr:CodeWriter) {
|
|
962
|
+
fn postprocess (root:CodeNode ctx:RangerAppWriterContext wr:CodeWriter) {
|
|
165
963
|
print "*** plugin postprocess was called ***"
|
|
166
964
|
}
|
|
167
965
|
}
|
|
168
966
|
```
|
|
169
967
|
|
|
170
|
-
|
|
171
968
|
# Notes about the syntax
|
|
172
969
|
|
|
173
970
|
Ranger syntax is originally based on Lisp -language syntax and most operators will use prefix notation. However, the Ranger modifies
|
|
@@ -182,14 +979,15 @@ class Hello {
|
|
|
182
979
|
print "x < 10"
|
|
183
980
|
} {
|
|
184
981
|
print "x >= 10"
|
|
185
|
-
}
|
|
982
|
+
}
|
|
186
983
|
}
|
|
187
984
|
}
|
|
188
985
|
```
|
|
189
986
|
|
|
190
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
|
+
|
|
191
989
|
```
|
|
192
|
-
def obj (new Hello)
|
|
990
|
+
def obj (new Hello)
|
|
193
991
|
```
|
|
194
992
|
|
|
195
993
|
For most common mathematical symbols and boolean operators infix notation can be used and they are automatically converted to lisp expressions.
|
|
@@ -198,41 +996,45 @@ Thus you can write expressions such as `(x + y * z)` instead of `(+ x (* y z))`
|
|
|
198
996
|
```
|
|
199
997
|
def x 100
|
|
200
998
|
def y 200
|
|
201
|
-
def z ( x + y * 10)
|
|
999
|
+
def z ( x + y * 10)
|
|
202
1000
|
if ( x < 20 || y == 0 ) {
|
|
203
1001
|
|
|
204
1002
|
}
|
|
205
1003
|
```
|
|
1004
|
+
|
|
206
1005
|
The assigment operator is also automatically prefixed from infix notation so you can say
|
|
1006
|
+
|
|
207
1007
|
```
|
|
208
1008
|
x = y
|
|
209
1009
|
```
|
|
1010
|
+
|
|
210
1011
|
Instead of common lisp syntax `(= x y)`
|
|
211
1012
|
|
|
212
1013
|
## Main function
|
|
213
1014
|
|
|
214
1015
|
Each file can have a static main function, which is executed as the main program.
|
|
215
1016
|
|
|
216
|
-
```
|
|
1017
|
+
```
|
|
217
1018
|
class Hello {
|
|
218
1019
|
static fn main() {
|
|
219
|
-
}
|
|
1020
|
+
}
|
|
220
1021
|
}
|
|
221
1022
|
|
|
222
1023
|
```
|
|
1024
|
+
|
|
223
1025
|
This is a static function which marks the start of execution for the program.
|
|
224
1026
|
|
|
225
1027
|
## Functions and Static functions
|
|
226
1028
|
|
|
227
|
-
```
|
|
1029
|
+
```
|
|
228
1030
|
class Hello {
|
|
229
1031
|
fn SomeNonStaticFn () {
|
|
230
|
-
}
|
|
1032
|
+
}
|
|
231
1033
|
sfn SomeStaticFn () {
|
|
232
1034
|
; static function which instantiates Hello and calls non-static
|
|
233
1035
|
def o (new Hello)
|
|
234
1036
|
o.SomeNonStaticFn()
|
|
235
|
-
}
|
|
1037
|
+
}
|
|
236
1038
|
}
|
|
237
1039
|
|
|
238
1040
|
```
|
|
@@ -247,8 +1049,8 @@ Hello.SomeStaticFn()
|
|
|
247
1049
|
|
|
248
1050
|
Function not inferred or declared as `void` should always return value with `return` statement.
|
|
249
1051
|
|
|
250
|
-
|
|
251
1052
|
## Comments
|
|
1053
|
+
|
|
252
1054
|
```
|
|
253
1055
|
; here is a comment
|
|
254
1056
|
class Hello {
|
|
@@ -274,18 +1076,21 @@ Basic primitive types are
|
|
|
274
1076
|
- boolean
|
|
275
1077
|
- string
|
|
276
1078
|
- double
|
|
277
|
-
- char
|
|
1079
|
+
- char
|
|
278
1080
|
- charbuffer
|
|
279
1081
|
|
|
280
1082
|
Type of function returning nothing is
|
|
1083
|
+
|
|
281
1084
|
- void
|
|
282
1085
|
|
|
283
1086
|
Type which can be used as variable types, but require signature are
|
|
1087
|
+
|
|
284
1088
|
- Arrays
|
|
285
1089
|
- Hashes
|
|
286
1090
|
- Anonymous functions
|
|
287
1091
|
|
|
288
1092
|
Types which require type declaration are
|
|
1093
|
+
|
|
289
1094
|
- Enum
|
|
290
1095
|
- class
|
|
291
1096
|
- systemclass
|
|
@@ -303,9 +1108,39 @@ def long_string "
|
|
|
303
1108
|
"
|
|
304
1109
|
```
|
|
305
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
|
+
|
|
306
1140
|
## Enums
|
|
307
1141
|
|
|
308
1142
|
Enums will be compiled to type `int` but are type checked by the Ranger preprosessor
|
|
1143
|
+
|
|
309
1144
|
```
|
|
310
1145
|
Enum LineJoin (
|
|
311
1146
|
Undefined
|
|
@@ -321,6 +1156,7 @@ class foo {
|
|
|
321
1156
|
## Arrays and Hashes
|
|
322
1157
|
|
|
323
1158
|
Arrays and hashes are automatically initialized and are ready to be used after their declaration
|
|
1159
|
+
|
|
324
1160
|
```
|
|
325
1161
|
def list:[string]
|
|
326
1162
|
def usedKeywords:[string:string]
|
|
@@ -330,20 +1166,27 @@ def classMap:[string:myClass]
|
|
|
330
1166
|
### Operators for hashes
|
|
331
1167
|
|
|
332
1168
|
if we have a hashmap
|
|
1169
|
+
|
|
333
1170
|
```
|
|
334
1171
|
def someMap:[string:string]
|
|
335
1172
|
```
|
|
1173
|
+
|
|
336
1174
|
Operator `set` can be used to set key/value pair
|
|
1175
|
+
|
|
337
1176
|
```
|
|
338
1177
|
set someMap "foo" "bar"
|
|
339
1178
|
```
|
|
1179
|
+
|
|
340
1180
|
Operator `has` can be used to check if a key exists in the hash
|
|
1181
|
+
|
|
341
1182
|
```
|
|
342
1183
|
if (has someMap "a key") {
|
|
343
|
-
|
|
1184
|
+
|
|
344
1185
|
}
|
|
345
1186
|
```
|
|
1187
|
+
|
|
346
1188
|
Get is used to read the value associated with a key. The result is `@(optional)`
|
|
1189
|
+
|
|
347
1190
|
```
|
|
348
1191
|
(get someMap "foo")
|
|
349
1192
|
```
|
|
@@ -351,6 +1194,7 @@ Get is used to read the value associated with a key. The result is `@(optional)`
|
|
|
351
1194
|
## Anonymous functions / lambdas
|
|
352
1195
|
|
|
353
1196
|
Anonymous function type declaration is automatically inferred
|
|
1197
|
+
|
|
354
1198
|
```
|
|
355
1199
|
def name "foo"
|
|
356
1200
|
def myFilter (fn:boolean (param:string) {
|
|
@@ -379,9 +1223,7 @@ this.foo({
|
|
|
379
1223
|
})
|
|
380
1224
|
```
|
|
381
1225
|
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
# Automatically infixed math support
|
|
1226
|
+
# Automatically infixed math support
|
|
385
1227
|
|
|
386
1228
|
It is easy to define new mathematical operations in the Lang.clj file or in modules. However, some mathematical operations are automatically infixed
|
|
387
1229
|
for easier usage. Thus, instead of using common lips notation `(* 4 10)` you can use easier to read infixed `4 * 10` -syntax
|
|
@@ -412,7 +1254,6 @@ a >= b
|
|
|
412
1254
|
a != b
|
|
413
1255
|
```
|
|
414
1256
|
|
|
415
|
-
|
|
416
1257
|
# Common set of Operators and the Grammar file
|
|
417
1258
|
|
|
418
1259
|
The file `Lang.clj` is used by the compiler for the common set of operators and compilation rules. The
|
|
@@ -429,13 +1270,57 @@ modifications, rather it describes common set of rules used and thus should be e
|
|
|
429
1270
|
The file has couple of sections, but the `reserved_words` and `commands`. The Reserved words section declares (surprise!)
|
|
430
1271
|
the reserved words and their transformation. This is required because for example in Go the word `map` is a keyword and can
|
|
431
1272
|
not be used unless it is conveted to some other name, for example to `FnMap`.
|
|
1273
|
+
|
|
432
1274
|
```
|
|
433
1275
|
reserved_words {
|
|
434
|
-
|
|
435
|
-
|
|
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
|
+
}
|
|
436
1318
|
}
|
|
437
1319
|
```
|
|
438
|
-
|
|
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
|
|
439
1324
|
compiler will transform anything named `map` to `fnMap` if possible. If transformation is not possible, compiler error is
|
|
440
1325
|
generated.
|
|
441
1326
|
|
|
@@ -444,16 +1329,17 @@ and return values and rules on how they should be compiled into the target langu
|
|
|
444
1329
|
and possible macros or helper function which should be created if the operator is used.
|
|
445
1330
|
|
|
446
1331
|
Example of simple operator is `(M_PI)` which will return double value of mathematical symbol "pi".
|
|
1332
|
+
|
|
447
1333
|
```
|
|
448
1334
|
commands {
|
|
449
1335
|
M_PI mathPi:double () {
|
|
450
1336
|
templates {
|
|
451
1337
|
es6 ("Math.PI")
|
|
452
|
-
go ( "math.Pi" (imp "math"))
|
|
453
|
-
swift3 ( "Double.pi" (imp "Foundation"))
|
|
454
|
-
java7 ( "Math.PI" (imp "java.lang.Math"))
|
|
455
|
-
php ("pi()")
|
|
456
|
-
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>"))
|
|
457
1343
|
}
|
|
458
1344
|
}
|
|
459
1345
|
...
|
|
@@ -462,15 +1348,15 @@ Example of simple operator is `(M_PI)` which will return double value of mathema
|
|
|
462
1348
|
Most operators are simple, but some require creating custom macros, helpoer functions and some of them are so complex
|
|
463
1349
|
that they may be implemented in the compiler core.
|
|
464
1350
|
|
|
465
|
-
|
|
466
1351
|
# Modules, classes and operators
|
|
467
1352
|
|
|
468
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
|
|
469
|
-
have two functions with different parameters or different return values.
|
|
1354
|
+
have two functions with different parameters or different return values.
|
|
470
1355
|
|
|
471
|
-
Each source file can import other files using `Import` command.
|
|
472
|
-
|
|
473
|
-
|
|
1356
|
+
Each source file can import other files using `Import` command.
|
|
1357
|
+
|
|
1358
|
+
```
|
|
1359
|
+
Import "Vec2.clj"
|
|
474
1360
|
|
|
475
1361
|
class vectorTest {
|
|
476
1362
|
fn testVectors () {
|
|
@@ -481,7 +1367,7 @@ class vectorTest {
|
|
|
481
1367
|
|
|
482
1368
|
## Class declaration
|
|
483
1369
|
|
|
484
|
-
```
|
|
1370
|
+
```
|
|
485
1371
|
class fatherClass {
|
|
486
1372
|
def msg "Hello "
|
|
487
1373
|
fn foo:string ( txt:string ) {
|
|
@@ -503,7 +1389,7 @@ class mainProgram {
|
|
|
503
1389
|
|
|
504
1390
|
## Class constructor
|
|
505
1391
|
|
|
506
|
-
```
|
|
1392
|
+
```
|
|
507
1393
|
class myClass {
|
|
508
1394
|
def name:string ""
|
|
509
1395
|
Constructor (n:string) {
|
|
@@ -513,13 +1399,16 @@ class myClass {
|
|
|
513
1399
|
```
|
|
514
1400
|
|
|
515
1401
|
Notes:
|
|
516
|
-
|
|
1402
|
+
|
|
1403
|
+
1. currently only a single variant of the constructor is possible.
|
|
517
1404
|
2. as of this writing calling the parent class constructor does not work properly
|
|
518
1405
|
|
|
519
1406
|
## Class invocation
|
|
1407
|
+
|
|
520
1408
|
```
|
|
521
1409
|
def obj (new myClass ("name"))
|
|
522
1410
|
```
|
|
1411
|
+
|
|
523
1412
|
classes without constructor can be invocated without arguments
|
|
524
1413
|
|
|
525
1414
|
```
|
|
@@ -536,7 +1425,7 @@ Extension can
|
|
|
536
1425
|
- add new functions to the class
|
|
537
1426
|
- add new member variables to the class
|
|
538
1427
|
|
|
539
|
-
```
|
|
1428
|
+
```
|
|
540
1429
|
extension childClass {
|
|
541
1430
|
def name:string ""
|
|
542
1431
|
fn bar:string ( txt:string ) {
|
|
@@ -553,26 +1442,28 @@ non-nullable value should cause compiler error. In Ranger any variable which is
|
|
|
553
1442
|
This corresponds to Swift `?` optional type.
|
|
554
1443
|
|
|
555
1444
|
You can also declare variables optional using @optional annotation
|
|
1445
|
+
|
|
556
1446
|
```
|
|
557
1447
|
def item@(optional):myClass
|
|
558
1448
|
```
|
|
559
1449
|
|
|
560
1450
|
Some operators also return optional values, for example `(get <hash> <key>)` operator is returning always optional value. To use
|
|
561
1451
|
the value you must use `(unwrap <value>)` operator
|
|
1452
|
+
|
|
562
1453
|
```
|
|
563
1454
|
def strMap:[string:string]
|
|
564
1455
|
def str (get strMap "myKey")
|
|
565
1456
|
if(!null? str) {
|
|
566
1457
|
print (unwrap str)
|
|
567
1458
|
}
|
|
568
|
-
```
|
|
1459
|
+
```
|
|
569
1460
|
|
|
570
|
-
**Warning
|
|
1461
|
+
**Warning\*** currently optinal variables in Ranger are not "safe" in the sense the language makes sure that you can not make
|
|
571
1462
|
programming errors - it is possible to create programming mistake by using a variable which automatically unwrapped. The plan
|
|
572
|
-
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
|
|
573
1464
|
|
|
574
1465
|
Another warning: Ranger does not protect you from mistakes when automatically unwrapping long reference chains like
|
|
575
|
-
`obj.property.subProperty.foo` where `property` and `subProperty ` are optional variables.
|
|
1466
|
+
`obj.property.subProperty.foo` where `property` and `subProperty ` are optional variables.
|
|
576
1467
|
|
|
577
1468
|
## Control flow
|
|
578
1469
|
|
|
@@ -589,7 +1480,7 @@ if ( x < 10 ) {
|
|
|
589
1480
|
}
|
|
590
1481
|
```
|
|
591
1482
|
|
|
592
|
-
### switch - case
|
|
1483
|
+
### switch - case
|
|
593
1484
|
|
|
594
1485
|
Note: currently case statement does not support multiple matching values, it is planned to add support for that later.
|
|
595
1486
|
|
|
@@ -611,15 +1502,18 @@ switch name {
|
|
|
611
1502
|
## Loops
|
|
612
1503
|
|
|
613
1504
|
### for -loop
|
|
1505
|
+
|
|
614
1506
|
```
|
|
615
1507
|
def list:[string]
|
|
616
1508
|
for list s:string i {
|
|
617
1509
|
print s
|
|
618
1510
|
}
|
|
619
1511
|
```
|
|
1512
|
+
|
|
620
1513
|
You can use `break` and `continue` to control the for -loop.
|
|
621
1514
|
|
|
622
1515
|
### while -loop
|
|
1516
|
+
|
|
623
1517
|
```
|
|
624
1518
|
def cnt 10
|
|
625
1519
|
while (cnt > 0 ) {
|
|
@@ -636,6 +1530,7 @@ using macros. Together with `systemclass` they allow the system to integrate to
|
|
|
636
1530
|
native API's.
|
|
637
1531
|
|
|
638
1532
|
Operators allow type matching against
|
|
1533
|
+
|
|
639
1534
|
- defined primitive types
|
|
640
1535
|
- defined classes
|
|
641
1536
|
- Enums
|
|
@@ -677,17 +1572,17 @@ operators {
|
|
|
677
1572
|
* base:Mat2 ( a:Mat2 b:Mat2) {
|
|
678
1573
|
templates {
|
|
679
1574
|
* @macro(true) ( (e 1 ) ".multiply(" (e 2) " )" )
|
|
680
|
-
}
|
|
1575
|
+
}
|
|
681
1576
|
}
|
|
682
1577
|
}
|
|
683
1578
|
|
|
684
1579
|
```
|
|
685
|
-
The `* @macro(true)` means that we target all languages and this is a macro, not actual target language construct.
|
|
686
1580
|
|
|
1581
|
+
The `* @macro(true)` means that we target all languages and this is a macro, not actual target language construct.
|
|
687
1582
|
|
|
688
1583
|
## Custom operators and System classes
|
|
689
1584
|
|
|
690
|
-
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
|
|
691
1586
|
together with the code.
|
|
692
1587
|
|
|
693
1588
|
```
|
|
@@ -699,12 +1594,12 @@ operators {
|
|
|
699
1594
|
find base:DOMElement ( id:string) {
|
|
700
1595
|
templates {
|
|
701
1596
|
es6 ("document.getElementById( " (e 1) " )")
|
|
702
|
-
}
|
|
1597
|
+
}
|
|
703
1598
|
}
|
|
704
1599
|
setAttribute _:void ( elem:DOMElement name:string value:string) {
|
|
705
1600
|
templates {
|
|
706
1601
|
es6 ( (e 1) ".setAttribute(" (e 2) ", " (e 3) ")" )
|
|
707
|
-
}
|
|
1602
|
+
}
|
|
708
1603
|
}
|
|
709
1604
|
}
|
|
710
1605
|
|
|
@@ -716,25 +1611,25 @@ class tester {
|
|
|
716
1611
|
}
|
|
717
1612
|
```
|
|
718
1613
|
|
|
719
|
-
|
|
720
1614
|
Note: Definition of system classes will be revisited in near future and there will be potentially small changes to it.
|
|
721
1615
|
|
|
722
1616
|
## Unions of system classes
|
|
723
1617
|
|
|
724
|
-
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
|
|
725
1619
|
a single type.
|
|
726
1620
|
|
|
727
1621
|
```
|
|
728
1622
|
systemunion DOMElementUnion ( DOMElement string )
|
|
729
1623
|
```
|
|
730
|
-
The you can create operator which accepts either `DOMElement` or `string` and reduces that to a single type.
|
|
731
1624
|
|
|
1625
|
+
The you can create operator which accepts either `DOMElement` or `string` and reduces that to a single type.
|
|
732
1626
|
|
|
733
1627
|
## Traits
|
|
734
1628
|
|
|
735
1629
|
Traits are like extensions, which can be plugged into several classes using `does` keyword.
|
|
736
1630
|
|
|
737
|
-
Traits
|
|
1631
|
+
Traits
|
|
1632
|
+
|
|
738
1633
|
```
|
|
739
1634
|
trait bar {
|
|
740
1635
|
fn hello() {
|
|
@@ -742,7 +1637,7 @@ trait bar {
|
|
|
742
1637
|
}
|
|
743
1638
|
}
|
|
744
1639
|
|
|
745
|
-
; foo implements "bar" trait
|
|
1640
|
+
; foo implements "bar" trait
|
|
746
1641
|
class foo {
|
|
747
1642
|
does bar
|
|
748
1643
|
}
|
|
@@ -783,14 +1678,14 @@ class Main {
|
|
|
783
1678
|
def n (coll.map({
|
|
784
1679
|
return ("item = " + item)
|
|
785
1680
|
}))
|
|
786
|
-
print (join n.items " ")
|
|
1681
|
+
print (join n.items " ")
|
|
787
1682
|
}
|
|
788
1683
|
sfn hello@(main):void () {
|
|
789
1684
|
def hello (new Main ())
|
|
790
1685
|
hello.testCollection()
|
|
791
|
-
}
|
|
1686
|
+
}
|
|
792
1687
|
}
|
|
793
|
-
```
|
|
1688
|
+
```
|
|
794
1689
|
|
|
795
1690
|
## Variable definitions
|
|
796
1691
|
|
|
@@ -807,15 +1702,15 @@ def strObjMap:[string:someClass] ; map of string -> object of type someClass
|
|
|
807
1702
|
|
|
808
1703
|
# Advanced topics
|
|
809
1704
|
|
|
810
|
-
|
|
811
1705
|
## Compiling a new version of the compiler
|
|
812
1706
|
|
|
813
1707
|
Then run command
|
|
1708
|
+
|
|
814
1709
|
```
|
|
815
1710
|
ranger-compiler -compiler -copysrc
|
|
816
1711
|
```
|
|
817
|
-
The result will be written to directory `bin/ng_Compiler.js`.
|
|
818
1712
|
|
|
1713
|
+
The result will be written to directory `bin/ng_Compiler.js`.
|
|
819
1714
|
|
|
820
1715
|
# Annotations
|
|
821
1716
|
|
|
@@ -845,7 +1740,7 @@ trait GenericCollection @paras(T V) {
|
|
|
845
1740
|
class StringCollection {
|
|
846
1741
|
does GenericCollection @params(string StringCollection)
|
|
847
1742
|
}
|
|
848
|
-
```
|
|
1743
|
+
```
|
|
849
1744
|
|
|
850
1745
|
## def variableName@(optional)
|
|
851
1746
|
|
|
@@ -871,4 +1766,4 @@ the lifetime calculations.
|
|
|
871
1766
|
## def variableName@(temp)
|
|
872
1767
|
|
|
873
1768
|
@(temp) annotation can be used to note the compiler that it should not worry about freeing the variable, in case the
|
|
874
|
-
target language has option to release the variable.
|
|
1769
|
+
target language has option to release the variable.
|