This commit is contained in:
mark 2023-05-27 18:31:58 +02:00
parent 3b44e5984f
commit e0f13bdb85
3 changed files with 52 additions and 15 deletions

View File

@ -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.

View File

@ -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<RStatement, ToRunnableError> {
// 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) => {

View File

@ -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<VType> {
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<VType> {
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<VType> {
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<VType> {
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<bool> {
let mut noref = false;