#![cfg(all(feature = "compile", feature = "verify"))]
extern crate alloc;
use keleusma::Arena;
use keleusma::bytecode::{EnumBody, StructBody, TupleBody, Value};
use keleusma::compiler::compile;
use keleusma::lexer::tokenize;
use keleusma::parser::parse;
use keleusma::vm::{DEFAULT_ARENA_CAPACITY, Vm, VmState};
fn run(src: &str) -> (Value, Arena) {
let m = compile(&parse(&tokenize(src).expect("lex")).expect("parse")).expect("compile");
let arena = Arena::with_capacity(DEFAULT_ARENA_CAPACITY);
let v = {
let mut vm = Vm::new(m, &arena).expect("verify");
match vm.call(&[]).expect("call") {
VmState::Finished(v) => v,
other => panic!("expected finished, got {:?}", other),
}
};
(v, arena)
}
fn run_word(src: &str) -> i64 {
let (v, _arena) = run(src);
match v {
Value::Int(n) => n,
other => panic!("expected Int, got {:?}", other),
}
}
#[test]
fn nested_struct_in_struct_constructs_flat_in_arena() {
let src = "struct Inner { a: Word, b: Word }\n\
struct Outer { inner: Inner, c: Word }\n\
fn main() -> Outer { Outer { inner: Inner { a: 1, b: 2 }, c: 3 } }";
let (v, arena) = run(src);
match &v {
Value::Struct(StructBody::Flat(fc)) => {
assert!(
fc.is_valid(&arena),
"outer struct body must be arena-resident and valid"
);
}
other => panic!("expected flat struct body, got {:?}", other),
}
}
#[test]
fn nested_struct_in_struct_fields_round_trip() {
let src = "struct Inner { a: Word, b: Word }\n\
struct Outer { inner: Inner, c: Word }\n\
fn main() -> Word { \
let o = Outer { inner: Inner { a: 10, b: 20 }, c: 30 }; \
o.inner.a + o.inner.b + o.c }";
assert_eq!(run_word(src), 60);
}
#[test]
fn struct_in_tuple_round_trips() {
let src = "struct P { x: Word, y: Word }\n\
fn main() -> Word { \
let t = (P { x: 4, y: 5 }, 6); \
t.0.x + t.0.y + t.1 }";
assert_eq!(run_word(src), 15);
}
#[test]
fn array_of_structs_round_trips() {
let src = "struct P { x: Word, y: Word }\n\
fn main() -> Word { \
let a = [P { x: 1, y: 2 }, P { x: 3, y: 4 }]; \
a[0].x + a[0].y + a[1].x + a[1].y }";
assert_eq!(run_word(src), 10);
}
#[test]
fn deeply_nested_tuple_round_trips() {
let src = "fn main() -> Word { \
let t = (((1, 2), 3), 4); \
let a = t.0; \
let b = a.0; \
b.0 + b.1 + a.1 + t.1 }";
assert_eq!(run_word(src), 10);
}
#[test]
fn enum_with_nested_struct_payload_is_flat() {
let src = "struct P { x: Word, y: Word }\n\
enum E { Empty, Pair(P) }\n\
fn main() -> E { E::Pair(P { x: 7, y: 8 }) }";
let (v, arena) = run(src);
match &v {
Value::Enum(EnumBody::Flat(fc)) => {
assert!(fc.is_valid(&arena), "enum body must be arena-resident");
}
other => panic!("expected flat enum body, got {:?}", other),
}
}
#[test]
fn scalar_tuple_constructs_flat() {
let src = "fn main() -> (Word, Word, Word) { (1, 2, 3) }";
let (v, arena) = run(src);
match &v {
Value::Tuple(TupleBody::Flat(fc)) => {
assert!(fc.is_valid(&arena), "tuple body must be arena-resident");
}
other => panic!("expected flat tuple body, got {:?}", other),
}
}