def p_line_label(p): ''' line : LABEL NEWLINE ''' p[0] = None # Nothing to append __DEBUG__("Declaring '%s' (value %04Xh) in %i" % (p[1], MEMORY.org, p.lineno(1))) MEMORY.declare_label(p[1], p.lineno(1))
def p_line_label_asm(p): ''' line : LABEL asm NEWLINE ''' p[0] = p[2] __DEBUG__("Declaring '%s' (value %04Xh) in %i" % (p[1], MEMORY.org, p.lineno(1))) MEMORY.declare_label(p[1], p.lineno(1))
def exit_proc(self, lineno): ''' Exits current procedure. Local labels are transferred to global scope unless they have been marked as local ones. Raises an error if no current local context (stack underflow) ''' __DEBUG__('Exiting current scope from lineno %i' % lineno) if len(self.local_labels) <= 1: error(lineno, 'ENDP in global scope (with no PROC)') for label in self.local_labels[-1].values(): if label.local: if not label.defined: error(lineno, "Undefined LOCAL label '%s'" % label.name) continue name = label.name _lineno = label.lineno value = label.value if name not in self.global_labels.keys(): self.global_labels[name] = label else: self.global_labels[name].define(value, _lineno) self.local_labels.pop() # Removes current context self.scopes.pop()
def enter_proc(self, lineno): ''' Enters (pushes) a new context ''' self.local_labels.append({}) # Add a new context self.scopes.append(lineno) __DEBUG__('Entering scope level %i at line %i' % (len(self.scopes), lineno))
def p_LOCAL(p): ''' asm : LOCAL id_list ''' p[0] = None for label, line in p[2]: __DEBUG__("Setting label '%s' as local at line %i" % (label, line)) MEMORY.set_label(label, line, local = True)
def p_def_label(p): ''' line : ID EQU expr NEWLINE | ID EQU pexpr NEWLINE ''' p[0] = None __DEBUG__("Declaring '%s' in %i" % (p[1], p.lineno(1))) MEMORY.declare_label(p[1], p.lineno(1), p[3])
def __call__(self, table): __DEBUG__("evaluating id '%s'" % self.name) if self.value is None: __DEBUG__("undefined (null) value. BUG?") return '' result = '' for token in self.value: __DEBUG__("evaluating token '%s'" % str(token)) if isinstance(token, MacroCall): __DEBUG__("token '%s'(%s) is a MacroCall" % (token._id, str(token))) if table.defined(token._id): tmp = table[token._id] __DEBUG__("'%s' is defined in the symbol table as '%s'" % (token._id, tmp.name)) if isinstance(tmp, ID) and not tmp.hasArgs: __DEBUG__("'%s' is an ID" % tmp.name) token = copy.deepcopy(token) token._id = tmp(table) # *** __DEBUG__("'%s' is the new id" % token._id) __DEBUG__("executing MacroCall '%s'" % token._id) tmp = token(table) else: if isinstance(token, ID): __DEBUG__("token '%s' is an ID" % token._id) token = token(table) tmp = token __DEBUG__("token got value '%s'" % tmp) result += tmp return result
def p_program_line(p): ''' program : program line ''' if p[2] is not None: __DEBUG__('%04Xh [%04Xh] ASM: %s' % (MEMORY.org, MEMORY.org - MEMORY.ORG, p[2].asm)) MEMORY.add_instruction(p[2])
def __call__(self, symbolTable = None): ''' Execute the macro call using LAZY evaluation ''' __DEBUG__("evaluating '%s'" % self._id) if symbolTable is None: symbolTable = self.table if not self.is_defined(symbolTable): # The macro is not defined => returned as is __DEBUG__("macro '%s' not defined" % self._id) tmp = self._id if self.callargs is not None: tmp += str(self.callargs) __DEBUG__("evaluation result: %s" % tmp) return tmp # The macro is defined __DEBUG__("macro '%s' defined" % self._id) TABLE = copy.deepcopy(symbolTable) ID = TABLE[self._id] # Get the defined macro if ID.hasArgs and self.callargs is None: # If no args passed, returned as is return self._id if self.callargs: # has args. Evaluate them removing spaces __DEBUG__("'%s' has args defined" % self._id) __DEBUG__("evaluating %i arg(s) for '%s'" % (len(self.callargs), self._id )) args = [x(TABLE).strip() for x in self.callargs] __DEBUG__("macro call: %s%s" % (self._id, '(' + ', '.join(args) + ')')) if not ID.hasArgs: # The macro doesn't need args __DEBUG__("'%s' has no args defined" % self._id) tmp = ID(TABLE) if self.callargs is not None: # If args (even empty () list) passed calculate them tmp += '(' + ', '.join(args) + ')' __DEBUG__("evaluation result: %s" % tmp) return tmp # Now ensure both args and callargs have the same length if len(self.callargs) != len(ID.args): raise PreprocError('Macro "%s" expected %i params, got %i' % \ (str(self._id), len(ID.args), len(self.callargs)), self.lineno) # Carry out unification __DEBUG__('carrying out args unification') for i in range(len(self.callargs)): __DEBUG__("arg '%s' = '%s'" % (ID.args[i].name, args[i])) TABLE.set(ID.args[i].name, self.lineno, args[i]) tmp = ID(TABLE) if '\n' in tmp: tmp += '\n#line %i\n' % (self.lineno) return tmp
def __call__(self, symbolTable=None): ''' Execute the macro call using LAZY evaluation ''' __DEBUG__("evaluating '%s'" % self._id) if symbolTable is None: symbolTable = self.table if not self.is_defined( symbolTable): # The macro is not defined => returned as is __DEBUG__("macro '%s' not defined" % self._id) tmp = self._id if self.callargs is not None: tmp += str(self.callargs) __DEBUG__("evaluation result: %s" % tmp) return tmp # The macro is defined __DEBUG__("macro '%s' defined" % self._id) TABLE = copy.deepcopy(symbolTable) ID = TABLE[self._id] # Get the defined macro if ID.hasArgs and self.callargs is None: # If no args passed, returned as is return self._id if self.callargs: # has args. Evaluate them removing spaces __DEBUG__("'%s' has args defined" % self._id) __DEBUG__("evaluating %i arg(s) for '%s'" % (len(self.callargs), self._id)) args = [x(TABLE).strip() for x in self.callargs] __DEBUG__("macro call: %s%s" % (self._id, '(' + ', '.join(args) + ')')) if not ID.hasArgs: # The macro doesn't need args __DEBUG__("'%s' has no args defined" % self._id) tmp = ID(TABLE) if self.callargs is not None: # If args (even empty () list) passed calculate them tmp += '(' + ', '.join(args) + ')' __DEBUG__("evaluation result: %s" % tmp) return tmp # Now ensure both args and callargs have the same length if len(self.callargs) != len(ID.args): raise PreprocError('Macro "%s" expected %i params, got %i' % \ (str(self._id), len(ID.args), len(self.callargs)), self.lineno) # Carry out unification __DEBUG__('carrying out args unification') for i in range(len(self.callargs)): __DEBUG__("arg '%s' = '%s'" % (ID.args[i].name, args[i])) TABLE.set(ID.args[i].name, self.lineno, args[i]) tmp = ID(TABLE) if '\n' in tmp: tmp += '\n#line %i\n' % (self.lineno) return tmp