assembler.py
def linkPasses(self):
        """
        Link passes, tries to find empty links and assign them
        """
        asmDelList = []
        while self.markedLines:
            pass_tainted = False
            watchdog_markedLength = len(self.markedLines)
            delList = []
            for lineNumber in self.markedLines.keys():
                currentProgress = self.linePos[lineNumber]
                line = self.cleanLine(self.assembly[lineNumber])
                markLine = 0
                
                # Label assignment
                if line[0][-1] == ":":
                    labelName = line[0][:-1]
                    if self.labels.get(labelName,None) != None:
                        print(ERRORS[6].format(lineNumber,labelName))
                    else:
                        self.labels[labelName] = currentProgress
                    asmDelList.append(lineNumber)
                
                # Constant assignment
                elif line[0] == '.const':
                    if self.constants.get(line[1],None) != None:
                        print(ERRORS[7].format(lineNumber,line[1]))
                    elif re.search('[\-]*\d+',line[2]):
                        self.constants[line[1]] = numexpr.evaluate(line[2]).item()
                    else:
                        markLine = True
                    asmDelList.append(lineNumber)
                
                # Replace constants, absolute labels, and mark empty links
                linkList = set(re.findall('[!]*<link_[a-z]{1}[\w_]*/>',self.assembly[lineNumber]))
                for linkName in linkList:
                    absoluteLabel = linkName.startswith('!')
                    if linkName in self.constants:
                        self.assembly[lineNumber] = re.sub(
                            '(?<![\w_])%s(?![\w_])' % linkName, str(self.constants[linkName]),
                            self.assembly[lineNumber])
                    elif linkName[absoluteLabel:] in self.labels:
                        # Absolute labels, always assignable
                        if absoluteLabel:
                            self.assembly[lineNumber] = re.sub(
                                '(?<![\w_])%s(?![\w_])' % linkName,
                                str(self.labels[linkName[1:]]),
                                self.assembly[lineNumber])
                    else:
                        markLine = True
                
                newLine = [line[0]]
                
                # Find links and replace them with zero
                for operand in line[1:]:
                    if re.search('[<>/~%^&*()-+]',operand):
                        newLine.append(str(numexpr.evaluate(re.sub('[!]*<link_[a-z]{1}[\w_]*/>','0',operand)).item()))
                    else:
                        newLine.append(operand)
                
                # Categorize operands for easy identification
                categorizedLine = self.categorizeOperands(newLine)
                
                # Find untainted Links and replace them
                linkList = set(re.findall('[!]*<link_[a-z]{1}[\w_]*/>',self.assembly[lineNumber]))
                for linkName in linkList:
                    absoluteLabel = linkName.startswith('!')
                    if linkName[absoluteLabel:] in self.labels:
                        # N/PC-relative labels
                        # Check whether it's an instruction we're making a
                        # relative label for and if architecture uses NPC
                        instruction = self.instructions.get(
                            categorizedLine, None)
                        instLength = 0
                        # It is an instruction and NPC, calculate length
                        if instruction and self.jump_npc:
                            instLength = self.formats[instruction[0]][0]//8
                        self.assembly[lineNumber] = re.sub(
                            '(?<![\w_])%s(?![\w_])' % linkName,
                            str(self.labels[linkName]
                            -(currentProgress+instLength)),
                            self.assembly[lineNumber])
                
                line = self.cleanLine(self.assembly[lineNumber])
                
                # Find unmarked operands and attempt to evaluate them
                if not markLine and lineNumber not in delList:
                    for operand in line[1:]:
                        if re.search('[<>/~%^&*()-+]',operand):
                            self.assembly[lineNumber] = re.sub(
                                '(?<![\w<>?/~!%%^&*()\-+])%s(?![\w<>?/~!%%^&*()\-+])' % re.escape(operand),
                                str(numexpr.evaluate(operand).item()),self.assembly[lineNumber])
                
                # Store line for further pass(es)
                if markLine:
                    pass_tainted = True
                    self.markedLines[lineNumber] = self.assembly[lineNumber]
                else:
                    delList.append(lineNumber)
            
            for lineNumber in set(delList):
                del self.markedLines[lineNumber]
            
            if watchdog_markedLength == len(self.markedLines):
                print(ERROR_FATAL[1])
                for lineNumber in self.markedLines.keys():
                    print(self.markedLines[lineNumber])
                print(self.labels)
                quit(101)
        
        for lineNumber in set(asmDelList):
            del self.assembly[lineNumber]

        Link passes, tries to find empty links and assign them
        
Link passes, tries to find empty links and assign them
Link passes tries to find empty links and assign them
def linkPasses(self):
        asmDelList = []
        while self.markedLines:
            pass_tainted = False
            watchdog_markedLength = len(self.markedLines)
            delList = []
            for lineNumber in self.markedLines.keys():
                currentProgress = self.linePos[lineNumber]
                line = self.cleanLine(self.assembly[lineNumber])
                markLine = 0
                if line[0][-1] == ":":
                    labelName = line[0][:-1]
                    if self.labels.get(labelName,None) != None:
                        print(ERRORS[6].format(lineNumber,labelName))
                    else:
                        self.labels[labelName] = currentProgress
                    asmDelList.append(lineNumber)
                elif line[0] == '.const':
                    if self.constants.get(line[1],None) != None:
                        print(ERRORS[7].format(lineNumber,line[1]))
                    elif re.search('[\-]*\d+',line[2]):
                        self.constants[line[1]] = numexpr.evaluate(line[2]).item()
                    else:
                        markLine = True
                    asmDelList.append(lineNumber)
                linkList = set(re.findall('[!]*<link_[a-z]{1}[\w_]*/>',self.assembly[lineNumber]))
                for linkName in linkList:
                    absoluteLabel = linkName.startswith('!')
                    if linkName in self.constants:
                        self.assembly[lineNumber] = re.sub(
                            '(?<![\w_])%s(?![\w_])' % linkName, str(self.constants[linkName]),
                            self.assembly[lineNumber])
                    elif linkName[absoluteLabel:] in self.labels:
                        if absoluteLabel:
                            self.assembly[lineNumber] = re.sub(
                                '(?<![\w_])%s(?![\w_])' % linkName,
                                str(self.labels[linkName[1:]]),
                                self.assembly[lineNumber])
                    else:
                        markLine = True
                newLine = [line[0]]
                for operand in line[1:]:
                    if re.search('[<>/~%^&*()-+]',operand):
                        newLine.append(str(numexpr.evaluate(re.sub('[!]*<link_[a-z]{1}[\w_]*/>','0',operand)).item()))
                    else:
                        newLine.append(operand)
                categorizedLine = self.categorizeOperands(newLine)
                linkList = set(re.findall('[!]*<link_[a-z]{1}[\w_]*/>',self.assembly[lineNumber]))
                for linkName in linkList:
                    absoluteLabel = linkName.startswith('!')
                    if linkName[absoluteLabel:] in self.labels:
                        instruction = self.instructions.get(
                            categorizedLine, None)
                        instLength = 0
                        if instruction and self.jump_npc:
                            instLength = self.formats[instruction[0]][0]//8
                        self.assembly[lineNumber] = re.sub(
                            '(?<![\w_])%s(?![\w_])' % linkName,
                            str(self.labels[linkName]
                            -(currentProgress+instLength)),
                            self.assembly[lineNumber])
                line = self.cleanLine(self.assembly[lineNumber])
                if not markLine and lineNumber not in delList:
                    for operand in line[1:]:
                        if re.search('[<>/~%^&*()-+]',operand):
                            self.assembly[lineNumber] = re.sub(
                                '(?<![\w<>?/~!%%^&*()\-+])%s(?![\w<>?/~!%%^&*()\-+])' % re.escape(operand),
                                str(numexpr.evaluate(operand).item()),self.assembly[lineNumber])
                if markLine:
                    pass_tainted = True
                    self.markedLines[lineNumber] = self.assembly[lineNumber]
                else:
                    delList.append(lineNumber)
            for lineNumber in set(delList):
                del self.markedLines[lineNumber]
            if watchdog_markedLength == len(self.markedLines):
                print(ERROR_FATAL[1])
                for lineNumber in self.markedLines.keys():
                    print(self.markedLines[lineNumber])
                print(self.labels)
                quit(101)
        for lineNumber in set(asmDelList):
            del self.assembly[lineNumber]
def linkPasses ( self ) : asmDelList = [ ] while self . markedLines : pass_tainted = False watchdog_markedLength = len ( self . markedLines ) delList = [ ] for lineNumber in self . markedLines . keys ( ) : currentProgress = self . linePos [ lineNumber ] line = self . cleanLine ( self . assembly [ lineNumber ] ) markLine = 0 if line [ 0 ] [ - 1 ] == ":" : labelName = line [ 0 ] [ : - 1 ] if self . labels . get ( labelName , None ) != None : print ( ERRORS [ 6 ] . format ( lineNumber , labelName ) ) else : self . labels [ labelName ] = currentProgress asmDelList . append ( lineNumber ) elif line [ 0 ] == '.const' : if self . constants . get ( line [ 1 ] , None ) != None : print ( ERRORS [ 7 ] . format ( lineNumber , line [ 1 ] ) ) elif re . search ( '[\-]*\d+' , line [ 2 ] ) : self . constants [ line [ 1 ] ] = numexpr . evaluate ( line [ 2 ] ) . item ( ) else : markLine = True asmDelList . append ( lineNumber ) linkList = set ( re . findall ( '[!]*<link_[a-z]{1}[\w_]*/>' , self . assembly [ lineNumber ] ) ) for linkName in linkList : absoluteLabel = linkName . startswith ( '!' ) if linkName in self . constants : self . assembly [ lineNumber ] = re . sub ( '(?<![\w_])%s(?![\w_])' % linkName , str ( self . constants [ linkName ] ) , self . assembly [ lineNumber ] ) elif linkName [ absoluteLabel : ] in self . labels : if absoluteLabel : self . assembly [ lineNumber ] = re . sub ( '(?<![\w_])%s(?![\w_])' % linkName , str ( self . labels [ linkName [ 1 : ] ] ) , self . assembly [ lineNumber ] ) else : markLine = True newLine = [ line [ 0 ] ] for operand in line [ 1 : ] : if re . search ( '[<>/~%^&*()-+]' , operand ) : newLine . append ( str ( numexpr . evaluate ( re . sub ( '[!]*<link_[a-z]{1}[\w_]*/>' , '0' , operand ) ) . item ( ) ) ) else : newLine . append ( operand ) categorizedLine = self . categorizeOperands ( newLine ) linkList = set ( re . findall ( '[!]*<link_[a-z]{1}[\w_]*/>' , self . assembly [ lineNumber ] ) ) for linkName in linkList : absoluteLabel = linkName . startswith ( '!' ) if linkName [ absoluteLabel : ] in self . labels : instruction = self . instructions . get ( categorizedLine , None ) instLength = 0 if instruction and self . jump_npc : instLength = self . formats [ instruction [ 0 ] ] [ 0 ] // 8 self . assembly [ lineNumber ] = re . sub ( '(?<![\w_])%s(?![\w_])' % linkName , str ( self . labels [ linkName ] - ( currentProgress + instLength ) ) , self . assembly [ lineNumber ] ) line = self . cleanLine ( self . assembly [ lineNumber ] ) if not markLine and lineNumber not in delList : for operand in line [ 1 : ] : if re . search ( '[<>/~%^&*()-+]' , operand ) : self . assembly [ lineNumber ] = re . sub ( '(?<![\w<>?/~!%%^&*()\-+])%s(?![\w<>?/~!%%^&*()\-+])' % re . escape ( operand ) , str ( numexpr . evaluate ( operand ) . item ( ) ) , self . assembly [ lineNumber ] ) if markLine : pass_tainted = True self . markedLines [ lineNumber ] = self . assembly [ lineNumber ] else : delList . append ( lineNumber ) for lineNumber in set ( delList ) : del self . markedLines [ lineNumber ] if watchdog_markedLength == len ( self . markedLines ) : print ( ERROR_FATAL [ 1 ] ) for lineNumber in self . markedLines . keys ( ) : print ( self . markedLines [ lineNumber ] ) print ( self . labels ) quit ( 101 ) for lineNumber in set ( asmDelList ) : del self . assembly [ lineNumber ]
Link passes, tries to find empty links and assign them
Link passes tries to find empty links and assign them
"""
        Link passes, tries to find empty links and assign them
        """ # Label assignment # Constant assignment # Replace constants, absolute labels, and mark empty links # Absolute labels, always assignable # Find links and replace them with zero # Categorize operands for easy identification # Find untainted Links and replace them # N/PC-relative labels # Check whether it's an instruction we're making a # relative label for and if architecture uses NPC # It is an instruction and NPC, calculate length # Find unmarked operands and attempt to evaluate them # Store line for further pass(es)
self