summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2020-06-20 19:30:13 +0200
committerAndreas Baumann <mail@andreasbaumann.cc>2020-06-20 19:30:13 +0200
commitc35a3209434122adfce3159210cdaef380c1e952 (patch)
treef46029e8c2eb7e5f6684c76e8ed4390869a87f70
parente65aa4b6f359327c142d099328c23197857593ac (diff)
downloadcompilertests-c35a3209434122adfce3159210cdaef380c1e952.tar.gz
compilertests-c35a3209434122adfce3159210cdaef380c1e952.tar.bz2
first version of array dereferncing (read and write) using the stack
-rw-r--r--ecomp-c/ec.c72
-rw-r--r--ecomp-c/test1.e11
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