summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2020-08-20 15:12:14 +0200
committerAndreas Baumann <mail@andreasbaumann.cc>2020-08-20 15:12:14 +0200
commit102450c101cb1496c7e0eaf2240aa9e6a8bd90f2 (patch)
tree5340cd3143421f3c47a01f19e97a56b180db70b0
parentbfe947bbd5841142943e18e30b95439807d89478 (diff)
downloadcompilertests-102450c101cb1496c7e0eaf2240aa9e6a8bd90f2.tar.gz
compilertests-102450c101cb1496c7e0eaf2240aa9e6a8bd90f2.tar.bz2
got parameter type checking working properly
-rw-r--r--ecomp-c/ec.c108
-rw-r--r--ecomp-c/tests/procedure_call_value_parameters_wrong_types.easm48
-rw-r--r--ecomp-c/tests/procedure_call_value_parameters_wrong_types.ecomp_err1
3 files changed, 121 insertions, 36 deletions
diff --git a/ecomp-c/ec.c b/ecomp-c/ec.c
index 1e8dc63..7501ec5 100644
--- a/ecomp-c/ec.c
+++ b/ecomp-c/ec.c
@@ -681,6 +681,7 @@ typedef struct Symbol {
/* procedure type */
char *label;
struct Scope *scope;
+ struct Symbol *param;
} Symbol;
static Symbol *integer_type;
@@ -722,6 +723,15 @@ static void free_symbol( Symbol *sym )
if( sym->label != NULL ) {
free( sym->label );
}
+ if( sym->param != NULL ) {
+ Symbol *param, *tmp;
+ param = sym->param;
+ while( param != NULL ) {
+ tmp = param->next;
+ free_symbol( param );
+ param = tmp;
+ }
+ }
free( sym->name );
free( sym );
}
@@ -779,36 +789,61 @@ static Symbol *get_symbol( Scope *scope, char *name )
return NULL;
}
+static Symbol *create_symbol( char *name, SymbolClass class )
+{
+ Symbol *symbol;
+
+ symbol = Allocate( sizeof( Symbol ) );
+ symbol->class = class;
+ symbol->name = Allocate( strlen( name ) + 1 );
+ strlcpy( symbol->name, name, strlen( name ) + 1 );
+ symbol->size = 0;
+ symbol->offset = 0;
+ symbol->dim = 0;
+ symbol->string_value = NULL;
+ symbol->intarr_value = NULL;
+ symbol->type = NULL;
+ symbol->label = NULL;
+ symbol->param = NULL;
+
+ return symbol;
+}
+
+static Symbol *copy_symbol( Symbol *symbol )
+{
+ Symbol *copy;
+
+ copy = Allocate( sizeof( Symbol ) );
+ memcpy( copy, symbol, sizeof( Symbol ) );
+ copy->name = AllocateAndCopyStr( symbol->name );
+ copy->string_value = AllocateAndCopyStr( symbol->string_value );
+ copy->label = AllocateAndCopyStr( symbol->label );
+
+ return copy;
+}
+
static Symbol *insert_symbol( Scope *scope, char *name, SymbolClass class )
{
- Symbol *sym;
+ Symbol *symbol;
- sym = scope->symbol;
- while( sym != NULL ) {
- if( strcmp( sym->name, name ) == 0 ) {
- return sym;
+ symbol = scope->symbol;
+ while( symbol != NULL ) {
+ if( strcmp( symbol->name, name ) == 0 ) {
+ return symbol;
}
- sym = sym->next;
+ symbol = symbol->next;
}
- if( sym != NULL ) {
+ if( symbol != NULL ) {
Abort( "'%s' is already defined.", name );
}
+
+ symbol = create_symbol( name, class );
- sym = Allocate( sizeof( Symbol ) );
- sym->class = class;
- sym->name = Allocate( strlen( name ) + 1 );
- strlcpy( sym->name, name, strlen( name ) + 1 );
- sym->size = 0;
- sym->offset = 0;
- sym->dim = 0;
- sym->next = scope->symbol;
- sym->string_value = NULL;
- sym->intarr_value = NULL;
- sym->label = NULL;
- scope->symbol = sym;
+ symbol->next = scope->symbol;
+ scope->symbol = symbol;
scope->nof_symbols++;
- return sym;
+ return symbol;
}
static char moduleName[MAX_IDENT_LEN+1];
@@ -1582,11 +1617,9 @@ static void parseProcedureCall( Scope *scope )
symbol = get_symbol( scope, ident );
nof_expected_params = 0;
- param = symbol->scope->symbol;
+ param = symbol->param;
while( param != NULL ) {
- if( param->offset < 0 ) {
- nof_expected_params++;
- }
+ nof_expected_params++;
param = param->next;
}
@@ -1609,14 +1642,12 @@ static void parseProcedureCall( Scope *scope )
/* check types */
if( nof_expected_params > 0 ) {
node = head;
- param = symbol->scope->symbol;
+ param = symbol->param;
while( param != NULL ) {
- if( param->offset < 0 ) {
- param = param->next;
- continue;
+ if( !is_compatible_type( node->actual_type, param->type ) ) {
+ Abort( "Incompatible parameter type for parameter '%s' in procedure '%s', expecting type '%s', got '%s'",
+ param->name, symbol->name, param->type->name, node->actual_type->name );
}
- fprintf( stderr, "%s <?> %s\n", node->actual_type->name,
- symbol->scope->symbol->type->name );
node = node->next;
param = param->next;
}
@@ -2105,13 +2136,9 @@ static void parseParameterDeclaration( Scope *scope )
symbol = insert_symbol( scope, ident, SYMBOL_CLASS_VARIABLE );
sym = getSym( );
- /* TODO: allocate size for parameters on stack, make sure they
- * are allocated on the other side of the stack
- */
-
Expect( S_colon );
- symbol->type = parseType( scope );
+ symbol->type = parseType( scope );
}
static void parseParameterDeclarationList( Scope *scope )
@@ -2160,7 +2187,7 @@ static void parseProcedureDeclaration( Scope *scope )
size_params = 0;
} else if( sym == S_lparen ) {
- Symbol *param;
+ Symbol *param, *copy;
int offset;
parseParameterDeclarationList( symbol->scope );
@@ -2171,6 +2198,9 @@ static void parseProcedureDeclaration( Scope *scope )
param = symbol->scope->symbol;
+ /* compute size and offsets of parameter on the stack,
+ * also remember the types of the parameters for type
+ * checking when generating a produre call */
size_params = 0;
offset = -4;
while( param != NULL ) {
@@ -2182,6 +2212,12 @@ static void parseProcedureDeclaration( Scope *scope )
param->name, param->offset, size );
offset -= size;
}
+
+ copy = copy_symbol( param );
+ copy->scope = NULL;
+ copy->next = symbol->param;
+ symbol->param = copy;
+
param = param->next;
}
}
diff --git a/ecomp-c/tests/procedure_call_value_parameters_wrong_types.easm b/ecomp-c/tests/procedure_call_value_parameters_wrong_types.easm
new file mode 100644
index 0000000..d7fb8b4
--- /dev/null
+++ b/ecomp-c/tests/procedure_call_value_parameters_wrong_types.easm
@@ -0,0 +1,48 @@
+format binary
+use32
+org $1000000
+jmp __global_0
+; DECL i -> integer, 1
+; param x, offset: -8, size: 4
+; PROC proc
+__global_proc:
+push ebp
+push esp
+pop ebp
+; DECL l -> integer, 0
+; local l, offset: 4, size: 4
+mov eax, 4
+sub esp, eax
+push ebp
+pop ebx
+mov eax, 4
+sub ebx, eax
+mov eax, 0
+mov [ebx], eax
+; LET l <- x
+push ebp
+pop ebx
+mov eax, -8
+sub ebx, eax
+mov eax, [ebx]
+push eax
+push ebp
+pop ebx
+mov eax, 4
+sub ebx, eax
+pop eax
+mov [ebx], eax
+; LET i <- l
+push ebp
+pop ebx
+mov eax, 4
+sub ebx, eax
+mov eax, [ebx]
+push eax
+pop eax
+mov [i], eax
+mov eax, 4
+add esp, eax
+pop ebp
+ret 4
+__global_0:
diff --git a/ecomp-c/tests/procedure_call_value_parameters_wrong_types.ecomp_err b/ecomp-c/tests/procedure_call_value_parameters_wrong_types.ecomp_err
new file mode 100644
index 0000000..3ce59a7
--- /dev/null
+++ b/ecomp-c/tests/procedure_call_value_parameters_wrong_types.ecomp_err
@@ -0,0 +1 @@
+Error line 20, pos 1: Incompatible parameter type for parameter 'x' in procedure 'proc', expecting type 'integer', got 'boolean'