;; Zodiac compatibility layer,
;;  for programs that used to manipulate the
;;  output of zodiac elaboration.

(module zodiac-unit mzscheme
  (require (lib "unitsig.ss")
	   (lib "list.ss"))
  (require "kerncase.ss")

  (require "zodiac-sig.ss"
	   "stx.ss")

  (provide zodiac@)

  (define zodiac@
    (unit/sig zodiac^
      (import)
      
      (define (stx-bound-assq ssym l)
	(ormap (lambda (p)
		 (and (bound-identifier=? ssym (car p))
		      p))
	       l))

      (define global-prepare-id (gensym))
      (define global-lookup-id (gensym))
      (define global-assign-id (gensym))
      (define safe-vector-ref-id (gensym))

      ;; Back boxes ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

      (define-struct secure-box (value))

      (define init-value-list '())

      (define register-initial-value
	(lambda (index value-thunk)
	  (set! init-value-list
		(append init-value-list
			(list value-thunk)))))

      (define make-initial-value-vector
	(lambda ()
	  (let ((v (make-vector current-vector-size uninitialized-flag)))
	    (let loop ((index 0) (inits init-value-list))
	      (unless (null? inits)
		(vector-set! v index ((car inits)))
		(loop (add1 index) (cdr inits))))
	    v)))

      (define make-empty-back-box
	(lambda ()
	  (make-secure-box (make-initial-value-vector))))

      (define current-vector-size 2)
      
      (define next-client-count
	(let ((count -1))
	  (lambda ()
	    (set! count (add1 count))
	    (when (>= count current-vector-size)
	      (set! current-vector-size (* 2 current-vector-size)))
	    count)))

      (define-struct uninitialized-back ())
      (define uninitialized-flag (make-uninitialized-back))
      
      (define getters-setters
	(lambda (index)
	  (values
	   (lambda (back)		; getter
	     (let ((v (secure-box-value back)))
	       (with-handlers
		   ((exn:fail:contract?
		     (lambda (exception)
		       (vector-ref (extend-back-vector back) index))))
		 (let ((value (vector-ref v index)))
		   (if (uninitialized-back? value)
		       (let ((correct-value
			      ((list-ref init-value-list index))))
			 (vector-set! v index correct-value)
			 correct-value)
		       value)))))
	   (lambda (back value)		; setter
	     (let ((v (secure-box-value back)))
	       (with-handlers
		   ((exn:fail:contract?
		     (lambda (exception)
		       (vector-set! (extend-back-vector back) index value))))
		 (vector-set! v index value)))))))
  
      (define register-client
	(lambda (client-name default-initial-value-thunk)
	  (let ((index (next-client-count)))
	    (register-initial-value index default-initial-value-thunk)
	    (getters-setters index))))
      
      (define extend-back-vector
	(lambda (back-box)
	  (let ((v (secure-box-value back-box)))
	    (let ((new-v (make-initial-value-vector)))
	      (let loop ((n (sub1 (vector-length v))))
		(when (>= n 0)
		  (vector-set! new-v n (vector-ref v n))
		  (loop (sub1 n))))
	      (set-secure-box-value! back-box new-v)
	      new-v))))
      
      ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

      (define (mk-back) (make-empty-back-box))

      (define (get-slot stx table)
	(let ([l (hash-table-get table (syntax-e stx) (lambda () null))])
	  (let ([s (ormap (lambda (b)
			    (and (module-identifier=? stx (car b))
				 (cdr b)))
			  l)])
	    (if s
		s
		(let ([s (box #f)])
		  (hash-table-put! table (syntax-e stx) (cons (cons stx s) l))
		  s)))))

      (define (let-s->z mk-let rec? stx env loop)
	(syntax-case stx ()
	  [(_ ([vars rhs] ...) . body)
	   (let* ([varses (syntax->list (syntax (vars ...)))]
		  [rhses (syntax->list (syntax (rhs ...)))]
		  [z:varses (map (lambda (vars)
				   (map (lambda (var)
					  (make-binding
					   stx
					   (mk-back)
					   (gensym (syntax-e var))
					   (syntax-e var)))
					(syntax->list vars)))
				 varses)]
		  [body-env (append
			     (apply
			      append
			      (map (lambda (z:vars vars)
				     (map (lambda (z:var var)
					    (cons
					     var
					     z:var))
					  z:vars
					  (syntax->list vars)))
				   z:varses
				   varses))
			     env)])
	     (mk-let
	      stx
	      (mk-back)
	      z:varses
	      (map (lambda (rhs)
		     (loop rhs (if rec? body-env env)))
		   rhses)
	      (loop (syntax (begin . body)) body-env)))]))
      
      (define (args-s->z env args)
	(let-values ([(maker ids)
		      (syntax-case args ()
			[id
			 (identifier? (syntax id))
			 (values make-sym-arglist
				 (list (syntax id)))]
			[(id ...)
			 (values make-list-arglist (syntax->list args))]
			[_else (values make-ilist-arglist
				       (let loop ([args args])
					 (syntax-case args ()
					   [id (identifier? args) (list args)]
					   [(id . rest)
					    (cons (syntax id) (loop (syntax rest)))])))])])
	  (let ([bindings
		 (map (lambda (id)
			(make-binding
			 id
			 (mk-back)
			 (gensym (syntax-e id))
			 (syntax-e id)))
		      ids)])
	    (values
	     (append (map cons ids bindings) env)
	     (maker bindings)))))

      (define (syntax->zodiac stx)
	(define slot-table (make-hash-table))
	(define trans-slot-table (make-hash-table))
	(define syntax-slot-table (make-hash-table))

	(if (eof-object? stx)
	    stx
	    (let loop ([stx stx][env null][trans? #f])
	      (kernel-syntax-case stx trans?
		[id
		 (identifier? stx)
		 (let ([a (stx-bound-assq stx env)])
		   (if a
		       ;; Lexical reference:
		       (make-bound-varref
			stx
			(mk-back)
			(binding-var (cdr a))
			(cdr a))
		       ;; Top-level (or module) reference:
		       (let ([b (let ([b ((if trans?
					      identifier-transformer-binding
					      identifier-binding)
					  stx)])
				  ;; If b, is it imported?
				  (and (pair? b)
				       (let ([modname (and (pair? b) (car b))])
					 (and (or (symbol? modname)
						  (and (module-path-index? modname)
						       (let-values ([(name base) (module-path-index-split modname)])
							 (or name base))))
					      b))))])
			 (make-top-level-varref
			  stx
			  (mk-back)
			  (if b
			      (cadr b)
			      (syntax-e stx))
			  (let ([modname (and b (car b))])
			    modname)
			  (get-slot stx (if trans? trans-slot-table slot-table))
			  trans?
			  (and b (list-ref b 4))
			  (and b
			       ((if trans?
				    identifier-transformer-binding-export-position
				    identifier-binding-export-position)
				stx))))))]

		[(#%top . id)
		 ;; Top-level reference:
		 (make-top-level-varref
		  stx
		  (mk-back)
		  (syntax-e (syntax id))
		  #f
		  (get-slot (syntax id) (if trans? trans-slot-table slot-table))
		  trans?
		  #f
		  #f)]

		[(#%datum . val)
		 (let ([val (syntax val)])
		   (make-quote-form
		    stx
		    (mk-back)
		    (make-zread
		     val)))]

		[(define-values names rhs)
		 (make-define-values-form
		  stx
		  (mk-back)
		  (map (lambda (stx)
			 (let ([b (identifier-binding stx)])
			   (make-top-level-varref
			    stx
			    (mk-back)
			    (if (pair? b)
				(cadr b)
				(syntax-e stx))
			    (and (pair? b) (car b))
			    (get-slot stx slot-table)
			    #f
			    #f
			    #f)))
		       (syntax->list (syntax names)))
		  (loop (syntax rhs) null #f))]
		
		[(-define names rhs)
		 (or (module-identifier=? #'-define #'define-syntaxes)
		     (module-identifier=? #'-define #'define-values-for-syntax))
		 (let ([for-stx? (module-identifier=? #'-define #'define-values-for-syntax)])
		   ((if for-stx?
			make-define-for-syntax-form
			make-define-syntaxes-form)
		    stx
		    (mk-back)
		    (map (lambda (stx)
			   (let ([b (identifier-binding stx)])
			     (make-top-level-varref
			      stx
			      (mk-back)
			      (if (pair? b)
				  (cadr b)
				  (syntax-e stx))
			      (and (pair? b) (car b))
			      (get-slot stx syntax-slot-table)
			      #f
			      for-stx?
			      #f)))
			 (syntax->list (syntax names)))
		    (loop (syntax rhs) null #t)))]
		
		[(module name init-require (#%plain-module-begin . body))
		 (let* ([body (map (lambda (x)
				     (loop x env trans?))
				   (syntax->list (syntax body)))]
			[get-required-modules
			 (lambda (req)
			   (let loop ([body body])
			     (cond
			      [(null? body) null]
			      [(and (require/provide-form? (car body))
				    (module-identifier=? req (stx-car (zodiac-stx (car body)))))
			       (append
				(map (lambda (r)
				       (syntax-case* r (prefix all-except rename)
					   (lambda (a b) (eq? (syntax-e a)
							      (syntax-e b)))
					 [mod
					  (identifier? r)
					  r]
					 [(prefix id mod)
					  (syntax mod)]
					 [(rename mod . _)
					  (syntax mod)]
					 [(all-except mod . _)
					  (syntax mod)]
					 [_else r]))
				     (stx->list (stx-cdr (zodiac-stx (car body)))))
				(loop (cdr body)))]
			      [else (loop (cdr body))])))]
			[rt-required
			 (cons (syntax init-require)
			       (get-required-modules (quote-syntax require)))]
			[et-required
			 (cons (syntax init-require)
			       (get-required-modules (quote-syntax require-for-syntax)))]
			[tt-required
			 (cons (syntax init-require)
			       (get-required-modules (quote-syntax require-for-template)))]
			[et-body
			 (filter (lambda (e)
				   (or (define-syntaxes-form? e)
				       (define-for-syntax-form? e)))
				 body)]
			[rt-body
			 (filter (lambda (e) (and (not (define-syntaxes-form? e))
						  (not (define-for-syntax-form? e))
						  (not (require/provide-form? e))))
				 body)])
		   (make-module-form
		    stx
		    (mk-back)
		    (syntax name)
		    rt-required
		    et-required
		    tt-required
		    (make-begin-form
		     stx
		     (mk-back)
		     rt-body)
		    (make-begin-form
		     stx
		     (mk-back)
		     et-body)
		    (syntax-property stx 'module-variable-provides)
		    (syntax-property stx 'module-syntax-provides)
		    (syntax-property stx 'module-indirect-provides)
		    (syntax-property stx 'module-kernel-reprovide-hint)
		    (syntax-property stx 'module-self-path-index)))]
		[(require i ...)
		 (make-require/provide-form
		  stx
		  (mk-back))]
		[(require-for-syntax i ...)
		 (make-require/provide-form
		  stx
		  (mk-back))]
		[(require-for-template i ...)
		 (make-require/provide-form
		  stx
		  (mk-back))]
		[(provide i ...)
		 (make-require/provide-form
		  stx
		  (mk-back))]

		[(quote expr)
		 (make-quote-form
		  stx
		  (mk-back)
		  (make-zread (syntax expr)))]

		[(quote-syntax expr)
		 (make-quote-syntax-form
		  stx
		  (mk-back)
		  (syntax expr))]
		
		[(lambda args . body)
		 (let-values ([(env args) (args-s->z env (syntax args))])
		   (make-case-lambda-form
		    stx
		    (mk-back)
		    (list args)
		    (list (loop (syntax (begin . body)) env trans?))))]
		[(case-lambda [args . body] ...)
		 (let-values ([(envs argses)
			       (let ([es+as
				      (map
				       (lambda (args)
					 (let-values ([(env args) (args-s->z env args)])
					   (cons env args)))
				       (syntax->list (syntax (args ...))))])
				 (values
				  (map car es+as)
				  (map cdr es+as)))])
		   (make-case-lambda-form
		    stx
		    (mk-back)
		    argses
		    (map (lambda (env body)
			   (with-syntax ([body body])
			     (loop (syntax (begin . body)) env trans?)))
			 envs
			 (syntax->list (syntax (body ...))))))]

		[(let-values . _)
		 (let-s->z make-let-values-form #f stx env
			   (lambda (b env) (loop b env trans?)))]
		[(letrec-values . _)
		 (let-s->z make-letrec-values-form #t stx env
			   (lambda (b env) (loop b env trans?)))]
		
		[(set! var rhs)
		 (make-set!-form
		  stx
		  (mk-back)
		  (loop (syntax var) env trans?)
		  (loop (syntax rhs) env trans?))]
		
		[(begin . exprs)
		 (make-begin-form
		  stx
		  (mk-back)
		  (map (lambda (x)
			 (loop x env trans?))
		       (syntax->list (syntax exprs))))]
		
		[(begin0 . exprs)
		 (make-begin0-form
		  stx
		  (mk-back)
		  (map (lambda (x)
			 (loop x env trans?))
		       (syntax->list (syntax exprs))))]

		[(if test then)
		 (make-if-form
		  stx
		  (mk-back)
		  (loop (syntax test) env trans?)
		  (loop (syntax then) env trans?)
		  (loop (syntax (#%app void)) env trans?))]

		[(if test then else)
		 (make-if-form
		  stx
		  (mk-back)
		  (loop (syntax test) env trans?)
		  (loop (syntax then) env trans?)
		  (loop (syntax else) env trans?))]

		[(with-continuation-mark k v body)
		 (make-with-continuation-mark-form
		  stx
		  (mk-back)
		  (loop (syntax k) env trans?)
		  (loop (syntax v) env trans?)
		  (loop (syntax body) env trans?))]

		[(#%app 'gp vec (#%datum . pos))
		 (and (eq? (syntax-e #'gp) global-prepare-id)
		      (number? (syntax-e #'pos)))
		 (make-global-prepare
		  stx
		  (mk-back)
		  (loop (syntax vec) env trans?)
		  (syntax-e #'pos))]
		[(#%app 'gl vec (#%datum . pos))
		 (and (eq? (syntax-e #'gl) global-lookup-id)
		      (number? (syntax-e #'pos)))
		 (make-global-lookup
		  stx
		  (mk-back)
		  (loop (syntax vec) env trans?)
		  (syntax-e #'pos))]
		[(#%app 'ga vec (#%datum . pos) val)
		 (and (eq? (syntax-e #'ga) global-assign-id)
		      (number? (syntax-e #'pos)))
		 (make-global-assign
		  stx
		  (mk-back)
		  (loop (syntax vec) env trans?)
		  (syntax-e #'pos)
		  (loop (syntax val) env trans?))]
		[(#%app 'svr vec (#%datum . pos))
		 (and (eq? (syntax-e #'svr) safe-vector-ref-id)
		      (number? (syntax-e #'pos)))
		 (make-safe-vector-ref
		  stx
		  (mk-back)
		  (loop (syntax vec) env trans?)
		  (syntax-e #'pos))]
		
		[(#%app)
		 (make-quote-form
		  (syntax/loc stx ())
		  (mk-back)
		  (make-zread (quote-syntax ())))]
		[(#%app func arg ...)
		 (make-app
		  stx
		  (mk-back)
		  (loop (syntax func) env trans?)
		  (map
		   (lambda (arg)
		     (loop arg env trans?))
		   (syntax->list (syntax (arg ...)))))]
		
		[_else
		 (error 'syntax->zodiac
			"unrecognized expression form: ~e"
			(syntax-object->datum stx))]))))

      
      (define (zodiac->syntax x)
	(let loop ([x x])
	  (cond
	   [(zread? x)
	    (zodiac-stx x)]

	   [(top-level-varref? x)
	    (zodiac-stx x)]
	   [(bound-varref? x)
	    ;; An stx object is getting gensymmed here!
	    (datum->syntax-object #f (binding-var (bound-varref-binding x)) #f)]
	   
	   [(app? x)
	    (with-syntax ([fun (loop (app-fun x))]
			  [args (map loop (app-args x))])
	      (syntax (#%app fun . args)))]

	   [(if-form? x)
	    (with-syntax ([test (loop (if-form-test x))]
			  [then (loop (if-form-then x))]
			  [else (loop (if-form-else x))])
	      (syntax (if test then else)))]

	   [(quote-form? x)
	    (with-syntax ([v (zodiac-stx (quote-form-expr x))])
	      (syntax (quote v)))]
	   [(quote-syntax-form? x)
	    (with-syntax ([v (quote-syntax-form-expr x)])
	      (syntax (quote-syntax v)))]

	   [(begin-form? x)
	    (with-syntax ([body (map loop (begin-form-bodies))])
	      (syntax (begin . body)))]
	   [(begin0-form? x)
	    (with-syntax ([body (map loop (begin-form-bodies))])
	      (syntax (begin0 . body)))]

	   [(let-values-form? x)
	    (with-syntax ([(vars ...)
			   (map (lambda (vars)
				  (map binding-var vars))
				(let-values-form-vars x))]
			  [(val ...)
			   (map loop (let-values-form-vals x))]
			  [body (loop (let-values-form-body x))])
	      (syntax (let-values ([vars val] ...) body)))]
	   [(letrec-values-form? x)
	    (with-syntax ([(vars ...)
			   (map (lambda (vars)
				  (map binding-var vars))
				(letrec-values-form-vars x))]
			  [(val ...)
			   (map loop (letrec-values-form-vals x))]
			  [body (loop (letrec-values-form-body x))])
	      (syntax (letrec-values ([vars val] ...) body)))]
	   
	   [(define-values-form? x)
	    (with-syntax ([vars (map zodiac-stx (define-values-form-vars x))]
			  [val (loop (define-values-form-val x))])
	      (syntax (define-values vars val)))]
	   
	   [(set!-form? x)
	    (with-syntax ([var (loop (set!-form-var x))]
			  [val (loop (set!-form-val x))])
	      (syntax (set! var val)))]
	   
	   [(case-lambda-form? x)
	    (with-syntax ([(args ...)
			   (map (lambda (args)
				  (cond
				   [(sym-arglist? args)
				    (datum->syntax-object #f (binding-var (car (arglist-vars args))) #f)]
				   [(list-arglist? args)
				    (map (lambda (var)
					   (datum->syntax-object #f (binding-var var) #f))
					 (arglist-vars args))]
				   [(ilist-arglist? args)
				    (let loop ([vars (arglist-vars args)])
				      (let ([id (datum->syntax-object #f (binding-var (car vars)) #f)])
					(if (null? (cdr vars))
					    id
					    (cons id (loop (cdr vars))))))]))
				(case-lambda-form-args x))]
			  [(body ...)
			   (map loop (case-lambda-form-bodies x))])
	      (syntax (case-lambda [args body] ...)))]

	   [(with-continuation-mark-form? x)
	    (with-syntax ([key (loop (with-continuation-mark-form-key x))]
			  [val (loop (with-continuation-mark-form-val x))]
			  [body (loop (with-continuation-mark-form-body x))])
	      (syntax (with-continuation-mark key val body)))]

	   [else (error 'zodiac->syntax
			"unknown zodiac record type: ~e"
			x)])))

      (define (zodiac-origin z) z)

      (define (origin-who z)
	(if (syntax-original? (zodiac-stx z))
	    'source
	    'macro))

      (define (origin-how z)
	(syntax-property (zodiac-stx z) 'origin))
      
      (define (zodiac-start z) z)
      (define (zodiac-finish z) z)

      (define (location-line z)
	(and (zodiac-stx z) (syntax-line (zodiac-stx z))))
      
      (define (location-column z)
	(and (zodiac-stx z) (syntax-column (zodiac-stx z))))

      (define (location-file z)
	(and (zodiac-stx z) (syntax-source (zodiac-stx z))))

      (define (zread-object z)
	(syntax-e (zodiac-stx z)))

      (define (structurize-syntax sexp)
	(make-zread (datum->syntax-object #f sexp #f)))

      ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

      (define eof? eof-object?)

      (define-struct zodiac (stx))
      (define-struct (zread zodiac) ())

      (define-struct (parsed zodiac) (back))

      (define-struct (varref parsed) (var))

      (define-struct (top-level-varref varref) (module slot exptime? expdef? position))
      (define (create-top-level-varref z var module slot exptime? expdef? position)
	(make-top-level-varref (zodiac-stx z) (mk-back) var module slot exptime? expdef? position))

      (define-struct (bound-varref varref) (binding))
      (define (create-bound-varref z var binding)
	(make-bound-varref (zodiac-stx z) (mk-back) var binding))

      (define lexical-varref? bound-varref?)
      (define make-lexical-varref make-bound-varref)
      (define create-lexical-varref create-bound-varref)

      (define-struct (binding parsed) (var orig-name))
      (define (create-binding z var orig-name)
	(make-binding (zodiac-stx z) (mk-back) var orig-name))

      (define lexical-binding? binding?)
      (define make-lexical-binding make-binding)
      (define create-lexical-binding create-binding)


      (define-struct (app parsed) (fun args))
      (define (create-app z fun args)
	(make-app (zodiac-stx z) (mk-back) fun args))

      (define-struct (if-form parsed) (test then else))
      (define (create-if-form z test then else)
	(make-if-form (zodiac-stx z) (mk-back) test then else))

      (define-struct (quote-form parsed) (expr))
      (define (create-quote-form z expr)
	(make-quote-form (zodiac-stx z) (mk-back) expr))

      (define-struct (begin-form parsed) (bodies))
      (define (create-begin-form z bodies)
	(make-begin-form (zodiac-stx z) (mk-back) bodies))

      (define-struct (begin0-form parsed) (bodies))
      (define (create-begin0-form z bodies)
	(make-begin0-form (zodiac-stx z) (mk-back) bodies))

      (define-struct (let-values-form parsed) (vars vals body))
      (define (create-let-values-form z vars vals body)
	(make-let-values-form (zodiac-stx z) (mk-back) vars vals body))

      (define-struct (letrec-values-form parsed) (vars vals body))
      (define (create-letrec-values-form z vars vals body)
	(make-letrec-values-form (zodiac-stx z) (mk-back) vars vals body))

      (define-struct (define-values-form parsed) (vars val))
      (define (create-define-values-form z vars val)
	(make-define-values-form (zodiac-stx z) (mk-back) vars val))

      (define-struct (set!-form parsed) (var val))
      (define (create-set!-form z var val)
	(make-set!-form (zodiac-stx z) (mk-back) var val))

      (define-struct (case-lambda-form parsed) (args bodies))
      (define (create-case-lambda-form z args bodies)
	(make-case-lambda-form (zodiac-stx z) (mk-back) args bodies))

      (define-struct (with-continuation-mark-form parsed) (key val body))
      (define (create-with-continuation-mark-form z key val body)
	(make-with-continuation-mark-form (zodiac-stx z) (mk-back) key val body))

      (define-struct (quote-syntax-form parsed) (expr))
      (define (create-quote-syntax-form z expr)
	(make-quote-syntax-form (zodiac-stx z) (mk-back) expr))

      (define-struct (define-syntaxes-form parsed) (names expr))
      (define (create-define-syntaxes-form z names expr)
	(make-define-syntaxes-form (zodiac-stx z) (mk-back) names expr))

      (define-struct (define-for-syntax-form parsed) (names expr))
      (define (create-define-for-syntax-form z names expr)
	(make-define-for-syntax-form (zodiac-stx z) (mk-back) names expr))

      (define-struct (module-form parsed) (name requires for-syntax-requires for-template-requires 
						body syntax-body 
						provides syntax-provides indirect-provides
						kernel-reprovide-hint
						self-path-index))
      (define (create-module-form z name rt-requires et-requires tt-requires
				  rt-body et-body
				  var-provides syntax-provides indirect-provides
				  kernel-hint self)
	(make-module-form (zodiac-stx z) (mk-back) 
			  name rt-requires et-requires tt-requires 
			  rt-body et-body
			  var-provides syntax-provides indirect-provides
			  kernel-hint self))

      (define-struct (require/provide-form parsed) ())
      (define (create-require/provide-form z)
	(make-require/provide-form (zodiac-stx z) (mk-back)))
      
      (define-struct (global-prepare parsed) (vec pos))
      (define (create-global-prepare z vec pos)
	(make-global-prepare (zodiac-stx z) (mk-back) vec pos))

      (define-struct (global-lookup parsed) (vec pos))
      (define (create-global-lookup z vec pos)
	(make-global-lookup (zodiac-stx z) (mk-back) vec pos))

      (define-struct (global-assign parsed) (vec pos expr))
      (define (create-global-assign z vec pos expr)
	(make-global-assign (zodiac-stx z) (mk-back) vec pos expr))

      (define-struct (safe-vector-ref parsed) (vec pos))
      (define (create-safe-vector-ref z vec pos)
	(make-safe-vector-ref (zodiac-stx z) (mk-back) vec pos))

      (define-struct arglist (vars))
      (define-struct (sym-arglist arglist) ())
      (define-struct (list-arglist arglist) ())
      (define-struct (ilist-arglist arglist) ()))))
