diff options
author | Andreas Baumann <mail@andreasbaumann.cc> | 2018-12-24 15:40:12 +0100 |
---|---|---|
committer | Andreas Baumann <mail@andreasbaumann.cc> | 2018-12-24 15:40:12 +0100 |
commit | 8f8d30e72eddbc8a57ab6ea211a4ca4610da30e0 (patch) | |
tree | 29ea62f5f90eda1ddf520ab6b4bcdc6c0ac2439b /minie | |
parent | 836832f9718de1773e0673e2b078dbe5d88974c8 (diff) | |
download | compilertests-8f8d30e72eddbc8a57ab6ea211a4ca4610da30e0.tar.gz compilertests-8f8d30e72eddbc8a57ab6ea211a4ca4610da30e0.tar.bz2 |
removed temporary hack needed becauseof lacking symbol table, started to add function symbols for internal functions
Diffstat (limited to 'minie')
-rw-r--r-- | minie/README | 2 | ||||
-rw-r--r-- | minie/e2c.c | 112 | ||||
-rw-r--r-- | minie/test6.e | 2 |
3 files changed, 84 insertions, 32 deletions
diff --git a/minie/README b/minie/README index 9ae9438..c8fe74e 100644 --- a/minie/README +++ b/minie/README @@ -19,4 +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 +test6: string functions, internal function 'length' diff --git a/minie/e2c.c b/minie/e2c.c index 065c4a0..6c358a1 100644 --- a/minie/e2c.c +++ b/minie/e2c.c @@ -11,8 +11,9 @@ enum { MAX_NUMBER_LEN = 9, MAX_ERRMSG_LEN = 64, MAX_STRING_LEN = 64, + MAX_SYMBOLS = 32, MAX_RECORD_MEMBERS = 8, - MAX_SYMBOLS = 32 + MAX_FUNCTION_PARAMETERS = 4 }; /* SCANNER */ @@ -414,7 +415,8 @@ typedef enum { TYPE_BYTE, TYPE_CHAR, TYPE_ARRAY, - TYPE_RECORD + TYPE_RECORD, + TYPE_FUNCTION } BasicType; static BasicType strToBasicType( char *name ) @@ -443,11 +445,20 @@ typedef struct RecordType { int len; } RecordType; +typedef struct FunctionType { + BasicType params[MAX_FUNCTION_PARAMETERS]; + int len; + int internal; +} FunctionType; + typedef struct Type { BasicType type; char name[MAX_IDENT_LEN]; - ArrayType array; - RecordType record; + union { + ArrayType array; + RecordType record; + FunctionType function; + } details; } Type; static int nof_symbols = 0; @@ -475,7 +486,21 @@ static Type get_symbol_type( char *name ) } } - Abort( "Could not determine type of symbol '%s'", name ); + Abort( "Unknown symbol '%s'", name ); +} + +/* INTERNAL FUNCTIONS */ + +static int length( char *name ) +{ + Type type; + + type = get_symbol_type( name ); + if( type.type == TYPE_ARRAY ) { + return type.details.array.len; + } else { + Abort( "length called on non-array variable '%s'", name ); + } } /* PARSER */ @@ -483,7 +508,6 @@ static Type get_symbol_type( char *name ) 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]; @@ -513,12 +537,26 @@ static void emit( char *s, ... ) va_end( args ); } -static void prologue( void ) +static void register_internal_functions( void ) { + Type type; + + /* register compiler-internal functions */ + type.type = TYPE_FUNCTION; + type.details.function.len = 1; + type.details.function.params[0] = TYPE_ARRAY; + type.details.function.internal = 1; + insert_symbol( type, "length" ); +} + +static void prologue( void ) +{ emitLn( "/* generated with e2c */" ); emitLn( "#include <stdio.h>" ); emitLn( "#include <stdlib.h>" ); emitLn( "#include <string.h>" ); + + register_internal_functions( ); } static void init( void ) @@ -569,9 +607,12 @@ static void variableName( void ) } static void expression( void ); +static void parameterList( void ); static void factor( void ) { + Type type; + if( sym == S_plus ) { sym = getSym( ); } else if( sym == S_minus ) { @@ -585,17 +626,25 @@ static void factor( void ) emit( "\"%s\"", str ); sym = getSym( ); } else if( sym == S_ident ) { - /* TODO: hacky, the question is also, should this - * be a keyword - */ - if( strcmp( ident, "true" ) == 0 ) { - emit( "1" ); - } else if( strcmp( ident, "false" ) == 0 ) { - emit( "0" ); + type = get_symbol_type( ident ); + if( type.type == TYPE_FUNCTION ) { + emit( "%s( ", ident ); + sym = getSym( ); + parameterList( ); + emit( " )" ); } else { - emit( "%s", ident ); + /* TODO: hacky, the question is also, should this + * be a keyword + */ + if( strcmp( ident, "true" ) == 0 ) { + emit( "1" ); + } else if( strcmp( ident, "false" ) == 0 ) { + emit( "0" ); + } else { + emit( "%s", ident ); + } + sym = getSym( ); } - sym = getSym( ); } else if( sym == S_lparen ) { emit( "(" ); sym = getSym( ); @@ -636,14 +685,14 @@ static void assignment( void ) /* precondition: ident is a variable and already parsed */ Expect( S_assign ); type = get_symbol_type( varName ); - if( type.type == TYPE_ARRAY && type.array.type == TYPE_CHAR ) { + if( type.type == TYPE_ARRAY && type.details.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 ); + if( type.type == TYPE_ARRAY && type.details.array.type == TYPE_CHAR ) { + emit( ", %d )", type.details.array.len ); } emitLn( ";" ); } @@ -683,14 +732,21 @@ static void doIf( void ) static void parameterList( void ) { + int n = 0; + Expect( S_lparen ); if( sym == S_rparen ) { + if( strcmp( varName, "length" ) == 0 ) { + emit( "%d", length( varName ) ); + } sym = getSym( ); return; } /* TODO: no VAR parameters, strictly pass-by-value */ expression( ); + n = 1; while( sym == S_comma ) { + n++; emit( ", " ); sym = getSym( ); /* TODO: no VAR parameters, strictly pass-by-value */ @@ -719,18 +775,16 @@ static void statement( void ) } 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" ); + /* TODO: check if parameter is an array of char, + get length of the defined array and put it into the parameter + of getline */ + emit( "{ size_t _n = %d; fgets( (char *)&", 255 ); } else { emit( "%s( ", varName ); } parameterList( ); /* TODO: procedure call */ 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( ");" ); @@ -806,8 +860,8 @@ static void arrayType( void ) type( ); /* type is in ident */ lastType.type = TYPE_ARRAY; - lastType.array.type = strToBasicType( ident ); - lastType.array.len = num; + lastType.details.array.type = strToBasicType( ident ); + lastType.details.array.len = num; } else { Abort( "of' expected in array definition" ); } @@ -818,10 +872,8 @@ static void type( void ) identifier( ); if( sym == S_ident ) { simpleType( ); - isArray = 0; } else if( sym == S_array ) { arrayType( ); - isArray = 1; } } @@ -832,7 +884,7 @@ static void variableDeclaration( void ) Expect( S_colon ); type( ); insert_symbol( lastType, varName ); - if( isArray ) { + if( lastType.type == TYPE_ARRAY ) { emitLn( "static %s %s[%d];", typeName, varName, num ); } else { emitLn( "static %s %s;", typeName, varName ); diff --git a/minie/test6.e b/minie/test6.e index 15e5969..42838ef 100644 --- a/minie/test6.e +++ b/minie/test6.e @@ -8,7 +8,7 @@ var begin system.readline( s ); - len := len( s ); + len := length( s ); system.writestring( "String: " ); system.writeline( s ); system.writestring( "Length: " ); |