home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Amiga 3 / MA_Cover_3.iso / maksiu / extensions / varcheck101.lha / VarChecker.AMOS / VarChecker.amosSourceCode
Encoding:
AMOS Source Code  |  1992-02-26  |  16.3 KB  |  548 lines

  1. '****************************************************************************
  2. '**      Variable Checker V1.01  -  By Paul Hickman (ph@doc.ic.ac.uk)      **
  3. '**                                                                        **
  4. '**  Requires AMOS Pro & Easylife V1.4+   Distributed as freeware          **
  5. '****************************************************************************
  6. Set Accessory 
  7.  
  8. '
  9. 'MXVARS is the maximum number of variable names in your program
  10. 'NUMCOMMANDS is the number of commands which may be confused with  
  11. 'variable names (See Line 34).   
  12. '
  13. Set Buffer 80
  14. MXVARS=300 : NUMCOMMANDS=6
  15. '
  16.  
  17. Dim NAME$(MXVARS,1),NAME(MXVARS,4),TYPE$(4),COMMAND$(NUMCOMMANDS)
  18. Global AL$,NAME$(),NAME(),LAST,GLO,SHA,LOC,FLP,COMMAND$()
  19. 'NAME(N,0)=Type (See Below)
  20. 'NAME(N,1)=Number of local uses. 
  21. 'NAME(N,2)=Number of global assignments.   
  22. 'NAME(N,3)=Number of global references.  
  23. 'NAME(N,4)=Line Number of definition.  
  24. '
  25. GLO=1 : TYPE$(1)="Global"
  26. SHA=2 : TYPE$(2)="Shared"
  27. LOC=3 : TYPE$(3)="Local"
  28. FLP=4 : TYPE$(4)="For Loop"
  29. LAST=0
  30.  
  31. For A=1 To NUMCOMMANDS : Read COMMAND$(A) : Next 
  32.  
  33. '************************************************************************  
  34. 'These are the commands to ignore - Set NUMCOMANDS at the top of the code
  35. 'to the number of them.
  36.  
  37. Data "Scene X","Scene Y","Imouse X","Imouse Y","Jd Char X","Jd Char Y"
  38.  
  39. '************************************************************************
  40.  
  41. INIT_SCREEN
  42.  
  43. ' Make sure we are an accessory
  44. If Prg Under<>1
  45.    If Exist("VarChecker.Doc")
  46.       Read Text "VarChecker.Doc"
  47.    Else 
  48.       NULL=Dialog Box(AL$,1,"This program must be run as an accessory!")
  49.    End If 
  50.    MN_QUIT
  51. End If 
  52.  
  53. ' Initialise Program Listing 
  54. '  
  55. TITLE
  56. Clear Key 
  57.  
  58. ' Open all procedures  
  59. Call Editor 89 : Rem Equ("AEd_UnfoldAll") 
  60.  
  61. ' Ask number of lines
  62. Ask Editor 5 : NLINES=Param : Rem Equ("AEdAsk_NumberOfLines")  
  63.  
  64. ' Top of text
  65. Call Editor 17 : RemEqu("AEd_TopOfText")
  66.  
  67. SCOPE$="MAIN PROGRAM"
  68. For N=1 To NLINES
  69.    Ask Editor 1,N : LINE$=Param$ : Rem Equ("AEdAsk_CurrentLine")
  70.    SP= Extension_16_00C8(LINE$,32)
  71.    LINE$=Mid$(LINE$,SP)
  72.    If Left$(LINE$,7)="Shared "
  73.       _DECLARE[Mid$(LINE$,8),SCOPE$,SHA,N,False]
  74.    End If 
  75. Next 
  76.  
  77. For N=1 To NLINES
  78.    
  79.    'Read the current line 
  80.    
  81.    Ask Editor 1,N : LINE$=Param$ : Rem Equ("AEdAsk_CurrentLine")
  82.    
  83.    'Ignore whole line comments
  84.    
  85.    SP= Extension_16_00C8(LINE$,32)
  86.    LINE$=Mid$(LINE$,SP)
  87.    If(SP>0) and(Asc(LINE$)<>39)
  88.       
  89.       'Replace all quoted strings with 0.
  90.       
  91.       Repeat 
  92.          A1= Extension_16_00AA(LINE$,"'") : If A1=0 : A1=Len(LINE$)+1 : End If 
  93.          A2= Extension_16_00AA(LINE$,'"') : If A2=0 : A2=Len(LINE$)+1 : End If 
  94.          A=Min(A1,A2)
  95.          If A<Len(LINE$)+1
  96.             If A=A1
  97.                AA= Extension_16_00BC(LINE$,"'",A)
  98.             Else 
  99.                AA= Extension_16_00BC(LINE$,'"',A)
  100.             End If 
  101.             If AA
  102.                LINE$=Left$(LINE$,A-1)+"0"+Mid$(LINE$,AA+1)
  103.             Else 
  104.                LINE$=Left$(LINE$,A-1)
  105.             End If 
  106.          End If 
  107.       Until A=Len(LINE$)+1
  108.       
  109.       'Check for procedure definition      
  110.       
  111.       If Left$(Upper$(LINE$),9)="PROCEDURE"
  112.          
  113.          'Get procedure name for scope of local variables 
  114.          
  115.          P= Extension_16_008C(LINE$,91)
  116.          If P
  117.             SCOPE$=Mid$(LINE$,11,P-11)
  118.          Else 
  119.             SCOPE$=Mid$(LINE$,11)
  120.          End If 
  121.          
  122.          'Record declaration of parameters as local variables 
  123.          
  124.          _DECLARE[Mid$(LINE$,P+1,Len(LINE$)-P-1),SCOPE$,LOC,N,False]
  125.          
  126.          
  127.          
  128.       Else If Left$(LINE$,8)="End Proc"
  129.          
  130.          'Pass End Proc's argument string for references
  131.          
  132.          If Mid$(LINE$,9,1)="["
  133.             PARSE_ARGS[Mid$(LINE$,10,Len(LINE$)-10),SCOPE$,False,N]
  134.          End If 
  135.          
  136.          'Scan for local variables/parameters were not refered to, and
  137.          'shared variables that were not refered to, or set to a value. 
  138.          
  139.          A=0 : While A<LAST
  140.             If NAME$(A,1)=SCOPE$
  141.                If NAME(A,1)=0
  142.                   If NAME(A,0)=LOC
  143.                      'Allow NULL to be unreferenced 
  144.                      If(NAME$(A,0)<>"NULL") and(NAME$(A,0)<>"NULL#") and(NAME$(A,0)<>"NULL$")
  145.                         DLOG["Unreferenced Local Variable: "+NAME$(A,0)]
  146.                      End If 
  147.                   Else 
  148.                      If NAME(A,0)=SHA
  149.                         DLOG["Unused Shared Variable: "+NAME$(A,0)]
  150.                      End If 
  151.                   End If 
  152.                End If 
  153.                If NAME(A,0)>=LOC
  154.                   'Remove all local/for loop variables from array  
  155.                   For AA=A To LAST+1
  156.                      For XX=0 To 4 : NAME(AA,XX)=NAME(AA+1,XX) : Next 
  157.                      NAME$(AA,0)=NAME$(AA+1,0)
  158.                      NAME$(AA,1)=NAME$(AA+1,1)
  159.                   Next 
  160.                   Dec LAST
  161.                Else 
  162.                   NAME(A,1)=0
  163.                   Inc A
  164.                End If 
  165.             Else 
  166.                Inc A
  167.             End If 
  168.          Wend 
  169.          
  170.          'Change scope to outside procedure 
  171.          
  172.          SCOPE$="MAIN PROGRAM"
  173.          
  174.          
  175.          
  176.          
  177.       Else If Left$(LINE$,7)="Shared "
  178.          'Record declaration of shared variables
  179.          _DECLARE[Mid$(LINE$,8),SCOPE$,SHA,N,False]
  180.          
  181.       Else If Left$(LINE$,7)="Global "
  182.          'Record declaratino of global variables
  183.          _DECLARE[Mid$(LINE$,8),SCOPE$,GLO,N,False]
  184.          
  185.       Else 
  186.          'Splitup the line into it's statements, and parse each in turn.
  187.          
  188.          While LINE$<>""
  189.             Exit If Left$(LINE$,4)="Rem "
  190.             SEP= Extension_16_00AA(LINE$,":")
  191.             If SEP
  192.                STATE$=Left$(LINE$,SEP-2)
  193.                LINE$=Mid$(LINE$,SEP+2)
  194.             Else 
  195.                STATE$=LINE$ : LINE$=""
  196.             End If 
  197.             '
  198.             PARSE_STAT[STATE$,N,False]
  199.          Wend 
  200.          
  201.       End If 
  202.    End If 
  203.    
  204.    'Move to the next line of program source.
  205.    
  206.    Call Editor 2 : Rem Equ("AEd_Down")
  207.    
  208. Next 
  209.  
  210. For A=0 To LAST
  211.    If(NAME$(A,0)<>"") and(NAME(A,0)<>FLP) and(NAME$(A,0)<>"NULL") and(NAME$(A,0)<>"NULL#") and(NAME$(A,0)<>"NULL$")
  212.       If(NAME(A,2)=0) and(NAME(A,3)=0)
  213.          Call Editor 76,NAME(A,4)
  214.          DLOG["Unused "+TYPE$(NAME(A,0))+" Variable: "+NAME$(A,0)]
  215.       Else If(NAME(A,2)=0) and(NAME(A,0)<>LOC)
  216.          Call Editor 76,NAME(A,4)
  217.          DLOG["Undefined "+TYPE$(NAME(A,0))+" Variable: "+NAME$(A,0)]
  218.       Else If NAME(A,3)=0
  219.          Call Editor 76,NAME(A,4)
  220.          T$=TYPE$(NAME(A,0))
  221.          If(NAME(A,0)=LOC) and(NAME$(A,1)="MAIN PROGRAM") : T$="Main Program" : End If 
  222.          DLOG["Unreferenced "+T$+" Variable: "+NAME$(A,0)]
  223.       End If 
  224.    End If 
  225. Next 
  226. NULL=Dialog Box(AL$,1,"Scan completed. No more undeclared or unreferenced variables")
  227. MN_QUIT
  228.  
  229. Procedure INIT_SCREEN
  230.    
  231.    'Generates code to draw requesters.
  232.    
  233.    Restore ALT
  234.    Repeat 
  235.       Read A$ : AL$=AL$+A$
  236.    Until A$=""
  237.    For A=1 To 7 : Trap Screen Close A : Next 
  238.    Resource Screen Open 0,640,40,0
  239.    Curs Off : Flash Off : Cls 0
  240.    Screen Display 0,,60,,
  241.    Wait Vbl 
  242.    
  243.    Paper 0 : Pen 1
  244.    Pop Proc
  245.    
  246.    ' QUICK RUN DIALOG BOXES 
  247.    ' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
  248.    ALT: Data " "
  249.    ' One button, CANCEL 
  250.    ' ~~~~~~~~~~~~~~~~~~ 
  251.    Data "SIze   SW,SH;"
  252.    Data "BAse   SWidth SX -2/,SHeight SY- 2/;"
  253.    Data "IF     0VA 0=;"
  254.    Data "["
  255.    Data "BOx    0,0,1,SX,SY;"
  256.    Data "POut   1VACX,16,1VA,0,7;"
  257.    Data "BU 0,0,0,SX,SY,0,0,0;[][SM;]"
  258.    Data "]"
  259.    Data "IF     0VA 1=;"
  260.    Data "["
  261.    Data "BOx    0,0,1,SX,SY;"
  262.    Data "POut   1VACX,8,1VA,0,7;"
  263.    Data "BU 1,SX112-,SY16-,96,16,0,0,1;[LI 0,0,41BP3*+,SX;PR 'Quit' CXBP+,1,'Quit',7;][BR0;BQ;]"
  264.    Data "KY 27,0;"
  265.    Data "BU 0,0,0,SX,SY,0,0,0;[][SM;]"
  266.    Data "RUn    0,3;"
  267.    Data "]"
  268.    Data "IF     0VA 2=;"
  269.    Data "["
  270.    Data "BOx    0,0,1,SX,SY;"
  271.    Data "POut   1VACX,8,1VA,0,7;"
  272.    Data "BU 1,16,SY16-,96,16,0,0,1;[LI 0,0,41BP3*+,SX;PR 'Continue'CXBP+,1,'Continue',7;][BR0;BQ;]"
  273.    Data "KY 13,0;"
  274.    Data "BU 2,SX112-,SY16-,96,16,0,0,1;[LI 0,0,41BP3*+,SX;PR 'Stop'CXBP+,1,'Stop',7;][BR0;BQ;]"
  275.    Data "KY 27,0;"
  276.    Data "BU 0,0,0,SX,SY,0,0,0;[][SM;]"
  277.    Data "RUn    0,3;"
  278.    Data "]"
  279.    Data "EXit;"
  280.    Data ""
  281.    
  282. End Proc
  283. Procedure MN_QUIT
  284.    'Closes everything 
  285.    
  286.    Trap Dialog Close 
  287.    Trap Screen Close 0
  288.    Erase All : Close 
  289.    Edit 
  290. End Proc
  291. Procedure _DECLARE[L$,SCOPE$,TYPE,N,REF]
  292.    'Records the declaration of a list of variables.   
  293.    
  294.    While L$<>""
  295.       
  296.       'Get variables from list 
  297.       A=0
  298.       Repeat 
  299.          A= Extension_16_00BC(L$,",;",A)
  300.       Until Extension_16_051C(Left$(L$,A),40)= Extension_16_051C(Left$(L$,A),41)
  301.       If A
  302.          A$=Left$(L$,A-1)
  303.          L$=Mid$(L$,A+1)
  304.       Else 
  305.          A$="" : Swap A$,L$
  306.       End If 
  307.       
  308.       'A$=Next variable
  309.       'Check for brackets after, which means it is an array, or the
  310.       'last word of a command, and should be ignored, however, the 
  311.       'contents of the brackets show be checked for references.
  312.       
  313.       B1= Extension_16_008C(A$,40)
  314.       If B1>0
  315.          If Mid$(A$,B1+1,1)<>")"
  316.             PARSE_ARGS[Mid$(A$,B1+1,Len(A$)-B1-1),SCOPE$,False,N]
  317.          End If 
  318.       Else 
  319.          If A$=Upper$(A$)
  320.             'Ignore reserved variables / bits of command names, which
  321.             'will contain lower case variables.  
  322.             
  323.             'Check if this name is already declared in this scope. 
  324.             _SEARCH[A$,SCOPE$,False,TYPE=SHA] : R=Param
  325.             
  326.             If R=>0
  327.                'It is. That means this is a use, for non-local variables
  328.                If TYPE=GLO
  329.                   'A Global command occurs after variable use
  330.                   If NAME(R,0)=SHA
  331.                      DLOG["Global Variable "+A$+" Is Shared In Some Procedures "]
  332.                   Else 
  333.                      DLOG["Variable "+A$+" Made Global AFTER Use"]
  334.                   End If 
  335.                   NAME(R,0)=GLO
  336.                Else If(NAME(R,0)<>LOC)
  337.                   Inc NAME(R,1) : Inc NAME(R,2)
  338.                End If 
  339.             Else 
  340.                'Otherwise, record the declaration.
  341.                A=0
  342.                If LAST>0
  343.                   While NAME$(A,0)<A$ : Inc A : Exit If A=LAST : Wend 
  344.                   
  345.                   For AA=LAST To A Step -1
  346.                      NAME$(AA+1,0)=NAME$(AA,0)
  347.                      NAME$(AA+1,1)=NAME$(AA,1)
  348.                      For XX=0 To 4 : NAME(AA+1,XX)=NAME(AA,XX) : Next 
  349.                   Next 
  350.                End If 
  351.                NAME$(A,0)=A$
  352.                NAME$(A,1)=SCOPE$
  353.                NAME(A,0)=TYPE
  354.                If REF
  355.                   NAME(A,1)=1
  356.                   NAME(A,2)=0
  357.                   NAME(A,3)=1
  358.                Else 
  359.                   NAME(A,1)=0
  360.                   NAME(A,2)=1
  361.                   NAME(A,3)=0
  362.                End If 
  363.                NAME(A,4)=N
  364.                Inc LAST
  365.             End If 
  366.          End If 
  367.       End If 
  368.       
  369.       
  370.    Wend 
  371. End Proc
  372. Procedure PARSE_STAT[STATE$,N,FSTAT]
  373.    Shared SCOPE$
  374.    If Left$(STATE$,5)="Trap "
  375.       PARSE_STAT[Mid$(STATE$,6),N,False]
  376.       
  377.    Else If(Left$(STATE$,7)="Input #") or(Left$(STATE$,12)="Line Input #")
  378.       HASH= Extension_16_008C(STATE$,35)
  379.       SEP=0
  380.       Repeat 
  381.          SEP= Extension_16_009E(STATE$,44,SEP)
  382.       Until Extension_16_051C(Left$(STATE$,SEP),40)= Extension_16_051C(Left$(STATE$,SEP),41)
  383.       PARSE_ARGS[Mid$(STATE$,HASH+1,SEP-HASH),SCOPE$,False,N]
  384.       _DECLARE[Mid$(STATE$,SEP+1),SCOPE$,LOC,N,False]
  385.       
  386.    Else If Left$(STATE$,6)="Input "
  387.       SEP= Extension_16_010C(STATE$,59)
  388.       If SEP
  389.          PARSE_ARGS[Mid$(STATE$,6,SEP-6),SCOPE$,False,N]
  390.          _DECLARE[Mid$(STATE$,SEP+1),SCOPE$,LOC,N,False]
  391.       Else 
  392.          _DECLARE[Mid$(STATE$,6),SCOPE$,LOC,N,False]
  393.       End If 
  394.       
  395.       
  396.    Else If Left$(STATE$,4)="For "
  397.       PARSE_STAT[Mid$(STATE$,5),N,True]
  398.       
  399.    Else If(Left$(STATE$,5)="Read ") and(Left$(STATE$,10)<>"Read Text$")
  400.       _DECLARE[Mid$(STATE$,6),SCOPE$,LOC,N,False]
  401.    Else If(Left$(STATE$,5)="Goto ") or(Left$(STATE$,6)="Gosub ") or(Left$(STATE$,5)="Proc ")
  402.       'Do Nothing
  403.    Else If(Left$(STATE$,8)="Restore ") or(Left$(STATE$,7)="Resume ") or(Left$(STATE$,6)="Def Fn")
  404.       'Also Do nothing 
  405.       
  406.    Else If(Left$(STATE$,3)="On ")
  407.       A=Instr(STATE$," Proc ")
  408.       If A>0 : PARSE_ARGS[Mid$(STATE$,4,A-4),SCOPE$,False,N] : End If 
  409.       A=Instr(STATE$," Goto ")
  410.       If A>0 : PARSE_ARGS[Mid$(STATE$,4,A-4),SCOPE$,False,N] : End If 
  411.       A=Instr(STATE$," Gosub ")
  412.       If A>0 : PARSE_ARGS[Mid$(STATE$,4,A-4),SCOPE$,False,N] : End If 
  413.       
  414.    Else If(Left$(STATE$,6)="Every ")
  415.       A=Instr(STATE$," Proc ")
  416.       If A>0 : PARSE_ARGS[Mid$(STATE$,6,A-6),SCOPE$,False,N] : End If 
  417.       A=Instr(STATE$," Gosub ")
  418.       If A>0 : PARSE_ARGS[Mid$(STATE$,6,A-6),SCOPE$,False,N] : End If 
  419.       
  420.    Else If(Left$(STATE$,3)="If ") or(Left$(STATE$,3)="If(")
  421.       A=Instr(STATE$," Then ",A+1)
  422.       If A>0
  423.          PARSE_ARGS[Mid$(STATE$,3,A-3),SCOPE$,False,N]
  424.          PARSE_STAT[Mid$(STATE$,A+6),N,False]
  425.       Else 
  426.          PARSE_ARGS[Mid$(STATE$,3),SCOPE$,False,N]
  427.       End If 
  428.       
  429.    Else 
  430.       A=Instr(STATE$,"Else ",A+1)
  431.       If A
  432.          If Asc(Mid$(STATE$,A-1))=32
  433.             PARSE_STAT[Left$(STATE$,A-2),N,False]
  434.          Else 
  435.             PARSE_STAT[Left$(STATE$,A-1),N,False]
  436.          End If 
  437.          PARSE_STAT[Mid$(STATE$,A+5),N,False]
  438.       Else 
  439.          
  440.          
  441.          'Check for '=' outside brackets, before any spaces, and before commas  
  442.          EQ=0
  443.          Repeat 
  444.             EQ= Extension_16_009E(STATE$,61,EQ)
  445.             Exit If EQ=0
  446.             NAME$=Left$(STATE$,EQ-1)
  447.          Until( Extension_16_051C(NAME$,40)= Extension_16_051C(NAME$,41)) and( Extension_16_008C(NAME$,32)=0) and( Extension_16_008C(NAME$,44)=0)
  448.          
  449.          
  450.          If EQ
  451.             PARSE_ARGS[Mid$(STATE$,EQ+1),SCOPE$,False,N]
  452.             If FSTAT
  453.                _DECLARE[NAME$,SCOPE$,FLP,N,False]
  454.             Else 
  455.                _DECLARE[NAME$,SCOPE$,LOC,N,False]
  456.             End If 
  457.          Else 
  458.             PARSE_ARGS[STATE$,SCOPE$,True,N]
  459.          End If 
  460.       End If 
  461.    End If 
  462. End Proc
  463. Procedure PARSE_ARGS[ARG$,SCOPE$,WHOLE,N]
  464.    Shared NUMCOMMANDS,NUMINLINES
  465.    
  466.    If ARG$="" Then Pop Proc
  467.    A=0 : L1$="ABCDEFGHIJKLMNOPQRSTUVWXYZ_"
  468.    L2$="1234567890#$"
  469.    FL$="<>=+-*/^,]) "
  470.    PRE$="$1234567890"
  471.    Do 
  472.       Repeat 
  473.          Inc A
  474.          B=Asc(Mid$(ARG$,A))
  475.          Exit If A>Len(ARG$),2
  476.       Until Extension_16_008C(L1$,B)>0
  477.       '
  478.       If A>1
  479.          Exit If Extension_16_008C(PRE$,Asc(Mid$(ARG$,A-1)))>0
  480.       End If 
  481.       
  482.       A1=0 : IGNORE=False
  483.       Repeat 
  484.          Inc A1
  485.          Exit If A+A1>Len(ARG$)
  486.          B1=Asc(Mid$(ARG$,A+A1))
  487.       Until Extension_16_008C(L1$+L2$,B1)=0
  488.       
  489.       If A1=1
  490.          If(Asc(Mid$(ARG$,A+A1,1))=32)
  491.             X$=Mid$(ARG$,A+A1+1,1)
  492.             If X$=Upper$(X$)
  493.                IGNORE=True
  494.             End If 
  495.          End If 
  496.          For X=1 To NUMCOMMANDS
  497.             If A>=Len(COMMAND$(X))-1
  498.                If Mid$(ARG$,A-Len(COMMAND$(X))+1,Len(COMMAND$(X)))=COMMAND$(X)
  499.                   IGNORE=True : Exit 
  500.                End If 
  501.             End If 
  502.          Next 
  503.  
  504.       End If 
  505.       
  506.       If Not IGNORE
  507.          If(A+A1>Len(ARG$)) or( Extension_16_008C(FL$,B1)>0) or(Mid$(ARG$,A+A1,4)=" and") or(Mid$(ARG$,A+A1,3)=" or") or(Mid$(ARG$,A+A1,3)=" To") or(Mid$(ARG$,A+A1,3)=" As")
  508.             If Not((A=1) and(A1=Len(ARG$)) and(WHOLE=True))
  509.                _REFERAL[Mid$(ARG$,A,A1),SCOPE$,N]
  510.             End If 
  511.          End If 
  512.       End If 
  513.       A=A+A1
  514.    Loop 
  515. End Proc
  516. Procedure _REFERAL[ARG$,SCOPE$,N]
  517.    _SEARCH[ARG$,SCOPE$,True,False]
  518.    If Param=True
  519.       DLOG["Undefined Variable: "+ARG$]
  520.       _DECLARE[ARG$,SCOPE$,LOC,N,True]
  521.    End If 
  522. End Proc
  523. Procedure _SEARCH[NAME$,SCOPE$,REFER,NEWSHARED]
  524.    
  525.    R=-1 : A=0
  526.    While A<LAST
  527.       If NAME$(A,0)=NAME$
  528.          If(NAME(A,0)=SHA) and NEWSHARED
  529.             NAME$(A,1)=SCOPE$
  530.          End If 
  531.          If(NAME(A,0)=GLO) or((NAME(A,0)>=LOC) and(NAME$(A,1)=SCOPE$)) or((NAME(A,0)=SHA) and((NAME$(A,1)=SCOPE$) or(SCOPE$="MAIN PROGRAM")))
  532.             If REFER : Inc NAME(A,1) : Inc NAME(A,3) : End If 
  533.             R=A : Exit 
  534.          End If 
  535.       Else If NAME$(A,0)>NAME$
  536.          Exit 
  537.       End If 
  538.       Inc A
  539.    Wend 
  540. End Proc[R]
  541. Procedure DLOG[A$]
  542.    R=Dialog Box(AL$,2,A$)
  543.    If R=2 : MN_QUIT : End If 
  544.    TITLE
  545. End Proc
  546. Procedure TITLE
  547.    NULL=Dialog Box(AL$,0,"Variable Checker By Paul Hickman. Ctrl-C To Abort")
  548. End Proc