summaryrefslogtreecommitdiff
path: root/minie
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2018-09-29 21:29:28 +0200
committerAndreas Baumann <mail@andreasbaumann.cc>2018-09-29 21:29:28 +0200
commit9e5c8a8491c6bd1aff0cddb093c55a580f7fcbb1 (patch)
treeb5529b1d06d797ed31e16a5b3e6558ebc77659e0 /minie
parent0edac98af9ced6ae42059f2989a5fe4bd4c75d27 (diff)
downloadcompilertests-9e5c8a8491c6bd1aff0cddb093c55a580f7fcbb1.tar.gz
compilertests-9e5c8a8491c6bd1aff0cddb093c55a580f7fcbb1.tar.bz2
more work on parameter lists, added string parser
Diffstat (limited to 'minie')
-rw-r--r--minie/README2
-rw-r--r--minie/e2c.c123
2 files changed, 108 insertions, 17 deletions
diff --git a/minie/README b/minie/README
index 28cae32..384afaf 100644
--- a/minie/README
+++ b/minie/README
@@ -6,4 +6,4 @@ gcc -g -O0 -Wall -pedantic -std=c89 -o e2c e2c.c
./e2c < test4.e > test4.c && gcc -o test4 test4.c && ./test4
-
+./e2c < ec.e
diff --git a/minie/e2c.c b/minie/e2c.c
index 869c65c..d2274bf 100644
--- a/minie/e2c.c
+++ b/minie/e2c.c
@@ -2,27 +2,31 @@
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
+#include <assert.h>
enum {
MAX_IDENT_LEN = 16,
MAX_NUMBER_LEN = 9,
- MAX_ERRMSG_LEN = 64
+ MAX_ERRMSG_LEN = 64,
+ MAX_STRING_LEN = 64
};
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 num;
typedef enum {
S_char = 0,
S_ident,
S_number,
+ S_string,
S_module,
S_begin,
S_end,
@@ -32,6 +36,7 @@ typedef enum {
S_if,
S_do,
S_else,
+ S_dot,
S_comma,
S_semicolon,
S_colon,
@@ -49,6 +54,7 @@ char *symname[S_eof+1] = {
"char",
"ident",
"nunber",
+ "string",
"module",
"begin",
"end",
@@ -58,6 +64,7 @@ char *symname[S_eof+1] = {
"if",
"do",
"else",
+ ".",
",",
";",
":",
@@ -126,6 +133,22 @@ static int isDigit( int c )
return 0;
}
+static int isCharacter( int c )
+{
+ if( isAlpha( c ) ) return 1;
+ if( isDigit( c ) ) return 1;
+ switch( c ) {
+ case ' ':
+ case '[':
+ case ']':
+ /* TODO: allow more characters as we go along */
+ return 1;
+ default:
+ return 0;
+ }
+ return 0;
+}
+
static void skipWhite( void )
{
while( isWhite( look ) ) {
@@ -133,7 +156,7 @@ static void skipWhite( void )
}
}
-static void identifier( )
+static void identifier( void )
{
int n = 0;
if( isAlpha( look ) ) {
@@ -147,13 +170,13 @@ static void identifier( )
}
ident[n] = '\0';
if( n == MAX_IDENT_LEN ) {
- Abort( "Identifier exceeded maximal length" );
+ Abort( "Identifier exceeds maximal length" );
}
sym = S_ident;
}
}
-static void number( )
+static void number( void )
{
int n = 0;
if( isDigit( look ) ) {
@@ -171,10 +194,34 @@ static void number( )
}
}
-static Symbol getSym( )
+static void string( void )
+{
+ int n = 0;
+ look = getChar( );
+ while( look != '"' && isCharacter( look ) && n < MAX_STRING_LEN ) {
+ str[n] = look;
+ n++;
+ look = getChar( );
+ }
+ str[n] = '\0';
+ if( n == MAX_STRING_LEN ) {
+ Abort( "String constant exceeds maximal length" );
+ }
+ if( look != '"' ) {
+ Abort( "Unterminated string or illegal character in string" );
+ }
+ sym = S_string;
+ assert( look == '"' );
+ look = getChar( );
+}
+
+
+static Symbol getSym( void )
{
skipWhite( );
+ num = 0;
ident[0] = '\0';
+ str[0] = '\0';
switch( look ) {
case '0':
case '1':
@@ -283,6 +330,9 @@ static Symbol getSym( )
case 'Z':
identifier( );
return S_ident;
+ case '"':
+ string( );
+ return S_string;
case ':':
look = getChar( );
if( look == '=' ) {
@@ -293,6 +343,9 @@ static Symbol getSym( )
case ';':
look = getChar( );
return S_semicolon;
+ case '.':
+ look = getChar( );
+ return S_dot;
case ',':
look = getChar( );
return S_comma;
@@ -370,6 +423,26 @@ static void epilogue( void )
emitLn( "}" );
}
+static void qualident( void )
+{
+ identifier( );
+ if( sym == S_ident ) {
+ strncpy( varName, ident, MAX_IDENT_LEN );
+ varName[MAX_IDENT_LEN-1] = '\0';
+ }
+ sym = getSym( );
+ if( sym == S_dot ) {
+ sym = getSym( );
+ if( sym == S_ident ) {
+ strncat( varName, ".", MAX_IDENT_LEN );
+ varName[MAX_IDENT_LEN-1] = '\0';
+ strncat( varName, ident, MAX_IDENT_LEN );
+ varName[MAX_IDENT_LEN-1] = '\0';
+ sym = getSym( );
+ }
+ }
+}
+
static void variableName( void )
{
identifier( );
@@ -392,6 +465,9 @@ static void factor( void )
if( sym == S_number ) {
emit( "%d", num );
sym = getSym( );
+ } else if( sym == S_string ) {
+ emit( "\"%s\"", str );
+ sym = getSym( );
} else if( sym == S_ident ) {
/* TODO: hacky */
if( strcmp( ident, "true" ) == 0 ) {
@@ -437,9 +513,7 @@ static void expression( void )
static void assignment( void )
{
- /* qualident is variableName( ) and has been read already */
- variableName( );
- sym = getSym( );
+ /* precondition: ident is a variable and already parsed */
Expect( S_assign );
emit( "%s = ", varName );
expression( );
@@ -479,6 +553,23 @@ static void doIf( void )
emitLn( "}" );
}
+static void parameterList( void )
+{
+ Expect( S_lparen );
+ if( sym == S_rparen ) {
+ return;
+ }
+ /* TODO: no VAR parameters, strictly pass-by-value */
+ expression( );
+ sym = getSym( );
+ while( sym == S_comma ) {
+ sym = getSym( );
+ /* TODO: no VAR parameters, strictly pass-by-value */
+ expression( );
+ }
+ Expect( S_rparen );
+}
+
static void statement( void )
{
if( sym == S_if ) {
@@ -488,17 +579,17 @@ static void statement( void )
} else if( sym == S_end || sym == S_else ) {
return;
} else if( sym == S_ident ) {
- assignment( );
+ qualident( );
+ if( sym == S_lparen ) {
+ parameterList( );
+ /* TODO: procedure call */
+ } else {
+ assignment( );
+ }
} else {
Abort( "Illegal statement" );
}
}
-/*
-QualifiedIdentifier = Identifier [ "." Identifier ];
-ParameterList = "(" ")" .
-ProdecureCall = QualifiedIdentifier ParameterList .
-Statement = Assignment | IfStatement | ProcedureCall .
-*/
static void statementSequence( void )
{