diff options
author | Andreas Baumann <mail@andreasbaumann.cc> | 2018-12-26 21:46:01 +0100 |
---|---|---|
committer | Andreas Baumann <mail@andreasbaumann.cc> | 2018-12-26 21:46:01 +0100 |
commit | 50c50f34707df53e373ed2d772098162179142f9 (patch) | |
tree | 56e0fd512f57966509fdf21497be778b551d32bd /minie | |
parent | 62d6644b2ab51ee8dda46752f1e7c8d422b65e04 (diff) | |
download | compilertests-50c50f34707df53e373ed2d772098162179142f9.tar.gz compilertests-50c50f34707df53e373ed2d772098162179142f9.tar.bz2 |
added formal parameter declarations for procedures and return types for functions
added for loop
Diffstat (limited to 'minie')
-rwxr-xr-x | minie/build.sh | 2 | ||||
-rw-r--r-- | minie/e2c.c | 117 |
2 files changed, 108 insertions, 11 deletions
diff --git a/minie/build.sh b/minie/build.sh index 12fde40..101aed4 100755 --- a/minie/build.sh +++ b/minie/build.sh @@ -10,7 +10,7 @@ gcc -g -O0 -Wall -pedantic -std=c89 -Wno-return-type -o e2c e2c.c ./e2c < test7.e ./e2c < test5.e > test5.c && gcc -g -o test5 test5.c && ./test5 -./e2c < test6.e > test6.c && gcc -g -o test6 test6.c && ./test6 +./e2c < test6.e > test6.c && gcc -g -o test6 test6.c && ( echo 'Hello' | ./test6 ) ./e2c < test7.e > test7.c && gcc -g -o test7 test7.c && ./test7 ./e2c < ec.e diff --git a/minie/e2c.c b/minie/e2c.c index 09b151d..8bd7105 100644 --- a/minie/e2c.c +++ b/minie/e2c.c @@ -13,7 +13,7 @@ enum { MAX_STRING_LEN = 64, MAX_SYMBOLS = 32, MAX_RECORD_MEMBERS = 8, - MAX_FUNCTION_PARAMETERS = 4 + MAX_PARAMETERS = 4 }; /* SCANNER */ @@ -41,6 +41,8 @@ typedef enum { S_else, S_array, S_of, + S_for, + S_to, S_dot, S_comma, S_semicolon, @@ -73,6 +75,8 @@ char *symname[S_eof+1] = { "else", "array", "of", + "for", + "to", ".", ",", ";", @@ -292,6 +296,11 @@ next: } return S_ident; case 'f': + identifier( ); + if( strcmp( ident, "for" ) == 0 ) { + return S_for; + } + return S_ident; case 'g': case 'h': case 'j': @@ -332,6 +341,11 @@ next: case 'r': case 's': case 't': + identifier( ); + if( strcmp( ident, "to" ) == 0 ) { + return S_to; + } + return S_ident; case 'u': case 'v': identifier( ); @@ -467,7 +481,7 @@ typedef struct RecordType { } RecordType; typedef struct FunctionType { - BasicType params[MAX_FUNCTION_PARAMETERS]; + BasicType params[MAX_PARAMETERS]; int len; int internal; } FunctionType; @@ -772,6 +786,31 @@ static void doIf( void ) emitLn( "}" ); } +static void statementBlock( void ); + +void static doFor( void ) +{ + char loopVar[MAX_IDENT_LEN]; + + emit( "for( " ); + identifier( ); + strncpy( loopVar, ident, MAX_IDENT_LEN ); + loopVar[MAX_IDENT_LEN-1] = '\0'; + emit( " %s = ", loopVar ); + sym = getSym( ); + Expect( S_assign ); + expression( ); + emit( "; %s <= ", loopVar ); + Expect( S_to ); + expression( ); + /* TODO: add "by" constExpression if needed */ + emitLn( "; %s++ ) {", loopVar ); + Expect( S_do ); + statementSequence( ); + Expect( S_end ); + emitLn( "}" ); +} + static void parameterList( void ) { char funcName[MAX_IDENT_LEN]; @@ -782,6 +821,7 @@ static void parameterList( void ) * to have parsed a qualident */ strncpy( funcName, varName, MAX_IDENT_LEN ); + funcName[MAX_IDENT_LEN-1] = '\0'; if( sym != S_lparen ) { Abort( "Expected symbol '%s'", symname[sym] ); @@ -797,6 +837,7 @@ static void parameterList( void ) if( sym != S_comma ) { /* TODO: add internal function maps as symbols and procedures */ if( strcmp( funcName, "length" ) == 0 ) { + /* we don't allow expression here, only simple variables */ qualident( ); emit( "%d", length( varName ) ); Expect( S_rparen ); @@ -840,12 +881,7 @@ static void parameterList( void ) emit( ")" ); } } - Expect( S_rparen ); - -#if 0 -#endif - } static void statement( void ) @@ -853,6 +889,9 @@ static void statement( void ) if( sym == S_if ) { sym = getSym( ); doIf( ); + } else if( sym == S_for ) { + sym = getSym( ); + doFor( ); /* TODO: S_else feels wrong here, just for the end ';' in an if-block */ } else if( sym == S_end || sym == S_else ) { return; @@ -986,13 +1025,71 @@ static void procedureName( void ) static void procedureDeclaration( void ) { + char return_type[MAX_IDENT_LEN]; + int nof_params = 0; + Type params[MAX_PARAMETERS]; + Expect( S_procedure ); procedureName( ); sym = getSym( ); - /* TODO: procedure parameters */ + if( sym == S_lparen ) { + sym = getSym( ); + do { + if( nof_params >= MAX_PARAMETERS ) { + Halt( "Too many parameters in definition of procedure" ); + } + identifier( ); + strncpy( params[nof_params].name, ident, MAX_IDENT_LEN ); + params[nof_params].name[MAX_IDENT_LEN-1] = '\0'; + sym = getSym( ); + Expect( S_colon ); + if( sym == S_array ) { + sym = getSym( ); + Expect( S_of ); + type( ); + /* TODO type */ + } else { + type( ); + /* TODO type */ + } + nof_params++; + } while( sym == S_comma ); + Expect( S_rparen ); + if( sym == S_colon ) { + sym = getSym( ); + type( ); + strncpy( return_type, typeName, MAX_IDENT_LEN ); + return_type[MAX_IDENT_LEN-1] = '\0'; + } else { + strncpy( return_type, "void", MAX_IDENT_LEN ); + } + /* do not allow empty parameter lists in C++ style */ + if( nof_params == 0 ) { + Halt( "Empty parameter list must not be enclosed with ( )" ); + } + } else if( sym == S_semicolon ) { + strncpy( return_type, "void", MAX_IDENT_LEN ); + /* skip, ok */ + } else { + Halt( "Expected '(' after procedure declaration" ); + } Expect( S_semicolon ); - emitLn( "void %s( void ) {", procName ); - statementBlock( ); + emit( "%s %s( ", return_type, procName ); + if( nof_params == 0 ) { + emit( "void" ); + } else { + int i; + for( i = 0; i < nof_params; i++ ) { + emit( "%s ", params[i].name ); + } + } + emitLn( ") {" ); + if( sym == S_var ) { + variableBlock( ); + } + if( sym == S_begin ) { + statementBlock( ); + } emitLn( "}" ); } |