1
0

Continue addind type evaluation

This commit is contained in:
Jeff 2024-11-06 00:57:54 -05:00
parent 314913dbf5
commit a16f7795de
4 changed files with 63 additions and 24 deletions

View File

@ -18,7 +18,7 @@ use std::{
use colored::Colorize;
use serde::{Deserialize, Serialize};
use crate::{Instruction, Span, Type, Value};
use crate::{Instruction, Operation, Span, Type, Value};
/// In-memory representation of a Dust program or function.
///
@ -174,13 +174,43 @@ impl Chunk {
return local_type;
}
self.instructions.iter().find_map(|(instruction, _)| {
if instruction.yields_value() && instruction.a() == register_index {
instruction.yielded_type(self)
} else {
None
}
})
self.instructions
.iter()
.enumerate()
.find_map(|(index, (instruction, _))| {
if let Operation::LoadList = instruction.operation() {
if instruction.a() == register_index {
let mut length = (instruction.c() - instruction.b() + 1) as usize;
let mut item_type = Type::Any;
let distance_to_end = self.len() - index;
for (instruction, _) in self
.instructions()
.iter()
.rev()
.skip(distance_to_end)
.take(length)
{
if let Operation::Close = instruction.operation() {
length -= (instruction.c() - instruction.b()) as usize;
} else if let Type::Any = item_type {
item_type = instruction.yielded_type(self).unwrap_or(Type::Any);
}
}
return Some(Type::List {
item_type: Box::new(item_type),
length,
});
}
}
if instruction.yields_value() && instruction.a() == register_index {
instruction.yielded_type(self)
} else {
None
}
})
}
pub fn return_type(&self) -> Option<Type> {

View File

@ -406,6 +406,8 @@ impl Instruction {
chunk.get_register_type(self.b())
}
}
LoadConstant => chunk.get_constant_type(self.b()),
LoadList => chunk.get_register_type(self.a()),
GetLocal => chunk.get_local_type(self.b()),
CallNative => {
let native_function = NativeFunction::from(self.b());

View File

@ -123,12 +123,19 @@ impl Vm {
let to_register = instruction.a();
let first_register = instruction.b();
let last_register = instruction.c();
let is_empty = to_register == first_register && first_register == last_register;
let item_type = if is_empty {
Type::Any
} else {
self.get_register(first_register, position)?.r#type()
let register_range = (first_register as usize)..=(last_register as usize);
self.stack[register_range]
.iter()
.find_map(|register| match register {
Register::Value(value) => Some(value.r#type()),
_ => None,
})
.unwrap_or(Type::Any)
};
let value = Value::list(first_register, last_register, item_type);

View File

@ -64,21 +64,21 @@ fn add_assign_expects_mutable_variable() {
);
}
#[test]
fn add_expects_integer_float_or_string() {
let source = "true + false";
// #[test]
// fn add_expects_integer_float_or_string() {
// let source = "true + false";
assert_eq!(
parse(source),
Err(DustError::Parse {
error: ParseError::ExpectedIntegerFloatOrString {
found: Token::True,
position: Span(0, 3)
},
source
})
);
}
// assert_eq!(
// parse(source),
// Err(DustError::Parse {
// error: ParseError::ExpectedIntegerFloatOrString {
// found: Token::True,
// position: Span(0, 3)
// },
// source
// })
// );
// }
#[test]
fn divide() {