From 4c8997a64e453f5bb018459258e8658cd93a6bf8 Mon Sep 17 00:00:00 2001 From: Edgar Luque Date: Wed, 8 Jan 2025 10:46:44 +0100 Subject: [PATCH 01/18] Reorder project and add book --- .github/workflows/book.yml | 29 ++++++++ Cargo.toml | 41 ++++++++++-- Makefile | 12 ++-- README.md | 20 +++--- crates/concrete/build.rs => build.rs | 0 crates/concrete/Cargo.toml | 36 ---------- crates/concrete/tests/examples.rs | 66 ------------------- docs/book/.gitignore | 1 + docs/book/book.toml | 6 ++ docs/book/src/SUMMARY.md | 7 ++ docs/book/src/getting_started.md | 6 ++ docs/book/src/installation.md | 10 +++ docs/book/src/internal/index.md | 3 + docs/book/src/internal/ir.md | 59 +++++++++++++++++ docs/book/src/intro.md | 5 ++ {crates/concrete/src => src}/ast/common.rs | 0 {crates/concrete/src => src}/ast/constants.rs | 0 {crates/concrete/src => src}/ast/enums.rs | 0 .../concrete/src => src}/ast/expressions.rs | 0 {crates/concrete/src => src}/ast/functions.rs | 0 {crates/concrete/src => src}/ast/imports.rs | 0 {crates/concrete/src => src}/ast/mod.rs | 0 {crates/concrete/src => src}/ast/modules.rs | 0 .../concrete/src => src}/ast/statements.rs | 0 {crates/concrete/src => src}/ast/structs.rs | 0 {crates/concrete/src => src}/ast/types.rs | 0 .../src => src}/check/linearity_check.rs | 0 .../check/linearity_check/errors.rs | 0 {crates/concrete/src => src}/check/mod.rs | 0 .../concrete/src => src}/codegen/compiler.rs | 0 .../concrete/src => src}/codegen/context.rs | 0 .../concrete/src => src}/codegen/errors.rs | 0 {crates/concrete/src => src}/codegen/mod.rs | 0 .../concrete/src => src}/codegen/module.rs | 0 .../src => src}/codegen/pass_manager.rs | 0 {crates/concrete/src => src}/driver/config.rs | 0 {crates/concrete/src => src}/driver/db.rs | 0 {crates/concrete/src => src}/driver/linker.rs | 0 {crates/concrete/src => src}/driver/mod.rs | 0 {crates/concrete/src => src}/grammar.lalrpop | 0 {crates/concrete/src => src}/ir/lowering.rs | 0 .../src => src}/ir/lowering/common.rs | 0 .../src => src}/ir/lowering/errors.rs | 0 .../src => src}/ir/lowering/prepass.rs | 0 {crates/concrete/src => src}/ir/mod.rs | 0 {crates/concrete/src => src}/lib.rs | 0 {crates/concrete/src => src}/main.rs | 0 {crates/concrete/src => src}/parser/error.rs | 0 {crates/concrete/src => src}/parser/lexer.rs | 0 {crates/concrete/src => src}/parser/mod.rs | 0 {crates/concrete/src => src}/parser/tokens.rs | 0 {crates/concrete/src => src}/session/mod.rs | 0 tests/.gitkeep | 1 - {crates/concrete/tests => tests}/checks.rs | 0 {crates/concrete/tests => tests}/common.rs | 0 tests/examples.rs | 66 +++++++++++++++++++ .../call_param_count_mismatch.con | 0 .../call_param_type_mismatch.con | 0 .../invalid_programs/immutable_mutation.con | 0 .../invalid_programs/import1.con | 0 .../invalid_programs/import2.con | 0 .../invalid_programs/invalid_assign.con | 0 .../invalid_programs/invalid_borrow_mut.con | 0 .../mutable_nonmut_borrow.con | 0 .../tests => tests}/invalid_programs/type.con | 0 .../invalid_programs/undeclared_var.con | 0 {crates/concrete/tests => tests}/programs.rs | 0 67 files changed, 247 insertions(+), 121 deletions(-) create mode 100644 .github/workflows/book.yml rename crates/concrete/build.rs => build.rs (100%) delete mode 100644 crates/concrete/Cargo.toml delete mode 100644 crates/concrete/tests/examples.rs create mode 100644 docs/book/.gitignore create mode 100644 docs/book/book.toml create mode 100644 docs/book/src/SUMMARY.md create mode 100644 docs/book/src/getting_started.md create mode 100644 docs/book/src/installation.md create mode 100644 docs/book/src/internal/index.md create mode 100644 docs/book/src/internal/ir.md create mode 100644 docs/book/src/intro.md rename {crates/concrete/src => src}/ast/common.rs (100%) rename {crates/concrete/src => src}/ast/constants.rs (100%) rename {crates/concrete/src => src}/ast/enums.rs (100%) rename {crates/concrete/src => src}/ast/expressions.rs (100%) rename {crates/concrete/src => src}/ast/functions.rs (100%) rename {crates/concrete/src => src}/ast/imports.rs (100%) rename {crates/concrete/src => src}/ast/mod.rs (100%) rename {crates/concrete/src => src}/ast/modules.rs (100%) rename {crates/concrete/src => src}/ast/statements.rs (100%) rename {crates/concrete/src => src}/ast/structs.rs (100%) rename {crates/concrete/src => src}/ast/types.rs (100%) rename {crates/concrete/src => src}/check/linearity_check.rs (100%) rename {crates/concrete/src => src}/check/linearity_check/errors.rs (100%) rename {crates/concrete/src => src}/check/mod.rs (100%) rename {crates/concrete/src => src}/codegen/compiler.rs (100%) rename {crates/concrete/src => src}/codegen/context.rs (100%) rename {crates/concrete/src => src}/codegen/errors.rs (100%) rename {crates/concrete/src => src}/codegen/mod.rs (100%) rename {crates/concrete/src => src}/codegen/module.rs (100%) rename {crates/concrete/src => src}/codegen/pass_manager.rs (100%) rename {crates/concrete/src => src}/driver/config.rs (100%) rename {crates/concrete/src => src}/driver/db.rs (100%) rename {crates/concrete/src => src}/driver/linker.rs (100%) rename {crates/concrete/src => src}/driver/mod.rs (100%) rename {crates/concrete/src => src}/grammar.lalrpop (100%) rename {crates/concrete/src => src}/ir/lowering.rs (100%) rename {crates/concrete/src => src}/ir/lowering/common.rs (100%) rename {crates/concrete/src => src}/ir/lowering/errors.rs (100%) rename {crates/concrete/src => src}/ir/lowering/prepass.rs (100%) rename {crates/concrete/src => src}/ir/mod.rs (100%) rename {crates/concrete/src => src}/lib.rs (100%) rename {crates/concrete/src => src}/main.rs (100%) rename {crates/concrete/src => src}/parser/error.rs (100%) rename {crates/concrete/src => src}/parser/lexer.rs (100%) rename {crates/concrete/src => src}/parser/mod.rs (100%) rename {crates/concrete/src => src}/parser/tokens.rs (100%) rename {crates/concrete/src => src}/session/mod.rs (100%) delete mode 100644 tests/.gitkeep rename {crates/concrete/tests => tests}/checks.rs (100%) rename {crates/concrete/tests => tests}/common.rs (100%) create mode 100644 tests/examples.rs rename {crates/concrete/tests => tests}/invalid_programs/call_param_count_mismatch.con (100%) rename {crates/concrete/tests => tests}/invalid_programs/call_param_type_mismatch.con (100%) rename {crates/concrete/tests => tests}/invalid_programs/immutable_mutation.con (100%) rename {crates/concrete/tests => tests}/invalid_programs/import1.con (100%) rename {crates/concrete/tests => tests}/invalid_programs/import2.con (100%) rename {crates/concrete/tests => tests}/invalid_programs/invalid_assign.con (100%) rename {crates/concrete/tests => tests}/invalid_programs/invalid_borrow_mut.con (100%) rename {crates/concrete/tests => tests}/invalid_programs/mutable_nonmut_borrow.con (100%) rename {crates/concrete/tests => tests}/invalid_programs/type.con (100%) rename {crates/concrete/tests => tests}/invalid_programs/undeclared_var.con (100%) rename {crates/concrete/tests => tests}/programs.rs (100%) diff --git a/.github/workflows/book.yml b/.github/workflows/book.yml new file mode 100644 index 00000000..2fd58865 --- /dev/null +++ b/.github/workflows/book.yml @@ -0,0 +1,29 @@ +name: book + +on: + push: + branches: + - main + pull_request: + +jobs: + deploy: + runs-on: ubuntu-latest + concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + steps: + - uses: actions/checkout@v2 + + - name: Setup mdBook + uses: peaceiris/actions-mdbook@v2 + with: + mdbook-version: 'latest' + + - run: cd ./docs/book && mdbook build + + - name: Deploy + uses: peaceiris/actions-gh-pages@v3 + if: ${{ github.ref == 'refs/heads/main' }} + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./docs/book/book diff --git a/Cargo.toml b/Cargo.toml index de0c4d42..49da4e15 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,9 +1,40 @@ -[workspace] -resolver = "2" +[package] +name = "concrete" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +tracing = "0.1.41" +itertools = "0.13.0" +thiserror = "2.0.6" +educe = "0.5.11" +lalrpop-util = { version = "0.22.0", features = ["unicode"] } +logos = "0.15.0" +salsa = { git = "https://github.com/salsa-rs/salsa.git", rev = "c2a6d6238efa5f4642e8f0d2b5097f06b5f46dd0"} +ariadne = { version = "0.5.0", features = ["auto-color"] } +unescaper = "0.1.5" +logos-display = "0.1.3" + +melior = { version = "0.20.0", features = ["ods-dialects", "helpers"] } +llvm-sys = "191.0.0" +mlir-sys = "0.4.1" +anyhow = "1.0.94" +git2 = "0.19.0" +owo-colors = "4.1.0" +clap = { version = "4.5.23", features = ["derive"] } +tracing-subscriber = { version = "0.3.19", features = ["env-filter"] } +serde = { version = "1.0.216", features = ["derive"] } +toml = "0.8.19" +test-case = "3.3.1" + +[build-dependencies] +lalrpop = "0.22.0" + +[dev-dependencies] +tempfile = "3.14.0" -members = [ - "crates/concrete", -] [profile.release] lto = true diff --git a/Makefile b/Makefile index 4ee6e02d..acc420c3 100644 --- a/Makefile +++ b/Makefile @@ -26,12 +26,12 @@ endif .PHONY: build build: check-deps - cargo build --workspace --release --all-features + cargo build --release --all-features .PHONY: check check: check-deps cargo fmt --all -- --check - cargo clippy --workspace --all-targets --all-features -- -D warnings + cargo clippy --all-targets --all-features -- -D warnings .PHONY: clean clean: @@ -39,12 +39,16 @@ clean: .PHONY: test test: check-deps - cargo test --workspace --all-targets --all-features + cargo test --all-targets --all-features .PHONY: coverage coverage: check-deps - cargo llvm-cov --verbose --all-features --all-targets --workspace --lcov --output-path lcov.info + cargo llvm-cov --verbose --all-features --all-targets --lcov --output-path lcov.info .PHONY: bench bench: check-deps ./bench/bench.sh + +.PHONY: book +book: + cd ./docs/book && mdbook serve --open diff --git a/README.md b/README.md index 990a19ee..1bcd5489 100644 --- a/README.md +++ b/README.md @@ -229,7 +229,7 @@ Meaning: - :x: = work not started yet - 🤔 = to be defined -Features: +Builtin Features: - if/else ✔️ - while ✔️ - modules ✔️ @@ -238,21 +238,23 @@ Features: - borrowing ✔️ - structs ✔️ - casts ✔️ -- arrays 🏗️ -- iterators :x: - for 🏗️ -- match :x: -- option :x: -- enums :x: -- impl :x: +- ffi 🏗️ - linear type checker 🏗️ +- impl block 🏗️ +- generics 🏗️ +- enums :x: +- match :x: - borrow checker :x: -- generics :x: - traits :x: - unsafe :x: + +Standard lib features: +- arrays 🏗️ +- iterators :x: +- option :x: - box :x: - rc (for cyclical data structures like graphs) :x: -- ffi :x: - operating system threads with move only semantics :x: - rayon-like :x: diff --git a/crates/concrete/build.rs b/build.rs similarity index 100% rename from crates/concrete/build.rs rename to build.rs diff --git a/crates/concrete/Cargo.toml b/crates/concrete/Cargo.toml deleted file mode 100644 index 9dc8956e..00000000 --- a/crates/concrete/Cargo.toml +++ /dev/null @@ -1,36 +0,0 @@ -[package] -name = "concrete" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -tracing = "0.1.41" -itertools = "0.13.0" -thiserror = "2.0.6" -educe = "0.5.11" -lalrpop-util = { version = "0.22.0", features = ["unicode"] } -logos = "0.15.0" -salsa = { git = "https://github.com/salsa-rs/salsa.git", rev = "c2a6d6238efa5f4642e8f0d2b5097f06b5f46dd0"} -ariadne = { version = "0.5.0", features = ["auto-color"] } -unescaper = "0.1.5" -logos-display = "0.1.3" - -melior = { version = "0.20.0", features = ["ods-dialects", "helpers"] } -llvm-sys = "191.0.0" -mlir-sys = "0.4.1" -anyhow = "1.0.94" -git2 = "0.19.0" -owo-colors = "4.1.0" -clap = { version = "4.5.23", features = ["derive"] } -tracing-subscriber = { version = "0.3.19", features = ["env-filter"] } -serde = { version = "1.0.216", features = ["derive"] } -toml = "0.8.19" -test-case = "3.3.1" - -[build-dependencies] -lalrpop = "0.22.0" - -[dev-dependencies] -tempfile = "3.14.0" diff --git a/crates/concrete/tests/examples.rs b/crates/concrete/tests/examples.rs deleted file mode 100644 index 477b7d2f..00000000 --- a/crates/concrete/tests/examples.rs +++ /dev/null @@ -1,66 +0,0 @@ -use crate::common::{compile_and_run, compile_and_run_output}; -use concrete::session::OptLevel; -use test_case::test_case; - -mod common; - -#[test_case(include_str!("../../../examples/borrow.con"), "borrow", false, 2 ; "borrow.con")] -#[test_case(include_str!("../../../examples/factorial_if.con"), "factorial_if", false, 24 ; "factorial_if.con")] -#[test_case(include_str!("../../../examples/fib_if.con"), "fib_if", false, 55 ; "fib_if.con")] -#[test_case(include_str!("../../../examples/import.con"), "import", false, 12 ; "import.con")] -#[test_case(include_str!("../../../examples/simple.con"), "simple", false, 8 ; "simple.con")] -#[test_case(include_str!("../../../examples/while.con"), "while", false, 16 ; "while.con")] -#[test_case(include_str!("../../../examples/chars.con"), "chars", false, 117 ; "chars.con")] -#[test_case(include_str!("../../../examples/floats.con"), "floats", false, 1 ; "floats.con")] -#[test_case(include_str!("../../../examples/refs.con"), "refs", false, 6 ; "refs.con")] -#[test_case(include_str!("../../../examples/structs.con"), "structs", false, 8 ; "structs.con")] -#[test_case(include_str!("../../../examples/casts.con"), "casts", false, 2 ; "casts.con")] -#[test_case(include_str!("../../../examples/malloc.con"), "malloc", false, 5 ; "malloc.con")] -#[test_case(include_str!("../../../examples/while_if_false.con"), "while_if_false", false, 7 ; "while_if_false.con")] -#[test_case(include_str!("../../../examples/if_if_false.con"), "if_if_false", false, 7 ; "if_if_false.con")] -#[test_case(include_str!("../../../examples/for.con"), "for", false, 10 ; "for.con")] -#[test_case(include_str!("../../../examples/for_while.con"), "for_while", false, 10 ; "for_while.con")] -#[test_case(include_str!("../../../examples/arrays.con"), "arrays", false, 5 ; "arrays.con")] -#[test_case(include_str!("../../../examples/constants.con"), "constants", false, 20 ; "constants.con")] -#[test_case(include_str!("../../../examples/linearExample01.con"), "linearity", false, 2 ; "linearExample01.con")] -#[test_case(include_str!("../../../examples/linearExample02.con"), "linearity", false, 2 ; "linearExample02.con")] -#[test_case(include_str!("../../../examples/linearExample03if.con"), "linearity", false, 0 ; "linearExample03if.con")] -fn example_tests(source: &str, name: &str, is_library: bool, status_code: i32) { - assert_eq!( - status_code, - compile_and_run(source, name, is_library, OptLevel::None) - ); - assert_eq!( - status_code, - compile_and_run(source, name, is_library, OptLevel::Less) - ); - assert_eq!( - status_code, - compile_and_run(source, name, is_library, OptLevel::Default) - ); - assert_eq!( - status_code, - compile_and_run(source, name, is_library, OptLevel::Aggressive) - ); -} - -#[test_case(include_str!("../../../examples/hello_world_hacky.con"), "hello_world_hacky", false, "Hello World\n" ; "hello_world_hacky.con")] -#[test_case(include_str!("../../../examples/hello_world_array.con"), "hello_world_array", false, "hello world!\n" ; "hello_world_array.con")] -fn example_tests_with_output(source: &str, name: &str, is_library: bool, result: &str) { - assert_eq!( - result, - compile_and_run_output(source, name, is_library, OptLevel::None) - ); - assert_eq!( - result, - compile_and_run_output(source, name, is_library, OptLevel::Less) - ); - assert_eq!( - result, - compile_and_run_output(source, name, is_library, OptLevel::Default) - ); - assert_eq!( - result, - compile_and_run_output(source, name, is_library, OptLevel::Aggressive) - ); -} diff --git a/docs/book/.gitignore b/docs/book/.gitignore new file mode 100644 index 00000000..7585238e --- /dev/null +++ b/docs/book/.gitignore @@ -0,0 +1 @@ +book diff --git a/docs/book/book.toml b/docs/book/book.toml new file mode 100644 index 00000000..68b82226 --- /dev/null +++ b/docs/book/book.toml @@ -0,0 +1,6 @@ +[book] +authors = ["Lambda Class"] +language = "en" +multilingual = false +src = "src" +title = "The Concrete Programming Language" diff --git a/docs/book/src/SUMMARY.md b/docs/book/src/SUMMARY.md new file mode 100644 index 00000000..3151f421 --- /dev/null +++ b/docs/book/src/SUMMARY.md @@ -0,0 +1,7 @@ +# Summary + +- [The Concrete Programming Language](./intro.md) +- [Getting Started](./getting_started.md) + - [Installation](./installation.md) +- [Internal Details](./internal/index.md) + - [The IR](./internal/ir.md) diff --git a/docs/book/src/getting_started.md b/docs/book/src/getting_started.md new file mode 100644 index 00000000..7f614919 --- /dev/null +++ b/docs/book/src/getting_started.md @@ -0,0 +1,6 @@ +# Getting Started + +Here we will discuss: +- Installing Concrete on Linux, macOS. +- Writing a simple program. +- Using concrete to create a project. diff --git a/docs/book/src/installation.md b/docs/book/src/installation.md new file mode 100644 index 00000000..5f079cce --- /dev/null +++ b/docs/book/src/installation.md @@ -0,0 +1,10 @@ +# Installation + +Currently Concrete is distrubted via source only, so you will have to compile it: + +```bash +git clone https://github.com/lambdaclass/concrete.git +cd concrete +make build +cp ./target/release/concrete /usr/local/bin/ +``` diff --git a/docs/book/src/internal/index.md b/docs/book/src/internal/index.md new file mode 100644 index 00000000..2af62f55 --- /dev/null +++ b/docs/book/src/internal/index.md @@ -0,0 +1,3 @@ +# Internal Details + +Here you can find several internal and implementation details of how Concrete is made. diff --git a/docs/book/src/internal/ir.md b/docs/book/src/internal/ir.md new file mode 100644 index 00000000..de6a37fa --- /dev/null +++ b/docs/book/src/internal/ir.md @@ -0,0 +1,59 @@ +# The Concrete IR + +Currently in Concrete, the AST is lowered first to a IR to help support multiple targets and ease the generation of code on the end of the compilation process. + +This IR is based on the concept of basic blocks, where within each block there is a linear flow (i.e) there is no branching. + +Each block has a terminator, which for example can return or jump to another block, this is what defines the control flow of the program. + + +## The ProgramBody + +The `ProgramBody` holds the whole program, with all the modules defined within. + +All modules, functions, constants, struct types, types, etc have a defined `DefId`. + +The `ProgramBody` stores all of these in a flat structure, i.e, functions defined in a submodule are available for lookup directly by their id. + +## The ModuleBody + +Defines a module in concrete. + +This structure holds the ids of the functions, structs, modules, etc defined within this module. This allows to resolve imports. + +It also has a symbol table and a import table to aid during the construction of the IR. + +## The FnBody + +Defines a function in concrete. + +It holds the basic blocks and the locals used within. + +## The BasicBlock + +It holds a array of statements and a terminator. + +The statements have no branching. + +The terminator defines where to branch, return from a function, a switch, etc. + +## The Statement + +Currently there are 3 kinds of statements: assign, storage live, storage dead. + +Only assign is used currently: it contains a place and a rvalue. + +## Place + +This defines a place in memory, where you can load or store. + +## RValue + +A value found in the right hand side of an assignment, for example the use of an operand or a binary operation with 2 operands, a reference to a place, etc. + +## Operand + +A operand is a value, either from a place in memory or constant data. + +## Local +A local is a local variable within a function body, it is defined by a place and the type of local, such as temporary, argument or a return pointer. diff --git a/docs/book/src/intro.md b/docs/book/src/intro.md new file mode 100644 index 00000000..e14c538e --- /dev/null +++ b/docs/book/src/intro.md @@ -0,0 +1,5 @@ +# The Concrete Programming Language + +This book is a work in progress, much like the language itself, proceed with caution. + +Some stuff may be outdated. diff --git a/crates/concrete/src/ast/common.rs b/src/ast/common.rs similarity index 100% rename from crates/concrete/src/ast/common.rs rename to src/ast/common.rs diff --git a/crates/concrete/src/ast/constants.rs b/src/ast/constants.rs similarity index 100% rename from crates/concrete/src/ast/constants.rs rename to src/ast/constants.rs diff --git a/crates/concrete/src/ast/enums.rs b/src/ast/enums.rs similarity index 100% rename from crates/concrete/src/ast/enums.rs rename to src/ast/enums.rs diff --git a/crates/concrete/src/ast/expressions.rs b/src/ast/expressions.rs similarity index 100% rename from crates/concrete/src/ast/expressions.rs rename to src/ast/expressions.rs diff --git a/crates/concrete/src/ast/functions.rs b/src/ast/functions.rs similarity index 100% rename from crates/concrete/src/ast/functions.rs rename to src/ast/functions.rs diff --git a/crates/concrete/src/ast/imports.rs b/src/ast/imports.rs similarity index 100% rename from crates/concrete/src/ast/imports.rs rename to src/ast/imports.rs diff --git a/crates/concrete/src/ast/mod.rs b/src/ast/mod.rs similarity index 100% rename from crates/concrete/src/ast/mod.rs rename to src/ast/mod.rs diff --git a/crates/concrete/src/ast/modules.rs b/src/ast/modules.rs similarity index 100% rename from crates/concrete/src/ast/modules.rs rename to src/ast/modules.rs diff --git a/crates/concrete/src/ast/statements.rs b/src/ast/statements.rs similarity index 100% rename from crates/concrete/src/ast/statements.rs rename to src/ast/statements.rs diff --git a/crates/concrete/src/ast/structs.rs b/src/ast/structs.rs similarity index 100% rename from crates/concrete/src/ast/structs.rs rename to src/ast/structs.rs diff --git a/crates/concrete/src/ast/types.rs b/src/ast/types.rs similarity index 100% rename from crates/concrete/src/ast/types.rs rename to src/ast/types.rs diff --git a/crates/concrete/src/check/linearity_check.rs b/src/check/linearity_check.rs similarity index 100% rename from crates/concrete/src/check/linearity_check.rs rename to src/check/linearity_check.rs diff --git a/crates/concrete/src/check/linearity_check/errors.rs b/src/check/linearity_check/errors.rs similarity index 100% rename from crates/concrete/src/check/linearity_check/errors.rs rename to src/check/linearity_check/errors.rs diff --git a/crates/concrete/src/check/mod.rs b/src/check/mod.rs similarity index 100% rename from crates/concrete/src/check/mod.rs rename to src/check/mod.rs diff --git a/crates/concrete/src/codegen/compiler.rs b/src/codegen/compiler.rs similarity index 100% rename from crates/concrete/src/codegen/compiler.rs rename to src/codegen/compiler.rs diff --git a/crates/concrete/src/codegen/context.rs b/src/codegen/context.rs similarity index 100% rename from crates/concrete/src/codegen/context.rs rename to src/codegen/context.rs diff --git a/crates/concrete/src/codegen/errors.rs b/src/codegen/errors.rs similarity index 100% rename from crates/concrete/src/codegen/errors.rs rename to src/codegen/errors.rs diff --git a/crates/concrete/src/codegen/mod.rs b/src/codegen/mod.rs similarity index 100% rename from crates/concrete/src/codegen/mod.rs rename to src/codegen/mod.rs diff --git a/crates/concrete/src/codegen/module.rs b/src/codegen/module.rs similarity index 100% rename from crates/concrete/src/codegen/module.rs rename to src/codegen/module.rs diff --git a/crates/concrete/src/codegen/pass_manager.rs b/src/codegen/pass_manager.rs similarity index 100% rename from crates/concrete/src/codegen/pass_manager.rs rename to src/codegen/pass_manager.rs diff --git a/crates/concrete/src/driver/config.rs b/src/driver/config.rs similarity index 100% rename from crates/concrete/src/driver/config.rs rename to src/driver/config.rs diff --git a/crates/concrete/src/driver/db.rs b/src/driver/db.rs similarity index 100% rename from crates/concrete/src/driver/db.rs rename to src/driver/db.rs diff --git a/crates/concrete/src/driver/linker.rs b/src/driver/linker.rs similarity index 100% rename from crates/concrete/src/driver/linker.rs rename to src/driver/linker.rs diff --git a/crates/concrete/src/driver/mod.rs b/src/driver/mod.rs similarity index 100% rename from crates/concrete/src/driver/mod.rs rename to src/driver/mod.rs diff --git a/crates/concrete/src/grammar.lalrpop b/src/grammar.lalrpop similarity index 100% rename from crates/concrete/src/grammar.lalrpop rename to src/grammar.lalrpop diff --git a/crates/concrete/src/ir/lowering.rs b/src/ir/lowering.rs similarity index 100% rename from crates/concrete/src/ir/lowering.rs rename to src/ir/lowering.rs diff --git a/crates/concrete/src/ir/lowering/common.rs b/src/ir/lowering/common.rs similarity index 100% rename from crates/concrete/src/ir/lowering/common.rs rename to src/ir/lowering/common.rs diff --git a/crates/concrete/src/ir/lowering/errors.rs b/src/ir/lowering/errors.rs similarity index 100% rename from crates/concrete/src/ir/lowering/errors.rs rename to src/ir/lowering/errors.rs diff --git a/crates/concrete/src/ir/lowering/prepass.rs b/src/ir/lowering/prepass.rs similarity index 100% rename from crates/concrete/src/ir/lowering/prepass.rs rename to src/ir/lowering/prepass.rs diff --git a/crates/concrete/src/ir/mod.rs b/src/ir/mod.rs similarity index 100% rename from crates/concrete/src/ir/mod.rs rename to src/ir/mod.rs diff --git a/crates/concrete/src/lib.rs b/src/lib.rs similarity index 100% rename from crates/concrete/src/lib.rs rename to src/lib.rs diff --git a/crates/concrete/src/main.rs b/src/main.rs similarity index 100% rename from crates/concrete/src/main.rs rename to src/main.rs diff --git a/crates/concrete/src/parser/error.rs b/src/parser/error.rs similarity index 100% rename from crates/concrete/src/parser/error.rs rename to src/parser/error.rs diff --git a/crates/concrete/src/parser/lexer.rs b/src/parser/lexer.rs similarity index 100% rename from crates/concrete/src/parser/lexer.rs rename to src/parser/lexer.rs diff --git a/crates/concrete/src/parser/mod.rs b/src/parser/mod.rs similarity index 100% rename from crates/concrete/src/parser/mod.rs rename to src/parser/mod.rs diff --git a/crates/concrete/src/parser/tokens.rs b/src/parser/tokens.rs similarity index 100% rename from crates/concrete/src/parser/tokens.rs rename to src/parser/tokens.rs diff --git a/crates/concrete/src/session/mod.rs b/src/session/mod.rs similarity index 100% rename from crates/concrete/src/session/mod.rs rename to src/session/mod.rs diff --git a/tests/.gitkeep b/tests/.gitkeep deleted file mode 100644 index 8b137891..00000000 --- a/tests/.gitkeep +++ /dev/null @@ -1 +0,0 @@ - diff --git a/crates/concrete/tests/checks.rs b/tests/checks.rs similarity index 100% rename from crates/concrete/tests/checks.rs rename to tests/checks.rs diff --git a/crates/concrete/tests/common.rs b/tests/common.rs similarity index 100% rename from crates/concrete/tests/common.rs rename to tests/common.rs diff --git a/tests/examples.rs b/tests/examples.rs new file mode 100644 index 00000000..c3725291 --- /dev/null +++ b/tests/examples.rs @@ -0,0 +1,66 @@ +use crate::common::{compile_and_run, compile_and_run_output}; +use concrete::session::OptLevel; +use test_case::test_case; + +mod common; + +#[test_case(include_str!("../examples/borrow.con"), "borrow", false, 2 ; "borrow.con")] +#[test_case(include_str!("../examples/factorial_if.con"), "factorial_if", false, 24 ; "factorial_if.con")] +#[test_case(include_str!("../examples/fib_if.con"), "fib_if", false, 55 ; "fib_if.con")] +#[test_case(include_str!("../examples/import.con"), "import", false, 12 ; "import.con")] +#[test_case(include_str!("../examples/simple.con"), "simple", false, 8 ; "simple.con")] +#[test_case(include_str!("../examples/while.con"), "while", false, 16 ; "while.con")] +#[test_case(include_str!("../examples/chars.con"), "chars", false, 117 ; "chars.con")] +#[test_case(include_str!("../examples/floats.con"), "floats", false, 1 ; "floats.con")] +#[test_case(include_str!("../examples/refs.con"), "refs", false, 6 ; "refs.con")] +#[test_case(include_str!("../examples/structs.con"), "structs", false, 8 ; "structs.con")] +#[test_case(include_str!("../examples/casts.con"), "casts", false, 2 ; "casts.con")] +#[test_case(include_str!("../examples/malloc.con"), "malloc", false, 5 ; "malloc.con")] +#[test_case(include_str!("../examples/while_if_false.con"), "while_if_false", false, 7 ; "while_if_false.con")] +#[test_case(include_str!("../examples/if_if_false.con"), "if_if_false", false, 7 ; "if_if_false.con")] +#[test_case(include_str!("../examples/for.con"), "for", false, 10 ; "for.con")] +#[test_case(include_str!("../examples/for_while.con"), "for_while", false, 10 ; "for_while.con")] +#[test_case(include_str!("../examples/arrays.con"), "arrays", false, 5 ; "arrays.con")] +#[test_case(include_str!("../examples/constants.con"), "constants", false, 20 ; "constants.con")] +#[test_case(include_str!("../examples/linearExample01.con"), "linearity", false, 2 ; "linearExample01.con")] +#[test_case(include_str!("../examples/linearExample02.con"), "linearity", false, 2 ; "linearExample02.con")] +#[test_case(include_str!("../examples/linearExample03if.con"), "linearity", false, 0 ; "linearExample03if.con")] +fn example_tests(source: &str, name: &str, is_library: bool, status_code: i32) { + assert_eq!( + status_code, + compile_and_run(source, name, is_library, OptLevel::None) + ); + assert_eq!( + status_code, + compile_and_run(source, name, is_library, OptLevel::Less) + ); + assert_eq!( + status_code, + compile_and_run(source, name, is_library, OptLevel::Default) + ); + assert_eq!( + status_code, + compile_and_run(source, name, is_library, OptLevel::Aggressive) + ); +} + +#[test_case(include_str!("../examples/hello_world_hacky.con"), "hello_world_hacky", false, "Hello World\n" ; "hello_world_hacky.con")] +#[test_case(include_str!("../examples/hello_world_array.con"), "hello_world_array", false, "hello world!\n" ; "hello_world_array.con")] +fn example_tests_with_output(source: &str, name: &str, is_library: bool, result: &str) { + assert_eq!( + result, + compile_and_run_output(source, name, is_library, OptLevel::None) + ); + assert_eq!( + result, + compile_and_run_output(source, name, is_library, OptLevel::Less) + ); + assert_eq!( + result, + compile_and_run_output(source, name, is_library, OptLevel::Default) + ); + assert_eq!( + result, + compile_and_run_output(source, name, is_library, OptLevel::Aggressive) + ); +} diff --git a/crates/concrete/tests/invalid_programs/call_param_count_mismatch.con b/tests/invalid_programs/call_param_count_mismatch.con similarity index 100% rename from crates/concrete/tests/invalid_programs/call_param_count_mismatch.con rename to tests/invalid_programs/call_param_count_mismatch.con diff --git a/crates/concrete/tests/invalid_programs/call_param_type_mismatch.con b/tests/invalid_programs/call_param_type_mismatch.con similarity index 100% rename from crates/concrete/tests/invalid_programs/call_param_type_mismatch.con rename to tests/invalid_programs/call_param_type_mismatch.con diff --git a/crates/concrete/tests/invalid_programs/immutable_mutation.con b/tests/invalid_programs/immutable_mutation.con similarity index 100% rename from crates/concrete/tests/invalid_programs/immutable_mutation.con rename to tests/invalid_programs/immutable_mutation.con diff --git a/crates/concrete/tests/invalid_programs/import1.con b/tests/invalid_programs/import1.con similarity index 100% rename from crates/concrete/tests/invalid_programs/import1.con rename to tests/invalid_programs/import1.con diff --git a/crates/concrete/tests/invalid_programs/import2.con b/tests/invalid_programs/import2.con similarity index 100% rename from crates/concrete/tests/invalid_programs/import2.con rename to tests/invalid_programs/import2.con diff --git a/crates/concrete/tests/invalid_programs/invalid_assign.con b/tests/invalid_programs/invalid_assign.con similarity index 100% rename from crates/concrete/tests/invalid_programs/invalid_assign.con rename to tests/invalid_programs/invalid_assign.con diff --git a/crates/concrete/tests/invalid_programs/invalid_borrow_mut.con b/tests/invalid_programs/invalid_borrow_mut.con similarity index 100% rename from crates/concrete/tests/invalid_programs/invalid_borrow_mut.con rename to tests/invalid_programs/invalid_borrow_mut.con diff --git a/crates/concrete/tests/invalid_programs/mutable_nonmut_borrow.con b/tests/invalid_programs/mutable_nonmut_borrow.con similarity index 100% rename from crates/concrete/tests/invalid_programs/mutable_nonmut_borrow.con rename to tests/invalid_programs/mutable_nonmut_borrow.con diff --git a/crates/concrete/tests/invalid_programs/type.con b/tests/invalid_programs/type.con similarity index 100% rename from crates/concrete/tests/invalid_programs/type.con rename to tests/invalid_programs/type.con diff --git a/crates/concrete/tests/invalid_programs/undeclared_var.con b/tests/invalid_programs/undeclared_var.con similarity index 100% rename from crates/concrete/tests/invalid_programs/undeclared_var.con rename to tests/invalid_programs/undeclared_var.con diff --git a/crates/concrete/tests/programs.rs b/tests/programs.rs similarity index 100% rename from crates/concrete/tests/programs.rs rename to tests/programs.rs From 8d58462af29e6f6a277b82e8ef5784940b344c05 Mon Sep 17 00:00:00 2001 From: Edgar Luque Date: Wed, 8 Jan 2025 12:15:42 +0100 Subject: [PATCH 02/18] refactor lower type --- Cargo.lock | 89 ++++++++++++------- Cargo.toml | 16 ++-- src/ast/common.rs | 3 - src/ast/constants.rs | 4 +- src/ast/expressions.rs | 4 +- src/ast/functions.rs | 6 +- src/ast/statements.rs | 6 +- src/ast/structs.rs | 4 +- src/ast/types.rs | 47 ++++------ src/check/linearity_check.rs | 2 +- src/check/mod.rs | 2 +- src/driver/mod.rs | 2 + src/grammar.lalrpop | 61 ++++++------- src/ir/lowering.rs | 167 +++++++++++++++-------------------- src/ir/lowering/common.rs | 4 +- 15 files changed, 206 insertions(+), 211 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5b2121b4..3e6070fe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -74,9 +74,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.94" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1fd03a028ef38ba2276dce7e33fcd6369c158a1bca17946c4b1b701891c1ff7" +checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04" [[package]] name = "append-only-vec" @@ -281,9 +281,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.23" +version = "4.5.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3135e7ec2ef7b10c6ed8950f0f792ed96ee093fa088608f1c76e569722700c84" +checksum = "9560b07a799281c7e0958b9296854d6fafd4c5f31444a7e5bb1ad6dde5ccf1bd" dependencies = [ "clap_builder", "clap_derive", @@ -291,9 +291,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.23" +version = "4.5.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30582fc632330df2bd26877bde0c1f4470d57c582bbc070376afcd04d8cb4838" +checksum = "874e0dd3eb68bf99058751ac9712f622e61e6f393a94f7128fa26e3f02f5c7cd" dependencies = [ "anstream", "anstyle", @@ -303,9 +303,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.18" +version = "4.5.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" +checksum = "54b755194d6389280185988721fffba69495eed5ee9feeee9a599b53db80318c" dependencies = [ "heck", "proc-macro2", @@ -327,9 +327,9 @@ checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" [[package]] name = "comrak" -version = "0.31.0" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "453dcb42e33f7b474d7e0db12e0b8d82802c88f35cf5a1d8c297d0dfcecb154f" +checksum = "48ae8f3e7e3f3d424cbb33354fc36943d507327d210aa5794b0192f4be726c6d" dependencies = [ "bon", "caseless", @@ -371,7 +371,7 @@ dependencies = [ "clap", "educe", "git2", - "itertools 0.13.0", + "itertools 0.14.0", "lalrpop", "lalrpop-util", "llvm-sys", @@ -384,7 +384,7 @@ dependencies = [ "serde", "tempfile", "test-case", - "thiserror 2.0.6", + "thiserror 2.0.9", "toml", "tracing", "tracing-subscriber", @@ -657,11 +657,22 @@ dependencies = [ "version_check", ] +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + [[package]] name = "git2" -version = "0.19.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b903b73e45dc0c6c596f2d37eccece7c1c8bb6e4407b001096387c63d0d93724" +checksum = "3fda788993cc341f69012feba8bf45c0ba4f3291fcc08e214b4d5a7332d88aff" dependencies = [ "bitflags 2.6.0", "libc", @@ -913,6 +924,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +dependencies = [ + "either", +] + [[package]] name = "jobserver" version = "0.1.32" @@ -983,9 +1003,9 @@ checksum = "5aaeb2981e0606ca11d79718f8bb01164f1d6ed75080182d3abf017e6d244b6d" [[package]] name = "libgit2-sys" -version = "0.17.0+1.8.1" +version = "0.18.0+1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10472326a8a6477c3c20a64547b0059e4b0d086869eee31e6d7da728a8eb7224" +checksum = "e1a117465e7e1597e8febea8bb0c410f1c7fb93b1e1cddf34363f8390367ffec" dependencies = [ "cc", "libc", @@ -1129,9 +1149,9 @@ dependencies = [ [[package]] name = "melior" -version = "0.20.0" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ee1cff4225a41563d0517e274eea56d6e07d40004184dda898ef08f421c1546" +checksum = "1cfcb398e6571361b6f54fd0057066d9b47a822bcb797bf5867e5412e9e6f387" dependencies = [ "melior-macro", "mlir-sys", @@ -1139,9 +1159,9 @@ dependencies = [ [[package]] name = "melior-macro" -version = "0.13.0" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c74bfe1b3e796b3dec1b4a178d813398171658a0f55a3ccb963cc9212022d1" +checksum = "3086e8c12eb1999d636595cc3c2aee82a28d4bb80163267d51bd66a617cdaefc" dependencies = [ "comrak", "convert_case", @@ -1522,18 +1542,18 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.216" +version = "1.0.217" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e" +checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.216" +version = "1.0.217" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e" +checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" dependencies = [ "proc-macro2", "quote", @@ -1657,12 +1677,13 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.14.0" +version = "3.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c" +checksum = "9a8a559c81686f576e8cd0290cd2a24a2a9ad80c98b3478856500fcbd7acd704" dependencies = [ "cfg-if", "fastrand", + "getrandom", "once_cell", "rustix", "windows-sys 0.59.0", @@ -1722,11 +1743,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.6" +version = "2.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fec2a1820ebd077e2b90c4df007bebf344cd394098a13c563957d0afc83ea47" +checksum = "f072643fd0190df67a8bab670c20ef5d8737177d6ac6b2e9a236cb096206b2cc" dependencies = [ - "thiserror-impl 2.0.6", + "thiserror-impl 2.0.9", ] [[package]] @@ -1742,9 +1763,9 @@ dependencies = [ [[package]] name = "thiserror-impl" -version = "2.0.6" +version = "2.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d65750cab40f4ff1929fb1ba509e9914eb756131cef4210da8d5d700d26f6312" +checksum = "7b50fa271071aae2e6ee85f842e2e28ba8cd2c5fb67f11fcb1fd70b276f9e7d4" dependencies = [ "proc-macro2", "quote", @@ -2004,6 +2025,12 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + [[package]] name = "wasm-bindgen" version = "0.2.99" diff --git a/Cargo.toml b/Cargo.toml index 49da4e15..7eb0965a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,8 +7,8 @@ edition = "2021" [dependencies] tracing = "0.1.41" -itertools = "0.13.0" -thiserror = "2.0.6" +itertools = "0.14.0" +thiserror = "2.0.9" educe = "0.5.11" lalrpop-util = { version = "0.22.0", features = ["unicode"] } logos = "0.15.0" @@ -17,15 +17,15 @@ ariadne = { version = "0.5.0", features = ["auto-color"] } unescaper = "0.1.5" logos-display = "0.1.3" -melior = { version = "0.20.0", features = ["ods-dialects", "helpers"] } +melior = { version = "0.20.2", features = ["ods-dialects", "helpers"] } llvm-sys = "191.0.0" mlir-sys = "0.4.1" -anyhow = "1.0.94" -git2 = "0.19.0" +anyhow = "1.0.95" +git2 = "0.20.0" owo-colors = "4.1.0" -clap = { version = "4.5.23", features = ["derive"] } +clap = { version = "4.5.24", features = ["derive"] } tracing-subscriber = { version = "0.3.19", features = ["env-filter"] } -serde = { version = "1.0.216", features = ["derive"] } +serde = { version = "1.0.217", features = ["derive"] } toml = "0.8.19" test-case = "3.3.1" @@ -33,7 +33,7 @@ test-case = "3.3.1" lalrpop = "0.22.0" [dev-dependencies] -tempfile = "3.14.0" +tempfile = "3.15.0" [profile.release] diff --git a/src/ast/common.rs b/src/ast/common.rs index f07c542b..6f6278cb 100644 --- a/src/ast/common.rs +++ b/src/ast/common.rs @@ -1,7 +1,5 @@ use std::ops::Range; -use super::types::TypeSpec; - #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Span { pub from: usize, @@ -34,7 +32,6 @@ pub struct Ident { #[derive(Clone, Debug, Eq, Hash, PartialEq)] pub struct GenericParam { pub name: Ident, - pub params: Vec, pub span: Span, } diff --git a/src/ast/constants.rs b/src/ast/constants.rs index 09cf41b1..b2ff5bef 100644 --- a/src/ast/constants.rs +++ b/src/ast/constants.rs @@ -1,7 +1,7 @@ use super::{ common::{DocString, Ident}, expressions::Expression, - types::TypeSpec, + types::TypeDescriptor, }; #[derive(Clone, Debug, PartialEq, Eq)] @@ -9,7 +9,7 @@ pub struct ConstantDecl { pub doc_string: Option, pub name: Ident, pub is_pub: bool, - pub r#type: TypeSpec, + pub r#type: TypeDescriptor, } #[derive(Clone, Debug, PartialEq, Eq)] diff --git a/src/ast/expressions.rs b/src/ast/expressions.rs index 8b36a49a..6f603ba0 100644 --- a/src/ast/expressions.rs +++ b/src/ast/expressions.rs @@ -3,7 +3,7 @@ use std::collections::HashMap; use super::{ common::{Ident, Span}, statements::Statement, - types::TypeSpec, + types::TypeDescriptor, }; #[derive(Clone, Debug, Eq, PartialEq)] @@ -18,7 +18,7 @@ pub enum Expression { ArrayInit(ArrayInitExpr), Deref(Box, Span), AsRef(Box, bool, Span), - Cast(Box, TypeSpec, Span), + Cast(Box, TypeDescriptor, Span), } #[derive(Clone, Debug, Eq, PartialEq)] diff --git a/src/ast/functions.rs b/src/ast/functions.rs index cc147060..059eaeec 100644 --- a/src/ast/functions.rs +++ b/src/ast/functions.rs @@ -1,7 +1,7 @@ use super::{ common::{Attribute, DocString, GenericParam, Ident, Span}, statements::Statement, - types::TypeSpec, + types::TypeDescriptor, }; #[derive(Clone, Debug, Eq, PartialEq)] @@ -10,7 +10,7 @@ pub struct FunctionDecl { pub generic_params: Vec, pub name: Ident, pub params: Vec, - pub ret_type: Option, + pub ret_type: Option, pub is_extern: bool, pub is_pub: bool, pub attributes: Vec, @@ -27,5 +27,5 @@ pub struct FunctionDef { #[derive(Clone, Debug, Eq, Hash, PartialEq)] pub struct Param { pub name: Ident, - pub r#type: TypeSpec, + pub r#type: TypeDescriptor, } diff --git a/src/ast/statements.rs b/src/ast/statements.rs index bb4d6388..7bbb28ca 100644 --- a/src/ast/statements.rs +++ b/src/ast/statements.rs @@ -1,7 +1,7 @@ use super::{ common::{Ident, Span}, expressions::{Expression, FnCallOp, IfExpr, MatchExpr, PathOp}, - types::TypeSpec, + types::TypeDescriptor, }; #[derive(Clone, Debug, Eq, PartialEq)] @@ -18,7 +18,7 @@ pub enum Statement { #[derive(Clone, Debug, Eq, PartialEq)] pub enum LetStmtTarget { - Simple { id: Ident, r#type: TypeSpec }, + Simple { id: Ident, r#type: TypeDescriptor }, Destructure(Vec), } @@ -48,7 +48,7 @@ pub struct AssignStmt { pub struct Binding { pub id: Ident, pub rename: Option, - pub r#type: TypeSpec, + pub r#type: TypeDescriptor, } #[derive(Clone, Debug, Eq, PartialEq)] diff --git a/src/ast/structs.rs b/src/ast/structs.rs index fe61d365..6f69bfe5 100644 --- a/src/ast/structs.rs +++ b/src/ast/structs.rs @@ -1,6 +1,6 @@ use super::{ common::{GenericParam, Ident, Span}, - types::TypeSpec, + types::TypeDescriptor, }; #[derive(Clone, Debug, Eq, PartialEq)] @@ -14,6 +14,6 @@ pub struct StructDecl { #[derive(Clone, Debug, Eq, Hash, PartialEq)] pub struct Field { pub name: Ident, - pub r#type: TypeSpec, + pub r#type: TypeDescriptor, pub span: Span, } diff --git a/src/ast/types.rs b/src/ast/types.rs index 2e426da0..206eeb43 100644 --- a/src/ast/types.rs +++ b/src/ast/types.rs @@ -1,47 +1,38 @@ use super::common::{DocString, Ident, Span}; -#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub enum TypeQualifier { - Ref, // & - RefMut, // &mut - Ptr, // *const - PtrMut, // *mut -} - #[derive(Clone, Debug, Eq, Hash, PartialEq)] -pub enum TypeSpec { - Simple { +pub enum TypeDescriptor { + Type { name: Ident, - qualifiers: Vec, + generics: Vec, span: Span, }, - Generic { - name: Ident, - qualifiers: Vec, - type_params: Vec, + Ref { + of: Box, + span: Span, + }, + MutRef { + of: Box, + span: Span, + }, + ConstPtr { + of: Box, + span: Span, + }, + MutPtr { + of: Box, span: Span, }, Array { - of_type: Box, + of: Box, size: u64, - qualifiers: Vec, span: Span, }, } -impl TypeSpec { - pub fn get_name(&self) -> String { - match self { - TypeSpec::Simple { name, .. } => name.name.clone(), - TypeSpec::Generic { name, .. } => name.name.clone(), - TypeSpec::Array { of_type, .. } => format!("[{}]", of_type.get_name()), - } - } -} - #[derive(Clone, Debug, Eq, Hash, PartialEq)] pub struct TypeDecl { pub doc_string: Option, pub name: Ident, - pub value: TypeSpec, + pub value: TypeDescriptor, } diff --git a/src/check/linearity_check.rs b/src/check/linearity_check.rs index 835e10d6..ccb0a754 100644 --- a/src/check/linearity_check.rs +++ b/src/check/linearity_check.rs @@ -12,7 +12,7 @@ use crate::ast::statements::{AssignStmt, Binding, LetStmt, LetStmtTarget, Statem use crate::ast::Program; use std::path::PathBuf; -use crate::ast::types::TypeSpec; +use crate::ast::types::TypeDescriptor; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] enum VarState { diff --git a/src/check/mod.rs b/src/check/mod.rs index 305f797e..be4bcc42 100644 --- a/src/check/mod.rs +++ b/src/check/mod.rs @@ -4,7 +4,7 @@ use crate::ir::lowering::errors::LoweringError; use crate::session::Session; use ariadne::{ColorGenerator, Label, Report, ReportKind}; -pub mod linearity_check; +// pub mod linearity_check; /// Creates a report from a lowering error. pub fn lowering_error_to_report( diff --git a/src/driver/mod.rs b/src/driver/mod.rs index 0f1d4e70..04e3d37f 100644 --- a/src/driver/mod.rs +++ b/src/driver/mod.rs @@ -598,6 +598,7 @@ pub fn compile(args: &CompilerArgs) -> Result { } }; + /* #[allow(unused_variables)] if args.check { let linearity_result = @@ -610,6 +611,7 @@ pub fn compile(args: &CompilerArgs) -> Result { } }; } + */ if args.ir { std::fs::write( diff --git a/src/grammar.lalrpop b/src/grammar.lalrpop index f7395c4b..576b677c 100644 --- a/src/grammar.lalrpop +++ b/src/grammar.lalrpop @@ -146,29 +146,36 @@ pub(crate) Ident: ast::common::Ident = { } } -pub(crate) TypeQualifier: ast::types::TypeQualifier = { - "&" => ast::types::TypeQualifier::Ref, - "&" "mut" => ast::types::TypeQualifier::RefMut, - "*" "const" => ast::types::TypeQualifier::Ptr, - "*" "mut" => ast::types::TypeQualifier::PtrMut, -} - -pub(crate) TypeSpec: ast::types::TypeSpec = { - => ast::types::TypeSpec::Simple { +pub(crate) TypeDescriptor: ast::types::TypeDescriptor = { + => ast::types::TypeDescriptor::Type { name, - qualifiers, + generics: Vec::new(), span: Span::new(lo, hi), }, - "<" > ">" => ast::types::TypeSpec::Generic { + "<" > ">" => ast::types::TypeDescriptor::Type { name, - type_params, - qualifiers, + generics, span: Span::new(lo, hi), }, - "[" )> "]" => ast::types::TypeSpec::Array { - of_type: Box::new(of_type), + "[" )> "]" => ast::types::TypeDescriptor::Array { + of: Box::new(of_type), size: size.try_into().expect("size is too big"), - qualifiers, + span: Span::new(lo, hi), + }, + "&" => ast::types::TypeDescriptor::Ref { + of: Box::new(ty), + span: Span::new(lo, hi), + }, + "&" "mut" => ast::types::TypeDescriptor::MutRef { + of: Box::new(ty), + span: Span::new(lo, hi), + }, + "*" "const" => ast::types::TypeDescriptor::ConstPtr { + of: Box::new(ty), + span: Span::new(lo, hi), + }, + "*" "mut" => ast::types::TypeDescriptor::MutPtr { + of: Box::new(ty), span: Span::new(lo, hi), } } @@ -176,12 +183,6 @@ pub(crate) TypeSpec: ast::types::TypeSpec = { pub(crate) GenericParam: ast::common::GenericParam = { => ast::common::GenericParam { name, - params: vec![], - span: Span::new(lo, hi), - }, - ":" > => ast::common::GenericParam { - name, - params, span: Span::new(lo, hi), }, } @@ -279,7 +280,7 @@ pub(crate) ModuleDefItem: ast::modules::ModuleDefItem = { // Constants pub(crate) ConstantDef: ast::constants::ConstantDef = { - "const" ":" "=" => { + "const" ":" "=" => { ast::constants::ConstantDef { decl: ast::constants::ConstantDecl { doc_string: None, @@ -294,12 +295,12 @@ pub(crate) ConstantDef: ast::constants::ConstantDef = { // -- Functions -pub(crate) FunctionRetType: ast::types::TypeSpec = { - "->" => <> +pub(crate) FunctionRetType: ast::types::TypeDescriptor = { + "->" => <> } pub(crate) Param: ast::functions::Param = { - ":" => ast::functions::Param { + ":" => ast::functions::Param { name, r#type: param_type } @@ -343,7 +344,7 @@ pub(crate) FunctionDef: ast::functions::FunctionDef = { // Struct pub(crate) StructField: ast::structs::Field = { - ":" => ast::structs::Field { + ":" => ast::structs::Field { name, r#type, span: Span::new(lo, hi), @@ -457,7 +458,7 @@ pub(crate) Expression: ast::expressions::Expression = { Box::new(rhs) ), #[precedence(level="5")] #[assoc(side="left")] - "as" => ast::expressions::Expression::Cast(Box::new(a), b, Span::new(lo, hi)), + "as" => ast::expressions::Expression::Cast(Box::new(a), b, Span::new(lo, hi)), "(" ")" => ast::expressions::Expression::StructInit(<>), => ast::expressions::Expression::ArrayInit(<>), } @@ -594,7 +595,7 @@ pub(crate) Statement: ast::statements::Statement = { } pub(crate) LetStmt: ast::statements::LetStmt = { - "let" ":" "=" => ast::statements::LetStmt { + "let" ":" "=" => ast::statements::LetStmt { is_mutable: is_mutable.is_some(), target: ast::statements::LetStmtTarget::Simple { id, @@ -603,7 +604,7 @@ pub(crate) LetStmt: ast::statements::LetStmt = { value, span: Span::new(lo, hi), }, - "let" ":" "=" => ast::statements::LetStmt { + "let" ":" "=" => ast::statements::LetStmt { is_mutable: is_mutable.is_some(), target: ast::statements::LetStmtTarget::Simple { id, diff --git a/src/ir/lowering.rs b/src/ir/lowering.rs index f7854c17..2098a209 100644 --- a/src/ir/lowering.rs +++ b/src/ir/lowering.rs @@ -11,7 +11,7 @@ use crate::ast::{ modules::{Module, ModuleDefItem}, statements::{self, AssignStmt, ForStmt, LetStmt, LetStmtTarget, ReturnStmt, WhileStmt}, structs::StructDecl, - types::{TypeQualifier, TypeSpec}, + types::TypeDescriptor, Program, }; use common::{BuildCtx, FnBodyBuilder, IdGenerator}; @@ -1744,105 +1744,82 @@ pub fn lower_path( Ok((Place { local, projection }, ty, info.span)) } -pub fn lower_type(ctx: &BuildCtx, spec: &TypeSpec, module_id: DefId) -> Result { - Ok(match spec { - TypeSpec::Simple { +pub fn lower_type( + ctx: &BuildCtx, + ty: &TypeDescriptor, + module_id: DefId, +) -> Result { + Ok(match ty { + TypeDescriptor::Type { name, - qualifiers, + generics, span, - } => { - let mut ty = Ty::new(span, name_to_tykind(ctx, &name.name, *span, module_id)?); - - for qual in qualifiers.iter().rev() { - ty = match qual { - TypeQualifier::Ref => Ty::new(span, TyKind::Ref(Box::new(ty), Mutability::Not)), - TypeQualifier::RefMut => { - Ty::new(span, TyKind::Ref(Box::new(ty), Mutability::Mut)) - } - TypeQualifier::Ptr => Ty::new(span, TyKind::Ptr(Box::new(ty), Mutability::Not)), - TypeQualifier::PtrMut => { - Ty::new(span, TyKind::Ptr(Box::new(ty), Mutability::Mut)) + } => match name.name.as_str() { + "i64" => Ty::new(span, TyKind::Int(IntTy::I64)), + "i32" => Ty::new(span, TyKind::Int(IntTy::I32)), + "i16" => Ty::new(span, TyKind::Int(IntTy::I16)), + "i8" => Ty::new(span, TyKind::Int(IntTy::I8)), + "u64" => Ty::new(span, TyKind::Uint(UintTy::U64)), + "u32" => Ty::new(span, TyKind::Uint(UintTy::U32)), + "u16" => Ty::new(span, TyKind::Uint(UintTy::U16)), + "u8" => Ty::new(span, TyKind::Uint(UintTy::U8)), + "f32" => Ty::new(span, TyKind::Float(FloatTy::F32)), + "f64" => Ty::new(span, TyKind::Float(FloatTy::F64)), + "bool" => Ty::new(span, TyKind::Bool), + "string" => Ty::new(span, TyKind::String), + "char" => Ty::new(span, TyKind::Char), + other => { + let module = ctx.body.modules.get(&module_id).expect("module not found"); + // Check if the type is a struct + if let Some(struct_id) = module.symbols.structs.get(other) { + let mut generic_tys = Vec::new(); + for generic in generics { + generic_tys.push(lower_type(ctx, generic, module_id)?); } - } - } - ty - } - TypeSpec::Generic { span, .. } => Err(LoweringError::NotYetImplemented { - span: *span, - message: "Generics not yet implemented", - program_id: module_id.program_id, - })?, - TypeSpec::Array { - of_type, - size, - qualifiers, - span, - } => { - let mut ty = Ty { - span: Some(*span), - kind: TyKind::Array( - Box::new(lower_type(ctx, of_type, module_id)?), - Box::new(ConstData { - ty: Ty { - span: Some(*span), - kind: TyKind::Uint(UintTy::U64), + Ty::new( + span, + TyKind::Struct { + id: *struct_id, + generics: generic_tys, }, - data: ConstKind::Value(ValueTree::Leaf(ConstValue::U64(*size))), - }), - ), - }; - - for qual in qualifiers.iter().rev() { - ty = match qual { - TypeQualifier::Ref => Ty::new(span, TyKind::Ref(Box::new(ty), Mutability::Not)), - TypeQualifier::RefMut => { - Ty::new(span, TyKind::Ref(Box::new(ty), Mutability::Mut)) - } - TypeQualifier::Ptr => Ty::new(span, TyKind::Ptr(Box::new(ty), Mutability::Not)), - TypeQualifier::PtrMut => { - Ty::new(span, TyKind::Ptr(Box::new(ty), Mutability::Mut)) - } - } - } - ty - } - }) -} - -pub fn name_to_tykind( - ctx: &BuildCtx, - name: &str, - span: Span, - module_id: DefId, -) -> Result { - Ok(match name { - "i64" => TyKind::Int(IntTy::I64), - "i32" => TyKind::Int(IntTy::I32), - "i16" => TyKind::Int(IntTy::I16), - "i8" => TyKind::Int(IntTy::I8), - "u64" => TyKind::Uint(UintTy::U64), - "u32" => TyKind::Uint(UintTy::U32), - "u16" => TyKind::Uint(UintTy::U16), - "u8" => TyKind::Uint(UintTy::U8), - "f32" => TyKind::Float(FloatTy::F32), - "f64" => TyKind::Float(FloatTy::F64), - "bool" => TyKind::Bool, - "string" => TyKind::String, - "char" => TyKind::Char, - other => { - let module = ctx.body.modules.get(&module_id).expect("module not found"); - if let Some(struct_id) = module.symbols.structs.get(other) { - TyKind::Struct { - id: *struct_id, - generics: vec![], + ) + } else { + Err(LoweringError::UnrecognizedType { + span: *span, + name: other.to_string(), + program_id: module_id.program_id, + })? } - } else { - Err(LoweringError::UnrecognizedType { - span, - name: other.to_string(), - program_id: module_id.program_id, - })? } - } + }, + TypeDescriptor::Ref { of, span } => Ty::new( + span, + TyKind::Ref(Box::new(lower_type(ctx, of, module_id)?), Mutability::Not), + ), + TypeDescriptor::MutRef { of, span } => Ty::new( + span, + TyKind::Ref(Box::new(lower_type(ctx, of, module_id)?), Mutability::Mut), + ), + TypeDescriptor::ConstPtr { of, span } => Ty::new( + span, + TyKind::Ptr(Box::new(lower_type(ctx, of, module_id)?), Mutability::Not), + ), + TypeDescriptor::MutPtr { of, span } => Ty::new( + span, + TyKind::Ptr(Box::new(lower_type(ctx, of, module_id)?), Mutability::Mut), + ), + TypeDescriptor::Array { of, size, span } => Ty::new( + span, + TyKind::Array( + Box::new(lower_type(ctx, of, module_id)?), + Box::new(ConstData { + ty: Ty { + span: Some(*span), + kind: TyKind::Uint(UintTy::U64), + }, + data: ConstKind::Value(ValueTree::Leaf(ConstValue::U64(*size))), + }), + ), + ), }) } diff --git a/src/ir/lowering/common.rs b/src/ir/lowering/common.rs index 8d38e96a..f34518ea 100644 --- a/src/ir/lowering/common.rs +++ b/src/ir/lowering/common.rs @@ -37,8 +37,8 @@ pub struct BuildCtx { pub unresolved_function_signatures: HashMap< DefId, ( - Vec, - Option, + Vec, + Option, ), >, pub gen: IdGenerator, From 5c35d06675a2e15cd7840954f7b6ced26ffb5acd Mon Sep 17 00:00:00 2001 From: Edgar Luque Date: Thu, 9 Jan 2025 10:37:30 +0100 Subject: [PATCH 03/18] Add initial grammar for impl blocks --- src/ast/functions.rs | 7 +++++++ src/ast/modules.rs | 3 ++- src/grammar.lalrpop | 14 ++++++++++++++ src/ir/lowering.rs | 1 + src/ir/lowering/prepass.rs | 2 ++ src/parser/tokens.rs | 2 ++ 6 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/ast/functions.rs b/src/ast/functions.rs index 059eaeec..5cf8a124 100644 --- a/src/ast/functions.rs +++ b/src/ast/functions.rs @@ -29,3 +29,10 @@ pub struct Param { pub name: Ident, pub r#type: TypeDescriptor, } + +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct ImplBlock { + pub target: Ident, + pub methods: Vec, + pub span: Span, +} diff --git a/src/ast/modules.rs b/src/ast/modules.rs index 1af61309..6ce3a277 100644 --- a/src/ast/modules.rs +++ b/src/ast/modules.rs @@ -2,7 +2,7 @@ use super::{ common::{DocString, Ident, Span}, constants::ConstantDef, enums::{EnumDecl, UnionDecl}, - functions::{FunctionDecl, FunctionDef}, + functions::{FunctionDecl, FunctionDef, ImplBlock}, imports::ImportStmt, structs::StructDecl, types::TypeDecl, @@ -23,6 +23,7 @@ pub enum ModuleDefItem { Constant(ConstantDef), Function(FunctionDef), FunctionDecl(FunctionDecl), + Impl(ImplBlock), Struct(StructDecl), Union(UnionDecl), Enum(EnumDecl), diff --git a/src/grammar.lalrpop b/src/grammar.lalrpop index 576b677c..647b140f 100644 --- a/src/grammar.lalrpop +++ b/src/grammar.lalrpop @@ -20,6 +20,7 @@ extern { "struct" => Token::KeywordStruct, "union" => Token::KeywordUnion, "enum" => Token::KeywordEnum, + "impl" => Token::KeywordImpl, "if" => Token::KeywordIf, "else" => Token::KeywordElse, "while" => Token::KeywordWhile, @@ -272,6 +273,9 @@ pub(crate) ModuleDefItem: ast::modules::ModuleDefItem = { ";" => { ast::modules::ModuleDefItem::FunctionDecl(<>) }, + => { + ast::modules::ModuleDefItem::Impl(<>) + }, => { ast::modules::ModuleDefItem::Module(<>) }, @@ -341,6 +345,16 @@ pub(crate) FunctionDef: ast::functions::FunctionDef = { } } +pub(crate) ImplBlock: ast::functions::ImplBlock = { + "impl" "{" "}" => { + ast::functions::ImplBlock { + target, + methods, + span: Span::new(lo, hi), + } + } +} + // Struct pub(crate) StructField: ast::structs::Field = { diff --git a/src/ir/lowering.rs b/src/ir/lowering.rs index 2098a209..576837b2 100644 --- a/src/ir/lowering.rs +++ b/src/ir/lowering.rs @@ -176,6 +176,7 @@ fn lower_module(mut ctx: BuildCtx, module: &Module, id: DefId) -> Result { ctx = lower_func_decl(ctx, fn_decl, id)?; } + ModuleDefItem::Impl(_impl_block) => todo!(), } } diff --git a/src/ir/lowering/prepass.rs b/src/ir/lowering/prepass.rs index 78f4e503..d2695833 100644 --- a/src/ir/lowering/prepass.rs +++ b/src/ir/lowering/prepass.rs @@ -112,6 +112,7 @@ pub fn prepass_module( ), ); } + ast::modules::ModuleDefItem::Impl(_impl_block) => todo!(), } } @@ -229,6 +230,7 @@ pub fn prepass_sub_module( ), ); } + ast::modules::ModuleDefItem::Impl(_impl_block) => todo!(), } } diff --git a/src/parser/tokens.rs b/src/parser/tokens.rs index 5374a1c9..25a7deeb 100644 --- a/src/parser/tokens.rs +++ b/src/parser/tokens.rs @@ -37,6 +37,8 @@ pub enum Token { KeywordUnion, #[token("enum")] KeywordEnum, + #[token("impl")] + KeywordImpl, #[token("if")] KeywordIf, #[token("else")] From f2450979ad8def500db1d0554b8e8246b87de649 Mon Sep 17 00:00:00 2001 From: Edgar Luque Date: Thu, 9 Jan 2025 11:59:45 +0100 Subject: [PATCH 04/18] optimize grammar --- src/grammar.lalrpop | 92 ++++++++++++++++++++++----------------------- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/src/grammar.lalrpop b/src/grammar.lalrpop index 647b140f..92927327 100644 --- a/src/grammar.lalrpop +++ b/src/grammar.lalrpop @@ -140,14 +140,14 @@ SemiColonSeparated: Vec = { // -- Common -pub(crate) Ident: ast::common::Ident = { +Ident: ast::common::Ident = { => ast::common::Ident { name, span: ast::common::Span::new(lo, hi), } } -pub(crate) TypeDescriptor: ast::types::TypeDescriptor = { +TypeDescriptor: ast::types::TypeDescriptor = { => ast::types::TypeDescriptor::Type { name, generics: Vec::new(), @@ -181,14 +181,14 @@ pub(crate) TypeDescriptor: ast::types::TypeDescriptor = { } } -pub(crate) GenericParam: ast::common::GenericParam = { +GenericParam: ast::common::GenericParam = { => ast::common::GenericParam { name, span: Span::new(lo, hi), }, } -pub(crate) GenericParams: Vec = { +GenericParams: Vec = { "<" > ">" => <> } @@ -209,11 +209,11 @@ pub Program: ast::Program = { // Modules -pub(crate) ExternalModule: ast::common::Ident = { +ExternalModule: ast::common::Ident = { "mod" ";" => name } -pub(crate) Module: ast::modules::Module = { +Module: ast::modules::Module = { "mod" "{" ?> "}" => { ast::modules::Module { doc_string: None, @@ -226,7 +226,7 @@ pub(crate) Module: ast::modules::Module = { } } -pub(crate) ImportList: Vec = { +ImportList: Vec = { => vec![<>], => { s.push(n); @@ -235,7 +235,7 @@ pub(crate) ImportList: Vec = { } -pub(crate) ImportStmt: ast::imports::ImportStmt = { +ImportStmt: ast::imports::ImportStmt = { "import" > "{" > "}" ";" => { ast::imports::ImportStmt { module, @@ -246,7 +246,7 @@ pub(crate) ImportStmt: ast::imports::ImportStmt = { } -pub(crate) ModuleItems: Vec = { +ModuleItems: Vec = { => vec![<>], => { s.push(n); @@ -254,7 +254,7 @@ pub(crate) ModuleItems: Vec = { }, } -pub(crate) ModuleDefItem: ast::modules::ModuleDefItem = { +ModuleDefItem: ast::modules::ModuleDefItem = { ";" => { ast::modules::ModuleDefItem::Constant(<>) }, @@ -283,7 +283,7 @@ pub(crate) ModuleDefItem: ast::modules::ModuleDefItem = { // Constants -pub(crate) ConstantDef: ast::constants::ConstantDef = { +ConstantDef: ast::constants::ConstantDef = { "const" ":" "=" => { ast::constants::ConstantDef { decl: ast::constants::ConstantDecl { @@ -299,18 +299,18 @@ pub(crate) ConstantDef: ast::constants::ConstantDef = { // -- Functions -pub(crate) FunctionRetType: ast::types::TypeDescriptor = { +FunctionRetType: ast::types::TypeDescriptor = { "->" => <> } -pub(crate) Param: ast::functions::Param = { +Param: ast::functions::Param = { ":" => ast::functions::Param { name, r#type: param_type } } -pub(crate) Attribute: ast::common::Attribute = { +Attribute: ast::common::Attribute = { "#" "[" )?> "]" => ast::common::Attribute { name, value, @@ -318,7 +318,7 @@ pub(crate) Attribute: ast::common::Attribute = { } } -pub(crate) FunctionDecl: ast::functions::FunctionDecl = { +FunctionDecl: ast::functions::FunctionDecl = { ?> "fn" "(" > ")" => @@ -335,7 +335,7 @@ pub(crate) FunctionDecl: ast::functions::FunctionDecl = { } } -pub(crate) FunctionDef: ast::functions::FunctionDef = { +FunctionDef: ast::functions::FunctionDef = { "{" "}" => { ast::functions::FunctionDef { decl, @@ -345,7 +345,7 @@ pub(crate) FunctionDef: ast::functions::FunctionDef = { } } -pub(crate) ImplBlock: ast::functions::ImplBlock = { +ImplBlock: ast::functions::ImplBlock = { "impl" "{" "}" => { ast::functions::ImplBlock { target, @@ -357,7 +357,7 @@ pub(crate) ImplBlock: ast::functions::ImplBlock = { // Struct -pub(crate) StructField: ast::structs::Field = { +StructField: ast::structs::Field = { ":" => ast::structs::Field { name, r#type, @@ -365,7 +365,7 @@ pub(crate) StructField: ast::structs::Field = { } } -pub(crate) StructDef: ast::structs::StructDecl = { +StructDef: ast::structs::StructDecl = { "struct" "{" > "}" => ast::structs::StructDecl { name, fields, @@ -375,7 +375,7 @@ pub(crate) StructDef: ast::structs::StructDecl = { } -pub(crate) UnionDef: ast::enums::UnionDecl = { +UnionDef: ast::enums::UnionDecl = { "union" "{" > "}" => ast::enums::UnionDecl { name, variants, @@ -384,7 +384,7 @@ pub(crate) UnionDef: ast::enums::UnionDecl = { } } -pub(crate) EnumDef: ast::enums::EnumDecl = { +EnumDef: ast::enums::EnumDecl = { "enum" "{" > "}" => ast::enums::EnumDecl { name, variants, @@ -394,7 +394,7 @@ pub(crate) EnumDef: ast::enums::EnumDecl = { } -pub(crate) EnumVariant: ast::enums::EnumVariant = { +EnumVariant: ast::enums::EnumVariant = { > "}")?> )?> => ast::enums::EnumVariant { name, fields: fields.unwrap_or_default(), @@ -403,7 +403,7 @@ pub(crate) EnumVariant: ast::enums::EnumVariant = { } } -pub(crate) StructInitField: (ast::common::Ident, ast::expressions::StructInitField) = { +StructInitField: (ast::common::Ident, ast::expressions::StructInitField) = { ":" => (name, ast::expressions::StructInitField { value, span: Span::new(lo, hi), @@ -414,7 +414,7 @@ pub(crate) StructInitField: (ast::common::Ident, ast::expressions::StructInitFie }) } -pub(crate) StructInitExpr: ast::expressions::StructInitExpr = { +StructInitExpr: ast::expressions::StructInitExpr = { "{" > "}" => ast::expressions::StructInitExpr { name, fields: fields.into_iter().collect(), @@ -423,7 +423,7 @@ pub(crate) StructInitExpr: ast::expressions::StructInitExpr = { } -pub(crate) ArrayInitExpr: ast::expressions::ArrayInitExpr = { +ArrayInitExpr: ast::expressions::ArrayInitExpr = { "[" > "]" => ast::expressions::ArrayInitExpr { values: values.into_iter().collect(), span: Span::new(lo, hi), @@ -432,7 +432,7 @@ pub(crate) ArrayInitExpr: ast::expressions::ArrayInitExpr = { // Expressions -pub(crate) Term: ast::expressions::Expression = { +Term: ast::expressions::Expression = { #[precedence(level="0")] => ast::expressions::Expression::Value(v, Span::new(lo, hi)), => ast::expressions::Expression::FnCall(<>), @@ -442,7 +442,7 @@ pub(crate) Term: ast::expressions::Expression = { "(" ")", } -pub(crate) Expression: ast::expressions::Expression = { +Expression: ast::expressions::Expression = { #[precedence(level="0")] , #[precedence(level="1")] #[assoc(side="left")] @@ -477,7 +477,7 @@ pub(crate) Expression: ast::expressions::Expression = { => ast::expressions::Expression::ArrayInit(<>), } -pub BinaryFirstLvlOp: ast::expressions::BinaryOp = { +BinaryFirstLvlOp: ast::expressions::BinaryOp = { "==" => ast::expressions::BinaryOp::Compare(ast::expressions::CmpOp::Eq), "!=" => ast::expressions::BinaryOp::Compare(ast::expressions::CmpOp::NotEq), "<" => ast::expressions::BinaryOp::Compare(ast::expressions::CmpOp::Lt), @@ -488,13 +488,13 @@ pub BinaryFirstLvlOp: ast::expressions::BinaryOp = { "||" => ast::expressions::BinaryOp::Logic(ast::expressions::LogicOp::Or), } -pub BinarySecondLvlOp: ast::expressions::BinaryOp = { +BinarySecondLvlOp: ast::expressions::BinaryOp = { "/" => ast::expressions::BinaryOp::Arith(ast::expressions::ArithOp::Div), "*" => ast::expressions::BinaryOp::Arith(ast::expressions::ArithOp::Mul), "%" => ast::expressions::BinaryOp::Arith(ast::expressions::ArithOp::Mod), } -pub BinaryThirdLvlOp: ast::expressions::BinaryOp = { +BinaryThirdLvlOp: ast::expressions::BinaryOp = { "+" => ast::expressions::BinaryOp::Arith(ast::expressions::ArithOp::Add), "-" => ast::expressions::BinaryOp::Arith(ast::expressions::ArithOp::Sub), "&" => ast::expressions::BinaryOp::Bitwise(ast::expressions::BitwiseOp::And), @@ -502,13 +502,13 @@ pub BinaryThirdLvlOp: ast::expressions::BinaryOp = { "^" => ast::expressions::BinaryOp::Bitwise(ast::expressions::BitwiseOp::Xor), } -pub UnaryOp: ast::expressions::UnaryOp = { +UnaryOp: ast::expressions::UnaryOp = { "-" => ast::expressions::UnaryOp::ArithNeg, "!" => ast::expressions::UnaryOp::LogicalNot, "~" => ast::expressions::UnaryOp::BitwiseNot, } -pub(crate) ValueExpr: ast::expressions::ValueExpr = { +ValueExpr: ast::expressions::ValueExpr = { => ast::expressions::ValueExpr::ConstInt(v, Span::new(lo, hi)), => ast::expressions::ValueExpr::ConstFloat(v, Span::new(lo, hi)), => ast::expressions::ValueExpr::ConstBool(v, Span::new(lo, hi)), @@ -517,7 +517,7 @@ pub(crate) ValueExpr: ast::expressions::ValueExpr = { => ast::expressions::ValueExpr::Path(<>), } -pub(crate) IfExpr: ast::expressions::IfExpr = { +IfExpr: ast::expressions::IfExpr = { "if" "{" "}" "}")?> => { ast::expressions::IfExpr { @@ -529,7 +529,7 @@ pub(crate) IfExpr: ast::expressions::IfExpr = { } } -pub(crate) MatchExpr: ast::expressions::MatchExpr = { +MatchExpr: ast::expressions::MatchExpr = { "match" "{" > "}" => { ast::expressions::MatchExpr { expr: Box::new(expr), @@ -539,7 +539,7 @@ pub(crate) MatchExpr: ast::expressions::MatchExpr = { } } -pub(crate) MatchVariant: ast::expressions::MatchVariant = { +MatchVariant: ast::expressions::MatchVariant = { // 0 -> 1 "->" => { ast::expressions::MatchVariant { @@ -558,7 +558,7 @@ pub(crate) MatchVariant: ast::expressions::MatchVariant = { } } -pub(crate) PathOp: ast::expressions::PathOp = { +PathOp: ast::expressions::PathOp = { => ast::expressions::PathOp { first, extra: extra.unwrap_or(vec![]), @@ -566,12 +566,12 @@ pub(crate) PathOp: ast::expressions::PathOp = { }, } -pub(crate) PathSegment: ast::expressions::PathSegment = { +PathSegment: ast::expressions::PathSegment = { "." => ast::expressions::PathSegment::FieldAccess(e, Span::new(lo, hi)), "[" "]" => ast::expressions::PathSegment::ArrayIndex(e, Span::new(lo, hi)), } -pub PathSegments: Vec = { +PathSegments: Vec = { => vec![<>], => { s.push(n); @@ -579,7 +579,7 @@ pub PathSegments: Vec = { }, } -pub(crate) FnCallOp: ast::expressions::FnCallOp = { +FnCallOp: ast::expressions::FnCallOp = { "(" > ")" => ast::expressions::FnCallOp { target, args, @@ -589,7 +589,7 @@ pub(crate) FnCallOp: ast::expressions::FnCallOp = { // -- Statements -pub StatementList: Vec = { +StatementList: Vec = { => vec![<>], => { s.push(n); @@ -597,7 +597,7 @@ pub StatementList: Vec = { }, } -pub(crate) Statement: ast::statements::Statement = { +Statement: ast::statements::Statement = { ";"? => ast::statements::Statement::Match(<>), ";"? => ast::statements::Statement::If(<>), ";"? => ast::statements::Statement::While(<>), @@ -608,7 +608,7 @@ pub(crate) Statement: ast::statements::Statement = { ";" => ast::statements::Statement::Return(<>), } -pub(crate) LetStmt: ast::statements::LetStmt = { +LetStmt: ast::statements::LetStmt = { "let" ":" "=" => ast::statements::LetStmt { is_mutable: is_mutable.is_some(), target: ast::statements::LetStmtTarget::Simple { @@ -629,7 +629,7 @@ pub(crate) LetStmt: ast::statements::LetStmt = { }, } -pub(crate) AssignStmt: ast::statements::AssignStmt = { +AssignStmt: ast::statements::AssignStmt = { "=" => ast::statements::AssignStmt { lvalue, rvalue, @@ -644,14 +644,14 @@ pub(crate) AssignStmt: ast::statements::AssignStmt = { }, } -pub(crate) ReturnStmt: ast::statements::ReturnStmt = { +ReturnStmt: ast::statements::ReturnStmt = { "return" => ast::statements::ReturnStmt { value, span: Span::new(lo, hi), }, } -pub(crate) WhileStmt: ast::statements::WhileStmt = { +WhileStmt: ast::statements::WhileStmt = { "while" "{" "}" => { ast::statements::WhileStmt { condition, @@ -661,7 +661,7 @@ pub(crate) WhileStmt: ast::statements::WhileStmt = { } -pub(crate) ForStmt: ast::statements::ForStmt = { +ForStmt: ast::statements::ForStmt = { "for" "(" ";" ";" ")" "{" "}" => { ast::statements::ForStmt { init, From b43f5ead33b8f5469407c84c09968f5246a2c73a Mon Sep 17 00:00:00 2001 From: Edgar Luque Date: Fri, 10 Jan 2025 14:59:42 +0100 Subject: [PATCH 05/18] Add TypeName to AST, allowing type names to have a full path and generics --- Cargo.lock | 129 +++++++++++++++++++------------------- Cargo.toml | 4 +- src/ast/common.rs | 15 +++++ src/ast/types.rs | 5 +- src/grammar.lalrpop | 28 ++++++--- src/ir/lowering.rs | 17 ++--- src/ir/lowering/common.rs | 14 ++--- src/parser/tokens.rs | 2 + 8 files changed, 122 insertions(+), 92 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3e6070fe..ef3dd32e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -128,7 +128,7 @@ version = "0.69.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.7.0", "cexpr", "clang-sys", "itertools 0.12.1", @@ -151,7 +151,7 @@ version = "0.71.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f58bf3d7db68cfbac37cfc485a8d711e87e064c3d0fe0435b92f7a407f9d6b3" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.7.0", "cexpr", "clang-sys", "itertools 0.13.0", @@ -188,9 +188,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.6.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +checksum = "1be3f42a67d6d345ecd59f675f3f012d6974981560836e938c22b424b85ce1be" [[package]] name = "block-buffer" @@ -203,9 +203,9 @@ dependencies = [ [[package]] name = "bon" -version = "3.3.0" +version = "3.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f265cdb2e8501f1c952749e78babe8f1937be92c98120e5f78fc72d634682bad" +checksum = "fe7acc34ff59877422326db7d6f2d845a582b16396b6b08194942bf34c6528ab" dependencies = [ "bon-macros", "rustversion", @@ -213,9 +213,9 @@ dependencies = [ [[package]] name = "bon-macros" -version = "3.3.0" +version = "3.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38aa5c627cd7706490e5b003d685f8b9d69bc343b1a00b9fdd01e75fdf6827cf" +checksum = "4159dd617a7fbc9be6a692fe69dc2954f8e6bb6bb5e4d7578467441390d77fd0" dependencies = [ "darling", "ident_case", @@ -234,19 +234,18 @@ checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "caseless" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "808dab3318747be122cb31d36de18d4d1c81277a76f8332a02b81a3d73463d7f" +checksum = "8b6fd507454086c8edfd769ca6ada439193cdb209c7681712ef6275cccbfe5d8" dependencies = [ - "regex", "unicode-normalization", ] [[package]] name = "cc" -version = "1.2.3" +version = "1.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27f657647bcff5394bf56c7317665bbf790a137a50eaaa5c6bfbb9e27a518f2d" +checksum = "a012a0df96dd6d06ba9a1b29d6402d1a5d77c6befd2566afdc26e10603dc93d7" dependencies = [ "jobserver", "libc", @@ -281,9 +280,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.24" +version = "4.5.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9560b07a799281c7e0958b9296854d6fafd4c5f31444a7e5bb1ad6dde5ccf1bd" +checksum = "a8eb5e908ef3a6efbe1ed62520fb7287959888c88485abe072543190ecc66783" dependencies = [ "clap_builder", "clap_derive", @@ -291,9 +290,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.24" +version = "4.5.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "874e0dd3eb68bf99058751ac9712f622e61e6f393a94f7128fa26e3f02f5c7cd" +checksum = "96b01801b5fc6a0a232407abc821660c9c6d25a1cafc0d4f85f29fb8d9afc121" dependencies = [ "anstream", "anstyle", @@ -384,7 +383,7 @@ dependencies = [ "serde", "tempfile", "test-case", - "thiserror 2.0.9", + "thiserror 2.0.10", "toml", "tracing", "tracing-subscriber", @@ -424,18 +423,18 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.13" +version = "0.5.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" +checksum = "06ba6d68e24814cb8de6bb986db8222d3a027d15872cabc0d18817bc3c0e4471" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-deque" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" dependencies = [ "crossbeam-epoch", "crossbeam-utils", @@ -452,18 +451,18 @@ dependencies = [ [[package]] name = "crossbeam-queue" -version = "0.3.11" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35" +checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-utils" -version = "0.8.20" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "crypto-common" @@ -674,7 +673,7 @@ version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fda788993cc341f69012feba8bf45c0ba4f3291fcc08e214b4d5a7332d88aff" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.7.0", "libc", "libgit2-sys", "log", @@ -685,9 +684,9 @@ dependencies = [ [[package]] name = "glob" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" [[package]] name = "hashbrown" @@ -727,11 +726,11 @@ checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" [[package]] name = "home" -version = "0.5.9" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -997,9 +996,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.168" +version = "0.2.169" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aaeb2981e0606ca11d79718f8bb01164f1d6ed75080182d3abf017e6d244b6d" +checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" [[package]] name = "libgit2-sys" @@ -1041,9 +1040,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.20" +version = "1.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2d16453e800a8cf6dd2fc3eb4bc99b786a9b90c663b8559a5b1a041bf89e472" +checksum = "df9b68e50e6e0b26f672573834882eb57759f6db9b3be2ea3c35c91188bb4eaa" dependencies = [ "cc", "libc", @@ -1053,9 +1052,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.4.14" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" [[package]] name = "litemap" @@ -1318,9 +1317,9 @@ checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" [[package]] name = "pin-project-lite" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" [[package]] name = "pkg-config" @@ -1336,9 +1335,9 @@ checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" [[package]] name = "prettyplease" -version = "0.2.25" +version = "0.2.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033" +checksum = "483f8c21f64f3ea09fe0f30f5d48c3e8eefe5dac9129f0075f76593b4c1da705" dependencies = [ "proc-macro2", "syn", @@ -1355,9 +1354,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.37" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" dependencies = [ "proc-macro2", ] @@ -1388,7 +1387,7 @@ version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.7.0", ] [[package]] @@ -1464,11 +1463,11 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.42" +version = "0.38.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93dc38ecbab2eb790ff964bb77fa94faf256fd3e73285fd7ba0903b76bedb85" +checksum = "a78891ee6bf2340288408954ac787aa063d8e8817e9f53abb37c695c6d834ef6" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.7.0", "errno", "libc", "linux-raw-sys", @@ -1477,9 +1476,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.18" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" +checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4" [[package]] name = "salsa" @@ -1536,9 +1535,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "semver" -version = "1.0.23" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" +checksum = "3cb6eb87a131f756572d7fb904f6e7b68633f09cca868c5df1c4b8d1a694bbba" [[package]] name = "serde" @@ -1643,9 +1642,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.90" +version = "2.0.96" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" +checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80" dependencies = [ "proc-macro2", "quote", @@ -1691,9 +1690,9 @@ dependencies = [ [[package]] name = "term" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4df4175de05129f31b80458c6df371a15e7fc3fd367272e6bf938e5c351c7ea0" +checksum = "a3bb6001afcea98122260987f8b7b5da969ecad46dbf0b5453702f776b491a41" dependencies = [ "home", "windows-sys 0.52.0", @@ -1743,11 +1742,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.9" +version = "2.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f072643fd0190df67a8bab670c20ef5d8737177d6ac6b2e9a236cb096206b2cc" +checksum = "a3ac7f54ca534db81081ef1c1e7f6ea8a3ef428d2fc069097c079443d24124d3" dependencies = [ - "thiserror-impl 2.0.9", + "thiserror-impl 2.0.10", ] [[package]] @@ -1763,9 +1762,9 @@ dependencies = [ [[package]] name = "thiserror-impl" -version = "2.0.9" +version = "2.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b50fa271071aae2e6ee85f842e2e28ba8cd2c5fb67f11fcb1fd70b276f9e7d4" +checksum = "9e9465d30713b56a37ede7185763c3492a91be2f5fa68d958c44e41ab9248beb" dependencies = [ "proc-macro2", "quote", @@ -1794,9 +1793,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.8.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" +checksum = "022db8904dfa342efe721985167e9fcd16c29b226db4397ed752a761cfce81e8" dependencies = [ "tinyvec_macros", ] @@ -2278,9 +2277,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.6.20" +version = "0.6.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" +checksum = "39281189af81c07ec09db316b302a3e67bf9bd7cbf6c820b50e35fee9c2fa980" dependencies = [ "memchr", ] diff --git a/Cargo.toml b/Cargo.toml index 7eb0965a..1c9ffc2b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,7 @@ edition = "2021" [dependencies] tracing = "0.1.41" itertools = "0.14.0" -thiserror = "2.0.9" +thiserror = "2.0.10" educe = "0.5.11" lalrpop-util = { version = "0.22.0", features = ["unicode"] } logos = "0.15.0" @@ -23,7 +23,7 @@ mlir-sys = "0.4.1" anyhow = "1.0.95" git2 = "0.20.0" owo-colors = "4.1.0" -clap = { version = "4.5.24", features = ["derive"] } +clap = { version = "4.5.26", features = ["derive"] } tracing-subscriber = { version = "0.3.19", features = ["env-filter"] } serde = { version = "1.0.217", features = ["derive"] } toml = "0.8.19" diff --git a/src/ast/common.rs b/src/ast/common.rs index 6f6278cb..294019c9 100644 --- a/src/ast/common.rs +++ b/src/ast/common.rs @@ -23,12 +23,27 @@ pub struct DocString { contents: String, } +/// Identifiers, without a path or generics. #[derive(Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)] pub struct Ident { pub name: String, pub span: Span, } +/// A type name, supporting fully qualified paths and generics: +/// ``` +/// std::module::X +/// ``` +/// Used only when specifying types. +#[derive(Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)] +pub struct TypeName { + pub path: Vec, + pub name: Ident, + pub generics: Vec, + pub span: Span, +} + +/// Used as a generic param in function and struct declarations. #[derive(Clone, Debug, Eq, Hash, PartialEq)] pub struct GenericParam { pub name: Ident, diff --git a/src/ast/types.rs b/src/ast/types.rs index 206eeb43..7902478f 100644 --- a/src/ast/types.rs +++ b/src/ast/types.rs @@ -1,10 +1,9 @@ -use super::common::{DocString, Ident, Span}; +use super::common::{DocString, Ident, Span, TypeName}; #[derive(Clone, Debug, Eq, Hash, PartialEq)] pub enum TypeDescriptor { Type { - name: Ident, - generics: Vec, + name: TypeName, span: Span, }, Ref { diff --git a/src/grammar.lalrpop b/src/grammar.lalrpop index 92927327..1c43af7b 100644 --- a/src/grammar.lalrpop +++ b/src/grammar.lalrpop @@ -52,6 +52,7 @@ extern { "=" => Token::Assign, ";" => Token::Semicolon, ":" => Token::Colon, + "::" => Token::DoubleColon, "->" => Token::Arrow, "," => Token::Coma, "#" => Token::Hashtag, @@ -101,6 +102,16 @@ Comma: Vec = { } }; +Colon: Vec = { + ":")*> => match e { + None => v, + Some(e) => { + v.push(e); + v + } + } +}; + SemiColon: Vec = { ";")*> => match e { None => v, @@ -147,15 +158,18 @@ Ident: ast::common::Ident = { } } -TypeDescriptor: ast::types::TypeDescriptor = { - => ast::types::TypeDescriptor::Type { +TypeName: ast::common::TypeName = { + "::")*> > ">")?> => ast::common::TypeName { name, - generics: Vec::new(), - span: Span::new(lo, hi), - }, - "<" > ">" => ast::types::TypeDescriptor::Type { + path, + generics: generics.unwrap_or_default(), + span: ast::common::Span::new(lo, hi), + } +} + +TypeDescriptor: ast::types::TypeDescriptor = { + => ast::types::TypeDescriptor::Type { name, - generics, span: Span::new(lo, hi), }, "[" )> "]" => ast::types::TypeDescriptor::Array { diff --git a/src/ir/lowering.rs b/src/ir/lowering.rs index 576837b2..2d3df9c8 100644 --- a/src/ir/lowering.rs +++ b/src/ir/lowering.rs @@ -1751,11 +1751,7 @@ pub fn lower_type( module_id: DefId, ) -> Result { Ok(match ty { - TypeDescriptor::Type { - name, - generics, - span, - } => match name.name.as_str() { + TypeDescriptor::Type { name, span } => match name.name.name.as_str() { "i64" => Ty::new(span, TyKind::Int(IntTy::I64)), "i32" => Ty::new(span, TyKind::Int(IntTy::I32)), "i16" => Ty::new(span, TyKind::Int(IntTy::I16)), @@ -1774,8 +1770,15 @@ pub fn lower_type( // Check if the type is a struct if let Some(struct_id) = module.symbols.structs.get(other) { let mut generic_tys = Vec::new(); - for generic in generics { - generic_tys.push(lower_type(ctx, generic, module_id)?); + for generic in &name.generics { + generic_tys.push(lower_type( + ctx, + &TypeDescriptor::Type { + name: generic.clone(), + span: generic.span, + }, + module_id, + )?); } Ty::new( span, diff --git a/src/ir/lowering/common.rs b/src/ir/lowering/common.rs index f34518ea..57cf6efb 100644 --- a/src/ir/lowering/common.rs +++ b/src/ir/lowering/common.rs @@ -1,6 +1,9 @@ use std::collections::HashMap; -use crate::ir::{DefId, FnBody, Local, LocalIndex, ModuleBody, ProgramBody, Statement, Ty, TyKind}; +use crate::{ + ast::types::TypeDescriptor, + ir::{DefId, FnBody, Local, LocalIndex, ModuleBody, ProgramBody, Statement, Ty, TyKind}, +}; #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] pub struct IdGenerator { @@ -34,13 +37,8 @@ impl IdGenerator { #[derive(Debug, Clone)] pub struct BuildCtx { pub body: ProgramBody, - pub unresolved_function_signatures: HashMap< - DefId, - ( - Vec, - Option, - ), - >, + pub unresolved_function_signatures: + HashMap, Option)>, pub gen: IdGenerator, } diff --git a/src/parser/tokens.rs b/src/parser/tokens.rs index 25a7deeb..44ffd1b3 100644 --- a/src/parser/tokens.rs +++ b/src/parser/tokens.rs @@ -105,6 +105,8 @@ pub enum Token { Semicolon, #[token(":")] Colon, + #[token("::")] + DoubleColon, #[token("->")] Arrow, #[token(",")] From a2ad74de7aa6cc4040379bbf760c584236b2caa7 Mon Sep 17 00:00:00 2001 From: Edgar Luque Date: Fri, 10 Jan 2025 15:01:51 +0100 Subject: [PATCH 06/18] remove unused --- src/grammar.lalrpop | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/grammar.lalrpop b/src/grammar.lalrpop index 1c43af7b..9f8fb9f0 100644 --- a/src/grammar.lalrpop +++ b/src/grammar.lalrpop @@ -102,16 +102,6 @@ Comma: Vec = { } }; -Colon: Vec = { - ":")*> => match e { - None => v, - Some(e) => { - v.push(e); - v - } - } -}; - SemiColon: Vec = { ";")*> => match e { None => v, From 2dea50788522540b6b088f69561bd5c13a028319 Mon Sep 17 00:00:00 2001 From: Edgar Luque Date: Tue, 14 Jan 2025 12:21:05 +0100 Subject: [PATCH 07/18] remove comment --- src/driver/mod.rs | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/driver/mod.rs b/src/driver/mod.rs index 04e3d37f..11c74d06 100644 --- a/src/driver/mod.rs +++ b/src/driver/mod.rs @@ -598,21 +598,6 @@ pub fn compile(args: &CompilerArgs) -> Result { } }; - /* - #[allow(unused_variables)] - if args.check { - let linearity_result = - match crate::check::linearity_check::linearity_check_program(&programs, &session) { - Ok(ir) => ir, - Err(error) => { - //TODO improve reporting - println!("Linearity check failed: {:#?}", error); - std::process::exit(1); - } - }; - } - */ - if args.ir { std::fs::write( session.output_file.with_extension("ir"), From d97dde3a019a91a3c5c4715bc2b2b93e560d7773 Mon Sep 17 00:00:00 2001 From: Edgar Luque Date: Mon, 13 Jan 2025 11:13:12 +0100 Subject: [PATCH 08/18] improve impl grammar --- src/ast/expressions.rs | 1 + src/ast/types.rs | 5 ++++ src/grammar.lalrpop | 16 ++++++++++++ src/ir/lowering.rs | 5 ++++ src/parser/mod.rs | 56 ++++++++++++++++++++++++++++++++++++++++++ src/parser/tokens.rs | 2 ++ 6 files changed, 85 insertions(+) diff --git a/src/ast/expressions.rs b/src/ast/expressions.rs index 6f603ba0..49c47a26 100644 --- a/src/ast/expressions.rs +++ b/src/ast/expressions.rs @@ -123,6 +123,7 @@ pub struct MatchVariant { pub enum PathSegment { FieldAccess(Ident, Span), ArrayIndex(ValueExpr, Span), + MethodCall(FnCallOp, Span), } #[derive(Clone, Debug, Eq, PartialEq)] diff --git a/src/ast/types.rs b/src/ast/types.rs index 7902478f..1da8d6cf 100644 --- a/src/ast/types.rs +++ b/src/ast/types.rs @@ -27,6 +27,11 @@ pub enum TypeDescriptor { size: u64, span: Span, }, + // Used in impl blocks. + SelfType { + is_ref: bool, + is_mut: bool, + }, } #[derive(Clone, Debug, Eq, Hash, PartialEq)] diff --git a/src/grammar.lalrpop b/src/grammar.lalrpop index 9f8fb9f0..0e8b18f5 100644 --- a/src/grammar.lalrpop +++ b/src/grammar.lalrpop @@ -32,6 +32,7 @@ extern { "import" => Token::KeywordImport, "extern" => Token::KeywordExtern, "as" => Token::KeywordAs, + "self" => Token::KeywordSelf, // literals "identifier" => Token::Identifier(), @@ -145,6 +146,10 @@ Ident: ast::common::Ident = { => ast::common::Ident { name, span: ast::common::Span::new(lo, hi), + }, + => ast::common::Ident { + name: name.to_string(), + span: ast::common::Span::new(lo, hi), } } @@ -311,6 +316,16 @@ Param: ast::functions::Param = { ":" => ast::functions::Param { name, r#type: param_type + }, + "self" => ast::functions::Param { + name: ast::common::Ident { + name: "self".to_string(), + span: Span::new(lo, hi), + }, + r#type: ast::types::TypeDescriptor::SelfType { + is_ref: is_ref.is_some(), + is_mut: is_mut.is_some(), + }, } } @@ -572,6 +587,7 @@ PathOp: ast::expressions::PathOp = { PathSegment: ast::expressions::PathSegment = { "." => ast::expressions::PathSegment::FieldAccess(e, Span::new(lo, hi)), + "." => ast::expressions::PathSegment::MethodCall(e, Span::new(lo, hi)), "[" "]" => ast::expressions::PathSegment::ArrayIndex(e, Span::new(lo, hi)), } diff --git a/src/ir/lowering.rs b/src/ir/lowering.rs index 2d3df9c8..f5522559 100644 --- a/src/ir/lowering.rs +++ b/src/ir/lowering.rs @@ -1739,6 +1739,7 @@ pub fn lower_path( ty = *element_type; } } + PathSegment::MethodCall(fn_call_op, span) => todo!(), } } @@ -1825,5 +1826,9 @@ pub fn lower_type( }), ), ), + TypeDescriptor::SelfType { + is_ref: _, + is_mut: _, + } => todo!(), }) } diff --git a/src/parser/mod.rs b/src/parser/mod.rs index f5ccd877..456c9fd1 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -297,6 +297,62 @@ mod ModuleName { let source = r##"mod MyMod { #[intrinsic = "simdsomething"] pub extern fn myintrinsic(); +}"##; + let lexer = Lexer::new(source); + let parser = grammar::ProgramParser::new(); + parser.parse(lexer).unwrap(); + } + + #[test] + fn parse_impl() { + let source = r##"mod MyMod { + struct A { + a: i32, + b: i32, + } + + impl A { + pub fn hello(&self, other: i32) -> i32 { + return self.a * other; + } + } + + pub fn main() -> i32 { + let x: A = A { + a: 2, + b: 3, + }; + + return x.hello(4); + } +}"##; + let lexer = Lexer::new(source); + let parser = grammar::ProgramParser::new(); + parser.parse(lexer).unwrap(); + } + + #[test] + fn parse_impl_mut() { + let source = r##"mod MyMod { + struct A { + a: i32, + b: i32, + } + + impl A { + pub fn hello(&mut self, other: i32) -> i32 { + return self.a * other; + } + } + + pub fn main() -> i32 { + let x: A = A { + a: 2, + b: 3, + }; + + return x.hello(4); + } }"##; let lexer = Lexer::new(source); let parser = grammar::ProgramParser::new(); diff --git a/src/parser/tokens.rs b/src/parser/tokens.rs index 44ffd1b3..16406068 100644 --- a/src/parser/tokens.rs +++ b/src/parser/tokens.rs @@ -61,6 +61,8 @@ pub enum Token { KeywordExtern, #[token("as")] KeywordAs, + #[token("self")] + KeywordSelf, // Modern way of allowing identifiers, read: https://unicode.org/reports/tr31/ #[regex(r"[\p{XID_Start}_]\p{XID_Continue}*", |lex| lex.slice().to_string())] From 6fe75ded36a289fd7906ba29b066a656bf2c96b5 Mon Sep 17 00:00:00 2001 From: Edgar Luque Date: Mon, 13 Jan 2025 15:11:02 +0100 Subject: [PATCH 09/18] clippy --- src/ir/lowering.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ir/lowering.rs b/src/ir/lowering.rs index f5522559..82f0c4e7 100644 --- a/src/ir/lowering.rs +++ b/src/ir/lowering.rs @@ -1739,7 +1739,7 @@ pub fn lower_path( ty = *element_type; } } - PathSegment::MethodCall(fn_call_op, span) => todo!(), + PathSegment::MethodCall(_fn_call_op, _span) => todo!(), } } From 2cd5a57e003e7854ee40d03a62f7e73cc0b00ee1 Mon Sep 17 00:00:00 2001 From: Edgar Luque Date: Tue, 14 Jan 2025 13:03:59 +0100 Subject: [PATCH 10/18] start lowering impl block --- src/ast/functions.rs | 4 ++-- src/grammar.lalrpop | 2 +- src/ir/lowering/prepass.rs | 33 ++++++++++++++++++++++++++++++++- src/ir/mod.rs | 2 ++ 4 files changed, 37 insertions(+), 4 deletions(-) diff --git a/src/ast/functions.rs b/src/ast/functions.rs index 5cf8a124..1f250b0d 100644 --- a/src/ast/functions.rs +++ b/src/ast/functions.rs @@ -1,5 +1,5 @@ use super::{ - common::{Attribute, DocString, GenericParam, Ident, Span}, + common::{Attribute, DocString, GenericParam, Ident, Span, TypeName}, statements::Statement, types::TypeDescriptor, }; @@ -32,7 +32,7 @@ pub struct Param { #[derive(Clone, Debug, Eq, PartialEq)] pub struct ImplBlock { - pub target: Ident, + pub target: TypeName, pub methods: Vec, pub span: Span, } diff --git a/src/grammar.lalrpop b/src/grammar.lalrpop index 0e8b18f5..3335b7d5 100644 --- a/src/grammar.lalrpop +++ b/src/grammar.lalrpop @@ -365,7 +365,7 @@ FunctionDef: ast::functions::FunctionDef = { } ImplBlock: ast::functions::ImplBlock = { - "impl" "{" "}" => { + "impl" "{" "}" => { ast::functions::ImplBlock { target, methods, diff --git a/src/ir/lowering/prepass.rs b/src/ir/lowering/prepass.rs index d2695833..4c273126 100644 --- a/src/ir/lowering/prepass.rs +++ b/src/ir/lowering/prepass.rs @@ -1,5 +1,8 @@ use std::collections::HashMap; +use std::io::Read; +use crate::ast::common::TypeName; +use crate::ast::types::TypeDescriptor; use crate::ir::{DefId, ModuleBody}; use crate::ast; @@ -112,7 +115,35 @@ pub fn prepass_module( ), ); } - ast::modules::ModuleDefItem::Impl(_impl_block) => todo!(), + ast::modules::ModuleDefItem::Impl(impl_block) => { + // TODO: traverse target path and deal with generics + let struct_id = current_module + .symbols + .structs + .get(&impl_block.target.name.name) + .expect("target struct not found"); + for info in &impl_block.methods { + let next_id = gen.next_defid(); + current_module + .symbols + .methods + .insert((*struct_id, info.decl.name.name.clone()), next_id); + current_module.functions.insert(next_id); + ctx.unresolved_function_signatures.insert( + next_id, + ( + [TypeDescriptor::Type { + name: impl_block.target.clone(), + span: impl_block.target.span, + }] + .into_iter() + .chain(info.decl.params.iter().map(|x| &x.r#type).cloned()) + .collect(), + info.decl.ret_type.clone(), + ), + ); + } + } } } diff --git a/src/ir/mod.rs b/src/ir/mod.rs index a1d21d08..ad950caa 100644 --- a/src/ir/mod.rs +++ b/src/ir/mod.rs @@ -21,6 +21,8 @@ pub struct SymbolTable { pub symbols: HashMap, pub modules: HashMap, pub functions: HashMap, + /// (Struct ID, Name) -> id + pub methods: HashMap<(DefId, String), DefId>, pub constants: HashMap, pub structs: HashMap, pub types: HashMap, From 6c2af6fd5a8a800e851d43199254784cd5cfe104 Mon Sep 17 00:00:00 2001 From: Edgar Luque Date: Tue, 14 Jan 2025 13:54:36 +0100 Subject: [PATCH 11/18] prog --- src/ast/functions.rs | 2 +- src/grammar.lalrpop | 2 +- src/ir/lowering.rs | 10 ++++++++-- src/ir/lowering/prepass.rs | 11 +---------- 4 files changed, 11 insertions(+), 14 deletions(-) diff --git a/src/ast/functions.rs b/src/ast/functions.rs index 1f250b0d..7731be5d 100644 --- a/src/ast/functions.rs +++ b/src/ast/functions.rs @@ -32,7 +32,7 @@ pub struct Param { #[derive(Clone, Debug, Eq, PartialEq)] pub struct ImplBlock { - pub target: TypeName, + pub target: TypeDescriptor, pub methods: Vec, pub span: Span, } diff --git a/src/grammar.lalrpop b/src/grammar.lalrpop index 3335b7d5..7915517f 100644 --- a/src/grammar.lalrpop +++ b/src/grammar.lalrpop @@ -365,7 +365,7 @@ FunctionDef: ast::functions::FunctionDef = { } ImplBlock: ast::functions::ImplBlock = { - "impl" "{" "}" => { + "impl" "{" "}" => { ast::functions::ImplBlock { target, methods, diff --git a/src/ir/lowering.rs b/src/ir/lowering.rs index 82f0c4e7..f946226c 100644 --- a/src/ir/lowering.rs +++ b/src/ir/lowering.rs @@ -162,7 +162,7 @@ fn lower_module(mut ctx: BuildCtx, module: &Module, id: DefId) -> Result { /* already processed */ } ModuleDefItem::Function(fn_def) => { - ctx = lower_func(ctx, fn_def, id)?; + ctx = lower_func(ctx, fn_def, id, None)?; } ModuleDefItem::Type(_) => todo!(), ModuleDefItem::Module(mod_def) => { @@ -176,7 +176,12 @@ fn lower_module(mut ctx: BuildCtx, module: &Module, id: DefId) -> Result { ctx = lower_func_decl(ctx, fn_decl, id)?; } - ModuleDefItem::Impl(_impl_block) => todo!(), + ModuleDefItem::Impl(impl_block) => { + let self_ty = lower_type(&ctx, &impl_block.target, id)?; + for info in &impl_block.methods { + ctx = lower_func(ctx, info, id, Some(self_ty.clone()))?; + } + }, } } @@ -302,6 +307,7 @@ fn lower_func( ctx: BuildCtx, func: &FunctionDef, module_id: DefId, + has_self: Option, ) -> Result { let is_intrinsic: Option = None; diff --git a/src/ir/lowering/prepass.rs b/src/ir/lowering/prepass.rs index 4c273126..2baa6b2a 100644 --- a/src/ir/lowering/prepass.rs +++ b/src/ir/lowering/prepass.rs @@ -116,12 +116,6 @@ pub fn prepass_module( ); } ast::modules::ModuleDefItem::Impl(impl_block) => { - // TODO: traverse target path and deal with generics - let struct_id = current_module - .symbols - .structs - .get(&impl_block.target.name.name) - .expect("target struct not found"); for info in &impl_block.methods { let next_id = gen.next_defid(); current_module @@ -132,10 +126,7 @@ pub fn prepass_module( ctx.unresolved_function_signatures.insert( next_id, ( - [TypeDescriptor::Type { - name: impl_block.target.clone(), - span: impl_block.target.span, - }] + [impl_block.target.clone()] .into_iter() .chain(info.decl.params.iter().map(|x| &x.r#type).cloned()) .collect(), From 145266a8f48f5a2a277eed4112a7b490eeb76ab4 Mon Sep 17 00:00:00 2001 From: Edgar Luque Date: Wed, 15 Jan 2025 14:03:25 +0100 Subject: [PATCH 12/18] progress --- src/ast/types.rs | 10 +++++++++- src/ir/lowering.rs | 2 +- src/ir/lowering/prepass.rs | 14 +++++++------- src/ir/mod.rs | 6 +++--- 4 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/ast/types.rs b/src/ast/types.rs index 1da8d6cf..c8c72e09 100644 --- a/src/ast/types.rs +++ b/src/ast/types.rs @@ -1,30 +1,38 @@ use super::common::{DocString, Ident, Span, TypeName}; +use educe::Educe; -#[derive(Clone, Debug, Eq, Hash, PartialEq)] +#[derive(Clone, Debug, Educe)] +#[educe(PartialEq, Eq, Hash)] pub enum TypeDescriptor { Type { name: TypeName, + #[educe(PartialEq(ignore), Hash(ignore))] span: Span, }, Ref { of: Box, + #[educe(PartialEq(ignore), Hash(ignore))] span: Span, }, MutRef { of: Box, + #[educe(PartialEq(ignore), Hash(ignore))] span: Span, }, ConstPtr { of: Box, + #[educe(PartialEq(ignore), Hash(ignore))] span: Span, }, MutPtr { of: Box, + #[educe(PartialEq(ignore), Hash(ignore))] span: Span, }, Array { of: Box, size: u64, + #[educe(PartialEq(ignore), Hash(ignore))] span: Span, }, // Used in impl blocks. diff --git a/src/ir/lowering.rs b/src/ir/lowering.rs index f946226c..96ee08ce 100644 --- a/src/ir/lowering.rs +++ b/src/ir/lowering.rs @@ -181,7 +181,7 @@ fn lower_module(mut ctx: BuildCtx, module: &Module, id: DefId) -> Result { for info in &impl_block.methods { let next_id = gen.next_defid(); - current_module - .symbols - .methods - .insert((*struct_id, info.decl.name.name.clone()), next_id); + current_module.symbols.methods.insert( + (impl_block.target.clone(), info.decl.name.name.clone()), + next_id, + ); current_module.functions.insert(next_id); ctx.unresolved_function_signatures.insert( next_id, ( [impl_block.target.clone()] - .into_iter() - .chain(info.decl.params.iter().map(|x| &x.r#type).cloned()) - .collect(), + .into_iter() + .chain(info.decl.params.iter().map(|x| &x.r#type).cloned()) + .collect(), info.decl.ret_type.clone(), ), ); diff --git a/src/ir/mod.rs b/src/ir/mod.rs index ad950caa..478cacdc 100644 --- a/src/ir/mod.rs +++ b/src/ir/mod.rs @@ -4,7 +4,7 @@ use std::{ path::PathBuf, }; -use crate::ast::common::Ident; +use crate::ast::{common::Ident, types::TypeDescriptor}; pub mod lowering; @@ -21,8 +21,8 @@ pub struct SymbolTable { pub symbols: HashMap, pub modules: HashMap, pub functions: HashMap, - /// (Struct ID, Name) -> id - pub methods: HashMap<(DefId, String), DefId>, + /// (type name, Name) -> id + pub methods: HashMap<(TypeDescriptor, String), DefId>, pub constants: HashMap, pub structs: HashMap, pub types: HashMap, From 17336da0a3f445ee2ed6470665e4bffa6d4375ff Mon Sep 17 00:00:00 2001 From: Edgar Luque Date: Thu, 16 Jan 2025 16:06:35 +0100 Subject: [PATCH 13/18] prog --- src/ir/lowering.rs | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/src/ir/lowering.rs b/src/ir/lowering.rs index 96ee08ce..a687c45d 100644 --- a/src/ir/lowering.rs +++ b/src/ir/lowering.rs @@ -177,9 +177,8 @@ fn lower_module(mut ctx: BuildCtx, module: &Module, id: DefId) -> Result { - let self_ty = lower_type(&ctx, &impl_block.target, id)?; for info in &impl_block.methods { - ctx = lower_func(ctx, info, id, Some(self_ty.clone()))?; + ctx = lower_func(ctx, info, id, Some(&impl_block.target))?; } } } @@ -307,23 +306,33 @@ fn lower_func( ctx: BuildCtx, func: &FunctionDef, module_id: DefId, - has_self: Option, + has_self: Option<&TypeDescriptor>, ) -> Result { let is_intrinsic: Option = None; // TODO: parse insintrics here. + let id = { + let body = ctx.body.modules.get(&module_id).unwrap(); + if let Some(self_ty) = has_self { + *body + .symbols + .methods + .get(&(self_ty.clone(), func.decl.name.name.clone())) + .unwrap() + } else { + *body.symbols.functions.get(&func.decl.name.name).unwrap() + } + }; + let mut builder = FnBodyBuilder { body: FnBody { basic_blocks: Vec::new(), locals: Vec::new(), is_extern: func.decl.is_extern, is_intrinsic, - name: func.decl.name.name.clone(), - id: { - let body = ctx.body.modules.get(&module_id).unwrap(); - *body.symbols.functions.get(&func.decl.name.name).unwrap() - }, + name: format!("{}_{}_{}", &func.decl.name.name, id.program_id, id.id), + id, }, local_module: module_id, ret_local: 0, @@ -346,7 +355,7 @@ fn lower_func( .functions .get(&func.decl.name.name) .unwrap(); - let (args_ty, ret_ty) = builder + let (mut args_ty, ret_ty) = builder .ctx .body .function_signatures From df1c4e9b41369bad58965199df35d2c01dc1997c Mon Sep 17 00:00:00 2001 From: Edgar Luque Date: Thu, 16 Jan 2025 17:44:21 +0100 Subject: [PATCH 14/18] prog --- src/ir/lowering.rs | 150 +++++++++++++++++++++++++++++++++---- src/ir/lowering/prepass.rs | 6 +- 2 files changed, 136 insertions(+), 20 deletions(-) diff --git a/src/ir/lowering.rs b/src/ir/lowering.rs index a687c45d..0c073c86 100644 --- a/src/ir/lowering.rs +++ b/src/ir/lowering.rs @@ -154,6 +154,65 @@ fn lower_module(mut ctx: BuildCtx, module: &Module, id: DefId) -> Result { + for fn_def in &impl_block.methods { + let fn_id = *body + .symbols + .methods + .get(&(impl_block.target.clone(), fn_def.decl.name.name.clone())) + .ok_or_else(|| LoweringError::FunctionNotFound { + span: fn_def.span, + function: fn_def.decl.name.name.clone(), + program_id: body.id.program_id, + })?; + + let mut args = Vec::new(); + let ret_type; + + let mut first_is_self = false; + if let Some(self_ty) = fn_def.decl.params.first() { + if let TypeDescriptor::SelfType { is_ref, is_mut } = self_ty.r#type { + let mut target_ty = lower_type(&ctx, &impl_block.target, id)?; + if is_ref { + target_ty = Ty { + span: target_ty.span, + kind: TyKind::Ref( + Box::new(target_ty), + if is_mut { + Mutability::Mut + } else { + Mutability::Not + }, + ), + }; + } + args.push(target_ty); + first_is_self = true; + } + } + + let mut arg_iter = fn_def.decl.params.iter(); + if first_is_self { + arg_iter.next(); + } + for arg in arg_iter { + let ty = lower_type(&ctx, &arg.r#type, id)?; + args.push(ty); + } + + if let Some(ty) = &fn_def.decl.ret_type { + ret_type = lower_type(&ctx, ty, id)?; + } else { + ret_type = Ty { + span: None, + kind: TyKind::Unit, + }; + } + + ctx.body.function_signatures.insert(fn_id, (args, ret_type)); + ctx.unresolved_function_signatures.remove(&fn_id); + } + } _ => {} } } @@ -312,7 +371,7 @@ fn lower_func( // TODO: parse insintrics here. - let id = { + let fn_id = { let body = ctx.body.modules.get(&module_id).unwrap(); if let Some(self_ty) = has_self { *body @@ -331,8 +390,8 @@ fn lower_func( locals: Vec::new(), is_extern: func.decl.is_extern, is_intrinsic, - name: format!("{}_{}_{}", &func.decl.name.name, id.program_id, id.id), - id, + name: format!("{}_{}_{}", &func.decl.name.name, fn_id.program_id, fn_id.id), + id: fn_id, }, local_module: module_id, ret_local: 0, @@ -349,13 +408,7 @@ fn lower_func( }); } - let fn_id = *builder - .get_module_body() - .symbols - .functions - .get(&func.decl.name.name) - .unwrap(); - let (mut args_ty, ret_ty) = builder + let (args_ty, ret_ty) = builder .ctx .body .function_signatures @@ -517,7 +570,7 @@ fn lower_statement( assert!(builder.statements.is_empty()); } statements::Statement::FnCall(info) => { - lower_fn_call(builder, info)?; + lower_fn_call(builder, info, None)?; } } Ok(()) @@ -1032,7 +1085,7 @@ fn lower_expression( let value = lower_value_expr(builder, info, type_hint)?; (value.0, value.1, *span) } - Expression::FnCall(info) => lower_fn_call(builder, info)?, + Expression::FnCall(info) => lower_fn_call(builder, info, None)?, Expression::Match(_) => todo!(), Expression::If(_) => todo!(), Expression::UnaryOp(_, _) => todo!(), @@ -1277,6 +1330,7 @@ fn lower_expression( fn lower_fn_call( builder: &mut FnBodyBuilder, info: &FnCallOp, + self_value: Option<(Place, Ty)>, ) -> Result<(Rvalue, Ty, Span), LoweringError> { let fn_id = { let mod_body = builder.get_module_body(); @@ -1306,7 +1360,14 @@ fn lower_fn_call( let args: Vec = args .iter() - .map(|arg| lower_type(&builder.ctx, arg, builder.local_module)) + .map(|arg| { + lower_type_with_self( + &builder.ctx, + arg, + builder.local_module, + self_value.as_ref().map(|x| &x.1), + ) + }) .collect::, _>>()?; let ret = ret .as_ref() @@ -1691,7 +1752,7 @@ pub fn lower_path( builder: &mut FnBodyBuilder, info: &PathOp, ) -> Result<(Place, Ty, Span), LoweringError> { - let local = *builder.name_to_local.get(&info.first.name).ok_or( + let mut local = *builder.name_to_local.get(&info.first.name).ok_or( LoweringError::UseOfUndeclaredVariable { span: info.span, name: info.first.name.clone(), @@ -1754,13 +1815,72 @@ pub fn lower_path( ty = *element_type; } } - PathSegment::MethodCall(_fn_call_op, _span) => todo!(), + PathSegment::MethodCall(fn_call_op, _span) => { + // auto deref + while let TyKind::Ref(inner, _) = ty.kind { + projection.push(PlaceElem::Deref); + ty = *inner; + } + + let (value, new_ty, _span) = lower_fn_call( + builder, + fn_call_op, + Some(( + Place { + local, + projection: projection.clone(), + }, + ty.clone(), + )), + )?; + + ty = new_ty; + + match value { + Rvalue::Use(operand) => match operand { + Operand::Place(place) => { + local = place.local; + projection = place.projection; + } + Operand::Const(_const_data) => todo!(), + }, + Rvalue::Ref(_mutability, _place) => todo!(), + _ => unreachable!(), + } + } } } Ok((Place { local, projection }, ty, info.span)) } +pub fn lower_type_with_self( + ctx: &BuildCtx, + ty: &TypeDescriptor, + module_id: DefId, + self_ty: Option<&Ty>, +) -> Result { + if let TypeDescriptor::SelfType { is_ref, is_mut } = ty { + let self_ty = self_ty.unwrap().clone(); + if *is_ref { + return Ok(Ty { + span: self_ty.span, + kind: TyKind::Ref( + Box::new(self_ty), + if *is_mut { + Mutability::Mut + } else { + Mutability::Not + }, + ), + }); + } + Ok(self_ty) + } else { + lower_type(&ctx, ty, module_id) + } +} + pub fn lower_type( ctx: &BuildCtx, ty: &TypeDescriptor, diff --git a/src/ir/lowering/prepass.rs b/src/ir/lowering/prepass.rs index f51882e5..ae9bebe2 100644 --- a/src/ir/lowering/prepass.rs +++ b/src/ir/lowering/prepass.rs @@ -1,9 +1,5 @@ -use std::collections::HashMap; -use std::io::Read; - -use crate::ast::common::TypeName; -use crate::ast::types::TypeDescriptor; use crate::ir::{DefId, ModuleBody}; +use std::collections::HashMap; use crate::ast; use crate::ir::lowering::{common::BuildCtx, errors::LoweringError}; From 022e3f4c265fc2269143ebac21aa51631feb0dc2 Mon Sep 17 00:00:00 2001 From: Edgar Luque Date: Tue, 21 Jan 2025 14:16:28 +0100 Subject: [PATCH 15/18] works --- .gitignore | 4 ++ src/ast/functions.rs | 2 +- src/codegen/compiler.rs | 9 ++- src/ir/lowering.rs | 118 +++++++++++++++++++++++++++++----------- src/ir/mod.rs | 22 ++++---- 5 files changed, 110 insertions(+), 45 deletions(-) diff --git a/.gitignore b/.gitignore index 76f87cfd..f4e0fdb1 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,7 @@ build/ *.so *.a +*.mlir +*.ast +*.ll +*.ir diff --git a/src/ast/functions.rs b/src/ast/functions.rs index 7731be5d..bf416ed8 100644 --- a/src/ast/functions.rs +++ b/src/ast/functions.rs @@ -1,5 +1,5 @@ use super::{ - common::{Attribute, DocString, GenericParam, Ident, Span, TypeName}, + common::{Attribute, DocString, GenericParam, Ident, Span}, statements::Statement, types::TypeDescriptor, }; diff --git a/src/codegen/compiler.rs b/src/codegen/compiler.rs index 3e87dc2d..5fe25f5f 100644 --- a/src/codegen/compiler.rs +++ b/src/codegen/compiler.rs @@ -1425,7 +1425,7 @@ fn compile_value_tree<'c: 'b, 'b>( FloatAttribute::new( ctx.context(), Type::float32(ctx.context()), - (*value).into(), + value.parse().unwrap(), ) .into(), Location::unknown(ctx.context()), @@ -1435,7 +1435,12 @@ fn compile_value_tree<'c: 'b, 'b>( crate::ir::ConstValue::F64(value) => block .append_operation(arith::constant( ctx.context(), - FloatAttribute::new(ctx.context(), Type::float64(ctx.context()), *value).into(), + FloatAttribute::new( + ctx.context(), + Type::float64(ctx.context()), + value.parse().unwrap(), + ) + .into(), Location::unknown(ctx.context()), )) .result(0)? diff --git a/src/ir/lowering.rs b/src/ir/lowering.rs index 0c073c86..1e826fdd 100644 --- a/src/ir/lowering.rs +++ b/src/ir/lowering.rs @@ -169,6 +169,8 @@ fn lower_module(mut ctx: BuildCtx, module: &Module, id: DefId) -> Result Result { - lower_fn_call(builder, info, None)?; + lower_fn_call(builder, info, None, None)?; } } Ok(()) @@ -1085,7 +1096,7 @@ fn lower_expression( let value = lower_value_expr(builder, info, type_hint)?; (value.0, value.1, *span) } - Expression::FnCall(info) => lower_fn_call(builder, info, None)?, + Expression::FnCall(info) => lower_fn_call(builder, info, None, None)?, Expression::Match(_) => todo!(), Expression::If(_) => todo!(), Expression::UnaryOp(_, _) => todo!(), @@ -1331,11 +1342,15 @@ fn lower_fn_call( builder: &mut FnBodyBuilder, info: &FnCallOp, self_value: Option<(Place, Ty)>, + // The id of the fn to call, in case its a method. + fn_id: Option, ) -> Result<(Rvalue, Ty, Span), LoweringError> { let fn_id = { let mod_body = builder.get_module_body(); - if let Some(id) = mod_body.symbols.functions.get(&info.target.name) { + if let Some(id) = fn_id { + id + } else if let Some(id) = mod_body.symbols.functions.get(&info.target.name) { *id } else { *mod_body @@ -1385,7 +1400,15 @@ fn lower_fn_call( } }; - if args_ty.len() != info.args.len() { + if args_ty.len() + != info.args.len() + { + if self_value.is_some() { + 1 + } else { + 0 + } + } + { return Err(LoweringError::CallParamCountMismatch { span: info.span, found: info.args.len(), @@ -1396,7 +1419,24 @@ fn lower_fn_call( let mut args = Vec::new(); - for (arg, arg_ty) in info.args.iter().zip(args_ty) { + let mut args_ty_iter = args_ty.into_iter(); + + // Add the self value if there is one. + if let Some((arg, _arg_ty)) = self_value { + // Here arg_ty is the type without references. + // We should use the type from the fn sig to know if it needs a reference. + let expected_ty = args_ty_iter.next().expect("self ty should be there"); + match expected_ty.kind { + TyKind::Ref(_, mutability) => { + args.push(Rvalue::Ref(mutability, arg.clone())); + } + _ => { + args.push(Rvalue::Use(Operand::Place(arg.clone()))); + } + } + } + + for (arg, arg_ty) in info.args.iter().zip(args_ty_iter) { let (rvalue, rvalue_ty, arg_span) = lower_expression(builder, arg, Some(arg_ty.clone()))?; if rvalue_ty.kind != arg_ty.kind { @@ -1817,35 +1857,49 @@ pub fn lower_path( } PathSegment::MethodCall(fn_call_op, _span) => { // auto deref - while let TyKind::Ref(inner, _) = ty.kind { - projection.push(PlaceElem::Deref); - ty = *inner; - } - let (value, new_ty, _span) = lower_fn_call( - builder, - fn_call_op, - Some(( - Place { - local, - projection: projection.clone(), - }, - ty.clone(), - )), - )?; - - ty = new_ty; + loop { + if let Some(methods) = builder.ctx.body.methods.get(&ty.kind) { + if let Some(defid) = methods.get(&fn_call_op.target.name) { + let (value, new_ty, _span) = lower_fn_call( + builder, + fn_call_op, + Some(( + Place { + local, + projection: projection.clone(), + }, + ty.clone(), + )), + Some(*defid), + )?; + + ty = new_ty; + + match value { + Rvalue::Use(operand) => match operand { + Operand::Place(place) => { + local = place.local; + projection = place.projection; + } + Operand::Const(_const_data) => todo!(), + }, + Rvalue::Ref(_mutability, _place) => todo!(), + _ => unreachable!(), + } - match value { - Rvalue::Use(operand) => match operand { - Operand::Place(place) => { - local = place.local; - projection = place.projection; + break; } - Operand::Const(_const_data) => todo!(), - }, - Rvalue::Ref(_mutability, _place) => todo!(), - _ => unreachable!(), + } else if let TyKind::Ref(inner, _) = ty.kind { + projection.push(PlaceElem::Deref); + ty = *inner; + } else { + Err(LoweringError::FunctionNotFound { + span: fn_call_op.target.span, + function: fn_call_op.target.name.clone(), + program_id: builder.local_module.program_id, + })?; + } } } } diff --git a/src/ir/mod.rs b/src/ir/mod.rs index 478cacdc..338a885b 100644 --- a/src/ir/mod.rs +++ b/src/ir/mod.rs @@ -37,6 +37,8 @@ pub struct ProgramBody { pub modules: BTreeMap, /// This stores all the functions from all modules pub functions: BTreeMap, + /// Impl block methods. + pub methods: BTreeMap>, /// This stores all the structs from all modules pub structs: BTreeMap, /// The function signatures. @@ -332,8 +334,8 @@ pub struct DefId { } /// A type -#[derive(Debug, Clone, Educe, PartialOrd)] -#[educe(PartialEq)] +#[derive(Debug, Clone, Educe, PartialOrd, Ord, Eq)] +#[educe(PartialEq, Hash)] pub struct Ty { #[educe(PartialEq(ignore))] pub span: Option, @@ -349,7 +351,7 @@ impl Ty { } } -#[derive(Debug, Clone, PartialEq, PartialOrd)] +#[derive(Debug, Clone, PartialEq, PartialOrd, Ord, Eq, Hash)] pub enum TyKind { Unit, // () Bool, @@ -548,13 +550,13 @@ pub enum FloatTy { F64, } -#[derive(Debug, Clone, PartialEq, PartialOrd)] +#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)] pub struct ConstData { pub ty: Ty, pub data: ConstKind, } -#[derive(Debug, Clone, PartialEq, PartialOrd)] +#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)] pub enum ConstKind { /// A generic parameter constant. Param(ParamConst), @@ -573,7 +575,7 @@ pub struct ParamConst { } /// Constant data, in case the data is complex such as an array it will be a branch with leaf values. -#[derive(Debug, Clone, PartialEq, PartialOrd)] +#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)] // https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/consts/valtree/enum.ValTree.html pub enum ValueTree { Leaf(ConstValue), @@ -581,7 +583,7 @@ pub enum ValueTree { } /// Constant expression -#[derive(Debug, Clone, PartialEq, PartialOrd)] +#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)] pub enum ConstExpr { Binop(BinOp, ConstData, ConstData), UnOp(UnOp, ConstData), @@ -620,7 +622,7 @@ pub enum UnOp { Neg, } -#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)] +#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)] pub enum ConstValue { Bool(bool), Char(u8), @@ -634,8 +636,8 @@ pub enum ConstValue { U32(u32), U64(u64), U128(u128), - F32(f32), - F64(f64), + F32(String), + F64(String), } #[derive(Debug, Clone, Copy, PartialEq, PartialOrd)] From b2d4c05e53a61aae9f1c061d4eff87489b0a5c51 Mon Sep 17 00:00:00 2001 From: Edgar Luque Date: Tue, 21 Jan 2025 14:21:24 +0100 Subject: [PATCH 16/18] test --- examples/impl_block.con | 21 +++++++++++++++++++++ src/ast/common.rs | 2 +- tests/examples.rs | 1 + 3 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 examples/impl_block.con diff --git a/examples/impl_block.con b/examples/impl_block.con new file mode 100644 index 00000000..6aafd73e --- /dev/null +++ b/examples/impl_block.con @@ -0,0 +1,21 @@ +mod ImplBlock { + struct A { + a: i64, + b: i64, + } + + impl A { + pub fn hello(&self, other: i64) -> i64 { + return self.a * other; + } + } + + pub fn main() -> i64 { + let x: A = A { + a: 2, + b: 3, + }; + + return x.hello(4); + } +} diff --git a/src/ast/common.rs b/src/ast/common.rs index 294019c9..0ac89ed3 100644 --- a/src/ast/common.rs +++ b/src/ast/common.rs @@ -31,7 +31,7 @@ pub struct Ident { } /// A type name, supporting fully qualified paths and generics: -/// ``` +/// ```text /// std::module::X /// ``` /// Used only when specifying types. diff --git a/tests/examples.rs b/tests/examples.rs index c3725291..021f165b 100644 --- a/tests/examples.rs +++ b/tests/examples.rs @@ -8,6 +8,7 @@ mod common; #[test_case(include_str!("../examples/factorial_if.con"), "factorial_if", false, 24 ; "factorial_if.con")] #[test_case(include_str!("../examples/fib_if.con"), "fib_if", false, 55 ; "fib_if.con")] #[test_case(include_str!("../examples/import.con"), "import", false, 12 ; "import.con")] +#[test_case(include_str!("../examples/impl_block.con"), "impl_block", false, 8 ; "impl_block.con")] #[test_case(include_str!("../examples/simple.con"), "simple", false, 8 ; "simple.con")] #[test_case(include_str!("../examples/while.con"), "while", false, 16 ; "while.con")] #[test_case(include_str!("../examples/chars.con"), "chars", false, 117 ; "chars.con")] From 065f5b86355d0d344b68de8dc20ff09581ed15eb Mon Sep 17 00:00:00 2001 From: Edgar Luque Date: Tue, 21 Jan 2025 14:25:22 +0100 Subject: [PATCH 17/18] fix --- Cargo.lock | 159 +++++----------------------------------- Cargo.toml | 2 +- src/codegen/compiler.rs | 1 + src/ir/lowering.rs | 2 +- 4 files changed, 20 insertions(+), 144 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6b6c34e4..a4bd09d5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -123,29 +123,6 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1" -[[package]] -name = "bindgen" -version = "0.69.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" -dependencies = [ - "bitflags 2.7.0", - "cexpr", - "clang-sys", - "itertools 0.12.1", - "lazy_static", - "lazycell", - "log", - "prettyplease", - "proc-macro2", - "quote", - "regex", - "rustc-hash 1.1.0", - "shlex", - "syn", - "which", -] - [[package]] name = "bindgen" version = "0.71.1" @@ -161,7 +138,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "rustc-hash 2.1.0", + "rustc-hash", "shlex", "syn", ] @@ -202,31 +179,6 @@ dependencies = [ "generic-array", ] -[[package]] -name = "bon" -version = "3.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe7acc34ff59877422326db7d6f2d845a582b16396b6b08194942bf34c6528ab" -dependencies = [ - "bon-macros", - "rustversion", -] - -[[package]] -name = "bon-macros" -version = "3.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4159dd617a7fbc9be6a692fe69dc2954f8e6bb6bb5e4d7578467441390d77fd0" -dependencies = [ - "darling", - "ident_case", - "prettyplease", - "proc-macro2", - "quote", - "rustversion", - "syn", -] - [[package]] name = "bumpalo" version = "3.16.0" @@ -327,16 +279,13 @@ checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" [[package]] name = "comrak" -version = "0.32.0" +version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48ae8f3e7e3f3d424cbb33354fc36943d507327d210aa5794b0192f4be726c6d" +checksum = "39bff2cbb80102771ca62bd2375bc6f6611dc1493373440b23aa08a155538708" dependencies = [ - "bon", "caseless", "entities", "memchr", - "once_cell", - "regex", "slug", "typed-arena", "unicode_categories", @@ -393,9 +342,9 @@ dependencies = [ [[package]] name = "convert_case" -version = "0.6.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" +checksum = "bb402b8d4c85569410425650ce3eddc7d698ed96d39a73f941b08fb63082f1e7" dependencies = [ "unicode-segmentation", ] @@ -475,41 +424,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "darling" -version = "0.20.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" -dependencies = [ - "darling_core", - "darling_macro", -] - -[[package]] -name = "darling_core" -version = "0.20.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim", - "syn", -] - -[[package]] -name = "darling_macro" -version = "0.20.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" -dependencies = [ - "darling_core", - "quote", - "syn", -] - [[package]] name = "dashmap" version = "6.1.0" @@ -852,12 +766,6 @@ dependencies = [ "syn", ] -[[package]] -name = "ident_case" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" - [[package]] name = "idna" version = "1.0.3" @@ -906,15 +814,6 @@ version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" -[[package]] -name = "itertools" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" -dependencies = [ - "either", -] - [[package]] name = "itertools" version = "0.13.0" @@ -989,12 +888,6 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" -[[package]] -name = "lazycell" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" - [[package]] name = "libc" version = "0.2.169" @@ -1149,9 +1042,9 @@ dependencies = [ [[package]] name = "melior" -version = "0.20.2" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cfcb398e6571361b6f54fd0057066d9b47a822bcb797bf5867e5412e9e6f387" +checksum = "f2af6454b7bcd7edc8c2060a3726a18ceaed60e25c34d9f8de9c6b44e82eb647" dependencies = [ "melior-macro", "mlir-sys", @@ -1159,9 +1052,9 @@ dependencies = [ [[package]] name = "melior-macro" -version = "0.13.2" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3086e8c12eb1999d636595cc3c2aee82a28d4bb80163267d51bd66a617cdaefc" +checksum = "a99671327250df8e24e56d8304474a970e7a2c6bb8f6dc71382d188136fe4d1b" dependencies = [ "comrak", "convert_case", @@ -1169,7 +1062,7 @@ dependencies = [ "quote", "regex", "syn", - "tblgen-alt", + "tblgen", "unindent", ] @@ -1191,7 +1084,7 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "21b598f9c0fa7a453eeaa9fe419ae93759c94a66eb6f8a496d195ba596ae3c4d" dependencies = [ - "bindgen 0.71.1", + "bindgen", ] [[package]] @@ -1441,12 +1334,6 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - [[package]] name = "rustc-hash" version = "2.1.0" @@ -1495,7 +1382,7 @@ dependencies = [ "lazy_static", "parking_lot", "rayon", - "rustc-hash 2.1.0", + "rustc-hash", "salsa-macro-rules", "salsa-macros", "smallvec", @@ -1664,15 +1551,15 @@ dependencies = [ ] [[package]] -name = "tblgen-alt" -version = "0.4.0" +name = "tblgen" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ecbc9175dd38627cd01d546e7b41c9a115e5773f4c98f64e2185c81ec5f45ab" +checksum = "c155c9310c9e11e6f642b4c8a30ae572ea0cad013d5c9e28bb264b52fa8163bb" dependencies = [ - "bindgen 0.69.5", + "bindgen", "cc", "paste", - "thiserror 1.0.69", + "thiserror 2.0.11", ] [[package]] @@ -2089,18 +1976,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "which" -version = "4.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" -dependencies = [ - "either", - "home", - "once_cell", - "rustix", -] - [[package]] name = "winapi" version = "0.3.9" diff --git a/Cargo.toml b/Cargo.toml index 88e4b9d6..774398e4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,7 @@ ariadne = { version = "0.5.0", features = ["auto-color"] } unescaper = "0.1.5" logos-display = "0.1.3" -melior = { version = "0.20.2", features = ["ods-dialects", "helpers"] } +melior = { version = "0.21.0", features = ["ods-dialects", "helpers"] } llvm-sys = "191.0.0" mlir-sys = "0.4.1" anyhow = "1.0.95" diff --git a/src/codegen/compiler.rs b/src/codegen/compiler.rs index 5fe25f5f..d581d4fc 100644 --- a/src/codegen/compiler.rs +++ b/src/codegen/compiler.rs @@ -5,6 +5,7 @@ use crate::ir::{ ProgramBody, Rvalue, Span, Ty, TyKind, ValueTree, }; use crate::session::Session; +use melior::ir::BlockLike; use melior::{ dialect::{ arith, cf, func, diff --git a/src/ir/lowering.rs b/src/ir/lowering.rs index 1e826fdd..e5afc604 100644 --- a/src/ir/lowering.rs +++ b/src/ir/lowering.rs @@ -1931,7 +1931,7 @@ pub fn lower_type_with_self( } Ok(self_ty) } else { - lower_type(&ctx, ty, module_id) + lower_type(ctx, ty, module_id) } } From 3218a9af990b4dc5f3e5f058bac4c116d5cff141 Mon Sep 17 00:00:00 2001 From: Edgar Luque Date: Thu, 23 Jan 2025 12:50:44 +0100 Subject: [PATCH 18/18] add method call as statement --- examples/impl_block_mut.con | 28 ++++++++++++++++++++++++++++ src/ast/statements.rs | 2 ++ src/grammar.lalrpop | 1 + src/ir/lowering.rs | 3 +++ tests/examples.rs | 1 + 5 files changed, 35 insertions(+) create mode 100644 examples/impl_block_mut.con diff --git a/examples/impl_block_mut.con b/examples/impl_block_mut.con new file mode 100644 index 00000000..b767ba39 --- /dev/null +++ b/examples/impl_block_mut.con @@ -0,0 +1,28 @@ +mod ImplBlockMut { + struct A { + a: i32, + b: i32, + } + + impl A { + pub fn hello(&self, other: i32) -> i32 { + return self.a * other; + } + + pub fn set_a(&mut self, value: i32) { + self.a = value; + return; + } + } + + pub fn main() -> i32 { + let mut x: A = A { + a: 2, + b: 3, + }; + + x.set_a(4); + + return x.a; + } +} diff --git a/src/ast/statements.rs b/src/ast/statements.rs index 7bbb28ca..2bb0b706 100644 --- a/src/ast/statements.rs +++ b/src/ast/statements.rs @@ -14,6 +14,8 @@ pub enum Statement { Return(ReturnStmt), While(WhileStmt), FnCall(FnCallOp), + // To allow method calls. + PathOp(PathOp), } #[derive(Clone, Debug, Eq, PartialEq)] diff --git a/src/grammar.lalrpop b/src/grammar.lalrpop index 7915517f..0540d5b5 100644 --- a/src/grammar.lalrpop +++ b/src/grammar.lalrpop @@ -625,6 +625,7 @@ Statement: ast::statements::Statement = { ";" => ast::statements::Statement::Let(<>), ";" => ast::statements::Statement::Assign(<>), ";" => ast::statements::Statement::FnCall(<>), + ";" => ast::statements::Statement::PathOp(<>), ";" => ast::statements::Statement::Return(<>), } diff --git a/src/ir/lowering.rs b/src/ir/lowering.rs index e5afc604..b524b4bc 100644 --- a/src/ir/lowering.rs +++ b/src/ir/lowering.rs @@ -583,6 +583,9 @@ fn lower_statement( statements::Statement::FnCall(info) => { lower_fn_call(builder, info, None, None)?; } + statements::Statement::PathOp(info) => { + lower_path(builder, info)?; + } } Ok(()) } diff --git a/tests/examples.rs b/tests/examples.rs index 021f165b..d85a60ca 100644 --- a/tests/examples.rs +++ b/tests/examples.rs @@ -9,6 +9,7 @@ mod common; #[test_case(include_str!("../examples/fib_if.con"), "fib_if", false, 55 ; "fib_if.con")] #[test_case(include_str!("../examples/import.con"), "import", false, 12 ; "import.con")] #[test_case(include_str!("../examples/impl_block.con"), "impl_block", false, 8 ; "impl_block.con")] +#[test_case(include_str!("../examples/impl_block_mut.con"), "impl_block_mut", false, 4 ; "impl_block_mut.con")] #[test_case(include_str!("../examples/simple.con"), "simple", false, 8 ; "simple.con")] #[test_case(include_str!("../examples/while.con"), "while", false, 16 ; "while.con")] #[test_case(include_str!("../examples/chars.con"), "chars", false, 117 ; "chars.con")]