mirror of
https://github.com/Dummi26/mers.git
synced 2025-03-10 14:13:52 +01:00
fix "weird" behavior with globalinfo not updating
This commit is contained in:
parent
8868746e17
commit
f979100bfb
@ -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.10"
|
mers_lib = "0.9.12"
|
||||||
# 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.12"
|
version = "0.9.13"
|
||||||
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"
|
||||||
|
@ -8,7 +8,7 @@ use mers_lib::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
fn main() -> Result<(), CheckError> {
|
fn main() -> Result<(), CheckError> {
|
||||||
let (_, func) = parse_compile_check_run(
|
let (_, func, info) = parse_compile_check_run(
|
||||||
// The `[(String -> String)]` type annotation ensures that decorate.mers returns a `String -> String` function.
|
// The `[(String -> String)]` type annotation ensures that decorate.mers returns a `String -> String` function.
|
||||||
"[(String -> String)] #include \"examples/decorate.mers\"".to_owned(),
|
"[(String -> String)] #include \"examples/decorate.mers\"".to_owned(),
|
||||||
)?;
|
)?;
|
||||||
@ -23,7 +23,10 @@ fn main() -> Result<(), CheckError> {
|
|||||||
|
|
||||||
// use the function to decorate these 3 test strings
|
// use the function to decorate these 3 test strings
|
||||||
for input in ["my test string", "Main Menu", "O.o"] {
|
for input in ["my test string", "Main Menu", "O.o"] {
|
||||||
let result = func.run_immut(Data::new(data::string::String(input.to_owned())))?;
|
let result = func.run_immut(
|
||||||
|
Data::new(data::string::String(input.to_owned())),
|
||||||
|
info.global.clone(),
|
||||||
|
)?;
|
||||||
let result = result.get();
|
let result = result.get();
|
||||||
let result = &result
|
let result = &result
|
||||||
.as_any()
|
.as_any()
|
||||||
@ -37,7 +40,9 @@ fn main() -> Result<(), CheckError> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// example 00
|
/// example 00
|
||||||
fn parse_compile_check_run(src: String) -> Result<(Type, Data), CheckError> {
|
fn parse_compile_check_run(
|
||||||
|
src: String,
|
||||||
|
) -> Result<(Type, Data, mers_lib::program::run::Info), CheckError> {
|
||||||
let mut source = Source::new_from_string(src);
|
let mut source = Source::new_from_string(src);
|
||||||
let srca = Arc::new(source.clone());
|
let srca = Arc::new(source.clone());
|
||||||
let parsed = parse(&mut source, &srca)?;
|
let parsed = parse(&mut source, &srca)?;
|
||||||
@ -45,5 +50,5 @@ fn parse_compile_check_run(src: String) -> Result<(Type, Data), CheckError> {
|
|||||||
let compiled = parsed.compile(&mut i1, CompInfo::default())?;
|
let compiled = parsed.compile(&mut i1, CompInfo::default())?;
|
||||||
let output_type = compiled.check(&mut i3, None)?;
|
let output_type = compiled.check(&mut i3, None)?;
|
||||||
let output_value = compiled.run(&mut i2)?;
|
let output_value = compiled.run(&mut i2)?;
|
||||||
Ok((output_type, output_value))
|
Ok((output_type, output_value, i2))
|
||||||
}
|
}
|
||||||
|
@ -80,11 +80,25 @@ impl Function {
|
|||||||
pub fn check(&self, arg: &Type) -> Result<Type, CheckError> {
|
pub fn check(&self, arg: &Type) -> Result<Type, CheckError> {
|
||||||
self.get_as_type().o(arg)
|
self.get_as_type().o(arg)
|
||||||
}
|
}
|
||||||
pub fn run_mut(&mut self, arg: Data) -> Result<Data, CheckError> {
|
pub fn run_mut(
|
||||||
|
&mut self,
|
||||||
|
arg: Data,
|
||||||
|
gi: crate::program::run::RunLocalGlobalInfo,
|
||||||
|
) -> Result<Data, CheckError> {
|
||||||
|
self.info.global = gi;
|
||||||
|
self.run_mut_with_prev_gi(arg)
|
||||||
|
}
|
||||||
|
pub fn run_mut_with_prev_gi(&mut self, arg: Data) -> Result<Data, CheckError> {
|
||||||
(self.run)(arg, &mut self.info)
|
(self.run)(arg, &mut self.info)
|
||||||
}
|
}
|
||||||
pub fn run_immut(&self, arg: Data) -> Result<Data, CheckError> {
|
pub fn run_immut(
|
||||||
(self.run)(arg, &mut self.info.duplicate())
|
&self,
|
||||||
|
arg: Data,
|
||||||
|
gi: crate::program::run::RunLocalGlobalInfo,
|
||||||
|
) -> Result<Data, CheckError> {
|
||||||
|
let mut i = self.info.duplicate();
|
||||||
|
i.global = gi;
|
||||||
|
(self.run)(arg, &mut i)
|
||||||
}
|
}
|
||||||
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();
|
||||||
@ -114,13 +128,25 @@ impl MersData for Function {
|
|||||||
fn executable(&self) -> Option<crate::data::function::FunctionT> {
|
fn executable(&self) -> Option<crate::data::function::FunctionT> {
|
||||||
Some(self.get_as_type())
|
Some(self.get_as_type())
|
||||||
}
|
}
|
||||||
fn execute(&self, arg: Data) -> Option<Result<Data, CheckError>> {
|
fn execute(
|
||||||
Some(self.run_immut(arg))
|
&self,
|
||||||
|
arg: Data,
|
||||||
|
gi: &crate::program::run::RunLocalGlobalInfo,
|
||||||
|
) -> Option<Result<Data, CheckError>> {
|
||||||
|
Some(self.run_immut(arg, gi.clone()))
|
||||||
}
|
}
|
||||||
fn iterable(&self) -> Option<Box<dyn Iterator<Item = Result<Data, CheckError>>>> {
|
fn iterable(
|
||||||
|
&self,
|
||||||
|
gi: &crate::program::run::RunLocalGlobalInfo,
|
||||||
|
) -> Option<Box<dyn Iterator<Item = Result<Data, CheckError>>>> {
|
||||||
let mut s = Clone::clone(self);
|
let mut s = Clone::clone(self);
|
||||||
|
let mut gi = Some(gi.clone());
|
||||||
Some(Box::new(std::iter::from_fn(move || {
|
Some(Box::new(std::iter::from_fn(move || {
|
||||||
match s.run_mut(Data::empty_tuple()) {
|
match if let Some(gi) = gi.take() {
|
||||||
|
s.run_mut(Data::empty_tuple(), gi)
|
||||||
|
} else {
|
||||||
|
s.run_mut_with_prev_gi(Data::empty_tuple())
|
||||||
|
} {
|
||||||
Err(e) => Some(Err(e)),
|
Err(e) => Some(Err(e)),
|
||||||
Ok(v) => {
|
Ok(v) => {
|
||||||
if let Some(v) = v.one_tuple_content() {
|
if let Some(v) = v.one_tuple_content() {
|
||||||
|
@ -30,16 +30,28 @@ pub trait MersData: Any + Debug + Send + Sync {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
fn execute(&self, arg: Data) -> Option<Result<Data, CheckError>> {
|
fn execute(
|
||||||
|
&self,
|
||||||
|
arg: Data,
|
||||||
|
gi: &crate::program::run::RunLocalGlobalInfo,
|
||||||
|
) -> Option<Result<Data, CheckError>> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
fn iterable(&self) -> Option<Box<dyn Iterator<Item = Result<Data, CheckError>>>> {
|
#[allow(unused_variables)]
|
||||||
|
fn iterable(
|
||||||
|
&self,
|
||||||
|
gi: &crate::program::run::RunLocalGlobalInfo,
|
||||||
|
) -> Option<Box<dyn Iterator<Item = Result<Data, CheckError>>>> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
/// By default, uses `iterable` to get an iterator and `nth` to retrieve the nth element.
|
/// By default, uses `iterable` to get an iterator and `nth` to retrieve the nth element.
|
||||||
/// Should have a custom implementation for better performance on most types
|
/// Should have a custom implementation for better performance on most types
|
||||||
fn get(&self, i: usize) -> Option<Result<Data, CheckError>> {
|
fn get(
|
||||||
self.iterable()?.nth(i)
|
&self,
|
||||||
|
i: usize,
|
||||||
|
gi: &crate::program::run::RunLocalGlobalInfo,
|
||||||
|
) -> Option<Result<Data, CheckError>> {
|
||||||
|
self.iterable(gi)?.nth(i)
|
||||||
}
|
}
|
||||||
/// If self and other are different types (`other.as_any().downcast_ref::<Self>().is_none()`),
|
/// If self and other are different types (`other.as_any().downcast_ref::<Self>().is_none()`),
|
||||||
/// this *must* return false.
|
/// this *must* return false.
|
||||||
|
@ -27,7 +27,11 @@ impl MersData for Reference {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn execute(&self, arg: Data) -> Option<Result<Data, CheckError>> {
|
fn execute(
|
||||||
|
&self,
|
||||||
|
arg: Data,
|
||||||
|
gi: &crate::program::run::RunLocalGlobalInfo,
|
||||||
|
) -> Option<Result<Data, CheckError>> {
|
||||||
let mut inner = self.0.write().unwrap();
|
let mut inner = self.0.write().unwrap();
|
||||||
let mut inner = inner.get_mut();
|
let mut inner = inner.get_mut();
|
||||||
if let Some(func) = inner
|
if let Some(func) = inner
|
||||||
@ -35,13 +39,17 @@ impl MersData for Reference {
|
|||||||
.mut_any()
|
.mut_any()
|
||||||
.downcast_mut::<crate::data::function::Function>()
|
.downcast_mut::<crate::data::function::Function>()
|
||||||
{
|
{
|
||||||
Some(func.run_mut(arg))
|
Some(func.run_mut(arg, gi.clone()))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn iterable(&self) -> Option<Box<dyn Iterator<Item = Result<Data, CheckError>>>> {
|
fn iterable(
|
||||||
|
&self,
|
||||||
|
gi: &crate::program::run::RunLocalGlobalInfo,
|
||||||
|
) -> Option<Box<dyn Iterator<Item = Result<Data, CheckError>>>> {
|
||||||
let inner = Arc::clone(&self.0);
|
let inner = Arc::clone(&self.0);
|
||||||
|
let gi = gi.clone();
|
||||||
Some(Box::new(std::iter::from_fn(move || {
|
Some(Box::new(std::iter::from_fn(move || {
|
||||||
match inner
|
match inner
|
||||||
.write()
|
.write()
|
||||||
@ -50,7 +58,7 @@ impl MersData for Reference {
|
|||||||
.mut_any()
|
.mut_any()
|
||||||
.downcast_mut::<crate::data::function::Function>()
|
.downcast_mut::<crate::data::function::Function>()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.run_mut(Data::empty_tuple())
|
.run_mut(Data::empty_tuple(), gi.clone())
|
||||||
{
|
{
|
||||||
Err(e) => Some(Err(e)),
|
Err(e) => Some(Err(e)),
|
||||||
Ok(v) => {
|
Ok(v) => {
|
||||||
|
@ -35,7 +35,10 @@ impl MersData for Tuple {
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn iterable(&self) -> Option<Box<dyn Iterator<Item = Result<Data, CheckError>>>> {
|
fn iterable(
|
||||||
|
&self,
|
||||||
|
_gi: &crate::program::run::RunLocalGlobalInfo,
|
||||||
|
) -> Option<Box<dyn Iterator<Item = Result<Data, CheckError>>>> {
|
||||||
Some(Box::new(self.0.clone().into_iter().map(Ok)))
|
Some(Box::new(self.0.clone().into_iter().map(Ok)))
|
||||||
}
|
}
|
||||||
fn clone(&self) -> Box<dyn MersData> {
|
fn clone(&self) -> Box<dyn MersData> {
|
||||||
|
@ -63,14 +63,14 @@ impl Config {
|
|||||||
}
|
}
|
||||||
Ok(Type::empty_tuple())
|
Ok(Type::empty_tuple())
|
||||||
})),
|
})),
|
||||||
run: Arc::new(|a, _i| {
|
run: Arc::new(|a, i| {
|
||||||
let a = a.get();
|
let a = a.get();
|
||||||
let a = a.as_any().downcast_ref::<data::tuple::Tuple>().unwrap();
|
let a = a.as_any().downcast_ref::<data::tuple::Tuple>().unwrap();
|
||||||
let arg_ref = a.0[0].get();
|
let arg_ref = a.0[0].get();
|
||||||
let arg_ref = arg_ref.as_any().downcast_ref::<data::reference::Reference>().unwrap();
|
let arg_ref = arg_ref.as_any().downcast_ref::<data::reference::Reference>().unwrap();
|
||||||
let mut arg = arg_ref.0.write().unwrap();
|
let mut arg = arg_ref.0.write().unwrap();
|
||||||
let func = a.0[1].get();
|
let func = a.0[1].get();
|
||||||
*arg = func.execute(arg.clone()).unwrap()?;
|
*arg = func.execute(arg.clone(), &i.global).unwrap()?;
|
||||||
Ok(Data::empty_tuple())
|
Ok(Data::empty_tuple())
|
||||||
}),
|
}),
|
||||||
inner_statements: None,
|
inner_statements: None,
|
||||||
@ -103,12 +103,12 @@ impl Config {
|
|||||||
}
|
}
|
||||||
Ok(Type::new(data::int::IntT(0, INT_MAX)))
|
Ok(Type::new(data::int::IntT(0, INT_MAX)))
|
||||||
})),
|
})),
|
||||||
run: Arc::new(|a, _i| {
|
run: Arc::new(|a, i| {
|
||||||
Ok(Data::new(data::int::Int(if let Some(t) = a.get().as_any().downcast_ref::<data::tuple::Tuple>() {
|
Ok(Data::new(data::int::Int(if let Some(t) = a.get().as_any().downcast_ref::<data::tuple::Tuple>() {
|
||||||
t.0.len().try_into().unwrap_or(INT_MAX)
|
t.0.len().try_into().unwrap_or(INT_MAX)
|
||||||
} else if let Some(s) = a.get().as_any().downcast_ref::<data::string::String>() {
|
} else if let Some(s) = a.get().as_any().downcast_ref::<data::string::String>() {
|
||||||
s.0.len().try_into().unwrap_or(INT_MAX)
|
s.0.len().try_into().unwrap_or(INT_MAX)
|
||||||
} else if let Some(i) = a.get().iterable() {
|
} else if let Some(i) = a.get().iterable(&i.global) {
|
||||||
i.count().try_into().unwrap_or(INT_MAX)
|
i.count().try_into().unwrap_or(INT_MAX)
|
||||||
} else {
|
} else {
|
||||||
return Err("called len on {a:?}, which isn't a tuple, a string, or something iterable.".into());
|
return Err("called len on {a:?}, which isn't a tuple, a string, or something iterable.".into());
|
||||||
@ -130,8 +130,8 @@ impl Config {
|
|||||||
}
|
}
|
||||||
Ok(bool_type())
|
Ok(bool_type())
|
||||||
})),
|
})),
|
||||||
run: Arc::new(|a, _i| {
|
run: Arc::new(|a, i| {
|
||||||
Ok(Data::new(data::bool::Bool(if let Some(mut i) = a.get().iterable() {
|
Ok(Data::new(data::bool::Bool(if let Some(mut i) = a.get().iterable(&i.global) {
|
||||||
if let Some(f) = i.next() {
|
if let Some(f) = i.next() {
|
||||||
let f = f?;
|
let f = f?;
|
||||||
let mut o = true;
|
let mut o = true;
|
||||||
|
@ -12,7 +12,6 @@ use crate::{
|
|||||||
object::ObjectFieldsMap,
|
object::ObjectFieldsMap,
|
||||||
Data, MersData, MersDataWInfo, MersType, Type,
|
Data, MersData, MersDataWInfo, MersType, Type,
|
||||||
},
|
},
|
||||||
errors::CheckError,
|
|
||||||
info::DisplayInfo,
|
info::DisplayInfo,
|
||||||
program::{self, run::CheckInfo},
|
program::{self, run::CheckInfo},
|
||||||
};
|
};
|
||||||
@ -56,7 +55,7 @@ impl Config {
|
|||||||
let cmd = cmd.get();
|
let cmd = cmd.get();
|
||||||
let (cmd, args) = (
|
let (cmd, args) = (
|
||||||
cmd.as_any().downcast_ref::<data::string::String>().unwrap(),
|
cmd.as_any().downcast_ref::<data::string::String>().unwrap(),
|
||||||
args.get().iterable().unwrap(),
|
args.get().iterable(&i.global).unwrap(),
|
||||||
);
|
);
|
||||||
let args = args.map(|v| v.map(|v| v.get().with_info(i).to_string())).collect::<Result<Vec<_>, _>>()?;
|
let args = args.map(|v| v.map(|v| v.get().with_info(i).to_string())).collect::<Result<Vec<_>, _>>()?;
|
||||||
match Command::new(&cmd.0)
|
match Command::new(&cmd.0)
|
||||||
@ -107,7 +106,7 @@ impl Config {
|
|||||||
let cmd = cmd.get();
|
let cmd = cmd.get();
|
||||||
let (cmd, args) = (
|
let (cmd, args) = (
|
||||||
cmd.as_any().downcast_ref::<data::string::String>().unwrap(),
|
cmd.as_any().downcast_ref::<data::string::String>().unwrap(),
|
||||||
args.get().iterable().unwrap(),
|
args.get().iterable(&i.global).unwrap(),
|
||||||
);
|
);
|
||||||
let args = args.map(|v| v.map(|v| v.get().with_info(i).to_string())).collect::<Result<Vec<_>, _>>()?;
|
let args = args.map(|v| v.map(|v| v.get().with_info(i).to_string())).collect::<Result<Vec<_>, _>>()?;
|
||||||
match Command::new(&cmd.0)
|
match Command::new(&cmd.0)
|
||||||
@ -203,14 +202,14 @@ impl Config {
|
|||||||
return Err(format!("childproc_write_bytes called on non-`(ChildProcess, Iter<Byte>)` type {}", a.with_info(i)).into());
|
return Err(format!("childproc_write_bytes called on non-`(ChildProcess, Iter<Byte>)` type {}", a.with_info(i)).into());
|
||||||
}
|
}
|
||||||
})),
|
})),
|
||||||
run: Arc::new(|a, _i| {
|
run: Arc::new(|a, i| {
|
||||||
let a = a.get();
|
let a = a.get();
|
||||||
let tuple = a.as_any().downcast_ref::<data::tuple::Tuple>().unwrap();
|
let tuple = a.as_any().downcast_ref::<data::tuple::Tuple>().unwrap();
|
||||||
let child = tuple.0[0].get();
|
let child = tuple.0[0].get();
|
||||||
let bytes = tuple.0[1].get();
|
let bytes = tuple.0[1].get();
|
||||||
let child = child.as_any().downcast_ref::<ChildProcess>().unwrap();
|
let child = child.as_any().downcast_ref::<ChildProcess>().unwrap();
|
||||||
let mut child = child.0.lock().unwrap();
|
let mut child = child.0.lock().unwrap();
|
||||||
let buf = bytes.iterable().unwrap().map(|v| v.map(|v| v.get().as_any().downcast_ref::<data::byte::Byte>().unwrap().0)).collect::<Result<Vec<_>, _>>()?;
|
let buf = bytes.iterable(&i.global).unwrap().map(|v| v.map(|v| v.get().as_any().downcast_ref::<data::byte::Byte>().unwrap().0)).collect::<Result<Vec<_>, _>>()?;
|
||||||
Ok(if child.1.as_mut().is_some_and(|v| v.write_all(&buf).is_ok() && v.flush().is_ok()) {
|
Ok(if child.1.as_mut().is_some_and(|v| v.write_all(&buf).is_ok() && v.flush().is_ok()) {
|
||||||
Data::new(data::bool::Bool(true))
|
Data::new(data::bool::Bool(true))
|
||||||
} else {
|
} else {
|
||||||
@ -385,12 +384,6 @@ impl MersData for ChildProcess {
|
|||||||
fn display(&self, _info: &DisplayInfo<'_>, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
fn display(&self, _info: &DisplayInfo<'_>, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
write!(f, "{self}")
|
write!(f, "{self}")
|
||||||
}
|
}
|
||||||
fn iterable(&self) -> Option<Box<dyn Iterator<Item = Result<Data, CheckError>>>> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
fn get(&self, _i: usize) -> Option<Result<Data, CheckError>> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
fn is_eq(&self, other: &dyn MersData) -> bool {
|
fn is_eq(&self, other: &dyn MersData) -> bool {
|
||||||
other
|
other
|
||||||
.as_any()
|
.as_any()
|
||||||
|
@ -50,14 +50,14 @@ impl Config {
|
|||||||
Arc::new(data::tuple::TupleT(vec![])),
|
Arc::new(data::tuple::TupleT(vec![])),
|
||||||
]))
|
]))
|
||||||
})),
|
})),
|
||||||
run: Arc::new(|a, _i| {
|
run: Arc::new(|a, i| {
|
||||||
let a = a.get();
|
let a = a.get();
|
||||||
if let (Some(v), Some(i)) = (a.get(0), a.get(1)) {
|
if let (Some(v), Some(x)) = (a.get(0, &i.global), a.get(1, &i.global)) {
|
||||||
let (v, i2) = (v?, i?);
|
let (v, x2) = (v?, x?);
|
||||||
let o = if let Some(i3) = i2.get().as_any().downcast_ref::<data::int::Int>()
|
let o = if let Some(x3) = x2.get().as_any().downcast_ref::<data::int::Int>()
|
||||||
{
|
{
|
||||||
if let Ok(i) = i3.0.try_into() {
|
if let Ok(x) = x3.0.try_into() {
|
||||||
if let Some(v) = v.get().get(i) {
|
if let Some(v) = v.get().get(x, &i.global) {
|
||||||
Ok(Data::one_tuple(v?))
|
Ok(Data::one_tuple(v?))
|
||||||
} else {
|
} else {
|
||||||
Ok(Data::empty_tuple())
|
Ok(Data::empty_tuple())
|
||||||
|
@ -30,16 +30,16 @@ impl Config {
|
|||||||
/// `all: fn` returns true if all elements of the iterator are true
|
/// `all: fn` returns true if all elements of the iterator are true
|
||||||
pub fn with_iters(self) -> Self {
|
pub fn with_iters(self) -> Self {
|
||||||
self
|
self
|
||||||
.add_var("any", genfunc_iter_in_val_out("all".to_string(), data::bool::bool_type(), data::bool::bool_type(), |a, _i| {
|
.add_var("any", genfunc_iter_in_val_out("all".to_string(), data::bool::bool_type(), data::bool::bool_type(), |a, i| {
|
||||||
for v in a.get().iterable().unwrap().map(|v| v.map(|v| v.get().as_any().downcast_ref::<data::bool::Bool>().is_some_and(|v| v.0))) {
|
for v in a.get().iterable(&i.global).unwrap().map(|v| v.map(|v| v.get().as_any().downcast_ref::<data::bool::Bool>().is_some_and(|v| v.0))) {
|
||||||
if v? {
|
if v? {
|
||||||
return Ok(Data::new(data::bool::Bool(true)));
|
return Ok(Data::new(data::bool::Bool(true)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(Data::new(data::bool::Bool(false)))
|
Ok(Data::new(data::bool::Bool(false)))
|
||||||
}))
|
}))
|
||||||
.add_var("all", genfunc_iter_in_val_out("all".to_string(), data::bool::bool_type(), data::bool::bool_type(), |a, _i| {
|
.add_var("all", genfunc_iter_in_val_out("all".to_string(), data::bool::bool_type(), data::bool::bool_type(), |a, i| {
|
||||||
for v in a.get().iterable().unwrap().map(|v| v.map(|v| v.get().as_any().downcast_ref::<data::bool::Bool>().is_some_and(|v| v.0))) {
|
for v in a.get().iterable(&i.global).unwrap().map(|v| v.map(|v| v.get().as_any().downcast_ref::<data::bool::Bool>().is_some_and(|v| v.0))) {
|
||||||
if !v? {
|
if !v? {
|
||||||
return Ok(Data::new(data::bool::Bool(false)));
|
return Ok(Data::new(data::bool::Bool(false)));
|
||||||
}
|
}
|
||||||
@ -88,13 +88,13 @@ impl Config {
|
|||||||
}
|
}
|
||||||
Ok(Type::empty_tuple())
|
Ok(Type::empty_tuple())
|
||||||
})),
|
})),
|
||||||
run: Arc::new(|a, _i| {
|
run: Arc::new(|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>() {
|
||||||
if let (Some(v), Some(f)) = (tuple.get(0), tuple.get(1)) {
|
if let (Some(v), Some(f)) = (tuple.get(0), tuple.get(1)) {
|
||||||
if let Some(iter) = v.get().iterable() {
|
if let Some(iter) = v.get().iterable(&i.global) {
|
||||||
let f = f.get();
|
let f = f.get();
|
||||||
for v in iter {
|
for v in iter {
|
||||||
f.execute(v?).unwrap()?;
|
f.execute(v?, &i.global).unwrap()?;
|
||||||
}
|
}
|
||||||
Ok(Data::empty_tuple())
|
Ok(Data::empty_tuple())
|
||||||
} else {
|
} else {
|
||||||
@ -319,21 +319,25 @@ impl MersData for Iter {
|
|||||||
fn is_eq(&self, _other: &dyn MersData) -> bool {
|
fn is_eq(&self, _other: &dyn MersData) -> bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
fn iterable(&self) -> Option<Box<dyn Iterator<Item = Result<Data, CheckError>>>> {
|
fn iterable(
|
||||||
|
&self,
|
||||||
|
gi: &crate::program::run::RunLocalGlobalInfo,
|
||||||
|
) -> Option<Box<dyn Iterator<Item = Result<Data, CheckError>>>> {
|
||||||
|
let gi = gi.clone();
|
||||||
Some(match &self.0 {
|
Some(match &self.0 {
|
||||||
Iters::Map(f) => {
|
Iters::Map(f) => {
|
||||||
let f = Clone::clone(f);
|
let f = Clone::clone(f);
|
||||||
Box::new(self.1.get().iterable()?.map(move |v| {
|
Box::new(self.1.get().iterable(&gi)?.map(move |v| {
|
||||||
f.get()
|
f.get()
|
||||||
.execute(v?)
|
.execute(v?, &gi)
|
||||||
.ok_or_else(|| CheckError::from("called map with non-function argument"))?
|
.ok_or_else(|| CheckError::from("called map with non-function argument"))?
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
Iters::Filter(f) => {
|
Iters::Filter(f) => {
|
||||||
let f = Clone::clone(f);
|
let f = Clone::clone(f);
|
||||||
Box::new(self.1.get().iterable()?.filter_map(move |v| {
|
Box::new(self.1.get().iterable(&gi)?.filter_map(move |v| {
|
||||||
match v {
|
match v {
|
||||||
Ok(v) => match f.get().execute(v.clone()) {
|
Ok(v) => match f.get().execute(v.clone(), &gi) {
|
||||||
Some(Ok(f)) => {
|
Some(Ok(f)) => {
|
||||||
if f.get()
|
if f.get()
|
||||||
.as_any()
|
.as_any()
|
||||||
@ -356,8 +360,8 @@ impl MersData for Iter {
|
|||||||
}
|
}
|
||||||
Iters::FilterMap(f) => {
|
Iters::FilterMap(f) => {
|
||||||
let f = Clone::clone(f);
|
let f = Clone::clone(f);
|
||||||
Box::new(self.1.get().iterable()?.filter_map(move |v| match v {
|
Box::new(self.1.get().iterable(&gi)?.filter_map(move |v| match v {
|
||||||
Ok(v) => match f.get().execute(v) {
|
Ok(v) => match f.get().execute(v, &gi) {
|
||||||
Some(Ok(r)) => Some(Ok(r.one_tuple_content()?)),
|
Some(Ok(r)) => Some(Ok(r.one_tuple_content()?)),
|
||||||
Some(Err(e)) => Some(Err(e)),
|
Some(Err(e)) => Some(Err(e)),
|
||||||
None => Some(Err(CheckError::from(
|
None => Some(Err(CheckError::from(
|
||||||
@ -369,8 +373,8 @@ impl MersData for Iter {
|
|||||||
}
|
}
|
||||||
Iters::MapWhile(f) => {
|
Iters::MapWhile(f) => {
|
||||||
let f = Clone::clone(f);
|
let f = Clone::clone(f);
|
||||||
Box::new(self.1.get().iterable()?.map_while(move |v| match v {
|
Box::new(self.1.get().iterable(&gi)?.map_while(move |v| match v {
|
||||||
Ok(v) => match f.get().execute(v) {
|
Ok(v) => match f.get().execute(v, &gi) {
|
||||||
Some(Ok(r)) => Some(Ok(r.one_tuple_content()?)),
|
Some(Ok(r)) => Some(Ok(r.one_tuple_content()?)),
|
||||||
Some(Err(e)) => Some(Err(e)),
|
Some(Err(e)) => Some(Err(e)),
|
||||||
None => Some(Err(CheckError::from(
|
None => Some(Err(CheckError::from(
|
||||||
@ -380,22 +384,28 @@ impl MersData for Iter {
|
|||||||
Err(e) => Some(Err(e)),
|
Err(e) => Some(Err(e)),
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
Iters::Take(limit) => Box::new(self.1.get().iterable()?.take(*limit)),
|
Iters::Take(limit) => Box::new(self.1.get().iterable(&gi)?.take(*limit)),
|
||||||
Iters::Enumerate => {
|
Iters::Enumerate => {
|
||||||
Box::new(self.1.get().iterable()?.enumerate().map(|(i, v)| match v {
|
Box::new(
|
||||||
|
self.1
|
||||||
|
.get()
|
||||||
|
.iterable(&gi)?
|
||||||
|
.enumerate()
|
||||||
|
.map(|(i, v)| match v {
|
||||||
Ok(v) => Ok(Data::new(data::tuple::Tuple(vec![
|
Ok(v) => Ok(Data::new(data::tuple::Tuple(vec![
|
||||||
Data::new(data::int::Int(i as _)),
|
Data::new(data::int::Int(i as _)),
|
||||||
v,
|
v,
|
||||||
]))),
|
]))),
|
||||||
Err(e) => Err(e),
|
Err(e) => Err(e),
|
||||||
}))
|
}),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
Iters::Chained => {
|
Iters::Chained => {
|
||||||
match self
|
match self
|
||||||
.1
|
.1
|
||||||
.get()
|
.get()
|
||||||
.iterable()?
|
.iterable(&gi)?
|
||||||
.map(|v| Ok(v?.get().iterable()))
|
.map(move |v| Ok(v?.get().iterable(&gi)))
|
||||||
.collect::<Result<Option<Vec<_>>, CheckError>>()
|
.collect::<Result<Option<Vec<_>>, CheckError>>()
|
||||||
{
|
{
|
||||||
Ok(Some(iters)) => Box::new(iters.into_iter().flatten()),
|
Ok(Some(iters)) => Box::new(iters.into_iter().flatten()),
|
||||||
|
@ -221,9 +221,9 @@ impl Config {
|
|||||||
).into())
|
).into())
|
||||||
}
|
}
|
||||||
})),
|
})),
|
||||||
run: Arc::new(|a, _i| {
|
run: Arc::new(|a, i| {
|
||||||
if let Some(i) = a.get().iterable() {
|
if let Some(iter) = a.get().iterable(&i.global) {
|
||||||
Ok(Data::new(List(i.map(|v| Ok::<_, CheckError>(Arc::new(RwLock::new(v?)))).collect::<Result<_, _>>()?)))
|
Ok(Data::new(List(iter.map(|v| Ok::<_, CheckError>(Arc::new(RwLock::new(v?)))).collect::<Result<_, _>>()?)))
|
||||||
} else {
|
} else {
|
||||||
Err("as_list called on non-iterable".into())
|
Err("as_list called on non-iterable".into())
|
||||||
}
|
}
|
||||||
@ -272,7 +272,10 @@ impl MersData for List {
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn iterable(&self) -> Option<Box<dyn Iterator<Item = Result<Data, CheckError>>>> {
|
fn iterable(
|
||||||
|
&self,
|
||||||
|
_gi: &crate::program::run::RunLocalGlobalInfo,
|
||||||
|
) -> Option<Box<dyn Iterator<Item = Result<Data, CheckError>>>> {
|
||||||
Some(Box::new(
|
Some(Box::new(
|
||||||
self.0
|
self.0
|
||||||
.clone()
|
.clone()
|
||||||
|
@ -501,10 +501,10 @@ impl Config {
|
|||||||
}
|
}
|
||||||
Ok(o)
|
Ok(o)
|
||||||
},
|
},
|
||||||
|a, _| {
|
|a, i| {
|
||||||
let mut min_int = None;
|
let mut min_int = None;
|
||||||
let mut min_float = None;
|
let mut min_float = None;
|
||||||
for a in a.get().iterable().expect("called `min` on non-itereable") {
|
for a in a.get().iterable(&i.global).expect("called `min` on non-itereable") {
|
||||||
let a = a?;
|
let a = a?;
|
||||||
let a = a.get();
|
let a = a.get();
|
||||||
let a = a.as_any().downcast_ref::<data::int::Int>().map(|v| Ok(v.0)).or_else(|| a.as_any().downcast_ref::<data::float::Float>().map(|v| Err(v.0))).expect("found non-Int/Float element in argument to `min`");
|
let a = a.as_any().downcast_ref::<data::int::Int>().map(|v| Ok(v.0)).or_else(|| a.as_any().downcast_ref::<data::float::Float>().map(|v| Err(v.0))).expect("found non-Int/Float element in argument to `min`");
|
||||||
@ -581,10 +581,10 @@ impl Config {
|
|||||||
}
|
}
|
||||||
Ok(o)
|
Ok(o)
|
||||||
},
|
},
|
||||||
|a, _| {
|
|a, i| {
|
||||||
let mut min_int = None;
|
let mut min_int = None;
|
||||||
let mut min_float = None;
|
let mut min_float = None;
|
||||||
for a in a.get().iterable().expect("called `min` on non-itereable") {
|
for a in a.get().iterable(&i.global).expect("called `min` on non-itereable") {
|
||||||
let a = a?;
|
let a = a?;
|
||||||
let a = a.get();
|
let a = a.get();
|
||||||
let a = a.as_any().downcast_ref::<data::int::Int>().map(|v| Ok(v.0)).or_else(|| a.as_any().downcast_ref::<data::float::Float>().map(|v| Err(v.0))).expect("found non-Int/Float element in argument to `min`");
|
let a = a.as_any().downcast_ref::<data::int::Int>().map(|v| Ok(v.0)).or_else(|| a.as_any().downcast_ref::<data::float::Float>().map(|v| Err(v.0))).expect("found non-Int/Float element in argument to `min`");
|
||||||
@ -796,7 +796,7 @@ fn func_math_op(
|
|||||||
}
|
}
|
||||||
Ok(o)
|
Ok(o)
|
||||||
},
|
},
|
||||||
move |a, _| {
|
move |a, i| {
|
||||||
let a = a.get();
|
let a = a.get();
|
||||||
Ok(
|
Ok(
|
||||||
if let Some(a) = &a
|
if let Some(a) = &a
|
||||||
@ -839,7 +839,7 @@ fn func_math_op(
|
|||||||
let (mut acc, _) = iter_version
|
let (mut acc, _) = iter_version
|
||||||
.expect("no iter version for this math op, but argument not a 2-tuple...");
|
.expect("no iter version for this math op, but argument not a 2-tuple...");
|
||||||
for a in a
|
for a in a
|
||||||
.iterable()
|
.iterable(&i.global)
|
||||||
.expect("math op with iter version called on non-iterable")
|
.expect("math op with iter version called on non-iterable")
|
||||||
{
|
{
|
||||||
let a = a?;
|
let a = a?;
|
||||||
|
@ -47,9 +47,10 @@ impl Config {
|
|||||||
}
|
}
|
||||||
Ok(Type::new(ThreadT(out)))
|
Ok(Type::new(ThreadT(out)))
|
||||||
})),
|
})),
|
||||||
run: Arc::new(|a, _i| {
|
run: Arc::new(|a, i| {
|
||||||
|
let gi = i.global.clone();
|
||||||
Ok(Data::new(Thread(Arc::new(Mutex::new(Ok(std::thread::spawn(
|
Ok(Data::new(Thread(Arc::new(Mutex::new(Ok(std::thread::spawn(
|
||||||
move || a.get().execute(Data::empty_tuple()).unwrap(),
|
move || a.get().execute(Data::empty_tuple(), &gi).unwrap(),
|
||||||
)))))))
|
)))))))
|
||||||
}),
|
}),
|
||||||
inner_statements: None,
|
inner_statements: None,
|
||||||
|
@ -81,7 +81,7 @@ impl Config {
|
|||||||
|a, i| {
|
|a, i| {
|
||||||
Ok(Data::new(data::string::String(
|
Ok(Data::new(data::string::String(
|
||||||
a.get()
|
a.get()
|
||||||
.iterable()
|
.iterable(&i.global)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.map(|v| v.map(|v| v.get().with_info(i).to_string()))
|
.map(|v| v.map(|v| v.get().with_info(i).to_string()))
|
||||||
.collect::<Result<_, _>>()?,
|
.collect::<Result<_, _>>()?,
|
||||||
|
@ -92,7 +92,7 @@ impl MersStatement for Chain {
|
|||||||
let f = self.first.run(info)?;
|
let f = self.first.run(info)?;
|
||||||
let c = self.chained.run(info)?;
|
let c = self.chained.run(info)?;
|
||||||
let c = c.get();
|
let c = c.get();
|
||||||
match c.execute(f) {
|
match c.execute(f, &info.global) {
|
||||||
Some(Ok(v)) => Ok(v),
|
Some(Ok(v)) => Ok(v),
|
||||||
Some(Err(e)) => Err(if let Some(_) = &self.as_part_of_include {
|
Some(Err(e)) => Err(if let Some(_) = &self.as_part_of_include {
|
||||||
CheckError::new().err_with_diff_src(e).src(vec![(
|
CheckError::new().err_with_diff_src(e).src(vec![(
|
||||||
|
@ -116,7 +116,7 @@ impl MersStatement for Try {
|
|||||||
match func.executable().map(|func| func.o(&arg_type)) {
|
match func.executable().map(|func| func.o(&arg_type)) {
|
||||||
Some(Ok(_)) => {
|
Some(Ok(_)) => {
|
||||||
drop(ar);
|
drop(ar);
|
||||||
return func.execute(arg).unwrap();
|
return func.execute(arg, &info.global).unwrap();
|
||||||
}
|
}
|
||||||
None | Some(Err(_)) => (),
|
None | Some(Err(_)) => (),
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user