dellingr 0.3.0

An embeddable, pure-Rust Lua VM with precise instruction-cost accounting
Documentation
use dellingr::{ArgCount, RetCount, State};

fn run_number(code: &str) -> f64 {
    let mut state = State::new();
    state.load_string(code).unwrap();
    state
        .call(ArgCount::Fixed(0), RetCount::Fixed(1))
        .unwrap_or_else(|e| panic!("Error running: {code}\n{e}"));
    state.to_number(-1).unwrap()
}

#[test]
fn templated_constructor_does_not_iterate_nil_fields() {
    let result = run_number(
        r#"
        local t = {a = nil, b = 2, c = 3, d = 4, e = 5}
        local count = 0
        local sum = 0
        local saw_a = 0
        for k, v in pairs(t) do
            count = count + 1
            sum = sum + v
            if k == "a" then
                saw_a = 1
            end
        end
        return count * 100 + sum + saw_a
    "#,
    );
    assert_eq!(result, 414.0);
}

#[test]
fn templated_constructor_handles_nil_before_later_fields() {
    let result = run_number(
        r#"
        local t = {a = 1, b = nil, c = 3, d = 4, e = 5}
        local count = 0
        local sum = 0
        local saw_b = 0
        for k, v in pairs(t) do
            count = count + 1
            sum = sum + v
            if k == "b" then
                saw_b = 1
            end
        end
        return count * 100 + sum + saw_b
    "#,
    );
    assert_eq!(result, 413.0);
}

#[test]
fn duplicate_named_constructor_fields_keep_last_value() {
    let result = run_number(
        r#"
        local t = {a = 1, b = 2, c = 3, d = 4, a = 5}
        return t.a * 1000 + t.b * 100 + t.c * 10 + t.d
    "#,
    );
    assert_eq!(result, 5234.0);
}