Skip to content

Commit

Permalink
Implement the 'instVarAt:' primitive.
Browse files Browse the repository at this point in the history
  • Loading branch information
ltratt committed Jun 15, 2020
1 parent 54422e8 commit ec29caf
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 2 deletions.
14 changes: 14 additions & 0 deletions lang_tests/inst_var_at.som
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
"
VM:
status: success
stdout: 5
"

inst_var_at = (
| x |

run = (
x := 5.
(self instVarAt: 1) println.
)
)
17 changes: 17 additions & 0 deletions lang_tests/inst_var_at_bad_idx.som
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
"
VM:
status: error
stderr:
Traceback...
...
Index 2 not valid for array of length 1.
"

inst_var_at_bad_idx = (
| x |

run = (
x := 5.
(self instVarAt: 2) println.
)
)
8 changes: 7 additions & 1 deletion src/lib/vm/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -815,7 +815,13 @@ impl VM {
SendReturn::Val
}
Primitive::Inspect => unimplemented!(),
Primitive::InstVarAt => unimplemented!(),
Primitive::InstVarAt => {
let n = stry!(self.stack.pop().as_usize(self));
let inst = stry!(rcv.tobj(self));
let v = stry!(inst.inst_var_at(self, n));
self.stack.push(v);
SendReturn::Val
}
Primitive::InstVarAtPut => unimplemented!(),
Primitive::InstVarNamed => unimplemented!(),
Primitive::InvokeOnWith => todo!(),
Expand Down
4 changes: 4 additions & 0 deletions src/lib/vm/objects/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ impl Obj for Inst {
self.class
}

fn num_inst_vars(&self) -> usize {
unsafe { &*self.inst_vars.get() }.len()
}

unsafe fn unchecked_inst_var_get(&self, n: usize) -> Val {
let inst_vars = &mut *self.inst_vars.get();
inst_vars[n]
Expand Down
26 changes: 25 additions & 1 deletion src/lib/vm/objects/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,11 @@ pub use string_::String_;
use natrob::narrowable_rboehm;
use rboehm::Gc;

use crate::vm::{core::VM, error::VMError, val::Val};
use crate::vm::{
core::VM,
error::{VMError, VMErrorKind},
val::Val,
};

/// The SOM type of objects.
#[derive(Debug, PartialEq)]
Expand Down Expand Up @@ -93,6 +97,26 @@ pub trait Obj: std::fmt::Debug {
unreachable!();
}

/// How many instance variables does this object contain?
fn num_inst_vars(&self) -> usize {
unreachable!();
}

/// Return the instance variable at `i` (using SOM indexing).
fn inst_var_at(&self, vm: &VM, i: usize) -> Result<Val, Box<VMError>> {
if i > 0 && i <= self.num_inst_vars() {
Ok(unsafe { self.unchecked_inst_var_get(i - 1) })
} else {
Err(VMError::new(
vm,
VMErrorKind::IndexError {
tried: i,
max: self.num_inst_vars(),
},
))
}
}

/// Lookup an instance variable in this object. If `usize` exceeds the number of instance
/// variables this will lead to undefined behaviour.
unsafe fn unchecked_inst_var_get(&self, _: usize) -> Val {
Expand Down

0 comments on commit ec29caf

Please sign in to comment.