#![cfg(feature = "wasm")]
use metadol::parse_file;
use metadol::wasm::layout::{FieldLayout, GeneLayout, WasmFieldType};
use metadol::wasm::{WasmCompiler, WasmRuntime};
#[test]
fn debug_control_flow_wasm() {
let source = r#"
fun max(a: i64, b: i64) -> i64 {
if a > b {
return a
}
return b
}
exegesis { Returns the maximum of two integers. }
"#;
let module = parse_file(source).expect("Failed to parse");
println!("Parsed AST:\n{:#?}", module);
let mut compiler = WasmCompiler::new();
let wasm_bytes = compiler.compile(&module).expect("Compilation failed");
println!("\nWASM size: {} bytes", wasm_bytes.len());
println!("WASM hex dump:");
for (i, byte) in wasm_bytes.iter().enumerate() {
print!("{:02x} ", byte);
if (i + 1) % 16 == 0 {
println!();
}
}
println!();
let runtime = WasmRuntime::new().expect("Failed to create runtime");
match runtime.load(&wasm_bytes) {
Ok(_) => println!("WasmRuntime load: SUCCESS"),
Err(e) => println!("WasmRuntime load FAILED: {:?}", e),
}
}
#[test]
fn debug_match_wasm() {
let source = r#"
fun classify(x: i64) -> i64 {
match x {
0 => 100,
1 => 200,
_ => 300,
}
}
exegesis { Classifies an integer. }
"#;
let module = parse_file(source).expect("Failed to parse");
println!("Match AST:\n{:#?}", module);
let mut compiler = WasmCompiler::new();
let wasm_bytes = compiler.compile(&module).expect("Compilation failed");
println!("\nMatch WASM size: {} bytes", wasm_bytes.len());
println!("WASM hex dump:");
for (i, byte) in wasm_bytes.iter().enumerate() {
print!("{:02x} ", byte);
if (i + 1) % 16 == 0 {
println!();
}
}
println!();
let runtime = WasmRuntime::new().expect("Failed to create runtime");
match runtime.load(&wasm_bytes) {
Ok(_) => println!("WasmRuntime load: SUCCESS"),
Err(e) => println!("WasmRuntime load FAILED: {:?}", e),
}
}
#[test]
fn test_member_access() {
let source = r#"
fun get_x() -> i64 {
let p = Point { x: 42, y: 10 }
return p.x
}
exegesis { Gets the x coordinate. }
"#;
let module = parse_file(source).expect("Failed to parse");
println!("Parsed AST:\n{:#?}", module);
let point_layout = GeneLayout {
name: "Point".to_string(),
fields: vec![
FieldLayout::primitive("x", 0, WasmFieldType::I64),
FieldLayout::primitive("y", 8, WasmFieldType::I64),
],
total_size: 16,
alignment: 8,
};
let mut compiler = WasmCompiler::new();
compiler.register_gene_layout(point_layout);
let wasm_bytes = compiler.compile(&module).expect("Compilation failed");
println!("Member access WASM size: {} bytes", wasm_bytes.len());
let runtime = WasmRuntime::new().expect("Failed to create runtime");
let mut wasm_module = runtime.load(&wasm_bytes).expect("Failed to load module");
let result = wasm_module.call("get_x", &[]).expect("Call failed");
println!("get_x() returned: {:?}", result);
assert_eq!(result.first().and_then(|v| v.i64()), Some(42));
}
#[test]
fn test_function_call() {
let source = r#"
fun double(x: i64) -> i64 {
return x * 2
}
exegesis { Doubles a number. }
"#;
let module = parse_file(source).expect("Failed to parse");
let mut compiler = WasmCompiler::new();
let wasm_bytes = compiler.compile(&module).expect("Compilation failed");
println!("Function call WASM size: {} bytes", wasm_bytes.len());
let runtime = WasmRuntime::new().expect("Failed to create runtime");
let mut wasm_module = runtime.load(&wasm_bytes).expect("Failed to load module");
let result = wasm_module
.call("double", &[21i64.into()])
.expect("Call failed");
println!("double(21) returned: {:?}", result);
assert_eq!(result.first().and_then(|v| v.i64()), Some(42));
}
#[test]
fn debug_enum_type_mapping() {
use metadol::parse_file;
use metadol::wasm::WasmCompiler;
let source = r#"
fun compare_account_type(a: AccountType, b: AccountType) -> i32 {
if a == b {
return 1
}
return 0
}
exegesis { Compare two account types. }
"#;
let module = parse_file(source).expect("Failed to parse");
println!("Parsed function:");
println!("{:#?}", module);
let mut compiler = WasmCompiler::new();
compiler.register_enum(
"AccountType",
vec![
"Node".to_string(),
"RevivalPool".to_string(),
"Treasury".to_string(),
],
);
match compiler.compile(&module) {
Ok(wasm_bytes) => {
println!("\nCompiled {} bytes", wasm_bytes.len());
println!("WASM hex dump (all bytes):");
for (i, byte) in wasm_bytes.iter().enumerate() {
print!("{:02x} ", byte);
if (i + 1) % 16 == 0 {
println!();
}
}
println!();
std::fs::write("/tmp/enum_test.wasm", &wasm_bytes).ok();
let runtime = WasmRuntime::new().expect("Failed to create runtime");
match runtime.load(&wasm_bytes) {
Ok(_) => println!("WasmRuntime load: SUCCESS"),
Err(e) => {
println!("WasmRuntime load FAILED: {:?}", e);
println!("Full error: {:#?}", e);
}
}
}
Err(e) => {
println!("Compilation error: {:?}", e);
}
}
}
#[test]
fn debug_gene_inheritance_wasm() {
use metadol::wasm::WasmCompiler;
use metadol::Parser;
let source = r#"
module inheritance_test @ 0.1.0
gene Animal {
has age: i64
fun get_age() -> i64 {
return age
}
}
gene Dog extends Animal {
has breed_id: i64
fun bark_count() -> i64 {
return age * 2
}
}
"#;
let mut parser = Parser::new(source);
let dol_file = parser.parse_file().expect("Failed to parse");
println!("Parsed file successfully");
println!(
"Module path: {:?}",
dol_file.module.as_ref().map(|m| &m.path)
);
println!("Declarations: {}", dol_file.declarations.len());
for (i, decl) in dol_file.declarations.iter().enumerate() {
match decl {
metadol::Declaration::Gene(gene) => {
println!(" [{}] Gene: {} extends {:?}", i, gene.name, gene.extends);
}
_ => println!(" [{}] Other declaration", i),
}
}
let mut compiler = WasmCompiler::new();
match compiler.compile_file(&dol_file) {
Ok(wasm_bytes) => {
println!("\nCompiled {} bytes", wasm_bytes.len());
println!("WASM hex dump (first 128 bytes):");
for (i, byte) in wasm_bytes.iter().take(128).enumerate() {
print!("{:02x} ", byte);
if (i + 1) % 16 == 0 {
println!();
}
}
println!();
let runtime = WasmRuntime::new().expect("Failed to create runtime");
match runtime.load(&wasm_bytes) {
Ok(_) => println!("WasmRuntime load: SUCCESS"),
Err(e) => println!("WasmRuntime load FAILED: {:?}", e),
}
}
Err(e) => {
println!("Compilation error: {:?}", e);
}
}
}