mirror of
				https://github.com/Dummi26/mers.git
				synced 2025-10-30 19:35:25 +01:00 
			
		
		
		
	added macro support, syntax is !(macro-type ...), i.e. !(mers my_file.mers) or !(mers { "value to compute at compile-time".regex("\\S+").assume_no_enum() })
This commit is contained in:
		
							parent
							
								
									0a2c67c2d5
								
							
						
					
					
						commit
						09d0d29138
					
				| @ -121,7 +121,10 @@ impl Lib { | |||||||
|                             fn_signature.next(); |                             fn_signature.next(); | ||||||
|                         } else { |                         } else { | ||||||
|                             loop { |                             loop { | ||||||
|                                 let mut t = match parse::parse_type_adv(&mut fn_signature, true) { |                                 let mut t = match parse::implementation::parse_type_adv( | ||||||
|  |                                     &mut fn_signature, | ||||||
|  |                                     true, | ||||||
|  |                                 ) { | ||||||
|                                     Ok(v) => v, |                                     Ok(v) => v, | ||||||
|                                     Err(e) => panic!("{e}"), |                                     Err(e) => panic!("{e}"), | ||||||
|                                 }; |                                 }; | ||||||
| @ -132,7 +135,8 @@ impl Lib { | |||||||
|                                 } |                                 } | ||||||
|                             } |                             } | ||||||
|                         } |                         } | ||||||
|                         let mut fn_out = match parse::parse_type(&mut fn_signature) { |                         let mut fn_out = match parse::implementation::parse_type(&mut fn_signature) | ||||||
|  |                         { | ||||||
|                             Ok(v) => v, |                             Ok(v) => v, | ||||||
|                             Err(e) => panic!("{e}"), |                             Err(e) => panic!("{e}"), | ||||||
|                         }; |                         }; | ||||||
|  | |||||||
| @ -1,16 +1,20 @@ | |||||||
| use std::path::PathBuf; | use std::path::PathBuf; | ||||||
| 
 | 
 | ||||||
| pub fn path_from_string(path: &str, script_directory: &PathBuf) -> Option<PathBuf> { | pub fn path_from_string(path: &str, script_path: &PathBuf) -> Option<PathBuf> { | ||||||
|     let path = PathBuf::from(path); |     let path = PathBuf::from(path); | ||||||
|     if path.is_absolute() { |     if path.is_absolute() { | ||||||
|         return Some(path); |         return Some(path); | ||||||
|     } |     } | ||||||
|     if let Some(p) = script_directory |     if let Some(p) = script_path | ||||||
|         .canonicalize() |         .canonicalize() | ||||||
|         .unwrap_or_else(|_| script_directory.clone()) |         .unwrap_or_else(|_| script_path.clone()) | ||||||
|         .parent() |         .parent() | ||||||
|     { |     { | ||||||
|  |         #[cfg(debug_assertions)] | ||||||
|  |         eprintln!("path: parent path: {p:?}"); | ||||||
|         let p = p.join(&path); |         let p = p.join(&path); | ||||||
|  |         #[cfg(debug_assertions)] | ||||||
|  |         eprintln!("path: joined: {p:?}"); | ||||||
|         if p.exists() { |         if p.exists() { | ||||||
|             return Some(p); |             return Some(p); | ||||||
|         } |         } | ||||||
|  | |||||||
| @ -108,12 +108,27 @@ impl File { | |||||||
|     } |     } | ||||||
|     pub fn skip_whitespaces(&mut self) { |     pub fn skip_whitespaces(&mut self) { | ||||||
|         loop { |         loop { | ||||||
|             match self.chars.get(self.pos.current_char_index) { |             match self.peek() { | ||||||
|                 Some(ch) if ch.1.is_whitespace() => _ = self.next(), |                 Some(ch) if ch.is_whitespace() => _ = self.next(), | ||||||
|                 _ => break, |                 _ => break, | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |     pub fn collect_to_whitespace(&mut self) -> String { | ||||||
|  |         let mut o = String::new(); | ||||||
|  |         loop { | ||||||
|  |             if let Some(ch) = self.next() { | ||||||
|  |                 if ch.is_whitespace() { | ||||||
|  |                     self.set_pos(*self.get_ppos()); | ||||||
|  |                     break; | ||||||
|  |                 } | ||||||
|  |                 o.push(ch); | ||||||
|  |             } else { | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         o | ||||||
|  |     } | ||||||
|     pub fn path(&self) -> &PathBuf { |     pub fn path(&self) -> &PathBuf { | ||||||
|         &self.path |         &self.path | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -3,6 +3,7 @@ use std::{process::Command, sync::Arc}; | |||||||
| use crate::{ | use crate::{ | ||||||
|     libs, |     libs, | ||||||
|     script::{ |     script::{ | ||||||
|  |         code_macro::MacroError, | ||||||
|         code_parsed::*, |         code_parsed::*, | ||||||
|         code_runnable::RScript, |         code_runnable::RScript, | ||||||
|         global_info::GSInfo, |         global_info::GSInfo, | ||||||
| @ -239,6 +240,7 @@ pub enum ParseErrors { | |||||||
|     CannotUseFixedIndexingWithThisType(VType), |     CannotUseFixedIndexingWithThisType(VType), | ||||||
|     CannotWrapWithThisStatement(SStatementEnum), |     CannotWrapWithThisStatement(SStatementEnum), | ||||||
|     ErrorParsingFunctionArgs(Box<ParseError>), |     ErrorParsingFunctionArgs(Box<ParseError>), | ||||||
|  |     MacroError(MacroError), | ||||||
| } | } | ||||||
| impl ParseErrors { | impl ParseErrors { | ||||||
|     fn fmtgs( |     fn fmtgs( | ||||||
| @ -285,14 +287,21 @@ impl ParseErrors { | |||||||
|                 write!(f, "error parsing function args: ")?; |                 write!(f, "error parsing function args: ")?; | ||||||
|                 parse_error.fmt_custom(f, file) |                 parse_error.fmt_custom(f, file) | ||||||
|             } |             } | ||||||
|  |             Self::MacroError(e) => write!(f, "error in macro: {e}"), | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | use implementation::*; | ||||||
|  | 
 | ||||||
|  | pub mod implementation { | ||||||
|  | 
 | ||||||
|  |     use super::*; | ||||||
|  | 
 | ||||||
|     fn parse_block(file: &mut File) -> Result<SBlock, ParseError> { |     fn parse_block(file: &mut File) -> Result<SBlock, ParseError> { | ||||||
|         parse_block_advanced(file, None, true, false, false) |         parse_block_advanced(file, None, true, false, false) | ||||||
|     } |     } | ||||||
| fn parse_block_advanced( |     pub(crate) fn parse_block_advanced( | ||||||
|         file: &mut File, |         file: &mut File, | ||||||
|         assume_single_statement: Option<bool>, |         assume_single_statement: Option<bool>, | ||||||
|         treat_closed_block_bracket_as_closing_delimeter: bool, |         treat_closed_block_bracket_as_closing_delimeter: bool, | ||||||
| @ -376,10 +385,75 @@ fn parse_block_advanced( | |||||||
|         Ok(SBlock::new(statements)) |         Ok(SBlock::new(statements)) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| fn parse_statement(file: &mut File) -> Result<SStatement, ParseError> { |     /// convenience function. If you require a string, use this. If the first character is a " it will parse
 | ||||||
|  |     /// until it finds a closing ". If the first character is anything else it will parse until it finds a character matching closing_char.
 | ||||||
|  |     /// Escape sequences (like \n) will only be interpreted as such if "" is used.
 | ||||||
|  |     pub(crate) fn parse_string_val<F>(file: &mut File, closing_char: F) -> String | ||||||
|  |     where | ||||||
|  |         F: Fn(char) -> bool, | ||||||
|  |     { | ||||||
|  |         match file.peek() { | ||||||
|  |             Some('"') => { | ||||||
|  |                 file.next(); | ||||||
|  |                 parse_string(file).unwrap_or(String::new()) | ||||||
|  |             } | ||||||
|  |             _ => { | ||||||
|  |                 let mut buf = String::new(); | ||||||
|  |                 loop { | ||||||
|  |                     if let Some(ch) = file.next() { | ||||||
|  |                         if closing_char(ch) { | ||||||
|  |                             file.set_pos(*file.get_ppos()); | ||||||
|  |                             break; | ||||||
|  |                         } | ||||||
|  |                         buf.push(ch); | ||||||
|  |                     } else { | ||||||
|  |                         break; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 buf | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     /// assumes the starting " has already been consumed.
 | ||||||
|  |     pub(crate) fn parse_string(file: &mut File) -> Result<String, ParseError> { | ||||||
|  |         let mut buf = String::new(); | ||||||
|  |         let err_start_of_statement = *file.get_pos(); | ||||||
|  |         loop { | ||||||
|  |             match file.next() { | ||||||
|  |                 Some('\\') => { | ||||||
|  |                     if let Some(ch) = file.next() { | ||||||
|  |                         buf.push(match ch { | ||||||
|  |                                 '\\' => '\\', | ||||||
|  |                                 'n' => '\n', | ||||||
|  |                                 't' => '\t', | ||||||
|  |                                 '"' => '"', | ||||||
|  |                                 ch => { | ||||||
|  |                                     eprintln!("Warn: Weird char escape \"\\{ch}\", will be replaced with \"{ch}\"."); | ||||||
|  |                                     ch | ||||||
|  |                                 }, | ||||||
|  |                             }) | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 Some('"') => break, | ||||||
|  |                 Some(ch) => buf.push(ch), | ||||||
|  |                 None => { | ||||||
|  |                     return Err(ParseError { | ||||||
|  |                         err: ParseErrors::FoundEofInString, | ||||||
|  |                         location: err_start_of_statement, | ||||||
|  |                         location_end: Some(*file.get_pos()), | ||||||
|  |                         context: vec![], | ||||||
|  |                         info: None, | ||||||
|  |                     }) | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         Ok(buf) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub(crate) fn parse_statement(file: &mut File) -> Result<SStatement, ParseError> { | ||||||
|         parse_statement_adv(file, false) |         parse_statement_adv(file, false) | ||||||
|     } |     } | ||||||
| fn parse_statement_adv( |     pub(crate) fn parse_statement_adv( | ||||||
|         file: &mut File, |         file: &mut File, | ||||||
|         is_part_of_chain_already: bool, |         is_part_of_chain_already: bool, | ||||||
|     ) -> Result<SStatement, ParseError> { |     ) -> Result<SStatement, ParseError> { | ||||||
| @ -415,37 +489,7 @@ fn parse_statement_adv( | |||||||
|             } |             } | ||||||
|             Some('"') => { |             Some('"') => { | ||||||
|                 file.next(); |                 file.next(); | ||||||
|             let mut buf = String::new(); |                 Some(SStatementEnum::Value(VDataEnum::String(parse_string(file)?).to()).to()) | ||||||
|             loop { |  | ||||||
|                 match file.next() { |  | ||||||
|                     Some('\\') => { |  | ||||||
|                         if let Some(ch) = file.next() { |  | ||||||
|                             buf.push(match ch { |  | ||||||
|                                 '\\' => '\\', |  | ||||||
|                                 'n' => '\n', |  | ||||||
|                                 't' => '\t', |  | ||||||
|                                 '"' => '"', |  | ||||||
|                                 ch => { |  | ||||||
|                                     eprintln!("Warn: Weird char escape \"\\{ch}\", will be replaced with \"{ch}\"."); |  | ||||||
|                                     ch |  | ||||||
|                                 }, |  | ||||||
|                             }) |  | ||||||
|                         } |  | ||||||
|                     } |  | ||||||
|                     Some('"') => break, |  | ||||||
|                     Some(ch) => buf.push(ch), |  | ||||||
|                     None => { |  | ||||||
|                         return Err(ParseError { |  | ||||||
|                             err: ParseErrors::FoundEofInString, |  | ||||||
|                             location: err_start_of_statement, |  | ||||||
|                             location_end: Some(*file.get_pos()), |  | ||||||
|                             context: vec![], |  | ||||||
|                             info: None, |  | ||||||
|                         }) |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|             Some(SStatementEnum::Value(VDataEnum::String(buf).to()).to()) |  | ||||||
|             } |             } | ||||||
|             _ => None, |             _ => None, | ||||||
|         }; |         }; | ||||||
| @ -643,7 +687,9 @@ fn parse_statement_adv( | |||||||
|                                 break SStatementEnum::Match(match_what, cases).to(); |                                 break SStatementEnum::Match(match_what, cases).to(); | ||||||
|                             } |                             } | ||||||
|                             "true" => break SStatementEnum::Value(VDataEnum::Bool(true).to()).to(), |                             "true" => break SStatementEnum::Value(VDataEnum::Bool(true).to()).to(), | ||||||
|                         "false" => break SStatementEnum::Value(VDataEnum::Bool(false).to()).to(), |                             "false" => { | ||||||
|  |                                 break SStatementEnum::Value(VDataEnum::Bool(false).to()).to() | ||||||
|  |                             } | ||||||
|                             _ => { |                             _ => { | ||||||
|                                 // int, float, var
 |                                 // int, float, var
 | ||||||
|                                 break { |                                 break { | ||||||
| @ -672,7 +718,8 @@ fn parse_statement_adv( | |||||||
|                                     //     SStatementEnum::Value(VDataEnum::Float(v).to()).to()
 |                                     //     SStatementEnum::Value(VDataEnum::Float(v).to()).to()
 | ||||||
|                                     } else { |                                     } else { | ||||||
|                                         if start.starts_with('&') { |                                         if start.starts_with('&') { | ||||||
|                                         SStatementEnum::Variable(start[1..].to_string(), true).to() |                                             SStatementEnum::Variable(start[1..].to_string(), true) | ||||||
|  |                                                 .to() | ||||||
|                                         } else { |                                         } else { | ||||||
|                                             SStatementEnum::Variable(start.to_string(), false).to() |                                             SStatementEnum::Variable(start.to_string(), false).to() | ||||||
|                                         } |                                         } | ||||||
| @ -684,21 +731,48 @@ fn parse_statement_adv( | |||||||
|                     Some('(') => { |                     Some('(') => { | ||||||
|                         // parse_block_advanced: only treat ) as closing delimeter, don't use single-statement (missing {, so would be assumed otherwise)
 |                         // parse_block_advanced: only treat ) as closing delimeter, don't use single-statement (missing {, so would be assumed otherwise)
 | ||||||
|                         let name = start.trim(); |                         let name = start.trim(); | ||||||
|                     if name.is_empty() { |                         match name { | ||||||
|  |                             "" => { | ||||||
|                                 break SStatementEnum::FunctionDefinition( |                                 break SStatementEnum::FunctionDefinition( | ||||||
|                                     None, |                                     None, | ||||||
|                                     parse_function(file, Some(err_start_of_statement))?, |                                     parse_function(file, Some(err_start_of_statement))?, | ||||||
|                                 ) |                                 ) | ||||||
|                                 .to(); |                                 .to(); | ||||||
|                     } else { |                             } | ||||||
|  |                             "!" => { | ||||||
|  |                                 break SStatementEnum::Macro( | ||||||
|  |                                     match crate::script::code_macro::parse_macro(file) { | ||||||
|  |                                         Ok(v) => v, | ||||||
|  |                                         Err(e) => { | ||||||
|  |                                             return Err(ParseError { | ||||||
|  |                                                 err: ParseErrors::MacroError(e), | ||||||
|  |                                                 location: err_start_of_statement, | ||||||
|  |                                                 location_end: Some(*file.get_pos()), | ||||||
|  |                                                 context: vec![], | ||||||
|  |                                                 info: None, | ||||||
|  |                                             }); | ||||||
|  |                                         } | ||||||
|  |                                     }, | ||||||
|  |                                 ) | ||||||
|  |                                 .to() | ||||||
|  |                             } | ||||||
|  |                             _ => { | ||||||
|                                 break SStatementEnum::FunctionCall( |                                 break SStatementEnum::FunctionCall( | ||||||
|                                     name.to_string(), |                                     name.to_string(), | ||||||
|                             match parse_block_advanced(file, Some(false), false, false, true) { |                                     match parse_block_advanced( | ||||||
|  |                                         file, | ||||||
|  |                                         Some(false), | ||||||
|  |                                         false, | ||||||
|  |                                         false, | ||||||
|  |                                         true, | ||||||
|  |                                     ) { | ||||||
|                                         Ok(block) => block.statements, |                                         Ok(block) => block.statements, | ||||||
|                                         Err(e) => { |                                         Err(e) => { | ||||||
|                                             // NOTE: Alternatively, just add an entry to the original error's context.
 |                                             // NOTE: Alternatively, just add an entry to the original error's context.
 | ||||||
|                                             return Err(ParseError { |                                             return Err(ParseError { | ||||||
|                                         err: ParseErrors::ErrorParsingFunctionArgs(Box::new(e)), |                                                 err: ParseErrors::ErrorParsingFunctionArgs( | ||||||
|  |                                                     Box::new(e), | ||||||
|  |                                                 ), | ||||||
|                                                 location: err_start_of_statement, |                                                 location: err_start_of_statement, | ||||||
|                                                 location_end: Some(*file.get_pos()), |                                                 location_end: Some(*file.get_pos()), | ||||||
|                                                 context: vec![], |                                                 context: vec![], | ||||||
| @ -710,6 +784,7 @@ fn parse_statement_adv( | |||||||
|                                 .to(); |                                 .to(); | ||||||
|                             } |                             } | ||||||
|                         } |                         } | ||||||
|  |                     } | ||||||
|                     Some(ch) => start.push(ch), |                     Some(ch) => start.push(ch), | ||||||
|                     None => { |                     None => { | ||||||
|                         return Err(ParseError { |                         return Err(ParseError { | ||||||
| @ -734,7 +809,8 @@ fn parse_statement_adv( | |||||||
|             if !is_part_of_chain_already { |             if !is_part_of_chain_already { | ||||||
|                 let mut chain_length = 0; |                 let mut chain_length = 0; | ||||||
|                 let mut err_end_of_prev = err_end_of_original_statement; |                 let mut err_end_of_prev = err_end_of_original_statement; | ||||||
|             while let Some('.') = file.get_char(file.get_pos().current_char_index.saturating_sub(1)) |                 while let Some('.') = | ||||||
|  |                     file.get_char(file.get_pos().current_char_index.saturating_sub(1)) | ||||||
|                 { |                 { | ||||||
|                     let err_start_of_wrapper = *file.get_pos(); |                     let err_start_of_wrapper = *file.get_pos(); | ||||||
|                     let wrapper = parse_statement_adv(file, true)?; |                     let wrapper = parse_statement_adv(file, true)?; | ||||||
| @ -815,7 +891,7 @@ fn parse_statement_adv( | |||||||
|     /// Assumes the function name and opening bracket have already been parsed. File should continue like "name type name type ...) <statement>"
 |     /// Assumes the function name and opening bracket have already been parsed. File should continue like "name type name type ...) <statement>"
 | ||||||
|     fn parse_function( |     fn parse_function( | ||||||
|         file: &mut File, |         file: &mut File, | ||||||
|     err_fn_start: Option<super::file::FilePosition>, |         err_fn_start: Option<crate::parse::file::FilePosition>, | ||||||
|     ) -> Result<SFunction, ParseError> { |     ) -> Result<SFunction, ParseError> { | ||||||
|         file.skip_whitespaces(); |         file.skip_whitespaces(); | ||||||
|         // find the arguments to the function
 |         // find the arguments to the function
 | ||||||
| @ -1098,3 +1174,4 @@ fn parse_single_type_adv( | |||||||
|             closed_bracket_in_fn_args, |             closed_bracket_in_fn_args, | ||||||
|         )) |         )) | ||||||
|     } |     } | ||||||
|  | } | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| use std::fmt::{self, Display, Formatter, Pointer}; | use std::fmt::{self, Display, Formatter, Pointer}; | ||||||
| 
 | 
 | ||||||
| use super::{global_info::GSInfo, val_data::VData, val_type::VType}; | use super::{code_macro::Macro, global_info::GSInfo, val_data::VData, val_type::VType}; | ||||||
| 
 | 
 | ||||||
| pub enum SStatementEnum { | pub enum SStatementEnum { | ||||||
|     Value(VData), |     Value(VData), | ||||||
| @ -17,6 +17,7 @@ pub enum SStatementEnum { | |||||||
|     Match(String, Vec<(SStatement, SStatement)>), |     Match(String, Vec<(SStatement, SStatement)>), | ||||||
|     IndexFixed(SStatement, usize), |     IndexFixed(SStatement, usize), | ||||||
|     EnumVariant(String, SStatement), |     EnumVariant(String, SStatement), | ||||||
|  |     Macro(Macro), | ||||||
| } | } | ||||||
| impl SStatementEnum { | impl SStatementEnum { | ||||||
|     pub fn to(self) -> SStatement { |     pub fn to(self) -> SStatement { | ||||||
| @ -172,6 +173,9 @@ impl SStatementEnum { | |||||||
|                 write!(f, "{variant}: ")?; |                 write!(f, "{variant}: ")?; | ||||||
|                 inner.fmtgs(f, info) |                 inner.fmtgs(f, info) | ||||||
|             } |             } | ||||||
|  |             Self::Macro(m) => { | ||||||
|  |                 write!(f, "!({m})") | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,4 +1,5 @@ | |||||||
| pub mod builtins; | pub mod builtins; | ||||||
|  | pub mod code_macro; | ||||||
| pub mod code_parsed; | pub mod code_parsed; | ||||||
| pub mod code_runnable; | pub mod code_runnable; | ||||||
| pub mod global_info; | pub mod global_info; | ||||||
|  | |||||||
| @ -16,6 +16,7 @@ use crate::{ | |||||||
| 
 | 
 | ||||||
| use super::{ | use super::{ | ||||||
|     builtins::BuiltinFunction, |     builtins::BuiltinFunction, | ||||||
|  |     code_macro::Macro, | ||||||
|     code_parsed::{SBlock, SFunction, SStatement, SStatementEnum}, |     code_parsed::{SBlock, SFunction, SStatement, SStatementEnum}, | ||||||
|     code_runnable::{RBlock, RFunction, RScript, RStatement, RStatementEnum}, |     code_runnable::{RBlock, RFunction, RScript, RStatement, RStatementEnum}, | ||||||
| }; | }; | ||||||
| @ -565,6 +566,9 @@ fn statement( | |||||||
|                     v |                     v | ||||||
|                 } |                 } | ||||||
|             }, statement(s, ginfo, linfo)?), |             }, statement(s, ginfo, linfo)?), | ||||||
|  |             SStatementEnum::Macro(m) => match m { | ||||||
|  |                 Macro::StaticMers(val) => RStatementEnum::Value(val.clone()), | ||||||
|  |             }, | ||||||
|         } |         } | ||||||
|         .to(); |         .to(); | ||||||
|     // if force_output_type is set, verify that the real output type actually fits in the forced one.
 |     // if force_output_type is set, verify that the real output type actually fits in the forced one.
 | ||||||
|  | |||||||
| @ -47,6 +47,9 @@ impl PartialEq for VDataEnum { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl VData { | impl VData { | ||||||
|  |     pub fn safe_to_share(&self) -> bool { | ||||||
|  |         self.data.safe_to_share() | ||||||
|  |     } | ||||||
|     pub fn out(&self) -> VType { |     pub fn out(&self) -> VType { | ||||||
|         VType { |         VType { | ||||||
|             types: vec![self.out_single()], |             types: vec![self.out_single()], | ||||||
| @ -82,6 +85,15 @@ impl VDataEnum { | |||||||
| 
 | 
 | ||||||
| // get()
 | // get()
 | ||||||
| impl VDataEnum { | impl VDataEnum { | ||||||
|  |     pub fn safe_to_share(&self) -> bool { | ||||||
|  |         match self { | ||||||
|  |             Self::Bool(_) | Self::Int(_) | Self::Float(_) | Self::String(_) | Self::Function(_) => { | ||||||
|  |                 true | ||||||
|  |             } | ||||||
|  |             Self::Tuple(v) | Self::List(_, v) => v.iter().all(|v| v.safe_to_share()), | ||||||
|  |             Self::Thread(..) | Self::Reference(..) | Self::EnumVariant(..) => false, | ||||||
|  |         } | ||||||
|  |     } | ||||||
|     pub fn noenum(self) -> VData { |     pub fn noenum(self) -> VData { | ||||||
|         match self { |         match self { | ||||||
|             Self::EnumVariant(_, v) => *v, |             Self::EnumVariant(_, v) => *v, | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Dummi26
						Dummi26