diff --git a/Cargo.toml b/Cargo.toml index 18a673d..5d8753d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,6 @@ members = [ "compiler/cl-repl", "compiler/cl-typeck", - "compiler/cl-embed", "compiler/cl-interpret", "compiler/cl-structures", "compiler/cl-token", @@ -14,7 +13,7 @@ resolver = "2" [workspace.package] repository = "https://git.soft.fish/j/Conlang" -version = "0.0.10" +version = "0.0.11" authors = ["John Breaux "] edition = "2024" license = "MIT" diff --git a/compiler/cl-embed/Cargo.toml b/compiler/cl-embed/Cargo.toml deleted file mode 100644 index e97bfb7..0000000 --- a/compiler/cl-embed/Cargo.toml +++ /dev/null @@ -1,18 +0,0 @@ -[package] -name = "cl-embed" -version = "0.1.0" -repository.workspace = true -authors.workspace = true -edition.workspace = true -license.workspace = true -publish.workspace = true - -[dependencies] -cl-interpret = { path = "../cl-interpret" } -cl-ast = { path = "../cl-ast" } -cl-structures = { path = "../cl-structures" } -cl-lexer = { path = "../cl-lexer" } -cl-parser = { path = "../cl-parser" } - -[dev-dependencies] -repline = { version = "*", registry = "soft-fish" } diff --git a/compiler/cl-embed/examples/calculator.rs b/compiler/cl-embed/examples/calculator.rs deleted file mode 100644 index 3fc4db1..0000000 --- a/compiler/cl-embed/examples/calculator.rs +++ /dev/null @@ -1,27 +0,0 @@ -//! Demonstrates the cl_embed library - -use cl_embed::*; -use repline::{Response, prebaked}; - -fn main() -> Result<(), repline::Error> { - let mut env = Environment::new(); - - if let Err(e) = conlang_include!("calculator/expression.cl")(&mut env) { - panic!("{e}") - } - - prebaked::read_and("", "calc >", " ? >", |line| { - env.bind("line", line); - - let res = conlang! { - - let (expr, rest) = parse(line.chars(), Power::None); - execute(expr) - - }(&mut env)?; - - println!("{res}"); - - Ok(Response::Accept) - }) -} diff --git a/compiler/cl-embed/examples/calculator/expression.cl b/compiler/cl-embed/examples/calculator/expression.cl deleted file mode 120000 index 85b49cd..0000000 --- a/compiler/cl-embed/examples/calculator/expression.cl +++ /dev/null @@ -1 +0,0 @@ -../../../../sample-code/calculator.cl \ No newline at end of file diff --git a/compiler/cl-embed/src/lib.rs b/compiler/cl-embed/src/lib.rs deleted file mode 100644 index 9062758..0000000 --- a/compiler/cl-embed/src/lib.rs +++ /dev/null @@ -1,182 +0,0 @@ -//! Embed Conlang code into your Rust project! -//! -//! # This crate is experimental, and has no guarantees of stability. -#![feature(decl_macro)] -#![cfg_attr(test, feature(assert_matches))] -#![allow(unused_imports)] - -pub use cl_interpret::{convalue::ConValue as Value, env::Environment}; - -use cl_ast::{Block, File, Module, ast_visitor::Fold}; -use cl_interpret::{convalue::ConValue, interpret::Interpret}; -use cl_lexer::Lexer; -use cl_parser::{Parser, error::Error as ParseError, inliner::ModuleInliner}; -use std::{path::Path, sync::OnceLock}; - -/// Constructs a function which evaluates a Conlang Block -/// -/// # Examples -/// -/// Bind and use a variable -/// ```rust -/// # fn main() -> Result<(), Box> { -/// use cl_embed::{conlang, Environment, Value}; -/// -/// let mut env = Environment::new(); -/// -/// // Bind a variable named `message` to "Hello, world!" -/// env.bind("message", "Hello, World!"); -/// -/// let print_hello = conlang!{ -/// println(message); -/// }; -/// -/// // Run the function -/// let ret = print_hello(&mut env)?; -/// -/// // `println` returns Empty -/// assert!(matches!(ret, Value::Empty)); -/// -/// # Ok(()) -/// # } -/// ``` -pub macro conlang( - $($t:tt)* -) {{ - // Parse once - static FN: OnceLock> = OnceLock::new(); - - |env: &mut Environment| -> Result { - FN.get_or_init(|| { - // TODO: embed the full module tree at compile time - let path = - AsRef::::as_ref(&concat!(env!("CARGO_MANIFEST_DIR"), "/../../", file!())) - .with_extension(""); - let mut mi = ModuleInliner::new(path); - let code = mi.fold_block( - Parser::new( - concat!(file!(), ":", line!(), ":", column!()), - Lexer::new(stringify!({ $($t)* })), - ) - .parse::()?, - ); - if let Some((ie, pe)) = mi.into_errs() { - for (file, err) in ie { - eprintln!("{}: {err}", file.display()); - } - for (file, err) in pe { - eprintln!("{}: {err}", file.display()); - } - } - Ok(code) - }) - .as_ref() - .map_err(Clone::clone)? - .interpret(env) - .map_err(Into::into) - } -}} - -pub macro conlang_include{ - ($path:literal, $name:ident) => { - |env: &mut Environment| -> Result { - // TODO: embed the full module tree at compile time - let path = AsRef::::as_ref(&concat!(env!("CARGO_MANIFEST_DIR"), "/../../", file!())) - .with_file_name(concat!($path)); - let mut mi = ModuleInliner::new(path); - let code = mi.fold_module(Module { - name: stringify!($name).into(), - file: Some( - Parser::new( - concat!(file!(), ":", line!(), ":", column!()), - Lexer::new(include_str!($path)), - ) - .parse()?, - ), - }); - if let Some((ie, pe)) = mi.into_errs() { - for (file, err) in ie { - eprintln!("{}: {err}", file.display()); - } - for (file, err) in pe { - eprintln!("{}: {err}", file.display()); - } - } - code.interpret(env).map_err(Into::into) - } - }, - ($path:literal) => { - |env: &mut Environment| -> Result { - // TODO: embed the full module tree at compile time - let path = AsRef::::as_ref(&concat!(env!("CARGO_MANIFEST_DIR"), "/../../", file!())) - .with_file_name(concat!($path)); - let mut mi = ModuleInliner::new(path); - let code = mi.fold_file( - Parser::new( - concat!(file!(), ":", line!(), ":", column!()), - Lexer::new(include_str!($path)), - ) - .parse()?, - ); - if let Some((ie, pe)) = mi.into_errs() { - for (file, err) in ie { - eprintln!("{}: {err}", file.display()); - } - for (file, err) in pe { - eprintln!("{}: {err}", file.display()); - } - } - code.interpret(env).map_err(Into::into) - } - } -} - -#[derive(Clone, Debug)] -pub enum EvalError { - Parse(cl_parser::error::Error), - Interpret(cl_interpret::error::Error), -} - -impl From for EvalError { - fn from(value: cl_parser::error::Error) -> Self { - Self::Parse(value) - } -} -impl From for EvalError { - fn from(value: cl_interpret::error::Error) -> Self { - Self::Interpret(value) - } -} -impl std::error::Error for EvalError {} -impl std::fmt::Display for EvalError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - EvalError::Parse(error) => error.fmt(f), - EvalError::Interpret(error) => error.fmt(f), - } - } -} - -#[cfg(test)] -mod tests { - use std::assert_matches::assert_matches; - - use super::*; - - #[test] - fn it_works() -> Result<(), EvalError> { - let mut env = Environment::new(); - - let result = conlang! { - fn add(left, right) -> isize { - left + right - } - - add(2, 2) - }(&mut env); - - assert_matches!(result, Ok(Value::Int(4))); - - Ok(()) - } -}