IMD 1.16: 1/06/2007 10:06:54 FOGCPM.174 --FOGCPM174JRTMAN 1028 JRTMAN 104 JRTMAN 105 JRTMAN 105< !"#$-04-00 87 JRTMAN APA%&'JRTMAN APB()JRTMAN APC*+,JRTMAN APD-.JRTMAN APEf/0123456789:;JRTMAN APF<=EPRO COM.>?@ABCEPRO DOC^DEFGHIJKLMNOSAMPLE PROPSCIAM PRO QRCANTONESDOCSTUVWXYZ[\]^_`abCANTONESDOCcdefghijklmnopqrCANTONESDOCstuvwxyz{|}~CANTONESDOC-CPM174 DOCCAN BASCAN BASRLESSONEW LESSONEX LESSONEY LESSONEZ SCORE SP SORT COM PRINT MM This is the disk name.  JRT Pascal User's Guide version 3.0 NOT FOR SALE -136- 12. External Procedures and Functions External procedures are a facility for segmenting programs into separately compiled modules. With these, the size of the entire program can be practically unlimited. This is because, unlike with segment procedures, overlays or chaining, the virtual storage manager loads, and when necessary deletes, program sections automatically. This makes the actual storage of the computer seem much larger than it actually is. Refer to the previous section on storage management for a full description of virtual/dynamic storage. External procedures are loaded into dynamic storage by EXEC when they are first referenced, unless they were linked with the main program to form one module (see section 8 for a description of the linker). The loading is transparent to the programmer in that no planning or effort is required. External procedures which are not linked with the main program remain in storage once they are loaded unless a short-on-storage condition occurs, then the least-recently-used procedure may be deleted. If this happens, the control blocks associated with the procedure ARE KEPT so that reloading, if necessary, can be done more rapidly. When main storage is severely overloaded, frequent deleting and reloading of external procedures may occur. This condition is called "thrashing". Thrashing can be recognized by unusually frequent disk accessing and little useful processing being done by the program. It is necessary in this case to reduce the storage requirements of the program. SECTION 12: External Procedures and Functions JRT Pascal User's Guide version 3.0 NOT FOR SALE -137- 12.1 Coding external procedures and functions The external procedure Pascal file is very similar to a standard "internal" procedure in format. In many cases the only differences from a standard procedure format are that the PROCEDURE reserved word is preceded by the reserved word EXTERN and that the whole file is ended with a period to signify the end of the compile unit. An example of this basic case follows: EXTERN (* PRINT THE TOTAL AND AVERAGE OF 4 NUMBERS *) PROCEDURE XDEMO (A,B,C,D : REAL ); VAR TOTAL : REAL; BEGIN TOTAL := A + B + C + D; WRITELN('TOTAL =',TOTAL, ' AVERAGE =',TOTAL / 4.0); END;. ****** IMPORTANT ****** READ THE FOLLOWING CAREFULLY  JRT Pascal external procedures can access all of the global variables in the main program. The GLOBAL VARIABLES are those IN THE MAIN PROGRAM DECLARED BEFORE ANY PROCEDURE OR FUNCTION DECLARATIONS. They are variables that are available globally and not only local to some procedure. In the preceding example, TOTAL is a local variable - it is not accessible outside of the procedure XDEMO. To access global variables or files, their declarations are inserted in the external procedure file AFTER the word EXTERN and BEFORE the procedure header. The three declaration sections CONST, TYPE, VAR may be inserted at this point. They must be identical to the global declarations in the main program, except that additional constants and type identifiers may be added here. Type identifiers may be required in the procedure header parameter list or in a function return value declaration. The declaration of these type identifiers should appear IN THE SAME LOCATION as the global declarations -- just after EXTERN. SECTION 12: External Procedures and Functions JRT Pascal User's Guide version 3.0 NOT FOR SALE -138- EXTERN CONST NAME_SIZE = 32; TYPE NAME = ARRAY [1..NAME_SIZE] OF CHAR; CUSTOMER_RECORD = RECORD CUST_NAME, CUST_ADDR : NAME; BALANCE : REAL; END; VAR (* MAIN PROGRAM GLOBAL VARIABLES *) CUSTOMER_LIST : ARRAY [1..100] OF CUSTOMER_RECORD; (**** SEARCH CUSTOMER LIST FOR GIVEN NAME ****) FUNCTION SEARCH ( N : NAME ) : CUSTOMER_RECORD;  VAR I : INTEGER; BEGIN I:=1; WHILE (N <> CUSTOMER_LIST[I].CUST_NAME AND (I <= 100) DO I:=I+1; IF N = CUSTOMER_LIST[I].CUST_NAME THEN SEARCH:=CUSTOMER_LIST[I] ELSE SEARCH:=' '; END;. SECTION 12: External Procedures and Functions JRT Pascal User's Guide version 3.0 NOT FOR SALE -139- 12.2 Referencing external procedures and functions External procedures and functions MUST be declared in the main programs which reference them. Their declaration is identical to a regular procedure except that the entire body of the procedure is replaced with the reserved word EXTERN. PROCEDURE PLOTTER ( X,Y : INTEGER ); EXTERN;  FUNCTION CUBEROOT ( A : REAL ): REAL; EXTERN; For clarity, it is useful to group all external procedure declarations as the first procedure declarations in the program. External procedures may reference other external procedures if appropriate declarations are included in the referencing procedure. EXEC indentifies external procedures by a SEQUENCE NUMBER. External procedures SHOULD ALWAYS BE DECLARED IN THE SAME SEQUENCE, in the main program or in another external procedure. NOTE that THE USER MUST ENSURE that external procedure declarations and parameter lists are CONSISTENT among different files, since the compiler does not validate this. SECTION 12: External Procedures and Functions ations and parameter lists are CONSISTENT among different files, since the compiler does  JRT Pascal User's Guide version 3.0 NOT FOR SALE -154- 14. Extended CASE statement Format CASE selector_expression OF label_expression ... , label_expression : statement; ... ... ELSE : statement; END The CASE statement is used to select one of several statements for execution based on the value of the selector_expression. The selector_expression and the label_expression must be compatibile data types. The label_expressions are evaluated sequentially. If one is found equal to the selector, the corresponding statement is executed. If none are equal, then the optional ELSE clause statement is executed. The ELSE clause is a JRT Pascal extension. Also, standard Pascal allows only constants as labels, while expressions are allowed by JRT Pascal. Not more than 128 label clauses are allowed in one CASE statement. Not more than 128 labels per label clause are allowed. The statements should be followed by a semicolon. The semicolon is optional on the last statement in the CASE statement. Examples: CASE I OF 2 : WRITELN('I IS 2'); 4 : WRITELN('I IS 4'); ELSE : WRITELN('I IS NOT 2 OR 4'); END; CASE LANGUAGE OF (* STRING EXPRESSION *) 'PASCAL' : YEAR := 1970; 'PL/I' : YEAR := 1964; 'BASIC' : YEAR := 1965; END; Compliments of Merle Schnick SECTION 14: Extended CASE statement JRT Pascal User's Guide version 3.0 NOT FOR SALE -155- (* EXAMPLE OF EXPRESSIONS IN LABELS *) CASE ANGLE OF PHI : WRITELN('PHI'); 2.0 * PHI : WRITELN('TWO PHI'); 3.0 * PHI : WRITELN('THREE PHI'); ELSE : WRITELN('ANGLE NOT ON NODE'); END; (* EXAMPLE OF BOOLEAN SELECTOR AND LABEL EXPRESSIONS *) (* CHECK VOLTAGE V FOR VALID RANGE *) CASE TRUE OF (V > 2.5) AND (V < 4.3) : PROCESS_RANGE_1; (V > 5.6) AND (V <= 14.08) : PROCESS_RANGE_2; (V > 35.6) AND (V <= 100.0) : PROCESS_RANGE_3; ELSE : WRITELN('VOLTAGE OUT OF VALID RANGES:',V); END; Compliments of Merle Schnick SECTION 14: Extended CASE statement S_RANGE_3; ELSE : WRITELN('VOLTAGE OUT OF VALID RANGES:',V); END; version 3.0 NOT FOR SALE -155- (* EXAMPLE OF EXPRESSIONS IN LABELS *) CASE ANGLE OF PHI : WRITELN('PHI'); 2.0 * PHI : WRITELN('TWO PHI'); 3.0 * PHI : WRITELN('THRE JRT Pascal User's Guide version 3.0 NOT FOR SALE -156- 15. CRT Formatting This section describes JRT Pascal CRT formatting facilities. It requries a basic knowledge of Pascal and of JRT Pascal external procedures. The CRTMAP utility enables the user to quickly format a CRT terminal screen. One record at a time may be displayed. The utility program takes as its input a Map Description File (MDF) which describes the CRT map in a simple command language. The utility generates the source program for a Pascal external procedure which may then be compiled. This external procedure contains all the logic to display all or part of one record data type. Descriptive information may also be displayed on the screen. Source code for CRTMAP is include and its features may be modified or extended. The distribution version of CRTMAP assumes a Televideo display terminal. It may be adapted to any other terminal or computer by modifying two lines in the program. These two lines specify the control codes for cursor positioning and clearing the screen. Consult your display terminal user manual for the codes for your system. The cursor positioning code is in procedure GOTOXY in the CRTMAP.PAS file. The screen clear code is procedure CLEAR. Procedure PART2 from CRTMAP.PAS is reproduced here. This code generates "part2" of the generated external procedure. The line marked XXX contains the terminal codes for clearing the CRT screen. The line marked YYY contains the terminal codes for moving the cursor to a particular position. Copy compliments of Merle Schnick SECTION 15: CRT Formatting JRT Pascal User's Guide version 3.0 NOT FOR SALE -157-  procedure part2; begin writeln(f2; 'procedure clear;'); writeln(f2; 'begin'); writeln(f2; 'write(chr(27),''*'');'); { XXX } writeln(f2; 'end;'); writeln(f2); writeln(f2; 'procedure gotoxy (x,y : integer );'); writeln(f2; 'begin'); writeln(f2; 'write(chr(27),''='',chr(y+20h),chr(x+20h));'); { YYY } writeln(f2; 'end;'); writeln(f2); end; {part2} The CRT screen corrdinates have the origin 0,0 in the upper left corner: 0 x 79 ---------------------------------- 0 ! ! ! ! ! ! y ! ! ! ! !  ! 23 ! ! ---------------------------------- The first coordinate X indicates the column, the second Y indicates the row. 15.1 Structure of the external procedure CRTMAP generates a Pascal external procedure according to the parameters in the Map Description File. This external procedure then does the display formatting of your data record. Copy compliments of Merle Schnick SECTION 15: CRT Formatting JRT Pascal User's Guide version 3.0 NOT FOR SALE -158- Structure of the generated external procedure: PART1 EXTERN TYPE %INCLUDE type_declaration_filename PROCEDURE exproc_name ( VAR R : type_name ); PART2 PROCEDURE CLEAR; PROCEDURE GOTOXY; PART3 PROCEDURE DISPLAY; { format the CRT } PART4..PART8 (omitted) PART9 BEGIN main_line_code END;. Copy compliments of Merle Schnick SECTION 15: CRT Formatting JRT Pascal User's Guide version 3.0 NOT FOR SALE -159- 15.2 Map Definition File The MDF defines the format of the CRT screen for the display of one record type. CRTMAP recognizes seven different MDF commands. The MDF commands MUST be entered in a fixed sequence except for LITERAL and FIELD which may be intermixed. There should be one command per line. Blank lines may be inserted for readability. EXPROC = eeeeeeee INCLUDE = iiiiiiii RECORD = rrrrrrrr  any number of intermixed LITERAL and FIELD commands CURSOR = x,y END MDF Commands EXPROC - the name of the external procedure to be generated by CRTMAP. INCLUDE - the name of the %INCLUDE file which contains the TYPE declaration of the record to be displayed and all TYPEs and CONSTants to which it refers. example: INCLUDE = TYPES.DCL RECORD - the name of the record data type to be displayed - this type declaration is in the include file. LITERAL - causes a character string to be displayed on the CRT screen, the string must be entered between single quotes. LITERAL column, row, 'literal string to be displayed' examples: LITERAL 0,0,'* this is the upper left corner' LITERAL 40,12,'* this is about the center' LITERAL 0,23,'bottom row of the crt' screen coordinates have the origin 0,0 in the upper left corner, first number X is the column, second number Y is the row. FIELD - causes a field in the input record to be displayed at the specified location, may include optional minimum width and decimal places numbers for displaying integers and reals. FIELD column, row, field_name {:min_width {:dec_places}} FIELD 10,20, customer_name Copy compliments of Merle Schnick SECTION 15: CRT Formatting JRT Pascal User's Guide version 3.0 NOT FOR SALE -160- FIELD 12,20, account_balance:10:2 FIELD 20,60, days_until_armageddon:1 CURSOR - specifies where the cursor should be positioned on the screen after the record is displayed. CURSOR column, row END - indicates end of Map Description File, ALWAYS required. Copy compliments of Merle Schnick SECTION 15: CRT Formatting JRT Pascal User's Guide version 3.0 NOT FOR SALE -161- 15.3 Operating CRTMAP To operate CRTMAP, first prepare the Map Description File (section 15.2). Prepare a file containing the record to be displayed and its subordinate type declarations - this will be the INCLUDE file. Make sure the CRTMAP utility was modified to support your terminal type (see section 15.). To run the utility, enter: EXEC CRTMAP It will ask for the "filename.type" of your Map Description File. On successful termination of CRTMAP, the new external procedure source file will be found on the default disk. It must be compiled with the JRT Pascal version 3 compiler. 15.4 CRTMAP example An example of the use of the CRTMAP utility is provided here. A simple customer record is formatted and displayed. The Map Definition File named MDF is listed. The include file named CUSTOMER.PAS contains the main record declaration CUST and a subordinate declaration CHAR30. The external procedure generated by CRTMAP is named CUSTMAP.PAS and is listed. A complete compiler listing of CRTMAP.PAS follows. Copy compliments of Merle Schnick SECTION 15: CRT Formatting JRT Pascal User's Guide version 3.0 NOT FOR SALE -162- Operation flowchart of CRTMAP utility (ver 3.0) Map Description File !  ! ! ! V ----------------- ! ! ! CRTMAP ! ! utiltiy ! ! ! ----------------- ! ! ! V Pascal source code external %include procedure file ! / ! / ! / ! /  ! / ! / ! / ! / ! / V V ----------------- ! ! ! JRTPAS3 ! ! ! ----------------- ! ! ! ! V compiled CRT mapping external procedure Copy compliments of Merle Schnick SECTION 15: CRT Formatting  JRT Pascal User's Guide version 3.0 NOT FOR SALE -163- CRT Screen formatted by CUSTMAP external procedure ----------------------------------------------------------------- ! ! ! ---------- CUSTOMER RECORD ---------- ! ! ! ! ! ! Name PASCAL, BLAISE ! ! ! ! Addr 777 RUE D'ARGENT ! ! ! ! City PARIS ! ! ! ! ! !  ! ! ! ! Balance $ 1490.34 ! ! ! ! ! ! ! ! ! ! _ ! ! !_! ! !_______________________________________________________________! Copy compliments of Merle Schnick SECTION 15: CRT Formatting JRT Pascal User's Guide version 3.0 NOT FOR SALE -164- File CUSTOMER.PAS contains TYPE declaration of customer data record CHAR30 = ARRAY [1..30] OF CHAR; CUST = RECORD NAME : CHAR30; ADDRESS : CHAR30; CITY : CHAR30; BALANCE : REAL; END; FILE MDF contains Map Definition File which describes CRT screen format EXPROC = CUSTMAP INCLUDE = CUSTOMER.PAS RECORD = CUST LITERAL = 0,0,'---------- CUSTOMER RECORD ----------' LITERAL = 5,3,'Name ' FIELD =12,3,NAME LITERAL = 5,5,'Addr ' FIELD = 12,5,ADDRESS LITERAL = 5,7,'City ' FIELD = 12,7,CITY LITERAL = 15,14,'Balance $' FIELD = 15,14,BALANCE:8:2 CURSOR = 0,22 END Copy compliments of Merle Schnick SECTION 15: CRT Formatting JRT Pascal User's Guide version 3.0 NOT FOR SALE -165- File CUSTMAP.PAS Pascal external procedure generated by CRTMAP utility { CRTMAP generated external procedure } extern type %include ('CUSTOMER.PAS ') procedure CUSTMAP ( var r : CUST ); procedure clear; begin write(chr(27),'*'); end; procedure gotoxy ( x,y : integer ); begin write(chr(27),'=',chr(y+20h),chr(x+20h)); end; procedure display; begin clear; gotoxy( 0 ,0 ); write('---------- CUSTOMER RECORD ----------'); gotoxy( 5 ,3 ); write('Name '); gotoxy( 12 ,3 ); write( r,NAME ); gotoxy( 5 ,5 ); write('Addr '); gotoxy( 12 ,5 ); write( r,ADDRESS ); gotoxy( 5 ,7 ); write('City '); gotoxy( 12 ,7 ); write( r,CITY );  gotoxy( 5 ,14 ); write('Balance $'); gotoxy( 15 ,14 ); write( r,BALANCE:8:2 ); gotoxy( 0 ,22 ); end; begin display; end;. Copy compliments of Merle Schnick SECTION 15: CRT Formatting JRT Pascal User's Guide version 3.0 NOT FOR SALE -166- JRT Pascal ver 3.0 CRTMAP Page 001 ----- CRT Mapping Utility ----- 0000 0002: %page(50) 0000 0003: 0000 0004: { This version setup for Televideo terminals. To adapt to oth 0000 0005: terminals modify PROCEDURE PART2 which generates the cursor 0000 0006: positioning (gotoxy) and clear screen (clear) codes. } 0000 0007: 0000 0008: program crtmap; 0000 0009: 0003 0010: type 0010 0011: char16 = array [1..16] of char; 0010 0012: 0010 0013: var 0010 0014:  ch : char; 0010 0015: alphameric : set of char; 0010 0016: end_of_file : boolean; 0010 0017: map_file_name : string[15]; 0010 0018: word : char16; 0010 0019: exproc_name : char16; 0010 0020: include_name : char16; 0010 0021: record_name : char16; 0010 0022: f1, f2 : file of char; 0010 0023: 0010 0024: 0010 0025: procedure error ( msg : string[40] ); 0013 0026: var 0013 0027: dummy : char16; 0016 0028: begin 001A 0029: writeln; 001E 0030: writeln; 0028 0031: writeln(msg); 002C 0032: writeln; 002C 0033: { abnormally terminate - return to CP/M } 0034 0034: call(0,dummy,dummy); 0035 0035: end; 0035 0036: 0035 0037: procedure get_char; 003B 0038: begin 004C 0039: read(f1; ch); 0081 0040: if ch = chr(1ah) then error('Premature end of input file'); 008D 0041: write(ch); 008E 0042: end; 008E 0043: 008E 0044: procedure get_word; 0091 0045: label 9 9; 0091 0047: var 0091 0047: i : integer; 0094 0048: begin 009D 0049: word := ' '; 00AC 0050: while not (ch in alphameric) do 00AC 0051: begin Copy compliments of Merle Schnick SECTION 15: CRT Formatting JRT Pascal User's Guide version 3.0 NOT FOR SALE -167- JRT Pascal ver 3.0 CRTMAP page 002 ----- CRT Mapping Utility ----- 00B1 0052: get_char; 00B4 0053: end; 00C4 0054: word[1] := ch; 00C9 0055: i := 2; 00CE 0056: get_char; 00DC 0057: while (ch in alphameric) do 00DC 0058: begin 00EF 0059: word[i] := ch; 00F9 0060: i := i + 1; 00FE 0061: get_char; 0101 0062: end; 010E 0063: word := upcase(word); 010F 0064: end; {get_word} 010F 0065: 010F 0066: 010F 0067: procedure init; 0115 0068: begin 012C 0069:  writeln('CRTMAP ver 3.0'); 0130 0070: writeln; 0157 0071: write('name of Map Desription File : '); 0160 0072: readln(map_file_name); 0164 0073: writeln; 0168 0074: writeln; 0177 0075: reset(f1,map_file_name,binary,256); 017C 0076: end_of_file := false; 0185 0077: ch := ' '; 01A7 0078: alphameric := ['A'..'Z','a'..'z','0'..'9',':','.']; 01AC 0079: get_word; 01E1 0080: if word <> 'EXPROC' then error('EXPROC command expected'); 01E6 0081: get_word; 01F2 0082: exproc_name := word; 020A 0083: rewrite(f2, exproc_name + '.pas', binary, 256); 020F 0084: get_word; 0246 0085: if word <> 'INCLUDE' then error('INCLUDE' command expected'); 024B 0086: get_word; 0257 0087: include_name := word; 025C 0088: get_word; 0291 0089: if word <> 'RECORD' then error('RECORD' command expected'); 0296 0090: get_word; 02A2 0091: record_name := word; 02A3 0092: end; {init} 02A3 0093: 02A3 0094:  02A3 0095: procedure part1; 02A9 0096: begin 02DF 0097: writeln(f2; '{CRTMAP generated external procedure }'); 02F4 0098: writeln(f2; 'extern'); 02FF 0099: writeln(f2); 0312 0100: writeln(f2; 'type'); 033C 0101: writeln(f2; '%include (''',include_name,''')'); Copy compliments of Merle Schnick SECTION 15: CRT Formatting JRT Pascal User's Guide version 3.0 NOT FOR SALE -168- JRT Pascal ver 3.0 CRTMAP page 003 ----- CRT Mapping Utility ----- 0347 0102: writeln(f2); 0386 0103: writeln(f2; 'procedure ',exproc_name, '(var r : '.recor_nam ');'); 0391 0104: writeln(f2); 0392 0105: end; {part1} 0392 0106: 0392 0107: 0392 0108: procedure part2; 0398 0109: begin 03B7 0110: writeln(f2; 'procedure clear;'); 03CB 0111: writeln(f2; 'begin'); 03ED 0112: writeln(f2; 'write(chr(27),''*'');'); 0400 0113: writeln(f2; 'end;'); 040B 0114: writeln(f2); 043D 0115: writeln(f2; 'procedure gotoxy ( x,y : integer );'); 0451 0116: writeln(f2; 'begin'); 0489 0117: writeln(f2; 'write(chr(27),''='',chr(y+20h),chr(x+20h));'); 049C 0118: writeln(f2; 'end;'); 04A7 0119: writeln(f2); 04A8 0120: end; {part2} 04A8 0121: 04A8 0122: 04A8 0123: procedure part3; {create DISPLAY procedure} 04A8 0124: 04AB 0125: procedure process_coordinates; 04AE 0126: var 04AE 0127: x_coord, y_coord : char16; 04B1 0128: begin 04B6 0129: get_word; 04C2 0130: x_coord := word; 04C7 0131: get_word; 04D3 0132: y_coord := word; 0507 0133: writeln(f2; 'gotoxy( ',x_coord,',',y_coord,');'); 0508 0134: end; 0508 0135: 0508 0136: procedure process_string; 050E 0137: begin 050E 0138: {find start of string} 052E 0139: while not (ch in ['''',chr(0dh),' ',chr(9),chr(1ah)]) do 0536 0140: get_char; 0566 0141: if ch <> '''' then error('Literal string expected'); 057B 0142: write(f2; 'write('); 057B 0143: repeat 058E 0144: write(f2; ch); 0593 0145: get_char; 05A1 0146: until ch = chr(0dh); 05B2 0147: writeln(f2; ');'); 05B3 0148: end; 05B3 0149: 05B3 0150: 05B6 0151: begin {part3} Copy compliments of Merle Schnick SECTION 15: CRT Formatting JRT Pascal User's Guide version 3.0 NOT FOR SALE -169- JRT Pascal ver 3.0 CRTMAP page 004 ----- CRT Mapping Utility ----- 05D7 0152: writeln(f2; 'procedure display;'); 05EB 0153: writeln(f2; 'begin'); 0600 0154: writeln(f2; 'clear;'); 0608 0155: while not end_of_file do 0608 0156: begin 060D 0157: get_word; 0613 0158: case word of 0621 0159: 'LITERAL' : 0621 0160: begin 0626 0161: pr ocess_coordinates; 062B 0162: process_string; 062E 0163: end; 063A 0164: 'FIELD' : 063A 0165: begin 063F 0166: process_coordinates; 0644 0167: get_word; 066C 0168: writeln(f2; 'write( r,',word,');'); 066F 0169: end; 0684 0170: 'CURSOR' : process_coordinates; 0696 0171: 'END' : end_of_file := true; 06D3 0172: else : error('LITERAL, FIELD, CURSOR, or END command ex cted'); 06D4 0173: end; 06D7 0174: end; 06EA 0175: writeln(f2; 'end;' ); 06F5 0176: writeln(f2); 06F6 0177: end; {part3} 06F6 0178: 06F6 0179: 06F6 0180: procedure part9; 06FC 0181: begin 0710 0182: writeln(f2; 'begin'); 0727 0183: writeln(f2; 'display;'); 073B 0184: writeln(f2; 'end;.'); 073C 0185: end; {part9} 073C 0186: 073C 0187: 073F 0188: begin {crtmap} 0744 0189: init; 0749 0190: part1; 074E 0191: part2; 0753 0192: part3; 0758 0193: part9; 075C 0194: close(f1); 0760 0195: close(f2); 0761 0196: end {crtmap}. No errors detected Module size = 1893 dec bytes End of compile for CRTMAP Copy compliments of Merle Schnick SECTION 15: CRT Formatting 075C 0194: close(f1); 0760 0195: close(f2); 0761 0196: end {crtmap}. No errors detected Module size = 1893 else : error('LITERAL, FIELD, CURSOR, or END command ex cted'); 06D4 0173: end; 06D7 0174: end; 06EA 0175: writeln(f2; 'end;' ); 06F5 0176: writeln(f2); 06F6 0177: end; {part3} 06F6 0178: 06F6 0179: 06F6 0180: procedure part9; 06FC 0181: begin 0710 0182: writeln(f2; 'begin'); 0727 0183: writeln(f2; 'display;'); 073B 0184: writeln(f2; 'end;.'); 073C 0185: end; {part9} 073C 0186: 073C 0187: 073F 0188: begi JRT Pascal User's Guide NOT FOR SALE -170- A. Reserved words The following words are reserved in JRT Pascal and may not be used as identifiers: abs addr allocate and array begin binary boolean call case char chr close compress concat cons const copy deallocate delete dispose div do downto else end eof eoln exten false file fillchar for forward free function get goto hex$ if in include  Copy compliments of Merle Schnick APPENDIX A: Reserved words JRT Pascal User's Guide NOT FOR SALE -171- initialize input insert integer label length list lrange ltrace map maxint mod new nil nocons nolist noltrace noptrace not nowarning odd of open or ord output page portin portout pos pred procedure program ptrace put rba read readln real real$ record repeat reset rewrite  round rrn set sqr Copy compliments of Merle Schnick APPENDIX A: Reserved words JRT Pascal User's Guide NOT FOR SALE -172- succ string system text then to true trunc type until upcase var warning while with write writeln xor Copy compliments of Merle Schnick APPENDIX A: Reserved words  while procedure program ptrace put rba read readln real real$ record repeat reset rewrite   JRT Pascal User's Guide NOT FOR SALE -173- B. Activity analyzer The activity analyzer, Activan, is a facility which monitors the execution of a Pascal program and prints a graph showing the amount of time spent executing each portion of the program. To use Activan, a program must be compiled with the %LTRACE directive or the $L compile switch on. Activan monitors the line numbers as a program executes and keeps counters for the line numbers in the specified range. The range of line numbers to be monitored and the line spacing can be set and changed when the program is running. To run a program with Activan, specify the $A switch when the program is started with the EXEC command: EXEC TEXTPGM $A Before the program begins execution, Activan will request console input to specify the line range to be monitored and the line spacing. When those parameters have been entered, the program execution will begin. If Activan is active when the program terminates, Activan mode is entered so that a final histogram can be printed. While the program is running, it can be interrupted and control returned to Activan by keying in a control-A command. Activan will then request which action is desired: code action ---- ------- C clear the counters to zero H print histogram of activity I initialize the line range and spacing M run the program with Activan monitoring W run the program without Activan Z terminate the program Copy compliments of Merle Schnick APPENDIX B: Activitiy analyzer  program with Activan moni JRT Pascal User's Guide NOT FOR SALE -174- C. Block letters An external procedure named LETTERS is provided to generate large block letters. These letters are 9 lines high and from 4 to 10 columns wide. The external procedure generates an entire row at a time of letters for use as report headers, program identifiers, etc. The output line may be up to 220 columns wide. The upper case letters, numbers, and dash may be input to the external procedure. Unsupported characters are converted to spaces. Lower case characters are converted to upper case. The output from letters is placed in a buffer which is an array of strings. This must be defined exactly as shown. The declaration for LETTERS is: TYPE BUFFER = ARRAY [1..9] OF STRING[220]; PROCEDURE LETTERS (INPUT_STRING : STRING;  SLANT : CHAR; VAR B : BUFFER ); EXTERN; The input_string is the line of characters to be converted to block letter format. The slant character provides for 'streamlined' characters by slanting to the left or right. Slant may be 'L' or 'R' or ' ', for no slant. The output buffer B refers to a variable of type buffer in the user's program. Note that B is a referenced parameter. Copy compliments of Merle Schnick APPENDIX C: Block letters JRT Pascal User's Guide NOT FOR SALE -175- This sample program will print out the word 'PASCAL' in block letters: PROGRAM BLOCKS; TYPE BUFFER = ARRAY [1..9] OF STRING[220]; VAR I : INTEGER; BLOCKS_BUFR : BUFFER; PROCEDURE LETTERS ( INPUT_STRING : STRING; SLANT : CHAR; VAR B : BUFFER ); EXTERN; BEGIN LETTERS('PASCAL','R',BLOCKS_BUFR); SYSTEM(LIST); FOR I:=1 TO 9 DO WRITELN( BLOCKS_BUFR[I] ); END. Copy compliments of Merle Schnick APPENDIX C: Block letters  SYSTEM(LIST); FOR I:=1 TO 9 DO WRITELN( B Copy compliments of Merle Schnick APPENDIX C: Block letters JRT Pascal User's Guide NOT FOR SALE -175- This sample program will print out the word 'PASCAL' in block letters: PROGRAM BLOCKS; TYPE BUFFER = ARRAY [1..9] OF STRING[220]; VAR I : INTEGER; BLOCKS_BUFR : BUFFER; PROCEDURE LETTERS ( INPUT_STRIN  JRT Pascal User's Guide NOT FOR SALE -176- D. JSTAT JSTAT is an external procedure which can be used to compute several basic statistics given an array of real numbers as input. It computes the arithmetic mean, standard deviation, variance, skewness, kurtosis and the first four moments about the mean. The source code for JSTAT is provided on the distribution disk and may be modified as necessary. The procedure is restricted to an array of 1000 real numbers, but this can be easily changed by modifying the declaration of the data type jstat_array and recompiling the procedure. While jstat_array is declared as a 1000 element array, a much smaller array may be used to hold the data values since the input array is used as a referenced parameter. JSTAT (in its distributed form) requires three parameters:  n - number of data items in the input array x - array of up to 1000 real numbers r - output record containing computed statistic The following type declarations and procedure declaration are required in the calling Pascal program: TYPE JSTAT_INTERFACE = RECORD MEAN, STANDARD_DEVIATION, VARIANCE, SKEWNESS, KURTOSIS, M1, M2, M3, M4 : REAL; END; JSTAT_ARRAY = ARRAY [1..1000] OF REAL; PROCEDURE JSTAT (N : INTEGER; VAR X : JSTAT_ARRAY; VAR R : JSTAT_INTERFACE ); EXTERN; Copy compliments of Merle Schnick APPENDIX D: JSTAT  VAR X : JSTAT_ARRAY; VAR R : JSTAT_INTERFACE ); EXTE JRT Pascal User's Guide NOT FOR SALE -177- E. JGRAF JGRAF is an external procedure which formats x-y graphs and scatter graphs. The graph size in rows and columns and the lower and upper x and y bounds are set by the user. A title to the graph may be provided. Once the graph has been prepared, it can be displayed on the console, printed or stored in a disk file. Any number of data points can be plotted. Any number of separate plots can be prepared simultaneously (within memory limitations). To use JGRAF, your program (or occasionally an external procedure) must declare the char9000 and jgraf_interface types. Your program must then declare one (or more) variable of type jgraf_interface. For convenience, the interface variable will be called jgi in this document. Your program could call the interface variable(s) anything appropriate. Your program must also declare JGRAF as an external procedure. The declarations for sample main program to take plotting commands from a disk file and create a plot is shown here. (The body of the sample program is listed later.) Everything listed here is required of any program using JGRAF except for the declarations noted as specific to jg. Copy compliments of Merle Schnick APPENDIX E: JGRAF JRT Pascal User's Guide NOT FOR SALE -178- program jg; %ltrace %ptrace (* optional - suggested *) type char9000 = array [1..9000] of char; jgraf_interface = record command : char; (* R *) plot_char : char; (* R *) x_grid : boolean; (* R *) y_grid : boolean; (* R *) rows : integer; (* R *) columns : integer; (* R *) x_lower : real; (* R *) x_upper : real; (* R *) y_lower : real; (* R *) y_upper : real; (* R *) filename : array [1..14] of char; graf_title : string; (* R *) (* fields below used internally by jgraf *) b : ^char9000; bufr_size : integer; line_size : integer; row_count : integer; x_spacing : real; y_spacing : real; end; var jgi : jgraf_interface; (* following are used by program jg *) file_name : array[1..20] of char; title : array[1..24] of char; inf : file of char; x, y : real; command : char; (* end of variables used by sample program *) procedure jgraf ( var jg : jgraf_interface;   x, y : real ); extern; (* end of declarations *) To produce graphs, your program must first set all members of jgi marked (* R *) in the jgraf_interface type declaration to appropriate values. Copy compliments of Merle Schnick APPENDIX E: JGRAF JRT Pascal User's Guide NOT FOR SALE -179- Jgi.x_grid would be set to false if grid lines running across the graph should be omitted. Jg.y_grid is likewise set to false if grid lines running up and down are to be omitted. Jgi.rows and jgi.columns contain the number of lines and number of characters across the body of the plot itself (minus one). The number of rows and columns should normally be divisible by 10. Plot size can be calculated as (number of columns + 16) * (number of lines + 5), which should not exceed 9000 characters. The length of jgi.title should be less than the number of columns in the plot. Once all the requaired members of jgi are initialized, set jgi.command to 'I' and call JGRAF, as JGI.COMMAND := 'I'; JGRAF ( JGI, 0.0, 0.0 ); (Note that the examples listed here in upper case are for illustration only and are NOT part of the program jg.) Then, to place data points on the graph, set jgi.command to 'D' and call JGRAF for each of the appropriate points. Do this as often as needed. To get two distinct curves, you could set jgi.plot_char to '*' for one set of points, then set it to '#' before calling JGRAF with another set of points. JGI.COMMAND := 'D'; JGI.PLOT_CHAR := '*'; JGRAF ( JGI, 15.4, 199.2 ); JGRAF ( JGI, 15.9, 205.7 ); JGI.PLOT_CHAR := '#'; JGRAF ( JGI, 9.0, 105.0 ); To print the graph on the console, set jgi.command to 'C' and call JGRAF with x and y arguments zero, as JGI.COMMAND := 'C'; JGRAF ( JGI, 0.0, 0.0 ); If you want output to the line printer as well as to the console, set jgi.command to 'P' instead of 'C' before calling JGRAF. Copy compliments of Merle Schnick APPENDIX E: JGRAF JRT Pascal User's Guide NOT FOR SALE -180- To write the graph to a file, set jgi.filename to the desired name, jgi.command to 'S', and call JGRAF. JGI.FILENAME := 'B:PLOT.5'; JGI.COMMAND := 'S'; JGRAF ( JGI, 0.0, 0.0 ); More data points can be added to a graph after printing, so that development or trends can be plotted in succession. Further, by setting jgi.plot_char to a space (' '), data points can be erased (although grid lines will not be restored). If you want to print more than one graph using the same interface record (jgi) or want JGRAF to free the memory allocated to produce a graph, you can set jgi.command to 'X' before calling JGRAF. This will free the buffers allocated by JGRAF (in the 'I' command). Note that every call to JGRAF that is not providing data (jgi.command = 'D') should have the x and y arguments equal to 0.0. The body of the sample program jg is included here, and illustrates one use of JGRAF. Jg takes a disk file of commands as input and produces one or more plots as directed. Commands on the disk file are similiar to the options to JGRAF, with the addition of two commands. T followed by 'title' may preceed the I command. Period (.) followed by a space and a new plot character will reset the current plot character. begin (* jg *) write('General graphing input file: '); readln(file_name); reset(inf,file_name, text, 512); jgi.title := ' '; while (not eof(inf)) do begin read(inf; command); command := upcase(command); writeln('db ',command); jgi.command := command; case command of 'T': begin readln (inf; title); jgi.title := title; end; Copy compliments of Merle Schnick APPENDIX E: JGRAF JRT Pascal User's Guide NOT FOR SALE -181- 'I': begin readln (inf; jgi.rows, jgi.columns, jgi.x_lower, jgi.x_upper, jgi.y_lower, jgi.y_upper); jgi.plot_char := '*'; jgi.x_grid := true; jgi.y_grid := true; (* note that all required members *) (* of jgi have been set *) jgraf(jgi, 0.0, 0.0); writeln(' done I'); end; 'D': begin read(inf; x, y); jgraf(jgi, x, y); end; '.': readln(inf; jgi.plot_char); 'C': jgraf(jgi, 0.0, 0.0); 'P': jgraf(jgi, 0.0, 0.0); 'S': begin readln(inf; file_name); jgi.filename := file_name;  jgraf(jgi, 0.0, 0.0); end; 'X': jgraf(jgi, 0.0, 0.0); else: writeln('Unrecognized command: ',command); end; end; close(inf); end. Given the input file SAMPLE.DAT as follows: T 'Sample' I 20 40 0 40 0 60 D 5 6 D 6 10 D 7 12 D 8 15 D 9 16 D 10 16 . # D 5 2 D 32 6 D 32 27 C S sample.out X Copy compliments of Merle Schnick APPENDIX E: JGRAF JRT Pascal User's Guide NOT FOR SALE -182- Jg will produce the (uninspired) output file SAMPLE.OUT as follows, given the input listed above. JGRAF ver 3.0 **** Sample ****  60 -I---------I---------I---------I---------I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I 30 -I---------I---------I---------I---------I I I I I # I I I I I I I I I I I I I I I I I *** I I I I * I I I I I * I I I I I * I I I # I I # I I I I 0 -I---------I---------I---------I---------I 0 10 20 30 40 A summary of the commands to JGRAF is included now for reference: code meaning ---- ----------- C display graph on console D plot a data point I initialize graph buffer and axes P print graph S save graph on a disk file X delete graph buffer The source code for JGRAF is provided and may be modified. For example, the number of lines between the x_grid lines can be changed to 6 (or to 8) so that the grid lines form a one inch square on printers with 10 characters per inch and 6 (or 8) lines per inch. Copy compliments of Merle Schnick APPENDIX E: JGRAF JRT Pascal User's Guide NOT FOR SALE -183- JGRAF is not limited to scatter plots. With appropriate selection of data points, histograms can be produced. Contour plots (and even isometric drawings) are also possible. Copy compliments of Merle Schnick APPENDIX E: JGRAF  plots (and even isometric drawings) are also possible. The source code for JGRAF is provided and may be modified. For example, the number of lines between the x_grid lines can be changed to 6 (or to 8) so that the grid lines form a one inch square on printers with 10 cha JRT Pascal User's Guide NOT FOR SALE -184- F. Restrictions 1. Arrays are limited to 8 dimensions. 2. Literal character strings in the 'const' section are limited to 32 characters. 3. Random disk files require CP/M 2.2 and may be up to 8 megabytes in size. 4. Sets are limited to 128 elements. The first element (leftmost) corresponds to 0; the last element (rightmost) corresponds to 127. 5. Not more than 63 external procedures and functions may be declared. 6. Not more than 1632 dynamic storage blocks may be allocated at one time. The run-time system may require up to 100 of these for file buffers, file control blocks, external procedures and other uses. 7. "With" statements may not be nested to more than 31 levels. 8. "Case" statements are limited to 128 clauses with 128 labels per clause. 9. Integers must be between +32767 and -32768, since they are stored in 16-bit twos-complement format. In a few cases, integers will be treated as unsigned 16-bit values with a range of 0 to +65535. The MAP and CALL builtin procedures require addresses which may range up to 65535. Accessing random files by relative byte address may require byte addresses up to 65535. 10. "Real" numbers are represented in 14 digit binary coded decimal (BCD) format. The floating point exponent range is from -64 to +63. 11. The names of procedures and functions may not be used as parameters. 12. Literal character strings in the source program may not exceed 127 characters. Copy compliments of Merle Schnick APPENDIX F: Restrictions not be used as parameters. 12. Literal character strings in the source program may not exceed 127 characters. Y  illegal. Syntax error. E-Prolog ver. 2.2 (July 5, 1985) {j*"*" 2ͧF ;(gw !,U(v͈ :( :<2ͳÆ͈ :) :=2!| &ͧ"͈ :)(!B:=2*ͳͧ:[ ͈:]  ( ( ( ɯɯRwͦwFw@[@[ @[M@;[M@[O@ͦ(~?(>ɯ~#fo s#rnfnfnfnfututututnfnfutut#### Out of string space.!"i͈ ͈(*!͈()T])):0_͈ͳ͏!:" ͈͗*i:w#"i͈:" I' ͈͗*i:w#"i͈:' (ͮ(*i:w#"i͈ͮ ͳ *i:w#"i*i6*M"k*k~ *k0 *k####"m*k##"m^#VSk!@ *ms#r#:08:0ɯ:^͈:^@2:_ʓ-ʓ?ʓ0ڕ:ړAڕ[ړaڕ{ړÕ*Os#r#s#r#s#r#!~# "O[@8!oB Out of heap space." a"[ @0"@( @(*"" a"[ @@ **"* [ @!dS|( * d" !B",S.* "0####" ͪ*0[,[."8S2* " ͪ)*80*2>a"6*8"8;('[6"4͝(*J7"8"6*8"8;('[6"4͝(*J7"8"6*87":* ####" S*:Z[ ͪS>"<;(%*>[ @0[<@*< w*<* "@" *@* " ͪ1 Cannot change built-in commands. SN"P͏(!R,*P@(##"P*N*Ps#r*N*Ls#r+##"L* "͝(@("S[@( *"*"S"S;(#["͝ ***; ["͝*;(n*[@(^0**""*@(,*+**KB+"*[*[>*[K+**[***w(_*;(*[K+**w(5*[*[(*;(*[K+*w [@y2ʇ3 Retry on LESS. ) !7" S ;(2* " ͝(!* s#r* * s#r* w(A" ;(#* " " ;(* " * s#r* !!|!! l !| ͲͲ:=l < 2r #*+"!!~(#d@ !d"dl Ͳl ͲͲs l r " S !  " @r !  " @r * ͏(* ͏(* [ @l r * ͦ(* ͦ(* * ~l r !͜* ͝((_* * " w(! ͩ* ! é͉ :=l : !͗ ͉ :=l < 2r 2!"l " S ͆" S ͈:o&" !͜* * [ l * Br " S 2ͧ ͲͲ: !͗s  :="B "7@ F*7@(AEB@ !͜|Ç(F!7@  Z"B͜7aL d(|LZÇF~L@ Q"7L@ 6[5@ : : !9ͩ(*7EL[7 LLZ~E@ F~2@*5d">͝(.> _ͩ!Aͩ*>x>2@X*>">:@ X!E͈ͩ :Y(y(>"K͝( ͩ*K!"; ͝(!M,!" @" @~{_͋9{{:F:*@*?:?:*@%99i zi W{_*@*@99BK*@"@x*;+w ;"@4;ô9*&=*@99i zi W{_*> "S2!#6! 6 ! ͦ(b@(X>2͗! ͦ(?}@ :@2! 6 m@ ! ͦ(͗: E:2:(o&!ͩ > _2!~#"_6 #6:!"ȯ2*@(~(( 2#"ɯ2Ë*+":w I8L!="=*=6!=~G#^#VͣE !<O*R2= END B DISK WRITE ERROR. | 'd Sfd͏[f~#"hSj2!#6! 6 !hj ͦ(r@(h>2@W>2͗!hj ͦ(?}@ :@2! 6 m@ !hj ͦ(͗!lͩ_:(= !*dd@ ͑!s#"d!oB~#_:=>2*dd@(6#͑"S;*@($*["͝ "*"*͏ͦ(é>(_*@**["S";(4*@('*["͝ *"*"*d $!ͩ**["""*@(> _1>)_| >0_ _ WR8R8<0_> _ W IMPLEMENTATION ERROR.:(<(Ͳ2ͩ,!mQ[Qr8r "Q.w /u: APPEND }CLOSECON CREATE FAIL LESS LIST  LOADNULL OPENPRO READ *READCHAR: READLISTM ASAVE WRITE 5WRITECHAR Cannot allocate space.22!"J!J"L!SP!0ͩ!S*R[RS| !QB*M["*[R" *"  Cannot allocate space.22!"J!J"L!2͗!hj ͦ(?}@ :@2! 6 m@ !hj ͦ(͗!lͩ_:(= !*dd@ ͑!s#"d!oB~#_:=>2*dd@(6#͑"S;*@($*[ E-PROLOG -------- (ver. 2.2 -- July 5, 1985) This is a small Prolog system for CP/M-80 Z-80 computer. The current code occupies less than 6K bytes of space, so that there is a lot of space left over for the database and for the VERY deep subroutine stack. The executable version of E-Prolog is called EPRO.COM. This version was prepared under CP/M 2.2, but if you do not use APPEND, it should run under CP/M 1.4. Some E-Prolog sample programs are included in the DL, also: SAMPLE.PRO a sample database - see below SCIAM.PRO a logic puzzle from Scientific American --------------------------------------------------------------- EXPLANATION ----------- This DOC file DOES NOT teach Prolog. See the appropriate books for that. 1. W. F. Clocksin & C. S. Mellish, Programming in Prolog, Springer-Verlag, 1981. 2. K. L. Clark and F. G. McCabe, Micro-PROLOG: Programming in Logic, Prentice-Hall, 1984. E-Prolog does not have the special features of the large systems described in these books, but neither does it have the large price tags of those systems. Here are the peculiarities of E-Prolog. (Mostly things were done this way to save space.) TOKENS are the smallest elements recognized by the language. They are used to identify individuals (constants) and relations (predicate symbols), and some of them have special uses as well. The most common tokens are strings consisting of letters (upper and lower case are different), digits, and the characters '-', '_' , and '?' . Most other printable characters usually represent tokens of a single character. Exceptions to this can be enforced by enclosing a string in quotation marks (either " or ' ). Inside such a string, control characters are indicated as usual with the escape character '^'. Text enclosed in square brackets [ and ] is a comment, and is ignored. Space, Tab, Carriage return, Linefeed and comments separate one token from the next. Examples: Here there is one token on each line: ken Ken /  "A long string with spaces." But this line has eight tokens: How-to-tell.where one/token[really]ends. They are: How-to-tell . where one / token ends . VARIABLES are represented as strings beginning with the character '?'. Examples: ?X ?who ?mother-in-law LISTS are represented by placing the items of the list between a pair of parentheses. Examples: (A B C D E) a list with 5 items () the empty list (A (B C D E)) a list with 2 items (LOAD A:SAMPLE.PRO) a list with 6 items (LOAD A : SAMPLE . PRO) the same list PAIRS are represented using the vertical '|'. Example: (A | B) Technically, lists are built from the empty list up as pairs. The list (A B C D) is (A | (B | (C| (D | ())))) . Example: if (?X | ?Y) matches (first second third fourth) then ?X must be first and ?Y must be (second third fourth) This idea is extended to work with longer lists, too: If (?a ?b ?c | ?d) matches (alpha beta gamma) then ?a is alpha, ?b is beta, ?c is gamma, and ?d is (). NUMBERS are not really implemented in E-Prolog. Numbers from 0 to about 5500 can be used. They can be compared using LESS, but no arithmetic has been implemented. ATOMS are what Prolog asserions and rules are built from. They are lists: the first item in the list is the "predicate symbol" or "relation name", the others are the arguments. Example: (father jack ken) means that the relation "father" holds between the individuals "jack" and "ken". In Clocksin & Mellish, this is written: father(jack,ken). It might have the interpretation (if we choose) that Jack is the father of Ken. CLAUSES are lists of atoms. This is how Prolog rules are stored in the database. The first atom is the conclusion, and the others are the conditions. Example: ((grandparent ?A ?C) (parent ?A ?B) (parent ?B ?C)) This clause represents the Prolog rule: A is the grandparent of C if A is the parent of B and B is the parent of C. In Clocksin & Mellish it would be: grandparent(A,C) :- parent(A,B) , parent(B,C). --------------------------------------------------------------- BUILT-IN PREDICATES ------------------- Certain predicates are built into E-Prolog. These have to be special so that they can have "side effects", such as printing out information to the outside world. Here are brief descriptions of these special predicates. LESS This compares two strings (or two numbers). Examples: (LESS help hurt) succeeds (LESS help help) fails LIST This sends the entire database to the console (or other current output device). Example: (LIST) READ This is used to input a token from the console (or the current input file). Example: (READ ?X) will read one token and unify it with ?X. READLIST This is used to input a list from the console (or the current input file). Examples: (READ ?X), where ?X is a variable that does not have a current value, will read one item from the console, and assign it to ?X. But (READ (?X A : C)) will read one item from the console, and attempt to unify it with the list (?X A : C). Try it! READCHAR This inputs one character, which is treated internally as a number between 0 and 255. Example: (READCHAR ?x) WRITE This writes items to the console (or other output device). Examples: (WRITE ?X ?Y ?Z) (WRITE "Now is the time.") (WRITE "The father's name is " ?father ".^M^J") WRITECHAR This outputs as one character a number between 0 and 255. This number presumably was obtained using a READCHAR. Example: (WRITECHAR ?x) OPEN This opens a file for input. After an OPEN atom is verified, input is taken from that file instead of from the console. Any remaining input in the previous input file (or the input line from the console) is ignored. When EOF is reached, input reverts to the console. The input device may also be altered by a LOAD or OPEN command in the file. This command requires a file name. The name may be CON for the console. Examples: (OPEN A:FILE.INP) (OPEN CON) CREATE This opens a previously nonexistent file for output. (If the file already exists, then it will be deleted, and a new file opened with the same name.) After a CREATE atom is verified, output goes to the file instead of to the console. To end output to the file, use CLOSE, or CREATE another file. This command requires a file name, as in OPEN. The file name may be CON for the console, or NULL for output suppression. Examples: (CREATE A:FILE.OUT) (CREATE | ?file) the variable should be matched before this is attempted APPEND This is used to open an existing file for output. It is like CREATE, except that output starts at the end of the existing information. Requires a file name. Examples: (APPEND A:SAMPLE.PRO) (APPEND FAM) no filetype CLOSE This closes the output file. Further output will go to the console. Output sent to a file that is never closed will probably be lost. Example: (CLOSE) SAVE This writes the current database to a file. Requires a file name. The default file type is 'PRO'. Example: (SAVE A) is roughly equivalent to the following commands, in order: (CREATE A.PRO) (LIST) (CLOSE). LOAD This loads input from a given file. Usually used to add to the database. Use this only at command level, not from a program. (Use OPEN to get commands from a file.) Requires a file name. When EOF is reached, the input device reverts to the console. Loading may also be prematurely terminated with another LOAD or OPEN command in the file. Requires a file name. The file type 'PRO' is the default. / This is the CUT. It prohibits backtracking of the current predicate past the point it marks. See example below. --------------------------------------------------------------- SAMPLE SESSION -------------- In the sample session below, the comments are written flush left, and the actual input and output is indented. We will use the sample database SAMPLE.PRO. If you have a working E-Prolog, follow along yourself. Begin from CP/M. The tail of the command line is the first input to E-Prolog. (Remember that CP/M converts the command line to upper case.) A> EPRO (LOAD SAMPLE) E-Prolog ver. 2.2 (July 5, 1985) > This is the E-Prolog prompt. It is only shown when the input device is the console. To ask E-Prolog to attempt to prove a statement, just enter the atom. > (father jack ken) Yes. > The statement was proved. (The 'Yes' response is shown only when the input and output devices are both the console.) > (mother jack ken) > If the statement was not proved, no response is printed. Now let's try one with variables. > (father jack ?who) Yes. ?who = ken One solution was found. E-Prolog asks whether to try for other solutions: More?> y Yes. ?who = karen More?> y > The commands are entered just like other atoms. > (LIST) ((father jack ken)) ((father jack karen)) ((grandparent ?grandparent ?grandchild) (parent ?grandparent ?parent) (parent ?parent ?grandchild)) ((mother el ken)) ((mother cele jack)) ((parent ?parent ?child) (mother ?parent ?child)) ((parent ?parent ?child) (father ?parent ?child)) Yes. > Let's try something more difficult to solve: > (grandparent ?001 ?002) Yes. ?001 = cele ?002 = ken More?> y Yes. ?001 = cele ?002 = karen More?> y > Here is another variation. Try this one on your expensive Prolog system! > (?relation jack karen) Yes. ?relation = father More?> y Yes. ?relation = parent More?> y > To add to the database, enter a clause in the form of a list of atoms. > ((father carl jack)) > (LIST) ((father jack ken)) ((father jack karen)) ((father carl jack)) ((grandparent ?grandparent ?grandchild) (parent ?grandparent ?parent) (parent ?parent ?grandchild)) ((mother el ken)) ((mother cele jack)) ((parent ?parent ?child) (mother ?parent ?child)) ((parent ?parent ?child) (father ?parent ?child)) Yes. > Now let's add a rule to the database. (The prompt '1>' indicates that there is one open parenthesis that has not been closed.) > ((z ?x ?y) 1> (father jack ?x) 1> (father jack ?y) 1> ) This one illustrates backtracking. > (z | ?u) ?u = (ken ken) More?> y Yes. ?u = (ken karen) More?> y Yes. ?u = (karen ken) More?> y Yes. ?u = (karen karen) More?> y > Here is one with a cut to prohibit backtracking. > ((zz ?x ?y) (father jack ?x) (/) (father jack ?y)) > (zz | ?v) Yes. ?v = (ken ken) More?> y Yes. ?v = (ken karen) More?> y > Isn't the next one interesting: > ?x Yes. ?x = (father jack ken) More?> y Yes. ?x = (father jack karen) More?> y Yes. ?x = (grandparent cele ken) More?> y Yes. ?x = (grandparent cele karen) More?> y Yes. ?x = (grandparent carl ken) More?> n > If we didn't cut it off, it would go ahead and list all the facts that can be deduced from these rules! Some standard connectives are in the file STD.PRO. (Currently EQ , AND , OR , NOT, IF, IFF .) > (LOAD STD) > (EQ 3 6) > (EQ 3 3) Yes. > (AND (parent ?x ?y)(parent ?y ?z)) Yes. ?x = cele ?y = jack ?z = ken More?> y Yes. ?x = cele ?y = jack ?z = karen More?> n > ^C This is the way to leave E-Prolog. Don't forget to (CLOSE) if you have been writing to the disk. --------------------------------------------------------------- G. A. Edgar CompuServe 70715,1324 107 W. Dodridge St. Columbus, OH 43202 n) More?> y Yes. ?x = (father jack karen) More?> y Yes. ?x = (grandparent cele ken) More?> y Yes. ?x = (grandparent cele karen) More?> y Yes. ?x = (grandparent carl ken) More?> n > If we didn't cut it of[ A sample database for testing E-Prolog. See the documentation file EPRO.DOC. ] ((father jack ken)) ((father jack karen)) ((grandparent ?grandparent ?grandchild) (parent ?grandparent ?parent) (parent ?parent ?grandchild)) ((mother el ken)) ((mother cele jack)) ((parent ?parent ?child) (mother ?parent ?child)) ((parent ?parent ?child) (father ?parent ?child)) EPRO DOC^DEFGHIJKLMNOSAMPLE $$$[ This simple logic problem is found on p. 206 of the September, 1984, Scientific American, in the article "Computer Software for Intelligent Systems". To find out whether Marcus hates Caesar, use the query > (hates Marcus Caesar) ] [ 1. Marcus was a man.] ((man Marcus)) [ 2. Marcus was a Pompeian.] ((pompeian Marcus)) [ 3. All Pompeians were Romans.] ((roman ?X) (pompeian ?X)) [ 4. Caesar was a ruler.] ((ruler Caesar)) [ 5. All romans were either loyal to Caesar or hated him.] ((hates ?X Caesar) (roman ?X) (not-loyal-to ?X Caesar)) [ 6. People only try to assasinate rulers they are not loyal to.] ((not-loyal-to ?X ?Y) (man ?X) (tries-to-assasinate ?X ?Y)) [ 7. Marcus tried to assasinate Caesar.] ((tries-to-assasinate Marcus Caesar)) [ 8. A person hates someone who steals his wife.] ((hates ?X ?Y) (steals-wife-of ?Y ?X)) [ 9. If the wife of a man who is alive marries a second man, then the second man stole the first man's wife.] ((steals-wife-of ?X ?Y) (wife-of ?Z ?Y) (alive ?Y) (marries ?X ?Z)) [10. Lucretia was Marcus's wife.] ((wife-of Lucretia Marcus)) [11. Marcus was alive.] ((alive Marcus)) us was a man.] ((man Marcus)) [ 2. Marcus was a Pompeian.] ((pompeian Marcus)) [ 3. All Pompeians were Romans.] ((roman ?X) (pompeian ?X)) [ 4. Caesar was a ruler.] ((ruler Caesar)) [ 5. All romans were either loyal to Caesar or hated him.] ((hates ?X Caesar) (roman ?X) (not-loyal-to ?X Caesar)) [ 6. People only try to assasinate rulers they are not loyal to.] ((not-loyal-to ?X ?Y) (man ?X) (tries-to-assasinate ?X ?Y)) [ 7. Marcus tried to assasinate Caesar.] ((tries-to-assasinate Marcus Caesar)) [ 8. A person hates someone who steals his wife.] ((hates ?X ?Y) (steals-wife-of ?Y ?X)) [ 9. If the wife of a man who is alive marries a second man, then the second man stole the first man's wife.] ((steals- CANTONES.DOC An Explanation of CANTONES A Program to Teach Spoken Cantonese The Osborne1 Version (May 1986) ======================================================= (c) 1986 by Louie Crew. All rights reserved. .pa Contents I. What the Program Does II. Limitations of the Program III. The Files That You Receive IV. Use Main Menu PREPARING LESSONS An Overview Naming Files Entering data Ending the Entry of a Lesson Resuming Entry Correcting Mistakes THE REVIEWS The Quick Reviews List both Chinese and English Forms List English Forms Only Chinese Forms Only  The Slower Reviews Branching Scores A Sample Slow Review Translation Skills Specialized Reviews V. Creating New Files by Word Class A Tip On Alphabetizing Viewing the Lesson Data Files VI. MergePrinting Back Up Your Files VII. Ending a Session VIII. Improving This Program: A Note from the Author .pa CAN.BAS runs with the Osborne 1b. It is copyrighted "Free-Ware." Copy a friend's disk or download from an electronic bulletin board. Persons who use the program frequently may want to send a contribution to the researcher. Those who contribute at least US$10 will be informed of all future updates as registered users. Persons who don't use the program should give it to someone else who will. The program itself is free and must remain so. For those who cannot find a copy in another way, the author will supply a disk by air mail for US$15, or by local Hong Kong post for HK$70, to cover processing costs. Remit in either US$ or HK$. Warning: No one may sell this program; you may only give it away. The program comes with no guarantees, written or implied. .cp 7 Louie Crew (a.k.a. Li Min Hua) Department of English Chinese University Shatin, NT Hong Kong TELEX 50301 CUHK HX TELEGRAM SINOVERSITY .pa I. What the Program Does CANTONESE is designed to teach spoken Cantonese, but can readily adapt to Mandarin, or to any other language which the IBM keyboard can support, sometimes with no modifications. CANTONESE serves mainly to teach vocabulary and pronunciation. The program accommodates the tone system used by Parker Po-Fei Huang and Gerard P. Kok in Speak Cantonese, (New Asia--Yale-in-China Chinese Language Center, 1981), who distinguish the seven tones of Cantonese by using western script in combination with three superscript markers ( \ / and - ) and a silent letter "h," as with the following round vowel: _ o = high level \ o = high falling / o = high rising o = mid level \ oh = low falling / oh = low rising oh = low level CANTONESE keeps score about the user's success with four categories which the user mush master: word recognition tone recognition measure recognitimn sentence translation CANTONESE allows the user to review in different ways: prompted by Chinese or by English prompted with words or with sentences completing whole lessons or special categories of lessons testing only those items which one missed last time or the entire lesson again CANTONESE will print lessons, including lists of those words the user still does not know from a lesson, if you use it in connection with MailMerge of WordStar. The program is based on Crew's earlier version, "MailMerge Cantonese," Hong Kong Computer Journal (February 1985), awarded "Best Article of 1985 by the Hong Kong Computer Society. .cp 7 II. Limitations of the Program The program teaches nothing about written Chinese characters. The program teaches nothing about grammar. The program works best if one uses it in the context of a course, with lessons, textbook, audiotapes, and a class in which to practice. The program comes with only one sample lesson, to demonstrate how the program will work with any lessons which the user wants to learn. Users must finally talk to Cantonese speakers to test their real performance. The program augments the work of teachers, textbooks, and friends who are native speakers. The program allows learners to continue privately, at their own pace, processes which began in class, in books, or in live conversation. III. The Files That You Receive The full program contains the following files: LESSONEW Sample lessons. LESSONEX LESSONEY LESSONEZ SORT.COM A public-domain utility which lets you sort the files alphabetically, if you want to. SCORE.SP The file which stores data about your progress. (Empty at first) CAN.BAS The primary program CANTONES.DOC This documentation file. MERGETST.DOC A sample MergePrint file which MergePrints LESSONEX when used with MailMerge. (Serves as a model for other print options.) The program requires you to use your own MBASIC. You also must have at least one lesson to work at all. The program uses SCORE.SP to store data regarding your progress. You never have to open or close SCORE.SP on your own. CANTONESE maintains it automatically. It arrives empty because you have not yet taken a lesson, but it will soon hold your scores during your ten most recent reviews. The file must always appear in the same directory with CANTONESE for the program to to work properly. .cp 5 IV. Use To use, turn on your computer. Copy MBASIC.COM to the CANTONESE disk. Then log onto the drive with the CANTONESE and type: MBASIC CAN The program should load to the main menu: PREPARE NEW LESSONS 1 = Enter data 2 = Add data 3 = Edit REVIEW LESSONS PROMPTED WITH Chinese English 4 = Words 6 = Words 5 = Sentences 7 = Sentences 8 = Toggle to review by parts of speech (OFF) Just a quick list of (E)ng. (C)hinese (B)oth 0= END Enter: =========================================== Study the menus very closely. It can tell you almost everything else you will read in this booklet. It is your main guide to the program. The program should always return to the menu after you complete any one task. Preparing Lessons An Overview Since the program is not tied to any one textbook, users (teachers or students) will need to to prepare the lessons for review, typically by entering words from a textbook or from some other source, such as a native speaker's list of words around a particular subject one wants to master. Learners will often find that the task of typing the lessons into the computer effectively introduces them to the material; and often in the very first review of the lesson, they will already know a several items from this exposure. Many will not want to limit their use of the program to Cantonese, or even to Chinese. The program allows you to build vocabulary lists for any two languages which the IBM keyboard can support. The Main Menu specifies the options: 1 = Enter data 2 = Add data 3 = Edit "1" here begins a new lesson. "2" lets you continue adding material to an old lesson, as when you have stopped to do some other task or when you have discovered some new terms to add to your special word lists "3" lets you correct mistakes that you detect in lessons that you have already created. Naming Files In time you will want to establish clear conventions in naming files, especially to distinguish between permanent files and temporary ones. For example, if I am trying to learn most of my vocabulary from lessons in a textbook, I will want to create permanent files which contain all words in the lesson. Even as I learn more and more of the words in a lesson, I will want to keep the full lesson in tact. I will also want to have temporary files, to collect the items that I now do not know, so that I do not waste time reviewing material that I already know. CANTONESE collects mistakes automatically: whenever the user begins to review a lesson, the user must specify the name of a file which will store the items which the user did not know. Then next time, the user can elect to review only that smaller file, and from that, write the mistakes into hopefully an even smaller file, etc., until the latest file of "mistakes" is empty. Usually the user will want to return to the "permanent" file to test memory again. For this process to work efficiently, users need to name files in ways that distinguish between the permanent and the temporary. I recommend my own system: I name all permanent files from the same source in a similar way, such as L1, L2, L3.... for files which come from one source, SLANG1, SLANG2.... for files from another, etc. I name all temporary files REV1 or REV2. When I do, the program recognizes my convention and automatically writes the mistakes in REV1 to REV2, or the mistakes in REV2 to REV1, alternately. Or I may simply number between 1 to 10, or often just "1" and "2" alternately. I don't need to fill the disk with my mistakes, but I do need to store them briefly until I know them. Thereby my names always reflect a files relationship to other files. Whenever I begin a new sitting, I always know which files I can and cannot safely overwrite. Especially remember: the computer overwrites any old file if the user names a new file with the same name. Users will want to overwrite temporary files, to limit their proliferation. They are "temporary" precisely because you will not need them very long. For example, I might need to see the items I missed at 9 a.m. this morning for five more times, but I will not need to see them next week, unless I am too stupid to be learning a language at all. If next week I need to review the same lesson, I need to start with the entire lesson, or with a file I have renamed on purpose, such as HARD6 for the ones I found hardest in Lesson 6. Novices to computers will want to read their computer manual for additional material about the conventions computers require for file names, such as the restriction to a maximum of 8 continuous letters, plus an optional extension of up to a maximum of 3 continuous letters. The menu requires users to name files often. Do so purposefully, carefully. ********************* Enter data If you choose "1," the screen responds: Here are the files you already have: C: LESSONEW LESSONEX LESSONEY LESSONEZ SCORE .SP CAN.BAS CANTONES.DOC MERGETST.DOC What name would you like to give to your new lesson? Your own screen here will change to reflect any additions or subtractions to make to your collection of files as you continue to use the program. Notice: Of these here, only those which begin "Lesson" are lessons. You cannot review any of the other files, but you can review any which you have prepared with options 1, 2, or 3. Next you are prompted to enter data for each item: <> to end. Word in Chinese? \ Suppose you enter the Chinese word yahn. First you type the "y"; then the "a"; then the "\" ... The accent mark will appear over the previous letter automatically (unless you have come to the end of a line). The program recognizes only three such tone markers, and only when you respond to prompts for Chinese: \ = the slash descending to the right / = the slash ascending to the right - = the hyphen N.B.: the program regards these keys strictly as superscripts in Chinese entries: hence they are not available for other uses. Next the screen prompts: English? Here you would enter "person". Then the screen reviews the following parts of speech and prompts you to specify one: a = adverb p = particle at = attributive pat = patterns av = auxiliary verb ph = phrase bf = boundform pn = pronoun cv = coverb pv = postverb ev = equative verb pw = placeword fv = functive verb q = question i = interjection rv = resultative verb ie = idiomatic expression rve = resultative ending m = measure sp = specifier ma = movable adverb sv = stative verb n = noun vo = verb-object comp. nu = number tw = time word on = onomatopoeia x = other useful expressions --------------------------------------------- Part of speech? \ Since yahn is a noun, you would enter "n". Lower case matters here. Be consistent: use upper or lower case all of the time, if you want the program to match properly with several options that you will specify when you review the lessons! (Note: Programmers again could alter these codes to reflect different analyses of Cantonese or or any other languages. See the note at the end about the availability of the source code.) Non-programmers themselves can use different codes here without even changing the program, so long as they remember what codes they have used when later they ask to review items which match.) Since you specified "n" the program will ask you Measure? It will not ask for measure for other word classes. \ The correct measure for "yahn" is "go," which you would then enter. Next the program prompts: Sample Chinese sentence: - - \ / You might respond: Nidi yahn hou guih.<> Next the screen prompts: English? You would need to type "These people are very tired." Finally, the program plays back the full entry and asks: Is the full entry correct? Y/N If you say "N," you are allowed to re-enter it from the beginning. If you say "Y", the program prompts for the next word: Note: the program will also prompt "Correct? (Y/N)" for earlier entries in Chinese, but not for those in English. These prompts allow you to correct smaller, more difficult portions of the entry without having to retype the entire entry. In practice, those prompts speed rather than delay the task, since the Chinese entries are less familiar and provoke more mistakes more easily. Ending the Entry of a Lesson Whenever you complete the entry of one item in a lesson, the program prompts you again for another items, as before: .cp 4 Enter:  <> to end. Word in Chinese? The "<>" here means "carriage return" or "ENTER key." To end the session completely, hit the carriage return or the ENTER key. The screen will remind you of the name which you have given to your new file "Your new entries have created ..." and will prompt "Hit any key to return to the main menu." Make a note of the file name. Return to the main menu, and enter your next response, even if merely "0" to end the session. Remember: after each new item when you are entering a lesson, you will always return to this first prompt. Always end a session in the orderly way described. Otherwise you risk losing all data which you have entered for this lesson. You can fearlessly terminate your the creation of lessons prematurely, because the program allows you to return to the same lesson: Resuming Entry As we have seen, the Main Menu specifies the options:  1 = Enter data 2 = Add data 3 = Edit Choice 2 allows users to enlarge lessons created earlier. The program prompts for items exactly as in Choice 1, but first the user specifies an existing file to which the program will add them, rather than a new file. The program also lists all existing files so that the user can precisely name the file to be enlarged. Choice 2 especially helps one who needs to work in short segments of time while entering a long lesson. One closes each "incomplete" version in the orderly way described above; leaves to do something else; and returns to the lesson by Choice 2. Correcting Mistakes Choice 3 provides an orderly way for users to rectify mistakes after they have already created a file. It lists every item in a specified file individually, and prompts "Correct? Y/N." If the user says "N," the program prompts as the user re-enters that item completely.  THE REVIEWS The Quick Reviews Many times one wants merely to flash through a lesson, sometimes just to see what it there, sometimes to warm up for a more thorough session. The program provides three ways to do so: List both Chinese and English Forms If one responds with a "B" at the Main Menu, the program will list all words in a lesson giving both the Chinese and the English versions. When we type the letter, the screen prompts "Which of your files do you want to list?" and, to guide us as we choose, lists all of the files currently on the drive with the program. When we answer, as with LESSONEX, the program scrolls through the Chinese and the English words in that lesson: \ syu book / bouji newspaper \ Junggwok China / meihgwok America gwai expensive Hit any key for more... Notice that the program pauses when the screen fills. As you hit a key, you see more of the lesson, until you have seen all items. At the end of the lesson you have another choice: 1 = List another file 2 = Return to the main menu Enter: If you choose "1," you will review according to the same terms that you expressed in your first review (here, to see both Chinese and English together). The program prompts to you name the next lesson and you proceed. If you want to change terms for a different kind of review, choose "2" and specify your choice at the main menu. "2" here speeds up this process if you mainly want to flash through several lessons very quickly. .cp 4 List English Forms Only This review works just like Choice B, except that you flash through lessons with only the English words. This is very useful if you want quickly to test your knowledge of a lesson. .cp 4 List Chinese Forms Only This review works just like Choice B and Choice E, except that you flash through lessons with only the Chinese words. .cp 5 The Slower Reviews The heart of the program, and of any instruction, is the slower, more thoughtful review. The menu specifies: REVIEW LESSONS PROMPTED WITH Chinese English 4 = Words 6 = Words 5 = Sentences 7 = Sentences  8 = Toggle to review by parts of speech (OFF) The "slow" reviews add features essential to good instruction: Branching The more menu prompts the user to specify a file to collect the ones missed. Typically, in the next round you will want to review only those items, writing the mistakes in that round to yet another (hopefully smaller) file....until the file of mistakes is an empty file and you have succeeded in learning the lesson. (Alternatively, one may create specialized word lists by "missing" the ones desired for the lists. See Part V.) This feature keeps the program from boring you. It "branches," as any good program must, into what you personally need to know, and does not require you to stay with anyone's prior expectations, yours or those of the one who prepared the lesson which you have begun to review. It also keeps the program from paying false compliments, as it would if you continued to  get high scores but only because you limited your vision to what you already know. .cp 3 Scores The program keeps your score, in 4 categories: word recognition, proper tone designation (if you respond in Chinese), proper identification of measure (if the word is a noun), proper translation of sentences. At the end of any lesson, the program computes your score in all categories and reports it automatically. It also allows you to choose to see how you compare in this lesson with your score on the last 10 lessons (or as many as you have completed up to that number). This option lets you diagnose which of the 4 categories to concentrate more closely on next time. The program never lies to you about your progress or your lack of it. It does not court your approval, as many a teacher might. Nor do you have to worry about others knowing your mistakes. Many will find that they will sit at a lesson much longer merely under the compulsion to compete more effectively against their own private record. Note: the program gets you to help keep score. Some will consider this an annoyance, if not a "bug"; others an advantage. After you answer, the screen shows you the correct answer and asks "Correct? Y/N"--for each possible error. One key stroke sends you along. (The program never even shows the Y or N on the screen; nor does it require a carriage return.) Perhaps it would be nice for the computer to decide whether you were correct, but practically that would present more problems than efficiency now seems to warrant. For example, some will want to credit themselves as correct with a translation in which they have only one error in tone. Others will be stricter. Almost everyone will want the freedom to put tone markers over any letter in a syllable, not just over the letter arbitrarily chosen when the lesson was created. Spelling is not the object. Few Chinese people could read these phonetic transcriptions anyway. Their sole function is to point towards intonation and live performance. A Sample Slow Review Here follows a sample of the screens that would appear as one reviewed an a lesson slowly, prompted with English words--i.e., when one requests "6" on the menu. The double underlining here indicates a user's responses from the keyboard. (The file to which you wrote those missed last was: REV1). Type the name of the file which you would like to review. Note: the illustration here assumes that you have just reviewed another lesson. (If you have not, the sentence will appear without a file name where "REV1" appears here.) The program is reminding you that you wrote the items which you missed to a new file called "REV1" (or another specified file), in case you forgot). Often the file of misses is the file you want to review next. Type the name of the file which you would like to review. .cp 2 ? REV1 ==== Type the name of the file in which you would like to store the items that you miss: .cp 2 ? REV2 ==== .cp 7 Person / Chinese: yahn <> ======= \ yahn Note: the screen stops with the colon after "Chinese" until you enter your answer and hit a carriage return. Then the screen shows you the correct answer and asks Regarding the Word?  .cp 2 Correct? Y/N = Here you confirm with one key that you got it right or wrong, as with next question, where you missed one: Regarding the Tone? Correct? Y/N Measure: .cp 4 go == go .cp 5 RE measure: Correct? Y/N = Translate: These people are tired. .cp 3 - - \ / Nidi yahn hou guih.<> =================== .cp 2 - - \ / Nidi yahn hou guih. RE translation: .cp 2  Correct? Y/N = Because you acknowledged one one mistake, with tone the first time, the program will save this entire item into your new file of misses (here you named it "REV2"), so that you can review the entire entry again. The program will continue in the same fashion with the next word, the next.... The program will inform you when you have finished and will review your score. (Here we will assume that only this one item was in the file.): .cp 7 You have completed your review of: REV1 Summary 1 = Records in the file 1 = Records actually reviewed 100 = Percentage of records reviewed ------------------------------------- 75 = Overall score ************** 1 = Records with at least one error  100 = % of total Words missed: 0 or 0 % Measure missed: 0 or 0 % of tested Tone missed: 1 or 100 % Sentences missed: 0 or 0 % You earned only the 75% because you missed one of the four things tested for this item. If you had reviewed a longer lesson, these counts would be much more useful, as you would lose track of your score. Often that score keeps you informed well enough before you dive into the misses for another try. Sometimes, however, you want to back off for a fuller diagnosis as the program prompts: .cp 2 Do you want a fuller review? Y/N = Had you said "N," you would have the choice of immediately going to the file of mistakes or of returning to the Main Menu for full options. The full review follows. The statistics here will vary from your own scores. Always the program reports the scores for the most recent lesson first and then the score for 10 most lessons, whether or not the user has asked to review those scores each time. .cp 7 Regarding Words Not Recognized -------------------------------------------- File: Percentage REV1 0 REV2 0 REV1 0 LESSON1 1 REV2 0 REV1 17 REV2 17 REV1 40 REV2 70 REV1 80 LESSON14 95 Hit any key to review next category. Enter: Notice: The user here has recently reviewed two lessons, the current one, L1, (which has only 1 item in it, remember) and L14. Notice how the user improved the score each time with L14 until finally the user had no errors, at least no errors in word recognition. When the user hits any key, the program continues to review the score in like fashion for the other three categories monitored: Regarding Tones Missed Regarding Measure Missed Regarding Translations With Mistakes If for one particular review, one of these categories did not apply, the program specifies "N/A"--as when one reviewed a lesson prompted with Chinese and therefore did not test knowledge of tone. .cp 7 The full review concludes with a composite score: Enter: Here is a review of your overall scores on the recent lessons: Lesson Size Score  REV1 1 75 REV2 1 50 REV1 1 25 LESSON1 1 0 REV2 4 100 REV1 7 91 REV2 12 77 REV1 20 77 REV2 24 56 REV1 25 44 LESSON14 30 10 Here the user sees the progress, especially with the full LESSON14, which got smaller and smaller in the reviews of temporary files (here REV1 and REV2). The student still needs to review the full LESSON14 again to see whether these reviews have fixed the full list more permanently in mind. These scores show that the user has chosen to progress only with those most recently missed and needs to test real memory or all of LESSON14, especially of those items recognized once but not reviewed recently. The full score concludes with a reminder: Remember that you have stored all those with any errors in the new file called REV2 Hit any key to list them quickly. \ If the user hits a key, the screen shows the Chinese and English for yahn, since that is the item which the user had missed. Then the user must choose: 1 = Review this new file more slowly again saving those missed. 2 = Return to the main menu. .cp 5 Translation Skills The program reviews any example sentences stored with lessons. Sometimes you will create lessons without sample sentences. The program allows you to create lessons of either kind. Options 5 and 7 review only those items in lessons which include illustrative sentences. These options by-pass many of the fundamental questions about individual words. Most will not want to use them except for specialized instruction. Nevertheless, CANTONESE most effectively uses translation as an adjuncts to building vocabulary one word at a time. Options 5 and 7 will not really prove very useful, because of two special problems, though a few users may want the freedom to do so. The problems: The program writes any item ("record" is the official term) into one record line, maximally 254 characters long (including spaces, accents...every jot and tittle). After you have entered a word in Cantonese, then in English, then its measure, and its part of speech, typically you have room for maybe one line (80-columns) of sentence and one more line of translation. That is not much room for elaborate translation exercises. Besides, complicated translations do not make good use of the computer screen: a user's answers are too hard to match with stored answers when the eye must take in more than 2 lines at a time. Remember that the program will assume that you have ended entry for the entire lesson unless you enter more than a space or carriage return for the first prompt, the one that asks for a word in Chinese. Even if you user want to use only sentences, you person will still need to enter something, however meaningless, when prompted for the Chinese word. You can circumvent this problem by entering the same null character every time, such as "."-- but will not be able to ask for a quick review of the lesson, as it would list only a screen of dots. .cp 5 Specialized Reviews: Toggle for Parts of Speech A toggle works by hitting the specified key (here "8") to change its condition. It alternates ON or OFF.  If ON, this toggle does focus merely on the one part of speech which it later prompts you to specify. The condition when one load the program is stated on the main menu: 8 = Toggle to review by parts of speech (OFF) Users may choose to review words of just one class by first hitting "8." The screen will then show that the toggle is ON. This option when on allows the user to specify any one class of words to review within a lesson, either of a class which the user has chosen and remembered when entering the words, or of a class which the screen prompted for at entry time: a = adverb p = particle at = attributive pat = patterns av = auxiliary verb ph = phrase bf = boundform pn = pronoun cv = coverb pv = postverb ev = equative verb pw = placeword fv = functive verb q = question i = interjection rv = resultative verb ie = idiomatic expression rve = resultative ending m = measure sp = specifier ma = movable adverb sv = stative verb n = noun vo = verb-object comp. nu = number tw = time word on = onomatopoeia x = other useful expressions If a person has problems with words in any one of these classes, this option allows the user to focus. V. Creating New Files by Word Class With a little imagination, the user can exploit the toggle to generate specialized lessons of great variety. Thereby the toggle can serve very effectively to help one design additional instruction. Suppose, for example that after 10 lessons or so a user wants to review all time words. One can enter each lesson one at a time an toggle to review on the "tw" That method is easy enough--all that most users will need. But suppose that a teacher or learner wants to create a new, permanent file which contains all and only time words. Doing so is fairly easy: 1) Toggle "8" to ON. 2) Specify the class (here, tw) when prompted to do so 3) Specify the file to collect "mistakes" with a name that reflects your design, e.g., LESSONTW.3 -- to contain all time words from LESSON3. 4) "Miss" (i.e., say "N" when asked "CORRECT? Y/N" for at least one of the scores kept on each item. (You can then hit carriage return for all other answers to speed the "review") 5) Repeat steps 2-4 for each lesson from which you want to cull the time words, writing "mistakes" always to different files with the same name, but a different extension, in LESSONTW.1, LESSONTW.2.... 6) After you have culled time words from all files that you wanted to review, then at the CP/M prompt, type PIP LESSONTW.ALL=LESSONTW.* Specify a drive it pip.com is not on the logged drive. LESSONTW.ALL will contain all of your gleanings. These steps run very quickly and give you a huge freedom in building specialized word lists. Note that nothing prevents you from using other letters to designate word categories, so long as you do so when you enter the words initially into your word lists. .cp 5 A Tip On Alphabetizing Most word lists don't really need to be in alphabetical order, but that order helps for lists from which one frequently wants to isolate specific examples, as in special review lists, small dictionary-making, etc. Users can quickly sort any file which CANTONESE creates. Use the SORT.COM available from FOG and other CP/M boards and distributed with this disk. Enter the following sequence at CP/M command line: SORT FILETOBESORTED NEWFILE End the line with a carriage return, and put no spaces between the character and the file name. Add drive designators for any files not on the same drive with SORT.COM. Then inspect NEWFILE (or whatever name you specified) to confirm that it is alphabetized. Usually you will then enter the sequence: ERASE FILETOBESORTED REN NEWFILE FILETOBESORTED --supplying your own names for the files. Viewing the Lesson Data Files Users may also view their lesson files directly by using the non- document mode of their word-processors, but should do so very cautiously. Any alterations in the "comma separated variables" could make that file inaccessible to the computer. These files are not very intelligible, as the accent marks appear next to rather than above the appropriate letters. CANTONESE reads these files and reports them in the formats described earlier. VI. MergePrinting A sample MailMerge file (MERGETST.DOC) is included with the program for users familiar with WordStar. It shows how users can MergePrint data from the Lesson files. Users can modify this model for other formats, as to print flash cards, vocabulary tests, etc. This method makes print options much more available, as each user will already have installed the proper print codes for his or her version of WordStar. MERGETST.DOC prints the accents (\ / or -) to the right of the letter. If you want the accents over the letters, you can make a second copy of the lesson and use WordStar to add the codes for backspacing and superscripting for each of the three accents used. The procedure looks long, but actually works very quickly: 1. copy LESSONEX (or any other lesson you create) into a file of another name. 2. Let the new name replace the file named after .df in MERGETST.DOC. Better, make a copy of MERGETST.DOC and change the file name after .df to that of your lesson file altered to overprint the accents. 3. Enter the new copy of the lesson via WordStar. 4. Type ^QA 5. When prompted for string, enter \ 6. When prompted for replacement, enter ^PH^PT\^PT 7. When prompted for options, enter NG 8. Type ^QA 9. When prompted for string, enter / 10. When prompted for replacement, enter ^PH^PT/^PT 11. When prompted for options, enter NG 12. Type ^QA 13. When prompted for string, enter - 14. When prompted for replacement, enter ^PH^PT-^PT 15. When prompted for options, enter NG 16. Save the revised file 17. MergePrint either MERGETST.DOC (altered as in Step 2) or from a copy of MERGETST.DOC renamed after you have altered it. Back Up Your Files ALWAYS WORK FROM BACKED-UP COPIES, both with program files and with lessons that you create! You can create a submit file to backup lessons after each new creation, or, if you use the convention of naming all lesson files with LESSON as the first six characters, the following command line from drive B: (with your lessons) will copy your files to a backup disk in Drive A: B>PIP A:=B:LESSON?? Add a drive for PIP if you do not have it on Drive A. .cp 5 VII. Ending a Session Always end a session in an orderly fashion: type "0" when at the Main Menu. You will return to the CP/M prompt from which you began the program. Any other option on the Main Men will return you to the Main Menu when you have completed the task. In this way you will help to assure that your files will remain in tact. .cp 4 VIII. Improving This Program: A Note from the Author I am not a professional computer programmer. I am a writer who teaches Chinese people to write in English. I began this project strictly to help me prepare as I began to study Cantonese. First I wrote a version using MailMerge (see Hong Kong Computer Journal, February 1985). Then I wrote it in BASIC and continued to embellish it, especially to add the scoring feature that made me study more aggressively. Finally, I compiled it. I began on a CP/M machine, and only recently rewrote the program to run on my IBM clone. FOG also supplies that compiled program, as CANTONES.EXE. CANTONESE does a job that no other program now does. I avoided silly games, I hope. For example, the computer does not ask for your name and then say, "Mary, got got that one right, didn't you? Congratulations." Computers are not people, and I believe that people should learn from them without fiction. We never had that problem with flash cards, but some programmers treat the computer like a modern prayer wheel. CANTONESE never tires as it drills me. I don't want to wear out my teacher or my friends. I hope that my program will help them learn to speak Cantonese. I also hope that some other programmers will help to make the program better. I am now adapting the program to teaching English vocabulary to students of English. The program tests students' mastery of new vocabulary in most of their readings for our literature assignments. I hope that publishers of anthologies will soon provide much more sophisticated versions for the literature of all languages. I want be the among the first to use a program that will let me review Faulkner's or Proust's vocabulary after a chapter has just moved me. I will glady supply the source code for programmers who want to modify CANTONESE for other kinds of language instruction. Send US$ 15 to cover my costs in copying and mailing. I have still other programs which I have written for myself, which may also help others. Write me if you want more details. These now all are for MS-DOS only, however. STYLED A Program which profiles syntax CHINGLISH A Program which detects hundreds of forms of English which beset Chinese learners of English and prompts for revision. MUSES A Program which manages a writer's circulation data and related correspondence with publishers. (See Ratner's review in CODA, publication of Poets & Writers, Inc., Summer, 1986) APPLY A Program which manages data for applications--as for jobs, grants, etc. F Keeps up with all expenses and income, sorted into 55 categories, and posts periodic totals to an eXecute files for use in SuperCalc (see preliminary report in Portable Companion, 1985). CREW UTILITIES MS-DOS programs to convert case, recover parts of a file lost because the system insert preliminary end-of-file markers; a print program, which addresses envelopes by reading the inside address which you typed only on the letter; which makes indexing easy; which installs for 2 printers, names, 2 return addreses; which allows print-time formatting.... Computer users are reviving "community" in substantive ways which too many academic settings long ago abandoned. A few computer people still bark at a corner to protect their narrowness, but more and more are abandoning territoriality. That is what "free-ware" is all about--another tradition, that of hospitality, of kindness to the stranger within our gates--as old as Buddah, Beowulf, Ulysses, or Abraham. Please share reactions as you use this material. I hope that CANTONESE contributes modestly as you work to learn a language which will access the rich resources of friendship and culture which Cantonese opens. .cp 2 / \ Hou teng indeed! Louie Crew, a.k.a. Li Min Hua .pa CANTONES$$$cdefghijklmnopqrCANTONES$$$stuvwxyz{|}~CANTONES$$$10 PRINT CHR$(26) 20 ' Revised 10 September 1985 30 WIDTH 52 40 PRINT CHR$(27) + ")" 50 REM " CAN.BAS (C) 1985 by Louie Crew 60 PRINT " PREPARE NEW LESSONS 70 PRINT 80 PRINT " 1 = Enter data 2 = Add data 3 = Edit 90 PRINT 100 PRINT 110 PRINT " REVIEW LESSONS PROMPTED WITH 120 PRINT 130 PRINT " Chinese",," English" 140 PRINT 150 PRINT "4 = Words",," 6 = Words 160 PRINT "5 = Sentences",," 7 = Sentences 170 PRINT 180 PRINT "8 = Toggle to review by parts of speech " CHR$(27) + "("; 190 IF TOG>0 THEN 240 200 PRINT "(OFF)" CHR$(27) + ")" 210 GOTO 250 220 ' -- 230 ' 240 PRINT "(ON)" CHR$(27) + ")" 250 PRINT 260 PRINT " Just a quick list of (E)ng. (C)hinese (B)oth 270 PRINT 280 PRINT 290 PRINT " 9 = PRINT A FILE 0 = END 300 PRINT CHR$(27) + "(" 310 PRINT " (C) 1985 by Louie Crew"; 320 GOSUB 26000 330 IF Z$="1" THEN 3000 340 IF Z$="0" THEN 600 350 IF Z$="2" THEN 5000 360 IF Z$="4" THEN 700 370 IF Z$="5" THEN 800 380 IF Z$="6" THEN 900 390 IF Z$="7" THEN 1000 400 IF Z$="8" THEN 1100 410 IF Z$="3" THEN 10000 420 IF Z$="9" THEN 11000 430 IF Z$="C" OR Z$="c" OR Z$="E" OR Z$="e" OR Z$="B" OR Z$="b" THEN 12000 440 PRINT "Try again! 450 GOTO 320 460 ' -- 470 ' 600 PRINT CHR$(26) 610 END 620 ' -- 630 ' 700 PROMPT1$="1" 710 GOTO 5470 720 ' -- 730 ' 800 PROMPT1$="2" 810 GOTO 5470 820 ' -- 830 ' 900 PROMPT1$="3" 910 GOTO 5470 920 ' -- 930 ' 1000 PROMPT1$="4" 1010 GOTO 5470 1020 ' -- 1030 ' 1100 IF TOG=0 THEN 1150 1110 TOG=0 1120 GOTO 10 1130 ' -- 1140 ' 1150 TOG=1 1160 GOTO 10 1170 ' -- 1180 ' 3000 PRINT CHR$(26) 3010 PRINT "Here are the files you already have: 3020 PRINT 3030 FILES "*. " 3040 PRINT 3050 PRINT 3060 PRINT 3070 PRINT "What name would you like to give 3080 LINE INPUT "to the new file? (ALL CAPS): ",NEWFILE$ 3090 OPEN "O",#2,NEWFILE$ 3100 PRINT CHR$(26) 3110 PRINT " <> to end. 3120 PRINT 3130 PRINT "Word in Chinese? 3140 GOSUB 17000 3150 IF WORDC$="" GOTO 4010 3160 PRINT 3170 PRINT 3180 LINE INPUT "English? ",WORDE$ 3190 IF C=60 THEN 3380 3200 PRINT "-------------------------------------------- 3210 PRINT " a = adverb p = particle 3220 PRINT " at = attributive pat = patterns 3230 PRINT " av = auxiliary verb ph = phrase 3240 PRINT " bf = boundform pn = pronoun 3250 PRINT " cv = coverb pv = postverb 3260 PRINT " ev = equative verb pw = placeword 3270 PRINT " fv = functive verb q = question 3280 PRINT " i = interjection rv = resultative verb 3290 PRINT " ie = idiomatic expression rve = resultative ending 3300 PRINT " m = measure sp = specifier 3310 PRINT " ma = movable adverb sv = stative verb 3320 PRINT " n = noun vo = verb-object comp. 3330 PRINT " nu = number tw = time word 3340 PRINT " on = onomatopoeia 3350 PRINT 3360 PRINT ,"x = other useful expressions 3370 PRINT "--------------------------------------------- 3380 INPUT "Part of speech";P$ 3390 PRINT 3400 IF P$="n" THEN 3410 ELSE 3460 3410 PRINT "Measure? 3420 GOSUB 17100 3430 GOTO 3470 3440 ' -- 3450 ' 3460 MEASURE$="" 3470 PRINT 3480 PRINT 3490 PRINT "Sample Chinese sentence: 3500 GOSUB 17050 3510 IF CSENT$="" THEN 3520 ELSE 3560 3520 ESENT$="" 3530 GOTO 3590 3540 ' -- 3550 ' 3560 PRINT 3570 PRINT 3580 INPUT "English";ESENT$ 3590 PRINT CHR$(26) 3600 PRINT "Is the full entry correct? 3610 PRINT 3620 GOSUB 19000 3630 PRINT 3640 PRINT 3650 PRINT WORDE$ 3660 PRINT 3670 PRINT "Part of speech: ";P$ 3680 PRINT 3690 IF MEASURE$="" THEN 3740 3700 PRINT "Measure 3710 PRINT 3720 PRINT 3730 GOSUB 21000 3740 GOSUB 20000 3750 PRINT 3760 PRINT 3770 PRINT ESENT$ 3780 PRINT 3790 PRINT 3800 IF C=60 THEN 10240 3810 PRINT "Y/N 3820 GOSUB 26000 3830 IF C=70 THEN 10330 3840 IF Z$="Y" OR Z$="y" THEN 3970 3850 IF Z$="N" OR Z$="n" THEN 3900 3860 PRINT "Try again. " 3870 GOTO 3590 3880 ' -- 3890 ' 3900 PRINT CHR$(26) 3910 PRINT "Re-enter the data for this entry 3920 PRINT "from the start: 3930 PRINT 3940 GOTO 3110 3950 ' -- 3960 ' 3970 GOSUB 16000 3980 GOTO 3100 3990 ' -- 4000 ' 4010 CLOSE 4020 IF GUIDE=1 THEN 5340 4030 PRINT CHR$(26) 4040 PRINT "Your new entries have created ";NEWFILE$ 4050 PRINT 4060 PRINT "Hit any key to return to the main menu." 4070 GOSUB 26000 4080 GOTO 10 4090 ' -- 4100 ' 5000 PRINT CHR$(26) 5010 ON ERROR GOTO 5460 5020 ' -- 5030 ' 5040 PRINT "Enter the name of the lesson to which you 5050 PRINT "want to add data. 5060 PRINT 5070 PRINT "Here are your files: 5080 PRINT 5090 FILES "*. " 5100 PRINT 5110 PRINT "================================== 5120 PRINT 5130 PRINT 5140 PRINT 5150 PRINT 5160 INPUT OLDFILE$ 5170 GUIDE=1 5180 OPEN "I",#1,OLDFILE$ 5190 OPEN "O",#2,"TEMP1" 5200 IF EOF (1) THEN 5260 5210 LINE INPUT #1,VVV$ 5220 PRINT #2,VVV$ 5230 GOTO 5200 5240 ' -- 5250 ' 5260 CLOSE #1 5270 REM Now you go to the same entry requests you use for main menu choice 1 5280 PRINT CHR$(26) 5290 PRINT "You are adding entries to ";OLDFILE$ 5300 PRINT 5310 GOTO 3100 5320 ' -- 5330 ' 5340 PRINT CHR$(26) 5350 PRINT "You have finished updating ";OLDFILE$ 5360 PRINT "Your files are being closed 5370 CLOSE 5380 HH$=OLDFILE$+".BAK" 5390 KILL HH$ 5400 NAME OLDFILE$ AS HH$ 5410 NAME "TEMP1" AS OLDFILE$ 5420 GUIDE=0 5430 GOTO 10 5440 ' -- 5450 ' 5460 IF ERL=5390 THEN RESUME NEXT ELSE END 5470 PRINT CHR$(26) 5480 PRINT "Type the name of the file which you 5490 PRINT "would like to review. Use CAPS. 5500 PRINT 5510 PRINT "Here are your files: 5520 PRINT 5530 FILES "*. " 5540 PRINT 5550 PRINT 5560 PRINT "(The file to which you wrote those 5570 PRINT "missed last was: ";NEWFILE$;"). 5580 PRINT 5590 INPUT REVFILE$ 5600 PRINT 5610 PRINT "Type the name of the file in which you 5620 PRINT "would like to store the items 5630 PRINT "that you miss: (again, in CAPS) 5640 PRINT 5650 INPUT NEWFILE$ 5660 PRINT CHR$(26) 5670 IF TOG=0 THEN 5900 5680 PRINT 5690 PRINT "Indicate the specific category to review: 5700 PRINT 5710 PRINT " a = adverb p = particle 5720 PRINT " at = attributive pat = patterns 5730 PRINT " av = auxiliary verb ph = phrase 5740 PRINT " bf = bound form pn = pronoun 5750 PRINT " cv = coverb pv = postverb 5760 PRINT " ef = equative verb pw = placeword 5770 PRINT " fv = functive verb q = question 5780 PRINT " i = interjection pv = postverb 5790 PRINT " ie = idiomatic expression rv = resultative verb 5800 PRINT " m = measure rve = resultative ending 5810 PRINT " ma = movable adverb sp = specifier 5820 PRINT " n = noun sv = stative verb 5830 PRINT " nu = number tw = time word 5840 PRINT " on = onomatopoeia  vo = verb-obj. comp. 5850 PRINT 5860 PRINT ," x = Useful expressions 5870 PRINT 5880 INPUT PROMPT2$ 5890 IF PROMPT2$="" THEN 5900 ELSE 5910 5900 PROMPT2$="1" 5910 A=0 5920 B=0 5930 C=0 5940 D=0 5950 E=0 5960 F=0 5970 G=0 5980 H=0 5990 K=0 6000 L=0 6010 X=0 6020 REM A = RECORDS IN THE FILE 6030 REM B = RECORDS ACTUALLY REVIEWED 6040 REM C = WORDS (LETTERS) MISSED 6050 REM D = TONES MISSED 6060 REM E = MEASURES COUNTED 6070 REM F = MEASURES MISSED 6080 REM G = SENTENCES REVIEWED 6090 REM H = SENTENCES MISSED 6100 REM X <> 0 IDENTIFIES CHECK OF SENTENCES ONLY 6110 REM K = RECORDS WITH AT LEAST ONE ERROR 6120 REM L = COUNTS MULTIPLE ERRORS W/I ONE RECORD 6130 OPEN "I",#1,REVFILE$ 6140 OPEN "O",#2,NEWFILE$ 6150 IF EOF (1) THEN 7790 6160 A=A+1 6170 L=0 6180 GOSUB 15000 6190 IF PROMPT2$="1" THEN 6210 6200 IF P$=PROMPT2$ THEN 6210 ELSE 6150 6210 IF PROMPT1$="1" THEN 6250 6220 IF PROMPT1$="2" THEN 6750 6230 IF PROMPT1$="3" THEN 6960 6240 IF PROMPT1$="4" THEN 7560 6250 PRINT CHR$(26) 6260 B=B+1 6270 L=0 6280 GOSUB 19000 6290 PRINT 6300 PRINT 6310 PRINT 6320 LINE INPUT "Type the English: ",WASTE$ 6330 PRINT 6340 PRINT " ";WORDE$ 6350 PRINT 6360 PRINT "RE word: " 6370 GOSUB 28000 6380 IF Z$= "" THEN 6410 6390 C=C+1 6400 L=L+1 6410 IF P$="n" THEN 6420 ELSE 6560 6420 IF MEASURE$="" THEN 6560 6430 E=E+1 6440 PRINT 6450 PRINT "Measure: 6460 PRINT 6470 GOSUB 22000 6480 GOSUB 21000 6490 PRINT 6500 PRINT "RE measure: " 6510 PRINT 6520 GOSUB 28000 6530 IF Z$="" THEN 6560 6540 F=F+1 6550 L=L+1 6560 IF CSENT$="" THEN 6740 6570 PRINT 6580 PRINT "Translate: " 6590 G=G+1 6600 PRINT 6610 GOSUB 20000 6620 PRINT 6630 PRINT 6640 LINE INPUT WASTE$ 6650 PRINT 6660 PRINT ESENT$ 6670 PRINT 6680 PRINT "RE translation: " 6690 GOSUB 28000 6700 IF Z$= "" THEN 6730 6710 H=H+1 6720 L=L+1 6730 PRINT 6740 IF L>0 THEN 7740 ELSE 6150 6750 PRINT CHR$(26) 6760 X=X+1 6770 IF CSENT$="" THEN 6150 6780 B=B+1 6790 G=G+1 6800 GOSUB 20000 6810 PRINT 6820 PRINT 6830 PRINT "Translate: 6840 PRINT 6850 INPUT WASTE$ 6860 PRINT 6870 PRINT ESENT$ 6880 PRINT 6890 PRINT "Missed in any way? (Y/N) 6900 GOSUB 26000 6910 IF Z$="Y" OR Z$="y" THEN 6920 ELSE 6150 6920 H=H+1 6930 GOTO 7740 6940 ' -- 6950 ' 6960 PRINT CHR$(26) 6970 B=B+1 6980 L=0 6990 PRINT " ",WORDE$ 7000 PRINT 7010 PRINT "Type in Chinese: " 7020 PRINT 7030 GOSUB 22000 7040 PRINT 7050 PRINT " "; 7060 GOSUB 19000 7070 PRINT 7080 PRINT 7090 PRINT "RE tone: " 7100 GOSUB 28000 7110 IF Z$="" THEN 7140 7120 D=D+1 7130 L=L+1 7140 PRINT 7150 PRINT "RE word itself: " 7160 GOSUB 28000 7170 IF Z$="" THEN 7200 7180 C=C+1 7190 L=L+1 7200 IF P$="n" THEN 7210 ELSE 7370 7210 IF MEASURE$="" THEN 7370 7220 E=E+1 7230 PRINT 7240 PRINT "Measure? 7250 PRINT 7260 GOSUB 22000 7270 PRINT 7280 PRINT 7290 GOSUB 21000 7300 PRINT 7310 PRINT "RE measure: " 7320 GOSUB 28000 7330 IF Z$="" THEN 7360 7340 F=F+1 7350 L=L+1 7360 PRINT 7370 PRINT 7380 IF ESENT$="" THEN 7540 7390 PRINT "Translate: 7400 G=G+1 7410 PRINT 7420 PRINT ESENT$ 7430 PRINT 7440 GOSUB 22000 7450 PRINT 7460 GOSUB 20000 7470 PRINT 7480 PRINT 7490 PRINT "RE your translation: " 7500 GOSUB 28000 7510 IF Z$="" THEN 7540 7520 H=H+1 7530 L=L+1 7540 PRINT 7550 IF L>0 THEN 7740 ELSE 6150 7560 PRINT CHR$(26) 7570 X=X+1 7580 IF ESENT$="" THEN 6150 7590 B=B+1 7600 G=G+1 7610 PRINT ESENT$ 7620 PRINT 7630 PRINT "Translate: 7640 PRINT 7650 GOSUB 22000 7660 PRINT 7670 GOSUB 20000 7680 PRINT 7690 PRINT 7700 PRINT "Missed in any way? (Y/N) 7710 GOSUB 26000 7720 IF Z$="Y" OR Z$="y" THEN 7730 ELSE 6150 7730 H=H+1 7740 K=K+1 7750 GOSUB 16000 7760 GOTO 6150 7770 ' -- 7780 ' 7790 CLOSE 7800 IF PROMPT1$<>"2" AND PROMPT1$<>"4" THEN 7860 7810 Q=G/H*100 7820 PRINT CHR$(26) 7830 GOTO 8000 7840 ' -- 7850 ' 7860 PRINT CHR$(26) 7870 IF PROMPT1$="1" THEN 7880 ELSE 7940 7880 N=B+E+G 7890 P=C+F+H 7900 REM N=total possible P=total errors 7910 GOTO 7970 7920 ' -- 7930 ' 7940 N=B+B+E+G 7950 P=C+D+F+H 7960 REM see 8032 tones counted here and not there 7970 J=N-P 7980 Q=J/N*100 7990 REM J=No correct Q=% correct 8000 PRINT "You have completed your review of: ";REVFILE$ 8010 PRINT 8020 PRINT ,"Summary 8030 PRINT 8040 PRINT A," = Records in the file 8050 T=B/A*100 8060 PRINT B," = Records actually reviewed 8070 PRINT T," = Percentage of records reviewed 8080 PRINT "------------------------------------- 8090 PRINT Q," = Overall score ************** 8100 PRINT 8110 IF X<>0 THEN 8430 8120 PRINT K," = Records with at least one error 8130 S=K/B*100 8140 PRINT S; 8150 PRINT ," = % of total 8160 PRINT 8170 IF PROMPT1$="1" THEN 8180 ELSE 8220 8180 DD$="N.A." 8190 GOTO 8260 8200 ' -- 8210 ' 8220 DD=D/B*100 8230 DD$=STR$(DD) 8240 PRINT "Tones missed: ",D;" or "; 8250 PRINT DD;" % of tested 8260 CC=C/B*100 8270 CC$=STR$(CC) 8280 PRINT "Words missed: ",C;" or "; 8290 PRINT CC;" % 8300 IF E=0 THEN 8380 8310 FF=F/E*100 8320 FF$=STR$(FF) 8330 PRINT "Measure missed: ",F;" or "; 8340 PRINT FF;" % of tested 8350 GOTO 8400 8360 ' -- 8370 ' 8380 PRINT "No measures tested" 8390 FF$="N.A." 8400 IF G=0 THEN 8480 8410 HH=H/G*100 8420 HH$=STR$(HH) 8430 PRINT "Sentences missed: ",H;" or "; 8440 PRINT HH;" % 8450 GOTO 8500 8460 ' -- 8470 ' 8480 PRINT "No sentences tested." 8490 HH$="N.A." 8500 PRINT 8510 IF X<>0 THEN 9170 8520 V=0 8530 OPEN "I",#1,"SCORE.SP" 8540 OPEN "O",#2,"TEMP1" 8550 WRITE #2,REVFILE$,B,Q,CC$,DD$,FF$,HH$ 8560 IF V=10 THEN 8630 8570 INPUT #1,Z$,Y,X,W$,U$,T$,S$ 8580 V=V+1 8590 WRITE #2,Z$,Y,X,W$,U$,T$,S$ 8600 GOTO 8560 8610 ' -- 8620 ' 8630 CLOSE 8640 PRINT 8650 PRINT "------------------------------------------- 8660 PRINT 8670 KILL "SCORE.SP" 8680 NAME "TEMP1" AS "SCORE.SP" 8690 PRINT  "Do you want a fuller review? Y/N" 8700 GOSUB 27000 8710 PRINT CHR$(26) 8720 V=0 8730 IF Z$="N" OR Z$="n" THEN 9300 8740 RESTORE 8750 8750 DATA Words Not Recognized,Tones Missed,Measure Missed,Translations With Mistakes,x 8760 READ LABEL$ 8770 IF LABEL$="x" THEN 9160 8780 PRINT "Regarding ";LABEL$ 8790 PRINT "-------------------------------------------- 8800 PRINT 8810 OPEN "I",#1,"SCORE.SP" 8820 PRINT "File:","Percentage 8830 PRINT 8840 IF EOF (1) THEN 9060 8850 INPUT #1,Z$,Y,X,W$,U$,T$,S$ 8860 IF V<>0 THEN 8910 8870 PRINT Z$,W$ 8880 GOTO 8840 8890 ' -- 8900 ' 8910 IF V<>1 THEN 8960 8920 PRINT Z$,U$ 8930 GOTO 8840 8940 ' -- 8950 ' 8960 IF V<>2 THEN 9010 8970 PRINT Z$,T$ 8980 GOTO 8840 8990 ' -- 9000 ' 9010 IF V<>3 THEN 9030 9020 PRINT Z$,S$ 9030 GOTO 8840 9040 ' -- 9050 ' 9060 CLOSE 9070 V=V+1 9080 PRINT 9090 PRINT "Hit any key to review next category. 9100 PRINT 9110 GOSUB 26000 9120 PRINT CHR$(26) 9130 GOTO 8760 9140 ' -- 9150 ' 9160 PRINT CHR$(26) 9170 PRINT "Here is a review of your overall scores 9180 PRINT "on the recent lessons: 9190 PRINT 9200 PRINT "Lesson","Size","Score 9210 PRINT 9220 OPEN "I",#1,"SCORE.SP" 9230 IF EOF (1) THEN 9290 9240 INPUT #1,Z$,Y,X,W$,U$,T$,S$ 9250 PRINT Z$,Y,X 9260 GOTO 9230 9270 ' -- 9280 ' 9290 CLOSE 9300 PRINT 9310 PRINT "Remember that you have stored all those 9320 PRINT "with any errors in the new file called 9330 PRINT NEWFILE$ 9340 PRINT 9350 PRINT "Hit any key to list them quickly. 9360 PRINT 9370 PRP$=INPUT$(1) 9380 PRINT CHR$(26) 9390 PRINT 9400 SZ=0 9410 OPEN "I",#1,NEWFILE$ 9420 IF EOF (1) THEN 9700 9430 SZ=SZ+3 9440 GOSUB 15000 9450 IF PROMPT1$="3" OR PROMPT1$="4" THEN 9580 9460 GOSUB 19000 9470 PRINT 9480 PRINT WORDE$ 9490 PRINT 9500 IF SZ<15 THEN 9550 9510 PRINT ,,,"Hit any key to continue" 9520 HIC$=INPUT$(1) 9530 SZ=0 9540 PRINT CHR$(26) 9550 GOTO 9420 9560 ' -- 9570 ' 9580 PRINT WORDE$ 9590 GOSUB 19000 9600 PRINT 9610 PRINT 9620 IF SZ<18 THEN 9670 9630 PRINT ,,,"Hit any key to continue" 9640 HIC$=INPUT$(1) 9650 SZ=0 9660 PRINT CHR$(26) 9670 GOTO 9420 9680 ' -- 9690 ' 9700 CLOSE 9710 PRINT 9720 PRINT "1 = Review this new file more slowly 9730 PRINT " again saving those missed. 9740 PRINT 9750 PRINT "2 = Return to the main menu. 9760 GOSUB 26000 9770 IF Z$="2" THEN 10 9780 REVFILE$=NEWFILE$ 9790 IF NEWFILE$="REV1" THEN 9840 9800 NEWFILE$="REV1" 9810 GOTO 5890 9820 ' -- 9830 ' 9840 NEWFILE$="REV2" 9850 GOTO 5890 9860 ' -- 9870 ' 10000 PRINT CHR$(26) 10010 PRINT "Here are the files that you now have: 10020 PRINT 10030 FILES "*. " 10040 PRINT 10050 PRINT 10060 PRINT 10070 PRINT "What file would you like to edit? (ALL CAPS) 10080 PRINT 10090 ON ERROR GOTO 10480 10100 ' -- 10110 ' 10120 LINE INPUT EFILE$ 10130 OPEN "I",#1,EFILE$ 10140 OPEN "O",#2,"TEMP" 10150 C=60 10160 IF EOF (1) THEN 10390 10170 GOSUB 15000 10180 PRINT CHR$(26) 10190 PRINT "Your current entry reads: 10200 PRINT 10210 GOTO 3610 10220 ' -- 10230 ' 10240 PRINT "Okay? (Y/N) --If Y, you will see next item. 10250 PRINT 10260 GOSUB 26000 10270 IF Z$="Y" OR Z$="y" THEN 10340 10280 PRINT "Re-enter the full item completely: 10290 C=70 10300 GOTO 3100 10310 ' -- 10320 ' 10330 IF Z$="Y" OR Z$="y" THEN 10340 ELSE 3900 10340 GOSUB 16000 10350 C=60 10360 GOTO 10160 10370 ' -- 10380 ' 10390 CLOSE 10400 NN$=".BAK" 10410 N2$=EFILE$+NN$ 10420 KILL N2$ 10430 NAME EFILE$ AS N2$ 10440 NAME "TEMP" AS EFILE$ 10450 GOTO 10 10460 ' -- 10470 ' 10480 IF ERL=10420 THEN RESUME NEXT ELSE END 11000 PRINT CHR$(26) 11010 PRINT "Here are the files you already have: 11020 PRINT 11030 FILES "*. " 11040 PRINT 11050 PRINT 11060 PRINT 11070 PRINT "What file would you like to print? 11080 PRINT 11090 PRINT "Be sure that the printer is ONLINE 11100 PRINT "and paper at the first line. 11110 PRINT 11120 PRINT "Use the courier wheel, 12- or 10-pitch" 11130 PRINT 11140 LINE INPUT PRINTFILE$ 11150 LPRINT "Here are the contents of ";PRINTFILE$ 11160 LPRINT 11170 LLL=6 11180 OPEN "I",#1,PRINTFILE$ 11190 IF EOF (1) THEN 11410 11200 GOSUB 15000 11210 GOSUB 23000 11220 LPRINT WORDE$ 11230 LPRINT P$ 11240 LLL=LLL+3 11250 IF MEASURE$="" THEN 11290 11260 LPRINT "Measure: 11270 LLL=LLL+1 11280 GOSUB 25000 11290 IF CSENT$="" THEN 11330 11300 GOSUB 24000 11310 LPRINT ESENT$ 11320 LLL=LLL+2 11330 LPRINT 11340 LLL=LLL+2 11350 IF LLL<=62 THEN 11380 11360 LLL=3 11370 LPRINT CHR$(12) 11380 GOTO 11190 11390 ' -- 11400 ' 11410 CLOSE 11420 PRINT 11430 PRINT "1 = Print another file. 11440 PRINT "2 = Return to main menu. 11450 PRINT 11460 GOSUB 26000 11470 IF Z$="1" THEN 11000 11480 GOTO 10 11490 ' -- 11500 ' 12000 ROUTE$=Z$ 12010 COUNT1=0 12020 COUNT2=0 12030 PRINT CHR$(26) 12040 PRINT "Which of your files do you want to list?: 12050 PRINT 12060 FILES 12070 PRINT 12080 PRINT 12090 PRINT 12100 INPUT REVNOW$ 12110 PRINT CHR$(26) 1!2120 OPEN "I",#1,REVNOW$ 12130 IF EOF (1) THEN 12530 12140 GOSUB 15000 12150 IF ROUTE$="C" OR ROUTE$="c" THEN 12300 12160 IF ROUTE$="E" OR ROUTE$="e" THEN 12420 12170 COUNT1=COUNT1+4 12180 GOSUB 19000 12190 PRINT 12200 PRINT WORDE$ 12210 PRINT 12220 IF COUNT1<18 THEN 12130 12230 PRINT " Hit any key for more... 12240 PROMPT$=INPUT$(1) 12250 PRINT CHR$(26) 12260 COUNT1=0 12270 GOTO 12130 12280 ' -- 12290 ' 12300 GOSUB 19000 12310 PRINT 12320 COUNT2=COUNT2+1 12330 IF COUNT2<10 THEN 12130 12340 PRINT 12350 PRINT " Hit any key for more... 12360 PROMPT$=INPUT$(1) 12370 PRINT CHR$(26) 12380 COUNT2=0 12390 GOTO 12130 12400 ' -- 12410 ' 12420 PRINT WORDE$ 12430 COUNT2=COUNT2+1 12440 IF COUNT2<19 THEN 12130 12450 PRINT 12460 PRINT " Hit any key for more... 12470 PROMPT$=INPUT$(1) 12480 PRINT CHR$(26) 12490 COUNT2=0 12500 GOTO 12130 12510 ' -- 12520 ' 12530 CLOSE 12540 PRINT 12550 PRINT "1 = List another file 12560 PRINT "2 = Return to the main menu 12570 PRINT 12580 GOSUB 26000 12590 IF Z$="1" THEN 12010 ELSE 10 12600 ' -- 12610 ' 15000 INPUT #1,WORDC$,WORDE$,P$,MEASURE$,CSENT$,ESENT$ 15010 RETURN 15020 ' -- 15030 ' 16000 WRITE #2,WORDC$,WORDE$,P$,MEASURE$,CSENT$,ESENT$ 16010 RETURN 16020 ' -- 16030 ' 17000 ROUTE=1 17010 WORDC$="" 17020 GOTO 17120 17030 ' -- 17040 ' 17050 ROUTE=2 17060 CSENT$="" 17070 GOTO 17120 17080 ' -- 17090 ' 17100 ROUTE=3 17110 MEASURE$="" 17120 PRINT : FRY2=0 17130 Z$=INPUT$(1) 17135 Z=ASC(Z$) 17140 IF Z=13 THEN 18000 17150 IF ROUTE=2 THEN 17220 17160 IF ROUTE=3 THEN 17260 17170 WORDC$=WORDC$+Z$ 17175 FRY=LEN(WORDC$) 17190 GOTO 17270 17200 ' -- 17210 ' 17220 CSENT$=CSENT$+Z$ 17225 FRY=LEN(CSENT$) 17230 GOTO 17270 17240 ' -- 17250 ' 17260 MEASURE$=MEASURE$+Z$ 17265 FRY=LEN(MEASURE$) 17270 IF Z$="-" THEN 17300 17280 IF Z$="\" THEN 17340 17290 IF Z$="/" THEN 17380 ELSE 17430 17300 A$ = CHR$(11) + CHR$(8) + CHR$(45) + CHR$(10) 17310 GOTO 17390 17320 ' -- 17330 ' 17340 A$ = CHR$(11) + CHR$(8) + CHR$(92) + CHR$(10) 17350 GOTO 17390 17360 ' -- 17370 ' 17380 A$ = CHR$(11) + CHR$(8) + CHR$(47) + CHR$(10) 17390 Y$=A$ 17400 GOTO 17440 17410 ' -- 17420 ' 17430 Y$=Z$ 17440 PRINT Y$; 17442 IF FRY=50 OR FRY=100 OR FRY=150 THEN 17445 17444 GOTO 17130 17445 PRINT : PRINT 17450 GOTO 17130 17460 ' -- 17470 ' 18000 PRINT 18004 IF WORDC$="" THEN RETURN 18005 IF MEASURE$="" THEN RETURN 18010 IF ROUTE=1 GOTO 18080 18020 IF ROUTE=3 GOTO 18120 18030 IF CSENT$="" THEN RETURN 18040 GOSUB 20000 18050 GOTO 18130 18060 ' -- 18070 ' 18080 GOSUB 19000 18090 GOTO 18130 18100 ' -- 18110 ' 18120 GOSUB 21000 18130 PRINT 18140 PRINT 18150 PRINT "Correct? (Y/N)"; 18160 PROMPT$=INPUT$(1) 18170 IF PROMPT$="Y" OR PROMPT$="y" THEN RETURN 18180 PRINT CHR$(26) 18190 PRINT "Re-enter the Chinese: 18200 PRINT 18210 WORDC$="" 18220 CSENT$="" 18230 MEASURE$="" 18240 GOTO 17130 18250 ' -- 18260 ' 19000 PRINT 19010 R=0 19020 T=LEN(WORDC$) 19030 R=R+1 19040 WHILE R<=T 19050 X$=LEFT$(WORDC$,R) 19060 Y$=RIGHT$(X$,1) 19070 IF Y$="/" THEN 19100 19080 IF Y$="\" THEN 19140 19090 IF Y$="-" THEN 19180 ELSE 19220 19100 Z$= CHR$(11) + CHR$(8) + CHR$(47) + CHR$(10) 19110 GOTO 19230 19120 ' -- 19130 ' 19140 Z$= CHR$(11) + CHR$(8) + CHR$(92) + CHR$(10) 19150 GOTO 19230 19160 ' -- 19170 ' 19180 Z$= CHR$(11) + CHR$(8) + CHR$(45) + CHR$(10) 19190 GOTO 19230 19200 ' -- 19210 ' 19220 Z$=Y$ 19230 PRINT Z$; 19235 IF RR=50 THEN 19030 19240 IF R<50 THEN 19270 19250 PRINT 19255 RR=50 19260 PRINT 19270 GOTO 19030 19280 ' -- 19290 ' 19300 WEND 19310 RETURN 19320 ' -- 19330 ' 20000 PRINT 20010 R=0 20020 T=LEN(CSENT$) 20030 R=R+1 20040 WHILE R<=T 20050 X$=LEFT$(CSENT$,R) 20060 Y$=RIGHT$(X$,1) 20070 IF Y$="/" THEN 20100 20080 IF Y$="\" THEN 20140 20090 IF Y$="-" THEN 20180 ELSE 20220 20100 Z$=CHR$(11) + CHR$(8) + CHR$(47) + CHR$(10) 20110 GOTO 20230 20120 ' -- 20130 ' 20140 Z$=CHR$(11) + CHR$(8) + CHR$(92) + CHR$(10) 20150 GOTO 20230 20160 ' -- 20170 ' 20180 Z$=CHR$(11) + CHR$(8) + CHR$(45) + CHR$(10) 20190 GOTO 20230 20200 ' -- 20210 ' 20220 Z$=Y$ 20230 PRINT Z$; 20235 IF RR=50 THEN 20030 20240 IF R<50 THEN 20270 20250 PRINT 20255 RR=50 20260 PRINT 20270 GOTO 20030 20280 ' -- 20290 ' 20300 WEND 20310 RETURN 20320 ' -- 20330 ' 21000 PRINT 21010 R=0 21020 T=LEN(MEASURE$) 21030 R=R+1 21040 WHILE R<=T 21050 X$=LEFT$(MEASURE$,R) 21060 Y$=RIGHT$(X$,1) 21070 IF Y$="/" THEN 21100 21080 IF Y$="\" THEN 21140 21090 IF Y$="-" THEN 21180 ELSE 21220 21100 Z$= CHR$(11) + CHR$(8) + CHR$(47) + CHR$(10) 21110 GOTO 21230 21120 ' -- 21130 ' 21140 Z$= CHR$(11) + CHR$(8) + CHR$(92) + CHR$(10) 21150 GOTO 21230 21160 ' -- 21170 ' 21180 Z$= CHR$(11) + CHR$(8) + CHR$(45) + CHR$(10) 21190 GOTO 21230 21200 ' -- 21210 ' 21220 Z$=Y$ 21230 PRINT Z$; 21240 GOTO 21030 21250 ' -- 21260 ' 21270 WEND 21280 RETURN 2"1290 ' -- 21300 ' 22000 PRINT 22010 Z$=INPUT$(1) 22015 Z=ASC(Z$) 22020 IF Z=13 THEN RETURN 22030 IF Z$="-" THEN 22060 22040 IF Z$="\" THEN 22100 22050 IF Z$="/" THEN 22140 ELSE 22190 22060 A$ = CHR$(11) + CHR$(8) + CHR$(45) + CHR$(10) 22070 GOTO 22150 22080 ' -- 22090 ' 22100 A$ = CHR$(11) + CHR$(8) + CHR$(92) + CHR$(10) 22110 GOTO 22150 22120 ' -- 22130 ' 22140 A$ = CHR$(11) + CHR$(8) + CHR$(47) + CHR$(10) 22150 Y$=A$ 22160 GOTO 22200 22170 ' -- 22180 ' 22190 Y$=Z$ 22200 PRINT Y$; 22210 GOTO 22010 22220 ' -- 22230 ' 23000 R=0 23010 T=LEN(WORDC$) 23020 R=R+1 23030 WHILE R<=T 23040 X$=LEFT$(WORDC$,R) 23050 Y$=RIGHT$(X$,1) 23060 IF Y$="/" THEN 23090 23070 IF Y$="\" THEN 23130 23080 IF Y$="-" THEN 23170 ELSE 23210 23090 LPRINT CHR$(27) CHR$(68) CHR$(8) CHR$(47) CHR$(27) CHR$(85); 23100 GOTO 23020 23110 ' -- 23120 ' 23130 LPRINT CHR$(27) CHR$(68) CHR$(8) CHR$(92) CHR$(27) CHR$(85); 23140 GOTO 23020 23150 ' -- 23160 ' 23170 LPRINT CHR$(27) CHR$(68) CHR$(8) CHR$(45) CHR$(27) CHR$(85); 23180 GOTO 23020 23190 ' -- 23200 ' 23210 LPRINT Y$; 23220 GOTO 23020 23230 ' -- 23240 ' 23250 WEND 23260 LPRINT 23270 RETURN 23280 ' -- 23290 ' 24000 R=0 24010 T=LEN(CSENT$) 24020 R=R+1 24030 WHILE R<=T 24040 X$=LEFT$(CSENT$,R) 24050 Y$=RIGHT$(X$,1) 24060 IF Y$="/" THEN 24090 24070 IF Y$="\" THEN 24130 24080 IF Y$="-" THEN 24170 ELSE 24210 24090 LPRINT CHR$(27) CHR$(68) CHR$(8) CHR$(47) CHR$(27) CHR$(85); 24100 GOTO 24020 24110 ' -- 24120 ' 24130 LPRINT CHR$(27) CHR$(68) CHR$(8) CHR$(92) CHR$(27) CHR$(85); 24140 GOTO 24020 24150 ' -- 24160 ' 24170 LPRINT CHR$(27) CHR$(68) CHR$(8) CHR$(45) CHR$(27) CHR$(85); 24180 GOTO 24020 24190 ' -- 24200 ' 24210 LPRINT Y$; 24220 GOTO 24020 24230 ' -- 24240 ' 24250 WEND 24260 LPRINT 24270 RETURN 24280 ' -- 24290 ' 25000 R=0 25010 T=LEN(MEASURE$) 25020 R=R+1 25030 WHILE R<=T 25040 X$=LEFT$(MEASURE$,R) 25050 Y$=RIGHT$(X$,1) 25060 IF Y$="/" THEN 25090 25070 IF Y$="\" THEN 25130 25080 IF Y$="-" THEN 25170 ELSE 25210 25090 LPRINT CHR$(27) CHR$(68) CHR$(8) CHR$(47) CHR$(27) CHR$(85); 25100 GOTO 25020 25110 ' -- 25120 ' 25130 LPRINT CHR$(27) CHR$(68) CHR$(8) CHR$(92) CHR$(27) CHR$(85); 25140 GOTO 25020 25150 ' -- 25160 ' 25170 LPRINT CHR$(27) CHR$(68) CHR$(8) CHR$(45) CHR$(27) CHR$(85); 25180 GOTO 25020 25190 ' -- 25200 ' 25210 LPRINT Y$; 25220 GOTO 25020 25230 ' -- 25240 ' 25250 WEND 25260 LPRINT 25270 RETURN 25280 ' -- 25290 ' 26000 PRINT 26010 PRINT "Enter:" 26020 Z$="" 26030 Z$=INKEY$ 26040 IF Z$="" THEN 26030 26050 RETURN 26060 ' -- 26070 ' 27000 Z$=INPUT$(1) 27010 RETURN 27020 ' -- 27030 ' 28000 PRINT 28010 PRINT "Correct? Y/N"; 28020 GOSUB 27000 28030 PRINT 28040 IF Z$="Y" OR Z$="y" THEN 28050 ELSE 28060 28050 Z$="" 28060 IF Z$="" OR Z$="N" OR Z$="n" THEN 28110 28070 PRINT "Try again. 28080 GOTO 28000 28090 ' -- 28100 ' 28110 RETURN 28120 ' -- 28130 ' 29000 PRINT 29010 OPEN "O",#1,"TEMP" 29020 GOSUB 28000 29030 WRITE #1,Z$,Z$,Z$ 29040 IF Z$="Y" THEN 29060 29050 PRINT "This first 29060 PRINT "this second 29070 CLOSE 29080 END 29090 ' -- 29100 ' 9040 IF Z$="Y" THEN 29060 29050 PRINT "This first 29060 PRINT "this TO 25020 25150 ' -- 25160 ' 25170 LPRINT CHR$(27) CHR$(68) CHR$(8) CHR$(45) CHR$(27) CHR$(85); 25180 GOTO 25020 25190 ' -- 25200 ' 25210 LPRINT Y$; 25220 GOTO 25020 25230 ' -- 25240 ' 25250 WEND 25260 LPRINT 25270 RETURN 25280 ' -- 25290 ' 26000 PRINT 26010 PRINT "Enter:" 26020 Z$="" 26030 Z$=INKEY$ 26040 IF Z$="" THEN 26030 26050 RETURN 26060 ' -- 26070 ' 27000 Z$=INPUT$(1) 27010 RETURN 27020 ' -- 27030 ' 28000 PRINT 28010 PRINT "Correct? Y/N"; 28020 GOSUB 27000 28030 PRINT 28040 IF Z$="Y" OR Z$="y" THEN 28050 ELSE 28060 28050 Z$="" 28060 IF Z$="" OR Z$="N" OR Z$="n" THEN 28110 28070 PRINT "Try again. 28080 GOTO 28000 28090 ' -- 28100 ' 28110 RETURN 28120 ' -- 28130 ' 29000 PRINT 29010 OPEN "O",#1"ba-si/","bus","n","","","" "si/uba-","minibus","n","","","" "di-ksi/","taxi","n","","","" "fo che\","truck","n","","","" "fo/ che\","train","n","","","" "dihn che\","tram","n","","","" "da-an che ","bicycle","n","","","" "dihn da-an che\","motor cycle","","","","" "Haih me-","Really?!","x","","","" "ho\i da-ng","turn on the light (lit. open the light)","x","","","" "sai sa\m","meticulous","sv","","","" "Baat gwa","gossip","sv","","","" "Cha-t li\hng ya-t","gossip (sv; lit. 7 & 1, or 8)","x","","","" "Ngo/h lai\h ni-syu","I come here","x","","","" "ho/u nga/ahn fan","sleepy (lit. very eyes sleep)","x","","","" "ho/u Jung nga/ahn fan","dozing","x","","","" "fangaau","sleep (v)","sv","","","" "cho/h, ke/ih, fan, Jyuh (what do these have in common?)","The four verb that can use either pattern for phrases designating place","x","","","" "yahpla\ih","in","a","","","" "ti\hm","sweet (of food)","sv","","","" "ha\ahm","salty (of food, things...)","sv","","","" "yi-kwaahk","or (in questions only)"#,"a","","Haih ti\hmge yi-kwaahk ha\ahm ga?","Is this sweet or sour??" "syu\n","sour","sv","","","" "fu/","bitter","sv","","Haih syu\ng yi-kwaahk fu/ ga?","Is this sour or bitter?" "laaht","spicy, hot","sv","","","" "yiht","hot (as in very warm)","sv","","Nei/h sihk laaht yi-kwaahk yiht faahn a?","Do you prefer spicy or warm food?" "ge\ng","afraid","sv","","","" ur Files VII. Ending a Session VIII. Improving This Program: A Note from the Author .pa CAN.BAS runs with"","" "Ngo/h lai\h ni-syu","I come here","x","","","" "ho/u nga/ahn fan","sleepy (lit. very eyes sleep)","x","","","" "ho/u Jung nga/ahn fan","dozing","x","","","" "fangaau","sleep (v)","sv","","","" "cho/h, ke/ih, fan, Jyuh (what do these have in common?)","The four verb that can use either pattern for phrases designating place","x","","","" "yahpla\ih","in","a","","","" "ti\hm","sweet (of food)","sv","","","" "ha\ahm","salty (of food, things...)","sv","","","" "yi-kwaahk","or (in questions only)""syu\","book","n","bu/n, bouh","","" "bouji/","newspaper","n","je\ung, fahn","","" "Ju\nggwok","China","pw","","","" "me/ihgwok","America","pw","","","" "gwai","expensive","sv","","","" "Sa-i ba-an nga\h","Spain","pw","","","" "sa/i yi- ge-i","washing mashine (wash clothes machine)","n","","","" "la/ahng hei ge-i","airconditioner (cold air machine)","n","","","" "cheung ge-i","record player (singing machine)","n","","","" "da/ jih ge-i","typewriter (hit word machine)","n","","","" "Ngo/h ma-tye/h do-u yiu sihk","I want to eat everything.","x","","","" "cha-ak yihm","quiz (small test)","n","","","" "ha/au si/h","examination (formal, large test)","n","","","" "dihn sih","TV (electric see)","n","","","" "ta/i dihn sih","watch tv","x","","","" "sing daan faai lohk","Merry Christmas (holy birth merry)","x","","","" "sa\ang yaht faai lohk","Happy Birthday","x","","","" "wu- jou-","dirty","sv","","","" "Ne/ih heui bi-n (syu [or] douh) a?","Where are you going?","x","","","" "ya/mbu-i | or | ya/msing","cheers! [as drinking toast]","x","","","" "go-n bui-","Bottoms up! Dry (your) glass!","x","","","" h syu\ng yi-kwaahk fu/ ga?","Is this sour or bitter?" "laaht","spicy, hot","sv","","","" "yiht","hot (as in very warm)","sv","","Nei/h sihk laaht yi-kwaahk yiht faahn a?","Do you prefer spicy or warm food?" "ge\ng","afraid","sv","","","" ur Files VII. Ending a Session VIII. Improving This Program: A Note from the Author .pa CAN.BAS runs withdo-u yiu sihk","I want to eat everything.","x","","","" "cha-ak yihm","quiz (small test)","n","","","" "ha/au si/h","examination (formal, large test)","n","","","" "dihn sih","TV (electric see)","n","","","" "ta/i dihn sih","watch tv","x","","","" "sing daan faai lohk","Merry Christmas (holy birth merry)","x","","","" "sa\ang yaht faai lohk","Happy Birthday","x","","","" "wu- jou-","dirty","sv","","","" "Ne/ih heui bi-n (syu [or] douh) a?","Where are you going?","x","","","" "ya/mbu-i | or | ya/ms"sihk yeuhk","take medicine","vo","","","" "ma\hn go-","folk song","n","sa/u, ji\, jek","","" "dung","cold (weather, air, etc.)","sv","","","" "Hah ya-tgo Jaahm haih....(pw)","The next stop is...(pw)","x","","","" "la/ahngcha\n","catch a cold (illness)","vo","","","" "nyu/hn lou\h","heater","x","","","" "dihnya\uh Jaahm","gas station (electricity [oil] stop)","x","","","" "chi\h di- gin","see you later","x","","","" "se\ungfu\ng","cold (wind wounded)","v/n","","","" "Pou\htou\hnga\n","Portugal","pw","","","" "(go) ta-ai yiu Ba-m hei.","The tire needs (pumped) air.","x","","","" "sa\am suhp n/gh bohng","35 pounds (as for air in tire)","x","","","" "yahp mu/hn ke/uih","fill it up (as with gas)","x","","","" "Che/ng maht kaau gahn che\ mu\hn.","Please do not lean near the car doors.","x","","","" "tau\h","head","n&v","","","" "chi\h dou","late (lit. late arrive)","x","","","" "Ke/uih m\hai ni-douh jyuh la.","He does not live here.","x","","","" "che-ungmu/n","window","n","","","" "mu\hn","door","n","douh","","" "mo\uh","body hair","n","","","" "ta\uh faat","head hair","n","","","" "gwo\ng ta\uh lo/u","bald person","x","","","" "ho\i","open, start","fv","","","" "ho\i sam","happy (lit. open heart)","sv","","","" "gu\nghe/i","congratulations!","x","","","" "ho/i","sea","n","","","" "Di/m ye/ung go/ng Gwo/ngdu\ngwa/....","How do you say in Cantonese...?","x","","","" "Ni-go la/ihbaai ya-t","This Monday","tw","","","" "nga-ak","cheat","fv","","","" "ya-tgo yuht","one month","tw","","","" "ja/am","chop","fv","","Lea/h Si-nsa\ang ja/am cha\n ke/uihge yauhsa/u.","Mr. Li chopped his right hand." "ja-m","stitch","n","","","" "si-k","know how, acqainted with","vo","","","" "si\ufa","digest","vo","","","" "lyuhn","be in disorder, be confused","sv","","","" "hahgo la/ihbaai ya-t","next week on Monday","tw","","","" "che/un","stupid","sv","","","" "Nei/h di/m a?","How are you? (Short form)","x","","","" "yu\hng (yih; yu\hngyih)","easy","sv","","","" "yu\hngyih di-","easier","sv","","","" $"di-","er (comparitive suffix)","p","","","" "Di-m go/ng a?","How do you say?","x","","","" "Ga\na\hdaaih","Canada","pw","","","" "da-k ha\ahn","free (able to leisure)","x","","","" "\m da-kha\ahn","busy (unable to leisure)","x","","","" "ho/u mo\hng","very busy (more cultured form)","x","","","" "di/m","o/clock","tw","","","" "le/uhng di/m","two oclock","tw","","","" "le/uhng di/m sa\am","two twenty (oclock)","tw","","","" "Ge/i di/m a","What time is it?","x","","","" "fa\n","minutes (less popular, more precise form)","tw","","",""  TELEGRAM SINOVERSITY .pa I. What the Program Does CANTONESE is designed to teach spoken Cantonese, but can readily adapt to Mandarin, or to any other language which the IBM keyboard can support, sometimes with no modifications. CANTONESE serves mainly to teach vocabulary and pronunciation. The program ac"lohk yu/h","raining (down rain)","x","","","" "Che/ng maht Jaahm (Kaau) gahn che\ mu\hn.","Please stand (keep) clear of the car doors.","x","","","" "hah ya-t","next (lit. = down one)","x","","","" "seuhng ya-t","last (lit. = up one)","x","","","" "chi\hn yaht","day before yesterday","x","","","" "hauh yaht","day after tomorrow (lit. = behind one)","x","","","" "Baat Baak Buhn","Yaohan (lit. = 800 companions)","x","","","" "ya/m gu/n, ya/m tu/ng","straw (lit. = drink pipe)","x","","","" "Jeui + SV","form for the superlative","x","","","" "SV + di-","Form for the comparative","x","","","" "Mou/h la/ih maauh","impolite; rude","x","","","" "cho\u lo/uh","lacking delicacy; rude","x","","","" "si/u sa\m","careful (FV)","fv","","","" "Si/u sa\m bo! (the bo is not used with male peers)","Be careful.","x","","","" "syu syu do-u yau/h","everywhere","x","","","" "Ya-t Ga/u Baat N/gh","1985","x","","","" "Ha\hng Sa-ng Nga\hn Ho\hng","Hang Seng Bank (lit. Always Living Silver Dollar Store)","pw","","","" "Sa\n Ni\hn Faailohk","Happy New Year (formal)","x","","","" "Gu\nghe/i Faat Choi\h","Happy New Year (popular = Congratulations! Make Money!)","x","","","" "ni\hn","year","x","","","" "syu\gu/k","bookstore ","pw","","","" "da-k ha\ahn","free (able to leisure)","sv","","","" "m\da-k ha\ahn","busy","sv","","","" "ho/u mo\hng","very busy (cultured form)","sv","","","" "di/m","oclock","tw","","","" "le/uhng di/m","two oclock","x","","","" "le/uhng di/m sa\am","2:20","x","","","" "Ge/i di/m a?","What time is it?","x","","","" "fa\n","minutes (used for digital-type accuracy)","tw","","","" ","","" "si-k","know how, acqainted with","vo","","","" "si\ufa","digest","vo","","","" "lyuhn","be in disorder, be confused","sv","","","" "hahgo la/ihbaai ya-t","next week on Monday","tw","","","" "che/un","stupid","sv","","","" "Nei/h di/m a?","How are you? (Short form)","x","","","" "yu\hng (yih; yu\hngyih)","easy","sv","","","" "yu\hngyih di-","easier","sv","","","" "LESSON1",19,76.3158," 21.0526"," 26.3158","N.A.","N.A." "REV2",1,100," 0"," 0"," 0","N.A." "REV1",2,83.3333," 0"," 0"," 100"," 0" "REV2",11,94.2857," 0"," 0"," 16.6667"," 14.2857" "REV1",23,78.8732," 17.3913"," 30.4348"," 25"," 11.7647" "LESSON16",47,72.3881," 17.0213"," 25.5319"," 38.4615"," 44.4445" "LESSON15",42,46.9231," 50"," 47.619"," 72.7273"," 50" "1",3,100," 0","N.A."," 0","N.A." "LESSON3",28,90.9091," 7.14286","N.A."," 20","N.A." "LESSON14",1,100," 0","N.A.","N.A."," 0" "LESSON14",1,0," 100"," 100","N.A."," 100" ,90.9091," 7.14286","N.A."," 20","N.A." "LESSON14",1,100," 0","N.A.","N.A."," 0" "LESSON14",1,0,"CAN BASRLESSONEW LESSONEX LESSONEY LESSONEZ SCORE $$$1SORTV rev 1.3 $ :Rͥ3L++DONE++$!~@#=^~#I:] ʁ:m t@t!l !\ L++Error - Command format requires an input name, and an output name.$\2N#F+ w# w +*\q#p{z "\^#V|7~#+7!"W2h2|!\ \\<*ͭo>!U_!U\L++DONE++$##~!U_~ ¯> !U_^#V|7L++Can't make output file$~# x^#V#N#FxI#~G#~#fo>>}ƀo|g+~+w+++#~g}o|g~ +p+q^#V#N#F w#~½G#~#fo-}ƀo|g{++6+6+p+q^#V#N#F#xyx2N#F+ w# w +*\q#p{z "\^#V|7~#+7!"W2h2|!\ \\<*ͭo>!U_!U\L++DONE++$##~!U_~ ¯> !U_^#V|7L++Can't make output file$~# x^#V#N#FxI#~G#~#fo>>}ƀo|g+~+w+++#~g}o|g~ +p+q^#V#N#F w#~½G#~#fo-}ƀo|g{++6+6+p+q^#V#N#F#xyx "A" goto Measure: &measure& .ef .ex &csent& => "1" goto &csent& &esent& .ef JRTMAN APD-.JRTMAN APEf/0123456789:;JRTMAN APF<=EPRO COM.>?@ABCEPRO DOC^DEFGHIJKLMNOSAMPLE PROPSCIAM PRO QRCANTONESDOCSTUVWXYZ[\]^_`abCANTONESDOCcdefghijklmnopqrCANTONESDOCstuvwxyz{|}~CANTONESDOCCAN BASCAN BASRLESSONEW LESSONEX LESSONEY LESSONEZ SCORE SP SORT COM PRINT $$$ This is the release date of the disk. ANTONESDOC s@ANTONESDOC -CPM174 DOC CAN BAS iAN BAS )LESSONEW LESSONEX LESSONEY LESSONEZ SCORE SP SORT COM PRINT MM EPRO .COM C7 32 5888 46 EPRO .DOC 9D A8 12032 94 SAMPLE .PRO 14 09 384 3 SCIAM .PRO 15 A2 1280 10 CANTONES.DOC D6 82 49664 388 CAN .BAS 39 25 26880 210 LESSONEW. 0A 7A 1536 12 LESSONEX. 54 8D 1536 12 LESSONEY. BB 65 3072 24 LESSONEZ. 21 43 2048 16 SCORE .SP B7 05 640 5 SORT .COM C6 7E 1152 9 PRINT  Fog Library Disk FOG-CPM.174 Copyright (1987) by Fog International Computer Users Group to the extent not copyrighted by the original author for the exclusive use and enjoyment of its members. Any reproduction or distribution for profit or personal gain is strictly forbidden. For information, contact FOG, P. O. Box 3474, Daly City, CA. 94015-0474. as part of the description of a file indicates that the program is distributed on a "try first, pay if you like it" basis. If you find the program(s) meet your need, please refer to the author's documentation for information on becoming a registered user. Only by registering and paying for the programs you like and use will the authors of such programs continue development. Often, more complete documentation, additional modules, and new releases are available only to registered users. Disk 4 of 4. JRT Pascal. Filename Description -04-00 .87 This is the release date of the disk. -CPM174 .DOC This is the description of the disk contents. JRTMAN .102 E1DE 7K ver. 4.0 [JRT Pascal 57 of 78] JRTMAN .104 7911 3K ver. 4.0 [JRT Pascal 58 of 78] JRTMAN .105 DE5A 24K ver. 4.0 [JRT Pascal 59 of 78] JRTMAN .APA 9C24 3K ver. 4.0 [JRT Pascal 60 of 78] JRTMAN .APB 8EAA 2K ver. 4.0 [JRT Pascal 61 of 78] JRTMAN .APC 223F 3K ver. 4.0 [JRT Pascal 62 of 78] JRTMAN .APD 22E4 2K ver. 4.0 [JRT Pascal 63 of 78] JRTMAN .APE 5A6B 13K ver. 4.0 [JRT Pascal 64 of 78] JRTMAN .APF 5F02 2K ver. 4.0 [JRT Pascal 65 of 78] EPRO .COM C732 6K ver. 4.0 [JRT Pascal 66 of 78] EPRO .DOC 9DA8 12K ver. 4.0 [JRT Pascal 67 of 78] SAMPLE .PRO 1409 1K ver. 4.0 [JRT Pascal 68 of 78] SCIAM .PRO 15A2 2K ver. 4.0 [JRT Pascal 69 of 78] CANTONES.DOC D682 49K ver. 4.0 [JRT Pascal 70 of 78] CAN .BAS 3925 27K ver. 4.0 [JRT Pascal 71 of 78] LESSONEW. 0A7A 2K ver. 4.0 [JRT Pascal 72 of 78] LESSONEX. 548D 2K ver. 4.&0 [JRT Pascal 73 of 78] LESSONEY. BB65 3K ver. 4.0 [JRT Pascal 74 of 78] LESSONEZ. 2143 2K ver. 4.0 [JRT Pascal 75 of 78] SCORE .SP B705 1K ver. 4.0 [JRT Pascal 76 of 78] SORT .COM C67E 2K ver. 4.0 [JRT Pascal 77 of 78] PRINT .MM EF95 1K ver. 4.0 [JRT Pascal 78 of 78] 5,3)-"&mdiskno"-".DOC" TO malt SET ALTE TO &malt SET ALTE ON DO WHILE diskno="&mdiskno".AND. .NOT. EOF() IF diskno="000" IF dfile="FOG-DOS" ? " '