Classic Computer Magazine Archive A.N.A.L.O.G. ISSUE 67 / DECEMBER 1988 / PAGE 43

D: CHECK
in Action!


by Steven Yates

Because of the nature of the Action! system, typing checkers like D: CHECK (Issue 16) cannot be implemented. A lack of line numbers leaves no way to communicate to the user where typos are. Moreover, the flexibility in the source program's form makes finding errors difficult-without requiring the reader to type the program exactly as it appears.
    D:CHECK in Action! gives you a program (D: CHECK.ACT) which works with the Action! system to provide interactive checking and correcting of typing errors. Instead of printing a list of numbers which you compare to a similar list in the magazine, this Action! version finds the errors and puts you back into the editor at their approximate locations in your source.
    This extra power takes some more typing on your part. If you look at Listing 1, you'll notice the first few lines contain a set of numbers headed "CHECKSUM DATA." All other Action! programs printed in ANALOG Computing will have similar lines at the start of their listings.
    These lines give D:CHECK in Action! its power. The program generates numbers from what you've typed and compares them to the numbers here. If there are any discrepancies, it will then help you to find the problems so they can be corrected.
    When typing in the listing, these lines must be typed in exactly as printed.
    There are square brackets at the beginning and end of the checksum list, and one space between each value. All values are two-digit numbers and must be typed as such. After these lines are typed, the remainder of the program can be entered in any way you wish.
    You may type it as listed, or you may decide not to include the blank lines inserted for easier reading. You may add more blank lines, if you like. You may combine short lines to form one line with a space or more between the originals; or you could break long lines into two or more lines, so everything fits on the screen.
    The program ignores spaces; so you don't need to indent lines, and you can add spaces if it's more readable for you. D:CHECK in Action! also ignores comments, so you can leave them out and save some typing or add some of your own.
    This flexibility of program form is basic to the Action! system which D:CHECK in Action! preserves. Remember, any modifications to the form of the program may make it more difficult to compare to the original if there's a problem-use your judgement. Anything between quotes must be typed exactly as shown, including spaces and upperand lowercase letters.

D: CHECK in Action!
gives you a program which
works with the Action!
system to provide interactive
checking and correcting
of typing errors.

    The latter presents another problem. Action! allows you to type in whatever case you want, but also offers the option of being case sensitive. This lets you have two or more variables of the same name, with different letters in uppercase to distinguish them.
    D:CHECK in Action! offers the same option. If the article doesn't specify otherwise, you may use either case. If the program must be compiled with the case-sensitive option, the words Case Sensitive will appear with the checksum data. You must type all letters in the case in which they're listed. Because it must be able to handle other case-sensitive programs, D:CHECK in Action! must also be able to compile under this option; so remember to type each letter properly.

Using it
    First, type in Listing 1 and save it. Because the program can't check itself until it compiles successfully, you must be careful keying it in. Don't forget that the program is case-sensitive.
    Try compiling. If there are any compile errors, fix them as you normally would. Once D:CHECK in Action! compiles, run it. If the program says there are no problems, you're ready to use it for other programs printed in ANALOG Computing.
    If it tells you there are problems, follow the directions below. The program cannot guarantee the locations it gives for errors in its own source file because typing errors may be causing problems with its error-locating routines. Be sure to save a final copy after you've fixed all the errors, as D:CHECK.ACT (cassette users may save it as C:).
    To check another program containing the checksum numbers, type it in and save a copy. With the newly typed program still in memory, go to the monitor. If the article says the program is case-sensitive, use the monitor option command to set it for this; otherwise set this option to "no."
    When this is done, type R"D:CHECK.ACT" (cassette users, type R"C:"). The program will load from disk, compile, then run. It must be uncompiled when stored, because it needs to relocate itself for each program checked.
    If the program being checked isn't too large (about 100 disk sectors), time can be saved by loading D:CHECK.ACT into the second editing window. It can then be compiled and run without accessing the disk each time.
    To do this, type in the program to be checked and save it. Enter Window 2 by pressing CTRL-SHIFT-2, read D:CHECK.ACT, then enter the monitor and use C and R to compile and run.
    To rerun D:CHECK.ACT after a problem's corrected, just enter Window 2 (CTRL-SHIFT-2) before returning to the monitor, then compile and run as before. If you don't move the cursor to Window 2 before entering the monitor, Action! will attempt to compile the program in Window 1, and D:CHECK.ACT won't be executed.
    If you get an out-of-memory error when loading or compiling D:CHECK.ACT, make sure your source program is saved and use the monitor boot command to reset Action!. Then reload your program and run D:CHECK.ACT from disk or tape as explained previously.
    If the D:CHECK.ACT program says there are no problems, you should be able to compile the program. If it does find a problem, it will display the checksum lines on-screen, with one number highlighted. It will ask if the sum was typed correctly.
    Check the highlighted value against the magazine listing. If they don't match, press N in response to its question. Return to the editor. The cursor will be on the first digit of the incorrect sum. Retype the sum, return to the monitor and repeat the command to run D:CHECK.ACT.
    If the highlighted sum matches that printed in the magazine, press Y. The program will tell you to return to the editor and check the line containing the cursor, plus a certain number of lines following it. The number of lines to check depends mostly on the line length, and blank lines aren't counted.
    Find any mistakes you can on these lines, correct them, return to the monitor and rerun D:CHECK.ACT. Once you've found all errors and are given a clean check, save a final copy, then compile and run it, according to the directions in the related article.
    It's possible that a program which checks out all right won't compile. If this happens, return to the editor and make sure you didn't insert or delete a space, which would confuse the compiler. Check the word the cursor's on and change it to look exactly as it does in the magazine. This should be the only thing to cause a problem in a properly checked program.
    Now you should be able to enjoy printed Action! programs without being frustrated by cryptic compiler errors or having a program compile and not perform as expected. If you remember the difference D:CHECK made in the time it took to get a BASIC program running, you'll type in D:CHECK in Action! as soon as possible.


Because the program can't check
itself until it compiles successfully,
you must be careful keying it in.
Don't forget it is casesensitive.


;  CHECK.ACT
; Steven Yates
;  12/02/85

;     CHECKSUM DATA
;[9E 43 B1 2D 74 DD 67 7C
; 13 30 E5 8F 7A CA C9 77
; AD AE 96 44 B0 F8 99 39
; EB ]

BYTE StartChar,CurChar,Count,X,
     Flag=[0],Character,Sum,ISum,
     Product,Key,Case=[0],Column=1152,
     Sensitive=[1],Lines,SumLine,
     WrongLine,Segment=[0],String=[1],
     SubString=[2],Space=[32]
CARD StartLine,Line=1160,
     FirstLine=1156
BYTE ARRAY Sums(256)
CARD ARRAY SumLines(32)
BYTE POINTER Length
CARD POINTER CurLine,NextLine,
             WrongSum

DEFINE is="=", not="<>", Done="Flag=1"

PROC End_Of_Line()

  DO
    CurLine=NextLine^
    CurChar=7
    Length=CurLine+6
    NextLine=CurLine+4
    IF CurLine=0 THEN
      EXIT
    FI
    UNTIL Length^>0
  OD

RETURN

PROC Quotes()

  IF Segment is String THEN
    Segment=0
  ELSE
    Segment=String
  FI

RETURN

PROC Ignore()

  X==-1
  count==-1
  Character=0

RETURN

PROC Check_Line()

  Character=Peek(CurLine+CurChar)
  IF Segment is SubString THEN
    Segment=0
  ELSEIF Character='" THEN
    Quotes ()
  ELSEIF Segment is String THEN
  ELSEIF Character='' THEN
    Segment is SubString
  ELSEIF Character is Space THEN
    Ignore()
  ELSEIF Character='; THEN
    Ignore()
    CurChar=Length^+6
  ELSEIF Case not Sensitive AND
         Character>96 AND
         Character<123 THEN
    Character==-32
  FI
  Product=(X*Character) RSH Case
  Sum==+Product
  CurChar==+1
  X==+1
  IF X=4 THEN
    X=1
  FI

RETURN

PROC Find_Sums()

  DO
    DO

  Character=Peek(CurLine+CurChar)
  IF Character not '; THEN
    End_Of_Line()
  ELSEIF Length^>l. THEN
    EXIT
  ELSE
    End_Of_Line()
  FI
  IF CurLine=0 THEN
    Done
    EXIT
  FI
OD
CurChar=8
Character=Peek(CurLine+CurChar)
IF Character is '[ THEN
  EXIT
FI
IF Done THEN
  PrintE("Listing does not")
  PrintE("contain checksums.")
      PutE()
      PrintE("Cannot CHECK!")
      EXIT
    FI
    End_Of_Line()
  OD

RETURN

PROC Get_Sums()

 BYTE I
 BYTE ARRAY Hex(1)

  Find-Sums()
  SumLine=0
  DO
    IF Done THEN
      EXIT
    FI
    SumLines(SumLine)=CurLine
    CurChar=9
    FOR ISum=0 TO 7 DO
      FOR I=0 TO 1 DO
        Hex(I)=Peek(CurLine+CurChar+I)
        IF Hex(I))='A THEN
          Hex(I)==-('A-'9-1)
        FI
        Hex(I)==-'0
      OD
      Sum=(Hex(0) LSH 4)+Hex(1)
      Sums(SumLine*8+ISum)=Sum
      IF Peek(CurLine+CurChar+3] is ']
       THEN
        Done
        EXIT
      FI
      CurChar==+3
    OD
    End-Of-Line()
    IF Done THEN
      Flag=0
      EXIT
    FI
    SumLine==+1
  OD

RETURN

PROC Mistyped()

  Line=StartLine
  Column=StartChar
  PrintE("Return to editor and check")
  Print("the ")
  PrintB(Lines)
  PrintE(" lines following the line")
  Print("the cursor is on for a ")
  PrintE("typo.")

RETURN

PROC Bad_Sum()

 BYTE I

  IF Case is Sensitive THEN
    Print("If article does not ")
    PrintE("specify")
    Print("case sensitive, use ")
    PrintE("option")
    Print("command to set this to ")
    PrintE("no.")
    PutE()
    PutE()
FI
WrongLine=ISum/8
Sum=ISum&7
WrongSum=SumLines(WrongLine)+9+Sum*3
WrongSUM^==%$8080
FOR I=0 TO SumLine DO
  PrintE(SumLines(I)+6)
OD
WrongSUM^==!$8080
PutE()
Print("Is highlighted sum correct?")
Key=GetD(1)
Key==%32
PutE()
  PutE()
  IF Key='y THEN
    Mistyped()
  ELSE
    Print("Return to editor and ")
    PrintE("correct")
    PrintE("mistyped sum.")
    Line=SumLines(WrongLine)
    Column=(Sum+1)*3
  FI

RETURN

PROC No_Problems()

  PrintE("Program CHECKS out fine.")
  PrintE("Save program and use")
  PrintE("according to directions")
  PrintE("in the article.")
  Done

RETURN

PROC Check_Sum()

  IF Sum<>Sums(ISum) THEN
    Bad_Sum()
    Done
  FI
  ISum==+1

RETURN

PROC Initialize()

  IF Peek(1226)=255 THEN
    Case is Sensitive
  FI
  X=1
  CurLine=FirstLine
  Length=CurLine+6
  NextLine=CurLine+4
  IF Length^=0 THEN
    End_Of_Line()
  FI
  CurChar=7
  Close(1)
  Open (1,"K:",4,8)

RETURN

PROC D_Check()

  Initialize()
  Get-Sums()
  ISum=0
  DO
    IF Done THEN
      EXIT
    FI
    Sum=0
    Lines=0
    FOR Count=0 TO 127 DO
      IF Count=0 THEN
        StartLine=CurLine
        StartChar=CurChar-6
      FI
      Check-Line()
      IF CurChar=Length^+7 THEN
        End_Of_Line()
        IF CurLine=0 THEN
          Check_Sum()
          IF Done THEN
            EXIT
          FI
          No_Problems()
          EXIT
        FI
        Lines==+1
      FI
    OD
    IF Done THEN
      EXIT
    FI
    Check_Sum()
  OD
  Close(1)

RETURN