mirror of
https://github.com/Dummi26/mers.git
synced 2025-03-10 14:13:52 +01:00
added more accurate type-checking to some of the builtins
This commit is contained in:
parent
effdc096a2
commit
65fdc87c01
@ -332,8 +332,13 @@ impl BuiltinFunction {
|
|||||||
if input.len() == 2 {
|
if input.len() == 2 {
|
||||||
// check if the element that should be inserted fits in the list's inner type
|
// check if the element that should be inserted fits in the list's inner type
|
||||||
let (vec, el) = (&input[0], &input[1]);
|
let (vec, el) = (&input[0], &input[1]);
|
||||||
if let Some(t) = vec.get_any() {
|
// if vec.is_reference().is_some_and(|v| v) { // unstable
|
||||||
el.fits_in(&t).is_empty()
|
if let Some(true) = vec.is_reference() {
|
||||||
|
if let Some(t) = vec.get_any() {
|
||||||
|
el.fits_in(&t).is_empty()
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
@ -344,8 +349,50 @@ impl BuiltinFunction {
|
|||||||
Self::Insert => {
|
Self::Insert => {
|
||||||
if input.len() == 3 {
|
if input.len() == 3 {
|
||||||
let (vec, el) = (&input[0], &input[1]);
|
let (vec, el) = (&input[0], &input[1]);
|
||||||
if let Some(t) = vec.get_any() {
|
if let Some(true) = vec.is_reference() {
|
||||||
el.fits_in(&t).is_empty()
|
if let Some(t) = vec.get_any() {
|
||||||
|
el.fits_in(&t).is_empty()
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Self::Pop => {
|
||||||
|
if input.len() == 1 {
|
||||||
|
let vec = &input[0];
|
||||||
|
if let Some(true) = vec.is_reference() {
|
||||||
|
// TODO! this also returns true for tuples. what should we do for tuples? should pop return (first_val rest_of_tuple) and not take a reference?
|
||||||
|
if let Some(_) = vec.get_any() {
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Self::Remove => {
|
||||||
|
if input.len() == 2 {
|
||||||
|
let (vec, index) = (&input[0], &input[1]);
|
||||||
|
if let Some(true) = vec.is_reference() {
|
||||||
|
// TODO! same issue as in pop
|
||||||
|
if let Some(_) = vec.get_any() {
|
||||||
|
if index.fits_in(&VSingleType::Int.to()).is_empty() {
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
@ -354,7 +401,26 @@ impl BuiltinFunction {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO! finish this
|
// TODO! finish this
|
||||||
Self::Pop | Self::Remove | Self::Get | Self::Len | Self::Substring => true,
|
Self::Get | Self::Len => true,
|
||||||
|
Self::Substring => {
|
||||||
|
if input.len() >= 2 && input.len() <= 3 {
|
||||||
|
let (s, start) = (&input[0], &input[1]);
|
||||||
|
let index_type = VSingleType::Int.to();
|
||||||
|
if s.fits_in(&VSingleType::String.to()).is_empty()
|
||||||
|
&& start.fits_in(&index_type).is_empty()
|
||||||
|
{
|
||||||
|
if let Some(end) = input.get(2) {
|
||||||
|
end.fits_in(&index_type).is_empty()
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
Self::Contains | Self::StartsWith | Self::EndsWith | Self::Regex => {
|
Self::Contains | Self::StartsWith | Self::EndsWith | Self::Regex => {
|
||||||
input.len() == 2
|
input.len() == 2
|
||||||
&& input
|
&& input
|
||||||
|
@ -41,6 +41,24 @@ impl VType {
|
|||||||
}
|
}
|
||||||
Some(out)
|
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;
|
||||||
|
let mut reference = false;
|
||||||
|
for t in &self.types {
|
||||||
|
if t.is_reference() {
|
||||||
|
reference = true;
|
||||||
|
} else {
|
||||||
|
noref = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if noref != reference {
|
||||||
|
Some(reference)
|
||||||
|
} else {
|
||||||
|
// either empty (false == false) or mixed (true == true)
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl VSingleType {
|
impl VSingleType {
|
||||||
@ -55,6 +73,12 @@ impl VSingleType {
|
|||||||
Self::EnumVariantS(..) => unreachable!(),
|
Self::EnumVariantS(..) => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pub fn is_reference(&self) -> bool {
|
||||||
|
match self {
|
||||||
|
Self::Reference(_) => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
impl VType {
|
impl VType {
|
||||||
pub fn get_any(&self) -> Option<VType> {
|
pub fn get_any(&self) -> Option<VType> {
|
||||||
|
Loading…
Reference in New Issue
Block a user