def add(cls, **columns):
        r'''Internal method called by `create`.

        This inserts the new type (and sub_elements, if any) into the
        database.

        This method is shared by all base classes.
        '''
        sub_elements = None
        if 'sub_elements' in columns:
            sub_elements = columns['sub_elements']
            del columns['sub_elements']
        insert_columns = columns.copy()
        if 'element_type' in insert_columns:
            insert_columns['element_type'] = insert_columns['element_type'].id
        id = crud.insert('type', kind=cls.__name__, **insert_columns)
        if sub_elements:
            for i, field in enumerate(sub_elements):
                if isinstance(field, base_type):
                    name = None
                    type = field
                else:
                    name, type = field
                crud.insert('sub_element', parent_id=id, element_order=i,
                                           name=name, element_type=type)
        return cls(id, columns, sub_elements)
def uses(fn_id, var_id):
    r'''Function fn_id directly references global variable var_id.

    Fn_id and var_id are the symbol_ids of the function and global variable,
    respectively.
    '''
    crud.insert('fn_global_var_uses', 'ignore',
                fn_id=fn_id, var_id=var_id, sets=False)
def sets(fn_id, var_id):
    r'''Function fn_id directly sets global variable var_id.

    Fn_id and var_id are the symbol_ids of the function and global variable,
    respectively.
    '''
                                      # FIX: Shouldn't this be 'replace'?
    crud.insert('fn_global_var_uses', 'ignore',
                fn_id=fn_id, var_id=var_id, sets=True)
def init():
    crud.Db_conn = crud.db.connect('avr.db')
    crud.Db_cur = crud.Db_conn.cursor()
    try:
        # insert 0's for m=0:

        crud.Db_cur.execute("""
          insert into worst (N, C, m, value)
            select N.id, C.id, 0, 0 from reg_class N cross join reg_class C
        """)

        crud.Db_conn.commit()

        registers = crud.read_column('register', 'name')
        aliases = {}
        for R in registers:
            aliases[R] = frozenset(crud.read_column('alias', 'r2', r1=R))

        reg_classes = crud.read_column('reg_class', 'id')
        regs_in_class = {}
        for C in reg_classes:
            regs_in_class[C] = \
              frozenset(crud.read_column('reg_in_class', 'reg', reg_class=C))
        print 'reg_classes', reg_classes

        for N in reg_classes:
            print 'N', N
            N_regs = regs_in_class[N]
            for C in reg_classes:
                C_regs = regs_in_class[C]
                print 'C', C, C_regs

                # {set of S: set of registers}
                worsts0 = {frozenset(): frozenset()}

                for m in range(1, len(C_regs) + 1):
                    print 'm', m
                    worsts1 = {}
                    for R in C_regs:
                        for S0, regs in worsts0.iteritems():
                            if R not in S0:
                                worsts1[S0.union((R,))] = \
                                    regs.union(aliases[R]).intersection(N_regs)
                    crud.insert('worst', N=N, C=C, m=m,
                                value=max(len(regs)
                                          for regs in worsts1.itervalues()))
                    worsts0 = worsts1
            crud.Db_conn.commit()
        worst0 = worst1 = None
    except:
        crud.Db_conn.rollback()
        raise
    finally:
        crud.Db_cur.close()
        crud.Db_conn.close()
    def create(cls, label, kind, context = None, **attributes):
        r'''Creates a new symbol_table entry.

        Updates an existing database row (if found), or inserts a new row.

        Returns the id of the row.
        '''
        if context is None:
            id = crud.read1_column('symbol_table', 'id',
                                   label=label, context=None,
                                   zero_ok=True)
            if id is not None:
                crud.update('symbol_table', {'id': id}, kind=kind,
                            **attributes)
                if id in Symbols_by_id:
                    del Symbols_by_id[id]
                    del Symbols[label, None]
                return cls(id, label, context, kind=kind, **attributes)
        id = crud.insert('symbol_table',
                         option='replace',
                         label=label,
                         kind=kind,
                         context=context and context.id,
                         **attributes)
        return cls(id, label, context, kind=kind, **attributes)
    def write(self, next = None):
        r'''Writes the block and associated triples to the database.

        Returns the id assigned to the block.
        '''

        global Current_block

        #print self.name, "write"

        if self.state == 'end_absolute':
            next = None
        else:
            assert next is not None

        id = crud.insert('blocks',
                         name=self.name,
                         word_symbol_id=self.word_symbol_id,
                         last_triple_id=self.last_triple.id
                                          if self.last_triple
                                          else None,
                         next=next,
                         next_conditional=self.next_conditional)

        # add final labels to their associated triples:
        for var_id, t in self.labels.iteritems():
            t.add_label(var_id, True)

        # write out triples:
        #
        # first figure out the set of all triples that will be forcably
        # written:
        forced_triples = set(self.labels.values())
        if self.side_effects is not None:
            #print self.name, "adding", self.side_effects, "due to side_effects"
            forced_triples.add(self.side_effects)
        forced_triples.update(self.sets_global.values())
        if self.last_triple is not None:
            #print self.name, "adding", self.last_triple, "as last_triple"
            forced_triples.add(self.last_triple)
        #
        # then write them all:
        #
        for t in forced_triples:
            t.write(id)
        #
        # then call write_soft_predecessors for all of them:
        #
        for t in forced_triples:
            t.write_soft_predecessors(id)

        assert self.name not in Block_ids
        Block_ids[self.name] = id

        Current_block = None
        #print self.name, "write returning", id
        return id
 def save(self, word_symbol,
          parent = None, parent_arg_num = None, arg_order = None):
     r'''Writes itself and its children (args) to the database.
     '''
     kws = dict(itertools.chain(
                  map(lambda attr: (attr, getattr(self, attr)),
                      self.attr_cols),
                  zip(self.arg_cols,
                      (word_symbol.id, parent, parent_arg_num,
                       arg_order))))
     self.word_symbol = word_symbol
     self.id = crud.insert('ast', **kws)
     save_args(self.args, word_symbol, self.id)
def calls(caller_id, called_id):
    r'''Function caller_id directly calls function called_id.

    Both caller_id and called_id are the symbol_id of the function.
    '''
    crud.insert('fn_calls', 'ignore', caller_id=caller_id, called_id=called_id)