mirror of
https://github.com/Dummi26/mers.git
synced 2025-03-10 05:43:53 +01:00
functions no longer modify state, funcrefs exist
you can use &func as a function, too. this allows the function to mutate its inner state.
This commit is contained in:
parent
7acaafaa2f
commit
18cd3ee0ae
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "mers"
|
||||
version = "0.8.25"
|
||||
version = "0.9.0"
|
||||
edition = "2021"
|
||||
license = "MIT OR Apache-2.0"
|
||||
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"]
|
||||
|
||||
[dependencies]
|
||||
mers_lib = "0.8.25"
|
||||
mers_lib = "0.9.0"
|
||||
# mers_lib = { path = "../mers_lib" }
|
||||
clap = { version = "4.3.19", features = ["derive"] }
|
||||
colored = { version = "2.1.0", optional = true }
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "mers_lib"
|
||||
version = "0.8.25"
|
||||
version = "0.9.0"
|
||||
edition = "2021"
|
||||
license = "MIT OR Apache-2.0"
|
||||
description = "library to use the mers language in other projects"
|
||||
|
@ -23,7 +23,7 @@ fn main() -> Result<(), CheckError> {
|
||||
|
||||
// use the function to decorate these 3 test strings
|
||||
for input in ["my test string", "Main Menu", "O.o"] {
|
||||
let result = func.run(Data::new(data::string::String(input.to_owned())))?;
|
||||
let result = func.run_immut(Data::new(data::string::String(input.to_owned())))?;
|
||||
let result = result.get();
|
||||
let result = &result
|
||||
.as_any()
|
||||
|
@ -6,14 +6,14 @@ use std::{
|
||||
|
||||
use crate::{
|
||||
errors::CheckError,
|
||||
info::Local,
|
||||
program::run::{CheckInfo, Info},
|
||||
};
|
||||
|
||||
use super::{Data, MersData, MersType, Type};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Function {
|
||||
pub info: Arc<Info>,
|
||||
pub info: Info,
|
||||
pub info_check: Arc<Mutex<CheckInfo>>,
|
||||
pub out: Arc<dyn Fn(&Type, &mut CheckInfo) -> Result<Type, CheckError> + Send + Sync>,
|
||||
pub run:
|
||||
@ -23,20 +23,31 @@ pub struct Function {
|
||||
Arc<Box<dyn crate::program::run::MersStatement>>,
|
||||
)>,
|
||||
}
|
||||
impl Clone for Function {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
info: self.info.duplicate(),
|
||||
info_check: self.info_check.clone(),
|
||||
out: self.out.clone(),
|
||||
run: self.run.clone(),
|
||||
inner_statements: self.inner_statements.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl Function {
|
||||
pub fn new(
|
||||
out: impl Fn(&Type) -> Result<Type, CheckError> + Send + Sync + 'static,
|
||||
run: impl Fn(Data) -> Result<Data, CheckError> + Send + Sync + 'static,
|
||||
) -> Self {
|
||||
Self {
|
||||
info: Arc::new(crate::info::Info::neverused()),
|
||||
info: crate::info::Info::neverused(),
|
||||
info_check: Arc::new(Mutex::new(crate::info::Info::neverused())),
|
||||
out: Arc::new(move |a, _| out(a)),
|
||||
run: Arc::new(move |a, _| run(a)),
|
||||
inner_statements: None,
|
||||
}
|
||||
}
|
||||
pub fn with_info_run(&self, info: Arc<Info>) -> Self {
|
||||
pub fn with_info_run(&self, info: Info) -> Self {
|
||||
Self {
|
||||
info,
|
||||
info_check: Arc::clone(&self.info_check),
|
||||
@ -57,8 +68,11 @@ impl Function {
|
||||
drop(lock);
|
||||
(self.out)(arg, &mut info)
|
||||
}
|
||||
pub fn run(&self, arg: Data) -> Result<Data, CheckError> {
|
||||
(self.run)(arg, &mut self.info.as_ref().clone())
|
||||
pub fn run_mut(&mut self, arg: Data) -> Result<Data, CheckError> {
|
||||
(self.run)(arg, &mut self.info)
|
||||
}
|
||||
pub fn run_immut(&self, arg: Data) -> Result<Data, CheckError> {
|
||||
(self.run)(arg, &mut self.info.duplicate())
|
||||
}
|
||||
pub fn get_as_type(&self) -> FunctionT {
|
||||
let out = Arc::clone(&self.out);
|
||||
@ -73,10 +87,16 @@ impl Function {
|
||||
}
|
||||
|
||||
impl MersData for Function {
|
||||
fn executable(&self) -> Option<crate::data::function::FunctionT> {
|
||||
Some(self.get_as_type())
|
||||
}
|
||||
fn execute(&self, arg: Data) -> Option<Result<Data, CheckError>> {
|
||||
Some(self.run_immut(arg))
|
||||
}
|
||||
fn iterable(&self) -> Option<Box<dyn Iterator<Item = Result<Data, CheckError>>>> {
|
||||
let s = Clone::clone(self);
|
||||
let mut s = Clone::clone(self);
|
||||
Some(Box::new(std::iter::from_fn(move || {
|
||||
match s.run(Data::empty_tuple()) {
|
||||
match s.run_mut(Data::empty_tuple()) {
|
||||
Err(e) => Some(Err(e)),
|
||||
Ok(v) => {
|
||||
if let Some(v) = v.one_tuple_content() {
|
||||
@ -122,6 +142,9 @@ impl FunctionT {
|
||||
}
|
||||
}
|
||||
impl MersType for FunctionT {
|
||||
fn executable(&self) -> Option<crate::data::function::FunctionT> {
|
||||
Some(self.clone())
|
||||
}
|
||||
fn iterable(&self) -> Option<Type> {
|
||||
// if this function can be called with an empty tuple and returns `()` or `(T)`, it can act as an iterator with type `T`.
|
||||
if let Ok(t) = self.o(&Type::empty_tuple()) {
|
||||
|
@ -19,6 +19,15 @@ pub mod tuple;
|
||||
pub mod defs;
|
||||
|
||||
pub trait MersData: Any + Debug + Display + Send + Sync {
|
||||
/// must be the same as the `executable` impl on the MersType
|
||||
#[allow(unused_variables)]
|
||||
fn executable(&self) -> Option<crate::data::function::FunctionT> {
|
||||
None
|
||||
}
|
||||
#[allow(unused_variables)]
|
||||
fn execute(&self, arg: Data) -> Option<Result<Data, CheckError>> {
|
||||
None
|
||||
}
|
||||
fn iterable(&self) -> Option<Box<dyn Iterator<Item = Result<Data, CheckError>>>> {
|
||||
None
|
||||
}
|
||||
@ -38,6 +47,10 @@ pub trait MersData: Any + Debug + Display + Send + Sync {
|
||||
}
|
||||
|
||||
pub trait MersType: Any + Debug + Display + Send + Sync {
|
||||
#[allow(unused_variables)]
|
||||
fn executable(&self) -> Option<crate::data::function::FunctionT> {
|
||||
None
|
||||
}
|
||||
/// If Some(T), calling `iterable` on the MersData this MersType belongs to
|
||||
/// Should return Some(I), where I is an Iterator which only returns items of type T.
|
||||
fn iterable(&self) -> Option<Type> {
|
||||
|
@ -4,12 +4,63 @@ use std::{
|
||||
sync::{Arc, RwLock},
|
||||
};
|
||||
|
||||
use crate::errors::CheckError;
|
||||
|
||||
use super::{Data, MersData, MersType, Type};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Reference(pub Arc<RwLock<Data>>);
|
||||
|
||||
impl MersData for Reference {
|
||||
fn executable(&self) -> Option<crate::data::function::FunctionT> {
|
||||
let inner = self.0.read().unwrap();
|
||||
let inner = inner.get();
|
||||
if let Some(func) = inner
|
||||
.as_ref()
|
||||
.as_any()
|
||||
.downcast_ref::<crate::data::function::Function>()
|
||||
{
|
||||
Some(func.get_as_type())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
fn execute(&self, arg: Data) -> Option<Result<Data, CheckError>> {
|
||||
let mut inner = self.0.write().unwrap();
|
||||
let mut inner = inner.get_mut();
|
||||
if let Some(func) = inner
|
||||
.as_mut()
|
||||
.mut_any()
|
||||
.downcast_mut::<crate::data::function::Function>()
|
||||
{
|
||||
Some(func.run_mut(arg))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
fn iterable(&self) -> Option<Box<dyn Iterator<Item = Result<Data, CheckError>>>> {
|
||||
let inner = Arc::clone(&self.0);
|
||||
Some(Box::new(std::iter::from_fn(move || {
|
||||
match inner
|
||||
.write()
|
||||
.unwrap()
|
||||
.get_mut()
|
||||
.mut_any()
|
||||
.downcast_mut::<crate::data::function::Function>()
|
||||
.unwrap()
|
||||
.run_mut(Data::empty_tuple())
|
||||
{
|
||||
Err(e) => Some(Err(e)),
|
||||
Ok(v) => {
|
||||
if let Some(v) = v.one_tuple_content() {
|
||||
Some(Ok(v))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
})))
|
||||
}
|
||||
fn is_eq(&self, other: &dyn MersData) -> bool {
|
||||
if let Some(other) = other.as_any().downcast_ref::<Self>() {
|
||||
*other.0.write().unwrap() == *self.0.write().unwrap()
|
||||
@ -37,6 +88,38 @@ impl MersData for Reference {
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ReferenceT(pub Type);
|
||||
impl MersType for ReferenceT {
|
||||
fn executable(&self) -> Option<crate::data::function::FunctionT> {
|
||||
let mut funcs: Vec<crate::data::function::FunctionT> = vec![];
|
||||
for func in self.0.types.iter() {
|
||||
funcs.push(Clone::clone(
|
||||
func.as_any()
|
||||
.downcast_ref::<crate::data::function::FunctionT>()?,
|
||||
));
|
||||
}
|
||||
Some(super::function::FunctionT(Ok(Arc::new(move |a| {
|
||||
let mut out = Type::empty();
|
||||
for func in funcs.iter() {
|
||||
out.add_all(&func.o(a)?);
|
||||
}
|
||||
Ok(out)
|
||||
}))))
|
||||
}
|
||||
fn iterable(&self) -> Option<Type> {
|
||||
let mut out = Type::empty();
|
||||
for func in self.0.types.iter() {
|
||||
out.add_all(
|
||||
&func
|
||||
.as_any()
|
||||
.downcast_ref::<crate::data::function::FunctionT>()?
|
||||
.iterable()?,
|
||||
);
|
||||
}
|
||||
if !out.types.is_empty() {
|
||||
Some(out)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
fn is_same_type_as(&self, other: &dyn MersType) -> bool {
|
||||
if let Some(o) = other.as_any().downcast_ref::<Self>() {
|
||||
self.0.is_same_type_as(&o.0)
|
||||
@ -76,7 +159,7 @@ impl MersType for ReferenceT {
|
||||
|
||||
impl Display for Reference {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "&{}", self.0.write().unwrap().get())
|
||||
write!(f, "&{}", self.0.read().unwrap().get())
|
||||
}
|
||||
}
|
||||
impl Display for ReferenceT {
|
||||
|
@ -52,7 +52,7 @@ impl<L: Local> Local for Info<L> {
|
||||
}
|
||||
fn duplicate(&self) -> Self {
|
||||
Self {
|
||||
scopes: vec![self.scopes[0].duplicate()],
|
||||
scopes: self.scopes.iter().map(|v| v.duplicate()).collect(),
|
||||
global: self.global.clone(),
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ pub fn to_mers_func(
|
||||
run: impl Fn(Data) -> Result<Data, CheckError> + Send + Sync + 'static,
|
||||
) -> data::function::Function {
|
||||
data::function::Function {
|
||||
info: Arc::new(Info::neverused()),
|
||||
info: Info::neverused(),
|
||||
info_check: Arc::new(Mutex::new(Info::neverused())),
|
||||
out: Arc::new(move |a, _| out(a)),
|
||||
run: Arc::new(move |a, _| run(a)),
|
||||
|
@ -27,7 +27,7 @@ impl Config {
|
||||
// .add_var("try".to_string(), get_try(false))
|
||||
// .add_var("try_allow_unused".to_string(), get_try(true))
|
||||
.add_var("lock_update".to_string(), Data::new(data::function::Function {
|
||||
info: Arc::new(Info::neverused()),
|
||||
info: Info::neverused(),
|
||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||
out: Arc::new(|a, _i| {
|
||||
for t in a.types.iter() {
|
||||
@ -37,7 +37,7 @@ impl Config {
|
||||
if let Some(arg) = arg_ref.dereference() {
|
||||
let func = &t.0[1];
|
||||
for func_t in func.types.iter() {
|
||||
if let Some(f) = func_t.as_any().downcast_ref::<data::function::FunctionT>() {
|
||||
if let Some(f) = func_t.executable() {
|
||||
match f.o(&arg) {
|
||||
Ok(out) => {
|
||||
if !out.is_included_in(&arg) {
|
||||
@ -69,14 +69,13 @@ impl Config {
|
||||
let arg_ref = arg_ref.as_any().downcast_ref::<data::reference::Reference>().unwrap();
|
||||
let mut arg = arg_ref.0.write().unwrap();
|
||||
let func = a.0[1].get();
|
||||
let func = func.as_any().downcast_ref::<data::function::Function>().unwrap();
|
||||
*arg = func.run(arg.clone())?;
|
||||
*arg = func.execute(arg.clone()).unwrap()?;
|
||||
Ok(Data::empty_tuple())
|
||||
}),
|
||||
inner_statements: None,
|
||||
}))
|
||||
.add_var("sleep".to_string(), Data::new(data::function::Function {
|
||||
info: Arc::new(Info::neverused()),
|
||||
info: Info::neverused(),
|
||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||
out: Arc::new(|a, _i| if a.is_included_in(&Type::newm(vec![
|
||||
Arc::new(data::int::IntT),
|
||||
@ -105,7 +104,7 @@ impl Config {
|
||||
inner_statements: None,
|
||||
}))
|
||||
.add_var("exit".to_string(), Data::new(data::function::Function {
|
||||
info: Arc::new(Info::neverused()),
|
||||
info: Info::neverused(),
|
||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||
out: Arc::new(|a, _i| if a.is_included_in_single(&data::int::IntT) {
|
||||
Ok(Type::empty())
|
||||
@ -118,7 +117,7 @@ impl Config {
|
||||
inner_statements: None,
|
||||
}))
|
||||
.add_var("panic".to_string(), Data::new(data::function::Function {
|
||||
info: Arc::new(Info::neverused()),
|
||||
info: Info::neverused(),
|
||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||
out: Arc::new(|a, _i| if a.is_included_in_single(&data::string::StringT) {
|
||||
Ok(Type::empty())
|
||||
@ -140,7 +139,7 @@ impl Config {
|
||||
.add_var(
|
||||
"len".to_string(),
|
||||
Data::new(data::function::Function {
|
||||
info: Arc::new(Info::neverused()),
|
||||
info: Info::neverused(),
|
||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||
out: Arc::new(|a, _i| {
|
||||
for t in &a.types {
|
||||
@ -168,7 +167,7 @@ impl Config {
|
||||
.add_var(
|
||||
"eq".to_string(),
|
||||
Data::new(data::function::Function {
|
||||
info: Arc::new(Info::neverused()),
|
||||
info: Info::neverused(),
|
||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||
out: Arc::new(|a, _i| {
|
||||
for t in &a.types {
|
||||
@ -204,7 +203,7 @@ impl Config {
|
||||
.add_var(
|
||||
"mkref".to_string(),
|
||||
Data::new(data::function::Function {
|
||||
info: Arc::new(Info::neverused()),
|
||||
info: Info::neverused(),
|
||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||
out: Arc::new(|a, _i| Ok(Type::new(data::reference::ReferenceT(a.clone())))),
|
||||
run: Arc::new(|a, _i| {
|
||||
@ -216,7 +215,7 @@ impl Config {
|
||||
.add_var(
|
||||
"deref".to_string(),
|
||||
Data::new(data::function::Function {
|
||||
info: Arc::new(Info::neverused()),
|
||||
info: Info::neverused(),
|
||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||
out: Arc::new(|a, _i| if let Some(v) = a.dereference() { Ok(v) } else { Err(format!("cannot dereference type {a}").into())
|
||||
}),
|
||||
@ -239,7 +238,7 @@ impl Config {
|
||||
|
||||
// fn get_try(allow_unused_functions: bool) -> Data {
|
||||
// Data::new(data::function::Function {
|
||||
// info: Arc::new(Info::neverused()),
|
||||
// info: Info::neverused(),
|
||||
// info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||
// out: Arc::new(move |a, _i| {
|
||||
// let mut out = Type::empty();
|
||||
|
@ -27,7 +27,7 @@ impl Config {
|
||||
.add_var(
|
||||
"run_command".to_string(),
|
||||
Data::new(data::function::Function {
|
||||
info: Arc::new(program::run::Info::neverused()),
|
||||
info: program::run::Info::neverused(),
|
||||
info_check: Arc::new(Mutex::new( CheckInfo::neverused())),
|
||||
out: Arc::new(|a, _i| {
|
||||
if a.types.iter().all(|t| t.as_any().downcast_ref::<data::tuple::TupleT>().is_some_and(|t| t.0.len() == 2 && t.0[0].is_included_in_single(&data::string::StringT) && t.0[1].iterable().is_some_and(|t| t.is_included_in_single(&data::string::StringT)))) {
|
||||
@ -82,7 +82,7 @@ impl Config {
|
||||
.add_var(
|
||||
"spawn_command".to_string(),
|
||||
Data::new(data::function::Function {
|
||||
info: Arc::new(program::run::Info::neverused()),
|
||||
info: program::run::Info::neverused(),
|
||||
info_check: Arc::new(Mutex::new( CheckInfo::neverused())),
|
||||
out: Arc::new(|a, _i| {
|
||||
if a.types.iter().all(|t| t.as_any().downcast_ref::<data::tuple::TupleT>().is_some_and(|t| t.0.len() == 2 && t.0[0].is_included_in_single(&data::string::StringT) && t.0[1].iterable().is_some_and(|t| t.is_included_in_single(&data::string::StringT)))) {
|
||||
@ -126,7 +126,7 @@ impl Config {
|
||||
.add_var(
|
||||
"childproc_exited".to_string(),
|
||||
Data::new(data::function::Function {
|
||||
info: Arc::new(program::run::Info::neverused()),
|
||||
info: program::run::Info::neverused(),
|
||||
info_check: Arc::new(Mutex::new( CheckInfo::neverused())),
|
||||
out: Arc::new(|a, _i| {
|
||||
if a.is_included_in_single(&ChildProcessT) {
|
||||
@ -154,7 +154,7 @@ impl Config {
|
||||
.add_var(
|
||||
"childproc_await".to_string(),
|
||||
Data::new(data::function::Function {
|
||||
info: Arc::new(program::run::Info::neverused()),
|
||||
info: program::run::Info::neverused(),
|
||||
info_check: Arc::new(Mutex::new( CheckInfo::neverused())),
|
||||
out: Arc::new(|a, _i| {
|
||||
if a.is_included_in_single(&ChildProcessT) {
|
||||
@ -187,7 +187,7 @@ impl Config {
|
||||
.add_var(
|
||||
"childproc_write_bytes".to_string(),
|
||||
Data::new(data::function::Function {
|
||||
info: Arc::new(program::run::Info::neverused()),
|
||||
info: program::run::Info::neverused(),
|
||||
info_check: Arc::new(Mutex::new( CheckInfo::neverused())),
|
||||
out: Arc::new(|a, _i| {
|
||||
if a.types.iter().all(|a| a.as_any().downcast_ref::<data::tuple::TupleT>().is_some_and(|t| t.0.len() == 2 && t.0[0].is_included_in_single(&ChildProcessT) && t.0[1].iterable().is_some_and(|i| i.is_included_in_single(&data::byte::ByteT)))) {
|
||||
@ -216,7 +216,7 @@ impl Config {
|
||||
.add_var(
|
||||
"childproc_write_string".to_string(),
|
||||
Data::new(data::function::Function {
|
||||
info: Arc::new(program::run::Info::neverused()),
|
||||
info: program::run::Info::neverused(),
|
||||
info_check: Arc::new(Mutex::new( CheckInfo::neverused())),
|
||||
out: Arc::new(|a, _i| {
|
||||
if a.is_included_in_single(&data::tuple::TupleT(vec![Type::new(ChildProcessT), Type::new(data::string::StringT)])) {
|
||||
@ -245,7 +245,7 @@ impl Config {
|
||||
.add_var(
|
||||
"childproc_read_byte".to_string(),
|
||||
Data::new(data::function::Function {
|
||||
info: Arc::new(program::run::Info::neverused()),
|
||||
info: program::run::Info::neverused(),
|
||||
info_check: Arc::new(Mutex::new( CheckInfo::neverused())),
|
||||
out: Arc::new(|a, _i| {
|
||||
if a.is_included_in_single(&ChildProcessT) {
|
||||
@ -274,7 +274,7 @@ impl Config {
|
||||
.add_var(
|
||||
"childproc_readerr_byte".to_string(),
|
||||
Data::new(data::function::Function {
|
||||
info: Arc::new(program::run::Info::neverused()),
|
||||
info: program::run::Info::neverused(),
|
||||
info_check: Arc::new(Mutex::new( CheckInfo::neverused())),
|
||||
out: Arc::new(|a, _i| {
|
||||
if a.is_included_in_single(&ChildProcessT) {
|
||||
@ -303,7 +303,7 @@ impl Config {
|
||||
.add_var(
|
||||
"childproc_read_line".to_string(),
|
||||
Data::new(data::function::Function {
|
||||
info: Arc::new(program::run::Info::neverused()),
|
||||
info: program::run::Info::neverused(),
|
||||
info_check: Arc::new(Mutex::new( CheckInfo::neverused())),
|
||||
out: Arc::new(|a, _i| {
|
||||
if a.is_included_in_single(&ChildProcessT) {
|
||||
@ -332,7 +332,7 @@ impl Config {
|
||||
.add_var(
|
||||
"childproc_readerr_line".to_string(),
|
||||
Data::new(data::function::Function {
|
||||
info: Arc::new(program::run::Info::neverused()),
|
||||
info: program::run::Info::neverused(),
|
||||
info_check: Arc::new(Mutex::new( CheckInfo::neverused())),
|
||||
out: Arc::new(|a, _i| {
|
||||
if a.is_included_in_single(&ChildProcessT) {
|
||||
|
@ -13,7 +13,7 @@ impl Config {
|
||||
self.add_var(
|
||||
"get".to_string(),
|
||||
Data::new(data::function::Function {
|
||||
info: Arc::new(program::run::Info::neverused()),
|
||||
info: program::run::Info::neverused(),
|
||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||
out: Arc::new(|a, _i| {
|
||||
let mut out = Type::empty();
|
||||
|
@ -47,7 +47,7 @@ impl Config {
|
||||
.add_var(
|
||||
"for_each".to_string(),
|
||||
Data::new(data::function::Function {
|
||||
info: Arc::new(program::run::Info::neverused()),
|
||||
info: program::run::Info::neverused(),
|
||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||
out: Arc::new(|a, _i| {
|
||||
for a in &a.types {
|
||||
@ -58,7 +58,7 @@ impl Config {
|
||||
f.types
|
||||
.iter()
|
||||
.map(|t| {
|
||||
t.as_any().downcast_ref::<data::function::FunctionT>()
|
||||
t.executable()
|
||||
})
|
||||
.collect::<Option<Vec<_>>>(),
|
||||
) {
|
||||
@ -88,17 +88,15 @@ impl Config {
|
||||
run: Arc::new(|a, _i| {
|
||||
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(iter), Some(f)) = (
|
||||
v.get().iterable(),
|
||||
f.get().as_any().downcast_ref::<data::function::Function>(),
|
||||
) {
|
||||
if let Some(iter) = v.get().iterable() {
|
||||
let f = f.get();
|
||||
for v in iter {
|
||||
f.run(v?)?;
|
||||
f.execute(v?).unwrap()?;
|
||||
}
|
||||
Ok(Data::empty_tuple())
|
||||
} else {
|
||||
return Err(
|
||||
"for_each called on tuple not containing iterable and function".into()
|
||||
"for_each called on tuple not containing iterable and function (not an iterable)".into()
|
||||
);
|
||||
}
|
||||
} else {
|
||||
@ -129,11 +127,11 @@ impl Config {
|
||||
)
|
||||
.add_var("take".to_string(), Data::new(genfunc_iter_and_arg("take", |_: &data::int::IntT| ItersT::Take, |v: &data::int::Int| {
|
||||
Iters::Take(v.0.max(0) as _)
|
||||
})))
|
||||
}, &data::int::IntT)))
|
||||
.add_var(
|
||||
"enumerate".to_string(),
|
||||
Data::new(data::function::Function {
|
||||
info: Arc::new(program::run::Info::neverused()),
|
||||
info: program::run::Info::neverused(),
|
||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||
out: Arc::new(|a, _i| {
|
||||
let data = if let Some(a) = a.iterable() {
|
||||
@ -150,7 +148,7 @@ impl Config {
|
||||
.add_var(
|
||||
"chain".to_string(),
|
||||
Data::new(data::function::Function {
|
||||
info: Arc::new(program::run::Info::neverused()),
|
||||
info: program::run::Info::neverused(),
|
||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||
out: Arc::new(|a, _i| {
|
||||
let data = if let Some(a) = a.iterable() {
|
||||
@ -167,11 +165,16 @@ impl Config {
|
||||
}
|
||||
}
|
||||
|
||||
fn iter_out_arg<T: MersType>(
|
||||
fn genfunc_iter_and_func(
|
||||
name: &'static str,
|
||||
ft: impl Fn(FunctionT) -> ItersT + Send + Sync + 'static,
|
||||
fd: impl Fn(Data) -> Iters + Send + Sync + 'static,
|
||||
) -> data::function::Function {
|
||||
fn iter_out_arg(
|
||||
a: &Type,
|
||||
name: &str,
|
||||
func: impl Fn(&T) -> ItersT + Sync + Send,
|
||||
) -> Result<Type, CheckError> {
|
||||
func: impl Fn(FunctionT) -> ItersT + Sync + Send,
|
||||
) -> Result<Type, CheckError> {
|
||||
let mut out = Type::empty();
|
||||
for t in a.types.iter() {
|
||||
if let Some(t) = t.as_any().downcast_ref::<data::tuple::TupleT>() {
|
||||
@ -180,7 +183,7 @@ fn iter_out_arg<T: MersType>(
|
||||
}
|
||||
if let Some(v) = t.0[0].iterable() {
|
||||
for f in t.0[1].types.iter() {
|
||||
if let Some(f) = f.as_any().downcast_ref::<T>() {
|
||||
if let Some(f) = f.executable() {
|
||||
out.add(Arc::new(IterT::new(func(f), v.clone())?));
|
||||
} else {
|
||||
return Err(format!("cannot call {name} on tuple that isn't (_, function): got {} instead of function as part of {a}", t.0[1]).into());
|
||||
@ -195,28 +198,65 @@ fn iter_out_arg<T: MersType>(
|
||||
}
|
||||
}
|
||||
Ok(out)
|
||||
}
|
||||
|
||||
fn genfunc_iter_and_func(
|
||||
name: &'static str,
|
||||
ft: impl Fn(FunctionT) -> ItersT + Send + Sync + 'static,
|
||||
fd: impl Fn(Function) -> Iters + Send + Sync + 'static,
|
||||
) -> data::function::Function {
|
||||
genfunc_iter_and_arg(
|
||||
name,
|
||||
move |v| ft(Clone::clone(v)),
|
||||
move |v| fd(Clone::clone(v)),
|
||||
)
|
||||
}
|
||||
data::function::Function {
|
||||
info: program::run::Info::neverused(),
|
||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||
out: Arc::new(move |a, _i| iter_out_arg(a, name, |f| ft(f))),
|
||||
run: Arc::new(move |a, _i| {
|
||||
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)) {
|
||||
Ok(Data::new(Iter(fd(f.clone()), v.clone())))
|
||||
} else {
|
||||
return Err("{name} called on tuple with len < 2".into());
|
||||
}
|
||||
} else {
|
||||
return Err("{name} called on non-tuple".into());
|
||||
}
|
||||
}),
|
||||
inner_statements: None,
|
||||
}
|
||||
}
|
||||
fn genfunc_iter_and_arg<T: MersType, D: MersData>(
|
||||
name: &'static str,
|
||||
ft: impl Fn(&T) -> ItersT + Send + Sync + 'static,
|
||||
fd: impl Fn(&D) -> Iters + Send + Sync + 'static,
|
||||
type_sample: &'static T,
|
||||
) -> data::function::Function {
|
||||
fn iter_out_arg<T: MersType>(
|
||||
a: &Type,
|
||||
name: &str,
|
||||
func: impl Fn(&T) -> ItersT + Sync + Send,
|
||||
type_sample: &T,
|
||||
) -> Result<Type, CheckError> {
|
||||
let mut out = Type::empty();
|
||||
for t in a.types.iter() {
|
||||
if let Some(t) = t.as_any().downcast_ref::<data::tuple::TupleT>() {
|
||||
if t.0.len() != 2 {
|
||||
return Err(format!("cannot call {name} on tuple where len != 2").into());
|
||||
}
|
||||
if let Some(v) = t.0[0].iterable() {
|
||||
for f in t.0[1].types.iter() {
|
||||
if let Some(f) = f.as_any().downcast_ref::<T>() {
|
||||
out.add(Arc::new(IterT::new(func(f), v.clone())?));
|
||||
} else {
|
||||
return Err(format!("cannot call {name} on tuple that isn't (_, {type_sample}): got {} instead of {type_sample} as part of {a}", t.0[1]).into());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return Err(format!(
|
||||
"cannot call {name} on non-iterable type {t}, which is part of {a}."
|
||||
)
|
||||
.into());
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(out)
|
||||
}
|
||||
data::function::Function {
|
||||
info: Arc::new(program::run::Info::neverused()),
|
||||
info: program::run::Info::neverused(),
|
||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||
out: Arc::new(move |a, _i| iter_out_arg(a, name, |f: &T| ft(f))),
|
||||
out: Arc::new(move |a, _i| iter_out_arg(a, name, |f: &T| ft(f), type_sample)),
|
||||
run: Arc::new(move |a, _i| {
|
||||
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)) {
|
||||
@ -238,10 +278,10 @@ fn genfunc_iter_and_arg<T: MersType, D: MersData>(
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum Iters {
|
||||
Map(data::function::Function),
|
||||
Filter(data::function::Function),
|
||||
FilterMap(data::function::Function),
|
||||
MapWhile(data::function::Function),
|
||||
Map(Data),
|
||||
Filter(Data),
|
||||
FilterMap(Data),
|
||||
MapWhile(Data),
|
||||
Take(usize),
|
||||
Enumerate,
|
||||
Chained,
|
||||
@ -268,14 +308,18 @@ impl MersData for Iter {
|
||||
Some(match &self.0 {
|
||||
Iters::Map(f) => {
|
||||
let f = Clone::clone(f);
|
||||
Box::new(self.1.get().iterable()?.map(move |v| f.run(v?)))
|
||||
Box::new(self.1.get().iterable()?.map(move |v| {
|
||||
f.get()
|
||||
.execute(v?)
|
||||
.ok_or_else(|| CheckError::from("called map with non-function argument"))?
|
||||
}))
|
||||
}
|
||||
Iters::Filter(f) => {
|
||||
let f = Clone::clone(f);
|
||||
Box::new(self.1.get().iterable()?.filter_map(move |v| {
|
||||
match v {
|
||||
Ok(v) => match f.run(v.clone()) {
|
||||
Ok(f) => {
|
||||
Ok(v) => match f.get().execute(v.clone()) {
|
||||
Some(Ok(f)) => {
|
||||
if f.get()
|
||||
.as_any()
|
||||
.downcast_ref::<data::bool::Bool>()
|
||||
@ -286,7 +330,10 @@ impl MersData for Iter {
|
||||
None
|
||||
}
|
||||
}
|
||||
Err(e) => Some(Err(e)),
|
||||
Some(Err(e)) => Some(Err(e)),
|
||||
None => Some(Err(CheckError::from(
|
||||
"called filter with non-function argument",
|
||||
))),
|
||||
},
|
||||
Err(e) => Some(Err(e)),
|
||||
}
|
||||
@ -295,9 +342,12 @@ impl MersData for Iter {
|
||||
Iters::FilterMap(f) => {
|
||||
let f = Clone::clone(f);
|
||||
Box::new(self.1.get().iterable()?.filter_map(move |v| match v {
|
||||
Ok(v) => match f.run(v) {
|
||||
Ok(r) => Some(Ok(r.one_tuple_content()?)),
|
||||
Err(e) => Some(Err(e)),
|
||||
Ok(v) => match f.get().execute(v) {
|
||||
Some(Ok(r)) => Some(Ok(r.one_tuple_content()?)),
|
||||
Some(Err(e)) => Some(Err(e)),
|
||||
None => Some(Err(CheckError::from(
|
||||
"called filter_map with non-function argument",
|
||||
))),
|
||||
},
|
||||
Err(e) => Some(Err(e)),
|
||||
}))
|
||||
@ -305,9 +355,12 @@ impl MersData for Iter {
|
||||
Iters::MapWhile(f) => {
|
||||
let f = Clone::clone(f);
|
||||
Box::new(self.1.get().iterable()?.map_while(move |v| match v {
|
||||
Ok(v) => match f.run(v) {
|
||||
Ok(r) => Some(Ok(r.one_tuple_content()?)),
|
||||
Err(e) => Some(Err(e)),
|
||||
Ok(v) => match f.get().execute(v) {
|
||||
Some(Ok(r)) => Some(Ok(r.one_tuple_content()?)),
|
||||
Some(Err(e)) => Some(Err(e)),
|
||||
None => Some(Err(CheckError::from(
|
||||
"called map_while with non-function argument",
|
||||
))),
|
||||
},
|
||||
Err(e) => Some(Err(e)),
|
||||
}))
|
||||
@ -449,10 +502,10 @@ impl Display for IterT {
|
||||
impl Iters {
|
||||
fn as_type(&self) -> ItersT {
|
||||
match self {
|
||||
Self::Map(f) => ItersT::Map(f.get_as_type()),
|
||||
Self::Filter(f) => ItersT::Filter(f.get_as_type()),
|
||||
Self::FilterMap(f) => ItersT::FilterMap(f.get_as_type()),
|
||||
Self::MapWhile(f) => ItersT::MapWhile(f.get_as_type()),
|
||||
Self::Map(f) => ItersT::Map(f.get().executable().unwrap()),
|
||||
Self::Filter(f) => ItersT::Filter(f.get().executable().unwrap()),
|
||||
Self::FilterMap(f) => ItersT::FilterMap(f.get().executable().unwrap()),
|
||||
Self::MapWhile(f) => ItersT::MapWhile(f.get().executable().unwrap()),
|
||||
Self::Take(_) => ItersT::Take,
|
||||
Self::Enumerate => ItersT::Enumerate,
|
||||
Self::Chained => ItersT::Chained,
|
||||
@ -470,7 +523,7 @@ fn genfunc_iter_in_val_out(
|
||||
+ 'static,
|
||||
) -> Function {
|
||||
Function {
|
||||
info: Arc::new(crate::info::Info::neverused()),
|
||||
info: crate::info::Info::neverused(),
|
||||
info_check: Arc::new(Mutex::new(crate::info::Info::neverused())),
|
||||
out: Arc::new(move |a, _i| {
|
||||
if let Some(iter_over) = a.iterable() {
|
||||
|
@ -32,7 +32,7 @@ impl Config {
|
||||
let t = crate::parsing::types::parse_type(&mut src, &srca)?;
|
||||
Ok(Arc::new(Type::new(ListT(crate::parsing::types::type_from_parsed(&t, i)?))))})))
|
||||
.add_var("get_mut".to_string(), Data::new(data::function::Function {
|
||||
info: Arc::new(program::run::Info::neverused()),
|
||||
info: program::run::Info::neverused(),
|
||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||
out: Arc::new(|a, _i| {
|
||||
let mut out = Type::empty_tuple();
|
||||
@ -101,7 +101,7 @@ impl Config {
|
||||
.add_var(
|
||||
"pop".to_string(),
|
||||
Data::new(data::function::Function {
|
||||
info: Arc::new(program::run::Info::neverused()),
|
||||
info: program::run::Info::neverused(),
|
||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||
out: Arc::new(|a, _i| {
|
||||
if let Some(a) = a.dereference() {
|
||||
@ -149,7 +149,7 @@ impl Config {
|
||||
.add_var(
|
||||
"push".to_string(),
|
||||
Data::new(data::function::Function {
|
||||
info: Arc::new(program::run::Info::neverused()),
|
||||
info: program::run::Info::neverused(),
|
||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||
out: Arc::new(|a, _i| {
|
||||
for t in a.types.iter() {
|
||||
@ -212,7 +212,7 @@ impl Config {
|
||||
.add_var(
|
||||
"as_list".to_string(),
|
||||
Data::new(data::function::Function {
|
||||
info: Arc::new(program::run::Info::neverused()),
|
||||
info: program::run::Info::neverused(),
|
||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||
out: Arc::new(|a, _i| {
|
||||
if let Some(v) = a.iterable() {
|
||||
|
@ -71,7 +71,7 @@ impl Config {
|
||||
.add_var(
|
||||
"parse_float".to_string(),
|
||||
Data::new(data::function::Function {
|
||||
info: Arc::new(program::run::Info::neverused()),
|
||||
info: program::run::Info::neverused(),
|
||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||
out: Arc::new(|a, _i| {
|
||||
if a.is_included_in(&Type::new(data::string::StringT)) {
|
||||
@ -105,7 +105,7 @@ impl Config {
|
||||
.add_var(
|
||||
"parse_int".to_string(),
|
||||
Data::new(data::function::Function {
|
||||
info: Arc::new(program::run::Info::neverused()),
|
||||
info: program::run::Info::neverused(),
|
||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||
out: Arc::new(|a, _i| {
|
||||
if a.is_included_in(&Type::new(data::string::StringT)) {
|
||||
@ -139,7 +139,7 @@ impl Config {
|
||||
.add_var(
|
||||
"signum".to_string(),
|
||||
Data::new(data::function::Function {
|
||||
info: Arc::new(program::run::Info::neverused()),
|
||||
info: program::run::Info::neverused(),
|
||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||
out: Arc::new(|a, _i| {
|
||||
if a.is_included_in(&Type::newm(vec![
|
||||
@ -255,7 +255,7 @@ fn num_iter_to_num(
|
||||
func: impl Fn(Result<isize, f64>, Result<isize, f64>) -> Result<isize, f64> + Send + Sync + 'static,
|
||||
) -> data::function::Function {
|
||||
data::function::Function {
|
||||
info: Arc::new(program::run::Info::neverused()),
|
||||
info: program::run::Info::neverused(),
|
||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||
out: Arc::new(move |a, _i| {
|
||||
if let Some(a) = a.iterable() {
|
||||
@ -320,7 +320,7 @@ fn two_num_tuple_to_num(
|
||||
func_ff: impl Fn(f64, f64) -> Result<f64, CheckError> + Send + Sync + 'static,
|
||||
) -> data::function::Function {
|
||||
data::function::Function {
|
||||
info: Arc::new(program::run::Info::neverused()),
|
||||
info: program::run::Info::neverused(),
|
||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||
out: Arc::new(|a, _i| two_tuple_to_num_impl_check(a, func_name)),
|
||||
run: Arc::new(move |a, _i| {
|
||||
@ -406,7 +406,7 @@ fn ltgtoe_function(
|
||||
op: impl Fn(IntOrFloatOrNothing, IntOrFloatOrNothing) -> bool + Send + Sync + 'static,
|
||||
) -> data::function::Function {
|
||||
data::function::Function {
|
||||
info: Arc::new(program::run::Info::neverused()),
|
||||
info: program::run::Info::neverused(),
|
||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||
out: Arc::new(move |a, _i| {
|
||||
if let Some(iter_type) = a.iterable() {
|
||||
|
@ -30,12 +30,12 @@ impl Config {
|
||||
.add_var(
|
||||
"thread".to_string(),
|
||||
Data::new(data::function::Function {
|
||||
info: Arc::new(program::run::Info::neverused()),
|
||||
info: program::run::Info::neverused(),
|
||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||
out: Arc::new(|a, _i| {
|
||||
let mut out = Type::empty();
|
||||
for t in a.types.iter() {
|
||||
if let Some(f) = t.as_any().downcast_ref::<data::function::FunctionT>() {
|
||||
if let Some(f) = t.executable() {
|
||||
match f.o(&Type::empty_tuple()) {
|
||||
Ok(t) => out.add_all(&t),
|
||||
Err(e) => return Err(CheckError::new().msg_str(format!("Can't call thread on a function which can't be called on an empty tuple: ")).err(e))
|
||||
@ -47,24 +47,15 @@ impl Config {
|
||||
Ok(Type::new(ThreadT(out)))
|
||||
}),
|
||||
run: Arc::new(|a, _i| {
|
||||
let a = a.get();
|
||||
if let Some(f) = a
|
||||
.as_any()
|
||||
.downcast_ref::<data::function::Function>()
|
||||
.cloned()
|
||||
{
|
||||
Ok(Data::new(Thread(Arc::new(Mutex::new(Ok(std::thread::spawn(
|
||||
move || f.run(Data::empty_tuple()),
|
||||
move || a.get().execute(Data::empty_tuple()).unwrap(),
|
||||
)))))))
|
||||
} else {
|
||||
return Err("thread called, but arg wasn't a function".into());
|
||||
}
|
||||
}),
|
||||
inner_statements: None,
|
||||
}),
|
||||
)
|
||||
.add_var("thread_finished".to_string(), Data::new(data::function::Function {
|
||||
info: Arc::new(program::run::Info::neverused()),
|
||||
info: program::run::Info::neverused(),
|
||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||
out: Arc::new(|a, _i| {
|
||||
for t in a.types.iter() {
|
||||
@ -85,7 +76,7 @@ impl Config {
|
||||
inner_statements: None,
|
||||
}))
|
||||
.add_var("thread_await".to_string(), Data::new(data::function::Function {
|
||||
info: Arc::new(program::run::Info::neverused()),
|
||||
info: program::run::Info::neverused(),
|
||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||
out: Arc::new(|a, _i| {
|
||||
let mut out = Type::empty();
|
||||
|
@ -22,7 +22,7 @@ impl Config {
|
||||
self.add_var(
|
||||
"read_line".to_string(),
|
||||
Data::new(data::function::Function {
|
||||
info: Arc::new(program::run::Info::neverused()),
|
||||
info: program::run::Info::neverused(),
|
||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||
out: Arc::new(|a, _i| {
|
||||
if a.is_zero_tuple() {
|
||||
@ -50,7 +50,7 @@ impl Config {
|
||||
.add_var(
|
||||
"debug".to_string(),
|
||||
Data::new(data::function::Function {
|
||||
info: Arc::new(program::run::Info::neverused()),
|
||||
info: program::run::Info::neverused(),
|
||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||
out: Arc::new(|a, _i| Ok(a.clone())),
|
||||
run: Arc::new(|a, _i| {
|
||||
@ -65,7 +65,7 @@ impl Config {
|
||||
.add_var(
|
||||
"eprint".to_string(),
|
||||
Data::new(data::function::Function {
|
||||
info: Arc::new(program::run::Info::neverused()),
|
||||
info: program::run::Info::neverused(),
|
||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||
out: Arc::new(|_a, _i| Ok(Type::empty_tuple())),
|
||||
run: Arc::new(|a, _i| {
|
||||
@ -79,7 +79,7 @@ impl Config {
|
||||
.add_var(
|
||||
"eprintln".to_string(),
|
||||
Data::new(data::function::Function {
|
||||
info: Arc::new(program::run::Info::neverused()),
|
||||
info: program::run::Info::neverused(),
|
||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||
out: Arc::new(|_a, _i| Ok(Type::empty_tuple())),
|
||||
run: Arc::new(|a, _i| {
|
||||
@ -92,7 +92,7 @@ impl Config {
|
||||
.add_var(
|
||||
"print".to_string(),
|
||||
Data::new(data::function::Function {
|
||||
info: Arc::new(program::run::Info::neverused()),
|
||||
info: program::run::Info::neverused(),
|
||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||
out: Arc::new(|_a, _i| Ok(Type::empty_tuple())),
|
||||
run: Arc::new(|a, _i| {
|
||||
@ -106,7 +106,7 @@ impl Config {
|
||||
.add_var(
|
||||
"println".to_string(),
|
||||
Data::new(data::function::Function {
|
||||
info: Arc::new(program::run::Info::neverused()),
|
||||
info: program::run::Info::neverused(),
|
||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||
out: Arc::new(|_a, _i| Ok(Type::empty_tuple())),
|
||||
run: Arc::new(|a, _i| {
|
||||
|
@ -36,7 +36,7 @@ impl MersStatement for Function {
|
||||
Ok(Box::new(program::run::function::Function {
|
||||
pos_in_src: self.pos_in_src.clone(),
|
||||
func_no_info: data::function::Function {
|
||||
info: Arc::new(program::run::Info::neverused()),
|
||||
info: program::run::Info::neverused(),
|
||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||
out: Arc::new(move |a, i| {
|
||||
arg2.check(i, Some(a))?;
|
||||
|
@ -54,7 +54,7 @@ impl MersStatement for IncludeMers {
|
||||
chained: Box::new(program::run::function::Function {
|
||||
pos_in_src: self.pos_in_src.clone(),
|
||||
func_no_info: data::function::Function {
|
||||
info: Arc::new(info::Info::neverused()),
|
||||
info: info::Info::neverused(),
|
||||
info_check: Arc::new(Mutex::new(info::Info::neverused())),
|
||||
out: Arc::new(move |_, i| compiled.check(&mut i.duplicate(), None)),
|
||||
run: Arc::new(move |_, i| compiled2.run(&mut i.duplicate())),
|
||||
|
@ -31,10 +31,7 @@ impl MersStatement for Chain {
|
||||
info.global.enable_hooks = prev_enable_hooks;
|
||||
let mut o = Type::empty();
|
||||
for func in &func.types {
|
||||
if let Some(func) = func
|
||||
.as_any()
|
||||
.downcast_ref::<crate::data::function::FunctionT>()
|
||||
{
|
||||
if let Some(func) = func.executable() {
|
||||
match func.o(&arg) {
|
||||
Ok(t) => o.add_all(&t),
|
||||
Err(e) => {
|
||||
@ -89,10 +86,9 @@ impl MersStatement for Chain {
|
||||
let f = self.first.run(info)?;
|
||||
let c = self.chained.run(info)?;
|
||||
let c = c.get();
|
||||
if let Some(func) = c.as_any().downcast_ref::<crate::data::function::Function>() {
|
||||
match func.run(f) {
|
||||
Ok(v) => Ok(v),
|
||||
Err(e) => Err(if let Some(_) = &self.as_part_of_include {
|
||||
match c.execute(f) {
|
||||
Some(Ok(v)) => Ok(v),
|
||||
Some(Err(e)) => Err(if let Some(_) = &self.as_part_of_include {
|
||||
CheckError::new().err_with_diff_src(e).src(vec![(
|
||||
self.pos_in_src.clone(),
|
||||
Some(EColor::StacktraceDescendHashInclude),
|
||||
@ -103,14 +99,12 @@ impl MersStatement for Chain {
|
||||
(self.source_range(), Some(EColor::StacktraceDescend)),
|
||||
])
|
||||
}),
|
||||
}
|
||||
} else {
|
||||
Err(CheckError::new()
|
||||
None => Err(CheckError::new()
|
||||
.msg_str("tried to chain with non-function".to_owned())
|
||||
.src(vec![(
|
||||
self.chained.source_range(),
|
||||
Some(EColor::ChainWithNonFunction),
|
||||
)]))
|
||||
)])),
|
||||
}
|
||||
}
|
||||
fn has_scope(&self) -> bool {
|
||||
|
@ -1,8 +1,7 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::{
|
||||
data::{self, Data, MersData, Type},
|
||||
errors::{CheckError, SourceRange},
|
||||
info::Local,
|
||||
};
|
||||
|
||||
use super::MersStatement;
|
||||
@ -26,9 +25,7 @@ impl MersStatement for Function {
|
||||
Ok(self.func_no_info.as_type())
|
||||
}
|
||||
fn run_custom(&self, info: &mut super::Info) -> Result<Data, CheckError> {
|
||||
Ok(Data::new(
|
||||
self.func_no_info.with_info_run(Arc::new(info.clone())),
|
||||
))
|
||||
Ok(Data::new(self.func_no_info.with_info_run(info.duplicate())))
|
||||
}
|
||||
fn has_scope(&self) -> bool {
|
||||
true
|
||||
|
@ -53,7 +53,7 @@ impl MersStatement for Try {
|
||||
let mut func_res = Type::empty();
|
||||
let mut func_err = None;
|
||||
for ft in func.types.iter() {
|
||||
if let Some(ft) = ft.as_any().downcast_ref::<data::function::FunctionT>() {
|
||||
if let Some(ft) = ft.executable() {
|
||||
match ft.o(&Type::newm(vec![Arc::clone(arg)])) {
|
||||
Ok(res) => {
|
||||
func_res.add_all(&res);
|
||||
@ -107,32 +107,18 @@ impl MersStatement for Try {
|
||||
let ar = arg.get();
|
||||
let a = ar.as_ref();
|
||||
let arg_type = a.as_type();
|
||||
let functions = self
|
||||
.funcs
|
||||
.iter()
|
||||
.map(|v| {
|
||||
Ok::<_, CheckError>(
|
||||
v.run(info)?
|
||||
.get()
|
||||
.as_any()
|
||||
.downcast_ref::<data::function::Function>()
|
||||
.unwrap()
|
||||
.clone(),
|
||||
)
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
let mut found = None;
|
||||
for (i, func) in functions.iter().enumerate() {
|
||||
match func.get_as_type().o(&arg_type) {
|
||||
Ok(_) => {
|
||||
found = Some(i);
|
||||
break;
|
||||
}
|
||||
Err(_) => (),
|
||||
}
|
||||
}
|
||||
for func in self.funcs.iter() {
|
||||
let func = func.run(info)?;
|
||||
let func = func.get();
|
||||
match func.executable().map(|func| func.o(&arg_type)) {
|
||||
Some(Ok(_)) => {
|
||||
drop(ar);
|
||||
functions[found.expect("try: no function found")].run(arg)
|
||||
return func.execute(arg).unwrap();
|
||||
}
|
||||
None | Some(Err(_)) => (),
|
||||
}
|
||||
}
|
||||
panic!("try: no function found")
|
||||
}
|
||||
fn has_scope(&self) -> bool {
|
||||
true
|
||||
|
Loading…
Reference in New Issue
Block a user