diff --git a/mers/Cargo.toml b/mers/Cargo.toml index 7930b42..19cacb5 100755 --- a/mers/Cargo.toml +++ b/mers/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mers" -version = "0.4.0" +version = "0.5.0" edition = "2021" license = "MIT OR Apache-2.0" description = "dynamically typed but type-checked programming language" diff --git a/mers_language_server/Cargo.toml b/mers_language_server/Cargo.toml index 5690c5b..d50f591 100644 --- a/mers_language_server/Cargo.toml +++ b/mers_language_server/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -mers_lib = { path = "../mers_lib", features = ["parse"] } +mers_lib = "0.5.0" tokio = { version = "1.34.0", default-features = false, features = ["macros", "rt", "io-std"] } tower-lsp = "0.20.0" line-span = "0.1.5" diff --git a/mers_lib/examples/02_own_variable.rs b/mers_lib/examples/02_own_variable.rs new file mode 100644 index 0000000..3e78434 --- /dev/null +++ b/mers_lib/examples/02_own_variable.rs @@ -0,0 +1,60 @@ +use std::sync::Arc; + +use mers_lib::{ + data::{self, Data, MersType, Type}, + errors::CheckError, + prelude_compile::{parse, CompInfo, Config, Source}, +}; + +fn main() { + eprintln!("This is valid:"); + run("my_custom_var.debug.rust_func.debug".to_owned()).unwrap(); + eprintln!(); + + eprintln!("This is not:"); + let e = run("5.rust_func".to_owned()).err().unwrap(); + eprintln!("{e}"); +} +fn run(src: String) -> Result<(), CheckError> { + let mut source = Source::new_from_string(src); + let srca = Arc::new(source.clone()); + let parsed = parse(&mut source, &srca)?; + + // Add our custom variables to the `Config` + let (mut i1, mut i2, mut i3) = Config::new() + .bundle_std() + .add_var( + "my_custom_var".to_owned(), + Data::new(data::string::String(format!("my custom value!"))), + ) + .add_var( + "rust_func".to_owned(), + Data::new(data::function::Function::new( + |arg| { + // If the input is a string, the output is a string. + // Otherwise, the function is used incorrectly. + if arg.is_included_in(&data::string::StringT) { + Ok(Type::new(data::string::StringT)) + } else { + // Wrong argument type. The code won't compile and this is the error message shown to the user. + Err(format!("Can't call rust_func with non-string argument {arg}!").into()) + } + }, + |arg| { + let arg = arg.get(); + let arg = &arg + .as_any() + .downcast_ref::() + .unwrap() + .0; + Data::new(data::string::String(arg.chars().rev().collect())) + }, + )), + ) + .infos(); + + let compiled = parsed.compile(&mut i1, CompInfo::default())?; + compiled.check(&mut i3, None)?; + compiled.run(&mut i2); + Ok(()) +}