(module jvm_prelude
   (import type_type ast_var ast_node jvm_lisp)
   (export (compile-prelude e::node)) )

(define (compile-prelude e::node)
   (prelude e) )

(define-generic (prelude e::node)
   (prelude e) )

(define-method (prelude e::atom)
   'ok )

(define-method (prelude e::var)
   (let ( (var (var-variable e)) )
      ;; CARE e.type != var.type (var.type seems good)
      '(node-type-set! e (variable-type var)) ))

(define-method (prelude e::let-var)
   (with-access::let-var e (bindings body)
      (for-each (lambda (b) (prelude (cdr b))) bindings)
      (prelude body) ))

(define-method (prelude e::setq)
   (with-access::setq e (value)
      (prelude value) ))

(define-method (prelude e::sequence)
   (with-access::sequence e (nodes)
      (define (walk l)
	 (if (null? l)
	     'ok
	     (begin
		(if (null? (cdr l))
		    ;; CARE e.type != (car l).type (later seems good)
		    '(node-type-set! e (node-type (car l))) )
		(prelude (car l))
		(walk (cdr l)) )))
      (walk nodes) ))

(define-method (prelude e::conditional)
   (with-access::conditional e (test true false)
      (prelude test)
      (prelude true)
      (prelude false) ))

(define-method (prelude e::select)
   (with-access::select e (test clauses)
      (prelude test)
      (for-each (lambda (c) (prelude (cdr c))) clauses) ))

(define-method (prelude e::let-fun)
   (with-access::let-fun e (locals body)
      (for-each (lambda (v) 
		   (with-access::local v (value)
		      (with-access::sfun value (body)
			 (prelude body) )))
		locals )
      (prelude body) ))

(define-method (prelude e::app)
   (with-access::app e (fun args)
      (let ( (v (var-variable fun)) )
	 ;; CARE e.type != v.type (v.type seems good)
	 '(node-type-set! e (variable-type v))
	 (for-each (lambda (e) (prelude e)) args) )))

(define-method (prelude e::app-ly)
   (with-access::app-ly e (fun arg)
      (prelude fun)
      (prelude arg) ))
	  
(define-method (prelude e::funcall)
   (with-access::funcall e (fun args)
      (prelude fun)
      (for-each (lambda (e) (prelude e)) args) ))

(define-method (prelude e::extern)
   (with-access::extern e (expr*)
      (for-each (lambda (e) (prelude e)) expr*) ))

(define-method (prelude e::cast)
   (with-access::cast e (arg)
      (prelude arg) ))

(define-method (prelude e::set-ex-it)
   (with-access::set-ex-it e (var body)
      (prelude body) ))

(define-method (prelude e::jump-ex-it)
   (with-access::jump-ex-it e (exit value)
      (prelude exit)
      (prelude value) ))

(define-method (prelude e::fail)
   (with-access::fail e (proc msg obj)
      (prelude proc)
      (prelude msg)
      (prelude obj) ))

(define-method (prelude e::make-box)
   (with-access::make-box e (value)
      (prelude value) ))

(define-method (prelude e::box-ref)
   'ok )

(define-method (prelude e::box-set!)
   (with-access::box-set! e (var value)
      (prelude value) ))

      
