summaryrefslogtreecommitdiff
path: root/miniany/cc.c
diff options
context:
space:
mode:
Diffstat (limited to 'miniany/cc.c')
-rw-r--r--miniany/cc.c77
1 files changed, 52 insertions, 25 deletions
diff --git a/miniany/cc.c b/miniany/cc.c
index cef1af2..5cf2f9c 100644
--- a/miniany/cc.c
+++ b/miniany/cc.c
@@ -487,6 +487,7 @@ struct Parser {
int token;
struct Scanner *scanner;
struct Scope *global_scope;
+ int debug;
};
struct Generator {
@@ -940,6 +941,10 @@ int generateFromAST( struct Generator *generator, struct ASTnode *node, int inre
void genPrologue( struct Compiler *compiler )
{
+ if( compiler->parser->debug ) {
+ putstring( "; prologue" );
+ putnl( );
+ }
putstring( "format binary" ); putnl( );
putstring( "use32" ); putnl( );
putstring( "org $1000000" ); putnl( );
@@ -968,15 +973,19 @@ void genPrologue( struct Compiler *compiler )
putstring( "mov edx, 11" ); putnl( );
putstring( "int 0x80" ); putnl( );
putstring( "ret" ); putnl( );
- putstring( "_start:" ); putnl( );
}
void genEpilogue( struct Compiler *compiler )
{
struct Symbol *sym;
- putstring( "hlt" );
- putnl( );
+ if( compiler->parser->debug ) {
+ putstring( "; entry point" );
+ putnl( );
+ }
+ putstring( "_start:" ); putnl( );
+ putstring( "call main" ); putnl( );
+ putstring( "hlt" ); putnl( );
sym = compiler->parser->global_scope->sym;
while( sym != NULL ) {
genAddGlob( compiler->generator, sym->name );
@@ -995,6 +1004,7 @@ struct Parser *createParser( )
parser = (struct Parser *)malloc( sizeof( struct Parser ) );
parser->scanner = createScanner( );
parser->global_scope = createScope( "global" );
+ parser->debug = 0;
return parser;
}
@@ -1269,22 +1279,22 @@ void parseIf( struct Compiler *compiler )
parserExpect( parser, S_IF, "if" );
parserExpect( parser, S_LPAREN, "(" );
node = parseExpression( parser, 0 );
- if( compiler->generator->debug ) {
+ if( parser->debug ) {
putstring( "; if <cond> then" ); putnl( );
}
generateFromAST( compiler->generator, node, NOREG );
/* TODO: this should be condensed and optimized for the normal path
* (rare ifs, invert the condition, jmpXX directly */
putstring( "cmp al, 0" ); putnl( );
+ genFreeAllRegs( compiler->generator );
label1 = genGetLabel( compiler, compiler->parser->global_scope );
putstring( "je " ); putstring( label1 ); putnl( );
- 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 ) {
+ if( parser->debug ) {
putstring( "; else" ); putnl( );
}
putstring( label1 ); putchar( ':' ); putnl( );
@@ -1296,7 +1306,7 @@ void parseIf( struct Compiler *compiler )
putstring( label1 ); putchar( ':' ); putnl( );
}
- if( compiler->generator->debug ) {
+ if( parser->debug ) {
putstring( "; fi" ); putnl( );
}
free( label1 );
@@ -1313,21 +1323,21 @@ void parseWhile( struct Compiler *compiler )
parserExpect( parser, S_WHILE, "while" );
parserExpect( parser, S_LPAREN, "(" );
node = parseExpression( parser, 0 );
- if( compiler->generator->debug ) {
+ if( parser->debug ) {
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( );
+ genFreeAllRegs( compiler->generator );
label1 = genGetLabel( compiler, compiler->parser->global_scope );
putstring( "je " ); putstring( label1 ); putnl( );
- genFreeAllRegs( compiler->generator );
parserExpect( parser, S_RPAREN, ")" );
parseStatementBlock( compiler );
putstring( "jmp " ); putstring( label2 ); putnl( );
putstring( label1 ); putchar( ':' ); putnl( );
- if( compiler->generator->debug ) {
+ if( parser->debug ) {
putstring( "; fi" ); putnl( );
}
free( label2 );
@@ -1342,7 +1352,7 @@ void parseDo( struct Compiler *compiler )
parser = compiler->parser;
parserExpect( parser, S_DO, "do" );
- if( compiler->generator->debug ) {
+ if( parser->debug ) {
putstring( "; do" ); putnl( );
}
label1 = genGetLabel( compiler, compiler->parser->global_scope );
@@ -1353,25 +1363,13 @@ void parseDo( struct Compiler *compiler )
node = parseExpression( parser, 0 );
generateFromAST( compiler->generator, node, NOREG );
putstring( "cmp al, 0" ); putnl( );
- putstring( "jne " ); putstring( label1 ); putnl( );
genFreeAllRegs( compiler->generator );
+ putstring( "jne " ); putstring( label1 ); putnl( );
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;
@@ -1413,6 +1411,34 @@ void parseStatementBlock( struct Compiler *compiler )
parserExpect( parser, S_RBRACE, "}" );
}
+void parseFunctionDeclaraion( struct Compiler *compiler )
+{
+ struct Parser *parser;
+
+ parser = compiler->parser;
+ if( parser->token == S_IDENT ) {
+ if( strcmp( parser->scanner->ident, "void" ) != 0 ) {
+ scannerPrintErrorHeader( parser->scanner );
+ putstring( "expected void as return value of a function declaration" );
+ putnl( );
+ exit( EXIT_FAILURE );
+ }
+ }
+ parser->token = getToken( parser->scanner );
+ if( parser->debug ) {
+ putstring( "; function declaration '" );
+ putstring( parser->scanner->ident );
+ putstring( "'" );
+ putnl( );
+ }
+ putstring( parser->scanner->ident ); putchar( ':' ); putnl( );
+ parser->token = getToken( compiler->parser->scanner );
+ parserExpect( parser, S_LPAREN, "(" );
+ parserExpect( parser, S_RPAREN, ")" );
+ parseStatementBlock( compiler );
+ putstring( "ret" ); putnl( );
+}
+
/* compiler */
struct Compiler *createCompiler( )
@@ -1441,10 +1467,11 @@ int main( int argc, char **argv )
compiler = createCompiler( );
/* compiler->parser->scanner->debug = 1; */
+ /* compiler->parser->debug = 1; */
/* compiler->generator->debug = 1; */
genPrologue( compiler );
compiler->parser->token = getToken( compiler->parser->scanner );
- parseStatementBlock( compiler );
+ parseFunctionDeclaraion( compiler );
genEpilogue( compiler );
freeCompiler( compiler );