mirror of
				https://github.com/Dummi26/mers.git
				synced 2025-10-31 19:56:15 +01:00 
			
		
		
		
	add #include
This commit is contained in:
		
							parent
							
								
									e851559016
								
							
						
					
					
						commit
						39951a59e9
					
				| @ -1,6 +1,6 @@ | |||||||
| use clap::{Parser, Subcommand, ValueEnum}; | use clap::{Parser, Subcommand, ValueEnum}; | ||||||
| use mers_lib::prelude_compile::*; | use mers_lib::prelude_compile::*; | ||||||
| use std::{fmt::Display, fs, path::PathBuf}; | use std::{fmt::Display, fs, path::PathBuf, process::exit}; | ||||||
| 
 | 
 | ||||||
| mod cfg_globals; | mod cfg_globals; | ||||||
| 
 | 
 | ||||||
| @ -67,17 +67,33 @@ fn main() { | |||||||
|     let (mut info_parsed, mut info_run, mut info_check) = config.infos(); |     let (mut info_parsed, mut info_run, mut info_check) = config.infos(); | ||||||
|     let mut source = match args.command { |     let mut source = match args.command { | ||||||
|         Command::Run { file } => { |         Command::Run { file } => { | ||||||
|             let str = fs::read_to_string(file).unwrap(); |             let str = match fs::read_to_string(&file) { | ||||||
|  |                 Ok(s) => s, | ||||||
|  |                 Err(e) => { | ||||||
|  |                     eprintln!("Can't read file {file:?}: {e}"); | ||||||
|  |                     exit(10); | ||||||
|  |                 } | ||||||
|  |             }; | ||||||
|             Source::new(str) |             Source::new(str) | ||||||
|         } |         } | ||||||
|         Command::Exec { source } => Source::new(source), |         Command::Exec { source } => Source::new(source), | ||||||
|     }; |     }; | ||||||
|     let parsed = parse(&mut source).unwrap(); |     let parsed = match parse(&mut source) { | ||||||
|  |         Ok(v) => v, | ||||||
|  |         Err(e) => { | ||||||
|  |             eprintln!("{}", e.display(&source)); | ||||||
|  |             exit(20); | ||||||
|  |         } | ||||||
|  |     }; | ||||||
|     #[cfg(debug_assertions)] |     #[cfg(debug_assertions)] | ||||||
|     dbg!(&parsed); |     dbg!(&parsed); | ||||||
|     let run = parsed |     let run = match parsed.compile(&mut info_parsed, Default::default()) { | ||||||
|         .compile(&mut info_parsed, Default::default()) |         Ok(v) => v, | ||||||
|         .unwrap(); |         Err(e) => { | ||||||
|  |             eprintln!("{}", e.display(&source)); | ||||||
|  |             exit(24); | ||||||
|  |         } | ||||||
|  |     }; | ||||||
|     #[cfg(debug_assertions)] |     #[cfg(debug_assertions)] | ||||||
|     dbg!(&run); |     dbg!(&run); | ||||||
|     match args.check { |     match args.check { | ||||||
| @ -89,7 +105,7 @@ fn main() { | |||||||
|                 Ok(v) => v, |                 Ok(v) => v, | ||||||
|                 Err(e) => { |                 Err(e) => { | ||||||
|                     eprint!("{}", e.display(&source)); |                     eprint!("{}", e.display(&source)); | ||||||
|                     std::process::exit(36); |                     exit(28); | ||||||
|                 } |                 } | ||||||
|             }; |             }; | ||||||
|             if args.check == Check::Yes { |             if args.check == Check::Yes { | ||||||
|  | |||||||
| @ -23,6 +23,7 @@ pub trait Local: Default + Debug { | |||||||
|     fn get_var_mut(&mut self, id: &Self::VariableIdentifier) -> Option<&mut Self::VariableData>; |     fn get_var_mut(&mut self, id: &Self::VariableIdentifier) -> Option<&mut Self::VariableData>; | ||||||
|     // fn add_type(&mut self, id: Self::TypesIdentifier, new_type: Self::TypesType);
 |     // fn add_type(&mut self, id: Self::TypesIdentifier, new_type: Self::TypesType);
 | ||||||
|     // fn get_type(&self, id: Self::TypesIdentifier) -> Option<&Self::TypesType>;
 |     // fn get_type(&self, id: Self::TypesIdentifier) -> Option<&Self::TypesType>;
 | ||||||
|  |     fn duplicate(&self) -> Self; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl<L: Local> Info<L> { | impl<L: Local> Info<L> { | ||||||
| @ -47,6 +48,11 @@ impl<L: Local> Local for Info<L> { | |||||||
|     fn get_var_mut(&mut self, id: &Self::VariableIdentifier) -> Option<&mut Self::VariableData> { |     fn get_var_mut(&mut self, id: &Self::VariableIdentifier) -> Option<&mut Self::VariableData> { | ||||||
|         self.scopes.iter_mut().find_map(|l| l.get_var_mut(id)) |         self.scopes.iter_mut().find_map(|l| l.get_var_mut(id)) | ||||||
|     } |     } | ||||||
|  |     fn duplicate(&self) -> Self { | ||||||
|  |         Self { | ||||||
|  |             scopes: self.scopes.iter().map(|v| v.duplicate()).collect(), | ||||||
|  |         } | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl<L: Local> Default for Info<L> { | impl<L: Local> Default for Info<L> { | ||||||
|  | |||||||
| @ -1,12 +1,12 @@ | |||||||
| use std::sync::Arc; | use std::sync::Arc; | ||||||
| 
 | 
 | ||||||
| use crate::program::{self, parsed::block::Block}; | use crate::program::{self, parsed::block::Block, run::CheckError}; | ||||||
| 
 | 
 | ||||||
| pub mod errors; | pub mod errors; | ||||||
| pub mod statements; | pub mod statements; | ||||||
| pub mod types; | pub mod types; | ||||||
| 
 | 
 | ||||||
| pub fn parse(src: &mut Source) -> Result<Box<dyn program::parsed::MersStatement>, ()> { | pub fn parse(src: &mut Source) -> Result<Box<dyn program::parsed::MersStatement>, CheckError> { | ||||||
|     let pos_in_src = src.get_pos(); |     let pos_in_src = src.get_pos(); | ||||||
|     let statements = statements::parse_multiple(src, "")?; |     let statements = statements::parse_multiple(src, "")?; | ||||||
|     let block = Block { |     let block = Block { | ||||||
|  | |||||||
| @ -1,10 +1,16 @@ | |||||||
| use super::Source; | use std::fs; | ||||||
|  | 
 | ||||||
|  | use colored::{Color, Colorize}; | ||||||
|  | 
 | ||||||
|  | use super::{Source, SourcePos}; | ||||||
| use crate::{ | use crate::{ | ||||||
|     data::Data, |     data::Data, | ||||||
|     program::{self, parsed::MersStatement}, |     program::{self, parsed::MersStatement, run::CheckError}, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| pub fn parse(src: &mut Source) -> Result<Option<Box<dyn program::parsed::MersStatement>>, ()> { | pub fn parse( | ||||||
|  |     src: &mut Source, | ||||||
|  | ) -> Result<Option<Box<dyn program::parsed::MersStatement>>, CheckError> { | ||||||
|     src.section_begin("statement".to_string()); |     src.section_begin("statement".to_string()); | ||||||
|     let mut first = if let Some(s) = parse_no_chain(src)? { |     let mut first = if let Some(s) = parse_no_chain(src)? { | ||||||
|         s |         s | ||||||
| @ -16,7 +22,14 @@ pub fn parse(src: &mut Source) -> Result<Option<Box<dyn program::parsed::MersSta | |||||||
|         ":=" => { |         ":=" => { | ||||||
|             let pos_in_src = src.get_pos(); |             let pos_in_src = src.get_pos(); | ||||||
|             src.next_word(); |             src.next_word(); | ||||||
|             let source = parse(src)?.expect("todo"); |             let source = parse(src)?.ok_or_else(|| { | ||||||
|  |                 CheckError::new() | ||||||
|  |                     .src(vec![( | ||||||
|  |                         (pos_in_src, src.get_pos()).into(), | ||||||
|  |                         Some(Color::BrightBlack), | ||||||
|  |                     )]) | ||||||
|  |                     .msg(format!("EOF after :=")) | ||||||
|  |             })?; | ||||||
|             first = Box::new(program::parsed::init_to::InitTo { |             first = Box::new(program::parsed::init_to::InitTo { | ||||||
|                 pos_in_src: (pos_in_src, src.get_pos()).into(), |                 pos_in_src: (pos_in_src, src.get_pos()).into(), | ||||||
|                 target: first, |                 target: first, | ||||||
| @ -26,7 +39,14 @@ pub fn parse(src: &mut Source) -> Result<Option<Box<dyn program::parsed::MersSta | |||||||
|         "=" => { |         "=" => { | ||||||
|             let pos_in_src = src.get_pos(); |             let pos_in_src = src.get_pos(); | ||||||
|             src.next_word(); |             src.next_word(); | ||||||
|             let source = parse(src)?.expect("todo"); |             let source = parse(src)?.ok_or_else(|| { | ||||||
|  |                 CheckError::new() | ||||||
|  |                     .src(vec![( | ||||||
|  |                         (pos_in_src, src.get_pos()).into(), | ||||||
|  |                         Some(Color::BrightBlack), | ||||||
|  |                     )]) | ||||||
|  |                     .msg(format!("EOF after =")) | ||||||
|  |             })?; | ||||||
|             first = Box::new(program::parsed::assign_to::AssignTo { |             first = Box::new(program::parsed::assign_to::AssignTo { | ||||||
|                 pos_in_src: (pos_in_src, src.get_pos()).into(), |                 pos_in_src: (pos_in_src, src.get_pos()).into(), | ||||||
|                 target: first, |                 target: first, | ||||||
| @ -73,7 +93,10 @@ pub fn parse(src: &mut Source) -> Result<Option<Box<dyn program::parsed::MersSta | |||||||
|     } |     } | ||||||
|     Ok(Some(first)) |     Ok(Some(first)) | ||||||
| } | } | ||||||
| pub fn parse_multiple(src: &mut Source, end: &str) -> Result<Vec<Box<dyn MersStatement>>, ()> { | pub fn parse_multiple( | ||||||
|  |     src: &mut Source, | ||||||
|  |     end: &str, | ||||||
|  | ) -> Result<Vec<Box<dyn MersStatement>>, CheckError> { | ||||||
|     src.section_begin("block".to_string()); |     src.section_begin("block".to_string()); | ||||||
|     let mut statements = vec![]; |     let mut statements = vec![]; | ||||||
|     loop { |     loop { | ||||||
| @ -92,10 +115,68 @@ pub fn parse_multiple(src: &mut Source, end: &str) -> Result<Vec<Box<dyn MersSta | |||||||
| } | } | ||||||
| pub fn parse_no_chain( | pub fn parse_no_chain( | ||||||
|     src: &mut Source, |     src: &mut Source, | ||||||
| ) -> Result<Option<Box<dyn program::parsed::MersStatement>>, ()> { | ) -> Result<Option<Box<dyn program::parsed::MersStatement>>, CheckError> { | ||||||
|     src.section_begin("statement no chain".to_string()); |     src.section_begin("statement no chain".to_string()); | ||||||
|     src.skip_whitespace(); |     src.skip_whitespace(); | ||||||
|     match src.peek_char() { |     match src.peek_char() { | ||||||
|  |         Some('#') => { | ||||||
|  |             let pos_in_src = src.get_pos(); | ||||||
|  |             src.next_char(); | ||||||
|  |             if src.peek_char().is_none() { | ||||||
|  |                 return Err(CheckError::new() | ||||||
|  |                     .src(vec![((pos_in_src, src.get_pos()).into(), Some(Color::Red))]) | ||||||
|  |                     .msg(format!("EOF after #"))); | ||||||
|  |             } | ||||||
|  |             if src.peek_char().is_some_and(|ch| ch.is_whitespace()) { | ||||||
|  |                 src.skip_whitespace(); | ||||||
|  |                 return Err(CheckError::new() | ||||||
|  |                     .src(vec![((pos_in_src, src.get_pos()).into(), Some(Color::Red))]) | ||||||
|  |                     .msg(format!("Whitespace after #"))); | ||||||
|  |             } | ||||||
|  |             match src.next_word() { | ||||||
|  |                 "include" => { | ||||||
|  |                     let end_in_src = src.get_pos(); | ||||||
|  |                     src.skip_whitespace(); | ||||||
|  |                     let string_in_src = src.get_pos(); | ||||||
|  |                     if src.next_char() == Some('"') { | ||||||
|  |                         let s = parse_string(src, string_in_src)?; | ||||||
|  |                         match fs::read_to_string(&s) { | ||||||
|  |                             Ok(s) => { | ||||||
|  |                                 return Ok(Some(Box::new( | ||||||
|  |                                     program::parsed::include_mers::IncludeMers { | ||||||
|  |                                         pos_in_src: (pos_in_src, src.get_pos()).into(), | ||||||
|  |                                         include: super::parse(&mut Source::new(s))?, | ||||||
|  |                                     }, | ||||||
|  |                                 ))); | ||||||
|  |                             } | ||||||
|  |                             Err(e) => { | ||||||
|  |                                 return Err(CheckError::new() | ||||||
|  |                                     .src(vec![ | ||||||
|  |                                         ((pos_in_src, end_in_src).into(), None), | ||||||
|  |                                         ((string_in_src, src.get_pos()).into(), Some(Color::Red)), | ||||||
|  |                                     ]) | ||||||
|  |                                     .msg(format!("Can't load file '{s}': {e}"))); | ||||||
|  |                             } | ||||||
|  |                         } | ||||||
|  |                     } else { | ||||||
|  |                         return Err(CheckError::new() | ||||||
|  |                             .src(vec![ | ||||||
|  |                                 ((pos_in_src, end_in_src).into(), Some(Color::BrightBlack)), | ||||||
|  |                                 ((string_in_src, src.get_pos()).into(), Some(Color::Red)), | ||||||
|  |                             ]) | ||||||
|  |                             .msg(format!( | ||||||
|  |                                 "#include must be followed by a string literal like \"file.mers\" (\" expected)." | ||||||
|  |                             ))); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 other => { | ||||||
|  |                     let msg = format!("Unknown #statement: {other}"); | ||||||
|  |                     return Err(CheckError::new() | ||||||
|  |                         .src(vec![((pos_in_src, src.get_pos()).into(), Some(Color::Red))]) | ||||||
|  |                         .msg(msg)); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|         Some('{') => { |         Some('{') => { | ||||||
|             let pos_in_src = src.get_pos(); |             let pos_in_src = src.get_pos(); | ||||||
|             src.next_char(); |             src.next_char(); | ||||||
| @ -118,28 +199,7 @@ pub fn parse_no_chain( | |||||||
|             src.section_begin("string literal".to_string()); |             src.section_begin("string literal".to_string()); | ||||||
|             let pos_in_src = src.get_pos(); |             let pos_in_src = src.get_pos(); | ||||||
|             src.next_char(); |             src.next_char(); | ||||||
|             let mut s = String::new(); |             let s = parse_string(src, pos_in_src)?; | ||||||
|             loop { |  | ||||||
|                 if let Some(ch) = src.next_char() { |  | ||||||
|                     if ch == '\\' { |  | ||||||
|                         s.push(match src.next_char() { |  | ||||||
|                             Some('\\') => '\\', |  | ||||||
|                             Some('r') => '\r', |  | ||||||
|                             Some('n') => '\n', |  | ||||||
|                             Some('t') => '\t', |  | ||||||
|                             Some('"') => '"', |  | ||||||
|                             Some(o) => todo!("err: unknown backslash escape '\\{o}'"), |  | ||||||
|                             None => todo!("err: eof in backslash escape"), |  | ||||||
|                         }); |  | ||||||
|                     } else if ch == '"' { |  | ||||||
|                         break; |  | ||||||
|                     } else { |  | ||||||
|                         s.push(ch); |  | ||||||
|                     } |  | ||||||
|                 } else { |  | ||||||
|                     todo!("err: eof in string") |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|             return Ok(Some(Box::new(program::parsed::value::Value { |             return Ok(Some(Box::new(program::parsed::value::Value { | ||||||
|                 pos_in_src: (pos_in_src, src.get_pos()).into(), |                 pos_in_src: (pos_in_src, src.get_pos()).into(), | ||||||
|                 data: Data::new(crate::data::string::String(s)), |                 data: Data::new(crate::data::string::String(s)), | ||||||
| @ -222,3 +282,50 @@ pub fn parse_no_chain( | |||||||
|         } |         } | ||||||
|     })) |     })) | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | /// expects to be called *after* a " character is consumed from src
 | ||||||
|  | pub fn parse_string(src: &mut Source, double_quote: SourcePos) -> Result<String, CheckError> { | ||||||
|  |     let mut s = String::new(); | ||||||
|  |     loop { | ||||||
|  |         if let Some(ch) = src.next_char() { | ||||||
|  |             if ch == '\\' { | ||||||
|  |                 let backslash_in_src = src.get_pos(); | ||||||
|  |                 s.push(match src.next_char() { | ||||||
|  |                     Some('\\') => '\\', | ||||||
|  |                     Some('r') => '\r', | ||||||
|  |                     Some('n') => '\n', | ||||||
|  |                     Some('t') => '\t', | ||||||
|  |                     Some('"') => '"', | ||||||
|  |                     Some(o) => { | ||||||
|  |                         return Err(CheckError::new() | ||||||
|  |                             .src(vec![( | ||||||
|  |                                 (backslash_in_src, src.get_pos()).into(), | ||||||
|  |                                 Some(Color::Red), | ||||||
|  |                             )]) | ||||||
|  |                             .msg(format!("unknown backslash escape '\\{o}'"))); | ||||||
|  |                     } | ||||||
|  |                     None => { | ||||||
|  |                         return Err(CheckError::new() | ||||||
|  |                             .src(vec![( | ||||||
|  |                                 (backslash_in_src, src.get_pos()).into(), | ||||||
|  |                                 Some(Color::Red), | ||||||
|  |                             )]) | ||||||
|  |                             .msg(format!("EOF in backslash escape"))); | ||||||
|  |                     } | ||||||
|  |                 }); | ||||||
|  |             } else if ch == '"' { | ||||||
|  |                 break; | ||||||
|  |             } else { | ||||||
|  |                 s.push(ch); | ||||||
|  |             } | ||||||
|  |         } else { | ||||||
|  |             return Err(CheckError::new() | ||||||
|  |                 .src(vec![( | ||||||
|  |                     (double_quote, src.get_pos()).into(), | ||||||
|  |                     Some(Color::BrightBlack), | ||||||
|  |                 )]) | ||||||
|  |                 .msg(format!("EOF in string literal"))); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     Ok(s) | ||||||
|  | } | ||||||
|  | |||||||
| @ -1,4 +1,7 @@ | |||||||
| use crate::program::{self, run::SourceRange}; | use crate::program::{ | ||||||
|  |     self, | ||||||
|  |     run::{CheckError, SourceRange}, | ||||||
|  | }; | ||||||
| 
 | 
 | ||||||
| use super::{CompInfo, MersStatement}; | use super::{CompInfo, MersStatement}; | ||||||
| 
 | 
 | ||||||
| @ -17,7 +20,7 @@ impl MersStatement for AssignTo { | |||||||
|         &self, |         &self, | ||||||
|         info: &mut crate::info::Info<super::Local>, |         info: &mut crate::info::Info<super::Local>, | ||||||
|         comp: CompInfo, |         comp: CompInfo, | ||||||
|     ) -> Result<Box<dyn program::run::MersStatement>, String> { |     ) -> Result<Box<dyn program::run::MersStatement>, CheckError> { | ||||||
|         Ok(Box::new(program::run::assign_to::AssignTo { |         Ok(Box::new(program::run::assign_to::AssignTo { | ||||||
|             pos_in_src: self.pos_in_src, |             pos_in_src: self.pos_in_src, | ||||||
|             is_init: false, |             is_init: false, | ||||||
|  | |||||||
| @ -1,6 +1,9 @@ | |||||||
| use crate::{ | use crate::{ | ||||||
|     info, |     info, | ||||||
|     program::{self, run::SourceRange}, |     program::{ | ||||||
|  |         self, | ||||||
|  |         run::{CheckError, SourceRange}, | ||||||
|  |     }, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| use super::{CompInfo, MersStatement}; | use super::{CompInfo, MersStatement}; | ||||||
| @ -18,7 +21,7 @@ impl MersStatement for Block { | |||||||
|         &self, |         &self, | ||||||
|         info: &mut info::Info<super::Local>, |         info: &mut info::Info<super::Local>, | ||||||
|         comp: CompInfo, |         comp: CompInfo, | ||||||
|     ) -> Result<Box<dyn program::run::MersStatement>, String> { |     ) -> Result<Box<dyn program::run::MersStatement>, CheckError> { | ||||||
|         Ok(Box::new(program::run::block::Block { |         Ok(Box::new(program::run::block::Block { | ||||||
|             pos_in_src: self.pos_in_src, |             pos_in_src: self.pos_in_src, | ||||||
|             statements: self |             statements: self | ||||||
|  | |||||||
| @ -1,4 +1,4 @@ | |||||||
| use crate::program::run::SourceRange; | use crate::program::run::{CheckError, SourceRange}; | ||||||
| use crate::{info, program}; | use crate::{info, program}; | ||||||
| 
 | 
 | ||||||
| use super::{CompInfo, MersStatement}; | use super::{CompInfo, MersStatement}; | ||||||
| @ -17,7 +17,7 @@ impl MersStatement for Chain { | |||||||
|         &self, |         &self, | ||||||
|         info: &mut info::Info<super::Local>, |         info: &mut info::Info<super::Local>, | ||||||
|         comp: CompInfo, |         comp: CompInfo, | ||||||
|     ) -> Result<Box<dyn program::run::MersStatement>, String> { |     ) -> Result<Box<dyn program::run::MersStatement>, CheckError> { | ||||||
|         Ok(Box::new(program::run::chain::Chain { |         Ok(Box::new(program::run::chain::Chain { | ||||||
|             pos_in_src: self.pos_in_src, |             pos_in_src: self.pos_in_src, | ||||||
|             first: self.first.compile(info, comp)?, |             first: self.first.compile(info, comp)?, | ||||||
|  | |||||||
| @ -1,4 +1,4 @@ | |||||||
| use crate::program::run::SourceRange; | use crate::program::run::{CheckError, SourceRange}; | ||||||
| use std::sync::{Arc, Mutex}; | use std::sync::{Arc, Mutex}; | ||||||
| 
 | 
 | ||||||
| use crate::{ | use crate::{ | ||||||
| @ -24,7 +24,7 @@ impl MersStatement for Function { | |||||||
|         &self, |         &self, | ||||||
|         info: &mut crate::info::Info<super::Local>, |         info: &mut crate::info::Info<super::Local>, | ||||||
|         mut comp: CompInfo, |         mut comp: CompInfo, | ||||||
|     ) -> Result<Box<dyn program::run::MersStatement>, String> { |     ) -> Result<Box<dyn program::run::MersStatement>, CheckError> { | ||||||
|         comp.is_init = true; |         comp.is_init = true; | ||||||
|         let arg_target = Arc::new(self.arg.compile(info, comp)?); |         let arg_target = Arc::new(self.arg.compile(info, comp)?); | ||||||
|         comp.is_init = false; |         comp.is_init = false; | ||||||
|  | |||||||
| @ -1,4 +1,7 @@ | |||||||
| use crate::program::{self, run::SourceRange}; | use crate::program::{ | ||||||
|  |     self, | ||||||
|  |     run::{CheckError, SourceRange}, | ||||||
|  | }; | ||||||
| 
 | 
 | ||||||
| use super::{CompInfo, MersStatement}; | use super::{CompInfo, MersStatement}; | ||||||
| 
 | 
 | ||||||
| @ -18,7 +21,7 @@ impl MersStatement for If { | |||||||
|         &self, |         &self, | ||||||
|         info: &mut crate::info::Info<super::Local>, |         info: &mut crate::info::Info<super::Local>, | ||||||
|         comp: CompInfo, |         comp: CompInfo, | ||||||
|     ) -> Result<Box<dyn program::run::MersStatement>, String> { |     ) -> Result<Box<dyn program::run::MersStatement>, CheckError> { | ||||||
|         Ok(Box::new(program::run::r#if::If { |         Ok(Box::new(program::run::r#if::If { | ||||||
|             pos_in_src: self.pos_in_src, |             pos_in_src: self.pos_in_src, | ||||||
|             condition: self.condition.compile(info, comp)?, |             condition: self.condition.compile(info, comp)?, | ||||||
|  | |||||||
							
								
								
									
										60
									
								
								mers_lib/src/program/parsed/include_mers.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								mers_lib/src/program/parsed/include_mers.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,60 @@ | |||||||
|  | use std::sync::{Arc, Mutex}; | ||||||
|  | 
 | ||||||
|  | use colored::Colorize; | ||||||
|  | 
 | ||||||
|  | use crate::{ | ||||||
|  |     data::{self, Data}, | ||||||
|  |     info::{self, Local}, | ||||||
|  |     program::{ | ||||||
|  |         self, | ||||||
|  |         run::{CheckError, SourceRange}, | ||||||
|  |     }, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | use super::{CompInfo, MersStatement}; | ||||||
|  | 
 | ||||||
|  | #[derive(Debug)] | ||||||
|  | pub struct IncludeMers { | ||||||
|  |     pub pos_in_src: SourceRange, | ||||||
|  |     pub include: Box<dyn MersStatement>, | ||||||
|  | } | ||||||
|  | impl MersStatement for IncludeMers { | ||||||
|  |     fn has_scope(&self) -> bool { | ||||||
|  |         true | ||||||
|  |     } | ||||||
|  |     fn compile_custom( | ||||||
|  |         &self, | ||||||
|  |         info: &mut info::Info<super::Local>, | ||||||
|  |         comp: CompInfo, | ||||||
|  |     ) -> Result<Box<dyn program::run::MersStatement>, CheckError> { | ||||||
|  |         let compiled = match self.include.compile(info, comp) { | ||||||
|  |             Ok(v) => Arc::new(v), | ||||||
|  |             Err(e) => { | ||||||
|  |                 return Err(CheckError::new() | ||||||
|  |                     .src(vec![(self.pos_in_src, Some(colored::Color::Red))]) | ||||||
|  |                     .msg("Error in inner mers statement! (note: inner errors may refer to a different file)".red().to_string()) | ||||||
|  |                 .err(e)) | ||||||
|  |             } | ||||||
|  |         }; | ||||||
|  |         let compiled2 = Arc::clone(&compiled); | ||||||
|  |         Ok(Box::new(program::run::chain::Chain { | ||||||
|  |             pos_in_src: self.pos_in_src, | ||||||
|  |             first: Box::new(program::run::value::Value { | ||||||
|  |                 pos_in_src: self.pos_in_src, | ||||||
|  |                 val: Data::empty_tuple(), | ||||||
|  |             }), | ||||||
|  |             chained: Box::new(program::run::function::Function { | ||||||
|  |                 pos_in_src: self.pos_in_src, | ||||||
|  |                 func_no_info: data::function::Function { | ||||||
|  |                     info: Arc::new(info::Info::neverused()), | ||||||
|  |                     info_check: Arc::new(Mutex::new(info::Info::neverused())), | ||||||
|  |                     out: Arc::new(move |_, i| compiled.check(&mut i.duplicate(), None)), | ||||||
|  |                     run: Arc::new(move |_, i| compiled2.run(&mut i.duplicate())), | ||||||
|  |                 }, | ||||||
|  |             }), | ||||||
|  |         })) | ||||||
|  |     } | ||||||
|  |     fn source_range(&self) -> SourceRange { | ||||||
|  |         self.pos_in_src | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -1,5 +1,5 @@ | |||||||
| use crate::program; |  | ||||||
| use crate::program::run::SourceRange; | use crate::program::run::SourceRange; | ||||||
|  | use crate::program::{self, run::CheckError}; | ||||||
| 
 | 
 | ||||||
| use super::{CompInfo, MersStatement}; | use super::{CompInfo, MersStatement}; | ||||||
| 
 | 
 | ||||||
| @ -18,7 +18,7 @@ impl MersStatement for InitTo { | |||||||
|         &self, |         &self, | ||||||
|         info: &mut crate::info::Info<super::Local>, |         info: &mut crate::info::Info<super::Local>, | ||||||
|         mut comp: CompInfo, |         mut comp: CompInfo, | ||||||
|     ) -> Result<Box<dyn crate::program::run::MersStatement>, String> { |     ) -> Result<Box<dyn crate::program::run::MersStatement>, CheckError> { | ||||||
|         comp.is_init = true; |         comp.is_init = true; | ||||||
|         let target = self.target.compile(info, comp)?; |         let target = self.target.compile(info, comp)?; | ||||||
|         comp.is_init = false; |         comp.is_init = false; | ||||||
|  | |||||||
| @ -2,7 +2,7 @@ use std::{collections::HashMap, fmt::Debug}; | |||||||
| 
 | 
 | ||||||
| use crate::info; | use crate::info; | ||||||
| 
 | 
 | ||||||
| use super::run::SourceRange; | use super::run::{CheckError, SourceRange}; | ||||||
| 
 | 
 | ||||||
| #[cfg(feature = "parse")] | #[cfg(feature = "parse")] | ||||||
| pub mod assign_to; | pub mod assign_to; | ||||||
| @ -15,6 +15,8 @@ pub mod function; | |||||||
| #[cfg(feature = "parse")] | #[cfg(feature = "parse")] | ||||||
| pub mod r#if; | pub mod r#if; | ||||||
| #[cfg(feature = "parse")] | #[cfg(feature = "parse")] | ||||||
|  | pub mod include_mers; | ||||||
|  | #[cfg(feature = "parse")] | ||||||
| pub mod init_to; | pub mod init_to; | ||||||
| #[cfg(feature = "parse")] | #[cfg(feature = "parse")] | ||||||
| pub mod tuple; | pub mod tuple; | ||||||
| @ -29,12 +31,12 @@ pub trait MersStatement: Debug + Send + Sync { | |||||||
|         &self, |         &self, | ||||||
|         info: &mut Info, |         info: &mut Info, | ||||||
|         comp: CompInfo, |         comp: CompInfo, | ||||||
|     ) -> Result<Box<dyn super::run::MersStatement>, String>; |     ) -> Result<Box<dyn super::run::MersStatement>, CheckError>; | ||||||
|     fn compile( |     fn compile( | ||||||
|         &self, |         &self, | ||||||
|         info: &mut Info, |         info: &mut Info, | ||||||
|         comp: CompInfo, |         comp: CompInfo, | ||||||
|     ) -> Result<Box<dyn super::run::MersStatement>, String> { |     ) -> Result<Box<dyn super::run::MersStatement>, CheckError> { | ||||||
|         if self.has_scope() { |         if self.has_scope() { | ||||||
|             info.create_scope(); |             info.create_scope(); | ||||||
|         } |         } | ||||||
| @ -77,4 +79,7 @@ impl info::Local for Local { | |||||||
|     fn get_var_mut(&mut self, id: &Self::VariableIdentifier) -> Option<&mut Self::VariableData> { |     fn get_var_mut(&mut self, id: &Self::VariableIdentifier) -> Option<&mut Self::VariableData> { | ||||||
|         self.vars.get_mut(id) |         self.vars.get_mut(id) | ||||||
|     } |     } | ||||||
|  |     fn duplicate(&self) -> Self { | ||||||
|  |         self.clone() | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,6 +1,9 @@ | |||||||
| use crate::{ | use crate::{ | ||||||
|     info, |     info, | ||||||
|     program::{self, run::SourceRange}, |     program::{ | ||||||
|  |         self, | ||||||
|  |         run::{CheckError, SourceRange}, | ||||||
|  |     }, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| use super::{CompInfo, MersStatement}; | use super::{CompInfo, MersStatement}; | ||||||
| @ -18,7 +21,7 @@ impl MersStatement for Tuple { | |||||||
|         &self, |         &self, | ||||||
|         info: &mut info::Info<super::Local>, |         info: &mut info::Info<super::Local>, | ||||||
|         comp: CompInfo, |         comp: CompInfo, | ||||||
|     ) -> Result<Box<dyn program::run::MersStatement>, String> { |     ) -> Result<Box<dyn program::run::MersStatement>, CheckError> { | ||||||
|         Ok(Box::new(program::run::tuple::Tuple { |         Ok(Box::new(program::run::tuple::Tuple { | ||||||
|             pos_in_src: self.pos_in_src, |             pos_in_src: self.pos_in_src, | ||||||
|             elems: self |             elems: self | ||||||
|  | |||||||
| @ -1,4 +1,4 @@ | |||||||
| use crate::program::run::SourceRange; | use crate::program::run::{CheckError, SourceRange}; | ||||||
| use crate::{data::Data, program}; | use crate::{data::Data, program}; | ||||||
| 
 | 
 | ||||||
| use super::{CompInfo, MersStatement}; | use super::{CompInfo, MersStatement}; | ||||||
| @ -17,7 +17,7 @@ impl MersStatement for Value { | |||||||
|         &self, |         &self, | ||||||
|         _info: &mut crate::info::Info<super::Local>, |         _info: &mut crate::info::Info<super::Local>, | ||||||
|         _comp: CompInfo, |         _comp: CompInfo, | ||||||
|     ) -> Result<Box<dyn program::run::MersStatement>, String> { |     ) -> Result<Box<dyn program::run::MersStatement>, CheckError> { | ||||||
|         Ok(Box::new(program::run::value::Value { |         Ok(Box::new(program::run::value::Value { | ||||||
|             pos_in_src: self.pos_in_src, |             pos_in_src: self.pos_in_src, | ||||||
|             val: self.data.clone(), |             val: self.data.clone(), | ||||||
|  | |||||||
| @ -1,6 +1,9 @@ | |||||||
| use crate::{ | use crate::{ | ||||||
|     info::Local, |     info::Local, | ||||||
|     program::{self, run::SourceRange}, |     program::{ | ||||||
|  |         self, | ||||||
|  |         run::{CheckError, SourceRange}, | ||||||
|  |     }, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| use super::{CompInfo, MersStatement}; | use super::{CompInfo, MersStatement}; | ||||||
| @ -20,7 +23,7 @@ impl MersStatement for Variable { | |||||||
|         &self, |         &self, | ||||||
|         info: &mut crate::info::Info<super::Local>, |         info: &mut crate::info::Info<super::Local>, | ||||||
|         comp: CompInfo, |         comp: CompInfo, | ||||||
|     ) -> Result<Box<dyn program::run::MersStatement>, String> { |     ) -> Result<Box<dyn program::run::MersStatement>, CheckError> { | ||||||
|         if comp.is_init { |         if comp.is_init { | ||||||
|             info.init_var( |             info.init_var( | ||||||
|                 self.var.clone(), |                 self.var.clone(), | ||||||
| @ -37,7 +40,9 @@ impl MersStatement for Variable { | |||||||
|             var: if let Some(v) = info.get_var(&self.var) { |             var: if let Some(v) = info.get_var(&self.var) { | ||||||
|                 *v |                 *v | ||||||
|             } else { |             } else { | ||||||
|                 return Err(format!("No variable named '{}' found!", self.var)); |                 return Err(CheckError::new() | ||||||
|  |                     .src(vec![(self.pos_in_src, Some(colored::Color::Red))]) | ||||||
|  |                     .msg(format!("No variable named '{}' found!", self.var))); | ||||||
|             }, |             }, | ||||||
|         })) |         })) | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -268,6 +268,15 @@ impl info::Local for Local { | |||||||
|             None => None, |             None => None, | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |     fn duplicate(&self) -> Self { | ||||||
|  |         Self { | ||||||
|  |             vars: self | ||||||
|  |                 .vars | ||||||
|  |                 .iter() | ||||||
|  |                 .map(|v| Arc::new(RwLock::new(v.read().unwrap().clone()))) | ||||||
|  |                 .collect(), | ||||||
|  |         } | ||||||
|  |     } | ||||||
| } | } | ||||||
| impl info::Local for CheckLocal { | impl info::Local for CheckLocal { | ||||||
|     type VariableIdentifier = usize; |     type VariableIdentifier = usize; | ||||||
| @ -290,4 +299,7 @@ impl info::Local for CheckLocal { | |||||||
|             None => None, |             None => None, | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |     fn duplicate(&self) -> Self { | ||||||
|  |         self.clone() | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Mark
						Mark