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