Skip to content

Commit

Permalink
Index vector
Browse files Browse the repository at this point in the history
  • Loading branch information
Quaqqer committed Jan 22, 2024
1 parent 7c729e9 commit d2de176
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 7 deletions.
42 changes: 40 additions & 2 deletions crates/saft-bytecode/src/value.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::fmt::Write;
use std::rc::Rc;

use crate::{chunk::Chunk, num::Num};
Expand All @@ -7,6 +8,7 @@ pub enum Value {
Nil,
Num(Num),
Function(Function),
Vec(Vec<Value>),
}

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -133,6 +135,7 @@ impl Value {
Value::Num(Num::Int(_)) => ValueType::Int,
Value::Num(Num::Float(_)) => ValueType::Float,
Value::Function(_) => ValueType::Function,
Value::Vec(_) => ValueType::Vec,
}
}

Expand All @@ -148,11 +151,37 @@ impl Value {
Value::Nil => "nil".into(),
Value::Num(num) => num.repr(),
Value::Function(_) => "<function>".into(),
Value::Vec(vec) => {
let mut buf = String::new();
write!(buf, "[").unwrap();
for (i, v) in vec.iter().enumerate() {
if i != 0 {
write!(buf, ", ").unwrap();
}
write!(buf, "{}", v.repr()).unwrap();
}
write!(buf, "]").unwrap();
buf
}
}
}

pub fn index(&self, _index: &Value) -> Option<&Value> {
None
pub fn index<'a>(&'a self, index: &Value) -> IndexRes<'a> {
match self {
Value::Vec(vec) => match index {
Value::Num(Num::Int(i)) => {
let Ok(i): Result<usize, _> = (*i).try_into() else {
return IndexRes::OutOfBounds;
};

vec.get(i)
.map(IndexRes::Value)
.unwrap_or(IndexRes::OutOfBounds)
}
_ => IndexRes::Unindexable,
},
_ => IndexRes::Unindexable,
}
}

pub fn index_assign(&self, _index: &Value, _value: Value) -> bool {
Expand Down Expand Up @@ -244,6 +273,7 @@ pub enum ValueType {
Int,
Float,
Function,
Vec,
}

impl ValueType {
Expand All @@ -254,6 +284,14 @@ impl ValueType {
ValueType::Int => "int",
ValueType::Float => "float",
ValueType::Function => "function",
ValueType::Vec => "vec",
}
}
}

pub enum IndexRes<'a> {
Unindexable,
OutOfBounds,
NonExistant,
Value(&'a Value),
}
28 changes: 23 additions & 5 deletions crates/saft-bytecode/src/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::{
constant::Constant,
num::Num,
op::Op,
value::{Function, Value},
value::{Function, IndexRes, Value},
};

struct CallFrame {
Expand Down Expand Up @@ -94,7 +94,12 @@ impl Vm {
) -> Result<(), Error> {
self.call_stack.push(CallFrame::new(chunk, 0));

self.run(constants)
let res = self.run(constants);

self.call_stack.pop().unwrap();
assert!(self.call_stack.is_empty());

res
}

pub fn interpret_expr(
Expand Down Expand Up @@ -221,8 +226,7 @@ impl Vm {
let index = self.pop();
let indexable = self.pop();
match indexable.index(&index) {
Some(v) => self.push(v.clone()),
None => exotic!(
IndexRes::Unindexable => exotic!(
"Unindexable",
s,
format!(
Expand All @@ -231,9 +235,23 @@ impl Vm {
index.ty().name()
)
),
IndexRes::OutOfBounds => exotic!(
"Out of bounds",
s,
format!(
"Cannot index '{}' by '{}'",
indexable.ty().name(),
index.ty().name()
)
),
IndexRes::NonExistant => todo!(),
IndexRes::Value(v) => self.push(v.clone()),
}
}
Op::Vec(_) => todo!(),
Op::Vec(n) => {
let elems = self.popn(*n);
self.push(Value::Vec(elems));
}
Op::Assign(i) => {
self.stack[*i] = self.stack.last().unwrap().clone();
}
Expand Down

0 comments on commit d2de176

Please sign in to comment.