summaryrefslogtreecommitdiff
path: root/ecomp-c/asm-i386.c
diff options
context:
space:
mode:
Diffstat (limited to 'ecomp-c/asm-i386.c')
-rw-r--r--ecomp-c/asm-i386.c49
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;