mescc: Support break in while.
* module/language/c99/compiler.mes (make): Add break field. (.break): New function. (clone): Support break field. (ast->info): Support break. * scaffold/t.c (test): Test it. * scaffold/mini-mes.c (lookup_symbol_): Use it; remove goto workaround.
This commit is contained in:
parent
6009cf95fe
commit
39d334d51b
|
@ -114,8 +114,9 @@
|
||||||
(define <locals> '<locals>)
|
(define <locals> '<locals>)
|
||||||
(define <function> '<function>)
|
(define <function> '<function>)
|
||||||
(define <text> '<text>)
|
(define <text> '<text>)
|
||||||
|
(define <break> '<break>)
|
||||||
|
|
||||||
(define* (make o #:key (types '()) (constants '()) (functions '()) (globals '()) (init '()) (locals '()) (function #f) (text '()))
|
(define* (make o #:key (types '()) (constants '()) (functions '()) (globals '()) (init '()) (locals '()) (function #f) (text '()) (break '()))
|
||||||
(pmatch o
|
(pmatch o
|
||||||
(<info> (list <info>
|
(<info> (list <info>
|
||||||
(cons <types> types)
|
(cons <types> types)
|
||||||
|
@ -125,7 +126,8 @@
|
||||||
(cons <init> init)
|
(cons <init> init)
|
||||||
(cons <locals> locals)
|
(cons <locals> locals)
|
||||||
(cons <function> function)
|
(cons <function> function)
|
||||||
(cons <text> text)))))
|
(cons <text> text)
|
||||||
|
(cons <break> break)))))
|
||||||
|
|
||||||
(define (.types o)
|
(define (.types o)
|
||||||
(pmatch o
|
(pmatch o
|
||||||
|
@ -159,6 +161,10 @@
|
||||||
(pmatch o
|
(pmatch o
|
||||||
((<info> . ,alist) (assq-ref alist <text>))))
|
((<info> . ,alist) (assq-ref alist <text>))))
|
||||||
|
|
||||||
|
(define (.break o)
|
||||||
|
(pmatch o
|
||||||
|
((<info> . ,alist) (assq-ref alist <break>))))
|
||||||
|
|
||||||
(define (info? o)
|
(define (info? o)
|
||||||
(and (pair? o) (eq? (car o) <info>)))
|
(and (pair? o) (eq? (car o) <info>)))
|
||||||
|
|
||||||
|
@ -171,7 +177,8 @@
|
||||||
(init (.init o))
|
(init (.init o))
|
||||||
(locals (.locals o))
|
(locals (.locals o))
|
||||||
(function (.function o))
|
(function (.function o))
|
||||||
(text (.text o)))
|
(text (.text o))
|
||||||
|
(break (.break o)))
|
||||||
(let-keywords rest
|
(let-keywords rest
|
||||||
#f
|
#f
|
||||||
((types types)
|
((types types)
|
||||||
|
@ -181,8 +188,9 @@
|
||||||
(init init)
|
(init init)
|
||||||
(locals locals)
|
(locals locals)
|
||||||
(function function)
|
(function function)
|
||||||
(text text))
|
(text text)
|
||||||
(make <info> #:types types #:constants constants #:functions functions #:globals globals #:init init #:locals locals #:function function #:text text))))))
|
(break break))
|
||||||
|
(make <info> #:types types #:constants constants #:functions functions #:globals globals #:init init #:locals locals #:function function #:text text #:break break))))))
|
||||||
|
|
||||||
(define (push-global globals)
|
(define (push-global globals)
|
||||||
(lambda (o)
|
(lambda (o)
|
||||||
|
@ -744,8 +752,7 @@
|
||||||
(lambda (o)
|
(lambda (o)
|
||||||
(pmatch o
|
(pmatch o
|
||||||
((break) (append-text info (jump body-length)))
|
((break) (append-text info (jump body-length)))
|
||||||
(_
|
(_ ((ast->info info) o)))))
|
||||||
((ast->info info) o)))))
|
|
||||||
(define (test->text test)
|
(define (test->text test)
|
||||||
(let ((value (pmatch test
|
(let ((value (pmatch test
|
||||||
(0 0)
|
(0 0)
|
||||||
|
@ -985,6 +992,9 @@
|
||||||
((cast (type-name (decl-spec-list (type-spec (void)))) _)
|
((cast (type-name (decl-spec-list (type-spec (void)))) _)
|
||||||
info)
|
info)
|
||||||
|
|
||||||
|
((break)
|
||||||
|
(append-text info (wrap-as (i386:Xjump (- (car (.break info)) (length (text->list text)))))))
|
||||||
|
|
||||||
;; FIXME: expr-stmt wrapper?
|
;; FIXME: expr-stmt wrapper?
|
||||||
(trans-unit info)
|
(trans-unit info)
|
||||||
((expr-stmt) info)
|
((expr-stmt) info)
|
||||||
|
@ -1132,21 +1142,21 @@
|
||||||
#:globals (append globals (list-tail (.globals body-info) (length globals)))
|
#:globals (append globals (list-tail (.globals body-info) (length globals)))
|
||||||
#:locals locals)))
|
#:locals locals)))
|
||||||
|
|
||||||
;; FIXME: support break statement (see switch/case)
|
|
||||||
((while ,test ,body)
|
((while ,test ,body)
|
||||||
(let* ((skip-info (lambda (body-length)
|
(let* ((skip-info (lambda (body-length test-length)
|
||||||
(clone info #:text (append text
|
(clone info
|
||||||
(wrap-as (i386:Xjump body-length))))))
|
#:text (append text (wrap-as (i386:Xjump body-length)))
|
||||||
(text (.text (skip-info 0)))
|
#:break (cons (+ (length (text->list text)) body-length test-length
|
||||||
|
(length (i386:Xjump 0)))
|
||||||
|
(.break info)))))
|
||||||
|
(text (.text (skip-info 0 0)))
|
||||||
(text-length (length text))
|
(text-length (length text))
|
||||||
|
(body-info (lambda (body-length test-length)
|
||||||
|
((ast->info (skip-info body-length test-length)) body)))
|
||||||
|
|
||||||
(body-info (lambda (body-length)
|
(body-text (list-tail (.text (body-info 0 0)) text-length))
|
||||||
((ast->info (skip-info body-length)) body)))
|
|
||||||
(body-text (list-tail (.text (body-info 0)) text-length))
|
|
||||||
(body-length (length (text->list body-text)))
|
(body-length (length (text->list body-text)))
|
||||||
|
|
||||||
(body-info (body-info body-length))
|
|
||||||
|
|
||||||
(empty (clone info #:text '()))
|
(empty (clone info #:text '()))
|
||||||
(test-jump->info ((test->jump->info empty) test))
|
(test-jump->info ((test->jump->info empty) test))
|
||||||
(test+jump-info (test-jump->info 0))
|
(test+jump-info (test-jump->info 0))
|
||||||
|
@ -1155,7 +1165,10 @@
|
||||||
(jump-text (wrap-as (i386:Xjump (- (+ body-length test-length)))))
|
(jump-text (wrap-as (i386:Xjump (- (+ body-length test-length)))))
|
||||||
(jump-length (length (text->list jump-text)))
|
(jump-length (length (text->list jump-text)))
|
||||||
|
|
||||||
(test-text (.text (test-jump->info jump-length))))
|
(test-text (.text (test-jump->info jump-length)))
|
||||||
|
|
||||||
|
(body-info (body-info body-length (length (text->list test-text)))))
|
||||||
|
|
||||||
(clone info #:text
|
(clone info #:text
|
||||||
(append
|
(append
|
||||||
(.text body-info)
|
(.text body-info)
|
||||||
|
|
|
@ -278,11 +278,9 @@ lookup_symbol_ (SCM s)
|
||||||
{
|
{
|
||||||
SCM x = g_symbols;
|
SCM x = g_symbols;
|
||||||
while (x) {
|
while (x) {
|
||||||
//if (list_of_char_equal_p (STRING (car (x)), s) == cell_t) break;
|
if (list_of_char_equal_p (STRING (car (x)), s) == cell_t) break;
|
||||||
if (list_of_char_equal_p (STRING (car (x)), s) == cell_t) goto dun;
|
|
||||||
x = cdr (x);
|
x = cdr (x);
|
||||||
}
|
}
|
||||||
dun:
|
|
||||||
if (x) x = car (x);
|
if (x) x = car (x);
|
||||||
if (!x) x = make_symbol_ (s);
|
if (!x) x = make_symbol_ (s);
|
||||||
return x;
|
return x;
|
||||||
|
|
|
@ -683,6 +683,15 @@ test (char *p)
|
||||||
return 1;
|
return 1;
|
||||||
ok0:
|
ok0:
|
||||||
|
|
||||||
|
puts ("t: while (1) break;\n");
|
||||||
|
while (1) break;
|
||||||
|
|
||||||
|
puts ("t: while (1) ... break;\n");
|
||||||
|
while (1) {f=0;break;}
|
||||||
|
|
||||||
|
puts ("t: while (1) ... break;\n");
|
||||||
|
while (1) {while (1) break;break;}
|
||||||
|
|
||||||
puts ("t: while (1) { goto label; };\n");
|
puts ("t: while (1) { goto label; };\n");
|
||||||
while (1) {
|
while (1) {
|
||||||
goto ok00;
|
goto ok00;
|
||||||
|
|
Loading…
Reference in a new issue