This is the mail archive of the guile@cygnus.com mailing list for the guile project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Announcing: Sonya, and I think I'm really learning Scheme :-)


Wow, I managed to code this and actually make it work! Yes,
people _can_ learn Scheme! ;-)

Sonya is the "Stack-Oriented Notation Yearned Adaptor". It will
be a bunch of Guile Scheme code to allow processing of postfix
stack-based languages (like forth or, of course, postscript).

It doesn't change the syntax (you still use () for grouping, ""
for strings, ; for comments, (list ...) for lists etc); changing
the syntax is for that other cool module.

Sonya only implements an operand stack and then processes all
members in a list the way it should if it was a stack-oriented
language (pushing results there and expecting procedures to pop
those they use).

It even knows about using lists to implement fake procedures,
but as we still don't have a "cvx" operator this doesn't do too
much good. It uses object properties for that (property
"executable").

You may call normal procedures from such code, but you will only
receive the required arguments; for example, (sonya 1 2 3 +)
will add 2 and 3 and leave 1 on the stack, returning (5 1).

You may also write procedures specially for Sonya; in this case
expect to receive a single argument, a list, which should be the
operand stack (most recent item is car), and return another
list, which should be the resulting operand stack after you're
done.

Finally, before running it (but after loading) you may
(set! sonya-verbose #t) to see annoying debug messages.


Of course this code needs major testing and reviewing before any
further steps. But just in case someone is wondering _why_ I
wasted my night on this, these next steps are:

1: a module with a collection of Sonya-friendly procedures
(let's call these "operators" that implement an usable subset of
postscript except for the graphics (these will have to come
later if at all). I'm thinking if I want to call this module
"GuileScript" or "Jax" or "JaxScript"... :-)

2: a translator using the lang-allover package; it should be
able to use Sonya to execute postscript, and also convert a
postscript file to a Sonya-powered scheme file

3: Find a way to support DSC in both steps above

Thanks for you're time, it's 8AM here and I need some sleep :-)

[]s,
                                               |alo
                                               +----

PS: No license, no copyright notices, no version numbers, no
nothing for now. C'mon, I have to sleep. :-) In the lack of a
license, just don't distribute it; read, test, use, examine, and
send me your comments (or send them to the list). After I sleep
I'll shape it into a real (alpha) release.

--
      I am Lalo of deB-org. You will be freed.
                 Resistance is futile.

http://www.webcom.com/lalo      mailto:lalo@webcom.com
                 pgp key in the web page

Debian GNU/Linux       --        http://www.debian.org
(use-modules (ice-9 syncase))

(define sonya-verbose #f)

(define sonya-debug-display (lambda (what)
  (if sonya-verbose (display what))
))

(define sonya-debug-write (lambda (what)
  (if sonya-verbose (write what))
))

(define sonya-eval (lambda (op-stack sonya-list)
  (for-each 
    (lambda (v) 
      (if (and (list? v) (object-property v 'executable))
        (begin
          (sonya-debug-display "entering sublist with operand stack: ")
          (sonya-debug-write op-stack)
          (sonya-debug-display "\n(\n")
          (set! op-stack (sonya-eval op-stack v))
          (sonya-debug-display ")\nresulting operand stack: ")
          (sonya-debug-write op-stack)
          (sonya-debug-display "\n")
        )
        (begin
          (sonya-debug-display "found: ")
          (sonya-debug-write v)
          (set! op-stack (append (list v) op-stack))
          (sonya-debug-display 
            (begin
              (if (number? v)
                " - number!"
                (if (list? v)
                  " - list!"
                  (if (procedure? v)
                    (begin
                      (set! op-stack (cdr op-stack))
                      (define my-env (procedure->syntax (lambda (x env) env)))
                      (if (procedure-property v 'for-sonya)
                        (set! op-stack (v op-stack))
                        (set! op-stack (append (list
                          (local-eval `(v ,@(list-head op-stack (car (procedure-property v 'arity)))) (my-env) ))
                          (list-tail op-stack (car (procedure-property v 'arity)))))
                      )
                      (if (unspecified? (car op-stack))
                        (set! op-stack (cdr op-stack)) ; discard return value if procedure returns nothing
                      )
                      " - procedure!"
                    )
                    (if (symbol? v)
                      " - symbol!"
                      " - other?"
                    )
                  )
                )
              )
            )
          )
          (sonya-debug-display "\n")
        )
      )
    )
    sonya-list)
    op-stack
))

(define-syntax sonya (syntax-rules ()
  ((sonya <first> ...) ((lambda () 
    (sonya-debug-display "Running sonya...\n")
    (sonya-eval () (list <first> ...))
    ))
  )
))

; for the def command, remember:
; (eval `(define ,(string->symbol fooname) fooval))
;
; for "procedures" vs lists:
; (set-object-property! a 'executable #t)
; 
; for sonya procedures written in scheme:
; (set-procedure-property! a 'for-sonya #t)
;
; other procedures are called normally but with the obrigatory parameters
; (car (porcedure-property a 'arity)) and the result is put on the stack