mirror of
https://github.com/Dummi26/mers.git
synced 2025-07-20 06:47:47 +02:00
improve .try resolving types, removes subtypes methods
Some checks failed
Rust / build (push) Has been cancelled
Some checks failed
Rust / build (push) Has been cancelled
This commit is contained in:
parent
ac6b405a3c
commit
35efae75ac
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "mers"
|
name = "mers"
|
||||||
version = "0.9.22"
|
version = "0.9.23"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT OR Apache-2.0"
|
license = "MIT OR Apache-2.0"
|
||||||
description = "dynamically typed but type-checked programming language"
|
description = "dynamically typed but type-checked programming language"
|
||||||
@ -15,7 +15,7 @@ default = ["colored-output"]
|
|||||||
colored-output = ["mers_lib/ecolor-term", "mers_lib/pretty-print", "dep:colored"]
|
colored-output = ["mers_lib/ecolor-term", "mers_lib/pretty-print", "dep:colored"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
mers_lib = "0.9.22"
|
mers_lib = "0.9.23"
|
||||||
# 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 = { version = "2.1.0", optional = true }
|
colored = { version = "2.1.0", optional = true }
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "mers_lib"
|
name = "mers_lib"
|
||||||
version = "0.9.22"
|
version = "0.9.23"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT OR Apache-2.0"
|
license = "MIT OR Apache-2.0"
|
||||||
description = "library to use the mers language in other projects"
|
description = "library to use the mers language in other projects"
|
||||||
|
@ -61,8 +61,12 @@ impl MersType for TrueT {
|
|||||||
fn is_included_in(&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 without(&self, remove: &dyn MersType) -> Option<Type> {
|
||||||
acc.add(Arc::new(self.clone()));
|
if self.is_included_in(remove) {
|
||||||
|
Some(Type::empty())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fn as_any(&self) -> &dyn Any {
|
fn as_any(&self) -> &dyn Any {
|
||||||
self
|
self
|
||||||
@ -88,8 +92,12 @@ impl MersType for FalseT {
|
|||||||
fn is_included_in(&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 without(&self, remove: &dyn MersType) -> Option<Type> {
|
||||||
acc.add(Arc::new(self.clone()));
|
if self.is_included_in(remove) {
|
||||||
|
Some(Type::empty())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fn as_any(&self) -> &dyn Any {
|
fn as_any(&self) -> &dyn Any {
|
||||||
self
|
self
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use std::{any::Any, fmt::Display, sync::Arc};
|
use std::{any::Any, fmt::Display};
|
||||||
|
|
||||||
use crate::info::DisplayInfo;
|
use crate::info::DisplayInfo;
|
||||||
|
|
||||||
@ -51,8 +51,12 @@ impl MersType for ByteT {
|
|||||||
fn is_included_in(&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 without(&self, remove: &dyn MersType) -> Option<Type> {
|
||||||
acc.add(Arc::new(self.clone()));
|
if self.is_included_in(remove) {
|
||||||
|
Some(Type::empty())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fn as_any(&self) -> &dyn Any {
|
fn as_any(&self) -> &dyn Any {
|
||||||
self
|
self
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use std::{any::Any, fmt::Display, sync::Arc};
|
use std::{any::Any, fmt::Display};
|
||||||
|
|
||||||
use crate::info::DisplayInfo;
|
use crate::info::DisplayInfo;
|
||||||
|
|
||||||
@ -51,8 +51,12 @@ impl MersType for FloatT {
|
|||||||
fn is_included_in(&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 without(&self, remove: &dyn MersType) -> Option<Type> {
|
||||||
acc.add(Arc::new(self.clone()));
|
if self.is_included_in(remove) {
|
||||||
|
Some(Type::empty())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fn as_any(&self) -> &dyn Any {
|
fn as_any(&self) -> &dyn Any {
|
||||||
self
|
self
|
||||||
|
@ -7,6 +7,7 @@ use std::{
|
|||||||
use crate::{
|
use crate::{
|
||||||
errors::CheckError,
|
errors::CheckError,
|
||||||
info::DisplayInfo,
|
info::DisplayInfo,
|
||||||
|
parsing::types::ParsedType,
|
||||||
program::run::{CheckInfo, Info},
|
program::run::{CheckInfo, Info},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -15,6 +16,8 @@ use super::{Data, MersData, MersType, Type};
|
|||||||
pub struct Function {
|
pub struct Function {
|
||||||
pub info: Info,
|
pub info: Info,
|
||||||
pub info_check: Arc<Mutex<CheckInfo>>,
|
pub info_check: Arc<Mutex<CheckInfo>>,
|
||||||
|
pub fixed_type: Option<Vec<(Vec<ParsedType>, Option<Vec<ParsedType>>)>>,
|
||||||
|
pub fixed_type_out: Arc<Mutex<Option<Result<Arc<Vec<(Type, Type)>>, CheckError>>>>,
|
||||||
pub out: Result<
|
pub out: Result<
|
||||||
Arc<dyn Fn(&Type, &mut CheckInfo) -> Result<Type, CheckError> + Send + Sync>,
|
Arc<dyn Fn(&Type, &mut CheckInfo) -> Result<Type, CheckError> + Send + Sync>,
|
||||||
Arc<Vec<(Type, Type)>>,
|
Arc<Vec<(Type, Type)>>,
|
||||||
@ -31,6 +34,8 @@ impl Clone for Function {
|
|||||||
Self {
|
Self {
|
||||||
info: self.info.duplicate(),
|
info: self.info.duplicate(),
|
||||||
info_check: self.info_check.clone(),
|
info_check: self.info_check.clone(),
|
||||||
|
fixed_type: self.fixed_type.clone(),
|
||||||
|
fixed_type_out: self.fixed_type_out.clone(),
|
||||||
out: self.out.clone(),
|
out: self.out.clone(),
|
||||||
run: self.run.clone(),
|
run: self.run.clone(),
|
||||||
inner_statements: self.inner_statements.clone(),
|
inner_statements: self.inner_statements.clone(),
|
||||||
@ -45,6 +50,8 @@ impl Function {
|
|||||||
Self {
|
Self {
|
||||||
info: crate::info::Info::neverused(),
|
info: crate::info::Info::neverused(),
|
||||||
info_check: Arc::new(Mutex::new(crate::info::Info::neverused())),
|
info_check: Arc::new(Mutex::new(crate::info::Info::neverused())),
|
||||||
|
fixed_type: None,
|
||||||
|
fixed_type_out: Arc::new(Mutex::new(None)),
|
||||||
out: Err(Arc::new(out)),
|
out: Err(Arc::new(out)),
|
||||||
run: Arc::new(run),
|
run: Arc::new(run),
|
||||||
inner_statements: None,
|
inner_statements: None,
|
||||||
@ -57,6 +64,8 @@ impl Function {
|
|||||||
Self {
|
Self {
|
||||||
info: crate::info::Info::neverused(),
|
info: crate::info::Info::neverused(),
|
||||||
info_check: Arc::new(Mutex::new(crate::info::Info::neverused())),
|
info_check: Arc::new(Mutex::new(crate::info::Info::neverused())),
|
||||||
|
fixed_type: None,
|
||||||
|
fixed_type_out: Arc::new(Mutex::new(None)),
|
||||||
out: Ok(Arc::new(move |a, i| out(a, i))),
|
out: Ok(Arc::new(move |a, i| out(a, i))),
|
||||||
run: Arc::new(run),
|
run: Arc::new(run),
|
||||||
inner_statements: None,
|
inner_statements: None,
|
||||||
@ -66,6 +75,8 @@ impl Function {
|
|||||||
Self {
|
Self {
|
||||||
info,
|
info,
|
||||||
info_check: Arc::clone(&self.info_check),
|
info_check: Arc::clone(&self.info_check),
|
||||||
|
fixed_type: self.fixed_type.clone(),
|
||||||
|
fixed_type_out: self.fixed_type_out.clone(),
|
||||||
out: self.out.clone(),
|
out: self.out.clone(),
|
||||||
run: Arc::clone(&self.run),
|
run: Arc::clone(&self.run),
|
||||||
inner_statements: self
|
inner_statements: self
|
||||||
@ -75,11 +86,56 @@ impl Function {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn with_info_check(&self, check: CheckInfo) {
|
pub fn with_info_check(&self, check: CheckInfo) {
|
||||||
|
if let Some(fixed_type) = &self.fixed_type {
|
||||||
|
if let Ok(out_func) = &self.out {
|
||||||
|
let mut nout = Ok(Vec::with_capacity(fixed_type.len()));
|
||||||
|
for (in_type, out_type) in fixed_type {
|
||||||
|
if let Ok(new_out) = &mut nout {
|
||||||
|
let in_type = crate::parsing::types::type_from_parsed(in_type, &check)
|
||||||
|
.expect("failed to get intype from parsed type");
|
||||||
|
let out_type_want = out_type.as_ref().map(|out_type| {
|
||||||
|
crate::parsing::types::type_from_parsed(out_type, &check)
|
||||||
|
.expect("failed to get intype from parsed type")
|
||||||
|
});
|
||||||
|
let mut out_type = match out_func(&in_type, &mut check.clone()) {
|
||||||
|
Ok(t) => t,
|
||||||
|
Err(e) => {
|
||||||
|
nout = Err(e);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if let Some(out_type_want) = out_type_want {
|
||||||
|
if out_type.is_included_in(&out_type_want) {
|
||||||
|
out_type = out_type_want;
|
||||||
|
} else {
|
||||||
|
nout = Err(format!(
|
||||||
|
"function must return {} for input {} because of its definition, but it returns {}.",
|
||||||
|
out_type_want.with_info(&check),
|
||||||
|
in_type.with_info(&check),
|
||||||
|
out_type.with_info(&check),
|
||||||
|
)
|
||||||
|
.into());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
new_out.push((in_type, out_type));
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*self.fixed_type_out.lock().unwrap() = Some(nout.map(Arc::new));
|
||||||
|
}
|
||||||
|
}
|
||||||
*self.info_check.lock().unwrap() = check;
|
*self.info_check.lock().unwrap() = check;
|
||||||
}
|
}
|
||||||
pub fn check(&self, arg: &Type) -> Result<Type, CheckError> {
|
pub fn check(&self, arg: &Type) -> Result<Type, CheckError> {
|
||||||
|
// TODO: this should require a CheckInfo and call `with_info_check`.
|
||||||
self.get_as_type().o(arg)
|
self.get_as_type().o(arg)
|
||||||
}
|
}
|
||||||
|
pub fn check_try(&self, arg: &Type) -> Result<Type, (CheckError, Vec<(Type, Type)>)> {
|
||||||
|
// TODO: this should require a CheckInfo and call `with_info_check`.
|
||||||
|
self.get_as_type().o_try(arg)
|
||||||
|
}
|
||||||
pub fn run_mut(
|
pub fn run_mut(
|
||||||
&mut self,
|
&mut self,
|
||||||
arg: Data,
|
arg: Data,
|
||||||
@ -102,6 +158,19 @@ impl Function {
|
|||||||
}
|
}
|
||||||
pub fn get_as_type(&self) -> FunctionT {
|
pub fn get_as_type(&self) -> FunctionT {
|
||||||
let info = self.info_check.lock().unwrap().clone();
|
let info = self.info_check.lock().unwrap().clone();
|
||||||
|
if self.fixed_type.is_some() {
|
||||||
|
match &*self.fixed_type_out.lock().unwrap() {
|
||||||
|
Some(Ok(types)) => return FunctionT(Err(types.clone()), info),
|
||||||
|
Some(Err(e)) => {
|
||||||
|
let e = e.clone();
|
||||||
|
return FunctionT(
|
||||||
|
Ok(Arc::new(move |_, _| Err(e.clone()))),
|
||||||
|
crate::info::Info::neverused(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
match &self.out {
|
match &self.out {
|
||||||
Ok(out) => {
|
Ok(out) => {
|
||||||
let out = Arc::clone(out);
|
let out = Arc::clone(out);
|
||||||
@ -189,13 +258,26 @@ pub struct FunctionT(
|
|||||||
impl FunctionT {
|
impl FunctionT {
|
||||||
/// get output type
|
/// get output type
|
||||||
pub fn o(&self, i: &Type) -> Result<Type, CheckError> {
|
pub fn o(&self, i: &Type) -> Result<Type, CheckError> {
|
||||||
|
self.o_try(i).map_err(|(e, _)| e)
|
||||||
|
}
|
||||||
|
/// get output type
|
||||||
|
pub fn o_try(&self, i: &Type) -> Result<Type, (CheckError, Vec<(Type, Type)>)> {
|
||||||
match &self.0 {
|
match &self.0 {
|
||||||
Ok(f) => f(i, &self.1),
|
Ok(f) => f(i, &self.1).map_err(|e| (e, vec![])),
|
||||||
Err(v) => v
|
Err(v) => v
|
||||||
.iter()
|
.iter()
|
||||||
.find(|(a, _)| i.is_included_in(a))
|
.find(|(a, _)| i.is_included_in(a))
|
||||||
.map(|(_, o)| o.clone())
|
.map(|(_, o)| o.clone())
|
||||||
.ok_or_else(|| format!("This function, which was defined with an explicit type, cannot be called with an argument of type {}.", i.with_info(&self.1)).into()),
|
.ok_or_else(||
|
||||||
|
(
|
||||||
|
format!("This function, which was defined with an explicit type, cannot be called with an argument of type {}.", i.with_info(&self.1)).into(),
|
||||||
|
v.iter()
|
||||||
|
.filter(|(a, _)| i.types.iter().any(|i| a.types.iter().any(|a|
|
||||||
|
i.without(a.as_ref()).is_some())))
|
||||||
|
.map(|(a, o)| (a.clone(), o.clone()))
|
||||||
|
.collect()
|
||||||
|
)
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -280,8 +362,12 @@ impl MersType for FunctionT {
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn subtypes(&self, acc: &mut Type) {
|
fn without(&self, remove: &dyn MersType) -> Option<Type> {
|
||||||
acc.add(Arc::new(self.clone()));
|
if self.is_included_in(remove) {
|
||||||
|
Some(Type::empty())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fn as_any(&self) -> &dyn Any {
|
fn as_any(&self) -> &dyn Any {
|
||||||
self
|
self
|
||||||
|
@ -96,27 +96,35 @@ impl MersType for IntT {
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn subtypes(&self, acc: &mut Type) {
|
fn without(&self, remove: &dyn MersType) -> Option<Type> {
|
||||||
// INT_MIN .. INT32U_MIN .. INT32S_MIN .. -128 .. -1 .. 0 .. 1 .. 127 .. 255 .. 65535 .. INT32S_MAX .. INT32U_MAX .. INT_MAX
|
if self.is_included_in(remove) {
|
||||||
let mut add_range = |min, max| {
|
Some(Type::empty())
|
||||||
// the range is non-empty, self starts before or where the range ends, and self ends after or where the range starts.
|
} else if let Some(remove) = remove.as_any().downcast_ref::<Self>() {
|
||||||
if min <= max && self.0 <= max && min <= self.1 {
|
if remove.0 <= self.0 && self.1 <= remove.1 {
|
||||||
acc.add(Arc::new(IntT(self.0.max(min), self.1.min(max))));
|
Some(Type::empty())
|
||||||
|
} else if remove.0 <= self.0 && self.0 <= remove.1 && remove.1 <= self.1 {
|
||||||
|
if remove.1 + 1 <= self.1 {
|
||||||
|
Some(Type::new(Self(remove.1 + 1, self.1)))
|
||||||
|
} else {
|
||||||
|
Some(Type::empty())
|
||||||
|
}
|
||||||
|
} else if self.0 <= remove.0 && remove.0 <= self.1 && self.1 <= remove.1 {
|
||||||
|
if self.0 <= remove.0 + 1 {
|
||||||
|
Some(Type::new(Self(self.0, remove.0 - 1)))
|
||||||
|
} else {
|
||||||
|
Some(Type::empty())
|
||||||
|
}
|
||||||
|
} else if self.0 < remove.0 && remove.0 <= remove.1 && remove.1 < self.1 {
|
||||||
|
Some(Type::newm(vec![
|
||||||
|
Arc::new(Self(self.0, remove.0 - 1)),
|
||||||
|
Arc::new(Self(remove.1 + 1, self.1)),
|
||||||
|
]))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
}
|
}
|
||||||
};
|
} else {
|
||||||
add_range(INT_MIN, INT32U_MIN.saturating_sub(1));
|
None
|
||||||
add_range(INT32U_MIN, INT32S_MIN.saturating_sub(1));
|
}
|
||||||
add_range(INT32S_MIN, -129);
|
|
||||||
add_range(-128, -2);
|
|
||||||
add_range(-1, -1);
|
|
||||||
add_range(0, 0);
|
|
||||||
add_range(1, 1);
|
|
||||||
add_range(2, 127);
|
|
||||||
add_range(128, 255);
|
|
||||||
add_range(256, 65535);
|
|
||||||
add_range(65536, INT32S_MAX);
|
|
||||||
add_range(INT32S_MAX.saturating_add(1), INT32U_MAX);
|
|
||||||
add_range(INT32U_MAX.saturating_add(1), INT_MAX);
|
|
||||||
}
|
}
|
||||||
fn as_any(&self) -> &dyn Any {
|
fn as_any(&self) -> &dyn Any {
|
||||||
self
|
self
|
||||||
|
@ -142,20 +142,10 @@ pub trait MersType: Any + Debug + Send + Sync {
|
|||||||
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 (Type::is_included_in handles it)
|
/// This doesn't handle the case where target is Type (Type::is_included_in handles it)
|
||||||
fn is_included_in(&self, target: &dyn MersType) -> bool;
|
fn is_included_in(&self, target: &dyn MersType) -> bool;
|
||||||
/// Returns all types that can result from the use of this type.
|
/// Returns `self` with `remove` removed, if it is different from `self`.
|
||||||
/// Usually, this is just `acc.add(Arc::new(self.clone()))`
|
/// This must, at least, return `Some(Type::empty())` if `self.is_included_in(remove)`.
|
||||||
/// but if there exists one or more inner types, this becomes interesting:
|
/// For example, `(Int<1..9>).remove(Int<4..6>)` would return `Some(Int<1..3>/Int<7..9>)`.
|
||||||
/// Using `(int/string)` will end up being either `(int)` or `(string)`,
|
fn without(&self, remove: &dyn MersType) -> Option<Type>;
|
||||||
/// so this function should add `(int)` and `(string)`.
|
|
||||||
/// Since `(int/string)` can't exist at runtime, we don't need to list `self`.
|
|
||||||
/// note also: `subtypes` has to be called recursively, i.e. you would have to call `.substring` on `int` and `string`.
|
|
||||||
fn subtypes(&self, acc: &mut Type);
|
|
||||||
/// like `subtypes`, but returns the accumulator
|
|
||||||
fn subtypes_type(&self) -> Type {
|
|
||||||
let mut acc = Type::empty();
|
|
||||||
self.subtypes(&mut acc);
|
|
||||||
acc
|
|
||||||
}
|
|
||||||
fn as_any(&self) -> &dyn Any;
|
fn as_any(&self) -> &dyn Any;
|
||||||
fn mut_any(&mut self) -> &mut dyn Any;
|
fn mut_any(&mut self) -> &mut dyn Any;
|
||||||
fn to_any(self) -> Box<dyn Any>;
|
fn to_any(self) -> Box<dyn Any>;
|
||||||
@ -189,8 +179,8 @@ impl MersType for TypeWithOnlyName {
|
|||||||
fn is_included_in(&self, _target: &dyn MersType) -> bool {
|
fn is_included_in(&self, _target: &dyn MersType) -> bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
fn subtypes(&self, acc: &mut Type) {
|
fn without(&self, _remove: &dyn MersType) -> Option<Type> {
|
||||||
acc.add(Arc::new(self.clone()))
|
None
|
||||||
}
|
}
|
||||||
fn as_any(&self) -> &dyn Any {
|
fn as_any(&self) -> &dyn Any {
|
||||||
self
|
self
|
||||||
@ -478,6 +468,29 @@ impl Type {
|
|||||||
self.add(Arc::clone(t));
|
self.add(Arc::clone(t));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pub fn without_in_place(&mut self, remove: &dyn MersType) {
|
||||||
|
let mut rm = vec![];
|
||||||
|
let mut add = vec![];
|
||||||
|
for (i, t) in self.types.iter_mut().enumerate() {
|
||||||
|
if t.is_included_in(remove) {
|
||||||
|
rm.push(i);
|
||||||
|
} else if let Some(without) = t.without(remove) {
|
||||||
|
rm.push(i);
|
||||||
|
add.push(without);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for i in rm.into_iter().rev() {
|
||||||
|
self.types.swap_remove(i);
|
||||||
|
}
|
||||||
|
for t in add {
|
||||||
|
self.add_all(&t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn without_in_place_all(&mut self, remove: &Self) {
|
||||||
|
for t in &remove.types {
|
||||||
|
self.without_in_place(t.as_ref());
|
||||||
|
}
|
||||||
|
}
|
||||||
pub fn dereference(&self) -> Option<Self> {
|
pub fn dereference(&self) -> Option<Self> {
|
||||||
let mut o = Self::empty();
|
let mut o = Self::empty();
|
||||||
for t in &self.types {
|
for t in &self.types {
|
||||||
@ -514,17 +527,6 @@ impl Type {
|
|||||||
pub fn is_included_in_single(&self, target: &dyn MersType) -> bool {
|
pub fn is_included_in_single(&self, target: &dyn MersType) -> bool {
|
||||||
self.types.iter().all(|s| s.is_included_in(target))
|
self.types.iter().all(|s| s.is_included_in(target))
|
||||||
}
|
}
|
||||||
pub fn subtypes(&self, acc: &mut Type) {
|
|
||||||
for t in &self.types {
|
|
||||||
t.subtypes(acc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn subtypes_type(&self) -> Type {
|
|
||||||
let mut acc = Type::empty();
|
|
||||||
acc.smart_type_simplification = false;
|
|
||||||
self.subtypes(&mut acc);
|
|
||||||
acc
|
|
||||||
}
|
|
||||||
pub fn iterable(&self) -> Option<Type> {
|
pub 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() {
|
||||||
|
@ -128,8 +128,62 @@ impl MersType for ObjectT {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
fn subtypes(&self, acc: &mut Type) {
|
fn without(&self, remove: &dyn MersType) -> Option<Type> {
|
||||||
self.gen_subtypes_recursively(acc, &mut Vec::with_capacity(self.len()));
|
let m = self.0.len();
|
||||||
|
if let Some(remove) = remove
|
||||||
|
.as_any()
|
||||||
|
.downcast_ref::<Self>()
|
||||||
|
.filter(|r| r.0.len() <= m)
|
||||||
|
{
|
||||||
|
let mut out = Type::empty();
|
||||||
|
for i1 in 0usize.. {
|
||||||
|
let mut self_tuple = Vec::with_capacity(m);
|
||||||
|
let mut i1 = i1;
|
||||||
|
for j in 0..m {
|
||||||
|
let mm = self.0[j].1.types.len();
|
||||||
|
self_tuple.push((self.0[j].0, &self.0[j].1.types[i1 % mm]));
|
||||||
|
i1 /= mm;
|
||||||
|
}
|
||||||
|
if i1 != 0 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
let mut covered = false;
|
||||||
|
for i2 in 0usize.. {
|
||||||
|
let mut remove_tuple = Vec::with_capacity(m);
|
||||||
|
let mut i2 = i2;
|
||||||
|
for j in 0..remove.0.len() {
|
||||||
|
let mm = remove.0[j].1.types.len();
|
||||||
|
remove_tuple.push((remove.0[j].0, &remove.0[j].1.types[i2 % mm]));
|
||||||
|
i2 /= mm;
|
||||||
|
}
|
||||||
|
if i2 != 0 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (0..m).all(|j| {
|
||||||
|
remove_tuple
|
||||||
|
.iter()
|
||||||
|
.find(|(v, _)| *v == self_tuple[j].0)
|
||||||
|
.is_none_or(|(_, r)| {
|
||||||
|
self_tuple[j].1.as_ref().is_included_in(r.as_ref())
|
||||||
|
})
|
||||||
|
}) {
|
||||||
|
covered = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !covered {
|
||||||
|
out.add(Arc::new(Self(
|
||||||
|
self_tuple
|
||||||
|
.iter()
|
||||||
|
.map(|(vi, v)| (*vi, Type::newm(vec![Arc::clone(v)])))
|
||||||
|
.collect(),
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(out)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fn as_any(&self) -> &dyn std::any::Any {
|
fn as_any(&self) -> &dyn std::any::Any {
|
||||||
self
|
self
|
||||||
@ -150,30 +204,6 @@ impl MersType for ObjectT {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ObjectT {
|
|
||||||
pub fn gen_subtypes_recursively(
|
|
||||||
&self,
|
|
||||||
acc: &mut Type,
|
|
||||||
types: &mut Vec<(usize, Arc<dyn MersType>)>,
|
|
||||||
) {
|
|
||||||
if types.len() >= self.len() {
|
|
||||||
let nt = Self(
|
|
||||||
types
|
|
||||||
.iter()
|
|
||||||
.map(|(s, v)| (s.clone(), Type::newm(vec![Arc::clone(v)])))
|
|
||||||
.collect(),
|
|
||||||
);
|
|
||||||
acc.add(Arc::new(nt));
|
|
||||||
} else {
|
|
||||||
for t in self.0[types.len()].1.subtypes_type().types {
|
|
||||||
types.push((self.0[types.len()].0.clone(), t));
|
|
||||||
self.gen_subtypes_recursively(acc, types);
|
|
||||||
types.pop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait ObjectFieldsMap {
|
pub trait ObjectFieldsMap {
|
||||||
fn get_or_add_field(&self, field: &str) -> usize;
|
fn get_or_add_field(&self, field: &str) -> usize;
|
||||||
}
|
}
|
||||||
|
@ -155,16 +155,11 @@ impl MersType for ReferenceT {
|
|||||||
// &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)
|
||||||
}
|
}
|
||||||
fn subtypes(&self, acc: &mut Type) {
|
fn without(&self, remove: &dyn MersType) -> Option<Type> {
|
||||||
// // we don't call subtypes because (int/string) must stay that so we can assign either
|
if self.is_included_in(remove) {
|
||||||
// // NOTE: this might not be right...?
|
Some(Type::empty())
|
||||||
// acc.add(Arc::new(self.clone()));
|
} else {
|
||||||
// FOR NOW (until we can put the compile-time type in ReferenceT), add all these types, too
|
None
|
||||||
// TODO: Figure out how to fix
|
|
||||||
// x := if true 1 else 0.5
|
|
||||||
// &x.debug // prints &Int instead of &{Int/Float} at runtime :(
|
|
||||||
for t in self.0.subtypes_type().types {
|
|
||||||
acc.add(Arc::new(Self(Type::newm(vec![t]))));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn as_any(&self) -> &dyn Any {
|
fn as_any(&self) -> &dyn Any {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use std::{any::Any, fmt::Display, sync::Arc};
|
use std::{any::Any, fmt::Display};
|
||||||
|
|
||||||
use crate::info::DisplayInfo;
|
use crate::info::DisplayInfo;
|
||||||
|
|
||||||
@ -51,8 +51,12 @@ impl MersType for StringT {
|
|||||||
fn is_included_in(&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 without(&self, remove: &dyn MersType) -> Option<Type> {
|
||||||
acc.add(Arc::new(self.clone()));
|
if self.is_included_in(remove) {
|
||||||
|
Some(Type::empty())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fn as_any(&self) -> &dyn Any {
|
fn as_any(&self) -> &dyn Any {
|
||||||
self
|
self
|
||||||
|
@ -107,8 +107,59 @@ impl MersType for TupleT {
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn subtypes(&self, acc: &mut Type) {
|
fn without(&self, remove: &dyn MersType) -> Option<Type> {
|
||||||
self.gen_subtypes_recursively(acc, &mut Vec::with_capacity(self.0.len()));
|
let m = self.0.len();
|
||||||
|
if let Some(remove) = remove
|
||||||
|
.as_any()
|
||||||
|
.downcast_ref::<Self>()
|
||||||
|
.filter(|r| r.0.len() == m)
|
||||||
|
{
|
||||||
|
let mut out = Type::empty();
|
||||||
|
for i1 in 0usize.. {
|
||||||
|
let mut self_tuple = Vec::with_capacity(m);
|
||||||
|
let mut i1 = i1;
|
||||||
|
for j in 0..m {
|
||||||
|
let mm = self.0[j].types.len();
|
||||||
|
self_tuple.push(&self.0[j].types[i1 % mm]);
|
||||||
|
i1 /= mm;
|
||||||
|
}
|
||||||
|
if i1 != 0 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
let mut covered = false;
|
||||||
|
for i2 in 0usize.. {
|
||||||
|
let mut remove_tuple = Vec::with_capacity(m);
|
||||||
|
let mut i2 = i2;
|
||||||
|
for j in 0..m {
|
||||||
|
let mm = remove.0[j].types.len();
|
||||||
|
remove_tuple.push(&remove.0[j].types[i2 % mm]);
|
||||||
|
i2 /= mm;
|
||||||
|
}
|
||||||
|
if i2 != 0 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (0..m).all(|j| {
|
||||||
|
self_tuple[j]
|
||||||
|
.as_ref()
|
||||||
|
.is_included_in(remove_tuple[j].as_ref())
|
||||||
|
}) {
|
||||||
|
covered = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !covered {
|
||||||
|
out.add(Arc::new(Self(
|
||||||
|
self_tuple
|
||||||
|
.iter()
|
||||||
|
.map(|v| Type::newm(vec![Arc::clone(v)]))
|
||||||
|
.collect(),
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(out)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fn as_any(&self) -> &dyn Any {
|
fn as_any(&self) -> &dyn Any {
|
||||||
self
|
self
|
||||||
@ -128,23 +179,3 @@ impl MersType for TupleT {
|
|||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TupleT {
|
|
||||||
pub fn gen_subtypes_recursively(&self, acc: &mut Type, types: &mut Vec<Arc<dyn MersType>>) {
|
|
||||||
if types.len() >= self.0.len() {
|
|
||||||
let nt = Self(
|
|
||||||
types
|
|
||||||
.iter()
|
|
||||||
.map(|v| Type::newm(vec![Arc::clone(v)]))
|
|
||||||
.collect(),
|
|
||||||
);
|
|
||||||
acc.add(Arc::new(nt));
|
|
||||||
} else {
|
|
||||||
for t in self.0[types.len()].subtypes_type().types {
|
|
||||||
types.push(t);
|
|
||||||
self.gen_subtypes_recursively(acc, types);
|
|
||||||
types.pop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -114,6 +114,68 @@ pub fn parse(
|
|||||||
let mut pos_after_first = src.get_pos();
|
let mut pos_after_first = src.get_pos();
|
||||||
loop {
|
loop {
|
||||||
src.skip_whitespace();
|
src.skip_whitespace();
|
||||||
|
// check for `arg [types] -> expr` function syntax
|
||||||
|
if let Some('[') = src.peek_char() {
|
||||||
|
let reset_no_func_pos = src.get_pos();
|
||||||
|
let _ = src.next_char();
|
||||||
|
let mut fixed_type = Vec::new();
|
||||||
|
loop {
|
||||||
|
src.skip_whitespace();
|
||||||
|
if let Ok(ty) = super::types::parse_type(src, srca) {
|
||||||
|
src.skip_whitespace();
|
||||||
|
if src.peek_word() == "->" {
|
||||||
|
src.next_word();
|
||||||
|
if let Ok(ot) = super::types::parse_type(src, srca) {
|
||||||
|
fixed_type.push((ty, Some(ot)));
|
||||||
|
} else {
|
||||||
|
fixed_type.clear();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fixed_type.push((ty, None));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fixed_type.clear();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
src.skip_whitespace();
|
||||||
|
match src.next_char() {
|
||||||
|
Some(']') => break,
|
||||||
|
Some(',') => continue,
|
||||||
|
_ => {
|
||||||
|
fixed_type.clear();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if fixed_type.is_empty() {
|
||||||
|
src.set_pos(reset_no_func_pos);
|
||||||
|
} else {
|
||||||
|
src.skip_whitespace();
|
||||||
|
let pos_in_src = src.get_pos();
|
||||||
|
if src.next_word() != "->" {
|
||||||
|
src.set_pos(reset_no_func_pos);
|
||||||
|
} else {
|
||||||
|
src.skip_whitespace();
|
||||||
|
let run = match parse(src, srca) {
|
||||||
|
Ok(Some(v)) => v,
|
||||||
|
Ok(None) => {
|
||||||
|
return Err(CheckError::new()
|
||||||
|
.src(vec![((pos_in_src, src.get_pos(), srca).into(), None)])
|
||||||
|
.msg_str(format!("EOF after `->`")))
|
||||||
|
}
|
||||||
|
Err(e) => return Err(e),
|
||||||
|
};
|
||||||
|
first = Box::new(program::parsed::function::Function {
|
||||||
|
pos_in_src: (first.source_range().start(), src.get_pos(), srca).into(),
|
||||||
|
arg: first,
|
||||||
|
run,
|
||||||
|
fixed_type: Some(fixed_type),
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
match src.peek_word_allow_colon() {
|
match src.peek_word_allow_colon() {
|
||||||
":=" => {
|
":=" => {
|
||||||
let pos_in_src = src.get_pos();
|
let pos_in_src = src.get_pos();
|
||||||
@ -164,6 +226,7 @@ pub fn parse(
|
|||||||
pos_in_src: (first.source_range().start(), src.get_pos(), srca).into(),
|
pos_in_src: (first.source_range().start(), src.get_pos(), srca).into(),
|
||||||
arg: first,
|
arg: first,
|
||||||
run,
|
run,
|
||||||
|
fixed_type: None,
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,8 @@ pub fn to_mers_func(
|
|||||||
data::function::Function {
|
data::function::Function {
|
||||||
info: Info::neverused(),
|
info: Info::neverused(),
|
||||||
info_check: Arc::new(Mutex::new(Info::neverused())),
|
info_check: Arc::new(Mutex::new(Info::neverused())),
|
||||||
|
fixed_type: None,
|
||||||
|
fixed_type_out: Arc::new(Mutex::new(None)),
|
||||||
out: Ok(Arc::new(move |a, i| out(a, i))),
|
out: Ok(Arc::new(move |a, i| out(a, i))),
|
||||||
run: Arc::new(move |a, i| run(a, i)),
|
run: Arc::new(move |a, i| run(a, i)),
|
||||||
inner_statements: None,
|
inner_statements: None,
|
||||||
|
@ -30,6 +30,8 @@ impl Config {
|
|||||||
.add_var("lock_update", data::function::Function {
|
.add_var("lock_update", data::function::Function {
|
||||||
info: Info::neverused(),
|
info: Info::neverused(),
|
||||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||||
|
fixed_type: None,
|
||||||
|
fixed_type_out: Arc::new(Mutex::new(None)),
|
||||||
out: Ok(Arc::new(|a, i| {
|
out: Ok(Arc::new(|a, i| {
|
||||||
for t in a.types.iter() {
|
for t in a.types.iter() {
|
||||||
if let Some(t) = t.as_any().downcast_ref::<data::tuple::TupleT>() {
|
if let Some(t) = t.as_any().downcast_ref::<data::tuple::TupleT>() {
|
||||||
@ -95,6 +97,8 @@ impl Config {
|
|||||||
data::function::Function {
|
data::function::Function {
|
||||||
info: Info::neverused(),
|
info: Info::neverused(),
|
||||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||||
|
fixed_type: None,
|
||||||
|
fixed_type_out: Arc::new(Mutex::new(None)),
|
||||||
out: Ok(Arc::new(|a, i| {
|
out: Ok(Arc::new(|a, i| {
|
||||||
for t in &a.types {
|
for t in &a.types {
|
||||||
if t.as_any().downcast_ref::<data::string::StringT>().is_none() && t.as_any().downcast_ref::<data::tuple::TupleT>().is_none() && t.iterable().is_none() {
|
if t.as_any().downcast_ref::<data::string::StringT>().is_none() && t.as_any().downcast_ref::<data::tuple::TupleT>().is_none() && t.iterable().is_none() {
|
||||||
@ -122,6 +126,8 @@ impl Config {
|
|||||||
data::function::Function {
|
data::function::Function {
|
||||||
info: Info::neverused(),
|
info: Info::neverused(),
|
||||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||||
|
fixed_type: None,
|
||||||
|
fixed_type_out: Arc::new(Mutex::new(None)),
|
||||||
out: Ok(Arc::new(|a, _i| {
|
out: Ok(Arc::new(|a, _i| {
|
||||||
for t in &a.types {
|
for t in &a.types {
|
||||||
if t.iterable().is_none() {
|
if t.iterable().is_none() {
|
||||||
@ -158,6 +164,8 @@ impl Config {
|
|||||||
data::function::Function {
|
data::function::Function {
|
||||||
info: Info::neverused(),
|
info: Info::neverused(),
|
||||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||||
|
fixed_type: None,
|
||||||
|
fixed_type_out: Arc::new(Mutex::new(None)),
|
||||||
out: Ok(Arc::new(|a, _i| Ok(Type::new(data::reference::ReferenceT(a.clone()))))),
|
out: Ok(Arc::new(|a, _i| Ok(Type::new(data::reference::ReferenceT(a.clone()))))),
|
||||||
run: Arc::new(|a, _i| {
|
run: Arc::new(|a, _i| {
|
||||||
Ok(Data::new(data::reference::Reference(Arc::new(RwLock::new(a.clone())))))
|
Ok(Data::new(data::reference::Reference(Arc::new(RwLock::new(a.clone())))))
|
||||||
@ -170,6 +178,8 @@ impl Config {
|
|||||||
data::function::Function {
|
data::function::Function {
|
||||||
info: Info::neverused(),
|
info: Info::neverused(),
|
||||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||||
|
fixed_type: None,
|
||||||
|
fixed_type_out: Arc::new(Mutex::new(None)),
|
||||||
out: Ok(Arc::new(|a, i| if let Some(v) = a.dereference() { Ok(v) } else { Err(format!("cannot dereference type {}", a.with_info(i)).into())
|
out: Ok(Arc::new(|a, i| if let Some(v) = a.dereference() { Ok(v) } else { Err(format!("cannot dereference type {}", a.with_info(i)).into())
|
||||||
})),
|
})),
|
||||||
run: Arc::new(|a, _i| {
|
run: Arc::new(|a, _i| {
|
||||||
|
@ -34,6 +34,8 @@ impl Config {
|
|||||||
data::function::Function {
|
data::function::Function {
|
||||||
info: program::run::Info::neverused(),
|
info: program::run::Info::neverused(),
|
||||||
info_check: Arc::new(Mutex::new( CheckInfo::neverused())),
|
info_check: Arc::new(Mutex::new( CheckInfo::neverused())),
|
||||||
|
fixed_type: None,
|
||||||
|
fixed_type_out: Arc::new(Mutex::new(None)),
|
||||||
out: Ok(Arc::new(|a, i| {
|
out: Ok(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_single(&data::string::StringT) && t.0[1].iterable().is_some_and(|t| t.is_included_in_single(&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![
|
||||||
@ -89,6 +91,8 @@ impl Config {
|
|||||||
data::function::Function {
|
data::function::Function {
|
||||||
info: program::run::Info::neverused(),
|
info: program::run::Info::neverused(),
|
||||||
info_check: Arc::new(Mutex::new( CheckInfo::neverused())),
|
info_check: Arc::new(Mutex::new( CheckInfo::neverused())),
|
||||||
|
fixed_type: None,
|
||||||
|
fixed_type_out: Arc::new(Mutex::new(None)),
|
||||||
out: Ok(Arc::new(|a, i| {
|
out: Ok(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_single(&data::string::StringT) && t.0[1].iterable().is_some_and(|t| t.is_included_in_single(&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![
|
||||||
@ -133,6 +137,8 @@ impl Config {
|
|||||||
data::function::Function {
|
data::function::Function {
|
||||||
info: program::run::Info::neverused(),
|
info: program::run::Info::neverused(),
|
||||||
info_check: Arc::new(Mutex::new( CheckInfo::neverused())),
|
info_check: Arc::new(Mutex::new( CheckInfo::neverused())),
|
||||||
|
fixed_type: None,
|
||||||
|
fixed_type_out: Arc::new(Mutex::new(None)),
|
||||||
out: Ok(Arc::new(|a, i| {
|
out: Ok(Arc::new(|a, i| {
|
||||||
if a.is_included_in_single(&ChildProcessT) {
|
if a.is_included_in_single(&ChildProcessT) {
|
||||||
Ok(Type::newm(vec![
|
Ok(Type::newm(vec![
|
||||||
@ -161,6 +167,8 @@ impl Config {
|
|||||||
data::function::Function {
|
data::function::Function {
|
||||||
info: program::run::Info::neverused(),
|
info: program::run::Info::neverused(),
|
||||||
info_check: Arc::new(Mutex::new( CheckInfo::neverused())),
|
info_check: Arc::new(Mutex::new( CheckInfo::neverused())),
|
||||||
|
fixed_type: None,
|
||||||
|
fixed_type_out: Arc::new(Mutex::new(None)),
|
||||||
out: Ok(Arc::new(|a, i| {
|
out: Ok(Arc::new(|a, i| {
|
||||||
if a.is_included_in_single(&ChildProcessT) {
|
if a.is_included_in_single(&ChildProcessT) {
|
||||||
Ok(Type::newm(vec![
|
Ok(Type::newm(vec![
|
||||||
@ -195,6 +203,8 @@ impl Config {
|
|||||||
data::function::Function {
|
data::function::Function {
|
||||||
info: program::run::Info::neverused(),
|
info: program::run::Info::neverused(),
|
||||||
info_check: Arc::new(Mutex::new( CheckInfo::neverused())),
|
info_check: Arc::new(Mutex::new( CheckInfo::neverused())),
|
||||||
|
fixed_type: None,
|
||||||
|
fixed_type_out: Arc::new(Mutex::new(None)),
|
||||||
out: Ok(Arc::new(|a, i| {
|
out: Ok(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_single(&ChildProcessT) && t.0[1].iterable().is_some_and(|i| i.is_included_in_single(&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(data::bool::bool_type())
|
Ok(data::bool::bool_type())
|
||||||
@ -224,6 +234,8 @@ impl Config {
|
|||||||
data::function::Function {
|
data::function::Function {
|
||||||
info: program::run::Info::neverused(),
|
info: program::run::Info::neverused(),
|
||||||
info_check: Arc::new(Mutex::new( CheckInfo::neverused())),
|
info_check: Arc::new(Mutex::new( CheckInfo::neverused())),
|
||||||
|
fixed_type: None,
|
||||||
|
fixed_type_out: Arc::new(Mutex::new(None)),
|
||||||
out: Ok(Arc::new(|a, i| {
|
out: Ok(Arc::new(|a, i| {
|
||||||
if a.is_included_in_single(&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(data::bool::bool_type())
|
Ok(data::bool::bool_type())
|
||||||
@ -253,6 +265,8 @@ impl Config {
|
|||||||
data::function::Function {
|
data::function::Function {
|
||||||
info: program::run::Info::neverused(),
|
info: program::run::Info::neverused(),
|
||||||
info_check: Arc::new(Mutex::new( CheckInfo::neverused())),
|
info_check: Arc::new(Mutex::new( CheckInfo::neverused())),
|
||||||
|
fixed_type: None,
|
||||||
|
fixed_type_out: Arc::new(Mutex::new(None)),
|
||||||
out: Ok(Arc::new(|a, i| {
|
out: Ok(Arc::new(|a, i| {
|
||||||
if a.is_included_in_single(&ChildProcessT) {
|
if a.is_included_in_single(&ChildProcessT) {
|
||||||
Ok(Type::newm(vec![
|
Ok(Type::newm(vec![
|
||||||
@ -282,6 +296,8 @@ impl Config {
|
|||||||
data::function::Function {
|
data::function::Function {
|
||||||
info: program::run::Info::neverused(),
|
info: program::run::Info::neverused(),
|
||||||
info_check: Arc::new(Mutex::new( CheckInfo::neverused())),
|
info_check: Arc::new(Mutex::new( CheckInfo::neverused())),
|
||||||
|
fixed_type: None,
|
||||||
|
fixed_type_out: Arc::new(Mutex::new(None)),
|
||||||
out: Ok(Arc::new(|a, i| {
|
out: Ok(Arc::new(|a, i| {
|
||||||
if a.is_included_in_single(&ChildProcessT) {
|
if a.is_included_in_single(&ChildProcessT) {
|
||||||
Ok(Type::newm(vec![
|
Ok(Type::newm(vec![
|
||||||
@ -311,6 +327,8 @@ impl Config {
|
|||||||
data::function::Function {
|
data::function::Function {
|
||||||
info: program::run::Info::neverused(),
|
info: program::run::Info::neverused(),
|
||||||
info_check: Arc::new(Mutex::new( CheckInfo::neverused())),
|
info_check: Arc::new(Mutex::new( CheckInfo::neverused())),
|
||||||
|
fixed_type: None,
|
||||||
|
fixed_type_out: Arc::new(Mutex::new(None)),
|
||||||
out: Ok(Arc::new(|a, i| {
|
out: Ok(Arc::new(|a, i| {
|
||||||
if a.is_included_in_single(&ChildProcessT) {
|
if a.is_included_in_single(&ChildProcessT) {
|
||||||
Ok(Type::newm(vec![
|
Ok(Type::newm(vec![
|
||||||
@ -340,6 +358,8 @@ impl Config {
|
|||||||
data::function::Function {
|
data::function::Function {
|
||||||
info: program::run::Info::neverused(),
|
info: program::run::Info::neverused(),
|
||||||
info_check: Arc::new(Mutex::new( CheckInfo::neverused())),
|
info_check: Arc::new(Mutex::new( CheckInfo::neverused())),
|
||||||
|
fixed_type: None,
|
||||||
|
fixed_type_out: Arc::new(Mutex::new(None)),
|
||||||
out: Ok(Arc::new(|a, i| {
|
out: Ok(Arc::new(|a, i| {
|
||||||
if a.is_included_in_single(&ChildProcessT) {
|
if a.is_included_in_single(&ChildProcessT) {
|
||||||
Ok(Type::newm(vec![
|
Ok(Type::newm(vec![
|
||||||
@ -431,8 +451,12 @@ impl MersType for ChildProcessT {
|
|||||||
fn is_included_in(&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 without(&self, remove: &dyn MersType) -> Option<Type> {
|
||||||
acc.add(Arc::new(self.clone()));
|
if self.is_included_in(remove) {
|
||||||
|
Some(Type::empty())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fn as_any(&self) -> &dyn std::any::Any {
|
fn as_any(&self) -> &dyn std::any::Any {
|
||||||
self
|
self
|
||||||
|
@ -15,6 +15,8 @@ impl Config {
|
|||||||
data::function::Function {
|
data::function::Function {
|
||||||
info: program::run::Info::neverused(),
|
info: program::run::Info::neverused(),
|
||||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||||
|
fixed_type: None,
|
||||||
|
fixed_type_out: Arc::new(Mutex::new(None)),
|
||||||
out: Ok(Arc::new(|a, i| {
|
out: Ok(Arc::new(|a, i| {
|
||||||
let mut out = Type::empty();
|
let mut out = Type::empty();
|
||||||
for a in a.types.iter() {
|
for a in a.types.iter() {
|
||||||
|
@ -144,6 +144,8 @@ impl Config {
|
|||||||
data::function::Function {
|
data::function::Function {
|
||||||
info: program::run::Info::neverused(),
|
info: program::run::Info::neverused(),
|
||||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||||
|
fixed_type: None,
|
||||||
|
fixed_type_out: Arc::new(Mutex::new(None)),
|
||||||
out: Ok(Arc::new(|a, i| {
|
out: Ok(Arc::new(|a, i| {
|
||||||
for a in &a.types {
|
for a in &a.types {
|
||||||
if let Some(tuple) = a.as_any().downcast_ref::<data::tuple::TupleT>() {
|
if let Some(tuple) = a.as_any().downcast_ref::<data::tuple::TupleT>() {
|
||||||
@ -229,6 +231,8 @@ impl Config {
|
|||||||
data::function::Function {
|
data::function::Function {
|
||||||
info: program::run::Info::neverused(),
|
info: program::run::Info::neverused(),
|
||||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||||
|
fixed_type: None,
|
||||||
|
fixed_type_out: Arc::new(Mutex::new(None)),
|
||||||
out: Ok(Arc::new(|a, i| {
|
out: Ok(Arc::new(|a, i| {
|
||||||
let data = if let Some(a) = a.iterable() {
|
let data = if let Some(a) = a.iterable() {
|
||||||
a
|
a
|
||||||
@ -246,6 +250,8 @@ impl Config {
|
|||||||
data::function::Function {
|
data::function::Function {
|
||||||
info: program::run::Info::neverused(),
|
info: program::run::Info::neverused(),
|
||||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||||
|
fixed_type: None,
|
||||||
|
fixed_type_out: Arc::new(Mutex::new(None)),
|
||||||
out: Ok(Arc::new(|a, i| {
|
out: Ok(Arc::new(|a, i| {
|
||||||
let data = if let Some(a) = a.iterable() {
|
let data = if let Some(a) = a.iterable() {
|
||||||
a
|
a
|
||||||
@ -301,6 +307,8 @@ fn genfunc_iter_and_func(
|
|||||||
data::function::Function {
|
data::function::Function {
|
||||||
info: program::run::Info::neverused(),
|
info: program::run::Info::neverused(),
|
||||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||||
|
fixed_type: None,
|
||||||
|
fixed_type_out: Arc::new(Mutex::new(None)),
|
||||||
out: Ok(Arc::new(move |a, i| iter_out_arg(a, i, name, |f| ft(f)))),
|
out: Ok(Arc::new(move |a, i| iter_out_arg(a, i, name, |f| ft(f)))),
|
||||||
run: Arc::new(move |a, _i| {
|
run: Arc::new(move |a, _i| {
|
||||||
if let Some(tuple) = a.get().as_any().downcast_ref::<data::tuple::Tuple>() {
|
if let Some(tuple) = a.get().as_any().downcast_ref::<data::tuple::Tuple>() {
|
||||||
@ -359,6 +367,8 @@ fn genfunc_iter_and_arg<T: MersType, D: MersData>(
|
|||||||
data::function::Function {
|
data::function::Function {
|
||||||
info: program::run::Info::neverused(),
|
info: program::run::Info::neverused(),
|
||||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||||
|
fixed_type: None,
|
||||||
|
fixed_type_out: Arc::new(Mutex::new(None)),
|
||||||
out: Ok(Arc::new(move |a, i| {
|
out: Ok(Arc::new(move |a, i| {
|
||||||
iter_out_arg(a, i, name, |f: &T| ft(f), type_sample)
|
iter_out_arg(a, i, name, |f: &T| ft(f), type_sample)
|
||||||
})),
|
})),
|
||||||
@ -607,13 +617,16 @@ impl MersType for IterT {
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fn without(&self, remove: &dyn MersType) -> Option<Type> {
|
||||||
|
if self.is_included_in(remove) {
|
||||||
|
Some(Type::empty())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
fn iterable(&self) -> Option<Type> {
|
fn iterable(&self) -> Option<Type> {
|
||||||
Some(self.2.clone())
|
Some(self.2.clone())
|
||||||
}
|
}
|
||||||
fn subtypes(&self, acc: &mut Type) {
|
|
||||||
// NOTE: This might not be good enough
|
|
||||||
acc.add(Arc::new(self.clone()));
|
|
||||||
}
|
|
||||||
fn as_any(&self) -> &dyn std::any::Any {
|
fn as_any(&self) -> &dyn std::any::Any {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@ -655,6 +668,8 @@ fn genfunc_iter_in_val_out(
|
|||||||
Function {
|
Function {
|
||||||
info: crate::info::Info::neverused(),
|
info: crate::info::Info::neverused(),
|
||||||
info_check: Arc::new(Mutex::new(crate::info::Info::neverused())),
|
info_check: Arc::new(Mutex::new(crate::info::Info::neverused())),
|
||||||
|
fixed_type: None,
|
||||||
|
fixed_type_out: Arc::new(Mutex::new(None)),
|
||||||
out: Ok(Arc::new(move |a, i| {
|
out: Ok(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(&iter_type) {
|
||||||
@ -748,8 +763,12 @@ impl MersType for RangeT {
|
|||||||
self.is_empty() || (!target.is_empty() && self.0 >= target.0 && self.1 <= target.1)
|
self.is_empty() || (!target.is_empty() && self.0 >= target.0 && self.1 <= target.1)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
fn subtypes(&self, acc: &mut Type) {
|
fn without(&self, remove: &dyn MersType) -> Option<Type> {
|
||||||
acc.add(Arc::new(Clone::clone(self)))
|
if self.is_included_in(remove) {
|
||||||
|
Some(Type::empty())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fn as_any(&self) -> &dyn std::any::Any {
|
fn as_any(&self) -> &dyn std::any::Any {
|
||||||
self
|
self
|
||||||
|
@ -37,6 +37,8 @@ impl Config {
|
|||||||
data::function::Function {
|
data::function::Function {
|
||||||
info: program::run::Info::neverused(),
|
info: program::run::Info::neverused(),
|
||||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||||
|
fixed_type: None,
|
||||||
|
fixed_type_out: Arc::new(Mutex::new(None)),
|
||||||
out: Ok(Arc::new(|a, i| {
|
out: Ok(Arc::new(|a, i| {
|
||||||
if let Some(a) = a.dereference() {
|
if let Some(a) = a.dereference() {
|
||||||
let mut out = Type::empty();
|
let mut out = Type::empty();
|
||||||
@ -85,6 +87,8 @@ impl Config {
|
|||||||
data::function::Function {
|
data::function::Function {
|
||||||
info: program::run::Info::neverused(),
|
info: program::run::Info::neverused(),
|
||||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||||
|
fixed_type: None,
|
||||||
|
fixed_type_out: Arc::new(Mutex::new(None)),
|
||||||
out: Ok(Arc::new(|a, i| {
|
out: Ok(Arc::new(|a, i| {
|
||||||
for t in a.types.iter() {
|
for t in a.types.iter() {
|
||||||
if let Some(t) = t.as_any().downcast_ref::<data::tuple::TupleT>() {
|
if let Some(t) = t.as_any().downcast_ref::<data::tuple::TupleT>() {
|
||||||
@ -148,6 +152,8 @@ impl Config {
|
|||||||
data::function::Function {
|
data::function::Function {
|
||||||
info: program::run::Info::neverused(),
|
info: program::run::Info::neverused(),
|
||||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||||
|
fixed_type: None,
|
||||||
|
fixed_type_out: Arc::new(Mutex::new(None)),
|
||||||
out: Ok(Arc::new(|a, i| {
|
out: Ok(Arc::new(|a, i| {
|
||||||
for t in a.types.iter() {
|
for t in a.types.iter() {
|
||||||
if let Some(t) = t.as_any().downcast_ref::<data::tuple::TupleT>() {
|
if let Some(t) = t.as_any().downcast_ref::<data::tuple::TupleT>() {
|
||||||
@ -221,6 +227,8 @@ impl Config {
|
|||||||
data::function::Function {
|
data::function::Function {
|
||||||
info: program::run::Info::neverused(),
|
info: program::run::Info::neverused(),
|
||||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||||
|
fixed_type: None,
|
||||||
|
fixed_type_out: Arc::new(Mutex::new(None)),
|
||||||
out: Ok(Arc::new(|a, i| {
|
out: Ok(Arc::new(|a, i| {
|
||||||
let mut o = Type::empty();
|
let mut o = Type::empty();
|
||||||
for t in a.types.iter() {
|
for t in a.types.iter() {
|
||||||
@ -298,6 +306,8 @@ impl Config {
|
|||||||
data::function::Function {
|
data::function::Function {
|
||||||
info: program::run::Info::neverused(),
|
info: program::run::Info::neverused(),
|
||||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||||
|
fixed_type: None,
|
||||||
|
fixed_type_out: Arc::new(Mutex::new(None)),
|
||||||
out: Ok(Arc::new(|a, i| {
|
out: Ok(Arc::new(|a, i| {
|
||||||
let mut o = Type::empty();
|
let mut o = Type::empty();
|
||||||
for t in a.types.iter() {
|
for t in a.types.iter() {
|
||||||
@ -369,6 +379,8 @@ impl Config {
|
|||||||
data::function::Function {
|
data::function::Function {
|
||||||
info: program::run::Info::neverused(),
|
info: program::run::Info::neverused(),
|
||||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||||
|
fixed_type: None,
|
||||||
|
fixed_type_out: Arc::new(Mutex::new(None)),
|
||||||
out: Ok(Arc::new(|a, i| {
|
out: Ok(Arc::new(|a, i| {
|
||||||
if let Some(v) = a.iterable() {
|
if let Some(v) = a.iterable() {
|
||||||
Ok(Type::new(ListT(v)))
|
Ok(Type::new(ListT(v)))
|
||||||
@ -464,12 +476,11 @@ impl MersType for ListT {
|
|||||||
.downcast_ref::<Self>()
|
.downcast_ref::<Self>()
|
||||||
.is_some_and(|v| self.0.is_included_in(&v.0))
|
.is_some_and(|v| self.0.is_included_in(&v.0))
|
||||||
}
|
}
|
||||||
fn subtypes(&self, acc: &mut Type) {
|
fn without(&self, remove: &dyn MersType) -> Option<Type> {
|
||||||
// The type of an empty list is a list where the items are `<unreachable>`
|
if self.is_included_in(remove) {
|
||||||
acc.add(Arc::new(Self(Type::empty())));
|
Some(Type::empty())
|
||||||
// All possible list types
|
} else {
|
||||||
for t in self.0.subtypes_type().types {
|
None
|
||||||
acc.add(Arc::new(Self(Type::newm(vec![t]))));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn as_any(&self) -> &dyn std::any::Any {
|
fn as_any(&self) -> &dyn std::any::Any {
|
||||||
|
@ -33,6 +33,8 @@ impl Config {
|
|||||||
data::function::Function {
|
data::function::Function {
|
||||||
info: program::run::Info::neverused(),
|
info: program::run::Info::neverused(),
|
||||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||||
|
fixed_type: None,
|
||||||
|
fixed_type_out: Arc::new(Mutex::new(None)),
|
||||||
out: Ok(Arc::new(|a, _i| {
|
out: Ok(Arc::new(|a, _i| {
|
||||||
let mut out = Type::empty();
|
let mut out = Type::empty();
|
||||||
for t in a.types.iter() {
|
for t in a.types.iter() {
|
||||||
@ -59,6 +61,8 @@ impl Config {
|
|||||||
.add_var("thread_finished", data::function::Function {
|
.add_var("thread_finished", data::function::Function {
|
||||||
info: program::run::Info::neverused(),
|
info: program::run::Info::neverused(),
|
||||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||||
|
fixed_type: None,
|
||||||
|
fixed_type_out: Arc::new(Mutex::new(None)),
|
||||||
out: Ok(Arc::new(|a, i| {
|
out: Ok(Arc::new(|a, i| {
|
||||||
for t in a.types.iter() {
|
for t in a.types.iter() {
|
||||||
if !t.as_any().is::<ThreadT>() {
|
if !t.as_any().is::<ThreadT>() {
|
||||||
@ -80,6 +84,8 @@ impl Config {
|
|||||||
.add_var("thread_await", data::function::Function {
|
.add_var("thread_await", data::function::Function {
|
||||||
info: program::run::Info::neverused(),
|
info: program::run::Info::neverused(),
|
||||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||||
|
fixed_type: None,
|
||||||
|
fixed_type_out: Arc::new(Mutex::new(None)),
|
||||||
out: Ok(Arc::new(|a, i| {
|
out: Ok(Arc::new(|a, i| {
|
||||||
let mut out = Type::empty();
|
let mut out = Type::empty();
|
||||||
for t in a.types.iter() {
|
for t in a.types.iter() {
|
||||||
@ -162,9 +168,11 @@ impl MersType for ThreadT {
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn subtypes(&self, acc: &mut Type) {
|
fn without(&self, remove: &dyn MersType) -> Option<Type> {
|
||||||
for t in self.0.subtypes_type().types {
|
if self.is_included_in(remove) {
|
||||||
acc.add(Arc::new(Self(Type::newm(vec![t]))));
|
Some(Type::empty())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn as_any(&self) -> &dyn std::any::Any {
|
fn as_any(&self) -> &dyn std::any::Any {
|
||||||
|
@ -91,6 +91,8 @@ impl Config {
|
|||||||
data::function::Function {
|
data::function::Function {
|
||||||
info: program::run::Info::neverused(),
|
info: program::run::Info::neverused(),
|
||||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||||
|
fixed_type: None,
|
||||||
|
fixed_type_out: Arc::new(Mutex::new(None)),
|
||||||
out: Ok(Arc::new(|a, _i| Ok(a.clone()))),
|
out: Ok(Arc::new(|a, _i| Ok(a.clone()))),
|
||||||
run: Arc::new(|a, i| {
|
run: Arc::new(|a, i| {
|
||||||
let a2 = a.get();
|
let a2 = a.get();
|
||||||
@ -114,6 +116,8 @@ impl Config {
|
|||||||
data::function::Function {
|
data::function::Function {
|
||||||
info: program::run::Info::neverused(),
|
info: program::run::Info::neverused(),
|
||||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||||
|
fixed_type: None,
|
||||||
|
fixed_type_out: Arc::new(Mutex::new(None)),
|
||||||
out: Ok(Arc::new(|_a, _i| Ok(Type::empty_tuple()))),
|
out: Ok(Arc::new(|_a, _i| Ok(Type::empty_tuple()))),
|
||||||
run: Arc::new(|a, i| {
|
run: Arc::new(|a, i| {
|
||||||
if let Some((_, stderr)) = &mut *i.global.stdout.lock().unwrap() {
|
if let Some((_, stderr)) = &mut *i.global.stdout.lock().unwrap() {
|
||||||
@ -133,6 +137,8 @@ impl Config {
|
|||||||
data::function::Function {
|
data::function::Function {
|
||||||
info: program::run::Info::neverused(),
|
info: program::run::Info::neverused(),
|
||||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||||
|
fixed_type: None,
|
||||||
|
fixed_type_out: Arc::new(Mutex::new(None)),
|
||||||
out: Ok(Arc::new(|_a, _i| Ok(Type::empty_tuple()))),
|
out: Ok(Arc::new(|_a, _i| Ok(Type::empty_tuple()))),
|
||||||
run: Arc::new(|a, i| {
|
run: Arc::new(|a, i| {
|
||||||
if let Some((_, stderr)) = &mut *i.global.stdout.lock().unwrap() {
|
if let Some((_, stderr)) = &mut *i.global.stdout.lock().unwrap() {
|
||||||
@ -151,6 +157,8 @@ impl Config {
|
|||||||
data::function::Function {
|
data::function::Function {
|
||||||
info: program::run::Info::neverused(),
|
info: program::run::Info::neverused(),
|
||||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||||
|
fixed_type: None,
|
||||||
|
fixed_type_out: Arc::new(Mutex::new(None)),
|
||||||
out: Ok(Arc::new(|_a, _i| Ok(Type::empty_tuple()))),
|
out: Ok(Arc::new(|_a, _i| Ok(Type::empty_tuple()))),
|
||||||
run: Arc::new(|a, i| {
|
run: Arc::new(|a, i| {
|
||||||
if let Some((stdout, _)) = &mut *i.global.stdout.lock().unwrap() {
|
if let Some((stdout, _)) = &mut *i.global.stdout.lock().unwrap() {
|
||||||
@ -170,6 +178,8 @@ impl Config {
|
|||||||
data::function::Function {
|
data::function::Function {
|
||||||
info: program::run::Info::neverused(),
|
info: program::run::Info::neverused(),
|
||||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||||
|
fixed_type: None,
|
||||||
|
fixed_type_out: Arc::new(Mutex::new(None)),
|
||||||
out: Ok(Arc::new(|_a, _i| Ok(Type::empty_tuple()))),
|
out: Ok(Arc::new(|_a, _i| Ok(Type::empty_tuple()))),
|
||||||
run: Arc::new(|a, i| {
|
run: Arc::new(|a, i| {
|
||||||
if let Some((stdout, _)) = &mut *i.global.stdout.lock().unwrap() {
|
if let Some((stdout, _)) = &mut *i.global.stdout.lock().unwrap() {
|
||||||
|
@ -3,6 +3,7 @@ use std::sync::{Arc, Mutex};
|
|||||||
use crate::{
|
use crate::{
|
||||||
data,
|
data,
|
||||||
errors::{CheckError, SourceRange},
|
errors::{CheckError, SourceRange},
|
||||||
|
parsing::types::ParsedType,
|
||||||
program::{self, run::CheckInfo},
|
program::{self, run::CheckInfo},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -13,6 +14,7 @@ pub struct Function {
|
|||||||
pub pos_in_src: SourceRange,
|
pub pos_in_src: SourceRange,
|
||||||
pub arg: Box<dyn MersStatement>,
|
pub arg: Box<dyn MersStatement>,
|
||||||
pub run: Box<dyn MersStatement>,
|
pub run: Box<dyn MersStatement>,
|
||||||
|
pub fixed_type: Option<Vec<(Vec<ParsedType>, Option<Vec<ParsedType>>)>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MersStatement for Function {
|
impl MersStatement for Function {
|
||||||
@ -38,6 +40,8 @@ impl MersStatement for Function {
|
|||||||
func_no_info: data::function::Function {
|
func_no_info: data::function::Function {
|
||||||
info: program::run::Info::neverused(),
|
info: program::run::Info::neverused(),
|
||||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||||
|
fixed_type: self.fixed_type.clone(),
|
||||||
|
fixed_type_out: Arc::new(Mutex::new(None)),
|
||||||
out: Ok(Arc::new(move |a, i| {
|
out: Ok(Arc::new(move |a, i| {
|
||||||
arg2.check(i, Some(a))?;
|
arg2.check(i, Some(a))?;
|
||||||
Ok(run2.check(i, None)?)
|
Ok(run2.check(i, None)?)
|
||||||
|
@ -56,6 +56,8 @@ impl MersStatement for IncludeMers {
|
|||||||
func_no_info: data::function::Function {
|
func_no_info: data::function::Function {
|
||||||
info: info::Info::neverused(),
|
info: info::Info::neverused(),
|
||||||
info_check: Arc::new(Mutex::new(info::Info::neverused())),
|
info_check: Arc::new(Mutex::new(info::Info::neverused())),
|
||||||
|
fixed_type: None,
|
||||||
|
fixed_type_out: Arc::new(Mutex::new(None)),
|
||||||
out: Ok(Arc::new(move |_, i| {
|
out: Ok(Arc::new(move |_, i| {
|
||||||
compiled.check(&mut i.duplicate(), None)
|
compiled.check(&mut i.duplicate(), None)
|
||||||
})),
|
})),
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use std::sync::{Arc, Mutex};
|
use std::sync::Mutex;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
data::{self, Data, Type},
|
data::{self, Data, Type},
|
||||||
@ -25,7 +25,7 @@ impl MersStatement for Try {
|
|||||||
return Err("can't init to statement type Try".to_string().into());
|
return Err("can't init to statement type Try".to_string().into());
|
||||||
}
|
}
|
||||||
let mut t = Type::empty();
|
let mut t = Type::empty();
|
||||||
let arg = self.arg.check(info, init_to)?;
|
let mut arg = self.arg.check(info, init_to)?;
|
||||||
let funcs = self
|
let funcs = self
|
||||||
.funcs
|
.funcs
|
||||||
.iter()
|
.iter()
|
||||||
@ -46,62 +46,75 @@ impl MersStatement for Try {
|
|||||||
};
|
};
|
||||||
drop(unused_try_statements_lock);
|
drop(unused_try_statements_lock);
|
||||||
drop(index_lock);
|
drop(index_lock);
|
||||||
for arg in arg.subtypes_type().types.iter() {
|
'func_options: for (i, func) in funcs.iter().enumerate() {
|
||||||
let mut found = false;
|
// TODO! handle the case where a function is a one-of-multiple type...
|
||||||
let mut errs = vec![];
|
if func.types.len() != 1 {
|
||||||
for (i, func) in funcs.iter().enumerate() {
|
return Err(format!(
|
||||||
let mut func_res = Type::empty();
|
"Try-statement requires clearly defined functions, but got type {}",
|
||||||
let mut func_err = None;
|
func.with_info(info)
|
||||||
for ft in func.types.iter() {
|
)
|
||||||
if let Some(ft) = ft.executable() {
|
.into());
|
||||||
match ft.o(&Type::newm(vec![Arc::clone(arg)])) {
|
}
|
||||||
Ok(res) => {
|
for ft in func.types.iter() {
|
||||||
func_res.add_all(&res);
|
if let Some(ft) = ft.executable() {
|
||||||
}
|
let using_func = |t: &mut Type, func_res: &Type| {
|
||||||
Err(e) => func_err = Some(e),
|
// found the function to use
|
||||||
|
info.global.unused_try_statements.lock().unwrap()[my_index].1[i] = None;
|
||||||
|
t.add_all(func_res);
|
||||||
|
};
|
||||||
|
match ft.o_try(&arg) {
|
||||||
|
Ok(res) => {
|
||||||
|
using_func(&mut t, &res);
|
||||||
|
arg = Type::empty();
|
||||||
|
break 'func_options;
|
||||||
|
}
|
||||||
|
Err((_, covered)) => {
|
||||||
|
for (t_in, t_out) in &covered {
|
||||||
|
arg.without_in_place_all(t_in);
|
||||||
|
using_func(&mut t, t_out);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
return Err(CheckError::new()
|
|
||||||
.msg_str(format!(
|
|
||||||
"try: #{} is not a function, type is {} within {}.",
|
|
||||||
i + 1,
|
|
||||||
ft.simplified_as_string(info),
|
|
||||||
func.simplify_for_display(info).with_info(info),
|
|
||||||
))
|
|
||||||
.src(vec![
|
|
||||||
(self.source_range(), None),
|
|
||||||
(self.funcs[i].source_range(), Some(EColor::TryNotAFunction)),
|
|
||||||
]));
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if let Some(err) = func_err {
|
|
||||||
// can't use this function for this argument
|
|
||||||
errs.push(err);
|
|
||||||
} else {
|
} else {
|
||||||
// found the function to use
|
return Err(CheckError::new()
|
||||||
info.global.unused_try_statements.lock().unwrap()[my_index].1[i] = None;
|
.msg_str(format!(
|
||||||
found = true;
|
"try: #{} is not a function, type is {} within {}.",
|
||||||
t.add_all(&func_res);
|
i + 1,
|
||||||
break;
|
ft.simplified_as_string(info),
|
||||||
|
func.simplify_for_display(info).with_info(info),
|
||||||
|
))
|
||||||
|
.src(vec![
|
||||||
|
(self.source_range(), None),
|
||||||
|
(self.funcs[i].source_range(), Some(EColor::TryNotAFunction)),
|
||||||
|
]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !found {
|
}
|
||||||
let mut err = CheckError::new()
|
if !arg.types.is_empty() {
|
||||||
.msg_str(format!(
|
let mut err = CheckError::new()
|
||||||
"try: no function found for argument of type {}.",
|
.msg_str(format!(
|
||||||
arg.simplified_as_string(info)
|
"try: uncovered argument type {}.",
|
||||||
))
|
arg.simplified_as_string(info)
|
||||||
.src(vec![(
|
))
|
||||||
self.pos_in_src.clone(),
|
.src(vec![(
|
||||||
Some(EColor::TryNoFunctionFound),
|
self.pos_in_src.clone(),
|
||||||
)]);
|
Some(EColor::TryNoFunctionFound),
|
||||||
for (i, e) in errs.into_iter().enumerate() {
|
)]);
|
||||||
err = err
|
for (i, func) in funcs.iter().enumerate() {
|
||||||
.msg_str(format!("Error for function #{}:", i + 1))
|
err = err.msg_str(format!(
|
||||||
.err(e);
|
"Error for function #{} {}:",
|
||||||
|
i + 1,
|
||||||
|
func.with_info(info)
|
||||||
|
));
|
||||||
|
for e in func
|
||||||
|
.types
|
||||||
|
.iter()
|
||||||
|
.filter_map(|t| t.executable().unwrap().o(&arg).err())
|
||||||
|
{
|
||||||
|
err = err.err(e);
|
||||||
}
|
}
|
||||||
return Err(err);
|
|
||||||
}
|
}
|
||||||
|
return Err(err);
|
||||||
}
|
}
|
||||||
Ok(t)
|
Ok(t)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user