use crate::{ Word, lexer::Token }; use super::{ Program, Address, Instruction }; impl Program { pub(crate) fn new(tokens: Vec, absolute_start: usize) -> Program { let mut prog = Program {absolute_start, ..Default::default() }; let mut op_name = String::new(); let mut op_args = Vec::new(); let mut value = Address::None; let mut symbol_def = String::new(); for token in tokens { match token { /* Names (lvalue) */ Token::Operator(name) => { if ! op_name.is_empty() { prog.instructions.push(Instruction { name: op_name, args: op_args.clone(), }); } op_name = name; op_args.clear(); }, Token::Label(name) => { // Predicting the index let index = prog.instructions.len() + !op_name.is_empty() as usize; prog.definitions.insert(name, Address::Instruction(index)); }, Token::SymbolDef(name) => symbol_def = name, /* Values (rvalue) */ Token::Address(num) => { value = Address::Memory(num as usize); }, Token::Number(num) => { prog.constants.push(num); value = Address::Constants(prog.constants.len() - 1); }, Token::String(str) => { let index = prog.constants.len(); for c in str.chars() { prog.constants.push(c as Word); } prog.constants.push(0); // terminating null value = Address::Constants(index); }, Token::Symbol(name) => { value = Address::Definitions(name); }, } if value != Address::None { if ! symbol_def.is_empty() { prog.definitions.insert(symbol_def.clone(), value.take()); symbol_def.clear(); } else { op_args.push(value.take()); } } } if ! op_name.is_empty() { prog.instructions.push(Instruction { name: op_name, args: op_args.clone(), }); } prog } }