From b0c6943121f186c79d2152694d209f82904ff1e1 Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Thu, 30 Sep 2021 17:03:17 +0200 Subject: cc: rearanged for a pseudo-main --- miniany/cc.c | 77 ++++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 52 insertions(+), 25 deletions(-) (limited to 'miniany/cc.c') diff --git a/miniany/cc.c b/miniany/cc.c index cef1af2..5cf2f9c 100644 --- a/miniany/cc.c +++ b/miniany/cc.c @@ -487,6 +487,7 @@ struct Parser { int token; struct Scanner *scanner; struct Scope *global_scope; + int debug; }; struct Generator { @@ -940,6 +941,10 @@ int generateFromAST( struct Generator *generator, struct ASTnode *node, int inre void genPrologue( struct Compiler *compiler ) { + if( compiler->parser->debug ) { + putstring( "; prologue" ); + putnl( ); + } putstring( "format binary" ); putnl( ); putstring( "use32" ); putnl( ); putstring( "org $1000000" ); putnl( ); @@ -968,15 +973,19 @@ void genPrologue( struct Compiler *compiler ) putstring( "mov edx, 11" ); putnl( ); putstring( "int 0x80" ); putnl( ); putstring( "ret" ); putnl( ); - putstring( "_start:" ); putnl( ); } void genEpilogue( struct Compiler *compiler ) { struct Symbol *sym; - putstring( "hlt" ); - putnl( ); + if( compiler->parser->debug ) { + putstring( "; entry point" ); + putnl( ); + } + putstring( "_start:" ); putnl( ); + putstring( "call main" ); putnl( ); + putstring( "hlt" ); putnl( ); sym = compiler->parser->global_scope->sym; while( sym != NULL ) { genAddGlob( compiler->generator, sym->name ); @@ -995,6 +1004,7 @@ struct Parser *createParser( ) parser = (struct Parser *)malloc( sizeof( struct Parser ) ); parser->scanner = createScanner( ); parser->global_scope = createScope( "global" ); + parser->debug = 0; return parser; } @@ -1269,22 +1279,22 @@ void parseIf( struct Compiler *compiler ) parserExpect( parser, S_IF, "if" ); parserExpect( parser, S_LPAREN, "(" ); node = parseExpression( parser, 0 ); - if( compiler->generator->debug ) { + if( parser->debug ) { putstring( "; if then" ); putnl( ); } generateFromAST( compiler->generator, node, NOREG ); /* TODO: this should be condensed and optimized for the normal path * (rare ifs, invert the condition, jmpXX directly */ putstring( "cmp al, 0" ); putnl( ); + genFreeAllRegs( compiler->generator ); label1 = genGetLabel( compiler, compiler->parser->global_scope ); putstring( "je " ); putstring( label1 ); putnl( ); - genFreeAllRegs( compiler->generator ); parserExpect( parser, S_RPAREN, ")" ); parseStatementBlock( compiler ); if( parser->token == S_ELSE ) { label2 = genGetLabel( compiler, compiler->parser->global_scope ); putstring( "jmp " ); putstring( label2 ); putnl( ); - if( compiler->generator->debug ) { + if( parser->debug ) { putstring( "; else" ); putnl( ); } putstring( label1 ); putchar( ':' ); putnl( ); @@ -1296,7 +1306,7 @@ void parseIf( struct Compiler *compiler ) putstring( label1 ); putchar( ':' ); putnl( ); } - if( compiler->generator->debug ) { + if( parser->debug ) { putstring( "; fi" ); putnl( ); } free( label1 ); @@ -1313,21 +1323,21 @@ void parseWhile( struct Compiler *compiler ) parserExpect( parser, S_WHILE, "while" ); parserExpect( parser, S_LPAREN, "(" ); node = parseExpression( parser, 0 ); - if( compiler->generator->debug ) { + if( parser->debug ) { putstring( "; while " ); putnl( ); } label2 = genGetLabel( compiler, compiler->parser->global_scope ); putstring( label2 ); putchar( ':' ); putnl( ); generateFromAST( compiler->generator, node, NOREG ); putstring( "cmp al, 0" ); putnl( ); + genFreeAllRegs( compiler->generator ); label1 = genGetLabel( compiler, compiler->parser->global_scope ); putstring( "je " ); putstring( label1 ); putnl( ); - genFreeAllRegs( compiler->generator ); parserExpect( parser, S_RPAREN, ")" ); parseStatementBlock( compiler ); putstring( "jmp " ); putstring( label2 ); putnl( ); putstring( label1 ); putchar( ':' ); putnl( ); - if( compiler->generator->debug ) { + if( parser->debug ) { putstring( "; fi" ); putnl( ); } free( label2 ); @@ -1342,7 +1352,7 @@ void parseDo( struct Compiler *compiler ) parser = compiler->parser; parserExpect( parser, S_DO, "do" ); - if( compiler->generator->debug ) { + if( parser->debug ) { putstring( "; do" ); putnl( ); } label1 = genGetLabel( compiler, compiler->parser->global_scope ); @@ -1353,25 +1363,13 @@ void parseDo( struct Compiler *compiler ) node = parseExpression( parser, 0 ); generateFromAST( compiler->generator, node, NOREG ); putstring( "cmp al, 0" ); putnl( ); - putstring( "jne " ); putstring( label1 ); putnl( ); genFreeAllRegs( compiler->generator ); + putstring( "jne " ); putstring( label1 ); putnl( ); parserExpect( parser, S_RPAREN, ")" ); parserExpect( parser, S_SEMICOLON, ";" ); free( label1 ); } -/* - - - putstring( "jmp " ); putstring( label2 ); putnl( ); - putstring( label1 ); putchar( ':' ); putnl( ); - if( compiler->generator->debug ) { - putstring( "; fi" ); putnl( ); - } - free( label2 ); - free( label1 ); -} - */ void parseStatement( struct Compiler *compiler ) { struct Parser *parser; @@ -1413,6 +1411,34 @@ void parseStatementBlock( struct Compiler *compiler ) parserExpect( parser, S_RBRACE, "}" ); } +void parseFunctionDeclaraion( struct Compiler *compiler ) +{ + struct Parser *parser; + + 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 ); + } + } + parser->token = getToken( parser->scanner ); + if( parser->debug ) { + putstring( "; function declaration '" ); + putstring( parser->scanner->ident ); + putstring( "'" ); + putnl( ); + } + putstring( parser->scanner->ident ); putchar( ':' ); putnl( ); + parser->token = getToken( compiler->parser->scanner ); + parserExpect( parser, S_LPAREN, "(" ); + parserExpect( parser, S_RPAREN, ")" ); + parseStatementBlock( compiler ); + putstring( "ret" ); putnl( ); +} + /* compiler */ struct Compiler *createCompiler( ) @@ -1441,10 +1467,11 @@ int main( int argc, char **argv ) compiler = createCompiler( ); /* compiler->parser->scanner->debug = 1; */ + /* compiler->parser->debug = 1; */ /* compiler->generator->debug = 1; */ genPrologue( compiler ); compiler->parser->token = getToken( compiler->parser->scanner ); - parseStatementBlock( compiler ); + parseFunctionDeclaraion( compiler ); genEpilogue( compiler ); freeCompiler( compiler ); -- cgit v1.2.3-54-g00ecf