mirror of
https://github.com/Noratrieb/ub.git
synced 2026-01-14 08:35:06 +01:00
salsa
This commit is contained in:
parent
2fd78566a3
commit
6260ca0307
7 changed files with 430 additions and 71 deletions
302
Cargo.lock
generated
302
Cargo.lock
generated
|
|
@ -11,6 +11,23 @@ dependencies = [
|
|||
"const-random",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ahash"
|
||||
version = "0.7.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"once_cell",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "arc-swap"
|
||||
version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6"
|
||||
|
||||
[[package]]
|
||||
name = "ariadne"
|
||||
version = "0.1.5"
|
||||
|
|
@ -20,12 +37,24 @@ dependencies = [
|
|||
"yansi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "beef"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
|
|
@ -38,7 +67,7 @@ version = "0.8.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8d02796e4586c6c41aeb68eae9bfb4558a522c35f1430c14b40136c3706e09e4"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"ahash 0.3.8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -50,7 +79,7 @@ dependencies = [
|
|||
"encode_unicode",
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"windows-sys",
|
||||
"windows-sys 0.42.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -75,18 +104,108 @@ dependencies = [
|
|||
"tiny-keccak",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2801af0d36612ae591caa9568261fddce32ce6e08a7275ea334a06a4ad021a2c"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"crossbeam-channel",
|
||||
"crossbeam-deque",
|
||||
"crossbeam-epoch",
|
||||
"crossbeam-queue",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-channel"
|
||||
version = "0.5.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf2b3e8478797446514c91ef04bafcb59faba183e621ad488df88983cc14128c"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-deque"
|
||||
version = "0.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"crossbeam-epoch",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-epoch"
|
||||
version = "0.9.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "46bd5f3f85273295a9d14aedfb86f6aadbff6d8f5295c4a9edb08e819dcf5695"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cfg-if",
|
||||
"crossbeam-utils",
|
||||
"memoffset",
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-queue"
|
||||
version = "0.3.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d1cfb3ea8a53f37c40dea2c7bedcbd88bdfae54f5e2175d6ecaff1c988353add"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crunchy"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
|
||||
|
||||
[[package]]
|
||||
name = "dashmap"
|
||||
version = "5.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "907076dfda823b0b36d2a1bb5f90c96660a5bbcd7729e10727f07858f22c4edc"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"hashbrown",
|
||||
"lock_api",
|
||||
"once_cell",
|
||||
"parking_lot_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "encode_unicode"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
|
||||
|
||||
[[package]]
|
||||
name = "eyre"
|
||||
version = "0.6.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c2b6b5a29c02cdc822728b7d7b8ae1bab3e3b05d44522770ddd49722eeac7eb"
|
||||
dependencies = [
|
||||
"indenter",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fnv"
|
||||
version = "1.0.7"
|
||||
|
|
@ -104,6 +223,46 @@ dependencies = [
|
|||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
||||
dependencies = [
|
||||
"ahash 0.7.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashlink"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "69fe1fcf8b4278d860ad0548329f892a3631fb63f82574df68275f34cdbe0ffa"
|
||||
dependencies = [
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
|
||||
|
||||
[[package]]
|
||||
name = "indenter"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683"
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "1.9.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "insta"
|
||||
version = "1.28.0"
|
||||
|
|
@ -135,6 +294,25 @@ version = "0.5.6"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "logos"
|
||||
version = "0.12.1"
|
||||
|
|
@ -158,12 +336,44 @@ dependencies = [
|
|||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.17.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3"
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
|
||||
dependencies = [
|
||||
"lock_api",
|
||||
"parking_lot_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot_core"
|
||||
version = "0.9.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"smallvec",
|
||||
"windows-sys 0.45.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-hack"
|
||||
version = "0.5.20+deprecated"
|
||||
|
|
@ -188,18 +398,75 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||
|
||||
[[package]]
|
||||
name = "salsa-2022"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/salsa-rs/salsa?rev=ef7c0f12c8159e7025316e959c26f6278a576fa5#ef7c0f12c8159e7025316e959c26f6278a576fa5"
|
||||
dependencies = [
|
||||
"arc-swap",
|
||||
"crossbeam",
|
||||
"crossbeam-utils",
|
||||
"dashmap",
|
||||
"hashlink",
|
||||
"indexmap",
|
||||
"log",
|
||||
"parking_lot",
|
||||
"rustc-hash",
|
||||
"salsa-2022-macros",
|
||||
"smallvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "salsa-2022-macros"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/salsa-rs/salsa?rev=ef7c0f12c8159e7025316e959c26f6278a576fa5#ef7c0f12c8159e7025316e959c26f6278a576fa5"
|
||||
dependencies = [
|
||||
"eyre",
|
||||
"heck",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||
|
||||
[[package]]
|
||||
name = "similar"
|
||||
version = "2.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "420acb44afdae038210c99e69aae24109f32f15500aa708e81d46c9f29d55fcf"
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.109"
|
||||
|
|
@ -228,6 +495,7 @@ dependencies = [
|
|||
"chumsky",
|
||||
"insta",
|
||||
"logos",
|
||||
"salsa-2022",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -236,6 +504,12 @@ version = "1.0.7"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "775c11906edafc97bc378816b94585fbd9a054eabaf86fdd0ced94af449efab7"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
|
|
@ -257,6 +531,30 @@ dependencies = [
|
|||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.45.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.42.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.42.1"
|
||||
|
|
|
|||
|
|
@ -10,5 +10,10 @@ ariadne = "0.1.5"
|
|||
chumsky = "0.8.0"
|
||||
logos = "0.12.0"
|
||||
|
||||
[dependencies.salsa]
|
||||
git = "https://github.com/salsa-rs/salsa"
|
||||
rev = "ef7c0f12c8159e7025316e959c26f6278a576fa5"
|
||||
package = "salsa-2022"
|
||||
|
||||
[dev-dependencies]
|
||||
insta = "1.13.0"
|
||||
|
|
|
|||
43
src/ast.rs
43
src/ast.rs
|
|
@ -1,36 +1,35 @@
|
|||
use std::{ops::Range, path::PathBuf};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct NodeId(u32);
|
||||
|
||||
type Span = Range<usize>;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct File {
|
||||
pub name: PathBuf,
|
||||
pub items: Vec<Item>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct Ty {
|
||||
pub span: Span,
|
||||
pub kind: TyKind,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum TyKind {
|
||||
U64,
|
||||
Ptr(Box<Ty>),
|
||||
Name(String),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum Item {
|
||||
FnDecl(FnDecl),
|
||||
StructDecl(StructDecl),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct FnDecl {
|
||||
pub name: String,
|
||||
pub params: Vec<NameTyPair>,
|
||||
|
|
@ -40,7 +39,7 @@ pub struct FnDecl {
|
|||
pub body: Vec<Stmt>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct NameTyPair {
|
||||
pub name: String,
|
||||
pub ty: Ty,
|
||||
|
|
@ -48,7 +47,7 @@ pub struct NameTyPair {
|
|||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct StructDecl {
|
||||
pub name: String,
|
||||
pub fields: Vec<NameTyPair>,
|
||||
|
|
@ -56,7 +55,7 @@ pub struct StructDecl {
|
|||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum Stmt {
|
||||
VarDecl(VarDecl),
|
||||
Assignment(Assignment),
|
||||
|
|
@ -67,7 +66,7 @@ pub enum Stmt {
|
|||
Expr(Expr),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct VarDecl {
|
||||
pub name: String,
|
||||
pub ty: Option<Ty>,
|
||||
|
|
@ -75,14 +74,14 @@ pub struct VarDecl {
|
|||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct Assignment {
|
||||
pub place: Expr,
|
||||
pub rhs: Expr,
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct IfStmt {
|
||||
pub cond: Expr,
|
||||
pub body: Vec<Stmt>,
|
||||
|
|
@ -90,33 +89,33 @@ pub struct IfStmt {
|
|||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum ElsePart {
|
||||
Else(Vec<Stmt>, Span),
|
||||
ElseIf(Box<IfStmt>),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct WhileStmt {
|
||||
pub cond: Expr,
|
||||
pub body: Vec<Stmt>,
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct LoopStmt {
|
||||
pub body: Vec<Stmt>,
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct Expr {
|
||||
pub kind: ExprKind,
|
||||
pub id: NodeId,
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum ExprKind {
|
||||
BinOp(BinOp),
|
||||
UnaryOp(UnaryOp),
|
||||
|
|
@ -127,7 +126,7 @@ pub enum ExprKind {
|
|||
Array(Vec<Expr>),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct BinOp {
|
||||
pub kind: BinOpKind,
|
||||
pub lhs: Box<Expr>,
|
||||
|
|
@ -157,7 +156,7 @@ pub enum BinOpKind {
|
|||
Xor,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct UnaryOp {
|
||||
pub expr: Box<Expr>,
|
||||
pub kind: UnaryOpKind,
|
||||
|
|
@ -172,13 +171,13 @@ pub enum UnaryOpKind {
|
|||
AddrOf,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct FieldAccess {
|
||||
pub expr: Box<Expr>,
|
||||
pub field_name: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct Call {
|
||||
pub callee: Box<Expr>,
|
||||
pub args: Vec<Expr>,
|
||||
|
|
|
|||
20
src/lexer.rs
20
src/lexer.rs
|
|
@ -3,7 +3,7 @@ use std::fmt::{Debug, Display, Formatter};
|
|||
use logos::Logos;
|
||||
|
||||
#[derive(Logos, Debug, Clone, Hash, PartialEq, Eq)]
|
||||
pub enum Token<'a> {
|
||||
pub enum Token {
|
||||
#[regex("//[^\n]*", logos::skip)]
|
||||
Comment,
|
||||
|
||||
|
|
@ -83,21 +83,21 @@ pub enum Token<'a> {
|
|||
#[token("let")]
|
||||
Let,
|
||||
|
||||
#[regex(r"[a-zA-Z_]\w*")]
|
||||
Ident(&'a str),
|
||||
#[regex(r"[a-zA-Z_]\w*", |lex| lex.slice().to_string())]
|
||||
Ident(String),
|
||||
|
||||
#[regex(r##""[^"]*""##)]
|
||||
String(&'a str),
|
||||
#[regex(r##""[^"]*""##, |lex| lex.slice().to_string())]
|
||||
String(String),
|
||||
|
||||
#[regex(r"\d+")]
|
||||
Integer(&'a str),
|
||||
#[regex(r"\d+", |lex| lex.slice().parse())]
|
||||
Integer(u64),
|
||||
|
||||
#[error]
|
||||
#[regex(r"[ \t\r\n]+", logos::skip)]
|
||||
Error,
|
||||
}
|
||||
|
||||
impl<'a> Display for Token<'a> {
|
||||
impl Display for Token {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Token::Comment => f.write_str("comment"),
|
||||
|
|
@ -145,7 +145,7 @@ impl<'a> Display for Token<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn lex<'src>(code: &'src str) -> logos::Lexer<'_, Token<'src>> {
|
||||
pub fn lex<'src>(code: &'src str) -> logos::Lexer<'_, Token> {
|
||||
Token::lexer(code)
|
||||
}
|
||||
|
||||
|
|
@ -153,7 +153,7 @@ pub fn lex<'src>(code: &'src str) -> logos::Lexer<'_, Token<'src>> {
|
|||
mod tests {
|
||||
use crate::lexer::Token;
|
||||
|
||||
fn lex_test(str: &str) -> Vec<Token<'_>> {
|
||||
fn lex_test(str: &str) -> Vec<Token> {
|
||||
let lexer = super::lex(str);
|
||||
lexer.collect()
|
||||
}
|
||||
|
|
|
|||
40
src/lib.rs
40
src/lib.rs
|
|
@ -5,7 +5,6 @@ use std::path::PathBuf;
|
|||
|
||||
use ariadne::{Color, Fmt, Label, Report, ReportKind, Source};
|
||||
use chumsky::prelude::Simple;
|
||||
use logos::Logos;
|
||||
|
||||
use crate::lexer::Token;
|
||||
|
||||
|
|
@ -14,10 +13,34 @@ mod lexer;
|
|||
mod parser;
|
||||
mod pretty;
|
||||
|
||||
pub fn parse(_str: &str, _file_name: PathBuf) -> Result<ast::File, ()> {
|
||||
todo!()
|
||||
#[salsa::input]
|
||||
pub struct SourceProgram {
|
||||
#[return_ref]
|
||||
pub text: String,
|
||||
#[return_ref]
|
||||
pub file_name: PathBuf,
|
||||
}
|
||||
|
||||
#[salsa::jar(db = Db)]
|
||||
pub struct Jar(SourceProgram, Diagnostics, crate::parser::parse);
|
||||
|
||||
pub trait Db: salsa::DbWithJar<Jar> {}
|
||||
|
||||
impl<DB> Db for DB where DB: ?Sized + salsa::DbWithJar<Jar> {}
|
||||
|
||||
#[salsa::accumulator]
|
||||
pub struct Diagnostics(Simple<Token>);
|
||||
|
||||
#[derive(Default)]
|
||||
#[salsa::db(crate::Jar)]
|
||||
pub(crate) struct Database {
|
||||
storage: salsa::Storage<Self>,
|
||||
}
|
||||
|
||||
impl salsa::Database for Database {}
|
||||
|
||||
// aaa
|
||||
|
||||
pub fn test() {
|
||||
let src = "
|
||||
fn main(uwu: u64, owo: ptr WOW) -> ptr u64 {
|
||||
|
|
@ -34,11 +57,10 @@ fn main(uwu: u64, owo: ptr WOW) -> ptr u64 {
|
|||
fn aa() {}
|
||||
";
|
||||
|
||||
let lexer = Token::lexer(src);
|
||||
let len = lexer.source().len();
|
||||
let state = parser::ParserState::default();
|
||||
let db = Database::default();
|
||||
let source_program = SourceProgram::new(&db, src.to_string(), "uwu.ub".into());
|
||||
|
||||
let (file, errors) = parser::parse(lexer.spanned(), &state, len, "test_file".into());
|
||||
let (file, errors) = parser::parse(&db, source_program);
|
||||
|
||||
if let Some(file) = file {
|
||||
println!("{}", pretty::pretty_print_ast(&file));
|
||||
|
|
@ -47,10 +69,10 @@ fn aa() {}
|
|||
report_errors(src, errors);
|
||||
}
|
||||
|
||||
fn report_errors(src: &str, errors: Vec<Simple<Token<'_>>>) {
|
||||
fn report_errors(src: &str, errors: Vec<parser::Error>) {
|
||||
errors
|
||||
.into_iter()
|
||||
.map(|e| e.map(|c| c.to_string()))
|
||||
.map(|e| e.0.map(|c| c.to_string()))
|
||||
.for_each(|e| {
|
||||
let report = Report::build(ReportKind::Error, (), e.span().start);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use std::{cell::Cell, ops::Range, path::PathBuf};
|
||||
|
||||
use chumsky::{prelude::*, Stream};
|
||||
use logos::Logos;
|
||||
|
||||
use crate::{
|
||||
ast::{
|
||||
|
|
@ -9,10 +10,34 @@ use crate::{
|
|||
WhileStmt,
|
||||
},
|
||||
lexer::Token,
|
||||
SourceProgram,
|
||||
};
|
||||
|
||||
type Error<'src> = Simple<Token<'src>>;
|
||||
type Span = Range<usize>;
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct Error(pub chumsky::error::Simple<Token>);
|
||||
|
||||
impl Eq for Error {}
|
||||
|
||||
impl chumsky::Error<Token> for Error {
|
||||
type Span = Span;
|
||||
type Label = &'static str;
|
||||
fn expected_input_found<Iter: IntoIterator<Item = Option<Token>>>(
|
||||
span: Self::Span,
|
||||
expected: Iter,
|
||||
found: Option<Token>,
|
||||
) -> Self {
|
||||
Self(<_>::expected_input_found(span, expected, found))
|
||||
}
|
||||
fn with_label(self, label: Self::Label) -> Self {
|
||||
Self(self.0.with_label(label))
|
||||
}
|
||||
|
||||
fn merge(self, other: Self) -> Self {
|
||||
Self(self.0.merge(other.0))
|
||||
}
|
||||
}
|
||||
|
||||
pub type Span = Range<usize>;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct ParserState {
|
||||
|
|
@ -27,19 +52,25 @@ impl ParserState {
|
|||
}
|
||||
}
|
||||
|
||||
fn ident_parser<'src>() -> impl Parser<Token<'src>, String, Error = Error<'src>> + Clone {
|
||||
fn ident_parser() -> impl Parser<Token, String, Error = Error> + Clone {
|
||||
let ident = select! {
|
||||
Token::Ident(ident) => ident.to_owned(),
|
||||
};
|
||||
ident.labelled("identifier").boxed()
|
||||
}
|
||||
|
||||
fn ty_parser<'src>() -> impl Parser<Token<'src>, Ty, Error = Error<'src>> + Clone {
|
||||
fn ty_parser() -> impl Parser<Token, Ty, Error = Error> + Clone {
|
||||
recursive(|ty_parser| {
|
||||
let primitive = filter_map(|span, token| {
|
||||
let kind = match token {
|
||||
Token::Ident("u64") => TyKind::U64,
|
||||
_ => return Err(Simple::expected_input_found(span, Vec::new(), Some(token))),
|
||||
Token::Ident(name) => TyKind::Name(name),
|
||||
_ => {
|
||||
return Err(Error(Simple::expected_input_found(
|
||||
span,
|
||||
Vec::new(),
|
||||
Some(token),
|
||||
)))
|
||||
}
|
||||
};
|
||||
Ok(Ty { span, kind })
|
||||
})
|
||||
|
|
@ -66,7 +97,7 @@ fn ty_parser<'src>() -> impl Parser<Token<'src>, Ty, Error = Error<'src>> + Clon
|
|||
|
||||
fn expr_parser<'src>(
|
||||
state: &'src ParserState,
|
||||
) -> impl Parser<Token<'src>, Expr, Error = Error<'src>> + Clone + 'src {
|
||||
) -> impl Parser<Token, Expr, Error = Error> + Clone + 'src {
|
||||
recursive(|expr| {
|
||||
let literal = filter_map(|span: Span, token| match token {
|
||||
Token::String(str) => Ok(Expr {
|
||||
|
|
@ -79,11 +110,15 @@ fn expr_parser<'src>(
|
|||
}),
|
||||
// todo lol unwrap
|
||||
Token::Integer(int) => Ok(Expr {
|
||||
kind: ExprKind::Literal(Literal::Integer(int.parse().unwrap(), span.clone())),
|
||||
kind: ExprKind::Literal(Literal::Integer(int, span.clone())),
|
||||
id: state.next_id(),
|
||||
span,
|
||||
}),
|
||||
_ => Err(Simple::expected_input_found(span, Vec::new(), Some(token))),
|
||||
_ => Err(Error(Simple::expected_input_found(
|
||||
span,
|
||||
Vec::new(),
|
||||
Some(token),
|
||||
))),
|
||||
})
|
||||
.labelled("literal");
|
||||
|
||||
|
|
@ -231,7 +266,7 @@ fn expr_parser<'src>(
|
|||
|
||||
fn statement_parser<'src>(
|
||||
state: &'src ParserState,
|
||||
) -> impl Parser<Token<'src>, Stmt, Error = Error<'src>> + Clone {
|
||||
) -> impl Parser<Token, Stmt, Error = Error> + Clone + 'src {
|
||||
recursive(|stmt| {
|
||||
let var_decl = just(Token::Let)
|
||||
.ignore_then(ident_parser())
|
||||
|
|
@ -308,7 +343,7 @@ fn statement_parser<'src>(
|
|||
|
||||
fn name_ty_pair_parser<'src>(
|
||||
state: &'src ParserState,
|
||||
) -> impl Parser<Token<'src>, NameTyPair, Error = Error<'src>> + Clone {
|
||||
) -> impl Parser<Token, NameTyPair, Error = Error> + Clone + 'src {
|
||||
ident_parser()
|
||||
.then_ignore(just(Token::Colon))
|
||||
.then(ty_parser())
|
||||
|
|
@ -322,7 +357,7 @@ fn name_ty_pair_parser<'src>(
|
|||
|
||||
fn struct_parser<'src>(
|
||||
state: &'src ParserState,
|
||||
) -> impl Parser<Token<'src>, StructDecl, Error = Error<'src>> + Clone {
|
||||
) -> impl Parser<Token, StructDecl, Error = Error> + Clone + 'src {
|
||||
let name = just(Token::Struct).ignore_then(ident_parser());
|
||||
|
||||
let fields = name_ty_pair_parser(state)
|
||||
|
|
@ -341,7 +376,7 @@ fn struct_parser<'src>(
|
|||
|
||||
fn item_parser<'src>(
|
||||
state: &'src ParserState,
|
||||
) -> impl Parser<Token<'src>, Item, Error = Error<'src>> + Clone {
|
||||
) -> impl Parser<Token, Item, Error = Error> + Clone + 'src {
|
||||
// ---- function
|
||||
|
||||
let name = ident_parser();
|
||||
|
|
@ -383,7 +418,7 @@ fn item_parser<'src>(
|
|||
fn file_parser<'src>(
|
||||
file_name: PathBuf,
|
||||
state: &'src ParserState,
|
||||
) -> impl Parser<Token<'src>, File, Error = Error<'src>> + Clone {
|
||||
) -> impl Parser<Token, File, Error = Error> + Clone + 'src {
|
||||
item_parser(state)
|
||||
.repeated()
|
||||
.then_ignore(end())
|
||||
|
|
@ -394,20 +429,18 @@ fn file_parser<'src>(
|
|||
.labelled("file")
|
||||
}
|
||||
|
||||
pub fn parse<'src, I>(
|
||||
lexer: I,
|
||||
state: &'src ParserState,
|
||||
len: usize,
|
||||
file_name: PathBuf,
|
||||
) -> (Option<File>, Vec<Error<'src>>)
|
||||
where
|
||||
I: 'src,
|
||||
I: Iterator<Item = (Token<'src>, Span)>,
|
||||
{
|
||||
file_parser(file_name, state).parse_recovery_verbose(Stream::from_iter(len..len + 1, lexer))
|
||||
#[salsa::tracked]
|
||||
pub fn parse(db: &dyn crate::Db, source: SourceProgram) -> (Option<File>, Vec<Error>) {
|
||||
let lexer = Token::lexer(source.text(db));
|
||||
let len = lexer.source().len();
|
||||
let state = ParserState::default();
|
||||
|
||||
let result = file_parser(source.file_name(db).clone(), &state)
|
||||
.parse_recovery_verbose(Stream::from_iter(len..len + 1, lexer.spanned()));
|
||||
result
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[cfg(disabled)]
|
||||
mod tests {
|
||||
use std::{fmt::Debug, path::PathBuf};
|
||||
|
||||
|
|
@ -492,7 +525,10 @@ mod tests {
|
|||
fn var_decl() {
|
||||
let state = ParserState::default();
|
||||
|
||||
let r = parse("fn foo() -> u64 { let hello: u64 = 5; let owo = 0; let nice: u64; let nothing; }", &state);
|
||||
let r = parse(
|
||||
"fn foo() -> u64 { let hello: u64 = 5; let owo = 0; let nice: u64; let nothing; }",
|
||||
&state,
|
||||
);
|
||||
insta::assert_debug_snapshot!(r);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -71,7 +71,6 @@ impl Printer {
|
|||
|
||||
fn print_ty(&mut self, ty: &Ty) {
|
||||
match &ty.kind {
|
||||
TyKind::U64 => self.word("u64"),
|
||||
TyKind::Name(name) => self.word(name),
|
||||
TyKind::Ptr(ty) => {
|
||||
self.word("ptr ");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue