From 03e211d6eeb3f8f3c6f0b22f77c2074e81443952 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sun, 6 Sep 2015 18:08:38 +0800 Subject: Rough span support --- Makefile | 1 + src/ast/path.cpp | 8 +++--- src/ast/path.hpp | 47 +++++++++++++++++++-------------- src/ast/provided_module.cpp | 4 +-- src/convert/ast_iterate.cpp | 2 +- src/convert/decorators.cpp | 2 +- src/convert/resolve.cpp | 14 +++++----- src/convert/typecheck_bounds.cpp | 2 +- src/convert/typecheck_expr.cpp | 2 +- src/convert/typecheck_params.cpp | 2 +- src/include/span.hpp | 56 ++++++++++++++++++++++++++++++++++++++++ src/macros.cpp | 6 ++--- src/parse/common.hpp | 2 +- src/parse/expr.cpp | 4 +-- src/parse/lex.cpp | 32 +++++++++++++++++++---- src/parse/lex.hpp | 25 +++++++++--------- src/parse/paths.cpp | 25 +++++++++--------- src/parse/root.cpp | 13 ++++++---- src/parse/types.cpp | 13 ++++++++-- src/span.cpp | 37 ++++++++++++++++++++++++++ src/types.hpp | 5 ++++ 21 files changed, 222 insertions(+), 80 deletions(-) create mode 100644 src/include/span.hpp create mode 100644 src/span.cpp 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 >::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 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 #include #include +#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 l): - Path("", l) - {} Path(::std::string crate, ::std::vector 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 nodes={}); // VARIABLE struct TagLocal {}; @@ -171,18 +172,18 @@ public: // RELATIVE struct TagRelative {}; - Path(TagRelative): - m_class( Class::make_Relative({}) ) + Path(TagRelative, ::std::vector nodes): + m_class( Class::make_Relative({nodes: mv$(nodes)}) ) {} // SELF struct TagSelf {}; - Path(TagSelf): - m_class( Class::make_Self({}) ) + Path(TagSelf, ::std::vector nodes): + m_class( Class::make_Self({nodes: nodes}) ) {} // SUPER struct TagSuper {}; - Path(TagSuper): - m_class( Class::make_Super({}) ) + Path(TagSuper, ::std::vector 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 msg) const; + void error(ErrorType tag, ::std::function msg) const; + void warning(WarningType tag, ::std::function msg) const; + void note(::std::function 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 Parse_PathNodes(TokenStream& lex, eParsePathGenericMode generic_mode); extern ::std::vector 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 #include +#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 Parse_PathNodes(TokenStream& lex, eParsePathGenericMode generic_mode); ::std::vector 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 Parse_PathNodes(TokenStream& lex, eParsePathGenericMode generic_mode) { - TRACE_FUNCTION_F("path = " << path); - Token tok; + ::std::vector 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 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 TRACE_FUNCTION; Token tok; - AST::Path path = AST::Path(AST::Path::TagAbsolute()); + AST::Path path = AST::Path("", {}); ::std::vector 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 } 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 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,10 +35,19 @@ 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; @@ -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 +#include +#include + +void Span::bug(::std::function 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 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 msg) const { + ::std::cerr << this->filename << ":" << this->start_line << ": warning:"; + msg(::std::cerr); + ::std::cerr << ::std::endl; + //abort(); +} +void Span::note(::std::function 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) -- cgit v1.2.3