Improve API and errors
This commit is contained in:
parent
28efa78db1
commit
13394e6a8f
265
Cargo.lock
generated
265
Cargo.lock
generated
@ -29,6 +29,54 @@ version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5"
|
||||
|
||||
[[package]]
|
||||
name = "anstream"
|
||||
version = "0.6.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"anstyle-parse",
|
||||
"anstyle-query",
|
||||
"anstyle-wincon",
|
||||
"colorchoice",
|
||||
"utf8parse",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc"
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-parse"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c"
|
||||
dependencies = [
|
||||
"utf8parse",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-query"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648"
|
||||
dependencies = [
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-wincon"
|
||||
version = "3.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ariadne"
|
||||
version = "0.4.0"
|
||||
@ -65,12 +113,68 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b9c28d4e5dd9a9262a38b231153591da6ce1471b818233f4727985d3dd0ed93c"
|
||||
dependencies = [
|
||||
"hashbrown",
|
||||
"regex-automata",
|
||||
"regex-automata 0.3.9",
|
||||
"serde",
|
||||
"stacker",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b230ab84b0ffdf890d5a10abdbc8b83ae1c4918275daea1ab8801f71536b2651"
|
||||
dependencies = [
|
||||
"clap_builder",
|
||||
"clap_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_builder"
|
||||
version = "4.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
"clap_lex",
|
||||
"strsim",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_derive"
|
||||
version = "4.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "307bc0538d5f0f83b8248db3087aa92fe504e4691294d0c96c0eabc33f47ba47"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_lex"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce"
|
||||
|
||||
[[package]]
|
||||
name = "colorchoice"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
|
||||
|
||||
[[package]]
|
||||
name = "colored"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "concolor"
|
||||
version = "0.1.1"
|
||||
@ -97,6 +201,32 @@ version = "0.5.0"
|
||||
dependencies = [
|
||||
"ariadne",
|
||||
"chumsky",
|
||||
"clap",
|
||||
"colored",
|
||||
"env_logger",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "env_filter"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a009aa4810eb158359dda09d0c87378e4bbb89b5a801f016885a4707ba24f7ea"
|
||||
dependencies = [
|
||||
"log",
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "env_logger"
|
||||
version = "0.11.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38b35839ba51819680ba087cd351788c9a3c476841207e0b8cee0b04722343b9"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
"env_filter",
|
||||
"humantime",
|
||||
"log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -109,12 +239,24 @@ dependencies = [
|
||||
"allocator-api2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd5256b483761cd23699d0da46cc6fd2ee3be420bbe6d020ae4a091e70b7e9fd"
|
||||
|
||||
[[package]]
|
||||
name = "humantime"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
|
||||
|
||||
[[package]]
|
||||
name = "is-terminal"
|
||||
version = "0.4.12"
|
||||
@ -126,12 +268,24 @@ dependencies = [
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.153"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.1"
|
||||
@ -171,6 +325,18 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.10.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-automata 0.4.6",
|
||||
"regex-syntax 0.8.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.3.9"
|
||||
@ -179,7 +345,18 @@ checksum = "59b23e92ee4318893fa3fe3e6fb365258efbfe6ac6ab30f090cdcbb7aa37efa9"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
"regex-syntax 0.7.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax 0.8.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -188,6 +365,12 @@ version = "0.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da"
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.197"
|
||||
@ -221,6 +404,12 @@ dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.50"
|
||||
@ -244,6 +433,12 @@ version = "0.1.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85"
|
||||
|
||||
[[package]]
|
||||
name = "utf8parse"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.4"
|
||||
@ -281,6 +476,15 @@ dependencies = [
|
||||
"windows-targets 0.42.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
|
||||
dependencies = [
|
||||
"windows-targets 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.52.0"
|
||||
@ -305,6 +509,21 @@ dependencies = [
|
||||
"windows_x86_64_msvc 0.42.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.48.5",
|
||||
"windows_aarch64_msvc 0.48.5",
|
||||
"windows_i686_gnu 0.48.5",
|
||||
"windows_i686_msvc 0.48.5",
|
||||
"windows_x86_64_gnu 0.48.5",
|
||||
"windows_x86_64_gnullvm 0.48.5",
|
||||
"windows_x86_64_msvc 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.0"
|
||||
@ -326,6 +545,12 @@ version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.0"
|
||||
@ -338,6 +563,12 @@ version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.0"
|
||||
@ -350,6 +581,12 @@ version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.0"
|
||||
@ -362,6 +599,12 @@ version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.0"
|
||||
@ -374,6 +617,12 @@ version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.0"
|
||||
@ -386,6 +635,12 @@ version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.0"
|
||||
@ -398,6 +653,12 @@ version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.0"
|
||||
|
@ -15,3 +15,6 @@ opt-level = 3
|
||||
[dependencies]
|
||||
ariadne = { version = "0.4.0", features = ["auto-color"] }
|
||||
chumsky = { version = "1.0.0-alpha.6", features = ["pratt", "label"] }
|
||||
clap = { version = "4.5.2", features = ["derive"] }
|
||||
colored = "2.1.0"
|
||||
env_logger = "0.11.3"
|
||||
|
62
src/error.rs
62
src/error.rs
@ -1,29 +1,69 @@
|
||||
use std::sync::PoisonError;
|
||||
|
||||
use chumsky::prelude::Rich;
|
||||
use ariadne::{Color, Label, Report, ReportKind};
|
||||
use chumsky::{prelude::Rich, span::SimpleSpan};
|
||||
|
||||
use crate::{abstract_tree::Type, lexer::Token};
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum Error<'src> {
|
||||
Parse(Vec<Rich<'src, Token<'src>>>),
|
||||
Lex(Vec<Rich<'src, char>>),
|
||||
pub enum Error {
|
||||
Parse {
|
||||
expected: String,
|
||||
found: Option<String>,
|
||||
span: SimpleSpan,
|
||||
},
|
||||
Lex {
|
||||
expected: String,
|
||||
found: Option<char>,
|
||||
span: SimpleSpan,
|
||||
},
|
||||
Runtime(RuntimeError),
|
||||
}
|
||||
|
||||
impl<'src> From<Vec<Rich<'src, Token<'src>>>> for Error<'src> {
|
||||
fn from(errors: Vec<Rich<'src, Token<'src>>>) -> Self {
|
||||
Error::Parse(errors)
|
||||
impl Error {
|
||||
pub fn report(&self, source: &str) -> Report {
|
||||
match self {
|
||||
Error::Parse {
|
||||
expected,
|
||||
found,
|
||||
span,
|
||||
} => Report::build(ReportKind::Custom("Parsing Error", Color::Red), (), 0).finish(),
|
||||
Error::Lex {
|
||||
expected,
|
||||
found,
|
||||
span,
|
||||
} => Report::build(ReportKind::Custom("Lexing Error", Color::Red), (), 0)
|
||||
.with_label(Label::new(span.start..span.end).with_message(format!(
|
||||
"Exptected {expected} but found {}.",
|
||||
found.unwrap_or(' '),
|
||||
)))
|
||||
.finish(),
|
||||
Error::Runtime(_) => todo!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'src> From<Vec<Rich<'src, char>>> for Error<'src> {
|
||||
fn from(errors: Vec<Rich<'src, char>>) -> Self {
|
||||
Error::Lex(errors)
|
||||
impl From<Rich<'_, char>> for Error {
|
||||
fn from(error: Rich<'_, char>) -> Self {
|
||||
Error::Lex {
|
||||
expected: error.expected().map(|error| error.to_string()).collect(),
|
||||
found: error.reason().found().map(|c| c.clone()),
|
||||
span: error.span().clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'src> From<RuntimeError> for Error<'src> {
|
||||
impl<'src> From<Rich<'_, Token<'src>>> for Error {
|
||||
fn from(error: Rich<'_, Token<'src>>) -> Self {
|
||||
Error::Parse {
|
||||
expected: error.expected().map(|error| error.to_string()).collect(),
|
||||
found: error.reason().found().map(|c| c.to_string()),
|
||||
span: error.span().clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<RuntimeError> for Error {
|
||||
fn from(error: RuntimeError) -> Self {
|
||||
Error::Runtime(error)
|
||||
}
|
||||
|
@ -31,11 +31,11 @@ impl<'src> Display for Token<'src> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn lex<'src>(source: &'src str) -> Result<Vec<(Token, SimpleSpan)>, Error<'src>> {
|
||||
pub fn lex<'src>(source: &'src str) -> Result<Vec<(Token<'src>, SimpleSpan)>, Vec<Error>> {
|
||||
lexer()
|
||||
.parse(source)
|
||||
.into_result()
|
||||
.map_err(|error| Error::Lex(error))
|
||||
.map_err(|errors| errors.into_iter().map(|error| error.into()).collect())
|
||||
}
|
||||
|
||||
pub fn lexer<'src>() -> impl Parser<
|
||||
|
39
src/lib.rs
39
src/lib.rs
@ -5,30 +5,35 @@ pub mod lexer;
|
||||
pub mod parser;
|
||||
pub mod value;
|
||||
|
||||
use abstract_tree::Statement;
|
||||
use chumsky::{prelude::*, Parser};
|
||||
use abstract_tree::AbstractTree;
|
||||
use context::Context;
|
||||
use error::Error;
|
||||
use lexer::lex;
|
||||
pub use parser::{parse, parser, DustParser};
|
||||
pub use value::Value;
|
||||
|
||||
pub struct Interpreter<P> {
|
||||
_parser: P,
|
||||
_context: Context,
|
||||
pub struct Interpreter {
|
||||
context: Context,
|
||||
}
|
||||
|
||||
impl<'src, P> Interpreter<P>
|
||||
where
|
||||
P: Parser<'src, &'src str, Statement<'src>, extra::Err<Rich<'src, char>>>,
|
||||
{
|
||||
pub fn run(&self, _source: &'src str) -> Result<Value, Error<'src>> {
|
||||
todo!();
|
||||
impl Interpreter {
|
||||
pub fn new(context: Context) -> Self {
|
||||
Interpreter { context }
|
||||
}
|
||||
|
||||
// let final_value = self
|
||||
// .parser
|
||||
// .parse(source)
|
||||
// .into_result()?
|
||||
// .run(&self.context)?;
|
||||
pub fn run(&mut self, source: &str) -> Result<Value, Vec<Error>> {
|
||||
let tokens = lex(source)?;
|
||||
let statements = parse(&tokens)?;
|
||||
|
||||
// Ok(final_value)
|
||||
let mut value = Value::none();
|
||||
|
||||
for (statement, _span) in statements {
|
||||
value = match statement.run(&self.context) {
|
||||
Ok(value) => value,
|
||||
Err(runtime_error) => return Err(vec![Error::Runtime(runtime_error)]),
|
||||
}
|
||||
}
|
||||
|
||||
Ok(value)
|
||||
}
|
||||
}
|
||||
|
61
src/main.rs
Normal file
61
src/main.rs
Normal file
@ -0,0 +1,61 @@
|
||||
//! Command line interface for the dust programming language.
|
||||
|
||||
use ariadne::Source;
|
||||
use clap::Parser;
|
||||
use colored::Colorize;
|
||||
|
||||
use std::{fs::read_to_string, io::Write};
|
||||
|
||||
use dust_lang::{context::Context, Interpreter};
|
||||
|
||||
/// Command-line arguments to be parsed.
|
||||
#[derive(Parser, Debug)]
|
||||
#[command(author, version, about, long_about = None)]
|
||||
struct Args {
|
||||
/// Dust source code to evaluate.
|
||||
#[arg(short, long)]
|
||||
command: Option<String>,
|
||||
|
||||
/// Location of the file to run.
|
||||
path: Option<String>,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
env_logger::Builder::from_env("DUST_LOG")
|
||||
.format(|buffer, record| {
|
||||
let args = record.args();
|
||||
let log_level = record.level().to_string().bold();
|
||||
let timestamp = buffer.timestamp_seconds().to_string().dimmed();
|
||||
|
||||
writeln!(buffer, "[{log_level} {timestamp}] {args}")
|
||||
})
|
||||
.init();
|
||||
|
||||
let args = Args::parse();
|
||||
let context = Context::new();
|
||||
|
||||
let source = if let Some(path) = &args.path {
|
||||
read_to_string(path).unwrap()
|
||||
} else if let Some(command) = args.command {
|
||||
command
|
||||
} else {
|
||||
String::with_capacity(0)
|
||||
};
|
||||
|
||||
let mut interpreter = Interpreter::new(context);
|
||||
|
||||
let eval_result = interpreter.run(&source);
|
||||
|
||||
match eval_result {
|
||||
Ok(value) => {
|
||||
if !value.is_none() {
|
||||
println!("{value}")
|
||||
}
|
||||
}
|
||||
Err(errors) => {
|
||||
for error in errors {
|
||||
error.report(&source).eprint(Source::from(&source)).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -4,24 +4,27 @@ use chumsky::{input::SpannedInput, pratt::*, prelude::*};
|
||||
|
||||
use crate::{abstract_tree::*, error::Error, lexer::Token};
|
||||
|
||||
type ParserInput<'tokens, 'src> =
|
||||
SpannedInput<Token<'src>, SimpleSpan, &'tokens [(Token<'src>, SimpleSpan)]>;
|
||||
pub type DustParser<'src> = Boxed<
|
||||
'src,
|
||||
'src,
|
||||
ParserInput<'src>,
|
||||
Vec<(Statement<'src>, SimpleSpan)>,
|
||||
extra::Err<Rich<'src, Token<'src>, SimpleSpan>>,
|
||||
>;
|
||||
|
||||
pub fn parse<'tokens, 'src: 'tokens>(
|
||||
tokens: &'tokens [(Token<'src>, SimpleSpan)],
|
||||
) -> Result<Vec<(Statement<'src>, SimpleSpan)>, Error<'tokens>> {
|
||||
pub type ParserInput<'src> =
|
||||
SpannedInput<Token<'src>, SimpleSpan, &'src [(Token<'src>, SimpleSpan)]>;
|
||||
|
||||
pub fn parse<'src>(
|
||||
tokens: &'src [(Token<'src>, SimpleSpan)],
|
||||
) -> Result<Vec<(Statement<'src>, SimpleSpan)>, Vec<Error>> {
|
||||
parser()
|
||||
.parse(tokens.spanned((0..0).into()))
|
||||
.parse(tokens.spanned((tokens.len()..tokens.len()).into()))
|
||||
.into_result()
|
||||
.map_err(|error| Error::Parse(error))
|
||||
.map_err(|errors| errors.into_iter().map(|error| error.into()).collect())
|
||||
}
|
||||
|
||||
fn parser<'tokens, 'src: 'tokens>() -> impl Parser<
|
||||
'tokens,
|
||||
ParserInput<'tokens, 'src>,
|
||||
Vec<(Statement<'src>, SimpleSpan)>,
|
||||
extra::Err<Rich<'tokens, Token<'src>, SimpleSpan>>,
|
||||
> {
|
||||
pub fn parser<'src>() -> DustParser<'src> {
|
||||
let identifiers: RefCell<HashMap<&str, Identifier>> = RefCell::new(HashMap::new());
|
||||
|
||||
let identifier = select! {
|
||||
@ -185,6 +188,7 @@ fn parser<'tokens, 'src: 'tokens>() -> impl Parser<
|
||||
.map_with(|item, state| (item, state.span()))
|
||||
.repeated()
|
||||
.collect()
|
||||
.boxed()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@ -512,7 +516,8 @@ mod tests {
|
||||
fn positive_integer() {
|
||||
for i in 0..10 {
|
||||
let source = i.to_string();
|
||||
let statements = parse(&lex(&source).unwrap()).unwrap();
|
||||
let tokens = lex(&source).unwrap();
|
||||
let statements = parse(&tokens).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
statements[0].0,
|
||||
@ -537,7 +542,8 @@ mod tests {
|
||||
fn negative_integer() {
|
||||
for i in -9..1 {
|
||||
let source = i.to_string();
|
||||
let statements = parse(&lex(&source).unwrap()).unwrap();
|
||||
let tokens = lex(&source).unwrap();
|
||||
let statements = parse(&tokens).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
statements[0].0,
|
||||
|
39
src/value.rs
39
src/value.rs
@ -1,6 +1,7 @@
|
||||
use std::{
|
||||
cmp::Ordering,
|
||||
collections::BTreeMap,
|
||||
fmt::{self, Display, Formatter},
|
||||
ops::Range,
|
||||
sync::{Arc, OnceLock},
|
||||
};
|
||||
@ -9,6 +10,15 @@ use crate::{abstract_tree::Identifier, error::ValidationError};
|
||||
|
||||
pub static NONE: OnceLock<Value> = OnceLock::new();
|
||||
|
||||
fn get_none<'a>() -> &'a Value {
|
||||
NONE.get_or_init(|| {
|
||||
Value(Arc::new(ValueInner::Enum(
|
||||
Identifier::new("Option"),
|
||||
Identifier::new("None"),
|
||||
)))
|
||||
})
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct Value(Arc<ValueInner>);
|
||||
|
||||
@ -18,13 +28,7 @@ impl Value {
|
||||
}
|
||||
|
||||
pub fn none() -> Self {
|
||||
NONE.get_or_init(|| {
|
||||
Value(Arc::new(ValueInner::Enum(
|
||||
Identifier::new("Option"),
|
||||
Identifier::new("None"),
|
||||
)))
|
||||
})
|
||||
.clone()
|
||||
get_none().clone()
|
||||
}
|
||||
|
||||
pub fn boolean(boolean: bool) -> Self {
|
||||
@ -66,6 +70,27 @@ impl Value {
|
||||
|
||||
Err(ValidationError::ExpectedBoolean)
|
||||
}
|
||||
|
||||
pub fn is_none(&self) -> bool {
|
||||
self == get_none()
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Value {
|
||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||
use ValueInner::*;
|
||||
|
||||
match self.inner().as_ref() {
|
||||
Boolean(boolean) => write!(f, "{boolean}"),
|
||||
Float(float) => write!(f, "{float}"),
|
||||
Integer(integer) => write!(f, "{integer}"),
|
||||
List(_) => todo!(),
|
||||
Map(_) => todo!(),
|
||||
Range(_) => todo!(),
|
||||
String(_) => todo!(),
|
||||
Enum(_, _) => todo!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for Value {}
|
||||
|
Loading…
Reference in New Issue
Block a user