diff options
author | John Hodge <tpg@mutabah.net> | 2015-03-07 12:07:43 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2015-03-07 12:07:43 +0800 |
commit | fcec09900f158aa939eb1c96607aaabf4c8171ef (patch) | |
tree | eaac668a8d19b56fee0cdafb218ec069cdab8bc5 /src | |
parent | a9692e359884672b30e1742bada368330115cc14 (diff) | |
download | mrust-fcec09900f158aa939eb1c96607aaabf4c8171ef.tar.gz |
Added file+line reporting to error messages
Diffstat (limited to 'src')
-rw-r--r-- | src/macros.cpp | 8 | ||||
-rw-r--r-- | src/macros.hpp | 4 | ||||
-rw-r--r-- | src/parse/common.hpp | 4 | ||||
-rw-r--r-- | src/parse/expr.cpp | 6 | ||||
-rw-r--r-- | src/parse/lex.cpp | 14 | ||||
-rw-r--r-- | src/parse/lex.hpp | 413 | ||||
-rw-r--r-- | src/parse/parseerror.cpp | 9 | ||||
-rw-r--r-- | src/parse/parseerror.hpp | 4 | ||||
-rw-r--r-- | src/parse/preproc.cpp | 16 | ||||
-rw-r--r-- | src/parse/preproc.hpp | 5 | ||||
-rw-r--r-- | src/parse/root.cpp | 121 | ||||
-rw-r--r-- | src/parse/tokentree.hpp | 4 |
12 files changed, 371 insertions, 237 deletions
diff --git a/src/macros.cpp b/src/macros.cpp index fa9ca9ef..7d0c7096 100644 --- a/src/macros.cpp +++ b/src/macros.cpp @@ -68,7 +68,7 @@ MacroExpander Macro_Invoke(const char* name, TokenTree input) // Create token stream for input tree
TTStream lex(input);
if(GET_TOK(tok, lex) == TOK_EOF) {
- throw ParseError::Unexpected(tok);
+ throw ParseError::Unexpected(lex, tok);
}
::std::map<const char*,TokenTree,cmp_str> bound_tts;
// Parse according to rules
@@ -102,7 +102,7 @@ MacroExpander Macro_Invoke(const char* name, TokenTree input) }
// TODO: Actually check if the final token is the closer to the first
if( !fail && GET_TOK(tok, lex) == TOK_EOF) {
- throw ParseError::Unexpected(tok);
+ throw ParseError::Unexpected(lex, tok);
}
if( !fail && lex.getToken().type() == TOK_EOF )
{
@@ -115,6 +115,10 @@ MacroExpander Macro_Invoke(const char* name, TokenTree input) throw ParseError::Generic( ::std::string("Macro '") + name + "' was not found" );
}
+Position MacroExpander::getPosition() const
+{
+ return Position("Macro", 0);
+}
Token MacroExpander::realGetToken()
{
if( m_ttstream.get() )
diff --git a/src/macros.hpp b/src/macros.hpp index f5779d4d..b2aeda53 100644 --- a/src/macros.hpp +++ b/src/macros.hpp @@ -87,7 +87,9 @@ public: m_ofs(0)
{
}
- virtual Token realGetToken();
+
+ virtual Position getPosition() const override;
+ virtual Token realGetToken() override;
};
extern MacroExpander Macro_Invoke(const char* name, TokenTree input);
diff --git a/src/parse/common.hpp b/src/parse/common.hpp index 0d6d550b..950a204d 100644 --- a/src/parse/common.hpp +++ b/src/parse/common.hpp @@ -5,11 +5,11 @@ #define GET_TOK(tok, lex) ((tok = lex.getToken()).type())
#define GET_CHECK_TOK(tok, lex, exp) do {\
if((tok = lex.getToken()).type() != exp) \
- throw ParseError::Unexpected(tok, Token(exp));\
+ throw ParseError::Unexpected(lex, tok, Token(exp));\
} while(0)
#define CHECK_TOK(tok, exp) do {\
if(tok.type() != exp) \
- throw ParseError::Unexpected(tok, Token(exp));\
+ throw ParseError::Unexpected(lex, tok, Token(exp));\
} while(0)
enum eParsePathGenericMode
diff --git a/src/parse/expr.cpp b/src/parse/expr.cpp index 2ed992ce..1ee3a2e2 100644 --- a/src/parse/expr.cpp +++ b/src/parse/expr.cpp @@ -155,7 +155,7 @@ AST::Pattern Parse_Pattern(TokenStream& lex) // This may also have to handle range expressions? (and other complexities)
throw ParseError::Todo("tuple patterns");
default:
- throw ParseError::Unexpected(tok);
+ throw ParseError::Unexpected(lex, tok);
}
throw ParseError::BugCheck("Parse_Pattern should early return");
}
@@ -618,7 +618,7 @@ ExprNodeP Parse_ExprVal(TokenStream& lex) return Parse_Expr0(expanded_macro);
}
default:
- throw ParseError::Unexpected(tok);
+ throw ParseError::Unexpected(lex, tok);
}
}
@@ -701,7 +701,7 @@ TokenTree Parse_TT_Val(TokenStream& lex) break;
default:
// Oh, fail :(
- throw ParseError::Unexpected(tok);
+ throw ParseError::Unexpected(lex, tok);
}
return TokenTree(ret);
}
diff --git a/src/parse/lex.cpp b/src/parse/lex.cpp index 2d6873d0..43fc12aa 100644 --- a/src/parse/lex.cpp +++ b/src/parse/lex.cpp @@ -205,6 +205,8 @@ Token Lexer::getToken() { char ch = this->getc(); + if( ch == '\n' ) + return Token(TOK_NEWLINE); if( isspace(ch) ) { while( isspace(this->getc()) ) @@ -311,6 +313,7 @@ Token Lexer::getToken() str.push_back(ch); ch = this->getc(); } + this->putback(); return Token(TOK_COMMENT, str); } case BLOCKCOMMENT: { ::std::string str; @@ -449,6 +452,7 @@ const char* Token::typestr(enum eTokenType type) case TOK_NULL: return "TOK_NULL"; case TOK_EOF: return "TOK_EOF"; + case TOK_NEWLINE: return "TOK_NEWLINE"; case TOK_WHITESPACE: return "TOK_WHITESPACE"; case TOK_COMMENT: return "TOK_COMMENT"; @@ -579,11 +583,15 @@ const char* Token::typestr(enum eTokenType type) return ">>BUGCHECK: BADTOK<<"; } -::std::ostream& operator<<(::std::ostream& os, Token& tok) +::std::ostream& operator<<(::std::ostream& os, const Token& tok) { os << Token::typestr(tok.type()) << "\"" << tok.str() << "\""; return os; } +::std::ostream& operator<<(::std::ostream& os, const Position& p) +{ + return os << p.filename << ":" << p.line; +} TTStream::TTStream(const TokenTree& input_tt): m_input_tt(input_tt) @@ -623,6 +631,10 @@ Token TTStream::realGetToken() } return Token(TOK_EOF); } +Position TTStream::getPosition() const +{ + return Position("TTStream", 0); +} TokenStream::TokenStream(): m_cache_valid(false) diff --git a/src/parse/lex.hpp b/src/parse/lex.hpp index 710f3a6c..38f730c5 100644 --- a/src/parse/lex.hpp +++ b/src/parse/lex.hpp @@ -1,201 +1,216 @@ -#ifndef LEX_HPP_INCLUDED
-#define LEX_HPP_INCLUDED
-
-#include "../types.hpp"
+#ifndef LEX_HPP_INCLUDED +#define LEX_HPP_INCLUDED + +#include "../types.hpp" #include <string> -#include <fstream>
-
-enum eTokenType
-{
- TOK_NULL,
- TOK_EOF,
-
- TOK_WHITESPACE,
- TOK_COMMENT,
-
- // Value tokens
- TOK_IDENT,
- TOK_MACRO,
- TOK_LIFETIME,
- TOK_INTEGER,
- TOK_CHAR,
- TOK_FLOAT,
+#include <fstream> + +enum eTokenType +{ + TOK_NULL, + TOK_EOF, + + TOK_NEWLINE, + TOK_WHITESPACE, + TOK_COMMENT, + + // Value tokens + TOK_IDENT, + TOK_MACRO, + TOK_LIFETIME, + TOK_INTEGER, + TOK_CHAR, + TOK_FLOAT, TOK_STRING, -
- TOK_CATTR_OPEN,
- TOK_ATTR_OPEN,
-
- // Symbols
- TOK_PAREN_OPEN, TOK_PAREN_CLOSE,
- TOK_BRACE_OPEN, TOK_BRACE_CLOSE,
- TOK_LT, TOK_GT,
- TOK_SQUARE_OPEN,TOK_SQUARE_CLOSE,
- TOK_COMMA,
- TOK_SEMICOLON,
- TOK_COLON,
- TOK_DOUBLE_COLON,
- TOK_STAR, TOK_AMP,
- TOK_PIPE,
-
- TOK_FATARROW, // =>
- TOK_THINARROW, // ->
-
- TOK_PLUS, TOK_DASH,
- TOK_EXCLAM,
- TOK_PERCENT,
- TOK_SLASH,
-
- TOK_DOT,
- TOK_DOUBLE_DOT,
- TOK_TRIPLE_DOT,
-
- TOK_EQUAL,
- TOK_PLUS_EQUAL,
- TOK_DASH_EQUAL,
- TOK_PERCENT_EQUAL,
- TOK_SLASH_EQUAL,
- TOK_STAR_EQUAL,
- TOK_AMP_EQUAL,
- TOK_PIPE_EQUAL,
-
- TOK_DOUBLE_EQUAL,
- TOK_EXCLAM_EQUAL,
- TOK_GTE,
- TOK_LTE,
-
- TOK_DOUBLE_AMP,
- TOK_DOUBLE_PIPE,
- TOK_DOUBLE_LT,
- TOK_DOUBLE_GT,
-
- TOK_QMARK,
- TOK_AT,
- TOK_TILDE,
- TOK_BACKSLASH,
- TOK_CARET,
- TOK_BACKTICK,
-
- // Reserved Words
- TOK_RWORD_PUB,
- TOK_RWORD_PRIV,
- TOK_RWORD_MUT,
- TOK_RWORD_CONST,
- TOK_RWORD_STATIC,
- TOK_RWORD_UNSAFE,
- TOK_RWORD_EXTERN,
-
- TOK_RWORD_CRATE,
- TOK_RWORD_MOD,
- TOK_RWORD_STRUCT,
- TOK_RWORD_ENUM,
- TOK_RWORD_TRAIT,
- TOK_RWORD_FN,
- TOK_RWORD_USE,
- TOK_RWORD_IMPL,
- TOK_RWORD_TYPE,
-
- TOK_RWORD_WHERE,
- TOK_RWORD_AS,
-
- TOK_RWORD_LET,
- TOK_RWORD_MATCH,
- TOK_RWORD_IF,
- TOK_RWORD_ELSE,
- TOK_RWORD_LOOP,
- TOK_RWORD_WHILE,
- TOK_RWORD_FOR,
- TOK_RWORD_IN,
- TOK_RWORD_DO,
-
- TOK_RWORD_CONTINUE,
- TOK_RWORD_BREAK,
- TOK_RWORD_RETURN,
- TOK_RWORD_YIELD,
- TOK_RWORD_BOX,
- TOK_RWORD_REF,
-
- TOK_RWORD_FALSE,
- TOK_RWORD_TRUE,
- TOK_RWORD_SELF,
- TOK_RWORD_SUPER,
-
- TOK_RWORD_PROC,
- TOK_RWORD_MOVE,
- TOK_RWORD_ONCE,
-
- TOK_RWORD_ABSTRACT,
- TOK_RWORD_FINAL,
- TOK_RWORD_PURE,
- TOK_RWORD_OVERRIDE,
- TOK_RWORD_VIRTUAL,
-
- TOK_RWORD_ALIGNOF,
- TOK_RWORD_OFFSETOF,
- TOK_RWORD_SIZEOF,
- TOK_RWORD_TYPEOF,
-
- TOK_RWORD_BE,
- TOK_RWORD_UNSIZED,
-};
-
-class Token
-{
- enum eTokenType m_type;
- ::std::string m_str;
- enum eCoreType m_datatype;
- union {
- uint64_t m_intval;
- double m_floatval;
- };
-public:
- Token();
- Token(enum eTokenType type);
- Token(enum eTokenType type, ::std::string str);
- Token(uint64_t val, enum eCoreType datatype);
- Token(double val, enum eCoreType datatype);
-
- enum eTokenType type() const { return m_type; }
- const ::std::string& str() const { return m_str; }
- enum eCoreType datatype() const { return m_datatype; }
- uint64_t intval() const { return m_intval; }
- double floatval() const { return m_floatval; }
-
- static const char* typestr(enum eTokenType type);
-};
-
-extern ::std::ostream& operator<<(::std::ostream& os, Token& tok);
-
-class TokenStream
-{
- bool m_cache_valid;
- Token m_cache;
-public:
- TokenStream();
- virtual ~TokenStream();
- Token getToken();
- void putback(Token tok);
-protected:
- virtual Token realGetToken() = 0;
-};
-
-class Lexer
-{
- ::std::ifstream m_istream;
- bool m_last_char_valid;
- char m_last_char;
-public:
- Lexer(::std::string filename);
-
- Token getToken();
-
-private:
- signed int getSymbol();
- uint32_t parseEscape(char enclosing);
-
- char getc();
- void putback();
-
- class EndOfFile {};
-};
-
-#endif // LEX_HPP_INCLUDED
+ + TOK_CATTR_OPEN, + TOK_ATTR_OPEN, + + // Symbols + TOK_PAREN_OPEN, TOK_PAREN_CLOSE, + TOK_BRACE_OPEN, TOK_BRACE_CLOSE, + TOK_LT, TOK_GT, + TOK_SQUARE_OPEN,TOK_SQUARE_CLOSE, + TOK_COMMA, + TOK_SEMICOLON, + TOK_COLON, + TOK_DOUBLE_COLON, + TOK_STAR, TOK_AMP, + TOK_PIPE, + + TOK_FATARROW, // => + TOK_THINARROW, // -> + + TOK_PLUS, TOK_DASH, + TOK_EXCLAM, + TOK_PERCENT, + TOK_SLASH, + + TOK_DOT, + TOK_DOUBLE_DOT, + TOK_TRIPLE_DOT, + + TOK_EQUAL, + TOK_PLUS_EQUAL, + TOK_DASH_EQUAL, + TOK_PERCENT_EQUAL, + TOK_SLASH_EQUAL, + TOK_STAR_EQUAL, + TOK_AMP_EQUAL, + TOK_PIPE_EQUAL, + + TOK_DOUBLE_EQUAL, + TOK_EXCLAM_EQUAL, + TOK_GTE, + TOK_LTE, + + TOK_DOUBLE_AMP, + TOK_DOUBLE_PIPE, + TOK_DOUBLE_LT, + TOK_DOUBLE_GT, + + TOK_QMARK, + TOK_AT, + TOK_TILDE, + TOK_BACKSLASH, + TOK_CARET, + TOK_BACKTICK, + + // Reserved Words + TOK_RWORD_PUB, + TOK_RWORD_PRIV, + TOK_RWORD_MUT, + TOK_RWORD_CONST, + TOK_RWORD_STATIC, + TOK_RWORD_UNSAFE, + TOK_RWORD_EXTERN, + + TOK_RWORD_CRATE, + TOK_RWORD_MOD, + TOK_RWORD_STRUCT, + TOK_RWORD_ENUM, + TOK_RWORD_TRAIT, + TOK_RWORD_FN, + TOK_RWORD_USE, + TOK_RWORD_IMPL, + TOK_RWORD_TYPE, + + TOK_RWORD_WHERE, + TOK_RWORD_AS, + + TOK_RWORD_LET, + TOK_RWORD_MATCH, + TOK_RWORD_IF, + TOK_RWORD_ELSE, + TOK_RWORD_LOOP, + TOK_RWORD_WHILE, + TOK_RWORD_FOR, + TOK_RWORD_IN, + TOK_RWORD_DO, + + TOK_RWORD_CONTINUE, + TOK_RWORD_BREAK, + TOK_RWORD_RETURN, + TOK_RWORD_YIELD, + TOK_RWORD_BOX, + TOK_RWORD_REF, + + TOK_RWORD_FALSE, + TOK_RWORD_TRUE, + TOK_RWORD_SELF, + TOK_RWORD_SUPER, + + TOK_RWORD_PROC, + TOK_RWORD_MOVE, + TOK_RWORD_ONCE, + + TOK_RWORD_ABSTRACT, + TOK_RWORD_FINAL, + TOK_RWORD_PURE, + TOK_RWORD_OVERRIDE, + TOK_RWORD_VIRTUAL, + + TOK_RWORD_ALIGNOF, + TOK_RWORD_OFFSETOF, + TOK_RWORD_SIZEOF, + TOK_RWORD_TYPEOF, + + TOK_RWORD_BE, + TOK_RWORD_UNSIZED, +}; + +class Token +{ + enum eTokenType m_type; + ::std::string m_str; + enum eCoreType m_datatype; + union { + uint64_t m_intval; + double m_floatval; + }; +public: + Token(); + Token(enum eTokenType type); + Token(enum eTokenType type, ::std::string str); + Token(uint64_t val, enum eCoreType datatype); + Token(double val, enum eCoreType datatype); + + enum eTokenType type() const { return m_type; } + const ::std::string& str() const { return m_str; } + enum eCoreType datatype() const { return m_datatype; } + uint64_t intval() const { return m_intval; } + double floatval() const { return m_floatval; } + + static const char* typestr(enum eTokenType type); +}; + +extern ::std::ostream& operator<<(::std::ostream& os, const Token& tok); + +struct Position +{ + ::std::string filename; + unsigned int line; + + Position(::std::string filename, unsigned int line): + filename(filename), + line(line) + { + } +}; +extern ::std::ostream& operator<<(::std::ostream& os, const Position& p); + +class TokenStream +{ + bool m_cache_valid; + Token m_cache; +public: + TokenStream(); + virtual ~TokenStream(); + Token getToken(); + void putback(Token tok); + virtual Position getPosition() const = 0; +protected: + virtual Token realGetToken() = 0; +}; + +class Lexer +{ + ::std::ifstream m_istream; + bool m_last_char_valid; + char m_last_char; +public: + Lexer(::std::string filename); + + Token getToken(); + +private: + signed int getSymbol(); + uint32_t parseEscape(char enclosing); + + char getc(); + void putback(); + + class EndOfFile {}; +}; + +#endif // LEX_HPP_INCLUDED diff --git a/src/parse/parseerror.cpp b/src/parse/parseerror.cpp index 37beb863..ed7a845c 100644 --- a/src/parse/parseerror.cpp +++ b/src/parse/parseerror.cpp @@ -37,14 +37,15 @@ ParseError::BadChar::~BadChar() throw() {
}
-ParseError::Unexpected::Unexpected(Token tok):
+ParseError::Unexpected::Unexpected(const TokenStream& lex, Token tok):
m_tok(tok)
{
- ::std::cout << "Unexpected(" << tok << ")" << ::std::endl;
+ ::std::cout << lex.getPosition() << ": Unexpected(" << tok << ")" << ::std::endl;
}
-ParseError::Unexpected::Unexpected(Token tok, Token exp)
+ParseError::Unexpected::Unexpected(const TokenStream& lex, Token tok, Token exp):
+ m_tok(tok)
{
- ::std::cout << "Unexpected(" << tok << ", " << exp << ")" << ::std::endl;
+ ::std::cout << lex.getPosition() << ": Unexpected(" << tok << ", " << exp << ")" << ::std::endl;
}
ParseError::Unexpected::~Unexpected() throw()
{
diff --git a/src/parse/parseerror.hpp b/src/parse/parseerror.hpp index 11324476..33c02a92 100644 --- a/src/parse/parseerror.hpp +++ b/src/parse/parseerror.hpp @@ -56,8 +56,8 @@ class Unexpected: {
Token m_tok;
public:
- Unexpected(Token tok);
- Unexpected(Token tok, Token exp);
+ Unexpected(const TokenStream& lex, Token tok);
+ Unexpected(const TokenStream& lex, Token tok, Token exp);
virtual ~Unexpected() throw ();
};
diff --git a/src/parse/preproc.cpp b/src/parse/preproc.cpp index 3e2865b2..c8f0aeea 100644 --- a/src/parse/preproc.cpp +++ b/src/parse/preproc.cpp @@ -1,7 +1,10 @@ #include "preproc.hpp"
#include <iostream>
+#include <algorithm>
Preproc::Preproc(::std::string path):
+ m_path(path),
+ m_line(1),
m_lex(path)
{
//ctor
@@ -20,16 +23,25 @@ Token Preproc::getTokenInt() //::std::cout << "getTokenInt: tok = " << tok << ::std::endl;
switch(tok.type())
{
- case TOK_WHITESPACE:
+ case TOK_NEWLINE:
+ m_line ++;
continue;
- case TOK_COMMENT:
+ case TOK_WHITESPACE:
continue;
+ case TOK_COMMENT: {
+ ::std::string comment = tok.str();
+ m_line += ::std::count(comment.begin(), comment.end(), '\n');
+ continue; }
default:
return tok;
}
}
}
+Position Preproc::getPosition() const
+{
+ return Position(m_path, m_line);
+}
Token Preproc::realGetToken()
{
return getTokenInt();
diff --git a/src/parse/preproc.hpp b/src/parse/preproc.hpp index bedb3076..08fda12d 100644 --- a/src/parse/preproc.hpp +++ b/src/parse/preproc.hpp @@ -6,13 +6,16 @@ class Preproc:
public TokenStream
{
+ ::std::string m_path;
+ unsigned int m_line;
Lexer m_lex;
public:
Preproc(::std::string path);
~Preproc();
- virtual Token realGetToken();
+ virtual Position getPosition() const override;
+ virtual Token realGetToken() override;
private:
Token getTokenInt();
};
diff --git a/src/parse/root.cpp b/src/parse/root.cpp index 2b4126e9..ef04ea2f 100644 --- a/src/parse/root.cpp +++ b/src/parse/root.cpp @@ -169,7 +169,7 @@ TypeRef Parse_Type(TokenStream& lex) // Immutable pointer
return TypeRef(TypeRef::TagPointer(), false, Parse_Type(lex));
default:
- throw ParseError::Unexpected(tok, Token(TOK_RWORD_CONST));
+ throw ParseError::Unexpected(lex, tok, Token(TOK_RWORD_CONST));
}
throw ParseError::BugCheck("Reached end of Parse_Type:STAR");
case TOK_SQUARE_OPEN: {
@@ -205,7 +205,7 @@ TypeRef Parse_Type(TokenStream& lex) case TOK_EXCLAM:
throw ParseError::Todo("noreturn type");
default:
- throw ParseError::Unexpected(tok);
+ throw ParseError::Unexpected(lex, tok);
}
throw ParseError::BugCheck("Reached end of Parse_Type");
}
@@ -228,7 +228,7 @@ AST::TypeParams Parse_TypeParams(TokenStream& lex) break;
default:
// Oopsie!
- throw ParseError::Unexpected(tok);
+ throw ParseError::Unexpected(lex, tok);
}
::std::string param_name = tok.str();
ret.add_param( AST::TypeParam( is_lifetime, param_name ) );
@@ -425,8 +425,7 @@ void Parse_Struct(AST::Module& mod, TokenStream& lex, const bool is_public, cons {
refs.push_back( Parse_Type(lex) );
}
- if( tok.type() != TOK_PAREN_CLOSE )
- throw ParseError::Unexpected(tok, Token(TOK_PAREN_CLOSE));
+ CHECK_TOK(tok, TOK_PAREN_CLOSE);
inner = TypeRef(TypeRef::TagTuple(), refs);
}
throw ParseError::Todo("tuple struct");
@@ -449,14 +448,13 @@ void Parse_Struct(AST::Module& mod, TokenStream& lex, const bool is_public, cons tok = lex.getToken();
if(tok.type() == TOK_BRACE_CLOSE)
break;
- if(tok.type() != TOK_COMMA)
- throw ParseError::Unexpected(tok, Token(TOK_COMMA));
+ CHECK_TOK(tok, TOK_COMMA);
}
mod.add_struct(is_public, name, params, items);
}
else
{
- throw ParseError::Unexpected(tok);
+ throw ParseError::Unexpected(lex, tok);
}
}
@@ -473,6 +471,25 @@ AST::Trait Parse_TraitDef(TokenStream& lex, const ::std::vector<AST::MetaItem> m GET_CHECK_TOK(tok, lex, TOK_GT);
tok = lex.getToken();
}
+
+ // Trait bounds "trait Trait : 'lifetime + OtherTrait + OtherTrait2"
+ if(tok.type() == TOK_COLON)
+ {
+ do
+ {
+ if( GET_TOK(tok, lex) == TOK_LIFETIME )
+ {
+ // Lifetime requirement
+ throw ParseError::Todo("Trait bounds (lifetime)");
+ }
+ else
+ {
+ lex.putback(tok);
+ params.add_bound( AST::GenericBound("Self", Parse_Type(lex)) );
+ }
+ } while(GET_TOK(tok, lex) == TOK_PLUS);
+ }
+
// TODO: Support "for Sized?"
if(tok.type() == TOK_RWORD_WHERE)
{
@@ -662,7 +679,7 @@ AST::Impl Parse_Impl(TokenStream& lex) break; }
default:
- throw ParseError::Unexpected(tok);
+ throw ParseError::Unexpected(lex, tok);
}
}
@@ -693,7 +710,7 @@ void Parse_Use(Preproc& lex, ::std::function<void(AST::Path, ::std::string)> fcn path.append( AST::PathNode(tok.str(), {}) );
break;
default:
- throw ParseError::Unexpected(tok);
+ throw ParseError::Unexpected(lex, tok);
}
// TODO: Use from crate root
while( GET_TOK(tok, lex) == TOK_DOUBLE_COLON )
@@ -723,7 +740,7 @@ void Parse_Use(Preproc& lex, ::std::function<void(AST::Path, ::std::string)> fcn // early return - can't have anything else after
return;
default:
- throw ParseError::Unexpected(tok);
+ throw ParseError::Unexpected(lex, tok);
}
GET_TOK(tok, lex);
break;
@@ -786,11 +803,11 @@ void Parse_ModRoot(Preproc& lex, AST::Crate& crate, AST::Module& mod, const ::st {
case TOK_BRACE_CLOSE:
if( !nested_module )
- throw ParseError::Unexpected(tok);
+ throw ParseError::Unexpected(lex, tok);
return ;
case TOK_EOF:
if( nested_module )
- throw ParseError::Unexpected(tok);
+ throw ParseError::Unexpected(lex, tok);
return ;
default:
lex.putback(tok);
@@ -824,7 +841,36 @@ void Parse_ModRoot(Preproc& lex, AST::Crate& crate, AST::Module& mod, const ::st Parse_Use(lex, [&mod,is_public](AST::Path p, std::string s) { mod.add_alias(is_public, p, s); });
GET_CHECK_TOK(tok, lex, TOK_SEMICOLON);
break;
-
+
+ case TOK_RWORD_EXTERN:
+ switch( GET_TOK(tok, lex) )
+ {
+ case TOK_STRING:
+ throw ParseError::Todo("'extern \"C\"'");
+ break;
+ case TOK_RWORD_CRATE:
+ if( GET_TOK(tok, lex) == TOK_STRING )
+ {
+ ::std::string path = tok.str();
+ GET_CHECK_TOK(tok, lex, TOK_RWORD_AS);
+ GET_CHECK_TOK(tok, lex, TOK_IDENT);
+ ::std::string name = tok.str();
+
+ mod.add_ext_crate(path, name);
+ }
+ else if( tok.type() == TOK_IDENT )
+ {
+ ::std::string name = tok.str();
+
+ mod.add_ext_crate(name, name);
+ }
+ GET_CHECK_TOK(tok, lex, TOK_SEMICOLON);
+ break;
+ default:
+ throw ParseError::Unexpected(lex, tok);
+ }
+ break;
+
case TOK_RWORD_CONST: {
GET_CHECK_TOK(tok, lex, TOK_IDENT);
::std::string name = tok.str();
@@ -892,10 +938,43 @@ void Parse_ModRoot(Preproc& lex, AST::Crate& crate, AST::Module& mod, const ::st switch( GET_TOK(tok, lex) )
{
case TOK_BRACE_OPEN:
- Parse_ModRoot(lex, crate, submod, "");
+ Parse_ModRoot(lex, crate, submod, "-");
break;
case TOK_SEMICOLON:
- throw ParseError::Todo("sub-modules from other files");
+ DEBUG("Mod = " << name << ", curpath = " << path);
+ if( path.back() != '/' )
+ {
+ throw ParseError::Generic( FMT("Can't load from files outside of mod.rs or crate root") );
+ }
+ else
+ {
+ ::std::string newpath_dir = path + name + "/";
+ ::std::string newpath_file = path + name + ".rs";
+ ::std::ifstream ifs_dir (newpath_dir + "mod.rs");
+ ::std::ifstream ifs_file(newpath_file);
+ if( ifs_dir.is_open() && ifs_file.is_open() )
+ {
+ // Collision
+ }
+ else if( ifs_dir.is_open() )
+ {
+ // Load from dir
+ Preproc sub_lex(newpath_dir + "mod.rs");
+ Parse_ModRoot(sub_lex, crate, submod, newpath_dir);
+ }
+ else if( ifs_file.is_open() )
+ {
+ // Load from file
+ Preproc sub_lex(newpath_file);
+ Parse_ModRoot(sub_lex, crate, submod, newpath_file);
+ }
+ else
+ {
+ // Can't find file
+ throw ParseError::Generic( FMT("Can't find file for " << name << " in '" << path << "'") );
+ }
+ }
+ break;
default:
throw ParseError::Generic("Expected { or ; after module name");
}
@@ -903,7 +982,7 @@ void Parse_ModRoot(Preproc& lex, AST::Crate& crate, AST::Module& mod, const ::st break; }
default:
- throw ParseError::Unexpected(tok);
+ throw ParseError::Unexpected(lex, tok);
}
}
}
@@ -912,7 +991,11 @@ AST::Crate Parse_Crate(::std::string mainfile) {
Token tok;
- Preproc lex(mainfile);
+ Preproc lex(mainfile);
+
+ size_t p = mainfile.find_last_of('/');
+ ::std::string mainpath = (p != ::std::string::npos ? ::std::string(mainfile.begin(), mainfile.begin()+p+1) : "./");
+
AST::Crate crate;
AST::Module& rootmod = crate.root_module();
@@ -948,7 +1031,7 @@ AST::Crate Parse_Crate(::std::string mainfile) // Include the std if the 'no_std' attribute was absent
// - First need to load the std macros, then can import the prelude
- Parse_ModRoot(lex, crate, rootmod, mainfile);
+ Parse_ModRoot(lex, crate, rootmod, mainpath);
return crate;
}
diff --git a/src/parse/tokentree.hpp b/src/parse/tokentree.hpp index b1b353ea..f7094357 100644 --- a/src/parse/tokentree.hpp +++ b/src/parse/tokentree.hpp @@ -39,8 +39,10 @@ public: TTStream(const TokenTree& input_tt);
~TTStream();
+ virtual Position getPosition() const override;
+
protected:
- virtual Token realGetToken();
+ virtual Token realGetToken() override;
};
extern TokenTree Parse_TT(TokenStream& lex);
|