Technical Correspondence: Vector Jan 2000: Utility Corner (pp. 27-35)
Vector 17:1, page 106
Transcribed from the printed issue; not yet reviewed. Read it in the PDF of the issue, page 106
Remarks by the solution on disk: (workspace VECTOR)
- I did not understand the purpose of the mixed use of
ANALYZEandANALYSE. - I used
ANALYSEfor testing ofANALYSE1(= modified given function with same line-numbers) (this makes testing much easier and you don’t create extra global variables in the workspace) - The given function doesn’t work if
FNAMEhas no local variables!!! (but see for my correction the lines [42] and [55]).
The correction in line [31] accounts for a function that doesn’t exist or is locked. - In line [60] a character ‘s’ must be changed in ‘z’ (but I used
⎕AV) - A display of FNS is not given because it concerns a analyse of
FNAMEand not of the workspace! - I removed duplicate names from IDS (a SORT should also be useful) by adding lines [86] and [87].
- The function
SUBFNSgives the indices for the subfunctions in FNS and uses the subsubfunctionBIJMAT. - You should (for completeness) have added a similar analyse for global variables used in
FNA - I use APL*PLUS SE.
- The workspace VECTOR contains also the function
DOEALL(using TEXTREPL for 'MMM').
You can test ANALYSE for alle functions in the WS by excecuting :
[Second letter dated 18th March]¶
Herewith an improved version of my workspace ‘VECTOR’ (my letter dd. 16/3)
The improvements concern:
A display of FNS is added to function
ANALYSEAn error-message is given by function ‘
ANALYSE’ for function-names shadowed by local variable-names, locked functions and not existent fns.(see
ANALYS1[0] and [31] for corrections concerning yourANALYSE-function)A sort of the IDS-list is added to
ANALYSE1(see [88]).Function
BIJMAT(called inSUBFNS) is renamed inINMAT.A part of my function
DOEALLwas (very) superflous and is now removed.
Remarks:
After ANALYSE 'TEXTREPL' the identifier TEXTREPLvOBJ is missing owing to '⎕'!.
Line [87] of ANALYS1 doesn’t work (in APLS*PLUS SE) for large functions with many identifiers, do you have a better solution?
NB: You can test the ANALYSE functions for all functions in the workspace by executing:
H.J.Veenendaal
[address omitted]
Den Haag (NL)
Code Listings (see www.vector.org.uk/v171/hjv.zip)¶
∇ ANALYSE FNAME;FNS;RESULT;ARGS;LOCALS;LABELS;IDS;IDS1;COLS;CR;
HDR;I;LEN;LET;MAX;N;NUM;OK;START;VC;WID
[1] ⍝ ANALYSE the identifiers within the function named in FNAME.
[2] ' '
[3] FNAME,':'
[4] (1+⍴FNAME)⍴'='
[5] →(0=1↑⍴⎕CR FNAME)/ERR
[6] ANALYSE1 FNAME
[7] 'FNS: The names of functions in the workspace'
[8] '---'
[9] FNS
[10] ' '
[11] 'RESULT: The name of the result variable (0 rows if none)'
[12] '------'
[13] RESULT
[14] ⍎(0=1↑⍴RESULT)/'''[none]'''
[15] ' '
[16] 'ARGS: The names of the argument variables (0, 1 or 2 rows)'
[17] '----'
[18] ARGS
[19] ⍎(0=1↑⍴ARGS)/'''[none]'''
[20] ' '
[21] 'LOCALS: The names of the variables localised in the header'
[22] '------'
[23] LOCALS
[24] ⍎(0=1↑⍴LOCALS)/'''[none]'''
[25] ' '
[26] 'LABELS: The names of the labels'
[27] '------'
[28] LABELS
[29] ⍎(0=1↑⍴LABELS)/'''[none]'''
[30] ' '
[31] 'IDS: The names of all identifiers within the body of
the functions'
[32] '---'
[33] IDS
[34] ⍎(0=1↑⍴IDS)/'''[none]'''
[35] ' '
[36] 'SUBFNS: Indices of subfunctions'
[37] '------'
[38] SUBFNS
[39] ⍎(0=⍴SUBFNS)/'⎕CURSOR[1]←¯1+⎕CURSOR[1]'
[40] ⍎(0=⍴SUBFNS)/'''[none]'''
[41] ' '
[42] 'SUBFUNCTIONS:'
[43] '-------------'
[44] FNS[SUBFNS;]
[45] ⍎(0=⍴SUBFNS)/'''[none]'''
[46] →0
[47] ERR:
[48] ' '
[49] 'ANALYSE NOT POSSIBLE FOR: ',FNAME
[50] ⍝ ANALYSE: H.J.Veenendaal 18/03/00 11:29
∇
∇ ANALYSE1 FNAME;⎕IO
[1] ⍝ ANALYSE the identifiers within the function named in FNAME.
[2] ⍝ The ANALYSE1 function creates six global character variables
[3] ⍝ with one left-justified name per row:
[4] ⍝ FNS, RESULT, ARGS, LOCALS, LABELS and IDS (see also ANALYSE)
[5] ⍝
...
[27] ⍝
[28] ⎕IO←0
[29] FNS←⎕NL 3
[30] COLS←1↓⍴FNS
[31] →((0=1↑⍴CR←⎕CR FNAME)∨(3≠⎕NC FNAME))/0 ⍝ Quit if FNAME not available
[32] WID←⍴HDR←CR[0;]
[33] ⍝
[34] CR←1 0↓CR
[35] LEN←('←'∊HDR)×HDR⍳'←' ⍝ Length of the result-var if any
[36] ⍝ Result is 0 or 1 row matrix (0 if to long)
[37] RESULT←(((LEN≤COLS)∧×LEN),COLS)⍴COLS↑LEN↑HDR
[38] HDR←(LEN+×LEN)↓HDR
[39] HDR←(+/∨\⌽HDR≠' ')↑HDR ⍝ Delete trailing blanks
[40] LEN←HDR⍳';'
[41] ARGS←LEN↑HDR
[42] HDR←(LEN↓HDR),';' ⍝ Drop syntax leaving semicolon!!!!!
[43] I←(ARGS=' ')/⍳LEN
[44] N←⍴LEN←(I,LEN)-0,I+1 ⍝ Length of names in syntax
[45] MAX←⌈/LEN ⍝ Length of longest name
[46] ⍝ Convert to matrix:
[47] ARGS←(N,COLS)↑(N,MAX)⍴(,LEN∘.>⍳MAX)\ARGS~' '
[48] ⍝ Select args, not fn name, unless to long:
[49] ARGS←((LEN≤COLS)∧(N≥3 1 2)/1 0 1)⌿ARGS
[50] I←(HDR=';')/⍳LEN←⍴HDR ⍝ Indices of semicolon
[51] N←⍴LEN←(1↓I,LEN)-I+1 ⍝ Length of localised name
[52] MAX←⌈/LEN ⍝ Length of longest localised name
[53] ⍝ Convert to matrix:
[54] LOCALS←(N,COLS)↑(N,MAX)⍴(,LEN∘.>⍳MAX)\HDR~';'
[55] LOCALS←¯1 0↓(LEN≤COLS)⌿LOCALS ⍝ Ignore long ones (and extra one)
[56] OK←=\CR≠'''' ⍝ Flag code NOT within quotes
[57] ⍝ Flag code NOT within comment or quotes:
[58] OK←OK∧∧\OK≤CR≠'⍝'
[59] ⍝ Chars that can begin identifier-names:
[60] LET←⎕AV[(65+⍳26),(97+⍳26)],'∆⍙'
[61] ⍝ Other valid chars:
[62] NUM←'0123456789'
[63] ⍝ Flag any valid chars, adding col for ending IDs:
[64] VC←,(OK∧CR∊LET,NUM),0
[65] ⍝ Flag start and end (+1) of each run:
[66] VC←VC≠¯1↓0,VC
[67] N←⍴IDS←VC/⍳⍴VC ⍝ Convert to indices
[68] IDS←((N÷2),2)⍴IDS ⍝ Two col-mat of start/end indices
[69] CR←,CR,' ' ⍝ Ravel code and pad to match VC
[70] START←IDS[;0] ⍝ Start of indices
[71] LEN←IDS[;1]-START ⍝ Length of names
[72] ⍝ Must start with letter not be too long and not be preceded by '⎕':
[73] ⍝
[74] OK←(CR[START]∊LET)∧(LEN≤COLS)∧'⎕'≠CR[0⌈START-1]
[75] START←OK/START ⍝ Squeeze out bad ones
[76] N←⍴LEN←OK/LEN
[77] IDS←(N×COLS)⍴' ' ⍝ IDS in raveled form
[78] ⍝ I←(⍳LEN[0]),(⍳LEN[1]),(⍳LEN[⍳2])...:
[79] I←LEN/¯1↓0,+\LEN
[80] I←(⍳⍴I)-I
[81] ⍝ Insert IDS where they belong:
[82] IDS[I+LEN/COLS×⍳N]←CR[I+LEN/START]
[83] IDS←(N,COLS)⍴IDS ⍝ Reshape to a matrix
[84] ⍝ Labels start a line and are folowed by a colon:
[85] LABELS←((0=(WID+1)|START)∧CR[START+LEN]=':')⌿IDS
[86] IDS1←IDS
[87] IDS←(0 0⍉<\IDS∧.=⍉IDS)⌿IDS ⍝ IDS without double items
[88] IDS←SORTMAT IDS
[89] ⍝ ANALYSE1: H.J.Veenendaal 18/03/00 11:29
∇