From b4d48a598a4482369c26c6b57720aee37c82ea3a Mon Sep 17 00:00:00 2001 From: Schrottkatze Date: Wed, 13 Dec 2023 18:13:43 +0100 Subject: [PATCH] restart basically lmao --- Cargo.lock | 326 +------------------------------------ Cargo.toml | 12 +- crates/executor/Cargo.toml | 8 + crates/executor/src/lib.rs | 14 ++ crates/pl-cli/Cargo.toml | 8 + crates/pl-cli/src/main.rs | 3 + crates/rpl/Cargo.toml | 8 + crates/rpl/src/lib.rs | 14 ++ src/args.rs | 11 -- src/builtins/mod.rs | 39 ----- src/builtins/namespace.rs | 1 - src/error/mod.rs | 90 ---------- src/evaluator.rs | 137 ---------------- src/globals.rs | 26 --- src/lexer.rs | 58 ------- src/lib.rs | 20 --- src/main.rs | 12 -- src/namespace/command.rs | 70 -------- src/namespace/mod.rs | 213 ------------------------ src/namespace/trait.rs | 35 ---- src/namespace/type.rs | 55 ------- src/namespace/typedef.rs | 184 --------------------- src/syntax/check.rs | 214 ------------------------ src/syntax/check/test.rs | 66 -------- src/syntax/mod.rs | 110 ------------- src/typed.rs | 234 -------------------------- 26 files changed, 61 insertions(+), 1907 deletions(-) create mode 100644 crates/executor/Cargo.toml create mode 100644 crates/executor/src/lib.rs create mode 100644 crates/pl-cli/Cargo.toml create mode 100644 crates/pl-cli/src/main.rs create mode 100644 crates/rpl/Cargo.toml create mode 100644 crates/rpl/src/lib.rs delete mode 100644 src/args.rs delete mode 100644 src/builtins/mod.rs delete mode 100644 src/builtins/namespace.rs delete mode 100644 src/error/mod.rs delete mode 100644 src/evaluator.rs delete mode 100644 src/globals.rs delete mode 100644 src/lexer.rs delete mode 100644 src/lib.rs delete mode 100644 src/main.rs delete mode 100644 src/namespace/command.rs delete mode 100644 src/namespace/mod.rs delete mode 100644 src/namespace/trait.rs delete mode 100644 src/namespace/type.rs delete mode 100644 src/namespace/typedef.rs delete mode 100644 src/syntax/check.rs delete mode 100644 src/syntax/check/test.rs delete mode 100644 src/syntax/mod.rs delete mode 100644 src/typed.rs diff --git a/Cargo.lock b/Cargo.lock index ee349ac..71c3f53 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3,329 +3,13 @@ version = 3 [[package]] -name = "anstream" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44" -dependencies = [ - "anstyle", - "anstyle-parse", - "anstyle-query", - "anstyle-wincon", - "colorchoice", - "utf8parse", -] - -[[package]] -name = "anstyle" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" - -[[package]] -name = "anstyle-parse" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "317b9a89c1868f5ea6ff1d9539a69f45dffc21ce321ac1fd1160dfa48c8e2140" -dependencies = [ - "utf8parse", -] - -[[package]] -name = "anstyle-query" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" -dependencies = [ - "windows-sys", -] - -[[package]] -name = "anstyle-wincon" -version = "3.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628" -dependencies = [ - "anstyle", - "windows-sys", -] - -[[package]] -name = "beef" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1" - -[[package]] -name = "clap" -version = "4.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2275f18819641850fa26c89acc84d465c1bf91ce57bc2748b28c420473352f64" -dependencies = [ - "clap_builder", - "clap_derive", -] - -[[package]] -name = "clap_builder" -version = "4.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07cdf1b148b25c1e1f7a42225e30a0d99a615cd4637eae7365548dd4529b95bc" -dependencies = [ - "anstream", - "anstyle", - "clap_lex", - "strsim", -] - -[[package]] -name = "clap_derive" -version = "4.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "clap_lex" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" - -[[package]] -name = "codespan-reporting" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" -dependencies = [ - "termcolor", - "unicode-width", -] - -[[package]] -name = "colorchoice" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" - -[[package]] -name = "logos" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c000ca4d908ff18ac99b93a062cb8958d331c3220719c52e77cb19cc6ac5d2c1" -dependencies = [ - "logos-derive", -] - -[[package]] -name = "logos-codegen" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc487311295e0002e452025d6b580b77bb17286de87b57138f3b5db711cded68" -dependencies = [ - "beef", - "fnv", - "proc-macro2", - "quote", - "regex-syntax", - "syn", -] - -[[package]] -name = "logos-derive" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbfc0d229f1f42d790440136d941afd806bc9e949e2bcb8faa813b0f00d1267e" -dependencies = [ - "logos-codegen", -] - -[[package]] -name = "pipeline-lang" +name = "executor" version = "0.1.0" -dependencies = [ - "clap", - "codespan-reporting", - "logos", -] [[package]] -name = "proc-macro2" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" -dependencies = [ - "unicode-ident", -] +name = "pl-cli" +version = "0.1.0" [[package]] -name = "quote" -version = "1.0.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "regex-syntax" -version = "0.6.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" - -[[package]] -name = "strsim" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" - -[[package]] -name = "syn" -version = "2.0.39" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "termcolor" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff1bc3d3f05aff0403e8ac0d92ced918ec05b666a43f83297ccef5bea8a3d449" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "unicode-ident" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" - -[[package]] -name = "unicode-width" -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 = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-util" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" -dependencies = [ - "winapi", -] - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" -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.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - -[[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_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - -[[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_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +name = "rpl" +version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index 2291d53..d5fdd00 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,14 +1,4 @@ -[package] -name = "pipeline-lang" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -logos = "0.13" -codespan-reporting = "0.11" -clap = { version = "4.4.8", features = [ "derive" ] } +workspace = { members = [ "crates/executor", "crates/pl-cli","crates/rpl"] } [lints.rust] unsafe_code = "deny" diff --git a/crates/executor/Cargo.toml b/crates/executor/Cargo.toml new file mode 100644 index 0000000..cd74c92 --- /dev/null +++ b/crates/executor/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "executor" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/crates/executor/src/lib.rs b/crates/executor/src/lib.rs new file mode 100644 index 0000000..7d12d9a --- /dev/null +++ b/crates/executor/src/lib.rs @@ -0,0 +1,14 @@ +pub fn add(left: usize, right: usize) -> usize { + left + right +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn it_works() { + let result = add(2, 2); + assert_eq!(result, 4); + } +} diff --git a/crates/pl-cli/Cargo.toml b/crates/pl-cli/Cargo.toml new file mode 100644 index 0000000..d4b95e9 --- /dev/null +++ b/crates/pl-cli/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "pl-cli" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/crates/pl-cli/src/main.rs b/crates/pl-cli/src/main.rs new file mode 100644 index 0000000..e7a11a9 --- /dev/null +++ b/crates/pl-cli/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} diff --git a/crates/rpl/Cargo.toml b/crates/rpl/Cargo.toml new file mode 100644 index 0000000..e6e42c6 --- /dev/null +++ b/crates/rpl/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "rpl" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/crates/rpl/src/lib.rs b/crates/rpl/src/lib.rs new file mode 100644 index 0000000..7d12d9a --- /dev/null +++ b/crates/rpl/src/lib.rs @@ -0,0 +1,14 @@ +pub fn add(left: usize, right: usize) -> usize { + left + right +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn it_works() { + let result = add(2, 2); + assert_eq!(result, 4); + } +} diff --git a/src/args.rs b/src/args.rs deleted file mode 100644 index 6a0e72b..0000000 --- a/src/args.rs +++ /dev/null @@ -1,11 +0,0 @@ -use clap::Parser; - -#[derive(Parser, Debug)] -#[command(author, version, about, long_about = None)] -pub struct Args { - pub text: String, - #[arg(long)] - pub debug_tokens: bool, - #[arg(long)] - pub debug_typed_repr: bool, -} diff --git a/src/builtins/mod.rs b/src/builtins/mod.rs deleted file mode 100644 index a6e6e2f..0000000 --- a/src/builtins/mod.rs +++ /dev/null @@ -1,39 +0,0 @@ -use crate::namespace::{typedef::TypeDef, GlobalNamespace}; - -pub const TYPE_INTEGER: &str = "int"; -pub const TYPE_FLOAT: &str = "float"; -pub const TYPE_STRING: &str = "string"; - -pub const TRAIT_NUMERIC: &str = "Num"; - -pub const CMD_ADD: &str = "add"; - -#[allow( - clippy::unwrap_used, - reason = "Errs can only be returned in case of duplicate names in the same namespace, which will not happen here" -)] -#[allow(clippy::missing_panics_doc, reason = "will not panic")] -pub fn initialise_globals() -> GlobalNamespace { - let ns = GlobalNamespace::init(); - - let numeric = ns.register_trait(TRAIT_NUMERIC).unwrap(); - - ns.register_type(TYPE_INTEGER).unwrap().add_trait(&numeric); - ns.register_type(TYPE_FLOAT).unwrap().add_trait(&numeric); - - ns.register_type(TYPE_STRING).unwrap(); - - // def math add [ Numeric Numeric ] -> Numeric - ns.register_command( - CMD_ADD, - vec![("T", vec![&numeric])], - Some(&TypeDef::List(vec![ - TypeDef::Generic("T".to_owned()), - TypeDef::Generic("T".to_owned()), - ])), - Some(&TypeDef::Generic("T".to_owned())), - ) - .unwrap(); - - ns -} diff --git a/src/builtins/namespace.rs b/src/builtins/namespace.rs deleted file mode 100644 index 8b13789..0000000 --- a/src/builtins/namespace.rs +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/error/mod.rs b/src/error/mod.rs deleted file mode 100644 index 4f15d36..0000000 --- a/src/error/mod.rs +++ /dev/null @@ -1,90 +0,0 @@ -use codespan_reporting::{ - diagnostic::{Diagnostic, Label}, - files::SimpleFiles, -}; - -use crate::Span; - -#[derive(Debug)] -pub struct Errors { - pub kind: ErrorKind, - pub locs: Vec, -} - -#[derive(Debug)] -pub enum ErrorKind { - InvalidToken, - SyntaxError(SyntaxErrorKind), - CommandNotFound, -} - -#[derive(Debug)] -pub enum SyntaxErrorKind { - /// `MissingStreamer` means, that the pipeline starts with a Pipe (`|`), so it has no streamer as input in front of it. - MissingStreamer, - /// `MissingSink` means, that the pipeline ends with a Pipe (`|`), meaning that the output can't go anywhere - MissingSink, - /// This indicates a missing filter somewhere in the pipeline, meaning that there's 2 pipes after one another - MissingFilter, - /// A literal cannot be a sink - LiteralAsSink, - /// A literal can't be a filter either - LiteralAsFilter, - /// A literal acting as streamer cannot take arguments - LiteralWithArgs, -} - -impl Errors { - pub fn new(kind: ErrorKind, locs: Vec) -> Self { - Self { kind, locs } - } - pub fn new_single(kind: ErrorKind, loc: Span) -> Self { - Self { - kind, - locs: vec![loc], - } - } - pub fn into_diag( - &self, - file_id: usize, - _file_db: &SimpleFiles<&str, String>, - ) -> Diagnostic { - let Errors { kind, locs } = self; - - match kind { - ErrorKind::InvalidToken => simple_diag(locs.clone(), file_id, "invalid tokens"), - ErrorKind::SyntaxError(syntax_error) => match syntax_error { - SyntaxErrorKind::MissingStreamer => simple_diag( - locs.clone(), - file_id, - "pipeline is missing an input provider", - ), - SyntaxErrorKind::MissingSink => { - simple_diag(locs.clone(), file_id, "pipeline is missing a sink") - } - SyntaxErrorKind::MissingFilter => { - simple_diag(locs.clone(), file_id, "missing filters in pipeline") - } - SyntaxErrorKind::LiteralAsSink => { - simple_diag(locs.clone(), file_id, "pipelines can't end in a literal") - } - SyntaxErrorKind::LiteralAsFilter => { - simple_diag(locs.clone(), file_id, "literals can't filter data") - } - SyntaxErrorKind::LiteralWithArgs => { - simple_diag(locs.clone(), file_id, "literals can't take arguments") - } - }, - ErrorKind::CommandNotFound => simple_diag(locs.clone(), file_id, "command not found"), - } - } -} - -fn simple_diag(spans: Vec, file_id: usize, msg: &str) -> Diagnostic { - Diagnostic::error().with_message(msg).with_labels( - spans - .into_iter() - .map(|span| Label::primary(file_id, span)) - .collect(), - ) -} diff --git a/src/evaluator.rs b/src/evaluator.rs deleted file mode 100644 index 9b11f3e..0000000 --- a/src/evaluator.rs +++ /dev/null @@ -1,137 +0,0 @@ -use std::{collections::HashMap, process::exit}; - -use clap::error::Result; -use codespan_reporting::{ - files::SimpleFiles, - term::{ - self, - termcolor::{ColorChoice, StandardStream}, - }, -}; - -use crate::{ - builtins::initialise_globals, - error::{ErrorKind, Errors}, - syntax::{check::check, parse_syntax, PipelineElement}, - typed::into_typed_repr, -}; - -pub struct EvalConfig { - debug_raw_toks: bool, - debug_print_typed_repr: bool, -} - -impl EvalConfig { - pub fn new(debug_raw_toks: bool, debug_print_typed_repr: bool) -> Self { - Self { - debug_raw_toks, - debug_print_typed_repr, - } - } -} - -pub type FileId = usize; - -// this is also bad -// need a better architecture for this -pub struct Evaluator<'a> { - curr_phase: EvalPhase, - files: SimpleFiles<&'a str, String>, - errors: HashMap>, - cfg: EvalConfig, -} - -impl<'a> Evaluator<'a> { - pub fn init(cfg: EvalConfig) -> Self { - Self { - curr_phase: EvalPhase::Lex, - files: SimpleFiles::new(), - errors: HashMap::new(), - cfg, - } - } - - pub fn run(&mut self, input: &str, name: Option<&'a str>) { - let fid = self.files.add(name.unwrap_or("input"), input.to_owned()); - - let syntax = parse_syntax(input); - if self.cfg.debug_raw_toks { - println!("Raw tokens: {syntax:#?}"); - } - - match syntax { - Ok(syntax) => self.curr_phase = EvalPhase::Check(fid, syntax), - Err(errs) => { - self.errors.insert( - fid, - vec![Errors { - kind: ErrorKind::InvalidToken, - locs: errs, - }], - ); - self.curr_phase = EvalPhase::Failed; - } - }; - } - - pub fn next(mut self) { - match self.curr_phase { - EvalPhase::Lex => { - unreachable!() - } - EvalPhase::Check(file_id, syntax) => { - let r = check(&syntax); - - if let Err(errs) = r { - self.errors.insert(file_id, errs); - self.curr_phase = EvalPhase::Failed; - } else { - self.curr_phase = EvalPhase::BareTyped(file_id, syntax.clone()); - } - } - EvalPhase::BareTyped(file_id, syntax) => { - let ns = initialise_globals(); - let r = into_typed_repr(&ns, syntax); - - match r { - Ok(typed) => { - if self.cfg.debug_print_typed_repr { - println!("Typed repr: {typed:#?}"); - } - - todo!() - } - Err(errs) => { - self.errors.insert(file_id, vec![errs]); - self.curr_phase = EvalPhase::Failed; - } - } - } - EvalPhase::Failed => self.error_out().expect("unable to print errors"), - } - self.next(); - } - - pub fn error_out(self) -> Result { - let Evaluator { files, errors, .. } = self; - - let writer = StandardStream::stderr(ColorChoice::Always); - let config = term::Config::default(); - - for (file_id, errors) in &errors { - let writer = &mut writer.lock(); - for error in errors { - term::emit(writer, &config, &files, &error.into_diag(*file_id, &files))?; - } - } - - exit(1) - } -} - -enum EvalPhase { - Lex, - Check(FileId, Vec), - BareTyped(FileId, Vec), - Failed, -} diff --git a/src/globals.rs b/src/globals.rs deleted file mode 100644 index 3de4b77..0000000 --- a/src/globals.rs +++ /dev/null @@ -1,26 +0,0 @@ -// concepts -// root type namespace -// -> builtin types/traits/functions -// -> builtin constants -// -// generic item namespaces -// -> in generic functions ( `add [ T T ] -> T` ) -// -> in generic types ( vec ) -// -> generic traits ( T: From ) -// -// TODO: how builtins? just compile everything to builtin types/defs? - -/// This is the root type namespace. -struct RootTypeNamespace { - -} - -mod r#type { - -} -struct Type<'a> { - pub(super) id: usize, - pub(super) namespace: &'a GlobalNamespace, -} - -struct InternalType diff --git a/src/lexer.rs b/src/lexer.rs deleted file mode 100644 index 917a4e9..0000000 --- a/src/lexer.rs +++ /dev/null @@ -1,58 +0,0 @@ -use logos::Logos; - -#[derive(Logos, Debug, PartialEq)] -#[logos(skip r"[\s]+")] -pub enum Token<'a> { - #[regex("[\\w]+", |lex| lex.slice())] - Word(&'a str), - #[regex("[\\d]+", priority = 2, callback = |lex| lex.slice().parse::().expect("regex should only match valid integers. This is a bug."))] - IntLiteral(i64), - #[regex("[\\d]+\\.[\\d]+", |lex| lex.slice().parse::().expect("regex should only match valid floats. This is a bug."))] - FloatLiteral(f64), - #[regex(r#""([^"\\]|\\["\\bnfrt]|u[a-fA-F0-9]{4})*""#, |lex| lex.slice().to_owned())] - StringLiteral(String), - #[token("|")] - Pipe, - // #[token("def")] - // Define, - // #[token("type")] - // Type, - // #[token("->")] - // RightArrow, - // #[token("[")] - // BracketOpening, - // #[token("]")] - // BracketClosing, - // #[token("(")] - // ParensOpening, - // #[token(")")] - // ParensClosing, - // #[token("{")] - // BraceOpening, - // #[token("}")] - // BraceClosing, - // #[token("+")] - // Plus, - // #[token("-")] - // Minus, - // #[token("*")] - // Multiply, - // #[token("/")] - // Divide, - // #[token("%")] - // Percent, - // #[token("&")] - // Ampersand, - // #[token(":")] - // Colon, - // #[token(";")] - // Semicolon, - // #[token(".")] - // Dot, - // #[token(",")] - // Comma, - // #[token("!")] - // ExclaimationMark, - // #[token("?")] - // QuestionMark, -} diff --git a/src/lib.rs b/src/lib.rs deleted file mode 100644 index d8a67e7..0000000 --- a/src/lib.rs +++ /dev/null @@ -1,20 +0,0 @@ -#![feature(never_type, lint_reasons)] - -use std::ops::Range; - -pub mod args; -pub mod builtins; -pub mod error; -pub mod evaluator; - -#[allow(clippy::indexing_slicing, reason = "in logos, outside our control")] -pub mod lexer; - -pub mod namespace; -pub mod syntax; - -#[allow(dead_code, reason = "the future!!!")] -pub mod typed; - -// basically logos::Span but in this repo -pub type Span = Range; diff --git a/src/main.rs b/src/main.rs deleted file mode 100644 index 2727830..0000000 --- a/src/main.rs +++ /dev/null @@ -1,12 +0,0 @@ -use clap::Parser; -use pipeline_lang::args::Args; -use pipeline_lang::evaluator::{EvalConfig, Evaluator}; - -fn main() { - let args = Args::parse(); - - let mut evaluator = Evaluator::init(EvalConfig::new(args.debug_tokens, args.debug_typed_repr)); - - evaluator.run(&args.text, None); - evaluator.next(); -} diff --git a/src/namespace/command.rs b/src/namespace/command.rs deleted file mode 100644 index 9513ca2..0000000 --- a/src/namespace/command.rs +++ /dev/null @@ -1,70 +0,0 @@ -use std::fmt::Debug; -use std::fmt::Display; - -use super::typedef::{InternalTypeDef, TypeDef}; -use super::CommandId; - -use super::GlobalNamespace; - -#[derive(Clone, Copy)] -pub struct Command<'a> { - pub(super) id: CommandId, - pub(super) namespace: &'a GlobalNamespace, -} - -impl<'a> Command<'a> { - pub fn get_input_types(&self) -> Option> { - self.namespace.commands.borrow()[self.id] - .input - .as_ref() - .map(|def| TypeDef::from_internal(self.namespace, def)) - } - // get a count of inputs required - pub fn input_count(&self) -> usize { - self.namespace.commands.borrow()[self.id] - .input - .as_ref() - .map_or(0, |inputs| match inputs { - InternalTypeDef::Single(_) | InternalTypeDef::Generic(_) => 1, - InternalTypeDef::List(list) => list.len(), - InternalTypeDef::Record(rec) => rec.len(), - }) - } - pub fn get_output_types(&self) -> Option { - self.namespace.commands.borrow()[self.id] - .output - .as_ref() - .map(|def| TypeDef::from_internal(self.namespace, def)) - } -} - -impl Display for Command<'_> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let name = &self.namespace.commands.borrow()[self.id].name; - f.write_fmt(format_args!( - "{name} {} -> {}", - self.get_input_types() - .map_or("!".to_owned(), |v| v.to_string()), - self.get_output_types() - .map_or("!".to_owned(), |v| v.to_string()) - )) - } -} - -impl Debug for Command<'_> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let name = &self.namespace.commands.borrow()[self.id].name; - f.write_fmt(format_args!( - "{name:?} {:?} -> {:?}", - self.get_input_types(), - self.get_output_types() - )) - } -} - -pub(super) struct InternalCommand { - pub(super) name: String, - // gosh this is hacky - pub(super) input: Option, - pub(super) output: Option, -} diff --git a/src/namespace/mod.rs b/src/namespace/mod.rs deleted file mode 100644 index 5931ae6..0000000 --- a/src/namespace/mod.rs +++ /dev/null @@ -1,213 +0,0 @@ -use std::{ - cell::RefCell, - collections::{HashMap, HashSet}, -}; - -use self::{ - command::{Command, InternalCommand}, - r#trait::{InternalTrait, Trait}, - r#type::{InternalType, Type}, - typedef::TypeDef, -}; - -pub mod command; -pub mod r#trait; -pub mod r#type; -pub mod typedef; - -pub struct GlobalNamespace { - types: RefCell>, - traits: RefCell>, - type_namespace: RefCell>, - commands: RefCell>, - data_namespace: RefCell>, -} - -pub type TypeId = usize; -pub type TraitId = usize; -pub type CommandId = usize; - -enum TypeNamespaceId { - Types(TypeId), - Traits(TraitId), -} - -enum DataNamespaceId { - Commands(CommandId), -} - -impl GlobalNamespace { - pub fn init() -> Self { - Self { - types: RefCell::new(Vec::new()), - traits: RefCell::new(Vec::new()), - type_namespace: RefCell::new(HashMap::new()), - commands: RefCell::new(Vec::new()), - data_namespace: RefCell::new(HashMap::new()), - } - } - - /// register a type to the namespace - /// - /// # Errors - /// - /// Will return `NsRegistrationError::NameAlreadyExists` if the desired name is already in use - pub fn register_type(&self, name: &str) -> Result { - if self.type_namespace.borrow().contains_key(name) { - Err(NsRegistrationError::NameAlreadyExists) - } else { - self.types.borrow_mut().push(InternalType { - traits: RefCell::new(HashSet::new()), - name: name.to_owned(), - }); - let id = self.types.borrow().len() - 1; - let _ = self - .type_namespace - .borrow_mut() - .insert(name.to_owned(), TypeNamespaceId::Types(id)); - Ok(Type { - id, - namespace: self, - }) - } - } - - /// register a trait to the namespace - /// - /// # Errors - /// - /// Will return `NsRegistrationError::NameAlreadyExists` if the desired name is already in use - pub fn register_trait(&self, name: &str) -> Result { - if self.type_namespace.borrow().contains_key(name) { - Err(NsRegistrationError::NameAlreadyExists) - } else { - self.traits.borrow_mut().push(InternalTrait { - types: RefCell::new(HashSet::new()), - name: name.to_owned(), - }); - let id = self.traits.borrow().len() - 1; - let _ = self - .type_namespace - .borrow_mut() - .insert(name.to_owned(), TypeNamespaceId::Traits(id)); - Ok(Trait { - id, - namespace: self, - }) - } - } - - /// register a command to the namespace - /// - /// # Errors - /// - /// Will return `NsRegistrationError::NameAlreadyExists` if the desired name is already in use - pub fn register_command<'a>( - &self, - name: &'a str, - // TODO: refacto with builder pattern maybe? - generics: Vec<(&'a str, Vec<&Trait>)>, - input: Option<&'a TypeDef>, - output: Option<&'a TypeDef>, - ) -> Result> { - if self.data_namespace.borrow().contains_key(name) { - Err(NsRegistrationError::NameAlreadyExists) - } else { - let mut internal_generics_namespace: HashMap> = HashMap::new(); - - for (name, conditions) in generics { - if internal_generics_namespace.contains_key(name) { - return Err(NsRegistrationError::GenericNameAlreadyExists); - } - internal_generics_namespace - .insert(name.to_owned(), conditions.iter().map(|t| t.id).collect()); - } - - if let Some(def) = input { - def.check_generics_exist(&internal_generics_namespace) - .map_err(NsRegistrationError::UnregisteredGenericsUsed)?; - } - - if let Some(def) = output { - def.check_generics_exist(&internal_generics_namespace) - .map_err(NsRegistrationError::UnregisteredGenericsUsed)?; - } - - self.commands.borrow_mut().push(InternalCommand { - name: name.to_owned(), - input: input.map(std::convert::Into::into), - output: output.map(std::convert::Into::into), - }); - let id = self.traits.borrow().len() - 1; - let _ = self - .data_namespace - .borrow_mut() - .insert(name.to_owned(), DataNamespaceId::Commands(id)); - Ok(Command { - id, - namespace: self, - }) - } - } - - pub fn get_type(&self, id: TypeId) -> Option { - (self.types.borrow().len() > id).then_some(Type { - id, - namespace: self, - }) - } - - pub fn get_trait(&self, id: TraitId) -> Option { - (self.traits.borrow().len() > id).then_some(Trait { - id, - namespace: self, - }) - } - - pub fn get_command(&self, id: CommandId) -> Option { - (self.commands.borrow().len() > id).then_some(Command { - id, - namespace: self, - }) - } - - pub fn get_type_by_name(&self, name: &str) -> Option { - if let Some(TypeNamespaceId::Types(id)) = self.type_namespace.borrow().get(name) { - Some(Type { - id: *id, - namespace: self, - }) - } else { - None - } - } - - pub fn get_trait_by_name(&self, name: &str) -> Option { - if let Some(TypeNamespaceId::Traits(id)) = self.type_namespace.borrow().get(name) { - Some(Trait { - id: *id, - namespace: self, - }) - } else { - None - } - } - - pub fn get_command_by_name(&self, name: &str) -> Option { - if let Some(DataNamespaceId::Commands(id)) = self.data_namespace.borrow().get(name) { - Some(Command { - id: *id, - namespace: self, - }) - } else { - None - } - } -} - -#[derive(Debug)] -pub enum NsRegistrationError<'a> { - NameAlreadyExists, - GenericNameAlreadyExists, - UnregisteredGenericsUsed(Vec<&'a str>), -} diff --git a/src/namespace/trait.rs b/src/namespace/trait.rs deleted file mode 100644 index 9cb3f74..0000000 --- a/src/namespace/trait.rs +++ /dev/null @@ -1,35 +0,0 @@ -use std::collections::HashSet; - -use std::cell::RefCell; -use std::fmt::Debug; -use std::fmt::Display; - -use super::GlobalNamespace; -use super::TraitId; -use super::TypeId; - -#[derive(Clone, Copy)] -pub struct Trait<'a> { - pub(super) id: TraitId, - pub(super) namespace: &'a GlobalNamespace, -} - -impl Display for Trait<'_> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let name = &self.namespace.traits.borrow()[self.id].name; - - f.write_fmt(format_args!("{name}")) - } -} - -impl Debug for Trait<'_> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "Trait({self})") - } -} - -pub(super) struct InternalTrait { - // make resolution easier - pub(super) types: RefCell>, - pub(super) name: String, -} diff --git a/src/namespace/type.rs b/src/namespace/type.rs deleted file mode 100644 index 18a1bad..0000000 --- a/src/namespace/type.rs +++ /dev/null @@ -1,55 +0,0 @@ -use std::collections::HashSet; - -use std::cell::RefCell; -use std::fmt::Debug; -use std::fmt::Display; - -use super::Trait; - -use super::GlobalNamespace; -use super::TraitId; -use super::TypeId; - -#[derive(Clone, Copy)] -pub struct Type<'a> { - pub(super) id: TypeId, - pub(super) namespace: &'a GlobalNamespace, -} - -impl<'a> Type<'a> { - pub fn add_trait(&self, to_add: &'a Trait) { - let internal_self = &self.namespace.types.borrow()[self.id]; - - internal_self.traits.borrow_mut().insert(to_add.id); - self.namespace.traits.borrow_mut()[to_add.id] - .types - .borrow_mut() - .insert(self.id); - } - - pub fn has_trait(&self, to_check: &'a Trait) -> bool { - self.namespace.types.borrow()[self.id] - .traits - .borrow() - .contains(&to_check.id) - } -} - -impl Display for Type<'_> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let name = &self.namespace.types.borrow()[self.id].name; - - f.write_fmt(format_args!("{name}")) - } -} - -impl Debug for Type<'_> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "Type({self})") - } -} - -pub(super) struct InternalType { - pub(super) traits: RefCell>, - pub(super) name: String, -} diff --git a/src/namespace/typedef.rs b/src/namespace/typedef.rs deleted file mode 100644 index 8afb772..0000000 --- a/src/namespace/typedef.rs +++ /dev/null @@ -1,184 +0,0 @@ -use std::collections::HashMap; -use std::fmt::Debug; -use std::fmt::Display; - -use super::TraitId; -use super::TypeId; - -use super::GlobalNamespace; - -use super::r#type::Type; - -pub enum TypeDef<'a> { - Type(Type<'a>), - Generic(String), - List(Vec>), - Record(Vec<(String, TypeDef<'a>)>), -} - -impl<'a> TypeDef<'a> { - pub(super) fn check_generics_exist( - &'a self, - map: &HashMap>, - ) -> Result<(), Vec<&'a str>> { - match self { - TypeDef::Type(_) => Ok(()), - TypeDef::Generic(name) => { - if map.contains_key(name) { - Ok(()) - } else { - Err(vec![name]) - } - } - TypeDef::List(defs) => { - let r = defs - .iter() - .map(|def| def.check_generics_exist(map)) - .filter_map(|check_res| { - if let Err(invalid_names) = check_res { - Some(invalid_names) - } else { - None - } - }) - .reduce(|mut acc, mut errs| { - acc.append(&mut errs); - acc - }); - - match r { - Some(e) => Err(e), - None => Ok(()), - } - } - TypeDef::Record(rec) => { - let r = rec - .iter() - .map(|(_n, def)| def.check_generics_exist(map)) - .filter_map(|check_res| { - if let Err(invalid_names) = check_res { - Some(invalid_names) - } else { - None - } - }) - .reduce(|mut acc, mut errs| { - acc.append(&mut errs); - acc - }); - - match r { - Some(e) => Err(e), - None => Ok(()), - } - } - } - } - pub(super) fn from_internal(ns: &'a GlobalNamespace, def: &InternalTypeDef) -> TypeDef<'a> { - match def { - InternalTypeDef::Single(id) => TypeDef::Type( - ns.get_type(*id) - .expect("Unregistered internal type ID. This is a bug."), - ), - InternalTypeDef::Generic(name) => TypeDef::Generic(name.clone()), - InternalTypeDef::List(list) => TypeDef::List( - list.iter() - .map(|def| Self::from_internal(ns, def)) - .collect(), - ), - InternalTypeDef::Record(rec) => TypeDef::Record( - rec.iter() - .map(|(name, def)| (name.clone(), Self::from_internal(ns, def))) - .collect(), - ), - } - } -} - -impl Display for TypeDef<'_> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - TypeDef::Type(t) => Display::fmt(&t, f), - TypeDef::Generic(name) => Display::fmt(name, f), - TypeDef::List(l) => { - f.write_str("[ ")?; - if let Some(first) = l.first() { - Display::fmt(&first, f)?; - } - for item in l.iter().skip(1) { - f.write_str(", ")?; - Display::fmt(&item, f)?; - } - f.write_str(" ]") - } - TypeDef::Record(rec) => { - f.write_str("{ ")?; - for (i, item) in rec.iter().enumerate() { - if i != 0 { - f.write_str(", ")?; - } - f.write_fmt(format_args!("{}: {}", item.0, item.1))?; - } - f.write_str(" }") - } - } - } -} - -impl Debug for TypeDef<'_> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - TypeDef::Type(t) => Debug::fmt(&t, f), - TypeDef::Generic(name) => Debug::fmt(name, f), - TypeDef::List(l) => { - f.write_str("[ ")?; - for (i, item) in l.iter().enumerate() { - if i != 0 { - f.write_str(", ")?; - } - Debug::fmt(&item, f)?; - } - f.write_str(" ]") - } - TypeDef::Record(rec) => { - f.write_str("{ ")?; - for (i, item) in rec.iter().enumerate() { - if i != 0 { - f.write_str(", ")?; - } - f.write_fmt(format_args!("{:?}: {:?}", item.0, item.1))?; - } - f.write_str(" }") - } - } - } -} - -impl<'a> From> for TypeDef<'a> { - fn from(value: Type<'a>) -> Self { - TypeDef::Type(value) - } -} - -pub(super) enum InternalTypeDef { - Single(TypeId), - Generic(String), - List(Vec), - Record(Vec<(String, InternalTypeDef)>), -} - -impl From<&TypeDef<'_>> for InternalTypeDef { - fn from(value: &TypeDef) -> Self { - match value { - TypeDef::Type(val) => Self::Single(val.id), - // TODO: rewrite this to be better - TypeDef::Generic(name) => Self::Generic(name.to_owned()), - TypeDef::List(list) => Self::List(list.iter().map(std::convert::Into::into).collect()), - TypeDef::Record(rec) => Self::Record( - rec.iter() - .map(|(name, typ)| (name.to_owned(), typ.into())) - .collect(), - ), - } - } -} diff --git a/src/syntax/check.rs b/src/syntax/check.rs deleted file mode 100644 index ff5b76e..0000000 --- a/src/syntax/check.rs +++ /dev/null @@ -1,214 +0,0 @@ -#[cfg(test)] -#[allow(clippy::unwrap_used, reason = "these are tests. they may unwrap.")] -mod test; - -use crate::{ - error::{ErrorKind, Errors, SyntaxErrorKind}, - syntax::CommandPart, -}; - -use super::{CommandPartKind, PipelineElement, PipelineElementKind}; - -pub fn check(syntax: &[PipelineElement]) -> Result<(), Vec> { - let mut errs = Vec::new(); - - if let Err(e_span) = check_missing_streamer(syntax) { - errs.push(Errors::new_single( - ErrorKind::SyntaxError(SyntaxErrorKind::MissingStreamer), - e_span, - )); - } - - if let Err(err_locs) = check_missing_filters(syntax) { - errs.push(Errors::new( - ErrorKind::SyntaxError(SyntaxErrorKind::MissingFilter), - err_locs, - )); - } - - if let Err(e_span) = check_missing_sink(syntax) { - errs.push(Errors::new_single( - ErrorKind::SyntaxError(SyntaxErrorKind::MissingSink), - e_span, - )); - } - - if let Err(e_span) = check_literal_as_sink(syntax) { - errs.push(Errors::new_single( - ErrorKind::SyntaxError(SyntaxErrorKind::LiteralAsSink), - e_span, - )); - } - - if let Err(err_locs) = check_literal_as_filter(syntax) { - errs.push(Errors::new( - ErrorKind::SyntaxError(SyntaxErrorKind::LiteralAsFilter), - err_locs, - )); - } - - if let Err(e_span) = check_literal_with_args(syntax) { - errs.push(Errors::new_single( - ErrorKind::SyntaxError(SyntaxErrorKind::LiteralWithArgs), - e_span, - )); - } - - if errs.is_empty() { - Ok(()) - } else { - Err(errs) - } -} - -fn check_missing_streamer(syntax: &[PipelineElement]) -> Result<(), logos::Span> { - if let Some(&PipelineElement { - kind: PipelineElementKind::Pipe, - ref span, - }) = syntax.first() - { - Err(span.clone()) - } else { - Ok(()) - } -} - -fn check_missing_filters(syntax: &[PipelineElement]) -> Result<(), Vec> { - let mut missing_filter_locs = Vec::new(); - - for i in 0..syntax.len() { - if let ( - Some(&PipelineElement { - kind: PipelineElementKind::Pipe, - ref span, - }), - Some(&PipelineElement { - kind: PipelineElementKind::Pipe, - span: ref span1, - }), - ) = (syntax.get(i), syntax.get(i + 1)) - { - missing_filter_locs.push(span.start..span1.end); - } - } - - if missing_filter_locs.is_empty() { - Ok(()) - } else { - Err(missing_filter_locs) - } -} - -fn check_missing_sink(syntax: &[PipelineElement]) -> Result<(), logos::Span> { - if let Some(&PipelineElement { - kind: PipelineElementKind::Pipe, - ref span, - }) = syntax.last() - { - Err(span.clone()) - } else { - Ok(()) - } -} - -fn check_literal_as_sink(syntax: &[PipelineElement]) -> Result<(), logos::Span> { - let last_block: Option<&[PipelineElement]> = syntax - .split(|PipelineElement { kind, .. }| kind == &PipelineElementKind::Pipe) - .last(); - - // there HAS to be a better way to do this... this is HORRIBLE - if let Some(last_block) = last_block { - if let Some(PipelineElement { - kind: PipelineElementKind::Command(parts), - span, - }) = last_block.first() - { - if let Some(first_part) = parts.first() { - if matches!( - first_part, - CommandPart { - kind: CommandPartKind::Word(_), - .. - } - ) { - Ok(()) - } else { - Err(span.clone()) - } - } else { - Ok(()) - } - } else { - Ok(()) - } - } else { - Ok(()) - } -} - -fn check_literal_as_filter(syntax: &[PipelineElement]) -> Result<(), Vec> { - let errs = syntax - .iter() - .take(syntax.len() - 1) - .skip(1) - .filter(|element| { - !matches!( - element, - PipelineElement { - kind: PipelineElementKind::Pipe, - .. - } - ) - }) - .map(|item| { - let PipelineElement { - kind: PipelineElementKind::Command(c), - span, - } = item - else { - return None; - }; - - let Some(CommandPart { kind, .. }) = c.first() else { - return None; - }; - - if matches!(kind, CommandPartKind::Word(_)) { - None - } else { - Some(span) - } - }) - .filter_map(|err| err.map(Clone::clone)) - .collect::>(); - - if errs.is_empty() { - Ok(()) - } else { - Err(errs) - } -} - -fn check_literal_with_args(syntax: &[PipelineElement]) -> Result<(), logos::Span> { - if let Some(PipelineElement { - kind: PipelineElementKind::Command(c), - span, - }) = syntax.first() - { - if c.len() > 1 - && !matches!( - c.first(), - Some(CommandPart { - kind: CommandPartKind::Word(_), - .. - }) - ) - { - Err(span.clone()) - } else { - Ok(()) - } - } else { - Ok(()) - } -} diff --git a/src/syntax/check/test.rs b/src/syntax/check/test.rs deleted file mode 100644 index 9166ea3..0000000 --- a/src/syntax/check/test.rs +++ /dev/null @@ -1,66 +0,0 @@ -use crate::syntax::{ - check::{ - check_literal_as_filter, check_literal_as_sink, check_literal_with_args, - check_missing_filters, check_missing_sink, check_missing_streamer, - }, - parse_syntax, -}; - -#[test] -fn test_check_missing_streamer() { - let test_data = "| invert | save \"./image_processed.jpg\""; - let syntax = parse_syntax(test_data).unwrap(); - - assert_eq!(check_missing_streamer(&syntax), Err(0..1)); -} - -#[test] -fn test_check_missing_filters() { - let test_data = "meow | | test | awa | | nya"; - let syntax = parse_syntax(test_data).unwrap(); - - assert_eq!(check_missing_filters(&syntax), Err(vec![5..8, 20..25])); -} - -#[test] -fn test_check_missing_sink() { - let test_data = "meow | invert | "; - let syntax = parse_syntax(test_data).unwrap(); - - assert_eq!(check_missing_sink(&syntax), Err(14..15)); -} - -#[test] -fn test_check_literal_as_sink() { - let test_data = "meow | test | 3"; - let syntax = parse_syntax(test_data).unwrap(); - - assert_eq!(check_literal_as_sink(&syntax), Err(14..15)); -} - -#[test] -fn test_check_literal_as_filter() { - let test_data = "meow | \"gay\" | 42 | 3.14 | uwu"; - let syntax = parse_syntax(test_data).unwrap(); - - assert_eq!( - check_literal_as_filter(&syntax), - Err(vec![7..12, 15..17, 20..24]) - ); -} - -#[test] -fn test_check_literal_as_filter_positive_on_sink() { - let test_data = "meow | 42"; - let syntax = parse_syntax(test_data).unwrap(); - - assert_eq!(check_literal_as_filter(&syntax), Ok(())); -} - -#[test] -fn test_check_literal_with_args() { - let test_data = "14 12 | sink"; - let syntax = parse_syntax(test_data).unwrap(); - - assert_eq!(check_literal_with_args(&syntax), Err(0..5)); -} diff --git a/src/syntax/mod.rs b/src/syntax/mod.rs deleted file mode 100644 index cb4bbfd..0000000 --- a/src/syntax/mod.rs +++ /dev/null @@ -1,110 +0,0 @@ -use logos::Logos; -use logos::Span; - -use crate::lexer::Token; - -pub mod check; - -#[derive(Debug, Clone, PartialEq)] -pub struct PipelineElement { - pub kind: PipelineElementKind, - pub span: Span, -} - -#[derive(Debug, Clone, PartialEq)] -pub enum PipelineElementKind { - Pipe, - Command(Vec), -} - -#[derive(Debug, Clone, PartialEq)] -pub struct CommandPart { - pub kind: CommandPartKind, - pub span: Span, -} - -#[derive(Debug, Clone, PartialEq)] -pub enum CommandPartKind { - Word(String), - Integer(i64), - Float(f64), - String(String), -} - -pub fn parse_syntax(input: &str) -> Result, Vec> { - let lexer = Token::lexer(input); - let mut errs = Vec::new(); - - let mut r = Vec::new(); - - let mut partial_command: Vec = Vec::new(); - for (tok, span) in lexer.spanned() { - if let Ok(tok) = tok { - match tok { - Token::Pipe => { - if !partial_command.is_empty() { - #[allow( - clippy::unwrap_used, - reason = "this branch can only run if partial_command isn't empty" - )] - let span = partial_command.first().unwrap().span.start - ..partial_command.last().unwrap().span.end; - r.push(PipelineElement { - kind: PipelineElementKind::Command(std::mem::take( - &mut partial_command, - )), - span, - }); - } - r.push(PipelineElement { - kind: PipelineElementKind::Pipe, - span, - }); - } - Token::Word(word) => partial_command.push(CommandPart { - kind: CommandPartKind::Word(word.to_owned()), - span, - }), - Token::IntLiteral(int) => partial_command.push(CommandPart { - kind: CommandPartKind::Integer(int), - span, - }), - Token::FloatLiteral(float) => partial_command.push(CommandPart { - kind: CommandPartKind::Float(float), - span, - }), - Token::StringLiteral(string) => partial_command.push(CommandPart { - kind: CommandPartKind::String(string), - span, - }), - } - } else { - errs.push(span); - } - } - - if !partial_command.is_empty() { - #[allow( - clippy::unwrap_used, - reason = "this branch can only run if partial_command isn't empty" - )] - let span = - partial_command.first().unwrap().span.start..partial_command.last().unwrap().span.end; - r.push(PipelineElement { - kind: PipelineElementKind::Command(std::mem::take(&mut partial_command)), - span, - }); - } - - if errs.is_empty() { - Ok(r) - } else { - Err(errs) - } -} - -#[test] -fn test_invalid_toks() { - let test_data = "meow | gay $ error!"; - assert_eq!(parse_syntax(test_data), Err(vec![11..12, 18..19])); -} diff --git a/src/typed.rs b/src/typed.rs deleted file mode 100644 index fbe86ab..0000000 --- a/src/typed.rs +++ /dev/null @@ -1,234 +0,0 @@ -use core::panic; - -use crate::{ - builtins::{TYPE_FLOAT, TYPE_INTEGER, TYPE_STRING}, - error::Errors, - namespace::{command::Command, r#type::Type, typedef::TypeDef, GlobalNamespace}, - syntax::{CommandPart, CommandPartKind, PipelineElement, PipelineElementKind}, - Span, -}; - -#[allow(dead_code, reason = "will be used later")] -#[derive(Debug)] -pub struct Expr<'a> { - kind: ExprKind<'a>, - span: Span, -} - -impl<'a> Expr<'a> { - fn try_find_concrete(&'a self, ns: &'a GlobalNamespace) -> IoTypes<'a> { - let Self { ref kind, .. } = self; - kind.try_find_concrete(ns) - } - - fn get_input_typedef(&'a self) -> Option> { - match &self.kind { - ExprKind::Command(c) => c.command.get_input_types(), - ExprKind::Literal(_) => None, - } - } -} - -#[derive(Debug)] -pub enum ExprKind<'a> { - Command(CommandExpr<'a>), - Literal(LiteralKind), -} - -impl<'a> ExprKind<'a> { - fn try_find_concrete(&'a self, ns: &'a GlobalNamespace) -> IoTypes<'a> { - match self { - ExprKind::Literal(lit) => IoTypes::Concrete(lit.get_type(ns)), - ExprKind::Command(c) => c.try_find_concrete(ns), - } - } -} - -#[derive(Debug)] -pub struct CommandExpr<'a> { - command: Command<'a>, - args: Vec>, -} - -impl<'a> CommandExpr<'a> { - fn try_find_concrete(&'a self, _ns: &'a GlobalNamespace) -> IoTypes<'a> { - let Self { command, .. } = self; - - match command.get_output_types() { - None => IoTypes::Empty, - Some(def) => { - if let Some(concrete) = ConcreteTypeDef::try_from_typedef(&def) { - IoTypes::Concrete(concrete) - } else { - // TODO: make it possible to get clear output type - IoTypes::Unclear - } - } - } - } -} - -#[derive(Debug)] -pub enum LiteralKind { - Int(i64), - Float(f64), - String(String), -} - -enum IoTypes<'a> { - /// expression does not expect/return anything - Empty, - /// expression does expect/return something, but some types are unclear - Unclear, - /// we know for sure what types the expression expects/returns - Concrete(ConcreteTypeDef<'a>), -} - -impl LiteralKind { - #[allow( - clippy::unwrap_used, - reason = "these are fetched by type name constants used for keeping names consistent in codebase, which cannot be None" - )] - fn get_type<'a>(&self, ns: &'a GlobalNamespace) -> ConcreteTypeDef<'a> { - ConcreteTypeDef::Single(match self { - LiteralKind::Int(_) => ns.get_type_by_name(TYPE_INTEGER).unwrap(), - LiteralKind::Float(_) => ns.get_type_by_name(TYPE_FLOAT).unwrap(), - LiteralKind::String(_) => ns.get_type_by_name(TYPE_STRING).unwrap(), - }) - } -} - -pub fn into_typed_repr( - ns: &GlobalNamespace, - syntax: Vec, -) -> Result, Errors> { - let mut res = Vec::new(); - let mut errs = Vec::new(); - - for item in syntax { - let PipelineElement { kind, span } = item; - match kind { - PipelineElementKind::Command(c) => { - if c.len() == 1 { - let CommandPart { kind, .. } = &c[0]; - - res.push(Expr { - kind: match kind { - CommandPartKind::Word(val) => ExprKind::Command(CommandExpr { - command: { - let Some(c) = ns.get_command_by_name(val) else { - errs.push(span); - continue; - }; - c - }, - args: Vec::new(), - }), - CommandPartKind::Integer(val) => { - ExprKind::Literal(LiteralKind::Int(*val)) - } - CommandPartKind::Float(val) => { - ExprKind::Literal(LiteralKind::Float(*val)) - } - CommandPartKind::String(val) => { - ExprKind::Literal(LiteralKind::String(val.clone())) - } - }, - span, - }); - } else { - let Some(CommandPart { - kind: CommandPartKind::Word(name), - span, - }) = c.first() - else { - panic!("tried conversion to typed representation with invalid syntax") - }; - - res.push(Expr { - kind: ExprKind::Command(CommandExpr { - command: { - let Some(c) = ns.get_command_by_name(name) else { - errs.push(span.clone()); - continue; - }; - c - }, - args: c - .iter() - .skip(1) - .map(|CommandPart { kind, span }| Expr { - kind: ExprKind::Literal(match kind { - CommandPartKind::String(val) - | CommandPartKind::Word(val) => { - LiteralKind::String(val.to_string()) - } - CommandPartKind::Integer(val) => LiteralKind::Int(*val), - CommandPartKind::Float(val) => LiteralKind::Float(*val), - }), - span: span.clone(), - }) - .collect(), - }), - span: span.clone(), - }); - } - } - PipelineElementKind::Pipe => {} - } - } - - if errs.is_empty() { - Ok(res) - } else { - Err(Errors::new(crate::error::ErrorKind::CommandNotFound, errs)) - } -} - -enum ConcreteTypeDef<'a> { - Single(Type<'a>), - List(Vec>), - Record(Vec<(String, ConcreteTypeDef<'a>)>), -} - -impl<'a> ConcreteTypeDef<'a> { - fn try_from_typedef(val: &TypeDef<'a>) -> Option { - match val { - TypeDef::Type(typ) => Some(Self::Single(*typ)), - TypeDef::Generic(_) => todo!(), - TypeDef::List(list) => { - let out: Vec> = - list.iter().filter_map(Self::try_from_typedef).collect(); - - (out.len() == list.len()).then_some(ConcreteTypeDef::List(out)) - } - TypeDef::Record(rec) => { - let out: Vec<(String, ConcreteTypeDef<'a>)> = rec - .iter() - .filter_map(|(name, def)| { - Self::try_from_typedef(def).map(|def| (name.clone(), def)) - }) - .collect(); - - (out.len() == rec.len()).then_some(ConcreteTypeDef::Record(out)) - } - } - } -} - -struct TypeChecker<'a> { - global_ns: &'a GlobalNamespace, - typed_syntax: Vec>, -} - -impl<'a> TypeChecker<'a> { - fn new(ns: &'a GlobalNamespace, syntax: Vec>) -> TypeChecker<'a> { - Self { - global_ns: ns, - typed_syntax: syntax, - } - } - - // not sure if this is the optimal alg, or even a working one, but lets see - fn check_forward() {} -}