mirror of
https://github.com/Dummi26/mers.git
synced 2025-03-10 14:13:52 +01:00
fix bug where error would reference wrong file
This commit is contained in:
parent
12af47d18a
commit
0a9eea2045
@ -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);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -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())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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))
|
||||||
|
@ -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!(
|
||||||
|
@ -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();
|
||||||
|
@ -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(),
|
||||||
|
@ -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)?)))
|
||||||
})),
|
})),
|
||||||
)
|
)
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user