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.c34
1 files changed, 29 insertions, 5 deletions
diff --git a/ecomp-c/ec.c b/ecomp-c/ec.c
index 275cec9..4da751d 100644
--- a/ecomp-c/ec.c
+++ b/ecomp-c/ec.c
@@ -742,6 +742,7 @@ static Symbol *insert_symbol( Scope *scope, char *name, SymbolClass class )
strlcpy( sym->name, name, strlen( name ) + 1 );
sym->initialized = 0;
sym->size = 0;
+ sym->dim = 0;
sym->next = scope->symbol;
sym->string_value = NULL;
scope->symbol = sym;
@@ -878,6 +879,25 @@ static void EmitConditionTest( Scope *scope, S_Symbol relation )
free( jump_label1 );
}
+static int is_compatible_type( Symbol *to, Symbol *from )
+{
+ if( to == from ) {
+ return 1;
+ }
+
+ if( to->class == SYMBOL_CLASS_ARRAY_TYPE &&
+ from->class == SYMBOL_CLASS_ARRAY_TYPE ) {
+ if( to->type == character_type &&
+ from->type == character_type ) {
+ if( to->dim >= from->dim ) {
+ return 1;
+ }
+ }
+ }
+
+ return 0;
+}
+
static int get_size( Symbol *symbol )
{
switch( symbol->class ) {
@@ -1213,7 +1233,7 @@ static void parseAssignment( Scope *scope )
node = parseExpression( );
- if( symbol->type != node->actual_type ) {
+ if( !is_compatible_type( symbol->type, node->actual_type ) ) {
Abort( "Incompatible assignment of expression of type '%s' to variable '%s' of type '%s'",
node->actual_type->name, symbol->name, symbol->type->name );
}
@@ -1424,8 +1444,7 @@ static void generate_variable_comment( Symbol *variable )
static void symbol_copy_value( Symbol *from, Symbol *to )
{
-
- if( from->type != to->type ) {
+ if( !is_compatible_type( from->type, to->type ) ) {
Abort( "type mismatch when copying symbol value (from: '%s', to: '%s')",
from->type->name, to->type->name );
}
@@ -1558,18 +1577,20 @@ static void parseConstDeclaration( Scope *current_scope )
Expect( S_equals );
node = parseConstExpression( );
- if( type != node->actual_type ) {
+ if( !is_compatible_type( type, node->actual_type ) ) {
Abort( "Assigning a constant of type '%s' from an expression of type '%s'",
type->name, node->actual_type->name );
}
if( node->type == EXPRESSION_NODE_TYPE_CONST ) {
for( i = 0; i < nof_constants; i++ ) {
+ /* TODO: type copying and type conversion */
constant[i]->type = node->actual_type;
symbol_copy_node_value( node, constant[i] );
}
} else if( node->type == EXPRESSION_NODE_TYPE_VAR ) {
for( i = 0; i < nof_constants; i++ ) {
+ /* TODO: type copying and type conversion */
constant[i]->type = node->symbol->type;
symbol_copy_value( node->symbol, constant[i] );
}
@@ -1626,18 +1647,20 @@ static void parseVariableDeclaration( Scope *current_scope )
if( sym == S_assign ) {
sym = getSym( );
node = parseConstExpression( );
- if( type != node->actual_type ) {
+ if( !is_compatible_type( type, node->actual_type ) ) {
Abort( "Assigning a variable of type '%s' from an expression of type '%s'",
type->name, node->actual_type->name );
}
if( node->type == EXPRESSION_NODE_TYPE_CONST ) {
for( i = 0; i < nof_variables; i++ ) {
+ /* TODO: type copying and type conversion */
variable[i]->type = node->actual_type;
symbol_copy_node_value( node, variable[i] );
}
} else if( node->type == EXPRESSION_NODE_TYPE_VAR ) {
for( i = 0; i < nof_variables; i++ ) {
+ /* TODO: type copying and type conversion */
variable[i]->type = node->symbol->type;
symbol_copy_value( node->symbol, variable[i] );
}
@@ -1648,6 +1671,7 @@ static void parseVariableDeclaration( Scope *current_scope )
variable[i]->integer_value = 0;
variable[i]->boolean_value = 0; /* false */
variable[i]->character_value = 0; /* NUL */
+ /* TODO: type copying and type conversion */
variable[i]->type = type;
}
}