Next: J.T.W. Proof of concept #2 file inclusion, Previous: About GNU Java Training Wheels, Up: Top [Contents][Index]
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 = 0to
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 = 0to
10step
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 = 10downto
0step
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 = xto
(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
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") )))))
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
SuperForbegin
beginMain
foo(1,2);endMain
function
void foo(int x, int y)begin
superfor
(var
int i=0 to (x < yQUEST
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: J.T.W. Proof of concept #2 file inclusion, Previous: About GNU Java Training Wheels, Up: Top [Contents][Index]