diff --git a/dwarf/dwarf-compiler/AST.h b/dwarf/dwarf-compiler/AST.h
index 3c26e43..4a42ce9 100755
--- a/dwarf/dwarf-compiler/AST.h
+++ b/dwarf/dwarf-compiler/AST.h
@@ -14,6 +14,9 @@ typedef enum {
AST_MINUS,
AST_MULT,
AST_DIVIDE,
+ AST_LT,
+ AST_EQ,
+ AST_GT,
AST_SEQ,
AST_IDENTIFIER,
AST_PRINT
@@ -77,6 +80,12 @@ ast_t* ast_plus( ast_t* left, ast_t* right );
ast_t* ast_minus( ast_t* left, ast_t* right );
ast_t* ast_mult( ast_t* left, ast_t* right );
ast_t* ast_div( ast_t* left, ast_t* right );
+
+ast_t* ast_lt( ast_t* left, ast_t* right );
+ast_t* ast_eq( ast_t* left, ast_t* right );
+ast_t* ast_gt( ast_t* left, ast_t* right );
+
+
ast_t* ast_assignment( ast_t* ident, ast_t* expr );
ast_t* ast_seq( ast_t* left, ast_t* right );
ast_t* ast_identifier( char* name );
diff --git a/dwarf/dwarf-compiler/ast_constructors.c b/dwarf/dwarf-compiler/ast_constructors.c
index 4a8e169..fa0eadf 100755
--- a/dwarf/dwarf-compiler/ast_constructors.c
+++ b/dwarf/dwarf-compiler/ast_constructors.c
@@ -41,18 +41,10 @@ ast_t* ast_lt( ast_t* left, ast_t* right ) {
return ast_binop( left, right, AST_LT );
}
-ast_t* ast_le( ast_t* left, ast_t* right ) {
- return ast_binop( left, right, AST_LE );
-}
-
ast_t* ast_eq( ast_t* left, ast_t* right ) {
return ast_binop( left, right, AST_EQ );
}
-ast_t* ast_ge( ast_t* left, ast_t* right ) {
- return ast_binop( left, right, AST_GE );
-}
-
ast_t* ast_gt( ast_t* left, ast_t* right ) {
return ast_binop( left, right, AST_GT );
}
diff --git a/dwarf/dwarf-compiler/ast_helpers.c b/dwarf/dwarf-compiler/ast_helpers.c
index 58b23a2..c9fc080 100755
--- a/dwarf/dwarf-compiler/ast_helpers.c
+++ b/dwarf/dwarf-compiler/ast_helpers.c
@@ -27,10 +27,8 @@ void ast_visit( ast_t* node, void (before)( ast_t* node ), void (after)( ast_t*
case AST_MINUS:
case AST_MULT:
case AST_DIVIDE:
- case AST_LT:
- case AST_LE:
- case AST_EQ:
- case AST_GE:
+ case AST_LT:
+ case AST_EQ:
case AST_GT:
ast_visit( node->attributes.as_binop.left, before, after );
ast_visit( node->attributes.as_binop.right, before, after );
@@ -119,28 +117,14 @@ void ast_print( ast_t* node, FILE* out ) {
fprintf( out, " < " );
ast_print( node->attributes.as_binop.right, out );
fprintf( out, " )" );
- break;
- case AST_LE:
- fprintf( out, "( " );
- ast_print( node->attributes.as_binop.left, out );
- fprintf( out, " <= " );
- ast_print( node->attributes.as_binop.right, out );
- fprintf( out, " )" );
- break;
+ break;
case AST_EQ:
fprintf( out, "( " );
ast_print( node->attributes.as_binop.left, out );
fprintf( out, " == " );
ast_print( node->attributes.as_binop.right, out );
fprintf( out, " )" );
- break;
- case AST_GE:
- fprintf( out, "( " );
- ast_print( node->attributes.as_binop.left, out );
- fprintf( out, " >= " );
- ast_print( node->attributes.as_binop.right, out );
- fprintf( out, " )" );
- break;
+ break;
case AST_GT:
fprintf( out, "( " );
ast_print( node->attributes.as_binop.left, out );
diff --git a/dwarf/dwarf-compiler/bytecode.c b/dwarf/dwarf-compiler/bytecode.c
index e3f45b0..3665ce0 100755
--- a/dwarf/dwarf-compiler/bytecode.c
+++ b/dwarf/dwarf-compiler/bytecode.c
@@ -9,27 +9,19 @@ size_t bytecode_size[] = {
1,
1,
1,
+ 1,
1 + sizeof( lang_int_t ),
1 + sizeof( reg_num_t ),
1 + sizeof( reg_num_t ),
1 + sizeof( addr_offset_t ),
1 + sizeof( addr_offset_t ),
+ 1 + sizeof( addr_offset_t ),
+ 1,
1,
1,
1
};
-/* Helpers *//*
-static bytecode_t* last( bytecode_t* bc )
-{
- while (bc != NULL) bc = bc->next;
- return bc;
-}
-
-static void bc_concat( bytecode_t* left, bytecode_t* right ) {
- last( left )-> next = right;
-}*/
-
void bytecode_foreach( bytecode_t* bc, void ( action )( bytecode_t* ) ) {
bytecode_t* next;
@@ -57,7 +49,6 @@ bytecode_t* emit_bytecode( bytecode_builder_t* builder, opcode_t opcode) {
}
-
/* Helpers to emit specific bytecodes with parameters */
static addr_offset_t* emit_delayed_jump( bytecode_builder_t* builder, opcode_t code ) {
@@ -132,4 +123,42 @@ void bytecode_prettyprint( bytecode_t* bc ) {
bc = next;
}
}
+static void bytecode_free_one( bytecode_t* bc ) { free (bc); }
+
+void bytecode_free( bytecode_t* bc ) {
+ bytecode_foreach( bc, bytecode_free_one );
+}
+
+static void bytecode_flush_one( bytecode_t* bc, FILE* file ) {
+ fwrite( &(bc->opcode), 1, 1, file );
+
+ switch( bc->opcode ) {
+ case BC_IPUSHC:
+ fwrite( &(bc-> params.immediate), sizeof( lang_int_t ), 1, file );
+ break;
+ case BC_IPUSHREG:
+ case BC_IPOPREG:
+ fwrite( &(bc-> params.reg), sizeof( reg_num_t ), 1, file );
+ break;
+ case BC_JMP:
+ case BC_JZ:
+ fwrite( &(bc-> params.offset), sizeof( addr_offset_t ), 1, file );
+ break;
+ default:
+ break;
+
+ }
+}
+
+void bytecode_flush( bytecode_t* bc, FILE* file) {
+ bytecode_t* next;
+
+ if ( bc == NULL ) return;
+
+ while( bc != NULL ) {
+ next = bc->next;
+ bytecode_flush_one( bc, file );
+ bc = next;
+ }
+}
\ No newline at end of file
diff --git a/dwarf/dwarf-compiler/bytecode.h b/dwarf/dwarf-compiler/bytecode.h
index 1bd832e..bd6e7e3 100755
--- a/dwarf/dwarf-compiler/bytecode.h
+++ b/dwarf/dwarf-compiler/bytecode.h
@@ -18,6 +18,7 @@ typedef enum {
BC_JZ,
BC_JNZ,
BC_ICMP,
+ BC_EQ,
BC_PRINT,
BC_DEBUG
} opcode_t;
@@ -36,6 +37,7 @@ static char* bytecode_mnemonics[] = {
"JZ",
"JNZ",
"ICMP",
+ "EQ",
"PRINT",
"DEBUG"
};
@@ -61,11 +63,7 @@ typedef struct {
bytecode_t* last;
}
bytecode_builder_t;
-
-typedef struct {
- addr_offset_t* addr;
-} addr_param_t;
-
+
bytecode_t* emit_bytecode( bytecode_builder_t* builder, opcode_t opcode );
@@ -90,5 +88,6 @@ void emit_ipopreg( bytecode_builder_t* builder, reg_num_t reg);
void bytecode_foreach( bytecode_t* bc, void ( action )( bytecode_t* ) );
void bytecode_print( bytecode_t* bytecode );
void bytecode_prettyprint( bytecode_t* bc );
-
+void bytecode_free( bytecode_t* bc );
+void bytecode_flush( bytecode_t* bc, FILE* file);
#endif
\ No newline at end of file
diff --git a/dwarf/dwarf-compiler/codegen.c b/dwarf/dwarf-compiler/codegen.c
index 01fc7bc..4c71ca1 100755
--- a/dwarf/dwarf-compiler/codegen.c
+++ b/dwarf/dwarf-compiler/codegen.c
@@ -77,64 +77,33 @@ static size_t generate_div( ast_t* node, bytecode_builder_t* bc, generator_conte
return first + bytecode_size[ BC_IDIV ] + second;
}
-static size_t generate_lt( ast_t* node, bytecode_builder_t* bc, generator_context_t* ctx ) {
+static size_t generate_gt_helper( ast_t* left, ast_t* right, bytecode_builder_t* bc, generator_context_t* ctx ) {
size_t first, second;
- first = generate( node->attributes.as_binop.right, bc, ctx );
- second = generate( node->attributes.as_binop.left, bc, ctx );
+ first = generate( left, bc, ctx );
+ second = generate( right, bc, ctx );
emit_bytecode( bc, BC_ICMP );
- return first + bytecode_size[ BC_ICMP ] + second;
-}
-
-static size_t generate_gt( ast_t* node, bytecode_builder_t* bc, generator_context_t* ctx ) {
- size_t first, second;
- first = generate( node->attributes.as_binop.left, bc, ctx );
- second = generate( node->attributes.as_binop.right, bc, ctx );
- emit_bytecode( bc, BC_ICMP );
- return first + bytecode_size[ BC_ICMP ] + second;
-}
-
-static size_t generate_eq( ast_t* node, bytecode_builder_t* bc, generator_context_t* ctx ) {
- size_t first, second;
- first = generate( node->attributes.as_binop.left, bc, ctx );
- second = generate( node->attributes.as_binop.right, bc, ctx );
- emit_bytecode( bc, BC_ICMP );
- emit_bytecode( bc, BC_DUP );
- emit_bytecode( bc, BC_IMUL );
- emit_ipushc( bc, -1 );
- emit_ipushc( bc, BC_IADD );
+ emit_ipushc( bc, 1 );
+ emit_bytecode( bc, BC_EQ );
return first + second
+ bytecode_size[ BC_ICMP ]
- + bytecode_size[ BC_DUP ]
- + bytecode_size[ BC_IMUL ]
+ bytecode_size[ BC_IPUSHC ]
- + bytecode_size[ BC_IADD ] ;
+ + bytecode_size[ BC_EQ ];
}
-static size_t generate_le( ast_t* node, bytecode_builder_t* bc, generator_context_t* ctx ) {
- size_t first, second;
- first = generate( node->attributes.as_binop.right, bc, ctx );
- second = generate( node->attributes.as_binop.left, bc, ctx );
- emit_bytecode( bc, BC_ICMP );
- emit_ipushc( bc, 1 );
- emit_ipushc( bc, BC_IADD );
- return first + second
- + bytecode_size[ BC_ICMP ]
- + bytecode_size[ BC_IPUSHC ]
- + bytecode_size[ BC_IADD ] ;
+static size_t generate_gt( ast_t* node, bytecode_builder_t* bc, generator_context_t* ctx ) {
+ return generate_gt_helper( node->attributes.as_binop.left, node->attributes.as_binop.right, bc, ctx );
}
+static size_t generate_lt( ast_t* node, bytecode_builder_t* bc, generator_context_t* ctx ) { //a < b === b > a
+ return generate_gt_helper( node->attributes.as_binop.right, node->attributes.as_binop.left, bc, ctx );
+}
-static size_t generate_ge( ast_t* node, bytecode_builder_t* bc, generator_context_t* ctx ) {
- size_t first, second;
- first = generate( node->attributes.as_binop.left, bc, ctx );
- second = generate( node->attributes.as_binop.right, bc, ctx );
- emit_bytecode( bc, BC_ICMP );
- emit_ipushc( bc, 1 );
- emit_ipushc( bc, BC_IADD );
- return first + second
- + bytecode_size[ BC_ICMP ]
- + bytecode_size[ BC_IPUSHC ]
- + bytecode_size[ BC_IADD ] ;
+
+static size_t generate_eq( ast_t* node, bytecode_builder_t* bc, generator_context_t* ctx ) {
+ size_t parts;
+ parts = generate( node->attributes.as_binop.left, bc, ctx ) + generate( node->attributes.as_binop.right, bc, ctx );
+ emit_bytecode( bc, BC_EQ );
+ return parts + bytecode_size[ BC_EQ ];
}
static size_t generate_seq( ast_t* node, bytecode_builder_t* bc, generator_context_t* ctx ) {
@@ -214,10 +183,8 @@ static size_t generate( ast_t* node, bytecode_builder_t* bc, generator_context_t
case AST_MINUS: return generate_minus( node, bc, ctx );
case AST_MULT: return generate_mult( node, bc, ctx );
case AST_DIVIDE: return generate_div( node, bc, ctx );
- case AST_LT: return generate_lt( node, bc, ctx );
- case AST_LE: return generate_le( node, bc, ctx );
- case AST_EQ: return generate_eq( node, bc, ctx );
- case AST_GE: return generate_ge( node, bc, ctx );
+ case AST_LT: return generate_lt( node, bc, ctx );
+ case AST_EQ: return generate_eq( node, bc, ctx );
case AST_GT: return generate_gt( node, bc, ctx );
case AST_SEQ: return generate_seq( node, bc, ctx );
case AST_IDENTIFIER: return generate_identifier( node, bc, ctx );
diff --git a/dwarf/dwarf-compiler/dwarf-compiler.vcxproj b/dwarf/dwarf-compiler/dwarf-compiler.vcxproj
index e2d6154..ecb930c 100755
--- a/dwarf/dwarf-compiler/dwarf-compiler.vcxproj
+++ b/dwarf/dwarf-compiler/dwarf-compiler.vcxproj
@@ -82,7 +82,7 @@
-
+
@@ -93,6 +93,7 @@
+
diff --git a/dwarf/dwarf-compiler/dwarf-compiler.vcxproj.filters b/dwarf/dwarf-compiler/dwarf-compiler.vcxproj.filters
index 2c1a250..6fc77da 100755
--- a/dwarf/dwarf-compiler/dwarf-compiler.vcxproj.filters
+++ b/dwarf/dwarf-compiler/dwarf-compiler.vcxproj.filters
@@ -39,7 +39,7 @@
Header Files
-
+
Header Files
@@ -71,5 +71,8 @@
Source Files
+
+ Source Files
+
\ No newline at end of file
diff --git a/dwarf/dwarf-compiler/main.c b/dwarf/dwarf-compiler/main.c
index 22d9efd..3f44a61 100755
--- a/dwarf/dwarf-compiler/main.c
+++ b/dwarf/dwarf-compiler/main.c
@@ -9,34 +9,64 @@
static void token_item_print( token_list_t* item ) {
token_print( & ( item->token ) );
}
+
+static char* read_file_by_name( char* name ) {
+ FILE* input;
+ char* contents;
+ input = fopen( name, "r" );
+ if( input ) {
+ contents = read_file( input );
+ fclose( input );
+ return contents;
+ } else return NULL;
+
+}
+
+void usage( void ) {
+ fprintf( stderr, "Usage: dwarf-compiler input-file-name output-file-name\n" );
+}
int main( int argc, char** argv )
{
token_list_t* list;
bytecode_builder_t bc;
ast_t* tree;
- char* program;
- FILE* input;
+ char* program;
+ FILE* output;
+ char* input_filename = NULL;
+ char* output_filename = "out.dwarfvm";
- input = fopen( "program.txt", "r" );
- if (!input) return EXIT_FAILURE;
+ if (argc != 2 && argc != 3 ) { usage(); return EXIT_FAILURE; }
+
+ if ( argc >= 2 ) input_filename = argv[1];
+ if ( argc >= 3 ) output_filename = argv[2];
- program = read_file( input );
- fclose( input );
+ program = read_file_by_name( input_filename );
+
+ if ( program == NULL ) { fprintf( stderr, "Can not read file %s!\n", input_filename ); return EXIT_FAILURE; }
list = tokenize( program );
+
puts("Tokens:");
token_list_foreach( list, token_item_print );
puts("");
tree = parse( list, program );
+ puts("Parsing successful, ast tree: " );
+ ast_print( tree, stdout );
+ puts( "\nGenerating bytecode:" );
bc = generate_from_ast( tree );
- puts("");
bytecode_prettyprint( bc.first );
-
+
+ output = fopen( output_filename, "wb");
+ if (output)
+ bytecode_flush( bc.first , output);
+
+ else { fprintf( stderr, "Can not write bytecode to file %s!", output_filename); return EXIT_FAILURE; }
+
free( program );
token_list_free( list );
ast_free( tree );
- //free bytecode?
+ bytecode_free( bc.first );
}
diff --git a/dwarf/dwarf-compiler/parser.c b/dwarf/dwarf-compiler/parser.c
index c7c29f9..81729fc 100755
--- a/dwarf/dwarf-compiler/parser.c
+++ b/dwarf/dwarf-compiler/parser.c
@@ -73,15 +73,9 @@ static ast_t* expression( token_list_t** stream, const char* const code ) {
if ( accept( stream, TOK_LT) ) {
rhs = expression0( stream, code ); error_if_null( rhs, stream, code );
return ast_lt( lhs, rhs );
- } else if ( accept( stream, TOK_LE) ) {
- rhs = expression0( stream, code ); error_if_null( rhs, stream, code );
- return ast_le( lhs, rhs );
} else if ( accept( stream, TOK_EQ) ) {
rhs = expression0( stream, code ); error_if_null( rhs, stream, code );
return ast_eq( lhs, rhs );
- } else if ( accept( stream, TOK_GE) ) {
- rhs = expression0( stream, code ); error_if_null( rhs, stream, code );
- return ast_ge( lhs, rhs );
} else if ( accept( stream, TOK_GT) ) {
rhs = expression0( stream, code ); error_if_null( rhs, stream, code );
return ast_gt( lhs, rhs );
diff --git a/dwarf/dwarf-compiler/tokens.h b/dwarf/dwarf-compiler/tokens.h
index a761349..36c2fb9 100755
--- a/dwarf/dwarf-compiler/tokens.h
+++ b/dwarf/dwarf-compiler/tokens.h
@@ -23,10 +23,8 @@ typedef enum {
TOK_MULT,
TOK_DIVIDE,
- TOK_LE,
TOK_LT,
- TOK_EQ,
- TOK_GE,
+ TOK_EQ,
TOK_GT,
TOK_NUM,
@@ -55,11 +53,9 @@ static char* token_strings[] = {
"*",
"/",
- "<=",
"<",
- "==",
- ">=",
- ">"
+ "==",
+ ">",
"",
"",