From e0f13bdb85599783ae70aea802c7c13bfab91946 Mon Sep 17 00:00:00 2001 From: mark Date: Sat, 27 May 2023 18:31:58 +0200 Subject: [PATCH] fixed issue https://github.com/Dummi26/mers/issues/1#issue-1728187127 and fixed `=` vs. `:=` in README. --- README.md | 2 +- mers/src/lang/to_runnable.rs | 8 ++--- mers/src/lang/val_type.rs | 57 +++++++++++++++++++++++++++++------- 3 files changed, 52 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 9063153..799cd9c 100755 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ mers has... - the type-safety of statically typed languages + mers will not crash unless you `exit()` with a nonzero exit code or write flawed assumptions using the builtin `.assume*()` functions (Rust's `unwrap` or `expect`) - the flexibility of dynamically typed languages - + `x = if condition() { "my string" } else { 12 } // <- this is valid` + + `x := if condition() { "my string" } else { 12 } // <- this is valid` - "correctness" (this is subjective and I'll be happy to discuss some of these decisions with people) + there is no `null` / `nil` + all references are explicit: if you pass a list by value, the original list will *never* be modified in any way. diff --git a/mers/src/lang/to_runnable.rs b/mers/src/lang/to_runnable.rs index 527db94..714da93 100755 --- a/mers/src/lang/to_runnable.rs +++ b/mers/src/lang/to_runnable.rs @@ -358,10 +358,10 @@ fn statement_adv( // if Some((t, is_init)), the statement creates by this function is the left side of an assignment, meaning it can create variables. t is the type that will be assigned to it. to_be_assigned_to: &mut Option<(VType, &mut bool)>, ) -> Result { - // eprintln!("TR : {}", s); - // if let Some(t) = &to_be_assigned_to { - // eprintln!(" --> {}", t.0); - // } + eprintln!("TR : {}", s); + if let Some(t) = &to_be_assigned_to { + eprintln!(" --> {}", t.0); + } let mut state = match &*s.statement { SStatementEnum::Value(v) => RStatementEnum::Value(v.clone()), SStatementEnum::Tuple(v) | SStatementEnum::List(v) => { diff --git a/mers/src/lang/val_type.rs b/mers/src/lang/val_type.rs index 6171cc9..5fe8fe9 100755 --- a/mers/src/lang/val_type.rs +++ b/mers/src/lang/val_type.rs @@ -37,12 +37,17 @@ impl VSingleType { /// None => Cannot get, Some(t) => getting can return t or nothing pub fn get(&self, i: usize, gsinfo: &GlobalScriptInfo) -> Option { match self { - Self::Bool | Self::Int | Self::Float | Self::Function(..) | Self::Thread(..) => None, + 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).cloned(), Self::List(t) => Some(t.clone()), Self::Reference(r) => r.get_ref(i, gsinfo), - Self::EnumVariant(_, t) | Self::EnumVariantS(_, t) => t.get(i, gsinfo), Self::CustomType(t) => gsinfo.custom_types[*t].get(i, gsinfo), &Self::CustomTypeS(_) => { unreachable!("CustomTypeS instead of CustomType, compiler bug? [get]") @@ -51,13 +56,18 @@ impl VSingleType { } pub fn get_ref(&self, i: usize, gsinfo: &GlobalScriptInfo) -> Option { match self { - Self::Bool | Self::Int | Self::Float | Self::Function(..) | Self::Thread(..) => None, + 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.clone()), - Self::Reference(r) => r.get(i, gsinfo), - Self::EnumVariant(_, t) | Self::EnumVariantS(_, t) => t.get(i, gsinfo), - Self::CustomType(t) => gsinfo.custom_types[*t].get(i, gsinfo), + 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]") } @@ -72,16 +82,36 @@ impl VSingleType { | Self::String | Self::List(_) | Self::Function(..) - | Self::Thread(..) => None, + | Self::Thread(..) + | Self::EnumVariant(..) + | Self::EnumVariantS(..) => None, Self::Tuple(t) => t.get(i).cloned(), - Self::Reference(r) => r.get_always(i, info), - Self::EnumVariant(_, t) | Self::EnumVariantS(_, t) => t.get_always(i, info), + Self::Reference(r) => r.get_always_ref(i, info), Self::CustomType(t) => info.custom_types[*t].get_always(i, info), Self::CustomTypeS(_) => { unreachable!("CustomTypeS instead of CustomType, compiler bug? [get_always]") } } } + pub fn get_always_ref(&self, i: usize, info: &GlobalScriptInfo) -> Option { + match self { + Self::Bool + | Self::Int + | Self::Float + | Self::String + | Self::List(_) + | Self::Function(..) + | Self::Thread(..) + | Self::EnumVariant(..) + | Self::EnumVariantS(..) => None, + Self::Tuple(t) => Some(t.get(i)?.reference()), + Self::Reference(r) => r.get_always_ref(i, info), + Self::CustomType(t) => info.custom_types[*t].get_always_ref(i, info), + Self::CustomTypeS(_) => { + unreachable!("CustomTypeS instead of CustomType, compiler bug? [get_always]") + } + } + } } impl VType { pub fn empty() -> Self { @@ -101,6 +131,13 @@ impl VType { } Some(out) } + pub fn get_always_ref(&self, i: usize, info: &GlobalScriptInfo) -> Option { + let mut out = VType { types: vec![] }; + for t in &self.types { + out = out | t.get_always_ref(i, info)?; // if we can't use *get* on one type, we can't use it at all. + } + Some(out) + } /// returns Some(true) or Some(false) if all types are references or not references. If it is mixed or types is empty, returns None. pub fn is_reference(&self) -> Option { let mut noref = false;