Skip to content

Commit fd9e981

Browse files
authored
Always emit a block for let binding lists (#126)
This moves the unnecessary special cases for lists of bindings in `let` out of the parser and into Expr lowering.
1 parent d81eafb commit fd9e981

File tree

3 files changed

+26
-19
lines changed

3 files changed

+26
-19
lines changed

src/expr.jl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,16 @@ function _to_expr(node::SyntaxNode; iteration_spec=false, need_linenodes=true,
243243
elseif headsym == :char
244244
@check length(args) == 1
245245
return args[1]
246+
elseif headsym == :let
247+
@check Meta.isexpr(args[1], :block)
248+
a1 = args[1].args
249+
# Ugly logic to strip the Expr(:block) in certian cases for compatibility
250+
if length(a1) == 1
251+
a = a1[1]
252+
if a isa Symbol || Meta.isexpr(a, (:(=), :(::)))
253+
args[1] = a
254+
end
255+
end
246256
end
247257
return Expr(headsym, args...)
248258
end

src/parser.jl

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1696,19 +1696,16 @@ function parse_resword(ps::ParseState)
16961696
elseif word == K"let"
16971697
bump(ps, TRIVIA_FLAG)
16981698
if peek(ps) KSet"NewlineWs ;"
1699-
# let x=1\n end ==> (let (= x 1) (block))
1699+
# let x=1\n end ==> (let (block (= x 1)) (block))
1700+
# let x=1 ; end ==> (let (block (= x 1)) (block))
17001701
m = position(ps)
17011702
n_subexprs = parse_comma_separated(ps, parse_eq_star)
17021703
kb = peek_behind(ps).kind
1703-
# Wart: This ugly logic seems unfortunate. Why not always emit a block?
1704-
# let x=1 ; end ==> (let (= x 1) (block))
1705-
# let x::1 ; end ==> (let (:: x 1) (block))
1706-
# let x ; end ==> (let x (block))
1707-
if n_subexprs > 1 || !(kb in KSet"Identifier = ::")
1708-
# let x=1,y=2 ; end ==> (let (block (= x 1) (= y 2) (block)))
1709-
# let x+=1 ; end ==> (let (block (+= x 1)) (block))
1710-
emit(ps, m, K"block")
1711-
end
1704+
# let x::1 ; end ==> (let (block (:: x 1)) (block))
1705+
# let x ; end ==> (let (block x) (block))
1706+
# let x=1,y=2 ; end ==> (let (block (= x 1) (= y 2) (block)))
1707+
# let x+=1 ; end ==> (let (block (+= x 1)) (block))
1708+
emit(ps, m, K"block")
17121709
else
17131710
# let end ==> (let (block) (block))
17141711
# let ; end ==> (let (block) (block))

test/parser.jl

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -357,15 +357,15 @@ tests = [
357357
"for x in xs end" => "(for (= x xs) (block))"
358358
"for x in xs, y in ys \n a \n end" => "(for (block (= x xs) (= y ys)) (block a))"
359359
# let
360-
"let x=1\n end" => "(let (= x 1) (block))"
361-
"let x ; end" => "(let x (block))"
362-
"let x=1 ; end" => "(let (= x 1) (block))"
363-
"let x::1 ; end" => "(let (:: x 1) (block))"
364-
"let x=1,y=2 end" => "(let (block (= x 1) (= y 2)) (block))"
365-
"let x+=1 ; end" => "(let (block (+= x 1)) (block))"
366-
"let ; end" => "(let (block) (block))"
367-
"let ; body end" => "(let (block) (block body))"
368-
"let\na\nb\nend" => "(let (block) (block a b))"
360+
"let x=1\n end" => "(let (block (= x 1)) (block))" => Expr(:let, Expr(:(=), :x, 1), Expr(:block))
361+
"let x=1 ; end" => "(let (block (= x 1)) (block))" => Expr(:let, Expr(:(=), :x, 1), Expr(:block))
362+
"let x ; end" => "(let (block x) (block))" => Expr(:let, :x, Expr(:block))
363+
"let x::1 ; end" => "(let (block (:: x 1)) (block))" => Expr(:let, Expr(:(::), :x, 1), Expr(:block))
364+
"let x=1,y=2 end" => "(let (block (= x 1) (= y 2)) (block))" => Expr(:let, Expr(:block, Expr(:(=), :x, 1), Expr(:(=), :y, 2)), Expr(:block))
365+
"let x+=1 ; end" => "(let (block (+= x 1)) (block))" => Expr(:let, Expr(:block, Expr(:+=, :x, 1)), Expr(:block))
366+
"let ; end" => "(let (block) (block))" => Expr(:let, Expr(:block), Expr(:block))
367+
"let ; body end" => "(let (block) (block body))" => Expr(:let, Expr(:block), Expr(:block, :body))
368+
"let\na\nb\nend" => "(let (block) (block a b))" => Expr(:let, Expr(:block), Expr(:block, :a, :b))
369369
# abstract type
370370
"abstract type A end" => "(abstract A)"
371371
"abstract type A ; end" => "(abstract A)"

0 commit comments

Comments
 (0)