;; Compile a node in tail position
(module dotnet_tail
   (import type_type ast_var ast_node
	   object_class      ; tclass
	   dotnet_env dotnet_instr dotnet_expr dotnet_compiler )
   (export (generic compile-tail e::node env::env)) )

(define-generic (compile-tail e::node env::env))

(define-method (compile-tail e::atom env::env)
   (compiler-atom e env) )

(define-method (compile-tail e::var env::env)
   (compiler-var e env) )

(define-method (compile-tail e::let-var env::env)
   (compiler-let e env compile-tail) )

(define-method (compile-tail e::setq env::env)
   (compiler-setq e env)
   (_getstatic env (jlib-declare env 'unspecified)) )

(define-method (compile-tail e::sequence env::env)
   (compiler-sequence e env compile-tail) )

(define-method (compile-tail e::conditional env::env)
   (compiler-if e env compile-tail) )

(define-method (compile-tail e::select env::env)
   (compiler-select e env compile-tail) )

(define-method (compile-tail e::let-fun env::env)
   (compiler-labels e env compile-tail) )

(define-method (compile-tail e::app env::env)
   (with-access::app e (fun args)
      (let ( (v (var-variable fun)) )
	 (if (eq? v (env-current-method env))
	     (let ( (params (sfun-args (global-value v))) )
		(for-each (lambda (e) (compile-expr e env)) args)
		(for-each (lambda (p) (_store env p)) (reverse params))
		(env-stack-set!
		 env
		 (cons (simple-type (compile-type (global-type v) env))
		       (env-stack env) ))
		(_goto env 'begin) )
	     (compiler-app e env compile-tail) ))))

(define-method (compile-tail e::app-ly env::env)
   (compiler-apply e env) )

(define-method (compile-tail e::funcall env::env)
   (compiler-funcall e env) )

(define-method (compile-tail e::pragma env::env)
   (compiler-pragma e env) )

(define-method (compile-tail e::getfield env::env)
   (compiler-getfield e env) )

(define-method (compile-tail e::setfield env::env)
   (compiler-setfield e env)
   (_getstatic env (jlib-declare env 'unspecified)) )

(define-method (compile-tail e::new env::env)
   (compiler-new e env) )

(define-method (compile-tail e::valloc env::env)
   (compiler-valloc e env) )

(define-method (compile-tail e::vref env::env)
   (compiler-vref e env) )

(define-method (compile-tail e::vset! env::env)
   (compiler-vset e env)
   (_getstatic env (jlib-declare env 'unspecified)) )

(define-method (compile-tail e::vlength env::env)
   (compiler-vlength e env) )

(define-method (compile-tail e::isa env::env)
   (compiler-isa e env) )

(define-method (compile-tail e::cast env::env)
   (compiler-cast e env compile-tail) )

(define-method (compile-tail e::set-ex-it env::env)
   (compiler-setexit e env compile-expr) )

(define-method (compile-tail e::jump-ex-it env::env)
   (compiler-jump-exit e env) )

(define-method (compile-tail e::fail env::env)
   (compiler-fail e env) )

(define-method (compile-tail e::make-box env::env)
   (compiler-make-box e env) )

(define-method (compile-tail e::box-ref env::env)
   (compiler-box-ref e env) )

(define-method (compile-tail e::box-set! env::env)
   (compiler-box-set! e env)
   (_getstatic env (jlib-declare env 'unspecified)) )
