diff options
author | Andreas Baumann <mail@andreasbaumann.cc> | 2018-12-22 21:38:02 +0100 |
---|---|---|
committer | Andreas Baumann <mail@andreasbaumann.cc> | 2018-12-22 21:38:02 +0100 |
commit | 8975a83c3532e56f97b2555db71d957dd69cda81 (patch) | |
tree | 5438ad833e5d0675d8b83dea8855229cd3445ecb /minie | |
parent | 2244c65cdb0bfa2cc88ebe04cfdeba7349251f33 (diff) | |
download | compilertests-8975a83c3532e56f97b2555db71d957dd69cda81.tar.gz compilertests-8975a83c3532e56f97b2555db71d957dd69cda81.tar.bz2 |
some work on arrays and reading from stdin
Diffstat (limited to 'minie')
-rw-r--r-- | minie/DESIGN | 2 | ||||
-rw-r--r-- | minie/README | 35 | ||||
-rwxr-xr-x | minie/build.sh | 17 | ||||
-rw-r--r-- | minie/e2c.c | 124 | ||||
-rw-r--r-- | minie/ec.e | 8 | ||||
-rw-r--r-- | minie/test4.e | 2 | ||||
-rw-r--r-- | minie/test5.e | 17 |
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 ) @@ -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 |