├── .github └── workflows │ └── ci.yaml ├── .gitignore ├── .idea ├── codeStyles │ ├── Project.xml │ └── codeStyleConfig.xml ├── encodings.xml ├── google-java-format.xml ├── lexer.iml ├── modules.xml ├── vcs.xml └── workspace.xml ├── .travis.yml ├── .vscode ├── launch.json ├── settings.json └── tasks.json ├── Cargo.lock ├── Cargo.toml ├── LICENSE ├── README.md ├── assets ├── bar.png ├── errors.png └── program.png ├── codegen ├── Cargo.toml └── src │ ├── db.rs │ ├── hir.rs │ └── lib.rs ├── errors ├── Cargo.toml └── src │ ├── db.rs │ ├── files.rs │ ├── lib.rs │ ├── pos.rs │ └── reporter.rs ├── ir ├── Cargo.toml └── src │ ├── block.rs │ ├── builder.rs │ ├── db.rs │ ├── frame.rs │ ├── frame │ └── x86_64.rs │ ├── ir.rs │ ├── lib.rs │ └── printer.rs ├── notes └── infer.md ├── opcode ├── Cargo.toml └── src │ └── lib.rs ├── parser ├── Cargo.toml ├── grammar.md └── src │ ├── db.rs │ ├── lexer.rs │ ├── lib.rs │ ├── macros.rs │ ├── parse.rs │ ├── parser.rs │ ├── parser │ ├── classes.rs │ ├── enums.rs │ ├── expressions.rs │ ├── expressions │ │ ├── binary.rs │ │ ├── block.rs │ │ ├── break_expr.rs │ │ ├── call_expr.rs │ │ ├── closure_expr.rs │ │ ├── continue_expr.rs │ │ ├── do_expr.rs │ │ ├── field_expr.rs │ │ ├── for_expr.rs │ │ ├── grouping.rs │ │ ├── ident.rs │ │ ├── if_expr.rs │ │ ├── index_expr.rs │ │ ├── let_expr.rs │ │ ├── literal.rs │ │ ├── match_expr.rs │ │ ├── record_expr.rs │ │ ├── return_expr.rs │ │ ├── snapshots │ │ │ ├── parser__parser__expressions__binary__tests__parse_assign_bin_expr_.snap │ │ │ ├── parser__parser__expressions__binary__tests__parse_bin_expr.snap │ │ │ ├── parser__parser__expressions__binary__tests__parse_chained_assign_bin_expr_.snap │ │ │ ├── parser__parser__expressions__binary__tests__parse_wrapped_bin_expr_literal.snap │ │ │ ├── parser__parser__expressions__block__tests__parse_block_with_statements.snap │ │ │ ├── parser__parser__expressions__block__tests__parse_free_block.snap │ │ │ ├── parser__parser__expressions__block__tests__parse_nested_block.snap │ │ │ ├── parser__parser__expressions__break_expr__tests__parse_break_expr.snap │ │ │ ├── parser__parser__expressions__call_expr__tests__parse_call_generic_params_expr.snap │ │ │ ├── parser__parser__expressions__call_expr__tests__parse_call_ife.snap │ │ │ ├── parser__parser__expressions__call_expr__tests__parse_call_ife_with_args.snap │ │ │ ├── parser__parser__expressions__call_expr__tests__parse_call_no_args_expr.snap │ │ │ ├── parser__parser__expressions__call_expr__tests__parse_call_trailing_comma.snap │ │ │ ├── parser__parser__expressions__call_expr__tests__parse_simple_call_expr.snap │ │ │ ├── parser__parser__expressions__closure_expr__tests__parse_closure_with_types.snap │ │ │ ├── parser__parser__expressions__closure_expr__tests__parse_empty_closure_expr.snap │ │ │ ├── parser__parser__expressions__closure_expr__tests__parse_free_closure_expr.snap │ │ │ ├── parser__parser__expressions__closure_expr__tests__parse_simple_closure_expr.snap │ │ │ ├── parser__parser__expressions__continue_expr__tests__parse_continue_expr.snap │ │ │ ├── parser__parser__expressions__do_expr__tests__parse_do_expr.snap │ │ │ ├── parser__parser__expressions__field_expr__tests__parse_field_access.snap │ │ │ ├── parser__parser__expressions__field_expr__tests__parse_field_access_assign.snap │ │ │ ├── parser__parser__expressions__field_expr__tests__parse_field_access_chain.snap │ │ │ ├── parser__parser__expressions__field_expr__tests__parse_field_access_method.snap │ │ │ ├── parser__parser__expressions__field_expr__tests__parse_field_access_method_chain.snap │ │ │ ├── parser__parser__expressions__for_expr__tests__parse_empty_for_expr.snap │ │ │ ├── parser__parser__expressions__for_expr__tests__parse_for_expr.snap │ │ │ ├── parser__parser__expressions__for_expr__tests__parse_for_no_cond.snap │ │ │ ├── parser__parser__expressions__for_expr__tests__parse_for_no_incr.snap │ │ │ ├── parser__parser__expressions__for_expr__tests__parse_for_no_init.snap │ │ │ ├── parser__parser__expressions__grouping__tests__parse_grouping_expr.snap │ │ │ ├── parser__parser__expressions__grouping__tests__parse_tuple_expr.snap │ │ │ ├── parser__parser__expressions__ident__tests__parse_generic_ident_expr.snap │ │ │ ├── parser__parser__expressions__ident__tests__parse_ident_expr.snap │ │ │ ├── parser__parser__expressions__if_expr__tests__parse_chained_if.snap │ │ │ ├── parser__parser__expressions__if_expr__tests__parse_chained_if_and_else.snap │ │ │ ├── parser__parser__expressions__if_expr__tests__parse_empty_if.snap │ │ │ ├── parser__parser__expressions__if_expr__tests__parse_if_and_else.snap │ │ │ ├── parser__parser__expressions__index_expr__tests__parse_nested_index_expr.snap │ │ │ ├── parser__parser__expressions__index_expr__tests__parse_simple_index_expr.snap │ │ │ ├── parser__parser__expressions__let_expr__tests__parse_empty_let_expr.snap │ │ │ ├── parser__parser__expressions__let_expr__tests__parse_let_expr.snap │ │ │ ├── parser__parser__expressions__let_expr__tests__parse_let_patter_expr.snap │ │ │ ├── parser__parser__expressions__let_expr__tests__parse_let_type_expr.snap │ │ │ ├── parser__parser__expressions__literal__tests__parse_bool_literal.snap │ │ │ ├── parser__parser__expressions__literal__tests__parse_float_literal.snap │ │ │ ├── parser__parser__expressions__literal__tests__parse_int_literal.snap │ │ │ ├── parser__parser__expressions__literal__tests__parse_nil_literal.snap │ │ │ ├── parser__parser__expressions__literal__tests__parse_string_literal.snap │ │ │ ├── parser__parser__expressions__match_expr__tests__parse_empty_match_expr.snap │ │ │ ├── parser__parser__expressions__match_expr__tests__parse_match_expr.snap │ │ │ ├── parser__parser__expressions__record_expr__tests__parse_empty_record_literal.snap │ │ │ ├── parser__parser__expressions__record_expr__tests__parse_longhand_record_literal.snap │ │ │ ├── parser__parser__expressions__record_expr__tests__parse_mixed_record_literal.snap │ │ │ ├── parser__parser__expressions__record_expr__tests__parse_shorthand_record_literal.snap │ │ │ ├── parser__parser__expressions__return_expr__tests__parse_empty_return_expr.snap │ │ │ ├── parser__parser__expressions__return_expr__tests__parse_return_expr.snap │ │ │ ├── parser__parser__expressions__unary__tests__parse_nested_unary_expr.snap │ │ │ ├── parser__parser__expressions__unary__tests__parse_unary_expr.snap │ │ │ ├── parser__parser__expressions__while_expr__tests__parse_empty_while_expr.snap │ │ │ └── parser__parser__expressions__while_expr__tests__parse_while_expr.snap │ │ ├── unary.rs │ │ └── while_expr.rs │ ├── function.rs │ ├── imports.rs │ ├── module.rs │ ├── params.rs │ ├── pattern.rs │ ├── pratt.rs │ ├── restrictions.rs │ ├── snapshots │ │ ├── parser__parser__classes__tests__parse_class_fields.snap │ │ ├── parser__parser__classes__tests__parse_class_fields_methods.snap │ │ ├── parser__parser__classes__tests__parse_class_generic.snap │ │ ├── parser__parser__classes__tests__parse_class_methods.snap │ │ ├── parser__parser__classes__tests__parse_empty_class.snap │ │ ├── parser__parser__classes__tests__parse_exported_class.snap │ │ ├── parser__parser__enums__tests__parse_empty_enum.snap │ │ ├── parser__parser__enums__tests__parse_enum_generic.snap │ │ ├── parser__parser__enums__tests__parse_enum_variants_trailing_comma.snap │ │ ├── parser__parser__enums__tests__parse_enum_variants_types.snap │ │ ├── parser__parser__enums__tests__parse_enum_with_variants.snap │ │ ├── parser__parser__enums__tests__parse_exported_enum.snap │ │ ├── parser__parser__function__tests__parse_exported_function.snap │ │ ├── parser__parser__function__tests__parse_function.snap │ │ ├── parser__parser__imports__tests__parse_empty_import.snap │ │ ├── parser__parser__imports__tests__parse_import_with_brace.snap │ │ ├── parser__parser__imports__tests__parse_import_with_brace_nested_segments.snap │ │ ├── parser__parser__imports__tests__parse_import_with_multiple_segments.snap │ │ ├── parser__parser__module__tests__parse_many_mods.snap │ │ ├── parser__parser__module__tests__parse_single_mod.snap │ │ ├── parser__parser__pattern__tests__parse_binding_pattern.snap │ │ ├── parser__parser__pattern__tests__parse_nested_tuple_pattern.snap │ │ ├── parser__parser__pattern__tests__parse_placeholder_pattern.snap │ │ ├── parser__parser__pattern__tests__parse_tuple_pattern.snap │ │ ├── parser__parser__type_alias__tests__parse_exported_type_alias.snap │ │ ├── parser__parser__type_alias__tests__parse_type_alias.snap │ │ ├── parser__parser__type_alias__tests__parse_type_alias_params.snap │ │ ├── parser__parser__types__tests__parse_array_tuple_type.snap │ │ ├── parser__parser__types__tests__parse_array_type.snap │ │ ├── parser__parser__types__tests__parse_fn_tuple_type.snap │ │ ├── parser__parser__types__tests__parse_fn_type.snap │ │ ├── parser__parser__types__tests__parse_ident_type.snap │ │ ├── parser__parser__types__tests__parse_tuple_type.snap │ │ ├── parser__parser__visibility__tests__parse_pub_alias.snap │ │ ├── parser__parser__visibility__tests__parse_pub_class.snap │ │ ├── parser__parser__visibility__tests__parse_pub_enum.snap │ │ └── parser__parser__visibility__tests__parse_pub_function.snap │ ├── source_file.rs │ ├── type_alias.rs │ ├── type_args.rs │ ├── type_params.rs │ ├── types.rs │ └── visibility.rs │ ├── snapshots │ ├── parser__lexer__tests__it_works.snap │ ├── parser__lexer__tests__lex_block_comments.snap │ ├── parser__lexer__tests__lex_floats.snap │ ├── parser__lexer__tests__lex_int.snap │ ├── parser__lexer__tests__lex_line_comment.snap │ └── parser__lexer__tests__lex_nested_block_comments.snap │ └── utils.rs ├── semant ├── Cargo.toml └── src │ ├── db.rs │ ├── hir.rs │ ├── infer.rs │ ├── infer │ ├── binary.rs │ ├── block.rs │ ├── call.rs │ ├── ctx.rs │ ├── enum_expr.rs │ ├── field.rs │ ├── infer.rs │ ├── pattern_matrix.rs │ ├── pattern_matrix │ │ ├── matrix.rs │ │ └── pattern.rs │ ├── record.rs │ ├── stacked_map.rs │ ├── subst.rs │ ├── tests │ │ ├── tuple_field.ron │ │ ├── tuple_high_index.ron │ │ └── tuple_non_int.ron │ ├── ty.rs │ └── unify.rs │ ├── lib.rs │ ├── lower.rs │ ├── lower │ ├── alias.rs │ ├── class.rs │ ├── enums.rs │ ├── function.rs │ ├── imports.rs │ └── module.rs │ ├── resolver.rs │ ├── resolver │ ├── alias.rs │ ├── class.rs │ ├── data.rs │ ├── enums.rs │ ├── escape.rs │ ├── function.rs │ ├── function │ │ └── expression.rs │ ├── imports.rs │ ├── module.rs │ ├── module_graph.rs │ ├── source_file.rs │ └── tests │ │ ├── basic_class.ron │ │ ├── basic_enum.ron │ │ ├── enum_dup_variant.ron │ │ ├── exported_class.ron │ │ ├── flat_structure.ron │ │ ├── import_alias.ron │ │ ├── import_deep.ron │ │ ├── import_deep_dirs.ron │ │ ├── import_dir_and_file.ron │ │ ├── import_fn_as_type.ron │ │ ├── import_many.ron │ │ ├── import_no_exported.ron │ │ ├── import_single.ron │ │ ├── mod.rs │ │ ├── recursive_enum.ron │ │ └── with_dir.ron │ ├── typed.rs │ └── util.rs ├── syntax ├── Cargo.toml └── src │ ├── ast.rs │ ├── ast.rs.tera │ ├── ast_ext.rs │ ├── grammer.ron │ ├── lexer.rs │ ├── lib.rs │ ├── macros.rs │ ├── token.rs │ └── traits.rs ├── tests ├── fail │ ├── assign │ │ ├── assign.tox │ │ ├── bool.tox │ │ ├── grouping.tox │ │ ├── infix_operator.tox │ │ ├── prefix_operator.tox │ │ ├── to_this.tox │ │ └── undefined.tox │ ├── call │ │ ├── nil.tox │ │ ├── num.tox │ │ ├── object.tox │ │ └── string.tox │ ├── cast │ │ ├── boolean2float.tox │ │ └── boolean2str.tox │ ├── constructor │ ├── enum │ │ ├── mising_inner.tox │ │ └── unify.tox │ └── print │ │ └── missing_argument.tox ├── pass │ ├── assign │ │ ├── associativity.tox │ │ ├── global.tox │ │ ├── local.tox │ │ ├── local_reference_self.tox │ │ ├── reassignment.tox │ │ ├── scope.tox │ │ └── syntax.tox │ ├── benchmark │ │ ├── binary_trees.tox │ │ ├── equality.tox │ │ ├── fib.tox │ │ ├── invocation.tox │ │ ├── method_call.tox │ │ ├── properties.tox │ │ └── string_equality.tox │ ├── boolean │ │ ├── empty.tox │ │ ├── equality.tox │ │ └── not.tox │ ├── cast │ │ ├── boolean.tox │ │ ├── float2int.tox │ │ ├── float2str.tox │ │ └── int2str.tox │ ├── class │ │ ├── empty.tox │ │ └── inherited_method.tox │ ├── comments │ │ ├── line_at_eof.tox │ │ ├── only_line_comment.tox │ │ ├── only_line_comment_and_line.tox │ │ └── unicode.tox │ ├── constructor │ ├── enums │ │ ├── basic.tox │ │ ├── basic_item_name.tox │ │ ├── data.tox │ │ ├── match.tox │ │ └── usage.tox │ ├── expressions │ │ └── evaluate.tox │ ├── float │ │ └── literals.tox │ └── match │ │ ├── assign_match.tox │ │ ├── assign_match_all.tox │ │ └── empty_match.tox ├── test.tox └── test_runner.rs ├── tools ├── Cargo.toml └── src │ ├── cli.rs │ └── main.rs ├── tox-wasm ├── Cargo.toml └── src │ └── lib.rs └── tox ├── .DS_Store ├── Cargo.toml └── src ├── bar └── bar.tox ├── cli.rs ├── db.rs ├── foo.tox ├── main.rs ├── test.tox └── test.tox.asm /.github/workflows/ci.yaml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: 3 | pull_request: 4 | push: 5 | branches: 6 | - master 7 | 8 | jobs: 9 | rust: 10 | name: Rust 11 | runs-on: ${{ matrix.os }} 12 | strategy: 13 | fail-fast: false 14 | matrix: 15 | os: [ubuntu-latest, macos-latest] 16 | env: 17 | RUSTFLAGS: -D warnings 18 | CARGO_INCREMENTAL: 0 19 | RUSTUP_MAX_RETRIES: 10 20 | CARGO_NET_RETRY: 10 21 | steps: 22 | - name: Checkout repository 23 | uses: actions/checkout@v1 24 | 25 | - name: Install Rust toolchain 26 | uses: actions-rs/toolchain@v1 27 | with: 28 | toolchain: stable 29 | profile: minimal 30 | override: true 31 | components: rustfmt, rust-src, clippy 32 | 33 | - name: Cache cargo registry 34 | uses: actions/cache@v1 35 | with: 36 | path: ~/.cargo/registry 37 | key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }} 38 | 39 | - name: Cache cargo index 40 | uses: actions/cache@v1 41 | with: 42 | path: ~/.cargo/git 43 | key: ${{ runner.os }}-cargo-index-${{ hashFiles('**/Cargo.lock') }} 44 | 45 | - name: Cache cargo target dir 46 | uses: actions/cache@v1 47 | with: 48 | path: target 49 | key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('**/Cargo.lock') }} 50 | 51 | - name: Compile 52 | uses: actions-rs/cargo@v1 53 | with: 54 | command: build 55 | 56 | - name: Format 57 | uses: actions-rs/cargo@v1 58 | with: 59 | command: fmt 60 | args: -- --check 61 | 62 | # - name: Clippy 63 | # uses: actions-rs/clippy-check@v1 64 | # with: 65 | # token: ${{ secrets.GITHUB_TOKEN }} 66 | # args: --all-features 67 | 68 | - name: Test 69 | uses: actions-rs/cargo@v1 70 | with: 71 | command: test 72 | args: --all 73 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | /target/ 3 | **/*.rs.bk 4 | 5 | */target/ 6 | tox/out.ll 7 | .DS_Store 8 | */.DS_Store 9 | /target 10 | **/*.rs.bk 11 | .DS_STORE 12 | node_modules -------------------------------------------------------------------------------- /.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /.idea/codeStyles/codeStyleConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.idea/google-java-format.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: rust 2 | dist: trusty 3 | rust: 4 | - stable 5 | - beta 6 | - nightly 7 | matrix: 8 | allow_failures: 9 | - rust: 10 | - stable 11 | - beta 12 | - nightly 13 | 14 | addons: 15 | apt: 16 | packages: 17 | - libssl-dev 18 | cache: cargo 19 | before_script: ((cargo install cargo-travis && cargo install rustfmt-nightly) || true) 20 | script: 21 | - cargo clean 22 | - cargo build 23 | - cargo test --features=all -- --nocapture 24 | - cd vm && cargo test --features "debug" 25 | after_success: | 26 | if [[ "$TRAVIS_RUST_VERSION" == stable ]]; then 27 | bash <(curl https://raw.githubusercontent.com/xd009642/tarpaulin/master/travis-install.sh) 28 | cargo tarpaulin --ciserver travis-ci --coveralls $TRAVIS_JOB_ID 29 | fi 30 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "type": "lldb", 9 | "request": "launch", 10 | "name": "Debug", 11 | "program": "${workspaceFolder}/target/debug/tox", 12 | "args": ["/Users/lenardpratt/Projects/Rust/tox-rewrite/tox/src/test.tox"], 13 | "cwd": "${workspaceFolder}" 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "workbench.colorCustomizations": {} 3 | } 4 | -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | // See https://go.microsoft.com/fwlink/?LinkId=733558 3 | // for the documentation about the tasks.json format 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "type": "shell", 8 | "taskName": "cargo build", 9 | "command": "cargo", 10 | "args": ["build"], 11 | "problemMatcher": ["$rustc"] 12 | } 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | members=[ 3 | "errors", 4 | "parser", 5 | "syntax", 6 | "codegen", 7 | "semant", 8 | "ir", 9 | "tools", 10 | "tox-wasm", 11 | "tox", 12 | ] 13 | default-members=["tox"] 14 | [profile.dev] 15 | opt-level = 0 16 | overflow-checks = true 17 | debug-assertions = true 18 | # panic = "abort" 19 | # debug = false 20 | codegen-units = 8 21 | lto = false 22 | incremental = true 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2018 Lenard Pratt 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. -------------------------------------------------------------------------------- /assets/bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lapz/tox/76df92fe9c1fe48a9831cdceb465673a29a3cd14/assets/bar.png -------------------------------------------------------------------------------- /assets/errors.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lapz/tox/76df92fe9c1fe48a9831cdceb465673a29a3cd14/assets/errors.png -------------------------------------------------------------------------------- /assets/program.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lapz/tox/76df92fe9c1fe48a9831cdceb465673a29a3cd14/assets/program.png -------------------------------------------------------------------------------- /codegen/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "codegen" 3 | version = "0.1.0" 4 | authors = ["Lenard Pratt "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | errors= {path="../errors"} 11 | semant = {path="../semant"} 12 | salsa = "^0.14.1" 13 | -------------------------------------------------------------------------------- /codegen/src/db.rs: -------------------------------------------------------------------------------- 1 | use errors::{db::File, FileId, WithError}; 2 | use semant::HirDatabase; 3 | 4 | #[salsa::query_group(CodegenDatabaseStorage)] 5 | pub trait CodegenDatabase: HirDatabase { 6 | /* 7 | #[salsa::invoke(c)] 8 | fn escape_analysis(&self,file:FileId) -> WithError>; 9 | */ 10 | #[salsa::invoke(crate::hir::compile_to_asm_query)] 11 | fn compile_to_asm(&self, file: FileId) -> WithError<()>; 12 | } 13 | -------------------------------------------------------------------------------- /codegen/src/lib.rs: -------------------------------------------------------------------------------- 1 | mod db; 2 | mod hir; 3 | 4 | pub use db::{CodegenDatabase, CodegenDatabaseStorage}; 5 | -------------------------------------------------------------------------------- /errors/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "errors" 3 | version = "0.1.0" 4 | authors = ["Lenard Pratt "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | codespan-reporting = {version="^0.9.0",git="https://github.com/Lapz/codespan"} 11 | reporting = {version="^0.9.0",package="codespan-reporting"} 12 | itertools="*" 13 | salsa = "^0.14.1" -------------------------------------------------------------------------------- /errors/src/files.rs: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /errors/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod db; 2 | mod files; 3 | pub mod pos; 4 | mod reporter; 5 | pub use crate::reporter::Reporter; 6 | pub use codespan_reporting::{ 7 | diagnostic::Diagnostic, 8 | files::Files, 9 | term::{ 10 | emit, 11 | termcolor::{ColorChoice, StandardStream}, 12 | Config, 13 | }, 14 | }; 15 | 16 | pub use pos::Span; 17 | 18 | pub use db::{FileDatabase, FileDatabaseStorage, FileId}; 19 | 20 | #[derive(Debug, Clone, Eq, PartialEq)] 21 | pub struct WithError(pub T, pub Vec>); 22 | 23 | impl WithError { 24 | #[inline(always)] 25 | pub fn is_ok(&self) -> bool { 26 | self.1.is_empty() 27 | } 28 | 29 | #[inline(always)] 30 | pub fn is_err(&self) -> bool { 31 | !self.is_ok() 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /ir/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "ir" 3 | version = "0.1.0" 4 | authors = ["Lenard Pratt "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | errors= {path="../errors"} 11 | semant = {path="../semant"} 12 | salsa = "^0.14.1" -------------------------------------------------------------------------------- /ir/src/block.rs: -------------------------------------------------------------------------------- 1 | use crate::ir::{Instruction, Register}; 2 | 3 | #[derive(Debug, Clone, Hash, PartialEq, Eq, Copy)] 4 | pub struct BlockID(pub u32); 5 | 6 | #[derive(Clone,Debug)] 7 | pub struct Block { 8 | pub instructions: Vec, 9 | pub end: BlockEnd, 10 | } 11 | 12 | #[derive(Debug, Clone, PartialEq)] 13 | pub enum BlockEnd { 14 | Jump(BlockID), 15 | Return(Register), 16 | Branch(Register, BlockID, BlockID), 17 | Link(BlockID), 18 | End, 19 | } 20 | 21 | #[derive(Debug)] 22 | pub struct LoopDescription { 23 | pub start: BlockID, 24 | pub end: BlockID, 25 | } 26 | 27 | 28 | impl LoopDescription { 29 | pub fn start(&self) -> BlockID { 30 | self.start 31 | } 32 | 33 | pub fn end(&self) -> BlockID { 34 | self.end 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /ir/src/db.rs: -------------------------------------------------------------------------------- 1 | use crate::ir::Instruction; 2 | use errors::{FileId, WithError}; 3 | use semant::HirDatabase; 4 | 5 | #[salsa::query_group(IrDatabaseStorage)] 6 | pub trait IrDatabase: HirDatabase { 7 | /* 8 | #[salsa::invoke(c)] 9 | fn escape_analysis(&self,file:FileId) -> WithError>; 10 | */ 11 | #[salsa::invoke(crate::builder::build_ir_query)] 12 | fn build_ir(&self, file: FileId) -> WithError<()>; 13 | } 14 | -------------------------------------------------------------------------------- /ir/src/frame.rs: -------------------------------------------------------------------------------- 1 | use crate::ir::Label; 2 | mod x86_64; 3 | pub trait Frame: Clone { 4 | type Access: Clone; 5 | 6 | fn new(&mut self, name: Label, formals: Vec, register_count: u32) -> Self; 7 | 8 | fn name(&self) -> Label; 9 | 10 | fn formals(&self) -> &[Self::Access]; 11 | 12 | fn alloc_local(&mut self, escape: bool) -> Self::Access; 13 | } 14 | -------------------------------------------------------------------------------- /ir/src/frame/x86_64.rs: -------------------------------------------------------------------------------- 1 | use crate::ir::{Label, Register}; 2 | 3 | use super::Frame; 4 | 5 | pub const POINTER_SIZE: i64 = 8; 6 | pub const FUNCTION_SIZE: i64 = 8; 7 | 8 | #[derive(Debug, Clone)] 9 | struct X86_64 { 10 | name: Label, 11 | formals: Vec, 12 | offset: i64, 13 | register_count: u32, 14 | } 15 | #[derive(Debug, Clone)] 16 | enum Access { 17 | InFrame(i64), 18 | InReg(Register), 19 | } 20 | 21 | impl Frame for X86_64 { 22 | type Access = Access; 23 | 24 | fn new(&mut self, name: crate::ir::Label, formals: Vec, register_count: u32) -> Self { 25 | let mut frame = Self { 26 | name, 27 | formals: Vec::new(), 28 | offset: 0, 29 | register_count, 30 | }; 31 | 32 | frame.formals = formals 33 | .iter() 34 | .map(|escape| frame.alloc_local(*escape)) 35 | .collect(); 36 | 37 | frame 38 | } 39 | 40 | fn name(&self) -> crate::ir::Label { 41 | self.name 42 | } 43 | 44 | fn formals(&self) -> &[Self::Access] { 45 | &self.formals 46 | } 47 | 48 | fn alloc_local(&mut self, escape: bool) -> Self::Access { 49 | if escape { 50 | self.offset -= POINTER_SIZE; 51 | Access::InFrame(self.offset) 52 | } else { 53 | self.register_count += 1; 54 | Access::InReg(Register(self.register_count)) 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /ir/src/ir.rs: -------------------------------------------------------------------------------- 1 | use std::collections::HashMap; 2 | 3 | use semant::hir::{ FunctionId}; 4 | 5 | 6 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] 7 | pub struct Register(pub u32); 8 | 9 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] 10 | pub struct Label(pub u32); 11 | 12 | #[derive(Debug, PartialEq, Clone, Eq)] 13 | pub enum Value { 14 | Nil, 15 | Bool(bool), 16 | Int(i64), 17 | Float { 18 | f_bits: f32, 19 | i_bits: i32, 20 | } 21 | } 22 | 23 | #[repr(C)] 24 | pub union FloatParts { 25 | pub f_bits: f32, 26 | pub i_bits: i32, 27 | } 28 | 29 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] 30 | pub enum Size { 31 | Bit8, 32 | Bit32, 33 | Bit64, 34 | } 35 | 36 | pub struct Function { 37 | id: FunctionId, 38 | params: Vec, 39 | layout: HashMap, 40 | instructions: Vec, 41 | } 42 | 43 | #[derive(Debug, Clone, PartialEq, Eq)] 44 | pub enum Instruction { 45 | /// $dest = $lhs $op $rhs 46 | Binary(Register, Register, BinOp, Register), 47 | ///Cast the value from one type to another 48 | /// $dest = $val as type 49 | Cast(Register, Register, Size), 50 | /// Call the function with the provided args in registers and store in in the dest 51 | /// $dest = call $func($args) 52 | Call(Register, Register, Vec), 53 | /// $dest = val 54 | StoreI(Register, Value), 55 | /// $dest = val 56 | Store(Register, Register), 57 | Illegal, 58 | } 59 | 60 | #[derive(Debug, Clone, PartialEq, Eq)] 61 | pub enum BinOp { 62 | Plus, 63 | Minus, 64 | Mul, 65 | Div, 66 | Gt, 67 | Lt, 68 | Equal 69 | } 70 | -------------------------------------------------------------------------------- /ir/src/lib.rs: -------------------------------------------------------------------------------- 1 | mod builder; 2 | mod db; 3 | mod frame; 4 | mod ir; 5 | mod block; 6 | mod printer; 7 | -------------------------------------------------------------------------------- /notes/infer.md: -------------------------------------------------------------------------------- 1 | # Type Inference 2 | 3 | During the type inference variable resolution is done as well as doing 4 | type inference. 5 | 6 | The type inference is based on the HIR. 7 | 8 | ```rust 9 | #[derive(Debug, Clone, Eq, PartialEq)] 10 | pub enum Stmt { 11 | Let { 12 | pat: PatId, 13 | initializer: Option, 14 | }, 15 | Expr(ExprId), 16 | } 17 | #[derive(Debug, Clone, PartialEq, Eq)] 18 | pub enum Expr { 19 | Array(Vec), 20 | Binary { lhs: ExprId, op: BinOp, rhs: ExprId }, 21 | Block(Vec), 22 | Break, 23 | Call { callee: ExprId, args: Vec }, 24 | Cast { expr: ExprId, ty: TypeId }, 25 | Continue, 26 | If { cond: ExprId }, 27 | Ident(NameId), 28 | Index { base: ExprId, index: ExprId }, 29 | While { cond: ExprId, body: Vec }, 30 | Literal(LiteralId), 31 | Paren(ExprId), 32 | Tuple(Vec), 33 | Unary { op: UnaryOp, expr: ExprId }, 34 | Return(Option), 35 | Match { expr: ExprId, arms: Vec }, 36 | } 37 | 38 | 39 | ``` 40 | 41 | It should be done using query's. 42 | -------------------------------------------------------------------------------- /opcode/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "opcode" 3 | version = "0.1.0" 4 | authors = ["Lenard Pratt "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | -------------------------------------------------------------------------------- /parser/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "parser" 3 | version = "0.1.0" 4 | authors = ["Lenard Pratt "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | salsa = "^0.14.1" 11 | syntax={path="../syntax",version="*"} 12 | errors = {path="../errors"} 13 | rowan="0.9.0" 14 | [dev-dependencies] 15 | insta = "0.16.0" 16 | pretty_assertions = "0.6.1" 17 | tempfile = "3.1.0" -------------------------------------------------------------------------------- /parser/src/db.rs: -------------------------------------------------------------------------------- 1 | use errors::pos::Span; 2 | use errors::FileDatabase; 3 | use errors::FileId; 4 | use errors::WithError; 5 | use syntax::ast::SourceFile; 6 | use syntax::Token; 7 | 8 | #[salsa::query_group(ParseDatabaseStorage)] 9 | pub trait ParseDatabase: FileDatabase { 10 | #[salsa::invoke(crate::parse::parse_query)] 11 | fn parse(&self, file: FileId) -> WithError; 12 | 13 | #[salsa::invoke(crate::parse::lex_query)] 14 | fn lex(&self, file: FileId) -> WithError>>; 15 | } 16 | -------------------------------------------------------------------------------- /parser/src/lexer.rs: -------------------------------------------------------------------------------- 1 | #[cfg(test)] 2 | mod tests { 3 | 4 | use crate::utils::MockDatabaseImpl; 5 | use crate::ParseDatabase; 6 | use errors::{pos::Span, FileDatabase}; 7 | use insta::assert_debug_snapshot; 8 | use std::io::Write; 9 | use syntax::Token; 10 | use tempfile::NamedTempFile; 11 | 12 | fn get_tokens(input: &str) -> Vec> { 13 | let mut file = NamedTempFile::new().unwrap(); 14 | write!(file, "{}", input).unwrap(); 15 | 16 | let db = MockDatabaseImpl::default(); 17 | let handle = db.intern_file(file.path().to_path_buf()); 18 | 19 | db.lex(handle).0 20 | } 21 | 22 | #[test] 23 | fn it_works() { 24 | let input = "fn main() {print(\"hello\")}"; 25 | 26 | assert_debug_snapshot!(get_tokens(input)) 27 | } 28 | #[test] 29 | fn lex_int() { 30 | let input = "12,34,,45,67,89,0"; 31 | 32 | assert_debug_snapshot!(get_tokens(input)) 33 | } 34 | 35 | #[test] 36 | fn lex_floats() { 37 | let input = "12.34,45.67,89.10"; 38 | 39 | assert_debug_snapshot!(get_tokens(input)) 40 | } 41 | 42 | #[test] 43 | fn lex_block_comments() { 44 | let input = "12 /*this is a comment */ 34"; 45 | 46 | assert_debug_snapshot!(get_tokens(input)) 47 | } 48 | 49 | #[test] 50 | fn lex_nested_block_comments() { 51 | let input = "/*this /*is a nested */ comment */"; 52 | 53 | assert_debug_snapshot!(get_tokens(input)) 54 | } 55 | 56 | #[test] 57 | fn lex_line_comment() { 58 | let input = "12 // this is a line comment"; 59 | 60 | assert_debug_snapshot!(get_tokens(input)) 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /parser/src/lib.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | mod macros; 3 | mod db; 4 | #[cfg(test)] 5 | mod lexer; 6 | mod parse; 7 | mod parser; 8 | mod utils; 9 | pub use crate::parser::Parser; 10 | pub use db::{ParseDatabase, ParseDatabaseStorage}; 11 | pub(crate) use errors::pos::Span; 12 | pub(crate) use syntax::{ast, AstNode, SyntaxKind, SyntaxNode}; 13 | pub use utils::dump_debug; 14 | -------------------------------------------------------------------------------- /parser/src/macros.rs: -------------------------------------------------------------------------------- 1 | #[macro_export] 2 | macro_rules! test_parser { 3 | ($f_name:ident,$test:expr) => { 4 | #[test] 5 | fn $f_name() { 6 | let parser_output = $crate::utils::parse($test).0; 7 | 8 | insta::assert_snapshot!($crate::utils::dump_debug(&parser_output)); 9 | } 10 | }; 11 | } 12 | -------------------------------------------------------------------------------- /parser/src/parse.rs: -------------------------------------------------------------------------------- 1 | use crate::db::ParseDatabase; 2 | use crate::Parser; 3 | use errors::{pos::Span, FileId, Reporter, WithError}; 4 | use syntax::{ast::SourceFile, Lexer, Token}; 5 | 6 | pub fn lex_query(db: &impl ParseDatabase, file: FileId) -> WithError>> { 7 | let reporter = Reporter::new(file); 8 | let source = db.source(file); 9 | let mut lexer = Lexer::new(&source, reporter); 10 | let tokens = lexer.lex(); 11 | let reporter = lexer.reporter(); 12 | 13 | WithError(tokens, reporter.finish()) 14 | } 15 | 16 | pub fn parse_query(db: &impl ParseDatabase, file: FileId) -> WithError { 17 | let reporter = Reporter::new(file); 18 | 19 | let source = db.source(file); 20 | 21 | let WithError(tokens, mut errors) = db.lex(file); 22 | let mut parser = Parser::new(&tokens, reporter, &source); 23 | let program = parser.parse_program(); 24 | let reporter = parser.reporter(); 25 | errors.extend(reporter.finish()); 26 | WithError(program, errors) 27 | } 28 | -------------------------------------------------------------------------------- /parser/src/parser/enums.rs: -------------------------------------------------------------------------------- 1 | use syntax::T; 2 | 3 | use crate::parser::Parser; 4 | 5 | use crate::SyntaxKind::*; 6 | 7 | impl<'a> Parser<'a> { 8 | pub(crate) fn parse_enum(&mut self, checkpoint: rowan::Checkpoint) { 9 | self.start_node_at(checkpoint, ENUM_DEF); 10 | 11 | self.expect(T![enum]); 12 | 13 | self.ident(); 14 | 15 | if self.at(T![<]) { 16 | self.parse_type_params(false); 17 | } 18 | 19 | self.parse_enum_variants(); 20 | 21 | self.finish_node() 22 | } 23 | 24 | fn parse_enum_variants(&mut self) { 25 | self.start_node(ENUM_VARIANT_LIST); 26 | 27 | self.expect(T!["{"]); 28 | 29 | while !self.at(EOF) && !self.at(T!["}"]) { 30 | self.parse_enum_variant(); 31 | if !self.at(T!["}"]) && !self.expected(T![,]) { 32 | break; 33 | } 34 | } 35 | 36 | self.expect(T!["}"]); 37 | 38 | self.finish_node(); 39 | } 40 | 41 | fn parse_enum_variant(&mut self) { 42 | self.start_node(ENUM_VARIANT); 43 | 44 | self.ident(); 45 | 46 | if self.at(T!["("]) { 47 | self.parse_enum_variant_types() 48 | } 49 | 50 | self.finish_node(); 51 | } 52 | 53 | fn parse_enum_variant_types(&mut self) { 54 | self.bump(); // Eat the "(" 55 | while !self.at(EOF) && !self.at(T![")"]) { 56 | self.parse_type(); 57 | 58 | if !self.at(T![")"]) && !self.expected(T![,]) { 59 | break; 60 | } 61 | } 62 | 63 | self.expect(T![")"]); 64 | } 65 | } 66 | 67 | #[cfg(test)] 68 | mod tests { 69 | test_parser! {parse_empty_enum,"enum Foo {}"} 70 | test_parser! {parse_exported_enum,"export enum Foo {}"} 71 | test_parser! {parse_enum_with_variants,"enum Foo {A,B,C}"} 72 | test_parser! {parse_enum_variants_trailing_comma,"enum Foo {A,B,C,}"} 73 | test_parser! {parse_enum_variants_types,"enum Foo { A([i32]),B(i32),C((i32,i32)),}"} 74 | test_parser! {parse_enum_generic,"enum Result { Ok(T),Err(E)}"} 75 | } 76 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/binary.rs: -------------------------------------------------------------------------------- 1 | use syntax::T; 2 | 3 | use crate::parser::pratt::{InfixParser, Precedence}; 4 | use crate::parser::{Parser, Restrictions}; 5 | 6 | use crate::SyntaxKind::*; 7 | 8 | impl<'a> Parser<'a> { 9 | pub(crate) fn parse_op(&mut self) { 10 | match self.current() { 11 | T![-] 12 | | T![+] 13 | | T![*] 14 | | T![/] 15 | | T![&&] 16 | | T![||] 17 | |T![<] 18 | |T![>] 19 | // | T![^] 20 | // | T![%] 21 | | T![=] 22 | | T![==] 23 | | T![!] 24 | | T![!=] 25 | | T![<=] 26 | | T![>=] 27 | | T![+=] 28 | | T![-=] 29 | | T![*=] 30 | | T![/=] => self.bump(), 31 | 32 | _ => self.error("Expected an operator",format!("Expected one of `-` | `+` |`*`| `/` | `&&` | `||` | `<` | `>` | `==` | `!` | `!=` | `>=` | `<=` | `+=` | `-=` | `*=` | `/=` instead found `{}`",self.current_string())), 33 | } 34 | } 35 | } 36 | #[derive(Debug)] 37 | pub struct BinaryParselet(pub Precedence); 38 | 39 | impl InfixParser for BinaryParselet { 40 | fn pred(&self) -> Precedence { 41 | self.0 42 | } 43 | 44 | fn parse(&self, parser: &mut Parser, checkpoint: rowan::Checkpoint) { 45 | parser.start_node_at(checkpoint, BIN_EXPR); 46 | 47 | parser.parse_op(); 48 | 49 | let restriction = parser.restriction.unwrap_or(Restrictions::default()); 50 | parser.parse_expression(self.0.higher(), restriction); 51 | 52 | parser.finish_node(); 53 | } 54 | } 55 | 56 | #[cfg(test)] 57 | mod tests { 58 | test_parser! {parse_bin_expr,"fn main() {1+1;}"} 59 | test_parser! {parse_wrapped_bin_expr_literal,"fn main() {1.0+2.0+2.0;}"} 60 | test_parser! {parse_assign_bin_expr_,"fn main() {x=10;x+=10;x-=10;x/=10;x*=10;}"} 61 | test_parser! {parse_chained_assign_bin_expr_,"fn main() {x=10=10=2=3;}"} 62 | } 63 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/break_expr.rs: -------------------------------------------------------------------------------- 1 | use syntax::T; 2 | 3 | use crate::parser::Parser; 4 | 5 | use crate::SyntaxKind::*; 6 | 7 | impl<'a> Parser<'a> { 8 | pub(crate) fn parse_break_expr(&mut self) { 9 | self.start_node(BREAK_EXPR); 10 | 11 | self.expect(T![break]); 12 | 13 | self.finish_node() 14 | } 15 | } 16 | 17 | #[cfg(test)] 18 | mod tests { 19 | test_parser! {parse_break_expr,"fn main() {break;}"} 20 | } 21 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/call_expr.rs: -------------------------------------------------------------------------------- 1 | use syntax::T; 2 | 3 | use crate::parser::pratt::{InfixParser, Precedence}; 4 | use crate::parser::{Parser, Restrictions}; 5 | 6 | use crate::SyntaxKind::*; 7 | 8 | #[derive(Debug)] 9 | pub struct CallParselet(pub Precedence); 10 | 11 | impl InfixParser for CallParselet { 12 | fn parse(&self, parser: &mut Parser, checkpoint: rowan::Checkpoint) { 13 | parser.start_node_at(checkpoint, CALL_EXPR); 14 | parser.start_node(ARG_LIST); 15 | 16 | parser.expect(T!["("]); 17 | 18 | while !parser.at(EOF) && !parser.at(T![")"]) { 19 | parser.parse_expression(Precedence::Assignment, Restrictions::default()); 20 | 21 | if !parser.at(T![")"]) && !parser.expected(T![,]) { 22 | break; 23 | } 24 | } 25 | 26 | parser.expect(T![")"]); 27 | 28 | parser.finish_node(); 29 | parser.finish_node(); 30 | } 31 | 32 | fn pred(&self) -> Precedence { 33 | self.0 34 | } 35 | } 36 | 37 | #[cfg(test)] 38 | mod tests { 39 | test_parser! {parse_simple_call_expr,"fn main() {a(1,2);}"} 40 | test_parser! {parse_call_no_args_expr,"fn main() {a();}"} 41 | test_parser! {parse_call_generic_params_expr,"fn main() {a::(a,b);}"} 42 | test_parser! {parse_call_trailing_comma,"fn main() {a(a,b,);}"} 43 | test_parser! {parse_call_ife,"fn main() {a(a,b,)();}"} 44 | test_parser! {parse_call_ife_with_args,"fn main() {a(a,b,)(1,2,3);}"} 45 | } 46 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/closure_expr.rs: -------------------------------------------------------------------------------- 1 | use syntax::T; 2 | 3 | use crate::parser::Parser; 4 | 5 | use crate::SyntaxKind::*; 6 | 7 | use crate::parser::PrefixParser; 8 | 9 | #[derive(Debug)] 10 | pub struct ClosureParselet; 11 | 12 | impl<'a> Parser<'a> { 13 | pub(crate) fn parse_closure_expr(&mut self) { 14 | self.start_node(CLOSURE_EXPR); 15 | 16 | self.parse_func_params(T![|]); 17 | 18 | if self.current() == T![->] { 19 | self.parse_return_type(); 20 | } 21 | 22 | self.parse_block(); 23 | 24 | self.finish_node() 25 | } 26 | } 27 | 28 | impl PrefixParser for ClosureParselet { 29 | fn parse(&self, parser: &mut Parser) { 30 | parser.parse_closure_expr(); 31 | } 32 | } 33 | 34 | #[cfg(test)] 35 | mod tests { 36 | test_parser! {parse_simple_closure_expr,r" 37 | fn main() { 38 | let a = |x,y| { 39 | return x+y; 40 | } 41 | }"} 42 | test_parser! {parse_closure_with_types,"fn main() { 43 | let a = |x,y| -> i32 { 44 | return x+y; 45 | } 46 | }"} 47 | test_parser! {parse_empty_closure_expr,"fn main() { 48 | let a = || {}; 49 | }"} 50 | test_parser! {parse_free_closure_expr,"fn main() { 51 | || {}; 52 | }"} 53 | } 54 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/continue_expr.rs: -------------------------------------------------------------------------------- 1 | use syntax::T; 2 | 3 | use crate::parser::Parser; 4 | 5 | use crate::SyntaxKind::*; 6 | 7 | impl<'a> Parser<'a> { 8 | pub(crate) fn parse_continue_expr(&mut self) { 9 | self.start_node(CONTINUE_EXPR); 10 | 11 | self.expect(T![continue]); 12 | 13 | self.finish_node() 14 | } 15 | } 16 | 17 | #[cfg(test)] 18 | mod tests { 19 | test_parser! {parse_continue_expr,"fn main() {continue;}"} 20 | } 21 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/do_expr.rs: -------------------------------------------------------------------------------- 1 | use syntax::T; 2 | 3 | use crate::parser::{Parser, Restrictions}; 4 | 5 | use crate::SyntaxKind::*; 6 | 7 | use crate::parser::Precedence; 8 | 9 | impl<'a> Parser<'a> { 10 | pub(crate) fn parse_do_expr(&mut self) { 11 | self.start_node(DO_EXPR); 12 | 13 | self.expect(T![do]); 14 | 15 | self.parse_block(); 16 | 17 | self.expect(T![while]); 18 | 19 | self.parse_expression(Precedence::Assignment, Restrictions::no_records()); 20 | 21 | self.finish_node() 22 | } 23 | } 24 | 25 | #[cfg(test)] 26 | mod tests { 27 | test_parser! {parse_do_expr,"fn main() { do {println(x); x=x+1;} while x<10;}"} 28 | } 29 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/field_expr.rs: -------------------------------------------------------------------------------- 1 | use syntax::T; 2 | 3 | use crate::parser::pratt::{InfixParser, Precedence}; 4 | use crate::parser::{Parser, Restrictions}; 5 | 6 | use crate::SyntaxKind::*; 7 | 8 | #[derive(Debug)] 9 | pub struct FieldParselet(pub Precedence); 10 | 11 | impl InfixParser for FieldParselet { 12 | fn parse(&self, parser: &mut Parser, checkpoint: rowan::Checkpoint) { 13 | parser.start_node_at(checkpoint, FIELD_EXPR); 14 | 15 | parser.expect(T![.]); 16 | 17 | parser.parse_expression(Precedence::Or, Restrictions::default()); 18 | 19 | parser.finish_node(); 20 | } 21 | 22 | fn pred(&self) -> Precedence { 23 | self.0 24 | } 25 | } 26 | 27 | #[cfg(test)] 28 | mod tests { 29 | test_parser! {parse_field_access,"fn main(){a.b;}"} 30 | test_parser! {parse_field_access_assign,"fn main(){a.b = 10;}"} 31 | test_parser! {parse_field_access_chain,"fn main(){a.b.c.d.e.f;}"} 32 | test_parser! {parse_field_access_method,"fn main(){a.b();}"} 33 | test_parser! {parse_field_access_method_chain,"fn main(){a.b.c.d.e();}"} 34 | } 35 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/for_expr.rs: -------------------------------------------------------------------------------- 1 | use syntax::T; 2 | 3 | use crate::parser::{Parser, Precedence, Restrictions}; 4 | use crate::SyntaxKind::*; 5 | 6 | impl<'a> Parser<'a> { 7 | pub(crate) fn parse_for_expr(&mut self) { 8 | self.start_node(FOR_EXPR); 9 | 10 | self.expect(T![for]); 11 | 12 | self.expect(T!["("]); 13 | 14 | if self.at(T![;]) { 15 | self.bump() 16 | } else if self.at(T![let]) { 17 | self.parse_let_expr(); 18 | self.expect(T![;]); 19 | } else { 20 | self.parse_expression(Precedence::Assignment, Restrictions::default()); 21 | self.expect(T![;]); 22 | } 23 | 24 | if self.at(T![;]) { 25 | self.bump() 26 | } else { 27 | self.parse_expression(Precedence::Comparison, Restrictions::default()); 28 | self.expect(T![;]); 29 | } 30 | 31 | if self.at(T![;]) { 32 | self.bump(); 33 | } else if self.at(T![")"]) { 34 | } else { 35 | self.parse_expression(Precedence::Assignment, Restrictions::default()); 36 | } 37 | 38 | self.expect(T![")"]); 39 | 40 | self.parse_block(); 41 | 42 | self.finish_node() 43 | } 44 | } 45 | 46 | mod tests { 47 | test_parser! {parse_empty_for_expr,"fn main() {for(;;;) {}}"} 48 | test_parser! {parse_for_expr," 49 | fn main() { 50 | for(let x = 10; x< 10; x=x+1) { 51 | println(\"it works \") 52 | };}" 53 | } 54 | test_parser! {parse_for_no_incr,"fn main() { for (let x=10;x<10;;){};}"} 55 | test_parser! {parse_for_no_cond,"fn main() { for (let x=10;;x+=10){};}"} 56 | test_parser! {parse_for_no_init,"fn main() { for (;x<10;x+=10){};}"} 57 | } 58 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/grouping.rs: -------------------------------------------------------------------------------- 1 | use syntax::T; 2 | 3 | use crate::parser::pratt::{Precedence, PrefixParser}; 4 | use crate::parser::{Parser, Restrictions}; 5 | 6 | use crate::SyntaxKind::*; 7 | 8 | #[derive(Debug)] 9 | pub struct GroupingParselet; 10 | 11 | impl PrefixParser for GroupingParselet { 12 | fn parse(&self, parser: &mut Parser) { 13 | let checkpoint = parser.checkpoint(); 14 | 15 | let mut seen_comma = false; 16 | 17 | parser.bump(); // Eats the `(` 18 | 19 | parser.parse_expression(Precedence::Assignment, Restrictions::default()); 20 | 21 | if parser.at(T![,]) { 22 | seen_comma = true; 23 | parser.bump(); 24 | 25 | while !parser.at(EOF) && !parser.at(T![")"]) { 26 | parser.parse_expression(Precedence::Assignment, Restrictions::default()); 27 | if !parser.at(T![")"]) && !parser.expected(T![,]) { 28 | break; 29 | } 30 | } 31 | } 32 | 33 | parser.expect(T![")"]); 34 | 35 | if seen_comma { 36 | parser.start_node_at(checkpoint, TUPLE_EXPR); 37 | } else { 38 | parser.start_node_at(checkpoint, PAREN_EXPR) 39 | } 40 | 41 | parser.finish_node(); 42 | } 43 | } 44 | 45 | #[cfg(test)] 46 | mod tests { 47 | test_parser! {parse_grouping_expr,"fn main() {(1+10-1);}"} 48 | test_parser! {parse_tuple_expr,"fn main() {(1,2,3,4);}"} 49 | } 50 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/ident.rs: -------------------------------------------------------------------------------- 1 | use syntax::T; 2 | 3 | use crate::parser::pratt::{Precedence, PrefixParser}; 4 | use crate::parser::{restrictions::Restrictions, Parser}; 5 | use crate::SyntaxKind::*; 6 | 7 | #[derive(Debug)] 8 | pub struct IdentParselet; 9 | 10 | impl PrefixParser for IdentParselet { 11 | fn parse(&self, parser: &mut Parser) { 12 | let c = parser.checkpoint(); 13 | parser.start_node(IDENT_EXPR); 14 | 15 | parser.start_node(NAME); 16 | 17 | parser.expect(IDENT); 18 | 19 | if parser.at(T![::]) { 20 | parser.finish_node(); // close name 21 | 22 | parser.bump(); 23 | 24 | if parser.at(T![<]) { 25 | parser.parse_type_args(); 26 | parser.finish_node(); // close ident_expr 27 | } else { 28 | parser.finish_node(); 29 | 30 | parser.start_node(IDENT_EXPR); 31 | 32 | parser.start_node(NAME); 33 | parser.expect(IDENT); 34 | 35 | parser.finish_node(); 36 | parser.finish_node(); 37 | 38 | if !parser.at(T![;]) && parser.at(T!["("]) { 39 | parser.parse_expression(Precedence::Assignment, Restrictions::default()); 40 | } 41 | 42 | parser.start_node_at(c, ENUM_EXPR); 43 | parser.finish_node(); 44 | } 45 | } else { 46 | parser.finish_node(); 47 | parser.finish_node(); 48 | } 49 | } 50 | } 51 | 52 | #[cfg(test)] 53 | mod tests { 54 | test_parser! { 55 | parse_ident_expr,"fn main(){a;}" 56 | } 57 | test_parser! { 58 | parse_generic_ident_expr,"fn main(){a::;}" 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/if_expr.rs: -------------------------------------------------------------------------------- 1 | use syntax::T; 2 | 3 | use crate::parser::{Parser, Precedence, Restrictions}; 4 | 5 | use crate::SyntaxKind::*; 6 | 7 | impl<'a> Parser<'a> { 8 | pub(crate) fn parse_if_expr(&mut self) { 9 | self.start_node(IF_EXPR); 10 | 11 | self.expect(T![if]); 12 | 13 | self.start_node(CONDITION); 14 | 15 | self.restriction = Some(Restrictions::no_records()); 16 | self.parse_expression(Precedence::Assignment, Restrictions::no_records()); 17 | self.finish_node(); 18 | self.restriction = None; 19 | self.parse_block(); 20 | 21 | if self.current() == T![else] { 22 | self.parse_else() 23 | } 24 | 25 | self.finish_node() 26 | } 27 | 28 | fn parse_else(&mut self) { 29 | self.bump(); // eat the `else` 30 | 31 | if self.current() == T![if] { 32 | self.parse_if_expr() 33 | } else { 34 | self.parse_block(); 35 | } 36 | } 37 | } 38 | 39 | #[cfg(test)] 40 | mod tests { 41 | test_parser! {parse_empty_if,"fn main() { if true {}}"} 42 | test_parser! {parse_if_and_else,"fn main() { if true {} else {}}"} 43 | test_parser! {parse_chained_if,"fn main() { if true {} else if false {} else if true {} else if false {} }"} 44 | test_parser! {parse_chained_if_and_else,"fn main() { if true {} else if false {} else if true {} else {} }"} 45 | } 46 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/index_expr.rs: -------------------------------------------------------------------------------- 1 | use syntax::T; 2 | 3 | use crate::parser::pratt::{InfixParser, Precedence}; 4 | use crate::parser::{Parser, Restrictions}; 5 | 6 | use crate::SyntaxKind::*; 7 | 8 | #[derive(Debug)] 9 | pub struct IndexParselet(pub Precedence); 10 | 11 | impl InfixParser for IndexParselet { 12 | fn parse(&self, parser: &mut Parser, checkpoint: rowan::Checkpoint) { 13 | parser.start_node_at(checkpoint, INDEX_EXPR); 14 | 15 | parser.expect(T!["["]); 16 | 17 | parser.parse_expression(Precedence::Assignment, Restrictions::default()); 18 | 19 | parser.expect(T!["]"]); 20 | 21 | parser.finish_node(); 22 | } 23 | 24 | fn pred(&self) -> Precedence { 25 | self.0 26 | } 27 | } 28 | 29 | #[cfg(test)] 30 | mod tests { 31 | test_parser! {parse_simple_index_expr,"fn main() {a[1+2];}"} 32 | test_parser! {parse_nested_index_expr,"fn main() {a[0][1];}"} 33 | } 34 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/let_expr.rs: -------------------------------------------------------------------------------- 1 | use syntax::T; 2 | 3 | use crate::parser::{Parser, Restrictions}; 4 | 5 | use crate::SyntaxKind::*; 6 | 7 | use crate::parser::Precedence; 8 | 9 | impl<'a> Parser<'a> { 10 | pub(crate) fn parse_let_expr(&mut self) { 11 | self.start_node(LET_STMT); 12 | 13 | self.expect(T![let]); 14 | 15 | self.parse_pattern(false); 16 | 17 | if self.at(T![:]) { 18 | self.bump(); 19 | self.parse_type(); 20 | } 21 | 22 | if self.at(T![;]) { 23 | self.finish_node(); 24 | return; 25 | } 26 | 27 | self.expect(T![=]); 28 | 29 | if self.at(T!["{"]) { 30 | self.parse_block() 31 | } else { 32 | self.parse_expression(Precedence::Assignment, Restrictions::default()); 33 | } 34 | 35 | self.finish_node() 36 | } 37 | } 38 | 39 | mod tests { 40 | test_parser! {parse_let_expr,"fn main() {let foo = 10; let bar = \"a\"}"} 41 | test_parser! {parse_empty_let_expr,"fn main() {let foo;}"} 42 | test_parser! {parse_let_type_expr,"fn main() {let foo:i32; let bar: (i32,i32);}"} 43 | test_parser! {parse_let_patter_expr,"fn main() {let (a,b); let _ = 10;}"} 44 | } 45 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/literal.rs: -------------------------------------------------------------------------------- 1 | use syntax::T; 2 | 3 | use crate::parser::{ 4 | pratt::{Precedence, PrefixParser}, 5 | Parser, Restrictions, 6 | }; 7 | 8 | use crate::SyntaxKind::*; 9 | 10 | #[derive(Debug)] 11 | pub struct LiteralParselet; 12 | 13 | impl PrefixParser for LiteralParselet { 14 | fn parse(&self, parser: &mut Parser) { 15 | match parser.current() { 16 | INT_NUMBER | FLOAT_NUMBER | STRING | T![nil] |T![true]|T![false] => { 17 | parser.start_node(LITERAL); 18 | parser.bump(); 19 | parser.finish_node(); 20 | }, 21 | 22 | 23 | T!["["] => { 24 | parser.start_node(ARRAY_EXPR); 25 | parser.bump(); // Eats the `[` 26 | 27 | if parser.at(T!["]"]) { 28 | parser.bump(); // Eats the `]` 29 | parser.finish_node(); 30 | return 31 | } 32 | 33 | while !parser.at(EOF) && !parser.at(T!["]"]) { 34 | parser.parse_expression(Precedence::Assignment, Restrictions::default()); 35 | if !parser.at(T!["]"]) && !parser.expected(T![,]) { 36 | break; 37 | } 38 | } 39 | 40 | parser.expect(T!["]"]); 41 | 42 | 43 | parser.finish_node() 44 | 45 | 46 | }, 47 | 48 | _ => parser.error("Expected `{{int}}` or `{{nil}}` or `{{true|false}}` or `{{ident}}` or `{{string}}`",format!("Expected `{{int}}` or `{{nil}}` or `{{true|false}}` or `{{ident}}` or `{{string}}` found `{}`",parser.current_string())) 49 | } 50 | } 51 | } 52 | 53 | #[cfg(test)] 54 | mod tests { 55 | test_parser! {parse_int_literal,"fn main() {1;}"} 56 | test_parser! {parse_float_literal,"fn main() {1.0;}"} 57 | test_parser! {parse_string_literal,"fn main() {\"abc\";}"} 58 | test_parser! {parse_nil_literal,"fn main() {nil};"} 59 | test_parser! {parse_bool_literal,"fn main() {true;false;}"} 60 | } 61 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/match_expr.rs: -------------------------------------------------------------------------------- 1 | use syntax::T; 2 | 3 | use crate::parser::{Parser, Restrictions}; 4 | 5 | use crate::SyntaxKind::*; 6 | 7 | use crate::parser::Precedence; 8 | 9 | impl<'a> Parser<'a> { 10 | pub(crate) fn parse_match_expr(&mut self) { 11 | self.start_node(MATCH_EXPR); 12 | 13 | self.expect(T![match]); 14 | 15 | self.parse_expression(Precedence::Call, Restrictions::no_records()); // TODO Forbid struct literal 16 | 17 | self.expect(T!["{"]); 18 | 19 | self.parse_match_arms(); 20 | 21 | self.expect(T!["}"]); 22 | 23 | self.finish_node() 24 | } 25 | 26 | fn parse_match_arms(&mut self) { 27 | self.start_node(MATCH_ARM_LIST); 28 | 29 | while !self.at(EOF) && !self.at(T!["}"]) { 30 | self.parse_match_arm(); 31 | if !self.at(T!["}"]) && !self.expected(T![,]) { 32 | break; 33 | } 34 | } 35 | 36 | self.finish_node(); 37 | } 38 | 39 | fn parse_match_arm(&mut self) { 40 | self.start_node(MATCH_ARM); 41 | self.parse_pat_list(); 42 | 43 | self.expected(T![=>]); 44 | 45 | if self.at(T!["{"]) { 46 | self.parse_block() 47 | } else { 48 | self.parse_expression(Precedence::Call, Restrictions::default()) 49 | } 50 | self.finish_node(); 51 | } 52 | 53 | fn parse_pat_list(&mut self) { 54 | if self.at(T![|]) { 55 | self.bump(); 56 | } 57 | 58 | self.parse_pattern(true); 59 | 60 | while self.at(T![|]) { 61 | self.bump(); 62 | self.parse_pattern(true) 63 | } 64 | } 65 | } 66 | 67 | mod tests { 68 | test_parser! {parse_empty_match_expr,"fn main() { match a {};}"} 69 | test_parser! {parse_match_expr,"fn main() { match (a,b) { x => 10,1 =>3};}"} 70 | } 71 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/record_expr.rs: -------------------------------------------------------------------------------- 1 | use syntax::T; 2 | 3 | use crate::parser::pratt::{InfixParser, Precedence}; 4 | use crate::parser::{Parser, Restrictions}; 5 | 6 | use crate::SyntaxKind::*; 7 | 8 | #[derive(Debug)] 9 | pub struct RecordParselet(pub Precedence); 10 | 11 | impl InfixParser for RecordParselet { 12 | fn parse(&self, parser: &mut Parser, checkpoint: rowan::Checkpoint) { 13 | parser.start_node_at(checkpoint, RECORD_LITERAL_EXPR); 14 | 15 | parser.start_node(NAMED_FIELD_LIST); 16 | 17 | parser.expect(T!["{"]); 18 | 19 | while !parser.at(EOF) && !parser.at(T!["}"]) { 20 | parser.parse_record_field(); 21 | 22 | if !parser.at(T!["}"]) && !parser.expected(T![,]) { 23 | break; 24 | } 25 | } 26 | 27 | parser.expect(T!["}"]); 28 | parser.finish_node(); 29 | 30 | parser.finish_node(); 31 | } 32 | 33 | fn pred(&self) -> Precedence { 34 | self.0 35 | } 36 | } 37 | 38 | impl<'a> Parser<'a> { 39 | pub(crate) fn parse_record_field(&mut self) { 40 | self.start_node(NAMED_FIELD); 41 | 42 | self.start_node(NAME); 43 | 44 | self.expect(IDENT); 45 | 46 | self.finish_node(); 47 | 48 | if self.at(T![:]) { 49 | self.bump(); 50 | self.parse_expression(Precedence::Assignment, Restrictions::default()); 51 | } 52 | 53 | self.finish_node() 54 | } 55 | } 56 | 57 | #[cfg(test)] 58 | mod tests { 59 | test_parser! {parse_empty_record_literal,"fn main() { foo{};}"} 60 | test_parser! {parse_shorthand_record_literal,"fn main() { foo{ shorthand,short,shortymcshort};}"} 61 | test_parser! {parse_longhand_record_literal,"fn main() { foo{ longhand:longhand,long:long,longymclong:longymclong};}"} 62 | test_parser! {parse_mixed_record_literal,"fn main() { foo{ longhand:longhand,longymclong,long:long};}"} 63 | } 64 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/return_expr.rs: -------------------------------------------------------------------------------- 1 | use syntax::T; 2 | 3 | use crate::parser::{Parser, Restrictions}; 4 | 5 | use crate::SyntaxKind::*; 6 | 7 | use crate::parser::Precedence; 8 | 9 | impl<'a> Parser<'a> { 10 | pub(crate) fn parse_return_expr(&mut self) { 11 | self.start_node(RETURN_EXPR); 12 | 13 | self.expect(T![return]); 14 | 15 | if self.current() == T![;] { 16 | self.finish_node(); 17 | return; 18 | } 19 | 20 | self.parse_expression(Precedence::Assignment, Restrictions::default()); 21 | 22 | self.finish_node() 23 | } 24 | } 25 | 26 | #[cfg(test)] 27 | mod tests { 28 | test_parser! {parse_return_expr,"fn main() {return 1+1;}"} 29 | test_parser! {parse_empty_return_expr,"fn main() {return;}"} 30 | } 31 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/snapshots/parser__parser__expressions__binary__tests__parse_bin_expr.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/expressions/binary.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 16) 6 | FN_DEF@[0; 16) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 9) 12 | L_PAREN@[7; 8) "(" 13 | R_PAREN@[8; 9) ")" 14 | WHITESPACE@[9; 10) " " 15 | BLOCK_EXPR@[10; 16) 16 | BLOCK@[10; 16) 17 | L_CURLY@[10; 11) "{" 18 | EXPR_STMT@[11; 14) 19 | BIN_EXPR@[11; 14) 20 | LITERAL@[11; 12) 21 | INT_NUMBER@[11; 12) "1" 22 | PLUS@[12; 13) "+" 23 | LITERAL@[13; 14) 24 | INT_NUMBER@[13; 14) "1" 25 | SEMI@[14; 15) ";" 26 | R_CURLY@[15; 16) "}" 27 | 28 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/snapshots/parser__parser__expressions__binary__tests__parse_chained_assign_bin_expr_.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/expressions/binary.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 24) 6 | FN_DEF@[0; 24) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 9) 12 | L_PAREN@[7; 8) "(" 13 | R_PAREN@[8; 9) ")" 14 | WHITESPACE@[9; 10) " " 15 | BLOCK_EXPR@[10; 24) 16 | BLOCK@[10; 24) 17 | L_CURLY@[10; 11) "{" 18 | EXPR_STMT@[11; 22) 19 | BIN_EXPR@[11; 22) 20 | BIN_EXPR@[11; 20) 21 | BIN_EXPR@[11; 18) 22 | BIN_EXPR@[11; 15) 23 | IDENT_EXPR@[11; 12) 24 | NAME@[11; 12) 25 | IDENT@[11; 12) "x" 26 | EQ@[12; 13) "=" 27 | LITERAL@[13; 15) 28 | INT_NUMBER@[13; 15) "10" 29 | EQ@[15; 16) "=" 30 | LITERAL@[16; 18) 31 | INT_NUMBER@[16; 18) "10" 32 | EQ@[18; 19) "=" 33 | LITERAL@[19; 20) 34 | INT_NUMBER@[19; 20) "2" 35 | EQ@[20; 21) "=" 36 | LITERAL@[21; 22) 37 | INT_NUMBER@[21; 22) "3" 38 | SEMI@[22; 23) ";" 39 | R_CURLY@[23; 24) "}" 40 | 41 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/snapshots/parser__parser__expressions__binary__tests__parse_wrapped_bin_expr_literal.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/expressions/binary.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 24) 6 | FN_DEF@[0; 24) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 9) 12 | L_PAREN@[7; 8) "(" 13 | R_PAREN@[8; 9) ")" 14 | WHITESPACE@[9; 10) " " 15 | BLOCK_EXPR@[10; 24) 16 | BLOCK@[10; 24) 17 | L_CURLY@[10; 11) "{" 18 | EXPR_STMT@[11; 22) 19 | BIN_EXPR@[11; 22) 20 | BIN_EXPR@[11; 18) 21 | LITERAL@[11; 14) 22 | FLOAT_NUMBER@[11; 14) "1.0" 23 | PLUS@[14; 15) "+" 24 | LITERAL@[15; 18) 25 | FLOAT_NUMBER@[15; 18) "2.0" 26 | PLUS@[18; 19) "+" 27 | LITERAL@[19; 22) 28 | FLOAT_NUMBER@[19; 22) "2.0" 29 | SEMI@[22; 23) ";" 30 | R_CURLY@[23; 24) "}" 31 | 32 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/snapshots/parser__parser__expressions__block__tests__parse_free_block.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/expressions/block.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 14) 6 | FN_DEF@[0; 14) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 9) 12 | L_PAREN@[7; 8) "(" 13 | R_PAREN@[8; 9) ")" 14 | WHITESPACE@[9; 10) " " 15 | BLOCK_EXPR@[10; 14) 16 | BLOCK@[10; 14) 17 | L_CURLY@[10; 11) "{" 18 | EXPR_STMT@[11; 13) 19 | BLOCK_EXPR@[11; 13) 20 | BLOCK@[11; 13) 21 | L_CURLY@[11; 12) "{" 22 | R_CURLY@[12; 13) "}" 23 | R_CURLY@[13; 14) "}" 24 | 25 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/snapshots/parser__parser__expressions__block__tests__parse_nested_block.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/expressions/block.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 16) 6 | FN_DEF@[0; 16) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 9) 12 | L_PAREN@[7; 8) "(" 13 | R_PAREN@[8; 9) ")" 14 | WHITESPACE@[9; 10) " " 15 | BLOCK_EXPR@[10; 16) 16 | BLOCK@[10; 16) 17 | L_CURLY@[10; 11) "{" 18 | EXPR_STMT@[11; 15) 19 | BLOCK_EXPR@[11; 15) 20 | BLOCK@[11; 15) 21 | L_CURLY@[11; 12) "{" 22 | EXPR_STMT@[12; 14) 23 | BLOCK_EXPR@[12; 14) 24 | BLOCK@[12; 14) 25 | L_CURLY@[12; 13) "{" 26 | R_CURLY@[13; 14) "}" 27 | R_CURLY@[14; 15) "}" 28 | R_CURLY@[15; 16) "}" 29 | 30 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/snapshots/parser__parser__expressions__break_expr__tests__parse_break_expr.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/expressions/break_expr.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 18) 6 | FN_DEF@[0; 18) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 9) 12 | L_PAREN@[7; 8) "(" 13 | R_PAREN@[8; 9) ")" 14 | WHITESPACE@[9; 10) " " 15 | BLOCK_EXPR@[10; 18) 16 | BLOCK@[10; 18) 17 | L_CURLY@[10; 11) "{" 18 | EXPR_STMT@[11; 16) 19 | BREAK_EXPR@[11; 16) 20 | BREAK_KW@[11; 16) "break" 21 | SEMI@[16; 17) ";" 22 | R_CURLY@[17; 18) "}" 23 | 24 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/snapshots/parser__parser__expressions__call_expr__tests__parse_call_generic_params_expr.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/expressions/call_expr.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 26) 6 | FN_DEF@[0; 26) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 9) 12 | L_PAREN@[7; 8) "(" 13 | R_PAREN@[8; 9) ")" 14 | WHITESPACE@[9; 10) " " 15 | BLOCK_EXPR@[10; 26) 16 | BLOCK@[10; 26) 17 | L_CURLY@[10; 11) "{" 18 | EXPR_STMT@[11; 24) 19 | CALL_EXPR@[11; 24) 20 | IDENT_EXPR@[11; 19) 21 | NAME@[11; 12) 22 | IDENT@[11; 12) "a" 23 | COLON_COLON@[12; 14) "::" 24 | TYPE_ARG_LIST@[14; 19) 25 | L_ANGLE@[14; 15) "<" 26 | IDENT_TYPE@[15; 18) 27 | IDENT@[15; 18) "i32" 28 | R_ANGLE@[18; 19) ">" 29 | ARG_LIST@[19; 24) 30 | L_PAREN@[19; 20) "(" 31 | IDENT_EXPR@[20; 21) 32 | NAME@[20; 21) 33 | IDENT@[20; 21) "a" 34 | COMMA@[21; 22) "," 35 | IDENT_EXPR@[22; 23) 36 | NAME@[22; 23) 37 | IDENT@[22; 23) "b" 38 | R_PAREN@[23; 24) ")" 39 | SEMI@[24; 25) ";" 40 | R_CURLY@[25; 26) "}" 41 | 42 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/snapshots/parser__parser__expressions__call_expr__tests__parse_call_ife.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/expressions/call_expr.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 22) 6 | FN_DEF@[0; 22) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 9) 12 | L_PAREN@[7; 8) "(" 13 | R_PAREN@[8; 9) ")" 14 | WHITESPACE@[9; 10) " " 15 | BLOCK_EXPR@[10; 22) 16 | BLOCK@[10; 22) 17 | L_CURLY@[10; 11) "{" 18 | EXPR_STMT@[11; 20) 19 | CALL_EXPR@[11; 20) 20 | CALL_EXPR@[11; 18) 21 | IDENT_EXPR@[11; 12) 22 | NAME@[11; 12) 23 | IDENT@[11; 12) "a" 24 | ARG_LIST@[12; 18) 25 | L_PAREN@[12; 13) "(" 26 | IDENT_EXPR@[13; 14) 27 | NAME@[13; 14) 28 | IDENT@[13; 14) "a" 29 | COMMA@[14; 15) "," 30 | IDENT_EXPR@[15; 16) 31 | NAME@[15; 16) 32 | IDENT@[15; 16) "b" 33 | COMMA@[16; 17) "," 34 | R_PAREN@[17; 18) ")" 35 | ARG_LIST@[18; 20) 36 | L_PAREN@[18; 19) "(" 37 | R_PAREN@[19; 20) ")" 38 | SEMI@[20; 21) ";" 39 | R_CURLY@[21; 22) "}" 40 | 41 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/snapshots/parser__parser__expressions__call_expr__tests__parse_call_ife_with_args.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/expressions/call_expr.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 27) 6 | FN_DEF@[0; 27) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 9) 12 | L_PAREN@[7; 8) "(" 13 | R_PAREN@[8; 9) ")" 14 | WHITESPACE@[9; 10) " " 15 | BLOCK_EXPR@[10; 27) 16 | BLOCK@[10; 27) 17 | L_CURLY@[10; 11) "{" 18 | EXPR_STMT@[11; 25) 19 | CALL_EXPR@[11; 25) 20 | CALL_EXPR@[11; 18) 21 | IDENT_EXPR@[11; 12) 22 | NAME@[11; 12) 23 | IDENT@[11; 12) "a" 24 | ARG_LIST@[12; 18) 25 | L_PAREN@[12; 13) "(" 26 | IDENT_EXPR@[13; 14) 27 | NAME@[13; 14) 28 | IDENT@[13; 14) "a" 29 | COMMA@[14; 15) "," 30 | IDENT_EXPR@[15; 16) 31 | NAME@[15; 16) 32 | IDENT@[15; 16) "b" 33 | COMMA@[16; 17) "," 34 | R_PAREN@[17; 18) ")" 35 | ARG_LIST@[18; 25) 36 | L_PAREN@[18; 19) "(" 37 | LITERAL@[19; 20) 38 | INT_NUMBER@[19; 20) "1" 39 | COMMA@[20; 21) "," 40 | LITERAL@[21; 22) 41 | INT_NUMBER@[21; 22) "2" 42 | COMMA@[22; 23) "," 43 | LITERAL@[23; 24) 44 | INT_NUMBER@[23; 24) "3" 45 | R_PAREN@[24; 25) ")" 46 | SEMI@[25; 26) ";" 47 | R_CURLY@[26; 27) "}" 48 | 49 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/snapshots/parser__parser__expressions__call_expr__tests__parse_call_no_args_expr.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/expressions/call_expr.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 16) 6 | FN_DEF@[0; 16) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 9) 12 | L_PAREN@[7; 8) "(" 13 | R_PAREN@[8; 9) ")" 14 | WHITESPACE@[9; 10) " " 15 | BLOCK_EXPR@[10; 16) 16 | BLOCK@[10; 16) 17 | L_CURLY@[10; 11) "{" 18 | EXPR_STMT@[11; 14) 19 | CALL_EXPR@[11; 14) 20 | IDENT_EXPR@[11; 12) 21 | NAME@[11; 12) 22 | IDENT@[11; 12) "a" 23 | ARG_LIST@[12; 14) 24 | L_PAREN@[12; 13) "(" 25 | R_PAREN@[13; 14) ")" 26 | SEMI@[14; 15) ";" 27 | R_CURLY@[15; 16) "}" 28 | 29 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/snapshots/parser__parser__expressions__call_expr__tests__parse_call_trailing_comma.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/expressions/call_expr.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 20) 6 | FN_DEF@[0; 20) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 9) 12 | L_PAREN@[7; 8) "(" 13 | R_PAREN@[8; 9) ")" 14 | WHITESPACE@[9; 10) " " 15 | BLOCK_EXPR@[10; 20) 16 | BLOCK@[10; 20) 17 | L_CURLY@[10; 11) "{" 18 | EXPR_STMT@[11; 18) 19 | CALL_EXPR@[11; 18) 20 | IDENT_EXPR@[11; 12) 21 | NAME@[11; 12) 22 | IDENT@[11; 12) "a" 23 | ARG_LIST@[12; 18) 24 | L_PAREN@[12; 13) "(" 25 | IDENT_EXPR@[13; 14) 26 | NAME@[13; 14) 27 | IDENT@[13; 14) "a" 28 | COMMA@[14; 15) "," 29 | IDENT_EXPR@[15; 16) 30 | NAME@[15; 16) 31 | IDENT@[15; 16) "b" 32 | COMMA@[16; 17) "," 33 | R_PAREN@[17; 18) ")" 34 | SEMI@[18; 19) ";" 35 | R_CURLY@[19; 20) "}" 36 | 37 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/snapshots/parser__parser__expressions__call_expr__tests__parse_simple_call_expr.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/expressions/call_expr.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 19) 6 | FN_DEF@[0; 19) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 9) 12 | L_PAREN@[7; 8) "(" 13 | R_PAREN@[8; 9) ")" 14 | WHITESPACE@[9; 10) " " 15 | BLOCK_EXPR@[10; 19) 16 | BLOCK@[10; 19) 17 | L_CURLY@[10; 11) "{" 18 | EXPR_STMT@[11; 17) 19 | CALL_EXPR@[11; 17) 20 | IDENT_EXPR@[11; 12) 21 | NAME@[11; 12) 22 | IDENT@[11; 12) "a" 23 | ARG_LIST@[12; 17) 24 | L_PAREN@[12; 13) "(" 25 | LITERAL@[13; 14) 26 | INT_NUMBER@[13; 14) "1" 27 | COMMA@[14; 15) "," 28 | LITERAL@[15; 16) 29 | INT_NUMBER@[15; 16) "2" 30 | R_PAREN@[16; 17) ")" 31 | SEMI@[17; 18) ";" 32 | R_CURLY@[18; 19) "}" 33 | 34 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/snapshots/parser__parser__expressions__closure_expr__tests__parse_empty_closure_expr.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/expressions/closure_expr.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 40) 6 | FN_DEF@[0; 40) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 9) 12 | L_PAREN@[7; 8) "(" 13 | R_PAREN@[8; 9) ")" 14 | WHITESPACE@[9; 10) " " 15 | BLOCK_EXPR@[10; 40) 16 | BLOCK@[10; 40) 17 | L_CURLY@[10; 11) "{" 18 | WHITESPACE@[11; 20) "\n " 19 | LET_STMT@[20; 33) 20 | LET_KW@[20; 23) "let" 21 | WHITESPACE@[23; 24) " " 22 | BIND_PAT@[24; 25) 23 | NAME@[24; 25) 24 | IDENT@[24; 25) "a" 25 | WHITESPACE@[25; 26) " " 26 | EQ@[26; 27) "=" 27 | WHITESPACE@[27; 28) " " 28 | CLOSURE_EXPR@[28; 33) 29 | PARAM_LIST@[28; 30) 30 | PIPE@[28; 29) "|" 31 | PIPE@[29; 30) "|" 32 | WHITESPACE@[30; 31) " " 33 | BLOCK_EXPR@[31; 33) 34 | BLOCK@[31; 33) 35 | L_CURLY@[31; 32) "{" 36 | R_CURLY@[32; 33) "}" 37 | SEMI@[33; 34) ";" 38 | WHITESPACE@[34; 39) "\n " 39 | R_CURLY@[39; 40) "}" 40 | 41 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/snapshots/parser__parser__expressions__closure_expr__tests__parse_free_closure_expr.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/expressions/closure_expr.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 32) 6 | FN_DEF@[0; 32) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 9) 12 | L_PAREN@[7; 8) "(" 13 | R_PAREN@[8; 9) ")" 14 | WHITESPACE@[9; 10) " " 15 | BLOCK_EXPR@[10; 32) 16 | BLOCK@[10; 32) 17 | L_CURLY@[10; 11) "{" 18 | WHITESPACE@[11; 20) "\n " 19 | EXPR_STMT@[20; 25) 20 | CLOSURE_EXPR@[20; 25) 21 | PARAM_LIST@[20; 22) 22 | PIPE@[20; 21) "|" 23 | PIPE@[21; 22) "|" 24 | WHITESPACE@[22; 23) " " 25 | BLOCK_EXPR@[23; 25) 26 | BLOCK@[23; 25) 27 | L_CURLY@[23; 24) "{" 28 | R_CURLY@[24; 25) "}" 29 | SEMI@[25; 26) ";" 30 | WHITESPACE@[26; 31) "\n " 31 | R_CURLY@[31; 32) "}" 32 | 33 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/snapshots/parser__parser__expressions__continue_expr__tests__parse_continue_expr.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/expressions/continue_expr.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 21) 6 | FN_DEF@[0; 21) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 9) 12 | L_PAREN@[7; 8) "(" 13 | R_PAREN@[8; 9) ")" 14 | WHITESPACE@[9; 10) " " 15 | BLOCK_EXPR@[10; 21) 16 | BLOCK@[10; 21) 17 | L_CURLY@[10; 11) "{" 18 | EXPR_STMT@[11; 19) 19 | CONTINUE_EXPR@[11; 19) 20 | CONTINUE_KW@[11; 19) "continue" 21 | SEMI@[19; 20) ";" 22 | R_CURLY@[20; 21) "}" 23 | 24 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/snapshots/parser__parser__expressions__field_expr__tests__parse_field_access.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/expressions/field_expr.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 15) 6 | FN_DEF@[0; 15) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 9) 12 | L_PAREN@[7; 8) "(" 13 | R_PAREN@[8; 9) ")" 14 | BLOCK_EXPR@[9; 15) 15 | BLOCK@[9; 15) 16 | L_CURLY@[9; 10) "{" 17 | EXPR_STMT@[10; 13) 18 | FIELD_EXPR@[10; 13) 19 | IDENT_EXPR@[10; 11) 20 | NAME@[10; 11) 21 | IDENT@[10; 11) "a" 22 | DOT@[11; 12) "." 23 | IDENT_EXPR@[12; 13) 24 | NAME@[12; 13) 25 | IDENT@[12; 13) "b" 26 | SEMI@[13; 14) ";" 27 | R_CURLY@[14; 15) "}" 28 | 29 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/snapshots/parser__parser__expressions__field_expr__tests__parse_field_access_assign.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/expressions/field_expr.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 20) 6 | FN_DEF@[0; 20) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 9) 12 | L_PAREN@[7; 8) "(" 13 | R_PAREN@[8; 9) ")" 14 | BLOCK_EXPR@[9; 20) 15 | BLOCK@[9; 20) 16 | L_CURLY@[9; 10) "{" 17 | EXPR_STMT@[10; 18) 18 | BIN_EXPR@[10; 18) 19 | FIELD_EXPR@[10; 14) 20 | IDENT_EXPR@[10; 11) 21 | NAME@[10; 11) 22 | IDENT@[10; 11) "a" 23 | DOT@[11; 12) "." 24 | IDENT_EXPR@[12; 14) 25 | NAME@[12; 14) 26 | IDENT@[12; 13) "b" 27 | WHITESPACE@[13; 14) " " 28 | EQ@[14; 15) "=" 29 | WHITESPACE@[15; 16) " " 30 | LITERAL@[16; 18) 31 | INT_NUMBER@[16; 18) "10" 32 | SEMI@[18; 19) ";" 33 | R_CURLY@[19; 20) "}" 34 | 35 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/snapshots/parser__parser__expressions__field_expr__tests__parse_field_access_chain.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/expressions/field_expr.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 23) 6 | FN_DEF@[0; 23) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 9) 12 | L_PAREN@[7; 8) "(" 13 | R_PAREN@[8; 9) ")" 14 | BLOCK_EXPR@[9; 23) 15 | BLOCK@[9; 23) 16 | L_CURLY@[9; 10) "{" 17 | EXPR_STMT@[10; 21) 18 | FIELD_EXPR@[10; 21) 19 | IDENT_EXPR@[10; 11) 20 | NAME@[10; 11) 21 | IDENT@[10; 11) "a" 22 | DOT@[11; 12) "." 23 | FIELD_EXPR@[12; 21) 24 | IDENT_EXPR@[12; 13) 25 | NAME@[12; 13) 26 | IDENT@[12; 13) "b" 27 | DOT@[13; 14) "." 28 | FIELD_EXPR@[14; 21) 29 | IDENT_EXPR@[14; 15) 30 | NAME@[14; 15) 31 | IDENT@[14; 15) "c" 32 | DOT@[15; 16) "." 33 | FIELD_EXPR@[16; 21) 34 | IDENT_EXPR@[16; 17) 35 | NAME@[16; 17) 36 | IDENT@[16; 17) "d" 37 | DOT@[17; 18) "." 38 | FIELD_EXPR@[18; 21) 39 | IDENT_EXPR@[18; 19) 40 | NAME@[18; 19) 41 | IDENT@[18; 19) "e" 42 | DOT@[19; 20) "." 43 | IDENT_EXPR@[20; 21) 44 | NAME@[20; 21) 45 | IDENT@[20; 21) "f" 46 | SEMI@[21; 22) ";" 47 | R_CURLY@[22; 23) "}" 48 | 49 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/snapshots/parser__parser__expressions__field_expr__tests__parse_field_access_method.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/expressions/field_expr.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 17) 6 | FN_DEF@[0; 17) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 9) 12 | L_PAREN@[7; 8) "(" 13 | R_PAREN@[8; 9) ")" 14 | BLOCK_EXPR@[9; 17) 15 | BLOCK@[9; 17) 16 | L_CURLY@[9; 10) "{" 17 | EXPR_STMT@[10; 15) 18 | FIELD_EXPR@[10; 15) 19 | IDENT_EXPR@[10; 11) 20 | NAME@[10; 11) 21 | IDENT@[10; 11) "a" 22 | DOT@[11; 12) "." 23 | CALL_EXPR@[12; 15) 24 | IDENT_EXPR@[12; 13) 25 | NAME@[12; 13) 26 | IDENT@[12; 13) "b" 27 | ARG_LIST@[13; 15) 28 | L_PAREN@[13; 14) "(" 29 | R_PAREN@[14; 15) ")" 30 | SEMI@[15; 16) ";" 31 | R_CURLY@[16; 17) "}" 32 | 33 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/snapshots/parser__parser__expressions__field_expr__tests__parse_field_access_method_chain.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/expressions/field_expr.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 23) 6 | FN_DEF@[0; 23) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 9) 12 | L_PAREN@[7; 8) "(" 13 | R_PAREN@[8; 9) ")" 14 | BLOCK_EXPR@[9; 23) 15 | BLOCK@[9; 23) 16 | L_CURLY@[9; 10) "{" 17 | EXPR_STMT@[10; 21) 18 | FIELD_EXPR@[10; 21) 19 | IDENT_EXPR@[10; 11) 20 | NAME@[10; 11) 21 | IDENT@[10; 11) "a" 22 | DOT@[11; 12) "." 23 | FIELD_EXPR@[12; 21) 24 | IDENT_EXPR@[12; 13) 25 | NAME@[12; 13) 26 | IDENT@[12; 13) "b" 27 | DOT@[13; 14) "." 28 | FIELD_EXPR@[14; 21) 29 | IDENT_EXPR@[14; 15) 30 | NAME@[14; 15) 31 | IDENT@[14; 15) "c" 32 | DOT@[15; 16) "." 33 | FIELD_EXPR@[16; 21) 34 | IDENT_EXPR@[16; 17) 35 | NAME@[16; 17) 36 | IDENT@[16; 17) "d" 37 | DOT@[17; 18) "." 38 | CALL_EXPR@[18; 21) 39 | IDENT_EXPR@[18; 19) 40 | NAME@[18; 19) 41 | IDENT@[18; 19) "e" 42 | ARG_LIST@[19; 21) 43 | L_PAREN@[19; 20) "(" 44 | R_PAREN@[20; 21) ")" 45 | SEMI@[21; 22) ";" 46 | R_CURLY@[22; 23) "}" 47 | 48 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/snapshots/parser__parser__expressions__for_expr__tests__parse_empty_for_expr.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/expressions/for_expr.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 23) 6 | FN_DEF@[0; 23) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 9) 12 | L_PAREN@[7; 8) "(" 13 | R_PAREN@[8; 9) ")" 14 | WHITESPACE@[9; 10) " " 15 | BLOCK_EXPR@[10; 23) 16 | BLOCK@[10; 23) 17 | L_CURLY@[10; 11) "{" 18 | EXPR_STMT@[11; 22) 19 | FOR_EXPR@[11; 22) 20 | FOR_KW@[11; 14) "for" 21 | L_PAREN@[14; 15) "(" 22 | SEMI@[15; 16) ";" 23 | SEMI@[16; 17) ";" 24 | SEMI@[17; 18) ";" 25 | R_PAREN@[18; 19) ")" 26 | WHITESPACE@[19; 20) " " 27 | BLOCK_EXPR@[20; 22) 28 | BLOCK@[20; 22) 29 | L_CURLY@[20; 21) "{" 30 | R_CURLY@[21; 22) "}" 31 | R_CURLY@[22; 23) "}" 32 | 33 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/snapshots/parser__parser__expressions__for_expr__tests__parse_for_no_cond.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/expressions/for_expr.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 37) 6 | FN_DEF@[0; 37) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 9) 12 | L_PAREN@[7; 8) "(" 13 | R_PAREN@[8; 9) ")" 14 | WHITESPACE@[9; 10) " " 15 | BLOCK_EXPR@[10; 37) 16 | BLOCK@[10; 37) 17 | L_CURLY@[10; 11) "{" 18 | WHITESPACE@[11; 12) " " 19 | EXPR_STMT@[12; 35) 20 | FOR_EXPR@[12; 35) 21 | FOR_KW@[12; 15) "for" 22 | WHITESPACE@[15; 16) " " 23 | L_PAREN@[16; 17) "(" 24 | LET_STMT@[17; 25) 25 | LET_KW@[17; 20) "let" 26 | WHITESPACE@[20; 21) " " 27 | BIND_PAT@[21; 22) 28 | NAME@[21; 22) 29 | IDENT@[21; 22) "x" 30 | EQ@[22; 23) "=" 31 | LITERAL@[23; 25) 32 | INT_NUMBER@[23; 25) "10" 33 | SEMI@[25; 26) ";" 34 | SEMI@[26; 27) ";" 35 | BIN_EXPR@[27; 32) 36 | IDENT_EXPR@[27; 28) 37 | NAME@[27; 28) 38 | IDENT@[27; 28) "x" 39 | PLUSEQ@[28; 30) "+=" 40 | LITERAL@[30; 32) 41 | INT_NUMBER@[30; 32) "10" 42 | R_PAREN@[32; 33) ")" 43 | BLOCK_EXPR@[33; 35) 44 | BLOCK@[33; 35) 45 | L_CURLY@[33; 34) "{" 46 | R_CURLY@[34; 35) "}" 47 | SEMI@[35; 36) ";" 48 | R_CURLY@[36; 37) "}" 49 | 50 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/snapshots/parser__parser__expressions__for_expr__tests__parse_for_no_incr.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/expressions/for_expr.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 37) 6 | FN_DEF@[0; 37) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 9) 12 | L_PAREN@[7; 8) "(" 13 | R_PAREN@[8; 9) ")" 14 | WHITESPACE@[9; 10) " " 15 | BLOCK_EXPR@[10; 37) 16 | BLOCK@[10; 37) 17 | L_CURLY@[10; 11) "{" 18 | WHITESPACE@[11; 12) " " 19 | EXPR_STMT@[12; 35) 20 | FOR_EXPR@[12; 35) 21 | FOR_KW@[12; 15) "for" 22 | WHITESPACE@[15; 16) " " 23 | L_PAREN@[16; 17) "(" 24 | LET_STMT@[17; 25) 25 | LET_KW@[17; 20) "let" 26 | WHITESPACE@[20; 21) " " 27 | BIND_PAT@[21; 22) 28 | NAME@[21; 22) 29 | IDENT@[21; 22) "x" 30 | EQ@[22; 23) "=" 31 | LITERAL@[23; 25) 32 | INT_NUMBER@[23; 25) "10" 33 | SEMI@[25; 26) ";" 34 | BIN_EXPR@[26; 30) 35 | IDENT_EXPR@[26; 27) 36 | NAME@[26; 27) 37 | IDENT@[26; 27) "x" 38 | L_ANGLE@[27; 28) "<" 39 | LITERAL@[28; 30) 40 | INT_NUMBER@[28; 30) "10" 41 | SEMI@[30; 31) ";" 42 | SEMI@[31; 32) ";" 43 | R_PAREN@[32; 33) ")" 44 | BLOCK_EXPR@[33; 35) 45 | BLOCK@[33; 35) 46 | L_CURLY@[33; 34) "{" 47 | R_CURLY@[34; 35) "}" 48 | SEMI@[35; 36) ";" 49 | R_CURLY@[36; 37) "}" 50 | 51 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/snapshots/parser__parser__expressions__for_expr__tests__parse_for_no_init.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/expressions/for_expr.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 33) 6 | FN_DEF@[0; 33) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 9) 12 | L_PAREN@[7; 8) "(" 13 | R_PAREN@[8; 9) ")" 14 | WHITESPACE@[9; 10) " " 15 | BLOCK_EXPR@[10; 33) 16 | BLOCK@[10; 33) 17 | L_CURLY@[10; 11) "{" 18 | WHITESPACE@[11; 12) " " 19 | EXPR_STMT@[12; 31) 20 | FOR_EXPR@[12; 31) 21 | FOR_KW@[12; 15) "for" 22 | WHITESPACE@[15; 16) " " 23 | L_PAREN@[16; 17) "(" 24 | SEMI@[17; 18) ";" 25 | BIN_EXPR@[18; 22) 26 | IDENT_EXPR@[18; 19) 27 | NAME@[18; 19) 28 | IDENT@[18; 19) "x" 29 | L_ANGLE@[19; 20) "<" 30 | LITERAL@[20; 22) 31 | INT_NUMBER@[20; 22) "10" 32 | SEMI@[22; 23) ";" 33 | BIN_EXPR@[23; 28) 34 | IDENT_EXPR@[23; 24) 35 | NAME@[23; 24) 36 | IDENT@[23; 24) "x" 37 | PLUSEQ@[24; 26) "+=" 38 | LITERAL@[26; 28) 39 | INT_NUMBER@[26; 28) "10" 40 | R_PAREN@[28; 29) ")" 41 | BLOCK_EXPR@[29; 31) 42 | BLOCK@[29; 31) 43 | L_CURLY@[29; 30) "{" 44 | R_CURLY@[30; 31) "}" 45 | SEMI@[31; 32) ";" 46 | R_CURLY@[32; 33) "}" 47 | 48 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/snapshots/parser__parser__expressions__grouping__tests__parse_grouping_expr.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/expressions/grouping.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 21) 6 | FN_DEF@[0; 21) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 9) 12 | L_PAREN@[7; 8) "(" 13 | R_PAREN@[8; 9) ")" 14 | WHITESPACE@[9; 10) " " 15 | BLOCK_EXPR@[10; 21) 16 | BLOCK@[10; 21) 17 | L_CURLY@[10; 11) "{" 18 | EXPR_STMT@[11; 19) 19 | PAREN_EXPR@[11; 19) 20 | L_PAREN@[11; 12) "(" 21 | BIN_EXPR@[12; 18) 22 | BIN_EXPR@[12; 16) 23 | LITERAL@[12; 13) 24 | INT_NUMBER@[12; 13) "1" 25 | PLUS@[13; 14) "+" 26 | LITERAL@[14; 16) 27 | INT_NUMBER@[14; 16) "10" 28 | MINUS@[16; 17) "-" 29 | LITERAL@[17; 18) 30 | INT_NUMBER@[17; 18) "1" 31 | R_PAREN@[18; 19) ")" 32 | SEMI@[19; 20) ";" 33 | R_CURLY@[20; 21) "}" 34 | 35 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/snapshots/parser__parser__expressions__grouping__tests__parse_tuple_expr.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/expressions/grouping.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 22) 6 | FN_DEF@[0; 22) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 9) 12 | L_PAREN@[7; 8) "(" 13 | R_PAREN@[8; 9) ")" 14 | WHITESPACE@[9; 10) " " 15 | BLOCK_EXPR@[10; 22) 16 | BLOCK@[10; 22) 17 | L_CURLY@[10; 11) "{" 18 | EXPR_STMT@[11; 20) 19 | TUPLE_EXPR@[11; 20) 20 | L_PAREN@[11; 12) "(" 21 | LITERAL@[12; 13) 22 | INT_NUMBER@[12; 13) "1" 23 | COMMA@[13; 14) "," 24 | LITERAL@[14; 15) 25 | INT_NUMBER@[14; 15) "2" 26 | COMMA@[15; 16) "," 27 | LITERAL@[16; 17) 28 | INT_NUMBER@[16; 17) "3" 29 | COMMA@[17; 18) "," 30 | LITERAL@[18; 19) 31 | INT_NUMBER@[18; 19) "4" 32 | R_PAREN@[19; 20) ")" 33 | SEMI@[20; 21) ";" 34 | R_CURLY@[21; 22) "}" 35 | 36 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/snapshots/parser__parser__expressions__ident__tests__parse_generic_ident_expr.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/expressions/ident.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 20) 6 | FN_DEF@[0; 20) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 9) 12 | L_PAREN@[7; 8) "(" 13 | R_PAREN@[8; 9) ")" 14 | BLOCK_EXPR@[9; 20) 15 | BLOCK@[9; 20) 16 | L_CURLY@[9; 10) "{" 17 | EXPR_STMT@[10; 18) 18 | IDENT_EXPR@[10; 18) 19 | NAME@[10; 11) 20 | IDENT@[10; 11) "a" 21 | COLON_COLON@[11; 13) "::" 22 | TYPE_ARG_LIST@[13; 18) 23 | L_ANGLE@[13; 14) "<" 24 | IDENT_TYPE@[14; 17) 25 | IDENT@[14; 17) "i32" 26 | R_ANGLE@[17; 18) ">" 27 | SEMI@[18; 19) ";" 28 | R_CURLY@[19; 20) "}" 29 | 30 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/snapshots/parser__parser__expressions__ident__tests__parse_ident_expr.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/expressions/ident.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 13) 6 | FN_DEF@[0; 13) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 9) 12 | L_PAREN@[7; 8) "(" 13 | R_PAREN@[8; 9) ")" 14 | BLOCK_EXPR@[9; 13) 15 | BLOCK@[9; 13) 16 | L_CURLY@[9; 10) "{" 17 | EXPR_STMT@[10; 11) 18 | IDENT_EXPR@[10; 11) 19 | NAME@[10; 11) 20 | IDENT@[10; 11) "a" 21 | SEMI@[11; 12) ";" 22 | R_CURLY@[12; 13) "}" 23 | 24 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/snapshots/parser__parser__expressions__if_expr__tests__parse_empty_if.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/expressions/if_expr.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 23) 6 | FN_DEF@[0; 23) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 9) 12 | L_PAREN@[7; 8) "(" 13 | R_PAREN@[8; 9) ")" 14 | WHITESPACE@[9; 10) " " 15 | BLOCK_EXPR@[10; 23) 16 | BLOCK@[10; 23) 17 | L_CURLY@[10; 11) "{" 18 | WHITESPACE@[11; 12) " " 19 | EXPR_STMT@[12; 22) 20 | IF_EXPR@[12; 22) 21 | IF_KW@[12; 14) "if" 22 | WHITESPACE@[14; 15) " " 23 | CONDITION@[15; 20) 24 | LITERAL@[15; 19) 25 | TRUE_KW@[15; 19) "true" 26 | WHITESPACE@[19; 20) " " 27 | BLOCK_EXPR@[20; 22) 28 | BLOCK@[20; 22) 29 | L_CURLY@[20; 21) "{" 30 | R_CURLY@[21; 22) "}" 31 | R_CURLY@[22; 23) "}" 32 | 33 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/snapshots/parser__parser__expressions__if_expr__tests__parse_if_and_else.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/expressions/if_expr.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 31) 6 | FN_DEF@[0; 31) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 9) 12 | L_PAREN@[7; 8) "(" 13 | R_PAREN@[8; 9) ")" 14 | WHITESPACE@[9; 10) " " 15 | BLOCK_EXPR@[10; 31) 16 | BLOCK@[10; 31) 17 | L_CURLY@[10; 11) "{" 18 | WHITESPACE@[11; 12) " " 19 | EXPR_STMT@[12; 30) 20 | IF_EXPR@[12; 30) 21 | IF_KW@[12; 14) "if" 22 | WHITESPACE@[14; 15) " " 23 | CONDITION@[15; 20) 24 | LITERAL@[15; 19) 25 | TRUE_KW@[15; 19) "true" 26 | WHITESPACE@[19; 20) " " 27 | BLOCK_EXPR@[20; 22) 28 | BLOCK@[20; 22) 29 | L_CURLY@[20; 21) "{" 30 | R_CURLY@[21; 22) "}" 31 | WHITESPACE@[22; 23) " " 32 | ELSE_KW@[23; 27) "else" 33 | WHITESPACE@[27; 28) " " 34 | BLOCK_EXPR@[28; 30) 35 | BLOCK@[28; 30) 36 | L_CURLY@[28; 29) "{" 37 | R_CURLY@[29; 30) "}" 38 | R_CURLY@[30; 31) "}" 39 | 40 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/snapshots/parser__parser__expressions__index_expr__tests__parse_nested_index_expr.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/expressions/index_expr.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 20) 6 | FN_DEF@[0; 20) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 9) 12 | L_PAREN@[7; 8) "(" 13 | R_PAREN@[8; 9) ")" 14 | WHITESPACE@[9; 10) " " 15 | BLOCK_EXPR@[10; 20) 16 | BLOCK@[10; 20) 17 | L_CURLY@[10; 11) "{" 18 | EXPR_STMT@[11; 18) 19 | INDEX_EXPR@[11; 18) 20 | INDEX_EXPR@[11; 15) 21 | IDENT_EXPR@[11; 12) 22 | NAME@[11; 12) 23 | IDENT@[11; 12) "a" 24 | L_BRACK@[12; 13) "[" 25 | LITERAL@[13; 14) 26 | INT_NUMBER@[13; 14) "0" 27 | R_BRACK@[14; 15) "]" 28 | L_BRACK@[15; 16) "[" 29 | LITERAL@[16; 17) 30 | INT_NUMBER@[16; 17) "1" 31 | R_BRACK@[17; 18) "]" 32 | SEMI@[18; 19) ";" 33 | R_CURLY@[19; 20) "}" 34 | 35 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/snapshots/parser__parser__expressions__index_expr__tests__parse_simple_index_expr.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/expressions/index_expr.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 19) 6 | FN_DEF@[0; 19) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 9) 12 | L_PAREN@[7; 8) "(" 13 | R_PAREN@[8; 9) ")" 14 | WHITESPACE@[9; 10) " " 15 | BLOCK_EXPR@[10; 19) 16 | BLOCK@[10; 19) 17 | L_CURLY@[10; 11) "{" 18 | EXPR_STMT@[11; 17) 19 | INDEX_EXPR@[11; 17) 20 | IDENT_EXPR@[11; 12) 21 | NAME@[11; 12) 22 | IDENT@[11; 12) "a" 23 | L_BRACK@[12; 13) "[" 24 | BIN_EXPR@[13; 16) 25 | LITERAL@[13; 14) 26 | INT_NUMBER@[13; 14) "1" 27 | PLUS@[14; 15) "+" 28 | LITERAL@[15; 16) 29 | INT_NUMBER@[15; 16) "2" 30 | R_BRACK@[16; 17) "]" 31 | SEMI@[17; 18) ";" 32 | R_CURLY@[18; 19) "}" 33 | 34 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/snapshots/parser__parser__expressions__let_expr__tests__parse_empty_let_expr.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/expressions/let_expr.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 20) 6 | FN_DEF@[0; 20) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 9) 12 | L_PAREN@[7; 8) "(" 13 | R_PAREN@[8; 9) ")" 14 | WHITESPACE@[9; 10) " " 15 | BLOCK_EXPR@[10; 20) 16 | BLOCK@[10; 20) 17 | L_CURLY@[10; 11) "{" 18 | LET_STMT@[11; 18) 19 | LET_KW@[11; 14) "let" 20 | WHITESPACE@[14; 15) " " 21 | BIND_PAT@[15; 18) 22 | NAME@[15; 18) 23 | IDENT@[15; 18) "foo" 24 | SEMI@[18; 19) ";" 25 | R_CURLY@[19; 20) "}" 26 | 27 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/snapshots/parser__parser__expressions__let_expr__tests__parse_let_expr.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/expressions/let_expr.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 39) 6 | FN_DEF@[0; 39) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 9) 12 | L_PAREN@[7; 8) "(" 13 | R_PAREN@[8; 9) ")" 14 | WHITESPACE@[9; 10) " " 15 | BLOCK_EXPR@[10; 39) 16 | BLOCK@[10; 39) 17 | L_CURLY@[10; 11) "{" 18 | LET_STMT@[11; 23) 19 | LET_KW@[11; 14) "let" 20 | WHITESPACE@[14; 15) " " 21 | BIND_PAT@[15; 18) 22 | NAME@[15; 18) 23 | IDENT@[15; 18) "foo" 24 | WHITESPACE@[18; 19) " " 25 | EQ@[19; 20) "=" 26 | WHITESPACE@[20; 21) " " 27 | LITERAL@[21; 23) 28 | INT_NUMBER@[21; 23) "10" 29 | SEMI@[23; 24) ";" 30 | WHITESPACE@[24; 25) " " 31 | LET_STMT@[25; 38) 32 | LET_KW@[25; 28) "let" 33 | WHITESPACE@[28; 29) " " 34 | BIND_PAT@[29; 32) 35 | NAME@[29; 32) 36 | IDENT@[29; 32) "bar" 37 | WHITESPACE@[32; 33) " " 38 | EQ@[33; 34) "=" 39 | WHITESPACE@[34; 35) " " 40 | LITERAL@[35; 38) 41 | STRING@[35; 38) "\"a\"" 42 | R_CURLY@[38; 39) "}" 43 | 44 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/snapshots/parser__parser__expressions__let_expr__tests__parse_let_patter_expr.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/expressions/let_expr.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 34) 6 | FN_DEF@[0; 34) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 9) 12 | L_PAREN@[7; 8) "(" 13 | R_PAREN@[8; 9) ")" 14 | WHITESPACE@[9; 10) " " 15 | BLOCK_EXPR@[10; 34) 16 | BLOCK@[10; 34) 17 | L_CURLY@[10; 11) "{" 18 | LET_STMT@[11; 20) 19 | LET_KW@[11; 14) "let" 20 | WHITESPACE@[14; 15) " " 21 | TUPLE_PAT@[15; 20) 22 | L_PAREN@[15; 16) "(" 23 | BIND_PAT@[16; 17) 24 | NAME@[16; 17) 25 | IDENT@[16; 17) "a" 26 | COMMA@[17; 18) "," 27 | BIND_PAT@[18; 19) 28 | NAME@[18; 19) 29 | IDENT@[18; 19) "b" 30 | R_PAREN@[19; 20) ")" 31 | SEMI@[20; 21) ";" 32 | WHITESPACE@[21; 22) " " 33 | LET_STMT@[22; 32) 34 | LET_KW@[22; 25) "let" 35 | WHITESPACE@[25; 26) " " 36 | PLACEHOLDER_PAT@[26; 27) 37 | UNDERSCORE@[26; 27) "_" 38 | WHITESPACE@[27; 28) " " 39 | EQ@[28; 29) "=" 40 | WHITESPACE@[29; 30) " " 41 | LITERAL@[30; 32) 42 | INT_NUMBER@[30; 32) "10" 43 | SEMI@[32; 33) ";" 44 | R_CURLY@[33; 34) "}" 45 | 46 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/snapshots/parser__parser__expressions__let_expr__tests__parse_let_type_expr.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/expressions/let_expr.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 44) 6 | FN_DEF@[0; 44) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 9) 12 | L_PAREN@[7; 8) "(" 13 | R_PAREN@[8; 9) ")" 14 | WHITESPACE@[9; 10) " " 15 | BLOCK_EXPR@[10; 44) 16 | BLOCK@[10; 44) 17 | L_CURLY@[10; 11) "{" 18 | LET_STMT@[11; 22) 19 | LET_KW@[11; 14) "let" 20 | WHITESPACE@[14; 15) " " 21 | BIND_PAT@[15; 18) 22 | NAME@[15; 18) 23 | IDENT@[15; 18) "foo" 24 | COLON@[18; 19) ":" 25 | IDENT_TYPE@[19; 22) 26 | IDENT@[19; 22) "i32" 27 | SEMI@[22; 23) ";" 28 | WHITESPACE@[23; 24) " " 29 | LET_STMT@[24; 42) 30 | LET_KW@[24; 27) "let" 31 | WHITESPACE@[27; 28) " " 32 | BIND_PAT@[28; 31) 33 | NAME@[28; 31) 34 | IDENT@[28; 31) "bar" 35 | COLON@[31; 32) ":" 36 | WHITESPACE@[32; 33) " " 37 | PAREN_TYPE@[33; 42) 38 | L_PAREN@[33; 34) "(" 39 | IDENT_TYPE@[34; 37) 40 | IDENT@[34; 37) "i32" 41 | COMMA@[37; 38) "," 42 | IDENT_TYPE@[38; 41) 43 | IDENT@[38; 41) "i32" 44 | R_PAREN@[41; 42) ")" 45 | SEMI@[42; 43) ";" 46 | R_CURLY@[43; 44) "}" 47 | 48 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/snapshots/parser__parser__expressions__literal__tests__parse_bool_literal.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/expressions/literal.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 23) 6 | FN_DEF@[0; 23) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 9) 12 | L_PAREN@[7; 8) "(" 13 | R_PAREN@[8; 9) ")" 14 | WHITESPACE@[9; 10) " " 15 | BLOCK_EXPR@[10; 23) 16 | BLOCK@[10; 23) 17 | L_CURLY@[10; 11) "{" 18 | EXPR_STMT@[11; 15) 19 | LITERAL@[11; 15) 20 | TRUE_KW@[11; 15) "true" 21 | SEMI@[15; 16) ";" 22 | EXPR_STMT@[16; 21) 23 | LITERAL@[16; 21) 24 | FALSE_KW@[16; 21) "false" 25 | SEMI@[21; 22) ";" 26 | R_CURLY@[22; 23) "}" 27 | 28 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/snapshots/parser__parser__expressions__literal__tests__parse_float_literal.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/expressions/literal.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 16) 6 | FN_DEF@[0; 16) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 9) 12 | L_PAREN@[7; 8) "(" 13 | R_PAREN@[8; 9) ")" 14 | WHITESPACE@[9; 10) " " 15 | BLOCK_EXPR@[10; 16) 16 | BLOCK@[10; 16) 17 | L_CURLY@[10; 11) "{" 18 | EXPR_STMT@[11; 14) 19 | LITERAL@[11; 14) 20 | FLOAT_NUMBER@[11; 14) "1.0" 21 | SEMI@[14; 15) ";" 22 | R_CURLY@[15; 16) "}" 23 | 24 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/snapshots/parser__parser__expressions__literal__tests__parse_int_literal.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/expressions/literal.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 14) 6 | FN_DEF@[0; 14) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 9) 12 | L_PAREN@[7; 8) "(" 13 | R_PAREN@[8; 9) ")" 14 | WHITESPACE@[9; 10) " " 15 | BLOCK_EXPR@[10; 14) 16 | BLOCK@[10; 14) 17 | L_CURLY@[10; 11) "{" 18 | EXPR_STMT@[11; 12) 19 | LITERAL@[11; 12) 20 | INT_NUMBER@[11; 12) "1" 21 | SEMI@[12; 13) ";" 22 | R_CURLY@[13; 14) "}" 23 | 24 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/snapshots/parser__parser__expressions__literal__tests__parse_nil_literal.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/expressions/literal.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 16) 6 | FN_DEF@[0; 15) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 9) 12 | L_PAREN@[7; 8) "(" 13 | R_PAREN@[8; 9) ")" 14 | WHITESPACE@[9; 10) " " 15 | BLOCK_EXPR@[10; 15) 16 | BLOCK@[10; 15) 17 | L_CURLY@[10; 11) "{" 18 | EXPR_STMT@[11; 14) 19 | LITERAL@[11; 14) 20 | NIL_KW@[11; 14) "nil" 21 | R_CURLY@[14; 15) "}" 22 | SEMI@[15; 16) ";" 23 | 24 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/snapshots/parser__parser__expressions__literal__tests__parse_string_literal.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/expressions/literal.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 18) 6 | FN_DEF@[0; 18) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 9) 12 | L_PAREN@[7; 8) "(" 13 | R_PAREN@[8; 9) ")" 14 | WHITESPACE@[9; 10) " " 15 | BLOCK_EXPR@[10; 18) 16 | BLOCK@[10; 18) 17 | L_CURLY@[10; 11) "{" 18 | EXPR_STMT@[11; 16) 19 | LITERAL@[11; 16) 20 | STRING@[11; 16) "\"abc\"" 21 | SEMI@[16; 17) ";" 22 | R_CURLY@[17; 18) "}" 23 | 24 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/snapshots/parser__parser__expressions__match_expr__tests__parse_empty_match_expr.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/expressions/match_expr.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 24) 6 | FN_DEF@[0; 24) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 9) 12 | L_PAREN@[7; 8) "(" 13 | R_PAREN@[8; 9) ")" 14 | WHITESPACE@[9; 10) " " 15 | BLOCK_EXPR@[10; 24) 16 | BLOCK@[10; 24) 17 | L_CURLY@[10; 11) "{" 18 | WHITESPACE@[11; 12) " " 19 | EXPR_STMT@[12; 22) 20 | MATCH_EXPR@[12; 22) 21 | MATCH_KW@[12; 17) "match" 22 | WHITESPACE@[17; 18) " " 23 | IDENT_EXPR@[18; 20) 24 | NAME@[18; 20) 25 | IDENT@[18; 19) "a" 26 | WHITESPACE@[19; 20) " " 27 | L_CURLY@[20; 21) "{" 28 | MATCH_ARM_LIST@[21; 21) 29 | R_CURLY@[21; 22) "}" 30 | SEMI@[22; 23) ";" 31 | R_CURLY@[23; 24) "}" 32 | 33 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/snapshots/parser__parser__expressions__match_expr__tests__parse_match_expr.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/expressions/match_expr.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 42) 6 | FN_DEF@[0; 42) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 9) 12 | L_PAREN@[7; 8) "(" 13 | R_PAREN@[8; 9) ")" 14 | WHITESPACE@[9; 10) " " 15 | BLOCK_EXPR@[10; 42) 16 | BLOCK@[10; 42) 17 | L_CURLY@[10; 11) "{" 18 | WHITESPACE@[11; 12) " " 19 | EXPR_STMT@[12; 40) 20 | MATCH_EXPR@[12; 40) 21 | MATCH_KW@[12; 17) "match" 22 | WHITESPACE@[17; 18) " " 23 | TUPLE_EXPR@[18; 23) 24 | L_PAREN@[18; 19) "(" 25 | IDENT_EXPR@[19; 20) 26 | NAME@[19; 20) 27 | IDENT@[19; 20) "a" 28 | COMMA@[20; 21) "," 29 | IDENT_EXPR@[21; 22) 30 | NAME@[21; 22) 31 | IDENT@[21; 22) "b" 32 | R_PAREN@[22; 23) ")" 33 | WHITESPACE@[23; 24) " " 34 | L_CURLY@[24; 25) "{" 35 | WHITESPACE@[25; 26) " " 36 | MATCH_ARM_LIST@[26; 39) 37 | MATCH_ARM@[26; 33) 38 | BIND_PAT@[26; 27) 39 | NAME@[26; 27) 40 | IDENT@[26; 27) "x" 41 | WHITESPACE@[27; 28) " " 42 | FAT_ARROW@[28; 30) "=>" 43 | WHITESPACE@[30; 31) " " 44 | LITERAL@[31; 33) 45 | INT_NUMBER@[31; 33) "10" 46 | COMMA@[33; 34) "," 47 | MATCH_ARM@[34; 39) 48 | LITERAL_PAT@[34; 36) 49 | LITERAL@[34; 35) 50 | INT_NUMBER@[34; 35) "1" 51 | WHITESPACE@[35; 36) " " 52 | FAT_ARROW@[36; 38) "=>" 53 | LITERAL@[38; 39) 54 | INT_NUMBER@[38; 39) "3" 55 | R_CURLY@[39; 40) "}" 56 | SEMI@[40; 41) ";" 57 | R_CURLY@[41; 42) "}" 58 | 59 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/snapshots/parser__parser__expressions__record_expr__tests__parse_empty_record_literal.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/expressions/record_expr.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 19) 6 | FN_DEF@[0; 19) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 9) 12 | L_PAREN@[7; 8) "(" 13 | R_PAREN@[8; 9) ")" 14 | WHITESPACE@[9; 10) " " 15 | BLOCK_EXPR@[10; 19) 16 | BLOCK@[10; 19) 17 | L_CURLY@[10; 11) "{" 18 | WHITESPACE@[11; 12) " " 19 | EXPR_STMT@[12; 17) 20 | RECORD_LITERAL_EXPR@[12; 17) 21 | IDENT_EXPR@[12; 15) 22 | NAME@[12; 15) 23 | IDENT@[12; 15) "foo" 24 | NAMED_FIELD_LIST@[15; 17) 25 | L_CURLY@[15; 16) "{" 26 | R_CURLY@[16; 17) "}" 27 | SEMI@[17; 18) ";" 28 | R_CURLY@[18; 19) "}" 29 | 30 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/snapshots/parser__parser__expressions__record_expr__tests__parse_longhand_record_literal.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/expressions/record_expr.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 71) 6 | FN_DEF@[0; 71) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 9) 12 | L_PAREN@[7; 8) "(" 13 | R_PAREN@[8; 9) ")" 14 | WHITESPACE@[9; 10) " " 15 | BLOCK_EXPR@[10; 71) 16 | BLOCK@[10; 71) 17 | L_CURLY@[10; 11) "{" 18 | WHITESPACE@[11; 12) " " 19 | EXPR_STMT@[12; 69) 20 | RECORD_LITERAL_EXPR@[12; 69) 21 | IDENT_EXPR@[12; 15) 22 | NAME@[12; 15) 23 | IDENT@[12; 15) "foo" 24 | NAMED_FIELD_LIST@[15; 69) 25 | L_CURLY@[15; 16) "{" 26 | WHITESPACE@[16; 17) " " 27 | NAMED_FIELD@[17; 34) 28 | NAME@[17; 25) 29 | IDENT@[17; 25) "longhand" 30 | COLON@[25; 26) ":" 31 | IDENT_EXPR@[26; 34) 32 | NAME@[26; 34) 33 | IDENT@[26; 34) "longhand" 34 | COMMA@[34; 35) "," 35 | NAMED_FIELD@[35; 44) 36 | NAME@[35; 39) 37 | IDENT@[35; 39) "long" 38 | COLON@[39; 40) ":" 39 | IDENT_EXPR@[40; 44) 40 | NAME@[40; 44) 41 | IDENT@[40; 44) "long" 42 | COMMA@[44; 45) "," 43 | NAMED_FIELD@[45; 68) 44 | NAME@[45; 56) 45 | IDENT@[45; 56) "longymclong" 46 | COLON@[56; 57) ":" 47 | IDENT_EXPR@[57; 68) 48 | NAME@[57; 68) 49 | IDENT@[57; 68) "longymclong" 50 | R_CURLY@[68; 69) "}" 51 | SEMI@[69; 70) ";" 52 | R_CURLY@[70; 71) "}" 53 | 54 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/snapshots/parser__parser__expressions__record_expr__tests__parse_mixed_record_literal.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/expressions/record_expr.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 59) 6 | FN_DEF@[0; 59) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 9) 12 | L_PAREN@[7; 8) "(" 13 | R_PAREN@[8; 9) ")" 14 | WHITESPACE@[9; 10) " " 15 | BLOCK_EXPR@[10; 59) 16 | BLOCK@[10; 59) 17 | L_CURLY@[10; 11) "{" 18 | WHITESPACE@[11; 12) " " 19 | EXPR_STMT@[12; 57) 20 | RECORD_LITERAL_EXPR@[12; 57) 21 | IDENT_EXPR@[12; 15) 22 | NAME@[12; 15) 23 | IDENT@[12; 15) "foo" 24 | NAMED_FIELD_LIST@[15; 57) 25 | L_CURLY@[15; 16) "{" 26 | WHITESPACE@[16; 17) " " 27 | NAMED_FIELD@[17; 34) 28 | NAME@[17; 25) 29 | IDENT@[17; 25) "longhand" 30 | COLON@[25; 26) ":" 31 | IDENT_EXPR@[26; 34) 32 | NAME@[26; 34) 33 | IDENT@[26; 34) "longhand" 34 | COMMA@[34; 35) "," 35 | NAMED_FIELD@[35; 46) 36 | NAME@[35; 46) 37 | IDENT@[35; 46) "longymclong" 38 | COMMA@[46; 47) "," 39 | NAMED_FIELD@[47; 56) 40 | NAME@[47; 51) 41 | IDENT@[47; 51) "long" 42 | COLON@[51; 52) ":" 43 | IDENT_EXPR@[52; 56) 44 | NAME@[52; 56) 45 | IDENT@[52; 56) "long" 46 | R_CURLY@[56; 57) "}" 47 | SEMI@[57; 58) ";" 48 | R_CURLY@[58; 59) "}" 49 | 50 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/snapshots/parser__parser__expressions__record_expr__tests__parse_shorthand_record_literal.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/expressions/record_expr.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 49) 6 | FN_DEF@[0; 49) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 9) 12 | L_PAREN@[7; 8) "(" 13 | R_PAREN@[8; 9) ")" 14 | WHITESPACE@[9; 10) " " 15 | BLOCK_EXPR@[10; 49) 16 | BLOCK@[10; 49) 17 | L_CURLY@[10; 11) "{" 18 | WHITESPACE@[11; 12) " " 19 | EXPR_STMT@[12; 47) 20 | RECORD_LITERAL_EXPR@[12; 47) 21 | IDENT_EXPR@[12; 15) 22 | NAME@[12; 15) 23 | IDENT@[12; 15) "foo" 24 | NAMED_FIELD_LIST@[15; 47) 25 | L_CURLY@[15; 16) "{" 26 | WHITESPACE@[16; 17) " " 27 | NAMED_FIELD@[17; 26) 28 | NAME@[17; 26) 29 | IDENT@[17; 26) "shorthand" 30 | COMMA@[26; 27) "," 31 | NAMED_FIELD@[27; 32) 32 | NAME@[27; 32) 33 | IDENT@[27; 32) "short" 34 | COMMA@[32; 33) "," 35 | NAMED_FIELD@[33; 46) 36 | NAME@[33; 46) 37 | IDENT@[33; 46) "shortymcshort" 38 | R_CURLY@[46; 47) "}" 39 | SEMI@[47; 48) ";" 40 | R_CURLY@[48; 49) "}" 41 | 42 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/snapshots/parser__parser__expressions__return_expr__tests__parse_empty_return_expr.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/expressions/return_expr.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 19) 6 | FN_DEF@[0; 19) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 9) 12 | L_PAREN@[7; 8) "(" 13 | R_PAREN@[8; 9) ")" 14 | WHITESPACE@[9; 10) " " 15 | BLOCK_EXPR@[10; 19) 16 | BLOCK@[10; 19) 17 | L_CURLY@[10; 11) "{" 18 | EXPR_STMT@[11; 17) 19 | RETURN_EXPR@[11; 17) 20 | RETURN_KW@[11; 17) "return" 21 | SEMI@[17; 18) ";" 22 | R_CURLY@[18; 19) "}" 23 | 24 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/snapshots/parser__parser__expressions__return_expr__tests__parse_return_expr.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/expressions/return_expr.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 23) 6 | FN_DEF@[0; 23) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 9) 12 | L_PAREN@[7; 8) "(" 13 | R_PAREN@[8; 9) ")" 14 | WHITESPACE@[9; 10) " " 15 | BLOCK_EXPR@[10; 23) 16 | BLOCK@[10; 23) 17 | L_CURLY@[10; 11) "{" 18 | EXPR_STMT@[11; 21) 19 | RETURN_EXPR@[11; 21) 20 | RETURN_KW@[11; 17) "return" 21 | WHITESPACE@[17; 18) " " 22 | BIN_EXPR@[18; 21) 23 | LITERAL@[18; 19) 24 | INT_NUMBER@[18; 19) "1" 25 | PLUS@[19; 20) "+" 26 | LITERAL@[20; 21) 27 | INT_NUMBER@[20; 21) "1" 28 | SEMI@[21; 22) ";" 29 | R_CURLY@[22; 23) "}" 30 | 31 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/snapshots/parser__parser__expressions__unary__tests__parse_nested_unary_expr.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/expressions/unary.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 19) 6 | FN_DEF@[0; 19) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 9) 12 | L_PAREN@[7; 8) "(" 13 | R_PAREN@[8; 9) ")" 14 | WHITESPACE@[9; 10) " " 15 | BLOCK_EXPR@[10; 19) 16 | BLOCK@[10; 19) 17 | L_CURLY@[10; 11) "{" 18 | EXPR_STMT@[11; 17) 19 | PREFIX_EXPR@[11; 17) 20 | EXCL@[11; 12) "!" 21 | PREFIX_EXPR@[12; 17) 22 | EXCL@[12; 13) "!" 23 | LITERAL@[13; 17) 24 | TRUE_KW@[13; 17) "true" 25 | SEMI@[17; 18) ";" 26 | R_CURLY@[18; 19) "}" 27 | 28 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/snapshots/parser__parser__expressions__unary__tests__parse_unary_expr.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/expressions/unary.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 20) 6 | FN_DEF@[0; 20) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 9) 12 | L_PAREN@[7; 8) "(" 13 | R_PAREN@[8; 9) ")" 14 | WHITESPACE@[9; 10) " " 15 | BLOCK_EXPR@[10; 20) 16 | BLOCK@[10; 20) 17 | L_CURLY@[10; 11) "{" 18 | EXPR_STMT@[11; 16) 19 | PREFIX_EXPR@[11; 16) 20 | EXCL@[11; 12) "!" 21 | LITERAL@[12; 16) 22 | TRUE_KW@[12; 16) "true" 23 | SEMI@[16; 17) ";" 24 | EXPR_STMT@[17; 19) 25 | PREFIX_EXPR@[17; 19) 26 | MINUS@[17; 18) "-" 27 | LITERAL@[18; 19) 28 | INT_NUMBER@[18; 19) "1" 29 | R_CURLY@[19; 20) "}" 30 | 31 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/snapshots/parser__parser__expressions__while_expr__tests__parse_empty_while_expr.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/expressions/while_expr.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 24) 6 | FN_DEF@[0; 24) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 9) 12 | L_PAREN@[7; 8) "(" 13 | R_PAREN@[8; 9) ")" 14 | BLOCK_EXPR@[9; 24) 15 | BLOCK@[9; 24) 16 | L_CURLY@[9; 10) "{" 17 | EXPR_STMT@[10; 23) 18 | WHILE_EXPR@[10; 23) 19 | WHILE_KW@[10; 15) "while" 20 | WHITESPACE@[15; 16) " " 21 | CONDITION@[16; 21) 22 | LITERAL@[16; 20) 23 | TRUE_KW@[16; 20) "true" 24 | WHITESPACE@[20; 21) " " 25 | BLOCK_EXPR@[21; 23) 26 | BLOCK@[21; 23) 27 | L_CURLY@[21; 22) "{" 28 | R_CURLY@[22; 23) "}" 29 | R_CURLY@[23; 24) "}" 30 | 31 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/snapshots/parser__parser__expressions__while_expr__tests__parse_while_expr.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/expressions/while_expr.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 41) 6 | FN_DEF@[0; 41) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 9) 12 | L_PAREN@[7; 8) "(" 13 | R_PAREN@[8; 9) ")" 14 | BLOCK_EXPR@[9; 41) 15 | BLOCK@[9; 41) 16 | L_CURLY@[9; 10) "{" 17 | EXPR_STMT@[10; 40) 18 | WHILE_EXPR@[10; 40) 19 | WHILE_KW@[10; 15) "while" 20 | WHITESPACE@[15; 16) " " 21 | CONDITION@[16; 21) 22 | LITERAL@[16; 20) 23 | TRUE_KW@[16; 20) "true" 24 | WHITESPACE@[20; 21) " " 25 | BLOCK_EXPR@[21; 40) 26 | BLOCK@[21; 40) 27 | L_CURLY@[21; 22) "{" 28 | EXPR_STMT@[22; 39) 29 | CALL_EXPR@[22; 39) 30 | IDENT_EXPR@[22; 27) 31 | NAME@[22; 27) 32 | IDENT@[22; 27) "print" 33 | ARG_LIST@[27; 39) 34 | L_PAREN@[27; 28) "(" 35 | LITERAL@[28; 38) 36 | STRING@[28; 38) "\"it works\"" 37 | R_PAREN@[38; 39) ")" 38 | R_CURLY@[39; 40) "}" 39 | R_CURLY@[40; 41) "}" 40 | 41 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/unary.rs: -------------------------------------------------------------------------------- 1 | use syntax::T; 2 | 3 | use crate::parser::pratt::{Precedence, PrefixParser}; 4 | use crate::parser::{Parser, Restrictions}; 5 | 6 | use crate::SyntaxKind::*; 7 | 8 | impl<'a> Parser<'a> { 9 | pub(crate) fn parse_unary_op(&mut self) { 10 | match self.current() { 11 | T![-] | T![!] => self.bump(), 12 | _ => self.error( 13 | "Expected one of `-` | `!`", 14 | format!( 15 | "Expected one of `-` | `!` but instead found `{:?}`", 16 | self.current_string() 17 | ), 18 | ), 19 | } 20 | } 21 | } 22 | #[derive(Debug)] 23 | pub struct UnaryParselet; 24 | 25 | impl PrefixParser for UnaryParselet { 26 | fn parse(&self, parser: &mut Parser) { 27 | parser.start_node(PREFIX_EXPR); 28 | 29 | parser.parse_unary_op(); 30 | 31 | parser.parse_expression(Precedence::Unary, Restrictions::default()); 32 | 33 | parser.finish_node(); 34 | } 35 | } 36 | 37 | #[cfg(test)] 38 | mod tests { 39 | test_parser! {parse_unary_expr,"fn main() {!true;-1}"} 40 | test_parser! {parse_nested_unary_expr,"fn main() {!!true;}"} 41 | } 42 | -------------------------------------------------------------------------------- /parser/src/parser/expressions/while_expr.rs: -------------------------------------------------------------------------------- 1 | use syntax::T; 2 | 3 | use crate::parser::{Parser, Restrictions}; 4 | 5 | use crate::SyntaxKind::*; 6 | 7 | use crate::parser::Precedence; 8 | 9 | impl<'a> Parser<'a> { 10 | pub(crate) fn parse_while_expr(&mut self) { 11 | self.start_node(WHILE_EXPR); 12 | 13 | self.expect(T![while]); 14 | 15 | self.start_node(CONDITION); 16 | self.parse_expression(Precedence::Assignment, Restrictions::no_records()); 17 | self.finish_node(); 18 | 19 | self.parse_block(); 20 | 21 | self.finish_node() 22 | } 23 | } 24 | 25 | #[cfg(test)] 26 | mod tests { 27 | test_parser! {parse_empty_while_expr,"fn main(){while true {}}"} 28 | test_parser! {parse_while_expr,"fn main(){while true {print(\"it works\")}}"} 29 | } 30 | -------------------------------------------------------------------------------- /parser/src/parser/function.rs: -------------------------------------------------------------------------------- 1 | use syntax::T; 2 | 3 | use crate::parser::Parser; 4 | 5 | use crate::SyntaxKind::*; 6 | 7 | impl<'a> Parser<'a> { 8 | pub(crate) fn parse_function(&mut self, checkpoint: rowan::Checkpoint) { 9 | self.start_node_at(checkpoint, FN_DEF); 10 | 11 | self.expect(T![fn]); 12 | 13 | self.ident(); 14 | 15 | if self.current() == T![<] { 16 | self.parse_type_params(false); 17 | } 18 | 19 | if self.current() == T!["("] { 20 | self.parse_func_params(T!(")")); 21 | } 22 | 23 | if self.current() == T![->] { 24 | self.parse_return_type(); 25 | } 26 | 27 | self.parse_block(); 28 | 29 | self.finish_node() 30 | } 31 | 32 | pub(crate) fn parse_return_type(&mut self) { 33 | self.start_node(RET_TYPE); 34 | self.expect(T![->]); 35 | self.parse_type(); 36 | self.finish_node() 37 | } 38 | } 39 | 40 | #[cfg(test)] 41 | mod tests { 42 | test_parser! {parse_function,"fn main() {}"} 43 | test_parser! {parse_exported_function,"export fn main() {}"} 44 | } 45 | -------------------------------------------------------------------------------- /parser/src/parser/imports.rs: -------------------------------------------------------------------------------- 1 | use syntax::T; 2 | 3 | use crate::parser::Parser; 4 | 5 | use crate::SyntaxKind::*; 6 | 7 | impl<'a> Parser<'a> { 8 | pub(crate) fn parse_import(&mut self) { 9 | self.start_node(IMPORT_DEF); 10 | 11 | self.expect(T![import]); 12 | 13 | while !self.at(EOF) && !self.at(T![;]) { 14 | self.parse_import_segment(); 15 | 16 | if !self.at(T![;]) && !self.expected(T![::]) { 17 | break; 18 | } 19 | } 20 | 21 | self.expect(T![;]); 22 | 23 | self.finish_node(); 24 | } 25 | 26 | pub(crate) fn parse_import_segment(&mut self) { 27 | if self.at(T!["{"]) { 28 | self.start_node(IMPORT_LIST); 29 | 30 | self.bump(); 31 | 32 | while !self.at(EOF) && !self.at(T!["}"]) { 33 | self.parse_import_segment(); 34 | 35 | if !self.at(T!["}"]) && !self.expects(vec![T![,], T![::]]) { 36 | break; 37 | } 38 | } 39 | 40 | self.expect(T!["}"]); 41 | } else if !self.at(T![;]) { 42 | self.start_node(IMPORT_SEGMENT); 43 | self.ident(); 44 | } 45 | 46 | self.finish_node(); 47 | } 48 | } 49 | 50 | #[cfg(test)] 51 | mod tests { 52 | test_parser! {parse_empty_import,"import foo;"} 53 | test_parser! {parse_import_with_multiple_segments,"import foo::bar::baz;"} 54 | test_parser! {parse_import_with_brace,"import foo::{bar,baz};"} 55 | test_parser! {parse_import_with_brace_nested_segments,"import foo::{bar::baz,fubar};"} 56 | } 57 | -------------------------------------------------------------------------------- /parser/src/parser/module.rs: -------------------------------------------------------------------------------- 1 | use syntax::T; 2 | 3 | use crate::parser::Parser; 4 | 5 | use crate::SyntaxKind::*; 6 | 7 | impl<'a> Parser<'a> { 8 | pub(crate) fn parse_module(&mut self) { 9 | self.start_node(MOD_DEF); 10 | 11 | self.expect(T![mod]); 12 | 13 | self.ident(); 14 | 15 | self.expect(T![;]); 16 | 17 | self.finish_node(); 18 | } 19 | } 20 | 21 | #[cfg(test)] 22 | mod tests { 23 | test_parser! {parse_single_mod,"mod foo;"} 24 | test_parser! {parse_many_mods,"mod bar; mod foo;"} 25 | } 26 | -------------------------------------------------------------------------------- /parser/src/parser/params.rs: -------------------------------------------------------------------------------- 1 | use crate::parser::Parser; 2 | use syntax::T; 3 | 4 | use crate::SyntaxKind::{self, *}; 5 | 6 | impl<'a> Parser<'a> { 7 | pub(crate) fn parse_func_params(&mut self, flavour: SyntaxKind) { 8 | self.start_node(PARAM_LIST); 9 | 10 | // We assume that we have parsed the opening token 11 | 12 | self.bump(); 13 | 14 | while !self.at(EOF) && !self.at(flavour) { 15 | self.func_param(); 16 | 17 | if !self.at(flavour) && !self.expected(T![,]) { 18 | break; 19 | } 20 | } 21 | 22 | self.expect(flavour); 23 | 24 | self.finish_node() 25 | } 26 | 27 | pub(crate) fn func_param(&mut self) { 28 | self.start_node(PARAM); 29 | self.parse_pattern(false); 30 | 31 | if self.at(T![:]) { 32 | self.expect(T![:]); 33 | self.parse_type(); 34 | } 35 | 36 | self.finish_node(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /parser/src/parser/restrictions.rs: -------------------------------------------------------------------------------- 1 | #[derive(Debug, Default, Clone, Copy)] 2 | pub(crate) struct Restrictions { 3 | pub forbid_record: bool, 4 | } 5 | 6 | impl Restrictions { 7 | pub fn no_records() -> Self { 8 | Self { 9 | forbid_record: true, 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /parser/src/parser/snapshots/parser__parser__classes__tests__parse_class_fields.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/classes.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 44) 6 | CLASS_DEF@[0; 44) 7 | CLASS_KW@[0; 5) "class" 8 | WHITESPACE@[5; 6) " " 9 | NAME@[6; 12) 10 | IDENT@[6; 12) "Person" 11 | WHITESPACE@[12; 13) " " 12 | L_CURLY@[13; 14) "{" 13 | WHITESPACE@[14; 15) " " 14 | NAMED_FIELD_DEF@[15; 27) 15 | NAME@[15; 19) 16 | IDENT@[15; 19) "name" 17 | COLON@[19; 20) ":" 18 | IDENT_TYPE@[20; 26) 19 | IDENT@[20; 26) "String" 20 | SEMI@[26; 27) ";" 21 | WHITESPACE@[27; 28) " " 22 | NAMED_FIELD_DEF@[28; 43) 23 | NAME@[28; 35) 24 | IDENT@[28; 35) "surname" 25 | COLON@[35; 36) ":" 26 | IDENT_TYPE@[36; 42) 27 | IDENT@[36; 42) "String" 28 | SEMI@[42; 43) ";" 29 | R_CURLY@[43; 44) "}" 30 | 31 | -------------------------------------------------------------------------------- /parser/src/parser/snapshots/parser__parser__classes__tests__parse_class_fields_methods.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/classes.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 62) 6 | CLASS_DEF@[0; 62) 7 | CLASS_KW@[0; 5) "class" 8 | WHITESPACE@[5; 6) " " 9 | NAME@[6; 12) 10 | IDENT@[6; 12) "Person" 11 | WHITESPACE@[12; 13) " " 12 | L_CURLY@[13; 14) "{" 13 | WHITESPACE@[14; 15) " " 14 | NAMED_FIELD_DEF@[15; 27) 15 | NAME@[15; 19) 16 | IDENT@[15; 19) "name" 17 | COLON@[19; 20) ":" 18 | IDENT_TYPE@[20; 26) 19 | IDENT@[20; 26) "String" 20 | SEMI@[26; 27) ";" 21 | WHITESPACE@[27; 28) " " 22 | NAMED_FIELD_DEF@[28; 43) 23 | NAME@[28; 35) 24 | IDENT@[28; 35) "surname" 25 | COLON@[35; 36) ":" 26 | IDENT_TYPE@[36; 42) 27 | IDENT@[36; 42) "String" 28 | SEMI@[42; 43) ";" 29 | WHITESPACE@[43; 44) " " 30 | FN_DEF@[44; 61) 31 | FN_KW@[44; 46) "fn" 32 | WHITESPACE@[46; 47) " " 33 | NAME@[47; 52) 34 | IDENT@[47; 52) "hello" 35 | PARAM_LIST@[52; 58) 36 | L_PAREN@[52; 53) "(" 37 | PARAM@[53; 57) 38 | SELF_KW@[53; 57) "self" 39 | R_PAREN@[57; 58) ")" 40 | WHITESPACE@[58; 59) " " 41 | BLOCK_EXPR@[59; 61) 42 | BLOCK@[59; 61) 43 | L_CURLY@[59; 60) "{" 44 | R_CURLY@[60; 61) "}" 45 | R_CURLY@[61; 62) "}" 46 | 47 | -------------------------------------------------------------------------------- /parser/src/parser/snapshots/parser__parser__classes__tests__parse_class_generic.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/classes.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 20) 6 | CLASS_DEF@[0; 20) 7 | CLASS_KW@[0; 5) "class" 8 | WHITESPACE@[5; 6) " " 9 | NAME@[6; 12) 10 | IDENT@[6; 12) "Result" 11 | TYPE_PARAM_LIST@[12; 17) 12 | L_ANGLE@[12; 13) "<" 13 | TYPE_PARAM@[13; 14) 14 | NAME@[13; 14) 15 | IDENT@[13; 14) "T" 16 | COMMA@[14; 15) "," 17 | TYPE_PARAM@[15; 16) 18 | NAME@[15; 16) 19 | IDENT@[15; 16) "E" 20 | R_ANGLE@[16; 17) ">" 21 | WHITESPACE@[17; 18) " " 22 | L_CURLY@[18; 19) "{" 23 | R_CURLY@[19; 20) "}" 24 | 25 | -------------------------------------------------------------------------------- /parser/src/parser/snapshots/parser__parser__classes__tests__parse_class_methods.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/classes.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 66) 6 | CLASS_DEF@[0; 66) 7 | CLASS_KW@[0; 5) "class" 8 | WHITESPACE@[5; 6) " " 9 | NAME@[6; 12) 10 | IDENT@[6; 12) "Person" 11 | WHITESPACE@[12; 13) " " 12 | L_CURLY@[13; 14) "{" 13 | WHITESPACE@[14; 15) " " 14 | NAMED_FIELD_DEF@[15; 27) 15 | NAME@[15; 19) 16 | IDENT@[15; 19) "name" 17 | COLON@[19; 20) ":" 18 | IDENT_TYPE@[20; 26) 19 | IDENT@[20; 26) "String" 20 | SEMI@[26; 27) ";" 21 | WHITESPACE@[27; 28) " " 22 | NAMED_FIELD_DEF@[28; 43) 23 | NAME@[28; 35) 24 | IDENT@[28; 35) "surname" 25 | COLON@[35; 36) ":" 26 | IDENT_TYPE@[36; 42) 27 | IDENT@[36; 42) "String" 28 | SEMI@[42; 43) ";" 29 | WHITESPACE@[43; 44) " " 30 | FN_DEF@[44; 65) 31 | FN_KW@[44; 46) "fn" 32 | WHITESPACE@[46; 47) " " 33 | NAME@[47; 50) 34 | IDENT@[47; 50) "new" 35 | PARAM_LIST@[50; 52) 36 | L_PAREN@[50; 51) "(" 37 | R_PAREN@[51; 52) ")" 38 | WHITESPACE@[52; 53) " " 39 | RET_TYPE@[53; 63) 40 | FRETURN@[53; 55) "->" 41 | WHITESPACE@[55; 56) " " 42 | IDENT_TYPE@[56; 63) 43 | IDENT@[56; 62) "Person" 44 | WHITESPACE@[62; 63) " " 45 | BLOCK_EXPR@[63; 65) 46 | BLOCK@[63; 65) 47 | L_CURLY@[63; 64) "{" 48 | R_CURLY@[64; 65) "}" 49 | R_CURLY@[65; 66) "}" 50 | 51 | -------------------------------------------------------------------------------- /parser/src/parser/snapshots/parser__parser__classes__tests__parse_empty_class.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/classes.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 12) 6 | CLASS_DEF@[0; 12) 7 | CLASS_KW@[0; 5) "class" 8 | WHITESPACE@[5; 6) " " 9 | NAME@[6; 9) 10 | IDENT@[6; 9) "Foo" 11 | WHITESPACE@[9; 10) " " 12 | L_CURLY@[10; 11) "{" 13 | R_CURLY@[11; 12) "}" 14 | 15 | -------------------------------------------------------------------------------- /parser/src/parser/snapshots/parser__parser__classes__tests__parse_exported_class.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/classes.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 19) 6 | CLASS_DEF@[0; 19) 7 | VISIBILITY@[0; 6) 8 | EXPORT_KW@[0; 6) "export" 9 | WHITESPACE@[6; 7) " " 10 | CLASS_KW@[7; 12) "class" 11 | WHITESPACE@[12; 13) " " 12 | NAME@[13; 16) 13 | IDENT@[13; 16) "Foo" 14 | WHITESPACE@[16; 17) " " 15 | L_CURLY@[17; 18) "{" 16 | R_CURLY@[18; 19) "}" 17 | 18 | -------------------------------------------------------------------------------- /parser/src/parser/snapshots/parser__parser__enums__tests__parse_empty_enum.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/enums.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 11) 6 | ENUM_DEF@[0; 11) 7 | ENUM_KW@[0; 4) "enum" 8 | WHITESPACE@[4; 5) " " 9 | NAME@[5; 8) 10 | IDENT@[5; 8) "Foo" 11 | WHITESPACE@[8; 9) " " 12 | ENUM_VARIANT_LIST@[9; 11) 13 | L_CURLY@[9; 10) "{" 14 | R_CURLY@[10; 11) "}" 15 | 16 | -------------------------------------------------------------------------------- /parser/src/parser/snapshots/parser__parser__enums__tests__parse_enum_generic.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/enums.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 32) 6 | ENUM_DEF@[0; 32) 7 | ENUM_KW@[0; 4) "enum" 8 | WHITESPACE@[4; 5) " " 9 | NAME@[5; 11) 10 | IDENT@[5; 11) "Result" 11 | TYPE_PARAM_LIST@[11; 16) 12 | L_ANGLE@[11; 12) "<" 13 | TYPE_PARAM@[12; 13) 14 | NAME@[12; 13) 15 | IDENT@[12; 13) "T" 16 | COMMA@[13; 14) "," 17 | TYPE_PARAM@[14; 15) 18 | NAME@[14; 15) 19 | IDENT@[14; 15) "E" 20 | R_ANGLE@[15; 16) ">" 21 | WHITESPACE@[16; 17) " " 22 | ENUM_VARIANT_LIST@[17; 32) 23 | L_CURLY@[17; 18) "{" 24 | WHITESPACE@[18; 19) " " 25 | ENUM_VARIANT@[19; 24) 26 | NAME@[19; 21) 27 | IDENT@[19; 21) "Ok" 28 | L_PAREN@[21; 22) "(" 29 | IDENT_TYPE@[22; 23) 30 | IDENT@[22; 23) "T" 31 | R_PAREN@[23; 24) ")" 32 | COMMA@[24; 25) "," 33 | ENUM_VARIANT@[25; 31) 34 | NAME@[25; 28) 35 | IDENT@[25; 28) "Err" 36 | L_PAREN@[28; 29) "(" 37 | IDENT_TYPE@[29; 30) 38 | IDENT@[29; 30) "E" 39 | R_PAREN@[30; 31) ")" 40 | R_CURLY@[31; 32) "}" 41 | 42 | -------------------------------------------------------------------------------- /parser/src/parser/snapshots/parser__parser__enums__tests__parse_enum_variants_trailing_comma.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/enums.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 17) 6 | ENUM_DEF@[0; 17) 7 | ENUM_KW@[0; 4) "enum" 8 | WHITESPACE@[4; 5) " " 9 | NAME@[5; 8) 10 | IDENT@[5; 8) "Foo" 11 | WHITESPACE@[8; 9) " " 12 | ENUM_VARIANT_LIST@[9; 17) 13 | L_CURLY@[9; 10) "{" 14 | ENUM_VARIANT@[10; 11) 15 | NAME@[10; 11) 16 | IDENT@[10; 11) "A" 17 | COMMA@[11; 12) "," 18 | ENUM_VARIANT@[12; 13) 19 | NAME@[12; 13) 20 | IDENT@[12; 13) "B" 21 | COMMA@[13; 14) "," 22 | ENUM_VARIANT@[14; 15) 23 | NAME@[14; 15) 24 | IDENT@[14; 15) "C" 25 | COMMA@[15; 16) "," 26 | R_CURLY@[16; 17) "}" 27 | 28 | -------------------------------------------------------------------------------- /parser/src/parser/snapshots/parser__parser__enums__tests__parse_enum_variants_types.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/enums.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 41) 6 | ENUM_DEF@[0; 41) 7 | ENUM_KW@[0; 4) "enum" 8 | WHITESPACE@[4; 5) " " 9 | NAME@[5; 8) 10 | IDENT@[5; 8) "Foo" 11 | WHITESPACE@[8; 9) " " 12 | ENUM_VARIANT_LIST@[9; 41) 13 | L_CURLY@[9; 10) "{" 14 | WHITESPACE@[10; 11) " " 15 | ENUM_VARIANT@[11; 19) 16 | NAME@[11; 12) 17 | IDENT@[11; 12) "A" 18 | L_PAREN@[12; 13) "(" 19 | ARRAY_TYPE@[13; 18) 20 | L_BRACK@[13; 14) "[" 21 | IDENT_TYPE@[14; 17) 22 | IDENT@[14; 17) "i32" 23 | R_BRACK@[17; 18) "]" 24 | R_PAREN@[18; 19) ")" 25 | COMMA@[19; 20) "," 26 | ENUM_VARIANT@[20; 26) 27 | NAME@[20; 21) 28 | IDENT@[20; 21) "B" 29 | L_PAREN@[21; 22) "(" 30 | IDENT_TYPE@[22; 25) 31 | IDENT@[22; 25) "i32" 32 | R_PAREN@[25; 26) ")" 33 | COMMA@[26; 27) "," 34 | ENUM_VARIANT@[27; 39) 35 | NAME@[27; 28) 36 | IDENT@[27; 28) "C" 37 | L_PAREN@[28; 29) "(" 38 | PAREN_TYPE@[29; 38) 39 | L_PAREN@[29; 30) "(" 40 | IDENT_TYPE@[30; 33) 41 | IDENT@[30; 33) "i32" 42 | COMMA@[33; 34) "," 43 | IDENT_TYPE@[34; 37) 44 | IDENT@[34; 37) "i32" 45 | R_PAREN@[37; 38) ")" 46 | R_PAREN@[38; 39) ")" 47 | COMMA@[39; 40) "," 48 | R_CURLY@[40; 41) "}" 49 | 50 | -------------------------------------------------------------------------------- /parser/src/parser/snapshots/parser__parser__enums__tests__parse_enum_with_variants.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/enums.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 16) 6 | ENUM_DEF@[0; 16) 7 | ENUM_KW@[0; 4) "enum" 8 | WHITESPACE@[4; 5) " " 9 | NAME@[5; 8) 10 | IDENT@[5; 8) "Foo" 11 | WHITESPACE@[8; 9) " " 12 | ENUM_VARIANT_LIST@[9; 16) 13 | L_CURLY@[9; 10) "{" 14 | ENUM_VARIANT@[10; 11) 15 | NAME@[10; 11) 16 | IDENT@[10; 11) "A" 17 | COMMA@[11; 12) "," 18 | ENUM_VARIANT@[12; 13) 19 | NAME@[12; 13) 20 | IDENT@[12; 13) "B" 21 | COMMA@[13; 14) "," 22 | ENUM_VARIANT@[14; 15) 23 | NAME@[14; 15) 24 | IDENT@[14; 15) "C" 25 | R_CURLY@[15; 16) "}" 26 | 27 | -------------------------------------------------------------------------------- /parser/src/parser/snapshots/parser__parser__enums__tests__parse_exported_enum.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/enums.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 18) 6 | ENUM_DEF@[0; 18) 7 | VISIBILITY@[0; 6) 8 | EXPORT_KW@[0; 6) "export" 9 | WHITESPACE@[6; 7) " " 10 | ENUM_KW@[7; 11) "enum" 11 | WHITESPACE@[11; 12) " " 12 | NAME@[12; 15) 13 | IDENT@[12; 15) "Foo" 14 | WHITESPACE@[15; 16) " " 15 | ENUM_VARIANT_LIST@[16; 18) 16 | L_CURLY@[16; 17) "{" 17 | R_CURLY@[17; 18) "}" 18 | 19 | -------------------------------------------------------------------------------- /parser/src/parser/snapshots/parser__parser__function__tests__parse_exported_function.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/function.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 19) 6 | FN_DEF@[0; 19) 7 | VISIBILITY@[0; 6) 8 | EXPORT_KW@[0; 6) "export" 9 | WHITESPACE@[6; 7) " " 10 | FN_KW@[7; 9) "fn" 11 | WHITESPACE@[9; 10) " " 12 | NAME@[10; 14) 13 | IDENT@[10; 14) "main" 14 | PARAM_LIST@[14; 16) 15 | L_PAREN@[14; 15) "(" 16 | R_PAREN@[15; 16) ")" 17 | WHITESPACE@[16; 17) " " 18 | BLOCK_EXPR@[17; 19) 19 | BLOCK@[17; 19) 20 | L_CURLY@[17; 18) "{" 21 | R_CURLY@[18; 19) "}" 22 | 23 | -------------------------------------------------------------------------------- /parser/src/parser/snapshots/parser__parser__function__tests__parse_function.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/function.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 12) 6 | FN_DEF@[0; 12) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 9) 12 | L_PAREN@[7; 8) "(" 13 | R_PAREN@[8; 9) ")" 14 | WHITESPACE@[9; 10) " " 15 | BLOCK_EXPR@[10; 12) 16 | BLOCK@[10; 12) 17 | L_CURLY@[10; 11) "{" 18 | R_CURLY@[11; 12) "}" 19 | 20 | -------------------------------------------------------------------------------- /parser/src/parser/snapshots/parser__parser__imports__tests__parse_empty_import.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/imports.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 11) 6 | IMPORT_DEF@[0; 11) 7 | IMPORT_KW@[0; 6) "import" 8 | WHITESPACE@[6; 7) " " 9 | IMPORT_SEGMENT@[7; 10) 10 | NAME@[7; 10) 11 | IDENT@[7; 10) "foo" 12 | SEMI@[10; 11) ";" 13 | 14 | -------------------------------------------------------------------------------- /parser/src/parser/snapshots/parser__parser__imports__tests__parse_import_with_brace.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/imports.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 22) 6 | IMPORT_DEF@[0; 22) 7 | IMPORT_KW@[0; 6) "import" 8 | WHITESPACE@[6; 7) " " 9 | IMPORT_SEGMENT@[7; 10) 10 | NAME@[7; 10) 11 | IDENT@[7; 10) "foo" 12 | COLON_COLON@[10; 12) "::" 13 | IMPORT_LIST@[12; 21) 14 | L_CURLY@[12; 13) "{" 15 | IMPORT_SEGMENT@[13; 16) 16 | NAME@[13; 16) 17 | IDENT@[13; 16) "bar" 18 | COMMA@[16; 17) "," 19 | IMPORT_SEGMENT@[17; 20) 20 | NAME@[17; 20) 21 | IDENT@[17; 20) "baz" 22 | R_CURLY@[20; 21) "}" 23 | SEMI@[21; 22) ";" 24 | 25 | -------------------------------------------------------------------------------- /parser/src/parser/snapshots/parser__parser__imports__tests__parse_import_with_brace_nested_segments.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/imports.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 29) 6 | IMPORT_DEF@[0; 29) 7 | IMPORT_KW@[0; 6) "import" 8 | WHITESPACE@[6; 7) " " 9 | IMPORT_SEGMENT@[7; 10) 10 | NAME@[7; 10) 11 | IDENT@[7; 10) "foo" 12 | COLON_COLON@[10; 12) "::" 13 | IMPORT_LIST@[12; 28) 14 | L_CURLY@[12; 13) "{" 15 | IMPORT_SEGMENT@[13; 16) 16 | NAME@[13; 16) 17 | IDENT@[13; 16) "bar" 18 | COLON_COLON@[16; 18) "::" 19 | IMPORT_SEGMENT@[18; 21) 20 | NAME@[18; 21) 21 | IDENT@[18; 21) "baz" 22 | COMMA@[21; 22) "," 23 | IMPORT_SEGMENT@[22; 27) 24 | NAME@[22; 27) 25 | IDENT@[22; 27) "fubar" 26 | R_CURLY@[27; 28) "}" 27 | SEMI@[28; 29) ";" 28 | 29 | -------------------------------------------------------------------------------- /parser/src/parser/snapshots/parser__parser__imports__tests__parse_import_with_multiple_segments.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/imports.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 21) 6 | IMPORT_DEF@[0; 21) 7 | IMPORT_KW@[0; 6) "import" 8 | WHITESPACE@[6; 7) " " 9 | IMPORT_SEGMENT@[7; 10) 10 | NAME@[7; 10) 11 | IDENT@[7; 10) "foo" 12 | COLON_COLON@[10; 12) "::" 13 | IMPORT_SEGMENT@[12; 15) 14 | NAME@[12; 15) 15 | IDENT@[12; 15) "bar" 16 | COLON_COLON@[15; 17) "::" 17 | IMPORT_SEGMENT@[17; 20) 18 | NAME@[17; 20) 19 | IDENT@[17; 20) "baz" 20 | SEMI@[20; 21) ";" 21 | 22 | -------------------------------------------------------------------------------- /parser/src/parser/snapshots/parser__parser__module__tests__parse_many_mods.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/module.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 17) 6 | MOD_DEF@[0; 8) 7 | MOD_KW@[0; 3) "mod" 8 | WHITESPACE@[3; 4) " " 9 | NAME@[4; 7) 10 | IDENT@[4; 7) "bar" 11 | SEMI@[7; 8) ";" 12 | WHITESPACE@[8; 9) " " 13 | MOD_DEF@[9; 17) 14 | MOD_KW@[9; 12) "mod" 15 | WHITESPACE@[12; 13) " " 16 | NAME@[13; 16) 17 | IDENT@[13; 16) "foo" 18 | SEMI@[16; 17) ";" 19 | 20 | -------------------------------------------------------------------------------- /parser/src/parser/snapshots/parser__parser__module__tests__parse_single_mod.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/module.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 8) 6 | MOD_DEF@[0; 8) 7 | MOD_KW@[0; 3) "mod" 8 | WHITESPACE@[3; 4) " " 9 | NAME@[4; 7) 10 | IDENT@[4; 7) "foo" 11 | SEMI@[7; 8) ";" 12 | 13 | -------------------------------------------------------------------------------- /parser/src/parser/snapshots/parser__parser__pattern__tests__parse_binding_pattern.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/pattern.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 17) 6 | FN_DEF@[0; 17) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 14) 12 | L_PAREN@[7; 8) "(" 13 | PARAM@[8; 13) 14 | BIND_PAT@[8; 9) 15 | NAME@[8; 9) 16 | IDENT@[8; 9) "x" 17 | COLON@[9; 10) ":" 18 | IDENT_TYPE@[10; 13) 19 | IDENT@[10; 13) "i32" 20 | R_PAREN@[13; 14) ")" 21 | WHITESPACE@[14; 15) " " 22 | BLOCK_EXPR@[15; 17) 23 | BLOCK@[15; 17) 24 | L_CURLY@[15; 16) "{" 25 | R_CURLY@[16; 17) "}" 26 | 27 | -------------------------------------------------------------------------------- /parser/src/parser/snapshots/parser__parser__pattern__tests__parse_nested_tuple_pattern.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/pattern.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 25) 6 | FN_DEF@[0; 25) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 22) 12 | L_PAREN@[7; 8) "(" 13 | PARAM@[8; 21) 14 | TUPLE_PAT@[8; 17) 15 | L_PAREN@[8; 9) "(" 16 | BIND_PAT@[9; 10) 17 | NAME@[9; 10) 18 | IDENT@[9; 10) "x" 19 | COMMA@[10; 11) "," 20 | TUPLE_PAT@[11; 16) 21 | L_PAREN@[11; 12) "(" 22 | BIND_PAT@[12; 13) 23 | NAME@[12; 13) 24 | IDENT@[12; 13) "y" 25 | COMMA@[13; 14) "," 26 | PLACEHOLDER_PAT@[14; 15) 27 | UNDERSCORE@[14; 15) "_" 28 | R_PAREN@[15; 16) ")" 29 | R_PAREN@[16; 17) ")" 30 | COLON@[17; 18) ":" 31 | IDENT_TYPE@[18; 21) 32 | IDENT@[18; 21) "i32" 33 | R_PAREN@[21; 22) ")" 34 | WHITESPACE@[22; 23) " " 35 | BLOCK_EXPR@[23; 25) 36 | BLOCK@[23; 25) 37 | L_CURLY@[23; 24) "{" 38 | R_CURLY@[24; 25) "}" 39 | 40 | -------------------------------------------------------------------------------- /parser/src/parser/snapshots/parser__parser__pattern__tests__parse_placeholder_pattern.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/pattern.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 17) 6 | FN_DEF@[0; 17) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 14) 12 | L_PAREN@[7; 8) "(" 13 | PARAM@[8; 13) 14 | PLACEHOLDER_PAT@[8; 9) 15 | UNDERSCORE@[8; 9) "_" 16 | COLON@[9; 10) ":" 17 | IDENT_TYPE@[10; 13) 18 | IDENT@[10; 13) "i32" 19 | R_PAREN@[13; 14) ")" 20 | WHITESPACE@[14; 15) " " 21 | BLOCK_EXPR@[15; 17) 22 | BLOCK@[15; 17) 23 | L_CURLY@[15; 16) "{" 24 | R_CURLY@[16; 17) "}" 25 | 26 | -------------------------------------------------------------------------------- /parser/src/parser/snapshots/parser__parser__pattern__tests__parse_tuple_pattern.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/pattern.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 21) 6 | FN_DEF@[0; 21) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 18) 12 | L_PAREN@[7; 8) "(" 13 | PARAM@[8; 17) 14 | TUPLE_PAT@[8; 13) 15 | L_PAREN@[8; 9) "(" 16 | BIND_PAT@[9; 10) 17 | NAME@[9; 10) 18 | IDENT@[9; 10) "x" 19 | COMMA@[10; 11) "," 20 | BIND_PAT@[11; 12) 21 | NAME@[11; 12) 22 | IDENT@[11; 12) "y" 23 | R_PAREN@[12; 13) ")" 24 | COLON@[13; 14) ":" 25 | IDENT_TYPE@[14; 17) 26 | IDENT@[14; 17) "i32" 27 | R_PAREN@[17; 18) ")" 28 | WHITESPACE@[18; 19) " " 29 | BLOCK_EXPR@[19; 21) 30 | BLOCK@[19; 21) 31 | L_CURLY@[19; 20) "{" 32 | R_CURLY@[20; 21) "}" 33 | 34 | -------------------------------------------------------------------------------- /parser/src/parser/snapshots/parser__parser__type_alias__tests__parse_exported_type_alias.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/type_alias.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 22) 6 | TYPE_ALIAS_DEF@[0; 22) 7 | VISIBILITY@[0; 6) 8 | EXPORT_KW@[0; 6) "export" 9 | WHITESPACE@[6; 7) " " 10 | TYPE_KW@[7; 11) "type" 11 | WHITESPACE@[11; 12) " " 12 | NAME@[12; 15) 13 | IDENT@[12; 15) "Foo" 14 | WHITESPACE@[15; 16) " " 15 | EQ@[16; 17) "=" 16 | WHITESPACE@[17; 18) " " 17 | IDENT_TYPE@[18; 21) 18 | IDENT@[18; 21) "i32" 19 | SEMI@[21; 22) ";" 20 | 21 | -------------------------------------------------------------------------------- /parser/src/parser/snapshots/parser__parser__type_alias__tests__parse_type_alias.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/type_alias.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 15) 6 | TYPE_ALIAS_DEF@[0; 15) 7 | TYPE_KW@[0; 4) "type" 8 | WHITESPACE@[4; 5) " " 9 | NAME@[5; 8) 10 | IDENT@[5; 8) "Foo" 11 | WHITESPACE@[8; 9) " " 12 | EQ@[9; 10) "=" 13 | WHITESPACE@[10; 11) " " 14 | IDENT_TYPE@[11; 14) 15 | IDENT@[11; 14) "i32" 16 | SEMI@[14; 15) ";" 17 | 18 | -------------------------------------------------------------------------------- /parser/src/parser/snapshots/parser__parser__type_alias__tests__parse_type_alias_params.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/type_alias.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 37) 6 | TYPE_ALIAS_DEF@[0; 37) 7 | TYPE_KW@[0; 4) "type" 8 | WHITESPACE@[4; 5) " " 9 | NAME@[5; 16) 10 | IDENT@[5; 16) "ParseResult" 11 | TYPE_PARAM_LIST@[16; 19) 12 | L_ANGLE@[16; 17) "<" 13 | TYPE_PARAM@[17; 18) 14 | NAME@[17; 18) 15 | IDENT@[17; 18) "T" 16 | R_ANGLE@[18; 19) ">" 17 | WHITESPACE@[19; 20) " " 18 | EQ@[20; 21) "=" 19 | WHITESPACE@[21; 22) " " 20 | IDENT_TYPE@[22; 36) 21 | IDENT@[22; 28) "Result" 22 | TYPE_ARG_LIST@[28; 36) 23 | L_ANGLE@[28; 29) "<" 24 | IDENT_TYPE@[29; 30) 25 | IDENT@[29; 30) "T" 26 | COMMA@[30; 31) "," 27 | IDENT_TYPE@[31; 35) 28 | IDENT@[31; 35) "void" 29 | R_ANGLE@[35; 36) ">" 30 | SEMI@[36; 37) ";" 31 | 32 | -------------------------------------------------------------------------------- /parser/src/parser/snapshots/parser__parser__types__tests__parse_array_tuple_type.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/types.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 25) 6 | FN_DEF@[0; 25) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 22) 12 | L_PAREN@[7; 8) "(" 13 | PARAM@[8; 21) 14 | BIND_PAT@[8; 9) 15 | NAME@[8; 9) 16 | IDENT@[8; 9) "x" 17 | COLON@[9; 10) ":" 18 | ARRAY_TYPE@[10; 21) 19 | L_BRACK@[10; 11) "[" 20 | PAREN_TYPE@[11; 20) 21 | L_PAREN@[11; 12) "(" 22 | IDENT_TYPE@[12; 15) 23 | IDENT@[12; 15) "i32" 24 | COMMA@[15; 16) "," 25 | IDENT_TYPE@[16; 19) 26 | IDENT@[16; 19) "i32" 27 | R_PAREN@[19; 20) ")" 28 | R_BRACK@[20; 21) "]" 29 | R_PAREN@[21; 22) ")" 30 | WHITESPACE@[22; 23) " " 31 | BLOCK_EXPR@[23; 25) 32 | BLOCK@[23; 25) 33 | L_CURLY@[23; 24) "{" 34 | R_CURLY@[24; 25) "}" 35 | 36 | -------------------------------------------------------------------------------- /parser/src/parser/snapshots/parser__parser__types__tests__parse_array_type.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/types.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 19) 6 | FN_DEF@[0; 19) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 16) 12 | L_PAREN@[7; 8) "(" 13 | PARAM@[8; 15) 14 | BIND_PAT@[8; 9) 15 | NAME@[8; 9) 16 | IDENT@[8; 9) "x" 17 | COLON@[9; 10) ":" 18 | ARRAY_TYPE@[10; 15) 19 | L_BRACK@[10; 11) "[" 20 | IDENT_TYPE@[11; 14) 21 | IDENT@[11; 14) "i32" 22 | R_BRACK@[14; 15) "]" 23 | R_PAREN@[15; 16) ")" 24 | WHITESPACE@[16; 17) " " 25 | BLOCK_EXPR@[17; 19) 26 | BLOCK@[17; 19) 27 | L_CURLY@[17; 18) "{" 28 | R_CURLY@[18; 19) "}" 29 | 30 | -------------------------------------------------------------------------------- /parser/src/parser/snapshots/parser__parser__types__tests__parse_fn_tuple_type.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/types.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 34) 6 | FN_DEF@[0; 34) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 31) 12 | L_PAREN@[7; 8) "(" 13 | PARAM@[8; 30) 14 | PLACEHOLDER_PAT@[8; 9) 15 | UNDERSCORE@[8; 9) "_" 16 | COLON@[9; 10) ":" 17 | FN_TYPE@[10; 30) 18 | FN_KW@[10; 12) "fn" 19 | L_PAREN@[12; 13) "(" 20 | PAREN_TYPE@[13; 22) 21 | L_PAREN@[13; 14) "(" 22 | IDENT_TYPE@[14; 17) 23 | IDENT@[14; 17) "i32" 24 | COMMA@[17; 18) "," 25 | IDENT_TYPE@[18; 21) 26 | IDENT@[18; 21) "i32" 27 | R_PAREN@[21; 22) ")" 28 | R_PAREN@[22; 23) ")" 29 | WHITESPACE@[23; 24) " " 30 | RET_TYPE@[24; 30) 31 | FRETURN@[24; 26) "->" 32 | WHITESPACE@[26; 27) " " 33 | IDENT_TYPE@[27; 30) 34 | IDENT@[27; 30) "i32" 35 | R_PAREN@[30; 31) ")" 36 | WHITESPACE@[31; 32) " " 37 | BLOCK_EXPR@[32; 34) 38 | BLOCK@[32; 34) 39 | L_CURLY@[32; 33) "{" 40 | R_CURLY@[33; 34) "}" 41 | 42 | -------------------------------------------------------------------------------- /parser/src/parser/snapshots/parser__parser__types__tests__parse_fn_type.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/types.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 32) 6 | FN_DEF@[0; 32) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 29) 12 | L_PAREN@[7; 8) "(" 13 | PARAM@[8; 28) 14 | PLACEHOLDER_PAT@[8; 9) 15 | UNDERSCORE@[8; 9) "_" 16 | COLON@[9; 10) ":" 17 | FN_TYPE@[10; 28) 18 | FN_KW@[10; 12) "fn" 19 | L_PAREN@[12; 13) "(" 20 | IDENT_TYPE@[13; 16) 21 | IDENT@[13; 16) "i32" 22 | COMMA@[16; 17) "," 23 | IDENT_TYPE@[17; 20) 24 | IDENT@[17; 20) "i32" 25 | R_PAREN@[20; 21) ")" 26 | WHITESPACE@[21; 22) " " 27 | RET_TYPE@[22; 28) 28 | FRETURN@[22; 24) "->" 29 | WHITESPACE@[24; 25) " " 30 | IDENT_TYPE@[25; 28) 31 | IDENT@[25; 28) "i32" 32 | R_PAREN@[28; 29) ")" 33 | WHITESPACE@[29; 30) " " 34 | BLOCK_EXPR@[30; 32) 35 | BLOCK@[30; 32) 36 | L_CURLY@[30; 31) "{" 37 | R_CURLY@[31; 32) "}" 38 | 39 | -------------------------------------------------------------------------------- /parser/src/parser/snapshots/parser__parser__types__tests__parse_ident_type.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/types.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 17) 6 | FN_DEF@[0; 17) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 14) 12 | L_PAREN@[7; 8) "(" 13 | PARAM@[8; 13) 14 | BIND_PAT@[8; 9) 15 | NAME@[8; 9) 16 | IDENT@[8; 9) "x" 17 | COLON@[9; 10) ":" 18 | IDENT_TYPE@[10; 13) 19 | IDENT@[10; 13) "i32" 20 | R_PAREN@[13; 14) ")" 21 | WHITESPACE@[14; 15) " " 22 | BLOCK_EXPR@[15; 17) 23 | BLOCK@[15; 17) 24 | L_CURLY@[15; 16) "{" 25 | R_CURLY@[16; 17) "}" 26 | 27 | -------------------------------------------------------------------------------- /parser/src/parser/snapshots/parser__parser__types__tests__parse_tuple_type.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/types.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 23) 6 | FN_DEF@[0; 23) 7 | FN_KW@[0; 2) "fn" 8 | WHITESPACE@[2; 3) " " 9 | NAME@[3; 7) 10 | IDENT@[3; 7) "main" 11 | PARAM_LIST@[7; 20) 12 | L_PAREN@[7; 8) "(" 13 | PARAM@[8; 19) 14 | BIND_PAT@[8; 9) 15 | NAME@[8; 9) 16 | IDENT@[8; 9) "x" 17 | COLON@[9; 10) ":" 18 | PAREN_TYPE@[10; 19) 19 | L_PAREN@[10; 11) "(" 20 | IDENT_TYPE@[11; 14) 21 | IDENT@[11; 14) "i32" 22 | COMMA@[14; 15) "," 23 | IDENT_TYPE@[15; 18) 24 | IDENT@[15; 18) "i32" 25 | R_PAREN@[18; 19) ")" 26 | R_PAREN@[19; 20) ")" 27 | WHITESPACE@[20; 21) " " 28 | BLOCK_EXPR@[21; 23) 29 | BLOCK@[21; 23) 30 | L_CURLY@[21; 22) "{" 31 | R_CURLY@[22; 23) "}" 32 | 33 | -------------------------------------------------------------------------------- /parser/src/parser/snapshots/parser__parser__visibility__tests__parse_pub_alias.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/visibility.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 20) 6 | TYPE_ALIAS_DEF@[0; 20) 7 | VISIBILITY@[0; 6) 8 | EXPORT_KW@[0; 6) "export" 9 | WHITESPACE@[6; 7) " " 10 | TYPE_KW@[7; 11) "type" 11 | WHITESPACE@[11; 12) " " 12 | NAME@[12; 15) 13 | IDENT@[12; 15) "Foo" 14 | EQ@[15; 16) "=" 15 | IDENT_TYPE@[16; 19) 16 | IDENT@[16; 19) "i32" 17 | SEMI@[19; 20) ";" 18 | 19 | -------------------------------------------------------------------------------- /parser/src/parser/snapshots/parser__parser__visibility__tests__parse_pub_class.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/visibility.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 31) 6 | CLASS_DEF@[0; 30) 7 | VISIBILITY@[0; 6) 8 | EXPORT_KW@[0; 6) "export" 9 | WHITESPACE@[6; 7) " " 10 | CLASS_KW@[7; 12) "class" 11 | WHITESPACE@[12; 13) " " 12 | NAME@[13; 16) 13 | IDENT@[13; 16) "Foo" 14 | L_CURLY@[16; 17) "{" 15 | WHITESPACE@[17; 18) " " 16 | NAMED_FIELD_DEF@[18; 29) 17 | NAME@[18; 21) 18 | IDENT@[18; 21) "bar" 19 | COLON@[21; 22) ":" 20 | IDENT_TYPE@[22; 28) 21 | IDENT@[22; 28) "string" 22 | SEMI@[28; 29) ";" 23 | R_CURLY@[29; 30) "}" 24 | SEMI@[30; 31) ";" 25 | 26 | -------------------------------------------------------------------------------- /parser/src/parser/snapshots/parser__parser__visibility__tests__parse_pub_enum.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/visibility.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 18) 6 | ENUM_DEF@[0; 17) 7 | VISIBILITY@[0; 6) 8 | EXPORT_KW@[0; 6) "export" 9 | WHITESPACE@[6; 7) " " 10 | ENUM_KW@[7; 11) "enum" 11 | WHITESPACE@[11; 12) " " 12 | NAME@[12; 15) 13 | IDENT@[12; 15) "Bar" 14 | ENUM_VARIANT_LIST@[15; 17) 15 | L_CURLY@[15; 16) "{" 16 | R_CURLY@[16; 17) "}" 17 | SEMI@[17; 18) ";" 18 | 19 | -------------------------------------------------------------------------------- /parser/src/parser/snapshots/parser__parser__visibility__tests__parse_pub_function.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/parser/visibility.rs 3 | expression: "crate::utils::dump_debug(&parser_output)" 4 | --- 5 | SOURCE_FILE@[0; 19) 6 | FN_DEF@[0; 19) 7 | VISIBILITY@[0; 6) 8 | EXPORT_KW@[0; 6) "export" 9 | WHITESPACE@[6; 7) " " 10 | FN_KW@[7; 9) "fn" 11 | WHITESPACE@[9; 10) " " 12 | NAME@[10; 14) 13 | IDENT@[10; 14) "main" 14 | PARAM_LIST@[14; 16) 15 | L_PAREN@[14; 15) "(" 16 | R_PAREN@[15; 16) ")" 17 | WHITESPACE@[16; 17) " " 18 | BLOCK_EXPR@[17; 19) 19 | BLOCK@[17; 19) 20 | L_CURLY@[17; 18) "{" 21 | R_CURLY@[18; 19) "}" 22 | 23 | -------------------------------------------------------------------------------- /parser/src/parser/source_file.rs: -------------------------------------------------------------------------------- 1 | use crate::ast::*; 2 | use crate::parser::Parser; 3 | use rowan::GreenNodeBuilder; 4 | use syntax::T; 5 | 6 | use crate::{AstNode, SyntaxKind::*, SyntaxNode}; 7 | 8 | impl<'a> Parser<'a> { 9 | pub fn parse_program(&mut self) -> SourceFile { 10 | self.start_node(SOURCE_FILE); 11 | 12 | while !self.at(EOF) && !self.at(ERROR) { 13 | let has_visibility = self.has_visibility(); 14 | let checkpoint = self.checkpoint(); 15 | 16 | if has_visibility { 17 | self.parse_visibility(); 18 | } 19 | 20 | match self.current() { 21 | T![type] => self.parse_type_alias(checkpoint), 22 | T![fn] => { 23 | self.parse_function(checkpoint); 24 | } 25 | T![mod] => self.parse_module(), 26 | T![import] => self.parse_import(), 27 | T![enum] => self.parse_enum(checkpoint), 28 | T![class] => self.parse_class(checkpoint), 29 | T!["//"] => { 30 | self.bump(); 31 | continue; 32 | } 33 | IDENT => { 34 | let message = format!("Unknown top level modifier"); 35 | 36 | self.error( 37 | message, 38 | "Only `type`, `fn`, `mod`, `import`, `enum` , `class` are allowed at the top level", 39 | ) 40 | } 41 | 42 | _ => self.recover(), 43 | } 44 | } 45 | 46 | self.finish_node(); 47 | 48 | let mut _builder = GreenNodeBuilder::new(); 49 | 50 | std::mem::swap(&mut self.builder, &mut _builder); 51 | 52 | let green = _builder.finish(); 53 | 54 | let root = SyntaxNode::new_root(green); 55 | 56 | SourceFile::cast(root).unwrap() 57 | } 58 | 59 | pub(crate) fn has_visibility(&mut self) -> bool { 60 | match self.current() { 61 | T![export] => true, 62 | _ => false, 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /parser/src/parser/type_alias.rs: -------------------------------------------------------------------------------- 1 | use syntax::T; 2 | 3 | use crate::parser::Parser; 4 | 5 | use crate::SyntaxKind::*; 6 | 7 | impl<'a> Parser<'a> { 8 | pub(crate) fn parse_type_alias(&mut self, checkpoint: rowan::Checkpoint) { 9 | self.start_node_at(checkpoint, TYPE_ALIAS_DEF); 10 | 11 | self.expect(T![type]); 12 | 13 | self.ident(); 14 | 15 | if self.at(L_ANGLE) { 16 | self.parse_type_params(false); 17 | } 18 | 19 | self.expect(EQ); 20 | 21 | self.parse_type(); 22 | 23 | self.expect(SEMI); 24 | 25 | self.finish_node() 26 | } 27 | } 28 | 29 | #[cfg(test)] 30 | mod tests { 31 | test_parser! {parse_type_alias,"type Foo = i32;"} 32 | test_parser! {parse_exported_type_alias,"export type Foo = i32;"} 33 | test_parser! {parse_type_alias_params,"type ParseResult = Result;"} 34 | } 35 | -------------------------------------------------------------------------------- /parser/src/parser/type_args.rs: -------------------------------------------------------------------------------- 1 | use crate::parser::Parser; 2 | use crate::SyntaxKind::*; 3 | use syntax::T; 4 | 5 | impl<'a> Parser<'a> { 6 | pub(crate) fn parse_type_args(&mut self) { 7 | self.start_node(TYPE_ARG_LIST); 8 | 9 | self.bump(); 10 | 11 | while !self.at(EOF) && !self.at(T![>]) { 12 | self.parse_type(); 13 | 14 | if !self.at(T![>]) && !self.expected(T![,]) { 15 | break; 16 | } 17 | } 18 | 19 | self.expect(T![>]); 20 | 21 | self.finish_node(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /parser/src/parser/type_params.rs: -------------------------------------------------------------------------------- 1 | use crate::parser::Parser; 2 | use crate::SyntaxKind::*; 3 | use syntax::T; 4 | 5 | impl<'a> Parser<'a> { 6 | pub(crate) fn parse_type_params(&mut self, allow_types: bool) { 7 | self.start_node(TYPE_PARAM_LIST); 8 | self.bump(); 9 | 10 | while !self.at(EOF) && !self.at(T![>]) { 11 | if allow_types { 12 | self.start_node(TYPE_PARAM); 13 | self.parse_type(); 14 | self.finish_node(); 15 | } else { 16 | self.type_param(); 17 | } 18 | 19 | if !self.at(T![>]) && !self.expected(T![,]) { 20 | break; 21 | } 22 | } 23 | 24 | self.expect(T![>]); 25 | self.finish_node() 26 | } 27 | 28 | fn type_param(&mut self) { 29 | self.start_node(TYPE_PARAM); 30 | self.ident(); 31 | self.finish_node(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /parser/src/parser/visibility.rs: -------------------------------------------------------------------------------- 1 | use crate::parser::Parser; 2 | use syntax::T; 3 | 4 | use crate::SyntaxKind::*; 5 | 6 | impl<'a> Parser<'a> { 7 | pub(crate) fn parse_visibility(&mut self) { 8 | self.start_node(VISIBILITY); 9 | self.expect(T![export]); 10 | self.finish_node(); 11 | } 12 | } 13 | 14 | #[cfg(test)] 15 | mod tests { 16 | use crate::utils::parse; 17 | use errors::WithError; 18 | use syntax::{FnDefOwner, VisibilityOwner}; 19 | #[test] 20 | fn test_visibility() { 21 | let WithError(source_file, _) = parse("export fn main(){}"); 22 | 23 | let func = source_file.functions().next().unwrap(); 24 | 25 | assert!(func.visibility().is_some()) 26 | } 27 | #[test] 28 | fn test_visibility_not_present() { 29 | let WithError(source_file, _) = parse("fn main(){}"); 30 | 31 | let func = source_file.functions().next().unwrap(); 32 | 33 | assert!(func.visibility().is_none()) 34 | } 35 | 36 | test_parser! {parse_pub_function,"export fn main() {}"} 37 | test_parser! {parse_pub_alias,"export type Foo=i32;"} 38 | test_parser! {parse_pub_enum,"export enum Bar{};"} 39 | test_parser! {parse_pub_class,"export class Foo{ bar:string;};"} 40 | } 41 | -------------------------------------------------------------------------------- /parser/src/snapshots/parser__lexer__tests__lex_line_comment.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/lexer.rs 3 | expression: get_tokens(input) 4 | --- 5 | [ 6 | Span { 7 | value: Token { 8 | kind: INT_NUMBER, 9 | len: 2, 10 | }, 11 | start: Position { 12 | column: 1, 13 | line: 1, 14 | absolute: 0, 15 | }, 16 | end: Position { 17 | column: 3, 18 | line: 1, 19 | absolute: 2, 20 | }, 21 | }, 22 | Span { 23 | value: Token { 24 | kind: WHITESPACE, 25 | len: 1, 26 | }, 27 | start: Position { 28 | column: 3, 29 | line: 1, 30 | absolute: 2, 31 | }, 32 | end: Position { 33 | column: 4, 34 | line: 1, 35 | absolute: 3, 36 | }, 37 | }, 38 | Span { 39 | value: Token { 40 | kind: COMMENT, 41 | len: 25, 42 | }, 43 | start: Position { 44 | column: 4, 45 | line: 1, 46 | absolute: 3, 47 | }, 48 | end: Position { 49 | column: 29, 50 | line: 1, 51 | absolute: 28, 52 | }, 53 | }, 54 | Span { 55 | value: Token { 56 | kind: EOF, 57 | len: 1, 58 | }, 59 | start: Position { 60 | column: 29, 61 | line: 1, 62 | absolute: 28, 63 | }, 64 | end: Position { 65 | column: 29, 66 | line: 1, 67 | absolute: 28, 68 | }, 69 | }, 70 | ] 71 | -------------------------------------------------------------------------------- /parser/src/snapshots/parser__lexer__tests__lex_nested_block_comments.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: parser/src/lexer.rs 3 | expression: get_tokens(input) 4 | --- 5 | [ 6 | Span { 7 | value: Token { 8 | kind: COMMENT, 9 | len: 35, 10 | }, 11 | start: Position { 12 | column: 1, 13 | line: 1, 14 | absolute: 0, 15 | }, 16 | end: Position { 17 | column: 36, 18 | line: 1, 19 | absolute: 35, 20 | }, 21 | }, 22 | Span { 23 | value: Token { 24 | kind: EOF, 25 | len: 1, 26 | }, 27 | start: Position { 28 | column: 36, 29 | line: 1, 30 | absolute: 35, 31 | }, 32 | end: Position { 33 | column: 36, 34 | line: 1, 35 | absolute: 35, 36 | }, 37 | }, 38 | ] 39 | -------------------------------------------------------------------------------- /parser/src/utils.rs: -------------------------------------------------------------------------------- 1 | use crate::AstNode; 2 | #[cfg(test)] 3 | use errors::WithError; 4 | #[cfg(test)] 5 | use syntax::ast::SourceFile; 6 | 7 | pub fn dump_debug(item: &T) -> String { 8 | format!("{:#?}", item.syntax()) 9 | } 10 | 11 | #[cfg(test)] 12 | #[salsa::database(errors::FileDatabaseStorage, crate::ParseDatabaseStorage)] 13 | #[derive(Debug, Default)] 14 | pub struct MockDatabaseImpl { 15 | runtime: salsa::Runtime, 16 | } 17 | 18 | #[cfg(test)] 19 | impl salsa::Database for MockDatabaseImpl { 20 | fn salsa_runtime(&self) -> &salsa::Runtime { 21 | &self.runtime 22 | } 23 | 24 | fn salsa_runtime_mut(&mut self) -> &mut salsa::Runtime { 25 | &mut self.runtime 26 | } 27 | } 28 | 29 | #[cfg(test)] 30 | pub fn parse<'a>(input: &'a str) -> WithError { 31 | use crate::ParseDatabase; 32 | use errors::FileDatabase; 33 | use std::io::Write; 34 | use tempfile::NamedTempFile; 35 | 36 | let mut file = NamedTempFile::new().unwrap(); 37 | write!(file, "{}", input).unwrap(); 38 | let db = MockDatabaseImpl::default(); 39 | let handle = db.intern_file(file.path().to_path_buf()); 40 | 41 | db.parse(handle) 42 | } 43 | -------------------------------------------------------------------------------- /semant/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "semant" 3 | version = "0.1.0" 4 | authors = ["Lenard Pratt "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | syntax= {path="../syntax"} 11 | parser= {path="../parser"} 12 | salsa = "^0.14.1" 13 | errors = {path="../errors"} 14 | indexmap = "1.3.0" 15 | serde ="*" 16 | tracing="^0.1.22" 17 | [dev-dependencies] 18 | serde ="1.0.106" 19 | ron = "0.5.1" 20 | tempfile = "3.1.0" 21 | walkdir = "2" -------------------------------------------------------------------------------- /semant/src/infer/block.rs: -------------------------------------------------------------------------------- 1 | use syntax::TextUnit; 2 | 3 | use crate::{ 4 | hir::{BlockId, FunctionAstMap}, 5 | infer::InferDataCollector, 6 | typed, HirDatabase, Type, TypeCon, 7 | }; 8 | impl<'a, DB> InferDataCollector<&'a DB> 9 | where 10 | DB: HirDatabase, 11 | { 12 | pub(crate) fn infer_block( 13 | &mut self, 14 | 15 | block_id: &BlockId, 16 | has_value: bool, 17 | span: (TextUnit, TextUnit), 18 | map: &FunctionAstMap, 19 | ) -> typed::Typed { 20 | self.env.begin_scope(); 21 | 22 | let block = map.block(block_id); 23 | 24 | let mut stmts = Vec::with_capacity(block.0.len()); 25 | let mut returns = Type::Con(TypeCon::Void); 26 | 27 | for (index, stmt) in block.0.iter().enumerate() { 28 | let stmt = self.infer_statement(stmt, map); 29 | if has_value && index == block.0.len() - 1 { 30 | returns = stmt.ty.clone(); 31 | } 32 | 33 | stmts.push(stmt); 34 | } 35 | 36 | self.env.begin_scope(); 37 | 38 | typed::Typed::new(typed::Expr::Block(stmts, has_value), returns, span) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /semant/src/infer/tests/tuple_field.ron: -------------------------------------------------------------------------------- 1 | Program ( 2 | contents: " 3 | fn main() { 4 | let a:(i32,i32); 5 | a.1 = 1; 6 | } 7 | ", 8 | errors:[ 9 | "is not a valid tuple field" 10 | ] 11 | ) -------------------------------------------------------------------------------- /semant/src/infer/tests/tuple_high_index.ron: -------------------------------------------------------------------------------- 1 | Program ( 2 | contents: " 3 | fn main() { 4 | let a:(i32,i32); 5 | a.5 = 1; 6 | } 7 | ", 8 | errors:[ 9 | "Unknown tuple field `5`" 10 | ] 11 | ) -------------------------------------------------------------------------------- /semant/src/infer/tests/tuple_non_int.ron: -------------------------------------------------------------------------------- 1 | Program ( 2 | contents: " 3 | fn main() { 4 | let a:(i32,i32); 5 | a.true = 1; 6 | } 7 | ", 8 | errors:[ 9 | "is not a valid tuple field" 10 | ] 11 | ) -------------------------------------------------------------------------------- /semant/src/lib.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | mod db; 3 | pub mod hir; 4 | pub mod infer; 5 | // mod infer2; 6 | mod lower; 7 | pub mod typed; 8 | mod util; 9 | #[macro_use] 10 | mod resolver; 11 | pub use db::{HirDatabase, HirDatabaseStorage, InternDatabaseStorage}; 12 | pub use indexmap::IndexMap; 13 | pub use infer::{Ctx, InferDataMap, StackedMap, Type, TypeCon}; 14 | pub use resolver::Resolver; 15 | pub use syntax::{SmolStr, TextRange}; 16 | pub use typed::{Function, Program, Typed}; 17 | pub use util::Span; 18 | -------------------------------------------------------------------------------- /semant/src/lower/alias.rs: -------------------------------------------------------------------------------- 1 | use crate::db::HirDatabase; 2 | use crate::{hir, impl_collector, util}; 3 | use std::sync::Arc; 4 | use syntax::{AstNode, NameOwner, TypeParamsOwner, TypesOwner, VisibilityOwner}; 5 | 6 | #[derive(Debug)] 7 | pub(crate) struct TypeAliasDataCollector { 8 | db: DB, 9 | type_param_count: u64, 10 | type_params: Vec>, 11 | ast_map: hir::FunctionAstMap, 12 | } 13 | 14 | impl_collector!(TypeAliasDataCollector); 15 | 16 | impl<'a, DB> TypeAliasDataCollector<&'a DB> 17 | where 18 | DB: HirDatabase, 19 | { 20 | pub fn finish( 21 | self, 22 | name: util::Span, 23 | exported: bool, 24 | ty: util::Span, 25 | span: crate::TextRange, 26 | ) -> hir::TypeAlias { 27 | let type_params = self.type_params; 28 | hir::TypeAlias { 29 | name, 30 | type_params, 31 | span, 32 | ast_map: self.ast_map, 33 | exported, 34 | ty, 35 | } 36 | } 37 | } 38 | pub(crate) fn lower_type_alias_query( 39 | db: &impl HirDatabase, 40 | alias_id: hir::TypeAliasId, 41 | ) -> Arc { 42 | let alias = db.lookup_intern_type_alias(alias_id); 43 | let name = util::Span::from_ast( 44 | db.intern_name(alias.name().unwrap().into()), 45 | &alias.name().unwrap(), 46 | ); 47 | 48 | let exported = alias.visibility().is_some(); 49 | let mut collector = TypeAliasDataCollector { 50 | db, 51 | type_params: Vec::new(), 52 | type_param_count: 0, 53 | ast_map: hir::FunctionAstMap::default(), 54 | }; 55 | 56 | if let Some(type_params_list) = alias.type_param_list() { 57 | for type_param in type_params_list.type_params() { 58 | collector.lower_type_param(type_param); 59 | } 60 | } 61 | 62 | let ty = collector.lower_type(alias.type_ref().unwrap()); 63 | let span = alias.syntax().text_range(); 64 | Arc::new(collector.finish(name, exported, ty, span)) 65 | } 66 | -------------------------------------------------------------------------------- /semant/src/lower/imports.rs: -------------------------------------------------------------------------------- 1 | use crate::hir; 2 | use crate::{util, HirDatabase}; 3 | use errors::FileId; 4 | use std::sync::Arc; 5 | 6 | use syntax::{AstNode, ImportSegmentOwner}; 7 | 8 | pub(crate) fn lower_import_query( 9 | db: &impl HirDatabase, 10 | file: FileId, 11 | import_id: hir::ImportId, 12 | ) -> Arc { 13 | let import = db.lookup_intern_import(import_id); 14 | let mut segments = Vec::new(); 15 | 16 | for segment in import.segments() { 17 | let name = segment.name().map(|name| name.into()); 18 | 19 | let name = util::Span::from_ast(db.intern_name(name.unwrap()), &segment.name().unwrap()); 20 | 21 | let nested_imports = Vec::new(); 22 | 23 | segments.push(hir::Segment { 24 | name, 25 | nested_imports, 26 | }); 27 | } 28 | 29 | if let Some(list) = import.import_list() { 30 | let index = segments.len() - 1; 31 | let last = &mut segments[index]; 32 | for segment in list.segments() { 33 | let name = segment.name().map(|name| name.into()); 34 | 35 | let name = db.intern_name(name.unwrap()); 36 | last.nested_imports 37 | .push(util::Span::from_ast(name, &segment.name().unwrap())); 38 | } 39 | } else if import.segments().count() > 1 { 40 | // only when we have import foo::something 41 | // get the last import 42 | assert!(segments.len() > 1); 43 | let actual_import = segments.pop().unwrap(); 44 | let index = segments.len() - 1; 45 | 46 | segments[index].nested_imports.push(actual_import.name); 47 | } 48 | 49 | let span = import.syntax().text_range(); 50 | 51 | Arc::new(hir::Import { 52 | segments, 53 | id: import_id, 54 | file, 55 | span, 56 | }) 57 | } 58 | -------------------------------------------------------------------------------- /semant/src/lower/module.rs: -------------------------------------------------------------------------------- 1 | use crate::hir; 2 | use crate::util::Span; 3 | use crate::HirDatabase; 4 | use errors::FileId; 5 | use std::sync::Arc; 6 | 7 | use syntax::{AstNode, NameOwner}; 8 | 9 | pub(crate) fn lower_module_query( 10 | db: &impl HirDatabase, 11 | file: FileId, 12 | mod_id: hir::ModuleId, 13 | ) -> Arc { 14 | let module = db.lookup_intern_module(mod_id); 15 | 16 | let name = module.name().unwrap(); 17 | let range = name.syntax().text_range(); 18 | let name_id = db.intern_name(name.into()); 19 | let name = Span::from_range(name_id, range); 20 | 21 | let span = module.syntax().text_range(); 22 | Arc::new(hir::Module { 23 | id: mod_id, 24 | file, 25 | name, 26 | span, 27 | }) 28 | } 29 | -------------------------------------------------------------------------------- /semant/src/resolver.rs: -------------------------------------------------------------------------------- 1 | mod alias; 2 | mod class; 3 | mod data; 4 | mod enums; 5 | mod escape; 6 | mod function; 7 | mod imports; 8 | mod module; 9 | mod module_graph; 10 | mod source_file; 11 | #[macro_use] 12 | #[cfg(test)] 13 | mod tests; 14 | 15 | pub use data::FunctionData; 16 | pub use data::Resolver; 17 | pub(crate) use data::TypeKind; 18 | pub(crate) use imports::resolve_imports_query; 19 | pub(crate) use module::resolve_modules_query; 20 | pub(crate) use module_graph::module_graph_query; 21 | pub(crate) use module_graph::ModuleGraph; 22 | pub(crate) use source_file::resolve_exports_query; 23 | pub(crate) use source_file::resolve_hir_type_query; 24 | pub(crate) use source_file::resolve_named_type_query; 25 | pub(crate) use source_file::resolve_source_file_query; 26 | 27 | #[macro_export] 28 | macro_rules! create_test { 29 | ($filename:ident ,is_err) => { 30 | $crate::__create_test!($filename, is_err); 31 | }; 32 | ($filename:ident ) => { 33 | $crate::__create_test!($filename, is_ok); 34 | }; 35 | } 36 | #[macro_export] 37 | macro_rules! __create_test { 38 | ($filename:ident,$kind:ident) => { 39 | #[test] 40 | fn $filename() -> std::io::Result<()> { 41 | use errors::db::FileDatabase; 42 | use $crate::HirDatabase; 43 | 44 | let dir = tempfile::tempdir()?; 45 | 46 | let structure = $crate::resolver::tests::load_file(&format!( 47 | "{}/src/resolver/tests/{}.ron", 48 | env!("CARGO_MANIFEST_DIR"), 49 | stringify!($filename) 50 | )); 51 | 52 | let mut file_names = Vec::new(); 53 | 54 | $crate::resolver::tests::create_structure(&dir.path(), &structure, &mut file_names)?; 55 | 56 | let db = $crate::resolver::tests::MockDatabaseImpl::default(); 57 | 58 | let handle = db.intern_file(file_names.remove(0)); 59 | 60 | assert!(db.resolve_source_file(handle).$kind()); 61 | Ok(()) 62 | } 63 | }; 64 | } 65 | -------------------------------------------------------------------------------- /semant/src/resolver/alias.rs: -------------------------------------------------------------------------------- 1 | use super::data::{ResolverDataCollector, TypeKind}; 2 | use crate::{hir::TypeAlias, infer::Type, HirDatabase}; 3 | 4 | impl<'a, DB> ResolverDataCollector<&'a DB> 5 | where 6 | DB: HirDatabase, 7 | { 8 | pub(crate) fn resolve_alias(&mut self, alias: &TypeAlias) -> Result<(), ()> { 9 | let name = alias.name; 10 | 11 | let mut poly_tvs = Vec::new(); 12 | 13 | self.begin_scope(); 14 | 15 | for type_param in &alias.type_params { 16 | let type_param = alias.ast_map.type_param(&type_param.item); 17 | 18 | let tv = self.ctx.type_var(); 19 | 20 | self.insert_type(&type_param.name, Type::Var(tv), TypeKind::Type); 21 | 22 | poly_tvs.push(tv) 23 | } 24 | 25 | let ty = self.resolve_type(&alias.ty); 26 | 27 | self.end_scope(); 28 | 29 | self.insert_type(&name, Type::Poly(poly_tvs, Box::new(ty)), TypeKind::Alias); 30 | 31 | if alias.exported { 32 | self.exported_items.insert(alias.name.item); 33 | } 34 | 35 | Ok(()) 36 | } 37 | } 38 | 39 | #[cfg(test)] 40 | mod test { 41 | use crate::create_test; 42 | create_test!(import_alias); 43 | } 44 | -------------------------------------------------------------------------------- /semant/src/resolver/escape.rs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lapz/tox/76df92fe9c1fe48a9831cdceb465673a29a3cd14/semant/src/resolver/escape.rs -------------------------------------------------------------------------------- /semant/src/resolver/tests/basic_class.ron: -------------------------------------------------------------------------------- 1 | DirectoryStructure ( 2 | contents: [ 3 | ( 4 | name:"main.tox", 5 | text: "class Foo { bar:i32;} class Bar { f:Foo;}" 6 | ) 7 | ] 8 | ) -------------------------------------------------------------------------------- /semant/src/resolver/tests/basic_enum.ron: -------------------------------------------------------------------------------- 1 | DirectoryStructure ( 2 | contents: [ 3 | ( 4 | name:"main.tox", 5 | text: "enum Foo {A(i32),B } enum Bar {Foo(Foo)}" 6 | ) 7 | ] 8 | ) -------------------------------------------------------------------------------- /semant/src/resolver/tests/enum_dup_variant.ron: -------------------------------------------------------------------------------- 1 | DirectoryStructure ( 2 | contents: [ 3 | ( 4 | name:"main.tox", 5 | text: "enum Foo {A,A}" 6 | ) 7 | ] 8 | ) -------------------------------------------------------------------------------- /semant/src/resolver/tests/exported_class.ron: -------------------------------------------------------------------------------- 1 | DirectoryStructure ( 2 | contents: [ 3 | ( 4 | name:"main.tox", 5 | text: "import foo::Bar; mod foo;fn main() {}" 6 | ), 7 | ( 8 | name:"foo.tox", 9 | text: "export class Bar {}" 10 | ) 11 | ] 12 | ) -------------------------------------------------------------------------------- /semant/src/resolver/tests/flat_structure.ron: -------------------------------------------------------------------------------- 1 | DirectoryStructure ( 2 | contents: [ 3 | ( 4 | name:"main.tox", 5 | text: "import foo::bar; fn main() {}" 6 | ), 7 | ( 8 | name:"foo.tox", 9 | text: "export fn bar() {}" 10 | ) 11 | ] 12 | ) -------------------------------------------------------------------------------- /semant/src/resolver/tests/import_alias.ron: -------------------------------------------------------------------------------- 1 | DirectoryStructure ( 2 | contents: [ 3 | ( 4 | name:"main.tox", 5 | text: "import foo::Foo; mod foo; type Bar = Foo; fn main() {}" 6 | ), 7 | ( 8 | name:"foo.tox", 9 | text: "export type Foo = i32; " 10 | ) 11 | ] 12 | ) -------------------------------------------------------------------------------- /semant/src/resolver/tests/import_deep.ron: -------------------------------------------------------------------------------- 1 | DirectoryStructure ( 2 | contents: [ 3 | ( 4 | name:"main.tox", 5 | text: "import foo::bar; mod foo; fn main() {}" 6 | ), 7 | ( 8 | name:"foo.tox", 9 | text: "mod bar; export fn bar() {} export fn baz() {}" 10 | ), 11 | ( 12 | name:"bar", 13 | kind: Dir, 14 | contents: Some( 15 | DirectoryStructure( 16 | contents:[ 17 | ( 18 | name:"bar.tox", 19 | text: "export fn bar() {}" 20 | ) 21 | ] 22 | ) 23 | ) 24 | ) 25 | ] 26 | ) -------------------------------------------------------------------------------- /semant/src/resolver/tests/import_deep_dirs.ron: -------------------------------------------------------------------------------- 1 | DirectoryStructure ( 2 | contents: [ 3 | ( 4 | name:"main.tox", 5 | text: "import foo::bar::bar; mod foo; fn main() {}" 6 | ), 7 | ( 8 | name:"foo", 9 | kind: Dir, 10 | contents: Some( 11 | DirectoryStructure( 12 | contents:[ 13 | ( 14 | name:"foo.tox", 15 | text: "mod bar; export fn bar() {}" 16 | ), 17 | ( 18 | name:"bar", 19 | kind: Dir, 20 | contents: Some( 21 | DirectoryStructure( 22 | contents:[ 23 | ( 24 | name:"bar.tox", 25 | text: "export fn bar() {}" 26 | ) 27 | ] 28 | ) 29 | ) 30 | ) 31 | ] 32 | ) 33 | ) 34 | ) 35 | ] 36 | ) -------------------------------------------------------------------------------- /semant/src/resolver/tests/import_dir_and_file.ron: -------------------------------------------------------------------------------- 1 | DirectoryStructure ( 2 | contents: [ 3 | ( 4 | name:"main.tox", 5 | text: "import foo::bar; mod foo; fn main() {}" 6 | ), 7 | ( 8 | name:"foo.tox", 9 | text: "mod foo; export fn bar() {} export fn baz() {}" 10 | ), 11 | ( 12 | name:"foo", 13 | kind: Dir, 14 | contents: Some( 15 | DirectoryStructure( 16 | contents:[ 17 | ( 18 | name:"foo.tox", 19 | text: "export fn bar() {}" 20 | ) 21 | ] 22 | ) 23 | ) 24 | ) 25 | ] 26 | ) -------------------------------------------------------------------------------- /semant/src/resolver/tests/import_fn_as_type.ron: -------------------------------------------------------------------------------- 1 | DirectoryStructure ( 2 | contents: [ 3 | ( 4 | name:"main.tox", 5 | text: "import foo::bar; mod foo; type Foo = bar; fn main() {}" 6 | ), 7 | ( 8 | name:"foo.tox", 9 | text: "export fn bar() {} " 10 | ) 11 | ] 12 | ) -------------------------------------------------------------------------------- /semant/src/resolver/tests/import_many.ron: -------------------------------------------------------------------------------- 1 | DirectoryStructure ( 2 | contents: [ 3 | ( 4 | name:"main.tox", 5 | text: "import foo::{bar,baz}; mod foo; fn main() {}" 6 | ), 7 | ( 8 | name:"foo.tox", 9 | text: "export fn bar() {} export fn baz() {}" 10 | ) 11 | ] 12 | ) -------------------------------------------------------------------------------- /semant/src/resolver/tests/import_no_exported.ron: -------------------------------------------------------------------------------- 1 | DirectoryStructure ( 2 | contents: [ 3 | ( 4 | name:"main.tox", 5 | text: "import foo::bar; mod foo; fn main() {}" 6 | ), 7 | ( 8 | name:"foo.tox", 9 | text: "fn bar() {}" 10 | ) 11 | ] 12 | ) -------------------------------------------------------------------------------- /semant/src/resolver/tests/import_single.ron: -------------------------------------------------------------------------------- 1 | DirectoryStructure ( 2 | contents: [ 3 | ( 4 | name:"main.tox", 5 | text: "import foo::bar; mod foo; fn main() {}" 6 | ), 7 | ( 8 | name:"foo.tox", 9 | text: "export fn bar() {}" 10 | ) 11 | ] 12 | ) -------------------------------------------------------------------------------- /semant/src/resolver/tests/recursive_enum.ron: -------------------------------------------------------------------------------- 1 | DirectoryStructure ( 2 | contents: [ 3 | ( 4 | name:"main.tox", 5 | text: "enum Foo {Foo(Foo) }" 6 | ) 7 | ] 8 | ) -------------------------------------------------------------------------------- /semant/src/resolver/tests/with_dir.ron: -------------------------------------------------------------------------------- 1 | DirectoryStructure( 2 | contents: [ 3 | ( 4 | name:"main.tox", 5 | text: "import foo::bar; fn main() {}" 6 | ), 7 | ( 8 | name:"foo.tox", 9 | text: "fn baz() {}" 10 | ), 11 | ( 12 | name:"foo", 13 | kind: Dir, 14 | contents: Some( 15 | DirectoryStructure( 16 | contents:[ 17 | ( 18 | name:"bar.tox", 19 | text: "export fn bar() {}" 20 | ) 21 | ] 22 | ) 23 | ) 24 | ) 25 | ] 26 | ) -------------------------------------------------------------------------------- /semant/src/util.rs: -------------------------------------------------------------------------------- 1 | use std::hash::Hash; 2 | use syntax::{AstNode, TextRange, TextUnit}; 3 | 4 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 5 | pub struct Span { 6 | pub item: T, 7 | pub start: TextUnit, 8 | pub end: TextUnit, 9 | } 10 | 11 | impl Span 12 | where 13 | T: std::fmt::Debug + Clone + Hash, 14 | { 15 | pub fn new(item: T, start: TextUnit, end: TextUnit) -> Self { 16 | Self { item, start, end } 17 | } 18 | 19 | pub fn from_ast(item: T, node: &N) -> Self { 20 | let range = node.syntax().text_range(); 21 | Span { 22 | item, 23 | start: range.start(), 24 | end: range.end(), 25 | } 26 | } 27 | 28 | pub fn from_range(item: T, range: TextRange) -> Self { 29 | Span { 30 | item, 31 | start: range.start(), 32 | end: range.end(), 33 | } 34 | } 35 | 36 | pub fn start(&self) -> TextUnit { 37 | self.start 38 | } 39 | 40 | pub fn end(&self) -> TextUnit { 41 | self.end 42 | } 43 | 44 | pub fn as_reporter_span(&self) -> (usize, usize) { 45 | (self.start.to_usize(), self.end.to_usize()) 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /syntax/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "syntax" 3 | version = "0.1.0" 4 | authors = ["Lenard Pratt "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | rowan = "0.9.0" 11 | itertools="*" 12 | errors = {path="../errors"} 13 | 14 | [dev-dependencies] 15 | insta = "0.16.0" 16 | tempfile = "3.1.0" 17 | -------------------------------------------------------------------------------- /syntax/src/lib.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | mod macros; 3 | #[rustfmt::skip] 4 | pub mod ast; 5 | mod lexer; 6 | 7 | mod ast_ext; 8 | mod token; 9 | mod traits; 10 | pub use ast::SyntaxKind; 11 | pub use lexer::Lexer; 12 | pub use rowan::{SmolStr, TextRange, TextUnit}; 13 | pub use token::Token; 14 | pub use traits::*; 15 | 16 | pub type SyntaxNode = rowan::SyntaxNode; 17 | #[allow(unused)] 18 | pub type SyntaxToken = rowan::SyntaxToken; 19 | #[allow(unused)] 20 | pub type SyntaxElement = rowan::NodeOrToken; 21 | 22 | pub type SyntaxNodeChildren = rowan::SyntaxNodeChildren; 23 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] 24 | pub enum ToxLang {} 25 | impl rowan::Language for ToxLang { 26 | type Kind = SyntaxKind; 27 | fn kind_from_raw(raw: rowan::SyntaxKind) -> Self::Kind { 28 | assert!(raw.0 <= SyntaxKind::__LAST as u16); 29 | unsafe { std::mem::transmute::(raw.0) } 30 | } 31 | fn kind_to_raw(kind: Self::Kind) -> rowan::SyntaxKind { 32 | kind.into() 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /syntax/src/token.rs: -------------------------------------------------------------------------------- 1 | use crate::ast::SyntaxKind; 2 | 3 | #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] 4 | pub struct Token { 5 | pub kind: SyntaxKind, 6 | pub len: u32, 7 | } 8 | 9 | impl Token { 10 | pub const fn new(kind: SyntaxKind, len: u32) -> Self { 11 | Token { kind, len } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/fail/assign/assign.tox: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let foo = true; 3 | foo(); //error: `foo` is not callable 4 | } 5 | -------------------------------------------------------------------------------- /tests/fail/assign/bool.tox: -------------------------------------------------------------------------------- 1 | fn main() { 2 | true(); //error: Not callable 3 | } -------------------------------------------------------------------------------- /tests/fail/assign/grouping.tox: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let a = "a"; 3 | (a) = "value"; // error: Not a valid assingment target 4 | } -------------------------------------------------------------------------------- /tests/fail/assign/infix_operator.tox: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let a = "a"; 3 | let b = "b"; 4 | a + b = "value"; //error: Not a valid assingment target 5 | } -------------------------------------------------------------------------------- /tests/fail/assign/prefix_operator.tox: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let a = "a"; 3 | !a = "value"; //error: Not a valid assingment target 4 | } -------------------------------------------------------------------------------- /tests/fail/assign/to_this.tox: -------------------------------------------------------------------------------- 1 | class Foo { 2 | fn Foo(this:Foo) { 3 | this = "value"; //error: Cannot unify `Class Foo` vs `Str` 4 | } 5 | } 6 | 7 | fn main() { 8 | Foo(); 9 | } -------------------------------------------------------------------------------- /tests/fail/assign/undefined.tox: -------------------------------------------------------------------------------- 1 | fn main() { 2 | unknown = "what"; //error: Undefined variable 'unknown' 3 | } -------------------------------------------------------------------------------- /tests/fail/call/nil.tox: -------------------------------------------------------------------------------- 1 | fn main() { 2 | nil(); //error: Not callable 3 | } -------------------------------------------------------------------------------- /tests/fail/call/num.tox: -------------------------------------------------------------------------------- 1 | fn main() { 2 | 123 (); //Can only call functions and classes. 3 | } -------------------------------------------------------------------------------- /tests/fail/call/object.tox: -------------------------------------------------------------------------------- 1 | class Foo {} 2 | 3 | fn main() { 4 | let foo = Foo{}; 5 | foo(); //error: `foo` is not callable 6 | } -------------------------------------------------------------------------------- /tests/fail/call/string.tox: -------------------------------------------------------------------------------- 1 | fn main() { 2 | "str" (); //error: Not callable 3 | } -------------------------------------------------------------------------------- /tests/fail/cast/boolean2float.tox: -------------------------------------------------------------------------------- 1 | 2 | 3 | fn main() { 4 | print true as float;//error: Cannot cast `bool` to type `float` 5 | } -------------------------------------------------------------------------------- /tests/fail/cast/boolean2str.tox: -------------------------------------------------------------------------------- 1 | 2 | 3 | fn main() { 4 | print true as str;//error: Cannot cast `bool` to type `str` 5 | } -------------------------------------------------------------------------------- /tests/fail/constructor/missing_arguments.tox: -------------------------------------------------------------------------------- 1 | class Foo { 2 | a:int,b:int; 3 | 4 | fn init(a:int, b:int) -> Foo { 5 | return Foo {a:a,b:b}; 6 | } 7 | } 8 | 9 | fn main() { 10 | let foo = Foo.init(1); //error: Expected `2` args found `1` 11 | } -------------------------------------------------------------------------------- /tests/fail/enum/mising_inner.tox: -------------------------------------------------------------------------------- 1 | enum List { 2 | Head(int), 3 | Tail 4 | } 5 | 6 | fn main() { 7 | let foo = List::Tail(10); 8 | } -------------------------------------------------------------------------------- /tests/fail/enum/unify.tox: -------------------------------------------------------------------------------- 1 | enum List { 2 | Head(int), 3 | Tail 4 | } 5 | 6 | enum List2 { 7 | Head(int), 8 | Tail 9 | } 10 | 11 | fn main() { 12 | let foo:List = List2::Tail; 13 | } -------------------------------------------------------------------------------- /tests/fail/print/missing_argument.tox: -------------------------------------------------------------------------------- 1 | fn main() { 2 | print;//error: No rules expected ';' 3 | } -------------------------------------------------------------------------------- /tests/pass/assign/associativity.tox: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let a = "a"; 3 | let b = "b"; 4 | let c = "c"; 5 | 6 | // Assignment is right-associative. 7 | a = b = c; 8 | print(a); // expect:c 9 | print(b); // expect:c 10 | print(c); // expect:c 11 | } -------------------------------------------------------------------------------- /tests/pass/assign/global.tox: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let a = "before"; 3 | print(a); // expect:before 4 | 5 | a = "after"; 6 | print(a); // expect:after 7 | 8 | print(a = "arg"); // expect:arg 9 | print(a); // expect:arg 10 | } -------------------------------------------------------------------------------- /tests/pass/assign/local.tox: -------------------------------------------------------------------------------- 1 | fn main() { 2 | { 3 | let a = "before"; 4 | print a; // expect:before 5 | 6 | a = "after"; 7 | print a; // expect:after 8 | 9 | a = "arg"; 10 | print(a); // expect:arg 11 | } 12 | } -------------------------------------------------------------------------------- /tests/pass/assign/local_reference_self.tox: -------------------------------------------------------------------------------- 1 | class Foo { 2 | fn returnSelf() -> Foo { 3 | return Foo {}; 4 | } 5 | } 6 | 7 | fn main() { 8 | print(Foo{}.returnSelf()); // expect:instance 9 | } 10 | -------------------------------------------------------------------------------- /tests/pass/assign/reassignment.tox: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let a = 10; 3 | a = "a"; // expect:Expected type 'Int' but instead got 'Str' on line 2,column 3 4 | } -------------------------------------------------------------------------------- /tests/pass/assign/scope.tox: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let a = "outer"; 3 | 4 | { 5 | let a = "inner"; 6 | print(a); // expect:inner 7 | } 8 | 9 | print(a); // expect:outer 10 | } -------------------------------------------------------------------------------- /tests/pass/assign/syntax.tox: -------------------------------------------------------------------------------- 1 | fn main() { 2 | // Assignment on RHS of variable. 3 | let a = "before"; 4 | let c = a = "let"; 5 | print(a); // expect:let 6 | print(c); // expect:let 7 | } -------------------------------------------------------------------------------- /tests/pass/benchmark/binary_trees.tox: -------------------------------------------------------------------------------- 1 | //skip 2 | class Tree { 3 | item:T,depth:int; 4 | fn init(item, depth) -> Tree { 5 | this.item = item; 6 | this.depth = depth; 7 | if (depth > 0) { 8 | let item2 = item + item; 9 | depth = depth - 1; 10 | this.left = Tree(item2 - 1, depth); 11 | this.right = Tree(item2, depth); 12 | } else { 13 | this.left = nil; 14 | this.right = nil; 15 | } 16 | } 17 | 18 | fn check(this:Tree) { 19 | if (this.left == nil) { 20 | return this.item; 21 | } 22 | 23 | return this.item + this 24 | .left 25 | .check() - this 26 | .right 27 | .check(); 28 | } 29 | } 30 | 31 | let minDepth = 4; 32 | let maxDepth = 12; 33 | let stretchDepth = maxDepth + 1; 34 | 35 | let start = clock(); 36 | 37 | print("stretch tree of depth:"); 38 | print(stretchDepth); 39 | print("check:"); 40 | print(Tree(0, stretchDepth).check()); 41 | 42 | let longLivedTree = Tree(0, maxDepth); 43 | 44 | // iterations = 2 ** maxDepth 45 | let iterations = 1; 46 | let d = 0; 47 | while (d < maxDepth) { 48 | iterations = iterations * 2; 49 | d = d + 1; 50 | } 51 | 52 | let depth = minDepth; 53 | while (depth < stretchDepth) { 54 | let check = 0; 55 | let i = 1; 56 | while (i <= iterations) { 57 | check = check + Tree(i, depth).check() + Tree(-i, depth).check(); 58 | i = i + 1; 59 | } 60 | 61 | print("num trees:"); 62 | print(iterations * 2); 63 | print("depth:"); 64 | print(depth); 65 | print("check:"); 66 | print(check); 67 | 68 | iterations = iterations / 4; 69 | depth = depth + 2; 70 | } 71 | 72 | print("long lived tree of depth:"); 73 | print(maxDepth); 74 | print("check:"); 75 | print(longLivedTree.check()); 76 | print("elapsed:"); 77 | print(clock() - start); 78 | -------------------------------------------------------------------------------- /tests/pass/benchmark/equality.tox: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lapz/tox/76df92fe9c1fe48a9831cdceb465673a29a3cd14/tests/pass/benchmark/equality.tox -------------------------------------------------------------------------------- /tests/pass/benchmark/fib.tox: -------------------------------------------------------------------------------- 1 | fn fib(n:int) -> int { 2 | if (n < 2) { 3 | return n; 4 | }else { 5 | return fib(n - 2) + fib(n - 1); 6 | } 7 | 8 | } 9 | 10 | fn main() { 11 | let start = clock(); 12 | print(fib(30) == 832040); // expect:true 13 | print(clock() - start); 14 | return; 15 | } -------------------------------------------------------------------------------- /tests/pass/benchmark/invocation.tox: -------------------------------------------------------------------------------- 1 | // This benchmark stresses just method invocation. 2 | 3 | class Foo { 4 | fn method0() {} 5 | fn method1() {} 6 | fn method2() {} 7 | fn method3() {} 8 | fn method4() {} 9 | fn method5() {} 10 | fn method6() {} 11 | fn method7() {} 12 | fn method8() {} 13 | fn method9() {} 14 | fn method10() {} 15 | fn method11() {} 16 | fn method12() {} 17 | fn method13() {} 18 | fn method14() {} 19 | fn method15() {} 20 | fn method16() {} 21 | fn method17() {} 22 | fn method18() {} 23 | fn method19() {} 24 | fn method20() {} 25 | fn method21() {} 26 | fn method22() {} 27 | fn method23() {} 28 | fn method24() {} 29 | fn method25() {} 30 | fn method26() {} 31 | fn method27() {} 32 | fn method28() {} 33 | fn method29() {} 34 | } 35 | 36 | fn main() { 37 | let foo = Foo{}; 38 | let start = clock(); 39 | let i = 0; 40 | while (i < 500000) { 41 | foo.method0(); 42 | foo.method1(); 43 | foo.method2(); 44 | foo.method3(); 45 | foo.method4(); 46 | foo.method5(); 47 | foo.method6(); 48 | foo.method7(); 49 | foo.method8(); 50 | foo.method9(); 51 | foo.method10(); 52 | foo.method11(); 53 | foo.method12(); 54 | foo.method13(); 55 | foo.method14(); 56 | foo.method15(); 57 | foo.method16(); 58 | foo.method17(); 59 | foo.method18(); 60 | foo.method19(); 61 | foo.method20(); 62 | foo.method21(); 63 | foo.method22(); 64 | foo.method23(); 65 | foo.method24(); 66 | foo.method25(); 67 | foo.method26(); 68 | foo.method27(); 69 | foo.method28(); 70 | foo.method29(); 71 | i = i + 1; 72 | } 73 | 74 | print(clock() - start); 75 | } 76 | -------------------------------------------------------------------------------- /tests/pass/boolean/empty.tox: -------------------------------------------------------------------------------- 1 | fn main() { 2 | {} // By itself. 3 | 4 | // In a statement. 5 | if (true) {} 6 | if (false) {} else {} 7 | 8 | print("ok"); // expect:ok 9 | } -------------------------------------------------------------------------------- /tests/pass/boolean/equality.tox: -------------------------------------------------------------------------------- 1 | fn main () { 2 | print(true == true); // expect:true 3 | print(true == false); // expect:false 4 | print(false == true); // expect:false 5 | print(false == false); // expect:true 6 | 7 | // Not equal to other types. 8 | print(true == 1); // expect:false 9 | print(false == 0); // expect:false 10 | print(true == "true"); // expect:false 11 | print(false == "false"); // expect:false 12 | print(false == ""); // expect:false 13 | 14 | print(true != true); // expect:false 15 | print(true != false); // expect:true 16 | print(false != true); // expect:true 17 | print(false != false); // expect:false 18 | 19 | // Not equal to other types 20 | print(true != "true"); // expect:true 21 | print(false != "false"); // expect:true 22 | print(false != ""); // expect:true 23 | } -------------------------------------------------------------------------------- /tests/pass/boolean/not.tox: -------------------------------------------------------------------------------- 1 | fn main() { 2 | print(!true); // expect:false 3 | print(!false); // expect:true 4 | print(!!true); // expect:true 5 | } -------------------------------------------------------------------------------- /tests/pass/cast/boolean.tox: -------------------------------------------------------------------------------- 1 | 2 | fn main() { 3 | let t = true; 4 | let f = false; 5 | 6 | print t as int; // expect:1 7 | print f as int; // expect:0 8 | 9 | } -------------------------------------------------------------------------------- /tests/pass/cast/float2int.tox: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let cal = 1/3 as float; 3 | print cal;// expect:0 4 | 5 | let cal = 5.0/3.0; 6 | print cal;// expect:1.6666666666666667 7 | 8 | print cal as int;// expect:1 9 | } -------------------------------------------------------------------------------- /tests/pass/cast/float2str.tox: -------------------------------------------------------------------------------- 1 | 2 | 3 | fn main() { 4 | print 1.3330 as str;// expect:1.333 5 | } -------------------------------------------------------------------------------- /tests/pass/cast/int2str.tox: -------------------------------------------------------------------------------- 1 | 2 | 3 | fn main() { 4 | print 1 as str;// expect:1 5 | } -------------------------------------------------------------------------------- /tests/pass/class/empty.tox: -------------------------------------------------------------------------------- 1 | class Foo {} 2 | 3 | fn main() { 4 | print(Foo{}); // expect:instance 5 | } -------------------------------------------------------------------------------- /tests/pass/class/inherited_method.tox: -------------------------------------------------------------------------------- 1 | class Foo { 2 | fn inFoo() { 3 | print("in foo"); 4 | } 5 | } 6 | 7 | class Bar extends Foo { 8 | fn inBar() { 9 | print("in bar"); 10 | 11 | } 12 | } 13 | 14 | class Baz extends Bar { 15 | fn init() -> Baz { 16 | return Baz {}; 17 | } 18 | fn inBaz() { 19 | print("in baz"); 20 | 21 | } 22 | } 23 | 24 | fn main() { 25 | let baz = Baz.init(); 26 | baz.inFoo(); // expect:in foo 27 | baz.inBar(); // expect:in bar 28 | baz.inBaz(); // expect:in baz 29 | } -------------------------------------------------------------------------------- /tests/pass/comments/line_at_eof.tox: -------------------------------------------------------------------------------- 1 | fn main() { 2 | print("ok"); // expect:ok 3 | // comment 4 | } -------------------------------------------------------------------------------- /tests/pass/comments/only_line_comment.tox: -------------------------------------------------------------------------------- 1 | fn main() { 2 | // comment 3 | } -------------------------------------------------------------------------------- /tests/pass/comments/only_line_comment_and_line.tox: -------------------------------------------------------------------------------- 1 | fn main() { 2 | // comment 3 | 4 | } -------------------------------------------------------------------------------- /tests/pass/comments/unicode.tox: -------------------------------------------------------------------------------- 1 | fn main() { 2 | // Unicode characters are allowed in comments. 3 | // 4 | // Latin 1 Supplement: £§¶ÜÞ Latin Extended-A: ĐĦŋœ Latin Extended-B: ƂƢƩǁ Other 5 | // stuff: ឃᢆ᯽₪ℜ↩⊗┺░ Emoji: ☃☺♣ 6 | 7 | print("ok"); // expect:ok 8 | } -------------------------------------------------------------------------------- /tests/pass/constructor/arguments.tox: -------------------------------------------------------------------------------- 1 | class Foo { 2 | a:int,b:int; 3 | fn init(a:int, b:int) -> Foo { 4 | print("init"); // expect:init 5 | return Foo {a:a,b:b}; 6 | } 7 | } 8 | 9 | fn main() { 10 | let foo = Foo.init(1,2); 11 | print(foo.a); // expect:1 12 | print(foo.b); // expect:2 13 | } -------------------------------------------------------------------------------- /tests/pass/constructor/default.tox: -------------------------------------------------------------------------------- 1 | class Foo {} 2 | 3 | fn main() { 4 | let foo = Foo {}; 5 | print(foo); // expect:instance 6 | } -------------------------------------------------------------------------------- /tests/pass/constructor/early_return.tox: -------------------------------------------------------------------------------- 1 | class Foo { 2 | fn init() -> Foo { 3 | print("init"); 4 | return Foo{}; 5 | print("nope"); 6 | } 7 | } 8 | 9 | fn main() { 10 | let foo = Foo.init(); // expect:init 11 | print(foo); // expect:instance 12 | } -------------------------------------------------------------------------------- /tests/pass/constructor/extra_arguments.tox: -------------------------------------------------------------------------------- 1 | class Foo { 2 | a:int,b:int; 3 | fn init(a:int, b:int) -> Foo{ 4 | print("init"); // expect:init 5 | return Foo {a:a,b:b}; 6 | } 7 | } 8 | 9 | fn main() { 10 | let foo = Foo.init(1, 2); 11 | print(foo.a); // expect:1 12 | print(foo.b); // expect:2 13 | } -------------------------------------------------------------------------------- /tests/pass/enums/basic.tox: -------------------------------------------------------------------------------- 1 | enum Foo { 2 | Fizz, 3 | Bar 4 | } 5 | 6 | fn main() { 7 | 8 | } -------------------------------------------------------------------------------- /tests/pass/enums/basic_item_name.tox: -------------------------------------------------------------------------------- 1 | enum Result { 2 | Ok(T), 3 | Err(E) 4 | } 5 | 6 | 7 | fn me() -> Result { 8 | if true { 9 | return Result::Ok(1); 10 | } 11 | return Result::Err("You are not a person"); 12 | } 13 | fn main() { 14 | let res = me(); 15 | 16 | print res; 17 | 18 | } -------------------------------------------------------------------------------- /tests/pass/enums/data.tox: -------------------------------------------------------------------------------- 1 | enum List { 2 | Head(List), 3 | Tail 4 | } 5 | 6 | 7 | fn main() { 8 | let list = List::Head(List::Head(List::Tail)); 9 | } -------------------------------------------------------------------------------- /tests/pass/enums/match.tox: -------------------------------------------------------------------------------- 1 | enum Day { 2 | Monday, 3 | Tuesday, 4 | Wednesday, 5 | Thursday, 6 | Friday, 7 | Saturday, 8 | Sunday 9 | } 10 | 11 | 12 | fn main() { 13 | 14 | let today = Day::Monday; 15 | let tomorrow = Day::Tuesday; 16 | 17 | match today { 18 | Day::Monday => { 19 | print "today is monday"; 20 | }, 21 | Day::Tuesday => { 22 | print "today is tuesday"; 23 | }, 24 | _ => { 25 | print "today is not monday"; 26 | } 27 | }; 28 | } -------------------------------------------------------------------------------- /tests/pass/enums/usage.tox: -------------------------------------------------------------------------------- 1 | enum Day { 2 | Monday, 3 | Tuesday, 4 | Wednesday, 5 | Thursday, 6 | Friday, 7 | Saturday, 8 | Sunday 9 | } 10 | 11 | 12 | fn main() { 13 | 14 | let today = Day::Monday; 15 | let tomorrow = Day::Tuesday; 16 | 17 | print today; 18 | print tomorrow; 19 | 20 | print today == tomorrow; 21 | print today != tomorrow; 22 | } -------------------------------------------------------------------------------- /tests/pass/expressions/evaluate.tox: -------------------------------------------------------------------------------- 1 | // Note: This is just for the expression evaluating chapter which evaluates an 2 | // expression directly. 3 | fn main() { 4 | print (5 - (3 - 1)) + -1;// expect:2 5 | } -------------------------------------------------------------------------------- /tests/pass/float/literals.tox: -------------------------------------------------------------------------------- 1 | fn main() { 2 | print 123; // expect:123 3 | print 987654; // expect:987654 4 | print 0; // expect:0 5 | print -0; // expect:-0 6 | 7 | print 123.456; // expect:123.456 8 | print -0.001; // expect:-0.001 9 | 10 | } -------------------------------------------------------------------------------- /tests/pass/match/assign_match.tox: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let name = "Lenard"; 3 | let x =10; 4 | 5 | let admin = match name { 6 | "Lenard" => "yes", 7 | "Rust" => "no" 8 | }; 9 | 10 | 11 | print admin;// expect:yes 12 | } -------------------------------------------------------------------------------- /tests/pass/match/assign_match_all.tox: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let name = "Lenards"; 3 | 4 | let admin = match name { 5 | "Lenard" => "yes", 6 | "Rust" => "no", 7 | _ => "other", 8 | _ => "negro" 9 | }; 10 | 11 | print admin;// expect:other 12 | } -------------------------------------------------------------------------------- /tests/pass/match/empty_match.tox: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let a = 10; 3 | 4 | match a { 5 | 6 | }; 7 | } -------------------------------------------------------------------------------- /tests/test.tox: -------------------------------------------------------------------------------- 1 | fn fib(n:i32) -> i32 { 2 | if (n < 2) 3 | return n; 4 | return fib(n - 2) + fib(n - 1); 5 | } -------------------------------------------------------------------------------- /tools/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "tools" 3 | version = "0.1.0" 4 | authors = ["Lenard Pratt "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | teraron = "0.1.0" 11 | structopt = "0.3" -------------------------------------------------------------------------------- /tools/src/cli.rs: -------------------------------------------------------------------------------- 1 | use std::path::PathBuf; 2 | use structopt::StructOpt; 3 | #[derive(StructOpt, Debug)] 4 | #[structopt(name = "tox")] 5 | pub struct Cli { 6 | /// The source code file to be ran 7 | pub source: Option, 8 | /// The template file where the ast/ir will be outputted 9 | #[structopt(short, long, parse(from_os_str))] 10 | pub template: PathBuf, 11 | #[structopt(short, long, parse(from_os_str))] 12 | /// The output destination of the template 13 | pub grammar: PathBuf, 14 | /// Output the ast tokens to stdout or the file provided 15 | /// by output 16 | #[structopt(short, long)] 17 | pub syntax: bool, 18 | } 19 | 20 | pub enum Commands { 21 | GenAst, 22 | } 23 | -------------------------------------------------------------------------------- /tools/src/main.rs: -------------------------------------------------------------------------------- 1 | mod cli; 2 | use cli::{Cli, Commands}; 3 | use structopt::StructOpt as _; 4 | 5 | fn generate_syntax( 6 | template: &std::path::Path, 7 | grammar: &std::path::Path, 8 | ) -> Result<(), Box> { 9 | teraron::generate(template, grammar, teraron::Mode::Overwrite) 10 | } 11 | 12 | fn main() -> Result<(), Box> { 13 | let opts = Cli::from_args(); 14 | 15 | let command = if opts.syntax { 16 | Commands::GenAst 17 | } else { 18 | return Err("The only command available is to generate the ast".into()); 19 | }; 20 | 21 | let template = opts.template; 22 | 23 | let grammar = opts.grammar; 24 | 25 | match command { 26 | Commands::GenAst => generate_syntax(&template, &grammar)?, 27 | } 28 | 29 | Ok(()) 30 | } 31 | -------------------------------------------------------------------------------- /tox-wasm/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "tox-wasm" 3 | version = "0.1.0" 4 | authors = ["Lenard Pratt "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | salsa ="^0.14.1" 11 | syntax={path="../syntax",version="*"} 12 | errors= {path="../errors",version="*"} 13 | parser={path="../parser",version="*"} 14 | semant = {path="../semant"} 15 | reporting = {version="^0.9.0",package="codespan-reporting"} 16 | wasm-bindgen="*" 17 | console_error_panic_hook = "0.1.6" 18 | [lib] 19 | crate-type = ["cdylib"] 20 | 21 | 22 | -------------------------------------------------------------------------------- /tox/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lapz/tox/76df92fe9c1fe48a9831cdceb465673a29a3cd14/tox/.DS_Store -------------------------------------------------------------------------------- /tox/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "tox" 3 | version = "0.1.0" 4 | authors = ["Lenard Pratt "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | [dependencies] 9 | salsa ="^0.14.1" 10 | structopt = "0.3" 11 | syntax={path="../syntax",version="*"} 12 | errors= {path="../errors",version="*"} 13 | parser={path="../parser",version="*"} 14 | semant = {path="../semant"} 15 | codegen = {path="../codegen"} 16 | reporting = {version="^0.9.0",package="codespan-reporting"} 17 | tracing = "^0.1.22" 18 | tracing-subscriber = "0.2" 19 | tracing-tree = "0.1.6" 20 | [dev-dependencies] 21 | insta = "0.16.0" 22 | serde ="1.0.106" 23 | ron = "0.5.1" 24 | tempfile = "3.1.0" 25 | walkdir = "2" 26 | -------------------------------------------------------------------------------- /tox/src/bar/bar.tox: -------------------------------------------------------------------------------- 1 | fn foo() {} 2 | 3 | 4 | export fn bar() { 5 | 6 | } 7 | 8 | export class Foo { 9 | bar:i32; 10 | }; -------------------------------------------------------------------------------- /tox/src/foo.tox: -------------------------------------------------------------------------------- 1 | mod bar; 2 | 3 | fn Struct() {} -------------------------------------------------------------------------------- /tox/src/main.rs: -------------------------------------------------------------------------------- 1 | mod cli; 2 | mod db; 3 | use crate::cli::Cli; 4 | use structopt::StructOpt as _; 5 | use tracing_subscriber::{prelude::*, Registry}; 6 | use tracing_tree::HierarchicalLayer; 7 | pub type ParseResult = Result; 8 | 9 | fn main() -> std::io::Result<()> { 10 | let opt = Cli::from_args(); 11 | 12 | if opt.trace { 13 | let subscriber = Registry::default().with(HierarchicalLayer::new(2)); 14 | tracing::subscriber::set_global_default(subscriber).unwrap(); 15 | } 16 | 17 | opt.run()?; 18 | 19 | Ok(()) 20 | } 21 | -------------------------------------------------------------------------------- /tox/src/test.tox: -------------------------------------------------------------------------------- 1 | fn main() ->bool{ 2 | let a = 10; 3 | let b = 20; 4 | a+=10; 5 | return a <= b; 6 | } 7 | -------------------------------------------------------------------------------- /tox/src/test.tox.asm: -------------------------------------------------------------------------------- 1 | .text 2 | .globl _main 3 | _main: 4 | push %rbp 5 | mov %rsp, %rbp 6 | sub $16, %rsp 7 | # span (23, 27) 8 | mov $1092616192, %eax # float 10 9 | movq %rax, %xmm0 10 | popq %rbp 11 | ret 12 | --------------------------------------------------------------------------------