summaryrefslogtreecommitdiff
path: root/minie
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2018-12-26 21:46:01 +0100
committerAndreas Baumann <mail@andreasbaumann.cc>2018-12-26 21:46:01 +0100
commit50c50f34707df53e373ed2d772098162179142f9 (patch)
tree56e0fd512f57966509fdf21497be778b551d32bd /minie
parent62d6644b2ab51ee8dda46752f1e7c8d422b65e04 (diff)
downloadcompilertests-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-xminie/build.sh2
-rw-r--r--minie/e2c.c117
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( "}" );
}