[fine] Support assignment to member, loops with iterators
Hmm it's starting to look like something.
This commit is contained in:
parent
3415b1a3f6
commit
239e859eaf
7 changed files with 360 additions and 171 deletions
|
|
@ -1,3 +1,4 @@
|
|||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
|
||||
use crate::compiler::{Export, Function, Instruction, Module};
|
||||
|
|
@ -48,17 +49,17 @@ type Result<T> = std::result::Result<T, VMErrorCode>;
|
|||
pub struct Object {
|
||||
name: Rc<str>,
|
||||
class_id: i64,
|
||||
values: Box<[StackValue]>,
|
||||
values: RefCell<Box<[StackValue]>>,
|
||||
}
|
||||
|
||||
impl Object {
|
||||
pub fn get_slot(&self, index: usize) -> Result<StackValue> {
|
||||
match self.values.get(index) {
|
||||
match self.values.borrow().get(index) {
|
||||
Some(v) => Ok(v.clone()),
|
||||
None => Err(VMErrorCode::SlotOutOfRange(
|
||||
index,
|
||||
self.name.clone(),
|
||||
self.values.len(),
|
||||
self.values.borrow().len(),
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
|
@ -76,6 +77,43 @@ pub enum StackValue {
|
|||
Object(Rc<Object>),
|
||||
}
|
||||
|
||||
impl StackValue {
|
||||
pub fn is_object(&self, id: i64) -> bool {
|
||||
match self {
|
||||
StackValue::Object(o) => o.class_id == id,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_float(&self) -> bool {
|
||||
match self {
|
||||
StackValue::Float(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_nothing(&self) -> bool {
|
||||
match self {
|
||||
StackValue::Nothing => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_bool(&self) -> bool {
|
||||
match self {
|
||||
StackValue::Bool(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_string(&self) -> bool {
|
||||
match self {
|
||||
StackValue::String(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum FuncValue {
|
||||
Function(Rc<Function>),
|
||||
ExternFunction(usize),
|
||||
|
|
@ -387,6 +425,11 @@ fn eval_one(
|
|||
let v = f.pop_value()?;
|
||||
c.set_global(i, v)?;
|
||||
}
|
||||
Instruction::StoreSlot(i) => {
|
||||
let o = f.pop_object()?;
|
||||
let v = f.pop_value()?;
|
||||
o.values.borrow_mut()[i] = v;
|
||||
}
|
||||
Instruction::LoadFunction(i) => {
|
||||
let v = c.get_function(i)?;
|
||||
f.push_function(v);
|
||||
|
|
@ -477,7 +520,7 @@ fn eval_one(
|
|||
let object = Object {
|
||||
name,
|
||||
class_id,
|
||||
values: values.into(),
|
||||
values: RefCell::new(values.into()),
|
||||
};
|
||||
|
||||
f.push_object(object.into());
|
||||
|
|
@ -488,16 +531,27 @@ fn eval_one(
|
|||
}
|
||||
Instruction::IsClass(id) => {
|
||||
let value = f.pop_value()?;
|
||||
match value {
|
||||
StackValue::Object(o) => {
|
||||
f.push_bool(o.class_id == id);
|
||||
}
|
||||
_ => f.push_bool(false),
|
||||
}
|
||||
f.push_bool(value.is_object(id));
|
||||
}
|
||||
Instruction::PushInt(v) => {
|
||||
f.push_int(v);
|
||||
}
|
||||
Instruction::IsBool => {
|
||||
let v = f.pop_value()?;
|
||||
f.push_bool(v.is_bool());
|
||||
}
|
||||
Instruction::IsFloat => {
|
||||
let v = f.pop_value()?;
|
||||
f.push_bool(v.is_float());
|
||||
}
|
||||
Instruction::IsString => {
|
||||
let v = f.pop_value()?;
|
||||
f.push_bool(v.is_string());
|
||||
}
|
||||
Instruction::IsNothing => {
|
||||
let v = f.pop_value()?;
|
||||
f.push_bool(v.is_nothing());
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Flow::Continue)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue