summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2015-09-06 18:08:38 +0800
committerJohn Hodge <tpg@mutabah.net>2015-09-06 18:08:38 +0800
commit03e211d6eeb3f8f3c6f0b22f77c2074e81443952 (patch)
tree5e07ee69f9020e829e79fb700fa2f35e602b0bcb
parent0b6d7c51056ed7b8eb25af6041c4feb5e6e23051 (diff)
downloadmrust-03e211d6eeb3f8f3c6f0b22f77c2074e81443952.tar.gz
Rough span support
-rw-r--r--Makefile1
-rw-r--r--src/ast/path.cpp8
-rw-r--r--src/ast/path.hpp47
-rw-r--r--src/ast/provided_module.cpp4
-rw-r--r--src/convert/ast_iterate.cpp2
-rw-r--r--src/convert/decorators.cpp2
-rw-r--r--src/convert/resolve.cpp14
-rw-r--r--src/convert/typecheck_bounds.cpp2
-rw-r--r--src/convert/typecheck_expr.cpp2
-rw-r--r--src/convert/typecheck_params.cpp2
-rw-r--r--src/include/span.hpp56
-rw-r--r--src/macros.cpp6
-rw-r--r--src/parse/common.hpp2
-rw-r--r--src/parse/expr.cpp4
-rw-r--r--src/parse/lex.cpp32
-rw-r--r--src/parse/lex.hpp25
-rw-r--r--src/parse/paths.cpp25
-rw-r--r--src/parse/root.cpp13
-rw-r--r--src/parse/types.cpp13
-rw-r--r--src/span.cpp37
-rw-r--r--src/types.hpp5
21 files changed, 222 insertions, 80 deletions
diff --git a/Makefile b/Makefile
index 44611658..ce0209b8 100644
--- a/Makefile
+++ b/Makefile
@@ -16,6 +16,7 @@ OBJDIR = .obj/
BIN := bin/mrustc$(EXESUF)
OBJ := main.o macros.o types.o serialise.o
+OBJ += span.o
OBJ += ast/ast.o ast/path.o ast/expr.o ast/pattern.o
OBJ += ast/provided_module.o
OBJ += parse/parseerror.o parse/lex.o
diff --git a/src/ast/path.cpp b/src/ast/path.cpp
index 971cc657..247a6b2b 100644
--- a/src/ast/path.cpp
+++ b/src/ast/path.cpp
@@ -83,13 +83,14 @@ typename ::std::vector<Item<T> >::const_iterator find_named(const ::std::vector<
}
// --- AST::Path
-AST::Path::Path(TagUfcs, TypeRef type, TypeRef trait):
- m_class( AST::Path::Class::make_UFCS({box$(type), box$(trait), {}}) )
+AST::Path::Path(TagUfcs, TypeRef type, TypeRef trait, ::std::vector<AST::PathNode> nodes):
+ m_class( AST::Path::Class::make_UFCS({box$(type), box$(trait), nodes}) )
{
}
AST::Path::Path(const Path& x):
m_crate(x.m_crate),
- m_class()
+ m_class(),
+ m_span(x.m_span)
//m_binding(x.m_binding)
{
TU_MATCH(Class, (x.m_class), (ent),
@@ -850,6 +851,7 @@ void Path::print_pretty(::std::ostream& os) const
os << "::" << n;
)
)
+ os << "/*[" << path.span().filename << ":" << path.span().start_line << "]*/";
#else
switch(path.m_class)
{
diff --git a/src/ast/path.hpp b/src/ast/path.hpp
index 0fa4ff04..9e190453 100644
--- a/src/ast/path.hpp
+++ b/src/ast/path.hpp
@@ -12,6 +12,7 @@
#include <serialise.hpp>
#include <tagged_union.hpp>
#include <string>
+#include "../include/span.hpp"
class TypeRef;
@@ -130,6 +131,7 @@ private:
public:
Class m_class;
+ Span m_span;
private:
PathBinding m_binding;
@@ -139,18 +141,17 @@ public:
m_class()
{}
Path(Path&&) noexcept = default;
- Path& operator=(AST::Path&&) = default;
+ Path& operator=(AST::Path&& x) {
+ m_crate = mv$(x.m_crate);
+ m_class = mv$(x.m_class);
+ //m_span = mv$(x.m_span);
+ x.m_binding = mv$(x.m_binding);
+ return *this;
+ }
Path(const Path& x);
// ABSOLUTE
- struct TagAbsolute {};
- Path(TagAbsolute):
- m_class( Class::make_Absolute({}) )
- {}
- Path(::std::initializer_list<PathNode> l):
- Path("", l)
- {}
Path(::std::string crate, ::std::vector<PathNode> nodes):
m_crate( ::std::move(crate) ),
m_class( Class::make_Absolute({nodes: mv$(nodes)}) )
@@ -158,7 +159,7 @@ public:
// UFCS
struct TagUfcs {};
- Path(TagUfcs, TypeRef type, TypeRef trait);
+ Path(TagUfcs, TypeRef type, TypeRef trait, ::std::vector<PathNode> nodes={});
// VARIABLE
struct TagLocal {};
@@ -171,18 +172,18 @@ public:
// RELATIVE
struct TagRelative {};
- Path(TagRelative):
- m_class( Class::make_Relative({}) )
+ Path(TagRelative, ::std::vector<PathNode> nodes):
+ m_class( Class::make_Relative({nodes: mv$(nodes)}) )
{}
// SELF
struct TagSelf {};
- Path(TagSelf):
- m_class( Class::make_Self({}) )
+ Path(TagSelf, ::std::vector<PathNode> nodes):
+ m_class( Class::make_Self({nodes: nodes}) )
{}
// SUPER
struct TagSuper {};
- Path(TagSuper):
- m_class( Class::make_Super({}) )
+ Path(TagSuper, ::std::vector<PathNode> nodes):
+ m_class( Class::make_Super({nodes: nodes}) )
{}
void set_crate(::std::string crate) {
@@ -191,6 +192,12 @@ public:
DEBUG("crate set to " << m_crate);
}
}
+ void set_span(Span sp) {
+ this->m_span = sp;
+ }
+ const Span& span() const {
+ return this->m_span;
+ }
Class::Tag class_tag() const {
@@ -222,14 +229,14 @@ public:
m_binding = PathBinding();
}
Path operator+(PathNode&& pn) const {
- Path tmp = Path(TagRelative());
- tmp.append( ::std::move(pn) );
- return Path(*this) += tmp;
+ Path tmp = Path(*this);
+ tmp.nodes().push_back( pn );
+ return tmp;
}
Path operator+(const ::std::string& s) const {
- Path tmp = Path(TagRelative());
+ Path tmp = Path(*this);
tmp.append(PathNode(s, {}));
- return Path(*this) += tmp;
+ return tmp;
}
Path operator+(const Path& x) const {
return Path(*this) += x;
diff --git a/src/ast/provided_module.cpp b/src/ast/provided_module.cpp
index 460b7494..fc006020 100644
--- a/src/ast/provided_module.cpp
+++ b/src/ast/provided_module.cpp
@@ -23,11 +23,11 @@ void AST_InitProvidedModule()
void AST_InitProvidedModule_Impls()
{
if( !g_copy_marker_path.is_valid() ) {
- g_copy_marker_path = AST::Path( {AST::PathNode("marker"),AST::PathNode("Copy")} );
+ g_copy_marker_path = AST::Path( "", {AST::PathNode("marker"),AST::PathNode("Copy")} );
}
if( !g_sized_marker_path.is_valid() ) {
- g_sized_marker_path = AST::Path( {AST::PathNode("marker"),AST::PathNode("Sized")} );
+ g_sized_marker_path = AST::Path( "", {AST::PathNode("marker"),AST::PathNode("Sized")} );
}
#define impl(trait, type) \
diff --git a/src/convert/ast_iterate.cpp b/src/convert/ast_iterate.cpp
index a61dd553..cdb927e6 100644
--- a/src/convert/ast_iterate.cpp
+++ b/src/convert/ast_iterate.cpp
@@ -377,7 +377,7 @@ void CASTIterator::handle_impl(AST::Path modpath, AST::Impl& impl)
for( auto& fcn : impl.functions() )
{
DEBUG("- Function '" << fcn.name << "'");
- handle_function(AST::Path(AST::Path::TagRelative()) + fcn.name, fcn.data);
+ handle_function(AST::Path(AST::Path::TagRelative(), { AST::PathNode(fcn.name) }), fcn.data);
}
end_scope();
diff --git a/src/convert/decorators.cpp b/src/convert/decorators.cpp
index 8f9bb461..267f9dc7 100644
--- a/src/convert/decorators.cpp
+++ b/src/convert/decorators.cpp
@@ -72,6 +72,6 @@ void Process_Decorators(AST::Crate& crate)
{
CProcessor processor(crate);
- processor.handle_module(AST::Path({}), crate.root_module());
+ processor.handle_module(AST::Path("", {}), crate.root_module());
}
diff --git a/src/convert/resolve.cpp b/src/convert/resolve.cpp
index 9725549c..bdbf1854 100644
--- a/src/convert/resolve.cpp
+++ b/src/convert/resolve.cpp
@@ -865,8 +865,11 @@ void CPathResolver::handle_type(TypeRef& type)
else if( name == "Self" )
{
// If the name was "Self", but Self isn't already defined... then we need to make it an arg?
- throw CompileError::Generic( FMT("CPathResolver::handle_type - Unexpected 'Self'") );
- type = TypeRef(TypeRef::TagArg(), "Self");
+ ERROR(type.path().span(), E0000, "Unexpected 'Self'");
+
+ TypeRef nt = TypeRef(TypeRef::TagArg(), "Self");
+ nt.set_span(type.span());
+ type = nt;
}
else
{
@@ -930,8 +933,7 @@ void CPathResolver::handle_pattern(AST::Pattern& pat, const TypeRef& type_hint)
::std::string name = pat.binding();
// Locate a _constant_ within the current namespace which matches this name
// - Variables don't count
- AST::Path newpath = AST::Path(AST::Path::TagRelative());
- newpath.append(name);
+ AST::Path newpath = AST::Path(AST::Path::TagRelative(), { AST::PathNode(name) });
handle_path(newpath, CASTIterator::MODE_BIND);
if( newpath.is_relative() )
{
@@ -1096,12 +1098,12 @@ void ResolvePaths(AST::Crate& crate)
// Handle 'use' statements in an initial parss
DEBUG(" --- Use Statements");
INDENT();
- ResolvePaths_HandleModule_Use(crate, AST::Path(AST::Path::TagAbsolute()), crate.root_module());
+ ResolvePaths_HandleModule_Use(crate, AST::Path("", {}), crate.root_module());
UNINDENT();
// Then do path resolution on all other items
CPathResolver pr(crate);
DEBUG(" ---");
- pr.handle_module(AST::Path(AST::Path::TagAbsolute()), crate.root_module());
+ pr.handle_module(AST::Path("", {}), crate.root_module());
DEBUG(" <<<");
}
diff --git a/src/convert/typecheck_bounds.cpp b/src/convert/typecheck_bounds.cpp
index 7b89453d..ed3ae1e2 100644
--- a/src/convert/typecheck_bounds.cpp
+++ b/src/convert/typecheck_bounds.cpp
@@ -52,6 +52,6 @@ void Typecheck_GenericBounds(AST::Crate& crate)
{
DEBUG(" --- ");
CGenericBoundChecker chk;
- chk.handle_module(AST::Path({}), crate.root_module());
+ chk.handle_module(AST::Path("", {}), crate.root_module());
}
diff --git a/src/convert/typecheck_expr.cpp b/src/convert/typecheck_expr.cpp
index 876c8e4f..16aaf62d 100644
--- a/src/convert/typecheck_expr.cpp
+++ b/src/convert/typecheck_expr.cpp
@@ -611,7 +611,7 @@ void Typecheck_Expr(AST::Crate& crate)
{
DEBUG(" >>>");
CTypeChecker tc(crate);
- tc.handle_module(AST::Path({}), crate.root_module());
+ tc.handle_module(AST::Path("", {}), crate.root_module());
DEBUG(" <<<");
}
diff --git a/src/convert/typecheck_params.cpp b/src/convert/typecheck_params.cpp
index f195c811..eba02653 100644
--- a/src/convert/typecheck_params.cpp
+++ b/src/convert/typecheck_params.cpp
@@ -337,7 +337,7 @@ void Typecheck_GenericParams(AST::Crate& crate)
{
DEBUG(" >>> ");
CGenericParamChecker chk(crate);
- chk.handle_module(AST::Path({}), crate.root_module());
+ chk.handle_module(AST::Path("", {}), crate.root_module());
DEBUG(" <<< ");
}
diff --git a/src/include/span.hpp b/src/include/span.hpp
new file mode 100644
index 00000000..c8c61627
--- /dev/null
+++ b/src/include/span.hpp
@@ -0,0 +1,56 @@
+/*
+ * MRustC - Rust Compiler
+ * - By John Hodge (Mutabah/thePowersGang)
+ *
+ * include/span.hpp
+ * - Spans and error handling
+ */
+
+#pragma once
+
+enum ErrorType
+{
+ E0000,
+};
+enum WarningType
+{
+ W0000,
+};
+
+struct ProtoSpan
+{
+ ::std::string filename;
+
+ unsigned int start_line;
+ unsigned int start_ofs;
+};
+struct Span
+{
+ ::std::string filename;
+
+ unsigned int start_line;
+ unsigned int start_ofs;
+ unsigned int end_line;
+ unsigned int end_ofs;
+
+ Span(::std::string filename, unsigned int start_line, unsigned int start_ofs, unsigned int end_line, unsigned int end_ofs):
+ filename(filename),
+ start_line(start_line),
+ start_ofs(start_ofs),
+ end_line(end_line),
+ end_ofs(end_ofs)
+ {}
+ Span():
+ filename(""),
+ start_line(0), start_ofs(0),
+ end_line(0), end_ofs(0)
+ {}
+
+ void bug(::std::function<void(::std::ostream&)> msg) const;
+ void error(ErrorType tag, ::std::function<void(::std::ostream&)> msg) const;
+ void warning(WarningType tag, ::std::function<void(::std::ostream&)> msg) const;
+ void note(::std::function<void(::std::ostream&)> msg) const;
+};
+
+#define ERROR(span, code, msg) do { (span).error(code, [](::std::ostream& os) { os << msg; }); throw ::std::runtime_error("Error fell through" #code); } while(0)
+
diff --git a/src/macros.cpp b/src/macros.cpp
index da149aef..d7d30f4e 100644
--- a/src/macros.cpp
+++ b/src/macros.cpp
@@ -480,7 +480,7 @@ bool Macro_HandlePattern(TTStream& lex, const MacroPatEnt& pat, unsigned int lay
Position MacroExpander::getPosition() const
{
DEBUG("olex.getPosition() = " << m_olex.getPosition());
- return Position(FMT("Macro:" << ""), m_offsets[0].read_pos);
+ return Position(FMT("Macro:" << ""), 0, m_offsets[0].read_pos);
}
Token MacroExpander::realGetToken()
{
@@ -786,7 +786,7 @@ MacroToken::MacroToken(Token tok):
}
Position MacroToken::getPosition() const
{
- return Position("MacroToken", 0);
+ return Position("MacroToken", 0, 0);
}
Token MacroToken::realGetToken()
{
@@ -810,7 +810,7 @@ MacroStringify::MacroStringify(const TokenTree& input)
}
Position MacroStringify::getPosition() const
{
- return Position("Stringify", 0);
+ return Position("Stringify", 0,0);
}
Token MacroStringify::realGetToken()
{
diff --git a/src/parse/common.hpp b/src/parse/common.hpp
index 3372b608..e24ef82b 100644
--- a/src/parse/common.hpp
+++ b/src/parse/common.hpp
@@ -34,7 +34,7 @@ enum eParsePathGenericMode
};
extern AST::Path Parse_Path(TokenStream& lex, eParsePathGenericMode generic_mode); // Auto-determines
extern AST::Path Parse_Path(TokenStream& lex, bool is_abs, eParsePathGenericMode generic_mode);
-extern AST::Path Parse_PathFrom(TokenStream& lex, AST::Path src, eParsePathGenericMode generic_mode);
+extern ::std::vector<AST::PathNode> Parse_PathNodes(TokenStream& lex, eParsePathGenericMode generic_mode);
extern ::std::vector<TypeRef> Parse_Path_GenericList(TokenStream& lex);
diff --git a/src/parse/expr.cpp b/src/parse/expr.cpp
index eb53ac98..285531eb 100644
--- a/src/parse/expr.cpp
+++ b/src/parse/expr.cpp
@@ -995,7 +995,7 @@ ExprNodeP Parse_ExprVal(TokenStream& lex)
GET_CHECK_TOK(tok, lex, TOK_GT);
// TODO: Terminating the "path" here is sometimes valid
GET_CHECK_TOK(tok, lex, TOK_DOUBLE_COLON);
- path = Parse_PathFrom(lex, AST::Path(AST::Path::TagUfcs(), ty, trait), PATH_GENERIC_EXPR);
+ path = AST::Path(AST::Path::TagUfcs(), ty, trait, Parse_PathNodes(lex, PATH_GENERIC_EXPR));
}
if(0)
case TOK_RWORD_SELF:
@@ -1013,7 +1013,7 @@ ExprNodeP Parse_ExprVal(TokenStream& lex)
case TOK_RWORD_SUPER:
{
GET_CHECK_TOK(tok, lex, TOK_DOUBLE_COLON);
- path = Parse_PathFrom(lex, AST::Path(AST::Path::TagSuper()), PATH_GENERIC_EXPR);
+ path = AST::Path(AST::Path::TagSuper(), Parse_PathNodes(lex, PATH_GENERIC_EXPR));
}
if(0)
case TOK_IDENT:
diff --git a/src/parse/lex.cpp b/src/parse/lex.cpp
index cac8f511..9855e3c0 100644
--- a/src/parse/lex.cpp
+++ b/src/parse/lex.cpp
@@ -22,6 +22,7 @@
Lexer::Lexer(::std::string filename):
m_path(filename),
m_line(1),
+ m_line_ofs(0),
m_istream(filename.c_str()),
m_last_char_valid(false)
{
@@ -212,7 +213,7 @@ bool issym(char ch)
Position Lexer::getPosition() const
{
- return Position(m_path, m_line);
+ return Position(m_path, m_line, m_line_ofs);
}
Token Lexer::realGetToken()
{
@@ -224,6 +225,7 @@ Token Lexer::realGetToken()
{
case TOK_NEWLINE:
m_line ++;
+ m_line_ofs = 0;
//DEBUG("m_line = " << m_line << " (NL)");
continue;
case TOK_WHITESPACE:
@@ -644,9 +646,10 @@ char Lexer::getc()
}
else
{
- m_last_char = m_istream.get();
- if( m_istream.eof() )
- throw Lexer::EndOfFile();
+ m_last_char = m_istream.get();
+ m_line_ofs += 1;
+ if( m_istream.eof() )
+ throw Lexer::EndOfFile();
}
//::std::cout << "getc(): '" << m_last_char << "'" << ::std::endl;
return m_last_char;
@@ -943,7 +946,7 @@ Token TTStream::realGetToken()
}
Position TTStream::getPosition() const
{
- return Position("TTStream", 0);
+ return Position("TTStream", 0,0);
}
TokenStream::TokenStream():
@@ -1021,3 +1024,22 @@ eTokenType TokenStream::lookahead(unsigned int i)
return m_lookahead[i].type();
}
+ProtoSpan TokenStream::start_span() const
+{
+ auto p = this->getPosition();
+ return ProtoSpan {
+ .filename = p.filename,
+ .start_line = p.line,
+ .start_ofs = p.ofs,
+ };
+}
+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
+ );
+}
+
diff --git a/src/parse/lex.hpp b/src/parse/lex.hpp
index f2e268ac..30500ba2 100644
--- a/src/parse/lex.hpp
+++ b/src/parse/lex.hpp
@@ -12,6 +12,8 @@
#include <string>
#include <fstream>
+#include "../include/span.hpp"
+
enum eTokenType
{
#define _(t) t,
@@ -23,29 +25,22 @@ struct Position
{
::std::string filename;
unsigned int line;
+ unsigned int ofs;
Position():
filename(""),
- line(0)
+ line(0),
+ ofs(0)
{}
- Position(::std::string filename, unsigned int line):
+ Position(::std::string filename, unsigned int line, unsigned int ofs):
filename(filename),
- line(line)
+ line(line),
+ ofs(ofs)
{
}
};
extern ::std::ostream& operator<<(::std::ostream& os, const Position& p);
-struct Span
-{
- ::std::string filename;
-
- unsigned int start_line;
- unsigned int start_ofs;
- unsigned int end_line;
- unsigned int end_ofs;
-};
-
class Token:
public Serialisable
{
@@ -147,6 +142,9 @@ public:
ParseState& parse_state() { return m_parse_state; }
+ ProtoSpan start_span() const;
+ Span end_span(ProtoSpan ps) const;
+
protected:
virtual Token realGetToken() = 0;
private:
@@ -179,6 +177,7 @@ class Lexer:
{
::std::string m_path;
unsigned int m_line;
+ unsigned int m_line_ofs;
::std::ifstream m_istream;
bool m_last_char_valid;
diff --git a/src/parse/paths.cpp b/src/parse/paths.cpp
index 43346172..f867e244 100644
--- a/src/parse/paths.cpp
+++ b/src/parse/paths.cpp
@@ -11,7 +11,7 @@
AST::Path Parse_Path(TokenStream& lex, eParsePathGenericMode generic_mode);
AST::Path Parse_Path(TokenStream& lex, bool is_abs, eParsePathGenericMode generic_mode);
-AST::Path Parse_PathFrom(TokenStream& lex, AST::Path path, eParsePathGenericMode generic_mode);
+::std::vector<AST::PathNode> Parse_PathNodes(TokenStream& lex, eParsePathGenericMode generic_mode);
::std::vector<TypeRef> Parse_Path_GenericList(TokenStream& lex);
AST::Path Parse_Path(TokenStream& lex, eParsePathGenericMode generic_mode)
@@ -32,7 +32,7 @@ AST::Path Parse_Path(TokenStream& lex, eParsePathGenericMode generic_mode)
GET_CHECK_TOK(tok, lex, TOK_GT);
// TODO: Terminating the "path" here is sometimes valid
GET_CHECK_TOK(tok, lex, TOK_DOUBLE_COLON);
- return Parse_PathFrom(lex, AST::Path(AST::Path::TagUfcs(), ty, trait), PATH_GENERIC_EXPR);
+ return AST::Path(AST::Path::TagUfcs(), ty, trait, Parse_PathNodes(lex, PATH_GENERIC_EXPR));
}
default:
lex.putback(tok);
@@ -47,11 +47,11 @@ AST::Path Parse_Path(TokenStream& lex, bool is_abs, eParsePathGenericMode generi
if( GET_TOK(tok, lex) == TOK_STRING ) {
::std::string cratename = tok.str();
GET_CHECK_TOK(tok, lex, TOK_DOUBLE_COLON);
- return Parse_PathFrom(lex, AST::Path(cratename, {}), generic_mode);
+ return AST::Path(cratename, Parse_PathNodes(lex, generic_mode));
}
else {
lex.putback(tok);
- return Parse_PathFrom(lex, AST::Path(AST::Path::TagAbsolute()), generic_mode);
+ return AST::Path("", Parse_PathNodes(lex, generic_mode));
}
}
else {
@@ -61,16 +61,15 @@ AST::Path Parse_Path(TokenStream& lex, bool is_abs, eParsePathGenericMode generi
//}
//else {
// lex.putback(tok);
- return Parse_PathFrom(lex, AST::Path(AST::Path::TagRelative()), generic_mode);
+ return AST::Path(AST::Path::TagRelative(), Parse_PathNodes(lex, generic_mode));
//}
}
}
-AST::Path Parse_PathFrom(TokenStream& lex, AST::Path path, eParsePathGenericMode generic_mode)
+::std::vector<AST::PathNode> Parse_PathNodes(TokenStream& lex, eParsePathGenericMode generic_mode)
{
- TRACE_FUNCTION_F("path = " << path);
-
Token tok;
+ ::std::vector<AST::PathNode> ret;
tok = lex.getToken();
while(true)
@@ -131,7 +130,7 @@ AST::Path Parse_PathFrom(TokenStream& lex, AST::Path path, eParsePathGenericMode
}
}
if( tok.type() != TOK_DOUBLE_COLON ) {
- path.append( AST::PathNode(component, params) );
+ ret.push_back( AST::PathNode(component, params) );
break;
}
tok = lex.getToken();
@@ -145,19 +144,19 @@ AST::Path Parse_PathFrom(TokenStream& lex, AST::Path path, eParsePathGenericMode
params = Parse_Path_GenericList(lex);
tok = lex.getToken();
if( tok.type() != TOK_DOUBLE_COLON ) {
- path.append( AST::PathNode(component, params) );
+ ret.push_back( AST::PathNode(component, params) );
break;
}
GET_TOK(tok, lex);
}
- path.append( AST::PathNode(component, params) );
+ ret.push_back( AST::PathNode(component, params) );
}
lex.putback(tok);
//if( path.is_trivial() ) {
// path = AST::Path(path[0].name());
//}
- DEBUG("path = " << path);
- return path;
+ DEBUG("ret = " << ret);
+ return ret;
}
/// Parse a list of parameters within a path
::std::vector<TypeRef> Parse_Path_GenericList(TokenStream& lex)
diff --git a/src/parse/root.cpp b/src/parse/root.cpp
index 832aa209..422f036e 100644
--- a/src/parse/root.cpp
+++ b/src/parse/root.cpp
@@ -541,7 +541,7 @@ AST::Trait Parse_TraitDef(TokenStream& lex, const AST::MetaItems& meta_items)
if( GET_TOK(tok, lex) == TOK_COLON )
{
// Bounded associated type
- TypeRef a_type = TypeRef( AST::Path(AST::Path::TagUfcs(), TypeRef(TypeRef::TagArg(), "Self"), TypeRef())+ name);
+ TypeRef a_type = TypeRef( AST::Path(AST::Path::TagUfcs(), TypeRef(TypeRef::TagArg(), "Self"), TypeRef(), {AST::PathNode(name)}) );
//TypeRef a_type = TypeRef(TypeRef::TagAssoc(), TypeRef(TypeRef::TagArg(), "Self"), TypeRef(), name);
Parse_TypeBound(lex, params, a_type);
GET_TOK(tok, lex);
@@ -942,16 +942,17 @@ void Parse_Use(TokenStream& lex, ::std::function<void(AST::Path, ::std::string)>
TRACE_FUNCTION;
Token tok;
- AST::Path path = AST::Path(AST::Path::TagAbsolute());
+ AST::Path path = AST::Path("", {});
::std::vector<AST::PathNode> nodes;
+ ProtoSpan span_start = lex.start_span();
switch( GET_TOK(tok, lex) )
{
case TOK_RWORD_SELF:
- path = AST::Path( AST::Path::TagSelf() ); // relative path
+ path = AST::Path( AST::Path::TagSelf(), {} ); // relative path
break;
case TOK_RWORD_SUPER:
- path = AST::Path( AST::Path::TagSuper() );
+ path = AST::Path( AST::Path::TagSuper(), {} );
break;
case TOK_IDENT:
path.append( AST::PathNode(tok.str(), {}) );
@@ -985,10 +986,11 @@ void Parse_Use(TokenStream& lex, ::std::function<void(AST::Path, ::std::string)>
}
else
{
+ path.set_span( lex.end_span(span_start) );
switch( tok.type() )
{
case TOK_BRACE_OPEN:
- Parse_Use_Set(lex, path, fcn);
+ Parse_Use_Set(lex, mv$(path), fcn);
GET_CHECK_TOK(tok, lex, TOK_BRACE_CLOSE);
break ;
case TOK_STAR:
@@ -1001,6 +1003,7 @@ void Parse_Use(TokenStream& lex, ::std::function<void(AST::Path, ::std::string)>
return ;
}
}
+ path.set_span( lex.end_span(span_start) );
::std::string name;
// This should only be allowed if the last token was an ident
diff --git a/src/parse/types.cpp b/src/parse/types.cpp
index 95076e29..7777de79 100644
--- a/src/parse/types.cpp
+++ b/src/parse/types.cpp
@@ -35,11 +35,20 @@ static const struct {
// === PROTOTYPES ===
TypeRef Parse_Type(TokenStream& lex);
+TypeRef Parse_Type_Int(TokenStream& lex);
TypeRef Parse_Type_Fn(TokenStream& lex);
// === CODE ===
TypeRef Parse_Type(TokenStream& lex)
{
+ ProtoSpan ps = lex.start_span();
+ TypeRef rv = Parse_Type_Int(lex);
+ rv.set_span(lex.end_span(ps));
+ return rv;
+}
+
+TypeRef Parse_Type_Int(TokenStream& lex)
+{
//TRACE_FUNCTION;
Token tok;
@@ -97,7 +106,7 @@ TypeRef Parse_Type(TokenStream& lex)
if( tok.str() == "str" )
{
// TODO: Create an internal newtype for 'str'
- return TypeRef(TypeRef::TagPath(), AST::Path({ AST::PathNode("#",{}), AST::PathNode("str",{}) }));
+ return TypeRef(TypeRef::TagPath(), AST::Path("", { AST::PathNode("#",{}), AST::PathNode("str",{}) }));
}
// - Fall through to path handling
// '::' - Absolute path
@@ -125,7 +134,7 @@ TypeRef Parse_Type(TokenStream& lex)
// 'super' - Parent relative path
case TOK_RWORD_SUPER:
GET_CHECK_TOK(tok, lex, TOK_DOUBLE_COLON);
- return TypeRef(TypeRef::TagPath(), Parse_PathFrom(lex, AST::Path(AST::Path::TagSuper()), PATH_GENERIC_TYPE));
+ return TypeRef(TypeRef::TagPath(), AST::Path(AST::Path::TagSuper(), Parse_PathNodes(lex, PATH_GENERIC_TYPE)));
// HACK! Convert && into & &
case TOK_DOUBLE_AMP:
diff --git a/src/span.cpp b/src/span.cpp
new file mode 100644
index 00000000..e3458c8b
--- /dev/null
+++ b/src/span.cpp
@@ -0,0 +1,37 @@
+/*
+ * MRustC - Rust Compiler
+ * - By John Hodge (Mutabah/thePowersGang)
+ *
+ * span.cpp
+ * - Spans and error handling
+ */
+#include <functional>
+#include <iostream>
+#include <span.hpp>
+
+void Span::bug(::std::function<void(::std::ostream&)> msg) const
+{
+ ::std::cerr << this->filename << ":" << this->start_line << ": BUG:";
+ msg(::std::cerr);
+ ::std::cerr << ::std::endl;
+ abort();
+}
+
+void Span::error(ErrorType tag, ::std::function<void(::std::ostream&)> msg) const {
+ ::std::cerr << this->filename << ":" << this->start_line << ": error:";
+ msg(::std::cerr);
+ ::std::cerr << ::std::endl;
+ abort();
+}
+void Span::warning(WarningType tag, ::std::function<void(::std::ostream&)> msg) const {
+ ::std::cerr << this->filename << ":" << this->start_line << ": warning:";
+ msg(::std::cerr);
+ ::std::cerr << ::std::endl;
+ //abort();
+}
+void Span::note(::std::function<void(::std::ostream&)> msg) const {
+ ::std::cerr << this->filename << ":" << this->start_line << ": note:";
+ msg(::std::cerr);
+ ::std::cerr << ::std::endl;
+ //abort();
+}
diff --git a/src/types.hpp b/src/types.hpp
index 7612e743..5bb257c7 100644
--- a/src/types.hpp
+++ b/src/types.hpp
@@ -98,6 +98,7 @@ TAGGED_UNION(TypeData, None,
class TypeRef:
public Serialisable
{
+ Span m_span;
public:
TypeData m_data;
@@ -203,6 +204,10 @@ public:
m_data(TypeData::make_TraitObject({ ::std::move(traits) }))
{}
+
+ void set_span(Span sp) { this->m_span = sp; }
+ const Span& span() { return this->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)