|
20 | 20 |
|
21 | 21 | #------------------------------------------------------------------------------- |
22 | 22 |
|
23 | | -function is_identifier_like(ex) |
24 | | - k = kind(ex) |
25 | | - k == K"Identifier" || k == K"BindingId" || k == K"Placeholder" |
26 | | -end |
27 | | - |
28 | 23 | # Return true when `x` and `y` are "the same identifier", but also works with |
29 | 24 | # bindings (and hence ssa vars). See also `is_identifier_like()` |
30 | 25 | function is_same_identifier_like(ex::SyntaxTree, y::SyntaxTree) |
@@ -1394,22 +1389,71 @@ function expand_let(ctx, ex) |
1394 | 1389 | elseif kb == K"=" && numchildren(binding) == 2 |
1395 | 1390 | lhs = binding[1] |
1396 | 1391 | rhs = binding[2] |
1397 | | - if is_sym_decl(lhs) |
| 1392 | + kl = kind(lhs) |
| 1393 | + if kl == K"Identifier" || kl == K"BindingId" |
1398 | 1394 | blk = @ast ctx binding [K"block" |
1399 | 1395 | tmp := rhs |
1400 | 1396 | [K"scope_block"(ex, scope_type=scope_type) |
1401 | | - # TODO: Use single child for scope_block? |
1402 | | - [K"local_def"(lhs) lhs] # TODO: Use K"local" with attr? |
1403 | | - [K"="(rhs) |
1404 | | - decl_var(lhs) |
1405 | | - tmp |
1406 | | - ] |
| 1397 | + [K"local"(lhs) lhs] |
| 1398 | + [K"always_defined" lhs] |
| 1399 | + [K"="(binding) lhs tmp] |
| 1400 | + blk |
| 1401 | + ] |
| 1402 | + ] |
| 1403 | + elseif kl == K"::" |
| 1404 | + var = lhs[1] |
| 1405 | + if !(kind(var) in KSet"Identifier BindingId") |
| 1406 | + throw(LoweringError(var, "Invalid assignment location in let syntax")) |
| 1407 | + end |
| 1408 | + blk = @ast ctx binding [K"block" |
| 1409 | + tmp := rhs |
| 1410 | + type := lhs[2] |
| 1411 | + [K"scope_block"(ex, scope_type=scope_type) |
| 1412 | + [K"local"(lhs) [K"::" var type]] |
| 1413 | + [K"always_defined" var] |
| 1414 | + [K"="(binding) var tmp] |
| 1415 | + blk |
| 1416 | + ] |
| 1417 | + ] |
| 1418 | + elseif kind(lhs) == K"tuple" |
| 1419 | + lhs_locals = SyntaxList(ctx) |
| 1420 | + foreach_lhs_var(lhs) do var |
| 1421 | + push!(lhs_locals, @ast ctx var [K"local" var]) |
| 1422 | + push!(lhs_locals, @ast ctx var [K"always_defined" var]) |
| 1423 | + end |
| 1424 | + blk = @ast ctx binding [K"block" |
| 1425 | + tmp := rhs |
| 1426 | + [K"scope_block"(ex, scope_type=scope_type) |
| 1427 | + lhs_locals... |
| 1428 | + [K"="(binding) lhs tmp] |
1407 | 1429 | blk |
1408 | 1430 | ] |
1409 | 1431 | ] |
1410 | 1432 | else |
1411 | | - TODO("Functions and multiple assignment") |
| 1433 | + throw(LoweringError(lhs, "Invalid assignment location in let syntax")) |
1412 | 1434 | end |
| 1435 | + elseif kind(binding) == K"function" |
| 1436 | + sig = binding[1] |
| 1437 | + func_name = assigned_function_name(sig) |
| 1438 | + if isnothing(func_name) |
| 1439 | + # Some valid function syntaxes define methods on existing types and |
| 1440 | + # don't really make sense with let: |
| 1441 | + # let A.f() = 1 ... end |
| 1442 | + # let (obj::Callable)() = 1 ... end |
| 1443 | + throw(LoweringError(sig, "Function signature does not define a local function name")) |
| 1444 | + end |
| 1445 | + blk = @ast ctx binding [K"block" |
| 1446 | + [K"scope_block"(ex, scope_type=scope_type) |
| 1447 | + [K"local"(func_name) func_name] |
| 1448 | + [K"always_defined" func_name] |
| 1449 | + binding |
| 1450 | + [K"scope_block"(ex, scope_type=scope_type) |
| 1451 | + # The inside of the block is isolated from the closure, |
| 1452 | + # which itself can only capture values from the outside. |
| 1453 | + blk |
| 1454 | + ] |
| 1455 | + ] |
| 1456 | + ] |
1413 | 1457 | else |
1414 | 1458 | throw(LoweringError(binding, "Invalid binding in let")) |
1415 | 1459 | continue |
@@ -1801,10 +1845,14 @@ end |
1801 | 1845 |
|
1802 | 1846 | function foreach_lhs_var(f::Function, ex) |
1803 | 1847 | k = kind(ex) |
1804 | | - if k == K"Identifier" |
| 1848 | + if k == K"Identifier" || k == K"BindingId" |
1805 | 1849 | f(ex) |
1806 | 1850 | elseif k == K"Placeholder" |
1807 | 1851 | # Ignored |
| 1852 | + elseif k == K"tuple" |
| 1853 | + for e in children(ex) |
| 1854 | + foreach_lhs_var(f, e) |
| 1855 | + end |
1808 | 1856 | else |
1809 | 1857 | TODO(ex, "LHS vars") |
1810 | 1858 | end |
@@ -3091,7 +3139,8 @@ function expand_abstract_or_primitive_type(ctx, ex) |
3091 | 3139 | @ast ctx ex [K"block" |
3092 | 3140 | [K"scope_block"(scope_type=:hard) |
3093 | 3141 | [K"block" |
3094 | | - [K"local_def" name] |
| 3142 | + [K"local" name] |
| 3143 | + [K"always_defined" name] |
3095 | 3144 | typevar_stmts... |
3096 | 3145 | [K"=" |
3097 | 3146 | newtype_var |
@@ -3624,7 +3673,8 @@ function expand_struct_def(ctx, ex, docs) |
3624 | 3673 | [K"block" |
3625 | 3674 | [K"global" global_struct_name] |
3626 | 3675 | [K"const" global_struct_name] |
3627 | | - [K"local_def" struct_name] |
| 3676 | + [K"local" struct_name] |
| 3677 | + [K"always_defined" struct_name] |
3628 | 3678 | typevar_stmts... |
3629 | 3679 | [K"=" |
3630 | 3680 | newtype_var |
|
0 commit comments