BASIC TACL COURSE English Version, March 2005
title
Beginners TACL Course
version, date
English Version, t November jjjj
Author
Dean Southall –
[email protected]
Index BASIC TACL COURSE....................................................................1 BASIC TACL COURSE....................................................................1 BASIC TACL COURSE....................................................................1 BASIC TACL COURSE....................................................................1 BASIC TACL COURSE....................................................................1 BASIC TACL COURSE....................................................................1 BASIC TACL COURSE....................................................................1 BASIC TACL COURSE....................................................................1 1. INTRODUCTION..........................................................................1 1.1 . General.......................................................................................1 2. TACL................................................................................................2 2.1 style & Standards........................................................................2 2.2 . TACL Variables........................................................................2 2.2.1 . Aliases ................................................................................3 2.2.2 . text.......................................................................................3 2.2.3 . Macro’s...............................................................................3 2.2.4 . Routine’s.............................................................................4 2.2.5 . Struct’s................................................................................5 2.2.6 . Def’s....................................................................................5 2.2.7 . Directories..........................................................................6 2.2.8 . Everything you wanted to know about variables but were afraid to ask .........................................................................7 2.3 . General TACL tricks.................................................................7 2.3.1 . Be Nice................................................................................7 2.3.2 . Error Handling (only routines)........................................8 2.3.3 . Object Orientated?............................................................8 2.3.4 . TACL & Processes & files................................................9 2.3.5 . Defined Processes..........................................................10 2.3.6 . Debugging........................................................................11 2.3.7 . TACL Segments................................................................11 2.3.8 . TACL & Netbatch............................................................12 3. APPENDICES................................................................................13 3.1 . create^segment........................................................................13 3.2 . Defined Processes...................................................................15
R
Beginners TACL Course English Version
1
1. Introduction 1.1
. General
The high level language TACL (Tandem’s Advanced Command Language) is a Command Line Interpreter (CLI). It is interpreted code and therefore fairly expensive in processor time compared to compiled code. This is just a basic course. After this course you can use the 2 TACL manuals :TACL Reference Manual TACL Programming Guide In order to use this manual you must have Basic Tandem knowledge, the more the better.
R
TACL Cursus English Version
1
2. TACL 2.1
style & Standards
Look at the TACL Programming Guide page 1.2 for good style tips. TANDEM written macros/routines begin with _ or ^ thus your macros must never begin with _ of ^. You can use _ or ^ in the names of your macros e.g. tedit^file of kill_process.
2.2
. TACL Variables
TACL is interpreted code (thus not compiled). The command of TACL can heavily tax the system. You write TACL efficiently so as not to hammer the system. There are 3 different ways to execute TACL code: 1) Run 2) Load/ KEEP 1/ 3) Usage of segment files A good example of 1) is your TACLCSTM (TACL custom) file. Everyone has their own copy. It's used to customise your TACL environment, to load TACL macros etc. etc. Here below is an example of a TACLCSTM file: ?TACL ROUTINE #SET #INFORMAT TACL #SET #OUTFORMAT PRETTY ATTACHSEG SHARED $DATA.DEAN.LOGSEG :LOGSEG USE :LOGSEG [#uselist] PMSG ON == shows the process number as a process starts [#IF [#INTERACTIVE] |THEN| :logseg:sp ] RUN $DATA.DVNIBMT.BBSLOGON param pathmon-name $PMW dpp == define process peruse (comments in a macro begins with ==) [.....] means :- the value of something |THEN| |ELSE| etc. are ‘labels’ and belong always to a multi row/complex functions e.g. #IF #CASE etc. The other 2 ways will be described later. There are 8 sorts of TACL variables: Macro’s Routines Directories text Aliases Struct’s Def’s Delta's.
R
TACL Cursus English Version
2
2.2.1
. Aliases
These are the simplest TACL variables. They are useful for shortcuts. ?SECTION t ALIAS tedit Instead of tedit you only have to type a t. e.g. T $DATA01.DEAN.TACLCSTM 2.2.2
. text
These are the default variables commonly used to hold values e.g. #PUSH name == make a variable #SET name Dean == give the variable a value #OUTPUT My name is [name] == show on the screen #POP name == remove the variable All #xxxx command's are codes of the Guardian operating system and written in TAL or C. Many of this commands are comparable with COBOL system calls. 2.2.3
. Macro’s
Macro's and routines are the programming language of TACL. They can exist independently in a file (with ?TACL MACRO as 1st row) or in a library file with other macro’s and routines. There is no error handling possible in a macro. ?SECTION t MACRO #OUPUT Tediting %1%. TEDIT %1% %2% == %1% and %2% are parameters If you type in: T TACLCSTM R then TACL will do the following :1) Reads the macro 2) replaces %1% door TACLCSTM 3) replaces %2% door R 4) runs the macro (thus: TEDIT TACLCSTM R) Macro’s are simple and quick to make and are very useful for small pieces of code. As they become bigger, they become more difficult to read (who knows what %9% means after 100 rows of code?) and slower because TACL a macro must be read twice read because the parameters have to be filled in first before execution can take place.
R
TACL Cursus English Version
3
2.2.4
. Routine’s
Routine's are more complex than macro’s but give more functionality: 1) You can write your own error handling. 2) You can control the parameters. 3) you can return a value back to the calling routine/macro. 4) you can a exit a routine whenever you want. ?SECTION T ROUTINE #FRAME #PUSH filename type #SET type [#ARGUMENT / VALUE filename / FILENAME WORD] [#CASE [type] |1| [#IF [#FILEINFO / OPENNOW / [filename]] |then| #OUTPUT Sorry guy! [filename] is already open |else| [#IF [#FILEINFO /CODE/[filename]] = 101 |then| tedit [filename] A [#REST] |else| #OUTPUT Sorry guy! [filename] is not an edit file ] ] |2| [#IF [#match [#INPUT [filename] exists not, create?] Y] |then| tedit [filename] ! ] ] #UNFRAME
1) All variables made pushed (created) after the 1st #FRAME are automatically deleted after the #UNFRAME (you can #POP xyz but #UNFRAME is easier). You can use frames in routines and macro's. 2) [filename] contains the value of the filename. If the filename is $data.dean.taclcstm, then the command #OUTPUT filename [filename] displays the following :filename $data.dean.taclcstm 3) #ARGUMENT is comparable to %n% in a macro. Value filename means: stead here the value of the 1st parameter. As you #ARGUMENT for the 2nd time uses than reads he the 2nd parameter etc. Before the value of the parameter in #ARGUMENT is replaced, TACL looks in the check-list after the 2nd “/”. First it checks if the parameter is a filename or a word. If either of these are true then TACL the value in filename and the value of the bit between brackets is 1 if it's a filename and 2 if it's a word. If neither is true then uses TACL the standard error handling and crashes with : expecting the name of an existing file or any text up to a standard TACL separator or end You can avoid that TACL does this standard error-handling with help of the command OTHERWISE (comparable with the WHEN OTHER statement of EVALUATE). You can do your own error-handling and output your own (hopefully more meaningful!) error messages. There are very many possibilities after the “/’. Look in the “TACL REFERENCE MANUAL”, I've only shown a couple here Very many Guardian routines give a value back. #ARGUMENT returns the number of the appropriate type. In the example you get the value 1 as the parameter is a filename and the value 2 if the argument is a word. 4) #CASE is similar to evaluate in COBOL85. An alternative is: #IF type = 1 |THEN| ........ |ELSE| ....... 5) [#FILEINFO /OPENNOW /[FILENAME]] and [#IF [#FILEINFO /CODE/[FILENAME]] = 101
R
TACL Cursus English Version
4
are also very interesting. With the 1st command ask you Guardian of the file [filename] is open. Guardian responds with true (value -1 non-null-value) or not true (value 0). This is easy to test with #IF. The 2nd command doesn't return a true/not true value, but the filecode of the file. 6) #INPUT waits for input from of the user and gives as value the input. e.g. #SET filename [#INPUT ...] 7) #MATCH can you use to compare 2 strings. The value returned is 0 (strings are different) or -1 (strings are the same). There are a number of differences between TACL routines/macro's and obey-files. If there's a ?TACL ROUTINE or a ?TACL MACRO as the 1st row then you see only the output of every row; in an obey file you see the command and the output. A TACL file you start with the command RUN; an obey file with the command OBEY. The difference between a TACL routine and a TACL macro is that a routine is parsed just once and a macro twice. Thus it is better to make your TACLCSTM file a ROUTINE than a macro. 2.2.5
. Struct’s
This are TACL ‘records’. You can make TACL records with DDL (Data Dictionary Language). This happens in the same way as with COBOL. Thus if you have DDL source, can you quickly create TACL struct's e.g. : 1 ?TACL Output source for TACL is opened on $ZTN0.#WIN0027 2 output def p10559. Loading Definition P10559 == SCHEMA PRODUCED DATE - TIME : 5/18/90 14:49:49 == Definition P10559 version 1 updated on 05/01/90 at 15:55 == NE05Z00A ?Section P10559 Struct Begin == Function-CODE INT E41330; == GUARDIAN NUMBER-FILENAME INT E41331; == MESSAGE-NUMBER INT E41332; == CODE-PROGRAM-RPCN STRUCT E41333; BEGIN CHAR BYTE(0:9); END; == PROGRAM data == ABEND-indicator CHAR E41342; End; TACL output produced for P10559.
See the TACL manual for a description. See also paragraph 2.2.4. over TACL & Netbatch for the _completion struct. 2.2.6
. Def’s
Def’s are local versions of TACL-variables. Thus in a macro/routine you can make local versions of macros, routines, struct’s etc. which disappear (if you use #FRAME and #UNFRAME) when the routine finishes. N.B: END is a useful argument for #ARGUMENT. This means ‘no argument’ is also valid. We see also the usage of the command #LOOP. There are 2 versions of this command: 1) #LOOP |while| condition |do| ……. 2) #LOOP |do| ….. |until| condition |while| checks the condition for the loop as it begins. |until| executes the loop first and then checks the condition after each
R
TACL Cursus English Version
5
loop. #APPEND ‘appends’ onto a variable; the variable becomes a list/stack. We'll see more examples later of #APPEND. #RESULT works only in routine’s. The gives a value back to the calling routine/macro. #TIMESTAMP shows how many seconds there have been since midnight of 31st December 1974. Exciting eh! There are a lot functions to translate this to something more useful (see the TACL manual). Here below are a number of examples e.g. #OUTPUT [#TIMESTAMP] #OUTPUT [#CONTIME [#TIMESTAMP] ] #OUTPUT [_CONTIME_TO_TEXT_DATE [#CONTIME [#TIMESTAMP]]]
gives …. 70670204971 1997 5 23 10 7 58 20 May 23, 1997 2.2.7
. Directories
You can organise all TACL-variables in directories. You can compare them with directories on the PC. The difference between directories and volumes.subvolumes is, that directories stay in memory and volumes.subvolumes are on disk. On the Tandem you use #PMSEARCHLIST in order to tell Guardian where to search for programs and #USELIST for your TACL variables: e.g. #SET #PMSEARCHLIST $SYSTEM.SYSTEM $DATS.NE00YRUN USE :DEANSEG [#USELIST]
Try executing the following 3 commands at the TACL prompt: #PMSEARCHLIST #USELIST ENV
Question: What happens? SEGINFO is useful to tell you what segments you have attached and some details about them. Seginfo…… Pgs Pgs Bytes Bytes Segment File Access Now Max Now Max % UC Directory $datf.#0008763 pr 24 1024 27332 2097152 11 : $system.sys02.taclsegf sh 208 1024 420308 2097152 20 3 :utils.1 $dats.ne00ytcl.interseg sh 112 1024 226700 2097152 10 1 :internet.1 $datf.dean.deanseg sh 332 1024 667960 2097152 31 1 :deanseg.1 $datf.dean.DEANseg sh 616 1024 1257072 2097152 59 1 :DEANseg.1 $datf.dean.DEANseg2 sh 716 1024 1459540 2097152 69 1 :DEANseg2.1
1
The utils directory/segment $system.sys02.taclsegf contains Tandem’s TACL’s. If you type “Variables :UTILS” you get as output the content of the directory. :utils. It's always shared (sh in the access column) and that means that everyone in this directory may read, but not write to it. The : is your root directory. When you #push to create variables or use the LOAD command to load libraries, they will normally go here. All other directories hang off the root directory (use “VTREE” to see this).
R
TACL Cursus English Version
6
You load macro’s with: LOAD /KEEP 1/ You can change directory with home : As you the name of a variable type in, then TACL searches first in the current directory and after that in every other directory in the #USELIST. You can type “VARINFO “ to see summary info of a macro/routine/text variable e.g. VARINFO volume You can see the content of a macro with of OUTVAR e.g. OUTVAR volume OUTVAR OUTVAR exercise : Try but the above 3 TACL command’s. 2.2.8 . Everything you wanted to know about variables but were afraid to ask
TACL uses a stack for every variable. Thus as you do this #PUSH x y z #SETMANY x y z,1 2 3 == multiple of #SET #PUSH y z #OUTPUT [x] [y] [z]
Then get you 1 on the screen because the 2 newest versions of y and z are empty. You can still see and use the old values :#OUTPUT [x.1] [y.1] [z.1]
You can use #POP to delete the new values e.g. #POP x y z Question: Can you #POP also use to delete old values? e.g. #POP x.1 Answer: No, not unless it's the highest in the stack, which it isn't in this case. If you use LOAD without the KEEP 1 option, then make you always a new copy on top of the old in the stack. If you do this often then you'll start using up lots of memory! Question: LOAD /KEEP 0/ is a valid statement. What does it do?
2.3
. General TACL tricks
2.3.1
. Be Nice
A user generally prefers that his environment isn't changed after a macro has ended. Take copies of variables you plan to change e.g #DEFAULTS (this keeps track of your current subvol). This be achieved with use of framing & popping: #PUSH #DEFAULTS Volume $datf.work ............. macro #POP #DEFAULTS
R
TACL Cursus English Version
==#DEFAULTS.2 created. ==#DEFAULTS now = $datf.work == the core of your ==back to the subvolume where you == started NOT on $datf.work
7
2.3.2
. Error Handling (only routines)
[#CASE [#EXCEPTION] |_CALL| == normal entry point for this ROUTINE |_BREAK| == break key handling #OUTPUT Session terminated because the break key was hit #UNFRAME #RETURN |_ERROR| #PUSH errtxt #ERRORTEXT /CAPTURE errtxt/ #OUTPUT Tacl generated error filtered #OUTPUT error text contains : #OUTPUTV ERRTXT #UNFRAME #RETURN ] == end of exception case #FILTER _BREAK _ERROR
This piece code MUST be on the 1st line in a routine! Otherwise the error-handling won't work properly! Question: In the above TACL-variable there's #OUTPUT and #OUTPUTV. What is the difference between these command's? 2.3.3
. Object Orientated?
With TACL you can quickly build up a library of routines. Make the routines object-orientated (thus ‘black boxes’), so you can use them again and again. Give them logical names and use #RESULT to return true or false values if you can ?SECTION is_valid_define ROUTINE #FRAME #PUSH define^name [#CASE [#ARGUMENT /VALUE define^name/ DEFINENAME WORD END] |1| #RESULT -1 == valid define name |OTHERWISE| #RESULT 0 == invalid define name ] #UNFRAME ?SECTION is_valid_file ROUTINE #FRAME #PUSH filename [#CASE [#ARGUMENT /VALUE filename/ FILENAME/SYNTAX/ WORD END] |1| #RESULT -1 == valid filename |OTHERWISE| #RESULT 0 == invalid filename ] #UNFRAME ?SECTION DBU ROUTINE #FRAME #PUSH #DEFAULTS options filename #OUTFORMAT #SET #OUTFORMAT PRETTY [#IF [#MORE] |THEN| #SET filename [#REST] [#IF [is_valid_define =[filename]] |THEN| < doe something here> ] [#IF [is_valid_file [filename]] |THEN| #SET options ,FILE [filename] |ELSE| #SET filename [#REST] ]
R
TACL Cursus English Version
8
] [#IF [#VARIABLEINFO/EXISTENCE/ vol_1] AND [#VARIABLEINFO/EXISTENCE/ & env_name] A < doe here something> ] #UNFRAME
In the 2 subroutines “is_valid_.....” there is no usage made of external variables. They give a true/not true value back. In this example see you also again the usage of #ARGUMENT and #RESULT. New command's: #VARIABLEINFO has a number of possibilities. In this example EXISTENCE checks if a TACL variable exists or not. This gives always 0 of -1 back. #MORE and #REST are only useful in routines. With #MORE can you check if there are more arguments. If there are more arguments available then it gives -1 back, otherwise 0. This is useful if you want to process a list of files but you don't know how many. With a combination of #LOOP and #MORE you can process the whole list. #REST returns all of the unread arguments in one job lot. This is useful as not all parameters of important are for TACL: e.g. TEDIT [filename] [#REST] the
==#REST has no value of contains parameters for
TEDIT
Questions : 1. The other possibilities of #VARIABLEINFO are in the TACL manual. What possibilities are there. 2. Write an example that #LOOP and #MORE that uses a list of filenames to and displays them in a nicer way on the screen. Use [#FILENAMES] as input e.g. display_files [#FILENAMES] 3. what do #OUTFORMAT and #INFORMAT do? why in the DBU example is #OUTFORMAT pushed? 2.3.4
. TACL & Processes & files
EDIT/in infile,out outfile,nowait/ EDIT/inv edit_in DYNAMIC,outv edit_out,nowait/ Maybe can you guess what the 2nd command does as you (hopefully!) know what the 1st line does. Here can you make good use of #APPEND and #EXTRACT e.g. ?TACL ROUTINE #FRAME #PUSH ipm results edit^level next fup purgedata $datf.dean.DEANTACL EDIT /INV ipm DYNAMIC ,OUTV results,NAME, NOWAIT/ SINK [#WAIT ipm] #SET results #SET next [#FILENAMES/MAXIMUM 1/*] [#LOOP |WHILE| NOT [#EMPTYV next] |DO| [#IF ([#FILEINFO/CODE/[next]] = 101) AND ([#FILEINFO/EOF/[next]] > 0) AND (NOT [#FILEINFO /OPENNOW/[next]]) |THEN| #OUTPUT [next] #APPEND ipm GET [next] put $datf.dean.DEANtemp! #APPEND ipm CB /?TACL/?SECTION [next]/ A #APPEND ipm GET $datf.dean.DEANTACL #APPEND ipm GET $DATF.DEAN.DEANtemp TO L
R
TACL Cursus English Version
9
SINK [#WAIT ipm] #OUTPUTV results #SET results |ELSE| #OUTPUT Problem with [next] fi [next] ] #SET next [#FILENAMES/MAXIMUM 1,PREVIOUS [next]/*] ] == END LOOP #APPEND ipm EXIT SINK [#WAIT ipm] #UNFRAME
DYNAMIC means that the program runs until an exit-command is received. You can first fill in ipm and after that EDIT /inv ipm, ......, but if you use the above way than you can do nowaited processing. You use #APPEND (