iridium/assembler/
program_parsers.rs1use assembler::directive_parsers::directive;
2use assembler::instruction_parsers::{instruction, AssemblerInstruction};
3use assembler::SymbolTable;
4use nom::types::CompleteStr;
5
6#[derive(Debug, PartialEq)]
7pub struct Program {
8 pub instructions: Vec<AssemblerInstruction>,
9}
10
11impl Program {
12 pub fn to_bytes(&self, symbols: &SymbolTable) -> Vec<u8> {
13 let mut program = vec![];
14 for instruction in &self.instructions {
15 program.append(&mut instruction.to_bytes(symbols));
16 }
17 program
18 }
19}
20
21named!(pub program<CompleteStr, Program>,
22 do_parse!(
23 instructions: many1!(alt!(instruction | directive)) >>
24 (
25 Program {
26 instructions
27 }
28 )
29 )
30);
31
32#[cfg(test)]
33mod tests {
34 use super::*;
35 use assembler::Assembler;
36 use vm::VM;
37
38 #[test]
39 fn test_parse_program() {
40 let result = program(CompleteStr("load $0 #100\n"));
41 assert_eq!(result.is_ok(), true);
42 let (leftover, p) = result.unwrap();
43 assert_eq!(leftover, CompleteStr(""));
44 assert_eq!(1, p.instructions.len());
45 }
47
48 #[test]
49 fn test_program_to_bytes() {
50 let result = program(CompleteStr("load $0 #100\n"));
51 assert_eq!(result.is_ok(), true);
52 let (_, program) = result.unwrap();
53 let symbols = SymbolTable::new();
54 let bytecode = program.to_bytes(&symbols);
55 assert_eq!(bytecode.len(), 4);
56 }
57
58 #[test]
59 fn test_complete_program() {
60 let test_program = CompleteStr(".data\nhello: .asciiz 'Hello everyone!'\n.code\nhlt");
61 let result = program(test_program);
62 assert_eq!(result.is_ok(), true);
63 }
64
65 #[test]
66 fn test_parse_load_greater_than_i16() {
67 let mut test_assembler = Assembler::new();
68 let mut test_vm = VM::new();
69 let result = test_assembler.assemble(".data\n.code\nload $0 #-50000");
70 assert!(result.is_ok());
71 let result = result.unwrap();
72 test_vm.program = result;
73 test_vm.run();
74 }
75
76 #[test]
77 fn test_parse_cloop() {
78 let mut test_assembler = Assembler::new();
79 let mut test_vm = VM::new();
80 let result = test_assembler.assemble(".data\n.code\ncloop #10");
81 assert!(result.is_ok());
82 let result = result.unwrap();
83 test_vm.program = result;
84 test_vm.run();
85 }
86}