summaryrefslogtreecommitdiff
path: root/src/expand/assert.cpp
diff options
context:
space:
mode:
authorJohn Hodge <tpg@ucc.asn.au>2019-11-02 11:07:23 +0800
committerJohn Hodge <tpg@ucc.asn.au>2019-11-02 11:07:23 +0800
commit1d02810c3cf908bfba7c15ae50eb5314603b9d85 (patch)
tree79dd5e4ef4c3ff79db0912ba546f08e61a7a8c10 /src/expand/assert.cpp
parent7111acba04d72fe4084b1a1f3209ff83efe8614d (diff)
parent8b53b38f40625ab0510f541d69db3f83332a830a (diff)
downloadmrust-1d02810c3cf908bfba7c15ae50eb5314603b9d85.tar.gz
Merge branch 'nightly-1.29' - #95 Working support for rustc 1.29
Diffstat (limited to 'src/expand/assert.cpp')
-rw-r--r--src/expand/assert.cpp88
1 files changed, 88 insertions, 0 deletions
diff --git a/src/expand/assert.cpp b/src/expand/assert.cpp
new file mode 100644
index 00000000..ffba7b98
--- /dev/null
+++ b/src/expand/assert.cpp
@@ -0,0 +1,88 @@
+/*
+ * MRustC - Rust Compiler
+ * - By John Hodge (Mutabah/thePowersGang)
+ *
+ * expand/assert.cpp
+ * - assert! built-in macro (1.29)
+ */
+#include <synext_macro.hpp>
+#include <synext.hpp> // for Expand_BareExpr
+#include <parse/interpolated_fragment.hpp>
+#include "../parse/ttstream.hpp"
+#include "../parse/common.hpp"
+#include "../parse/parseerror.hpp"
+
+class CExpander_assert:
+ public ExpandProcMacro
+{
+ ::std::unique_ptr<TokenStream> expand(const Span& sp, const ::AST::Crate& crate, const TokenTree& tt, AST::Module& mod) override
+ {
+ Token tok;
+
+ auto lex = TTStream(sp, tt);
+ lex.parse_state().module = &mod;
+
+ // assertion condition
+ auto n = Parse_Expr0(lex);
+ ASSERT_BUG(sp, n, "No expression returned");
+
+ ::std::vector<TokenTree> toks;
+
+ toks.push_back( Token(TOK_RWORD_IF) );
+ toks.push_back( Token(TOK_EXCLAM) );
+
+ GET_TOK(tok, lex);
+ if( tok == TOK_COMMA )
+ {
+ toks.push_back( Token(InterpolatedFragment(InterpolatedFragment::EXPR, n.release())) );
+ toks.push_back( Token(TOK_BRACE_OPEN) );
+ // User-provided message
+ toks.push_back( Token(TOK_IDENT, RcString::new_interned("panic")) );
+ toks.push_back( Token(TOK_EXCLAM) );
+ toks.push_back( Token(TOK_PAREN_OPEN) );
+ while(lex.lookahead(0) != TOK_EOF )
+ {
+ toks.push_back( Token(InterpolatedFragment(InterpolatedFragment::EXPR, Parse_Expr0(lex).release())) );
+ if( lex.lookahead(0) != TOK_COMMA )
+ break;
+ GET_CHECK_TOK(tok, lex, TOK_COMMA);
+ toks.push_back( Token(TOK_COMMA) );
+ }
+ GET_CHECK_TOK(tok, lex, TOK_EOF);
+ toks.push_back( Token(TOK_PAREN_CLOSE) );
+ }
+ else if( tok == TOK_EOF )
+ {
+ ::std::stringstream ss;
+ ss << "assertion failed: ";
+ n->print(ss);
+
+ toks.push_back( Token(InterpolatedFragment(InterpolatedFragment::EXPR, n.release())) );
+
+ toks.push_back( Token(TOK_BRACE_OPEN) );
+ // Auto-generated message
+ toks.push_back( Token(TOK_IDENT, RcString::new_interned("panic")) );
+ toks.push_back( Token(TOK_EXCLAM) );
+ toks.push_back( Token(TOK_PAREN_OPEN) );
+ toks.push_back( Token(TOK_STRING, ss.str()) );
+ toks.push_back( Token(TOK_PAREN_CLOSE) );
+ }
+ else
+ {
+ throw ParseError::Unexpected(lex, tok, {TOK_COMMA, TOK_EOF});
+ }
+
+ toks.push_back( Token(TOK_BRACE_CLOSE) );
+
+ return box$( TTStreamO(sp, TokenTree(Ident::Hygiene::new_scope(), mv$(toks))) );
+ }
+};
+
+void Expand_init_assert()
+{
+ if( TARGETVER_1_29 )
+ {
+ Register_Synext_Macro("assert", ::std::unique_ptr<ExpandProcMacro>(new CExpander_assert));
+ }
+}
+