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)
  ;;(checkpoint "2")
  (save-excursion
    ;;(setq parse-sexp-ignore-comments t)
    (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))
        ;;(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")
          (when (and (not (eq (nth 0 form) 'char))
                     (not (eq (nth 0 form) 'short))
                     (not (eq (nth 0 form) 'int))
                     (not (eq (nth 0 form) 'long))
                     (not (eq (nth 0 form) 'float))
                     (not (eq (nth 0 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
            (setq type (nth 1 form))
            (setq T (prin1-to-string type))
            (setq variable (nth 2 form))
            (setq variable-equals (prin1-to-string (nth 2 form)))
            (if (string-match "=" variable-equals)
                (progn
                  (setq variable (read-str (substring variable-equals 0 (match-beginning 0))))
                  (setq start    (read-str (substring variable-equals (match-end 0))))
                  (if (eq (nth 3 form) 'to)
                      (setq to 'to)
                    (if (eq (nth 3 form) 'downto)
                        (setq to 'downto)
                      (assert "The Bug")))
                  (setq stop     (nth 4 form))
                  (if (eq (nth 5 form) 'step)
                      (setq step-size (nth 6 form))
                    ;;(setq step-size 1)
                    ))
              (assert (or (eq (nth 3 form) '=)))
              ;;(debug "Joaquin Rodrigo")
              (setq start (nth 4 form))
              (if (eq (nth 5 form) 'to)
                  (setq to 'to)
                (if (eq (nth 5 form) 'downto)
                    (setq to 'downto)
                  (assert "Planet of New Orleans")))
              (setq stop (nth 6 form))
              (if (eq (nth 7 form) 'step)
                  (progn
                    (setq step-size (nth 8 form))
                    ;;(assert (numberp (nth 8 form)))
                    )
                ;;(setq step-size 1)
                )
              ))
          (d-quote
           (debug "Rocket Queen")
           (setq type "")
           (setq T "double")
           (setq variable (nth 0 form))
           (assert (eq (nth 1 form) '=))
           (setq start (nth 2 form))
           (if (eq (nth 3 form) 'to)
               (setq to 'to)
             (if (eq (nth 3 form) 'downto)
                 (setq to 'downto)
               (debug "My Michelle")))
           (setq stop (nth 4 form))
           (if (eq (nth 5 form) 'step)
               (setq step-size (nth 6 form))))
          (setq var         (prin1-to-string variable))
          (setq start       (prin1-to-string start))
          (setq stop        (prin1-to-string stop))
          (setq step-size-2 (prin1-to-string step-size))
          (setq start       (warn--splat-quest start))
          (setq stop        (warn--splat-quest stop))
          (setq step-size-2 (warn--splat-quest step-size-2))
           -----------------------------------------------------
          (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 ";")
                          (concat "var " T " " this_stop  " = " stop  ";")
                          (if step-size
                              (concat "var " T " " this_step " = " step-size-2 ";"
                                      "var " T " " this_step_size " = "
                                      (if (eq to 'to) (concat "Math.abs(" this_step ")") (if (eq to 'downto) (concat "-Math.abs(" this_step ")") (debug "Heavy Fuel"))) ";\n")
                            (concat "var " T " " this_step_size " = " (if (eq to 'to) "1" (if (eq to 'downto) "-1" (debug "Ticket to Heaven"))))) ";\n"))
          (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 default-directory *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 ")"))
          ;;(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]