summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--miniany/cc.c49
-rw-r--r--miniany/test1.c5
2 files changed, 26 insertions, 28 deletions
diff --git a/miniany/cc.c b/miniany/cc.c
index 28d9f1c..6e3f391 100644
--- a/miniany/cc.c
+++ b/miniany/cc.c
@@ -27,6 +27,7 @@ enum {
S_INT = 50,
S_IF,
S_ELSE,
+ S_WHILE,
S_PUTINT,
S_IDENT = 60,
S_NUM = 70,
@@ -174,22 +175,23 @@ int keyword( char *ident )
return S_IF;
} else if( strcmp( ident, "int" ) == 0 ) {
return S_INT;
- } else {
- return 0;
}
break;
case 'p':
if( strcmp( ident, "putint" ) == 0 ) {
return S_PUTINT;
- } else {
- return 0;
}
break;
-
- default:
- return 0;
+
+ case 'w':
+ if( strcmp( ident, "while" ) == 0 ) {
+ return S_WHILE;
+ }
+ break;
}
+
+ return 0;
}
int getToken( struct Scanner *scanner )
@@ -1295,20 +1297,22 @@ void parseIf( struct Compiler *compiler )
free( label1 );
}
-/*
- void parseIf( struct Compiler *compiler )
+void parseWhile( struct Compiler *compiler )
{
struct Parser *parser;
struct ASTnode *node;
char *label1, *label2;
-
+
parser = compiler->parser;
- parserExpect( parser, S_IF, "if" );
+
+ parserExpect( parser, S_WHILE, "while" );
parserExpect( parser, S_LPAREN, "(" );
node = parseExpression( parser, 0 );
if( compiler->generator->debug ) {
- putstring( "; if <cond> then" ); putnl( );
+ putstring( "; while <cond>" ); putnl( );
}
+ label2 = genGetLabel( compiler, compiler->parser->global_scope );
+ putstring( label2 ); putchar( ':' ); putnl( );
generateFromAST( compiler->generator, node, NOREG );
putstring( "cmp al, 0" ); putnl( );
label1 = genGetLabel( compiler, compiler->parser->global_scope );
@@ -1316,28 +1320,15 @@ void parseIf( struct Compiler *compiler )
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 ) {
- putstring( "; else" ); putnl( );
- }
- putstring( label1 ); putchar( ':' ); putnl( );
- compiler->parser->token = getToken( compiler->parser->scanner );
- parseStatementBlock( compiler );
- putstring( label2 ); putchar( ':' ); putnl( );
- free( label2 );
- } else {
- putstring( label1 ); putchar( ':' ); putnl( );
- }
-
+ 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;
@@ -1351,6 +1342,8 @@ void parseStatement( struct Compiler *compiler )
parsePutint( compiler );
} else if( parser->token == S_IF ) {
parseIf( compiler );
+ } else if( parser->token == S_WHILE ) {
+ parseWhile( compiler );
} else if( parser->token == S_RBRACE || parser->token == S_EOI ) {
return;
} else {
diff --git a/miniany/test1.c b/miniany/test1.c
index 5747ca1..4492d4f 100644
--- a/miniany/test1.c
+++ b/miniany/test1.c
@@ -26,4 +26,9 @@
putint( 0 );
}
}
+ i = 10;
+ while( i > 0 ) {
+ putint( i );
+ i = i-1;
+ }
}