summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2020-06-28 08:44:23 +0200
committerAndreas Baumann <mail@andreasbaumann.cc>2020-06-28 08:44:23 +0200
commit94c2ac9790daff1f10252b474c1fc2fc17bd3cac (patch)
treef9c635f2e0aca9bb5a5c30391555aa837acbaa24
parent04614fca7cf56ba12aebe5af7ae69a6adaa56b6f (diff)
downloadcompilertests-94c2ac9790daff1f10252b474c1fc2fc17bd3cac.tar.gz
compilertests-94c2ac9790daff1f10252b474c1fc2fc17bd3cac.tar.bz2
added forward procedure declarations and fixed some memory leaks
-rw-r--r--ecomp-c/README39
-rw-r--r--ecomp-c/ec.c35
-rw-r--r--ecomp-c/test1.e4
3 files changed, 67 insertions, 11 deletions
diff --git a/ecomp-c/README b/ecomp-c/README
index f0e3fc5..4e1e88c 100644
--- a/ecomp-c/README
+++ b/ecomp-c/README
@@ -197,9 +197,46 @@ initializing a constant of 'boolean'.
detection of uninitialized variables
------------------------------------
-this might be very hard and heuristical (and the depend on the compiler
+This might be very hard and heuristical (and the depend on the compiler
optimization level). Simple flows can be statically analyzed, what
to do when conditions, loops and complex data structures come into place?
+Also, all statically allocated variables must be initialized (and be it
+to zero) to get deterministic behaviour. Not a biggie, considering this
+is done at compile time and doesn't affect runtime.
+Data on the stack (local variables and parameters) must always be
+initialized by hand.
+
+nesting
+-------
+
+proper function/procedure nesting implies a lot of things to implement
+like closures. For now we don't implement them.
+
+prototypes/forward declarations
+-------------------------------
+
+Wirth dropped them (use function variables or nesting), and uses
+variables of type procedure/function. We should see if it is not
+easier to implement them as they are merily the same as importing
+an exported module symbol. Also, not having nesting might require
+us to use forward references (we have them now in C in both the
+compiler and the assembler, so).
+
+https://github.com/andreaspirklbauer/Oberon-forward-references-of-procedures
+
+loops
+-----
+
+do we need repeat/until along to a while?
+can we do simpler SIMD optimizations when adding a simple (stricly
+mathematical FOR-loop)?
+what about WHILE S1 DO, ELSIF S2 DO, ELSE S3.. like in Oberon?
+
+assertions
+----------
+
+got added in Oberon, handy for debugging and strict contract-based
+programming.
assembler
---------
diff --git a/ecomp-c/ec.c b/ecomp-c/ec.c
index 4243a93..2b88b0e 100644
--- a/ecomp-c/ec.c
+++ b/ecomp-c/ec.c
@@ -1752,6 +1752,7 @@ static Symbol *parseArrayType( Scope *scope )
integer_type->name, node->actual_type->name );
}
num = evaluate_const_expression_as_integer( node );
+ free_expression_node( node );
}
Expect( S_of );
@@ -1938,20 +1939,28 @@ static void parseProcedureBlock( Scope *scope )
Expect( S_procedure );
Expect( S_ident );
- procedure_label = get_scoped_label( scope, ident );
- Emit( "; PROC %s\n", ident );
-
- symbol = insert_symbol( scope, ident, SYMBOL_CLASS_PROCEDURE_TYPE );
- symbol->label = procedure_label;
+ symbol = get_symbol( scope, ident );
+ if( symbol == NULL ) {
+ symbol = insert_symbol( scope, ident, SYMBOL_CLASS_PROCEDURE_TYPE );
+ procedure_label = get_scoped_label( scope, ident );
+ symbol->label = AllocateAndCopyStr( procedure_label );
+ free( procedure_label );
+ } else if( symbol->class == SYMBOL_CLASS_PROCEDURE_TYPE ) {
+ /* TODO: check, if parameter lists and return values match */
+ }
Expect( S_semicolon );
- parseProcedureDeclarationBlock( scope );
+ if( sym == S_const || sym == S_var || sym == S_begin ) {
+ parseProcedureDeclarationBlock( scope );
- Emit( "%s:\n", procedure_label );
- parseStatementBlock( scope );
+ Emit( "; PROC %s\n", symbol->name );
+
+ Emit( "%s:\n", symbol->label );
+ parseStatementBlock( scope );
- Emit( "ret\n" );
+ Emit( "ret\n" );
+ }
}
static void parseDeclarationBlock( Scope *scope )
@@ -1976,12 +1985,18 @@ static void parseModule( Scope *scope )
if( sym == S_ident ) {
strlcpy( moduleName, ident, MAX_IDENT_LEN );
}
+
entry_label = get_local_label( scope );
- Emit( "jmp %s\n", entry_label );
+ Emit( "jmp %s\n", entry_label );
+
Expect( S_semicolon );
+
parseDeclarationBlock( scope );
Emit( "%s:\n", entry_label );
+
parseStatementBlock( scope );
+
+ free( entry_label );
}
static void register_internal_types( Scope *scope )
diff --git a/ecomp-c/test1.e b/ecomp-c/test1.e
index b5c5edc..a9fbbe8 100644
--- a/ecomp-c/test1.e
+++ b/ecomp-c/test1.e
@@ -32,14 +32,18 @@ var
s2 : array 10 of character := "hello";
a1 : array 10 of integer;
+procedure B;
+
procedure A;
begin
a1[5] := 43;
+ B;
end
procedure B;
begin
a1[4] := 44;
+ A;
end
begin