changed VType internals

This commit is contained in:
mark 2023-06-06 13:51:33 +02:00
parent f7feb688e8
commit 1c749da401
8 changed files with 161 additions and 155 deletions

View File

@ -381,7 +381,7 @@ impl BuiltinFunction {
if let Some(true) = vec.is_reference() { if let Some(true) = vec.is_reference() {
if let Some(t) = vec.get_any(info) { if let Some(t) = vec.get_any(info) {
el.fits_in( el.fits_in(
&t.dereference() &t.dereference(info)
.expect("running get() on &[ ...] should give a reference"), .expect("running get() on &[ ...] should give a reference"),
info, info,
) )
@ -402,7 +402,7 @@ impl BuiltinFunction {
if let Some(true) = vec.is_reference() { if let Some(true) = vec.is_reference() {
if let Some(t) = vec.get_any(info) { if let Some(t) = vec.get_any(info) {
el.fits_in( el.fits_in(
&t.dereference() &t.dereference(info)
.expect("running get() on a &[ ...] should give a reference."), .expect("running get() on a &[ ...] should give a reference."),
info, info,
) )
@ -519,10 +519,10 @@ impl BuiltinFunction {
match t { match t {
VSingleType::Tuple(v) => { VSingleType::Tuple(v) => {
if !v.is_empty() { if !v.is_empty() {
out = out | &v[0]; out.add_typesr(&v[0], info)
} }
} }
v => out = out | v.clone().to(), v => out.add_typer(v, info),
} }
} }
out out
@ -532,15 +532,15 @@ impl BuiltinFunction {
for t in &input[0].types { for t in &input[0].types {
match t { match t {
VSingleType::EnumVariant(..) | VSingleType::EnumVariantS(..) => (), VSingleType::EnumVariant(..) | VSingleType::EnumVariantS(..) => (),
t => out = out | t.clone().to(), t => out.add_typer(t, info),
} }
} }
out out
} }
Self::NoEnum => input[0].clone().noenum(), Self::NoEnum => input[0].clone().noenum(info),
Self::Matches => input[0].matches().1, Self::Matches => input[0].matches(info).1,
Self::Clone => input[0] Self::Clone => input[0]
.dereference() .dereference(info)
.expect("type is a reference, so it can be dereferenced"), .expect("type is a reference, so it can be dereferenced"),
// [] // []
Self::Print | Self::Println | Self::Debug | Self::Sleep => VType { Self::Print | Self::Println | Self::Debug | Self::Sleep => VType {
@ -562,25 +562,25 @@ impl BuiltinFunction {
for func in &funcs.types { for func in &funcs.types {
if let VSingleType::Function(io) = func { if let VSingleType::Function(io) = func {
let mut empty = true; let mut empty = true;
let fn_out = io.iter().fold(VType::empty(), |t, (fn_in, fn_out)| { let fn_out =
if fn_in.len() == (input.len() - 1) io.iter().fold(VType::empty(), |mut t, (fn_in, fn_out)| {
&& fn_in if fn_in.len() == (input.len() - 1)
.iter() && fn_in
.zip(input.iter().skip(1)) .iter()
.all(|(fn_in, arg)| arg.fits_in(fn_in, info).is_empty()) .zip(input.iter().skip(1))
{ .all(|(fn_in, arg)| arg.fits_in(fn_in, info).is_empty())
empty = false; {
t | fn_out.clone() empty = false;
} else { t.add_typesr(fn_out, info);
}
t t
} });
});
if empty { if empty {
unreachable!( unreachable!(
"fn args are incorrect for builtin run() or thread()!" "fn args are incorrect for builtin run() or thread()!"
); );
} }
out = out | fn_out; out.add_types(fn_out, info);
} else { } else {
unreachable!("run called, first arg not a function") unreachable!("run called, first arg not a function")
} }
@ -599,7 +599,7 @@ impl BuiltinFunction {
let mut out = VType { types: vec![] }; let mut out = VType { types: vec![] };
for v in &v.types { for v in &v.types {
if let VSingleType::Thread(v) = v { if let VSingleType::Thread(v) = v {
out = out | v; out.add_typesr(v, info);
} else { } else {
unreachable!("await called with non-thread arg") unreachable!("await called with non-thread arg")
} }
@ -611,7 +611,7 @@ impl BuiltinFunction {
} }
Self::Pop => { Self::Pop => {
if let Some(v) = input.first() { if let Some(v) = input.first() {
if let Some(v) = v.dereference() { if let Some(v) = v.dereference(info) {
VType { VType {
types: vec![ types: vec![
VSingleType::Tuple(vec![]), VSingleType::Tuple(vec![]),
@ -629,14 +629,14 @@ impl BuiltinFunction {
} }
Self::Remove => { Self::Remove => {
if input[1].fits_in(&VSingleType::Int.to(), info).is_empty() { if input[1].fits_in(&VSingleType::Int.to(), info).is_empty() {
if let Some(v) = input[0].dereference() { if let Some(v) = input[0].dereference(info) {
VType { VType {
types: vec![ types: vec![
VSingleType::Tuple(vec![]), VSingleType::Tuple(vec![]),
VSingleType::Tuple(vec![v VSingleType::Tuple(vec![v
.get_any(info) .get_any(info)
.expect("cannot use get on this type") .expect("cannot use get on this type")
.dereference() .dereference(info)
.expect( .expect(
"running get_any() on &[ ...] should give a reference...", "running get_any() on &[ ...] should give a reference...",
)]), )]),
@ -745,7 +745,7 @@ impl BuiltinFunction {
(false, false) => (), (false, false) => (),
} }
} }
let o = match ( let mut o = match (
( (
input[0].contains(&VSingleType::Int, info), input[0].contains(&VSingleType::Int, info),
input[0].contains(&VSingleType::Float, info), input[0].contains(&VSingleType::Float, info),
@ -763,10 +763,9 @@ impl BuiltinFunction {
_ => VSingleType::Float.to(), _ => VSingleType::Float.to(),
}; };
if might_be_string { if might_be_string {
o | VSingleType::String.to() o.add_type(VSingleType::String, info);
} else {
o
} }
o
} else { } else {
unreachable!("called add/sub/mul/div/mod/pow with args != 2") unreachable!("called add/sub/mul/div/mod/pow with args != 2")
} }

View File

@ -83,7 +83,7 @@ impl RFunction {
let out = self let out = self
.out_map .out_map
.iter() .iter()
.fold(VType::empty(), |t, (fn_in, fn_out)| { .fold(VType::empty(), |mut t, (fn_in, fn_out)| {
if fn_in.len() == (input_types.len()) if fn_in.len() == (input_types.len())
&& fn_in && fn_in
.iter() .iter()
@ -91,10 +91,9 @@ impl RFunction {
.all(|(fn_in, arg)| arg.fits_in(fn_in, info).is_empty()) .all(|(fn_in, arg)| arg.fits_in(fn_in, info).is_empty())
{ {
empty = false; empty = false;
t | fn_out.clone() t.add_typesr(fn_out, info);
} else {
t
} }
t
}); });
if empty { if empty {
None None
@ -102,9 +101,12 @@ impl RFunction {
Some(out) Some(out)
} }
} }
pub fn out_all(&self, _info: &GlobalScriptInfo) -> VType { pub fn out_all(&self, info: &GlobalScriptInfo) -> VType {
// self.statement.out(info) // self.statement.out(info)
self.out_map.iter().fold(VType::empty(), |t, (_, v)| t | v) self.out_map.iter().fold(VType::empty(), |mut t, (_, v)| {
t.add_typesr(v, info);
t
})
} }
pub fn in_types(&self) -> &Vec<VType> { pub fn in_types(&self) -> &Vec<VType> {
&self.input_types &self.input_types
@ -155,7 +157,7 @@ impl RStatement {
} }
let mut o = self.statement.out(info); let mut o = self.statement.out(info);
for _ in 0..self.derefs { for _ in 0..self.derefs {
o = o.dereference().expect("can't dereference (out())"); o = o.dereference(info).expect("can't dereference (out())");
} }
o o
} }
@ -177,7 +179,7 @@ impl RStatementEnum {
let mut out = VType { types: vec![] }; let mut out = VType { types: vec![] };
for v in v { for v in v {
let val = v.run(info); let val = v.run(info);
out = out | val.out(); out.add_types(val.out(), &info);
w.push(val); w.push(val);
} }
VDataEnum::List(out, w).to() VDataEnum::List(out, w).to()
@ -331,7 +333,7 @@ impl RStatementEnum {
Self::List(v) => VSingleType::List({ Self::List(v) => VSingleType::List({
let mut types = VType { types: vec![] }; let mut types = VType { types: vec![] };
for t in v { for t in v {
types = types | t.out(info); types.add_types(t.out(info), info);
} }
types types
}) })
@ -358,14 +360,20 @@ impl RStatementEnum {
Self::LibFunctionCall(.., out) => out.clone(), Self::LibFunctionCall(.., out) => out.clone(),
Self::Block(b) => b.out(info), Self::Block(b) => b.out(info),
Self::If(_, a, b) => { Self::If(_, a, b) => {
let mut out = a.out(info);
if let Some(b) = b { if let Some(b) = b {
a.out(info) | b.out(info) out.add_types(b.out(info), info);
} else { } else {
a.out(info) | VSingleType::Tuple(vec![]).to() out.add_type(VSingleType::Tuple(vec![]), info);
} }
out
}
Self::Loop(c) => c.out(info).matches(info).1,
Self::For(_, _, b) => {
let mut out = b.out(info).matches(info).1;
out.add_type(VSingleType::Tuple(vec![]), info);
out
} }
Self::Loop(c) => c.out(info).matches().1,
Self::For(_, _, b) => VSingleType::Tuple(vec![]).to() | b.out(info).matches().1,
Self::BuiltinFunctionCall(f, args) => { Self::BuiltinFunctionCall(f, args) => {
f.returns(args.iter().map(|rs| rs.out(info)).collect(), info) f.returns(args.iter().map(|rs| rs.out(info)).collect(), info)
} }
@ -379,7 +387,7 @@ impl RStatementEnum {
}; };
for switch_on in switch_on { for switch_on in switch_on {
for (_on_type, _assign_to, case) in cases.iter() { for (_on_type, _assign_to, case) in cases.iter() {
out = out | case.out(info); out.add_types(case.out(info), info);
} }
} }
out out
@ -388,14 +396,14 @@ impl RStatementEnum {
let mut out = VType::empty(); let mut out = VType::empty();
let mut can_fail_to_match = true; let mut can_fail_to_match = true;
for (condition, _assign_to, action) in cases { for (condition, _assign_to, action) in cases {
out = out | action.out(info); out.add_types(action.out(info), info);
if !condition.out(info).matches().0 { if !condition.out(info).matches(info).0 {
can_fail_to_match = false; can_fail_to_match = false;
break; break;
} }
} }
if can_fail_to_match { if can_fail_to_match {
out = out | VSingleType::Tuple(vec![]).to() out.add_type(VSingleType::Tuple(vec![]), info);
} }
out out
} }

View File

@ -508,19 +508,21 @@ fn statement_adv(
let lib = &ginfo.libs[*libid]; let lib = &ginfo.libs[*libid];
let libfn = &lib.registered_fns[*fnid]; let libfn = &lib.registered_fns[*fnid];
let mut empty = true; let mut empty = true;
let fn_out = libfn.1.iter().fold(VType::empty(), |t, (fn_in, fn_out)| { let fn_out =
if fn_in.len() == arg_types.len() libfn
&& fn_in .1
.iter() .iter()
.zip(arg_types.iter()) .fold(VType::empty(), |mut t, (fn_in, fn_out)| {
.all(|(fn_in, arg)| arg.fits_in(fn_in, ginfo).is_empty()) if fn_in.len() == arg_types.len()
{ && fn_in.iter().zip(arg_types.iter()).all(|(fn_in, arg)| {
empty = false; arg.fits_in(fn_in, ginfo).is_empty()
t | fn_out.clone() })
} else { {
t empty = false;
} t.add_typesr(fn_out, ginfo);
}); }
t
});
if empty { if empty {
return Err(ToRunnableError::WrongArgsForLibFunction( return Err(ToRunnableError::WrongArgsForLibFunction(
v.to_owned(), v.to_owned(),
@ -579,7 +581,7 @@ fn statement_adv(
SStatementEnum::For(v, c, b) => { SStatementEnum::For(v, c, b) => {
let mut linfo = linfo.clone(); let mut linfo = linfo.clone();
let container = statement(&c, ginfo, &mut linfo)?; let container = statement(&c, ginfo, &mut linfo)?;
let inner = container.out(ginfo).inner_types(); let inner = container.out(ginfo).inner_types(ginfo);
if inner.types.is_empty() { if inner.types.is_empty() {
return Err(ToRunnableError::ForLoopContainerHasNoInnerTypes); return Err(ToRunnableError::ForLoopContainerHasNoInnerTypes);
} }
@ -601,7 +603,7 @@ fn statement_adv(
stypes(&mut v, ginfo)?; stypes(&mut v, ginfo)?;
v v
}; };
covered_types = covered_types | &case_type; covered_types.add_typesr(&case_type, ginfo);
ncases.push(( ncases.push((
case_type.clone(), case_type.clone(),
statement_adv( statement_adv(
@ -633,7 +635,7 @@ fn statement_adv(
for (condition, assign_to, action) in cases.iter() { for (condition, assign_to, action) in cases.iter() {
let mut linfo = linfo.clone(); let mut linfo = linfo.clone();
let condition = statement(condition, ginfo, &mut linfo)?; let condition = statement(condition, ginfo, &mut linfo)?;
let (can_fail, matches) = condition.out(ginfo).matches(); let (can_fail, matches) = condition.out(ginfo).matches(ginfo);
let assign_to = statement_adv( let assign_to = statement_adv(
assign_to, assign_to,
ginfo, ginfo,
@ -647,7 +649,7 @@ fn statement_adv(
} }
} }
if may_not_match { if may_not_match {
out_type = out_type | VSingleType::Tuple(vec![]).to(); out_type.add_type(VSingleType::Tuple(vec![]), ginfo);
} }
RStatementEnum::Match(ncases).to() RStatementEnum::Match(ncases).to()

View File

@ -417,13 +417,13 @@ impl VSingleType {
} }
impl VType { impl VType {
/// returns (can_fail_to_match, matches_as) /// returns (can_fail_to_match, matches_as)
pub fn matches(&self) -> (bool, VType) { pub fn matches(&self, info: &GlobalScriptInfo) -> (bool, VType) {
let mut can_fail = false; let mut can_fail = false;
let mut matches_as = VType { types: vec![] }; let mut matches_as = VType { types: vec![] };
for t in self.types.iter() { for t in self.types.iter() {
let (f, t) = t.matches(); let (f, t) = t.matches();
can_fail |= f; can_fail |= f;
matches_as = matches_as | t; matches_as.add_types(t, info);
} }
(can_fail, matches_as) (can_fail, matches_as)
} }

View File

@ -14,12 +14,12 @@ use super::{
use super::global_info::LogMsg; use super::global_info::LogMsg;
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug)]
pub struct VType { pub struct VType {
pub types: Vec<VSingleType>, pub types: Vec<VSingleType>,
} }
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug)]
pub enum VSingleType { pub enum VSingleType {
Any, Any,
Bool, Bool,
@ -128,21 +128,21 @@ impl VType {
pub fn get(&self, i: usize, info: &GlobalScriptInfo) -> Option<VType> { pub fn get(&self, i: usize, info: &GlobalScriptInfo) -> Option<VType> {
let mut out = VType { types: vec![] }; let mut out = VType { types: vec![] };
for t in &self.types { for t in &self.types {
out = out | t.get(i, info)?; // if we can't use *get* on one type, we can't use it at all. out.add_types(t.get(i, info)?, info); // if we can't use *get* on one type, we can't use it at all.
} }
Some(out) Some(out)
} }
pub fn get_always(&self, i: usize, info: &GlobalScriptInfo) -> Option<VType> { pub fn get_always(&self, i: usize, info: &GlobalScriptInfo) -> Option<VType> {
let mut out = VType { types: vec![] }; let mut out = VType { types: vec![] };
for t in &self.types { for t in &self.types {
out = out | t.get_always(i, info)?; // if we can't use *get* on one type, we can't use it at all. out.add_types(t.get_always(i, info)?, info); // if we can't use *get* on one type, we can't use it at all.
} }
Some(out) Some(out)
} }
pub fn get_always_ref(&self, i: usize, info: &GlobalScriptInfo) -> Option<VType> { pub fn get_always_ref(&self, i: usize, info: &GlobalScriptInfo) -> Option<VType> {
let mut out = VType { types: vec![] }; let mut out = VType { types: vec![] };
for t in &self.types { 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. out.add_types(t.get_always_ref(i, info)?, info); // if we can't use *get* on one type, we can't use it at all.
} }
Some(out) Some(out)
} }
@ -165,10 +165,10 @@ impl VType {
} }
} }
/// returns Some(t) where t is the type you get from dereferencing self or None if self contains even a single type that cannot be dereferenced. /// returns Some(t) where t is the type you get from dereferencing self or None if self contains even a single type that cannot be dereferenced.
pub fn dereference(&self) -> Option<Self> { pub fn dereference(&self, info: &GlobalScriptInfo) -> Option<Self> {
let mut out = Self::empty(); let mut out = Self::empty();
for t in self.types.iter() { for t in self.types.iter() {
out = out | t.deref()?.to(); out.add_type(t.deref()?, info);
} }
Some(out) Some(out)
} }
@ -194,7 +194,10 @@ impl VSingleType {
| Self::Function(..) | Self::Function(..)
| Self::Thread(..) => None, | Self::Thread(..) => None,
Self::String => Some(VSingleType::String.into()), Self::String => Some(VSingleType::String.into()),
Self::Tuple(t) => Some(t.iter().fold(VType { types: vec![] }, |a, b| a | b)), Self::Tuple(t) => Some(t.iter().fold(VType::empty(), |mut a, b| {
a.add_typesr(b, info);
a
})),
Self::List(t) => Some(t.clone()), Self::List(t) => Some(t.clone()),
Self::Reference(r) => r.get_any_ref(info), Self::Reference(r) => r.get_any_ref(info),
Self::EnumVariant(_, t) => t.get_any(info), Self::EnumVariant(_, t) => t.get_any(info),
@ -212,10 +215,10 @@ impl VSingleType {
| Self::Function(..) | Self::Function(..)
| Self::Thread(..) => None, | Self::Thread(..) => None,
Self::String => Some(VSingleType::String.into()), Self::String => Some(VSingleType::String.into()),
Self::Tuple(t) => Some( Self::Tuple(t) => Some(t.iter().fold(VType::empty(), |mut a, b| {
t.iter() a.add_types(b.reference(), info);
.fold(VType { types: vec![] }, |a, b| a | b.reference()), a
), })),
Self::List(t) => Some(t.reference()), Self::List(t) => Some(t.reference()),
// TODO: idk if this is right... // TODO: idk if this is right...
Self::Reference(r) => r.get_any_ref(info), Self::Reference(r) => r.get_any_ref(info),
@ -243,14 +246,14 @@ impl VType {
pub fn get_any(&self, info: &GlobalScriptInfo) -> Option<VType> { pub fn get_any(&self, info: &GlobalScriptInfo) -> Option<VType> {
let mut out = VType { types: vec![] }; let mut out = VType { types: vec![] };
for t in &self.types { for t in &self.types {
out = out | t.get_any(info)?; // if we can't use *get* on one type, we can't use it at all. out.add_types(t.get_any(info)?, info); // if we can't use *get* on one type, we can't use it at all.
} }
Some(out) Some(out)
} }
pub fn get_any_ref(&self, info: &GlobalScriptInfo) -> Option<VType> { pub fn get_any_ref(&self, info: &GlobalScriptInfo) -> Option<VType> {
let mut out = VType { types: vec![] }; let mut out = VType { types: vec![] };
for t in &self.types { for t in &self.types {
out = out | t.get_any_ref(info)?; // if we can't use *get* on one type, we can't use it at all. out.add_types(t.get_any_ref(info)?, info); // if we can't use *get* on one type, we can't use it at all.
} }
Some(out) Some(out)
} }
@ -272,12 +275,10 @@ impl VType {
} }
no no
} }
pub fn inner_types(&self) -> VType { pub fn inner_types(&self, info: &GlobalScriptInfo) -> VType {
let mut out = VType { types: vec![] }; let mut out = VType { types: vec![] };
for t in &self.types { for t in &self.types {
for it in t.inner_types() { out.add_types(t.inner_types(info), info);
out = out | it.to();
}
} }
out out
} }
@ -289,36 +290,45 @@ impl VType {
pub fn contains(&self, t: &VSingleType, info: &GlobalScriptInfo) -> bool { pub fn contains(&self, t: &VSingleType, info: &GlobalScriptInfo) -> bool {
t.fits_in_type(self, info) t.fits_in_type(self, info)
} }
pub fn noenum(self) -> Self { pub fn noenum(self, info: &GlobalScriptInfo) -> Self {
let mut o = Self { types: vec![] }; let mut o = Self { types: vec![] };
for t in self.types { for t in self.types {
o = o | t.noenum(); o.add_types(t.noenum(), info);
} }
o o
} }
} }
impl BitOr for VType {
type Output = Self; impl VType {
fn bitor(self, rhs: Self) -> Self::Output { pub fn eq(&self, rhs: &Self, info: &GlobalScriptInfo) -> bool {
let mut types = self.types; self.fits_in(rhs, info).is_empty() && rhs.fits_in(self, info).is_empty()
for t in rhs.types {
if !types.contains(&t) {
types.push(t)
}
}
Self { types }
} }
} }
impl BitOr<&VType> for VType { impl VSingleType {
type Output = Self; pub fn eq(&self, rhs: &Self, info: &GlobalScriptInfo) -> bool {
fn bitor(self, rhs: &Self) -> Self::Output { self.fits_in(rhs, info) && rhs.fits_in(self, info)
let mut types = self.types; }
for t in &rhs.types { }
if !types.contains(t) { impl VType {
types.push(t.clone()) pub fn add_types(&mut self, new: Self, info: &GlobalScriptInfo) {
} for t in new.types {
self.add_type(t, info)
}
}
pub fn add_type(&mut self, new: VSingleType, info: &GlobalScriptInfo) {
if !self.contains(&new, info) {
self.types.push(new)
}
}
pub fn add_typesr(&mut self, new: &Self, info: &GlobalScriptInfo) {
for t in &new.types {
self.add_typer(t, info)
}
}
pub fn add_typer(&mut self, new: &VSingleType, info: &GlobalScriptInfo) {
if !self.contains(new, info) {
self.types.push(new.clone())
} }
Self { types }
} }
} }
@ -326,65 +336,49 @@ impl VSingleType {
pub fn to(self) -> VType { pub fn to(self) -> VType {
VType { types: vec![self] } VType { types: vec![self] }
} }
pub fn inner_types(&self) -> Vec<VSingleType> { pub fn inner_types(&self, info: &GlobalScriptInfo) -> VType {
match self { match self {
Self::Tuple(v) => { Self::Tuple(v) => {
let mut types = vec![]; let mut out = VType::empty();
for it in v { for it in v {
// the tuple values out.add_typesr(it, info);
for it in &it.types {
// the possible types for each value
if !types.contains(it) {
types.push(it.clone());
}
}
} }
types out
} }
Self::List(v) => v.types.clone(), Self::List(v) => v.clone(),
// NOTE: to make ints work in for loops // NOTE: to make ints work in for loops
Self::Int => vec![Self::Int], Self::Int => Self::Int.to(),
// for iterators in for loops: the match of the function's returned value make up the inner type // for iterators in for loops: the match of the function's returned value make up the inner type
Self::Function(f) => { Self::Function(f) => {
// function that takes no inputs // function that takes no inputs
if let Some(out) = f.iter().find_map(|(args, out)| { if let Some(out) = f.iter().find_map(|(args, out)| {
if args.is_empty() { if args.is_empty() {
Some(out.clone().inner_types()) Some(out.clone())
} else { } else {
None None
} }
}) { }) {
out.types out
} else { } else {
vec![] VType::empty()
} }
} }
Self::Reference(r) => r.inner_types_ref(), Self::Reference(r) => r.inner_types_ref(info),
_ => vec![], _ => VType::empty(),
} }
} }
pub fn inner_types_ref(&self) -> Vec<VSingleType> { pub fn inner_types_ref(&self, info: &GlobalScriptInfo) -> VType {
match self { match self {
Self::Tuple(v) => { Self::Tuple(v) => {
let mut types = vec![]; let mut out = VType::empty();
for it in v { for it in v {
// the tuple values out.add_types(it.reference(), info);
for it in &it.types {
// the possible types for each value
if !types.contains(it) {
types.push(Self::Reference(Box::new(it.clone())));
}
}
} }
types out
} }
Self::List(v) => v Self::List(v) => v.reference(),
.types Self::Reference(r) => r.inner_types_ref(info),
.iter() _ => VType::empty(),
.map(|v| Self::Reference(Box::new(v.clone())))
.collect(),
Self::Reference(r) => r.inner_types_ref(),
_ => vec![],
} }
} }
pub fn noenum(self) -> VType { pub fn noenum(self) -> VType {

View File

@ -5,7 +5,7 @@ mod lang;
mod libs; mod libs;
mod parsing; mod parsing;
pub use lang::{val_data::*, val_type::*}; pub use lang::{global_info::GlobalScriptInfo, val_data::*, val_type::*};
pub use libs::{ pub use libs::{
comms::{ByteData, ByteDataA, Message, RespondableMessage}, comms::{ByteData, ByteDataA, Message, RespondableMessage},
inlib::MyLib, inlib::MyLib,
@ -14,7 +14,10 @@ pub use parsing::*;
pub mod prelude { pub mod prelude {
pub use super::{ pub use super::{
lang::{val_data::*, val_type::*}, lang::{
val_data::{VData, VDataEnum},
val_type::{VSingleType, VType},
},
MyLib, RespondableMessage, MyLib, RespondableMessage,
}; };
} }

View File

@ -495,8 +495,9 @@ impl ByteDataA for VDataEnum {
vec.push(b't'); vec.push(b't');
c.as_byte_data(vec); c.as_byte_data(vec);
} }
Self::List(_, data) => { Self::List(t, data) => {
vec.push(b'l'); vec.push(b'l');
t.as_byte_data(vec);
data.as_byte_data(vec); data.as_byte_data(vec);
} }
// TODO? // TODO?
@ -525,13 +526,10 @@ impl ByteData for VDataEnum {
b'f' => Self::Float(ByteData::from_byte_data(data)?), b'f' => Self::Float(ByteData::from_byte_data(data)?),
b'"' => Self::String(ByteData::from_byte_data(data)?), b'"' => Self::String(ByteData::from_byte_data(data)?),
b't' => Self::Tuple(ByteData::from_byte_data(data)?), b't' => Self::Tuple(ByteData::from_byte_data(data)?),
b'l' => { b'l' => Self::List(
let entries: Vec<VData> = ByteData::from_byte_data(data)?; ByteData::from_byte_data(data)?,
Self::List( ByteData::from_byte_data(data)?,
entries.iter().fold(VType::empty(), |t, v| t | v.out()), ),
entries,
)
}
b'E' => Self::EnumVariant( b'E' => Self::EnumVariant(
ByteData::from_byte_data(data)?, ByteData::from_byte_data(data)?,
Box::new(ByteData::from_byte_data(data)?), Box::new(ByteData::from_byte_data(data)?),

View File

@ -1,6 +1,6 @@
use std::io::Cursor; use std::io::Cursor;
use mers_libs::prelude::*; use mers_libs::{prelude::*, GlobalScriptInfo};
use mers_libs::{ByteData, ByteDataA}; use mers_libs::{ByteData, ByteDataA};
#[test] #[test]
@ -14,9 +14,10 @@ fn list_type() {
); );
let a = VSingleType::List(VSingleType::Int.to()).to(); let a = VSingleType::List(VSingleType::Int.to()).to();
assert_eq!( assert!(
VType::from_byte_data(&mut Cursor::new(a.as_byte_data_vec())).unwrap(), VType::from_byte_data(&mut Cursor::new(a.as_byte_data_vec()))
a .unwrap()
.eq(&a, &GlobalScriptInfo::default()),
); );
let a = VSingleType::Tuple(vec![ let a = VSingleType::Tuple(vec![
@ -27,8 +28,9 @@ fn list_type() {
VSingleType::EnumVariant(12, VSingleType::Float.to()).to(), VSingleType::EnumVariant(12, VSingleType::Float.to()).to(),
]) ])
.to(); .to();
assert_eq!( assert!(
VType::from_byte_data(&mut Cursor::new(a.as_byte_data_vec())).unwrap(), VType::from_byte_data(&mut Cursor::new(a.as_byte_data_vec()))
a .unwrap()
.eq(&a, &GlobalScriptInfo::default())
); );
} }