asmscan.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 682 行 · 第 1/2 页
C
682 行
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
* DESCRIBE IT HERE!
*
****************************************************************************/
#include "asmglob.h"
#include <ctype.h>
#include "asmins.h"
#include "asmdefs.h"
char *CurrString; // Current Input Line
extern int get_instruction_position( char *string );
#if defined( _STANDALONE_ )
extern global_options Options;
void GetInsString( enum asm_token token, char *string, int len )
/**************************************************************/
{
int index;
if( len > AsmOpcode[ token ].len ) {
len = AsmOpcode[ token ].len;
index = AsmOpcode[ token ].index;
if( AsmChars[index]== '.' ) {
index++;
len--;
}
strncpy( string, &(AsmChars[ index ]), len );
string[ len ] = '\0';
} else {
*string='\0';
}
return;
}
#endif
typedef union {
float f;
long l;
} NUMBERFL;
static int get_float( struct asm_tok *buf, char **input, char **output )
/**********************************************************************/
{
/* valid floats look like: (int)[.(int)][e(int)] */
char got_decimal = FALSE;
char got_e = FALSE;
char *ptr = *input;
for( ; *ptr != '\0'; ptr++ ) {
if( isdigit( *ptr ) )
continue;
if( isspace( *ptr ) )
break;
switch( tolower( *ptr ) ) {
case '.':
got_decimal = TRUE;
continue;
case 'r':
*ptr=' ';
goto done_scanning_float;
case 'e':
if( !got_e ) {
got_e = TRUE;
/* accept e+2 / e-4 /etc. */
switch( *(ptr+1) ) {
case '+':
case '-':
ptr++;
/* fall through */
default:
continue;
}
}
/* fall through */
default:
goto done_scanning_float;
// return( get_string( buf, input, output ) );
}
}
done_scanning_float:
buf->token = T_FLOAT;
/* copy the string, fix input & output pointers */
strncpy( *output, *input, ptr - *input );
buf->string_ptr = *output;
*output += ( ptr - *input );
**output = '\0';
(*output)++;
*input = ptr;
*((float *)(&buf->value)) = atof(buf->string_ptr);
return( NOT_ERROR );
}
static void array_mul_add(char *buf, unsigned base, unsigned num, unsigned size) {
while( size-- > 0 ) {
num += *buf * base;
*(buf++) = num;
num >>= 8;
}
}
static int get_string( struct asm_tok *buf, char **input, char **output )
/***********************************************************************/
{
char symbol_o;
char symbol_c;
int count;
int level;
buf->string_ptr = *output;
symbol_o = **input;
buf->token = T_STRING;
switch( symbol_o ) {
case '"':
case '\'':
symbol_c = 0;
break; // end of string marker is the same
case '<':
symbol_c = '>';
break;
case '{':
symbol_c = '}';
break;
default:
/* this is an undelimited string,
* so just copy it until we hit something that looks like the end
*/
for( count = 0; **input != '\0' && !isspace( **input ) && **input != ','; count++ ) {
*(*output)++ = *(*input)++; /* keep the 2nd one */
}
*(*output)++ = '\0';
buf->value = count;
return( NOT_ERROR );
}
(*input)++;
count = 0;
level = 0;
while( count < MAX_TOK_LEN ) {
if( **input == symbol_o ) {
if( symbol_c ) {
level++;
*(*output)++ = *(*input)++;
count++;
} else if( *( *input + 1 ) == symbol_o ) {
/* if we see "" in a " delimited string,
* treat it as a literal " */
(*input)++; /* skip the 1st one */
*(*output)++ = *(*input)++; /* keep the 2nd one */
count++;
} else {
*(*output)++ = '\0';
(*input)++; /* skip the closing delimiter */
buf->value = count;
break;
}
} else if( symbol_c && **input == symbol_c ) {
if( level ) {
level--;
*(*output)++ = *(*input)++;
count++;
} else {
*(*output)++ = '\0';
(*input)++; /* skip the closing delimiter */
buf->value = count;
break;
}
} else if( **input == '\0' || **input == '\n' ) {
AsmError( SYNTAX_ERROR );
return( ERROR );
} else {
*(*output)++ = *(*input)++;
count++;
}
}
return( NOT_ERROR );
}
static int get_number( struct asm_tok *buf, char **input, char **output )
/***********************************************************************/
{
char *ptr = *input;
char *dig_start;
char first_char_0 = FALSE;
unsigned extra;
unsigned len;
unsigned base = 0;
unsigned digits_seen;
unsigned long val;
#define VALID_BINARY 0x0003
#define VALID_OCTAL 0x00ff
#define VALID_DECIMAL 0x03ff
#define OK_NUM( t ) ((digits_seen & ~VALID_##t) == 0)
digits_seen = 0;
extra = 0;
if( *ptr == '0' ) {
if( tolower( *(ptr+1) ) == 'x' ) {
ptr+=2;
base = 16;
} else {
ptr += 1;
first_char_0 = TRUE;
}
}
dig_start = ptr;
for( ;; ) {
switch( tolower( *ptr ) ) {
case '9':
case '8':
case '7':
case '6':
case '5':
case '4':
case '3':
case '2':
case '1':
case '0':
digits_seen |= 1 << (*ptr - '0');
break;
case 'a':
digits_seen |= 1 << 10;
break;
case 'b':
if( base == 0
&& OK_NUM( BINARY )
&& !isxdigit( ptr[1] )
&& tolower( ptr[1] ) != 'h' ) {
base = 2;
extra = 1;
goto done_scan;
}
digits_seen |= 1 << 11;
break;
case 'c':
digits_seen |= 1 << 12;
break;
case 'd':
if( base == 0
&& OK_NUM( DECIMAL )
&& !isxdigit( ptr[1] )
&& tolower( ptr[1] ) != 'h' ) {
if( !isalnum( ptr[1] ) && ptr[1] != '_' ) {
base = 10;
extra = 1;
}
goto done_scan;
}
digits_seen |= 1 << 13;
break;
case 'e': /* note that this could NOT be part of a float */
digits_seen |= 1 << 14;
break;
case 'f':
digits_seen |= 1U << 15;
break;
case 'y':
base = 2;
extra = 1;
goto done_scan;
case 'h':
base = 16;
extra = 1;
goto done_scan;
case 'o':
base = 8;
extra = 1;
goto done_scan;
case '.':
case 'r':
/* note that a float MUST contain a dot
* OR be ended with an "r"
* 1234e78 is NOT a valid float */
return( get_float( buf, input, output ) );
default:
goto done_scan;
}
++ptr;
}
done_scan:
if( digits_seen == 0 ) {
if( !first_char_0 ) {
return( get_string( buf, input, output ) );
}
digits_seen |= 1;
first_char_0 = FALSE;
dig_start = *input;
}
#if defined( _STANDALONE_ )
if( !Options.allow_c_octals ) {
first_char_0 = FALSE;
}
#endif
buf->token = T_NUM;
if( base == 0 ) {
base = first_char_0 ? 8 : 10;
}
switch( base ) {
case 10:
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?