From d72082d2bd47707f6bcde00eba55f6f2018e24fa Mon Sep 17 00:00:00 2001 From: John Hodge Date: Thu, 25 Aug 2016 08:32:44 +0800 Subject: Parse - What an interesting feature --- src/parse/expr.cpp | 33 +++++++++++++++++++++++++++++++++ src/parse/pattern.cpp | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) (limited to 'src/parse') diff --git a/src/parse/expr.cpp b/src/parse/expr.cpp index 3cd54a7d..b497e4a7 100644 --- a/src/parse/expr.cpp +++ b/src/parse/expr.cpp @@ -854,6 +854,39 @@ ExprNodeP Parse_ExprVal_StructLiteral(TokenStream& lex, AST::Path path) TRACE_FUNCTION; Token tok; + // #![feature(relaxed_adts)] + if( LOOK_AHEAD(lex) == TOK_INTEGER ) + { + ::std::map nodes; + while( GET_TOK(tok, lex) == TOK_INTEGER ) + { + unsigned int ofs = tok.intval(); + GET_CHECK_TOK(tok, lex, TOK_COLON); + ExprNodeP val = Parse_Stmt(lex); + if( ! nodes.insert( ::std::make_pair(ofs, mv$(val)) ).second ) { + ERROR(lex.getPosition(), E0000, "Duplicate index"); + } + + if( GET_TOK(tok,lex) == TOK_BRACE_CLOSE ) + break; + CHECK_TOK(tok, TOK_COMMA); + } + CHECK_TOK(tok, TOK_BRACE_CLOSE); + + ::std::vector items; + unsigned int i = 0; + for(auto& p : nodes) + { + if( p.first != i ) { + ERROR(lex.getPosition(), E0000, "Missing index " << i); + } + items.push_back( mv$(p.second) ); + i ++; + } + + return NEWNODE( AST::ExprNode_CallPath, mv$(path), mv$(items) ); + } + // Braced structure literal // - A series of 0 or more pairs of : , // - '..' diff --git a/src/parse/pattern.cpp b/src/parse/pattern.cpp index ded81103..f0b15ffe 100644 --- a/src/parse/pattern.cpp +++ b/src/parse/pattern.cpp @@ -360,6 +360,55 @@ AST::Pattern Parse_PatternStruct(TokenStream& lex, AST::Path path, bool is_refut TRACE_FUNCTION; Token tok; + // #![feature(relaxed_adts)] + if( LOOK_AHEAD(lex) == TOK_INTEGER ) + { + bool split_allowed = false; + ::std::map pats; + while( GET_TOK(tok, lex) == TOK_INTEGER ) + { + unsigned int ofs = tok.intval(); + GET_CHECK_TOK(tok, lex, TOK_COLON); + auto val = Parse_Pattern(lex, is_refutable); + if( ! pats.insert( ::std::make_pair(ofs, mv$(val)) ).second ) { + ERROR(lex.getPosition(), E0000, "Duplicate index"); + } + + if( GET_TOK(tok,lex) == TOK_BRACE_CLOSE ) + break; + CHECK_TOK(tok, TOK_COMMA); + } + if( tok.type() == TOK_DOUBLE_DOT ) { + split_allowed = true; + GET_TOK(tok, lex); + } + CHECK_TOK(tok, TOK_BRACE_CLOSE); + + bool has_split = false; + ::std::vector leading; + ::std::vector trailing; + unsigned int i = 0; + for(auto& p : pats) + { + if( p.first != i ) { + if( has_split || !split_allowed ) { + ERROR(lex.getPosition(), E0000, "Missing index " << i); + } + has_split = true; + i = p.first; + } + if( ! has_split ) { + leading.push_back( mv$(p.second) ); + } + else { + trailing.push_back( mv$(p.second) ); + } + i ++; + } + + return AST::Pattern(AST::Pattern::TagNamedTuple(), mv$(path), AST::Pattern::TuplePat { mv$(leading), has_split, mv$(trailing) }); + } + bool is_exhaustive = true; ::std::vector< ::std::pair< ::std::string, AST::Pattern> > subpats; do { -- cgit v1.2.3