mescc: Refactor assignment.

* module/language/c99/compiler.mes (expr->accu): Refactor assignment.
  Support multiple operators.
* scaffold/t.c (math_test): Test it.
* scaffold/mini-mes.c (minus, divide, modulo, multiply,
  logior)[!__GNUC__]: Remove branch.
This commit is contained in:
Jan Nieuwenhuizen 2017-04-08 06:31:12 +02:00
parent da931b4faa
commit 2deca502ed
3 changed files with 63 additions and 113 deletions

View file

@ -566,88 +566,49 @@
((cast ,cast ,o) ((cast ,cast ,o)
((expr->accu info) o)) ((expr->accu info) o))
;; *p++ = b; ((assn-expr ,a (op ,op) ,b)
((assn-expr (de-ref (post-inc (p-expr (ident ,name)))) (op ,op) ,b) (let* ((info ((expr->accu info) b))
(when (not (equal? op "=")) (info (if (equal? op "=") info
(stderr "OOOPS0.0: op=~s\n" op) (let* ((info (append-text info (wrap-as (i386:push-accu))))
barf) (info ((expr->accu info) a))
(let ((info ((expr->base info) b))) (info (append-text info (wrap-as (i386:pop-base)))))
(append-text info (append ((base->ident-address info) name) (append-text info (cond ((equal? op "+=") (wrap-as (i386:accu+base)))
((ident->accu info) name) ((equal? op "-=") (wrap-as (i386:accu-base)))
((ident-add info) name 1))))) ((equal? op "*=") (wrap-as (i386:accu*base)))
((equal? op "/=") (wrap-as (i386:accu/base)))
;; *p-- = b; ((equal? op "%=") (wrap-as (i386:accu%base)))
((assn-expr (de-ref (post-dec (p-expr (ident ,name)))) (op ,op) ,b) ((equal? op "|=") (wrap-as (i386:accu-or-base)))
(when (not (equal? op "=")) (else (error "mescc: op ~a not supported: ~a\n" op o))))))))
(stderr "OOOPS0.0: op=~s\n" op) (pmatch a
barf) ((p-expr (ident ,name)) (append-text info ((accu->ident info) name)))
(let ((info ((expr->base info) b))) ((d-sel (ident ,field) . ,d-sel)
(append-text info (append ((base->ident-address info) name) (let* ((type (list "struct" "scm")) ;; FIXME
((ident->accu info) name)
((ident-add info) name -1)))))
;; CAR (x) = 0
;; TYPE (x) = PAIR;
((assn-expr (d-sel (ident ,field) . ,d-sel) (op ,op) ,b)
(when (not (equal? op "="))
(stderr "OOOPS0: op=~s\n" op)
barf)
(let* (;;(empty (clone info #:text '()))
;;(expr ((expr->accu* empty) `(d-sel (ident ,field) ,@d-sel))) ;; <-OFFSET
(info ((expr->accu info) b))
(info (append-text info (wrap-as (i386:push-accu))))
(info ((expr->accu* info) `(d-sel (ident ,field) ,@d-sel))) ;; <-OFFSET
(info (append-text info (wrap-as (i386:pop-base))))
(type (list "struct" "scm")) ;; FIXME
(fields (type->description info type)) (fields (type->description info type))
(size (type->size info type)) (size (type->size info type))
(field-size 4) ;; FIXME:4, not fixed (field-size 4) ;; FIXME:4, not fixed
(offset (* field-size (1- (length (member field (reverse fields) (lambda (a b) (equal? a (cdr b)))))))) ) (offset (* field-size (1- (length (member field (reverse fields) (lambda (a b) (equal? a (cdr b))))))))
(info (append-text info (wrap-as (i386:push-accu))))
(info ((expr->accu* info) a))
(info (append-text info (wrap-as (i386:pop-base)))))
(append-text info (wrap-as (i386:base->accu-address))))) ; FIXME: size (append-text info (wrap-as (i386:base->accu-address))))) ; FIXME: size
((de-ref (p-expr (ident ,array)))
(append-text info (append (wrap-as (i386:accu->base))
;; i = 0;
;; c = f ();
;; i = i + 48;
;; p = g_cell;
((assn-expr (p-expr (ident ,name)) (op ,op) ,b)
(when (and (not (equal? op "="))
(not (equal? op "+="))
(not (equal? op "-=")))
(stderr "OOOPS1: op=~s\n" op)
barf)
(let ((info ((expr->base info) b)))
(append-text info (append (if (equal? op "=") '()
(append ((ident->accu info) name)
(wrap-as (append (if (equal? op "+=") (i386:accu+base)
(i386:accu-base))
(i386:accu->base)))))
;;assign:
((base->ident info) name)
(wrap-as (i386:base->accu))))))
;; *p = 0;
((assn-expr (de-ref (p-expr (ident ,array))) (op ,op) ,b)
(when (not (equal? op "="))
(stderr "OOOPS2: op=~s\n" op)
barf)
(let ((info ((expr->base info) b)))
(append-text info (append ;;assign:
((base->ident-address info) array) ((base->ident-address info) array)
(wrap-as (i386:base->accu)))))) (wrap-as (i386:base->accu)))))
((de-ref (post-inc (p-expr (ident ,name))))
;; g_cells[<expr>] = <expr>; (let ((info ((expr->accu info) `(assn-expr (de-ref (p-expr (ident ,name))) (op ,op) ,b))))
((assn-expr (array-ref ,index (p-expr (ident ,array))) (op ,op) ,b) (append-text info ((ident-add info) name 1))))
(when (not (equal? op "=")) ((de-ref (post-dec (p-expr (ident ,name))))
(stderr "OOOPS3: op=~s\n" op) (let ((info ((expr->accu info) `(assn-expr (de-ref (p-expr (ident ,name))) (op ,op) ,b))))
barf) (append-text info ((ident-add info) name -1))))
(let* ((info ((expr->accu* info) `(array-ref ,index (p-expr (ident ,array))))) ((array-ref ,index (p-expr (ident ,array)))
(info ((expr->base info) b)) (let* ((type (ident->type info array))
(type (ident->type info array))
(size (type->size info type)) (size (type->size info type))
(ptr (ident->pointer info array))) (info (append-text info (wrap-as (append (i386:push-accu)))))
(append-text info (append (info ((expr->accu* info) a))
(if (eq? size 1) (wrap-as (i386:byte-base->accu-address)) (info (append-text info (wrap-as (append (i386:pop-base))))))
(append-text info
(append (if (eq? size 1) (wrap-as (i386:byte-base->accu-address))
(append (append
(wrap-as (i386:base-address->accu-address)) (wrap-as (i386:base-address->accu-address))
(if (<= size 4) '() (if (<= size 4) '()
@ -658,6 +619,7 @@
(wrap-as (append (i386:accu+n 4) (wrap-as (append (i386:accu+n 4)
(i386:base+n 4) (i386:base+n 4)
(i386:base-address->accu-address)))))))))) (i386:base-address->accu-address))))))))))
(_ barf-assign))))
(_ (_
(format (current-error-port) "SKIP: expr->accu=~s\n" o) (format (current-error-port) "SKIP: expr->accu=~s\n" o)

View file

@ -1194,11 +1194,7 @@ minus (SCM x) ///((name . "-") (arity . n))
while (x != cell_nil) while (x != cell_nil)
{ {
assert (TYPE (car (x)) == TNUMBER); assert (TYPE (car (x)) == TNUMBER);
#if __GNUC__
n -= VALUE (car (x)); n -= VALUE (car (x));
#else
n = n - VALUE (car (x));
#endif
x = cdr (x); x = cdr (x);
} }
return MAKE_NUMBER (n); return MAKE_NUMBER (n);
@ -1211,11 +1207,7 @@ plus (SCM x) ///((name . "+") (arity . n))
while (x != cell_nil) while (x != cell_nil)
{ {
assert (TYPE (car (x)) == TNUMBER); assert (TYPE (car (x)) == TNUMBER);
#if __GNUC__
n += VALUE (car (x)); n += VALUE (car (x));
#else
n = n + VALUE (car (x));
#endif
x = cdr (x); x = cdr (x);
} }
return MAKE_NUMBER (n); return MAKE_NUMBER (n);
@ -1233,11 +1225,7 @@ divide (SCM x) ///((name . "/") (arity . n))
while (x != cell_nil) while (x != cell_nil)
{ {
assert (TYPE (car (x)) == TNUMBER); assert (TYPE (car (x)) == TNUMBER);
#if __GNUC__
n /= VALUE (car (x)); n /= VALUE (car (x));
#else
n = n / VALUE (car (x));
#endif
x = cdr (x); x = cdr (x);
} }
return MAKE_NUMBER (n); return MAKE_NUMBER (n);
@ -1260,11 +1248,7 @@ multiply (SCM x) ///((name . "*") (arity . n))
while (x != cell_nil) while (x != cell_nil)
{ {
assert (TYPE (car (x)) == TNUMBER); assert (TYPE (car (x)) == TNUMBER);
#if __GNUC__
n *= VALUE (car (x)); n *= VALUE (car (x));
#else
n = n * VALUE (car (x));
#endif
x = cdr (x); x = cdr (x);
} }
return MAKE_NUMBER (n); return MAKE_NUMBER (n);
@ -1277,11 +1261,7 @@ logior (SCM x) ///((arity . n))
while (x != cell_nil) while (x != cell_nil)
{ {
assert (TYPE (car (x)) == TNUMBER); assert (TYPE (car (x)) == TNUMBER);
#if __GNUC__
n |= VALUE (car (x)); n |= VALUE (car (x));
#else
n = n | VALUE (car (x));
#endif
x = cdr (x); x = cdr (x);
} }
return MAKE_NUMBER (n); return MAKE_NUMBER (n);

View file

@ -223,10 +223,18 @@ math_test ()
putchar (i); putchar (i);
puts ("\n"); puts ("\n");
puts ("t: 3*4="); puts ("t: 3*4=\n");
i = 3 * 4; i = 3 * 4;
if (i!=12) return 1; if (i!=12) return 1;
puts ("t: i /= 4\n");
i /= 4;
if (i!=3) return 1;
puts ("t: i *= 4\n");
i *= 4;
if (i!=12) return 1;
puts ("t: 1 << 3\n"); puts ("t: 1 << 3\n");
if (1 << 3 != 8) return 1 << 3; if (1 << 3 != 8) return 1 << 3;