summaryrefslogtreecommitdiff
path: root/minie
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2019-02-23 22:06:11 +0100
committerAndreas Baumann <mail@andreasbaumann.cc>2019-02-23 22:06:11 +0100
commit5d931bd7c39025224eeac43724529b4938585367 (patch)
tree15eb8c0e273f25c1d02d6e0bf73f85a59d1d90e3 /minie
parent9f76ed072277ec01ca591e478cf7686914b9e530 (diff)
downloadcompilertests-5d931bd7c39025224eeac43724529b4938585367.tar.gz
compilertests-5d931bd7c39025224eeac43724529b4938585367.tar.bz2
added stacking scopes
Diffstat (limited to 'minie')
-rw-r--r--minie/TODOS2
-rw-r--r--minie/e2c.c43
-rw-r--r--minie/ec.e12
3 files changed, 45 insertions, 12 deletions
diff --git a/minie/TODOS b/minie/TODOS
index 0d53087..d925789 100644
--- a/minie/TODOS
+++ b/minie/TODOS
@@ -227,6 +227,8 @@ design
Scanner class or struct vs. OPS module containing all variables. all modules
in the Oberon compiler act as singletons.
+nested procedures
+
links
-----
diff --git a/minie/e2c.c b/minie/e2c.c
index da59c30..8108502 100644
--- a/minie/e2c.c
+++ b/minie/e2c.c
@@ -592,6 +592,13 @@ struct SymbolTable {
};
static SymbolTable symbols;
+static SymbolTable *current_scope = &symbols;
+
+static void init_symboltable( SymbolTable *table, SymbolTable *parent )
+{
+ table->nof_symbols = 0;
+ table->parent = parent;
+}
static void insert_symbol( SymbolTable *table, Type type, char *name )
{
@@ -601,19 +608,25 @@ static void insert_symbol( SymbolTable *table, Type type, char *name )
table->symbols[table->nof_symbols] = type;
strncpy( table->symbols[table->nof_symbols].name, name, MAX_IDENT_LEN );
-
+
table->nof_symbols++;
}
static Type get_symbol_type( SymbolTable *table, char *name )
{
int i;
-
+
+ /* search in table of currect scope */
for( i = 0; i < table->nof_symbols; i++ ) {
if( strcmp( table->symbols[i].name, name ) == 0 ) {
return table->symbols[i];
}
}
+
+ /* traverse stack of parent symbol tables */
+ if( table->parent != NULL ) {
+ return get_symbol_type( table->parent, name );
+ }
Abort( "Unknown symbol '%s'", name );
}
@@ -655,7 +668,7 @@ static int length( char *name )
{
Type type;
- type = get_symbol_type( &symbols, name );
+ type = get_symbol_type( current_scope, name );
if( type.type == TYPE_ARRAY ) {
return type.details.array.len;
} else {
@@ -784,6 +797,8 @@ static void prologue( void )
" return c;" \
" }" \
"}" );
+
+ init_symboltable( &symbols, NULL );
register_internal_functions( );
register_internal_constants( );
@@ -851,7 +866,7 @@ static void factor( void )
sym = getSym( );
} else if( sym == S_ident ) {
qualident( );
- type = get_symbol_type( &symbols, varName );
+ type = get_symbol_type( current_scope, varName );
if( type.type == TYPE_FUNCTION ) {
parameterList( );
} else if( type.type == TYPE_CONSTANT ) {
@@ -955,7 +970,7 @@ static void selector( void )
selected_array = 0;
if( sym == S_lbracket ) {
Expect( S_lbracket );
- type = get_symbol_type( &symbols, varName );
+ type = get_symbol_type( current_scope, varName );
if( type.type != TYPE_ARRAY ) {
Abort( "Selecting element of non-array" );
}
@@ -976,7 +991,7 @@ static void assignment( void )
/* left hand side */
/* precondition: qualident has been already parsed outside */
selector( );
- type = get_symbol_type( &symbols, varName );
+ type = get_symbol_type( current_scope, varName );
/* x := ( a+ b )- 3; -> x = (a+b)-3;
* s1 := s2; -> strncpy( s2, s1, length( s2 ) );
@@ -1181,7 +1196,7 @@ static void statement( void )
parameterList( );
emitLn( ";" );
} else {
- Type type = get_symbol_type( &symbols, varName );
+ Type type = get_symbol_type( current_scope, varName );
if( type.type == TYPE_FUNCTION ) {
/* procedure call without parameter */
/* TODO: check number of parameter and return value to be 0 */
@@ -1310,7 +1325,7 @@ static void variableDeclaration( void )
sym = getSym( );
Expect( S_colon );
type( );
- insert_symbol( &symbols, lastType, varName );
+ insert_symbol( current_scope, lastType, varName );
if( lastType.type == TYPE_ARRAY ) {
/* TODO: this works for now, though it's not correct */
emitLn( "static %s %s[%d];",
@@ -1351,6 +1366,9 @@ static void procedureDeclaration( void )
{
char return_type[MAX_IDENT_LEN];
Type funcType;
+ SymbolTable locals;
+
+ init_symboltable( &locals, current_scope );
funcType.type = TYPE_FUNCTION;
funcType.details.function.internal = 0;
@@ -1385,6 +1403,8 @@ static void procedureDeclaration( void )
type( );
funcType.details.function.params[funcType.details.function.len]->type = lastType.type;
}
+ insert_symbol( &locals, *funcType.details.function.params[funcType.details.function.len],
+ funcType.details.function.params[funcType.details.function.len]->name );
funcType.details.function.len++;
} while( sym == S_comma );
}
@@ -1405,7 +1425,8 @@ static void procedureDeclaration( void )
}
Expect( S_semicolon );
- insert_symbol( &symbols, funcType, procName );
+ insert_symbol( current_scope, funcType, procName );
+ current_scope = &locals;
emit( "%s %s( ", return_type, procName );
if( funcType.details.function.len == 0 ) {
@@ -1419,12 +1440,16 @@ static void procedureDeclaration( void )
}
}
emitLn( ") {" );
+
if( sym == S_var ) {
variableBlock( );
}
if( sym == S_begin ) {
statementBlock( );
}
+
+ current_scope = current_scope->parent;
+
emitLn( "}" );
}
diff --git a/minie/ec.e b/minie/ec.e
index 1dd1221..57d5a55 100644
--- a/minie/ec.e
+++ b/minie/ec.e
@@ -44,16 +44,20 @@ begin
end
end
+procedure getSym : integer;
+begin
+end
+
(* parser *)
procedure Expect( expect : integer );
-(* TODO: Error line 51, pos 22: Unknown symbol 'expect': add symbol to local scope
- and remove it at end of scope/procedure *)
begin
if ( sym = expect ) do
- sym = getSym( );
+ sym := getSym( );
else
+ (* TODO: symtable names
Abort( "Expected symbol", symname[expect] );
+ *)
end
end
@@ -72,7 +76,9 @@ end
procedure doModule;
begin
+ (* TODO: unkown symbol of state CONST
Expect( S_module );
+ *)
look := getChar( );
while ( look <> char( 0 ) ) do
if not isWhite( look ) do