home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / devel / lang / lisp / guile-ii.src / guile-ii / guile-src / ctax / ctax.scm < prev    next >
Encoding:
Text File  |  1995-08-15  |  21.0 KB  |  767 lines

  1. #!/bin/sh
  2. type;exec guile -l $0 -e "(ctax-repl *stdin*)"
  3. ;;; -*-scheme-*- tells emacs this is a scheme file.
  4.  
  5. ;;;;     Copyright (C) 1994, 1995 Free Software Foundation, Inc.
  6. ;;;; 
  7. ;;;; This program is free software; you can redistribute it and/or modify
  8. ;;;; it under the terms of the GNU General Public License as published by
  9. ;;;; the Free Software Foundation; either version 2, or (at your option)
  10. ;;;; any later version.
  11. ;;;; 
  12. ;;;; This program is distributed in the hope that it will be useful,
  13. ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. ;;;; GNU General Public License for more details.
  16. ;;;; 
  17. ;;;; You should have received a copy of the GNU General Public License
  18. ;;;; along with this software; see the file COPYING.  If not, write to
  19. ;;;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  20. ;;;; 
  21.  
  22.  
  23.  
  24. ;; Easier to type:
  25. ;;
  26. (define pp (lambda args (apply pretty-print args)))
  27.  
  28. ;; Especially good for debugging -- wrap this 
  29. ;; around a form.  E.g.:
  30. ;;      (+ x <some-exp>) => (+ x (pk 'buggy-exp-val <some-exp>))
  31. ;;
  32. (define (pk tag val)
  33.   (pp (list tag val))
  34.   val)
  35.  
  36. ;;; {Warnings and Errors.}
  37. ;;;
  38.  
  39. ;; Crudely warn about semantic errors in the source program 
  40. ;; (e.g. ``statements after return'').
  41. ;;
  42. (define (warning v)
  43.   (pp (list 'warning v)))
  44.       
  45.  
  46. ;;; {Entry Points}
  47. ;;;
  48.  
  49. ;; repl
  50. (define (ctax-repl port)
  51.   (synthetic-repl ctax-prompt ctax-read ctax-eval pp port))
  52.  
  53.  
  54. (define (ctax-repl-thunk)
  55.   (ctax-prompt)
  56.   (pp (ctax-eval (ctax-read)))
  57.   (ctax-repl-thunk))
  58.  
  59. ;; Prompter
  60. ;;
  61. (define (ctax-prompt) (display "ctax> ") (force-output))
  62.  
  63. ;; Parse one ctax command from a port.
  64. ;;
  65. (define (ctax-read) (ctax-parse (lambda () (string (read-char)))))
  66.  
  67. ;; Evaluate a parsed form.
  68. ;;
  69. (define (ctax-eval tree)  (eval (ctax-transl-command tree)))
  70.  
  71.  
  72. ;; Parse and translate a string, pretty-print the answer
  73. ;;
  74. (define (ctax-translation string)
  75.   (let ((tree (ctax-tree string)))
  76.     (ctax-transl-command tree)))
  77.  
  78.  
  79.  
  80.  
  81. ;; Return a parse tree for the argument string
  82. ;;
  83. (define (ctax-tree string)
  84.   (ctax-parse (lambda ()
  85.         (let ((answer string))
  86.           (set! string #f)
  87.           answer))))
  88.  
  89. ;; Translate a tree returned from ctax parse.  The tree
  90. ;; is either a stand-alone statement or a definition.
  91. ;;
  92. (define (ctax-transl-command tree)
  93.   (cond
  94.    ((and (pair? tree)
  95.      (eq? 'ctax:define (car tree)))
  96.     (ctax-transl-definition tree))
  97.  
  98.    ((and (pair? tree)
  99.      (eq? 'ctax:SCM (car tree)))
  100.     (cons 'begin
  101.       (map (lambda (v)
  102.          (if (and (pair? (caddr tree))
  103.               (eq? 'ctax:struct (car (caddr tree))))
  104.              (set! v (struct-name v)))
  105.          `(define ,v ,(ctax-transl-expression (caddr tree))))
  106.            (cadr tree))))
  107.  
  108.    (#t
  109.     (ctax-transl-top-level-statement tree))))
  110.  
  111.  
  112. ;;; {The Translator}
  113. ;;;
  114.  
  115. ;; Return a Scheme form that is equivalent to a
  116. ;; top-level ctax statement.  We compile the statement
  117. ;; as if it were the body of a parameterless, anonymous function, 
  118. ;; and then construct an application of that function.
  119. ;;
  120. (define (ctax-transl-top-level-statement tree)
  121.   `((lambda ()
  122.       ,(ctax-transl-function-defining-statement tree))))
  123.     
  124. ;; Defines translate to defines.
  125. ;;
  126. (define (ctax-transl-definition tree)
  127.   (let ((iens (cadr tree))
  128.     (formals (caddr tree))
  129.     (doc (cadddr tree))
  130.     (interaction (car (cddddr tree)))
  131.     (body (cadr (cddddr tree))))
  132.     `(define ,(cons iens formals)
  133.        ,(ctax-transl-function-defining-statement body))))
  134.  
  135. ;;
  136. (define (ctax-transl-definition-procedure tree)
  137.   (let ((iens (cadr tree))
  138.     (formals (caddr tree))
  139.     (doc (cadddr tree))
  140.     (interaction (car (cddddr tree)))
  141.     (body (cadr (cddddr tree))))
  142.     `(lambda ,formals
  143.        ,(ctax-transl-function-defining-statement body))))
  144.  
  145.  
  146. ;; A statement that is the body of a function definition
  147. ;; is translated by this procedure.  The gist is that the statement
  148. ;; is translated as usual, but that we might have to provide
  149. ;; some bindings for free labels like `break' or `fi'.
  150. ;;
  151. (define (ctax-transl-function-defining-statement tree)
  152.   (ctax-transl-statement
  153.    tree
  154.    #f
  155.    #f
  156.    (lambda (translation free-attribs)
  157.      (cond
  158.       ((member free-attribs '(() (return))) translation)
  159.       ((member free-attribs '((break) (fi)))
  160.        `(let ((,(car free-attribs) (lambda (x) x)))
  161.       ,translation))
  162.       (t (error (list 'internal-error-bad-attributes free-attribs)))))))
  163.  
  164.  
  165. ;; Translate a statement
  166. ;;
  167. ;; The arguments are 
  168.  
  169. ;;     tree -- a ctax syntax tree to translate
  170.  
  171. ;;     following -- the name of a label to which to pass the value
  172. ;;                  of this statement.  #f if the statment should just
  173. ;;                  return it's value.
  174.  
  175. ;;                  For example, the two branches of a conditional are
  176. ;;                  (normally) translated with following set to 'fi,
  177. ;;                  and that label is given to the statements that
  178. ;;                  follow the conditional.
  179.  
  180. ;;                  Some care is taken to not introduce labels
  181. ;;                  unecessarily.  For example, if a conditional is
  182. ;;                  being compiled with following set to 'break
  183. ;;                  (indicating an enclosing while loop), then it
  184. ;;                  won't introduce a 'fi label.  Instead, the two
  185. ;;                  branches will also have following set to 'break.
  186. ;;                  This optimization is a kind of goto compression.
  187.  
  188. ;;     exits-ok? -- #f unless the statement is enclosed in a loop.
  189. ;;                  Only if this is not false can the statement be `break'
  190. ;;                  or `continue'
  191.  
  192. ;;     return -- the return continuation. Takes two arguments.
  193. ;;
  194. ;;               The first argument is the Scheme form which is the
  195. ;;               translation.
  196.  
  197. ;;               The second is a list of flags describing the translation.
  198. ;;               In this implementation, the flags are either '() or a
  199. ;;               one element list.
  200.  
  201. ;;               The flags can be:
  202.  
  203. ;;                   '(return)  -- the statement is a return statement.
  204.  
  205. ;;                   '(fi) -- the statement passes its value to the
  206. ;;                            label `fi'.  Presumably the statement
  207. ;;                            was a conditional.
  208.  
  209. ;;                   '(break) -- the statement passes its label to the
  210. ;;                               label `break'.  The statement was
  211. ;;                               some form of loop (while, for or do).
  212. ;;
  213.  
  214.  
  215. (define (ctax-transl-statement tree following exits-ok? return)
  216.  
  217.   (let ((statement-type (ctax-tree-type tree)))
  218.     (case statement-type
  219.  
  220.       ;; Compound statements.
  221.       ;;
  222.       ;; In the simplest case, a ctax block turns into just a Scheme
  223.       ;; block:
  224.       ;;
  225.       ;;   { a; b; c; }    =>   (begin [a] [b] [c])
  226.       ;;
  227.       ;; That case is handled by translating a to [a], and then
  228.       ;; making (conceptually):
  229.       ;;
  230.       ;;        (begin [a] (begin [{b; c;}]))
  231.       ;;
  232.       ;; To actually build such a scheme form, we use ctax-make-begin!
  233.       ;; which flattens nested begin forms.
  234.       ;;
  235.       ;; In a more complicated case, the first statment might be
  236.       ;; a loop or conditional.  In that case, the rest of the
  237.       ;; statements have to be labeled:
  238.       ;;
  239.       ;;      { if (a) b; else return c;  d; }
  240.       ;;    =>
  241.       ;;      (let ((fi (lambda (return) [d])))
  242.       ;;         (if (ctax-test [a])
  243.       ;;            (fi [b])
  244.       ;;            c))
  245.       ;;
  246.       ;; Note that this translation isn't hygenic: it mixes some
  247.       ;; compiler generated identifiers ("fi" and "return") in with
  248.       ;; the identifiers of the source program.  We get away with that
  249.       ;; by making the labels illegal ctax identifiers.  Slightly more
  250.       ;; sophisticated translations could be hygenic but there is no
  251.       ;; need so long as the compiler can allocate a few variable
  252.       ;; names to itself.
  253.       ;;
  254.       
  255.       
  256.       ((ctax:begin)
  257.  
  258.        (let* ((formals (cadr tree))
  259.           (body (cddr tree))
  260.           (first-stmt (car body))
  261.           (rest-stmts (cdr body)))
  262.  
  263.      (if (null? rest-stmts)
  264.  
  265.          ;; If a compound statement only contains one element,
  266.          ;; just translate that element.
  267.          ;;
  268.          (ctax-transl-statement
  269.           (car body)
  270.           following
  271.           exits-ok?
  272.           (lambda (only-tree only-labels)
  273.         (return
  274.          ;; Even though the block has only one statement, it
  275.          ;; may have some local variables.
  276.          ;;
  277.          (if (null? formals)
  278.              only-tree
  279.              (ctax-enclose-with-formals formals only-tree))
  280.          only-labels)))
  281.  
  282.  
  283.          ;; Truly compound statemts
  284.          ;;
  285.          ;; Start by translating the first statement...
  286.          ;;
  287.          (ctax-transl-statement
  288.           first-stmt
  289.  
  290.           ;; We are in the middle of a block, so the first statement
  291.           ;; is followed directly by other statements.  Therefore,
  292.           ;; it should just return its value normally:
  293.           ;;
  294.           #f
  295.  
  296.           ;; It is only ok for the first statement to be a break
  297.           ;; or continue if it was ok for this whole block to have
  298.           ;; been a break or continue:
  299.           ;;
  300.           exits-ok?
  301.  
  302.           (lambda (first-tree first-attribs)
  303.         ;; A big dispatch on the attributes of the first
  304.         ;; statement:
  305.         ;;
  306.         (cond
  307.          ;; If the first statement was simple enough, then there
  308.          ;; are no free labels to resolve
  309.          ;;
  310.          ((null? first-attribs)
  311.           ;; Just put the statement in a scheme block with the
  312.           ;; rest of the statements.  First, contruct a ctax block
  313.           ;; containing only the rest of this block, and compile
  314.           ;; that:
  315.           ;;
  316.           (ctax-transl-statement
  317.            (cons 'ctax:begin (cons '() rest-stmts))
  318.  
  319.            ;; The subblock containing all statements after the
  320.            ;; first is followed by whatever follows the block
  321.            ;; we're working on.
  322.            ;;
  323.            following
  324.  
  325.            ;; Again, this is inherited:
  326.            ;;
  327.            exits-ok?
  328.  
  329.            (lambda (rest-tree rest-attribs)
  330.              ;; This function has the compiled first
  331.              ;; statement, and the compiled rest of the block.
  332.              ;;
  333.              (let ((block-denot
  334.                 (ctax-make-begin! (list first-tree rest-tree))))
  335.                (return
  336.             (if (null? formals)
  337.                 block-denot
  338.                 (ctax-enclose-with-formals formals block-denot))
  339.             ;; The attributes of the tail of the block
  340.             ;; become the attributes of the whole block:
  341.             ;;
  342.             rest-attribs)))))
  343.  
  344.  
  345.          ;; If the first statement was a return statement,
  346.          ;; then ignore the remaining statements and consider 
  347.          ;; this whole block a return statement.
  348.          ;;
  349.          ((equal? '(return) first-attribs)
  350.           (warning 'statements-after-return)
  351.           (return first-tree '(return)))
  352.  
  353.          ;; If the first statement was a conditional or loop,
  354.          ;; provide the appropriate label for the rest of the block:
  355.          ;;
  356.          ((member first-attribs '((fi) (break)))
  357.           (ctax-transl-statement
  358.            ;; Compile the rest of the block.
  359.            ;;
  360.            (cons 'ctax:begin (cons '() rest-stmts))
  361.  
  362.            ;; The rest of the block inherits the whole
  363.            ;; block's follow.
  364.            ;;
  365.            following
  366.  
  367.            ;; Inherit whether we are in a loop:
  368.            ;;
  369.            exits-ok?
  370.  
  371.            (lambda (rest-tree rest-attribs)
  372.              ;; Label the rest of the block `fi' or `break'
  373.              ;; so that the first statement can terminate using
  374.              ;; branches to that label.
  375.              ;;
  376.              (let ((block-denot `(let ((,(car first-attribs)
  377.                         (lambda (return) ,rest-tree)))
  378.                        ,first-tree)))
  379.                (return
  380.             (if (null? formals)
  381.                 block-denot
  382.                 (ctax-enclose-with-formals formals
  383.                                block-denot))
  384.  
  385.             rest-attribs)))))
  386.  
  387.          (t (list 'goof
  388.               first-attribs
  389.               first-tree))))))))
  390.  
  391.       ;; Return statements simply denote their expression's denotation.
  392.       ;; This is different from an expression statement.  An expression
  393.       ;; statement denotes its expression's denotation but wrapped in a
  394.       ;; call to the label implied by `follow'.
  395.       ;;
  396.       ((ctax:return)
  397.        (return (ctax-transl-expression (cadr tree)) '(return)))
  398.       
  399.  
  400.       ((ctax:if)
  401.        (let* ((pred (cadr tree))
  402.           (consequent (caddr tree))
  403.           (anticons (cadddr tree))
  404.  
  405.           (tail-label  (or following 'fi))
  406.  
  407.           ;; Translate the predicate trivially...
  408.           ;;
  409.           (pred-denot `(ctax:test ,(ctax-transl-expression pred))))
  410.      
  411.      (ctax-transl-statement
  412.       consequent
  413.       tail-label
  414.       exits-ok?    
  415.       (lambda (cons-denot cons-labels)
  416.         (ctax-transl-statement
  417.          anticons
  418.          tail-label
  419.          exits-ok?
  420.          (lambda (anticons-denot anticons-labels)
  421.            (return
  422.         `(if ,pred-denot
  423.              ,cons-denot
  424.              ,anticons-denot)
  425.         (if following
  426.             #f
  427.             '(fi)))))))))
  428.  
  429.       ((ctax:while ctax:do)
  430.        (let* ((pred (cadr tree))
  431.           (body (caddr tree))
  432.           (pred-denot `(ctax:test ,(ctax-transl-expression pred)))
  433.           (tail-label (or following 'break)))
  434.  
  435.      (ctax-transl-statement
  436.       body
  437.       'continue
  438.       #t
  439.       (lambda (body-denot body-labels)
  440.         (return
  441.          
  442.          (let ((w/continue
  443.             `(letrec ((continue
  444.                    (lambda (return)
  445.                  (if ,pred-denot
  446.                      ,body-denot
  447.                      (break return)))))
  448.                ;; Does one execution of the body always
  449.                ;; precede the first evaluation of the predicate?
  450.                ;;
  451.                ,(if (eq? statement-type 'ctax:do)
  452.                 body-denot
  453.                 '(continue #f)))))
  454.  
  455.            ;; If there is a `following' label, then that
  456.            ;; label is where calls to `break' should go.
  457.            ;;
  458.            (if following
  459.            `(let ((break ,following))
  460.               ,w/continue)
  461.            w/continue))
  462.  
  463.          
  464.          ;; If there is no following label, then 
  465.          ;; the caller has to provide an appropriate
  466.          ;; binding for `break'.
  467.          ;;
  468.          (if following
  469.          #f
  470.          '(break)))))))
  471.  
  472.  
  473.       ;; For loops are simply rewritten in the way you'd expect.
  474.       ((ctax:for)
  475.        (let* ((init (cadr tree))
  476.           (pred (caddr tree))
  477.           (increment (cadddr tree))
  478.           (body (car (cddddr tree)))
  479.           (new-body `(ctax:begin
  480.               ()
  481.               ,body
  482.               ,increment))
  483.           (new-loop `(ctax:while ,pred
  484.                      ,new-body))
  485.           (easier-form `(ctax:begin
  486.                  ()
  487.                  ,init
  488.                  ,new-loop)))
  489.  
  490.      (ctax-transl-statement easier-form following exits-ok? return)))
  491.  
  492.       ((ctax:break) (return '(break #f) '(break)))
  493.  
  494.       ((ctax:continue) (return '(continue #f) '(continue)))
  495.  
  496.       ;; Expressions:
  497.       (else
  498.        (let ((exp-denot (ctax-transl-expression tree)))
  499.      (return
  500.       (if following
  501.           (list following exp-denot)
  502.           exp-denot)
  503.       '()))))))
  504.  
  505.  
  506. ;; Translate an expression.  This is trivial because flow of control
  507. ;; is not an issue.  For simplicity, we presume a ctax run-time with 
  508. ;; function names that match the symbols used as syntactic identifiers.
  509. ;;
  510.  
  511. (define (struct-name symbol)
  512.   (symbol-append '< 'struct '- symbol '>))
  513. (define (struct-predicate-name symbol)
  514.   (symbol-append '< 'struct '- symbol '? '>))
  515.  
  516. (define (ctax-transl-expression tree)
  517.   (case (ctax-tree-type tree)
  518.     ;; Expressions:
  519.     ((ctax:comma)
  520.      (ctax-make-begin! (map ctax-transl-expression (cdr tree))))
  521.      
  522.  
  523.     ((ctax:constant) tree)
  524.  
  525.     ((ctax:variable) tree)
  526.  
  527.     ((ctax:make-struct)
  528.      (let ((sname (struct-name (cadr tree)))
  529.        (inits (cddr tree)))
  530.        `(ctax:make-struct ,sname
  531.               ,@(map ctax-transl-expression inits))))
  532.  
  533.     ((ctax:struct)
  534.      (let ((sname (cadr tree))
  535.        (fields (caddr tree))
  536.        (super (cadddr tree)))
  537.        `(ctax:struct ',(struct-name sname) ',fields ,(and super (struct-name super)))))
  538.  
  539.     ((ctax:struct-type)  (struct-name (cadr tree)))
  540.  
  541.     ((ctax:->)  (list 'ctax:->
  542.               (caddr tree)
  543.               (ctax-transl-expression (cadr tree))))
  544.  
  545.     ((ctax:scheme-kw) (symbol->keyword (cadr tree)))
  546.  
  547.     ((ctax:neg ctax:log-neg ctax:pos ctax:bit-neg)
  548.      (cons (car tree)
  549.        (map ctax-transl-expression (cdr tree))))
  550.  
  551.     ((ctax:scheme-val)
  552.      `(quote ,(with-input-from-string (cadr tree) read)))
  553.  
  554.     ((ctax:assign)
  555.      (let* ((dest (cadr tree))
  556.         (val (caddr tree))
  557.         (dest-denot (ctax-transl-expression dest))
  558.         (val-denot (ctax-transl-expression val)))
  559.        (ctax-make-assignment dest-denot val-denot)))
  560.        
  561.     ((ctax:times ctax:div ctax:mod ctax:plus ctax:minus ctax:lshift
  562.          ctax:rshift ctax:eq ctax:ne ctax:le ctax:ge
  563.          ctax:lt ctax:gt ctax:bit-and ctax:bit-xor ctax:bit-or
  564.          ctax:log-and ctax:log-or ctax:if-exp ctax:aref)
  565.      (cons (car tree)
  566.        (map ctax-transl-expression (cdr tree))))
  567.  
  568.     ((ctax:apply)
  569.      (map ctax-transl-expression (cons (cadr tree) (caddr tree))))
  570.  
  571.     ((ctax:lambda)
  572.      `(lambda ,(cadr tree)
  573.     ,(ctax-transl-function-defining-statement (car (cddddr tree)))))
  574.  
  575.     (else (error (list 'internal-error tree)))))
  576.  
  577.   
  578.  
  579. ;; Return a symbol describing a parse tree.
  580. ;;
  581. (define (ctax-tree-type tree)
  582.   (cond
  583.    ((pair? tree) (car tree))
  584.    ((memq tree '(ctax:break ctax:continue)) tree)
  585.    ((symbol? tree) 'ctax:variable)
  586.    (t 'ctax:constant)))
  587.  
  588.  
  589. ;; When building up scheme forms like (begin...), collapse
  590. ;; nested begin forms destructively.
  591. ;;
  592. (define (ctax-make-begin! expressions)
  593.  
  594.   (define (is-begin form)
  595.     (and (pair? form) (eq? (car form) 'begin)))
  596.  
  597.   (define (build-list! dest exps)
  598.     (cond
  599.      ((null? exps)
  600.       (set-cdr! dest '()))
  601.      ((is-begin (car exps))
  602.       (set-cdr! dest (cdar exps))
  603.       (build-list! (last-pair dest) (cdr exps)))
  604.      (t
  605.       (set-cdr! dest (cons (car exps) '()))
  606.       (build-list! (cdr dest) (cdr exps)))))
  607.  
  608.   (let ((answer (cons 'begin '#f)))
  609.     (build-list! answer expressions)
  610.     answer))
  611.  
  612.  
  613. ;; Assignment translates trivially
  614. ;;
  615. (define (ctax-make-assignment dest val)
  616.   (cond
  617.    ((symbol? dest)
  618.     `(set! ,dest ,val))
  619.  
  620.    ((eq? (car dest) 'ctax:aref)
  621.     `(vector-set! ,(cadr dest)
  622.           ,(caddr dest)
  623.           ,val))
  624.  
  625.    ((eq? (car dest) 'ctax:->)
  626.     `(ctax:set->! ,(cadr dest)
  627.           ,(caddr dest)
  628.           ,val))   
  629.    (else
  630.     (error (list 'illegal-assignment dest val)))))
  631.  
  632.  
  633.  
  634. (define (ctax-enclose-with-formals formals scheme-form)
  635.   (define (formal->let-binding formal)
  636.     (let* ((var-names (cadr formal))
  637.        (first-var (car var-names))
  638.        (init-expression (caddr formal)))
  639.       (cons (list first-var
  640.           (ctax-transl-expression init-expression))
  641.         (map (lambda (var-name)
  642.            (list var-name first-var))
  643.          (cdr var-names)))))
  644.  
  645.   (define (formals-list->let-bindings list)
  646.     (if (null? list)
  647.     '()
  648.     (append (formal->let-binding (car list))
  649.         (formals-list->let-bindings (cdr list)))))
  650.  
  651.   `(let* ,(formals-list->let-bindings formals)
  652.      ,scheme-form))
  653.  
  654.  
  655. (define (ctax-enclose-with-formals formals scheme-form)
  656.   (define (formal->sets formal)
  657.     (if (eq? (car formal) 'ctax:define)
  658.     `((set! ,(cadr formal)
  659.         ,(ctax-transl-definition-procedure formal)))
  660.     (let ((var-names (cadr formal))
  661.           (init-expression (caddr formal)))
  662.       (let loop ((answer '())
  663.              (val init-expression)
  664.              (vars var-names))
  665.         (if (null? vars)
  666.         (reverse answer)
  667.         (loop (cons `(set! ,(car vars) ,val) answer)
  668.               (car vars)
  669.               (cdr vars)))))))
  670.  
  671.   (define (formals-list->sets list)
  672.     (if (null? list)
  673.     '()
  674.     (append! (formal->sets (car list))
  675.          (formals-list->sets (cdr list)))))
  676.  
  677.   (define (formal-decls f)
  678.     (if (eq? (car f) 'ctax:define)
  679.     (cons (list (cadr f) 0) '())
  680.     (map (lambda (v) (list v 0)) (cadr f))))
  681.  
  682.   `(let ,(apply append! (map formal-decls formals))
  683.      (begin ,@(formals-list->sets formals))
  684.      ,scheme-form))
  685.  
  686.  
  687.  
  688. (define (ctax:test val)
  689.   (and val (not (eq? 0 val))))
  690.  
  691. (defmacro ctax:eq (a b) `(eq? ,a ,b))
  692. (defmacro ctax:ne (a b) `(not (eq? ,a ,b)))
  693. (defmacro ctax:le (a b) `(<= ,a ,b))
  694. (defmacro ctax:ge (a b) `(>= ,a ,b))
  695. (defmacro ctax:lt (a b) `(< ,a ,b))
  696. (defmacro ctax:gt (a b) `(> ,a ,b))
  697.  
  698. (defmacro ctax:minus (a b) `(- ,a ,b))
  699. (defmacro ctax:plus (a b) `(+ ,a ,b))
  700. (defmacro ctax:times (a b) `(* ,a ,b))
  701. (defmacro ctax:div (a b) `(/ ,a ,b))
  702. (defmacro ctax:mod (a b) `(mod ,a ,b))
  703.  
  704. (defmacro ctax:neg (a) `(- ,a))
  705. (defmacro ctax:pos (a) a)
  706.  
  707. (define (ctax:log-neg a) (if (or (not a) (eq? 0 a)) 1 0))
  708.  
  709. (defmacro ctax:lshift (a b) `(ash ,a ,b))
  710. (defmacro ctax:rshift (a b) `(ash ,a (- ,b))) 
  711. (defmacro ctax:bit-neg (a) `(lognot ,a))
  712. (defmacro ctax:bit-and (a b) `(logand ,a ,b))
  713. (defmacro ctax:bit-xor (a b) `(logxor ,a ,b))
  714. (defmacro ctax:bit-or (a b) `(logor ,a ,b))
  715.  
  716. (defmacro ctax:log-and subforms
  717.   `(and ,@subforms))
  718. (defmacro ctax:log-or subforms
  719.   `(or ,@subforms))
  720. (defmacro ctax:if-exp subforms `(if ,@subforms))
  721. (defmacro (false) #f)
  722.  
  723. (define argv *argv*)
  724.  
  725. (define (ctax:struct name fields super)
  726.   (make-struct-type name fields super))
  727.  
  728. (define ctax:array vector)
  729. (define (ctax:bit-array . elts) (list->uniform-vector #t elts))
  730. (define (ctax:bit-array . elts) (list->uniform-vector #t elts))
  731. (define (ctax:bit-array . elts) (list->uniform-vector #t elts))
  732. (define (ctax:bit-array . elts) (list->uniform-vector #t elts))
  733. (define (ctax:bit-array . elts) (list->uniform-vector #t elts))
  734. (define (ctax:bit-array . elts) (list->uniform-vector #t elts))
  735.  
  736.   
  737. (define (ctax:make-struct type . inits)
  738.   (apply make-struct type inits))
  739.  
  740. (defmacro ctax:-> (field struct)
  741.   (list (struct-accessor field) struct))
  742. (defmacro ctax:set->! (field struct val)
  743.   (list (struct-modifier field) struct val))
  744.  
  745. (defmacro ctax:->! (field struct val)
  746.   (list (struct-accessor field) struct val))
  747.  
  748. (define (ctax:bit-array . args)
  749.   (list->uniform-vector #t (map ctax:test args)))
  750. (define (ctax:uint-array . args)
  751.   (list->uniform-vector 1 args))
  752. (define (ctax:int-array . args)
  753.   (list->uniform-vector -1 args))
  754. (define (ctax:float-array . args)
  755.   (list->uniform-vector 1.0 args))
  756. (define (ctax:double-array . args)
  757.   (list->uniform-vector 1/3 args))
  758. (define (ctax:complex-array . args)
  759.   (list->uniform-vector +i args))
  760. (define ctax:list list)
  761. (provide 'ctax)
  762.  
  763.  
  764.  
  765.  
  766. (load "../gls/lstruct.scm")
  767.