diff options
Diffstat (limited to 'ecomp-c/ec.c')
-rw-r--r-- | ecomp-c/ec.c | 71 |
1 files changed, 46 insertions, 25 deletions
diff --git a/ecomp-c/ec.c b/ecomp-c/ec.c index 46ee4b4..5b72bfc 100644 --- a/ecomp-c/ec.c +++ b/ecomp-c/ec.c @@ -911,11 +911,22 @@ static int get_size( Symbol *symbol ); static void EmitArrayAddress( Symbol *array ) { + /* expecting result of expression (the array index) on top of the stack + * and an array symbol */ Emit( "pop eax\n" ); Emit( "mov ebx, %d\n", get_size( array->type->type ) ); Emit( "mul ebx\n" ); Emit( "push eax\n" ); - Emit( "mov eax, %s\n", array->name ); + if( array->offset == 0 ) { + /* global variable */ + Emit( "mov eax, %s\n", array->name ); + } else { + /* local variable */ + Emit( "push ebp\n" ); + Emit( "pop eax\n" ); + Emit( "mov ebx, %d\n", array->offset ); + Emit( "sub eax, ebx\n" ); + } Emit( "pop ebx\n" ); Emit( "add eax, ebx\n" ); Emit( "push eax\n" ); @@ -1003,7 +1014,7 @@ static int get_size( Symbol *symbol ) case SYMBOL_CLASS_SIMPLE_TYPE: return symbol->size; case SYMBOL_CLASS_ARRAY_TYPE: - return symbol->dim * symbol->size; + return symbol->dim * get_size( symbol->type ); default: Abort( "No size for class '%d", symbol->class ); } @@ -2023,14 +2034,16 @@ static void parseProcedureBlock( Scope *scope ) parseProcedureDeclarationBlock( symbol->scope ); /* compute sizes of all locals */ - offset = 4; + offset = 0; scope->size_locals = 0; sym = symbol->scope->symbol; while( sym != NULL ) { if( sym->class == SYMBOL_CLASS_VARIABLE ) { int size = get_size( sym ); scope->size_locals += size; - sym->offset = offset; + sym->offset = offset + size; + Emit( "; local %s, offset: %d, size: %d\n", + sym->name, sym->offset, size ); offset += size; } sym = sym->next; @@ -2049,27 +2062,35 @@ static void parseProcedureBlock( Scope *scope ) if( sym->class == SYMBOL_CLASS_VARIABLE ) { /* TODO: use type here! */ int size = get_size( sym ); - switch( size ) { - case 4: - /* TODO: cleanup local global variable access */ - Emit( "push ebp\n" ); - Emit( "pop ebx\n" ); - Emit( "mov eax, %d\n", sym->offset ); - Emit( "sub ebx, eax\n" ); - Emit( "mov eax, %d\n", sym->integer_value ); - Emit( "mov [ebx], eax\n" ); - break; - case 1: - /* TODO: cleanup local global variable access */ - Emit( "push ebp\n" ); - Emit( "pop ebx\n" ); - Emit( "mov eax, %d\n", sym->offset ); - Emit( "sub ebx, eax\n" ); - Emit( "mov eax, %d\n", sym->boolean_value ); - Emit( "mov [ebx], al\n" ); - break; - default: - Abort( "Not handled case when initializing local variable '%s' on stack", symbol->name ); + if( sym->type == integer_type || sym->type == boolean_type ) { + switch( size ) { + case 4: + /* TODO: cleanup local global variable access */ + Emit( "push ebp\n" ); + Emit( "pop ebx\n" ); + Emit( "mov eax, %d\n", sym->offset ); + Emit( "sub ebx, eax\n" ); + Emit( "mov eax, %d\n", sym->integer_value ); + Emit( "mov [ebx], eax\n" ); + break; + case 1: + /* TODO: cleanup local global variable access */ + Emit( "push ebp\n" ); + Emit( "pop ebx\n" ); + Emit( "mov eax, %d\n", sym->offset ); + Emit( "sub ebx, eax\n" ); + Emit( "mov eax, %d\n", sym->boolean_value ); + Emit( "mov [ebx], al\n" ); + break; + default: + Abort( "Unhandled case when initializing local variable '%s' of primitive type on stack", sym->name ); + } + } else if( sym->type->class == SYMBOL_CLASS_ARRAY_TYPE ) { + /* TODO: we would need an internal memset here + * memset( ebp + offset, get_size, 0 ) + */ + } else { + Abort( "Unhandled case when initializing local variable '%s' of complex type on stack", sym->name ); } } sym = sym->next; |