Exemple #1
0
def basetype2():

    # basetype = builtin-type
    # builtin-type = "int2"

    if not is_typename2():
        raise asmd.ManncError( '変数の定義が型名からはじまりません。 100' )

    if consume_tk( TK.INT2 ):
        return asmd.Type2( kind = TYP.INT2, size = 4, align = 4, is_complete = True, base = 0, array_len = 0, members = 0, return_ty = 0 )
    else :
        raise asmd.ManncError( 'サポートしていない型です' )
Exemple #2
0
    def stmt_while():
        if not consume( '(' ):
            raise asmd.ManncError('while の後は ( が必要です')
        node = asmd.NodeWHILE()
        node.kind = ND.WHILE
        node.expr = expr()

        if not consume( ')' ) :
            raise asmd.ManncError('while の ''('' 後は '')'' が必要です')
        node.block = stmt()
        
        return node
Exemple #3
0
    def stmt_if():
        #print('#IF')
        if not consume( '(' ) :
            raise asmd.ManncError('if の後は ( が必要です')
        node = asmd.NodeIF()
        node.kind = ND.IF
        node.expr = expr()
        if not consume( ')' ) :
            raise asmd.ManncError('if の ''('' 後は '')'' が必要です')
        node.truebl = stmt()
        if consume_tk( TK.ELSE ) :
            node.elsebl = stmt()

        return node
Exemple #4
0
def getgvar():


    if asmd.tkn[0].str != 'int' and asmd.tkn[0].str != 'char':
        raise asmd.ManncError( '変数の定義が型名からはじまりません。 1' )

    #
    # 型
    #
    if consume_tk( TK.INT ) :
        thistype = asmd.myType()
        if consume( '*' ) :
            # intへのポインタ型
            thistype.ty = TYP.PTR
            thistype.ptr_to = asmd.myType()
            thistype.ptr_to.ty = TYP.INT
        else:
            # int型
            thistype.ty = TYP.INT
    elif consume_tk( TK.CHAR ) :
        if consume( '*' ) :
            # charへのポインタ型
            thistype.ty = TYP.PTR
            thistype.ptr_to = asmd.myType()
            thistype.ptr_to.ty = TYP.CHAR
        else:
            # char型
            thistype.ty = TYP.CHAR
    elif consume_tk( TK.STRUCT ) :
        pass

    else:
        raise asmd.ManncError( '変数の定義が型名からはじまりません。2 {0}'.format(asmd.tkn[0].str ) )

    if asmd.tkn[0].str in asmd.glvars_t:
        raise asmd.ManncError( 'グローバル変数が二重で宣言されています' )
        
    asmd.glvars_t[ asmd.tkn[0].str ] = thistype
    
    del asmd.tkn[0]

    if consume( '=' ) :
        #グローバル変数の初期化
        raise asmd.ManncError( 'グローバル変数の初期化は未実装' )
        pass

    if not consume( ';' ):
        raise asmd.ManncError( 'グローバル変数が ; で終了していません。{0}'.format( asmd.tkn[0].str ) )
        
    return
Exemple #5
0
    def stmt_switch():
        if not consume( '(' ):
            raise asmd.ManncError('switch の後は ( が必要です')
        node = asmd.NodeSWITCH()
        node.kind = ND.SWITCH
        node.expr = expr()
        if not consume( ')' ) :
            raise asmd.ManncError('switch の ''('' 後は '')'' が必要です')

        sw = asmd.current_switch
        asmd.current_switch = node
        node.block = stmt()
        asmd.current_switch = sw
        
        return node
Exemple #6
0
def expect( op ):
    #print(" # expect {0}".format( op ) )
    if asmd.tkn[0].kind != TK.RESERVED or asmd.tkn[0].str != op:
        raise asmd.ManncError( "'{0}'ではありません".format(op) )
        #sys.exit()

    del asmd.tkn[0]
    return True
Exemple #7
0
def declarator2():
    # declarator = ident
    if not asmd.tkn[0].kind :
        raise asmd.ManncError( '型名の後に変数名がありません' )

    name = asmd.tkn[0].str
    del asmd.tkn[0]

    return( 0, name ) # 型と名前(ident)を返す
Exemple #8
0
def unary():
    #print("# unary")

    #sizeof
    if consume_tk( TK.SIZEOF ):
        node = unary()
        if node.type == TYP.INT:
            return new_node_num( 8 )
        else :
            return new_node_num( 8 )

    if consume( '+' ):
        lnode = new_node_num( 0 )
        node = new_node( ND.ADD, lnode, primary() )
        return node

    if consume( '-' ):
        lnode = new_node_num( 0 )
        node = new_node( ND.SUB, lnode, primary() )
        return node
    
    if asmd.tkn[1].str == '[':
        #配列の場合
        newnode = new_node( ND.DEREF, 0, 0 )
        #newnode.type = TYP.ARRAY
        newnode.lhs = new_node( ND.PTR_ADD, 0, 0 )
        newnode.lhs.lhs = primary()
        newnode.lhs.type = newnode.lhs.lhs.type
        del asmd.tkn[0] # [ を削除する
        newnode.lhs.rhs = expr()
        if not consume( ']' ):
            raise asmd.ManncError('配列が]で閉じられていません{0}'.format(asmd.tkn[0].str) )

        return newnode

    # アドレス(ポインタ)用演算子
    if consume( '*' ):
        print('#ND.DEREF')
        node = new_node( ND.DEREF, unary(), 0 )
        if node.lhs.kind == ND.ADD:
            node.lhs.kind = ND.PTR_ADD
        node.type = node.lhs.type
        #node = new_node( ND.DEREF, 0, 0 )
        #node.lhs = new_node( ND.PTR_ADD, unary(), 0 )
        #node.type = node.lhs.type
        #node.lhs.type = node.lhs.type
        print("#DEREF pins" )
        asmd.pins( node )
        asmd.pins( node.lhs )
        
        return node
    if consume( '&' ):
        print('#ND.ADDR')
        node = new_node( ND.ADDR, unary(), 0 )
        return node
    
    return primary()
Exemple #9
0
    def tk_char():
        nonlocal ch
        nonlocal offset
        nonlocal offset
        f.seek(offset)
        offset += 1
        chb = f.read(1)
        ch = chb.decode('utf-8')

        if ch == '\\':
            # エスケープ
            f.seek(offset)
            offset += 1
            chb = f.read(1)
            ch = chb.decode('utf-8')
            if ch == 'n':
                # 改行文字
                newtkn = asmd.Token()
                newtkn.kind = TK.NUM
                newtkn.val = 10
                asmd.tkn.append(newtkn)
            else:
                raise asmd.ManncError('文字の特殊文字は改行だけ')

        else:
            #f.seek( offset )
            #offset += 1
            #chb = f.read(1)
            #ch  = chb.decode('utf-8')

            # 文字を数値に変換
            newtkn = asmd.Token()
            newtkn.kind = TK.NUM
            newtkn.val = ord(ch)
            asmd.tkn.append(newtkn)
            #print("<{0}>".format(newtkn.val))

        # 閉じクォート
        f.seek(offset)
        offset += 1
        chb = f.read(1)
        ch = chb.decode('utf-8')
        if ch != '\'':
            raise asmd.ManncError('文字は一文字だけ')
Exemple #10
0
def expect_number():
    #print('# expect_number  tknknd {0}'.format(asmd.tkn[0].kind ))
    if asmd.tkn[0].kind != TK.NUM:
        raise asmd.ManncError("数ではありません {0}".format(asmd.tkn[0].str))
        #sys.exit()

    #print('# valval {0}'.format(asmd.tkn[0].val ) )

    val = asmd.tkn[0].val
    del asmd.tkn[0]

    return val
Exemple #11
0
def program() :
    while asmd.tkn[0].kind != TK.EOF:
        # グローバル変数?  関数定義?
        if asmd.tkn[0].str != 'int' and asmd.tkn[0].str != 'char':
            raise asmd.ManncError( '関数、変数の定義が型名からはじまりません。{0}'.format( asmd.tkn[0].str ) )
            
        if asmd.tkn[1].str == '*' :
            if asmd.tkn[2].kind != TK.IDENT: 
                raise asmd.ManncError( '型名の後ろが識別子ではありません' )
            if asmd.tkn[3].str == '(':
                #ポインタを返す関数
                asmd.code.append( funcdef() )
            else:
                #グローバルのポインタ変数
                getgvar2()
        else:
            if asmd.tkn[1].kind != TK.IDENT: 
                raise asmd.ManncError( '型名の後ろが識別子ではありません' )
            if asmd.tkn[2].str == '(':
                #ポインタ以外を返す関数
                asmd.code.append( funcdef() )
            else:
                #グローバルのポインタ以外の変数
                getgvar2()
Exemple #12
0
    def stmt_case():

        print("#CASE")
        if asmd.current_switch == 0:
            raise asmd.ManncError('stray case')
        val = expect_number()
        print("#VAL {0}".format(val))

        expect( ':' )
        node = asmd.NodeCASE()
        node.kind = ND.CASE
        node.block = stmt()
        node.val = val
        node.case_next = asmd.current_switch.case_next
        asmd.current_switch.case_next = node
        return node
Exemple #13
0
def gen_lval(node):
    print("# gen_lval START")
    #asmd.pins( node )

    print("#in {0}(): if node.kind == {1}".format(
        inspect.currentframe().f_back.f_code.co_name, node.kind))

    if node.type == TYP.ARRAY:
        print("#in {0}(): if node.kind == {1}".format(
            inspect.currentframe().f_back.f_code.co_name, node.kind))
        return

    if node.kind == ND.LVAR:
        print("#in {0}(): if node.kind == {1}".format(
            inspect.currentframe().f_back.f_code.co_name, node.kind))
        var = node.str

        if var in asmd.glvars_t:
            # グローバル変数の左辺値
            print("\tpush offset {0}".format(var))
            return

        # グローバル変数でないときにローカル変数とみなす
        #if len(node.lvars2) > 0 :
        #return

        print('#here {0}'.format(var))
        offset = asmd.lvars[var].offset
        print('#gen_lval var={0} offset={1}'.format(var, offset))

        print('\tmov rax, rbp')
        print('\tsub rax, {0}'.format(offset))
        print('#raxtest 6')
        print('\tpush rax')

        return

    if node.kind == ND.DEREF:
        print("#in {0}(): if node.kind == {1}".format(
            inspect.currentframe().f_back.f_code.co_name, node.kind))
        gen(node.lhs)
        return

    raise asmd.ManncError('代入の左辺値が変数ではありません')
Exemple #14
0
 def stmt_continue():
     if not consume( ';' ):
         raise asmd.ManncError('continue の後は ; が必要です')
     node = asmd.Node()
     node.kind = ND.CONTINUE
     return node
Exemple #15
0
def funcdef():
    global locals2

    newnode = asmd.NodeFUNCDEF()

    if asmd.tkn[0].kind == TK.INT:
        newnode.type = asmd.TypeType( kind = TYP.INT,  size = 4, align = 4, array_len = 0, base = 0, function = 0 )
    elif asmd.tkn[0].kind == TK.CHAR:
        newnode.type = asmd.TypeType( kind = TYP.CHAR, size = 1, align = 1, array_len = 0, base = 0, function = 0 )
    else:
        raise asmd.ManncError( '関数の定義が型名からはじまりません。' )
    del asmd.tkn[0]

    if asmd.tkn[0].kind != TK.IDENT:
        raise asmd.ManncError( '関数の定義ではありません' )

    newnode.kind = ND.FUNCDEF
    newnode.name = asmd.tkn[0].str
    del asmd.tkn[0]

    newnode.offset = 0

    if not consume( '(' ):
        raise asmd.ManncError('関数パラメータの定義がおかしいです A')

    while True :
        if consume( ')' ):
            # 引数のない関数
            break;
##############
        ( thistype, vname ) =  type.declaration( 'PARA' )

        #asmd.glvars_t[ name ] = t
##############

        newnode.paranum += 1

        #vname = asmd.tkn[0].str

        # 関数引数のローカル変数用左辺値
        if vname in newnode.lvars :
           # パラメータの変数名が重複する場合は考慮しない
            pass
        else :

            newnode.lvars_t[ vname ] = thistype
            newnode.para.append( vname )

            newnode.lvars[ vname ] = asmd.MYVar()
            newnode.lvars[ vname ].name = vname
            newnode.lvars[ vname ].type = thistype
            newnode.lvars[ vname ].offset  = asmd.align_to( newnode.offset, thistype.align )
            newnode.lvars[ vname ].offset += newnode.lvars[ vname ].type.size 
            
            newnode.offset += newnode.lvars_t[ vname ].size
            #newnode.offset = newnode.lvarst[ vname ].offset

        #del asmd.tkn[0]

        if consume( ')' ):
            # 引数のない関数
            break;
        
        if not consume( ',' ):
            raise asmd.ManncError('関数パラメータの定義がおかしいです C')
            sys.exit()
        
    # パラメータ読み込み終わり

    # 関数の実行部分は BLOCK で書き換えられる?
    # BLOCKにしないと、genする時にうまく生成できない?

    asmd.offset =   newnode.offset
    asmd.lvars_t = copy.deepcopy( newnode.lvars_t )
    asmd.lvars = copy.deepcopy( newnode.lvars )

    newnode.block = stmt()

    newnode.lvars = copy.deepcopy( asmd.lvars )

    #newnode.lvars2 = copy.deepcopy( locals2 )
    newnode.lvars2 = locals2
    asmd.pins(newnode)
    if newnode.lvars2 != 0 :
        print('#0921')
        for item in newnode.lvars2.values():
            print("#name={0}".format(item))

            print("#ty.kind={0}".format(item.ty.kind))
            print("#ty.kind ={0}".format(item.ty.kind))
            print("#ty.size ={0}".format(item.ty.size))
            print("#ty.align ={0}".format(item.ty.align))
            print("#ty.is_complete ={0}".format(item.ty.is_complete))
            print("#ty.base ={0}".format(item.ty.base))
            print("#ty.array_len ={0}".format(item.ty.array_len))
            print("#ty.members ={0}".format(item.ty.members))
            print("#ty.return_ty ={0}".format(item.ty.return_ty))

    newnode.lvars_t = copy.deepcopy( asmd.lvars_t )
    newnode.offset = asmd.offset
    
    return newnode
Exemple #16
0
    def primary_IDENT() :

        #print('######TK_IDENT')

        if saki( '(', 1 ):
            newnode = asmd.NodeFUNCCALL()
            newnode.kind = ND.FUNC
            newnode.name = asmd.tkn[0].str
            del asmd.tkn[0]
            del asmd.tkn[0]

            #
            # 関数呼び出しの場合
            #
            if consume( ')' ):
                return newnode
            
            while True :
                para = expr();
                newnode.para.append( para )

                if consume( ')' ) :
                    break
                if not consume( ',' ):
                    raise asmd.ManncError('関数呼び出し方が不正です' )
                    # sys.exit()
            return newnode

        else :
            #
            # 変数(左辺値)の場合
            #
            if asmd.tkn[0].str in asmd.glvars_t:
                #グローバル変数として宣言されている場合
                newnode = asmd.Node()
                newnode.kind = ND.LVAR
                newnode.str = asmd.tkn[0].str
                newnode.size = asmd.glvars_t[ asmd.tkn[0].str ].size
                newnode.type = asmd.glvars_t[ asmd.tkn[0].str ]
                del asmd.tkn[0]
                return newnode

            # リファクタリング用
            if asmd.tkn[0].str in locals2.keys():
                print('#0922test{0}'.format( asmd.tkn[0].str) )
                newnode = asmd.Node()
                newnode.kind = ND.LVAR2
                newnode.name2 = asmd.tkn[0].str #Nodeに変数名は必要ない?
                newnode.size = locals2[ asmd.tkn[0].str ].ty.size
                newnode.offset = locals2[ asmd.tkn[0].str ].offset
                newnode.type = locals2[ asmd.tkn[0].str ]
                del asmd.tkn[0]
                return newnode

            if not asmd.tkn[0].str in asmd.lvars :
                raise asmd.ManncError('宣言されていない変数を使用しようとしています<{0}><{1}>'.format(asmd.tkn[0].str, asmd.lvars ) )

            #配列ではない場合
            newnode = asmd.Node()
            newnode.kind = ND.LVAR
            newnode.str = asmd.tkn[0].str
            newnode.size = asmd.lvars_t[ asmd.tkn[0].str ].size

            newnode.offset = asmd.lvars[ asmd.tkn[0].str ]
            newnode.type = asmd.lvars_t[ asmd.tkn[0].str ]

            del asmd.tkn[0]
            return newnode
Exemple #17
0
def stmt():
    #print("# stmt")
    #
    # 関数内関数
    #

    # declaration の最終目標↓
    # declaration = basetype declarator type-suffix ("=" lvar-initializer)? ";"
    #             | basetype ";"

    def stmt_declaration2():

        # declaration = basetype declarator ";"

        ty = basetype2()
        ( dummy, name ) = declarator2()
        #if not consume( ';' ) :
            #raise asmd.ManncError('宣言文 の後は ; が必要です')
        
        return new_lvar2( name, ty )
        
    def stmt_switch():
        if not consume( '(' ):
            raise asmd.ManncError('switch の後は ( が必要です')
        node = asmd.NodeSWITCH()
        node.kind = ND.SWITCH
        node.expr = expr()
        if not consume( ')' ) :
            raise asmd.ManncError('switch の ''('' 後は '')'' が必要です')

        sw = asmd.current_switch
        asmd.current_switch = node
        node.block = stmt()
        asmd.current_switch = sw
        
        return node

    def stmt_case():

        print("#CASE")
        if asmd.current_switch == 0:
            raise asmd.ManncError('stray case')
        val = expect_number()
        print("#VAL {0}".format(val))

        expect( ':' )
        node = asmd.NodeCASE()
        node.kind = ND.CASE
        node.block = stmt()
        node.val = val
        node.case_next = asmd.current_switch.case_next
        asmd.current_switch.case_next = node
        return node

    def stmt_break():
        if not consume( ';' ):
            raise asmd.ManncError('break の後は ; が必要です')
        node = asmd.Node()
        node.kind = ND.BREAK
        return node
        
    def stmt_continue():
        if not consume( ';' ):
            raise asmd.ManncError('continue の後は ; が必要です')
        node = asmd.Node()
        node.kind = ND.CONTINUE
        return node
        
    def stmt_while():
        if not consume( '(' ):
            raise asmd.ManncError('while の後は ( が必要です')
        node = asmd.NodeWHILE()
        node.kind = ND.WHILE
        node.expr = expr()

        if not consume( ')' ) :
            raise asmd.ManncError('while の ''('' 後は '')'' が必要です')
        node.block = stmt()
        
        return node

    def stmt_if():
        #print('#IF')
        if not consume( '(' ) :
            raise asmd.ManncError('if の後は ( が必要です')
        node = asmd.NodeIF()
        node.kind = ND.IF
        node.expr = expr()
        if not consume( ')' ) :
            raise asmd.ManncError('if の ''('' 後は '')'' が必要です')
        node.truebl = stmt()
        if consume_tk( TK.ELSE ) :
            node.elsebl = stmt()

        return node
    #
    # 関数内関数 おわり 
    #
    if consume( ';' ) :
        node = asmd.Node()
        node.kind = ND.NOP
        return node

    if consume( '{' ) :
        #print('#print BLOCK start')
        node = asmd.NodeBLOCK()
        node.kind = ND.BLOCK

        if consume( '}' ):
            return node

        while True:
            newstmt = stmt()
            node.stmts.append( newstmt )
            if consume( '}' ):
                break;
        
        return node

    # 変数の宣言文の場合    
    if asmd.tkn[0].kind in ( TK.INT, TK.CHAR ):
        tknkind = asmd.tkn[0].kind 
        
        ( thistype, vname ) =  type.declaration( 'NOTPARA' )
        print('#var dec')
        print('#{0}'.format(vname))
        thistype.myself()
        if thistype.base != 0 :
            thistype.base.myself()

        asmd.lvars_t[ vname ] = thistype
        asmd.offset = asmd.align_to( asmd.offset, thistype.align )
        asmd.offset += asmd.lvars_t[ vname ].size
        asmd.lvars[ vname ] = asmd.MYVar()
        asmd.lvars[ vname ].offset = asmd.offset
        print('#offset aaaaa')
        print('#offset  {0}'.format( asmd.offset ) )
        print('#lvars   {0}'.format( asmd.lvars[ vname ].offset ) )
        #print('#lvars_t {0}'.format( asmd.lvars_t[ vname ].offset ) )
        #del asmd.tkn[0]

        return 0
        
    if is_typename2():
        return stmt_declaration2()
    if consume_tk( TK.SWITCH ):
        return stmt_switch()
    if consume_tk( TK.CASE ):
        return stmt_case()
    if consume_tk( TK.CONTINUE ):
        return stmt_continue()
    if consume_tk( TK.BREAK ):
        return stmt_break()
    if consume_tk( TK.WHILE ):
        return stmt_while()
    if consume_tk( TK.IF ):
        return stmt_if()
    if consume_tk( TK.RETURN ) :
        node = asmd.Node()
        node.kind = ND.RETURN
        node.lhs = expr()
    else :
        node = expr()

    if consume( ';' ):
        return node
    else:
        raise asmd.ManncError(';ではないトークンです{0}'.format(asmd.tkn[0].str))
Exemple #18
0
def gen(node):
    global seq
    global if_num
    global while_num
    global break_num
    global switch_num
    global lvars2

    while_num_tmp = 0

    print("# gen START")
    #asmd.pins( node )

    if node == 0:
        return

    if node.kind == ND.NOP:
        print("#NOP")
        return

    if node.kind == ND.STRING:
        print("\tpush offset .L.strings.{0}".format(node.val))
        print('\tpop rax')
        print('\tmov rax, [rax]')
        print('\tpush rax')
        return

    # NodeKind が変数の場合 リファクタリング用
    if node.kind == ND.LVAR2:
        print("#0922 x ")
        gen_lval2(node)

        # 配列の場合のみアドレスが指す先をメモリから読み込む処理を
        # 飛ばす条件分岐を追加する必要がある todo
        load(node.size)

        return

    # NodeKind が変数の場合
    if node.kind == ND.LVAR:
        gen_lval(node)

        # 配列の場合のみアドレスが指す先をメモリから読み込む処理を
        if node.type.kind != TYP.ARRAY:
            load(node.size)
        return

    # NodeKind が代入の場合
    if node.kind == ND.ASSIGN:
        gen_lval(node.lhs)
        gen(node.rhs)
        store(node.lhs.size)
        return

    # NodeKind が代入の場合 リファクタリング
    if node.kind == ND.ASSIGN2:
        print("#0922 ASSIGN2")
        print("#lhs")
        asmd.pins(node.lhs)
        print("#rhs")
        asmd.pins(node.rhs)

        gen_lval2(node.lhs)
        gen(node.rhs)
        store(node.lhs.size)
        return

    # Nodekind が '*' の場合
    if node.kind == ND.DEREF:
        print('#test001')
        #asmd.pins( node )
        #asmd.pins( node.lhs )
        #asmd.pins( node.lhs.lhs )
        #asmd.pins( node.lhs.rhs )
        gen(node.lhs)
        #load( node.lhs.type.size )
        #asmd.pins( node )
        if node.lhs.type != TYP.ARRAY:
            print("#in {0}:{1}".format(
                os.path.basename(
                    inspect.currentframe().f_back.f_code.co_filename),
                inspect.currentframe().f_back.f_lineno))
            print('#test002')
            #load( 4 )
            load(node.lhs.type.base.size)
        return

    # Nodekind が '&' の場合
    if node.kind == ND.ADDR:
        print("# gen ND.ADDRF")
        gen_lval(node.lhs)
        return

    if node.kind == ND.FUNCDEF:

        lvars2 = node.lvars2

        node.myself()

        # 関数の名前=ラベル
        print("{0}:".format(node.name))

        # プロローグ
        print('#プロローグ')
        print('\tpush rbp')
        print('\tmov rbp, rsp')
        print('\tsub rsp, {0}'.format(node.offset))

        # レジスタの中身をパラメータにコピーする
        para_i = 0
        #para_reg64 = [ "rdi", "rsi", "rdx", "rcx" ];
        #para_reg32 = [ "edi", "esi", "edx", "ecx" ];
        #para_reg8  = [ "dil", "sil", "dl",  "cl" ];
        while para_i < node.paranum:
            print("#para{0}".format(para_i))
            print("#para{0}".format(node.para[para_i]))
            print("\tmov rax, rbp\n")
            #print("#DDDDEBUG {0}".format( node.para[para_i] ) )
            print("\tsub rax, {0}\n".format(
                node.lvars[node.para[para_i]].offset))
            if node.lvars_t[node.para[para_i]].size == 8:
                print("\tmov [rax], {0}\n".format(para_reg64[para_i]))
            elif node.lvars_t[node.para[para_i]].size == 4:
                print("\tmov [rax], {0}\n".format(para_reg32[para_i]))
            elif node.lvars_t[node.para[para_i]].size == 1:
                print("\tmov [rax], {0}\n".format(para_reg8[para_i]))
            else:
                raise asmd.ManncError('代入のサイズがおかしい')

            para_i += 1

        asmd.lvars = node.lvars.copy()
        asmd.lvars_t = node.lvars_t.copy()

        # 関数本体(ブロック)を出力する
        gen(node.block)

        #エピローグ
        #最後の式の結果がRAXに残っているのでそれが返り値になる
        print('#エピローグ')
        print('\tpop rax')
        print('\tmov rsp, rbp')
        print('\tpop rbp')

        return

    # NodeKind が FUNC の場合
    if node.kind == ND.FUNC:
        print('#FUNC')
        pcnt = 0
        for para in node.para:
            gen(para)
            if pcnt == 0:
                print("\tpop rdi\n")
            elif pcnt == 1:
                print("\tpop rsi\n")
            elif pcnt == 2:
                print("\tpop rdx\n")
            elif pcnt == 3:
                print("\tpop rcx\n")
            else:
                raise asmd.ManncError('関数の引数は4つまで')
                #sys.exit()
            pcnt += 1

        print("  mov rax, rsp")
        print("  and rax, 15")
        print("  jnz .L.call.{0}".format(seq))
        print("  mov rax, 0")
        #print("  call %s\n", node->funcname);
        print('\tcall {0}'.format(node.name))
        print("  jmp .L.end.{0}".format(seq))
        print(".L.call.{0}:".format(seq))
        print("  sub rsp, 8")
        print("  mov rax, 0")
        #print("  call %s\n", node->funcname);
        print('\tcall {0}'.format(node.name))
        print("  add rsp, 8")
        print(".L.end.{0}:".format(seq))
        seq += 1

        #print('\tcall {0}'.format(node.name) )
        print('#raxtest 2')
        print('\tpush rax')

        return

    # NodeKindが、数値の場合
    # スタックにその値をプッシュする
    if node.kind == ND.NUM:
        print("#in {0}(): if node.kind == {1}".format(
            inspect.currentframe().f_back.f_code.co_name, node.kind))
        print('\tpush {0}'.format(node.val))
        return

    if node.kind == ND.BLOCK:
        for stmt in node.stmts:
            gen(stmt)
            print('#raxtest 3')
            #print('\tpush rax')
        return

    if node.kind == ND.SWITCH:
        switch_num_tmp = switch_num
        switch_num += 1
        break_num_tmp = break_num
        break_num = switch_num_tmp
        node.case_label = switch_num_tmp

        gen(node.expr)
        print("\tpop rax")

        n = node.case_next
        while n != 0:
            n.case_label = switch_num
            switch_num += 1
            n.case_end_label = switch_num_tmp
            #print('\tpop rax')
            print('\tcmp rax, {0}'.format(n.val))
            print('\tje .L.case.{0}'.format(n.case_label))
            n = n.case_next

        if node.default_case:
            i = switch_num
            switch_num += 1
            node.default_case.case_end_label = switch_num_tmp
            node.default_case.case_label = i
            print("\tjmp .L.case.{0}".format(i))

        print("\tjmp .L.break.{0}".format(switch_num_tmp))
        gen(node.block)
        print(".L.break.{0}:\n".format(switch_num_tmp))

        break_num = break_num_tmp

        return

        #switch 終わり

    if node.kind == ND.CASE:
        print(".L.case.{0}:".format(node.case_label))
        gen(node.block)
        return

    if node.kind == ND.WHILE:
        while_num_tmp = while_num
        break_num_tmp = break_num
        break_num = while_num
        while_num += 1

        print('#whilegen')
        print(".Lbegin{0}:".format(while_num_tmp))
        gen(node.expr)
        print('\tpop rax')
        print('\tcmp rax, 0')
        print("je  .Lend{0}".format(while_num_tmp))
        gen(node.block)
        print("jmp .Lbegin{0}".format(while_num_tmp))
        print(".Lend{0}:".format(while_num_tmp))
        ###print(".L.break.{0}:".format(break_num_tmp))
        print(".L.break.{0}:".format(break_num))
        print('#whilegen end')

        break_num = break_num_tmp

        return

    if node.kind == ND.CONTINUE:
        print("#continue")
        print("jmp .Lbegin{0}".format(while_num_tmp))
        return

    if node.kind == ND.BREAK:
        print("#break")
        print("jmp .L.break.{0}".format(break_num))
        return

    if node.kind == ND.IF:
        print('#ifgen')
        gen(node.expr)
        print('\tpop rax')
        print('\tcmp rax, 0')
        if_num_tmp1 = if_num
        if_num += 1
        if_num_tmp2 = if_num
        if_num += 1
        print('\tje .ELSE' + str(if_num_tmp1).zfill(3))
        print('#ture gen')
        if not node.truebl == 0:
            gen(node.truebl)
        print('\tjmp .IFEND' + str(if_num_tmp2).zfill(3))
        print('\t.ELSE' + str(if_num_tmp1).zfill(3) + ':')
        if not node.elsebl == 0:
            gen(node.elsebl)
        print('.IFEND' + str(if_num_tmp2).zfill(3) + ':')

        return

    # NodeKind が reurn の場合
    if node.kind == ND.RETURN:
        print('#NDRETUN')
        gen(node.lhs)
        print('#NDRETURN エピローグ')
        print('\tpop rax')
        print('\tmov rsp, rbp')
        print('\tpop rbp')
        print('\tret')
        return

    # NodeKindが、二項演算子(四則演算、等号、不等号)の場合
    # lhs がスタックトップ
    # rhs がその次
    # pop してその二つを rdi と rax に入れる
    # 演算の結果は rax に入れてプッシュする

    print("#in {0}:{1}".format(
        os.path.basename(inspect.currentframe().f_back.f_code.co_filename),
        inspect.currentframe().f_back.f_lineno))
    gen(node.lhs)
    gen(node.rhs)

    print('\tpop rdi')
    print('\tpop rax')

    if node.kind == ND.PTR_ADD:
        print("#in {0}:{1}".format(
            os.path.basename(inspect.currentframe().f_back.f_code.co_filename),
            inspect.currentframe().f_back.f_lineno))
        print("# gen ND.PTR_ADDR")
        #ポインタの計算をする場合
        #size = node.lhs.type.size
        #node.lhs.type.size = 4
        print('\timul rdi, {0}'.format(node.lhs.type.base.size))
        print('\tadd rax, rdi')

    elif node.kind == ND.ADD:
        print('\tadd rax, rdi')
    elif node.kind == ND.SUB:
        print('\tsub rax, rdi')
    elif node.kind == ND.MUL:
        print('\timul rax, rdi')
    elif node.kind == ND.DIV:
        print('\tcqo')
        print('\tidiv rax, rdi')
    elif node.kind == ND.EQU:
        print('\tcmp rax, rdi')
        print('sete al')
        print('movzb rax, al')
    elif node.kind == ND.NEQ:
        print('\tcmp rax, rdi')
        print('\tsetne al')
        print('\tmovzb rax, al')
    elif node.kind == ND.LT:
        print('\tcmp rax, rdi')
        print('\tsetl al')
        print('\tmovzb rax, al')
    elif node.kind == ND.LTE:
        print('\tcmp rax, rdi')
        print('\tsetle al')
        print('\tmovzb rax, al')

    print('#raxtesta5')
    print('\tpush rax')

    return
Exemple #19
0
 def stmt_break():
     if not consume( ';' ):
         raise asmd.ManncError('break の後は ; が必要です')
     node = asmd.Node()
     node.kind = ND.BREAK
     return node
Exemple #20
0
    def tk_string():
        nonlocal ch
        nonlocal offset

        #offset += 1
        f.seek(offset)
        chb = f.read(1)
        ch = chb.decode('utf-8')
        tmpstr = ''
        # 文字リテラル読み込みループ開始
        while True:
            if ch == '"':
                break
            #print('string={0}'.format(ch))

            #文字列中のバックスペースはエスケープシーケンス
            if ch == '\\':
                offset += 1
                f.seek(offset)
                chb = f.read(1)
                ch = chb.decode('utf-8')

                if ch == 'n':  # 改行文字
                    ch = "\n"

                if ch.isdecimal():  # '\nnn は8進数のコード
                    cnt8 = 1
                    num8 = 0
                    while ch.isdecimal() and cnt8 <= 3:
                        if 0 <= int(ch) <= 7:

                            num8 *= 8
                            num8 += int(ch)

                            offset += 1
                            f.seek(offset)
                            chb = f.read(1)
                            ch = chb.decode('utf-8')

                            cnt8 += 1
                        else:
                            raise asmd.ManncError(
                                'リテラルのバックスラッシュの後ろの数値は0から7までです')

                    tmpstr += chr(num8)
                    continue

            tmpstr += ch
            offset += 1
            f.seek(offset)
            chb = f.read(1)
            ch = chb.decode('utf-8')
        # 文字リテラル読み込みループ終了

        #string_i 文字列の通し番号
        label = ".L.LITERAL.{0}".format(asmd.string_i)
        asmd.strings[label] = tmpstr
        asmd.string_i += 1

        newtkn = asmd.Token()
        newtkn.kind = TK.STRING
        newtkn.str = label  # 変数名=ラベル
        asmd.tkn.append(newtkn)

        # ダブルクォーテーションを読み捨てる
        offset += 1
        chb = f.read(1)
Exemple #21
0
def declaration(mode):

    #
    # 変数の定義は int または char から始まる
    #
    if asmd.tkn[0].str == 'int':
        base = asmd.TypeType(TYP.INT, 4, 4, 0, 0, 0)
    elif asmd.tkn[0].str == 'char':
        base = asmd.TypeType(TYP.CHAR, 1, 1, 0, 0, 0)
    else:
        raise asmd.ManncError('変数の定義が型名からはじまりません。 t')

    del asmd.tkn[0]

    ptype = 0
    if asmd.tkn[0].str == '*':
        #
        # ポインタ * が 1 個以上続く
        #
        ptype = asmd.TypeType(TYP.PTR, 8, 8, 0, 0, 0)
        lastp = ptype
        del asmd.tkn[0]
        while asmd.tkn[0].str == '*':
            print('loop')
            lastp.base = asmd.TypeType(TYP.PTR, 8, 8, 0, 0, 0)
            lastp = last.base
            del asmd.tkn[0]

    # * の後は IDENT のはず
    if asmd.tkn[0].kind != TK.IDENT:
        raise asmd.ManncError('変数の名前がありません {0}'.format(asmd.tkn[0].str))

    # 変数の名前
    vname = asmd.tkn[0].str
    del asmd.tkn[0]

    arrayt = 0
    if asmd.tkn[0].str == '[':
        print('#declare arrayt')
        #
        # 配列の場合
        #
        del asmd.tkn[0]
        if asmd.tkn[0].kind != TK.NUM:
            raise asmd.ManncError('配列の添え字が数値ではありません')

        # そえじの処理
        arraylen = asmd.tkn[0].val
        arrayt = asmd.TypeType(TYP.ARRAY, base.size * arraylen, base.align,
                               arraylen, 0, 0)
        lastp = arrayt.base

        arraysize = asmd.tkn[0].val
        del asmd.tkn[0]

        if asmd.tkn[0].str != ']':
            raise asmd.ManncError('配列の添え字の後ろに ] がありません')

        del asmd.tkn[0]

    # この関数が、通常の宣言部か、関数のパラメータで呼ばれたかで
    # 処理(区切り文字)を変える
    if mode == 'NOTPARA':
        if asmd.tkn[0].str != ';':
            raise asmd.ManncError('宣言の終わりが ; ではありません{0}'.format(
                asmd.tkn[0].str))
        del asmd.tkn[0]
    if mode == 'PARA':
        if asmd.tkn[0].str != ',' and asmd.tkn[0].str != ')':
            raise asmd.ManncError('パラメータのおわり、区切りが , )  ではありません'.format(
                asmd.tkn[0].str))
        #del しない

    if arrayt == 0 and ptype == 0:
        return (base, vname)

    if arrayt != 0:
        if ptype == 0:
            arrayt.base = base

            print('#declare arrayt')
            arrayt.myself()
            base.myself()

            return (arrayt, vname)
        else:
            arrayt.base = ptype
            lastp = base
            return (arrayt, vname)

    lastp.base = base

    return (ptype, vname)