Article View: comp.sys.amiga.tech
Article #673Re: Solution for EXECUTE: No K Directive (long)
From: Rob Peck
Date: Tue, 01 Aug 1989 17:33
Date: Tue, 01 Aug 1989 17:33
302 lines
12819 bytes
12819 bytes
In article <696@jc3b21.UUCP> fgd3@jc3b21.UUCP (Fabbian G. Dufoe) writes:
>From article <3020@blake.acs.washington.edu>, by dlarson@blake.acs.washington.edu (Dale Larson):
>> importantly, why could I find no reference whatsoever to this error message
>> in any description of EXECUTE or on any page listed under "error" in the
>> index of any Amiga documentation? (Maybe I forgot to put on my glasses :-)
It was suggested in an earlier answer that just using the .bra and .ket
as the first two lines of your file would make the "No K directive" error
go away. For some reason, this did not work for me, and I finally put
a ".key dummy" as the very first line. This got rid of the error.
AmigaDOS seemed to be telling me that if I was doing ANY variable substitution
(in a test script, I was using the {$$} stuff, similar to that described
below) but no OTHER variable substitution in a much smaller script,
and I still got the error. The AmigaDOS manual says that if you want
to do any variable substitution, that the first line of the script
must start with a ".", so the use of .bra { and .ket } should
have been enough. But it was not. I dont have the machine here, but
I THINK this is all I was doing:
.bra {
.ket }
echo "The CLI Process that is running me is: {$$}"
and IT generated this error (NO K Directive), so I added .key dummy
as the first line and it went away. Hmmm. Ah well, thats MY solution.
If you want a tutorial approach writing of scripts that can be EXECUTEd,
I put a whole chapter on that topic into the Amiga Companion, and even
included an explanation of the startup-sequence, in English so to speak.
Anyone who has tried to decipher the example for "EVAL" in the 1.3
enhancer docs will also appreciate the new explanation that is in the
Second Edition of the Companion. I found that the example itself is
very clever and contains a couple of useful tricks, but with no documentation
to support it, it took a while to figure it out. For those who have not
seen the Companion yet, here is what I tell folks about EVAL (starts on
page 161 and runs to page 165 of the second edition)
Note that this is the "UNEDITED" version of the material. It is as
submitted to Amiga World as the "Please insert this material into
the first edition of the Companion to create the second edition." So
they may have trimmed a few words but told me that the concepts and
examples have remained intact.
========================
Using EVAL To Aid Decision Making
The EVAL command has been added to 1.3 to let you do simple
arithmetic. EVAL is like IF, but where IF compares strings,
EVAL compares strings-as-numbers. The command template for
EVAL is:
VALUE1/A,OP,VALUE2,TO,LFORMAT/K:
which means that you MUST provide at least one parameter
If no operation or other parameter is specified,
the answer evaluates to that of the first parameter.
1> EVAL 695
695
1>
EVAL works with integer values (whole numbers) only, and
you can specify an operation to perform on two integer values.
You specify the operation by using a particular symbol, as
contained in the table below. Eval accepts the symbol either
by its expected position (between the two values, as with normal
arithmetic) or by the keyword method (common to most if not
all AmigaDOS commands).
1> EVAL 4 * 6
24
1> EVAL VALUE1 4 VALUE2 6 OP *
24
1>
Here are all of the available operations that EVAL can perform,
along with the "operator" that EVAL recognizes for this operation:
Operation Operator Result
========= ======== =========================
Addition + Value1 + Value2
Subtraction - Value1 - Value2
Multiplication * Value1 * Value2
Division / Value1 / Value2
Modulo mod Remainder after Value1/Value2
AND & Bits in both Value1 and Value2
OR | Bits in either Value1 or Value2
NOT ~ Zero bits become one bits and VV.
Left Shift << Shift the Value1 bits left by
Value2 bit positions
Right Shift >> Shift the Value1 bits right by
Value2 bit positions
Negation - Placed before any value, that
value is treated as negative
(unary minus)
Exclusive OR xor Exclusive-OR function
Bitwise Equivalence eqv Equivalence function
Many of these operations are performed by programmers. If you
want more information about the operations other than the simple
arithmetic, I'd suggest you look into a book on logic programming
or programming in C.
The TO keyword lets you redirect the output of the EVAL command to
a file. This can be quite useful in command scripts because the contents
of the file can be read later and used to make operating decisions.
An example:
1> EVAL 12 mod 7 TO ENV:remainder
1> GETENV remainder
5
1>
The other keyword, LFORMAT, lets you tell EVAL how to output its
answer. You provide a format string, and EVAL will put the answer
out using that format. For example the number can be formatted as
decimal (specify %N somewhere in the output string), or in hexadecimal
(specify %X), or in octal (specify %O). When using other than
decimal, you can also tell EVAL how many digits to output by specifying
the number of digits following the specification. For example,
to use 8 hexadecimal digits, specify %X8. There is also a special
character sequence that EVAL recognizes (*N) to place a newline
into your output string:
1> EVAL 256 LFORMAT "256 decimal = %X8 hexadecimal*N"
256 decimal = 00000100 hexadecimal
1>
Without the *N in there, it has the same effect as the NOLINE
switch to the ECHO command. The next output simply appears on
the same line, in the next available character position.
The default input integer values are decimal, but if you
tell EVAL that a number is hexadecimal (by prepending "0x" or "#x" to
it), or octal (by prepending a leading zero or a #-sign to it),
EVAL correctly interprets the value:
1> EVAL 127 + 1
128
1> EVAL 0x7F + 1 ;hexadecimal
128
1> EVAL 0177 + 1 ;octal
128
1> EVAL #x7f + 1 ;hex again
128
1> EVAL #177 + 1 ;octal
128
1>
Now that you know what EVAL can do, lets look, line by line,
at an example command script that was provided with the AmigaDOS
1.3 Enhancer kit. What you'll see here is a slight revision
of the original script.
The script file that uses EVAL to form a loop. I commented each
line but you can leave out the comments if you try it. Remember
that at least the .key statement and any other dot-statement
should start in column 1:
.key command/a,howmany/a
; Both parameters are needed
.bra {
.ket }
; Allow left/right arrows for redirection
; so give EXECUTE an alternate for enclosing
; its parameters (alternate BRA(c)KET(s))
ECHO >ENV:loop {howmany}
; Incoming loop value stored in environment
; variable so that we can read it later and
; test its value.
;
LAB BEGIN
;
; The start of a loop
; Execute command NOW, assumes at least ONE pass.
;
ECHO "This is loop number " NOLINE
GETENV loop
;
; Now we are going to modify the loop value by using
; EVAL to do it. Get the value, change it (subtract
; one), then put it back and loop to BEGIN if the
; value still has not reached zero.
;
EVAL <ENV:loop >NIL: TO T:junk{$$} VALUE2 1 OP - ?
;
; This one is just a little tough to explain, but
; here goes:
;
; 1. The specification "<EVAL:loop" says that we are
; using AmigaDOS I/O redirection to take the input
; for the command from a file (ENV:loop) instead
; of from the user directly.
;
; 2. The "?" at the end of the line tells EVAL that
; it should accept some input from somewhere, and
; because of the input redirection, that somewhere
; is the contents of the environment variable (file)
; named "loop". This file contains not only the
; value itself, but also a linefeed character which
; has the same effect as the user pressing return
; after typing some command followed by a question
; mark.
;
; 3. The parameter ">NIL:" is a command to redirect
; the output of the command to a file instead of
; to the screen. This prevents the command template
; from being printed to the screen.
;
; 4. The parameter spec "TO T:junk{$$}" says to take
; the real output (the answer) of EVAL, and put it
; into a file and that file should have a unique
; name. If running from CLI 1, then the file name
; will be T:junk1; if running from CLI 2, the file
; name will be T:junk2 and so on.
;
; 5. Finally positional parameters are used to tell
; EVAL what it is supposed to do. We establish
; VALUE2=1 and OP=-, in other words, whatever we
; read from ENV:loop will have 1 subtracted from
; it and the result goes into a uniquely named
; temporary file.
;
; This complicated method had to be used because
; EVAL does not know how to read environment
; variable values (IF knows how) directly, so we
; have to take advantage of the "?" capability to
; fool EVAL into reading the value from the file.
;
TYPE >ENV:loop T:junk{$$}
;
; Why not say:
; COPY FROM T:junk{$$} TO ENV:loop
;
; Well, TYPE always puts a newline character as the
; final character output, but COPY copies only what
; is there. EVAL may or may not (depending on whether
; LFORMAT is used). So this is a just-in-case so
; that we can guarantee that there will be at least
; one newline in the file for EVAL to read on the
; next loop around.
;
IF val $loop GT 0
;
; Test the present value of loop counter, may exit.
;
SKIP BEGIN BACK
;
; If the test is true, go back and restart script.
;
ENDIF
;
DELETE T:temp{$$} T:temp2{$$} T:doit{$$}
ECHO "Done"
Bug Alert (SKIP Command)
---------
If one command script calls the EXECUTE function from within
the script, the SKIP command, even though told to skip BACK,
can no longer find the target label for the SKIP. (This deficiency
is actually built into EXECUTE.) So if your command file needs
to use the BACK option of switch, do not call EXECUTE from within
the script. If you need to call EXECUTE, then follow the menu
script example instead, and make the script call itself as it
exits.
==========================
I don't know who at CATS actually supplied the example for the use of
EVAL in the 1.3 enhancer docs, but I really DO think it is clever and
its one of those things that is a "forehead slapper" when you realize
"hey, that's a real neat way to do it", specifically EVAL <ENV:loop.
Based on the knowledge that Andy Finkel did the Menu example that I
explained and expanded on for the first edition of the Amiga Companion,
I 'suspect' that he did this one too. But my congradulations to WHOEVER
at CATS did this example.
Actually, one seldom thinks of using the '?' feature at all. Normally
when trying to get user input, you automatically think of using the
ASK command, and you only have a chance to get Y/N answers, and SKIP
to something on that basis. However, using the '?' with the SKIP
command lets you get any kind of answer and as long as what the user
enters matches a particular label and you tell the user what the labels
are, it gives added flexibility. That idea WAS Andy's and we acknowledged
it in the first edition of the Companion, in the Menu example.
AREXX is fun and more flexible than the commands that you have now on 1.3,
but it seems now WITH 1.3's command set, that there are at least more
chances to workaround problems and more possibilities to solve problems
than ever.
Thanks, CATS. I'm having fun just learning to use the latest features.
Once I "know it all", I guess I'll be ready for 1.4. :-)
Rob Peck
Technical Details
Message-ID:
<7686@ardent.UUCP>Path:
arc1-ca.pugleaf.net!utzoo!attcan!utgpu!jarvis.csri.toronto.edu!mailrus!iuvax!cica!ctrsol!lll-winken!ubvax!ardent!peck!rapReferences:
<3020@blake.acs.washington.edu> <696@jc3b21.UUCP>Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!attcan!utgpu!jarvis.csri.toronto.edu!mailrus!iuvax!cica!ctrsol!lll-winken!ubvax!ardent!peck!rap From: rap@peck.ardent.com (Rob Peck) Newsgroups: comp.sys.amiga.tech Subject: Re: Solution for EXECUTE: No K Directive (long) Message-ID: <7686@ardent.UUCP> Date: 1 Aug 89 17:33:11 GMT References: <3020@blake.acs.washington.edu> <696@jc3b21.UUCP> Sender: news@ardent.UUCP Reply-To: rap@peck.ardent.com (Rob Peck) Organization: Ardent Computer Corp., Sunnyvale, CA Lines: 302