assigning to tuples should work properly now

This commit is contained in:
Mark 2023-08-15 19:18:52 +02:00
parent 0119211d92
commit ae0e163595
23 changed files with 265 additions and 75 deletions

View File

@ -1,15 +1,25 @@
use crate::program::run::CheckError; use super::Data;
use super::{Data, MersType, Type}; pub fn assign(from: &Data, target: &Data) {
pub fn assign(from: Data, target: &Data) {
let target = target.get();
if let Some(r) = target if let Some(r) = target
.get()
.as_any() .as_any()
.downcast_ref::<crate::data::reference::Reference>() .downcast_ref::<crate::data::reference::Reference>()
{ {
*r.0.lock().unwrap().get_mut() = from.get().clone(); *r.0.lock().unwrap() = from.clone();
} else if let (Some(from), Some(target)) = (
from.get()
.as_any()
.downcast_ref::<crate::data::tuple::Tuple>(),
target
.get()
.as_any()
.downcast_ref::<crate::data::tuple::Tuple>(),
) {
for (from, target) in from.0.iter().zip(target.0.iter()) {
assign(from, target);
}
} else { } else {
todo!("assignment to non-reference") unreachable!("invalid assignment")
} }
} }

View File

@ -4,10 +4,7 @@ use std::{
sync::{Arc, Mutex}, sync::{Arc, Mutex},
}; };
use crate::program::{ use crate::program::run::{CheckError, CheckInfo, Info};
self,
run::{CheckError, CheckInfo, Info},
};
use super::{Data, MersData, MersType, Type}; use super::{Data, MersData, MersType, Type};

View File

@ -1,24 +1,85 @@
use std::sync::Arc; use std::sync::Arc;
use crate::program; use crate::program::{self, parsed::block::Block};
pub mod errors; pub mod errors;
pub mod statements; pub mod statements;
pub mod types; pub mod types;
pub fn parse(src: &mut Source) -> Result<Box<dyn program::parsed::MersStatement>, ()> { pub fn parse(src: &mut Source) -> Result<Box<dyn program::parsed::MersStatement>, ()> {
Ok(Box::new(statements::parse_block(src)?)) let pos_in_src = src.get_pos();
Ok(Box::new(Block {
pos_in_src,
statements: statements::parse_multiple(src, "")?,
}))
} }
pub struct Source { pub struct Source {
src_raw_len: usize,
src: String, src: String,
/// (start, content) of each comment, including start/end (//, \n, /* and */)
comments: Vec<(usize, String)>,
i: usize, i: usize,
sections: Vec<SectionMarker>, sections: Vec<SectionMarker>,
} }
impl Source { impl Source {
pub fn new(src: String) -> Self { pub fn new(source: String) -> Self {
let mut src = String::with_capacity(source.len());
let mut comment = (0, String::new());
let mut comments = Vec::new();
let mut chars = source.char_indices().peekable();
let mut in_comment = None;
loop {
if let Some((i, ch)) = chars.next() {
match in_comment {
Some(false) => {
comment.1.push(ch);
if ch == '\n' {
in_comment = None;
comments.push((
comment.0,
std::mem::replace(&mut comment.1, String::new()),
));
}
}
Some(true) => {
comment.1.push(ch);
if ch == '*' && matches!(chars.peek(), Some((_, '/'))) {
chars.next();
comment.1.push('/');
in_comment = None;
comments.push((
comment.0,
std::mem::replace(&mut comment.1, String::new()),
));
}
}
None => match ch {
'/' if matches!(chars.peek(), Some((_, '/'))) => {
chars.next();
in_comment = Some(false);
comment.0 = i;
comment.1.push('/');
comment.1.push('/');
}
'/' if matches!(chars.peek(), Some((_, '*'))) => {
chars.next();
in_comment = Some(true);
comment.0 = i;
comment.1.push('/');
comment.1.push('*');
}
_ => src.push(ch),
},
}
} else {
break;
}
}
Self { Self {
src_raw_len: source.len(),
src, src,
comments,
i: 0, i: 0,
sections: vec![], sections: vec![],
} }
@ -105,6 +166,37 @@ impl Source {
pub fn sections(&self) -> &Vec<SectionMarker> { pub fn sections(&self) -> &Vec<SectionMarker> {
&self.sections &self.sections
} }
pub fn format(&self, insertions: &Vec<(usize, bool, String)>) -> String {
let mut o = String::with_capacity(self.src_raw_len);
let mut insertions = insertions.iter().peekable();
let mut comments = self.comments.iter().peekable();
for (i, ch) in self.src.char_indices() {
let insert = if let Some((index, pre, _)) = insertions.peek() {
if *index <= i {
Some(*pre)
} else {
None
}
} else {
None
};
if let Some((index, comment)) = comments.peek() {
if *index == i {
comments.next();
o.push_str(comment);
}
}
if let Some(true) = insert {
o.push_str(&insertions.next().unwrap().2);
}
o.push(ch);
if let Some(false) = insert {
o.push_str(&insertions.next().unwrap().2);
}
}
o
}
} }
impl Drop for Source { impl Drop for Source {
@ -144,7 +236,7 @@ impl SectionMarker {
} }
} }
#[derive(Clone, Copy)] #[derive(Clone, Copy, Debug)]
pub struct SourcePos(usize); pub struct SourcePos(usize);
impl SourcePos { impl SourcePos {
fn diff(&self, rhs: &Self) -> usize { fn diff(&self, rhs: &Self) -> usize {

View File

@ -1,5 +1,3 @@
use std::sync::Arc;
use super::Source; use super::Source;
use crate::{ use crate::{
data::Data, data::Data,
@ -16,32 +14,43 @@ pub fn parse(src: &mut Source) -> Result<Option<Box<dyn program::parsed::MersSta
src.skip_whitespace(); src.skip_whitespace();
match src.peek_word() { match src.peek_word() {
":=" => { ":=" => {
let pos_in_src = src.get_pos();
src.next_word(); src.next_word();
first = Box::new(program::parsed::init_to::InitTo { first = Box::new(program::parsed::init_to::InitTo {
pos_in_src,
target: first, target: first,
source: parse(src)?.expect("todo"), source: parse(src)?.expect("todo"),
}); });
} }
"=" => { "=" => {
let pos_in_src = src.get_pos();
src.next_word(); src.next_word();
first = Box::new(program::parsed::assign_to::AssignTo { first = Box::new(program::parsed::assign_to::AssignTo {
pos_in_src,
target: first, target: first,
source: parse(src)?.expect("todo"), source: parse(src)?.expect("todo"),
}); });
} }
"->" => { "->" => {
let pos_in_src = src.get_pos();
src.next_word(); src.next_word();
first = Box::new(program::parsed::function::Function { first = Box::new(program::parsed::function::Function {
pos_in_src,
arg: first, arg: first,
run: parse(src)?.expect("err: bad eof, fn needs some statement"), run: parse(src)?.expect("err: bad eof, fn needs some statement"),
}); });
} }
_ => loop { _ => loop {
let pos_in_src = src.get_pos();
src.skip_whitespace(); src.skip_whitespace();
if let Some('.') = src.peek_char() { if let Some('.') = src.peek_char() {
src.next_char(); src.next_char();
let chained = parse_no_chain(src)?.expect("err: EOF instead of chain"); let chained = parse_no_chain(src)?.expect("err: EOF instead of chain");
first = Box::new(program::parsed::chain::Chain { first, chained }); first = Box::new(program::parsed::chain::Chain {
pos_in_src,
first,
chained,
});
} else { } else {
break; break;
} }
@ -52,23 +61,12 @@ pub fn parse(src: &mut Source) -> Result<Option<Box<dyn program::parsed::MersSta
} }
Ok(Some(first)) Ok(Some(first))
} }
/// Assumes the { has already been parsed pub fn parse_multiple(src: &mut Source, end: &str) -> Result<Vec<Box<dyn MersStatement>>, ()> {
pub fn parse_block(src: &mut Source) -> Result<program::parsed::block::Block, ()> {
Ok(program::parsed::block::Block {
statements: parse_multiple(src, '}')?,
})
}
pub fn parse_tuple(src: &mut Source) -> Result<program::parsed::tuple::Tuple, ()> {
Ok(program::parsed::tuple::Tuple {
elems: parse_multiple(src, ')')?,
})
}
pub fn parse_multiple(src: &mut Source, end: char) -> Result<Vec<Box<dyn MersStatement>>, ()> {
src.section_begin("block".to_string()); src.section_begin("block".to_string());
let mut statements = vec![]; let mut statements = vec![];
loop { loop {
src.skip_whitespace(); src.skip_whitespace();
if matches!(src.peek_char(), Some(e) if e == end) { 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)? {
@ -87,15 +85,24 @@ pub fn parse_no_chain(
src.skip_whitespace(); src.skip_whitespace();
match src.peek_char() { match src.peek_char() {
Some('{') => { Some('{') => {
let pos_in_src = src.get_pos();
src.next_char(); src.next_char();
return Ok(Some(Box::new(parse_block(src)?))); return Ok(Some(Box::new(program::parsed::block::Block {
pos_in_src,
statements: parse_multiple(src, "}")?,
})));
} }
Some('(') => { Some('(') => {
let pos_in_src = src.get_pos();
src.next_char(); src.next_char();
return Ok(Some(Box::new(parse_tuple(src)?))); return Ok(Some(Box::new(program::parsed::tuple::Tuple {
pos_in_src,
elems: parse_multiple(src, ")")?,
})));
} }
Some('"') => { Some('"') => {
src.section_begin("string literal".to_string()); src.section_begin("string literal".to_string());
let pos_in_src = src.get_pos();
src.next_char(); src.next_char();
let mut s = String::new(); let mut s = String::new();
loop { loop {
@ -118,16 +125,19 @@ pub fn parse_no_chain(
todo!("err: eof in string") todo!("err: eof in string")
} }
} }
return Ok(Some(Box::new(program::parsed::value::Value(Data::new( return Ok(Some(Box::new(program::parsed::value::Value {
crate::data::string::String(s), pos_in_src,
))))); data: Data::new(crate::data::string::String(s)),
})));
} }
_ => {} _ => {}
} }
let pos_in_src = src.get_pos();
Ok(Some(match src.next_word() { Ok(Some(match src.next_word() {
"if" => { "if" => {
src.section_begin("if".to_string()); src.section_begin("if".to_string());
Box::new(program::parsed::r#if::If { Box::new(program::parsed::r#if::If {
pos_in_src,
condition: parse(src)?.expect("err: EOF instead of condition"), condition: parse(src)?.expect("err: EOF instead of condition"),
on_true: parse(src)?.expect("err: EOF instead of on_true"), on_true: parse(src)?.expect("err: EOF instead of on_true"),
on_false: { on_false: {
@ -142,16 +152,14 @@ pub fn parse_no_chain(
}, },
}) })
} }
"switch" => { "true" => Box::new(program::parsed::value::Value {
src.section_begin("loop".to_string()); pos_in_src,
todo!() data: Data::new(crate::data::bool::Bool(true)),
} }),
"true" => Box::new(program::parsed::value::Value(Data::new( "false" => Box::new(program::parsed::value::Value {
crate::data::bool::Bool(true), pos_in_src,
))), data: Data::new(crate::data::bool::Bool(false)),
"false" => Box::new(program::parsed::value::Value(Data::new( }),
crate::data::bool::Bool(false),
))),
"" => return Ok(None), "" => return Ok(None),
o => { o => {
let o = o.to_string(); let o = o.to_string();
@ -161,28 +169,33 @@ pub fn parse_no_chain(
let here = src.get_pos(); let here = src.get_pos();
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(Data::new( Box::new(program::parsed::value::Value {
crate::data::float::Float(num), pos_in_src,
))) data: Data::new(crate::data::float::Float(num)),
})
} else { } else {
src.set_pos(here); src.set_pos(here);
Box::new(program::parsed::value::Value(Data::new( Box::new(program::parsed::value::Value {
crate::data::int::Int(n), pos_in_src,
))) data: Data::new(crate::data::int::Int(n)),
})
} }
} else { } else {
Box::new(program::parsed::value::Value(Data::new( Box::new(program::parsed::value::Value {
crate::data::int::Int(n), pos_in_src,
))) 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,
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,
is_ref: false, is_ref: false,
var: o.to_string(), var: o.to_string(),
}) })

View File

@ -1,7 +1,7 @@
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use crate::{ use crate::{
data::{self, Data, MersType, Type}, data::{self, Data, Type},
program::run::{CheckInfo, Info}, program::run::{CheckInfo, Info},
}; };
@ -18,7 +18,6 @@ impl Config {
info: Arc::new(Info::neverused()), info: Arc::new(Info::neverused()),
info_check: Arc::new(Mutex::new(CheckInfo::neverused())), info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
out: Arc::new(|a, i| { out: Arc::new(|a, i| {
dbg!(a);
let mut o = Type::empty(); let mut o = Type::empty();
for t in &a.types { for t in &a.types {
if let Some(t) = t.as_any().downcast_ref::<data::function::FunctionT>() { if let Some(t) = t.as_any().downcast_ref::<data::function::FunctionT>() {

View File

@ -1,9 +1,10 @@
use crate::program; use crate::{parsing::SourcePos, program};
use super::{CompInfo, MersStatement}; use super::{CompInfo, MersStatement};
#[derive(Debug)] #[derive(Debug)]
pub struct AssignTo { pub struct AssignTo {
pub pos_in_src: SourcePos,
pub target: Box<dyn MersStatement>, pub target: Box<dyn MersStatement>,
pub source: Box<dyn MersStatement>, pub source: Box<dyn MersStatement>,
} }
@ -18,6 +19,7 @@ impl MersStatement for AssignTo {
comp: CompInfo, comp: CompInfo,
) -> Result<Box<dyn program::run::MersStatement>, String> { ) -> Result<Box<dyn program::run::MersStatement>, String> {
Ok(Box::new(program::run::assign_to::AssignTo { Ok(Box::new(program::run::assign_to::AssignTo {
pos_in_src: self.pos_in_src,
is_init: false, is_init: false,
target: self.target.compile(info, comp)?, target: self.target.compile(info, comp)?,
source: self.source.compile(info, comp)?, source: self.source.compile(info, comp)?,

View File

@ -1,9 +1,10 @@
use crate::{info, program}; use crate::{info, parsing::SourcePos, program};
use super::{CompInfo, MersStatement}; use super::{CompInfo, MersStatement};
#[derive(Debug)] #[derive(Debug)]
pub struct Block { pub struct Block {
pub pos_in_src: SourcePos,
pub statements: Vec<Box<dyn MersStatement>>, pub statements: Vec<Box<dyn MersStatement>>,
} }
impl MersStatement for Block { impl MersStatement for Block {
@ -16,6 +17,7 @@ impl MersStatement for Block {
comp: CompInfo, comp: CompInfo,
) -> Result<Box<dyn program::run::MersStatement>, String> { ) -> Result<Box<dyn program::run::MersStatement>, String> {
Ok(Box::new(program::run::block::Block { Ok(Box::new(program::run::block::Block {
pos_in_src: self.pos_in_src,
statements: self statements: self
.statements .statements
.iter() .iter()

View File

@ -1,9 +1,11 @@
use crate::parsing::SourcePos;
use crate::{info, program}; use crate::{info, program};
use super::{CompInfo, MersStatement}; use super::{CompInfo, MersStatement};
#[derive(Debug)] #[derive(Debug)]
pub struct Chain { pub struct Chain {
pub pos_in_src: SourcePos,
pub first: Box<dyn MersStatement>, pub first: Box<dyn MersStatement>,
pub chained: Box<dyn MersStatement>, pub chained: Box<dyn MersStatement>,
} }
@ -17,6 +19,7 @@ impl MersStatement for Chain {
comp: CompInfo, comp: CompInfo,
) -> Result<Box<dyn program::run::MersStatement>, String> { ) -> Result<Box<dyn program::run::MersStatement>, String> {
Ok(Box::new(program::run::chain::Chain { Ok(Box::new(program::run::chain::Chain {
pos_in_src: self.pos_in_src,
first: self.first.compile(info, comp)?, first: self.first.compile(info, comp)?,
chained: self.chained.compile(info, comp)?, chained: self.chained.compile(info, comp)?,
})) }))

View File

@ -1,3 +1,4 @@
use crate::parsing::SourcePos;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use crate::{ use crate::{
@ -9,6 +10,7 @@ use super::{CompInfo, MersStatement};
#[derive(Debug)] #[derive(Debug)]
pub struct Function { pub struct Function {
pub pos_in_src: SourcePos,
pub arg: Box<dyn MersStatement>, pub arg: Box<dyn MersStatement>,
pub run: Box<dyn MersStatement>, pub run: Box<dyn MersStatement>,
} }
@ -30,6 +32,7 @@ impl MersStatement for Function {
let arg2 = Arc::clone(&arg_target); let arg2 = Arc::clone(&arg_target);
let run2 = Arc::clone(&run); let run2 = Arc::clone(&run);
Ok(Box::new(program::run::function::Function { Ok(Box::new(program::run::function::Function {
pos_in_src: self.pos_in_src,
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())),
@ -38,7 +41,7 @@ impl MersStatement for Function {
Ok(run2.check(i, None)?) Ok(run2.check(i, None)?)
}), }),
run: Arc::new(move |arg, info| { run: Arc::new(move |arg, info| {
data::defs::assign(arg, &arg_target.run(info)); data::defs::assign(&arg, &arg_target.run(info));
run.run(info) run.run(info)
}), }),
}, },

View File

@ -1,9 +1,10 @@
use crate::program; use crate::{parsing::SourcePos, program};
use super::{CompInfo, MersStatement}; use super::{CompInfo, MersStatement};
#[derive(Debug)] #[derive(Debug)]
pub struct If { pub struct If {
pub pos_in_src: SourcePos,
pub condition: Box<dyn MersStatement>, pub condition: Box<dyn MersStatement>,
pub on_true: Box<dyn MersStatement>, pub on_true: Box<dyn MersStatement>,
pub on_false: Option<Box<dyn MersStatement>>, pub on_false: Option<Box<dyn MersStatement>>,
@ -19,6 +20,7 @@ impl MersStatement for If {
comp: CompInfo, comp: CompInfo,
) -> Result<Box<dyn program::run::MersStatement>, String> { ) -> Result<Box<dyn program::run::MersStatement>, String> {
Ok(Box::new(program::run::r#if::If { Ok(Box::new(program::run::r#if::If {
pos_in_src: self.pos_in_src,
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 {

View File

@ -1,9 +1,11 @@
use crate::parsing::SourcePos;
use crate::program; use crate::program;
use super::{CompInfo, MersStatement}; use super::{CompInfo, MersStatement};
#[derive(Debug)] #[derive(Debug)]
pub struct InitTo { pub struct InitTo {
pub pos_in_src: SourcePos,
pub target: Box<dyn MersStatement>, pub target: Box<dyn MersStatement>,
pub source: Box<dyn MersStatement>, pub source: Box<dyn MersStatement>,
} }
@ -22,6 +24,7 @@ impl MersStatement for InitTo {
comp.is_init = false; comp.is_init = false;
let source = self.source.compile(info, comp)?; let source = self.source.compile(info, comp)?;
Ok(Box::new(program::run::assign_to::AssignTo { Ok(Box::new(program::run::assign_to::AssignTo {
pos_in_src: self.pos_in_src,
is_init: true, is_init: true,
target, target,
source, source,

View File

@ -1,9 +1,10 @@
use crate::{info, program}; use crate::{info, parsing::SourcePos, program};
use super::{CompInfo, MersStatement}; use super::{CompInfo, MersStatement};
#[derive(Debug)] #[derive(Debug)]
pub struct Tuple { pub struct Tuple {
pub pos_in_src: SourcePos,
pub elems: Vec<Box<dyn MersStatement>>, pub elems: Vec<Box<dyn MersStatement>>,
} }
impl MersStatement for Tuple { impl MersStatement for Tuple {
@ -16,6 +17,7 @@ impl MersStatement for Tuple {
comp: CompInfo, comp: CompInfo,
) -> Result<Box<dyn program::run::MersStatement>, String> { ) -> Result<Box<dyn program::run::MersStatement>, String> {
Ok(Box::new(program::run::tuple::Tuple { Ok(Box::new(program::run::tuple::Tuple {
pos_in_src: self.pos_in_src,
elems: self elems: self
.elems .elems
.iter() .iter()

View File

@ -1,9 +1,13 @@
use crate::parsing::SourcePos;
use crate::{data::Data, program}; use crate::{data::Data, program};
use super::{CompInfo, MersStatement}; use super::{CompInfo, MersStatement};
#[derive(Debug)] #[derive(Debug)]
pub struct Value(pub Data); pub struct Value {
pub pos_in_src: SourcePos,
pub data: Data,
}
impl MersStatement for Value { impl MersStatement for Value {
fn has_scope(&self) -> bool { fn has_scope(&self) -> bool {
@ -15,7 +19,8 @@ impl MersStatement for Value {
_comp: CompInfo, _comp: CompInfo,
) -> Result<Box<dyn program::run::MersStatement>, String> { ) -> Result<Box<dyn program::run::MersStatement>, String> {
Ok(Box::new(program::run::value::Value { Ok(Box::new(program::run::value::Value {
val: self.0.clone(), pos_in_src: self.pos_in_src,
val: self.data.clone(),
})) }))
} }
} }

View File

@ -1,9 +1,10 @@
use crate::{info::Local, program}; use crate::{info::Local, parsing::SourcePos, program};
use super::{CompInfo, MersStatement}; use super::{CompInfo, MersStatement};
#[derive(Debug)] #[derive(Debug)]
pub struct Variable { pub struct Variable {
pub pos_in_src: SourcePos,
pub is_ref: bool, pub is_ref: bool,
pub var: String, pub var: String,
} }
@ -27,6 +28,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,
is_init: comp.is_init, is_init: comp.is_init,
is_ref: comp.is_init || self.is_ref, is_ref: comp.is_init || self.is_ref,
var: if let Some(v) = info.get_var(&self.var) { var: if let Some(v) = info.get_var(&self.var) {

View File

@ -1,9 +1,13 @@
use crate::data::{self, Type}; use crate::{
data::{self, Type},
parsing::SourcePos,
};
use super::{CheckError, CheckInfo, MersStatement}; use super::{CheckError, CheckInfo, MersStatement};
#[derive(Debug)] #[derive(Debug)]
pub struct AssignTo { pub struct AssignTo {
pub pos_in_src: SourcePos,
pub is_init: bool, pub is_init: bool,
pub target: Box<dyn MersStatement>, pub target: Box<dyn MersStatement>,
pub source: Box<dyn MersStatement>, pub source: Box<dyn MersStatement>,
@ -27,10 +31,13 @@ impl MersStatement for AssignTo {
fn run_custom(&self, info: &mut super::Info) -> crate::data::Data { fn run_custom(&self, info: &mut super::Info) -> crate::data::Data {
let source = self.source.run(info); let source = self.source.run(info);
let target = self.target.run(info); let target = self.target.run(info);
data::defs::assign(source, &target); data::defs::assign(&source, &target);
target target
} }
fn has_scope(&self) -> bool { fn has_scope(&self) -> bool {
false false
} }
fn pos_in_src(&self) -> &SourcePos {
&self.pos_in_src
}
} }

View File

@ -1,9 +1,10 @@
use crate::data::Type; use crate::{data::Type, parsing::SourcePos};
use super::{CheckError, MersStatement}; use super::{CheckError, MersStatement};
#[derive(Debug)] #[derive(Debug)]
pub struct Block { pub struct Block {
pub pos_in_src: SourcePos,
pub statements: Vec<Box<dyn MersStatement>>, pub statements: Vec<Box<dyn MersStatement>>,
} }
impl MersStatement for Block { impl MersStatement for Block {
@ -31,4 +32,7 @@ impl MersStatement for Block {
fn has_scope(&self) -> bool { fn has_scope(&self) -> bool {
true true
} }
fn pos_in_src(&self) -> &SourcePos {
&self.pos_in_src
}
} }

View File

@ -1,11 +1,15 @@
use std::sync::Arc; use std::sync::Arc;
use crate::data::{Data, Type}; use crate::{
data::{Data, Type},
parsing::SourcePos,
};
use super::{CheckError, MersStatement}; use super::{CheckError, MersStatement};
#[derive(Debug)] #[derive(Debug)]
pub struct Chain { pub struct Chain {
pub pos_in_src: SourcePos,
pub first: Box<dyn MersStatement>, pub first: Box<dyn MersStatement>,
pub chained: Box<dyn MersStatement>, pub chained: Box<dyn MersStatement>,
} }
@ -54,4 +58,7 @@ impl MersStatement for Chain {
fn has_scope(&self) -> bool { fn has_scope(&self) -> bool {
false false
} }
fn pos_in_src(&self) -> &SourcePos {
&self.pos_in_src
}
} }

View File

@ -1,11 +1,15 @@
use std::sync::Arc; use std::sync::Arc;
use crate::data::{self, Data, MersData, Type}; use crate::{
data::{self, Data, MersData, Type},
parsing::SourcePos,
};
use super::{CheckError, MersStatement}; use super::{CheckError, MersStatement};
#[derive(Debug)] #[derive(Debug)]
pub struct Function { pub struct Function {
pub pos_in_src: SourcePos,
pub func_no_info: data::function::Function, pub func_no_info: data::function::Function,
} }
@ -29,4 +33,7 @@ impl MersStatement for Function {
fn has_scope(&self) -> bool { fn has_scope(&self) -> bool {
true true
} }
fn pos_in_src(&self) -> &SourcePos {
&self.pos_in_src
}
} }

View File

@ -1,11 +1,15 @@
use std::sync::Arc; use std::sync::Arc;
use crate::data::{self, Data, MersType, Type}; use crate::{
data::{self, Data, MersType, Type},
parsing::SourcePos,
};
use super::{CheckError, MersStatement}; use super::{CheckError, MersStatement};
#[derive(Debug)] #[derive(Debug)]
pub struct If { pub struct If {
pub pos_in_src: SourcePos,
pub condition: Box<dyn MersStatement>, pub condition: Box<dyn MersStatement>,
pub on_true: Box<dyn MersStatement>, pub on_true: Box<dyn MersStatement>,
pub on_false: Option<Box<dyn MersStatement>>, pub on_false: Option<Box<dyn MersStatement>>,
@ -55,4 +59,7 @@ impl MersStatement for If {
fn has_scope(&self) -> bool { fn has_scope(&self) -> bool {
true true
} }
fn pos_in_src(&self) -> &SourcePos {
&self.pos_in_src
}
} }

View File

@ -6,6 +6,7 @@ use std::{
use crate::{ use crate::{
data::{self, Data, Type}, data::{self, Data, Type},
info, info,
parsing::SourcePos,
}; };
#[cfg(feature = "run")] #[cfg(feature = "run")]
@ -34,6 +35,7 @@ pub trait MersStatement: Debug + Send + Sync {
fn run_custom(&self, info: &mut Info) -> Data; fn run_custom(&self, info: &mut Info) -> Data;
/// if true, local variables etc. will be contained inside their own scope. /// if true, local variables etc. will be contained inside their own scope.
fn has_scope(&self) -> bool; fn has_scope(&self) -> bool;
fn pos_in_src(&self) -> &SourcePos;
fn check(&self, info: &mut CheckInfo, assign: Option<&Type>) -> Result<Type, CheckError> { fn check(&self, info: &mut CheckInfo, assign: Option<&Type>) -> Result<Type, CheckError> {
if self.has_scope() { if self.has_scope() {
info.create_scope(); info.create_scope();

View File

@ -1,11 +1,15 @@
use std::sync::Arc; use std::sync::Arc;
use crate::data::{self, tuple::TupleT, Data, Type}; use crate::{
data::{self, tuple::TupleT, Data, Type},
parsing::SourcePos,
};
use super::{CheckError, MersStatement}; use super::{CheckError, MersStatement};
#[derive(Debug)] #[derive(Debug)]
pub struct Tuple { pub struct Tuple {
pub pos_in_src: SourcePos,
pub elems: Vec<Box<dyn MersStatement>>, pub elems: Vec<Box<dyn MersStatement>>,
} }
impl MersStatement for Tuple { impl MersStatement for Tuple {
@ -31,7 +35,7 @@ impl MersStatement for Tuple {
} }
} else { } else {
return Err(CheckError( return Err(CheckError(
"can't init to statement type Tuple with value type {t}, which is part of {init_to} - only tuples can be assigned to tuples".to_string(), format!("can't init to statement type Tuple with value type {t}, which is part of {init_to} - only tuples can be assigned to tuples"),
)); ));
} }
} }
@ -64,4 +68,7 @@ impl MersStatement for Tuple {
fn has_scope(&self) -> bool { fn has_scope(&self) -> bool {
false false
} }
fn pos_in_src(&self) -> &SourcePos {
&self.pos_in_src
}
} }

View File

@ -1,9 +1,13 @@
use crate::data::{Data, Type}; use crate::{
data::{Data, Type},
parsing::SourcePos,
};
use super::{CheckError, MersStatement}; use super::{CheckError, MersStatement};
#[derive(Debug)] #[derive(Debug)]
pub struct Value { pub struct Value {
pub pos_in_src: SourcePos,
pub val: Data, pub val: Data,
} }
@ -24,4 +28,7 @@ impl MersStatement for Value {
fn run_custom(&self, _info: &mut super::Info) -> Data { fn run_custom(&self, _info: &mut super::Info) -> Data {
self.val.clone() self.val.clone()
} }
fn pos_in_src(&self) -> &SourcePos {
&self.pos_in_src
}
} }

View File

@ -1,11 +1,15 @@
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use crate::data::{self, Data, Type}; use crate::{
data::{self, Data, Type},
parsing::SourcePos,
};
use super::MersStatement; use super::MersStatement;
#[derive(Debug)] #[derive(Debug)]
pub struct Variable { pub struct Variable {
pub pos_in_src: SourcePos,
pub is_init: bool, pub is_init: bool,
pub is_ref: bool, pub is_ref: bool,
pub var: (usize, usize), pub var: (usize, usize),
@ -55,4 +59,7 @@ impl MersStatement for Variable {
.clone() .clone()
} }
} }
fn pos_in_src(&self) -> &SourcePos {
&self.pos_in_src
}
} }