From 0a9eea2045276b54a54d054c408ad5a6d09054bb Mon Sep 17 00:00:00 2001 From: Mark Date: Fri, 24 Nov 2023 13:19:38 +0100 Subject: [PATCH] fix bug where error would reference wrong file --- mers/src/main.rs | 11 +- mers_lib/src/errors/mod.rs | 75 +++------- mers_lib/src/parsing/mod.rs | 9 +- mers_lib/src/parsing/statements.rs | 139 +++++++++--------- mers_lib/src/parsing/types.rs | 18 +-- mers_lib/src/program/configs/with_list.rs | 4 +- .../program/configs/with_multithreading.rs | 4 +- mers_lib/src/program/parsed/as_type.rs | 6 +- mers_lib/src/program/parsed/assign_to.rs | 4 +- mers_lib/src/program/parsed/block.rs | 4 +- mers_lib/src/program/parsed/chain.rs | 4 +- mers_lib/src/program/parsed/custom_type.rs | 4 +- mers_lib/src/program/parsed/function.rs | 4 +- mers_lib/src/program/parsed/if.rs | 4 +- mers_lib/src/program/parsed/include_mers.rs | 12 +- mers_lib/src/program/parsed/init_to.rs | 4 +- mers_lib/src/program/parsed/tuple.rs | 4 +- mers_lib/src/program/parsed/value.rs | 4 +- mers_lib/src/program/parsed/variable.rs | 9 +- mers_lib/src/program/run/as_type.rs | 8 +- mers_lib/src/program/run/assign_to.rs | 8 +- mers_lib/src/program/run/block.rs | 2 +- mers_lib/src/program/run/chain.rs | 12 +- mers_lib/src/program/run/custom_type.rs | 2 +- mers_lib/src/program/run/function.rs | 2 +- mers_lib/src/program/run/if.rs | 4 +- mers_lib/src/program/run/tuple.rs | 2 +- mers_lib/src/program/run/value.rs | 2 +- mers_lib/src/program/run/variable.rs | 2 +- 29 files changed, 173 insertions(+), 194 deletions(-) diff --git a/mers/src/main.rs b/mers/src/main.rs index 147fe17..3d68649 100755 --- a/mers/src/main.rs +++ b/mers/src/main.rs @@ -1,6 +1,6 @@ use clap::{Parser, Subcommand, ValueEnum}; use mers_lib::prelude_compile::*; -use std::{fmt::Display, fs, path::PathBuf, process::exit}; +use std::{fmt::Display, path::PathBuf, process::exit, sync::Arc}; mod cfg_globals; @@ -78,10 +78,11 @@ fn main() { }, Command::Exec { source } => Source::new_from_string(source), }; - let parsed = match parse(&mut source) { + let srca = Arc::new(source.clone()); + let parsed = match parse(&mut source, &srca) { Ok(v) => v, Err(e) => { - eprintln!("{}", e.display(&source).show_comments(!args.hide_comments)); + eprintln!("{}", e.display().show_comments(!args.hide_comments)); exit(20); } }; @@ -90,7 +91,7 @@ fn main() { let run = match parsed.compile(&mut info_parsed, Default::default()) { Ok(v) => v, Err(e) => { - eprintln!("{}", e.display(&source).show_comments(!args.hide_comments)); + eprintln!("{}", e.display().show_comments(!args.hide_comments)); exit(24); } }; @@ -104,7 +105,7 @@ fn main() { let return_type = match run.check(&mut info_check, None) { Ok(v) => v, Err(e) => { - eprint!("{}", e.display(&source).show_comments(!args.hide_comments)); + eprint!("{}", e.display().show_comments(!args.hide_comments)); exit(28); } }; diff --git a/mers_lib/src/errors/mod.rs b/mers_lib/src/errors/mod.rs index eb87b69..050e5e1 100644 --- a/mers_lib/src/errors/mod.rs +++ b/mers_lib/src/errors/mod.rs @@ -1,4 +1,7 @@ -use std::fmt::{Debug, Display}; +use std::{ + fmt::{Debug, Display}, + sync::Arc, +}; use colored::Colorize; use line_span::LineSpans; @@ -14,14 +17,16 @@ impl SourcePos { } } -#[derive(Clone, Copy, Debug)] +#[derive(Clone, Debug)] pub struct SourceRange { + in_file: Arc, start: SourcePos, end: SourcePos, } -impl From<(SourcePos, SourcePos)> for SourceRange { - fn from(value: (SourcePos, SourcePos)) -> Self { +impl From<(SourcePos, SourcePos, &Arc)> for SourceRange { + fn from(value: (SourcePos, SourcePos, &Arc)) -> Self { SourceRange { + in_file: Arc::clone(value.2), start: value.0, end: value.1, } @@ -74,7 +79,7 @@ pub mod error_colors { enum CheckErrorComponent { Message(String), Error(CheckError), - ErrorWithSrc(CheckErrorWithSrc), + ErrorWithDifferentSource(CheckError), Source(Vec<(SourceRange, Option)>), } #[derive(Clone)] @@ -88,13 +93,6 @@ pub struct CheckErrorHRConfig { #[cfg(feature = "parse")] pub struct CheckErrorDisplay<'a> { e: &'a CheckError, - src: Option<&'a Source>, - pub show_comments: bool, -} -#[cfg(feature = "parse")] -pub struct CheckErrorWithSrc { - e: CheckError, - src: Source, pub show_comments: bool, } #[cfg(feature = "parse")] @@ -105,33 +103,10 @@ impl<'a> CheckErrorDisplay<'a> { } } #[cfg(feature = "parse")] -impl CheckErrorWithSrc { - pub fn show_comments(mut self, show_comments: bool) -> Self { - self.show_comments = show_comments; - self - } -} -#[cfg(feature = "parse")] impl Display for CheckErrorDisplay<'_> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { self.e.human_readable( f, - self.src, - &CheckErrorHRConfig { - indent_start: String::new(), - indent_default: String::new(), - indent_end: String::new(), - show_comments: self.show_comments, - }, - ) - } -} -#[cfg(feature = "parse")] -impl Display for CheckErrorWithSrc { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - self.e.human_readable( - f, - Some(&self.src), &CheckErrorHRConfig { indent_start: String::new(), indent_default: String::new(), @@ -155,29 +130,16 @@ impl CheckError { pub(crate) fn err(self, e: Self) -> Self { self.add(CheckErrorComponent::Error(e)) } - pub(crate) fn err_with_src(self, e: CheckError, src: Source) -> Self { - self.add(CheckErrorComponent::ErrorWithSrc(CheckErrorWithSrc { - e, - src, - show_comments: true, - })) + pub(crate) fn err_with_diff_src(self, e: CheckError) -> Self { + self.add(CheckErrorComponent::ErrorWithDifferentSource(e)) } pub(crate) fn src(self, s: Vec<(SourceRange, Option)>) -> Self { self.add(CheckErrorComponent::Source(s)) } #[cfg(feature = "parse")] - pub fn display<'a>(&'a self, src: &'a Source) -> CheckErrorDisplay<'a> { + pub fn display<'a>(&'a self) -> CheckErrorDisplay<'a> { CheckErrorDisplay { e: self, - src: Some(src), - show_comments: true, - } - } - #[cfg(feature = "parse")] - pub fn display_no_src<'a>(&'a self) -> CheckErrorDisplay<'a> { - CheckErrorDisplay { - e: self, - src: None, show_comments: true, } } @@ -186,7 +148,6 @@ impl CheckError { fn human_readable( &self, f: &mut std::fmt::Formatter<'_>, - src: Option<&Source>, cfg: &CheckErrorHRConfig, ) -> std::fmt::Result { use crate::parsing::SourceFrom; @@ -211,18 +172,18 @@ impl CheckError { cfg.indent_start.push_str("│"); cfg.indent_default.push_str("│"); cfg.indent_end.push_str("└"); - err.human_readable(f, src, &cfg)?; + err.human_readable(f, &cfg)?; } - CheckErrorComponent::ErrorWithSrc(err) => { + CheckErrorComponent::ErrorWithDifferentSource(err) => { let mut cfg = cfg.clone(); cfg.indent_start.push_str(&"│".bright_yellow().to_string()); cfg.indent_default .push_str(&"│".bright_yellow().to_string()); cfg.indent_end.push_str(&"└".bright_yellow().to_string()); - err.e.human_readable(f, Some(&err.src), &cfg)?; + err.human_readable(f, &cfg)?; } CheckErrorComponent::Source(highlights) => { - if let Some(src) = src { + if let Some(src) = highlights.first().map(|v| v.0.in_file.as_ref()) { let start = highlights.iter().map(|v| v.0.start.pos()).min(); let end = highlights.iter().map(|v| v.0.end.pos()).max(); if let (Some(start_in_line), Some(end_in_line)) = (start, end) { @@ -370,6 +331,6 @@ impl Debug for CheckError { } impl Display for CheckError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.display_no_src()) + write!(f, "{}", self.display()) } } diff --git a/mers_lib/src/parsing/mod.rs b/mers_lib/src/parsing/mod.rs index 6f62403..3754345 100755 --- a/mers_lib/src/parsing/mod.rs +++ b/mers_lib/src/parsing/mod.rs @@ -8,11 +8,14 @@ use crate::{ pub mod statements; pub mod types; -pub fn parse(src: &mut Source) -> Result, CheckError> { +pub fn parse( + src: &mut Source, + srca: &Arc, +) -> Result, CheckError> { let pos_in_src = src.get_pos(); - let statements = statements::parse_multiple(src, "")?; + let statements = statements::parse_multiple(src, srca, "")?; let block = Block { - pos_in_src: (pos_in_src, src.get_pos()).into(), + pos_in_src: (pos_in_src, src.get_pos(), srca).into(), statements, }; Ok(Box::new(block)) diff --git a/mers_lib/src/parsing/statements.rs b/mers_lib/src/parsing/statements.rs index 9476246..5a86e3f 100755 --- a/mers_lib/src/parsing/statements.rs +++ b/mers_lib/src/parsing/statements.rs @@ -1,4 +1,4 @@ -use std::path::PathBuf; +use std::{path::PathBuf, sync::Arc}; use super::{Source, SourcePos}; use crate::{ @@ -12,6 +12,7 @@ use crate::{ pub fn parse( src: &mut Source, + srca: &Arc, ) -> Result>, CheckError> { src.section_begin("statement".to_string()); src.skip_whitespace(); @@ -37,11 +38,11 @@ pub fn parse( if src.peek_word() == ":=" { src.next_word(); // [[name] := statement] - let statement = match parse(src) { + let statement = match parse(src, srca) { Ok(Some(v)) => v, Ok(None) => { return Err(CheckError::new() - .src(vec![((pos_in_src, src.get_pos()).into(), None)]) + .src(vec![((pos_in_src, src.get_pos(), srca).into(), None)]) .msg(format!("EOF after `[...]` type annotation"))) } Err(e) => return Err(e), @@ -52,14 +53,14 @@ pub fn parse( ))); } Box::new(program::parsed::custom_type::CustomType { - pos_in_src: (pos_in_src, src.get_pos()).into(), + pos_in_src: (pos_in_src, src.get_pos(), srca).into(), name, source: Err(statement), }) } else { // [[name] type] src.skip_whitespace(); - let as_type = super::types::parse_type(src)?; + let as_type = super::types::parse_type(src, srca)?; src.skip_whitespace(); if !matches!(src.next_char(), Some(']')) { return Err(CheckError::new().msg(format!( @@ -67,7 +68,7 @@ pub fn parse( ))); } Box::new(program::parsed::custom_type::CustomType { - pos_in_src: (pos_in_src, src.get_pos()).into(), + pos_in_src: (pos_in_src, src.get_pos(), srca).into(), name, source: Ok(as_type), }) @@ -76,28 +77,28 @@ pub fn parse( // [type] statement src.skip_whitespace(); let type_pos_in_src = src.get_pos(); - let as_type = super::types::parse_type(src)?; - let type_pos_in_src = (type_pos_in_src, src.get_pos()).into(); + let as_type = super::types::parse_type(src, srca)?; + let type_pos_in_src = (type_pos_in_src, src.get_pos(), srca).into(); src.skip_whitespace(); if !matches!(src.next_char(), Some(']')) { return Err(CheckError::new() .src(vec![( - (pos_in_src, src.get_pos()).into(), + (pos_in_src, src.get_pos(), srca).into(), Some(error_colors::TypeAnnotationNoClosingBracket), )]) .msg(format!("Missing closing bracket ']' after type annotation"))); } - let statement = match parse(src) { + let statement = match parse(src, srca) { Ok(Some(v)) => v, Ok(None) => { return Err(CheckError::new() - .src(vec![((pos_in_src, src.get_pos()).into(), None)]) + .src(vec![((pos_in_src, src.get_pos(), srca).into(), None)]) .msg(format!("EOF after `[...]` type annotation"))) } Err(e) => return Err(e), }; Box::new(AsType { - pos_in_src: (pos_in_src, src.get_pos()).into(), + pos_in_src: (pos_in_src, src.get_pos(), srca).into(), statement, as_type, type_pos_in_src, @@ -105,7 +106,7 @@ pub fn parse( }) })); } - let mut first = if let Some(s) = parse_no_chain(src)? { + let mut first = if let Some(s) = parse_no_chain(src, srca)? { s } else { return Ok(None); @@ -116,13 +117,13 @@ pub fn parse( ":=" => { let pos_in_src = src.get_pos(); src.next_word(); - let source = parse(src)?.ok_or_else(|| { + let source = parse(src, srca)?.ok_or_else(|| { CheckError::new() - .src(vec![((pos_in_src, src.get_pos()).into(), None)]) + .src(vec![((pos_in_src, src.get_pos(), srca).into(), None)]) .msg(format!("EOF after `:=`")) })?; 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(), srca).into(), target: first, source, }); @@ -130,13 +131,13 @@ pub fn parse( "=" => { let pos_in_src = src.get_pos(); src.next_word(); - let source = parse(src)?.ok_or_else(|| { + let source = parse(src, srca)?.ok_or_else(|| { CheckError::new() - .src(vec![((pos_in_src, src.get_pos()).into(), None)]) + .src(vec![((pos_in_src, src.get_pos(), srca).into(), None)]) .msg(format!("EOF after `=`")) })?; 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(), srca).into(), target: first, source, }); @@ -144,17 +145,17 @@ pub fn parse( "->" => { let pos_in_src = src.get_pos(); src.next_word(); - let run = match parse(src) { + let run = match parse(src, srca) { Ok(Some(v)) => v, Ok(None) => { return Err(CheckError::new() - .src(vec![((pos_in_src, src.get_pos()).into(), None)]) + .src(vec![((pos_in_src, src.get_pos(), srca).into(), None)]) .msg(format!("EOF after `->`"))) } Err(e) => return Err(e), }; first = Box::new(program::parsed::function::Function { - pos_in_src: (pos_in_src, src.get_pos()).into(), + pos_in_src: (pos_in_src, src.get_pos(), srca).into(), arg: first, run, }); @@ -164,11 +165,11 @@ pub fn parse( let dot_in_src = src.get_pos(); if let Some('.') = src.peek_char() { src.next_char(); - let chained = match parse_no_chain(src) { + let chained = match parse_no_chain(src, srca) { Ok(Some(v)) => v, Ok(None) => { return Err(CheckError::new() - .src(vec![((dot_in_src, src.get_pos()).into(), None)]) + .src(vec![((dot_in_src, src.get_pos(), srca).into(), None)]) .msg(format!("EOF after `.`"))) } Err(e) => return Err(e), @@ -176,14 +177,14 @@ pub fn parse( // allow a.f(b, c) syntax (but not f(a, b, c)) if let Some('(') = src.peek_char() { src.next_char(); - let elems = parse_multiple(src, ")")?; + let elems = parse_multiple(src, srca, ")")?; first = Box::new(program::parsed::tuple::Tuple { - pos_in_src: (first.source_range().start(), src.get_pos()).into(), + pos_in_src: (first.source_range().start(), src.get_pos(), srca).into(), elems: [first].into_iter().chain(elems).collect(), }); } first = Box::new(program::parsed::chain::Chain { - pos_in_src: (first.source_range().start(), src.get_pos()).into(), + pos_in_src: (first.source_range().start(), src.get_pos(), srca).into(), first, chained, }); @@ -201,6 +202,7 @@ pub fn parse( } pub fn parse_multiple( src: &mut Source, + srca: &Arc, end: &str, ) -> Result>, CheckError> { src.section_begin("block".to_string()); @@ -210,7 +212,7 @@ pub fn parse_multiple( if src.peek_char().is_some_and(|ch| end.contains(ch)) { src.next_char(); break; - } else if let Some(s) = parse(src)? { + } else if let Some(s) = parse(src, srca)? { statements.push(s); } else { // EOF @@ -221,6 +223,7 @@ pub fn parse_multiple( } pub fn parse_no_chain( src: &mut Source, + srca: &Arc, ) -> Result>, CheckError> { src.skip_whitespace(); src.section_begin("statement no chain".to_string()); @@ -230,14 +233,14 @@ pub fn parse_no_chain( src.next_char(); if src.peek_char().is_none() { return Err(CheckError::new() - .src(vec![((pos_in_src, src.get_pos()).into(), None)]) + .src(vec![((pos_in_src, src.get_pos(), srca).into(), None)]) .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(), + (pos_in_src, src.get_pos(), srca).into(), Some(error_colors::WhitespaceAfterHashtag), )]) .msg(format!("Whitespace after #"))); @@ -248,18 +251,17 @@ pub fn parse_no_chain( src.skip_whitespace(); let string_in_src = src.get_pos(); if src.next_char() == Some('"') { - let file_path = parse_string(src, string_in_src)?; + let file_path = parse_string(src, srca, string_in_src)?; match Source::new_from_file(PathBuf::from(&file_path)) { Ok(mut inner_src) => { + let inner_srca = Arc::new(inner_src.clone()); return Ok(Some(Box::new( program::parsed::include_mers::IncludeMers { - pos_in_src: (pos_in_src, src.get_pos()).into(), - include: match super::parse(&mut inner_src) { + pos_in_src: (pos_in_src, src.get_pos(), srca).into(), + include: match super::parse(&mut inner_src, &inner_srca) { Ok(v) => v, Err(e) => { - return Err( - CheckError::new().err_with_src(e, inner_src) - ) + return Err(CheckError::new().err_with_diff_src(e)) } }, inner_src, @@ -269,9 +271,9 @@ pub fn parse_no_chain( Err(e) => { return Err(CheckError::new() .src(vec![ - ((pos_in_src, end_in_src).into(), None), + ((pos_in_src, end_in_src, srca).into(), None), ( - (string_in_src, src.get_pos()).into(), + (string_in_src, src.get_pos(), srca).into(), Some(error_colors::HashIncludeCantLoadFile), ), ]) @@ -281,8 +283,8 @@ pub fn parse_no_chain( } else { return Err(CheckError::new() .src(vec![ - ((pos_in_src, end_in_src).into(), None), - ((string_in_src, src.get_pos()).into(), Some(error_colors::HashIncludeNotAString)), + ((pos_in_src, end_in_src, srca).into(), None), + ((string_in_src, src.get_pos(), srca).into(), Some(error_colors::HashIncludeNotAString)), ]) .msg(format!( "#include must be followed by a string literal like \"file.mers\" (\" expected)." @@ -293,7 +295,7 @@ pub fn parse_no_chain( let msg = format!("Unknown #statement: {other}"); return Err(CheckError::new() .src(vec![( - (pos_in_src, src.get_pos()).into(), + (pos_in_src, src.get_pos(), srca).into(), Some(error_colors::HashUnknown), )]) .msg(msg)); @@ -303,18 +305,18 @@ pub fn parse_no_chain( Some('{') => { let pos_in_src = src.get_pos(); src.next_char(); - let statements = parse_multiple(src, "}")?; + let statements = parse_multiple(src, srca, "}")?; return Ok(Some(Box::new(program::parsed::block::Block { - pos_in_src: (pos_in_src, src.get_pos()).into(), + pos_in_src: (pos_in_src, src.get_pos(), srca).into(), statements, }))); } Some('(') => { let pos_in_src = src.get_pos(); src.next_char(); - let elems = parse_multiple(src, ")")?; + let elems = parse_multiple(src, srca, ")")?; return Ok(Some(Box::new(program::parsed::tuple::Tuple { - pos_in_src: (pos_in_src, src.get_pos()).into(), + pos_in_src: (pos_in_src, src.get_pos(), srca).into(), elems, }))); } @@ -322,9 +324,9 @@ pub fn parse_no_chain( src.section_begin("string literal".to_string()); let pos_in_src = src.get_pos(); src.next_char(); - let s = parse_string(src, pos_in_src)?; + let s = parse_string(src, srca, pos_in_src)?; 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(), srca).into(), data: Data::new(crate::data::string::String(s)), }))); } @@ -335,20 +337,20 @@ pub fn parse_no_chain( "if" => { src.section_begin("if".to_string()); src.skip_whitespace(); - let condition = match parse(src) { + let condition = match parse(src, srca) { Ok(Some(v)) => v, Ok(None) => { return Err(CheckError::new() - .src(vec![((pos_in_src, src.get_pos()).into(), None)]) + .src(vec![((pos_in_src, src.get_pos(), srca).into(), None)]) .msg(format!("EOF in `if`"))) } Err(e) => return Err(e), }; - let on_true = match parse(src) { + let on_true = match parse(src, srca) { Ok(Some(v)) => v, Ok(None) => { return Err(CheckError::new() - .src(vec![((pos_in_src, src.get_pos()).into(), None)]) + .src(vec![((pos_in_src, src.get_pos(), srca).into(), None)]) .msg(format!("EOF after `if `"))) } Err(e) => return Err(e), @@ -358,11 +360,11 @@ pub fn parse_no_chain( if src.peek_word() == "else" { src.section_begin("else".to_string()); src.next_word(); - Some(match parse(src) { + Some(match parse(src, srca) { Ok(Some(v)) => v, Ok(None) => { return Err(CheckError::new() - .src(vec![((pos_in_src, src.get_pos()).into(), None)]) + .src(vec![((pos_in_src, src.get_pos(), srca).into(), None)]) .msg(format!("EOF after `else`"))) } Err(e) => return Err(e), @@ -372,18 +374,18 @@ pub fn parse_no_chain( } }; Box::new(program::parsed::r#if::If { - pos_in_src: (pos_in_src, src.get_pos()).into(), + pos_in_src: (pos_in_src, src.get_pos(), srca).into(), condition, on_true, on_false, }) } "true" => 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(), srca).into(), data: Data::new(crate::data::bool::Bool(true)), }), "false" => 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(), srca).into(), data: Data::new(crate::data::bool::Bool(false)), }), "" => return Ok(None), @@ -396,32 +398,32 @@ pub fn parse_no_chain( src.next_char(); if let Ok(num) = format!("{o}.{}", src.next_word()).parse() { 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(), srca).into(), data: Data::new(crate::data::float::Float(num)), }) } else { src.set_pos(here); 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(), srca).into(), data: Data::new(crate::data::int::Int(n)), }) } } else { 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(), srca).into(), data: Data::new(crate::data::int::Int(n)), }) } } else { if let Some('&') = o.chars().next() { Box::new(program::parsed::variable::Variable { - pos_in_src: (pos_in_src, src.get_pos()).into(), + pos_in_src: (pos_in_src, src.get_pos(), srca).into(), is_ref: true, var: o[1..].to_string(), }) } else { Box::new(program::parsed::variable::Variable { - pos_in_src: (pos_in_src, src.get_pos()).into(), + pos_in_src: (pos_in_src, src.get_pos(), srca).into(), is_ref: false, var: o.to_string(), }) @@ -432,11 +434,16 @@ 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 { - parse_string_custom_end(src, double_quote, '"', '"') +pub fn parse_string( + src: &mut Source, + srca: &Arc, + double_quote: SourcePos, +) -> Result { + parse_string_custom_end(src, srca, double_quote, '"', '"') } pub fn parse_string_custom_end( src: &mut Source, + srca: &Arc, opening: SourcePos, opening_char: char, closing_char: char, @@ -456,7 +463,7 @@ pub fn parse_string_custom_end( Some(o) => { return Err(CheckError::new() .src(vec![( - (backslash_in_src, src.get_pos()).into(), + (backslash_in_src, src.get_pos(), srca).into(), Some(error_colors::BackslashEscapeUnknown), )]) .msg(format!("unknown backslash escape '\\{o}'"))); @@ -464,7 +471,7 @@ pub fn parse_string_custom_end( None => { return Err(CheckError::new() .src(vec![( - (backslash_in_src, src.get_pos()).into(), + (backslash_in_src, src.get_pos(), srca).into(), Some(error_colors::BackslashEscapeEOF), )]) .msg(format!("EOF in backslash escape"))); @@ -478,7 +485,7 @@ pub fn parse_string_custom_end( } else { return Err(CheckError::new() .src(vec![( - (opening, src.get_pos()).into(), + (opening, src.get_pos(), srca).into(), Some(error_colors::StringEOF), )]) .msg(format!( diff --git a/mers_lib/src/parsing/types.rs b/mers_lib/src/parsing/types.rs index 1be85dc..67264fc 100755 --- a/mers_lib/src/parsing/types.rs +++ b/mers_lib/src/parsing/types.rs @@ -16,7 +16,7 @@ pub enum ParsedType { TypeWithInfo(String, String), } -pub fn parse_single_type(src: &mut Source) -> Result { +pub fn parse_single_type(src: &mut Source, srca: &Arc) -> Result { src.section_begin("parse single type".to_string()); src.skip_whitespace(); Ok(match src.peek_char() { @@ -25,7 +25,7 @@ pub fn parse_single_type(src: &mut Source) -> Result { src.next_char(); if let Some('{') = src.peek_char() { src.next_char(); - let types = parse_type(src)?; + let types = parse_type(src, srca)?; let nc = src.next_char(); if !matches!(nc, Some('}')) { let nc = if let Some(nc) = nc { @@ -39,7 +39,7 @@ pub fn parse_single_type(src: &mut Source) -> Result { } ParsedType::Reference(types) } else { - ParsedType::Reference(vec![parse_single_type(src)?]) + ParsedType::Reference(vec![parse_single_type(src, srca)?]) } } // Tuple @@ -53,7 +53,7 @@ pub fn parse_single_type(src: &mut Source) -> Result { // empty tuple, don't even start the loop } else { loop { - inner.push(parse_type(src)?); + inner.push(parse_type(src, srca)?); match src.peek_char() { Some(')') => { src.next_char(); @@ -67,9 +67,9 @@ pub fn parse_single_type(src: &mut Source) -> Result { src.next_char(); return Err(CheckError::new() .src(vec![ - ((pos_in_src, src.get_pos()).into(), None), + ((pos_in_src, src.get_pos(), srca).into(), None), ( - (ppos, src.get_pos()).into(), + (ppos, src.get_pos(), srca).into(), Some(error_colors::BadCharInTupleType), ), ]) @@ -90,7 +90,7 @@ pub fn parse_single_type(src: &mut Source) -> Result { src.next_char(); ParsedType::TypeWithInfo( t, - super::statements::parse_string_custom_end(src, pos, '<', '>')?, + super::statements::parse_string_custom_end(src, srca, pos, '<', '>')?, ) } else { ParsedType::Type(t) @@ -100,11 +100,11 @@ pub fn parse_single_type(src: &mut Source) -> Result { }) } -pub fn parse_type(src: &mut Source) -> Result, CheckError> { +pub fn parse_type(src: &mut Source, srca: &Arc) -> Result, CheckError> { src.section_begin("parse single type".to_string()); let mut types = vec![]; loop { - types.push(parse_single_type(src)?); + types.push(parse_single_type(src, srca)?); src.skip_whitespace(); if let Some('/') = src.peek_char() { src.next_char(); diff --git a/mers_lib/src/program/configs/with_list.rs b/mers_lib/src/program/configs/with_list.rs index 75b1b16..b96c6e2 100755 --- a/mers_lib/src/program/configs/with_list.rs +++ b/mers_lib/src/program/configs/with_list.rs @@ -23,7 +23,9 @@ impl Config { // TODO: Type with generics self.add_type("List".to_string(), Err(Arc::new(|s, i| { - let t = crate::parsing::types::parse_type(&mut Source::new_from_string_raw(s.to_owned()))?; + let mut src = Source::new_from_string_raw(s.to_owned()); + let srca = Arc::new(src.clone()); + let t = crate::parsing::types::parse_type(&mut src, &srca)?; Ok(Arc::new(ListT(crate::parsing::types::type_from_parsed(&t, i)?)))}))) .add_var( "pop".to_string(), diff --git a/mers_lib/src/program/configs/with_multithreading.rs b/mers_lib/src/program/configs/with_multithreading.rs index c6d11c7..dc7bd81 100755 --- a/mers_lib/src/program/configs/with_multithreading.rs +++ b/mers_lib/src/program/configs/with_multithreading.rs @@ -21,7 +21,9 @@ impl Config { self.add_type( "Thread".to_string(), Err(Arc::new(|s, i| { - let t = crate::parsing::types::parse_type(&mut Source::new_from_string_raw(s.to_owned()))?; + let mut src = Source::new_from_string_raw(s.to_owned()); + let srca = Arc::new(src.clone()); + let t = crate::parsing::types::parse_type(&mut src, &srca)?; Ok(Arc::new(ThreadT(crate::parsing::types::type_from_parsed(&t, i)?))) })), ) diff --git a/mers_lib/src/program/parsed/as_type.rs b/mers_lib/src/program/parsed/as_type.rs index 5cdbb3e..c188246 100755 --- a/mers_lib/src/program/parsed/as_type.rs +++ b/mers_lib/src/program/parsed/as_type.rs @@ -25,14 +25,14 @@ impl MersStatement for AsType { comp: CompInfo, ) -> Result, CheckError> { Ok(Box::new(program::run::as_type::AsType { - pos_in_src: self.pos_in_src, + pos_in_src: self.pos_in_src.clone(), statement: self.statement.compile(info, comp)?, as_type: self.as_type.clone(), - type_pos_in_src: self.type_pos_in_src, + type_pos_in_src: self.type_pos_in_src.clone(), expand_type: self.expand_type, })) } fn source_range(&self) -> SourceRange { - self.pos_in_src + self.pos_in_src.clone() } } diff --git a/mers_lib/src/program/parsed/assign_to.rs b/mers_lib/src/program/parsed/assign_to.rs index ce9628a..aa81998 100755 --- a/mers_lib/src/program/parsed/assign_to.rs +++ b/mers_lib/src/program/parsed/assign_to.rs @@ -22,13 +22,13 @@ impl MersStatement for AssignTo { comp: CompInfo, ) -> Result, CheckError> { Ok(Box::new(program::run::assign_to::AssignTo { - pos_in_src: self.pos_in_src, + pos_in_src: self.pos_in_src.clone(), is_init: false, source: self.source.compile(info, comp)?, target: self.target.compile(info, comp)?, })) } fn source_range(&self) -> SourceRange { - self.pos_in_src + self.pos_in_src.clone() } } diff --git a/mers_lib/src/program/parsed/block.rs b/mers_lib/src/program/parsed/block.rs index c905432..2797687 100755 --- a/mers_lib/src/program/parsed/block.rs +++ b/mers_lib/src/program/parsed/block.rs @@ -21,7 +21,7 @@ impl MersStatement for Block { comp: CompInfo, ) -> Result, CheckError> { Ok(Box::new(program::run::block::Block { - pos_in_src: self.pos_in_src, + pos_in_src: self.pos_in_src.clone(), statements: self .statements .iter() @@ -30,6 +30,6 @@ impl MersStatement for Block { })) } fn source_range(&self) -> SourceRange { - self.pos_in_src + self.pos_in_src.clone() } } diff --git a/mers_lib/src/program/parsed/chain.rs b/mers_lib/src/program/parsed/chain.rs index cdac4d0..b08c9e1 100755 --- a/mers_lib/src/program/parsed/chain.rs +++ b/mers_lib/src/program/parsed/chain.rs @@ -21,13 +21,13 @@ impl MersStatement for Chain { comp: CompInfo, ) -> Result, CheckError> { Ok(Box::new(program::run::chain::Chain { - pos_in_src: self.pos_in_src, + pos_in_src: self.pos_in_src.clone(), first: self.first.compile(info, comp)?, chained: self.chained.compile(info, comp)?, as_part_of_include: None, })) } fn source_range(&self) -> SourceRange { - self.pos_in_src + self.pos_in_src.clone() } } diff --git a/mers_lib/src/program/parsed/custom_type.rs b/mers_lib/src/program/parsed/custom_type.rs index 690d958..c54cef8 100644 --- a/mers_lib/src/program/parsed/custom_type.rs +++ b/mers_lib/src/program/parsed/custom_type.rs @@ -23,7 +23,7 @@ impl MersStatement for CustomType { Err(s) => Err(s.compile(info, comp)?), }; Ok(Box::new(crate::program::run::custom_type::CustomType { - pos_in_src: self.pos_in_src, + pos_in_src: self.pos_in_src.clone(), name: self.name.clone(), source: Box::new(move |ci| match &src { Ok(parsed) => Ok(Ok(Arc::new(type_from_parsed(parsed, ci)?))), @@ -35,7 +35,7 @@ impl MersStatement for CustomType { false } fn source_range(&self) -> SourceRange { - self.pos_in_src + self.pos_in_src.clone() } } diff --git a/mers_lib/src/program/parsed/function.rs b/mers_lib/src/program/parsed/function.rs index eb02e4c..6d5ac9c 100755 --- a/mers_lib/src/program/parsed/function.rs +++ b/mers_lib/src/program/parsed/function.rs @@ -32,7 +32,7 @@ impl MersStatement for Function { let arg2: Arc> = Arc::clone(&arg_target); let run2: Arc> = Arc::clone(&run); Ok(Box::new(program::run::function::Function { - pos_in_src: self.pos_in_src, + pos_in_src: self.pos_in_src.clone(), func_no_info: data::function::Function { info: Arc::new(program::run::Info::neverused()), info_check: Arc::new(Mutex::new(CheckInfo::neverused())), @@ -48,6 +48,6 @@ impl MersStatement for Function { })) } fn source_range(&self) -> SourceRange { - self.pos_in_src + self.pos_in_src.clone() } } diff --git a/mers_lib/src/program/parsed/if.rs b/mers_lib/src/program/parsed/if.rs index 6bc4790..1e37b98 100755 --- a/mers_lib/src/program/parsed/if.rs +++ b/mers_lib/src/program/parsed/if.rs @@ -23,7 +23,7 @@ impl MersStatement for If { comp: CompInfo, ) -> Result, CheckError> { Ok(Box::new(program::run::r#if::If { - pos_in_src: self.pos_in_src, + pos_in_src: self.pos_in_src.clone(), condition: self.condition.compile(info, comp)?, on_true: self.on_true.compile(info, comp)?, on_false: if let Some(v) = &self.on_false { @@ -34,6 +34,6 @@ impl MersStatement for If { })) } fn source_range(&self) -> SourceRange { - self.pos_in_src + self.pos_in_src.clone() } } diff --git a/mers_lib/src/program/parsed/include_mers.rs b/mers_lib/src/program/parsed/include_mers.rs index 70c3315..93f96fe 100644 --- a/mers_lib/src/program/parsed/include_mers.rs +++ b/mers_lib/src/program/parsed/include_mers.rs @@ -33,7 +33,7 @@ impl MersStatement for IncludeMers { Err(e) => { return Err(CheckError::new() .src(vec![( - self.pos_in_src, + self.pos_in_src.clone(), Some(error_colors::HashIncludeErrorInIncludedFile), )]) .msg( @@ -41,18 +41,18 @@ impl MersStatement for IncludeMers { .color(error_colors::HashIncludeErrorInIncludedFile) .to_string(), ) - .err_with_src(e, self.inner_src.clone())) + .err_with_diff_src(e)) } }; let compiled2 = Arc::clone(&compiled); Ok(Box::new(program::run::chain::Chain { - pos_in_src: self.pos_in_src, + pos_in_src: self.pos_in_src.clone(), first: Box::new(program::run::value::Value { - pos_in_src: self.pos_in_src, + pos_in_src: self.pos_in_src.clone(), val: Data::empty_tuple(), }), chained: Box::new(program::run::function::Function { - pos_in_src: self.pos_in_src, + pos_in_src: self.pos_in_src.clone(), func_no_info: data::function::Function { info: Arc::new(info::Info::neverused()), info_check: Arc::new(Mutex::new(info::Info::neverused())), @@ -64,6 +64,6 @@ impl MersStatement for IncludeMers { })) } fn source_range(&self) -> SourceRange { - self.pos_in_src + self.pos_in_src.clone() } } diff --git a/mers_lib/src/program/parsed/init_to.rs b/mers_lib/src/program/parsed/init_to.rs index fd14e93..e4b2eef 100755 --- a/mers_lib/src/program/parsed/init_to.rs +++ b/mers_lib/src/program/parsed/init_to.rs @@ -28,13 +28,13 @@ impl MersStatement for InitTo { let target = self.target.compile(info, comp)?; comp.is_init = false; Ok(Box::new(program::run::assign_to::AssignTo { - pos_in_src: self.pos_in_src, + pos_in_src: self.pos_in_src.clone(), is_init: true, source, target, })) } fn source_range(&self) -> SourceRange { - self.pos_in_src + self.pos_in_src.clone() } } diff --git a/mers_lib/src/program/parsed/tuple.rs b/mers_lib/src/program/parsed/tuple.rs index 6e675d6..9215e5f 100755 --- a/mers_lib/src/program/parsed/tuple.rs +++ b/mers_lib/src/program/parsed/tuple.rs @@ -21,7 +21,7 @@ impl MersStatement for Tuple { comp: CompInfo, ) -> Result, CheckError> { Ok(Box::new(program::run::tuple::Tuple { - pos_in_src: self.pos_in_src, + pos_in_src: self.pos_in_src.clone(), elems: self .elems .iter() @@ -30,6 +30,6 @@ impl MersStatement for Tuple { })) } fn source_range(&self) -> SourceRange { - self.pos_in_src + self.pos_in_src.clone() } } diff --git a/mers_lib/src/program/parsed/value.rs b/mers_lib/src/program/parsed/value.rs index dbb1f67..7a4788e 100755 --- a/mers_lib/src/program/parsed/value.rs +++ b/mers_lib/src/program/parsed/value.rs @@ -22,11 +22,11 @@ impl MersStatement for Value { _comp: CompInfo, ) -> Result, CheckError> { Ok(Box::new(program::run::value::Value { - pos_in_src: self.pos_in_src, + pos_in_src: self.pos_in_src.clone(), val: self.data.clone(), })) } fn source_range(&self) -> SourceRange { - self.pos_in_src + self.pos_in_src.clone() } } diff --git a/mers_lib/src/program/parsed/variable.rs b/mers_lib/src/program/parsed/variable.rs index 342494b..ef39bec 100755 --- a/mers_lib/src/program/parsed/variable.rs +++ b/mers_lib/src/program/parsed/variable.rs @@ -35,7 +35,7 @@ impl MersStatement for Variable { } } Ok(Box::new(program::run::variable::Variable { - pos_in_src: self.pos_in_src, + pos_in_src: self.pos_in_src.clone(), is_init: comp.is_init, is_ref_not_ignore: if comp.is_init { !init_and_ignore @@ -48,12 +48,15 @@ impl MersStatement for Variable { *v } else { return Err(CheckError::new() - .src(vec![(self.pos_in_src, Some(error_colors::UnknownVariable))]) + .src(vec![( + self.pos_in_src.clone(), + Some(error_colors::UnknownVariable), + )]) .msg(format!("No variable named '{}' found!", self.var))); }, })) } fn source_range(&self) -> SourceRange { - self.pos_in_src + self.pos_in_src.clone() } } diff --git a/mers_lib/src/program/run/as_type.rs b/mers_lib/src/program/run/as_type.rs index 3d02e30..dd2394a 100644 --- a/mers_lib/src/program/run/as_type.rs +++ b/mers_lib/src/program/run/as_type.rs @@ -32,7 +32,7 @@ impl MersStatement for AsType { crate::parsing::types::type_from_parsed(&self.as_type, info).map_err(|e| { CheckError::new() .src(vec![( - self.type_pos_in_src, + self.type_pos_in_src.clone(), Some(error_colors::BadTypeFromParsed), )]) .err(e) @@ -40,9 +40,9 @@ impl MersStatement for AsType { if !return_type.is_included_in(&as_type) { return Err(CheckError::new() .src(vec![ - (self.pos_in_src, None), + (self.pos_in_src.clone(), None), ( - self.type_pos_in_src, + self.type_pos_in_src.clone(), Some(error_colors::AsTypeTypeAnnotation), ), ( @@ -73,6 +73,6 @@ impl MersStatement for AsType { false } fn source_range(&self) -> SourceRange { - self.pos_in_src + self.pos_in_src.clone() } } diff --git a/mers_lib/src/program/run/assign_to.rs b/mers_lib/src/program/run/assign_to.rs index e52bf36..7557b16 100755 --- a/mers_lib/src/program/run/assign_to.rs +++ b/mers_lib/src/program/run/assign_to.rs @@ -30,7 +30,7 @@ impl MersStatement for AssignTo { Err(e) => { return Err(CheckError::new() .src(vec![ - (self.pos_in_src, None), + (self.pos_in_src.clone(), None), (self.target.source_range(), Some(error_colors::InitTo)), (self.source.source_range(), Some(error_colors::InitFrom)), ]) @@ -43,7 +43,7 @@ impl MersStatement for AssignTo { if !source.is_included_in(&t) { return Err(CheckError::new() .src(vec![ - (self.pos_in_src, None), + (self.pos_in_src.clone(), None), (self.target.source_range(), Some(error_colors::AssignTo)), (self.source.source_range(), Some(error_colors::AssignFrom)), ]) @@ -57,7 +57,7 @@ impl MersStatement for AssignTo { } else { return Err(CheckError::new() .src(vec![ - (self.pos_in_src, None), + (self.pos_in_src.clone(), None), ( self.target.source_range(), Some(error_colors::AssignTargetNonReference), @@ -81,6 +81,6 @@ impl MersStatement for AssignTo { false } fn source_range(&self) -> SourceRange { - self.pos_in_src + self.pos_in_src.clone() } } diff --git a/mers_lib/src/program/run/block.rs b/mers_lib/src/program/run/block.rs index 8765917..cd55409 100755 --- a/mers_lib/src/program/run/block.rs +++ b/mers_lib/src/program/run/block.rs @@ -36,6 +36,6 @@ impl MersStatement for Block { true } fn source_range(&self) -> SourceRange { - self.pos_in_src + self.pos_in_src.clone() } } diff --git a/mers_lib/src/program/run/chain.rs b/mers_lib/src/program/run/chain.rs index a67fdd0..6d307b5 100755 --- a/mers_lib/src/program/run/chain.rs +++ b/mers_lib/src/program/run/chain.rs @@ -37,10 +37,10 @@ impl MersStatement for Chain { match (func.0)(&arg) { Ok(t) => o.add(Arc::new(t)), Err(e) => { - return Err(if let Some(inner_src) = &self.as_part_of_include { + return Err(if let Some(_) = &self.as_part_of_include { CheckError::new() .src(vec![( - self.pos_in_src, + self.pos_in_src.clone(), Some(error_colors::HashIncludeErrorInIncludedFile), )]) .msg( @@ -48,11 +48,11 @@ impl MersStatement for Chain { .color(error_colors::HashIncludeErrorInIncludedFile) .to_string(), ) - .err_with_src(e, inner_src.clone()) + .err_with_diff_src(e) } else { CheckError::new() .src(vec![ - (self.pos_in_src, None), + (self.pos_in_src.clone(), None), ( self.first.source_range(), Some(error_colors::FunctionArgument), @@ -71,7 +71,7 @@ impl MersStatement for Chain { } else { return Err(CheckError::new() .src(vec![ - (self.pos_in_src, None), + (self.pos_in_src.clone(), None), ( self.chained.source_range(), Some(error_colors::ChainWithNonFunction), @@ -99,6 +99,6 @@ impl MersStatement for Chain { false } fn source_range(&self) -> SourceRange { - self.pos_in_src + self.pos_in_src.clone() } } diff --git a/mers_lib/src/program/run/custom_type.rs b/mers_lib/src/program/run/custom_type.rs index b462c83..e85f8c1 100644 --- a/mers_lib/src/program/run/custom_type.rs +++ b/mers_lib/src/program/run/custom_type.rs @@ -52,7 +52,7 @@ impl MersStatement for CustomType { false } fn source_range(&self) -> SourceRange { - self.pos_in_src + self.pos_in_src.clone() } } diff --git a/mers_lib/src/program/run/function.rs b/mers_lib/src/program/run/function.rs index c8d770a..8af9b7f 100755 --- a/mers_lib/src/program/run/function.rs +++ b/mers_lib/src/program/run/function.rs @@ -32,6 +32,6 @@ impl MersStatement for Function { true } fn source_range(&self) -> SourceRange { - self.pos_in_src + self.pos_in_src.clone() } } diff --git a/mers_lib/src/program/run/if.rs b/mers_lib/src/program/run/if.rs index 51406d9..e2d0994 100755 --- a/mers_lib/src/program/run/if.rs +++ b/mers_lib/src/program/run/if.rs @@ -30,7 +30,7 @@ impl MersStatement for If { if !cond_return_type.is_included_in(&data::bool::BoolT) { return Err(CheckError::new() .src(vec![ - (self.pos_in_src, None), + (self.pos_in_src.clone(), None), ( self.condition.source_range(), Some(error_colors::IfConditionNotBool), @@ -71,6 +71,6 @@ impl MersStatement for If { true } fn source_range(&self) -> SourceRange { - self.pos_in_src + self.pos_in_src.clone() } } diff --git a/mers_lib/src/program/run/tuple.rs b/mers_lib/src/program/run/tuple.rs index 6e0a8f9..93158cc 100755 --- a/mers_lib/src/program/run/tuple.rs +++ b/mers_lib/src/program/run/tuple.rs @@ -91,6 +91,6 @@ impl MersStatement for Tuple { false } fn source_range(&self) -> SourceRange { - self.pos_in_src + self.pos_in_src.clone() } } diff --git a/mers_lib/src/program/run/value.rs b/mers_lib/src/program/run/value.rs index 85f118b..8ca74a4 100755 --- a/mers_lib/src/program/run/value.rs +++ b/mers_lib/src/program/run/value.rs @@ -29,6 +29,6 @@ impl MersStatement for Value { self.val.clone() } fn source_range(&self) -> SourceRange { - self.pos_in_src + self.pos_in_src.clone() } } diff --git a/mers_lib/src/program/run/variable.rs b/mers_lib/src/program/run/variable.rs index c3198c8..5755315 100755 --- a/mers_lib/src/program/run/variable.rs +++ b/mers_lib/src/program/run/variable.rs @@ -77,6 +77,6 @@ impl MersStatement for Variable { } } fn source_range(&self) -> SourceRange { - self.pos_in_src + self.pos_in_src.clone() } }