mirror of
				https://github.com/Dummi26/mers.git
				synced 2025-11-04 05:16:17 +01:00 
			
		
		
		
	added nushell support.
This commit is contained in:
		
							parent
							
								
									1a446248e4
								
							
						
					
					
						commit
						0feb1b8778
					
				@ -34,9 +34,12 @@ The compiler checks your program. It will guarantee type-safety. If a variable h
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
## building mers
 | 
					## building mers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
to use mers, clone this repo and compile it using cargo. (if you don't have rustc and cargo, get it from https://rustup.rs/. the mers project is in the mers subdirectory, one level deeper than this readme.)
 | 
					Build scripts can be found in build_scripts/ and compile mers using cargo. If you don't have rustc and cargo, install it using [rustup](https://rustup.rs/).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
for simplicity, i will assume you have the executable in your path and it is named mers. Since this probably isn't the case, just know that `mers` can be replaced with `cargo run --release` in all of the following commands.
 | 
					If you're using [Nushell](https://www.nushell.sh/), there is a script that integrates mers, since most mers values can be converted to ones nu understands.
 | 
				
			||||||
 | 
					I would recommend that you put the normal mers binary in your PATH even if you want to use mers-nu, because it has more CLI options.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For simplicity, i will assume you have the executable in your path and it is named mers. Since this probably isn't the case, just know that `mers` can be replaced with `cargo run --release` in all of the following commands, assuming you are located in the mers/ directory.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### running from a file
 | 
					### running from a file
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										1089
									
								
								mers/Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										1089
									
								
								mers/Cargo.lock
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -14,3 +14,12 @@ edit = "0.1.4"
 | 
				
			|||||||
notify = "5.1.0"
 | 
					notify = "5.1.0"
 | 
				
			||||||
regex = "1.7.2"
 | 
					regex = "1.7.2"
 | 
				
			||||||
static_assertions = "1.1.0"
 | 
					static_assertions = "1.1.0"
 | 
				
			||||||
 | 
					nu-plugin = { version = "0.79.0", optional = true }
 | 
				
			||||||
 | 
					nu-protocol = { version = "0.79.0", features = ["plugin"], optional = true }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[features]
 | 
				
			||||||
 | 
					# default = ["nushell_plugin"]
 | 
				
			||||||
 | 
					nushell_plugin = ["dep:nu-plugin", "dep:nu-protocol"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[profile.nushellplugin]
 | 
				
			||||||
 | 
					inherits = "release"
 | 
				
			||||||
 | 
				
			|||||||
@ -309,7 +309,7 @@ where
 | 
				
			|||||||
        't' | 'l' => {
 | 
					        't' | 'l' => {
 | 
				
			||||||
            let mut v = vec![];
 | 
					            let mut v = vec![];
 | 
				
			||||||
            loop {
 | 
					            loop {
 | 
				
			||||||
                if stdout.one_byte().unwrap() == '\n' as _ {
 | 
					                if stdout.one_byte().unwrap() == '\n' as u8 {
 | 
				
			||||||
                    break if id_byte == 't' {
 | 
					                    break if id_byte == 't' {
 | 
				
			||||||
                        VDataEnum::Tuple(v)
 | 
					                        VDataEnum::Tuple(v)
 | 
				
			||||||
                    } else {
 | 
					                    } else {
 | 
				
			||||||
 | 
				
			|||||||
@ -7,11 +7,20 @@ use notify::Watcher as FsWatcher;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
mod interactive_mode;
 | 
					mod interactive_mode;
 | 
				
			||||||
mod libs;
 | 
					mod libs;
 | 
				
			||||||
 | 
					#[cfg(feature = "nushell_plugin")]
 | 
				
			||||||
 | 
					mod nushell_plugin;
 | 
				
			||||||
mod parse;
 | 
					mod parse;
 | 
				
			||||||
mod script;
 | 
					mod script;
 | 
				
			||||||
mod tutor;
 | 
					mod tutor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn main() {
 | 
					fn main() {
 | 
				
			||||||
 | 
					    #[cfg(not(feature = "nushell_plugin"))]
 | 
				
			||||||
 | 
					    normal_main();
 | 
				
			||||||
 | 
					    #[cfg(feature = "nushell_plugin")]
 | 
				
			||||||
 | 
					    nushell_plugin::main();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn normal_main() {
 | 
				
			||||||
    let args: Vec<_> = std::env::args().skip(1).collect();
 | 
					    let args: Vec<_> = std::env::args().skip(1).collect();
 | 
				
			||||||
    #[cfg(debug_assertions)]
 | 
					    #[cfg(debug_assertions)]
 | 
				
			||||||
    let args = if args.len() == 0 {
 | 
					    let args = if args.len() == 0 {
 | 
				
			||||||
@ -125,7 +134,10 @@ fn main() {
 | 
				
			|||||||
            println!("Output ({}s)\n{out}", elapsed.as_secs_f64());
 | 
					            println!("Output ({}s)\n{out}", elapsed.as_secs_f64());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        Err(e) => {
 | 
					        Err(e) => {
 | 
				
			||||||
            println!("Couldn't compile:\n{}", e.0.with_file_and_gsinfo(&file, e.1.as_ref()));
 | 
					            println!(
 | 
				
			||||||
 | 
					                "Couldn't compile:\n{}",
 | 
				
			||||||
 | 
					                e.0.with_file_and_gsinfo(&file, e.1.as_ref())
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
            std::process::exit(99);
 | 
					            std::process::exit(99);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -8,7 +8,7 @@ use crate::libs;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
use super::{
 | 
					use super::{
 | 
				
			||||||
    code_runnable::RStatement,
 | 
					    code_runnable::RStatement,
 | 
				
			||||||
    global_info::{GlobalScriptInfo, GSInfo},
 | 
					    global_info::{GSInfo, GlobalScriptInfo},
 | 
				
			||||||
    val_data::{thread::VDataThreadEnum, VData, VDataEnum},
 | 
					    val_data::{thread::VDataThreadEnum, VData, VDataEnum},
 | 
				
			||||||
    val_type::{VSingleType, VType},
 | 
					    val_type::{VSingleType, VType},
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
@ -276,14 +276,18 @@ impl BuiltinFunction {
 | 
				
			|||||||
            Self::Sleep => {
 | 
					            Self::Sleep => {
 | 
				
			||||||
                input.len() == 1
 | 
					                input.len() == 1
 | 
				
			||||||
                    && input[0]
 | 
					                    && input[0]
 | 
				
			||||||
                        .fits_in(&VType {
 | 
					                        .fits_in(
 | 
				
			||||||
                            types: vec![VSingleType::Int, VSingleType::Float],
 | 
					                            &VType {
 | 
				
			||||||
                        }, info)
 | 
					                                types: vec![VSingleType::Int, VSingleType::Float],
 | 
				
			||||||
 | 
					                            },
 | 
				
			||||||
 | 
					                            info,
 | 
				
			||||||
 | 
					                        )
 | 
				
			||||||
                        .is_empty()
 | 
					                        .is_empty()
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            Self::Exit => {
 | 
					            Self::Exit => {
 | 
				
			||||||
                input.len() == 0
 | 
					                input.len() == 0
 | 
				
			||||||
                    || (input.len() == 1 && input[0].fits_in(&VSingleType::Int.to(), info).is_empty())
 | 
					                    || (input.len() == 1
 | 
				
			||||||
 | 
					                        && input[0].fits_in(&VSingleType::Int.to(), info).is_empty())
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            // TODO!
 | 
					            // TODO!
 | 
				
			||||||
            Self::FsList => true,
 | 
					            Self::FsList => true,
 | 
				
			||||||
@ -307,7 +311,8 @@ impl BuiltinFunction {
 | 
				
			|||||||
                input.len() == 1 && input[0].fits_in(&VSingleType::String.to(), info).is_empty()
 | 
					                input.len() == 1 && input[0].fits_in(&VSingleType::String.to(), info).is_empty()
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            Self::RunCommand | Self::RunCommandGetBytes => {
 | 
					            Self::RunCommand | Self::RunCommandGetBytes => {
 | 
				
			||||||
                if input.len() >= 1 && input[0].fits_in(&VSingleType::String.to(), info).is_empty() {
 | 
					                if input.len() >= 1 && input[0].fits_in(&VSingleType::String.to(), info).is_empty()
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
                    if input.len() == 1 {
 | 
					                    if input.len() == 1 {
 | 
				
			||||||
                        true
 | 
					                        true
 | 
				
			||||||
                    } else if input.len() == 2 {
 | 
					                    } else if input.len() == 2 {
 | 
				
			||||||
@ -328,11 +333,15 @@ impl BuiltinFunction {
 | 
				
			|||||||
                        types: vec![VSingleType::Int, VSingleType::Float],
 | 
					                        types: vec![VSingleType::Int, VSingleType::Float],
 | 
				
			||||||
                    };
 | 
					                    };
 | 
				
			||||||
                    let st = VSingleType::String.to();
 | 
					                    let st = VSingleType::String.to();
 | 
				
			||||||
                    (input[0].fits_in(&num, info).is_empty() && input[1].fits_in(&num, info).is_empty())
 | 
					                    (input[0].fits_in(&num, info).is_empty()
 | 
				
			||||||
                        || (input[0].fits_in(&st, info).is_empty() && input[1].fits_in(&st, info).is_empty())
 | 
					                        && input[1].fits_in(&num, info).is_empty())
 | 
				
			||||||
 | 
					                        || (input[0].fits_in(&st, info).is_empty()
 | 
				
			||||||
 | 
					                            && input[1].fits_in(&st, info).is_empty())
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            Self::Not => input.len() == 1 && input[0].fits_in(&VSingleType::Bool.to(), info).is_empty(),
 | 
					            Self::Not => {
 | 
				
			||||||
 | 
					                input.len() == 1 && input[0].fits_in(&VSingleType::Bool.to(), info).is_empty()
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            Self::And | Self::Or => {
 | 
					            Self::And | Self::Or => {
 | 
				
			||||||
                input.len() == 2
 | 
					                input.len() == 2
 | 
				
			||||||
                    && input
 | 
					                    && input
 | 
				
			||||||
@ -354,7 +363,8 @@ impl BuiltinFunction {
 | 
				
			|||||||
                    let num = VType {
 | 
					                    let num = VType {
 | 
				
			||||||
                        types: vec![VSingleType::Int, VSingleType::Float],
 | 
					                        types: vec![VSingleType::Int, VSingleType::Float],
 | 
				
			||||||
                    };
 | 
					                    };
 | 
				
			||||||
                    input[0].fits_in(&num, info).is_empty() && input[1].fits_in(&num, info).is_empty()
 | 
					                    input[0].fits_in(&num, info).is_empty()
 | 
				
			||||||
 | 
					                        && input[1].fits_in(&num, info).is_empty()
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            // TODO! check that we pass a reference to a list!
 | 
					            // TODO! check that we pass a reference to a list!
 | 
				
			||||||
@ -462,12 +472,15 @@ impl BuiltinFunction {
 | 
				
			|||||||
            Self::IndexOf => {
 | 
					            Self::IndexOf => {
 | 
				
			||||||
                input.len() == 2
 | 
					                input.len() == 2
 | 
				
			||||||
                    && input.iter().all(|v| {
 | 
					                    && input.iter().all(|v| {
 | 
				
			||||||
                        v.fits_in(&VType {
 | 
					                        v.fits_in(
 | 
				
			||||||
                            types: vec![
 | 
					                            &VType {
 | 
				
			||||||
                                VSingleType::String,
 | 
					                                types: vec![
 | 
				
			||||||
                                VSingleType::Reference(Box::new(VSingleType::String)),
 | 
					                                    VSingleType::String,
 | 
				
			||||||
                            ],
 | 
					                                    VSingleType::Reference(Box::new(VSingleType::String)),
 | 
				
			||||||
                        }, info)
 | 
					                                ],
 | 
				
			||||||
 | 
					                            },
 | 
				
			||||||
 | 
					                            info,
 | 
				
			||||||
 | 
					                        )
 | 
				
			||||||
                        .is_empty()
 | 
					                        .is_empty()
 | 
				
			||||||
                    })
 | 
					                    })
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@ -773,7 +786,10 @@ impl BuiltinFunction {
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
            BuiltinFunction::Println => {
 | 
					            BuiltinFunction::Println => {
 | 
				
			||||||
                if let VDataEnum::String(arg) = args[0].run(vars, info).data {
 | 
					                if let VDataEnum::String(arg) = args[0].run(vars, info).data {
 | 
				
			||||||
 | 
					                    #[cfg(not(feature = "nushell_plugin"))]
 | 
				
			||||||
                    println!("{}", arg);
 | 
					                    println!("{}", arg);
 | 
				
			||||||
 | 
					                    #[cfg(feature = "nushell_plugin")]
 | 
				
			||||||
 | 
					                    eprintln!("{}", arg);
 | 
				
			||||||
                    VDataEnum::Tuple(vec![]).to()
 | 
					                    VDataEnum::Tuple(vec![]).to()
 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
                    unreachable!()
 | 
					                    unreachable!()
 | 
				
			||||||
@ -781,12 +797,20 @@ impl BuiltinFunction {
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
            BuiltinFunction::Debug => {
 | 
					            BuiltinFunction::Debug => {
 | 
				
			||||||
                let val = args[0].run(vars, info);
 | 
					                let val = args[0].run(vars, info);
 | 
				
			||||||
 | 
					                #[cfg(not(feature = "nushell_plugin"))]
 | 
				
			||||||
                println!(
 | 
					                println!(
 | 
				
			||||||
                    "{} :: {} :: {}",
 | 
					                    "{} :: {} :: {}",
 | 
				
			||||||
                    args[0].out(info).gsi(info.clone()),
 | 
					                    args[0].out(info).gsi(info.clone()),
 | 
				
			||||||
                    val.out().gsi(info.clone()),
 | 
					                    val.out().gsi(info.clone()),
 | 
				
			||||||
                    val.gsi(info.clone())
 | 
					                    val.gsi(info.clone())
 | 
				
			||||||
                );
 | 
					                );
 | 
				
			||||||
 | 
					                #[cfg(feature = "nushell_plugin")]
 | 
				
			||||||
 | 
					                eprintln!(
 | 
				
			||||||
 | 
					                    "{} :: {} :: {}",
 | 
				
			||||||
 | 
					                    args[0].out(info).gsi(info.clone()),
 | 
				
			||||||
 | 
					                    val.out().gsi(info.clone()),
 | 
				
			||||||
 | 
					                    val.gsi(info.clone())
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
                VDataEnum::Tuple(vec![]).to()
 | 
					                VDataEnum::Tuple(vec![]).to()
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            Self::StdinReadLine => {
 | 
					            Self::StdinReadLine => {
 | 
				
			||||||
 | 
				
			|||||||
@ -2,7 +2,7 @@ use std::sync::{Arc, Mutex};
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
use super::{
 | 
					use super::{
 | 
				
			||||||
    builtins::BuiltinFunction,
 | 
					    builtins::BuiltinFunction,
 | 
				
			||||||
    global_info::{GlobalScriptInfo, GSInfo},
 | 
					    global_info::{GSInfo, GlobalScriptInfo},
 | 
				
			||||||
    to_runnable::ToRunnableError,
 | 
					    to_runnable::ToRunnableError,
 | 
				
			||||||
    val_data::{VData, VDataEnum},
 | 
					    val_data::{VData, VDataEnum},
 | 
				
			||||||
    val_type::{VSingleType, VType},
 | 
					    val_type::{VSingleType, VType},
 | 
				
			||||||
@ -320,7 +320,9 @@ impl RStatementEnum {
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
            Self::Loop(c) => c.out(info).matches().1,
 | 
					            Self::Loop(c) => c.out(info).matches().1,
 | 
				
			||||||
            Self::For(_, _, b) => VSingleType::Tuple(vec![]).to() | b.out(info).matches().1,
 | 
					            Self::For(_, _, b) => VSingleType::Tuple(vec![]).to() | b.out(info).matches().1,
 | 
				
			||||||
            Self::BuiltinFunction(f, args) => f.returns(args.iter().map(|rs| rs.out(info)).collect(), info),
 | 
					            Self::BuiltinFunction(f, args) => {
 | 
				
			||||||
 | 
					                f.returns(args.iter().map(|rs| rs.out(info)).collect(), info)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            Self::Switch(switch_on, cases) => {
 | 
					            Self::Switch(switch_on, cases) => {
 | 
				
			||||||
                let switch_on = switch_on.out(info).types;
 | 
					                let switch_on = switch_on.out(info).types;
 | 
				
			||||||
                let mut might_return_empty = switch_on.is_empty();
 | 
					                let mut might_return_empty = switch_on.is_empty();
 | 
				
			||||||
@ -371,7 +373,7 @@ impl RScript {
 | 
				
			|||||||
        if main.inputs.len() != 1 {
 | 
					        if main.inputs.len() != 1 {
 | 
				
			||||||
            return Err(ToRunnableError::MainWrongInput);
 | 
					            return Err(ToRunnableError::MainWrongInput);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        Ok(Self { main, info: info })
 | 
					        Ok(Self { main, info })
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    pub fn run(&self, args: Vec<String>) -> VData {
 | 
					    pub fn run(&self, args: Vec<String>) -> VData {
 | 
				
			||||||
        let mut vars = Vec::with_capacity(self.info.vars);
 | 
					        let mut vars = Vec::with_capacity(self.info.vars);
 | 
				
			||||||
@ -387,4 +389,7 @@ impl RScript {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        self.main.run(&vars, &self.info)
 | 
					        self.main.run(&vars, &self.info)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    pub fn info(&self) -> &GSInfo {
 | 
				
			||||||
 | 
					        &self.info
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user