summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ast/ast.hpp2
-rw-r--r--src/macro_rules/eval.cpp26
-rw-r--r--src/macro_rules/macro_rules.hpp1
-rw-r--r--src/macro_rules/mod.cpp12
-rw-r--r--src/macro_rules/parse.cpp15
-rw-r--r--src/macro_rules/pattern_checks.hpp1
-rw-r--r--src/parse/common.hpp1
-rw-r--r--src/parse/eTokenType.enum.h1
-rw-r--r--src/parse/expr.cpp1
-rw-r--r--src/parse/interpolated_fragment.cpp11
-rw-r--r--src/parse/interpolated_fragment.hpp3
-rw-r--r--src/parse/parseerror.cpp22
-rw-r--r--src/parse/root.cpp7
-rw-r--r--src/parse/token.cpp27
-rw-r--r--src/parse/token.hpp3
-rw-r--r--src/parse/types.cpp10
16 files changed, 128 insertions, 15 deletions
diff --git a/src/ast/ast.hpp b/src/ast/ast.hpp
index f78d559f..49e2bdc6 100644
--- a/src/ast/ast.hpp
+++ b/src/ast/ast.hpp
@@ -42,6 +42,8 @@ class Item;
using ::std::unique_ptr;
using ::std::move;
+typedef bool Visibility;
+
enum eItemType
{
ITEM_TRAIT,
diff --git a/src/macro_rules/eval.cpp b/src/macro_rules/eval.cpp
index cda51ebe..558f26b3 100644
--- a/src/macro_rules/eval.cpp
+++ b/src/macro_rules/eval.cpp
@@ -655,6 +655,8 @@ bool Macro_TryPatternCap(TokenStream& lex, MacroPatEnt::Type type)
return LOOK_AHEAD(lex) == TOK_IDENT || LOOK_AHEAD(lex) == TOK_INTERPOLATED_META;
case MacroPatEnt::PAT_ITEM:
return is_token_item( LOOK_AHEAD(lex) ) || LOOK_AHEAD(lex) == TOK_IDENT;
+ case MacroPatEnt::PAT_VIS:
+ return is_token_vis( LOOK_AHEAD(lex) );
}
BUG(lex.point_span(), "Fell through");
}
@@ -723,6 +725,8 @@ InterpolatedFragment Macro_HandlePatternCap(TokenStream& lex, MacroPatEnt::Type
CHECK_TOK(tok, TOK_IDENT);
// TODO: TOK_INTERPOLATED_IDENT
return InterpolatedFragment( TokenTree(lex.getHygiene(), tok) );
+ case MacroPatEnt::PAT_VIS:
+ return InterpolatedFragment( Parse_Publicity(lex, /*allow_restricted=*/true) );
}
throw "";
}
@@ -1817,6 +1821,26 @@ namespace
}
return true;
}
+ bool consume_vis(TokenStreamRO& lex)
+ {
+ TRACE_FUNCTION;
+ if( lex.consume_if(TOK_INTERPOLATED_VIS) )
+ {
+ return true;
+ }
+ else if( lex.consume_if(TOK_RWORD_PUB) )
+ {
+ if( lex.next() == TOK_PAREN_OPEN )
+ {
+ return consume_tt(lex);
+ }
+ return true;
+ }
+ else
+ {
+ return true;
+ }
+ }
bool consume_from_frag(TokenStreamRO& lex, MacroPatEnt::Type type)
{
@@ -1891,6 +1915,8 @@ namespace
break;
case MacroPatEnt::PAT_ITEM:
return consume_item(lex);
+ case MacroPatEnt::PAT_VIS:
+ return consume_vis(lex);
}
return true;
}
diff --git a/src/macro_rules/macro_rules.hpp b/src/macro_rules/macro_rules.hpp
index c04e3548..9ec6a6bb 100644
--- a/src/macro_rules/macro_rules.hpp
+++ b/src/macro_rules/macro_rules.hpp
@@ -60,6 +60,7 @@ struct MacroPatEnt
PAT_BLOCK,
PAT_META,
PAT_ITEM, // :item
+ PAT_VIS,
} type;
MacroPatEnt():
diff --git a/src/macro_rules/mod.cpp b/src/macro_rules/mod.cpp
index 6410d334..fcea5b25 100644
--- a/src/macro_rules/mod.cpp
+++ b/src/macro_rules/mod.cpp
@@ -156,6 +156,16 @@ bool is_token_item(eTokenType tt) {
return false;
}
}
+bool is_token_vis(eTokenType tt) {
+ switch(tt)
+ {
+ case TOK_RWORD_PUB:
+ case TOK_INTERPOLATED_VIS:
+ return true;
+ default:
+ return true; // TODO: Is this true? it can capture just nothing
+ }
+}
MacroRulesPtr::~MacroRulesPtr()
{
@@ -188,6 +198,7 @@ MacroRulesPtr::~MacroRulesPtr()
case MacroPatEnt::PAT_BLOCK: os << "block"; break;
case MacroPatEnt::PAT_META: os << "meta"; break;
case MacroPatEnt::PAT_ITEM: os << "item"; break;
+ case MacroPatEnt::PAT_VIS: os << "vis"; break;
}
break;
}
@@ -209,6 +220,7 @@ MacroRulesPtr::~MacroRulesPtr()
case MacroPatEnt::PAT_BLOCK: os << "PAT_BLOCK"; break;
case MacroPatEnt::PAT_META: os << "PAT_META"; break;
case MacroPatEnt::PAT_ITEM: os << "PAT_ITEM"; break;
+ case MacroPatEnt::PAT_VIS: os << "PAT_VIS"; break;
}
return os;
}
diff --git a/src/macro_rules/parse.cpp b/src/macro_rules/parse.cpp
index 00cf7cf7..e6d9d7ae 100644
--- a/src/macro_rules/parse.cpp
+++ b/src/macro_rules/parse.cpp
@@ -82,6 +82,8 @@ public:
ret.push_back( MacroPatEnt(name, idx, MacroPatEnt::PAT_BLOCK) );
else if( type == "item" )
ret.push_back( MacroPatEnt(name, idx, MacroPatEnt::PAT_ITEM) );
+ else if( /*TARGETVER_1_29 && */ type == "vis" ) // TODO: Should this be selective?
+ ret.push_back( MacroPatEnt(name, idx, MacroPatEnt::PAT_VIS) );
else
ERROR(lex.point_span(), E0000, "Unknown fragment type '" << type << "'");
break; }
@@ -428,6 +430,19 @@ bool patterns_are_same(const Span& sp, const MacroPatEnt& left, const MacroPatEn
default:
ERROR(sp, E0000, "Incompatible macro fragments " << right << " used with " << left);
}
+ // Matches visibility specifiers
+ case MacroPatEnt::PAT_VIS:
+ switch(left.type)
+ {
+ case MacroPatEnt::PAT_TOKEN:
+ if( is_token_vis(left.tok.type()) )
+ ERROR(sp, E0000, "Incompatible macro fragments");
+ return false;
+ case MacroPatEnt::PAT_VIS:
+ return true;
+ default:
+ ERROR(sp, E0000, "Incompatible macro fragments " << right << " used with " << left);
+ }
}
throw "";
}
diff --git a/src/macro_rules/pattern_checks.hpp b/src/macro_rules/pattern_checks.hpp
index 4ebbe915..6ce15050 100644
--- a/src/macro_rules/pattern_checks.hpp
+++ b/src/macro_rules/pattern_checks.hpp
@@ -13,3 +13,4 @@ extern bool is_token_type(eTokenType tt);
extern bool is_token_expr(eTokenType tt);
extern bool is_token_stmt(eTokenType tt);
extern bool is_token_item(eTokenType tt);
+extern bool is_token_vis(eTokenType tt);
diff --git a/src/parse/common.hpp b/src/parse/common.hpp
index 49499c86..c742fe4f 100644
--- a/src/parse/common.hpp
+++ b/src/parse/common.hpp
@@ -40,6 +40,7 @@ extern ::std::vector<AST::PathNode> Parse_PathNodes(TokenStream& lex, eParsePath
extern AST::PathParams Parse_Path_GenericList(TokenStream& lex);
+extern AST::Visibility Parse_Publicity(TokenStream& lex, bool allow_restricted=true);
extern AST::HigherRankedBounds Parse_HRB(TokenStream& lex);
extern AST::AttributeList Parse_ItemAttrs(TokenStream& lex);
extern void Parse_ParentAttrs(TokenStream& lex, AST::AttributeList& out);
diff --git a/src/parse/eTokenType.enum.h b/src/parse/eTokenType.enum.h
index 4408c45a..93590264 100644
--- a/src/parse/eTokenType.enum.h
+++ b/src/parse/eTokenType.enum.h
@@ -21,6 +21,7 @@ _(TOK_INTERPOLATED_STMT)
_(TOK_INTERPOLATED_BLOCK)
_(TOK_INTERPOLATED_META)
_(TOK_INTERPOLATED_ITEM)
+_(TOK_INTERPOLATED_VIS)
// Value tokens
_(TOK_IDENT)
diff --git a/src/parse/expr.cpp b/src/parse/expr.cpp
index e5d7981d..03c77043 100644
--- a/src/parse/expr.cpp
+++ b/src/parse/expr.cpp
@@ -124,6 +124,7 @@ ExprNodeP Parse_ExprBlockLine_WithItems(TokenStream& lex, ::std::shared_ptr<AST:
switch(tok.type())
{
// Items:
+ case TOK_INTERPOLATED_VIS:
case TOK_RWORD_PUB:
// NOTE: Allowed, but doesn't do much
case TOK_RWORD_TYPE:
diff --git a/src/parse/interpolated_fragment.cpp b/src/parse/interpolated_fragment.cpp
index d8a8bc43..634309a5 100644
--- a/src/parse/interpolated_fragment.cpp
+++ b/src/parse/interpolated_fragment.cpp
@@ -31,6 +31,9 @@ InterpolatedFragment::~InterpolatedFragment()
case InterpolatedFragment::ITEM:
delete reinterpret_cast<AST::Named<AST::Item>*>(m_ptr);
break;
+ case InterpolatedFragment::VIS:
+ delete reinterpret_cast<AST::Visibility*>(m_ptr);
+ break;
}
}
}
@@ -82,6 +85,11 @@ InterpolatedFragment::InterpolatedFragment(TypeRef v):
m_ptr( new TypeRef(mv$(v)) )
{
}
+InterpolatedFragment::InterpolatedFragment(AST::Visibility v):
+ m_type( InterpolatedFragment::VIS ),
+ m_ptr( new AST::Visibility(mv$(v)) )
+{
+}
::std::ostream& operator<<(::std::ostream& os, InterpolatedFragment const& x)
{
@@ -117,6 +125,9 @@ InterpolatedFragment::InterpolatedFragment(TypeRef v):
const auto& named_item = *reinterpret_cast<const AST::Named<AST::Item>*>(x.m_ptr);
os << "item[" << named_item.data.tag_str() << "(" << named_item.name << ")]";
} break;
+ case InterpolatedFragment::VIS:
+ os << "vis[" << *reinterpret_cast<const AST::Visibility*>(x.m_ptr) << "]";
+ break;
}
return os;
}
diff --git a/src/parse/interpolated_fragment.hpp b/src/parse/interpolated_fragment.hpp
index 36539fb0..1e69fe26 100644
--- a/src/parse/interpolated_fragment.hpp
+++ b/src/parse/interpolated_fragment.hpp
@@ -12,6 +12,7 @@
class TypeRef;
class TokenTree;
namespace AST {
+ typedef bool Visibility;
class Pattern;
class Path;
class ExprNode;
@@ -37,6 +38,7 @@ public:
META,
ITEM,
+ VIS,
} m_type;
// Owned type-pruned pointer
@@ -53,6 +55,7 @@ public:
InterpolatedFragment(::AST::Named<AST::Item> );
~InterpolatedFragment();
InterpolatedFragment(Type , ::AST::ExprNode*);
+ InterpolatedFragment(AST::Visibility); // :vis
TokenTree& as_tt() { assert(m_type == TT); return *reinterpret_cast<TokenTree*>(m_ptr); }
const TokenTree& as_tt() const { assert(m_type == TT); return *reinterpret_cast<TokenTree*>(m_ptr); }
diff --git a/src/parse/parseerror.cpp b/src/parse/parseerror.cpp
index 1bb30985..f2a5343b 100644
--- a/src/parse/parseerror.cpp
+++ b/src/parse/parseerror.cpp
@@ -61,7 +61,7 @@ ParseError::Unexpected::Unexpected(const TokenStream& lex, const Token& tok)//:
Span pos = tok.get_pos();
if(pos.filename == "")
pos = lex.point_span();
- ::std::cout << pos << ": Unexpected(" << tok << ")" << ::std::endl;
+ ERROR(pos, E0000, "Unexpected token " << tok);
}
ParseError::Unexpected::Unexpected(const TokenStream& lex, const Token& tok, Token exp)//:
// m_tok( mv$(tok) )
@@ -69,22 +69,22 @@ ParseError::Unexpected::Unexpected(const TokenStream& lex, const Token& tok, Tok
Span pos = tok.get_pos();
if(pos.filename == "")
pos = lex.point_span();
- ::std::cout << pos << ": Unexpected(" << tok << ", " << exp << ")" << ::std::endl;
+ ERROR(pos, E0000, "Unexpected token " << tok << ", expected " << exp);
}
ParseError::Unexpected::Unexpected(const TokenStream& lex, const Token& tok, ::std::vector<eTokenType> exp)
{
Span pos = tok.get_pos();
if(pos.filename == "")
pos = lex.point_span();
- ::std::cout << pos << ": Unexpected " << tok << ", expected ";
- bool f = true;
- for(auto v: exp) {
- if(!f)
- ::std::cout << " or ";
- f = false;
- ::std::cout << Token::typestr(v);
- }
- ::std::cout << ::std::endl;
+ ERROR(pos, E0000, "Unexpected token " << tok << ", expected one of " << FMT_CB(os, {
+ bool f = true;
+ for(auto v: exp) {
+ if(!f)
+ os << " or ";
+ f = false;
+ os << Token::typestr(v);
+ }
+ }));
}
ParseError::Unexpected::~Unexpected() throw()
{
diff --git a/src/parse/root.cpp b/src/parse/root.cpp
index ef1fb439..61218326 100644
--- a/src/parse/root.cpp
+++ b/src/parse/root.cpp
@@ -49,9 +49,14 @@ void Parse_ModRoot(TokenStream& lex, AST::Module& mod, AST::AttributeList& mod_a
bool Parse_MacroInvocation_Opt(TokenStream& lex, AST::MacroInvocation& out_inv);
//::AST::Path Parse_Publicity(TokenStream& lex)
-bool Parse_Publicity(TokenStream& lex, bool allow_restricted=true)
+::AST::Visibility Parse_Publicity(TokenStream& lex, bool allow_restricted/*=true*/)
{
Token tok;
+ if( LOOK_AHEAD(lex) == TOK_INTERPOLATED_VIS )
+ {
+ GET_TOK(tok, lex);
+ return tok.take_frag_vis();
+ }
if( LOOK_AHEAD(lex) == TOK_RWORD_PUB )
{
GET_TOK(tok, lex);
diff --git a/src/parse/token.cpp b/src/parse/token.cpp
index f1471453..f9c168e8 100644
--- a/src/parse/token.cpp
+++ b/src/parse/token.cpp
@@ -35,6 +35,9 @@ Token::~Token()
case TOK_INTERPOLATED_META:
delete reinterpret_cast<AST::Attribute*>(m_data.as_Fragment());
break;
+ case TOK_INTERPOLATED_VIS:
+ delete reinterpret_cast<AST::Visibility*>(m_data.as_Fragment());
+ break;
default:
break;
}
@@ -68,7 +71,12 @@ Token::Token(const InterpolatedFragment& frag)
{
switch(frag.m_type)
{
- case InterpolatedFragment::TT: throw "";
+ case InterpolatedFragment::TT:
+ throw "";
+ case InterpolatedFragment::VIS:
+ m_type = TOK_INTERPOLATED_VIS;
+ m_data = new AST::Visibility( *reinterpret_cast<const AST::Visibility*>(frag.m_ptr) );
+ break;
case InterpolatedFragment::TYPE:
m_type = TOK_INTERPOLATED_TYPE;
m_data = new TypeRef( reinterpret_cast<const TypeRef*>(frag.m_ptr)->clone() );
@@ -106,7 +114,12 @@ Token::Token(TagTakeIP, InterpolatedFragment frag)
{
switch(frag.m_type)
{
- case InterpolatedFragment::TT: throw "";
+ case InterpolatedFragment::TT:
+ throw "";
+ case InterpolatedFragment::VIS:
+ m_type = TOK_INTERPOLATED_VIS;
+ m_data = new AST::Visibility( mv$(*reinterpret_cast<AST::Visibility*>(frag.m_ptr)) );
+ break;
case InterpolatedFragment::TYPE:
m_type = TOK_INTERPOLATED_TYPE;
m_data = new TypeRef( mv$(*reinterpret_cast<TypeRef*>(frag.m_ptr)) );
@@ -228,6 +241,15 @@ Token Token::clone() const
delete ptr;
return mv$(rv);
}
+::AST::Visibility Token::take_frag_vis()
+{
+ assert( m_type == TOK_INTERPOLATED_VIS );
+ auto ptr = reinterpret_cast<AST::Visibility*>(m_data.as_Fragment());
+ m_data.as_Fragment() = nullptr;
+ auto rv = mv$( *ptr );
+ delete ptr;
+ return mv$(rv);
+}
const char* Token::typestr(enum eTokenType type)
{
@@ -309,6 +331,7 @@ struct EscapedString {
case TOK_INTERPOLATED_META: return "/*:meta*/";
case TOK_INTERPOLATED_ITEM: return "/*:item*/";
case TOK_INTERPOLATED_IDENT: return "/*:ident*/";
+ case TOK_INTERPOLATED_VIS: return "/*:vis*/";
// Value tokens
case TOK_IDENT: return m_data.as_String();
case TOK_LIFETIME: return "'" + m_data.as_String();
diff --git a/src/parse/token.hpp b/src/parse/token.hpp
index 3605679b..d5e7a6db 100644
--- a/src/parse/token.hpp
+++ b/src/parse/token.hpp
@@ -44,6 +44,7 @@ extern ::std::ostream& operator<<(::std::ostream& os, const Position& p);
class TypeRef;
class TokenTree;
namespace AST {
+ typedef bool Visibility;
class Pattern;
class Path;
class ExprNode;
@@ -120,12 +121,14 @@ public:
uint64_t intval() const { return m_data.as_Integer().m_intval; }
double floatval() const { return m_data.as_Float().m_floatval; }
+ // TODO: Replace these with a way of getting a InterpolatedFragment&
TypeRef& frag_type() { assert(m_type == TOK_INTERPOLATED_TYPE); return *reinterpret_cast<TypeRef*>( m_data.as_Fragment() ); }
AST::Path& frag_path() { assert(m_type == TOK_INTERPOLATED_PATH); return *reinterpret_cast<AST::Path*>( m_data.as_Fragment() ); }
AST::Pattern& frag_pattern() { assert(m_type == TOK_INTERPOLATED_PATTERN); return *reinterpret_cast<AST::Pattern*>( m_data.as_Fragment() ); }
AST::Attribute& frag_meta() { assert(m_type == TOK_INTERPOLATED_META); return *reinterpret_cast<AST::Attribute*>( m_data.as_Fragment() ); }
::std::unique_ptr<AST::ExprNode> take_frag_node();
::AST::Named<AST::Item> take_frag_item();
+ ::AST::Visibility take_frag_vis();
bool operator==(const Token& r) const {
if(type() != r.type())
diff --git a/src/parse/types.cpp b/src/parse/types.cpp
index db66a77e..bbcff489 100644
--- a/src/parse/types.cpp
+++ b/src/parse/types.cpp
@@ -87,7 +87,15 @@ TypeRef Parse_Type_Int(TokenStream& lex, bool allow_trait_list)
}
if( TARGETVER_1_29 && tok.str() == "dyn" )
{
- return Parse_Type_TraitObject(lex, {});
+ if( lex.lookahead(0) == TOK_PAREN_OPEN ) {
+ GET_TOK(tok, lex);
+ auto rv = Parse_Type_TraitObject(lex, {});
+ GET_CHECK_TOK(tok, lex, TOK_PAREN_CLOSE);
+ return rv;
+ }
+ else {
+ return Parse_Type_TraitObject(lex, {});
+ }
}
// or a primitive
//if( auto ct = coretype_fromstring(tok.str()) )