about summary refs log tree commit diff
path: root/src/interpret/value.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/interpret/value.rs')
-rw-r--r--src/interpret/value.rs45
1 files changed, 37 insertions, 8 deletions
diff --git a/src/interpret/value.rs b/src/interpret/value.rs
index 1a7422b..f923742 100644
--- a/src/interpret/value.rs
+++ b/src/interpret/value.rs
@@ -2,7 +2,7 @@ use crate::parse::ast::nodes::FnNode;
 use std::{cell::RefCell, fmt::Display, rc::Rc};
 use thiserror::Error;
 
-type Ref<T> = RefCell<Rc<T>>;
+type ReferenceOnCopy<T> = Rc<RefCell<T>>;
 
 #[derive(Clone, Debug)]
 pub enum Value {
@@ -10,8 +10,8 @@ pub enum Value {
     Float(f64),
     Int(i64),
     Bool(bool),
-    Array(Vec<Value>),
-    Fn(Ref<FnNode>),
+    Array(ReferenceOnCopy<Vec<Value>>),
+    Fn(ReferenceOnCopy<FnNode>),
     Void,
 }
 
@@ -173,17 +173,45 @@ impl Value {
 
         match self {
             Value::Array(a) => {
-                if index < 0 || index as usize >= a.len() {
+                let array = a.borrow();
+                if index < 0 || index as usize >= array.len() {
                     Err(OperationError::ArrayIndexOutOfRange {
                         index,
-                        length: a.len(),
+                        length: array.len(),
                     })
                 } else {
-                    Ok(a[index as usize].clone())
+                    Ok(array[index as usize].clone())
                 }
             }
             // Maybe allow string subscripts?
-            x => Err(OperationError::ArrayType(x)),
+            x => Err(OperationError::ArrayType(x.clone())),
+        }
+    }
+
+    pub fn subscript_assign(
+        &mut self,
+        index: Value,
+        value: Value,
+    ) -> Result<Value, OperationError> {
+        let index = match index {
+            Value::Int(i) => i,
+            i => return Err(OperationError::ArrayIndexType(i)),
+        };
+
+        match self {
+            Value::Array(a) => {
+                let mut array = a.borrow_mut();
+                if index < 0 || index as usize >= array.len() {
+                    Err(OperationError::ArrayIndexOutOfRange {
+                        index,
+                        length: array.len(),
+                    })
+                } else {
+                    array[index as usize] = value;
+                    Ok(array[index as usize].clone())
+                }
+            }
+            x => Err(OperationError::ArrayType(x.clone())),
         }
     }
 }
@@ -213,7 +241,8 @@ impl Display for Value {
                 write!(
                     f,
                     "[{}]",
-                    a.iter()
+                    a.borrow()
+                        .iter()
                         .map(|v| format!("{}", v))
                         .collect::<Vec<_>>()
                         .join(", ")