├── .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 |
--------------------------------------------------------------------------------