#------------------------------------------------------------------------------
# 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' ],
})
#------------------------------------------------------------------------------
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
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
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
--- /dev/null
+#include "cork.h"
+
+#ifdef DETECT_MEM_LEAKS
+
+// We want to use the real malloc and free in this file
+#undef malloc
+#undef free
+
+#include <iostream>
+#include <exception> // for std::bad_alloc
+#include <cstdlib> // for malloc() and free()
+#include <string.h>
+
+// 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
--- /dev/null
+#ifndef CORK_H
+#define CORK_H
+
+#ifdef DETECT_MEM_LEAKS
+ #include <string>
+ 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
#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;
}
#ifndef DLLEXER_H
#define DLLEXER_H
-#include "lexer.h"
+#include "ilexer.h"
#include <sstream>
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);
};
#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<std::string,Macro*>(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<std::string,Macro*>(id->text(), macro) );
+
+ return _new AST(MACRO);
}
AST* DLParser::MacroExpansion(void)
{
- AST* ret = NULL;
- Macro* cur_macro = macros[ lookaheadToken(1)->text() ];
- list<Param*>::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<Param*>::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;
}
#include "macro.h"
#include "macroapplication.h"
+#include "cork.h"
+
+using namespace std;
Macro::Macro(AST* macro_def)
{
- list<AST*>::iterator it = macro_def->children()->begin();
-
- // Set Name
- macro_name = (*it++)->text();
+ list<AST*>::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<Param*>& 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<AST*>::iterator it = param_tree->children()->begin();
- for(; it != param_tree->children()->end(); it++)
- {
- macro_params.push_back( new Param( *it ) );
- }
+ list<AST*>::iterator it = param_tree->children()->begin();
+ for(; it != param_tree->children()->end(); it++)
+ {
+ macro_params.push_back( _new Param( *it ) );
+ }
}
class Macro
{
- private:
- std::string macro_name;
- std::list<Param*> macro_params;
- AST* macro_body;
+ private:
+ std::string macro_name;
+ std::list<Param*> 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<Param*>& params(void);
- AST* apply(void);
+ const std::string& name(void);
+ const std::list<Param*>& params(void);
+ AST* apply(void);
};
#endif
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;
+ }
}
#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
#include "dlparser.h"
#include "sexp.h"
#include "scheme.h"
+#include "cork.h"
using namespace std;
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] << " <filename>\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] << " <filename>\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;
}
+++ /dev/null
-#include "ast.h"
-#include <sstream>
-#include <string.h>
-#include <iostream>
-
-AST::AST(ASTNodeType type)
-{
- node_type = type;
- node_text = NULL;
- node_children = new list<AST*>();
-}
-
-AST::~AST()
-{
- list<AST*>::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::AST(ASTNodeType type, const std::string& text)
-{
- node_type = type;
- node_text = new string(text);
- node_children = new list<AST*>();
-}
-
-AST::AST(ASTNodeType type, int child_count, ...)
-{
- va_list arg_list;
- int i = 0;
- node_type = type;
- node_text = NULL;
- node_children = new list<AST*>();
- 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<AST*>::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*>* 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<AST*>::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;
-}
-
+++ /dev/null
-#ifndef AST_H
-#define AST_H
-
-#include <stdarg.h>
-#include <list>
-#include <string>
-
-using namespace std;
-
-typedef unsigned int ASTNodeType;
-
-class AST
-{
- protected:
- ASTNodeType node_type;
- string* node_text;
- list<AST*>* 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<AST*>* children(void);
- void addChild(AST* node);
- AST* clone(void);
-};
-
-#endif
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;
}
--- /dev/null
+#include <exception>
+#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;
+ }
+}
+
+
--- /dev/null
+#ifndef LEXER_H
+#define LEXER_H
+
+#include <iostream>
+#include <sstream>
+#include <cstdio>
+#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
+++ /dev/null
-#include <exception>
-#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;
- }
-}
-
-
+++ /dev/null
-#ifndef LEXER_H
-#define LEXER_H
-
-#include <iostream>
-#include <sstream>
-#include <cstdio>
-#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
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;
}
#ifndef TOKEN_H
-#define TOKEN_H
+#define TOKEN_H
#include <string>
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
--- /dev/null
+#include "ast.h"
+#include <sstream>
+#include <string.h>
+#include <iostream>
+#include "cork.h"
+
+AST::AST(ASTNodeType type)
+{
+ node_type = type;
+ node_text = "";
+ node_children = _new list<AST*>();
+}
+
+AST::AST(ASTNodeType type, const char* text)
+{
+ node_type = type;
+ node_text = string(text);
+ node_children = _new list<AST*>();
+}
+
+AST::AST(ASTNodeType type, std::string text)
+{
+ node_type = type;
+ node_text = text;
+ node_children = _new list<AST*>();
+}
+
+AST::AST(ASTNodeType type, int child_count, ...)
+{
+ va_list arg_list;
+ int i = 0;
+ node_type = type;
+ node_text = "";
+ node_children = _new list<AST*>();
+ 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<AST*>::iterator it = node_children->begin();
+ for(; it != node_children->end(); it++)
+ {
+ delete *(it);
+ }
+ delete node_children;
+}
+
+AST& AST::operator = (AST& rhs)
+{
+ list<AST*>::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*>* 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<AST*>::iterator it = node_children->begin();
+ for(; it != node_children->end(); it++)
+ {
+ new_clone->addChild( (*it)->clone() );
+ }
+ return new_clone;
+}
+
--- /dev/null
+#ifndef AST_H
+#define AST_H
+
+#include <stdarg.h>
+#include <list>
+#include <string>
+
+using namespace std;
+
+typedef unsigned int ASTNodeType;
+
+class AST
+{
+ protected:
+ ASTNodeType node_type;
+ string node_text;
+ list<AST*>* 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<AST*>* children(void);
+ void addChild(AST* node);
+ AST* clone(void);
+};
+
+#endif
-#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);
}
#include <exception>
#include <vector>
-#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<unsigned int> markers;
- std::vector<Token*> lookahead;
- public:
- BTParser(Lexer* lxer);
- ~BTParser();
+ private:
+ ILexer* lexer;
+ unsigned int current;
+ std::vector<unsigned int> markers;
+ std::vector<Token*> 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
* Includes and Prototypes
*****************************************************************************/
#include <stdio.h>
-#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;
}
#include <string>
#include <sstream>
#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
#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;
}
#define LLK_PARSER_H
#include <exception>
-#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
--- /dev/null
+#include "ivisitor.h"
+#include <list>
+
+using namespace std;
+
+void IVisitor::visit(AST* cur, int depth)
+{
+ list<AST*>* children;
+ list<AST*>::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 );
+}
+
--- /dev/null
+#ifndef TRANSLATOR_H
+#define TRANSLATOR_H
+
+#include "ast.h"
+#include <string>
+#include <iostream>
+
+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
+++ /dev/null
-#include "visitor.h"
-#include <list>
-
-using namespace std;
-
-void Visitor::visit(AST* cur, int depth)
-{
- list<AST*>* children;
- list<AST*>::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 );
-}
-
+++ /dev/null
-#ifndef TRANSLATOR_H
-#define TRANSLATOR_H
-
-#include "ast.h"
-#include <string>
-#include <iostream>
-
-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
-#include "MacroApplication.h"
+#include "macroapplication.h"
#include "dllexer.h"
using namespace std;
Param* MacroApplication::getParamByName(std::string name)
{
- Param* ret = NULL;
- std::list<Param*>::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<Param*>::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)
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)
#ifndef MacroApplication_H
-#define MacroApplication_H
+#define MacroApplication_H
-#include "visitor.h"
+#include "ivisitor.h"
#include <iostream>
#include <sstream>
#include "param.h"
-class MacroApplication : public Visitor {
- protected:
- AST* mod_ast;
- ostringstream stream;
- std::list<Param*> macro_params;
- public:
- MacroApplication(AST* root,std::list<Param*>& 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<Param*> macro_params;
+ public:
+ MacroApplication(AST* root,std::list<Param*>& 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
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)
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)
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;
+ }
}
#ifndef Scheme_H
-#define Scheme_H
+#define Scheme_H
#include <iostream>
#include <sstream>
-#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
#ifndef SEXP_H
-#define SEXP_H
+#define SEXP_H
-#include "visitor.h"
+#include "ivisitor.h"
#include <iostream>
#include <sstream>
-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
+++ /dev/null
-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
+++ /dev/null
-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
+++ /dev/null
-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
-