From c3c7f10a4f6b55abbc5e577930ed59d94577cb59 Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Thu, 23 Jul 2020 15:53:46 +0200 Subject: asm-i386: started to work on const expressions, works again for pure integer/hex constants --- ecomp-c/asm-i386.c | 130 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 127 insertions(+), 3 deletions(-) diff --git a/ecomp-c/asm-i386.c b/ecomp-c/asm-i386.c index fc91130..3cb6ff1 100644 --- a/ecomp-c/asm-i386.c +++ b/ecomp-c/asm-i386.c @@ -90,6 +90,8 @@ typedef enum { S_rbrak, S_plus, S_minus, + S_star, + S_slash, S_eof } S_Symbol; @@ -108,6 +110,8 @@ static char *symname[S_eof+1] = { "]", "+", "-", + "*", + "/", "eof" }; @@ -395,6 +399,12 @@ static S_Symbol getSym( void ) case '+': s = S_plus; break; + case '*': + s = S_star; + break; + case '/': + s = S_slash; + break; case 'f': identifier( ); if( strcmp( ident, "format" ) == 0 ) { @@ -761,6 +771,7 @@ typedef struct OperandInfo { int addr; Symbol *symbol; struct OperandInfo *next; + struct ExpressionNode *node; } OperandInfo; typedef struct OpcodeInfo { @@ -997,6 +1008,116 @@ static void assign_label( OperandInfo *operand_info, char *label ) } } +typedef enum ExpressionNodeType { + EXPRESSION_NODE_TYPE_CONST, + EXPRESSION_NODE_TYPE_VAR, + EXPRESSION_NODE_TYPE_OP +} ExpressionNodeType; + +typedef struct ExpressionNode { + ExpressionNodeType type; + S_Symbol op; + struct ExpressionNode *left, *right; + int integer_value; + Symbol *symbol; +} ExpressionNode; + +static ExpressionNode *create_expression_node( void ) +{ + ExpressionNode *node = Allocate( sizeof( ExpressionNode ) ); + node->left = NULL; + node->right = NULL; + + return node; +} + +static void free_expression_node( ExpressionNode *node ) +{ + if( node->left != NULL ) { + free_expression_node( node->left ); + } + if( node->right != NULL ) { + free_expression_node( node->right ); + } + free( node ); +} + +static ExpressionNode *parseFactor( void ) +{ + Symbol *symbol; + ExpressionNode *node = NULL; + + if( sym == S_number ) { + node = create_expression_node( ); + node->type = EXPRESSION_NODE_TYPE_CONST; + node->integer_value = num; + sym = getSym( ); + } else if( sym == S_ident ) { + symbol = get_symbol( ident ); + if( symbol == NULL ) { + Abort( "Unknown identifier '%s'", ident ); + } + node = create_expression_node( ); + node->type = EXPRESSION_NODE_TYPE_VAR; + node->symbol = symbol; + sym = getSym( ); + } else { + Abort( "Expected a literal, a variable or a constant." ); + } + + return node; +} + +static ExpressionNode *parseTerm( void ) +{ + ExpressionNode *node, *tmp; + + node = parseFactor( ); + + while( sym == S_star || sym == S_slash ) { + tmp = node; + node = create_expression_node( ); + node->type = EXPRESSION_NODE_TYPE_OP; + node->op = sym; + sym = getSym( ); + node->left = tmp; + node->right = parseFactor( ); + } + + return node; +} + +static ExpressionNode *parseExpression( void ) +{ + ExpressionNode *node, *tmp; + + node = parseTerm( ); + while( sym == S_plus || sym == S_minus ) { + tmp = node; + node = create_expression_node( ); + node->type = EXPRESSION_NODE_TYPE_OP; + node->op = sym; + sym = getSym( ); + node->left = tmp; + node->right = parseTerm( ); + } + + return node; +} + +static int evaluate_const_expression_as_integer( ExpressionNode *node ) +{ + switch( node->type ) { + case EXPRESSION_NODE_TYPE_CONST: + return node->integer_value; + case EXPRESSION_NODE_TYPE_VAR: + case EXPRESSION_NODE_TYPE_OP: + Abort( "Const node expression node not implemented yet" ); + } + + return 0; +} + static OperandInfo *parseOperand( OpcodeInfo *opcode_info ) { OperandInfo *operand_info; @@ -1018,10 +1139,13 @@ static OperandInfo *parseOperand( OpcodeInfo *opcode_info ) } sym = getSym( ); } else if( sym == S_number ) { - /* absolute operand, like in mov eax, $1 */ + /* absolute operand, like in mov eax, $1, + * we have assemble-time expressions here + */ operand_info->type = OPERAND_ABSOLUTE; - operand_info->num = num; - sym = getSym( ); + operand_info->node = parseExpression( ); + operand_info->num = evaluate_const_expression_as_integer( operand_info->node ); + free_expression_node( operand_info->node ); } else if( sym == S_string ) { operand_info->type = OPERAND_ABSOLUTE; operand_info->str = AllocateAndCopyStr( str ); -- cgit v1.2.3-54-g00ecf