mirror of
https://github.com/Dummi26/mers.git
synced 2025-04-28 18:16:05 +02:00
implemented enum functionality. todo: default functions should use Ok/Err enum variants?
This commit is contained in:
parent
260e42d4a7
commit
b1a90d5872
12
enums.txt
Normal file
12
enums.txt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
x = if false enum_a: "hello" else "world"
|
||||||
|
x.debug()
|
||||||
|
switch! x {
|
||||||
|
string {
|
||||||
|
println("no enum")
|
||||||
|
x.println()
|
||||||
|
}
|
||||||
|
enum_a: string {
|
||||||
|
println("Enum!")
|
||||||
|
x.noenum().println()
|
||||||
|
}
|
||||||
|
}
|
@ -175,6 +175,7 @@ fn data_to_bytes(data: &VData, stdin: &mut ChildStdin) {
|
|||||||
VDataEnum::Function(..) | VDataEnum::Reference(..) | VDataEnum::Thread(..) => {
|
VDataEnum::Function(..) | VDataEnum::Reference(..) | VDataEnum::Thread(..) => {
|
||||||
panic!("cannot use functions, references or threads in LibFunctions.")
|
panic!("cannot use functions, references or threads in LibFunctions.")
|
||||||
}
|
}
|
||||||
|
VDataEnum::EnumVariant(..) => todo!(),
|
||||||
}
|
}
|
||||||
stdin.flush().unwrap();
|
stdin.flush().unwrap();
|
||||||
}
|
}
|
||||||
|
@ -217,6 +217,12 @@ fn parse_statement_adv(
|
|||||||
Some('=') => {
|
Some('=') => {
|
||||||
break parse_statement(file)?.output_to(start.trim().to_string());
|
break parse_statement(file)?.output_to(start.trim().to_string());
|
||||||
}
|
}
|
||||||
|
Some(':') => {
|
||||||
|
return Ok(SStatement::new(SStatementEnum::EnumVariant(
|
||||||
|
start,
|
||||||
|
parse_statement(file)?,
|
||||||
|
)));
|
||||||
|
}
|
||||||
Some(ch) if ch.is_whitespace() || matches!(ch, '}' | ']' | ')' | '.') => {
|
Some(ch) if ch.is_whitespace() || matches!(ch, '}' | ']' | ')' | '.') => {
|
||||||
file.skip_whitespaces();
|
file.skip_whitespaces();
|
||||||
if let Some('=') = file.peek() {
|
if let Some('=') = file.peek() {
|
||||||
@ -506,7 +512,7 @@ fn parse_single_type_adv(
|
|||||||
VSingleType::Tuple(types)
|
VSingleType::Tuple(types)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(ch) => {
|
Some(ch) => 'parse_single_type: {
|
||||||
let mut name = ch.to_string();
|
let mut name = ch.to_string();
|
||||||
loop {
|
loop {
|
||||||
match file.peek() {
|
match file.peek() {
|
||||||
@ -516,6 +522,16 @@ fn parse_single_type_adv(
|
|||||||
}
|
}
|
||||||
match file.next() {
|
match file.next() {
|
||||||
Some(ch) if ch.is_whitespace() => break,
|
Some(ch) if ch.is_whitespace() => break,
|
||||||
|
Some(':') => {
|
||||||
|
break 'parse_single_type VSingleType::EnumVariantS(name, {
|
||||||
|
let po = parse_type_adv(file, in_fn_args)?;
|
||||||
|
if po.1 {
|
||||||
|
closed_bracket_in_fn_args = true;
|
||||||
|
}
|
||||||
|
po.0
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
Some(')') if in_fn_args => {
|
Some(')') if in_fn_args => {
|
||||||
closed_bracket_in_fn_args = true;
|
closed_bracket_in_fn_args = true;
|
||||||
break;
|
break;
|
||||||
|
@ -72,6 +72,7 @@ pub enum SStatementEnum {
|
|||||||
Switch(String, Vec<(VType, SStatement)>, bool),
|
Switch(String, Vec<(VType, SStatement)>, bool),
|
||||||
Match(String, Vec<(SStatement, SStatement)>),
|
Match(String, Vec<(SStatement, SStatement)>),
|
||||||
IndexFixed(SStatement, usize),
|
IndexFixed(SStatement, usize),
|
||||||
|
EnumVariant(String, SStatement),
|
||||||
}
|
}
|
||||||
impl Into<SStatement> for SStatementEnum {
|
impl Into<SStatement> for SStatementEnum {
|
||||||
fn into(self) -> SStatement {
|
fn into(self) -> SStatement {
|
||||||
@ -157,6 +158,7 @@ pub mod to_runnable {
|
|||||||
vars: usize,
|
vars: usize,
|
||||||
libs: Arc<Vec<libs::Lib>>,
|
libs: Arc<Vec<libs::Lib>>,
|
||||||
lib_fns: HashMap<String, (usize, usize)>,
|
lib_fns: HashMap<String, (usize, usize)>,
|
||||||
|
enum_variants: HashMap<String, usize>,
|
||||||
}
|
}
|
||||||
impl GInfo {
|
impl GInfo {
|
||||||
pub fn new(libs: Arc<Vec<libs::Lib>>) -> Self {
|
pub fn new(libs: Arc<Vec<libs::Lib>>) -> Self {
|
||||||
@ -166,7 +168,7 @@ pub mod to_runnable {
|
|||||||
lib_fns.insert(name.to_string(), (libid, fnid));
|
lib_fns.insert(name.to_string(), (libid, fnid));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Self { vars: 0, libs, lib_fns, }
|
Self { vars: 0, libs, lib_fns, enum_variants: HashMap::new() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Local, used to keep local variables separated
|
// Local, used to keep local variables separated
|
||||||
@ -268,6 +270,35 @@ pub mod to_runnable {
|
|||||||
Ok(RBlock { statements })
|
Ok(RBlock { statements })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn stypes(t: &mut VType, ginfo: &mut GInfo) {
|
||||||
|
for t in &mut t.types {
|
||||||
|
stype(t, ginfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn stype(t: &mut VSingleType, ginfo: &mut GInfo) {
|
||||||
|
match t {
|
||||||
|
VSingleType::Tuple(v) => {
|
||||||
|
for t in v {
|
||||||
|
stypes(t, ginfo);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
VSingleType::EnumVariantS(e, v) => *t = VSingleType::EnumVariant({
|
||||||
|
if let Some(v) = ginfo.enum_variants.get(e) {
|
||||||
|
*v
|
||||||
|
} else {
|
||||||
|
let v = ginfo.enum_variants.len();
|
||||||
|
ginfo.enum_variants.insert(e.clone(), v);
|
||||||
|
v
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
stypes(v, ginfo);
|
||||||
|
v.clone()
|
||||||
|
}
|
||||||
|
),
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
fn statement(
|
fn statement(
|
||||||
s: &SStatement,
|
s: &SStatement,
|
||||||
ginfo: &mut GInfo,
|
ginfo: &mut GInfo,
|
||||||
@ -288,7 +319,8 @@ pub mod to_runnable {
|
|||||||
}
|
}
|
||||||
SStatementEnum::Variable(v, is_ref) => {
|
SStatementEnum::Variable(v, is_ref) => {
|
||||||
if let Some(var) = linfo.vars.get(v) {
|
if let Some(var) = linfo.vars.get(v) {
|
||||||
RStatementEnum::Variable(var.0, var.1.clone(), *is_ref)
|
RStatementEnum::Variable(var.0, {
|
||||||
|
let mut v = var.1.clone(); stypes(&mut v, ginfo); v }, *is_ref)
|
||||||
} else {
|
} else {
|
||||||
return Err(ToRunnableError::UseOfUndefinedVariable(v.clone()));
|
return Err(ToRunnableError::UseOfUndefinedVariable(v.clone()));
|
||||||
}
|
}
|
||||||
@ -423,8 +455,9 @@ pub mod to_runnable {
|
|||||||
let mut ncases = Vec::with_capacity(cases.len());
|
let mut ncases = Vec::with_capacity(cases.len());
|
||||||
let og_type = switch_on_v.1.clone(); // linfo.vars.get(switch_on).unwrap().1.clone();
|
let og_type = switch_on_v.1.clone(); // linfo.vars.get(switch_on).unwrap().1.clone();
|
||||||
for case in cases {
|
for case in cases {
|
||||||
linfo.vars.get_mut(switch_on).unwrap().1 = case.0.clone();
|
let case0 = { let mut v = case.0.clone(); stypes(&mut v, ginfo); v };
|
||||||
ncases.push((case.0.clone(), statement(&case.1, ginfo, linfo)?));
|
linfo.vars.get_mut(switch_on).unwrap().1 = case0.clone();
|
||||||
|
ncases.push((case0, statement(&case.1, ginfo, linfo)?));
|
||||||
}
|
}
|
||||||
linfo.vars.get_mut(switch_on).unwrap().1 = og_type;
|
linfo.vars.get_mut(switch_on).unwrap().1 = og_type;
|
||||||
|
|
||||||
@ -438,12 +471,22 @@ pub mod to_runnable {
|
|||||||
linf2.vars.get_mut(switch_on).unwrap().1 = val_type.clone();
|
linf2.vars.get_mut(switch_on).unwrap().1 = val_type.clone();
|
||||||
'force: {
|
'force: {
|
||||||
for (case_type, _) in cases {
|
for (case_type, _) in cases {
|
||||||
if val_type.fits_in(&case_type).is_empty() {
|
let mut ct = case_type.clone();
|
||||||
|
stypes(&mut ct, ginfo);
|
||||||
|
if val_type.fits_in(&ct).is_empty() {
|
||||||
break 'force;
|
break 'force;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
types_not_covered_req_error = true;
|
types_not_covered_req_error = true;
|
||||||
types_not_covered = types_not_covered | val_type;
|
types_not_covered = types_not_covered | {
|
||||||
|
let mut v = val_type;
|
||||||
|
for t in v.types.iter_mut() {
|
||||||
|
if let VSingleType::EnumVariant(i, v) = t {
|
||||||
|
*t = VSingleType::EnumVariantS(ginfo.enum_variants.iter().find_map(|(st, us)| if *us == *i { Some(st.clone()) } else { None }).unwrap(), v.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
v
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if types_not_covered_req_error {
|
if types_not_covered_req_error {
|
||||||
@ -532,6 +575,15 @@ pub mod to_runnable {
|
|||||||
return Err(ToRunnableError::NotIndexableFixed(st.out(), *i));
|
return Err(ToRunnableError::NotIndexableFixed(st.out(), *i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
SStatementEnum::EnumVariant(variant, s) => RStatementEnum::EnumVariant({
|
||||||
|
if let Some(v) = ginfo.enum_variants.get(variant) {
|
||||||
|
*v
|
||||||
|
} else {
|
||||||
|
let v = ginfo.enum_variants.len();
|
||||||
|
ginfo.enum_variants.insert(variant.clone(), v);
|
||||||
|
v
|
||||||
|
}
|
||||||
|
}, statement(s, ginfo, linfo)?),
|
||||||
}
|
}
|
||||||
.to();
|
.to();
|
||||||
if let Some(opt) = &s.output_to {
|
if let Some(opt) = &s.output_to {
|
||||||
@ -674,6 +726,7 @@ pub enum RStatementEnum {
|
|||||||
Switch(RStatement, Vec<(VType, RStatement)>),
|
Switch(RStatement, Vec<(VType, RStatement)>),
|
||||||
Match(usize, Vec<(RStatement, RStatement)>),
|
Match(usize, Vec<(RStatement, RStatement)>),
|
||||||
IndexFixed(RStatement, usize),
|
IndexFixed(RStatement, usize),
|
||||||
|
EnumVariant(usize, RStatement)
|
||||||
}
|
}
|
||||||
impl RStatementEnum {
|
impl RStatementEnum {
|
||||||
pub fn run(&self, vars: &Vec<Am<VData>>, libs: &Arc<Vec<libs::Lib>>) -> VData {
|
pub fn run(&self, vars: &Vec<Am<VData>>, libs: &Arc<Vec<libs::Lib>>) -> VData {
|
||||||
@ -799,6 +852,9 @@ impl RStatementEnum {
|
|||||||
VDataEnum::Tuple(vec![]).to()
|
VDataEnum::Tuple(vec![]).to()
|
||||||
}
|
}
|
||||||
Self::IndexFixed(st, i) => st.run(vars, libs).get(*i).unwrap(),
|
Self::IndexFixed(st, i) => st.run(vars, libs).get(*i).unwrap(),
|
||||||
|
Self::EnumVariant(e, v) => {
|
||||||
|
VDataEnum::EnumVariant(*e, Box::new(v.run(vars, libs))).to()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn out(&self) -> VType {
|
pub fn out(&self) -> VType {
|
||||||
@ -848,7 +904,7 @@ impl RStatementEnum {
|
|||||||
let mut might_return_empty = switch_on.is_empty();
|
let mut might_return_empty = switch_on.is_empty();
|
||||||
let mut out = VType { types: vec![] }; // if nothing is executed
|
let mut out = VType { types: vec![] }; // if nothing is executed
|
||||||
for switch_on in switch_on {
|
for switch_on in switch_on {
|
||||||
let switch_on: VType = switch_on.into();
|
let switch_on = switch_on.to();
|
||||||
'search: {
|
'search: {
|
||||||
for (on_type, case) in cases.iter() {
|
for (on_type, case) in cases.iter() {
|
||||||
if switch_on.fits_in(&on_type).is_empty() {
|
if switch_on.fits_in(&on_type).is_empty() {
|
||||||
@ -872,6 +928,7 @@ impl RStatementEnum {
|
|||||||
out
|
out
|
||||||
}
|
}
|
||||||
Self::IndexFixed(st, i) => st.out().get(*i).unwrap(),
|
Self::IndexFixed(st, i) => st.out().get(*i).unwrap(),
|
||||||
|
Self::EnumVariant(e, v) => VSingleType::EnumVariant(*e, v.out()).to(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn to(self) -> RStatement {
|
pub fn to(self) -> RStatement {
|
||||||
@ -968,6 +1025,8 @@ impl Display for VSingleType {
|
|||||||
Self::Function(_) => write!(f, "FUNCTION"),
|
Self::Function(_) => write!(f, "FUNCTION"),
|
||||||
Self::Thread(_) => write!(f, "THREAD"),
|
Self::Thread(_) => write!(f, "THREAD"),
|
||||||
Self::Reference(r) => write!(f, "&{r}"),
|
Self::Reference(r) => write!(f, "&{r}"),
|
||||||
|
Self::EnumVariant(v, t) => write!(f, "{v}: {t}"),
|
||||||
|
Self::EnumVariantS(v, t) => write!(f, "{v}: {t}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1047,6 +1106,7 @@ impl Display for SStatementEnum {
|
|||||||
write!(f, "}}")
|
write!(f, "}}")
|
||||||
}
|
}
|
||||||
SStatementEnum::IndexFixed(st, i) => write!(f, "{st}.{i}"),
|
SStatementEnum::IndexFixed(st, i) => write!(f, "{st}.{i}"),
|
||||||
|
SStatementEnum::EnumVariant(e, s) => write!(f, "{e}: {s}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1087,6 +1147,7 @@ impl Display for VDataEnum {
|
|||||||
Self::Function(v) => write!(f, "{v}"),
|
Self::Function(v) => write!(f, "{v}"),
|
||||||
Self::Thread(..) => write!(f, "THREAD"),
|
Self::Thread(..) => write!(f, "THREAD"),
|
||||||
Self::Reference(r) => write!(f, "{}", r.lock().unwrap()),
|
Self::Reference(r) => write!(f, "{}", r.lock().unwrap()),
|
||||||
|
Self::EnumVariant(v, d) => write!(f, "{v}: {d}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ use super::{
|
|||||||
pub enum BuiltinFunction {
|
pub enum BuiltinFunction {
|
||||||
// core
|
// core
|
||||||
Assume1, // assume []/[t] is [t], return t. Optionally provide a reason as to why (2nd arg)
|
Assume1, // assume []/[t] is [t], return t. Optionally provide a reason as to why (2nd arg)
|
||||||
|
NoEnum,
|
||||||
// print
|
// print
|
||||||
Print,
|
Print,
|
||||||
Println,
|
Println,
|
||||||
@ -77,6 +78,7 @@ impl BuiltinFunction {
|
|||||||
pub fn get(s: &str) -> Option<Self> {
|
pub fn get(s: &str) -> Option<Self> {
|
||||||
Some(match s {
|
Some(match s {
|
||||||
"assume1" => Self::Assume1,
|
"assume1" => Self::Assume1,
|
||||||
|
"noenum" => Self::NoEnum,
|
||||||
"print" => Self::Print,
|
"print" => Self::Print,
|
||||||
"println" => Self::Println,
|
"println" => Self::Println,
|
||||||
"debug" => Self::Debug,
|
"debug" => Self::Debug,
|
||||||
@ -161,6 +163,7 @@ impl BuiltinFunction {
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Self::NoEnum => input.len() == 1,
|
||||||
Self::Print | Self::Println => {
|
Self::Print | Self::Println => {
|
||||||
if input.len() == 1 {
|
if input.len() == 1 {
|
||||||
input[0].fits_in(&VSingleType::String.to()).is_empty()
|
input[0].fits_in(&VSingleType::String.to()).is_empty()
|
||||||
@ -334,6 +337,7 @@ impl BuiltinFunction {
|
|||||||
}
|
}
|
||||||
out
|
out
|
||||||
}
|
}
|
||||||
|
Self::NoEnum => input[0].clone().noenum(),
|
||||||
// []
|
// []
|
||||||
Self::Print | Self::Println | Self::Debug | Self::Sleep => VType {
|
Self::Print | Self::Println | Self::Debug | Self::Sleep => VType {
|
||||||
types: vec![VSingleType::Tuple(vec![])],
|
types: vec![VSingleType::Tuple(vec![])],
|
||||||
@ -539,6 +543,7 @@ impl BuiltinFunction {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Self::NoEnum => args[0].run(vars, libs).noenum(),
|
||||||
BuiltinFunction::Print => {
|
BuiltinFunction::Print => {
|
||||||
if let VDataEnum::String(arg) = args[0].run(vars, libs).data {
|
if let VDataEnum::String(arg) = args[0].run(vars, libs).data {
|
||||||
print!("{}", arg);
|
print!("{}", arg);
|
||||||
|
@ -27,6 +27,7 @@ pub enum VDataEnum {
|
|||||||
Function(RFunction),
|
Function(RFunction),
|
||||||
Thread(VDataThread, VType),
|
Thread(VDataThread, VType),
|
||||||
Reference(Arc<Mutex<VData>>),
|
Reference(Arc<Mutex<VData>>),
|
||||||
|
EnumVariant(usize, Box<VData>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl VData {
|
impl VData {
|
||||||
@ -46,11 +47,15 @@ impl VData {
|
|||||||
VDataEnum::Function(f) => VSingleType::Function(f.input_output_map.clone()),
|
VDataEnum::Function(f) => VSingleType::Function(f.input_output_map.clone()),
|
||||||
VDataEnum::Thread(_, o) => VSingleType::Thread(o.clone()),
|
VDataEnum::Thread(_, o) => VSingleType::Thread(o.clone()),
|
||||||
VDataEnum::Reference(r) => r.lock().unwrap().out_single(),
|
VDataEnum::Reference(r) => r.lock().unwrap().out_single(),
|
||||||
|
VDataEnum::EnumVariant(e, v) => VSingleType::EnumVariant(*e, v.out()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn get(&self, i: usize) -> Option<Self> {
|
pub fn get(&self, i: usize) -> Option<Self> {
|
||||||
self.data.get(i)
|
self.data.get(i)
|
||||||
}
|
}
|
||||||
|
pub fn noenum(self) -> Self {
|
||||||
|
self.data.noenum()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl VDataEnum {
|
impl VDataEnum {
|
||||||
@ -61,6 +66,12 @@ impl VDataEnum {
|
|||||||
|
|
||||||
// get()
|
// get()
|
||||||
impl VDataEnum {
|
impl VDataEnum {
|
||||||
|
pub fn noenum(self) -> VData {
|
||||||
|
match self {
|
||||||
|
Self::EnumVariant(_, v) => *v,
|
||||||
|
v => v.to(),
|
||||||
|
}
|
||||||
|
}
|
||||||
pub fn get(&self, i: usize) -> Option<VData> {
|
pub fn get(&self, i: usize) -> Option<VData> {
|
||||||
match self {
|
match self {
|
||||||
Self::Bool(..)
|
Self::Bool(..)
|
||||||
@ -75,6 +86,7 @@ impl VDataEnum {
|
|||||||
},
|
},
|
||||||
Self::Tuple(v) | Self::List(_, v) => v.get(i).cloned(),
|
Self::Tuple(v) | Self::List(_, v) => v.get(i).cloned(),
|
||||||
Self::Reference(r) => r.lock().unwrap().get(i),
|
Self::Reference(r) => r.lock().unwrap().get(i),
|
||||||
|
Self::EnumVariant(_, v) => v.get(i),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn matches_ref_bool(&self) -> bool {
|
pub fn matches_ref_bool(&self) -> bool {
|
||||||
@ -154,9 +166,7 @@ impl VDataThread {
|
|||||||
if v.is_finished() {
|
if v.is_finished() {
|
||||||
let m = std::mem::replace(
|
let m = std::mem::replace(
|
||||||
&mut *mg,
|
&mut *mg,
|
||||||
VDataThreadEnum::Finished(VData {
|
VDataThreadEnum::Finished(VDataEnum::Bool(false).to()),
|
||||||
data: VDataEnum::Bool(false),
|
|
||||||
}),
|
|
||||||
);
|
);
|
||||||
match m {
|
match m {
|
||||||
VDataThreadEnum::Running(v) => {
|
VDataThreadEnum::Running(v) => {
|
||||||
|
@ -16,6 +16,8 @@ pub enum VSingleType {
|
|||||||
Function(Vec<(Vec<VSingleType>, VType)>),
|
Function(Vec<(Vec<VSingleType>, VType)>),
|
||||||
Thread(VType),
|
Thread(VType),
|
||||||
Reference(Box<Self>),
|
Reference(Box<Self>),
|
||||||
|
EnumVariant(usize, VType),
|
||||||
|
EnumVariantS(String, VType),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl VSingleType {
|
impl VSingleType {
|
||||||
@ -27,6 +29,7 @@ impl VSingleType {
|
|||||||
Self::Tuple(t) => t.get(i).cloned(),
|
Self::Tuple(t) => t.get(i).cloned(),
|
||||||
Self::List(t) => Some(t.clone()),
|
Self::List(t) => Some(t.clone()),
|
||||||
Self::Reference(r) => r.get(i),
|
Self::Reference(r) => r.get(i),
|
||||||
|
Self::EnumVariant(_, t) | Self::EnumVariantS(_, t) => t.get(i),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -48,6 +51,8 @@ impl VSingleType {
|
|||||||
Self::Tuple(t) => Some(t.iter().fold(VType { types: vec![] }, |a, b| a | b)),
|
Self::Tuple(t) => Some(t.iter().fold(VType { types: vec![] }, |a, b| a | b)),
|
||||||
Self::List(t) => Some(t.clone()),
|
Self::List(t) => Some(t.clone()),
|
||||||
Self::Reference(r) => r.get_any(),
|
Self::Reference(r) => r.get_any(),
|
||||||
|
Self::EnumVariant(_, t) => t.get_any(),
|
||||||
|
Self::EnumVariantS(..) => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -85,6 +90,13 @@ impl VType {
|
|||||||
pub fn contains(&self, t: &VSingleType) -> bool {
|
pub fn contains(&self, t: &VSingleType) -> bool {
|
||||||
self.types.contains(t)
|
self.types.contains(t)
|
||||||
}
|
}
|
||||||
|
pub fn noenum(self) -> Self {
|
||||||
|
let mut o = Self { types: vec![] };
|
||||||
|
for t in self.types {
|
||||||
|
o = o | t.noenum();
|
||||||
|
}
|
||||||
|
o
|
||||||
|
}
|
||||||
}
|
}
|
||||||
impl BitOr for VType {
|
impl BitOr for VType {
|
||||||
type Output = Self;
|
type Output = Self;
|
||||||
@ -136,8 +148,21 @@ impl VSingleType {
|
|||||||
_ => vec![],
|
_ => vec![],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pub fn noenum(self) -> VType {
|
||||||
|
match self {
|
||||||
|
Self::EnumVariant(_, v) | Self::EnumVariantS(_, v) => v,
|
||||||
|
v => v.to(),
|
||||||
|
}
|
||||||
|
}
|
||||||
pub fn fits_in(&self, rhs: &Self) -> bool {
|
pub fn fits_in(&self, rhs: &Self) -> bool {
|
||||||
match (self, rhs) {
|
match (self, rhs) {
|
||||||
|
(Self::Reference(r), Self::Reference(b)) => r.fits_in(b),
|
||||||
|
(Self::Reference(_), _) | (_, Self::Reference(_)) => false,
|
||||||
|
(Self::EnumVariant(v1, t1), Self::EnumVariant(v2, t2)) => {
|
||||||
|
*v1 == *v2 && t1.fits_in(&t2).is_empty()
|
||||||
|
}
|
||||||
|
(Self::EnumVariant(..), _) | (_, Self::EnumVariant(..)) => false,
|
||||||
|
(Self::EnumVariantS(..), _) | (_, Self::EnumVariantS(..)) => unreachable!(),
|
||||||
(Self::Bool, Self::Bool)
|
(Self::Bool, Self::Bool)
|
||||||
| (Self::Int, Self::Int)
|
| (Self::Int, Self::Int)
|
||||||
| (Self::Float, Self::Float)
|
| (Self::Float, Self::Float)
|
||||||
@ -171,8 +196,6 @@ impl VSingleType {
|
|||||||
(Self::Function(..), _) => false,
|
(Self::Function(..), _) => false,
|
||||||
(Self::Thread(a), Self::Thread(b)) => a.fits_in(b).is_empty(),
|
(Self::Thread(a), Self::Thread(b)) => a.fits_in(b).is_empty(),
|
||||||
(Self::Thread(..), _) => false,
|
(Self::Thread(..), _) => false,
|
||||||
(Self::Reference(r), Self::Reference(b)) => r.fits_in(b),
|
|
||||||
(Self::Reference(_), _) => false,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user