From 6d26e15fbe9a91bcae9cc98fab0743ca75c41ea7 Mon Sep 17 00:00:00 2001 From: Laurenz Date: Thu, 30 Sep 2021 19:07:06 +0200 Subject: [PATCH] Support `else if` --- src/parse/mod.rs | 36 ++++++++++++++++++++---------------- src/syntax/pretty.rs | 1 + tests/ref/code/if.png | Bin 1838 -> 2090 bytes tests/typ/code/if.typ | 27 +++++++++++++++++++++++++++ 4 files changed, 48 insertions(+), 16 deletions(-) diff --git a/src/parse/mod.rs b/src/parse/mod.rs index 9cd176048..19d810ea4 100644 --- a/src/parse/mod.rs +++ b/src/parse/mod.rs @@ -600,7 +600,7 @@ fn let_expr(p: &mut Parser) -> Option { let start = p.next_start(); p.eat_assert(Token::Let); - let mut let_expr = None; + let mut output = None; if let Some(binding) = ident(p) { let mut init = None; @@ -635,14 +635,14 @@ fn let_expr(p: &mut Parser) -> Option { } } - let_expr = Some(Expr::Let(Box::new(LetExpr { + output = Some(Expr::Let(Box::new(LetExpr { span: p.span_from(start), binding, init, }))); } - let_expr + output } /// Parse an if expresion. @@ -650,15 +650,19 @@ fn if_expr(p: &mut Parser) -> Option { let start = p.next_start(); p.eat_assert(Token::If); - let mut if_expr = None; + let mut output = None; if let Some(condition) = expr(p) { if let Some(if_body) = body(p) { let mut else_body = None; if p.eat_if(Token::Else) { - else_body = body(p); + if p.peek() == Some(Token::If) { + else_body = if_expr(p); + } else { + else_body = body(p); + } } - if_expr = Some(Expr::If(Box::new(IfExpr { + output = Some(Expr::If(Box::new(IfExpr { span: p.span_from(start), condition, if_body, @@ -667,7 +671,7 @@ fn if_expr(p: &mut Parser) -> Option { } } - if_expr + output } /// Parse a while expresion. @@ -675,10 +679,10 @@ fn while_expr(p: &mut Parser) -> Option { let start = p.next_start(); p.eat_assert(Token::While); - let mut while_expr = None; + let mut output = None; if let Some(condition) = expr(p) { if let Some(body) = body(p) { - while_expr = Some(Expr::While(Box::new(WhileExpr { + output = Some(Expr::While(Box::new(WhileExpr { span: p.span_from(start), condition, body, @@ -686,7 +690,7 @@ fn while_expr(p: &mut Parser) -> Option { } } - while_expr + output } /// Parse a for expression. @@ -694,12 +698,12 @@ fn for_expr(p: &mut Parser) -> Option { let start = p.next_start(); p.eat_assert(Token::For); - let mut for_expr = None; + let mut output = None; if let Some(pattern) = for_pattern(p) { if p.eat_expect(Token::In) { if let Some(iter) = expr(p) { if let Some(body) = body(p) { - for_expr = Some(Expr::For(Box::new(ForExpr { + output = Some(Expr::For(Box::new(ForExpr { span: p.span_from(start), pattern, iter, @@ -710,7 +714,7 @@ fn for_expr(p: &mut Parser) -> Option { } } - for_expr + output } /// Parse a for loop pattern. @@ -743,10 +747,10 @@ fn import_expr(p: &mut Parser) -> Option { Imports::Idents(idents(p, items)) }; - let mut import_expr = None; + let mut output = None; if p.eat_expect(Token::From) { if let Some(path) = expr(p) { - import_expr = Some(Expr::Import(Box::new(ImportExpr { + output = Some(Expr::Import(Box::new(ImportExpr { span: p.span_from(start), imports, path, @@ -754,7 +758,7 @@ fn import_expr(p: &mut Parser) -> Option { } } - import_expr + output } /// Parse an include expression. diff --git a/src/syntax/pretty.rs b/src/syntax/pretty.rs index d186eaf68..6ac5672e4 100644 --- a/src/syntax/pretty.rs +++ b/src/syntax/pretty.rs @@ -603,6 +603,7 @@ mod tests { roundtrip("#let x = 1 + 2"); test_parse("#let f(x) = y", "#let f = (x) => y"); roundtrip("#if x [y] else [z]"); + roundtrip("#if x {} else if y {} else {}"); roundtrip("#while x {y}"); roundtrip("#for x in y {z}"); roundtrip("#for k, x in y {z}"); diff --git a/tests/ref/code/if.png b/tests/ref/code/if.png index 7b54203aa040b44e2fc932b849d5b5acb14aafc0..bce70b89943cc910316c86c7425242234fb65e6f 100644 GIT binary patch delta 1926 zcmV;12YL9e4yq847hymM00000f2v)q000N^NklF9mpL}f=&l2;dd@DGhg<6Gskvv_Ke_tFFfAax#0;C{}xMTilQir zq9}^;WH?xp@dX%vgujB2?)Uq_5yH80U2T_mR0QBw1c0Ts>8J>dwmil}W%EH1qV?O? z*-q)02!8wX1Jybp_9F2t0yGx3uk_YIy!d!+&+8bO`|gsf$+HN6*|w43%@Hf>hA>rS z0xlyA%@Gi`JpqC_m~H0qIoH6v{lZ=mfMS~yfZ2Ko7Jy`b9=ggo=ek_aAD%^k&W7zP z-lh!!^HBO+N5YE;vz@lDbVd4xQ1u5vz}fcqUTowWLRV&ew0sr;NZaZ1()4^sn5~Hr z0-??ET=JD`hcsCGasRwj6F|J!C6cbzF3_8`O%0uOJ4b*tdG8;8>m`J+5JLz72!5D= z#V>nD*lUE7@&y+Vgx^9?6h%=KMNyRh6`eKw$UV>-M?6 z8=F3EUwcOY%0K%jG}d>%TSvz1LZ~l$NBG`9VKN7kd0?^tOPwHCt_O|x5Q25vyVB7- z^kv(&O|f@wgnzy?58lRaFN~j#(m!Fet!E1K7QZ3bQ4mtKjR#UWd~Y4#P6t6?Dayy7 zKiBCy!e|#D1=20YbIF&k9jfvp!B^`N!1U;+ae-7@d%M-~5d9OT&K0g-N5$0peq`?a z;34&O(MOo89DCF0eu9(m1sQ*Yzk{&1HBR0_=&tuI_iK(f)_()x)O+tMtG)L_k@sV_ zcM+I9fM1_FP2({U)(VXWLfX}mFRvaQ{Jx5neipvH?;BLk$pfE%AI8fue`jl`wyfP_DJEwPiXl zyo)ecie0doIL0pcBux8uzeN`|04npSDu0KHt=hHa>%f&6{Q-sgK zoflx~`))o4LN|rA30r5UuCF4O3C1!pyTnrDqVO|>85j(}YJllRWtlz$=s!I}l8iON18dQzK7bHbMpmaAF0_S6cEo#XnMZdQIIU^F|OdRPi8 zn_?m4a%bWtgb+dqVF4LfLI`pFOd*8z$|63F32F3G0>(_v6?A7wlaK)vk_HEV{uV+S z+BKOkZSuoCVO-x1AKj4=!ebve^qvs*HV}mHBZRa7gxk6@-tu*Wbidys@Y$!2+s<1D z1UujF_hy208B?gs1x7Q7Ltz1GtD7pz-ZC#CRNnh)hRXn?s!Urm8E*lSRf#P7>%2M~ z2ouX%sWIC44FSvb;Q125uzq=Bl&b`DM?`pR z2%P_k@bR%%1W1={?NBDWBx1b)vo)VzU1yhx#ZD0jX1UdSKZ`*0-h00-uid-eubVnK zH>9x->n}v0ANIN@>^hT?0TYr22!HTb5Yp|D^K?`MAof;;5JK0%^?KCd@OU7bI@sBW zdG*o!x>Vl0uNC4{v-B210@5FILcHg?BHDX%!exYOS&=$3&*H3$T!+cE$5kBIglQ0RK3=?p zuyqo9Aowy(9{efiNs%|pbvA@(Q=7o&R+;jv2y{&kEOut?$+%>y@hk!`*=airHqGNF z0id(?>wfhtS+0)v(p6+zJ6DeYX>e{xtV^c?X)r51#G>B&p75_SnNJ44g0Pd5jsX^u z1_XcjD+uZHcKbRw!c>jHTL;WJE%NlM2+;yCmXP)~V4g()zy7!ehFl-R{}ch2W#gP* zMi{Nx6gcXfK&q`=dt`i_E1250XKdR&csz>$Bxlw}z?%a`n@Dx;r3tShz*tzh0JQ^f zWjgO;nt1JuG1hk4YBY#Nvywj)#vn*#TKN&5Tl~R9- z0Hn#!>k5Go2mlLlfjRfmCEZjJf|KwC7bAWbK~WS%Q4~c{{*0OZ7yT?xPj@oV(*OVf M07*qoM6N<$g8V6?fB*mh literal 1838 zcmai#dobIH7RP__O!SHbeW*u;-d?R%RUb$^A{CEXVzogLud0|L)F`qpf^bofxVvqX z#cXeBX%nxd6iKCnA~$NgC^w=Z;t|=XG@=^at8@S8-Q7ELXU>^9bLPzX<1^p$J;nZh zp1L}RbpQa+_4aZP005B2UK)e<8i3JaLlppMDZJg?u4K$g=O%7;AP*J@=Rm0x6a^}R zCTn-A^K<#2RZ1!vNkjQVPPqNKZ&|I%aYS`CXI&Jd6)fRgWSzEma#Q2Rj(zpDA@*~y zjGzY)U^g%ZmItGnYy74Z;$WML?;IR3-B*|lX?1xCz`qT^;*Bdxo=4s^GPvWbjrE#h z)O=gJc?Pc9S=MeQqt~$uz2H~D!S<_93Q`rTX)Nxwn6+6+pfBq-P{lw&1SU=GU3%B> zv2T&+c@t2Sv%Yy%{>ZVr<4szPii2AvfT84j;HxRORvYS%z3G_w&+Ts6ou)kFkIGR*0_%Tu6VQehg=U)$t=3RoTo=M!>GUMf$8`?%ba z`QJ%0a^cyim-@JtS&L?Q%FJ5mglkj+LHLY(rLs1jzhB}1~0KoX-7hx9m26*yeBVeCM$U*m3$@3C8^VYY0`3FCWPtkTv-Ejr^uF& z5ipOM$REv8G_!PRT_Fn}PN-qEi9sA&wBz)%sjdmK5Kk4P+{pL+`Cc5!$kNzUuf^i1 z@eX>@&s5a#U@TF=li)S@O@&d+ot9IebEXgar%!_Doxw@W;88gmoTe3B=^glssW8p1 zBev;Mv)!wIx>B2a=AUUaS#6bX9EU{KLcAqmZG#3>)>ZvKUebSnd^#Kzab9O0OCb@k zW{S}5U+GdN?pJ18%f(3u?j7T$0JgBk(zi4M zwno~mXUySM2RO5Z`>GP+&u`!?-p3P1TfpenV;qNo8RMfkm!t=d!pq=yv4K42PRup> zxg2rto^lRx{T@Q2qpn|e=LE9uW#}NNFia6}hDsBUn_#MBCx1%udzpXatZjlQ#BKg0 z&3welxTRd zj-s?-&!r2H=5LnXWt_7VNoW@d9*4N*iUQ3?3{tc2)?KpB51WD@gRo5VpzGl^BN_W> zjM0R4Hm~DFuC4y^rLuuS9C+`V>Trnn@}U5xKGzf;H8YakG}E^A2rO}+WN?M8>oM&H z&x2!DPJ!q-mVN!w{h-ZT1k`sE%zIZnBiqHh|45V~^`+lYBD*@jk;yD*eM&*gSbRED zE@zhW6yz0-Y9C}}r{4_HTmA>f{Q^J*!LUyElzL);03sfY`0*5<1y35ds+ySm5G50#e zmWWPHHlo~ke7l&HaA-8>Q@D~LOvP@LQq?m