├── .github ├── FUNDING.yml └── workflows │ └── dart.yml ├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── analysis_options.yaml ├── apollovm_dart.iml ├── bin └── apollovm.dart ├── example ├── apollovm-logo.png └── apollovm_example.dart ├── lib ├── apollovm.dart └── src │ ├── apollovm_base.dart │ ├── apollovm_code_generator.dart │ ├── apollovm_code_storage.dart │ ├── apollovm_generated_output.dart │ ├── apollovm_generator.dart │ ├── apollovm_parser.dart │ ├── apollovm_runner.dart │ ├── ast │ ├── apollovm_ast_annotation.dart │ ├── apollovm_ast_base.dart │ ├── apollovm_ast_expression.dart │ ├── apollovm_ast_statement.dart │ ├── apollovm_ast_toplevel.dart │ ├── apollovm_ast_type.dart │ ├── apollovm_ast_value.dart │ └── apollovm_ast_variable.dart │ ├── core │ └── apollovm_core_base.dart │ └── languages │ ├── dart │ ├── dart_generator.dart │ ├── dart_grammar.dart │ ├── dart_grammar_lexer.dart │ ├── dart_parser.dart │ └── dart_runner.dart │ ├── java │ └── java11 │ │ ├── java11_generator.dart │ │ ├── java11_grammar.dart │ │ ├── java11_grammar_lexer.dart │ │ ├── java11_parser.dart │ │ └── java11_runner.dart │ └── wasm │ ├── wasm.dart │ ├── wasm_generator.dart │ ├── wasm_parser.dart │ ├── wasm_runner.dart │ ├── wasm_runtime.dart │ ├── wasm_runtime_browser.dart │ ├── wasm_runtime_generic.dart │ └── wasm_runtime_io.dart ├── pubspec.yaml └── test ├── apollovm_languages_basic_test.dart ├── apollovm_languages_extended_test.dart ├── apollovm_languages_test_definition.dart ├── apollovm_version_test.dart ├── apollovm_wasm_test.dart ├── hello_world.dart ├── hello_world.java └── tests_definitions ├── dart_basic_class_field.test.xml ├── dart_basic_class_function.test.xml ├── dart_basic_class_function_with_multi_args.test.xml ├── dart_basic_class_function_with_multi_args_and_comments.test.xml ├── dart_basic_class_this_function.test.xml ├── dart_basic_for_loop.test.xml ├── dart_basic_main_1.test.xml ├── dart_basic_main_2.test.xml ├── dart_basic_main_3_negation.test.xml ├── dart_basic_main_with_division.test.xml ├── dart_basic_vars.xml ├── dart_basic_with_branch.test.xml ├── dart_basic_with_comparisons.test.xml ├── dart_basic_with_inline_string.test.xml ├── dart_basic_with_multiline_string.test.xml ├── dart_basic_with_raw_multiline_string.test.xml ├── dart_basic_with_raw_string.test.xml ├── dart_basic_with_string_variable.test.xml ├── dart_core_lc.test.xml ├── java11_basic_args.xml ├── java11_basic_class_field.test.xml ├── java11_basic_class_function_with_multi_args.test.xml ├── java11_basic_class_function_with_multi_args_and_comments.test.xml ├── java11_basic_class_this_function.test.xml ├── java11_basic_for_loop.test.xml ├── java11_basic_for_loop_decrement.test.xml ├── java11_basic_for_loop_increment.test.xml ├── java11_basic_for_loop_pre_decrement.test.xml ├── java11_basic_for_loop_pre_increment.test.xml ├── java11_basic_main_1.test.xml ├── java11_basic_main_2.test.xml ├── java11_basic_main_3_negation.test.xml ├── java11_basic_main_with_division.test.xml ├── java11_basic_main_with_inline_string.xml ├── java11_basic_var_decrement.xml ├── java11_basic_var_increment.xml ├── java11_basic_vars.xml ├── java11_basic_with_branches.test.xml └── java11_basic_with_string_variable.test.xml /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [gmpassos] 2 | -------------------------------------------------------------------------------- /.github/workflows/dart.yml: -------------------------------------------------------------------------------- 1 | name: Dart CI 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | jobs: 10 | build: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v3 14 | - uses: dart-lang/setup-dart@v1 15 | - name: Dart version 16 | run: | 17 | dart --version 18 | uname -a 19 | - name: Install dependencies 20 | run: dart pub get 21 | - name: Upgrade dependencies 22 | run: dart pub upgrade 23 | - name: dart format 24 | run: dart format -o none --set-exit-if-changed . 25 | - name: dart analyze 26 | run: dart analyze --fatal-infos --fatal-warnings . 27 | - name: dependency_validator 28 | run: dart run dependency_validator 29 | - name: dart doc 30 | run: dart doc --dry-run 31 | - name: dart pub publish --dry-run 32 | run: dart pub publish --dry-run 33 | 34 | test_vm: 35 | runs-on: ubuntu-latest 36 | steps: 37 | - uses: actions/checkout@v3 38 | - uses: dart-lang/setup-dart@v1 39 | - name: Dart version 40 | run: | 41 | dart --version 42 | uname -a 43 | - name: Install dependencies 44 | run: dart pub get 45 | - name: Upgrade dependencies 46 | run: dart pub upgrade 47 | - name: wasm_run:setup (install dynamic library) 48 | run: dart run wasm_run:setup 49 | - name: Run tests (VM) 50 | run: dart test --platform vm --coverage=./coverage 51 | - name: Generate coverage report 52 | run: | 53 | dart pub global activate coverage 54 | dart pub global run coverage:format_coverage --packages=.dart_tool/package_config.json --report-on=lib --lcov -o ./coverage/lcov.info -i ./coverage 55 | - name: Upload coverage to Codecov 56 | uses: codecov/codecov-action@v3 57 | env: 58 | CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} 59 | with: 60 | directory: ./coverage/ 61 | flags: unittests 62 | env_vars: OS,DART 63 | fail_ci_if_error: true 64 | verbose: true 65 | 66 | 67 | test_exe: 68 | runs-on: ubuntu-latest 69 | steps: 70 | - uses: actions/checkout@v3 71 | - uses: dart-lang/setup-dart@v1 72 | - name: Dart version 73 | run: | 74 | dart --version 75 | uname -a 76 | - name: Install dependencies 77 | run: dart pub get 78 | - name: Upgrade dependencies 79 | run: dart pub upgrade 80 | - name: wasm_run:setup (install dynamic library) 81 | run: dart run wasm_run:setup 82 | - name: Run tests (exe) 83 | run: dart test --compiler exe 84 | 85 | 86 | test_chrome: 87 | runs-on: ubuntu-latest 88 | steps: 89 | - uses: actions/checkout@v3 90 | - uses: dart-lang/setup-dart@v1 91 | - name: Dart version 92 | run: | 93 | dart --version 94 | uname -a 95 | - name: Install dependencies 96 | run: dart pub get 97 | - name: Upgrade dependencies 98 | run: dart pub upgrade 99 | - name: Run tests (Chrome) 100 | run: dart test --platform chrome 101 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Files and directories created by pub 2 | .dart_tool/ 3 | .packages 4 | 5 | # Omit commiting pubspec.lock for library packages: 6 | # https://dart.dev/guides/libraries/private-files#pubspeclock 7 | pubspec.lock 8 | 9 | # Conventional directory for build outputs 10 | build/ 11 | 12 | # Directory created by dartdoc 13 | doc/api/ 14 | 15 | .DS_Store 16 | 17 | articles/ 18 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. -------------------------------------------------------------------------------- /analysis_options.yaml: -------------------------------------------------------------------------------- 1 | 2 | include: package:lints/recommended.yaml 3 | 4 | # For lint rules and documentation, see http://dart-lang.github.io/linter/lints. 5 | # Uncomment to specify additional rules. 6 | # linter: 7 | # rules: 8 | # - camel_case_types 9 | 10 | analyzer: 11 | # exclude: 12 | # - path/to/excluded/files/** 13 | -------------------------------------------------------------------------------- /apollovm_dart.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /bin/apollovm.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:apollovm/apollovm.dart'; 4 | import 'package:args/args.dart'; 5 | import 'package:args/command_runner.dart'; 6 | import 'package:swiss_knife/swiss_knife.dart'; 7 | 8 | void _log(String ns, String message) { 9 | print('## [$ns]\t$message'); 10 | } 11 | 12 | void main(List args) async { 13 | var commandRunner = CommandRunner('apollovm', 14 | 'ApolloVM/${ApolloVM.VERSION} - A compact VM for Dart and Java.') 15 | ..addCommand(CommandRun()) 16 | ..addCommand(CommandTranslate()); 17 | 18 | commandRunner.argParser.addFlag('version', 19 | abbr: 'v', 20 | negatable: false, 21 | defaultsTo: false, 22 | help: 'Show ApolloVM version.'); 23 | 24 | { 25 | var argsResult = commandRunner.argParser.parse(args); 26 | if (argsResult['version']) { 27 | showVersion(); 28 | return; 29 | } 30 | } 31 | 32 | await commandRunner.run(args); 33 | } 34 | 35 | void showVersion() { 36 | print('ApolloVM - ${ApolloVM.VERSION}'); 37 | } 38 | 39 | abstract class CommandSourceFileBase extends Command { 40 | final _argParser = ArgParser(allowTrailingOptions: false); 41 | 42 | @override 43 | ArgParser get argParser => _argParser; 44 | 45 | CommandSourceFileBase() { 46 | argParser.addFlag('verbose', 47 | abbr: 'v', 48 | help: 'VM in Verbose mode', 49 | defaultsTo: false, 50 | negatable: false); 51 | argParser.addOption('language', 52 | help: 'Programming language of source file.\n' 53 | '(defaults to language of the file extension)', 54 | valueHelp: 'dart|java'); 55 | } 56 | 57 | bool? _verbose; 58 | 59 | bool get verbose { 60 | _verbose ??= argResults!['verbose'] as bool; 61 | return _verbose!; 62 | } 63 | 64 | String get sourceFilePath { 65 | var argResults = this.argResults!; 66 | 67 | if (argResults.rest.isEmpty) { 68 | throw StateError('Empty arguments: no source file path!'); 69 | } 70 | 71 | return argResults.rest[0]; 72 | } 73 | 74 | File get sourceFile => File(sourceFilePath); 75 | 76 | String get sourceFileExtension { 77 | var ext = getPathExtension(sourceFilePath) ?? ''; 78 | return ext.trim().toLowerCase(); 79 | } 80 | 81 | String get language { 82 | var lang = argResults!['language']; 83 | return lang != null 84 | ? lang.toString().toLowerCase() 85 | : ApolloVM.parseLanguageFromFilePathExtension(sourceFilePath); 86 | } 87 | 88 | String get source => sourceFile.readAsStringSync(); 89 | } 90 | 91 | class CommandRun extends CommandSourceFileBase { 92 | @override 93 | final String description = 'Run a source file.'; 94 | 95 | @override 96 | final String name = 'run'; 97 | 98 | CommandRun() { 99 | argParser.addOption('function', 100 | abbr: 'f', 101 | help: 'Named of the main function to call', 102 | defaultsTo: 'main', 103 | valueHelp: 'main|start'); 104 | } 105 | 106 | String get mainFunction => argResults!['function'] ?? 'main'; 107 | 108 | List get parameters => argResults!.rest.sublist(1).toList(); 109 | 110 | @override 111 | FutureOr run() async { 112 | var parameters = this.parameters; 113 | 114 | if (verbose) { 115 | _log('RUN', 116 | '$sourceFile ; language: $language > $mainFunction( $parameters )'); 117 | } 118 | 119 | var vm = ApolloVM(); 120 | 121 | var codeUnit = SourceCodeUnit(language, source, id: sourceFilePath); 122 | 123 | var loadOK = await vm.loadCodeUnit(codeUnit); 124 | 125 | if (!loadOK) { 126 | throw StateError( 127 | "Can't parse source! language: $language ; sourceFilePath: $sourceFilePath"); 128 | } 129 | 130 | var runner = vm.createRunner(language)!; 131 | 132 | var namespaces = vm.getLanguageNamespaces(language).namespaces; 133 | if (!namespaces.contains('')) namespaces.insert(0, ''); 134 | 135 | ASTValue? result; 136 | 137 | for (var namespace in namespaces) { 138 | result = 139 | await runner.tryExecuteFunction(namespace, mainFunction, parameters); 140 | if (result != null) break; 141 | } 142 | 143 | if (result == null) { 144 | LOOP_NS: 145 | for (var namespace in namespaces) { 146 | var classes = 147 | vm.getLanguageNamespaces(language).get(namespace).classesNames; 148 | for (var clazz in classes) { 149 | result = await runner.tryExecuteClassFunction( 150 | namespace, clazz, mainFunction, parameters); 151 | if (result != null) break LOOP_NS; 152 | } 153 | } 154 | } 155 | 156 | if (result == null) { 157 | throw StateError("Can't find main function: $mainFunction"); 158 | } 159 | 160 | return true; 161 | } 162 | } 163 | 164 | class CommandTranslate extends CommandSourceFileBase { 165 | @override 166 | final String description = 'Translate a source file.'; 167 | 168 | @override 169 | final String name = 'translate'; 170 | 171 | CommandTranslate() { 172 | argParser.addOption('target', 173 | help: 'Target Programming language for translation.\n' 174 | '(defaults to the opposite of the source language)', 175 | valueHelp: 'dart|java'); 176 | } 177 | 178 | String get targetLanguage { 179 | var target = argResults!['target']; 180 | if (target == null) { 181 | if (language == 'dart') { 182 | target = 'java'; 183 | } else { 184 | target = 'dart'; 185 | } 186 | } 187 | return target; 188 | } 189 | 190 | @override 191 | FutureOr run() async { 192 | if (verbose) { 193 | _log('TRANSLATE', 194 | '$sourceFile ; language: $language > targetLanguage: $targetLanguage'); 195 | } 196 | 197 | var vm = ApolloVM(); 198 | 199 | var codeUnit = SourceCodeUnit(language, source, id: sourceFilePath); 200 | 201 | var loadOK = await vm.loadCodeUnit(codeUnit); 202 | 203 | if (!loadOK) { 204 | throw StateError( 205 | "Can't parse source! language: $language ; sourceFilePath: $sourceFilePath"); 206 | } 207 | 208 | var codeStorage = vm.generateAllCodeIn(targetLanguage); 209 | 210 | var allSources = codeStorage.writeAllSources().toString(); 211 | 212 | print(allSources); 213 | 214 | return true; 215 | } 216 | } 217 | -------------------------------------------------------------------------------- /example/apollovm-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ApolloVM/apollovm_dart/234596dabfcbee8fdc3788ee6d83c81267e57b65/example/apollovm-logo.png -------------------------------------------------------------------------------- /example/apollovm_example.dart: -------------------------------------------------------------------------------- 1 | import 'package:apollovm/apollovm.dart'; 2 | 3 | void main() async { 4 | var vm = ApolloVM(); 5 | 6 | var codeUnit = SourceCodeUnit( 7 | 'dart', 8 | r''' 9 | 10 | class Foo { 11 | 12 | int main(List args) { 13 | var title = args[0]; 14 | var a = args[1]; 15 | var b = args[2] ~/ 2; 16 | var c = args[3] * 3; 17 | 18 | if (c > 120) { 19 | c = 120 ; 20 | } 21 | 22 | var str = 'variables> a: $a ; b: $b ; c: $c' ; 23 | var sumAB = a + b ; 24 | var sumABC = a + b + c; 25 | 26 | print(str); 27 | print(title); 28 | print(sumAB); 29 | print(sumABC); 30 | 31 | // Map: 32 | var map = { 33 | 'a': a, 34 | 'b': b, 35 | 'c': c, 36 | 'sumAB': sumAB, 37 | "sumABC": sumABC, 38 | }; 39 | 40 | print('Map: $map'); 41 | print('Map `b`: ${map['b']}'); 42 | 43 | return map['sumABC']; 44 | } 45 | 46 | } 47 | 48 | ''', 49 | id: 'test'); 50 | 51 | var loadOK = await vm.loadCodeUnit(codeUnit); 52 | 53 | if (!loadOK) { 54 | print("Can't load source!"); 55 | return; 56 | } 57 | 58 | print('---------------------------------------'); 59 | 60 | var dartRunner = vm.createRunner('dart')!; 61 | 62 | // Map the `print` function in the VM: 63 | dartRunner.externalPrintFunction = (o) => print("» $o"); 64 | 65 | var astValue = await dartRunner.executeClassMethod( 66 | '', 67 | 'Foo', 68 | 'main', 69 | positionalParameters: [ 70 | ['Sums:', 10, 30, 50] 71 | ], 72 | ); 73 | 74 | var result = astValue.getValueNoContext(); 75 | print('Result: $result'); 76 | 77 | print('---------------------------------------'); 78 | 79 | // Regenerate code in Dart: 80 | var codeStorageDart = vm.generateAllCodeIn('dart'); 81 | var allSourcesDart = codeStorageDart.writeAllSources(); 82 | print(allSourcesDart); 83 | 84 | print('---------------------------------------'); 85 | 86 | // Regenerate code in Java11: 87 | var codeStorageJava = vm.generateAllCodeIn('java11'); 88 | var allSourcesJava = codeStorageJava.writeAllSources(); 89 | print(allSourcesJava); 90 | } 91 | 92 | ///////////// 93 | // OUTPUT: // 94 | ///////////// 95 | // --------------------------------------- 96 | // » variables> a: 10 ; b: 15 ; c: 120 97 | // » Sums: 98 | // » 25 99 | // » 145 100 | // » Map: {a: 10, b: 15, c: 120, sumAB: 25, sumABC: 145} 101 | // » Map `b`: 15 102 | // Result: 145 103 | // --------------------------------------- 104 | // <<<< [SOURCES_BEGIN] >>>> 105 | // <<<< NAMESPACE="" >>>> 106 | // <<<< CODE_UNIT_START="/test" >>>> 107 | // class Foo { 108 | // 109 | // int main(List args) { 110 | // var title = args[0]; 111 | // var a = args[1]; 112 | // var b = args[2] ~/ 2; 113 | // var c = args[3] * 3; 114 | // if (c > 120) { 115 | // c = 120; 116 | // } 117 | // 118 | // var str = 'variables> a: $a ; b: $b ; c: $c'; 119 | // var sumAB = a + b; 120 | // var sumABC = a + b + c; 121 | // print(str); 122 | // print(title); 123 | // print(sumAB); 124 | // print(sumABC); 125 | // var map = {'a': a, 'b': b, 'c': c, 'sumAB': sumAB, 'sumABC': sumABC}; 126 | // print('Map: $map'); 127 | // print('Map `b`: ${map['b']}'); 128 | // return map['sumABC']; 129 | // } 130 | // 131 | // } 132 | // <<<< CODE_UNIT_END="/test" >>>> 133 | // <<<< [SOURCES_END] >>>> 134 | // 135 | // --------------------------------------- 136 | // <<<< [SOURCES_BEGIN] >>>> 137 | // <<<< NAMESPACE="" >>>> 138 | // <<<< CODE_UNIT_START="/test" >>>> 139 | // class Foo { 140 | // 141 | // int main(Object[] args) { 142 | // var title = args[0]; 143 | // var a = args[1]; 144 | // var b = args[2] / 2; 145 | // var c = args[3] * 3; 146 | // if (c > 120) { 147 | // c = 120; 148 | // } 149 | // 150 | // var str = "variables> a: " + a + " ; b: " + b + " ; c: " + c; 151 | // var sumAB = a + b; 152 | // var sumABC = a + b + c; 153 | // print(str); 154 | // print(title); 155 | // print(sumAB); 156 | // print(sumABC); 157 | // var map = new HashMap(){{ 158 | // put("a", a); 159 | // put("b", b); 160 | // put("c", c); 161 | // put("sumAB", sumAB); 162 | // put("sumABC", sumABC); 163 | // }}; 164 | // print("Map: " + map); 165 | // print("Map `b`: " + String.valueOf( map["b"] )); 166 | // return map["sumABC"]; 167 | // } 168 | // 169 | // } 170 | // <<<< CODE_UNIT_END="/test" >>>> 171 | // <<<< [SOURCES_END] >>>> 172 | // 173 | -------------------------------------------------------------------------------- /lib/apollovm.dart: -------------------------------------------------------------------------------- 1 | // Copyright © 2020 Graciliano M. P. All rights reserved. 2 | // This code is governed by the Apache License, Version 2.0. 3 | // Please refer to the LICENSE and AUTHORS files for details. 4 | 5 | library apollovm; 6 | 7 | export 'package:async_extension/async_extension.dart'; 8 | 9 | export 'src/apollovm_base.dart'; 10 | export 'src/apollovm_generated_output.dart'; 11 | export 'src/apollovm_generator.dart'; 12 | export 'src/apollovm_parser.dart'; 13 | export 'src/apollovm_runner.dart'; 14 | export 'src/ast/apollovm_ast_annotation.dart'; 15 | export 'src/ast/apollovm_ast_base.dart'; 16 | export 'src/ast/apollovm_ast_expression.dart'; 17 | export 'src/ast/apollovm_ast_statement.dart'; 18 | export 'src/ast/apollovm_ast_toplevel.dart'; 19 | export 'src/ast/apollovm_ast_type.dart'; 20 | export 'src/ast/apollovm_ast_value.dart'; 21 | export 'src/ast/apollovm_ast_variable.dart'; 22 | export 'src/languages/dart/dart_parser.dart'; 23 | export 'src/languages/dart/dart_runner.dart'; 24 | export 'src/languages/java/java11/java11_parser.dart'; 25 | export 'src/languages/java/java11/java11_runner.dart'; 26 | export 'src/languages/wasm/wasm_parser.dart'; 27 | export 'src/languages/wasm/wasm_runner.dart'; 28 | export 'src/languages/wasm/wasm_runtime.dart'; 29 | -------------------------------------------------------------------------------- /lib/src/apollovm_code_storage.dart: -------------------------------------------------------------------------------- 1 | // Copyright © 2020 Graciliano M. P. All rights reserved. 2 | // This code is governed by the Apache License, Version 2.0. 3 | // Please refer to the LICENSE and AUTHORS files for details. 4 | 5 | import 'dart:async'; 6 | import 'dart:typed_data'; 7 | 8 | /// Base class for a code unit storage. 9 | /// 10 | /// The implementation can be a local file system, a memory storage or a remote repository. 11 | abstract class ApolloCodeUnitStorage { 12 | FutureOr> getNamespaces(); 13 | 14 | /// Returns a list of code units IDs of a namespace. 15 | FutureOr> getNamespaceCodeUnitsIDs(String namespace); 16 | 17 | /// Returns the source code of a [codeUnitID] in [namespace]. 18 | FutureOr getNamespaceCodeUnit(String namespace, String codeUnitID); 19 | 20 | /// Adds a source code to this storage. 21 | FutureOr add(String namespace, String codeUnitID, T codeUnitData); 22 | 23 | /// Returns all the entries in this storage. 24 | FutureOr>> allEntries(); 25 | } 26 | 27 | /// Base class for a binary code storage. 28 | /// 29 | /// The implementation can be a local file system, a memory storage or a remote repository. 30 | abstract class ApolloBinaryCodeStorage 31 | extends ApolloCodeUnitStorage {} 32 | 33 | /// In memory source code storage implementation. 34 | class ApolloBinaryCodeStorageMemory extends ApolloBinaryCodeStorage { 35 | final Map> _namespaces = {}; 36 | 37 | @override 38 | List getNamespaces() => _namespaces.keys.toList(); 39 | 40 | @override 41 | List getNamespaceCodeUnitsIDs(String namespace) { 42 | var ns = _namespaces[namespace]; 43 | return ns?.keys.toList() ?? []; 44 | } 45 | 46 | @override 47 | Uint8List? getNamespaceCodeUnit(String namespace, String codeUnitID) { 48 | var ns = _namespaces[namespace]; 49 | return ns?[codeUnitID]; 50 | } 51 | 52 | @override 53 | void add(String namespace, String codeUnitID, Uint8List codeUnitData) { 54 | var ns = _namespaces.putIfAbsent(namespace, () => {}); 55 | ns[codeUnitID] = codeUnitData; 56 | } 57 | 58 | @override 59 | Map> allEntries() { 60 | return _namespaces.map((k, v) => MapEntry(k, Map.from(v))); 61 | } 62 | } 63 | 64 | /// Base class for a source code storage. 65 | /// 66 | /// The implementation can be a local file system, a memory storage or a remote repository. 67 | abstract class ApolloSourceCodeStorage extends ApolloCodeUnitStorage { 68 | /// Write all code unit sources. 69 | Future writeAllSources( 70 | {String commentPrefix = '<<<<', 71 | String commentSuffix = '>>>>', 72 | String nsSeparator = '/'}) async { 73 | var s = StringBuffer(); 74 | 75 | s.write(commentPrefix); 76 | s.write(' [SOURCES_BEGIN] '); 77 | s.write(commentSuffix); 78 | s.write('\n'); 79 | 80 | for (var ns in await getNamespaces()) { 81 | s.write(commentPrefix); 82 | s.write(' NAMESPACE="$ns" '); 83 | s.write(commentSuffix); 84 | s.write('\n'); 85 | 86 | for (var cu in await getNamespaceCodeUnitsIDs(ns)) { 87 | var fullCU = '$nsSeparator$cu'; 88 | 89 | s.write(commentPrefix); 90 | s.write(' CODE_UNIT_START="$fullCU" '); 91 | s.write(commentSuffix); 92 | s.write('\n'); 93 | 94 | var source = await getNamespaceCodeUnit(ns, cu); 95 | s.write(source); 96 | 97 | s.write(commentPrefix); 98 | s.write(' CODE_UNIT_END="$fullCU" '); 99 | s.write(commentSuffix); 100 | s.write('\n'); 101 | } 102 | } 103 | 104 | s.write(commentPrefix); 105 | s.write(' [SOURCES_END] '); 106 | s.write(commentSuffix); 107 | s.write('\n'); 108 | 109 | return s; 110 | } 111 | } 112 | 113 | /// In memory source code storage implementation. 114 | class ApolloSourceCodeStorageMemory extends ApolloSourceCodeStorage { 115 | final Map> _namespaces = {}; 116 | 117 | @override 118 | List getNamespaces() => _namespaces.keys.toList(); 119 | 120 | @override 121 | List getNamespaceCodeUnitsIDs(String namespace) { 122 | var ns = _namespaces[namespace]; 123 | return ns?.keys.toList() ?? []; 124 | } 125 | 126 | @override 127 | String? getNamespaceCodeUnit(String namespace, String codeUnitID) { 128 | var ns = _namespaces[namespace]; 129 | return ns?[codeUnitID]; 130 | } 131 | 132 | @override 133 | void add(String namespace, String codeUnitID, String codeUnitData) { 134 | var ns = _namespaces.putIfAbsent(namespace, () => {}); 135 | ns[codeUnitID] = codeUnitData; 136 | } 137 | 138 | @override 139 | Map> allEntries() { 140 | return _namespaces.map((k, v) => MapEntry(k, Map.from(v))); 141 | } 142 | } 143 | 144 | /// In memory source code storage implementation. 145 | class ApolloGenericCodeStorageMemory 146 | extends ApolloCodeUnitStorage { 147 | final Map> _namespaces = {}; 148 | 149 | @override 150 | List getNamespaces() => _namespaces.keys.toList(); 151 | 152 | @override 153 | List getNamespaceCodeUnitsIDs(String namespace) { 154 | var ns = _namespaces[namespace]; 155 | return ns?.keys.toList() ?? []; 156 | } 157 | 158 | @override 159 | T? getNamespaceCodeUnit(String namespace, String codeUnitID) { 160 | var ns = _namespaces[namespace]; 161 | return ns?[codeUnitID]; 162 | } 163 | 164 | @override 165 | void add(String namespace, String codeUnitID, T codeUnitData) { 166 | var ns = _namespaces.putIfAbsent(namespace, () => {}); 167 | ns[codeUnitID] = codeUnitData; 168 | } 169 | 170 | @override 171 | Map> allEntries() { 172 | return _namespaces.map((k, v) => MapEntry(k, Map.from(v))); 173 | } 174 | } 175 | -------------------------------------------------------------------------------- /lib/src/apollovm_generated_output.dart: -------------------------------------------------------------------------------- 1 | // Copyright © 2020 Graciliano M. P. All rights reserved. 2 | // This code is governed by the Apache License, Version 2.0. 3 | // Please refer to the LICENSE and AUTHORS files for details. 4 | 5 | import 'dart:typed_data'; 6 | 7 | import 'package:data_serializer/data_serializer.dart'; 8 | 9 | /// Base class for code generation output. 10 | mixin GeneratedOutput { 11 | void writeAll(Iterable list) { 12 | for (var e in list) { 13 | write(e); 14 | } 15 | } 16 | 17 | void write(T o); 18 | 19 | O output(); 20 | } 21 | 22 | /// Generated Bytes. 23 | /// - [toString] will show bytes description. 24 | class BytesOutput extends BytesEmitter 25 | implements GeneratedOutput> { 26 | BytesOutput({super.data, super.description}); 27 | } 28 | -------------------------------------------------------------------------------- /lib/src/apollovm_parser.dart: -------------------------------------------------------------------------------- 1 | // Copyright © 2020 Graciliano M. P. All rights reserved. 2 | // This code is governed by the Apache License, Version 2.0. 3 | // Please refer to the LICENSE and AUTHORS files for details. 4 | 5 | import 'package:petitparser/petitparser.dart'; 6 | import 'package:swiss_knife/swiss_knife.dart'; 7 | 8 | import 'apollovm_base.dart'; 9 | import 'ast/apollovm_ast_toplevel.dart'; 10 | 11 | /// Base class for [ApolloVM] parsers. 12 | abstract class ApolloCodeParser { 13 | /// The language of this parser. 14 | String get language; 15 | 16 | /// Parses a [codeUnit] to an [ASTRoot] and returns a [ParseResult]. 17 | /// 18 | /// If some error occurs, returns a [ParseResult] with an error message. 19 | Future> parse(CodeUnit codeUnit); 20 | 21 | void check(CodeUnit codeUnit) { 22 | if (!acceptsLanguage(codeUnit.language)) { 23 | throw StateError( 24 | "This parser is for the language '$language'. Trying to parse a CodeUnit of language: '${codeUnit.language}'"); 25 | } 26 | } 27 | 28 | bool acceptsLanguage(String language) { 29 | return this.language == language; 30 | } 31 | } 32 | 33 | /// Base class for [ApolloVM] source code parsers. 34 | abstract class ApolloSourceCodeParser extends ApolloCodeParser { 35 | /// The [GrammarDefinition] of this parser. 36 | final GrammarDefinition _grammar; 37 | 38 | ApolloSourceCodeParser(this._grammar); 39 | 40 | Parser? _grammarParserInstance; 41 | 42 | Parser get _grammarParser { 43 | _grammarParserInstance ??= _grammar.build(); 44 | return _grammarParserInstance!; 45 | } 46 | 47 | /// Parses a [codeUnit] to an [ASTRoot] and returns a [ParseResult]. 48 | /// 49 | /// If some error occurs, returns a [ParseResult] with an error message. 50 | @override 51 | Future> parse(CodeUnit codeUnit) async { 52 | check(codeUnit); 53 | 54 | var result = _grammarParser.parse(codeUnit.code); 55 | 56 | if (result is! Success) { 57 | var lineAndColumn = result 58 | .toPositionString() 59 | .split(':') 60 | .map((e) => parseInt(e)!) 61 | .toList(); 62 | 63 | return ParseResult(codeUnit, 64 | errorMessage: result.message, 65 | errorPosition: result.position, 66 | errorLineAndColumn: lineAndColumn); 67 | } 68 | 69 | var root = result.value; 70 | return ParseResult(codeUnit, root: root); 71 | } 72 | } 73 | 74 | class ParseResult { 75 | /// The parsed code. 76 | final CodeUnit codeUnit; 77 | 78 | /// The parsed [codeUnit] code. 79 | T get source => codeUnit.code; 80 | 81 | /// A parsed [ASTRoot] 82 | final ASTRoot? root; 83 | 84 | /// The error message if some parsing error occurred. 85 | final String? errorMessage; 86 | 87 | /// The position of the error in the [codeUnit] [source]. 88 | final int? errorPosition; 89 | 90 | /// The line and column of the error in the [codeUnit] [source]. 91 | final List? errorLineAndColumn; 92 | 93 | /// Returns true if this parse result is OK. 94 | bool get isOK => root != null; 95 | 96 | /// Returns true if this parse result has errors. 97 | bool get hasError => root == null; 98 | 99 | /// The error line at [codeUnit]. 100 | String? get errorLine { 101 | var lineAndColumn = errorLineAndColumn; 102 | if (lineAndColumn != null && lineAndColumn.isNotEmpty) { 103 | final codeUnit = this.codeUnit; 104 | if (codeUnit is SourceCodeUnit) { 105 | var sourceCodeUnit = codeUnit as SourceCodeUnit; 106 | return sourceCodeUnit.getLine(lineAndColumn[0]); 107 | } 108 | } 109 | 110 | return null; 111 | } 112 | 113 | ParseResult(this.codeUnit, 114 | {this.root, 115 | this.errorMessage, 116 | this.errorPosition, 117 | this.errorLineAndColumn}); 118 | 119 | /// Returns the [errorMessage] with the error line information. 120 | String get errorMessageExtended { 121 | final errorLine = this.errorLine; 122 | 123 | if (errorLine != null && errorLine.isNotEmpty) { 124 | final errorLineAndColumn = this.errorLineAndColumn; 125 | 126 | if (errorLineAndColumn != null && errorLineAndColumn.length >= 2) { 127 | var line = errorLineAndColumn[0].toString(); 128 | var column = errorLineAndColumn[1]; 129 | 130 | var errorCursor = column < 0 131 | ? '' 132 | : '\n${' '.padLeft(line.length)} ${'^'.padLeft(column)}'; 133 | 134 | return "$errorMessage @$errorPosition$errorLineAndColumn:\n$line>$errorLine$errorCursor"; 135 | } else { 136 | return "$errorMessage @$errorPosition$errorLineAndColumn:\n$errorLine"; 137 | } 138 | } else { 139 | return "$errorMessage @$errorPosition$errorLineAndColumn"; 140 | } 141 | } 142 | 143 | @override 144 | String toString() { 145 | if (isOK) { 146 | return 'ParseResult[OK]: $root'; 147 | } else { 148 | return 'ParseResult[ERROR]: $errorMessageExtended'; 149 | } 150 | } 151 | } 152 | 153 | /// Syntax [Error] while parsing. 154 | class SyntaxError extends Error { 155 | final String message; 156 | 157 | final ParseResult? parseResult; 158 | 159 | SyntaxError(this.message, {this.parseResult}); 160 | 161 | @override 162 | String toString() { 163 | return '[SyntaxError] $message'; 164 | } 165 | } 166 | 167 | /// Unsupported type [Error] while parsing. 168 | class UnsupportedTypeError extends UnsupportedError { 169 | UnsupportedTypeError(String message) : super('[Unsupported Type] $message'); 170 | } 171 | 172 | /// Unsupported syntax [Error] while parsing. 173 | class UnsupportedSyntaxError extends UnsupportedError { 174 | UnsupportedSyntaxError(String message) 175 | : super('[Unsupported Syntax] $message'); 176 | } 177 | 178 | /// Unsupported value operation [Error] while parsing. 179 | class UnsupportedValueOperationError extends UnsupportedError { 180 | UnsupportedValueOperationError(String message) 181 | : super('[Unsupported Value operation] $message'); 182 | } 183 | 184 | extension ListTypedExtension on List { 185 | /// Provide access to the generic type at runtime. 186 | Type get genericType => T; 187 | } 188 | -------------------------------------------------------------------------------- /lib/src/apollovm_runner.dart: -------------------------------------------------------------------------------- 1 | // Copyright © 2020 Graciliano M. P. All rights reserved. 2 | // This code is governed by the Apache License, Version 2.0. 3 | // Please refer to the LICENSE and AUTHORS files for details. 4 | 5 | import 'package:async_extension/async_extension.dart'; 6 | 7 | import 'apollovm_base.dart'; 8 | import 'ast/apollovm_ast_toplevel.dart'; 9 | import 'ast/apollovm_ast_type.dart'; 10 | import 'ast/apollovm_ast_value.dart'; 11 | 12 | @Deprecated("Renamed to `ApolloRunner`") 13 | typedef ApolloLanguageRunner = ApolloRunner; 14 | 15 | /// Base class for [ApolloVM] runners. 16 | /// 17 | /// Implementations of this class allows the execution of an [ASTRoot] 18 | /// in a specific [language]. 19 | abstract class ApolloRunner implements VMTypeResolver { 20 | /// The [ApolloVM] of this runner. 21 | final ApolloVM apolloVM; 22 | 23 | /// The target programing language of this runner. 24 | String get language; 25 | 26 | late LanguageNamespaces _languageNamespaces; 27 | 28 | ApolloExternalFunctionMapper? externalFunctionMapper; 29 | 30 | ApolloRunner(this.apolloVM) { 31 | _languageNamespaces = apolloVM.getLanguageNamespaces(language); 32 | externalFunctionMapper = createDefaultApolloExternalFunctionMapper(); 33 | } 34 | 35 | /// Returns a copy of this instance. 36 | ApolloRunner copy(); 37 | 38 | /// The default [ApolloExternalFunctionMapper] for this target language runner. 39 | /// 40 | /// Useful to mimic the behavior of the target language runtime. 41 | ApolloExternalFunctionMapper? createDefaultApolloExternalFunctionMapper() { 42 | var externalFunctionMapper = ApolloExternalFunctionMapper(); 43 | 44 | externalFunctionMapper.mapExternalFunction1(ASTTypeVoid.instance, 'print', 45 | ASTTypeObject.instance, 'o', (o) => externalPrintFunction(o)); 46 | 47 | return externalFunctionMapper; 48 | } 49 | 50 | /// The external [print] function to map. 51 | /// 52 | /// Can be overwritten by any kind of function. 53 | void Function(Object? o) externalPrintFunction = print; 54 | 55 | /// Executes a class method. 56 | /// 57 | /// - [namespace] Namespace/package of the target class. 58 | /// - [className] Name of the target class. 59 | /// - [methodName] Name of the target method. 60 | /// - [positionalParameters] Positional parameters to pass to the method. 61 | /// - [namedParameters] Named parameters to pass to the method. 62 | FutureOr executeClassMethod( 63 | String namespace, String className, String methodName, 64 | {List? positionalParameters, 65 | Map? namedParameters, 66 | VMObject? classInstanceObject, 67 | Map? classInstanceFields}) async { 68 | var codeNamespace = _languageNamespaces.get(namespace); 69 | 70 | var codeUnit = codeNamespace.getCodeUnitWithClass(className); 71 | if (codeUnit == null) { 72 | throw StateError("Can't find class to execute: $className->$methodName"); 73 | } 74 | 75 | var clazz = codeUnit.root!.getClass(className); 76 | if (clazz == null) { 77 | throw StateError( 78 | "Can't find class method to execute: $className->$methodName"); 79 | } 80 | 81 | var result = await clazz.execute( 82 | methodName, positionalParameters, namedParameters, 83 | classInstanceObject: classInstanceObject, 84 | classInstanceFields: classInstanceFields, 85 | externalFunctionMapper: externalFunctionMapper, 86 | typeResolver: this); 87 | return result; 88 | } 89 | 90 | /// Returns an [ASTClassNormal] for [className] in [namespace] (optional). 91 | FutureOr getClass(String className, 92 | {String? namespace, bool caseInsensitive = false}) { 93 | return _languageNamespaces.getClass(className, 94 | namespace: namespace, caseInsensitive: caseInsensitive); 95 | } 96 | 97 | /// Returns a class method. 98 | /// 99 | /// - [positionalParameters] and [namedParameters] are used to 100 | /// determine the method parameters signature. 101 | FutureOr getClassMethod( 102 | String namespace, String className, String methodName, 103 | [dynamic positionalParameters, dynamic namedParameters]) async { 104 | var clazz = await getClass(className, namespace: namespace); 105 | if (clazz == null) return null; 106 | 107 | return clazz.getFunctionWithParameters( 108 | methodName, positionalParameters, namedParameters, 109 | externalFunctionMapper: externalFunctionMapper, typeResolver: this); 110 | } 111 | 112 | FutureOr<({CodeUnit? codeUnit, String? className})> getFunctionCodeUnit( 113 | String namespace, String functionName, 114 | {bool allowClassMethod = false}) { 115 | var codeNamespace = _languageNamespaces.get(namespace); 116 | 117 | var codeUnit = codeNamespace.getCodeUnitWithFunction(functionName); 118 | 119 | if (codeUnit == null && allowClassMethod) { 120 | var codeUnitWithMethod = 121 | codeNamespace.getCodeUnitWithClassMethod(functionName); 122 | 123 | if (codeUnitWithMethod != null) { 124 | var classWithMethod = 125 | codeUnitWithMethod.root?.getClassWithMethod(functionName); 126 | 127 | if (classWithMethod != null) { 128 | return ( 129 | codeUnit: codeUnitWithMethod, 130 | className: classWithMethod.name, 131 | ); 132 | } 133 | } 134 | } 135 | 136 | return (codeUnit: codeUnit, className: null); 137 | } 138 | 139 | /// Executes a function in [namespace] and with name [functionName]. 140 | /// 141 | /// - [positionalParameters] Positional parameters to pass to the function. 142 | /// - [namedParameters] Named parameters to pass to the function. 143 | Future executeFunction(String namespace, String functionName, 144 | {List? positionalParameters, 145 | Map? namedParameters, 146 | bool allowClassMethod = false}) async { 147 | var r = await getFunctionCodeUnit(namespace, functionName, 148 | allowClassMethod: allowClassMethod); 149 | 150 | var codeUnit = r.codeUnit; 151 | if (codeUnit == null) { 152 | throw StateError( 153 | "Can't find function to execute> functionName: $functionName ; language: $language"); 154 | } 155 | 156 | var className = r.className; 157 | if (className != null) { 158 | return executeClassMethod(namespace, className, functionName, 159 | positionalParameters: positionalParameters, 160 | namedParameters: namedParameters); 161 | } 162 | 163 | var result = await codeUnit.root!.execute( 164 | functionName, positionalParameters, namedParameters, 165 | externalFunctionMapper: externalFunctionMapper, typeResolver: this); 166 | 167 | return result; 168 | } 169 | 170 | /// Returns a function in [namespace] and with name [functionName]. 171 | /// 172 | /// - [positionalParameters] and [namedParameters] are used to 173 | /// determine the function parameters signature. 174 | FutureOr getFunction( 175 | String namespace, String functionName, 176 | [List? positionalParameters, Map? namedParameters]) async { 177 | var codeNamespace = _languageNamespaces.get(namespace); 178 | 179 | var codeUnit = codeNamespace.getCodeUnitWithFunction(functionName); 180 | if (codeUnit == null) return null; 181 | 182 | return await codeUnit.root!.getFunctionWithParameters( 183 | functionName, positionalParameters, namedParameters, 184 | externalFunctionMapper: externalFunctionMapper, typeResolver: this); 185 | } 186 | 187 | /// Tries to execute a function with variations of [positionalParameters]. 188 | Future tryExecuteFunction(String namespace, String functionName, 189 | [List? positionalParameters]) async { 190 | positionalParameters ??= []; 191 | 192 | if (await getFunction(namespace, functionName, positionalParameters) != 193 | null) { 194 | return await executeFunction(namespace, functionName, 195 | positionalParameters: positionalParameters); 196 | } else if (await getFunction( 197 | namespace, functionName, [positionalParameters]) != 198 | null) { 199 | return await executeFunction(namespace, functionName, 200 | positionalParameters: [positionalParameters]); 201 | } else if (await getFunction( 202 | namespace, functionName, [ASTTypeArray.instanceOfString]) != 203 | null) { 204 | return await executeFunction(namespace, functionName, 205 | positionalParameters: [ 206 | positionalParameters.map((e) => '$e').toList() 207 | ]); 208 | } else if (await getFunction( 209 | namespace, functionName, [ASTTypeArray.instanceOfDynamic]) != 210 | null) { 211 | return await executeFunction(namespace, functionName, 212 | positionalParameters: [positionalParameters]); 213 | } 214 | return null; 215 | } 216 | 217 | /// Tries to execute a class function with variations of [positionalParameters]. 218 | Future tryExecuteClassFunction( 219 | String namespace, String className, String functionName, 220 | [List? positionalParameters]) async { 221 | positionalParameters ??= []; 222 | 223 | if (await getClassMethod( 224 | namespace, className, functionName, positionalParameters) != 225 | null) { 226 | return await executeClassMethod(namespace, className, functionName, 227 | positionalParameters: positionalParameters); 228 | } else if (await getClassMethod( 229 | namespace, className, functionName, [positionalParameters]) != 230 | null) { 231 | return await executeClassMethod(namespace, className, functionName, 232 | positionalParameters: [positionalParameters]); 233 | } else if (await getClassMethod(namespace, className, functionName, 234 | [ASTTypeArray.instanceOfString]) != 235 | null) { 236 | return await executeClassMethod(namespace, className, functionName, 237 | positionalParameters: [ 238 | positionalParameters.map((e) => '$e').toList() 239 | ]); 240 | } else if (await getClassMethod(namespace, className, functionName, 241 | [ASTTypeArray.instanceOfDynamic]) != 242 | null) { 243 | return await executeClassMethod(namespace, className, functionName, 244 | positionalParameters: [positionalParameters]); 245 | } 246 | return null; 247 | } 248 | 249 | @override 250 | FutureOr resolveType(String typeName, 251 | {String? namespace, String? language, bool caseInsensitive = false}) { 252 | if (language != null) { 253 | if (this.language == language) { 254 | var ret = getClass(typeName, 255 | namespace: namespace, caseInsensitive: caseInsensitive); 256 | 257 | return ret.resolveMapped((clazz) => 258 | clazz?.type ?? 259 | apolloVM.resolveCoreType(typeName, 260 | namespace: namespace, 261 | language: language, 262 | caseInsensitive: caseInsensitive)); 263 | } 264 | } 265 | 266 | return apolloVM.resolveType(typeName, 267 | namespace: namespace, 268 | language: language, 269 | caseInsensitive: caseInsensitive); 270 | } 271 | 272 | void reset() { 273 | externalFunctionMapper = createDefaultApolloExternalFunctionMapper(); 274 | } 275 | 276 | @override 277 | String toString() { 278 | return 'ApolloRunner{ language: $language, apolloVM: $apolloVM }'; 279 | } 280 | } 281 | -------------------------------------------------------------------------------- /lib/src/ast/apollovm_ast_annotation.dart: -------------------------------------------------------------------------------- 1 | // Copyright © 2020 Graciliano M. P. All rights reserved. 2 | // This code is governed by the Apache License, Version 2.0. 3 | // Please refer to the LICENSE and AUTHORS files for details. 4 | 5 | import 'apollovm_ast_base.dart'; 6 | 7 | class ASTAnnotation with ASTNode { 8 | String name; 9 | 10 | Map? parameters; 11 | 12 | ASTAnnotation(this.name, [this.parameters]); 13 | 14 | @override 15 | Iterable get children => [...?parameters?.values]; 16 | 17 | ASTNode? _parentNode; 18 | 19 | @override 20 | ASTNode? get parentNode => _parentNode; 21 | 22 | @override 23 | void resolveNode(ASTNode? parentNode) { 24 | _parentNode = parentNode; 25 | 26 | cacheDescendantChildren(); 27 | } 28 | 29 | @override 30 | ASTNode? getNodeIdentifier(String name, {ASTNode? requester}) => 31 | parentNode?.getNodeIdentifier(name, requester: requester); 32 | } 33 | 34 | class ASTAnnotationParameter with ASTNode { 35 | String name; 36 | 37 | String value; 38 | 39 | bool defaultParameter; 40 | 41 | ASTAnnotationParameter(this.name, this.value, 42 | [this.defaultParameter = false]); 43 | 44 | @override 45 | Iterable get children => []; 46 | 47 | ASTNode? _parentNode; 48 | 49 | @override 50 | ASTNode? get parentNode => _parentNode; 51 | 52 | @override 53 | void resolveNode(ASTNode? parentNode) { 54 | _parentNode = parentNode; 55 | 56 | cacheDescendantChildren(); 57 | } 58 | 59 | @override 60 | ASTNode? getNodeIdentifier(String name, {ASTNode? requester}) => 61 | parentNode?.getNodeIdentifier(name, requester: requester); 62 | } 63 | -------------------------------------------------------------------------------- /lib/src/ast/apollovm_ast_base.dart: -------------------------------------------------------------------------------- 1 | // Copyright © 2020 Graciliano M. P. All rights reserved. 2 | // This code is governed by the Apache License, Version 2.0. 3 | // Please refer to the LICENSE and AUTHORS files for details. 4 | 5 | import 'dart:async'; 6 | import 'dart:collection'; 7 | 8 | import '../apollovm_base.dart'; 9 | import 'apollovm_ast_type.dart'; 10 | import 'apollovm_ast_value.dart'; 11 | 12 | /// An AST (Abstract Syntax Tree) Node. 13 | abstract mixin class ASTNode { 14 | ASTNode? get parentNode; 15 | 16 | void resolveNode(ASTNode? parentNode); 17 | 18 | ASTNode? getNodeIdentifier(String name, {ASTNode? requester}) => 19 | parentNode?.getNodeIdentifier(name, requester: requester); 20 | 21 | /// The children nodes of this node. 22 | Iterable get children; 23 | 24 | UnmodifiableListView? _descendantChildren; 25 | 26 | /// Return the [children] and it's descendant children (unmodifiable). 27 | List get descendantChildren { 28 | var descendantChildren = _descendantChildren; 29 | if (descendantChildren != null) return descendantChildren; 30 | 31 | if (_cacheDescendantChildren) { 32 | return _descendantChildren = 33 | UnmodifiableListView(_computeDescendantChildren()); 34 | } else { 35 | return _computeDescendantChildren(); 36 | } 37 | } 38 | 39 | bool _cacheDescendantChildren = false; 40 | 41 | /// Mark that this node can cache its [descendantChildren]. 42 | void cacheDescendantChildren() { 43 | _cacheDescendantChildren = true; 44 | } 45 | 46 | /// Compute [descendantChildren] in DFS order. 47 | List _computeDescendantChildren() { 48 | final processed = {}; 49 | final queue = ListQueue()..add(this); 50 | 51 | while (queue.isNotEmpty) { 52 | var node = queue.removeFirst(); 53 | 54 | if (processed.add(node)) { 55 | var children = node.children.toList(growable: false); 56 | 57 | for (var e in children.reversed) { 58 | queue.addFirst(e); 59 | } 60 | } 61 | } 62 | 63 | processed.remove(this); 64 | 65 | return processed.toList(); 66 | } 67 | } 68 | 69 | /// The runtime status of execution. 70 | /// 71 | /// Used to indicate: 72 | /// - If a function have returned. 73 | /// - If a loop have continued or broke. 74 | class ASTRunStatus { 75 | static final ASTRunStatus dummy = ASTRunStatus(); 76 | 77 | bool returned = false; 78 | 79 | ASTValue? returnedValue; 80 | FutureOr? returnedFutureValue; 81 | 82 | ASTValueVoid returnVoid() { 83 | returned = true; 84 | returnedValue = ASTValueVoid.instance; 85 | return ASTValueVoid.instance; 86 | } 87 | 88 | ASTValueNull returnNull() { 89 | returned = true; 90 | returnedValue = ASTValueNull.instance; 91 | return ASTValueNull.instance; 92 | } 93 | 94 | ASTValue returnValue(ASTValue value) { 95 | returned = true; 96 | returnedValue = value; 97 | return value; 98 | } 99 | 100 | FutureOr returnFutureOrValue(FutureOr futureValue) { 101 | returned = true; 102 | returnedFutureValue = futureValue; 103 | return futureValue; 104 | } 105 | 106 | /// Returns true if some statement demands continue of loop (next iteration). 107 | bool continued = false; 108 | 109 | /// Returns true if some statement demands loop interruption (break). 110 | bool broke = false; 111 | } 112 | 113 | abstract class ASTTypedNode { 114 | FutureOr resolveType(VMContext? context); 115 | 116 | void associateToType(ASTTypedNode node) {} 117 | } 118 | 119 | /// An AST that can be [run]. 120 | abstract class ASTCodeRunner extends ASTTypedNode { 121 | VMContext defineRunContext(VMContext parentContext) { 122 | return parentContext; 123 | } 124 | 125 | FutureOr run(VMContext parentContext, ASTRunStatus runStatus); 126 | } 127 | 128 | /// Modifiers of an [ASTNode] element. 129 | class ASTModifiers { 130 | static final ASTModifiers modifiersNone = ASTModifiers(); 131 | static final ASTModifiers modifierStatic = ASTModifiers(isStatic: true); 132 | static final ASTModifiers modifierFinal = ASTModifiers(isFinal: true); 133 | static final ASTModifiers modifiersStaticFinal = 134 | ASTModifiers(isStatic: true, isFinal: true); 135 | 136 | final bool isStatic; 137 | 138 | final bool isFinal; 139 | 140 | final bool isPrivate; 141 | 142 | final bool isPublic; 143 | 144 | ASTModifiers( 145 | {this.isStatic = false, 146 | this.isFinal = false, 147 | this.isPrivate = false, 148 | this.isPublic = false}) { 149 | if (isPrivate && isPublic) { 150 | throw StateError("Can't be private and public at the same time!"); 151 | } 152 | } 153 | 154 | ASTModifiers copyWith( 155 | {bool? isStatic, bool? isFinal, bool? isPrivate, bool? isPublic}) { 156 | return ASTModifiers( 157 | isStatic: isStatic ?? this.isStatic, 158 | isFinal: isFinal ?? this.isFinal, 159 | isPrivate: isPrivate ?? this.isPrivate, 160 | isPublic: isPublic ?? this.isPublic, 161 | ); 162 | } 163 | 164 | List get modifiers => [ 165 | if (isPublic) 'public', 166 | if (isPrivate) 'private', 167 | if (isStatic) 'static', 168 | if (isFinal) 'final', 169 | ]; 170 | 171 | @override 172 | String toString() { 173 | return modifiers.join(' '); 174 | } 175 | } 176 | -------------------------------------------------------------------------------- /lib/src/ast/apollovm_ast_variable.dart: -------------------------------------------------------------------------------- 1 | // Copyright © 2020 Graciliano M. P. All rights reserved. 2 | // This code is governed by the Apache License, Version 2.0. 3 | // Please refer to the LICENSE and AUTHORS files for details. 4 | 5 | import 'package:async_extension/async_extension.dart'; 6 | 7 | import '../apollovm_base.dart'; 8 | import 'apollovm_ast_base.dart'; 9 | import 'apollovm_ast_expression.dart'; 10 | import 'apollovm_ast_statement.dart'; 11 | import 'apollovm_ast_toplevel.dart'; 12 | import 'apollovm_ast_type.dart'; 13 | import 'apollovm_ast_value.dart'; 14 | 15 | /// Base class for variable reference. 16 | abstract class ASTVariable with ASTNode implements ASTTypedNode { 17 | final String name; 18 | 19 | ASTVariable(this.name); 20 | 21 | bool get isTypeIdentifier => false; 22 | 23 | ASTType? get typeIdentifier => null; 24 | 25 | @override 26 | void associateToType(ASTTypedNode node) {} 27 | 28 | FutureOr resolveVariable(VMContext context); 29 | 30 | FutureOr getValue(VMContext context) { 31 | var variable = resolveVariable(context); 32 | return variable.resolveMapped((v) => v.getValue(context)); 33 | } 34 | 35 | FutureOr setValue(VMContext context, ASTValue value) { 36 | return resolveVariable(context).resolveMapped((variable) { 37 | variable.setValue(context, value); 38 | }); 39 | } 40 | 41 | FutureOr readIndex(VMContext context, int index) { 42 | return getValue(context).resolveMapped((value) { 43 | return value.readIndex(context, index); 44 | }); 45 | } 46 | 47 | FutureOr readKey(VMContext context, Object key) { 48 | return getValue(context).resolveMapped((value) { 49 | return value.readKey(context, key); 50 | }); 51 | } 52 | 53 | ASTNode? _parentNode; 54 | 55 | @override 56 | ASTNode? get parentNode => _parentNode; 57 | 58 | @override 59 | void resolveNode(ASTNode? parentNode) { 60 | _parentNode = parentNode; 61 | 62 | cacheDescendantChildren(); 63 | } 64 | 65 | @override 66 | ASTNode? getNodeIdentifier(String name, {ASTNode? requester}) => 67 | parentNode?.getNodeIdentifier(name, requester: requester); 68 | 69 | @override 70 | String toString() { 71 | return name; 72 | } 73 | } 74 | 75 | /// [ASTVariable] with [type]. 76 | abstract class ASTTypedVariable extends ASTVariable { 77 | ASTType type; 78 | final bool finalValue; 79 | 80 | ASTTypedVariable(this.type, String name, this.finalValue) : super(name); 81 | 82 | @override 83 | ASTType resolveType(VMContext? context) => type; 84 | 85 | @override 86 | void resolveNode(ASTNode? parentNode) { 87 | super.resolveNode(parentNode); 88 | 89 | type.resolveNode(parentNode); 90 | } 91 | 92 | @override 93 | String toString() { 94 | return '$type $name'; 95 | } 96 | } 97 | 98 | /// [ASTVariable] for class fields. 99 | class ASTClassField extends ASTTypedVariable { 100 | ASTClassField(super.type, super.name, super.finalValue); 101 | 102 | @override 103 | Iterable get children => []; 104 | 105 | @override 106 | ASTVariable resolveVariable(VMContext context) { 107 | var variable = context.getField(name); 108 | if (variable == null) { 109 | throw StateError("Can't find Class field: $name"); 110 | } 111 | return variable; 112 | } 113 | } 114 | 115 | /// [ASTVariable] for class fields with initial values. 116 | class ASTClassFieldWithInitialValue extends ASTClassField { 117 | final ASTExpression _initialValueExpression; 118 | 119 | ASTClassFieldWithInitialValue(ASTType type, String name, 120 | this._initialValueExpression, bool finalValue) 121 | : super(type, name, finalValue); 122 | 123 | ASTExpression get initialValue => _initialValueExpression; 124 | 125 | FutureOr getInitialValue( 126 | VMContext context, ASTRunStatus runStatus) { 127 | return _initialValueExpression.run(context, runStatus); 128 | } 129 | 130 | FutureOr getInitialValueNoContext() { 131 | var context = VMContext(ASTBlock(null)); 132 | var runStatus = ASTRunStatus(); 133 | return _initialValueExpression.run(context, runStatus); 134 | } 135 | } 136 | 137 | /// [ASTVariable] for a runtime value. 138 | /// 139 | /// Used to represent a resolved variable at runtime. 140 | class ASTRuntimeVariable extends ASTTypedVariable { 141 | ASTValue _value; 142 | 143 | ASTRuntimeVariable(ASTType type, String name, [ASTValue? value]) 144 | : _value = value ?? ASTValueNull.instance, 145 | super(type, name, false); 146 | 147 | @override 148 | Iterable get children => [_value]; 149 | 150 | @override 151 | void resolveNode(ASTNode? parentNode) { 152 | super.resolveNode(parentNode); 153 | 154 | _value.resolveNode(parentNode); 155 | } 156 | 157 | @override 158 | ASTType resolveType(VMContext? context) { 159 | if (type is ASTTypeVar) { 160 | var t = _value.resolveType(context); 161 | if (t is ASTType) { 162 | return t; 163 | } 164 | return _value.type; 165 | } 166 | 167 | return type; 168 | } 169 | 170 | @override 171 | ASTVariable resolveVariable(VMContext context) { 172 | return this; 173 | } 174 | 175 | @override 176 | ASTValue getValue(VMContext context) { 177 | return _value; 178 | } 179 | 180 | @override 181 | void setValue(VMContext context, ASTValue value) { 182 | _value = value; 183 | } 184 | 185 | @override 186 | String toString() { 187 | return 'ASTRuntimeVariable{value: $_value}'; 188 | } 189 | } 190 | 191 | /// [ASTVariable] for a variable visible in a scope context. 192 | class ASTScopeVariable extends ASTVariable { 193 | ASTScopeVariable(super.name); 194 | 195 | @override 196 | Iterable get children => []; 197 | 198 | @override 199 | FutureOr resolveType(VMContext? context) { 200 | final associatedNode = _associatedNode; 201 | 202 | if (associatedNode != null) { 203 | return associatedNode.resolveType(context); 204 | } 205 | 206 | if (context == null) { 207 | var parentNode = _parentNode; 208 | if (parentNode != null) { 209 | var node = parentNode.getNodeIdentifier(name, requester: this); 210 | 211 | if (node is ASTTypedNode) { 212 | var typedNode = node as ASTTypedNode; 213 | var t = typedNode.resolveType(null); 214 | if (t is ASTType) return t; 215 | } 216 | } 217 | 218 | return ASTTypeDynamic.instance; 219 | } 220 | 221 | return context.getVariable(name, false).resolveMapped((variable) { 222 | return variable?.resolveType(context) ?? ASTTypeDynamic.instance; 223 | }); 224 | } 225 | 226 | ASTTypedNode? _associatedNode; 227 | 228 | @override 229 | void associateToType(ASTTypedNode node) => _associatedNode = node; 230 | 231 | @override 232 | FutureOr resolveVariable(VMContext context) { 233 | var variable = context.getVariable(name, true); 234 | 235 | return variable.resolveMapped((v) { 236 | if (v == null) { 237 | var typeResolver = context.typeResolver; 238 | var resolveType = typeResolver.resolveType(name); 239 | return resolveType.resolveMapped((t) { 240 | if (t != null) { 241 | var staticAccessor = t.getClass().staticAccessor; 242 | return staticAccessor.staticClassAccessorVariable; 243 | } 244 | throw StateError("Can't find variable: '$name'"); 245 | }); 246 | } 247 | return v; 248 | }); 249 | } 250 | 251 | ASTNode? resolvedIdentifier; 252 | 253 | @override 254 | void resolveNode(ASTNode? parentNode) { 255 | super.resolveNode(parentNode); 256 | 257 | resolvedIdentifier = 258 | this.parentNode!.getNodeIdentifier(name, requester: this); 259 | } 260 | 261 | @override 262 | bool get isTypeIdentifier => resolvedIdentifier is ASTClass; 263 | 264 | @override 265 | ASTType? get typeIdentifier { 266 | var resolvedIdentifier = this.resolvedIdentifier; 267 | return resolvedIdentifier is ASTClass ? resolvedIdentifier.type : null; 268 | } 269 | } 270 | 271 | /// [ASTVariable] for `this`/`self` reference. 272 | class ASTThisVariable extends ASTVariable { 273 | ASTThisVariable() : super('this'); 274 | 275 | @override 276 | Iterable get children => []; 277 | 278 | @override 279 | FutureOr resolveType(VMContext? context) { 280 | if (context is VMClassContext) { 281 | return context.clazz.type; 282 | } 283 | 284 | final associatedNode = _associatedNode; 285 | 286 | return associatedNode == null 287 | ? ASTTypeDynamic.instance 288 | : associatedNode.resolveType(context); 289 | } 290 | 291 | ASTTypedNode? _associatedNode; 292 | 293 | @override 294 | void associateToType(ASTTypedNode node) => _associatedNode = node; 295 | 296 | @override 297 | ASTVariable resolveVariable(VMContext context) { 298 | var obj = context.getClassInstance(); 299 | if (obj == null) { 300 | throw ApolloVMRuntimeError( 301 | "Can't determine 'this'! No ASTObjectInstance defined!"); 302 | } 303 | return ASTRuntimeVariable(obj.type, 'this', obj); 304 | } 305 | } 306 | 307 | /// [ASTVariable] for `static` reference. 308 | class ASTStaticClassAccessorVariable extends ASTVariable { 309 | final ASTClass clazz; 310 | late final ASTClassStaticAccessor, T> staticAccessor; 311 | 312 | ASTStaticClassAccessorVariable(this.clazz) : super(clazz.name); 313 | 314 | @override 315 | Iterable get children => [staticAccessor]; 316 | 317 | void setAccessor(ASTClassStaticAccessor, T> accessor) { 318 | staticAccessor = accessor; 319 | } 320 | 321 | @override 322 | FutureOr resolveType(VMContext? context) { 323 | return clazz.type; 324 | } 325 | 326 | @override 327 | ASTVariable resolveVariable(VMContext context) => this; 328 | 329 | @override 330 | FutureOr getValue(VMContext context) { 331 | return staticAccessor; 332 | } 333 | } 334 | -------------------------------------------------------------------------------- /lib/src/core/apollovm_core_base.dart: -------------------------------------------------------------------------------- 1 | // Copyright © 2020 Graciliano M. P. All rights reserved. 2 | // This code is governed by the Apache License, Version 2.0. 3 | // Please refer to the LICENSE and AUTHORS files for details. 4 | 5 | import 'package:swiss_knife/swiss_knife.dart'; 6 | 7 | import '../apollovm_base.dart'; 8 | import '../ast/apollovm_ast_toplevel.dart'; 9 | import '../ast/apollovm_ast_type.dart'; 10 | import '../ast/apollovm_ast_value.dart'; 11 | 12 | class ApolloVMCore { 13 | static ASTClass? getClass(String className) { 14 | switch (className) { 15 | case 'String': 16 | return CoreClassString.instance as ASTClass; 17 | case 'int': 18 | case 'Integer': 19 | return CoreClassInt.instance as ASTClass; 20 | default: 21 | return null; 22 | } 23 | } 24 | } 25 | 26 | abstract class CoreClassPrimitive extends ASTClassPrimitive { 27 | final String coreName; 28 | 29 | CoreClassPrimitive(ASTTypePrimitive type, this.coreName) : super(type) { 30 | type.setClass(this); 31 | } 32 | 33 | ASTExternalClassFunction _externalClassFunctionArgs0( 34 | String name, ASTType returnType, Function externalFunction, 35 | [ParameterValueResolver? parameterValueResolver]) { 36 | return ASTExternalClassFunction( 37 | this, 38 | name, 39 | ASTParametersDeclaration(null, null, null), 40 | returnType, 41 | externalFunction, 42 | parameterValueResolver); 43 | } 44 | 45 | ASTExternalClassFunction _externalClassFunctionArgs1( 46 | String name, 47 | ASTType returnType, 48 | ASTFunctionParameterDeclaration param1, 49 | Function externalFunction, 50 | [ParameterValueResolver? parameterValueResolver]) { 51 | return ASTExternalClassFunction( 52 | this, 53 | name, 54 | ASTParametersDeclaration([param1], null, null), 55 | returnType, 56 | externalFunction, 57 | parameterValueResolver); 58 | } 59 | 60 | // ignore: unused_element 61 | ASTExternalFunction _externalStaticFunctionArgs0( 62 | String name, ASTType returnType, Function externalFunction, 63 | [ParameterValueResolver? parameterValueResolver]) { 64 | return ASTExternalFunction( 65 | name, 66 | ASTParametersDeclaration(null, null, null), 67 | returnType, 68 | externalFunction, 69 | parameterValueResolver); 70 | } 71 | 72 | ASTExternalFunction _externalStaticFunctionArgs1( 73 | String name, 74 | ASTType returnType, 75 | ASTFunctionParameterDeclaration param1, 76 | Function externalFunction, 77 | [ParameterValueResolver? parameterValueResolver]) { 78 | return ASTExternalFunction( 79 | name, 80 | ASTParametersDeclaration([param1], null, null), 81 | returnType, 82 | externalFunction, 83 | parameterValueResolver); 84 | } 85 | } 86 | 87 | class CoreClassString extends CoreClassPrimitive { 88 | static final CoreClassString instance = CoreClassString._(); 89 | 90 | late final ASTExternalClassFunction _functionContains; 91 | 92 | late final ASTExternalClassFunction _functionToUpperCase; 93 | 94 | late final ASTExternalClassFunction _functionToLowerCase; 95 | 96 | late final ASTExternalFunction _functionValueOf; 97 | 98 | CoreClassString._() : super(ASTTypeString.instance, 'String') { 99 | _functionContains = _externalClassFunctionArgs1( 100 | 'contains', 101 | ASTTypeBool.instance, 102 | ASTFunctionParameterDeclaration(ASTTypeString.instance, 's', 0, false), 103 | (String o, String p1) => o.contains(p1), 104 | ); 105 | 106 | _functionToUpperCase = _externalClassFunctionArgs0( 107 | 'toUpperCase', 108 | ASTTypeString.instance, 109 | (String o) => o.toUpperCase(), 110 | ); 111 | 112 | _functionToLowerCase = _externalClassFunctionArgs0( 113 | 'toLowerCase', 114 | ASTTypeString.instance, 115 | (String o) => o.toLowerCase(), 116 | ); 117 | 118 | _functionValueOf = _externalStaticFunctionArgs1( 119 | 'valueOf', 120 | ASTTypeString.instance, 121 | ASTFunctionParameterDeclaration(ASTTypeDynamic.instance, 'obj', 0, false), 122 | (dynamic o) => o?.toString() ?? 'null', 123 | resolveValueToString, 124 | ); 125 | } 126 | 127 | String resolveValueToString(ASTValue? paramVal, VMContext context) { 128 | if (paramVal == null) return 'null'; 129 | 130 | if (paramVal is VMObject) { 131 | return paramVal.toString(); 132 | } 133 | 134 | var val = paramVal.getValue(context); 135 | return '$val'; 136 | } 137 | 138 | @override 139 | ASTFunctionDeclaration? getFunction( 140 | String fName, ASTFunctionSignature parametersSignature, VMContext context, 141 | {bool caseInsensitive = false}) { 142 | switch (fName) { 143 | case 'contains': 144 | return _functionContains; 145 | case 'toUpperCase': 146 | return _functionToUpperCase; 147 | case 'toLowerCase': 148 | return _functionToLowerCase; 149 | case 'valueOf': 150 | return _functionValueOf; 151 | } 152 | throw StateError( 153 | "Can't find core function: $coreName.$fName( $parametersSignature )"); 154 | } 155 | } 156 | 157 | class CoreClassInt extends CoreClassPrimitive { 158 | static final CoreClassInt instance = CoreClassInt._(); 159 | 160 | late final ASTExternalFunction _functionValueOf; 161 | 162 | late final ASTExternalFunction _functionParseInt; 163 | 164 | CoreClassInt._() : super(ASTTypeInt.instance, 'int') { 165 | _functionParseInt = _externalStaticFunctionArgs1( 166 | 'parseInt', 167 | ASTTypeInt.instance, 168 | ASTFunctionParameterDeclaration(ASTTypeString.instance, 's', 0, false), 169 | (dynamic p1) => parseInt(p1), 170 | ); 171 | 172 | _functionValueOf = _externalStaticFunctionArgs1( 173 | 'valueOf', 174 | ASTTypeString.instance, 175 | ASTFunctionParameterDeclaration(ASTTypeDynamic.instance, 'obj', 0, false), 176 | (dynamic o) => '$o', 177 | ); 178 | } 179 | 180 | @override 181 | ASTFunctionDeclaration? getFunction( 182 | String fName, ASTFunctionSignature parametersSignature, VMContext context, 183 | {bool caseInsensitive = false}) { 184 | switch (fName) { 185 | case 'parseInt': 186 | case 'parse': 187 | return _functionParseInt; 188 | case 'valueOf': 189 | return _functionValueOf; 190 | } 191 | throw StateError( 192 | "Can't find core function: $coreName.$fName( $parametersSignature )"); 193 | } 194 | } 195 | -------------------------------------------------------------------------------- /lib/src/languages/dart/dart_parser.dart: -------------------------------------------------------------------------------- 1 | // Copyright © 2020 Graciliano M. P. All rights reserved. 2 | // This code is governed by the Apache License, Version 2.0. 3 | // Please refer to the LICENSE and AUTHORS files for details. 4 | 5 | import '../../apollovm_parser.dart'; 6 | import 'dart_grammar.dart'; 7 | 8 | /// Dart implementation of an [ApolloParser]. 9 | class ApolloParserDart extends ApolloSourceCodeParser { 10 | static final ApolloParserDart instance = ApolloParserDart(); 11 | 12 | ApolloParserDart() : super(DartGrammarDefinition()); 13 | 14 | @override 15 | String get language => 'dart'; 16 | } 17 | -------------------------------------------------------------------------------- /lib/src/languages/dart/dart_runner.dart: -------------------------------------------------------------------------------- 1 | // Copyright © 2020 Graciliano M. P. All rights reserved. 2 | // This code is governed by the Apache License, Version 2.0. 3 | // Please refer to the LICENSE and AUTHORS files for details. 4 | 5 | import '../../apollovm_runner.dart'; 6 | 7 | /// Dart implementation of an [ApolloRunner]. 8 | class ApolloRunnerDart extends ApolloRunner { 9 | ApolloRunnerDart(super.apolloVM); 10 | 11 | @override 12 | String get language => 'dart'; 13 | 14 | @override 15 | ApolloRunnerDart copy() { 16 | return ApolloRunnerDart(apolloVM); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /lib/src/languages/java/java11/java11_grammar_lexer.dart: -------------------------------------------------------------------------------- 1 | // Copyright © 2020 Graciliano M. P. All rights reserved. 2 | // This code is governed by the Apache License, Version 2.0. 3 | // Please refer to the LICENSE and AUTHORS files for details. 4 | 5 | import 'package:petitparser/petitparser.dart'; 6 | 7 | abstract class Java11GrammarLexer extends GrammarDefinition { 8 | Parser token(Object input) { 9 | if (input is Parser) { 10 | return input.token().trim(ref0(hiddenStuffWhitespace)); 11 | } else if (input is String) { 12 | return token(input.toParser()); 13 | } else if (input is Parser Function()) { 14 | return token(ref0(input)); 15 | } 16 | throw ArgumentError.value(input, 'invalid token parser'); 17 | } 18 | 19 | Parser identifier() => 20 | ref1(token, ref0(identifierLexicalToken)).map((t) { 21 | return t is Token ? t.value : '$t'; 22 | }); 23 | 24 | // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file 25 | // for details. All rights reserved. Use of this source code is governed by a 26 | // BSD-style license that can be found in the LICENSE file. 27 | 28 | // ----------------------------------------------------------------- 29 | // Keyword definitions. 30 | // ----------------------------------------------------------------- 31 | Parser breakToken() => ref1(token, 'break'); 32 | 33 | Parser caseToken() => ref1(token, 'case'); 34 | 35 | Parser catchToken() => ref1(token, 'catch'); 36 | 37 | Parser constToken() => ref1(token, 'const'); 38 | 39 | Parser continueToken() => ref1(token, 'continue'); 40 | 41 | Parser defaultToken() => ref1(token, 'default'); 42 | 43 | Parser doToken() => ref1(token, 'do'); 44 | 45 | Parser elseToken() => ref1(token, 'else'); 46 | 47 | Parser falseToken() => ref1(token, 'false'); 48 | 49 | Parser finalToken() => ref1(token, 'final'); 50 | 51 | Parser finallyToken() => ref1(token, 'finally'); 52 | 53 | Parser forToken() => ref1(token, 'for'); 54 | 55 | Parser ifToken() => ref1(token, 'if'); 56 | 57 | Parser inToken() => ref1(token, 'in'); 58 | 59 | Parser newToken() => ref1(token, 'new'); 60 | 61 | Parser nullToken() => ref1(token, 'null'); 62 | 63 | Parser returnToken() => ref1(token, 'return'); 64 | 65 | Parser superToken() => ref1(token, 'super'); 66 | 67 | Parser switchToken() => ref1(token, 'switch'); 68 | 69 | Parser thisToken() => ref1(token, 'this'); 70 | 71 | Parser throwToken() => ref1(token, 'throw'); 72 | 73 | Parser trueToken() => ref1(token, 'true'); 74 | 75 | Parser tryToken() => ref1(token, 'try'); 76 | 77 | Parser varToken() => ref1(token, 'var'); 78 | 79 | Parser voidToken() => ref1(token, 'void'); 80 | 81 | Parser whileToken() => ref1(token, 'while'); 82 | 83 | // Pseudo-keywords that should also be valid identifiers. 84 | Parser abstractToken() => ref1(token, 'abstract'); 85 | 86 | Parser asToken() => ref1(token, 'as'); 87 | 88 | Parser assertToken() => ref1(token, 'assert'); 89 | 90 | Parser classToken() => ref1(token, 'class'); 91 | 92 | Parser deferredToken() => ref1(token, 'deferred'); 93 | 94 | Parser exportToken() => ref1(token, 'export'); 95 | 96 | Parser extendsToken() => ref1(token, 'extends'); 97 | 98 | Parser factoryToken() => ref1(token, 'factory'); 99 | 100 | Parser getToken() => ref1(token, 'get'); 101 | 102 | Parser hideToken() => ref1(token, 'hide'); 103 | 104 | Parser implementsToken() => ref1(token, 'implements'); 105 | 106 | Parser importToken() => ref1(token, 'import'); 107 | 108 | Parser isToken() => ref1(token, 'is'); 109 | 110 | Parser libraryToken() => ref1(token, 'library'); 111 | 112 | Parser nativeToken() => ref1(token, 'native'); 113 | 114 | Parser negateToken() => ref1(token, 'negate'); 115 | 116 | Parser ofToken() => ref1(token, 'of'); 117 | 118 | Parser operatorToken() => ref1(token, 'operator'); 119 | 120 | Parser partToken() => ref1(token, 'part'); 121 | 122 | Parser setToken() => ref1(token, 'set'); 123 | 124 | Parser showToken() => ref1(token, 'show'); 125 | 126 | Parser staticToken() => ref1(token, 'static'); 127 | 128 | Parser typedefToken() => ref1(token, 'typedef'); 129 | 130 | Parser identifierLexicalToken() => 131 | (ref0(identifierStartLexicalToken) & 132 | ref0(identifierPartLexicalToken).star()) 133 | .map((ts) => ts.expand((e) => e is Iterable ? e : [e]).join()); 134 | 135 | Parser hexNumberLexicalToken() => 136 | string('0x') & ref0(hexDigitLexicalToken).plus() | 137 | string('0X') & ref0(hexDigitLexicalToken).plus(); 138 | 139 | Parser numberLexicalToken() => ((ref0(digitLexicalToken).plus() & 140 | ref0(numberOptFractionalPartLexicalToken) & 141 | ref0(exponentLexicalToken).optional() & 142 | ref0(numberOptIllegalEndLexicalToken)) | 143 | (char('.') & 144 | ref0(digitLexicalToken).plus() & 145 | ref0(exponentLexicalToken).optional() & 146 | ref0(numberOptIllegalEndLexicalToken))) 147 | .flatten(); 148 | 149 | Parser numberOptFractionalPartLexicalToken() => 150 | char('.') & ref0(digitLexicalToken).plus() | epsilon(); 151 | 152 | Parser numberOptIllegalEndLexicalToken() => epsilon(); 153 | 154 | Parser hexDigitLexicalToken() => pattern('0-9a-fA-F'); 155 | 156 | Parser identifierStartLexicalToken() => 157 | ref0(identifierStartNoDollarLexicalToken) | char('\$'); 158 | 159 | Parser identifierStartNoDollarLexicalToken() => 160 | ref0(letterLexicalToken) | char('_'); 161 | 162 | Parser identifierPartLexicalToken() => 163 | ref0(identifierStartLexicalToken) | ref0(digitLexicalToken); 164 | 165 | Parser letterLexicalToken() => letter(); 166 | 167 | Parser digitLexicalToken() => digit(); 168 | 169 | Parser exponentLexicalToken() => 170 | pattern('eE') & pattern('+-').optional() & ref0(digitLexicalToken).plus(); 171 | 172 | Parser stringLexicalToken() => singleLineStringLexicalToken().trim(); 173 | 174 | Parser singleLineStringLexicalToken() => (char('"') & 175 | ref0(stringContentDoubleQuotedLexicalToken).star() & 176 | char('"')) 177 | .map((v) { 178 | var list = v[1] as List; 179 | return list.length == 1 ? list[0] : list.join(''); 180 | }); 181 | 182 | Parser stringContentDoubleQuotedLexicalToken() => 183 | (stringContentDoubleQuotedLexicalTokenUnescaped() | 184 | stringContentQuotedLexicalTokenEscaped()) 185 | .cast(); 186 | 187 | Parser stringContentDoubleQuotedLexicalTokenUnescaped() => 188 | pattern('^\\"\n\r').plus().flatten(); 189 | 190 | Parser stringContentQuotedLexicalTokenEscaped() => (char('\\') & 191 | (char('n').map((_) => '\n') | 192 | char('r').map((_) => '\r') | 193 | char('"').map((_) => '"') | 194 | char("'").map((_) => "'") | 195 | char('t').map((_) => '\t') | 196 | char('b').map((_) => '\b') | 197 | char('\\').map((_) => '\\'))) 198 | .map((v) { 199 | return v[1] as String; 200 | }); 201 | 202 | static Parser newlineLexicalToken() => pattern('\n\r'); 203 | 204 | // ----------------------------------------------------------------- 205 | // Whitespace and comments. 206 | // ----------------------------------------------------------------- 207 | Parser hiddenWhitespace() => ref0(hiddenStuffWhitespace).plus(); 208 | 209 | static Parser hiddenStuffWhitespace() => 210 | ref0(visibleWhitespace) | 211 | ref0(singleLineComment) | 212 | ref0(multiLineComment); 213 | 214 | static Parser visibleWhitespace() => whitespace(); 215 | 216 | static Parser singleLineComment() => 217 | string('//') & 218 | ref0(newlineLexicalToken).neg().star() & 219 | ref0(newlineLexicalToken).optional(); 220 | 221 | static Parser multiLineComment() => 222 | string('/*') & 223 | (ref0(multiLineComment) | string('*/').neg()).star() & 224 | string('*/'); 225 | } 226 | 227 | extension TrimHiddenStuffWhitespaceParserExtension on Parser { 228 | Parser trimHidden() => trim(Java11GrammarLexer.hiddenStuffWhitespace()); 229 | } 230 | -------------------------------------------------------------------------------- /lib/src/languages/java/java11/java11_parser.dart: -------------------------------------------------------------------------------- 1 | // Copyright © 2020 Graciliano M. P. All rights reserved. 2 | // This code is governed by the Apache License, Version 2.0. 3 | // Please refer to the LICENSE and AUTHORS files for details. 4 | 5 | import '../../../apollovm_parser.dart'; 6 | import 'java11_grammar.dart'; 7 | 8 | /// Java11 implementation of an [ApolloParser]. 9 | class ApolloParserJava11 extends ApolloSourceCodeParser { 10 | static final ApolloParserJava11 instance = ApolloParserJava11(); 11 | 12 | ApolloParserJava11() : super(Java11GrammarDefinition()); 13 | 14 | @override 15 | String get language => 'java11'; 16 | 17 | @override 18 | bool acceptsLanguage(String language) { 19 | language = language.toLowerCase().trim(); 20 | 21 | if (this.language == language || language == 'java') { 22 | return true; 23 | } 24 | 25 | return false; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /lib/src/languages/java/java11/java11_runner.dart: -------------------------------------------------------------------------------- 1 | // Copyright © 2020 Graciliano M. P. All rights reserved. 2 | // This code is governed by the Apache License, Version 2.0. 3 | // Please refer to the LICENSE and AUTHORS files for details. 4 | 5 | import '../../../apollovm_runner.dart'; 6 | 7 | /// Java11 implementation of an [ApolloRunner]. 8 | class ApolloRunnerJava11 extends ApolloRunner { 9 | ApolloRunnerJava11(super.apolloVM); 10 | 11 | @override 12 | String get language => 'java11'; 13 | 14 | @override 15 | ApolloRunnerJava11 copy() { 16 | return ApolloRunnerJava11(apolloVM); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /lib/src/languages/wasm/wasm.dart: -------------------------------------------------------------------------------- 1 | // Copyright © 2020 Graciliano M. P. All rights reserved. 2 | // This code is governed by the Apache License, Version 2.0. 3 | // Please refer to the LICENSE and AUTHORS files for details. 4 | 5 | import 'dart:convert'; 6 | import 'dart:typed_data'; 7 | 8 | import 'package:data_serializer/data_serializer.dart'; 9 | 10 | enum WasmType { 11 | voidType('void', 0x40), 12 | i32Type('i32', 0x7f), 13 | i64Type('i64', 0x7e), 14 | f32Type('f32', 0x7d), 15 | f64Type('f64', 0x7c); 16 | 17 | final String name; 18 | final int value; 19 | 20 | const WasmType(this.name, this.value); 21 | } 22 | 23 | enum FloatAlign { align1, align2, align3 } 24 | 25 | /// Wasm constants and helpers. 26 | class Wasm { 27 | static const magicModuleHeader = [0x00, 0x61, 0x73, 0x6d]; 28 | static const moduleVersion = [0x01, 0x00, 0x00, 0x00]; 29 | 30 | static const typeIdx = 0x00; 31 | static const memoryIdx = 0x02; 32 | static const globalType = 0x03; 33 | static const functionType = 0x60; 34 | 35 | static List block(WasmType blockType) => [0x02, blockType.value]; 36 | 37 | static List loop(WasmType blockType) => [0x03, blockType.value]; 38 | 39 | static List ifInstruction(WasmType retType) => 40 | [0x04, retType.value]; 41 | 42 | static const elseInstruction = 0x05; 43 | static const end = 0x0b; 44 | 45 | static const functionReturn = 0x0f; 46 | 47 | static const unreachable = 0x00; 48 | 49 | static List brIf(int i) => [0x0d, ...Leb128.encodeUnsigned(i)]; 50 | 51 | static List call(int i) => [0x10, ...Leb128.encodeUnsigned(i)]; 52 | 53 | static const drop = 0x1a; 54 | static const select = 0x1b; 55 | 56 | static List localGet(int i) => [0x20, ...Leb128.encodeUnsigned(i)]; 57 | 58 | static List localSet(int i) => [0x21, ...Leb128.encodeUnsigned(i)]; 59 | 60 | static List localTee(int i) => [0x22, ...Leb128.encodeUnsigned(i)]; 61 | 62 | static List globalGet(int i) => [0x23, ...Leb128.encodeUnsigned(i)]; 63 | 64 | static List globalSet(int i) => [0x24, ...Leb128.encodeUnsigned(i)]; 65 | 66 | static List encodeString(String s) { 67 | var strBs = utf8.encode(s); 68 | return Uint8List.fromList( 69 | [...Leb128.encodeUnsigned(strBs.length), ...strBs]); 70 | } 71 | } 72 | 73 | /// Wasm 32-bits opcodes. 74 | class Wasm32 { 75 | static List i32Const(int i) => [0x41, ...Leb128.encodeSigned(i)]; 76 | 77 | static List f32Const(double i) => [0x43, ...encodeF32(i)]; 78 | 79 | static const int i32ExtendToI64Signed = 0xAC; 80 | static const int i32ExtendToI64Unsigned = 0xAD; 81 | 82 | static const int i32ConvertToF32Signed = 0xB2; 83 | static const int i32ConvertToF32Unsigned = 0xB3; 84 | static const int i32ConvertToF64Signed = 0xB7; 85 | static const int i32ConvertToF64Unsigned = 0xB8; 86 | 87 | static const int i32Add = 0x6A; 88 | static const int i32Subtract = 0x6B; 89 | static const int i32Multiply = 0x6C; 90 | static const int i32DivideSigned = 0x6D; 91 | static const int i32DivideUnsigned = 0x6E; 92 | 93 | static const int i32RemainderSigned = 0x6F; 94 | static const int i32RemainderUnsigned = 0x70; 95 | 96 | static const int i32BitwiseAnd = 0x71; 97 | static const int i32BitwiseOr = 0x72; 98 | static const int i32BitwiseXor = 0x73; 99 | static const int i32ShiftLeft = 0x74; 100 | static const int i32ShiftRightSigned = 0x75; 101 | static const int i32ShiftRightUnsigned = 0x76; 102 | static const int i32RotateLeft = 0x77; 103 | static const int i32RotateRight = 0x78; 104 | 105 | static const int i32EqualsToZero = 0x45; 106 | static const int i32Equals = 0x46; 107 | static const int i32NotEquals = 0x47; 108 | 109 | static const int i32LessThanSigned = 0x48; 110 | static const int i32LessThanUnsigned = 0x49; 111 | static const int i32GreaterThanSigned = 0x4A; 112 | static const int i32GreaterThanUnsigned = 0x4B; 113 | 114 | static const int i32LessThanOrEqualsSigned = 0x4C; 115 | static const int i32LessThanOrEqualsUnsigned = 0x4D; 116 | static const int i32GreaterThanOrEqualsSigned = 0x4E; 117 | static const int i32GreaterThanOrEqualsUnsigned = 0x4F; 118 | 119 | static const int f32LessThan = 0x5D; 120 | static const int f32GreaterThan = 0x5E; 121 | static const int f32LessThanOrEquals = 0x5F; 122 | static const int f32GreaterThanOrEquals = 0x60; 123 | 124 | static const int f32Min = 0x96; 125 | static const int f32Max = 0x97; 126 | 127 | static const int f32Equals = 0x5B; 128 | static const int f32NotEquals = 0x5C; 129 | 130 | static const int f32Absolute = 0x8B; 131 | static const int f32Negation = 0x8C; 132 | static const int f32Ceil = 0x8D; 133 | static const int f32Floor = 0x8E; 134 | static const int f32Sqrt = 0x91; 135 | 136 | static const int f32Add = 0x92; 137 | static const int f32Subtract = 0x93; 138 | static const int f32Multiply = 0x94; 139 | static const int f32Divide = 0x95; 140 | 141 | static const int f32TruncateToF32Signed = 0x8F; 142 | static const int f32TruncateToI32Signed = 0xA8; 143 | static const int f32TruncateToI32Unsigned = 0xA9; 144 | static const int f32TruncateToI64Signed = 0xAE; 145 | static const int f32TruncateToI64Unsigned = 0xAF; 146 | 147 | static Uint8List encodeF32(double d) { 148 | final arr = Uint8List(4); 149 | writeFloat32(arr, 0, d); 150 | return arr; 151 | } 152 | 153 | static void writeFloat32(Uint8List buffer, int offset, double value) { 154 | var byteData = 155 | buffer.buffer.asByteData(buffer.offsetInBytes, buffer.lengthInBytes); 156 | byteData.setFloat32(offset, value, Endian.little); 157 | } 158 | } 159 | 160 | /// Wasm 64-bits opcodes. 161 | class Wasm64 { 162 | static List i64Const(int i) => [0x42, ...Leb128.encodeSigned(i)]; 163 | 164 | static List f64Const(double i) => [0x44, ...encodeF64(i)]; 165 | 166 | static const int i64ConvertToF32Signed = 0xB4; 167 | static const int i64ConvertToF32Unsigned = 0xB5; 168 | static const int i64ConvertToF64Signed = 0xB9; 169 | static const int i64ConvertToF64Unsigned = 0xBA; 170 | 171 | static const int i64Add = 0x7C; 172 | static const int i64Subtract = 0x7D; 173 | static const int i64Multiply = 0x7E; 174 | static const int i64DivideSigned = 0x7F; 175 | static const int i64DivideUnsigned = 0x80; 176 | 177 | static const int i64RemainderSigned = 0x81; 178 | static const int i64RemainderUnsigned = 0x82; 179 | 180 | static const int i64BitwiseAnd = 0x83; 181 | static const int i64BitwiseOr = 0x84; 182 | static const int i64BitwiseXor = 0x85; 183 | static const int i64ShiftLeft = 0x86; 184 | static const int i64ShiftRightSigned = 0x87; 185 | static const int i64ShiftRightUnsigned = 0x88; 186 | static const int i64RotateLeft = 0x89; 187 | static const int i64RotateRight = 0x8A; 188 | 189 | static const int i64EqualsToZero = 0x50; 190 | static const int i64Equals = 0x51; 191 | static const int i64NotEquals = 0x52; 192 | 193 | static const int i64LessThanSigned = 0x53; 194 | static const int i64LessThanUnsigned = 0x54; 195 | static const int i64GreaterThanSigned = 0x55; 196 | static const int i64GreaterThanUnsigned = 0x56; 197 | 198 | static const int i64LessThanOrEqualsSigned = 0x57; 199 | static const int i64LessThanOrEqualsUnsigned = 0x58; 200 | static const int i64GreaterThanOrEqualsSigned = 0x59; 201 | static const int i64GreaterThanOrEqualsUnsigned = 0x5A; 202 | 203 | static const int f64LessThan = 0x63; 204 | static const int f64GreaterThan = 0x64; 205 | static const int f64LessThanOrEquals = 0x65; 206 | static const int f64GreaterThanOrEquals = 0x66; 207 | 208 | static const int f64Min = 0xa4; 209 | static const int f64Max = 0xa5; 210 | 211 | static const int f64Equals = 0x61; 212 | static const int f64NotEquals = 0x62; 213 | 214 | static const int f64Absolute = 0x99; 215 | static const int f64Negation = 0x9a; 216 | static const int f64Ceil = 0x9b; 217 | static const int f64Floor = 0x9c; 218 | static const int f64Sqrt = 0x9f; 219 | 220 | static const int f64Add = 0xA0; 221 | static const int f64Subtract = 0xA1; 222 | static const int f64Multiply = 0xA2; 223 | static const int f64Divide = 0xA3; 224 | 225 | static const int f64TruncateToF64Signed = 0x9D; 226 | static const int f64TruncateToI32Signed = 0xAA; 227 | static const int f64TruncateToI32Unsigned = 0xAB; 228 | static const int f64TruncateToI64Signed = 0xB0; 229 | static const int f64TruncateToI64Unsigned = 0xB1; 230 | 231 | static const int i64WrapToi32 = 0xA7; 232 | 233 | static Uint8List encodeF64(double d) { 234 | final arr = Uint8List(8); 235 | writeFloat64(arr, 0, d); 236 | return arr; 237 | } 238 | 239 | static void writeFloat64(Uint8List buffer, int offset, double value) { 240 | var byteData = 241 | buffer.buffer.asByteData(buffer.offsetInBytes, buffer.lengthInBytes); 242 | byteData.setFloat64(offset, value, Endian.little); 243 | } 244 | 245 | static List f64Load(FloatAlign align, int offset) => [ 246 | 0x2b, 247 | ...Leb128.encodeUnsigned(align.index), 248 | ...Leb128.encodeUnsigned(offset) 249 | ]; 250 | 251 | static List f64Store(FloatAlign align, int offset) => [ 252 | 0x39, 253 | ...Leb128.encodeUnsigned(align.index), 254 | ...Leb128.encodeUnsigned(offset) 255 | ]; 256 | } 257 | -------------------------------------------------------------------------------- /lib/src/languages/wasm/wasm_parser.dart: -------------------------------------------------------------------------------- 1 | // Copyright © 2020 Graciliano M. P. All rights reserved. 2 | // This code is governed by the Apache License, Version 2.0. 3 | // Please refer to the LICENSE and AUTHORS files for details. 4 | 5 | import 'dart:typed_data'; 6 | 7 | import 'package:collection/collection.dart'; 8 | import 'package:data_serializer/data_serializer.dart'; 9 | 10 | import '../../apollovm_base.dart'; 11 | import '../../apollovm_parser.dart'; 12 | import '../../ast/apollovm_ast_toplevel.dart'; 13 | import '../../ast/apollovm_ast_type.dart'; 14 | import 'wasm.dart'; 15 | 16 | /// Dart implementation of an [ApolloParser]. 17 | /// - This only parses the exported [Function]s into an [ASTRoot], 18 | /// so that the [ApolloRunnerWasm] can know what functions can be called. 19 | /// - There are NO plans to parse the entire Wasm code into an full AST tree 20 | /// because decompiling it in this way is not an efficient process. 21 | class ApolloParserWasm extends ApolloCodeParser { 22 | static final ApolloParserWasm instance = ApolloParserWasm(); 23 | 24 | ApolloParserWasm() : super(); 25 | 26 | @override 27 | String get language => 'wasm'; 28 | 29 | @override 30 | Future> parse(CodeUnit codeUnit) async { 31 | var bytes = BytesBuffer.from(codeUnit.code); 32 | 33 | bytes.seek(0); 34 | 35 | var magic = bytes.readBytes(4); 36 | if (!magic.equals(Wasm.magicModuleHeader.asUint8List)) { 37 | throw StateError("Binary not starting with Wasm magic!"); 38 | } 39 | 40 | var version = bytes.readBytes(4); 41 | if (!version.equals(Wasm.moduleVersion.asUint8List)) { 42 | throw StateError("Binary version unsupported: $version"); 43 | } 44 | 45 | List<_TypeFunction>? typeFunctions; 46 | List? astFunctions; 47 | 48 | while (bytes.remaining > 0) { 49 | var sectionID = bytes.readByte(); 50 | var block = bytes.readLeb128Block(); 51 | 52 | // Section Type: 53 | if (sectionID == 0x01) { 54 | typeFunctions = _parseSectionType(block); 55 | } 56 | // Section Export: 57 | else if (sectionID == 0x07) { 58 | astFunctions = _parseSectionExport(block, typeFunctions); 59 | } 60 | } 61 | 62 | var astRoot = ASTRoot(); 63 | 64 | if (astFunctions != null) { 65 | astRoot.addAllFunctions(astFunctions); 66 | } 67 | 68 | var parseResult = ParseResult(codeUnit, root: astRoot); 69 | return parseResult; 70 | } 71 | 72 | List<_TypeFunction> _parseSectionType(Uint8List block) { 73 | var bytes = BytesBuffer.from(block); 74 | 75 | var count = bytes.readLeb128UnsignedInt(); 76 | 77 | var typeFunctions = <_TypeFunction>[]; 78 | 79 | for (var i = 0; i < count; ++i) { 80 | var type = bytes.readByte(); 81 | 82 | // Function: 83 | if (type == 96) { 84 | var parameters = bytes.readLeb128Block(); 85 | var results = bytes.readLeb128Block(); 86 | 87 | typeFunctions.add(_TypeFunction(parameters, results)); 88 | } 89 | } 90 | 91 | return typeFunctions; 92 | } 93 | 94 | List _parseSectionExport( 95 | Uint8List block, List<_TypeFunction>? typeFunctions) { 96 | typeFunctions ??= []; 97 | 98 | var bytes = BytesBuffer.from(block); 99 | 100 | var count = bytes.readLeb128UnsignedInt(); 101 | 102 | var functions = []; 103 | 104 | for (var i = 0; i < count; ++i) { 105 | var name = bytes.readLeb128String(); 106 | var type = bytes.readByte(); 107 | var index = bytes.readLeb128UnsignedInt(); 108 | 109 | // Function: 110 | if (type == 0) { 111 | var typeFunction = typeFunctions[index]; 112 | 113 | var astParameters = typeFunction.toASTParametersDeclaration(); 114 | 115 | var astReturn = typeFunction.results.toASTTypes().firstOrNull ?? 116 | ASTTypeVoid.instance; 117 | 118 | var astFunction = 119 | ASTFunctionDeclaration(name, astParameters, astReturn); 120 | 121 | functions.add(astFunction); 122 | } 123 | } 124 | 125 | return functions; 126 | } 127 | } 128 | 129 | class _TypeFunction { 130 | List parameters; 131 | 132 | List results; 133 | 134 | _TypeFunction(this.parameters, this.results); 135 | 136 | List toASTFunctionParameterDeclaration() => 137 | parameters 138 | .mapIndexed((i, p) => 139 | ASTFunctionParameterDeclaration(p.toASTType(), 'p$i', i, false)) 140 | .toList(); 141 | 142 | ASTParametersDeclaration toASTParametersDeclaration() => 143 | ASTParametersDeclaration(toASTFunctionParameterDeclaration()); 144 | } 145 | 146 | extension _ListIntExtension on List { 147 | List toASTTypes() => map((t) => t.toASTType()).toList(); 148 | } 149 | 150 | final _astTypeInt32 = ASTTypeInt.instance32; 151 | final _astTypeInt64 = ASTTypeInt.instance64; 152 | final _astTypeDouble32 = ASTTypeDouble.instance32; 153 | final _astTypeDouble64 = ASTTypeDouble.instance64; 154 | 155 | extension _IntExtension on int { 156 | ASTType toASTType() { 157 | final t = this; 158 | 159 | if (t == WasmType.i32Type.value) { 160 | return _astTypeInt32; 161 | } else if (t == WasmType.i64Type.value) { 162 | return _astTypeInt64; 163 | } else if (t == WasmType.f32Type.value) { 164 | return _astTypeDouble32; 165 | } else if (t == WasmType.f64Type.value) { 166 | return _astTypeDouble64; 167 | } else { 168 | throw StateError("Can't handle type: $t"); 169 | } 170 | } 171 | } 172 | -------------------------------------------------------------------------------- /lib/src/languages/wasm/wasm_runner.dart: -------------------------------------------------------------------------------- 1 | // Copyright © 2020 Graciliano M. P. All rights reserved. 2 | // This code is governed by the Apache License, Version 2.0. 3 | // Please refer to the LICENSE and AUTHORS files for details. 4 | 5 | import 'dart:math' as math; 6 | import 'dart:typed_data'; 7 | 8 | import 'package:collection/collection.dart'; 9 | import 'package:swiss_knife/swiss_knife.dart'; 10 | 11 | import '../../apollovm_base.dart'; 12 | import '../../apollovm_runner.dart'; 13 | import '../../ast/apollovm_ast_toplevel.dart'; 14 | import '../../ast/apollovm_ast_type.dart'; 15 | import '../../ast/apollovm_ast_value.dart'; 16 | import 'wasm_runtime.dart'; 17 | 18 | /// WebAssembly (Wasm) implementation of an [ApolloRunner]. 19 | class ApolloRunnerWasm extends ApolloRunner { 20 | final _wasmRuntime = WasmRuntime(); 21 | 22 | ApolloRunnerWasm(super.apolloVM); 23 | 24 | @override 25 | String get language => 'wasm'; 26 | 27 | @override 28 | ApolloRunnerWasm copy() { 29 | return ApolloRunnerWasm(apolloVM); 30 | } 31 | 32 | @override 33 | Future executeFunction(String namespace, String functionName, 34 | {List? positionalParameters, 35 | Map? namedParameters, 36 | bool allowClassMethod = false}) async { 37 | var r = await getFunctionCodeUnit(namespace, functionName, 38 | allowClassMethod: allowClassMethod); 39 | 40 | var codeUnit = r.codeUnit as CodeUnit?; 41 | if (codeUnit == null) { 42 | throw StateError( 43 | "Can't find function to execute> functionName: $functionName ; language: $language"); 44 | } 45 | 46 | if (!_wasmRuntime.isSupported) { 47 | throw StateError( 48 | "`WasmRuntime` not supported on this platform: ${_wasmRuntime.platformVersion}"); 49 | } 50 | 51 | var module = await _wasmRuntime.loadModule(codeUnit.id, codeUnit.code); 52 | 53 | var f = module.getFunction(functionName); 54 | if (f == null) { 55 | throw StateError("Can't find function: $functionName"); 56 | } 57 | 58 | var allParams = [ 59 | ...?positionalParameters, 60 | ...?namedParameters?.values, 61 | ]; 62 | 63 | var astFunction = _getASTFunction(codeUnit, functionName, allParams); 64 | if (astFunction != null) { 65 | _resolveWasmCallParameters(astFunction, allParams); 66 | } 67 | 68 | dynamic res; 69 | try { 70 | res = Function.apply(f, allParams); 71 | } catch (e) { 72 | throw WasmModuleExecutionError(functionName, 73 | parameters: allParams, function: f, cause: e); 74 | } 75 | 76 | res = module.resolveReturnedValue(res, astFunction); 77 | 78 | var astValue = 79 | res == null ? ASTValueNull.instance : ASTValue.fromValue(res); 80 | 81 | return astValue; 82 | } 83 | 84 | void _resolveWasmCallParameters( 85 | ASTFunctionDeclaration astFunction, List parameters) { 86 | var astParameters = astFunction.parameters.allParameters; 87 | var limit = math.min(parameters.length, astParameters.length); 88 | 89 | for (var i = 0; i < limit; ++i) { 90 | var p = astParameters[i]; 91 | var v = parameters[i]; 92 | 93 | var v2 = _resolveParameterValueType(p, v); 94 | parameters[i] = v2; 95 | } 96 | } 97 | 98 | Object? _resolveParameterValueType( 99 | ASTFunctionParameterDeclaration p, Object? v) { 100 | var t = p.type; 101 | 102 | if (t is ASTTypeInt) { 103 | var n = parseInt(v); 104 | 105 | if (n != null && t.bits == 64) { 106 | return BigInt.from(n); 107 | } else { 108 | return n ?? v; 109 | } 110 | } else if (t is ASTTypeDouble) { 111 | var n = parseDouble(v); 112 | return n ?? v; 113 | } 114 | 115 | return v; 116 | } 117 | 118 | ASTFunctionDeclaration? _getASTFunction( 119 | CodeUnit codeUnit, String functionName, List parameters) { 120 | var astFunctionSet = codeUnit.root?.getFunctionWithName(functionName); 121 | if (astFunctionSet == null) return null; 122 | 123 | if (astFunctionSet.functions.length <= 1) { 124 | return astFunctionSet.functions.firstOrNull; 125 | } 126 | 127 | var list = astFunctionSet.functions 128 | .where((f) => f.parameters.size == parameters.length); 129 | 130 | if (list.length <= 1) return list.firstOrNull; 131 | 132 | throw StateError( 133 | "Ambiguous AST functions. Can't determine function with name `$functionName` and with ${parameters.length} parameters"); 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /lib/src/languages/wasm/wasm_runtime.dart: -------------------------------------------------------------------------------- 1 | import 'dart:typed_data'; 2 | 3 | import '../../ast/apollovm_ast_toplevel.dart'; 4 | import 'package:async_extension/async_extension.dart'; 5 | 6 | import 'wasm_runtime_generic.dart' 7 | if (dart.library.html) 'wasm_runtime_browser.dart' 8 | if (dart.library.io) 'wasm_runtime_io.dart'; 9 | 10 | /// A WebAssembly (Wasm) Runtime. 11 | abstract class WasmRuntime { 12 | final Map _loadedModules = {}; 13 | 14 | WasmRuntime.base(); 15 | 16 | factory WasmRuntime() { 17 | return createWasmRuntime(); 18 | } 19 | 20 | /// Returns the platform version of the Wasm runtime. 21 | String get platformVersion; 22 | 23 | /// Returns true if the WebAssembly (Wasm) Runtime is supported in the platform. 24 | bool get isSupported; 25 | 26 | /// Returns a loaded Wasm module. 27 | WasmModule? getModule(String moduleName) { 28 | return _loadedModules[moduleName]; 29 | } 30 | 31 | /// Loads a Wasm module. 32 | Future loadModule( 33 | String moduleName, Uint8List wasmModuleBinary) async { 34 | return _loadedModules[moduleName] ??= 35 | await loadModuleImpl(moduleName, wasmModuleBinary); 36 | } 37 | 38 | /// Platform specific implementation. 39 | /// Call [loadModule]. 40 | Future loadModuleImpl( 41 | String moduleName, Uint8List wasmModuleBinary); 42 | 43 | /// Removes a Wasm module. 44 | FutureOr removeModule(String moduleName) { 45 | var module = _loadedModules.remove(moduleName); 46 | if (module == null) return null; 47 | 48 | return module.dispose().resolveWithValue(module); 49 | } 50 | } 51 | 52 | /// A WebAssembly (Wasm) Runtime module 53 | abstract class WasmModule { 54 | /// The module name. 55 | final String name; 56 | 57 | WasmModule(this.name); 58 | 59 | /// Returns a copy instance of this module. 60 | Future copy({String? name}); 61 | 62 | /// Returns a module function mapped to [F]. 63 | F? getFunction(String functionName); 64 | 65 | /// Resolves the returned [value] from a called module function. 66 | Object? resolveReturnedValue(Object? value, ASTFunctionDeclaration? f); 67 | 68 | /// Disposes this module instance. 69 | FutureOr dispose() {} 70 | } 71 | 72 | /// [WasmModule] error. 73 | class WasmModuleError extends Error { 74 | final String message; 75 | 76 | WasmModuleError(this.message); 77 | 78 | @override 79 | String toString() { 80 | return 'WasmModuleError: $message'; 81 | } 82 | } 83 | 84 | /// Thrown when [WasmModule] fails to load. 85 | class WasmModuleLoadError extends WasmModuleError { 86 | final Object? cause; 87 | 88 | WasmModuleLoadError(super.message, {this.cause}); 89 | 90 | @override 91 | String toString() { 92 | return 'WasmModuleLoadError: $message\nCause: $cause'; 93 | } 94 | } 95 | 96 | /// Thrown when [WasmModule] execution fails. 97 | class WasmModuleExecutionError extends WasmModuleError { 98 | final String functionName; 99 | final List? parameters; 100 | final Function? function; 101 | 102 | final Object? cause; 103 | 104 | WasmModuleExecutionError(this.functionName, 105 | {this.parameters, this.function, String? message, this.cause}) 106 | : super( 107 | "Error executing Wasm function> $functionName( $parameters )${function != null ? ' -> $function' : ''}"); 108 | 109 | @override 110 | String toString() { 111 | return 'WasmModuleExecutionError: $message\nCause: $cause'; 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /lib/src/languages/wasm/wasm_runtime_browser.dart: -------------------------------------------------------------------------------- 1 | import 'dart:html'; 2 | import 'dart:typed_data'; 3 | 4 | import 'package:wasm_interop/wasm_interop.dart' as browser_wasm; 5 | 6 | import '../../ast/apollovm_ast_toplevel.dart'; 7 | import 'wasm_runtime.dart'; 8 | 9 | /// [WasmRuntime] implementation for the Browser. 10 | class WasmRuntimeBrowser extends WasmRuntime { 11 | WasmRuntimeBrowser() : super.base(); 12 | 13 | @override 14 | String get platformVersion => 'Browser: ${window.navigator.userAgent}'; 15 | 16 | @override 17 | bool get isSupported => true; 18 | 19 | @override 20 | Future loadModuleImpl( 21 | String moduleName, Uint8List wasmModuleBinary) async { 22 | try { 23 | final moduleInstance = 24 | await browser_wasm.Instance.fromBytesAsync(wasmModuleBinary); 25 | return WasmModuleBrowser(moduleName, moduleInstance); 26 | } catch (e) { 27 | throw WasmModuleLoadError("Can't load wasm module: $moduleName", 28 | cause: e); 29 | } 30 | } 31 | } 32 | 33 | class WasmModuleBrowser extends WasmModule { 34 | browser_wasm.Instance instance; 35 | 36 | WasmModuleBrowser(super.name, this.instance); 37 | 38 | @override 39 | Future copy({String? name}) async { 40 | name ??= this.name; 41 | 42 | var instance2 = 43 | await browser_wasm.Instance.fromModuleAsync(instance.module); 44 | return WasmModuleBrowser(name, instance2); 45 | } 46 | 47 | @override 48 | F? getFunction(String functionName) { 49 | return instance.functions[functionName]! as F?; 50 | } 51 | 52 | @override 53 | Object? resolveReturnedValue(Object? value, ASTFunctionDeclaration? f) { 54 | if (value == null) return null; 55 | 56 | if (browser_wasm.JsBigInt.isJsBigInt(value)) { 57 | var bigInt = browser_wasm.JsBigInt.toBigInt(value); 58 | 59 | if (bigInt.isValidInt) { 60 | return bigInt.toInt(); 61 | } else { 62 | return bigInt; 63 | } 64 | } 65 | 66 | return value; 67 | } 68 | 69 | @override 70 | String toString() { 71 | return 'WasmModuleBrowser{name: $name, instance: $instance}'; 72 | } 73 | } 74 | 75 | WasmRuntime createWasmRuntime() { 76 | return WasmRuntimeBrowser(); 77 | } 78 | -------------------------------------------------------------------------------- /lib/src/languages/wasm/wasm_runtime_generic.dart: -------------------------------------------------------------------------------- 1 | import 'dart:typed_data'; 2 | 3 | import '../../ast/apollovm_ast_toplevel.dart'; 4 | import 'wasm_runtime.dart'; 5 | 6 | class WasmRuntimeGeneric extends WasmRuntime { 7 | WasmRuntimeGeneric() : super.base(); 8 | 9 | @override 10 | String get platformVersion => '?'; 11 | 12 | @override 13 | bool get isSupported => false; 14 | 15 | @override 16 | Future loadModuleImpl( 17 | String moduleName, Uint8List wasmModuleBinary) async { 18 | return WasmModuleGeneric(moduleName); 19 | } 20 | } 21 | 22 | class WasmModuleGeneric extends WasmModule { 23 | WasmModuleGeneric(super.name); 24 | 25 | @override 26 | Future copy({String? name}) async { 27 | name ??= this.name; 28 | return WasmModuleGeneric(name); 29 | } 30 | 31 | @override 32 | F? getFunction(String functionName) => null; 33 | 34 | @override 35 | Object? resolveReturnedValue(Object? value, ASTFunctionDeclaration? f) => 36 | value; 37 | } 38 | 39 | WasmRuntime createWasmRuntime() { 40 | return WasmRuntimeGeneric(); 41 | } 42 | -------------------------------------------------------------------------------- /lib/src/languages/wasm/wasm_runtime_io.dart: -------------------------------------------------------------------------------- 1 | import 'dart:ffi'; 2 | import 'dart:io'; 3 | import 'dart:typed_data'; 4 | 5 | import 'package:crypto/crypto.dart'; 6 | import 'package:path/path.dart' as pack_path; 7 | import 'package:wasm_run/wasm_run.dart' as wasm_run; 8 | 9 | import '../../ast/apollovm_ast_toplevel.dart'; 10 | import '../../ast/apollovm_ast_type.dart'; 11 | import 'wasm_runtime.dart'; 12 | 13 | /// [WasmRuntime] implementation for Dart VM. 14 | class WasmRuntimeIO extends WasmRuntime { 15 | static bool _boot = false; 16 | 17 | static bool _wasmRunDynLibLoaded = false; 18 | 19 | static void boot() { 20 | if (_boot) return; 21 | _boot = true; 22 | 23 | if (wasm_run.WasmRunLibrary.isReachable()) { 24 | print('** Loading `wasm_run` dynamic library with default resolver.'); 25 | _wasmRunDynLibLoaded = true; 26 | return; 27 | } 28 | 29 | var libPath = _wasmRunLibraryFilePath(); 30 | 31 | if (libPath == null) { 32 | throw StateError("Unable to locate the `wasm_run` dynamic library. " 33 | "You can specify the library path using the environment variable `WASM_RUN_LIB_PATH`."); 34 | } 35 | 36 | print('** Loading `wasm_run` dynamic library: $libPath'); 37 | 38 | var dynLib = DynamicLibrary.open(libPath); 39 | 40 | var ok = dynLib.providesSymbol('wire_compile_wasm'); 41 | if (!ok) { 42 | throw StateError("Invalid `wasm_run` dynamic library: $libPath"); 43 | } 44 | 45 | _wasmRunDynLibLoaded = true; 46 | } 47 | 48 | WasmRuntimeIO() : super.base(); 49 | 50 | @override 51 | String get platformVersion => 'Dart: ${Platform.version}'; 52 | 53 | @override 54 | bool get isSupported { 55 | try { 56 | boot(); 57 | } catch (e, s) { 58 | print(e); 59 | print(s); 60 | } 61 | return _wasmRunDynLibLoaded; 62 | } 63 | 64 | @override 65 | Future loadModuleImpl( 66 | String moduleName, Uint8List wasmModuleBinary) async { 67 | var module = await _compileModule(wasmModuleBinary); 68 | var moduleInstance = await module.builder().build(); 69 | return WasmModuleIO(moduleName, module, moduleInstance); 70 | } 71 | 72 | final Map _compiledModules = {}; 73 | 74 | Future _compileModule(Uint8List wasmModuleBinary) async { 75 | var binarySignature = _computeBinarySignatureHex(wasmModuleBinary); 76 | 77 | var module = _compiledModules[binarySignature] ??= 78 | await _compileModuleImpl(wasmModuleBinary); 79 | 80 | return module; 81 | } 82 | 83 | Future _compileModuleImpl(Uint8List wasmModuleBinary) { 84 | boot(); 85 | return wasm_run.compileWasmModule(wasmModuleBinary); 86 | } 87 | 88 | String _computeBinarySignatureHex(Uint8List wasmModuleBinary) => 89 | sha256.convert(wasmModuleBinary).toString(); 90 | } 91 | 92 | /// [WasmModule] implementation for Dart VM. 93 | class WasmModuleIO extends WasmModule { 94 | final wasm_run.WasmModule _module; 95 | wasm_run.WasmInstance instance; 96 | 97 | WasmModuleIO(super.name, this._module, this.instance); 98 | 99 | @override 100 | Future copy({String? name}) async { 101 | name ??= this.name; 102 | 103 | var instance2 = await _module.builder().build(); 104 | return WasmModuleIO(name, _module, instance2); 105 | } 106 | 107 | @override 108 | F? getFunction(String functionName) { 109 | var f = instance.getFunction(functionName); 110 | if (f == null) return null; 111 | 112 | return f.inner as F?; 113 | } 114 | 115 | @override 116 | void dispose() { 117 | instance.dispose(); 118 | } 119 | 120 | @override 121 | Object? resolveReturnedValue(Object? value, ASTFunctionDeclaration? f) { 122 | if (f?.returnType is ASTTypeVoid) { 123 | return null; 124 | } 125 | 126 | return value; 127 | } 128 | } 129 | 130 | WasmRuntime createWasmRuntime() { 131 | return WasmRuntimeIO(); 132 | } 133 | 134 | String? _wasmRunLibraryFileName() { 135 | if (Platform.isMacOS) { 136 | return 'libwasm_run_dart.dylib'; 137 | } else if (Platform.isWindows) { 138 | return 'wasm_run_dart.dll'; 139 | } else if (Platform.isLinux) { 140 | return 'libwasm_run_dart.so'; 141 | } 142 | return null; 143 | } 144 | 145 | String? _wasmRunLibraryFilePath() { 146 | var libName = 147 | _wasmRunLibraryFileName() ?? Platform.environment['WASM_RUN_LIB_PATH']; 148 | if (libName == null || libName.isEmpty) return null; 149 | 150 | var possibleDirs = [ 151 | libName, 152 | '.', 153 | '../', 154 | '../../', 155 | 'lib', 156 | '../lib', 157 | '../../lib' 158 | ]; 159 | 160 | for (var dirPath in possibleDirs) { 161 | var file = File(pack_path.join(dirPath, libName)); 162 | if (file.existsSync()) { 163 | return pack_path.normalize(file.absolute.path); 164 | } 165 | } 166 | 167 | return null; 168 | } 169 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: apollovm 2 | description: ApolloVM, a Multilingual portable VM (native, JS/Web, Flutter) for Dart, Java, JavaScript with on-the-fly Wasm compilation. 3 | version: 0.0.53 4 | repository: https://github.com/ApolloVM/apollovm_dart 5 | issue_tracker: https://github.com/ApolloVM/apollovm_dart/issues 6 | 7 | topics: 8 | - vm 9 | - dart 10 | - java 11 | - compiler 12 | - translator 13 | 14 | screenshots: 15 | - description: 'ApolloVM Logo' 16 | path: example/apollovm-logo.png 17 | 18 | environment: 19 | sdk: '>=3.3.0 <4.0.0' 20 | 21 | dependencies: 22 | swiss_knife: ^3.2.0 23 | async_extension: ^1.2.5 24 | data_serializer: ^1.1.0 25 | petitparser: ^6.0.2 26 | collection: ^1.18.0 27 | args: ^2.4.2 28 | wasm_interop: ^2.0.1 29 | wasm_run: ^0.1.0+1 30 | crypto: ^3.0.3 31 | path: ^1.9.0 32 | 33 | dev_dependencies: 34 | lints: ^3.0.0 35 | dependency_validator: ^3.2.3 36 | test: ^1.25.2 37 | pubspec: ^2.3.0 38 | xml: ^6.5.0 39 | 40 | executables: 41 | apollovm: 42 | -------------------------------------------------------------------------------- /test/apollovm_languages_basic_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:apollovm/apollovm.dart'; 2 | 3 | import 'apollovm_languages_test_definition.dart'; 4 | 5 | Future main() async { 6 | print('BASIC TESTS DEFINITIONS'); 7 | 8 | var definitions = [ 9 | TestDefinition('dart_basic_main_1.test.xml', ''' 10 | 11 | 12 | 13 | args) { 15 | var title = args[0]; 16 | var a = args[1]; 17 | var b = args[2]; 18 | var c = args[3]; 19 | var sumAB = a + b ; 20 | var sumABC = a + b + c; 21 | print(title); 22 | print(sumAB); 23 | print(sumABC); 24 | } 25 | ]]> 26 | 27 | 28 | [ 29 | ["Strings:", "A", "B", "C"] 30 | ] 31 | 32 | 33 | ["Strings:", "AB", "ABC"] 34 | 35 | >>> 36 | <<<< NAMESPACE="" >>>> 37 | <<<< CODE_UNIT_START="/test" >>>> 38 | void main(List args) { 39 | var title = args[0]; 40 | var a = args[1]; 41 | var b = args[2]; 42 | var c = args[3]; 43 | var sumAB = a + b; 44 | var sumABC = a + b + c; 45 | print(title); 46 | print(sumAB); 47 | print(sumABC); 48 | } 49 | 50 | <<<< CODE_UNIT_END="/test" >>>> 51 | <<<< [SOURCES_END] >>>> 52 | ]]> 53 | 54 | '''), 55 | TestDefinition('java11_basic_main_1.test.xml', ''' 56 | 57 | 58 | 59 | 76 | 77 | 78 | [ 79 | ["Strings:", "A", "B", "C"] 80 | ] 81 | 82 | 83 | ["Strings:", "AB", "ABC"] 84 | 85 | >>> 86 | <<<< NAMESPACE="" >>>> 87 | <<<< CODE_UNIT_START="/test" >>>> 88 | class Foo { 89 | 90 | static void main(List args) { 91 | var title = args[0]; 92 | var a = args[1]; 93 | var b = args[2]; 94 | var c = args[3]; 95 | var sumAB = a + b; 96 | var sumABC = a + b + c; 97 | print(title); 98 | print(sumAB); 99 | print(sumABC); 100 | } 101 | 102 | } 103 | <<<< CODE_UNIT_END="/test" >>>> 104 | <<<< [SOURCES_END] >>>> 105 | ]]> 106 | 107 | >>> 108 | <<<< NAMESPACE="" >>>> 109 | <<<< CODE_UNIT_START="/test" >>>> 110 | class Foo { 111 | 112 | static void main(String[] args) { 113 | var title = args[0]; 114 | var a = args[1]; 115 | var b = args[2]; 116 | var c = args[3]; 117 | var sumAB = a + b; 118 | var sumABC = a + b + c; 119 | print(title); 120 | print(sumAB); 121 | print(sumABC); 122 | } 123 | 124 | } 125 | <<<< CODE_UNIT_END="/test" >>>> 126 | <<<< [SOURCES_END] >>>> 127 | ]]> 128 | 129 | '''), 130 | TestDefinition('dart_basic_main_2.test.xml', ''' 131 | 132 | 133 | 134 | [a, b, c]; 148 | print(list); 149 | 150 | var listEmpty = []; 151 | print(listEmpty); 152 | } 153 | ]]> 154 | 155 | 156 | [ 157 | ["Integers:", 10, 20, 30] 158 | ] 159 | 160 | 161 | ["Integers:", 30, 60, [10, 20, 30], []] 162 | 163 | >>> 164 | <<<< NAMESPACE="" >>>> 165 | <<<< CODE_UNIT_START="/test" >>>> 166 | void main(List args) { 167 | var title = args[0]; 168 | var a = args[1]; 169 | var b = args[2]; 170 | var c = args[3]; 171 | var sumAB = a + b; 172 | var sumABC = a + b + c; 173 | print(title); 174 | print(sumAB); 175 | print(sumABC); 176 | var list = [a, b, c]; 177 | print(list); 178 | var listEmpty = []; 179 | print(listEmpty); 180 | } 181 | 182 | <<<< CODE_UNIT_END="/test" >>>> 183 | <<<< [SOURCES_END] >>>> 184 | ]]> 185 | 186 | '''), 187 | TestDefinition('dart_basic_main_3.test.xml', r''' 188 | 189 | 190 | 191 | ["x",'y',title]; 208 | print('List: $list'); 209 | print('List[0]: ${list[0]}'); 210 | print('List[2]: ${list[2]}'); 211 | 212 | // Map: 213 | var map = { 214 | 'a': a, 215 | 'b': b, 216 | 'c': c, 217 | }; 218 | 219 | print('Map: $map'); 220 | print('Map `b`: ${map['b']}'); 221 | } 222 | 223 | } 224 | ]]> 225 | 226 | 227 | [ 228 | ["Integers:", 10, 20, 30] 229 | ] 230 | 231 | 232 | ["Integers:", 30, 60, "List: [x, y, Integers:]", "List[0]: x", "List[2]: Integers:", "Map: {a: 10, b: 20, c: 30}", "Map `b`: 20"] 233 | 234 | >>> 235 | <<<< NAMESPACE="" >>>> 236 | <<<< CODE_UNIT_START="/test" >>>> 237 | class Foo { 238 | 239 | void main(List args) { 240 | var title = args[0]; 241 | var a = args[1]; 242 | var b = args[2]; 243 | var c = args[3]; 244 | var sumAB = a + b; 245 | var sumABC = a + b + c; 246 | print(title); 247 | print(sumAB); 248 | print(sumABC); 249 | var list = ['x', 'y', title]; 250 | print('List: $list'); 251 | print('List[0]: ${list[0]}'); 252 | print('List[2]: ${list[2]}'); 253 | var map = {'a': a, 'b': b, 'c': c}; 254 | print('Map: $map'); 255 | print('Map `b`: ${map['b']}'); 256 | } 257 | 258 | } 259 | <<<< CODE_UNIT_END="/test" >>>> 260 | <<<< [SOURCES_END] >>>> 261 | ]]> 262 | >>> 263 | <<<< NAMESPACE="" >>>> 264 | <<<< CODE_UNIT_START="/test" >>>> 265 | class Foo { 266 | 267 | void main(Object[] args) { 268 | var title = args[0]; 269 | var a = args[1]; 270 | var b = args[2]; 271 | var c = args[3]; 272 | var sumAB = a + b; 273 | var sumABC = a + b + c; 274 | print(title); 275 | print(sumAB); 276 | print(sumABC); 277 | var list = new ArrayList(){{ 278 | add("x"); 279 | add("y"); 280 | add(title); 281 | }}; 282 | print("List: " + list); 283 | print("List[0]: " + String.valueOf( list[0] )); 284 | print("List[2]: " + String.valueOf( list[2] )); 285 | var map = new HashMap(){{ 286 | put("a", a); 287 | put("b", b); 288 | put("c", c); 289 | }}; 290 | print("Map: " + map); 291 | print("Map `b`: " + String.valueOf( map["b"] )); 292 | } 293 | 294 | } 295 | <<<< CODE_UNIT_END="/test" >>>> 296 | <<<< [SOURCES_END] >>>> 297 | ]]> 298 | 299 | '''), 300 | TestDefinition('dart_basic_class_function_with_multi_args.test.xml', r''' 301 | 302 | 303 | 304 | a: $a ; x: $x ; y: $y ; z: $z ; b: $b' ; 322 | print(s); 323 | } 324 | } 325 | 326 | ]]> 327 | 328 | 329 | [123] 330 | 331 | 332 | ["Foo{x: int, y: int} > a: 123 ; x: 0 ; y: 10 ; z: 20 ; b: 600"] 333 | 334 | >>> 335 | <<<< NAMESPACE="" >>>> 336 | <<<< CODE_UNIT_START="/test" >>>> 337 | class Foo { 338 | 339 | int x = 0; 340 | int y = 10; 341 | 342 | int getZ() { 343 | return y * 2; 344 | } 345 | 346 | int calcB(int b1, int b2) { 347 | return y * b1 * b2; 348 | } 349 | 350 | void test(int a) { 351 | var z = getZ(); 352 | var b = calcB(z, 3); 353 | var s = '$this > a: $a ; x: $x ; y: $y ; z: $z ; b: $b'; 354 | print(s); 355 | } 356 | 357 | } 358 | <<<< CODE_UNIT_END="/test" >>>> 359 | <<<< [SOURCES_END] >>>> 360 | ]]> 361 | 362 | >>> 363 | <<<< NAMESPACE="" >>>> 364 | <<<< CODE_UNIT_START="/test" >>>> 365 | class Foo { 366 | 367 | int x = 0; 368 | int y = 10; 369 | 370 | int getZ() { 371 | return y * 2; 372 | } 373 | 374 | int calcB(int b1, int b2) { 375 | return y * b1 * b2; 376 | } 377 | 378 | void test(int a) { 379 | var z = getZ(); 380 | var b = calcB(z, 3); 381 | var s = String.valueOf( this ) + " > a: " + a + " ; x: " + x + " ; y: " + y + " ; z: " + z + " ; b: " + b; 382 | print(s); 383 | } 384 | 385 | } 386 | <<<< CODE_UNIT_END="/test" >>>> 387 | <<<< [SOURCES_END] >>>> 388 | ]]> 389 | 390 | '''), 391 | ]; 392 | 393 | await runTestDefinitions(definitions); 394 | } 395 | -------------------------------------------------------------------------------- /test/apollovm_languages_extended_test.dart: -------------------------------------------------------------------------------- 1 | @TestOn('vm') 2 | import 'dart:io'; 3 | 4 | import 'package:apollovm/apollovm.dart'; 5 | import 'package:test/test.dart'; 6 | 7 | import 'apollovm_languages_test_definition.dart'; 8 | 9 | Future main() async { 10 | var definitionsDirectory = Directory('./test/tests_definitions'); 11 | 12 | print('TESTS DEFINITIONS DIRECTORY: $definitionsDirectory'); 13 | 14 | var envVars = Platform.environment; 15 | var singleTest = envVars['SINGLE_TEST']; 16 | 17 | // ENV: SINGLE_TEST=java11_basic_for_loop_increment.test.xml 18 | 19 | if (singleTest != null) { 20 | print('SINGLE_TEST: $singleTest'); 21 | } 22 | 23 | var definitions = await definitionsDirectory 24 | .list() 25 | .where((f) => f.path.endsWith('.xml')) 26 | .where((f) => singleTest == null || f.path.endsWith('/$singleTest')) 27 | .map((f) => File(f.path)) 28 | .map((f) => TestDefinition(f.path, f.readAsStringSync())) 29 | .toList(); 30 | 31 | await runTestDefinitions(definitions); 32 | } 33 | -------------------------------------------------------------------------------- /test/apollovm_version_test.dart: -------------------------------------------------------------------------------- 1 | @TestOn('vm') 2 | 3 | import 'package:pubspec/pubspec.dart'; 4 | import 'package:swiss_knife/swiss_knife_vm.dart'; 5 | import 'package:test/test.dart'; 6 | import 'dart:io'; 7 | 8 | import 'package:path/path.dart' as path; 9 | 10 | void main() { 11 | group('ApolloVM.VERSION', () { 12 | setUp(() {}); 13 | 14 | test('Check Version', () async { 15 | var projectDirectory = Directory.current; 16 | 17 | print(projectDirectory); 18 | 19 | var pubspecFile = File(path.join(projectDirectory.path, 'pubspec.yaml')); 20 | 21 | print('pubspecFile: $pubspecFile'); 22 | 23 | var pubSpec = await PubSpec.loadFile(pubspecFile.path); 24 | 25 | print('PubSpec.name: ${pubSpec.name}'); 26 | print('PubSpec.version: ${pubSpec.version}'); 27 | 28 | var srcFile = 29 | File(path.join(projectDirectory.path, 'lib/src/apollovm_base.dart')); 30 | 31 | print(srcFile); 32 | 33 | var src = await catFile(srcFile); 34 | 35 | var versionMatch = RegExp(r"VERSION\s*=\s*'(.*?)'").firstMatch(src)!; 36 | 37 | var srcVersion = versionMatch.group(1); 38 | 39 | print('srcVersion: $srcVersion'); 40 | 41 | expect(pubSpec.version.toString(), equals(srcVersion), 42 | reason: 43 | 'ApolloVM.VERSION[$srcVersion] != PubSpec.version[${pubSpec.version}]'); 44 | }); 45 | }); 46 | } 47 | -------------------------------------------------------------------------------- /test/hello_world.dart: -------------------------------------------------------------------------------- 1 | class Foo { 2 | void main(List args) { 3 | var a0 = args[0]; 4 | 5 | print('Hello World!'); 6 | print('- args: $args'); 7 | print('- a0: $a0'); 8 | 9 | for (var i = 0; i < 1; i += 1) { 10 | var e = args[i]; 11 | print('$i> $e$e'); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /test/hello_world.java: -------------------------------------------------------------------------------- 1 | 2 | class Hello { 3 | static public void main(String[] args) { 4 | var a0 = args[0]; 5 | 6 | print("Hello World!"); 7 | print("- args: "+ args); 8 | print("- a0: "+ a0); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test/tests_definitions/dart_basic_class_field.test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | a: $a ; x: $x ; y: $y ; z: $z' ; 17 | print(s); 18 | } 19 | } 20 | 21 | ]]> 22 | 23 | 24 | [ 123 ] 25 | 26 | 27 | ["Foo{x: Null, y: int} > a: 123 ; x: null ; y: 10 ; z: 20"] 28 | 29 | >>> 30 | <<<< NAMESPACE="" >>>> 31 | <<<< CODE_UNIT_START="/test" >>>> 32 | class Foo { 33 | 34 | int x; 35 | int y = 10; 36 | 37 | int getZ() { 38 | return y * 2; 39 | } 40 | 41 | void test(int a) { 42 | var z = getZ(); 43 | var s = '$this > a: $a ; x: $x ; y: $y ; z: $z'; 44 | print(s); 45 | } 46 | 47 | } 48 | <<<< CODE_UNIT_END="/test" >>>> 49 | <<<< [SOURCES_END] >>>> 50 | ]]> 51 | 52 | >>> 53 | <<<< NAMESPACE="" >>>> 54 | <<<< CODE_UNIT_START="/test" >>>> 55 | class Foo { 56 | 57 | int x; 58 | int y = 10; 59 | 60 | int getZ() { 61 | return y * 2; 62 | } 63 | 64 | void test(int a) { 65 | var z = getZ(); 66 | var s = String.valueOf( this ) + " > a: " + a + " ; x: " + x + " ; y: " + y + " ; z: " + z; 67 | print(s); 68 | } 69 | 70 | } 71 | <<<< CODE_UNIT_END="/test" >>>> 72 | <<<< [SOURCES_END] >>>> 73 | ]]> 74 | 75 | -------------------------------------------------------------------------------- /test/tests_definitions/dart_basic_class_function.test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | a: $a' ; 9 | print(s); 10 | } 11 | } 12 | 13 | ]]> 14 | 15 | 16 | [ 123 ] 17 | 18 | 19 | ["Foo{} > a: 123"] 20 | 21 | >>> 22 | <<<< NAMESPACE="" >>>> 23 | <<<< CODE_UNIT_START="/test" >>>> 24 | class Foo { 25 | 26 | void test(int a) { 27 | var s = '$this > a: $a'; 28 | print(s); 29 | } 30 | 31 | } 32 | <<<< CODE_UNIT_END="/test" >>>> 33 | <<<< [SOURCES_END] >>>> 34 | ]]> 35 | 36 | >>> 37 | <<<< NAMESPACE="" >>>> 38 | <<<< CODE_UNIT_START="/test" >>>> 39 | class Foo { 40 | 41 | void test(int a) { 42 | var s = String.valueOf( this ) + " > a: " + a; 43 | print(s); 44 | } 45 | 46 | } 47 | <<<< CODE_UNIT_END="/test" >>>> 48 | <<<< [SOURCES_END] >>>> 49 | ]]> 50 | 51 | -------------------------------------------------------------------------------- /test/tests_definitions/dart_basic_class_function_with_multi_args.test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | a: $a ; x: $x ; y: $y ; z: $z ; b: $b' ; 22 | print(s); 23 | } 24 | } 25 | 26 | ]]> 27 | 28 | 29 | [123] 30 | 31 | 32 | ["Foo{x: int, y: int} > a: 123 ; x: 0 ; y: 10 ; z: 20 ; b: 600"] 33 | 34 | >>> 35 | <<<< NAMESPACE="" >>>> 36 | <<<< CODE_UNIT_START="/test" >>>> 37 | class Foo { 38 | 39 | int x = 0; 40 | int y = 10; 41 | 42 | int getZ() { 43 | return y * 2; 44 | } 45 | 46 | int calcB(int b1, int b2) { 47 | return y * b1 * b2; 48 | } 49 | 50 | void test(int a) { 51 | var z = getZ(); 52 | var b = calcB(z, 3); 53 | var s = '$this > a: $a ; x: $x ; y: $y ; z: $z ; b: $b'; 54 | print(s); 55 | } 56 | 57 | } 58 | <<<< CODE_UNIT_END="/test" >>>> 59 | <<<< [SOURCES_END] >>>> 60 | ]]> 61 | 62 | >>> 63 | <<<< NAMESPACE="" >>>> 64 | <<<< CODE_UNIT_START="/test" >>>> 65 | class Foo { 66 | 67 | int x = 0; 68 | int y = 10; 69 | 70 | int getZ() { 71 | return y * 2; 72 | } 73 | 74 | int calcB(int b1, int b2) { 75 | return y * b1 * b2; 76 | } 77 | 78 | void test(int a) { 79 | var z = getZ(); 80 | var b = calcB(z, 3); 81 | var s = String.valueOf( this ) + " > a: " + a + " ; x: " + x + " ; y: " + y + " ; z: " + z + " ; b: " + b; 82 | print(s); 83 | } 84 | 85 | } 86 | <<<< CODE_UNIT_END="/test" >>>> 87 | <<<< [SOURCES_END] >>>> 88 | ]]> 89 | 90 | -------------------------------------------------------------------------------- /test/tests_definitions/dart_basic_class_function_with_multi_args_and_comments.test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | a: $a ; x: $x ; y: $y ; z: $z ; b: $b' ; 30 | print(s); 31 | // Comment X 32 | var f = IF(1 > 2, 1, 2); 33 | print(f) ; 34 | // Comment X 35 | return b; 36 | } 37 | } 38 | 39 | ]]> 40 | 41 | 42 | [123] 43 | 44 | 45 | ["Foo{x: int, y: int} > a: 123 ; x: 0 ; y: 10 ; z: 20 ; b: 600", 2] 46 | 47 | >>> 48 | <<<< NAMESPACE="" >>>> 49 | <<<< CODE_UNIT_START="/test" >>>> 50 | class Foo { 51 | 52 | int x = 0; 53 | int y = 10; 54 | 55 | int getZ() { 56 | return y * 2; 57 | } 58 | 59 | int calcB(int b1, int b2) { 60 | return y * b1 * b2; 61 | } 62 | 63 | int IF(bool b, int p1, int p2) { 64 | if (b) { 65 | return p1; 66 | } else { 67 | return p2; 68 | } 69 | 70 | } 71 | 72 | int test(int a) { 73 | var z = getZ(); 74 | var b = calcB(z, 3); 75 | var s = '$this > a: $a ; x: $x ; y: $y ; z: $z ; b: $b'; 76 | print(s); 77 | var f = IF(1 > 2, 1, 2); 78 | print(f); 79 | return b; 80 | } 81 | 82 | } 83 | <<<< CODE_UNIT_END="/test" >>>> 84 | <<<< [SOURCES_END] >>>> 85 | ]]> 86 | 87 | >>> 88 | <<<< NAMESPACE="" >>>> 89 | <<<< CODE_UNIT_START="/test" >>>> 90 | class Foo { 91 | 92 | int x = 0; 93 | int y = 10; 94 | 95 | int getZ() { 96 | return y * 2; 97 | } 98 | 99 | int calcB(int b1, int b2) { 100 | return y * b1 * b2; 101 | } 102 | 103 | int IF(bool b, int p1, int p2) { 104 | if (b) { 105 | return p1; 106 | } else { 107 | return p2; 108 | } 109 | 110 | } 111 | 112 | int test(int a) { 113 | var z = getZ(); 114 | var b = calcB(z, 3); 115 | var s = String.valueOf( this ) + " > a: " + a + " ; x: " + x + " ; y: " + y + " ; z: " + z + " ; b: " + b; 116 | print(s); 117 | var f = IF(1 > 2, 1, 2); 118 | print(f); 119 | return b; 120 | } 121 | 122 | } 123 | <<<< CODE_UNIT_END="/test" >>>> 124 | <<<< [SOURCES_END] >>>> 125 | ]]> 126 | 127 | -------------------------------------------------------------------------------- /test/tests_definitions/dart_basic_class_this_function.test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | a: $a ; b: $b ; c: $c' ; 17 | print(s); 18 | } 19 | } 20 | 21 | ]]> 22 | 23 | 24 | [ 123 ] 25 | 26 | 27 | ["Foo{} > a: 123 ; b: 1230 ; c: 12300"] 28 | 29 | >>> 30 | <<<< NAMESPACE="" >>>> 31 | <<<< CODE_UNIT_START="/test" >>>> 32 | class Foo { 33 | 34 | int m10(int a) { 35 | return a * 10; 36 | } 37 | 38 | void test(int a) { 39 | var b = m10(a); 40 | var self = this; 41 | var c = self.m10(b); 42 | var s = '$this > a: $a ; b: $b ; c: $c'; 43 | print(s); 44 | } 45 | 46 | } 47 | <<<< CODE_UNIT_END="/test" >>>> 48 | <<<< [SOURCES_END] >>>> 49 | ]]> 50 | 51 | >>> 52 | <<<< NAMESPACE="" >>>> 53 | <<<< CODE_UNIT_START="/test" >>>> 54 | class Foo { 55 | 56 | int m10(int a) { 57 | return a * 10; 58 | } 59 | 60 | void test(int a) { 61 | var b = m10(a); 62 | var self = this; 63 | var c = self.m10(b); 64 | var s = String.valueOf( this ) + " > a: " + a + " ; b: " + b + " ; c: " + c; 65 | print(s); 66 | } 67 | 68 | } 69 | <<<< CODE_UNIT_END="/test" >>>> 70 | <<<< [SOURCES_END] >>>> 71 | ]]> 72 | 73 | -------------------------------------------------------------------------------- /test/tests_definitions/dart_basic_for_loop.test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | args) { 7 | var title = args[0]; 8 | var init = args[1]; 9 | var end = args[2]; 10 | var increment = args[3]; 11 | 12 | print(title); 13 | 14 | for (var i = init ; i <= end; i += increment) { 15 | print(i); 16 | } 17 | } 18 | } 19 | ]]> 20 | 21 | 22 | [ 23 | ["For loop:", 10, 20, 1] 24 | ] 25 | 26 | 27 | ["For loop:", 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20] 28 | 29 | 30 | [ 31 | ["For loop:", 10, 20, 2] 32 | ] 33 | 34 | 35 | ["For loop:", 10, 12, 14, 16, 18, 20] 36 | 37 | >>> 38 | <<<< NAMESPACE="" >>>> 39 | <<<< CODE_UNIT_START="/test" >>>> 40 | class Foo { 41 | 42 | void main(List args) { 43 | var title = args[0]; 44 | var init = args[1]; 45 | var end = args[2]; 46 | var increment = args[3]; 47 | print(title); 48 | for (var i = init; i <= end ; i += increment) { 49 | print(i); 50 | } 51 | } 52 | 53 | } 54 | <<<< CODE_UNIT_END="/test" >>>> 55 | <<<< [SOURCES_END] >>>> 56 | ]]> 57 | >>> 58 | <<<< NAMESPACE="" >>>> 59 | <<<< CODE_UNIT_START="/test" >>>> 60 | class Foo { 61 | 62 | void main(Object[] args) { 63 | var title = args[0]; 64 | var init = args[1]; 65 | var end = args[2]; 66 | var increment = args[3]; 67 | print(title); 68 | for (var i = init; i <= end ; i += increment) { 69 | print(i); 70 | } 71 | } 72 | 73 | } 74 | <<<< CODE_UNIT_END="/test" >>>> 75 | <<<< [SOURCES_END] >>>> 76 | ]]> 77 | 78 | -------------------------------------------------------------------------------- /test/tests_definitions/dart_basic_main_1.test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | args) { 6 | var title = args[0]; 7 | var a = args[1]; 8 | var b = args[2]; 9 | var c = args[3]; 10 | var sumAB = a + b ; 11 | var sumABC = a + b + c; 12 | var greater = sumABC > sumAB ; 13 | print(title); 14 | print(sumAB); 15 | print(sumABC); 16 | if ( greater ) { 17 | var eq = greater == true ; 18 | print('sumABC > sumAB = $eq'); 19 | } 20 | } 21 | ]]> 22 | 23 | 24 | [ 25 | ["Sums:", 10, 20, 50] 26 | ] 27 | 28 | 29 | ["Sums:", 30, 80, "sumABC > sumAB = true"] 30 | 31 | >>> 32 | <<<< NAMESPACE="" >>>> 33 | <<<< CODE_UNIT_START="/test" >>>> 34 | void main(List args) { 35 | var title = args[0]; 36 | var a = args[1]; 37 | var b = args[2]; 38 | var c = args[3]; 39 | var sumAB = a + b; 40 | var sumABC = a + b + c; 41 | var greater = sumABC > sumAB; 42 | print(title); 43 | print(sumAB); 44 | print(sumABC); 45 | if (greater) { 46 | var eq = greater == true; 47 | print('sumABC > sumAB = $eq'); 48 | } 49 | 50 | } 51 | 52 | <<<< CODE_UNIT_END="/test" >>>> 53 | <<<< [SOURCES_END] >>>> 54 | ]]> 55 | 56 | -------------------------------------------------------------------------------- /test/tests_definitions/dart_basic_main_2.test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | args) { 6 | var title = args[0]; 7 | var a = args[1]; 8 | var b = args[2]; 9 | var c = args[3]; 10 | var sumAB = a + b ; 11 | var sumABC = a + b + c; 12 | print(title); 13 | print(sumAB); 14 | print(sumABC); 15 | } 16 | ]]> 17 | 18 | 19 | [ 20 | ["Strings:", "A", "B", "C"] 21 | ] 22 | 23 | 24 | ["Strings:", "AB", "ABC"] 25 | 26 | >>> 27 | <<<< NAMESPACE="" >>>> 28 | <<<< CODE_UNIT_START="/test" >>>> 29 | void main(List args) { 30 | var title = args[0]; 31 | var a = args[1]; 32 | var b = args[2]; 33 | var c = args[3]; 34 | var sumAB = a + b; 35 | var sumABC = a + b + c; 36 | print(title); 37 | print(sumAB); 38 | print(sumABC); 39 | } 40 | 41 | <<<< CODE_UNIT_END="/test" >>>> 42 | <<<< [SOURCES_END] >>>> 43 | ]]> 44 | 45 | -------------------------------------------------------------------------------- /test/tests_definitions/dart_basic_main_3_negation.test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | args) { 6 | var title = args[0]; 7 | var a = args[1]; 8 | var b = args[2]; 9 | var c = args[3]; 10 | var sumAB = a + b ; 11 | var sumABC = a + b + c; 12 | var lower = sumABC < sumAB ; 13 | print(title); 14 | print(sumAB); 15 | print(sumABC); 16 | if ( !lower ) { 17 | var eq = lower == false ; 18 | print('[NOT] sumABC:$sumABC > sumAB:$sumAB = $eq'); 19 | } else { 20 | var eq = lower == true ; 21 | print('sumABC:$sumABC < sumAB:$sumAB = $eq'); 22 | } 23 | } 24 | ]]> 25 | 26 | 27 | [ 28 | ["Sums:", 10, 20, 50] 29 | ] 30 | 31 | 32 | ["Sums:", 30, 80, "[NOT] sumABC:80 > sumAB:30 = true"] 33 | 34 | 35 | [ 36 | ["Sums:", 10, 20, -50] 37 | ] 38 | 39 | 40 | ["Sums:", 30, -20, "sumABC:-20 < sumAB:30 = true"] 41 | 42 | >>> 43 | <<<< NAMESPACE="" >>>> 44 | <<<< CODE_UNIT_START="/test" >>>> 45 | void main(List args) { 46 | var title = args[0]; 47 | var a = args[1]; 48 | var b = args[2]; 49 | var c = args[3]; 50 | var sumAB = a + b; 51 | var sumABC = a + b + c; 52 | var lower = sumABC < sumAB; 53 | print(title); 54 | print(sumAB); 55 | print(sumABC); 56 | if (!lower) { 57 | var eq = lower == false; 58 | print('[NOT] sumABC:$sumABC > sumAB:$sumAB = $eq'); 59 | } else { 60 | var eq = lower == true; 61 | print('sumABC:$sumABC < sumAB:$sumAB = $eq'); 62 | } 63 | 64 | } 65 | 66 | <<<< CODE_UNIT_END="/test" >>>> 67 | <<<< [SOURCES_END] >>>> 68 | ]]> 69 | 70 | -------------------------------------------------------------------------------- /test/tests_definitions/dart_basic_main_with_division.test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | args) { 7 | var title = args[0]; 8 | var a = args[1]; 9 | var b = args[2] ~/ 2; 10 | var c = args[3] * 3; 11 | 12 | if (c > 120) { 13 | c = 120 ; 14 | } 15 | 16 | var str = 'variables> a: $a ; b: $b ; c: $c' ; 17 | var sumAB = a + b ; 18 | var sumABC = a + b + c; 19 | 20 | print(str); 21 | print(title); 22 | print(sumAB); 23 | print(sumABC); 24 | } 25 | 26 | ]]> 27 | 28 | 29 | [ 30 | ["Sums:", 10, 30, 50] 31 | ] 32 | 33 | 34 | ["variables> a: 10 ; b: 15 ; c: 120", "Sums:", 25, 145] 35 | 36 | >>> 37 | <<<< NAMESPACE="" >>>> 38 | <<<< CODE_UNIT_START="/test" >>>> 39 | void main(List args) { 40 | var title = args[0]; 41 | var a = args[1]; 42 | var b = args[2] ~/ 2; 43 | var c = args[3] * 3; 44 | if (c > 120) { 45 | c = 120; 46 | } 47 | 48 | var str = 'variables> a: $a ; b: $b ; c: $c'; 49 | var sumAB = a + b; 50 | var sumABC = a + b + c; 51 | print(str); 52 | print(title); 53 | print(sumAB); 54 | print(sumABC); 55 | } 56 | 57 | <<<< CODE_UNIT_END="/test" >>>> 58 | <<<< [SOURCES_END] >>>> 59 | ]]> 60 | 61 | -------------------------------------------------------------------------------- /test/tests_definitions/dart_basic_vars.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | 21 | [ ] 22 | 23 | 24 | [579, "c: 579"] 25 | 26 | >>> 27 | <<<< NAMESPACE="" >>>> 28 | <<<< CODE_UNIT_START="/test" >>>> 29 | class Foo { 30 | 31 | void main(List args) { 32 | var a = 123; 33 | var b = 456; 34 | var c = a + b; 35 | print(c); 36 | print('c: $c'); 37 | } 38 | 39 | } 40 | <<<< CODE_UNIT_END="/test" >>>> 41 | <<<< [SOURCES_END] >>>> 42 | ]]> 43 | 44 | >>> 45 | <<<< NAMESPACE="" >>>> 46 | <<<< CODE_UNIT_START="/test" >>>> 47 | class Foo { 48 | 49 | void main(Object[] args) { 50 | var a = 123; 51 | var b = 456; 52 | var c = a + b; 53 | print(c); 54 | print("c: " + c); 55 | } 56 | 57 | } 58 | <<<< CODE_UNIT_END="/test" >>>> 59 | <<<< [SOURCES_END] >>>> 60 | ]]> 61 | 62 | -------------------------------------------------------------------------------- /test/tests_definitions/dart_basic_with_branch.test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | args) { 8 | var a = args[0] ; 9 | var b = args[1] ; 10 | var eq = a == b ; 11 | 12 | if (a == b) { 13 | print('if: a==b'); 14 | } 15 | 16 | if (a != b) { 17 | print('if: a!=b'); 18 | } 19 | else { 20 | print('else: a!=b'); 21 | } 22 | 23 | if (a < b) { 24 | print('if: a b) { 27 | print('else: a>b'); 28 | } 29 | else { 30 | print('else: a==b'); 31 | } 32 | } 33 | } 34 | 35 | ]]> 36 | 37 | 38 | [ 39 | [10, 20] 40 | ] 41 | 42 | 43 | ["if: a!=b", "if: a<b"] 44 | 45 | >>> 46 | <<<< NAMESPACE="" >>>> 47 | <<<< CODE_UNIT_START="/test" >>>> 48 | class Bar { 49 | 50 | static void main(List args) { 51 | var a = args[0]; 52 | var b = args[1]; 53 | var eq = a == b; 54 | if (a == b) { 55 | print('if: a==b'); 56 | } 57 | 58 | if (a != b) { 59 | print('if: a!=b'); 60 | } else { 61 | print('else: a!=b'); 62 | } 63 | 64 | if (a < b) { 65 | print('if: a b) { 67 | print('else: a>b'); 68 | } else { 69 | print('else: a==b'); 70 | } 71 | 72 | } 73 | 74 | } 75 | <<<< CODE_UNIT_END="/test" >>>> 76 | <<<< [SOURCES_END] >>>> 77 | ]]> 78 | 79 | -------------------------------------------------------------------------------- /test/tests_definitions/dart_basic_with_comparisons.test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | args) { 8 | var a = args[0] ; 9 | var b = args[1] ; 10 | var eq = a == b ; 11 | var notEq = a != b ; 12 | var greater = a > b ; 13 | var lower = a < b ; 14 | var greaterOrEq = a >= b ; 15 | var lowerOrEq = a <= b ; 16 | print(eq); 17 | print(notEq); 18 | print(greater); 19 | print(lower); 20 | print(greaterOrEq); 21 | print(lowerOrEq); 22 | } 23 | } 24 | 25 | ]]> 26 | 27 | 28 | [ 29 | [10, 20] 30 | ] 31 | 32 | 33 | [false, true, false, true, false, true] 34 | 35 | 36 | >>> 37 | <<<< NAMESPACE="" >>>> 38 | <<<< CODE_UNIT_START="/test" >>>> 39 | class Bar { 40 | 41 | static void main(List args) { 42 | var a = args[0]; 43 | var b = args[1]; 44 | var eq = a == b; 45 | var notEq = a != b; 46 | var greater = a > b; 47 | var lower = a < b; 48 | var greaterOrEq = a >= b; 49 | var lowerOrEq = a <= b; 50 | print(eq); 51 | print(notEq); 52 | print(greater); 53 | print(lower); 54 | print(greaterOrEq); 55 | print(lowerOrEq); 56 | } 57 | 58 | } 59 | <<<< CODE_UNIT_END="/test" >>>> 60 | <<<< [SOURCES_END] >>>> 61 | ]]> 62 | 63 | >>> 64 | <<<< NAMESPACE="" >>>> 65 | <<<< CODE_UNIT_START="/test" >>>> 66 | class Bar { 67 | 68 | static void main(Object[] args) { 69 | var a = args[0]; 70 | var b = args[1]; 71 | var eq = a == b; 72 | var notEq = a != b; 73 | var greater = a > b; 74 | var lower = a < b; 75 | var greaterOrEq = a >= b; 76 | var lowerOrEq = a <= b; 77 | print(eq); 78 | print(notEq); 79 | print(greater); 80 | print(lower); 81 | print(greaterOrEq); 82 | print(lowerOrEq); 83 | } 84 | 85 | } 86 | <<<< CODE_UNIT_END="/test" >>>> 87 | <<<< [SOURCES_END] >>>> 88 | ]]> 89 | 90 | -------------------------------------------------------------------------------- /test/tests_definitions/dart_basic_with_inline_string.test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | args) { 7 | var title = args[0]; 8 | var a = args[1]; 9 | var b = args[2]; 10 | var s1 = 'inline'; 11 | var s2 = r'string'; 12 | var c = s1 + ' \t' +"\t " + s2 ; 13 | var sumAB = a + b ; 14 | var sumABC = a + b + c; 15 | print(title); 16 | print(sumAB); 17 | print(sumABC); 18 | } 19 | 20 | ]]> 21 | 22 | 23 | [ 24 | ["Operations:", 10, 20] 25 | ] 26 | 27 | 28 | ["Operations:", 30, "1020inline \t\t string"] 29 | 30 | >>> 31 | <<<< NAMESPACE="" >>>> 32 | <<<< CODE_UNIT_START="/test" >>>> 33 | void main(List args) { 34 | var title = args[0]; 35 | var a = args[1]; 36 | var b = args[2]; 37 | var s1 = 'inline'; 38 | var s2 = 'string'; 39 | var c = '$s1 \t\t $s2'; 40 | var sumAB = a + b; 41 | var sumABC = a + b + c; 42 | print(title); 43 | print(sumAB); 44 | print(sumABC); 45 | } 46 | 47 | <<<< CODE_UNIT_END="/test" >>>> 48 | <<<< [SOURCES_END] >>>> 49 | ]]> 50 | 51 | -------------------------------------------------------------------------------- /test/tests_definitions/dart_basic_with_multiline_string.test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | args) { 7 | var title = args[0]; 8 | var a = args[1]; 9 | var b = args[2]; 10 | var l = '''line1 11 | line2 12 | line3 13 | '''; 14 | var s = a + '\\::' + l + b; 15 | print(title); 16 | print(s); 17 | } 18 | 19 | ]]> 20 | 21 | 22 | [ 23 | ["Multiline:", 10, 20] 24 | ] 25 | 26 | 27 | ["Multiline:", "10\\::line1\nline2\nline3\n20"] 28 | 29 | >>> 30 | <<<< NAMESPACE="" >>>> 31 | <<<< CODE_UNIT_START="/test" >>>> 32 | void main(List args) { 33 | var title = args[0]; 34 | var a = args[1]; 35 | var b = args[2]; 36 | var l = 'line1\nline2\nline3\n'; 37 | var s = a + r'\::' + l + b; 38 | print(title); 39 | print(s); 40 | } 41 | 42 | <<<< CODE_UNIT_END="/test" >>>> 43 | <<<< [SOURCES_END] >>>> 44 | ]]> 45 | 46 | -------------------------------------------------------------------------------- /test/tests_definitions/dart_basic_with_raw_multiline_string.test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | args) { 7 | var m1 = '''single \'quote\''''; 8 | var rm1 = r'''double \"quote\"'''; 9 | var m2 = """double \"quote\""""; 10 | var rm2 = r"""single \'quote\'"""; 11 | print(m1); 12 | print(m2); 13 | print(rm1); 14 | print(rm2); 15 | } 16 | 17 | ]]> 18 | 19 | 20 | [ ] 21 | 22 | 23 | [ 24 | "single 'quote'", 25 | "double \"quote\"", 26 | "double \\\"quote\\\"", 27 | "single \\'quote\\'" 28 | ] 29 | 30 | >>> 31 | <<<< NAMESPACE="" >>>> 32 | <<<< CODE_UNIT_START="/test" >>>> 33 | void main(List args) { 34 | var m1 = "single 'quote'"; 35 | var rm1 = r'double \"quote\"'; 36 | var m2 = 'double "quote"'; 37 | var rm2 = r"single \'quote\'"; 38 | print(m1); 39 | print(m2); 40 | print(rm1); 41 | print(rm2); 42 | } 43 | 44 | <<<< CODE_UNIT_END="/test" >>>> 45 | <<<< [SOURCES_END] >>>> 46 | ]]> 47 | 48 | -------------------------------------------------------------------------------- /test/tests_definitions/dart_basic_with_raw_string.test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | args) { 7 | var s1 = 'single \'quote\''; 8 | var s2 = "double \"quote\""; 9 | var r1 = r"single \'quote\'"; 10 | var r2 = r'double \"quote\"'; 11 | print(s1); 12 | print(s2); 13 | print(r1); 14 | print(r2); 15 | } 16 | 17 | ]]> 18 | 19 | 20 | [ ] 21 | 22 | 23 | [ 24 | "single 'quote'", 25 | "double \"quote\"", 26 | "single \\'quote\\'", 27 | "double \\\"quote\\\"" 28 | ] 29 | 30 | >>> 31 | <<<< NAMESPACE="" >>>> 32 | <<<< CODE_UNIT_START="/test" >>>> 33 | void main(List args) { 34 | var s1 = "single 'quote'"; 35 | var s2 = 'double "quote"'; 36 | var r1 = r"single \'quote\'"; 37 | var r2 = r'double \"quote\"'; 38 | print(s1); 39 | print(s2); 40 | print(r1); 41 | print(r2); 42 | } 43 | 44 | <<<< CODE_UNIT_END="/test" >>>> 45 | <<<< [SOURCES_END] >>>> 46 | ]]> 47 | 48 | -------------------------------------------------------------------------------- /test/tests_definitions/dart_basic_with_string_variable.test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | args) { 8 | var a = 123 ; 9 | var b = 123 * 2 ; 10 | var sv1 = 'a: <$a>;\t\$b->a*2: $b ;\ta*3: ${ a * 3 }!' ; 11 | print(sv1); 12 | var sv2 = '$a$a'; 13 | print(sv2); 14 | } 15 | } 16 | 17 | ]]> 18 | 19 | 20 | [ ] 21 | 22 | 23 | ["a: <123>;\t$b->a*2: 246 ;\ta*3: 369!", "123123"] 24 | 25 | >>> 26 | <<<< NAMESPACE="" >>>> 27 | <<<< CODE_UNIT_START="/test" >>>> 28 | class Foo { 29 | 30 | static void main(List args) { 31 | var a = 123; 32 | var b = 123 * 2; 33 | var sv1 = 'a: <$a>;\t\$b->a*2: $b ;\ta*3: ${a * 3}!'; 34 | print(sv1); 35 | var sv2 = '$a$a'; 36 | print(sv2); 37 | } 38 | 39 | } 40 | <<<< CODE_UNIT_END="/test" >>>> 41 | <<<< [SOURCES_END] >>>> 42 | ]]> 43 | 44 | >>> 45 | <<<< NAMESPACE="" >>>> 46 | <<<< CODE_UNIT_START="/test" >>>> 47 | class Foo { 48 | 49 | static void main(String[] args) { 50 | var a = 123; 51 | var b = 123 * 2; 52 | var sv1 = "a: <" + a + ">;\t$b->a*2: " + b + " ;\ta*3: " + String.valueOf( a * 3 ) + "!"; 53 | print(sv1); 54 | var sv2 = String.valueOf( a ) + a; 55 | print(sv2); 56 | } 57 | 58 | } 59 | <<<< CODE_UNIT_END="/test" >>>> 60 | <<<< [SOURCES_END] >>>> 61 | ]]> 62 | 63 | -------------------------------------------------------------------------------- /test/tests_definitions/dart_core_lc.test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 19 | 20 | [ 123 ] 21 | 22 | 23 | ["Param A: 123", "param a: 123", "PARAM A: 123"] 24 | 25 | >>> 26 | <<<< NAMESPACE="" >>>> 27 | <<<< CODE_UNIT_START="/test" >>>> 28 | class Foo { 29 | 30 | void test(int a) { 31 | var s = 'Param A: $a'; 32 | var sLC = s.toLowerCase(); 33 | var sUC = sLC.toUpperCase(); 34 | print(s); 35 | print(sLC); 36 | print(sUC); 37 | } 38 | 39 | } 40 | <<<< CODE_UNIT_END="/test" >>>> 41 | <<<< [SOURCES_END] >>>> 42 | ]]> 43 | >>> 44 | <<<< NAMESPACE="" >>>> 45 | <<<< CODE_UNIT_START="/test" >>>> 46 | class Foo { 47 | 48 | void test(int a) { 49 | var s = "Param A: " + a; 50 | var sLC = s.toLowerCase(); 51 | var sUC = sLC.toUpperCase(); 52 | print(s); 53 | print(sLC); 54 | print(sUC); 55 | } 56 | 57 | } 58 | <<<< CODE_UNIT_END="/test" >>>> 59 | <<<< [SOURCES_END] >>>> 60 | ]]> 61 | 62 | -------------------------------------------------------------------------------- /test/tests_definitions/java11_basic_args.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | 21 | [["10", 20]] 22 | 23 | 24 | ["a: 10", "b: 20", "c: 30"] 25 | 26 | >>> 27 | <<<< NAMESPACE="" >>>> 28 | <<<< CODE_UNIT_START="/test" >>>> 29 | class Foo { 30 | 31 | void main(List args) { 32 | var a = int.parse(args[0]); 33 | var b = args[1]; 34 | var c = a + b; 35 | print('a: $a'); 36 | print('b: $b'); 37 | print('c: $c'); 38 | } 39 | 40 | } 41 | <<<< CODE_UNIT_END="/test" >>>> 42 | <<<< [SOURCES_END] >>>> 43 | ]]> 44 | 45 | >>> 46 | <<<< NAMESPACE="" >>>> 47 | <<<< CODE_UNIT_START="/test" >>>> 48 | class Foo { 49 | 50 | void main(Object[] args) { 51 | var a = Integer.parseInt(args[0]); 52 | var b = args[1]; 53 | var c = a + b; 54 | print("a: " + a); 55 | print("b: " + b); 56 | print("c: " + c); 57 | } 58 | 59 | } 60 | <<<< CODE_UNIT_END="/test" >>>> 61 | <<<< [SOURCES_END] >>>> 62 | ]]> 63 | 64 | -------------------------------------------------------------------------------- /test/tests_definitions/java11_basic_class_field.test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | a: "+ a +" ; x: "+ x +" ; y: "+ y +" ; z: "+ z ; 17 | print(s); 18 | } 19 | } 20 | 21 | ]]> 22 | 23 | 24 | [ 123 ] 25 | 26 | 27 | ["Foo{x: Null, y: int} > a: 123 ; x: null ; y: 10 ; z: 20"] 28 | 29 | >>> 30 | <<<< NAMESPACE="" >>>> 31 | <<<< CODE_UNIT_START="/test" >>>> 32 | class Foo { 33 | 34 | int x; 35 | int y = 10; 36 | 37 | int getZ() { 38 | return y * 2; 39 | } 40 | 41 | void test(int a) { 42 | var z = getZ(); 43 | var s = '$this > a: $a ; x: $x ; y: $y ; z: $z'; 44 | print(s); 45 | } 46 | 47 | } 48 | <<<< CODE_UNIT_END="/test" >>>> 49 | <<<< [SOURCES_END] >>>> 50 | ]]> 51 | 52 | >>> 53 | <<<< NAMESPACE="" >>>> 54 | <<<< CODE_UNIT_START="/test" >>>> 55 | class Foo { 56 | 57 | int x; 58 | int y = 10; 59 | 60 | int getZ() { 61 | return y * 2; 62 | } 63 | 64 | void test(int a) { 65 | var z = getZ(); 66 | var s = this + " > a: " + a + " ; x: " + x + " ; y: " + y + " ; z: " + z; 67 | print(s); 68 | } 69 | 70 | } 71 | <<<< CODE_UNIT_END="/test" >>>> 72 | <<<< [SOURCES_END] >>>> 73 | ]]> 74 | 75 | -------------------------------------------------------------------------------- /test/tests_definitions/java11_basic_class_function_with_multi_args.test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | a: "+ a +" ; x: "+ x +" ; y: "+ y +" ; z: "+ z +" ; b: "+ b ; 22 | print(s); 23 | } 24 | } 25 | 26 | ]]> 27 | 28 | 29 | [ 123 ] 30 | 31 | 32 | ["Foo{x: int, y: int} > a: 123 ; x: 0 ; y: 10 ; z: 20 ; b: 600"] 33 | 34 | >>> 35 | <<<< NAMESPACE="" >>>> 36 | <<<< CODE_UNIT_START="/test" >>>> 37 | class Foo { 38 | 39 | int x = 0; 40 | int y = 10; 41 | 42 | int getZ() { 43 | return y * 2; 44 | } 45 | 46 | int calcB(int b1, int b2) { 47 | return y * b1 * b2; 48 | } 49 | 50 | void test(int a) { 51 | var z = getZ(); 52 | var b = calcB(z, 3); 53 | var s = '$this > a: $a ; x: $x ; y: $y ; z: $z ; b: $b'; 54 | print(s); 55 | } 56 | 57 | } 58 | <<<< CODE_UNIT_END="/test" >>>> 59 | <<<< [SOURCES_END] >>>> 60 | ]]> 61 | 62 | >>> 63 | <<<< NAMESPACE="" >>>> 64 | <<<< CODE_UNIT_START="/test" >>>> 65 | class Foo { 66 | 67 | int x = 0; 68 | int y = 10; 69 | 70 | int getZ() { 71 | return y * 2; 72 | } 73 | 74 | int calcB(int b1, int b2) { 75 | return y * b1 * b2; 76 | } 77 | 78 | void test(int a) { 79 | var z = getZ(); 80 | var b = calcB(z, 3); 81 | var s = this + " > a: " + a + " ; x: " + x + " ; y: " + y + " ; z: " + z + " ; b: " + b; 82 | print(s); 83 | } 84 | 85 | } 86 | <<<< CODE_UNIT_END="/test" >>>> 87 | <<<< [SOURCES_END] >>>> 88 | ]]> 89 | 90 | -------------------------------------------------------------------------------- /test/tests_definitions/java11_basic_class_function_with_multi_args_and_comments.test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | a: "+ a +" ; x: "+ x +" ; y: "+ y +" ; z: "+ z +" ; b: "+ b ; 31 | print(s); 32 | // Comment X 33 | var f = IF(1 > 2, 1, 2); 34 | print(f) ; 35 | // Comment X 36 | return b; 37 | } 38 | } 39 | 40 | ]]> 41 | 42 | 43 | [ 123 ] 44 | 45 | 46 | ["Foo{x: int, y: int} > a: 123 ; x: 0 ; y: 10 ; z: 20 ; b: 600", 2] 47 | 48 | >>> 49 | <<<< NAMESPACE="" >>>> 50 | <<<< CODE_UNIT_START="/test" >>>> 51 | class Foo { 52 | 53 | int x = 0; 54 | int y = 10; 55 | 56 | int getZ() { 57 | return y * 2; 58 | } 59 | 60 | int calcB(int b1, int b2) { 61 | return y * b1 * b2; 62 | } 63 | 64 | int IF(bool b, int p1, int p2) { 65 | if (b) { 66 | return p1; 67 | } else { 68 | return p2; 69 | } 70 | 71 | } 72 | 73 | int test(int a) { 74 | var z = getZ(); 75 | var b = calcB(z, 3); 76 | var s = '$this > a: $a ; x: $x ; y: $y ; z: $z ; b: $b'; 77 | print(s); 78 | var f = IF(1 > 2, 1, 2); 79 | print(f); 80 | return b; 81 | } 82 | 83 | } 84 | <<<< CODE_UNIT_END="/test" >>>> 85 | <<<< [SOURCES_END] >>>> 86 | ]]> 87 | 88 | >>> 89 | <<<< NAMESPACE="" >>>> 90 | <<<< CODE_UNIT_START="/test" >>>> 91 | class Foo { 92 | 93 | int x = 0; 94 | int y = 10; 95 | 96 | int getZ() { 97 | return y * 2; 98 | } 99 | 100 | int calcB(int b1, int b2) { 101 | return y * b1 * b2; 102 | } 103 | 104 | int IF(bool b, int p1, int p2) { 105 | if (b) { 106 | return p1; 107 | } else { 108 | return p2; 109 | } 110 | 111 | } 112 | 113 | int test(int a) { 114 | var z = getZ(); 115 | var b = calcB(z, 3); 116 | var s = this + " > a: " + a + " ; x: " + x + " ; y: " + y + " ; z: " + z + " ; b: " + b; 117 | print(s); 118 | var f = IF(1 > 2, 1, 2); 119 | print(f); 120 | return b; 121 | } 122 | 123 | } 124 | <<<< CODE_UNIT_END="/test" >>>> 125 | <<<< [SOURCES_END] >>>> 126 | ]]> 127 | 128 | -------------------------------------------------------------------------------- /test/tests_definitions/java11_basic_class_this_function.test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | a: "+ a +" ; b: "+ b +" ; c: "+ c ; 17 | print(s); 18 | } 19 | } 20 | 21 | ]]> 22 | 23 | 24 | [ 123 ] 25 | 26 | 27 | ["Foo{} > a: 123 ; b: 1230 ; c: 12300"] 28 | 29 | >>> 30 | <<<< NAMESPACE="" >>>> 31 | <<<< CODE_UNIT_START="/test" >>>> 32 | class Foo { 33 | 34 | int m10(int a) { 35 | return a * 10; 36 | } 37 | 38 | void test(int a) { 39 | var b = m10(a); 40 | var self = this; 41 | var c = self.m10(b); 42 | var s = '$this > a: $a ; b: $b ; c: $c'; 43 | print(s); 44 | } 45 | 46 | } 47 | <<<< CODE_UNIT_END="/test" >>>> 48 | <<<< [SOURCES_END] >>>> 49 | ]]> 50 | 51 | >>> 52 | <<<< NAMESPACE="" >>>> 53 | <<<< CODE_UNIT_START="/test" >>>> 54 | class Foo { 55 | 56 | int m10(int a) { 57 | return a * 10; 58 | } 59 | 60 | void test(int a) { 61 | var b = m10(a); 62 | var self = this; 63 | var c = self.m10(b); 64 | var s = this + " > a: " + a + " ; b: " + b + " ; c: " + c; 65 | print(s); 66 | } 67 | 68 | } 69 | <<<< CODE_UNIT_END="/test" >>>> 70 | <<<< [SOURCES_END] >>>> 71 | ]]> 72 | 73 | -------------------------------------------------------------------------------- /test/tests_definitions/java11_basic_for_loop.test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 20 | 21 | 22 | [ 23 | ["For loop:", 10, 20, 1] 24 | ] 25 | 26 | 27 | ["For loop:", 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20] 28 | 29 | 30 | [ 31 | ["For loop:", 10, 20, 2] 32 | ] 33 | 34 | 35 | ["For loop:", 10, 12, 14, 16, 18, 20] 36 | 37 | >>> 38 | <<<< NAMESPACE="" >>>> 39 | <<<< CODE_UNIT_START="/test" >>>> 40 | class Foo { 41 | 42 | static void main(List args) { 43 | var title = args[0]; 44 | var init = args[1]; 45 | var end = args[2]; 46 | var increment = args[3]; 47 | print(title); 48 | for (var i = init; i <= end ; i += increment) { 49 | print(i); 50 | } 51 | } 52 | 53 | } 54 | <<<< CODE_UNIT_END="/test" >>>> 55 | <<<< [SOURCES_END] >>>> 56 | ]]> 57 | >>> 58 | <<<< NAMESPACE="" >>>> 59 | <<<< CODE_UNIT_START="/test" >>>> 60 | class Foo { 61 | 62 | static void main(Object[] args) { 63 | var title = args[0]; 64 | var init = args[1]; 65 | var end = args[2]; 66 | var increment = args[3]; 67 | print(title); 68 | for (var i = init; i <= end ; i += increment) { 69 | print(i); 70 | } 71 | } 72 | 73 | } 74 | <<<< CODE_UNIT_END="/test" >>>> 75 | <<<< [SOURCES_END] >>>> 76 | ]]> 77 | 78 | -------------------------------------------------------------------------------- /test/tests_definitions/java11_basic_for_loop_decrement.test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | = end; i--) { 14 | print(i); 15 | } 16 | } 17 | } 18 | ]]> 19 | 20 | 21 | [ 22 | ["For loop:", 20, 10] 23 | ] 24 | 25 | 26 | ["For loop:", 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10] 27 | 28 | >>> 29 | <<<< NAMESPACE="" >>>> 30 | <<<< CODE_UNIT_START="/test" >>>> 31 | class Foo { 32 | 33 | static void main(List args) { 34 | var title = args[0]; 35 | var init = args[1]; 36 | var end = args[2]; 37 | print(title); 38 | for (var i = init; i >= end ; i--) { 39 | print(i); 40 | } 41 | } 42 | 43 | } 44 | <<<< CODE_UNIT_END="/test" >>>> 45 | <<<< [SOURCES_END] >>>> 46 | ]]> 47 | >>> 48 | <<<< NAMESPACE="" >>>> 49 | <<<< CODE_UNIT_START="/test" >>>> 50 | class Foo { 51 | 52 | static void main(Object[] args) { 53 | var title = args[0]; 54 | var init = args[1]; 55 | var end = args[2]; 56 | print(title); 57 | for (var i = init; i >= end ; i--) { 58 | print(i); 59 | } 60 | } 61 | 62 | } 63 | <<<< CODE_UNIT_END="/test" >>>> 64 | <<<< [SOURCES_END] >>>> 65 | ]]> 66 | 67 | -------------------------------------------------------------------------------- /test/tests_definitions/java11_basic_for_loop_increment.test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | 21 | [ 22 | ["For loop:", 10, 20] 23 | ] 24 | 25 | 26 | ["For loop:", 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20] 27 | 28 | >>> 29 | <<<< NAMESPACE="" >>>> 30 | <<<< CODE_UNIT_START="/test" >>>> 31 | class Foo { 32 | 33 | static void main(List args) { 34 | var title = args[0]; 35 | var init = args[1]; 36 | var end = args[2]; 37 | print(title); 38 | for (var i = init; i <= end ; i++) { 39 | print(i); 40 | } 41 | } 42 | 43 | } 44 | <<<< CODE_UNIT_END="/test" >>>> 45 | <<<< [SOURCES_END] >>>> 46 | ]]> 47 | >>> 48 | <<<< NAMESPACE="" >>>> 49 | <<<< CODE_UNIT_START="/test" >>>> 50 | class Foo { 51 | 52 | static void main(Object[] args) { 53 | var title = args[0]; 54 | var init = args[1]; 55 | var end = args[2]; 56 | print(title); 57 | for (var i = init; i <= end ; i++) { 58 | print(i); 59 | } 60 | } 61 | 62 | } 63 | <<<< CODE_UNIT_END="/test" >>>> 64 | <<<< [SOURCES_END] >>>> 65 | ]]> 66 | 67 | -------------------------------------------------------------------------------- /test/tests_definitions/java11_basic_for_loop_pre_decrement.test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | = end; --i) { 14 | print(i); 15 | } 16 | } 17 | } 18 | ]]> 19 | 20 | 21 | [ 22 | ["For loop:", 20, 10] 23 | ] 24 | 25 | 26 | ["For loop:", 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10] 27 | 28 | >>> 29 | <<<< NAMESPACE="" >>>> 30 | <<<< CODE_UNIT_START="/test" >>>> 31 | class Foo { 32 | 33 | static void main(List args) { 34 | var title = args[0]; 35 | var init = args[1]; 36 | var end = args[2]; 37 | print(title); 38 | for (var i = init; i >= end ; --i) { 39 | print(i); 40 | } 41 | } 42 | 43 | } 44 | <<<< CODE_UNIT_END="/test" >>>> 45 | <<<< [SOURCES_END] >>>> 46 | ]]> 47 | >>> 48 | <<<< NAMESPACE="" >>>> 49 | <<<< CODE_UNIT_START="/test" >>>> 50 | class Foo { 51 | 52 | static void main(Object[] args) { 53 | var title = args[0]; 54 | var init = args[1]; 55 | var end = args[2]; 56 | print(title); 57 | for (var i = init; i >= end ; --i) { 58 | print(i); 59 | } 60 | } 61 | 62 | } 63 | <<<< CODE_UNIT_END="/test" >>>> 64 | <<<< [SOURCES_END] >>>> 65 | ]]> 66 | 67 | -------------------------------------------------------------------------------- /test/tests_definitions/java11_basic_for_loop_pre_increment.test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | 21 | [ 22 | ["For loop:", 10, 20] 23 | ] 24 | 25 | 26 | ["For loop:", 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20] 27 | 28 | >>> 29 | <<<< NAMESPACE="" >>>> 30 | <<<< CODE_UNIT_START="/test" >>>> 31 | class Foo { 32 | 33 | static void main(List args) { 34 | var title = args[0]; 35 | var init = args[1]; 36 | var end = args[2]; 37 | print(title); 38 | for (var i = init; i <= end ; ++i) { 39 | print(i); 40 | } 41 | } 42 | 43 | } 44 | <<<< CODE_UNIT_END="/test" >>>> 45 | <<<< [SOURCES_END] >>>> 46 | ]]> 47 | >>> 48 | <<<< NAMESPACE="" >>>> 49 | <<<< CODE_UNIT_START="/test" >>>> 50 | class Foo { 51 | 52 | static void main(Object[] args) { 53 | var title = args[0]; 54 | var init = args[1]; 55 | var end = args[2]; 56 | print(title); 57 | for (var i = init; i <= end ; ++i) { 58 | print(i); 59 | } 60 | } 61 | 62 | } 63 | <<<< CODE_UNIT_END="/test" >>>> 64 | <<<< [SOURCES_END] >>>> 65 | ]]> 66 | 67 | -------------------------------------------------------------------------------- /test/tests_definitions/java11_basic_main_1.test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | sumAB; 15 | print(title); 16 | print(sumAB); 17 | print(sumABC); 18 | if (greater) { 19 | var eq = greater == true; 20 | print("sumABC > sumAB = "+ eq); 21 | } 22 | } 23 | } 24 | 25 | ]]> 26 | 27 | 28 | [ 29 | ["Sums:", 10, 20, 50] 30 | ] 31 | 32 | 33 | ["Sums:", 30, 80, "sumABC > sumAB = true"] 34 | 35 | >>> 36 | <<<< NAMESPACE="" >>>> 37 | <<<< CODE_UNIT_START="/test" >>>> 38 | class Foo { 39 | 40 | static void main(List args) { 41 | var title = args[0]; 42 | var a = args[1]; 43 | var b = args[2]; 44 | var c = args[3]; 45 | var sumAB = a + b; 46 | var sumABC = a + b + c; 47 | var greater = sumABC > sumAB; 48 | print(title); 49 | print(sumAB); 50 | print(sumABC); 51 | if (greater) { 52 | var eq = greater == true; 53 | print('sumABC > sumAB = $eq'); 54 | } 55 | 56 | } 57 | 58 | } 59 | <<<< CODE_UNIT_END="/test" >>>> 60 | <<<< [SOURCES_END] >>>> 61 | ]]> 62 | 63 | >>> 64 | <<<< NAMESPACE="" >>>> 65 | <<<< CODE_UNIT_START="/test" >>>> 66 | class Foo { 67 | 68 | static void main(Object[] args) { 69 | var title = args[0]; 70 | var a = args[1]; 71 | var b = args[2]; 72 | var c = args[3]; 73 | var sumAB = a + b; 74 | var sumABC = a + b + c; 75 | var greater = sumABC > sumAB; 76 | print(title); 77 | print(sumAB); 78 | print(sumABC); 79 | if (greater) { 80 | var eq = greater == true; 81 | print("sumABC > sumAB = " + eq); 82 | } 83 | 84 | } 85 | 86 | } 87 | <<<< CODE_UNIT_END="/test" >>>> 88 | <<<< [SOURCES_END] >>>> 89 | ]]> 90 | 91 | -------------------------------------------------------------------------------- /test/tests_definitions/java11_basic_main_2.test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 21 | 22 | 23 | [ 24 | ["Strings:", "A", "B", "C"] 25 | ] 26 | 27 | 28 | ["Strings:", "AB", "ABC"] 29 | 30 | >>> 31 | <<<< NAMESPACE="" >>>> 32 | <<<< CODE_UNIT_START="/test" >>>> 33 | class Foo { 34 | 35 | static void main(List args) { 36 | var title = args[0]; 37 | var a = args[1]; 38 | var b = args[2]; 39 | var c = args[3]; 40 | var sumAB = a + b; 41 | var sumABC = a + b + c; 42 | print(title); 43 | print(sumAB); 44 | print(sumABC); 45 | } 46 | 47 | } 48 | <<<< CODE_UNIT_END="/test" >>>> 49 | <<<< [SOURCES_END] >>>> 50 | ]]> 51 | 52 | >>> 53 | <<<< NAMESPACE="" >>>> 54 | <<<< CODE_UNIT_START="/test" >>>> 55 | class Foo { 56 | 57 | static void main(String[] args) { 58 | var title = args[0]; 59 | var a = args[1]; 60 | var b = args[2]; 61 | var c = args[3]; 62 | var sumAB = a + b; 63 | var sumABC = a + b + c; 64 | print(title); 65 | print(sumAB); 66 | print(sumABC); 67 | } 68 | 69 | } 70 | <<<< CODE_UNIT_END="/test" >>>> 71 | <<<< [SOURCES_END] >>>> 72 | ]]> 73 | 74 | -------------------------------------------------------------------------------- /test/tests_definitions/java11_basic_main_3_negation.test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | sumAB:"+sumAB +" = "+ eq); 21 | } else { 22 | var eq = lower == true; 23 | print("sumABC:"+sumABC+" < sumAB:"+sumAB +" = "+ eq); 24 | } 25 | } 26 | } 27 | 28 | ]]> 29 | 30 | 31 | [ 32 | ["Sums:", 10, 20, 50] 33 | ] 34 | 35 | 36 | ["Sums:", 30, 80, "[NOT] sumABC:80 > sumAB:30 = true"] 37 | 38 | 39 | [ 40 | ["Sums:", 10, 20, -50] 41 | ] 42 | 43 | 44 | ["Sums:", 30, -20, "sumABC:-20 < sumAB:30 = true"] 45 | 46 | >>> 47 | <<<< NAMESPACE="" >>>> 48 | <<<< CODE_UNIT_START="/test" >>>> 49 | class Foo { 50 | 51 | static void main(List args) { 52 | var title = args[0]; 53 | var a = args[1]; 54 | var b = args[2]; 55 | var c = args[3]; 56 | var sumAB = a + b; 57 | var sumABC = a + b + c; 58 | var lower = sumABC < sumAB; 59 | print(title); 60 | print(sumAB); 61 | print(sumABC); 62 | if (!lower) { 63 | var eq = lower == false; 64 | print('[NOT] sumABC:$sumABC > sumAB:$sumAB = $eq'); 65 | } else { 66 | var eq = lower == true; 67 | print('sumABC:$sumABC < sumAB:$sumAB = $eq'); 68 | } 69 | 70 | } 71 | 72 | } 73 | <<<< CODE_UNIT_END="/test" >>>> 74 | <<<< [SOURCES_END] >>>> 75 | ]]> 76 | 77 | >>> 78 | <<<< NAMESPACE="" >>>> 79 | <<<< CODE_UNIT_START="/test" >>>> 80 | class Foo { 81 | 82 | static void main(Object[] args) { 83 | var title = args[0]; 84 | var a = args[1]; 85 | var b = args[2]; 86 | var c = args[3]; 87 | var sumAB = a + b; 88 | var sumABC = a + b + c; 89 | var lower = sumABC < sumAB; 90 | print(title); 91 | print(sumAB); 92 | print(sumABC); 93 | if (!lower) { 94 | var eq = lower == false; 95 | print("[NOT] sumABC:" + sumABC + " > sumAB:" + sumAB + " = " + eq); 96 | } else { 97 | var eq = lower == true; 98 | print("sumABC:" + sumABC + " < sumAB:" + sumAB + " = " + eq); 99 | } 100 | 101 | } 102 | 103 | } 104 | <<<< CODE_UNIT_END="/test" >>>> 105 | <<<< [SOURCES_END] >>>> 106 | ]]> 107 | 108 | -------------------------------------------------------------------------------- /test/tests_definitions/java11_basic_main_with_division.test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 120) { 14 | c = 120 ; 15 | } 16 | 17 | var str = "function's \"variables\"> a: "+ a +" ; b: "+ b +" ; c: "+ c ; 18 | var sumAB = a + b ; 19 | var sumABC = a + b + c; 20 | 21 | print(str); 22 | print(title); 23 | print(sumAB); 24 | print(sumABC); 25 | } 26 | } 27 | 28 | ]]> 29 | 30 | 31 | [ 32 | ["Sums:", 10, 30, 50] 33 | ] 34 | 35 | 36 | 37 | [ 38 | "function's \"variables\"> a: 10 ; b: 15 ; c: 120", 39 | "Sums:", 40 | 25, 41 | 145 42 | ] 43 | 44 | 45 | [ 46 | "function's \"variables\"> a: 10 ; b: 15.0 ; c: 120", 47 | "Sums:", 48 | 25.0, 49 | 145.0 50 | ] 51 | 52 | 53 | >>> 54 | <<<< NAMESPACE="" >>>> 55 | <<<< CODE_UNIT_START="/test" >>>> 56 | class Foo { 57 | 58 | static void main(List args) { 59 | var title = args[0]; 60 | var a = args[1]; 61 | var b = args[2] / 2; 62 | var c = args[3] * 3; 63 | if (c > 120) { 64 | c = 120; 65 | } 66 | 67 | var str = "function's \"variables\"> a: " + '$a ; b: $b ; c: $c'; 68 | var sumAB = a + b; 69 | var sumABC = a + b + c; 70 | print(str); 71 | print(title); 72 | print(sumAB); 73 | print(sumABC); 74 | } 75 | 76 | } 77 | <<<< CODE_UNIT_END="/test" >>>> 78 | <<<< [SOURCES_END] >>>> 79 | ]]> 80 | 81 | >>> 82 | <<<< NAMESPACE="" >>>> 83 | <<<< CODE_UNIT_START="/test" >>>> 84 | class Foo { 85 | 86 | static void main(Object[] args) { 87 | var title = args[0]; 88 | var a = args[1]; 89 | var b = args[2] / 2; 90 | var c = args[3] * 3; 91 | if (c > 120) { 92 | c = 120; 93 | } 94 | 95 | var str = "function's \"variables\"> a: " + a + " ; b: " + b + " ; c: " + c; 96 | var sumAB = a + b; 97 | var sumABC = a + b + c; 98 | print(str); 99 | print(title); 100 | print(sumAB); 101 | print(sumABC); 102 | } 103 | 104 | } 105 | <<<< CODE_UNIT_END="/test" >>>> 106 | <<<< [SOURCES_END] >>>> 107 | ]]> 108 | 109 | -------------------------------------------------------------------------------- /test/tests_definitions/java11_basic_main_with_inline_string.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 23 | 24 | 25 | [ 26 | ["Operations:", 10, 20] 27 | ] 28 | 29 | 30 | ["Operations:", 30, "1020inline \t\t string"] 31 | 32 | >>> 33 | <<<< NAMESPACE="" >>>> 34 | <<<< CODE_UNIT_START="/test" >>>> 35 | class Foo { 36 | 37 | static void main(List args) { 38 | var title = args[0]; 39 | var a = args[1]; 40 | var b = args[2]; 41 | var s1 = 'inline'; 42 | var s2 = 'string'; 43 | var c = '$s1 \t\t $s2'; 44 | var sumAB = a + b; 45 | var sumABC = a + b + c; 46 | print(title); 47 | print(sumAB); 48 | print(sumABC); 49 | } 50 | 51 | } 52 | <<<< CODE_UNIT_END="/test" >>>> 53 | <<<< [SOURCES_END] >>>> 54 | ]]> 55 | 56 | >>> 57 | <<<< NAMESPACE="" >>>> 58 | <<<< CODE_UNIT_START="/test" >>>> 59 | class Foo { 60 | 61 | static void main(Object[] args) { 62 | var title = args[0]; 63 | var a = args[1]; 64 | var b = args[2]; 65 | var s1 = "inline"; 66 | var s2 = "string"; 67 | var c = s1 + " \t\t " + s2; 68 | var sumAB = a + b; 69 | var sumABC = a + b + c; 70 | print(title); 71 | print(sumAB); 72 | print(sumABC); 73 | } 74 | 75 | } 76 | <<<< CODE_UNIT_END="/test" >>>> 77 | <<<< [SOURCES_END] >>>> 78 | ]]> 79 | 80 | -------------------------------------------------------------------------------- /test/tests_definitions/java11_basic_var_decrement.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 33 | 34 | 35 | [ [10, 20] ] 36 | 37 | 38 | ["a: 10", "b: 20", "a2: 9", "b2: 19", "a3: 9", "b3: 19", "a: 8", "b: 18"] 39 | 40 | >>> 41 | <<<< NAMESPACE="" >>>> 42 | <<<< CODE_UNIT_START="/test" >>>> 43 | class Foo { 44 | 45 | void main(List args) { 46 | var a = args[0]; 47 | var b = args[1]; 48 | print('a: $a'); 49 | print('b: $b'); 50 | var a2 = --a; 51 | var b2 = --b; 52 | print('a2: $a2'); 53 | print('b2: $b2'); 54 | var a3 = a--; 55 | var b3 = b--; 56 | print('a3: $a3'); 57 | print('b3: $b3'); 58 | print('a: $a'); 59 | print('b: $b'); 60 | } 61 | 62 | } 63 | <<<< CODE_UNIT_END="/test" >>>> 64 | <<<< [SOURCES_END] >>>> 65 | ]]> 66 | 67 | >>> 68 | <<<< NAMESPACE="" >>>> 69 | <<<< CODE_UNIT_START="/test" >>>> 70 | class Foo { 71 | 72 | void main(int[] args) { 73 | var a = args[0]; 74 | var b = args[1]; 75 | print("a: " + a); 76 | print("b: " + b); 77 | var a2 = --a; 78 | var b2 = --b; 79 | print("a2: " + a2); 80 | print("b2: " + b2); 81 | var a3 = a--; 82 | var b3 = b--; 83 | print("a3: " + a3); 84 | print("b3: " + b3); 85 | print("a: " + a); 86 | print("b: " + b); 87 | } 88 | 89 | } 90 | <<<< CODE_UNIT_END="/test" >>>> 91 | <<<< [SOURCES_END] >>>> 92 | ]]> 93 | 94 | -------------------------------------------------------------------------------- /test/tests_definitions/java11_basic_var_increment.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 33 | 34 | 35 | [ [10, 20] ] 36 | 37 | 38 | ["a: 10", "b: 20", "a2: 11", "b2: 21", "a3: 11", "b3: 21", "a: 12", "b: 22"] 39 | 40 | >>> 41 | <<<< NAMESPACE="" >>>> 42 | <<<< CODE_UNIT_START="/test" >>>> 43 | class Foo { 44 | 45 | void main(List args) { 46 | var a = args[0]; 47 | var b = args[1]; 48 | print('a: $a'); 49 | print('b: $b'); 50 | var a2 = ++a; 51 | var b2 = ++b; 52 | print('a2: $a2'); 53 | print('b2: $b2'); 54 | var a3 = a++; 55 | var b3 = b++; 56 | print('a3: $a3'); 57 | print('b3: $b3'); 58 | print('a: $a'); 59 | print('b: $b'); 60 | } 61 | 62 | } 63 | <<<< CODE_UNIT_END="/test" >>>> 64 | <<<< [SOURCES_END] >>>> 65 | ]]> 66 | 67 | >>> 68 | <<<< NAMESPACE="" >>>> 69 | <<<< CODE_UNIT_START="/test" >>>> 70 | class Foo { 71 | 72 | void main(int[] args) { 73 | var a = args[0]; 74 | var b = args[1]; 75 | print("a: " + a); 76 | print("b: " + b); 77 | var a2 = ++a; 78 | var b2 = ++b; 79 | print("a2: " + a2); 80 | print("b2: " + b2); 81 | var a3 = a++; 82 | var b3 = b++; 83 | print("a3: " + a3); 84 | print("b3: " + b3); 85 | print("a: " + a); 86 | print("b: " + b); 87 | } 88 | 89 | } 90 | <<<< CODE_UNIT_END="/test" >>>> 91 | <<<< [SOURCES_END] >>>> 92 | ]]> 93 | 94 | -------------------------------------------------------------------------------- /test/tests_definitions/java11_basic_vars.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 19 | 20 | [ ] 21 | 22 | 23 | [579, "c: 579"] 24 | 25 | >>> 26 | <<<< NAMESPACE="" >>>> 27 | <<<< CODE_UNIT_START="/test" >>>> 28 | class Foo { 29 | 30 | void main(List args) { 31 | var a = 123; 32 | var b = 456; 33 | var c = a + b; 34 | print(c); 35 | print('c: $c'); 36 | } 37 | 38 | } 39 | <<<< CODE_UNIT_END="/test" >>>> 40 | <<<< [SOURCES_END] >>>> 41 | ]]> 42 | 43 | >>> 44 | <<<< NAMESPACE="" >>>> 45 | <<<< CODE_UNIT_START="/test" >>>> 46 | class Foo { 47 | 48 | void main(Object[] args) { 49 | var a = 123; 50 | var b = 456; 51 | var c = a + b; 52 | print(c); 53 | print("c: " + c); 54 | } 55 | 56 | } 57 | <<<< CODE_UNIT_END="/test" >>>> 58 | <<<< [SOURCES_END] >>>> 59 | ]]> 60 | 61 | -------------------------------------------------------------------------------- /test/tests_definitions/java11_basic_with_branches.test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | b) { 27 | print("else: a>b"); 28 | } 29 | else { 30 | print("else: a==b"); 31 | } 32 | 33 | } 34 | } 35 | 36 | ]]> 37 | 38 | 39 | [ 40 | [10, 20] 41 | ] 42 | 43 | 44 | ["if: a!=b", "if: a<b"] 45 | 46 | 47 | 48 | [ 49 | [20, 20] 50 | ] 51 | 52 | 53 | ["if: a==b", "else: a!=b", "else: a==b"] 54 | 55 | 56 | >>> 57 | <<<< NAMESPACE="" >>>> 58 | <<<< CODE_UNIT_START="/test" >>>> 59 | class Bar { 60 | 61 | static void main(List args) { 62 | var a = args[0]; 63 | var b = args[1]; 64 | var eq = a == b; 65 | if (a == b) { 66 | print('if: a==b'); 67 | } 68 | 69 | if (a != b) { 70 | print('if: a!=b'); 71 | } else { 72 | print('else: a!=b'); 73 | } 74 | 75 | if (a < b) { 76 | print('if: a b) { 78 | print('else: a>b'); 79 | } else { 80 | print('else: a==b'); 81 | } 82 | 83 | } 84 | 85 | } 86 | <<<< CODE_UNIT_END="/test" >>>> 87 | <<<< [SOURCES_END] >>>> 88 | ]]> 89 | 90 | >>> 91 | <<<< NAMESPACE="" >>>> 92 | <<<< CODE_UNIT_START="/test" >>>> 93 | class Bar { 94 | 95 | static void main(Object[] args) { 96 | var a = args[0]; 97 | var b = args[1]; 98 | var eq = a == b; 99 | if (a == b) { 100 | print("if: a==b"); 101 | } 102 | 103 | if (a != b) { 104 | print("if: a!=b"); 105 | } else { 106 | print("else: a!=b"); 107 | } 108 | 109 | if (a < b) { 110 | print("if: a b) { 112 | print("else: a>b"); 113 | } else { 114 | print("else: a==b"); 115 | } 116 | 117 | } 118 | 119 | } 120 | <<<< CODE_UNIT_END="/test" >>>> 121 | <<<< [SOURCES_END] >>>> 122 | ]]> 123 | 124 | -------------------------------------------------------------------------------- /test/tests_definitions/java11_basic_with_string_variable.test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ;\t$b->a*2: " + b + " ;\ta*3: " + String.valueOf( a * 3 ) + "!"; 12 | print(sv1); 13 | var sv2 = String.valueOf( a ) + a; 14 | print(sv2); 15 | } 16 | 17 | } 18 | 19 | ]]> 20 | 21 | 22 | [ ] 23 | 24 | 25 | ["a: <123>;\t$b->a*2: 246 ;\ta*3: 369!", "123123"] 26 | 27 | >>> 28 | <<<< NAMESPACE="" >>>> 29 | <<<< CODE_UNIT_START="/test" >>>> 30 | class Foo { 31 | 32 | static void main(List args) { 33 | var a = 123; 34 | var b = 123 * 2; 35 | var sv1 = 'a: <' + a + '>;\t\$b->a*2: ' + b + ' ;\ta*3: ' + String.valueOf(a * 3) + '!'; 36 | print(sv1); 37 | var sv2 = String.valueOf(a) + a; 38 | print(sv2); 39 | } 40 | 41 | } 42 | <<<< CODE_UNIT_END="/test" >>>> 43 | <<<< [SOURCES_END] >>>> 44 | ]]> 45 | 46 | >>> 47 | <<<< NAMESPACE="" >>>> 48 | <<<< CODE_UNIT_START="/test" >>>> 49 | class Foo { 50 | 51 | static void main(String[] args) { 52 | var a = 123; 53 | var b = 123 * 2; 54 | var sv1 = "a: <" + a + ">;\t$b->a*2: " + b + " ;\ta*3: " + String.valueOf(a * 3) + "!"; 55 | print(sv1); 56 | var sv2 = String.valueOf(a) + a; 57 | print(sv2); 58 | } 59 | 60 | } 61 | <<<< CODE_UNIT_END="/test" >>>> 62 | <<<< [SOURCES_END] >>>> 63 | ]]> 64 | 65 | --------------------------------------------------------------------------------