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)