summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--miniany/REQUIREMENTS6
-rw-r--r--miniany/cc.c49
-rw-r--r--miniany/test1.c7
3 files changed, 58 insertions, 4 deletions
diff --git a/miniany/REQUIREMENTS b/miniany/REQUIREMENTS
index cbee3f2..985def7 100644
--- a/miniany/REQUIREMENTS
+++ b/miniany/REQUIREMENTS
@@ -126,5 +126,9 @@ TODO:
a variable. Knowing the contest would require an AST.
- AST should not be the output of whole programs, scoping is maybe better
- don't allow non-blocked if/else, just avoid dangling else problems
-
+- for loops: they simply have a too general and weird semantic in C (missing
+ semicolon after the last triplet). IMHO a for loop makes sense for SIMD
+ operations only when we can use a stricter grammar to optimize certain
+ iterations.
+
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 {
diff --git a/miniany/test1.c b/miniany/test1.c
index 4492d4f..4bf86e3 100644
--- a/miniany/test1.c
+++ b/miniany/test1.c
@@ -26,9 +26,14 @@
putint( 0 );
}
}
- i = 10;
+ i = 5;
while( i > 0 ) {
putint( i );
i = i-1;
}
+ i = 1;
+ do {
+ putint( i );
+ i = i+1;
+ } while( i <= 5 );
}