summaryrefslogtreecommitdiff
path: root/miniany/cc.c
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2024-01-14 19:46:20 +0100
committerAndreas Baumann <mail@andreasbaumann.cc>2024-01-14 19:46:20 +0100
commit41568587eaee36488b70e6e76b2f9ea68890471e (patch)
tree87bf362dd5bad006d96983f6848bb3c878b59a2e /miniany/cc.c
parent7bde6411b1b82cafd997df8ac222e82280a6e786 (diff)
downloadcompilertests-41568587eaee36488b70e6e76b2f9ea68890471e.tar.gz
compilertests-41568587eaee36488b70e6e76b2f9ea68890471e.tar.bz2
updated todos and documentation
Diffstat (limited to 'miniany/cc.c')
-rw-r--r--miniany/cc.c65
1 files changed, 54 insertions, 11 deletions
diff --git a/miniany/cc.c b/miniany/cc.c
index 22781a2..64c881f 100644
--- a/miniany/cc.c
+++ b/miniany/cc.c
@@ -34,8 +34,9 @@ enum {
S_RETURN,
S_PUTINT,
S_PUTCHAR,
- S_IDENT = 60,
- S_NUM = 70,
+ S_PUTNL,
+ S_IDENT = 70,
+ S_NUM = 80,
S_EOI = 98,
S_ERR = 99
};
@@ -198,6 +199,8 @@ int keyword( char *ident )
return S_PUTINT;
} else if( strcmp( ident, "putchar" ) == 0 ) {
return S_PUTCHAR;
+ } else if( strcmp( ident, "putnl" ) == 0 ) {
+ return S_PUTNL;
}
break;
@@ -947,10 +950,17 @@ int genCompare( char *op, struct Generator *generator, int leftreg, int rightreg
int genFuncCall( struct Generator *generator, char *name )
{
+ /* TODO: push parameters to stack in reverse order */
+ putstring( "push eax" );
+ putnl( );
putstring( "call " );
putstring( name );
putnl( );
+ /* TODO: compute size of all parameters, adjust stack pointer */
+ putstring( "add esp, 4" );
+ putnl( );
+ /* return value is in EAX by calling convention */
return EAX;
}
@@ -1035,6 +1045,7 @@ void genPrologue( struct Compiler *compiler )
putstring( "use32" ); putnl( );
putstring( "org $1000000" ); putnl( );
putstring( "jmp _start" ); putnl( );
+
putstring( "putchar:" ); putnl( );
putstring( "mov [putint_string_fmt], eax" ); putnl( );
putstring( "mov eax, 4" ); putnl( );
@@ -1043,8 +1054,10 @@ void genPrologue( struct Compiler *compiler )
putstring( "mov edx, 1" ); putnl( );
putstring( "int 0x80" ); putnl( );
putstring( "ret" ); putnl( );
+
putstring( "putint:" ); putnl( );
putstring( "mov esi, 0" ); putnl( );
+ putstring( "mov ecx, 0" ); putnl( );
putstring( "lea edi, [putint_string_fmt]" ); putnl( );
putstring( "itoa_init:" ); putnl( );
putstring( "mov byte [edi], 0x20" ); putnl( );
@@ -1054,17 +1067,20 @@ void genPrologue( struct Compiler *compiler )
putstring( "jne itoa_init" ); putnl( );
putstring( "inc esi"); putnl( );
putstring( "itoa_loop:" ); putnl( );
+ putstring( "mov ebx, 0" ); putnl( );
putstring( "mov edx, 0" ); putnl( );
putstring( "div esi" ); putnl( );
putstring( "add edx, 0x30" ); putnl( );
putstring( "mov byte [edi], dl" ); putnl( );
putstring( "dec edi" ); putnl( );
+ putstring( "inc ecx" ); putnl( );
putstring( "cmp eax, 0" ); putnl( );
putstring( "jnz itoa_loop" ); putnl( );
- putstring( "mov eax, 4" ); putnl( );
+ putstring( "inc edi" ); putnl( );
+ putstring( "mov edx, ecx" ); putnl( );
+ putstring( "mov ecx, edi" ); putnl( );
putstring( "mov ebx, 1" ); putnl( );
- putstring( "mov ecx, putint_string_fmt" ); putnl( );
- putstring( "mov edx, 11" ); putnl( );
+ putstring( "mov eax, 4" ); putnl( );
putstring( "int 0x80" ); putnl( );
putstring( "ret" ); putnl( );
}
@@ -1088,7 +1104,7 @@ void genEpilogue( struct Compiler *compiler )
sym = sym->next;
}
putstring( "putint_string_fmt:" ); putnl( );
- putstring( "db \" \", 10, 0" ); putnl( );
+ putstring( "db \" \", 0" ); putnl( );
}
/* parser */
@@ -1229,10 +1245,7 @@ struct ASTnode *parseFunctionCall( struct Parser *parser, struct Symbol *sym )
struct ASTnode *node, *left;
parserExpect( parser, S_LPAREN, "(" );
- /* TODO: parse parameters as expressions:
left = parseExpression( parser, 0 );
- */
- left = NULL;
parserExpect( parser, S_RPAREN, ")" );
node = createASTunary( A_FUNC_CALL, left );
node->sym = sym;
@@ -1283,6 +1296,13 @@ struct ASTnode *parseExpression( struct Parser *parser, int level )
putnl( );
exit( EXIT_FAILURE );
}
+ } else if( parser->token == S_LPAREN ) {
+ /* TODO: what should level be here exactly? */
+ parserExpect( parser, S_LPAREN, "(" );
+ left = parseExpression( parser, level );
+ parserExpect( parser, S_RPAREN, ")" );
+ } else if( parser->token == S_RPAREN ) {
+ left = NULL;
} else {
left = NULL;
scannerPrintErrorHeader( parser->scanner );
@@ -1433,6 +1453,21 @@ void parsePutchar( struct Compiler *compiler )
freeASTnode( node );
}
+void parsePutnl( struct Compiler *compiler )
+{
+ struct Parser *parser;
+
+ parser = compiler->parser;
+ parserExpect( parser, S_PUTNL, "putnl" );
+ parserExpect( parser, S_LPAREN, "(" );
+ parserExpect( parser, S_RPAREN, ")" );
+ parserExpect( parser, S_SEMICOLON, ";" );
+ putstring( "mov eax, 10" ); putnl( );
+ putstring( "push eax" ); putnl( );
+ putstring( "call putchar" ); putnl( );
+ genFreeAllRegs( compiler->generator );
+}
+
/* TODO c4: forward reference of function */
void parseStatementBlock( struct Compiler *compiler );
@@ -1606,6 +1641,8 @@ void parseStatement( struct Compiler *compiler )
parsePutint( compiler );
} else if( parser->token == S_PUTCHAR ) {
parsePutchar( compiler );
+ } else if( parser->token == S_PUTNL ) {
+ parsePutnl( compiler );
} else if( parser->token == S_IF ) {
parseIf( compiler );
} else if( parser->token == S_WHILE ) {
@@ -1674,8 +1711,13 @@ void parseFunctionDeclaration( struct Compiler *compiler )
putstring( parser->scanner->ident ); putchar( ':' ); putnl( );
putstring( "push ebp" ); putnl( );
putstring( "mov ebp, esp" ); putnl( );
+ /* TODO: create local scope with local symbols with address information
+ * pointing to ESP+8, +c, +10, etc. */
+ /* TODO: align stack on 4-byte 'sub esp, 4*N' and 'and esp, 0xfffffff0' */
parserExpect( parser, S_LPAREN, "(" );
- /* TODO: parse parameter list */
+ while( parser->token != S_RPAREN ) {
+ compiler->parser->token = getToken( compiler->parser->scanner );
+ }
parserExpect( parser, S_RPAREN, ")" );
parseStatementBlock( compiler );
@@ -1689,6 +1731,7 @@ void parseFunctionDeclaration( struct Compiler *compiler )
exit( EXIT_FAILURE );
}
+ putstring( "mov esp, ebp" ); putnl( );
putstring( "pop ebp" ); putnl( );
putstring( "ret" ); putnl( );
genFreeAllRegs( compiler->generator );
@@ -1723,7 +1766,7 @@ int main( int argc, char **argv )
compiler = createCompiler( );
/* compiler->parser->scanner->debug = 1; */
compiler->parser->debug = 1;
- /* compiler->generator->debug = 1; */
+ compiler->generator->debug = 1;
genPrologue( compiler );
compiler->parser->token = getToken( compiler->parser->scanner );
while( compiler->parser->token != S_EOI ) {