summaryrefslogtreecommitdiff
path: root/minie
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2018-12-22 21:38:02 +0100
committerAndreas Baumann <mail@andreasbaumann.cc>2018-12-22 21:38:02 +0100
commit8975a83c3532e56f97b2555db71d957dd69cda81 (patch)
tree5438ad833e5d0675d8b83dea8855229cd3445ecb /minie
parent2244c65cdb0bfa2cc88ebe04cfdeba7349251f33 (diff)
downloadcompilertests-8975a83c3532e56f97b2555db71d957dd69cda81.tar.gz
compilertests-8975a83c3532e56f97b2555db71d957dd69cda81.tar.bz2
some work on arrays and reading from stdin
Diffstat (limited to 'minie')
-rw-r--r--minie/DESIGN2
-rw-r--r--minie/README35
-rwxr-xr-xminie/build.sh17
-rw-r--r--minie/e2c.c124
-rw-r--r--minie/ec.e8
-rw-r--r--minie/test4.e2
-rw-r--r--minie/test5.e17
7 files changed, 162 insertions, 43 deletions
diff --git a/minie/DESIGN b/minie/DESIGN
index 5a6d15d..beb46de 100644
--- a/minie/DESIGN
+++ b/minie/DESIGN
@@ -44,7 +44,7 @@ Steps:
- N: new language we want to have a compiler for
- N', N'': subset languages of language N with reduced features
-Step 1: Build a translator from N'' -> O'' written in O, O', O''
+Step 1: Build a translator (a transpiler) from N'' -> O'' written in O, O', O''
We also use the O-toolchain for building all artifacts (compiler, assembler, linker).
Try to build minimal subsets of N and use as little features of O for
diff --git a/minie/README b/minie/README
index fe0ebc5..e7ea35d 100644
--- a/minie/README
+++ b/minie/README
@@ -1,14 +1,21 @@
-gcc -g -O0 -Wall -pedantic -std=c89 -o e2c e2c.c
-./e2c < test1.e
-./e2c < test2.e
-./e2c < test3.e
-./e2c < test4.e
-
-./e2c < test4.e > test4.c && gcc -o test4 test4.c && ./test4
-
-./e2c < ec.e
-./e2c < ec.e > ec.c && gcc -o ec ec.c
-./ec < test1.e > test1.asm
-nasm -o test1.bin -f bin test1.asm
-ndisasm -b32 test1.bin
-../crenshaw/emul test1.bin
+Transpiler
+----------
+
+e2c.c : written in C89, translates E code to C89 code. Compile to
+ a running binary with any C toolchain
+
+Stage 0 E compiler
+------------------
+
+ec.e : stage 0 E compiler
+
+testX.e : test cases for stage 0 compiler
+
+Test cases for the language E
+-----------------------------
+
+test1: empty module
+test2: syntax error, no module definition
+test3: module definition lacking a module name
+test4: general expressions and variables
+test5: basic system input/output, import of pseudo module 'system'
diff --git a/minie/build.sh b/minie/build.sh
new file mode 100755
index 0000000..3dc1339
--- /dev/null
+++ b/minie/build.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+
+gcc -g -O0 -Wall -pedantic -std=c89 -o e2c e2c.c
+./e2c < test1.e
+./e2c < test2.e
+./e2c < test3.e
+./e2c < test4.e
+./e2c < test5.e
+
+./e2c < test5.e > test5.c && gcc -g -o test5 test5.c && ./test5
+
+./e2c < ec.e
+./e2c < ec.e > ec.c && gcc -o ec ec.c
+./ec < test1.e > test1.asm
+nasm -o test1.bin -f bin test1.asm
+ndisasm -b32 test1.bin
+../crenshaw/emul test1.bin
diff --git a/minie/e2c.c b/minie/e2c.c
index f1ba44b..438dbe4 100644
--- a/minie/e2c.c
+++ b/minie/e2c.c
@@ -5,7 +5,7 @@
#include <assert.h>
enum {
- MAX_IDENT_LEN = 16,
+ MAX_IDENT_LEN = 24,
MAX_NUMBER_LEN = 9,
MAX_ERRMSG_LEN = 64,
MAX_STRING_LEN = 64
@@ -21,6 +21,7 @@ static char moduleName[MAX_IDENT_LEN+1];
static char varName[MAX_IDENT_LEN+1];
static char typeName[MAX_IDENT_LEN+1];
static char procName[MAX_IDENT_LEN+1];
+static int isArray = 0;
typedef enum {
S_char = 0,
@@ -36,6 +37,8 @@ typedef enum {
S_if,
S_do,
S_else,
+ S_array,
+ S_of,
S_dot,
S_comma,
S_semicolon,
@@ -47,6 +50,8 @@ typedef enum {
S_slash,
S_lparen,
S_rparen,
+ S_lbracket,
+ S_rbracket,
S_eof
} Symbol;
@@ -64,6 +69,8 @@ char *symname[S_eof+1] = {
"if",
"do",
"else",
+ "array",
+ "of",
".",
",",
";",
@@ -75,6 +82,8 @@ char *symname[S_eof+1] = {
"/",
"(",
")",
+ "[",
+ "]",
"eof"
};
@@ -141,6 +150,7 @@ static int isCharacter( int c )
case ' ':
case '[':
case ']':
+ case ':':
/* TODO: allow more characters as we go along */
return 1;
default:
@@ -235,9 +245,14 @@ static Symbol getSym( void )
case '7':
case '8':
case '9':
- case 'a':
number( );
return S_number;
+ case 'a':
+ identifier( );
+ if( strcmp( ident, "array" ) == 0 ) {
+ return S_array;
+ }
+ return S_ident;
case 'b':
identifier( );
if( strcmp( ident, "begin" ) == 0 ) {
@@ -282,7 +297,14 @@ static Symbol getSym( void )
}
return S_ident;
case 'n':
+ identifier( );
+ return S_ident;
case 'o':
+ identifier( );
+ if( strcmp( ident, "of" ) == 0 ) {
+ return S_of;
+ }
+ return S_ident;
case 'p':
identifier( );
if( strcmp( ident, "procedure" ) == 0 ) {
@@ -369,6 +391,12 @@ static Symbol getSym( void )
case ')':
look = getChar( );
return S_rparen;
+ case '[':
+ look = getChar( );
+ return S_lbracket;
+ case ']':
+ look = getChar( );
+ return S_rbracket;
case EOF:
return S_eof;
default:
@@ -588,17 +616,31 @@ static void statement( void )
qualident( );
if( sym == S_lparen ) {
/* TODO: add internal function maps as symbols and procedures */
- if( strcmp( varName, "system.writeln" ) == 0 ) {
- emit( "printf( " );
+ if( strcmp( varName, "system.writestring" ) == 0 ||
+ strcmp( varName, "system.writeline" ) == 0 ) {
+ emit( "printf( \"%%s\", " );
+ } else if( strcmp( varName, "system.writeinteger" ) == 0 ) {
+ emit( "printf( \"%%d\", " );
} else if( strcmp( varName, "system.halt" ) == 0 ) {
emit( "exit( " );
+ } else if( strcmp( varName, "system.readline" ) == 0 ) {
+ emit( "{ size_t _n = %d; fgets( (char *)&", num );
+ } else if( strcmp( varName, "length" ) == 0 ) {
+ emit( "255" );
} else {
emit( "%s( ", varName );
}
parameterList( );
/* TODO: procedure call */
- emitLn( ");" );
- if( strcmp( varName, "system.writeln" ) == 0 ) {
+ if( strcmp( varName, "system.readline" ) == 0 ) {
+ /* TODO: check if parameter is an array of char,
+ get length of the defined array and put it into the parameter
+ of getline */
+ emitLn( ", _n, stdin ); }" );
+ } else {
+ emitLn( ");" );
+ }
+ if( strcmp( varName, "system.writeline" ) == 0 ) {
emitLn( "puts( \"\" );" );
}
} else {
@@ -626,26 +668,58 @@ static void statementBlock( void )
Expect( S_end );
}
+static void type( void );
+
+static void simpleType( void )
+{
+ /* TODO: handle build-in types in init, register them in
+ type table */
+ if( strcmp( ident, "integer" ) == 0 ) {
+ strcpy( typeName, "signed int" );
+ sym = getSym( );
+ } else if( strcmp( ident, "boolean" ) == 0 ) {
+ /* C89, no bool */
+ strcpy( typeName, "unsigned char" );
+ sym = getSym( );
+ } else if( strcmp( ident, "char" ) == 0 ) {
+ /* TODO: Unicode, for now ASCII */
+ strcpy( typeName, "unsigned char" );
+ sym = getSym( );
+ } else if( strcmp( ident, "byte" ) == 0 ) {
+ /* C89, no bool */
+ strcpy( typeName, "unsigned char" );
+ sym = getSym( );
+ } else {
+ Abort( "Unknown type '%s'", ident );
+ }
+}
+
+static void arrayType( void )
+{
+ sym = getSym( );
+ Expect( S_lbracket );
+ number( );
+ sym = getSym( );
+ Expect( S_rbracket );
+ /* array size is in num */
+ if( sym == S_of ) {
+ sym = getSym( );
+ type( );
+ /* type is in ident */
+ } else {
+ Abort( "of' expected in array definition" );
+ }
+}
+
static void type( void )
{
identifier( );
if( sym == S_ident ) {
- /* TODO: handle build-in types in init, register them in
- type table */
- if( strcmp( ident, "integer" ) == 0 ) {
- strcpy( typeName, "signed int" );
- sym = getSym( );
- } else if( strcmp( ident, "bool" ) == 0 ) {
- /* C89, no bool */
- strcpy( typeName, "unsigned char" );
- sym = getSym( );
- } else if( strcmp( ident, "byte" ) == 0 ) {
- /* C89, no bool */
- strcpy( typeName, "unsigned char" );
- sym = getSym( );
- } else {
- Abort( "Unknown type '%s'", ident );
- }
+ simpleType( );
+ isArray = 0;
+ } else if( sym == S_array ) {
+ arrayType( );
+ isArray = 1;
}
}
@@ -655,7 +729,11 @@ static void variableDeclaration( void )
sym = getSym( );
Expect( S_colon );
type( );
- emitLn( "static %s %s;", typeName, varName );
+ if( isArray ) {
+ emitLn( "static %s %s[%d];", typeName, varName, num );
+ } else {
+ emitLn( "static %s %s;", typeName, varName );
+ }
}
static void variableBlock( void )
diff --git a/minie/ec.e b/minie/ec.e
index b51559b..272cc13 100644
--- a/minie/ec.e
+++ b/minie/ec.e
@@ -4,14 +4,14 @@ import system;
procedure prologue;
begin
- system.writeln( "[bits 32]" );
- system.writeln( "cpu 486" );
- system.writeln( "org 0x1000000" );
+ system.writeline( "[bits 32]" );
+ system.writeline( "cpu 486" );
+ system.writeline( "org 0x1000000" );
end
procedure epilogue;
begin
- system.writeln( "hlt" );
+ system.writeline( "hlt" );
end
begin
diff --git a/minie/test4.e b/minie/test4.e
index 0ad93e0..2dc3722 100644
--- a/minie/test4.e
+++ b/minie/test4.e
@@ -4,7 +4,7 @@ var
x : integer;
y : integer;
z : integer;
- b : bool;
+ b : boolean;
c : byte;
res : integer;
diff --git a/minie/test5.e b/minie/test5.e
new file mode 100644
index 0000000..1b4e991
--- /dev/null
+++ b/minie/test5.e
@@ -0,0 +1,17 @@
+module test4;
+
+import system;
+
+var
+ s : array[64] of char;
+ len : integer;
+
+begin
+ system.readline( s );
+ len := len( s );
+ system.writestring( "String: " );
+ system.writeline( s );
+ system.writestring( "Length: " );
+ system.writeinteger( len );
+ system.writeline( "" )
+end