Skip to content

Commit 0263235

Browse files
committed
Implement the 'instVarAt:put:' primitive.
1 parent ec29caf commit 0263235

File tree

4 files changed

+60
-1
lines changed

4 files changed

+60
-1
lines changed

lang_tests/inst_var_at_put.som

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
"
2+
VM:
3+
status: success
4+
stdout:
5+
5
6+
instance of inst_var_at_put
7+
6
8+
"
9+
10+
inst_var_at_put = (
11+
| x |
12+
13+
run = (
14+
x := 5.
15+
(self instVarAt: 1) println.
16+
(self instVarAt: 1 put: 6) println.
17+
x println.
18+
)
19+
)
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
"
2+
VM:
3+
status: error
4+
stderr:
5+
Traceback...
6+
...
7+
Index 2 not valid for array of length 1.
8+
"
9+
10+
inst_var_at_put_bad_idx = (
11+
| x |
12+
13+
run = (
14+
x := 5.
15+
self instVarAt: 2 put: 6.
16+
x println.
17+
)
18+
)

src/lib/vm/core.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -822,7 +822,14 @@ impl VM {
822822
self.stack.push(v);
823823
SendReturn::Val
824824
}
825-
Primitive::InstVarAtPut => unimplemented!(),
825+
Primitive::InstVarAtPut => {
826+
let v = self.stack.pop();
827+
let n = stry!(self.stack.pop().as_usize(self));
828+
let inst = stry!(rcv.tobj(self));
829+
stry!(inst.inst_var_at_put(self, n, v));
830+
self.stack.push(rcv);
831+
SendReturn::Val
832+
}
826833
Primitive::InstVarNamed => unimplemented!(),
827834
Primitive::InvokeOnWith => todo!(),
828835
Primitive::IsDigits => unimplemented!(),

src/lib/vm/objects/mod.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,21 @@ pub trait Obj: std::fmt::Debug {
117117
}
118118
}
119119

120+
/// Return the instance variable at `i` (using SOM indexing).
121+
fn inst_var_at_put(&self, vm: &VM, i: usize, v: Val) -> Result<(), Box<VMError>> {
122+
if i > 0 && i <= self.num_inst_vars() {
123+
Ok(unsafe { self.unchecked_inst_var_set(i - 1, v) })
124+
} else {
125+
Err(VMError::new(
126+
vm,
127+
VMErrorKind::IndexError {
128+
tried: i,
129+
max: self.num_inst_vars(),
130+
},
131+
))
132+
}
133+
}
134+
120135
/// Lookup an instance variable in this object. If `usize` exceeds the number of instance
121136
/// variables this will lead to undefined behaviour.
122137
unsafe fn unchecked_inst_var_get(&self, _: usize) -> Val {

0 commit comments

Comments
 (0)