summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2021-09-24 19:07:50 +0000
committerAndreas Baumann <mail@andreasbaumann.cc>2021-09-24 19:07:50 +0000
commitd0491186abedd36a6e065e97bf29eaaf87f6f95c (patch)
tree21cfa4049b5f98dfb0e7b54b634e700f1a6eb5f4
parent728d58d5cbea121faf26699bca726db2530ae71a (diff)
downloadcompilertests-d0491186abedd36a6e065e97bf29eaaf87f6f95c.tar.gz
compilertests-d0491186abedd36a6e065e97bf29eaaf87f6f95c.tar.bz2
cc: about to emulate a printint build-in keyword (for now just prints a string)
-rw-r--r--miniany/REQUIREMENTS7
-rw-r--r--miniany/cc.c67
-rw-r--r--miniany/test1.c1
3 files changed, 69 insertions, 6 deletions
diff --git a/miniany/REQUIREMENTS b/miniany/REQUIREMENTS
index 7dcfc78..0472c1e 100644
--- a/miniany/REQUIREMENTS
+++ b/miniany/REQUIREMENTS
@@ -110,3 +110,10 @@ TODO:
- static: just ignore, we don't have a linker, otoh, just rewrite it whithout static,
vararg, etc.
- c4.c: checkout c5-AST branch (darn, that one looks more promising to extend!)
+- cc.c: putint as a command in the language for early debugging (as in early Pascal),
+ points to a fundamental conflict: bootstrapping is better with stdout and stdin in
+ the language (no linker, no function calls etc. needed). OTOH we don't want to
+ have I/O as part of the language later, more be in the standard library.
+ Inline assembly in the generated code duplicates code with the putint in libc-freestanding.
+
+
diff --git a/miniany/cc.c b/miniany/cc.c
index 4d26893..b9cfe5a 100644
--- a/miniany/cc.c
+++ b/miniany/cc.c
@@ -15,6 +15,7 @@ enum {
S_SEMICOLON,
S_EQUALS,
S_INT = 10,
+ S_PUTINT,
S_IDENT = 20,
S_NUM = 30,
S_EOI = 98,
@@ -155,6 +156,15 @@ int keyword( char *ident )
return 0;
}
break;
+
+ case 'p':
+ if( strcmp( ident, "putint" ) == 0 ) {
+ return S_PUTINT;
+ } else {
+ return 0;
+ }
+ break;
+
default:
return 0;
}
@@ -782,12 +792,37 @@ int generateFromAST( struct Generator *generator, struct ASTnode *node, int inre
void genPrologue( struct Compiler *compiler )
{
- putstring( "format binary" );
- putnl( );
- putstring( "use32" );
- putnl( );
- putstring( "org $1000000" );
- putnl( );
+ putstring( "format binary" ); putnl( );
+ putstring( "use32" ); putnl( );
+ putstring( "org $1000000" ); putnl( );
+ putstring( "jmp _start" ); putnl( );
+ putstring( "putint:" ); putnl( );
+ putstring( "mov eax, 4" ); putnl( );
+ putstring( "mov ebx, 1" ); putnl( );
+ /* TODO: itoa in assembly (yuck!) and print resulting string */
+ putstring( "mov ecx, putint_string" ); putnl( );
+ /* TODO: compute length with a assemble time function sizeof or so.. */
+ putstring( "mov edx, 13" ); putnl( );
+ putstring( "int 0x80" ); putnl( );
+ putstring( "ret 4" ); putnl( );
+ putstring( "_start:" ); putnl( );
+
+/*
+ __asm__ volatile( "\
+ push %%ebx\n\
+ push %%ecx\n\
+ push %%edx\n\
+ mov %1, %%eax\n\
+ mov %2, %%ebx\n\
+ mov %3, %%ecx\n\
+ mov %4, %%edx\n\
+ int $0x80\n\
+ mov %%eax, %0\n\
+ pop %%edx\n\
+ pop %%ecx\n\
+ pop %%ebx\n" : "=m"( retval ) : "m"( id ), "m"( arg0 ), "m"( arg1 ), "m"( arg2 )
+ : "eax", "ebx", "ecx", "edx" );
+ */
}
void genEpilogue( struct Compiler *compiler )
@@ -801,6 +836,8 @@ void genEpilogue( struct Compiler *compiler )
genAddGlob( compiler->generator, sym->name );
sym = sym->next;
}
+ putstring( "putint_string:" ); putnl( );
+ putstring( "db \"putint test \", 10, 0" ); putnl( );
}
/* parser */
@@ -1002,6 +1039,22 @@ void parseAssignment( struct Compiler *compiler )
freeASTnode( node );
}
+void parsePutint( struct Compiler *compiler )
+{
+ struct Parser *parser;
+ struct ASTnode *node;
+
+ parser = compiler->parser;
+ parserExpect( parser, S_PUTINT, "putint" );
+ node = parseExpression( parser, 0 );
+ parserExpect( parser, S_SEMICOLON, ";" );
+ generateFromAST( compiler->generator, node, NOREG );
+ putstring( "push eax" ); putnl( );
+ putstring( "call putint" ); putnl( );
+ genFreeAllRegs( compiler->generator );
+ freeASTnode( node );
+}
+
void parseStatement( struct Compiler *compiler )
{
struct Parser *parser;
@@ -1011,6 +1064,8 @@ void parseStatement( struct Compiler *compiler )
parseDeclaration( compiler );
} else if( parser->token == S_IDENT ) {
parseAssignment( compiler );
+ } else if( parser->token == S_PUTINT ) {
+ parsePutint( compiler );
} else if( parser->token == S_EOI ) {
return;
} else {
diff --git a/miniany/test1.c b/miniany/test1.c
index 4eeffed..d7015e2 100644
--- a/miniany/test1.c
+++ b/miniany/test1.c
@@ -5,3 +5,4 @@ int j;
i = 12+25/5-2*3; // 25/5 -> 5, 12+5 -> 17, 2*3 -> 6, 17-6 -> 11
j = i/3+3*4; // 11 / 3 -> 3, 3*4 -> 12, 3+12 -> 15
+putint i;