summaryrefslogtreecommitdiff
path: root/minie
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2018-12-24 12:43:44 +0100
committerAndreas Baumann <mail@andreasbaumann.cc>2018-12-24 12:43:44 +0100
commit836832f9718de1773e0673e2b078dbe5d88974c8 (patch)
treeb9fc0d57d0ab4b9057d442612d6afd1e0e737287 /minie
parent8975a83c3532e56f97b2555db71d957dd69cda81 (diff)
downloadcompilertests-836832f9718de1773e0673e2b078dbe5d88974c8.tar.gz
compilertests-836832f9718de1773e0673e2b078dbe5d88974c8.tar.bz2
added simplistic symbol managemnt for variables
Diffstat (limited to 'minie')
-rw-r--r--minie/README1
-rwxr-xr-xminie/build.sh4
-rw-r--r--minie/e2c.c123
-rw-r--r--minie/test5.e18
-rw-r--r--minie/test6.e17
5 files changed, 144 insertions, 19 deletions
diff --git a/minie/README b/minie/README
index e7ea35d..9ae9438 100644
--- a/minie/README
+++ b/minie/README
@@ -19,3 +19,4 @@ 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'
+test6: string functions
diff --git a/minie/build.sh b/minie/build.sh
index 3dc1339..898cb5a 100755
--- a/minie/build.sh
+++ b/minie/build.sh
@@ -1,13 +1,15 @@
#!/bin/bash
-gcc -g -O0 -Wall -pedantic -std=c89 -o e2c e2c.c
+gcc -g -O0 -Wall -pedantic -std=c89 -Wno-return-type -o e2c e2c.c
./e2c < test1.e
./e2c < test2.e
./e2c < test3.e
./e2c < test4.e
./e2c < test5.e
+./e2c < test6.e
./e2c < test5.e > test5.c && gcc -g -o test5 test5.c && ./test5
+./e2c < test6.e > test6.c && gcc -g -o test6 test6.c && ./test6
./e2c < ec.e
./e2c < ec.e > ec.c && gcc -o ec ec.c
diff --git a/minie/e2c.c b/minie/e2c.c
index 438dbe4..065c4a0 100644
--- a/minie/e2c.c
+++ b/minie/e2c.c
@@ -4,24 +4,25 @@
#include <stdarg.h>
#include <assert.h>
+/* CONSTANTS */
+
enum {
MAX_IDENT_LEN = 24,
MAX_NUMBER_LEN = 9,
MAX_ERRMSG_LEN = 64,
- MAX_STRING_LEN = 64
+ MAX_STRING_LEN = 64,
+ MAX_RECORD_MEMBERS = 8,
+ MAX_SYMBOLS = 32
};
+/* SCANNER */
+
static int look;
static int row;
static int col;
static int num;
static char str[MAX_STRING_LEN+1];
static char ident[MAX_IDENT_LEN+1];
-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,
@@ -198,7 +199,7 @@ static void number( void )
look = getChar( );
}
if( n == MAX_NUMBER_LEN ) {
- Abort( "Number constand exceeds maximal length" );
+ Abort( "Number gand exceeds maximal length" );
}
sym = S_number;
}
@@ -225,7 +226,6 @@ static void string( void )
look = getChar( );
}
-
static Symbol getSym( void )
{
skipWhite( );
@@ -405,6 +405,88 @@ static Symbol getSym( void )
return S_char;
}
+/* SYMBOL TABLE */
+
+typedef enum {
+ TYPE_UNKNOWN,
+ TYPE_INTEGER,
+ TYPE_BOOLEAN,
+ TYPE_BYTE,
+ TYPE_CHAR,
+ TYPE_ARRAY,
+ TYPE_RECORD
+} BasicType;
+
+static BasicType strToBasicType( char *name )
+{
+ if( strcmp( name, "integer" ) == 0 ) {
+ return TYPE_INTEGER;
+ } else if( strcmp( name, "boolean" ) == 0 ) {
+ return TYPE_BOOLEAN;
+ } else if( strcmp( name, "byte" ) == 0 ) {
+ return TYPE_BYTE;
+ } else if( strcmp( name, "char" ) == 0 ) {
+ return TYPE_CHAR;
+ } else {
+ Abort( "Unknown type '%s'", name );
+ }
+ return TYPE_UNKNOWN;
+}
+
+typedef struct ArrayType {
+ BasicType type;
+ int len;
+} ArrayType;
+
+typedef struct RecordType {
+ BasicType type[MAX_RECORD_MEMBERS];
+ int len;
+} RecordType;
+
+typedef struct Type {
+ BasicType type;
+ char name[MAX_IDENT_LEN];
+ ArrayType array;
+ RecordType record;
+} Type;
+
+static int nof_symbols = 0;
+static Type symbols[MAX_SYMBOLS];
+
+static void insert_symbol( Type type, char *name )
+{
+ if( nof_symbols >= MAX_SYMBOLS ) {
+ Halt( "Symbol table exhausted, increase MAX_SYMBOLS and recompile e2c" );
+ }
+
+ symbols[nof_symbols] = type;
+ strncpy( symbols[nof_symbols].name, name, MAX_IDENT_LEN );
+
+ nof_symbols++;
+}
+
+static Type get_symbol_type( char *name )
+{
+ int i;
+
+ for( i = 0; i < nof_symbols; i++ ) {
+ if( strcmp( symbols[i].name, name ) == 0 ) {
+ return symbols[i];
+ }
+ }
+
+ Abort( "Could not determine type of symbol '%s'", name );
+}
+
+/* PARSER */
+
+static char moduleName[MAX_IDENT_LEN+1];
+static char varName[MAX_IDENT_LEN+1];
+static Type lastType;
+static int isArray = 0;
+static char typeName[MAX_IDENT_LEN+1];
+static char procName[MAX_IDENT_LEN+1];
+
static void Expect( Symbol expect )
{
if( sym == expect ) {
@@ -436,6 +518,7 @@ static void prologue( void )
emitLn( "/* generated with e2c */" );
emitLn( "#include <stdio.h>" );
emitLn( "#include <stdlib.h>" );
+ emitLn( "#include <string.h>" );
}
static void init( void )
@@ -502,7 +585,9 @@ static void factor( void )
emit( "\"%s\"", str );
sym = getSym( );
} else if( sym == S_ident ) {
- /* TODO: hacky */
+ /* TODO: hacky, the question is also, should this
+ * be a keyword
+ */
if( strcmp( ident, "true" ) == 0 ) {
emit( "1" );
} else if( strcmp( ident, "false" ) == 0 ) {
@@ -546,10 +631,20 @@ static void expression( void )
static void assignment( void )
{
+ Type type;
+
/* precondition: ident is a variable and already parsed */
Expect( S_assign );
- emit( "%s = ", varName );
+ type = get_symbol_type( varName );
+ if( type.type == TYPE_ARRAY && type.array.type == TYPE_CHAR ) {
+ emit( "strncpy( %s, ", varName );
+ } else {
+ emit( "%s = ", varName );
+ }
expression( );
+ if( type.type == TYPE_ARRAY && type.array.type == TYPE_CHAR ) {
+ emit( ", %d )", type.array.len );
+ }
emitLn( ";" );
}
@@ -675,17 +770,21 @@ static void simpleType( void )
/* TODO: handle build-in types in init, register them in
type table */
if( strcmp( ident, "integer" ) == 0 ) {
+ lastType.type = TYPE_INTEGER;
strcpy( typeName, "signed int" );
sym = getSym( );
} else if( strcmp( ident, "boolean" ) == 0 ) {
+ lastType.type = TYPE_BOOLEAN;
/* C89, no bool */
strcpy( typeName, "unsigned char" );
sym = getSym( );
} else if( strcmp( ident, "char" ) == 0 ) {
+ lastType.type = TYPE_CHAR;
/* TODO: Unicode, for now ASCII */
strcpy( typeName, "unsigned char" );
sym = getSym( );
} else if( strcmp( ident, "byte" ) == 0 ) {
+ lastType.type = TYPE_BYTE;
/* C89, no bool */
strcpy( typeName, "unsigned char" );
sym = getSym( );
@@ -706,6 +805,9 @@ static void arrayType( void )
sym = getSym( );
type( );
/* type is in ident */
+ lastType.type = TYPE_ARRAY;
+ lastType.array.type = strToBasicType( ident );
+ lastType.array.len = num;
} else {
Abort( "of' expected in array definition" );
}
@@ -729,6 +831,7 @@ static void variableDeclaration( void )
sym = getSym( );
Expect( S_colon );
type( );
+ insert_symbol( lastType, varName );
if( isArray ) {
emitLn( "static %s %s[%d];", typeName, varName, num );
} else {
diff --git a/minie/test5.e b/minie/test5.e
index 1b4e991..0b745e8 100644
--- a/minie/test5.e
+++ b/minie/test5.e
@@ -1,17 +1,19 @@
-module test4;
+module test5;
import system;
-
+
var
s : array[64] of char;
- len : integer;
+ i : integer;
begin
- system.readline( s );
- len := len( s );
+ s := "Hello World";
system.writestring( "String: " );
- system.writeline( s );
- system.writestring( "Length: " );
- system.writeinteger( len );
+ system.writestring( s );
+ system.writeline( "" );
+
+ i := 42;
+ system.writestring( "Integer: " );
+ system.writeinteger( i );
system.writeline( "" )
end
diff --git a/minie/test6.e b/minie/test6.e
new file mode 100644
index 0000000..15e5969
--- /dev/null
+++ b/minie/test6.e
@@ -0,0 +1,17 @@
+module test6;
+
+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