From d0491186abedd36a6e065e97bf29eaaf87f6f95c Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Fri, 24 Sep 2021 19:07:50 +0000 Subject: cc: about to emulate a printint build-in keyword (for now just prints a string) --- miniany/REQUIREMENTS | 7 ++++++ miniany/cc.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++----- miniany/test1.c | 1 + 3 files changed, 69 insertions(+), 6 deletions(-) diff --git a/miniany/REQUIREMENTS b/miniany/REQUIREMENTS index 7dcfc78..0472c1e 100644 --- a/miniany/REQUIREMENTS +++ b/miniany/REQUIREMENTS @@ -110,3 +110,10 @@ TODO: - static: just ignore, we don't have a linker, otoh, just rewrite it whithout static, vararg, etc. - c4.c: checkout c5-AST branch (darn, that one looks more promising to extend!) +- cc.c: putint as a command in the language for early debugging (as in early Pascal), + points to a fundamental conflict: bootstrapping is better with stdout and stdin in + the language (no linker, no function calls etc. needed). OTOH we don't want to + have I/O as part of the language later, more be in the standard library. + Inline assembly in the generated code duplicates code with the putint in libc-freestanding. + + diff --git a/miniany/cc.c b/miniany/cc.c index 4d26893..b9cfe5a 100644 --- a/miniany/cc.c +++ b/miniany/cc.c @@ -15,6 +15,7 @@ enum { S_SEMICOLON, S_EQUALS, S_INT = 10, + S_PUTINT, S_IDENT = 20, S_NUM = 30, S_EOI = 98, @@ -155,6 +156,15 @@ int keyword( char *ident ) return 0; } break; + + case 'p': + if( strcmp( ident, "putint" ) == 0 ) { + return S_PUTINT; + } else { + return 0; + } + break; + default: return 0; } @@ -782,12 +792,37 @@ int generateFromAST( struct Generator *generator, struct ASTnode *node, int inre void genPrologue( struct Compiler *compiler ) { - putstring( "format binary" ); - putnl( ); - putstring( "use32" ); - putnl( ); - putstring( "org $1000000" ); - putnl( ); + putstring( "format binary" ); putnl( ); + putstring( "use32" ); putnl( ); + putstring( "org $1000000" ); putnl( ); + putstring( "jmp _start" ); putnl( ); + putstring( "putint:" ); putnl( ); + putstring( "mov eax, 4" ); putnl( ); + putstring( "mov ebx, 1" ); putnl( ); + /* TODO: itoa in assembly (yuck!) and print resulting string */ + putstring( "mov ecx, putint_string" ); putnl( ); + /* TODO: compute length with a assemble time function sizeof or so.. */ + putstring( "mov edx, 13" ); putnl( ); + putstring( "int 0x80" ); putnl( ); + putstring( "ret 4" ); putnl( ); + putstring( "_start:" ); putnl( ); + +/* + __asm__ volatile( "\ + push %%ebx\n\ + push %%ecx\n\ + push %%edx\n\ + mov %1, %%eax\n\ + mov %2, %%ebx\n\ + mov %3, %%ecx\n\ + mov %4, %%edx\n\ + int $0x80\n\ + mov %%eax, %0\n\ + pop %%edx\n\ + pop %%ecx\n\ + pop %%ebx\n" : "=m"( retval ) : "m"( id ), "m"( arg0 ), "m"( arg1 ), "m"( arg2 ) + : "eax", "ebx", "ecx", "edx" ); + */ } void genEpilogue( struct Compiler *compiler ) @@ -801,6 +836,8 @@ void genEpilogue( struct Compiler *compiler ) genAddGlob( compiler->generator, sym->name ); sym = sym->next; } + putstring( "putint_string:" ); putnl( ); + putstring( "db \"putint test \", 10, 0" ); putnl( ); } /* parser */ @@ -1002,6 +1039,22 @@ void parseAssignment( struct Compiler *compiler ) freeASTnode( node ); } +void parsePutint( struct Compiler *compiler ) +{ + struct Parser *parser; + struct ASTnode *node; + + parser = compiler->parser; + parserExpect( parser, S_PUTINT, "putint" ); + node = parseExpression( parser, 0 ); + parserExpect( parser, S_SEMICOLON, ";" ); + generateFromAST( compiler->generator, node, NOREG ); + putstring( "push eax" ); putnl( ); + putstring( "call putint" ); putnl( ); + genFreeAllRegs( compiler->generator ); + freeASTnode( node ); +} + void parseStatement( struct Compiler *compiler ) { struct Parser *parser; @@ -1011,6 +1064,8 @@ void parseStatement( struct Compiler *compiler ) parseDeclaration( compiler ); } else if( parser->token == S_IDENT ) { parseAssignment( compiler ); + } else if( parser->token == S_PUTINT ) { + parsePutint( compiler ); } else if( parser->token == S_EOI ) { return; } else { diff --git a/miniany/test1.c b/miniany/test1.c index 4eeffed..d7015e2 100644 --- a/miniany/test1.c +++ b/miniany/test1.c @@ -5,3 +5,4 @@ int j; i = 12+25/5-2*3; // 25/5 -> 5, 12+5 -> 17, 2*3 -> 6, 17-6 -> 11 j = i/3+3*4; // 11 / 3 -> 3, 3*4 -> 12, 3+12 -> 15 +putint i; -- cgit v1.2.3-54-g00ecf