From 12d304afab3fcdc28f28508895d162a84cb56cde Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sun, 3 Dec 2023 21:06:53 +0800 Subject: [PATCH] AST - Draft `let-else` impl --- src/ast/expr.cpp | 9 +++++++-- src/ast/expr.hpp | 10 ++++++---- src/hir/from_ast_expr.cpp | 3 +++ src/parse/expr.cpp | 7 ++++++- 4 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/ast/expr.cpp b/src/ast/expr.cpp index 6f585ee0..affacd53 100644 --- a/src/ast/expr.cpp +++ b/src/ast/expr.cpp @@ -253,10 +253,14 @@ NODE(ExprNode_Flow, { NODE(ExprNode_LetBinding, { os << "let " << m_pat << ": " << m_type; - if(m_value) + if(m_value) { os << " = " << *m_value; + if( m_else ) { + os << " else " << *m_else; + } + } },{ - return NEWNODE(ExprNode_LetBinding, m_pat.clone(), m_type.clone(), OPT_CLONE(m_value)); + return NEWNODE(ExprNode_LetBinding, m_pat.clone(), m_type.clone(), OPT_CLONE(m_value), OPT_CLONE(m_else)); }) NODE(ExprNode_Assign, { @@ -664,6 +668,7 @@ NV(ExprNode_LetBinding, { // TODO: Handle recurse into Let pattern? visit(node.m_value); + visit(node.m_else); }) NV(ExprNode_Assign, { diff --git a/src/ast/expr.hpp b/src/ast/expr.hpp index 545c2a9a..e34a98da 100644 --- a/src/ast/expr.hpp +++ b/src/ast/expr.hpp @@ -204,11 +204,13 @@ struct ExprNode_LetBinding: Pattern m_pat; TypeRef m_type; ExprNodeP m_value; + ExprNodeP m_else; - ExprNode_LetBinding(Pattern pat, TypeRef type, ExprNodeP value): - m_pat( move(pat) ), - m_type( move(type) ), - m_value( move(value) ) + ExprNode_LetBinding(Pattern pat, TypeRef type, ExprNodeP value, ExprNodeP else_arm={}) + : m_pat( move(pat) ) + , m_type( move(type) ) + , m_value( move(value) ) + , m_else( move(else_arm) ) { } diff --git a/src/hir/from_ast_expr.cpp b/src/hir/from_ast_expr.cpp index 6ff66ed6..67e6443a 100644 --- a/src/hir/from_ast_expr.cpp +++ b/src/hir/from_ast_expr.cpp @@ -163,6 +163,9 @@ struct LowerHIR_ExprNode_Visitor: } } virtual void visit(::AST::ExprNode_LetBinding& v) override { + if( v.m_else ) { + TODO(v.span(), "Handle let-else in HIR expand, or elsewhere?"); + } m_rv.reset( new ::HIR::ExprNode_Let( v.span(), LowerHIR_Pattern( v.m_pat ), LowerHIR_Type( v.m_type ), diff --git a/src/parse/expr.cpp b/src/parse/expr.cpp index bfb43aae..8861714b 100644 --- a/src/parse/expr.cpp +++ b/src/parse/expr.cpp @@ -657,13 +657,18 @@ ExprNodeP Parse_Stmt_Let(TokenStream& lex) GET_TOK(tok, lex); } ExprNodeP val; + ExprNodeP else_arm; if( tok.type() == TOK_EQUAL ) { val = Parse_Expr0(lex); + if( lex.lookahead(0) == TOK_RWORD_ELSE ) { + GET_TOK(tok, lex); + else_arm = Parse_ExprBlockNode(lex); + } } else { PUTBACK(tok, lex); } - return NEWNODE( AST::ExprNode_LetBinding, ::std::move(pat), mv$(type), ::std::move(val) ); + return NEWNODE( AST::ExprNode_LetBinding, ::std::move(pat), mv$(type), ::std::move(val), ::std::move(else_arm) ); } ::std::vector Parse_ParenList(TokenStream& lex)