summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2020-06-27 20:32:54 +0200
committerAndreas Baumann <mail@andreasbaumann.cc>2020-06-27 20:32:54 +0200
commit04614fca7cf56ba12aebe5af7ae69a6adaa56b6f (patch)
treef47521661ab32946b28db4e2b8cf76e5ddddf4ef
parent73e960a483aac72bf8a0301b577f2c7924183640 (diff)
downloadcompilertests-04614fca7cf56ba12aebe5af7ae69a6adaa56b6f.tar.gz
compilertests-04614fca7cf56ba12aebe5af7ae69a6adaa56b6f.tar.bz2
some cleanup around scoping, all const/var in procedures
-rw-r--r--ecomp-c/ec.c122
-rw-r--r--ecomp-c/minie.ebnf67
2 files changed, 101 insertions, 88 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 )
diff --git a/ecomp-c/minie.ebnf b/ecomp-c/minie.ebnf
index ed55e14..484572d 100644
--- a/ecomp-c/minie.ebnf
+++ b/ecomp-c/minie.ebnf
@@ -1,33 +1,36 @@
-Digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" .
-Letter = "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J" | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" | "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z" |
- "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" | "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z" .
-Special = "_" | " " .
-Identifier = Letter { Letter | Digit | "_" } .
-Number = Digit { Digit } .
-Character = "'" Digit | Letter | Special | "'" .
-String = """" { Character } """" .
+# scanner/lexer
+Digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" .
+Letter = "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J" | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" | "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z" |
+ "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" | "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z" .
+Special = "_" | " " .
+Identifier = Letter { Letter | Digit | "_" } .
+Number = Digit { Digit } .
+Character = "'" Digit | Letter | Special | "'" .
+String = """" { Character } """" .
-Factor = Number | Character | String | Identifier [ "[" Expression "]" ] | "(" Expression ")" | "not" Factor .
-Term = Factor { ( "*" | "/" | "mod" | "and" ) Factor } .
-SimpleExpression = Term { ( "+" | "-" | "or" ) Term } .
-RelationalOperator = "=" | "<>" | "<" | ">" | "<=" | ">=" .
-Expression = SimpleExpression [ RelationalOperator SimpleExpression ] .
-Assignment = Identifier [ "[" Expression "]" ] ":=" Expression .
-IfStatement = "if" Expression "do" StatementSequence "else" StatementSequence "end" .
-WhileStatement = "while" Expression "do" StatementSequence "end" .
-ProcedureCall = Identifier .
-Statement = Assignment | IfStatement | WhileStatement | ProcedureCall .
-StatementSequence = Statement { ";" Statement } .
-StatementBlock = "begin" StatementSequence "end" .
-SimpleType = Identifier .
-ArrayType = "array" [ ConstExpression ] "of" Type .
-Type = SimpleType | ArrayType .
-ConstExpression = ( Number | Identifier ) .
-ConstDeclaration = Identifier { "," Identifier } ":" Type "=" ConstExpression .
-ConstBlock = "const" { ConstDeclaration ";" } .
-VariableDeclaration = Identifier { "," Identifier } ":" Type [ ":=" ConstExpression ] .
-VariableBlock = "var" { VariableDeclaration ";" } .
-ProcedureDeclaration = "procedure" Identifier ";" StatementBlock .
-ProcedureBlock = { ProcedureDeclaration } .
-DeclarationBlock = [ ConstBlock ] [ VariableBlock ] [ ProcedureBlock ] .
-Module = "module" Identifier ";" DeclarationBlock StatementBlock .
+# parser
+Factor = Number | Character | String | Identifier [ "[" Expression "]" ] | "(" Expression ")" | "not" Factor .
+Term = Factor { ( "*" | "/" | "mod" | "and" ) Factor } .
+SimpleExpression = Term { ( "+" | "-" | "or" ) Term } .
+RelationalOperator = "=" | "<>" | "<" | ">" | "<=" | ">=" .
+Expression = SimpleExpression [ RelationalOperator SimpleExpression ] .
+Assignment = Identifier [ "[" Expression "]" ] ":=" Expression .
+IfStatement = "if" Expression "do" StatementSequence "else" StatementSequence "end" .
+WhileStatement = "while" Expression "do" StatementSequence "end" .
+ProcedureCall = Identifier .
+Statement = Assignment | IfStatement | WhileStatement | ProcedureCall .
+StatementSequence = Statement { ";" Statement } .
+StatementBlock = "begin" StatementSequence "end" .
+SimpleType = Identifier .
+ArrayType = "array" [ ConstExpression ] "of" Type .
+Type = SimpleType | ArrayType .
+ConstExpression = ( Number | Identifier ) .
+ConstDeclaration = Identifier { "," Identifier } ":" Type "=" ConstExpression .
+ConstBlock = "const" { ConstDeclaration ";" } .
+VariableDeclaration = Identifier { "," Identifier } ":" Type [ ":=" ConstExpression ] .
+VariableBlock = "var" { VariableDeclaration ";" } .
+ProcedureDeclaration = "procedure" Identifier ";" ProcedureDeclarationBlock StatementBlock .
+ProcedureBlock = { ProcedureDeclaration } .
+ProcedureDeclarationBlock = [ ConstBlock ] [ VariableBlock ] .
+DeclarationBlock = [ ConstBlock ] [ VariableBlock ] [ ProcedureBlock ] .
+Module = "module" Identifier ";" DeclarationBlock StatementBlock .