summaryrefslogtreecommitdiff
path: root/src/parse
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-04-30 13:05:14 +0800
committerJohn Hodge <tpg@mutabah.net>2016-04-30 13:05:14 +0800
commit756abd3f2fd768e73a014e190c7a446a3f5aa44c (patch)
tree77cd0718121eec7d992ea7ea2a06e24bbb49a52d /src/parse
parent8f694dbd8ee7b0ea786229642b994a6d00cbe478 (diff)
downloadmrust-756abd3f2fd768e73a014e190c7a446a3f5aa44c.tar.gz
Parser - Handle '?', '...', and 'default fn`
Diffstat (limited to 'src/parse')
-rw-r--r--src/parse/expr.cpp14
-rw-r--r--src/parse/root.cpp34
2 files changed, 41 insertions, 7 deletions
diff --git a/src/parse/expr.cpp b/src/parse/expr.cpp
index 58c82a0b..407afbf3 100644
--- a/src/parse/expr.cpp
+++ b/src/parse/expr.cpp
@@ -578,12 +578,12 @@ bool Parse_IsTokValue(eTokenType tok_type)
}
}
-ExprNodeP Parse_Expr1_5(TokenStream& lex);
+ExprNodeP Parse_Expr1_1(TokenStream& lex);
// Very evil handling for '..'
ExprNodeP Parse_Expr1(TokenStream& lex)
{
Token tok;
- ExprNodeP (*next)(TokenStream&) = Parse_Expr1_5;
+ ExprNodeP (*next)(TokenStream&) = Parse_Expr1_1;
ExprNodeP left, right;
if( GET_TOK(tok, lex) != TOK_DOUBLE_DOT )
@@ -610,6 +610,12 @@ ExprNodeP Parse_Expr1(TokenStream& lex)
return NEWNODE( AST::ExprNode_BinOp, AST::ExprNode_BinOp::RANGE, ::std::move(left), ::std::move(right) );
}
+// TODO: Is this left associative?
+LEFTASSOC(Parse_Expr1_1, Parse_Expr1_5,
+ case TOK_TRIPLE_DOT:
+ rv = NEWNODE( AST::ExprNode_BinOp, AST::ExprNode_BinOp::RANGE_INC, mv$(rv), next(lex) );
+ break;
+)
// 1: Bool OR
LEFTASSOC(Parse_Expr1_5, Parse_Expr2,
case TOK_DOUBLE_PIPE:
@@ -765,6 +771,10 @@ ExprNodeP Parse_ExprFC(TokenStream& lex)
Token tok;
switch(GET_TOK(tok, lex))
{
+ case TOK_QMARK:
+ val = NEWNODE( AST::ExprNode_UniOp, AST::ExprNode_UniOp::QMARK, mv$(val) );
+ break;
+
case TOK_PAREN_OPEN:
// Expression method call
lex.putback(tok);
diff --git a/src/parse/root.cpp b/src/parse/root.cpp
index 4aba4874..0ce6935b 100644
--- a/src/parse/root.cpp
+++ b/src/parse/root.cpp
@@ -972,7 +972,8 @@ void Parse_Impl_Item(TokenStream& lex, AST::Impl& impl)
GET_CHECK_TOK(tok, lex, TOK_SEMICOLON);
break; }
case TOK_RWORD_CONST:
- if( GET_TOK(tok, lex) != TOK_RWORD_FN && tok.type() != TOK_RWORD_UNSAFE )
+ GET_TOK(tok, lex);
+ if( tok.type() != TOK_RWORD_FN && tok.type() != TOK_RWORD_UNSAFE )
{
CHECK_TOK(tok, TOK_IDENT);
auto name = mv$(tok.str());
@@ -989,11 +990,14 @@ void Parse_Impl_Item(TokenStream& lex, AST::Impl& impl)
}
else if( tok.type() == TOK_RWORD_UNSAFE )
{
- if( GET_TOK(tok, lex) != TOK_RWORD_FN )
- ERROR(lex.end_span(lex.start_span()), E0000, "");
+ GET_CHECK_TOK(tok, lex, TOK_RWORD_FN);
+ // TODO: Use a better marker
item_attrs.push_back( AST::MetaItem("#UNSAFE") );
}
+ // TODO: Mark `const fn` as const (properly)
+ item_attrs.push_back( AST::MetaItem("#CONST") );
if( 0 )
+ // FALL
case TOK_RWORD_EXTERN:
{
abi = "C";
@@ -1005,6 +1009,7 @@ void Parse_Impl_Item(TokenStream& lex, AST::Impl& impl)
GET_TOK(tok, lex);
}
CHECK_TOK(tok, TOK_RWORD_FN);
+ // FALL
case TOK_RWORD_FN: {
GET_CHECK_TOK(tok, lex, TOK_IDENT);
::std::string name = tok.str();
@@ -1012,6 +1017,21 @@ void Parse_Impl_Item(TokenStream& lex, AST::Impl& impl)
auto fcn = Parse_FunctionDefWithCode(lex, abi, item_attrs, true);
impl.add_function(is_public, ::std::move(name), mv$(fcn));
break; }
+
+ case TOK_IDENT:
+ if( tok.str() == "default" ) {
+ // TODO: Mark `default` functions as default (i.e. specialisable)
+ GET_CHECK_TOK(tok, lex, TOK_RWORD_FN);
+ GET_CHECK_TOK(tok, lex, TOK_IDENT);
+ ::std::string name = tok.str();
+ // - Self allowed, can't be prototype-form
+ auto fcn = Parse_FunctionDefWithCode(lex, abi, item_attrs, true);
+ impl.add_function(is_public, ::std::move(name), mv$(fcn));
+ }
+ else {
+ throw ParseError::Unexpected(lex, tok);
+ }
+ break;
default:
throw ParseError::Unexpected(lex, tok);
@@ -1340,13 +1360,16 @@ void Parse_Mod_Item(TokenStream& lex, bool file_controls_dir, const ::std::strin
GET_CHECK_TOK(tok, lex, TOK_RWORD_FN);
GET_CHECK_TOK(tok, lex, TOK_IDENT);
// TODO: Mark as const and unsafe
+ meta_items.push_back( AST::MetaItem("#UNSAFE") );
+ meta_items.push_back( AST::MetaItem("#CONST") );
auto i = Parse_FunctionDefWithCode(lex, "rust", meta_items, false);
mod.add_function(is_public, tok.str(), mv$(i), mv$(meta_items));
break; }
case TOK_RWORD_FN: {
GET_CHECK_TOK(tok, lex, TOK_IDENT);
- // - self not allowed, not prototype
// TODO: Mark as const
+ meta_items.push_back( AST::MetaItem("#CONST") );
+ // - self not allowed, not prototype
auto i = Parse_FunctionDefWithCode(lex, "rust", meta_items, false);
mod.add_function(is_public, tok.str(), mv$(i), mv$(meta_items));
break; }
@@ -1403,8 +1426,9 @@ void Parse_Mod_Item(TokenStream& lex, bool file_controls_dir, const ::std::strin
// `unsafe fn`
case TOK_RWORD_FN: {
GET_CHECK_TOK(tok, lex, TOK_IDENT);
- // - self not allowed, not prototype
// TODO: Mark as unsafe
+ meta_items.push_back( AST::MetaItem("#UNSAFE") );
+ // - self not allowed, not prototype
auto i = Parse_FunctionDefWithCode(lex, "rust", meta_items, false);
//i.set_unsafe();
mod.add_function(is_public, tok.str(), mv$(i), mv$(meta_items));