mirror of
https://github.com/Dummi26/mers.git
synced 2025-03-10 14:13:52 +01:00
changed VType internals
This commit is contained in:
parent
f7feb688e8
commit
1c749da401
@ -381,7 +381,7 @@ impl BuiltinFunction {
|
||||
if let Some(true) = vec.is_reference() {
|
||||
if let Some(t) = vec.get_any(info) {
|
||||
el.fits_in(
|
||||
&t.dereference()
|
||||
&t.dereference(info)
|
||||
.expect("running get() on &[ ...] should give a reference"),
|
||||
info,
|
||||
)
|
||||
@ -402,7 +402,7 @@ impl BuiltinFunction {
|
||||
if let Some(true) = vec.is_reference() {
|
||||
if let Some(t) = vec.get_any(info) {
|
||||
el.fits_in(
|
||||
&t.dereference()
|
||||
&t.dereference(info)
|
||||
.expect("running get() on a &[ ...] should give a reference."),
|
||||
info,
|
||||
)
|
||||
@ -519,10 +519,10 @@ impl BuiltinFunction {
|
||||
match t {
|
||||
VSingleType::Tuple(v) => {
|
||||
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
|
||||
@ -532,15 +532,15 @@ impl BuiltinFunction {
|
||||
for t in &input[0].types {
|
||||
match t {
|
||||
VSingleType::EnumVariant(..) | VSingleType::EnumVariantS(..) => (),
|
||||
t => out = out | t.clone().to(),
|
||||
t => out.add_typer(t, info),
|
||||
}
|
||||
}
|
||||
out
|
||||
}
|
||||
Self::NoEnum => input[0].clone().noenum(),
|
||||
Self::Matches => input[0].matches().1,
|
||||
Self::NoEnum => input[0].clone().noenum(info),
|
||||
Self::Matches => input[0].matches(info).1,
|
||||
Self::Clone => input[0]
|
||||
.dereference()
|
||||
.dereference(info)
|
||||
.expect("type is a reference, so it can be dereferenced"),
|
||||
// []
|
||||
Self::Print | Self::Println | Self::Debug | Self::Sleep => VType {
|
||||
@ -562,25 +562,25 @@ impl BuiltinFunction {
|
||||
for func in &funcs.types {
|
||||
if let VSingleType::Function(io) = func {
|
||||
let mut empty = true;
|
||||
let fn_out = io.iter().fold(VType::empty(), |t, (fn_in, fn_out)| {
|
||||
if fn_in.len() == (input.len() - 1)
|
||||
&& fn_in
|
||||
.iter()
|
||||
.zip(input.iter().skip(1))
|
||||
.all(|(fn_in, arg)| arg.fits_in(fn_in, info).is_empty())
|
||||
{
|
||||
empty = false;
|
||||
t | fn_out.clone()
|
||||
} else {
|
||||
let fn_out =
|
||||
io.iter().fold(VType::empty(), |mut t, (fn_in, fn_out)| {
|
||||
if fn_in.len() == (input.len() - 1)
|
||||
&& fn_in
|
||||
.iter()
|
||||
.zip(input.iter().skip(1))
|
||||
.all(|(fn_in, arg)| arg.fits_in(fn_in, info).is_empty())
|
||||
{
|
||||
empty = false;
|
||||
t.add_typesr(fn_out, info);
|
||||
}
|
||||
t
|
||||
}
|
||||
});
|
||||
});
|
||||
if empty {
|
||||
unreachable!(
|
||||
"fn args are incorrect for builtin run() or thread()!"
|
||||
);
|
||||
}
|
||||
out = out | fn_out;
|
||||
out.add_types(fn_out, info);
|
||||
} else {
|
||||
unreachable!("run called, first arg not a function")
|
||||
}
|
||||
@ -599,7 +599,7 @@ impl BuiltinFunction {
|
||||
let mut out = VType { types: vec![] };
|
||||
for v in &v.types {
|
||||
if let VSingleType::Thread(v) = v {
|
||||
out = out | v;
|
||||
out.add_typesr(v, info);
|
||||
} else {
|
||||
unreachable!("await called with non-thread arg")
|
||||
}
|
||||
@ -611,7 +611,7 @@ impl BuiltinFunction {
|
||||
}
|
||||
Self::Pop => {
|
||||
if let Some(v) = input.first() {
|
||||
if let Some(v) = v.dereference() {
|
||||
if let Some(v) = v.dereference(info) {
|
||||
VType {
|
||||
types: vec![
|
||||
VSingleType::Tuple(vec![]),
|
||||
@ -629,14 +629,14 @@ impl BuiltinFunction {
|
||||
}
|
||||
Self::Remove => {
|
||||
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 {
|
||||
types: vec![
|
||||
VSingleType::Tuple(vec![]),
|
||||
VSingleType::Tuple(vec![v
|
||||
.get_any(info)
|
||||
.expect("cannot use get on this type")
|
||||
.dereference()
|
||||
.dereference(info)
|
||||
.expect(
|
||||
"running get_any() on &[ ...] should give a reference...",
|
||||
)]),
|
||||
@ -745,7 +745,7 @@ impl BuiltinFunction {
|
||||
(false, false) => (),
|
||||
}
|
||||
}
|
||||
let o = match (
|
||||
let mut o = match (
|
||||
(
|
||||
input[0].contains(&VSingleType::Int, info),
|
||||
input[0].contains(&VSingleType::Float, info),
|
||||
@ -763,10 +763,9 @@ impl BuiltinFunction {
|
||||
_ => VSingleType::Float.to(),
|
||||
};
|
||||
if might_be_string {
|
||||
o | VSingleType::String.to()
|
||||
} else {
|
||||
o
|
||||
o.add_type(VSingleType::String, info);
|
||||
}
|
||||
o
|
||||
} else {
|
||||
unreachable!("called add/sub/mul/div/mod/pow with args != 2")
|
||||
}
|
||||
|
@ -83,7 +83,7 @@ impl RFunction {
|
||||
let out = self
|
||||
.out_map
|
||||
.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())
|
||||
&& fn_in
|
||||
.iter()
|
||||
@ -91,10 +91,9 @@ impl RFunction {
|
||||
.all(|(fn_in, arg)| arg.fits_in(fn_in, info).is_empty())
|
||||
{
|
||||
empty = false;
|
||||
t | fn_out.clone()
|
||||
} else {
|
||||
t
|
||||
t.add_typesr(fn_out, info);
|
||||
}
|
||||
t
|
||||
});
|
||||
if empty {
|
||||
None
|
||||
@ -102,9 +101,12 @@ impl RFunction {
|
||||
Some(out)
|
||||
}
|
||||
}
|
||||
pub fn out_all(&self, _info: &GlobalScriptInfo) -> VType {
|
||||
pub fn out_all(&self, info: &GlobalScriptInfo) -> VType {
|
||||
// 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> {
|
||||
&self.input_types
|
||||
@ -155,7 +157,7 @@ impl RStatement {
|
||||
}
|
||||
let mut o = self.statement.out(info);
|
||||
for _ in 0..self.derefs {
|
||||
o = o.dereference().expect("can't dereference (out())");
|
||||
o = o.dereference(info).expect("can't dereference (out())");
|
||||
}
|
||||
o
|
||||
}
|
||||
@ -177,7 +179,7 @@ impl RStatementEnum {
|
||||
let mut out = VType { types: vec![] };
|
||||
for v in v {
|
||||
let val = v.run(info);
|
||||
out = out | val.out();
|
||||
out.add_types(val.out(), &info);
|
||||
w.push(val);
|
||||
}
|
||||
VDataEnum::List(out, w).to()
|
||||
@ -331,7 +333,7 @@ impl RStatementEnum {
|
||||
Self::List(v) => VSingleType::List({
|
||||
let mut types = VType { types: vec![] };
|
||||
for t in v {
|
||||
types = types | t.out(info);
|
||||
types.add_types(t.out(info), info);
|
||||
}
|
||||
types
|
||||
})
|
||||
@ -358,14 +360,20 @@ impl RStatementEnum {
|
||||
Self::LibFunctionCall(.., out) => out.clone(),
|
||||
Self::Block(b) => b.out(info),
|
||||
Self::If(_, a, b) => {
|
||||
let mut out = a.out(info);
|
||||
if let Some(b) = b {
|
||||
a.out(info) | b.out(info)
|
||||
out.add_types(b.out(info), info);
|
||||
} 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) => {
|
||||
f.returns(args.iter().map(|rs| rs.out(info)).collect(), info)
|
||||
}
|
||||
@ -379,7 +387,7 @@ impl RStatementEnum {
|
||||
};
|
||||
for switch_on in switch_on {
|
||||
for (_on_type, _assign_to, case) in cases.iter() {
|
||||
out = out | case.out(info);
|
||||
out.add_types(case.out(info), info);
|
||||
}
|
||||
}
|
||||
out
|
||||
@ -388,14 +396,14 @@ impl RStatementEnum {
|
||||
let mut out = VType::empty();
|
||||
let mut can_fail_to_match = true;
|
||||
for (condition, _assign_to, action) in cases {
|
||||
out = out | action.out(info);
|
||||
if !condition.out(info).matches().0 {
|
||||
out.add_types(action.out(info), info);
|
||||
if !condition.out(info).matches(info).0 {
|
||||
can_fail_to_match = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if can_fail_to_match {
|
||||
out = out | VSingleType::Tuple(vec![]).to()
|
||||
out.add_type(VSingleType::Tuple(vec![]), info);
|
||||
}
|
||||
out
|
||||
}
|
||||
|
@ -508,19 +508,21 @@ fn statement_adv(
|
||||
let lib = &ginfo.libs[*libid];
|
||||
let libfn = &lib.registered_fns[*fnid];
|
||||
let mut empty = true;
|
||||
let fn_out = libfn.1.iter().fold(VType::empty(), |t, (fn_in, fn_out)| {
|
||||
if fn_in.len() == arg_types.len()
|
||||
&& fn_in
|
||||
.iter()
|
||||
.zip(arg_types.iter())
|
||||
.all(|(fn_in, arg)| arg.fits_in(fn_in, ginfo).is_empty())
|
||||
{
|
||||
empty = false;
|
||||
t | fn_out.clone()
|
||||
} else {
|
||||
t
|
||||
}
|
||||
});
|
||||
let fn_out =
|
||||
libfn
|
||||
.1
|
||||
.iter()
|
||||
.fold(VType::empty(), |mut t, (fn_in, fn_out)| {
|
||||
if fn_in.len() == arg_types.len()
|
||||
&& fn_in.iter().zip(arg_types.iter()).all(|(fn_in, arg)| {
|
||||
arg.fits_in(fn_in, ginfo).is_empty()
|
||||
})
|
||||
{
|
||||
empty = false;
|
||||
t.add_typesr(fn_out, ginfo);
|
||||
}
|
||||
t
|
||||
});
|
||||
if empty {
|
||||
return Err(ToRunnableError::WrongArgsForLibFunction(
|
||||
v.to_owned(),
|
||||
@ -579,7 +581,7 @@ fn statement_adv(
|
||||
SStatementEnum::For(v, c, b) => {
|
||||
let mut linfo = linfo.clone();
|
||||
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() {
|
||||
return Err(ToRunnableError::ForLoopContainerHasNoInnerTypes);
|
||||
}
|
||||
@ -601,7 +603,7 @@ fn statement_adv(
|
||||
stypes(&mut v, ginfo)?;
|
||||
v
|
||||
};
|
||||
covered_types = covered_types | &case_type;
|
||||
covered_types.add_typesr(&case_type, ginfo);
|
||||
ncases.push((
|
||||
case_type.clone(),
|
||||
statement_adv(
|
||||
@ -633,7 +635,7 @@ fn statement_adv(
|
||||
for (condition, assign_to, action) in cases.iter() {
|
||||
let mut linfo = linfo.clone();
|
||||
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(
|
||||
assign_to,
|
||||
ginfo,
|
||||
@ -647,7 +649,7 @@ fn statement_adv(
|
||||
}
|
||||
}
|
||||
if may_not_match {
|
||||
out_type = out_type | VSingleType::Tuple(vec![]).to();
|
||||
out_type.add_type(VSingleType::Tuple(vec![]), ginfo);
|
||||
}
|
||||
|
||||
RStatementEnum::Match(ncases).to()
|
||||
|
@ -417,13 +417,13 @@ impl VSingleType {
|
||||
}
|
||||
impl VType {
|
||||
/// 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 matches_as = VType { types: vec![] };
|
||||
for t in self.types.iter() {
|
||||
let (f, t) = t.matches();
|
||||
can_fail |= f;
|
||||
matches_as = matches_as | t;
|
||||
matches_as.add_types(t, info);
|
||||
}
|
||||
(can_fail, matches_as)
|
||||
}
|
||||
|
@ -14,12 +14,12 @@ use super::{
|
||||
|
||||
use super::global_info::LogMsg;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct VType {
|
||||
pub types: Vec<VSingleType>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum VSingleType {
|
||||
Any,
|
||||
Bool,
|
||||
@ -128,21 +128,21 @@ impl VType {
|
||||
pub fn get(&self, i: usize, info: &GlobalScriptInfo) -> Option<VType> {
|
||||
let mut out = VType { types: vec![] };
|
||||
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)
|
||||
}
|
||||
pub fn get_always(&self, i: usize, info: &GlobalScriptInfo) -> Option<VType> {
|
||||
let mut out = VType { types: vec![] };
|
||||
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)
|
||||
}
|
||||
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.
|
||||
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)
|
||||
}
|
||||
@ -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.
|
||||
pub fn dereference(&self) -> Option<Self> {
|
||||
pub fn dereference(&self, info: &GlobalScriptInfo) -> Option<Self> {
|
||||
let mut out = Self::empty();
|
||||
for t in self.types.iter() {
|
||||
out = out | t.deref()?.to();
|
||||
out.add_type(t.deref()?, info);
|
||||
}
|
||||
Some(out)
|
||||
}
|
||||
@ -194,7 +194,10 @@ impl VSingleType {
|
||||
| Self::Function(..)
|
||||
| Self::Thread(..) => None,
|
||||
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::Reference(r) => r.get_any_ref(info),
|
||||
Self::EnumVariant(_, t) => t.get_any(info),
|
||||
@ -212,10 +215,10 @@ impl VSingleType {
|
||||
| Self::Function(..)
|
||||
| Self::Thread(..) => None,
|
||||
Self::String => Some(VSingleType::String.into()),
|
||||
Self::Tuple(t) => Some(
|
||||
t.iter()
|
||||
.fold(VType { types: vec![] }, |a, b| a | b.reference()),
|
||||
),
|
||||
Self::Tuple(t) => Some(t.iter().fold(VType::empty(), |mut a, b| {
|
||||
a.add_types(b.reference(), info);
|
||||
a
|
||||
})),
|
||||
Self::List(t) => Some(t.reference()),
|
||||
// TODO: idk if this is right...
|
||||
Self::Reference(r) => r.get_any_ref(info),
|
||||
@ -243,14 +246,14 @@ impl VType {
|
||||
pub fn get_any(&self, info: &GlobalScriptInfo) -> Option<VType> {
|
||||
let mut out = VType { types: vec![] };
|
||||
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)
|
||||
}
|
||||
pub fn get_any_ref(&self, info: &GlobalScriptInfo) -> Option<VType> {
|
||||
let mut out = VType { types: vec![] };
|
||||
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)
|
||||
}
|
||||
@ -272,12 +275,10 @@ impl VType {
|
||||
}
|
||||
no
|
||||
}
|
||||
pub fn inner_types(&self) -> VType {
|
||||
pub fn inner_types(&self, info: &GlobalScriptInfo) -> VType {
|
||||
let mut out = VType { types: vec![] };
|
||||
for t in &self.types {
|
||||
for it in t.inner_types() {
|
||||
out = out | it.to();
|
||||
}
|
||||
out.add_types(t.inner_types(info), info);
|
||||
}
|
||||
out
|
||||
}
|
||||
@ -289,36 +290,45 @@ impl VType {
|
||||
pub fn contains(&self, t: &VSingleType, info: &GlobalScriptInfo) -> bool {
|
||||
t.fits_in_type(self, info)
|
||||
}
|
||||
pub fn noenum(self) -> Self {
|
||||
pub fn noenum(self, info: &GlobalScriptInfo) -> Self {
|
||||
let mut o = Self { types: vec![] };
|
||||
for t in self.types {
|
||||
o = o | t.noenum();
|
||||
o.add_types(t.noenum(), info);
|
||||
}
|
||||
o
|
||||
}
|
||||
}
|
||||
impl BitOr for VType {
|
||||
type Output = Self;
|
||||
fn bitor(self, rhs: Self) -> Self::Output {
|
||||
let mut types = self.types;
|
||||
for t in rhs.types {
|
||||
if !types.contains(&t) {
|
||||
types.push(t)
|
||||
}
|
||||
}
|
||||
Self { types }
|
||||
|
||||
impl VType {
|
||||
pub fn eq(&self, rhs: &Self, info: &GlobalScriptInfo) -> bool {
|
||||
self.fits_in(rhs, info).is_empty() && rhs.fits_in(self, info).is_empty()
|
||||
}
|
||||
}
|
||||
impl BitOr<&VType> for VType {
|
||||
type Output = Self;
|
||||
fn bitor(self, rhs: &Self) -> Self::Output {
|
||||
let mut types = self.types;
|
||||
for t in &rhs.types {
|
||||
if !types.contains(t) {
|
||||
types.push(t.clone())
|
||||
}
|
||||
impl VSingleType {
|
||||
pub fn eq(&self, rhs: &Self, info: &GlobalScriptInfo) -> bool {
|
||||
self.fits_in(rhs, info) && rhs.fits_in(self, info)
|
||||
}
|
||||
}
|
||||
impl VType {
|
||||
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 {
|
||||
VType { types: vec![self] }
|
||||
}
|
||||
pub fn inner_types(&self) -> Vec<VSingleType> {
|
||||
pub fn inner_types(&self, info: &GlobalScriptInfo) -> VType {
|
||||
match self {
|
||||
Self::Tuple(v) => {
|
||||
let mut types = vec![];
|
||||
let mut out = VType::empty();
|
||||
for it in v {
|
||||
// the tuple values
|
||||
for it in &it.types {
|
||||
// the possible types for each value
|
||||
if !types.contains(it) {
|
||||
types.push(it.clone());
|
||||
}
|
||||
}
|
||||
out.add_typesr(it, info);
|
||||
}
|
||||
types
|
||||
out
|
||||
}
|
||||
Self::List(v) => v.types.clone(),
|
||||
Self::List(v) => v.clone(),
|
||||
// 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
|
||||
Self::Function(f) => {
|
||||
// function that takes no inputs
|
||||
if let Some(out) = f.iter().find_map(|(args, out)| {
|
||||
if args.is_empty() {
|
||||
Some(out.clone().inner_types())
|
||||
Some(out.clone())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}) {
|
||||
out.types
|
||||
out
|
||||
} else {
|
||||
vec![]
|
||||
VType::empty()
|
||||
}
|
||||
}
|
||||
Self::Reference(r) => r.inner_types_ref(),
|
||||
_ => vec![],
|
||||
Self::Reference(r) => r.inner_types_ref(info),
|
||||
_ => VType::empty(),
|
||||
}
|
||||
}
|
||||
pub fn inner_types_ref(&self) -> Vec<VSingleType> {
|
||||
pub fn inner_types_ref(&self, info: &GlobalScriptInfo) -> VType {
|
||||
match self {
|
||||
Self::Tuple(v) => {
|
||||
let mut types = vec![];
|
||||
let mut out = VType::empty();
|
||||
for it in v {
|
||||
// the tuple values
|
||||
for it in &it.types {
|
||||
// the possible types for each value
|
||||
if !types.contains(it) {
|
||||
types.push(Self::Reference(Box::new(it.clone())));
|
||||
}
|
||||
}
|
||||
out.add_types(it.reference(), info);
|
||||
}
|
||||
types
|
||||
out
|
||||
}
|
||||
Self::List(v) => v
|
||||
.types
|
||||
.iter()
|
||||
.map(|v| Self::Reference(Box::new(v.clone())))
|
||||
.collect(),
|
||||
Self::Reference(r) => r.inner_types_ref(),
|
||||
_ => vec![],
|
||||
Self::List(v) => v.reference(),
|
||||
Self::Reference(r) => r.inner_types_ref(info),
|
||||
_ => VType::empty(),
|
||||
}
|
||||
}
|
||||
pub fn noenum(self) -> VType {
|
||||
|
@ -5,7 +5,7 @@ mod lang;
|
||||
mod libs;
|
||||
mod parsing;
|
||||
|
||||
pub use lang::{val_data::*, val_type::*};
|
||||
pub use lang::{global_info::GlobalScriptInfo, val_data::*, val_type::*};
|
||||
pub use libs::{
|
||||
comms::{ByteData, ByteDataA, Message, RespondableMessage},
|
||||
inlib::MyLib,
|
||||
@ -14,7 +14,10 @@ pub use parsing::*;
|
||||
|
||||
pub mod prelude {
|
||||
pub use super::{
|
||||
lang::{val_data::*, val_type::*},
|
||||
lang::{
|
||||
val_data::{VData, VDataEnum},
|
||||
val_type::{VSingleType, VType},
|
||||
},
|
||||
MyLib, RespondableMessage,
|
||||
};
|
||||
}
|
||||
|
@ -495,8 +495,9 @@ impl ByteDataA for VDataEnum {
|
||||
vec.push(b't');
|
||||
c.as_byte_data(vec);
|
||||
}
|
||||
Self::List(_, data) => {
|
||||
Self::List(t, data) => {
|
||||
vec.push(b'l');
|
||||
t.as_byte_data(vec);
|
||||
data.as_byte_data(vec);
|
||||
}
|
||||
// TODO?
|
||||
@ -525,13 +526,10 @@ impl ByteData for VDataEnum {
|
||||
b'f' => Self::Float(ByteData::from_byte_data(data)?),
|
||||
b'"' => Self::String(ByteData::from_byte_data(data)?),
|
||||
b't' => Self::Tuple(ByteData::from_byte_data(data)?),
|
||||
b'l' => {
|
||||
let entries: Vec<VData> = ByteData::from_byte_data(data)?;
|
||||
Self::List(
|
||||
entries.iter().fold(VType::empty(), |t, v| t | v.out()),
|
||||
entries,
|
||||
)
|
||||
}
|
||||
b'l' => Self::List(
|
||||
ByteData::from_byte_data(data)?,
|
||||
ByteData::from_byte_data(data)?,
|
||||
),
|
||||
b'E' => Self::EnumVariant(
|
||||
ByteData::from_byte_data(data)?,
|
||||
Box::new(ByteData::from_byte_data(data)?),
|
||||
|
@ -1,6 +1,6 @@
|
||||
use std::io::Cursor;
|
||||
|
||||
use mers_libs::prelude::*;
|
||||
use mers_libs::{prelude::*, GlobalScriptInfo};
|
||||
use mers_libs::{ByteData, ByteDataA};
|
||||
|
||||
#[test]
|
||||
@ -14,9 +14,10 @@ fn list_type() {
|
||||
);
|
||||
|
||||
let a = VSingleType::List(VSingleType::Int.to()).to();
|
||||
assert_eq!(
|
||||
VType::from_byte_data(&mut Cursor::new(a.as_byte_data_vec())).unwrap(),
|
||||
a
|
||||
assert!(
|
||||
VType::from_byte_data(&mut Cursor::new(a.as_byte_data_vec()))
|
||||
.unwrap()
|
||||
.eq(&a, &GlobalScriptInfo::default()),
|
||||
);
|
||||
|
||||
let a = VSingleType::Tuple(vec![
|
||||
@ -27,8 +28,9 @@ fn list_type() {
|
||||
VSingleType::EnumVariant(12, VSingleType::Float.to()).to(),
|
||||
])
|
||||
.to();
|
||||
assert_eq!(
|
||||
VType::from_byte_data(&mut Cursor::new(a.as_byte_data_vec())).unwrap(),
|
||||
a
|
||||
assert!(
|
||||
VType::from_byte_data(&mut Cursor::new(a.as_byte_data_vec()))
|
||||
.unwrap()
|
||||
.eq(&a, &GlobalScriptInfo::default())
|
||||
);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user