From f895cabf52336db0f2a259bbe6fae6e6fc81c98a Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Sun, 10 Oct 2021 19:46:42 +0200 Subject: cc: work on int, char types --- miniany/cc.c | 101 +++++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 78 insertions(+), 23 deletions(-) (limited to 'miniany/cc.c') diff --git a/miniany/cc.c b/miniany/cc.c index c630a8f..e977bc9 100644 --- a/miniany/cc.c +++ b/miniany/cc.c @@ -25,6 +25,8 @@ enum { S_MORE, S_MORE_OR_EQUALS, S_INT = 50, + S_CHAR, + S_VOID, S_IF, S_ELSE, S_WHILE, @@ -50,7 +52,7 @@ struct Scanner { void scannerPrintErrorHeader( struct Scanner *scanner ) { putnl( ); - putstring( "Error line " ); + putstring( "; ERROR: line " ); putint( scanner->row ); putstring( ", pos " ); putint( scanner->col ); @@ -163,6 +165,12 @@ void scanIdent( struct Scanner *scanner ) int keyword( char *ident ) { switch( ident[0] ) { + case 'c': + if( strcmp( ident, "char" ) == 0 ) { + return S_CHAR; + } + break; + case 'd': if( strcmp( ident, "do" ) == 0 ) { return S_DO; @@ -189,6 +197,12 @@ int keyword( char *ident ) } break; + case 'v': + if( strcmp( ident, "void" ) == 0 ) { + return S_VOID; + } + break; + case 'w': if( strcmp( ident, "while" ) == 0 ) { return S_WHILE; @@ -330,16 +344,24 @@ int getToken( struct Scanner *scanner ) /* symbol table */ +enum { + SYMBOL_CLASS_VARIABLE, + SYMBOL_CLASS_FUNCTION +}; + struct Symbol { - char *name; - struct Symbol *next; + int class; /* class SYMBOL_CLASS_XXX */ + char *name; /* name of the symbol */ + int type; /* type of variable when type is SYMBOL_CLASS_VARIABLE */ + struct Symbol *next; /* pointer to next symbol */ }; -struct Symbol *createSymbol( char *s ) +struct Symbol *createSymbol( int class, char *s ) { struct Symbol *sym; sym = (struct Symbol *)malloc( sizeof ( struct Symbol ) ); + sym->class = class; sym->name = strdup( s ); sym->next = NULL; @@ -586,11 +608,19 @@ void putlow8reg( struct Generator *generator, int reg ) } -void genAddGlob( struct Generator *generator, char *ident ) +void genAddGlob( struct Generator *generator, struct Symbol *sym ) { - putstring( ident ); + putstring( sym->name ); putstring( ": " ); - putstring( "dd $0" ); + switch( sym->type ) { + case S_INT: + putstring( "dd $0" ); + break; + + case S_CHAR: + putstring( "db $0" ); + break; + } putnl( ); } @@ -988,7 +1018,9 @@ void genEpilogue( struct Compiler *compiler ) putstring( "hlt" ); putnl( ); sym = compiler->parser->global_scope->sym; while( sym != NULL ) { - genAddGlob( compiler->generator, sym->name ); + if( sym->class == SYMBOL_CLASS_VARIABLE ) { + genAddGlob( compiler->generator, sym ); + } sym = sym->next; } putstring( "putint_string_fmt:" ); putnl( ); @@ -1180,17 +1212,38 @@ struct ASTnode *parseExpression( struct Parser *parser, int level ) return left; } -void parseDeclaration( struct Compiler *compiler ) +int parseType( struct Compiler *compiler ) +{ + struct Parser *parser; + int type; + + parser = compiler->parser; + if( parser->token == S_INT || parser->token == S_CHAR || parser->token == S_VOID ) { + type = parser->token; + parser->token = getToken( parser->scanner ); + } else { + scannerPrintErrorHeader( parser->scanner ); + putstring( "type expected" ); + putnl( ); + exit( EXIT_FAILURE ); + } + + return type; +} + +void parseVariableDeclaration( struct Compiler *compiler ) { struct Parser *parser; struct Symbol *sym; + int type; parser = compiler->parser; - parserExpect( parser, S_INT, "int" ); + type = parseType( compiler ); parserExpect( parser, S_IDENT, "identifier" ); sym = getSymbol( parser->global_scope, parser->scanner->ident ); if( sym == NULL ) { - sym = createSymbol( parser->scanner->ident ); + sym = createSymbol( SYMBOL_CLASS_VARIABLE, parser->scanner->ident ); + sym->type = type; insertSymbol( parser->global_scope, sym ); } else { scannerPrintErrorHeader( parser->scanner ); @@ -1338,7 +1391,7 @@ void parseWhile( struct Compiler *compiler ) putstring( "jmp " ); putstring( label2 ); putnl( ); putstring( label1 ); putchar( ':' ); putnl( ); if( parser->debug ) { - putstring( "; fi" ); putnl( ); + putstring( "; end while" ); putnl( ); } free( label2 ); free( label1 ); @@ -1359,6 +1412,9 @@ void parseDo( struct Compiler *compiler ) putstring( label1 ); putchar( ':' ); putnl( ); parseStatementBlock( compiler ); parserExpect( parser, S_WHILE, "while" ); + if( parser->debug ) { + putstring( "; end do, while " ); putnl( ); + } parserExpect( parser, S_LPAREN, "(" ); node = parseExpression( parser, 0 ); generateFromAST( compiler->generator, node, NOREG ); @@ -1375,8 +1431,8 @@ void parseStatement( struct Compiler *compiler ) struct Parser *parser; parser = compiler->parser; - if( parser->token == S_INT ) { - parseDeclaration( compiler ); + if( parser->token == S_INT || parser->token == S_CHAR ) { + parseVariableDeclaration( compiler ); } else if( parser->token == S_IDENT ) { parseAssignment( compiler ); } else if( parser->token == S_PUTINT ) { @@ -1415,22 +1471,22 @@ void parseFunctionDeclaration( struct Compiler *compiler ) { struct Parser *parser; struct Symbol *sym; + int type; parser = compiler->parser; - if( parser->token == S_IDENT ) { - if( strcmp( parser->scanner->ident, "void" ) != 0 ) { - scannerPrintErrorHeader( parser->scanner ); - putstring( "expected void as return value of a function declaration" ); - putnl( ); - exit( EXIT_FAILURE ); - } + type = parseType( compiler ); + if( type != S_VOID ) { + scannerPrintErrorHeader( parser->scanner ); + putstring( "expected void as return value of a function declaration" ); + putnl( ); + exit( EXIT_FAILURE ); } parserExpect( parser, S_IDENT, "identifier" ); sym = getSymbol( parser->global_scope, parser->scanner->ident ); if( sym == NULL ) { - sym = createSymbol( parser->scanner->ident ); + sym = createSymbol( SYMBOL_CLASS_FUNCTION, parser->scanner->ident ); insertSymbol( parser->global_scope, sym ); } else { scannerPrintErrorHeader( parser->scanner ); @@ -1450,7 +1506,6 @@ void parseFunctionDeclaration( struct Compiler *compiler ) putstring( parser->scanner->ident ); putchar( ':' ); putnl( ); putstring( "push ebp" ); putnl( ); putstring( "mov ebp, esp" ); putnl( ); - parser->token = getToken( compiler->parser->scanner ); parserExpect( parser, S_LPAREN, "(" ); parserExpect( parser, S_RPAREN, ")" ); parseStatementBlock( compiler ); -- cgit v1.2.3-54-g00ecf