rual-core 0.0.4

A slim, embeddable language
Documentation
use super::*;

fn exec(instrs: &[Instruction]) -> VM {
    let mut vm = VM::new();
    vm.execute(&instrs);
    vm
}

#[test]
fn simple_numeric_declaration() {
    let instrs = vec![
        Instruction::Push(RlValue::Num(7)),
        Instruction::Push(RlValue::Num(9)),
        Instruction::Push(RlValue::Num(3)),
        Instruction::Mul,
        Instruction::Sub,
        Instruction::Declare("num".into()),
    ];

    let vm = exec(&instrs);

    assert_eq!(-20, vm.lookup_num("num").unwrap());
}

#[test]
fn string_declaration() {
    let instrs = vec![
        Instruction::Push(RlValue::Str("some string".into())),
        Instruction::Declare("s".into()),
    ];

    let vm = exec(&instrs);

    assert_eq!(String::from("some string"), vm.lookup_str("s").unwrap());
}

#[test]
fn range_declaration() {
    let instrs = vec![
        Instruction::Push(RlValue::Num(5)),
        Instruction::Push(RlValue::Num(11)),
        Instruction::Push(RlValue::Num(9)),
        Instruction::Mul,
        Instruction::MakeRange,
        Instruction::Declare("xs".into()),
    ];

    let vm = exec(&instrs);

    assert_eq!(
        (5..=99).collect::<Vec<i32>>(),
        vm.lookup_list("xs").unwrap()
    );
}

#[test]
fn parameterless_function_declaration_and_invocation() {
    let instrs = vec![
        // N.B. see the test of the same name in the compilation mod for info
        Instruction::Push(RlValue::Function(3, 0)),
        Instruction::Push(RlValue::Addr(7)),
        Instruction::Jump,
        Instruction::Push(RlValue::Num(1)),
        Instruction::Push(RlValue::Num(4)),
        Instruction::Add,
        Instruction::Ret,
        Instruction::Declare("five".into()),
        Instruction::Call("five".into()),
        Instruction::Declare("x".into()),
    ];

    let vm = exec(&instrs);

    assert_eq!(5, vm.lookup_num("x").unwrap());
}

#[test]
fn function_declaration_and_invocation() {
    let instrs = vec![
        Instruction::Push(RlValue::Function(3, 3)),
        Instruction::Push(RlValue::Addr(14)),
        Instruction::Jump,
        Instruction::Declare("z".into()),
        Instruction::Declare("y".into()),
        Instruction::Declare("x".into()),
        Instruction::PushLocal("x".into()),
        Instruction::PushLocal("z".into()),
        Instruction::Add,
        Instruction::Declare("mid_way".into()),
        Instruction::PushLocal("mid_way".into()),
        Instruction::PushLocal("y".into()),
        Instruction::Add,
        Instruction::Ret,
        Instruction::Declare("sum".into()),
        Instruction::Push(RlValue::Num(9)),
        Instruction::Push(RlValue::Num(8)),
        Instruction::Mul,
        Instruction::Push(RlValue::Num(8)),
        Instruction::Push(RlValue::Num(2)),
        Instruction::Sub,
        Instruction::Push(RlValue::Num(15)),
        Instruction::Mul,
        Instruction::Push(RlValue::Num(4)),
        Instruction::Push(RlValue::Num(1)),
        Instruction::Push(RlValue::Num(3)),
        Instruction::Mul,
        Instruction::Sub,
        Instruction::Call("sum".into()),
        Instruction::Declare("res".into()),
    ];

    let vm = exec(&instrs);

    assert_eq!(163, vm.lookup_num("res").unwrap());
}