diff options
author | Andreas Baumann <mail@andreasbaumann.cc> | 2019-03-09 21:39:05 +0100 |
---|---|---|
committer | Andreas Baumann <mail@andreasbaumann.cc> | 2019-03-09 21:39:05 +0100 |
commit | 27e108db73c9c8d89fc5d15df73396abd7fa6a50 (patch) | |
tree | 7330b8ef14ff1e1753b4c3c0c260353a0db9e319 /minie | |
parent | 0abefa3cdee7b821c49c2eab28b2c7b2b34a88e7 (diff) | |
download | compilertests-27e108db73c9c8d89fc5d15df73396abd7fa6a50.tar.gz compilertests-27e108db73c9c8d89fc5d15df73396abd7fa6a50.tar.bz2 |
introducing better symbol table.. work in progress
Diffstat (limited to 'minie')
-rw-r--r-- | minie/TODOS | 35 | ||||
-rw-r--r-- | minie/e2c.c | 514 |
2 files changed, 362 insertions, 187 deletions
diff --git a/minie/TODOS b/minie/TODOS index edae44a..d06e971 100644 --- a/minie/TODOS +++ b/minie/TODOS @@ -244,6 +244,41 @@ point to types. This also means we usually get a global namespace this way, so a variable 'a', a type 'a' and a procedure 'a' cannot co-exist. +procdure types + +type + Func = procdure( x : integer, y : integer ) : char; +var + f : func; +begin + f := nil; + +this is a pointer to a function, so is 'pointer to procdure' better as +in a pointer to a procedure implementing that inteface? also, the 'x' +and 'y' don't really have a semantic meaning in the type declaration +as I can assign also a matching function 'f2': + +procdure f2( a : integer, b : integer ) : char; +begin + ... +end + +f := f2; + +nil should most likely end in an exception. but this means we have to +check a special condition on every function call. + +e2c or C-transpiler questions + +Symbol for scanner and Symbol for symbol table clash, we should use modules +and different names. And why are we insisting on having no preprocessor +and only one e2c.c? + +set/bitset/enum + +set: mutually exclusive +bitset: usable as switches, flags + links ----- diff --git a/minie/e2c.c b/minie/e2c.c index d20098b..920c130 100644 --- a/minie/e2c.c +++ b/minie/e2c.c @@ -12,9 +12,8 @@ enum { MAX_ERRMSG_LEN = 64, MAX_STRING_LEN = 64, MAX_SYMBOLS = 64, - MAX_RECORD_MEMBERS = 8, - MAX_PARAMETERS = 4, - MAX_TYPE_DATA_SIZE = 2048 + MAX_RECORD_MEMBERS = 4, + MAX_PARAMETERS = 4 }; /* scanner */ @@ -70,7 +69,7 @@ typedef enum { S_more, S_not_equals, S_eof -} Symbol; +} Scanner_Symbol; char *symname[S_eof+1] = { "char", @@ -118,7 +117,7 @@ char *symname[S_eof+1] = { "eof" }; -static Symbol sym; +static Scanner_Symbol sym; static void Err( char *s, va_list args ) { @@ -279,7 +278,7 @@ cont: look = getChar( ); } -static Symbol getSym( void ) +static Scanner_Symbol getSym( void ) { next: skipWhite( ); @@ -512,82 +511,94 @@ next: /* symbol table */ typedef enum { - TYPE_UNKNOWN, - TYPE_INTEGER, - TYPE_BOOLEAN, - TYPE_BYTE, - TYPE_CHAR, + SYMBOL_TYPE = 1, + SYMBOL_VARIABLE = 2, + SYMBOL_CONSTANT = 4, + SYMBOL_PROCEDURE = 8, + SYMBOL_MODULE = 16 +} SymbolKind; + +static const SymbolKind SYMBOL_ANY = SYMBOL_TYPE | SYMBOL_VARIABLE | SYMBOL_CONSTANT | SYMBOL_PROCEDURE | SYMBOL_MODULE; + +typedef enum { + TYPE_BASIC, TYPE_ARRAY, TYPE_RECORD, - TYPE_FUNCTION, - TYPE_CONSTANT, - TYPE_NONE -} BasicType; + TYPE_PROCEDURE, + TYPE_NONE, + TYPE_ANY +} TypeKind; -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 Symbol Symbol; typedef struct Type Type; typedef struct ArrayType { - char data[MAX_TYPE_DATA_SIZE]; Type *type; int len; } ArrayType; typedef struct RecordType { - char data[MAX_TYPE_DATA_SIZE*MAX_RECORD_MEMBERS]; - struct Type *type[MAX_RECORD_MEMBERS]; + Type *type[MAX_RECORD_MEMBERS]; int len; } RecordType; -typedef struct FunctionType { - char data[MAX_TYPE_DATA_SIZE*MAX_PARAMETERS]; - struct Type *params[MAX_PARAMETERS]; - struct Type *return_value; +typedef struct Procedure { + Type *params[MAX_PARAMETERS]; + Type *return_value; int len; - int internal; -} FunctionType; + /* TODO: later origin, module + int internal;*/ +} Procedure; + +typedef enum BasicType { + TYPE_INTEGER, + TYPE_BOOLEAN, + TYPE_CHAR, + TYPE_BYTE +} BasicType; + +struct Type { + TypeKind kind; + union { + BasicType basic; + ArrayType array; + RecordType *record; + Procedure *procedure; + } type; +}; + +typedef struct Variable { + Type *type; +} Variable; -typedef struct ConstantType { - BasicType type; +/* TODO: constants are only possible to define from basic types currently */ +typedef struct Constant { + Type *type; union { int boolean; int integer; - char byte; char character; + char byte; } value; -} ConstantType; +} Constant; -struct Type { - BasicType type; +struct Symbol { + SymbolKind kind; char name[MAX_IDENT_LEN]; union { - ArrayType array; - RecordType record; - FunctionType function; - ConstantType constant; - } details; + Type type; + Variable variable; + Constant constant; + Procedure procedure; + } symbol; }; typedef struct SymbolTable SymbolTable; struct SymbolTable { int nof_symbols; - Type symbols[MAX_SYMBOLS]; + Symbol symbols[MAX_SYMBOLS]; SymbolTable *parent; }; @@ -600,39 +611,67 @@ static void init_symboltable( SymbolTable *table, SymbolTable *parent ) table->parent = parent; } -static void insert_symbol( SymbolTable *table, Type type, char *name ) +static Symbol *insert_symbol( SymbolTable *table, char *name ) { if( table->nof_symbols >= MAX_SYMBOLS ) { Abort( "Symbol table exhausted, increase MAX_SYMBOLS and recompile e2c" ); } - - table->symbols[table->nof_symbols] = type; + strncpy( table->symbols[table->nof_symbols].name, name, MAX_IDENT_LEN ); + table->symbols[table->nof_symbols].name[MAX_IDENT_LEN-1] = '\0'; table->nof_symbols++; + + return &table->symbols[table->nof_symbols-1]; } -static Type get_symbol_type( SymbolTable *table, char *name ) +/* TODO: this is inefficient and should be a search tree of sorts */ +static Symbol *get_symbol( SymbolTable *table, char *name, SymbolKind kind ) { int i; /* search in table of currect scope */ for( i = 0; i < table->nof_symbols; i++ ) { - if( strcmp( table->symbols[i].name, name ) == 0 ) { - return table->symbols[i]; + if( strcmp( table->symbols[i].name, name ) == 0 && ( table->symbols[i].kind == kind ) ) { + return &table->symbols[i]; } } /* traverse stack of parent symbol tables */ if( table->parent != NULL ) { - return get_symbol_type( table->parent, name ); + return get_symbol( table->parent, name, kind ); + } + + return NULL; +} + +static Type *get_type_symbol( SymbolTable *table, char *name ) +{ + Symbol *symbol = get_symbol( table, name, SYMBOL_TYPE ); + + if( symbol->kind != SYMBOL_TYPE ) { + Abort( "Expected name of a type for '%s'", name ); } - Abort( "Unknown symbol '%s'", name ); + return &symbol->symbol.type; } +#if 0 +/* done with symbol table now */ +static Type *strToBasicType( SymbolTable *table, char *name ) +{ + Type *type = get_type_symbol( table, name ); + + if( type == NULL || type->kind != TYPE_BASIC ) { + Abort( "'%s' is not a basic type as expected", name ); + } + + return type; +} +#endif + static char *basicTypeToCType( BasicType type ) -{ +{ switch( type ) { case TYPE_INTEGER: return "signed int"; @@ -653,10 +692,18 @@ static char *typeToCType( Type *type ) { static char s[MAX_IDENT_LEN]; - if( type->type == TYPE_ARRAY ) { - sprintf( s, "%s*", basicTypeToCType( type->details.array.type->type ) ); + if( type->kind == TYPE_ARRAY ) { + Type *subType = type->type.array.type; + /* TODO: must be a basic type for now */ + if( subType->kind == TYPE_BASIC ) { + sprintf( s, "%s*", basicTypeToCType( subType->type.basic ) ); + } else { + Abort( "Arrays are currently only possible for basic types" ); + } + } else if( type->kind == TYPE_BASIC ) { + sprintf( s, "%s ", basicTypeToCType( type->type.basic ) ); } else { - sprintf( s, "%s ", basicTypeToCType( type->type ) ); + Abort( "Unknown complex type to C mapping" ); } return s; @@ -666,11 +713,11 @@ static char *typeToCType( Type *type ) static int length( char *name ) { - Type type; + Type *type; - type = get_symbol_type( current_scope, name ); - if( type.type == TYPE_ARRAY ) { - return type.details.array.len; + type = get_type_symbol( current_scope, name ); + if( type != NULL && type->kind == TYPE_ARRAY ) { + return type->type.array.len; } else { Abort( "length called on non-array variable '%s'", name ); } @@ -680,10 +727,9 @@ static int length( char *name ) static char moduleName[MAX_IDENT_LEN+1]; static char varName[MAX_IDENT_LEN+1]; -static Type lastType; static char procName[MAX_IDENT_LEN+1]; -static void Expect( Symbol expect ) +static void Expect( Scanner_Symbol expect ) { if( sym == expect ) { sym = getSym( ); @@ -711,61 +757,102 @@ static void emit( char *s, ... ) fflush( stdout ); } -static void register_internal_functions( void ) +static void register_internal_types( void ) { - Type type; + Symbol *symbol; - /* register compiler-internal functions */ - type.type = TYPE_FUNCTION; - type.details.function.len = 1; - type.details.function.params[0] = (Type *)type.details.function.data; - type.details.function.params[0]->type = TYPE_ARRAY; - type.details.function.return_value = (Type *)( type.details.function.data + sizeof( Type ) ); - type.details.function.return_value->type = TYPE_INTEGER; - type.details.function.internal = 1; - insert_symbol( &symbols, type, "length" ); + /* basic types */ + symbol = insert_symbol( &symbols, "integer" ); + symbol->kind = SYMBOL_TYPE; + symbol->symbol.type.kind = TYPE_BASIC; + + symbol = insert_symbol( &symbols, "boolean" ); + symbol->kind = SYMBOL_TYPE; + symbol->symbol.type.kind = TYPE_BASIC; + + symbol = insert_symbol( &symbols, "char" ); + symbol->kind = SYMBOL_TYPE; + symbol->symbol.type.kind = TYPE_BASIC; + + symbol = insert_symbol( &symbols, "byte" ); + symbol->kind = SYMBOL_TYPE; + symbol->symbol.type.kind = TYPE_BASIC; - /* constructor for char type */ - type.type = TYPE_FUNCTION; - type.details.function.len = 1; - type.details.function.params[0] = (Type *)type.details.function.data; - type.details.function.params[0]->type = TYPE_INTEGER; - type.details.function.return_value = (Type *)( type.details.function.data + sizeof( Type ) ); - type.details.function.return_value->type = TYPE_CHAR; - type.details.function.internal = 1; - insert_symbol( &symbols, type, "char" ); - - /* TODO: register functions in module system, should be outside in the stage-1 compiler */ + /* the any type (for the type in the array for length) */ + symbol = insert_symbol( &symbols, "__any" ); + symbol->kind = SYMBOL_TYPE; + symbol->symbol.type.kind = TYPE_ANY; + + /* the null type (for procedures not returning a type) */ + symbol = insert_symbol( &symbols, "__void" ); + symbol->kind = SYMBOL_TYPE; + symbol->symbol.type.kind = TYPE_NONE; + + /* array of any type (for length) */ + symbol = insert_symbol( &symbols, "__gen_array_of_any" ); + symbol->kind = SYMBOL_TYPE; + symbol->symbol.type.kind = TYPE_ARRAY; + symbol->symbol.type.type.array.len = 0; + symbol->symbol.type.type.array.type = get_type_symbol( &symbols, "__any" ); - type.type = TYPE_FUNCTION; - type.details.function.len = 0; - type.details.function.return_value = (Type *)type.details.function.data; - type.details.function.return_value->type = TYPE_CHAR; - type.details.function.internal = 1; - insert_symbol( &symbols, type, "system.readchar" ); - - type.type = TYPE_FUNCTION; - type.details.function.len = 1; - type.details.function.params[0] = (Type *)type.details.function.data; - type.details.function.params[0]->type = TYPE_ARRAY; - type.details.function.return_value = (Type *)type.details.function.data; - type.details.function.return_value->type = TYPE_NONE; - type.details.function.internal = 1; - insert_symbol( &symbols, type, "system.readline" ); + /* array of any size of char (string, for system.readline) */ + symbol = insert_symbol( &symbols, "__gen_array_of_char" ); + symbol->kind = SYMBOL_TYPE; + symbol->symbol.type.kind = TYPE_ARRAY; + symbol->symbol.type.type.array.len = 0; + symbol->symbol.type.type.array.type = get_type_symbol( &symbols, "char" ); } static void register_internal_constants( void ) { - Type type; + Symbol *symbol; - type.type = TYPE_CONSTANT; - type.details.constant.type = TYPE_BOOLEAN; - type.details.constant.value.boolean = 1; - insert_symbol( &symbols, type, "true" ); + symbol = insert_symbol( &symbols, "true" ); + symbol->kind = SYMBOL_CONSTANT; + symbol->symbol.constant.type = get_type_symbol( &symbols, "boolean" ); + symbol->symbol.constant.value.boolean = 1; + + symbol = insert_symbol( &symbols, "false" ); + symbol->kind = SYMBOL_CONSTANT; + symbol->symbol.constant.type = get_type_symbol( &symbols, "boolean" ); + symbol->symbol.constant.value.boolean = 0; +} + +static void register_internal_functions( void ) +{ + Symbol *symbol; - type.details.constant.type = TYPE_BOOLEAN; - type.details.constant.value.boolean = 0; - insert_symbol( &symbols, type, "false" ); + /* internal compiler functions, are always internal to the compiler as they need + * special treatment */ + + /* get length of any array */ + symbol = insert_symbol( &symbols, "length" ); + symbol->kind = SYMBOL_PROCEDURE; + symbol->symbol.procedure.return_value = get_type_symbol( &symbols, "integer" ); + symbol->symbol.procedure.len = 1; + symbol->symbol.procedure.params[0] = get_type_symbol( &symbols, "__gen_array_of_any" ); + + /* constructor for char type (from type integer) */ + symbol = insert_symbol( &symbols, "char" ); + symbol->kind = SYMBOL_PROCEDURE; + symbol->symbol.procedure.return_value = get_type_symbol( &symbols, "char" ); + symbol->symbol.procedure.len = 1; + symbol->symbol.procedure.params[0] = get_type_symbol( &symbols, "integer" ); + + /* TODO: register functions in module system, should be outside in the stage-1 compiler, + * should also add a system module symbol first and attach all procedures to it + * needs a rewrite of the qualifier matching code, so later.. + */ + symbol = insert_symbol( &symbols, "system.readchar" ); + symbol->kind = SYMBOL_PROCEDURE; + symbol->symbol.procedure.return_value = get_type_symbol( &symbols, "char" ); + symbol->symbol.procedure.len = 0; + + symbol = insert_symbol( &symbols, "system.readline" ); + symbol->kind = SYMBOL_PROCEDURE; + symbol->symbol.procedure.return_value = get_type_symbol( &symbols, "__void" ); + symbol->symbol.procedure.len = 1; + symbol->symbol.procedure.params[0] = get_type_symbol( &symbols, "__gen_array_of_char" ); } static void init( void ) @@ -799,9 +886,10 @@ static void prologue( void ) "}" ); init_symboltable( &symbols, NULL ); - - register_internal_functions( ); + + register_internal_types( ); register_internal_constants( ); + register_internal_functions( ); } static void epilogue( void ) @@ -847,7 +935,7 @@ static void parameterList( void ); static void factor( void ) { - Type type; + Symbol *symbol; if( sym == S_plus ) { sym = getSym( ); @@ -866,16 +954,31 @@ static void factor( void ) sym = getSym( ); } else if( sym == S_ident ) { qualident( ); - type = get_symbol_type( current_scope, varName ); - if( type.type == TYPE_FUNCTION ) { + symbol = get_symbol( current_scope, varName, SYMBOL_ANY ); + if( symbol->kind == SYMBOL_TYPE && symbol->symbol.type.kind == TYPE_PROCEDURE ) { parameterList( ); - } else if( type.type == TYPE_CONSTANT ) { - if( type.details.constant.type == TYPE_BOOLEAN || type.details.constant.type == TYPE_INTEGER ) { - emit( "%d", type.details.constant.value ); + } else if( symbol->kind == SYMBOL_CONSTANT ) { + if( symbol->symbol.constant.type->kind == TYPE_BASIC ) { + switch( symbol->symbol.constant.type->type.basic ) { + case TYPE_BOOLEAN: + emit( "%d", symbol->symbol.constant.value.boolean ); + break; + case TYPE_INTEGER: + emit( "%d", symbol->symbol.constant.value.integer ); + break; + case TYPE_CHAR: + emit( "%c", symbol->symbol.constant.value.character ); + break; + case TYPE_BYTE: + emit( "%d", symbol->symbol.constant.value.byte ); + break; + default: + Abort( "Unknown basic type constant '%s'", varName ); + } } else { - Abort( "Unknown constant '%s'", varName ); + Abort( "Unknown complex constant '%s'", varName ); } - } else if( type.type == TYPE_ARRAY ) { + } else if( symbol->kind == SYMBOL_TYPE && symbol->symbol.type.kind == TYPE_ARRAY ) { if( sym == S_lbracket ) { sym = getSym( ); emit( "%s[", varName ); @@ -885,8 +988,10 @@ static void factor( void ) } else { emit( "%s", varName ); } - } else { + } else if( symbol->kind == SYMBOL_VARIABLE ) { emit( "%s", varName ); + } else { + Abort( "Unkown factor symbol '%s'", varName ); } } else if( sym == S_lparen ) { emit( "(" ); @@ -923,7 +1028,7 @@ static void simpleExpression( void ) } } -static int isRelationalOperator( Symbol sym ) +static int isRelationalOperator( Scanner_Symbol sym ) { if( sym == S_less || sym == S_less_or_equals || sym == S_equals || sym == S_more || @@ -965,13 +1070,13 @@ static int selected_array; static void selector( void ) { - Type type; + Type *type; selected_array = 0; if( sym == S_lbracket ) { Expect( S_lbracket ); - type = get_symbol_type( current_scope, varName ); - if( type.type != TYPE_ARRAY ) { + type = get_type_symbol( current_scope, varName ); + if( type != NULL && type->kind != TYPE_ARRAY ) { Abort( "Selecting element of non-array" ); } selected_array = 1; @@ -986,12 +1091,15 @@ static void selector( void ) static void assignment( void ) { - Type type; + Type *type; /* left hand side */ /* precondition: qualident has been already parsed outside */ selector( ); - type = get_symbol_type( current_scope, varName ); + type = get_type_symbol( current_scope, varName ); + if( type == NULL ) { + Abort( "Unknown type for variable '%s'", varName ); + } /* x := ( a+ b )- 3; -> x = (a+b)-3; * s1 := s2; -> strncpy( s2, s1, length( s2 ) ); @@ -1003,7 +1111,8 @@ static void assignment( void ) * way without an AST in-between */ - if( type.type == TYPE_ARRAY && type.details.array.type->type == TYPE_CHAR ) { + if( type->kind != TYPE_ARRAY && type->type.array.type->kind == TYPE_BASIC + && type->type.array.type->type.basic == TYPE_CHAR ) { emit( "strncpy( %s, ", varName ); } else { if( selected_array ) { @@ -1019,9 +1128,10 @@ static void assignment( void ) /* right hand side, any expression */ expression( ); - if( type.type == TYPE_ARRAY && type.details.array.type->type == TYPE_CHAR ) { - emit( ", %d ); ", type.details.array.len ); - emit( "%s[%d-1] = '\\0'", varName, type.details.array.len ); + if( type->kind != TYPE_ARRAY && type->type.array.type->kind == TYPE_BASIC + && type->type.array.type->type.basic == TYPE_CHAR ) { + emit( ", %d ); ", type->type.array.len ); + emit( "%s[%d-1] = '\\0'", varName, type->type.array.len ); } emitLn( ";" ); } @@ -1198,13 +1308,15 @@ static void statement( void ) parameterList( ); emitLn( ";" ); } else { - Type type = get_symbol_type( current_scope, varName ); - if( type.type == TYPE_FUNCTION ) { + Symbol *symbol = get_symbol( current_scope, varName, SYMBOL_ANY ); + if( symbol->kind == SYMBOL_PROCEDURE ) { /* procedure call without parameter */ /* TODO: check number of parameter and return value to be 0 */ emitLn( "%s( );", varName ); - } else { + } else if( symbol->kind == SYMBOL_VARIABLE ) { assignment( ); + } else { + Abort( "Expected variable for assignment or a procedure for a procedure call for '%s'", varName ); } } } else { @@ -1233,31 +1345,26 @@ static void statementBlock( void ) Expect( S_end ); } -static void type( void ); +static Type *doType( void ); -static void simpleType( void ) +static Type *simpleType( void ) { - /* TODO: handle build-in types in init, register them in - type table */ - if( strcmp( ident, "integer" ) == 0 ) { - lastType.type = TYPE_INTEGER; - sym = getSym( ); - } else if( strcmp( ident, "boolean" ) == 0 ) { - lastType.type = TYPE_BOOLEAN; - sym = getSym( ); - } else if( strcmp( ident, "char" ) == 0 ) { - lastType.type = TYPE_CHAR; + Type *type; + type = get_type_symbol( current_scope, ident ); + if( type != NULL && type->kind == TYPE_BASIC ) { sym = getSym( ); - } else if( strcmp( ident, "byte" ) == 0 ) { - lastType.type = TYPE_BYTE; - sym = getSym( ); + return type; } else { Abort( "Unknown type '%s'", ident ); } } -static void arrayType( void ) +static Type *arrayType( void ) { + char typeName[MAX_STRING_LEN]; + Type *type; + Type *basicType; + sym = getSym( ); Expect( S_lbracket ); /* TODO: should be a const expression */ @@ -1270,24 +1377,31 @@ static void arrayType( void ) /* array size is in num */ if( sym == S_of ) { sym = getSym( ); - type( ); - /* type is in ident */ - lastType.type = TYPE_ARRAY; - lastType.details.array.type = (Type *)&lastType.details.array.data; - lastType.details.array.type->type = strToBasicType( ident ); - lastType.details.array.len = num; + basicType = doType( ); + /* TODO here: this is an anonymous type of an array of len and basic type */ + sprintf( typeName, "__array_%d_of_%s", num, ident ); + type = get_type_symbol( current_scope, typeName ); + if( type == NULL ) { + Symbol *symbol = insert_symbol( current_scope, typeName ); + symbol->kind = SYMBOL_TYPE; + symbol->symbol.type.kind = TYPE_ARRAY; + symbol->symbol.type.type.array.len = num; + symbol->symbol.type.type.array.type = basicType; + type = &symbol->symbol.type; + } + return type; } else { Abort( "of' expected in array definition" ); } } -static void type( void ) +static Type *doType( ) { identifier( ); if( sym == S_ident ) { - simpleType( ); + return simpleType( ); } else if( sym == S_array ) { - arrayType( ); + return arrayType( ); } } static void constDeclaration( void ) @@ -1298,13 +1412,14 @@ static void constDeclaration( void ) Expect( S_equals ); /* TODO: ConstExpression requires an interpreter */ if( sym == S_number ) { - Type type; + Symbol *symbol; number( ); sym = getSym( ); - type.type = TYPE_CONSTANT; - type.details.constant.type = TYPE_INTEGER; - type.details.constant.value.integer = num; - insert_symbol( current_scope, type, varName ); + symbol = insert_symbol( &symbols, varName ); + symbol->kind = SYMBOL_CONSTANT; + /* TODO: deduce type from value (byte/integer)? */ + symbol->symbol.constant.type = get_type_symbol( &symbols, "integer" ); + symbol->symbol.constant.value.integer = num; } else { Abort( "Supporting numeric constants only" ); } @@ -1327,20 +1442,33 @@ static void constBlock( void ) static void variableDeclaration( void ) { + Type *type; + Symbol *symbol; + variableName( ); sym = getSym( ); Expect( S_colon ); - type( ); - insert_symbol( current_scope, lastType, varName ); - if( lastType.type == TYPE_ARRAY ) { - /* TODO: this works for now, though it's not correct */ - emitLn( "static %s %s[%d];", - basicTypeToCType( lastType.details.array.type->type ), - varName, num ); + type = doType( ); + symbol = insert_symbol( current_scope, varName ); + symbol->kind = SYMBOL_VARIABLE; + symbol->symbol.variable.type = type; + if( type->kind == TYPE_ARRAY ) { + if( type->type.array.type->kind == TYPE_BASIC ) { + /* TODO: this works for now, though it's not correct */ + emitLn( "static %s %s[%d];", + basicTypeToCType( type->type.array.type->type.basic ), + varName, num ); + } else { + Abort( "Declaring an array '%s' with no basic type is not supported", varName ); + } } else { - emitLn( "static %s %s;", - basicTypeToCType( lastType.type ), - varName ); + if( type->type.array.type->kind == TYPE_BASIC ) { + emitLn( "static %s %s;", + basicTypeToCType( type->type.array.type->type.basic ), + varName ); + } else { + Abort( "User defined types not supported" ); + } } } @@ -1371,27 +1499,39 @@ static void procedureName( void ) static void procedureDeclaration( void ) { char return_type[MAX_IDENT_LEN]; - Type funcType; + Symbol *symbol; + Type *funcType; SymbolTable locals; init_symboltable( &locals, current_scope ); - - funcType.type = TYPE_FUNCTION; - funcType.details.function.internal = 0; - funcType.details.function.len = 0; - + Expect( S_procedure ); procedureName( ); + + symbol = insert_symbol( &locals, procName ); + symbol->kind = TYPE_PROCEDURE; + symbol->symbol.procedure.len = 0; + +#if 0 + //~ symbol->symbol.procedure.return_value = get_type_symbol( &symbols, "integer" ); + //~ symbol->symbol.procedure.params[0] = get_type_symbol( &symbols, "__gen_array_of_any" ); +#endif + sym = getSym( ); if( sym == S_lparen ) { sym = getSym( ); /* TODO: || S_var later */ if( sym == S_ident ) { do { - if( funcType.details.function.len >= MAX_PARAMETERS ) { + if( symbol->symbol.procedure.len >= MAX_PARAMETERS ) { Abort( "Too many parameters in definition of procedure" ); } identifier( ); + /* TODO from here */ + /* lookup types, define local variables as parameters */ + symbol->symbol.procedure.params[symbol->symbol.procedure.len] + + funcType.details.function.params[funcType.details.function.len] = (Type *)( &funcType.details.function.data + sizeof( Type ) * funcType.details.function.len ); strncpy( funcType.details.function.params[funcType.details.function.len]->name, ident, MAX_IDENT_LEN ); funcType.details.function.params[funcType.details.function.len]->name[MAX_IDENT_LEN-1] = '\0'; @@ -1400,13 +1540,13 @@ static void procedureDeclaration( void ) if( sym == S_array ) { sym = getSym( ); Expect( S_of ); - type( ); + doType( ); funcType.details.function.params[funcType.details.function.len]->type = TYPE_ARRAY; funcType.details.function.params[funcType.details.function.len]->details.array.len = 0; funcType.details.function.params[funcType.details.function.len]->details.array.type = (Type *)&funcType.details.function.params[funcType.details.function.len]->details.array.data; funcType.details.function.params[funcType.details.function.len]->details.array.type->type = lastType.type; } else { - type( ); + doType( ); funcType.details.function.params[funcType.details.function.len]->type = lastType.type; } insert_symbol( &locals, *funcType.details.function.params[funcType.details.function.len], |