|
1422 | 1422 | ,@(reverse after)
|
1423 | 1423 | (unnecessary (tuple ,@(reverse elts))))
|
1424 | 1424 | (let ((L (car lhss))
|
1425 |
| - (R (car rhss))) |
| 1425 | + ;; rhss can be null iff L is a vararg |
| 1426 | + (R (if (null? rhss) '() (car rhss)))) |
1426 | 1427 | (cond ((and (symbol-like? L)
|
1427 | 1428 | (or (not (pair? R)) (quoted? R) (equal? R '(null)))
|
1428 | 1429 | ;; overwrite var immediately if it doesn't occur elsewhere
|
|
1434 | 1435 | (cons (make-assignment L R) stmts)
|
1435 | 1436 | after
|
1436 | 1437 | (cons R elts)))
|
| 1438 | + ((vararg? L) |
| 1439 | + (if (null? (cdr lhss)) |
| 1440 | + (let ((temp (make-ssavalue))) |
| 1441 | + `(block ,@(reverse stmts) |
| 1442 | + (= ,temp (tuple ,@rhss)) |
| 1443 | + ,@(reverse after) |
| 1444 | + (= ,(cadr L) ,temp) |
| 1445 | + (unnecessary (tuple ,@(reverse elts) (... ,temp))))) |
| 1446 | + (error (string "invalid \"...\" on non-final assignment location \"" |
| 1447 | + (cadr L) "\"")))) |
1437 | 1448 | ((vararg? R)
|
1438 | 1449 | (let ((temp (make-ssavalue)))
|
1439 | 1450 | `(block ,@(reverse stmts)
|
|
2035 | 2046 | (define (sides-match? l r)
|
2036 | 2047 | ;; l and r either have equal lengths, or r has a trailing ...
|
2037 | 2048 | (cond ((null? l) (null? r))
|
| 2049 | + ((vararg? (car l)) #t) |
2038 | 2050 | ((null? r) #f)
|
2039 | 2051 | ((vararg? (car r)) (null? (cdr r)))
|
2040 | 2052 | (else (sides-match? (cdr l) (cdr r)))))
|
|
2044 | 2056 | (expand-forms
|
2045 | 2057 | (tuple-to-assignments lhss x))
|
2046 | 2058 | ;; (a, b, ...) = other
|
2047 |
| - (let* ((xx (if (or (and (symbol? x) (not (memq x lhss))) |
2048 |
| - (ssavalue? x)) |
2049 |
| - x (make-ssavalue))) |
2050 |
| - (ini (if (eq? x xx) '() (list (sink-assignment xx (expand-forms x))))) |
2051 |
| - (n (length lhss)) |
2052 |
| - (funcs (make-ssavalue)) |
2053 |
| - (iterate (make-ssavalue)) |
2054 |
| - (index (make-ssavalue)) |
2055 |
| - (st (gensy))) |
2056 |
| - `(block |
2057 |
| - ,@ini |
2058 |
| - ,(lower-tuple-assignment |
2059 |
| - (list iterate index) |
2060 |
| - `(call (top iterate_and_index) ,xx)) |
2061 |
| - ,.(map (lambda (i lhs) |
2062 |
| - (expand-forms |
2063 |
| - `(block |
2064 |
| - (= ,st (call ,iterate |
2065 |
| - ,xx ,.(if (eq? i 0) '() `(,st)))) |
2066 |
| - ,(if (eventually-call? lhs) |
2067 |
| - (let ((val (gensy))) |
2068 |
| - `(block |
2069 |
| - (= ,val (call ,index ,st ,(+ i 1))) |
2070 |
| - (= ,lhs ,val))) |
2071 |
| - `(= ,lhs (call ,index ,st ,(+ i 1))))))) |
2072 |
| - (iota n) |
2073 |
| - lhss) |
2074 |
| - (unnecessary ,xx)))))) |
| 2059 | + (begin |
| 2060 | + ;; like memq, but if last element of lhss is (... sym), |
| 2061 | + ;; check against sym instead |
| 2062 | + (define (in-lhs? x lhss) |
| 2063 | + (if (null? lhss) |
| 2064 | + #f |
| 2065 | + (let ((l (car lhss))) |
| 2066 | + (cond ((and (pair? l) (eq? (car l) '|...|)) |
| 2067 | + (if (null? (cdr lhss)) |
| 2068 | + (eq? (cadr l) x) |
| 2069 | + (error (string "invalid \"...\" on non-final assignment location \"" |
| 2070 | + (cadr l) "\"")))) |
| 2071 | + ((eq? l x) #t) |
| 2072 | + (else (in-lhs? x (cdr lhss))))))) |
| 2073 | + (define (gensymified-assignment lhs rhs) |
| 2074 | + (if (eventually-call? lhs) |
| 2075 | + (let ((val (gensy))) |
| 2076 | + `(block |
| 2077 | + (= ,val ,rhs) |
| 2078 | + (= ,lhs ,val))) |
| 2079 | + `(= ,lhs ,rhs))) |
| 2080 | + (let* ((xx (if (or (and (not (in-lhs? x lhss)) (symbol? x)) |
| 2081 | + (ssavalue? x)) |
| 2082 | + x (make-ssavalue))) |
| 2083 | + (ini (if (eq? x xx) '() (list (sink-assignment xx (expand-forms x))))) |
| 2084 | + (n (length lhss)) |
| 2085 | + (funcs (make-ssavalue)) |
| 2086 | + (iterate (make-ssavalue)) |
| 2087 | + (index (make-ssavalue)) |
| 2088 | + (st (gensy))) |
| 2089 | + `(block |
| 2090 | + ,@ini |
| 2091 | + ,(lower-tuple-assignment |
| 2092 | + (list iterate index) |
| 2093 | + `(call (top iterate_and_index) ,xx)) |
| 2094 | + ,.(map (lambda (i lhs) |
| 2095 | + (expand-forms |
| 2096 | + (if (and (pair? lhs) (eq? (car lhs) '|...|)) |
| 2097 | + (gensymified-assignment |
| 2098 | + (cadr lhs) |
| 2099 | + `(call (top _rest) |
| 2100 | + ,xx |
| 2101 | + ,(if (eq? i 0) '(tuple) `(tuple ,st)) |
| 2102 | + ,(+ i 1))) |
| 2103 | + `(block |
| 2104 | + (= ,st (call ,iterate |
| 2105 | + ,xx ,.(if (eq? i 0) '() `(,st)))) |
| 2106 | + ,(gensymified-assignment |
| 2107 | + lhs |
| 2108 | + `(call ,index ,st ,(+ i 1))))))) |
| 2109 | + (iota n) |
| 2110 | + lhss) |
| 2111 | + (unnecessary ,xx))))))) |
2075 | 2112 | ((typed_hcat)
|
2076 | 2113 | (error "invalid spacing in left side of indexed assignment"))
|
2077 | 2114 | ((typed_vcat)
|
|
0 commit comments