summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2020-05-16 20:43:59 +0200
committerAndreas Baumann <mail@andreasbaumann.cc>2020-05-16 20:43:59 +0200
commitd530fcbacbfaf4f2a3c0db789b89a882ca54bbb2 (patch)
tree2d01f2d9fa26e3a0c5d5d6cb6f1842b2b76607a9
parenta97dfcfb8a1f49d634b17c493ef54fa4fed72047 (diff)
downloadcompilertests-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.c72
-rw-r--r--ecomp-c/minie.ebnf5
-rwxr-xr-xecomp-c/test.sh1
-rw-r--r--ecomp-c/tests/const_assignment_from_another_constant_illegal_type.ecomp_err2
-rw-r--r--ecomp-c/tests/const_assignment_from_unknown_constant.ecomp_err2
-rw-r--r--ecomp-c/tests/variable_initialization.e17
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