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]
|
||||
name = "mers"
|
||||
version = "0.9.26"
|
||||
version = "0.9.28"
|
||||
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.9.26"
|
||||
mers_lib = "0.9.28"
|
||||
# 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.9.26"
|
||||
version = "0.9.28"
|
||||
edition = "2021"
|
||||
license = "MIT OR Apache-2.0"
|
||||
description = "library to use the mers language in other projects"
|
||||
|
||||
@@ -6,33 +6,70 @@ pub fn assign(from: &Data, target: &Data) {
|
||||
.as_any()
|
||||
.downcast_ref::<crate::data::reference::Reference>()
|
||||
{
|
||||
*r.0.write().unwrap() = from.clone();
|
||||
} else if let (Some(from), Some(target)) = (
|
||||
*r.write() = from.clone();
|
||||
} else if let (Some((from, from_ref)), Some(target)) = (
|
||||
from.get()
|
||||
.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
|
||||
.get()
|
||||
.as_any()
|
||||
.downcast_ref::<crate::data::tuple::Tuple>(),
|
||||
) {
|
||||
for (from, target) in from.0.iter().zip(target.0.iter()) {
|
||||
assign(from, target);
|
||||
for (from, target) in from.0.into_iter().zip(target.0.iter()) {
|
||||
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()
|
||||
.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
|
||||
.get()
|
||||
.as_any()
|
||||
.downcast_ref::<crate::data::object::Object>(),
|
||||
) {
|
||||
for (field, target) in target.iter() {
|
||||
let from = from
|
||||
.get(*field)
|
||||
.expect("type-checks should guarantee that from has every field of target");
|
||||
assign(from, target);
|
||||
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
|
||||
.get(*field)
|
||||
.expect("type-checks should guarantee that from has every field of target");
|
||||
assign(&from, &*target.read());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
unreachable!("invalid assignment")
|
||||
|
||||
@@ -225,7 +225,7 @@ impl Data {
|
||||
Self::new(tuple::Tuple(vec![]))
|
||||
}
|
||||
pub fn one_tuple(v: Self) -> Self {
|
||||
Self::new(tuple::Tuple(vec![v]))
|
||||
Self::new(tuple::Tuple::from([v]))
|
||||
}
|
||||
/// Returns true if self is `()`.
|
||||
pub fn is_zero_tuple(&self) -> bool {
|
||||
@@ -253,13 +253,13 @@ impl Data {
|
||||
None
|
||||
}
|
||||
}
|
||||
pub fn get(&self) -> RwLockReadGuard<Box<dyn MersData>> {
|
||||
pub fn get(&'_ self) -> RwLockReadGuard<'_, Box<dyn MersData>> {
|
||||
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()
|
||||
}
|
||||
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 {
|
||||
Some(self.get_mut_unchecked())
|
||||
} 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.
|
||||
/// 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() {
|
||||
#[cfg(debug_assertions)]
|
||||
eprintln!(
|
||||
|
||||
@@ -7,18 +7,33 @@ use crate::info::DisplayInfo;
|
||||
|
||||
use super::{Data, MersData, MersDataWInfo, MersType, Type};
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub struct Object(Vec<(usize, Data)>);
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct Object(Vec<(usize, super::reference::Reference)>);
|
||||
impl Object {
|
||||
pub fn new(v: Vec<(usize, Data)>) -> Self {
|
||||
Self(v)
|
||||
pub fn new(v: impl IntoIterator<Item = (usize, Data)>) -> Self {
|
||||
Self(
|
||||
v.into_iter()
|
||||
.map(|(i, d)| (i, super::reference::Reference::from(d)))
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
pub fn get(&self, f: usize) -> Option<&Data> {
|
||||
self.iter().find(|v| v.0 == f).map(|v| &v.1)
|
||||
pub fn get(&self, f: usize) -> Option<Data> {
|
||||
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()
|
||||
}
|
||||
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)]
|
||||
pub struct ObjectT(Vec<(usize, Type)>);
|
||||
@@ -29,7 +44,7 @@ impl ObjectT {
|
||||
pub fn get(&self, f: usize) -> Option<&Type> {
|
||||
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()
|
||||
}
|
||||
fn len(&self) -> usize {
|
||||
@@ -49,7 +64,7 @@ impl MersData for Object {
|
||||
f,
|
||||
"{}: {}",
|
||||
info.get_object_field_name(*field),
|
||||
val.get().with_display(info)
|
||||
val.read().get().with_display(info)
|
||||
)?;
|
||||
comma_sep = true;
|
||||
}
|
||||
@@ -69,7 +84,7 @@ impl MersData for Object {
|
||||
fn as_type(&self) -> Type {
|
||||
Type::new(ObjectT(
|
||||
self.iter()
|
||||
.map(|(n, v)| (n.clone(), v.get().as_type()))
|
||||
.map(|(n, v)| (n.clone(), v.read().get().as_type()))
|
||||
.collect(),
|
||||
))
|
||||
}
|
||||
|
||||
@@ -1,14 +1,32 @@
|
||||
use std::{
|
||||
any::Any,
|
||||
sync::{Arc, RwLock},
|
||||
sync::{Arc, RwLock, RwLockReadGuard, RwLockWriteGuard},
|
||||
};
|
||||
|
||||
use crate::{errors::CheckError, info::DisplayInfo};
|
||||
|
||||
use super::{Data, MersData, MersType, Type};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Reference(pub Arc<RwLock<Data>>);
|
||||
#[derive(Debug)]
|
||||
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 {
|
||||
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> {
|
||||
Box::new(Clone::clone(self))
|
||||
Box::new(self.clone_ref())
|
||||
}
|
||||
fn as_type(&self) -> 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)]
|
||||
pub struct ReferenceT(pub Type);
|
||||
impl MersType for ReferenceT {
|
||||
|
||||
@@ -4,15 +4,38 @@ use crate::{errors::CheckError, info::DisplayInfo};
|
||||
|
||||
use super::{Data, MersData, MersType, Type};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Tuple(pub Vec<Data>);
|
||||
#[derive(Debug)]
|
||||
pub struct Tuple(pub Vec<super::reference::Reference>);
|
||||
|
||||
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 {
|
||||
self.0.len()
|
||||
}
|
||||
pub fn get(&self, i: usize) -> Option<&Data> {
|
||||
self.0.get(i)
|
||||
pub fn get(&self, i: usize) -> Option<Data> {
|
||||
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 {
|
||||
write!(f, ", ")?;
|
||||
}
|
||||
c.get().display(info, f)?;
|
||||
c.read().get().display(info, f)?;
|
||||
}
|
||||
write!(f, ")")?;
|
||||
Ok(())
|
||||
@@ -39,13 +62,21 @@ impl MersData for Tuple {
|
||||
&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(
|
||||
Clone::clone(self)
|
||||
.0
|
||||
.into_iter()
|
||||
.map(|r| r.read().clone())
|
||||
.map(Ok),
|
||||
))
|
||||
}
|
||||
fn clone(&self) -> Box<dyn MersData> {
|
||||
Box::new(Clone::clone(self))
|
||||
}
|
||||
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 {
|
||||
self
|
||||
|
||||
@@ -178,7 +178,7 @@ impl CheckErrorHRConfig {
|
||||
.color(s, EColor::Indent(self.color_index), &mut t);
|
||||
return t;
|
||||
}
|
||||
pub fn indent_start(&self, right: bool) -> IndentStr {
|
||||
pub fn indent_start(&'_ self, right: bool) -> IndentStr<'_> {
|
||||
IndentStr(
|
||||
&self.idt_start,
|
||||
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(
|
||||
&self.idt_default,
|
||||
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(
|
||||
&self.idt_end,
|
||||
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(
|
||||
&self.idt_single,
|
||||
self.color(if self.is_inner {
|
||||
|
||||
@@ -43,7 +43,7 @@ impl<A: FromMersData> FromMersData for OneOrNone<A> {
|
||||
if v.0.is_empty() {
|
||||
f(Some(Self(None)))
|
||||
} 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 {
|
||||
f(Some(Self(Some(va))))
|
||||
} else {
|
||||
@@ -205,7 +205,7 @@ impl<A: FromMersData> FromMersData for (A,) {
|
||||
.downcast_ref::<data::tuple::Tuple>()
|
||||
.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 {
|
||||
f(Some((va,)))
|
||||
} else {
|
||||
@@ -222,7 +222,7 @@ impl<A: ToMersData> ToMersData for (A,) {
|
||||
Type::new(data::tuple::TupleT(vec![A::as_type_to()]))
|
||||
}
|
||||
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>()
|
||||
.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 {
|
||||
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 {
|
||||
f(Some((va, vb)))
|
||||
} 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()]))
|
||||
}
|
||||
fn represent(self) -> Data {
|
||||
Data::new(data::tuple::Tuple(vec![
|
||||
Data::new(data::tuple::Tuple::from([
|
||||
self.0.represent(),
|
||||
self.1.represent(),
|
||||
]))
|
||||
@@ -288,11 +288,11 @@ impl<A: FromMersData, B: FromMersData, C: FromMersData> FromMersData for (A, B,
|
||||
.downcast_ref::<data::tuple::Tuple>()
|
||||
.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 {
|
||||
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 {
|
||||
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 {
|
||||
f(Some((va, vb, vc)))
|
||||
} else {
|
||||
@@ -321,7 +321,7 @@ impl<A: ToMersData, B: ToMersData, C: ToMersData> ToMersData for (A, B, C) {
|
||||
]))
|
||||
}
|
||||
fn represent(self) -> Data {
|
||||
Data::new(data::tuple::Tuple(vec![
|
||||
Data::new(data::tuple::Tuple::from([
|
||||
self.0.represent(),
|
||||
self.1.represent(),
|
||||
self.2.represent(),
|
||||
|
||||
@@ -100,8 +100,10 @@ pub fn to_mers_func_concrete_string_string_to_any(
|
||||
move |a, _| {
|
||||
let a = a.get();
|
||||
let a = &a.as_any().downcast_ref::<data::tuple::Tuple>().unwrap().0;
|
||||
let l = a[0].get();
|
||||
let r = a[1].get();
|
||||
let l = a[0].read();
|
||||
let l = l.get();
|
||||
let r = a[1].read();
|
||||
let r = r.get();
|
||||
f(
|
||||
l.as_any()
|
||||
.downcast_ref::<data::string::String>()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use std::{
|
||||
sync::{Arc, Mutex, RwLock},
|
||||
sync::{Arc, Mutex},
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
|
||||
@@ -68,10 +68,12 @@ impl Config {
|
||||
run: Arc::new(|a, i| {
|
||||
let a = a.get();
|
||||
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 mut arg = arg_ref.0.write().unwrap();
|
||||
let func = a.0[1].get();
|
||||
let mut arg = arg_ref.write();
|
||||
let func = a.0[1].read();
|
||||
let func = func.get();
|
||||
*arg = func.execute(arg.clone(), &i.global).unwrap()?;
|
||||
Ok(Data::empty_tuple())
|
||||
}),
|
||||
@@ -168,7 +170,7 @@ impl Config {
|
||||
fixed_type_out: Arc::new(Mutex::new(None)),
|
||||
out: Ok(Arc::new(|a, _i| Ok(Type::new(data::reference::ReferenceT(a.clone()))))),
|
||||
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,
|
||||
},
|
||||
@@ -188,7 +190,7 @@ impl Config {
|
||||
.as_any()
|
||||
.downcast_ref::<data::reference::Reference>()
|
||||
{
|
||||
Ok(r.0.write().unwrap().clone())
|
||||
Ok(r.read().clone())
|
||||
} else {
|
||||
Err("called deref on non-reference".into())
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ impl Config {
|
||||
run: Arc::new(|a, i| {
|
||||
let a = a.get();
|
||||
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, args) = (
|
||||
cmd.as_any().downcast_ref::<data::string::String>().unwrap(),
|
||||
@@ -74,7 +74,7 @@ impl Config {
|
||||
String::from_utf8_lossy(&output.stdout).into_owned();
|
||||
let stderr =
|
||||
String::from_utf8_lossy(&output.stderr).into_owned();
|
||||
Ok(Data::new(data::tuple::Tuple(vec![
|
||||
Ok(Data::new(data::tuple::Tuple::from([
|
||||
status,
|
||||
Data::new(data::string::String(stdout)),
|
||||
Data::new(data::string::String(stderr)),
|
||||
@@ -106,7 +106,7 @@ impl Config {
|
||||
run: Arc::new(|a, i| {
|
||||
let a = a.get();
|
||||
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, args) = (
|
||||
cmd.as_any().downcast_ref::<data::string::String>().unwrap(),
|
||||
@@ -215,8 +215,10 @@ impl Config {
|
||||
run: Arc::new(|a, i| {
|
||||
let a = a.get();
|
||||
let tuple = a.as_any().downcast_ref::<data::tuple::Tuple>().unwrap();
|
||||
let child = tuple.0[0].get();
|
||||
let bytes = tuple.0[1].get();
|
||||
let child = tuple.0[0].read();
|
||||
let child = child.get();
|
||||
let bytes = tuple.0[1].read();
|
||||
let bytes = bytes.get();
|
||||
let child = child.as_any().downcast_ref::<ChildProcess>().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<_>, _>>()?;
|
||||
@@ -246,8 +248,10 @@ impl Config {
|
||||
run: Arc::new(|a, _i| {
|
||||
let a = a.get();
|
||||
let tuple = a.as_any().downcast_ref::<data::tuple::Tuple>().unwrap();
|
||||
let child = tuple.0[0].get();
|
||||
let string = tuple.0[1].get();
|
||||
let child = tuple.0[0].read();
|
||||
let child = child.get();
|
||||
let string = tuple.0[1].read();
|
||||
let string = string.get();
|
||||
let child = child.as_any().downcast_ref::<ChildProcess>().unwrap();
|
||||
let mut child = child.0.lock().unwrap();
|
||||
let buf = string.as_any().downcast_ref::<data::string::String>().unwrap().0.as_bytes();
|
||||
|
||||
@@ -76,7 +76,8 @@ impl Config {
|
||||
.as_any()
|
||||
.downcast_ref::<Tuple>()
|
||||
.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
|
||||
.as_any()
|
||||
.downcast_ref::<data::string::String>()
|
||||
|
||||
@@ -74,7 +74,8 @@ impl Config {
|
||||
}, |a, _| {
|
||||
let a = a.get();
|
||||
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());
|
||||
Ok(Data::new(Range(v.0, e.0)))
|
||||
}
|
||||
@@ -114,7 +115,8 @@ impl Config {
|
||||
}, |a, _| {
|
||||
let a = a.get();
|
||||
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());
|
||||
if let Some(e) = e.0.checked_sub(1) {
|
||||
Ok(Data::new(Range(v.0, e)))
|
||||
@@ -495,7 +497,7 @@ impl MersData for Iter {
|
||||
.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::from([
|
||||
Data::new(data::int::Int(i as _)),
|
||||
v,
|
||||
]))),
|
||||
|
||||
@@ -65,9 +65,7 @@ impl Config {
|
||||
.as_any()
|
||||
.downcast_ref::<data::reference::Reference>()
|
||||
.unwrap()
|
||||
.0
|
||||
.write()
|
||||
.unwrap()
|
||||
.get_mut()
|
||||
.mut_any()
|
||||
.downcast_mut::<List>()
|
||||
@@ -128,20 +126,18 @@ impl Config {
|
||||
run: Arc::new(|a, _i| {
|
||||
let tuple = a.get();
|
||||
let tuple = tuple.as_any().downcast_ref::<data::tuple::Tuple>().unwrap();
|
||||
tuple.0[0]
|
||||
tuple.0[0].read()
|
||||
.get()
|
||||
.as_any()
|
||||
.downcast_ref::<data::reference::Reference>()
|
||||
.unwrap()
|
||||
.0
|
||||
.write()
|
||||
.unwrap()
|
||||
.get_mut()
|
||||
.mut_any()
|
||||
.downcast_mut::<List>()
|
||||
.unwrap()
|
||||
.0
|
||||
.push(tuple.0[1].clone());
|
||||
.push(tuple.0[1].read().clone());
|
||||
Ok(Data::empty_tuple())
|
||||
}),
|
||||
inner_statements: None,
|
||||
@@ -197,15 +193,14 @@ impl Config {
|
||||
run: Arc::new(|a, _i| {
|
||||
let tuple = a.get();
|
||||
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 list = tuple.0[0]
|
||||
.get();
|
||||
let index = tuple.0[1].read().get().as_any().downcast_ref::<data::int::Int>().unwrap().0 as usize;
|
||||
let list = tuple.0[0].read();
|
||||
let list = list.get();
|
||||
let mut list = list
|
||||
.as_any()
|
||||
.downcast_ref::<data::reference::Reference>()
|
||||
.unwrap()
|
||||
.0
|
||||
.write().unwrap();
|
||||
.write();
|
||||
let mut list = list
|
||||
.get_mut();
|
||||
let list = list
|
||||
@@ -215,7 +210,7 @@ impl Config {
|
||||
if index > list.0.len() {
|
||||
Ok(Data::new(data::bool::Bool(false)))
|
||||
} 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)))
|
||||
}
|
||||
}),
|
||||
@@ -277,15 +272,14 @@ impl Config {
|
||||
run: Arc::new(|a, _i| {
|
||||
let tuple = a.get();
|
||||
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 list = tuple.0[0]
|
||||
.get();
|
||||
let index = tuple.0[1].read().get().as_any().downcast_ref::<data::int::Int>().unwrap().0 as usize;
|
||||
let list = tuple.0[0].read();
|
||||
let list = list.get();
|
||||
let mut list = list
|
||||
.as_any()
|
||||
.downcast_ref::<data::reference::Reference>()
|
||||
.unwrap()
|
||||
.0
|
||||
.write().unwrap();
|
||||
.write();
|
||||
let mut list = list
|
||||
.get_mut();
|
||||
let list = list
|
||||
@@ -293,7 +287,7 @@ impl Config {
|
||||
.downcast_mut::<List>()
|
||||
.unwrap();
|
||||
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 {
|
||||
Ok(Data::empty_tuple())
|
||||
}
|
||||
@@ -350,15 +344,14 @@ impl Config {
|
||||
run: Arc::new(|a, _i| {
|
||||
let tuple = a.get();
|
||||
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 list = tuple.0[0]
|
||||
.get();
|
||||
let index = tuple.0[1].read().get().as_any().downcast_ref::<data::int::Int>().unwrap().0 as usize;
|
||||
let list = tuple.0[0].read();
|
||||
let list = list.get();
|
||||
let mut list = list
|
||||
.as_any()
|
||||
.downcast_ref::<data::reference::Reference>()
|
||||
.unwrap()
|
||||
.0
|
||||
.write().unwrap();
|
||||
.write();
|
||||
let mut list = list
|
||||
.get_mut();
|
||||
let list = list
|
||||
|
||||
@@ -805,7 +805,7 @@ fn func_math_op(
|
||||
.map(|v| &v.0)
|
||||
.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 = a
|
||||
.as_any()
|
||||
|
||||
@@ -30,7 +30,7 @@ impl MersStatement for Block {
|
||||
.iter()
|
||||
.map(|s| s.run(info))
|
||||
.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 {
|
||||
true
|
||||
|
||||
@@ -95,7 +95,7 @@ impl MersStatement for FieldChain {
|
||||
.as_any()
|
||||
.downcast_ref::<data::reference::Reference>()
|
||||
{
|
||||
obj_ref = r.0.read().unwrap();
|
||||
obj_ref = r.read();
|
||||
obj_in_ref = obj_ref.get();
|
||||
obj_in_ref.as_any().downcast_ref::<data::object::Object>()
|
||||
} else {
|
||||
@@ -126,7 +126,7 @@ impl MersStatement for FieldChain {
|
||||
for res in more_args.iter().map(|arg| arg.run(info)) {
|
||||
args.push(res?);
|
||||
}
|
||||
Data::new(Tuple(args))
|
||||
Data::new(Tuple::from(args))
|
||||
} else {
|
||||
object
|
||||
};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::collections::HashMap;
|
||||
use std::{collections::HashMap, sync::Arc};
|
||||
|
||||
use crate::{
|
||||
data::{self, object::ObjectT, Data, Type},
|
||||
data::{self, object::ObjectT, reference::ReferenceT, Data, Type},
|
||||
errors::{CheckError, EColor, SourceRange},
|
||||
};
|
||||
|
||||
@@ -23,7 +23,19 @@ impl MersStatement for Object {
|
||||
init_to_is_empty_type = init_to.types.is_empty();
|
||||
let print_is_part_of = init_to.types.len() > 1;
|
||||
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>() {
|
||||
let mut fields = self.fields.iter().map(|(t, _)| *t).collect::<Vec<_>>();
|
||||
fields.sort();
|
||||
@@ -31,10 +43,12 @@ impl MersStatement for Object {
|
||||
if let Ok(i) = fields.binary_search(field) {
|
||||
fields.remove(i);
|
||||
}
|
||||
init_fields
|
||||
.entry(*field)
|
||||
.or_insert_with(Type::empty)
|
||||
.add_all(t);
|
||||
let init_fields = init_fields.entry(*field).or_insert_with(Type::empty);
|
||||
if init_to_ref {
|
||||
init_fields.add(Arc::new(ReferenceT(t.clone())));
|
||||
} else {
|
||||
init_fields.add_all(t);
|
||||
}
|
||||
}
|
||||
if !fields.is_empty() {
|
||||
return Err(CheckError::new().msg(vec![
|
||||
@@ -136,7 +150,7 @@ impl MersStatement for Object {
|
||||
self.fields
|
||||
.iter()
|
||||
.map(|(n, s)| Ok::<_, CheckError>((n.clone(), s.run(info)?)))
|
||||
.collect::<Result<_, _>>()?,
|
||||
.collect::<Result<Vec<_>, _>>()?,
|
||||
)))
|
||||
}
|
||||
fn has_scope(&self) -> bool {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::collections::VecDeque;
|
||||
use std::{collections::VecDeque, sync::Arc};
|
||||
|
||||
use crate::{
|
||||
data::{self, tuple::TupleT, Data, MersType, Type},
|
||||
data::{self, reference::ReferenceT, tuple::TupleT, Data, MersType, Type},
|
||||
errors::{CheckError, EColor, SourceRange},
|
||||
};
|
||||
|
||||
@@ -23,11 +23,27 @@ impl MersStatement for Tuple {
|
||||
.map(|_| Type::empty())
|
||||
.collect::<VecDeque<_>>();
|
||||
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 t.0.len() == self.elems.len() {
|
||||
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 {
|
||||
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> {
|
||||
Ok(Data::new(data::tuple::Tuple(
|
||||
Ok(Data::new(data::tuple::Tuple::from(
|
||||
self.elems
|
||||
.iter()
|
||||
.map(|s| Ok(s.run(info)?))
|
||||
.collect::<Result<_, CheckError>>()?,
|
||||
.collect::<Result<Vec<_>, CheckError>>()?,
|
||||
)))
|
||||
}
|
||||
fn has_scope(&self) -> bool {
|
||||
|
||||
@@ -60,14 +60,14 @@ impl MersStatement for Variable {
|
||||
info.scopes[self.var.0].vars[self.var.1] = nothing;
|
||||
} else {
|
||||
// (reference to) data which will never be referenced again
|
||||
return Ok(Data::new(data::reference::Reference(Arc::new(
|
||||
RwLock::new(Data::empty_tuple()),
|
||||
))));
|
||||
return Ok(Data::new(data::reference::Reference::from(
|
||||
Data::empty_tuple(),
|
||||
)));
|
||||
}
|
||||
}
|
||||
Ok(if self.is_ref_not_ignore {
|
||||
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 {
|
||||
info.scopes[self.var.0].vars[self.var.1]
|
||||
.write()
|
||||
|
||||
@@ -4,7 +4,7 @@ version = "0.9.15"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
mers_lib = "0.9.18"
|
||||
mers_lib = "0.9.28"
|
||||
lspower = "1.5.0"
|
||||
tokio = { version = "1.36.0", features = ["full"] }
|
||||
line-span = "0.1.5"
|
||||
|
||||
Reference in New Issue
Block a user