Improve API and errors

This commit is contained in:
Jeff 2024-03-06 15:36:58 -05:00
parent 28efa78db1
commit 13394e6a8f
8 changed files with 455 additions and 54 deletions

265
Cargo.lock generated
View File

@ -29,6 +29,54 @@ version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" 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]] [[package]]
name = "ariadne" name = "ariadne"
version = "0.4.0" version = "0.4.0"
@ -65,12 +113,68 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9c28d4e5dd9a9262a38b231153591da6ce1471b818233f4727985d3dd0ed93c" checksum = "b9c28d4e5dd9a9262a38b231153591da6ce1471b818233f4727985d3dd0ed93c"
dependencies = [ dependencies = [
"hashbrown", "hashbrown",
"regex-automata", "regex-automata 0.3.9",
"serde", "serde",
"stacker", "stacker",
"unicode-ident", "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]] [[package]]
name = "concolor" name = "concolor"
version = "0.1.1" version = "0.1.1"
@ -97,6 +201,32 @@ version = "0.5.0"
dependencies = [ dependencies = [
"ariadne", "ariadne",
"chumsky", "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]] [[package]]
@ -109,12 +239,24 @@ dependencies = [
"allocator-api2", "allocator-api2",
] ]
[[package]]
name = "heck"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
[[package]] [[package]]
name = "hermit-abi" name = "hermit-abi"
version = "0.3.6" version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd5256b483761cd23699d0da46cc6fd2ee3be420bbe6d020ae4a091e70b7e9fd" checksum = "bd5256b483761cd23699d0da46cc6fd2ee3be420bbe6d020ae4a091e70b7e9fd"
[[package]]
name = "humantime"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
[[package]] [[package]]
name = "is-terminal" name = "is-terminal"
version = "0.4.12" version = "0.4.12"
@ -126,12 +268,24 @@ dependencies = [
"windows-sys 0.52.0", "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]] [[package]]
name = "libc" name = "libc"
version = "0.2.153" version = "0.2.153"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
[[package]]
name = "log"
version = "0.4.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
[[package]] [[package]]
name = "memchr" name = "memchr"
version = "2.7.1" version = "2.7.1"
@ -171,6 +325,18 @@ dependencies = [
"proc-macro2", "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]] [[package]]
name = "regex-automata" name = "regex-automata"
version = "0.3.9" version = "0.3.9"
@ -179,7 +345,18 @@ checksum = "59b23e92ee4318893fa3fe3e6fb365258efbfe6ac6ab30f090cdcbb7aa37efa9"
dependencies = [ dependencies = [
"aho-corasick", "aho-corasick",
"memchr", "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]] [[package]]
@ -188,6 +365,12 @@ version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da"
[[package]]
name = "regex-syntax"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.197" version = "1.0.197"
@ -221,6 +404,12 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "strsim"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01"
[[package]] [[package]]
name = "syn" name = "syn"
version = "2.0.50" version = "2.0.50"
@ -244,6 +433,12 @@ version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85"
[[package]]
name = "utf8parse"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
[[package]] [[package]]
name = "version_check" name = "version_check"
version = "0.9.4" version = "0.9.4"
@ -281,6 +476,15 @@ dependencies = [
"windows-targets 0.42.2", "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]] [[package]]
name = "windows-sys" name = "windows-sys"
version = "0.52.0" version = "0.52.0"
@ -305,6 +509,21 @@ dependencies = [
"windows_x86_64_msvc 0.42.2", "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]] [[package]]
name = "windows-targets" name = "windows-targets"
version = "0.52.0" version = "0.52.0"
@ -326,6 +545,12 @@ version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
[[package]] [[package]]
name = "windows_aarch64_gnullvm" name = "windows_aarch64_gnullvm"
version = "0.52.0" version = "0.52.0"
@ -338,6 +563,12 @@ version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
[[package]]
name = "windows_aarch64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
[[package]] [[package]]
name = "windows_aarch64_msvc" name = "windows_aarch64_msvc"
version = "0.52.0" version = "0.52.0"
@ -350,6 +581,12 @@ version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
[[package]]
name = "windows_i686_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
[[package]] [[package]]
name = "windows_i686_gnu" name = "windows_i686_gnu"
version = "0.52.0" version = "0.52.0"
@ -362,6 +599,12 @@ version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
[[package]]
name = "windows_i686_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
[[package]] [[package]]
name = "windows_i686_msvc" name = "windows_i686_msvc"
version = "0.52.0" version = "0.52.0"
@ -374,6 +617,12 @@ version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" 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]] [[package]]
name = "windows_x86_64_gnu" name = "windows_x86_64_gnu"
version = "0.52.0" version = "0.52.0"
@ -386,6 +635,12 @@ version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" 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]] [[package]]
name = "windows_x86_64_gnullvm" name = "windows_x86_64_gnullvm"
version = "0.52.0" version = "0.52.0"
@ -398,6 +653,12 @@ version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" 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]] [[package]]
name = "windows_x86_64_msvc" name = "windows_x86_64_msvc"
version = "0.52.0" version = "0.52.0"

View File

@ -15,3 +15,6 @@ opt-level = 3
[dependencies] [dependencies]
ariadne = { version = "0.4.0", features = ["auto-color"] } ariadne = { version = "0.4.0", features = ["auto-color"] }
chumsky = { version = "1.0.0-alpha.6", features = ["pratt", "label"] } 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"

View File

@ -1,29 +1,69 @@
use std::sync::PoisonError; 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}; use crate::{abstract_tree::Type, lexer::Token};
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
pub enum Error<'src> { pub enum Error {
Parse(Vec<Rich<'src, Token<'src>>>), Parse {
Lex(Vec<Rich<'src, char>>), expected: String,
found: Option<String>,
span: SimpleSpan,
},
Lex {
expected: String,
found: Option<char>,
span: SimpleSpan,
},
Runtime(RuntimeError), Runtime(RuntimeError),
} }
impl<'src> From<Vec<Rich<'src, Token<'src>>>> for Error<'src> { impl Error {
fn from(errors: Vec<Rich<'src, Token<'src>>>) -> Self { pub fn report(&self, source: &str) -> Report {
Error::Parse(errors) 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> { impl From<Rich<'_, char>> for Error {
fn from(errors: Vec<Rich<'src, char>>) -> Self { fn from(error: Rich<'_, char>) -> Self {
Error::Lex(errors) 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 { fn from(error: RuntimeError) -> Self {
Error::Runtime(error) Error::Runtime(error)
} }

View File

@ -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() lexer()
.parse(source) .parse(source)
.into_result() .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< pub fn lexer<'src>() -> impl Parser<

View File

@ -5,30 +5,35 @@ pub mod lexer;
pub mod parser; pub mod parser;
pub mod value; pub mod value;
use abstract_tree::Statement; use abstract_tree::AbstractTree;
use chumsky::{prelude::*, Parser};
use context::Context; use context::Context;
use error::Error; use error::Error;
use lexer::lex;
pub use parser::{parse, parser, DustParser};
pub use value::Value; pub use value::Value;
pub struct Interpreter<P> { pub struct Interpreter {
_parser: P, context: Context,
_context: Context,
} }
impl<'src, P> Interpreter<P> impl Interpreter {
where pub fn new(context: Context) -> Self {
P: Parser<'src, &'src str, Statement<'src>, extra::Err<Rich<'src, char>>>, Interpreter { context }
{ }
pub fn run(&self, _source: &'src str) -> Result<Value, Error<'src>> {
todo!();
// let final_value = self pub fn run(&mut self, source: &str) -> Result<Value, Vec<Error>> {
// .parser let tokens = lex(source)?;
// .parse(source) let statements = parse(&tokens)?;
// .into_result()?
// .run(&self.context)?;
// 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
View 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();
}
}
}
}

View File

@ -4,24 +4,27 @@ use chumsky::{input::SpannedInput, pratt::*, prelude::*};
use crate::{abstract_tree::*, error::Error, lexer::Token}; use crate::{abstract_tree::*, error::Error, lexer::Token};
type ParserInput<'tokens, 'src> = pub type DustParser<'src> = Boxed<
SpannedInput<Token<'src>, SimpleSpan, &'tokens [(Token<'src>, SimpleSpan)]>; 'src,
'src,
ParserInput<'src>,
Vec<(Statement<'src>, SimpleSpan)>,
extra::Err<Rich<'src, Token<'src>, SimpleSpan>>,
>;
pub fn parse<'tokens, 'src: 'tokens>( pub type ParserInput<'src> =
tokens: &'tokens [(Token<'src>, SimpleSpan)], SpannedInput<Token<'src>, SimpleSpan, &'src [(Token<'src>, SimpleSpan)]>;
) -> Result<Vec<(Statement<'src>, SimpleSpan)>, Error<'tokens>> {
pub fn parse<'src>(
tokens: &'src [(Token<'src>, SimpleSpan)],
) -> Result<Vec<(Statement<'src>, SimpleSpan)>, Vec<Error>> {
parser() parser()
.parse(tokens.spanned((0..0).into())) .parse(tokens.spanned((tokens.len()..tokens.len()).into()))
.into_result() .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< pub fn parser<'src>() -> DustParser<'src> {
'tokens,
ParserInput<'tokens, 'src>,
Vec<(Statement<'src>, SimpleSpan)>,
extra::Err<Rich<'tokens, Token<'src>, SimpleSpan>>,
> {
let identifiers: RefCell<HashMap<&str, Identifier>> = RefCell::new(HashMap::new()); let identifiers: RefCell<HashMap<&str, Identifier>> = RefCell::new(HashMap::new());
let identifier = select! { let identifier = select! {
@ -185,6 +188,7 @@ fn parser<'tokens, 'src: 'tokens>() -> impl Parser<
.map_with(|item, state| (item, state.span())) .map_with(|item, state| (item, state.span()))
.repeated() .repeated()
.collect() .collect()
.boxed()
} }
#[cfg(test)] #[cfg(test)]
@ -512,7 +516,8 @@ mod tests {
fn positive_integer() { fn positive_integer() {
for i in 0..10 { for i in 0..10 {
let source = i.to_string(); let source = i.to_string();
let statements = parse(&lex(&source).unwrap()).unwrap(); let tokens = lex(&source).unwrap();
let statements = parse(&tokens).unwrap();
assert_eq!( assert_eq!(
statements[0].0, statements[0].0,
@ -537,7 +542,8 @@ mod tests {
fn negative_integer() { fn negative_integer() {
for i in -9..1 { for i in -9..1 {
let source = i.to_string(); let source = i.to_string();
let statements = parse(&lex(&source).unwrap()).unwrap(); let tokens = lex(&source).unwrap();
let statements = parse(&tokens).unwrap();
assert_eq!( assert_eq!(
statements[0].0, statements[0].0,

View File

@ -1,6 +1,7 @@
use std::{ use std::{
cmp::Ordering, cmp::Ordering,
collections::BTreeMap, collections::BTreeMap,
fmt::{self, Display, Formatter},
ops::Range, ops::Range,
sync::{Arc, OnceLock}, sync::{Arc, OnceLock},
}; };
@ -9,6 +10,15 @@ use crate::{abstract_tree::Identifier, error::ValidationError};
pub static NONE: OnceLock<Value> = OnceLock::new(); 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)] #[derive(Clone, Debug, PartialEq)]
pub struct Value(Arc<ValueInner>); pub struct Value(Arc<ValueInner>);
@ -18,13 +28,7 @@ impl Value {
} }
pub fn none() -> Self { pub fn none() -> Self {
NONE.get_or_init(|| { get_none().clone()
Value(Arc::new(ValueInner::Enum(
Identifier::new("Option"),
Identifier::new("None"),
)))
})
.clone()
} }
pub fn boolean(boolean: bool) -> Self { pub fn boolean(boolean: bool) -> Self {
@ -66,6 +70,27 @@ impl Value {
Err(ValidationError::ExpectedBoolean) 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 {} impl Eq for Value {}