asmdata.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 896 行 · 第 1/2 页

C
896
字号
            if( store_fixup( 0 ) == ERROR )
                return( ERROR );
#endif
            /* now actually output the data */
            ptr = (char *)&data;
#if defined( _STANDALONE_ )
            if( sym && Parse_Pass == PASS_1 ) {
                update_sizes( sym, first, no_of_bytes );
            }
            if( !struct_field ) {
#endif
                /* only output up to 4 bytes of offset (segment is on fixup) */
                for( i = 0; i < min( no_of_bytes, 4 ); i++ ) {
                    AsmDataByte( *ptr );
                    ptr++;
                }
                /* leave space for segment */
                for( ; i < no_of_bytes; i++ ) {
                    AsmDataByte( 0 );
                }
#if defined( _STANDALONE_ )
            } else if( the_struct != NULL ) {
                Definition.curr_struct->e.structinfo->size += no_of_bytes;
                update_sizes( the_struct, first, no_of_bytes );
            }
#endif
            // set position back to main loop worked correctly
            cur_pos--;
            break;
            }
        case T_UNARY_OPERATOR: {
            int i;
            int fixup_type;
            int seg_off_operator_loc = 0;
            asm_sym *init_sym;
            char *ptr;
            long data = 0;
            struct asmfixup     *fixup;

            if( AsmBuffer[cur_pos]->value == T_OFFSET ||
                AsmBuffer[cur_pos]->value == T_SEG ) {
                // see asmins.h about T_SEG
                if( no_of_bytes < 2 ) {
                    AsmError( OFFSET_TOO_SMALL );
                    return( ERROR );
                }
            }
            seg_off_operator_loc = cur_pos;
#if defined( _STANDALONE_ )
            i = ++cur_pos;
            if( i + 2 < Token_Count ) {
                if( ( AsmBuffer[i]->token == T_RES_ID )
                    && ( AsmBuffer[i + 1]->token == T_RES_ID )
                    && ( AsmBuffer[i + 1]->value == T_PTR ) ) {
                    i += 2;
                }
            }
            if( check_override( &i ) == ERROR ) {
                return( ERROR );
            }
            i--;
            cur_pos = i;
#endif
            if( cur_pos + 1 < Token_Count ) {
                if( AsmBuffer[++cur_pos]->token == T_ID ) {
                    init_sym = AsmLookup( AsmBuffer[cur_pos]->string_ptr );
                    if( init_sym == NULL )
                        return( ERROR );

                    if( AsmBuffer[seg_off_operator_loc]->value == T_OFFSET ) {
                        if( init_sym->state == SYM_STACK ) {
                            AsmError( CANNOT_OFFSET_AUTO );
                            return( ERROR );
#if defined( _STANDALONE_ )
                        } else if( init_sym->state == SYM_GRP ) {
                            AsmError( CANNOT_OFFSET_GRP );
                            return( ERROR );
#endif
                        }
                        switch( no_of_bytes ) {
                        case 1:
                            AsmError( OFFSET_TOO_SMALL ); // fixme
                            return( ERROR );
                        case 2:
                            fixup_type = FIX_OFF16;
                            break;
                        case 4:
                            fixup_type = FIX_OFF32;
#if defined( _STANDALONE_ )
                            if( !SymIs32( init_sym ) ) {
                                fixup_type = FIX_OFF16;
                            }
#endif
                            break;
                        default:
                            AsmError( NOT_IMPLEMENTED );
                            return( ERROR );
                        }
                    } else if( AsmBuffer[seg_off_operator_loc]->value == T_SEG ) {
                        if( init_sym->state == SYM_STACK ) {
                            AsmError( CANNOT_SEG_AUTO );
                        }
                        fixup_type = FIX_SEG;
                    }

                    switch( AsmBuffer[seg_off_operator_loc]->value ) {
                    case T_OFFSET:
#if defined( _STANDALONE_ )
                        if( init_sym->state == SYM_STRUCT_FIELD ) {
                            data = init_sym->offset;
                            break;
                        }
#endif
                    case T_SEG:
#if defined( _STANDALONE_ )
                        find_frame( init_sym );
#endif
                        fixup = AddFixup( init_sym, fixup_type, OPTJ_NONE );
                        InsFixups[OPND1] = fixup;
                        if( AsmBuffer[seg_off_operator_loc]->value == T_OFFSET ) {
                            data += fixup->offset;
                        }
#if defined( _STANDALONE_ )
                        if( store_fixup( 0 ) == ERROR )
                            return( ERROR );
#endif
                        break;
#if defined( _STANDALONE_ )
                    case T_LENGTH:
                        data = init_sym->first_length;
                        break;
                    case T_LENGTHOF:
                        data = init_sym->total_length;
                        break;
                    case T_SIZE:
                        data = init_sym->first_size;
                        break;
                    case T_SIZEOF:
                        data = init_sym->total_size;
                        break;
#endif
                    default:
                        AsmError( SYNTAX_ERROR );
                        return( ERROR );
                    }
                    for( cur_pos++;
                        ( cur_pos < Token_Count ) && ( AsmBuffer[cur_pos]->token != T_FINAL)
                        && ( AsmBuffer[cur_pos]->token != T_COMMA );
                        cur_pos++ ) {
                        switch( AsmBuffer[cur_pos]->token ) {
                        case T_PLUS:
                        case T_DOT:
                        case T_OP_SQ_BRACKET:
                            break;
#if defined( _STANDALONE_ )
                        case T_ID:
                            init_sym = AsmLookup( AsmBuffer[cur_pos]->string_ptr );
                            data += init_sym->offset;
                            break;
#endif
                        case T_MINUS:
                            if( AsmBuffer[cur_pos+1]->token != T_NUM ) {
                                AsmError( EXPECTING_NUMBER );
                                return( ERROR );
                            }
                            AsmBuffer[cur_pos+1]->value *=-1;
                            break;
                        case T_NUM:
                            data += AsmBuffer[cur_pos]->value;
                        }
                    }

                    /* now actually output the data */
                    ptr = (char *)&data;
#if defined( _STANDALONE_ )
                    if( sym && Parse_Pass == PASS_1 ) {
                        update_sizes( sym, first, no_of_bytes );
                    }
                    if( !struct_field ) {
#endif
                        for( i = 0; i < no_of_bytes; i++ ) {
                            AsmDataByte( *ptr );
                            ptr++;
                        }
#if defined( _STANDALONE_ )
                    } else {
                        if( the_struct == NULL )
                            break;
                        Definition.curr_struct->e.structinfo->size += no_of_bytes;
                        update_sizes( the_struct, first, no_of_bytes );
                    }
#endif
                } else {
                    AsmError( SYNTAX_ERROR );
                    return( ERROR );
                }
            }
            // set position back to main loop worked correctly
            cur_pos--;
            // AsmError( NOT_IMPLEMENTED );
            break;
            }
        case T_CL_BRACKET:
            return( cur_pos );
        default:
            AsmError( EXPECTING_NUMBER );
            return( ERROR );
        }
    }
    return( cur_pos );
}

static int dup_array( asm_sym *sym, asm_sym *struct_sym, int start_pos, unsigned no_of_bytes )
/********************************************************************************************/
/*
  parse array with DUP operator;
*/
{
    int                 cur_pos = start_pos;
    int                 returned_pos;
    int                 count;
#if defined( _STANDALONE_ )
    bool                was_first;
#endif

    ExpandTheWorld( start_pos, FALSE, TRUE );
    while( cur_pos + 2 < Token_Count ) {
        if(( AsmBuffer[cur_pos + 1]->token == T_RES_ID )
            && ( AsmBuffer[cur_pos + 1]->value == T_DUP )) {
            if( AsmBuffer[cur_pos]->token != T_NUM ) {
                AsmError( SYNTAX_ERROR );
                return( ERROR );
            }
            count = AsmBuffer[cur_pos]->value;
            cur_pos += 2;
            if( AsmBuffer[cur_pos]->token != T_OP_BRACKET ) {
                AsmError( SYNTAX_ERROR );
                return( ERROR );
            }

            cur_pos++;
#if defined( _STANDALONE_ )
            was_first = first;
#endif
            while( count > 0 ) {
                /* in case there was a "," inside the dup */
#if defined( _STANDALONE_ )
                first = was_first;
#endif
                returned_pos = array_element( sym, struct_sym, cur_pos, no_of_bytes );
                if( returned_pos == ERROR )
                    return( ERROR );
                count--;
            }
            if( AsmBuffer[returned_pos]->token != T_CL_BRACKET ) {
                AsmError( BRACKET_EXPECTED );
                return( ERROR );
            }
        } else {
            returned_pos = array_element( sym, struct_sym, cur_pos, no_of_bytes );
            if( returned_pos == ERROR )
                return( ERROR );
            if( AsmBuffer[returned_pos]->token != T_CL_BRACKET ) {
                /* array_element hit T_FINAL so stop */
                return( returned_pos );
            }
        }
        if( AsmBuffer[returned_pos+1]->token != T_COMMA ) {
            return( returned_pos );
        }
        cur_pos = returned_pos + 2;
#if defined( _STANDALONE_ )
        first = FALSE;
#endif
    }
    return( array_element( sym, struct_sym, cur_pos, no_of_bytes ) );
}

int data_init( int sym_loc, int initializer_loc )
/***********************************************/
/*
  parse data initialization assembly line;
*/
{
    unsigned            no_of_bytes;
    memtype             mem_type;
    struct asm_sym      *sym = NULL;
    struct asm_sym      *struct_sym = NULL;
#if defined( _STANDALONE_ )
    uint                old_offset;
    char                label_dir = FALSE;

    struct_field = FALSE;
    first = TRUE;
#endif

    if( sym_loc >= 0 ) {
        sym = AsmLookup( AsmBuffer[sym_loc]->string_ptr );
        if( sym == NULL ) {
            return( ERROR );
        }
    }

    switch( AsmBuffer[initializer_loc]->value ) {
#if defined( _STANDALONE_ )
    case T_SBYTE:                       // 20-Aug-92
        mem_type = MT_SBYTE;
        no_of_bytes = BYTE_1;
        break;
    case T_SWORD:                       // 20-Aug-92
        mem_type = MT_SWORD;
        no_of_bytes = BYTE_2;
        break;
    case T_SDWORD:                      // 20-Aug-92
        mem_type = MT_SDWORD;
        no_of_bytes = BYTE_4;
        break;
    case T_DQ:
    case T_QWORD:
        mem_type = MT_QWORD;
        no_of_bytes = BYTE_8;
        break;
    case T_DT:
    case T_TBYTE:                       // 20-Aug-92
        mem_type = MT_TBYTE;
        no_of_bytes = BYTE_10;
        break;
    case T_OWORD:
        mem_type = MT_OWORD;
        no_of_bytes = BYTE_16;
        break;
    case T_STRUC:
    case T_STRUCT:
        mem_type = MT_STRUCT;
        struct_sym = AsmLookup( AsmBuffer[initializer_loc]->string_ptr );
        no_of_bytes = GetStructSize( struct_sym );
        break;
#endif
    case T_DB:
    case T_BYTE:
        mem_type = MT_BYTE;
        no_of_bytes = BYTE_1;
        break;
    case T_DW:
    case T_WORD:
        mem_type = MT_WORD;
        no_of_bytes = BYTE_2;
        break;
    case T_DD:
    case T_DWORD:
        mem_type = MT_DWORD;
        no_of_bytes = BYTE_4;
        break;
    case T_DF:                          // 20-Aug-92
    case T_FWORD:
    case T_DP:
    case T_PWORD:
        mem_type = MT_FWORD;
        no_of_bytes = BYTE_6;
        break;
    default:
        AsmError( INVALID_LABEL_DEFINITION );
        return( ERROR );
    }
    if( AsmBuffer[ initializer_loc + 1 ]->token == T_FINAL ) {
        AsmError( SYNTAX_ERROR );
        return( ERROR );
    }

#if defined( _STANDALONE_ )
    if( sym_loc >= 0 && AsmBuffer[ sym_loc ]->value == T_LABEL ) {
        label_dir = TRUE;
        sym_loc--;
    }
    if( sym_loc < 0 ) {
        if( Definition.struct_depth != 0 ) {
            if( Parse_Pass == PASS_1 ) {
                AddFieldToStruct( initializer_loc );
                struct_field = TRUE;
            } else {
                return( NOT_ERROR );
            }
        }
    }
#endif

    if( More_Array_Element == TRUE ) {
        More_Array_Element = FALSE;
    } else if( sym_loc >= 0 ) {
#if defined( _STANDALONE_ )
        /* defining a field in a structure */
        if( Definition.struct_depth != 0 ) {
            if( Parse_Pass == PASS_1 ) {
                sym->offset = AddFieldToStruct( initializer_loc );
                struct_field = TRUE;
                sym->state = SYM_STRUCT_FIELD;
                sym->mem_type = mem_type;
                if( dup_array( sym, NULL, initializer_loc + 1, no_of_bytes ) == ERROR ) {
                    return( ERROR );
                }
            }
            return( NOT_ERROR );
        }

        if( Parse_Pass == PASS_1 ) {
            if( sym->state != SYM_UNDEFINED ) {
                // redefine label
                AsmError( SYMBOL_ALREADY_DEFINED );
                return( ERROR );
            }
        } else {
            old_offset = sym->offset;
        }
        GetSymInfo( sym );
        if( Parse_Pass != PASS_1 && sym->offset != old_offset ) {
            PhaseError = TRUE;
        }
#else
        if( sym->state != SYM_UNDEFINED ) {
            // redefine label
            AsmError( SYMBOL_ALREADY_DEFINED );
            return( ERROR );
        }
#endif
        sym->state = SYM_INTERNAL;
        sym->mem_type = mem_type;
        BackPatch( sym );
    }
#if defined( _STANDALONE_ )
    if( label_dir )
        return( NOT_ERROR );
#endif
    if( dup_array( sym, struct_sym, initializer_loc + 1, no_of_bytes ) == ERROR ) {
        return( ERROR );
    }
    return( NOT_ERROR );
}

int NextArrayElement( void )
{
    if( More_Array_Element ) {
        More_Array_Element = FALSE;
        return( dup_array( NULL, NULL, 0, Last_Element_Size ) );
    } else {
        return( EMPTY );
    }
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?