Skip to content

Commit 3b236e4

Browse files
authored
Merge pull request #28 from Maaarcocr/main
Implement arrays natively
2 parents 6e54d08 + 711da3e commit 3b236e4

File tree

4 files changed

+125
-32
lines changed

4 files changed

+125
-32
lines changed

src/array.rs

Lines changed: 111 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,55 +2,144 @@ use crate::vm::{Value, Actor};
22
use crate::alloc::Alloc;
33
use crate::host::HostFn;
44

5-
#[derive(Clone, Default)]
65
pub struct Array
76
{
8-
pub elems: Vec<Value>,
7+
pub elems: *mut [Value],
8+
pub len: usize,
99
}
1010

1111
impl Array
1212
{
13-
pub fn with_capacity(cap: u32) -> Self
13+
pub fn with_capacity(capacity: usize, alloc: &mut Alloc) -> Result<Self, ()>
1414
{
15-
Self {
16-
elems: Vec::with_capacity(cap as usize)
15+
let table = alloc.alloc_table(capacity)?;
16+
Ok(Array { elems: table, len: 0 })
17+
}
18+
19+
pub fn clone(&self, alloc: &mut Alloc) -> Result<Self, ()>
20+
{
21+
let table = alloc.alloc_table(self.len)?;
22+
let mut arr = Array { elems: table, len: self.len };
23+
arr.items_mut().copy_from_slice(self.items());
24+
Ok(arr)
25+
}
26+
27+
pub fn items(&self) -> &[Value] {
28+
unsafe { &(*self.elems)[..self.len] }
29+
}
30+
31+
pub fn items_mut(&mut self) -> &mut [Value] {
32+
unsafe { &mut (*self.elems)[..self.len] }
33+
}
34+
35+
pub fn push(&mut self, val: Value, alloc: &mut Alloc) -> Result<(), ()>
36+
{
37+
if self.len == self.elems.len() {
38+
let new_len = self.len * 2 + 1;
39+
let new_elems = alloc.alloc_table(new_len)?;
40+
unsafe {
41+
(&mut *new_elems)[..self.len].copy_from_slice(&(*self.elems)[..self.len]);
42+
self.elems = new_elems;
43+
}
44+
}
45+
unsafe {
46+
(&mut *self.elems)[self.len] = val;
47+
self.len += 1;
48+
}
49+
Ok(())
50+
}
51+
52+
pub fn insert(&mut self, idx: usize, val: Value, alloc: &mut Alloc) -> Result<(), ()>
53+
{
54+
if self.len == self.elems.len() {
55+
let new_len = self.len * 2 + 1;
56+
let new_elems = alloc.alloc_table(new_len)?;
57+
unsafe {
58+
(&mut *new_elems).copy_from_slice(&(*self.elems)[..self.len]);
59+
self.elems = new_elems;
60+
}
1761
}
62+
unsafe {
63+
(&mut *self.elems).copy_within(idx..self.len, idx + 1);
64+
(&mut *self.elems)[idx] = val;
65+
self.len += 1;
66+
}
67+
68+
Ok(())
1869
}
1970

20-
pub fn push(&mut self, val: Value)
71+
pub fn remove(&mut self, idx: usize) -> Value
2172
{
22-
self.elems.push(val);
73+
if idx >= self.len {
74+
return Value::Nil;
75+
}
76+
77+
let removed = unsafe { (&mut *self.elems)[idx] };
78+
unsafe {
79+
(&mut *self.elems).copy_within(idx + 1..self.len, idx);
80+
}
81+
82+
self.len -= 1;
83+
removed
84+
}
85+
86+
pub fn extend(&mut self, other: &Array, alloc: &mut Alloc) -> Result<(), ()> {
87+
let other_elems = other.elems;
88+
if self.len + other_elems.len() > self.elems.len() {
89+
let new_len = self.len + other_elems.len();
90+
let new_elems = alloc.alloc_table(new_len)?;
91+
unsafe {
92+
(&mut *new_elems)[..self.len].copy_from_slice(&(*self.elems)[..self.len]);
93+
(&mut *new_elems)[self.len..].copy_from_slice(&(*other_elems)[..other_elems.len()]);
94+
self.elems = new_elems;
95+
}
96+
} else {
97+
unsafe {
98+
(&mut *self.elems)[self.len..].copy_from_slice(&(*other_elems)[..other_elems.len()]);
99+
}
100+
}
101+
self.len += other_elems.len();
102+
103+
Ok(())
23104
}
24105

25106
pub fn pop(&mut self) -> Value
26107
{
27-
self.elems.pop().unwrap()
108+
if self.len == 0 {
109+
return Value::Nil;
110+
}
111+
112+
self.len -= 1;
113+
unsafe { (*self.elems) [self.len] }
28114
}
29115

30116
pub fn get(&self, idx: usize) -> Value
31117
{
32-
self.elems[idx]
118+
unsafe { (*self.elems) [idx] }
33119
}
34120

35121
pub fn set(&mut self, idx: usize, val: Value)
36122
{
37-
self.elems[idx] = val;
123+
unsafe { (*self.elems) [idx] = val };
124+
}
125+
126+
pub fn len(&self) -> usize {
127+
self.len
38128
}
39129
}
40130

41131
pub fn array_with_size(actor: &mut Actor, _self: Value, num_elems: Value, fill_val: Value) -> Result<Value, String>
42132
{
43133
let num_elems = num_elems.unwrap_usize();
44-
let mut elems = Vec::with_capacity(num_elems);
45-
elems.resize(num_elems, fill_val);
46-
let arr = Array { elems };
47-
let p_arr = actor.alloc.alloc(arr).unwrap();
48-
Ok(Value::Array(p_arr))
134+
let mut elems = actor.alloc.alloc_table(num_elems).unwrap();
135+
unsafe { (&mut *elems).fill(fill_val); }
136+
let arr = Array { elems, len: num_elems };
137+
Ok(Value::Array(actor.alloc.alloc(arr).unwrap()))
49138
}
50139

51140
pub fn array_push(actor: &mut Actor, mut array: Value, val: Value) -> Result<Value, String>
52141
{
53-
array.unwrap_arr().push(val);
142+
array.unwrap_arr().push(val, &mut actor.alloc).unwrap();
54143
Ok(Value::Nil)
55144
}
56145

@@ -62,19 +151,19 @@ pub fn array_pop(actor: &mut Actor, mut array: Value) -> Result<Value, String>
62151
pub fn array_remove(actor: &mut Actor, mut array: Value, idx: Value) -> Result<Value, String>
63152
{
64153
let idx = idx.unwrap_usize();
65-
Ok(array.unwrap_arr().elems.remove(idx))
154+
Ok(array.unwrap_arr().remove(idx))
66155
}
67156

68157
pub fn array_insert(actor: &mut Actor, mut array: Value, idx: Value, val: Value) -> Result<Value, String>
69158
{
70159
let idx = idx.unwrap_usize();
71-
array.unwrap_arr().elems.insert(idx, val);
160+
array.unwrap_arr().insert(idx, val, &mut actor.alloc).unwrap();
72161
Ok(Value::Nil)
73162
}
74163

75-
pub fn array_append(_actor: &mut Actor, mut self_array: Value, mut other_array: Value) -> Result<Value, String>
164+
pub fn array_append(actor: &mut Actor, mut self_array: Value, mut other_array: Value) -> Result<Value, String>
76165
{
77-
let other_elems = other_array.unwrap_arr().elems.clone();
78-
self_array.unwrap_arr().elems.extend(other_elems);
166+
let other_elems = other_array.unwrap_arr();
167+
self_array.unwrap_arr().extend(other_elems, &mut actor.alloc).unwrap();
79168
Ok(Value::Nil)
80-
}
169+
}

src/deepcopy.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -127,9 +127,9 @@ pub fn deepcopy(
127127
}
128128

129129
Value::Array(p) => {
130-
let new_arr = unsafe { (*p).clone() };
130+
let new_arr = unsafe { (*p).clone(dst_alloc).unwrap() };
131131

132-
for val in &new_arr.elems {
132+
for val in new_arr.items() {
133133
push_val!(val);
134134
}
135135

@@ -195,7 +195,7 @@ pub fn remap(dst_map: &mut HashMap<Value, Value>)
195195

196196
Value::Array(p) => {
197197
let arr = unsafe { &mut **p };
198-
for val in &mut arr.elems {
198+
for val in arr.items_mut() {
199199
remap_val!(val);
200200
}
201201
}

src/runtime.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use crate::array::Array;
12
use crate::ast::*;
23
use crate::vm::{Value, Actor};
34
use crate::{error, unwrap_usize, unwrap_str};
@@ -248,13 +249,16 @@ fn string_split(actor: &mut Actor, s: Value, sep: Value) -> Result<Value, String
248249
{
249250
let s = unwrap_str!(s);
250251
let sep = unwrap_str!(sep);
252+
let str_parts = s.split(sep);
253+
let size = str_parts.size_hint().0;
251254

252-
let parts: Vec<Value> = s.split(sep).map(|part| {
253-
actor.alloc.str_val(&part.to_string()).unwrap()
254-
}).collect();
255+
let mut array = Array::with_capacity(size, &mut actor.alloc).unwrap();
255256

256-
let arr = crate::array::Array { elems: parts };
257-
Ok(Value::Array(actor.alloc.alloc(arr).unwrap()))
257+
for part in str_parts {
258+
array.push(actor.alloc.str_val(part).unwrap(), &mut actor.alloc).unwrap();
259+
}
260+
261+
Ok(Value::Array(actor.alloc.alloc(array).unwrap()))
258262
}
259263

260264
pub fn init_runtime(prog: &mut Program)

src/vm.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1866,7 +1866,7 @@ impl Actor
18661866
let val = match obj {
18671867
Value::Array(p) => {
18681868
match field_name.as_str() {
1869-
"len" => obj.unwrap_arr().elems.len().into(),
1869+
"len" => obj.unwrap_arr().len().into(),
18701870
_ => error!("get_field", "field not found on array")
18711871
}
18721872
}
@@ -1998,7 +1998,7 @@ impl Actor
19981998
Insn::arr_push => {
19991999
let val = pop!();
20002000
let mut arr = pop!();
2001-
arr.unwrap_arr().push(val);
2001+
arr.unwrap_arr().push(val, &mut self.alloc).unwrap();
20022002
}
20032003

20042004
// Clone a bytearray

0 commit comments

Comments
 (0)