summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@ucc.asn.au>2017-06-11 11:34:16 +0800
committerJohn Hodge <tpg@ucc.asn.au>2017-06-11 11:34:16 +0800
commit52d872b36d7fda733273d70100d21b16506f1647 (patch)
tree5f192e2650a0f15893546d484fcc6537786e6a46
parentc211c01437ce248d654b0d6ba9b739d1633cce68 (diff)
downloadmrust-52d872b36d7fda733273d70100d21b16506f1647.tar.gz
Parse - Support chaining of spans (for macro expansions)
-rw-r--r--src/ast/expr.cpp8
-rw-r--r--src/ast/expr.hpp7
-rw-r--r--src/expand/mod.cpp8
-rw-r--r--src/hir/from_ast_expr.cpp46
-rw-r--r--src/include/span.hpp3
-rw-r--r--src/macro_rules/eval.cpp10
-rw-r--r--src/macro_rules/parse.cpp6
-rw-r--r--src/parse/expr.cpp16
-rw-r--r--src/parse/parseerror.cpp20
-rw-r--r--src/parse/pattern.cpp6
-rw-r--r--src/parse/root.cpp26
-rw-r--r--src/parse/tokenstream.cpp14
-rw-r--r--src/parse/tokenstream.hpp4
-rw-r--r--src/parse/types.cpp2
-rw-r--r--src/resolve/absolute.cpp12
-rw-r--r--src/span.cpp3
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) // */