diff options
author | Andreas Baumann <mail@andreasbaumann.cc> | 2020-05-16 20:43:59 +0200 |
---|---|---|
committer | Andreas Baumann <mail@andreasbaumann.cc> | 2020-05-16 20:43:59 +0200 |
commit | d530fcbacbfaf4f2a3c0db789b89a882ca54bbb2 (patch) | |
tree | 2d01f2d9fa26e3a0c5d5d6cb6f1842b2b76607a9 | |
parent | a97dfcfb8a1f49d634b17c493ef54fa4fed72047 (diff) | |
download | compilertests-d530fcbacbfaf4f2a3c0db789b89a882ca54bbb2.tar.gz compilertests-d530fcbacbfaf4f2a3c0db789b89a882ca54bbb2.tar.bz2 |
refactored parsing of const expressions (currently literals and identifiers/other constants only)
started to add initialization of variables
-rw-r--r-- | ecomp-c/ec.c | 72 | ||||
-rw-r--r-- | ecomp-c/minie.ebnf | 5 | ||||
-rwxr-xr-x | ecomp-c/test.sh | 1 | ||||
-rw-r--r-- | ecomp-c/tests/const_assignment_from_another_constant_illegal_type.ecomp_err | 2 | ||||
-rw-r--r-- | ecomp-c/tests/const_assignment_from_unknown_constant.ecomp_err | 2 | ||||
-rw-r--r-- | ecomp-c/tests/variable_initialization.e | 17 |
6 files changed, 72 insertions, 27 deletions
diff --git a/ecomp-c/ec.c b/ecomp-c/ec.c index ee8d03c..fbc054a 100644 --- a/ecomp-c/ec.c +++ b/ecomp-c/ec.c @@ -1167,11 +1167,43 @@ static void parseStatementBlock( Scope *scope ) Expect( S_end ); } +/* TODO: implement simple expression and later complex expression */ +static ExpressionNode *parseConstExpression( void ) +{ + ExpressionNode *node; + + if( sym == S_number ) { + node = create_expression_node( ); + node->type = EXPRESSION_NODE_TYPE_CONST; + node->number = num; + node->actual_type = get_symbol( current_scope, "integer" ); + sym = getSym( ); + } else if( sym == S_ident ) { + Symbol *symbol = get_symbol( current_scope, ident ); + if( symbol == NULL ) { + Abort( "Constant '%s' is unknown", ident ); + } + if( symbol->class != SYMBOL_CLASS_CONSTANT ) { + Abort( "Assignment value of '%s' is not a constant", ident ); + } + node = create_expression_node( ); + node->type = EXPRESSION_NODE_TYPE_VAR; + node->symbol = symbol; + node->actual_type = symbol->type; + sym = getSym( ); + } else { + Abort( "Expected a literal or a constant identifier" ); + } + + return node; +} + static void parseConstDeclaration( void ) { int nof_constants = 0; - Symbol *constant[MAX_NUMBER_OF_ENUMERATIONS], *type, *const_expr; + Symbol *constant[MAX_NUMBER_OF_ENUMERATIONS], *type; int i; + ExpressionNode *node; do { if( sym == S_begin || sym == S_var ) { @@ -1188,6 +1220,7 @@ static void parseConstDeclaration( void ) } while( sym == S_comma ); Expect( S_colon ); + type = get_symbol( current_scope, ident ); if( type == NULL ) { Abort( "Unknown type '%s'", ident ); @@ -1198,33 +1231,26 @@ static void parseConstDeclaration( void ) sym = getSym( ); Expect( S_equals ); - if( sym == S_number ) { + + node = parseConstExpression( ); + if( 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++ ) { - constant[i]->value = num; - constant[i]->type = type; - Emit( "; CONST %s -> %s, %d\n", constant[i]->name, constant[i]->type->name, num ); - } - sym = getSym( ); - } else if( sym == S_ident ) { - const_expr = get_symbol( current_scope, ident ); - if( const_expr == NULL ) { - Abort( "Constant '%s' is unknown", ident ); - } - if( const_expr->class != SYMBOL_CLASS_CONSTANT ) { - Abort( "Assignment value of '%s' is not a constant", ident ); - } - if( type != const_expr->type ) { - Abort( "Assigning a constant of type '%s' from a constant of type '%s'", - type->name, const_expr->type->name ); + constant[i]->value = node->number; + constant[i]->type = node->actual_type; + Emit( "; CONST %s -> %s, %d\n", constant[i]->name, constant[i]->type->name, constant[i]->value ); } + } else if( node->type == EXPRESSION_NODE_TYPE_VAR ) { for( i = 0; i < nof_constants; i++ ) { - constant[i]->value = const_expr->value; - constant[i]->type = type; - Emit( "; CONST %s -> %s, %d\n", constant[i]->name, constant[i]->type->name, const_expr->value ); + constant[i]->value = node->symbol->value; + constant[i]->type = node->symbol->type; + Emit( "; CONST %s -> %s, %d\n", constant[i]->name, constant[i]->type->name, constant[i]->value ); } - sym = getSym( ); } else { - Abort( "Expected a constant number" ); + Abort( "Complex constant expressions not implemented yet" ); } } diff --git a/ecomp-c/minie.ebnf b/ecomp-c/minie.ebnf index bd1eb08..be82d9e 100644 --- a/ecomp-c/minie.ebnf +++ b/ecomp-c/minie.ebnf @@ -18,9 +18,10 @@ StatementSequence = Statement { ";" Statement } . StatementBlock = "begin" StatementList "end" . SimpleType = Identifier . Type = SimpleType . -ConstDeclaration = Identifier { "," Identifier } ":" Type "=" ( Number | Identifier ). +ConstExpression = ( Number | Identifier ) . +ConstDeclaration = Identifier { "," Identifier } ":" Type "=" ConstExpression . ConstBlock = "const" { ConstDeclaration ";" } . -VariableDeclaration = Identifier { "," Identifier } ":" Type . +VariableDeclaration = Identifier { "," Identifier } ":" Type [ ":=" ConstExpression ] . VariableBlock = "var" { VariableDeclaration ";" } . DeclarationBlock = ConstBlock VariableBlock . Module = "module" Identifier ";" DeclarationBlock StatementBlock . diff --git a/ecomp-c/test.sh b/ecomp-c/test.sh index c5448e1..94bed3b 100755 --- a/ecomp-c/test.sh +++ b/ecomp-c/test.sh @@ -5,6 +5,7 @@ empty_module unknown_variable variable_name_as_type variable_not_initialized +variable_initialization unknown_type const_assignment_error const_assignment_from_another_constant diff --git a/ecomp-c/tests/const_assignment_from_another_constant_illegal_type.ecomp_err b/ecomp-c/tests/const_assignment_from_another_constant_illegal_type.ecomp_err index 6e55dce..a8e982c 100644 --- a/ecomp-c/tests/const_assignment_from_another_constant_illegal_type.ecomp_err +++ b/ecomp-c/tests/const_assignment_from_another_constant_illegal_type.ecomp_err @@ -1 +1 @@ -Error line 10, pos 18: Assigning a constant of type 'integer' from a constant of type 'boolean' +Error line 10, pos 19: Assigning a constant of type 'integer' from an expression of type 'boolean' diff --git a/ecomp-c/tests/const_assignment_from_unknown_constant.ecomp_err b/ecomp-c/tests/const_assignment_from_unknown_constant.ecomp_err index 6e55dce..a8e982c 100644 --- a/ecomp-c/tests/const_assignment_from_unknown_constant.ecomp_err +++ b/ecomp-c/tests/const_assignment_from_unknown_constant.ecomp_err @@ -1 +1 @@ -Error line 10, pos 18: Assigning a constant of type 'integer' from a constant of type 'boolean' +Error line 10, pos 19: Assigning a constant of type 'integer' from an expression of type 'boolean' diff --git a/ecomp-c/tests/variable_initialization.e b/ecomp-c/tests/variable_initialization.e new file mode 100644 index 0000000..8387cdd --- /dev/null +++ b/ecomp-c/tests/variable_initialization.e @@ -0,0 +1,17 @@ +/* + * show different ways we can initialize variables + */ + +module variable_initialization; + +const + N : integer = 1; this is a constant, exists only during compilation + +var + a : integer; // not initialized + b : integer := N; // initialized on declaration, initialized in data segment + c : integer; + +begin + c := 2; // initialized at runtime, in data segment initialized as zero +end |