mirror of
https://github.com/zaphar/ucg.git
synced 2025-07-22 18:19:54 -04:00
DEV: DSL for table based testing using macros.
This commit is contained in:
parent
3bb6f6e8eb
commit
aac263be2c
@ -22,49 +22,58 @@ use super::Primitive::{Bool, Float, Int, Str};
|
|||||||
use super::Value::{C, P, T};
|
use super::Value::{C, P, T};
|
||||||
use super::VM;
|
use super::VM;
|
||||||
|
|
||||||
|
macro_rules! assert_cases {
|
||||||
|
(__impl__ $cases:expr) => {
|
||||||
|
for case in $cases.drain(0..) {
|
||||||
|
let mut vm = VM::new(&case.0);
|
||||||
|
vm.run().unwrap();
|
||||||
|
assert_eq!(vm.pop().unwrap(), case.1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
(($input:expr, $result:expr), $($tok:tt)*) => {
|
||||||
|
assert_cases!(__impl__ vec![($input, $result), $($tok)*])
|
||||||
|
};
|
||||||
|
|
||||||
|
($($input:expr => $result:expr, )* ) => {
|
||||||
|
assert_cases!(
|
||||||
|
$(($input, $result),)*
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_math_ops() {
|
fn test_math_ops() {
|
||||||
let mut cases = vec![
|
assert_cases!(
|
||||||
// 1+1;
|
// 1+1;
|
||||||
(vec![Val(Int(1)), Val(Int(1)), Add], P(Int(2))),
|
vec![Val(Int(1)), Val(Int(1)), Add] => P(Int(2)),
|
||||||
// 1-1;
|
// 1-1;
|
||||||
(vec![Val(Int(1)), Val(Int(1)), Sub], P(Int(0))),
|
vec![Val(Int(1)), Val(Int(1)), Sub] => P(Int(0)),
|
||||||
// 2*2;
|
// 2*2;
|
||||||
(vec![Val(Int(2)), Val(Int(2)), Mul], P(Int(4))),
|
vec![Val(Int(2)), Val(Int(2)), Mul] => P(Int(4)),
|
||||||
// 6/3;
|
// 6/3;
|
||||||
(vec![Val(Int(2)), Val(Int(6)), Div], P(Int(3))),
|
vec![Val(Int(2)), Val(Int(6)), Div] => P(Int(3)),
|
||||||
// 1.0+1.0;
|
// 1.0+1.0;
|
||||||
(vec![Val(Float(1.0)), Val(Float(1.0)), Add], P(Float(2.0))),
|
vec![Val(Float(1.0)), Val(Float(1.0)), Add] => P(Float(2.0)),
|
||||||
// 1.0-1.0;
|
// 1.0-1.0;
|
||||||
(vec![Val(Float(1.0)), Val(Float(1.0)), Sub], P(Float(0.0))),
|
vec![Val(Float(1.0)), Val(Float(1.0)), Sub] => P(Float(0.0)),
|
||||||
// 2.0*2.0;
|
// 2.0*2.0;
|
||||||
(vec![Val(Float(2.0)), Val(Float(2.0)), Mul], P(Float(4.0))),
|
vec![Val(Float(2.0)), Val(Float(2.0)), Mul] => P(Float(4.0)),
|
||||||
// 6.0/3.0;
|
// 6.0/3.0;
|
||||||
(vec![Val(Float(2.0)), Val(Float(6.0)), Div], P(Float(3.0))),
|
vec![Val(Float(2.0)), Val(Float(6.0)), Div] => P(Float(3.0)),
|
||||||
// string concatenation
|
// string concatenation
|
||||||
(
|
vec![Val(Str("bar".to_owned())), Val(Str("foo".to_owned())), Add] => P(Str("foobar".to_owned())),
|
||||||
vec![Val(Str("bar".to_owned())), Val(Str("foo".to_owned())), Add],
|
|
||||||
P(Str("foobar".to_owned())),
|
|
||||||
),
|
|
||||||
// Composite operations
|
// Composite operations
|
||||||
(
|
vec![
|
||||||
vec![
|
Val(Int(1)),
|
||||||
Val(Int(1)),
|
Val(Int(1)),
|
||||||
Val(Int(1)),
|
Add, // 1 + 1
|
||||||
Add, // 1 + 1
|
Val(Int(1)),
|
||||||
Val(Int(1)),
|
Add, // 2 + 1
|
||||||
Add, // 2 + 1
|
Val(Int(1)),
|
||||||
Val(Int(1)),
|
Add, // 3 + 1
|
||||||
Add, // 3 + 1
|
] => P(Int(4)),
|
||||||
],
|
);
|
||||||
P(Int(4)),
|
|
||||||
),
|
|
||||||
];
|
|
||||||
for case in cases.drain(0..) {
|
|
||||||
let mut vm = VM::new(&case.0);
|
|
||||||
vm.run().unwrap();
|
|
||||||
assert_eq!(vm.pop().unwrap(), case.1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -87,415 +96,308 @@ fn test_bind_op() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_list_ops() {
|
fn test_list_ops() {
|
||||||
let mut cases = vec![
|
assert_cases!(
|
||||||
(vec![InitList], C(List(Vec::new()))),
|
vec![InitList] => C(List(Vec::new())),
|
||||||
(
|
vec![InitList, Val(Int(1)), Element] => C(List(vec![P(Int(1))])),
|
||||||
vec![InitList, Val(Int(1)), Element],
|
vec![InitList, Val(Int(2)), Element, Val(Int(1)), Element] => C(List(vec![P(Int(2)), P(Int(1))])),
|
||||||
C(List(vec![P(Int(1))])),
|
vec![
|
||||||
),
|
InitList,
|
||||||
(
|
Val(Int(1)),
|
||||||
vec![InitList, Val(Int(2)), Element, Val(Int(1)), Element],
|
Element,
|
||||||
C(List(vec![P(Int(2)), P(Int(1))])),
|
Val(Int(1)),
|
||||||
),
|
Val(Int(1)),
|
||||||
(
|
Add,
|
||||||
vec![
|
Element,
|
||||||
InitList,
|
] => C(List(vec![P(Int(1)), P(Int(2))])),
|
||||||
Val(Int(1)),
|
);
|
||||||
Element,
|
|
||||||
Val(Int(1)),
|
|
||||||
Val(Int(1)),
|
|
||||||
Add,
|
|
||||||
Element,
|
|
||||||
],
|
|
||||||
C(List(vec![P(Int(1)), P(Int(2))])),
|
|
||||||
),
|
|
||||||
];
|
|
||||||
for case in cases.drain(0..) {
|
|
||||||
let mut vm = VM::new(&case.0);
|
|
||||||
vm.run().unwrap();
|
|
||||||
assert_eq!(vm.pop().unwrap(), case.1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_tuple_ops() {
|
fn test_tuple_ops() {
|
||||||
let mut cases = vec![
|
assert_cases!(
|
||||||
(vec![InitTuple], C(Tuple(Vec::new()))),
|
vec![InitTuple] => C(Tuple(Vec::new())),
|
||||||
(
|
vec![InitTuple, Val(Str("foo".to_owned())), Val(Int(1)), Field] => C(Tuple(vec![("foo".to_owned(), P(Int(1)))])),
|
||||||
vec![InitTuple, Val(Str("foo".to_owned())), Val(Int(1)), Field],
|
vec![
|
||||||
C(Tuple(vec![("foo".to_owned(), P(Int(1)))])),
|
InitTuple,
|
||||||
),
|
Sym("bar".to_owned()),
|
||||||
(
|
Val(Str("quux".to_owned())),
|
||||||
vec![
|
Field,
|
||||||
InitTuple,
|
Val(Str("foo".to_owned())),
|
||||||
Sym("bar".to_owned()),
|
Val(Int(1)),
|
||||||
Val(Str("quux".to_owned())),
|
Field,
|
||||||
Field,
|
] => C(Tuple(vec![
|
||||||
Val(Str("foo".to_owned())),
|
("bar".to_owned(), P(Str("quux".to_owned()))),
|
||||||
Val(Int(1)),
|
("foo".to_owned(), P(Int(1))),
|
||||||
Field,
|
])),
|
||||||
],
|
vec![
|
||||||
C(Tuple(vec![
|
InitTuple,
|
||||||
("bar".to_owned(), P(Str("quux".to_owned()))),
|
Sym("bar".to_owned()),
|
||||||
("foo".to_owned(), P(Int(1))),
|
Val(Str("quux".to_owned())),
|
||||||
])),
|
Field,
|
||||||
),
|
Val(Str("foo".to_owned())),
|
||||||
(
|
Val(Int(1)),
|
||||||
vec![
|
Field,
|
||||||
InitTuple,
|
Val(Str("foo".to_owned())),
|
||||||
Sym("bar".to_owned()),
|
Val(Int(2)),
|
||||||
Val(Str("quux".to_owned())),
|
Field,
|
||||||
Field,
|
] => C(Tuple(vec![
|
||||||
Val(Str("foo".to_owned())),
|
("bar".to_owned(), P(Str("quux".to_owned()))),
|
||||||
Val(Int(1)),
|
("foo".to_owned(), P(Int(2))),
|
||||||
Field,
|
])),
|
||||||
Val(Str("foo".to_owned())),
|
vec![
|
||||||
Val(Int(2)),
|
InitTuple,
|
||||||
Field,
|
Sym("bar".to_owned()),
|
||||||
],
|
Val(Str("ux".to_owned())),
|
||||||
C(Tuple(vec![
|
Val(Str("qu".to_owned())),
|
||||||
("bar".to_owned(), P(Str("quux".to_owned()))),
|
Add,
|
||||||
("foo".to_owned(), P(Int(2))),
|
Field,
|
||||||
])),
|
Val(Str("foo".to_owned())),
|
||||||
),
|
Val(Int(1)),
|
||||||
(
|
Field,
|
||||||
vec![
|
Val(Str("foo".to_owned())),
|
||||||
InitTuple,
|
Val(Int(2)),
|
||||||
Sym("bar".to_owned()),
|
Field,
|
||||||
Val(Str("ux".to_owned())),
|
] => C(Tuple(vec![
|
||||||
Val(Str("qu".to_owned())),
|
("bar".to_owned(), P(Str("quux".to_owned()))),
|
||||||
Add,
|
("foo".to_owned(), P(Int(2))),
|
||||||
Field,
|
])),
|
||||||
Val(Str("foo".to_owned())),
|
vec![
|
||||||
Val(Int(1)),
|
InitTuple, // Override tuple
|
||||||
Field,
|
Val(Str("foo".to_owned())),
|
||||||
Val(Str("foo".to_owned())),
|
Val(Int(2)),
|
||||||
Val(Int(2)),
|
Field,
|
||||||
Field,
|
InitTuple, // Target tuple
|
||||||
],
|
Sym("bar".to_owned()),
|
||||||
C(Tuple(vec![
|
Val(Str("ux".to_owned())),
|
||||||
("bar".to_owned(), P(Str("quux".to_owned()))),
|
Val(Str("qu".to_owned())),
|
||||||
("foo".to_owned(), P(Int(2))),
|
Add,
|
||||||
])),
|
Field,
|
||||||
),
|
Val(Str("foo".to_owned())),
|
||||||
(
|
Val(Int(1)),
|
||||||
vec![
|
Field,
|
||||||
InitTuple, // Override tuple
|
Cp, // Do the tuple copy operation
|
||||||
Val(Str("foo".to_owned())),
|
] => C(Tuple(vec![
|
||||||
Val(Int(2)),
|
("bar".to_owned(), P(Str("quux".to_owned()))),
|
||||||
Field,
|
("foo".to_owned(), P(Int(2))),
|
||||||
InitTuple, // Target tuple
|
])),
|
||||||
Sym("bar".to_owned()),
|
);
|
||||||
Val(Str("ux".to_owned())),
|
|
||||||
Val(Str("qu".to_owned())),
|
|
||||||
Add,
|
|
||||||
Field,
|
|
||||||
Val(Str("foo".to_owned())),
|
|
||||||
Val(Int(1)),
|
|
||||||
Field,
|
|
||||||
Cp, // Do the tuple copy operation
|
|
||||||
],
|
|
||||||
C(Tuple(vec![
|
|
||||||
("bar".to_owned(), P(Str("quux".to_owned()))),
|
|
||||||
("foo".to_owned(), P(Int(2))),
|
|
||||||
])),
|
|
||||||
),
|
|
||||||
];
|
|
||||||
for case in cases.drain(0..) {
|
|
||||||
let mut vm = VM::new(&case.0);
|
|
||||||
vm.run().unwrap();
|
|
||||||
assert_eq!(vm.pop().unwrap(), case.1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_jump_ops() {
|
fn test_jump_ops() {
|
||||||
let mut cases = vec![
|
assert_cases!(
|
||||||
(vec![InitThunk(1), Val(Int(1)), Noop], T(0)),
|
vec![InitThunk(1), Val(Int(1)), Noop] => T(0),
|
||||||
(vec![Jump(1), Val(Int(1)), Noop, Val(Int(1))], P(Int(1))),
|
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_equality_ops() {
|
fn test_equality_ops() {
|
||||||
let mut cases = vec![
|
assert_cases![
|
||||||
(
|
vec![
|
||||||
vec![
|
Val(Str("foo".to_owned())),
|
||||||
Val(Str("foo".to_owned())),
|
Val(Str("foo".to_owned())),
|
||||||
Val(Str("foo".to_owned())),
|
Equal,
|
||||||
Equal,
|
] => P(Bool(true)),
|
||||||
],
|
vec![
|
||||||
P(Bool(true)),
|
Val(Str("bar".to_owned())),
|
||||||
),
|
Val(Str("foo".to_owned())),
|
||||||
(
|
Equal,
|
||||||
vec![
|
] => P(Bool(false)),
|
||||||
Val(Str("bar".to_owned())),
|
vec![Val(Int(1)), Val(Int(1)), Equal] => P(Bool(true)),
|
||||||
Val(Str("foo".to_owned())),
|
vec![Val(Int(1)), Val(Int(2)), Equal] => P(Bool(false)),
|
||||||
Equal,
|
vec![Val(Bool(true)), Val(Bool(true)), Equal] => P(Bool(true)),
|
||||||
],
|
vec![Val(Bool(false)), Val(Bool(false)), Equal] => P(Bool(true)),
|
||||||
P(Bool(false)),
|
vec![Val(Bool(true)), Val(Bool(false)), Equal] => P(Bool(false)),
|
||||||
),
|
vec![
|
||||||
(vec![Val(Int(1)), Val(Int(1)), Equal], P(Bool(true))),
|
InitTuple,
|
||||||
(vec![Val(Int(1)), Val(Int(2)), Equal], P(Bool(false))),
|
Val(Str("foo".to_owned())),
|
||||||
(vec![Val(Bool(true)), Val(Bool(true)), Equal], P(Bool(true))),
|
Val(Int(1)),
|
||||||
(
|
Field,
|
||||||
vec![Val(Bool(false)), Val(Bool(false)), Equal],
|
InitTuple,
|
||||||
P(Bool(true)),
|
Val(Str("foo".to_owned())),
|
||||||
),
|
Val(Int(1)),
|
||||||
(
|
Field,
|
||||||
vec![Val(Bool(true)), Val(Bool(false)), Equal],
|
Equal,
|
||||||
P(Bool(false)),
|
] => P(Bool(true)),
|
||||||
),
|
vec![
|
||||||
(
|
InitTuple,
|
||||||
vec![
|
Val(Str("foo".to_owned())),
|
||||||
InitTuple,
|
Val(Int(1)),
|
||||||
Val(Str("foo".to_owned())),
|
Field,
|
||||||
Val(Int(1)),
|
InitTuple,
|
||||||
Field,
|
Val(Str("bar".to_owned())),
|
||||||
InitTuple,
|
Val(Int(1)),
|
||||||
Val(Str("foo".to_owned())),
|
Field,
|
||||||
Val(Int(1)),
|
Equal,
|
||||||
Field,
|
] => P(Bool(false)),
|
||||||
Equal,
|
vec![
|
||||||
],
|
InitList,
|
||||||
P(Bool(true)),
|
Val(Str("foo".to_owned())),
|
||||||
),
|
Element,
|
||||||
(
|
InitList,
|
||||||
vec![
|
Val(Str("foo".to_owned())),
|
||||||
InitTuple,
|
Element,
|
||||||
Val(Str("foo".to_owned())),
|
Equal,
|
||||||
Val(Int(1)),
|
] => P(Bool(true)),
|
||||||
Field,
|
vec![
|
||||||
InitTuple,
|
InitList,
|
||||||
Val(Str("bar".to_owned())),
|
Val(Str("foo".to_owned())),
|
||||||
Val(Int(1)),
|
Element,
|
||||||
Field,
|
InitList,
|
||||||
Equal,
|
Val(Str("bar".to_owned())),
|
||||||
],
|
Element,
|
||||||
P(Bool(false)),
|
Equal,
|
||||||
),
|
] => P(Bool(false)),
|
||||||
(
|
|
||||||
vec![
|
|
||||||
InitList,
|
|
||||||
Val(Str("foo".to_owned())),
|
|
||||||
Element,
|
|
||||||
InitList,
|
|
||||||
Val(Str("foo".to_owned())),
|
|
||||||
Element,
|
|
||||||
Equal,
|
|
||||||
],
|
|
||||||
P(Bool(true)),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
vec![
|
|
||||||
InitList,
|
|
||||||
Val(Str("foo".to_owned())),
|
|
||||||
Element,
|
|
||||||
InitList,
|
|
||||||
Val(Str("bar".to_owned())),
|
|
||||||
Element,
|
|
||||||
Equal,
|
|
||||||
],
|
|
||||||
P(Bool(false)),
|
|
||||||
),
|
|
||||||
];
|
];
|
||||||
for case in cases.drain(0..) {
|
|
||||||
let mut vm = VM::new(&case.0);
|
|
||||||
vm.run().unwrap();
|
|
||||||
assert_eq!(vm.pop().unwrap(), case.1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_conditional_jump_ops() {
|
fn test_conditional_jump_ops() {
|
||||||
let mut cases = vec![
|
assert_cases![
|
||||||
(
|
vec![
|
||||||
vec![
|
Val(Bool(false)),
|
||||||
Val(Bool(false)),
|
JumpIfTrue(2),
|
||||||
JumpIfTrue(2),
|
Val(Bool(true)),
|
||||||
Val(Bool(true)),
|
JumpIfTrue(2),
|
||||||
JumpIfTrue(2),
|
Val(Int(1)),
|
||||||
Val(Int(1)),
|
Jump(1),
|
||||||
Jump(1),
|
Val(Int(2)),
|
||||||
Val(Int(2)),
|
Noop,
|
||||||
Noop,
|
] => P(Int(2)),
|
||||||
],
|
vec![
|
||||||
P(Int(2)),
|
Val(Bool(true)),
|
||||||
),
|
JumpIfTrue(2),
|
||||||
(
|
Val(Bool(false)),
|
||||||
vec![
|
JumpIfTrue(2),
|
||||||
Val(Bool(true)),
|
Val(Int(1)),
|
||||||
JumpIfTrue(2),
|
Jump(1),
|
||||||
Val(Bool(false)),
|
Val(Int(2)),
|
||||||
JumpIfTrue(2),
|
Noop,
|
||||||
Val(Int(1)),
|
] => P(Int(1)),
|
||||||
Jump(1),
|
vec![
|
||||||
Val(Int(2)),
|
Val(Int(1)),
|
||||||
Noop,
|
Val(Int(1)),
|
||||||
],
|
Equal,
|
||||||
P(Int(1)),
|
JumpIfTrue(2),
|
||||||
),
|
Val(Bool(false)),
|
||||||
(
|
JumpIfTrue(2),
|
||||||
vec![
|
Val(Int(1)),
|
||||||
Val(Int(1)),
|
Jump(1),
|
||||||
Val(Int(1)),
|
Val(Int(2)),
|
||||||
Equal,
|
Noop,
|
||||||
JumpIfTrue(2),
|
] => P(Int(1)),
|
||||||
Val(Bool(false)),
|
vec![
|
||||||
JumpIfTrue(2),
|
Val(Int(1)),
|
||||||
Val(Int(1)),
|
Val(Int(2)),
|
||||||
Jump(1),
|
Equal,
|
||||||
Val(Int(2)),
|
JumpIfFalse(2),
|
||||||
Noop,
|
Val(Bool(false)),
|
||||||
],
|
JumpIfTrue(2),
|
||||||
P(Int(1)),
|
Val(Int(1)),
|
||||||
),
|
Jump(1),
|
||||||
(
|
Val(Int(2)),
|
||||||
vec![
|
Noop,
|
||||||
Val(Int(1)),
|
] => P(Int(1)),
|
||||||
Val(Int(2)),
|
|
||||||
Equal,
|
|
||||||
JumpIfFalse(2),
|
|
||||||
Val(Bool(false)),
|
|
||||||
JumpIfTrue(2),
|
|
||||||
Val(Int(1)),
|
|
||||||
Jump(1),
|
|
||||||
Val(Int(2)),
|
|
||||||
Noop,
|
|
||||||
],
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_function_definition_and_call() {
|
fn test_function_definition_and_call() {
|
||||||
let mut cases = vec![
|
assert_cases![
|
||||||
(
|
vec![
|
||||||
vec![
|
Sym("f".to_owned()), // 0
|
||||||
Sym("f".to_owned()), // 0
|
InitList, // 1
|
||||||
InitList, // 1
|
Sym("arg".to_owned()), // 2
|
||||||
Sym("arg".to_owned()), // 2
|
Element, // 3
|
||||||
Element, // 3
|
Func(6), // 4
|
||||||
Func(6), // 4
|
DeRef("arg".to_owned()), // 5
|
||||||
DeRef("arg".to_owned()), // 5
|
Return, // 6
|
||||||
Return, // 6
|
Bind, // 7
|
||||||
Bind, // 7
|
Val(Int(1)), // 8
|
||||||
Val(Int(1)), // 8
|
DeRef("f".to_owned()), // 9
|
||||||
DeRef("f".to_owned()), // 9
|
FCall, // 10
|
||||||
FCall, // 10
|
] => P(Int(1)),
|
||||||
],
|
vec![
|
||||||
P(Int(1)),
|
Sym("closed".to_owned()), // 0
|
||||||
),
|
Val(Int(1)), // 1
|
||||||
(
|
Bind, // 2
|
||||||
vec![
|
Sym("f".to_owned()), // 3
|
||||||
Sym("closed".to_owned()), // 0
|
InitList, // 4
|
||||||
Val(Int(1)), // 1
|
Sym("arg".to_owned()), // 5
|
||||||
Bind, // 2
|
Element, // 6
|
||||||
Sym("f".to_owned()), // 3
|
Func(11), // 7
|
||||||
InitList, // 4
|
DeRef("arg".to_owned()), // 8
|
||||||
Sym("arg".to_owned()), // 5
|
DeRef("closed".to_owned()), // 9
|
||||||
Element, // 6
|
Add, // 10
|
||||||
Func(11), // 7
|
Return, // 11
|
||||||
DeRef("arg".to_owned()), // 8
|
Bind, // 12
|
||||||
DeRef("closed".to_owned()), // 9
|
Val(Int(1)), // 13
|
||||||
Add, // 10
|
DeRef("f".to_owned()), // 14
|
||||||
Return, // 11
|
FCall, // 16
|
||||||
Bind, // 12
|
] => P(Int(2)),
|
||||||
Val(Int(1)), // 13
|
|
||||||
DeRef("f".to_owned()), // 14
|
|
||||||
FCall, // 16
|
|
||||||
],
|
|
||||||
P(Int(2)),
|
|
||||||
),
|
|
||||||
];
|
];
|
||||||
for case in cases.drain(0..) {
|
|
||||||
let mut vm = VM::new(&case.0);
|
|
||||||
vm.run().unwrap();
|
|
||||||
assert_eq!(vm.pop().unwrap(), case.1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_module_call() {
|
fn test_module_call() {
|
||||||
let mut cases = vec![
|
assert_cases![
|
||||||
(
|
vec![
|
||||||
vec![
|
InitTuple, // 0 // override tuple
|
||||||
InitTuple, // 0 // override tuple
|
Sym("one".to_owned()), // 1
|
||||||
Sym("one".to_owned()), // 1
|
Val(Int(11)), // 2
|
||||||
Val(Int(11)), // 2
|
Field, // 3
|
||||||
Field, // 3
|
Sym("m".to_owned()), // 4 // binding name for module
|
||||||
Sym("m".to_owned()), // 4 // binding name for module
|
InitTuple, // 5 // Module tuple bindings
|
||||||
InitTuple, // 5 // Module tuple bindings
|
Sym("one".to_owned()), // 6
|
||||||
Sym("one".to_owned()), // 6
|
Val(Int(1)), // 7
|
||||||
Val(Int(1)), // 7
|
Field, // 8
|
||||||
Field, // 8
|
Sym("two".to_owned()), // 9
|
||||||
Sym("two".to_owned()), // 9
|
Val(Int(2)), // 10
|
||||||
Val(Int(2)), // 10
|
Field, // 11
|
||||||
Field, // 11
|
Module(17), // 12 // Module definition
|
||||||
Module(17), // 12 // Module definition
|
Bind, // 13
|
||||||
Bind, // 13
|
Sym("foo".to_owned()), // 14
|
||||||
Sym("foo".to_owned()), // 14
|
DeRef("mod".to_owned()), // 15
|
||||||
DeRef("mod".to_owned()), // 15
|
Bind, // 16 // bind mod tuple to foo
|
||||||
Bind, // 16 // bind mod tuple to foo
|
Return, // 17 // end the module
|
||||||
Return, // 17 // end the module
|
Bind, // 18 // bind module to the binding name
|
||||||
Bind, // 18 // bind module to the binding name
|
DeRef("m".to_owned()), // 19
|
||||||
DeRef("m".to_owned()), // 19
|
Cp, // 20
|
||||||
Cp, // 20
|
] => C(Tuple(vec![(
|
||||||
],
|
"foo".to_owned(),
|
||||||
C(Tuple(vec![(
|
C(Tuple(vec![
|
||||||
"foo".to_owned(),
|
("one".to_owned(), P(Int(11))),
|
||||||
C(Tuple(vec![
|
("two".to_owned(), P(Int(2))),
|
||||||
("one".to_owned(), P(Int(11))),
|
])),
|
||||||
("two".to_owned(), P(Int(2))),
|
)])),
|
||||||
])),
|
vec![
|
||||||
)])),
|
InitTuple, // 0 // override tuple
|
||||||
),
|
Sym("one".to_owned()), // 1
|
||||||
(
|
Val(Int(11)), // 2
|
||||||
vec![
|
Field, // 3
|
||||||
InitTuple, // 0 // override tuple
|
Sym("m".to_owned()), // 4 // binding name for module
|
||||||
Sym("one".to_owned()), // 1
|
InitTuple, // 5 // Module tuple bindings
|
||||||
Val(Int(11)), // 2
|
Sym("one".to_owned()), // 6
|
||||||
Field, // 3
|
Val(Int(1)), // 7
|
||||||
Sym("m".to_owned()), // 4 // binding name for module
|
Field, // 8
|
||||||
InitTuple, // 5 // Module tuple bindings
|
Sym("two".to_owned()), // 9
|
||||||
Sym("one".to_owned()), // 6
|
Val(Int(2)), // 10
|
||||||
Val(Int(1)), // 7
|
Field, // 11
|
||||||
Field, // 8
|
InitThunk(2), // 12 // Module Return expression
|
||||||
Sym("two".to_owned()), // 9
|
Val(Int(1)), // 13
|
||||||
Val(Int(2)), // 10
|
Return, // 14
|
||||||
Field, // 11
|
Module(20), // 15 // Module definition
|
||||||
InitThunk(2), // 12 // Module Return expression
|
Bind, // 16
|
||||||
Val(Int(1)), // 13
|
Sym("foo".to_owned()), // 17
|
||||||
Return, // 14
|
DeRef("mod".to_owned()), // 18
|
||||||
Module(20), // 15 // Module definition
|
Bind, // 19 // bind mod tuple to foo
|
||||||
Bind, // 16
|
Return, // 20 // end the module
|
||||||
Sym("foo".to_owned()), // 17
|
Bind, // 21 // bind module to the binding name
|
||||||
DeRef("mod".to_owned()), // 18
|
DeRef("m".to_owned()), // 22
|
||||||
Bind, // 19 // bind mod tuple to foo
|
Cp, // 23
|
||||||
Return, // 20 // end the module
|
] => P(Int(1)),
|
||||||
Bind, // 21 // bind module to the binding name
|
|
||||||
DeRef("m".to_owned()), // 22
|
|
||||||
Cp, // 23
|
|
||||||
],
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user