|
1521 | 1521 | (else
|
1522 | 1522 | (error (string "invalid syntax in \"" what "\" declaration"))))))))
|
1523 | 1523 |
|
| 1524 | +(define (expand-assignment e (const? #f)) |
| 1525 | + (define lhs (cadr e)) |
| 1526 | + (define (function-lhs? lhs) |
| 1527 | + (and (pair? lhs) |
| 1528 | + (or (eq? (car lhs) 'call) |
| 1529 | + (eq? (car lhs) 'where) |
| 1530 | + (and (eq? (car lhs) '|::|) |
| 1531 | + (pair? (cadr lhs)) |
| 1532 | + (eq? (car (cadr lhs)) 'call))))) |
| 1533 | + (define (assignment-to-function lhs e) ;; convert '= expr to 'function expr |
| 1534 | + (cons 'function (cdr e))) |
| 1535 | + (cond |
| 1536 | + ((function-lhs? lhs) |
| 1537 | + (expand-forms (assignment-to-function lhs e))) |
| 1538 | + ((and (pair? lhs) |
| 1539 | + (eq? (car lhs) 'curly)) |
| 1540 | + (expand-unionall-def (cadr e) (caddr e))) |
| 1541 | + ((assignment? (caddr e)) |
| 1542 | + ;; chain of assignments - convert a=b=c to `b=c; a=c` |
| 1543 | + (let loop ((lhss (list lhs)) |
| 1544 | + (rhs (caddr e))) |
| 1545 | + (if (and (assignment? rhs) (not (function-lhs? (cadr rhs)))) |
| 1546 | + (loop (cons (cadr rhs) lhss) (caddr rhs)) |
| 1547 | + (let ((rr (if (symbol-like? rhs) rhs (make-ssavalue)))) |
| 1548 | + (expand-forms |
| 1549 | + `(block ,.(if (eq? rr rhs) '() `((= ,rr ,(if (assignment? rhs) |
| 1550 | + (assignment-to-function (cadr rhs) rhs) |
| 1551 | + rhs)))) |
| 1552 | + ,@(map (lambda (l) `(= ,l ,rr)) |
| 1553 | + lhss) |
| 1554 | + (unnecessary ,rr))))))) |
| 1555 | + ((or (and (symbol-like? lhs) (valid-name? lhs)) |
| 1556 | + (globalref? lhs)) |
| 1557 | + (sink-assignment lhs (expand-forms (caddr e)))) |
| 1558 | + ((atom? lhs) |
| 1559 | + (error (string "invalid assignment location \"" (deparse lhs) "\""))) |
| 1560 | + (else |
| 1561 | + (case (car lhs) |
| 1562 | + ((|.|) |
| 1563 | + ;; a.b = |
| 1564 | + (let* ((a (cadr lhs)) |
| 1565 | + (b (caddr lhs)) |
| 1566 | + (rhs (caddr e))) |
| 1567 | + (if (and (length= b 2) (eq? (car b) 'tuple)) |
| 1568 | + (error (string "invalid syntax \"" |
| 1569 | + (string (deparse a) ".(" (deparse (cadr b)) ") = ...") "\""))) |
| 1570 | + (let ((aa (if (symbol-like? a) a (make-ssavalue))) |
| 1571 | + (bb (if (or (atom? b) (symbol-like? b) (and (pair? b) (quoted? b))) |
| 1572 | + b (make-ssavalue))) |
| 1573 | + (rr (if (or (symbol-like? rhs) (atom? rhs)) rhs (make-ssavalue)))) |
| 1574 | + `(block |
| 1575 | + ,.(if (eq? aa a) '() (list (sink-assignment aa (expand-forms a)))) |
| 1576 | + ,.(if (eq? bb b) '() (list (sink-assignment bb (expand-forms b)))) |
| 1577 | + ,.(if (eq? rr rhs) '() (list (sink-assignment rr (expand-forms rhs)))) |
| 1578 | + (call (top setproperty!) ,aa ,bb ,rr) |
| 1579 | + (unnecessary ,rr))))) |
| 1580 | + ((tuple) |
| 1581 | + (let ((lhss (cdr lhs)) |
| 1582 | + (x (caddr e))) |
| 1583 | + (if (has-parameters? lhss) |
| 1584 | + ;; property destructuring |
| 1585 | + (expand-property-destruct lhss x) |
| 1586 | + ;; multiple assignment |
| 1587 | + (expand-tuple-destruct lhss x)))) |
| 1588 | + ((typed_hcat) |
| 1589 | + (error "invalid spacing in left side of indexed assignment")) |
| 1590 | + ((typed_vcat typed_ncat) |
| 1591 | + (error "unexpected \";\" in left side of indexed assignment")) |
| 1592 | + ((ref) |
| 1593 | + ;; (= (ref a . idxs) rhs) |
| 1594 | + (let ((a (cadr lhs)) |
| 1595 | + (idxs (cddr lhs)) |
| 1596 | + (rhs (caddr e))) |
| 1597 | + (let* ((reuse (and (pair? a) |
| 1598 | + (contains (lambda (x) (eq? x 'end)) |
| 1599 | + idxs))) |
| 1600 | + (arr (if reuse (make-ssavalue) a)) |
| 1601 | + (stmts (if reuse `((= ,arr ,(expand-forms a))) '())) |
| 1602 | + (rrhs (and (pair? rhs) (not (ssavalue? rhs)) (not (quoted? rhs)))) |
| 1603 | + (r (if rrhs (make-ssavalue) rhs)) |
| 1604 | + (rini (if rrhs (list (sink-assignment r (expand-forms rhs))) '()))) |
| 1605 | + (receive |
| 1606 | + (new-idxs stuff) (process-indices arr idxs) |
| 1607 | + `(block |
| 1608 | + ,@stmts |
| 1609 | + ,.(map expand-forms stuff) |
| 1610 | + ,@rini |
| 1611 | + ,(expand-forms |
| 1612 | + `(call (top setindex!) ,arr ,r ,@new-idxs)) |
| 1613 | + (unnecessary ,r)))))) |
| 1614 | + ((|::|) |
| 1615 | + ;; (= (|::| T) rhs) is an error |
| 1616 | + (if (null? (cddr lhs)) |
| 1617 | + (error (string "invalid assignment location \"" (deparse lhs) "\""))) |
| 1618 | + ;; (= (|::| x T) rhs) |
| 1619 | + (let ((x (cadr lhs)) |
| 1620 | + (T (caddr lhs)) |
| 1621 | + (rhs (caddr e))) |
| 1622 | + (let ((e (remove-argument-side-effects x))) |
| 1623 | + (expand-forms |
| 1624 | + `(block ,@(cdr e) |
| 1625 | + (decl ,(car e) ,T) |
| 1626 | + (= ,(car e) ,rhs)))))) |
| 1627 | + ((vcat ncat) |
| 1628 | + ;; (= (vcat . args) rhs) |
| 1629 | + (error "use \"(a, b) = ...\" to assign multiple values")) |
| 1630 | + (else |
| 1631 | + (error (string "invalid assignment location \"" (deparse lhs) "\""))))))) |
| 1632 | + |
1524 | 1633 | ;; convert (lhss...) = (tuple ...) to assignments, eliminating the tuple
|
1525 | 1634 | (define (tuple-to-assignments lhss0 x wrap)
|
1526 | 1635 | (let loop ((lhss lhss0)
|
|
2492 | 2601 | 'global expand-local-or-global-decl
|
2493 | 2602 | 'local-def expand-local-or-global-decl
|
2494 | 2603 |
|
2495 |
| - '= |
2496 |
| - (lambda (e) |
2497 |
| - (define lhs (cadr e)) |
2498 |
| - (define (function-lhs? lhs) |
2499 |
| - (and (pair? lhs) |
2500 |
| - (or (eq? (car lhs) 'call) |
2501 |
| - (eq? (car lhs) 'where) |
2502 |
| - (and (eq? (car lhs) '|::|) |
2503 |
| - (pair? (cadr lhs)) |
2504 |
| - (eq? (car (cadr lhs)) 'call))))) |
2505 |
| - (define (assignment-to-function lhs e) ;; convert '= expr to 'function expr |
2506 |
| - (cons 'function (cdr e))) |
2507 |
| - (cond |
2508 |
| - ((function-lhs? lhs) |
2509 |
| - (expand-forms (assignment-to-function lhs e))) |
2510 |
| - ((and (pair? lhs) |
2511 |
| - (eq? (car lhs) 'curly)) |
2512 |
| - (expand-unionall-def (cadr e) (caddr e))) |
2513 |
| - ((assignment? (caddr e)) |
2514 |
| - ;; chain of assignments - convert a=b=c to `b=c; a=c` |
2515 |
| - (let loop ((lhss (list lhs)) |
2516 |
| - (rhs (caddr e))) |
2517 |
| - (if (and (assignment? rhs) (not (function-lhs? (cadr rhs)))) |
2518 |
| - (loop (cons (cadr rhs) lhss) (caddr rhs)) |
2519 |
| - (let ((rr (if (symbol-like? rhs) rhs (make-ssavalue)))) |
2520 |
| - (expand-forms |
2521 |
| - `(block ,.(if (eq? rr rhs) '() `((= ,rr ,(if (assignment? rhs) |
2522 |
| - (assignment-to-function (cadr rhs) rhs) |
2523 |
| - rhs)))) |
2524 |
| - ,@(map (lambda (l) `(= ,l ,rr)) |
2525 |
| - lhss) |
2526 |
| - (unnecessary ,rr))))))) |
2527 |
| - ((or (and (symbol-like? lhs) (valid-name? lhs)) |
2528 |
| - (globalref? lhs)) |
2529 |
| - (sink-assignment lhs (expand-forms (caddr e)))) |
2530 |
| - ((atom? lhs) |
2531 |
| - (error (string "invalid assignment location \"" (deparse lhs) "\""))) |
2532 |
| - (else |
2533 |
| - (case (car lhs) |
2534 |
| - ((|.|) |
2535 |
| - ;; a.b = |
2536 |
| - (let* ((a (cadr lhs)) |
2537 |
| - (b (caddr lhs)) |
2538 |
| - (rhs (caddr e))) |
2539 |
| - (if (and (length= b 2) (eq? (car b) 'tuple)) |
2540 |
| - (error (string "invalid syntax \"" |
2541 |
| - (string (deparse a) ".(" (deparse (cadr b)) ") = ...") "\""))) |
2542 |
| - (let ((aa (if (symbol-like? a) a (make-ssavalue))) |
2543 |
| - (bb (if (or (atom? b) (symbol-like? b) (and (pair? b) (quoted? b))) |
2544 |
| - b (make-ssavalue))) |
2545 |
| - (rr (if (or (symbol-like? rhs) (atom? rhs)) rhs (make-ssavalue)))) |
2546 |
| - `(block |
2547 |
| - ,.(if (eq? aa a) '() (list (sink-assignment aa (expand-forms a)))) |
2548 |
| - ,.(if (eq? bb b) '() (list (sink-assignment bb (expand-forms b)))) |
2549 |
| - ,.(if (eq? rr rhs) '() (list (sink-assignment rr (expand-forms rhs)))) |
2550 |
| - (call (top setproperty!) ,aa ,bb ,rr) |
2551 |
| - (unnecessary ,rr))))) |
2552 |
| - ((tuple) |
2553 |
| - (let ((lhss (cdr lhs)) |
2554 |
| - (x (caddr e))) |
2555 |
| - (if (has-parameters? lhss) |
2556 |
| - ;; property destructuring |
2557 |
| - (expand-property-destruct lhss x) |
2558 |
| - ;; multiple assignment |
2559 |
| - (expand-tuple-destruct lhss x)))) |
2560 |
| - ((typed_hcat) |
2561 |
| - (error "invalid spacing in left side of indexed assignment")) |
2562 |
| - ((typed_vcat typed_ncat) |
2563 |
| - (error "unexpected \";\" in left side of indexed assignment")) |
2564 |
| - ((ref) |
2565 |
| - ;; (= (ref a . idxs) rhs) |
2566 |
| - (let ((a (cadr lhs)) |
2567 |
| - (idxs (cddr lhs)) |
2568 |
| - (rhs (caddr e))) |
2569 |
| - (let* ((reuse (and (pair? a) |
2570 |
| - (contains (lambda (x) (eq? x 'end)) |
2571 |
| - idxs))) |
2572 |
| - (arr (if reuse (make-ssavalue) a)) |
2573 |
| - (stmts (if reuse `((= ,arr ,(expand-forms a))) '())) |
2574 |
| - (rrhs (and (pair? rhs) (not (ssavalue? rhs)) (not (quoted? rhs)))) |
2575 |
| - (r (if rrhs (make-ssavalue) rhs)) |
2576 |
| - (rini (if rrhs (list (sink-assignment r (expand-forms rhs))) '()))) |
2577 |
| - (receive |
2578 |
| - (new-idxs stuff) (process-indices arr idxs) |
2579 |
| - `(block |
2580 |
| - ,@stmts |
2581 |
| - ,.(map expand-forms stuff) |
2582 |
| - ,@rini |
2583 |
| - ,(expand-forms |
2584 |
| - `(call (top setindex!) ,arr ,r ,@new-idxs)) |
2585 |
| - (unnecessary ,r)))))) |
2586 |
| - ((|::|) |
2587 |
| - ;; (= (|::| T) rhs) is an error |
2588 |
| - (if (null? (cddr lhs)) |
2589 |
| - (error (string "invalid assignment location \"" (deparse lhs) "\""))) |
2590 |
| - ;; (= (|::| x T) rhs) |
2591 |
| - (let ((x (cadr lhs)) |
2592 |
| - (T (caddr lhs)) |
2593 |
| - (rhs (caddr e))) |
2594 |
| - (let ((e (remove-argument-side-effects x))) |
2595 |
| - (expand-forms |
2596 |
| - `(block ,@(cdr e) |
2597 |
| - (decl ,(car e) ,T) |
2598 |
| - (= ,(car e) ,rhs)))))) |
2599 |
| - ((vcat ncat) |
2600 |
| - ;; (= (vcat . args) rhs) |
2601 |
| - (error "use \"(a, b) = ...\" to assign multiple values")) |
2602 |
| - (else |
2603 |
| - (error (string "invalid assignment location \"" (deparse lhs) "\""))))))) |
| 2604 | + '= expand-assignment |
2604 | 2605 |
|
2605 | 2606 | 'abstract
|
2606 | 2607 | (lambda (e)
|
|
0 commit comments