diff options
author | John Hodge <tpg@mutabah.net> | 2016-11-02 14:51:21 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-11-02 14:51:21 +0800 |
commit | 52c363340a4f2ee589d2e6753f1c685ef7b907f5 (patch) | |
tree | 758c04ec4aada28255cb5cd7865ad27025f29e7f | |
parent | 563520207ad1a6c0deff41b881ac5d0168d3439e (diff) | |
download | mrust-52c363340a4f2ee589d2e6753f1c685ef7b907f5.tar.gz |
All - Hack in start of macro hygine - requires rework so is disabled
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | src/ast/dump.cpp | 34 | ||||
-rw-r--r-- | src/ast/expr.cpp | 29 | ||||
-rw-r--r-- | src/ast/path.cpp | 2 | ||||
-rw-r--r-- | src/ast/path.hpp | 11 | ||||
-rw-r--r-- | src/ast/pattern.cpp | 28 | ||||
-rw-r--r-- | src/ast/pattern.hpp | 46 | ||||
-rw-r--r-- | src/expand/derive.cpp | 6 | ||||
-rw-r--r-- | src/expand/format_args.cpp | 20 | ||||
-rw-r--r-- | src/expand/mod.cpp | 4 | ||||
-rw-r--r-- | src/hir/from_ast.cpp | 59 | ||||
-rw-r--r-- | src/ident.cpp | 60 | ||||
-rw-r--r-- | src/include/ident.hpp | 78 | ||||
-rw-r--r-- | src/include/rc_string.hpp | 1 | ||||
-rw-r--r-- | src/macro_rules/parse.cpp | 9 | ||||
-rw-r--r-- | src/parse/expr.cpp | 6 | ||||
-rw-r--r-- | src/parse/lex.cpp | 25 | ||||
-rw-r--r-- | src/parse/lex.hpp | 4 | ||||
-rw-r--r-- | src/parse/paths.cpp | 17 | ||||
-rw-r--r-- | src/parse/pattern.cpp | 78 | ||||
-rw-r--r-- | src/parse/root.cpp | 92 | ||||
-rw-r--r-- | src/parse/token.cpp | 25 | ||||
-rw-r--r-- | src/parse/token.hpp | 18 | ||||
-rw-r--r-- | src/resolve/absolute.cpp | 54 |
24 files changed, 489 insertions, 219 deletions
@@ -56,7 +56,7 @@ OBJDIR = .obj/ BIN := bin/mrustc$(EXESUF) OBJ := main.o serialise.o -OBJ += span.o rc_string.o debug.o +OBJ += span.o rc_string.o debug.o ident.o OBJ += ast/ast.o OBJ += ast/types.o ast/crate.o ast/path.o ast/expr.o ast/pattern.o OBJ += ast/dump.o diff --git a/src/ast/dump.cpp b/src/ast/dump.cpp index fa31401a..33ef5911 100644 --- a/src/ast/dump.cpp +++ b/src/ast/dump.cpp @@ -922,20 +922,38 @@ void RustPrinter::print_pattern(const AST::Pattern& p, bool is_refutable) ), (Slice, m_os << "["; + m_os << v.sub_pats; + m_os << "]"; + ), + (SplitSlice, + m_os << "["; bool needs_comma = false; if(v.leading.size()) { m_os << v.leading; - needs_comma = true; + m_os << ", "; } - if(v.extra_bind.size() > 0) { - if( needs_comma ) { - m_os << ", "; + + if(v.extra_bind.is_valid()) + { + const auto& b = v.extra_bind; + if( b.m_mutable ) + m_os << "mut "; + switch(b.m_type) + { + case ::AST::PatternBinding::Type::MOVE: + break; + case ::AST::PatternBinding::Type::REF: + m_os << "ref "; + break; + case ::AST::PatternBinding::Type::MUTREF: + m_os << "ref mut "; + break; } - if(v.extra_bind != "_") - m_os << v.extra_bind; - m_os << ".."; - needs_comma = true; + m_os << b.m_name << "/*"<<b.m_slot<<"*/"; } + m_os << ".."; + needs_comma = true; + if(v.trailing.size()) { if( needs_comma ) { m_os << ", "; diff --git a/src/ast/expr.cpp b/src/ast/expr.cpp index bfe3ad98..d856029a 100644 --- a/src/ast/expr.cpp +++ b/src/ast/expr.cpp @@ -55,12 +55,8 @@ Expr Expr::clone() const ::std::ostream& operator<<(::std::ostream& os, const ExprNode& node) { - //if( static_cast<const void*>(&node) != nullptr ) { - node.print(os); - //} - //else { - // os << "/* NULLPTR */"; - //} + assert( static_cast<const void*>(&node) != nullptr ); + node.print(os); return os; } ExprNode::~ExprNode() { @@ -332,6 +328,27 @@ NODE(ExprNode_TypeAnnotation, { }) NODE(ExprNode_BinOp, { + if( m_type == RANGE_INC ) { + os << "("; + if( m_left ) { + os << *m_left << " "; + } + os << "... " << *m_right; + os << ")"; + return ; + } + if( m_type == RANGE ) { + os << "("; + if( m_left ) { + os << *m_left; + } + os << ".."; + if( m_right ) { + os << " " << *m_right; + } + os << ")"; + return ; + } os << "(" << *m_left << " "; switch(m_type) { diff --git a/src/ast/path.cpp b/src/ast/path.cpp index d1781e1f..25c0c208 100644 --- a/src/ast/path.cpp +++ b/src/ast/path.cpp @@ -162,7 +162,7 @@ AST::Path::Path(const Path& x): m_class = Class::make_Local({ent.name}); ), (Relative, - m_class = Class::make_Relative({ent.nodes}); + m_class = Class::make_Relative({ent.hygine, ent.nodes}); ), (Self, m_class = Class::make_Self({ent.nodes}); diff --git a/src/ast/path.hpp b/src/ast/path.hpp index c47f37ca..5c2481a0 100644 --- a/src/ast/path.hpp +++ b/src/ast/path.hpp @@ -13,6 +13,7 @@ #include <tagged_union.hpp> #include <string> #include "../include/span.hpp" +#include "../include/ident.hpp" class TypeRef; @@ -161,6 +162,7 @@ public: ::std::string name; } ), (Relative, struct { // General relative + Ident::Hygine hygine; // Taken from the first ident ::std::vector<PathNode> nodes; } ), (Self, struct { // Module-relative @@ -224,8 +226,8 @@ public: // RELATIVE struct TagRelative {}; - Path(TagRelative, ::std::vector<PathNode> nodes): - m_class( Class::make_Relative({ mv$(nodes) }) ) + Path(TagRelative, Ident::Hygine hygine, ::std::vector<PathNode> nodes): + m_class( Class::make_Relative({ mv$(hygine), mv$(nodes) }) ) {} // SELF struct TagSelf {}; @@ -266,8 +268,9 @@ public: Path& operator+=(const Path& x); void append(PathNode node) { - if( m_class.is_Invalid() ) - m_class = Class::make_Relative({}); + assert( !m_class.is_Invalid() ); + //if( m_class.is_Invalid() ) + // m_class = Class::make_Relative({}); nodes().push_back( mv$(node) ); m_binding = PathBinding(); } diff --git a/src/ast/pattern.cpp b/src/ast/pattern.cpp index df1d0caf..3128fd91 100644 --- a/src/ast/pattern.cpp +++ b/src/ast/pattern.cpp @@ -113,20 +113,25 @@ namespace AST { ), (Slice, os << "["; + os << ent.sub_pats; + os << "]"; + ), + (SplitSlice, + os << "["; bool needs_comma = false; if(ent.leading.size()) { os << ent.leading; needs_comma = true; } - if(ent.extra_bind.size() > 0) { - if( needs_comma ) { - os << ", "; - } - if(ent.extra_bind != "_") - os << ent.extra_bind; - os << ".."; - needs_comma = true; + + if( needs_comma ) { + os << ", "; } + if( ent.extra_bind.is_valid() ) + os << ent.extra_bind.m_name; + os << ".."; + needs_comma = true; + if(ent.trailing.size()) { if( needs_comma ) { os << ", "; @@ -161,7 +166,7 @@ AST::Pattern AST::Pattern::clone() const { AST::Pattern rv; rv.m_span = m_span; - rv.m_binding = m_binding; + rv.m_binding = PatternBinding(m_binding); struct H { static ::std::unique_ptr<Pattern> clone_sp(const ::std::unique_ptr<Pattern>& p) { @@ -226,7 +231,10 @@ AST::Pattern AST::Pattern::clone() const rv.m_data = Data::make_Struct({ ::AST::Path(e.path), mv$(sps) }); ), (Slice, - rv.m_data = Data::make_Slice({ H::clone_list(e.leading), e.extra_bind, H::clone_list(e.trailing) }); + rv.m_data = Data::make_Slice({ H::clone_list(e.sub_pats) }); + ), + (SplitSlice, + rv.m_data = Data::make_SplitSlice({ H::clone_list(e.leading), e.extra_bind, H::clone_list(e.trailing) }); ) ) diff --git a/src/ast/pattern.hpp b/src/ast/pattern.hpp index 3a1dacc5..0dff4071 100644 --- a/src/ast/pattern.hpp +++ b/src/ast/pattern.hpp @@ -1,3 +1,10 @@ +/* + * MRustC - Rust Compiler + * - By John Hodge (Mutabah/thePowersGang) + * + * ast/pattern.hpp + * - AST Pattern representation + */ #ifndef _AST__PATTERN_HPP_INCLUDED_ #define _AST__PATTERN_HPP_INCLUDED_ @@ -6,6 +13,7 @@ #include <memory> #include <string> #include <tagged_union.hpp> +#include <ident.hpp> namespace AST { @@ -21,25 +29,29 @@ public: REF, MUTREF, }; - ::std::string m_name; + Ident m_name; Type m_type; bool m_mutable; unsigned int m_slot; PatternBinding(): - m_name(""), + m_name({0,{}}, ""), m_type(Type::MOVE), m_mutable(false), m_slot( ~0u ) {} - PatternBinding(::std::string name, Type ty, bool ismut): - m_name(name), + PatternBinding(Ident name, Type ty, bool ismut): + m_name(::std::move(name)), m_type(ty), m_mutable(ismut), m_slot( ~0u ) {} - bool is_valid() const { return m_name != ""; } + PatternBinding(PatternBinding&& x) = default; + PatternBinding(const PatternBinding& x) = default; + PatternBinding& operator=(PatternBinding&& x) = default; + + bool is_valid() const { return m_name.name != ""; } }; class Pattern: @@ -68,7 +80,7 @@ public: }; TAGGED_UNION(Data, Any, - (MaybeBind, struct { ::std::string name; } ), + (MaybeBind, struct { Ident name; } ), (Macro, struct { unique_ptr<::AST::MacroInvocation> inv; } ), (Any, struct { } ), (Box, struct { unique_ptr<Pattern> sub; } ), @@ -77,7 +89,8 @@ public: (Tuple, TuplePat ), (StructTuple, struct { Path path; TuplePat tup_pat; } ), (Struct, struct { Path path; ::std::vector< ::std::pair< ::std::string, Pattern> > sub_patterns; bool is_exhaustive; } ), - (Slice, struct { ::std::vector<Pattern> leading; ::std::string extra_bind; ::std::vector<Pattern> trailing; } ) + (Slice, struct { ::std::vector<Pattern> sub_pats; }), + (SplitSlice, struct { ::std::vector<Pattern> leading; PatternBinding extra_bind; ::std::vector<Pattern> trailing; } ) ); private: Span m_span; @@ -98,19 +111,19 @@ public: {}; struct TagMaybeBind {}; - Pattern(TagMaybeBind, ::std::string name): + Pattern(TagMaybeBind, Ident name): m_binding(), - m_data( Data::make_MaybeBind({name}) ) + m_data( Data::make_MaybeBind({ mv$(name) }) ) {} struct TagMacro {}; Pattern(TagMacro, unique_ptr<::AST::MacroInvocation> inv): - m_data( Data::make_Macro({mv$(inv)}) ) + m_data( Data::make_Macro({ mv$(inv) }) ) {} struct TagBind {}; - Pattern(TagBind, ::std::string name, PatternBinding::Type ty = PatternBinding::Type::MOVE, bool is_mut=false): - m_binding( PatternBinding(name, ty, is_mut) ) + Pattern(TagBind, Ident name, PatternBinding::Type ty = PatternBinding::Type::MOVE, bool is_mut=false): + m_binding( PatternBinding(mv$(name), ty, is_mut) ) {} struct TagBox {}; @@ -152,15 +165,10 @@ public: Pattern(TagStruct, Path path, ::std::vector< ::std::pair< ::std::string,Pattern> > sub_patterns, bool is_exhaustive): m_data( Data::make_Struct( { ::std::move(path), ::std::move(sub_patterns), is_exhaustive } ) ) {} - - struct TagSlice {}; - Pattern(TagSlice): - m_data( Data::make_Slice( {} ) ) - {} // Mutators - void set_bind(::std::string name, PatternBinding::Type type, bool is_mut) { - m_binding = PatternBinding(name, type, is_mut); + void set_bind(Ident name, PatternBinding::Type type, bool is_mut) { + m_binding = PatternBinding(mv$(name), type, is_mut); } diff --git a/src/expand/derive.cpp b/src/expand/derive.cpp index 55fb662d..983ab8c0 100644 --- a/src/expand/derive.cpp +++ b/src/expand/derive.cpp @@ -1772,15 +1772,15 @@ public: unsigned int idx = 0; for( const auto& fld : e.m_fields ) { - auto name_a = FMT("a" << fld.m_name); - pats_a.push_back( ::std::make_pair(fld.m_name, ::AST::Pattern(::AST::Pattern::TagBind(), name_a, ::AST::PatternBinding::Type::REF)) ); + auto name_a = Ident( FMT("a" << fld.m_name) ); + pats_a.push_back( ::std::make_pair(fld.m_name, ::AST::Pattern(::AST::Pattern::TagBind(), Ident(name_a), ::AST::PatternBinding::Type::REF)) ); nodes.push_back( NEWNODE(CallPath, this->get_trait_path_Encoder() + "emit_struct_variant_field", vec$( NEWNODE(NamedValue, AST::Path("s")), NEWNODE(String, fld.m_name), NEWNODE(Integer, idx, CORETYPE_UINT), - this->enc_closure(sp, this->enc_val_direct(NEWNODE(NamedValue, AST::Path(name_a)))) + this->enc_closure(sp, this->enc_val_direct(NEWNODE(NamedValue, AST::Path(name_a.name)))) ) ) ); idx ++; diff --git a/src/expand/format_args.cpp b/src/expand/format_args.cpp index 9696a586..977d7d69 100644 --- a/src/expand/format_args.cpp +++ b/src/expand/format_args.cpp @@ -365,17 +365,17 @@ namespace { break; case ::AST::Crate::LOAD_CORE: toks.push_back( TokenTree(TOK_DOUBLE_COLON) ); - toks.push_back( Token(TOK_STRING, "core") ); + toks.push_back( Token(Ident("core")) ); break; case ::AST::Crate::LOAD_STD: toks.push_back( TokenTree(TOK_DOUBLE_COLON) ); - toks.push_back( Token(TOK_IDENT, "std") ); + toks.push_back( Token(Ident("std")) ); break; } for(auto ent : il) { toks.push_back( TokenTree(TOK_DOUBLE_COLON) ); - toks.push_back( Token(TOK_IDENT, ent) ); + toks.push_back( Token(Ident(ent)) ); } } } @@ -417,7 +417,7 @@ class CFormatArgsExpander: if( lex.lookahead(0) == TOK_IDENT && lex.lookahead(1) == TOK_EQUAL ) { GET_CHECK_TOK(tok, lex, TOK_IDENT); - auto name = mv$(tok.str()); + auto name = mv$(tok.ident_str()); GET_CHECK_TOK(tok, lex, TOK_EQUAL); @@ -478,7 +478,7 @@ class CFormatArgsExpander: toks.push_back( TokenTree(TOK_PAREN_OPEN) ); for(unsigned int i = 0; i < free_args.size() + named_args.size(); i ++ ) { - toks.push_back( Token(TOK_IDENT, FMT("a" << i)) ); + toks.push_back( Token(Ident(FMT("a" << i))) ); toks.push_back( TokenTree(TOK_COMMA) ); } toks.push_back( TokenTree(TOK_PAREN_CLOSE) ); @@ -490,13 +490,13 @@ class CFormatArgsExpander: // - Contains N+1 entries, where N is the number of fragments { toks.push_back( TokenTree(TOK_RWORD_STATIC) ); - toks.push_back( Token(TOK_IDENT, "FRAGMENTS") ); + toks.push_back( Token(Ident("FRAGMENTS")) ); toks.push_back( TokenTree(TOK_COLON) ); toks.push_back( TokenTree(TOK_SQUARE_OPEN) ); toks.push_back( Token(TOK_AMP) ); toks.push_back( Token(TOK_LIFETIME, "static") ); - toks.push_back( Token(TOK_IDENT, "str") ); + toks.push_back( Token(Ident("str")) ); toks.push_back( Token(TOK_SEMICOLON) ); toks.push_back( Token(fragments.size() + 1, CORETYPE_UINT) ); toks.push_back( TokenTree(TOK_SQUARE_CLOSE) ); @@ -522,7 +522,7 @@ class CFormatArgsExpander: toks.push_back( TokenTree(TOK_PAREN_OPEN) ); { toks.push_back( TokenTree(TOK_AMP) ); - toks.push_back( Token(TOK_IDENT, "FRAGMENTS") ); + toks.push_back( Token(Ident("FRAGMENTS")) ); toks.push_back( TokenTree(TOK_COMMA) ); toks.push_back( TokenTree(TOK_AMP) ); @@ -531,7 +531,7 @@ class CFormatArgsExpander: { push_path(toks, crate, {"fmt", "ArgumentV1", "new"}); toks.push_back( Token(TOK_PAREN_OPEN) ); - toks.push_back( Token(TOK_IDENT, FMT("a" << frag.arg_index)) ); + toks.push_back( Token(Ident(FMT("a" << frag.arg_index))) ); toks.push_back( TokenTree(TOK_COMMA) ); @@ -554,7 +554,7 @@ class CFormatArgsExpander: toks.push_back( TokenTree(TOK_PAREN_OPEN) ); { toks.push_back( TokenTree(TOK_AMP) ); - toks.push_back( Token(TOK_IDENT, "FRAGMENTS") ); + toks.push_back( Token(Ident("FRAGMENTS")) ); toks.push_back( TokenTree(TOK_COMMA) ); // 1. Generate a set of arguments+formatters diff --git a/src/expand/mod.cpp b/src/expand/mod.cpp index 5542b333..0b9eb146 100644 --- a/src/expand/mod.cpp +++ b/src/expand/mod.cpp @@ -183,6 +183,10 @@ void Expand_Pattern(::AST::Crate& crate, LList<const AST::Module*> modstack, ::A Expand_Pattern(crate, modstack, mod, sp.second, is_refutable); ), (Slice, + for(auto& sp : e.sub_pats) + Expand_Pattern(crate, modstack, mod, sp, is_refutable); + ), + (SplitSlice, for(auto& sp : e.leading) Expand_Pattern(crate, modstack, mod, sp, is_refutable); for(auto& sp : e.trailing) diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp index b600879e..b1d8bd38 100644 --- a/src/hir/from_ast.cpp +++ b/src/hir/from_ast.cpp @@ -132,7 +132,7 @@ case ::AST::PatternBinding::Type::REF: bt = ::HIR::PatternBinding::Type::Ref; break; case ::AST::PatternBinding::Type::MUTREF: bt = ::HIR::PatternBinding::Type::MutRef; break; } - binding = ::HIR::PatternBinding(pat.binding().m_mutable, bt, pat.binding().m_name, pat.binding().m_slot); + binding = ::HIR::PatternBinding(pat.binding().m_mutable, bt, pat.binding().m_name.name, pat.binding().m_slot); } struct H { @@ -433,37 +433,38 @@ ), (Slice, ::std::vector< ::HIR::Pattern> leading; + for(const auto& sp : e.sub_pats) + leading.push_back( LowerHIR_Pattern(sp) ); + return ::HIR::Pattern { + mv$(binding), + ::HIR::Pattern::Data::make_Slice({ + mv$(leading) + }) + }; + ), + (SplitSlice, + ::std::vector< ::HIR::Pattern> leading; for(const auto& sp : e.leading) leading.push_back( LowerHIR_Pattern(sp) ); - if( e.extra_bind != "" || e.trailing.size() > 0 ) { - ::std::vector< ::HIR::Pattern> trailing; - for(const auto& sp : e.trailing) - trailing.push_back( LowerHIR_Pattern(sp) ); - - auto extra_bind = (e.extra_bind == "_" || e.extra_bind == "") - ? ::HIR::PatternBinding() - // TODO: Get slot name for `extra_bind` - : ::HIR::PatternBinding(false, ::HIR::PatternBinding::Type::Ref, e.extra_bind, 0) - ; - - return ::HIR::Pattern { - mv$(binding), - ::HIR::Pattern::Data::make_SplitSlice({ - mv$(leading), - mv$(extra_bind), - mv$(trailing) - }) - }; - } - else { - return ::HIR::Pattern { - mv$(binding), - ::HIR::Pattern::Data::make_Slice({ - mv$(leading) - }) - }; - } + ::std::vector< ::HIR::Pattern> trailing; + for(const auto& sp : e.trailing) + trailing.push_back( LowerHIR_Pattern(sp) ); + + auto extra_bind = e.extra_bind.is_valid() + ? ::HIR::PatternBinding() + // TODO: Share code with the outer binding code + : ::HIR::PatternBinding(false, ::HIR::PatternBinding::Type::Ref, e.extra_bind.m_name.name, e.extra_bind.m_slot) + ; + + return ::HIR::Pattern { + mv$(binding), + ::HIR::Pattern::Data::make_SplitSlice({ + mv$(leading), + mv$(extra_bind), + mv$(trailing) + }) + }; ) ) throw ::std::runtime_error("TODO: LowerHIR_Pattern"); diff --git a/src/ident.cpp b/src/ident.cpp new file mode 100644 index 00000000..5d0fe00c --- /dev/null +++ b/src/ident.cpp @@ -0,0 +1,60 @@ +/* + * MRustC - Rust Compiler + * - By John Hodge (Mutabah/thePowersGang) + * + * include/ident.cpp + * - Identifiers with hygine + */ +#include <iostream> +#include <ident.hpp> +#include <debug.hpp> +#include <common.hpp> // vector print + +bool Ident::Hygine::is_visible(const Hygine& src) const +{ + // HACK: Disable hygine for now + return true; + + DEBUG("*this = " << *this << ", src=" << src); + if( this->file_num != src.file_num ) { + DEBUG("- Different file"); + return false; + } + + // `this` is the item, `src` is the ident used to access it + + // If this is from a deeper point than the source, it won't work. + if( this->indexes.size() > src.indexes.size() ) { + DEBUG("- Not subset: len"); + return false; + } + + // If this hygine list (barring the last) is a subset of the source + for(unsigned int i = 0; i < this->indexes.size()-1 - 1; i ++) + { + if( this->indexes[i] != src.indexes[i] ) { + DEBUG("- Not subset: " << i); + return false; + } + } + + unsigned int end = this->indexes.size()-1-1; + // Allow match if this ident is from before the addressing ident + if( this->indexes[end] < src.indexes[end] ) { + return true; + } + + DEBUG("- Not before"); + return false; +} + +::std::ostream& operator<<(::std::ostream& os, const Ident& x) { + os << x.name; + return os; +} + +::std::ostream& operator<<(::std::ostream& os, const Ident::Hygine& x) { + os << "{" << x.file_num << ": [" << x.indexes << "]}"; + return os; +} + diff --git a/src/include/ident.hpp b/src/include/ident.hpp new file mode 100644 index 00000000..d5ce2e77 --- /dev/null +++ b/src/include/ident.hpp @@ -0,0 +1,78 @@ +/* + * MRustC - Rust Compiler + * - By John Hodge (Mutabah/thePowersGang) + * + * include/ident.hpp + * - Identifiers with hygine + */ +#pragma once +#include <vector> +#include <string> + +struct Ident +{ + struct Hygine + { + unsigned int file_num; + ::std::vector<unsigned int> indexes; + + Hygine(unsigned int file, ::std::vector<unsigned int> indexes): + file_num(file), + indexes(::std::move(indexes)) + {} + + Hygine(Hygine&& x) = default; + Hygine(const Hygine& x) = default; + Hygine& operator=(Hygine&& x) = default; + Hygine& operator=(const Hygine& x) = default; + + // Returns true if an ident with hygine `souce` can see an ident with this hygine + bool is_visible(const Hygine& source) const; + bool operator==(const Hygine& x) const { return file_num == x.file_num && indexes == x.indexes; } + bool operator!=(const Hygine& x) const { return file_num != x.file_num || indexes != x.indexes; } + + friend ::std::ostream& operator<<(::std::ostream& os, const Hygine& v); + }; + + Hygine hygine; + ::std::string name; + + Ident(const char* name): + hygine(~0u, {}), + name(name) + { } + Ident(::std::string name): + hygine(~0u, {}), + name(::std::move(name)) + { } + Ident(Hygine hygine, ::std::string name): + hygine(::std::move(hygine)), name(::std::move(name)) + { } + + Ident(Ident&& x) = default; + Ident(const Ident& x) = default; + Ident& operator=(Ident&& x) = default; + Ident& operator=(const Ident& x) = default; + + ::std::string into_string() { + return ::std::move(name); + } + + bool operator==(const char* s) const { + return this->name == s; + } + + bool operator==(const Ident& x) const { + if( this->name != x.name ) + return false; + //if( this->hygine.indexes != x.hygine.indexes ) + // return false; + return true; + } + bool operator!=(const Ident& x) const { + return !(*this == x); + } + bool operator<(const Ident& x) const; + + friend ::std::ostream& operator<<(::std::ostream& os, const Ident& x); +}; diff --git a/src/include/rc_string.hpp b/src/include/rc_string.hpp index 4649b36e..630f8e89 100644 --- a/src/include/rc_string.hpp +++ b/src/include/rc_string.hpp @@ -75,6 +75,7 @@ public: return ""; } } + bool operator==(const RcString& s) const { return *this == s.c_str(); } bool operator==(const char* s) const; friend ::std::ostream& operator<<(::std::ostream& os, const RcString& x) { return os << x.c_str(); diff --git a/src/macro_rules/parse.cpp b/src/macro_rules/parse.cpp index dce01c86..bd54c67d 100644 --- a/src/macro_rules/parse.cpp +++ b/src/macro_rules/parse.cpp @@ -49,10 +49,10 @@ public: switch( GET_TOK(tok, lex) ) { case TOK_IDENT: { - ::std::string name = tok.str(); + ::std::string name = mv$(tok.ident_str()); GET_CHECK_TOK(tok, lex, TOK_COLON); GET_CHECK_TOK(tok, lex, TOK_IDENT); - ::std::string type = tok.str(); + ::std::string type = mv$(tok.ident_str()); unsigned int idx = ::std::find( names.begin(), names.end(), name ) - names.begin(); if( idx == names.size() ) @@ -202,9 +202,10 @@ public: else if( tok.type() == TOK_IDENT ) { // Look up the named parameter in the list of param names for this arm - unsigned int idx = ::std::find(var_names.begin(), var_names.end(), tok.str()) - var_names.begin(); + const auto& name = tok.ident_str(); + unsigned int idx = ::std::find(var_names.begin(), var_names.end(), name) - var_names.begin(); if( idx == var_names.size() ) - ERROR(lex.getPosition(), E0000, "Macro variable $" << tok.str() << " not found"); + ERROR(lex.getPosition(), E0000, "Macro variable $" << name << " not found"); if( var_set_ptr ) { var_set_ptr->insert( ::std::make_pair(idx,true) ); } diff --git a/src/parse/expr.cpp b/src/parse/expr.cpp index a45e4384..f6ebca1f 100644 --- a/src/parse/expr.cpp +++ b/src/parse/expr.cpp @@ -889,7 +889,7 @@ ExprNodeP Parse_ExprFC(TokenStream& lex) switch(GET_TOK(tok, lex))
{
case TOK_IDENT: {
- AST::PathNode path(tok.str(), {});
+ AST::PathNode path( mv$(tok.ident_str()) , {});
switch( GET_TOK(tok, lex) )
{
case TOK_PAREN_OPEN:
@@ -965,7 +965,7 @@ ExprNodeP Parse_ExprVal_StructLiteral(TokenStream& lex, AST::Path path) ::std::vector< ::std::pair< ::std::string, ::std::unique_ptr<AST::ExprNode>> > items;
while( GET_TOK(tok, lex) == TOK_IDENT )
{
- ::std::string name = tok.str();
+ auto name = mv$(tok.ident_str());
GET_CHECK_TOK(tok, lex, TOK_COLON);
ExprNodeP val = Parse_Stmt(lex);
items.push_back( ::std::make_pair(::std::move(name), ::std::move(val)) );
@@ -1224,7 +1224,7 @@ ExprNodeP Parse_ExprMacro(TokenStream& lex, Token tok) ::std::string name = tok.str();
::std::string ident;
if( GET_TOK(tok, lex) == TOK_IDENT ) {
- ident = mv$(tok.str());
+ ident = mv$(tok.ident_str());
}
else {
PUTBACK(tok, lex);
diff --git a/src/parse/lex.cpp b/src/parse/lex.cpp index 76c8ab5d..a5c4e372 100644 --- a/src/parse/lex.cpp +++ b/src/parse/lex.cpp @@ -251,6 +251,29 @@ Token Lexer::realGetToken() //::std::cout << "getTokenInt: tok = " << tok << ::std::endl; switch(tok.type()) { + case TOK_IDENT: + if( m_hygine_stack.size() > 0 ) + { + m_hygine_stack.back() ++; + } + return tok; + + case TOK_PAREN_OPEN: + case TOK_SQUARE_OPEN: + case TOK_BRACE_OPEN: + case TOK_ATTR_OPEN: + case TOK_CATTR_OPEN: + m_hygine_stack.push_back(0); + return tok; + case TOK_PAREN_CLOSE: + case TOK_SQUARE_CLOSE: + case TOK_BRACE_CLOSE: + m_hygine_stack.pop_back(); + if( m_hygine_stack.size() > 0 ) { + m_hygine_stack.back() ++; + } + return tok; + case TOK_NEWLINE: m_line ++; m_line_ofs = 0; @@ -767,7 +790,7 @@ Token Lexer::getTokenInt_Identifier(Codepoint leader, Codepoint leader2) if( str < RWORDS[i].chars ) break; if( str == RWORDS[i].chars ) return Token((enum eTokenType)RWORDS[i].type); } - return Token(TOK_IDENT, str); + return Token(Ident( Ident::Hygine(m_file_index, m_hygine_stack), mv$(str) )); } } diff --git a/src/parse/lex.hpp b/src/parse/lex.hpp index 77151bea..208fa670 100644 --- a/src/parse/lex.hpp +++ b/src/parse/lex.hpp @@ -125,6 +125,10 @@ class Lexer: bool m_last_char_valid; Codepoint m_last_char; Token m_next_token; // Used when lexing generated two tokens + + unsigned int m_file_index; + // Incremented on every ident and TT close, pushed on TT open + ::std::vector<unsigned int> m_hygine_stack; public: Lexer(const ::std::string& filename); diff --git a/src/parse/paths.cpp b/src/parse/paths.cpp index e7fe1b0b..5e0faf90 100644 --- a/src/parse/paths.cpp +++ b/src/parse/paths.cpp @@ -91,14 +91,10 @@ AST::Path Parse_Path(TokenStream& lex, bool is_abs, eParsePathGenericMode generi } } else { - //assert( GET_TOK(tok, lex) == TOK_IDENT ); - //if( lex.lookahead(0) != TOK_DOUBLE_COLON ) { - // return AST::Path( tok.str() ); - //} - //else { - // PUTBACK(tok, lex); - return AST::Path(AST::Path::TagRelative(), Parse_PathNodes(lex, generic_mode)); - //} + GET_CHECK_TOK(tok, lex, TOK_IDENT); + auto hygine = mv$( tok.ident().hygine ); + PUTBACK(tok, lex); + return AST::Path(AST::Path::TagRelative(), mv$(hygine), Parse_PathNodes(lex, generic_mode)); } } @@ -115,7 +111,7 @@ AST::Path Parse_Path(TokenStream& lex, bool is_abs, eParsePathGenericMode generi ::AST::PathParams params; CHECK_TOK(tok, TOK_IDENT); - ::std::string component = tok.str(); + auto component = mv$( tok.ident_str() ); GET_TOK(tok, lex); if( generic_mode == PATH_GENERIC_TYPE ) @@ -144,6 +140,7 @@ AST::Path Parse_Path(TokenStream& lex, bool is_abs, eParsePathGenericMode generi { PUTBACK(tok, lex); do { + // TODO: Trailing commas args.push_back( Parse_Type(lex) ); } while( GET_TOK(tok, lex) == TOK_COMMA ); } @@ -221,7 +218,7 @@ AST::Path Parse_Path(TokenStream& lex, bool is_abs, eParsePathGenericMode generi case TOK_IDENT: if( LOOK_AHEAD(lex) == TOK_EQUAL ) { - ::std::string name = tok.str(); + ::std::string name = mv$(tok.ident_str()); GET_CHECK_TOK(tok, lex, TOK_EQUAL); assoc_bounds.push_back( ::std::make_pair( mv$(name), Parse_Type(lex,false) ) ); break; diff --git a/src/parse/pattern.cpp b/src/parse/pattern.cpp index 2b1be50e..df251bd3 100644 --- a/src/parse/pattern.cpp +++ b/src/parse/pattern.cpp @@ -80,18 +80,19 @@ AST::Pattern Parse_Pattern(TokenStream& lex, bool is_refutable) // Fall through } - ::std::string bind_name; + AST::PatternBinding binding; // If a 'ref' or 'mut' annotation was seen, the next name must be a binding name if( expect_bind ) { CHECK_TOK(tok, TOK_IDENT); - bind_name = tok.str(); + auto bind_name = tok.take_ident(); // If there's no '@' after it, it's a name binding only (_ pattern) if( GET_TOK(tok, lex) != TOK_AT ) { PUTBACK(tok, lex); - return AST::Pattern(AST::Pattern::TagBind(), bind_name, bind_type, is_mut); + return AST::Pattern(AST::Pattern::TagBind(), mv$(bind_name), bind_type, is_mut); } + binding = AST::PatternBinding( mv$(bind_name), bind_type, is_mut ); // '@' consumed, move on to next token GET_TOK(tok, lex); @@ -113,8 +114,8 @@ AST::Pattern Parse_Pattern(TokenStream& lex, bool is_refutable) break; // Known binding `ident @` case TOK_AT: - bind_name = mv$(tok.str()); - GET_TOK(tok, lex); + binding = AST::PatternBinding( tok.take_ident(), bind_type/*MOVE*/, is_mut/*false*/ ); + GET_TOK(tok, lex); // '@' GET_TOK(tok, lex); // Match lex.putback() below break; default: // Maybe bind @@ -122,11 +123,11 @@ AST::Pattern Parse_Pattern(TokenStream& lex, bool is_refutable) if( is_refutable ) { assert(bind_type == ::AST::PatternBinding::Type::MOVE); assert(is_mut == false); - return AST::Pattern(AST::Pattern::TagMaybeBind(), mv$(tok.str())); + return AST::Pattern(AST::Pattern::TagMaybeBind(), tok.take_ident()); } // Otherwise, it IS a binding else { - return AST::Pattern(AST::Pattern::TagBind(), mv$(tok.str()), bind_type, is_mut); + return AST::Pattern(AST::Pattern::TagBind(), tok.take_ident(), bind_type, is_mut); } } } @@ -137,8 +138,9 @@ AST::Pattern Parse_Pattern(TokenStream& lex, bool is_refutable) PUTBACK(tok, lex); auto pat = Parse_PatternReal(lex, is_refutable); - pat.set_bind(bind_name, bind_type, is_mut); - return mv$(pat); + //pat.set_bind( mv$(binding) ); + pat.binding() = mv$(binding); + return pat; } AST::Pattern Parse_PatternReal(TokenStream& lex, bool is_refutable) @@ -263,46 +265,48 @@ AST::Pattern Parse_PatternReal_Slice(TokenStream& lex, bool is_refutable) auto sp = lex.start_span(); Token tok; - auto rv = ::AST::Pattern( AST::Pattern::TagSlice() ); - auto& rv_array = rv.data().as_Slice(); + ::std::vector< ::AST::Pattern> leading; + ::std::vector< ::AST::Pattern> trailing; + ::AST::PatternBinding inner_binding; + bool is_split = false; - bool is_trailing = false; while(GET_TOK(tok, lex) != TOK_SQUARE_CLOSE) { - ::std::string binding_name; + bool has_binding = true; + ::AST::PatternBinding binding; if( tok.type() == TOK_RWORD_REF && lex.lookahead(0) == TOK_IDENT && lex.lookahead(1) == TOK_DOUBLE_DOT ) { GET_TOK(tok, lex); - // TODO: Bind type - binding_name = tok.str(); + binding = ::AST::PatternBinding( tok.take_ident(), ::AST::PatternBinding::Type::REF, false ); } else if( tok.type() == TOK_IDENT && lex.lookahead(0) == TOK_DOUBLE_DOT) { - // TODO: Bind type - binding_name = tok.str(); + binding = ::AST::PatternBinding( tok.take_ident(), ::AST::PatternBinding::Type::MOVE, false ); } else if( tok.type() == TOK_UNDERSCORE && lex.lookahead(0) == TOK_DOUBLE_DOT) { - binding_name = "_"; + // No binding, but switching to trailing } else if( tok.type() == TOK_DOUBLE_DOT ) { - binding_name = "_"; + // No binding, but switching to trailing PUTBACK(tok, lex); } else { + has_binding = false; } - if( binding_name != "" ) { - if(is_trailing) + if( has_binding ) { + if(is_split) ERROR(lex.end_span(sp), E0000, "Multiple instances of .. in a slice pattern"); - rv_array.extra_bind = mv$(binding_name); - is_trailing = true; + + inner_binding = mv$(binding); + is_split = true; GET_TOK(tok, lex); // TOK_DOUBLE_DOT } else { PUTBACK(tok, lex); - if(is_trailing) { - rv_array.trailing.push_back( Parse_Pattern(lex, is_refutable) ); + if(!is_split) { + leading.push_back( Parse_Pattern(lex, is_refutable) ); } else { - rv_array.leading.push_back( Parse_Pattern(lex, is_refutable) ); + trailing.push_back( Parse_Pattern(lex, is_refutable) ); } } @@ -311,7 +315,16 @@ AST::Pattern Parse_PatternReal_Slice(TokenStream& lex, bool is_refutable) } CHECK_TOK(tok, TOK_SQUARE_CLOSE); - return rv; + if( is_split ) + { + return ::AST::Pattern( ::AST::Pattern::Data::make_SplitSlice({ mv$(leading), mv$(inner_binding), mv$(trailing) }) ); + } + else + { + assert( !inner_binding.is_valid() ); + assert( trailing.empty() ); + return ::AST::Pattern( ::AST::Pattern::Data::make_Slice({ mv$(leading) }) ); + } } ::AST::Pattern::TuplePat Parse_PatternTuple(TokenStream& lex, bool is_refutable) @@ -453,14 +466,16 @@ AST::Pattern Parse_PatternStruct(TokenStream& lex, AST::Path path, bool is_refut } CHECK_TOK(tok, TOK_IDENT); - ::std::string field = tok.str(); + auto field_ident = tok.take_ident(); + ::std::string field_name; GET_TOK(tok, lex); AST::Pattern pat; if( is_short_bind || tok.type() != TOK_COLON ) { PUTBACK(tok, lex); - pat = AST::Pattern(AST::Pattern::TagBind(), field); - pat.set_bind(field, bind_type, is_mut); + pat = AST::Pattern(); + field_name = field_ident.name; + pat.set_bind(mv$(field_ident), bind_type, is_mut); if( is_box ) { pat = AST::Pattern(AST::Pattern::TagBox(), mv$(pat)); @@ -468,10 +483,11 @@ AST::Pattern Parse_PatternStruct(TokenStream& lex, AST::Path path, bool is_refut } else { CHECK_TOK(tok, TOK_COLON); + field_name = mv$(field_ident.name); pat = Parse_Pattern(lex, is_refutable); } - subpats.push_back( ::std::make_pair(::std::move(field), ::std::move(pat)) ); + subpats.push_back( ::std::make_pair(mv$(field_name), mv$(pat)) ); } while( GET_TOK(tok, lex) == TOK_COMMA ); CHECK_TOK(tok, TOK_BRACE_CLOSE); diff --git a/src/parse/root.cpp b/src/parse/root.cpp index 5954c76d..6c9acc14 100644 --- a/src/parse/root.cpp +++ b/src/parse/root.cpp @@ -132,7 +132,8 @@ AST::GenericParams Parse_GenericParams(TokenStream& lex) if( tok.type() == TOK_IDENT )
{
- ::std::string param_name = tok.str();
+ // TODO: Hygine
+ ::std::string param_name = mv$(tok.ident_str());
ret.add_ty_param( AST::TypeParam( param_name ) );
auto param_ty = TypeRef(lex.getPosition(), param_name);
@@ -150,6 +151,7 @@ AST::GenericParams Parse_GenericParams(TokenStream& lex) }
else if( tok.type() == TOK_LIFETIME )
{
+ // TODO: Should lifetimes have hygine?
::std::string param_name = tok.str();
ret.add_lft_param( param_name );
if( GET_TOK(tok, lex) == TOK_COLON )
@@ -527,7 +529,7 @@ AST::Struct Parse_Struct(TokenStream& lex, const AST::MetaItems& meta_items) }
CHECK_TOK(tok, TOK_IDENT);
- ::std::string name = tok.str();
+ auto name = mv$(tok.ident_str());
GET_CHECK_TOK(tok, lex, TOK_COLON);
TypeRef type = Parse_Type(lex);
@@ -613,7 +615,7 @@ AST::Trait Parse_TraitDef(TokenStream& lex, const AST::MetaItems& meta_items) }
bool is_specialisable = false;
- if( tok.type() == TOK_IDENT && tok.str() == "default" ) {
+ if( tok.type() == TOK_IDENT && tok.ident_str() == "default" ) {
is_specialisable = true;
GET_TOK(tok, lex);
}
@@ -627,7 +629,7 @@ AST::Trait Parse_TraitDef(TokenStream& lex, const AST::MetaItems& meta_items) {
case TOK_RWORD_STATIC: {
GET_CHECK_TOK(tok, lex, TOK_IDENT);
- auto name = mv$(tok.str());
+ auto name = mv$(tok.ident_str());
GET_CHECK_TOK(tok, lex, TOK_COLON);
auto ty = Parse_Type(lex);
GET_CHECK_TOK(tok, lex, TOK_SEMICOLON);
@@ -644,7 +646,7 @@ AST::Trait Parse_TraitDef(TokenStream& lex, const AST::MetaItems& meta_items) break; }
case TOK_RWORD_CONST: {
GET_CHECK_TOK(tok, lex, TOK_IDENT);
- auto name = mv$(tok.str());
+ auto name = mv$(tok.ident_str());
GET_CHECK_TOK(tok, lex, TOK_COLON);
auto ty = Parse_Type(lex);
@@ -662,7 +664,7 @@ AST::Trait Parse_TraitDef(TokenStream& lex, const AST::MetaItems& meta_items) case TOK_RWORD_TYPE: {
auto atype_params = ::AST::GenericParams { };
GET_CHECK_TOK(tok, lex, TOK_IDENT);
- ::std::string name = tok.str();
+ auto name = mv$(tok.ident_str());
if( GET_TOK(tok, lex) == TOK_COLON )
{
// Bounded associated type
@@ -702,7 +704,7 @@ AST::Trait Parse_TraitDef(TokenStream& lex, const AST::MetaItems& meta_items) CHECK_TOK(tok, TOK_RWORD_FN);
case TOK_RWORD_FN: {
GET_CHECK_TOK(tok, lex, TOK_IDENT);
- ::std::string name = tok.str();
+ ::std::string name = tok.take_ident().into_string();
// Self allowed, prototype-form allowed (optional names and no code)
auto fcn = Parse_FunctionDef(lex, abi, true, true, fn_is_unsafe, fn_is_const);
if( GET_TOK(tok, lex) == TOK_BRACE_OPEN )
@@ -766,7 +768,7 @@ AST::Enum Parse_EnumDef(TokenStream& lex, const AST::MetaItems& meta_items) SET_ATTRS(lex, item_attrs);
CHECK_TOK(tok, TOK_IDENT);
- ::std::string name = tok.str();
+ ::std::string name = tok.take_ident().into_string();
if( GET_TOK(tok, lex) == TOK_PAREN_OPEN )
{
::std::vector<TypeRef> types;
@@ -813,7 +815,7 @@ AST::Enum Parse_EnumDef(TokenStream& lex, const AST::MetaItems& meta_items) }
GET_CHECK_TOK(tok, lex, TOK_IDENT);
- auto name = mv$(tok.str());
+ auto name = tok.take_ident().into_string();
GET_CHECK_TOK(tok, lex, TOK_COLON);
auto ty = Parse_Type(lex);
fields.push_back( ::AST::StructItem(mv$(field_attrs), true, mv$(name), mv$(ty)) );
@@ -886,7 +888,7 @@ AST::Enum Parse_EnumDef(TokenStream& lex, const AST::MetaItems& meta_items) }
GET_CHECK_TOK(tok, lex, TOK_IDENT);
- auto name = mv$(tok.str());
+ auto name = tok.take_ident().into_string();
GET_CHECK_TOK(tok, lex, TOK_COLON);
auto ty = Parse_Type(lex);
@@ -911,7 +913,7 @@ AST::MetaItem Parse_MetaItem(TokenStream& lex) }
CHECK_TOK(tok, TOK_IDENT);
- ::std::string name = tok.str();
+ ::std::string name = tok.take_ident().into_string();
switch(GET_TOK(tok, lex))
{
case TOK_EQUAL:
@@ -1069,7 +1071,7 @@ void Parse_Impl_Item(TokenStream& lex, AST::Impl& impl) }
bool is_specialisable = false;
- if( tok.type() == TOK_IDENT && tok.str() == "default" ) {
+ if( tok.type() == TOK_IDENT && tok.ident() == "default" ) {
is_specialisable = true;
GET_TOK(tok, lex);
}
@@ -1081,7 +1083,7 @@ void Parse_Impl_Item(TokenStream& lex, AST::Impl& impl) {
case TOK_RWORD_TYPE: {
GET_CHECK_TOK(tok, lex, TOK_IDENT);
- ::std::string name = tok.str();
+ auto name = tok.take_ident().into_string();
GET_CHECK_TOK(tok, lex, TOK_EQUAL);
impl.add_type(is_public, is_specialisable, name, Parse_Type(lex));
GET_CHECK_TOK(tok, lex, TOK_SEMICOLON);
@@ -1096,7 +1098,7 @@ void Parse_Impl_Item(TokenStream& lex, AST::Impl& impl) if( tok.type() != TOK_RWORD_FN && tok.type() != TOK_RWORD_UNSAFE && !fn_is_unsafe )
{
CHECK_TOK(tok, TOK_IDENT);
- auto name = mv$(tok.str());
+ auto name = tok.take_ident().into_string();
GET_CHECK_TOK(tok, lex, TOK_COLON);
auto ty = Parse_Type(lex);
GET_CHECK_TOK(tok, lex, TOK_EQUAL);
@@ -1131,7 +1133,8 @@ void Parse_Impl_Item(TokenStream& lex, AST::Impl& impl) // FALL
case TOK_RWORD_FN: {
GET_CHECK_TOK(tok, lex, TOK_IDENT);
- ::std::string name = tok.str();
+ // TODO: Hygine on function names? - Not in impl blocks?
+ ::std::string name = tok.take_ident().into_string();
DEBUG("Function " << name);
// - Self allowed, can't be prototype-form
auto fcn = Parse_FunctionDefWithCode(lex, abi, true, fn_is_unsafe, fn_is_const);
@@ -1182,7 +1185,7 @@ AST::ExternBlock Parse_ExternBlock(TokenStream& lex, ::std::string abi, ::AST::M {
case TOK_RWORD_FN: {
GET_CHECK_TOK(tok, lex, TOK_IDENT);
- auto name = mv$(tok.str());
+ auto name = tok.take_ident().into_string();
// parse function as prototype
// - no self, "safe" and not const
auto i = ::AST::Item( Parse_FunctionDef(lex, abi, false, true, false,false) );
@@ -1200,7 +1203,7 @@ AST::ExternBlock Parse_ExternBlock(TokenStream& lex, ::std::string abi, ::AST::M else
PUTBACK(tok, lex);
GET_CHECK_TOK(tok, lex, TOK_IDENT);
- auto name = mv$(tok.str());
+ auto name = tok.take_ident().into_string();
GET_CHECK_TOK(tok, lex, TOK_COLON);
auto type = Parse_Type(lex);
GET_CHECK_TOK(tok, lex, TOK_SEMICOLON);
@@ -1239,12 +1242,13 @@ void Parse_Use_Set(TokenStream& lex, const ProtoSpan& ps, const AST::Path& base_ }
else {
CHECK_TOK(tok, TOK_IDENT);
- path = base_path + AST::PathNode(tok.str(), {});
- name = mv$(tok.str());
+ path = base_path + AST::PathNode(tok.ident_str(), {});
+ name = mv$(tok.ident_str());
}
+
if( GET_TOK(tok, lex) == TOK_RWORD_AS ) {
GET_CHECK_TOK(tok, lex, TOK_IDENT);
- name = mv$(tok.str());
+ name = mv$(tok.ident_str());
}
else {
PUTBACK(tok, lex);
@@ -1278,7 +1282,7 @@ void Parse_Use(TokenStream& lex, ::std::function<void(AST::UseStmt, ::std::strin path = AST::Path( AST::Path::TagSuper(), count, {} );
break; }
case TOK_IDENT:
- path.append( AST::PathNode(tok.str(), {}) );
+ path.append( AST::PathNode(tok.take_ident().into_string(), {}) );
break;
// Leading :: is allowed and ignored for the $crate feature
case TOK_DOUBLE_COLON:
@@ -1305,7 +1309,7 @@ void Parse_Use(TokenStream& lex, ::std::function<void(AST::UseStmt, ::std::strin {
if( GET_TOK(tok, lex) == TOK_IDENT )
{
- path.append( AST::PathNode(tok.str(), {}) );
+ path.append( AST::PathNode(tok.take_ident().into_string(), {}) );
}
else
{
@@ -1334,7 +1338,7 @@ void Parse_Use(TokenStream& lex, ::std::function<void(AST::UseStmt, ::std::strin if( tok.type() == TOK_RWORD_AS )
{
GET_CHECK_TOK(tok, lex, TOK_IDENT);
- name = tok.str();
+ name = tok.take_ident().into_string();
}
else
{
@@ -1352,7 +1356,7 @@ void Parse_Use(TokenStream& lex, ::std::function<void(AST::UseStmt, ::std::strin Token tok;
::std::string ident;
if( GET_TOK(tok, lex) == TOK_IDENT ) {
- ident = mv$(tok.str());
+ ident = tok.take_ident().into_string();
}
else {
PUTBACK(tok, lex);
@@ -1443,7 +1447,7 @@ void Parse_Use(TokenStream& lex, ::std::function<void(AST::UseStmt, ::std::strin // `extern "<ABI>" fn ...`
case TOK_RWORD_FN: {
GET_CHECK_TOK(tok, lex, TOK_IDENT);
- item_name = tok.str();
+ item_name = mv$(tok.ident_str());
item_data = ::AST::Item( Parse_FunctionDefWithCode(lex, abi, false, false,false) );
break; }
// `extern "ABI" {`
@@ -1458,7 +1462,7 @@ void Parse_Use(TokenStream& lex, ::std::function<void(AST::UseStmt, ::std::strin // `extern fn ...`
case TOK_RWORD_FN:
GET_CHECK_TOK(tok, lex, TOK_IDENT);
- item_name = tok.str();
+ item_name = mv$(tok.ident_str());
item_data = ::AST::Item( Parse_FunctionDefWithCode(lex, "C", false, false,false) );
break;
@@ -1480,17 +1484,17 @@ void Parse_Use(TokenStream& lex, ::std::function<void(AST::UseStmt, ::std::strin item_data = ::AST::Item::make_Crate({ tok.str() });
GET_CHECK_TOK(tok, lex, TOK_RWORD_AS);
GET_CHECK_TOK(tok, lex, TOK_IDENT);
- item_name = mv$(tok.str());
+ item_name = mv$(tok.ident_str());
break;
// `extern crate crate_name;`
// `extern crate crate_name as other_name;`
case TOK_IDENT:
- item_name = mv$(tok.str());
+ item_name = mv$(tok.ident_str());
if(GET_TOK(tok, lex) == TOK_RWORD_AS) {
item_data = ::AST::Item::make_Crate({ mv$(item_name) });
GET_CHECK_TOK(tok, lex, TOK_IDENT);
- item_name = mv$(tok.str());
+ item_name = mv$(tok.ident_str());
}
else {
PUTBACK(tok, lex);
@@ -1513,7 +1517,7 @@ void Parse_Use(TokenStream& lex, ::std::function<void(AST::UseStmt, ::std::strin switch( GET_TOK(tok, lex) )
{
case TOK_IDENT: {
- item_name = tok.str();
+ item_name = mv$(tok.ident_str());
GET_CHECK_TOK(tok, lex, TOK_COLON);
TypeRef type = Parse_Type(lex);
@@ -1525,12 +1529,12 @@ void Parse_Use(TokenStream& lex, ::std::function<void(AST::UseStmt, ::std::strin case TOK_RWORD_UNSAFE:
GET_CHECK_TOK(tok, lex, TOK_RWORD_FN);
GET_CHECK_TOK(tok, lex, TOK_IDENT);
- item_name = tok.str();
+ item_name = mv$(tok.ident_str());
item_data = ::AST::Item( Parse_FunctionDefWithCode(lex, ABI_RUST, false, true,true/*unsafe,const*/) );
break;
case TOK_RWORD_FN:
GET_CHECK_TOK(tok, lex, TOK_IDENT);
- item_name = tok.str();
+ item_name = mv$(tok.ident_str());
// - self not allowed, not prototype
item_data = ::AST::Item( Parse_FunctionDefWithCode(lex, ABI_RUST, false, false,true/*unsafe,const*/) );
break;
@@ -1547,7 +1551,7 @@ void Parse_Use(TokenStream& lex, ::std::function<void(AST::UseStmt, ::std::strin GET_TOK(tok, lex);
}
CHECK_TOK(tok, TOK_IDENT);
- item_name = tok.str();
+ item_name = mv$(tok.ident_str());
GET_CHECK_TOK(tok, lex, TOK_COLON);
TypeRef type = Parse_Type(lex);
@@ -1578,20 +1582,20 @@ void Parse_Use(TokenStream& lex, ::std::function<void(AST::UseStmt, ::std::strin }
GET_CHECK_TOK(tok, lex, TOK_RWORD_FN);
GET_CHECK_TOK(tok, lex, TOK_IDENT);
- item_name = mv$( tok.str() );
+ item_name = mv$(tok.ident_str());
item_data = ::AST::Item( Parse_FunctionDefWithCode(lex, abi, false, true,false/*unsafe,const*/) );
break; }
// `unsafe fn`
case TOK_RWORD_FN:
GET_CHECK_TOK(tok, lex, TOK_IDENT);
- item_name = mv$( tok.str() );
+ item_name = mv$(tok.ident_str());
// - self not allowed, not prototype
item_data = ::AST::Item( Parse_FunctionDefWithCode(lex, ABI_RUST, false, true,false/*unsafe,const*/) );
break;
// `unsafe trait`
case TOK_RWORD_TRAIT:
GET_CHECK_TOK(tok, lex, TOK_IDENT);
- item_name = tok.str();
+ item_name = mv$(tok.ident_str());
// TODO: Mark as unsafe
meta_items.push_back( AST::MetaItem("#UNSAFE") );
item_data = ::AST::Item( Parse_TraitDef(lex, meta_items) );
@@ -1606,33 +1610,33 @@ void Parse_Use(TokenStream& lex, ::std::function<void(AST::UseStmt, ::std::strin // `fn`
case TOK_RWORD_FN:
GET_CHECK_TOK(tok, lex, TOK_IDENT);
- item_name = tok.str();
+ item_name = mv$(tok.ident_str());
// - self not allowed, not prototype
item_data = ::AST::Item( Parse_FunctionDefWithCode(lex, ABI_RUST, false, false,false/*unsafe,const*/) );
break;
// `type`
case TOK_RWORD_TYPE:
GET_CHECK_TOK(tok, lex, TOK_IDENT);
- item_name = mv$(tok.str());
+ item_name = mv$(tok.ident_str());
item_data = ::AST::Item( Parse_TypeAlias(lex) );
break;
// `struct`
case TOK_RWORD_STRUCT:
GET_CHECK_TOK(tok, lex, TOK_IDENT);
- item_name = mv$(tok.str());
+ item_name = mv$(tok.ident_str());
item_data = ::AST::Item( Parse_Struct(lex, meta_items) );
break;
// `enum`
case TOK_RWORD_ENUM:
GET_CHECK_TOK(tok, lex, TOK_IDENT);
- item_name = mv$(tok.str());
+ item_name = mv$(tok.ident_str());
item_data = ::AST::Item( Parse_EnumDef(lex, meta_items) );
break;
// Contextual keywords
case TOK_IDENT:
- if( tok.str() == "union" ) {
+ if( tok.ident_str() == "union" ) {
GET_CHECK_TOK(tok, lex, TOK_IDENT);
- item_name = mv$(tok.str());
+ item_name = mv$(tok.ident_str());
item_data = ::AST::Item( Parse_Union(lex, meta_items) );
}
else {
@@ -1645,13 +1649,13 @@ void Parse_Use(TokenStream& lex, ::std::function<void(AST::UseStmt, ::std::strin // `trait`
case TOK_RWORD_TRAIT:
GET_CHECK_TOK(tok, lex, TOK_IDENT);
- item_name = tok.str();
+ item_name = mv$(tok.ident_str());
item_data = ::AST::Item( Parse_TraitDef(lex, meta_items) );
break;
case TOK_RWORD_MOD: {
GET_CHECK_TOK(tok, lex, TOK_IDENT);
- auto name = mv$(tok.str());
+ auto name = mv$(tok.ident_str());
DEBUG("Sub module '" << name << "'");
AST::Module submod( mod_path + name );
diff --git a/src/parse/token.cpp b/src/parse/token.cpp index 05ded69f..9f84df79 100644 --- a/src/parse/token.cpp +++ b/src/parse/token.cpp @@ -53,7 +53,12 @@ Token::Token(enum eTokenType type, ::std::string str): m_type(type), m_data(Data::make_String(mv$(str))) { + assert( m_type != TOK_IDENT ); } +Token::Token(Ident ident): + m_type(TOK_IDENT), + m_data(Data( mv$(ident) )) +{} Token::Token(uint64_t val, enum eCoreType datatype): m_type(TOK_INTEGER), m_data( Data::make_Integer({datatype, val}) ) @@ -152,6 +157,7 @@ Token::Token(const Token& t): (None, ), (String, m_data = Data::make_String(e); ), (Integer, m_data = Data::make_Integer(e);), + (Ident , m_data = Data(e);), (Float, m_data = Data::make_Float(e);), (Fragment, BUG(t.m_pos, "Attempted to copy a fragment - " << t);) ) @@ -171,6 +177,7 @@ Token Token::clone() const (Integer, rv.m_data = Data::make_Integer(e); ), + (Ident, rv.m_data = Data(e); ), (Float, rv.m_data = Data::make_Float(e); ), @@ -299,7 +306,7 @@ struct EscapedString { case TOK_INTERPOLATED_META: return "/*:meta*/"; case TOK_INTERPOLATED_ITEM: return "/*:item*/"; // Value tokens - case TOK_IDENT: return m_data.as_String(); + case TOK_IDENT: return m_data.as_Ident().name; case TOK_MACRO: return m_data.as_String() + "!"; case TOK_LIFETIME: return "'" + m_data.as_String(); case TOK_INTEGER: return FMT(m_data.as_Integer().m_intval); // TODO: suffix for type @@ -464,6 +471,10 @@ SERIALISE_TYPE(Token::, "Token", { s % e.m_datatype; s.item( e.m_intval ); ), + (Ident, + // Hygine contex for serialised idents is left for the loader + s << e.name; + ), (Float, s % e.m_datatype; s.item( e.m_floatval ); @@ -484,19 +495,25 @@ SERIALISE_TYPE(Token::, "Token", { { case Token::Data::TAGDEAD: break; case Token::Data::TAG_None: break; - case Token::Data::TAG_String:{ + case Token::Data::TAG_String: { ::std::string str; s.item( str ); m_data = Token::Data::make_String(str); break; } - case Token::Data::TAG_Integer:{ + case Token::Data::TAG_Integer: { enum eCoreType dt; uint64_t v; s % dt; s.item( v ); m_data = Token::Data::make_Integer({dt, v}); break; } - case Token::Data::TAG_Float:{ + case Token::Data::TAG_Ident: { + ::std::string str; + s.item( str ); + // - Hygine is populated by caller, fill with dummy values for now + m_data = Token::Data::make_Ident(Ident { {~0u,{}}, mv$(str) }); + break; } + case Token::Data::TAG_Float: { enum eCoreType dt; double v; s % dt; diff --git a/src/parse/token.hpp b/src/parse/token.hpp index 5fdcbc77..94458f1f 100644 --- a/src/parse/token.hpp +++ b/src/parse/token.hpp @@ -1,4 +1,9 @@ /* + * MRustC - Rust Compiler + * - By John Hodge (Mutabah/thePowersGang) + * + * parse/token.hpp + * - Lexer Tokens */ #pragma once @@ -6,6 +11,7 @@ #include <tagged_union.hpp> #include <serialise.hpp> #include "../coretypes.hpp" +#include <ident.hpp> enum eTokenType { @@ -55,6 +61,7 @@ class Token: TAGGED_UNION(Data, None, (None, struct {}), (String, ::std::string), + (Ident, Ident), (Integer, struct { enum eCoreType m_datatype; uint64_t m_intval; @@ -69,6 +76,7 @@ class Token: enum eTokenType m_type; Data m_data; Position m_pos; + public: virtual ~Token(); Token(); @@ -91,6 +99,7 @@ public: Token(enum eTokenType type); Token(enum eTokenType type, ::std::string str); + Token(Ident ident); Token(uint64_t val, enum eCoreType datatype); Token(double val, enum eCoreType datatype); Token(const InterpolatedFragment& ); @@ -98,11 +107,17 @@ public: Token(TagTakeIP, InterpolatedFragment ); enum eTokenType type() const { return m_type; } + ::std::string& str() { return m_data.as_String(); } const ::std::string& str() const { return m_data.as_String(); } enum eCoreType datatype() const { TU_MATCH_DEF(Data, (m_data), (e), (assert(!"Getting datatype of invalid token type");), (Integer, return e.m_datatype;), (Float, return e.m_datatype;)) } uint64_t intval() const { return m_data.as_Integer().m_intval; } double floatval() const { return m_data.as_Float().m_floatval; } + const Ident& ident() const { return m_data.as_Ident(); } + Ident take_ident() { return ::std::move(m_data.as_Ident()); } + ::std::string& ident_str() { return m_data.as_Ident().name; } + const ::std::string& ident_str() const { return m_data.as_Ident().name; } + TypeRef& frag_type() { assert(m_type == TOK_INTERPOLATED_TYPE); return *reinterpret_cast<TypeRef*>( m_data.as_Fragment() ); } AST::Path& frag_path() { assert(m_type == TOK_INTERPOLATED_PATH); return *reinterpret_cast<AST::Path*>( m_data.as_Fragment() ); } AST::Pattern& frag_pattern() { assert(m_type == TOK_INTERPOLATED_PATTERN); return *reinterpret_cast<AST::Pattern*>( m_data.as_Fragment() ); } @@ -115,7 +130,8 @@ public: return false; TU_MATCH(Data, (m_data, r.m_data), (e, re), (None, return true;), - (String, return e == re;), + (String, return e == re; ), + (Ident, return e == re; ), (Integer, return e.m_datatype == re.m_datatype && e.m_intval == re.m_intval;), (Float, return e.m_datatype == re.m_datatype && e.m_floatval == re.m_floatval;), (Fragment, assert(!"Token equality on Fragment");) diff --git a/src/resolve/absolute.cpp b/src/resolve/absolute.cpp index 0d47eb21..a37e0fce 100644 --- a/src/resolve/absolute.cpp +++ b/src/resolve/absolute.cpp @@ -47,7 +47,7 @@ struct Context (VarBlock, struct { unsigned int level; // "Map" of names to function-level variable slots - ::std::vector< Named< unsigned int > > variables; + ::std::vector< ::std::pair<Ident, unsigned int> > variables; }), (Generic, struct { // Map of names to slots @@ -169,7 +169,7 @@ struct Context m_block_level += 1; DEBUG("Push block to " << m_block_level); } - unsigned int push_var(const Span& sp, const ::std::string& name) { + unsigned int push_var(const Span& sp, const Ident& name) { if( m_var_count == ~0u ) { BUG(sp, "Assigning local when there's no variable context"); } @@ -183,8 +183,8 @@ struct Context for( const auto& v : vb.variables ) { // TODO: Error when a binding is used twice or not at all - if( v.name == name ) { - return v.value; + if( v.first == name ) { + return v.second; } } ERROR(sp, E0000, "Mismatched bindings in pattern"); @@ -198,7 +198,7 @@ struct Context DEBUG("New var @ " << m_block_level << ": #" << m_var_count << " " << name); auto& vb = m_name_context.back().as_VarBlock(); assert(vb.level == m_block_level); - vb.variables.push_back( Named<unsigned int> { name, m_var_count } ); + vb.variables.push_back( ::std::make_pair(mv$(name), m_var_count) ); m_var_count += 1; assert( m_var_count >= vb.variables.size() ); return m_var_count - 1; @@ -209,7 +209,7 @@ struct Context if( m_name_context.size() > 0 && m_name_context.back().is_VarBlock() && m_name_context.back().as_VarBlock().level == m_block_level ) { DEBUG("Pop block from " << m_block_level << " with vars:" << FMT_CB(os, for(const auto& v : m_name_context.back().as_VarBlock().variables) - os << " " << v.name << "#" << v.value; + os << " " << v.first << "#" << v.second; )); m_name_context.pop_back(); } @@ -259,20 +259,8 @@ struct Context } return ""; } - AST::Path lookup_mod(const Span& sp, const ::std::string& name) const { - return this->lookup(sp, name, LookupMode::Namespace); - } - AST::Path lookup_type(const Span& sp, const ::std::string& name) const { - return this->lookup(sp, name, LookupMode::Type); - } - AST::Path lookup_constant(const Span& sp, const ::std::string& name) const { - return this->lookup(sp, name, LookupMode::Constant); - } - AST::Path lookup_value(const Span& sp, const ::std::string& name) const { - return this->lookup(sp, name, LookupMode::Variable); - } - AST::Path lookup(const Span& sp, const ::std::string& name, LookupMode mode) const { - auto rv = this->lookup_opt(name, mode); + AST::Path lookup(const Span& sp, const ::std::string& name, const Ident::Hygine& src_context, LookupMode mode) const { + auto rv = this->lookup_opt(name, src_context, mode); if( !rv.is_valid() ) { switch(mode) { @@ -364,7 +352,7 @@ struct Context } return false; } - AST::Path lookup_opt(const ::std::string& name, LookupMode mode) const { + AST::Path lookup_opt(const ::std::string& name, const Ident::Hygine& src_context, LookupMode mode) const { for(auto it = m_name_context.rbegin(); it != m_name_context.rend(); ++ it) { @@ -391,9 +379,9 @@ struct Context else { for( auto it2 = e.variables.rbegin(); it2 != e.variables.rend(); ++ it2 ) { - if( it2->name == name ) { + if( it2->first.name == name && it2->first.hygine.is_visible(src_context) ) { ::AST::Path rv(name); - rv.bind_variable( it2->value ); + rv.bind_variable( it2->second ); return rv; } } @@ -457,8 +445,9 @@ struct Context if( mode == LookupMode::Variable ) { for( auto it2 = e.variables.rbegin(); it2 != e.variables.rend(); ++ it2 ) { - if( it2->name == name ) { - return it2->value; + // TODO: Hyginic lookup? + if( it2->first.name == name ) { + return it2->second; } } } @@ -1255,7 +1244,7 @@ void Resolve_Absolute_Path(/*const*/ Context& context, const Span& sp, Context:: if(e.nodes.size() > 1) { // Look up type/module name - auto p = context.lookup(sp, e.nodes[0].name(), Context::LookupMode::Namespace); + auto p = context.lookup(sp, e.nodes[0].name(), e.hygine, Context::LookupMode::Namespace); DEBUG("Found type/mod - " << p); // HACK: If this is a primitive name, and resolved to a module. // - If the next component isn't found in the located module @@ -1344,7 +1333,7 @@ void Resolve_Absolute_Path(/*const*/ Context& context, const Span& sp, Context:: } else { // Look up value - auto p = context.lookup(sp, e.nodes[0].name(), mode); + auto p = context.lookup(sp, e.nodes[0].name(), e.hygine, mode); //DEBUG("Found path " << p << " for " << path); if( p.is_absolute() ) { assert( !p.nodes().empty() ); @@ -1726,7 +1715,7 @@ void Resolve_Absolute_Pattern(Context& context, bool allow_refutable, ::AST::Pa if( allow_refutable ) { auto name = mv$( e.name ); // Attempt to resolve the name in the current namespace, and if it fails, it's a binding - auto p = context.lookup_opt( name, Context::LookupMode::Pattern ); + auto p = context.lookup_opt( name.name, name.hygine, Context::LookupMode::Pattern ); if( p.is_valid() ) { Resolve_Absolute_Path(context, pat.span(), Context::LookupMode::Pattern, p); pat = ::AST::Pattern(::AST::Pattern::TagValue(), ::AST::Pattern::Value::make_Named(mv$(p))); @@ -1783,10 +1772,15 @@ void Resolve_Absolute_Pattern(Context& context, bool allow_refutable, ::AST::Pa ), (Slice, // NOTE: Can be irrefutable (if the type is array) + for(auto& sp : e.sub_pats) + Resolve_Absolute_Pattern(context, allow_refutable, sp); + ), + (SplitSlice, + // NOTE: Can be irrefutable (if the type is array) for(auto& sp : e.leading) Resolve_Absolute_Pattern(context, allow_refutable, sp); - if( e.extra_bind != "" && e.extra_bind != "_" ) { - context.push_var( pat.span(), e.extra_bind ); + if( e.extra_bind.is_valid() ) { + context.push_var( pat.span(), e.extra_bind.m_name ); } for(auto& sp : e.trailing) Resolve_Absolute_Pattern(context, allow_refutable, sp); |