[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Compiled code query



    Date:           Fri, 6 Jul 84 11:34:52 PDT
    From:           Larry Severin <severin>

      How can I find out what the format of compiled T code is?
    More specifically, how can I generate my own "compiled-code" to
    pass to the RUN-COMPILED-CODE statement in T?
    One way is to do: (STANDARD-COMPILER expr *SCRATCH-ENV*), but
    I want to build my own objects to run.
      How can I see what these objects really look like?  Their internals
    are not directly accessible from T, as far as I know.
    Who here knows these things?

There are two kinds of compiled expressions, those created by TC and
those created by the "standard compiler".  TC's compiled expressions
are also called "object files" and have an unpleasant format that you
don't want to deal with.  The standard compiler produces closure
structures to represent its intermediate code.  The idea here is that
compilation can be seen as partial evaluation with respect to the
"shape" of the lexical environment.  E.g., a straightforward
S-expression evaluator (like the one in the T manual appendix) would do
something like this:

	(define (evaluate-if exp vars vals)
	  (if (evaluate (cadr exp) vars vals)
	      (evaluate (caddr exp) vars vals)
	      (evaluate (cadddr exp) vars vals)))

where vars is a list of the bound variables, and vals is a
corresponding list of the values of those variables.  Partial
evaluation with respect to "exp" and "vars" can be performed at compile
time, producing a tree of closures which can (and in fact does)
evaluate much more efficiently.  For example, macros can be expanded
at compile time, and the position that lexical variables will have in
the runtime environment can be determined, so that they can be
located quickly at runtime.  The compiler then looks almost the
same as the evaluator, but uses currying to accomplish most of the
work at compile time instead of run time.

	(define (compile-if exp vars)
	  (let ((test (compile (cadr exp) vars))
		(con (compile (caddr exp) vars))
		(alt (compile (cadddr exp) vars)))
	    (lambda (vars)
	      (if (test vars)
		  (con vars)
		  (alt vars)))))

I hope this gives some idea of the kind of beast you're up against when
you way you want to know what the standard compiler's data structures are.
The exact format of the closure which is the value of the (lambda (vars) ...)
is actually decided by TC, and there's really no way to manipulate it at
all - there's nothing to do but call it.

So calling STANDARD-COMPILER is still probably the best way to create
compiled expressions.

I would encourage you to look at the T sources to get answers to
questions like this.

Note that the second argument to STANDARD-COMPILER should be a syntax
table - that is, you must say
	(STANDARD-COMPILER expr (ENV-SYNTAX-TABLE env))
instead of
	(STANDARD-COMPILER expr env)
This is actually necessary in T 2.8, in which the implementation reflects
the manual's distinction between syntax tables and environments.

I know this isn't satisfactory, but I hope it helps clear up T's model of
how compilation works.

Jonathan