fix bug where error would reference wrong file

This commit is contained in:
Mark 2023-11-24 13:19:38 +01:00
parent 12af47d18a
commit 0a9eea2045
29 changed files with 173 additions and 194 deletions

View File

@ -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, process::exit}; use std::{fmt::Display, path::PathBuf, process::exit, sync::Arc};
mod cfg_globals; mod cfg_globals;
@ -78,10 +78,11 @@ fn main() {
}, },
Command::Exec { source } => Source::new_from_string(source), 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, Ok(v) => v,
Err(e) => { Err(e) => {
eprintln!("{}", e.display(&source).show_comments(!args.hide_comments)); eprintln!("{}", e.display().show_comments(!args.hide_comments));
exit(20); exit(20);
} }
}; };
@ -90,7 +91,7 @@ fn main() {
let run = match parsed.compile(&mut info_parsed, Default::default()) { let run = match parsed.compile(&mut info_parsed, Default::default()) {
Ok(v) => v, Ok(v) => v,
Err(e) => { Err(e) => {
eprintln!("{}", e.display(&source).show_comments(!args.hide_comments)); eprintln!("{}", e.display().show_comments(!args.hide_comments));
exit(24); exit(24);
} }
}; };
@ -104,7 +105,7 @@ fn main() {
let return_type = match run.check(&mut info_check, None) { let return_type = match run.check(&mut info_check, None) {
Ok(v) => v, Ok(v) => v,
Err(e) => { Err(e) => {
eprint!("{}", e.display(&source).show_comments(!args.hide_comments)); eprint!("{}", e.display().show_comments(!args.hide_comments));
exit(28); exit(28);
} }
}; };

View File

@ -1,4 +1,7 @@
use std::fmt::{Debug, Display}; use std::{
fmt::{Debug, Display},
sync::Arc,
};
use colored::Colorize; use colored::Colorize;
use line_span::LineSpans; use line_span::LineSpans;
@ -14,14 +17,16 @@ impl SourcePos {
} }
} }
#[derive(Clone, Copy, Debug)] #[derive(Clone, Debug)]
pub struct SourceRange { pub struct SourceRange {
in_file: Arc<Source>,
start: SourcePos, start: SourcePos,
end: SourcePos, end: SourcePos,
} }
impl From<(SourcePos, SourcePos)> for SourceRange { impl From<(SourcePos, SourcePos, &Arc<Source>)> for SourceRange {
fn from(value: (SourcePos, SourcePos)) -> Self { fn from(value: (SourcePos, SourcePos, &Arc<Source>)) -> Self {
SourceRange { SourceRange {
in_file: Arc::clone(value.2),
start: value.0, start: value.0,
end: value.1, end: value.1,
} }
@ -74,7 +79,7 @@ pub mod error_colors {
enum CheckErrorComponent { enum CheckErrorComponent {
Message(String), Message(String),
Error(CheckError), Error(CheckError),
ErrorWithSrc(CheckErrorWithSrc), ErrorWithDifferentSource(CheckError),
Source(Vec<(SourceRange, Option<colored::Color>)>), Source(Vec<(SourceRange, Option<colored::Color>)>),
} }
#[derive(Clone)] #[derive(Clone)]
@ -88,13 +93,6 @@ pub struct CheckErrorHRConfig {
#[cfg(feature = "parse")] #[cfg(feature = "parse")]
pub struct CheckErrorDisplay<'a> { pub struct CheckErrorDisplay<'a> {
e: &'a CheckError, 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, pub show_comments: bool,
} }
#[cfg(feature = "parse")] #[cfg(feature = "parse")]
@ -105,33 +103,10 @@ impl<'a> CheckErrorDisplay<'a> {
} }
} }
#[cfg(feature = "parse")] #[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<'_> { impl Display for CheckErrorDisplay<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.e.human_readable( self.e.human_readable(
f, 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 { &CheckErrorHRConfig {
indent_start: String::new(), indent_start: String::new(),
indent_default: String::new(), indent_default: String::new(),
@ -155,29 +130,16 @@ impl CheckError {
pub(crate) fn err(self, e: Self) -> Self { pub(crate) fn err(self, e: Self) -> Self {
self.add(CheckErrorComponent::Error(e)) self.add(CheckErrorComponent::Error(e))
} }
pub(crate) fn err_with_src(self, e: CheckError, src: Source) -> Self { pub(crate) fn err_with_diff_src(self, e: CheckError) -> Self {
self.add(CheckErrorComponent::ErrorWithSrc(CheckErrorWithSrc { self.add(CheckErrorComponent::ErrorWithDifferentSource(e))
e,
src,
show_comments: true,
}))
} }
pub(crate) fn src(self, s: Vec<(SourceRange, Option<colored::Color>)>) -> Self { pub(crate) fn src(self, s: Vec<(SourceRange, Option<colored::Color>)>) -> Self {
self.add(CheckErrorComponent::Source(s)) self.add(CheckErrorComponent::Source(s))
} }
#[cfg(feature = "parse")] #[cfg(feature = "parse")]
pub fn display<'a>(&'a self, src: &'a Source) -> CheckErrorDisplay<'a> { pub fn display<'a>(&'a self) -> CheckErrorDisplay<'a> {
CheckErrorDisplay { CheckErrorDisplay {
e: self, 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, show_comments: true,
} }
} }
@ -186,7 +148,6 @@ impl CheckError {
fn human_readable( fn human_readable(
&self, &self,
f: &mut std::fmt::Formatter<'_>, f: &mut std::fmt::Formatter<'_>,
src: Option<&Source>,
cfg: &CheckErrorHRConfig, cfg: &CheckErrorHRConfig,
) -> std::fmt::Result { ) -> std::fmt::Result {
use crate::parsing::SourceFrom; use crate::parsing::SourceFrom;
@ -211,18 +172,18 @@ impl CheckError {
cfg.indent_start.push_str(""); cfg.indent_start.push_str("");
cfg.indent_default.push_str(""); cfg.indent_default.push_str("");
cfg.indent_end.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(); let mut cfg = cfg.clone();
cfg.indent_start.push_str(&"".bright_yellow().to_string()); cfg.indent_start.push_str(&"".bright_yellow().to_string());
cfg.indent_default cfg.indent_default
.push_str(&"".bright_yellow().to_string()); .push_str(&"".bright_yellow().to_string());
cfg.indent_end.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) => { 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 start = highlights.iter().map(|v| v.0.start.pos()).min();
let end = highlights.iter().map(|v| v.0.end.pos()).max(); let end = highlights.iter().map(|v| v.0.end.pos()).max();
if let (Some(start_in_line), Some(end_in_line)) = (start, end) { if let (Some(start_in_line), Some(end_in_line)) = (start, end) {
@ -370,6 +331,6 @@ impl Debug for CheckError {
} }
impl Display for CheckError { impl Display for CheckError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.display_no_src()) write!(f, "{}", self.display())
} }
} }

View File

@ -8,11 +8,14 @@ use crate::{
pub mod statements; pub mod statements;
pub mod types; pub mod types;
pub fn parse(src: &mut Source) -> Result<Box<dyn program::parsed::MersStatement>, CheckError> { pub fn parse(
src: &mut Source,
srca: &Arc<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, srca, "")?;
let block = Block { 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, statements,
}; };
Ok(Box::new(block)) Ok(Box::new(block))

View File

@ -1,4 +1,4 @@
use std::path::PathBuf; use std::{path::PathBuf, sync::Arc};
use super::{Source, SourcePos}; use super::{Source, SourcePos};
use crate::{ use crate::{
@ -12,6 +12,7 @@ use crate::{
pub fn parse( pub fn parse(
src: &mut Source, src: &mut Source,
srca: &Arc<Source>,
) -> Result<Option<Box<dyn program::parsed::MersStatement>>, CheckError> { ) -> Result<Option<Box<dyn program::parsed::MersStatement>>, CheckError> {
src.section_begin("statement".to_string()); src.section_begin("statement".to_string());
src.skip_whitespace(); src.skip_whitespace();
@ -37,11 +38,11 @@ pub fn parse(
if src.peek_word() == ":=" { if src.peek_word() == ":=" {
src.next_word(); src.next_word();
// [[name] := statement] // [[name] := statement]
let statement = match parse(src) { let statement = match parse(src, srca) {
Ok(Some(v)) => v, Ok(Some(v)) => v,
Ok(None) => { Ok(None) => {
return Err(CheckError::new() 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"))) .msg(format!("EOF after `[...]` type annotation")))
} }
Err(e) => return Err(e), Err(e) => return Err(e),
@ -52,14 +53,14 @@ pub fn parse(
))); )));
} }
Box::new(program::parsed::custom_type::CustomType { 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, name,
source: Err(statement), source: Err(statement),
}) })
} else { } else {
// [[name] type] // [[name] type]
src.skip_whitespace(); src.skip_whitespace();
let as_type = super::types::parse_type(src)?; let as_type = super::types::parse_type(src, srca)?;
src.skip_whitespace(); src.skip_whitespace();
if !matches!(src.next_char(), Some(']')) { if !matches!(src.next_char(), Some(']')) {
return Err(CheckError::new().msg(format!( return Err(CheckError::new().msg(format!(
@ -67,7 +68,7 @@ pub fn parse(
))); )));
} }
Box::new(program::parsed::custom_type::CustomType { 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, name,
source: Ok(as_type), source: Ok(as_type),
}) })
@ -76,28 +77,28 @@ pub fn parse(
// [type] statement // [type] statement
src.skip_whitespace(); src.skip_whitespace();
let type_pos_in_src = src.get_pos(); let type_pos_in_src = src.get_pos();
let as_type = super::types::parse_type(src)?; let as_type = super::types::parse_type(src, srca)?;
let type_pos_in_src = (type_pos_in_src, src.get_pos()).into(); let type_pos_in_src = (type_pos_in_src, src.get_pos(), srca).into();
src.skip_whitespace(); src.skip_whitespace();
if !matches!(src.next_char(), Some(']')) { if !matches!(src.next_char(), Some(']')) {
return Err(CheckError::new() return Err(CheckError::new()
.src(vec![( .src(vec![(
(pos_in_src, src.get_pos()).into(), (pos_in_src, src.get_pos(), srca).into(),
Some(error_colors::TypeAnnotationNoClosingBracket), Some(error_colors::TypeAnnotationNoClosingBracket),
)]) )])
.msg(format!("Missing closing bracket ']' after type annotation"))); .msg(format!("Missing closing bracket ']' after type annotation")));
} }
let statement = match parse(src) { let statement = match parse(src, srca) {
Ok(Some(v)) => v, Ok(Some(v)) => v,
Ok(None) => { Ok(None) => {
return Err(CheckError::new() 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"))) .msg(format!("EOF after `[...]` type annotation")))
} }
Err(e) => return Err(e), Err(e) => return Err(e),
}; };
Box::new(AsType { 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, statement,
as_type, as_type,
type_pos_in_src, 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 s
} else { } else {
return Ok(None); return Ok(None);
@ -116,13 +117,13 @@ pub fn parse(
":=" => { ":=" => {
let pos_in_src = src.get_pos(); let pos_in_src = src.get_pos();
src.next_word(); src.next_word();
let source = parse(src)?.ok_or_else(|| { let source = parse(src, srca)?.ok_or_else(|| {
CheckError::new() 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 `:=`")) .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(), srca).into(),
target: first, target: first,
source, source,
}); });
@ -130,13 +131,13 @@ pub fn parse(
"=" => { "=" => {
let pos_in_src = src.get_pos(); let pos_in_src = src.get_pos();
src.next_word(); src.next_word();
let source = parse(src)?.ok_or_else(|| { let source = parse(src, srca)?.ok_or_else(|| {
CheckError::new() 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 `=`")) .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(), srca).into(),
target: first, target: first,
source, source,
}); });
@ -144,17 +145,17 @@ pub fn parse(
"->" => { "->" => {
let pos_in_src = src.get_pos(); let pos_in_src = src.get_pos();
src.next_word(); src.next_word();
let run = match parse(src) { let run = match parse(src, srca) {
Ok(Some(v)) => v, Ok(Some(v)) => v,
Ok(None) => { Ok(None) => {
return Err(CheckError::new() 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 `->`"))) .msg(format!("EOF after `->`")))
} }
Err(e) => return Err(e), Err(e) => return Err(e),
}; };
first = Box::new(program::parsed::function::Function { 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, arg: first,
run, run,
}); });
@ -164,11 +165,11 @@ pub fn parse(
let dot_in_src = src.get_pos(); let dot_in_src = src.get_pos();
if let Some('.') = src.peek_char() { if let Some('.') = src.peek_char() {
src.next_char(); src.next_char();
let chained = match parse_no_chain(src) { let chained = match parse_no_chain(src, srca) {
Ok(Some(v)) => v, Ok(Some(v)) => v,
Ok(None) => { Ok(None) => {
return Err(CheckError::new() 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 `.`"))) .msg(format!("EOF after `.`")))
} }
Err(e) => return Err(e), Err(e) => return Err(e),
@ -176,14 +177,14 @@ pub fn parse(
// allow a.f(b, c) syntax (but not f(a, b, c)) // allow a.f(b, c) syntax (but not f(a, b, c))
if let Some('(') = src.peek_char() { if let Some('(') = src.peek_char() {
src.next_char(); src.next_char();
let elems = parse_multiple(src, ")")?; let elems = parse_multiple(src, srca, ")")?;
first = Box::new(program::parsed::tuple::Tuple { 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(), elems: [first].into_iter().chain(elems).collect(),
}); });
} }
first = Box::new(program::parsed::chain::Chain { 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, first,
chained, chained,
}); });
@ -201,6 +202,7 @@ pub fn parse(
} }
pub fn parse_multiple( pub fn parse_multiple(
src: &mut Source, src: &mut Source,
srca: &Arc<Source>,
end: &str, end: &str,
) -> Result<Vec<Box<dyn MersStatement>>, CheckError> { ) -> Result<Vec<Box<dyn MersStatement>>, CheckError> {
src.section_begin("block".to_string()); 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)) { if src.peek_char().is_some_and(|ch| end.contains(ch)) {
src.next_char(); src.next_char();
break; break;
} else if let Some(s) = parse(src)? { } else if let Some(s) = parse(src, srca)? {
statements.push(s); statements.push(s);
} else { } else {
// EOF // EOF
@ -221,6 +223,7 @@ pub fn parse_multiple(
} }
pub fn parse_no_chain( pub fn parse_no_chain(
src: &mut Source, src: &mut Source,
srca: &Arc<Source>,
) -> Result<Option<Box<dyn program::parsed::MersStatement>>, CheckError> { ) -> Result<Option<Box<dyn program::parsed::MersStatement>>, CheckError> {
src.skip_whitespace(); src.skip_whitespace();
src.section_begin("statement no chain".to_string()); src.section_begin("statement no chain".to_string());
@ -230,14 +233,14 @@ pub fn parse_no_chain(
src.next_char(); src.next_char();
if src.peek_char().is_none() { if src.peek_char().is_none() {
return Err(CheckError::new() 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 #"))); .msg(format!("EOF after #")));
} }
if src.peek_char().is_some_and(|ch| ch.is_whitespace()) { if src.peek_char().is_some_and(|ch| ch.is_whitespace()) {
src.skip_whitespace(); src.skip_whitespace();
return Err(CheckError::new() return Err(CheckError::new()
.src(vec![( .src(vec![(
(pos_in_src, src.get_pos()).into(), (pos_in_src, src.get_pos(), srca).into(),
Some(error_colors::WhitespaceAfterHashtag), Some(error_colors::WhitespaceAfterHashtag),
)]) )])
.msg(format!("Whitespace after #"))); .msg(format!("Whitespace after #")));
@ -248,18 +251,17 @@ pub fn parse_no_chain(
src.skip_whitespace(); src.skip_whitespace();
let string_in_src = src.get_pos(); let string_in_src = src.get_pos();
if src.next_char() == Some('"') { 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)) { match Source::new_from_file(PathBuf::from(&file_path)) {
Ok(mut inner_src) => { Ok(mut inner_src) => {
let inner_srca = Arc::new(inner_src.clone());
return Ok(Some(Box::new( return Ok(Some(Box::new(
program::parsed::include_mers::IncludeMers { program::parsed::include_mers::IncludeMers {
pos_in_src: (pos_in_src, src.get_pos()).into(), pos_in_src: (pos_in_src, src.get_pos(), srca).into(),
include: match super::parse(&mut inner_src) { include: match super::parse(&mut inner_src, &inner_srca) {
Ok(v) => v, Ok(v) => v,
Err(e) => { Err(e) => {
return Err( return Err(CheckError::new().err_with_diff_src(e))
CheckError::new().err_with_src(e, inner_src)
)
} }
}, },
inner_src, inner_src,
@ -269,9 +271,9 @@ pub fn parse_no_chain(
Err(e) => { Err(e) => {
return Err(CheckError::new() return Err(CheckError::new()
.src(vec![ .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), Some(error_colors::HashIncludeCantLoadFile),
), ),
]) ])
@ -281,8 +283,8 @@ pub fn parse_no_chain(
} else { } else {
return Err(CheckError::new() return Err(CheckError::new()
.src(vec![ .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(), Some(error_colors::HashIncludeNotAString)), ((string_in_src, src.get_pos(), srca).into(), Some(error_colors::HashIncludeNotAString)),
]) ])
.msg(format!( .msg(format!(
"#include must be followed by a string literal like \"file.mers\" (\" expected)." "#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}"); let msg = format!("Unknown #statement: {other}");
return Err(CheckError::new() return Err(CheckError::new()
.src(vec![( .src(vec![(
(pos_in_src, src.get_pos()).into(), (pos_in_src, src.get_pos(), srca).into(),
Some(error_colors::HashUnknown), Some(error_colors::HashUnknown),
)]) )])
.msg(msg)); .msg(msg));
@ -303,18 +305,18 @@ pub fn parse_no_chain(
Some('{') => { Some('{') => {
let pos_in_src = src.get_pos(); let pos_in_src = src.get_pos();
src.next_char(); src.next_char();
let statements = parse_multiple(src, "}")?; let statements = parse_multiple(src, srca, "}")?;
return Ok(Some(Box::new(program::parsed::block::Block { 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, statements,
}))); })));
} }
Some('(') => { Some('(') => {
let pos_in_src = src.get_pos(); let pos_in_src = src.get_pos();
src.next_char(); src.next_char();
let elems = parse_multiple(src, ")")?; let elems = parse_multiple(src, srca, ")")?;
return Ok(Some(Box::new(program::parsed::tuple::Tuple { 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, elems,
}))); })));
} }
@ -322,9 +324,9 @@ 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 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 { 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)), data: Data::new(crate::data::string::String(s)),
}))); })));
} }
@ -335,20 +337,20 @@ pub fn parse_no_chain(
"if" => { "if" => {
src.section_begin("if".to_string()); src.section_begin("if".to_string());
src.skip_whitespace(); src.skip_whitespace();
let condition = match parse(src) { let condition = match parse(src, srca) {
Ok(Some(v)) => v, Ok(Some(v)) => v,
Ok(None) => { Ok(None) => {
return Err(CheckError::new() 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`"))) .msg(format!("EOF in `if`")))
} }
Err(e) => return Err(e), Err(e) => return Err(e),
}; };
let on_true = match parse(src) { let on_true = match parse(src, srca) {
Ok(Some(v)) => v, Ok(Some(v)) => v,
Ok(None) => { Ok(None) => {
return Err(CheckError::new() 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 <condition>`"))) .msg(format!("EOF after `if <condition>`")))
} }
Err(e) => return Err(e), Err(e) => return Err(e),
@ -358,11 +360,11 @@ pub fn parse_no_chain(
if src.peek_word() == "else" { if src.peek_word() == "else" {
src.section_begin("else".to_string()); src.section_begin("else".to_string());
src.next_word(); src.next_word();
Some(match parse(src) { Some(match parse(src, srca) {
Ok(Some(v)) => v, Ok(Some(v)) => v,
Ok(None) => { Ok(None) => {
return Err(CheckError::new() 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`"))) .msg(format!("EOF after `else`")))
} }
Err(e) => return Err(e), Err(e) => return Err(e),
@ -372,18 +374,18 @@ pub fn parse_no_chain(
} }
}; };
Box::new(program::parsed::r#if::If { 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, condition,
on_true, on_true,
on_false, on_false,
}) })
} }
"true" => Box::new(program::parsed::value::Value { "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)), data: Data::new(crate::data::bool::Bool(true)),
}), }),
"false" => Box::new(program::parsed::value::Value { "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)), data: Data::new(crate::data::bool::Bool(false)),
}), }),
"" => return Ok(None), "" => return Ok(None),
@ -396,32 +398,32 @@ pub fn parse_no_chain(
src.next_char(); src.next_char();
if let Ok(num) = format!("{o}.{}", src.next_word()).parse() { if let Ok(num) = format!("{o}.{}", src.next_word()).parse() {
Box::new(program::parsed::value::Value { 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)), data: Data::new(crate::data::float::Float(num)),
}) })
} else { } else {
src.set_pos(here); src.set_pos(here);
Box::new(program::parsed::value::Value { 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)), data: Data::new(crate::data::int::Int(n)),
}) })
} }
} else { } else {
Box::new(program::parsed::value::Value { 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)), data: Data::new(crate::data::int::Int(n)),
}) })
} }
} else { } else {
if let Some('&') = o.chars().next() { if let Some('&') = o.chars().next() {
Box::new(program::parsed::variable::Variable { 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, is_ref: true,
var: o[1..].to_string(), var: o[1..].to_string(),
}) })
} else { } else {
Box::new(program::parsed::variable::Variable { 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, is_ref: false,
var: o.to_string(), var: o.to_string(),
}) })
@ -432,11 +434,16 @@ pub fn parse_no_chain(
} }
/// expects to be called *after* a " character is consumed from src /// expects to be called *after* a " character is consumed from src
pub fn parse_string(src: &mut Source, double_quote: SourcePos) -> Result<String, CheckError> { pub fn parse_string(
parse_string_custom_end(src, double_quote, '"', '"') src: &mut Source,
srca: &Arc<Source>,
double_quote: SourcePos,
) -> Result<String, CheckError> {
parse_string_custom_end(src, srca, double_quote, '"', '"')
} }
pub fn parse_string_custom_end( pub fn parse_string_custom_end(
src: &mut Source, src: &mut Source,
srca: &Arc<Source>,
opening: SourcePos, opening: SourcePos,
opening_char: char, opening_char: char,
closing_char: char, closing_char: char,
@ -456,7 +463,7 @@ pub fn parse_string_custom_end(
Some(o) => { Some(o) => {
return Err(CheckError::new() return Err(CheckError::new()
.src(vec![( .src(vec![(
(backslash_in_src, src.get_pos()).into(), (backslash_in_src, src.get_pos(), srca).into(),
Some(error_colors::BackslashEscapeUnknown), Some(error_colors::BackslashEscapeUnknown),
)]) )])
.msg(format!("unknown backslash escape '\\{o}'"))); .msg(format!("unknown backslash escape '\\{o}'")));
@ -464,7 +471,7 @@ pub fn parse_string_custom_end(
None => { None => {
return Err(CheckError::new() return Err(CheckError::new()
.src(vec![( .src(vec![(
(backslash_in_src, src.get_pos()).into(), (backslash_in_src, src.get_pos(), srca).into(),
Some(error_colors::BackslashEscapeEOF), Some(error_colors::BackslashEscapeEOF),
)]) )])
.msg(format!("EOF in backslash escape"))); .msg(format!("EOF in backslash escape")));
@ -478,7 +485,7 @@ pub fn parse_string_custom_end(
} else { } else {
return Err(CheckError::new() return Err(CheckError::new()
.src(vec![( .src(vec![(
(opening, src.get_pos()).into(), (opening, src.get_pos(), srca).into(),
Some(error_colors::StringEOF), Some(error_colors::StringEOF),
)]) )])
.msg(format!( .msg(format!(

View File

@ -16,7 +16,7 @@ pub enum ParsedType {
TypeWithInfo(String, String), TypeWithInfo(String, String),
} }
pub fn parse_single_type(src: &mut Source) -> Result<ParsedType, CheckError> { pub fn parse_single_type(src: &mut Source, srca: &Arc<Source>) -> Result<ParsedType, CheckError> {
src.section_begin("parse single type".to_string()); src.section_begin("parse single type".to_string());
src.skip_whitespace(); src.skip_whitespace();
Ok(match src.peek_char() { Ok(match src.peek_char() {
@ -25,7 +25,7 @@ pub fn parse_single_type(src: &mut Source) -> Result<ParsedType, CheckError> {
src.next_char(); src.next_char();
if let Some('{') = src.peek_char() { if let Some('{') = src.peek_char() {
src.next_char(); src.next_char();
let types = parse_type(src)?; let types = parse_type(src, srca)?;
let nc = src.next_char(); let nc = src.next_char();
if !matches!(nc, Some('}')) { if !matches!(nc, Some('}')) {
let nc = if let Some(nc) = nc { let nc = if let Some(nc) = nc {
@ -39,7 +39,7 @@ pub fn parse_single_type(src: &mut Source) -> Result<ParsedType, CheckError> {
} }
ParsedType::Reference(types) ParsedType::Reference(types)
} else { } else {
ParsedType::Reference(vec![parse_single_type(src)?]) ParsedType::Reference(vec![parse_single_type(src, srca)?])
} }
} }
// Tuple // Tuple
@ -53,7 +53,7 @@ pub fn parse_single_type(src: &mut Source) -> Result<ParsedType, CheckError> {
// empty tuple, don't even start the loop // empty tuple, don't even start the loop
} else { } else {
loop { loop {
inner.push(parse_type(src)?); inner.push(parse_type(src, srca)?);
match src.peek_char() { match src.peek_char() {
Some(')') => { Some(')') => {
src.next_char(); src.next_char();
@ -67,9 +67,9 @@ pub fn parse_single_type(src: &mut Source) -> Result<ParsedType, CheckError> {
src.next_char(); src.next_char();
return Err(CheckError::new() return Err(CheckError::new()
.src(vec![ .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), Some(error_colors::BadCharInTupleType),
), ),
]) ])
@ -90,7 +90,7 @@ pub fn parse_single_type(src: &mut Source) -> Result<ParsedType, CheckError> {
src.next_char(); src.next_char();
ParsedType::TypeWithInfo( ParsedType::TypeWithInfo(
t, t,
super::statements::parse_string_custom_end(src, pos, '<', '>')?, super::statements::parse_string_custom_end(src, srca, pos, '<', '>')?,
) )
} else { } else {
ParsedType::Type(t) ParsedType::Type(t)
@ -100,11 +100,11 @@ pub fn parse_single_type(src: &mut Source) -> Result<ParsedType, CheckError> {
}) })
} }
pub fn parse_type(src: &mut Source) -> Result<Vec<ParsedType>, CheckError> { pub fn parse_type(src: &mut Source, srca: &Arc<Source>) -> Result<Vec<ParsedType>, CheckError> {
src.section_begin("parse single type".to_string()); src.section_begin("parse single type".to_string());
let mut types = vec![]; let mut types = vec![];
loop { loop {
types.push(parse_single_type(src)?); types.push(parse_single_type(src, srca)?);
src.skip_whitespace(); src.skip_whitespace();
if let Some('/') = src.peek_char() { if let Some('/') = src.peek_char() {
src.next_char(); src.next_char();

View File

@ -23,7 +23,9 @@ impl Config {
// TODO: Type with generics // TODO: Type with generics
self.add_type("List".to_string(), self.add_type("List".to_string(),
Err(Arc::new(|s, i| { 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)?)))}))) Ok(Arc::new(ListT(crate::parsing::types::type_from_parsed(&t, i)?)))})))
.add_var( .add_var(
"pop".to_string(), "pop".to_string(),

View File

@ -21,7 +21,9 @@ impl Config {
self.add_type( self.add_type(
"Thread".to_string(), "Thread".to_string(),
Err(Arc::new(|s, i| { 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)?))) Ok(Arc::new(ThreadT(crate::parsing::types::type_from_parsed(&t, i)?)))
})), })),
) )

View File

@ -25,14 +25,14 @@ impl MersStatement for AsType {
comp: CompInfo, comp: CompInfo,
) -> Result<Box<dyn program::run::MersStatement>, CheckError> { ) -> Result<Box<dyn program::run::MersStatement>, CheckError> {
Ok(Box::new(program::run::as_type::AsType { 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)?, statement: self.statement.compile(info, comp)?,
as_type: self.as_type.clone(), 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, expand_type: self.expand_type,
})) }))
} }
fn source_range(&self) -> SourceRange { fn source_range(&self) -> SourceRange {
self.pos_in_src self.pos_in_src.clone()
} }
} }

View File

@ -22,13 +22,13 @@ impl MersStatement for AssignTo {
comp: CompInfo, comp: CompInfo,
) -> Result<Box<dyn program::run::MersStatement>, CheckError> { ) -> 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.clone(),
is_init: false, is_init: false,
source: self.source.compile(info, comp)?, source: self.source.compile(info, comp)?,
target: self.target.compile(info, comp)?, target: self.target.compile(info, comp)?,
})) }))
} }
fn source_range(&self) -> SourceRange { fn source_range(&self) -> SourceRange {
self.pos_in_src self.pos_in_src.clone()
} }
} }

View File

@ -21,7 +21,7 @@ impl MersStatement for Block {
comp: CompInfo, comp: CompInfo,
) -> Result<Box<dyn program::run::MersStatement>, CheckError> { ) -> 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.clone(),
statements: self statements: self
.statements .statements
.iter() .iter()
@ -30,6 +30,6 @@ impl MersStatement for Block {
})) }))
} }
fn source_range(&self) -> SourceRange { fn source_range(&self) -> SourceRange {
self.pos_in_src self.pos_in_src.clone()
} }
} }

View File

@ -21,13 +21,13 @@ impl MersStatement for Chain {
comp: CompInfo, comp: CompInfo,
) -> Result<Box<dyn program::run::MersStatement>, CheckError> { ) -> 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.clone(),
first: self.first.compile(info, comp)?, first: self.first.compile(info, comp)?,
chained: self.chained.compile(info, comp)?, chained: self.chained.compile(info, comp)?,
as_part_of_include: None, as_part_of_include: None,
})) }))
} }
fn source_range(&self) -> SourceRange { fn source_range(&self) -> SourceRange {
self.pos_in_src self.pos_in_src.clone()
} }
} }

View File

@ -23,7 +23,7 @@ impl MersStatement for CustomType {
Err(s) => Err(s.compile(info, comp)?), Err(s) => Err(s.compile(info, comp)?),
}; };
Ok(Box::new(crate::program::run::custom_type::CustomType { 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(), name: self.name.clone(),
source: Box::new(move |ci| match &src { source: Box::new(move |ci| match &src {
Ok(parsed) => Ok(Ok(Arc::new(type_from_parsed(parsed, ci)?))), Ok(parsed) => Ok(Ok(Arc::new(type_from_parsed(parsed, ci)?))),
@ -35,7 +35,7 @@ impl MersStatement for CustomType {
false false
} }
fn source_range(&self) -> SourceRange { fn source_range(&self) -> SourceRange {
self.pos_in_src self.pos_in_src.clone()
} }
} }

View File

@ -32,7 +32,7 @@ impl MersStatement for Function {
let arg2: Arc<Box<dyn crate::program::run::MersStatement>> = Arc::clone(&arg_target); let arg2: Arc<Box<dyn crate::program::run::MersStatement>> = Arc::clone(&arg_target);
let run2: Arc<Box<dyn crate::program::run::MersStatement>> = Arc::clone(&run); let run2: Arc<Box<dyn crate::program::run::MersStatement>> = Arc::clone(&run);
Ok(Box::new(program::run::function::Function { 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 { func_no_info: data::function::Function {
info: Arc::new(program::run::Info::neverused()), info: Arc::new(program::run::Info::neverused()),
info_check: Arc::new(Mutex::new(CheckInfo::neverused())), info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
@ -48,6 +48,6 @@ impl MersStatement for Function {
})) }))
} }
fn source_range(&self) -> SourceRange { fn source_range(&self) -> SourceRange {
self.pos_in_src self.pos_in_src.clone()
} }
} }

View File

@ -23,7 +23,7 @@ impl MersStatement for If {
comp: CompInfo, comp: CompInfo,
) -> Result<Box<dyn program::run::MersStatement>, CheckError> { ) -> 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.clone(),
condition: self.condition.compile(info, comp)?, condition: self.condition.compile(info, comp)?,
on_true: self.on_true.compile(info, comp)?, on_true: self.on_true.compile(info, comp)?,
on_false: if let Some(v) = &self.on_false { on_false: if let Some(v) = &self.on_false {
@ -34,6 +34,6 @@ impl MersStatement for If {
})) }))
} }
fn source_range(&self) -> SourceRange { fn source_range(&self) -> SourceRange {
self.pos_in_src self.pos_in_src.clone()
} }
} }

View File

@ -33,7 +33,7 @@ impl MersStatement for IncludeMers {
Err(e) => { Err(e) => {
return Err(CheckError::new() return Err(CheckError::new()
.src(vec![( .src(vec![(
self.pos_in_src, self.pos_in_src.clone(),
Some(error_colors::HashIncludeErrorInIncludedFile), Some(error_colors::HashIncludeErrorInIncludedFile),
)]) )])
.msg( .msg(
@ -41,18 +41,18 @@ impl MersStatement for IncludeMers {
.color(error_colors::HashIncludeErrorInIncludedFile) .color(error_colors::HashIncludeErrorInIncludedFile)
.to_string(), .to_string(),
) )
.err_with_src(e, self.inner_src.clone())) .err_with_diff_src(e))
} }
}; };
let compiled2 = Arc::clone(&compiled); let compiled2 = Arc::clone(&compiled);
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.clone(),
first: Box::new(program::run::value::Value { 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(), val: Data::empty_tuple(),
}), }),
chained: Box::new(program::run::function::Function { 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 { func_no_info: data::function::Function {
info: Arc::new(info::Info::neverused()), info: Arc::new(info::Info::neverused()),
info_check: Arc::new(Mutex::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 { fn source_range(&self) -> SourceRange {
self.pos_in_src self.pos_in_src.clone()
} }
} }

View File

@ -28,13 +28,13 @@ impl MersStatement for InitTo {
let target = self.target.compile(info, comp)?; let target = self.target.compile(info, comp)?;
comp.is_init = false; comp.is_init = false;
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.clone(),
is_init: true, is_init: true,
source, source,
target, target,
})) }))
} }
fn source_range(&self) -> SourceRange { fn source_range(&self) -> SourceRange {
self.pos_in_src self.pos_in_src.clone()
} }
} }

View File

@ -21,7 +21,7 @@ impl MersStatement for Tuple {
comp: CompInfo, comp: CompInfo,
) -> Result<Box<dyn program::run::MersStatement>, CheckError> { ) -> 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.clone(),
elems: self elems: self
.elems .elems
.iter() .iter()
@ -30,6 +30,6 @@ impl MersStatement for Tuple {
})) }))
} }
fn source_range(&self) -> SourceRange { fn source_range(&self) -> SourceRange {
self.pos_in_src self.pos_in_src.clone()
} }
} }

View File

@ -22,11 +22,11 @@ impl MersStatement for Value {
_comp: CompInfo, _comp: CompInfo,
) -> Result<Box<dyn program::run::MersStatement>, CheckError> { ) -> 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.clone(),
val: self.data.clone(), val: self.data.clone(),
})) }))
} }
fn source_range(&self) -> SourceRange { fn source_range(&self) -> SourceRange {
self.pos_in_src self.pos_in_src.clone()
} }
} }

View File

@ -35,7 +35,7 @@ impl MersStatement for Variable {
} }
} }
Ok(Box::new(program::run::variable::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_init: comp.is_init,
is_ref_not_ignore: if comp.is_init { is_ref_not_ignore: if comp.is_init {
!init_and_ignore !init_and_ignore
@ -48,12 +48,15 @@ impl MersStatement for Variable {
*v *v
} else { } else {
return Err(CheckError::new() 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))); .msg(format!("No variable named '{}' found!", self.var)));
}, },
})) }))
} }
fn source_range(&self) -> SourceRange { fn source_range(&self) -> SourceRange {
self.pos_in_src self.pos_in_src.clone()
} }
} }

View File

@ -32,7 +32,7 @@ impl MersStatement for AsType {
crate::parsing::types::type_from_parsed(&self.as_type, info).map_err(|e| { crate::parsing::types::type_from_parsed(&self.as_type, info).map_err(|e| {
CheckError::new() CheckError::new()
.src(vec![( .src(vec![(
self.type_pos_in_src, self.type_pos_in_src.clone(),
Some(error_colors::BadTypeFromParsed), Some(error_colors::BadTypeFromParsed),
)]) )])
.err(e) .err(e)
@ -40,9 +40,9 @@ impl MersStatement for AsType {
if !return_type.is_included_in(&as_type) { if !return_type.is_included_in(&as_type) {
return Err(CheckError::new() return Err(CheckError::new()
.src(vec![ .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), Some(error_colors::AsTypeTypeAnnotation),
), ),
( (
@ -73,6 +73,6 @@ impl MersStatement for AsType {
false false
} }
fn source_range(&self) -> SourceRange { fn source_range(&self) -> SourceRange {
self.pos_in_src self.pos_in_src.clone()
} }
} }

View File

@ -30,7 +30,7 @@ impl MersStatement for AssignTo {
Err(e) => { Err(e) => {
return Err(CheckError::new() return Err(CheckError::new()
.src(vec![ .src(vec![
(self.pos_in_src, None), (self.pos_in_src.clone(), None),
(self.target.source_range(), Some(error_colors::InitTo)), (self.target.source_range(), Some(error_colors::InitTo)),
(self.source.source_range(), Some(error_colors::InitFrom)), (self.source.source_range(), Some(error_colors::InitFrom)),
]) ])
@ -43,7 +43,7 @@ impl MersStatement for AssignTo {
if !source.is_included_in(&t) { if !source.is_included_in(&t) {
return Err(CheckError::new() return Err(CheckError::new()
.src(vec![ .src(vec![
(self.pos_in_src, None), (self.pos_in_src.clone(), None),
(self.target.source_range(), Some(error_colors::AssignTo)), (self.target.source_range(), Some(error_colors::AssignTo)),
(self.source.source_range(), Some(error_colors::AssignFrom)), (self.source.source_range(), Some(error_colors::AssignFrom)),
]) ])
@ -57,7 +57,7 @@ impl MersStatement for AssignTo {
} else { } else {
return Err(CheckError::new() return Err(CheckError::new()
.src(vec![ .src(vec![
(self.pos_in_src, None), (self.pos_in_src.clone(), None),
( (
self.target.source_range(), self.target.source_range(),
Some(error_colors::AssignTargetNonReference), Some(error_colors::AssignTargetNonReference),
@ -81,6 +81,6 @@ impl MersStatement for AssignTo {
false false
} }
fn source_range(&self) -> SourceRange { fn source_range(&self) -> SourceRange {
self.pos_in_src self.pos_in_src.clone()
} }
} }

View File

@ -36,6 +36,6 @@ impl MersStatement for Block {
true true
} }
fn source_range(&self) -> SourceRange { fn source_range(&self) -> SourceRange {
self.pos_in_src self.pos_in_src.clone()
} }
} }

View File

@ -37,10 +37,10 @@ impl MersStatement for Chain {
match (func.0)(&arg) { match (func.0)(&arg) {
Ok(t) => o.add(Arc::new(t)), Ok(t) => o.add(Arc::new(t)),
Err(e) => { 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() CheckError::new()
.src(vec![( .src(vec![(
self.pos_in_src, self.pos_in_src.clone(),
Some(error_colors::HashIncludeErrorInIncludedFile), Some(error_colors::HashIncludeErrorInIncludedFile),
)]) )])
.msg( .msg(
@ -48,11 +48,11 @@ impl MersStatement for Chain {
.color(error_colors::HashIncludeErrorInIncludedFile) .color(error_colors::HashIncludeErrorInIncludedFile)
.to_string(), .to_string(),
) )
.err_with_src(e, inner_src.clone()) .err_with_diff_src(e)
} else { } else {
CheckError::new() CheckError::new()
.src(vec![ .src(vec![
(self.pos_in_src, None), (self.pos_in_src.clone(), None),
( (
self.first.source_range(), self.first.source_range(),
Some(error_colors::FunctionArgument), Some(error_colors::FunctionArgument),
@ -71,7 +71,7 @@ impl MersStatement for Chain {
} else { } else {
return Err(CheckError::new() return Err(CheckError::new()
.src(vec![ .src(vec![
(self.pos_in_src, None), (self.pos_in_src.clone(), None),
( (
self.chained.source_range(), self.chained.source_range(),
Some(error_colors::ChainWithNonFunction), Some(error_colors::ChainWithNonFunction),
@ -99,6 +99,6 @@ impl MersStatement for Chain {
false false
} }
fn source_range(&self) -> SourceRange { fn source_range(&self) -> SourceRange {
self.pos_in_src self.pos_in_src.clone()
} }
} }

View File

@ -52,7 +52,7 @@ impl MersStatement for CustomType {
false false
} }
fn source_range(&self) -> SourceRange { fn source_range(&self) -> SourceRange {
self.pos_in_src self.pos_in_src.clone()
} }
} }

View File

@ -32,6 +32,6 @@ impl MersStatement for Function {
true true
} }
fn source_range(&self) -> SourceRange { fn source_range(&self) -> SourceRange {
self.pos_in_src self.pos_in_src.clone()
} }
} }

View File

@ -30,7 +30,7 @@ impl MersStatement for If {
if !cond_return_type.is_included_in(&data::bool::BoolT) { if !cond_return_type.is_included_in(&data::bool::BoolT) {
return Err(CheckError::new() return Err(CheckError::new()
.src(vec![ .src(vec![
(self.pos_in_src, None), (self.pos_in_src.clone(), None),
( (
self.condition.source_range(), self.condition.source_range(),
Some(error_colors::IfConditionNotBool), Some(error_colors::IfConditionNotBool),
@ -71,6 +71,6 @@ impl MersStatement for If {
true true
} }
fn source_range(&self) -> SourceRange { fn source_range(&self) -> SourceRange {
self.pos_in_src self.pos_in_src.clone()
} }
} }

View File

@ -91,6 +91,6 @@ impl MersStatement for Tuple {
false false
} }
fn source_range(&self) -> SourceRange { fn source_range(&self) -> SourceRange {
self.pos_in_src self.pos_in_src.clone()
} }
} }

View File

@ -29,6 +29,6 @@ impl MersStatement for Value {
self.val.clone() self.val.clone()
} }
fn source_range(&self) -> SourceRange { fn source_range(&self) -> SourceRange {
self.pos_in_src self.pos_in_src.clone()
} }
} }

View File

@ -77,6 +77,6 @@ impl MersStatement for Variable {
} }
} }
fn source_range(&self) -> SourceRange { fn source_range(&self) -> SourceRange {
self.pos_in_src self.pos_in_src.clone()
} }
} }