diff options
author | Andreas Baumann <mail@andreasbaumann.cc> | 2018-12-22 21:38:02 +0100 |
---|---|---|
committer | Andreas Baumann <mail@andreasbaumann.cc> | 2018-12-22 21:38:02 +0100 |
commit | 8975a83c3532e56f97b2555db71d957dd69cda81 (patch) | |
tree | 5438ad833e5d0675d8b83dea8855229cd3445ecb /minie/e2c.c | |
parent | 2244c65cdb0bfa2cc88ebe04cfdeba7349251f33 (diff) | |
download | compilertests-8975a83c3532e56f97b2555db71d957dd69cda81.tar.gz compilertests-8975a83c3532e56f97b2555db71d957dd69cda81.tar.bz2 |
some work on arrays and reading from stdin
Diffstat (limited to 'minie/e2c.c')
-rw-r--r-- | minie/e2c.c | 124 |
1 files changed, 101 insertions, 23 deletions
diff --git a/minie/e2c.c b/minie/e2c.c index f1ba44b..438dbe4 100644 --- a/minie/e2c.c +++ b/minie/e2c.c @@ -5,7 +5,7 @@ #include <assert.h> enum { - MAX_IDENT_LEN = 16, + MAX_IDENT_LEN = 24, MAX_NUMBER_LEN = 9, MAX_ERRMSG_LEN = 64, MAX_STRING_LEN = 64 @@ -21,6 +21,7 @@ static char moduleName[MAX_IDENT_LEN+1]; static char varName[MAX_IDENT_LEN+1]; static char typeName[MAX_IDENT_LEN+1]; static char procName[MAX_IDENT_LEN+1]; +static int isArray = 0; typedef enum { S_char = 0, @@ -36,6 +37,8 @@ typedef enum { S_if, S_do, S_else, + S_array, + S_of, S_dot, S_comma, S_semicolon, @@ -47,6 +50,8 @@ typedef enum { S_slash, S_lparen, S_rparen, + S_lbracket, + S_rbracket, S_eof } Symbol; @@ -64,6 +69,8 @@ char *symname[S_eof+1] = { "if", "do", "else", + "array", + "of", ".", ",", ";", @@ -75,6 +82,8 @@ char *symname[S_eof+1] = { "/", "(", ")", + "[", + "]", "eof" }; @@ -141,6 +150,7 @@ static int isCharacter( int c ) case ' ': case '[': case ']': + case ':': /* TODO: allow more characters as we go along */ return 1; default: @@ -235,9 +245,14 @@ static Symbol getSym( void ) case '7': case '8': case '9': - case 'a': number( ); return S_number; + case 'a': + identifier( ); + if( strcmp( ident, "array" ) == 0 ) { + return S_array; + } + return S_ident; case 'b': identifier( ); if( strcmp( ident, "begin" ) == 0 ) { @@ -282,7 +297,14 @@ static Symbol getSym( void ) } return S_ident; case 'n': + identifier( ); + return S_ident; case 'o': + identifier( ); + if( strcmp( ident, "of" ) == 0 ) { + return S_of; + } + return S_ident; case 'p': identifier( ); if( strcmp( ident, "procedure" ) == 0 ) { @@ -369,6 +391,12 @@ static Symbol getSym( void ) case ')': look = getChar( ); return S_rparen; + case '[': + look = getChar( ); + return S_lbracket; + case ']': + look = getChar( ); + return S_rbracket; case EOF: return S_eof; default: @@ -588,17 +616,31 @@ static void statement( void ) qualident( ); if( sym == S_lparen ) { /* TODO: add internal function maps as symbols and procedures */ - if( strcmp( varName, "system.writeln" ) == 0 ) { - emit( "printf( " ); + if( strcmp( varName, "system.writestring" ) == 0 || + strcmp( varName, "system.writeline" ) == 0 ) { + emit( "printf( \"%%s\", " ); + } else if( strcmp( varName, "system.writeinteger" ) == 0 ) { + emit( "printf( \"%%d\", " ); } else if( strcmp( varName, "system.halt" ) == 0 ) { emit( "exit( " ); + } else if( strcmp( varName, "system.readline" ) == 0 ) { + emit( "{ size_t _n = %d; fgets( (char *)&", num ); + } else if( strcmp( varName, "length" ) == 0 ) { + emit( "255" ); } else { emit( "%s( ", varName ); } parameterList( ); /* TODO: procedure call */ - emitLn( ");" ); - if( strcmp( varName, "system.writeln" ) == 0 ) { + if( strcmp( varName, "system.readline" ) == 0 ) { + /* TODO: check if parameter is an array of char, + get length of the defined array and put it into the parameter + of getline */ + emitLn( ", _n, stdin ); }" ); + } else { + emitLn( ");" ); + } + if( strcmp( varName, "system.writeline" ) == 0 ) { emitLn( "puts( \"\" );" ); } } else { @@ -626,26 +668,58 @@ static void statementBlock( void ) Expect( S_end ); } +static void type( void ); + +static void simpleType( void ) +{ + /* TODO: handle build-in types in init, register them in + type table */ + if( strcmp( ident, "integer" ) == 0 ) { + strcpy( typeName, "signed int" ); + sym = getSym( ); + } else if( strcmp( ident, "boolean" ) == 0 ) { + /* C89, no bool */ + strcpy( typeName, "unsigned char" ); + sym = getSym( ); + } else if( strcmp( ident, "char" ) == 0 ) { + /* TODO: Unicode, for now ASCII */ + strcpy( typeName, "unsigned char" ); + sym = getSym( ); + } else if( strcmp( ident, "byte" ) == 0 ) { + /* C89, no bool */ + strcpy( typeName, "unsigned char" ); + sym = getSym( ); + } else { + Abort( "Unknown type '%s'", ident ); + } +} + +static void arrayType( void ) +{ + sym = getSym( ); + Expect( S_lbracket ); + number( ); + sym = getSym( ); + Expect( S_rbracket ); + /* array size is in num */ + if( sym == S_of ) { + sym = getSym( ); + type( ); + /* type is in ident */ + } else { + Abort( "of' expected in array definition" ); + } +} + static void type( void ) { identifier( ); if( sym == S_ident ) { - /* TODO: handle build-in types in init, register them in - type table */ - if( strcmp( ident, "integer" ) == 0 ) { - strcpy( typeName, "signed int" ); - sym = getSym( ); - } else if( strcmp( ident, "bool" ) == 0 ) { - /* C89, no bool */ - strcpy( typeName, "unsigned char" ); - sym = getSym( ); - } else if( strcmp( ident, "byte" ) == 0 ) { - /* C89, no bool */ - strcpy( typeName, "unsigned char" ); - sym = getSym( ); - } else { - Abort( "Unknown type '%s'", ident ); - } + simpleType( ); + isArray = 0; + } else if( sym == S_array ) { + arrayType( ); + isArray = 1; } } @@ -655,7 +729,11 @@ static void variableDeclaration( void ) sym = getSym( ); Expect( S_colon ); type( ); - emitLn( "static %s %s;", typeName, varName ); + if( isArray ) { + emitLn( "static %s %s[%d];", typeName, varName, num ); + } else { + emitLn( "static %s %s;", typeName, varName ); + } } static void variableBlock( void ) |