use crate::{ VM, Linker, Assembler }; #[test] fn test_vm() { let mut vm = VM::new(0x1000); let mut linker = Linker::new(0x100); linker.link(&mut vm, "@".into(), crate::Assembler::new() .instruction( crate::VM_Instruction::Fetch ) .build()); linker.link(&mut vm, "!".into(), crate::Assembler::new() .instruction( crate::VM_Instruction::Store ) .build()); linker.link(&mut vm, "addi".into(), crate::Assembler::new() .instruction( crate::VM_Instruction::Add ) .build()); linker.link(&mut vm, "subi".into(), crate::Assembler::new() .instruction( crate::VM_Instruction::BitwiseNot ) .lit(1) .instruction( crate::VM_Instruction::Add ) .instruction( crate::VM_Instruction::Add ) .build()); // declare variable 'x' at address 0x86 linker.link(&mut vm, "x".into(), crate::Assembler::new() .lit(0x86) .build()); /* * compile & run the following program: * * x = 100 + 23; * if( x != 123 ) { * emit('*'); * 333 * } else { * emit('+'); * 666 * } */ linker.link(&mut vm, "main".into(), crate::Assembler::new() // x = 123 .lit(100) .lit(23) .call( linker.resolve_symbol(&"addi".into()).expect("unknown symbol 'addi'") ) .call( linker.resolve_symbol(&"x".into()).expect("unknown symbol 'x'") ) .call( linker.resolve_symbol(&"!".into()).expect("unknown symbol '!'") ) // 200 - x .lit(123) .call( linker.resolve_symbol(&"x".into()).expect("unknown symbol 'x'") ) .call( linker.resolve_symbol(&"@".into()).expect("unknown symbol '@'") ) .call( linker.resolve_symbol(&"subi".into()).expect("unknown symbol 'subi'") ) .branch( crate::Assembler::new() .lit(42).instruction(crate::VM_Instruction::Emit) .lit(111), crate::Assembler::new() .lit(43).instruction(crate::VM_Instruction::Emit) .lit(222) ) .build()); vm.execute( linker.resolve_symbol(&"main".into()).expect("unknown symbol 'main'") ); assert_eq!( vm.data_stack, vec![ 222 ] ); println!("\nvm.datastack = {:?}", vm.data_stack); }