mirror of
https://github.com/zaphar/ucg.git
synced 2025-07-24 18:39:50 -04:00
DEV: Implement Jumping
This commit is contained in:
parent
04480663e8
commit
dc7437a8c1
@ -62,13 +62,18 @@ pub enum Op {
|
|||||||
Sym(String),
|
Sym(String),
|
||||||
// Complex Type ops
|
// Complex Type ops
|
||||||
InitTuple,
|
InitTuple,
|
||||||
FIELD,
|
Field,
|
||||||
InitList,
|
InitList,
|
||||||
Element,
|
Element,
|
||||||
// Operations
|
// Operations
|
||||||
Cp,
|
Cp,
|
||||||
// record
|
// Control Flow
|
||||||
InitThunk,
|
Select,
|
||||||
|
Bang,
|
||||||
|
Jump(usize),
|
||||||
|
Noop,
|
||||||
|
// Pending Computation
|
||||||
|
InitThunk(usize),
|
||||||
Return,
|
Return,
|
||||||
// - Call
|
// - Call
|
||||||
// Runtime hooks
|
// Runtime hooks
|
||||||
@ -86,6 +91,7 @@ pub struct Error {}
|
|||||||
|
|
||||||
pub struct VM {
|
pub struct VM {
|
||||||
stack: Vec<Value>,
|
stack: Vec<Value>,
|
||||||
|
// TODO(jwall): We may want to preserve order on these.
|
||||||
symbols: BTreeMap<String, Value>,
|
symbols: BTreeMap<String, Value>,
|
||||||
ops: OpPointer,
|
ops: OpPointer,
|
||||||
}
|
}
|
||||||
@ -114,13 +120,19 @@ impl VM {
|
|||||||
Op::InitList => self.composite_push(List(Vec::new()))?,
|
Op::InitList => self.composite_push(List(Vec::new()))?,
|
||||||
// Add a composite tuple value to the stack
|
// Add a composite tuple value to the stack
|
||||||
Op::InitTuple => self.composite_push(Tuple(Vec::new()))?,
|
Op::InitTuple => self.composite_push(Tuple(Vec::new()))?,
|
||||||
Op::FIELD => self.op_field()?,
|
Op::Field => self.op_field()?,
|
||||||
Op::Element => self.op_element()?,
|
Op::Element => self.op_element()?,
|
||||||
Op::Cp => self.op_copy()?,
|
Op::Cp => self.op_copy()?,
|
||||||
Op::InitThunk => self.op_thunk(idx)?,
|
Op::Select => self.op_select()?,
|
||||||
|
Op::Bang => return Err(Error {}),
|
||||||
|
Op::InitThunk(jp) => self.op_thunk(idx, *jp)?,
|
||||||
|
Op::Noop => {
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
Op::Return => {
|
Op::Return => {
|
||||||
// TODO(jwall): This means we return back to the start of the frame.
|
// TODO(jwall): This means we return back to the start of the frame.
|
||||||
}
|
}
|
||||||
|
Op::Jump(jp) => self.ops.jump(self.ops.ptr.map(|v| v + jp).unwrap_or(*jp))?,
|
||||||
Op::Pop => {
|
Op::Pop => {
|
||||||
self.pop()?;
|
self.pop()?;
|
||||||
}
|
}
|
||||||
@ -129,9 +141,20 @@ impl VM {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn op_thunk(&mut self, idx: usize) -> Result<(), Error> {
|
fn op_thunk(&mut self, idx: usize, jp: usize) -> Result<(), Error> {
|
||||||
// TODO(jwall): Record the position in the op codes.
|
|
||||||
self.push(Value::T(idx))?;
|
self.push(Value::T(idx))?;
|
||||||
|
self.ops.jump(self.ops.ptr.map(|v| v + jp).unwrap_or(jp))?;
|
||||||
|
// TODO(jwall): Skip over the rest until we reach the return?
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn op_select(&mut self) -> Result<(), Error> {
|
||||||
|
// first get our compare value from the stack
|
||||||
|
let search_field = self.pop()?;
|
||||||
|
// next get our default value from the stack
|
||||||
|
let default_field = self.pop()?;
|
||||||
|
// finally get our fields from the stack
|
||||||
|
let fields = self.pop()?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,9 +13,12 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
use super::Composite::{List, Tuple};
|
use super::Composite::{List, Tuple};
|
||||||
use super::Op::{Add, Bind, Cp, Div, Element, InitList, InitTuple, Mul, Sub, Sym, Val, FIELD};
|
use super::Op::{
|
||||||
|
Add, Bind, Cp, Div, Element, Field, InitList, InitThunk, InitTuple, Jump, Mul, Noop, Sub, Sym,
|
||||||
|
Val,
|
||||||
|
};
|
||||||
use super::Primitive::{Float, Int, Str};
|
use super::Primitive::{Float, Int, Str};
|
||||||
use super::Value::{C, P};
|
use super::Value::{C, P, T};
|
||||||
use super::VM;
|
use super::VM;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -118,7 +121,7 @@ fn test_tuple_ops() {
|
|||||||
let mut cases = vec![
|
let mut cases = vec![
|
||||||
(vec![InitTuple], C(Tuple(Vec::new()))),
|
(vec![InitTuple], C(Tuple(Vec::new()))),
|
||||||
(
|
(
|
||||||
vec![InitTuple, Val(Str("foo".to_owned())), Val(Int(1)), FIELD],
|
vec![InitTuple, Val(Str("foo".to_owned())), Val(Int(1)), Field],
|
||||||
C(Tuple(vec![("foo".to_owned(), P(Int(1)))])),
|
C(Tuple(vec![("foo".to_owned(), P(Int(1)))])),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@ -126,10 +129,10 @@ fn test_tuple_ops() {
|
|||||||
InitTuple,
|
InitTuple,
|
||||||
Sym("bar".to_owned()),
|
Sym("bar".to_owned()),
|
||||||
Val(Str("quux".to_owned())),
|
Val(Str("quux".to_owned())),
|
||||||
FIELD,
|
Field,
|
||||||
Val(Str("foo".to_owned())),
|
Val(Str("foo".to_owned())),
|
||||||
Val(Int(1)),
|
Val(Int(1)),
|
||||||
FIELD,
|
Field,
|
||||||
],
|
],
|
||||||
C(Tuple(vec![
|
C(Tuple(vec![
|
||||||
("bar".to_owned(), P(Str("quux".to_owned()))),
|
("bar".to_owned(), P(Str("quux".to_owned()))),
|
||||||
@ -141,14 +144,14 @@ fn test_tuple_ops() {
|
|||||||
InitTuple,
|
InitTuple,
|
||||||
Sym("bar".to_owned()),
|
Sym("bar".to_owned()),
|
||||||
Val(Str("quux".to_owned())),
|
Val(Str("quux".to_owned())),
|
||||||
FIELD,
|
Field,
|
||||||
Val(Str("foo".to_owned())),
|
Val(Str("foo".to_owned())),
|
||||||
Val(Int(1)),
|
Val(Int(1)),
|
||||||
FIELD,
|
Field,
|
||||||
Cp,
|
Cp,
|
||||||
Val(Str("foo".to_owned())),
|
Val(Str("foo".to_owned())),
|
||||||
Val(Int(2)),
|
Val(Int(2)),
|
||||||
FIELD,
|
Field,
|
||||||
],
|
],
|
||||||
C(Tuple(vec![
|
C(Tuple(vec![
|
||||||
("bar".to_owned(), P(Str("quux".to_owned()))),
|
("bar".to_owned(), P(Str("quux".to_owned()))),
|
||||||
@ -162,14 +165,14 @@ fn test_tuple_ops() {
|
|||||||
Val(Str("ux".to_owned())),
|
Val(Str("ux".to_owned())),
|
||||||
Val(Str("qu".to_owned())),
|
Val(Str("qu".to_owned())),
|
||||||
Add,
|
Add,
|
||||||
FIELD,
|
Field,
|
||||||
Val(Str("foo".to_owned())),
|
Val(Str("foo".to_owned())),
|
||||||
Val(Int(1)),
|
Val(Int(1)),
|
||||||
FIELD,
|
Field,
|
||||||
Cp,
|
Cp,
|
||||||
Val(Str("foo".to_owned())),
|
Val(Str("foo".to_owned())),
|
||||||
Val(Int(2)),
|
Val(Int(2)),
|
||||||
FIELD,
|
Field,
|
||||||
],
|
],
|
||||||
C(Tuple(vec![
|
C(Tuple(vec![
|
||||||
("bar".to_owned(), P(Str("quux".to_owned()))),
|
("bar".to_owned(), P(Str("quux".to_owned()))),
|
||||||
@ -183,3 +186,16 @@ fn test_tuple_ops() {
|
|||||||
assert_eq!(vm.pop().unwrap(), case.1);
|
assert_eq!(vm.pop().unwrap(), case.1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_jump_ops() {
|
||||||
|
let mut cases = vec![
|
||||||
|
(vec![InitThunk(1), Val(Int(1)), Noop], T(0)),
|
||||||
|
(vec![Jump(1), Val(Int(1)), Noop, Val(Int(1))], P(Int(1))),
|
||||||
|
];
|
||||||
|
for case in cases.drain(0..) {
|
||||||
|
let mut vm = VM::new(case.0);
|
||||||
|
vm.run().unwrap();
|
||||||
|
assert_eq!(vm.pop().unwrap(), case.1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user