SainTiss <[EMAIL PROTECTED]> writes:

> I'm wondering, though, if I can get things to work the first way? Aren't 
> lambda's supposed to be closures, so that they can actually access variables 
> defined in lexical scope? Or is there anything I could do with the _closure 
> parameter here (what is it for, anyway...)?

I hacked together something that allows you to create a Pepsi
BlockClosure from within Jolt.  It's a bit ugly, but here is the code
in case it suits your needs:

;; -*-Lisp-*-
;; with-block-closure.k - Define a dynamic-extent Pepsi closure from Jolt
;; Michael FIG <[EMAIL PROTECTED]>, 2007-07-16

;; Here's how to use it:
;;(let ((frotz 9)
;;      (baz 10)
;;      (bar 11)
;;      (bot 12))
;;
;;  (set baz "hello")
;;  (set bar 42)
;;  (printf "have %p\n" (addrof frotz))
;;  (printf "set %p to %s\n" (addrof baz) baz)
;;  (printf "set %p to %d\n" (addrof bar) bar)
;;
;;  (with-block-closure (frotz baz bar)
;;      (cb (arg1 arg2 arg3)
;;        (printf "cb got args %d %d %d\n" arg1 arg2 arg3)
;;        (printf "cb has %p %s %d\n" (long@ frotz) (long@ baz) (long@ bar))
;;        (set (long@ frotz) 18)
;;        (set (long@ baz) "goodbye")
;;        (set (long@ bar) 24))
;;    [cb value: 1 value: 2 value: 3])
;;
;;  (printf "now have %p %s %d\n" frotz baz bar))
;; results in:
;;
;; have 0xbff96b68
;; set 0xbff96b64 to hello
;; set 0xbff96b60 to 42
;; cb got args 1 2 3
;; cb has 0x9 hello 42
;; now have 0x12 goodbye 24

;; We need the BlockClosure definition.
(define BlockClosure (import "BlockClosure"))

(syntax with-block-closure
  (lambda (node compiler)
    (let ((posn '0)
          (state-spec [node second])
          (state-size [state-spec size])
          (state-setters [Expression new: state-size])
          (state-getters [Expression new: state-size])
          (block-name [[node third] first])
          (args [[node third] second])
          (arity [args size])
          (block-body [[node third] copyFrom: '2])
          (body [node copyFrom: '3]))

      (while [posn < state-size]
         ;; Put the address of the variable in the state array.
         [state-setters at: posn put:
           [Expression
             with: 'send with: ''at:put:
             with: '_state
             with: [Expression with: 'quote with: posn]
             with: [Expression with: 'addrof with: [state-spec at: posn]]]]
         ;; Bind the addresses of the variables from the state array.
         ;; FIXME: Automatic long@ indirection would be nice.
         [state-getters at: posn put:
           [Expression
             with: [state-spec at: posn]
               with: [Expression with: 'send with: ''at:
               with: '_state with: [Expression with: 'quote with: posn]]]]
         (set posn [posn + '1]))
      ;;[StdOut print: state-setters] [StdOut cr]
      ;;[StdOut print: state-getters] [StdOut cr]

      `(let ((_state [Array new: ',state-size])
             (,block-name [BlockClosure function_:
              (lambda (_closure self ,@args)
                (let ((_state (long@ (+ self 12)))
                      ,@state-getters)
                  ,@block-body))
              arity_: ,arity outer: 0 state: _state nlr_: 0]))

        ,@state-setters
        ,@body))))
;; End.

-- 
Michael FIG <[EMAIL PROTECTED]> //\
   http://michael.fig.org/    \//
_______________________________________________
fonc mailing list
[email protected]
http://vpri.org/mailman/listinfo/fonc

Reply via email to