From fd02c7107d295532710cf4c2589a48d20ee41c46 Mon Sep 17 00:00:00 2001 From: "Mike D. Lowis" Date: Thu, 23 Feb 2012 11:04:21 -0500 Subject: [PATCH] Overhauled codebase for major refactoring --- rakefile.rb | 37 +- source/cork/cork.cpp | 183 ++++++ source/cork/cork.h | 18 + source/dllexer/dllexer.cpp | 475 +++++++-------- source/dllexer/dllexer.h | 128 ++-- source/dlparser/dlparser.cpp | 557 +++++++++--------- source/dlparser/macro/macro.c | 41 +- source/dlparser/macro/macro.h | 22 +- source/dlparser/macro/param.c | 54 +- source/dlparser/macro/param.h | 28 +- source/main.cpp | 140 +++-- source/parse_utils/ast/ast.cpp | 113 ---- source/parse_utils/ast/ast.h | 34 -- source/parse_utils/exception/exception.cpp | 12 +- source/parse_utils/lexer/ilexer.cpp | 81 +++ source/parse_utils/lexer/ilexer.h | 32 + source/parse_utils/lexer/lexer.cpp | 80 --- source/parse_utils/lexer/lexer.h | 30 - source/parse_utils/lexer/token/token.cpp | 10 +- source/parse_utils/lexer/token/token.h | 26 +- source/parse_utils/parser/ast/ast.cpp | 98 +++ source/parse_utils/parser/ast/ast.h | 34 ++ .../parse_utils/parser/btparser/btparser.cpp | 110 ++-- source/parse_utils/parser/btparser/btparser.h | 50 +- .../parser/{parser.cpp => iparser.cpp} | 27 +- .../parser/{parser.h => iparser.h} | 22 +- .../parser/llkparser/llkparser.cpp | 127 ++-- .../parse_utils/parser/llkparser/llkparser.h | 38 +- source/parse_utils/visitor/ivisitor.cpp | 35 ++ source/parse_utils/visitor/ivisitor.h | 29 + source/parse_utils/visitor/visitor.cpp | 35 -- source/parse_utils/visitor/visitor.h | 29 - .../macroapplication/macroapplication.cpp | 42 +- .../macroapplication/macroapplication.h | 36 +- source/visitors/scheme/scheme.cpp | 272 ++++----- source/visitors/scheme/scheme.h | 38 +- source/visitors/sexp/sexp.h | 30 +- tools/rake_utils/buildconfig.rb | 44 -- tools/rake_utils/plainconfig.rb | 96 --- tools/rake_utils/testconfig.rb | 82 --- 40 files changed, 1683 insertions(+), 1692 deletions(-) create mode 100644 source/cork/cork.cpp create mode 100644 source/cork/cork.h delete mode 100644 source/parse_utils/ast/ast.cpp delete mode 100644 source/parse_utils/ast/ast.h create mode 100644 source/parse_utils/lexer/ilexer.cpp create mode 100644 source/parse_utils/lexer/ilexer.h delete mode 100644 source/parse_utils/lexer/lexer.cpp delete mode 100644 source/parse_utils/lexer/lexer.h create mode 100644 source/parse_utils/parser/ast/ast.cpp create mode 100644 source/parse_utils/parser/ast/ast.h rename source/parse_utils/parser/{parser.cpp => iparser.cpp} (78%) rename source/parse_utils/parser/{parser.h => iparser.h} (78%) create mode 100644 source/parse_utils/visitor/ivisitor.cpp create mode 100644 source/parse_utils/visitor/ivisitor.h delete mode 100644 source/parse_utils/visitor/visitor.cpp delete mode 100644 source/parse_utils/visitor/visitor.h delete mode 100644 tools/rake_utils/buildconfig.rb delete mode 100644 tools/rake_utils/plainconfig.rb delete mode 100644 tools/rake_utils/testconfig.rb diff --git a/rakefile.rb b/rakefile.rb index 54d67af..58af960 100644 --- a/rakefile.rb +++ b/rakefile.rb @@ -7,15 +7,16 @@ require 'tools/rake_utils/testconfig.rb' #------------------------------------------------------------------------------ # Configuration for the binary artifact Binary = BuildConfig.new({ - :name => 'dlang', - :compiler_options => [ '-c', '-Wall', '-Werror' ], - :source_files => [ 'source/**/*.c*' ], - :include_dirs => [ 'source/**/' ], + :name => 'dlang', + :compiler_options => [ '-c', '-Wall', '-Werror' ], + :source_files => [ 'source/**/*.c*' ], + :include_dirs => [ 'source/**/' ], + :preprocessor_defines => [ 'DETECT_MEM_LEAKS' ] }) # Configuration for the unit tests UnitTest = TestConfig.new({ - :test_files => [ 'tests/source/**.h' ], + :test_files => [ 'tests/source/**.h' ], }) #------------------------------------------------------------------------------ @@ -26,24 +27,24 @@ task :default => [ :release ] desc 'Display build configuration info' task :config do - puts 'Release Configuration' - puts '---------------------' - puts Binary - puts '' - puts 'Unit Test Configuration' - puts '-----------------------' - puts UnitTest + puts 'Release Configuration' + puts '---------------------' + puts Binary + puts '' + puts 'Unit Test Configuration' + puts '-----------------------' + puts UnitTest end desc 'Build and link the binary' task :release => [ Binary.binary_name() ] task Binary.binary_name() => Binary.directories() + Binary.objects() do - Binary.link() + Binary.link() end rule(/obj\/.+.o$/ => Binary.obj_src_lookup()) do |t| - Binary.compile(t.source,t.name) + Binary.compile(t.source,t.name) end #------------------------------------------------------------------------------ @@ -51,18 +52,18 @@ end #------------------------------------------------------------------------------ desc 'Execute all unit tests' task :test => UnitTest.directories() + UnitTest.runners() do - UnitTest.run_all_test_runners(); + UnitTest.run_all_test_runners(); end rule '_runner.exe' => UnitTest.bin_obj_lookup() do |t| - UnitTest.link([t.source],t.name) + UnitTest.link([t.source],t.name) end rule( /test\/.+_runner.o$/ => UnitTest.obj_src_lookup() ) do |t| - UnitTest.compile(t.source,t.name) + UnitTest.compile(t.source,t.name) end rule '_runner.cpp' => UnitTest.src_test_lookup() do |t| - UnitTest.generate_test_runner(t.source,t.name) + UnitTest.generate_test_runner(t.source,t.name) end diff --git a/source/cork/cork.cpp b/source/cork/cork.cpp new file mode 100644 index 0000000..0a298fa --- /dev/null +++ b/source/cork/cork.cpp @@ -0,0 +1,183 @@ +#include "cork.h" + +#ifdef DETECT_MEM_LEAKS + +// We want to use the real malloc and free in this file +#undef malloc +#undef free + +#include +#include // for std::bad_alloc +#include // for malloc() and free() +#include + +// Set the namespace +using namespace std; +/****************************************************************************** + * Typedefs + *****************************************************************************/ +typedef struct BlockTableEntry +{ + void * ptr; + unsigned int size; + const char* file; + int line; + void * next; +} BlockTableEntry_T; + +typedef struct BlockTable +{ + unsigned int size; + BlockTableEntry_T* blocks[TBL_SIZE]; +} BlockTable_T; + +/****************************************************************************** + * Prototypes + *****************************************************************************/ +void insert_record(void * ptr, BlockTable_T* entry); +void erase_record(void * ptr); + +/****************************************************************************** + * Globals + *****************************************************************************/ +unsigned int allocated; +static BlockTable_T Block_Table = { 0, {0} }; + +/****************************************************************************** + * Function Definitions + *****************************************************************************/ +void insert_record(void * ptr, BlockTableEntry_T* entry) +{ + unsigned int index = ((unsigned int)ptr) % TBL_SIZE; + BlockTableEntry_T* last = Block_Table.blocks[ index ]; + BlockTableEntry_T* curr = last; + + while (curr != NULL) + { + if ( curr->ptr == ptr ) + { + curr->size = entry->size; + free(entry); + break; + } + last = curr; + curr = (BlockTableEntry_T*)curr->next; + } + + if(curr == NULL) + { + if (last != NULL) + { + last->next = entry; + } + else + { + Block_Table.blocks[index] = entry; + } + Block_Table.size++; + } +} + +void erase_record(void * ptr) +{ + int depth = 0; + unsigned int index = ((unsigned int)ptr) % TBL_SIZE; + BlockTableEntry_T* last = Block_Table.blocks[ index ]; + BlockTableEntry_T* curr = last; + + while( curr != NULL ) + { + depth = 1; + if( curr->ptr == ptr ) + { + depth = 2; + if(last == curr) + { + depth = 3; + Block_Table.blocks[ index ] = (BlockTableEntry_T*)curr->next; + } + else + { + depth = 4; + last->next = curr->next; + } + free(curr); + Block_Table.size--; + break; + } + last = curr; + curr = (BlockTableEntry_T*)curr->next; + } +} + +void Cork_ReportMemoryLeaks(void) +{ + unsigned int index = 0; + cout << "-----------------------------------------------------------------" << endl; + cout << "Cork: Memory Allocation Analysis" << endl; + cout << "-----------------------------------------------------------------" << endl; + cout << "You have " << Block_Table.size << " Unclaimed objects." << endl; + + for(; index < TBL_SIZE; index++) + { + BlockTableEntry_T* entry = Block_Table.blocks[ index ]; + while(entry != NULL) + { + cout << "\t" << entry->size << "\t" << entry->ptr; + if( entry->file != NULL ) + { + cout << "\t" << entry->line << "\t" << entry->file; + } + cout << endl; + entry = (BlockTableEntry_T*)entry->next; + } + } +} + +void * operator new (size_t size, string file, unsigned int line) +{ + void * ptr = malloc(size); + char * fname = (char*)malloc(file.length()); + if(ptr == NULL) + { + throw bad_alloc(); + } + else + { + BlockTableEntry_T* entry = (BlockTableEntry_T*)malloc(sizeof(BlockTableEntry_T)); + strcpy( fname, file.c_str() ); + entry->ptr = ptr; + entry->size = size; + entry->file = fname; + entry->line = line; + entry->next = NULL; + insert_record(ptr,entry); + } + return ptr; +} + +void * operator new(size_t size) throw(bad_alloc) { + void * ptr = malloc(size); + if(ptr == NULL) + { + throw bad_alloc(); + } + else + { + BlockTableEntry_T* entry = (BlockTableEntry_T*)malloc(sizeof(BlockTableEntry_T)); + entry->ptr = ptr; + entry->size = size; + entry->file = NULL; + entry->line = 0; + entry->next = NULL; + insert_record(ptr,entry); + } + return ptr; +} + +void operator delete(void * p) { + free(p); + erase_record(p); +} + +#endif diff --git a/source/cork/cork.h b/source/cork/cork.h new file mode 100644 index 0000000..6af4f20 --- /dev/null +++ b/source/cork/cork.h @@ -0,0 +1,18 @@ +#ifndef CORK_H +#define CORK_H + +#ifdef DETECT_MEM_LEAKS + #include + typedef unsigned int size_t; + + void Cork_ReportMemoryLeaks(void); + void * operator new (size_t size, std::string file, unsigned int line); + #define TBL_SIZE 512 + #define REPORT_LEAKS() Cork_ReportMemoryLeaks() + #define _new new (__FILE__,__LINE__) +#else + #define REPORT_LEAKS() + #define _new new +#endif + +#endif diff --git a/source/dllexer/dllexer.cpp b/source/dllexer/dllexer.cpp index 3d99498..48f0773 100644 --- a/source/dllexer/dllexer.cpp +++ b/source/dllexer/dllexer.cpp @@ -1,316 +1,317 @@ #include "dllexer.h" #include "exception.h" +#include "cork.h" using namespace std; #define NUM_SINGLE_CHAR_MATCHES 14 SingleCharMatch_T Single_Character_Matches[ NUM_SINGLE_CHAR_MATCHES ] = { - { '[', LBRACK }, - { ']', RBRACK }, - { '(', LPAR }, - { ')', RPAR }, - { '{', LBRACE }, - { '}', RBRACE }, - { ',', COMMA }, - { '+', ADD }, - { '-', SUB }, - { '*', MUL }, - { '/', DIV }, - { '`', LIST }, - { '%', MACRO }, - { ':', SEP }, + { '[', LBRACK }, + { ']', RBRACK }, + { '(', LPAR }, + { ')', RPAR }, + { '{', LBRACE }, + { '}', RBRACE }, + { ',', COMMA }, + { '+', ADD }, + { '-', SUB }, + { '*', MUL }, + { '/', DIV }, + { '`', LIST }, + { '%', MACRO }, + { ':', SEP }, }; bool DLLexer::isWhiteSpace(void) { - return (current == ' ') || - (current == '\t') || - (current == '\r') || - (current == '\n'); + return (current == ' ') || + (current == '\t') || + (current == '\r') || + (current == '\n'); } bool DLLexer::isLetter(void) { - return ((current >= 'a') && (current <= 'z')) || - ((current >= 'A') && (current <= 'Z')); + return ((current >= 'a') && (current <= 'z')) || + ((current >= 'A') && (current <= 'Z')); } bool DLLexer::isDigit(void) { - return ((current >= '0') && (current <= '9')); + return ((current >= '0') && (current <= '9')); } bool DLLexer::isOperator(void) { - return ( (current == '=') - || (current == '!') - || (current == '<') - || (current == '>') - || (current == '|') - || (current == '&')); + return ( (current == '=') + || (current == '!') + || (current == '<') + || (current == '>') + || (current == '|') + || (current == '&')); } bool DLLexer::isStringChar(void) { - return ( (current != '"') - && (current != '\r') - && (current != '\n')); + return ( (current != '"') + && (current != '\r') + && (current != '\n')); } Token* DLLexer::next(void) { - Token* ret = NULL; - while ( (!input->eof()) && (ret == NULL) ) - { - if (isWhiteSpace()) - { - WS(); - } - else if(current == '#') - { - COMMENT(); - } - else if (isLetter()) - { - ret = Id(); - } - else if( isOperator() ) - { - ret = MultiCharOp(); - } - else if (isDigit()) - { - ret = Number(); - } - else if(current == '\'') - { - ret = Char(); - } - else if(current == '"') - { - ret = String(); - } - else if(current == '$') - { - ret = Symbol(); - } - else - { - ret = SingleCharOp(); - } - } - return ret; + Token* ret = NULL; + while ( (!input->eof()) && (ret == NULL) ) + { + if (isWhiteSpace()) + { + WS(); + } + else if(current == '#') + { + COMMENT(); + } + else if (isLetter()) + { + ret = Id(); + } + else if( isOperator() ) + { + ret = MultiCharOp(); + } + else if (isDigit()) + { + ret = Number(); + } + else if(current == '\'') + { + ret = Char(); + } + else if(current == '"') + { + ret = String(); + } + else if(current == '$') + { + ret = Symbol(); + } + else + { + ret = SingleCharOp(); + } + } + return ret; } void DLLexer::WS(void) { - do - { - consume(); - } - while(isWhiteSpace()); + do + { + consume(); + } + while(isWhiteSpace()); } void DLLexer::COMMENT(void) { - match('#'); - do - { - consume(); - } - while( (current != '\n') - && (current != EOF)); + match('#'); + do + { + consume(); + } + while( (current != '\n') + && (current != EOF)); } Token* DLLexer::Id(void) { - ostringstream oss; - do - { - oss << current; - consume(); - } - while(isLetter() || isDigit() || current == '_'); - return new Token(ID, oss.str(), line, column); + ostringstream oss; + do + { + oss << current; + consume(); + } + while(isLetter() || isDigit() || current == '_'); + return _new Token(ID, oss.str(), line, column); } Token* DLLexer::Number(void) { - ostringstream oss; - do - { - oss << current; - consume(); - } - while(isDigit()); + ostringstream oss; + do + { + oss << current; + consume(); + } + while(isDigit()); - if(current == '.') - { - return Decimal(oss); - } + if(current == '.') + { + return Decimal(oss); + } - return new Token(NUM, oss.str(), line, column); + return _new Token(NUM, oss.str(), line, column); } Token* DLLexer::Decimal(ostringstream& oss) { - oss << current; - consume(); - - if(!isDigit()) - { - Exception ex(line,column); - ex.setMessage("Missing fractional portion of floating point number."); - throw ex; - } - - do - { - oss << current; - consume(); - } - while ( isDigit() ); + oss << current; + consume(); - return new Token(NUM, oss.str(), line, column); + if(!isDigit()) + { + Exception ex(line,column); + ex.setMessage("Missing fractional portion of floating point number."); + throw ex; + } + + do + { + oss << current; + consume(); + } + while ( isDigit() ); + + return _new Token(NUM, oss.str(), line, column); } Token* DLLexer::Char(void) { - ostringstream oss; + ostringstream oss; - match('\''); - if(current != '\'') - { - oss << current; - consume(); - } - else - { - Exception ex(line,column); - ex.setMessage("Invalid character literal."); - throw ex; - } - match('\''); + match('\''); + if(current != '\'') + { + oss << current; + consume(); + } + else + { + Exception ex(line,column); + ex.setMessage("Invalid character literal."); + throw ex; + } + match('\''); - return new Token( CHAR, oss.str(), line, column ); + return _new Token( CHAR, oss.str(), line, column ); } Token* DLLexer::String(void) { - ostringstream oss; - match('"'); - while( isStringChar() ) - { - oss << current; - consume(); - } - match('"'); - return new Token( STRING, oss.str(), line, column ); + ostringstream oss; + match('"'); + while( isStringChar() ) + { + oss << current; + consume(); + } + match('"'); + return _new Token( STRING, oss.str(), line, column ); } Token* DLLexer::Symbol(void) { - ostringstream oss; - match('$'); - do - { - oss << current; - consume(); - } - while(isLetter() || isDigit() || current == '_'); - return new Token( SYMBOL, oss.str(), line, column ); + ostringstream oss; + match('$'); + do + { + oss << current; + consume(); + } + while(isLetter() || isDigit() || current == '_'); + return _new Token( SYMBOL, oss.str(), line, column ); } Token* DLLexer::SingleCharOp(void) { - for(int i = 0; i < NUM_SINGLE_CHAR_MATCHES; i++) - { - if(current == Single_Character_Matches[i].match) - { - consume(); - return new Token( Single_Character_Matches[i].type, line, column ); - } - } - throw Exception(line,column); + for(int i = 0; i < NUM_SINGLE_CHAR_MATCHES; i++) + { + if(current == Single_Character_Matches[i].match) + { + consume(); + return _new Token( Single_Character_Matches[i].type, line, column ); + } + } + throw Exception(line,column); } Token* DLLexer::MultiCharOp(void) { - Token* tok = NULL; - // save the current token so we can refer back to it - char last = current; - // remove the current token from the buffer so we cna see the next - consume(); + Token* tok = NULL; + // save the current token so we can refer back to it + char last = current; + // remove the current token from the buffer so we cna see the next + consume(); - if(last == '=') - { - if(current == '=') - { - consume(); - tok = new Token(EQ, line, column); - } - else - { - tok = new Token(ASSIGN, line, column); - } - } - else if(last == '!') - { - if(current == '=') - { - consume(); - tok = new Token(NE, line, column); - } - else - { - tok = new Token(NOT, line, column); - } - } - else if(last == '<') - { - if(current == '=') - { - consume(); - tok = new Token(LTE, line, column); - } - else - { - tok = new Token(LT, line, column); - } - } - else if(last == '>') - { - if(current == '=') - { - consume(); - tok = new Token(GTE, line, column); - } - else - { - tok = new Token(GT, line, column); - } - } - else if(last == '|') - { - if(current == '|') - { - consume(); - tok = new Token(OR, line, column); - } - else - { - tok = new Token(PIPE, line, column); - } - } - else if((last == '&') && (current == '&')) - { - consume(); - tok = new Token(AND, line, column); - } - else - { - throw Exception(line,column); - } - return tok; + if(last == '=') + { + if(current == '=') + { + consume(); + tok = _new Token(EQ, line, column); + } + else + { + tok = _new Token(ASSIGN, line, column); + } + } + else if(last == '!') + { + if(current == '=') + { + consume(); + tok = _new Token(NE, line, column); + } + else + { + tok = _new Token(NOT, line, column); + } + } + else if(last == '<') + { + if(current == '=') + { + consume(); + tok = _new Token(LTE, line, column); + } + else + { + tok = _new Token(LT, line, column); + } + } + else if(last == '>') + { + if(current == '=') + { + consume(); + tok = _new Token(GTE, line, column); + } + else + { + tok = _new Token(GT, line, column); + } + } + else if(last == '|') + { + if(current == '|') + { + consume(); + tok = _new Token(OR, line, column); + } + else + { + tok = _new Token(PIPE, line, column); + } + } + else if((last == '&') && (current == '&')) + { + consume(); + tok = _new Token(AND, line, column); + } + else + { + throw Exception(line,column); + } + return tok; } diff --git a/source/dllexer/dllexer.h b/source/dllexer/dllexer.h index f73eab4..e27bfe8 100644 --- a/source/dllexer/dllexer.h +++ b/source/dllexer/dllexer.h @@ -1,81 +1,81 @@ #ifndef DLLEXER_H #define DLLEXER_H -#include "lexer.h" +#include "ilexer.h" #include typedef enum TokenTypes { - // Datatypes - ID = 0, - NUM = 1, - CHAR = 2, - STRING = 3, - SYMBOL = 4, - LIST = 5, - VECTOR = 6, - FUNC = 7, + // Datatypes + ID = 0, + NUM = 1, + CHAR = 2, + STRING = 3, + SYMBOL = 4, + LIST = 5, + VECTOR = 6, + FUNC = 7, - // Symbols - LBRACK = 10, - RBRACK = 11, - LPAR = 12, - RPAR = 13, - LBRACE = 14, - RBRACE = 15, - COMMA = 16, - PIPE = 17, - - // Operators - AND = 20, - OR = 21, - NOT = 22, - EQ = 23, - NE = 24, - LT = 25, - GT = 26, - LTE = 27, - GTE = 28, - ASSIGN = 29, - ADD = 30, - SUB = 31, - MUL = 32, - DIV = 33, - - // AST "Virtual" Node Types - MACRO = 40, - SEP = 41, - PROGRAM = 42, - BLOCK = 43, - FN_CALL = 44, - PARAMS = 45, - ARRY_IDX = 46 + // Symbols + LBRACK = 10, + RBRACK = 11, + LPAR = 12, + RPAR = 13, + LBRACE = 14, + RBRACE = 15, + COMMA = 16, + PIPE = 17, + + // Operators + AND = 20, + OR = 21, + NOT = 22, + EQ = 23, + NE = 24, + LT = 25, + GT = 26, + LTE = 27, + GTE = 28, + ASSIGN = 29, + ADD = 30, + SUB = 31, + MUL = 32, + DIV = 33, + + // AST "Virtual" Node Types + MACRO = 40, + SEP = 41, + PROGRAM = 42, + BLOCK = 43, + FN_CALL = 44, + PARAMS = 45, + ARRY_IDX = 46 } eTokenTypes; typedef struct { - char match; - eTokenTypes type; + char match; + eTokenTypes type; } SingleCharMatch_T; -class DLLexer : public Lexer { - public: - bool isWhiteSpace(void); - bool isLetter(void); - bool isDigit(void); - bool isOperator(void); - bool isStringChar(void); - void WS(void); - void COMMENT(void); +class DLLexer : public ILexer { + public: + bool isWhiteSpace(void); + bool isLetter(void); + bool isDigit(void); + bool isOperator(void); + bool isStringChar(void); + void WS(void); + void COMMENT(void); - Token* next(void); - Token* Id(void); - Token* Number(void); - Token* Decimal(std::ostringstream& oss); - Token* Char(void); - Token* String(void); - Token* Symbol(void); - Token* SingleCharOp(void); - Token* MultiCharOp(void); + Token* next(void); + Token* Id(void); + Token* Number(void); + Token* Decimal(std::ostringstream& oss); + Token* Char(void); + Token* String(void); + Token* Symbol(void); + Token* SingleCharOp(void); + Token* MultiCharOp(void); }; diff --git a/source/dlparser/dlparser.cpp b/source/dlparser/dlparser.cpp index 690406e..f7f547d 100644 --- a/source/dlparser/dlparser.cpp +++ b/source/dlparser/dlparser.cpp @@ -1,376 +1,377 @@ #include "dlparser.h" #include "exception.h" +#include "cork.h" -DLParser::DLParser() : BTParser(new DLLexer()), ast(NULL) +DLParser::DLParser() : BTParser(_new DLLexer()), ast(NULL) { } void DLParser::parse(void) { - ast = Program(); + ast = Program(); } AST* DLParser::getAST(void) { - return ast; + return ast; } bool DLParser::isMacro( Token* token ) { - bool ret = false; - if( (token->type() == ID) && (macros.find(token->text()) != macros.end()) ) - { - ret = true; - } - return ret; + bool ret = false; + if( (token->type() == ID) && (macros.find(token->text()) != macros.end()) ) + { + ret = true; + } + return ret; } AST* DLParser::parseMacroParam(Param* param) { - AST* ret = NULL; - switch( param->type() ) - { - case ExpTyp: - ret = LogicalExpr(); - break; - - case BlockTyp: - ret = FuncLiteral(); - break; - - default: - Token* tok = lookaheadToken(1); - ostringstream oss; - oss << "Expected macro parameter type. Expected " << param->type() << ", received " << tok->type() << "."; - Exception ex( tok->line(), tok->column() ); - ex.setMessage(oss.str()); - break; - } - return ret; + AST* ret = NULL; + switch( param->type() ) + { + case ExpTyp: + ret = LogicalExpr(); + break; + + case BlockTyp: + ret = FuncLiteral(); + break; + + default: + Token* tok = lookaheadToken(1); + ostringstream oss; + oss << "Expected macro parameter type. Expected " << param->type() << ", received " << tok->type() << "."; + Exception ex( tok->line(), tok->column() ); + ex.setMessage(oss.str()); + break; + } + return ret; } AST* DLParser::Program(void) { - AST* node = new AST( PROGRAM ); - while( lookaheadType(1) != EOF ) - { - node->addChild( Expression() ); - } - return node; + AST* node = _new AST( PROGRAM ); + while( lookaheadType(1) != EOF ) + { + node->addChild( Expression() ); + } + return node; } AST* DLParser::Expression(void) { - AST* ret = NULL; - if((lookaheadType(1) == ID) && (lookaheadType(2) == ASSIGN)) - { - AST* id_node = new AST( ID,(char*)(lookaheadToken(1)->text().c_str()) ); - consume(); - match(ASSIGN); - ret = new AST( ASSIGN, 2, id_node, Expression()); - } - else if( (lookaheadType(1) == MACRO) && (lookaheadType(2) == ID)) - { - ret = MacroDefinition(); - } - else if( isMacro( lookaheadToken(1) ) ) - { - ret = MacroExpansion(); - } - else - { - ret = LogicalExpr(); - } - return ret; + AST* ret = NULL; + if((lookaheadType(1) == ID) && (lookaheadType(2) == ASSIGN)) + { + AST* id_node = _new AST( ID,(char*)(lookaheadToken(1)->text().c_str()) ); + consume(); + match(ASSIGN); + ret = _new AST( ASSIGN, 2, id_node, Expression()); + } + else if( (lookaheadType(1) == MACRO) && (lookaheadType(2) == ID)) + { + ret = MacroDefinition(); + } + else if( isMacro( lookaheadToken(1) ) ) + { + ret = MacroExpansion(); + } + else + { + ret = LogicalExpr(); + } + return ret; } AST* DLParser::LogicalExpr(void) { - AST* ret = CompExpr(); - while((lookaheadType(1) == AND) || (lookaheadType(1) == OR)) - { - ret = new AST( lookaheadType(1), 1, ret); - consume(); - ret->addChild( CompExpr() ); - } - return ret; + AST* ret = CompExpr(); + while((lookaheadType(1) == AND) || (lookaheadType(1) == OR)) + { + ret = _new AST( lookaheadType(1), 1, ret); + consume(); + ret->addChild( CompExpr() ); + } + return ret; } AST* DLParser::CompExpr(void) { - AST* ret = AddSubExpr(); - while( (lookaheadType(1) == EQ) || (lookaheadType(1) == NE) - || (lookaheadType(1) == LT) || (lookaheadType(1) == GT) - || (lookaheadType(1) == LTE) || (lookaheadType(1) == GTE)) - { - ret = new AST( lookaheadType(1), 1, ret); - consume(); - ret->addChild( AddSubExpr() ); - } - return ret; + AST* ret = AddSubExpr(); + while( (lookaheadType(1) == EQ) || (lookaheadType(1) == NE) + || (lookaheadType(1) == LT) || (lookaheadType(1) == GT) + || (lookaheadType(1) == LTE) || (lookaheadType(1) == GTE)) + { + ret = _new AST( lookaheadType(1), 1, ret); + consume(); + ret->addChild( AddSubExpr() ); + } + return ret; } AST* DLParser::AddSubExpr(void) { - AST* ret = MulDivExpr(); - while((lookaheadType(1) == ADD) || (lookaheadType(1) == SUB)) - { - ret = new AST( lookaheadType(1), 1, ret); - consume(); - ret->addChild( MulDivExpr() ); - } - return ret; + AST* ret = MulDivExpr(); + while((lookaheadType(1) == ADD) || (lookaheadType(1) == SUB)) + { + ret = _new AST( lookaheadType(1), 1, ret); + consume(); + ret->addChild( MulDivExpr() ); + } + return ret; } AST* DLParser::MulDivExpr(void) { - AST* ret = UnaryExpr(); - while((lookaheadType(1) == MUL) || (lookaheadType(1) == DIV)) - { - ret = new AST( lookaheadType(1), 1, ret); - consume(); - ret->addChild( UnaryExpr() ); - } - return ret; + AST* ret = UnaryExpr(); + while((lookaheadType(1) == MUL) || (lookaheadType(1) == DIV)) + { + ret = _new AST( lookaheadType(1), 1, ret); + consume(); + ret->addChild( UnaryExpr() ); + } + return ret; } AST* DLParser::UnaryExpr(void) { - AST* ret = NULL; - if(lookaheadType(1) == NOT) - { - consume(); - ret = new AST(NOT, 1, GroupExpr() ); - } - else - { - ret = GroupExpr(); - } - return ret; + AST* ret = NULL; + if(lookaheadType(1) == NOT) + { + consume(); + ret = _new AST(NOT, 1, GroupExpr() ); + } + else + { + ret = GroupExpr(); + } + return ret; } AST* DLParser::GroupExpr(void) { - AST* ret = NULL; - if(lookaheadType(1) == LPAR) - { - match(LPAR); - ret = LogicalExpr(); - match(RPAR); - } - else - { - ret = Literal(); - if( lookaheadType(1) == LPAR ) - { - match(LPAR); - ret = new AST( FN_CALL, 2, ret, ExpList( LIST, RPAR ) ); - match(RPAR); - } - else if( lookaheadType(1) == LBRACK ) - { - match(LBRACK); - ret = new AST( ARRY_IDX, 2, ret, LogicalExpr() ); - match(RBRACK); - } - } - return ret; + AST* ret = NULL; + if(lookaheadType(1) == LPAR) + { + match(LPAR); + ret = LogicalExpr(); + match(RPAR); + } + else + { + ret = Literal(); + if( lookaheadType(1) == LPAR ) + { + match(LPAR); + ret = _new AST( FN_CALL, 2, ret, ExpList( LIST, RPAR ) ); + match(RPAR); + } + else if( lookaheadType(1) == LBRACK ) + { + match(LBRACK); + ret = _new AST( ARRY_IDX, 2, ret, LogicalExpr() ); + match(RBRACK); + } + } + return ret; } AST* DLParser::Literal(void) { - AST* node = NULL; - switch(lookaheadType(1)) - { - // Literal = VectorLiteral - case LBRACK: - node = VectorLiteral(); - break; - - // Literal = ListLiteral - case LIST: - node = ListLiteral(); - break; - - // Literal = FuncLiteral - case LBRACE: - node = FuncLiteral(); - break; - - // Literal = ID - case ID: - node = new AST( ID, lookaheadToken(1)->text() ); - consume(); - break; - - // Literal = NUM - case NUM: - node = new AST( NUM, lookaheadToken(1)->text() ); - consume(); - break; - - // Literal = CHAR - case CHAR: - node = new AST( CHAR, lookaheadToken(1)->text() ); - consume(); - break; - - // Literal = STRING - case STRING: - node = new AST( STRING, lookaheadToken(1)->text() ); - consume(); - break; - - // Literal = SYMBOL - case SYMBOL: - node = new AST( SYMBOL, lookaheadToken(1)->text() ); - consume(); - break; - - default: - Token* tok = lookaheadToken(1); - ostringstream oss; - oss << "Expected literal type, recieved type " << tok->type() << "."; - Exception ex( tok->line(), tok->column() ); - ex.setMessage(oss.str()); - throw ex; - } - return node; + AST* node = NULL; + switch(lookaheadType(1)) + { + // Literal = VectorLiteral + case LBRACK: + node = VectorLiteral(); + break; + + // Literal = ListLiteral + case LIST: + node = ListLiteral(); + break; + + // Literal = FuncLiteral + case LBRACE: + node = FuncLiteral(); + break; + + // Literal = ID + case ID: + node = _new AST( ID, lookaheadToken(1)->text() ); + consume(); + break; + + // Literal = NUM + case NUM: + node = _new AST( NUM, lookaheadToken(1)->text() ); + consume(); + break; + + // Literal = CHAR + case CHAR: + node = _new AST( CHAR, lookaheadToken(1)->text() ); + consume(); + break; + + // Literal = STRING + case STRING: + node = _new AST( STRING, lookaheadToken(1)->text() ); + consume(); + break; + + // Literal = SYMBOL + case SYMBOL: + node = _new AST( SYMBOL, lookaheadToken(1)->text() ); + consume(); + break; + + default: + Token* tok = lookaheadToken(1); + ostringstream oss; + oss << "Expected literal type, recieved type " << tok->type() << "."; + Exception ex( tok->line(), tok->column() ); + ex.setMessage(oss.str()); + throw ex; + } + return node; } AST* DLParser::VectorLiteral(void) { - AST* ret = NULL; - match(LBRACK); - ret = ExpList(VECTOR, RBRACK); - match(RBRACK); - return ret; + AST* ret = NULL; + match(LBRACK); + ret = ExpList(VECTOR, RBRACK); + match(RBRACK); + return ret; } AST* DLParser::ListLiteral(void) { - AST* ret = NULL; - match(LIST); - match(LPAR); - ret = ExpList(LIST, RPAR); - match(RPAR); - return ret; + AST* ret = NULL; + match(LIST); + match(LPAR); + ret = ExpList(LIST, RPAR); + match(RPAR); + return ret; } AST* DLParser::FuncLiteral(void) { - AST* ret = NULL; - - match(LBRACE); - if(lookaheadType(1) == PIPE) - { - match(PIPE); - ret = ExpList(PARAMS, PIPE); - match(PIPE); - ret = new AST(FUNC, 2, ret, ExpBlock(BLOCK,RBRACE)); - } - else - { - ret = new AST(FUNC, 2, new AST(PARAMS), ExpBlock(BLOCK,RBRACE)); - } - match(RBRACE); - return ret; + AST* ret = NULL; + + match(LBRACE); + if(lookaheadType(1) == PIPE) + { + match(PIPE); + ret = ExpList(PARAMS, PIPE); + match(PIPE); + ret = _new AST(FUNC, 2, ret, ExpBlock(BLOCK,RBRACE)); + } + else + { + ret = _new AST(FUNC, 2, _new AST(PARAMS), ExpBlock(BLOCK,RBRACE)); + } + match(RBRACE); + return ret; } // MacroDefinition = '%' ID '(' MacroParamList ')' '{' Expression '}' AST* DLParser::MacroDefinition(void) { - AST* ret = NULL; - AST* id = NULL; - AST* params = NULL; - AST* body = NULL; - Macro* macro = NULL; - - match(MACRO); - id = new AST( ID, lookaheadToken(1)->text() ); - consume(); - match(LPAR); - params = MacroParamList(); - match(RPAR); - match(LBRACE); - body = Expression(); - match(RBRACE); - ret = new AST( MACRO, 3, id, params, body ); - - macro = new Macro( ret ); - macros.insert( std::pair(id->text(), macro) ); - - return new AST(MACRO); + AST* ret = NULL; + AST* id = NULL; + AST* params = NULL; + AST* body = NULL; + Macro* macro = NULL; + + match(MACRO); + id = _new AST( ID, lookaheadToken(1)->text() ); + consume(); + match(LPAR); + params = MacroParamList(); + match(RPAR); + match(LBRACE); + body = Expression(); + match(RBRACE); + ret = _new AST( MACRO, 3, id, params, body ); + + macro = _new Macro( ret ); + macros.insert( std::pair(id->text(), macro) ); + + return _new AST(MACRO); } AST* DLParser::MacroExpansion(void) { - AST* ret = NULL; - Macro* cur_macro = macros[ lookaheadToken(1)->text() ]; - list::const_iterator it = cur_macro->params().begin(); - - consume(); - for(; it != cur_macro->params().end(); it++) - { - (*it)->setValue( parseMacroParam( *it ) ); - } - ret = cur_macro->apply(); - - return ret; + AST* ret = NULL; + Macro* cur_macro = macros[ lookaheadToken(1)->text() ]; + list::const_iterator it = cur_macro->params().begin(); + + consume(); + for(; it != cur_macro->params().end(); it++) + { + (*it)->setValue( parseMacroParam( *it ) ); + } + ret = cur_macro->apply(); + + return ret; } -// MacroParamList = MacroParam (',' MacroParam)* +// MacroParamList = MacroParam (',' MacroParam)* AST* DLParser::MacroParamList(void) { - AST* ret = new AST( PARAMS ); - ret->addChild( MacroParam() ); - while(lookaheadType(1) == COMMA) - { - match(COMMA); - ret->addChild( MacroParam() ); - } - return ret; + AST* ret = _new AST( PARAMS ); + ret->addChild( MacroParam() ); + while(lookaheadType(1) == COMMA) + { + match(COMMA); + ret->addChild( MacroParam() ); + } + return ret; } // MacroParam = ID (':' ID)? AST* DLParser::MacroParam(void) { - AST* ret = new AST( ID, lookaheadToken(1)->text() ); - consume(); - if( lookaheadType(1) == SEP ) - { - match(SEP); - AST* type = new AST( ID, lookaheadToken(1)->text() ); - consume(); - ret = new AST(SEP, 2, ret, type); - } - return ret; + AST* ret = _new AST( ID, lookaheadToken(1)->text() ); + consume(); + if( lookaheadType(1) == SEP ) + { + match(SEP); + AST* type = _new AST( ID, lookaheadToken(1)->text() ); + consume(); + ret = _new AST(SEP, 2, ret, type); + } + return ret; } // ExpList = (Expression (',' Expression)*)? AST* DLParser::ExpList(TokenType_T node_type, TokenType_T terminator) { - AST* node = new AST( node_type ); - if(lookaheadType(1) != terminator) - { - node->addChild( Expression() ); - while(lookaheadType(1) == COMMA) - { - match(COMMA); - node->addChild( Expression() ); - } - } - return node; + AST* node = _new AST( node_type ); + if(lookaheadType(1) != terminator) + { + node->addChild( Expression() ); + while(lookaheadType(1) == COMMA) + { + match(COMMA); + node->addChild( Expression() ); + } + } + return node; } // ExpBlock = Expression+ AST* DLParser::ExpBlock(TokenType_T node_type, TokenType_T terminator) { - AST* node = new AST(node_type); - while(lookaheadType(1) != RBRACE) - { - node->addChild( Expression() ); - } - return node; + AST* node = _new AST(node_type); + while(lookaheadType(1) != RBRACE) + { + node->addChild( Expression() ); + } + return node; } diff --git a/source/dlparser/macro/macro.c b/source/dlparser/macro/macro.c index 8542218..0808661 100644 --- a/source/dlparser/macro/macro.c +++ b/source/dlparser/macro/macro.c @@ -1,49 +1,52 @@ #include "macro.h" #include "macroapplication.h" +#include "cork.h" + +using namespace std; Macro::Macro(AST* macro_def) { - list::iterator it = macro_def->children()->begin(); - - // Set Name - macro_name = (*it++)->text(); + list::iterator it = macro_def->children()->begin(); + + // Set Name + macro_name = (*it++)->text(); - // Set Body - setUpParamList( *it++ ); + // Set Body + setUpParamList( *it++ ); - // Set Params - macro_body = (*it++)->clone(); + // Set Params + macro_body = (*it++)->clone(); } Macro::~Macro() { - delete macro_body; + delete macro_body; } const std::string& Macro::name(void) { - return macro_name; + return macro_name; } const std::list& Macro::params(void) { - return macro_params; + return macro_params; } AST* Macro::apply(void) { - MacroApplication application(macro_body->clone(), macro_params); - application.visit(); - return application.getAST()->clone(); + MacroApplication application(macro_body->clone(), macro_params); + application.visit(); + return application.getAST()->clone(); } void Macro::setUpParamList( AST* param_tree ) { - list::iterator it = param_tree->children()->begin(); - for(; it != param_tree->children()->end(); it++) - { - macro_params.push_back( new Param( *it ) ); - } + list::iterator it = param_tree->children()->begin(); + for(; it != param_tree->children()->end(); it++) + { + macro_params.push_back( _new Param( *it ) ); + } } diff --git a/source/dlparser/macro/macro.h b/source/dlparser/macro/macro.h index b95d728..8c73c3f 100644 --- a/source/dlparser/macro/macro.h +++ b/source/dlparser/macro/macro.h @@ -8,19 +8,19 @@ class Macro { - private: - std::string macro_name; - std::list macro_params; - AST* macro_body; + private: + std::string macro_name; + std::list macro_params; + AST* macro_body; - void setUpParamList( AST* param_tree ); - public: - Macro(AST* macro_def); - ~Macro(); + void setUpParamList( AST* param_tree ); + public: + Macro(AST* macro_def); + ~Macro(); - const std::string& name(void); - const std::list& params(void); - AST* apply(void); + const std::string& name(void); + const std::list& params(void); + AST* apply(void); }; #endif diff --git a/source/dlparser/macro/param.c b/source/dlparser/macro/param.c index ac6a8bb..16f5164 100644 --- a/source/dlparser/macro/param.c +++ b/source/dlparser/macro/param.c @@ -2,56 +2,56 @@ Param::Param(AST* param_def) { - int children = param_def->children()->size(); - if( children == 0 ) - { - param_name = param_def->text(); - } - else if( children == 2) - { - param_name = param_def->children()->front()->text(); - setType( param_def->children()->front()->text() ); - } - else - { - // Throw - } + int children = param_def->children()->size(); + if( children == 0 ) + { + param_name = param_def->text(); + } + else if( children == 2) + { + param_name = param_def->children()->front()->text(); + setType( param_def->children()->front()->text() ); + } + else + { + // Throw + } } Param::~Param() { - delete param_value; + delete param_value; } std::string Param::name(void) { - return param_name; + return param_name; } ParamType_T Param::type(void) { - return param_type; + return param_type; } AST* Param::value(void) { - return param_value; + return param_value; } void Param::setValue(AST* val) { - param_value = val; + param_value = val; } void Param::setType( const std::string& type_string ) { - if ( type_string.compare("Block") == 0 ) - { - param_type = BlockTyp; - } - else - { - param_type = ExpTyp; - } + if ( type_string.compare("Block") == 0 ) + { + param_type = BlockTyp; + } + else + { + param_type = ExpTyp; + } } diff --git a/source/dlparser/macro/param.h b/source/dlparser/macro/param.h index 79c209f..b6787ca 100644 --- a/source/dlparser/macro/param.h +++ b/source/dlparser/macro/param.h @@ -5,27 +5,27 @@ #include "ast.h" typedef enum { - ExpTyp, - BlockTyp + ExpTyp, + BlockTyp } ParamType_T; class Param { - private: - std::string param_name; - ParamType_T param_type; - AST* param_value; + private: + std::string param_name; + ParamType_T param_type; + AST* param_value; - void setType( const std::string& type_string ); + void setType( const std::string& type_string ); - public: - Param(AST* param_def); - ~Param(); + public: + Param(AST* param_def); + ~Param(); - std::string name(void); - ParamType_T type(void); - AST* value(void); - void setValue(AST* val); + std::string name(void); + ParamType_T type(void); + AST* value(void); + void setValue(AST* val); }; #endif diff --git a/source/main.cpp b/source/main.cpp index 3c8b8fc..240e115 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -5,6 +5,7 @@ #include "dlparser.h" #include "sexp.h" #include "scheme.h" +#include "cork.h" using namespace std; @@ -13,75 +14,90 @@ static string createTempFileName(string fname); int main(int argc, char** argv) { - int ret = 0; - - if( (argc == 2) && fileExists( argv[1] ) ) - { - string input_fname(argv[1]); - string temp_fname = createTempFileName( input_fname ); - DLParser parser; - Scheme* visitor = NULL; - - // Open the input and output files - ifstream input(input_fname.c_str()); - ofstream output(temp_fname.c_str()); - - // Parse the file - parser.setInput(&input); - parser.parse(); - - // Translate the AST - visitor = new Scheme( parser.getAST() ); - visitor->visit(); - - // Write to a temp file - output << visitor->str(); - cout << visitor->str(); - output.close(); - - // Compile temp file - system(("csc " + temp_fname).c_str()); - - //// delete temp file - remove(temp_fname.c_str()); - } - else - { - ret = 1; - } - - if(ret != 0) - { - // Print error code specific error - cout << "Usage: " << argv[0] << " \n" << endl; - cerr << "Error: No input files." << endl; - } - - return ret; + int ret = 0; + + if( (argc == 2) && fileExists( argv[1] ) ) + { + //string input_fname(argv[1]); + //string temp_fname = createTempFileName( input_fname ); + //ifstream input(input_fname.c_str()); + //DLLexer lexer; + //lexer.setInput(&input); + //lexer.next(); + //(void)temp_fname; + + string input_fname(argv[1]); + string temp_fname = createTempFileName( input_fname ); + (void)temp_fname; + DLParser parser; + Scheme* visitor = NULL; + AST* parse_tree = NULL; + + // Open the input and output files + ifstream input(input_fname.c_str()); + //ofstream output(temp_fname.c_str()); + + // Parse the file + parser.setInput(&input); + parser.parse(); + parse_tree = parser.getAST(); + + // Translate the AST + visitor = _new Scheme( parse_tree ); + //visitor->visit(); + + // Write to a temp file + //output << visitor->str(); + //cout << visitor->str(); + //output.close(); + + // Compile temp file + //system(("csc " + temp_fname).c_str()); + + //// delete temp file + //remove(temp_fname.c_str()); + //delete visitor; + delete parse_tree; + } + else + { + ret = 1; + } + + if(ret != 0) + { + // Print error code specific error + cout << "Usage: " << argv[0] << " \n" << endl; + cerr << "Error: No input files." << endl; + } + + REPORT_LEAKS(); + + return ret; } bool fileExists(char* fname) { - string in_fname(fname); - ifstream file(fname,ifstream::in); - return (file != NULL); + string in_fname(fname); + ifstream file(fname,ifstream::in); + return (file != NULL); } string createTempFileName(string fname) { - string ret_str; - size_t ext_index = fname.find_last_of('.'); - // If we did NOT find a match, assume no extension given - if (ext_index == string::npos) - { - ret_str = fname + ".scm"; - } - // else replace the existing extension - else - { - ret_str = fname; - ret_str.replace(ext_index, (ret_str.size() -1), ".scm"); - } - return ret_str; + string ret_str; + size_t ext_index = fname.find_last_of('.'); + // If we did NOT find a match, assume no extension given + if (ext_index == string::npos) + { + ret_str = fname + ".scm"; + } + // else replace the existing extension + else + { + ret_str = fname; + ret_str.replace(ext_index, (ret_str.size() -1), ".scm"); + } + return ret_str; } diff --git a/source/parse_utils/ast/ast.cpp b/source/parse_utils/ast/ast.cpp deleted file mode 100644 index 35d14b7..0000000 --- a/source/parse_utils/ast/ast.cpp +++ /dev/null @@ -1,113 +0,0 @@ -#include "ast.h" -#include -#include -#include - -AST::AST(ASTNodeType type) -{ - node_type = type; - node_text = NULL; - node_children = new list(); -} - -AST::~AST() -{ - list::iterator it = node_children->begin(); - for(; it != node_children->end(); it++) - { - delete *(it); - } - delete node_children; - delete node_text; -} - -AST::AST(ASTNodeType type, const char* text) -{ - node_type = type; - node_text = new string(text); - node_children = new list(); -} - -AST::AST(ASTNodeType type, const std::string& text) -{ - node_type = type; - node_text = new string(text); - node_children = new list(); -} - -AST::AST(ASTNodeType type, int child_count, ...) -{ - va_list arg_list; - int i = 0; - node_type = type; - node_text = NULL; - node_children = new list(); - va_start (arg_list, child_count); - for (i = 0; i < child_count ; i++) - { - node_children->push_back( (AST*)va_arg(arg_list, AST*) ); - } - va_end(arg_list); -} - -AST& AST::operator = (AST& rhs) -{ - list::iterator it = rhs.children()->begin(); - node_type = rhs.type(); - *node_text = rhs.text(); - node_children->clear(); - - for(; it != rhs.children()->end(); it++) - { - node_children->push_back( (*it)->clone() ); - } - - return *this; -} - -ASTNodeType AST::type(void) -{ - return node_type; -} - -list* AST::children(void) -{ - return node_children; -} - -string AST::text(void) -{ - ostringstream oss; - if(node_text != NULL) - { - oss << node_text->c_str(); - } - return oss.str(); -} - -void AST::addChild(AST* node) -{ - node_children->push_back(node); -} - -AST* AST::clone(void) -{ - AST* new_clone = NULL; - list::iterator it = node_children->begin(); - - if(node_text == NULL) - { - new_clone = new AST( node_type ); - } - else - { - new_clone = new AST( node_type, *node_text ); - } - - for(; it != node_children->end(); it++) - { - new_clone->addChild( (*it)->clone() ); - } - return new_clone; -} - diff --git a/source/parse_utils/ast/ast.h b/source/parse_utils/ast/ast.h deleted file mode 100644 index 3ea3712..0000000 --- a/source/parse_utils/ast/ast.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef AST_H -#define AST_H - -#include -#include -#include - -using namespace std; - -typedef unsigned int ASTNodeType; - -class AST -{ - protected: - ASTNodeType node_type; - string* node_text; - list* node_children; - public: - AST(ASTNodeType type); - AST(ASTNodeType type, const char* text); - AST(ASTNodeType type, const string& text); - AST(ASTNodeType type, int child_count, ...); - virtual ~AST(); - - AST& operator = (AST& rhs); - - ASTNodeType type(void); - string text(void); - list* children(void); - void addChild(AST* node); - AST* clone(void); -}; - -#endif diff --git a/source/parse_utils/exception/exception.cpp b/source/parse_utils/exception/exception.cpp index cd4931b..f95f7ce 100644 --- a/source/parse_utils/exception/exception.cpp +++ b/source/parse_utils/exception/exception.cpp @@ -7,19 +7,19 @@ Exception::Exception(int line, int column) throw() : std::exception(), ex_line(l const char* Exception::what() const throw() { - std::ostringstream oss; - oss << "(ln " << ex_line << ", col " << ex_column << "): "; - oss << ((Exception*)this)->message() << std::endl; - return oss.str().c_str(); + std::ostringstream oss; + oss << "(ln " << ex_line << ", col " << ex_column << "): "; + oss << ((Exception*)this)->message() << std::endl; + return oss.str().c_str(); } void Exception::setMessage(std::string msg) throw() { - ex_msg = msg; + ex_msg = msg; } std::string& Exception::message(void) throw() { - return ex_msg; + return ex_msg; } diff --git a/source/parse_utils/lexer/ilexer.cpp b/source/parse_utils/lexer/ilexer.cpp new file mode 100644 index 0000000..6d8cac5 --- /dev/null +++ b/source/parse_utils/lexer/ilexer.cpp @@ -0,0 +1,81 @@ +#include +#include "ilexer.h" +#include "exception.h" +#include "cork.h" + +using namespace std; + +ILexer::ILexer() : line(-1), column(-1) +{ +} + +ILexer::~ILexer() +{ +} + +void ILexer::setInput(char* in) +{ + line = 1; + column = 0; + input = _new istringstream( string( in ) ); + consume(); +} + +void ILexer::setInput(string& in) +{ + line = 1; + column = 0; + input = _new istringstream( in ); + consume(); +} + +void ILexer::setInput(istream* in) +{ + line = 1; + column = 0; + input = in; + consume(); +} + +bool ILexer::eof(void) +{ + return ((input == NULL) || (input->eof())); +} + +void ILexer::consume(void) +{ + if(input->eof()) + { + current = EOF; + } + else + { + current = input->get(); + if(current == '\n') + { + line++; + column = 0; + } + else + { + column++; + } + } +} + +void ILexer::match(char x) { + if ( current == x) + { + consume(); + } + else + { + ostringstream oss; + oss << "Unexpected character. Expected " << x << ", received " << current << "."; + Exception ex(line,column); + ex.setMessage(oss.str()); + throw ex; + } +} + + diff --git a/source/parse_utils/lexer/ilexer.h b/source/parse_utils/lexer/ilexer.h new file mode 100644 index 0000000..3b04943 --- /dev/null +++ b/source/parse_utils/lexer/ilexer.h @@ -0,0 +1,32 @@ +#ifndef LEXER_H +#define LEXER_H + +#include +#include +#include +#include "token.h" + +class ILexer +{ + protected: + int line; + int column; + char current; + std::istream* input; + + void consume(void); + void match(char x); + bool eof(void); + + public: + ILexer(); + virtual ~ILexer(); + + void setInput(char* in); + void setInput(std::string& in); + void setInput(std::istream* in); + + virtual Token* next(void) = 0; +}; + +#endif diff --git a/source/parse_utils/lexer/lexer.cpp b/source/parse_utils/lexer/lexer.cpp deleted file mode 100644 index d84c25b..0000000 --- a/source/parse_utils/lexer/lexer.cpp +++ /dev/null @@ -1,80 +0,0 @@ -#include -#include "lexer.h" -#include "exception.h" - -using namespace std; - -Lexer::Lexer() : line(-1), column(-1) -{ -} - -Lexer::~Lexer() -{ -} - -void Lexer::setInput(char* in) -{ - line = 1; - column = 0; - input = new istringstream( string( in ) ); - consume(); -} - -void Lexer::setInput(string& in) -{ - line = 1; - column = 0; - input = new istringstream( in ); - consume(); -} - -void Lexer::setInput(istream* in) -{ - line = 1; - column = 0; - input = in; - consume(); -} - -bool Lexer::eof(void) -{ - return ((input == NULL) || (input->eof())); -} - -void Lexer::consume(void) -{ - if(input->eof()) - { - current = EOF; - } - else - { - current = input->get(); - if(current == '\n') - { - line++; - column = 0; - } - else - { - column++; - } - } -} - -void Lexer::match(char x) { - if ( current == x) - { - consume(); - } - else - { - ostringstream oss; - oss << "Unexpected character. Expected " << x << ", received " << current << "."; - Exception ex(line,column); - ex.setMessage(oss.str()); - throw ex; - } -} - - diff --git a/source/parse_utils/lexer/lexer.h b/source/parse_utils/lexer/lexer.h deleted file mode 100644 index 3b89235..0000000 --- a/source/parse_utils/lexer/lexer.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef LEXER_H -#define LEXER_H - -#include -#include -#include -#include "token.h" - -class Lexer -{ - public: - int line; - int column; - char current; - std::istream* input; - - Lexer(); - virtual ~Lexer(); - - void setInput(char* in); - void setInput(std::string& in); - void setInput(std::istream* in); - - void consume(void); - void match(char x); - bool eof(void); - virtual Token* next(void) = 0; -}; - -#endif diff --git a/source/parse_utils/lexer/token/token.cpp b/source/parse_utils/lexer/token/token.cpp index 9b68106..dab99b7 100644 --- a/source/parse_utils/lexer/token/token.cpp +++ b/source/parse_utils/lexer/token/token.cpp @@ -10,21 +10,21 @@ Token::Token(TokenType_T ttype, int line, int col) : tok_type(ttype), tok_line(l TokenType_T Token::type() { - return tok_type; + return tok_type; } -const std::string& Token::text() +std::string Token::text() { - return tok_text; + return tok_text; } int Token::line() { - return tok_line; + return tok_line; } int Token::column() { - return tok_col; + return tok_col; } diff --git a/source/parse_utils/lexer/token/token.h b/source/parse_utils/lexer/token/token.h index 32381b6..75f8a85 100644 --- a/source/parse_utils/lexer/token/token.h +++ b/source/parse_utils/lexer/token/token.h @@ -1,5 +1,5 @@ #ifndef TOKEN_H -#define TOKEN_H +#define TOKEN_H #include @@ -7,18 +7,18 @@ typedef int TokenType_T; class Token { - private: - TokenType_T tok_type; - std::string tok_text; - int tok_line; - int tok_col; - public: - Token(TokenType_T ttype, int line, int col); - Token(TokenType_T ttype, std::string ttext, int line, int col); - TokenType_T type(); - const std::string& text(); - int line(); - int column(); + private: + TokenType_T tok_type; + std::string tok_text; + int tok_line; + int tok_col; + public: + Token(TokenType_T ttype, int line, int col); + Token(TokenType_T ttype, std::string ttext, int line, int col); + TokenType_T type(); + std::string text(); + int line(); + int column(); }; #endif diff --git a/source/parse_utils/parser/ast/ast.cpp b/source/parse_utils/parser/ast/ast.cpp new file mode 100644 index 0000000..d090428 --- /dev/null +++ b/source/parse_utils/parser/ast/ast.cpp @@ -0,0 +1,98 @@ +#include "ast.h" +#include +#include +#include +#include "cork.h" + +AST::AST(ASTNodeType type) +{ + node_type = type; + node_text = ""; + node_children = _new list(); +} + +AST::AST(ASTNodeType type, const char* text) +{ + node_type = type; + node_text = string(text); + node_children = _new list(); +} + +AST::AST(ASTNodeType type, std::string text) +{ + node_type = type; + node_text = text; + node_children = _new list(); +} + +AST::AST(ASTNodeType type, int child_count, ...) +{ + va_list arg_list; + int i = 0; + node_type = type; + node_text = ""; + node_children = _new list(); + va_start (arg_list, child_count); + for (i = 0; i < child_count ; i++) + { + node_children->push_back( (AST*)va_arg(arg_list, AST*) ); + } + va_end(arg_list); +} + +AST::~AST() +{ + list::iterator it = node_children->begin(); + for(; it != node_children->end(); it++) + { + delete *(it); + } + delete node_children; +} + +AST& AST::operator = (AST& rhs) +{ + list::iterator it = rhs.children()->begin(); + node_type = rhs.type(); + node_text = rhs.text(); + node_children->clear(); + + for(; it != rhs.children()->end(); it++) + { + node_children->push_back( (*it)->clone() ); + } + + return *this; +} + +ASTNodeType AST::type(void) +{ + return node_type; +} + +list* AST::children(void) +{ + return node_children; +} + +string AST::text(void) +{ + return node_text; +} + +void AST::addChild(AST* node) +{ + node_children->push_back(node); +} + +AST* AST::clone(void) +{ + AST* new_clone = _new AST( node_type, node_text ); + list::iterator it = node_children->begin(); + for(; it != node_children->end(); it++) + { + new_clone->addChild( (*it)->clone() ); + } + return new_clone; +} + diff --git a/source/parse_utils/parser/ast/ast.h b/source/parse_utils/parser/ast/ast.h new file mode 100644 index 0000000..8e1079c --- /dev/null +++ b/source/parse_utils/parser/ast/ast.h @@ -0,0 +1,34 @@ +#ifndef AST_H +#define AST_H + +#include +#include +#include + +using namespace std; + +typedef unsigned int ASTNodeType; + +class AST +{ + protected: + ASTNodeType node_type; + string node_text; + list* node_children; + public: + AST(ASTNodeType type); + AST(ASTNodeType type, const char* text); + AST(ASTNodeType type, string text); + AST(ASTNodeType type, int child_count, ...); + virtual ~AST(); + + AST& operator = (AST& rhs); + + ASTNodeType type(void); + string text(void); + list* children(void); + void addChild(AST* node); + AST* clone(void); +}; + +#endif diff --git a/source/parse_utils/parser/btparser/btparser.cpp b/source/parse_utils/parser/btparser/btparser.cpp index 782174f..6aacba3 100644 --- a/source/parse_utils/parser/btparser/btparser.cpp +++ b/source/parse_utils/parser/btparser/btparser.cpp @@ -1,117 +1,117 @@ -#include "BTParser.h" +#include "btparser.h" #include "exception.h" -BTParser::BTParser(Lexer* lxer) : lexer(lxer), current(0) +BTParser::BTParser(ILexer* lxer) : lexer(lxer), current(0) { } BTParser::~BTParser() { - if(lexer != NULL) - { - delete lexer; - // Input stream was deleted with the lexer so null it out - Parser::setInput((istream*)NULL); - } + if(lexer != NULL) + { + delete lexer; + // Input stream was deleted with the lexer so null it out + IParser::setInput((istream*)NULL); + } } void BTParser::setInput(char* in) { - Parser::setInput(in); - lexer->setInput(in); + IParser::setInput(in); + lexer->setInput(in); } void BTParser::setInput(string& in) { - Parser::setInput(in); - lexer->setInput(in); + IParser::setInput(in); + lexer->setInput(in); } void BTParser::setInput(istream* in) { - Parser::setInput(in); - lexer->setInput(in); + IParser::setInput(in); + lexer->setInput(in); } void BTParser::consume(void) { - current++; - if((current == lookahead.size()) && !isSpeculating()) - { - current = 0; - lookahead.clear(); - } - sync(1); + current++; + if((current == lookahead.size()) && !isSpeculating()) + { + current = 0; + lookahead.clear(); + } + sync(1); } void BTParser::sync(unsigned int i) { - unsigned int next_index = current + i - 1; - unsigned int max_index = (lookahead.size() == 0) ? 0 : (lookahead.size() - 1); - if( next_index >= max_index ) - { - fill( next_index - max_index); - } + unsigned int next_index = current + i - 1; + unsigned int max_index = (lookahead.size() == 0) ? 0 : (lookahead.size() - 1); + if( next_index >= max_index ) + { + fill( next_index - max_index); + } } void BTParser::fill(unsigned int n) { - unsigned int i = 0; - for (i = 0; i <= n; i++) - { - lookahead.push_back( lexer->next() ); - } + unsigned int i = 0; + for (i = 0; i <= n; i++) + { + lookahead.push_back( lexer->next() ); + } } void BTParser::match(TokenType_T type) { - if( lookaheadType(1) == type ) - { - consume(); - } - else - { - Token* tok = lookaheadToken(1); - ostringstream oss; - oss << "Expected token type. Expected " << type << ", received " << tok->type() << "."; - Exception ex( tok->line(), tok->column() ); - ex.setMessage(oss.str()); - } + if( lookaheadType(1) == type ) + { + consume(); + } + else + { + Token* tok = lookaheadToken(1); + ostringstream oss; + oss << "Expected token type. Expected " << type << ", received " << tok->type() << "."; + Exception ex( tok->line(), tok->column() ); + ex.setMessage(oss.str()); + } } Token* BTParser::lookaheadToken(unsigned int i) { - sync(i); - return lookahead.at( current + i - 1 ); + sync(i); + return lookahead.at( current + i - 1 ); } TokenType_T BTParser::lookaheadType(unsigned int i) { - Token* tok = lookaheadToken(i); - return (tok != NULL) ? tok->type() : EOF; + Token* tok = lookaheadToken(i); + return (tok != NULL) ? tok->type() : EOF; } unsigned int BTParser::mark(void) { - markers.push_back(current); - return current; + markers.push_back(current); + return current; } void BTParser::release(void) { - unsigned int marker = markers.back(); - markers.pop_back(); - seek(marker); + unsigned int marker = markers.back(); + markers.pop_back(); + seek(marker); } void BTParser::seek(unsigned int index) { - current = index; + current = index; } bool BTParser::isSpeculating(void) { - return (markers.size() > 0); + return (markers.size() > 0); } diff --git a/source/parse_utils/parser/btparser/btparser.h b/source/parse_utils/parser/btparser/btparser.h index 3b032b4..ea77c39 100644 --- a/source/parse_utils/parser/btparser/btparser.h +++ b/source/parse_utils/parser/btparser/btparser.h @@ -3,37 +3,37 @@ #include #include -#include "parser.h" -#include "lexer.h" +#include "iparser.h" +#include "ilexer.h" #include "ast.h" -class BTParser : public Parser +class BTParser : public IParser { - private: - Lexer* lexer; - unsigned int current; - std::vector markers; - std::vector lookahead; - public: - BTParser(Lexer* lxer); - ~BTParser(); + private: + ILexer* lexer; + unsigned int current; + std::vector markers; + std::vector lookahead; + public: + BTParser(ILexer* lxer); + ~BTParser(); - void setInput(char* in); - void setInput(string& in); - void setInput(istream* in); + void setInput(char* in); + void setInput(string& in); + void setInput(istream* in); - void consume(void); - void sync(unsigned int i); - void fill(unsigned int n); - void match(TokenType_T type); - Token* lookaheadToken(unsigned int i); - TokenType_T lookaheadType(unsigned int i); - unsigned int mark(void); - void release(void); - void seek(unsigned int index); - bool isSpeculating(void); + void consume(void); + void sync(unsigned int i); + void fill(unsigned int n); + void match(TokenType_T type); + Token* lookaheadToken(unsigned int i); + TokenType_T lookaheadType(unsigned int i); + unsigned int mark(void); + void release(void); + void seek(unsigned int index); + bool isSpeculating(void); - virtual void parse(void) = 0; + virtual void parse(void) = 0; }; #endif diff --git a/source/parse_utils/parser/parser.cpp b/source/parse_utils/parser/iparser.cpp similarity index 78% rename from source/parse_utils/parser/parser.cpp rename to source/parse_utils/parser/iparser.cpp index a7eee89..82829b7 100644 --- a/source/parse_utils/parser/parser.cpp +++ b/source/parse_utils/parser/iparser.cpp @@ -18,38 +18,39 @@ * Includes and Prototypes *****************************************************************************/ #include -#include "parser.h" +#include "iparser.h" +#include "cork.h" using namespace std; /****************************************************************************** * Public Functions *****************************************************************************/ -Parser::Parser() : input(NULL) +IParser::IParser() : input(NULL) { } -Parser::~Parser() +IParser::~IParser() { - if(input != NULL) - { - delete input; - } + if(input != NULL) + { + delete input; + } } -void Parser::setInput(char* in) +void IParser::setInput(char* in) { - input = new istringstream( string( in ) ); + input = _new istringstream( string( in ) ); } -void Parser::setInput(string& in) +void IParser::setInput(string& in) { - input = new istringstream( in ); + input = _new istringstream( in ); } -void Parser::setInput(istream* in) +void IParser::setInput(istream* in) { - input = in; + input = in; } diff --git a/source/parse_utils/parser/parser.h b/source/parse_utils/parser/iparser.h similarity index 78% rename from source/parse_utils/parser/parser.h rename to source/parse_utils/parser/iparser.h index 929334f..0c4d86c 100644 --- a/source/parse_utils/parser/parser.h +++ b/source/parse_utils/parser/iparser.h @@ -20,21 +20,21 @@ #include #include #include "ast.h" -#include "visitor.h" +#include "ivisitor.h" using namespace std; -class Parser { - private: - istream* input; - public: - Parser(); - virtual ~Parser(); - virtual void parse() = 0; +class IParser { + private: + istream* input; + public: + IParser(); + virtual ~IParser(); + virtual void parse() = 0; - void setInput(char* in); - void setInput(string& in); - void setInput(istream* in); + void setInput(char* in); + void setInput(string& in); + void setInput(istream* in); }; #endif diff --git a/source/parse_utils/parser/llkparser/llkparser.cpp b/source/parse_utils/parser/llkparser/llkparser.cpp index db86ece..3568726 100644 --- a/source/parse_utils/parser/llkparser/llkparser.cpp +++ b/source/parse_utils/parser/llkparser/llkparser.cpp @@ -1,101 +1,102 @@ #include "llkparser.h" #include "exception.h" +#include "cork.h" -LLKParser::LLKParser(int k_val, Lexer* lxer) : k(k_val), next(0), lexer(lxer) +LLKParser::LLKParser(int k_val, ILexer* lxer) : k(k_val), next(0), lexer(lxer) { - if ( lexer != NULL ) - { - lookahead = new Token*[k]; - } - else - { - throw std::exception(); - } + if ( lexer != NULL ) + { + lookahead = new Token*[k]; + } + else + { + throw std::exception(); + } } LLKParser::~LLKParser() { - if(lexer != NULL) - { - delete lexer; - // Input stream was deleted with th elexer so null it out - Parser::setInput((istream*)NULL); - } - if (lookahead != NULL) - { - delete[] lookahead; - } + if(lexer != NULL) + { + delete lexer; + // Input stream was deleted with th elexer so null it out + IParser::setInput((istream*)NULL); + } + if (lookahead != NULL) + { + delete[] lookahead; + } } void LLKParser::setInput(char* in) { - Parser::setInput(in); - lexer->setInput(in); - for (int i = 0; i < k; i++) - { - consume(); - } + IParser::setInput(in); + lexer->setInput(in); + for (int i = 0; i < k; i++) + { + consume(); + } } void LLKParser::setInput(string& in) { - Parser::setInput(in); - lexer->setInput(in); - for (int i = 0; i < k; i++) - { - consume(); - } + IParser::setInput(in); + lexer->setInput(in); + for (int i = 0; i < k; i++) + { + consume(); + } } void LLKParser::setInput(istream* in) { - Parser::setInput(in); - lexer->setInput(in); - for (int i = 0; i < k; i++) - { - consume(); - } + IParser::setInput(in); + lexer->setInput(in); + for (int i = 0; i < k; i++) + { + consume(); + } } void LLKParser::consume(void) { - if ( lookahead != NULL ) - { - lookahead[next] = lexer->next(); - next = (next + 1) % k; - } + if ( lookahead != NULL ) + { + lookahead[next] = lexer->next(); + next = (next + 1) % k; + } } void LLKParser::match(TokenType_T type) { - if( lookaheadType(1) == type ) - { - consume(); - } - else - { - throw std::exception(); - } + if( lookaheadType(1) == type ) + { + consume(); + } + else + { + throw std::exception(); + } } Token* LLKParser::lookaheadToken(int i) { - Token* ret = NULL; - if( lookahead != NULL ) - { - ret = lookahead[(next + i - 1) % k]; - } - return ret; + Token* ret = NULL; + if( lookahead != NULL ) + { + ret = lookahead[(next + i - 1) % k]; + } + return ret; } TokenType_T LLKParser::lookaheadType(int i) { - TokenType_T ret = EOF; - if( lookahead != NULL ) - { - Token* tok = lookaheadToken(i); - ret = (tok != NULL) ? tok->type() : EOF; - } - return ret; + TokenType_T ret = EOF; + if( lookahead != NULL ) + { + Token* tok = lookaheadToken(i); + ret = (tok != NULL) ? tok->type() : EOF; + } + return ret; } diff --git a/source/parse_utils/parser/llkparser/llkparser.h b/source/parse_utils/parser/llkparser/llkparser.h index ab1fe51..2e403b7 100644 --- a/source/parse_utils/parser/llkparser/llkparser.h +++ b/source/parse_utils/parser/llkparser/llkparser.h @@ -2,30 +2,30 @@ #define LLK_PARSER_H #include -#include "parser.h" -#include "lexer.h" +#include "iparser.h" +#include "ilexer.h" #include "ast.h" -class LLKParser : public Parser +class LLKParser : public IParser { - private: - int k; - int next; - Lexer* lexer; - Token** lookahead; - public: - LLKParser(int k_val, Lexer* lxer); - ~LLKParser(); + private: + int k; + int next; + ILexer* lexer; + Token** lookahead; + public: + LLKParser(int k_val, ILexer* lxer); + ~LLKParser(); - void setInput(char* in); - void setInput(string& in); - void setInput(istream* in); + void setInput(char* in); + void setInput(string& in); + void setInput(istream* in); - void consume(void); - void match(TokenType_T type); - Token* lookaheadToken(int i); - TokenType_T lookaheadType(int i); - virtual void parse(void) = 0; + void consume(void); + void match(TokenType_T type); + Token* lookaheadToken(int i); + TokenType_T lookaheadType(int i); + virtual void parse(void) = 0; }; #endif diff --git a/source/parse_utils/visitor/ivisitor.cpp b/source/parse_utils/visitor/ivisitor.cpp new file mode 100644 index 0000000..ef4185c --- /dev/null +++ b/source/parse_utils/visitor/ivisitor.cpp @@ -0,0 +1,35 @@ +#include "ivisitor.h" +#include + +using namespace std; + +void IVisitor::visit(AST* cur, int depth) +{ + list* children; + list::iterator it; + + // If we are just starting then use the global tree + if(cur == NULL) cur = ast; + + // Execute or pre-walk actions + if(depth == 0) beforeVisit( cur, depth ); + + // Setup our locals + children = cur->children(); + it = children->begin(); + + // Visit the tree + beforeChildren(cur,depth); + depth++; + for(; it != children->end(); it++) + { + beforeChild( *it, depth ); + visit( *it, depth ); + afterChild( *it, depth ); + } + afterChildren(cur,depth); + + // Execute our post-walk actions + if(depth == 1) afterVisit( cur, depth ); +} + diff --git a/source/parse_utils/visitor/ivisitor.h b/source/parse_utils/visitor/ivisitor.h new file mode 100644 index 0000000..4d4cb2e --- /dev/null +++ b/source/parse_utils/visitor/ivisitor.h @@ -0,0 +1,29 @@ +#ifndef TRANSLATOR_H +#define TRANSLATOR_H + +#include "ast.h" +#include +#include + +class IVisitor { + protected: + AST* ast; + public: + IVisitor(AST* tree) : ast(tree) {}; + ~IVisitor() { delete ast; } + void visit(AST* cur = NULL, int depth = 0); + private: + virtual void beforeVisit(AST* cur, int depth) = 0; + virtual void afterVisit(AST* cur, int depth) = 0; + virtual void beforeChildren(AST* cur, int depth) = 0; + virtual void afterChildren(AST* cur, int depth) = 0; + virtual void beforeChild(AST* cur, int depth) = 0; + virtual void afterChild(AST* cur, int depth) = 0; +}; + +class IVisitorFactory { + public: + virtual IVisitor* createIVisitor(AST* root) = 0; +}; + +#endif diff --git a/source/parse_utils/visitor/visitor.cpp b/source/parse_utils/visitor/visitor.cpp deleted file mode 100644 index 71c3ccf..0000000 --- a/source/parse_utils/visitor/visitor.cpp +++ /dev/null @@ -1,35 +0,0 @@ -#include "visitor.h" -#include - -using namespace std; - -void Visitor::visit(AST* cur, int depth) -{ - list* children; - list::iterator it; - - // If we are just starting then use the global tree - if(cur == NULL) cur = ast; - - // Execute or pre-walk actions - if(depth == 0) beforeVisit( cur, depth ); - - // Setup our locals - children = cur->children(); - it = children->begin(); - - // Visit the tree - beforeChildren(cur,depth); - depth++; - for(; it != children->end(); it++) - { - beforeChild( *it, depth ); - visit( *it, depth ); - afterChild( *it, depth ); - } - afterChildren(cur,depth); - - // Execute our post-walk actions - if(depth == 1) afterVisit( cur, depth ); -} - diff --git a/source/parse_utils/visitor/visitor.h b/source/parse_utils/visitor/visitor.h deleted file mode 100644 index b93359e..0000000 --- a/source/parse_utils/visitor/visitor.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef TRANSLATOR_H -#define TRANSLATOR_H - -#include "ast.h" -#include -#include - -class Visitor { - protected: - AST* ast; - public: - Visitor(AST* tree) : ast(tree) {}; - ~Visitor() { delete ast; } - void visit(AST* cur = NULL, int depth = 0); - private: - virtual void beforeVisit(AST* cur, int depth) = 0; - virtual void afterVisit(AST* cur, int depth) = 0; - virtual void beforeChildren(AST* cur, int depth) = 0; - virtual void afterChildren(AST* cur, int depth) = 0; - virtual void beforeChild(AST* cur, int depth) = 0; - virtual void afterChild(AST* cur, int depth) = 0; -}; - -class VisitorFactory { - public: - virtual Visitor* createVisitor(AST* root) = 0; -}; - -#endif diff --git a/source/visitors/macroapplication/macroapplication.cpp b/source/visitors/macroapplication/macroapplication.cpp index 4cdbf04..5eefc0a 100644 --- a/source/visitors/macroapplication/macroapplication.cpp +++ b/source/visitors/macroapplication/macroapplication.cpp @@ -1,26 +1,26 @@ -#include "MacroApplication.h" +#include "macroapplication.h" #include "dllexer.h" using namespace std; Param* MacroApplication::getParamByName(std::string name) { - Param* ret = NULL; - std::list::iterator it = macro_params.begin(); - for(; it != macro_params.end(); it++) - { - if( (*it)->name().compare( name ) == 0) - { - ret = *it; - break; - } - } - return ret; + Param* ret = NULL; + std::list::iterator it = macro_params.begin(); + for(; it != macro_params.end(); it++) + { + if( (*it)->name().compare( name ) == 0) + { + ret = *it; + break; + } + } + return ret; } AST* MacroApplication::getAST(void) { - return mod_ast; + return mod_ast; } void MacroApplication::beforeVisit(AST* cur, int depth) @@ -33,14 +33,14 @@ void MacroApplication::afterVisit(AST* cur, int depth) void MacroApplication::beforeChildren(AST* cur, int depth) { - if(cur->type() == ID) - { - Param* param = getParamByName( cur->text() ); - if( param != NULL ) - { - (*cur) = *(param->value()); - } - } + if(cur->type() == ID) + { + Param* param = getParamByName( cur->text() ); + if( param != NULL ) + { + (*cur) = *(param->value()); + } + } } void MacroApplication::afterChildren(AST* cur, int depth) diff --git a/source/visitors/macroapplication/macroapplication.h b/source/visitors/macroapplication/macroapplication.h index 0c43449..dac41c9 100644 --- a/source/visitors/macroapplication/macroapplication.h +++ b/source/visitors/macroapplication/macroapplication.h @@ -1,27 +1,27 @@ #ifndef MacroApplication_H -#define MacroApplication_H +#define MacroApplication_H -#include "visitor.h" +#include "ivisitor.h" #include #include #include "param.h" -class MacroApplication : public Visitor { - protected: - AST* mod_ast; - ostringstream stream; - std::list macro_params; - public: - MacroApplication(AST* root,std::list& params) : Visitor(root), mod_ast(root), macro_params(params) {}; - Param* getParamByName(std::string name); - AST* getAST(void); - private: - void beforeVisit(AST* cur, int depth); - void afterVisit(AST* cur, int depth); - void beforeChildren(AST* cur, int depth); - void afterChildren(AST* cur, int depth); - void beforeChild(AST* cur, int depth); - void afterChild(AST* cur, int depth); +class MacroApplication : public IVisitor { + protected: + AST* mod_ast; + std::ostringstream stream; + std::list macro_params; + public: + MacroApplication(AST* root,std::list& params) : IVisitor(root), mod_ast(root), macro_params(params) {}; + Param* getParamByName(std::string name); + AST* getAST(void); + private: + void beforeVisit(AST* cur, int depth); + void afterVisit(AST* cur, int depth); + void beforeChildren(AST* cur, int depth); + void afterChildren(AST* cur, int depth); + void beforeChild(AST* cur, int depth); + void afterChild(AST* cur, int depth); }; #endif diff --git a/source/visitors/scheme/scheme.cpp b/source/visitors/scheme/scheme.cpp index 8d6e259..9f28fcf 100644 --- a/source/visitors/scheme/scheme.cpp +++ b/source/visitors/scheme/scheme.cpp @@ -3,88 +3,88 @@ using namespace std; -Scheme::Scheme(AST* root) : Visitor(root) { - ifstream input("res/environment.scm"); - if (input.is_open()) - { - while ( input.good() ) - { - string line; - getline(input,line); - stream << line << endl; - } +Scheme::Scheme(AST* root) : IVisitor(root) { + ifstream input("res/environment.scm"); + if (input.is_open()) + { + while ( input.good() ) + { + string line; + getline(input,line); + stream << line << endl; + } } input.close(); } string Scheme::str() { - return stream.str(); + return stream.str(); } string Scheme::typeToString(ASTNodeType type) { - ostringstream ret; + ostringstream ret; - switch (type) - { - case ID: - ret << "ID "; break; - case NUM: - ret << "NUM "; break; - case CHAR: - ret << "CHAR "; break; - case ADD: - ret << "ADD "; break; - case SUB: - ret << "SUB "; break; - case MUL: - ret << "MUL "; break; - case DIV: - ret << "DIV "; break; - case AND: - ret << "and "; break; - case OR: - ret << "or "; break; - case NOT: - ret << "NOT "; break; - case EQ: - ret << "EQ "; break; - case NE: - ret << "NE "; break; - case LT: - ret << "LT "; break; - case GT: - ret << "GT "; break; - case LTE: - ret << "LTE "; break; - case GTE: - ret << "GTE "; break; - case MACRO: - ret << "MACRO "; break; - case ASSIGN: - ret << "define "; break; - case PROGRAM: - ret << "begin "; break; - case VECTOR: - ret << "VECTOR "; break; - case LIST: - ret << "LIST "; break; - case BLOCK: - ret << "begin "; break; - case FUNC: - ret << "lambda "; break; - case FN_CALL: - ret << "FN_CALL "; break; - case ARRY_IDX: - ret << "ARRY_IDX "; break; - case PARAMS: - break; - default: - ret << type; break; - } + switch (type) + { + case ID: + ret << "ID "; break; + case NUM: + ret << "NUM "; break; + case CHAR: + ret << "CHAR "; break; + case ADD: + ret << "ADD "; break; + case SUB: + ret << "SUB "; break; + case MUL: + ret << "MUL "; break; + case DIV: + ret << "DIV "; break; + case AND: + ret << "and "; break; + case OR: + ret << "or "; break; + case NOT: + ret << "NOT "; break; + case EQ: + ret << "EQ "; break; + case NE: + ret << "NE "; break; + case LT: + ret << "LT "; break; + case GT: + ret << "GT "; break; + case LTE: + ret << "LTE "; break; + case GTE: + ret << "GTE "; break; + case MACRO: + ret << "MACRO "; break; + case ASSIGN: + ret << "define "; break; + case PROGRAM: + ret << "begin "; break; + case VECTOR: + ret << "VECTOR "; break; + case LIST: + ret << "LIST "; break; + case BLOCK: + ret << "begin "; break; + case FUNC: + ret << "lambda "; break; + case FN_CALL: + ret << "FN_CALL "; break; + case ARRY_IDX: + ret << "ARRY_IDX "; break; + case PARAMS: + break; + default: + ret << type; break; + } - return ret.str(); + return ret.str(); } void Scheme::beforeVisit(AST* cur, int depth) @@ -93,36 +93,36 @@ void Scheme::beforeVisit(AST* cur, int depth) void Scheme::afterVisit(AST* cur, int depth) { - stream << endl; + stream << endl; } void Scheme::beforeChildren(AST* cur, int depth) { - if( isDatatype( cur->type() ) ) - { - printDatatype( cur ); - } - else - { - stream << "(" << typeToString( cur->type() ) << cur->text(); - } + if( isDatatype( cur->type() ) ) + { + printDatatype( cur ); + } + else + { + stream << "(" << typeToString( cur->type() ) << cur->text(); + } } void Scheme::afterChildren(AST* cur, int depth) { - if( !isDatatype( cur->type() ) ) - { - stream << ")"; - } + if( !isDatatype( cur->type() ) ) + { + stream << ")"; + } } void Scheme::beforeChild(AST* cur, int depth) { - stream << endl; - for(int i = 0; i< depth; i++) - { - stream << " "; - } + stream << endl; + for(int i = 0; i< depth; i++) + { + stream << " "; + } } void Scheme::afterChild(AST* cur, int depth) @@ -131,60 +131,60 @@ void Scheme::afterChild(AST* cur, int depth) bool Scheme::isDatatype(ASTNodeType type) { - bool ret = false; - switch(type) - { - case ID: - case NUM: - case CHAR: - case STRING: - case SYMBOL: - ret = true; - break; - default: - break; - } - return ret; + bool ret = false; + switch(type) + { + case ID: + case NUM: + case CHAR: + case STRING: + case SYMBOL: + ret = true; + break; + default: + break; + } + return ret; } void Scheme::printDatatype(AST* cur) { - switch(cur->type()) - { - case ID: - stream << "dl/" << cur->text(); - break; - case NUM: - stream << cur->text(); - break; - case CHAR: - charToString( cur->text() ); - break; - case STRING: - stream << '"' << cur->text() << '"'; - break; - case SYMBOL: - stream << '\'' << cur->text(); - break; - default: - break; - } + switch(cur->type()) + { + case ID: + stream << "dl/" << cur->text(); + break; + case NUM: + stream << cur->text(); + break; + case CHAR: + charToString( cur->text() ); + break; + case STRING: + stream << '"' << cur->text() << '"'; + break; + case SYMBOL: + stream << '\'' << cur->text(); + break; + default: + break; + } } void Scheme::charToString(string ch) { - switch(ch.at(0)) - { - case ' ': - stream << "#\\space"; - break; - case '\n': - stream << "#\\newline"; - break; - case '\r': - stream << "#\\return"; - break; - default: - stream << "#\\" << ch; - } + switch(ch.at(0)) + { + case ' ': + stream << "#\\space"; + break; + case '\n': + stream << "#\\newline"; + break; + case '\r': + stream << "#\\return"; + break; + default: + stream << "#\\" << ch; + } } diff --git a/source/visitors/scheme/scheme.h b/source/visitors/scheme/scheme.h index e477f4c..4aaa47a 100644 --- a/source/visitors/scheme/scheme.h +++ b/source/visitors/scheme/scheme.h @@ -1,28 +1,28 @@ #ifndef Scheme_H -#define Scheme_H +#define Scheme_H #include #include -#include "visitor.h" +#include "ivisitor.h" #include "dllexer.h" -class Scheme : public Visitor { - protected: - ostringstream stream; - public: - Scheme(AST* root); - string str(); - string typeToString(ASTNodeType type); - bool isDatatype(ASTNodeType type); - void printDatatype(AST* cur); - void charToString(string ch); - private: - void beforeVisit(AST* cur, int depth); - void afterVisit(AST* cur, int depth); - void beforeChildren(AST* cur, int depth); - void afterChildren(AST* cur, int depth); - void beforeChild(AST* cur, int depth); - void afterChild(AST* cur, int depth); +class Scheme : public IVisitor { + protected: + ostringstream stream; + public: + Scheme(AST* root); + string str(); + string typeToString(ASTNodeType type); + bool isDatatype(ASTNodeType type); + void printDatatype(AST* cur); + void charToString(string ch); + private: + void beforeVisit(AST* cur, int depth); + void afterVisit(AST* cur, int depth); + void beforeChildren(AST* cur, int depth); + void afterChildren(AST* cur, int depth); + void beforeChild(AST* cur, int depth); + void afterChild(AST* cur, int depth); }; #endif diff --git a/source/visitors/sexp/sexp.h b/source/visitors/sexp/sexp.h index 16cf992..415fa18 100644 --- a/source/visitors/sexp/sexp.h +++ b/source/visitors/sexp/sexp.h @@ -1,23 +1,23 @@ #ifndef SEXP_H -#define SEXP_H +#define SEXP_H -#include "visitor.h" +#include "ivisitor.h" #include #include -class SEXP : public Visitor { - protected: - ostringstream stream; - public: - SEXP(AST* root) : Visitor(root) {}; - string str(); - private: - void beforeVisit(AST* cur, int depth); - void afterVisit(AST* cur, int depth); - void beforeChildren(AST* cur, int depth); - void afterChildren(AST* cur, int depth); - void beforeChild(AST* cur, int depth); - void afterChild(AST* cur, int depth); +class SEXP : public IVisitor { + protected: + ostringstream stream; + public: + SEXP(AST* root) : IVisitor(root) {}; + string str(); + private: + void beforeVisit(AST* cur, int depth); + void afterVisit(AST* cur, int depth); + void beforeChildren(AST* cur, int depth); + void afterChildren(AST* cur, int depth); + void beforeChild(AST* cur, int depth); + void afterChild(AST* cur, int depth); }; #endif diff --git a/tools/rake_utils/buildconfig.rb b/tools/rake_utils/buildconfig.rb deleted file mode 100644 index 6abfe57..0000000 --- a/tools/rake_utils/buildconfig.rb +++ /dev/null @@ -1,44 +0,0 @@ -require "#{File.expand_path(File.dirname(__FILE__))}/plainconfig" -require 'rake' -require 'rake/clean' - -class BuildConfig < PlainConfig - def initialize(config) - super(config) - - # Register output directories - register_directory("#{@settings[:output_dir]}/bin") - register_directory("#{@settings[:output_dir]}/obj") - register_directory("#{@settings[:output_dir]}/test") - - # set output name - @settings[:bin_name] = "#{@settings[:output_dir]}/bin/#{@settings[:name]}#{get_bin_extension()}" - CLEAN.include(@settings[:bin_name]) - - # Create object file list - @settings[:object_source_lookup] = {} - @settings[:object_files] = [] - @settings[:source_files].each{ |f| - obj_file = @settings[:output_dir] + '/obj/' + File.basename(f).ext('o') - CLEAN.include(obj_file) - @settings[:object_files].push( obj_file ) - @settings[:object_source_lookup][obj_file] = f - } - end - - def binary_name() - return @settings[:bin_name] - end - - def objects() - return @settings[:object_files] - end - - def source_from_obj(obj) - return @settings[:object_source_lookup][obj] - end - - def obj_src_lookup() - return lambda{|obj| @settings[:object_source_lookup][obj]} - end -end diff --git a/tools/rake_utils/plainconfig.rb b/tools/rake_utils/plainconfig.rb deleted file mode 100644 index aeebaaa..0000000 --- a/tools/rake_utils/plainconfig.rb +++ /dev/null @@ -1,96 +0,0 @@ -require 'pp' - -class PlainConfig - def initialize(config) - @settings = defaults() - @settings.merge!(config) - - # Process Source paths - @settings[:source_files] = make_file_list( @settings[:source_files] ) - - # Process Include paths - @settings[:include_dirs] = make_file_list( @settings[:include_dirs] ) - @settings[:include_dirs] = make_option_list( '-I', @settings[:include_dirs] ) - - # Process compiler options - @settings[:compiler_options] = make_option_list('',@settings[:compiler_options]) - - # Process linker options - @settings[:linker_options] = make_option_list('',@settings[:linker_options]) - - # Process preprocessor defines - @settings[:preprocessor_defines] = make_option_list('-D',@settings[:preprocessor_defines]) - end - - def defaults() - return { - :name => 'binary', - :output_dir => 'build', - - :compiler_bin => 'c++', - :compiler_options => ['-c'], - :preprocessor_defines => [], - - :linker_bin => 'c++', - :linker_options => [], - - :source_files => [ 'source/*.c*' ], - :include_dirs => [ 'source/**/' ], - :directories => [] - } - end - - def to_s - pp @settings - end - - def get_bin_extension() - if ENV['OS'] == 'Windows_NT' then - return '.exe' - else - return '' - end - end - - def make_option_list(prefix,list) - if list != nil then - return list.collect{|opt| "#{prefix}#{opt} "} - else - return list - end - end - - def make_file_list(patt_list) - file_list = [] - patt_list.each {|f| - file_list.concat( FileList[f] ) - } - return file_list - end - - def register_directory(dir_name) - @settings[:directories].push(dir_name) - directory dir_name - CLOBBER.include(dir_name) - end - - def directories() - return @settings[:directories] - end - - def compile(input,output) - config = @settings - sh "#{config[:compiler_bin]} #{config[:compiler_options]} #{config[:preprocessor_defines]} #{config[:include_dirs]} -o #{output} #{input}" - end - - def link(*args) - config = @settings - if args.size == 2 then - file_list = args[0] - output = args[1] - sh "#{config[:linker_bin]} #{config[:linker_options]} -o #{output} #{file_list.collect{|x| x + ' '}}" - else - sh "#{config[:linker_bin]} #{config[:linker_options]} -o #{config[:bin_name]} #{config[:object_files].collect{|x| x + ' '}}" - end - end -end diff --git a/tools/rake_utils/testconfig.rb b/tools/rake_utils/testconfig.rb deleted file mode 100644 index 2806d37..0000000 --- a/tools/rake_utils/testconfig.rb +++ /dev/null @@ -1,82 +0,0 @@ -require "#{File.expand_path(File.dirname(__FILE__))}/plainconfig" -require 'rake' -require 'rake/clean' - -class TestConfig < PlainConfig - def initialize(config) - super(config) - - # Register test output directory - register_directory("#{@settings[:output_dir]}/test") - - # Process test paths - @settings[:test_files] = make_file_list( @settings[:test_files] ) - - # Create source to runner lookup table - @settings[:src_test_lookup] = {} - @settings[:test_files].each{ |test| - out_dir = "#{@settings[:output_dir]}/test" - runner = "#{out_dir}/#{File.basename(test).ext('')}_runner.cpp" - @settings[:src_test_lookup][runner] = test - @settings[:runners].push( runner.ext(get_bin_extension()) ) - } - end - - def defaults() - defs = super() - defs.merge!({ - :test_gen_bin => 'python tools/cxxtest/bin/cxxtestgen', - :test_gen_options => ['--error-printer'], - :output_dir => 'build', - :test_files => ['tests/source/**.h'], - :include_dirs => [ '.','tests/**/', 'source/**/', 'tools/cxxtest' ], - :runners => [] - }) - return defs - end - - def directories() - dir_list = [ "#{@settings[:output_dir]}/test" ] - directory dir_list[0] - CLOBBER.include(dir_list[0]) - return dir_list - end - - def runners() - return @settings[:runners] - end - - def bin_obj_lookup() - return lambda{|bin| bin.ext('.o')} - end - - def obj_src_lookup() - return lambda{|obj| obj.ext('.cpp')} - end - - def src_test_lookup() - return lambda{|src| @settings[:src_test_lookup][src] } - end - - def generate_test_runner(input,output) - sh "#{@settings[:test_gen_bin]} #{@settings[:test_gen_options]} -o #{output} #{input}" - end - - def run_all_test_runners() - succeeded = true - puts '' - puts '------------------' - puts ' Unit Tests' - puts '------------------' - puts '' - @settings[:runners].each{|runner| - status = system(runner) - succeeded = (succeeded and status) - puts '' - } - if not succeeded then - abort('Error: There are unit test failures') - end - end -end - -- 2.49.0