| 11 | } |
| 12 | |
| 13 | pub fn decode_binary_program_to_instructions( |
| 14 | program: BinaryProgram, |
| 15 | ) -> Result<Vec<BinaryInstruction>, String> { |
| 16 | let mut prophets: HashMap<usize, OlaProphet> = HashMap::new(); |
| 17 | for prophet in program.prophets { |
| 18 | prophets.insert(prophet.host, prophet); |
| 19 | } |
| 20 | |
| 21 | let mut grouped_binary: Vec<Vec<String>> = vec![]; |
| 22 | let mut cached_first_instruction: Vec<String> = vec![]; |
| 23 | |
| 24 | let mut lines = program.bytecode.lines(); |
| 25 | loop { |
| 26 | if let Some(line) = lines.next() { |
| 27 | if !cached_first_instruction.is_empty() { |
| 28 | cached_first_instruction.push(line.to_string()); |
| 29 | grouped_binary.push(cached_first_instruction.clone()); |
| 30 | cached_first_instruction.clear(); |
| 31 | } else { |
| 32 | let length = get_instruction_length(line.to_string())?; |
| 33 | if length == 1 { |
| 34 | grouped_binary.push(vec![line.to_string()]); |
| 35 | } else { |
| 36 | cached_first_instruction.push(line.to_string()); |
| 37 | } |
| 38 | } |
| 39 | } else { |
| 40 | break; |
| 41 | } |
| 42 | } |
| 43 | |
| 44 | let mut instructions: Vec<BinaryInstruction> = vec![]; |
| 45 | let mut host: usize = 0; |
| 46 | for binary_code in grouped_binary { |
| 47 | let prophet = prophets.get(&host).cloned(); |
| 48 | let instruction = BinaryInstruction::decode(binary_code, prophet)?; |
| 49 | let instruction_len = instruction.binary_length(); |
| 50 | instructions.push(instruction); |
| 51 | host += instruction_len as usize; |
| 52 | } |
| 53 | Ok(instructions) |
| 54 | } |
| 55 | |
| 56 | fn get_instruction_length(instruction: String) -> Result<u8, String> { |
| 57 | let instruction_without_prefix = instruction.trim_start_matches("0x"); |