diff options
-rw-r--r-- | src/ast/macro.hpp | 7 | ||||
-rw-r--r-- | src/ast/path.hpp | 4 | ||||
-rw-r--r-- | src/expand/mod.cpp | 2 | ||||
-rw-r--r-- | src/include/span.hpp | 2 | ||||
-rw-r--r-- | src/parse/common.hpp | 2 | ||||
-rw-r--r-- | src/parse/pattern.cpp | 3 | ||||
-rw-r--r-- | src/parse/root.cpp | 10 | ||||
-rw-r--r-- | src/parse/types.cpp | 3 | ||||
-rw-r--r-- | src/types.hpp | 5 |
9 files changed, 27 insertions, 11 deletions
diff --git a/src/ast/macro.hpp b/src/ast/macro.hpp index 4696c732..4804f52b 100644 --- a/src/ast/macro.hpp +++ b/src/ast/macro.hpp @@ -3,6 +3,7 @@ #define _AST_MACRO_HPP_ #include "../parse/tokentree.hpp" +#include <span.hpp> #include "attrs.hpp" namespace AST { @@ -10,6 +11,8 @@ namespace AST { class MacroInvocation: public Serialisable { + Span m_span; + ::AST::MetaItems m_attrs; ::std::string m_macro_name; ::std::string m_ident; @@ -19,7 +22,8 @@ public: { } - MacroInvocation(MetaItems attrs, ::std::string macro, ::std::string ident, TokenTree input): + MacroInvocation(Span span, MetaItems attrs, ::std::string macro, ::std::string ident, TokenTree input): + m_span( mv$(span) ), m_attrs( mv$(attrs) ), m_macro_name( mv$(macro) ), m_ident( mv$(ident) ), @@ -39,6 +43,7 @@ public: m_input = TokenTree(); } + const Span& span() const { return m_span; } const ::std::string& name() const { return m_macro_name; } const ::std::string& input_ident() const { return m_ident; } diff --git a/src/ast/path.hpp b/src/ast/path.hpp index 1260ece3..4fc08bb1 100644 --- a/src/ast/path.hpp +++ b/src/ast/path.hpp @@ -130,6 +130,7 @@ public: private: /// The crate defining the root of this path (used for path resolution) ::std::string m_crate; + Span m_span; public: Class m_class; @@ -197,6 +198,9 @@ public: } + const Span& span() const { + return m_span; + } Class::Tag class_tag() const { return m_class.tag(); } diff --git a/src/expand/mod.cpp b/src/expand/mod.cpp index 3f35d4dc..c6d5eec2 100644 --- a/src/expand/mod.cpp +++ b/src/expand/mod.cpp @@ -80,7 +80,7 @@ AST::Expr Expand_Macro(bool is_early, LList<const AST::Module*> modstack, ::AST: if( ! is_early ) { // TODO: Error - Unknown macro name // TODO: Get a span via MacroInvocation and emit a good error - throw ::std::runtime_error( FMT("Unknown macro '" << mi.name() << "'") ); + ERROR(mi.span(), E0000, "Unknown macro '" << mi.name() << "'"); } // Leave valid and return an empty expression diff --git a/src/include/span.hpp b/src/include/span.hpp index 7603b080..49169e5b 100644 --- a/src/include/span.hpp +++ b/src/include/span.hpp @@ -59,7 +59,7 @@ struct Spanned T m_item; }; -#define ERROR(span, code, msg) do { (Span()/*span*/).error(code, [&](::std::ostream& os) { os << msg; }); throw ::std::runtime_error("Error fell through" #code); } while(0) +#define ERROR(span, code, msg) do { (span).error(code, [&](::std::ostream& os) { os << msg; }); throw ::std::runtime_error("Error fell through" #code); } while(0) #define BUG(span, msg) do { (span).bug([&](::std::ostream& os) { os << msg; }); throw ::std::runtime_error("Bug fell through"); } while(0) #define TODO(span, msg) do { (span).bug([&](::std::ostream& os) { os << "TODO: " << msg; }); throw ::std::runtime_error("Bug (todo) fell through"); } while(0) diff --git a/src/parse/common.hpp b/src/parse/common.hpp index 4b6ceb54..ed052a33 100644 --- a/src/parse/common.hpp +++ b/src/parse/common.hpp @@ -39,7 +39,7 @@ extern ::std::vector<TypeRef> Parse_Path_GenericList(TokenStream& lex); extern AST::MetaItem Parse_MetaItem(TokenStream& lex);
-extern ::AST::MacroInvocation Parse_MacroInvocation(::AST::MetaItems meta_items, ::std::string name, TokenStream& lex);
+extern ::AST::MacroInvocation Parse_MacroInvocation(ProtoSpan ps, ::AST::MetaItems meta_items, ::std::string name, TokenStream& lex);
extern TypeRef Parse_Type(TokenStream& lex);
extern AST::Pattern Parse_Pattern(TokenStream& lex, bool is_refutable);
diff --git a/src/parse/pattern.cpp b/src/parse/pattern.cpp index e8ccd962..dcbc8c5d 100644 --- a/src/parse/pattern.cpp +++ b/src/parse/pattern.cpp @@ -37,13 +37,14 @@ AST::Pattern Parse_PatternReal1(TokenStream& lex, bool is_refutable); AST::Pattern Parse_Pattern(TokenStream& lex, bool is_refutable) { TRACE_FUNCTION; + auto ps = lex.start_span(); Token tok; tok = lex.getToken(); if( tok.type() == TOK_MACRO ) { - return AST::Pattern( AST::Pattern::TagMacro(), box$(Parse_MacroInvocation(AST::MetaItems(), tok.str(), lex))); + return AST::Pattern( AST::Pattern::TagMacro(), box$(Parse_MacroInvocation(ps, AST::MetaItems(), tok.str(), lex))); } bool expect_bind = false; diff --git a/src/parse/root.cpp b/src/parse/root.cpp index faa2b9bb..0860a008 100644 --- a/src/parse/root.cpp +++ b/src/parse/root.cpp @@ -917,9 +917,10 @@ void Parse_Impl(TokenStream& lex, AST::Module& mod, AST::MetaItems attrs, bool i // A sequence of method implementations
while( GET_TOK(tok, lex) != TOK_BRACE_CLOSE )
{
+ auto ps = lex.start_span();
if( tok.type() == TOK_MACRO )
{
- impl.add_macro_invocation( Parse_MacroInvocation( AST::MetaItems(), mv$(tok.str()), lex ) );
+ impl.add_macro_invocation( Parse_MacroInvocation( ps, AST::MetaItems(), mv$(tok.str()), lex ) );
// - Silently consume ';' after the macro
if( GET_TOK(tok, lex) != TOK_SEMICOLON )
lex.putback(tok);
@@ -1206,7 +1207,7 @@ void Parse_Use(TokenStream& lex, ::std::function<void(AST::Path, ::std::string)> }
-::AST::MacroInvocation Parse_MacroInvocation(::AST::MetaItems meta_items, ::std::string name, TokenStream& lex)
+::AST::MacroInvocation Parse_MacroInvocation(ProtoSpan span_start, ::AST::MetaItems meta_items, ::std::string name, TokenStream& lex)
{
Token tok;
::std::string ident;
@@ -1217,7 +1218,7 @@ void Parse_Use(TokenStream& lex, ::std::function<void(AST::Path, ::std::string)> lex.putback(tok);
}
TokenTree tt = Parse_TT(lex, true);
- return ::AST::MacroInvocation( mv$(meta_items), mv$(name), mv$(ident), mv$(tt));
+ return ::AST::MacroInvocation( lex.end_span(span_start), mv$(meta_items), mv$(name), mv$(ident), mv$(tt));
}
void Parse_ExternCrate(TokenStream& lex, AST::Module& mod, AST::MetaItems meta_items)
@@ -1598,10 +1599,11 @@ void Parse_ModRoot_Items(TokenStream& lex, AST::Module& mod, LList<AST::Module*> DEBUG("meta_items = " << meta_items);
// root-level macros
+ auto ps = lex.start_span();
if( GET_TOK(tok, lex) == TOK_MACRO )
{
::std::string name = mv$(tok.str());
- mod.add_macro_invocation( Parse_MacroInvocation( mv$(meta_items), mv$(name), lex ) );
+ mod.add_macro_invocation( Parse_MacroInvocation( ps, mv$(meta_items), mv$(name), lex ) );
// - Silently consume ';' after the macro
// TODO: Check the tt next token before parsing to tell if this is needed
if( GET_TOK(tok, lex) != TOK_SEMICOLON )
diff --git a/src/parse/types.cpp b/src/parse/types.cpp index e6aadbbe..16e95f6d 100644 --- a/src/parse/types.cpp +++ b/src/parse/types.cpp @@ -28,13 +28,14 @@ TypeRef Parse_Type(TokenStream& lex) TypeRef Parse_Type_Int(TokenStream& lex) { //TRACE_FUNCTION; + auto ps = lex.start_span(); Token tok; switch( GET_TOK(tok, lex) ) { case TOK_MACRO: - return TypeRef(TypeRef::TagMacro(), Parse_MacroInvocation(AST::MetaItems(), mv$(tok.str()), lex)); + return TypeRef(TypeRef::TagMacro(), Parse_MacroInvocation(ps, AST::MetaItems(), mv$(tok.str()), lex)); // '!' - Only ever used as part of function prototypes, but is kinda a type... not allowed here though case TOK_EXCLAM: throw ParseError::Generic(lex, "! is not a real type"); diff --git a/src/types.hpp b/src/types.hpp index 24c0d9ea..5b19d036 100644 --- a/src/types.hpp +++ b/src/types.hpp @@ -103,6 +103,7 @@ TAGGED_UNION(TypeData, None, class TypeRef:
public Serialisable
{
+ Span m_span;
public:
TypeData m_data;
@@ -215,7 +216,9 @@ public: m_data(TypeData::make_TraitObject({ mv$(hrls), ::std::move(traits) }))
{}
-
+
+ const Span& span() const { return m_span; }
+
/// Dereference the type (return the result of *type_instance)
bool deref(bool is_implicit);
/// Merge with another type (combines known aspects, conflitcs cause an exception)
|