diff options
Diffstat (limited to 'src/parse')
-rw-r--r-- | src/parse/common.hpp | 2 | ||||
-rw-r--r-- | src/parse/expr.cpp | 4 | ||||
-rw-r--r-- | src/parse/lex.cpp | 32 | ||||
-rw-r--r-- | src/parse/lex.hpp | 25 | ||||
-rw-r--r-- | src/parse/paths.cpp | 25 | ||||
-rw-r--r-- | src/parse/root.cpp | 13 | ||||
-rw-r--r-- | src/parse/types.cpp | 13 |
7 files changed, 73 insertions, 41 deletions
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: |