plotnik-compiler 0.3.2

Compiler for Plotnik query language (parser, analyzer, bytecode emitter)
Documentation
use super::capture::CaptureEffects;
use crate::bytecode::{EffectIR, MemberRef};
use plotnik_bytecode::EffectOpcode;

#[test]
fn nest_scope_preserves_outer_and_nests_inner() {
    let outer = CaptureEffects::new(vec![EffectIR::start_obj()], vec![EffectIR::end_obj()]);

    let result = outer.nest_scope(EffectIR::start_enum(), EffectIR::end_enum());

    assert_eq!(result.pre.len(), 2);
    assert_eq!(result.pre[0].opcode, EffectOpcode::Obj);
    assert_eq!(result.pre[1].opcode, EffectOpcode::Enum);

    assert_eq!(result.post.len(), 2);
    assert_eq!(result.post[0].opcode, EffectOpcode::EndEnum);
    assert_eq!(result.post[1].opcode, EffectOpcode::EndObj);
}

#[test]
fn with_pre_values_appends_after_scope_opens() {
    let outer = CaptureEffects::new_pre(vec![EffectIR::start_obj()]);

    let result = outer.with_pre_values(vec![
        EffectIR::null(),
        EffectIR::with_member(EffectOpcode::Set, MemberRef::absolute(0)),
    ]);

    assert_eq!(result.pre.len(), 3);
    assert_eq!(result.pre[0].opcode, EffectOpcode::Obj);
    assert_eq!(result.pre[1].opcode, EffectOpcode::Null);
    assert_eq!(result.pre[2].opcode, EffectOpcode::Set);
}

#[test]
fn with_post_values_prepends_before_scope_closes() {
    let outer = CaptureEffects::new_post(vec![EffectIR::end_obj()]);

    let result = outer.with_post_values(vec![
        EffectIR::node(),
        EffectIR::with_member(EffectOpcode::Set, MemberRef::absolute(0)),
    ]);

    assert_eq!(result.post.len(), 3);
    assert_eq!(result.post[0].opcode, EffectOpcode::Node);
    assert_eq!(result.post[1].opcode, EffectOpcode::Set);
    assert_eq!(result.post[2].opcode, EffectOpcode::EndObj);
}

#[test]
#[should_panic(expected = "nest_scope expects scope-opening effect")]
fn nest_scope_rejects_non_scope_open() {
    let outer = CaptureEffects::default();
    outer.nest_scope(EffectIR::node(), EffectIR::end_obj());
}

#[test]
#[should_panic(expected = "nest_scope expects scope-closing effect")]
fn nest_scope_rejects_non_scope_close() {
    let outer = CaptureEffects::default();
    outer.nest_scope(EffectIR::start_obj(), EffectIR::node());
}