summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ast/crate.cpp1
-rw-r--r--src/ast/dump.cpp5
-rw-r--r--src/expand/asm.cpp1
-rw-r--r--src/expand/cfg.cpp9
-rw-r--r--src/expand/concat.cpp3
-rw-r--r--src/expand/env.cpp1
-rw-r--r--src/expand/file_line.cpp6
-rw-r--r--src/expand/format_args.cpp2
-rw-r--r--src/expand/include.cpp4
-rw-r--r--src/expand/macro_rules.cpp1
-rw-r--r--src/expand/rustc_diagnostics.cpp1
-rw-r--r--src/expand/stringify.cpp6
-rw-r--r--src/include/span.hpp1
-rw-r--r--src/macro_rules/eval.cpp2
-rw-r--r--src/parse/common.hpp4
-rw-r--r--src/parse/lex.cpp238
-rw-r--r--src/parse/lex.hpp93
-rw-r--r--src/parse/parseerror.hpp2
-rw-r--r--src/parse/root.cpp6
-rw-r--r--src/parse/tokenstream.cpp124
-rw-r--r--src/parse/tokenstream.hpp99
-rw-r--r--src/parse/tokentree.cpp23
-rw-r--r--src/parse/tokentree.hpp53
-rw-r--r--src/parse/ttstream.cpp109
-rw-r--r--src/parse/ttstream.hpp52
25 files changed, 466 insertions, 380 deletions
diff --git a/src/ast/crate.cpp b/src/ast/crate.cpp
index f99389d0..b18ca662 100644
--- a/src/ast/crate.cpp
+++ b/src/ast/crate.cpp
@@ -6,6 +6,7 @@
#include "../expand/cfg.hpp"
#include <hir/hir.hpp> // HIR::Crate
#include <hir/main_bindings.hpp> // HIR_Deserialise
+#include <fstream>
namespace {
bool check_item_cfg(const ::AST::MetaItems& attrs)
diff --git a/src/ast/dump.cpp b/src/ast/dump.cpp
index 33ef5911..15fb6c4a 100644
--- a/src/ast/dump.cpp
+++ b/src/ast/dump.cpp
@@ -9,6 +9,7 @@
#include <ast/ast.hpp>
#include <ast/expr.hpp>
#include <main_bindings.hpp>
+#include <fstream>
#include <cpp_unpack.h>
@@ -564,9 +565,9 @@ private:
void dec_indent();
};
-void Dump_Rust(const char *Filename, const AST::Crate& crate)
+void Dump_Rust(const char *filename, const AST::Crate& crate)
{
- ::std::ofstream os(Filename);
+ ::std::ofstream os(filename);
RustPrinter printer(os);
printer.handle_module(crate.root_module());
}
diff --git a/src/expand/asm.cpp b/src/expand/asm.cpp
index 783e6a20..3ca7bb72 100644
--- a/src/expand/asm.cpp
+++ b/src/expand/asm.cpp
@@ -8,6 +8,7 @@
#include <common.hpp>
#include <synext_macro.hpp>
#include <parse/tokentree.hpp>
+#include <parse/ttstream.hpp>
class CAsmExpander:
public ExpandProcMacro
diff --git a/src/expand/cfg.cpp b/src/expand/cfg.cpp
index 0a4617cf..00e3921c 100644
--- a/src/expand/cfg.cpp
+++ b/src/expand/cfg.cpp
@@ -1,9 +1,14 @@
/*
+ * MRustC - Rust Compiler
+ * - By John Hodge (Mutabah/thePowersGang)
+ *
+ * expand/cfg.hpp
+ * - cfg! and #[cfg] handling
*/
#include <synext.hpp>
-#include <parse/tokentree.hpp>
-#include <parse/lex.hpp>
#include <parse/common.hpp>
+#include <parse/tokentree.hpp>
+#include <parse/ttstream.hpp>
#include "cfg.hpp"
#include <ast/expr.hpp> // Needed to clear a ExprNodeP
#include <ast/crate.hpp>
diff --git a/src/expand/concat.cpp b/src/expand/concat.cpp
index c15be18b..7475325a 100644
--- a/src/expand/concat.cpp
+++ b/src/expand/concat.cpp
@@ -9,7 +9,8 @@
#include "../parse/common.hpp"
#include "../parse/parseerror.hpp"
#include "../parse/tokentree.hpp"
-#include "../parse/lex.hpp"
+#include "../parse/ttstream.hpp"
+#include "../parse/lex.hpp" // For Codepoint
#include <ast/expr.hpp>
class CConcatExpander:
diff --git a/src/expand/env.cpp b/src/expand/env.cpp
index 85742549..db51fa67 100644
--- a/src/expand/env.cpp
+++ b/src/expand/env.cpp
@@ -7,6 +7,7 @@
*/
#include <synext_macro.hpp>
#include <parse/common.hpp>
+#include <parse/ttstream.hpp>
#include <ast/expr.hpp> // ExprNode_*
#include <synext.hpp> // for Expand_BareExpr
diff --git a/src/expand/file_line.cpp b/src/expand/file_line.cpp
index 8ce56436..a485fe61 100644
--- a/src/expand/file_line.cpp
+++ b/src/expand/file_line.cpp
@@ -1,7 +1,13 @@
/*
+ * MRustC - Rust Compiler
+ * - By John Hodge (Mutabah/thePowersGang)
+ *
+ * expand/file_line.cpp
+ * - file! line! and macro_path! macros
*/
#include <synext.hpp>
#include "../parse/common.hpp"
+#include "../parse/ttstream.hpp"
class CExpanderFile:
public ExpandProcMacro
diff --git a/src/expand/format_args.cpp b/src/expand/format_args.cpp
index 4857a6c2..6881e19a 100644
--- a/src/expand/format_args.cpp
+++ b/src/expand/format_args.cpp
@@ -10,7 +10,7 @@
#include "../parse/common.hpp"
#include "../parse/parseerror.hpp"
#include "../parse/tokentree.hpp"
-#include "../parse/lex.hpp"
+#include "../parse/ttstream.hpp"
#include "../parse/interpolated_fragment.hpp"
#include <ast/crate.hpp> // for m_load_std
#include <ast/expr.hpp> // for ExprNode_*
diff --git a/src/expand/include.cpp b/src/expand/include.cpp
index b7fe0f53..83a2aa03 100644
--- a/src/expand/include.cpp
+++ b/src/expand/include.cpp
@@ -8,8 +8,8 @@
#include <synext_macro.hpp>
#include <parse/common.hpp>
#include <parse/parseerror.hpp> // for GET_CHECK_TOK
-#include <parse/tokentree.hpp> // TTStream
-#include <parse/lex.hpp>
+#include <parse/ttstream.hpp>
+#include <parse/lex.hpp> // Lexer (new files)
#include <ast/expr.hpp>
namespace {
diff --git a/src/expand/macro_rules.cpp b/src/expand/macro_rules.cpp
index c460e35d..163504db 100644
--- a/src/expand/macro_rules.cpp
+++ b/src/expand/macro_rules.cpp
@@ -13,6 +13,7 @@
#include "../ast/expr.hpp"
#include "../ast/ast.hpp"
#include "../parse/common.hpp"
+#include "../parse/ttstream.hpp"
#include <ast/crate.hpp>
#include "macro_rules.hpp"
#include <macro_rules/macro_rules.hpp>
diff --git a/src/expand/rustc_diagnostics.cpp b/src/expand/rustc_diagnostics.cpp
index e9990a93..b5337d26 100644
--- a/src/expand/rustc_diagnostics.cpp
+++ b/src/expand/rustc_diagnostics.cpp
@@ -7,6 +7,7 @@
*/
#include <synext.hpp>
#include <parse/common.hpp> // TokenTree etc
+#include <parse/ttstream.hpp>
class CExpanderRegisterDiagnostic:
public ExpandProcMacro
diff --git a/src/expand/stringify.cpp b/src/expand/stringify.cpp
index 2d70ca27..ce16847b 100644
--- a/src/expand/stringify.cpp
+++ b/src/expand/stringify.cpp
@@ -1,7 +1,13 @@
/*
+ * MRustC - Rust Compiler
+ * - By John Hodge (Mutabah/thePowersGang)
+ *
+ * expand/stringify.cpp
+ * - stringify! macro
*/
#include <synext.hpp>
#include "../parse/common.hpp"
+#include "../parse/ttstream.hpp"
class CExpander:
public ExpandProcMacro
diff --git a/src/include/span.hpp b/src/include/span.hpp
index 81ccd179..eafebb0a 100644
--- a/src/include/span.hpp
+++ b/src/include/span.hpp
@@ -8,6 +8,7 @@
#pragma once
#include <rc_string.hpp>
+#include <functional>
enum ErrorType
{
diff --git a/src/macro_rules/eval.cpp b/src/macro_rules/eval.cpp
index 110e8525..f7a5aab1 100644
--- a/src/macro_rules/eval.cpp
+++ b/src/macro_rules/eval.cpp
@@ -8,7 +8,7 @@
#include <common.hpp>
#include "macro_rules.hpp"
#include <parse/parseerror.hpp>
-#include <parse/tokentree.hpp>
+#include <parse/ttstream.hpp>
#include <parse/common.hpp>
#include <limits.h>
#include "pattern_checks.hpp"
diff --git a/src/parse/common.hpp b/src/parse/common.hpp
index 7bf41d22..57d6f24d 100644
--- a/src/parse/common.hpp
+++ b/src/parse/common.hpp
@@ -8,6 +8,7 @@
#ifndef PARSE_COMMON_HPP_INCLUDED
#define PARSE_COMMON_HPP_INCLUDED
#include <iostream>
+#include "tokenstream.hpp"
#include "../ast/ast.hpp"
#define GET_TOK(tok, lex) ((tok = lex.getToken()).type())
@@ -60,6 +61,9 @@ extern AST::ExprNodeP Parse_ExprBlockLine(TokenStream& lex, bool *add_silence);
extern AST::ExprNodeP Parse_ExprBlockLine_WithItems(TokenStream& lex, ::std::shared_ptr<AST::Module>& local_mod, bool& add_silence_if_end);
extern AST::ExprNodeP Parse_Stmt(TokenStream& lex);
+// unwrapped = Exclude the enclosing brackets (used by macro parse code)
+extern TokenTree Parse_TT(TokenStream& lex, bool unwrapped);
+
extern bool Parse_IsTokValue(eTokenType tok_type);
diff --git a/src/parse/lex.cpp b/src/parse/lex.cpp
index 9acb56e0..d6cfcddb 100644
--- a/src/parse/lex.cpp
+++ b/src/parse/lex.cpp
@@ -4,11 +4,6 @@
*
* parse/lex.cpp
* - Lexer (converts input file to token stream)
- *
- * Provides:
- * - Lexer : The file->token lexer
- * - TTStream : A stream of tokens from a TokenTree
- * - TokenStream : Common interface for all token streams
*/
#include "lex.hpp"
#include "tokentree.hpp"
@@ -18,11 +13,7 @@
#include <iostream>
#include <cstdlib> // strtol
#include <typeinfo>
-#include <algorithm> // std::count
-
-const bool DEBUG_PRINT_TOKENS = false;
-//const bool DEBUG_PRINT_TOKENS = true;
-//#define DEBUG_PRINT_TOKENS debug_enabled("Lexer Tokens")
+#include <algorithm> // std::count
Lexer::Lexer(const ::std::string& filename):
m_path(filename.c_str()),
@@ -978,230 +969,9 @@ void Lexer::ungetc()
m_last_char_valid = true;
}
-TTStream::TTStream(const TokenTree& input_tt)
-{
- DEBUG("input_tt = [" << input_tt << "]");
- m_stack.push_back( ::std::make_pair(0, &input_tt) );
-}
-TTStream::~TTStream()
-{
-}
-Token TTStream::realGetToken()
-{
- while(m_stack.size() > 0)
- {
- // If current index is above TT size, go up
- unsigned int& idx = m_stack.back().first;
- const TokenTree& tree = *m_stack.back().second;
-
- if(idx == 0 && tree.is_token()) {
- idx ++;
- return tree.tok();
- }
-
- if(idx < tree.size())
- {
- const TokenTree& subtree = tree[idx];
- idx ++;
- if( subtree.size() == 0 ) {
- m_hygiene_ptr = &m_stack.back().second->hygiene();
- return subtree.tok().clone();
- }
- else {
- m_stack.push_back( ::std::make_pair(0, &subtree) );
- }
- }
- else {
- m_stack.pop_back();
- }
- }
- //m_hygiene = nullptr;
- return Token(TOK_EOF);
-}
-Position TTStream::getPosition() const
-{
- return Position("TTStream", 0,0);
-}
-Ident::Hygiene TTStream::getHygiene() const
-{
- //assert( m_hygiene );
- return *m_hygiene_ptr;
-}
-
-
-TTStreamO::TTStreamO(TokenTree input_tt):
- m_input_tt( mv$(input_tt) )
-{
- m_stack.push_back( ::std::make_pair(0, nullptr) );
-}
-TTStreamO::~TTStreamO()
-{
-}
-Token TTStreamO::realGetToken()
-{
- while(m_stack.size() > 0)
- {
- // If current index is above TT size, go up
- unsigned int& idx = m_stack.back().first;
- TokenTree& tree = *( m_stack.back().second ? m_stack.back().second : &m_input_tt );
-
- if(idx == 0 && tree.is_token()) {
- idx ++;
- m_last_pos = tree.tok().get_pos();
- return mv$(tree.tok());
- }
-
- if(idx < tree.size())
- {
- TokenTree& subtree = tree[idx];
- idx ++;
- if( subtree.size() == 0 ) {
- m_last_pos = subtree.tok().get_pos();
- return mv$( subtree.tok() );
- }
- else {
- m_stack.push_back( ::std::make_pair(0, &subtree) );
- }
- }
- else {
- m_stack.pop_back();
- }
- }
- return Token(TOK_EOF);
-}
-Position TTStreamO::getPosition() const
-{
- return m_last_pos;
-}
-Ident::Hygiene TTStreamO::getHygiene() const
-{
- return (m_stack.back().second ? m_stack.back().second->hygiene() : m_input_tt.hygiene());
-}
-
-
-TokenStream::TokenStream():
- m_cache_valid(false)
-{
-}
-TokenStream::~TokenStream()
-{
-}
-
-Token TokenStream::innerGetToken()
-{
- Token ret = this->realGetToken();
- if( ret.get_pos().filename == "" )
- ret.set_pos( this->getPosition() );
- //DEBUG("ret.get_pos() = " << ret.get_pos());
- return ret;
-}
-Token TokenStream::getToken()
-{
- if( m_cache_valid )
- {
- m_cache_valid = false;
- return mv$(m_cache);
- }
- else if( m_lookahead.size() )
- {
- Token ret = mv$( m_lookahead.front() );
- m_lookahead.erase(m_lookahead.begin());
- if( DEBUG_PRINT_TOKENS ) {
- ::std::cout << "getToken[" << typeid(*this).name() << "] - " << ret.get_pos() << "-" << ret << ::std::endl;
- }
- return ret;
- }
- else
- {
- Token ret = this->innerGetToken();
- if( DEBUG_PRINT_TOKENS ) {
- ::std::cout << "getToken[" << typeid(*this).name() << "] - " << ret.get_pos() << "-" << ret << ::std::endl;
- }
- return ret;
- }
-}
-void TokenStream::putback(Token tok)
-{
- if( m_cache_valid )
- {
- DEBUG("" << getPosition() << " - Double putback: " << tok << " but " << m_cache);
- throw ParseError::BugCheck("Double putback");
- }
- else
- {
- m_cache_valid = true;
- m_cache = mv$(tok);
- }
-}
-
-eTokenType TokenStream::lookahead(unsigned int i)
-{
- const unsigned int MAX_LOOKAHEAD = 3;
-
- if( m_cache_valid )
- {
- if( i == 0 )
- return m_cache.type();
- i --;
- }
-
- if( i >= MAX_LOOKAHEAD )
- throw ParseError::BugCheck("Excessive lookahead");
-
- while( i >= m_lookahead.size() )
- {
- DEBUG("lookahead - read #" << m_lookahead.size());
- m_lookahead.push_back( this->innerGetToken() );
- }
-
- DEBUG("lookahead(" << i << ") = " << m_lookahead[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
- );
-}
-Ident TokenStream::get_ident(Token tok) const
-{
- if(tok.type() == TOK_IDENT) {
- return Ident(getHygiene(), tok.str());
- }
- else if( tok.type() == TOK_INTERPOLATED_IDENT ) {
- TODO(getPosition(), "");
- }
- else {
- throw ParseError::Unexpected(*this, tok);
- }
-}
-
-TokenTree TokenTree::clone() const
-{
- if( m_subtrees.size() == 0 ) {
- return TokenTree(m_tok.clone());
- }
- else {
- ::std::vector< TokenTree> ents;
- ents.reserve( m_subtrees.size() );
- for(const auto& sub : m_subtrees)
- ents.push_back( sub.clone() );
- return TokenTree( m_hygiene, mv$(ents) );
- }
-}
+// --------------------------------------------------------------------
+// Codepoint - Unicode codepoint.
+// --------------------------------------------------------------------
bool Codepoint::isspace() const {
switch(this->v)
diff --git a/src/parse/lex.hpp b/src/parse/lex.hpp
index d147d79d..3d41c3fc 100644
--- a/src/parse/lex.hpp
+++ b/src/parse/lex.hpp
@@ -8,99 +8,9 @@
#ifndef LEX_HPP_INCLUDED
#define LEX_HPP_INCLUDED
-#include <debug.hpp>
-#include <serialise.hpp>
-#include "../coretypes.hpp"
#include <string>
#include <fstream>
-
-#include "../include/span.hpp"
-
-#include "token.hpp"
-
-namespace AST {
- class Module;
- class MetaItems;
-}
-
-/// State the parser needs to pass down via a second channel.
-struct ParseState
-{
- // Used for "for/if/while" to handle ambiguity
- bool disallow_struct_literal = false;
- // A debugging hook that disables expansion of macros
- bool no_expand_macros = false;
-
- ::AST::Module* module = nullptr;
- ::AST::MetaItems* parent_attrs = nullptr;
-
- ::AST::Module& get_current_mod() {
- assert(this->module);
- return *this->module;
- }
-
- friend ::std::ostream& operator<<(::std::ostream& os, const ParseState& ps) {
- os << "ParseState {";
- if(ps.disallow_struct_literal) os << " disallow_struct_literal";
- if(ps.no_expand_macros) os << " no_expand_macros";
- os << " }";
- return os;
- }
-};
-
-class TokenStream
-{
- friend class TTLexer; // needs access to internals to know what was consumed
-
- bool m_cache_valid;
- Token m_cache;
- ::std::vector<Token> m_lookahead;
- ParseState m_parse_state;
-public:
- TokenStream();
- virtual ~TokenStream();
- Token getToken();
- void putback(Token tok);
- eTokenType lookahead(unsigned int count);
-
- virtual Position getPosition() const = 0;
- virtual Ident::Hygiene getHygiene() const = 0;
-
- ParseState& parse_state() { return m_parse_state; }
-
- ProtoSpan start_span() const;
- Span end_span(ProtoSpan ps) const;
-
- Ident get_ident(Token tok) const;
-
-protected:
- virtual Token realGetToken() = 0;
-private:
- Token innerGetToken();
-};
-
-class SavedParseState
-{
- TokenStream& m_lex;
- ParseState m_state;
-public:
- SavedParseState(TokenStream& lex, ParseState state):
- m_lex(lex),
- m_state(state)
- {
- }
- ~SavedParseState()
- {
- DEBUG("Restoring " << m_state);
- m_lex.parse_state() = m_state;
- }
-};
-
-#define SET_MODULE(lex, mod) SavedParseState _sps(lex, lex.parse_state()); lex.parse_state().module = &(mod)
-#define SET_ATTRS(lex, attrs) SavedParseState _sps(lex, lex.parse_state()); lex.parse_state().parent_attrs = &(attrs)
-#define SET_PARSE_FLAG(lex, flag) SavedParseState _sps(lex, lex.parse_state()); lex.parse_state().flag = true
-#define CLEAR_PARSE_FLAG(lex, flag) SavedParseState _sps(lex, lex.parse_state()); lex.parse_state().flag = false
-#define CHECK_PARSE_FLAG(lex, flag) (lex.parse_state().flag == true)
+#include "tokenstream.hpp"
struct Codepoint {
uint32_t v;
@@ -116,6 +26,7 @@ struct Codepoint {
};
extern ::std::string& operator+=(::std::string& s, const Codepoint& cp);
extern ::std::ostream& operator<<(::std::ostream& s, const Codepoint& cp);
+
typedef Codepoint uchar;
class Lexer:
diff --git a/src/parse/parseerror.hpp b/src/parse/parseerror.hpp
index b847ccc4..0a00f60a 100644
--- a/src/parse/parseerror.hpp
+++ b/src/parse/parseerror.hpp
@@ -2,7 +2,7 @@
#define PARSEERROR_HPP_INCLUDED
#include <stdexcept>
-#include "lex.hpp"
+#include "tokenstream.hpp"
#include <compile_error.hpp>
namespace ParseError {
diff --git a/src/parse/root.cpp b/src/parse/root.cpp
index 2f5114ed..a6683925 100644
--- a/src/parse/root.cpp
+++ b/src/parse/root.cpp
@@ -9,13 +9,15 @@
* - Parse_Crate : Handles crate attrbutes, and passes on to Parse_ModRoot
* - Parse_ModRoot
*/
-#include "../ast/ast.hpp"
-#include "../ast/crate.hpp"
+#include <ast/ast.hpp>
+#include <ast/crate.hpp>
#include "parseerror.hpp"
#include "common.hpp"
#include <cassert>
#include <hir/hir.hpp> // ABI_RUST - TODO: Move elsewhere?
#include <expand/cfg.hpp> // check_cfg - for `mod nonexistant;`
+#include <fstream> // Used by directory path
+#include "lex.hpp" // New file lexer
template<typename T>
Spanned<T> get_spanned(TokenStream& lex, ::std::function<T()> f) {
diff --git a/src/parse/tokenstream.cpp b/src/parse/tokenstream.cpp
new file mode 100644
index 00000000..5d9919f6
--- /dev/null
+++ b/src/parse/tokenstream.cpp
@@ -0,0 +1,124 @@
+/*
+ * MRustC - Rust Compiler
+ * - By John Hodge (Mutabah/thePowersGang)
+ *
+ * parse/tokenstream.cpp
+ * - TokenStream - Parser token source interface
+ */
+#include "tokenstream.hpp"
+#include <common.hpp>
+#include "parseerror.hpp"
+
+const bool DEBUG_PRINT_TOKENS = false;
+//const bool DEBUG_PRINT_TOKENS = true;
+//#define DEBUG_PRINT_TOKENS debug_enabled("Lexer Tokens")
+
+TokenStream::TokenStream():
+ m_cache_valid(false)
+{
+}
+TokenStream::~TokenStream()
+{
+}
+
+Token TokenStream::innerGetToken()
+{
+ Token ret = this->realGetToken();
+ if( ret.get_pos().filename == "" )
+ ret.set_pos( this->getPosition() );
+ //DEBUG("ret.get_pos() = " << ret.get_pos());
+ return ret;
+}
+Token TokenStream::getToken()
+{
+ if( m_cache_valid )
+ {
+ m_cache_valid = false;
+ return mv$(m_cache);
+ }
+ else if( m_lookahead.size() )
+ {
+ Token ret = mv$( m_lookahead.front() );
+ m_lookahead.erase(m_lookahead.begin());
+ if( DEBUG_PRINT_TOKENS ) {
+ ::std::cout << "getToken[" << typeid(*this).name() << "] - " << ret.get_pos() << "-" << ret << ::std::endl;
+ }
+ return ret;
+ }
+ else
+ {
+ Token ret = this->innerGetToken();
+ if( DEBUG_PRINT_TOKENS ) {
+ ::std::cout << "getToken[" << typeid(*this).name() << "] - " << ret.get_pos() << "-" << ret << ::std::endl;
+ }
+ return ret;
+ }
+}
+void TokenStream::putback(Token tok)
+{
+ if( m_cache_valid )
+ {
+ DEBUG("" << getPosition() << " - Double putback: " << tok << " but " << m_cache);
+ throw ParseError::BugCheck("Double putback");
+ }
+ else
+ {
+ m_cache_valid = true;
+ m_cache = mv$(tok);
+ }
+}
+
+eTokenType TokenStream::lookahead(unsigned int i)
+{
+ const unsigned int MAX_LOOKAHEAD = 3;
+
+ if( m_cache_valid )
+ {
+ if( i == 0 )
+ return m_cache.type();
+ i --;
+ }
+
+ if( i >= MAX_LOOKAHEAD )
+ throw ParseError::BugCheck("Excessive lookahead");
+
+ while( i >= m_lookahead.size() )
+ {
+ DEBUG("lookahead - read #" << m_lookahead.size());
+ m_lookahead.push_back( this->innerGetToken() );
+ }
+
+ DEBUG("lookahead(" << i << ") = " << m_lookahead[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
+ );
+}
+Ident TokenStream::get_ident(Token tok) const
+{
+ if(tok.type() == TOK_IDENT) {
+ return Ident(getHygiene(), tok.str());
+ }
+ else if( tok.type() == TOK_INTERPOLATED_IDENT ) {
+ TODO(getPosition(), "");
+ }
+ else {
+ throw ParseError::Unexpected(*this, tok);
+ }
+}
diff --git a/src/parse/tokenstream.hpp b/src/parse/tokenstream.hpp
new file mode 100644
index 00000000..c6e2de37
--- /dev/null
+++ b/src/parse/tokenstream.hpp
@@ -0,0 +1,99 @@
+/*
+ * MRustC - Rust Compiler
+ * - By John Hodge (Mutabah/thePowersGang)
+ *
+ * parse/tokenstream.hpp
+ * - Parser stream (TokenStream) header
+ */
+#pragma once
+
+#include <iostream>
+#include <vector>
+#include <span.hpp>
+#include <debug.hpp>
+#include <ident.hpp>
+#include "token.hpp"
+
+namespace AST {
+ class Module;
+ class MetaItems;
+}
+
+/// State the parser needs to pass down via a second channel.
+struct ParseState
+{
+ // Used for "for/if/while" to handle ambiguity
+ bool disallow_struct_literal = false;
+ // A debugging hook that disables expansion of macros
+ bool no_expand_macros = false;
+
+ ::AST::Module* module = nullptr;
+ ::AST::MetaItems* parent_attrs = nullptr;
+
+ ::AST::Module& get_current_mod() {
+ assert(this->module);
+ return *this->module;
+ }
+
+ friend ::std::ostream& operator<<(::std::ostream& os, const ParseState& ps) {
+ os << "ParseState {";
+ if(ps.disallow_struct_literal) os << " disallow_struct_literal";
+ if(ps.no_expand_macros) os << " no_expand_macros";
+ os << " }";
+ return os;
+ }
+};
+
+class TokenStream
+{
+ friend class TTLexer; // needs access to internals to know what was consumed
+
+ bool m_cache_valid;
+ Token m_cache;
+ ::std::vector<Token> m_lookahead;
+ ParseState m_parse_state;
+public:
+ TokenStream();
+ virtual ~TokenStream();
+ Token getToken();
+ void putback(Token tok);
+ eTokenType lookahead(unsigned int count);
+
+ virtual Position getPosition() const = 0;
+ virtual Ident::Hygiene getHygiene() const = 0;
+
+ ParseState& parse_state() { return m_parse_state; }
+
+ ProtoSpan start_span() const;
+ Span end_span(ProtoSpan ps) const;
+
+ Ident get_ident(Token tok) const;
+
+protected:
+ virtual Token realGetToken() = 0;
+private:
+ Token innerGetToken();
+};
+
+class SavedParseState
+{
+ TokenStream& m_lex;
+ ParseState m_state;
+public:
+ SavedParseState(TokenStream& lex, ParseState state):
+ m_lex(lex),
+ m_state(state)
+ {
+ }
+ ~SavedParseState()
+ {
+ DEBUG("Restoring " << m_state);
+ m_lex.parse_state() = m_state;
+ }
+};
+
+#define SET_MODULE(lex, mod) SavedParseState _sps(lex, lex.parse_state()); lex.parse_state().module = &(mod)
+#define SET_ATTRS(lex, attrs) SavedParseState _sps(lex, lex.parse_state()); lex.parse_state().parent_attrs = &(attrs)
+#define SET_PARSE_FLAG(lex, flag) SavedParseState _sps(lex, lex.parse_state()); lex.parse_state().flag = true
+#define CLEAR_PARSE_FLAG(lex, flag) SavedParseState _sps(lex, lex.parse_state()); lex.parse_state().flag = false
+#define CHECK_PARSE_FLAG(lex, flag) (lex.parse_state().flag == true)
diff --git a/src/parse/tokentree.cpp b/src/parse/tokentree.cpp
new file mode 100644
index 00000000..8fad6386
--- /dev/null
+++ b/src/parse/tokentree.cpp
@@ -0,0 +1,23 @@
+/*
+ * MRustC - Rust Compiler
+ * - By John Hodge (Mutabah/thePowersGang)
+ *
+ * parse/tokentree.cpp
+ * - Token Tree (collection of tokens)
+ */
+#include "tokentree.hpp"
+#include <common.hpp>
+
+TokenTree TokenTree::clone() const
+{
+ if( m_subtrees.size() == 0 ) {
+ return TokenTree(m_tok.clone());
+ }
+ else {
+ ::std::vector< TokenTree> ents;
+ ents.reserve( m_subtrees.size() );
+ for(const auto& sub : m_subtrees)
+ ents.push_back( sub.clone() );
+ return TokenTree( m_hygiene, mv$(ents) );
+ }
+}
diff --git a/src/parse/tokentree.hpp b/src/parse/tokentree.hpp
index 627d11e3..50ca72a5 100644
--- a/src/parse/tokentree.hpp
+++ b/src/parse/tokentree.hpp
@@ -1,7 +1,16 @@
+/*
+ * MRustC - Rust Compiler
+ * - By John Hodge (Mutabah/thePowersGang)
+ *
+ * parse/tokentree.hpp
+ * - Token Trees (groups of tokens
+ */
#ifndef TOKENTREE_HPP_INCLUDED
#define TOKENTREE_HPP_INCLUDED
-#include "lex.hpp"
+#include "token.hpp"
+#include <ident.hpp>
+#include <vector>
class TokenTree
{
@@ -55,46 +64,4 @@ public:
}
};
-class TTStream:
- public TokenStream
-{
- ::std::vector< ::std::pair<unsigned int, const TokenTree*> > m_stack;
- const Ident::Hygiene* m_hygiene_ptr = nullptr;
-public:
- TTStream(const TokenTree& input_tt);
- ~TTStream();
-
- TTStream& operator=(const TTStream& x) { m_stack = x.m_stack; return *this; }
-
- Position getPosition() const override;
- Ident::Hygiene getHygiene() const override;
-
-protected:
- Token realGetToken() override;
-};
-
-class TTStreamO:
- public TokenStream
-{
- Position m_last_pos;
- TokenTree m_input_tt;
- ::std::vector< ::std::pair<unsigned int, TokenTree*> > m_stack;
-public:
- TTStreamO(TokenTree input_tt);
- TTStreamO(TTStreamO&& x) = default;
- ~TTStreamO();
-
- TTStreamO& operator=(const TTStreamO& x) { m_stack = x.m_stack; return *this; }
- TTStreamO& operator=(TTStreamO&& x) = default;
-
- Position getPosition() const override;
- Ident::Hygiene getHygiene() const override;
-
-protected:
- Token realGetToken() override;
-};
-
-// unwrapped = Exclude the enclosing brackets (used by macro parse code)
-extern TokenTree Parse_TT(TokenStream& lex, bool unwrapped);
-
#endif // TOKENTREE_HPP_INCLUDED
diff --git a/src/parse/ttstream.cpp b/src/parse/ttstream.cpp
new file mode 100644
index 00000000..d969f514
--- /dev/null
+++ b/src/parse/ttstream.cpp
@@ -0,0 +1,109 @@
+/*
+ * MRustC - Rust Compiler
+ * - By John Hodge (Mutabah/thePowersGang)
+ *
+ * parse/ttstream.cpp
+ * - Token-Tree backed token streams
+ */
+#include "ttstream.hpp"
+#include <common.hpp>
+
+TTStream::TTStream(const TokenTree& input_tt)
+{
+ DEBUG("input_tt = [" << input_tt << "]");
+ m_stack.push_back( ::std::make_pair(0, &input_tt) );
+}
+TTStream::~TTStream()
+{
+}
+Token TTStream::realGetToken()
+{
+ while(m_stack.size() > 0)
+ {
+ // If current index is above TT size, go up
+ unsigned int& idx = m_stack.back().first;
+ const TokenTree& tree = *m_stack.back().second;
+
+ if(idx == 0 && tree.is_token()) {
+ idx ++;
+ return tree.tok();
+ }
+
+ if(idx < tree.size())
+ {
+ const TokenTree& subtree = tree[idx];
+ idx ++;
+ if( subtree.size() == 0 ) {
+ m_hygiene_ptr = &m_stack.back().second->hygiene();
+ return subtree.tok().clone();
+ }
+ else {
+ m_stack.push_back( ::std::make_pair(0, &subtree) );
+ }
+ }
+ else {
+ m_stack.pop_back();
+ }
+ }
+ //m_hygiene = nullptr;
+ return Token(TOK_EOF);
+}
+Position TTStream::getPosition() const
+{
+ return Position("TTStream", 0,0);
+}
+Ident::Hygiene TTStream::getHygiene() const
+{
+ assert( m_hygiene_ptr );
+ return *m_hygiene_ptr;
+}
+
+
+TTStreamO::TTStreamO(TokenTree input_tt):
+ m_input_tt( mv$(input_tt) )
+{
+ m_stack.push_back( ::std::make_pair(0, nullptr) );
+}
+TTStreamO::~TTStreamO()
+{
+}
+Token TTStreamO::realGetToken()
+{
+ while(m_stack.size() > 0)
+ {
+ // If current index is above TT size, go up
+ unsigned int& idx = m_stack.back().first;
+ TokenTree& tree = *( m_stack.back().second ? m_stack.back().second : &m_input_tt );
+
+ if(idx == 0 && tree.is_token()) {
+ idx ++;
+ m_last_pos = tree.tok().get_pos();
+ return mv$(tree.tok());
+ }
+
+ if(idx < tree.size())
+ {
+ TokenTree& subtree = tree[idx];
+ idx ++;
+ if( subtree.size() == 0 ) {
+ m_last_pos = subtree.tok().get_pos();
+ return mv$( subtree.tok() );
+ }
+ else {
+ m_stack.push_back( ::std::make_pair(0, &subtree) );
+ }
+ }
+ else {
+ m_stack.pop_back();
+ }
+ }
+ return Token(TOK_EOF);
+}
+Position TTStreamO::getPosition() const
+{
+ return m_last_pos;
+}
+Ident::Hygiene TTStreamO::getHygiene() const
+{
+ return (m_stack.back().second ? m_stack.back().second->hygiene() : m_input_tt.hygiene());
+}
diff --git a/src/parse/ttstream.hpp b/src/parse/ttstream.hpp
new file mode 100644
index 00000000..7b7fec4a
--- /dev/null
+++ b/src/parse/ttstream.hpp
@@ -0,0 +1,52 @@
+/*
+ * MRustC - Rust Compiler
+ * - By John Hodge (Mutabah/thePowersGang)
+ *
+ * parse/ttstrea.hpp
+ * - Token tree streams (for post-lex parsing)
+ */
+#pragma once
+
+#include "tokentree.hpp"
+#include "tokenstream.hpp"
+
+/// Borrowed TTStream
+class TTStream:
+ public TokenStream
+{
+ ::std::vector< ::std::pair<unsigned int, const TokenTree*> > m_stack;
+ const Ident::Hygiene* m_hygiene_ptr = nullptr;
+public:
+ TTStream(const TokenTree& input_tt);
+ ~TTStream();
+
+ TTStream& operator=(const TTStream& x) { m_stack = x.m_stack; return *this; }
+
+ Position getPosition() const override;
+ Ident::Hygiene getHygiene() const override;
+
+protected:
+ Token realGetToken() override;
+};
+
+/// Owned TTStream
+class TTStreamO:
+ public TokenStream
+{
+ Position m_last_pos;
+ TokenTree m_input_tt;
+ ::std::vector< ::std::pair<unsigned int, TokenTree*> > m_stack;
+public:
+ TTStreamO(TokenTree input_tt);
+ TTStreamO(TTStreamO&& x) = default;
+ ~TTStreamO();
+
+ TTStreamO& operator=(const TTStreamO& x) { m_stack = x.m_stack; return *this; }
+ TTStreamO& operator=(TTStreamO&& x) = default;
+
+ Position getPosition() const override;
+ Ident::Hygiene getHygiene() const override;
+
+protected:
+ Token realGetToken() override;
+};