summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2020-08-08 20:02:53 +0200
committerAndreas Baumann <mail@andreasbaumann.cc>2020-08-08 20:02:53 +0200
commit1da96894b6c25c3be9c1a1549befbfe1b8efd8a6 (patch)
tree8705e4e5666eb77b8cce5cc5720ed749ff957daf
parent6152ca4953bd23e1b6f7fd68966efc6b48e48361 (diff)
downloadcompilertests-1da96894b6c25c3be9c1a1549befbfe1b8efd8a6.tar.gz
compilertests-1da96894b6c25c3be9c1a1549befbfe1b8efd8a6.tar.bz2
more work on local variables
-rw-r--r--ecomp-c/ec.c111
-rw-r--r--ecomp-c/tests/procedure_local_variables.e6
-rw-r--r--ecomp-c/tests/procedure_scoping.easm10
3 files changed, 111 insertions, 16 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" );
diff --git a/ecomp-c/tests/procedure_local_variables.e b/ecomp-c/tests/procedure_local_variables.e
index 2838203..31373ea 100644
--- a/ecomp-c/tests/procedure_local_variables.e
+++ b/ecomp-c/tests/procedure_local_variables.e
@@ -5,18 +5,20 @@
module procedure_call;
var
- i : integer := 0;
+ i : integer := 1;
procedure proc;
+
const
C : integer = 42;
+
var
j : integer;
k : integer := C;
begin
j := i;
- i := k;
+ i := j;
end
begin
diff --git a/ecomp-c/tests/procedure_scoping.easm b/ecomp-c/tests/procedure_scoping.easm
index 72a9dfb..8f6dc6f 100644
--- a/ecomp-c/tests/procedure_scoping.easm
+++ b/ecomp-c/tests/procedure_scoping.easm
@@ -15,6 +15,8 @@ pop ebp
; DECL x -> array 2 of integer, array 2 of integer = { ... }
; DECL y -> array 3 of integer, array 3 of integer = { ... }
; DECL z -> integer, 0
+mov eax, 4
+sub esp, eax
; LET x[2 ] <- 3
mov eax, 2
push eax
@@ -34,8 +36,14 @@ mov [ebx], eax
; LET z <- 4
mov eax, 4
push eax
+push ebp
+pop ebx
+mov eax, 4
+sub ebx, eax
pop eax
-mov [z], eax
+mov [ebx], eax
+mov eax, 4
+add esp, eax
pop ebp
ret
; PROC B