├── .github ├── ISSUE_TEMPLATE │ ├── 01_bug_report.yml │ ├── 02_feature_request.yml │ └── config.yml └── workflows │ └── rust.yml ├── .gitignore ├── CONTRIBUTING.md ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md ├── core ├── README.md ├── manifest.toml └── src │ ├── fmt.capy │ ├── libc.capy │ ├── math.capy │ ├── mem.capy │ ├── meta.capy │ ├── mod.capy │ ├── ptr.capy │ └── structs │ ├── list.capy │ └── string_builder.capy ├── crates ├── ast │ ├── Cargo.toml │ └── src │ │ ├── lib.rs │ │ └── validation.rs ├── capy │ ├── Cargo.toml │ └── src │ │ ├── git.rs │ │ ├── main.rs │ │ └── source.rs ├── capy_macros │ ├── Cargo.toml │ └── src │ │ └── lib.rs ├── codegen │ ├── .gitignore │ ├── Cargo.toml │ └── src │ │ ├── builtin.rs │ │ ├── compiler │ │ ├── comptime.rs │ │ ├── functions.rs │ │ ├── mod.rs │ │ ├── program.rs │ │ └── ty_info.rs │ │ ├── convert.rs │ │ ├── convert │ │ └── abi │ │ │ ├── aarch64.rs │ │ │ ├── mod.rs │ │ │ ├── simplified.rs │ │ │ ├── x86_64.rs │ │ │ └── x86_64_windows.rs │ │ ├── extend.rs │ │ ├── layout.rs │ │ ├── lib.rs │ │ └── mangle.rs ├── diagnostics │ ├── Cargo.toml │ └── src │ │ └── lib.rs ├── hir │ ├── Cargo.toml │ └── src │ │ ├── body.rs │ │ ├── index.rs │ │ ├── lib.rs │ │ ├── subdir.rs │ │ └── world_index.rs ├── hir_ty │ ├── Cargo.toml │ └── src │ │ ├── globals.rs │ │ ├── lib.rs │ │ └── ty.rs ├── interner │ ├── Cargo.toml │ └── src │ │ └── lib.rs ├── lexer │ ├── Cargo.toml │ ├── build.rs │ └── src │ │ └── lib.rs ├── line_index │ ├── Cargo.toml │ └── src │ │ └── lib.rs ├── parser │ ├── Cargo.toml │ ├── build.rs │ └── src │ │ ├── error.rs │ │ ├── event.rs │ │ ├── grammar.rs │ │ ├── grammar │ │ ├── expr.rs │ │ └── stmt.rs │ │ ├── lib.rs │ │ ├── parser.rs │ │ ├── parser │ │ └── marker.rs │ │ ├── sink.rs │ │ ├── tests.rs │ │ ├── tests │ │ ├── repl_line │ │ │ ├── 2_var_defs.test │ │ │ ├── array_decl.test │ │ │ ├── array_decl_no_size.test │ │ │ ├── array_decl_no_type.test │ │ │ ├── array_decl_open.test │ │ │ ├── array_decl_safe_rbrace.test │ │ │ ├── array_lit_empty.test │ │ │ ├── array_lit_empty_comma.test │ │ │ ├── array_lit_end_at_comma.test │ │ │ ├── array_lit_open_eof.test │ │ │ ├── array_lit_open_random.test │ │ │ ├── array_lit_open_semicolon.test │ │ │ ├── array_lit_untyped.test │ │ │ ├── array_lit_with_values.test │ │ │ ├── array_missing_dot.test │ │ │ ├── array_old_syntax.test │ │ │ ├── bin_literal.test │ │ │ ├── bin_literal_multiplication.test │ │ │ ├── binary_cmp.test │ │ │ ├── binary_cmp_complex.test │ │ │ ├── binary_expr_left_assoc.test │ │ │ ├── binary_expr_mixed_assoc.test │ │ │ ├── binary_expr_paren.test │ │ │ ├── binary_expr_with_unary.test │ │ │ ├── binary_expr_without_rhs.test │ │ │ ├── block.test │ │ │ ├── block_end_at_open_eof.test │ │ │ ├── block_end_at_open_random.test │ │ │ ├── block_end_at_open_semicolon.test │ │ │ ├── block_lots_of_semicolons.test │ │ │ ├── block_multiple_stmts.test │ │ │ ├── block_nested.test │ │ │ ├── block_single_stmt.test │ │ │ ├── block_unclosed.test │ │ │ ├── block_with_inner_error.test │ │ │ ├── break_continue.test │ │ │ ├── break_continue_label.test │ │ │ ├── break_continue_with_val.test │ │ │ ├── call.test │ │ │ ├── call_end_at_comma.test │ │ │ ├── call_end_at_open_eof.test │ │ │ ├── call_end_at_open_semicolon.test │ │ │ ├── call_nested.test │ │ │ ├── call_with_args.test │ │ │ ├── cast.test │ │ │ ├── cast_array.test │ │ │ ├── cast_better_ptr.test │ │ │ ├── cast_better_ptr_nested.test │ │ │ ├── cast_empty.test │ │ │ ├── cast_nested.test │ │ │ ├── cast_no_type.test │ │ │ ├── cast_ptr.test │ │ │ ├── cast_ptr_nested.test │ │ │ ├── cast_unary_expr.test │ │ │ ├── char.test │ │ │ ├── char_no_close.test │ │ │ ├── char_with_quote_escape.test │ │ │ ├── comment.test │ │ │ ├── comptime_block.test │ │ │ ├── comptime_expr.test │ │ │ ├── defer.test │ │ │ ├── defer_missing.test │ │ │ ├── empty.test │ │ │ ├── empty_block.test │ │ │ ├── empty_char.test │ │ │ ├── empty_lambda.test │ │ │ ├── empty_string.test │ │ │ ├── enum_empty.test │ │ │ ├── enum_end_at_enum.test │ │ │ ├── enum_end_at_open_eof.test │ │ │ ├── enum_end_at_open_random.test │ │ │ ├── enum_end_at_open_semicolon.test │ │ │ ├── enum_multiple_variants.test │ │ │ ├── enum_one_discriminant_variant.test │ │ │ ├── enum_one_empty_variant.test │ │ │ ├── enum_one_typed_variant.test │ │ │ ├── hex_literal_addition.test │ │ │ ├── hex_literal_lowercase.test │ │ │ ├── hex_literal_mix.test │ │ │ ├── hex_literal_uppercase.test │ │ │ ├── import.test │ │ │ ├── import_old.test │ │ │ ├── index_ref_with_num.test │ │ │ ├── index_ref_with_ref.test │ │ │ ├── int_literal.test │ │ │ ├── int_literal_addition.test │ │ │ ├── int_literal_division.test │ │ │ ├── int_literal_with_e.test │ │ │ ├── label.test │ │ │ ├── label_end_at_backtick.test │ │ │ ├── label_end_at_colon.test │ │ │ ├── label_end_at_name.test │ │ │ ├── label_if.test │ │ │ ├── label_loop.test │ │ │ ├── lambda_comma_at_end.test │ │ │ ├── lambda_end_at_arrow.test │ │ │ ├── lambda_end_at_comma.test │ │ │ ├── lambda_end_at_open_eof.test │ │ │ ├── lambda_end_at_return_ty.test │ │ │ ├── lambda_end_at_rparen.test │ │ │ ├── lambda_extern.test │ │ │ ├── lambda_multiple_params.test │ │ │ ├── lambda_one_param.test │ │ │ ├── lambda_second_variadic.test │ │ │ ├── lambda_single_variadic.test │ │ │ ├── lambda_with_return_type.test │ │ │ ├── loop.test │ │ │ ├── member.test │ │ │ ├── member_end_at_dot.test │ │ │ ├── member_on_expr.test │ │ │ ├── mod.test │ │ │ ├── mod_old.test │ │ │ ├── mut_eof.test │ │ │ ├── mut_expr.test │ │ │ ├── mut_foo.test │ │ │ ├── mut_rawptr.test │ │ │ ├── no_semicolon_block.test │ │ │ ├── no_semicolon_comptime.test │ │ │ ├── no_semicolon_if.test │ │ │ ├── no_semicolon_while.test │ │ │ ├── paren.test │ │ │ ├── paren_empty.test │ │ │ ├── paren_end_at_open_random.test │ │ │ ├── paren_end_at_open_semicolon.test │ │ │ ├── paren_ident.test │ │ │ ├── quick_assign.test │ │ │ ├── quick_assign_end_at_equals.test │ │ │ ├── ref.test │ │ │ ├── return.test │ │ │ ├── semicolons_after.test │ │ │ ├── semicolons_before.test │ │ │ ├── semicolons_between.test │ │ │ ├── single_rbrace.test │ │ │ ├── string.test │ │ │ ├── string_no_close.test │ │ │ ├── string_with_quote_escape.test │ │ │ ├── struct_empty.test │ │ │ ├── struct_end_at_open_eof.test │ │ │ ├── struct_end_at_open_random.test │ │ │ ├── struct_end_at_open_semicolon.test │ │ │ ├── struct_end_at_struct.test │ │ │ ├── struct_lit.test │ │ │ ├── struct_lit_colons.test │ │ │ ├── struct_lit_empty.test │ │ │ ├── struct_lit_end_at_comma.test │ │ │ ├── struct_lit_end_at_equal.test │ │ │ ├── struct_lit_one_field.test │ │ │ ├── struct_lit_open_eof.test │ │ │ ├── struct_lit_open_random.test │ │ │ ├── struct_lit_open_semicolon.test │ │ │ ├── struct_lit_untyped.test │ │ │ ├── struct_multiple_fields.test │ │ │ ├── switch.test │ │ │ ├── switch_arm_open_eof.test │ │ │ ├── switch_arms_block_commas.test │ │ │ ├── switch_arms_block_no_comma.test │ │ │ ├── switch_arms_expr_comma.test │ │ │ ├── switch_arms_expr_no_comma.test │ │ │ ├── switch_end_at_enum_value.test │ │ │ ├── switch_end_at_fat_arrow.test │ │ │ ├── switch_end_at_in.test │ │ │ ├── switch_end_at_param.test │ │ │ ├── switch_end_at_switch.test │ │ │ ├── switch_end_at_variant_name.test │ │ │ ├── switch_open_eof.test │ │ │ ├── switch_semicolon.test │ │ │ ├── switch_semicolon_missing.test │ │ │ ├── switch_swap_param_and_value.test │ │ │ ├── switch_without_param.test │ │ │ ├── switch_without_param_fancy.test │ │ │ ├── unary_expr_bang.test │ │ │ ├── unary_expr_negative.test │ │ │ ├── unary_expr_positive.test │ │ │ ├── unary_expr_with_cast │ │ │ ├── var_def_decl_no_type.test │ │ │ ├── var_def_default_value.test │ │ │ ├── var_def_end_at_colon.test │ │ │ ├── var_def_end_at_type.test │ │ │ ├── var_def_missing_value.test │ │ │ ├── var_def_no_colon_equals.test │ │ │ ├── var_def_no_equals.test │ │ │ ├── var_def_with_member_type.test │ │ │ ├── var_def_with_type.test │ │ │ ├── while.test │ │ │ └── whitespace.test │ │ └── source_file │ │ │ ├── extern_binding.test │ │ │ ├── import.test │ │ │ ├── import_missing_file.test │ │ │ ├── import_missing_file_and_semicolon.test │ │ │ ├── missing_return_ty_block.test │ │ │ ├── missing_return_ty_extern.test │ │ │ ├── missing_value.test │ │ │ ├── no_semicolon_extern.test │ │ │ ├── no_semicolon_lambda.test │ │ │ ├── non_binding_at_root.test │ │ │ ├── return_distinct.test │ │ │ ├── semicolons_after.test │ │ │ ├── semicolons_before.test │ │ │ ├── semicolons_between.test │ │ │ ├── single_rbrace.test │ │ │ ├── unfinished_lambda_block.test │ │ │ ├── var_def_function_no_symbols.test │ │ │ ├── var_def_no_symbols.test │ │ │ └── var_def_recursion.test │ │ └── token_set.rs ├── syntax │ ├── Cargo.toml │ ├── build.rs │ └── src │ │ └── lib.rs ├── test-utils │ ├── Cargo.toml │ └── src │ │ └── lib.rs ├── token │ ├── Cargo.toml │ └── src │ │ └── lib.rs ├── topo │ ├── Cargo.toml │ └── src │ │ └── lib.rs └── uid_gen │ ├── Cargo.toml │ └── src │ └── lib.rs ├── examples ├── arrays.capy ├── arrays_of_arrays.capy ├── auto_deref.capy ├── comptime.capy ├── comptime_types.capy ├── drink.capy ├── enums_and_switch_statements.capy ├── fib.capy ├── files.capy ├── first_class_functions.capy ├── float_to_string.capy ├── hello_world.capy ├── io.capy ├── lists.capy ├── pretty.capy ├── ptr_assign.capy ├── ptrs_to_ptrs.capy ├── reflection.capy ├── slices.capy ├── strings.capy ├── structs.capy └── vectors.capy ├── fuzz ├── .gitignore ├── Cargo.toml ├── capy.dict ├── corpus │ └── main │ │ └── example └── fuzz_targets │ └── main.rs ├── resources └── capybara.png └── tokenizer.txt /.github/ISSUE_TEMPLATE/01_bug_report.yml: -------------------------------------------------------------------------------- 1 | name: Bug Report 2 | description: Create a report to help us fix a problem 3 | labels: ["bug"] 4 | body: 5 | - type: markdown 6 | attributes: 7 | value: | 8 | Thanks for filing a bug report 🐛 9 | 10 | Capy is early in development, and we want to fix as many issues as possible 😁 11 | - type: textarea 12 | id: problem 13 | attributes: 14 | label: Problem 15 | description: > 16 | Please provide a clear description of what the bug is, 17 | including what currently happens and what you expected to happen. 18 | validations: 19 | required: true 20 | - type: textarea 21 | id: steps 22 | attributes: 23 | label: Steps 24 | description: Please list the steps for us reproduce the bug. 25 | placeholder: | 26 | 1. 27 | 2. 28 | 3. 29 | - type: textarea 30 | id: notes 31 | attributes: 32 | label: Notes 33 | description: Provide any additional notes that might be helpful. 34 | - type: dropdown 35 | id: is-on-latest 36 | attributes: 37 | label: Does this happen on the latest commit? 38 | options: 39 | - "Yes" 40 | - "No" 41 | validations: 42 | required: true 43 | - type: dropdown 44 | id: targets 45 | attributes: 46 | label: What targets are you seeing the problem on? 47 | multiple: true 48 | options: 49 | - macOS 50 | - windows 51 | - linux 52 | - other 53 | validations: 54 | required: true 55 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/02_feature_request.yml: -------------------------------------------------------------------------------- 1 | name: Feature Request 2 | description: Suggest an idea for enhancing Capy 3 | labels: ["enhancement"] 4 | body: 5 | - type: markdown 6 | attributes: 7 | value: | 8 | Thanks for filing a feature request 😄 9 | 10 | We'd love to hear how we can improve the language! 11 | - type: textarea 12 | id: problem 13 | attributes: 14 | label: Problem 15 | description: > 16 | Please provide a clear description of your use case and the problem 17 | this feature request is trying to solve. 18 | validations: 19 | required: true 20 | - type: textarea 21 | id: solution 22 | attributes: 23 | label: Proposed Solution 24 | description: > 25 | Please provide a clear and concise description of what you want to happen. 26 | And while it's not necessary, try to include how you think this should be implemented. 27 | validations: 28 | required: true 29 | - type: textarea 30 | id: notes 31 | attributes: 32 | label: Notes 33 | description: Provide any additional context or information that might be helpful. 34 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: true 2 | contact_links: 3 | - name: Question 4 | url: https://github.com/NotAFlyingGoose 5 | about: | 6 | Got a question about Capy? 7 | Feel free to email NotAFlyingGoose for anything you're curious about 8 | -------------------------------------------------------------------------------- /.github/workflows/rust.yml: -------------------------------------------------------------------------------- 1 | name: Rust 2 | 3 | on: 4 | push: 5 | branches: [ "master" ] 6 | pull_request: 7 | branches: [ "master" ] 8 | 9 | env: 10 | CARGO_TERM_COLOR: always 11 | 12 | jobs: 13 | linux: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/checkout@v3 17 | - name: Build 18 | run: cargo build --verbose 19 | - name: Run tests 20 | run: cargo test --verbose 21 | windows: 22 | runs-on: Windows-latest 23 | steps: 24 | - uses: actions/checkout@v3 25 | - name: Build 26 | run: cargo build --verbose 27 | - name: Run tests 28 | run: cargo test --verbose 29 | macos: 30 | runs-on: macos-latest 31 | steps: 32 | - uses: actions/checkout@v3 33 | - name: Build 34 | run: cargo build --verbose 35 | - name: Run tests 36 | run: cargo test --verbose 37 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | target 3 | out 4 | c-tests 5 | 6 | examples/test*.capy 7 | 8 | **/.DS_STORE 9 | 10 | Cargo.lock 11 | .editorconfig 12 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | members = ["crates/*"] 3 | resolver = "2" 4 | -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Permission is hereby granted, free of charge, to any 2 | person obtaining a copy of this software and associated 3 | documentation files (the "Software"), to deal in the 4 | Software without restriction, including without 5 | limitation the rights to use, copy, modify, merge, 6 | publish, distribute, sublicense, and/or sell copies of 7 | the Software, and to permit persons to whom the Software 8 | is furnished to do so, subject to the following 9 | conditions: 10 | 11 | The above copyright notice and this permission notice 12 | shall be included in all copies or substantial portions 13 | of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 16 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 17 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 18 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 19 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 22 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | DEALINGS IN THE SOFTWARE. 24 | -------------------------------------------------------------------------------- /core/README.md: -------------------------------------------------------------------------------- 1 | # The Capy Standard Library 2 | 3 | This contains the basic functionality needed for any good program. It will automatically be downloaded from GitHub if it does not exist in the modules directory. 4 | 5 | You can forcefully update your version of core with `--redownload-core` 6 | 7 | You can import any module with the `#mod` directive 8 | 9 | ```capy 10 | core :: #mod("core"); 11 | ``` 12 | 13 | It will search the modules directory for a folder named "core" which contains a `mod.capy`. 14 | 15 | Note the distinction between `#mod` and `#import`. `#import` is specifically for local project files. 16 | 17 | ```capy 18 | server :: #import("server.capy"); 19 | ``` 20 | -------------------------------------------------------------------------------- /core/manifest.toml: -------------------------------------------------------------------------------- 1 | name = "core" 2 | version = "0.1.0-alpha.1" 3 | -------------------------------------------------------------------------------- /core/src/libc.capy: -------------------------------------------------------------------------------- 1 | 2 | // in the future, you wouldn't call `malloc` directly, you'd use an Allocator abstraction 3 | 4 | // allocates size bytes of memory. make sure to free() the pointer after your done. 5 | malloc :: (size: usize) -> mut rawptr extern; 6 | // allocates len * size bytes, all the bits are set to 0 7 | calloc :: (len: usize, size: usize) -> mut rawptr extern; 8 | // frees allocated memory 9 | free :: (ptr: rawptr) extern; 10 | // reallocates already allocated memory 11 | realloc :: (ptr: mut rawptr, size: usize) -> mut rawptr extern; 12 | // copies len bytes from dst to src 13 | memcpy :: (dst: mut rawptr, src: rawptr, len: usize) extern; 14 | 15 | // prints a string to the screen, adds a newline at the end 16 | puts :: (text: str) extern; 17 | // prints a char to the screen 18 | putchar :: (ch: char) extern; 19 | 20 | // a file descriptor is an integer that represents an open file 21 | File_Desc :: distinct i32; 22 | 23 | stdin : File_Desc : 0; 24 | stdout : File_Desc : 1; 25 | stderr : File_Desc : 2; 26 | 27 | // opens a file 28 | open :: (pathname: str, flags: i32) -> File_Desc extern; 29 | // moves the read/write pointer of a file descriptor 30 | lseek :: (file: File_Desc, offset: isize, whence: i32) -> isize extern; 31 | // closes a file descriptor fd 32 | close :: (file: File_Desc) -> i32 extern; 33 | // writes up to count bytes from the given buffer to 34 | // the file referred to by the file descriptor fd. 35 | write :: (file: File_Desc, buf: ^u8, count: usize) -> isize extern; 36 | // attempts to read up to count bytes from the file into the buf. 37 | // this returns the number of bytes read. 38 | read :: (file: File_Desc, buf: ^mut u8, count: usize) -> isize extern; 39 | 40 | // there are two ways to mess with files in libc: 41 | // `*FILE` pointers and file descriptors. 42 | // `FILE` is a struct in libc but it's platform specific, 43 | // so here it's represented by a usize 44 | File_Pointer :: distinct usize; 45 | 46 | // opens a file for either reading "r", writing "w", appending "a". 47 | // open a file to update both reading and writing "r+". 48 | // create an empty file for reading and writing "w+". 49 | // open a file for reading and appending "a+". 50 | fopen :: (pathname: str, mode: str) -> File_Pointer extern; 51 | // closes a file 52 | fclose :: (file: File_Pointer) -> i32 extern; 53 | 54 | // writes a char to a file 55 | fputc :: (ch: char, file: File_Pointer) -> i32 extern; 56 | // writes a string to a file and doesn't add a newline at the end 57 | fputs :: (text: str, file: File_Pointer) -> i32 extern; 58 | 59 | // read a char from a file 60 | fgetc :: (fp: File_Pointer) -> char extern; 61 | // read len char's from a file and store them in buf 62 | fgets :: (buf: ^mut char, len: i32, fp: File_Pointer) -> str extern; 63 | 64 | // tests the end-of-file indicator for the given file 65 | feof :: (fp: usize) -> bool extern; 66 | 67 | // exits the current program 68 | exit :: (status: i32) extern; 69 | -------------------------------------------------------------------------------- /core/src/mem.capy: -------------------------------------------------------------------------------- 1 | 2 | // for doing bit-twiddelling with f32s 3 | 4 | f32_to_bits :: (num: f32) -> u32 { 5 | // I don't think there's a way to do this with a cranelift intrinsic, 6 | // so pointer transmutation is the only option. 7 | num := num; 8 | (^u32).(rawptr.(^num))^ 9 | } 10 | 11 | f32_from_bits :: (raw: u32) -> f32 { 12 | raw := raw; 13 | (^f32).(rawptr.(^raw))^ 14 | } 15 | 16 | // for doing bit-twiddelling with f64s 17 | 18 | f64_to_bits :: (num: f64) -> u64 { 19 | num := num; 20 | (^u64).(rawptr.(^num))^ 21 | } 22 | 23 | f64_from_bits :: (raw: u64) -> f64 { 24 | raw := raw; 25 | (^f64).(rawptr.(^raw))^ 26 | } 27 | -------------------------------------------------------------------------------- /core/src/ptr.capy: -------------------------------------------------------------------------------- 1 | 2 | // compiler defined 3 | to_raw :: (ptr: rawptr) -> usize extern; 4 | // compiler defined 5 | const_from_raw :: (raw: usize) -> rawptr extern; 6 | // compiler defined 7 | mut_from_raw :: (raw: usize) -> mut rawptr extern; 8 | 9 | const_offset :: (ptr: rawptr, offset: usize) -> rawptr { 10 | const_from_raw(to_raw(ptr) + offset) 11 | } 12 | 13 | mut_offset :: (ptr: mut rawptr, offset: usize) -> mut rawptr { 14 | mut_from_raw(to_raw(ptr) + offset) 15 | } 16 | 17 | read :: (ptr: rawptr, offset: usize) -> u8 { 18 | plus_offset := (^u8).(const_offset(ptr, offset)); 19 | plus_offset^ 20 | } 21 | 22 | write :: (ptr: mut rawptr, byte: u8, offset: usize) { 23 | plus_offset := (^mut u8).(mut_offset(ptr, offset)); 24 | plus_offset^ = byte; 25 | } 26 | 27 | null :: () -> rawptr { 28 | const_from_raw(0) 29 | } 30 | 31 | mut_null :: () -> mut rawptr { 32 | mut_from_raw(0) 33 | } 34 | 35 | is_null :: (ptr: rawptr) -> bool { 36 | to_raw(ptr) == 0 37 | } 38 | 39 | // constructs a slice from a pointer and a length 40 | // 41 | // ```capy 42 | // data := [3] u32 { 1, 2, 3 }; 43 | // 44 | // slice := slice_from_raw_parts(^data, 3) as [] u32; 45 | // 46 | // core.println(slice); 47 | // ``` 48 | slice_from_raw_parts :: (data: rawptr, len: usize) -> rawslice { 49 | Raw_Slice :: struct { 50 | len: usize, 51 | data: rawptr, 52 | }; 53 | 54 | raw := Raw_Slice.{ 55 | len = len, 56 | data = data, 57 | }; 58 | 59 | // transmute Any to any using rawptr 60 | (^rawslice).((rawptr).(^raw))^ 61 | } 62 | -------------------------------------------------------------------------------- /core/src/structs/string_builder.capy: -------------------------------------------------------------------------------- 1 | core :: #mod("core"); 2 | libc :: core.libc; 3 | math :: core.math; 4 | ptr :: core.ptr; 5 | 6 | StringBuilder :: struct { 7 | buf: ^mut char, 8 | len: usize, 9 | cap: usize, 10 | }; 11 | 12 | make :: () -> StringBuilder { 13 | buf := (^mut char).(ptr.mut_null()); 14 | 15 | StringBuilder.{ 16 | buf = buf, 17 | len = 0, 18 | cap = 0, 19 | } 20 | }; 21 | 22 | make_with_capacity :: (cap: usize) -> StringBuilder { 23 | if cap == 0 { return make(); } 24 | 25 | buf := (^mut char).(libc.malloc(cap)); 26 | 27 | if cap > 0 && ptr.is_null(buf) { 28 | core.panic("Error allocating the StringBuilder"); 29 | } 30 | 31 | StringBuilder.{ 32 | buf = buf, 33 | len = 0, 34 | cap = cap, 35 | } 36 | } 37 | 38 | free :: (self: ^mut StringBuilder) { 39 | libc.free(self.buf); 40 | // to make sure the string isn't accidentally used after free 41 | self.cap = 0; 42 | self.len = 0; 43 | } 44 | 45 | shrink_to_fit :: (self: ^mut StringBuilder) { 46 | if self.len != 0 && self.len < self.cap { 47 | self.buf = (^mut char).(libc.realloc(self.buf, self.len)); 48 | self.cap = self.len; 49 | 50 | if self.cap > 0 && ptr.is_null(self.buf) { 51 | core.panic("Error reallocating the StringBuilder"); 52 | } 53 | } 54 | } 55 | 56 | _grow_by :: (self: ^mut StringBuilder, len: usize) { 57 | if self.len + len > self.cap { 58 | new_cap := math.max_usize(self.cap * 2, 1); 59 | new_cap = math.max_usize( 60 | math.next_pow_of_two(self.len + len), 61 | new_cap 62 | ); 63 | 64 | self.buf = (^mut char).(libc.realloc(self.buf, new_cap)); 65 | self.cap = new_cap; 66 | 67 | if ptr.is_null(self.buf) { 68 | core.panic("Error reallocating the StringBuilder"); 69 | } 70 | } 71 | } 72 | 73 | append_char :: (self: ^mut StringBuilder, ch: char) { 74 | _grow_by(self, 1); 75 | 76 | ptr.write(self.buf, u8.(ch), self.len); 77 | 78 | self.len = self.len + 1; 79 | } 80 | 81 | append_str :: (self: ^mut StringBuilder, s: str) { 82 | len :: core.str_len(s); 83 | 84 | _grow_by(self, len); 85 | 86 | offset := ptr.mut_offset(self.buf, self.len); 87 | 88 | libc.memcpy(offset, rawptr.(s), len); 89 | 90 | self.len = self.len + len; 91 | } 92 | 93 | append_string_builder :: (self: ^mut StringBuilder, other: ^StringBuilder) { 94 | _grow_by(self, other.len); 95 | 96 | offset := ptr.mut_offset(self.buf, self.len); 97 | 98 | libc.memcpy(offset, other.buf, other.len); 99 | 100 | self.len = self.len + other.len; 101 | } 102 | 103 | reverse :: (self: ^mut StringBuilder) { 104 | i := 0; 105 | j := self.len - 1; 106 | temp := 0; 107 | 108 | while i < j { 109 | temp = ptr.read(self.buf, i); 110 | ptr.write(self.buf, ptr.read(self.buf, j), i); 111 | ptr.write(self.buf, temp, j); 112 | i += 1; 113 | j -= 1; 114 | } 115 | } 116 | 117 | as_slice :: (self: ^mut StringBuilder) -> [] char { 118 | []char.(ptr.slice_from_raw_parts(self.buf, self.len)) 119 | } 120 | 121 | print :: (self: ^StringBuilder) { 122 | idx := 0; 123 | while idx < self.len { 124 | ch := char.(ptr.read(self.buf, idx)); 125 | libc.putchar(ch); 126 | idx += 1; 127 | } 128 | } 129 | 130 | println :: (self: ^StringBuilder) { 131 | print(self); 132 | libc.putchar('\n'); 133 | } 134 | -------------------------------------------------------------------------------- /crates/ast/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "ast" 3 | version = "0.1.0-alpha.1" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | syntax = {path = "../syntax"} 10 | text-size = "1.1.0" 11 | 12 | [dev-dependencies] 13 | lexer = {path = "../lexer"} 14 | parser = {path = "../parser"} 15 | -------------------------------------------------------------------------------- /crates/capy/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "capy" 3 | version = "0.1.0-alpha.1" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | ast = { path = "../ast" } 10 | la-arena = "0.3" 11 | codegen = { path = "../codegen" } 12 | hir = { path = "../hir" } 13 | hir_ty = { path = "../hir_ty" } 14 | lexer = { path = "../lexer" } 15 | parser = { path = "../parser" } 16 | token = { path = "../token" } 17 | line_index = { path = "../line_index" } 18 | diagnostics = { path = "../diagnostics" } 19 | interner = { path = "../interner" } 20 | rustc-hash = "2.1" 21 | supports-color = "3.0.0" 22 | itertools = "0.14.0" 23 | uid_gen = { path = "../uid_gen" } 24 | path-clean = "1.0.1" 25 | target-lexicon = "0.13" 26 | serde_json = "1.0" 27 | base64 = "0.22.1" 28 | platform-dirs = "0.3.0" 29 | enum-display = "0.1.4" 30 | 31 | [dependencies.reqwest] 32 | version = "0.12.5" 33 | features = ["blocking"] 34 | 35 | [dependencies.clap] 36 | version = "4.1.8" 37 | features = ["derive"] 38 | -------------------------------------------------------------------------------- /crates/capy_macros/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "capy_macros" 3 | version = "0.1.0-alpha.1" 4 | edition = "2021" 5 | 6 | [lib] 7 | proc-macro = true 8 | 9 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 10 | 11 | [dependencies] 12 | litrs = "0.4.0" 13 | quote = "1.0.31" 14 | -------------------------------------------------------------------------------- /crates/codegen/.gitignore: -------------------------------------------------------------------------------- 1 | test-temp/ 2 | 3 | hello.txt -------------------------------------------------------------------------------- /crates/codegen/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "codegen" 3 | version = "0.1.0-alpha.1" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | interner = { path = "../interner" } 10 | la-arena = "0.3" 11 | hir = { path = "../hir" } 12 | hir_ty = { path = "../hir_ty" } 13 | rustc-hash = "2.1" 14 | cranelift = "0.116" 15 | cranelift-module = "0.116" 16 | cranelift-jit = "0.116" 17 | cranelift-native = "0.116" 18 | cranelift-object = "0.116" 19 | target-lexicon = "0.13" 20 | internment = "0.8.3" 21 | uid_gen = { path = "../uid_gen" } 22 | num-traits = "0.2.16" 23 | glob = "0.3.1" 24 | tinyvec = { version = "1.6.1", features = ["tinyvec_macros"] } 25 | which = "7.0.2" 26 | 27 | [dev-dependencies] 28 | ast = { path = "../ast" } 29 | expect-test = "1.1" 30 | interner = { path = "../interner" } 31 | lexer = { path = "../lexer" } 32 | parser = { path = "../parser" } 33 | test-utils = { path = "../test-utils" } 34 | cfg-if = "1.0.0" 35 | path-clean = "1.0.1" 36 | sha256 = "1.5.0" 37 | -------------------------------------------------------------------------------- /crates/codegen/src/convert/abi/aarch64.rs: -------------------------------------------------------------------------------- 1 | // TODO: other kinds of aarch64 abis then apple 2 | 3 | use cranelift::prelude::types::{I128, I64}; 4 | use hir_ty::{ParamTy, Ty}; 5 | use internment::Intern; 6 | use tinyvec::ArrayVec; 7 | 8 | use crate::{convert::GetFinalTy, layout::GetLayoutInfo}; 9 | 10 | use super::{FnAbi, PassMode}; 11 | 12 | /// "A Homogeneous Floating-point Aggregate (HFA) is a Homogeneous Aggregate with a Fundamental Data Type that is a Floating-Point type and at most four uniquely addressable members." 13 | pub fn is_hfa(ty: Intern) -> Option { 14 | if let Some(members) = ty.as_struct() { 15 | let mut tys = ArrayVec::new(); 16 | let ty = members[0].ty; 17 | if members.len() > 4 { 18 | None 19 | } else { 20 | for member in members { 21 | if member.ty != ty || !member.ty.is_float() { 22 | return None; 23 | } 24 | tys.push(member.ty.get_final_ty().into_real_type().unwrap()); 25 | } 26 | Some(PassMode::cast(tys, ty)) 27 | } 28 | } else if let Some((sz, subty)) = ty.as_array() { 29 | if subty.is_float() && sz <= 4 { 30 | let mut tys = ArrayVec::new(); 31 | for _ in 0..sz { 32 | tys.push(subty.get_final_ty().into_real_type().unwrap()); 33 | } 34 | Some(PassMode::cast(tys, ty)) 35 | } else { 36 | None 37 | } 38 | } else { 39 | None 40 | } 41 | } 42 | 43 | fn classify_ret(ret: Intern) -> Option { 44 | if ret.is_zero_sized() { 45 | return None; 46 | } 47 | if !ret.is_aggregate() { 48 | return Some(PassMode::direct( 49 | ret.get_final_ty().into_real_type().unwrap(), 50 | )); 51 | } 52 | if let Some(hfa) = is_hfa(ret) { 53 | Some(hfa) 54 | } else if ret.size() <= 16 { 55 | Some(PassMode::cast( 56 | ArrayVec::from_array_len([I64, I64, I64, I64], (ret.size() + 7) as usize / 8), 57 | ret, 58 | )) 59 | } else { 60 | Some(PassMode::indirect()) 61 | } 62 | } 63 | fn classify_arg(arg: Intern) -> Option { 64 | if arg.is_zero_sized() { 65 | return None; 66 | } 67 | if !arg.is_aggregate() { 68 | return Some(PassMode::direct( 69 | arg.get_final_ty().into_real_type().unwrap(), 70 | )); 71 | } 72 | if let Some(hfa) = is_hfa(arg) { 73 | Some(hfa) 74 | } else if arg.size() <= 16 { 75 | if arg.align() != 128 { 76 | Some(PassMode::cast( 77 | ArrayVec::from_array_len([I64, I64, I64, I64], (arg.size() + 7) as usize / 8), 78 | arg, 79 | )) 80 | } else { 81 | Some(PassMode::cast( 82 | ArrayVec::from_array_len([I128, I128, I128, I128], (arg.size() + 15) as usize / 16), 83 | arg, 84 | )) 85 | } 86 | } else { 87 | Some(PassMode::indirect()) 88 | } 89 | } 90 | 91 | pub fn fn_ty_to_abi((args, ret): (&[ParamTy], Intern)) -> FnAbi { 92 | let mut sig = FnAbi::new(); 93 | sig.ret = classify_ret(ret); 94 | 95 | for (idx, arg) in args.iter().enumerate() { 96 | if let Some(arg) = classify_arg(arg.ty) { 97 | sig.args.push((arg, idx as u16)) 98 | } 99 | } 100 | 101 | sig 102 | } 103 | -------------------------------------------------------------------------------- /crates/codegen/src/convert/abi/simplified.rs: -------------------------------------------------------------------------------- 1 | use hir_ty::{ParamTy, Ty}; 2 | use internment::Intern; 3 | 4 | use crate::convert::GetFinalTy; 5 | 6 | use super::{FnAbi, PassMode}; 7 | 8 | fn ty_to_passmode(ty: Intern) -> Option { 9 | if ty.is_zero_sized() { 10 | None 11 | } else if ty.is_aggregate() { 12 | Some(PassMode::indirect()) 13 | } else { 14 | Some(PassMode::direct( 15 | ty.get_final_ty().into_real_type().unwrap(), 16 | )) 17 | } 18 | // TODO: vector types 19 | } 20 | 21 | pub fn fn_ty_to_abi((args, ret): (&[ParamTy], Intern)) -> FnAbi { 22 | let mut sig = FnAbi::new(); 23 | sig.ret = ty_to_passmode(ret); 24 | sig.simple_ret = true; 25 | 26 | for (idx, arg) in args.iter().enumerate() { 27 | if let Some(arg) = ty_to_passmode(arg.ty) { 28 | sig.args.push((arg, idx as u16)) 29 | } 30 | } 31 | 32 | sig 33 | } 34 | -------------------------------------------------------------------------------- /crates/codegen/src/convert/abi/x86_64_windows.rs: -------------------------------------------------------------------------------- 1 | use cranelift::codegen::ir::Type; 2 | use hir_ty::{ParamTy, Ty}; 3 | use internment::Intern; 4 | use tinyvec::array_vec; 5 | 6 | use crate::{convert::GetFinalTy, layout::GetLayoutInfo}; 7 | 8 | use super::{FnAbi, PassMode}; 9 | 10 | fn ty_to_passmode(ty: Intern) -> Option { 11 | fn is_pow_of2(n: u32) -> bool { 12 | (n & (n - 1)) == 0 13 | } 14 | if ty.is_zero_sized() { 15 | None 16 | } else if ty.is_aggregate() { 17 | match ty.size() { 18 | x if x <= 8 && is_pow_of2(x) => { 19 | let x = x as u16; 20 | Some(PassMode::cast( 21 | array_vec![Type::int_with_byte_size(x).unwrap()], 22 | ty, 23 | )) 24 | } 25 | _ => Some(PassMode::indirect()), 26 | } 27 | } else if ty.size() <= 8 { 28 | Some(PassMode::direct( 29 | ty.get_final_ty().into_real_type().unwrap(), 30 | )) 31 | } else { 32 | Some(PassMode::indirect()) 33 | } 34 | // TODO: vector types 35 | } 36 | 37 | pub fn fn_ty_to_abi((args, ret): (&[ParamTy], Intern)) -> FnAbi { 38 | let mut sig = FnAbi::new(); 39 | sig.ret = ty_to_passmode(ret); 40 | 41 | for (idx, arg) in args.iter().enumerate() { 42 | if let Some(arg) = ty_to_passmode(arg.ty) { 43 | sig.args.push((arg, idx as u16)) 44 | } 45 | } 46 | 47 | sig 48 | } 49 | -------------------------------------------------------------------------------- /crates/codegen/src/extend.rs: -------------------------------------------------------------------------------- 1 | use cranelift::codegen::ir::Endianness; 2 | 3 | use crate::compiler::comptime::IntBytes; 4 | 5 | pub(crate) trait ExtendWithNumBytes { 6 | fn extend_with_num_bytes(&mut self, num: u32, bit_width: u8, endianness: Endianness); 7 | } 8 | 9 | impl ExtendWithNumBytes for Vec { 10 | fn extend_with_num_bytes(&mut self, num: u32, target_bit_width: u8, endianness: Endianness) { 11 | self.extend((num as u64).into_bytes(endianness, target_bit_width)) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /crates/diagnostics/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "diagnostics" 3 | version = "0.1.0-alpha.1" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | ast = { path = "../ast" } 10 | hir = { path = "../hir" } 11 | hir_ty = { path = "../hir_ty" } 12 | interner = { path = "../interner" } 13 | line_index = { path = "../line_index" } 14 | parser = { path = "../parser" } 15 | syntax = { path = "../syntax" } 16 | text-size = "1.1" 17 | pathdiff = "0.2.1" 18 | 19 | [dev-dependencies] 20 | expect-test = "1.1" 21 | -------------------------------------------------------------------------------- /crates/hir/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "hir" 3 | version = "0.1.0-alpha.1" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | ast = { path = "../ast" } 10 | la-arena = "0.3" 11 | interner = { path = "../interner" } 12 | rustc-hash = "2.1" 13 | smol_str = "0.3.2" 14 | syntax = { path = "../syntax" } 15 | text-size = "1.1" 16 | regex = "1.9.4" 17 | path-clean = "1.0.1" 18 | uid_gen = { path = "../uid_gen" } 19 | pathdiff = "0.2.1" 20 | bimap = "0.6.3" 21 | 22 | [dev-dependencies] 23 | ast = { path = "../ast" } 24 | expect-test = "1.1" 25 | interner = { path = "../interner" } 26 | lexer = { path = "../lexer" } 27 | parser = { path = "../parser" } 28 | test-utils = { path = "../test-utils" } 29 | uid_gen = { path = "../uid_gen" } 30 | -------------------------------------------------------------------------------- /crates/hir/src/subdir.rs: -------------------------------------------------------------------------------- 1 | use std::path::{Component, Path}; 2 | 3 | pub trait SubDir { 4 | fn is_sub_dir_of(&self, base: &Self) -> bool; 5 | 6 | // get_sub_dir_divergence("/hello/world/foo/bar", "/hello/world/") 7 | // would return "foo" 8 | fn get_sub_dir_divergence(&self, base: &Self) -> Option; 9 | } 10 | 11 | impl SubDir for Path { 12 | fn is_sub_dir_of(&self, base: &Self) -> bool { 13 | let filter = |c: &Component| !matches!(c, Component::Prefix(_)); 14 | 15 | let mut sub = self.components().filter(filter); 16 | 17 | base.components() 18 | .filter(filter) 19 | .all(|base| sub.next().is_some_and(|sub| sub == base)) 20 | } 21 | 22 | fn get_sub_dir_divergence(&self, base: &Self) -> Option { 23 | let filter = |c: &Component| !matches!(c, Component::Prefix(_)); 24 | 25 | let mut base = base.components().filter(filter); 26 | 27 | for sub in self.components().filter(filter) { 28 | match base.next() { 29 | Some(base) => { 30 | if base != sub { 31 | return None; 32 | } 33 | } 34 | None => { 35 | if let Component::Normal(name) = sub { 36 | return Some(name.to_string_lossy().to_string()); 37 | } else { 38 | return None; 39 | } 40 | } 41 | } 42 | } 43 | 44 | None 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /crates/hir/src/world_index.rs: -------------------------------------------------------------------------------- 1 | use rustc_hash::FxHashMap; 2 | 3 | use crate::{FileName, Fqn, Index, RangeInfo}; 4 | 5 | #[derive(Default, Debug)] 6 | pub struct WorldIndex(FxHashMap); 7 | 8 | impl WorldIndex { 9 | pub fn definition(&self, fqn: Fqn) -> DefinitionStatus { 10 | match self.0.get(&fqn.file) { 11 | Some(index) => { 12 | if index.has_definition(fqn.name) { 13 | DefinitionStatus::Defined 14 | } else { 15 | DefinitionStatus::UnknownDefinition 16 | } 17 | } 18 | None => DefinitionStatus::UnknownFile, 19 | } 20 | } 21 | 22 | pub fn range_info(&self, fqn: Fqn) -> &RangeInfo { 23 | &self.0[&fqn.file].range_info[&fqn.name] 24 | } 25 | 26 | pub fn get_all_files(&self) -> Vec<(FileName, &Index)> { 27 | self.0.iter().map(|(file, index)| (*file, index)).collect() 28 | } 29 | 30 | pub fn get_file(&self, file: FileName) -> Option<&Index> { 31 | self.0.get(&file) 32 | } 33 | 34 | pub fn add_file(&mut self, file: FileName, index: Index) { 35 | assert!(self.0.insert(file, index).is_none()); 36 | } 37 | 38 | pub fn update_file(&mut self, file: FileName, index: Index) { 39 | *self.0.get_mut(&file).unwrap() = index; 40 | } 41 | 42 | pub fn ranges(&self) -> impl Iterator { 43 | self.0.iter().flat_map(|(file, index)| { 44 | index 45 | .ranges() 46 | .map(|(name, range)| (Fqn { file: *file, name }, range)) 47 | }) 48 | } 49 | } 50 | 51 | #[derive(Debug)] 52 | pub enum DefinitionStatus { 53 | Defined, 54 | UnknownFile, 55 | UnknownDefinition, 56 | } 57 | -------------------------------------------------------------------------------- /crates/hir_ty/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "hir_ty" 3 | version = "0.1.0-alpha.1" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | la-arena = "0.3" 10 | hir = { path = "../hir" } 11 | interner = { path = "../interner" } 12 | rustc-hash = "2.1" 13 | text-size = "1.1" 14 | internment = "0.8.3" 15 | indexmap = "2.0.0" 16 | itertools = "0.14" 17 | topo = { path = "../topo" } 18 | 19 | [dev-dependencies] 20 | ast = { path = "../ast" } 21 | expect-test = "1.1" 22 | interner = { path = "../interner" } 23 | lexer = { path = "../lexer" } 24 | parser = { path = "../parser" } 25 | test-utils = { path = "../test-utils" } 26 | uid_gen = { path = "../uid_gen" } 27 | text-diff = "0.4.0" 28 | derivative = "2.2.0" 29 | codegen = { path = "../codegen" } 30 | target-lexicon = "0.13.1" 31 | -------------------------------------------------------------------------------- /crates/interner/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "interner" 3 | version = "0.1.0-alpha.1" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | lasso = "0.7.3" 10 | -------------------------------------------------------------------------------- /crates/interner/src/lib.rs: -------------------------------------------------------------------------------- 1 | use std::mem; 2 | 3 | use lasso::Spur; 4 | 5 | macro_rules! impl_interner { 6 | ($($keyword:ident => $text:expr,)*) => { 7 | impl Default for Interner { 8 | fn default() -> Self { 9 | let mut interner = Self(lasso::Rodeo::default()); 10 | $(interner.intern($text);)* 11 | interner 12 | } 13 | } 14 | 15 | impl Key { 16 | impl_interner!(@step 1u32, $($keyword,)*); 17 | } 18 | }; 19 | (@step $idx:expr, $head:ident, $($tail:ident,)*) => { 20 | pub fn $head() -> Self { 21 | Self::from_raw($idx) 22 | } 23 | 24 | impl_interner!(@step ($idx + 1u32), $($tail,)*); 25 | }; 26 | (@step $_idx:expr,) => {}; 27 | } 28 | 29 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] 30 | pub struct Key(lasso::Spur); 31 | 32 | pub struct Interner(lasso::Rodeo); 33 | 34 | impl_interner! { 35 | void => "void", 36 | isize => "isize", 37 | i128 => "i128", 38 | i64 => "i64", 39 | i32 => "i32", 40 | i16 => "i16", 41 | i8 => "i8", 42 | usize => "usize", 43 | u128 => "u128", 44 | u64 => "u64", 45 | u32 => "u32", 46 | u16 => "u16", 47 | u8 => "u8", 48 | f64 => "f64", 49 | f32 => "f32", 50 | bool => "bool", 51 | str => "str", 52 | char => "char", 53 | r#type => "type", 54 | any => "any", 55 | rawptr => "rawptr", 56 | rawslice => "rawslice", 57 | } 58 | 59 | impl Interner { 60 | pub fn intern(&mut self, s: &str) -> Key { 61 | Key(self.0.get_or_intern(s)) 62 | } 63 | 64 | pub fn lookup(&self, key: Key) -> &str { 65 | self.0.resolve(&key.0) 66 | } 67 | } 68 | 69 | impl Key { 70 | pub fn from_raw(raw: u32) -> Self { 71 | unsafe { Self(mem::transmute::(raw)) } 72 | } 73 | 74 | pub fn to_raw(self) -> u32 { 75 | unsafe { mem::transmute(self.0) } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /crates/lexer/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "lexer" 3 | version = "0.1.0-alpha.1" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | logos = "0.14.4" 10 | token = { path = "../token" } 11 | text-size = "1.0.0" 12 | syntax = { path = "../syntax" } 13 | capy_macros = { path = "../capy_macros" } 14 | -------------------------------------------------------------------------------- /crates/lexer/build.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | println!("cargo:rerun-if-changed=../../tokenizer.txt"); 3 | } 4 | -------------------------------------------------------------------------------- /crates/line_index/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "line_index" 3 | authors = ["Luna Razzaghipour"] 4 | version = "0.1.0-alpha.1" 5 | edition = "2021" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | text-size = "1.1" 11 | -------------------------------------------------------------------------------- /crates/line_index/src/lib.rs: -------------------------------------------------------------------------------- 1 | use std::iter; 2 | use std::ops::{Index, Sub}; 3 | use text_size::TextSize; 4 | 5 | #[derive(Debug, Clone, PartialEq, Default)] 6 | pub struct LineIndex { 7 | line_starts: Vec, 8 | } 9 | 10 | #[derive(Debug, Clone, Copy, PartialEq)] 11 | pub struct LineNr(pub u32); 12 | 13 | #[derive(Debug, Clone, Copy, PartialEq)] 14 | pub struct ColNr(pub u32); 15 | 16 | impl LineIndex { 17 | pub fn new(text: &str) -> Self { 18 | Self { 19 | line_starts: iter::once(TextSize::from(0)) 20 | .chain( 21 | text.match_indices('\n') 22 | .map(|(idx, _)| TextSize::from(idx as u32 + 1)), 23 | ) 24 | .collect(), 25 | } 26 | } 27 | 28 | pub fn line_col(&self, offset: TextSize) -> (LineNr, ColNr) { 29 | let line = self.line_starts.partition_point(|&it| it <= offset) - 1; 30 | let line = LineNr(line as u32); 31 | 32 | let line_start_offset = self[line]; 33 | let col = ColNr(u32::from(offset - line_start_offset)); 34 | 35 | (line, col) 36 | } 37 | } 38 | 39 | impl Index for LineIndex { 40 | type Output = TextSize; 41 | 42 | fn index(&self, index: LineNr) -> &Self::Output { 43 | &self.line_starts[index.0 as usize] 44 | } 45 | } 46 | 47 | impl Sub for LineNr { 48 | type Output = Self; 49 | 50 | fn sub(self, rhs: Self) -> Self::Output { 51 | Self(self.0 - rhs.0) 52 | } 53 | } 54 | 55 | impl Sub for ColNr { 56 | type Output = Self; 57 | 58 | fn sub(self, rhs: Self) -> Self::Output { 59 | Self(self.0 - rhs.0) 60 | } 61 | } 62 | 63 | #[cfg(test)] 64 | mod tests { 65 | use super::*; 66 | 67 | fn check(text: &str, line_starts: [u32; LEN]) { 68 | assert_eq!( 69 | LineIndex::new(text), 70 | LineIndex { 71 | line_starts: line_starts.into_iter().map(TextSize::from).collect() 72 | } 73 | ); 74 | } 75 | 76 | #[test] 77 | fn empty() { 78 | check("", [0]); 79 | } 80 | 81 | #[test] 82 | fn one() { 83 | check("\n", [0, 1]); 84 | } 85 | 86 | #[test] 87 | fn trailing() { 88 | check("foo\n", [0, 4]); 89 | } 90 | 91 | #[test] 92 | fn two() { 93 | check("foo\nbar", [0, 4]); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /crates/parser/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "parser" 3 | version = "0.1.0-alpha.1" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | capy_macros = {path = "../capy_macros"} 10 | chrono = "0.4.23" 11 | drop_bomb = "0.1.5" 12 | static_assertions = "1.1" 13 | syntax = {path = "../syntax"} 14 | text-size = "1.0.0" 15 | timer = "0.2.0" 16 | token = {path = "../token"} 17 | 18 | [dev-dependencies] 19 | expect-test = "1.0.1" 20 | lexer = {path="../lexer"} 21 | -------------------------------------------------------------------------------- /crates/parser/build.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | println!("cargo:rerun-if-changed=../../tokenizer.txt"); 3 | } 4 | -------------------------------------------------------------------------------- /crates/parser/src/event.rs: -------------------------------------------------------------------------------- 1 | use syntax::NodeKind; 2 | 3 | #[derive(Debug, Clone, Copy)] 4 | pub(crate) enum Event { 5 | StartNode { kind: NodeKind }, 6 | FinishNode, 7 | AddToken, 8 | } 9 | 10 | static_assertions::assert_eq_size!(Event, Option, u8); 11 | -------------------------------------------------------------------------------- /crates/parser/src/grammar.rs: -------------------------------------------------------------------------------- 1 | mod expr; 2 | mod stmt; 3 | 4 | use syntax::{NodeKind, TokenKind}; 5 | 6 | use crate::parser::marker::CompletedMarker; 7 | use crate::parser::Parser; 8 | use crate::token_set::TokenSet; 9 | 10 | pub(crate) fn source_file(p: &mut Parser<'_>) { 11 | let m = p.start(); 12 | 13 | while !p.at_eof() { 14 | // just skip over semicolons 15 | if p.at(TokenKind::Semicolon) { 16 | p.bump(); 17 | continue; 18 | } 19 | // if we didn't get a semicolon, we definitely shouldn't be getting something else from the default recovery set 20 | if p.at_default_recovery_set() { 21 | let _guard = p.expected_syntax_name("definition"); 22 | p.error_with_recovery_set_no_default(TokenSet::NONE); 23 | continue; 24 | } 25 | stmt::parse_decl(p, true); 26 | } 27 | 28 | m.complete(p, NodeKind::Root); 29 | } 30 | 31 | pub(crate) fn repl_line(p: &mut Parser<'_>) { 32 | let m = p.start(); 33 | 34 | while !p.at_eof() { 35 | if p.at(TokenKind::Semicolon) { 36 | p.bump(); 37 | } else if stmt::parse_stmt(p, true).is_none() { 38 | if p.at_eof() { 39 | break; 40 | } 41 | let _guard = p.expected_syntax_name("statement"); 42 | p.error_with_skip(); 43 | } 44 | } 45 | 46 | m.complete(p, NodeKind::Root); 47 | } 48 | -------------------------------------------------------------------------------- /crates/parser/src/lib.rs: -------------------------------------------------------------------------------- 1 | mod error; 2 | mod event; 3 | mod grammar; 4 | mod parser; 5 | mod sink; 6 | mod token_set; 7 | 8 | #[cfg(test)] 9 | mod tests; 10 | 11 | use std::fmt; 12 | 13 | pub use error::*; 14 | 15 | use crate::parser::Parser; 16 | use sink::Sink; 17 | use syntax::{SyntaxTree, SyntaxTreeBuf}; 18 | use token::Tokens; 19 | 20 | pub fn parse_source_file(tokens: &Tokens, input: &str) -> Parse { 21 | let (events, errors) = Parser::new(tokens, input).parse(grammar::source_file); 22 | Sink::new(events, tokens, input).finish(errors) 23 | } 24 | 25 | pub fn parse_repl_line(tokens: &Tokens, input: &str) -> Parse { 26 | let (events, errors) = Parser::new(tokens, input).parse(grammar::repl_line); 27 | Sink::new(events, tokens, input).finish(errors) 28 | } 29 | 30 | pub struct Parse { 31 | syntax_tree: SyntaxTreeBuf, 32 | errors: Vec, 33 | } 34 | 35 | impl Parse { 36 | pub fn syntax_tree(&self) -> &SyntaxTree { 37 | &self.syntax_tree 38 | } 39 | 40 | pub fn into_syntax_tree(self) -> SyntaxTreeBuf { 41 | self.syntax_tree 42 | } 43 | 44 | pub fn errors(&self) -> &[SyntaxError] { 45 | &self.errors 46 | } 47 | } 48 | 49 | impl fmt::Debug for Parse { 50 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 51 | let tree = format!("{:#?}", self.syntax_tree); 52 | write!(f, "{}", &tree[0..tree.len() - 1])?; 53 | 54 | for error in &self.errors { 55 | write!(f, "\n{:?}", error)?; 56 | } 57 | 58 | Ok(()) 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /crates/parser/src/parser/marker.rs: -------------------------------------------------------------------------------- 1 | use std::mem; 2 | 3 | use drop_bomb::DropBomb; 4 | use syntax::NodeKind; 5 | 6 | use crate::event::Event; 7 | 8 | use super::Parser; 9 | 10 | pub(crate) struct Marker { 11 | start_token_idx: usize, 12 | pos: usize, 13 | bomb: DropBomb, 14 | } 15 | 16 | impl Marker { 17 | pub(crate) fn new(pos: usize, start_token_idx: usize) -> Self { 18 | Self { 19 | start_token_idx, 20 | pos, 21 | bomb: DropBomb::new("Markers need to be completed"), 22 | } 23 | } 24 | 25 | pub(crate) fn complete(mut self, p: &mut Parser<'_>, kind: NodeKind) -> CompletedMarker { 26 | self.bomb.defuse(); 27 | let old_event = mem::replace(&mut p.events[self.pos], Some(Event::StartNode { kind })); 28 | debug_assert!(old_event.is_none()); 29 | p.events.push(Some(Event::FinishNode)); 30 | 31 | CompletedMarker { 32 | kind, 33 | start_token_idx: self.start_token_idx, 34 | pos: self.pos, 35 | } 36 | } 37 | } 38 | 39 | #[derive(Copy, Clone)] 40 | pub(crate) struct CompletedMarker { 41 | kind: NodeKind, 42 | start_token_idx: usize, 43 | pos: usize, 44 | } 45 | 46 | impl CompletedMarker { 47 | pub(crate) fn kind(&self) -> NodeKind { 48 | self.kind 49 | } 50 | 51 | pub(crate) fn start_token_idx(&self) -> usize { 52 | self.start_token_idx 53 | } 54 | 55 | pub(crate) fn precede(self, p: &mut Parser) -> Marker { 56 | p.events.insert(self.pos, None); 57 | Marker::new(self.pos, self.start_token_idx) 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/2_var_defs.test: -------------------------------------------------------------------------------- 1 | foo := bar; 2 | baz := qux; 3 | === 4 | Root@0..23 5 | VarDef@0..11 6 | Ident@0..3 "foo" 7 | Whitespace@3..4 " " 8 | Colon@4..5 ":" 9 | Equals@5..6 "=" 10 | Whitespace@6..7 " " 11 | VarRef@7..10 12 | Ident@7..10 "bar" 13 | Semicolon@10..11 ";" 14 | Whitespace@11..12 "\n" 15 | VarDef@12..23 16 | Ident@12..15 "baz" 17 | Whitespace@15..16 " " 18 | Colon@16..17 ":" 19 | Equals@17..18 "=" 20 | Whitespace@18..19 " " 21 | VarRef@19..22 22 | Ident@19..22 "qux" 23 | Semicolon@22..23 ";" 24 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/array_decl.test: -------------------------------------------------------------------------------- 1 | [5]i32 2 | === 3 | Root@0..6 4 | ExprStmt@0..6 5 | ArrayDecl@0..6 6 | ArraySize@0..3 7 | LBrack@0..1 "[" 8 | IntLiteral@1..2 9 | Int@1..2 "5" 10 | RBrack@2..3 "]" 11 | Ty@3..6 12 | VarRef@3..6 13 | Ident@3..6 "i32" 14 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/array_decl_no_size.test: -------------------------------------------------------------------------------- 1 | []i32 2 | === 3 | Root@0..5 4 | ExprStmt@0..5 5 | ArrayDecl@0..5 6 | ArraySize@0..2 7 | LBrack@0..1 "[" 8 | RBrack@1..2 "]" 9 | Ty@2..5 10 | VarRef@2..5 11 | Ident@2..5 "i32" 12 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/array_decl_no_type.test: -------------------------------------------------------------------------------- 1 | [] 2 | === 3 | Root@0..2 4 | ExprStmt@0..2 5 | ArrayDecl@0..2 6 | ArraySize@0..2 7 | LBrack@0..1 "[" 8 | RBrack@1..2 "]" 9 | error at 2: missing array type 10 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/array_decl_open.test: -------------------------------------------------------------------------------- 1 | [ 2 | === 3 | Root@0..1 4 | ExprStmt@0..1 5 | ArrayDecl@0..1 6 | ArraySize@0..1 7 | LBrack@0..1 "[" 8 | error at 1: missing array size 9 | error at 1: missing RBrack 10 | error at 1: missing array type 11 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/array_decl_safe_rbrace.test: -------------------------------------------------------------------------------- 1 | if some_type == [3] i32 { 2 | 3 | } 4 | === 5 | Root@0..28 6 | ExprStmt@0..28 7 | IfExpr@0..28 8 | If@0..2 "if" 9 | Whitespace@2..3 " " 10 | BinaryExpr@3..23 11 | VarRef@3..12 12 | Ident@3..12 "some_type" 13 | Whitespace@12..13 " " 14 | DoubleEquals@13..15 "==" 15 | Whitespace@15..16 " " 16 | ArrayDecl@16..23 17 | ArraySize@16..19 18 | LBrack@16..17 "[" 19 | IntLiteral@17..18 20 | Int@17..18 "3" 21 | RBrack@18..19 "]" 22 | Whitespace@19..20 " " 23 | Ty@20..23 24 | VarRef@20..23 25 | Ident@20..23 "i32" 26 | Whitespace@23..24 " " 27 | Block@24..28 28 | LBrace@24..25 "{" 29 | Whitespace@25..27 "\n\n" 30 | RBrace@27..28 "}" 31 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/array_lit_empty.test: -------------------------------------------------------------------------------- 1 | i32.[] 2 | === 3 | Root@0..6 4 | ExprStmt@0..6 5 | ArrayLiteral@0..6 6 | Ty@0..3 7 | VarRef@0..3 8 | Ident@0..3 "i32" 9 | Dot@3..4 "." 10 | LBrack@4..5 "[" 11 | RBrack@5..6 "]" 12 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/array_lit_empty_comma.test: -------------------------------------------------------------------------------- 1 | i32.[,] 2 | === 3 | Root@0..7 4 | ExprStmt@0..7 5 | ArrayLiteral@0..7 6 | Ty@0..3 7 | VarRef@0..3 8 | Ident@0..3 "i32" 9 | Dot@3..4 "." 10 | LBrack@4..5 "[" 11 | ArrayItem@5..6 12 | Error@5..6 13 | Comma@5..6 "," 14 | RBrack@6..7 "]" 15 | error at 5..6: expected array item but found Comma 16 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/array_lit_end_at_comma.test: -------------------------------------------------------------------------------- 1 | i32.[5 * 2, 2 | === 3 | Root@0..11 4 | ExprStmt@0..11 5 | ArrayLiteral@0..11 6 | Ty@0..3 7 | VarRef@0..3 8 | Ident@0..3 "i32" 9 | Dot@3..4 "." 10 | LBrack@4..5 "[" 11 | ArrayItem@5..10 12 | BinaryExpr@5..10 13 | IntLiteral@5..6 14 | Int@5..6 "5" 15 | Whitespace@6..7 " " 16 | Asterisk@7..8 "*" 17 | Whitespace@8..9 " " 18 | IntLiteral@9..10 19 | Int@9..10 "2" 20 | Comma@10..11 "," 21 | error at 11: missing array item 22 | error at 11: missing RBrack 23 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/array_lit_open_eof.test: -------------------------------------------------------------------------------- 1 | i32.[ 2 | === 3 | Root@0..5 4 | ExprStmt@0..5 5 | ArrayLiteral@0..5 6 | Ty@0..3 7 | VarRef@0..3 8 | Ident@0..3 "i32" 9 | Dot@3..4 "." 10 | LBrack@4..5 "[" 11 | error at 5: missing array item 12 | error at 5: missing RBrack 13 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/array_lit_open_random.test: -------------------------------------------------------------------------------- 1 | i32.[) 2 | === 3 | Root@0..6 4 | ExprStmt@0..6 5 | ArrayLiteral@0..6 6 | Ty@0..3 7 | VarRef@0..3 8 | Ident@0..3 "i32" 9 | Dot@3..4 "." 10 | LBrack@4..5 "[" 11 | ArrayItem@5..6 12 | Error@5..6 13 | RParen@5..6 ")" 14 | error at 5..6: expected array item but found RParen 15 | error at 6: missing RBrack 16 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/array_lit_open_semicolon.test: -------------------------------------------------------------------------------- 1 | i32.[; 2 | === 3 | Root@0..6 4 | ExprStmt@0..6 5 | ArrayLiteral@0..5 6 | Ty@0..3 7 | VarRef@0..3 8 | Ident@0..3 "i32" 9 | Dot@3..4 "." 10 | LBrack@4..5 "[" 11 | Semicolon@5..6 ";" 12 | error at 5: missing array item 13 | error at 5: missing RBrack 14 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/array_lit_untyped.test: -------------------------------------------------------------------------------- 1 | .[true, false, "huh?"] 2 | === 3 | Root@0..22 4 | ExprStmt@0..22 5 | ArrayLiteral@0..22 6 | Dot@0..1 "." 7 | LBrack@1..2 "[" 8 | ArrayItem@2..6 9 | BoolLiteral@2..6 10 | Bool@2..6 "true" 11 | Comma@6..7 "," 12 | Whitespace@7..8 " " 13 | ArrayItem@8..13 14 | BoolLiteral@8..13 15 | Bool@8..13 "false" 16 | Comma@13..14 "," 17 | Whitespace@14..15 " " 18 | ArrayItem@15..21 19 | StringLiteral@15..21 20 | DoubleQuote@15..16 "\"" 21 | StringContents@16..20 "huh?" 22 | DoubleQuote@20..21 "\"" 23 | RBrack@21..22 "]" 24 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/array_lit_with_values.test: -------------------------------------------------------------------------------- 1 | str.["Hello", "World"] 2 | === 3 | Root@0..22 4 | ExprStmt@0..22 5 | ArrayLiteral@0..22 6 | Ty@0..3 7 | VarRef@0..3 8 | Ident@0..3 "str" 9 | Dot@3..4 "." 10 | LBrack@4..5 "[" 11 | ArrayItem@5..12 12 | StringLiteral@5..12 13 | DoubleQuote@5..6 "\"" 14 | StringContents@6..11 "Hello" 15 | DoubleQuote@11..12 "\"" 16 | Comma@12..13 "," 17 | Whitespace@13..14 " " 18 | ArrayItem@14..21 19 | StringLiteral@14..21 20 | DoubleQuote@14..15 "\"" 21 | StringContents@15..20 "World" 22 | DoubleQuote@20..21 "\"" 23 | RBrack@21..22 "]" 24 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/array_missing_dot.test: -------------------------------------------------------------------------------- 1 | i32 [1, 2, 3] 2 | === 3 | Root@0..13 4 | ExprStmt@0..13 5 | ArrayLiteral@0..13 6 | Ty@0..3 7 | VarRef@0..3 8 | Ident@0..3 "i32" 9 | Whitespace@3..4 " " 10 | LBrack@4..5 "[" 11 | ArrayItem@5..6 12 | IntLiteral@5..6 13 | Int@5..6 "1" 14 | Comma@6..7 "," 15 | Whitespace@7..8 " " 16 | ArrayItem@8..9 17 | IntLiteral@8..9 18 | Int@8..9 "2" 19 | Comma@9..10 "," 20 | Whitespace@10..11 " " 21 | ArrayItem@11..12 22 | IntLiteral@11..12 23 | Int@11..12 "3" 24 | RBrack@12..13 "]" 25 | error at 3: missing Dot 26 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/array_old_syntax.test: -------------------------------------------------------------------------------- 1 | [3] i32 { 1, 2, 3 } 2 | === 3 | Root@0..19 4 | ExprStmt@0..19 5 | ArrayLiteral@0..19 6 | ArraySize@0..3 7 | LBrack@0..1 "[" 8 | IntLiteral@1..2 9 | Int@1..2 "3" 10 | RBrack@2..3 "]" 11 | Whitespace@3..4 " " 12 | Ty@4..7 13 | VarRef@4..7 14 | Ident@4..7 "i32" 15 | Whitespace@7..8 " " 16 | Error@8..9 17 | LBrace@8..9 "{" 18 | Whitespace@9..10 " " 19 | ArrayItem@10..11 20 | IntLiteral@10..11 21 | Int@10..11 "1" 22 | Comma@11..12 "," 23 | Whitespace@12..13 " " 24 | ArrayItem@13..14 25 | IntLiteral@13..14 26 | Int@13..14 "2" 27 | Comma@14..15 "," 28 | Whitespace@15..16 " " 29 | ArrayItem@16..17 30 | IntLiteral@16..17 31 | Int@16..17 "3" 32 | Whitespace@17..18 " " 33 | Error@18..19 34 | RBrace@18..19 "}" 35 | error at 0..4: expected nothing but found ArraySize 36 | error at 7: missing Dot 37 | error at 8..9: expected LBrack but found LBrace 38 | error at 18..19: expected RBrack but found RBrace 39 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/bin_literal.test: -------------------------------------------------------------------------------- 1 | 0b10100010011111111 2 | === 3 | Root@0..19 4 | ExprStmt@0..19 5 | IntLiteral@0..19 6 | Bin@0..19 "0b10100010011111111" 7 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/bin_literal_multiplication.test: -------------------------------------------------------------------------------- 1 | 0b101010101 * 0b010101010 2 | === 3 | Root@0..25 4 | ExprStmt@0..25 5 | BinaryExpr@0..25 6 | IntLiteral@0..11 7 | Bin@0..11 "0b101010101" 8 | Whitespace@11..12 " " 9 | Asterisk@12..13 "*" 10 | Whitespace@13..14 " " 11 | IntLiteral@14..25 12 | Bin@14..25 "0b010101010" 13 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/binary_cmp.test: -------------------------------------------------------------------------------- 1 | 1 < 10 2 | === 3 | Root@0..6 4 | ExprStmt@0..6 5 | BinaryExpr@0..6 6 | IntLiteral@0..1 7 | Int@0..1 "1" 8 | Whitespace@1..2 " " 9 | Left@2..3 "<" 10 | Whitespace@3..4 " " 11 | IntLiteral@4..6 12 | Int@4..6 "10" 13 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/binary_cmp_complex.test: -------------------------------------------------------------------------------- 1 | 5 * 2 == 10 || 5 <= 10 && 6 / 2 == 3 2 | === 3 | Root@0..36 4 | ExprStmt@0..36 5 | BinaryExpr@0..36 6 | BinaryExpr@0..11 7 | BinaryExpr@0..5 8 | IntLiteral@0..1 9 | Int@0..1 "5" 10 | Whitespace@1..2 " " 11 | Asterisk@2..3 "*" 12 | Whitespace@3..4 " " 13 | IntLiteral@4..5 14 | Int@4..5 "2" 15 | Whitespace@5..6 " " 16 | DoubleEquals@6..8 "==" 17 | Whitespace@8..9 " " 18 | IntLiteral@9..11 19 | Int@9..11 "10" 20 | Whitespace@11..12 " " 21 | DoublePipe@12..14 "||" 22 | Whitespace@14..15 " " 23 | BinaryExpr@15..36 24 | BinaryExpr@15..22 25 | IntLiteral@15..16 26 | Int@15..16 "5" 27 | Whitespace@16..17 " " 28 | LeftEquals@17..19 "<=" 29 | Whitespace@19..20 " " 30 | IntLiteral@20..22 31 | Int@20..22 "10" 32 | Whitespace@22..23 " " 33 | DoubleAnd@23..25 "&&" 34 | Whitespace@25..26 " " 35 | BinaryExpr@26..36 36 | BinaryExpr@26..31 37 | IntLiteral@26..27 38 | Int@26..27 "6" 39 | Whitespace@27..28 " " 40 | Slash@28..29 "/" 41 | Whitespace@29..30 " " 42 | IntLiteral@30..31 43 | Int@30..31 "2" 44 | Whitespace@31..32 " " 45 | DoubleEquals@32..34 "==" 46 | Whitespace@34..35 " " 47 | IntLiteral@35..36 48 | Int@35..36 "3" 49 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/binary_expr_left_assoc.test: -------------------------------------------------------------------------------- 1 | 1+2+3+4; 2 | === 3 | Root@0..8 4 | ExprStmt@0..8 5 | BinaryExpr@0..7 6 | BinaryExpr@0..5 7 | BinaryExpr@0..3 8 | IntLiteral@0..1 9 | Int@0..1 "1" 10 | Plus@1..2 "+" 11 | IntLiteral@2..3 12 | Int@2..3 "2" 13 | Plus@3..4 "+" 14 | IntLiteral@4..5 15 | Int@4..5 "3" 16 | Plus@5..6 "+" 17 | IntLiteral@6..7 18 | Int@6..7 "4" 19 | Semicolon@7..8 ";" 20 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/binary_expr_mixed_assoc.test: -------------------------------------------------------------------------------- 1 | 1+2*3-4; 2 | === 3 | Root@0..8 4 | ExprStmt@0..8 5 | BinaryExpr@0..7 6 | BinaryExpr@0..5 7 | IntLiteral@0..1 8 | Int@0..1 "1" 9 | Plus@1..2 "+" 10 | BinaryExpr@2..5 11 | IntLiteral@2..3 12 | Int@2..3 "2" 13 | Asterisk@3..4 "*" 14 | IntLiteral@4..5 15 | Int@4..5 "3" 16 | Hyphen@5..6 "-" 17 | IntLiteral@6..7 18 | Int@6..7 "4" 19 | Semicolon@7..8 ";" 20 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/binary_expr_paren.test: -------------------------------------------------------------------------------- 1 | 5*{2+1}; 2 | === 3 | Root@0..8 4 | ExprStmt@0..8 5 | BinaryExpr@0..7 6 | IntLiteral@0..1 7 | Int@0..1 "5" 8 | Asterisk@1..2 "*" 9 | Block@2..7 10 | LBrace@2..3 "{" 11 | BinaryExpr@3..6 12 | IntLiteral@3..4 13 | Int@3..4 "2" 14 | Plus@4..5 "+" 15 | IntLiteral@5..6 16 | Int@5..6 "1" 17 | RBrace@6..7 "}" 18 | Semicolon@7..8 ";" 19 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/binary_expr_with_unary.test: -------------------------------------------------------------------------------- 1 | -20+20; 2 | === 3 | Root@0..7 4 | ExprStmt@0..7 5 | BinaryExpr@0..6 6 | UnaryExpr@0..3 7 | Hyphen@0..1 "-" 8 | IntLiteral@1..3 9 | Int@1..3 "20" 10 | Plus@3..4 "+" 11 | IntLiteral@4..6 12 | Int@4..6 "20" 13 | Semicolon@6..7 ";" 14 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/binary_expr_without_rhs.test: -------------------------------------------------------------------------------- 1 | 1 + 2 | === 3 | Root@0..3 4 | ExprStmt@0..3 5 | BinaryExpr@0..3 6 | IntLiteral@0..1 7 | Int@0..1 "1" 8 | Whitespace@1..2 " " 9 | Plus@2..3 "+" 10 | error at 3: missing operand 11 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/block.test: -------------------------------------------------------------------------------- 1 | {123}; 2 | === 3 | Root@0..6 4 | ExprStmt@0..5 5 | Block@0..5 6 | LBrace@0..1 "{" 7 | IntLiteral@1..4 8 | Int@1..4 "123" 9 | RBrace@4..5 "}" 10 | Semicolon@5..6 ";" 11 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/block_end_at_open_eof.test: -------------------------------------------------------------------------------- 1 | { 2 | === 3 | Root@0..1 4 | ExprStmt@0..1 5 | Block@0..1 6 | LBrace@0..1 "{" 7 | error at 1: missing RBrace 8 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/block_end_at_open_random.test: -------------------------------------------------------------------------------- 1 | {) 2 | === 3 | Root@0..2 4 | ExprStmt@0..2 5 | Block@0..2 6 | LBrace@0..1 "{" 7 | ExprStmt@1..2 8 | Error@1..2 9 | RParen@1..2 ")" 10 | error at 1..2: expected statement but found RParen 11 | error at 2: missing Semicolon 12 | error at 2: missing RBrace 13 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/block_end_at_open_semicolon.test: -------------------------------------------------------------------------------- 1 | {; 2 | === 3 | Root@0..2 4 | ExprStmt@0..2 5 | Block@0..2 6 | LBrace@0..1 "{" 7 | Semicolon@1..2 ";" 8 | error at 2: missing RBrace 9 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/block_lots_of_semicolons.test: -------------------------------------------------------------------------------- 1 | {;;;42;;;; a := 5;;;;;;; "foo";;;}; 2 | === 3 | Root@0..35 4 | ExprStmt@0..34 5 | Block@0..34 6 | LBrace@0..1 "{" 7 | Semicolon@1..2 ";" 8 | Semicolon@2..3 ";" 9 | Semicolon@3..4 ";" 10 | ExprStmt@4..7 11 | IntLiteral@4..6 12 | Int@4..6 "42" 13 | Semicolon@6..7 ";" 14 | Semicolon@7..8 ";" 15 | Semicolon@8..9 ";" 16 | Semicolon@9..10 ";" 17 | Whitespace@10..11 " " 18 | VarDef@11..18 19 | Ident@11..12 "a" 20 | Whitespace@12..13 " " 21 | Colon@13..14 ":" 22 | Equals@14..15 "=" 23 | Whitespace@15..16 " " 24 | IntLiteral@16..17 25 | Int@16..17 "5" 26 | Semicolon@17..18 ";" 27 | Semicolon@18..19 ";" 28 | Semicolon@19..20 ";" 29 | Semicolon@20..21 ";" 30 | Semicolon@21..22 ";" 31 | Semicolon@22..23 ";" 32 | Semicolon@23..24 ";" 33 | Whitespace@24..25 " " 34 | ExprStmt@25..31 35 | StringLiteral@25..30 36 | DoubleQuote@25..26 "\"" 37 | StringContents@26..29 "foo" 38 | DoubleQuote@29..30 "\"" 39 | Semicolon@30..31 ";" 40 | Semicolon@31..32 ";" 41 | Semicolon@32..33 ";" 42 | RBrace@33..34 "}" 43 | Semicolon@34..35 ";" 44 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/block_multiple_stmts.test: -------------------------------------------------------------------------------- 1 | {42; a := 5; "foo";}; 2 | === 3 | Root@0..21 4 | ExprStmt@0..20 5 | Block@0..20 6 | LBrace@0..1 "{" 7 | ExprStmt@1..4 8 | IntLiteral@1..3 9 | Int@1..3 "42" 10 | Semicolon@3..4 ";" 11 | Whitespace@4..5 " " 12 | VarDef@5..12 13 | Ident@5..6 "a" 14 | Whitespace@6..7 " " 15 | Colon@7..8 ":" 16 | Equals@8..9 "=" 17 | Whitespace@9..10 " " 18 | IntLiteral@10..11 19 | Int@10..11 "5" 20 | Semicolon@11..12 ";" 21 | Whitespace@12..13 " " 22 | ExprStmt@13..19 23 | StringLiteral@13..18 24 | DoubleQuote@13..14 "\"" 25 | StringContents@14..17 "foo" 26 | DoubleQuote@17..18 "\"" 27 | Semicolon@18..19 ";" 28 | RBrace@19..20 "}" 29 | Semicolon@20..21 ";" 30 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/block_nested.test: -------------------------------------------------------------------------------- 1 | {{{{{{10}}}}}}; 2 | === 3 | Root@0..15 4 | ExprStmt@0..14 5 | Block@0..14 6 | LBrace@0..1 "{" 7 | Block@1..13 8 | LBrace@1..2 "{" 9 | Block@2..12 10 | LBrace@2..3 "{" 11 | Block@3..11 12 | LBrace@3..4 "{" 13 | Block@4..10 14 | LBrace@4..5 "{" 15 | Block@5..9 16 | LBrace@5..6 "{" 17 | IntLiteral@6..8 18 | Int@6..8 "10" 19 | RBrace@8..9 "}" 20 | RBrace@9..10 "}" 21 | RBrace@10..11 "}" 22 | RBrace@11..12 "}" 23 | RBrace@12..13 "}" 24 | RBrace@13..14 "}" 25 | Semicolon@14..15 ";" 26 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/block_single_stmt.test: -------------------------------------------------------------------------------- 1 | {42;}; 2 | === 3 | Root@0..6 4 | ExprStmt@0..5 5 | Block@0..5 6 | LBrace@0..1 "{" 7 | ExprStmt@1..4 8 | IntLiteral@1..3 9 | Int@1..3 "42" 10 | Semicolon@3..4 ";" 11 | RBrace@4..5 "}" 12 | Semicolon@5..6 ";" 13 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/block_unclosed.test: -------------------------------------------------------------------------------- 1 | {foo 2 | === 3 | Root@0..4 4 | ExprStmt@0..4 5 | Block@0..4 6 | LBrace@0..1 "{" 7 | ExprStmt@1..4 8 | VarRef@1..4 9 | Ident@1..4 "foo" 10 | error at 4: missing Semicolon 11 | error at 4: missing RBrace 12 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/block_with_inner_error.test: -------------------------------------------------------------------------------- 1 | {42}; 2 | === 3 | Root@0..5 4 | ExprStmt@0..4 5 | Block@0..4 6 | LBrace@0..1 "{" 7 | IntLiteral@1..3 8 | Int@1..3 "42" 9 | RBrace@3..4 "}" 10 | Semicolon@4..5 ";" 11 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/break_continue.test: -------------------------------------------------------------------------------- 1 | while true { 2 | break; 3 | continue; 4 | } 5 | === 6 | Root@0..35 7 | ExprStmt@0..35 8 | WhileExpr@0..35 9 | While@0..5 "while" 10 | Whitespace@5..6 " " 11 | Condition@6..10 12 | BoolLiteral@6..10 13 | Bool@6..10 "true" 14 | Whitespace@10..11 " " 15 | Block@11..35 16 | LBrace@11..12 "{" 17 | Whitespace@12..15 "\n " 18 | BreakStmt@15..21 19 | Break@15..20 "break" 20 | Semicolon@20..21 ";" 21 | Whitespace@21..24 "\n " 22 | ContinueStmt@24..33 23 | Continue@24..32 "continue" 24 | Semicolon@32..33 ";" 25 | Whitespace@33..34 "\n" 26 | RBrace@34..35 "}" 27 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/break_continue_label.test: -------------------------------------------------------------------------------- 1 | `outer_loop: loop { 2 | `inner_loop: while true { 3 | break `outer_loop; 4 | continue `inner_loop; 5 | } 6 | } 7 | === 8 | Root@0..102 9 | ExprStmt@0..102 10 | WhileExpr@0..102 11 | LabelDecl@0..12 12 | Backtick@0..1 "`" 13 | Ident@1..11 "outer_loop" 14 | Colon@11..12 ":" 15 | Whitespace@12..13 " " 16 | Loop@13..17 "loop" 17 | Whitespace@17..18 " " 18 | Block@18..102 19 | LBrace@18..19 "{" 20 | Whitespace@19..22 "\n " 21 | WhileExpr@22..100 22 | LabelDecl@22..34 23 | Backtick@22..23 "`" 24 | Ident@23..33 "inner_loop" 25 | Colon@33..34 ":" 26 | Whitespace@34..35 " " 27 | While@35..40 "while" 28 | Whitespace@40..41 " " 29 | Condition@41..45 30 | BoolLiteral@41..45 31 | Bool@41..45 "true" 32 | Whitespace@45..46 " " 33 | Block@46..100 34 | LBrace@46..47 "{" 35 | Whitespace@47..52 "\n " 36 | BreakStmt@52..70 37 | Break@52..57 "break" 38 | Whitespace@57..58 " " 39 | LabelRef@58..69 40 | Backtick@58..59 "`" 41 | Ident@59..69 "outer_loop" 42 | Semicolon@69..70 ";" 43 | Whitespace@70..75 "\n " 44 | ContinueStmt@75..96 45 | Continue@75..83 "continue" 46 | Whitespace@83..84 " " 47 | LabelRef@84..95 48 | Backtick@84..85 "`" 49 | Ident@85..95 "inner_loop" 50 | Semicolon@95..96 ";" 51 | Whitespace@96..99 "\n " 52 | RBrace@99..100 "}" 53 | Whitespace@100..101 "\n" 54 | RBrace@101..102 "}" 55 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/break_continue_with_val.test: -------------------------------------------------------------------------------- 1 | `my_loop: loop { 2 | break `my_loop 5; 3 | break 42; 4 | continue `my_loop 5; 5 | continue 42; 6 | } 7 | === 8 | Root@0..88 9 | ExprStmt@0..88 10 | WhileExpr@0..88 11 | LabelDecl@0..9 12 | Backtick@0..1 "`" 13 | Ident@1..8 "my_loop" 14 | Colon@8..9 ":" 15 | Whitespace@9..10 " " 16 | Loop@10..14 "loop" 17 | Whitespace@14..15 " " 18 | Block@15..88 19 | LBrace@15..16 "{" 20 | Whitespace@16..19 "\n " 21 | BreakStmt@19..36 22 | Break@19..24 "break" 23 | Whitespace@24..25 " " 24 | LabelRef@25..33 25 | Backtick@25..26 "`" 26 | Ident@26..33 "my_loop" 27 | Whitespace@33..34 " " 28 | IntLiteral@34..35 29 | Int@34..35 "5" 30 | Semicolon@35..36 ";" 31 | Whitespace@36..39 "\n " 32 | BreakStmt@39..48 33 | Break@39..44 "break" 34 | Whitespace@44..45 " " 35 | IntLiteral@45..47 36 | Int@45..47 "42" 37 | Semicolon@47..48 ";" 38 | Whitespace@48..51 "\n " 39 | ContinueStmt@51..68 40 | Continue@51..59 "continue" 41 | Whitespace@59..60 " " 42 | LabelRef@60..68 43 | Backtick@60..61 "`" 44 | Ident@61..68 "my_loop" 45 | Whitespace@68..69 " " 46 | ExprStmt@69..71 47 | IntLiteral@69..70 48 | Int@69..70 "5" 49 | Semicolon@70..71 ";" 50 | Whitespace@71..74 "\n " 51 | ContinueStmt@74..82 52 | Continue@74..82 "continue" 53 | Whitespace@82..83 " " 54 | ExprStmt@83..86 55 | IntLiteral@83..85 56 | Int@83..85 "42" 57 | Semicolon@85..86 ";" 58 | Whitespace@86..87 "\n" 59 | RBrace@87..88 "}" 60 | error at 68: missing Semicolon 61 | error at 82: missing Semicolon 62 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/call.test: -------------------------------------------------------------------------------- 1 | foo(); 2 | === 3 | Root@0..6 4 | ExprStmt@0..6 5 | Call@0..5 6 | VarRef@0..3 7 | Ident@0..3 "foo" 8 | ArgList@3..5 9 | LParen@3..4 "(" 10 | RParen@4..5 ")" 11 | Semicolon@5..6 ";" 12 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/call_end_at_comma.test: -------------------------------------------------------------------------------- 1 | foo(bar, 2 | === 3 | Root@0..8 4 | ExprStmt@0..8 5 | Call@0..8 6 | VarRef@0..3 7 | Ident@0..3 "foo" 8 | ArgList@3..8 9 | LParen@3..4 "(" 10 | Arg@4..7 11 | VarRef@4..7 12 | Ident@4..7 "bar" 13 | Comma@7..8 "," 14 | error at 8: missing argument 15 | error at 8: missing RParen 16 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/call_end_at_open_eof.test: -------------------------------------------------------------------------------- 1 | foo( 2 | === 3 | Root@0..4 4 | ExprStmt@0..4 5 | Call@0..4 6 | VarRef@0..3 7 | Ident@0..3 "foo" 8 | ArgList@3..4 9 | LParen@3..4 "(" 10 | error at 4: missing argument 11 | error at 4: missing RParen 12 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/call_end_at_open_semicolon.test: -------------------------------------------------------------------------------- 1 | foo(; 2 | === 3 | Root@0..5 4 | ExprStmt@0..5 5 | Call@0..4 6 | VarRef@0..3 7 | Ident@0..3 "foo" 8 | ArgList@3..4 9 | LParen@3..4 "(" 10 | Semicolon@4..5 ";" 11 | error at 4: missing argument 12 | error at 4: missing RParen 13 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/call_nested.test: -------------------------------------------------------------------------------- 1 | foo.bar(42); 2 | === 3 | Root@0..12 4 | ExprStmt@0..12 5 | Call@0..11 6 | Path@0..7 7 | VarRef@0..3 8 | Ident@0..3 "foo" 9 | Dot@3..4 "." 10 | Ident@4..7 "bar" 11 | ArgList@7..11 12 | LParen@7..8 "(" 13 | Arg@8..10 14 | IntLiteral@8..10 15 | Int@8..10 "42" 16 | RParen@10..11 ")" 17 | Semicolon@11..12 ";" 18 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/call_with_args.test: -------------------------------------------------------------------------------- 1 | bar(42, "hello", 7 * 6); 2 | === 3 | Root@0..24 4 | ExprStmt@0..24 5 | Call@0..23 6 | VarRef@0..3 7 | Ident@0..3 "bar" 8 | ArgList@3..23 9 | LParen@3..4 "(" 10 | Arg@4..6 11 | IntLiteral@4..6 12 | Int@4..6 "42" 13 | Comma@6..7 "," 14 | Whitespace@7..8 " " 15 | Arg@8..15 16 | StringLiteral@8..15 17 | DoubleQuote@8..9 "\"" 18 | StringContents@9..14 "hello" 19 | DoubleQuote@14..15 "\"" 20 | Comma@15..16 "," 21 | Whitespace@16..17 " " 22 | Arg@17..22 23 | BinaryExpr@17..22 24 | IntLiteral@17..18 25 | Int@17..18 "7" 26 | Whitespace@18..19 " " 27 | Asterisk@19..20 "*" 28 | Whitespace@20..21 " " 29 | IntLiteral@21..22 30 | Int@21..22 "6" 31 | RParen@22..23 ")" 32 | Semicolon@23..24 ";" 33 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/cast.test: -------------------------------------------------------------------------------- 1 | foo.(bar) 2 | === 3 | Root@0..9 4 | ExprStmt@0..9 5 | CastExpr@0..9 6 | Ty@0..3 7 | VarRef@0..3 8 | Ident@0..3 "foo" 9 | Dot@3..4 "." 10 | LParen@4..5 "(" 11 | VarRef@5..8 12 | Ident@5..8 "bar" 13 | RParen@8..9 ")" 14 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/cast_array.test: -------------------------------------------------------------------------------- 1 | [10]i32.(my_array) 2 | === 3 | Root@0..18 4 | ExprStmt@0..18 5 | CastExpr@0..18 6 | Ty@0..7 7 | ArrayDecl@0..7 8 | ArraySize@0..4 9 | LBrack@0..1 "[" 10 | IntLiteral@1..3 11 | Int@1..3 "10" 12 | RBrack@3..4 "]" 13 | Ty@4..7 14 | VarRef@4..7 15 | Ident@4..7 "i32" 16 | Dot@7..8 "." 17 | LParen@8..9 "(" 18 | VarRef@9..17 19 | Ident@9..17 "my_array" 20 | RParen@17..18 ")" 21 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/cast_better_ptr.test: -------------------------------------------------------------------------------- 1 | (^foo).(^bar) 2 | === 3 | Root@0..13 4 | ExprStmt@0..13 5 | CastExpr@0..13 6 | Ty@0..6 7 | ParenExpr@0..6 8 | LParen@0..1 "(" 9 | RefExpr@1..5 10 | Caret@1..2 "^" 11 | VarRef@2..5 12 | Ident@2..5 "foo" 13 | RParen@5..6 ")" 14 | Dot@6..7 "." 15 | LParen@7..8 "(" 16 | RefExpr@8..12 17 | Caret@8..9 "^" 18 | VarRef@9..12 19 | Ident@9..12 "bar" 20 | RParen@12..13 ")" 21 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/cast_better_ptr_nested.test: -------------------------------------------------------------------------------- 1 | (^foo).((^bar).((^baz).(^qux))) 2 | // todo: maybe change this behavior 3 | === 4 | Root@0..67 5 | ExprStmt@0..31 6 | CastExpr@0..31 7 | Ty@0..6 8 | ParenExpr@0..6 9 | LParen@0..1 "(" 10 | RefExpr@1..5 11 | Caret@1..2 "^" 12 | VarRef@2..5 13 | Ident@2..5 "foo" 14 | RParen@5..6 ")" 15 | Dot@6..7 "." 16 | LParen@7..8 "(" 17 | CastExpr@8..30 18 | Ty@8..14 19 | ParenExpr@8..14 20 | LParen@8..9 "(" 21 | RefExpr@9..13 22 | Caret@9..10 "^" 23 | VarRef@10..13 24 | Ident@10..13 "bar" 25 | RParen@13..14 ")" 26 | Dot@14..15 "." 27 | LParen@15..16 "(" 28 | CastExpr@16..29 29 | Ty@16..22 30 | ParenExpr@16..22 31 | LParen@16..17 "(" 32 | RefExpr@17..21 33 | Caret@17..18 "^" 34 | VarRef@18..21 35 | Ident@18..21 "baz" 36 | RParen@21..22 ")" 37 | Dot@22..23 "." 38 | LParen@23..24 "(" 39 | RefExpr@24..28 40 | Caret@24..25 "^" 41 | VarRef@25..28 42 | Ident@25..28 "qux" 43 | RParen@28..29 ")" 44 | RParen@29..30 ")" 45 | RParen@30..31 ")" 46 | Whitespace@31..32 "\n" 47 | Comment@32..67 48 | CommentLeader@32..34 "//" 49 | CommentContents@34..67 " todo: maybe change this behavior" 50 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/cast_empty.test: -------------------------------------------------------------------------------- 1 | foo.() 2 | === 3 | Root@0..6 4 | ExprStmt@0..6 5 | CastExpr@0..6 6 | Ty@0..3 7 | VarRef@0..3 8 | Ident@0..3 "foo" 9 | Dot@3..4 "." 10 | LParen@4..5 "(" 11 | RParen@5..6 ")" 12 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/cast_nested.test: -------------------------------------------------------------------------------- 1 | foo.(bar.(baz.(qux))) 2 | === 3 | Root@0..21 4 | ExprStmt@0..21 5 | CastExpr@0..21 6 | Ty@0..3 7 | VarRef@0..3 8 | Ident@0..3 "foo" 9 | Dot@3..4 "." 10 | LParen@4..5 "(" 11 | CastExpr@5..20 12 | Ty@5..8 13 | VarRef@5..8 14 | Ident@5..8 "bar" 15 | Dot@8..9 "." 16 | LParen@9..10 "(" 17 | CastExpr@10..19 18 | Ty@10..13 19 | VarRef@10..13 20 | Ident@10..13 "baz" 21 | Dot@13..14 "." 22 | LParen@14..15 "(" 23 | VarRef@15..18 24 | Ident@15..18 "qux" 25 | RParen@18..19 ")" 26 | RParen@19..20 ")" 27 | RParen@20..21 ")" 28 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/cast_no_type.test: -------------------------------------------------------------------------------- 1 | .(foo) 2 | === 3 | Root@0..6 4 | ExprStmt@0..6 5 | CastExpr@0..6 6 | Dot@0..1 "." 7 | LParen@1..2 "(" 8 | VarRef@2..5 9 | Ident@2..5 "foo" 10 | RParen@5..6 ")" 11 | error at 1: missing type 12 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/cast_ptr.test: -------------------------------------------------------------------------------- 1 | ^foo.(^bar) 2 | === 3 | Root@0..11 4 | ExprStmt@0..11 5 | RefExpr@0..11 6 | Caret@0..1 "^" 7 | CastExpr@1..11 8 | Ty@1..4 9 | VarRef@1..4 10 | Ident@1..4 "foo" 11 | Dot@4..5 "." 12 | LParen@5..6 "(" 13 | RefExpr@6..10 14 | Caret@6..7 "^" 15 | VarRef@7..10 16 | Ident@7..10 "bar" 17 | RParen@10..11 ")" 18 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/cast_ptr_nested.test: -------------------------------------------------------------------------------- 1 | ^foo.(^bar.(^baz.(^qux))) 2 | // todo: maybe change this behavior 3 | === 4 | Root@0..61 5 | ExprStmt@0..25 6 | RefExpr@0..25 7 | Caret@0..1 "^" 8 | CastExpr@1..25 9 | Ty@1..4 10 | VarRef@1..4 11 | Ident@1..4 "foo" 12 | Dot@4..5 "." 13 | LParen@5..6 "(" 14 | RefExpr@6..24 15 | Caret@6..7 "^" 16 | CastExpr@7..24 17 | Ty@7..10 18 | VarRef@7..10 19 | Ident@7..10 "bar" 20 | Dot@10..11 "." 21 | LParen@11..12 "(" 22 | RefExpr@12..23 23 | Caret@12..13 "^" 24 | CastExpr@13..23 25 | Ty@13..16 26 | VarRef@13..16 27 | Ident@13..16 "baz" 28 | Dot@16..17 "." 29 | LParen@17..18 "(" 30 | RefExpr@18..22 31 | Caret@18..19 "^" 32 | VarRef@19..22 33 | Ident@19..22 "qux" 34 | RParen@22..23 ")" 35 | RParen@23..24 ")" 36 | RParen@24..25 ")" 37 | Whitespace@25..26 "\n" 38 | Comment@26..61 39 | CommentLeader@26..28 "//" 40 | CommentContents@28..61 " todo: maybe change this behavior" 41 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/cast_unary_expr.test: -------------------------------------------------------------------------------- 1 | usize.(-15); 2 | === 3 | Root@0..12 4 | ExprStmt@0..12 5 | CastExpr@0..11 6 | Ty@0..5 7 | VarRef@0..5 8 | Ident@0..5 "usize" 9 | Dot@5..6 "." 10 | LParen@6..7 "(" 11 | UnaryExpr@7..10 12 | Hyphen@7..8 "-" 13 | IntLiteral@8..10 14 | Int@8..10 "15" 15 | RParen@10..11 ")" 16 | Semicolon@11..12 ";" 17 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/char.test: -------------------------------------------------------------------------------- 1 | 'hello'; 2 | === 3 | Root@0..8 4 | ExprStmt@0..8 5 | CharLiteral@0..7 6 | SingleQuote@0..1 "'" 7 | StringContents@1..6 "hello" 8 | SingleQuote@6..7 "'" 9 | Semicolon@7..8 ";" 10 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/char_no_close.test: -------------------------------------------------------------------------------- 1 | ' 2 | === 3 | Root@0..1 4 | ExprStmt@0..1 5 | CharLiteral@0..1 6 | SingleQuote@0..1 "'" 7 | error at 1: missing SingleQuote 8 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/char_with_quote_escape.test: -------------------------------------------------------------------------------- 1 | '\'hello\''; 2 | === 3 | Root@0..12 4 | ExprStmt@0..12 5 | CharLiteral@0..11 6 | SingleQuote@0..1 "'" 7 | Escape@1..3 "\\'" 8 | StringContents@3..8 "hello" 9 | Escape@8..10 "\\'" 10 | SingleQuote@10..11 "'" 11 | Semicolon@11..12 ";" 12 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/comment.test: -------------------------------------------------------------------------------- 1 | // hello world! 2 | === 3 | Root@0..15 4 | Comment@0..15 5 | CommentLeader@0..2 "//" 6 | CommentContents@2..15 " hello world!" 7 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/comptime_block.test: -------------------------------------------------------------------------------- 1 | comptime { 2 | foo := 5; 3 | foo 4 | } 5 | === 6 | Root@0..38 7 | ExprStmt@0..38 8 | ComptimeExpr@0..38 9 | Comptime@0..8 "comptime" 10 | Whitespace@8..9 " " 11 | Block@9..38 12 | LBrace@9..10 "{" 13 | Whitespace@10..15 "\n " 14 | VarDef@15..24 15 | Ident@15..18 "foo" 16 | Whitespace@18..19 " " 17 | Colon@19..20 ":" 18 | Equals@20..21 "=" 19 | Whitespace@21..22 " " 20 | IntLiteral@22..23 21 | Int@22..23 "5" 22 | Semicolon@23..24 ";" 23 | Whitespace@24..29 "\n " 24 | VarRef@29..32 25 | Ident@29..32 "foo" 26 | Whitespace@32..37 " \n" 27 | RBrace@37..38 "}" 28 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/comptime_expr.test: -------------------------------------------------------------------------------- 1 | comptime 1 + 1 2 | === 3 | Root@0..14 4 | ExprStmt@0..14 5 | ComptimeExpr@0..14 6 | Comptime@0..8 "comptime" 7 | Whitespace@8..9 " " 8 | BinaryExpr@9..14 9 | IntLiteral@9..10 10 | Int@9..10 "1" 11 | Whitespace@10..11 " " 12 | Plus@11..12 "+" 13 | Whitespace@12..13 " " 14 | IntLiteral@13..14 15 | Int@13..14 "1" 16 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/defer.test: -------------------------------------------------------------------------------- 1 | defer foo.bar(); 2 | === 3 | Root@0..16 4 | DeferStmt@0..16 5 | Defer@0..5 "defer" 6 | Whitespace@5..6 " " 7 | Call@6..15 8 | Path@6..13 9 | VarRef@6..9 10 | Ident@6..9 "foo" 11 | Dot@9..10 "." 12 | Ident@10..13 "bar" 13 | ArgList@13..15 14 | LParen@13..14 "(" 15 | RParen@14..15 ")" 16 | Semicolon@15..16 ";" 17 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/defer_missing.test: -------------------------------------------------------------------------------- 1 | defer ; 2 | === 3 | Root@0..7 4 | DeferStmt@0..7 5 | Defer@0..5 "defer" 6 | Whitespace@5..6 " " 7 | Semicolon@6..7 ";" 8 | error at 5: missing defer expression 9 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/empty.test: -------------------------------------------------------------------------------- 1 | 2 | === 3 | Root@0..0 4 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/empty_block.test: -------------------------------------------------------------------------------- 1 | {}; 2 | === 3 | Root@0..3 4 | ExprStmt@0..2 5 | Block@0..2 6 | LBrace@0..1 "{" 7 | RBrace@1..2 "}" 8 | Semicolon@2..3 ";" 9 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/empty_char.test: -------------------------------------------------------------------------------- 1 | '' 2 | === 3 | Root@0..2 4 | ExprStmt@0..2 5 | CharLiteral@0..2 6 | SingleQuote@0..1 "'" 7 | SingleQuote@1..2 "'" 8 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/empty_lambda.test: -------------------------------------------------------------------------------- 1 | () {}; 2 | === 3 | Root@0..6 4 | ExprStmt@0..6 5 | Lambda@0..5 6 | ParamList@0..2 7 | LParen@0..1 "(" 8 | RParen@1..2 ")" 9 | Whitespace@2..3 " " 10 | Block@3..5 11 | LBrace@3..4 "{" 12 | RBrace@4..5 "}" 13 | Semicolon@5..6 ";" 14 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/empty_string.test: -------------------------------------------------------------------------------- 1 | ""; 2 | === 3 | Root@0..3 4 | ExprStmt@0..3 5 | StringLiteral@0..2 6 | DoubleQuote@0..1 "\"" 7 | DoubleQuote@1..2 "\"" 8 | Semicolon@2..3 ";" 9 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/enum_empty.test: -------------------------------------------------------------------------------- 1 | enum {}; 2 | === 3 | Root@0..8 4 | ExprStmt@0..8 5 | EnumDecl@0..7 6 | Enum@0..4 "enum" 7 | Whitespace@4..5 " " 8 | LBrace@5..6 "{" 9 | RBrace@6..7 "}" 10 | Semicolon@7..8 ";" 11 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/enum_end_at_enum.test: -------------------------------------------------------------------------------- 1 | enum 2 | === 3 | Root@0..4 4 | ExprStmt@0..4 5 | EnumDecl@0..4 6 | Enum@0..4 "enum" 7 | error at 4: missing enum body 8 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/enum_end_at_open_eof.test: -------------------------------------------------------------------------------- 1 | enum{ 2 | === 3 | Root@0..5 4 | ExprStmt@0..5 5 | EnumDecl@0..5 6 | Enum@0..4 "enum" 7 | LBrace@4..5 "{" 8 | VariantDecl@5..5 9 | error at 5: missing variant name 10 | error at 5: missing RBrace 11 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/enum_end_at_open_random.test: -------------------------------------------------------------------------------- 1 | enum{) 2 | === 3 | Root@0..6 4 | ExprStmt@0..6 5 | EnumDecl@0..6 6 | Enum@0..4 "enum" 7 | LBrace@4..5 "{" 8 | VariantDecl@5..6 9 | Error@5..6 10 | RParen@5..6 ")" 11 | error at 5..6: expected variant name but found RParen 12 | error at 6: missing RBrace 13 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/enum_end_at_open_semicolon.test: -------------------------------------------------------------------------------- 1 | enum{; 2 | === 3 | Root@0..6 4 | ExprStmt@0..6 5 | EnumDecl@0..5 6 | Enum@0..4 "enum" 7 | LBrace@4..5 "{" 8 | VariantDecl@5..5 9 | Semicolon@5..6 ";" 10 | error at 5: missing variant name 11 | error at 5: missing RBrace 12 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/enum_one_discriminant_variant.test: -------------------------------------------------------------------------------- 1 | enum { 2 | MyCoolVariant | 42 3 | } 4 | === 5 | Root@0..31 6 | ExprStmt@0..31 7 | EnumDecl@0..31 8 | Enum@0..4 "enum" 9 | Whitespace@4..5 " " 10 | LBrace@5..6 "{" 11 | Whitespace@6..11 "\n " 12 | VariantDecl@11..29 13 | Ident@11..24 "MyCoolVariant" 14 | Whitespace@24..25 " " 15 | Discriminant@25..29 16 | Pipe@25..26 "|" 17 | Whitespace@26..27 " " 18 | IntLiteral@27..29 19 | Int@27..29 "42" 20 | Whitespace@29..30 "\n" 21 | RBrace@30..31 "}" 22 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/enum_one_empty_variant.test: -------------------------------------------------------------------------------- 1 | enum { 2 | Hello 3 | }; 4 | === 5 | Root@0..19 6 | ExprStmt@0..19 7 | EnumDecl@0..18 8 | Enum@0..4 "enum" 9 | Whitespace@4..5 " " 10 | LBrace@5..6 "{" 11 | Whitespace@6..11 "\n " 12 | VariantDecl@11..16 13 | Ident@11..16 "Hello" 14 | Whitespace@16..17 "\n" 15 | RBrace@17..18 "}" 16 | Semicolon@18..19 ";" 17 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/enum_one_typed_variant.test: -------------------------------------------------------------------------------- 1 | enum { 2 | WhatsUp: i32, 3 | } 4 | === 5 | Root@0..26 6 | ExprStmt@0..26 7 | EnumDecl@0..26 8 | Enum@0..4 "enum" 9 | Whitespace@4..5 " " 10 | LBrace@5..6 "{" 11 | Whitespace@6..11 "\n " 12 | VariantDecl@11..23 13 | Ident@11..18 "WhatsUp" 14 | Colon@18..19 ":" 15 | Whitespace@19..20 " " 16 | Ty@20..23 17 | VarRef@20..23 18 | Ident@20..23 "i32" 19 | Comma@23..24 "," 20 | Whitespace@24..25 "\n" 21 | RBrace@25..26 "}" 22 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/hex_literal_addition.test: -------------------------------------------------------------------------------- 1 | 0x89 + 0x0a 2 | === 3 | Root@0..11 4 | ExprStmt@0..11 5 | BinaryExpr@0..11 6 | IntLiteral@0..4 7 | Hex@0..4 "0x89" 8 | Whitespace@4..5 " " 9 | Plus@5..6 "+" 10 | Whitespace@6..7 " " 11 | IntLiteral@7..11 12 | Hex@7..11 "0x0a" 13 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/hex_literal_lowercase.test: -------------------------------------------------------------------------------- 1 | 0xfe 2 | === 3 | Root@0..4 4 | ExprStmt@0..4 5 | IntLiteral@0..4 6 | Hex@0..4 "0xfe" 7 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/hex_literal_mix.test: -------------------------------------------------------------------------------- 1 | 0x0123456789abcdefABCDEF 2 | === 3 | Root@0..24 4 | ExprStmt@0..24 5 | IntLiteral@0..24 6 | Hex@0..24 "0x0123456789abcdefABCDEF" 7 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/hex_literal_uppercase.test: -------------------------------------------------------------------------------- 1 | 0x1A 2 | === 3 | Root@0..4 4 | ExprStmt@0..4 5 | IntLiteral@0..4 6 | Hex@0..4 "0x1A" 7 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/import.test: -------------------------------------------------------------------------------- 1 | #import("hello.capy") 2 | === 3 | Root@0..21 4 | ExprStmt@0..21 5 | Directive@0..21 6 | Hash@0..1 "#" 7 | Ident@1..7 "import" 8 | ArgList@7..21 9 | LParen@7..8 "(" 10 | Arg@8..20 11 | StringLiteral@8..20 12 | DoubleQuote@8..9 "\"" 13 | StringContents@9..19 "hello.capy" 14 | DoubleQuote@19..20 "\"" 15 | RParen@20..21 ")" 16 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/import_old.test: -------------------------------------------------------------------------------- 1 | import "hello.capy" 2 | === 3 | Root@0..19 4 | ExprStmt@0..19 5 | Directive@0..19 6 | Ident@0..6 "import" 7 | Whitespace@6..7 " " 8 | ArgList@7..19 9 | Arg@7..19 10 | StringLiteral@7..19 11 | DoubleQuote@7..8 "\"" 12 | StringContents@8..18 "hello.capy" 13 | DoubleQuote@18..19 "\"" 14 | error at 0: missing Hash 15 | error at 6: missing LParen 16 | error at 19: missing RParen 17 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/index_ref_with_num.test: -------------------------------------------------------------------------------- 1 | my_array[0] 2 | === 3 | Root@0..11 4 | ExprStmt@0..11 5 | IndexExpr@0..11 6 | Source@0..8 7 | VarRef@0..8 8 | Ident@0..8 "my_array" 9 | LBrack@8..9 "[" 10 | Index@9..10 11 | IntLiteral@9..10 12 | Int@9..10 "0" 13 | RBrack@10..11 "]" 14 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/index_ref_with_ref.test: -------------------------------------------------------------------------------- 1 | my_array[idx] 2 | === 3 | Root@0..13 4 | ExprStmt@0..13 5 | IndexExpr@0..13 6 | Source@0..8 7 | VarRef@0..8 8 | Ident@0..8 "my_array" 9 | LBrack@8..9 "[" 10 | Index@9..12 11 | VarRef@9..12 12 | Ident@9..12 "idx" 13 | RBrack@12..13 "]" 14 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/int_literal.test: -------------------------------------------------------------------------------- 1 | 42; 2 | === 3 | Root@0..3 4 | ExprStmt@0..3 5 | IntLiteral@0..2 6 | Int@0..2 "42" 7 | Semicolon@2..3 ";" 8 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/int_literal_addition.test: -------------------------------------------------------------------------------- 1 | 1 + 2; 2 | === 3 | Root@0..6 4 | ExprStmt@0..6 5 | BinaryExpr@0..5 6 | IntLiteral@0..1 7 | Int@0..1 "1" 8 | Whitespace@1..2 " " 9 | Plus@2..3 "+" 10 | Whitespace@3..4 " " 11 | IntLiteral@4..5 12 | Int@4..5 "2" 13 | Semicolon@5..6 ";" 14 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/int_literal_division.test: -------------------------------------------------------------------------------- 1 | 1 / 2; 2 | === 3 | Root@0..6 4 | ExprStmt@0..6 5 | BinaryExpr@0..5 6 | IntLiteral@0..1 7 | Int@0..1 "1" 8 | Whitespace@1..2 " " 9 | Slash@2..3 "/" 10 | Whitespace@3..4 " " 11 | IntLiteral@4..5 12 | Int@4..5 "2" 13 | Semicolon@5..6 ";" 14 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/int_literal_with_e.test: -------------------------------------------------------------------------------- 1 | 42e9 2 | === 3 | Root@0..4 4 | ExprStmt@0..4 5 | IntLiteral@0..4 6 | Int@0..4 "42e9" 7 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/label.test: -------------------------------------------------------------------------------- 1 | `blk: { x := 5; x = 2; x } 2 | === 3 | Root@0..26 4 | ExprStmt@0..26 5 | Block@0..26 6 | LabelDecl@0..5 7 | Backtick@0..1 "`" 8 | Ident@1..4 "blk" 9 | Colon@4..5 ":" 10 | Whitespace@5..6 " " 11 | LBrace@6..7 "{" 12 | Whitespace@7..8 " " 13 | VarDef@8..15 14 | Ident@8..9 "x" 15 | Whitespace@9..10 " " 16 | Colon@10..11 ":" 17 | Equals@11..12 "=" 18 | Whitespace@12..13 " " 19 | IntLiteral@13..14 20 | Int@13..14 "5" 21 | Semicolon@14..15 ";" 22 | Whitespace@15..16 " " 23 | Assign@16..22 24 | Source@16..17 25 | VarRef@16..17 26 | Ident@16..17 "x" 27 | Whitespace@17..18 " " 28 | Equals@18..19 "=" 29 | Whitespace@19..20 " " 30 | IntLiteral@20..21 31 | Int@20..21 "2" 32 | Semicolon@21..22 ";" 33 | Whitespace@22..23 " " 34 | VarRef@23..24 35 | Ident@23..24 "x" 36 | Whitespace@24..25 " " 37 | RBrace@25..26 "}" 38 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/label_end_at_backtick.test: -------------------------------------------------------------------------------- 1 | ` 2 | === 3 | Root@0..1 4 | LabelDecl@0..1 5 | Backtick@0..1 "`" 6 | error at 1: missing label name 7 | error at 1: missing Colon 8 | error at 1: missing block 9 | error at 1: missing statement 10 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/label_end_at_colon.test: -------------------------------------------------------------------------------- 1 | `my_label: 2 | === 3 | Root@0..10 4 | LabelDecl@0..10 5 | Backtick@0..1 "`" 6 | Ident@1..9 "my_label" 7 | Colon@9..10 ":" 8 | error at 10: missing block 9 | error at 10: missing statement 10 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/label_end_at_name.test: -------------------------------------------------------------------------------- 1 | `my_label 2 | === 3 | Root@0..9 4 | LabelDecl@0..9 5 | Backtick@0..1 "`" 6 | Ident@1..9 "my_label" 7 | error at 9: missing Colon 8 | error at 9: missing block 9 | error at 9: missing statement 10 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/label_if.test: -------------------------------------------------------------------------------- 1 | `my_if: if true { 2 | 12 3 | } else { 4 | 42 5 | } 6 | === 7 | Root@0..38 8 | LabelDecl@0..7 9 | Backtick@0..1 "`" 10 | Ident@1..6 "my_if" 11 | Colon@6..7 ":" 12 | Whitespace@7..8 " " 13 | ExprStmt@8..38 14 | IfExpr@8..38 15 | If@8..10 "if" 16 | Whitespace@10..11 " " 17 | BoolLiteral@11..15 18 | Bool@11..15 "true" 19 | Whitespace@15..16 " " 20 | Block@16..24 21 | LBrace@16..17 "{" 22 | Whitespace@17..20 "\n " 23 | IntLiteral@20..22 24 | Int@20..22 "12" 25 | Whitespace@22..23 "\n" 26 | RBrace@23..24 "}" 27 | Whitespace@24..25 " " 28 | ElseBranch@25..38 29 | Else@25..29 "else" 30 | Whitespace@29..30 " " 31 | Block@30..38 32 | LBrace@30..31 "{" 33 | Whitespace@31..34 "\n " 34 | IntLiteral@34..36 35 | Int@34..36 "42" 36 | Whitespace@36..37 "\n" 37 | RBrace@37..38 "}" 38 | error at 7: missing block 39 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/label_loop.test: -------------------------------------------------------------------------------- 1 | `my_loop: while x > 0 { 2 | print("Hello!"); 3 | } 4 | === 5 | Root@0..44 6 | ExprStmt@0..44 7 | WhileExpr@0..44 8 | LabelDecl@0..9 9 | Backtick@0..1 "`" 10 | Ident@1..8 "my_loop" 11 | Colon@8..9 ":" 12 | Whitespace@9..10 " " 13 | While@10..15 "while" 14 | Whitespace@15..16 " " 15 | Condition@16..21 16 | BinaryExpr@16..21 17 | VarRef@16..17 18 | Ident@16..17 "x" 19 | Whitespace@17..18 " " 20 | Right@18..19 ">" 21 | Whitespace@19..20 " " 22 | IntLiteral@20..21 23 | Int@20..21 "0" 24 | Whitespace@21..22 " " 25 | Block@22..44 26 | LBrace@22..23 "{" 27 | Whitespace@23..26 "\n " 28 | ExprStmt@26..42 29 | Call@26..41 30 | VarRef@26..31 31 | Ident@26..31 "print" 32 | ArgList@31..41 33 | LParen@31..32 "(" 34 | Arg@32..40 35 | StringLiteral@32..40 36 | DoubleQuote@32..33 "\"" 37 | StringContents@33..39 "Hello!" 38 | DoubleQuote@39..40 "\"" 39 | RParen@40..41 ")" 40 | Semicolon@41..42 ";" 41 | Whitespace@42..43 "\n" 42 | RBrace@43..44 "}" 43 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/lambda_comma_at_end.test: -------------------------------------------------------------------------------- 1 | (x: foo, y: bar, z: baz, w: qux,) {}; 2 | === 3 | Root@0..37 4 | ExprStmt@0..37 5 | Lambda@0..36 6 | ParamList@0..33 7 | LParen@0..1 "(" 8 | Param@1..7 9 | Ident@1..2 "x" 10 | Colon@2..3 ":" 11 | Whitespace@3..4 " " 12 | Ty@4..7 13 | VarRef@4..7 14 | Ident@4..7 "foo" 15 | Comma@7..8 "," 16 | Whitespace@8..9 " " 17 | Param@9..15 18 | Ident@9..10 "y" 19 | Colon@10..11 ":" 20 | Whitespace@11..12 " " 21 | Ty@12..15 22 | VarRef@12..15 23 | Ident@12..15 "bar" 24 | Comma@15..16 "," 25 | Whitespace@16..17 " " 26 | Param@17..23 27 | Ident@17..18 "z" 28 | Colon@18..19 ":" 29 | Whitespace@19..20 " " 30 | Ty@20..23 31 | VarRef@20..23 32 | Ident@20..23 "baz" 33 | Comma@23..24 "," 34 | Whitespace@24..25 " " 35 | Param@25..31 36 | Ident@25..26 "w" 37 | Colon@26..27 ":" 38 | Whitespace@27..28 " " 39 | Ty@28..31 40 | VarRef@28..31 41 | Ident@28..31 "qux" 42 | Comma@31..32 "," 43 | RParen@32..33 ")" 44 | Whitespace@33..34 " " 45 | Block@34..36 46 | LBrace@34..35 "{" 47 | RBrace@35..36 "}" 48 | Semicolon@36..37 ";" 49 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/lambda_end_at_arrow.test: -------------------------------------------------------------------------------- 1 | () -> 2 | === 3 | Root@0..5 4 | ExprStmt@0..5 5 | Lambda@0..5 6 | ParamList@0..2 7 | LParen@0..1 "(" 8 | RParen@1..2 ")" 9 | Whitespace@2..3 " " 10 | Arrow@3..5 "->" 11 | error at 5: missing return type 12 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/lambda_end_at_comma.test: -------------------------------------------------------------------------------- 1 | (x: i32, 2 | === 3 | Root@0..8 4 | ExprStmt@0..8 5 | Lambda@0..8 6 | ParamList@0..8 7 | LParen@0..1 "(" 8 | Param@1..7 9 | Ident@1..2 "x" 10 | Colon@2..3 ":" 11 | Whitespace@3..4 " " 12 | Ty@4..7 13 | VarRef@4..7 14 | Ident@4..7 "i32" 15 | Comma@7..8 "," 16 | Param@8..8 17 | error at 8: missing parameter name 18 | error at 8: missing Colon 19 | error at 8: missing parameter type 20 | error at 8: missing RParen 21 | error at 8: missing Arrow 22 | error at 8: missing return type 23 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/lambda_end_at_open_eof.test: -------------------------------------------------------------------------------- 1 | ( 2 | === 3 | Root@0..1 4 | ExprStmt@0..1 5 | Lambda@0..1 6 | ParamList@0..1 7 | LParen@0..1 "(" 8 | Param@1..1 9 | error at 1: missing parameter name 10 | error at 1: missing Colon 11 | error at 1: missing parameter type 12 | error at 1: missing RParen 13 | error at 1: missing Arrow 14 | error at 1: missing return type 15 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/lambda_end_at_return_ty.test: -------------------------------------------------------------------------------- 1 | (x: i32) -> void 2 | === 3 | Root@0..16 4 | ExprStmt@0..16 5 | Lambda@0..16 6 | ParamList@0..8 7 | LParen@0..1 "(" 8 | Param@1..7 9 | Ident@1..2 "x" 10 | Colon@2..3 ":" 11 | Whitespace@3..4 " " 12 | Ty@4..7 13 | VarRef@4..7 14 | Ident@4..7 "i32" 15 | RParen@7..8 ")" 16 | Whitespace@8..9 " " 17 | Arrow@9..11 "->" 18 | Whitespace@11..12 " " 19 | Ty@12..16 20 | VarRef@12..16 21 | Ident@12..16 "void" 22 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/lambda_end_at_rparen.test: -------------------------------------------------------------------------------- 1 | (x: i32) 2 | === 3 | Root@0..8 4 | ExprStmt@0..8 5 | Lambda@0..8 6 | ParamList@0..8 7 | LParen@0..1 "(" 8 | Param@1..7 9 | Ident@1..2 "x" 10 | Colon@2..3 ":" 11 | Whitespace@3..4 " " 12 | Ty@4..7 13 | VarRef@4..7 14 | Ident@4..7 "i32" 15 | RParen@7..8 ")" 16 | error at 8: missing Arrow 17 | error at 8: missing return type 18 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/lambda_extern.test: -------------------------------------------------------------------------------- 1 | (x: i32) extern; 2 | === 3 | Root@0..16 4 | ExprStmt@0..16 5 | Lambda@0..15 6 | ParamList@0..8 7 | LParen@0..1 "(" 8 | Param@1..7 9 | Ident@1..2 "x" 10 | Colon@2..3 ":" 11 | Whitespace@3..4 " " 12 | Ty@4..7 13 | VarRef@4..7 14 | Ident@4..7 "i32" 15 | RParen@7..8 ")" 16 | Whitespace@8..9 " " 17 | Extern@9..15 "extern" 18 | Semicolon@15..16 ";" 19 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/lambda_multiple_params.test: -------------------------------------------------------------------------------- 1 | (x: foo, y: bar, z: baz, w: qux) {}; 2 | === 3 | Root@0..36 4 | ExprStmt@0..36 5 | Lambda@0..35 6 | ParamList@0..32 7 | LParen@0..1 "(" 8 | Param@1..7 9 | Ident@1..2 "x" 10 | Colon@2..3 ":" 11 | Whitespace@3..4 " " 12 | Ty@4..7 13 | VarRef@4..7 14 | Ident@4..7 "foo" 15 | Comma@7..8 "," 16 | Whitespace@8..9 " " 17 | Param@9..15 18 | Ident@9..10 "y" 19 | Colon@10..11 ":" 20 | Whitespace@11..12 " " 21 | Ty@12..15 22 | VarRef@12..15 23 | Ident@12..15 "bar" 24 | Comma@15..16 "," 25 | Whitespace@16..17 " " 26 | Param@17..23 27 | Ident@17..18 "z" 28 | Colon@18..19 ":" 29 | Whitespace@19..20 " " 30 | Ty@20..23 31 | VarRef@20..23 32 | Ident@20..23 "baz" 33 | Comma@23..24 "," 34 | Whitespace@24..25 " " 35 | Param@25..31 36 | Ident@25..26 "w" 37 | Colon@26..27 ":" 38 | Whitespace@27..28 " " 39 | Ty@28..31 40 | VarRef@28..31 41 | Ident@28..31 "qux" 42 | RParen@31..32 ")" 43 | Whitespace@32..33 " " 44 | Block@33..35 45 | LBrace@33..34 "{" 46 | RBrace@34..35 "}" 47 | Semicolon@35..36 ";" 48 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/lambda_one_param.test: -------------------------------------------------------------------------------- 1 | (x: i32) {}; 2 | === 3 | Root@0..12 4 | ExprStmt@0..12 5 | Lambda@0..11 6 | ParamList@0..8 7 | LParen@0..1 "(" 8 | Param@1..7 9 | Ident@1..2 "x" 10 | Colon@2..3 ":" 11 | Whitespace@3..4 " " 12 | Ty@4..7 13 | VarRef@4..7 14 | Ident@4..7 "i32" 15 | RParen@7..8 ")" 16 | Whitespace@8..9 " " 17 | Block@9..11 18 | LBrace@9..10 "{" 19 | RBrace@10..11 "}" 20 | Semicolon@11..12 ";" 21 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/lambda_second_variadic.test: -------------------------------------------------------------------------------- 1 | (first: i32, others: ...i32) { 2 | 3 | } 4 | === 5 | Root@0..33 6 | ExprStmt@0..33 7 | Lambda@0..33 8 | ParamList@0..28 9 | LParen@0..1 "(" 10 | Param@1..11 11 | Ident@1..6 "first" 12 | Colon@6..7 ":" 13 | Whitespace@7..8 " " 14 | Ty@8..11 15 | VarRef@8..11 16 | Ident@8..11 "i32" 17 | Comma@11..12 "," 18 | Whitespace@12..13 " " 19 | Param@13..27 20 | Ident@13..19 "others" 21 | Colon@19..20 ":" 22 | Whitespace@20..21 " " 23 | Ellipsis@21..24 "..." 24 | Ty@24..27 25 | VarRef@24..27 26 | Ident@24..27 "i32" 27 | RParen@27..28 ")" 28 | Whitespace@28..29 " " 29 | Block@29..33 30 | LBrace@29..30 "{" 31 | Whitespace@30..32 "\n\n" 32 | RBrace@32..33 "}" 33 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/lambda_single_variadic.test: -------------------------------------------------------------------------------- 1 | (args: ...any) { 2 | 3 | } 4 | === 5 | Root@0..19 6 | ExprStmt@0..19 7 | Lambda@0..19 8 | ParamList@0..14 9 | LParen@0..1 "(" 10 | Param@1..13 11 | Ident@1..5 "args" 12 | Colon@5..6 ":" 13 | Whitespace@6..7 " " 14 | Ellipsis@7..10 "..." 15 | Ty@10..13 16 | VarRef@10..13 17 | Ident@10..13 "any" 18 | RParen@13..14 ")" 19 | Whitespace@14..15 " " 20 | Block@15..19 21 | LBrace@15..16 "{" 22 | Whitespace@16..18 "\n\n" 23 | RBrace@18..19 "}" 24 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/lambda_with_return_type.test: -------------------------------------------------------------------------------- 1 | () -> i32 {}; 2 | === 3 | Root@0..13 4 | ExprStmt@0..13 5 | Lambda@0..12 6 | ParamList@0..2 7 | LParen@0..1 "(" 8 | RParen@1..2 ")" 9 | Whitespace@2..3 " " 10 | Arrow@3..5 "->" 11 | Whitespace@5..6 " " 12 | Ty@6..9 13 | VarRef@6..9 14 | Ident@6..9 "i32" 15 | Whitespace@9..10 " " 16 | Block@10..12 17 | LBrace@10..11 "{" 18 | RBrace@11..12 "}" 19 | Semicolon@12..13 ";" 20 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/loop.test: -------------------------------------------------------------------------------- 1 | loop { } 2 | === 3 | Root@0..8 4 | ExprStmt@0..8 5 | WhileExpr@0..8 6 | Loop@0..4 "loop" 7 | Whitespace@4..5 " " 8 | Block@5..8 9 | LBrace@5..6 "{" 10 | Whitespace@6..7 " " 11 | RBrace@7..8 "}" 12 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/member.test: -------------------------------------------------------------------------------- 1 | foo.bar.baz; 2 | === 3 | Root@0..12 4 | ExprStmt@0..12 5 | Path@0..11 6 | Path@0..7 7 | VarRef@0..3 8 | Ident@0..3 "foo" 9 | Dot@3..4 "." 10 | Ident@4..7 "bar" 11 | Dot@7..8 "." 12 | Ident@8..11 "baz" 13 | Semicolon@11..12 ";" 14 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/member_end_at_dot.test: -------------------------------------------------------------------------------- 1 | foo. 2 | === 3 | Root@0..4 4 | ExprStmt@0..4 5 | Path@0..4 6 | VarRef@0..3 7 | Ident@0..3 "foo" 8 | Dot@3..4 "." 9 | error at 4: missing field name 10 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/member_on_expr.test: -------------------------------------------------------------------------------- 1 | { 1 + 1 }.hello 2 | === 3 | Root@0..15 4 | ExprStmt@0..15 5 | Path@0..15 6 | Block@0..9 7 | LBrace@0..1 "{" 8 | Whitespace@1..2 " " 9 | BinaryExpr@2..7 10 | IntLiteral@2..3 11 | Int@2..3 "1" 12 | Whitespace@3..4 " " 13 | Plus@4..5 "+" 14 | Whitespace@5..6 " " 15 | IntLiteral@6..7 16 | Int@6..7 "1" 17 | Whitespace@7..8 " " 18 | RBrace@8..9 "}" 19 | Dot@9..10 "." 20 | Ident@10..15 "hello" 21 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/mod.test: -------------------------------------------------------------------------------- 1 | #mod("foo") 2 | === 3 | Root@0..11 4 | ExprStmt@0..11 5 | Directive@0..11 6 | Hash@0..1 "#" 7 | Ident@1..4 "mod" 8 | ArgList@4..11 9 | LParen@4..5 "(" 10 | Arg@5..10 11 | StringLiteral@5..10 12 | DoubleQuote@5..6 "\"" 13 | StringContents@6..9 "foo" 14 | DoubleQuote@9..10 "\"" 15 | RParen@10..11 ")" 16 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/mod_old.test: -------------------------------------------------------------------------------- 1 | mod "core" 2 | === 3 | Root@0..10 4 | ExprStmt@0..10 5 | Directive@0..10 6 | Ident@0..3 "mod" 7 | Whitespace@3..4 " " 8 | ArgList@4..10 9 | Arg@4..10 10 | StringLiteral@4..10 11 | DoubleQuote@4..5 "\"" 12 | StringContents@5..9 "core" 13 | DoubleQuote@9..10 "\"" 14 | error at 0: missing Hash 15 | error at 3: missing LParen 16 | error at 10: missing RParen 17 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/mut_eof.test: -------------------------------------------------------------------------------- 1 | mut 2 | === 3 | Root@0..3 4 | ExprStmt@0..3 5 | MutExpr@0..3 6 | Mut@0..3 "mut" 7 | error at 3: missing operand 8 | error at 0: missing Caret 9 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/mut_expr.test: -------------------------------------------------------------------------------- 1 | mut foo.bar 2 | === 3 | Root@0..11 4 | ExprStmt@0..11 5 | MutExpr@0..11 6 | Mut@0..3 "mut" 7 | Whitespace@3..4 " " 8 | Path@4..11 9 | VarRef@4..7 10 | Ident@4..7 "foo" 11 | Dot@7..8 "." 12 | Ident@8..11 "bar" 13 | error at 0: missing Caret 14 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/mut_foo.test: -------------------------------------------------------------------------------- 1 | mut foo 2 | === 3 | Root@0..7 4 | ExprStmt@0..7 5 | MutExpr@0..7 6 | Mut@0..3 "mut" 7 | Whitespace@3..4 " " 8 | VarRef@4..7 9 | Ident@4..7 "foo" 10 | error at 0: missing Caret 11 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/mut_rawptr.test: -------------------------------------------------------------------------------- 1 | mut rawptr 2 | === 3 | Root@0..10 4 | ExprStmt@0..10 5 | MutExpr@0..10 6 | Mut@0..3 "mut" 7 | Whitespace@3..4 " " 8 | VarRef@4..10 9 | Ident@4..10 "rawptr" 10 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/no_semicolon_block.test: -------------------------------------------------------------------------------- 1 | { 2 | { 3 | 4 | } 5 | 6 | { 7 | 8 | } 9 | } 10 | === 11 | Root@0..30 12 | ExprStmt@0..30 13 | Block@0..30 14 | LBrace@0..1 "{" 15 | Whitespace@1..6 "\n " 16 | ExprStmt@6..14 17 | Block@6..14 18 | LBrace@6..7 "{" 19 | Whitespace@7..13 "\n\n " 20 | RBrace@13..14 "}" 21 | Whitespace@14..20 "\n\n " 22 | Block@20..28 23 | LBrace@20..21 "{" 24 | Whitespace@21..27 "\n\n " 25 | RBrace@27..28 "}" 26 | Whitespace@28..29 "\n" 27 | RBrace@29..30 "}" 28 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/no_semicolon_comptime.test: -------------------------------------------------------------------------------- 1 | { 2 | comptime { 3 | 4 | } 5 | 6 | comptime { 7 | 8 | } 9 | } 10 | === 11 | Root@0..48 12 | ExprStmt@0..48 13 | Block@0..48 14 | LBrace@0..1 "{" 15 | Whitespace@1..6 "\n " 16 | ExprStmt@6..23 17 | ComptimeExpr@6..23 18 | Comptime@6..14 "comptime" 19 | Whitespace@14..15 " " 20 | Block@15..23 21 | LBrace@15..16 "{" 22 | Whitespace@16..22 "\n\n " 23 | RBrace@22..23 "}" 24 | Whitespace@23..29 "\n\n " 25 | ComptimeExpr@29..46 26 | Comptime@29..37 "comptime" 27 | Whitespace@37..38 " " 28 | Block@38..46 29 | LBrace@38..39 "{" 30 | Whitespace@39..45 "\n\n " 31 | RBrace@45..46 "}" 32 | Whitespace@46..47 "\n" 33 | RBrace@47..48 "}" 34 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/no_semicolon_if.test: -------------------------------------------------------------------------------- 1 | { 2 | if true { 3 | 4 | } 5 | 6 | if false { 7 | 8 | } 9 | } 10 | === 11 | Root@0..47 12 | ExprStmt@0..47 13 | Block@0..47 14 | LBrace@0..1 "{" 15 | Whitespace@1..6 "\n " 16 | ExprStmt@6..22 17 | IfExpr@6..22 18 | If@6..8 "if" 19 | Whitespace@8..9 " " 20 | BoolLiteral@9..13 21 | Bool@9..13 "true" 22 | Whitespace@13..14 " " 23 | Block@14..22 24 | LBrace@14..15 "{" 25 | Whitespace@15..21 "\n\n " 26 | RBrace@21..22 "}" 27 | Whitespace@22..28 "\n\n " 28 | IfExpr@28..45 29 | If@28..30 "if" 30 | Whitespace@30..31 " " 31 | BoolLiteral@31..36 32 | Bool@31..36 "false" 33 | Whitespace@36..37 " " 34 | Block@37..45 35 | LBrace@37..38 "{" 36 | Whitespace@38..44 "\n\n " 37 | RBrace@44..45 "}" 38 | Whitespace@45..46 "\n" 39 | RBrace@46..47 "}" 40 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/no_semicolon_while.test: -------------------------------------------------------------------------------- 1 | { 2 | while true { 3 | 4 | } 5 | 6 | loop { 7 | 8 | } 9 | } 10 | === 11 | Root@0..46 12 | ExprStmt@0..46 13 | Block@0..46 14 | LBrace@0..1 "{" 15 | Whitespace@1..6 "\n " 16 | ExprStmt@6..25 17 | WhileExpr@6..25 18 | While@6..11 "while" 19 | Whitespace@11..12 " " 20 | Condition@12..16 21 | BoolLiteral@12..16 22 | Bool@12..16 "true" 23 | Whitespace@16..17 " " 24 | Block@17..25 25 | LBrace@17..18 "{" 26 | Whitespace@18..24 "\n\n " 27 | RBrace@24..25 "}" 28 | Whitespace@25..31 "\n\n " 29 | WhileExpr@31..44 30 | Loop@31..35 "loop" 31 | Whitespace@35..36 " " 32 | Block@36..44 33 | LBrace@36..37 "{" 34 | Whitespace@37..43 "\n\n " 35 | RBrace@43..44 "}" 36 | Whitespace@44..45 "\n" 37 | RBrace@45..46 "}" 38 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/paren.test: -------------------------------------------------------------------------------- 1 | (true + 5 * 25 / 2 || ("woah dude what's this" & 2)^) 2 | === 3 | Root@0..53 4 | ExprStmt@0..53 5 | ParenExpr@0..53 6 | LParen@0..1 "(" 7 | BinaryExpr@1..52 8 | BinaryExpr@1..18 9 | BoolLiteral@1..5 10 | Bool@1..5 "true" 11 | Whitespace@5..6 " " 12 | Plus@6..7 "+" 13 | Whitespace@7..8 " " 14 | BinaryExpr@8..18 15 | BinaryExpr@8..14 16 | IntLiteral@8..9 17 | Int@8..9 "5" 18 | Whitespace@9..10 " " 19 | Asterisk@10..11 "*" 20 | Whitespace@11..12 " " 21 | IntLiteral@12..14 22 | Int@12..14 "25" 23 | Whitespace@14..15 " " 24 | Slash@15..16 "/" 25 | Whitespace@16..17 " " 26 | IntLiteral@17..18 27 | Int@17..18 "2" 28 | Whitespace@18..19 " " 29 | DoublePipe@19..21 "||" 30 | Whitespace@21..22 " " 31 | DerefExpr@22..52 32 | ParenExpr@22..51 33 | LParen@22..23 "(" 34 | BinaryExpr@23..50 35 | StringLiteral@23..46 36 | DoubleQuote@23..24 "\"" 37 | StringContents@24..45 "woah dude what's this" 38 | DoubleQuote@45..46 "\"" 39 | Whitespace@46..47 " " 40 | And@47..48 "&" 41 | Whitespace@48..49 " " 42 | IntLiteral@49..50 43 | Int@49..50 "2" 44 | RParen@50..51 ")" 45 | Caret@51..52 "^" 46 | RParen@52..53 ")" 47 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/paren_empty.test: -------------------------------------------------------------------------------- 1 | () 2 | === 3 | Root@0..2 4 | ExprStmt@0..2 5 | ParenExpr@0..2 6 | LParen@0..1 "(" 7 | RParen@1..2 ")" 8 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/paren_end_at_open_random.test: -------------------------------------------------------------------------------- 1 | (5 2 | === 3 | Root@0..2 4 | ExprStmt@0..2 5 | ParenExpr@0..2 6 | LParen@0..1 "(" 7 | IntLiteral@1..2 8 | Int@1..2 "5" 9 | error at 2: missing RParen 10 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/paren_end_at_open_semicolon.test: -------------------------------------------------------------------------------- 1 | (; 2 | === 3 | Root@0..2 4 | ExprStmt@0..2 5 | ParenExpr@0..1 6 | LParen@0..1 "(" 7 | Semicolon@1..2 ";" 8 | error at 1: missing expression 9 | error at 1: missing RParen 10 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/paren_ident.test: -------------------------------------------------------------------------------- 1 | (foo) 2 | === 3 | Root@0..5 4 | ExprStmt@0..5 5 | ParenExpr@0..5 6 | LParen@0..1 "(" 7 | VarRef@1..4 8 | Ident@1..4 "foo" 9 | RParen@4..5 ")" 10 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/quick_assign.test: -------------------------------------------------------------------------------- 1 | foo += 5; 2 | === 3 | Root@0..9 4 | Assign@0..9 5 | Source@0..3 6 | VarRef@0..3 7 | Ident@0..3 "foo" 8 | Whitespace@3..4 " " 9 | Plus@4..5 "+" 10 | Equals@5..6 "=" 11 | Whitespace@6..7 " " 12 | IntLiteral@7..8 13 | Int@7..8 "5" 14 | Semicolon@8..9 ";" 15 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/quick_assign_end_at_equals.test: -------------------------------------------------------------------------------- 1 | bar[5] *= 2 | === 3 | Root@0..9 4 | Assign@0..9 5 | Source@0..6 6 | IndexExpr@0..6 7 | Source@0..3 8 | VarRef@0..3 9 | Ident@0..3 "bar" 10 | LBrack@3..4 "[" 11 | Index@4..5 12 | IntLiteral@4..5 13 | Int@4..5 "5" 14 | RBrack@5..6 "]" 15 | Whitespace@6..7 " " 16 | Asterisk@7..8 "*" 17 | Equals@8..9 "=" 18 | error at 9: missing value 19 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/ref.test: -------------------------------------------------------------------------------- 1 | foo; 2 | === 3 | Root@0..4 4 | ExprStmt@0..4 5 | VarRef@0..3 6 | Ident@0..3 "foo" 7 | Semicolon@3..4 ";" 8 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/return.test: -------------------------------------------------------------------------------- 1 | () { 2 | return; 3 | return 5; 4 | } 5 | === 6 | Root@0..28 7 | ExprStmt@0..28 8 | Lambda@0..28 9 | ParamList@0..2 10 | LParen@0..1 "(" 11 | RParen@1..2 ")" 12 | Whitespace@2..3 " " 13 | Block@3..28 14 | LBrace@3..4 "{" 15 | Whitespace@4..7 "\n " 16 | ReturnStmt@7..14 17 | Return@7..13 "return" 18 | Semicolon@13..14 ";" 19 | Whitespace@14..17 "\n " 20 | ReturnStmt@17..26 21 | Return@17..23 "return" 22 | Whitespace@23..24 " " 23 | IntLiteral@24..25 24 | Int@24..25 "5" 25 | Semicolon@25..26 ";" 26 | Whitespace@26..27 "\n" 27 | RBrace@27..28 "}" 28 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/semicolons_after.test: -------------------------------------------------------------------------------- 1 | foo := bar;;;; 2 | === 3 | Root@0..14 4 | VarDef@0..11 5 | Ident@0..3 "foo" 6 | Whitespace@3..4 " " 7 | Colon@4..5 ":" 8 | Equals@5..6 "=" 9 | Whitespace@6..7 " " 10 | VarRef@7..10 11 | Ident@7..10 "bar" 12 | Semicolon@10..11 ";" 13 | Semicolon@11..12 ";" 14 | Semicolon@12..13 ";" 15 | Semicolon@13..14 ";" 16 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/semicolons_before.test: -------------------------------------------------------------------------------- 1 | ;;;foo := bar; 2 | === 3 | Root@0..14 4 | Semicolon@0..1 ";" 5 | Semicolon@1..2 ";" 6 | Semicolon@2..3 ";" 7 | VarDef@3..14 8 | Ident@3..6 "foo" 9 | Whitespace@6..7 " " 10 | Colon@7..8 ":" 11 | Equals@8..9 "=" 12 | Whitespace@9..10 " " 13 | VarRef@10..13 14 | Ident@10..13 "bar" 15 | Semicolon@13..14 ";" 16 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/semicolons_between.test: -------------------------------------------------------------------------------- 1 | ;;;;foo := bar;;;;bar := baz;;;; 2 | === 3 | Root@0..32 4 | Semicolon@0..1 ";" 5 | Semicolon@1..2 ";" 6 | Semicolon@2..3 ";" 7 | Semicolon@3..4 ";" 8 | VarDef@4..15 9 | Ident@4..7 "foo" 10 | Whitespace@7..8 " " 11 | Colon@8..9 ":" 12 | Equals@9..10 "=" 13 | Whitespace@10..11 " " 14 | VarRef@11..14 15 | Ident@11..14 "bar" 16 | Semicolon@14..15 ";" 17 | Semicolon@15..16 ";" 18 | Semicolon@16..17 ";" 19 | Semicolon@17..18 ";" 20 | VarDef@18..29 21 | Ident@18..21 "bar" 22 | Whitespace@21..22 " " 23 | Colon@22..23 ":" 24 | Equals@23..24 "=" 25 | Whitespace@24..25 " " 26 | VarRef@25..28 27 | Ident@25..28 "baz" 28 | Semicolon@28..29 ";" 29 | Semicolon@29..30 ";" 30 | Semicolon@30..31 ";" 31 | Semicolon@31..32 ";" 32 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/single_rbrace.test: -------------------------------------------------------------------------------- 1 | } 2 | === 3 | Root@0..1 4 | Error@0..1 5 | RBrace@0..1 "}" 6 | error at 1: missing statement 7 | error at 0..1: expected statement but found RBrace 8 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/string.test: -------------------------------------------------------------------------------- 1 | "Hello, World!"; 2 | === 3 | Root@0..16 4 | ExprStmt@0..16 5 | StringLiteral@0..15 6 | DoubleQuote@0..1 "\"" 7 | StringContents@1..14 "Hello, World!" 8 | DoubleQuote@14..15 "\"" 9 | Semicolon@15..16 ";" 10 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/string_no_close.test: -------------------------------------------------------------------------------- 1 | " 2 | === 3 | Root@0..1 4 | ExprStmt@0..1 5 | StringLiteral@0..1 6 | DoubleQuote@0..1 "\"" 7 | error at 1: missing DoubleQuote 8 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/string_with_quote_escape.test: -------------------------------------------------------------------------------- 1 | "\"Hello, World\""; 2 | === 3 | Root@0..19 4 | ExprStmt@0..19 5 | StringLiteral@0..18 6 | DoubleQuote@0..1 "\"" 7 | Escape@1..3 "\\\"" 8 | StringContents@3..15 "Hello, World" 9 | Escape@15..17 "\\\"" 10 | DoubleQuote@17..18 "\"" 11 | Semicolon@18..19 ";" 12 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/struct_empty.test: -------------------------------------------------------------------------------- 1 | struct {}; 2 | === 3 | Root@0..10 4 | ExprStmt@0..10 5 | StructDecl@0..9 6 | Struct@0..6 "struct" 7 | Whitespace@6..7 " " 8 | LBrace@7..8 "{" 9 | RBrace@8..9 "}" 10 | Semicolon@9..10 ";" 11 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/struct_end_at_open_eof.test: -------------------------------------------------------------------------------- 1 | struct{ 2 | === 3 | Root@0..7 4 | ExprStmt@0..7 5 | StructDecl@0..7 6 | Struct@0..6 "struct" 7 | LBrace@6..7 "{" 8 | MemberDecl@7..7 9 | error at 7: missing field name 10 | error at 7: missing Colon 11 | error at 7: missing field type 12 | error at 7: missing RBrace 13 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/struct_end_at_open_random.test: -------------------------------------------------------------------------------- 1 | struct{) 2 | === 3 | Root@0..8 4 | ExprStmt@0..8 5 | StructDecl@0..8 6 | Struct@0..6 "struct" 7 | LBrace@6..7 "{" 8 | MemberDecl@7..8 9 | Error@7..8 10 | RParen@7..8 ")" 11 | error at 7..8: expected field name but found RParen 12 | error at 8: missing Colon 13 | error at 8: missing field type 14 | error at 8: missing RBrace 15 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/struct_end_at_open_semicolon.test: -------------------------------------------------------------------------------- 1 | struct{; 2 | === 3 | Root@0..8 4 | ExprStmt@0..8 5 | StructDecl@0..7 6 | Struct@0..6 "struct" 7 | LBrace@6..7 "{" 8 | MemberDecl@7..7 9 | Semicolon@7..8 ";" 10 | error at 7: missing field name 11 | error at 7: missing Colon 12 | error at 7: missing field type 13 | error at 7: missing RBrace 14 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/struct_end_at_struct.test: -------------------------------------------------------------------------------- 1 | struct 2 | === 3 | Root@0..6 4 | ExprStmt@0..6 5 | StructDecl@0..6 6 | Struct@0..6 "struct" 7 | error at 6: missing struct body 8 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/struct_lit.test: -------------------------------------------------------------------------------- 1 | Foo.{ 2 | bar = "Fancy!", 3 | baz = 1200, 4 | qux = u8.(true), 5 | } 6 | === 7 | Root@0..64 8 | ExprStmt@0..64 9 | StructLiteral@0..64 10 | Ty@0..3 11 | VarRef@0..3 12 | Ident@0..3 "Foo" 13 | Dot@3..4 "." 14 | LBrace@4..5 "{" 15 | Whitespace@5..10 "\n " 16 | MemberLiteral@10..24 17 | Ident@10..13 "bar" 18 | Whitespace@13..14 " " 19 | Equals@14..15 "=" 20 | Whitespace@15..16 " " 21 | StringLiteral@16..24 22 | DoubleQuote@16..17 "\"" 23 | StringContents@17..23 "Fancy!" 24 | DoubleQuote@23..24 "\"" 25 | Comma@24..25 "," 26 | Whitespace@25..30 "\n " 27 | MemberLiteral@30..40 28 | Ident@30..33 "baz" 29 | Whitespace@33..34 " " 30 | Equals@34..35 "=" 31 | Whitespace@35..36 " " 32 | IntLiteral@36..40 33 | Int@36..40 "1200" 34 | Comma@40..41 "," 35 | Whitespace@41..46 "\n " 36 | MemberLiteral@46..61 37 | Ident@46..49 "qux" 38 | Whitespace@49..50 " " 39 | Equals@50..51 "=" 40 | Whitespace@51..52 " " 41 | CastExpr@52..61 42 | Ty@52..54 43 | VarRef@52..54 44 | Ident@52..54 "u8" 45 | Dot@54..55 "." 46 | LParen@55..56 "(" 47 | BoolLiteral@56..60 48 | Bool@56..60 "true" 49 | RParen@60..61 ")" 50 | Comma@61..62 "," 51 | Whitespace@62..63 "\n" 52 | RBrace@63..64 "}" 53 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/struct_lit_colons.test: -------------------------------------------------------------------------------- 1 | Foo.{ 2 | name: "Paul Atreides", 3 | spice_levels: 0.9, 4 | } 5 | === 6 | Root@0..57 7 | ExprStmt@0..57 8 | StructLiteral@0..57 9 | Ty@0..3 10 | VarRef@0..3 11 | Ident@0..3 "Foo" 12 | Dot@3..4 "." 13 | LBrace@4..5 "{" 14 | Whitespace@5..10 "\n " 15 | MemberLiteral@10..31 16 | Ident@10..14 "name" 17 | Error@14..15 18 | Colon@14..15 ":" 19 | Whitespace@15..16 " " 20 | StringLiteral@16..31 21 | DoubleQuote@16..17 "\"" 22 | StringContents@17..30 "Paul Atreides" 23 | DoubleQuote@30..31 "\"" 24 | Comma@31..32 "," 25 | Whitespace@32..37 "\n " 26 | MemberLiteral@37..54 27 | Ident@37..49 "spice_levels" 28 | Error@49..50 29 | Colon@49..50 ":" 30 | Whitespace@50..51 " " 31 | FloatLiteral@51..54 32 | Float@51..54 "0.9" 33 | Comma@54..55 "," 34 | Whitespace@55..56 "\n" 35 | RBrace@56..57 "}" 36 | error at 14..15: expected Equals but found Colon 37 | error at 49..50: expected Equals but found Colon 38 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/struct_lit_empty.test: -------------------------------------------------------------------------------- 1 | My_Struct.{}; 2 | === 3 | Root@0..13 4 | ExprStmt@0..13 5 | StructLiteral@0..12 6 | Ty@0..9 7 | VarRef@0..9 8 | Ident@0..9 "My_Struct" 9 | Dot@9..10 "." 10 | LBrace@10..11 "{" 11 | RBrace@11..12 "}" 12 | Semicolon@12..13 ";" 13 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/struct_lit_end_at_comma.test: -------------------------------------------------------------------------------- 1 | Foo.{ 2 | bar = "pls don't crash!", 3 | === 4 | Root@0..35 5 | ExprStmt@0..35 6 | StructLiteral@0..35 7 | Ty@0..3 8 | VarRef@0..3 9 | Ident@0..3 "Foo" 10 | Dot@3..4 "." 11 | LBrace@4..5 "{" 12 | Whitespace@5..10 "\n " 13 | MemberLiteral@10..34 14 | Ident@10..13 "bar" 15 | Whitespace@13..14 " " 16 | Equals@14..15 "=" 17 | Whitespace@15..16 " " 18 | StringLiteral@16..34 19 | DoubleQuote@16..17 "\"" 20 | StringContents@17..33 "pls don't crash!" 21 | DoubleQuote@33..34 "\"" 22 | Comma@34..35 "," 23 | MemberLiteral@35..35 24 | error at 35: missing field name 25 | error at 35: missing Equals 26 | error at 35: missing field value 27 | error at 35: missing RBrace 28 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/struct_lit_end_at_equal.test: -------------------------------------------------------------------------------- 1 | Foo.{ 2 | bar = 3 | === 4 | Root@0..15 5 | ExprStmt@0..15 6 | StructLiteral@0..15 7 | Ty@0..3 8 | VarRef@0..3 9 | Ident@0..3 "Foo" 10 | Dot@3..4 "." 11 | LBrace@4..5 "{" 12 | Whitespace@5..10 "\n " 13 | MemberLiteral@10..15 14 | Ident@10..13 "bar" 15 | Whitespace@13..14 " " 16 | Equals@14..15 "=" 17 | error at 15: missing field value 18 | error at 15: missing RBrace 19 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/struct_lit_one_field.test: -------------------------------------------------------------------------------- 1 | Person.{ 2 | name = "Joe Shmoe", 3 | }; 4 | === 5 | Root@0..35 6 | ExprStmt@0..35 7 | StructLiteral@0..34 8 | Ty@0..6 9 | VarRef@0..6 10 | Ident@0..6 "Person" 11 | Dot@6..7 "." 12 | LBrace@7..8 "{" 13 | Whitespace@8..13 "\n " 14 | MemberLiteral@13..31 15 | Ident@13..17 "name" 16 | Whitespace@17..18 " " 17 | Equals@18..19 "=" 18 | Whitespace@19..20 " " 19 | StringLiteral@20..31 20 | DoubleQuote@20..21 "\"" 21 | StringContents@21..30 "Joe Shmoe" 22 | DoubleQuote@30..31 "\"" 23 | Comma@31..32 "," 24 | Whitespace@32..33 "\n" 25 | RBrace@33..34 "}" 26 | Semicolon@34..35 ";" 27 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/struct_lit_open_eof.test: -------------------------------------------------------------------------------- 1 | Foo.{ 2 | === 3 | Root@0..5 4 | ExprStmt@0..5 5 | StructLiteral@0..5 6 | Ty@0..3 7 | VarRef@0..3 8 | Ident@0..3 "Foo" 9 | Dot@3..4 "." 10 | LBrace@4..5 "{" 11 | MemberLiteral@5..5 12 | error at 5: missing field name 13 | error at 5: missing Equals 14 | error at 5: missing field value 15 | error at 5: missing RBrace 16 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/struct_lit_open_random.test: -------------------------------------------------------------------------------- 1 | Foo.{) 2 | === 3 | Root@0..6 4 | ExprStmt@0..6 5 | StructLiteral@0..6 6 | Ty@0..3 7 | VarRef@0..3 8 | Ident@0..3 "Foo" 9 | Dot@3..4 "." 10 | LBrace@4..5 "{" 11 | MemberLiteral@5..6 12 | Error@5..6 13 | RParen@5..6 ")" 14 | error at 5: missing field name 15 | error at 5: missing Equals 16 | error at 5..6: expected field value but found RParen 17 | error at 6: missing RBrace 18 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/struct_lit_open_semicolon.test: -------------------------------------------------------------------------------- 1 | Foo.{; 2 | === 3 | Root@0..6 4 | ExprStmt@0..6 5 | StructLiteral@0..5 6 | Ty@0..3 7 | VarRef@0..3 8 | Ident@0..3 "Foo" 9 | Dot@3..4 "." 10 | LBrace@4..5 "{" 11 | MemberLiteral@5..5 12 | Semicolon@5..6 ";" 13 | error at 5: missing field name 14 | error at 5: missing Equals 15 | error at 5: missing field value 16 | error at 5: missing RBrace 17 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/struct_lit_untyped.test: -------------------------------------------------------------------------------- 1 | .{ a = 5, bar = "hello" } 2 | === 3 | Root@0..25 4 | ExprStmt@0..25 5 | StructLiteral@0..25 6 | Dot@0..1 "." 7 | LBrace@1..2 "{" 8 | Whitespace@2..3 " " 9 | MemberLiteral@3..8 10 | Ident@3..4 "a" 11 | Whitespace@4..5 " " 12 | Equals@5..6 "=" 13 | Whitespace@6..7 " " 14 | IntLiteral@7..8 15 | Int@7..8 "5" 16 | Comma@8..9 "," 17 | Whitespace@9..10 " " 18 | MemberLiteral@10..23 19 | Ident@10..13 "bar" 20 | Whitespace@13..14 " " 21 | Equals@14..15 "=" 22 | Whitespace@15..16 " " 23 | StringLiteral@16..23 24 | DoubleQuote@16..17 "\"" 25 | StringContents@17..22 "hello" 26 | DoubleQuote@22..23 "\"" 27 | Whitespace@23..24 " " 28 | RBrace@24..25 "}" 29 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/struct_multiple_fields.test: -------------------------------------------------------------------------------- 1 | struct { 2 | name: string, 3 | age: i32, 4 | }; 5 | === 6 | Root@0..43 7 | ExprStmt@0..43 8 | StructDecl@0..42 9 | Struct@0..6 "struct" 10 | Whitespace@6..7 " " 11 | LBrace@7..8 "{" 12 | Whitespace@8..13 "\n " 13 | MemberDecl@13..25 14 | Ident@13..17 "name" 15 | Colon@17..18 ":" 16 | Whitespace@18..19 " " 17 | Ty@19..25 18 | VarRef@19..25 19 | Ident@19..25 "string" 20 | Comma@25..26 "," 21 | Whitespace@26..31 "\n " 22 | MemberDecl@31..39 23 | Ident@31..34 "age" 24 | Colon@34..35 ":" 25 | Whitespace@35..36 " " 26 | Ty@36..39 27 | VarRef@36..39 28 | Ident@36..39 "i32" 29 | Comma@39..40 "," 30 | Whitespace@40..41 "\n" 31 | RBrace@41..42 "}" 32 | Semicolon@42..43 ";" 33 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/switch.test: -------------------------------------------------------------------------------- 1 | switch foo in some_enum {} 2 | === 3 | Root@0..26 4 | ExprStmt@0..26 5 | SwitchExpr@0..26 6 | Switch@0..6 "switch" 7 | Whitespace@6..7 " " 8 | Ident@7..10 "foo" 9 | Whitespace@10..11 " " 10 | In@11..13 "in" 11 | Whitespace@13..14 " " 12 | VarRef@14..23 13 | Ident@14..23 "some_enum" 14 | Whitespace@23..24 " " 15 | LBrace@24..25 "{" 16 | RBrace@25..26 "}" 17 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/switch_arm_open_eof.test: -------------------------------------------------------------------------------- 1 | switch foo in get_enum() { 2 | Apples => { 3 | === 4 | Root@0..42 5 | ExprStmt@0..42 6 | SwitchExpr@0..42 7 | Switch@0..6 "switch" 8 | Whitespace@6..7 " " 9 | Ident@7..10 "foo" 10 | Whitespace@10..11 " " 11 | In@11..13 "in" 12 | Whitespace@13..14 " " 13 | Call@14..24 14 | VarRef@14..22 15 | Ident@14..22 "get_enum" 16 | ArgList@22..24 17 | LParen@22..23 "(" 18 | RParen@23..24 ")" 19 | Whitespace@24..25 " " 20 | LBrace@25..26 "{" 21 | Whitespace@26..31 "\n " 22 | SwitchArm@31..42 23 | Ident@31..37 "Apples" 24 | Whitespace@37..38 " " 25 | FatArrow@38..40 "=>" 26 | Whitespace@40..41 " " 27 | Block@41..42 28 | LBrace@41..42 "{" 29 | error at 42: missing RBrace 30 | error at 42: missing RBrace 31 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/switch_arms_block_commas.test: -------------------------------------------------------------------------------- 1 | switch foo in animal_enum { 2 | Dog => {}, 3 | Cat => {}, 4 | Turtle => {}, 5 | } 6 | === 7 | Root@0..77 8 | ExprStmt@0..77 9 | SwitchExpr@0..77 10 | Switch@0..6 "switch" 11 | Whitespace@6..7 " " 12 | Ident@7..10 "foo" 13 | Whitespace@10..11 " " 14 | In@11..13 "in" 15 | Whitespace@13..14 " " 16 | VarRef@14..25 17 | Ident@14..25 "animal_enum" 18 | Whitespace@25..26 " " 19 | LBrace@26..27 "{" 20 | Whitespace@27..32 "\n " 21 | SwitchArm@32..41 22 | Ident@32..35 "Dog" 23 | Whitespace@35..36 " " 24 | FatArrow@36..38 "=>" 25 | Whitespace@38..39 " " 26 | Block@39..41 27 | LBrace@39..40 "{" 28 | RBrace@40..41 "}" 29 | Comma@41..42 "," 30 | Whitespace@42..47 "\n " 31 | SwitchArm@47..56 32 | Ident@47..50 "Cat" 33 | Whitespace@50..51 " " 34 | FatArrow@51..53 "=>" 35 | Whitespace@53..54 " " 36 | Block@54..56 37 | LBrace@54..55 "{" 38 | RBrace@55..56 "}" 39 | Comma@56..57 "," 40 | Whitespace@57..62 "\n " 41 | SwitchArm@62..74 42 | Ident@62..68 "Turtle" 43 | Whitespace@68..69 " " 44 | FatArrow@69..71 "=>" 45 | Whitespace@71..72 " " 46 | Block@72..74 47 | LBrace@72..73 "{" 48 | RBrace@73..74 "}" 49 | Comma@74..75 "," 50 | Whitespace@75..76 "\n" 51 | RBrace@76..77 "}" 52 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/switch_arms_block_no_comma.test: -------------------------------------------------------------------------------- 1 | switch foo in animal_enum { 2 | Dog => {} 3 | Cat => {} 4 | Turtle => {} 5 | } 6 | === 7 | Root@0..74 8 | ExprStmt@0..74 9 | SwitchExpr@0..74 10 | Switch@0..6 "switch" 11 | Whitespace@6..7 " " 12 | Ident@7..10 "foo" 13 | Whitespace@10..11 " " 14 | In@11..13 "in" 15 | Whitespace@13..14 " " 16 | VarRef@14..25 17 | Ident@14..25 "animal_enum" 18 | Whitespace@25..26 " " 19 | LBrace@26..27 "{" 20 | Whitespace@27..32 "\n " 21 | SwitchArm@32..41 22 | Ident@32..35 "Dog" 23 | Whitespace@35..36 " " 24 | FatArrow@36..38 "=>" 25 | Whitespace@38..39 " " 26 | Block@39..41 27 | LBrace@39..40 "{" 28 | RBrace@40..41 "}" 29 | Whitespace@41..46 "\n " 30 | SwitchArm@46..55 31 | Ident@46..49 "Cat" 32 | Whitespace@49..50 " " 33 | FatArrow@50..52 "=>" 34 | Whitespace@52..53 " " 35 | Block@53..55 36 | LBrace@53..54 "{" 37 | RBrace@54..55 "}" 38 | Whitespace@55..60 "\n " 39 | SwitchArm@60..72 40 | Ident@60..66 "Turtle" 41 | Whitespace@66..67 " " 42 | FatArrow@67..69 "=>" 43 | Whitespace@69..70 " " 44 | Block@70..72 45 | LBrace@70..71 "{" 46 | RBrace@71..72 "}" 47 | Whitespace@72..73 "\n" 48 | RBrace@73..74 "}" 49 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/switch_arms_expr_comma.test: -------------------------------------------------------------------------------- 1 | switch foo in animal_enum { 2 | Dog => foo, 3 | Cat => "hello", 4 | Turtle => 2 * 10, 5 | } 6 | === 7 | Root@0..87 8 | ExprStmt@0..87 9 | SwitchExpr@0..87 10 | Switch@0..6 "switch" 11 | Whitespace@6..7 " " 12 | Ident@7..10 "foo" 13 | Whitespace@10..11 " " 14 | In@11..13 "in" 15 | Whitespace@13..14 " " 16 | VarRef@14..25 17 | Ident@14..25 "animal_enum" 18 | Whitespace@25..26 " " 19 | LBrace@26..27 "{" 20 | Whitespace@27..32 "\n " 21 | SwitchArm@32..42 22 | Ident@32..35 "Dog" 23 | Whitespace@35..36 " " 24 | FatArrow@36..38 "=>" 25 | Whitespace@38..39 " " 26 | VarRef@39..42 27 | Ident@39..42 "foo" 28 | Comma@42..43 "," 29 | Whitespace@43..48 "\n " 30 | SwitchArm@48..62 31 | Ident@48..51 "Cat" 32 | Whitespace@51..52 " " 33 | FatArrow@52..54 "=>" 34 | Whitespace@54..55 " " 35 | StringLiteral@55..62 36 | DoubleQuote@55..56 "\"" 37 | StringContents@56..61 "hello" 38 | DoubleQuote@61..62 "\"" 39 | Comma@62..63 "," 40 | Whitespace@63..68 "\n " 41 | SwitchArm@68..84 42 | Ident@68..74 "Turtle" 43 | Whitespace@74..75 " " 44 | FatArrow@75..77 "=>" 45 | Whitespace@77..78 " " 46 | BinaryExpr@78..84 47 | IntLiteral@78..79 48 | Int@78..79 "2" 49 | Whitespace@79..80 " " 50 | Asterisk@80..81 "*" 51 | Whitespace@81..82 " " 52 | IntLiteral@82..84 53 | Int@82..84 "10" 54 | Comma@84..85 "," 55 | Whitespace@85..86 "\n" 56 | RBrace@86..87 "}" 57 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/switch_arms_expr_no_comma.test: -------------------------------------------------------------------------------- 1 | switch foo in animal_enum { 2 | Dog => foo 3 | Cat => "hello" 4 | Turtle => 2 * 10 5 | } 6 | === 7 | Root@0..84 8 | ExprStmt@0..84 9 | SwitchExpr@0..84 10 | Switch@0..6 "switch" 11 | Whitespace@6..7 " " 12 | Ident@7..10 "foo" 13 | Whitespace@10..11 " " 14 | In@11..13 "in" 15 | Whitespace@13..14 " " 16 | VarRef@14..25 17 | Ident@14..25 "animal_enum" 18 | Whitespace@25..26 " " 19 | LBrace@26..27 "{" 20 | Whitespace@27..32 "\n " 21 | SwitchArm@32..42 22 | Ident@32..35 "Dog" 23 | Whitespace@35..36 " " 24 | FatArrow@36..38 "=>" 25 | Whitespace@38..39 " " 26 | VarRef@39..42 27 | Ident@39..42 "foo" 28 | Whitespace@42..47 "\n " 29 | SwitchArm@47..61 30 | Ident@47..50 "Cat" 31 | Whitespace@50..51 " " 32 | FatArrow@51..53 "=>" 33 | Whitespace@53..54 " " 34 | StringLiteral@54..61 35 | DoubleQuote@54..55 "\"" 36 | StringContents@55..60 "hello" 37 | DoubleQuote@60..61 "\"" 38 | Whitespace@61..66 "\n " 39 | SwitchArm@66..82 40 | Ident@66..72 "Turtle" 41 | Whitespace@72..73 " " 42 | FatArrow@73..75 "=>" 43 | Whitespace@75..76 " " 44 | BinaryExpr@76..82 45 | IntLiteral@76..77 46 | Int@76..77 "2" 47 | Whitespace@77..78 " " 48 | Asterisk@78..79 "*" 49 | Whitespace@79..80 " " 50 | IntLiteral@80..82 51 | Int@80..82 "10" 52 | Whitespace@82..83 "\n" 53 | RBrace@83..84 "}" 54 | error at 42: missing Comma 55 | error at 61: missing Comma 56 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/switch_end_at_enum_value.test: -------------------------------------------------------------------------------- 1 | switch foo in bar 2 | === 3 | Root@0..17 4 | ExprStmt@0..17 5 | SwitchExpr@0..17 6 | Switch@0..6 "switch" 7 | Whitespace@6..7 " " 8 | Ident@7..10 "foo" 9 | Whitespace@10..11 " " 10 | In@11..13 "in" 11 | Whitespace@13..14 " " 12 | VarRef@14..17 13 | Ident@14..17 "bar" 14 | error at 17: missing switch body 15 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/switch_end_at_fat_arrow.test: -------------------------------------------------------------------------------- 1 | switch foo in bar.baz { 2 | Cake => 3 | === 4 | Root@0..35 5 | ExprStmt@0..35 6 | SwitchExpr@0..35 7 | Switch@0..6 "switch" 8 | Whitespace@6..7 " " 9 | Ident@7..10 "foo" 10 | Whitespace@10..11 " " 11 | In@11..13 "in" 12 | Whitespace@13..14 " " 13 | Path@14..21 14 | VarRef@14..17 15 | Ident@14..17 "bar" 16 | Dot@17..18 "." 17 | Ident@18..21 "baz" 18 | Whitespace@21..22 " " 19 | LBrace@22..23 "{" 20 | Whitespace@23..28 "\n " 21 | SwitchArm@28..35 22 | Ident@28..32 "Cake" 23 | Whitespace@32..33 " " 24 | FatArrow@33..35 "=>" 25 | error at 35: missing switch arm 26 | error at 35: missing RBrace 27 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/switch_end_at_in.test: -------------------------------------------------------------------------------- 1 | switch foo in 2 | === 3 | Root@0..13 4 | ExprStmt@0..13 5 | SwitchExpr@0..13 6 | Switch@0..6 "switch" 7 | Whitespace@6..7 " " 8 | Ident@7..10 "foo" 9 | Whitespace@10..11 " " 10 | In@11..13 "in" 11 | error at 13: missing enum value 12 | error at 13: missing switch body 13 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/switch_end_at_param.test: -------------------------------------------------------------------------------- 1 | switch foo 2 | === 3 | Root@0..10 4 | ExprStmt@0..10 5 | SwitchExpr@0..10 6 | Switch@0..6 "switch" 7 | Whitespace@6..7 " " 8 | Ident@7..10 "foo" 9 | error at 10: missing In 10 | error at 10: missing enum value 11 | error at 10: missing switch body 12 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/switch_end_at_switch.test: -------------------------------------------------------------------------------- 1 | switch 2 | === 3 | Root@0..6 4 | ExprStmt@0..6 5 | SwitchExpr@0..6 6 | Switch@0..6 "switch" 7 | error at 6: missing enum value 8 | error at 6: missing switch body 9 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/switch_end_at_variant_name.test: -------------------------------------------------------------------------------- 1 | switch foo in bar { 2 | Cat 3 | === 4 | Root@0..27 5 | ExprStmt@0..27 6 | SwitchExpr@0..27 7 | Switch@0..6 "switch" 8 | Whitespace@6..7 " " 9 | Ident@7..10 "foo" 10 | Whitespace@10..11 " " 11 | In@11..13 "in" 12 | Whitespace@13..14 " " 13 | VarRef@14..17 14 | Ident@14..17 "bar" 15 | Whitespace@17..18 " " 16 | LBrace@18..19 "{" 17 | Whitespace@19..24 "\n " 18 | SwitchArm@24..27 19 | Ident@24..27 "Cat" 20 | error at 27: missing FatArrow 21 | error at 27: missing switch arm 22 | error at 27: missing RBrace 23 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/switch_open_eof.test: -------------------------------------------------------------------------------- 1 | switch foo in bar { 2 | === 3 | Root@0..19 4 | ExprStmt@0..19 5 | SwitchExpr@0..19 6 | Switch@0..6 "switch" 7 | Whitespace@6..7 " " 8 | Ident@7..10 "foo" 9 | Whitespace@10..11 " " 10 | In@11..13 "in" 11 | Whitespace@13..14 " " 12 | VarRef@14..17 13 | Ident@14..17 "bar" 14 | Whitespace@17..18 " " 15 | LBrace@18..19 "{" 16 | SwitchArm@19..19 17 | error at 19: missing enum variant name 18 | error at 19: missing FatArrow 19 | error at 19: missing switch arm 20 | error at 19: missing RBrace 21 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/switch_semicolon.test: -------------------------------------------------------------------------------- 1 | { 2 | switch foo {}; 3 | 5 4 | } 5 | === 6 | Root@0..28 7 | ExprStmt@0..28 8 | Block@0..28 9 | LBrace@0..1 "{" 10 | Whitespace@1..6 "\n " 11 | ExprStmt@6..19 12 | SwitchExpr@6..19 13 | Switch@6..12 "switch" 14 | Whitespace@12..13 " " 15 | VarRef@13..16 16 | Ident@13..16 "foo" 17 | Whitespace@16..17 " " 18 | LBrace@17..18 "{" 19 | RBrace@18..19 "}" 20 | Semicolon@19..20 ";" 21 | Whitespace@20..25 "\n " 22 | IntLiteral@25..26 23 | Int@25..26 "5" 24 | Whitespace@26..27 "\n" 25 | RBrace@27..28 "}" 26 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/switch_semicolon_missing.test: -------------------------------------------------------------------------------- 1 | { 2 | switch foo {} 3 | 5 4 | } 5 | === 6 | Root@0..27 7 | ExprStmt@0..27 8 | Block@0..27 9 | LBrace@0..1 "{" 10 | Whitespace@1..6 "\n " 11 | ExprStmt@6..19 12 | SwitchExpr@6..19 13 | Switch@6..12 "switch" 14 | Whitespace@12..13 " " 15 | VarRef@13..16 16 | Ident@13..16 "foo" 17 | Whitespace@16..17 " " 18 | LBrace@17..18 "{" 19 | RBrace@18..19 "}" 20 | Whitespace@19..24 "\n " 21 | IntLiteral@24..25 22 | Int@24..25 "5" 23 | Whitespace@25..26 "\n" 24 | RBrace@26..27 "}" 25 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/switch_swap_param_and_value.test: -------------------------------------------------------------------------------- 1 | switch foo.get_enum() in bar {} 2 | // todo: maybe change this behavior 3 | === 4 | Root@0..67 5 | ExprStmt@0..24 6 | SwitchExpr@0..24 7 | Switch@0..6 "switch" 8 | Whitespace@6..7 " " 9 | Call@7..21 10 | Path@7..19 11 | VarRef@7..10 12 | Ident@7..10 "foo" 13 | Dot@10..11 "." 14 | Ident@11..19 "get_enum" 15 | ArgList@19..21 16 | LParen@19..20 "(" 17 | RParen@20..21 ")" 18 | Whitespace@21..22 " " 19 | Error@22..24 20 | In@22..24 "in" 21 | Whitespace@24..25 " " 22 | ExprStmt@25..31 23 | StructLiteral@25..31 24 | Ty@25..28 25 | VarRef@25..28 26 | Ident@25..28 "bar" 27 | Whitespace@28..29 " " 28 | LBrace@29..30 "{" 29 | RBrace@30..31 "}" 30 | Whitespace@31..32 "\n" 31 | Comment@32..67 32 | CommentLeader@32..34 "//" 33 | CommentContents@34..67 " todo: maybe change this behavior" 34 | error at 22..24: expected switch body but found In 35 | error at 28: missing Dot 36 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/switch_without_param.test: -------------------------------------------------------------------------------- 1 | switch foo {} 2 | === 3 | Root@0..13 4 | ExprStmt@0..13 5 | SwitchExpr@0..13 6 | Switch@0..6 "switch" 7 | Whitespace@6..7 " " 8 | VarRef@7..10 9 | Ident@7..10 "foo" 10 | Whitespace@10..11 " " 11 | LBrace@11..12 "{" 12 | RBrace@12..13 "}" 13 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/switch_without_param_fancy.test: -------------------------------------------------------------------------------- 1 | switch foo.calculate_enum() {} 2 | === 3 | Root@0..30 4 | ExprStmt@0..30 5 | SwitchExpr@0..30 6 | Switch@0..6 "switch" 7 | Whitespace@6..7 " " 8 | Call@7..27 9 | Path@7..25 10 | VarRef@7..10 11 | Ident@7..10 "foo" 12 | Dot@10..11 "." 13 | Ident@11..25 "calculate_enum" 14 | ArgList@25..27 15 | LParen@25..26 "(" 16 | RParen@26..27 ")" 17 | Whitespace@27..28 " " 18 | LBrace@28..29 "{" 19 | RBrace@29..30 "}" 20 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/unary_expr_bang.test: -------------------------------------------------------------------------------- 1 | !true; 2 | === 3 | Root@0..6 4 | ExprStmt@0..6 5 | UnaryExpr@0..5 6 | Bang@0..1 "!" 7 | BoolLiteral@1..5 8 | Bool@1..5 "true" 9 | Semicolon@5..6 ";" 10 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/unary_expr_negative.test: -------------------------------------------------------------------------------- 1 | -10; 2 | === 3 | Root@0..4 4 | ExprStmt@0..4 5 | UnaryExpr@0..3 6 | Hyphen@0..1 "-" 7 | IntLiteral@1..3 8 | Int@1..3 "10" 9 | Semicolon@3..4 ";" 10 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/unary_expr_positive.test: -------------------------------------------------------------------------------- 1 | +20; 2 | === 3 | Root@0..4 4 | ExprStmt@0..4 5 | UnaryExpr@0..3 6 | Plus@0..1 "+" 7 | IntLiteral@1..3 8 | Int@1..3 "20" 9 | Semicolon@3..4 ";" 10 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/unary_expr_with_cast: -------------------------------------------------------------------------------- 1 | -42 as u32 2 | === 3 | 4 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/var_def_decl_no_type.test: -------------------------------------------------------------------------------- 1 | bar :; 2 | === 3 | Root@0..6 4 | VarDef@0..6 5 | Ident@0..3 "bar" 6 | Whitespace@3..4 " " 7 | Colon@4..5 ":" 8 | Semicolon@5..6 ";" 9 | error at 5: missing type annotation 10 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/var_def_default_value.test: -------------------------------------------------------------------------------- 1 | my_var: foo; 2 | === 3 | Root@0..12 4 | VarDef@0..12 5 | Ident@0..6 "my_var" 6 | Colon@6..7 ":" 7 | Whitespace@7..8 " " 8 | Ty@8..11 9 | VarRef@8..11 10 | Ident@8..11 "foo" 11 | Semicolon@11..12 ";" 12 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/var_def_end_at_colon.test: -------------------------------------------------------------------------------- 1 | x: 2 | === 3 | Root@0..2 4 | VarDef@0..2 5 | Ident@0..1 "x" 6 | Colon@1..2 ":" 7 | error at 2: missing type annotation 8 | error at 2: missing Semicolon 9 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/var_def_end_at_type.test: -------------------------------------------------------------------------------- 1 | x: some_type 2 | === 3 | Root@0..12 4 | VarDef@0..12 5 | Ident@0..1 "x" 6 | Colon@1..2 ":" 7 | Whitespace@2..3 " " 8 | Ty@3..12 9 | VarRef@3..12 10 | Ident@3..12 "some_type" 11 | error at 12: missing Semicolon 12 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/var_def_missing_value.test: -------------------------------------------------------------------------------- 1 | a :=; 2 | b := a; 3 | === 4 | Root@0..13 5 | VarDef@0..5 6 | Ident@0..1 "a" 7 | Whitespace@1..2 " " 8 | Colon@2..3 ":" 9 | Equals@3..4 "=" 10 | Semicolon@4..5 ";" 11 | Whitespace@5..6 "\n" 12 | VarDef@6..13 13 | Ident@6..7 "b" 14 | Whitespace@7..8 " " 15 | Colon@8..9 ":" 16 | Equals@9..10 "=" 17 | Whitespace@10..11 " " 18 | VarRef@11..12 19 | Ident@11..12 "a" 20 | Semicolon@12..13 ";" 21 | error at 4: missing value 22 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/var_def_no_colon_equals.test: -------------------------------------------------------------------------------- 1 | bar 5 2 | === 3 | Root@0..5 4 | ExprStmt@0..3 5 | VarRef@0..3 6 | Ident@0..3 "bar" 7 | Whitespace@3..4 " " 8 | ExprStmt@4..5 9 | IntLiteral@4..5 10 | Int@4..5 "5" 11 | error at 3: missing Semicolon 12 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/var_def_no_equals.test: -------------------------------------------------------------------------------- 1 | bar : 5 2 | === 3 | Root@0..7 4 | VarDef@0..7 5 | Ident@0..3 "bar" 6 | Whitespace@3..4 " " 7 | Colon@4..5 ":" 8 | Whitespace@5..6 " " 9 | Ty@6..7 10 | IntLiteral@6..7 11 | Int@6..7 "5" 12 | error at 7: missing Semicolon 13 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/var_def_with_member_type.test: -------------------------------------------------------------------------------- 1 | foo: bar.baz = qux; 2 | === 3 | Root@0..19 4 | VarDef@0..19 5 | Ident@0..3 "foo" 6 | Colon@3..4 ":" 7 | Whitespace@4..5 " " 8 | Ty@5..12 9 | Path@5..12 10 | VarRef@5..8 11 | Ident@5..8 "bar" 12 | Dot@8..9 "." 13 | Ident@9..12 "baz" 14 | Whitespace@12..13 " " 15 | Equals@13..14 "=" 16 | Whitespace@14..15 " " 17 | VarRef@15..18 18 | Ident@15..18 "qux" 19 | Semicolon@18..19 ";" 20 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/var_def_with_type.test: -------------------------------------------------------------------------------- 1 | foo: bar = baz; 2 | === 3 | Root@0..15 4 | VarDef@0..15 5 | Ident@0..3 "foo" 6 | Colon@3..4 ":" 7 | Whitespace@4..5 " " 8 | Ty@5..8 9 | VarRef@5..8 10 | Ident@5..8 "bar" 11 | Whitespace@8..9 " " 12 | Equals@9..10 "=" 13 | Whitespace@10..11 " " 14 | VarRef@11..14 15 | Ident@11..14 "baz" 16 | Semicolon@14..15 ";" 17 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/while.test: -------------------------------------------------------------------------------- 1 | while true { } 2 | === 3 | Root@0..14 4 | ExprStmt@0..14 5 | WhileExpr@0..14 6 | While@0..5 "while" 7 | Whitespace@5..6 " " 8 | Condition@6..10 9 | BoolLiteral@6..10 10 | Bool@6..10 "true" 11 | Whitespace@10..11 " " 12 | Block@11..14 13 | LBrace@11..12 "{" 14 | Whitespace@12..13 " " 15 | RBrace@13..14 "}" 16 | -------------------------------------------------------------------------------- /crates/parser/src/tests/repl_line/whitespace.test: -------------------------------------------------------------------------------- 1 | 2 | === 3 | Root@0..3 4 | Whitespace@0..3 " " 5 | -------------------------------------------------------------------------------- /crates/parser/src/tests/source_file/extern_binding.test: -------------------------------------------------------------------------------- 1 | foo : i32 : extern; 2 | bar :: extern; 3 | === 4 | Root@0..34 5 | Binding@0..19 6 | Ident@0..3 "foo" 7 | Whitespace@3..4 " " 8 | Colon@4..5 ":" 9 | Whitespace@5..6 " " 10 | Ty@6..9 11 | VarRef@6..9 12 | Ident@6..9 "i32" 13 | Whitespace@9..10 " " 14 | Colon@10..11 ":" 15 | Whitespace@11..12 " " 16 | Extern@12..18 "extern" 17 | Semicolon@18..19 ";" 18 | Whitespace@19..20 "\n" 19 | Binding@20..34 20 | Ident@20..23 "bar" 21 | Whitespace@23..24 " " 22 | Colon@24..25 ":" 23 | Colon@25..26 ":" 24 | Whitespace@26..27 " " 25 | Extern@27..33 "extern" 26 | Semicolon@33..34 ";" 27 | -------------------------------------------------------------------------------- /crates/parser/src/tests/source_file/import.test: -------------------------------------------------------------------------------- 1 | foo :: #import("foo.capy"); 2 | bar :: 32; 3 | === 4 | Root@0..38 5 | Binding@0..27 6 | Ident@0..3 "foo" 7 | Whitespace@3..4 " " 8 | Colon@4..5 ":" 9 | Colon@5..6 ":" 10 | Whitespace@6..7 " " 11 | Directive@7..26 12 | Hash@7..8 "#" 13 | Ident@8..14 "import" 14 | ArgList@14..26 15 | LParen@14..15 "(" 16 | Arg@15..25 17 | StringLiteral@15..25 18 | DoubleQuote@15..16 "\"" 19 | StringContents@16..24 "foo.capy" 20 | DoubleQuote@24..25 "\"" 21 | RParen@25..26 ")" 22 | Semicolon@26..27 ";" 23 | Whitespace@27..28 "\n" 24 | Binding@28..38 25 | Ident@28..31 "bar" 26 | Whitespace@31..32 " " 27 | Colon@32..33 ":" 28 | Colon@33..34 ":" 29 | Whitespace@34..35 " " 30 | IntLiteral@35..37 31 | Int@35..37 "32" 32 | Semicolon@37..38 ";" 33 | -------------------------------------------------------------------------------- /crates/parser/src/tests/source_file/import_missing_file.test: -------------------------------------------------------------------------------- 1 | foo :: #import(); 2 | bar :: 32; 3 | === 4 | Root@0..28 5 | Binding@0..17 6 | Ident@0..3 "foo" 7 | Whitespace@3..4 " " 8 | Colon@4..5 ":" 9 | Colon@5..6 ":" 10 | Whitespace@6..7 " " 11 | Directive@7..16 12 | Hash@7..8 "#" 13 | Ident@8..14 "import" 14 | ArgList@14..16 15 | LParen@14..15 "(" 16 | RParen@15..16 ")" 17 | Semicolon@16..17 ";" 18 | Whitespace@17..18 "\n" 19 | Binding@18..28 20 | Ident@18..21 "bar" 21 | Whitespace@21..22 " " 22 | Colon@22..23 ":" 23 | Colon@23..24 ":" 24 | Whitespace@24..25 " " 25 | IntLiteral@25..27 26 | Int@25..27 "32" 27 | Semicolon@27..28 ";" 28 | -------------------------------------------------------------------------------- /crates/parser/src/tests/source_file/import_missing_file_and_semicolon.test: -------------------------------------------------------------------------------- 1 | foo :: #import 2 | bar :: 32; 3 | baz :: 51; 4 | // todo: maybe parse this differently 5 | === 6 | Root@0..74 7 | Binding@0..25 8 | Ident@0..3 "foo" 9 | Whitespace@3..4 " " 10 | Colon@4..5 ":" 11 | Colon@5..6 ":" 12 | Whitespace@6..7 " " 13 | Directive@7..24 14 | Hash@7..8 "#" 15 | Ident@8..14 "import" 16 | Whitespace@14..15 "\n" 17 | ArgList@15..24 18 | Arg@15..18 19 | VarRef@15..18 20 | Ident@15..18 "bar" 21 | Whitespace@18..19 " " 22 | Arg@19..20 23 | Error@19..20 24 | Colon@19..20 ":" 25 | Arg@20..21 26 | Error@20..21 27 | Colon@20..21 ":" 28 | Whitespace@21..22 " " 29 | Arg@22..24 30 | IntLiteral@22..24 31 | Int@22..24 "32" 32 | Semicolon@24..25 ";" 33 | Whitespace@25..26 "\n" 34 | Binding@26..36 35 | Ident@26..29 "baz" 36 | Whitespace@29..30 " " 37 | Colon@30..31 ":" 38 | Colon@31..32 ":" 39 | Whitespace@32..33 " " 40 | IntLiteral@33..35 41 | Int@33..35 "51" 42 | Semicolon@35..36 ";" 43 | Whitespace@36..37 "\n" 44 | Comment@37..74 45 | CommentLeader@37..39 "//" 46 | CommentContents@39..74 " todo: maybe parse this differently" 47 | error at 14: missing LParen 48 | error at 18: missing Comma 49 | error at 19..20: expected argument but found Colon 50 | error at 20: missing Comma 51 | error at 20..21: expected argument but found Colon 52 | error at 21: missing Comma 53 | error at 24: missing RParen 54 | -------------------------------------------------------------------------------- /crates/parser/src/tests/source_file/missing_return_ty_block.test: -------------------------------------------------------------------------------- 1 | foo :: () -> { 2 | 3 | }; 4 | === 5 | Root@0..18 6 | Binding@0..17 7 | Ident@0..3 "foo" 8 | Whitespace@3..4 " " 9 | Colon@4..5 ":" 10 | Colon@5..6 ":" 11 | Whitespace@6..7 " " 12 | Lambda@7..17 13 | ParamList@7..9 14 | LParen@7..8 "(" 15 | RParen@8..9 ")" 16 | Whitespace@9..10 " " 17 | Arrow@10..12 "->" 18 | Whitespace@12..13 " " 19 | Block@13..17 20 | LBrace@13..14 "{" 21 | Whitespace@14..16 "\n\n" 22 | RBrace@16..17 "}" 23 | Semicolon@17..18 ";" 24 | error at 12: missing return type 25 | -------------------------------------------------------------------------------- /crates/parser/src/tests/source_file/missing_return_ty_extern.test: -------------------------------------------------------------------------------- 1 | foo :: () -> extern; 2 | === 3 | Root@0..20 4 | Binding@0..20 5 | Ident@0..3 "foo" 6 | Whitespace@3..4 " " 7 | Colon@4..5 ":" 8 | Colon@5..6 ":" 9 | Whitespace@6..7 " " 10 | Lambda@7..19 11 | ParamList@7..9 12 | LParen@7..8 "(" 13 | RParen@8..9 ")" 14 | Whitespace@9..10 " " 15 | Arrow@10..12 "->" 16 | Whitespace@12..13 " " 17 | Extern@13..19 "extern" 18 | Semicolon@19..20 ";" 19 | error at 12: missing return type 20 | -------------------------------------------------------------------------------- /crates/parser/src/tests/source_file/missing_value.test: -------------------------------------------------------------------------------- 1 | main :: () { 2 | x := 3 | } 4 | 5 | foo :: () { 6 | 2 + 2 7 | } 8 | === 9 | Root@0..48 10 | Binding@0..23 11 | Ident@0..4 "main" 12 | Whitespace@4..5 " " 13 | Colon@5..6 ":" 14 | Colon@6..7 ":" 15 | Whitespace@7..8 " " 16 | Lambda@8..23 17 | ParamList@8..10 18 | LParen@8..9 "(" 19 | RParen@9..10 ")" 20 | Whitespace@10..11 " " 21 | Block@11..23 22 | LBrace@11..12 "{" 23 | Whitespace@12..17 "\n " 24 | VarDef@17..21 25 | Ident@17..18 "x" 26 | Whitespace@18..19 " " 27 | Colon@19..20 ":" 28 | Equals@20..21 "=" 29 | Whitespace@21..22 "\n" 30 | RBrace@22..23 "}" 31 | Whitespace@23..25 "\n\n" 32 | Binding@25..48 33 | Ident@25..28 "foo" 34 | Whitespace@28..29 " " 35 | Colon@29..30 ":" 36 | Colon@30..31 ":" 37 | Whitespace@31..32 " " 38 | Lambda@32..48 39 | ParamList@32..34 40 | LParen@32..33 "(" 41 | RParen@33..34 ")" 42 | Whitespace@34..35 " " 43 | Block@35..48 44 | LBrace@35..36 "{" 45 | Whitespace@36..41 "\n " 46 | BinaryExpr@41..46 47 | IntLiteral@41..42 48 | Int@41..42 "2" 49 | Whitespace@42..43 " " 50 | Plus@43..44 "+" 51 | Whitespace@44..45 " " 52 | IntLiteral@45..46 53 | Int@45..46 "2" 54 | Whitespace@46..47 "\n" 55 | RBrace@47..48 "}" 56 | error at 21: missing value 57 | error at 21: missing Semicolon 58 | -------------------------------------------------------------------------------- /crates/parser/src/tests/source_file/no_semicolon_extern.test: -------------------------------------------------------------------------------- 1 | foo :: () extern 2 | === 3 | Root@0..16 4 | Binding@0..16 5 | Ident@0..3 "foo" 6 | Whitespace@3..4 " " 7 | Colon@4..5 ":" 8 | Colon@5..6 ":" 9 | Whitespace@6..7 " " 10 | Lambda@7..16 11 | ParamList@7..9 12 | LParen@7..8 "(" 13 | RParen@8..9 ")" 14 | Whitespace@9..10 " " 15 | Extern@10..16 "extern" 16 | error at 16: missing Semicolon 17 | -------------------------------------------------------------------------------- /crates/parser/src/tests/source_file/no_semicolon_lambda.test: -------------------------------------------------------------------------------- 1 | foo :: () {} 2 | === 3 | Root@0..12 4 | Binding@0..12 5 | Ident@0..3 "foo" 6 | Whitespace@3..4 " " 7 | Colon@4..5 ":" 8 | Colon@5..6 ":" 9 | Whitespace@6..7 " " 10 | Lambda@7..12 11 | ParamList@7..9 12 | LParen@7..8 "(" 13 | RParen@8..9 ")" 14 | Whitespace@9..10 " " 15 | Block@10..12 16 | LBrace@10..11 "{" 17 | RBrace@11..12 "}" 18 | -------------------------------------------------------------------------------- /crates/parser/src/tests/source_file/non_binding_at_root.test: -------------------------------------------------------------------------------- 1 | foo := () {}; 2 | === 3 | Root@0..13 4 | Binding@0..12 5 | Ident@0..3 "foo" 6 | Whitespace@3..4 " " 7 | Colon@4..5 ":" 8 | Error@5..6 9 | Equals@5..6 "=" 10 | Whitespace@6..7 " " 11 | Lambda@7..12 12 | ParamList@7..9 13 | LParen@7..8 "(" 14 | RParen@8..9 ")" 15 | Whitespace@9..10 " " 16 | Block@10..12 17 | LBrace@10..11 "{" 18 | RBrace@11..12 "}" 19 | Semicolon@12..13 ";" 20 | error at 5..6: expected Colon but found Equals 21 | -------------------------------------------------------------------------------- /crates/parser/src/tests/source_file/return_distinct.test: -------------------------------------------------------------------------------- 1 | foo :: () -> distinct i32 {} 2 | === 3 | Root@0..28 4 | Binding@0..28 5 | Ident@0..3 "foo" 6 | Whitespace@3..4 " " 7 | Colon@4..5 ":" 8 | Colon@5..6 ":" 9 | Whitespace@6..7 " " 10 | Lambda@7..28 11 | ParamList@7..9 12 | LParen@7..8 "(" 13 | RParen@8..9 ")" 14 | Whitespace@9..10 " " 15 | Arrow@10..12 "->" 16 | Whitespace@12..13 " " 17 | Ty@13..25 18 | Distinct@13..25 19 | Distinct@13..21 "distinct" 20 | Whitespace@21..22 " " 21 | Ty@22..25 22 | VarRef@22..25 23 | Ident@22..25 "i32" 24 | Whitespace@25..26 " " 25 | Block@26..28 26 | LBrace@26..27 "{" 27 | RBrace@27..28 "}" 28 | -------------------------------------------------------------------------------- /crates/parser/src/tests/source_file/semicolons_after.test: -------------------------------------------------------------------------------- 1 | main :: () {};;; 2 | === 3 | Root@0..16 4 | Binding@0..13 5 | Ident@0..4 "main" 6 | Whitespace@4..5 " " 7 | Colon@5..6 ":" 8 | Colon@6..7 ":" 9 | Whitespace@7..8 " " 10 | Lambda@8..13 11 | ParamList@8..10 12 | LParen@8..9 "(" 13 | RParen@9..10 ")" 14 | Whitespace@10..11 " " 15 | Block@11..13 16 | LBrace@11..12 "{" 17 | RBrace@12..13 "}" 18 | Semicolon@13..14 ";" 19 | Semicolon@14..15 ";" 20 | Semicolon@15..16 ";" 21 | -------------------------------------------------------------------------------- /crates/parser/src/tests/source_file/semicolons_before.test: -------------------------------------------------------------------------------- 1 | ;;;main :: () {} 2 | === 3 | Root@0..16 4 | Semicolon@0..1 ";" 5 | Semicolon@1..2 ";" 6 | Semicolon@2..3 ";" 7 | Binding@3..16 8 | Ident@3..7 "main" 9 | Whitespace@7..8 " " 10 | Colon@8..9 ":" 11 | Colon@9..10 ":" 12 | Whitespace@10..11 " " 13 | Lambda@11..16 14 | ParamList@11..13 15 | LParen@11..12 "(" 16 | RParen@12..13 ")" 17 | Whitespace@13..14 " " 18 | Block@14..16 19 | LBrace@14..15 "{" 20 | RBrace@15..16 "}" 21 | -------------------------------------------------------------------------------- /crates/parser/src/tests/source_file/semicolons_between.test: -------------------------------------------------------------------------------- 1 | ;;;main :: () {};;;foo :: "bar";;; 2 | === 3 | Root@0..34 4 | Semicolon@0..1 ";" 5 | Semicolon@1..2 ";" 6 | Semicolon@2..3 ";" 7 | Binding@3..16 8 | Ident@3..7 "main" 9 | Whitespace@7..8 " " 10 | Colon@8..9 ":" 11 | Colon@9..10 ":" 12 | Whitespace@10..11 " " 13 | Lambda@11..16 14 | ParamList@11..13 15 | LParen@11..12 "(" 16 | RParen@12..13 ")" 17 | Whitespace@13..14 " " 18 | Block@14..16 19 | LBrace@14..15 "{" 20 | RBrace@15..16 "}" 21 | Semicolon@16..17 ";" 22 | Semicolon@17..18 ";" 23 | Semicolon@18..19 ";" 24 | Binding@19..32 25 | Ident@19..22 "foo" 26 | Whitespace@22..23 " " 27 | Colon@23..24 ":" 28 | Colon@24..25 ":" 29 | Whitespace@25..26 " " 30 | StringLiteral@26..31 31 | DoubleQuote@26..27 "\"" 32 | StringContents@27..30 "bar" 33 | DoubleQuote@30..31 "\"" 34 | Semicolon@31..32 ";" 35 | Semicolon@32..33 ";" 36 | Semicolon@33..34 ";" 37 | -------------------------------------------------------------------------------- /crates/parser/src/tests/source_file/single_rbrace.test: -------------------------------------------------------------------------------- 1 | } 2 | === 3 | Root@0..1 4 | Error@0..1 5 | RBrace@0..1 "}" 6 | error at 0..1: expected definition but found RBrace 7 | -------------------------------------------------------------------------------- /crates/parser/src/tests/source_file/unfinished_lambda_block.test: -------------------------------------------------------------------------------- 1 | foo :: () { 2 | bar 3 | === 4 | Root@0..19 5 | Binding@0..19 6 | Ident@0..3 "foo" 7 | Whitespace@3..4 " " 8 | Colon@4..5 ":" 9 | Colon@5..6 ":" 10 | Whitespace@6..7 " " 11 | Lambda@7..19 12 | ParamList@7..9 13 | LParen@7..8 "(" 14 | RParen@8..9 ")" 15 | Whitespace@9..10 " " 16 | Block@10..19 17 | LBrace@10..11 "{" 18 | Whitespace@11..16 "\n " 19 | ExprStmt@16..19 20 | VarRef@16..19 21 | Ident@16..19 "bar" 22 | error at 19: missing Semicolon 23 | error at 19: missing RBrace 24 | -------------------------------------------------------------------------------- /crates/parser/src/tests/source_file/var_def_function_no_symbols.test: -------------------------------------------------------------------------------- 1 | my_fun(x: f32, y: f32) -> f32 { 2 | x + y 3 | } 4 | === 5 | Root@0..41 6 | Binding@0..41 7 | Ident@0..6 "my_fun" 8 | Lambda@6..41 9 | ParamList@6..22 10 | LParen@6..7 "(" 11 | Param@7..13 12 | Ident@7..8 "x" 13 | Colon@8..9 ":" 14 | Whitespace@9..10 " " 15 | Ty@10..13 16 | VarRef@10..13 17 | Ident@10..13 "f32" 18 | Comma@13..14 "," 19 | Whitespace@14..15 " " 20 | Param@15..21 21 | Ident@15..16 "y" 22 | Colon@16..17 ":" 23 | Whitespace@17..18 " " 24 | Ty@18..21 25 | VarRef@18..21 26 | Ident@18..21 "f32" 27 | RParen@21..22 ")" 28 | Whitespace@22..23 " " 29 | Arrow@23..25 "->" 30 | Whitespace@25..26 " " 31 | Ty@26..29 32 | VarRef@26..29 33 | Ident@26..29 "f32" 34 | Whitespace@29..30 " " 35 | Block@30..41 36 | LBrace@30..31 "{" 37 | Whitespace@31..34 "\n " 38 | BinaryExpr@34..39 39 | VarRef@34..35 40 | Ident@34..35 "x" 41 | Whitespace@35..36 " " 42 | Plus@36..37 "+" 43 | Whitespace@37..38 " " 44 | VarRef@38..39 45 | Ident@38..39 "y" 46 | Whitespace@39..40 "\n" 47 | RBrace@40..41 "}" 48 | error at 6: missing Colon 49 | error at 6: missing Colon 50 | -------------------------------------------------------------------------------- /crates/parser/src/tests/source_file/var_def_no_symbols.test: -------------------------------------------------------------------------------- 1 | bar 5; 2 | === 3 | Root@0..6 4 | Binding@0..6 5 | Ident@0..3 "bar" 6 | Whitespace@3..4 " " 7 | IntLiteral@4..5 8 | Int@4..5 "5" 9 | Semicolon@5..6 ";" 10 | error at 3: missing Colon 11 | error at 3: missing Colon 12 | -------------------------------------------------------------------------------- /crates/parser/src/tests/source_file/var_def_recursion.test: -------------------------------------------------------------------------------- 1 | a :: a; 2 | === 3 | Root@0..7 4 | Binding@0..7 5 | Ident@0..1 "a" 6 | Whitespace@1..2 " " 7 | Colon@2..3 ":" 8 | Colon@3..4 ":" 9 | Whitespace@4..5 " " 10 | VarRef@5..6 11 | Ident@5..6 "a" 12 | Semicolon@6..7 ";" 13 | -------------------------------------------------------------------------------- /crates/parser/src/token_set.rs: -------------------------------------------------------------------------------- 1 | use syntax::TokenKind; 2 | 3 | // Each bit represents whether that bit’s TokenKind is in the set. 4 | // 5 | // This is a TokenSet containing the first and third variants of TokenKind 6 | // (regardless of what they may be): 7 | // 8 | // 0000000000000101 9 | // 10 | // Thus, the number of TokenKind variants must not exceed 11 | // the number of bits in TokenSet. Which is why the macro automagically 12 | // determines the int type which has enough room to support all of our tokens 13 | // 14 | // This implementation is mostly stolen from rust-analyzer: 15 | // https://github.com/rust-analyzer/rust-analyzer/blob/b73b321478d3b2a98d380eb79de717e01620c4e9/crates/parser/src/token_set.rs 16 | // (This implementation is also stolen lol) 17 | capy_macros::define_token_set!("../../tokenizer.txt"); 18 | 19 | impl TokenSet { 20 | pub(crate) const fn new(kinds: [TokenKind; LEN]) -> Self { 21 | let mut value = 0; 22 | 23 | let mut idx = 0; 24 | while idx < kinds.len() { 25 | value |= mask(kinds[idx]); 26 | idx += 1; 27 | } 28 | 29 | Self(value) 30 | } 31 | 32 | pub(crate) const fn contains(self, kind: TokenKind) -> bool { 33 | self.0 & mask(kind) != 0 34 | } 35 | 36 | pub(crate) const fn union(self, other: Self) -> Self { 37 | Self(self.0 | other.0) 38 | } 39 | 40 | pub(crate) const fn without(self, kind: TokenKind) -> Self { 41 | Self(self.0 ^ mask(kind)) 42 | } 43 | } 44 | 45 | #[cfg(test)] 46 | #[test] 47 | fn it_works() { 48 | let set = TokenSet::new([TokenKind::Arrow, TokenKind::Int]); 49 | 50 | assert!(set.contains(TokenKind::Arrow)); 51 | assert!(set.contains(TokenKind::Int)); 52 | assert!(!set.contains(TokenKind::StringContents)); 53 | 54 | let set = set.union(TokenSet::new([TokenKind::StringContents])); 55 | 56 | assert!(set.contains(TokenKind::Arrow)); 57 | assert!(set.contains(TokenKind::Int)); 58 | assert!(set.contains(TokenKind::StringContents)); 59 | assert!(!set.contains(TokenKind::Ident)); 60 | } 61 | -------------------------------------------------------------------------------- /crates/syntax/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "syntax" 3 | version = "0.1.0-alpha.1" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | eventree = "0.7.0" 10 | capy_macros = {path = "../capy_macros"} 11 | -------------------------------------------------------------------------------- /crates/syntax/build.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | println!("cargo:rerun-if-changed=../../tokenizer.txt"); 3 | } 4 | -------------------------------------------------------------------------------- /crates/syntax/src/lib.rs: -------------------------------------------------------------------------------- 1 | use std::mem; 2 | 3 | pub type SyntaxBuilder = eventree::SyntaxBuilder; 4 | pub type SyntaxElement = eventree::SyntaxElement; 5 | pub type SyntaxNode = eventree::SyntaxNode; 6 | pub type SyntaxToken = eventree::SyntaxToken; 7 | pub type SyntaxTree = eventree::SyntaxTree; 8 | pub type SyntaxTreeBuf = eventree::SyntaxTreeBuf; 9 | pub type Event = eventree::Event; 10 | 11 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] 12 | pub enum TreeConfig {} 13 | 14 | unsafe impl eventree::TreeConfig for TreeConfig { 15 | type NodeKind = NodeKind; 16 | type TokenKind = TokenKind; 17 | 18 | fn node_kind_to_raw(node_kind: Self::NodeKind) -> u16 { 19 | node_kind as u16 20 | } 21 | 22 | fn token_kind_to_raw(token_kind: Self::TokenKind) -> u16 { 23 | token_kind as u16 24 | } 25 | 26 | unsafe fn token_kind_from_raw(raw: u16) -> Self::TokenKind { 27 | mem::transmute(raw as u8) 28 | } 29 | 30 | unsafe fn node_kind_from_raw(raw: u16) -> Self::NodeKind { 31 | mem::transmute(raw as u8) 32 | } 33 | } 34 | 35 | capy_macros::define_token_enum! { 36 | TokenKind, stripped, "../../tokenizer.txt" 37 | } 38 | 39 | /// Represents a group of tokens or other nodes. 40 | /// 41 | /// For example, StmtExpr might contain an IntLiteral which contains an Int token 42 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] 43 | pub enum NodeKind { 44 | Root, 45 | VarRef, 46 | Call, 47 | ArgList, 48 | Arg, 49 | Directive, 50 | ArrayDecl, 51 | ArraySize, 52 | ArrayLiteral, 53 | ArrayBody, 54 | ArrayItem, 55 | IndexExpr, // the entire expression of indexing. e.g. `my_array[6]` 56 | Index, // the actual index. `6` in `my_array[6]` 57 | Source, 58 | Distinct, 59 | ComptimeExpr, 60 | ParenExpr, 61 | Block, 62 | IfExpr, 63 | ElseBranch, 64 | WhileExpr, 65 | Condition, 66 | SwitchExpr, 67 | SwitchArm, 68 | LabelDecl, 69 | LabelRef, 70 | IntLiteral, 71 | FloatLiteral, 72 | BoolLiteral, 73 | CharLiteral, 74 | StringLiteral, 75 | CastExpr, 76 | RefExpr, // `^foo` or `^mut foo` 77 | MutExpr, // `mut rawptr` (yes, that's the only thing its used for) 78 | DerefExpr, 79 | BinaryExpr, 80 | UnaryExpr, 81 | Binding, // `x :: 5` 82 | VarDef, // `x := 5` 83 | Assign, 84 | ExprStmt, 85 | ReturnStmt, // todo: change these to void expressions 86 | BreakStmt, 87 | ContinueStmt, 88 | DeferStmt, 89 | Lambda, 90 | ParamList, 91 | Param, 92 | StructDecl, // `struct { foo: i32 }` 93 | MemberDecl, // `foo: i32` 94 | StructLiteral, // `My_Struct { foo: 123 }` 95 | MemberLiteral, // `foo: 123` 96 | EnumDecl, 97 | VariantDecl, 98 | Discriminant, 99 | ImportExpr, 100 | Ty, 101 | Path, 102 | Comment, 103 | Error, 104 | } 105 | -------------------------------------------------------------------------------- /crates/test-utils/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "test-utils" 3 | version = "0.1.0-alpha.1" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | rustc-hash = "2.1" 10 | -------------------------------------------------------------------------------- /crates/test-utils/src/lib.rs: -------------------------------------------------------------------------------- 1 | use rustc_hash::FxHashMap; 2 | 3 | /// splits text into multiple modules 4 | /// 5 | /// example: 6 | /// ```text 7 | /// #- main.capy 8 | /// foo :: import "foo.capy"; 9 | /// 10 | /// Foo :: foo.Foo; 11 | /// 12 | /// fun :: () -> Foo { 13 | /// foo : Foo = 0; 14 | /// 15 | /// foo 16 | /// } 17 | /// #- foo.capy 18 | /// Foo :: distinct i32; 19 | /// ``` 20 | /// 21 | /// this gets transformed into a map of 22 | /// ```text 23 | /// main.capy => "foo :: import ..." 24 | /// foo.capy => "Foo :: distinct ..." 25 | /// ``` 26 | /// 27 | /// alternatively, if there is no "#- " contained in the given input, 28 | /// the output will be a single map of 29 | /// ```text 30 | /// main.capy => {the entire input} 31 | /// ```` 32 | pub fn split_multi_module_test_data(input: &str) -> FxHashMap<&str, &str> { 33 | const MARKER_COMMENT_START: &str = "#- "; 34 | 35 | let has_no_marker_comments = !input.contains(MARKER_COMMENT_START); 36 | if has_no_marker_comments { 37 | let mut modules = FxHashMap::default(); 38 | modules.insert("main.capy", input); 39 | return modules; 40 | } 41 | 42 | let mut module_idxs = FxHashMap::default(); 43 | let mut current_module_name = None; 44 | let mut line_idxs = input.match_indices('\n').map(|(idx, _)| idx + 1).peekable(); 45 | 46 | while let Some(line_start) = line_idxs.next() { 47 | let line_end = match line_idxs.peek() { 48 | Some(end) => *end, 49 | None => break, 50 | }; 51 | 52 | let line = &input[line_start..line_end]; 53 | if let Some(idx) = line.find(MARKER_COMMENT_START) { 54 | let module_name_start = idx + MARKER_COMMENT_START.len(); 55 | let module_name_end = line.len() - 1; // remove newline 56 | 57 | let module_name = &line[module_name_start..module_name_end]; 58 | 59 | module_idxs.insert(module_name, line_end..line_end); 60 | current_module_name = Some(module_name); 61 | } 62 | 63 | module_idxs 64 | .get_mut(current_module_name.as_ref().unwrap()) 65 | .unwrap() 66 | .end = line_end; 67 | } 68 | 69 | module_idxs 70 | .into_iter() 71 | .map(|(module_name, range)| (module_name, &input[range])) 72 | .collect() 73 | } 74 | -------------------------------------------------------------------------------- /crates/token/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "token" 3 | version = "0.1.0-alpha.1" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | syntax = {path = "../syntax"} 10 | text-size = "1.1" 11 | -------------------------------------------------------------------------------- /crates/token/src/lib.rs: -------------------------------------------------------------------------------- 1 | use std::fmt; 2 | 3 | use syntax::TokenKind; 4 | use text_size::{TextRange, TextSize}; 5 | 6 | #[derive(PartialEq)] 7 | pub struct Tokens { 8 | kinds: Vec, 9 | starts: Vec, 10 | } 11 | 12 | impl Tokens { 13 | pub fn new(kinds: Vec, starts: Vec) -> Self { 14 | debug_assert_eq!(kinds.len() + 1, starts.len()); 15 | Self { kinds, starts } 16 | } 17 | 18 | pub fn kind(&self, idx: usize) -> TokenKind { 19 | self.kinds[idx] 20 | } 21 | 22 | pub fn get_kind(&self, idx: usize) -> Option { 23 | self.kinds.get(idx).copied() 24 | } 25 | 26 | pub fn range(&self, idx: usize) -> TextRange { 27 | let start = self.starts[idx]; 28 | let end = self.starts[idx + 1]; 29 | TextRange::new(start, end) 30 | } 31 | 32 | pub fn iter(&self) -> impl Iterator + '_ { 33 | self.kinds 34 | .iter() 35 | .copied() 36 | .zip(self.starts.iter().copied()) 37 | .zip(self.starts.iter().copied().skip(1)) 38 | .map(|((kind, start), end)| (kind, TextRange::new(start, end))) 39 | } 40 | 41 | #[allow(clippy::len_without_is_empty)] 42 | pub fn len(&self) -> usize { 43 | self.kinds.len() 44 | } 45 | } 46 | 47 | impl fmt::Debug for Tokens { 48 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 49 | for (i, (kind, range)) in self.iter().enumerate() { 50 | if i != 0 { 51 | writeln!(f)?; 52 | } 53 | 54 | write!(f, "{kind:?}@{range:?}")?; 55 | } 56 | 57 | Ok(()) 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /crates/topo/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "topo" 3 | version = "0.1.0-alpha.1" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | indexmap = "2.7.1" 10 | 11 | [dev-dependencies] 12 | itertools = "0.14.0" 13 | -------------------------------------------------------------------------------- /crates/uid_gen/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "uid_gen" 3 | version = "0.1.0-alpha.1" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /crates/uid_gen/src/lib.rs: -------------------------------------------------------------------------------- 1 | #[derive(Default)] 2 | pub struct UIDGenerator { 3 | inner: u32, 4 | } 5 | 6 | impl UIDGenerator { 7 | pub fn generate_unique_id(&mut self) -> u32 { 8 | let id = self.inner; 9 | self.inner += 1; 10 | id 11 | } 12 | } 13 | 14 | #[cfg(test)] 15 | mod tests { 16 | use super::*; 17 | 18 | #[test] 19 | fn test() { 20 | let mut uid_gen = UIDGenerator::default(); 21 | 22 | assert_eq!(uid_gen.generate_unique_id(), 0); 23 | assert_eq!(uid_gen.generate_unique_id(), 1); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /examples/arrays.capy: -------------------------------------------------------------------------------- 1 | 2 | core :: #mod("core"); 3 | 4 | main :: () { 5 | my_array : [6]i32 = build_array(); 6 | 7 | my_array_ptr := ^my_array; 8 | 9 | idx := 0; 10 | while idx < 6 { 11 | core.println(my_array_ptr[idx]); 12 | idx += 1; 13 | } 14 | } 15 | 16 | build_array :: () -> [6] i32 { 17 | my_array := i32.[4, 8, 15, 16, 23, 42]; 18 | 19 | my_array 20 | } 21 | -------------------------------------------------------------------------------- /examples/arrays_of_arrays.capy: -------------------------------------------------------------------------------- 1 | core :: #mod("core"); 2 | 3 | // with big nested arrays like this, it might be clearer to use `.[]` syntax instead like in `make_array` 4 | global :: ([3][3] i8).[ 5 | ([3] i8).[ i8.[105, 115, 125], i8.[105, 115, 125], i8.[105, 115, 125] ], 6 | ([3] i8).[ i8.[105, 115, 125], i8.[105, 115, 125], i8.[105, 115, 125] ], 7 | ([3] i8).[ i8.[105, 115, 125], i8.[105, 115, 125], i8.[105, 115, 125] ], 8 | ]; 9 | 10 | make_array :: (x: i8, y: i8, z: i8) -> [3][3][3] i8 { 11 | .[ 12 | .[ .[x, y, z], .[x, y, z], .[x, y, z] ], 13 | .[ .[x, y, z], .[x, y, z], .[x, y, z] ], 14 | .[ .[x, y, z], .[x, y, z], .[x, y, z] ], 15 | ] 16 | } 17 | 18 | // prints out an array from the stack, and one from the data section 19 | main :: () -> usize { 20 | my_array := make_array(2, 4, 6); 21 | 22 | // the stack memory of the above array isn't cleared, even if the old stack is overwritten by new function calls 23 | make_array(8, 10, 12); 24 | 25 | edit(^mut my_array); 26 | 27 | print_array_by_value(my_array, "my_array"); 28 | 29 | core.println(); 30 | 31 | print_array_by_ref(^global, "global"); 32 | 33 | 0 34 | } 35 | 36 | edit :: (arr: ^mut [3][3][3]i8) { 37 | arr[1][1] = i8.[127, 0, 42]; 38 | } 39 | 40 | // While an array is internally a pointer, a pointer to an array doesn't actually get 41 | // compiled as a pointer to a pointer. The only machine code difference between the 42 | // following two functions is that print_array_by_value memcopies the array into 43 | // it's stack before using it 44 | 45 | print_array_by_value :: (arr: [3][3][3]i8, name: str) { 46 | x : usize = 0; 47 | while x < 3 { 48 | y : usize = 0; 49 | while y < 3 { 50 | z : usize = 0; 51 | while z < 3 { 52 | core.println(name, "[", x, "][", y, "][", z, "] = ", arr[x][y][z]); 53 | z += 1; 54 | } 55 | y += 1; 56 | } 57 | x += 1; 58 | } 59 | } 60 | 61 | print_array_by_ref :: (arr: ^[3][3][3]i8, name: str) { 62 | x : usize = 0; 63 | while x < 3 { 64 | y : usize = 0; 65 | while y < 3 { 66 | z : usize = 0; 67 | while z < 3 { 68 | core.println(name, "[", x, "][", y, "][", z, "] = ", arr[x][y][z]); 69 | z += 1; 70 | } 71 | y += 1; 72 | } 73 | x += 1; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /examples/auto_deref.capy: -------------------------------------------------------------------------------- 1 | core :: #mod("core"); 2 | io :: #import("io.capy"); 3 | 4 | Foo :: struct { 5 | a: i32, 6 | b: i32, 7 | }; 8 | 9 | main :: () { 10 | core.println("struct auto deref:"); 11 | 12 | my_foo := Foo.{ 13 | a = 4, 14 | b = 8, 15 | }; 16 | 17 | core.println("my_foo.b ", my_foo.b); 18 | 19 | ptr := ^^^^my_foo; 20 | 21 | core.println("ptr^^^^.b ", ptr^^^^.b); 22 | core.println("ptr^^^.b ", ptr^^^.b); 23 | core.println("ptr^^.b ", ptr^^.b); 24 | core.println("ptr^.b ", ptr^.b); 25 | core.println("ptr.b ", ptr.b); 26 | 27 | core.println(" give:"); 28 | 29 | give_struct(ptr^^); 30 | 31 | core.println("\narray auto deref:"); 32 | 33 | my_array := i32.[4, 8, 15, 16, 23, 42]; 34 | 35 | ptr := ^my_array; 36 | 37 | idx : usize = 0; 38 | while idx < 3 { 39 | core.println("ptr^[", idx, "] ", ptr^[idx]); 40 | core.println("ptr[", idx, "] ", ptr[idx]); 41 | idx += 1; 42 | } 43 | 44 | ptr_ptr := ^^my_array; 45 | 46 | while idx < 6 { 47 | core.println("ptr_ptr^^[", idx, "] ", ptr_ptr^^[idx]); 48 | core.println("ptr_ptr^[", idx, "] ", ptr_ptr^[idx]); 49 | core.println("ptr_ptr[", idx, "] ", ptr_ptr[idx]); 50 | idx += 1; 51 | } 52 | 53 | core.println(" give:"); 54 | 55 | give_array(ptr_ptr); 56 | } 57 | 58 | give_struct :: (ptr: ^^Foo) { 59 | core.println("ptr^^.b ", ptr^^.b); 60 | core.println("ptr^.b ", ptr^.b); 61 | core.println("ptr.b ", ptr.b); 62 | } 63 | 64 | give_array :: (ptr_ptr: ^^[6] i32) { 65 | idx : usize = 0; 66 | while idx < 6 { 67 | core.println("ptr_ptr^^[", idx, "] ", ptr_ptr^^[idx]); 68 | core.println("ptr_ptr^[", idx, "] ", ptr_ptr^[idx]); 69 | core.println("ptr_ptr[", idx, "] ", ptr_ptr[idx]); 70 | idx += 1; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /examples/comptime.capy: -------------------------------------------------------------------------------- 1 | core :: #mod("core"); 2 | libc :: #mod("core").libc; 3 | io :: #import("io.capy"); 4 | 5 | // comptime blocks are JIT compiled and the bytes they return are baked into the data segment of the program 6 | my_global :: comptime { 7 | libc.puts("Calculating global value..."); 8 | 9 | x := 5; 10 | 11 | x * 2 12 | }; 13 | 14 | main :: () { 15 | core.println("Hello at runtime!"); 16 | 17 | core.println("that global was equal to ", my_global); 18 | 19 | powers_of_two := comptime { 20 | core.println("Doing heavy calculation..."); 21 | 22 | math :: #mod("core").math; 23 | 24 | array: [6]i32; 25 | 26 | idx := 0; 27 | while idx < array.len { 28 | array[idx] = math.pow_i32(2, i32.(idx)); 29 | idx += 1; 30 | } 31 | 32 | core.println("Finished heavy calculation :)"); 33 | 34 | array 35 | }; 36 | 37 | core.println("2^0 = ", powers_of_two[0]); 38 | core.println("2^1 = ", powers_of_two[1]); 39 | core.println("2^2 = ", powers_of_two[2]); 40 | core.println("2^3 = ", powers_of_two[3]); 41 | core.println("2^4 = ", powers_of_two[4]); 42 | core.println("2^5 = ", powers_of_two[5]); 43 | } 44 | 45 | -------------------------------------------------------------------------------- /examples/comptime_types.capy: -------------------------------------------------------------------------------- 1 | 2 | core :: #mod("core"); 3 | ptr :: core.ptr; 4 | libc :: core.libc; 5 | meta :: core.meta; 6 | 7 | io :: #import("io.capy"); 8 | 9 | My_Type :: comptime { 10 | libc.puts("This is getting JIT'ed!"); 11 | 12 | Field_Ty :: comptime { 13 | libc.puts("computing field type"); 14 | 15 | input := io.get_user_input(); 16 | 17 | if input == 32 { 18 | i32 19 | } else if input == 64 { 20 | i64 21 | } else { 22 | u8 23 | } 24 | }; 25 | 26 | size :: comptime { 27 | 6 / 2 28 | }; 29 | 30 | struct { 31 | a: Field_Ty, 32 | b: [size] i32, 33 | } 34 | }; 35 | 36 | main :: () { 37 | core.println("size: ", meta.size_of(My_Type)); 38 | 39 | foo : My_Type = My_Type.{ 40 | a = 42, 41 | b = i32.[4, 8, 15] 42 | }; 43 | 44 | core.println(foo); 45 | } 46 | 47 | -------------------------------------------------------------------------------- /examples/drink.capy: -------------------------------------------------------------------------------- 1 | core :: #mod("core"); 2 | 3 | main :: () -> i32 { 4 | age := 45; 5 | 6 | message := if age >= 21 { 7 | "you can drink" 8 | } else if age >= 18 { 9 | "you are an adult but can't drink" 10 | } else { 11 | "you can't drink" 12 | }; 13 | 14 | core.println(message); 15 | 16 | 0 17 | } 18 | -------------------------------------------------------------------------------- /examples/enums_and_switch_statements.capy: -------------------------------------------------------------------------------- 1 | 2 | core :: #mod("core"); 3 | 4 | Animal :: enum { 5 | Dog: str, 6 | Cat, 7 | Fish: i32, // maybe this is the fish's age or something 8 | Cow, 9 | Chicken | 20, 10 | Sheep: struct { 11 | name: str, 12 | wool_amount: f32, 13 | fullness: f32, 14 | }, 15 | Pig, 16 | }; 17 | 18 | main :: () { 19 | do_animal_stuff(Animal.Dog.("George")); 20 | do_animal_stuff(Animal.Cat.()); 21 | do_animal_stuff(Animal.Fish.(1000)); 22 | do_animal_stuff(Animal.Cow.()); 23 | do_animal_stuff(Animal.Chicken.()); 24 | do_animal_stuff(Animal.Sheep.{ 25 | name = "hello", 26 | wool_amount = 1.0, 27 | fullness = 0.5, 28 | }); 29 | do_animal_stuff(Animal.Pig.()); 30 | } 31 | 32 | do_animal_stuff :: (animal: Animal) { 33 | num := animal_to_num(animal); 34 | 35 | core.print("[", num, "] "); 36 | 37 | switch a in animal { 38 | Cat => core.print("cat!"), 39 | Dog => { 40 | core.print("dog: ", a); 41 | }, 42 | Fish => { 43 | core.print("it was a fish (age = ", a, ")"); 44 | }, 45 | Cow => core.print("cow!!!"), 46 | Chicken => core.print("chicken >>>"), 47 | Pig => core.print("oink oink"), 48 | Sheep => { 49 | core.print("sheep: ", a.name, ", wool: ", a.wool_amount, ", fullness: ", a.fullness); 50 | }, 51 | } 52 | 53 | core.println(); 54 | } 55 | 56 | animal_to_num :: (animal: Animal) -> u16 { 57 | num := switch animal { 58 | Cat => 100, 59 | Dog => 200, 60 | Fish => 300, 61 | Cow => 400, 62 | Chicken => 500, 63 | Pig => 600, 64 | Sheep => 700, 65 | }; 66 | 67 | num 68 | } 69 | 70 | -------------------------------------------------------------------------------- /examples/fib.capy: -------------------------------------------------------------------------------- 1 | 2 | core :: #mod("core"); 3 | 4 | target :: 28; 5 | repeat :: 5; 6 | answer :: 317811; 7 | 8 | fib :: (n: i32) -> i32 { 9 | if n <= 1 { 10 | n 11 | } else { 12 | fib(n - 1) + fib(n - 2) 13 | } 14 | } 15 | 16 | main :: () { 17 | io :: #import("io.capy"); 18 | 19 | core.println("Running Fibonacci #", target); 20 | core.println("Ready... Go!"); 21 | 22 | result := fib(target); 23 | 24 | core.println("Fibonacci number #", target, " = ", result); 25 | 26 | if result != answer { 27 | core.println("The answer is WRONG! Should be ", answer); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /examples/files.capy: -------------------------------------------------------------------------------- 1 | 2 | libc :: #mod("core").libc; 3 | 4 | write_to_file :: (filename: str) { 5 | my_file := libc.fopen("hello.txt", "w"); 6 | 7 | libc.fputs("Hello, World!", my_file); 8 | 9 | libc.fclose(my_file); 10 | } 11 | 12 | read_from_file :: (filename: str) { 13 | my_file := libc.fopen("hello.txt", "r"); 14 | 15 | buf := (^mut char).(libc.malloc(20)); 16 | 17 | text := libc.fgets(buf, 20, my_file); 18 | libc.puts(text); 19 | 20 | libc.free(buf); 21 | 22 | libc.fclose(my_file); 23 | } 24 | 25 | main :: () { 26 | libc.puts("writing to hello.txt"); 27 | write_to_file("hello.txt"); 28 | 29 | libc.puts("reading from hello.txt"); 30 | read_from_file("hello.txt"); 31 | } 32 | 33 | printf :: (s: str, buf: str) extern; 34 | -------------------------------------------------------------------------------- /examples/first_class_functions.capy: -------------------------------------------------------------------------------- 1 | 2 | core :: #mod("core"); 3 | 4 | add :: (x: i32, y: i32) -> i32 { 5 | x + y 6 | } 7 | 8 | sub :: (x: i32, y: i32) -> i32 { 9 | x - y 10 | } 11 | 12 | mul :: (x: i32, y: i32) -> i32 { 13 | x * y 14 | } 15 | 16 | div :: (x: i32, y: i32) -> i32 { 17 | x / y 18 | } 19 | 20 | apply :: (fn: (x: i32, y: i32) -> i32, x: i32, y: i32) -> i32 { 21 | fn(x, y) 22 | } 23 | 24 | main :: () -> i32 { 25 | core.println("apply add to 1 and 2 ... ", apply(add, 1, 2)); 26 | core.println("apply sub to 5 and 3 ... ", apply(sub, 5, 3)); 27 | core.println("apply mul to 3 and 2 ... ", apply(mul, 3, 2)); 28 | core.println("apply div to 10 and 2 ... ", apply(div, 10, 2)); 29 | 30 | pow :: (x: i32, y: i32) -> i32 { 31 | res := 1; 32 | 33 | i := 0; 34 | while i < y { 35 | res *= x; 36 | 37 | i += 1; 38 | } 39 | 40 | res 41 | }; 42 | 43 | core.println("apply pow to 2 and 3 ... ", apply(pow, 2, 3)); 44 | 45 | pow(5, 6); 46 | 47 | (val: i32) -> i32 { 48 | val * 2 49 | }(25) 50 | } 51 | -------------------------------------------------------------------------------- /examples/float_to_string.capy: -------------------------------------------------------------------------------- 1 | core :: #mod("core"); 2 | 3 | main :: () { 4 | core.println(3.14159); 5 | core.println(); 6 | 7 | core.println("ln 10 = ", comptime core.math.ln(10)); 8 | 9 | core.println("ln 50 = ", comptime core.math.ln(50)); 10 | 11 | core.println("ln 100 = ", comptime core.math.ln(100)); 12 | 13 | core.println("ln 500 = ", comptime core.math.ln(500)); 14 | 15 | core.println("log 10 = ", comptime core.math.log10(10)); 16 | 17 | core.println("log 50 = ", comptime core.math.log10(50)); 18 | 19 | core.println("log 100 = ", comptime core.math.log10(100)); 20 | 21 | core.println("log 500 = ", comptime core.math.log10(500)); 22 | 23 | core.println(" 1 / 0 = ", 1.0 / 0.0); 24 | 25 | core.println("-1 / 0 = ", -1.0 / 0.0); 26 | 27 | core.println(" 0 / 0 = ", 0.0 / 0.0); 28 | } 29 | 30 | -------------------------------------------------------------------------------- /examples/hello_world.capy: -------------------------------------------------------------------------------- 1 | core :: #mod("core"); 2 | 3 | greeting :: "Hello, World!"; 4 | 5 | main :: () -> i32 { 6 | core.println(greeting); 7 | 8 | // exit with code 0 9 | 0 10 | } 11 | -------------------------------------------------------------------------------- /examples/io.capy: -------------------------------------------------------------------------------- 1 | 2 | core :: #mod("core"); 3 | 4 | get_user_input :: () -> i32 { 5 | buffer := char.['\0', '\0', '\0', '\0', '\0']; 6 | 7 | core.libc.read(core.libc.stdin, (^mut u8).((mut rawptr).(^mut buffer)), 2); 8 | 9 | len := isize.(core.str_len(str.(buffer))); 10 | 11 | result := 0; 12 | idx := 0; 13 | 14 | `main_loop: while idx < buffer.len { 15 | ch := buffer[usize.(idx)]; 16 | 17 | digit := if ch == '0' { 18 | 0 19 | } else if ch == '1' { 20 | 1 21 | } else if ch == '2' { 22 | 2 23 | } else if ch == '3' { 24 | 3 25 | } else if ch == '4' { 26 | 4 27 | } else if ch == '5' { 28 | 5 29 | } else if ch == '6' { 30 | 6 31 | } else if ch == '7' { 32 | 7 33 | } else if ch == '8' { 34 | 8 35 | } else if ch == '9' { 36 | 9 37 | } else { 38 | break `main_loop; 39 | }; 40 | 41 | j : isize = 0; 42 | 43 | while j < len - 1 { 44 | digit *= 10; 45 | j += 1; 46 | } 47 | len -= 1; 48 | 49 | result += digit; 50 | 51 | idx += 1; 52 | } 53 | 54 | result 55 | } 56 | -------------------------------------------------------------------------------- /examples/lists.capy: -------------------------------------------------------------------------------- 1 | 2 | core :: #mod("core"); 3 | list :: core.list; 4 | 5 | main :: () { 6 | Sub_Type :: u128; 7 | 8 | // `List` is dynamic, and uses runtime reflection 9 | // to correctly store and manage it's contents 10 | my_list := list.make(Sub_Type); 11 | 12 | list.push(^mut my_list, 4); 13 | list.push(^mut my_list, 8); 14 | list.push(^mut my_list, 15); 15 | list.push(^mut my_list, 16); 16 | list.push(^mut my_list, 23); 17 | 18 | // `List` uses `core.cast_into`, which will cast 19 | // `any`s into the correct type at runtime 20 | last : u8 = 42; 21 | list.push(^mut my_list, last); 22 | 23 | core.println(list.get(^my_list, 5)); 24 | 25 | list.pop(^mut my_list); 26 | 27 | core.println([]Sub_Type.(list.to_slice(^my_list))); 28 | } 29 | -------------------------------------------------------------------------------- /examples/pretty.capy: -------------------------------------------------------------------------------- 1 | core :: #mod("core"); 2 | 3 | main :: () { 4 | // These are the same as odin 5 | core.println("\e[32mHello!\v\e[34mWorld\e[0m\n"); 6 | core.println("Joe\b\b\bP"); 7 | core.println("ALERT!\a"); 8 | core.println("\fAnd\r\n\tnow.."); 9 | core.println("\e[1;90mC\e[91mO\e[92mL\e[93m\e[94mO\e[95mR\e[96mS\e[97m!\e[0m"); 10 | } 11 | -------------------------------------------------------------------------------- /examples/ptr_assign.capy: -------------------------------------------------------------------------------- 1 | 2 | core :: #mod("core"); 3 | 4 | main :: () { 5 | x := 5; // to get a `^mut` to x, x must be mutable `:=` instead of immutable `::` 6 | y :: ^mut x; // since we're not actually assigning a value to y, y can be immutable `::` 7 | 8 | core.println("x = ", x); 9 | 10 | y^ = 25; 11 | 12 | core.println("x = ", x, "\n"); 13 | 14 | x := i32.[1, 2, 3]; 15 | y :: ^mut x; 16 | 17 | core.println("x = { ", x[0], ", ", x[1], ", ", x[2], " }"); 18 | 19 | y[1] = 42; 20 | 21 | core.println("x = { ", x[0], ", ", x[1], ", ", x[2], " }"); 22 | } 23 | -------------------------------------------------------------------------------- /examples/ptrs_to_ptrs.capy: -------------------------------------------------------------------------------- 1 | 2 | main :: () { 3 | x := 42; 4 | z := ^^x; 5 | 6 | printf("%x -> %x -> %i", z, z^, z^^); 7 | } 8 | 9 | printf :: (s: str, n1: ^^i32, n2: ^i32, n3: i32) extern; 10 | -------------------------------------------------------------------------------- /examples/slices.capy: -------------------------------------------------------------------------------- 1 | core :: #mod("core"); 2 | meta :: core.meta; 3 | 4 | main :: () { 5 | // arrays get autocasted to slices 6 | slice : []i32 = i32.[4, 8, 15, 16, 23, 42]; 7 | 8 | print_int_slice(slice); 9 | print_int_slice(i32.[1, 2, 3]); 10 | print_int_slice(i32.[4, 5, 6, 7, 8]); 11 | 12 | // arrays may autocast to slices but going the opposite 13 | // direction requires an explicit cast 14 | 15 | arr := [6]i32.(slice); // slice => array 16 | 17 | print_int_array(arr); 18 | } 19 | 20 | print_int_slice :: (slice: [] i32) { 21 | idx := 0; 22 | core.print("[ "); 23 | while idx < slice.len { 24 | core.print(slice[idx]); 25 | 26 | if idx < slice.len - 1 { 27 | core.print(", "); 28 | } 29 | 30 | idx += 1; 31 | } 32 | core.print(" ]\n"); 33 | }; 34 | 35 | print_int_array :: (arr: [6] i32) { 36 | idx := 0; 37 | core.print("[ "); 38 | while idx < arr.len { 39 | core.print(arr[idx]); 40 | 41 | if idx < arr.len - 1 { 42 | core.print(", "); 43 | } 44 | 45 | idx += 1; 46 | } 47 | core.print(" ]\n"); 48 | }; 49 | -------------------------------------------------------------------------------- /examples/strings.capy: -------------------------------------------------------------------------------- 1 | string_builder :: #mod("core").string_builder; 2 | 3 | main :: () { 4 | my_str := string_builder.make(); 5 | defer string_builder.free(^mut my_str); 6 | 7 | string_builder.append_char(^mut my_str, 'H'); 8 | string_builder.append_char(^mut my_str, 'e'); 9 | string_builder.append_char(^mut my_str, 'l'); 10 | string_builder.append_char(^mut my_str, 'l'); 11 | string_builder.append_char(^mut my_str, char.(111)); // o 12 | string_builder.append_char(^mut my_str, char.(32)); // \s 13 | string_builder.append_str(^mut my_str, "World"); 14 | string_builder.append_char(^mut my_str, '!'); 15 | string_builder.append_char(^mut my_str, '\n'); 16 | 17 | string_builder.print(^my_str); 18 | } 19 | -------------------------------------------------------------------------------- /examples/structs.capy: -------------------------------------------------------------------------------- 1 | 2 | core :: #mod("core"); 3 | libc :: core.libc; 4 | 5 | Person :: struct { 6 | name: str, 7 | age: i32 8 | }; 9 | 10 | Company :: struct { 11 | employees: [3]Person, 12 | }; 13 | 14 | main :: () { 15 | some_guy := Person.{ 16 | name = "Terry", 17 | age = 48, 18 | }; 19 | 20 | my_company := Company.{ 21 | employees = Person.[ 22 | Person.{ 23 | name = "Bob", 24 | age = 32, 25 | }, 26 | some_guy, // copied into the array 27 | Person.{ 28 | name = "Walter", 29 | age = 52, 30 | }, 31 | ], 32 | }; 33 | 34 | some_guy.age = 1000; 35 | 36 | my_company.employees[0].age = 3; 37 | 38 | libc.puts("people:"); 39 | idx := 0; 40 | while idx < 3 { 41 | print_person_by_ref(^my_company.employees[idx]); 42 | idx += 1; 43 | } 44 | 45 | libc.puts("\nsome_guy:"); 46 | print_person_by_value(some_guy); 47 | } 48 | 49 | // While a struct is internally a pointer, a pointer to a struct doesn't actually get 50 | // compiled as a pointer to a pointer. The only machine code difference between the 51 | // following two functions is that print_person_by_value memcopies the struct into 52 | // it's stack before using it 53 | 54 | print_person_by_value :: (p: Person) { 55 | core.println(p.name, " is ", p.age, " years old"); 56 | } 57 | 58 | print_person_by_ref :: (p: ^Person) { 59 | core.println(p.name, " is ", p.age, " years old"); 60 | } 61 | -------------------------------------------------------------------------------- /examples/vectors.capy: -------------------------------------------------------------------------------- 1 | 2 | core :: #mod("core"); 3 | 4 | Vector3 :: distinct [3] i32; 5 | 6 | main :: () { 7 | my_point : Vector3 = i32.[1, 2, 3]; 8 | 9 | core.println("my_point: (", my_point[0], ", ", my_point[1], ", ", my_point[2], ")"); 10 | } 11 | -------------------------------------------------------------------------------- /fuzz/.gitignore: -------------------------------------------------------------------------------- 1 | artifacts 2 | corpus/main/* 3 | !corpus/main/example -------------------------------------------------------------------------------- /fuzz/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "fuzz" 3 | version = "0.1.0" 4 | 5 | [package.metadata] 6 | cargo-fuzz = true 7 | 8 | [dependencies] 9 | ast = {path = "../crates/ast"} 10 | hir = {path = "../crates/hir"} 11 | hir_ty = {path = "../crates/hir_ty"} 12 | codegen = {path = "../crates/codegen"} 13 | interner = { version = "0.1.0", path = "../crates/interner" } 14 | la-arena = "0.3.1" 15 | lexer = {path = "../crates/lexer"} 16 | libfuzzer-sys = "0.4.2" 17 | parser = {path = "../crates/parser"} 18 | rustc-hash = "2.1" 19 | uid_gen = { version = "0.1.0", path = "../crates/uid_gen" } 20 | target-lexicon = "0.13.1" 21 | 22 | [workspace] 23 | 24 | [[bin]] 25 | name = "main" 26 | path = "fuzz_targets/main.rs" 27 | -------------------------------------------------------------------------------- /fuzz/capy.dict: -------------------------------------------------------------------------------- 1 | "a" 2 | "main" 3 | "::" 4 | ";" 5 | ":=" 6 | "[" 7 | "]" 8 | "{" 9 | "}" 10 | "=" 11 | "+" 12 | "*" 13 | "/" 14 | "%" 15 | "-" 16 | "," 17 | "^" 18 | "." 19 | "129830" 20 | "-12" 21 | "1" 22 | "0" 23 | "1.0" 24 | "123.456" 25 | ".1" 26 | "48.1516e2342" 27 | "42.0E0" 28 | "'" 29 | "'a'" 30 | "\"" 31 | "\\" 32 | "\"Hello\"" 33 | "//" 34 | "struct" 35 | "->" 36 | "b" 37 | "c" 38 | "d" 39 | "\"" 40 | "(" 41 | ")" 42 | "libc" 43 | "extern" 44 | "i32" 45 | "usize" 46 | "u8" 47 | "^i32" 48 | "^usize" 49 | "^u8" 50 | "string" 51 | "^string" 52 | "any" 53 | "^any" 54 | "mut" 55 | "^mut" 56 | "as" 57 | "while" 58 | ":" 59 | "<" 60 | "<=" 61 | ">" 62 | ">=" 63 | "!=" 64 | "==" 65 | "comptime" 66 | "if" 67 | "else" 68 | "fn" 69 | "x" 70 | "y" 71 | " " 72 | "distinct" 73 | "false" 74 | "true" 75 | "||" 76 | "&&" 77 | "loop" 78 | "!" 79 | "import" 80 | -------------------------------------------------------------------------------- /fuzz/corpus/main/example: -------------------------------------------------------------------------------- 1 | foo :: 10; 2 | bar := 20; 3 | a :: comptime { foo + {bar * bar - {100 / 33}} }; 4 | 5 | calc :: comptime { 6 | sum = (x: i32, y: i32) -> i32 { x + y }; 7 | mul = (x: i32, y: i32) -> i32 { x * y }; 8 | 9 | do_math = (op: (x: i32, y: i32) -> i32, x, y) { op(x, y) }; 10 | 11 | do_math(sum, 2, 3); 12 | do_math(mul, 2, 3); 13 | 14 | { 15 | do_math(mul, 6, 7) 16 | } 17 | }; 18 | 19 | Foo :: struct { 20 | a: i32, 21 | b: string, 22 | c: ^Bar, 23 | }; 24 | 25 | Bar :: struct { 26 | x: bool, 27 | y: Vector3, 28 | }; 29 | 30 | Foo2 :: distinct Foo; 31 | 32 | main :: () { 33 | old_array := [] i32 { 1, 2, 3 }; 34 | new_array := i32.[1, 2, 3]; 35 | 36 | str := "Wowza!"; 37 | 38 | array[0] = 2000; 39 | 40 | if array[1] == a * {a - 10} { 41 | printf("bleh", 1, 2, true); 42 | } else { 43 | panic("WHAT'S WRONG WITH YOU!"); 44 | } 45 | 46 | num := 5; 47 | ptr := ^num; 48 | 49 | ptr^ = 42; 50 | 51 | if !(array[0] as bool) { 52 | // wow look at this comment! 53 | 54 | ptr^ = (^array)^[2] * ptr^ * a; 55 | 56 | // so fancy! 57 | } 58 | 59 | idx := 5; 60 | while idx < 3 * math.factorial(200) { 61 | libc.puts("Hi!"); 62 | } 63 | 64 | loop { 65 | 18446744073709551615; 66 | 67 | 1.7976931348623157E+308; 68 | } 69 | 70 | ptr := ^str; 71 | str^ = "Hello, Sailor!"; 72 | 73 | Person :: struct { 74 | name: string, 75 | age: i32, 76 | }; 77 | 78 | old_gandalf := Person { 79 | name: "Gandalf", 80 | age: 2000, 81 | }; 82 | 83 | new_gandalf := Person.{ 84 | name = "Gandalf", 85 | age = 2000, 86 | }; 87 | 88 | gandalf.age = gandalf.age + 1; 89 | } 90 | 91 | printf :: (fmt: string, n1: i32, n2: i64, cond: bool) -> void extern; 92 | 93 | Vector3 :: distinct [3] i32; 94 | -------------------------------------------------------------------------------- /fuzz/fuzz_targets/main.rs: -------------------------------------------------------------------------------- 1 | #![no_main] 2 | 3 | extern crate ast; 4 | extern crate codegen; 5 | extern crate hir_ty; 6 | extern crate libfuzzer_sys; 7 | extern crate rustc_hash; 8 | extern crate target_lexicon; 9 | 10 | use std::path::Path; 11 | 12 | use ast::AstNode; 13 | use codegen::Verbosity; 14 | use hir_ty::{InferenceCtx, InferenceResult}; 15 | use libfuzzer_sys::fuzz_target; 16 | use rustc_hash::FxHashMap; 17 | use target_lexicon::Triple; 18 | 19 | fuzz_target!(|s: &str| { 20 | let mut interner = interner::Interner::default(); 21 | let mut world_index = hir::WorldIndex::default(); 22 | 23 | let mut uid_gen = uid_gen::UIDGenerator::default(); 24 | let mut world_bodies = hir::WorldBodies::default(); 25 | 26 | // `s` is the source code being tested 27 | let tokens = &lexer::lex(s); 28 | let parse = parser::parse_source_file(tokens, s); 29 | 30 | let tree = parse.syntax_tree(); 31 | let root = ast::Root::cast(tree.root(), tree).unwrap(); 32 | let _diagnostics = ast::validation::validate(root, tree); 33 | 34 | let (index, _indexing_diagnostics) = hir::index(root, tree, &mut interner); 35 | 36 | let (bodies, _lowering_diagnostics) = hir::lower( 37 | root, 38 | tree, 39 | Path::new("main.capy"), 40 | &index, 41 | &mut uid_gen, 42 | &mut interner, 43 | Path::new(""), 44 | true, 45 | ); 46 | 47 | let file = hir::FileName(interner.intern("main.capy")); 48 | 49 | world_index.add_file(file, index); 50 | world_bodies.add_file(file, bodies); 51 | 52 | let mut comptime_results = FxHashMap::default(); 53 | 54 | // type checking 55 | let InferenceResult { 56 | tys: _tys, 57 | diagnostics: _type_diagnostics, 58 | any_were_unsafe_to_compile: _any_unsafe, 59 | } = InferenceCtx::new(&world_index, &world_bodies, &interner, |comptime, tys| { 60 | // sometimes comptime need to be evaluated in order to figure out the types. 61 | // if we wanted to evaluate comptime blocks we could do: 62 | 63 | // codegen::eval_comptime_blocks( 64 | // Verbosity::LocalFunctions, 65 | // vec![comptime], 66 | // &mut comptime_results, 67 | // Path::new(""), 68 | // &interner, 69 | // &world_bodies, 70 | // tys, 71 | // Triple::host().pointer_width().unwrap().bits(), 72 | // ); 73 | // 74 | // comptime_results[&comptime].clone() 75 | 76 | // but we're not gonna do that, because I think running randomly generated code on 77 | // your computer is a bad idea 78 | 79 | todo!("figure something out for this") 80 | }) 81 | .finish(None, true); 82 | 83 | // frontend finally finished! 84 | // presumably you would use `codegen::compile_obj` now 85 | }); 86 | -------------------------------------------------------------------------------- /resources/capybara.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/capy-language/capy/a6e16222328ab6fe8da11c52bb81d8cf3e098a96/resources/capybara.png -------------------------------------------------------------------------------- /tokenizer.txt: -------------------------------------------------------------------------------- 1 | // This is a DSL I quickly put together to make it easier to 2 | // make new tokens or alter existing tokens 3 | Whitespace = /[ \t\r\n]+/ |=> 'whitespace' 4 | // Ideally this would be a literal instead of a regex 5 | NonBreakingSpace = /\xa0/ |=> 'non-breaking space character' 6 | As = 'as' 7 | If = 'if' 8 | Else = 'else' 9 | While = 'while' 10 | Loop = 'loop' 11 | Switch = 'switch' 12 | In = 'in' 13 | Distinct = 'distinct' 14 | Mut = 'mut' 15 | Extern = 'extern' 16 | Struct = 'struct' 17 | Enum = 'enum' 18 | Comptime = 'comptime' 19 | Return = 'return' 20 | Break = 'break' 21 | Continue = 'continue' 22 | Defer = 'defer' 23 | Ident = /[A-Za-z_][A-Za-z0-9_]*/ |=> 'identifier' 24 | // these basically match numbers that can contain `_`, 25 | // but must contain a digit as the first char 26 | Float = /(\d[\d_]*)?\.(\d[\d_]*)+([eE][-+]?(\d[\d_]*)+)?/ |=> 'float' 27 | Int = /(\d[\d_]*)+([eE](\d[\d_]*)+)?/ |=> 'integer' 28 | Hex = /0x[0-9a-fA-F]+/ |=> 'hex literal' 29 | Bin = /0b[01]+/ |=> 'binary literal' 30 | Bool = /true|false/ |=> 'boolean' 31 | _SingleQuote |=> '`'`' 32 | _DoubleQuote |=> '`"`' 33 | _Escape |=> 'escape sequence' 34 | _StringContents |=> 'string' 35 | Plus = '+' 36 | Hyphen = '-' 37 | Asterisk = '*' 38 | Slash = '/' 39 | Percent = '%' 40 | Left = '<' 41 | DoubleLeft = '<<' 42 | LeftEquals = '<=' 43 | Right = '>' 44 | DoubleRight = '>>' 45 | RightEquals = '>=' 46 | Bang = '!' 47 | BangEquals = '!=' 48 | And = '&' 49 | DoubleAnd = '&&' 50 | Pipe = '|' 51 | DoublePipe = '||' 52 | Equals = '=' 53 | DoubleEquals = '==' 54 | Tilde = '~' 55 | Comma = ',' 56 | Dot = '.' 57 | Ellipsis = '...' 58 | Arrow = '->' 59 | FatArrow = '=>' 60 | Caret = '^' 61 | Backtick = '`' 62 | LParen = '(' 63 | RParen = ')' 64 | LBrack = '[' 65 | RBrack = ']' 66 | LBrace = '{' 67 | RBrace = '}' 68 | _CommentLeader |=> 'comment' 69 | _CommentContents |=> 'comment' 70 | Colon = ':' 71 | Semicolon = ';' 72 | Hash = '#' 73 | Error |=> 'an unrecognized token' 74 | // The string/char doesn't have to end on a quote, this results in better error messages 75 | // this will internally get replaced by _SingleQuote, _Escape, and _StringContents 76 | __InternalString = /"([^"\\\n]|\\.)*"?/ 77 | // this will internally get replaced by _DoubleQuote, _Escape, and _StringContents 78 | __InternalChar = /'([^'\\\n]|\\.)*'?/ 79 | // this will internally get replaced by _CommentLeader and _CommentContents 80 | __InternalComment = ///.*/ 81 | --------------------------------------------------------------------------------