def ExpandMacro(): global Asm, Flags while len(dec.Asm.Macro_Stack) > 0: stackindex = len(dec.Asm.Macro_Stack) - 1 macroname = dec.Asm.Macro_Stack[stackindex][0] macroline = dec.Asm.Macro_Stack[stackindex][1] parameters = dec.Asm.Macro_Stack[stackindex][3] if macroline < len(dec.Asm.Macro[macroname]): # This macro still has at least one line left to be parsed dec.Asm.Parse_Line = dec.Asm.Macro[macroname][macroline] macroline = macroline + 1 dec.Asm.Macro_Stack[stackindex][1] = macroline ExpandParameters(parameters) assem.ParseLine() listing.ListLine(macroline, dec.Asm.Parse_Line) if dec.Flags.EndFile: # .EN directive was encountered, close all macro expansions # and the most recent source file dec.Asm.Macro_Stack = [] dec.Asm.Local_Index = 0 # leave flag True, has to break out of while in assem.Assemble if dec.Flags.ExitMacro: # .XM directive wants to exit this macro dec.Flags.ExitMacro = False dec.Asm.Local_Index = dec.Asm.Macro_Stack[stackindex][2] dec.Asm.Macro_Stack.pop() else: # End of this macro, pull it off the stack dec.Asm.Local_Index = dec.Asm.Macro_Stack[stackindex][2] dec.Asm.Macro_Stack.pop()
def Assemble(sourcename): """ Entry point for both assembly passes. Initialize symbol table, open main source file and parse each program line. """ global Asm, Flags Prepare_For_Pass() print("") if dec.Asm.Pass == 1: print("Pass one") else: print("Pass two") files.OpenSourceFile(sourcename) # Open main source file dec.Flags.CodeWarn = False while len(dec.Asm.File_Handle) > 0: # Do this until all source files are closed again dec.Flags.Comment = False dec.Asm.Macro_Def = '' while True: # Parse each line until end of file if len(dec.Asm.Macro_Stack) > 0: # Expanding macros, stay there until done macros.ExpandMacro() if dec.Flags.EndFile: # Macro expansion found .EN directive dec.Flags.EndFile = False break # Normal assembly, get next line from source and parse it index = len(dec.Asm.File_Handle) - 1 dec.Asm.Parse_Line = dec.Asm.File_Handle[index].readline() dec.Asm.File_LineNo[index] = dec.Asm.File_LineNo[index] + 1 lastline = dec.Asm.File_LineNo[index] # Save this, may change by .CH lineno = dec.Asm.File_LineNo[index] if len(dec.Asm.Parse_Line) > 0: # Not end of file # Now expand tabs, get rid of eol, truncate the line to a # sensible length and append trailing space. # This trailing space will ease parsing the string. # Windows tends to crash when the line length > 184 dec.Asm.Parse_Line = \ dec.Asm.Parse_Line.expandtabs(8).rstrip() + " " ParseLine() # Parse this source line listing.ListLine(lineno, dec.Asm.Parse_Line) if dec.Flags.EndFile: # .EN directive was encountered, close this file dec.Flags.EndFile = False break else: # End of file reached break # Close youngest source file in source stack dec.Asm.File_Handle[len(dec.Asm.File_Handle) - 1].close() dec.Asm.File_Handle.pop() dec.Asm.File_LineNo.pop() dec.Asm.File_Name.pop() # We may need this in case of errors during cleanup dec.Asm.File_Name.append(sourcename) dec.Asm.File_LineNo.append(lastline) if dec.Cross.Name != "": # Allow the cross overlay to do some final house keeping dec.Cross.CleanUp() target.CloseTarget(0) # Close code memory buffer target.CloseTarget(2) # Close EEPROM memory buffer dec.Asm.File_Name = [] # We won't need this anymore now dec.Asm.File_LineNo = [] files.SymbolFile() files.CloseAllFiles()