Skip to content

Commit 22cbf82

Browse files
ekaitz-zarragajanneke
authored andcommitted
mescc: Fix switch statements' fallthrough
Flattens case structures as nyacc is giving consecutive cases as a nested block like: (case testA (case testB (case testC BODY))) We convert to: ((case testA (expr-stmt)) (case testB (expr-stmt)) (case testC BODY)) And then treat them as independent cases. For the fallthrough we just add a jump to each case's body right before its clause (each of the case blocks is responsible of adding its own jump to its body): // This doesn't have it because it's the first CASE1: testA CASE1_BODY: goto CASE2_BODY CASE2: testB CASE2_BODY: goto CASE3_BODY CASE3: testB CASE3_BODY: This enables complex fallthrough schemes comparing to what was done before. * module/mescc/compile.scm (ast->info)[switch]{flatten-cases}: New variable. (ast->info)[switch]{statements}: Use flatten-cases on it. (switch->expr): Remove unneeded matchers and add jumps to body. * build-aux/check-mescc.sh(xfail-tests): Remove lib/tests/scaffold/66-local-char-array.c
1 parent e689782 commit 22cbf82

File tree

2 files changed

+30
-16
lines changed

2 files changed

+30
-16
lines changed

build-aux/check-mescc.sh

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,6 @@ if test $compiler = mescc; then
253253
xfail_tests="$xfail_tests
254254
lib/tests/scaffold/17-compare-unsigned-char-le.c
255255
lib/tests/scaffold/17-compare-unsigned-short-le.c
256-
lib/tests/scaffold/66-local-char-array.c
257256
lib/tests/scaffold/70-ternary-arithmetic-argument.c
258257
lib/tests/mes/90-abtod.c
259258
lib/tests/mes/90-dtoab.c

module/mescc/compile.scm

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1790,7 +1790,33 @@
17901790
(when (clause? (car o))
17911791
(set! i (1+ i)))
17921792
n))))
1793+
1794+
(define (flatten-cases c)
1795+
(define (flatten-case case)
1796+
(pmatch case
1797+
((case ,test (case . ,body))
1798+
(append `((case ,test (expr-stmt))) (flatten-case `(case ,@body))))
1799+
((case ,test ,casebody (case . ,body))
1800+
(append `((case ,test ,casebody)) (flatten-case `(case ,@body))))
1801+
((default (case . ,body))
1802+
(append `((default (expr-stmt))) (flatten-case `(case ,@body))))
1803+
((default ,defbody (case . ,body))
1804+
(append `((default ,defbody)) (flatten-case `(case ,@body))))
1805+
((case ,test (default . ,body))
1806+
(append `((case ,test (expr-stmt))) (flatten-case `(default ,@body))))
1807+
((default ,rest)
1808+
(list case))
1809+
((case ,test)
1810+
(list case))
1811+
((case ,test ,expr)
1812+
(list case))
1813+
(,s (list s))))
1814+
(fold (lambda (x acc) (append acc (flatten-case x))) '() c))
1815+
1816+
1817+
17931818
(let* ((info (append-text info (ast->comment `(switch ,expr (compd-stmt (block-item-list (ellipsis)))))))
1819+
(statements (flatten-cases statements))
17941820
(here (number->string (length text)))
17951821
(label (string-append "_" (.function info) "_" here "_"))
17961822
(break-label (string-append label "break"))
@@ -1926,8 +1952,8 @@
19261952
(let* ((i-string (number->string i))
19271953
(i+1-string (number->string (1+ i)))
19281954
(body-label (string-append label "body" i-string))
1929-
(next-body-label (string-append label "body" i+1-string))
19301955
(clause-label (string-append label "clause" i-string))
1956+
(first? (= i 0))
19311957
(last? (= i count))
19321958
(break-label (string-append label "break"))
19331959
(next-clause-label (string-append label "clause" i+1-string))
@@ -1953,30 +1979,19 @@
19531979
(let ((info (if clause? (append-text info (wrap-as `((#:label ,clause-label))))
19541980
info)))
19551981
(append-text info (test->text test))))
1956-
((case ,test (case . ,case1))
1957-
(let ((info (if clause? (append-text info (wrap-as `((#:label ,clause-label))))
1958-
info)))
1959-
(fold (cut switch->info #f label count <> i <>) info (cons `(case ,test) `((case ,@case1))))))
19601982
((case ,test (default . ,rest))
19611983
(let ((info (if clause? (append-text info (wrap-as `((#:label ,clause-label))))
19621984
info)))
19631985
(fold (cut switch->info #f label count <> i <>) info (cons `(case ,test) `(default ,@rest)))))
19641986
((case ,test ,statement)
1965-
(let* ((info (if clause? (append-text info (wrap-as `((#:label ,clause-label))))
1987+
(let* ((info (if first? info (append-text info (jump body-label)))) ; Enables fallthrough
1988+
(info (if clause? (append-text info (wrap-as `((#:label ,clause-label))))
19661989
info))
19671990
(info (switch->info #f label count `(case ,test) i info))
19681991
(info (append-text info (jump next-clause-label)))
19691992
(info (append-text info (wrap-as `((#:label ,body-label)))))
1970-
(info (ast->info statement info))
1971-
;; 66-local-char-array -- fallthrough FIXME
1972-
;; (info (if last? info
1973-
;; (append-text info (jump next-body-label))))
1974-
)
1993+
(info (ast->info statement info)))
19751994
info))
1976-
((case ,test (case . ,case1) . ,rest)
1977-
(let ((info (if clause? (append-text info (wrap-as `((#:label ,clause-label))))
1978-
info)))
1979-
(fold (cut switch->info #f label count <> i <>) info (cons `(case ,test) `((case ,@case1) ,@rest)))))
19801995
((default (case . ,case1) . ,rest)
19811996
(let* ((info (if clause? (append-text info (wrap-as `((#:label ,clause-label))))
19821997
info))

0 commit comments

Comments
 (0)