diff --git a/module/language/c99/compiler.mes b/module/language/c99/compiler.mes index ee80387d..9a2e120b 100644 --- a/module/language/c99/compiler.mes +++ b/module/language/c99/compiler.mes @@ -145,8 +145,9 @@ (define ') (define ') (define ') +(define ') -(define* (make o #:key (types '()) (constants '()) (functions '()) (globals '()) (locals '()) (function #f) (text '()) (break '())) +(define* (make o #:key (types '()) (constants '()) (functions '()) (globals '()) (locals '()) (function #f) (text '()) (break '()) (continue '())) (pmatch o ( (list (cons types) @@ -156,7 +157,8 @@ (cons locals) (cons function) (cons text) - (cons break))))) + (cons break) + (cons continue))))) (define (.types o) (pmatch o @@ -190,6 +192,10 @@ (pmatch o (( . ,alist) (assq-ref alist )))) +(define (.continue o) + (pmatch o + (( . ,alist) (assq-ref alist )))) + (define (info? o) (and (pair? o) (eq? (car o) ))) @@ -202,7 +208,8 @@ (locals (.locals o)) (function (.function o)) (text (.text o)) - (break (.break o))) + (break (.break o)) + (continue (.continue o))) (let-keywords rest #f ((types types) @@ -212,8 +219,9 @@ (locals locals) (function function) (text text) - (break break)) - (make #:types types #:constants constants #:functions functions #:globals globals #:locals locals #:function function #:text text #:break break)))))) + (break break) + (continue continue)) + (make #:types types #:constants constants #:functions functions #:globals globals #:locals locals #:function function #:text text #:break break #:continue continue)))))) (define (push-global globals) (lambda (o) @@ -1374,6 +1382,9 @@ (append-text info (wrap-as (i386:Xjump (- label (length (object->list text))))));;REMOVEME (append-text info (wrap-as (i386:jump-label `(#:local ,label))))))) + ((continue) + (append-text info (wrap-as (i386:jump-label `(#:local ,(car (.continue info))))))) + ;; FIXME: expr-stmt wrapper? (trans-unit info) ((expr-stmt) info) @@ -1534,18 +1545,22 @@ (let* ((source (with-output-to-string (lambda () (pretty-print-c99 `(while ,test (ellipsis)))))) (info (append-text info (wrap-as `(#:comment ,source)))) (here (number->string (length text))) - (while-label (string-append (.function info) "_while_" here)) - (skip-label (string-append (.function info) "_skip_" here)) + (loop-label (string-append (.function info) "_loop_" here)) + (continue-label (string-append (.function info) "_continue_" here)) (break-label (string-append (.function info) "_break_" here)) - (info (append-text info (wrap-as (i386:jump-label `(#:local ,skip-label))))) + (info (append-text info (wrap-as (i386:jump-label `(#:local ,continue-label))))) (info (clone info #:break (cons break-label (.break info)))) - (info (append-text info (wrap-as `(#:label ,while-label)))) + (info (clone info #:continue (cons continue-label (.continue info)))) + (info (append-text info (wrap-as `(#:label ,loop-label)))) (info ((ast->info info) body)) - (info (append-text info (wrap-as `(#:label ,skip-label)))) + (info (append-text info (wrap-as `(#:label ,continue-label)))) (info ((test-jump-label->info info break-label) test)) - (info (append-text info (wrap-as (i386:jump-label `(#:local ,while-label))))) + (info (append-text info (wrap-as (i386:jump-label `(#:local ,loop-label))))) (info (append-text info (wrap-as `(#:label ,break-label))))) - (clone info #:break (cdr (.break info))))) + (clone info + #:locals locals + #:break (cdr (.break info)) + #:continue (cdr (.continue info))))) ((do-while ,body ,test) (let* ((text-length (length text)) diff --git a/scaffold/t.c b/scaffold/t.c index c54b2f27..54bbaaf3 100644 --- a/scaffold/t.c +++ b/scaffold/t.c @@ -814,6 +814,10 @@ test (char *p) puts ("t: while (1) {while (1) break;break;}\n"); while (1) {while (1) break;break;} + puts ("t: while () {continue;...}\n"); + while (one--) {continue;one=1;} + one += 2; + puts ("t: while (1) { goto label; };\n"); while (1) { goto ok00;