summaryrefslogtreecommitdiff
path: root/miniany/cc.c
diff options
context:
space:
mode:
Diffstat (limited to 'miniany/cc.c')
-rw-r--r--miniany/cc.c49
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 {