summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/include/debug.hpp20
-rw-r--r--src/macros.cpp46
-rw-r--r--src/parse/expr.cpp136
-rw-r--r--src/parse/root.cpp8
-rw-r--r--src/parse/tokentree.hpp5
5 files changed, 163 insertions, 52 deletions
diff --git a/src/include/debug.hpp b/src/include/debug.hpp
index 4da63192..8376be07 100644
--- a/src/include/debug.hpp
+++ b/src/include/debug.hpp
@@ -26,23 +26,15 @@ struct RepeatLitStr
class TraceLog
{
- static unsigned int depth;
const char* m_tag;
public:
- TraceLog(const char* tag): m_tag(tag) { indent(); ::std::cout << ">> " << m_tag << ::std::endl; }
- ~TraceLog() { outdent(); ::std::cout << "<< " << m_tag << ::std::endl; }
-private:
- void indent()
- {
- for(unsigned int i = 0; i < depth; i ++)
- ::std::cout << " ";
- depth ++;
+ TraceLog(const char* tag): m_tag(tag) {
+ DEBUG(">> " << m_tag);
+ INDENT();
}
- void outdent()
- {
- depth --;
- for(unsigned int i = 0; i < depth; i ++)
- ::std::cout << " ";
+ ~TraceLog() {
+ UNINDENT();
+ DEBUG("<< " << m_tag);
}
};
#define TRACE_FUNCTION TraceLog _tf_(__func__)
diff --git a/src/macros.cpp b/src/macros.cpp
index 609726a6..71e0b85e 100644
--- a/src/macros.cpp
+++ b/src/macros.cpp
@@ -128,7 +128,7 @@ void Macro_HandlePattern(TTStream& lex, const MacroPatEnt& pat, bool rep, single
throw ParseError::Unexpected(lex, TOK_EOF);
else
lex.putback(tok);
- val = Parse_TT(lex);
+ val = Parse_TT(lex, false);
if(0)
case MacroPatEnt::PAT_EXPR:
val = Parse_TT_Expr(lex);
@@ -137,7 +137,7 @@ void Macro_HandlePattern(TTStream& lex, const MacroPatEnt& pat, bool rep, single
val = Parse_TT_Stmt(lex);
if(0)
case MacroPatEnt::PAT_PATH:
- val = Parse_TT_Path(lex);
+ val = Parse_TT_Path(lex, false); // non-expr mode
if(0)
case MacroPatEnt::PAT_BLOCK:
val = Parse_TT_Block(lex);
@@ -159,43 +159,49 @@ void Macro_HandlePattern(TTStream& lex, const MacroPatEnt& pat, bool rep, single
}
-MacroExpander Macro_InvokeInt(const MacroRules& rules, TokenTree input)
+MacroExpander Macro_InvokeInt(const char *name, const MacroRules& rules, TokenTree input)
{
+ TRACE_FUNCTION;
+
// 2. Check input token tree against possible variants
// 3. Bind names
// 4. Return expander
+ int i = 0;
for(const auto& rule : rules)
{
Token tok;
// Create token stream for input tree
TTStream lex(input);
- if(GET_TOK(tok, lex) == TOK_EOF) {
+ /*
+ enum eTokenType close;
+ switch( GET_TOK(tok, lex) )
+ {
+ case TOK_PAREN_OPEN: close = TOK_PAREN_CLOSE; break;
+ case TOK_BRACE_OPEN: close = TOK_BRACE_CLOSE; break;
+ default:
throw ParseError::Unexpected(lex, tok);
}
+ */
::std::map<const char*,TokenTree,cmp_str> bound_tts;
::std::multimap<const char*,TokenTree,cmp_str> rep_bound_tts;
// Parse according to rules
- bool fail = false;
try
{
for(const auto& pat : rule.m_pattern)
{
Macro_HandlePattern(lex, pat, false, bound_tts, rep_bound_tts);
}
+
+ //GET_CHECK_TOK(tok, lex, close);
+ GET_CHECK_TOK(tok, lex, TOK_EOF);
+ DEBUG( rule.m_contents.size() << " rule contents bound to " << bound_tts.size() << " values - " << name );
+ return MacroExpander(rule.m_contents, bound_tts);
}
catch(const ParseError::Base& e)
{
- DEBUG("Parse of rule failed - " << e.what());
- fail = true;
- }
- // TODO: Actually check if the final token is the closer to the first
- if( !fail )
- {
- if( GET_TOK(tok, lex) != TOK_EOF)
- throw ParseError::Unexpected(lex, tok);
- if( lex.getToken().type() == TOK_EOF )
- return MacroExpander(rule.m_contents, bound_tts);
+ DEBUG("Parse of rule " << i << " of " << name <<" failed - " << e.what());
}
+ i ++;
}
DEBUG("");
throw ParseError::Todo("Error when macro fails to match");
@@ -211,7 +217,7 @@ MacroExpander Macro_Invoke(const char* name, TokenTree input)
t_macro_regs::iterator macro_reg = g_macro_registrations.find(name);
if( macro_reg != g_macro_registrations.end() )
{
- return Macro_InvokeInt(macro_reg->second, input);
+ return Macro_InvokeInt(macro_reg->first.c_str(), macro_reg->second, input);
}
for( auto ent = g_macro_module; ent; ent = ent->m_prev )
@@ -222,7 +228,7 @@ MacroExpander Macro_Invoke(const char* name, TokenTree input)
DEBUG("" << m.name);
if( m.name == name )
{
- return Macro_InvokeInt(m.data, input);
+ return Macro_InvokeInt(m.name.c_str(), m.data, input);
}
}
@@ -231,7 +237,7 @@ MacroExpander Macro_Invoke(const char* name, TokenTree input)
DEBUG("" << mi.name);
if( mi.name == name )
{
- return Macro_InvokeInt(*mi.data, input);
+ return Macro_InvokeInt(mi.name.c_str(), *mi.data, input);
}
}
}
@@ -247,11 +253,13 @@ Token MacroExpander::realGetToken()
{
if( m_ttstream.get() )
{
+ DEBUG("TTStream set");
Token rv = m_ttstream->getToken();
if( rv.type() != TOK_EOF )
return rv;
m_ttstream.reset();
}
+ DEBUG("ofs " << m_ofs << " < " << m_contents.size());
if( m_ofs < m_contents.size() )
{
const MacroRuleEnt& ent = m_contents[m_ofs];
@@ -266,6 +274,8 @@ Token MacroExpander::realGetToken()
}
throw ParseError::Todo("MacroExpander - realGetToken");
}
+
+ DEBUG("EOF");
return Token(TOK_EOF);
}
diff --git a/src/parse/expr.cpp b/src/parse/expr.cpp
index a1b9ed29..34630115 100644
--- a/src/parse/expr.cpp
+++ b/src/parse/expr.cpp
@@ -364,6 +364,9 @@ ExprNodeP Parse_ExprBlocks(TokenStream& lex)
Token tok;
switch( GET_TOK(tok, lex) )
{
+ case TOK_BRACE_OPEN:
+ lex.putback(tok);
+ return Parse_ExprBlockNode(lex);
case TOK_RWORD_MATCH:
return Parse_Expr_Match(lex);
case TOK_RWORD_IF:
@@ -632,9 +635,12 @@ ExprNodeP Parse_ExprVal(TokenStream& lex)
return rv;
}
case TOK_MACRO:
- //return NEWNODE( AST::ExprNode_Macro, tok.str(), Parse_TT(lex) );
{
- MacroExpander expanded_macro = Macro_Invoke(tok.str().c_str(), Parse_TT(lex));
+ TokenTree tt = Parse_TT(lex, true);
+ if( tt.size() == 0 ) {
+ throw ParseError::Unexpected(lex, tt.tok());
+ }
+ MacroExpander expanded_macro = Macro_Invoke(tok.str().c_str(), tt);
return Parse_Expr0(expanded_macro);
}
default:
@@ -643,8 +649,10 @@ ExprNodeP Parse_ExprVal(TokenStream& lex)
}
// Token Tree Parsing
-TokenTree Parse_TT(TokenStream& lex)
+TokenTree Parse_TT(TokenStream& lex, bool unwrapped)
{
+ TRACE_FUNCTION;
+
Token tok = lex.getToken();
eTokenType closer = TOK_PAREN_CLOSE;
switch(tok.type())
@@ -663,19 +671,105 @@ TokenTree Parse_TT(TokenStream& lex)
}
::std::vector<TokenTree> items;
- items.push_back(tok);
+ if( !unwrapped )
+ items.push_back(tok);
while(GET_TOK(tok, lex) != closer && tok.type() != TOK_EOF)
{
lex.putback(tok);
- items.push_back(Parse_TT(lex));
+ items.push_back(Parse_TT(lex, false));
}
- items.push_back(tok);
+ if( !unwrapped )
+ items.push_back(tok);
return TokenTree(items);
}
-TokenTree Parse_TT_Path(TokenStream& lex)
+TokenTree Parse_TT_Type(TokenStream& lex)
+{
+ TRACE_FUNCTION;
+ Token tok;
+
+ ::std::vector<TokenTree> ret;
+ switch(GET_TOK(tok, lex))
+ {
+ case TOK_AMP:
+ throw ParseError::Todo("TokenTree type &-ptr");
+ case TOK_STAR:
+ throw ParseError::Todo("TokenTree type *-ptr");
+ case TOK_DOUBLE_COLON:
+ case TOK_IDENT:
+ lex.putback(tok);
+ return Parse_TT_Path(lex, false);
+ default:
+ throw ParseError::Unexpected(lex, tok);
+ }
+ return TokenTree(ret);
+}
+
+TokenTree Parse_TT_Path(TokenStream& lex, bool mode_expr)
{
- throw ParseError::Todo("TokenTree path");
+ TRACE_FUNCTION;
+
+ Token tok;
+
+ ::std::vector<TokenTree> ret;
+ if( GET_TOK(tok, lex) == TOK_DOUBLE_COLON ) {
+ ret.push_back(TokenTree(tok));
+ }
+ else {
+ lex.putback(tok);
+ }
+
+ for(;;)
+ {
+ // Expect an ident
+ GET_CHECK_TOK(tok, lex, TOK_IDENT);
+ ret.push_back(TokenTree(tok));
+ // If mode is expr, check for a double colon here
+ if( mode_expr )
+ {
+ if( GET_TOK(tok, lex) != TOK_DOUBLE_COLON )
+ break;
+ ret.push_back( TokenTree(tok) );
+ }
+
+ if( GET_TOK(tok, lex) == TOK_LT )
+ {
+ do {
+ ret.push_back( TokenTree(tok) );
+ ret.push_back(Parse_TT_Type(lex));
+ } while(GET_TOK(tok, lex) == TOK_COMMA);
+ if( tok.type() != TOK_GT )
+ {
+ if(tok.type() == TOK_DOUBLE_GT) {
+ ret.push_back(TokenTree(Token(TOK_GT)));
+ lex.putback(Token(TOK_GT));
+ }
+ else {
+ CHECK_TOK(tok, TOK_GT);
+ }
+ }
+ else {
+ ret.push_back(TokenTree(tok));
+ }
+
+ if( GET_TOK(tok, lex) != TOK_DOUBLE_COLON )
+ break;
+ ret.push_back(TokenTree(tok));
+ }
+ else
+ {
+ lex.putback(tok);
+
+ if( !mode_expr )
+ {
+ if( GET_TOK(tok, lex) != TOK_DOUBLE_COLON )
+ break;
+ ret.push_back(TokenTree(tok));
+ }
+ }
+ }
+ lex.putback(tok);
+ return TokenTree(ret);
}
/// Parse a token tree path
TokenTree Parse_TT_Val(TokenStream& lex)
@@ -686,16 +780,16 @@ TokenTree Parse_TT_Val(TokenStream& lex)
{
case TOK_PAREN_OPEN:
lex.putback(tok);
- return Parse_TT(lex);
+ return Parse_TT(lex, false);
case TOK_IDENT:
case TOK_DOUBLE_COLON: {
lex.putback(tok);
- TokenTree inner = Parse_TT_Path(lex);
+ TokenTree inner = Parse_TT_Path(lex, true);
if(GET_TOK(tok, lex) == TOK_BRACE_OPEN) {
lex.putback(tok);
ret.push_back(inner);
- ret.push_back(Parse_TT(lex));
+ ret.push_back(Parse_TT(lex, false));
}
else {
lex.putback(tok);
@@ -703,17 +797,20 @@ TokenTree Parse_TT_Val(TokenStream& lex)
}
break; }
case TOK_RWORD_SELF:
+ case TOK_INTEGER:
+ case TOK_FLOAT:
+ case TOK_STRING:
return TokenTree(tok);
case TOK_RWORD_MATCH:
ret.push_back(TokenTree(tok));
- ret.push_back(Parse_TT(lex));
+ ret.push_back(Parse_TT(lex, false));
break;
case TOK_RWORD_IF:
ret.push_back(TokenTree(tok));
- ret.push_back(Parse_TT(lex));
+ ret.push_back(Parse_TT_Expr(lex));
if( GET_TOK(tok, lex) == TOK_RWORD_ELSE ) {
ret.push_back(TokenTree(tok));
- ret.push_back(Parse_TT(lex));
+ ret.push_back(Parse_TT(lex, false));
}
else {
lex.putback(tok);
@@ -728,6 +825,8 @@ TokenTree Parse_TT_Val(TokenStream& lex)
/// Parse a token tree expression
TokenTree Parse_TT_Expr(TokenStream& lex)
{
+ TRACE_FUNCTION;
+
Token tok;
::std::vector<TokenTree> ret;
@@ -740,9 +839,16 @@ TokenTree Parse_TT_Expr(TokenStream& lex)
{
case TOK_PLUS:
case TOK_DASH:
+ case TOK_SLASH:
+ case TOK_STAR:
+ case TOK_PERCENT:
ret.push_back(tok);
ret.push_back(Parse_TT_Val(lex));
break;
+ case TOK_PAREN_OPEN:
+ lex.putback(tok);
+ ret.push_back(Parse_TT(lex, false));
+ break;
case TOK_DOT:
ret.push_back(tok);
GET_CHECK_TOK(tok, lex, TOK_IDENT);
@@ -753,7 +859,7 @@ TokenTree Parse_TT_Expr(TokenStream& lex)
throw ParseError::Todo("Generic type params in TT expr");
case TOK_PAREN_OPEN:
lex.putback(tok);
- ret.push_back(Parse_TT(lex));
+ ret.push_back(Parse_TT(lex, false));
break;
default:
lex.putback(tok);
diff --git a/src/parse/root.cpp b/src/parse/root.cpp
index 6b857ff9..ec2589f6 100644
--- a/src/parse/root.cpp
+++ b/src/parse/root.cpp
@@ -7,8 +7,6 @@
#include "../macros.hpp"
#include <cassert>
-unsigned int TraceLog::depth = 0;
-
extern AST::Pattern Parse_Pattern(TokenStream& lex);
::std::vector<TypeRef> Parse_Path_GenericList(TokenStream& lex)
@@ -820,7 +818,11 @@ MacroRule Parse_MacroRules_Var(Preproc& lex)
GET_CHECK_TOK(tok, lex, TOK_FATARROW);
// Replacement
- auto rep = Parse_TT(lex);
+ auto rep = Parse_TT(lex, true); // - don't care about the enclosing brackets
+ TTStream slex(rep);
+
+ while(GET_TOK(tok, slex) != TOK_EOF)
+ rule.m_contents.push_back( MacroRuleEnt(tok) );
return rule;
}
diff --git a/src/parse/tokentree.hpp b/src/parse/tokentree.hpp
index d69a7a12..629322dd 100644
--- a/src/parse/tokentree.hpp
+++ b/src/parse/tokentree.hpp
@@ -47,10 +47,11 @@ protected:
virtual Token realGetToken() override;
};
-extern TokenTree Parse_TT(TokenStream& lex);
+// unwrapped = Exclude the enclosing brackets (used by macro parse code)
+extern TokenTree Parse_TT(TokenStream& lex, bool unwrapped);
extern TokenTree Parse_TT_Expr(TokenStream& lex);
extern TokenTree Parse_TT_Stmt(TokenStream& lex);
extern TokenTree Parse_TT_Block(TokenStream& lex);
-extern TokenTree Parse_TT_Path(TokenStream& lex);
+extern TokenTree Parse_TT_Path(TokenStream& lex, bool mode_expr);
#endif // TOKENTREE_HPP_INCLUDED