mirror of
https://github.com/Dummi26/mers.git
synced 2025-12-11 18:16:50 +01:00
feat: reference destructuring pattern { a: a } := &o
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "mers"
|
name = "mers"
|
||||||
version = "0.9.26"
|
version = "0.9.28"
|
||||||
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.26"
|
mers_lib = "0.9.28"
|
||||||
# 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.26"
|
version = "0.9.28"
|
||||||
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"
|
||||||
|
|||||||
@@ -6,33 +6,70 @@ pub fn assign(from: &Data, target: &Data) {
|
|||||||
.as_any()
|
.as_any()
|
||||||
.downcast_ref::<crate::data::reference::Reference>()
|
.downcast_ref::<crate::data::reference::Reference>()
|
||||||
{
|
{
|
||||||
*r.0.write().unwrap() = from.clone();
|
*r.write() = from.clone();
|
||||||
} else if let (Some(from), Some(target)) = (
|
} else if let (Some((from, from_ref)), Some(target)) = (
|
||||||
from.get()
|
from.get()
|
||||||
.as_any()
|
.as_any()
|
||||||
.downcast_ref::<crate::data::tuple::Tuple>(),
|
.downcast_ref::<crate::data::tuple::Tuple>()
|
||||||
|
.map(|v| (v.clone(), false))
|
||||||
|
.or_else(|| {
|
||||||
|
from.get()
|
||||||
|
.as_any()
|
||||||
|
.downcast_ref::<crate::data::reference::Reference>()
|
||||||
|
.and_then(|r| {
|
||||||
|
r.read()
|
||||||
|
.get()
|
||||||
|
.as_any()
|
||||||
|
.downcast_ref::<crate::data::tuple::Tuple>()
|
||||||
|
.map(|v| (v.clone_refs(), true))
|
||||||
|
})
|
||||||
|
}),
|
||||||
target
|
target
|
||||||
.get()
|
.get()
|
||||||
.as_any()
|
.as_any()
|
||||||
.downcast_ref::<crate::data::tuple::Tuple>(),
|
.downcast_ref::<crate::data::tuple::Tuple>(),
|
||||||
) {
|
) {
|
||||||
for (from, target) in from.0.iter().zip(target.0.iter()) {
|
for (from, target) in from.0.into_iter().zip(target.0.iter()) {
|
||||||
assign(from, target);
|
if from_ref {
|
||||||
|
assign(&Data::new(from), &*target.read());
|
||||||
|
} else {
|
||||||
|
assign(&*from.read(), &*target.read());
|
||||||
}
|
}
|
||||||
} else if let (Some(from), Some(target)) = (
|
}
|
||||||
|
} else if let (Some((from, from_ref)), Some(target)) = (
|
||||||
from.get()
|
from.get()
|
||||||
.as_any()
|
.as_any()
|
||||||
.downcast_ref::<crate::data::object::Object>(),
|
.downcast_ref::<crate::data::object::Object>()
|
||||||
|
.map(|v| (v.clone(), false))
|
||||||
|
.or_else(|| {
|
||||||
|
from.get()
|
||||||
|
.as_any()
|
||||||
|
.downcast_ref::<crate::data::reference::Reference>()
|
||||||
|
.and_then(|r| {
|
||||||
|
r.read()
|
||||||
|
.get()
|
||||||
|
.as_any()
|
||||||
|
.downcast_ref::<crate::data::object::Object>()
|
||||||
|
.map(|v| (v.clone_refs(), true))
|
||||||
|
})
|
||||||
|
}),
|
||||||
target
|
target
|
||||||
.get()
|
.get()
|
||||||
.as_any()
|
.as_any()
|
||||||
.downcast_ref::<crate::data::object::Object>(),
|
.downcast_ref::<crate::data::object::Object>(),
|
||||||
) {
|
) {
|
||||||
for (field, target) in target.iter() {
|
for (field, target) in target.iter() {
|
||||||
|
if from_ref {
|
||||||
|
let from = from
|
||||||
|
.get_mut(*field)
|
||||||
|
.expect("type-checks should guarantee that from has every field of target");
|
||||||
|
assign(&Data::new(from.clone_ref()), &*target.read());
|
||||||
|
} else {
|
||||||
let from = from
|
let from = from
|
||||||
.get(*field)
|
.get(*field)
|
||||||
.expect("type-checks should guarantee that from has every field of target");
|
.expect("type-checks should guarantee that from has every field of target");
|
||||||
assign(from, target);
|
assign(&from, &*target.read());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
unreachable!("invalid assignment")
|
unreachable!("invalid assignment")
|
||||||
|
|||||||
@@ -225,7 +225,7 @@ impl Data {
|
|||||||
Self::new(tuple::Tuple(vec![]))
|
Self::new(tuple::Tuple(vec![]))
|
||||||
}
|
}
|
||||||
pub fn one_tuple(v: Self) -> Self {
|
pub fn one_tuple(v: Self) -> Self {
|
||||||
Self::new(tuple::Tuple(vec![v]))
|
Self::new(tuple::Tuple::from([v]))
|
||||||
}
|
}
|
||||||
/// Returns true if self is `()`.
|
/// Returns true if self is `()`.
|
||||||
pub fn is_zero_tuple(&self) -> bool {
|
pub fn is_zero_tuple(&self) -> bool {
|
||||||
@@ -253,13 +253,13 @@ impl Data {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn get(&self) -> RwLockReadGuard<Box<dyn MersData>> {
|
pub fn get(&'_ self) -> RwLockReadGuard<'_, Box<dyn MersData>> {
|
||||||
self.data.read().unwrap()
|
self.data.read().unwrap()
|
||||||
}
|
}
|
||||||
pub fn get_mut_unchecked(&self) -> RwLockWriteGuard<Box<dyn MersData>> {
|
pub fn get_mut_unchecked(&'_ self) -> RwLockWriteGuard<'_, Box<dyn MersData>> {
|
||||||
self.data.write().unwrap()
|
self.data.write().unwrap()
|
||||||
}
|
}
|
||||||
pub fn try_get_mut(&self) -> Option<RwLockWriteGuard<Box<dyn MersData>>> {
|
pub fn try_get_mut(&'_ self) -> Option<RwLockWriteGuard<'_, Box<dyn MersData>>> {
|
||||||
if self.is_mut && self.counts.0.load(std::sync::atomic::Ordering::Relaxed) == 0 {
|
if self.is_mut && self.counts.0.load(std::sync::atomic::Ordering::Relaxed) == 0 {
|
||||||
Some(self.get_mut_unchecked())
|
Some(self.get_mut_unchecked())
|
||||||
} else {
|
} else {
|
||||||
@@ -268,7 +268,7 @@ impl Data {
|
|||||||
}
|
}
|
||||||
/// like try_get_mut, but instead of returning `None` this function `get()`s the data and clones it.
|
/// like try_get_mut, but instead of returning `None` this function `get()`s the data and clones it.
|
||||||
/// When cloning data, this transforms `self` into a `Data` with `is_mut: true`, hence the `&mut self` parameter.
|
/// When cloning data, this transforms `self` into a `Data` with `is_mut: true`, hence the `&mut self` parameter.
|
||||||
pub fn get_mut(&mut self) -> RwLockWriteGuard<Box<dyn MersData>> {
|
pub fn get_mut(&'_ mut self) -> RwLockWriteGuard<'_, Box<dyn MersData>> {
|
||||||
if self.try_get_mut().is_none() {
|
if self.try_get_mut().is_none() {
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
eprintln!(
|
eprintln!(
|
||||||
|
|||||||
@@ -7,18 +7,33 @@ use crate::info::DisplayInfo;
|
|||||||
|
|
||||||
use super::{Data, MersData, MersDataWInfo, MersType, Type};
|
use super::{Data, MersData, MersDataWInfo, MersType, Type};
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub struct Object(Vec<(usize, Data)>);
|
pub struct Object(Vec<(usize, super::reference::Reference)>);
|
||||||
impl Object {
|
impl Object {
|
||||||
pub fn new(v: Vec<(usize, Data)>) -> Self {
|
pub fn new(v: impl IntoIterator<Item = (usize, Data)>) -> Self {
|
||||||
Self(v)
|
Self(
|
||||||
|
v.into_iter()
|
||||||
|
.map(|(i, d)| (i, super::reference::Reference::from(d)))
|
||||||
|
.collect(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
pub fn get(&self, f: usize) -> Option<&Data> {
|
pub fn get(&self, f: usize) -> Option<Data> {
|
||||||
self.iter().find(|v| v.0 == f).map(|v| &v.1)
|
self.iter().find(|v| v.0 == f).map(|v| v.1.read().clone())
|
||||||
}
|
}
|
||||||
pub fn iter(&self) -> std::slice::Iter<(usize, Data)> {
|
pub fn get_mut(&self, f: usize) -> Option<&super::reference::Reference> {
|
||||||
|
self.iter().find(|v| v.0 == f).map(|(_, v)| v)
|
||||||
|
}
|
||||||
|
pub fn iter(&'_ self) -> std::slice::Iter<'_, (usize, super::reference::Reference)> {
|
||||||
self.0.iter()
|
self.0.iter()
|
||||||
}
|
}
|
||||||
|
pub fn clone_refs(&self) -> Self {
|
||||||
|
Self(self.0.iter().map(|(i, r)| (*i, r.clone_ref())).collect())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Clone for Object {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
Self(self.0.iter().map(|(i, r)| (*i, r.clone_data())).collect())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct ObjectT(Vec<(usize, Type)>);
|
pub struct ObjectT(Vec<(usize, Type)>);
|
||||||
@@ -29,7 +44,7 @@ impl ObjectT {
|
|||||||
pub fn get(&self, f: usize) -> Option<&Type> {
|
pub fn get(&self, f: usize) -> Option<&Type> {
|
||||||
self.iter().find(|v| v.0 == f).map(|v| &v.1)
|
self.iter().find(|v| v.0 == f).map(|v| &v.1)
|
||||||
}
|
}
|
||||||
pub fn iter(&self) -> std::slice::Iter<(usize, Type)> {
|
pub fn iter(&'_ self) -> std::slice::Iter<'_, (usize, Type)> {
|
||||||
self.0.iter()
|
self.0.iter()
|
||||||
}
|
}
|
||||||
fn len(&self) -> usize {
|
fn len(&self) -> usize {
|
||||||
@@ -49,7 +64,7 @@ impl MersData for Object {
|
|||||||
f,
|
f,
|
||||||
"{}: {}",
|
"{}: {}",
|
||||||
info.get_object_field_name(*field),
|
info.get_object_field_name(*field),
|
||||||
val.get().with_display(info)
|
val.read().get().with_display(info)
|
||||||
)?;
|
)?;
|
||||||
comma_sep = true;
|
comma_sep = true;
|
||||||
}
|
}
|
||||||
@@ -69,7 +84,7 @@ impl MersData for Object {
|
|||||||
fn as_type(&self) -> Type {
|
fn as_type(&self) -> Type {
|
||||||
Type::new(ObjectT(
|
Type::new(ObjectT(
|
||||||
self.iter()
|
self.iter()
|
||||||
.map(|(n, v)| (n.clone(), v.get().as_type()))
|
.map(|(n, v)| (n.clone(), v.read().get().as_type()))
|
||||||
.collect(),
|
.collect(),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,32 @@
|
|||||||
use std::{
|
use std::{
|
||||||
any::Any,
|
any::Any,
|
||||||
sync::{Arc, RwLock},
|
sync::{Arc, RwLock, RwLockReadGuard, RwLockWriteGuard},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{errors::CheckError, info::DisplayInfo};
|
use crate::{errors::CheckError, info::DisplayInfo};
|
||||||
|
|
||||||
use super::{Data, MersData, MersType, Type};
|
use super::{Data, MersData, MersType, Type};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug)]
|
||||||
pub struct Reference(pub Arc<RwLock<Data>>);
|
pub struct Reference(Arc<RwLock<Data>>);
|
||||||
|
|
||||||
|
impl Reference {
|
||||||
|
/// Creates a reference from data,
|
||||||
|
/// so that the original data can't be
|
||||||
|
/// modified through the new reference.
|
||||||
|
pub fn from(data: Data) -> Self {
|
||||||
|
Self(Arc::new(RwLock::new(data.mkref().0)))
|
||||||
|
}
|
||||||
|
pub fn raw(reference: Arc<RwLock<Data>>) -> Self {
|
||||||
|
Self(reference)
|
||||||
|
}
|
||||||
|
pub fn read(&'_ self) -> RwLockReadGuard<'_, Data> {
|
||||||
|
self.0.read().unwrap()
|
||||||
|
}
|
||||||
|
pub fn write(&'_ self) -> RwLockWriteGuard<'_, Data> {
|
||||||
|
self.0.write().unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl MersData for Reference {
|
impl MersData for Reference {
|
||||||
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 {
|
||||||
@@ -79,7 +97,7 @@ impl MersData for Reference {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn clone(&self) -> Box<dyn MersData> {
|
fn clone(&self) -> Box<dyn MersData> {
|
||||||
Box::new(Clone::clone(self))
|
Box::new(self.clone_ref())
|
||||||
}
|
}
|
||||||
fn as_type(&self) -> Type {
|
fn as_type(&self) -> Type {
|
||||||
Type::new(ReferenceT(self.0.read().unwrap().get().as_type()))
|
Type::new(ReferenceT(self.0.read().unwrap().get().as_type()))
|
||||||
@@ -95,6 +113,23 @@ impl MersData for Reference {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Reference {
|
||||||
|
pub fn clone_ref(&self) -> Self {
|
||||||
|
Self(Arc::clone(&self.0))
|
||||||
|
}
|
||||||
|
pub fn clone_data(&self) -> Self {
|
||||||
|
Self(Arc::new(RwLock::new(
|
||||||
|
self.0.read().unwrap().clone().mkref().0,
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialEq for Reference {
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
*self.0.read().unwrap() == *other.0.read().unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct ReferenceT(pub Type);
|
pub struct ReferenceT(pub Type);
|
||||||
impl MersType for ReferenceT {
|
impl MersType for ReferenceT {
|
||||||
|
|||||||
@@ -4,15 +4,38 @@ use crate::{errors::CheckError, info::DisplayInfo};
|
|||||||
|
|
||||||
use super::{Data, MersData, MersType, Type};
|
use super::{Data, MersData, MersType, Type};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug)]
|
||||||
pub struct Tuple(pub Vec<Data>);
|
pub struct Tuple(pub Vec<super::reference::Reference>);
|
||||||
|
|
||||||
impl Tuple {
|
impl Tuple {
|
||||||
|
pub fn empty() -> Self {
|
||||||
|
Self(vec![])
|
||||||
|
}
|
||||||
|
pub fn from(elems: impl IntoIterator<Item = Data>) -> Self {
|
||||||
|
Self(
|
||||||
|
elems
|
||||||
|
.into_iter()
|
||||||
|
.map(|d| super::reference::Reference::from(d))
|
||||||
|
.collect(),
|
||||||
|
)
|
||||||
|
}
|
||||||
pub fn len(&self) -> usize {
|
pub fn len(&self) -> usize {
|
||||||
self.0.len()
|
self.0.len()
|
||||||
}
|
}
|
||||||
pub fn get(&self, i: usize) -> Option<&Data> {
|
pub fn get(&self, i: usize) -> Option<Data> {
|
||||||
self.0.get(i)
|
self.0.get(i).map(|v| v.read().clone())
|
||||||
|
}
|
||||||
|
pub fn get_mut(&self, i: usize) -> Option<super::reference::Reference> {
|
||||||
|
self.0.get(i).map(|v| v.clone_ref())
|
||||||
|
}
|
||||||
|
pub fn clone_refs(&self) -> Self {
|
||||||
|
Self(self.0.iter().map(|r| r.clone_ref()).collect())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Clone for Tuple {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
Self(self.0.iter().map(|r| r.clone_data()).collect())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -23,7 +46,7 @@ impl MersData for Tuple {
|
|||||||
if i > 0 {
|
if i > 0 {
|
||||||
write!(f, ", ")?;
|
write!(f, ", ")?;
|
||||||
}
|
}
|
||||||
c.get().display(info, f)?;
|
c.read().get().display(info, f)?;
|
||||||
}
|
}
|
||||||
write!(f, ")")?;
|
write!(f, ")")?;
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -39,13 +62,21 @@ impl MersData for Tuple {
|
|||||||
&self,
|
&self,
|
||||||
_gi: &crate::program::run::RunLocalGlobalInfo,
|
_gi: &crate::program::run::RunLocalGlobalInfo,
|
||||||
) -> Option<Box<dyn Iterator<Item = Result<Data, CheckError>>>> {
|
) -> Option<Box<dyn Iterator<Item = Result<Data, CheckError>>>> {
|
||||||
Some(Box::new(self.0.clone().into_iter().map(Ok)))
|
Some(Box::new(
|
||||||
|
Clone::clone(self)
|
||||||
|
.0
|
||||||
|
.into_iter()
|
||||||
|
.map(|r| r.read().clone())
|
||||||
|
.map(Ok),
|
||||||
|
))
|
||||||
}
|
}
|
||||||
fn clone(&self) -> Box<dyn MersData> {
|
fn clone(&self) -> Box<dyn MersData> {
|
||||||
Box::new(Clone::clone(self))
|
Box::new(Clone::clone(self))
|
||||||
}
|
}
|
||||||
fn as_type(&self) -> Type {
|
fn as_type(&self) -> Type {
|
||||||
Type::new(TupleT(self.0.iter().map(|v| v.get().as_type()).collect()))
|
Type::new(TupleT(
|
||||||
|
self.0.iter().map(|v| v.read().get().as_type()).collect(),
|
||||||
|
))
|
||||||
}
|
}
|
||||||
fn as_any(&self) -> &dyn Any {
|
fn as_any(&self) -> &dyn Any {
|
||||||
self
|
self
|
||||||
|
|||||||
@@ -178,7 +178,7 @@ impl CheckErrorHRConfig {
|
|||||||
.color(s, EColor::Indent(self.color_index), &mut t);
|
.color(s, EColor::Indent(self.color_index), &mut t);
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
pub fn indent_start(&self, right: bool) -> IndentStr {
|
pub fn indent_start(&'_ self, right: bool) -> IndentStr<'_> {
|
||||||
IndentStr(
|
IndentStr(
|
||||||
&self.idt_start,
|
&self.idt_start,
|
||||||
self.color(
|
self.color(
|
||||||
@@ -186,13 +186,13 @@ impl CheckErrorHRConfig {
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
pub fn indent_default(&self, right: bool) -> IndentStr {
|
pub fn indent_default(&'_ self, right: bool) -> IndentStr<'_> {
|
||||||
IndentStr(
|
IndentStr(
|
||||||
&self.idt_default,
|
&self.idt_default,
|
||||||
self.color(Self::CHARS[self.style as usize][1][right as usize]),
|
self.color(Self::CHARS[self.style as usize][1][right as usize]),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
pub fn indent_end(&self, right: bool) -> IndentStr {
|
pub fn indent_end(&'_ self, right: bool) -> IndentStr<'_> {
|
||||||
IndentStr(
|
IndentStr(
|
||||||
&self.idt_end,
|
&self.idt_end,
|
||||||
self.color(
|
self.color(
|
||||||
@@ -200,7 +200,7 @@ impl CheckErrorHRConfig {
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
pub fn indent_single(&self, right: bool) -> IndentStr {
|
pub fn indent_single(&'_ self, right: bool) -> IndentStr<'_> {
|
||||||
IndentStr(
|
IndentStr(
|
||||||
&self.idt_single,
|
&self.idt_single,
|
||||||
self.color(if self.is_inner {
|
self.color(if self.is_inner {
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ impl<A: FromMersData> FromMersData for OneOrNone<A> {
|
|||||||
if v.0.is_empty() {
|
if v.0.is_empty() {
|
||||||
f(Some(Self(None)))
|
f(Some(Self(None)))
|
||||||
} else {
|
} else {
|
||||||
A::try_represent(v.0[0].get().as_ref(), |v1| {
|
A::try_represent(v.0[0].read().get().as_ref(), |v1| {
|
||||||
if let Some(va) = v1 {
|
if let Some(va) = v1 {
|
||||||
f(Some(Self(Some(va))))
|
f(Some(Self(Some(va))))
|
||||||
} else {
|
} else {
|
||||||
@@ -205,7 +205,7 @@ impl<A: FromMersData> FromMersData for (A,) {
|
|||||||
.downcast_ref::<data::tuple::Tuple>()
|
.downcast_ref::<data::tuple::Tuple>()
|
||||||
.filter(|v| v.0.len() == 1)
|
.filter(|v| v.0.len() == 1)
|
||||||
{
|
{
|
||||||
A::try_represent(v.0[0].get().as_ref(), |v1| {
|
A::try_represent(v.0[0].read().get().as_ref(), |v1| {
|
||||||
if let Some(va) = v1 {
|
if let Some(va) = v1 {
|
||||||
f(Some((va,)))
|
f(Some((va,)))
|
||||||
} else {
|
} else {
|
||||||
@@ -222,7 +222,7 @@ impl<A: ToMersData> ToMersData for (A,) {
|
|||||||
Type::new(data::tuple::TupleT(vec![A::as_type_to()]))
|
Type::new(data::tuple::TupleT(vec![A::as_type_to()]))
|
||||||
}
|
}
|
||||||
fn represent(self) -> Data {
|
fn represent(self) -> Data {
|
||||||
Data::new(data::tuple::Tuple(vec![self.0.represent()]))
|
Data::new(data::tuple::Tuple::from([self.0.represent()]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -242,9 +242,9 @@ impl<A: FromMersData, B: FromMersData> FromMersData for (A, B) {
|
|||||||
.downcast_ref::<data::tuple::Tuple>()
|
.downcast_ref::<data::tuple::Tuple>()
|
||||||
.filter(|v| v.0.len() == 2)
|
.filter(|v| v.0.len() == 2)
|
||||||
{
|
{
|
||||||
A::try_represent(v.0[0].get().as_ref(), |v1| {
|
A::try_represent(v.0[0].read().get().as_ref(), |v1| {
|
||||||
if let Some(va) = v1 {
|
if let Some(va) = v1 {
|
||||||
B::try_represent(v.0[1].get().as_ref(), |v2| {
|
B::try_represent(v.0[1].read().get().as_ref(), |v2| {
|
||||||
if let Some(vb) = v2 {
|
if let Some(vb) = v2 {
|
||||||
f(Some((va, vb)))
|
f(Some((va, vb)))
|
||||||
} else {
|
} else {
|
||||||
@@ -265,7 +265,7 @@ impl<A: ToMersData, B: ToMersData> ToMersData for (A, B) {
|
|||||||
Type::new(data::tuple::TupleT(vec![A::as_type_to(), B::as_type_to()]))
|
Type::new(data::tuple::TupleT(vec![A::as_type_to(), B::as_type_to()]))
|
||||||
}
|
}
|
||||||
fn represent(self) -> Data {
|
fn represent(self) -> Data {
|
||||||
Data::new(data::tuple::Tuple(vec![
|
Data::new(data::tuple::Tuple::from([
|
||||||
self.0.represent(),
|
self.0.represent(),
|
||||||
self.1.represent(),
|
self.1.represent(),
|
||||||
]))
|
]))
|
||||||
@@ -288,11 +288,11 @@ impl<A: FromMersData, B: FromMersData, C: FromMersData> FromMersData for (A, B,
|
|||||||
.downcast_ref::<data::tuple::Tuple>()
|
.downcast_ref::<data::tuple::Tuple>()
|
||||||
.filter(|v| v.0.len() == 3)
|
.filter(|v| v.0.len() == 3)
|
||||||
{
|
{
|
||||||
A::try_represent(v.0[0].get().as_ref(), |v1| {
|
A::try_represent(v.0[0].read().get().as_ref(), |v1| {
|
||||||
if let Some(va) = v1 {
|
if let Some(va) = v1 {
|
||||||
B::try_represent(v.0[1].get().as_ref(), |v2| {
|
B::try_represent(v.0[1].read().get().as_ref(), |v2| {
|
||||||
if let Some(vb) = v2 {
|
if let Some(vb) = v2 {
|
||||||
C::try_represent(v.0[2].get().as_ref(), |v3| {
|
C::try_represent(v.0[2].read().get().as_ref(), |v3| {
|
||||||
if let Some(vc) = v3 {
|
if let Some(vc) = v3 {
|
||||||
f(Some((va, vb, vc)))
|
f(Some((va, vb, vc)))
|
||||||
} else {
|
} else {
|
||||||
@@ -321,7 +321,7 @@ impl<A: ToMersData, B: ToMersData, C: ToMersData> ToMersData for (A, B, C) {
|
|||||||
]))
|
]))
|
||||||
}
|
}
|
||||||
fn represent(self) -> Data {
|
fn represent(self) -> Data {
|
||||||
Data::new(data::tuple::Tuple(vec![
|
Data::new(data::tuple::Tuple::from([
|
||||||
self.0.represent(),
|
self.0.represent(),
|
||||||
self.1.represent(),
|
self.1.represent(),
|
||||||
self.2.represent(),
|
self.2.represent(),
|
||||||
|
|||||||
@@ -100,8 +100,10 @@ pub fn to_mers_func_concrete_string_string_to_any(
|
|||||||
move |a, _| {
|
move |a, _| {
|
||||||
let a = a.get();
|
let a = a.get();
|
||||||
let a = &a.as_any().downcast_ref::<data::tuple::Tuple>().unwrap().0;
|
let a = &a.as_any().downcast_ref::<data::tuple::Tuple>().unwrap().0;
|
||||||
let l = a[0].get();
|
let l = a[0].read();
|
||||||
let r = a[1].get();
|
let l = l.get();
|
||||||
|
let r = a[1].read();
|
||||||
|
let r = r.get();
|
||||||
f(
|
f(
|
||||||
l.as_any()
|
l.as_any()
|
||||||
.downcast_ref::<data::string::String>()
|
.downcast_ref::<data::string::String>()
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use std::{
|
use std::{
|
||||||
sync::{Arc, Mutex, RwLock},
|
sync::{Arc, Mutex},
|
||||||
time::{Duration, Instant},
|
time::{Duration, Instant},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -68,10 +68,12 @@ impl Config {
|
|||||||
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].read();
|
||||||
|
let arg_ref = arg_ref.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.write();
|
||||||
let func = a.0[1].get();
|
let func = a.0[1].read();
|
||||||
|
let func = func.get();
|
||||||
*arg = func.execute(arg.clone(), &i.global).unwrap()?;
|
*arg = func.execute(arg.clone(), &i.global).unwrap()?;
|
||||||
Ok(Data::empty_tuple())
|
Ok(Data::empty_tuple())
|
||||||
}),
|
}),
|
||||||
@@ -168,7 +170,7 @@ impl Config {
|
|||||||
fixed_type_out: Arc::new(Mutex::new(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::from(a)))
|
||||||
}),
|
}),
|
||||||
inner_statements: None,
|
inner_statements: None,
|
||||||
},
|
},
|
||||||
@@ -188,7 +190,7 @@ impl Config {
|
|||||||
.as_any()
|
.as_any()
|
||||||
.downcast_ref::<data::reference::Reference>()
|
.downcast_ref::<data::reference::Reference>()
|
||||||
{
|
{
|
||||||
Ok(r.0.write().unwrap().clone())
|
Ok(r.read().clone())
|
||||||
} else {
|
} else {
|
||||||
Err("called deref on non-reference".into())
|
Err("called deref on non-reference".into())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ impl Config {
|
|||||||
run: Arc::new(|a, i| {
|
run: Arc::new(|a, i| {
|
||||||
let a = a.get();
|
let a = a.get();
|
||||||
let cmd = a.as_any().downcast_ref::<data::tuple::Tuple>().unwrap();
|
let cmd = a.as_any().downcast_ref::<data::tuple::Tuple>().unwrap();
|
||||||
let (cmd, args) = (&cmd.0[0], &cmd.0[1]);
|
let (cmd, args) = (&cmd.0[0].read(), &cmd.0[1].read());
|
||||||
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(),
|
||||||
@@ -74,7 +74,7 @@ impl Config {
|
|||||||
String::from_utf8_lossy(&output.stdout).into_owned();
|
String::from_utf8_lossy(&output.stdout).into_owned();
|
||||||
let stderr =
|
let stderr =
|
||||||
String::from_utf8_lossy(&output.stderr).into_owned();
|
String::from_utf8_lossy(&output.stderr).into_owned();
|
||||||
Ok(Data::new(data::tuple::Tuple(vec![
|
Ok(Data::new(data::tuple::Tuple::from([
|
||||||
status,
|
status,
|
||||||
Data::new(data::string::String(stdout)),
|
Data::new(data::string::String(stdout)),
|
||||||
Data::new(data::string::String(stderr)),
|
Data::new(data::string::String(stderr)),
|
||||||
@@ -106,7 +106,7 @@ impl Config {
|
|||||||
run: Arc::new(|a, i| {
|
run: Arc::new(|a, i| {
|
||||||
let a = a.get();
|
let a = a.get();
|
||||||
let cmd = a.as_any().downcast_ref::<data::tuple::Tuple>().unwrap();
|
let cmd = a.as_any().downcast_ref::<data::tuple::Tuple>().unwrap();
|
||||||
let (cmd, args) = (&cmd.0[0], &cmd.0[1]);
|
let (cmd, args) = (&cmd.0[0].read(), &cmd.0[1].read());
|
||||||
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(),
|
||||||
@@ -215,8 +215,10 @@ impl Config {
|
|||||||
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].read();
|
||||||
let bytes = tuple.0[1].get();
|
let child = child.get();
|
||||||
|
let bytes = tuple.0[1].read();
|
||||||
|
let bytes = bytes.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(&i.global).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<_>, _>>()?;
|
||||||
@@ -246,8 +248,10 @@ impl Config {
|
|||||||
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].read();
|
||||||
let string = tuple.0[1].get();
|
let child = child.get();
|
||||||
|
let string = tuple.0[1].read();
|
||||||
|
let string = string.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 = string.as_any().downcast_ref::<data::string::String>().unwrap().0.as_bytes();
|
let buf = string.as_any().downcast_ref::<data::string::String>().unwrap().0.as_bytes();
|
||||||
|
|||||||
@@ -76,7 +76,8 @@ impl Config {
|
|||||||
.as_any()
|
.as_any()
|
||||||
.downcast_ref::<Tuple>()
|
.downcast_ref::<Tuple>()
|
||||||
.expect("got non-tuple argument to fs_read_text");
|
.expect("got non-tuple argument to fs_read_text");
|
||||||
let (a, b) = (a.0[0].get(), a.0[1].get());
|
let (a, b) = (a.0[0].read(), a.0[1].read());
|
||||||
|
let (a, b) = (a.get(), b.get());
|
||||||
let a = a
|
let a = a
|
||||||
.as_any()
|
.as_any()
|
||||||
.downcast_ref::<data::string::String>()
|
.downcast_ref::<data::string::String>()
|
||||||
|
|||||||
@@ -74,7 +74,8 @@ impl Config {
|
|||||||
}, |a, _| {
|
}, |a, _| {
|
||||||
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 (v, e) = (a.0[0].get(), a.0[1].get());
|
let (v, e) = (a.0[0].read(), a.0[1].read());
|
||||||
|
let (v, e) = (v.get(), e.get());
|
||||||
let (v, e) = (v.as_any().downcast_ref::<data::int::Int>().unwrap(), e.as_any().downcast_ref::<data::int::Int>().unwrap());
|
let (v, e) = (v.as_any().downcast_ref::<data::int::Int>().unwrap(), e.as_any().downcast_ref::<data::int::Int>().unwrap());
|
||||||
Ok(Data::new(Range(v.0, e.0)))
|
Ok(Data::new(Range(v.0, e.0)))
|
||||||
}
|
}
|
||||||
@@ -114,7 +115,8 @@ impl Config {
|
|||||||
}, |a, _| {
|
}, |a, _| {
|
||||||
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 (v, e) = (a.0[0].get(), a.0[1].get());
|
let (v, e) = (a.0[0].read(), a.0[1].read());
|
||||||
|
let (v, e) = (v.get(), e.get());
|
||||||
let (v, e) = (v.as_any().downcast_ref::<data::int::Int>().unwrap(), e.as_any().downcast_ref::<data::int::Int>().unwrap());
|
let (v, e) = (v.as_any().downcast_ref::<data::int::Int>().unwrap(), e.as_any().downcast_ref::<data::int::Int>().unwrap());
|
||||||
if let Some(e) = e.0.checked_sub(1) {
|
if let Some(e) = e.0.checked_sub(1) {
|
||||||
Ok(Data::new(Range(v.0, e)))
|
Ok(Data::new(Range(v.0, e)))
|
||||||
@@ -495,7 +497,7 @@ impl MersData for Iter {
|
|||||||
.iterable(&gi)?
|
.iterable(&gi)?
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(i, v)| match v {
|
.map(|(i, v)| match v {
|
||||||
Ok(v) => Ok(Data::new(data::tuple::Tuple(vec![
|
Ok(v) => Ok(Data::new(data::tuple::Tuple::from([
|
||||||
Data::new(data::int::Int(i as _)),
|
Data::new(data::int::Int(i as _)),
|
||||||
v,
|
v,
|
||||||
]))),
|
]))),
|
||||||
|
|||||||
@@ -65,9 +65,7 @@ impl Config {
|
|||||||
.as_any()
|
.as_any()
|
||||||
.downcast_ref::<data::reference::Reference>()
|
.downcast_ref::<data::reference::Reference>()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.0
|
|
||||||
.write()
|
.write()
|
||||||
.unwrap()
|
|
||||||
.get_mut()
|
.get_mut()
|
||||||
.mut_any()
|
.mut_any()
|
||||||
.downcast_mut::<List>()
|
.downcast_mut::<List>()
|
||||||
@@ -128,20 +126,18 @@ impl Config {
|
|||||||
run: Arc::new(|a, _i| {
|
run: Arc::new(|a, _i| {
|
||||||
let tuple = a.get();
|
let tuple = a.get();
|
||||||
let tuple = tuple.as_any().downcast_ref::<data::tuple::Tuple>().unwrap();
|
let tuple = tuple.as_any().downcast_ref::<data::tuple::Tuple>().unwrap();
|
||||||
tuple.0[0]
|
tuple.0[0].read()
|
||||||
.get()
|
.get()
|
||||||
.as_any()
|
.as_any()
|
||||||
.downcast_ref::<data::reference::Reference>()
|
.downcast_ref::<data::reference::Reference>()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.0
|
|
||||||
.write()
|
.write()
|
||||||
.unwrap()
|
|
||||||
.get_mut()
|
.get_mut()
|
||||||
.mut_any()
|
.mut_any()
|
||||||
.downcast_mut::<List>()
|
.downcast_mut::<List>()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.0
|
.0
|
||||||
.push(tuple.0[1].clone());
|
.push(tuple.0[1].read().clone());
|
||||||
Ok(Data::empty_tuple())
|
Ok(Data::empty_tuple())
|
||||||
}),
|
}),
|
||||||
inner_statements: None,
|
inner_statements: None,
|
||||||
@@ -197,15 +193,14 @@ impl Config {
|
|||||||
run: Arc::new(|a, _i| {
|
run: Arc::new(|a, _i| {
|
||||||
let tuple = a.get();
|
let tuple = a.get();
|
||||||
let tuple = tuple.as_any().downcast_ref::<data::tuple::Tuple>().unwrap();
|
let tuple = tuple.as_any().downcast_ref::<data::tuple::Tuple>().unwrap();
|
||||||
let index = tuple.0[1].get().as_any().downcast_ref::<data::int::Int>().unwrap().0 as usize;
|
let index = tuple.0[1].read().get().as_any().downcast_ref::<data::int::Int>().unwrap().0 as usize;
|
||||||
let list = tuple.0[0]
|
let list = tuple.0[0].read();
|
||||||
.get();
|
let list = list.get();
|
||||||
let mut list = list
|
let mut list = list
|
||||||
.as_any()
|
.as_any()
|
||||||
.downcast_ref::<data::reference::Reference>()
|
.downcast_ref::<data::reference::Reference>()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.0
|
.write();
|
||||||
.write().unwrap();
|
|
||||||
let mut list = list
|
let mut list = list
|
||||||
.get_mut();
|
.get_mut();
|
||||||
let list = list
|
let list = list
|
||||||
@@ -215,7 +210,7 @@ impl Config {
|
|||||||
if index > list.0.len() {
|
if index > list.0.len() {
|
||||||
Ok(Data::new(data::bool::Bool(false)))
|
Ok(Data::new(data::bool::Bool(false)))
|
||||||
} else {
|
} else {
|
||||||
list.0.insert(index, tuple.0[2].clone());
|
list.0.insert(index, tuple.0[2].read().clone());
|
||||||
Ok(Data::new(data::bool::Bool(true)))
|
Ok(Data::new(data::bool::Bool(true)))
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
@@ -277,15 +272,14 @@ impl Config {
|
|||||||
run: Arc::new(|a, _i| {
|
run: Arc::new(|a, _i| {
|
||||||
let tuple = a.get();
|
let tuple = a.get();
|
||||||
let tuple = tuple.as_any().downcast_ref::<data::tuple::Tuple>().unwrap();
|
let tuple = tuple.as_any().downcast_ref::<data::tuple::Tuple>().unwrap();
|
||||||
let index = tuple.0[1].get().as_any().downcast_ref::<data::int::Int>().unwrap().0 as usize;
|
let index = tuple.0[1].read().get().as_any().downcast_ref::<data::int::Int>().unwrap().0 as usize;
|
||||||
let list = tuple.0[0]
|
let list = tuple.0[0].read();
|
||||||
.get();
|
let list = list.get();
|
||||||
let mut list = list
|
let mut list = list
|
||||||
.as_any()
|
.as_any()
|
||||||
.downcast_ref::<data::reference::Reference>()
|
.downcast_ref::<data::reference::Reference>()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.0
|
.write();
|
||||||
.write().unwrap();
|
|
||||||
let mut list = list
|
let mut list = list
|
||||||
.get_mut();
|
.get_mut();
|
||||||
let list = list
|
let list = list
|
||||||
@@ -293,7 +287,7 @@ impl Config {
|
|||||||
.downcast_mut::<List>()
|
.downcast_mut::<List>()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
if index < list.0.len() {
|
if index < list.0.len() {
|
||||||
Ok(Data::one_tuple(std::mem::replace(&mut list.0[index], tuple.0[2].clone())))
|
Ok(Data::one_tuple(std::mem::replace(&mut list.0[index], tuple.0[2].read().clone())))
|
||||||
} else {
|
} else {
|
||||||
Ok(Data::empty_tuple())
|
Ok(Data::empty_tuple())
|
||||||
}
|
}
|
||||||
@@ -350,15 +344,14 @@ impl Config {
|
|||||||
run: Arc::new(|a, _i| {
|
run: Arc::new(|a, _i| {
|
||||||
let tuple = a.get();
|
let tuple = a.get();
|
||||||
let tuple = tuple.as_any().downcast_ref::<data::tuple::Tuple>().unwrap();
|
let tuple = tuple.as_any().downcast_ref::<data::tuple::Tuple>().unwrap();
|
||||||
let index = tuple.0[1].get().as_any().downcast_ref::<data::int::Int>().unwrap().0 as usize;
|
let index = tuple.0[1].read().get().as_any().downcast_ref::<data::int::Int>().unwrap().0 as usize;
|
||||||
let list = tuple.0[0]
|
let list = tuple.0[0].read();
|
||||||
.get();
|
let list = list.get();
|
||||||
let mut list = list
|
let mut list = list
|
||||||
.as_any()
|
.as_any()
|
||||||
.downcast_ref::<data::reference::Reference>()
|
.downcast_ref::<data::reference::Reference>()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.0
|
.write();
|
||||||
.write().unwrap();
|
|
||||||
let mut list = list
|
let mut list = list
|
||||||
.get_mut();
|
.get_mut();
|
||||||
let list = list
|
let list = list
|
||||||
|
|||||||
@@ -805,7 +805,7 @@ fn func_math_op(
|
|||||||
.map(|v| &v.0)
|
.map(|v| &v.0)
|
||||||
.filter(|v| v.len() == 2)
|
.filter(|v| v.len() == 2)
|
||||||
{
|
{
|
||||||
let (a, b) = (&a[0], &a[1]);
|
let (a, b) = (&a[0].read(), &a[1].read());
|
||||||
let (a, b) = (a.get(), b.get());
|
let (a, b) = (a.get(), b.get());
|
||||||
let a = a
|
let a = a
|
||||||
.as_any()
|
.as_any()
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ impl MersStatement for Block {
|
|||||||
.iter()
|
.iter()
|
||||||
.map(|s| s.run(info))
|
.map(|s| s.run(info))
|
||||||
.last()
|
.last()
|
||||||
.unwrap_or_else(|| Ok(Data::new(data::tuple::Tuple(vec![]))))
|
.unwrap_or_else(|| Ok(Data::new(data::tuple::Tuple::empty())))
|
||||||
}
|
}
|
||||||
fn has_scope(&self) -> bool {
|
fn has_scope(&self) -> bool {
|
||||||
true
|
true
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ impl MersStatement for FieldChain {
|
|||||||
.as_any()
|
.as_any()
|
||||||
.downcast_ref::<data::reference::Reference>()
|
.downcast_ref::<data::reference::Reference>()
|
||||||
{
|
{
|
||||||
obj_ref = r.0.read().unwrap();
|
obj_ref = r.read();
|
||||||
obj_in_ref = obj_ref.get();
|
obj_in_ref = obj_ref.get();
|
||||||
obj_in_ref.as_any().downcast_ref::<data::object::Object>()
|
obj_in_ref.as_any().downcast_ref::<data::object::Object>()
|
||||||
} else {
|
} else {
|
||||||
@@ -126,7 +126,7 @@ impl MersStatement for FieldChain {
|
|||||||
for res in more_args.iter().map(|arg| arg.run(info)) {
|
for res in more_args.iter().map(|arg| arg.run(info)) {
|
||||||
args.push(res?);
|
args.push(res?);
|
||||||
}
|
}
|
||||||
Data::new(Tuple(args))
|
Data::new(Tuple::from(args))
|
||||||
} else {
|
} else {
|
||||||
object
|
object
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use std::collections::HashMap;
|
use std::{collections::HashMap, sync::Arc};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
data::{self, object::ObjectT, Data, Type},
|
data::{self, object::ObjectT, reference::ReferenceT, Data, Type},
|
||||||
errors::{CheckError, EColor, SourceRange},
|
errors::{CheckError, EColor, SourceRange},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -23,7 +23,19 @@ impl MersStatement for Object {
|
|||||||
init_to_is_empty_type = init_to.types.is_empty();
|
init_to_is_empty_type = init_to.types.is_empty();
|
||||||
let print_is_part_of = init_to.types.len() > 1;
|
let print_is_part_of = init_to.types.len() > 1;
|
||||||
let mut init_fields = HashMap::new();
|
let mut init_fields = HashMap::new();
|
||||||
for t in init_to.types.iter() {
|
for (t, init_to_ref) in init_to
|
||||||
|
.types
|
||||||
|
.iter()
|
||||||
|
.filter_map(|t| t.as_any().downcast_ref::<ReferenceT>())
|
||||||
|
.flat_map(|r| r.0.types.iter().map(|t| (t, true)))
|
||||||
|
.chain(
|
||||||
|
init_to
|
||||||
|
.types
|
||||||
|
.iter()
|
||||||
|
.filter(|t| !t.as_any().is::<ReferenceT>())
|
||||||
|
.map(|t| (t, false)),
|
||||||
|
)
|
||||||
|
{
|
||||||
if let Some(ot) = t.as_any().downcast_ref::<ObjectT>() {
|
if let Some(ot) = t.as_any().downcast_ref::<ObjectT>() {
|
||||||
let mut fields = self.fields.iter().map(|(t, _)| *t).collect::<Vec<_>>();
|
let mut fields = self.fields.iter().map(|(t, _)| *t).collect::<Vec<_>>();
|
||||||
fields.sort();
|
fields.sort();
|
||||||
@@ -31,10 +43,12 @@ impl MersStatement for Object {
|
|||||||
if let Ok(i) = fields.binary_search(field) {
|
if let Ok(i) = fields.binary_search(field) {
|
||||||
fields.remove(i);
|
fields.remove(i);
|
||||||
}
|
}
|
||||||
init_fields
|
let init_fields = init_fields.entry(*field).or_insert_with(Type::empty);
|
||||||
.entry(*field)
|
if init_to_ref {
|
||||||
.or_insert_with(Type::empty)
|
init_fields.add(Arc::new(ReferenceT(t.clone())));
|
||||||
.add_all(t);
|
} else {
|
||||||
|
init_fields.add_all(t);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if !fields.is_empty() {
|
if !fields.is_empty() {
|
||||||
return Err(CheckError::new().msg(vec![
|
return Err(CheckError::new().msg(vec![
|
||||||
@@ -136,7 +150,7 @@ impl MersStatement for Object {
|
|||||||
self.fields
|
self.fields
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(n, s)| Ok::<_, CheckError>((n.clone(), s.run(info)?)))
|
.map(|(n, s)| Ok::<_, CheckError>((n.clone(), s.run(info)?)))
|
||||||
.collect::<Result<_, _>>()?,
|
.collect::<Result<Vec<_>, _>>()?,
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
fn has_scope(&self) -> bool {
|
fn has_scope(&self) -> bool {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use std::collections::VecDeque;
|
use std::{collections::VecDeque, sync::Arc};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
data::{self, tuple::TupleT, Data, MersType, Type},
|
data::{self, reference::ReferenceT, tuple::TupleT, Data, MersType, Type},
|
||||||
errors::{CheckError, EColor, SourceRange},
|
errors::{CheckError, EColor, SourceRange},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -23,11 +23,27 @@ impl MersStatement for Tuple {
|
|||||||
.map(|_| Type::empty())
|
.map(|_| Type::empty())
|
||||||
.collect::<VecDeque<_>>();
|
.collect::<VecDeque<_>>();
|
||||||
let print_is_part_of = init_to.types.len() > 1;
|
let print_is_part_of = init_to.types.len() > 1;
|
||||||
for t in init_to.types.iter() {
|
for (t, init_to_ref) in init_to
|
||||||
|
.types
|
||||||
|
.iter()
|
||||||
|
.filter_map(|t| t.as_any().downcast_ref::<ReferenceT>())
|
||||||
|
.flat_map(|r| r.0.types.iter().map(|t| (t, true)))
|
||||||
|
.chain(
|
||||||
|
init_to
|
||||||
|
.types
|
||||||
|
.iter()
|
||||||
|
.filter(|t| !t.as_any().is::<ReferenceT>())
|
||||||
|
.map(|t| (t, false)),
|
||||||
|
)
|
||||||
|
{
|
||||||
if let Some(t) = t.as_any().downcast_ref::<TupleT>() {
|
if let Some(t) = t.as_any().downcast_ref::<TupleT>() {
|
||||||
if t.0.len() == self.elems.len() {
|
if t.0.len() == self.elems.len() {
|
||||||
for (i, e) in t.0.iter().enumerate() {
|
for (i, e) in t.0.iter().enumerate() {
|
||||||
vec[i].add_all(&e);
|
if init_to_ref {
|
||||||
|
vec[i].add(Arc::new(ReferenceT(e.clone())));
|
||||||
|
} else {
|
||||||
|
vec[i].add_all(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return Err(CheckError::new().msg(vec![
|
return Err(CheckError::new().msg(vec![
|
||||||
@@ -102,11 +118,11 @@ impl MersStatement for Tuple {
|
|||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
fn run_custom(&self, info: &mut super::Info) -> Result<Data, CheckError> {
|
fn run_custom(&self, info: &mut super::Info) -> Result<Data, CheckError> {
|
||||||
Ok(Data::new(data::tuple::Tuple(
|
Ok(Data::new(data::tuple::Tuple::from(
|
||||||
self.elems
|
self.elems
|
||||||
.iter()
|
.iter()
|
||||||
.map(|s| Ok(s.run(info)?))
|
.map(|s| Ok(s.run(info)?))
|
||||||
.collect::<Result<_, CheckError>>()?,
|
.collect::<Result<Vec<_>, CheckError>>()?,
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
fn has_scope(&self) -> bool {
|
fn has_scope(&self) -> bool {
|
||||||
|
|||||||
@@ -60,14 +60,14 @@ impl MersStatement for Variable {
|
|||||||
info.scopes[self.var.0].vars[self.var.1] = nothing;
|
info.scopes[self.var.0].vars[self.var.1] = nothing;
|
||||||
} else {
|
} else {
|
||||||
// (reference to) data which will never be referenced again
|
// (reference to) data which will never be referenced again
|
||||||
return Ok(Data::new(data::reference::Reference(Arc::new(
|
return Ok(Data::new(data::reference::Reference::from(
|
||||||
RwLock::new(Data::empty_tuple()),
|
Data::empty_tuple(),
|
||||||
))));
|
)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(if self.is_ref_not_ignore {
|
Ok(if self.is_ref_not_ignore {
|
||||||
let v = &info.scopes[self.var.0].vars[self.var.1];
|
let v = &info.scopes[self.var.0].vars[self.var.1];
|
||||||
Data::new(data::reference::Reference(Arc::clone(v)))
|
Data::new(data::reference::Reference::raw(Arc::clone(v)))
|
||||||
} else {
|
} else {
|
||||||
info.scopes[self.var.0].vars[self.var.1]
|
info.scopes[self.var.0].vars[self.var.1]
|
||||||
.write()
|
.write()
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ version = "0.9.15"
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
mers_lib = "0.9.18"
|
mers_lib = "0.9.28"
|
||||||
lspower = "1.5.0"
|
lspower = "1.5.0"
|
||||||
tokio = { version = "1.36.0", features = ["full"] }
|
tokio = { version = "1.36.0", features = ["full"] }
|
||||||
line-span = "0.1.5"
|
line-span = "0.1.5"
|
||||||
|
|||||||
Reference in New Issue
Block a user