From 41568587eaee36488b70e6e76b2f9ea68890471e Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Sun, 14 Jan 2024 19:46:20 +0100 Subject: updated todos and documentation --- miniany/cc.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 54 insertions(+), 11 deletions(-) (limited to 'miniany/cc.c') diff --git a/miniany/cc.c b/miniany/cc.c index 22781a2..64c881f 100644 --- a/miniany/cc.c +++ b/miniany/cc.c @@ -34,8 +34,9 @@ enum { S_RETURN, S_PUTINT, S_PUTCHAR, - S_IDENT = 60, - S_NUM = 70, + S_PUTNL, + S_IDENT = 70, + S_NUM = 80, S_EOI = 98, S_ERR = 99 }; @@ -198,6 +199,8 @@ int keyword( char *ident ) return S_PUTINT; } else if( strcmp( ident, "putchar" ) == 0 ) { return S_PUTCHAR; + } else if( strcmp( ident, "putnl" ) == 0 ) { + return S_PUTNL; } break; @@ -947,10 +950,17 @@ int genCompare( char *op, struct Generator *generator, int leftreg, int rightreg int genFuncCall( struct Generator *generator, char *name ) { + /* TODO: push parameters to stack in reverse order */ + putstring( "push eax" ); + putnl( ); putstring( "call " ); putstring( name ); putnl( ); + /* TODO: compute size of all parameters, adjust stack pointer */ + putstring( "add esp, 4" ); + putnl( ); + /* return value is in EAX by calling convention */ return EAX; } @@ -1035,6 +1045,7 @@ void genPrologue( struct Compiler *compiler ) putstring( "use32" ); putnl( ); putstring( "org $1000000" ); putnl( ); putstring( "jmp _start" ); putnl( ); + putstring( "putchar:" ); putnl( ); putstring( "mov [putint_string_fmt], eax" ); putnl( ); putstring( "mov eax, 4" ); putnl( ); @@ -1043,8 +1054,10 @@ void genPrologue( struct Compiler *compiler ) putstring( "mov edx, 1" ); putnl( ); putstring( "int 0x80" ); putnl( ); putstring( "ret" ); putnl( ); + putstring( "putint:" ); putnl( ); putstring( "mov esi, 0" ); putnl( ); + putstring( "mov ecx, 0" ); putnl( ); putstring( "lea edi, [putint_string_fmt]" ); putnl( ); putstring( "itoa_init:" ); putnl( ); putstring( "mov byte [edi], 0x20" ); putnl( ); @@ -1054,17 +1067,20 @@ void genPrologue( struct Compiler *compiler ) putstring( "jne itoa_init" ); putnl( ); putstring( "inc esi"); putnl( ); putstring( "itoa_loop:" ); putnl( ); + putstring( "mov ebx, 0" ); putnl( ); putstring( "mov edx, 0" ); putnl( ); putstring( "div esi" ); putnl( ); putstring( "add edx, 0x30" ); putnl( ); putstring( "mov byte [edi], dl" ); putnl( ); putstring( "dec edi" ); putnl( ); + putstring( "inc ecx" ); putnl( ); putstring( "cmp eax, 0" ); putnl( ); putstring( "jnz itoa_loop" ); putnl( ); - putstring( "mov eax, 4" ); putnl( ); + putstring( "inc edi" ); putnl( ); + putstring( "mov edx, ecx" ); putnl( ); + putstring( "mov ecx, edi" ); putnl( ); putstring( "mov ebx, 1" ); putnl( ); - putstring( "mov ecx, putint_string_fmt" ); putnl( ); - putstring( "mov edx, 11" ); putnl( ); + putstring( "mov eax, 4" ); putnl( ); putstring( "int 0x80" ); putnl( ); putstring( "ret" ); putnl( ); } @@ -1088,7 +1104,7 @@ void genEpilogue( struct Compiler *compiler ) sym = sym->next; } putstring( "putint_string_fmt:" ); putnl( ); - putstring( "db \" \", 10, 0" ); putnl( ); + putstring( "db \" \", 0" ); putnl( ); } /* parser */ @@ -1229,10 +1245,7 @@ struct ASTnode *parseFunctionCall( struct Parser *parser, struct Symbol *sym ) struct ASTnode *node, *left; parserExpect( parser, S_LPAREN, "(" ); - /* TODO: parse parameters as expressions: left = parseExpression( parser, 0 ); - */ - left = NULL; parserExpect( parser, S_RPAREN, ")" ); node = createASTunary( A_FUNC_CALL, left ); node->sym = sym; @@ -1283,6 +1296,13 @@ struct ASTnode *parseExpression( struct Parser *parser, int level ) putnl( ); exit( EXIT_FAILURE ); } + } else if( parser->token == S_LPAREN ) { + /* TODO: what should level be here exactly? */ + parserExpect( parser, S_LPAREN, "(" ); + left = parseExpression( parser, level ); + parserExpect( parser, S_RPAREN, ")" ); + } else if( parser->token == S_RPAREN ) { + left = NULL; } else { left = NULL; scannerPrintErrorHeader( parser->scanner ); @@ -1433,6 +1453,21 @@ void parsePutchar( struct Compiler *compiler ) freeASTnode( node ); } +void parsePutnl( struct Compiler *compiler ) +{ + struct Parser *parser; + + parser = compiler->parser; + parserExpect( parser, S_PUTNL, "putnl" ); + parserExpect( parser, S_LPAREN, "(" ); + parserExpect( parser, S_RPAREN, ")" ); + parserExpect( parser, S_SEMICOLON, ";" ); + putstring( "mov eax, 10" ); putnl( ); + putstring( "push eax" ); putnl( ); + putstring( "call putchar" ); putnl( ); + genFreeAllRegs( compiler->generator ); +} + /* TODO c4: forward reference of function */ void parseStatementBlock( struct Compiler *compiler ); @@ -1606,6 +1641,8 @@ void parseStatement( struct Compiler *compiler ) parsePutint( compiler ); } else if( parser->token == S_PUTCHAR ) { parsePutchar( compiler ); + } else if( parser->token == S_PUTNL ) { + parsePutnl( compiler ); } else if( parser->token == S_IF ) { parseIf( compiler ); } else if( parser->token == S_WHILE ) { @@ -1674,8 +1711,13 @@ void parseFunctionDeclaration( struct Compiler *compiler ) putstring( parser->scanner->ident ); putchar( ':' ); putnl( ); putstring( "push ebp" ); putnl( ); putstring( "mov ebp, esp" ); putnl( ); + /* TODO: create local scope with local symbols with address information + * pointing to ESP+8, +c, +10, etc. */ + /* TODO: align stack on 4-byte 'sub esp, 4*N' and 'and esp, 0xfffffff0' */ parserExpect( parser, S_LPAREN, "(" ); - /* TODO: parse parameter list */ + while( parser->token != S_RPAREN ) { + compiler->parser->token = getToken( compiler->parser->scanner ); + } parserExpect( parser, S_RPAREN, ")" ); parseStatementBlock( compiler ); @@ -1689,6 +1731,7 @@ void parseFunctionDeclaration( struct Compiler *compiler ) exit( EXIT_FAILURE ); } + putstring( "mov esp, ebp" ); putnl( ); putstring( "pop ebp" ); putnl( ); putstring( "ret" ); putnl( ); genFreeAllRegs( compiler->generator ); @@ -1723,7 +1766,7 @@ int main( int argc, char **argv ) compiler = createCompiler( ); /* compiler->parser->scanner->debug = 1; */ compiler->parser->debug = 1; - /* compiler->generator->debug = 1; */ + compiler->generator->debug = 1; genPrologue( compiler ); compiler->parser->token = getToken( compiler->parser->scanner ); while( compiler->parser->token != S_EOI ) { -- cgit v1.2.3-54-g00ecf