fn phase_one(&mut self, program: &Program) -> Result<()> {
        self.current_phase = AssemblerPhase::First;

        let mut current_label_offset = 0;

        for instruction in program.instructions.iter() {
            if let Some(name) = instruction.label_name() {
                // We have a label
                ensure!(
                    self.current_section.is_some(),
                    LabelOutsideOfSectionSnafu {
                        label: name.clone()
                    }
                );
                ensure!(
                    !self.symbols.has_symbol(name),
                    SymbolAlreadyDefinedSnafu { name: name.clone() }
                );
                let symbol =
                    Symbol::new(String::from(name), SymbolType::Label, current_label_offset);
                self.symbols.add(symbol);
            }

            if let Some(name) = instruction.directive.as_ref() {
                // We have a directive.
                if instruction.has_operands() {
                    // Match which directive it is.
                    match name.as_ref() {
                        "asciiz" => {
                            // Null-terminated ascii string.
                            self.process_asciiz_directive(instruction)?;
                        }
                        "word" => {
                            self.process_word_directive(instruction)?;
                        }
                        _ => {
                            return Err(AssemblerError::UnknownDirective { name: name.clone() });
                        }
                    }
                } else {
                    // No operands => section header.
                    self.process_section_header(name)?;
                }
            }

            if let Some(op) = instruction.opcode.as_ref() {
                current_label_offset += op.width();
            }
        }
        Ok(())
    }
/// Phase one is the assembler pre-processing routine.
///
/// It is mainly tasked with extracting labels and directives.
Phase one is the assembler pre-processing routine.
It is mainly tasked with extracting labels and directives.
Phase one is the assembler pre - processing routine . It is mainly tasked with extracting labels and directives .
fn phase_one(&mut self, program: &Program) -> Result<()> {
        self.current_phase = AssemblerPhase::First;
        let mut current_label_offset = 0;
        for instruction in program.instructions.iter() {
            if let Some(name) = instruction.label_name() {
                // We have a label
                ensure!(
                    self.current_section.is_some(),
                    LabelOutsideOfSectionSnafu {
                        label: name.clone()
                    }
                );
                ensure!(
                    !self.symbols.has_symbol(name),
                    SymbolAlreadyDefinedSnafu { name: name.clone() }
                );
                let symbol =
                    Symbol::new(String::from(name), SymbolType::Label, current_label_offset);
                self.symbols.add(symbol);
            }
            if let Some(name) = instruction.directive.as_ref() {
                // We have a directive.
                if instruction.has_operands() {
                    // Match which directive it is.
                    match name.as_ref() {
                        "asciiz" => {
                            // Null-terminated ascii string.
                            self.process_asciiz_directive(instruction)?;
                        }
                        "word" => {
                            self.process_word_directive(instruction)?;
                        }
                        _ => {
                            return Err(AssemblerError::UnknownDirective { name: name.clone() });
                        }
                    }
                } else {
                    // No operands => section header.
                    self.process_section_header(name)?;
                }
            }
            if let Some(op) = instruction.opcode.as_ref() {
                current_label_offset += op.width();
            }
        }
        Ok(())
    }
fn phase_one ( & mut self , program : & Program ) -> Result < ( ) > { self . current_phase = AssemblerPhase :: First ; let mut current_label_offset = 0 ; for instruction in program . instructions . iter ( ) { if let Some ( name ) = instruction . label_name ( ) { // We have a label ensure ! ( self current_section is_some ( ) LabelOutsideOfSectionSnafu { label name clone ( ) } ) ; ensure ! ( self symbols has_symbol ( name ) SymbolAlreadyDefinedSnafu { name name clone ( ) } ) ; let symbol = Symbol :: new ( String :: from ( name ) , SymbolType :: Label , current_label_offset ) ; self . symbols . add ( symbol ) ; } if let Some ( name ) = instruction . directive . as_ref ( ) { // We have a directive. if instruction . has_operands ( ) { // Match which directive it is. match name . as_ref ( ) { " " => { // Null-terminated ascii string. self . process_asciiz_directive ( instruction ) ? ; } " " => { self . process_word_directive ( instruction ) ? ; } _ => { return Err ( AssemblerError :: UnknownDirective { name : name . clone ( ) } ) ; } } } else { // No operands => section header. self . process_section_header ( name ) ? ; } } if let Some ( op ) = instruction . opcode . as_ref ( ) { current_label_offset += op . width ( ) ; } } Ok ( ( ) ) }
Phase one is the assembler pre-processing routine.
Phase one is the assembler pre - processing routine .
&mut self
program
&Program
&mut self
program
&Program