mirror of
				https://github.com/Dummi26/mers.git
				synced 2025-10-31 11:46:15 +01:00 
			
		
		
		
	change parse_int/float and debug, add spawn_command and childproc_* functions
This commit is contained in:
		
							parent
							
								
									2a218ddbe2
								
							
						
					
					
						commit
						5d752c9969
					
				| @ -11,6 +11,6 @@ repository = "https://github.com/Dummi26/mers" | |||||||
| # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||||||
| 
 | 
 | ||||||
| [dependencies] | [dependencies] | ||||||
| mers_lib = "0.4.0" | # mers_lib = "0.4.0" | ||||||
| # mers_lib = { path = "../mers_lib" } | mers_lib = { path = "../mers_lib" } | ||||||
| clap = { version = "4.3.19", features = ["derive"] } | clap = { version = "4.3.19", features = ["derive"] } | ||||||
|  | |||||||
| @ -1,6 +1,7 @@ | |||||||
| use std::{ | use std::{ | ||||||
|     fmt::Display, |     fmt::Display, | ||||||
|     process::Command, |     io::{BufRead, BufReader, Read}, | ||||||
|  |     process::{ChildStderr, ChildStdin, ChildStdout, Command, Stdio}, | ||||||
|     sync::{Arc, Mutex}, |     sync::{Arc, Mutex}, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| @ -18,7 +19,10 @@ impl Config { | |||||||
|     /// `RunCommandError` holds the error if the command can't be executed
 |     /// `RunCommandError` holds the error if the command can't be executed
 | ||||||
|     /// returns (int/(), string, string) on success (status code, stdout, stderr)
 |     /// returns (int/(), string, string) on success (status code, stdout, stderr)
 | ||||||
|     pub fn with_command_running(self) -> Self { |     pub fn with_command_running(self) -> Self { | ||||||
|         self.add_var( |         self | ||||||
|  |             .add_type("RunCommandError".to_owned(), Ok(Arc::new(RunCommandErrorT))) | ||||||
|  |             .add_type("ChildProcess".to_owned(), Ok(Arc::new(ChildProcessT))) | ||||||
|  |             .add_var( | ||||||
|             "run_command".to_string(), |             "run_command".to_string(), | ||||||
|             Data::new(data::function::Function { |             Data::new(data::function::Function { | ||||||
|                 info: Arc::new(program::run::Info::neverused()), |                 info: Arc::new(program::run::Info::neverused()), | ||||||
| @ -27,7 +31,7 @@ impl Config { | |||||||
|                     if a.types.iter().all(|t| t.as_any().downcast_ref::<data::tuple::TupleT>().is_some_and(|t| t.0.len() == 2 && t.0[0].is_included_in(&data::string::StringT) && t.0[1].iterable().is_some_and(|t| t.is_included_in(&data::string::StringT)))) { |                     if a.types.iter().all(|t| t.as_any().downcast_ref::<data::tuple::TupleT>().is_some_and(|t| t.0.len() == 2 && t.0[0].is_included_in(&data::string::StringT) && t.0[1].iterable().is_some_and(|t| t.is_included_in(&data::string::StringT)))) { | ||||||
|                         Ok(Type::newm(vec![ |                         Ok(Type::newm(vec![ | ||||||
|                             Arc::new(data::tuple::TupleT(vec![ |                             Arc::new(data::tuple::TupleT(vec![ | ||||||
|                                 Type::newm(vec![Arc::new(data::int::IntT), Arc::new(data::tuple::TupleT(vec![]))]), |                                 Type::newm(vec![Arc::new(data::int::IntT), Arc::new(data::bool::BoolT)]), | ||||||
|                                 Type::new(data::string::StringT), |                                 Type::new(data::string::StringT), | ||||||
|                                 Type::new(data::string::StringT), |                                 Type::new(data::string::StringT), | ||||||
|                             ])), |                             ])), | ||||||
| @ -38,12 +42,14 @@ impl Config { | |||||||
|                     } |                     } | ||||||
|                 }), |                 }), | ||||||
|                 run: Arc::new(|a, _i| { |                 run: Arc::new(|a, _i| { | ||||||
|                     if let Some(cmd) = a.get().as_any().downcast_ref::<data::tuple::Tuple>() { |                     let a = a.get(); | ||||||
|                         if let (Some(cmd), Some(args)) = (cmd.get(0), cmd.get(1)) { |                     let cmd = a.as_any().downcast_ref::<data::tuple::Tuple>().unwrap(); | ||||||
|                             if let (Some(cmd), Some(args)) = ( |                     let (cmd, args) = (&cmd.0[0], &cmd.0[1]); | ||||||
|                                 cmd.get().as_any().downcast_ref::<data::string::String>(), |                     let cmd = cmd.get(); | ||||||
|                                 args.get().iterable(), |                     let (cmd, args) = ( | ||||||
|                             ) { |                         cmd.as_any().downcast_ref::<data::string::String>().unwrap(), | ||||||
|  |                         args.get().iterable().unwrap(), | ||||||
|  |                     ); | ||||||
|                     match Command::new(&cmd.0) |                     match Command::new(&cmd.0) | ||||||
|                         .args(args.map(|v| v.get().to_string())) |                         .args(args.map(|v| v.get().to_string())) | ||||||
|                         .output() |                         .output() | ||||||
| @ -52,7 +58,7 @@ impl Config { | |||||||
|                             let status = if let Some(code) = output.status.code() { |                             let status = if let Some(code) = output.status.code() { | ||||||
|                                 Data::new(data::int::Int(code as _)) |                                 Data::new(data::int::Int(code as _)) | ||||||
|                             } else { |                             } else { | ||||||
|                                             Data::empty_tuple() |                                 Data::new(data::bool::Bool(output.status.success())) | ||||||
|                             }; |                             }; | ||||||
|                             let stdout = |                             let stdout = | ||||||
|                                 String::from_utf8_lossy(&output.stdout).into_owned(); |                                 String::from_utf8_lossy(&output.stdout).into_owned(); | ||||||
| @ -66,19 +72,308 @@ impl Config { | |||||||
|                         } |                         } | ||||||
|                         Err(e) => Data::new(RunCommandError(e.to_string())), |                         Err(e) => Data::new(RunCommandError(e.to_string())), | ||||||
|                     } |                     } | ||||||
|  |                 }), | ||||||
|  |                 inner_statements: None, | ||||||
|  |             }), | ||||||
|  |         ) | ||||||
|  |         .add_var( | ||||||
|  |             "spawn_command".to_string(), | ||||||
|  |             Data::new(data::function::Function { | ||||||
|  |                 info: Arc::new(program::run::Info::neverused()), | ||||||
|  |                 info_check: Arc::new(Mutex::new( CheckInfo::neverused())), | ||||||
|  |                 out: Arc::new(|a, _i| { | ||||||
|  |                     if a.types.iter().all(|t| t.as_any().downcast_ref::<data::tuple::TupleT>().is_some_and(|t| t.0.len() == 2 && t.0[0].is_included_in(&data::string::StringT) && t.0[1].iterable().is_some_and(|t| t.is_included_in(&data::string::StringT)))) { | ||||||
|  |                         Ok(Type::newm(vec![ | ||||||
|  |                             Arc::new(ChildProcessT), | ||||||
|  |                             Arc::new(RunCommandErrorT) | ||||||
|  |                         ])) | ||||||
|                     } else { |                     } else { | ||||||
|                                 unreachable!("run_command called with arguments other than (String, <Iterable>).") |                         return Err(format!("spawn_command called with invalid arguments (must be (String, Iter<String>))").into()); | ||||||
|                     } |                     } | ||||||
|                         } else { |                 }), | ||||||
|                             unreachable!("run_command called with too few arguments") |                 run: Arc::new(|a, _i| { | ||||||
|  |                     let a = a.get(); | ||||||
|  |                     let cmd = a.as_any().downcast_ref::<data::tuple::Tuple>().unwrap(); | ||||||
|  |                     let (cmd, args) = (&cmd.0[0], &cmd.0[1]); | ||||||
|  |                     let cmd = cmd.get(); | ||||||
|  |                     let (cmd, args) = ( | ||||||
|  |                         cmd.as_any().downcast_ref::<data::string::String>().unwrap(), | ||||||
|  |                         args.get().iterable().unwrap(), | ||||||
|  |                     ); | ||||||
|  |                     match Command::new(&cmd.0) | ||||||
|  |                         .args(args.map(|v| v.get().to_string())) | ||||||
|  |                         .stdin(Stdio::piped()) | ||||||
|  |                         .stdout(Stdio::piped()) | ||||||
|  |                         .stderr(Stdio::piped()) | ||||||
|  |                         .spawn() | ||||||
|  |                     { | ||||||
|  |                         Ok(mut child) => { | ||||||
|  |                             let a = child.stdin.take().unwrap(); | ||||||
|  |                             let b = BufReader::new(child.stdout.take().unwrap()); | ||||||
|  |                             let c = BufReader::new(child.stderr.take().unwrap()); | ||||||
|  |                             Data::new(ChildProcess(Arc::new(Mutex::new((child, a, b, c))))) | ||||||
|                         } |                         } | ||||||
|                     } else { |                         Err(e) => Data::new(RunCommandError(e.to_string())), | ||||||
|                         unreachable!("run_command called with non-tuple argument") |  | ||||||
|                     } |                     } | ||||||
|                 }), |                 }), | ||||||
|                 inner_statements: None, |                 inner_statements: None, | ||||||
|             }), |             }), | ||||||
|         ) |         ) | ||||||
|  |         .add_var( | ||||||
|  |             "childproc_exited".to_string(), | ||||||
|  |             Data::new(data::function::Function { | ||||||
|  |                 info: Arc::new(program::run::Info::neverused()), | ||||||
|  |                 info_check: Arc::new(Mutex::new( CheckInfo::neverused())), | ||||||
|  |                 out: Arc::new(|a, _i| { | ||||||
|  |                     if a.is_included_in(&ChildProcessT) { | ||||||
|  |                         Ok(Type::newm(vec![ | ||||||
|  |                             Arc::new(data::tuple::TupleT(vec![Type::new(data::bool::BoolT)])), | ||||||
|  |                             Arc::new(data::tuple::TupleT(vec![])), | ||||||
|  |                         ])) | ||||||
|  |                     } else { | ||||||
|  |                         return Err(format!("childproc_exited called on non-ChildProcess type {a}").into()); | ||||||
|  |                     } | ||||||
|  |                 }), | ||||||
|  |                 run: Arc::new(|a, _i| { | ||||||
|  |                     let a = a.get(); | ||||||
|  |                     let child = a.as_any().downcast_ref::<ChildProcess>().unwrap(); | ||||||
|  |                         let mut child = child.0.lock().unwrap(); | ||||||
|  |                         match child.0.try_wait() { | ||||||
|  |                             Ok(Some(_)) => Data::one_tuple(Data::new(data::bool::Bool(true))), | ||||||
|  |                             Ok(None) => Data::one_tuple(Data::new(data::bool::Bool(false))), | ||||||
|  |                             Err(_) => Data::empty_tuple(), | ||||||
|  |                         } | ||||||
|  |                 }), | ||||||
|  |                 inner_statements: None, | ||||||
|  |             }), | ||||||
|  |         ) | ||||||
|  |         .add_var( | ||||||
|  |             "childproc_await".to_string(), | ||||||
|  |             Data::new(data::function::Function { | ||||||
|  |                 info: Arc::new(program::run::Info::neverused()), | ||||||
|  |                 info_check: Arc::new(Mutex::new( CheckInfo::neverused())), | ||||||
|  |                 out: Arc::new(|a, _i| { | ||||||
|  |                     if a.is_included_in(&ChildProcessT) { | ||||||
|  |                         Ok(Type::newm(vec![ | ||||||
|  |                             Arc::new(data::int::IntT), | ||||||
|  |                             Arc::new(data::bool::BoolT), | ||||||
|  |                             Arc::new(data::tuple::TupleT(vec![])), | ||||||
|  |                         ])) | ||||||
|  |                     } else { | ||||||
|  |                         return Err(format!("childproc_exited called on non-ChildProcess type {a}").into()); | ||||||
|  |                     } | ||||||
|  |                 }), | ||||||
|  |                 run: Arc::new(|a, _i| { | ||||||
|  |                     let a = a.get(); | ||||||
|  |                     let child = a.as_any().downcast_ref::<ChildProcess>().unwrap(); | ||||||
|  |                         let mut child = child.0.lock().unwrap(); | ||||||
|  |                         match child.0.wait() { | ||||||
|  |                             Ok(s) => if let Some(s) = s.code() { | ||||||
|  |                                 Data::new(data::int::Int(s as _)) | ||||||
|  |                             } else { | ||||||
|  |                                 Data::new(data::bool::Bool(s.success())) | ||||||
|  |                             } | ||||||
|  |                             Err(_) => Data::empty_tuple(), | ||||||
|  |                         } | ||||||
|  |                 }), | ||||||
|  |                 inner_statements: None, | ||||||
|  |             }), | ||||||
|  |         ) | ||||||
|  |         .add_var( | ||||||
|  |             "childproc_read_byte".to_string(), | ||||||
|  |             Data::new(data::function::Function { | ||||||
|  |                 info: Arc::new(program::run::Info::neverused()), | ||||||
|  |                 info_check: Arc::new(Mutex::new( CheckInfo::neverused())), | ||||||
|  |                 out: Arc::new(|a, _i| { | ||||||
|  |                     if a.is_included_in(&ChildProcessT) { | ||||||
|  |                         Ok(Type::newm(vec![ | ||||||
|  |                             Arc::new(data::tuple::TupleT(vec![Type::new(data::int::IntT)])), | ||||||
|  |                             Arc::new(data::tuple::TupleT(vec![])), | ||||||
|  |                         ])) | ||||||
|  |                     } else { | ||||||
|  |                         return Err(format!("childproc_read_byte called on non-ChildProcess type {a}").into()); | ||||||
|  |                     } | ||||||
|  |                 }), | ||||||
|  |                 run: Arc::new(|a, _i| { | ||||||
|  |                     let a = a.get(); | ||||||
|  |                     let child = a.as_any().downcast_ref::<ChildProcess>().unwrap(); | ||||||
|  |                         let mut child = child.0.lock().unwrap(); | ||||||
|  |                         let mut buf = [0]; | ||||||
|  |                         if child.2.read_exact(&mut buf).is_ok() { | ||||||
|  |                             Data::one_tuple(Data::new(data::int::Int(buf[0] as _))) | ||||||
|  |                         } else { | ||||||
|  |                             Data::empty_tuple() | ||||||
|  |                         } | ||||||
|  |                 }), | ||||||
|  |                 inner_statements: None, | ||||||
|  |             }), | ||||||
|  |         ) | ||||||
|  |         .add_var( | ||||||
|  |             "childproc_readerr_byte".to_string(), | ||||||
|  |             Data::new(data::function::Function { | ||||||
|  |                 info: Arc::new(program::run::Info::neverused()), | ||||||
|  |                 info_check: Arc::new(Mutex::new( CheckInfo::neverused())), | ||||||
|  |                 out: Arc::new(|a, _i| { | ||||||
|  |                     if a.is_included_in(&ChildProcessT) { | ||||||
|  |                         Ok(Type::newm(vec![ | ||||||
|  |                             Arc::new(data::tuple::TupleT(vec![Type::new(data::int::IntT)])), | ||||||
|  |                             Arc::new(data::tuple::TupleT(vec![])), | ||||||
|  |                         ])) | ||||||
|  |                     } else { | ||||||
|  |                         return Err(format!("childproc_readerr_byte called on non-ChildProcess type {a}").into()); | ||||||
|  |                     } | ||||||
|  |                 }), | ||||||
|  |                 run: Arc::new(|a, _i| { | ||||||
|  |                     let a = a.get(); | ||||||
|  |                     let child = a.as_any().downcast_ref::<ChildProcess>().unwrap(); | ||||||
|  |                         let mut child = child.0.lock().unwrap(); | ||||||
|  |                         let mut buf = [0]; | ||||||
|  |                         if child.3.read_exact(&mut buf).is_ok() { | ||||||
|  |                             Data::one_tuple(Data::new(data::int::Int(buf[0] as _))) | ||||||
|  |                         } else { | ||||||
|  |                             Data::empty_tuple() | ||||||
|  |                         } | ||||||
|  |                 }), | ||||||
|  |                 inner_statements: None, | ||||||
|  |             }), | ||||||
|  |         ) | ||||||
|  |         .add_var( | ||||||
|  |             "childproc_read_line".to_string(), | ||||||
|  |             Data::new(data::function::Function { | ||||||
|  |                 info: Arc::new(program::run::Info::neverused()), | ||||||
|  |                 info_check: Arc::new(Mutex::new( CheckInfo::neverused())), | ||||||
|  |                 out: Arc::new(|a, _i| { | ||||||
|  |                     if a.is_included_in(&ChildProcessT) { | ||||||
|  |                         Ok(Type::newm(vec![ | ||||||
|  |                             Arc::new(data::tuple::TupleT(vec![Type::new(data::string::StringT)])), | ||||||
|  |                             Arc::new(data::tuple::TupleT(vec![])), | ||||||
|  |                         ])) | ||||||
|  |                     } else { | ||||||
|  |                         return Err(format!("childproc_read_line called on non-ChildProcess type {a}").into()); | ||||||
|  |                     } | ||||||
|  |                 }), | ||||||
|  |                 run: Arc::new(|a, _i| { | ||||||
|  |                     let a = a.get(); | ||||||
|  |                     let child = a.as_any().downcast_ref::<ChildProcess>().unwrap(); | ||||||
|  |                         let mut child = child.0.lock().unwrap(); | ||||||
|  |                         let mut buf = String::new(); | ||||||
|  |                         if child.2.read_line(&mut buf).is_ok() { | ||||||
|  |                             Data::one_tuple(Data::new(data::string::String(buf))) | ||||||
|  |                         } else { | ||||||
|  |                             Data::empty_tuple() | ||||||
|  |                         } | ||||||
|  |                 }), | ||||||
|  |                 inner_statements: None, | ||||||
|  |             }), | ||||||
|  |         ) | ||||||
|  |         .add_var( | ||||||
|  |             "childproc_readerr_line".to_string(), | ||||||
|  |             Data::new(data::function::Function { | ||||||
|  |                 info: Arc::new(program::run::Info::neverused()), | ||||||
|  |                 info_check: Arc::new(Mutex::new( CheckInfo::neverused())), | ||||||
|  |                 out: Arc::new(|a, _i| { | ||||||
|  |                     if a.is_included_in(&ChildProcessT) { | ||||||
|  |                         Ok(Type::newm(vec![ | ||||||
|  |                             Arc::new(data::tuple::TupleT(vec![Type::new(data::string::StringT)])), | ||||||
|  |                             Arc::new(data::tuple::TupleT(vec![])), | ||||||
|  |                         ])) | ||||||
|  |                     } else { | ||||||
|  |                         return Err(format!("childproc_read_line called on non-ChildProcess type {a}").into()); | ||||||
|  |                     } | ||||||
|  |                 }), | ||||||
|  |                 run: Arc::new(|a, _i| { | ||||||
|  |                     let a = a.get(); | ||||||
|  |                     let child = a.as_any().downcast_ref::<ChildProcess>().unwrap(); | ||||||
|  |                         let mut child = child.0.lock().unwrap(); | ||||||
|  |                         let mut buf = String::new(); | ||||||
|  |                         if child.3.read_line(&mut buf).is_ok() { | ||||||
|  |                             Data::one_tuple(Data::new(data::string::String(buf))) | ||||||
|  |                         } else { | ||||||
|  |                             Data::empty_tuple() | ||||||
|  |                         } | ||||||
|  |                 }), | ||||||
|  |                 inner_statements: None, | ||||||
|  |             }), | ||||||
|  |         ) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Clone, Debug)] | ||||||
|  | pub struct ChildProcess( | ||||||
|  |     Arc< | ||||||
|  |         Mutex<( | ||||||
|  |             std::process::Child, | ||||||
|  |             ChildStdin, | ||||||
|  |             BufReader<ChildStdout>, | ||||||
|  |             BufReader<ChildStderr>, | ||||||
|  |         )>, | ||||||
|  |     >, | ||||||
|  | ); | ||||||
|  | #[derive(Clone, Debug)] | ||||||
|  | pub struct ChildProcessT; | ||||||
|  | impl MersData for ChildProcess { | ||||||
|  |     fn iterable(&self) -> Option<Box<dyn Iterator<Item = Data>>> { | ||||||
|  |         None | ||||||
|  |     } | ||||||
|  |     fn get(&self, _i: usize) -> Option<Data> { | ||||||
|  |         None | ||||||
|  |     } | ||||||
|  |     fn is_eq(&self, other: &dyn MersData) -> bool { | ||||||
|  |         other | ||||||
|  |             .as_any() | ||||||
|  |             .downcast_ref::<Self>() | ||||||
|  |             .is_some_and(|other| Arc::ptr_eq(&self.0, &other.0)) | ||||||
|  |     } | ||||||
|  |     fn clone(&self) -> Box<dyn MersData> { | ||||||
|  |         Box::new(Clone::clone(self)) | ||||||
|  |     } | ||||||
|  |     fn as_type(&self) -> Type { | ||||||
|  |         Type::new(ChildProcessT) | ||||||
|  |     } | ||||||
|  |     fn as_any(&self) -> &dyn std::any::Any { | ||||||
|  |         self | ||||||
|  |     } | ||||||
|  |     fn mut_any(&mut self) -> &mut dyn std::any::Any { | ||||||
|  |         self | ||||||
|  |     } | ||||||
|  |     fn to_any(self) -> Box<dyn std::any::Any> { | ||||||
|  |         Box::new(self) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | impl Display for ChildProcess { | ||||||
|  |     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||||||
|  |         write!(f, "<ChildProcess>") | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | impl MersType for ChildProcessT { | ||||||
|  |     fn iterable(&self) -> Option<Type> { | ||||||
|  |         None | ||||||
|  |     } | ||||||
|  |     fn get(&self) -> Option<Type> { | ||||||
|  |         None | ||||||
|  |     } | ||||||
|  |     fn is_same_type_as(&self, other: &dyn MersType) -> bool { | ||||||
|  |         other.as_any().is::<Self>() | ||||||
|  |     } | ||||||
|  |     fn is_included_in_single(&self, target: &dyn MersType) -> bool { | ||||||
|  |         target.as_any().is::<Self>() | ||||||
|  |     } | ||||||
|  |     fn subtypes(&self, acc: &mut Type) { | ||||||
|  |         acc.add(Arc::new(self.clone())); | ||||||
|  |     } | ||||||
|  |     fn as_any(&self) -> &dyn std::any::Any { | ||||||
|  |         self | ||||||
|  |     } | ||||||
|  |     fn mut_any(&mut self) -> &mut dyn std::any::Any { | ||||||
|  |         self | ||||||
|  |     } | ||||||
|  |     fn to_any(self) -> Box<dyn std::any::Any> { | ||||||
|  |         Box::new(self) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | impl Display for ChildProcessT { | ||||||
|  |     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||||||
|  |         write!(f, "ChildProcess") | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -132,7 +427,7 @@ impl MersType for RunCommandErrorT { | |||||||
| } | } | ||||||
| impl Display for RunCommandError { | impl Display for RunCommandError { | ||||||
|     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||||||
|         write!(f, "RunCommandError: {}", self.0) |         write!(f, "{}", self.0) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| impl Display for RunCommandErrorT { | impl Display for RunCommandErrorT { | ||||||
|  | |||||||
| @ -19,8 +19,8 @@ impl Config { | |||||||
|     /// `gt: fn` returns true if the input keeps decreasing, that is, for (a, b), a > b, for (a, b, c), a > b > c, and so on.
 |     /// `gt: fn` returns true if the input keeps decreasing, that is, for (a, b), a > b, for (a, b, c), a > b > c, and so on.
 | ||||||
|     /// `ltoe: fn` returns true if the input only increases, that is, for (a, b), a <= b, for (a, b, c), a <= b <= c, and so on.
 |     /// `ltoe: fn` returns true if the input only increases, that is, for (a, b), a <= b, for (a, b, c), a <= b <= c, and so on.
 | ||||||
|     /// `gtoe: fn` returns true if the input only decreases, that is, for (a, b), a >= b, for (a, b, c), a >= b >= c, and so on.
 |     /// `gtoe: fn` returns true if the input only decreases, that is, for (a, b), a >= b, for (a, b, c), a >= b >= c, and so on.
 | ||||||
|     /// `parse_int: fn` parses a string to an int, returns () on failure
 |     /// `parse_int: fn` parses a string to an int, returns () on failure and (Int) otherwise
 | ||||||
|     /// `parse_float: fn` parses a string to an int, returns () on failure
 |     /// `parse_float: fn` parses a string to an int, returns () on failure and (Int) otherwise
 | ||||||
|     /// TODO!
 |     /// TODO!
 | ||||||
|     /// `as_float: fn` turns integers into floats. returns floats without changing them.
 |     /// `as_float: fn` turns integers into floats. returns floats without changing them.
 | ||||||
|     /// `round: fn` rounds the float and returns an int
 |     /// `round: fn` rounds the float and returns an int
 | ||||||
| @ -62,7 +62,9 @@ impl Config { | |||||||
|             out: Arc::new(|a, _i| { |             out: Arc::new(|a, _i| { | ||||||
|                 if a.is_included_in(&Type::new(data::string::StringT)) { |                 if a.is_included_in(&Type::new(data::string::StringT)) { | ||||||
|                     Ok(Type::newm(vec![ |                     Ok(Type::newm(vec![ | ||||||
|                         Arc::new(data::float::FloatT), |                         Arc::new(data::tuple::TupleT(vec![ | ||||||
|  |                             Type::new(data::float::FloatT), | ||||||
|  |                         ])), | ||||||
|                         Arc::new(data::tuple::TupleT(vec![])), |                         Arc::new(data::tuple::TupleT(vec![])), | ||||||
|                     ])) |                     ])) | ||||||
|                 } else { |                 } else { | ||||||
| @ -71,7 +73,7 @@ impl Config { | |||||||
|             }), |             }), | ||||||
|             run: Arc::new(|a, _i| { |             run: Arc::new(|a, _i| { | ||||||
|                 if let Ok(n) = a.get().as_any().downcast_ref::<data::string::String>().unwrap().0.parse() { |                 if let Ok(n) = a.get().as_any().downcast_ref::<data::string::String>().unwrap().0.parse() { | ||||||
|                     Data::new(data::float::Float(n)) |                     Data::one_tuple(Data::new(data::float::Float(n))) | ||||||
|                 } else { |                 } else { | ||||||
|                     Data::empty_tuple() |                     Data::empty_tuple() | ||||||
|                 } |                 } | ||||||
| @ -83,7 +85,9 @@ impl Config { | |||||||
|             out: Arc::new(|a, _i| { |             out: Arc::new(|a, _i| { | ||||||
|                 if a.is_included_in(&Type::new(data::string::StringT)) { |                 if a.is_included_in(&Type::new(data::string::StringT)) { | ||||||
|                     Ok(Type::newm(vec![ |                     Ok(Type::newm(vec![ | ||||||
|                         Arc::new(data::int::IntT), |                         Arc::new(data::tuple::TupleT(vec![ | ||||||
|  |                             Type::new(data::int::IntT), | ||||||
|  |                         ])), | ||||||
|                         Arc::new(data::tuple::TupleT(vec![])), |                         Arc::new(data::tuple::TupleT(vec![])), | ||||||
|                     ])) |                     ])) | ||||||
|                 } else { |                 } else { | ||||||
| @ -92,7 +96,7 @@ impl Config { | |||||||
|             }), |             }), | ||||||
|             run: Arc::new(|a, _i| { |             run: Arc::new(|a, _i| { | ||||||
|                 if let Ok(n) = a.get().as_any().downcast_ref::<data::string::String>().unwrap().0.parse() { |                 if let Ok(n) = a.get().as_any().downcast_ref::<data::string::String>().unwrap().0.parse() { | ||||||
|                     Data::new(data::int::Int(n)) |                     Data::one_tuple(Data::new(data::int::Int(n))) | ||||||
|                 } else { |                 } else { | ||||||
|                     Data::empty_tuple() |                     Data::empty_tuple() | ||||||
|                 } |                 } | ||||||
|  | |||||||
| @ -50,11 +50,12 @@ impl Config { | |||||||
|             Data::new(data::function::Function { |             Data::new(data::function::Function { | ||||||
|                 info: Arc::new(program::run::Info::neverused()), |                 info: Arc::new(program::run::Info::neverused()), | ||||||
|                 info_check: Arc::new(Mutex::new(CheckInfo::neverused())), |                 info_check: Arc::new(Mutex::new(CheckInfo::neverused())), | ||||||
|                 out: Arc::new(|_a, _i| Ok(Type::empty_tuple())), |                 out: Arc::new(|a, _i| Ok(a.clone())), | ||||||
|                 run: Arc::new(|a, _i| { |                 run: Arc::new(|a, _i| { | ||||||
|                     let a = a.get(); |                     let a2 = a.get(); | ||||||
|                     eprintln!("{} :: {}", a.as_type(), a); |                     eprintln!("{} :: {}", a2.as_type(), a2); | ||||||
|                     Data::empty_tuple() |                     drop(a2); | ||||||
|  |                     a | ||||||
|                 }), |                 }), | ||||||
|                 inner_statements: None, |                 inner_statements: None, | ||||||
|             }), |             }), | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Mark
						Mark