mirror of
https://github.com/Dummi26/mers.git
synced 2025-03-10 14:13:52 +01:00
added basic tests
This commit is contained in:
parent
657f282006
commit
b83f54cb2d
@ -25,15 +25,15 @@ println(greeting)
|
||||
println!();
|
||||
if let Ok(file_contents) = fs::read_to_string(&temp_file) {
|
||||
let mut file =
|
||||
crate::parse::file::File::new(file_contents, temp_file.to_path_buf());
|
||||
match crate::parse::parse::parse(&mut file) {
|
||||
crate::parsing::file::File::new(file_contents, temp_file.to_path_buf());
|
||||
match crate::parsing::parse::parse(&mut file) {
|
||||
Ok(func) => {
|
||||
println!(" - - - - -");
|
||||
let output = func.run(vec![]);
|
||||
println!(" - - - - -");
|
||||
println!("{}", output);
|
||||
}
|
||||
Err(e) => println!("{}", e.0.with_file_and_gsinfo(&file, e.1.as_ref())),
|
||||
Err(e) => println!("{}", e.with_file(&file)),
|
||||
}
|
||||
} else {
|
||||
println!("can't read file at {:?}!", temp_file);
|
||||
|
@ -2,9 +2,9 @@
|
||||
#![allow(dead_code)]
|
||||
|
||||
mod libs;
|
||||
mod parse;
|
||||
mod parsing;
|
||||
mod script;
|
||||
|
||||
pub use libs::inlib::*;
|
||||
pub use parse::*;
|
||||
pub use parsing::*;
|
||||
pub use script::{val_data::*, val_type::*};
|
||||
|
@ -10,7 +10,7 @@ use std::{
|
||||
};
|
||||
|
||||
use crate::{
|
||||
parse::{file::File, parse},
|
||||
parsing::{file::File, parse},
|
||||
script::{
|
||||
val_data::{VData, VDataEnum},
|
||||
val_type::VType,
|
||||
|
@ -9,7 +9,7 @@ mod interactive_mode;
|
||||
mod libs;
|
||||
#[cfg(feature = "nushell_plugin")]
|
||||
mod nushell_plugin;
|
||||
mod parse;
|
||||
mod parsing;
|
||||
mod script;
|
||||
mod tutor;
|
||||
|
||||
@ -105,7 +105,7 @@ fn normal_main() {
|
||||
};
|
||||
return;
|
||||
} else if execute {
|
||||
parse::file::File::new(
|
||||
parsing::file::File::new(
|
||||
args.iter().skip(1).fold(String::new(), |mut s, v| {
|
||||
if !s.is_empty() {
|
||||
s.push(' ');
|
||||
@ -120,11 +120,11 @@ fn normal_main() {
|
||||
std::process::exit(101);
|
||||
}
|
||||
} else {
|
||||
parse::file::File::new(std::fs::read_to_string(&args[0]).unwrap(), path.into())
|
||||
parsing::file::File::new(std::fs::read_to_string(&args[0]).unwrap(), path.into())
|
||||
}
|
||||
}
|
||||
};
|
||||
match parse::parse::parse(&mut file) {
|
||||
match parsing::parse::parse(&mut file) {
|
||||
Ok(script) => {
|
||||
println!(" - - - - -");
|
||||
let start = Instant::now();
|
||||
@ -134,10 +134,7 @@ fn normal_main() {
|
||||
println!("Output ({}s)\n{out}", elapsed.as_secs_f64());
|
||||
}
|
||||
Err(e) => {
|
||||
println!(
|
||||
"Couldn't compile:\n{}",
|
||||
e.0.with_file_and_gsinfo(&file, e.1.as_ref())
|
||||
);
|
||||
println!("Couldn't compile:\n{}", e.with_file(&file));
|
||||
std::process::exit(99);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
use std::{process::Command, sync::Arc};
|
||||
use std::{fmt::Debug, process::Command, sync::Arc};
|
||||
|
||||
use crate::{
|
||||
libs,
|
||||
@ -6,7 +6,7 @@ use crate::{
|
||||
code_macro::MacroError,
|
||||
code_parsed::*,
|
||||
code_runnable::RScript,
|
||||
global_info::{GlobalScriptInfo, GSInfo},
|
||||
global_info::{GSInfo, GlobalScriptInfo},
|
||||
to_runnable::{self, ToRunnableError},
|
||||
val_data::VDataEnum,
|
||||
val_type::{VSingleType, VType},
|
||||
@ -61,7 +61,11 @@ impl<'a> ScriptError {
|
||||
pub fn with_gsinfo(&'a self, info: &'a GlobalScriptInfo) -> ScriptErrorWithInfo {
|
||||
ScriptErrorWithInfo(self, info)
|
||||
}
|
||||
pub fn with_file_and_gsinfo(&'a self, file: &'a File, info: &'a GlobalScriptInfo) -> ScriptErrorWithFileAndInfo {
|
||||
pub fn with_file_and_gsinfo(
|
||||
&'a self,
|
||||
file: &'a File,
|
||||
info: &'a GlobalScriptInfo,
|
||||
) -> ScriptErrorWithFileAndInfo {
|
||||
ScriptErrorWithFileAndInfo(self, file, info)
|
||||
}
|
||||
}
|
||||
@ -82,7 +86,12 @@ impl<'a> std::fmt::Display for ScriptErrorWithFileAndInfo<'a> {
|
||||
}
|
||||
|
||||
impl ScriptError {
|
||||
fn fmt_custom(&self, f: &mut std::fmt::Formatter<'_>, file: Option<&File>, info: Option<&GlobalScriptInfo>) -> std::fmt::Result {
|
||||
fn fmt_custom(
|
||||
&self,
|
||||
f: &mut std::fmt::Formatter<'_>,
|
||||
file: Option<&File>,
|
||||
info: Option<&GlobalScriptInfo>,
|
||||
) -> std::fmt::Result {
|
||||
match &self {
|
||||
ScriptError::CannotFindPathForLibrary(e) => write!(f, "{e}"),
|
||||
ScriptError::ParseError(e) => {
|
||||
@ -102,28 +111,51 @@ impl ScriptError {
|
||||
|
||||
pub const PARSE_VERSION: u64 = 0;
|
||||
|
||||
pub struct Error {
|
||||
pub err: ScriptError,
|
||||
pub ginfo: GSInfo,
|
||||
}
|
||||
impl From<(ScriptError, GSInfo)> for Error {
|
||||
fn from(value: (ScriptError, GSInfo)) -> Self {
|
||||
Self {
|
||||
err: value.0,
|
||||
ginfo: value.1,
|
||||
}
|
||||
}
|
||||
}
|
||||
impl Debug for Error {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}", self.err.with_gsinfo(&self.ginfo))
|
||||
}
|
||||
}
|
||||
impl Error {
|
||||
pub fn with_file<'a>(&'a self, file: &'a File) -> ScriptErrorWithFileAndInfo<'a> {
|
||||
self.err.with_file_and_gsinfo(file, self.ginfo.as_ref())
|
||||
}
|
||||
}
|
||||
|
||||
/// executes the 4 parse_steps in order: lib_paths => interpret => libs_load => compile
|
||||
pub fn parse(file: &mut File) -> Result<RScript, (ScriptError, GSInfo)> {
|
||||
pub fn parse(file: &mut File) -> Result<RScript, Error> {
|
||||
let mut ginfo = GlobalScriptInfo::default();
|
||||
|
||||
let libs = match parse_step_lib_paths(file) {
|
||||
Ok(v) => v,
|
||||
Err(e) => return Err((e.into(), ginfo.to_arc())),
|
||||
Err(e) => return Err((e.into(), ginfo.to_arc()).into()),
|
||||
};
|
||||
|
||||
let func = match parse_step_interpret(file) {
|
||||
Ok(v) => v,
|
||||
Err(e) => return Err((e.into(), ginfo.to_arc())),
|
||||
Err(e) => return Err((e.into(), ginfo.to_arc()).into()),
|
||||
};
|
||||
|
||||
ginfo.libs = match parse_step_libs_load(libs, &mut ginfo) {
|
||||
Ok(v) => v,
|
||||
Err(e) => return Err((e.into(), ginfo.to_arc())),
|
||||
Err(e) => return Err((e.into(), ginfo.to_arc()).into()),
|
||||
};
|
||||
|
||||
let run = match parse_step_compile(func, ginfo) {
|
||||
Ok(v) => v,
|
||||
Err(e) => return Err((e.0.into(), e.1)),
|
||||
Err(e) => return Err((e.0.into(), e.1).into()),
|
||||
};
|
||||
|
||||
Ok(run)
|
||||
@ -198,7 +230,10 @@ pub fn parse_step_libs_load(
|
||||
Ok(libs)
|
||||
}
|
||||
|
||||
pub fn parse_step_compile(main_func: SFunction, ginfo: GlobalScriptInfo) -> Result<RScript, (ToRunnableError, GSInfo)> {
|
||||
pub fn parse_step_compile(
|
||||
main_func: SFunction,
|
||||
ginfo: GlobalScriptInfo,
|
||||
) -> Result<RScript, (ToRunnableError, GSInfo)> {
|
||||
to_runnable::to_runnable(main_func, ginfo)
|
||||
}
|
||||
|
||||
@ -341,6 +376,8 @@ use implementation::*;
|
||||
|
||||
pub mod implementation {
|
||||
|
||||
use crate::parsing::file::FilePosition;
|
||||
|
||||
use super::*;
|
||||
|
||||
fn parse_block(file: &mut File) -> Result<SBlock, ParseError> {
|
||||
@ -733,7 +770,11 @@ pub mod implementation {
|
||||
}
|
||||
"type" => {
|
||||
file.skip_whitespaces();
|
||||
break SStatementEnum::TypeDefinition(file.collect_to_whitespace(), parse_type(file)?).to();
|
||||
break SStatementEnum::TypeDefinition(
|
||||
file.collect_to_whitespace(),
|
||||
parse_type(file)?,
|
||||
)
|
||||
.to();
|
||||
}
|
||||
"true" => break SStatementEnum::Value(VDataEnum::Bool(true).to()).to(),
|
||||
"false" => {
|
||||
@ -940,7 +981,7 @@ pub mod implementation {
|
||||
/// Assumes the function name and opening bracket have already been parsed. File should continue like "name type name type ...) <statement>"
|
||||
fn parse_function(
|
||||
file: &mut File,
|
||||
err_fn_start: Option<crate::parse::file::FilePosition>,
|
||||
err_fn_start: Option<FilePosition>,
|
||||
) -> Result<SFunction, ParseError> {
|
||||
file.skip_whitespaces();
|
||||
// find the arguments to the function
|
@ -1,6 +1,6 @@
|
||||
use std::{fmt::Display, fs};
|
||||
|
||||
use crate::parse::{
|
||||
use crate::parsing::{
|
||||
file::File,
|
||||
parse::{self, ParseError, ScriptError},
|
||||
};
|
||||
@ -43,7 +43,7 @@ fn parse_mers_code(file: &mut File) -> Result<RScript, MacroError> {
|
||||
_ = file.next();
|
||||
match parse::parse(file) {
|
||||
Ok(v) => Ok(v),
|
||||
Err(e) => Err(e.0.into()),
|
||||
Err(e) => Err(e.err.into()),
|
||||
}
|
||||
} else {
|
||||
let path = parse_string_val(file);
|
||||
@ -58,7 +58,7 @@ fn parse_mers_code(file: &mut File) -> Result<RScript, MacroError> {
|
||||
);
|
||||
Ok(match parse::parse(&mut file) {
|
||||
Ok(v) => v,
|
||||
Err(e) => return Err(e.0.into()),
|
||||
Err(e) => return Err(e.err.into()),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
use std::{path::PathBuf, thread::JoinHandle, time::Instant};
|
||||
|
||||
use crate::{
|
||||
parse::{self, parse::ScriptError, file::File},
|
||||
script::{code_runnable::RScript, val_data::VDataEnum, global_info::GSInfo},
|
||||
parsing::{self, file::File, parse::ScriptError},
|
||||
script::{code_runnable::RScript, global_info::GSInfo, val_data::VDataEnum},
|
||||
};
|
||||
|
||||
mod base_comments;
|
||||
@ -30,8 +30,8 @@ false
|
||||
",
|
||||
Box::new(move |file| {
|
||||
let mut file =
|
||||
parse::file::File::new(std::fs::read_to_string(file).unwrap(), PathBuf::new());
|
||||
sender.send((parse::parse::parse(&mut file), file)).unwrap();
|
||||
parsing::file::File::new(std::fs::read_to_string(file).unwrap(), PathBuf::new());
|
||||
sender.send((parsing::parse::parse(&mut file), file)).unwrap();
|
||||
}),
|
||||
)
|
||||
.unwrap();
|
||||
@ -60,7 +60,7 @@ pub struct Tutor {
|
||||
written_status_byte_len: usize,
|
||||
editor_join_handle: JoinHandle<()>,
|
||||
file_path: PathBuf,
|
||||
receiver: std::sync::mpsc::Receiver<(Result<RScript, (ScriptError, GSInfo)>, File)>,
|
||||
receiver: std::sync::mpsc::Receiver<(Result<RScript, parsing::parse::Error>, File)>,
|
||||
// i_ are inputs from the user
|
||||
pub i_name: Option<String>,
|
||||
}
|
||||
@ -70,10 +70,11 @@ impl Tutor {
|
||||
// eprintln!(" - - - - - - - - - - - - - - - - - - - - - - - - -");
|
||||
let script = loop {
|
||||
match self.receiver.recv().unwrap() {
|
||||
(Err((e, info)), file) => {
|
||||
(Err(e), file) => {
|
||||
self.current_status = format!(
|
||||
" - Error during build{}",
|
||||
e.with_file_and_gsinfo(&file, info.as_ref()).to_string()
|
||||
e.with_file(&file)
|
||||
.to_string()
|
||||
.lines()
|
||||
.map(|v| format!("\n// {v}"))
|
||||
.collect::<String>()
|
||||
|
1
mers/tests/return_true.mers
Normal file
1
mers/tests/return_true.mers
Normal file
@ -0,0 +1 @@
|
||||
true
|
24
mers/tests/test_in_mers.rs
Normal file
24
mers/tests/test_in_mers.rs
Normal file
@ -0,0 +1,24 @@
|
||||
use std::{fs, path::Path};
|
||||
|
||||
use mers_libs::file::File;
|
||||
use mers_libs::{parse, VDataEnum};
|
||||
|
||||
#[test]
|
||||
fn run_all() {
|
||||
for file in fs::read_dir(Path::new(file!()).parent().unwrap())
|
||||
.unwrap()
|
||||
.filter_map(|v| v.ok())
|
||||
{
|
||||
if let Some(file_name) = file.file_name().to_str() {
|
||||
if file_name.ends_with(".mers") {
|
||||
eprintln!("Checking {}", file_name);
|
||||
let mut file = File::new(fs::read_to_string(file.path()).unwrap(), file.path());
|
||||
// has to return true, otherwise the test will fail
|
||||
assert!(matches!(
|
||||
parse::parse(&mut file).unwrap().run(vec![]).data,
|
||||
VDataEnum::Bool(true)
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
3
mers/tests/type_syntax.mers
Normal file
3
mers/tests/type_syntax.mers
Normal file
@ -0,0 +1,3 @@
|
||||
var: [string ...] = [...]
|
||||
&var.push("a string")
|
||||
var.len().eq(1)
|
Loading…
Reference in New Issue
Block a user