summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2015-03-25 21:37:29 +0800
committerJohn Hodge <tpg@mutabah.net>2015-03-25 21:37:29 +0800
commit66880a641295734c437feb4eb32fb60bf5cd9af5 (patch)
tree723f47d10888e737548031b0d183cf30c0393121 /src
parent56601285b24450168e8b1853ae9c8b65f4576cb0 (diff)
downloadmrust-66880a641295734c437feb4eb32fb60bf5cd9af5.tar.gz
Macros updated with concat!, stringify!, and $crate
Diffstat (limited to 'src')
-rw-r--r--src/convert/resolve.cpp51
-rw-r--r--src/dump_as_rust.cpp10
-rw-r--r--src/macros.cpp94
-rw-r--r--src/parse/expr.cpp20
-rw-r--r--src/parse/lex.cpp147
-rw-r--r--src/parse/lex.hpp20
-rw-r--r--src/parse/pattern.cpp3
-rw-r--r--src/parse/root.cpp12
8 files changed, 319 insertions, 38 deletions
diff --git a/src/convert/resolve.cpp b/src/convert/resolve.cpp
index 66dc1b3a..62eb0bbf 100644
--- a/src/convert/resolve.cpp
+++ b/src/convert/resolve.cpp
@@ -35,7 +35,8 @@ class CPathResolver:
{}
friend ::std::ostream& operator<<(::std::ostream& os, const LocalItem& x) {
- return os << "'" << x.name << "' = " << x.path;
+ //return os << "'" << x.name << "' = " << x.path;
+ return os << "'" << x.name << "'";
}
};
const AST::Crate& m_crate;
@@ -365,26 +366,44 @@ void CPathResolver::handle_path(AST::Path& path, CASTIterator::PathMode mode)
// - Invalid afaik, instead Trait::method() is used
}
- // Search backwards up the stack of anon modules
- if( m_module_stack.size() )
+
+ if( path.nodes()[0].name() == "super" )
{
+ // Unwrap a single named node from the module path, and search that path
+ // - Requires resolving that path to a module to pass to lookup_path_in_module
AST::Path local_path = m_module_path;
- for(unsigned int i = 0; i < m_module_stack.size(); i ++)
- local_path.nodes().push_back( AST::PathNode( FMT("#" << m_module_stack[i].first), {} ) );
-
- for(unsigned int i = m_module_stack.size(); i--; )
+ local_path.nodes().pop_back();
+ local_path.resolve(m_crate);
+ DEBUG("'super' path is relative to " << local_path);
+ path.nodes().erase( path.nodes().begin() ); // delete the 'super' node
+ const AST::Module& mod = local_path.bound_module();
+ if( lookup_path_in_module(m_crate, mod, local_path, path) )
+ return ;
+ // this should always be an error, as 'super' paths are never MaybeBind
+ }
+ else
+ {
+ // Search backwards up the stack of anon modules
+ if( m_module_stack.size() )
{
- if( lookup_path_in_module(m_crate, *m_module_stack[i].second, local_path, path) ) {
- // Success!
- return ;
+ AST::Path local_path = m_module_path;
+ for(unsigned int i = 0; i < m_module_stack.size(); i ++)
+ local_path.nodes().push_back( AST::PathNode( FMT("#" << m_module_stack[i].first), {} ) );
+
+ for(unsigned int i = m_module_stack.size(); i--; )
+ {
+ if( lookup_path_in_module(m_crate, *m_module_stack[i].second, local_path, path) ) {
+ // Success!
+ return ;
+ }
+ local_path.nodes().pop_back();
}
- local_path.nodes().pop_back();
}
- }
- // Search current module, if found return with no error
- if( lookup_path_in_module(m_crate, *m_module, m_module_path, path) )
- {
- return;
+ // Search current module, if found return with no error
+ if( lookup_path_in_module(m_crate, *m_module, m_module_path, path) )
+ {
+ return;
+ }
}
DEBUG("no matches found for path = " << path);
diff --git a/src/dump_as_rust.cpp b/src/dump_as_rust.cpp
index 764f5a86..b8fb1647 100644
--- a/src/dump_as_rust.cpp
+++ b/src/dump_as_rust.cpp
@@ -643,7 +643,10 @@ void RustPrinter::print_params(const AST::TypeParams& params)
{
if( !is_first )
m_os << ", ";
- m_os << p.name();
+ if( p.is_type() )
+ m_os << p.name() << " = " << p.get_default();
+ else
+ m_os << "'" << p.name();
is_first = false;
}
m_os << ">";
@@ -741,13 +744,14 @@ void RustPrinter::handle_struct(const AST::Struct& s)
if( s.fields().size() == 0 )
{
- m_os << "()\n";
+ m_os << " /* unit-like */\n";
print_bounds(s.params());
m_os << indent() << ";\n";
}
else if( s.fields().size() == 1 && s.fields()[0].name == "" )
{
- m_os << "(" << "" <<")\n";
+ const auto& tuple = s.fields()[0].data;
+ m_os << "(" << tuple.print_pretty() <<")\n";
print_bounds(s.params());
m_os << indent() << ";\n";
}
diff --git a/src/macros.cpp b/src/macros.cpp
index 26e8ada4..fa303574 100644
--- a/src/macros.cpp
+++ b/src/macros.cpp
@@ -12,11 +12,6 @@ typedef ::std::map< ::std::string, MacroRules> t_macro_regs;
t_macro_regs g_macro_registrations;
const LList<AST::Module*>* g_macro_module;
-TokenTree g_crate_path_tt = TokenTree({
- TokenTree(Token(TOK_DOUBLE_COLON)),
- TokenTree(Token(TOK_STRING, "--CRATE--")),
- });
-
class ParameterMappings
{
// MultiMap (layer, name) -> TokenTree
@@ -141,7 +136,7 @@ public:
private:
const TokenStream& m_olex;
- const TokenTree& m_crate_path;
+ const ::std::string m_crate_name;
const ::std::vector<MacroRuleEnt>& m_root_contents;
const ParameterMappings m_mappings;
@@ -158,7 +153,7 @@ private:
public:
MacroExpander(const MacroExpander& x):
m_olex(x.m_olex),
- m_crate_path(x.m_crate_path),
+ m_crate_name(x.m_crate_name),
m_root_contents(x.m_root_contents),
m_mappings(x.m_mappings),
m_offsets({ {0,0} }),
@@ -166,9 +161,9 @@ public:
{
prep_counts();
}
- MacroExpander(const TokenStream& olex, const ::std::vector<MacroRuleEnt>& contents, ParameterMappings mappings, const TokenTree& crate_path):
+ MacroExpander(const TokenStream& olex, const ::std::vector<MacroRuleEnt>& contents, ParameterMappings mappings, ::std::string crate_name):
m_olex(olex),
- m_crate_path(crate_path),
+ m_crate_name(crate_name),
m_root_contents(contents),
m_mappings(mappings),
m_offsets({ {0,0} }),
@@ -219,6 +214,7 @@ const LList<AST::Module*>* Macro_GetModule()
void Macro_InitDefaults()
{
+ #if 0
// try!() macro
{
MacroRule rule;
@@ -268,6 +264,7 @@ void Macro_InitDefaults()
rules.push_back(rule);
g_macro_registrations.insert( make_pair(::std::string("panic"), rules));
}
+ #endif
}
bool Macro_TryPattern(TTStream& lex, const MacroPatEnt& pat)
@@ -275,8 +272,17 @@ bool Macro_TryPattern(TTStream& lex, const MacroPatEnt& pat)
DEBUG("pat = " << pat);
switch(pat.type)
{
- case MacroPatEnt::PAT_TOKEN:
- return LOOK_AHEAD(lex) == pat.tok.type();
+ case MacroPatEnt::PAT_TOKEN: {
+ Token tok = lex.getToken();
+ if( tok != pat.tok ) {
+ lex.putback(tok);
+ return false;
+ }
+ else {
+ lex.putback(tok);
+ return true;
+ }
+ }
case MacroPatEnt::PAT_LOOP:
if( pat.name == "*" )
return true;
@@ -460,7 +466,8 @@ bool Macro_HandlePattern(TTStream& lex, const MacroPatEnt& pat, unsigned int lay
// Count the number of repetitions
bound_tts.calculate_counts();
- TokenStream* ret_ptr = new MacroExpander(olex, rule.m_contents, bound_tts, g_crate_path_tt);
+ DEBUG("TODO: Obtain crate name correctly");
+ TokenStream* ret_ptr = new MacroExpander(olex, rule.m_contents, bound_tts, "");
// HACK! Disable nested macro expansion
//ret_ptr->parse_state().no_expand_macros = true;
@@ -487,7 +494,7 @@ bool Macro_HandlePattern(TTStream& lex, const MacroPatEnt& pat, unsigned int lay
if( name == "concat_idents" ) {
return Macro_Invoke_Concat(input, TOK_IDENT);
}
- else if( name == "concat_strings" ) {
+ else if( name == "concat_strings" || name == "concat" ) {
return Macro_Invoke_Concat(input, TOK_STRING);
}
else if( name == "cfg" ) {
@@ -496,6 +503,14 @@ bool Macro_HandlePattern(TTStream& lex, const MacroPatEnt& pat, unsigned int lay
else if( name == "stringify" ) {
return ::std::unique_ptr<TokenStream>( (TokenStream*)new MacroStringify(input) );
}
+ else if( name == "file" ) {
+ const ::std::string& pos = olex.getPosition().filename;
+ return ::std::unique_ptr<TokenStream>( (TokenStream*)new MacroToken(Token(TOK_STRING, pos)) );
+ }
+ else if( name == "line" ) {
+ auto pos = olex.getPosition().line;
+ return ::std::unique_ptr<TokenStream>( (TokenStream*)new MacroToken(Token((uint64_t)pos, CORETYPE_U32)) );
+ }
// Look for macro in builtins
t_macro_regs::iterator macro_reg = g_macro_registrations.find(name);
@@ -575,8 +590,11 @@ Token MacroExpander::realGetToken()
if( ent.name == "*crate" )
{
DEBUG("Crate name hack");
- m_ttstream.reset( new TTStream(m_crate_path) );
- return m_ttstream->getToken();
+ if( m_crate_name != "" )
+ {
+ m_next_token = Token(TOK_STRING, m_crate_name);
+ return Token(TOK_DOUBLE_COLON);
+ }
}
// - Expand to a parameter
else if( ent.name != "" )
@@ -704,6 +722,37 @@ const ::std::vector<MacroRuleEnt>* MacroExpander::getCurLayer() const
return ents;
}
+void Macro_Invoke_Concat_Once(::std::string& s, TokenStream& lex, enum eTokenType exp)
+{
+ Token tok;
+ GET_TOK(tok, lex);
+ if( exp == TOK_STRING )
+ {
+ if( tok.type() == TOK_MACRO )
+ {
+ // Special case, expand both concat! and stringify! internally
+ // TODO: Invoke
+ auto tt = Parse_TT(lex, false);
+ auto slex = Macro_Invoke(lex, tok.str(), tt);
+ Macro_Invoke_Concat_Once(s, (*slex), exp);
+ GET_CHECK_TOK(tok, (*slex), TOK_EOF);
+ }
+ else if( tok.type() == exp )
+ {
+ s += tok.str();
+ }
+ else
+ {
+ CHECK_TOK(tok, exp);
+ }
+ }
+ else
+ {
+ CHECK_TOK(tok, exp);
+ s += tok.str();
+ }
+}
+
::std::unique_ptr<TokenStream> Macro_Invoke_Concat(const TokenTree& input, enum eTokenType exp)
{
Token tok;
@@ -711,8 +760,7 @@ const ::std::vector<MacroRuleEnt>* MacroExpander::getCurLayer() const
::std::string val;
do
{
- GET_CHECK_TOK(tok, lex, exp);
- val += tok.str();
+ Macro_Invoke_Concat_Once(val, lex, exp);
} while( GET_TOK(tok, lex) == TOK_COMMA );
CHECK_TOK(tok, TOK_EOF);
@@ -758,7 +806,17 @@ Token MacroToken::realGetToken()
}
MacroStringify::MacroStringify(const TokenTree& input)
{
- throw ParseError::Todo("Stringify");
+ Token tok;
+ TTStream lex(input);
+
+ ::std::string rv;
+ while( GET_TOK(tok, lex) != TOK_EOF )
+ {
+ rv += tok.to_str();
+ rv += " ";
+ }
+
+ m_tok = Token(TOK_STRING, ::std::move(rv));
}
Position MacroStringify::getPosition() const
{
diff --git a/src/parse/expr.cpp b/src/parse/expr.cpp
index 222a6a3a..9b3ce04b 100644
--- a/src/parse/expr.cpp
+++ b/src/parse/expr.cpp
@@ -97,6 +97,26 @@ ExprNodeP Parse_ExprBlockNode(TokenStream& lex)
false ) );
break;
}
+ // - 'static'
+ case TOK_RWORD_STATIC:
+ keep_mod = true;
+ {
+ bool is_mut = false;
+ if( GET_TOK(tok, lex) == TOK_RWORD_MUT )
+ is_mut = true;
+ else
+ lex.putback(tok);
+ GET_CHECK_TOK(tok, lex, TOK_IDENT);
+ ::std::string name = tok.str();
+ GET_CHECK_TOK(tok, lex, TOK_COLON);
+ TypeRef type = Parse_Type(lex);
+ GET_CHECK_TOK(tok, lex, TOK_EQUAL);
+ auto val = Parse_Expr1(lex);
+ GET_CHECK_TOK(tok, lex, TOK_SEMICOLON);
+
+ local_mod->add_global(false, is_mut, ::std::move(name), ::std::move(type), ::std::move(val));
+ break;
+ }
// - 'struct'
case TOK_RWORD_STRUCT:
keep_mod = true;
diff --git a/src/parse/lex.cpp b/src/parse/lex.cpp
index d09bc2d8..34a2ff58 100644
--- a/src/parse/lex.cpp
+++ b/src/parse/lex.cpp
@@ -678,6 +678,153 @@ enum eTokenType Token::typefromstr(const ::std::string& s)
return TOK_NULL;
}
+::std::string Token::to_str() const
+{
+ switch(m_type)
+ {
+ case TOK_NULL: return "/*null*/";
+ case TOK_EOF: return "/*eof*/";
+
+ case TOK_NEWLINE: return "\n";
+ case TOK_WHITESPACE: return " ";
+ case TOK_COMMENT: return "/*" + m_str + "*/";
+ // Value tokens
+ case TOK_IDENT: return m_str;
+ case TOK_MACRO: return m_str + "!";
+ case TOK_LIFETIME: return "'" + m_str;
+ case TOK_INTEGER: return FMT(m_intval); // TODO: suffix for type
+ case TOK_CHAR: return FMT("'\\u{"<< ::std::hex << m_intval << "}");
+ case TOK_FLOAT: return FMT(m_floatval);
+ case TOK_STRING: return "\"" + m_str + "\"";
+ case TOK_CATTR_OPEN:return "#![";
+ case TOK_ATTR_OPEN: return "#[";
+ case TOK_UNDERSCORE:return "_";
+ // Symbols
+ case TOK_PAREN_OPEN: return "(";
+ case TOK_PAREN_CLOSE: return ")";
+ case TOK_BRACE_OPEN: return "{";
+ case TOK_BRACE_CLOSE: return "}";
+ case TOK_LT: return "<";
+ case TOK_GT: return ">";
+ case TOK_SQUARE_OPEN: return "[";
+ case TOK_SQUARE_CLOSE: return "]";
+ case TOK_COMMA: return ",";
+ case TOK_SEMICOLON: return ";";
+ case TOK_COLON: return ":";
+ case TOK_DOUBLE_COLON: return ":";
+ case TOK_STAR: return "*";
+ case TOK_AMP: return "&";
+ case TOK_PIPE: return "|";
+
+ case TOK_FATARROW: return "=>"; // =>
+ case TOK_THINARROW: return "->"; // ->
+
+ case TOK_PLUS: return "+";
+ case TOK_DASH: return "-";
+ case TOK_EXCLAM: return "!";
+ case TOK_PERCENT: return "%";
+ case TOK_SLASH: return "/";
+
+ case TOK_DOT: return ".";
+ case TOK_DOUBLE_DOT: return "...";
+ case TOK_TRIPLE_DOT: return "..";
+
+ case TOK_EQUAL: return "=";
+ case TOK_PLUS_EQUAL: return "+=";
+ case TOK_DASH_EQUAL: return "-";
+ case TOK_PERCENT_EQUAL: return "%=";
+ case TOK_SLASH_EQUAL: return "/=";
+ case TOK_STAR_EQUAL: return "*=";
+ case TOK_AMP_EQUAL: return "&=";
+ case TOK_PIPE_EQUAL: return "|=";
+
+ case TOK_DOUBLE_EQUAL: return "==";
+ case TOK_EXCLAM_EQUAL: return "!=";
+ case TOK_GTE: return ">=";
+ case TOK_LTE: return "<=";
+
+ case TOK_DOUBLE_AMP: return "&&";
+ case TOK_DOUBLE_PIPE: return "||";
+ case TOK_DOUBLE_LT: return "<<";
+ case TOK_DOUBLE_GT: return ">>";
+ case TOK_DOUBLE_LT_EQUAL: return "<=";
+ case TOK_DOUBLE_GT_EQUAL: return ">=";
+
+ case TOK_DOLLAR: return "$";
+
+ case TOK_QMARK: return "?";
+ case TOK_AT: return "@";
+ case TOK_TILDE: return "~";
+ case TOK_BACKSLASH: return "\\";
+ case TOK_CARET: return "^";
+ case TOK_CARET_EQUAL: return "^=";
+ case TOK_BACKTICK: return "`";
+
+ // Reserved Words
+ case TOK_RWORD_PUB: return "pub";
+ case TOK_RWORD_PRIV: return "priv";
+ case TOK_RWORD_MUT: return "mut";
+ case TOK_RWORD_CONST: return "const";
+ case TOK_RWORD_STATIC: return "static";
+ case TOK_RWORD_UNSAFE: return "unsafe";
+ case TOK_RWORD_EXTERN: return "extern";
+
+ case TOK_RWORD_CRATE: return "crate";
+ case TOK_RWORD_MOD: return "mod";
+ case TOK_RWORD_STRUCT: return "struct";
+ case TOK_RWORD_ENUM: return "enum";
+ case TOK_RWORD_TRAIT: return "trait";
+ case TOK_RWORD_FN: return "fn";
+ case TOK_RWORD_USE: return "use";
+ case TOK_RWORD_IMPL: return "impl";
+ case TOK_RWORD_TYPE: return "type";
+
+ case TOK_RWORD_WHERE: return "where";
+ case TOK_RWORD_AS: return "as";
+
+ case TOK_RWORD_LET: return "let";
+ case TOK_RWORD_MATCH: return "match";
+ case TOK_RWORD_IF: return "if";
+ case TOK_RWORD_ELSE: return "else";
+ case TOK_RWORD_LOOP: return "loop";
+ case TOK_RWORD_WHILE: return "while";
+ case TOK_RWORD_FOR: return "for";
+ case TOK_RWORD_IN: return "in";
+ case TOK_RWORD_DO: return "do";
+
+ case TOK_RWORD_CONTINUE:return "continue";
+ case TOK_RWORD_BREAK: return "break";
+ case TOK_RWORD_RETURN: return "return";
+ case TOK_RWORD_YIELD: return "yeild";
+ case TOK_RWORD_BOX: return "box";
+ case TOK_RWORD_REF: return "ref";
+
+ case TOK_RWORD_FALSE: return "false";
+ case TOK_RWORD_TRUE: return "true";
+ case TOK_RWORD_SELF: return "self";
+ case TOK_RWORD_SUPER: return "super";
+
+ case TOK_RWORD_PROC: return "proc";
+ case TOK_RWORD_MOVE: return "move";
+ case TOK_RWORD_ONCE: return "once";
+
+ case TOK_RWORD_ABSTRACT:return "abstract";
+ case TOK_RWORD_FINAL: return "final";
+ case TOK_RWORD_PURE: return "pure";
+ case TOK_RWORD_OVERRIDE:return "override";
+ case TOK_RWORD_VIRTUAL: return "virtual";
+
+ case TOK_RWORD_ALIGNOF: return "alignof";
+ case TOK_RWORD_OFFSETOF:return "offsetof";
+ case TOK_RWORD_SIZEOF: return "sizeof";
+ case TOK_RWORD_TYPEOF: return "typeof";
+
+ case TOK_RWORD_BE: return "be";
+ case TOK_RWORD_UNSIZED: return "unsized";
+ }
+ throw ParseError::BugCheck("Reached end of Token::to_str");
+}
+
void operator%(Serialiser& s, enum eTokenType c) {
s << Token::typestr(c);
}
diff --git a/src/parse/lex.hpp b/src/parse/lex.hpp
index a32a569b..aa5ed623 100644
--- a/src/parse/lex.hpp
+++ b/src/parse/lex.hpp
@@ -63,7 +63,27 @@ public:
enum eCoreType datatype() const { return m_datatype; }
uint64_t intval() const { return m_intval; }
double floatval() const { return m_floatval; }
+ bool operator==(const Token& r) const {
+ if(type() != r.type())
+ return false;
+ switch(type())
+ {
+ case TOK_STRING:
+ case TOK_IDENT:
+ case TOK_LIFETIME:
+ return str() == r.str();
+ case TOK_INTEGER:
+ return intval() == r.intval() && datatype() == r.datatype();
+ case TOK_FLOAT:
+ return floatval() == r.floatval() && datatype() == r.datatype();
+ default:
+ return true;
+ }
+ }
+ bool operator!=(const Token& r) { return !(*this == r); }
+ ::std::string to_str() const;
+
void set_pos(Position pos) { m_pos = pos; }
const Position& get_pos() const { return m_pos; }
diff --git a/src/parse/pattern.cpp b/src/parse/pattern.cpp
index 28e7ebaa..6d26cd4a 100644
--- a/src/parse/pattern.cpp
+++ b/src/parse/pattern.cpp
@@ -256,7 +256,8 @@ AST::Pattern Parse_PatternStruct(TokenStream& lex, AST::Path path)
CHECK_TOK(tok, TOK_COLON);
pat = Parse_Pattern(lex);
}
- // TODO: Append
+
+ subpats.push_back( ::std::make_pair(::std::move(field), ::std::move(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 759c65ac..39776689 100644
--- a/src/parse/root.cpp
+++ b/src/parse/root.cpp
@@ -825,6 +825,18 @@ void Parse_Use(TokenStream& lex, ::std::function<void(AST::Path, ::std::string)>
Token tok;
AST::Path path = AST::Path( AST::Path::TagAbsolute() );
+ // Leading :: is allowed and ignored for the $crate feature
+ if( LOOK_AHEAD(lex) == TOK_DOUBLE_COLON ) {
+ GET_TOK(tok, lex);
+ // HACK! mrustc emits $crate as `::"crate-name"`
+ if( LOOK_AHEAD(lex) == TOK_STRING )
+ {
+ GET_CHECK_TOK(tok, lex, TOK_STRING);
+ path.set_crate(tok.str());
+ GET_CHECK_TOK(tok, lex, TOK_DOUBLE_COLON);
+ }
+ }
+
switch( GET_TOK(tok, lex) )
{
case TOK_RWORD_SELF: