Type no longer implements MersType

This commit is contained in:
Mark 2024-04-16 13:38:50 +02:00
parent 4fc9441bd5
commit 2742112b09
33 changed files with 109 additions and 127 deletions

View File

@ -11,7 +11,7 @@ repository = "https://github.com/Dummi26/mers"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
mers_lib = "0.8.1" # mers_lib = "0.8.1"
# mers_lib = { path = "../mers_lib" } mers_lib = { path = "../mers_lib" }
clap = { version = "4.3.19", features = ["derive"] } clap = { version = "4.3.19", features = ["derive"] }
colored = "2.1.0" colored = "2.1.0"

View File

@ -1,7 +1,7 @@
use std::sync::Arc; use std::sync::Arc;
use mers_lib::{ use mers_lib::{
data::{Data, MersType, Type}, data::{Data, Type},
errors::CheckError, errors::CheckError,
prelude_compile::{parse, Config, Source}, prelude_compile::{parse, Config, Source},
program::parsed::CompInfo, program::parsed::CompInfo,

View File

@ -1,7 +1,7 @@
use std::sync::Arc; use std::sync::Arc;
use mers_lib::{ use mers_lib::{
data::{self, Data, MersType, Type}, data::{self, Data, Type},
errors::CheckError, errors::CheckError,
prelude_compile::{parse, Config, Source}, prelude_compile::{parse, Config, Source},
program::parsed::CompInfo, program::parsed::CompInfo,
@ -34,7 +34,7 @@ fn run(src: String) -> Result<(), CheckError> {
|arg| { |arg| {
// If the input is a string, the output is a string. // If the input is a string, the output is a string.
// Otherwise, the function is used incorrectly. // Otherwise, the function is used incorrectly.
if arg.is_included_in(&data::string::StringT) { if arg.is_included_in_single(&data::string::StringT) {
Ok(Type::new(data::string::StringT)) Ok(Type::new(data::string::StringT))
} else { } else {
// Wrong argument type. The code won't compile and this is the error message shown to the user. // Wrong argument type. The code won't compile and this is the error message shown to the user.

View File

@ -36,7 +36,7 @@ impl MersType for BoolT {
fn is_same_type_as(&self, other: &dyn MersType) -> bool { fn is_same_type_as(&self, other: &dyn MersType) -> bool {
other.as_any().downcast_ref::<Self>().is_some() other.as_any().downcast_ref::<Self>().is_some()
} }
fn is_included_in_single(&self, target: &dyn MersType) -> bool { fn is_included_in(&self, target: &dyn MersType) -> bool {
self.is_same_type_as(target) self.is_same_type_as(target)
} }
fn subtypes(&self, acc: &mut Type) { fn subtypes(&self, acc: &mut Type) {

View File

@ -36,7 +36,7 @@ impl MersType for ByteT {
fn is_same_type_as(&self, other: &dyn MersType) -> bool { fn is_same_type_as(&self, other: &dyn MersType) -> bool {
other.as_any().downcast_ref::<Self>().is_some() other.as_any().downcast_ref::<Self>().is_some()
} }
fn is_included_in_single(&self, target: &dyn MersType) -> bool { fn is_included_in(&self, target: &dyn MersType) -> bool {
self.is_same_type_as(target) self.is_same_type_as(target)
} }
fn subtypes(&self, acc: &mut Type) { fn subtypes(&self, acc: &mut Type) {

View File

@ -36,7 +36,7 @@ impl MersType for FloatT {
fn is_same_type_as(&self, other: &dyn MersType) -> bool { fn is_same_type_as(&self, other: &dyn MersType) -> bool {
other.as_any().downcast_ref::<Self>().is_some() other.as_any().downcast_ref::<Self>().is_some()
} }
fn is_included_in_single(&self, target: &dyn MersType) -> bool { fn is_included_in(&self, target: &dyn MersType) -> bool {
self.is_same_type_as(target) self.is_same_type_as(target)
} }
fn subtypes(&self, acc: &mut Type) { fn subtypes(&self, acc: &mut Type) {

View File

@ -121,7 +121,7 @@ impl MersType for FunctionT {
if t.0.len() > 1 { if t.0.len() > 1 {
return None; return None;
} else if let Some(t) = t.0.first() { } else if let Some(t) = t.0.first() {
out.add(Arc::new(t.clone())) out.add_all(&t);
} }
} else { } else {
return None; return None;
@ -153,7 +153,7 @@ impl MersType for FunctionT {
false false
} }
} }
fn is_included_in_single(&self, target: &dyn MersType) -> bool { fn is_included_in(&self, target: &dyn MersType) -> bool {
if let Some(target) = target.as_any().downcast_ref::<Self>() { if let Some(target) = target.as_any().downcast_ref::<Self>() {
if let Err(s) = &target.0 { if let Err(s) = &target.0 {
s.iter() s.iter()

View File

@ -36,7 +36,7 @@ impl MersType for IntT {
fn is_same_type_as(&self, other: &dyn MersType) -> bool { fn is_same_type_as(&self, other: &dyn MersType) -> bool {
other.as_any().downcast_ref::<Self>().is_some() other.as_any().downcast_ref::<Self>().is_some()
} }
fn is_included_in_single(&self, target: &dyn MersType) -> bool { fn is_included_in(&self, target: &dyn MersType) -> bool {
self.is_same_type_as(target) self.is_same_type_as(target)
} }
fn subtypes(&self, acc: &mut Type) { fn subtypes(&self, acc: &mut Type) {

View File

@ -50,17 +50,7 @@ pub trait MersType: Any + Debug + Display + Send + Sync {
/// this *must* return false. /// this *must* return false.
fn is_same_type_as(&self, other: &dyn MersType) -> bool; fn is_same_type_as(&self, other: &dyn MersType) -> bool;
/// This doesn't handle the case where target is Type (is_included_in handles it) /// This doesn't handle the case where target is Type (is_included_in handles it)
fn is_included_in_single(&self, target: &dyn MersType) -> bool; fn is_included_in(&self, target: &dyn MersType) -> bool;
fn is_included_in(&self, target: &dyn MersType) -> bool {
if let Some(target) = target.as_any().downcast_ref::<Type>() {
target
.types
.iter()
.any(|t| self.is_included_in_single(t.as_ref()))
} else {
self.is_included_in_single(target)
}
}
/// Returns all types that can result from the use of this type. /// Returns all types that can result from the use of this type.
/// Usually, this is just `acc.add(Arc::new(self.clone()))` /// Usually, this is just `acc.add(Arc::new(self.clone()))`
/// but if there exists one or more inner types, this becomes interesting: /// but if there exists one or more inner types, this becomes interesting:
@ -268,7 +258,7 @@ impl Type {
.filter(|v| v.0.len() == 1) .filter(|v| v.0.len() == 1)
.and_then(|v| v.0.get(0)) .and_then(|v| v.0.get(0))
{ {
o.add(Arc::new(t.clone())); o.add_all(&t);
} else { } else {
return None; return None;
} }
@ -287,7 +277,7 @@ impl Type {
.and_then(|v| v.0.get(0)) .and_then(|v| v.0.get(0))
{ {
nothing = false; nothing = false;
o.add(Arc::new(t.clone())); o.add_all(&t);
} }
} }
if nothing { if nothing {
@ -315,7 +305,7 @@ impl Type {
let mut o = Self::empty(); let mut o = Self::empty();
for t in &self.types { for t in &self.types {
if let Some(t) = t.is_reference_to() { if let Some(t) = t.is_reference_to() {
o.add(Arc::new(t.clone())); o.add_all(&t);
} else { } else {
return None; return None;
} }
@ -334,47 +324,45 @@ impl Type {
// then repeat with the second type if possible (here not, but for longer tuples, probably?) // then repeat with the second type if possible (here not, but for longer tuples, probably?)
// merge the last existing type in all the collections until we reach the first type again or the last types aren't equal anymore (how to check????) // merge the last existing type in all the collections until we reach the first type again or the last types aren't equal anymore (how to check????)
impl MersType for Type { impl Type {
fn is_same_type_as(&self, other: &dyn MersType) -> bool { pub fn is_same_type_as(&self, other: &Self) -> bool {
// TODO! improve // TODO! improve
self.is_included_in(other) && other.is_included_in(self) self.is_included_in(other) && other.is_included_in(self)
} }
fn is_included_in_single(&self, target: &dyn MersType) -> bool { pub fn is_included_in(&self, target: &Self) -> bool {
self.types.iter().all(|t| t.is_included_in_single(target)) self.types
.iter()
.all(|s| target.types.iter().any(|t| s.is_included_in(&**t)))
} }
fn is_included_in(&self, target: &dyn MersType) -> bool { pub fn is_included_in_single(&self, target: &dyn MersType) -> bool {
self.types.iter().all(|t| t.is_included_in(target)) self.types.iter().all(|s| s.is_included_in(target))
} }
fn subtypes(&self, acc: &mut Type) { pub fn subtypes(&self, acc: &mut Type) {
for t in &self.types { for t in &self.types {
t.subtypes(acc); t.subtypes(acc);
} }
} }
fn as_any(&self) -> &dyn Any { pub fn subtypes_type(&self) -> Type {
self let mut acc = Type::empty();
self.subtypes(&mut acc);
acc
} }
fn mut_any(&mut self) -> &mut dyn Any { pub fn iterable(&self) -> Option<Type> {
self
}
fn to_any(self) -> Box<dyn Any> {
Box::new(self)
}
fn iterable(&self) -> Option<Type> {
let mut o = Self::empty(); let mut o = Self::empty();
for t in self.types.iter() { for t in self.types.iter() {
if let Some(t) = t.iterable() { if let Some(t) = t.iterable() {
o.add(Arc::new(t)); o.add_all(&t);
} else { } else {
return None; return None;
} }
} }
Some(o) Some(o)
} }
fn get(&self) -> Option<Type> { pub fn get(&self) -> Option<Type> {
let mut o = Self::empty(); let mut o = Self::empty();
for t in self.types.iter() { for t in self.types.iter() {
if let Some(t) = t.get() { if let Some(t) = t.get() {
o.add(Arc::new(t)); o.add_all(&t);
} else { } else {
return None; return None;
} }

View File

@ -48,7 +48,7 @@ impl MersType for ObjectT {
.all(|((s1, t1), (s2, t2))| s1 == s2 && t1.is_same_type_as(t2)) .all(|((s1, t1), (s2, t2))| s1 == s2 && t1.is_same_type_as(t2))
}) })
} }
fn is_included_in_single(&self, target: &dyn MersType) -> bool { fn is_included_in(&self, target: &dyn MersType) -> bool {
target target
.as_any() .as_any()
.downcast_ref::<Self>() .downcast_ref::<Self>()

View File

@ -44,7 +44,7 @@ impl MersType for ReferenceT {
false false
} }
} }
fn is_included_in_single(&self, target: &dyn MersType) -> bool { fn is_included_in(&self, target: &dyn MersType) -> bool {
// &int isn't included in &(int/float), otherwise we could assign a float to it // &int isn't included in &(int/float), otherwise we could assign a float to it
self.is_same_type_as(target) self.is_same_type_as(target)
} }

View File

@ -36,7 +36,7 @@ impl MersType for StringT {
fn is_same_type_as(&self, other: &dyn MersType) -> bool { fn is_same_type_as(&self, other: &dyn MersType) -> bool {
other.as_any().downcast_ref::<Self>().is_some() other.as_any().downcast_ref::<Self>().is_some()
} }
fn is_included_in_single(&self, target: &dyn MersType) -> bool { fn is_included_in(&self, target: &dyn MersType) -> bool {
self.is_same_type_as(target) self.is_same_type_as(target)
} }
fn subtypes(&self, acc: &mut Type) { fn subtypes(&self, acc: &mut Type) {

View File

@ -48,7 +48,7 @@ impl MersType for TupleT {
fn iterable(&self) -> Option<Type> { fn iterable(&self) -> Option<Type> {
let mut o = Type::empty(); let mut o = Type::empty();
for t in self.0.iter() { for t in self.0.iter() {
o.add(Arc::new(t.clone())); o.add_all(&t);
} }
Some(o) Some(o)
} }
@ -64,7 +64,7 @@ impl MersType for TupleT {
false false
} }
} }
fn is_included_in_single(&self, target: &dyn MersType) -> bool { fn is_included_in(&self, target: &dyn MersType) -> bool {
if let Some(target) = target.as_any().downcast_ref::<Self>() { if let Some(target) = target.as_any().downcast_ref::<Self>() {
self.0.len() == target.0.len() self.0.len() == target.0.len()
&& self && self

View File

@ -208,33 +208,33 @@ pub fn type_from_parsed(
) -> Result<Type, CheckError> { ) -> Result<Type, CheckError> {
let mut as_type = Type::empty(); let mut as_type = Type::empty();
for t in parsed.iter() { for t in parsed.iter() {
as_type.add(match t { match t {
ParsedType::Reference(inner) => { ParsedType::Reference(inner) => {
let inner = type_from_parsed(inner, info)?; let inner = type_from_parsed(inner, info)?;
Arc::new(data::reference::ReferenceT(inner)) as_type.add(Arc::new(data::reference::ReferenceT(inner)));
} }
ParsedType::Tuple(t) => Arc::new(data::tuple::TupleT( ParsedType::Tuple(t) => as_type.add(Arc::new(data::tuple::TupleT(
t.iter() t.iter()
.map(|v| type_from_parsed(v, info)) .map(|v| type_from_parsed(v, info))
.collect::<Result<_, _>>()?, .collect::<Result<_, _>>()?,
)), ))),
ParsedType::Object(o) => Arc::new(data::object::ObjectT( ParsedType::Object(o) => as_type.add(Arc::new(data::object::ObjectT(
o.iter() o.iter()
.map(|(s, v)| -> Result<_, CheckError> { .map(|(s, v)| -> Result<_, CheckError> {
Ok((s.clone(), type_from_parsed(v, info)?)) Ok((s.clone(), type_from_parsed(v, info)?))
}) })
.collect::<Result<_, _>>()?, .collect::<Result<_, _>>()?,
)), ))),
ParsedType::Function(v) => Arc::new(data::function::FunctionT(Err(v ParsedType::Function(v) => as_type.add(Arc::new(data::function::FunctionT(Err(v
.iter() .iter()
.map(|(i, o)| Ok((type_from_parsed(i, info)?, type_from_parsed(o, info)?))) .map(|(i, o)| Ok((type_from_parsed(i, info)?, type_from_parsed(o, info)?)))
.collect::<Result<_, CheckError>>()?))), .collect::<Result<_, CheckError>>()?)))),
ParsedType::Type(name) => match info ParsedType::Type(name) => match info
.scopes .scopes
.iter() .iter()
.find_map(|scope| scope.types.iter().find(|v| v.0 == name).map(|(_, v)| v)) .find_map(|scope| scope.types.iter().find(|v| v.0 == name).map(|(_, v)| v))
{ {
Some(Ok(t)) => Arc::clone(t), Some(Ok(t)) => as_type.add_all(&*t),
Some(Err(_)) => { Some(Err(_)) => {
return Err(CheckError::new().msg(format!( return Err(CheckError::new().msg(format!(
"Type: specified type without info, but type needs additional info" "Type: specified type without info, but type needs additional info"
@ -252,10 +252,10 @@ pub fn type_from_parsed(
"Type: specified type with info, but type {t} doesn't need it" "Type: specified type with info, but type {t} doesn't need it"
))) )))
} }
Some(Err(f)) => f(&additional_info, info)?, Some(Err(f)) => as_type.add_all(&*f(&additional_info, info)?),
None => return Err(CheckError::new().msg(format!("Unknown type '{name}'"))), None => return Err(CheckError::new().msg(format!("Unknown type '{name}'"))),
}, },
}); }
} }
Ok(as_type) Ok(as_type)
} }

View File

@ -1,7 +1,7 @@
use std::sync::{Arc, RwLock}; use std::sync::{Arc, RwLock};
use crate::{ use crate::{
data::{self, Data, MersType}, data::{self, Data, Type},
errors::CheckError, errors::CheckError,
info::Local, info::Local,
program::run::CheckInfo, program::run::CheckInfo,
@ -70,7 +70,7 @@ impl Config {
.last_mut() .last_mut()
.unwrap() .unwrap()
.types .types
.insert(t.to_string(), Ok(Arc::new(t))); .insert(t.to_string(), Ok(Arc::new(data::Type::new(t))));
}; };
} }
init_d!(data::bool::BoolT); init_d!(data::bool::BoolT);
@ -106,8 +106,8 @@ impl Config {
mut self, mut self,
name: String, name: String,
t: Result< t: Result<
Arc<dyn MersType>, Arc<Type>,
Arc<dyn Fn(&str, &CheckInfo) -> Result<Arc<dyn MersType>, CheckError> + Send + Sync>, Arc<dyn Fn(&str, &CheckInfo) -> Result<Arc<Type>, CheckError> + Send + Sync>,
>, >,
) -> Self { ) -> Self {
self.info_check.scopes[0].types.insert(name, t); self.info_check.scopes[0].types.insert(name, t);

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},
errors::CheckError, errors::CheckError,
info::Info, info::Info,
}; };

View File

@ -4,7 +4,7 @@ use std::{
}; };
use crate::{ use crate::{
data::{self, Data, MersType, Type}, data::{self, Data, Type},
errors::CheckError, errors::CheckError,
program::run::{CheckInfo, Info}, program::run::{CheckInfo, Info},
}; };
@ -101,7 +101,7 @@ impl Config {
.add_var("panic".to_string(), Data::new(data::function::Function { .add_var("panic".to_string(), Data::new(data::function::Function {
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| if a.is_included_in(&data::int::IntT) { out: Arc::new(|a, _i| if a.is_included_in_single(&data::int::IntT) {
Ok(Type::empty()) Ok(Type::empty())
} else { } else {
Err(format!("cannot call exit with non-int argument").into()) Err(format!("cannot call exit with non-int argument").into())

View File

@ -20,15 +20,15 @@ impl Config {
/// returns (int/(), string, string) on success (status code, stdout, stderr) /// returns (int/(), string, string) on success (status code, stdout, stderr)
pub fn with_command_running(self) -> Self { pub fn with_command_running(self) -> Self {
self self
.add_type("RunCommandError".to_owned(), Ok(Arc::new(RunCommandErrorT))) .add_type("RunCommandError".to_owned(), Ok(Arc::new(Type::new(RunCommandErrorT))))
.add_type("ChildProcess".to_owned(), Ok(Arc::new(ChildProcessT))) .add_type("ChildProcess".to_owned(), Ok(Arc::new(Type::new(ChildProcessT))))
.add_var( .add_var(
"run_command".to_string(), "run_command".to_string(),
Data::new(data::function::Function { Data::new(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())),
out: Arc::new(|a, _i| { out: Arc::new(|a, _i| {
if a.types.iter().all(|t| t.as_any().downcast_ref::<data::tuple::TupleT>().is_some_and(|t| t.0.len() == 2 && t.0[0].is_included_in(&data::string::StringT) && t.0[1].iterable().is_some_and(|t| t.is_included_in(&data::string::StringT)))) { if a.types.iter().all(|t| t.as_any().downcast_ref::<data::tuple::TupleT>().is_some_and(|t| t.0.len() == 2 && t.0[0].is_included_in_single(&data::string::StringT) && t.0[1].iterable().is_some_and(|t| t.is_included_in_single(&data::string::StringT)))) {
Ok(Type::newm(vec![ Ok(Type::newm(vec![
Arc::new(data::tuple::TupleT(vec![ Arc::new(data::tuple::TupleT(vec![
Type::newm(vec![Arc::new(data::int::IntT), Arc::new(data::bool::BoolT)]), Type::newm(vec![Arc::new(data::int::IntT), Arc::new(data::bool::BoolT)]),
@ -82,7 +82,7 @@ impl Config {
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())),
out: Arc::new(|a, _i| { out: Arc::new(|a, _i| {
if a.types.iter().all(|t| t.as_any().downcast_ref::<data::tuple::TupleT>().is_some_and(|t| t.0.len() == 2 && t.0[0].is_included_in(&data::string::StringT) && t.0[1].iterable().is_some_and(|t| t.is_included_in(&data::string::StringT)))) { if a.types.iter().all(|t| t.as_any().downcast_ref::<data::tuple::TupleT>().is_some_and(|t| t.0.len() == 2 && t.0[0].is_included_in_single(&data::string::StringT) && t.0[1].iterable().is_some_and(|t| t.is_included_in_single(&data::string::StringT)))) {
Ok(Type::newm(vec![ Ok(Type::newm(vec![
Arc::new(ChildProcessT), Arc::new(ChildProcessT),
Arc::new(RunCommandErrorT) Arc::new(RunCommandErrorT)
@ -125,7 +125,7 @@ impl Config {
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())),
out: Arc::new(|a, _i| { out: Arc::new(|a, _i| {
if a.is_included_in(&ChildProcessT) { if a.is_included_in_single(&ChildProcessT) {
Ok(Type::newm(vec![ Ok(Type::newm(vec![
Arc::new(data::tuple::TupleT(vec![Type::new(data::bool::BoolT)])), Arc::new(data::tuple::TupleT(vec![Type::new(data::bool::BoolT)])),
Arc::new(data::tuple::TupleT(vec![])), Arc::new(data::tuple::TupleT(vec![])),
@ -153,7 +153,7 @@ impl Config {
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())),
out: Arc::new(|a, _i| { out: Arc::new(|a, _i| {
if a.is_included_in(&ChildProcessT) { if a.is_included_in_single(&ChildProcessT) {
Ok(Type::newm(vec![ Ok(Type::newm(vec![
Arc::new(data::int::IntT), Arc::new(data::int::IntT),
Arc::new(data::bool::BoolT), Arc::new(data::bool::BoolT),
@ -186,7 +186,7 @@ impl Config {
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())),
out: Arc::new(|a, _i| { out: Arc::new(|a, _i| {
if a.types.iter().all(|a| a.as_any().downcast_ref::<data::tuple::TupleT>().is_some_and(|t| t.0.len() == 2 && t.0[0].is_included_in(&ChildProcessT) && t.0[1].iterable().is_some_and(|i| i.is_included_in(&data::byte::ByteT)))) { if a.types.iter().all(|a| a.as_any().downcast_ref::<data::tuple::TupleT>().is_some_and(|t| t.0.len() == 2 && t.0[0].is_included_in_single(&ChildProcessT) && t.0[1].iterable().is_some_and(|i| i.is_included_in_single(&data::byte::ByteT)))) {
Ok(Type::new(data::bool::BoolT)) Ok(Type::new(data::bool::BoolT))
} else { } else {
return Err(format!("childproc_write_bytes called on non-`(ChildProcess, Iter<Byte>)` type {a}").into()); return Err(format!("childproc_write_bytes called on non-`(ChildProcess, Iter<Byte>)` type {a}").into());
@ -215,7 +215,7 @@ impl Config {
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())),
out: Arc::new(|a, _i| { out: Arc::new(|a, _i| {
if a.is_included_in(&data::tuple::TupleT(vec![Type::new(ChildProcessT), Type::new(data::string::StringT)])) { if a.is_included_in_single(&data::tuple::TupleT(vec![Type::new(ChildProcessT), Type::new(data::string::StringT)])) {
Ok(Type::new(data::bool::BoolT)) Ok(Type::new(data::bool::BoolT))
} else { } else {
return Err(format!("childproc_write_string called on non-`(ChildProcess, String)` type {a}").into()); return Err(format!("childproc_write_string called on non-`(ChildProcess, String)` type {a}").into());
@ -244,7 +244,7 @@ impl Config {
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())),
out: Arc::new(|a, _i| { out: Arc::new(|a, _i| {
if a.is_included_in(&ChildProcessT) { if a.is_included_in_single(&ChildProcessT) {
Ok(Type::newm(vec![ Ok(Type::newm(vec![
Arc::new(data::tuple::TupleT(vec![Type::new(data::byte::ByteT)])), Arc::new(data::tuple::TupleT(vec![Type::new(data::byte::ByteT)])),
Arc::new(data::tuple::TupleT(vec![])), Arc::new(data::tuple::TupleT(vec![])),
@ -273,7 +273,7 @@ impl Config {
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())),
out: Arc::new(|a, _i| { out: Arc::new(|a, _i| {
if a.is_included_in(&ChildProcessT) { if a.is_included_in_single(&ChildProcessT) {
Ok(Type::newm(vec![ Ok(Type::newm(vec![
Arc::new(data::tuple::TupleT(vec![Type::new(data::byte::ByteT)])), Arc::new(data::tuple::TupleT(vec![Type::new(data::byte::ByteT)])),
Arc::new(data::tuple::TupleT(vec![])), Arc::new(data::tuple::TupleT(vec![])),
@ -302,7 +302,7 @@ impl Config {
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())),
out: Arc::new(|a, _i| { out: Arc::new(|a, _i| {
if a.is_included_in(&ChildProcessT) { if a.is_included_in_single(&ChildProcessT) {
Ok(Type::newm(vec![ Ok(Type::newm(vec![
Arc::new(data::tuple::TupleT(vec![Type::new(data::string::StringT)])), Arc::new(data::tuple::TupleT(vec![Type::new(data::string::StringT)])),
Arc::new(data::tuple::TupleT(vec![])), Arc::new(data::tuple::TupleT(vec![])),
@ -331,7 +331,7 @@ impl Config {
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())),
out: Arc::new(|a, _i| { out: Arc::new(|a, _i| {
if a.is_included_in(&ChildProcessT) { if a.is_included_in_single(&ChildProcessT) {
Ok(Type::newm(vec![ Ok(Type::newm(vec![
Arc::new(data::tuple::TupleT(vec![Type::new(data::string::StringT)])), Arc::new(data::tuple::TupleT(vec![Type::new(data::string::StringT)])),
Arc::new(data::tuple::TupleT(vec![])), Arc::new(data::tuple::TupleT(vec![])),
@ -414,7 +414,7 @@ impl MersType for ChildProcessT {
fn is_same_type_as(&self, other: &dyn MersType) -> bool { fn is_same_type_as(&self, other: &dyn MersType) -> bool {
other.as_any().is::<Self>() other.as_any().is::<Self>()
} }
fn is_included_in_single(&self, target: &dyn MersType) -> bool { fn is_included_in(&self, target: &dyn MersType) -> bool {
target.as_any().is::<Self>() target.as_any().is::<Self>()
} }
fn subtypes(&self, acc: &mut Type) { fn subtypes(&self, acc: &mut Type) {
@ -468,7 +468,7 @@ impl MersType for RunCommandErrorT {
fn is_same_type_as(&self, other: &dyn MersType) -> bool { fn is_same_type_as(&self, other: &dyn MersType) -> bool {
other.as_any().downcast_ref::<Self>().is_some() other.as_any().downcast_ref::<Self>().is_some()
} }
fn is_included_in_single(&self, target: &dyn MersType) -> bool { fn is_included_in(&self, target: &dyn MersType) -> bool {
self.is_same_type_as(target) self.is_same_type_as(target)
} }
fn subtypes(&self, acc: &mut Type) { fn subtypes(&self, acc: &mut Type) {

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::{self, run::CheckInfo}, program::{self, run::CheckInfo},
}; };
@ -22,7 +22,7 @@ impl Config {
if t.0.len() != 2 { if t.0.len() != 2 {
return Err(format!("called get on tuple with len != 2").into()); return Err(format!("called get on tuple with len != 2").into());
} }
if !t.0[1].is_included_in(&data::int::IntT) { if !t.0[1].is_included_in_single(&data::int::IntT) {
return Err(format!( return Err(format!(
"called get with non-int index of type {}", "called get with non-int index of type {}",
t.0[1] t.0[1]
@ -30,7 +30,7 @@ impl Config {
.into()); .into());
} }
if let Some(v) = t.0[0].get() { if let Some(v) = t.0[0].get() {
out.add(Arc::new(v)); out.add_all(&v);
} else { } else {
return Err(format!( return Err(format!(
"called get on non-gettable type {t}, part of {a}" "called get on non-gettable type {t}, part of {a}"

View File

@ -327,7 +327,7 @@ impl IterT {
let t = match &iter { let t = match &iter {
ItersT::Map(f) => f.o(&data)?, ItersT::Map(f) => f.o(&data)?,
ItersT::Filter(f) => { ItersT::Filter(f) => {
if f.o(&data)?.is_included_in(&data::bool::BoolT) { if f.o(&data)?.is_included_in_single(&data::bool::BoolT) {
data.clone() data.clone()
} else { } else {
return Err(format!( return Err(format!(
@ -381,7 +381,7 @@ impl MersType for IterT {
false false
} }
} }
fn is_included_in_single(&self, target: &dyn MersType) -> bool { fn is_included_in(&self, target: &dyn MersType) -> bool {
if let Some(target) = target.as_any().downcast_ref::<Self>() { if let Some(target) = target.as_any().downcast_ref::<Self>() {
self.2.is_included_in(&target.2) self.2.is_included_in(&target.2)
} else { } else {
@ -440,7 +440,7 @@ fn genfunc_iter_in_val_out(
info_check: Arc::new(Mutex::new(crate::info::Info::neverused())), info_check: Arc::new(Mutex::new(crate::info::Info::neverused())),
out: Arc::new(move |a, _i| { out: Arc::new(move |a, _i| {
if let Some(iter_over) = a.iterable() { if let Some(iter_over) = a.iterable() {
if iter_over.is_included_in(&iter_type) { if iter_over.is_included_in_single(&iter_type) {
Ok(out_type.clone()) Ok(out_type.clone())
} else { } else {
Err(format!("Cannot call function {name} on iterator over type {a}, which isn't {iter_type}.").into()) Err(format!("Cannot call function {name} on iterator over type {a}, which isn't {iter_type}.").into())

View File

@ -29,7 +29,7 @@ impl Config {
let mut src = 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 srca = Arc::new(src.clone());
let t = crate::parsing::types::parse_type(&mut src, &srca)?; 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(Type::new(ListT(crate::parsing::types::type_from_parsed(&t, i)?))))})))
.add_var("get_mut".to_string(), Data::new(data::function::Function { .add_var("get_mut".to_string(), Data::new(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())),
@ -107,7 +107,7 @@ impl Config {
let mut out = Type::empty(); let mut out = Type::empty();
for t in a.types.iter() { for t in a.types.iter() {
if let Some(t) = t.as_any().downcast_ref::<ListT>() { if let Some(t) = t.as_any().downcast_ref::<ListT>() {
out.add(Arc::new(t.0.clone())); out.add_all(&t.0);
} else { } else {
return Err(format!( return Err(format!(
"pop: found a reference to {t}, which is not a list" "pop: found a reference to {t}, which is not a list"
@ -115,8 +115,8 @@ impl Config {
} }
} }
Ok(Type::newm(vec![ Ok(Type::newm(vec![
Arc::new(Type::new(data::tuple::TupleT(vec![out]))), Arc::new(data::tuple::TupleT(vec![out])),
Arc::new(Type::empty_tuple()) Arc::new(data::tuple::TupleT(vec![]))
])) ]))
} else { } else {
return Err(format!("pop: not a reference: {a}").into()); return Err(format!("pop: not a reference: {a}").into());
@ -286,7 +286,7 @@ impl MersType for ListT {
.downcast_ref::<Self>() .downcast_ref::<Self>()
.is_some_and(|v| self.0.is_same_type_as(&v.0)) .is_some_and(|v| self.0.is_same_type_as(&v.0))
} }
fn is_included_in_single(&self, target: &dyn MersType) -> bool { fn is_included_in(&self, target: &dyn MersType) -> bool {
target target
.as_any() .as_any()
.downcast_ref::<Self>() .downcast_ref::<Self>()
@ -333,7 +333,7 @@ impl List {
pub fn inner_type(&self) -> Type { pub fn inner_type(&self) -> Type {
let mut t = Type::empty(); let mut t = Type::empty();
for el in &self.0 { for el in &self.0 {
t.add(Arc::new(el.read().unwrap().get().as_type())); t.add_all(&el.read().unwrap().get().as_type());
} }
t t
} }

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},
errors::CheckError, errors::CheckError,
program::{self, run::CheckInfo}, program::{self, run::CheckInfo},
}; };

View File

@ -24,7 +24,7 @@ impl Config {
let mut src = 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 srca = Arc::new(src.clone());
let t = crate::parsing::types::parse_type(&mut src, &srca)?; 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(Type::new(ThreadT(crate::parsing::types::type_from_parsed(&t, i)?))))
})), })),
) )
.add_var( .add_var(
@ -37,7 +37,7 @@ impl Config {
for t in a.types.iter() { for t in a.types.iter() {
if let Some(f) = t.as_any().downcast_ref::<data::function::FunctionT>() { if let Some(f) = t.as_any().downcast_ref::<data::function::FunctionT>() {
match f.o(&Type::empty_tuple()) { match f.o(&Type::empty_tuple()) {
Ok(t) => out.add(Arc::new(t)), Ok(t) => out.add_all(&t),
Err(e) => return Err(CheckError::new().msg(format!("Can't call thread on a function which can't be called on an empty tuple: ")).err(e)) Err(e) => return Err(CheckError::new().msg(format!("Can't call thread on a function which can't be called on an empty tuple: ")).err(e))
} }
} else { } else {
@ -91,7 +91,7 @@ impl Config {
let mut out = Type::empty(); let mut out = Type::empty();
for t in a.types.iter() { for t in a.types.iter() {
if let Some(t) = t.as_any().downcast_ref::<ThreadT>() { if let Some(t) = t.as_any().downcast_ref::<ThreadT>() {
out.add(Arc::new(Clone::clone(&t.0))); out.add_all(&t.0);
} else { } else {
return Err(CheckError::new().msg(format!("Cannot call thread_await on a value of type {t}, which isn't a thread but part of the argument {a}."))); return Err(CheckError::new().msg(format!("Cannot call thread_await on a value of type {t}, which isn't a thread but part of the argument {a}.")));
} }
@ -146,9 +146,9 @@ impl MersType for ThreadT {
false false
} }
} }
fn is_included_in_single(&self, target: &dyn MersType) -> bool { fn is_included_in(&self, target: &dyn MersType) -> bool {
if let Some(target) = target.as_any().downcast_ref::<Self>() { if let Some(target) = target.as_any().downcast_ref::<Self>() {
self.0.is_included_in_single(&target.0) self.0.is_included_in(&target.0)
} else { } else {
false false
} }

View File

@ -1,6 +1,6 @@
use std::sync::{Arc, RwLock}; use std::sync::{Arc, RwLock};
use crate::data::{self, Data, MersType, Type}; use crate::data::{self, Data, Type};
use super::{util, Config}; use super::{util, Config};
@ -44,13 +44,13 @@ impl Config {
if t.0.len() != 2 && t.0.len() != 3 { if t.0.len() != 2 && t.0.len() != 3 {
return Err(format!("cannot call substring with tuple argument of len != 3").into()); return Err(format!("cannot call substring with tuple argument of len != 3").into());
} }
if !t.0[0].is_included_in(&data::string::StringT) { if !t.0[0].is_included_in_single(&data::string::StringT) {
return Err(format!("cannot call substring with tuple argument that isn't (*string*, int, int)").into()); return Err(format!("cannot call substring with tuple argument that isn't (*string*, int, int)").into());
} }
if !t.0[1].is_included_in(&data::int::IntT) { if !t.0[1].is_included_in_single(&data::int::IntT) {
return Err(format!("cannot call substring with tuple argument that isn't (string, *int*, int)").into()); return Err(format!("cannot call substring with tuple argument that isn't (string, *int*, int)").into());
} }
if t.0.len() > 2 && !t.0[2].is_included_in(&data::int::IntT) { if t.0.len() > 2 && !t.0[2].is_included_in_single(&data::int::IntT) {
return Err(format!("cannot call substring with tuple argument that isn't (string, int, *int*)").into()); return Err(format!("cannot call substring with tuple argument that isn't (string, int, *int*)").into());
} }
} else { } else {

View File

@ -1,7 +1,7 @@
use colored::Colorize; use colored::Colorize;
use crate::{ use crate::{
data::{Data, MersType, Type}, data::{Data, Type},
errors::{error_colors, CheckError, SourceRange}, errors::{error_colors, CheckError, SourceRange},
parsing::types::ParsedType, parsing::types::ParsedType,
}; };

View File

@ -1,7 +1,7 @@
use colored::Colorize; use colored::Colorize;
use crate::{ use crate::{
data::{self, Data, MersType, Type}, data::{self, Data, Type},
errors::{error_colors, CheckError, SourceRange}, errors::{error_colors, CheckError, SourceRange},
}; };

View File

@ -1,5 +1,3 @@
use std::sync::Arc;
use colored::Colorize; use colored::Colorize;
use crate::{ use crate::{
@ -40,7 +38,7 @@ impl MersStatement for Chain {
.downcast_ref::<crate::data::function::FunctionT>() .downcast_ref::<crate::data::function::FunctionT>()
{ {
match func.o(&arg) { match func.o(&arg) {
Ok(t) => o.add(Arc::new(t)), Ok(t) => o.add_all(&t),
Err(e) => { Err(e) => {
return Err(if let Some(_) = &self.as_part_of_include { return Err(if let Some(_) = &self.as_part_of_include {
CheckError::new() CheckError::new()

View File

@ -1,7 +1,7 @@
use std::{fmt::Debug, sync::Arc}; use std::{fmt::Debug, sync::Arc};
use crate::{ use crate::{
data::{Data, MersType, Type}, data::{Data, Type},
errors::{CheckError, SourceRange}, errors::{CheckError, SourceRange},
}; };
@ -15,12 +15,8 @@ pub struct CustomType {
&CheckInfo, &CheckInfo,
) -> Result< ) -> Result<
Result< Result<
Arc<dyn MersType>, Arc<Type>,
Arc< Arc<dyn Fn(&str, &CheckInfo) -> Result<Arc<Type>, CheckError> + Send + Sync>,
dyn Fn(&str, &CheckInfo) -> Result<Arc<dyn MersType>, CheckError>
+ Send
+ Sync,
>,
>, >,
CheckError, CheckError,
> + Send > + Send

View File

@ -3,7 +3,7 @@ use std::sync::Arc;
use colored::Colorize; use colored::Colorize;
use crate::{ use crate::{
data::{self, Data, MersType, Type}, data::{self, tuple::TupleT, Data, Type},
errors::{error_colors, CheckError, SourceRange}, errors::{error_colors, CheckError, SourceRange},
}; };
@ -27,7 +27,7 @@ impl MersStatement for If {
return Err("can't init to statement type If".to_string().into()); return Err("can't init to statement type If".to_string().into());
} }
let cond_return_type = self.condition.check(info, None)?; let cond_return_type = self.condition.check(info, None)?;
if !cond_return_type.is_included_in(&data::bool::BoolT) { if !cond_return_type.is_included_in_single(&data::bool::BoolT) {
return Err(CheckError::new() return Err(CheckError::new()
.src(vec![ .src(vec![
(self.pos_in_src.clone(), None), (self.pos_in_src.clone(), None),
@ -46,9 +46,9 @@ impl MersStatement for If {
} }
let mut t = self.on_true.check(info, None)?; let mut t = self.on_true.check(info, None)?;
if let Some(f) = &self.on_false { if let Some(f) = &self.on_false {
t.add(Arc::new(f.check(info, None)?)); t.add_all(&f.check(info, None)?);
} else { } else {
t.add(Arc::new(Type::empty_tuple())); t.add(Arc::new(TupleT(vec![])));
} }
Ok(t) Ok(t)
} }

View File

@ -5,7 +5,7 @@ use std::{
}; };
use crate::{ use crate::{
data::{self, Data, MersType, Type}, data::{self, Data, Type},
errors::{CheckError, SourceRange}, errors::{CheckError, SourceRange},
info, info,
}; };
@ -121,8 +121,8 @@ pub struct CheckLocal {
pub types: HashMap< pub types: HashMap<
String, String,
Result< Result<
Arc<dyn MersType>, Arc<Type>,
Arc<dyn Fn(&str, &CheckInfo) -> Result<Arc<dyn MersType>, CheckError> + Send + Sync>, Arc<dyn Fn(&str, &CheckInfo) -> Result<Arc<Type>, CheckError> + Send + Sync>,
>, >,
>, >,
} }

View File

@ -1,4 +1,4 @@
use std::{collections::VecDeque, sync::Arc}; use std::collections::VecDeque;
use colored::Colorize; use colored::Colorize;
@ -43,7 +43,7 @@ impl MersStatement for Object {
} }
).into()); ).into());
} }
acc[i].add(Arc::new(t.clone())); acc[i].add_all(&t);
} }
} else { } else {
return Err(format!( return Err(format!(

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},
errors::{error_colors, CheckError, SourceRange}, errors::{error_colors, CheckError, SourceRange},
}; };

View File

@ -1,4 +1,4 @@
use std::{collections::VecDeque, sync::Arc}; use std::collections::VecDeque;
use colored::Colorize; use colored::Colorize;
@ -29,7 +29,7 @@ impl MersStatement for Tuple {
if let Some(t) = t.as_any().downcast_ref::<TupleT>() { if let Some(t) = t.as_any().downcast_ref::<TupleT>() {
if t.0.len() == self.elems.len() { if t.0.len() == self.elems.len() {
for (i, e) in t.0.iter().enumerate() { for (i, e) in t.0.iter().enumerate() {
vec[i].add(Arc::new(e.clone())); vec[i].add_all(&e);
} }
} else { } else {
return Err( return Err(