use crate::{ VM, Linker, Assembler }; #[test] fn test_vm() { let mut vm = VM::new(0x1000); let mut linker = Linker::new(); linker.add_procedure("@", crate::Assembler::new() .inst( crate::VM_Instruction::Fetch ) .build()); linker.add_procedure("!", crate::Assembler::new() .inst( crate::VM_Instruction::Store ) .build()); linker.add_procedure("int-add", crate::Assembler::new() .inst( crate::VM_Instruction::IntAdd ) .build()); linker.add_procedure("int-sub", crate::Assembler::new() .inst( crate::VM_Instruction::BitNeg ) .lit(1) .inst( crate::VM_Instruction::IntAdd ) .inst( crate::VM_Instruction::IntAdd ) .build()); // declare variable 'x' at address 0x86 linker.add_procedure("x", crate::Assembler::new() .lit(0x86) .build()); /* * compile & run the following program: * * x = 100 + 23; * if( x != 123 ) { * emit('*'); * 333 * } else { * emit('+'); * 666 * } */ linker.add_procedure("main", crate::Assembler::new() // x = 123 .lit(100).lit(23).call("int-add") .call("x").call("!") // if ( 123 - x ) { emit '*' } else { emit '+' } .lit(123) .call("x").call("@") .call("int-sub") .branch( crate::Assembler::new() .lit(42).inst(crate::VM_Instruction::Emit) .lit(111), crate::Assembler::new() .lit(43).inst(crate::VM_Instruction::Emit) .lit(222)) .build()); let main_addr = linker.get_link_addr(&"main".into()).expect("main not foudn"); let bytecode = linker.link_total().expect("link error"); vm.load( bytecode ); vm.execute( main_addr ); assert_eq!( vm.data_stack, vec![ 222 ] ); println!("\nvm.datastack = {:?}", vm.data_stack); }