diff options
Diffstat (limited to 'miniany/cc.c')
-rw-r--r-- | miniany/cc.c | 49 |
1 files changed, 47 insertions, 2 deletions
diff --git a/miniany/cc.c b/miniany/cc.c index 6e3f391..cef1af2 100644 --- a/miniany/cc.c +++ b/miniany/cc.c @@ -28,6 +28,7 @@ enum { S_IF, S_ELSE, S_WHILE, + S_DO, S_PUTINT, S_IDENT = 60, S_NUM = 70, @@ -162,11 +163,15 @@ void scanIdent( struct Scanner *scanner ) int keyword( char *ident ) { switch( ident[0] ) { + case 'd': + if( strcmp( ident, "do" ) == 0 ) { + return S_DO; + } + break; + case 'e': if( strcmp( ident, "else" ) == 0 ) { return S_ELSE; - } else { - return 0; } break; @@ -1329,6 +1334,44 @@ void parseWhile( struct Compiler *compiler ) free( label1 ); } +void parseDo( struct Compiler *compiler ) +{ + struct Parser *parser; + struct ASTnode *node; + char *label1; + + parser = compiler->parser; + parserExpect( parser, S_DO, "do" ); + if( compiler->generator->debug ) { + putstring( "; do" ); putnl( ); + } + label1 = genGetLabel( compiler, compiler->parser->global_scope ); + putstring( label1 ); putchar( ':' ); putnl( ); + parseStatementBlock( compiler ); + parserExpect( parser, S_WHILE, "while" ); + parserExpect( parser, S_LPAREN, "(" ); + node = parseExpression( parser, 0 ); + generateFromAST( compiler->generator, node, NOREG ); + putstring( "cmp al, 0" ); putnl( ); + putstring( "jne " ); putstring( label1 ); putnl( ); + genFreeAllRegs( compiler->generator ); + 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; @@ -1344,6 +1387,8 @@ void parseStatement( struct Compiler *compiler ) parseIf( compiler ); } else if( parser->token == S_WHILE ) { parseWhile( compiler ); + } else if( parser->token == S_DO ) { + parseDo( compiler ); } else if( parser->token == S_RBRACE || parser->token == S_EOI ) { return; } else { |