diff --git a/lang_tests/instance_fields.som b/lang_tests/instance_fields.som new file mode 100644 index 00000000..c8ce65c0 --- /dev/null +++ b/lang_tests/instance_fields.som @@ -0,0 +1,19 @@ +" +VM: + status: success + stdout: + instance of Array + true + true +" + +instance_fields = ( + | x y | + run = ( + | fds | + fds := instance_fields fields. + fds println. + (fds contains: #x) println. + (fds contains: #y) println. + ) +) diff --git a/lang_tests/mutate_fields.som b/lang_tests/mutate_fields.som new file mode 100644 index 00000000..c9784f4e --- /dev/null +++ b/lang_tests/mutate_fields.som @@ -0,0 +1,29 @@ +" +VM: + status: success + stdout: + true + true + true + true + false +" + +mutate_fields = ( + | x y | + run = ( + | fds | + fds := mutate_fields fields. + (fds contains: #x) println. + (fds contains: #y) println. + fds at: 1 put: #z. + fds := mutate_fields fields. + (fds contains: #x) println. + (fds contains: #y) println. + (fds contains: #z) println. + ) + + find: sym = ( + method_holder methods do: [:e | ((e signature) == sym) ifTrue: [ ^e ]]. + ) +) diff --git a/src/lib/vm/core.rs b/src/lib/vm/core.rs index 57e9e463..06c61a24 100644 --- a/src/lib/vm/core.rs +++ b/src/lib/vm/core.rs @@ -717,7 +717,11 @@ impl VM { )) } } - Primitive::Fields => todo!(), + Primitive::Fields => { + let fields = stry!(rcv.downcast::(self)).fields(self); + self.stack.push(fields); + SendReturn::Val + } Primitive::FromString => todo!(), Primitive::FullGC => todo!(), Primitive::Global => { diff --git a/src/lib/vm/objects/class.rs b/src/lib/vm/objects/class.rs index 3bda8754..9e9baf16 100644 --- a/src/lib/vm/objects/class.rs +++ b/src/lib/vm/objects/class.rs @@ -12,7 +12,7 @@ use rboehm::Gc; use crate::vm::{ core::VM, error::{VMError, VMErrorKind}, - objects::{Array, Method, MethodsArray, Obj, ObjType, StaticObjType, String_}, + objects::{Array, Method, MethodsArray, NormalArray, Obj, ObjType, StaticObjType, String_}, val::{NotUnboxable, Val, ValKind}, }; @@ -164,6 +164,15 @@ impl Class { } } + pub fn fields(&self, vm: &mut VM) -> Val { + let field_strs = self + .inst_vars_map + .keys() + .map(|k| String_::new_sym(vm, k.clone())) + .collect(); + NormalArray::from_vec(vm, field_strs) + } + pub fn methods(&self, _: &VM) -> Val { self.methods }