diff options
author | Andreas Baumann <mail@andreasbaumann.cc> | 2020-06-20 19:30:13 +0200 |
---|---|---|
committer | Andreas Baumann <mail@andreasbaumann.cc> | 2020-06-20 19:30:13 +0200 |
commit | c35a3209434122adfce3159210cdaef380c1e952 (patch) | |
tree | f46029e8c2eb7e5f6684c76e8ed4390869a87f70 | |
parent | e65aa4b6f359327c142d099328c23197857593ac (diff) | |
download | compilertests-c35a3209434122adfce3159210cdaef380c1e952.tar.gz compilertests-c35a3209434122adfce3159210cdaef380c1e952.tar.bz2 |
first version of array dereferncing (read and write) using the stack
-rw-r--r-- | ecomp-c/ec.c | 72 | ||||
-rw-r--r-- | ecomp-c/test1.e | 11 |
2 files changed, 45 insertions, 38 deletions
diff --git a/ecomp-c/ec.c b/ecomp-c/ec.c index 8f40157..ac1632f 100644 --- a/ecomp-c/ec.c +++ b/ecomp-c/ec.c @@ -871,7 +871,7 @@ static void generate_expression_comment( ExpressionNode *node ) static int get_size( Symbol *symbol ); -static void EmitArrayDereference( Scope *scope, Symbol *array ) +static void EmitArrayAddress( Symbol *array ) { Emit( "pop eax\n" ); Emit( "mov ebx, %d\n", get_size( array->type->type ) ); @@ -883,6 +883,24 @@ static void EmitArrayDereference( Scope *scope, Symbol *array ) Emit( "push eax\n" ); } +static void EmitArrayDereference( Symbol *array ) +{ + EmitArrayAddress( array ); + Emit( "pop ebx\n" ); + switch( get_size( array->type->type ) ) { + case 4: + Emit( "mov eax, [ebx]\n" ); + Emit( "push eax\n" ); + break; + case 1: + Emit( "mov al, [ebx]\n" ); + Emit( "push eax\n" ); + break; + default: + Abort( "Unhandled size %d when retrieving register indirectly from memory", array->type->size ); + } +} + static void EmitConditionTest( Scope *scope, S_Symbol relation ) { char *jump_label1 = get_local_label( scope ); @@ -1086,6 +1104,14 @@ static void emit_expression_code( ExpressionNode *node, Scope *scope ) Emit( "%s:\n", jump_label ); Emit( "push eax\n" ); } break; + case S_lbracket: + if( !is_compatible_type( node->symbol->type->type, node->actual_type ) ) { + Abort( "Incompatible assignment of expression of type '%s' to variable '%s' of type '%s'", + node->actual_type->name, node->symbol->name, node->symbol->type->name ); + } + emit_expression_code( node->left, scope ); + EmitArrayDereference( node->symbol ); + break; default: Abort( "Unhandled operation '%s' when generating operation in expression tree!", symname[node->op] ); } @@ -1143,37 +1169,17 @@ static ExpressionNode *parseFactor( Scope *scope ) } sym = getSym( ); if( sym == S_lbracket ) { - ExpressionNode *expr; - Expect( S_lbracket ); if( symbol->type->class != SYMBOL_CLASS_ARRAY_TYPE ) { Abort( "Dereferencing non-array '%s'", symbol->name ); } - expr = parseExpression( scope ); - - /* HERE */ - emit_expression_code( expr, scope ); - - EmitArrayDereference( scope, symbol ); - -/* TODO: the right code, but in the wrong place as we should add - * array dereference as expression node into the AST and generate - * the dereferencing code much later when traversing the tree - * - if( !is_compatible_type( symbol->type->type, rhs->actual_type ) ) { - Abort( "Incompatible assignment of expression of type '%s' to variable '%s' of type '%s'", - rhs->actual_type->name, symbol->name, symbol->type->name ); - } - - emit_expression_code( rhs, scope ); - Emit( "pop eax\n" ); - - Emit( "pop ebx\n" ); -*/ - - free_expression_node( expr ); - - Expect( S_rbracket ); + node = create_expression_node( ); + node->type = EXPRESSION_NODE_TYPE_OP; + node->op = S_lbracket; + node->left = parseExpression( scope ); + node->symbol = symbol; + node->actual_type = symbol->type->type; + Expect( S_rbracket ); } } else if( sym == S_lparen ) { sym = getSym( ); @@ -1349,7 +1355,7 @@ static void parseAssignment( Scope *scope ) emit_expression_code( lhs, scope ); - EmitArrayDereference( scope, symbol ); + EmitArrayAddress( symbol ); if( !is_compatible_type( symbol->type->type, rhs->actual_type ) ) { Abort( "Incompatible assignment of expression of type '%s' to variable '%s' of type '%s'", @@ -1363,13 +1369,13 @@ static void parseAssignment( Scope *scope ) switch( get_size( symbol->type->type ) ) { case 4: - Emit( "mov [ebx], eax\n", symbol->name ); + Emit( "mov [ebx], eax\n" ); break; case 1: - Emit( "mov [ebx], al\n", symbol->name ); + Emit( "mov [ebx], al\n" ); break; default: - Abort( "Unhandled size %d when storing register indirectly to memory", symbol->size ); + Abort( "Unhandled size %d when storing register indirectly to memory", symbol->type->size ); } free_expression_node( rhs ); @@ -1546,7 +1552,7 @@ static void generate_symbol_comment( char *mode, Symbol *constant ) Emit( "'%c'", constant->character_value ); } else if( constant->type->class == SYMBOL_CLASS_ARRAY_TYPE ) { if( constant->type->type == character_type ) { - /* TODO: handl non-printables */ + /* TODO: handle non-printables */ Emit( "\"%s\"", constant->string_value ); } else { /* TODO: iterate all elements of basic type and issue value */ diff --git a/ecomp-c/test1.e b/ecomp-c/test1.e index d88c3de..e9e2cec 100644 --- a/ecomp-c/test1.e +++ b/ecomp-c/test1.e @@ -61,14 +61,15 @@ begin end; j := 'B'; - a1[4] := 42; - s1[0] := 'a'; - s[0] := 'H'; + s1[0] := ' '; + s[0] := 'X'; + s[1] := s[0]; + j := s[2]; i := 0; while i < 10 do a1[i] := i; i := i + 1; end; - s2[a1[2]] := 'X'; - //j := s2[1]; + a1[4] := 42; + s2[a1[2]] := 'Z'; end |