Next: , Previous: , Up: Top   [Contents][Index]


2 J.T.W. Proof of concept #1 A superfor macro

A proof of concept for the J.T.W. preprocessor is the superfor macro, which is an enhanced BASIC-style for loop. Here is how to invoke the superfor macro in your *.jtw file:

beginMain
    superfor (var int i = 0 to 10)
    begin
        System.out.println("i=" + i);
    end
endMain

The above code results in the following printout:

i=0
i=1
i=2
i=3
i=4
i=5
i=6
i=7
i=8
i=9
i=10

The step size argument is optional, here is an example with an explicit step size announced:

beginMain
    superfor (var int i = 0 to 10 step 2)
    begin
        System.out.println("i=" + i);
    end
endMain

The above code results in the following printout:

i=0
i=2
i=4
i=6
i=8
i=10

If the downto keyword is given instead of the to keyword then the loop will count downwards from the first given number to the second, even if a postive step size is given. Here is an example with a negative step size:

beginMain
    superfor (var int i = 10 downto 0 step 2)
    begin
        System.out.println("i=" + i);
    end
endMain

The above code results in the following printout:

i=10
i=8
i=6
i=4
i=2
i=0

Note that the specification of the superfor macro doesn’t need constants for the values of start, stop and step-size. They can be any variable or more generally any Java expression, and those expressions will be evaluated only once, should your code have side effects, i.e. changes the value of a variable in your code. See the following example. The expression ++y has the side effect of incrementing the value of y before returning the value of y:

beginMain
    var int x = 20;
    var int y = 15;
    superfor (var int i = x to (2 * ++y))
    begin
        System.out.println("i=" + i);
    end
endMain

The above code results in the following printout:

i=20
i=21
i=22
i=23
i=24
i=25
i=26
i=27
i=28
i=29
i=30
i=31
i=32

2.1 Elisp source code for the superfor macro

The following code belongs in the file ~/jtw/jtw-build-jtw.el which in itself is too large for inclusion in this manual. You can find this code by visiting J.T.W. tarball. Alternatively, you can study this fragment of the file ~/jtw/jtw-build-jtw.el which deals with the superfor macro. In the listing that follows, *pp-namespace* stores a string containing a long arbitrary name to prevent accidental aliasing of the include directives with rest of the comments code.

(let (p1 p2 str form type variable T var start stop step-size step-size-2
             this_start this_stop this_step this_step_size file line p-prior
             beg0 end0)
      (setq strobe nil)
      (checkpoint "2")
      (save-excursion
        (goto-char (point-min))
        (setq *superfor* 0)
        (while (re-search-forward "\\<superfor\\>" nil t)
          (setq beg0 (match-beginning 0))
          (setq end0 (match-end 0))
          ;;(checkpoint "sitting for 1 seconds...")
          (font-lock-fontify-buffer)
          ;;(sit-for 1)
          (when (save-excursion
                  (save-match-data
                    (re-search-forward "(" (point-at-eol) t)
                    (forward-char -1)
                    (re-search-forward "\\<var\\>" nil t)
                    (not (warn--inside-comment-or-string))))
            ;;(error "Smelly cat")
            (setq *current-buffer* (current-buffer))
            ;;(switch-to-buffer *current-buffer*)
            (setq p1 beg0)
            (assert (save-match-data
                      (looking-at " \t\r\n*(")))
            (setq p2 (save-excursion
                       (forward-sexp 1)
                       (point)))
            (setq str (buffer-substring-no-properties end0 p2))
            ;;(checkpoint "str=%s" str)
            (setq form (read-str str))
            ;;(checkpoint "form=%s" form)
            ;;(debug "form")
            (assert (consp form))
            (message "*** form=%s" form)
            ;;(error "Rolling Stones plays Cuba")
            (delete-region p1 p2)
            (incf *superfor*)
            (setq this (format "superfor_%d_" *superfor*))
            (when (not (eq (nth 0 form) 'var))
              (warn--log-message "Error 35: Keyword var missing from superfor construct")
              (when (and (not (eq (nth 1 form) 'char))
                         (not (eq (nth 1 form) 'short))
                         (not (eq (nth 1 form) 'int))
                         (not (eq (nth 1 form) 'long))
                         (not (eq (nth 1 form) 'float))
                         (not (eq (nth 1 form) 'double)))
                (warn--log-message (concat
                                    "Error 37:#1 argument type to superfor macro must be"
                                    " one of char/short/int/long/float/double"))))
            (when (eq (nth 0 form) 'var)
              (if (and (not (eq (nth 1 form) 'char))
                       (not (eq (nth 1 form) 'short))
                       (not (eq (nth 1 form) 'int))
                       (not (eq (nth 1 form) 'long))
                       (not (eq (nth 1 form) 'float))
                       (not (eq (nth 1 form) 'double)))
                  (warn--log-message (concat
                                      "Error 37:#2 argument type to superfor macro must be"
                                      " one of char/short/int/long/float/double")))
              (progn
                ;;(debug "Radiohead: Let Down")
                ;; (setq form '(var int i=0 to stop))
                ;; (setq form '(var int i =0 to stop))
                ;; (setq form '(var int i = 0 to stop))
                (setq type     (nth 1 form))
                (setq T        (prin1-to-string type))
                (setq variable (prin1-to-string (nth 2 form)))
                (if (string-match "=" variable)
                    (progn
                      (setq pre-red-str--variable (substring variable 0 (match-beginning 0)))
                      ;;(string-match "=" variable-equals)
                      (setq pre-red-str--start    (substring variable (match-end 0)))
                      ;;(debug "Radiohead: Fitter Happier")
                      ;;(debug "Jean Jarre: Equinoxe Part III")
                      (setq variable (and (not (string= "" pre-red-str--variable))
                                          (prin1-to-string (read-str pre-red-str--variable))))
                      (setq start (and (not (string= "" pre-red-str--start))
                                       (prin1-to-string (read-str pre-red-str--start))))
                      (cond
                       ((eq (nth 3 form) nil)
                        (setq start (concat start "()"))
                        (setq strobe t)
                        (debug "Queen: One Vision")
                        (cond
                         ((eq (nth 4 form) 'to)
                          (setq to 'to))
                         ((eq (nth 4 form) 'downto)
                          (setq to 'downto))
                         (t
                          (debug "Pretenders: Space Invader")))
                        (setq stop (prin1-to-string (nth 5 form)))
                        (cond
                         ((and (eq (nth 6 form) nil) (> (length form) 6))
                          (setq stop (concat stop "()"))
                          ;;(debug "The Pretenders: Kid")
                          (if (eq (nth 7 form) 'step)
                              (setq step-size (nth 8 form))))
                         ((string-match "(" (prin1-to-string (nth 6 form)))
                          (setq stop (concat stop (and (nth 6 form) (prin1-to-string (nth 6 form)))))
                          (if (eq (nth 7 form) 'step)
                              (setq step-size (nth 8 form))))
                         ((eq (nth 6 form) 'step)
                          (debug "Pretenders: Private Life")
                          (setq step-size (nth 7 form)))
                         (t
                          ;;(debug "Queen: It's a Kind of Magic")
                          )
                         ) ;; end COND!
                        (if strobe (debug "Queen: One Year of Love"))
                        )
                       ((string-match "(" (prin1-to-string (nth 3 form)))
                        ;;(debug "Public Enemy: Letter to the New York Post")
                        (setq start (and (nth 3 form) (concat start (prin1-to-string (nth 3 form)))))
                        (cond
                         ((eq (nth 4 form) 'to)
                          (setq to 'to))
                         ((eq (nth 4 form) 'downto)
                          (setq to 'downto))
                         (t
                          (debug "Elvis: King Creole")))
                        (setq stop (prin1-to-string (nth 5 form)))
                        (cond
                         ((and (eq (nth 6 form) nil) (> (length form) 6))
                          (setq stop (concat stop "()"))
                          ;;(debug "The Pretenders: Kid")
                          (if (eq (nth 7 form) 'step)
                              (setq step-size (nth 8 form))))
                         ;; ------------------------------------------
                         ((string-match "(" (prin1-to-string (nth 6 form)))
                          (setq stop (concat stop (prin1-to-string (nth 6 form))))
                          (if (eq (nth 7 form) 'step)
                              (setq step-size (nth 8 form))))
                         ;; ------------------------------------------
                         ((eq (nth 6 form) 'step)
                          (debug "Pretenders: Private Life")
                          (setq step-size (nth 7 form)))
                         (t
                          ;;(debug "Queen: It's a Kind of Magic")
                          )
                         )
                        ((eq (nth 3 form) 'to)
                         (setq to 'to)
                         (setq stop (nth 4 form))
                         (if (eq (nth 5 form) 'step)
                             (setq step-size (nth 6 form))
                           )
                         ;;(debug "aaa")
                         )
                        ((eq (nth 3 form) 'downto)
                         (setq to 'downto)
                         (setq stop (nth 4 form))
                         (if (eq (nth 5 form) 'step)
                             (setq step-size (nth 6 form))
                           )
                         (debug "bbb")
                         )
                        (t
                         (debug "Dire Straits: The Bug")))
                       )
                      ;;(debug "Bach's Mass in B Minor: Et in terra pax")
                      )
                  (if (eq (nth 3 form) '=)
                      (setq start (and (nth 4 form) (prin1-to-string (nth 4 form))))
                    (setq   start (and (nth 3 form) (prin1-to-string (nth 3 form))))
                    )) ;; end if!
                ;;(debug "Bach's Mass in B Minor: Kyrie eleison")
                (cond
                 ((eq (nth 3 form) 'to)
                  (setq to 'to)
                  (setq stop (prin1-to-string (nth 4 form)))
                  (if (and (eq (nth 5 form) nil) (> (length form) 5))
                      (setq stop (concat stop "()"))
                    (if (string-match "(" (prin1-to-string (nth 5 form)))
                        (setq stop (concat stop (prin1-to-string (nth 5 form))))
                      (if (eq (nth 5 form) 'step)
                          (setq step-size (prin1-to-string (nth 6 form))))))
                  )
                 ((eq (nth 3 form) 'downto)
                  (setq to 'downto)
                  (setq stop (prin1-to-string (nth 4 form)))
                  (if (and (eq (nth 5 form) nil) (> (length form) 5))
                      (setq stop (concat stop "()"))
                    (if (string-match "(" (prin1-to-string (nth 5 form)))
                        (setq stop (concat stop (prin1-to-string (nth 5 form))))
                      (if (eq (nth 5 form) 'step)
                          (setq step-size (prin1-to-string (nth 6 form))))))
                  )
                 (t
                  ;;(debug "Jean Michel Jarre: Oxygene III")))
                  ;;(debug "Joaquin Rodrigo")
                  (setq start (prin1-to-string (nth 4 form)))
                  (cond
                   ((eq (nth 5 form) 'to)
                    (setq to 'to))
                   ((eq (nth 5 form) 'downto)
                    (setq to 'downto))
                   (t
                    (debug "Dire Straits: Planet of New Orleans")))
                  (setq stop (prin1-to-string (nth 6 form)))
                  (if (eq (nth 7 form) 'step)
                      (progn
                        (setq step-size (and (nth 8 form) (prin1-to-string (nth 8 form))))
                        (assert (numberp (nth 8 form)))
                        )
                    )
                  )
                 )
                )
              ;;(debug "Rod Stewart's Maggie May")
              (progn
                (setq var         variable)
                (setq start-2     (warn--cull-quotes (warn--splat-quest start)))
                (setq stop-2      (warn--cull-quotes (warn--splat-quest stop)))
                (setq step-size-2 (warn--splat-quest (and step-size (prin1-to-string step-size))))
                ) ;; end PROGN!
              ;; -----------------------------------------------------
              ;;(debug "The Pretenders: Precious")
              (setq this_start     (concat this "start"))
              (setq this_stop      (concat this "stop"))
              (setq this_step      (concat this "step"))
              (setq this_step_size (concat this "step_size"))
              ;;(debug "My Parties")
              (insert (concat (concat "var " T " " this_start " = " start-2 "; ")
                              (concat "var " T " " this_stop  " = " stop-2  "; ")
                              (if step-size
                                  (concat "var " T " " this_step " = " step-size-2 "; "
                                          "var " T " " this_step_size " = "
                                          (cond
                                           ((eq to 'to)
                                            (concat "Math.abs(" this_step ")"))
                                           ((eq to 'downto)
                                            (concat "-Math.abs(" this_step ")"))
                                           (t
                                            (debug "Dire Straits: Heavy Fuel")))
                                          ";\n")
                                (concat "var " T " " this_step_size " = "
                                        (cond
                                         ((eq to 'to)
                                          "1")
                                         ((eq to 'downto)
                                          "-1")
                                         (t
                                          (debug "Dire Straits: Ticket to Heaven")))
                                        ) ;; end CONCAT!
                                )         ;; end if!
                              ";\n")      ;; end CONCAT!
                      )                   ;; end INSERT!
              ;;(debug "Rod Stewart: Hot Legs")
              (setq line 0)
              (setq p-prior
                    (save-excursion
                      (beginning-of-line)
                      (setq str (concat "^ \t*//+ " *pp-namespace* " #location0-9"
                                        " (\\("       *drive-spec*   "-a-zA-Z0-9_./+\\):\\(0-9+\\))"))
                      (if (or (looking-at str) (re-search-backward str nil t))
                          (progn
                            ;;(debug "Antonio Vivaldi")
                            (setq file (buffer-substring-no-properties           (match-beginning 1)
                                                                                 (match-end 1)))
                            (assert (stringp file))
                            (setq line (read-str (buffer-substring-no-properties (match-beginning 3)
                                                                                 (match-end 3))))
                            (assert (integerp line))
                            (point)
                            )
                        (setq file (concat *def-dir* *stump* ".jtw"))
                        (setq line 1)
                        (goto-char (point-min))
                        (forward-line 2)
                        (point)
                        )))
              (setq line (+ line (count-lines p-prior (point))))
              (decf line)
              (decf line)
              (insert (format "// %s (setq file-stack '%s)\n" *list-namespace* (prin1-to-string file-stack)))
              (insert (format "// %s #location3 (%s:%d)\n"    *pp-namespace*   file line))
              (insert (concat "for (var " T " " var " = " this_start ";"
                              " ((" this_step_size " > 0) ? " var " <= "
                              this_stop " : " var " >= " this_stop "); "
                              var " += " this_step_size ")"))
              (if strobe (debug "Pretenders: The Wait"))
              ;;(debug "Yehudi Menuhin")
              )))))

2.2 A bug in J.T.W. superfor

The question mark operator a ? b : c which expands to

Type result;
if (a) then
begin
    result = b;
end
else
begin
    result = c;
end

where type can be any Java type is not directly supported by the arguments to the superfor macro in J.T.W. Elsewhere the question mark is supported. Instead in the superfor macro you have to write the following code to get a question mark operator online:

class SuperFor
begin
    beginMain
        foo(1,2);
    endMain
    function void foo(int x, int y)
    begin
        superfor (var int i=0 to (x < y QUEST 10 : 20))
        begin
            System.out.print(" " + i);
        end
        System.out.println();
    end
end

where the symbol QUEST compiles into a question mark: ?. When built, the program prints out the following:

i=0
i=1
i=2
i=3
i=4
i=5
i=6
i=7
i=8
i=9
i=10

Next: , Previous: , Up: Top   [Contents][Index]