summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--miniany/Makefile3
-rw-r--r--miniany/README.html11
-rwxr-xr-xminiany/build.sh3
-rw-r--r--miniany/cc.c77
-rw-r--r--miniany/cc.wg13
-rw-r--r--miniany/test1.c1
6 files changed, 75 insertions, 33 deletions
diff --git a/miniany/Makefile b/miniany/Makefile
index 7ebaf6c..38d36e8 100644
--- a/miniany/Makefile
+++ b/miniany/Makefile
@@ -11,4 +11,7 @@ README.html: cc.md
cc.md: cc.wg
wordgrinder -c cc.wg cc.md
sed -i 's/`/\n```\n/g' cc.md
+ sed -i 's/\\</</g' cc.md
+ sed -i 's/\\>/>/g' cc.md
+
\ No newline at end of file
diff --git a/miniany/README.html b/miniany/README.html
index 40c9c49..9b7fcbf 100644
--- a/miniany/README.html
+++ b/miniany/README.html
@@ -38,7 +38,7 @@
<p>Compiled in either hosted (host libc) or freestanding (our own libc, currently IA-32 Linux kernel only syscalls):</p>
<pre><code>./build.sh cc hostcc hosted d
./build.sh cc hostcc freestanding d
-./cc \&lt; test1.c \&gt; test1.asm
+./cc &lt; test1.c &gt; test1.asm
</code></pre>
<p>Create a plain binary from the assembly code:</p>
<pre><code>fasm test1.asm test1.bin
@@ -54,12 +54,12 @@
</code></pre>
<p>Here again you can choose the host compiler for compiling C4.</p>
<p>Then we have to create the standard input for C4 using:</p>
-<pre><code>echo -n -e &quot;\034&quot; \&gt; EOF
+<pre><code>echo -n -e &quot;\034&quot; &gt; EOF
cat cc.c EOF hello.c | ./c4
cat c4.c EOF cc.c EOF hello.c | ./c4
cat c4.c4 EOF c4.c EOF cc.c EOF hello.c | ./c4
</code></pre>
-<p>EOF contains the traditional FS (file separator) character in the ASCII character set. Every time c4/c4.c is invoked it reads exacly one input file up to the first FS character (or stops at the end of stdin).</p>
+<p>EOF contains the traditional FS (file separator) character in the ASCII character set. Every time c4 is invoked it reads exacly one input file up to the first FS character (or stops at the end of stdin).</p>
<p>We can also use <i>-s</i>, or <i>-d </i>on every level as follows:</p>
<pre><code>cat cc.c EOF hello.c | ./c4 -d
</code></pre>
@@ -89,3 +89,8 @@ cat c4.c4 EOF c4.c EOF cc.c EOF hello.c | ./c4
<li><a href="https://github.com/felipensp/assembly/blob/master/x86/itoa.s">https://github.com/felipensp/assembly/blob/master/x86/itoa.s</a>, for putint (early debugging keyword)</li>
<li><a href="https://baptiste-wicht.com/posts/2011/11/print-strings-integers-intel-assembly.htm">https://baptiste-wicht.com/posts/2011/11/print-strings-integers-intel-assembly.htm</a> (earldy debugging keyword)</li>
</ul>
+<p>Documentation:</p>
+<ul>
+<li><a href="http://cowlark.com/wordgrinder/index.html">http://cowlark.com/wordgrinder/index.html</a>: the fabulous editor which just does what it should do</li>
+<li><a href="https://github.com/mity/md4c">https://github.com/mity/md4c</a>: markdown to HTML in C</li>
+</ul>
diff --git a/miniany/build.sh b/miniany/build.sh
index 5891613..7944eaf 100755
--- a/miniany/build.sh
+++ b/miniany/build.sh
@@ -78,6 +78,9 @@ case "${COMPILER}:${MODE}" in
pcc:hosted)
CFLAGS+=" -Wl,-emain"
;;
+esac
+
+case "${COMPILER}:${MODE}" in
*:hosted)
CFLAGS+=" -lbsd"
;;
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 );
diff --git a/miniany/cc.wg b/miniany/cc.wg
index dbf56a9..7aca567 100644
--- a/miniany/cc.wg
+++ b/miniany/cc.wg
@@ -29,14 +29,14 @@ WordGrinder dumpfile v3: this is a text file; diff me!
.clipboard.margin: 0
.clipboard.viewmode: 1
.clipboard.wordcount: 19
-.documents.1.co: 10
-.documents.1.cp: 39
-.documents.1.cw: 5
+.documents.1.co: 11
+.documents.1.cp: 74
+.documents.1.cw: 1
.documents.1.margin: 0
.documents.1.name: "main"
.documents.1.sticky_selection: false
.documents.1.viewmode: 1
-.documents.1.wordcount: 910
+.documents.1.wordcount: 928
.fileformat: 8
.findtext: "C4"
.menu.accelerators.^@: "ZM"
@@ -199,7 +199,7 @@ PRE echo -n -e "\034" > EOF
PRE cat cc.c EOF hello.c | ./c4
PRE cat c4.c EOF cc.c EOF hello.c | ./c4
PRE cat c4.c4 EOF c4.c EOF cc.c EOF hello.c | ./c4
-P EOF contains the traditional FS (file separator) character in the ASCII character set. Every time c4/c4.c is invoked it reads exacly one input file up to the first FS character (or stops at the end of stdin).
+P EOF contains the traditional FS (file separator) character in the ASCII character set. Every time c4 is invoked it reads exacly one input file up to the first FS character (or stops at the end of stdin).
P We can also use -s, or -d on every level as follows:
PRE cat cc.c EOF hello.c | ./c4 -d
H2 References
@@ -220,4 +220,7 @@ LB https://github.com/rswier/swieros.git: c.c in swieros, Robert Swierczek
P Assembly:
LB https://github.com/felipensp/assembly/blob/master/x86/itoa.s, for putint (early debugging keyword)
LB https://baptiste-wicht.com/posts/2011/11/print-strings-integers-intel-assembly.htm (earldy debugging keyword)
+P Documentation:
+LB http://cowlark.com/wordgrinder/index.html: the fabulous editor which just does what it should do
+LB https://github.com/mity/md4c: markdown to HTML in C
.
diff --git a/miniany/test1.c b/miniany/test1.c
index 4bf86e3..9c971ca 100644
--- a/miniany/test1.c
+++ b/miniany/test1.c
@@ -1,5 +1,6 @@
/* test1 */
+void main( )
{
int i;
int j;