RCONN@SIMTEL20.ARPA (03/28/84)
From: Rick Conn <RCONN@SIMTEL20.ARPA> ZCPR3 - Command Processing When a ZCPR3 user issues a command, an involved sequence of tests and steps takes place in order to identify that command and execute it. This sequence is outlined briefly: 1) the command is parsed; the first word in the command line (or subline if semicolons are used to place several commands on one line) is taken to be the name of the command 2) ZCPR3 checks to see if this command is a Flow Command (IF/ELSE/FI/XIF), and, if so, ZCPR3 runs the command 3) ZCPR3 then checks to see if the current IF condition is TRUE; IFs may be nested eight levels deep under ZCPR3; if the current IF condition is TRUE, ZCPR3 continues, else it flushes the command and goes on to the next command 4) continuing, ZCPR3 then checks to see if the command is built into the ZCPR3 Command Processor itself; if so, ZCPR3 runs the command 5) ZCPR3 then checks to see if the command is built into the current Resident Command Package (RCP); if so, ZCPR3 runs the command 6) ZCPR3 then searches along a series of directories indicated by a command-search path for a COM file with the same name as the command; if found, ZCPR3 loads the COM file and runs it 7) finally, if all of the above fails, ZCPR3 invokes an error handler or an extended command processor to process the command as an error or to try to resolve it further Let's look at some examples: A0:BASE>work2: B1:WORK2>dir B1:WORK2 -- 0 Files Using 0K ( 302K Left) B1:WORK2>NOTE in many ZCPR3 systems, you will find RCPs - B1:WORK2>NOTE Resident Command Packages B1:WORK2>NOTE this system has several, located in the ROOT B1:WORK2>dir root:*.rcp SYS .RCP 2r| SYS1 .RCP 2r| SYS2 .RCP 2r| SYS3 .RCP 2r A15:ROOT -- 4 Files Using 8K ( 204K Left) B1:WORK2>NOTE SYS.RCP is the default RCP I use B1:WORK2>NOTE the H command tells the user what RCP he has loaded and B1:WORK2>NOTE what commands are available in it B1:WORK2>h SYS 1.0A CP ECHO ERA LIST NOTE P POKE PROT REN TYPE B1:WORK2>NOTE there are 10 commands in this RCP B1:WORK2>cp work2:=base:rhex.com Done B1:WORK2>dir RHEX .COM 2 B1:WORK2 -- 1 Files Using 2K ( 300K Left) B1:WORK2>cp rhex2.com=rhex.com Done B1:WORK2>dir RHEX .COM 2 | RHEX2 .COM 2 B1:WORK2 -- 2 Files Using 4K ( 298K Left) B1:WORK2>era *.com i RHEX .COM - Erase (Y/N)? n RHEX2 .COM - Erase (Y/N)? y B1:WORK2>cp rhex1.com=rhex.com;cp rhex2.com=rhex.com Done Done B1:WORK2>prot *.* r RHEX .COM Set to R/O RHEX1 .COM Set to R/O RHEX2 .COM Set to R/O B1:WORK2>dir RHEX .COM 2r| RHEX1 .COM 2r| RHEX2 .COM 2r B1:WORK2 -- 3 Files Using 6K ( 296K Left) B1:WORK2>prot rhex1.com RHEX1 .COM Set to R/W B1:WORK2>era *.com RHEX .COM is R/O RHEX1 .COM RHEX2 .COM is R/O B1:WORK2>dir RHEX .COM 2r| RHEX2 .COM 2r B1:WORK2 -- 2 Files Using 4K ( 298K Left) B1:WORK2>echo this command simply echos the command line, as in messages THIS COMMAND SIMPLY ECHOS THE COMMAND LINE, AS IN MESSAGES B1:WORK2>ed demo.txt NEW FILE : *i 1: This is a test 2: This is only a test 3: : *e B1:WORK2>cp demo2.txt=demo.txt Done B1:WORK2>dir *.txt DEMO .TXT 2 | DEMO2 .TXT 2 B1:WORK2 -- 2 Files Using 4K ( 294K Left) B1:WORK2>ren demo1.txt=demo2.txt B1:WORK2>cp demo2.txt=demo.txt Done B1:WORK2>dir *.txt DEMO .TXT 2 | DEMO1 .TXT 2 | DEMO2 .TXT 2 B1:WORK2 -- 3 Files Using 6K ( 292K Left) B1:WORK2>ren demo1.txt=demo2.txt DEMO1 .TXT - Erase (Y/N)? n B1:WORK2>type demo.txt This is a test This is only a test B1:WORK2>type *.txt This is a test This is only a test Typing DEMO .TXT - This is a test This is only a test Typing DEMO1 .TXT - This is a test This is only a test B1:WORK2>p 8000 801f;NOTE I look at memory Peek at 8000 8000 - C3 29 00 C3 CE 80 C3 47 81 C3 82 81 C3 67 81 C3 |C).CN.CG.C..Cg.C| 8010 - 7E 81 C3 E9 80 C3 22 81 C3 10 81 80 F3 00 00 11 |~.Ci.C".C...s...| B1:WORK2>p 0 f;NOTE anywhere in memory Peek at 0000 0000 - C3 03 E2 01 11 C3 06 D4 00 FF 00 FF 00 FF 00 FF |C.b..C.T........| B1:WORK2>poke 8000 1 2 3 "this is a test Poke at 8000 B1:WORK2>p 8000 801f Peek at 8000 8000 - 01 02 03 54 48 49 53 20 49 53 20 41 20 54 45 53 |...THIS IS A TES| 8010 - 54 81 C3 E9 80 C3 22 81 C3 10 81 80 F3 00 00 11 |T.Ci.C".C...s...| B1:WORK2>NOTE the RCP commands can be changed by loading a new RCP B1:WORK2>ldr root:sys3.rcp ZCPR3 LDR, Version 1.0 Loading SYS3.RCP B1:WORK2>h SYS 1.0C CP ECHO ERA NOTE P POKE REN TYPE WHL WHLQ B1:WORK2>cp demo3.txt=demo.txt No Wheel B1:WORK2>era *.txt No Wheel B1:WORK2>wheel system s WHEEL, Version 3.0 Wheel Byte is ON B1:WORK2>cp demo3.txt=demo.txt Done Now let's take a look at some examples of Flow Commands, invoked from Flow Command Packages (FCPs): B1:WORK2>NOTE now for Flow Command Packages: B1:WORK2>NOTE under FCPs, we have IF/ELSE/FI (ENDIF)/XIF (Exit All IFs) B1:WORK2>NOTE Flow Commands: B1:WORK2>if exist demo.txt IF T B1:WORK2>type demo.txt This is a test This is only a test B1:WORK2>else IF F B1:WORK2>type demo2.txt B1:WORK2>fi To No IF B1:WORK2>if ~exist demo.txt IF F B1:WORK2>type demo.txt B1:WORK2>else IF T B1:WORK2>type demo2.txt This is a test This is only a test B1:WORK2>fi To No IF B1:WORK2>if exist *.txt IF T B1:WORK2>type demo.txt This is a test This is only a test B1:WORK2>echo we are in a TRUE IF WE ARE IN A TRUE IF B1:WORK2>xif To No IF B1:WORK2>NOTE IFs can be nested up to 8 levels deep: B1:WORK2>if exist demo.txt IF T B1:WORK2>if exist demo2.txt IF T B1:WORK2>if exist demo.txt IF T B1:WORK2>if exist demo3.txt IF T B1:WORK2>else IF F B1:WORK2>fi To IF T B1:WORK2>fi;fi;fi To IF T To IF T To No IF And, of course, let's start to think about command files and command file processors. Under ZCPR3, ZEX, a memory-based command file processor, is designed to be the principal tool used. B1:WORK2>NOTE ZEX is the command-file processor, memory-based B1:WORK2>NOTE Under ZEX, there is a GOTO command which works B1:WORK2>NOTE in conjunction with IFs to provide looping capability B1:WORK2>ed demo.zex NEW FILE : *i 1: NOTE Set Register 1 to 0;reg s1 0 2: ;=loop 3: NOTE Exit all pending IFs;xif 4: NOTE Add 1 to Register 1;reg p1 5: NOTE Test for end of loop;if ~1 3 6: NOTE Branch to LOOP if Register 1 <> 3;goto loop 7: NOTE Done with IF if Register 1 = 3;fi 8: : *e B1:WORK2>type demo.zex NOTE Set Register 1 to 0;reg s1 0 ;=loop NOTE Exit all pending IFs;xif NOTE Add 1 to Register 1;reg p1 NOTE Test for end of loop;if ~1 3 NOTE Branch to LOOP if Register 1 <> 3;goto loop NOTE Done with IF if Register 1 = 3;fi Here is an actual run of a ZEX command file (DEMO.ZEX), illustrating looping: B1:WORK2>zex demo ZEX, Version 3.0 -- Pass 1 -- B1:WORK2> ZEX: NOTE Set Register 1 to 0;reg s1 0 REG, Version 1.0 Reg 1 = 0 B1:WORK2> ZEX: ;=loop B1:WORK2> ZEX: NOTE Exit all pending IFs;xif To No IF B1:WORK2> ZEX: NOTE Add 1 to Register 1;reg p1 REG, Version 1.0 Reg 1 = 1 B1:WORK2> ZEX: NOTE Test for end of loop;if ~1 3 IF T B1:WORK2> ZEX: NOTE Branch to LOOP if Register 1 <> 3;goto loop GOTO Label LOOP -- Pass 2 -- B1:WORK2> ZEX: NOTE Exit all pending IFs;xif To No IF B1:WORK2> ZEX: NOTE Add 1 to Register 1;reg p1 REG, Version 1.0 Reg 1 = 2 B1:WORK2> ZEX: NOTE Test for end of loop;if ~1 3 IF T B1:WORK2> ZEX: NOTE Branch to LOOP if Register 1 <> 3;goto loop GOTO Label LOOP -- Pass 3 -- B1:WORK2> ZEX: NOTE Exit all pending IFs;xif To No IF B1:WORK2> ZEX: NOTE Add 1 to Register 1;reg p1 REG, Version 1.0 Reg 1 = 3 B1:WORK2> ZEX: NOTE Test for end of loop;if ~1 3 IF F -- Done -- B1:WORK2> ZEX: NOTE Branch to LOOP if Register 1 <> 4;goto loop B1:WORK2> ZEX: NOTE Done with IF if Register 1 = 3;fi To No IF B1:WORK2> ZEX: Done> -------