From 04614fca7cf56ba12aebe5af7ae69a6adaa56b6f Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Sat, 27 Jun 2020 20:32:54 +0200 Subject: some cleanup around scoping, all const/var in procedures --- ecomp-c/ec.c | 122 +++++++++++++++++++++++++++++------------------------ ecomp-c/minie.ebnf | 67 +++++++++++++++-------------- 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 . -- cgit v1.2.3-54-g00ecf