refactor module structure, clean up diagnostic reporting
This commit is contained in:
parent
e723335db6
commit
de9d979ce5
11 changed files with 222 additions and 227 deletions
158
Cargo.lock
generated
158
Cargo.lock
generated
|
@ -20,23 +20,11 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "arrayref"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544"
|
||||
|
||||
[[package]]
|
||||
name = "arrayvec"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
|
||||
|
||||
[[package]]
|
||||
name = "ascii-canvas"
|
||||
version = "2.0.0"
|
||||
version = "3.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ff8eb72df928aafb99fe5d37b383f2fe25bd2a765e3e5f7c365916b6f2463a29"
|
||||
checksum = "8824ecca2e851cec16968d54a01dd372ef8f95b244fb84b84e70128be347c3c6"
|
||||
dependencies = [
|
||||
"term",
|
||||
]
|
||||
|
@ -58,12 +46,6 @@ version = "1.0.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
|
||||
|
||||
[[package]]
|
||||
name = "beef"
|
||||
version = "0.5.0"
|
||||
|
@ -86,21 +68,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb"
|
||||
|
||||
[[package]]
|
||||
name = "blake2b_simd"
|
||||
version = "0.5.11"
|
||||
name = "bitflags"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587"
|
||||
dependencies = [
|
||||
"arrayref",
|
||||
"arrayvec",
|
||||
"constant_time_eq",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
||||
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
|
@ -131,29 +102,12 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "constant_time_eq"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
|
||||
|
||||
[[package]]
|
||||
name = "convert_case"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e"
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4feb231f0d4d6af81aed15928e58ecf5816aa62a2393e2c82f46973e92a9a278"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cfg-if",
|
||||
"lazy_static",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crunchy"
|
||||
version = "0.2.2"
|
||||
|
@ -190,10 +144,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "0e25ea47919b1560c4e3b7fe0aaab9becf5b84a10325ddf7db0f0ba5e1026499"
|
||||
|
||||
[[package]]
|
||||
name = "dirs"
|
||||
version = "1.0.5"
|
||||
name = "dirs-next"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fd78930633bd1c6e35c4b42b1df7b0cbc6bc191146e512bb3bedf243fcc3901"
|
||||
checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"dirs-sys-next",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs-sys-next"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"redox_users",
|
||||
|
@ -262,9 +226,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
|||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.1.16"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
|
||||
checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
|
@ -273,9 +237,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.9.1"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04"
|
||||
checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
|
@ -288,18 +252,18 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.18"
|
||||
version = "0.1.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c"
|
||||
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "1.6.2"
|
||||
version = "1.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "824845a0bf897a9042383849b02c1bc219c2383772efcd5c6f9766fa4b81aef3"
|
||||
checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"hashbrown",
|
||||
|
@ -322,9 +286,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.10.0"
|
||||
version = "0.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "37d572918e350e82412fe766d24b15e6682fb2ed2bbe018280caa810397cb319"
|
||||
checksum = "69ddb889f9d0d08a67338271fa9b62996bc788c7796a5c18cf057420aaed5eaf"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
@ -337,9 +301,9 @@ checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736"
|
|||
|
||||
[[package]]
|
||||
name = "lalrpop"
|
||||
version = "0.19.5"
|
||||
version = "0.19.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "46962a8c71b91c3524b117dfdd70844d4265a173c4c9109f98171aebdcf1195f"
|
||||
checksum = "b15174f1c529af5bf1283c3bc0058266b483a67156f79589fab2a25e23cf8988"
|
||||
dependencies = [
|
||||
"ascii-canvas",
|
||||
"atty",
|
||||
|
@ -360,9 +324,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "lalrpop-util"
|
||||
version = "0.19.5"
|
||||
version = "0.19.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a708007b751af124d09e9c5d97515257902bc6b486a56b40bcafd939e8ff467"
|
||||
checksum = "d3e58cce361efcc90ba8a0a5f982c741ff86b603495bb15a998412e957dcd278"
|
||||
dependencies = [
|
||||
"regex",
|
||||
]
|
||||
|
@ -375,9 +339,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
|||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.94"
|
||||
version = "0.2.98"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "18794a8ad5b29321f790b55d93dfba91e125cb1a9edbd4f8e3150acc771c1a5e"
|
||||
checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790"
|
||||
|
||||
[[package]]
|
||||
name = "linked-hash-map"
|
||||
|
@ -475,9 +439,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "pico-args"
|
||||
version = "0.4.1"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7d7afeb98c5a10e0bffcc7fc16e105b04d06729fac5fd6384aebf7ff5cb5a67d"
|
||||
checksum = "db8bcd96cb740d03149cbad5518db9fd87126a10ab519c011893b1754134c468"
|
||||
|
||||
[[package]]
|
||||
name = "precomputed-hash"
|
||||
|
@ -517,19 +481,21 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.1.57"
|
||||
version = "0.2.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
|
||||
checksum = "5ab49abadf3f9e1c4bc499e8845e152ad87d2ad2d30371841171169e9d75feee"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_users"
|
||||
version = "0.3.5"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d"
|
||||
checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"redox_syscall",
|
||||
"rust-argon2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -549,18 +515,6 @@ version = "0.6.25"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
|
||||
|
||||
[[package]]
|
||||
name = "rust-argon2"
|
||||
version = "0.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4b18820d944b33caa75a71378964ac46f58517c92b6ae5f762636247c09e78fb"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"blake2b_simd",
|
||||
"constant_time_eq",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.3.3"
|
||||
|
@ -570,6 +524,12 @@ dependencies = [
|
|||
"semver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustversion"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "61b3909d758bb75c79f23d4736fac9433868679d3ad2ea7a61e3c25cfda9a088"
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.5"
|
||||
|
@ -722,12 +682,12 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "term"
|
||||
version = "0.5.2"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "edd106a334b7657c10b7c540a0106114feadeb4dc314513e97df481d5d966f42"
|
||||
checksum = "c59df8ac95d96ff9bede18eb7300b0fda5e5d8d90960e76f8e14ae765eedbf1f"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"dirs",
|
||||
"dirs-next",
|
||||
"rustversion",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
|
@ -752,18 +712,18 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.25"
|
||||
version = "1.0.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa6f76457f59514c7eeb4e59d891395fab0b2fd1d40723ae737d64153392e9c6"
|
||||
checksum = "93119e4feac1cbe6c798c34d3a53ea0026b0b1de6a120deef895137c0529bfe2"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.25"
|
||||
version = "1.0.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a36768c0fbf1bb15eca10defa29526bda730a2376c2ab4393ccfa16fb1a318d"
|
||||
checksum = "060d69a0afe7796bf42e9e2ff91f5ee691fb15c53d38b4b62a9a53eb23164745"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -817,9 +777,9 @@ checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
|
|||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.9.0+wasi-snapshot-preview1"
|
||||
version = "0.10.2+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
|
||||
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
|
|
0
src/config/mod.rs
Normal file
0
src/config/mod.rs
Normal file
|
@ -1,4 +1,4 @@
|
|||
use crate::{
|
||||
use crate::parser::{
|
||||
ast::{Ast, AstType, Span},
|
||||
lexer, parse_error,
|
||||
};
|
||||
|
|
|
@ -1,42 +1,60 @@
|
|||
use codespan_reporting::{diagnostic, files};
|
||||
use simplexpr::dynval;
|
||||
|
||||
use crate::{ast::Span, error::AstError, parse_error};
|
||||
use diagnostic::*;
|
||||
|
||||
fn span_to_label(span: Span) -> Label<usize> {
|
||||
Label::primary(span.2, span.0..span.1)
|
||||
use crate::error::AstError;
|
||||
|
||||
use super::parser::{ast::Span, parse_error};
|
||||
|
||||
macro_rules! gen_diagnostic {
|
||||
(
|
||||
$(msg = $msg:expr)?
|
||||
$(, label = $span:expr $(=> $label:expr)?)?
|
||||
$(, note = $note:expr)? $(,)?
|
||||
) => {
|
||||
Diagnostic::error()
|
||||
$(.with_message($msg))?
|
||||
$(.with_labels(vec![
|
||||
Label::primary($span.2, $span.0..$span.1)
|
||||
$(.with_message($label))?
|
||||
]))?
|
||||
$(.with_notes(vec![$note]))?
|
||||
};
|
||||
($msg:expr $(, $span:expr $(,)?)?) => {{
|
||||
Diagnostic::error()
|
||||
.with_message($msg)
|
||||
$(.with_labels(vec![Label::primary($span.2, $span.0..$span.1)]))?
|
||||
}};
|
||||
}
|
||||
|
||||
pub trait ToDiagnostic {
|
||||
fn to_diagnostic(&self, files: &files::SimpleFiles<&str, &str>) -> Diagnostic<usize>;
|
||||
fn to_diagnostic(&self) -> Diagnostic<usize>;
|
||||
}
|
||||
|
||||
impl ToDiagnostic for AstError {
|
||||
fn to_diagnostic(&self, files: &files::SimpleFiles<&str, &str>) -> Diagnostic<usize> {
|
||||
fn to_diagnostic(&self) -> Diagnostic<usize> {
|
||||
let diag = Diagnostic::error();
|
||||
if let Some(span) = self.get_span() {
|
||||
use lalrpop_util::ParseError::*;
|
||||
match self {
|
||||
AstError::InvalidDefinition(_) => todo!(),
|
||||
|
||||
AstError::MissingNode(_, expected) => diag
|
||||
.with_message(format!("Missing {}", expected))
|
||||
.with_labels(vec![span_to_label(span).with_message(format!("Expected `{}` here", expected))]),
|
||||
AstError::MissingNode(_, expected) => gen_diagnostic! {
|
||||
msg = format!("Missing {}", expected),
|
||||
label = span => format!("Expected `{}` here", expected),
|
||||
},
|
||||
|
||||
AstError::WrongExprType(_, expected, actual) => diag
|
||||
.with_message("Wrong type of expression")
|
||||
.with_notes(vec![format!("Expected: {}\nGot: {}", expected, actual)])
|
||||
.with_labels(vec![span_to_label(span).with_message(format!("Expected a `{}` here", expected))]),
|
||||
AstError::WrongExprType(_, expected, actual) => gen_diagnostic! {
|
||||
msg = "Wrong type of expression",
|
||||
label = span => format!("Expected a `{}` here", expected),
|
||||
note = format!("Expected: {}\nGot: {}", expected, actual),
|
||||
},
|
||||
|
||||
AstError::ParseError { file_id, source } => {
|
||||
lalrpop_error_to_diagnostic(source, diag, span, move |diag, error| match error {
|
||||
parse_error::ParseError::SimplExpr(_, error) => simplexpr_error_to_diagnostic(error, diag, span),
|
||||
parse_error::ParseError::LexicalError(_) => diag
|
||||
.with_message("Invalid token")
|
||||
.with_labels(vec![span_to_label(span).with_message("Invalid token")]),
|
||||
})
|
||||
}
|
||||
AstError::ParseError { file_id, source } => lalrpop_error_to_diagnostic(source, span, |error| match error {
|
||||
parse_error::ParseError::SimplExpr(_, error) => simplexpr_error_to_diagnostic(error, span),
|
||||
parse_error::ParseError::LexicalError(_) => lexical_error_to_diagnostic(span),
|
||||
}),
|
||||
}
|
||||
} else {
|
||||
diag.with_message(format!("{}", self))
|
||||
|
@ -46,36 +64,47 @@ impl ToDiagnostic for AstError {
|
|||
|
||||
fn lalrpop_error_to_diagnostic<T: std::fmt::Display, E>(
|
||||
error: &lalrpop_util::ParseError<usize, T, E>,
|
||||
diag: Diagnostic<usize>,
|
||||
span: Span,
|
||||
handle_user_error: impl FnOnce(Diagnostic<usize>, &E) -> Diagnostic<usize>,
|
||||
handle_user_error: impl FnOnce(&E) -> Diagnostic<usize>,
|
||||
) -> Diagnostic<usize> {
|
||||
use lalrpop_util::ParseError::*;
|
||||
match error {
|
||||
InvalidToken { location } => diag.with_message("Invalid token").with_labels(vec![span_to_label(span)]),
|
||||
UnrecognizedEOF { location, expected } => diag
|
||||
.with_message("Input ended unexpectedly. Check if you have any unclosed delimiters")
|
||||
.with_labels(vec![span_to_label(span)]),
|
||||
UnrecognizedToken { token, expected } => diag
|
||||
.with_message(format!("Unexpected token `{}` encoutered", token.1))
|
||||
.with_labels(vec![span_to_label(span).with_message("Token unexpected")]),
|
||||
|
||||
ExtraToken { token } => diag.with_message(format!("Extra token encountered: `{}`", token.1)),
|
||||
User { error } => handle_user_error(diag, error),
|
||||
InvalidToken { location } => gen_diagnostic! { msg = "Invalid token", label = span },
|
||||
UnrecognizedEOF { location, expected } => gen_diagnostic! {
|
||||
msg = "Input ended unexpectedly. Check if you have any unclosed delimiters",
|
||||
label = span
|
||||
},
|
||||
UnrecognizedToken { token, expected } => gen_diagnostic! {
|
||||
msg = format!("Unexpected token `{}` encountered", token.1),
|
||||
label = span => "Token unexpected",
|
||||
},
|
||||
ExtraToken { token } => gen_diagnostic!(format!("Extra token encountered: `{}`", token.1)),
|
||||
User { error } => handle_user_error(error),
|
||||
}
|
||||
}
|
||||
|
||||
fn simplexpr_error_to_diagnostic(error: &simplexpr::error::Error, diag: Diagnostic<usize>, span: Span) -> Diagnostic<usize> {
|
||||
fn simplexpr_error_to_diagnostic(error: &simplexpr::error::Error, span: Span) -> Diagnostic<usize> {
|
||||
use simplexpr::error::Error::*;
|
||||
match error {
|
||||
simplexpr::error::Error::ParseError { source } => lalrpop_error_to_diagnostic(source, diag, span, move |diag, error| {
|
||||
diag.with_message("Invalid token").with_labels(vec![span_to_label(span).with_message("Invalid token")])
|
||||
}),
|
||||
simplexpr::error::Error::ConversionError(dynval::ConversionError { value, target_type, source }) => diag
|
||||
.with_message(format!("{}", error))
|
||||
.with_labels(vec![span_to_label(span).with_message(format!("{} is not of type `{}`", value, target_type))])
|
||||
.with_notes(source.as_ref().map(|x| vec![format!("{}", x)]).unwrap_or_default()),
|
||||
simplexpr::error::Error::Spanned(..) => todo!(),
|
||||
simplexpr::error::Error::Eval(error) => diag.with_message(format!("{}", error)).with_labels(vec![span_to_label(span)]),
|
||||
simplexpr::error::Error::Other(error) => diag.with_message(format!("{}", error)).with_labels(vec![span_to_label(span)]),
|
||||
ParseError { source } => lalrpop_error_to_diagnostic(source, span, move |error| lexical_error_to_diagnostic(span)),
|
||||
ConversionError(error) => conversion_error_to_diagnostic(error, span),
|
||||
Eval(error) => gen_diagnostic!(format!("{}", error), span),
|
||||
Other(error) => gen_diagnostic!(format!("{}", error), span),
|
||||
Spanned(_, error) => gen_diagnostic!(format!("{}", error), span),
|
||||
}
|
||||
}
|
||||
|
||||
fn conversion_error_to_diagnostic(error: &dynval::ConversionError, span: Span) -> Diagnostic<usize> {
|
||||
let diag = gen_diagnostic! {
|
||||
msg = format!("{}", error),
|
||||
label = span => format!("{} is not of type `{}`", error.value, error.target_type),
|
||||
};
|
||||
diag.with_notes(error.source.as_ref().map(|x| vec![format!("{}", x)]).unwrap_or_default())
|
||||
}
|
||||
|
||||
fn lexical_error_to_diagnostic(span: Span) -> Diagnostic<usize> {
|
||||
gen_diagnostic! {
|
||||
msg = "Invalid token",
|
||||
label = span => "Invalid token"
|
||||
}
|
||||
}
|
||||
|
|
61
src/lib.rs
61
src/lib.rs
|
@ -2,67 +2,8 @@
|
|||
#![allow(unused)]
|
||||
#![feature(try_blocks)]
|
||||
|
||||
pub mod ast;
|
||||
pub mod config;
|
||||
pub mod error;
|
||||
pub mod format_diagnostic;
|
||||
mod lexer;
|
||||
mod parse_error;
|
||||
pub mod parser;
|
||||
pub mod value;
|
||||
|
||||
use ast::Ast;
|
||||
use error::{AstError, AstResult};
|
||||
|
||||
use std::{fmt::Display, ops::Deref};
|
||||
|
||||
use itertools::Itertools;
|
||||
|
||||
use lalrpop_util::lalrpop_mod;
|
||||
|
||||
lalrpop_mod!(
|
||||
#[allow(clippy::all)]
|
||||
pub parser
|
||||
);
|
||||
|
||||
pub fn parse_string(file_id: usize, s: &str) -> AstResult<Ast> {
|
||||
let lexer = lexer::Lexer::new(file_id, s.to_string());
|
||||
let parser = parser::AstParser::new();
|
||||
parser.parse(file_id, lexer).map_err(|e| AstError::from_parse_error(file_id, e))
|
||||
}
|
||||
|
||||
macro_rules! test_parser {
|
||||
($($text:literal),*) => {{
|
||||
let p = crate::parser::AstParser::new();
|
||||
use crate::lexer::Lexer;
|
||||
|
||||
::insta::with_settings!({sort_maps => true}, {
|
||||
$(
|
||||
::insta::assert_debug_snapshot!(p.parse(0, Lexer::new(0, $text.to_string())));
|
||||
)*
|
||||
});
|
||||
}}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
test_parser!(
|
||||
"1",
|
||||
"(12)",
|
||||
"1.2",
|
||||
"-1.2",
|
||||
"(1 2)",
|
||||
"(1 :foo 1)",
|
||||
"(:foo 1)",
|
||||
"(:foo->: 1)",
|
||||
"(foo 1)",
|
||||
"(lol😄 1)",
|
||||
r#"(test "hi")"#,
|
||||
r#"(test "h\"i")"#,
|
||||
r#"(test " hi ")"#,
|
||||
"(+ (1 2 (* 2 5)))",
|
||||
r#"; test"#,
|
||||
r#"(f arg ; test
|
||||
arg2)"#,
|
||||
"\"h\\\"i\""
|
||||
);
|
||||
}
|
||||
|
|
|
@ -2,9 +2,11 @@ use itertools::Itertools;
|
|||
use simplexpr::ast::SimplExpr;
|
||||
use std::collections::HashMap;
|
||||
|
||||
use crate::{config::FromAst, error::*};
|
||||
use std::fmt::Display;
|
||||
|
||||
use super::element::FromAst;
|
||||
use crate::error::{AstError, AstResult};
|
||||
|
||||
#[derive(Eq, PartialEq, Clone, Copy)]
|
||||
pub struct Span(pub usize, pub usize, pub usize);
|
||||
|
||||
|
@ -124,15 +126,16 @@ impl std::fmt::Display for Ast {
|
|||
impl std::fmt::Debug for Ast {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
use Ast::*;
|
||||
match self {
|
||||
List(span, x) => f.debug_tuple(&format!("List<{}>", span)).field(x).finish(),
|
||||
Array(span, x) => f.debug_tuple(&format!("Array<{}>", span)).field(x).finish(),
|
||||
Keyword(span, x) => write!(f, "Number<{}>({})", span, x),
|
||||
Symbol(span, x) => write!(f, "Symbol<{}>({})", span, x),
|
||||
Value(span, x) => write!(f, "Value<{}>({})", span, x),
|
||||
SimplExpr(span, x) => write!(f, "SimplExpr<{}>({})", span, x),
|
||||
Comment(span) => write!(f, "Comment<{}>", span),
|
||||
}
|
||||
write!(f, "{}", self)
|
||||
// match self {
|
||||
// List(span, x) => f.debug_tuple(&format!("List<{}>", span)).field(x).finish(),
|
||||
// Array(span, x) => f.debug_tuple(&format!("Array<{}>", span)).field(x).finish(),
|
||||
// Keyword(span, x) => write!(f, "Number<{}>({})", span, x),
|
||||
// Symbol(span, x) => write!(f, "Symbol<{}>({})", span, x),
|
||||
// Value(span, x) => write!(f, "Value<{}>({})", span, x),
|
||||
// SimplExpr(span, x) => write!(f, "SimplExpr<{}>({})", span, x),
|
||||
// Comment(span) => write!(f, "Comment<{}>", span),
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +1,5 @@
|
|||
use crate::{
|
||||
ast::{Ast, AstIterator, AstType, Span},
|
||||
error::*,
|
||||
parser, spanned,
|
||||
};
|
||||
use super::ast::{Ast, AstIterator, AstType, Span};
|
||||
use crate::{error::*, parser, spanned};
|
||||
use itertools::Itertools;
|
||||
use std::{
|
||||
collections::{HashMap, LinkedList},
|
||||
|
@ -49,13 +46,17 @@ impl<C: FromAst, A: FromAst> FromAst for Element<C, A> {
|
|||
#[cfg(test)]
|
||||
mod test {
|
||||
|
||||
use super::*;
|
||||
use crate::lexer;
|
||||
use super::super::{
|
||||
ast::Ast,
|
||||
element::{Element, FromAst},
|
||||
lexer,
|
||||
};
|
||||
|
||||
use insta;
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
let parser = parser::AstParser::new();
|
||||
let parser = super::parser::parser::AstParser::new();
|
||||
insta::with_settings!({sort_maps => true}, {
|
||||
let lexer = lexer::Lexer::new(0, "(box :bar 12 :baz \"hi\" foo (bar))".to_string());
|
||||
insta::assert_debug_snapshot!(
|
|
@ -1,6 +1,6 @@
|
|||
use regex::{Regex, RegexSet};
|
||||
|
||||
use crate::{ast::Span, parse_error};
|
||||
use super::{ast::Span, parse_error};
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
pub enum Token {
|
62
src/parser/mod.rs
Normal file
62
src/parser/mod.rs
Normal file
|
@ -0,0 +1,62 @@
|
|||
use lalrpop_util::lalrpop_mod;
|
||||
|
||||
use super::error::{AstError, AstResult};
|
||||
use ast::Ast;
|
||||
|
||||
use std::{fmt::Display, ops::Deref};
|
||||
|
||||
use itertools::Itertools;
|
||||
|
||||
pub mod ast;
|
||||
pub mod element;
|
||||
pub(crate) mod lexer;
|
||||
pub(crate) mod parse_error;
|
||||
|
||||
lalrpop_mod!(
|
||||
#[allow(clippy::all)]
|
||||
pub parser,
|
||||
"/parser/parser.rs"
|
||||
);
|
||||
|
||||
pub fn parse_string(file_id: usize, s: &str) -> AstResult<Ast> {
|
||||
let lexer = lexer::Lexer::new(file_id, s.to_string());
|
||||
let parser = parser::AstParser::new();
|
||||
parser.parse(file_id, lexer).map_err(|e| AstError::from_parse_error(file_id, e))
|
||||
}
|
||||
|
||||
macro_rules! test_parser {
|
||||
($($text:literal),*) => {{
|
||||
let p = parser::AstParser::new();
|
||||
use lexer::Lexer;
|
||||
|
||||
::insta::with_settings!({sort_maps => true}, {
|
||||
$(
|
||||
::insta::assert_debug_snapshot!(p.parse(0, Lexer::new(0, $text.to_string())));
|
||||
)*
|
||||
});
|
||||
}}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
test_parser!(
|
||||
"1",
|
||||
"(12)",
|
||||
"1.2",
|
||||
"-1.2",
|
||||
"(1 2)",
|
||||
"(1 :foo 1)",
|
||||
"(:foo 1)",
|
||||
"(:foo->: 1)",
|
||||
"(foo 1)",
|
||||
"(lol😄 1)",
|
||||
r#"(test "hi")"#,
|
||||
r#"(test "h\"i")"#,
|
||||
r#"(test " hi ")"#,
|
||||
"(+ (1 2 (* 2 5)))",
|
||||
r#"; test"#,
|
||||
r#"(f arg ; test
|
||||
arg2)"#,
|
||||
"\"h\\\"i\""
|
||||
);
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
use crate::ast::Span;
|
||||
use super::ast::Span;
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum ParseError {
|
|
@ -1,6 +1,5 @@
|
|||
use std::str::FromStr;
|
||||
use crate::lexer::{Token};
|
||||
use crate::ast::{Ast, Span};
|
||||
use crate::parser::{lexer::{Token}, ast::{Ast, Span}, parse_error};
|
||||
use simplexpr::ast::SimplExpr;
|
||||
use simplexpr;
|
||||
use lalrpop_util::ParseError;
|
||||
|
@ -9,7 +8,7 @@ grammar(file_id: usize);
|
|||
|
||||
extern {
|
||||
type Location = usize;
|
||||
type Error = crate::parse_error::ParseError;
|
||||
type Error = parse_error::ParseError;
|
||||
|
||||
enum Token {
|
||||
"(" => Token::LPren,
|
||||
|
@ -58,7 +57,7 @@ SimplExpr: SimplExpr = {
|
|||
let expr = x[1..x.len() - 1].to_string();
|
||||
simplexpr::parse_string(&expr).map_err(|e| {
|
||||
let span = e.get_span().map(|simplexpr::Span(simpl_l, simpl_r)| Span(1 + l + simpl_l, 1 + l + simpl_r, file_id));
|
||||
ParseError::User { error: crate::parse_error::ParseError::SimplExpr(span, e) }})
|
||||
ParseError::User { error: parse_error::ParseError::SimplExpr(span, e) }})
|
||||
}
|
||||
}
|
||||
|
Loading…
Add table
Reference in a new issue