This commit is contained in:
nora 2023-03-04 12:14:33 +01:00
parent 2fd78566a3
commit 6260ca0307
7 changed files with 430 additions and 71 deletions

302
Cargo.lock generated
View file

@ -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"

View file

@ -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"

View file

@ -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>,

View file

@ -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()
}

View file

@ -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);

View file

@ -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);
}

View file

@ -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 ");