diff options
author | John Hodge <tpg@ucc.asn.au> | 2017-06-11 11:34:16 +0800 |
---|---|---|
committer | John Hodge <tpg@ucc.asn.au> | 2017-06-11 11:34:16 +0800 |
commit | 52d872b36d7fda733273d70100d21b16506f1647 (patch) | |
tree | 5f192e2650a0f15893546d484fcc6537786e6a46 | |
parent | c211c01437ce248d654b0d6ba9b739d1633cce68 (diff) | |
download | mrust-52d872b36d7fda733273d70100d21b16506f1647.tar.gz |
Parse - Support chaining of spans (for macro expansions)
-rw-r--r-- | src/ast/expr.cpp | 8 | ||||
-rw-r--r-- | src/ast/expr.hpp | 7 | ||||
-rw-r--r-- | src/expand/mod.cpp | 8 | ||||
-rw-r--r-- | src/hir/from_ast_expr.cpp | 46 | ||||
-rw-r--r-- | src/include/span.hpp | 3 | ||||
-rw-r--r-- | src/macro_rules/eval.cpp | 10 | ||||
-rw-r--r-- | src/macro_rules/parse.cpp | 6 | ||||
-rw-r--r-- | src/parse/expr.cpp | 16 | ||||
-rw-r--r-- | src/parse/parseerror.cpp | 20 | ||||
-rw-r--r-- | src/parse/pattern.cpp | 6 | ||||
-rw-r--r-- | src/parse/root.cpp | 26 | ||||
-rw-r--r-- | src/parse/tokenstream.cpp | 14 | ||||
-rw-r--r-- | src/parse/tokenstream.hpp | 4 | ||||
-rw-r--r-- | src/parse/types.cpp | 2 | ||||
-rw-r--r-- | src/resolve/absolute.cpp | 12 | ||||
-rw-r--r-- | src/span.cpp | 3 |
16 files changed, 101 insertions, 90 deletions
diff --git a/src/ast/expr.cpp b/src/ast/expr.cpp index dd586683..c1baf9b4 100644 --- a/src/ast/expr.cpp +++ b/src/ast/expr.cpp @@ -69,11 +69,11 @@ ExprNode::~ExprNode() { #define OPT_CLONE(node) (node.get() ? node->clone() : ::AST::ExprNodeP()) namespace { - static inline ExprNodeP mk_exprnodep(const Position& pos, AST::ExprNode* en) { - en->set_pos(pos); + static inline ExprNodeP mk_exprnodep(const Span& pos, AST::ExprNode* en) { + en->set_span(pos); return ExprNodeP(en); } - #define NEWNODE(type, ...) mk_exprnodep(get_pos(), new type(__VA_ARGS__)) + #define NEWNODE(type, ...) mk_exprnodep(span(), new type(__VA_ARGS__)) } NODE(ExprNode_Block, { @@ -453,7 +453,7 @@ NV(ExprNode_Block, { }) NV(ExprNode_Macro, { - BUG(node.get_pos(), "Hit unexpanded macro in expression - " << node); + BUG(node.span(), "Hit unexpanded macro in expression - " << node); }) NV(ExprNode_Asm, { diff --git a/src/ast/expr.hpp b/src/ast/expr.hpp index ee1da656..a6b58e03 100644 --- a/src/ast/expr.hpp +++ b/src/ast/expr.hpp @@ -26,7 +26,7 @@ class NodeVisitor; class ExprNode { MetaItems m_attrs; - Position m_pos; + Span m_span; public: virtual ~ExprNode() = 0; @@ -34,9 +34,8 @@ public: virtual void print(::std::ostream& os) const = 0; virtual ::std::unique_ptr<ExprNode> clone() const = 0; - void set_pos(Position p) { m_pos = ::std::move(p); } - const Position& get_pos() const { return m_pos; } - Span span() const { return m_pos; } + void set_span(Span s) { m_span = ::std::move(s); } + const Span& span() const { return m_span; } void set_attrs(MetaItems&& mi) { m_attrs = mv$(mi); diff --git a/src/expand/mod.cpp b/src/expand/mod.cpp index 1a534c0b..38e40347 100644 --- a/src/expand/mod.cpp +++ b/src/expand/mod.cpp @@ -317,7 +317,7 @@ struct CExpandExpr: { this->visit(cnode); if(cnode.get() == nullptr) - ERROR(parent.get_pos(), E0000, "#[cfg] not allowed in this position"); + ERROR(parent.span(), E0000, "#[cfg] not allowed in this position"); } assert( ! this->replacement ); } @@ -343,7 +343,7 @@ struct CExpandExpr: ::AST::ExprNodeP rv; auto& mod = this->cur_mod(); - auto ttl = Expand_Macro( crate, modstack, mod, Span(node.get_pos()), node.m_name, node.m_ident, node.m_tokens ); + auto ttl = Expand_Macro( crate, modstack, mod, node.span(), node.m_name, node.m_ident, node.m_tokens ); if( !ttl.get() ) { // No expansion @@ -362,7 +362,7 @@ struct CExpandExpr: auto newexpr = Parse_ExprBlockLine_WithItems(*ttl, local_mod_ptr, add_silence_if_end); if( tmp_local_mod ) - TODO(node.get_pos(), "Handle edge case where a macro expansion outside of a _Block creates an item"); + TODO(node.span(), "Handle edge case where a macro expansion outside of a _Block creates an item"); if( newexpr ) { @@ -382,7 +382,7 @@ struct CExpandExpr: if( ttl->lookahead(0) != TOK_EOF ) { if( !nodes_out ) { - ERROR(node.get_pos(), E0000, "Unused tokens at the end of macro expansion - " << ttl->getToken()); + ERROR(node.span(), E0000, "Unused tokens at the end of macro expansion - " << ttl->getToken()); } } } diff --git a/src/hir/from_ast_expr.cpp b/src/hir/from_ast_expr.cpp index 9085bd3b..296bdce1 100644 --- a/src/hir/from_ast_expr.cpp +++ b/src/hir/from_ast_expr.cpp @@ -30,7 +30,7 @@ struct LowerHIR_ExprNode_Visitor: auto rv = new ::HIR::ExprNode_Block(v.span()); for(const auto& n : v.m_nodes) { - ASSERT_BUG(v.get_pos(), n, "NULL node encountered in block"); + ASSERT_BUG(v.span(), n, "NULL node encountered in block"); rv->m_nodes.push_back( LowerHIR_ExprNode_Inner( *n ) ); } if( v.m_yields_final_value && ! rv->m_nodes.empty() ) @@ -48,7 +48,7 @@ struct LowerHIR_ExprNode_Visitor: m_rv.reset( static_cast< ::HIR::ExprNode*>(rv) ); } virtual void visit(::AST::ExprNode_Macro& v) override { - BUG(v.get_pos(), "Hit ExprNode_Macro"); + BUG(v.span(), "Hit ExprNode_Macro"); } virtual void visit(::AST::ExprNode_Asm& v) override { ::std::vector< ::HIR::ExprNode_Asm::ValRef> outputs; @@ -72,7 +72,7 @@ struct LowerHIR_ExprNode_Visitor: case ::AST::ExprNode_Flow::CONTINUE: case ::AST::ExprNode_Flow::BREAK: if( v.m_value ) - TODO(v.get_pos(), "Handle break/continue values in HIR"); + TODO(v.span(), "Handle break/continue values in HIR"); m_rv.reset( new ::HIR::ExprNode_LoopControl( v.span(), v.m_target, (v.m_type == ::AST::ExprNode_Flow::CONTINUE) ) ); break; } @@ -167,7 +167,7 @@ struct LowerHIR_ExprNode_Visitor: } break; } case ::AST::ExprNode_BinOp::PLACE_IN: - TODO(v.get_pos(), "Desugar placement syntax"); + TODO(v.span(), "Desugar placement syntax"); break; case ::AST::ExprNode_BinOp::CMPEQU : op = ::HIR::ExprNode_BinOp::Op::CmpEqu ; if(0) @@ -213,7 +213,7 @@ struct LowerHIR_ExprNode_Visitor: )); } break; case ::AST::ExprNode_UniOp::QMARK: - BUG(v.get_pos(), "Encounterd question mark operator (should have been expanded in AST)"); + BUG(v.span(), "Encounterd question mark operator (should have been expanded in AST)"); break; case ::AST::ExprNode_UniOp::REF: @@ -262,7 +262,7 @@ struct LowerHIR_ExprNode_Visitor: TU_MATCH_DEF(::AST::PathBinding, (v.m_path.binding()), (e), ( m_rv.reset( new ::HIR::ExprNode_CallPath( v.span(), - LowerHIR_Path(Span(v.get_pos()), v.m_path), + LowerHIR_Path(v.span(), v.m_path), mv$( args ) ) ); ), @@ -361,7 +361,7 @@ struct LowerHIR_ExprNode_Visitor: break; } case ::AST::ExprNode_Loop::FOR: // NOTE: This should already be desugared (as a pass before resolve) - BUG(v.get_pos(), "Encountered still-sugared for loop"); + BUG(v.span(), "Encountered still-sugared for loop"); break; } @@ -507,7 +507,7 @@ struct LowerHIR_ExprNode_Visitor: } m_rv.reset( new ::HIR::ExprNode_Literal( v.span(), ::HIR::ExprNode_Literal::Data::make_Integer({ - H::get_type( Span(v.get_pos()), v.m_datatype ), + H::get_type( v.span(), v.m_datatype ), v.m_value }) ) ); @@ -520,7 +520,7 @@ struct LowerHIR_ExprNode_Visitor: case CORETYPE_F32: ct = ::HIR::CoreType::F32; break; case CORETYPE_F64: ct = ::HIR::CoreType::F64; break; default: - BUG(v.get_pos(), "Unknown type for float literal"); + BUG(v.span(), "Unknown type for float literal"); } m_rv.reset( new ::HIR::ExprNode_Literal( v.span(), ::HIR::ExprNode_Literal::Data::make_Float({ ct, v.m_value }) @@ -560,7 +560,7 @@ struct LowerHIR_ExprNode_Visitor: ERROR(v.span(), E0000, "Union constructors can't take a base value"); m_rv.reset( new ::HIR::ExprNode_UnionLiteral( v.span(), - LowerHIR_GenericPath(v.get_pos(), v.m_path), + LowerHIR_GenericPath(v.span(), v.m_path), v.m_values[0].first, LowerHIR_ExprNode_Inner(*v.m_values[0].second) ) ); @@ -571,7 +571,7 @@ struct LowerHIR_ExprNode_Visitor: for(const auto& val : v.m_values) values.push_back( ::std::make_pair(val.first, LowerHIR_ExprNode_Inner(*val.second)) ); m_rv.reset( new ::HIR::ExprNode_StructLiteral( v.span(), - LowerHIR_GenericPath(v.get_pos(), v.m_path), + LowerHIR_GenericPath(v.span(), v.m_path), ! v.m_path.binding().is_EnumVar(), LowerHIR_ExprNode_Inner_Opt(v.m_base_value.get()), mv$(values) @@ -604,7 +604,7 @@ struct LowerHIR_ExprNode_Visitor: virtual void visit(::AST::ExprNode_NamedValue& v) override { TU_IFLET(::AST::Path::Class, v.m_path.m_class, Local, e, if( !v.m_path.binding().is_Variable() ) { - BUG(v.get_pos(), "Named value was a local, but wasn't bound - " << v.m_path); + BUG(v.span(), "Named value was a local, but wasn't bound - " << v.m_path); } auto slot = v.m_path.binding().as_Variable().slot; m_rv.reset( new ::HIR::ExprNode_Variable( v.span(), e.name, slot ) ); @@ -612,7 +612,7 @@ struct LowerHIR_ExprNode_Visitor: else { TU_MATCH_DEF(::AST::PathBinding, (v.m_path.binding()), (e), ( - auto p = LowerHIR_Path(Span(v.get_pos()), v.m_path); + auto p = LowerHIR_Path(v.span(), v.m_path); if( p.m_data.is_Generic() ) { BUG(v.span(), "Unknown binding for PathValue but path is generic - " << v.m_path); } @@ -643,10 +643,10 @@ struct LowerHIR_ExprNode_Visitor: } } if( is_tuple_constructor ) { - m_rv.reset( new ::HIR::ExprNode_PathValue( v.span(), LowerHIR_Path(Span(v.get_pos()), v.m_path), ::HIR::ExprNode_PathValue::STRUCT_CONSTR ) ); + m_rv.reset( new ::HIR::ExprNode_PathValue( v.span(), LowerHIR_Path(v.span(), v.m_path), ::HIR::ExprNode_PathValue::STRUCT_CONSTR ) ); } else { - m_rv.reset( new ::HIR::ExprNode_UnitVariant( v.span(), LowerHIR_GenericPath(Span(v.get_pos()), v.m_path), true ) ); + m_rv.reset( new ::HIR::ExprNode_UnitVariant( v.span(), LowerHIR_GenericPath(v.span(), v.m_path), true ) ); } ), (EnumVar, @@ -680,33 +680,33 @@ struct LowerHIR_ExprNode_Visitor: } (void)var_idx; // TODO: Save time later by saving this. if( is_tuple_constructor ) { - m_rv.reset( new ::HIR::ExprNode_PathValue( v.span(), LowerHIR_Path(Span(v.get_pos()), v.m_path), ::HIR::ExprNode_PathValue::ENUM_VAR_CONSTR ) ); + m_rv.reset( new ::HIR::ExprNode_PathValue( v.span(), LowerHIR_Path(v.span(), v.m_path), ::HIR::ExprNode_PathValue::ENUM_VAR_CONSTR ) ); } else { - m_rv.reset( new ::HIR::ExprNode_UnitVariant( v.span(), LowerHIR_GenericPath(Span(v.get_pos()), v.m_path), false ) ); + m_rv.reset( new ::HIR::ExprNode_UnitVariant( v.span(), LowerHIR_GenericPath(v.span(), v.m_path), false ) ); } ), (Function, - m_rv.reset( new ::HIR::ExprNode_PathValue( v.span(), LowerHIR_Path(Span(v.get_pos()), v.m_path), ::HIR::ExprNode_PathValue::FUNCTION ) ); + m_rv.reset( new ::HIR::ExprNode_PathValue( v.span(), LowerHIR_Path(v.span(), v.m_path), ::HIR::ExprNode_PathValue::FUNCTION ) ); ), (Static, if( e.static_ ) { if( e.static_->s_class() != ::AST::Static::CONST ) { - m_rv.reset( new ::HIR::ExprNode_PathValue( v.span(), LowerHIR_Path(Span(v.get_pos()), v.m_path), ::HIR::ExprNode_PathValue::STATIC ) ); + m_rv.reset( new ::HIR::ExprNode_PathValue( v.span(), LowerHIR_Path(v.span(), v.m_path), ::HIR::ExprNode_PathValue::STATIC ) ); } else { - m_rv.reset( new ::HIR::ExprNode_PathValue( v.span(), LowerHIR_Path(Span(v.get_pos()), v.m_path), ::HIR::ExprNode_PathValue::CONSTANT ) ); + m_rv.reset( new ::HIR::ExprNode_PathValue( v.span(), LowerHIR_Path(v.span(), v.m_path), ::HIR::ExprNode_PathValue::CONSTANT ) ); } } else if( e.hir ) { - m_rv.reset( new ::HIR::ExprNode_PathValue( v.span(), LowerHIR_Path(Span(v.get_pos()), v.m_path), ::HIR::ExprNode_PathValue::STATIC ) ); + m_rv.reset( new ::HIR::ExprNode_PathValue( v.span(), LowerHIR_Path(v.span(), v.m_path), ::HIR::ExprNode_PathValue::STATIC ) ); } // HACK: If the HIR pointer is nullptr, then it refers to a `const else { - m_rv.reset( new ::HIR::ExprNode_PathValue( v.span(), LowerHIR_Path(Span(v.get_pos()), v.m_path), ::HIR::ExprNode_PathValue::CONSTANT ) ); + m_rv.reset( new ::HIR::ExprNode_PathValue( v.span(), LowerHIR_Path(v.span(), v.m_path), ::HIR::ExprNode_PathValue::CONSTANT ) ); } ) ) @@ -739,7 +739,7 @@ struct LowerHIR_ExprNode_Visitor: const_cast<::AST::ExprNode*>(&e)->visit( v ); if( ! v.m_rv ) { - BUG(e.get_pos(), typeid(e).name() << " - Yielded a nullptr HIR node"); + BUG(e.span(), typeid(e).name() << " - Yielded a nullptr HIR node"); } return mv$( v.m_rv ); } diff --git a/src/include/span.hpp b/src/include/span.hpp index ddb08ae3..59c960fc 100644 --- a/src/include/span.hpp +++ b/src/include/span.hpp @@ -9,6 +9,7 @@ #include <rc_string.hpp> #include <functional> +#include <memory> enum ErrorType { @@ -30,7 +31,7 @@ struct ProtoSpan }; struct Span { - //::std::unique_ptr<Span> outer_span; // Expansion target for macros + ::std::shared_ptr<Span> outer_span; // Expansion target for macros RcString filename; unsigned int start_line; diff --git a/src/macro_rules/eval.cpp b/src/macro_rules/eval.cpp index 18ef563e..1bac45ee 100644 --- a/src/macro_rules/eval.cpp +++ b/src/macro_rules/eval.cpp @@ -618,9 +618,9 @@ bool Macro_TryPatternCap(TokenStream& lex, MacroPatEnt::Type type) switch(type) { case MacroPatEnt::PAT_TOKEN: - BUG(lex.getPosition(), ""); + BUG(lex.point_span(), ""); case MacroPatEnt::PAT_LOOP: - BUG(lex.getPosition(), ""); + BUG(lex.point_span(), ""); case MacroPatEnt::PAT_BLOCK: return LOOK_AHEAD(lex) == TOK_BRACE_OPEN || LOOK_AHEAD(lex) == TOK_INTERPOLATED_BLOCK; case MacroPatEnt::PAT_IDENT: @@ -651,7 +651,7 @@ bool Macro_TryPatternCap(TokenStream& lex, MacroPatEnt::Type type) case MacroPatEnt::PAT_ITEM: return is_token_item( LOOK_AHEAD(lex) ); } - BUG(lex.getPosition(), ""); + BUG(lex.point_span(), "Fell through"); } bool Macro_TryPattern(TokenStream& lex, const MacroPatEnt& pat) { @@ -680,9 +680,9 @@ InterpolatedFragment Macro_HandlePatternCap(TokenStream& lex, MacroPatEnt::Type switch(type) { case MacroPatEnt::PAT_TOKEN: - BUG(lex.getPosition(), "Encountered PAT_TOKEN when handling capture"); + BUG(lex.point_span(), "Encountered PAT_TOKEN when handling capture"); case MacroPatEnt::PAT_LOOP: - BUG(lex.getPosition(), "Encountered PAT_LOOP when handling capture"); + BUG(lex.point_span(), "Encountered PAT_LOOP when handling capture"); case MacroPatEnt::PAT_TT: if( GET_TOK(tok, lex) == TOK_EOF ) diff --git a/src/macro_rules/parse.cpp b/src/macro_rules/parse.cpp index 8264180f..1b7509fd 100644 --- a/src/macro_rules/parse.cpp +++ b/src/macro_rules/parse.cpp @@ -82,7 +82,7 @@ public: else if( type == "item" ) ret.push_back( MacroPatEnt(name, idx, MacroPatEnt::PAT_ITEM) ); else - ERROR(lex.getPosition(), E0000, "Unknown fragment type '" << type << "'"); + ERROR(lex.point_span(), E0000, "Unknown fragment type '" << type << "'"); break; } case TOK_PAREN_OPEN: { auto subpat = Parse_MacroRules_Pat(lex, TOK_PAREN_OPEN, TOK_PAREN_CLOSE, names); @@ -155,7 +155,7 @@ public: { DEBUG("depth--"); if(depth == 0) - ERROR(lex.getPosition(), E0000, "Unmatched " << Token(close) << " in macro content"); + ERROR(lex.point_span(), E0000, "Unmatched " << Token(close) << " in macro content"); depth --; } @@ -206,7 +206,7 @@ public: auto name = tok.type() == TOK_IDENT ? tok.str() : FMT(tok); unsigned int idx = ::std::find(var_names.begin(), var_names.end(), name) - var_names.begin(); if( idx == var_names.size() ) - ERROR(lex.getPosition(), E0000, "Macro variable $" << name << " not found"); + ERROR(lex.point_span(), E0000, "Macro variable $" << name << " not found"); if( var_set_ptr ) { var_set_ptr->insert( ::std::make_pair(idx,true) ); } diff --git a/src/parse/expr.cpp b/src/parse/expr.cpp index 28729b93..547e38e0 100644 --- a/src/parse/expr.cpp +++ b/src/parse/expr.cpp @@ -20,7 +20,8 @@ using AST::ExprNode; using AST::ExprNodeP; -static inline ExprNodeP mk_exprnodep(const TokenStream& lex, AST::ExprNode* en){en->set_pos(lex.getPosition()); return ExprNodeP(en); } +// TODO: Use a ProtoSpan +static inline ExprNodeP mk_exprnodep(const TokenStream& lex, AST::ExprNode* en){en->set_span(lex.point_span()); return ExprNodeP(en); } #define NEWNODE(type, ...) mk_exprnodep(lex, new type(__VA_ARGS__)) //ExprNodeP Parse_ExprBlockNode(TokenStream& lex, bool is_unsafe=false); // common.hpp @@ -552,7 +553,7 @@ ExprNodeP Parse_Stmt_Let(TokenStream& lex) { Token tok; AST::Pattern pat = Parse_Pattern(lex, false); // irrefutable - TypeRef type { lex.getPosition() }; + TypeRef type { lex.point_span() }; if( GET_TOK(tok, lex) == TOK_COLON ) { type = Parse_Type(lex); GET_TOK(tok, lex); @@ -969,7 +970,7 @@ ExprNodeP Parse_ExprVal_StructLiteral(TokenStream& lex, AST::Path path) GET_CHECK_TOK(tok, lex, TOK_COLON); ExprNodeP val = Parse_Stmt(lex); if( ! nodes.insert( ::std::make_pair(ofs, mv$(val)) ).second ) { - ERROR(lex.getPosition(), E0000, "Duplicate index"); + ERROR(lex.point_span(), E0000, "Duplicate index"); } if( GET_TOK(tok,lex) == TOK_BRACE_CLOSE ) @@ -983,7 +984,7 @@ ExprNodeP Parse_ExprVal_StructLiteral(TokenStream& lex, AST::Path path) for(auto& p : nodes) { if( p.first != i ) { - ERROR(lex.getPosition(), E0000, "Missing index " << i); + ERROR(lex.point_span(), E0000, "Missing index " << i); } items.push_back( mv$(p.second) ); i ++; @@ -1041,7 +1042,7 @@ ExprNodeP Parse_ExprVal_Closure(TokenStream& lex, bool is_move) // Irrefutable pattern AST::Pattern pat = Parse_Pattern(lex, false); - TypeRef type { lex.getPosition() }; + TypeRef type { lex.point_span() }; if( GET_TOK(tok, lex) == TOK_COLON ) type = Parse_Type(lex); else @@ -1054,7 +1055,7 @@ ExprNodeP Parse_ExprVal_Closure(TokenStream& lex, bool is_move) } CHECK_TOK(tok, TOK_PIPE); - auto rt = TypeRef(lex.getPosition()); + auto rt = TypeRef(lex.point_span()); if( GET_TOK(tok, lex) == TOK_THINARROW ) { if( GET_TOK(tok, lex) == TOK_EXCLAM ) { @@ -1264,8 +1265,9 @@ ExprNodeP Parse_ExprVal(TokenStream& lex) } ExprNodeP Parse_ExprMacro(TokenStream& lex, AST::Path path) { + ASSERT_BUG(lex.point_span(), path.is_trivial(), "TODO: Support path macros - " << path); + Token tok; - ASSERT_BUG(lex.getPosition(), path.is_trivial(), "TODO: Support path macros - " << path); ::std::string name = path.m_class.is_Local() ? path.m_class.as_Local().name : path.nodes()[0].name(); ::std::string ident; if( GET_TOK(tok, lex) == TOK_IDENT ) { diff --git a/src/parse/parseerror.cpp b/src/parse/parseerror.cpp index 3c5d41fe..1bb30985 100644 --- a/src/parse/parseerror.cpp +++ b/src/parse/parseerror.cpp @@ -19,13 +19,13 @@ CompileError::Generic::Generic(::std::string message): } CompileError::Generic::Generic(const TokenStream& lex, ::std::string message) { - ::std::cout << lex.getPosition() << ": Generic(" << message << ")" << ::std::endl; + ::std::cout << lex.point_span() << ": Generic(" << message << ")" << ::std::endl; } CompileError::BugCheck::BugCheck(const TokenStream& lex, ::std::string message): m_message(message) { - ::std::cout << lex.getPosition() << "BugCheck(" << message << ")" << ::std::endl; + ::std::cout << lex.point_span() << "BugCheck(" << message << ")" << ::std::endl; } CompileError::BugCheck::BugCheck(::std::string message): m_message(message) @@ -41,7 +41,7 @@ CompileError::Todo::Todo(::std::string message): CompileError::Todo::Todo(const TokenStream& lex, ::std::string message): m_message(message) { - ::std::cout << lex.getPosition() << ": Todo(" << message << ")" << ::std::endl; + ::std::cout << lex.point_span() << ": Todo(" << message << ")" << ::std::endl; } CompileError::Todo::~Todo() throw() { @@ -49,7 +49,7 @@ CompileError::Todo::~Todo() throw() ParseError::BadChar::BadChar(const TokenStream& lex, char character) { - ::std::cout << lex.getPosition() << ": BadChar(" << character << ")" << ::std::endl; + ::std::cout << lex.point_span() << ": BadChar(" << character << ")" << ::std::endl; } ParseError::BadChar::~BadChar() throw() { @@ -58,24 +58,24 @@ ParseError::BadChar::~BadChar() throw() ParseError::Unexpected::Unexpected(const TokenStream& lex, const Token& tok)//: // m_tok( mv$(tok) ) { - auto pos = tok.get_pos(); + Span pos = tok.get_pos(); if(pos.filename == "") - pos = lex.getPosition(); + pos = lex.point_span(); ::std::cout << pos << ": Unexpected(" << tok << ")" << ::std::endl; } ParseError::Unexpected::Unexpected(const TokenStream& lex, const Token& tok, Token exp)//: // m_tok( mv$(tok) ) { - auto pos = tok.get_pos(); + Span pos = tok.get_pos(); if(pos.filename == "") - pos = lex.getPosition(); + pos = lex.point_span(); ::std::cout << pos << ": Unexpected(" << tok << ", " << exp << ")" << ::std::endl; } ParseError::Unexpected::Unexpected(const TokenStream& lex, const Token& tok, ::std::vector<eTokenType> exp) { - auto pos = tok.get_pos(); + Span pos = tok.get_pos(); if(pos.filename == "") - pos = lex.getPosition(); + pos = lex.point_span(); ::std::cout << pos << ": Unexpected " << tok << ", expected "; bool f = true; for(auto v: exp) { diff --git a/src/parse/pattern.cpp b/src/parse/pattern.cpp index e9d086f9..974ff5fb 100644 --- a/src/parse/pattern.cpp +++ b/src/parse/pattern.cpp @@ -258,7 +258,7 @@ AST::Pattern Parse_PatternReal1(TokenStream& lex, bool is_refutable) return AST::Pattern( AST::Pattern::TagValue(), AST::Pattern::Value::make_Float({n->m_datatype, n->m_value}) ); } else { - TODO(lex.getPosition(), "Convert :expr into a pattern value - " << *e); + TODO(lex.point_span(), "Convert :expr into a pattern value - " << *e); } } break; @@ -414,7 +414,7 @@ AST::Pattern Parse_PatternStruct(TokenStream& lex, AST::Path path, bool is_refut GET_CHECK_TOK(tok, lex, TOK_COLON); auto val = Parse_Pattern(lex, is_refutable); if( ! pats.insert( ::std::make_pair(ofs, mv$(val)) ).second ) { - ERROR(lex.getPosition(), E0000, "Duplicate index"); + ERROR(lex.point_span(), E0000, "Duplicate index"); } if( GET_TOK(tok,lex) == TOK_BRACE_CLOSE ) @@ -435,7 +435,7 @@ AST::Pattern Parse_PatternStruct(TokenStream& lex, AST::Path path, bool is_refut { if( p.first != i ) { if( has_split || !split_allowed ) { - ERROR(lex.getPosition(), E0000, "Missing index " << i); + ERROR(lex.point_span(), E0000, "Missing index " << i); } has_split = true; i = p.first; diff --git a/src/parse/root.cpp b/src/parse/root.cpp index 5f8ed0a3..0790f05b 100644 --- a/src/parse/root.cpp +++ b/src/parse/root.cpp @@ -196,7 +196,7 @@ AST::GenericParams Parse_GenericParams(TokenStream& lex) ::std::string param_name = mv$(tok.str()); ret.add_ty_param( AST::TypeParam( param_name ) ); - auto param_ty = TypeRef(lex.getPosition(), param_name); + auto param_ty = TypeRef(lex.point_span(), param_name); if( GET_TOK(tok, lex) == TOK_COLON ) { Parse_TypeBound(lex, ret, mv$(param_ty)); @@ -382,7 +382,7 @@ AST::Function Parse_FunctionDef(TokenStream& lex, ::std::string abi, bool allow_ GET_TOK(tok, lex); if( allow_self == false ) throw ParseError::Generic(lex, "Self binding not expected"); - TypeRef ty = TypeRef( lex.getPosition(), "Self", 0xFFFF ); + TypeRef ty = TypeRef( lex.point_span(), "Self", 0xFFFF ); if( GET_TOK(tok, lex) == TOK_COLON ) { // Typed mut self ty = Parse_Type(lex); @@ -399,7 +399,7 @@ AST::Function Parse_FunctionDef(TokenStream& lex, ::std::string abi, bool allow_ // By-value method if( allow_self == false ) throw ParseError::Generic(lex, "Self binding not expected"); - TypeRef ty = TypeRef( lex.getPosition(), "Self", 0xFFFF ); + TypeRef ty = TypeRef( lex.point_span(), "Self", 0xFFFF ); if( GET_TOK(tok, lex) == TOK_COLON ) { // Typed mut self ty = Parse_Type(lex); @@ -723,14 +723,14 @@ AST::Trait Parse_TraitDef(TokenStream& lex, const AST::MetaItems& meta_items) if( GET_TOK(tok, lex) == TOK_COLON ) { // Bounded associated type - Parse_TypeBound(lex, atype_params, TypeRef(lex.getPosition(), "Self", 0xFFFF)); + Parse_TypeBound(lex, atype_params, TypeRef(lex.point_span(), "Self", 0xFFFF)); GET_TOK(tok, lex); } if( tok.type() == TOK_RWORD_WHERE ) { throw ParseError::Todo(lex, "Where clause on associated type"); } - TypeRef default_type = TypeRef( lex.getPosition() ); + TypeRef default_type = TypeRef( lex.point_span() ); if( tok.type() == TOK_EQUAL ) { default_type = Parse_Type(lex); GET_TOK(tok, lex); @@ -1049,7 +1049,7 @@ AST::MetaItem Parse_MetaItem(TokenStream& lex) if( GET_TOK(tok, lex) == TOK_DOUBLE_DOT ) { // Default impl - impl_type = TypeRef(TypeRef::TagInvalid(), lex.getPosition()); + impl_type = TypeRef(TypeRef::TagInvalid(), lex.point_span()); } else { @@ -1390,7 +1390,7 @@ void Parse_Use(TokenStream& lex, ::std::function<void(AST::UseStmt, ::std::strin else { PUTBACK(tok, lex); - ASSERT_BUG(lex.getPosition(), path.nodes().size() > 0, "`use` with no path"); + ASSERT_BUG(lex.point_span(), path.nodes().size() > 0, "`use` with no path"); name = path.nodes().back().name(); } @@ -1490,7 +1490,7 @@ bool Parse_MacroInvocation_Opt(TokenStream& lex, AST::MacroInvocation& out_inv) Parse_Use(lex, [&](AST::UseStmt p, std::string s) { DEBUG(mod_path << " - use " << p << " as '" << s << "'"); if( !item_data.is_None() ) - TODO(lex.getPosition(), "Encode multi-item use statements as a single Item"); + TODO(lex.point_span(), "Encode multi-item use statements as a single Item"); item_data = ::AST::Item(mv$(p)); item_name = mv$(s); }); @@ -1735,7 +1735,7 @@ bool Parse_MacroInvocation_Opt(TokenStream& lex, AST::MacroInvocation& out_inv) bool sub_file_controls_dir = true; if( mod_fileinfo.path == "-" ) { if( path_attr.size() ) { - ERROR(lex.getPosition(), E0000, "Cannot load module from file when reading stdin"); + ERROR(lex.point_span(), E0000, "Cannot load module from file when reading stdin"); } sub_path = "-"; } @@ -1779,11 +1779,11 @@ bool Parse_MacroInvocation_Opt(TokenStream& lex, AST::MacroInvocation& out_inv) break; case TOK_SEMICOLON: if( sub_path == "-" ) { - ERROR(lex.getPosition(), E0000, "Cannot load module from file when reading stdin"); + ERROR(lex.point_span(), E0000, "Cannot load module from file when reading stdin"); } else if( path_attr.size() == 0 && ! mod_fileinfo.controls_dir ) { - ERROR(lex.getPosition(), E0000, "Can't load from files outside of mod.rs or crate root"); + ERROR(lex.point_span(), E0000, "Can't load from files outside of mod.rs or crate root"); } else if( !H::check_item_cfg(meta_items) ) { // Ignore - emit Item::None @@ -1801,7 +1801,7 @@ bool Parse_MacroInvocation_Opt(TokenStream& lex, AST::MacroInvocation& out_inv) if( ifs_dir.is_open() && ifs_file.is_open() ) { // Collision - ERROR(lex.getPosition(), E0000, "Both modname.rs and modname/mod.rs exist"); + ERROR(lex.point_span(), E0000, "Both modname.rs and modname/mod.rs exist"); } else if( ifs_dir.is_open() ) { @@ -1815,7 +1815,7 @@ bool Parse_MacroInvocation_Opt(TokenStream& lex, AST::MacroInvocation& out_inv) else { // Can't find file - ERROR(lex.getPosition(), E0000, "Can't find file for '" << name << "' in '" << mod_fileinfo.path << "'"); + ERROR(lex.point_span(), E0000, "Can't find file for '" << name << "' in '" << mod_fileinfo.path << "'"); } DEBUG("- path = " << submod.m_file_info.path); Lexer sub_lex(submod.m_file_info.path); diff --git a/src/parse/tokenstream.cpp b/src/parse/tokenstream.cpp index 8cb9a910..2975a523 100644 --- a/src/parse/tokenstream.cpp +++ b/src/parse/tokenstream.cpp @@ -116,11 +116,15 @@ ProtoSpan TokenStream::start_span() const Span TokenStream::end_span(ProtoSpan ps) const { auto p = this->getPosition(); - return Span( - ps.filename, - ps.start_line, ps.start_ofs, - p.line, p.ofs - ); + auto rv = Span( ps.filename, ps.start_line, ps.start_ofs, p.line, p.ofs ); + rv.outer_span = this->outerSpan(); + return rv; +} +Span TokenStream::point_span() const +{ + Span rv = this->getPosition(); + rv.outer_span = this->outerSpan(); + return rv; } Ident TokenStream::get_ident(Token tok) const { diff --git a/src/parse/tokenstream.hpp b/src/parse/tokenstream.hpp index 85fc62e2..5f2e0733 100644 --- a/src/parse/tokenstream.hpp +++ b/src/parse/tokenstream.hpp @@ -60,17 +60,19 @@ public: void putback(Token tok); eTokenType lookahead(unsigned int count); - virtual Position getPosition() const = 0; Ident::Hygiene getHygiene() const; ParseState& parse_state() { return m_parse_state; } ProtoSpan start_span() const; Span end_span(ProtoSpan ps) const; + Span point_span() const; Ident get_ident(Token tok) const; protected: + virtual Position getPosition() const = 0; + virtual ::std::shared_ptr<Span> outerSpan() const { return ::std::shared_ptr<Span>(0); } virtual Token realGetToken() = 0; virtual Ident::Hygiene realGetHygiene() const = 0; private: diff --git a/src/parse/types.cpp b/src/parse/types.cpp index 905bd935..ff993693 100644 --- a/src/parse/types.cpp +++ b/src/parse/types.cpp @@ -218,7 +218,7 @@ TypeRef Parse_Type_Fn(TokenStream& lex, ::std::vector<::std::string> hrls) if( GET_TOK(tok, lex) == TOK_STRING ) { abi = tok.str(); if( abi == "" ) - ERROR(lex.getPosition(), E0000, "Empty ABI"); + ERROR(lex.point_span(), E0000, "Empty ABI"); GET_TOK(tok, lex); } else { diff --git a/src/resolve/absolute.cpp b/src/resolve/absolute.cpp index 26a45a1e..1e197769 100644 --- a/src/resolve/absolute.cpp +++ b/src/resolve/absolute.cpp @@ -1601,7 +1601,7 @@ void Resolve_Absolute_ExprNode(Context& context, ::AST::ExprNode& node) Resolve_Absolute_Pattern(this->context, true, node.m_pattern); break; case ::AST::ExprNode_Loop::FOR: - BUG(node.get_pos(), "`for` should be desugared"); + BUG(node.span(), "`for` should be desugared"); } node.m_code->visit( *this ); this->context.pop_block(); @@ -1629,22 +1629,22 @@ void Resolve_Absolute_ExprNode(Context& context, ::AST::ExprNode& node) } void visit(AST::ExprNode_StructLiteral& node) override { DEBUG("ExprNode_StructLiteral"); - Resolve_Absolute_Path(this->context, Span(node.get_pos()), Context::LookupMode::Type, node.m_path); + Resolve_Absolute_Path(this->context, node.span(), Context::LookupMode::Type, node.m_path); AST::NodeVisitorDef::visit(node); } void visit(AST::ExprNode_CallPath& node) override { DEBUG("ExprNode_CallPath"); - Resolve_Absolute_Path(this->context, Span(node.get_pos()), Context::LookupMode::Variable, node.m_path); + Resolve_Absolute_Path(this->context, node.span(), Context::LookupMode::Variable, node.m_path); AST::NodeVisitorDef::visit(node); } void visit(AST::ExprNode_CallMethod& node) override { DEBUG("ExprNode_CallMethod"); - Resolve_Absolute_PathParams(this->context, Span(node.get_pos()), node.m_method.args()); + Resolve_Absolute_PathParams(this->context, node.span(), node.m_method.args()); AST::NodeVisitorDef::visit(node); } void visit(AST::ExprNode_NamedValue& node) override { - DEBUG("(" << node.get_pos() << ") ExprNode_NamedValue - " << node.m_path); - Resolve_Absolute_Path(this->context, Span(node.get_pos()), Context::LookupMode::Variable, node.m_path); + DEBUG("(" << node.span() << ") ExprNode_NamedValue - " << node.m_path); + Resolve_Absolute_Path(this->context, node.span(), Context::LookupMode::Variable, node.m_path); } void visit(AST::ExprNode_Cast& node) override { DEBUG("ExprNode_Cast"); diff --git a/src/span.cpp b/src/span.cpp index 29d7201b..8d176671 100644 --- a/src/span.cpp +++ b/src/span.cpp @@ -12,6 +12,7 @@ #include <common.hpp> Span::Span(const Span& x): + outer_span(x.outer_span), filename(x.filename), start_line(x.start_line), start_ofs(x.start_ofs), @@ -20,6 +21,7 @@ Span::Span(const Span& x): { } Span::Span(const Position& pos): + outer_span(), filename(pos.filename), start_line(pos.line), start_ofs(pos.ofs), @@ -28,6 +30,7 @@ Span::Span(const Position& pos): { } Span::Span(): + outer_span(), filename("")/*, start_line(0), start_ofs(0), end_line(0), end_ofs(0) // */ |