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.c111
1 files changed, 98 insertions, 13 deletions
diff --git a/ecomp-c/ec.c b/ecomp-c/ec.c
index c98c766..46ee4b4 100644
--- a/ecomp-c/ec.c
+++ b/ecomp-c/ec.c
@@ -692,6 +692,7 @@ typedef struct Scope {
int label_no;
struct Symbol *symbol;
struct Scope *parent;
+ int size_locals;
} Scope;
static Scope *global_scope;
@@ -1028,10 +1029,28 @@ static void emit_expression_code( ExpressionNode *node, Scope *scope )
case EXPRESSION_NODE_TYPE_VAR:
switch( get_size( node->symbol ) ) {
case 4:
- Emit( "mov eax, [%s]\n", node->symbol->name );
+ /* TODO: cleanup local global variable access */
+ if( node->symbol->offset == 0 ) {
+ Emit( "mov eax, [%s]\n", node->symbol->name );
+ } else {
+ Emit( "push ebp\n" );
+ Emit( "pop ebx\n" );
+ Emit( "mov eax, %d\n", node->symbol->offset );
+ Emit( "sub ebx, eax\n" );
+ Emit( "mov eax, [ebx]\n" );
+ }
break;
case 1:
- Emit( "mov al, [%s]\n", node->symbol->name );
+ /* TODO: cleanup local global variable access */
+ if( node->symbol->offset == 0 ) {
+ Emit( "mov al, [%s]\n", node->symbol->name );
+ } else {
+ Emit( "push ebp\n" );
+ Emit( "pop ebx\n" );
+ Emit( "mov eax, %d\n", node->symbol->offset );
+ Emit( "sub ebx, eax\n" );
+ Emit( "mov al, [ebx]\n" );
+ }
break;
default:
Abort( "Unhandled size %d when reading register from memory", node->symbol->size );
@@ -1355,14 +1374,35 @@ static void parseAssignment( Scope *scope )
Emit( "\n" );
emit_expression_code( node, scope );
- Emit( "pop eax\n" );
switch( get_size( symbol ) ) {
case 4:
- Emit( "mov [%s], eax\n", symbol->name );
+ /* TODO: cleanup local global variable access */
+ if( symbol->offset == 0 ) {
+ Emit( "pop eax\n" );
+ Emit( "mov [%s], eax\n", symbol->name );
+ } else {
+ Emit( "push ebp\n" );
+ Emit( "pop ebx\n" );
+ Emit( "mov eax, %d\n", symbol->offset );
+ Emit( "sub ebx, eax\n" );
+ Emit( "pop eax\n" );
+ Emit( "mov [ebx], eax\n" );
+ }
break;
case 1:
- Emit( "mov [%s], al\n", symbol->name );
+ /* TODO: cleanup local global variable access */
+ if( symbol->offset == 0 ) {
+ Emit( "pop eax\n" );
+ Emit( "mov [%s], al\n", symbol->name );
+ } else {
+ Emit( "push ebp\n" );
+ Emit( "pop ebx\n" );
+ Emit( "mov eax, %d\n", symbol->offset );
+ Emit( "sub ebx, eax\n" );
+ Emit( "pop eax\n" );
+ Emit( "mov [ebx], al\n" );
+ }
break;
default:
Abort( "Unhandled size %d when storing register immediately to memory", symbol->size );
@@ -1962,7 +2002,7 @@ static void parseProcedureBlock( Scope *scope )
if( sym == S_const || sym == S_var || sym == S_begin ) {
Symbol *sym;
- int size_locals;
+ int offset;
Emit( "; PROC %s\n", symbol->name );
@@ -1982,30 +2022,75 @@ static void parseProcedureBlock( Scope *scope )
parseProcedureDeclarationBlock( symbol->scope );
- size_locals = 0;
+ /* compute sizes of all locals */
+ offset = 4;
+ scope->size_locals = 0;
sym = symbol->scope->symbol;
while( sym != NULL ) {
if( sym->class == SYMBOL_CLASS_VARIABLE ) {
- size_locals += get_size( sym );
+ int size = get_size( sym );
+ scope->size_locals += size;
+ sym->offset = offset;
+ offset += size;
}
sym = sym->next;
}
- if( size_locals > 0 ) {
- Emit( "mov eax, %d\n", size_locals );
+ /* reserve space on stack */
+ if( scope->size_locals > 0 ) {
+ Emit( "mov eax, %d\n", scope->size_locals );
Emit( "sub esp, eax\n" );
}
+ /* initialize local variables (sort of reserve_initialize_local)
+ * at runtime (every time the stack is created for that procedure) */
+ sym = symbol->scope->symbol;
+ while( sym != NULL ) {
+ 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 );
+ }
+ }
+ sym = sym->next;
+ }
+
/* TODO: allocate space on stack for local variables (and
* parameters) */
/* TODO: assign symbols to relative addresses (base pointer) */
/* TODO: initialize local variables */
parseStatementBlock( symbol->scope );
-
- free_scope( symbol->scope );
-
+
/* discard locals, reset base pointer */
+
+ if( scope->size_locals > 0 ) {
+ Emit( "mov eax, %d\n", scope->size_locals );
+ Emit( "add esp, eax\n" );
+ }
+
+ free_scope( symbol->scope );
+
Emit( "pop ebp\n" );
Emit( "ret\n" );