From 2689fd9d1ba0ac1060cd80fd5ae742a74fed5130 Mon Sep 17 00:00:00 2001 From: nganhkhoa Date: Fri, 29 Mar 2024 16:20:34 +0700 Subject: [PATCH] re-organize project --- Cargo.lock | 51 ++++++++++++++++++++----------- Cargo.toml | 12 +++++--- albireo/Cargo.toml | 12 ++++++++ {src => albireo/src}/albireo.pest | 2 +- {src => albireo/src}/albireo.rs | 34 +++++++++++++++++---- executor/Cargo.toml | 7 +++++ executor/src/errors.rs | 22 +++++++++++++ executor/src/lib.rs | 23 ++++++++++++++ src/main.rs | 29 +++++++++--------- test/simple/main.air | 4 +++ 10 files changed, 153 insertions(+), 43 deletions(-) create mode 100644 albireo/Cargo.toml rename {src => albireo/src}/albireo.pest (99%) rename {src => albireo/src}/albireo.rs (91%) create mode 100644 executor/Cargo.toml create mode 100644 executor/src/errors.rs create mode 100644 executor/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index cb02948..ee090d3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10,6 +10,14 @@ dependencies = [ "pest_derive", ] +[[package]] +name = "albireo-language" +version = "0.1.0" +dependencies = [ + "albireo", + "executor", +] + [[package]] name = "block-buffer" version = "0.10.4" @@ -54,6 +62,13 @@ dependencies = [ "crypto-common", ] +[[package]] +name = "executor" +version = "0.1.0" +dependencies = [ + "albireo", +] + [[package]] name = "generic-array" version = "0.14.7" @@ -72,9 +87,9 @@ checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" [[package]] name = "memchr" -version = "2.7.1" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" [[package]] name = "once_cell" @@ -84,9 +99,9 @@ checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "pest" -version = "2.7.7" +version = "2.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "219c0dcc30b6a27553f9cc242972b67f75b60eb0db71f0b5462f38b058c41546" +checksum = "56f8023d0fb78c8e03784ea1c7f3fa36e68a723138990b8d5a47d916b651e7a8" dependencies = [ "memchr", "thiserror", @@ -95,9 +110,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.7.7" +version = "2.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22e1288dbd7786462961e69bfd4df7848c1e37e8b74303dbdab82c3a9cdd2809" +checksum = "b0d24f72393fd16ab6ac5738bc33cdb6a9aa73f8b902e8fe29cf4e67d7dd1026" dependencies = [ "pest", "pest_generator", @@ -105,9 +120,9 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.7" +version = "2.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1381c29a877c6d34b8c176e734f35d7f7f5b3adaefe940cb4d1bb7af94678e2e" +checksum = "fdc17e2a6c7d0a492f0158d7a4bd66cc17280308bbaff78d5bef566dca35ab80" dependencies = [ "pest", "pest_meta", @@ -118,9 +133,9 @@ dependencies = [ [[package]] name = "pest_meta" -version = "2.7.7" +version = "2.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0934d6907f148c22a3acbda520c7eed243ad7487a30f51f6ce52b58b7077a8a" +checksum = "934cd7631c050f4674352a6e835d5f6711ffbfb9345c2fc0107155ac495ae293" dependencies = [ "once_cell", "pest", @@ -129,9 +144,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" dependencies = [ "unicode-ident", ] @@ -158,9 +173,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.48" +version = "2.0.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "002a1b3dbf967edfafc32655d0f377ab0bb7b994aa1d32c8cc7e9b8bf3ebb8f0" dependencies = [ "proc-macro2", "quote", @@ -169,18 +184,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.57" +version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b" +checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.57" +version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81" +checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index b974598..08984be 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,10 +1,14 @@ [package] -name = "albireo" +name = "albireo-language" version = "0.1.0" edition = "2021" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[workspace] +members = [ + "albireo" +, "executor" +] [dependencies] -pest = "2.7.6" -pest_derive = "2.7.6" +albireo = { path = "albireo" } +executor = { path = "executor" } diff --git a/albireo/Cargo.toml b/albireo/Cargo.toml new file mode 100644 index 0000000..95986de --- /dev/null +++ b/albireo/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "albireo" +version = "0.1.0" +edition = "2021" + +[lib] +path = "src/albireo.rs" + +[dependencies] +pest = "2.7.6" +pest_derive = "2.7.6" + diff --git a/src/albireo.pest b/albireo/src/albireo.pest similarity index 99% rename from src/albireo.pest rename to albireo/src/albireo.pest index 099c354..c693b22 100644 --- a/src/albireo.pest +++ b/albireo/src/albireo.pest @@ -194,7 +194,7 @@ module_declare = { } program = { - SOI ~ module_declare ~ declaration* + SOI ~ module_declare ~ declaration* ~ EOI } WHITESPACE = _{ " " | NEWLINE } diff --git a/src/albireo.rs b/albireo/src/albireo.rs similarity index 91% rename from src/albireo.rs rename to albireo/src/albireo.rs index f648dbc..4fe31ba 100644 --- a/src/albireo.rs +++ b/albireo/src/albireo.rs @@ -2,20 +2,23 @@ #[grammar = "albireo.pest"] pub struct AlbireoParser; +use pest::Parser; use pest::iterators::Pair; -use std::vec::Vec; +use std::path::Path; +use std::error::Error; +use std::fs; use std::collections::HashMap; #[derive(Clone, Debug, Eq, PartialEq, Hash)] pub struct Identifier { - name: String, + pub name: String, } #[derive(Clone, Debug)] pub struct Module { - module: ModuleInformation, - declaration: Vec + pub module: ModuleInformation, + pub declaration: HashMap } #[derive(Clone, Debug)] @@ -363,10 +366,16 @@ pub fn parse_module(parsed: Pair) -> Option { let module = p.next()?; let module_info = parse_module_declaration(module)?; - let mut declaration_list = Vec::new(); + let mut declaration_list = HashMap::new(); while let Some(declaration) = p.next() { + if declaration.as_rule() == Rule::EOI { + continue + } let declare = parse_declaration(declaration); - declaration_list.push(declare); + match declare { + Declaration::Type(ref id, _) => declaration_list.insert(id.clone(), declare), + Declaration::Variable(ref id, _, _) => declaration_list.insert(id.clone(), declare), + }; } Some(Module { @@ -374,3 +383,16 @@ pub fn parse_module(parsed: Pair) -> Option { declaration: declaration_list, }) } + +pub fn parse_file>(file: P) -> Result> { + let input = fs::read_to_string(file).expect("cannot read file"); + + let parsed = AlbireoParser::parse(Rule::program, &input) + .expect("file format is wrong or the parser is wrong") + .next() + .expect("cannot parse input file as a Albireo program"); + + let module = parse_module(parsed) + .ok_or("Cannot parse module completely")?; + Ok(module) +} diff --git a/executor/Cargo.toml b/executor/Cargo.toml new file mode 100644 index 0000000..00f475e --- /dev/null +++ b/executor/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "executor" +version = "0.1.0" +edition = "2021" + +[dependencies] +albireo = { path = "../albireo" } diff --git a/executor/src/errors.rs b/executor/src/errors.rs new file mode 100644 index 0000000..eb509e9 --- /dev/null +++ b/executor/src/errors.rs @@ -0,0 +1,22 @@ +use std::fmt; + +pub type Result = std::result::Result; + +#[derive(Debug)] +pub enum ExecutionError { + MainNotFound, + MainSignatureIncorrect, +} + +impl std::error::Error for ExecutionError {} + +impl fmt::Display for ExecutionError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + ExecutionError::MainNotFound => + write!(f, "main function not found"), + ExecutionError::MainSignatureIncorrect => + write!(f, "main function signature is incorrect, expecting Fn([], T) for any output type T"), + } + } +} diff --git a/executor/src/lib.rs b/executor/src/lib.rs new file mode 100644 index 0000000..4f50438 --- /dev/null +++ b/executor/src/lib.rs @@ -0,0 +1,23 @@ +pub mod errors; + +use errors::{Result, ExecutionError}; + +use albireo::{Expression, Type, Identifier, Module, Declaration}; + +// TODO: accepting a module map not a module +pub fn run_program(module: Module) -> Result<()> { + let main = module.declaration.get(&Identifier { name: "main".into() }) + .ok_or(ExecutionError::MainNotFound)?; + + // expecting main to be function receiving no parameter + if let Declaration::Variable(_, Type::Function(input, _), _) = main { + if input.len() != 0 { + return Err(ExecutionError::MainSignatureIncorrect) + } + } else { + return Err(ExecutionError::MainSignatureIncorrect) + }; + + println!("main {:?}", main); + Ok(()) +} diff --git a/src/main.rs b/src/main.rs index 708cb57..90f50b4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,18 +1,19 @@ -mod albireo; +use albireo::parse_file; +use executor::run_program; -use crate::albireo::{AlbireoParser, Rule, parse_module}; +use std::error::Error; -use std::fs; -use pest::Parser; - -fn main() { - let input = fs::read_to_string("test/simple/main.air").expect("cannot read file"); - - let parsed = AlbireoParser::parse(Rule::program, &input) - .expect("file format is wrong or the parser is wrong") - .next() - .expect("cannot parse input file as a Albireo program"); - - let module = parse_module(parsed); +fn main() -> Result<(), Box> { + let module = parse_file("test/simple/main.air")?; println!("{:?}", module); + match run_program(module) { + Ok(_) => { + println!("program executed successfully"); + Ok(()) + }, + Err(e) => { + println!("program executed with error: {}", e); + Err(Box::new(e)) + } + } } diff --git a/test/simple/main.air b/test/simple/main.air index 6a09335..a6db7cc 100644 --- a/test/simple/main.air +++ b/test/simple/main.air @@ -54,3 +54,7 @@ bruh2 : fn bool => number = function cond is else function x is x + 2 )(0) + + +main : fn => number = function is + 1