diff options
author | Andreas Baumann <mail@andreasbaumann.cc> | 2018-12-24 12:43:44 +0100 |
---|---|---|
committer | Andreas Baumann <mail@andreasbaumann.cc> | 2018-12-24 12:43:44 +0100 |
commit | 836832f9718de1773e0673e2b078dbe5d88974c8 (patch) | |
tree | b9fc0d57d0ab4b9057d442612d6afd1e0e737287 /minie | |
parent | 8975a83c3532e56f97b2555db71d957dd69cda81 (diff) | |
download | compilertests-836832f9718de1773e0673e2b078dbe5d88974c8.tar.gz compilertests-836832f9718de1773e0673e2b078dbe5d88974c8.tar.bz2 |
added simplistic symbol managemnt for variables
Diffstat (limited to 'minie')
-rw-r--r-- | minie/README | 1 | ||||
-rwxr-xr-x | minie/build.sh | 4 | ||||
-rw-r--r-- | minie/e2c.c | 123 | ||||
-rw-r--r-- | minie/test5.e | 18 | ||||
-rw-r--r-- | minie/test6.e | 17 |
5 files changed, 144 insertions, 19 deletions
diff --git a/minie/README b/minie/README index e7ea35d..9ae9438 100644 --- a/minie/README +++ b/minie/README @@ -19,3 +19,4 @@ test2: syntax error, no module definition test3: module definition lacking a module name test4: general expressions and variables test5: basic system input/output, import of pseudo module 'system' +test6: string functions diff --git a/minie/build.sh b/minie/build.sh index 3dc1339..898cb5a 100755 --- a/minie/build.sh +++ b/minie/build.sh @@ -1,13 +1,15 @@ #!/bin/bash -gcc -g -O0 -Wall -pedantic -std=c89 -o e2c e2c.c +gcc -g -O0 -Wall -pedantic -std=c89 -Wno-return-type -o e2c e2c.c ./e2c < test1.e ./e2c < test2.e ./e2c < test3.e ./e2c < test4.e ./e2c < test5.e +./e2c < test6.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 < ec.e ./e2c < ec.e > ec.c && gcc -o ec ec.c diff --git a/minie/e2c.c b/minie/e2c.c index 438dbe4..065c4a0 100644 --- a/minie/e2c.c +++ b/minie/e2c.c @@ -4,24 +4,25 @@ #include <stdarg.h> #include <assert.h> +/* CONSTANTS */ + enum { MAX_IDENT_LEN = 24, MAX_NUMBER_LEN = 9, MAX_ERRMSG_LEN = 64, - MAX_STRING_LEN = 64 + MAX_STRING_LEN = 64, + MAX_RECORD_MEMBERS = 8, + MAX_SYMBOLS = 32 }; +/* SCANNER */ + static int look; static int row; static int col; static int num; static char str[MAX_STRING_LEN+1]; static char ident[MAX_IDENT_LEN+1]; -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, @@ -198,7 +199,7 @@ static void number( void ) look = getChar( ); } if( n == MAX_NUMBER_LEN ) { - Abort( "Number constand exceeds maximal length" ); + Abort( "Number gand exceeds maximal length" ); } sym = S_number; } @@ -225,7 +226,6 @@ static void string( void ) look = getChar( ); } - static Symbol getSym( void ) { skipWhite( ); @@ -405,6 +405,88 @@ static Symbol getSym( void ) return S_char; } +/* SYMBOL TABLE */ + +typedef enum { + TYPE_UNKNOWN, + TYPE_INTEGER, + TYPE_BOOLEAN, + TYPE_BYTE, + TYPE_CHAR, + TYPE_ARRAY, + TYPE_RECORD +} BasicType; + +static BasicType strToBasicType( char *name ) +{ + if( strcmp( name, "integer" ) == 0 ) { + return TYPE_INTEGER; + } else if( strcmp( name, "boolean" ) == 0 ) { + return TYPE_BOOLEAN; + } else if( strcmp( name, "byte" ) == 0 ) { + return TYPE_BYTE; + } else if( strcmp( name, "char" ) == 0 ) { + return TYPE_CHAR; + } else { + Abort( "Unknown type '%s'", name ); + } + return TYPE_UNKNOWN; +} + +typedef struct ArrayType { + BasicType type; + int len; +} ArrayType; + +typedef struct RecordType { + BasicType type[MAX_RECORD_MEMBERS]; + int len; +} RecordType; + +typedef struct Type { + BasicType type; + char name[MAX_IDENT_LEN]; + ArrayType array; + RecordType record; +} Type; + +static int nof_symbols = 0; +static Type symbols[MAX_SYMBOLS]; + +static void insert_symbol( Type type, char *name ) +{ + if( nof_symbols >= MAX_SYMBOLS ) { + Halt( "Symbol table exhausted, increase MAX_SYMBOLS and recompile e2c" ); + } + + symbols[nof_symbols] = type; + strncpy( symbols[nof_symbols].name, name, MAX_IDENT_LEN ); + + nof_symbols++; +} + +static Type get_symbol_type( char *name ) +{ + int i; + + for( i = 0; i < nof_symbols; i++ ) { + if( strcmp( symbols[i].name, name ) == 0 ) { + return symbols[i]; + } + } + + Abort( "Could not determine type of symbol '%s'", name ); +} + +/* PARSER */ + +static char moduleName[MAX_IDENT_LEN+1]; +static char varName[MAX_IDENT_LEN+1]; +static Type lastType; +static int isArray = 0; +static char typeName[MAX_IDENT_LEN+1]; +static char procName[MAX_IDENT_LEN+1]; + static void Expect( Symbol expect ) { if( sym == expect ) { @@ -436,6 +518,7 @@ static void prologue( void ) emitLn( "/* generated with e2c */" ); emitLn( "#include <stdio.h>" ); emitLn( "#include <stdlib.h>" ); + emitLn( "#include <string.h>" ); } static void init( void ) @@ -502,7 +585,9 @@ static void factor( void ) emit( "\"%s\"", str ); sym = getSym( ); } else if( sym == S_ident ) { - /* TODO: hacky */ + /* TODO: hacky, the question is also, should this + * be a keyword + */ if( strcmp( ident, "true" ) == 0 ) { emit( "1" ); } else if( strcmp( ident, "false" ) == 0 ) { @@ -546,10 +631,20 @@ static void expression( void ) static void assignment( void ) { + Type type; + /* precondition: ident is a variable and already parsed */ Expect( S_assign ); - emit( "%s = ", varName ); + type = get_symbol_type( varName ); + if( type.type == TYPE_ARRAY && type.array.type == TYPE_CHAR ) { + emit( "strncpy( %s, ", varName ); + } else { + emit( "%s = ", varName ); + } expression( ); + if( type.type == TYPE_ARRAY && type.array.type == TYPE_CHAR ) { + emit( ", %d )", type.array.len ); + } emitLn( ";" ); } @@ -675,17 +770,21 @@ static void simpleType( void ) /* TODO: handle build-in types in init, register them in type table */ if( strcmp( ident, "integer" ) == 0 ) { + lastType.type = TYPE_INTEGER; strcpy( typeName, "signed int" ); sym = getSym( ); } else if( strcmp( ident, "boolean" ) == 0 ) { + lastType.type = TYPE_BOOLEAN; /* C89, no bool */ strcpy( typeName, "unsigned char" ); sym = getSym( ); } else if( strcmp( ident, "char" ) == 0 ) { + lastType.type = TYPE_CHAR; /* TODO: Unicode, for now ASCII */ strcpy( typeName, "unsigned char" ); sym = getSym( ); } else if( strcmp( ident, "byte" ) == 0 ) { + lastType.type = TYPE_BYTE; /* C89, no bool */ strcpy( typeName, "unsigned char" ); sym = getSym( ); @@ -706,6 +805,9 @@ static void arrayType( void ) sym = getSym( ); type( ); /* type is in ident */ + lastType.type = TYPE_ARRAY; + lastType.array.type = strToBasicType( ident ); + lastType.array.len = num; } else { Abort( "of' expected in array definition" ); } @@ -729,6 +831,7 @@ static void variableDeclaration( void ) sym = getSym( ); Expect( S_colon ); type( ); + insert_symbol( lastType, varName ); if( isArray ) { emitLn( "static %s %s[%d];", typeName, varName, num ); } else { diff --git a/minie/test5.e b/minie/test5.e index 1b4e991..0b745e8 100644 --- a/minie/test5.e +++ b/minie/test5.e @@ -1,17 +1,19 @@ -module test4; +module test5; import system; - + var s : array[64] of char; - len : integer; + i : integer; begin - system.readline( s ); - len := len( s ); + s := "Hello World"; system.writestring( "String: " ); - system.writeline( s ); - system.writestring( "Length: " ); - system.writeinteger( len ); + system.writestring( s ); + system.writeline( "" ); + + i := 42; + system.writestring( "Integer: " ); + system.writeinteger( i ); system.writeline( "" ) end diff --git a/minie/test6.e b/minie/test6.e new file mode 100644 index 0000000..15e5969 --- /dev/null +++ b/minie/test6.e @@ -0,0 +1,17 @@ +module test6; + +import system; + +var + s : array[64] of char; + len : integer; + +begin + system.readline( s ); + len := len( s ); + system.writestring( "String: " ); + system.writeline( s ); + system.writestring( "Length: " ); + system.writeinteger( len ); + system.writeline( "" ) +end |