def gen_fun(fun_id, fun_label, fun_kind):
    if fun_kind == 'function': far_size = 2
    else: far_size = 4
    prolog = assembler.block(fun_id, 'flash', fun_label)
    prolog.append_inst('push', 'r29')
    prolog.append_inst('push', 'r28')
    for id, kind, param_num \
     in crud.read_as_tuples('symbol_table', 'id', 'kind', 'int1',
                            context=fun_id,
                            order_by=('kind', 'desc', 'int1')):
        sym = symbol_table.get_by_id(id)
        far_size += 2
        sym.address = -far_size
        if fun_kind == 'task':
            sym.ram_size = 2
        if kind == 'parameter':
            prolog.append_inst('push', 'r%d' % (2 * param_num + 1))
            prolog.append_inst('push', 'r%d' % (2 * param_num))
    for id, name, next, next_conditional \
     in crud.read_as_tuples('blocks', 'id', 'name', 'next',
                            'next_conditional',
                            word_symbol_id=fun_id,
                            order_by=('id',)):
        asm_block = assembler.block(fun_id, 'flash', name)
        if next: asm_block.next_label(next)
        for what, should, this, be \
         in crud.read_as_tuples('triples',
                                block_id=id,
                                # FIX: finish...
                               ): pass
 def compile(self):
     assembler.delete(self.ww.symbol)
     initial_value = self.ww.get_value('initial_value')
     if initial_value is None:
         block = assembler.block(self.ww.symbol.id, 'bss', self.name)
         block.append_inst('zeroes', '2')
         block.write()
     else:
         block = assembler.block(self.ww.symbol.id, 'data', self.name)
         block.append_inst('int16', str(initial_value))
         block.write()
    def compile(self):
        r'''Generates intermediate code for this AST node.
        '''
        if self.kind in ('approx', 'int', 'ratio'):
            return block.Current_block.gen_triple(
                     self.kind, self.int1, self.int2,
                     syntax_position_info= self.get_syntax_position_info())

        if self.kind == 'string':
            name = crud.gensym('strlit')
            sym = symbol_table.symbol.create(name, 'const')
            asm_block = assembler.block(self.word_symbol.id, 'flash', name)
            asm_block.append_inst('int16', str(len(self.str1)))
            asm_block.append_inst('bytes', repr(self.str1))
            asm_block.write()
            return block.Current_block.gen_triple(
                     'global', sym.id,
                     syntax_position_info=self.get_syntax_position_info())

        if self.kind == 'call':
            if self.args and isinstance(self.args[0], ast) and \
               self.args[0].kind == 'word':
                word_obj = symbol_table.get(self.args[0].label).word_obj
                compile_method = word_obj.get_method('compile', self.expect)
                return compile_method(self)
            else:
                raise AssertionError("call indirect not supported yet")

        if self.kind == 'word':
            sym = symbol_table.get_by_id(self.symbol_id)
            if sym.context is None:
                word_obj = symbol_table.get_by_id(self.symbol_id).word_obj
                compile_method = word_obj.get_method('compile', self.expect)
                ans = compile_method(self)
                return ans
            if sym.kind in ('parameter', 'var'):
                return block.Current_block.gen_triple('local', sym,
                         syntax_position_info=self.get_syntax_position_info())
            raise ValueError("%s.compile: unknown symbol.kind %r" % sym.kind)

        if self.kind in ('no-op', 'None'):
            return None

        if self.kind == 'label':
            block.new_label(self.label, self.word_symbol.id)
            return None

        if self.kind == 'jump':
            block.Current_block.unconditional_to(self.label)
            return None

        if self.kind == 'if-true':
            arg_triples = self.compile_args()
            block.Current_block.true_to(arg_triples[0], self.label)
            return None

        if self.kind == 'if-false':
            arg_triples = self.compile_args()
            block.Current_block.false_to(arg_triples[0], self.label)
            return None

        if self.kind == 'series':
            self.compile_args()
            return None

        if self.kind in ('ioreg', 'ioreg-bit'):
            if self.expect in ('value', 'condition'):
                return block.Current_block.gen_triple(
                         'input' if self.kind == 'ioreg' else 'input-bit',
                         string=self.label, int1=self.int1,
                         syntax_position_info=self.get_syntax_position_info())
            else:
                raise AssertionError("ast node[%s]: expect %s not supported "
                                     "for %s" %
                                       (self.id, self.expect, self.kind))

        raise AssertionError("ast node[%s]: unknown ast kind -- %s" %
                               (self.id, self.kind))