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.c122
1 files changed, 66 insertions, 56 deletions
diff --git a/ecomp-c/ec.c b/ecomp-c/ec.c
index 6a8907c..4243a93 100644
--- a/ecomp-c/ec.c
+++ b/ecomp-c/ec.c
@@ -686,7 +686,6 @@ typedef struct Scope {
} Scope;
static Scope *global_scope;
-static Scope *current_scope;
static Scope *create_scope( Scope *parent, char *name )
{
@@ -1169,7 +1168,7 @@ static ExpressionNode *parseFactor( Scope *scope )
node->actual_type = character_type;
sym = getSym( );
} else if( sym == S_ident ) {
- symbol = get_symbol( current_scope, ident );
+ symbol = get_symbol( scope, ident );
if( symbol == NULL ) {
Abort( "Unknown identifier '%s'", ident );
}
@@ -1307,7 +1306,7 @@ static ExpressionNode *parseExpression( Scope *scope )
node->right = parseSimpleExpression( scope );
if( node->left->actual_type == node->right->actual_type ) {
- node->actual_type = get_symbol( current_scope, "boolean" );
+ node->actual_type = get_symbol( scope, "boolean" );
} else {
Abort( "Incompatible types in expression: '%s' on the left, '%s' on the right",
node->left->actual_type->name, node->right->actual_type->name );
@@ -1322,7 +1321,7 @@ static void parseAssignment( Scope *scope )
Symbol *symbol;
ExpressionNode *node, *lhs, *rhs;
- symbol = get_symbol( current_scope, ident );
+ symbol = get_symbol( scope, ident );
if( symbol == NULL ) {
Abort( "Unknown variable '%s'", ident );
}
@@ -1534,7 +1533,7 @@ static void parseStatementBlock( Scope *scope )
}
/* TODO: implement simple expression and later complex expression */
-static ExpressionNode *parseConstExpression( void )
+static ExpressionNode *parseConstExpression( Scope *scope )
{
ExpressionNode *node;
char typeName[MAX_IDENT_LEN+1];
@@ -1558,16 +1557,16 @@ static ExpressionNode *parseConstExpression( void )
node->string_value = AllocateAndCopyStr( str );
len = strlen( str );
snprintf( typeName, MAX_IDENT_LEN, "array %d of %s", len + 1, character_type->name );
- type = get_symbol( current_scope, typeName );
+ type = get_symbol( scope, typeName );
if( type == NULL ) {
- type = insert_symbol( current_scope, typeName, SYMBOL_CLASS_ARRAY_TYPE );
+ type = insert_symbol( scope, typeName, SYMBOL_CLASS_ARRAY_TYPE );
type->dim = len + 1;
type->type = character_type;
}
node->actual_type = type;
sym = getSym( );
} else if( sym == S_ident ) {
- Symbol *symbol = get_symbol( current_scope, ident );
+ Symbol *symbol = get_symbol( scope, ident );
if( symbol == NULL ) {
Abort( "Constant '%s' is unknown", ident );
}
@@ -1718,9 +1717,9 @@ static void symbol_copy_from_node( ExpressionNode *from, Symbol *to )
}
}
-static Symbol *parseSimpleType( Scope *current_scope )
+static Symbol *parseSimpleType( Scope *scope )
{
- Symbol *type = get_symbol( current_scope, ident );
+ Symbol *type = get_symbol( scope, ident );
if( type == NULL ) {
Abort( "Unknown type '%s'", ident );
@@ -1735,9 +1734,9 @@ static Symbol *parseSimpleType( Scope *current_scope )
return type;
}
-static Symbol *parseType( Scope *current_scope );
+static Symbol *parseType( Scope *scope );
-static Symbol *parseArrayType( Scope *current_scope )
+static Symbol *parseArrayType( Scope *scope )
{
char typeName[MAX_IDENT_LEN+1];
Symbol *type, *simple = NULL;
@@ -1747,7 +1746,7 @@ static Symbol *parseArrayType( Scope *current_scope )
Expect( S_array );
if( sym != S_of ) {
- node = parseConstExpression( );
+ node = parseConstExpression( scope );
if( !is_compatible_type( node->actual_type, integer_type ) ) {
Abort( "Dimension of an array declaration must be of type '%s', not '%s'",
integer_type->name, node->actual_type->name );
@@ -1757,13 +1756,13 @@ static Symbol *parseArrayType( Scope *current_scope )
Expect( S_of );
- simple = parseSimpleType( current_scope );
+ simple = parseSimpleType( scope );
snprintf( typeName, MAX_IDENT_LEN, "array %d of %s", num, simple->name );
- type = get_symbol( current_scope, typeName );
+ type = get_symbol( scope, typeName );
if( type == NULL ) {
- type = insert_symbol( current_scope, typeName, SYMBOL_CLASS_ARRAY_TYPE );
+ type = insert_symbol( scope, typeName, SYMBOL_CLASS_ARRAY_TYPE );
type->dim = num;
type->type = simple;
}
@@ -1771,20 +1770,20 @@ static Symbol *parseArrayType( Scope *current_scope )
return type;
}
-static Symbol *parseType( Scope *current_scope )
+static Symbol *parseType( Scope *scope )
{
Symbol *type;
if( sym == S_array ) {
- type = parseArrayType( current_scope );
+ type = parseArrayType( scope );
} else {
- type = parseSimpleType( current_scope );
+ type = parseSimpleType( scope );
}
return type;
}
-static void parseConstDeclaration( Scope *current_scope )
+static void parseConstDeclaration( Scope *scope )
{
int nof_constants = 0;
Symbol *constant[MAX_NUMBER_OF_ENUMERATIONS], *type;
@@ -1800,18 +1799,18 @@ static void parseConstDeclaration( Scope *current_scope )
if( nof_constants >= MAX_NUMBER_OF_ENUMERATIONS ) {
Abort( "Too many enumerations in const declaration" );
}
- constant[nof_constants] = insert_symbol( current_scope, ident, SYMBOL_CLASS_CONSTANT );
+ constant[nof_constants] = insert_symbol( scope, ident, SYMBOL_CLASS_CONSTANT );
nof_constants++;
sym = getSym( );
} while( sym == S_comma );
Expect( S_colon );
- type = parseType( current_scope );
+ type = parseType( scope );
Expect( S_equals );
- node = parseConstExpression( );
+ node = parseConstExpression( scope );
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 );
@@ -1829,14 +1828,14 @@ static void parseConstDeclaration( Scope *current_scope )
free_expression_node( node );
}
-static void parseConstBlock( Scope *current_scope )
+static void parseConstBlock( Scope *scope )
{
Expect( S_const );
- parseConstDeclaration( current_scope );
+ parseConstDeclaration( scope );
while( sym == S_semicolon ) {
sym = getSym( );
if( sym == S_ident ) {
- parseConstDeclaration( current_scope );
+ parseConstDeclaration( scope );
} else if( sym == S_begin || sym == S_var || sym == S_procedure ) {
return;
} else {
@@ -1845,7 +1844,7 @@ static void parseConstBlock( Scope *current_scope )
}
}
-static void parseVariableDeclaration( Scope *current_scope )
+static void parseVariableDeclaration( Scope *scope )
{
int nof_variables = 0;
Symbol *variable[MAX_NUMBER_OF_ENUMERATIONS], *type;
@@ -1861,18 +1860,18 @@ static void parseVariableDeclaration( Scope *current_scope )
if( nof_variables >= MAX_NUMBER_OF_ENUMERATIONS ) {
Abort( "Too many enumerations in variable declaration" );
}
- variable[nof_variables] = insert_symbol( current_scope, ident, SYMBOL_CLASS_VARIABLE );
+ variable[nof_variables] = insert_symbol( scope, ident, SYMBOL_CLASS_VARIABLE );
nof_variables++;
sym = getSym( );
} while( sym == S_comma );
Expect( S_colon );
- type = parseType( current_scope );
+ type = parseType( scope );
if( sym == S_assign ) {
sym = getSym( );
- node = parseConstExpression( );
+ node = parseConstExpression( scope );
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 );
@@ -1905,14 +1904,14 @@ static void parseVariableDeclaration( Scope *current_scope )
}
}
-static void parseVariableBlock( Scope *current_scope )
+static void parseVariableBlock( Scope *scope )
{
Expect( S_var );
- parseVariableDeclaration( current_scope );
+ parseVariableDeclaration( scope );
while( sym == S_semicolon ) {
sym = getSym( );
if( sym == S_ident ) {
- parseVariableDeclaration( current_scope );
+ parseVariableDeclaration( scope );
} else if( sym == S_begin || sym == S_procedure ) {
return;
} else {
@@ -1921,7 +1920,17 @@ static void parseVariableBlock( Scope *current_scope )
}
}
-static void parseProcedureBlock( Scope *current_scope )
+static void parseProcedureDeclarationBlock( Scope *scope )
+{
+ if( sym == S_const ) {
+ parseConstBlock( scope );
+ }
+ if( sym == S_var ) {
+ parseVariableBlock( scope );
+ }
+}
+
+static void parseProcedureBlock( Scope *scope )
{
char *procedure_label;
Symbol *symbol;
@@ -1929,34 +1938,36 @@ static void parseProcedureBlock( Scope *current_scope )
Expect( S_procedure );
Expect( S_ident );
- procedure_label = get_scoped_label( current_scope, ident );
+ procedure_label = get_scoped_label( scope, ident );
Emit( "; PROC %s\n", ident );
- symbol = insert_symbol( current_scope, ident, SYMBOL_CLASS_PROCEDURE_TYPE );
+ symbol = insert_symbol( scope, ident, SYMBOL_CLASS_PROCEDURE_TYPE );
symbol->label = procedure_label;
- Emit( "%s:\n", procedure_label );
-
Expect( S_semicolon );
- parseStatementBlock( current_scope );
+
+ parseProcedureDeclarationBlock( scope );
+
+ Emit( "%s:\n", procedure_label );
+ parseStatementBlock( scope );
Emit( "ret\n" );
}
-static void parseDeclarationBlock( Scope *current_scope )
+static void parseDeclarationBlock( Scope *scope )
{
if( sym == S_const ) {
- parseConstBlock( current_scope );
+ parseConstBlock( scope );
}
if( sym == S_var ) {
- parseVariableBlock( current_scope );
+ parseVariableBlock( scope );
}
while( sym == S_procedure ) {
- parseProcedureBlock( current_scope );
+ parseProcedureBlock( scope );
}
}
-static void parseModule( Scope *current_scope )
+static void parseModule( Scope *scope )
{
char *entry_label;
@@ -1965,33 +1976,33 @@ static void parseModule( Scope *current_scope )
if( sym == S_ident ) {
strlcpy( moduleName, ident, MAX_IDENT_LEN );
}
- entry_label = get_local_label( current_scope );
+ entry_label = get_local_label( scope );
Emit( "jmp %s\n", entry_label );
Expect( S_semicolon );
- parseDeclarationBlock( current_scope );
+ parseDeclarationBlock( scope );
Emit( "%s:\n", entry_label );
- parseStatementBlock( current_scope );
+ parseStatementBlock( scope );
}
static void register_internal_types( Scope *scope )
{
Symbol *const_symbol;
- integer_type = insert_symbol( current_scope, "integer", SYMBOL_CLASS_SIMPLE_TYPE );
+ integer_type = insert_symbol( scope, "integer", SYMBOL_CLASS_SIMPLE_TYPE );
integer_type->size = 4;
- boolean_type = insert_symbol( current_scope, "boolean", SYMBOL_CLASS_SIMPLE_TYPE );
+ boolean_type = insert_symbol( scope, "boolean", SYMBOL_CLASS_SIMPLE_TYPE );
boolean_type->size = 1;
- const_symbol = insert_symbol( current_scope, "false", SYMBOL_CLASS_CONSTANT );
+ const_symbol = insert_symbol( scope, "false", SYMBOL_CLASS_CONSTANT );
const_symbol->type = boolean_type;
const_symbol->boolean_value = 0;
- const_symbol = insert_symbol( current_scope, "true", SYMBOL_CLASS_CONSTANT );
+ const_symbol = insert_symbol( scope, "true", SYMBOL_CLASS_CONSTANT );
const_symbol->type = boolean_type;
const_symbol->boolean_value = 1;
- character_type = insert_symbol( current_scope, "character", SYMBOL_CLASS_SIMPLE_TYPE );
+ character_type = insert_symbol( scope, "character", SYMBOL_CLASS_SIMPLE_TYPE );
character_type->size = 1;
}
@@ -2002,9 +2013,8 @@ static void init( void )
look = getChar( );
global_scope = create_scope( NULL, "global" );
- current_scope = global_scope;
- register_internal_types( current_scope );
+ register_internal_types( global_scope );
sym = getSym( );
}
@@ -2089,7 +2099,7 @@ static void epilogue( void )
Symbol *symbol;
Emit( "hlt\n" );
- symbol = current_scope->symbol;
+ symbol = global_scope->symbol;
while( symbol != NULL ) {
if( symbol->class == SYMBOL_CLASS_VARIABLE ) {
Emit( "%s: ", symbol->name );
@@ -2101,7 +2111,7 @@ static void epilogue( void )
static void deinit( void )
{
- free_scope( current_scope );
+ free_scope( global_scope );
}
int main( void )