def create_parsers(top): r'''Creates a parser in each package. Returns {package_name: parser module} Also does load_word on all of the defining words. ''' global Rules, Token_dict Rules = [] Token_dict = {} package_parsers = {} syntax_file = os.path.join(os.path.dirname(__file__), 'SYNTAX') with crud.db_transaction(): for p in top.packages: for ww in p.get_words(): load_word(ww) #print "Rules", Rules #print "Token_dict", Token_dict # compile new parser for this package: with open(os.path.join(p.package_dir, 'parser.py'), 'w') \ as output_file: genparser.genparser(syntax_file, '\n'.join(Rules), Token_dict, output_file) # import needed modules from the package: package_parsers[p.package_name] = \ helpers.import_module(p.package_name + '.parser') return package_parsers
def parse_needed_words(top, package_parsers, quiet): r'''Parses all of the needed word files. Returns a set of the labels of the words parsed. ''' words_done = set() words_needed = set(['startup']) num_errors = 0 while words_needed: next_word = words_needed.pop() ww = top.get_word_by_label(next_word) word_obj = ww.symbol.word_obj status, more_words_needed = \ parse_word(ww, word_obj, package_parsers[ww.package_name]) if status: words_done.add(next_word) words_needed.update(more_words_needed - words_done) else: num_errors += 1 if num_errors: sys.stderr.write("%s files had syntax errors\n" % num_errors) sys.exit(1) with crud.db_transaction(): fn_xref.expand(quiet) return words_done
def run(top, prime_start_time = True, quiet = False): # The following gets a little confusing because we have two kinds of word # objects: # # 1. ww objects ("word_word", i.e., instances of the # ucc.word.word.word class) # 2. word_obj objects (either subclasses or instances of the # ucclib.built_in.declaration.declaration class) # if prime_start_time: elapsed() # prime the Start_time... compile_start_time = Start_time else: compile_start_time = Start_time if not quiet: print "top: %.2f" % elapsed() with crud.db_connection(top.packages[-1].package_dir): if not quiet: print "crud.db_connection: %.2f" % elapsed() types.init() if not quiet: print "types.init: %.2f" % elapsed() # Create symbols, word_objs and build the parsers for each package: # # {package_name: parser module} package_parsers = create_parsers(top) # Also loads all of the word objs if not quiet: print "create parsers: %.2f" % elapsed() # word files => ast words_done = parse_needed_words(top, package_parsers, quiet) if not quiet: print "parse_needed_words: %.2f" % elapsed() # ast => intermediate code for word_label in words_done: with crud.db_transaction(): symbol_table.get(word_label).word_obj.compile() if not quiet: print "generate intermediate code: %.2f" % elapsed() # intermediate code => optimized intermediate code optimize() if not quiet: print "optimize: %.2f" % elapsed() # intermediate code => assembler gen_assembler() if not quiet: print "gen_assembler: %.2f" % elapsed() # assembler => .hex files assemble_program(top.packages[-1].package_dir) if not quiet: print "assemble_program: %.2f" % elapsed() if not quiet: print "TOTAL: %.2f" % (Start_time - compile_start_time)
def parse_file(self, parser, debug = 0): filename = self.ww.get_filename() for i, label in enumerate(self.ww.get_value('argument')): symbol_table.symbol.create(label, 'parameter', self.ww.symbol, int1=i) worked, ast_args = parse.parse_file(parser, self.ww, debug) if not worked: raise AssertionError, "parse failed for " + filename words_needed = set() with crud.db_transaction(): self.ast_args = \ ast.prepare_args(self.ww.symbol, ast_args, words_needed) ast.save_word(self.label, self.ww.symbol, self.ast_args) return frozenset(words_needed)
def assemble_program(package_dir): r'''Assemble all of the sections. Generates .hex files in package_dir. ''' # Assign addresses to all labels in all sections: labels = {} # {label: address} with crud.db_transaction(): # flash start_data = assemble.assign_labels('flash', labels) # data assert 'start_data' not in labels, \ "duplicate assembler label: start_data" labels['start_data'] = start_data data_len = assemble.assign_labels('data', labels) assert 'data_len' not in labels, \ "duplicate assembler label: data_len" labels['data_len'] = data_len # bss bss_end = assemble.assign_labels('bss', labels, data_len) assert 'bss_len' not in labels, \ "duplicate assembler label: bss_len" labels['bss_len'] = bss_end - data_len # eeprom assemble.assign_labels('eeprom', labels) # assemble flash and data: hex_file.write(itertools.chain(assemble.assemble('flash', labels), assemble.assemble('data', labels)), package_dir, 'flash') # check that bss is blank! try: assemble.assemble('bss', labels).next() except StopIteration: pass else: raise AssertionError("bss is not blank!") # assemble eeprom: hex_file.write(assemble.assemble('eeprom', labels), package_dir, 'eeprom')
def gen_assembler(): for fun_id, fun_label, fun_kind \ in crud.read_as_tuples('symbol_table', 'id', 'label', 'kind', kind=('function', 'task')): with crud.db_transaction(): gen_fun(fun_id, fun_label, fun_kind)