From: Mike D. Lowis Date: Thu, 10 May 2012 20:30:45 +0000 (-0400) Subject: Created macro processing class to register new macros and expand macro usages on... X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=1f78815833443fa59dcea311652602f99428df61;p=archive%2Fdlang.git Created macro processing class to register new macros and expand macro usages on the fly --- diff --git a/example.dl b/example.dl index 6bc0e7d..70fe059 100644 --- a/example.dl +++ b/example.dl @@ -11,53 +11,52 @@ foo(1 2) foo(1 2 3) # Definition and assignment -#define foo 5 end -#set! foo 6 end +define foo 5 end +set! foo 6 end # Lambda expressions -#lambda () end -#lambda (a) end -#lambda (a b) end -#lambda (a b c) end -# -#lambda () -# foo() -#end -# -#lambda (a) -# foo(a) -#end -# -#lambda (a b) -# foo(a b) -#end -# -#lambda (a b c) -# foo(a b c) -#end +lambda () end +lambda (a) end +lambda (a b) end +lambda (a b c) end + +lambda () + foo(a) +end + +lambda (a) + foo(a) +end + +lambda (a b) + foo(a b) +end + +lambda (a b c) + foo(a b c) +end # Begin block -#begin end -# -#begin -# foo() -#end -# -#begin -# foo() -# bar() -#end +begin end + +begin + foo() +end + +begin + foo() + bar() +end # If statement -#if conditional -# if_branch -#else -# else_branch -#end -# -#if conditional -# if_branch -#end +if conditional + if_branch + else_branch +end + +if conditional + if_branch +end # Infix operator expression (1 add 1) @@ -66,12 +65,12 @@ foo(1 2 3) (1 - (1 + 1)) # Macros -#macro let (:= =) ; -# (a := b) -# define a b end -# (a = b) -# set! a b end -#end -# -#let foo := "bar" ; -#let foo = 5 ; +macro let (:= =) ; + (a := b) + define a b end + (a = b) + set! a b end +end + +let foo := "bar" end +let foo = 5 end diff --git a/source/dllexer/dllexer.cpp b/source/dllexer/dllexer.cpp index 8385b6b..8b1cbca 100644 --- a/source/dllexer/dllexer.cpp +++ b/source/dllexer/dllexer.cpp @@ -120,7 +120,7 @@ Token DLLexer::next(void) Id(ret); - if( escaped && (ret.text().compare( terminator_string ) == 0) ) + if( !escaped && (ret.text().compare( terminator_string ) == 0) ) { ret.type( TERM ); } diff --git a/source/dllexer/dllexer.h b/source/dllexer/dllexer.h index d68789c..27e7f8e 100644 --- a/source/dllexer/dllexer.h +++ b/source/dllexer/dllexer.h @@ -18,16 +18,17 @@ typedef enum TokenTypes EXP_LIST = 8, MACRO = 9, TRANSFORM = 10, - LPAR = 11, - RPAR = 12, - TERM = 13, + MACRO_APP = 11, + LPAR = 12, + RPAR = 13, + TERM = 14, // Datatypes - ID = 14, - NUM = 15, - CHAR = 16, - STRING = 17, - SYMBOL = 18, + ID = 15, + NUM = 16, + CHAR = 17, + STRING = 18, + SYMBOL = 19, } eTokenTypes; typedef struct { diff --git a/source/dlparser/dlparser.cpp b/source/dlparser/dlparser.cpp index e6d3403..8af9bdd 100644 --- a/source/dlparser/dlparser.cpp +++ b/source/dlparser/dlparser.cpp @@ -1,17 +1,18 @@ #include "dlparser.h" #include "exception.h" #include "common.h" +#include "macroprocessor.h" using namespace std; DLParser::DLParser() : BTParser() { - core_forms.insert( pair("define", DEFINE) ); - core_forms.insert( pair("set!", ASSIGN) ); - core_forms.insert( pair("lambda", LAMBDA) ); - core_forms.insert( pair("begin", BEGIN) ); - core_forms.insert( pair("if", IF) ); - core_forms.insert( pair("macro", MACRO) ); + core_forms["define"] = DEFINE; + core_forms["set!"] = ASSIGN; + core_forms["lambda"] = LAMBDA; + core_forms["begin"] = BEGIN; + core_forms["if"] = IF; + core_forms["macro"] = MACRO; } DLParser::~DLParser() @@ -20,17 +21,17 @@ DLParser::~DLParser() bool DLParser::isMacroName(void) { - return false; + return (macros.count( lookaheadToken(1).text() ) > 0); } bool DLParser::isCoreFormName(void) { - return false; + return (core_forms.count( lookaheadToken(1).text() ) > 0); } eTokenTypes DLParser::getCoreFormId(void) { - return (eTokenTypes)0; + return core_forms[ lookaheadToken(1).text() ]; } void DLParser::parse(void) @@ -87,6 +88,10 @@ AST* DLParser::Expression(void) ret = Application(); } + // Register any new macros and expand any existing macros + MacroProcessor processor( macros ); + processor.visit( ret ); + return ret; } @@ -105,16 +110,16 @@ AST* DLParser::CoreForm(void) break; case LAMBDA: - ret = new AST(LAMBDA, 2, IdList(), ExpList()); + ret = new AST(LAMBDA, 2, IdList(), ExpList(TERM)); break; case BEGIN: - ret = new AST(BEGIN, 1, ExpList()); + ret = new AST(BEGIN, 1, ExpList(TERM)); break; case IF: ret = new AST(IF, 2, Expression(), Expression()); - if(lookaheadType(1) != RPAR) + if(lookaheadType(1) != TERM) { ret->addChild( Expression() ); } @@ -159,6 +164,23 @@ AST* DLParser::Application(void) // Macro Expression if ( isMacroName() ) { + // Save current terminator + + // Register the new terminator + + // Consume the name + cout << "Macro Usage" << endl; + ret = new AST( MACRO_APP, 1, new AST( lookaheadToken(1) )); + consume(); + + // Consume the expressions + while( lookaheadType(1) != TERM ) + { + ret->addChild( Expression() ); + } + match(TERM); + + // Reset the terminator to its old value } // Traditional Function Application @@ -167,7 +189,7 @@ AST* DLParser::Application(void) ret = new AST( lookaheadToken(1) ); consume(); match(LPAR); - ret = new AST(APPLY, 2, ret, ExpList()); + ret = new AST(APPLY, 2, ret, ExpList(RPAR)); match(RPAR); } @@ -204,10 +226,10 @@ AST* DLParser::Literal(void) return ret; } -AST* DLParser::ExpList(void) +AST* DLParser::ExpList(eTokenTypes term) { AST* ret = new AST(EXP_LIST); - while(RPAR != lookaheadType(1)) + while(term != lookaheadType(1)) { ret->addChild( Expression() ); } diff --git a/source/dlparser/dlparser.h b/source/dlparser/dlparser.h index 2683d62..5e49310 100644 --- a/source/dlparser/dlparser.h +++ b/source/dlparser/dlparser.h @@ -30,7 +30,7 @@ class DLParser : public BTParser AST* CoreForm(void); AST* Application(void); AST* Literal(void); - AST* ExpList(void); + AST* ExpList(eTokenTypes term); AST* IdList(void); }; diff --git a/source/visitors/macroprocessor.cpp b/source/visitors/macroprocessor.cpp new file mode 100644 index 0000000..dc058e6 --- /dev/null +++ b/source/visitors/macroprocessor.cpp @@ -0,0 +1,38 @@ +#include "macroprocessor.h" + +MacroProcessor::MacroProcessor(std::set ¯os) : macro_registry(macros) +{ +} + +void MacroProcessor::beforeVisit(AST* cur, int depth) +{ +} + +void MacroProcessor::afterVisit(AST* cur, int depth) +{ +} + +void MacroProcessor::beforeChildren(AST* cur, int depth) +{ + if (cur->type() == MACRO_APP) + { + //expandMacro(cur); + } +} + +void MacroProcessor::afterChildren(AST* cur, int depth) +{ + if (cur->type() == MACRO) + { + macro_registry.insert( (*(cur->children()->begin()))->text() ); + } +} + +void MacroProcessor::beforeChild(AST* cur, int depth) +{ +} + +void MacroProcessor::afterChild(AST* cur, int depth) +{ +} + diff --git a/source/visitors/macroprocessor.h b/source/visitors/macroprocessor.h new file mode 100644 index 0000000..a9ba0bd --- /dev/null +++ b/source/visitors/macroprocessor.h @@ -0,0 +1,22 @@ +#ifndef MACRO_PROCESSOR_H +#define MACRO_PROCESSOR_H + +#include +#include "ivisitor.h" +#include "dllexer.h" + +class MacroProcessor : public IVisitor { + protected: + std::set& macro_registry; + public: + MacroProcessor(std::set& macros); + 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