mescc: Support any expression as arg.

* module/language/c99/compiler.mes (expr->arg): Also push parameter,
  always return info.
  (ast->info): Loop over args.  Fixes using function calls in arguments.
* module/mes/libc-i386.mes (i386:push-arg): Remove.
  (i386:call, i386:call-accu): Remove arguments parameter.
* doc/examples/t.c: Test it.
This commit is contained in:
Jan Nieuwenhuizen 2017-02-27 07:50:33 +01:00
parent 394a3925be
commit c9b251616a
5 changed files with 204 additions and 159 deletions

View file

@ -176,18 +176,33 @@
(text text))
(make <info> #:types types #:constants constants #:functions functions #:globals globals #:init init #:locals locals #:function function #:text text))))))
(define (push-global-address globals)
(lambda (o)
(lambda (f g ta t d)
(i386:push-global-address (+ (data-offset o g) d)))))
(define (push-global globals)
(lambda (o)
(lambda (f g ta t d)
(i386:push-global (+ (data-offset o g) d)))))
(define (push-local locals)
(lambda (o)
(lambda (f g ta t d)
(i386:push-local (local:id o)))))
(define (push-global-address globals)
(lambda (o)
(lambda (f g ta t d)
(i386:push-global-address (+ (data-offset o g) d)))))
(define (push-local-address locals)
(lambda (o)
(lambda (f g ta t d)
(i386:push-local-address (local:id o)))))
(define push-global-de-ref push-global)
(define (push-local-de-ref locals)
(lambda (o)
(lambda (f g ta t d)
(i386:push-local-de-ref (local:id o)))))
(define (string->global string)
(make-global string "string" 0 (append (string->list string) (list #\nul))))
@ -203,97 +218,118 @@
(define (push-ident info)
(lambda (o)
(let ((local (assoc-ref (.locals info) o)))
(if local (i386:push-local (local:id local))
(if local ((push-local (.locals info)) local)
((push-global (.globals info)) o))))) ;; FIXME: char*/int
(define (push-ident-address info)
(lambda (o)
(let ((local (assoc-ref (.locals info) o)))
(if local (i386:push-local-address (local:id local))
(if local ((push-local-address (.locals info)) local)
((push-global-address (.globals info)) o)))))
(define (push-ident-de-ref info)
(lambda (o)
(let ((local (assoc-ref (.locals info) o)))
(if local (i386:push-local-de-ref (local:id local))
(if local ((push-local-de-ref (.locals info)) local)
((push-global-de-ref (.globals info)) o)))))
(define (expr->arg info) ;; FIXME: get Mes curried-definitions
(lambda (o)
(pmatch o
((p-expr (fixed ,value)) (cstring->number value))
((neg (p-expr (fixed ,value))) (- (cstring->number value)))
((p-expr (string ,string)) ((push-global-address info) string))
((p-expr (ident ,name))
((push-ident info) name))
(let ((text (.text info)))
(pmatch o
((p-expr (fixed ,value))
(let ((value (cstring->number value)))
(clone info #:text (append text
(list
(lambda (f g ta t d)
(append
(i386:value->accu value)
(i386:push-accu))))))))
;; g_cells[0]
((array-ref (p-expr (fixed ,index)) (p-expr (ident ,array)))
(let ((index (cstring->number index))
(size 4)) ;; FIXME: type: int
(append
((ident->base info) array)
(list
(lambda (f g ta t d)
(append
(i386:value->accu (* size index)) ;; FIXME: type: int
(i386:base-mem->accu) ;; FIXME: type: int
(i386:push-accu) ;; hmm
))))))
((neg (p-expr (fixed ,value)))
(let ((value (- (cstring->number value))))
(clone info #:text (append text
(list
(lambda (f g ta t d)
(append
(i386:value->accu value)
(i386:push-accu))))))))
;; g_cells[i]
((array-ref (p-expr (ident ,index)) (p-expr (ident ,array)))
(let ((index (cstring->number index))
(size 4)) ;; FIXME: type: int
(append
((ident->base info) array)
((ident->accu info) array)
(list (lambda (f g ta t d)
;;(i386:byte-base-mem->accu)
(i386:base-mem->accu)
))
(list
(lambda (f g ta t d)
(append
(i386:push-accu)))))))
((p-expr (string ,string))
(clone info #:text (append text (list ((push-global-address info) string)))))
((de-ref (p-expr (ident ,name)))
(lambda (f g ta t d)
((push-ident-de-ref info) name)))
((p-expr (ident ,name))
(clone info #:text (append text (list ((push-ident info) name)))))
((ref-to (p-expr (ident ,name)))
(lambda (f g ta t d)
((push-ident-address info) name)))
;; g_cells[0]
((array-ref (p-expr (fixed ,index)) (p-expr (ident ,array)))
(let ((index (cstring->number index))
(size 4)) ;; FIXME: type: int
(clone info
#:text (append text
((ident->base info) array)
(list
(lambda (f g ta t d)
(append
(i386:value->accu (* size index)) ;; FIXME: type: int
(i386:base-mem->accu) ;; FIXME: type: int
(i386:push-accu))))))))
;; f (car (x))
((fctn-call . ,call)
(let* ((empty (clone info #:text '()))
(info ((ast->info empty) o)))
(append (.text info)
(list
(lambda (f g ta t d)
(i386:push-accu))))))
;; g_cells[i]
((array-ref (p-expr (ident ,index)) (p-expr (ident ,array)))
(let ((index (cstring->number index))
(size 4)) ;; FIXME: type: int
(clone info #:text (append text
((ident->base info) array)
((ident->accu info) array)
(list
(lambda (f g ta t d)
(i386:base-mem->accu)))
(list
(lambda (f g ta t d)
(i386:push-accu)))))))
;; f (CAR (x))
((d-sel . ,d-sel)
(let* ((empty (clone info #:text '()))
(expr ((expr->accu empty) `(d-sel ,@d-sel))))
(append (.text expr)
(list (lambda (f g ta t d)
(i386:push-accu))))))
((de-ref (p-expr (ident ,name)))
(clone info #:text (append text (list ((push-ident-de-ref info) name)))))
;; f (0 + x)
;;; aargh
;;;((add (p-expr (fixed ,value)) (d-sel (ident cdr) (array-ref (p-expr (ident x)) (p-expr (ident g_cells))))))
((ref-to (p-expr (ident ,name)))
(clone info #:text (append text (list ((push-ident-address info) name)))))
((cast (type-name (decl-spec-list (type-spec (fixed-type _)))
(abs-declr (pointer)))
,cast)
((expr->arg info) cast))
(_
(format (current-error-port) "SKIP: expr->arg=~s\n" o)
barf
0))))
;; f (car (x))
((fctn-call . ,call)
(let* (;;(empty (clone info #:text '()))
;;(info ((ast->info empty) o))
(info ((ast->info info) o))
(text (.text info)))
(clone info
#:text (append text
(list
(lambda (f g ta t d)
(i386:push-accu)))))))
;; f (CAR (x))
((d-sel . ,d-sel)
(let* (;;(empty (clone info #:text '()))
;;(expr ((expr->accu empty) `(d-sel ,@d-sel)))
(expr ((expr->accu info) `(d-sel ,@d-sel)))
(text (.text expr)))
(clone info
#:text (append text
(list (lambda (f g ta t d)
(i386:push-accu)))))))
;; f (0 + x)
;;; aargh
;;;((add (p-expr (fixed ,value)) (d-sel (ident cdr) (array-ref (p-expr (ident x)) (p-expr (ident g_cells))))))
((cast (type-name (decl-spec-list (type-spec (fixed-type _)))
(abs-declr (pointer)))
,cast)
((expr->arg info) cast))
(_
(format (current-error-port) "SKIP: expr->arg=~s\n" o)
barf
0)))))
;; FIXME: see ident->base
(define (ident->accu info)
@ -1019,47 +1055,46 @@
(clone info #:text (append text (list (lambda (f g ta t d) (asm->hex arg0))))))
(let* ((globals (append globals (filter-map expr->global expr-list)))
(info (clone info #:globals globals))
(args (map (expr->arg info) expr-list)))
(text-length (length text))
(args-info (let loop ((expressions (reverse expr-list)) (info info))
(if (null? expressions) info
(loop (cdr expressions) ((expr->arg info) (car expressions))))))
(text (.text args-info))
(n (length expr-list)))
(if ;;#t ;;(assoc-ref globals name)
(not (equal? name "functionx"))
(clone info #:text
(clone args-info #:text
(append text
(list (lambda (f g ta t d)
(apply i386:call (cons* f g ta t d
(+ t (function-offset name f)) args)))))
(i386:call f g ta t d (+ t (function-offset name f)) n))))
#:globals globals)
(let* ((empty (clone info #:text '()))
;;(accu ((ident->accu info) name))
(accu ((expr->accu empty) `(p-expr (ident ,name)))))
(stderr "DINGES: ~a\n" o)
(clone info #:text
(clone args-info #:text
(append text
(list (lambda (f g ta t d)
'(#x90)))
;;accu
(.text accu)
(list (lambda (f g ta t d)
'(#x90)))
(list (lambda (f g ta t d)
(apply i386:call-accu (cons* f g ta t d args)))))
(i386:call-accu f g ta t d n))))
#:globals globals))))))
;;((expr-stmt (fctn-call (d-sel (ident "function") (array-ref (d-sel (ident "cdr") (array-ref (p-expr (ident "fn")) (p-expr (ident "g_cells")))) (p-expr (ident "g_functions")))) (expr-list))))
((expr-stmt (fctn-call ,function (expr-list . ,expr-list)))
(let* ((globals (append globals (filter-map expr->global expr-list)))
(info (clone info #:globals globals))
(args (map (expr->arg info) expr-list))
(empty (clone info #:text '()))
(accu ((expr->accu empty) function)))
(info (clone info #:globals globals))
(text-length (length text))
(args-info (let loop ((expressions (reverse expr-list)) (info info))
(if (null? expressions) info
(loop (cdr expressions) ((expr->arg info) (car expressions))))))
(text (.text args-info))
(n (length expr-list))
(empty (clone info #:text '()))
(accu ((expr->accu empty) function)))
(clone info #:text
(append text
(list (lambda (f g ta t d)
'(#x90)))
(.text accu)
(list (lambda (f g ta t d)
'(#x90)))
(list (lambda (f g ta t d)
(apply i386:call-accu (cons* f g ta t d args)))))
(i386:call-accu f g ta t d n))))
#:globals globals)))
((if ,test ,body)
@ -1716,11 +1751,7 @@
(offset (* field-size (1- (length (member field (reverse fields) (lambda (a b) (equal? a (cdr b)))))))) )
(clone info #:text (append text
(.text expr)
(list (lambda (f g ta t d)
'(#x90)))
(.text base)
(list (lambda (f g ta t d)
'(#x90)))
(list (lambda (f g ta t d)
;;(i386:byte-base->accu-ref) ;; FIXME: size
(i386:base->accu-address)

View file

@ -68,17 +68,6 @@
(define (i386:push-base)
'(#x52)) ; push %eax
(define (i386:push-arg f g ta t d)
(lambda (o)
(or o push-arg)
(cond ((number? o)
`(#x68 ,@(int->bv32 o))) ; push $<o>
((and (pair? o) (procedure? (car o)))
(append-map (lambda (p) (p f g ta t d)) o))
((pair? o) o)
((procedure? o) (o f g ta t d))
(_ barf))))
(define (i386:ret . rest)
(lambda (f g ta t d)
`(
@ -280,36 +269,17 @@
(or n local-test)
`(#x83 #x7d ,(- 0 (* 4 n)) ,v)) ; cmpl $<v>,0x<n>(%ebp)
(define (i386:call f g ta t d address . arguments)
(define (i386:call f g ta t d address n)
(or address urg:call)
(let* ((pushes (append-map (i386:push-arg f g ta t d) (reverse arguments)))
(s (length pushes))
(n (length arguments)))
`(
,@pushes ; push args
#xe8 ,@(int->bv32 (- address 5 s)) ; call relative
#x83 #xc4 ,(* n 4) ; add $00,%esp
)))
`(#xe8 ,@(int->bv32 (- address 5)) ; call relative $00
#x83 #xc4 ,(* n 4))) ; add $00,%esp
(define (i386:call-accu f g ta t d n)
`(,@(i386:push-accu)
,@(i386:pop-accu)
#xff #xd0 ; call *%eax
#x83 #xc4 ,(* n 4))) ; add $00,%esp
(define (i386:call-accu f g ta t d . arguments)
;;(or address urg:call)
(let* ((pushes (append-map (i386:push-arg f g ta t d) (reverse arguments)))
(s (length pushes))
(n (length arguments)))
`(
,@(i386:push-accu)
,@pushes ; push args
;;#xe8 ,@(int->bv32 (- address 5 s)) ; call relative
;; FIXME: add t?/address
;; #x50 ; push %eax
;; #xc3 ; ret
,@(i386:pop-accu)
;; #x05 ,@(int->bv32 t) ; add <t>,%eax
;; #x05 ,@(int->bv32 ta) ; add <ta>,%eax
#xff #xd0 ; call *%eax
#x83 #xc4 ,(* n 4) ; add $00,%esp
)))
(define (i386:accu-not)
`(#x0f #x94 #xc0 ; sete %al
#x0f #xb6 #xc0)) ; movzbl %al,%eax

View file

@ -117,13 +117,16 @@
i386:xor-accu
i386:xor-zf
;; long jump
i386:Xjump
i386:Xjump
i386:XXjump
i386:Xjump-c
i386:Xjump-nc
i386:Xjump-nz
i386:Xjump-z
i386:XXjump
;; libc
i386:exit
i386:open

View file

@ -609,10 +609,21 @@ push_cc (SCM p1, SCM p2, SCM a, SCM c) ///((internal))
}
#endif
#if __GNUC__
SCM caar (SCM x) {return car (car (x));}
SCM cadr (SCM x) {return car (cdr (x));}
SCM cdar (SCM x) {return cdr (car (x));}
SCM cddr (SCM x) {return cdr (cdr (x));}
#else
SCM cadr (SCM x) {
x = cdr (x);
return car (x);
}
SCM cddr (SCM x) {
x = cdr (x);
return cdr (x);
}
#endif
#if __GNUC__
//FIXME
@ -625,6 +636,10 @@ eval_apply ()
{
puts ("e/a: fixme\n");
eval_apply:
asm (".byte 0x90");
asm (".byte 0x90");
asm (".byte 0x90");
asm (".byte 0x90");
puts ("eval_apply\n");
// if (g_free + GC_SAFETY > ARENA_SIZE)
// gc_pop_frame (gc (gc_push_frame ()));
@ -987,11 +1002,6 @@ eval_apply ()
gc_pop_frame ();
puts ("vm-return01\n");
r1 = x;
//FIXME:
r3 = cell_unspecified;
/// fIXME: must via eval-apply
return r1;
goto eval_apply;
}
@ -1069,9 +1079,24 @@ gc_peek_frame ()
{
SCM frame = car (g_stack);
r1 = car (frame);
#if __GNUC__
r2 = cadr (frame);
r3 = car (cddr (frame));
r0 = cadr (cddr (frame));
#else
r2 = cdr (frame);
r2 = car (r2);
r3 = cdr (frame);
r3 = cdr (r3);
r3 = car (r3);
r0 = cdr (frame);
r0 = cdr (r0);
r0 = cdr (r0);
r0 = cdr (r0);
r0 = car (r0);
#endif
return frame;
}

View file

@ -124,6 +124,19 @@ SCM tmp;
SCM tmp_num;
#if 1
int
add (int a, int b)
{
return a + b;
}
int
inc (int i)
{
return i + 1;
}
int
label (int c)
{
@ -444,6 +457,24 @@ test (char *p)
*x++ = c;
if (*g_chars != 'C') return 1;
puts ("t: inc (0)\n");
if (inc (0) != 1) return 1;
puts ("t: inc (inc (0))\n");
if (inc (inc (0)) != 2) return 1;
puts ("t: inc (inc (inc (0)))\n");
if (inc (inc (inc (0))) != 3) return 1;
puts ("t: add (1, 2)\n");
if (add (1, 2) != 3) return 1;
puts ("t: add (inc (0), inc (1))\n");
if (add (inc (0), inc (1)) != 3) return 1;
puts ("t: add (inc (inc (0)), inc (inc (1)))\n");
if (add (inc (inc (0)), inc (inc (1))) != 5) return 1;
puts ("t: goto label\n");
if (label (1) != 0) return 1;
@ -576,21 +607,6 @@ test (char *p)
int
main (int argc, char *argv[])
{
// main:
// puts ("t.c\n");
// if (argc == 0x22) return 11;
// argc = 0x22;
// goto main;
// switch (0)
// {
// case 0: {goto next;}
// // case 1: {goto next;}
// // case 2: {goto next;}
// // default: {goto next;}
// }
// return 1;
// next:
char *p = "t.c\n";
puts ("t.c\n");