From d94f727eaade787ae4a4a8c23ce515ac9274b83b Mon Sep 17 00:00:00 2001 From: mark Date: Mon, 12 Jun 2023 18:18:45 +0200 Subject: [PATCH] references can now be of type &(int/float): two types, one reference. --- mers/Cargo.lock | 2 +- mers/Cargo.toml | 2 +- mers/src/lang/builtins.rs | 2 +- mers/src/lang/code_runnable.rs | 11 +------ mers/src/lang/to_runnable.rs | 2 +- mers/src/lang/val_data.rs | 2 +- mers/src/lang/val_type.rs | 58 ++++++++++++---------------------- mers/src/libs/comms.rs | 2 +- mers/src/parsing/parse.rs | 34 +++++++++++++++++--- 9 files changed, 56 insertions(+), 59 deletions(-) diff --git a/mers/Cargo.lock b/mers/Cargo.lock index 556c2e6..538f2db 100755 --- a/mers/Cargo.lock +++ b/mers/Cargo.lock @@ -647,7 +647,7 @@ dependencies = [ [[package]] name = "mers" -version = "0.2.0" +version = "0.2.1" dependencies = [ "colorize", "edit", diff --git a/mers/Cargo.toml b/mers/Cargo.toml index e65185b..04d858f 100755 --- a/mers/Cargo.toml +++ b/mers/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mers" -version = "0.2.0" +version = "0.2.1" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/mers/src/lang/builtins.rs b/mers/src/lang/builtins.rs index c4342ce..a6dfce0 100755 --- a/mers/src/lang/builtins.rs +++ b/mers/src/lang/builtins.rs @@ -486,7 +486,7 @@ impl BuiltinFunction { &VType { types: vec![ VSingleType::String, - VSingleType::Reference(Box::new(VSingleType::String)), + VSingleType::Reference(VSingleType::String.to()), ], }, info, diff --git a/mers/src/lang/code_runnable.rs b/mers/src/lang/code_runnable.rs index 8667bd7..ca35142 100755 --- a/mers/src/lang/code_runnable.rs +++ b/mers/src/lang/code_runnable.rs @@ -349,16 +349,7 @@ impl RStatementEnum { .into(), Self::Variable(t, is_ref) => { if *is_ref { - VType { - types: t - .lock() - .unwrap() - .1 - .types - .iter() - .map(|t| VSingleType::Reference(Box::new(t.clone()))) - .collect(), - } + VSingleType::Reference(t.lock().unwrap().1.clone()).to() } else { t.lock().unwrap().1.clone() } diff --git a/mers/src/lang/to_runnable.rs b/mers/src/lang/to_runnable.rs index fe5078e..8b98635 100755 --- a/mers/src/lang/to_runnable.rs +++ b/mers/src/lang/to_runnable.rs @@ -312,7 +312,7 @@ pub fn stype(t: &mut VSingleType, ginfo: &mut GlobalScriptInfo) -> Result<(), To } } VSingleType::List(t) => stypes(t, ginfo)?, - VSingleType::Reference(t) => stype(t, ginfo)?, + VSingleType::Reference(t) => stypes(t, ginfo)?, VSingleType::Thread(t) => stypes(t, ginfo)?, VSingleType::EnumVariantS(e, v) => { *t = VSingleType::EnumVariant( diff --git a/mers/src/lang/val_data.rs b/mers/src/lang/val_data.rs index 2d7a1fc..40915ac 100755 --- a/mers/src/lang/val_data.rs +++ b/mers/src/lang/val_data.rs @@ -318,7 +318,7 @@ impl VDataEnum { Self::List(t, _) => VSingleType::List(t.clone()), Self::Function(f) => VSingleType::Function(f.out_map.clone()), Self::Thread(_, o) => VSingleType::Thread(o.clone()), - Self::Reference(r) => VSingleType::Reference(Box::new(r.out_single())), + Self::Reference(r) => VSingleType::Reference(r.out()), Self::EnumVariant(e, v) => VSingleType::EnumVariant(*e, v.out_single().to()), } } diff --git a/mers/src/lang/val_type.rs b/mers/src/lang/val_type.rs index 1b9e3aa..1ddaec6 100755 --- a/mers/src/lang/val_type.rs +++ b/mers/src/lang/val_type.rs @@ -28,7 +28,7 @@ pub enum VSingleType { List(VType), Function(Vec<(Vec, VType)>), Thread(VType), - Reference(Box), + Reference(VType), EnumVariant(usize, VType), EnumVariantS(String, VType), CustomType(usize), @@ -50,33 +50,13 @@ impl VSingleType { Self::String => Some(VSingleType::String.into()), Self::Tuple(t) => t.get(i).cloned(), Self::List(t) => Some(t.clone()), - Self::Reference(r) => r.get_ref(i, gsinfo), + Self::Reference(r) => Some(r.get(i, gsinfo)?.reference()), Self::CustomType(t) => gsinfo.custom_types[*t].get(i, gsinfo), &Self::CustomTypeS(_) => { unreachable!("CustomTypeS instead of CustomType, compiler bug? [get]") } } } - pub fn get_ref(&self, i: usize, gsinfo: &GlobalScriptInfo) -> Option { - match self { - Self::Any - | Self::Bool - | Self::Int - | Self::Float - | Self::Function(..) - | Self::Thread(..) - | Self::EnumVariant(..) - | Self::EnumVariantS(..) => None, - Self::String => Some(VSingleType::String.into()), - Self::Tuple(t) => t.get(i).map(|v| v.reference()), - Self::List(t) => Some(t.reference()), - Self::Reference(r) => r.get_ref(i, gsinfo), - Self::CustomType(t) => Some(gsinfo.custom_types[*t].get(i, gsinfo)?.reference()), - &Self::CustomTypeS(_) => { - unreachable!("CustomTypeS instead of CustomType, compiler bug? [get]") - } - } - } /// None => might not always return t, Some(t) => can only return t pub fn get_always(&self, i: usize, info: &GlobalScriptInfo) -> Option { match self { @@ -166,19 +146,12 @@ impl VType { pub fn dereference(&self, info: &GlobalScriptInfo) -> Option { let mut out = Self::empty(); for t in self.types.iter() { - out.add_type(t.deref()?, info); + out.add_types(t.deref()?, info); } Some(out) } pub fn reference(&self) -> Self { - let _out = Self::empty(); - Self { - types: self - .types - .iter() - .map(|v| VSingleType::Reference(Box::new(v.clone()))) - .collect(), - } + VSingleType::Reference(self.clone()).to() } } @@ -232,9 +205,9 @@ impl VSingleType { _ => false, } } - pub fn deref(&self) -> Option { + pub fn deref(&self) -> Option { if let Self::Reference(v) = self { - Some(*v.clone()) + Some(v.clone()) } else { None } @@ -361,7 +334,7 @@ impl VSingleType { VType::empty() } } - Self::Reference(r) => r.inner_types_ref(info), + Self::Reference(r) => r.inner_types(info).reference(), _ => VType::empty(), } } @@ -375,7 +348,7 @@ impl VSingleType { out } Self::List(v) => v.reference(), - Self::Reference(r) => r.inner_types_ref(info), + Self::Reference(r) => r.inner_types(info).reference(), _ => VType::empty(), } } @@ -424,7 +397,8 @@ impl VSingleType { let o = match (self, rhs) { (_, Self::Any) => true, (Self::Any, _) => false, - (Self::Reference(r), Self::Reference(b)) => r.fits_in(b, info), + // references have to be eq, not fits_in; otherwise whoever gets our reference could write invalid data to it! + (Self::Reference(a), Self::Reference(b)) => a.eq(b, info), (Self::Reference(_), _) | (_, Self::Reference(_)) => false, (Self::EnumVariant(v1, t1), Self::EnumVariant(v2, t2)) => { *v1 == *v2 && t1.fits_in(&t2, info).is_empty() @@ -583,8 +557,16 @@ impl FormatGs for VSingleType { write!(f, ")") } Self::Reference(inner) => { - write!(f, "&")?; - inner.fmtgs(f, info, form, file) + if inner.types.len() != 1 { + write!(f, "&(")?; + } else { + write!(f, "&")?; + } + inner.fmtgs(f, info, form, file)?; + if inner.types.len() != 1 { + write!(f, ")")?; + } + Ok(()) } Self::EnumVariant(variant, inner) => { if let Some(name) = if let Some(info) = info { diff --git a/mers/src/libs/comms.rs b/mers/src/libs/comms.rs index bddb48b..9c24dab 100644 --- a/mers/src/libs/comms.rs +++ b/mers/src/libs/comms.rs @@ -448,7 +448,7 @@ impl ByteData for VSingleType { b'l' => Self::List(ByteData::from_byte_data(data)?), b'F' => Self::Function(ByteData::from_byte_data(data)?), b'T' => Self::Thread(ByteData::from_byte_data(data)?), - b'R' => Self::Reference(Box::new(ByteData::from_byte_data(data)?)), + b'R' => Self::Reference(ByteData::from_byte_data(data)?), b'e' => Self::EnumVariant( ByteData::from_byte_data(data)?, ByteData::from_byte_data(data)?, diff --git a/mers/src/parsing/parse.rs b/mers/src/parsing/parse.rs index 533ca26..7da7210 100755 --- a/mers/src/parsing/parse.rs +++ b/mers/src/parsing/parse.rs @@ -312,6 +312,7 @@ pub enum ParseErrors { FoundEofInFunctionArgName, FoundEofInType, FoundEofInsteadOfType, + RefTypeWithBracketsNotClosedProperly, InvalidType(String), CannotUseFixedIndexingWithThisType(VType), CannotWrapWithThisStatement(SStatementEnum), @@ -350,6 +351,9 @@ impl FormatGs for ParseErrors { } Self::FoundEofInType => write!(f, "found EOF in type."), Self::FoundEofInsteadOfType => write!(f, "expected type, found EOF instead."), + Self::RefTypeWithBracketsNotClosedProperly => { + write!(f, "ref type with brackets &(...) wasn't closed properly.") + } Self::InvalidType(name) => write!(f, "\"{name}\" is not a type."), Self::CannotUseFixedIndexingWithThisType(t) => { write!(f, "cannot use fixed-indexing with type ")?; @@ -1178,11 +1182,31 @@ pub mod implementation { Ok(( match file.next() { Some('&') => { - let parse_output = parse_single_type_adv(file, in_fn_args)?; - if parse_output.1 { - closed_bracket_in_fn_args = true; - } - VSingleType::Reference(Box::new(parse_output.0)) + let output = if let Some('(') = file.peek() { + file.next(); + let (parse_output, closed_bracket) = parse_type_adv(file, true)?; + if !closed_bracket { + return Err(ParseError { + err: ParseErrors::RefTypeWithBracketsNotClosedProperly, + location: err_start_of_single_type, + location_end: Some(*file.get_pos()), + context: vec![], + info: None, + }); + } + if let Some(')') = file.peek() { + file.next(); + closed_bracket_in_fn_args = true; + } + parse_output + } else { + let (o, i_f) = parse_single_type_adv(file, in_fn_args)?; + if i_f { + closed_bracket_in_fn_args = true; + } + o.to() + }; + VSingleType::Reference(output) } // Tuple or Array Some('[') => {