mescc: Tinycc support: pointer arithmetic with variable.
* module/language/c99/compiler.mes (expr->accu): Support pointer arithmetic with variable: p + i, p - i, p += i, p -= i. * scaffold/tests/76-pointer-arithmetic.c (test): Test it.
This commit is contained in:
parent
1e23dbaf17
commit
0875ce655a
|
@ -799,28 +799,42 @@
|
||||||
((and struct? (= ptr -2)) 4)
|
((and struct? (= ptr -2)) 4)
|
||||||
((and struct? (= ptr 2)) 4)
|
((and struct? (= ptr 2)) 4)
|
||||||
(else 1))))
|
(else 1))))
|
||||||
((binop->accu info) a b (i386:accu+base))))
|
(if (= size 1) ((binop->accu info) a b (i386:accu+base))
|
||||||
|
(let* ((info ((expr->accu info) b))
|
||||||
|
(info (append-text info (wrap-as (i386:value->base size))))
|
||||||
|
(info (append-text info (wrap-as (i386:accu*base))))
|
||||||
|
(info ((expr->base info) a)))
|
||||||
|
(append-text info (wrap-as (i386:accu+base)))))))
|
||||||
|
|
||||||
((sub ,a (p-expr (fixed ,value)))
|
((sub ,a (p-expr (fixed ,value)))
|
||||||
(let* ((ptr (expr->pointer info a))
|
(let* ((ptr (expr->pointer info a))
|
||||||
|
(type0 (p-expr->type info a))
|
||||||
|
(struct? (memq (type:type (ast-type->type info type0)) '(struct union)))
|
||||||
(size (cond ((= ptr 1) (expr->size info a))
|
(size (cond ((= ptr 1) (expr->size info a))
|
||||||
((> ptr 1) 4)
|
((> ptr 1) 4)
|
||||||
|
((and struct? (= ptr -2)) 4)
|
||||||
|
((and struct? (= ptr 2)) 4)
|
||||||
(else 1)))
|
(else 1)))
|
||||||
(info ((expr->accu info) a))
|
(info ((expr->accu info) a))
|
||||||
(value (cstring->number value))
|
(value (cstring->number value))
|
||||||
(value (* size value)))
|
(value (* size value)))
|
||||||
(if (not (= size 1))
|
|
||||||
(warn (format #f "TODO: pointer arithmetic: ~s\n" o)))
|
|
||||||
(append-text info (wrap-as (i386:accu+value (- value))))))
|
(append-text info (wrap-as (i386:accu+value (- value))))))
|
||||||
|
|
||||||
((sub ,a ,b)
|
((sub ,a ,b)
|
||||||
(let* ((ptr (expr->pointer info a))
|
(let* ((ptr (expr->pointer info a))
|
||||||
|
(type0 (p-expr->type info a))
|
||||||
|
(struct? (memq (type:type (ast-type->type info type0)) '(struct union)))
|
||||||
(size (cond ((= ptr 1) (expr->size info a))
|
(size (cond ((= ptr 1) (expr->size info a))
|
||||||
((> ptr 1) 4)
|
((> ptr 1) 4)
|
||||||
|
((and struct? (= ptr -2)) 4)
|
||||||
|
((and struct? (= ptr 2)) 4)
|
||||||
(else 1))))
|
(else 1))))
|
||||||
(if (not (= size 1))
|
(if (= size 1) ((binop->accu info) a b (i386:accu-base))
|
||||||
(warn (format #f "TODO: pointer arithmetic: ~s\n" o))))
|
(let* ((info ((expr->accu info) b))
|
||||||
((binop->accu info) a b (i386:accu-base)))
|
(info (append-text info (wrap-as (i386:value->base size))))
|
||||||
|
(info (append-text info (wrap-as (i386:accu*base))))
|
||||||
|
(info ((expr->base info) a)))
|
||||||
|
(append-text info (wrap-as (i386:accu-base)))))))
|
||||||
|
|
||||||
((bitwise-and ,a ,b) ((binop->accu info) a b (i386:accu-and-base)))
|
((bitwise-and ,a ,b) ((binop->accu info) a b (i386:accu-and-base)))
|
||||||
((bitwise-not ,expr)
|
((bitwise-not ,expr)
|
||||||
|
@ -908,7 +922,18 @@
|
||||||
(let* ((info (append-text info (ast->comment o)))
|
(let* ((info (append-text info (ast->comment o)))
|
||||||
(info ((expr->accu info) b))
|
(info ((expr->accu info) b))
|
||||||
(info (if (equal? op "=") info
|
(info (if (equal? op "=") info
|
||||||
(let* ((info (append-text info (wrap-as (i386:push-accu))))
|
(let* ((ptr (expr->pointer info a))
|
||||||
|
(type0 (p-expr->type info a))
|
||||||
|
(struct? (memq (type:type (ast-type->type info type0)) '(struct union)))
|
||||||
|
(size (cond ((= ptr 1) (expr->size info a))
|
||||||
|
((> ptr 1) 4)
|
||||||
|
((and struct? (= ptr -2)) 4)
|
||||||
|
((and struct? (= ptr 2)) 4)
|
||||||
|
(else 1)))
|
||||||
|
(info (if (= size 1) info
|
||||||
|
(let ((info (append-text info (wrap-as (i386:value->base size)))))
|
||||||
|
(append-text info (wrap-as (i386:accu*base))))))
|
||||||
|
(info (append-text info (wrap-as (i386:push-accu))))
|
||||||
(info ((expr->accu info) a))
|
(info ((expr->accu info) a))
|
||||||
(info (append-text info (wrap-as (i386:pop-base)))))
|
(info (append-text info (wrap-as (i386:pop-base)))))
|
||||||
(append-text info (cond ((equal? op "+=") (wrap-as (i386:accu+base)))
|
(append-text info (cond ((equal? op "+=") (wrap-as (i386:accu+base)))
|
||||||
|
|
|
@ -23,6 +23,12 @@
|
||||||
|
|
||||||
char *list[2] = {"foo\n", "bar\n"};
|
char *list[2] = {"foo\n", "bar\n"};
|
||||||
|
|
||||||
|
struct foo {
|
||||||
|
int a;
|
||||||
|
int b;
|
||||||
|
int c;
|
||||||
|
};
|
||||||
|
|
||||||
int
|
int
|
||||||
test ()
|
test ()
|
||||||
{
|
{
|
||||||
|
@ -49,10 +55,41 @@ test ()
|
||||||
char **p = list;
|
char **p = list;
|
||||||
++*p;
|
++*p;
|
||||||
eputs (*p);
|
eputs (*p);
|
||||||
if (strcmp (*p, "oo\n")) return 1;
|
if (strcmp (*p, "oo\n")) return 13;
|
||||||
--*p;
|
--*p;
|
||||||
eputs (*p);
|
eputs (*p);
|
||||||
if (strcmp (*p, "foo\n")) return 2;
|
if (strcmp (*p, "foo\n")) return 14;
|
||||||
|
|
||||||
|
struct foo* pfoo = 0;
|
||||||
|
eputs ("pfoo="); eputs (itoa (pfoo)); eputs ("\n");
|
||||||
|
pfoo++;
|
||||||
|
eputs ("pfoo="); eputs (itoa (pfoo)); eputs ("\n");
|
||||||
|
if (pfoo != 12) return 15;
|
||||||
|
|
||||||
|
pfoo--;
|
||||||
|
eputs ("pfoo="); eputs (itoa (pfoo)); eputs ("\n");
|
||||||
|
if (pfoo) return 16;
|
||||||
|
|
||||||
|
pfoo++;
|
||||||
|
eputs ("pfoo="); eputs (itoa (pfoo)); eputs ("\n");
|
||||||
|
if (pfoo != 12) return 17;
|
||||||
|
|
||||||
|
int one = 1;
|
||||||
|
pfoo = pfoo - one;
|
||||||
|
eputs ("pfoo="); eputs (itoa (pfoo)); eputs ("\n");
|
||||||
|
if (pfoo) return 18;
|
||||||
|
|
||||||
|
pfoo = pfoo + one;
|
||||||
|
eputs ("pfoo="); eputs (itoa (pfoo)); eputs ("\n");
|
||||||
|
if (pfoo != 12) return 19;
|
||||||
|
|
||||||
|
pfoo -= one;
|
||||||
|
eputs ("pfoo="); eputs (itoa (pfoo)); eputs ("\n");
|
||||||
|
if (pfoo) return 20;
|
||||||
|
|
||||||
|
pfoo += one;
|
||||||
|
eputs ("pfoo="); eputs (itoa (pfoo)); eputs ("\n");
|
||||||
|
if (pfoo != 12) return 21;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue