diff options
Diffstat (limited to 'ecomp-c/asm-i386.c')
-rw-r--r-- | ecomp-c/asm-i386.c | 49 |
1 files changed, 40 insertions, 9 deletions
diff --git a/ecomp-c/asm-i386.c b/ecomp-c/asm-i386.c index 3cb6ff1..a0a65a7 100644 --- a/ecomp-c/asm-i386.c +++ b/ecomp-c/asm-i386.c @@ -70,8 +70,8 @@ enum { }; static int DEBUG_GETCHAR = 0; -static int DEBUG_SCANNER = 1; -static int DEBUG_PARSER = 1; +static int DEBUG_SCANNER = 0; +static int DEBUG_PARSER = 0; /* scanner */ @@ -92,6 +92,8 @@ typedef enum { S_minus, S_star, S_slash, + S_current_org, + S_current_addr, S_eof } S_Symbol; @@ -112,6 +114,8 @@ static char *symname[S_eof+1] = { "-", "*", "/", + "$$", + "$", "eof" }; @@ -203,6 +207,11 @@ static int getChar( void ) return c; } +static void ungetChar( int c ) +{ + ungetc( c, stdin ); +} + static int isWhite( int c ) { if( c == ' ' || c == '\r' || c == '\t' ) return 1; @@ -373,8 +382,18 @@ static S_Symbol getSym( void ) s = S_newline; break; case '$': - hexnumber( ); - s = S_number; + look = getChar( ); + if( look == '$' ) { + s = S_current_org; + } else if( ( look >= '0' && look <= '9' ) || + ( look >= 'a' && look <= 'f' ) || + ( look >= 'A' && look <= 'F' ) ) { + ungetChar( look ); + s = S_number; + hexnumber( ); + } else { + s = S_current_addr; + } break; case '\"': string( ); @@ -612,7 +631,9 @@ typedef struct Symbol { struct Symbol *symbol = NULL; enum { - ADDRESS_UNDEFINED = 0x7FFFFFFF + ADDRESS_UNDEFINED = 0x7FFFFFFF, + ADDRESS_CURRENT_ORG = 0x7FFFFFFE, + ADDRESS_CURRENT_ADDR = 0x7FFFFFFD }; static Symbol *get_symbol( char *name ) @@ -1060,7 +1081,17 @@ static ExpressionNode *parseFactor( void ) node = create_expression_node( ); node->type = EXPRESSION_NODE_TYPE_VAR; node->symbol = symbol; - sym = getSym( ); + sym = getSym( ); + } else if( sym == S_current_org ) { + node = create_expression_node( ); + node->type = EXPRESSION_NODE_TYPE_CONST; + node->integer_value = ADDRESS_CURRENT_ORG; + sym = getSym( ); + } else if( sym == S_current_addr ) { + node = create_expression_node( ); + node->type = EXPRESSION_NODE_TYPE_CONST; + node->integer_value = ADDRESS_CURRENT_ADDR; + sym = getSym( ); } else { Abort( "Expected a literal, a variable or a constant." ); } @@ -1105,7 +1136,7 @@ static ExpressionNode *parseExpression( void ) return node; } -static int evaluate_const_expression_as_integer( ExpressionNode *node ) +static int evaluateExpression( ExpressionNode *node ) { switch( node->type ) { case EXPRESSION_NODE_TYPE_CONST: @@ -1138,13 +1169,13 @@ static OperandInfo *parseOperand( OpcodeInfo *opcode_info ) assign_label( operand_info, ident ); } sym = getSym( ); - } else if( sym == S_number ) { + } else if( sym == S_number || sym == S_current_org || sym == S_current_addr ) { /* absolute operand, like in mov eax, $1, * we have assemble-time expressions here */ operand_info->type = OPERAND_ABSOLUTE; operand_info->node = parseExpression( ); - operand_info->num = evaluate_const_expression_as_integer( operand_info->node ); + operand_info->num = evaluateExpression( operand_info->node ); free_expression_node( operand_info->node ); } else if( sym == S_string ) { operand_info->type = OPERAND_ABSOLUTE; |