summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--macros.cpp35
-rw-r--r--parse/expr.cpp4
-rw-r--r--parse/lex.cpp27
-rw-r--r--parse/lex.hpp8
-rw-r--r--parse/tokentree.hpp1
5 files changed, 58 insertions, 17 deletions
diff --git a/macros.cpp b/macros.cpp
index 3561a911..e6750f49 100644
--- a/macros.cpp
+++ b/macros.cpp
@@ -3,6 +3,7 @@
#include "macros.hpp"
#include "parse/parseerror.hpp"
#include "parse/tokentree.hpp"
+#include "parse/common.hpp"
#define FOREACH(basetype, it, src) for(basetype::const_iterator it = src.begin(); it != src.end(); ++ it)
@@ -71,25 +72,35 @@ MacroExpander Macro_Invoke(const char* name, TokenTree input)
bool fail = false;
FOREACH(::std::vector<MacroPatEnt>, pat_it, rule_it->m_pattern)
{
+ Token tok;
+ TokenTree val;
const MacroPatEnt& pat = *pat_it;
- switch(pat.type)
+ try
{
- case MacroPatEnt::PAT_TOKEN:
- if( lex.getToken().type() != pat.tok.type() ) {
- fail = true;
+ switch(pat.type)
+ {
+ case MacroPatEnt::PAT_TOKEN:
+ GET_CHECK_TOK(tok, lex, pat.tok.type());
break;
+ case MacroPatEnt::PAT_EXPR:
+ val = Parse_TT_Expr(lex);
+ if(0)
+ case MacroPatEnt::PAT_STMT:
+ val = Parse_TT_Stmt(lex);
+ bound_tts.insert( std::make_pair(pat.name.c_str(), val) );
+ break;
+ default:
+ throw ParseError::Todo("macro pattern matching");
}
- break;
- case MacroPatEnt::PAT_EXPR:
- bound_tts.insert( std::make_pair(pat.name.c_str(), Parse_TT_Expr(lex)) );
- break;
- default:
- throw ParseError::Todo("macro pattern matching");
}
- if( fail )
+ catch(const ParseError::Base& e)
+ {
+ fail = true;
break;
+ }
}
- if( !fail ) {
+ if( !fail && lex.getToken().type() == TOK_EOF )
+ {
throw ParseError::Todo("Macro expansions");
}
}
diff --git a/parse/expr.cpp b/parse/expr.cpp
index cb3b80e7..b3c00247 100644
--- a/parse/expr.cpp
+++ b/parse/expr.cpp
@@ -452,6 +452,7 @@ TokenTree Parse_TT_Path(TokenStream& lex)
{
throw ParseError::Todo("TokenTree path");
}
+/// Parse a token tree path
TokenTree Parse_TT_Val(TokenStream& lex)
{
Token tok;
@@ -493,10 +494,11 @@ TokenTree Parse_TT_Val(TokenStream& lex)
break;
default:
// Oh, fail :(
- break;
+ throw ParseError::Unexpected(tok);
}
return TokenTree(ret);
}
+/// Parse a token tree expression
TokenTree Parse_TT_Expr(TokenStream& lex)
{
Token tok;
diff --git a/parse/lex.cpp b/parse/lex.cpp
index 99d787fb..e48cb9bb 100644
--- a/parse/lex.cpp
+++ b/parse/lex.cpp
@@ -541,6 +541,10 @@ const char* Token::typestr(enum eTokenType type)
return os;
}
+TokenTree::TokenTree()
+{
+
+}
TokenTree::TokenTree(Token tok)
{
@@ -551,15 +555,34 @@ TokenTree::TokenTree(::std::vector<TokenTree> subtrees)
}
TTStream::TTStream(const TokenTree& input_tt):
- m_input_tt(input_tt),
- m_cur_layer(&input_tt)
+ m_input_tt(input_tt)
{
+ m_stack.push_back( ::std::make_pair(0, &input_tt) );
}
TTStream::~TTStream()
{
}
Token TTStream::realGetToken()
{
+ while(m_stack.size() > 0)
+ {
+ // If current index is above TT size, go up
+ unsigned int& idx = m_stack.back().first;
+ const TokenTree& tree = *m_stack.back().second;
+ if(idx < tree.size())
+ {
+ if( tree[idx].size() == 0 ) {
+ idx ++;
+ return tree[idx-1].tok();
+ }
+ else {
+ m_stack.push_back( ::std::make_pair(0, &tree[idx] ) );
+ }
+ }
+ else {
+ m_stack.pop_back();
+ }
+ }
return Token(TOK_EOF);
}
diff --git a/parse/lex.hpp b/parse/lex.hpp
index 88aef072..e01a1cbf 100644
--- a/parse/lex.hpp
+++ b/parse/lex.hpp
@@ -200,16 +200,20 @@ private:
class TokenTree
{
public:
+ TokenTree();
TokenTree(Token tok);
TokenTree(::std::vector<TokenTree> subtrees);
+
+ const unsigned int size() const;
+ const TokenTree& operator[](unsigned int) const;
+ const Token& tok() const;
};
class TTStream:
public TokenStream
{
const TokenTree& m_input_tt;
- const TokenTree* m_cur_layer;
- ::std::vector<unsigned int> m_index_stack;
+ ::std::vector< ::std::pair<unsigned int, const TokenTree*> > m_stack;
public:
TTStream(const TokenTree& input_tt);
~TTStream();
diff --git a/parse/tokentree.hpp b/parse/tokentree.hpp
index 52871cce..4105897d 100644
--- a/parse/tokentree.hpp
+++ b/parse/tokentree.hpp
@@ -6,5 +6,6 @@
extern TokenTree Parse_TT(TokenStream& lex);
extern TokenTree Parse_TT_Expr(TokenStream& lex);
+extern TokenTree Parse_TT_Stmt(TokenStream& lex);
#endif // TOKENTREE_HPP_INCLUDED