Functions:
∇ run←{⍺←⊢
[1] ⍺ _code.run ⍵
[2] ⍝ Phil Last 2018-01-17 21.24
[3] }
∇
Scripts:
[0] :Namespace _qv
[1] ##.(⎕IO ⎕ML ⎕WX)←0 0 3
[2] :EndNamespace
References:
CD | ==> | ⎕SE.acre._code.UT.[Namespace] |
EN | ==> | ⎕SE.acre._code.[Namespace] |
MS | ==> | ⎕SE.acre._code.[Namespace] |
OPT | ==> | ⎕SE.acre._code.[Namespace] |
SV | ==> | ⎕SE.acre.[Namespace] |
SX | ==> | ⎕SE.acre._code.[Namespace] |
Functions:
∇ Cc←Cc
[1] Cc←819⌶
[2] ⍝ case folding
[3] ⍝ nilad returning ambivalent
∇
∇ Changes←{dat←⍺
[1] ~dat.hist:⍪''⊣dat noHistMsg''
[2] null⊢name date←⊃{⍺ ⍵/¨⍨⊂0<⎕NC ⍺}/dat changes'':⍪''
[3] dat.nspath≡⊃⍵:{ ⍝ project changes
[4] name date←(⊂⊂⍒date)⌷¨name date
[5] dt←OPT.when
[6] dt≡0:⍪name
[7] res←name,⍪↓DT.dt2fm date
[8] dt≡1:res
[9] lt←1∊'<≤'∊dt
[10] res⌿⍨lt≠date≥DT.fm2dt dt~'<≤≥>'
[11] }0
[12]
[13] null⊢item←⍬⍴⍵∩name:⍪'' ⍝ item change
[14] file←⊃dat getChangeFilenames item
[15] cmp←⌽1↓⍳1⊃⎕FSIZE⊢tie←file ⎕FTIE 0
[16] ptr val←UT.ht ⎕FREAD tie,⊂cmp
[17] cmp←1↓cmp
[18] date←↓MS.DK,⍤1 DT.(dt2fm∘ts2dt∘fd2ts)⊢/∘⎕FRDCI¨tie,¨cmp
[19] z←⎕FUNTIE tie
[20] ⍪⍪¨' ',¨(⊂¨↓⍕((cmp=ptr)\⊂'>>>'),(⊂MS.BF),cmp,⍪date),¨val
[21] ⍪⊃,/,(⊂⊂''),(⊂¨↓⍕((cmp=ptr)\⊂'>>>'),(⊂MS.BF),cmp,⍪date),⍪val
[22] ⍝ list changed items of project
[23] ⍝ or dates and values of item
[24] ⍝ Phil 2018-08-07 17.23
[25] }
∇
∇ Close←{dat←⍺
[1] ≢dataSpaces dat⊣showMsg MS.BX,dat.nspath
[2] ⍝ close a tracked project
[3] ⍝ ⍺ dat
[4] ⍝ ← number tracked
[5] ⍝ Phil 2018-06-06 21.11
[6] }
∇
∇ CreateProject←{
[1] 0=dat←createProject ⍵:''
[2] dat.nspath⊣dataSpaces dat ⍝ remember
[3] ⍝ ⍵ folder space
[4] ⍝ ← ProjectSpace
[5] ⍝ Phil Last 2017-11-28 09.50
[6] }
∇
∇ EditArray←{dat←⍺
[1] 2.1≠#.⎕NC⊂fqn←⊃⍵:'' ⍝ one item
[2] ⎕THIS.(sandbox←⎕NS'').(string←,matrix←↑list←'' '')
[3] pref←(⍕⎕THIS),'.sandbox.'
[4] txt←⊃∊/1(↑_↓)nameClass(⊂fqn),pref∘,¨↓sandbox.⎕NL 2
[5] txt:⎕ED&fqn
[6]
[7] enc←'j'∊Cc OPT.encoding
[8] else←{⍵:⍺⍺⊣⍺ ⋄ ⍵⍵⊣⍺}
[9] export←1∘(⎕JSON ⍠'Compact' 0)else(2∘AN.format)∘enc
[10] import←⎕JSON else AN.decode∘enc
[11]
[12] new←export⊢old←#.⍎fqn
[13] ed←#.⎕NS''
[14] name←'.'UT.nn fqn
[15] z←name ed.{⍎⍺,'←⍵'}new
[16] null ed.⎕ED name:''
[17] new←import ed.⍎name
[18] new≡old:''
[19] z←fqn #.{⍎⍺,'←⍵'}new
[20] r⊣showMsg(nonul r)/MS.DK,r←⊃dat SetChanged,⊂fqn
[21]
[22] ⍝ Phil 2018-08-22 23.01
[23] }
∇
∇ Erase←{dat←⍺ ⋄ unc←50 ⍝ up to 50 unconfirmed
[1] ns←(,1)≡0 ssp⊢arg←⍵ ⍝ non-scriptus
[2] endx←(⎕EX(ns/arg),⊢)⊢⊢
[3] nms←validItems{(⍎⊃⍵)UT.li validAPLType''}if ns⊢arg
[4] null nms:''⊣showMsg MS.DH
[5]
[6] 0={confirm 60,⊂MS.CA,⍵ UT.pl MS.FK}if(unc<⊢)≢nms:''
[7]
[8] ~dat.hist:endx dat delSource nms
[9]
[10] fqn typ val←getValue nms
[11] null fqn:''⊣showMsg MS.DH
[12]
[13] new←~old←⎕NEXISTS¨fns←dat getChangeFilenames fqn
[14] res←{⍺⊣⎕FUNTIE(((-≢MS.HN)↓⍵),MS.EX)⎕FRENAME ⍵ ⎕FTIE 0}/old⌿fqn,⍪fns
[15] ∧/old:endx dat delSource res
[16]
[17] z←dat putChange(new∘/¨fqn val typ),⊂MS.EX
[18] endx dat delSource fqn
[19]
[20] ⍝ ⍵ item(s)|space
[21] ⍝ ← items in ⍵ of which erased
[22] ⍝ if .change exists just rename to .delete - else put and rename
[23] ⍝ confirm if >50
[24] ⍝ Phil 2018-06-20 11.04
[25] }
∇
∇ FromAPLAN←{
[1] null ⍵:''
[2] AN.decode #.⍎if(2=⎕NC)⊃∘prefSpace if(0≤⎕NC)⊃(⊣,' ',⊢)/⍵
[3] ⍝ decode APLAN expression as array or space
[4] ⍝ see ToAPLAN
[5] ⍝ expression requires "double quotes" if it contains [brackets].
[6] ⍝ Phil 2018-01-25 08.05
[7] }
∇
∇ Install←{
[1] path wsid←2⍴,\1 ⎕NPARTS(⍵≡∊⍵)⊃⍵ ⎕WSID
[2] name←1↓{⍵/⍨1=+\⍵='.'}⊃⎕XSI
[3] apo←'"'∘(qu←UT.qu)
[4] sep←⊃~∘'∘'⊢⎕SE.SALT.PATHDEL ⍝ thanks Gil
[5] old←1↓¨{⍵⊂⍨⍵∊sep,'∘'}sep,⎕SE.SALT.Settings'cmddir' ⍝ seek both
[6] f←{⍵/⍨(⊢=⌈/)(+\×~)⍵∊'/\'} ⍝ last /substr/
[7] old←⊃,/sep,¨old/⍨~¯1(↓∊↑)Cc f¨old,⊂path ⍝ sans me
[8] z←⎕SE.SALT.Settings'cmddir "',path,old,'" -permanent' ⍝ add me
[9] cmds help opt syn type grp←{
[10] ⍕¨qu¨¨⍵.(command help options syntax type group)}cmdDefs name
[11] re←{⊃⍵{(⍴,⍵)↓⊃,/⍵∘,¨(⍴,⍺)↓¨⍺{⍵⊂⍨⍺⍷⍵}⍺,⍺⍺}/⍺}
[12] data←(name)(grp)(cmds)(opt)(help)(type)(syn)
[13] code←'<n>' '<g>' '<c>' '<o>' '<h>' '<t>' '<s>'
[14] script←,(⎕UCS 10),{0 3↓⍵⌿⍨>/'⍝: '⍷⍵}⎕CR⊃⎕SI
[15] script←⊂(⎕UCS 10){1↓¨⍵⊂⍨⍵=⍺}⊃re/(↓code,⍪data),⊂script
[16] z←script ⎕NPUT(path,name,'.dyalog')1 ⍝ 1=rewrite
[17] rel←path,'releaseNotes','.txt'
[18] z←(⊂{⍵/⍨∧\(⍵∊∊⍵)∨⍵∨.≠¨'-'}releaseNotes⊣'')⎕NPUT rel 1
[19] ⍪'Installed at ' ']open ',∘apo¨path rel
[20] ⍝: :namespace <n>Init
[21] ⍝: ⎕io ⎕ml←0
[22] ⍝: name ← ,'<n>' ⍝ string
[23] ⍝: group ← ,¨<g> ⍝ list
[24] ⍝: cmds ← ,¨<c> ⍝ list
[25] ⍝: help ← ,¨<h> ⍝ list
[26] ⍝: type ← ,¨<t> ⍝ list
[27] ⍝: syn ← ,¨<s> ⍝ list
[28] ⍝: parse ← ,¨<o> ⍝ list
[29] ⍝: ∇ r←List
[30] ⍝: r←{⎕NS''}¨⍳⍴cmds
[31] ⍝: r.(Name Desc Group Parse)←↓⍉↑cmds help group parse
[32] ⍝: ∇
[33] ⍝: Help←{⍕⍪'' 'Syntax: ',¨help syn⊃¨⍨cmds⍳⊂⍵
[34] ⍝: }
[35] ⍝: Run←{cmd arg←⍵
[36] ⍝: arg.help:Help cmd
[37] ⍝: (path wsid)←,\2⍴1 ⎕NPARTS ##.SourceFile
[38] ⍝: new←{⎕se.<n>._code. newSession''}⍣(~new)⊢new←0∊⎕SE.⎕NC name
[39] ⍝: z←⎕SE.{6::0 ⋄ ⊢'#.<n>'∘⎕CY ⍵}⍣new⊢wsid
[40] ⍝: nsi←((⎕XSI+.=¨'.')⍳1)⊃⎕NSI ⍝ whence called
[41] ⍝: type←type⊃⍨cmds⍳⊂cmd
[42] ⍝: ⍝ ↓↓↓↓
[43] ⍝: ⎕SE.<n>._code. userCmdRun new cmd arg type nsi path wsid name
[44] ⍝: }
[45] ⍝: :endnamespace
[46] }
∇
∇ On←{⍺←⊢
[1] ≡/Cc MS.GA(⍕⍵)
[2] ⍝ only if ⍵ is 'on', 'On', 'oN' or 'ON'.
[3] ⍝ Phil 2018-06-17 15.38
[4] }
∇
∇ OpenProject←{⍺←⊢
[1] 2<≢⍵:MS.DM
[2] tk←nOff OPT.track
[3] dp←nOff OPT.dependencies
[4] 0=dat←openProject tk dp ⍵:''
[5] dat.nspath⊣dataSpaces⍣tk⊢dat ⍝ remember
[6] ⍝ ⍵ folder [space]
[7] ⍝ ← projectspace
[8] ⍝ Phil 2018-06-06 21.11
[9] }
∇
∇ Orphans←{
[1] sn←{1⌽' ',⍵↑⍨-+/∧\'.'≠⌽⍵} ⍝ #.one.two.three → ' three '
[2] az←'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789∆⍙'
[3] nc←3.1 3.2 4.1 4.2 ⍝ defined fns & ops
[4] sps←1↓⍎⍕'⎕io',⍵/⍨9=⌊#.⎕NC ⍵
[5] (ol ul)←UT.li∘nc eu 2⍴sps
[6] on←sn¨ol ⍝ orphan names - simple names only
[7] ol/⍨~⊃{
[8] tg←az{⍵{⍵\⍵/⍺}⍵∊⍺}⎕VR ⍺ ⍝ alphanumerics separated by blanks
[9] ⍵∨(on∊⊂sn ⍺)<{1∊⍵⍷tg}¨on ⍝ called but not by me
[10] }/ul,0
[11] ⍝ result identical to: ⊃UT.uu/⌽2⍴⍵,#
[12]
[13] ⍝ Phil 2018-02-12 16.13
[14] }
∇
∇ Projects←{
[1] 0::0 2⍴''⊣showMsg MS.GX
[2] {↑⍵.(nspath folder)}openProjects''
[3] ⍝ Phil Last 2018-01-15 15.35
[4] }
∇
∇ PurgeHistory←{dat←⍺
[1] ~dat.hist:0⊣dat noHistMsg''
[2]
[3] dat.nspath≡⊃⍵:{ ⍝ all for project
[4] files←⊃(⊣(/⍨)2=⊢)/0 1 ⎕NINFO⍠1⊢dat.changes,'*'
[5] ok←∧/⎕NDELETE/1,⍪files
[6] dat.changed←''
[7] ok⊣showMsg ok/dat.nspath,MS.DA
[8] }0
[9] ⍝ one item
[10] dl←,∘MS.EX⊢(-≢MS.HN)↓fn←⊃dat getChangeFilenames⊂fqn←⊃validItems ⍵
[11] ok←1∊⎕NDELETE/1,⍪dl fn
[12] dat.changed~←⊂fqn
[13] ok⊣showMsg ok/fqn,MS.DA
[14] ⍝ Purge history for project or one item.
[15] ⍝ Phil 2018-03-13 00.51
[16] }
∇
∇ Redo←{
[1] ⍺(+undoredo)⍵
[2] ⍝ ⍺ dat
[3] ⍝ ⍵ fqns
[4] ⍝ ← fqns where changed
[5] ⍝ non-destructive,
[6] ⍝ pointer change to subsequent edit if exists
[7] }
∇
∇ Refresh←{dat←⍺
[1] dat getSource MS.BG
[2] ⍝ getSource will filter on date greater than previously known whether
[3] ⍝ edited externally or written back from ws.
[4] ⍝ Phil 2018-03-13 21.56
[5] }
∇
∇ Restore←{dat←⍺
[1] ~dat.hist:''⊣dat noHistMsg''
[2] (null∨0<⎕NC)fqn←⊃⍵∩dat deleted'':''
[3] tgt src←MS.EX MS.HN
[4] file←MS.EX,⍨(-≢MS.HN)↓chg←⊃dat getChangeFilenames fqn
[5] ⍝ type will be MS.AX ".*"
[6] null⊢del←⊃⊃0 ⎕NINFO⍠1⊢file:''
[7] name type←namx sPath del ⍝ file is path.name.type.delete
[8] chg←MS.HN,⍨(-≢MS.EX)↓del
[9] tie←del ⎕FTIE 0
[10] val←currentChange tie
[11] tie←⎕FUNTIE chg ⎕FRENAME tie
[12] null⊢fqn type val←fixValue fqn type val:''
[13] fqn⊣dat putSource fqn type val
[14] ⍝ Rename ONE ONLY .delete to .change
[15] ⍝ Replace in source
[16] ⍝ Refix in ws
[17]
[18] ⍝ can we do this for multiples and for spaces or wildcards?
[19]
[20] ⍝ Phil Last 2018-01-14 18.38
[21] }
∇
∇ SetChanged←{⍺←⊢
[1] dat←⍺
[2]
[3] dat setChange getValue validItems{(⍎⊃⍵)UT.li⍳10}if(⊃0∘ssp∧1=≢)⍵
[4] ⍝
[5] ⍝ Phil 2018-02-18 21.42
[6] }
∇
∇ Start←{
[1] path←⍵
[2] ⍝ setEnvironment∘setDataSpaces if newSession path
[3] setEnvironment∘setDataSpaces path
[4] ⍝ ⍵ used by setEnvironment unchanged
[5] ⍝ get things going once per session
[6] ⍝ ← did we need to
[7] }
∇
∇ Stats←{dat←⍺
[1] space←⍎dat.nspath ⎕NS''
[2] start←DT.dt2fm⊃s t←2⍴dat.loadtime
[3] time←~∘' ',{(×⍵)⌿1⌽⍕'ms',⍪⍵}0 60⊤⌈--/24×60×60×DT.dt2dd s t
[4] s←b/⊃s b←{s _ 0 ssp⊃n s←n ⍵/¨⍨⊂(0<⎕NC)n←UT.df¨⍵}(∪⊢,UT.nt)space
[5] sub←,+/s.(≢⎕NL)2.1 ⍝ arrays
[6] sub,←+/s.(≢⎕NL)⊂3.1 3.2 ⍝ functions
[7] sub,←+/s.(≢⎕NL)4 ⍝ operators
[8] sub,←+/b=0 ⍝ scripts
[9] sub,←+/s.(≢⎕NL)9.4 ⍝ classes
[10] sub,←+/s.(≢⎕NL)9.5 ⍝ interfaces
[11] h s n←{1,(+/,≢){⍵.Size}folderObj dat.changes}⍣dat.hist⊢0 0 0
[12] hist←{(⊃'B'UT.mn s),MS.FP,n UT.pl MS.FL}⍣(×n)⊢MS.FQ,h⊃MS.GB MS.GC
[13] tot←(⍕+/sub),MS.FP,(+/b)UT.pl MS.FJ
[14] nms←MS.FG MS.FH''MS.FA MS.FB MS.FC MS.FD MS.FE MS.FF''MS.FI MS.FO
[15] UT.bx nms,⍪start time'',sub,''tot hist
[16] ⍝
[17] ⍝.--------------------------------------.
[18] ⍝| When opened: 2018-04-04 22:08:36 |
[19] ⍝| Time to load: 2s |
[20] ⍝| |
[21] ⍝| Variables 4 |
[22] ⍝| Functions 354 |
[23] ⍝| Operators 81 |
[24] ⍝| Scripts 2 |
[25] ⍝| Classes 4 |
[26] ⍝| Interfaces 0 |
[27] ⍝| |
[28] ⍝| Total items: 445 in 9 namespaces |
[29] ⍝| Change History: 258kB in 9 files |
[30] ⍝'--------------------------------------'
[31]
[32] ⍝ Phil 2018-04-04 22.48
[33] }
∇
∇ ToAPLAN←{
[1] null ⍵:2⍴''''
[2] AN.format #.⍎if(~null)⊃∘prefSpace if(0≤⎕NC)⊃(⊣,' ',⊢)/⍵
[3] ⍝ format value as APLAN expression
[4] ⍝ see FromAPLAN
[5] ⍝ expression requires "double quotes" if it contains [brackets].
[6] ⍝ Phil 2018-01-25 08.05
[7] }
∇
∇ Undo←{
[1] ⍺(-undoredo)⍵
[2] ⍝ ⍺ dat
[3] ⍝ ⍵ fqns
[4] ⍝ ← fqns where changed
[5] ⍝ non-destructive,
[6] ⍝ pointer change to previous edit if exists
[7] }
∇
∇ _←{⍺ ⍵
[1] ⍝ Phil Last 2017-12-07 15.46
[2] }
∇
∇ r←_Created
[1] r←20080102.1652
[2] ⍝ the datetime above 2008-01-02 16.52 was when
[3] ⍝ this function was first created and is used to
[4] ⍝ distinguish between datetimes and transaction ids
[5] ⍝ work actually started late December 2007
[6] ⍝ Phil Last
∇
∇ allMessages←{
[1]
[2] name←⍵ ⍝ system name
[3] nms←{ ⍝ local ns
[4] ⍵.name←name
[5] ⍵.author←'Phil Last <phil.last@4xtra.com>'
[6] ⍵
[7] }⎕NS''
[8]
[9] ⊢{ ⍝ return ns
[10] ⍵.NA←nms.name
[11] ⍵.NB←'.',MS.NA,'/'
[12] ⍵.NU←nms.author
[13]
[14] ⍵.AA←'.array' ⍝ aplan
[15] ⍵.AF←'.function' ⍝ aplf
[16] ⍵.AO←'.operator' ⍝ aplo
[17] ⍵.AN←'.script' ⍝ apln
[18] ⍵.AC←'.class' ⍝ aplc
[19] ⍵.AI←'.interface' ⍝ apli
[20] ⍵.AL←'.charlist' ⍝ apll
[21] ⍵.AM←'.charmat' ⍝ aplm
[22] ⍵.AS←'.charstring' ⍝ apls
[23] ⍵.AX←'.*' ⍝ set as filetype for unknown
[24] ⍵.AZ←MS.AA MS.AF MS.AO MS.AN MS.AC MS.AI MS.AL MS.AM MS.AS
[25] ⍝ above MS.AZ and below MS.AY MUST correspond!
[26] ⍵.AY←'.apl'∘,¨'an' 'f' 'o' 'n' 'c' 'i' 'l' 'm' 's'
[27]
[28] ⍵.BA←'⎕SE.SALTUtils.EditorFix' ⍝ this is SALT callback on Fix
[29] ⍵.BC←'Please wait - '
[30] ⍵.BD←'Type changed'
[31] ⍵.BF←'Version '
[32] ⍵.BG←'Refresh'
[33] ⍵.BH←'quadVars'
[34] ⍵.BI←'⎕IO ⎕ML ⎕WX'
[35] ⍵.BJ←'⍝ This script was fixed by ',MS.NA
[36] ⍵.BK←'⍝ it can be kept, cloned, renamed, amended or ]erased.'
[37] ⍵.BL←'⍝ its purpose is to set the environment for the project.'
[38] ⍵.BM←'* Cannot rename file '
[39] ⍵.BN←MS.BJ MS.BK MS.BL
[40] ⍵.BO←'Added script "',MS.BH,'"'
[41] ⍵.BP←' may require attention.'
[42] ⍵.BU←'History is disabled for '
[43] ⍵.BV←'No change'
[44] ⍵.BW←'Project not tracked'
[45] ⍵.BX←'Closed '
[46]
[47] ⍵.CA←'This will erase '
[48] ⍵.CB←' will need to be amended.'
[49] ⍵.CC←'please restart within _ with code: -confirm=_'
[50] ⍵.CD←'Toggle between names with and without case-codes'
[51] ⍵.CE←'Return an item-name from a source-file-name'
[52] ⍵.CF←'Return a change-file-name from an item-name'
[53] ⍵.CG←'Return a source-file-name from an item-name'
[54] ⍵.CH←'Return a delete-file-name from an item-name'
[55]
[56] ⍵.DA←' - Local history purged'
[57] ⍵.DB←'! Problem reading '
[58] ⍵.DC←'! Invalid namespace name'
[59] ⍵.DD←'!!! Multiple source files exist for'
[60] ⍵.DE←'!!! A tracked project may not be opened inside another:'
[61] ⍵.DF←'! Project or folder already exists.'
[62] ⍵.DG←'!!! Invalid path or not a project.'
[63] ⍵.DH←'No appropriate items supplied'
[64] ⍵.DI←'No tracked project can handle item'
[65] ⍵.DJ←'!!! Not fixed '
[66] ⍵.DK←'Saved: '
[67] ⍵.DL←'Fixed: '
[68] ⍵.DM←'Syntax: '
[69] ⍵.DN←'!!! Trapped error in '
[70] ⍵.DO←' fixed as '
[71] ⍵.DP←'Startup - '
[72]
[73] ⍵.EF←'Comparing '
[74] ⍵.EG←'change changes'
[75] ⍵.EI←'Identifying changes'
[76] ⍵.EN←'Writing '
[77] ⍵.EO←'Reading '
[78] ⍵.EP←'Converting '
[79] ⍵.EQ←''
[80] ⍵.ER←'Opening'
[81] ⍵.ES←'Copying '
[82] ⍵.ET←'Deleting '
[83] ⍵.EU←'changes/'
[84] ⍵.EV←' removed'
[85] ⍵.EW←'config'
[86] ⍵.EX←'.delete'
[87] ⍵.EY←' from '
[88] ⍵.EZ←' to '
[89]
[90] ⍵.FA←'Variables'
[91] ⍵.FB←'Functions'
[92] ⍵.FC←'Operators'
[93] ⍵.FD←'Scripts'
[94] ⍵.FE←'Classes'
[95] ⍵.FF←'Interfaces'
[96] ⍵.FG←'When opened:'
[97] ⍵.FH←'Time to load:'
[98] ⍵.FI←'Total items:'
[99] ⍵.FJ←'namespace namespaces'
[100] ⍵.FK←'item items'
[101] ⍵.FL←'file files'
[102] ⍵.FM←'.gitignore'
[103] ⍵.FN←'update updates'
[104] ⍵.FO←'Change History:'
[105] ⍵.FP←' in '
[106] ⍵.FQ←' is '
[107] ⍵.FV←'AcreConfig'
[108] ⍵.FW←'File: '
[109] ⍵.FX←''
[110] ⍵.FY←''
[111] ⍵.FZ←'AcreDesktop_Testcases'
[112]
[113] ⍵.GA←'On'
[114] ⍵.GB←'Off'
[115] ⍵.GC←'empty'
[116] ⍵.GI←'hour hours'
[117] ⍵.GJ←'minute minutes'
[118] ⍵.GK←'second seconds'
[119] ⍵.GT←'NO MSG'
[120] ⍵.GU←'New in Editor'
[121] ⍵.GX←'No tracked projects'
[122] ⍵.GY←'APLSource/'
[123] ⍵.GZ←'.txt'
[124]
[125] ⍵.HA←''
[126] ⍵.HB←''
[127] ⍵.HE←'latest'
[128] ⍵.HG←':Namespace '
[129] ⍵.HH←':EndNamespace '
[130] ⍵.HI←'UTF-8'
[131] ⍵.HJ←'GetBuildID'
[132] ⍵.HM←MS.NA,MS.EW,MS.GZ
[133] ⍵.HN←'.change'
[134]
[135] ⍵.IB←'nameclass'
[136] ⍵.IC←'changefile'
[137] ⍵.ID←'deletefile'
[138] ⍵.IE←'sourcefile'
[139] ⍵.IF←'itemname'
[140] ⍵.IG←'version'
[141] ⍵.IH←'casecode'
[142] ⍵.IW←MS.NA,' version as: '
[143] ⍵.IX←MS.IB MS.IC MS.ID MS.IE MS.IF MS.IG MS.IH
[144] ⍵.IY←'''method'' ⎕SE.',MS.NA,'.run args'
[145] ⍵.IZ←'where ''method'' is one of'
[146]
[147] ⍵.__←⊃⎕XSI
[148] ⍵
[149] }MS←⎕NS''
[150]
[151] ⍝ ⍵ system name
[152] ⍝ ← ⍵ containing messages
[153] ⍝ reuse empties - search for "←''"
[154] ⍝ Phil 2018-01-23 15.35
[155] }
∇
∇ aplArrayNotation←{
[1] AN.help⊣'' ⍝ array or function?
[2] ⍝ Phil Last 2017-09-25 12.06
[3] }
∇
∇ aplErrors←{
[1] {
[2] ⍵.SE←2 ⍝ SYNTAX ERROR
[3] ⍵.IE←3 ⍝ INDEX ERROR
[4] ⍵.RE←4 ⍝ RANK ERROR
[5] ⍵.LE←5 ⍝ LENGTH ERROR
[6] ⍵.VE←6 ⍝ VALUE ERROR
[7] ⍵.DE←11 ⍝ DOMAIN ERROR
[8] ⍵.NE←16 ⍝ NONCE ERROR
[9] ⍵.FIE←20 ⍝ FILE INDEX ERRROR
[10] ⍵.FNE←22 ⍝ FILE NAME ERROR
[11] ⍵
[12] }⎕NS''
[13] ⍝ namespace with error number constants
[14] ⍝ Phil Last 2017-07-12 11.15
[15] }
∇
∇ buildWs←{⍺←⊢
[1] sc←⎕SE UT.fr'.'UT.nn sPath⊃⎕XSI ⍝ ⎕SE equiv
[2] z←⎕EX(,(/⍨)(≢/⊢,⍕∘⍎¨))⍪## UT.li 9 ⍝ anon refs
[3] aa fz←sc.(MS.NA MS.FZ)
[4] wsid←sc.SV.workspace
[5] sc←⍴sc.dataSpaces⍣2⊢'' ⍝ close all
[6] z←#.⎕EX~∘aa''~∘' '¨↓#.⎕NL⍳11 ⍝ clean
[7] z←##.⎕EX fz ⍝ testcases is sibling to _code
[8] #.⎕LX←((⊃⎕XSI)UT.re(⊃⎕SI)'Install'),2⍴'''' ⍝ set ⎕lx
[9] r←0 ⎕SAVE⊢#.⎕WSID←wsid ⍝ set wsid
[10] #.(⍎⎕LX)
[11] ⍝ from within dev project, close self using running ⎕SE clone
[12] ⍝ clean ws - see refs
[13] ⍝ Phil 2018-01-31 16.02
[14] }
∇
∇ changes←{dat←⍺
[1] ~dat.hist:''⍬
[2]
[3] file←folderObj dat.changes
[4] name type←↓⍉↑namx¨file.Path
[5] name date←name file.Date/¨⍨⊂type∊⊂MS.HN
[6] name←(dat.nspath,'.')∘,¨'..'decodeCaps UT.sp¨name ⍝ lose class
[7] name date/¨⍨⊂nub name
[8] ⍝ ← fqn date of all items in .change files
[9] ⍝ Phil 2018-08-06 22.10
[10] }
∇
∇ cmdDefs←{name←⍵
[1] f←{
[2] ([
[3] command←'Changes'
[4] help←'List changed items in project or changes to one'
[5] options←'help mess when'
[6] result←''
[7] syntax←'space | item'
[8] type←'item'
[9] ][
[10] command←'CreateProject'
[11] help←'Create a new project'
[12] options←'help mess case'
[13] result←''
[14] syntax←'folder space'
[15] type←'shared'
[16] ][
[17] command←'EditArray'
[18] help←'Edit array in tracked project. In APLAN if not regular text.'
[19] options←'help mess enco'
[20] result←''
[21] syntax←'item'
[22] type←'item'
[23] ][
[24] command←'Erase'
[25] help←'Erase an item, items or a space from a tracked project'
[26] options←'conf help mess'
[27] result←''
[28] syntax←'item(s) | space'
[29] type←'item'
[30] ][
[31] command←'FromAPLAN'
[32] help←'Evaluate an APLAN expression'
[33] options←'help mess'
[34] result←''
[35] syntax←'name | "expression"'
[36] type←'shared'
[37] ][
[38] command←'OpenProject'
[39] help←'Load project code into ws for development'
[40] options←'help mess track dep'
[41] result←''
[42] syntax←'folder [space]'
[43] type←'shared'
[44] ][
[45] command←'Projects'
[46] help←'List spaces & folders of all tracked projects.'
[47] options←'help mess'
[48] result←''
[49] syntax←''
[50] type←'shared'
[51] ][
[52] command←'PurgeHistory'
[53] help←'Fix changes to a tracked project'
[54] options←'help mess'
[55] result←''
[56] syntax←'space | item'
[57] type←'item'
[58] ][
[59] command←'Redo'
[60] help←'Re-apply last undone change.'
[61] options←'help mess'
[62] result←''
[63] syntax←'item(s)'
[64] type←'item'
[65] ][
[66] command←'Refresh'
[67] help←'Update tracked project with source changes since previous'
[68] options←'help mess'
[69] result←''
[70] syntax←'space'
[71] type←'project'
[72] ][
[73] command←'Restore'
[74] help←'Bring back items ]erased'
[75] options←'help mess'
[76] result←''
[77] syntax←'item'
[78] type←'item'
[79] ][
[80] command←'SetChanged'
[81] help←'Write items as if changed in the editor'
[82] options←'help mess'
[83] result←''
[84] syntax←'item(s)'
[85] type←'item'
[86] ][
[87] command←'Stats'
[88] help←'Project Statistics'
[89] options←'help mess'
[90] result←''
[91] syntax←'space'
[92] type←'project'
[93] ][
[94] command←'ToAPLAN'
[95] help←'Format a value as APLAN'
[96] options←'help mess'
[97] result←''
[98] syntax←'name | "expression"'
[99] type←'shared'
[100] ][
[101] command←'Undo'
[102] help←'Revert to previous version'
[103] options←'help mess'
[104] result←''
[105] syntax←'item(s)'
[106] type←'item'
[107] ])
[108] }
[109] r←AN.decode 1↓¯1↓⎕NR'f'
[110] r.group←⊂name
[111] r.syntax←,/(⊂']',name,'.'),r.command,' ',⍪r.syntax
[112] r.options←optionFields r.options
[113] UT.is r
[114] ⍝ see optionFields for valid options
[115] ⍝ Phil 2018-06-07 09.23
[116] }
∇
∇ code←{
[1] {⍵[(≢⍵){((1+⌊⍺⍟1⌈⌈/|⍵)⍴⍺)⊤⍵}⌊2⊃⎕AI÷1000]}819⌶⎕A,⎕D
[2] ⍝ ⍵ ?
[3] ⍝ ← the alpha code that confirm would issue at this time.
[4] ⍝ .`. supplying this obviates the need for confirmation.
[5] ⍝ Phil 2018-06-07 09.23
[6] }
∇
∇ codeHook←{⍺←⊢
[1] ⍝ null⊢fn←⊂Cc ⍺⊣'':''⊣showMsg MS.IY MS.IZ,MS.IX
[2] null⊢fn←⊂Cc ⍺⊣'':⍪MS.IX
[3] ns←dix⊢fns←MS.IX ⍝ MS.__
[4] ix←fns⍳fn
[5] SV.space←'.',⍨(¯1+((⊂MS.NA)(∨/⍷)¨⎕XSI)⍳0)⊃⎕NSI
[6] arg←⊂if≡⍵
[7] '?'∊⊃arg:{
[8] ix=ns.nameclass:ncHelp''
[9] ix=ns.changefile:MS.CF
[10] ix=ns.deletefile:MS.CH
[11] ix=ns.sourcefile:MS.CG
[12] ix=ns.itemname:MS.CE
[13] ix=ns.version:MS.IW,UT.fm' 'sep⊃releaseNotes⊣''
[14] ix=ns.casecode:MS.CD
[15] ⍪'?'
[16] }ix
[17] ix=ns.nameclass:nameClass prefSpace arg ⍝ itemMethod does this
[18] ix=ns.changefile:⊃if≢getChangeFilenames itemMethod 1⍴arg
[19] ix=ns.deletefile:,∘MS.EX if nonul(-≢MS.HN)↓⊃if≢getChangeFilenames itemMethod 1⍴arg
[20] ix=ns.sourcefile:⊃if≢getSourceFilenames itemMethod 1⍴arg
[21] ix=ns.itemname:itemName¨arg
[22] ix=ns.version:' 'sep⊃releaseNotes⊣''
[23] ix=ns.casecode:'#.'∘,⍣x⊃{'-'∊⍵:'..'decodeCaps ⍵
[24] '..'encodeCaps ⍵}(2×x←'#.'≡2⍴z)↓z←⊃arg
[25] ''
[26] ⍝ Marilyn Last named this fn
[27] ⍝ Phil 2018-08-20 22.19
[28] }
∇
∇ configFields←{⍺←⊢
[1] {
[2] ⍵.CaseCode←'On' ⍝ integer suffix to name elements
[3] ⍵.KeepHistory←'On' ⍝ store .change- and .delete-files
[4] ⍵.ProjectSpace←'' ⍝ #[.path]
[5] ⍵.Open←'' ⍝ Open with this project
[6] ⍵.StartUp←'' ⍝ executed after OpenProject
[7] ⍵
[8] }#.⎕NS''
[9] ⍝ ⍵ ?
[10] ⍝ ← config space
[11] ⍝ Phil 2018-06-06 21.11
[12] }
∇
∇ confirm←{
[1] (sec msg)←UT.ht ⍵
[2] ≡/1↓(a_9 code off)←Cc(⎕A,⎕D)OPT.confirm MS.GB:1
[3] ≠/×0 sec+(36⊥a_9⍳code)-⌊2⊃⎕AI÷1000:1
[4] msg≡,⊂MS.GT:0 ⍝ msg NO MSG
[5] {0}showMsg msg,⊂MS.CC UT.rm'_'(time sec)(a_9[36 UT.en⌊2⊃⎕AI÷1000])
[6] ⍝ ⍵ seconds message [message [...]]
[7] ⍝ code is option -confirm
[8] ⍝ ← 0|1 if code is as generated by this fn within past (seconds)
[9] ⍝ if msg is MS.GT the code is checked and no msg is shown
[10] ⍝ else if code is ok msgs are not shown.
[11] ⍝ else msgs are shown followed by:
[12] ⍝ please restart within [h m s] with code: -confirm=[code]
[13] ⍝ Phil 2018-06-12 11.02
[14] }
∇
∇ copyFile←{
[1] src tgt←⍵
[2] st←src ⎕NTIE 0
[3] z←3 ⎕MKDIR⊃⎕NPARTS tgt
[4] tt←tgt{EN.FNE::⊢0 ⎕NRESIZE ⍺ ⎕NTIE ⍵ ⋄ ⍺ ⎕NCREATE ⍵}0
[5] lim←⌊0.5×⎕WA
[6] (⎕NUNTIE st tt)⊢{(⎕NREAD st,83,lim)⎕NAPPEND tt,83}⍣=¯1
[7] ⍝ copy source to target in half ⎕WA chunks
[8] ⍝ ⍵ source target - FQNs
[9] ⍝ overwrite if exists
[10] ⍝ ← size
[11] ⍝ Phil Last 2017-05-03 15.37
[12] }
∇
∇ copyFolder←{⍺←⊢ ⋄ era←1=⍺⊣0
[1] source target←'/'UT.nn¨src tgt←¯1↓¨fPath¨⍵,¨'/'
[2] n←≢/Cc source target
[3] tgt,←n/'/',source
[4] z←showMsg MS.EI
[5] sp tp←{
[6] s←fileTree src
[7] z←3 ⎕MKDIR tgt
[8] t←fileTree tgt
[9] (s t).Path
[10] }UT.tk 0
[11] z←showMsg MS.EF,(≢sp)UT.pl MS.FL
[12] del copy←{
[13] sp←(⍴src)↓¨sp
[14] tp←(⍴tgt)↓¨tp
[15] s t←Cc sp tp
[16] del←tgt∘,¨tp/⍨~t∊s
[17] miss←↓⍉src tgt∘.,sp/⍨~mem←s∊t
[18] both←src tgt∘.,sp/⍨mem
[19] hash←{2 ⎕NQ'.'MS.HJ ⍵}
[20] diff←↓⍉both/⍨~≡⌿hash¨both
[21] del(miss,diff)
[22] }UT.tk 0
[23] del/⍨←era
[24] z←showMsg era/MS.ET,(≢del)UT.pl MS.FL
[25] z←⎕NDELETE⍨/UT.tk del,1
[26] z←showMsg MS.ES,(≢copy)UT.pl MS.FL
[27] z←(copyFile⊣)/UT.tk copy,0
[28] ⊢/↑copy
[29] ⍝ copy only missing and different.
[30] ⍝ [⍺] 1: delete from target if not in source
[31] ⍝ ⍵ source and target paths.
[32] ⍝ if last names differ then folder with
[33] ⍝ name of source is created inside target.
[34] ⍝ e.g. copyFolder 'C:/alpha/bravo' 'D:/charlie/delta'
[35] ⍝ creates 'D:/charlie/delta/bravo'
[36] ⍝ while copyFolder 'C:/echo/foxtrot' 'D:/golf/foxtrot'
[37] ⍝ uses 'D:/golf/foxtrot'
[38] ⍝ ← copied paths
[39] }
∇
∇ createProject←{
[1] dat.loadtime←DT.ts2dt ⎕TS⊣dat←⎕NS''
[2] ∨/nil⊢folder nspath←2↑⊂if≡⍵:0⊣showMsg MS.DM,SX.CreateProject
[3] dat.folder←fPath folder,'/'
[4] ⎕NEXISTS dat.folder:0⊣showMsg MS.DF
[5] dat.nspath←⊃prefSpace⊂nspath
[6] ~((1=≢)∨0∘ssp∨0=⎕NC)dat.nspath:0⊣showMsg MS.DC ⍝ 1=≢ => ,'#'
[7]
[8] dat.(hist case)←1,nOff OPT.casecode
[9] dat.(config source code changes latest)←{
[10] ⍵}dat.folder∘,¨MS.HM MS.GY,MS.NB∘,¨''MS.EU MS.HE
[11] ⍝ rem prev version if existed
[12] z←dat.nspath∘{dataSpaces ⍵/⍨⍵.nspath∊⊂⍺}if(×∘≢)openProjects''
[13] z←fixQV⊢space←⍎dat.nspath ⎕NS''
[14] z←3 ⎕MKDIR¨dat.(source changes)
[15] (cfg←configFields'').ProjectSpace←dat.nspath
[16] cfg.CaseCode←dat.case⊃MS.GB MS.GA
[17] z←(1⌽MS.HH MS.HG,1↓¯1↓2 AN.format cfg)MS.HI ⎕NPUT dat.config
[18] z←'dat'⎕NS UT.lc cfg ⍝ ← into dat ↑ write
[19] z←MS.FV space.{⍎⍺,'←⍵'}cfg⊣cfg.ProjectFolder←dat.folder
[20] z←MS.NB ⎕NPUT dat.folder,MS.FM ⍝ git specific -
[21] fqn←validItems space UT.li validAPLType''
[22] fqn type val←getValue fqn
[23] fqn type val←dat putSource fqn type val
[24] dat⊣dat.loadtime,←DT.ts2dt ⎕TS⊣dat.changed←''
[25] ⍝ ⍵ path [space]
[26] ⍝ ← dat or 0
[27] ⍝ see openProject CreateProject
[28] ⍝ Phil Last 2018-01-15 22.16
[29] }
∇
∇ currentChange←{⍺←⊢
[1] (⎕FUNTIE⍣c⊢t)⊢⎕FREAD t,⎕FREAD t,¯1+1⊃⎕FSIZE t←⎕FTIE∘0⍣(c←' '∊∊⍵)⊢⍵
[2] ⍝ ⍵ filename or tie
[3] ⍝ ← current value of item
[4] ⍝ last component is pointer to current
[5] ⍝ ⎕FTIE - quicker and should be no concurrence
[6] ⍝ Phil Last 2017-11-29 08.03
[7] }
∇
∇ deadletters←{
[1] {⍵,⍪MS.⍎¨⍵}{⍵/⍨0=,↑⍴¨⎕THIS UT.fi¨'MS.'∘,¨⍵}⎕A MS.⎕NL-2
[2] ⍝ redundant messages - assumes all used as MS.ID
[3] }
∇
∇ decode←{⍺←⊢
[1] abc←,'ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz'
[2] abc,←'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæçèéêëìíîïðñòóôõöøùúûüþ'
[3] abc,←'∆⍙ⒶⒷⒸⒹⒺⒻⒼⒽⒾⒿⓀⓁⓂⓃⓄⓅⓆⓇⓈⓉⓊⓋⓌⓍⓎⓏ'
[4] ⍝ ↑ (,(⌿⍨)0≤⎕NC)⍪⎕UCS⍳10000
[5] nan←' ''[(⊂¯.⋄←⍴)]' ⍝ non-alphanumeric
[6] syntax←⎕D,nan,abc
[7] quoted←≠\''''=⊢
[8] keep←∧\quoted≥'⍝'=⊢
[9] decom←,(/⍨),∘keep
[10] br←{(+/∨\' '≠⌽⍵)↑¨↓⍵}
[11] cr←⎕UCS 13
[12] sl←⊣(1↓¨=⊂⊢),
[13] simple←{2=⍴⍴⍵:decom'⋄',⍵ ⋄ 1≠≡1/⍵:⊃,/('⋄',decom)¨⍵
[14] cr∊⍵:⊃,/('⋄',decom)¨cr sl ⍵ ⋄ decom ⍵}
[15] r←∊∘'[(⍴⊂⋄ ←)]'
[16] rem←⊢(/⍨)quoted≥' '∘=∧(1⌽r)∨¯1⌽r ⍝ rem blanks adj to [(⍴⊂⋄ ←)]
[17] rho←'⍴'∘=>(¯1⌽∊∘⎕D)∧1⌽'⊂'∘= ⍝ '⍴' not twixt '0-9' and '⊂'
[18] enc←'⊂'∘=>¯1⌽∊∘'[(⋄⍴' ⍝ '⊂' not after '[(⋄⍴←⊂'
[19] syn←~∊∘syntax ⍝ not in syntax
[20] nam←∊∘abc>¯1⌽∊∘(abc,⎕D,'[⋄') ⍝ abc not after name or '[⋄'
[21] ass←'←'∘=>(¯1⌽∊∘(abc,⎕D))∧1⌽∊∘(⎕D,'.¯[(''') ⍝ '←' not twixt nam & val
[22]
[23] a←rem simple ⍵
[24] z←<\(quoted<rho∨enc∨syn∨nam∨ass)a
[25] ∨/z:((⎕EM 2),,cr,↑a(z\'^')/¨⍨⊂x∊z/x←+\a∊'[(⋄')⎕SIGNAL 2
[26] ......
[27] x←⍳⍴r←0⍴⍨⍴a
[28] d←q<'⋄'=a ⍝ bool where diamonds
[29] b←-⌿+\q<⍤1⊢'[]'∘.=a ⍝ dpth twixt brackets
[30] p←-⌿+\q<⍤1⊢'()'∘.=a ⍝ dpth twixt parens
[31] w←(⊢=⌈/)b+p ⍝ bool where max depth
[32] deepest←'(['(∊⍨⊂⊢)a/⍨(⊢=⌈/)b+p
[33] .
[34]
[35] ⍝ Phil Last 2018-01-03 21.03
[36] }
∇
∇ decodeCaps←{⍺←⊢ ⋄ null ⍵:''
[1] delta←{('∆⍙',⍵)[('+±',⍵)⍳⍵]} ⍝ remove this in June or July
[2] in out←'#-0' '#'(⊢,,)¨⍺⊣'/.'
[3] hd←⎕D,'abcdef',⎕D,'ABCDEF'
[4] one←{null 1⊃n c←2↑'-'sep ⍵:⍺,n
[5] ⍺,⊢⌿(↑1 0 Cc¨⊂n)⊖⍨(≢n)↑⌽,⍉(4⍴2)⊤16|hd⍳c}
[6] (≢out)↓¨(⊢⊂⍨out⍷⊢)⊃,/(⊃out)∘one eu 1↓(⊃in)sep delta⊃,/in∘,¨⊂if≡⍵
[7] ⍝ ⍺ input output separators
[8] ⍝ ← (ns.path)+
[9] ⍝ 'zero.One.tWo.THree.foUr.NinETynIne' +
[10] ⍝ ⍵ (file/path)+
[11] ⍝ 'zero-0/One-1/tWo-2/THree-3/foUr-4/NinETynIne-99' +
[12] ⍝ see encodeCaps
[13] ⍝ Phil Last 2018-01-11 17.17
[14] }
∇
∇ delSource←{dat←⍺ ⋄ fqn←⍵
[1] src←dat.nspath
[2] file←dat getSourceFilenames fqn
[3] gone←⎕NDELETE/1,⍪file
[4] gone/fqn
[5]
[6] ⍝ ⍺ dat
[7] ⍝ ⍵ fqns
[8] ⍝ ← fqn
[9] ⍝ Phil Last 2017-12-04 08.28
[10] }
∇
∇ deleteFolder←{
[1] {
[2] n t←0 1 ⎕NINFO⍠1⊢⍵,'/*' ⍝ name and type
[3] d f←(1 2=⊂t)/¨⊂n ⍝ dirs and files
[4] z←∇⍨/d,⎕NDELETE⍨/f,1 ⍝ del files and dirs
[5] z←⎕DL×≢n ⍝ delay if members
[6] ⎕NDELETE ⍵ ⍝ now it's empty
[7] }fPath ⍵,'/.'
[8] ⍝ delete folder and tree
[9] ⍝ Phil Last 2017-06-02 08.12
[10] }
∇
∇ deleted←{dat←⍺
[1] ~dat.hist:''
[2]
[3] ∪(dat.nspath,'.')∘,¨'..'decodeCaps UT.sp¨⊃{
[4] ⍺/⍨⍵∊⊂MS.EX}/↓⍉↑namx¨{⍵.Path}folderObj dat.changes
[5] ⍝ ← fqns of all items in .delete files
[6] ⍝ Phil 2018-02-21 16.32
[7] }
∇
∇ dix←{⍺←⊢
[1] ns←⎕NS''
[2] z←ns.(⍎⍕⍵,'←⍳⍴⍵')
[3] 1≡⍺ 1:ns
[4] ns⊣ns.(⍎⍕⍺,'←',⍵)
[5] ⍝ dictionary of indices
[6] ⍝ ⍵ names
[7] ⍝ ⍺ synonyms
[8] ⍝ ← space
[9] ⍝ dix 'alpha' 'bravo' 'charlie'
[10] ⍝ ns.[alpha←0 ⋄ bravo←1 ⋄ charlie←2]
[11] ⍝ 'delta' 'foxtrot' 'golf' dix 'alpha' 'bravo' 'charlie'
[12] ⍝ ns.[alpha←0 ⋄ bravo←1 ⋄ charlie←2 ⋄ delta←0 ⋄ foxtrot←1 ⋄ golf←2]
[13] ⍝ Phil 2018-07-10 12.37
[14] }
∇
∇ editFix←{
[1] (⍵≡'Start'):{ ⍝ from Start
[2] SV.eventnumber←enum←3611 ⍝ 26⊥⎕A⍳'FIX'
[3] (wx ⎕SE.⎕WX)←⎕SE.⎕WX 1 ⋄ qed←'⎕SE'⎕WG'Editor' ⍝ keep ⎕WX
[4] SV.fixandafter←UT.ds¨qed.(onFix onAfterFix) ⍝ odd extra nesting!
[5] qed.(onFix onAfterFix)←(evarg←0⊃⎕XSI)0
[6] ⎕SE.Event,←⊂enum,⊂evarg ⋄ ⎕SE.⎕WX←wx ⍝ reset ⎕WX
[7] {0}SV.itemvalue←editStore ⎕NS'' ⍝ create value store
[8] }''
[9] (⍵≡'Close'):{ ⍝ from Close
[10] qed←'⎕SE'⎕WG'Editor'
[11] (wx ⎕SE.⎕WX)←⎕SE.⎕WX 1 ⋄ qed.(onFix onAfterFix)←SV.fixandafter
[12] ⎕SE.⎕WX←wx ⋄ {0}'⎕SE'∘⎕WS UT.ep'Event'SV.eventnumber 0}''
[13] {0::1 ⋄ 0∊SV.setupcomplete,⍴openProjects''}0:
[14] enum←SV.eventnumber
[15] (editor event value space name new)←6↑⍵ ⍝ so long as onFix unchanged
[16] first←event≢enum ⋄ sn←1 ssp⊂⍕space ⍝ is space scripted?
[17] fqn←(⍕space),(sn≤space=#)/'.',name new⊃⍨ren←(≢∘∊⍨new)∧2≠space.⎕NC name
[18] (('⎕'∊fqn)≥(⎕NC⊂fqn)∊0,validAPLType''):
[19] first:{nv←fqn MS.GU if null⊃¨1 0 1/getValue,⊂fqn
[20] z←SV.itemvalue editStore nv
[21] z←⎕NQ'⎕SE'enum value space name new}''
[22] new←MS.GU≡oldval←SV.itemvalue editStore fqn
[23] ('⎕'∘∊∨0≥#.⎕NC∘⊂)fqn: ⍝ doesn't exist or bad name
[24] (oldval≡newval←⊃2⊃getValue,⊂fqn): ⍝ unchanged
[25] 0=dat←whichProject fqn:{}{
[26] ⍵}showMsg(~'['∊fqn)/UT.bx MS.DI,' "',fqn,'".'
[27] type←⊃nameClass fqn
[28] z←⍴dat∘putChange⍣(new⍱(⊂fqn)∊dat.changed)⊢fqn oldval type
[29] z←showMsg MS.DK,⊃dat setChange fqn type newval
[30] ⍝ ⍺ dat
[31] ⍝ ⍵ 'Start' or 'Close' or callback argument
[32] ⍝ ← 0 for 'Start' and 'Close' - else none
[33] ⍝ Phil Last ⍝ 2008-05-18 07:48
[34] }
∇
∇ editStore←{⍺←⊢
[1] 1≡⍺ 1:{⍵⊣⍵.(n v)←⊂,0}⍵ ⍝ monad - set store
[2] cat←⍺ ⍝ dyad - ⍺ is store
[3] name←⊃nv←⊂if≡⍵
[4] new←0≡cat.{((⍴n)|n⍳⍵)⊃n}⊂name ⍝ missing
[5] new:⊢cat.(n v),←⊂¨nv ⍝ add
[6] value←cat.{(n⍳⍵)⊃v}⊂name ⍝ retrieve
[7] value⊣cat.(n v)/⍨←⊂~cat.n∊⊂name ⍝ remove
[8] ⍝ maintain dictionary of names values for editFix
[9] ⍝ Phil Last 2015-05-07
[10] }
∇
∇ encode36←{null ⍵:''
[1] hd←⎕D,⎕A
[2] enc←{{⍵↑⍨-1⌈⊥⍨∨\0≠⍵}2 3 2 3⊥⍉s⍴⌽⍵↑⍨×/s←4,⍨⌈4÷⍨⍴⍵}
[3] one←{'/',⍵,'-',hd⌷⍨⊂enc ⍵≠Cc ⍵}
[4] in out←'.#.' '/#-0/'
[5] (≢out)↓¨(⊢⊂⍨out⍷⊢)⊃,/one eu 1↓(⊃in)sep⊃,/in∘,¨⊂if≡⍵
[6]
[7] ⍝ ⍵ (ns.path)+
[8] ⍝ 'zero.One.tWo.THree.foUr.NinETynIne' +
[9] ⍝ ← (file/path)+
[10] ⍝ 'zero-0/One-1/tWo-2/THree-3/foUr-4/NinETynIne-99' +
[11] ⍝ see decode
[12] ⍝ Phil Last 2017-12-21 19.09
[13] }
∇
∇ encodeCaps←{⍺←⊢ ⋄ null ⍵:''
[1] in out←'#' '#-0'(⊢,,)¨⍺⊣'./'
[2] hd←⎕D,'abcdef',⎕D,'ABCDEF'
[3] one←{⍺,⍵,'-',hd⌷⍨⊂{
[4] {⍵↑⍨-1⌈⊥⍨∨\0≠⍵}2⊥⍉s⍴⌽⍵↑⍨×/s←4,⍨⌈4÷⍨⍴⍵}⍵≠Cc ⍵}
[5] (≢out)↓¨(⊢⊂⍨out⍷⊢)⊃,/(⊃out)∘one eu 1↓(⊃in)sep⊃,/in∘,¨⊂if≡⍵
[6] ⍝ ⍺ input output separators
[7] ⍝ ⍵ (ns.path)+
[8] ⍝ 'zero.One.tWo.THree.foUr.NinETynIne' +
[9] ⍝ ← (file/path)+
[10] ⍝ 'zero-0/One-1/tWo-2/THree-3/foUr-4/NinETynIne-99' +
[11] ⍝ see decodeCaps
[12] ⍝ Phil Last 2018-01-11 17.17
[13] }
∇
∇ erase←{dat←⍺ ⋄ del←⍵
[1] z←showMsg(×z)/((z←≢del)UT.pl MS.FL),MS.EV,MS.EY,¯4 tPath dat.source
[2] fnm←~∘∊⍨(⊃∘⊃0 ⎕NINFO⍠1⊢)¨dat getChangeFilenames del ⍝ ".*"
[3] ⍝ rename existing .change to ↓ .delete ELSE FORGET!!
[4] z←showMsg(×z)/MS.EP,((z←≢fnm)UT.pl MS.EG),MS.EZ,MS.EX
[5] z←{⎕NUNTIE ⍵ ⎕NRENAME ⍺ ⎕NTIE 0}/fnm,⍪,∘MS.EX¨(-≢MS.HN)↓¨fnm
[6] ⍵
[7] ⍝ ⍺ dat
[8] ⍝ ⍵ fqns to "erase"
[9] ⍝ rename changefile to deletefile where sourcefile missing
[10] ⍝ Phil 2018-03-11 09.52
[11] }
∇
∇ excRep←{
[1] ⍺←⊢
[2] ⊃{⍺,' - ',⍵}/⍺ ⍵
[3] ⍝ ⍺ 'message text'
[4] ⍝ ⍵ 'item.name'
[5] ⍝ ← 'message text - item.name'
[6] ⍝ or
[7] ⍝ ⍺ missing
[8] ⍝ ⍵ 'msg text' 'more' 'more ...'
[9] ⍝ ← 'msg text - more - more ...'
[10] ⍝ Phil Last ⍝ 2008-01-29 10:29
[11] }
∇
∇ fPath←{r←⍵
[1] r←⊃,/1 ⎕NPARTS r
[2] ~∨/'/../'⍷r:r ⍝ ← Windows ...
[3] ⍝ {⍵,'/'/⍨0∊⍴⍵}1↓⊃,/'/',¨(⊢(/⍨){1=+/⍵∘.=⍵}∘(⍳∘⍴+⊢×1-2×+\)∘{⍵∊⊂'..'})'/'sep r
[4] 1↓⊃,/'/',¨~∘(⊂'..'){⍵/⍨(⊢⍱¯1⌽⊢)2 0⍷'..' ''⍳⍵}⍣≡'/'sep r
[5] ⍝ 1↓⊃,/'/',¨~∘(⊂'..'){⍵/⍨(⊢⍱¯1⌽⊢)0 1⍷⍵∊⊂'..'}⍣≡'/'sep r
[6] ⍝ ⍵ file path absolute or relative ending in '/' or '\'
[7] ⍝ ← absolute with '/' throughout
[8] ⍝ windows resolves '/a/b/../' to '/a/' where apparently unix doesn't
[9] ⍝ Phil 2018-07-24 22.37
[10] }
∇
∇ fileTree←{⍺←⊢
[1] root←fPath ⍵,'/.'
[2] file←{⍵⊣⍵.(Path Size Date)←''⍬ ⍬}⎕NS''
[3] tree←{file dir←⍺ ⍵
[4] p t s d←0 1 2 3 ⎕NINFO⍠1⊢dir,'/*'
[5] (sub z z)(p s d)←↓¨(1 2=⊂t)/¨⊂↑p s d
[6] file.(Path Size Date),←p s d
[7] ∇⍨/sub,file
[8] }
[9] r←file tree root
[10] r⊣r.Date←DT.ts2dt↑r.Date
[11] ⍝ file object - complete tree - see folderObj
[12] ⍝ ⍵ string - file root path
[13] ⍝ ← scalar space with [Path Size Date] for all files in tree
[14] ⍝ Path will always contain '/' rather than '\'
[15] ⍝ Date is float YYYYMMDD.hhmmss (smaller and 1 vs 7 per item)
[16] }
∇
∇ fixQV←{⍺←⊢
[1] 0≠⍵.⎕NC fn←MS.BH:'' ⍝ fn name
[2] nms←MS.BI ⍝ which vars ?
[3] z←⍵.⎕FIX(MS.HG,fn)(' ##.(',nms,')←',⍕⍵.⍎nms),MS.BN,⊂MS.HH
[4] showMsg MS.BO
[5] ⍝
[6] ⍝ Phil 2018-04-04 21.06
[7] }
∇
∇ fixValue←{⍺←⊢ ⋄ ren←⍺⊣0
[1] null ⍵:(3+ren)⍴⊂''
[2] fqn typ val←,∘⊂¨if(≡⊃)⍵
[3] fqn typ val{⍺[⍵]}←⊂ord←⍋(≢sPath)¨fqn
[4] ns←(1↓¨MS.AY)dix 1↓¨MS.AZ
[5] nc←⊃⌊/MS.AY MS.AZ⍳¨⊂typ
[6] nam←1↓¨1⊃spc nam←↓⍉↑namx¨fqn
[7] ers←⍳0 2⊣res←0⍴⍨⍴nam
[8] fixNs←⍎''⎕NS⍨⍕
[9] fixSrc←{0::0 ⋄ 1⊣(fixNs ⍺).⎕FIX ⍵}
[10] (x/res)←fixSrc⌿↑spc val/¨⍨⊂x←nc=ns.script
[11] spc←fixNs eu spc
[12] data←↓⍉↑(⍳⍴nam)nam spc val
[13] fixVar←{0::0 ⋄ x n s v←⍵ ⋄ 1⊣n s.{⍎⍺,'←⍵'}⍺⍺ v}
[14] fixFn←{0::0 ⋄ x n s v←⍵ ⋄ n≡r←s.⎕FX v:1 ⋄ 0∊∊r:0 ⋄ 1⊣ers⍪←x r}
[15] fixSrc←{0::0 ⋄ x n s v←⍵ ⋄ n≡r←'.'UT.nn⍕s.⎕FIX v:1 ⋄ 1⊣ers⍪←x r}
[16] fixClss←~{⍵\~1↓0,fixSrc/0,⍪⍵/⍺}⍣≡
[17]
[18] (x/res)←AN.decode fixVar/0,⍪data/⍨x←nc=ns.array
[19] (x/res)←⊢fixVar/0,⍪data/⍨x←nc=ns.charlist
[20] (x/res)←↑fixVar/0,⍪data/⍨x←nc=ns.charmat
[21] (x/res)←{1↓⊃,/UT.CR,¨⍵}fixVar/0,⍪data/⍨x←nc=ns.charstring
[22] (x/res)←fixFn/0,⍪data/⍨x←nc∊ns.(function operator)
[23] (x/res)←(x/data)∘fixClss 1/⍨x←nc∊ns.(class interface)
[24] z←{p←⊃'.'UT.pn⊃f t←⍺⊃¨fqn typ ⋄ (⍺⊃typ)←c←⊃nameClass⊢(⍺⊃fqn)←n←p,⍵
[25] showMsg'* ',t,' ',f,MS.DO,c,' ',n
[26] }/ers⍪{⍵,⍪'.'UT.nn¨fqn[⍵]}~∘(⊣/ers){⍵/⍳⍴⍵}res∧typ≢¨nameClass fqn
[27] z←showMsg,/(⊂MS.DJ),⍉↑typ' 'fqn/¨⍨⊂~res
[28] (⍋ord)∘{⍵[⍺]}¨⍣ren⊢((res∨ren)∘/¨fqn typ val),ren/⊂res
[29] ⍝ [⍺] 0|1 - compress or return fixed flags - dflt 0
[30] ⍝ ⍵ fqn type value
[31] ⍝ ← ⍵ fixed - compressed if ⍺=0 or with mask attached if ⍺=1
[32] ⍝ Phil 2018-07-12 17.44
[33] }
∇
∇ folder←folder
[1] folder←⊃⎕NPARTS
[2] ⍝ Phil 2018-08-10 18.39
∇
∇ folderObj←{⍺←⊢
[1] dir←fPath ⍵,'/'
[2] p t s d←0 1 2 3 ⎕NINFO⍠1⊢dir,'*'
[3] p s d/⍨←⊂t=2
[4] r⊣(r←⎕NS'').(Path Size Date)←p s(DT.ts2dt↑d)
[5] ⍝ folder object - ignore subfolders - see fileTree
[6] ⍝ ⍵ string - dir path
[7] ⍝ ← scalar space with [Path Size Date] for all files in dir
[8] ⍝ Path will always contain '/' rather than '\'
[9] ⍝ Date as YYYYMMDD.hhmmss
[10] }
∇
∇ getChangeFilenames←{dat←⍺
[1] f←,⊂if≡⍵
[2] ~dat.hist:(≢f)⍴⊂''
[3]
[4] s t←dat.(nspath changes)
[5] n←'..'encodeCaps⍣dat.case⊢(1+≢s)↓¨f ⍝ else leave as is
[6] c←nameClass f ⍝ may be MS.AX ".*" dealt with elsewhere
[7] ,/(⊂t),n,(⍪c),⊂MS.HN
[8]
[9] ⍝ ⍺ dat
[10] ⍝ ⍵ fqns
[11] ⍝ ← full paths
[12] ⍝ with nspath #.one
[13] ⍝ and folder c:/myproject/
[14] ⍝ script #.one.TWO.Three.four
[15] ⍝ → c:/myproject/.acme/changes/TWO-7.Three-1.four-0.script.change
[16] ⍝ must be encoded as separate files
[17] ⍝ Phil Last 2017-12-01 11.17
[18] }
∇
∇ getEnvironment←{
[1] ⊢2 ⎕NQ'.' 'GetEnvironment'⍵
[2] }
∇
∇ getFolder←{
[1] ⍵{
[2] ⍵.(HasEdit StartIn)←1,⊂fPath''if null ⍺
[3] ⍵.Target⊣⍵.Wait
[4] }⎕NEW⊂'BrowseBox'
[5] ⍝ ⍵ start-in folder
[6] ⍝ ← selected folder or ''
[7] ⍝ Phil Last 2016-09-22
[8] }
∇
∇ getSource←{dat←⍺ ⋄ ref←⍵≡MS.BG ⋄ prev←dat getTime''
[1] src tgt←dat.(source nspath),¨'' '.' ⍝ ../APLSource/
[2] read←{⊃MS.HI ⎕NGET ⍵ 1}
[3] (path date)←{⍵.(Path Date)}fileTree⊢src ⍝ all files
[4] path date/⍨←⊂~∨/'/.'⍷(≢src)↓⍤1↑path ⍝ ignore all /.*/
[5] file type←↓⍉↑(UT.px(≢src)↓⊢)¨path ⍝ 'ns/path/file' '.type'
[6] path date file type/⍨←∊/Cc type(MS.AZ,MS.AY) ⍝ only valid types
[7] name←'/.'decodeCaps file
[8] path date file name type/⍨←⊂ref≤new←date>prev ⍝ new or not refresh
[9] dup←(⊢∊⊢(/⍨)~∘nub)name
[10] z←showMsg MS.DD showList,/(tgt∘,¨dup/name),'=',⍪dup/type
[11] z←showMsg MS.BC,MS.EO,((≢path)UT.pl MS.FL),MS.EY,¯4 tPath src
[12] val←3 read ticks path ⋄ fqn←tgt∘,¨name
[13] fqn type val msk←1 fixValue fqn type val ⍝ name/type-change?
[14] z←showMsg MS.FW∘,¨(¯4 tPath¨path/⍨~msk),¨⊂MS.BP ⍝ file needs att'n
[15] fqn type val path date/⍨←⊂msk ⍝ remove unfixed
[16] z←dat renameSource path fqn ⍝ if different
[17] z←dat putTime''
[18] ~dat.hist:fqn if ref⊢⍵
[19] chgs←⊃(⊣(/⍨)prev<⊢)/dat changes'' ⍝ new in acre
[20] diff←(fqn∊chgs)<prev<date ⍝ new in OS
[21] msg←MS.EN,((+/diff)UT.pl MS.FN),MS.EZ,¯4 tPath dat.changes
[22] z←showMsg msg showList diff/fqn
[23] fqn←dat putChange diff∘/¨fqn val type
[24] fqn if ref⊢⍵
[25] ⍝ ⍺ dat
[26] ⍝ ⍵ ? or MS.BG ('Refresh')
[27] ⍝ ← ⍵ or fqns of refreshed items
[28] ⍝ get source and fix; if refresh fetch only changes
[29] ⍝ Phil 2018-07-18 19.47
[30] }
∇
∇ getSourceFilenames←{dat←⍺
[1] src tgt←dat.(nspath source)
[2] name←(1+≢src)↓¨fqn←,⊂if≡⍵
[3] alt←{1↓'#'sep⊃,/'/',¨'.'sep⊃,/'#',¨⍵}
[4] file←dat.case('./'∘encodeCaps)else alt name
[5] tgt∘,¨file,¨nameClass fqn
[6]
[7] ⍝ ⍺ dat
[8] ⍝ ⍵ assume fqns
[9] ⍝ ← full paths
[10] ⍝ with nspath #.one
[11] ⍝ and folder c:/myproject/
[12] ⍝ array #.one.TWO.Three.four
[13] ⍝ gives c:/myproject/APLSource/TWO-7/Three-1/four-0.array
[14] ⍝ Phil Last 2018-01-02 20.42
[15] }
∇
∇ getTime←{dat←⍺ ⋄ res←⌈/dat.loadtime
[1] ~dat.hist:res
[2] 0::res
[3] res⌊⊃1⊃⎕VFI~∘⎕TC⊃⎕NGET dat.latest
[4] ⍝ see putTime
[5] ⍝ Phil 2018-08-08 18.02
[6] }
∇
∇ getValue←{
[1] type←nameClass⊢fqn←,⊂if≡⍵
[2] ns←(1↓¨MS.AY)dix 1↓¨MS.AZ
[3] nc←⊃⌊/MS.AY MS.AZ⍳¨⊂type
[4] val←0⍴⍨⍴fqn
[5] (x/val)←⊢∘⍎/0,⍪fqn/⍨x←nc=ns.charlist
[6] (x/val)←⊢∘ntbs∘⍎/0,⍪fqn/⍨x←nc=ns.charmat
[7] (x/val)←sep∘⍎/UT.CR,⍪fqn/⍨x←nc=ns.charstring
[8] (x/val)←AN.format∘⍎/2,⍪fqn/⍨x←nc=ns.array
[9] (x/val)←⊢∘⎕NR/0,⍪fqn/⍨x←nc∊ns.(function operator)
[10] (x/val)←{0::0 ⋄ ⎕SRC⍎⍵}/0,⍪fqn/⍨x←nc∊ns.(script class interface)
[11] fqn type val/¨⍨⊂~val∊0 ⍝ remove anything else
[12] ⍝ ⍵ fqns
[13] ⍝ ← fqn type val - of only arrays, defined fns and ops and scripts
[14] ⍝ filtered and re-ordered
[15] ⍝ vals are lists of strings
[16] ⍝ see fix Values
[17] ⍝ Phil Last 2017-11-22 22.38
[18] }
∇
∇ getVersion←{
[1] 1:' 'sep⊃releaseNotes⊣''
[2] ⍝ see releaseNotes wherein first line should be
[3] ⍝ name ver date compat
[4] ⍝ name - system name
[5] ⍝ ver - as maj.mid.min
[6] ⍝ date - when code released
[7] ⍝ compat - earliest data-compatible ver
[8] ⍝
[9] ⍝ notes on the present release should be terminated
[10] ⍝ with a line containing only hyphens.
[11] ⍝ Phil Last 2014-10-10
[12] }
∇
∇ itemName←{
[1] f←(id←openProjects'').source
[2] null⊢b←{⊃∊/Cc f p}if null f∊p←(≢¨f)↑¨⊂fp←⊃,/2⍴1 ⎕NPARTS ⍵:''⊣showMsg fp
[3] id←⊃b/id
[4] id.nspath,'.',⊃'/.'decodeCaps(≢⊃b/f)↓fp
[5] ⍝ itemname from source filepath
[6] ⍝ Phil 2018-02-25 00.38
[7] }
∇
∇ keys←{⍺←⊢
[1] sig←⎕AN,,'G< 9999-99-99 99.99>'⎕FMT 100⊥5⍴⎕TS
[2] sig←'Z:L:R:U:⍝ ',sig,'L:'
[3] d←'E:←{⍺←⊢R:R:⍝R: }8:U:U:' '⎕NL¨⍳11'(']',MS.NA,'.')'⎕signal ' '' '→⎕lc'sig']changes '
[4] ⍝ 2 3 4 5 6 7 8 9
[5] UT.pf/(~d∊∊d)⌿d,⍪2+⍳⍴d
[6] ⍝
[7] ⍝ Phil 2018-01-23 15.22
[8] }
∇
∇ localFolder←{
[1] fPath(getEnvironment'temp'),'/../'
[2] ⍝ Phil 2018-01-23 15.35
[3] }
∇
∇ nOff←{⍺←⊢
[1] ≢/Cc MS.GB(⍕⍵)
[2] ⍝ not if ⍵ is 'off', 'Off', 'OFF' &c.
[3] ⍝ Phil 2018-06-18 12.32
[4] }
∇
∇ nameClass←{⍺←⊢
[1] null⊢fqn←,⊂if≡⍵:''
[2] type←⍺⊣0 ⍝ 0 (default) .array ... - 1 .apla ...
[3] ⍝ array function operator script class interface list matrix string unknown
[4] ⍝ 2 3 4 9.1 9.4 9.5 2 2 2 0
[5] ns←(1↓¨MS.AZ)(⎕NS'').{⎕THIS⊣⍎⍕⍺,'←⍵'}type⊃MS.AZ MS.AY
[6] c←9(⊢-1|>×⊢)(⎕NC fqn)(⊣×∊)validAPLType'' ⍝ floor < 9
[7] t←ns.(array function operator script class interface),⊂MS.AX
[8] r←t[2 3 4 9.1 9.4 9.5⍳c]
[9] (a/r)←{
[10] dr←(≡v),≢⍴v←#.⍎⍵
[11] dr≡2 1:ns.array ns.charlist⊃⍨∧/(''≡0∘/)¨v
[12] dr≡1 2:ns.array ns.charmat⊃⍨1=0=10|⎕DR v
[13] dr≡1 1:ns.array ns.charstring⊃⍨1=0=10|⎕DR v
[14] ns.array
[15] }/0,⍪fqn/⍨a←c=2
[16] (a/r)←{
[17] 0::'' ⍝ bluebell
[18] ns.script⊣⎕SRC #.⍎⍵ ⍝ script
[19] }/0,⍪fqn/⍨a←c=9.1
[20] r
[21] ⍝ return identifier also used as filetype
[22] ⍝ Phil Last 2018-01-15 15.35
[23] }
∇
∇ namx←namx
[1] namx←1↓⎕NPARTS
[2] ⍝ name, extension
[3] ⍝ nilad returning monad
[4] ⍝ 'zero/one/two.three.four'
[5] ⍝ → 'two.three' '.four'
[6] ⍝ ⎕NPARTS is far and away the fastest I can achieve.
∇
∇ ncHelp←{⍺←⊢
[1] z←⎕EX'temp'
[2] z←{
[3] ⍵.GeneralArray←⍳2 3
[4] ⍵.ListOfStrings←↓⍪⎕D
[5] ⍵.CharacterMatrix←⎕FMT ⎕D
[6] ⍵.CharacterString←⎕D
[7] ⍵.DirectFunction←{⎕D}
[8] ⍵.DirectOperator←{⍺⍺}
[9] z←⍵.⎕FX'r←TraditionalFunction w' ''
[10] z←⍵.⎕FX'r←(f TraditionalOperator)w' ''
[11] ⍵.ContainerNamespace←⎕NS''
[12] ⍵.ScriptedNamespace←⎕FIX':namespace' ':endnamespace'
[13] ⍵.Class←⎕FIX':class' ':endclass'
[14] ⍵.Interface←⎕FIX':interface' ':endinterface'
[15] ⍵.DerivedFunction←+.×.-
[16] ⍵.MixedArray←1 '2' 3 '4' 5 '6' 7 '8' 9 '0'
[17] ⍵.NumericArray←2 3⍴⍳9
[18] ⍵.MissingItem←''
[19] ⍵.GuiObject←⎕NEW'Form'(⊂'Visible' 0)
[20] ⍵.ClassInstance←⎕NEW ⎕FIX':Class' ':EndClass'
[21] ⍵
[22] }⍎nn←'temp'⎕NS''
[23] nms←~∘' '¨↓temp.⎕NL⍳11
[24] r←UT.xc¨nms
[25] z←temp.⎕EX'MissingItem'
[26] r,(nameClass,∘⍪⎕NC)(nn,'.')∘,¨nms
[27] ⍝
[28] ⍝ Phil 2018-05-15 14.07
[29] }
∇
∇ newSession←{
[1] 0::1 ⍝ if we error on SV.setupcomplete it must be new
[2] ~SV.setupcomplete:1 ⍝ if setup incomplete it must be new
[3] 0.000116<|SV.sessionstart-sessionStart''
[4] ⍝ ⍵ ignored
[5] ⍝ Is this a new session? yes/no
[6] ⍝ If setup isn't complete or if saved session start is ≥10s
[7] ⍝ before actual because ws has been saved with CMS open
[8] ⍝ called with userCmdRun in Run under ⎕SE.UCMD
[9] }
∇
∇ nil←nil
[1] nil←∊∘∊⍨ ⍝ member type
[2] ⍝ Phil 2018-06-12 10.44
∇
∇ noHistMsg←{dat←⍺
[1] showMsg MS.BU,dat.nspath,' ',¯4 tPath dat.folder
[2] ⍝
[3] ⍝ Phil 2018-03-11 20.49
[4] }
∇
∇ nonul←nonul
[1] nonul←≢∘∊⍨ ⍝ not match type
[2] ⍝ Phil 2018-06-12 10.44
∇
∇ ntbs←ntbs ⍝ no trailing blanks split
[1] ntbs←{(+/∨\' '≠⌽⍵)↑¨↓⍵} ⍝ nilad returning monad
[2] ⍝ Phil Last 2017-12-06 00.48
∇
∇ nub←nub
[1] nub←⍳⍨=⍳∘≢
[2] ⍝ nub sieve
[3] ⍝ Phil 2018-08-09 17.33
∇
∇ null←null ⍝ matches type - all blanks and zeros
[1] null←≡∘∊⍨ ⍝ nilad returning monad
[2] ⍝ Phil Last 2017-12-18 14.37
∇
∇ openConflict←{dat←⍺
[1] 0=⍴old←openProjects'':⍬
[2] new←,dat
[3] paths←old.(nspath,'.')
[4] path←new.(nspath,'.')
[5] path∊paths:'' ⍝ same space - ok
[6] ∨/⊃¨path⍷¨paths:'' ⍝ over - ok
[7] b←⊃¨paths⍷¨path ⍝ new in old - forbidden
[8] ∨/b:MS.DE showList(new,b/old).nspath
[9] ⍬
[10]
[11] ⍝ ⍺ dat
[12] ⍝ ← null or msgs
[13] ⍝ The order in this function is paramount.
[14] ⍝ implements rule:
[15] ⍝ A project may not be tracked inside another
[16] ⍝ if same, space is expunged and closed before loading
[17] ⍝ if over, spaces are expunged and closed before loading
[18] ⍝ if under, would be in conflict with parent
[19] ⍝ Phil 2018-06-06 21.11
[20] }
∇
∇ openLoad←{dat←⍺ ⋄ trk dep←⍵ ⍝ as of caller
[1] ~null showMsg dat∘openConflict⍣trk⊢'':0 ⍝ can't open this
[2] ~dep:1 ⍝ ok but no deps
[3] pref←{
[4] p←('/',⍺)[('\',⍺)⍳⍺]
[5] (':'∘∊∨'/'=⊃)p:p ⍵ ⍝ absolute path
[6] '.'=⊃p:(dat.folder,'../',p)⍵ ⍝ ../uncle/cousin/nephew
[7] (dat.folder,(⊃,/(1++/p∊'/\')/,/'../'),p)⍵ ⍝ uncle/cousin
[8] }
[9] 0∊⍴these←~∘∊⍨⊂if≡dat.open:1 ⍝ ex config
[10] nss←(⎕NEW ⎕SE.Parser(optionFields'dep track')).Parse¨these
[11] args←nss.Arguments
[12] args nss/⍨←⊂~args∊SV.arguments ⍝ this time
[13] 0∊⍴SV.arguments,←args:1
[14] track←trk∧nOff¨nss.track
[15] depend←dep∧nOff¨nss.dependencies
[16] dts←(⊂trk dep)openProject¨↓track,depend,⍪pref/↑2↑¨args
[17] dts track depend/⍨←⊂dts≠0 ⍝ only opened
[18] z←dataSpaces track/dts ⍝ keep only tracked dependencies
[19] ~null showMsg dat∘openConflict⍣trk⊢'':0⊣showMsg dat.config MS.CB
[20] 1:1
[21] ⍝ dyadic calls to openProject tell it NOT to run Startup
[22] ⍝ Open dependent projects
[23] ⍝ this is potentially endlessly recursive
[24] ⍝ Phil 2018-06-06 21.11
[25] }
∇
∇ openProject←{⍺←⊢ ⋄ top←1≡⍺ 1 ⋄ dflt←⍺⊣1 1
[1] trk dep←dflt∧2⍴z z proj←⍵
[2] null⊢src←{getFolder'/'}if null⊃src tgt←2↑proj:0
[3] (dat←⎕NS'').(changed folder loadtime)←''(fPath src,'/'),DT.ts2dt ⎕TS
[4] dat.(config source code changes latest)←{
[5] ⍵}dat.folder∘,¨MS.HM MS.GY,MS.NB∘,¨''MS.EU MS.HE
[6] ~∨/2⍴src cnf cde←⎕NEXISTS¨dat.(source config changes):{
[7] 0}showMsg MS.DG,' ',¯4 tPath dat.folder
[8] z←'dat'⎕NS UT.lc⊢cfg←readConfig dat.config ⍝ see configFields
[9] nspath←{'/'UT.nn ¯1↓dat.folder}if null dat.projectspace if null tgt
[10] ~((1=≢)∨0∘ssp∨0=⎕NC)dat.nspath←⊃prefSpace nspath:{
[11] 0}showMsg MS.DC
[12] ~dat openLoad trk dep:0 ⍝ load subsids
[13]
[14] z←showMsg(MS.ER,MS.EY),dat.folder
[15] space←⍎dat.nspath #.⎕NS''⊣openProjects⊣⎕EX{# UT.nl⍳10}if≢dat.nspath
[16] cfg.KeepHistory←MS.GB MS.GA⊃⍨dat.hist←≢/Cc dat.keephistory MS.GB
[17] cfg.CaseCode←MS.GB MS.GA⊃⍨dat.case←≢/Cc dat.casecode MS.GB
[18] z←MS.FV space.{⍎⍺,'←⍵'}cfg⊣cfg.ProjectFolder←dat.folder
[19] z←showMsg MS.EZ,dat.nspath
[20] z←deleteFolder⍣(cde>dat.hist)⊢dat.code
[21] z←⎕MKDIR/3,⍪dat.(source changes)/⍨(~src),cde<dat.hist
[22] z←MS.NB∘⎕NPUT if(~⎕NEXISTS)dat.folder,MS.FM ⍝ git specific -
[23] z←dat getSource''
[24] dat.changed←⊃dat changes''
[25] z←space∘{0::⊢showMsg UT.bx MS.DN,MS.DP,⍵
[26] ⊢⍺.⍎UT.ep ⍵}if(trk∧top>null)dat.startup ⍝ trk?
[27] dat⊣dat.loadtime,←DT.ts2dt ⎕TS
[28] ⍝ [⍺] trk dep
[29] ⍝ ⍵ trk dep (folder [space])
[30] ⍝ ← dat or 0 - see OpenProject LoadProject CreateProject
[31] ⍝ Phil 2018-06-06 21.11
[32] }
∇
∇ openProjects←{
[1] 0∊⍴ids←dataSpaces'':⍬ ⍝ none
[2] missing←ids/⍨(((0∊⍴#.⎕NL⍳10)∧1=≢¨)∨0=⎕NC)ids.nspath ⍝ path missing
[3] 1:⊢ids←dataSpaces missing ⍝ remove
[4] ⍝ ensure tracked projects still in ws
[5] ⍝ remove any ids where nspath no longer a space.
[6] ⍝ Phil 2018-06-06 21.11
[7] }
∇
∇ optionFields←{⍺←⊢
[1] unused←'abefgijklnopqrsuvxyz'
[2] opts←,⊂'casecode:on'
[3] opts,←⊂'confirm:'
[4] opts,←⊂'dependencies:on'
[5] opts,←⊂'encoding:aplan'
[6] opts,←⊂'help'
[7] opts,←⊂'messages:on'
[8] opts,←⊂'track:on'
[9] opts,←⊂'when[=]'
[10]
[11] in←3⍴¨opts
[12] opts←' -'∘,¨opts
[13] {1↓⊃,/opts[in⍳in∩3⍴¨' 'sep ⍵]}¨⊂if≡⍵
[14] ⍝ convert strings of initials to option specs
[15] ⍝ Phil 2018-04-03 12.16
[16] }
∇
∇ prefSpace←{
[1] null⊢nms←⊂if≡⍵:0/⊂''
[2] SV.space''['#'=⊃¨nms],¨nms
[3] ⍝ ⍵ items or spaces
[4] ⍝ ← depth-2 list of items or space paths
[5] ⍝ whence command called for non-fqn space or items
[6] ⍝ Phil Last 2018-01-15 22.16
[7] }
∇
∇ putChange←{dat←⍺ ⍝ or Deleted
[1] ~dat.hist:''
[2]
[3] null⊃fqn val typ del←4↑⍵:fqn
[4] chg del←0 1=del≡MS.EX
[5] fqn val typ←,∘⊂¨if(≡⊃)fqn val typ
[6] fns←dat getChangeFilenames fqn ⍝ if del or new type will be ".*"
[7] fns←⍉⍪fns{⍺ UT.re MS.AX ⍵}¨typ
[8] fns⍪⍨←(MS.EX,⍨(-≢MS.HN)↓⊢)¨fns ⍝ del over chg
[9] aud←2⊥fns∊{⍵.Path}folderObj dat.changes
[10] ⍝ extant: 0 add , 1 change , 2 delete , 3 BOTH!!!
[11] exi←aud≠0 ⍝ exists
[12] ren←(del∧aud=1)∨chg∧aud=2 ⍝ but wrong type
[13] old new←↓(del=ren)⊖fns
[14] change←{val old new ren exi←⍵
[15] tie←exi{
[16] ⍺:⍵ ⎕FTIE 0
[17] (⊢⊣0 ⎕FAPPEND⊢)⍵ ⎕FCREATE 0
[18] }old
[19] ptr←val ⎕FREPLACE tie,¯1+1⊃⎕FSIZE tie
[20] z←new∘⎕FRENAME⍣ren⊢tie
[21] (⎕FUNTIE tie)⊢ptr ⎕FAPPEND tie
[22] }
[23] z←change/0,⍪↓⍉↑val old new ren exi
[24] fqn⊣dat.changed∪←fqn
[25] ⍝ ⍺ dat
[26] ⍝ ⍵ fqn value type [MS.EX] if del
[27] ⍝ ← fqns
[28] ⍝ Phil 2018-02-17 23.14
[29] }
∇
∇ putSource←{dat←⍺
[1] null⊢fqn type value←,∘⊂¨if(≡⊃)⍵:⍵
[2] src tgt←dat.(nspath source)
[3] path←dat getSourceFilenames fqn
[4] (b/path)←{⍺ UT.re MS.AX ⍵}⌿↑path type/¨⍨⊂b←(1∊MS.AX⍷⊢)¨path
[5] tree←⎕MKDIR/3,⍪∪folder¨path ⍝ ensure folders
[6] z←(,∘⊂if≡¨value){(,⍺)MS.HI ⎕NPUT ⍵ 1}¨path
[7] fqn type value
[8]
[9] ⍝ ⍺ dat
[10] ⍝ ⍵ FQNs type values
[11] ⍝ ← ⍵ same - having written to sourcetree
[12] ⍝ write to source tree files
[13] ⍝ Phil 2018-08-07 14.40
[14] }
∇
∇ putTime←{dat←⍺
[1] dat.loadtime,←now←DT.ts2dt ⎕TS
[2] ~dat.hist:now
[3] 0::now
[4] now⊣(6⍕now+0.000001)⎕NPUT dat.latest 1 ⍝ file as plus 1 sec
[5] ⍝ see getTime
[6] ⍝ Phil 2018-08-07 14.27
[7] }
∇
∇ quoted←{⍺←⊢
[1] ≠\⍵=⊃(⍺,⍵,q)∩q←'''"'
[2] ⍝ Phil Last 2017-05-17 16.48
[3] }
∇
∇ readConfig←{cnf←⍵
[1] rl←Cc⊢ru←{⍵.⎕NL-2}res←configFields''
[2] 0::res⊣showMsg UT.bx MS.DB,cnf
[3] ~⎕NEXISTS cnf:res
[4] d←~∘∊⍨⊃MS.HI ⎕NGET cnf 1 ⍝ lose blank rows
[5] r t←0{'⍝'=z←⊃~∘' '⊃⍵:(1+⍺)∇ 1↓⍵ ⋄ ⍺ z}d ⍝ lose comment rows
[6] cl←Cc⊢cu←{⍵.⎕NL-2}cfg←t{ ⍝ actuals
[7] ⍺='{':7159⌶1↓⊃,/(⎕UCS 13),¨⍵ ⍝ JSON
[8] ⍺=':':0 ⎕FIX ⍵ ⍝ APLscript
[9] ⍺='[':AN.decode ⍵ ⍝ APLAN
[10] ⎕NS'' ⍝ none of the above
[11] }r↓d
[12] null⊢int←rl∩cl:res ⍝ supplied
[13] res⊣ru[rl⍳int]res.{⍎⍕⍺,'←⍵'}cfg.⍎⍕cu[cl⍳int] ⍝ merge
[14] ⍝ ⍵ config filename
[15] ⍝ config is JSON, APLscript or APLAN
[16] ⍝ result is namespace with all and only expected fields
[17] ⍝ with "proper" case restored
[18] }
∇
∇ ref←{⍺←⊢
[1] z\⊢∘(UT.df∘⍎≢⊢)/0,⍪⍵/⍨z←9=⌊⎕NC ⍵
[2] ⍝ ⍵ fqns
[3] ⍝ ← boolean which are refs or ptrs as opposed to named nss or clss
[4] ⍝ Phil 2018-03-20 00.08
[5] }
∇
∇ refs←{⍺←⊢
[1] ⎕AN≢'Phil':0 0⍴''
[2] z←#.ac.MS←allMessages 1⊃'.'sep⊃⎕XSI⊣#.(an ut)←{⍵.(AN UT)}#.ac←⎕THIS
[3] 0 0⍴keys''
[4] ⍝ see buildWs
[5] ⍝ Phil 2018-01-31 14.11
[6] }
∇
∇ renameSource←{dat←⍺
[1] ren←(⊢(⌿⍨)≢/)⊃{⍺,⍪dat getSourceFilenames ⍵}/⍵
[2] z←0⊣⎕MKDIR/3,⍪∪folder¨,ren
[3] msg←{
[4] t←⊃{~∘⍵-1+⍳1+≢⍵}⎕NNUMS
[5] 0::⊃,/MS.BM'"'⍺'"'MS.EZ'"'⍵'"'⊣⎕NUNTIE t
[6] 0⊣⎕NUNTIE ⍵ ⎕NRENAME ⍺ ⎕NTIE t
[7] }/ren
[8] 0⊣showMsg msg~0
[9] ⍝ ⍺ dat
[10] ⍝ ⍵ paths fqns
[11] ⍝ if source filename for fqn ≢ path then rename path
[12] ⍝ ← 0 - having messaged any failures
[13] ⍝ Phil 2018-08-10 11.36
[14] }
∇
∇ run←{⍺←⊢
[1] (OPT.messages was)←'off'OPT.messages
[2] 0::⎕SIGNAL ⎕EN⊣OPT.messages←was
[3] (OPT.messages←was)⊢⍺ codeHook ⍵
[4] ⍝ Phil Last 2018-01-17 23.16
[5] }
∇
∇ sPath←sPath
[1] sPath←1⊃⎕NPARTS
[2] ⍝ space path
[3] ⍝ monad
[4] ⍝ '#.a.b.c' → '#.a.b'
[5] ⍝ '#.a.b' → '#.a'
[6] ⍝ '#.a' → '#'
[7] ⍝ '#' → '#'
∇
∇ sep←sep ⍝ sep string to list sans sep
[1] sep←⊣(1↓¨=⊂⊢), ⍝ nilad returning dyad
[2] ⍝ Phil 2018-02-10 20.05
∇
∇ sessionStart←{
[1] (DT.ts2dd ⎕TS)-(2⊃⎕AI)÷×/24 60 60 1000
[2] ⍝ Session start in days.decs since Proleptic Gregorian origin.
[3] ⍝ From the difference between clock- (⎕TS) and session-time (⎕AI).
[4] ⍝ DT.dd2ts to see result in a readable form.
[5] }
∇
∇ setChange←{dat←⍺
[1] fqn typ val←⍵
[2] z←dat putChange fqn val typ
[3] ⊃dat putSource fqn typ val
[4] ⍝ both
[5] ⍝ Phil 2018-02-17 23.14
[6] }
∇
∇ setDataSpaces←{
[1] ⎕THIS.dataSpaces←({⍵⊣⍵.ids←⍬}⎕NS'')∘{⊢⍺.ids←⍺.ids{(⍺~⍵)∪⍵~⍺}⍵}
[2] 1:⍵
[3] ⍝ ←⍵ returned untouched
[4] ⍝ Runs once in new session.
[5] ⍝ Creates dataSpaces function that stores the spaces
[6] ⍝ in an anonymous space composed with the function.
[7] ⍝ Call dataSpaces only where adding or removing
[8] ⍝ To query use openProjects instead.
[9] }
∇
∇ setEnvironment←{⍺←⊢ ⍝ only if no projects
[1] top←UT.rs⊢ici←⎕THIS ⍝ child of # or ⎕SE
[2] ici.SV←top.⎕NS''
[3] SV.setupcomplete←0
[4] SV.(errmsgs opened)←'' ''
[5] path ws name←SV.(inipath workspace systemname)←⍵
[6] ici.MS←allMessages name
[7] ici.EN←aplErrors''
[8] ici.CD←cmdDefs name
[9] ici.SX←syntaxHelp name
[10] SV.sessionstart←sessionStart''
[11] z←editFix'Start' ⍝ sets other stuff in SV
[12] ⍝ ici.OPT←{⍵⊣⍵.messages←'on'}⎕NS'' ⍝ pro-tem as this runs
[13] z←showMsg⍕3⍴getVersion''
[14] 1:SV.setupcomplete←1
[15] ⍝ some dictionaries & derived fns
[16] ⍝ ⍵ ?
[17] ⍝ there should be no tracked instances when this runs
[18] ⍝ ← 1
[19] ⍝ Phil 2018-06-06 21.11
[20] }
∇
∇ showList←{
[1] (≢∘∊⍨⍵)/(⊂⍺∪':'),ntbs⍕1 UT.ty ⍵
[2] ⍝ ⍺ message:
[3] ⍝ ⍵ list e.g. 'one' 'two' 'three' ...
[4] ⍝ ← list as:
[5] ⍝ message:
[6] ⍝ one four seven ...
[7] ⍝ two five eight
[8] ⍝ three six ...
[9] ⍝ empty if ⍵ empty
[10] }
∇
∇ showMsg←{
[1] (null ⍵):⍵ ⍝ empty arg
[2] disp←OPT.messages
[3] data←ntbs ⎕FMT↑⍵
[4] SV.errmsgs,←data/⍨'!'=⊃¨data ⍝ reset in userCmdRun
[5] ≡/Cc disp MS.GB:data ⍝ its NOT having been displayed!
[6] '#'∊disp:data⊣⍎disp,(2 0 3⍳#.⎕NC disp)↓',← data'
[7] ⍝ data⊣#.what← data ⍝ named buffer - missing
[8] ⍝ data⊣#.what,← data ⍝ - array
[9] ⍝ data⊣#.what data ⍝ - function
[10] 1:⊢{⎕←⍵}¨data ⍝ else send everything to the session
[11]
[12] ⍝ ⍵ is msg(s) to be displayed
[13] ⍝ ← ⍵ its having been displayed or otherwise
[14] ⍝ values of OPT.messages recognised as
[15] ⍝ determining output. Default is session.
[16] ⍝ 'Off' no messages.
[17] ⍝ '#.path.to.missing' initialises buffer
[18] ⍝ '#.path.to.array' is buffer
[19] ⍝ '#.path.to.function' runs explicit function with arg - ignores result
[20] ⍝ Phil Last ⍝ 2008-10-26 08:27
[21] }
∇
∇ since←{⍺←⊢
[1] build←DT.ts2dt⊃⊃3 ⎕NINFO⍠1⊢⎕SE.acre._code.SV.workspace,'*'
[2] {⍵⌿⍨build<DT.fm2dt↑⊢/⍵}⎕SE.UCMD'changes #.acre -w'
[3] ⍝ Phil 2018-06-21 22.25
[4] }
∇
∇ ssp←{⍺←⊢ ⋄ b←⍺⊣1 ⍝ dflt 1 - scripted
[1] {n\{0::~⍺ ⋄ ⍺⊣⎕SRC⍎⍵}/b,⍪⍵/⍨n←9.1=⎕NC ⍵}⊂if≡⍵
[2] ⍝ ⍺ 1/0 - 1 scripted - 0 not-scripted
[3] ⍝ ⍵ fqns (2 1≡≡,≢∘⍴)
[4] ⍝ ← boolean - which are scripted or non-scripted spaces
[5] ⍝ NB # is neither
[6] ⍝ Phil 2018-02-01 17.06
[7] }
∇
∇ stripCode←{⍺←⊢
[1] in out←'#' '#'(⊢,,)¨⍺⊣'/.'
[2] one←{⍺,⊃'-'sep ⍵}
[3] (≢out)↓¨(⊢⊂⍨out⍷⊢)⊃,/(⊃out)∘one eu 1↓(⊃in)sep⊃,/in∘,¨⊂if≡⍵
[4] ⍝ same as decodeCaps but ignore caseCode leaving caps as are
[5] ⍝ Phil Last 2018-01-11 17.17
[6] }
∇
∇ syntaxHelp←{
[1] CD.command(⎕NS'').{⎕THIS⊣⍎⍕⍺,'←⍵'}CD.syntax
[2] ⍝ ns of command syntax uses CD ex setEnvironment & cmdDefs
[3] ⍝ Phil 2018-03-31 17.53
[4] }
∇
∇ tPath←{
[1] 1↓⊃,/'/',¨⍺ UT.tm~∘∊⍨'/'sep ⍵
[2] ⍝ truncate path
[3] ⍝ Phil 2018-08-21 21.18
[4] }
∇
∇ tempFolder←{
[1] fPath(getEnvironment'temp'),'/'
[2] ⍝ Phil 2018-01-23 15.35
[3] }
∇
∇ test←{⍺←⊢
[1] z←refs''
[2] tests←##.⍎MS.FZ
[3] fns←tests.Tests.⎕NL-3
[4] z←tests.(Tester.EstablishHelpersIn Tests)
[5] z←(1∊⍵)tests.Tests.RunDebug else{tests.Tests.Run⊣⍵}0
[6] z←tests.Tests.{⎕EX(⎕NL-3)~⍵}fns
[7] ⍝ Phil 2018-01-31 16.02
[8] }
∇
∇ time←{⍺←⊢
[1] UT.ls,UT.pl/(×t)⌿(t←0 60 60⊤⍵),⍪MS.GI MS.GJ MS.GK
[2] ⍝
[3] ⍝ Phil Last 2017-12-08 12.12
[4] }
∇
∇ userCmdRun←{
[1] (new method arg type space path wsid name)←⍵
[2] ⎕THIS.OPT←⎕NS arg.(⎕NS'qwertyuiopasdfghjklzxcvbnm'⎕NL 2.1)
[3] z←Start⍣new⊢path wsid name ⍝ once
[4] SV.debug←1∊⎕SE.SALTUtils.DEBUG ⍝ OK?
[5] SV.space←space,'.' ⍝ whence called
[6] SV.errmsgs←'' ⍝ new each cmd
[7] SV.arguments←,⊂arg.Arguments ⍝ ditto
[8] z←openProjects'' ⍝ still open?
[9] (item proj share)←'i' 'p' 's'=⊃type ⍝ see cmdDefs
[10] ⍝ ↓↓↓↓↓
[11] res←method{
[12] item:⍺(⍎⍺)itemMethod ⍵ ⍝ items of arg are names
[13] proj:⍺(⍎⍺)projMethod ⍵ ⍝ first item is project
[14] share:⍺(⍎⍺)sharedMethod ⍵ ⍝ arg is specific to method
[15] }arg.Arguments
[16] z←⎕SIGNAL/(,/(⎕UCS 13),¨SV.errmsgs),11/⍨×≢SV.errmsgs
[17] res
[18] ⍝ ⍵ new; method; arg ns; type of fn; whence called; whence loaded; system.
[19] ⍝ Phil 2018-01-28 00.43
[20] }
∇
∇ validAPLType←{
[1] 2.1 3.1 3.2 4.1 4.2 9.1 9.4 9.5
[2] ⍝ ⍵ nested list
[3] ⍝ ← valid ⎕nc values for storable items.
[4] ⍝ array, defined function, defined operator,script, class, interface.
[5] ⍝ Exclude field, property, derived function, ...
[6] ⍝ Phil Last ⍝ 2008-02-03 13:58
[7] }
∇
∇ validItems←{
[1] {⍵(/⍨)(1∘ssp⍱ref)uniq sPath¨⍵}(⊢(/⍨)0∘ssp<ref<⎕NC∊validAPLType),∘⊂if≡⍵
[2] ⍝ ⍵ list of fqns
[3] ⍝ ← ⍵ filtered to include only extant items with no labels; derived fns;
[4] ⍝ container spaces; instances; refs; or children of scripts or refs.
[5] ⍝ Phil 2018-08-09 08.35
[6] }
∇
∇ whichProject←{
[1] null⊢fqn←⊂if≡⍵:⍬
[2] 0∊⍴ids←openProjects'':{0}¨fqn
[3] nss←,∘'.'¨path←ids.nspath
[4] x←0=dss←(ids,0)path UT.co fqn ⍝ items are projects
[5] ~∨/x:dss
[6] (x/dss)←{⊃1↓0,ids/⍨nss(⊃⍷)¨⊂⍵}/0,⍪x/fqn ⍝ items are members
[7] dss
[8] ⍝ ⍵ fqns
[9] ⍝ ← dataspace or zero per fqn
[10] }
∇
Operators:
∇ else←{
[1] ⍺←⊢
[2] (1=⍺⊣0):⍺⍺⊣⍵ ⍝ antecedent
[3] (0=⍺⊣1):⍵⍵⊣⍵ ⍝ consequent
[4] (1 ⍺⍺ ⍵):0 ⍺⍺ ⍵ ⍝ antecedent then consequent
[5] ⍵⍵⊣⍵ ⍝ else alternative
[6] ⍝ ... if ... else ...
[7] ⍝ antecedent else consequent else alternative
[8] ⍝ applies antecedent followed by consequent or alternative to ⍵
[9] ⍝ antecedent, consequent and alternative are arrays or monads
[10] ⍝ Phil Last ⍝ 2008-01-22 07:53
[11] }
∇
∇ eu←{
[1] (⊂u⍳⍵)⌷⊢∘⍺⍺/0,⍪u←∪⍵
[2] ⍝ each unique
[3] ⍝ ⍺⍺ fn to run on each item of ⍵
[4] ⍝ ⍵ vector
[5] ⍝ ← equivalent of ⍺⍺¨⍵ ⍝ ***
[6] ⍝ but having run ⍺⍺ on only a single
[7] ⍝ instance of each unique value of ⍵
[8] ⍝ *** and not at all if none.
[9] ⍝ a fixed left arg can be composed with ⍺⍺ as in:
[10] ⍝ larg∘fn eu rarg
[11] ⍝ Phil Last 2017-12-20 08.57
[12] }
∇
∇ if←{
[1] 1∊⍵⍵⊣⍵:⍺⍺⊣⍵
[2] ⍵
[3] ⍝ consequent if antecedent arg else arg
[4] ⍝ ⍺⍺ any array or monad on ⍵ to return such
[5] ⍝ ⍵⍵ boolean singleton or monad on ⍵ to return such
[6] ⍝ ⍵ array (in domain of either or both of monad ⍺⍺ & ⍵⍵)
[7] ⍝ ← array ⍺⍺ or result of ⍺⍺ ⍵ or ⍵ unchanged
[8] ⍝ Phil Last ⍝ 2008-01-22 12:34
[9] }
∇
∇ itemMethod←{⍺←⊢ ⋄ mon←1≡⍺ 1
[1] mon<null⊢items←⍵:''⊣showMsg MS.DM,SX.⍎⍺
[2] 0∊⍴ids←openProjects'':''⊣showMsg MS.GX
[3] items←prefSpace items ⍝ prefix non-FQNs
[4] no←0=dat←whichProject items
[5] z←showMsg MS.DI showList no/items
[6] items dat/⍨←⊂~no
[7] 0∊⍴items:''⊣showMsg MS.DH
[8] ⍝ ↓↓↓↓
[9] ⊃if≢⍺⍺/dat{⍺ ⍵}⌸items
[10]
[11] ⍝ [⍺] name of method
[12] ⍝ ⍺⍺ method to run - takes instance data space left arg
[13] ⍝ ⍵ args
[14] ⍝ args random list of items of possiby disparate projects
[15] ⍝ Run instance method ⍺⍺ for each subgroup of ⍵
[16] ⍝ corresponding to a tracked project
[17] ⍝ Methods expected to take 1 or more names and return a subset
[18] ⍝ ← results per project, '' if none
[19] ⍝ Phil 2018-06-06 21.11
[20] }
∇
∇ projMethod←{⍺←⊢ ⋄ mon←1≡⍺ 1
[1] args←⍵
[2] proj arg←1(↑_↓)args
[3] mon<(null proj)∨0∊⍴dats←openProjects'':''⊣showMsg MS.DM,SX.⍎⍺
[4] msk←dats.nspath∊prefSpace proj
[5] 0=dat←⊃1↓0,msk/dats:''⊣showMsg MS.BW
[6] ⍝ ↓↓↓↓
[7] dat ⍺⍺ arg
[8]
[9] ⍝ [⍺] name of method
[10] ⍝ ⍺⍺ method
[11] ⍝ ⍵ args
[12] ⍝ args projectspace arg ...
[13] ⍝ run instance method of project ref'd in first of args
[14] ⍝ Phil Last 2018-01-10 21.54
[15] }
∇
∇ ticks←{⍺←⊢ ⋄ p←⍺⊣1
[1] s←⌈(≢⍵)×p÷100
[2] t←⎕AI
[3] r←⊢∘⍺⍺/0,⍪s↑⍵
[4] 1000>2⊃⎕AI-t:r,⊢∘⍺⍺/0,⍪s↓⍵
[5] r,⊢∘⍺⍺/UT.tk 0,⍪s↓⍵
[6] ⍝ [⍺] required percentage (dflt 1%) to run in one second to avoid ticks
[7] ⍝ ⍵ vector
[8] ⍝ ⍵⍵ fn to run on each item of ⍵
[9] ⍝ ← ⍵⍵¨⍵
[10] ⍝ display 1 second ticks if it takes more than one second
[11] ⍝ to process the first a% of items
[12] ⍝
[13] ⍝ Phil 2018-08-09 12.25
[14] }
∇
∇ under←{⍺←⊢
[1] (⍵⍵ ⍺)⍺⍺ ⍵⍵ ⍵ ⍝ 40% faster than ⊃⍺⍺/⍵⍵¨⍺ ⍵
[2] ⍝ dyad: ⍺⍺ twixt application of ⍵⍵ to each arg
[3] ⍝ monad: reapply ⍵⍵ after ⍺⍺ ⍵⍵
[4] ⍝ so might be useful for self inverse
[5] ⍝ Phil Last 2017-12-04 08.28
[6] }
∇
∇ undoredo←{dat←⍺
[1] ~dat.hist:''⊣dat noHistMsg''
[2]
[3] sig←⍺⍺ ⍝ Undo - , Redo +
[4] fqn←{⍵/⍨(#.⎕NC ⍵)∊validAPLType''},∘⊂if≡⍵
[5] fil←dat getChangeFilenames fqn
[6] null⊢fqn fil/⍨←⊂⎕NEXISTS¨fil:''
[7] doit←{fqn fil←⍺ ⍵
[8] f(n x)←0(¯1 ¯2)+2⍴⎕FSIZE t←fil ⎕FTIE 0
[9] p←⎕FREAD t,n
[10] q←f⌈x⌊p sig 1
[11] p=q:'' ''⊣showMsg fqn excRep MS.BV⊣⎕FUNTIE t
[12] n←q ⎕FREPLACE t,n
[13] val←(⎕FUNTIE t)⊢⎕FREAD t,q
[14] fqn val⊣showMsg fqn excRep⍕{⍺,'of',⍵}/q x-f-1
[15] }
[16] fqn val←↓⍉↑~∘∊⍨doit/fqn,⍪fil
[17] type←nameClass fqn
[18] null⊢fqn type val←fixValue fqn type val:''
[19] fqn⊣dat putSource fqn type val
[20] ⍝ ⍺ dat
[21] ⍝ ⍵ fqns
[22] ⍝ ← fqns where changed
[23] ⍝ non-destructive,
[24] ⍝ pointer change to previous edit if exists
[25] ⍝ changefile is [orig edit1 edit2 ... ptr]
[26] ⍝ putChange writes next edit to last comp and its number to next.
[27] ⍝ this increments or decrements pointer twixt first & penultimate
[28] ⍝ Phil Last 2018-01-14 23.07
[29] }
∇
∇ uniq←{⍺←⊢
[1] (⊂u⍳⍵)⌷⍺ ⍺⍺⊢u←∪⍵
[2] ⍝ as ⍺ ⍺⍺ ⍵ but having applied ⍺⍺ to only uniq items of ⍵
[3] ⍝ Phil 2018-02-18 20.42
[4] }
∇
Variables:
Rank: 1; Shape: 61; Depth: 2; Data Representation: 326
Rank: 1; Shape: 358; Depth: 2; Data Representation: 326
Functions:
∇ amend←{⍺←⊢
[1] CODE.startSV 0:
[2] CODE.SV.DB↓0::⎕SIGNAL/⌽⎕EN,⎕DM
[3] ⍺ CODE.amend ⍵
[4] ⍝ ⍵ APL array
[5] ⍝ ← maybe amended via format ⎕ED decode
[6] ⍝ Phil Last 2015-12-15
[7] }
∇
∇ decode←{
[1] CODE.startSV 0:
[2] CODE.SV.DB↓0::⎕SIGNAL/⌽⎕EN,⎕DM
[3] CODE.decode ⍵
[4] ⍝ ⍵ Array Notation encoding
[5] ⍝ ← original array represented by ⍵
[6] ⍝ Phil Last 2015-12-12
[7] }
∇
∇ encode←{
[1] CODE.startSV 0:
[2] CODE.SV.DB↓0::⎕SIGNAL/⌽⎕EN,⎕DM
[3] CODE.encode ⍵
[4] ⍝ ⍵ APL array
[5] ⍝ ← inline Array Notation encoding of ⍵
[6] ⍝ Phil Last 2015-12-12
[7] }
∇
∇ format←{⍺←⊢
[1] CODE.startSV 0:
[2] CODE.SV.DB↓0::⎕SIGNAL/⌽⎕EN,⎕DM
[3] ⍺ CODE.format ⍵
[4] ⍝ ⍺ see CODE
[5] ⍝ ⍵ APL array
[6] ⍝ ← pretty Array Notation encoding of ⍵
[7] ⍝ Phil Last 2015-12-12
[8] }
∇
∇ help←{
[1] CODE.help⊣'' ⍝ array or function?
[2] ⍝ Phil Last 2017-09-25 12.06
[3] }
∇
∇ reset←{⍺←⊢
[1] CODE.reset ⍵
[2] ⍝ reset all options to default
[3] ⍝ Phil Last 2016-01-06
[4] }
∇
∇ session←{
[1] CODE.startSV 0:
[2] CODE.SV.DB↓0::⎕SIGNAL/⌽⎕EN,⎕DM
[3] ⎕THIS.sandbox←⎕NS''
[4] OPTIONS.EX←(⍕⎕THIS),'.sandbox'
[5] (reset ⎕EX'sandbox')⊢CODE.session ⍵
[6]
[7] ⍝ ⍵ ?
[8] ⍝ indent, await input, decode, format result +
[9] ⍝ → to end
[10] ⍝ Phil Last 2017-09-20 14.31
[11] }
∇
Operators:
∇ value←{
[1] CODE.startSV 0:
[2] CODE.SV.DB↓0::⎕SIGNAL/⌽⎕EN,⎕DM
[3] ⍺⍺ CODE.value ⍵
[4] ⍝ ⍺⍺ dfn with embedded Array Notation encoding
[5] ⍝ ← decoded value
[6] ⍝ Phil Last 2015-12-16
[7] }
∇
References:
SB | ==> | ⎕SE.acre._code.AN.CODE.[Namespace] |
SV | ==> | ⎕SE.acre._code.AN.CODE.[Namespace] |
io1 | ==> | ⎕SE.acre._code.AN.CODE.[Namespace] |
ml3 | ==> | ⎕SE.acre._code.AN.CODE.[Namespace] |
Functions:
∇ amend←{⍺←⊢
[1] SV.DB↓0::⎕SIGNAL/⌽⎕EN,⎕DM
[2] ⍝ ns←#.⎕NS''
[3] ns←⎕NS''
[4] name←'APL','array' 'space'⊃⍨9=⎕NC'⍵'
[5] 1∘⊃⍣(1≢⍺ 1)decode name ns.{⍎⍺⊣⎕ED ⍺⊣⍎⍺,'←⍵'}format ⍺ ⍵
[6]
[7] ⍝ amend any(?) array
[8] ⍝ ⍵ array
[9] ⍝ ← possibly amended ⍵
[10] ⍝ see format, encode, decode, SV
[11] ⍝ Phil Last 2015-12-15
[12] }
∇
∇ blank←{
[1] ⍵,' '
[2] ⍝
[3] }
∇
∇ bracket←{
[1] SV.LB,⍵,SV.RB
[2] ⍝ bracket arg
[3] ⍝ Phil Last 2015-12-12
[4] }
∇
∇ brackets←{arg←' ',⍵
[1] q←quoted arg
[2] 1↓-∘⊃⍨-⌿+\(q(<⍤1)0 ¯1⌽SV.LB SV.RB∘.=⊢)arg
[3] ⍝ r←-∘⊃⍨-⌿+\(q(<⍤1)0 ¯1⌽SV.LB SV.RB∘.=⊢)arg
[4] ⍝ 1↓r-(SV.LB='[')∧(r>0)>1∊r/⍨q<SV.CS=arg
[5] ⍝ level of nesting of brackets - commented implements require CS if LB='['
[6] ⍝ Phil Last 2015-12-12
[7] }
∇
∇ catalog←{opt←⍵ ⋄ cat←⎕NS''
[1] 0⊣SV.{⍎⍺,'←⍵'}/##.OPTIONS.({(↓⍵),⍪1↓⍎'0',,' ',⍵}⎕NL 2.1): ⍝ copy options to SV
[2] ⍝ raw←''⍬(0 0⍴' ')(#.⎕NS'') ⍝ null str, vec, mat & ns
[3] raw←''⍬(0 0⍴' ')(⎕NS'') ⍝ null str, vec, mat & ns
[4] enc←SV.((AP,AP,' ')(,ZE)(LB CS RB)(LB CS AS RB)) ⍝ ditto
[5] cat.(key val)←cat,¨opt⌽raw enc
[6] cat⊣cat.def←SV.(LB,CS,(CI⌷CM AS),RB) ⍝ trap circle or not
[7] ⍝ rather than spending time looking for circular refs we use the memoizing default
[8] ⍝ to force a domain error by having it nested. see previous
[9] ⍝ memoising catalog
[10] ⍝ ⍺ ?
[11] ⍝ ⍵ 0 - encode - key is data and val is encoding
[12] ⍝ 1 - decode - key is encoding and val is data
[13] ⍝ ← cat with initial members of key and val for empty string, vector and space
[14] ⍝ and def being default encoding for incomplete structures.
[15] ⍝ Option CI (circular) (dflt 0) forces a DOMAIN ERROR when attempting to encode
[16] ⍝ a circular ref. Setting this to 1 encodes them as empty space '[⋄←]'
[17] ⍝ see SV reset
[18] ⍝ Phil Last 2015-12-12
[19] }
∇
∇ decode←{arg←⍵
[1] SV.DB↓0::⎕SIGNAL/⌽⎕EN,⎕DM
[2] ⍺←catalog 1⊣arg←prepare ⍵ ⍝ once
[3] cat←⍺
[4] rec←cat∘∇ ⍝ recursive
[5] cat≢res←cat previous arg:res ⍝ done?
[6] end←{cat record ⍺ ⍵}
[7] ' '∧.=arg:arg end'' ⍝ null ??
[8] lvl←brackets arg ⍝ '0[1[2]1]' → 0 1 1 2 2 2 1 1
[9] ∧/lvl=0:arg end exec⊢arg ⍝ simple executable string
[10] ∧/lvl>0:{ ⍝ multi-d array
[11] pts←~∘∊⍨((SV.CS∘≠∨quoted∨0<brackets)ml3.⊂⊢)1↓¯1↓arg
[12] ns←∨/(1=lvl)∧(SV.AS∘=>quoted)arg ⍝ or namespace
[13] ns∧←∧/{SV.AS=⊃⍵/⍨~∧\⍵∊SV.AZ}¨pts
[14] ns:arg end rec assign pts
[15] arg end↑(1/rec)eu pts ⍝ diamond delimited
[16] }arg
[17] pts←~∘∊⍨arg parts lvl ⍝ parse items
[18] pts/⍨←~pts(∧/∊)¨⊂' ',SV.CS ⍝ rem extra diamonds
[19] r←rec eu pts/⍨net←SV.LB=⊃¨pts ⍝
[20] exp←({⍕'(',⍵,'⊃⍺)'}¨⍳⍴r)am(net∘/)pts
[21] arg end r exec⍕exp ⍝ execute of composed expression
[22] ⍝ [⍺] catalog passed recursively
[23] ⍝ ⍵ encoding - see amend, encode, format, SV
[24] ⍝ ← array
[25] ⍝ Phil Last 2015-12-12
[26] }
∇
∇ desc←{1 1↓¯1↓⎕CR⊃⎕SI
[1]
[2] ⍝ contains all the code except the public functions and operator(s)
[3] ⍝ each of which has its counterpart here that does the biz.
[4] ⍝ also the scripted SV that holds the global values such as delimiters
[5] ⍝ that can be changed by setting them in ##.OPTIONS - see ##.reset
[6] ⍝ Phil Last 2016-01-08
[7]
[8] }
∇
∇ descape←{SV.DB↓0::⎕SIGNAL/⌽⎕EN,⎕DM
[1] s←⍵
[2] ~∨/e←s=SV.EE:s
[3] i←(⍳5)∘.+e/⍳⍴e ⍝ escape + 4 hex digits
[4] e[i]←~e[i] ⍝ where s → 0; where hex → 1
[5] ⍝ above is NOT redundant given ~e in last line
[6] ⍝ ⎕D, 'ABCDEF' ,⎕D, 'abcdef'
[7] s[⊣⌿i]←⎕UCS 16⊥16|'0123456789ABCDEF0123456789abcdef'⍳s[1↓i] ⍝ decode
[8] ⍵{5=⍴⍺:⍬⍴⍵ ⋄ ⍵}s/⍨~e ⍝ rem hex
[9] ⍝ ⍵ string with escape sequences
[10] ⍝ ← decoded string
[11] ⍝ Phil Last 2015-05-20
[12] }
∇
∇ diamond←{
[1] SV.CS,⍵
[2] ⍝ prefix diamond
[3] ⍝ Phil Last 2015-12-12
[4] }
∇
∇ enclose←{
[1] ⍝ (paren SV.EC,⊢)⍣(0=≢⍴⍺)⊢⍵
[2] SV.EC∘,⍣(0=≢⍴⍺)⊢⍵
[3] ⍝ prefix enclose '⊂' if scalar
[4] ⍝ Phil Last 2015-12-14
[5] }
∇
∇ encode←{SV.DB↓0::⎕SIGNAL/⌽⎕EN,⎕DM
[1] ⍺←catalog 0 ⋄ cat←⍺ ⋄ arg←⍵
[2] cat≢res←cat previous arg:res ⍝ done?
[3] end←{cat record ⍺ ⍵}
[4] 0∊⍴arg:arg end paren(⍕⍴arg),SV.RS,cat ∇⊃arg ⍝ empty
[5] n t←1 0=2 10|⎕DR arg ⍝ type
[6] ⍝ n:arg end blank arg ravel rank2code paren⍣(≡arg)⍕arg ⍝ simple
[7] n:arg end blank arg ravel rank2code paren⍣((,1)≡1<⍴arg)⍕arg ⍝ simple
[8] t:arg end blank escape⍣t⊢arg ravel rank2code quote arg ⍝ simple
[9] 0=≡arg:arg end cat∘∇ space arg ⍝ space
[10] 1=≡arg:arg end paren arg ravel arg enclose rank2code arg onecol↑,/cat ∇¨arg ⍝ mixed
[11] 1:arg end paren arg ravel arg enclose rank2code arg onecol↑,/cat ∇¨arg ⍝ nested
[12]
[13] arg end SV.(LB CS AS RB) ⍝ error
[14] ⍝ [⍺] catalog passed recursively
[15] ⍝ ⍵ array
[16] ⍝ ← encoding
[17] ⍝ see amend, decode, format, SV
[18] ⍝ Phil Last 2015-12-12
[19] }
∇
∇ escape←{
[1] ~∨/b←⍵∊SV.EE,SV.UT:⍵
[2] a w←b ⍵/¨⍨⊂1+4×b
[3] w⊣(a/w)←,SV.EE,(⎕D,⎕A)[⍉(4⍴16)⊤⎕UCS b/⍵]
[4] ⍝ ⍺ boolean untypeable ⍵
[5] ⍝ ⍵ text string
[6] ⍝ ← ⍵ with untypeable chars escaped
[7] ⍝ Phil Last 2015-05-01
[8] }
∇
∇ exec←{SV.DB↓0::⎕SIGNAL/⌽⎕EN,⎕DM
[1] ''≡str←trim ⍵:str
[2] ns←⍎SV.EX
[3] ∧/quoted str:descape ns.⍎str ⍝ external execute
[4] ns.⍎⊢descape str ⍝ ditto
[5] ⍝ ⍵ executable string maybe with escaped ctrl chars
[6] ⍝ ← evaluated before if all quoted else after replacing ctrl chars
[7] ⍝ Phil Last 2015-12-16
[8] }
∇
∇ expand←{
[1] ⍵\⍨{(¯1⌽1+⍳+/⍵)∊+\⍵}1+(quoted<SV.RB SV.LB⍷⊢)⍵
[2] ⍝ unquoted ][ → ] [
[3] ⍝ Phil Last 2015-12-16
[4] }
∇
∇ format←{⍺←⊢ ⋄ dpt←⍺⊣1 ⋄ dta←⍵
[1] SV.DB↓0::⎕SIGNAL/⌽⎕EN,⎕DM
[2] and←{⍺⍺⊣⍵:⍵⍵ ⍵ ⋄ 0}
[3] l←(1=≢∘⍴)and(4<≢)and(2=≡)and(∧/(''≡0∘/)¨)dta
[4] n←(paren SV.RV,⊢)⍣l encode⍪⍣l⊢dta
[5] q←quoted n
[6] d←q<n∊SV.(CS,RB)
[7] x←{⍵/¨⍨SV.RB=⍵}d/n
[8] b←-⌿+\q<⍤1⊢SV.(LB,RB)∘.=n
[9] r←⊃,/(x,¨⍨SV.CR↑¨⍨1+SV.IN×d/b)⊣am(d∘/)⊢n
[10] dpt=2:(1↓¨⊢⊂⍨⊢=⊃)SV.CR,r
[11] r
[12] ⍝ ⍺
[13] ⍝ 1: as CR separated string (dflt)
[14] ⍝ 2: as list of strings
[15] ⍝ ⍵ APL array
[16] ⍝ ← pretty Array Notation encoding of ⍵
[17] ⍝ see amend, encode, decode, SV
[18] ⍝ relies on redundant diamond encoded after left bracket
[19] ⍝ Phil Last 2015-12-12
[20] }
∇
∇ members←{
[1] ⍵.({⍵,⍪1↓⍎¨'0',⍵}~∘' '¨↓⎕NL 2 9) ⍝ 2.1 9.1)
[2] ⍝ ⍵ space
[3] ⍝ ← 2d members
[4] ⍝ name value
[5] ⍝ nam. valu.
[6] ⍝ ... ...
[7] }
∇
∇ onecol←{
[1] SV.EC∘,⍣(1=0⊥⍴⍺)⊢⍵
[2] ⍝ ⍺ array
[3] ⍝ ⍵ multi-d encoding
[4] ⍝ ← ensure single col enclosed
[5] ⍝ Phil Last 2015-12-12
[6] }
∇
∇ paren←{
[1] SV.LP,⍵,SV.RP
[2] ⍝ parenthesise ⍵
[3] ⍝ Phil Last 2015-12-12
[4] }
∇
∇ parts←{
[1] (⍺⊂⍨⊢≠¯1↓(~⊃),⊢)∘(0∘<)⍵
[2] ⍝ partition ⍺ by contiguous booleans in ⍵
[3] ⍝ 'ZeroOneTwoThree' part 0 0 0 0 1 1 1 0 0 0 1 1 1 1 1 → 'Zero' 'One' 'Two' 'Three'
[4] ⍝ Phil Last 2015-12-14
[5] }
∇
∇ prepare←{⍺←⊢
[1] arg←{
[2] dec←{(,⍵)/⍨,∧\(quoted∨'⍝'≠⊢)⍵}
[3] SV.CR∊⍵:⊃,/dec¨{⍵⊂⍨⍵=⊃⍵}SV.CR,⍵ ⍝ CR separated string
[4] 2=|≡⍵:⊃,/SV.CS,¨dec¨⍵ ⍝ list of strings
[5] 1=⍴⍴⍵:dec ⍵ ⍝ ⋄ separated string
[6] 2=⍴⍴⍵:dec SV.CS,⍵ ⍝ 2-D
[7] }⍵
[8] res←expand SV.CS am(((SV.CR∘=>quoted)arg)∘/)⊢arg ⍝ replace CRs
[9] res⊣(((quoted<∊∘SV.UT)res)/res)←' ' ⍝ rem funny chars
[10] ⍝ expect CR separated string, text matrix or list of strings,
[11] ⍝ any of which can be commented; or diamond separated string
[12] ⍝ whose first comment terminates the encoding.
[13] ⍝ Phil Last 2017-05-23 08.53
[14] }
∇
∇ previous←{cat←⍺ ⋄ arg←⍵
[1] cat≢res←cat.(((≢key)|key⍳⊂⍵)⊃val):res ⍝ been there, done that,
[2] cat⊣cat.(key val),←⊂¨⍵ cat.def ⍝ this is NOT the tee-shirt
[3] ⍝ ⍺ cat - see catalog
[4] ⍝ ⍵ arg which might or might not be in cat.key
[5] ⍝ ← if arg in cat.key then corresponding cat.val
[6] ⍝ else cat after adding arg and default cat.def to cat.key and cat.val
[7] ⍝ to be overwritten with the complete result when computed. see record.
[8] ⍝ The only way the default can be returned is if arg is a circular
[9] ⍝ reference whose encoding is as yet incomplete and it is designed
[10] ⍝ to cause a domain error.
[11] ⍝ Phil Last 2015-12-12
[12] }
∇
∇ quote←{
[1] SV.AP{⍺{1⌽⍵/⍨1+⍺=⍵}⍺,⍵}⍤1⊢⍵
[2] ⍝ double quotes
[3] ⍝ Phil Last 2015-12-12
[4] }
∇
∇ quoted←{
[1] (≠\∨⊢)SV.AP=⍵
[2] ⍝ is it?
[3] ⍝ Phil Last 2015-12-12
[4] }
∇
∇ rank2code←{SV.DB↓0::⎕SIGNAL/⌽⎕EN,⎕DM
[1] SV.DB<1≠≡⍵:SV.CM ⎕SIGNAL 11
[2] bracket∘{(,⌽∨\⌽⍵≠' ')/,⍵}∘diamond⍤2⍣{2>≢⍴⍺}⍣(1<≢⍴⍵)⊢⍵
[3] ⍝ ⍵ simple text array encoding of cells
[4] ⍝ ← ⍵ - bracketted and ravelled twixt diamonds if 1<⍴⍴⍵
[5] ⍝ Phil Last 2015-12-12
[6] }
∇
∇ ravel←{
[1] (paren SV.RV,⊢)⍣((,1)≡⍴⍺)⊢⍵
[2] ⍝ prefix comma if 1-item vector or string
[3] ⍝ Phil Last 2015-12-14
[4] }
∇
∇ record←{cat←⍺ ⋄ key val←⍵
[1] ⊢((cat.key⍳⊂key)⊃cat.val)←val
[2] ⍝ ⍺ cat - see catalog
[3] ⍝ ⍵ key val
[4] ⍝ ← val having overwritten cat.val where cat.key is key
[5] ⍝ key will always be recorded in cat.key where it has been placed
[6] ⍝ by previous along with val cat.def - a memoising default
[7] ⍝ Phil Last 2015-12-12
[8] }
∇
∇ reset←{⍺←⊢
[1] 'ok'⊣##.OPTIONS SV.{opts←⍺ ⋄ 'opts'⎕NS⊃∩/(⎕THIS ⍺).⎕NL-2.1}⊣startSV 1
[2] ⍝ Phil Last 2016-01-06
[3] }
∇
∇ session←{
[1] SV.DB↓0::⎕SIGNAL/⌽⎕EN,⎕DM
[2] {
[3] i←{∇⍣(z≢∊z)⊢⍵,⊂z←⍞}⊂⍞,0⍴⍞←SV.IN⍴' '
[4] '→'∊i:'bye'
[5] ∇ ⎕←format decode i
[6] }encode 0
[7] ⍝ indent, await input until blank line or '→', decode, format
[8] ⍝ Phil Last 2017-09-20 22.34
[9] }
∇
∇ startSV←{
[1] ⍵<×⎕NC'SV':0 ⍝ as is if exists and not forced
[2] hic←⎕THIS
[3] hic.io1←{⍵⊣⍵.⎕IO←1}⎕NS''
[4] hic.ml3←{⍵⊣⍵.⎕ML←3}⎕NS''
[5] hic.SB←⎕NS''
[6] hic.⎕PP←{0::⍵ ⋄ ∇ ⎕PP←1+⍵}⎕PP
[7] hic.SV←{ ⍝ else [re]-create
[8] ⍵.AP←'''' ⍝ apostrophe
[9] ⍵.AS←'←' ⍝ assignment
[10] ⍵.AZ←{⍵/⍨0≤⎕NC'_',⍪⍵}⎕UCS⍳256 ⍝ name alphabet
[11] ⍵.CI←0 ⍝ circular refs
[12] ⍵.CM←'CIRCULAR REFERENCE' ⍝ msg
[13] ⍵.CR←⎕UCS 13 ⍝ carriage return
[14] ⍵.CS←'⋄' ⍝ cell separator
[15] ⍵.DB←0 ⍝ debug ON/OFF - 1/0 - trap if OFF
[16] ⍵.DQ←'"' ⍝ doublequote
[17] ⍵.EC←'⊂' ⍝ enclose scalar or unit column
[18] ⍵.EE←'⍞' ⍝ escape
[19] ⍝ any quoted character MAY be encoded as EE,4 hex digits:
[20] ⍝ 0-9,A-F or 0-9,a-f, representing its Unicode code-point
[21] ⍵.EX←'SB' ⍝ where executa
[22] ⍵.IN←4 ⍝ depth indent (format)
[23] ⍵.LB←'[' ⍝ left bracket
[24] ⍵.LP←'(' ⍝ left paren
[25] ⍵.QN←'⎕NULL ' ⍝ disp as is not as '[NULL]'
[26] ⍵.RB←']' ⍝ right bracket
[27] ⍵.RP←')' ⍝ right paren
[28] ⍵.RS←'⍴⊂' ⍝ reshape on empty
[29] ⍵.RV←',' ⍝ ravel singleton
[30] ⍵.ZE←'⍬' ⍝ empty vector (zilde)
[31] ⍵.UT←⎕UCS(⍳32),133 160 ⍝ untypeable
[32] ⍝ ⍵.UT←⎕UCS 0 2 8 9 10 13 28 29 30 31 133 160 ⍝ non-printing
[33] ⍝ all these untypeables WILL be encoded with EE as above '⍞0000' - '⍞00A0'
[34] ⍵
[35] }⎕NS''
[36] 0
[37] ⍝ session variable space
[38] ⍝ ⍵ force new
[39] ⍝ ← 0
[40] ⍝ Phil Last 2017-02-16 19.24
[41] }
∇
∇ trim←{
[1] {(+/∧\⍵∊' ',SV.CS)↓⍵}∘⌽⍣2⊢⍵
[2] ⍝ rem pre and post blanks and diamonds
[3] ⍝ Phil Last 2015-12-12
[4] }
∇
Operators:
∇ am←{⍺←⊢
[1] W⊣W[i]←⍺ ⍺⍺⊣W[i←(⊂⍴W)|⍵⍵⊣⍳⍴W←⍵]
[2] ⍝ amend - [⍺](mod amend sel)⍵
[3] ⍝ [⍺] larg to ⍺⍺
[4] ⍝ ⍺⍺ modifier of selection of ⍵ or replacement thereof
[5] ⍝ ⍵⍵ selection function on ⍳⍴⍵ or selection thereof
[6] ⍝ ⍵ data to be amended
[7] ⍝ Phil Last 2015-12-12
[8] }
∇
∇ assign←{SV.DB↓0::⎕SIGNAL/⌽⎕EN,⎕DM
[1] rec←⍺⍺ ⋄ arg←⍵
[2] ns←(⍎SV.EX).⎕NS''
[3] as←arg⍳¨SV.AS
[4] nam←as↑¨arg
[5] nam as arg/⍨←⊂~nam∊∊nam
[6] val←rec¨(1+as)↓¨arg
[7] ns⊣ns.{⍎⍺,'←⍵'}/nam,⍪val
[8] ⍝ ⍺⍺ cat decode
[9] ⍝ ⍵ pairs - 'name←val'
[10] ⍝ ← ns
[11] }
∇
∇ eu←{SV.DB↓0::⎕SIGNAL/⌽⎕EN,⎕DM
[1] (⊂u⍳⍵)⌷⍺⍺¨u←∪,⍵
[2] ⍵ ⍺⍺¨{(⊂⍵⍳⍺)⌷⍺⍺ ⍵}∪⍵
[3] ⍝ each unique
[4] ⍝ ⍺⍺ fn to run on each item of ⍵
[5] ⍝ ⍵ array in domain of ⍺⍺¨
[6] ⍝ ← equivalent of ⍺⍺¨⍵
[7] ⍝ but having run ⍺⍺ on only a single
[8] ⍝ instance of each unique value of ⍵
[9] ⍝ Phil Last 2015-12-15
[10] }
∇
∇ member←{SV.DB↓0::⎕SIGNAL/⌽⎕EN,⎕DM
[1] ⍺←⊢
[2] ⍺,SV.AS,⍺⍺ ⍵
[3] ⍝ ⍺ name
[4] ⍝ ⍺⍺ cat∘encode
[5] ⍝ ⍵ value
[6] ⍝ ← encoding
[7] }
∇
∇ space←{SV.DB↓0::⎕SIGNAL/⌽⎕EN,⎕DM
[1] ⎕NULL=arg←⍵:SV.QN
[2] 0∊⍴mem←members arg:SV.(LB CS AS RB) ⍝ SV.LB SV.CS SV.AS LB.RB
[3] rank2code↑⍺⍺ member/mem
[4] ⍝ ⍺⍺ encode
[5] ⍝ ⍵ space or ⎕NULL
[6] ⍝ ← 2d members
[7] ⍝ name value
[8] ⍝ nam. valu.
[9] ⍝ ... ...
[10] ⍝ Phil Last 2017-02-16 19.24
[11] }
∇
∇ value←{⍺←⊢
[1] decode,SV.CR,1↓¯1↓⎕CR(f←⍺⍺)/'f'
[2] ⍝ ⍺⍺ dfn with embedded encoding
[3] ⍝ ← decode value
[4] ⍝ Phil Last 2015-12-16
[5] }
∇
Variables:
Rank: 1; Shape: 183; Depth: 2; Data Representation: 326
Functions:
∇ desc←{1 1↓¯1↓⎕CR⊃⎕SI
[1]
[2] ⍝ You may put certain named values in this ns to override the defaults:
[3] ⍝ DB debug zero traps, one does not default: zero
[4] ⍝ CI circular refs zero throws error, one substitutes an empty ref default: zero
[5] ⍝ EX execute space FQN of space wherein to evaluate expressions default: '#'
[6] ⍝ IN indent rank offset for format default: 2
[7] ⍝ Use: ... ##.reset 0 ⍝ to return all values to their defaults.
[8] ⍝ Phil Last 2016-01-06
[9] }
∇
Functions:
∇ ad2dt←{
[1] d←⍉(dt2ts ⍵)+∘(7∘↑)⍤1⊢⍺
[2] m d←1 0+(0 12)(0 24 60 60 1000)(⊣⊤⊥)¨(¯1+2↑d)(2↓d)
[3] (1 0 0 0 0⌿d)+←d2s⍉m⍪0
[4] ts2dt(s2d⊣⌿d),⍉1↓d
[5] ⍝ ⍺ period(s) - y m d h m s m - vector or matrix - any may be +/-
[6] ⍝ ⍵ date.time(s) - yyyymmdd.hhmmssmmm - scalar or vector
[7] ⍝ ⍺ conforms ⍤ 1 0 ⊢ ⍵
[8] ⍝ i.e. each vector in ⍺ corresponds to each element in ⍵
[9] ⍝ ← date.time ← period ∇ date.time
[10] ⍝ Phil Last 2015-11-13
[11] }
∇
∇ d2s←{⎕IO←⎕ML←0 ⍝ origin 0 on 0001-01-01
[1] y m d←↓⍉↑,↓⍵ ⍝ separate years months & days
[2] Y←{(⍵×365)+(⌊⍵÷4)-(⌊⍵÷100)-⌊⍵÷400}y-1 ⍝ days for full years
[3] M←(+\0 0 31 28,10⍴5⍴31 30)[m] ⍝ days to previous month end
[4] M←M+(m>2)∧(0=4|y)>(0=100|y)>(0=400|y) ⍝ + leap day after Feb
[5] (⍵∨.≠0)×Y+M+d ⍝ total proleptic gregorian days
[6] ⍝ ⍵ yyyy mm dd - 3 cols
[7] ⍝ ← dddd - rank 1
[8] ⍝ aka "Gregorian Serial Date"
[9] }
∇
∇ dd2dt←{
[1] ts2dt dd2ts ⍵
[2] ⍝ ⍵ days.decs - ddddd.dddddd - shape any
[3] ⍝ ← date.time - yyyymmdd.hhmmssmmm - shape ⍴⍵
[4] }
∇
∇ dd2ts←{
[1] dhm←24 60 60 1000
[2] (s2d⌊⍵),⍉dhm⊤⍉⌊0.5+(1|⍵)××/dhm
[3] ⍝ ⍵ days.decs ddddd.dddddd - shape any
[4] ⍝ ← timestamp yyyy mm dd hh mm ss mmm - shape (⍴⍵),7
[5] ⍝ try (dt2fm∘ts2dt∘dd2ts)(24÷⍨6+2.2×1○2×○(92⌽⍳366)÷366)+(39436+⍳366)
[6] ⍝ Phil Last ⍝ 2008-02-11 08:38
[7] }
∇
∇ dt2dd←{
[1] ts2dd dt2ts ⍵
[2] ⍝ ⍵ date.time - yyyymmdd.hhmmssmmm - shape any
[3] ⍝ ← days.decs - ddddd.dddddd - shape ⍴⍵
[4] }
∇
∇ dt2dt←{dhm←24 60 60 1000
[1] ts2dt dd2ts(ts2dd dt2ts ⍺)+⊃+/{
[2] (×/dhm)÷⍨dhm⊥(3 1/10*2 3)⊤⌊0.5+⍵×10*9
[3] }\⊂[1+⍳⍴⍴⍵]0 1⊤⍵
[4] ⍝ ⍺ date.time - yyyymmdd.hhmmssmmm
[5] ⍝ ⍵ +/-days.time - dd.hhmmssmmm
[6] ⍝ ← date.time ⍺+⍵
[7] ⍝ Phil Last ⍝ 2008-02-21 09:43
[8] }
∇
∇ dt2fm←{⎕CT←0 ⍝ don't let ⌊ round UP
[1] ((⍴⍵),19)⍴'O<>G<9999-99-99 99:99:99>'⎕FMT⌊,⍵×10*6
[2] ⍝ ((⍴⍵),19)⍴'K6G<9999-99-99 99:99:99>'⎕FMT,⍵
[3] ⍝ above gives 2008-02-19 08:11:60 for 20080219.081159910
[4] ⍝ ⍵ date.time yyyymmdd.hhmmssmmm - shape any
[5] ⍝ ← chararray 'yyyy-mm-dd hh:mm:ss' - shape (⍴⍵),19
[6] ⍝ Phil Last ⍝ 2008-02-21 09:38
[7] }
∇
∇ dt2mm←{
[1] 0 12⊥0 100⊤⌊⍵÷100
[2] ⍝ ⍵ date.time - shape any
[3] ⍝ ← months - shape ⍴⍵
[4] ⍝ origin is 1 Jan 1 bce (for what it's worth)
[5] ⍝ Phil Last ⍝ 2008-02-22 16:41
[6] }
∇
∇ dt2ts←{
[1] ⍉⌊(0,5 1/10*2 3)⊤⍉⍵×10*9
[2] ⍝ ⍵ date.time - yyyymmdd.hhmmssmmm - shape any
[3] ⍝ ← timestamp - yyyy mm dd hh mm ss mmm - shape (⍴⍵),7
[4] ⍝ Phil Last ⍝ 2008-02-20 22:49
[5] }
∇
∇ dt2wd←{
[1] d←7|¯1+s←d2s⍉↑y m d←↓0 100 100⊤,⌊⍵
[2] n←s-(⊂u⍳y)⌷d2s(u←∪y),⍤0 1⊢1 1
[3] w←⌊(10+n-d)÷7
[4] 0 1 0 1+⍤1⊢y,n,w,⍪d
[5]
[6] ⍝ l t←↓⍉(⊂u⍳y)⌷{(0=4|⍵)>(0=100|⍵)>0=400|⍵}u∘.-1 0 ⍝ leap last and this
[7]
[8] ⍝ ⍵ date/datetime yyyymmdd treated as vector
[9] ⍝ ← year yearday weekno weekday (4 cols)
[10] ⍝ yearday: 1 Jan ←→ 1
[11] ⍝ weekno, weekday: ISO - week 1 includes 4 Jan and Mon is day 1
[12] ⍝ - except -
[13] ⍝ weekno is 0 to 53 where 0 SHOULD be last week of previous year
[14] ⍝ (52 or 53) and year-1;
[15] ⍝ and 53 MIGHT be first of next and year+1
[16] }
∇
∇ fd2ts←{
[1] s←719163 ⍝ days before 1970 1 1 - ts2dd 1970 1 1
[2] d←5184000 ⍝ 60th secs per day - ×/24 60 60 60
[3] dd2ts s+⍵÷d ⍝ inv → d×s-⍨ts2dd ⍵
[4] ⍝ filedate to timestamp
[5] ⍝ ⍵ filedate - ⊢/⎕FRDCI - 60th secs since 1970-01-01 00.00
[6] ⍝ ← timestamp - shape as (⍴⍵),7
[7] ⍝ Phil Last 2017-10-31 07.57
[8] }
∇
∇ fm2dt←{
[1] (¯1↓⍴⍵)⍴{⍵÷10*¯7+⌊10⍟⍵+⍵=0}1⊃⎕VFI⊃,/,' 0'∘,¨~∘' -:/.'¨↓⍵
[2]
[3] ⍝ ⍵ formatted array 'yyyy mm dd [hh[mm[ss]]]' - rank>0
[4] ⍝ permitted separators '-/ :.' first eight digits are yyyymmdd
[5] ⍝ ← date.time yyyymmdd.hhmmss - shape ¯1↓⍴⍵
[6] ⍝ for dates twixt 1 Jan 1000 and 31 Dec 9999
[7] ⍝ Phil 2018-06-21 09.27
[8] }
∇
∇ mm2dt←{
[1] 101+100×100⊥0 12⊤⍵-1
[2] ⍝ ⍵ months - shape any
[3] ⍝ ← date.time - shape ⍴⍵
[4] ⍝ Phil Last ⍝ 2008-02-25 11:23
[5] }
∇
∇ s2d←{⎕IO←⎕ML←0 ⍝ origin 1 on 0001-01-01
[1] d←,⍵-1 ⍝ proleptic gregorian days
[2] q c o y←0 ⍝ local
[3] q d∘←↓0 146097⊤d ⍝ quadricentennium - 400 100 4 1+.×365 1 ¯1 1
[4] c d∘←↓0 36524⊤d ⍝ century - 100 25 1+.×365 1 ¯1
[5] s←c=4 ⍝ end of quadricentennium
[6] o d∘←↓0 1461⊤d ⍝ quadrennium - 4 1+.×365 1
[7] y d∘←↓0 365⊤d ⍝ year & day
[8] s∨←y=4 ⍝ end of quadrennium
[9] y d+←1+¯1 365×⊂s ⍝ end of century/quadricentennium
[10] y∘←↑q c o y+.×400 100 4 1 ⍝ total years
[11] l←=⌿0=4 100 400∘.|y ⍝ leap year
[12] m←(1 31 29,10⍴5⍴31 30)/⍳13 ⍝ a year of months
[13] d+←l<d>59 ⍝ skip 29 Feb for non leap-year
[14] m∘←m[d] ⍝ month
[15] n←+\0 0 31 29,10⍴5⍴31 30 ⍝ days to previous month end
[16] d-←n[m] ⍝ remainder
[17] ((⍴⍵),3)⍴⍉↑(⊂0≠⍵)×y m d ⍝ yyyy mm dd - 2d
[18] }
∇
∇ ts2dd←{
[1] dhm←24 60 60 1000
[2] (¯1↓⍴⍵)⍴⊃{(d2s ⍺)+(⍉dhm⊥⍉⍵)÷×/dhm}/1 0 0 1 0 0 0⊂7↑⍤1⊢⍵
[3] ⍝ ⍵ timestamp yyyy mm dd [hh [mm [ss [mmm]]]] - rank ≥1
[4] ⍝ ← days.decs ddddd.dddddd - shape ¯1↓⍴⍵
[5] ⍝ 1899-12-31 00:00 → 0 - a year and a day before the end of the 19th century!
[6] ⍝ Phil Last ⍝ 2008-02-18 15:24
[7] }
∇
∇ ts2dt←{⍝ inv - dt2ts
[1] ⍉1E¯9×(0,5 1/10*2 3)⊥⍉7↑⍤1⊢⍵
[2] ⍝ ⍵ timestamp - yyyy mm dd [hh [mm [ss [mmm]]]] - rank ≥1
[3] ⍝ ← date.time - yyyymmdd.hhmmssmmm - shape ¯1↓⍴⍵
[4] ⍝ Phil Last ⍝ 2008-02-20 22:38
[5] }
∇
Functions:
∇ r←BS
[1] r←⎕UCS 8 ⍝ back space
∇
∇ r←CR
[1] r←⎕UCS 13 ⍝ carriage return
∇
∇ r←HT
[1] r←⎕UCS 9 ⍝ horizonal tab
∇
∇ Ia←{⍺←⊢
[1] (⎕A,¨1↓¨⊢)ia''
[2] ⍝ ICAO (International Civil Aviation Organization) Alphabet
[3] }
∇
∇ r←LF
[1] r←⎕UCS 10 ⍝ line feed
∇
∇ r←NB
[1] r←⎕UCS 160 ⍝ non-breaking space
∇
∇ r←NL
[1] r←⎕UCS 133 ⍝ next line
∇
∇ r←TC ⍝ terminal control?
[1] r←HT LF CR NL
∇
∇ r←_Desc
[1] r←2 2↓⎕CR⊃⎕SI
[2] ⍝ UT
[3] ⍝
[4] ⍝ This ns contains the (fairly) definitive editions of a number of the most
[5] ⍝ useful or demonstrative functions and operators I've written plus a number
[6] ⍝ of things added which may be more specific to the workspace in which it
[7] ⍝ currently resides.
[8] ⍝
[9] ⍝ I didn't originate them all.
[10] ⍝
[11] ⍝ Though I hope at least some of them are better than an original I might have
[12] ⍝ found.
[13] ⍝
[14] ⍝ Some don't actually get used much if at all but I'll often cut and paste
[15] ⍝ algorithms into application code.
[16] ⍝
[17] ⍝ Not all of them are necessarily the fasted way of doing whatever has to be done
[18] ⍝ but if not I hope elegance or clarity might make up for it.
[19] ⍝
[20] ⍝ To avoid unneccessarily many assignments the functions and operators in this ns
[21] ⍝ are either written to be origin and/or APL2 compatibility independent or assume
[22] ⍝ ⎕IO←0 and ⎕ML←0
∇
∇ aa←{⍺←⊢
[1] ⍵{⊣/⍵⌽'&',⍪⍵\⍺}{(1+⍳⌈/⍵)∊⍵}+\1+<\~(1 cc ⍵)∊1 cc{⍵/⍨¯1⌽⍵='&'}⊃,/⍺
[2] ⍝ ⍺ extant captions
[3] ⍝ ⍵ new caption
[4] ⍝ ← new caption with (or without) &
[5] ⍝ add accelerator ampersand to new caption ⍵ given extant captions ⍺
[6] }
∇
∇ ab←{
[1] ~∘' '~∘⍵{⍵/⍨0≤⎕NC'_',,[⍬]⍵}⎕UCS⍳256
[2] ⍝ alphabet (inc. ⎕D)
[3] ⍝ ⍵ string
[4] ⍝ ← legal name elements without ⍵
[5] }
∇
∇ af←{
[1] ⍺{(⎕NUNTIE ⍵)⊢⍺ ⎕NAPPEND ⍵,⎕DR ⍺}{
[2] 22::⍵ ⎕NTIE 0
[3] ⍵ ⎕NCREATE 0
[4] }⍵
[5] ⍝ append file
[6] ⍝ ⍺ data in form it can be written as-is - char or num vec
[7] ⍝ ⍵ file path/name if not exists is created first
[8] ⍝ ← bytes written
[9] ⍝ Phil Last ⍝ 2011-09-12 12:00
[10] }
∇
∇ al←{
[1] ⍺←2 ⋄ on off←⍺
[2] len←⊃⍴/⍴txt←⎕FMT↑⍵ ⍝ this
[3] code rem←⊂[1+⍳2](∨\(txt⍷⍨on 1/' ⍝')>≠\txt='''')⊖↑txt' ' ⍝ not this
[4] (msk/len)←{0⌈⌈/+/∨\⌽' '∨.≠⍵}code⌿⍨msk←rem∨.≠' '
[5] rem←⊃,/(off⍴' '),⊂rem⌽⍨+/∧\rem=' ' ⍝ this
[6] {⍵/⍨⌽∨\⌽' '∨.≠⍵}↑(len↑¨↓code),¨↓rem
[7] ⍝ align
[8] ⍝ ⍺ on off - (minimum blanks to adjust),(minimum offset for alignment)
[9] ⍝ ⍵ text array - presumed to be a ⎕cr
[10] ⍝ ← (⍵) with aligned comments
[11] ⍝ Phil Last ⍝ 2008-09-10 08:26
[12] }
∇
∇ an←{
[1] ↑∪↓{
[2] (2=⍴⍵):2 2⍴⍵,⌽⍵
[3] ⊃⍪/⍵,∘∇¨↓{
[4] ⍵⍴⍨0 ¯1+⍴⍵
[5] }⌽⍵
[6] }⍵
[7] ⍝ anagrams
[8] ⍝ ⍵ string
[9] ⍝ ← anagrams
[10] ⍝ Phil Last ⍝ 2008-01-28 19:02
[11] }
∇
∇ ar←{
[1] req←~∘∊⍨' 'sl⍕⍺
[2] 22::0 ⍝ missing file
[3] tie←⍵ ⎕FSTIE 0
[4] dct←⎕FREAD tie,1
[5] 0∊⍴req:dct⊣⎕FUNTIE tie
[6] cmp←2+dct⍳nms←(⍺≡'*')⊃req dct
[7] 0∊⍴cmp:⎕NS''⊣⎕FUNTIE tie
[8] 20::⎕SIGNAL/⌽⎕EN,⎕DM⊣⎕FUNTIE tie ⍝ file index error
[9] (⎕FUNTIE tie)⊢dx nms{⍺ ⍵}⎕FREAD tie cmp
[10] ⍝ associative file read - see also aw
[11] ⍝ ⍺ required names | '*' for all | '' for names
[12] ⍝ ⍵ filename - component 1 is names. following are the associated values.
[13] ⍝ ← dictionary with named vars | 0∊⍴⍺: names | file missing: 0
[14] }
∇
∇ aw←{
[1] dict←⍺
[2] file←⍵
[3] data←dict.({(⊂⍵),1↓⍎¨'0',⍵}⎕NL-2)
[4] (old new)←{file,⍵,,'K-6F15.6'⎕FMT 100⊥6⍴⎕TS}¨'.OLD.' '.NEW.'
[5] newt←{⍵⊣⍺ ⎕FAPPEND ⍵}/(⌽data),new ⎕FCREATE 0
[6] ok←×oldt←{22::0 ⋄ old ⎕FRENAME file ⎕FTIE 0}0
[7] newt←⎕FUNTIE file ⎕FRENAME newt ⍝ ok!
[8] oldt←old∘⎕FERASE⍣ok⊢oldt
[9] file
[10] ⍝ associative file write - see also ar
[11] ⍝ ⍺ Dictionary - named vars that become the entire contents of new file.
[12] ⍝ ⍵ Filename - original safely renamed if extant and removed afterwards.
[13] ⍝ ← ⍵
[14] ⍝ Component one is names. Following are the associated values each in the
[15] ⍝ component numbered two more than the index of its name in component one
[16] ⍝ Temp filenames are original with 'OLD', or 'NEW', and the current time.
[17] ⍝ as: original.ext.OLD.20120322.113716; original.ext.NEW.20120322.113716.
[18] }
∇
∇ ay←{⍺←⊢
[1] drop←{⍵/⍨∨\' '∨.≠⍵}
[2] p3←({⍵⊣⍵.⎕ML←3}⎕NS'').⊂
[3] words←{(' '≠⍵)p3 ⍵}
[4] ctl←⊣/src←drop(0,⍴,⍵)↓⍵{⍵⌿⍨>/⍺⍷⍵}⎕CR 1⊃⎕XSI
[5] dat←{(+/∨\' '≠⌽⍵)↑¨↓⍵}drop 0 1↓src⌿⍨ctl←ctl=type←⊃ctl~' '
[6] ctl/⍨←(∨\ctl)∧⌽∨\⌽ctl
[7] (ctl dat)←⊃{d←⍺ p3 ⍺\⍵
[8] c←{⍵/⍨~0 1⍷⍵}⍺/⍨~1 1⍷⍺
[9] ⊃∘(∇/)⍣(0∊c)⊢c d
[10] }/ctl dat
[11] type='d':dat ⍝ text depth vs rank
[12] dat←{⍵⍴⍨(⍴⍵)↓⍨+/∧\1=⍴⍵}↑⍣(≡dat)⊢dat ⍝ convert depth to rank
[13] type='t':dat ⍝ text
[14] type='n':↑1∘⊃∘⎕VFI¨↓dat ⍝ numeric
[15] type='x':mx(⍺⊣#).⍎¨↓dat ⍝ executable
[16] type='w':~∘' '¨↑words¨↓dat ⍝ words
[17] type='m':⊃(~∘' '¨↑words¨↓dat){(⍴⍺)⍴⍺⊖↑⍺⍺ ⍵}/⊂rk ¯1↑⍉↑⍉⎕VFI¨↓dat
[18] 1:dat ⍝ ↑ mixed words and numbers
[19] ⍝ ⍺ space (dflt #) in which 'x' type source expressions are executed
[20] ⍝ ⍵ substring to identify source rows to use in caller.
[21] ⍝ source rows not preceded by first type char are rank indicators -
[22] ⍝ - as inserted blank rows in default output.
[23] ⍝ ← array represented by selected source rows in caller.
[24] }
∇
∇ b64←{
[1] ⍝ A←⎕A,(⎕UCS(⍳26)+⎕UCS'a'),⎕D,'+/' ⍝ alphabet
[2] A←'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
[3] ⍺←~∧/⍵∊A,'='
[4] ed←{⊃⍵{⍺{2⊥⍉((⌈(⍴⍵)÷⍺),⍺){⍺⍴(×/⍺)↑⍵}⍵},⍉(⍵⍴2)⊤⍺⍺}/⍺} ⍝ encode decode
[5] ⍺:{⍵,'='⍴⍨4|-⍴⍵}(⊂6 8 ed ⎕UCS ⍵)⌷A ⍝ encode strict /
[6] ⍺:(⊂6 8 ed ⎕UCS ⍵)⌷A ⍝ encode lax x
[7] 1:⎕UCS{x↓8 6 ed A⍳⍵,'='↑⍨x←-4|-⍴⍵}⍵∩A ⍝ decode lax /
[8] 1:⎕UCS{(-+/'='=¯3↑⍵)↓8 6 ed A⍳⍵}⍵∩A,'=' ⍝ decode strict x
[9] ⍝ base64 encoding
[10] ⍝ ⍺ 1=encode; 0=decode
[11] ⍝ ⍵ byte string: 256∧.>⎕ucs ⍵
[12] ⍝ ← ⍺=1: longer (4:3) string in A-Z,a-z,0-9,+/= only
[13] ⍝ ⍺=0: original string whence ⍵ was encoded
[14] ⍝ whitespace in (⍵) is ignored on decode
[15] }
∇
∇ bc←{
[1] ⍵/⍨⌽∨\⌽' '∨.≠⍵
[2] ⍝ blank column removal
[3] ⍝ ⍵ 2d text array
[4] ⍝ ← (⍵) without trailing blank columns
[5] ⍝ Phil Last ⍝ 2008-01-24 18:00
[6] }
∇
∇ bf←{⍺←⊢
[1] r←⎕FMT↑⍵
[2] b←r∊⍺⊣'.'
[3] m←⍉4⊥⍉2⊥↑↑(3,/0,b,0)(3,⌿0⍪b⍪0)
[4] c←'│ ─ ┌ │ │ └ ├ ─ ┐ ─ ┬ ┘ ┤ ┴ ┼ .'~' '
[5] n←13 14 15 28 29 30 31 44 45 46 47 60 61 62 63
[6] (⍴r)⍴(m∊n)⊖(2,⍴r)⍴r⍪(⊂n⍳m)⌷c
[7] ⍝ box frame
[8] ⍝ [⍺] char(s) to be replaced - dflt '.'
[9] ⍝ ⍵ char array
[10] ⍝ ← array with ⍺ replaced by boxing chars
[11] ⍝ ┌───┬───┬───┬───┬───┬───┬───┬───┐ ┌───┬───┬───┬───┬───┬───┬───┬───┐
[12] ⍝ │ │ ∘ │ │ ∘ │ │ ∘ │ │ ∘ │ │ │ │ │ │ │ │ │ │ │ │ │ │
[13] ⍝ │ ∘ │ ∘ │ ∘∘│ ∘∘│ ∘ │ ∘ │ ∘∘│ ∘∘│ │ ∘ │ │ │ ──│ └─│ │ │ │ │ ┌─│ ├─│
[14] ⍝ │ │ │ │ │ ∘ │ ∘ │ ∘ │ ∘ │ │ │ │ │ │ │ │ │ │ │ │ │ │
[15] ⍝ ├───┼───┼───┼───┼───┼───┼───┼───┤ ├───┼───┼───┼───┼───┼───┼───┼───┤
[16] ⍝ │ │ ∘ │ │ ∘ │ │ ∘ │ │ ∘ │ │ │ │ │ │ │ │ │ │ │ │ │ │
[17] ⍝ │∘∘ │∘∘ │∘∘∘│∘∘∘│∘∘ │∘∘ │∘∘∘│∘∘∘│ │── │─┘ │───│─┴─│─┐ │─┤ │─┬─│─┼─│
[18] ⍝ │ │ │ │ │ ∘ │ ∘ │ ∘ │ ∘ │ │ │ │ │ │ │ │ │ │ │ │ │ │
[19] ⍝ └───┴───┴───┴───┴───┴───┴───┴───┘ └───┴───┴───┴───┴───┴───┴───┴───┘
[20] ⍝ Phil Last 2016-02-12
[21] }
∇
∇ bs←{⍺←⊢
[1] 1↓{
[2] scr←(⊂''),{11 16::js ⍵ ⋄ ⎕SRC ⍵}⍵
[3] (¯1↓scr),(' '∘,¨⊃,/(⊂''),∇ ea ⍵{⍵/⍨⍺={⍵.##}ea ⍵}{⍵/⍨~'['∊∘⍕¨⍵}⍵.⍎ea↓⍵.⎕NL 9.1 9.4),⊢/scr
[4] }⍵
[5] ⍝ build script from space ⍵
[6] ⍝ see js
[7] }
∇
∇ bx←{
[1] ⍺←⊢
[2] (3 3⍴⍺⊃'.-.| |''-''' '┌─┐│ │└─┘'){
[3] (' ',' '⍪⍵){(⍴⍵)⍴(⍵≠' ')⊖↑⍺ ⍵}⊃⍺{1 ⍺ 1⌿1 ⍵ 1/⍺⍺}/⍴⍵
[4] }⎕FMT ⍵
[5] ⍝ box
[6] ⍝ Phil Last ⍝ 2008-01-23 13:35
[7] }
∇
∇ by←{
[1] ⍺←#
[2] ⍵{⍵/⍨∨/⍺⍷⍕⎕AT ⍵}⍺ li 3.1 3.2 4.1 4.2
[3] ⍝ saved by
[4] ⍝ ⍺ space
[5] ⍝ ⍵ potential "Last saved by:" (⎕AN)
[6] ⍝ ← fns ops in or below ⍺ last saved by ⍵
[7] ⍝ Phil Last ⍝ 2008-01-10 09:41
[8] }
∇
∇ c2←{
[1] c2←{
[2] ¯1↓¨2⍴⊃{
[3] l r m←⍵
[4] ((⍴m)<x←1+m⍳⍺):(l,1)(r,0)m
[5] (l,1↑⍨-x)(r,x⍴1)(x↓m)
[6] }/(⊂¨⌽⍺,⊂⍺ ⍵),⊂⍬ ⍬(⍵,⊂⍺ ⍵)
[7] }
[8] ⍺←⊢
[9] ⊃{(⍺ c2 ⍵){⍺ ⍵⊃⍨(⍴⊃⍺)>⍴⊃⍵}⌽(⍵ c2 ⍺)}/⍺ ⍵
[10] ⍝ compare two lists
[11] ⍝ ⍺ list presumed to be related to ⍵
[12] ⍝ ⍵ list presumed to be related to ⍺
[13] ⍝ [monad: ⍵ is two lists]
[14] ⍝ ← two expansion lists to accomodate mis-matches
[15] ⍝ Phil Last ⍝ 2008-07-17 21:28
[16] }
∇
∇ c3←{
[1] c3←{
[2] a b c←⍵
[3] xa xb←a c2 b
[4] xxa xc←(xa\a)c2 c
[5] (xxa\xa)(xxa\xb)(xc)
[6] }
[7] ⊃⍨∘(⍳∘(⌊/)⍨)∘(⊃∘⍴∘⊃¨)⍨⍵∘{⌽⍵⌽⌽c3 ⍵⌽⍺}¨⍳⍴⍵
[8] ⍝ compare three lists
[9] ⍝ ⍵ three lists presumed to be related
[10] ⍝ ← three expansion lists to accomodate mis-matches
[11] ⍝ Phil Last 2008-09-22 14:09
[12] }
∇
∇ ca←{
[1] q←''''∘{⍺,⍺,⍨⍵/⍨1+⍵=⍺}
[2] if←{⍺⍺⍣(⍵⍵⊣⍵)⊢⍵}
[3] v←⍎n←⍵
[4] (⊂⍕n'←⍬'),(↓⍕(⊂n,',←'),q if(≡∘⍕⍨)¨v),⊂⍕n'⍴⍨←'(⍴v)
[5] ⍝ create array -
[6] ⍝ ⍵ fully-qualified name of array
[7] ⍝ array mixed array (depth +/-2) of scalar numerics and text scalars or strings
[8] ⍝ ← executable expressions to reconstitute array
[9] }
∇
∇ cb←{
[1] {(⍵[0;⍵[1;]≠'|'])⍪1 0↓⍵}∘⊖⍣2 bx{
[2] ⍵/⍨2∨/1,' '∨.≠⍵
[3] }0 2↓⍕↓↑↑{⍵⊂⍨⍵='|'}¨↓⍪↑⍵
[4] ⍝ column box
[5] }
∇
∇ cc←cc
[1] cc←819⌶
[2] ⍝ convert case
[3] ⍝ Phil Last 2017-12-18 10.03
∇
∇ cg←{
[1] ⍺←# dx'⎕io ⎕ml'(⎕IO ⎕ML)
[2] res←⍺
[3] (0∊⍴txt←cu∘((⎕DR'')∘rf)⍣(~CR∊⍵),⍵):res
[4] txt←txt re fl{('\',⍵)''}¨(CR,LF)CR LF
[5] txt←{(+/∧\' '=⍵)⌽⍵}{⍵⌿⍨⍵∨.≠' '}⎕FMT txt~HT
[6] txt←↓⊣⌿(∧\txt≠'=')⊖txt,[-0.1]cc txt
[7] nms←(/⍨∘(∧\)∘(≠∘']'))⍨∘(1∘↓)¨txt/⍨msk←'['=⊃¨txt
[8] txt←msk⊂txt
[9] ~∨/msk←0≤⎕NC↑nms:res
[10] nms txt/⍨←⊂msk
[11] nss←res.{⍎⍵,'←⎕ns⍬'}¨nms
[12] z←nss.{{q←'''"'
[13] (≥/i j←+/∧\~(≠\⍵∊q)<[1]'=;'∘.=⍵):⍵ ⍝ unquoted ';' before '='
[14] (0>⎕NC i↑⍵):⍵
[15] (i↑⍵){⍺{⍎⍺,'←⍵'}{ ⍝ key←value
[16] (>/1 0∊0⊃v f←⎕VFI ⍵):⍴∘f~∘1⍴f ⍝ look like a duck?
[17] {⍵~q∩⊃⍵}⍵/⍨{(∨\⍵)∧⌽∨\⌽⍵}⍵≠' ' ⍝ trim and unquote
[18] }⍵
[19] }(1+i)↓j↑⍵
[20] }¨⍵}txt
[21] 0∊⍴cpy←nss/⍨2.1=nss.⎕NC⊂⊂'copysection':res ⍝ requiring copies
[22] cpy.copysection←cc cpy.(copysection~'#.[]') ⍝ minuscule
[23] 0∊⍴cpy←cpy/⍨9.1=res.⎕NC cpy.copysection:res ⍝ requiring extant copies
[24] cpy←cpy ms∘res.⍎¨cpy.copysection ⍝ merge
[25] res
[26] ⍝ config
[27] ⍝ ⍵ ini file path\name
[28] ⍝ ← namespace
[29] ⍝ ini sections as subnss (with minuscule names)
[30] ⍝ keys as vars (ditto)
[31] ⍝ values as text or numeric strings or scalars
[32] ⍝ Phil Last ⍝ 2008-06-02 11:30
[33] }
∇
∇ ch←{
[1] 9≠⎕NC ⍺:{⍵
[2] }z,(#.⍎¯1↓z←⍺/⍨⌽∨\⌽⍺='.').⎕FX 1↓¨{⍵⊂⍨⍵=⊃⍵}re∘⍵⊃,/CR,¨⎕NR ⍺
[3] ⊢z,(#.⍎¯1↓z←⍺/⍨⌽∨\⌽⍺='.').⎕FIX 1↓¨{⍵⊂⍨⍵=⊃⍵}re∘⍵⊃,/CR,¨⎕SRC⍎⍺
[4] ⍝ change in defined operation
[5] ⍝ ⍺ fully-qualified-fnname/opname/clsname
[6] ⍝ ⍵ oldstring newstring
[7] ⍝ ← result of in.situ.⎕FX on changed ⎕VR of function
[8] ⍝ Phil Last ⍝ 2008-03-17 10:55
[9] }
∇
∇ cl←{
[1] ⍺←⌈/⍵
[2] ⍵=⍺{⍵+⍺×⍺⍺≥⍺+⍵}as ⍵
[3] ⍝ clump
[4] ⍝ ⍺ desired maximum clump
[5] ⍝ ⍵ sizes
[6] ⍝ ← leading boolean partition mask such that
[7] ⍝ ⎕ML←0 ⋄ (⍺ cl ⍵)⊂⍵
[8] ⍝ or
[9] ⍝ ⎕ML←3 ⋄ (+\⍺ cl ⍵)⊂⍵
[10] ⍝ gives the largest contiguous collections of items of (⍵) having
[11] ⍝ totals not greater than (⍺) excepting individual items of (⍵)
[12] ⍝ that are greater than (⍺) dflt is maximum of (⍵)
[13] ⍝ Phil Last ⍝ 2008-07-02 19:01
[14] }
∇
∇ cm←{
[1] ↑⍵⍴¨⍨↓1+⌽↑-1-⌽∘⍴¨⍵
[2] ⍝ conform (mix)
[3] ⍝ ⍵ any array
[4] ⍝ ← mix a simple array
[5] ⍝ mix a uniformly nested array
[6] ⍝ otherwise uplift all items to the maximum rank and mix
[7] ⍝ primitive in 14.0
[8] }
∇
∇ cn←{
[1] ⍵.{⍵⊣⍵.{⍎'(',⍺,')←⍵'}∘⍎⍨'⎕IO',,' ',⎕NL 2.1}#.⎕NS''
[2] ⍝ clone
[3] ⍝ ⍵ space
[4] ⍝ ← unnamed space - having only & all of (⍵)'s vars.
[5] ⍝ The reason for this fn is so the object can be passed into
[6] ⍝ another function without fear that it might be changed.
[7] }
∇
∇ co←{
[1] ⊃⍵{(⊂⍵⍳⍺⍺)⌷(1+⍴⍵)↑⍺}/⍺
[2] ⍝ corresponding
[3] ⍝ A B co C ←→ A where B corresponds to C
[4] ⍝ ⍺ A B
[5] ⍝ A vector
[6] ⍝ B vector conforming [0] with A
[7] ⍝ ⍵ C
[8] ⍝ C array of members [1] of B
[9] ⍝ ← if A ←→ f¨ B then f¨ C
[10] ⍝ (⊂B⍳C)⌷(1+⍴B)↑A
[11] ⍝ shape of ⍵
[12] ⍝ [0] A[⍴B] may be preferred alternative prototype
[13] ⍝ [1] for C not in B return prototype of A but see [0]
[14] ⍝ Phil Last 2016-10-27
[15] }
∇
∇ cr←{
[1] '(~<≤=≥>≠∨∧⍱⍲)\'
[2] ⍝ default control chars for fi sc ps ec &c.
[3] }
∇
∇ ct←{
[1] q←''''∘{⍺,⍺,⍨⍵/⍨1+⍵=⍺}
[2] if←{⍺⍺⍣(⍵⍵⊣⍵)⊢⍵}
[3] (⍺,'←{')'⎕ml←0' 'r←⍬',(↓⍕(⊂'r,←⊂'),q if(≡∘⍕⍨)¨⍵),'↑r' ' }'
[4] ⍝ create createTable function
[5] ⍝ ⍺ name for function
[6] ⍝ ⍵ mixed matrix of scalar numerics and text scalars or strings
[7] ⍝ ← ⎕NR of function
[8] }
∇
∇ ct0←{
[1] q←''''∘{⍺,⍺,⍨⍵/⍨1+⍵=⍺}
[2] if←{⍺⍺⍣(⍵⍵⊣⍵)⊢⍵}
[3] v←⍎n←⍵
[4] (⊂⍕n'←⍬'),(↓⍕(⊂n,',←'),q if(≡∘⍕⍨)¨v),⊂⍕n'⍴⍨←'(⍴v)
[5] ⍝ create table -
[6] ⍝ ⍵ fully-qualified name of array
[7] ⍝ array mixed array (depth +/-2) of scalar numerics and text scalars or strings
[8] ⍝ ← executable expressions to reconstitute array
[9] }
∇
∇ cu←{
[1] 80≠⎕DR'':⍵ ⍝ non-unicode edition
[2] {
[3] ⍵↓⍨(⎕UCS⊃⍵)∊65534 65279
[4] }⍵{
[5] ∧/⍵<194:⍺ ⍝ maybe but doesn't matter
[6] ∨/⍵>244:⍺ ⍝ can't be
[7] ⍝ start not followed by continuation
[8] ⍝ ∨/((⍵>193)∧⍵<245)>1↓((⍵>127)∧⍵<192),0:⍺
[9] ⍝ continuation not preceded by start or continuation
[10] ⍝ ∨/((⍵>127)∧⍵<192)>¯1↓1,(⍵>127)∧⍵<245:⍺
[11] ⍝ let ⎕UCS test for start followed by wrong number of continuations
[12] 11::⍺
[13] 'UTF-8'⎕UCS ⍵
[14] }⎕UCS ⍵
[15] ⍝ convert UTF-8 or not
[16] ⍝ ⍵ text string, - UTF-8 bytes or not
[17] ⍝ ← clear text
[18] }
∇
∇ cv←{⍺←⊢
[1] ↑⍎'↓⍺ sc' '(∩∪)'ps ⍵
[2] ⍝ intersect or union (Ctrl+c Ctrl+v)
[3] }
∇
∇ cw←{
[1] {1↓⍵⊣⎕FUNTIE 1↑⍵}⊃{⍵,⍺ ⎕FAPPEND 1↑⍵}/(⌽,⍺),{
[2] 22::⍵ ⎕FCREATE 0
[3] ⍵ ⎕FSTIE 0
[4] }⍵
[5] ⍝ component write
[6] ⍝ ⍺ vector of arrays to write
[7] ⍝ ⍵ file path/name - create if missing
[8] ⍝ ← component numbers written
[9] ⍝ Phil Last ⍝ 2008-07-04 14:55
[10] }
∇
∇ da←{⍺←⊢
[1] f←{⍺⍺⍣(2<≢⍴⍵)⊢⍵}
[2] ∇ f⊂⍤2 f ⍵
[3]
[4] ∇⍣(2<≢⍴z)⊢z←⊂⍤2⍣(2<≢⍴⍵)⊢⍵
[5] ⍝
[6] }
∇
∇ dc←{
[1] ⍴∘⍵~∘1⍴⍵
[2] ⍝ decay
[3] ⍝ ⍵ array
[4] ⍝ ← (⍵) with all ones removed from its shape
[5] ⍝ 1 row or 1 col matrix becomes vector
[6] ⍝ singleton become scalar
[7] ⍝ Phil Last ⍝ 2008-07-18 10:06
[8] }
∇
∇ df←{
[1] ⍵{(⍺.⎕DF ⍵)⊢⍕⍺}⍵.⎕DF ⎕NULL
[2] ⍝ format ref - sans ⎕DF
[3] ⍝ ⍵ ns-ref
[4] ⍝ ← format of ns-ref - full path name
[5] ⍝ ignoring ⎕DF by using it twice!
[6] ⍝ Phil Last ⍝ 2008-03-13 23:14
[7] }
∇
∇ di←{⍺←⊢ ⋄ p←⍺⊣0
[1] ⎕PP←{0::⍵ ⋄ ∇ ⎕PP←1+⍵}⎕PP
[2] (⍴⍵){
[3] 1<|≡⍵:⍺ ∇{⍵/⍨' '∨.≠⍵}⎕FMT(⍴∇⊢)¨⍵⍴⍨1⌈⍴⍵
[4] (⊃'~''#'/⍨(⍬''∊⊂0⍴⍵),1){
[5] ⍉↑⍺{(⊂⌽⍺,1↓⌽⊃⍵),1↓⍵}↓⍉⍵
[6] }(⎕D,⎕A,'abcdefghijklmnopqrstuvwxyz','*')[62⌊↑,↓⍺]{ ⍝ use '*' for larger than 61
[7] (⍴⍵)⍴(' '≠⍺↑⍨⍴⍵)⊖↑⍵ ⍺}⍺{⍵/⍨1⌈1+(0⊥⍴⍵)↑-2-⍴⍺
[8] }p bx ⎕FMT ⍵⍴⍨1⌈⍴⍵
[9] }⍵
[10] ⍝ display
[11] ⍝ ⍺ internal
[12] ⍝ ⍵ any array
[13] ⍝ ← display form
[14] ⍝ Phil Last ⍝ 2008-01-23 13:35
[15] ⍝ {{⊂[¯2↑⍳⍴⍴⍵]⍵}⍣(⌊0.5×⍬⍴⍴⍴⍵)⊢⍵}
[16] ⍝ Phil Last 2017-07-01 09.06
[17] }
∇
∇ dn←{
[1] (nam num exp)←1↓¨{⍵⊂⍨{⍵∧4>+\⍵}⍵∊'[]'}'[',⍵
[2] scr←9=⎕NC nam
[3] new←(⊂exp)((⍎num)mg)(scr=1 0)⎕SRC∘⍎or ⎕NR nam
[4] (spc nam)←'.'pn nam
[5] 1:⊢(⍎spc,scr⊃'⎕fx' '⎕fix')new
[6] ⍝ define
[7] ⍝ ⍵ string - "#.path.itemname[n] expression"
[8] ⍝ itemname may be a function, operator, class or scripted space
[9] ⍝ ← result of #.path.⎕FX or #.path.⎕FIX on amended ⎕NR or script of named item
[10] }
∇
∇ dr←{
[1] ⍺←⌊0.5++/⍵
[2] n+(×e)×(⍳⍴⍵)∊(|e←⍺-+/n←⌊0.5+⍵×⍺÷+/⍵)⍴⍒|⍵
[3] ⍝ [re]distributive rounding
[4] ⍝ [⍺] [new] integer sum
[5] ⍝ ⍵ vector
[6] ⍝ ← ⍵ rounded and scaled to sum to ⍺
[7] ⍝ total rounding error distributed
[8] ⍝ among items of greatest magnitude
[9] ⍝ 2007-12-04 10.25 comp.lang.apl cb75f8564a3e0b22
[10] ⍝ http://groups.google.com/group/comp.lang.apl/browse_thread/thread/cb75f8564a3e0b22
[11] }
∇
∇ ds←{ ⍝ see (es)
[1] ⊃⍣(1=≢⍵)⊢⍵
[2] ⍝ disclose single
[3] ⍝ ⍵ any array
[4] ⍝ ← ⍵ or ⊃⍵ if single ⍵
[5] ⍝ Phil Last ⍝ 2008-03-06 09:28
[6] }
∇
∇ dt←{
[1] ⍺⊣(,⍺)∘.{⍺.((⊃⍬⍴⍵){⍴⍎⍺,'←⍵'/⍨0=⎕NC ⍺}{⊃⍬⍴⍵}⍣(2∊⍴⍵)⊢1↓⍵)},⊂⍣(1=≡⊃⍵)⊢⍵
[2] ⍝ above is existing code running in V12.0.5
[3] ⍝ below is equivalent using ⍺{...}¨¨⊂⍵ instead of ⍺∘.{...}⍵.
[4] ⍺⊣(,⍺){⍺.((⊃⍬⍴⍵){⍴⍎⍺,'←⍵'/⍨0=⎕NC ⍺}{⊃⍬⍴⍵}⍣(2∊⍴⍵)⊢1↓⍵)}¨¨⊂,⊂⍣(1=≡⊃⍵)⊢⍵
[5] ⍝ default
[6] ⍝ ⍺ ns(s)
[7] ⍝ ⍵ name-value pairs
[8] ⍝ ← ns(s) with named vars having values where previously missing
[9] ⍝ NB result IS ⍺ with named vars as stated.
[10] ⍝ In other words the argument is changed!!!!
[11] ⍝ Phil Last ⍝ 2006-02-21 20:54
[12] }
∇
∇ dx←{
[1] ⍺←⎕THIS
[2] ⍺.(⎕NS''){⍺⍺⊣⍺⍺.⍎⍕'(',⍺,')←⍵'}/ds\⍵
[3] ⍝ dictionary
[4] ⍝ ⍺ space - dflt here
[5] ⍝ ⍵ names values
[6] ⍝ ← ns within space ⍺ wherein vars named (names) valued (values)
[7] ⍝ Phil Last ⍝ 2008-03-06 18:58
[8] }
∇
∇ dy←{⍺←⊢
[1] 1≡⍺ 1:{⍵⊣⍵.(n v)←⊂,0}⎕NS''
[2] cat←⍺
[3] name←⊃nv←⊂if≡⍵
[4] new←0≡cat.{((⍴n)|n⍳⍵)⊃n}⊂name ⍝ missing
[5] new:1⊃cat.(n v),←⊂¨nv ⍝ add
[6] value←cat.{(n⍳⍵)⊃v}⊂name ⍝ retrieve
[7] value⊣cat.(n v)/⍨←⊂~cat.n∊⊂name ⍝ remove
[8] ⍝ maintain dictionary of names values "n" "v" with initial value ,0
[9] ⍝ monad:
[10] ⍝ ⍵ ?
[11] ⍝ ← empty store
[12] ⍝ dyad:
[13] ⍝ ⍺ store
[14] ⍝ ⍵ name value
[15] ⍝ ← if name not in store
[16] ⍝ value
[17] ⍝ if name already in store
[18] ⍝ value - and name is removed
[19] ⍝ Phil Last 2015-05-07
[20] }
∇
∇ ec←{
[1] ⍺←cr'' ⋄ e←'\'
[2] ⍵(⍺{⍵∘/¨⍺{⍺ ⍵}(⍺∊⍺⍺)∧¯1⌽⍵})~(⍵=e)∧(¯1⌽⍵≠e)∧(1⌽⍵∊⍺,e)
[3] ⍝ escape
[4] ⍝ ⍺ control chars
[5] ⍝ ⍵ string
[6] ⍝ ← (amended string)(control flags)
[7] ⍝ where:
[8] ⍝ amended string has actioned escape chars '\' removed
[9] ⍝ control flags is boolean length of amended string
[10] ⍝ with 1 where amended string is unescaped control
[11] ⍝ Phil Last ⍝ 2009-02-06 08:51
[12] }
∇
∇ ed←{
[1] ({⍵⊣⍵.s←''}⎕NS''){
[2] ⍺.(''⊣(⎕NS'').(⎕ED&'_'⊣_←⍵)) ⍝ ⍕⍪⍣(1 2≡(⍴∘⍴,≡)⍵)⊢⍵))
[3] }{
[4] 9.1≢⎕NC⊂,'⍵':# ⍺⍺ ⍵
[5] ⍵∊⍺.s:''
[6] ⍺.s,←⍵
[7] n←∇∘⍵.⍎/⍺,⍪~∘' '¨↓⍵.⎕NL 9.1
[8] ⍵ ⍺⍺↑({⊢/('['∊¨⍵)⌽(⊂'##'),⍪⍵}⍕¨⍵),¨↓'.',⍵.⎕NL 2 3 4
[9] }⍵
[10]
[11] {(⎕NS'').(⎕ED&'_'⊣_←⍵)} ⍝ is sufficient for an array
[12] ⍝ show
[13] ⍝ ⍺ ignored
[14] ⍝ ⍵ array or space
[15] ⍝ ← null
[16] ⍝ display array in editor
[17] ⍝ or display member list of space and
[18] ⍝ recursively for contained member spaces
[19] ⍝ Phil Last ⍝ 2008-03-12 08:32
[20] ⍝ Phil Last 2015-10-19
[21] }
∇
∇ en←{
[1] ((1+⌊⍺⍟1⌈⌈/|⍵)⍴⍺)⊤⍵
[2] ⍝ encode
[3] ⍝ ⍺ base
[4] ⍝ ⍵ numeric
[5] ⍝ ← ⍵ encoded to base ⍺ with sufficient digits
[6] ⍝ 2 1/2 times quicker than ⊥⍣¯1
[7] ⍝ Phil Last ⍝ 2008-03-11 18:10
[8] }
∇
∇ es←{ ⍝ see (ds)
[1] ⊂⍣(1=≡⍵)⊢⍵
[2] ⍝ enclose simple
[3] ⍝ ⍵ any array
[4] ⍝ ← ⍵ or ⊂⍵ if simple ⍵
[5] ⍝ Phil Last ⍝ 2008-03-06 09:27
[6] }
∇
∇ ev←{0::⎕SIGNAL/⌽⎕EN,⎕DM
[1] ##.AN.decode ⍵
[2] ⍝ APLAN decode ⍵
[3] }
∇
∇ ex←{
[1] ⍵[⌈\(⍳⍴⍵)×~∊∘∊⍨⍵]
[2] ⍝ extend list
[3] ⍝ ⍵ list extend
[4] ⍝ ← same list with nulls replaced by most recent non-null
[5] ⍝ nulls deemed to be empty or all ' ' and/or 0
[6] ⍝ so '' ⍬ ' ' 0 (' '0'')(⍳2 0 3) is null as are all its parts
[7] ⍝ Phil Last ⍝ 2008-04-23 17:28
[8] }
∇
∇ fc←{⍺←⊢
[1] {1↓¨⍵/⍨∧\'⍝'=⊣/¨⍵}(1+1⊃⎕LC)↓⎕NR 1⊃⎕XSI
[2] ⍝ following (full-line) comments in caller
[3] ⍝ Phil Last 2015-02-24
[4] }
∇
∇ fgh←{⍺←⊢
[1] #.(f←{⍺←⊢ ⋄ '(',⍺,' f ',⍵,')'})
[2] #.(g←{⍺←⊢ ⋄ '(',⍺,' g ',⍵,')'})
[3] #.(h←{⍺←⊢ ⋄ '(',⍺,' h ',⍵,')'})
[4] ⍝
[5] }
∇
∇ fi←{⍝ find
[1] ⎕ML←0
[2] ⍺←#
[3] 0::((⊃⎕DM),' - Try escaping "',(⍵∩'(~<≤=≥>≠∨∧⍱⍲)\'),'"')⎕SIGNAL ⎕EN
[4] ('1∊⍵⍷⍨'ps ⍵){⍵/⍨⍺∘{⍺{⍎⍺}⍕⍵{
[5] (⍵∊3 4):2↓⊃,/' ',CR,¨⎕NR ⍺
[6] (⍵=2):⍎⍺
[7] (⍵=9):{0::'' ⋄ ⎕SRC⍎⍵}⍺
[8] ''
[9] }⎕NC ⍵}¨⍵}{
[10] 2=≡⍵:⍵
[11] (⍬≡0⍴⍵):li ⍵
[12] (9=⎕NC'⍵'):⍵ li 3.1 3.2 4.1 4.2 9.4
[13] (⊃{⍺,'∨',⍵}/⊂if≡⍵)lf # li 3.1 3.2 4.1 4.2 9.4
[14] (''≢0⍴⍵):⍵ li 3.1 3.2 4.1 4.2 9.4
[15] ⍵ lf # li 3.1 3.2 4.1 4.2 9.4
[16] }⍺
[17] ⍝ find
[18] ⍝ ⍺ ref - search all in or below
[19] ⍝ string - logical wildcard selection of candidates anywhere
[20] ⍝ numbers - candidate ⎕NCs - dflt - 3.1 3.2 4.1 4.2 9.4
[21] ⍝ ⍵ search string - can contain executables "(~<≤=≥>≠∨∧⍱⍲)". see ps
[22] ⍝ ← fully qualified names of arrays, fns, ops & classes where found.
[23] ⍝ Phil Last ⍝ 2008-03-04 13:53
[24] }
∇
∇ fm←{⍺←⊢
[1] 0::⎕SIGNAL/⌽⎕EN,⎕DM
[2] ⍺ ##.AN.format ⍵
[3] ⍝ APLAN format ⍵
[4] }
∇
∇ fo←{
[1] ⍝ #.{
[2] {FO}'FO'⎕WC⊢FO←'OLECLIENT' 'Scripting.FileSystemObject'
[3] ⍝ }0
[4] ⍝ file system object
[5] ⍝ ⍵ ?
[6] ⍝ ← file system object
[7] }
∇
∇ fq←{⍺←⊢
[1] (⍺⊣0){⍵[;⍋⍺×⊢⌿⍵]}⍵{⍵,[-0.1]¯2-/((⌷⍨∘⊂∘⍋⍨⍵⍳⍺)⍳⍳⍴⍵),⍴⍺}∪⍵
[2] ⍝ frequency
[3] ⍝ [⍺] order ¯1|0|1 - dflt=0 - ¯1=descending; 0=first occurrence; 1=ascending
[4] ⍝ ⍵ list
[5] ⍝ ← 2d 2 rows - (unique ⍵)⍪(frequency)
[6] ⍝ Phil Last ⍝ 2008-03-05 11:37
[7] }
∇
∇ fr←{⍺←⊢
[1] (⊃⊢∘⊂/(≡⍵)↓0 0 ⍵){⊃1↓0,⍵⌿⍨{(⍵≠0)∧⍵=⌈/⍵}+/∨\('.',⍺,' ')⍷⍕⍪⍵}¨⊂nt ⍺⊣#
[2] ⍝ find ref(s) in tree of tgt
[3] ⍝ ⍺ tgt - space - dflt #
[4] ⍝ ⍵ simple name(s)
[5] ⍝ ← scalar or vector ref(s) nearest root or zero(s)
[6]
[7] ⍝ was:
[8] ⍝ ⊃⍺⍺/⍺,⊂⍵
[9] ⍝ for loop (fold right)
[10] ⍝ a b c d f fr w ←→ a f(b f(c f(d f w)))
[11] ⍝ Phil Last ⍝ 2011-10-20 07:26
[12] }
∇
∇ ft←{
[1] ⍵{(0,⍴,⍺)↓⍵⌿⍨>/⍺⍷⍵}{⍵⌽⍨+/∧\' '=⍵}⎕CR⊃1↓⎕XSI
[2] ⍝ Financial Times - "No Financial Times? No Comment!"
[3] ⍝ ⍵ string
[4] ⍝ ← lines of calling function starting in that string
[5] ⍝ presumed to start with a '⍝' but don't need to.
[6] ⍝ Phil Last ⍝ 2008-04-30 17:18
[7] }
∇
∇ gc←{
[1] ⍺←#
[2] w←⍵
[3] (s r)←⍵
[4] c←{⊃⍵<∨/⍵}('\',cr'')∊s
[5] s←{⍵ re fl{⍵,∘⊂¨'\',¨⍵}~∘'\'cr''}if c,s
[6] (0∊⍴z←{⍵/⍨(⎕NC ⍵)∊3.1 3.2 4.1 4.2 9.4}⍺ fi s):z
[7] z⊣z ch¨⊂(⊃ec s)r
[8] ⍝ global change
[9] ⍝ ⍺ space - dflt #
[10] ⍝ ⍵ old new strings
[11] ⍝ ← nms changed
[12] ⍝ Phil Last ⍝ 2008-03-17 16:51
[13] }
∇
∇ gd←{⍺←⊢
[1] z←⎕FMT'-'⍪'|',(⍺⊣0){
[2] ⍺:⍉↑,/{⍵'-'}¨⍉⍵
[3] '-'⍪⍨⍵
[4] }↑,/{⍵'|'}¨⍵
[5] r←(∨/z='-')∧∧/z∊'|- '
[6] c←(∨⌿z='|')∧∧⌿z∊'|- '
[7] (r⌿z)←'-'
[8] (c/z)←'|'
[9] ((,r∘.∧c)/,z)←'+'
[10] z
[11] ⍝ grid
[12] ⍝ ⍺ 0 sep cols not rows
[13] ⍝ 1 sep cols and rows
[14] ⍝ ⍵ array
[15] ⍝ ← boxed
[16] }
∇
∇ gw←{
[1] (⎕NS''){0::⍺ ⋄ ⍺⊣⍺.⎕CY ⍵}⍵
[2] ⍝ get ws
[3] ⍝ ⍵ name of accessible ws
[4] ⍝ ← anon root ns containing root and ns-tree of ws named ⍵
[5] }
∇
∇ ht←{
[1] (⊃⍵)(1↓⍵)
[2] ⍝ ⍵ list
[3] ⍝ ← head and tail
[4] ⍝ Phil Last ⍝ 2009-01-12 11:30
[5] }
∇
∇ hx←{
[1] t←0∊⊃⍬⍴0⍴⊂⍵
[2] a←⎕D,'abcdef',⎕D,6⍴⎕A
[3] t:⍉a⌷⍨⊂16⊥⍣¯1⊢⍉⍵
[4] ⍉16⊥16|a⍳⍉⍵
[5] ⍝ ⍵ simple dec- or hex-array
[6] ⍝ ← simple hex- or dec-array
[7] ⍝ accepts hex as CAPS or small
[8] ⍝ returns hex as small
[9] ⍝ dec to hex increases rank at right
[10] ⍝ hex to dec decreases rank from right
[11] }
∇
∇ ia←{⍺←⊢
[1] ~∘' '¨(⊢(⌿⍨)0≤⎕NC)⎕NR⊃⎕SI
[2] alpha
[3] bravo
[4] charlie
[5] delta
[6] echo
[7] foxtrot
[8] golf
[9] hotel
[10] india
[11] juliet
[12] kilo
[13] lima
[14] mike
[15] november
[16] oscar
[17] papa
[18] quebec
[19] romeo
[20] sierra
[21] tango
[22] uniform
[23] victor
[24] whisky
[25] x_ray
[26] yankee
[27] zulu
[28] ⍝ ICAO (international civil aviation organization) alphabet
[29] }
∇
∇ ic←{
[1] m←0
[2] ⍺←m←1
[3] f←¯1∘tc
[4] m:f ⍵
[5] ≡/f¨⍺ ⍵
[6] ⍝ ignore case
[7] ⍝ ⍺ [string]
[8] ⍝ ⍵ string
[9] ⍝ ← strings match ignoring case & non-alphanumerics
[10] ⍝ or only string lower case and non-alphanumeric
[11] ⍝ also:
[12] ⍝ interesting characters:
[13] ⍝ 181: mu (micro- prefix) (greek letter)
[14] ⍝ 8704: for all (upside down A)
[15] ⍝ 8707: there exists (backwards E)
[16] }
∇
∇ is←{0::⎕NS⍣(≢⍴⍵)⊢''
[1] ≢⍴⍵:r⊣⍎⍕'r.('n')←v'⊣r←⎕NS''⊣v←↓⍉↑⍵.(⍎¨)n←(⊢⍴⍨2⌈≢)¨∩/⍵.⎕NL-2
[2] ≢⊢⍵:r⊣⍎⍕'r.('n')←v'⊣r←{⎕NS''}¨⍳≢v←↓⍉↑⍵.⍎¨n←(⊢⍴⍨2⌈≢)↓⍵.⎕NL 2
[3]
[4] ⍝ invert space(s)
[5] ⍝ ⍵ space or list thereof
[6] ⍝ ⍵ space with named lists
[7] ⍝ ← list of spaces with named items
[8] ⍝ after lists overtaken to longest
[9] ⍝ or
[10] ⍝ ⍵ list of spaces with named items
[11] ⍝ ← space with named lists
[12] ⍝ of intersect of named items
[13] ⍝ After normalisation is is self inverse.
[14] ⍝ [
[15] ⍝ nam←('five' 'zero' 'two')
[16] ⍝ num←(5 0 2)
[17] ⍝ ]
[18] ⍝ vs
[19] ⍝ [
[20] ⍝ nam←'five'
[21] ⍝ num←5
[22] ⍝ ][
[23] ⍝ nam←'zero'
[24] ⍝ num←0
[25] ⍝ ][
[26] ⍝ nam←'two'
[27] ⍝ num←2
[28] ⍝ ]
[29] ⍝ Phil Last 2017-04-10 10.14
[30] }
∇
∇ js←{⍺←⊢
[1] head←':namespace ',name←⍺⊣'.'nn df ⍵
[2] par←'⍝ ## ←→ ',,df ⍵.##
[3] consts←'(⎕IO ⎕ML)←',⍕⍵.(⎕IO ⎕ML)
[4] fns←,⊃,/(⊂''),⍵.((⊂'')∘,∘⎕NR¨↓⎕NL 3.2 4.2)
[5] fns,←⊃,/(⊂''),⍵.({('∇',¨1⍴⍵),1↓⍵,'∇'}∘⎕NR¨↓⎕NL 3.1 4.1)
[6] tail←':endnamespace ⍝ ',name
[7] head par''consts,fns,''tail
[8] ⍝ flat script from defined fns and ops only
[9] }
∇
∇ ki←{
[1] 1:2↓¯2↓⎕NR⊃⎕SI ⍝ not this
[2] +/∧\
[3] +/∧\' '=
[4] ,/
[5] ,←
[6] /⍳
[7] /⍳⍴
[8] 0=⍴
[9] 0=⍴⍴
[10] 0∊⍴
[11] 1=≡
[12] {(+/∧\' '=⍵)↓⍵}
[13] {(+/∨\' '≠⌽⍵)↑¨↓⍵}
[14] {(↓⍺)⍳↓⍵}
[15] {(∨\' '≠⍵)/⍵}
[16] {0}
[17] {}
[18] {⍵[⍋⍵]}
[19] {⍵[⍋⍵;]}
[20] {⍵}
[21] {⍺ ⍵}
[22] {⍺}
[23] ~∘' '¨↓
[24] ↓⍉↑
[25] ∧\' '=
[26] ⊃∘⍴¨
[27] ⊃⌽
[28] ⍴⍴
[29] ⍝ known idioms
[30] }
∇
∇ kl←{⍺←⊢
[1] y m←0 100⊤⍵
[2] y←y+(y=0)⊃0,⎕TS
[3] y<100:∇¨(⍵×100)+1+4 3⍴⍳12
[4] l←>/0=4 100 400|y
[5] md←0 31 28,10⍴5⍴31 30
[6] fy←{(⍵×365)+(⌊⍵÷4)-(⌊⍵÷100)-⌊⍵÷400}y-1
[7] ytd←(m⊃+\0,md)+l∧m>2
[8] r←1↓43↑' ',1+⍳(m⊃md)+l∧m=2
[9] t←~∘' ',m⊃' ',{⍵/⍨¯1≠⎕NC ⍵}⎕NR⊃⎕SI
[10] 1:↑(⊂⍕t,y),↓⍕'SMTWTFS'⍪6 7⍴(-7|1+fy+ytd)⌽r
[11] January
[12] February
[13] March
[14] April
[15] May
[16] June
[17] July
[18] August
[19] Sepember
[20] October
[21] November
[22] December
[23] ⍝ kalends
[24] }
∇
∇ ku←{⍺←⊢
[1] ~∨/b←⍺=⊢/¨w←⍵:w
[2] (b/w)←b/2{(¯1↓⍺),⍵}/w,' '
[3] ⍺ ∇(¯1↓1,~b)/w
[4] ⍝ KontinUe - expects {(+/∨\' '≠⌽⍵)↑¨↓⍵} matrix
[5] }
∇
∇ la←{
[1] {⍵{(⍺,⍵)[⍒⍵;]}2 ⎕AT ⍵}⍵ li 3.1 3.2 4.1 4.2
[2] ⍝ latest fns/ops in ns ⍵
[3] ⍝ Phil Last ⍝ 2008-01-17 12:11
[4] }
∇
∇ lc←{
[1] 0 ll ⍵
[2] ⍝ lower case clone
[3] ⍝ ⍵ space with vars
[4] ⍝ ← space as ⍵ but all vars are lower case
[5] }
∇
∇ lf←{
[1] ⍵⌿⍨⍺ lw ⍵
[2] ⍝ ⍺ logical filter - wildcards '(*this∨that*)∧~the*other'
[3] ⍝ ⍵ namelist - 2d or string list
[4] ⍝ ← names in (⍵) matching filter
[5] ⍝ Phil Last ⍝ 2008-06-11 21:14
[6] }
∇
∇ li←{⍺←#
[1] 1↓⊃,/' ',⍵∘{(⍕⍵)∘,¨~∘' '¨↓'.',⍵.⎕NL|⍺}¨nt ⍺
[2] ⍝ list
[3] ⍝ ⍺ space
[4] ⍝ ⍵ nameclasses ∊ 0.1×⍳100
[5] ⍝ ← fullname list all nameclass items in or below space
[6] ⍝ Phil Last ⍝ 2008-01-09 12:09
[7] }
∇
∇ li0←{
[1] ⎕ML←0
[2] ⍺←#
[3] 1↓⊃,/' ',⍵∘{(⍕⍵)∘,¨~∘' '¨↓'.',⍵.⎕NL|⍺}¨nt ⍺
[4] ⍝ list
[5] ⍝ ⍺ space
[6] ⍝ ⍵ nameclasses ∊ 0.1×⍳100
[7] ⍝ ← fullname list all nameclass items in or below space
[8] ⍝ Phil Last ⍝ 2008-01-09 12:09
[9] }
∇
∇ ll←{
[1] ⍺{s←⎕NS'' ⋄ s⊣s.⍎(⍺⍺ cc ⍺),'←⍵'}/⍵.({⍵(⍎⍵)}'⎕io',,' ',⎕NL 2.1)
[2] ⍝ case-folded clone
[3] ⍝ ⍵ space with vars
[4] ⍝ ← space as ⍵ but all vars are lower/upper case according ⍺
[5] }
∇
∇ ls←{0∊⍴⍵:''
[1] ⍺←'&'
[2] s←1↓⌽(1,⍴⍵)/(' ',⍺,' ')', '
[3] (1+⍴0⊃s)↓⊃,/' ',s,¨⍵
[4] ⍝ list
[5] ⍝ ⍺ alternative to '&'
[6] ⍝ ⍵ list
[7] ⍝ ← string
[8] ⍝ ls 'one' 'two' 'three' 'four'
[9] ⍝ one, two, three & four
[10] }
∇
∇ lv←{
[1] 1:⎕CR⊃⎕SI
[2] ⍝ logical vector reduction
[3] ⍝ In the following list of logical vector reductions the
[4] ⍝ comment describes ⍵ when 1<⍴⍵ and the result is true.
[5] ⍝ The boolean digits are the values, for each ⍺⍺/ of ∘.⍺⍺⍨0 1
[6] ⍝ The two D:fns and two dervs are the missing logicals - (0 a c f)
[7]
[8] 0 0 0 0 ⋄ {0}/⍵ ⍝ never
[9] 0 0 0 1 ⋄ ∧/⍵ ⍝ no zeros
[10] 0 0 1 0 ⋄ >/⍵ ⍝ odd leading ones
[11] 0 0 1 1 ⋄ ⊣/⍵ ⍝ a leading one
[12] 0 1 0 0 ⋄ </⍵ ⍝ last is only one
[13] 0 1 0 1 ⋄ ⊢/⍵ ⍝ last is one
[14] 0 1 1 0 ⋄ ≠/⍵ ⍝ odd ones
[15] 0 1 1 1 ⋄ ∨/⍵ ⍝ at least one one
[16] 1 0 0 0 ⋄ ⍱/⍵ ⍝ odd leading zeros else last is only one
[17] 1 0 0 1 ⋄ =/⍵ ⍝ even zeros
[18] 1 0 1 0 ⋄ (~⊢)/⍵ ⍝ last is parity of width
[19] 1 0 1 1 ⋄ ≥/⍵ ⍝ even leading zeros
[20] 1 1 0 0 ⋄ (~⊣)/⍵ ⍝ a leading zero
[21] 1 1 0 1 ⋄ ≤/⍵ ⍝ last is not only zero
[22] 1 1 1 0 ⋄ ⍲/⍵ ⍝ even leading ones else last is only zero
[23] 1 1 1 1 ⋄ {1}/⍵ ⍝ always
[24] }
∇
∇ lw←{
[1] (⍺≡∊⍺):(⍬⍴⍴⍵)⍴0
[2] ⍺{⍎'⍵ wi'ps ⍺}↑⍵
[3] ⍝ ⍺ logical wildcard - wildcards '(*this∨that*)∧~the*other'
[4] ⍝ ⍵ namelist - 2d or string list
[5] ⍝ ← boolean - which names in (⍵) match filter
[6] }
∇
∇ md←{
[1] ⍬⍴⍵{⍵/⍨=∘(⌈/)⍨¯2-/((⌷⍨∘⊂∘⍋⍨⍵⍳⍺)⍳⍳⍴⍵),⍴⍺}∪⍵
[2] ⍝ mode
[3] ⍝ ⍵ list
[4] ⍝ ← most frequent item or first occurring of multiple
[5] }
∇
∇ ml←{
[1] r←re fl∘('&' '&')('<' '<')('>' '>')
[2] c←r if{'<'≠⍬⍴⍵}
[3] ((1=≡⍺)⊃⍺(⊂⍺)){
[4] ⍝ (⊃{⊂⍵}/(1∩≡⍺),⊂⍺){
[5] 1⌽'><',(⊃{⍵,⊃{' ',⍺,1⌽'"="',r ⍵}∘⍕/⍺}/⌽⍺),⊃(×⍴⍵)↓'/'('>',(c ⍵),'</',⊃⍺)
[6] },⍕⍵
[7] }
∇
∇ mn←{
[1] ⍺←''
[2] ⍝ mu below is ⎕ucs 181
[3] m n←'yzafpnµm' 'kMGTPEZY'
[4] (⊂⍺),¨⍨⍵{(m,(⊂''),n)[⍵+8],¨⍨⍕¨3 sg ⍺÷1000*⍵}⌊1000⍟|⍵+⍵=0
[5] ⍝ magnitute
[6] ⍝ ⍺ unit
[7] ⍝ ⍵ simple number array
[8] ⍝ ← (⍵) scaled such that (1 ≤ |n) ∧ 1000 > |n
[9] ⍝ followed by the relevant SI Prefixes and the unit (⍺)
[10] ⍝ 'g' ∇ 12345 0.12345 → 12.345kg 123.45mg
[11] ⍝ yocto, zepto, atto, femto, pico, nano, micro, milli,
[12] ⍝ 1e¯24 1e¯21 1e¯18 1e¯15 1e¯12 1e¯9 1e¯6 1e¯3
[13] ⍝ kilo, Mega, Giga, Tera, Peta, Exa, Zetta, Yotta.
[14] ⍝ 1e3 1e6 1e9 1e12 1e15 1e18 1e21 1e24
[15] }
∇
∇ ms←{
[1] ⍺⊣⍎{'⍺.(',⍵,')←⍵.(',⍵,')'}'⎕io',⍕⊃~/(⍵ ⍺).⎕NL-2
[2] ⍝ merge spaces
[3] ⍝ ⍺ space
[4] ⍝ ⍵ space
[5] ⍝ ← (⍺) with union of vars in (⍺) & (⍵)
[6] ⍝ vars already in (⍺) ARE NOT OVERWRITTEN
[7] ⍝ unlike 'a'⎕ns b which overwrites common vars in a with values from b
[8] ⍝ in ms/A B C
[9] ⍝ C will remain unchanged
[10] ⍝ B will keep its own and gain vars from C not in B
[11] ⍝ A will keep its own and gain vars from B ms C not in A
[12] ⍝ no values are changed.
[13] ⍝ Phil Last ⍝ 2008-09-02 22:05
[14] }
∇
∇ mv←{
[1] x n←((⌈/⍺)⌈⌈/⍵),(⌊/⍺)⌊⌊/⍵
[2] (⍵[⍋⍵],x)[(0,+\(⍳1+x-n)∊⍵-n)[⍺-n]]
[3] ⍝ move
[4] ⍝ ⍺ integer vector
[5] ⍝ ⍵ integer vector
[6] ⍝ ← ⍺ with items not in ⍵ moved to next ⍵
[7] ⍝ {(⍵,⌈/⍺)[+/⍺∘.>⍵]}∘{⍵[⍋⍵]} can be
[8] ⍝ quicker for relatively small ⍵
[9] }
∇
∇ mx←{
[1] ↑⍵⍴¨⍨↓1+⌽↑-1-⌽∘⍴¨⍵
[2] ⍝ mix variable rank
[3] }
∇
∇ na←{
[1] ⎕ML←0
[2] ⍺←#(2 3 4)
[3] s c←⍺
[4] c←(s≡c)⊃c(2 3 4)
[5] (,∘(⍵∘,)⍨'*'~⍵)lf s li c
[6] ⍝ names
[7] ⍝ ⍺ space [ nameclasses ]
[8] ⍝ ⍵ wildcard
[9] ⍝ ← wildcard matches having nameclass in or below space
[10] ⍝ Phil Last ⍝ 2008-01-22 21:26
[11] }
∇
∇ nd←{
[1] ⌈/-∘(⌊/)⍨+.=∘'.'⍕,[⍬]nt ⍵
[2] ⍝ namespace depth
[3] ⍝ ⍵ ns
[4] ⍝ ← 0⌈⌈/1+∇¨subnss
[5] ⍝ Phil Last ⍝ 2008-09-02 14:23
[6] }
∇
∇ ne←{
[1] ⍺(⍵{⍺+⍵ׯ1*(⍺-⍵)∊⍺⍺})⌊/|⍺∘.-⍵
[2] ⍝ nearest
[3] ⍝ ⍺ integer list
[4] ⍝ ⍵ ditto
[5] ⍝ ← ⍺ decreased or increased where necessary to nearest value of ⍵
[6] ⍝ 0 4 9 14 20 25 ne 3×⍳10
[7] ⍝ 0 3 9 15 21 24
[8] }
∇
∇ ni←{⍺←⊢ ⋄ ⍵≡⍺ ⍵:∇/⍵ ⋄ {⍵._Inst}{
[1] (⍵._Inst.⍎⍺,'←⍵∘{0::(⊃⍬⍴⎕DM)⎕SIGNAL ⎕EN ⋄ ⍺ ⍺._Class.',⍺,'⍵}')/⍵
[2] }/⍵,⍺{⍵⊣⍵.(_Class _Inst)←⍺,#.⎕NS''}#.⎕NS''
[3] ⍝ ⍵ (class)(methods)
[4] ⍝ ← instance
[5] ⍝ class: space having at least the functions named in methods.
[6] ⍝ methods: names of explicit dyadic functions in class.
[7] ⍝ instance: space with derived methods that call the class
[8] ⍝ methods that share data in their unnamed space
[9] ⍝ left argument that refs instance and class.
[10] ⍝ .-class-----. .-instance-. .-------------.
[11] ⍝ | fns, data | | methods | | data class |
[12] ⍝ | methods | '--↓-------' | instance ↓ |
[13] ⍝ '-----↓--↑--' | ↑ '--↓-------|--'
[14] ⍝ ↑ | | | | | ↑ |
[15] ⍝ | | '-------' '--------' | |
[16] ⍝ | | | |
[17] ⍝ | '---------------------------' |
[18] ⍝ | |
[19] ⍝ '----------------------------------'
[20] }
∇
∇ nm←{
[1] ⍺←#
[2] ,∘⍵⍣⍺.{0=⎕NC ⍺}''
[3] ⍝ new name
[4] ⍝ ⍺ space
[5] ⍝ ⍵ scalar char
[6] ⍝ ← new name undefined in space
[7] ⍝ Phil Last ⍝ 2009-02-14 18:28
[8] }
∇
∇ nn←nn
[1] nn←(-(⌽⊢)⍳⊣)↑⊢
[2] ⍝ node name
[3] ⍝ ⍺ separator
[4] ⍝ ⍵ name - qualified ws item, filename ?
[5] ⍝ ← last node
[6] ⍝ Phil Last ⍝ 2008-06-02 22:58
∇
∇ no←no
[1] no←~∘∊⍨
[2] ⍝ nulls out
[3] ⍝ Phil Last 2017-12-19 07.35
∇
∇ ns←{
[1] {⍵{⍵\{
[2] 0::1 ⍝ ok if error!
[3] {0}#.⎕SRC #.⍎⍵ ⍝ wrong if not
[4] }¨⍵/⍺
[5] }9.1=#.⎕NC ⍵}⊂if≡⍵
[6] ⍝ non scripted
[7] ⍝ ⍵ nested list
[8] ⍝ ← boolean, which of (⍵) are names of non-scripted (ordinary) nss
[9] ⍝ Phil Last ⍝ 2008-04-15 19:04
[10] }
∇
∇ nt←{
[1] ∪⍵{⊃∇/⍺.(⍺{(0,⍵)/⍨0,(⍺≠⍵)∧⍺=⍵.##}⍎⍕'⍺',⌽↓⎕NL 9.1),⊂⍵,⍺}⍬
[2] ⍝ namespace tree
[3] ⍝ ⍵ ns
[4] ⍝ ← ns and all nss below
[5] ⍝ excludes nss whose only ref is outside parent
[6] ⍝ Phil Last ⍝ 2008-04-30 00:30
[7] }
∇
∇ os←{
[1] f←({⍵⊣⍵.x←⍬}⎕NS'')∘{⍺.x⊣⍺.x{(⍺~⍵)∪⍵~⍺}←,⍵}
[2] f{⍵⊣⍵.(f←⍺⍺)/0}⎕NS''
[3] ⍝ one store
[4] ⍝ ⍵ ? ignored
[5] ⍝ ← ns containing function f
[6] ⍝ after which in ns.f ⍵
[7] ⍝ ⍵ array
[8] ⍝ ← contents of store after call being
[9] ⍝ items previously in store not in arg
[10] ⍝ and items in arg not previously in store
[11] ⍝ with the result that scalars in arg
[12] ⍝ are added to or removed from store.
[13] ⍝ ns.f ⍬ ←→ contents unchanged
[14] ⍝ ns.f⍣2⊢⍬ ←→ empty store
[15] }
∇
∇ pa←{
[1] ⍺←⎕PW-1
[2] {⍵↓¨⍨~1↑⍨⍴⍵}⍵{⍺⊂⍨⍵↑⍨⍴⍺}⊃,/⍺{⍵↑¨⍺ cl ⍵}¯2-/0,(⍴⍵),⍨(/∘⍳∘⍴⍨)⍵=' '
[3] ⍝ paragraph
[4] ⍝ ⍺ width
[5] ⍝ ⍵ text string
[6] ⍝ Phil Last ⍝ 2008-09-11 15:03
[7] }
∇
∇ pb←{
[1] bl ht nb←⎕UCS' 'HT NB
[2] (1=≡⍵){
[3] (↑⍣⍺)⎕UCS∘{
[4] {⊃⍵ nb+.×0 1=⊂{⍵∧⌽∨\⌽~⍵}⍵∊ht bl}⍵/⍨6*⍵=ht
[5] }∘⎕UCS¨(↓⍣⍺)⍵
[6] }⍵
[7]
[8] ⍝ preserve blanks
[9] ⍝ ⍵ text perhaps with leading or embedded blanks or tabs
[10] ⍝ ← ⍵ with leading and embedded blanks and tabs replaced by
[11] ⍝ non-breaking space(NB): ' ' 1 for 1; tab(HT) 6 for 1.
[12] }
∇
∇ pf←{⍺←⊢
[1] c←'R:' 'D:' 'U:' 'E:' 'Z:' 'L:' '8:'
[2] k←'ER' 'DC' 'UC' 'ED' 'DL' 'LL' 'F8'
[3] def←⍺ re fl↓c,⍪⊂¨k
[4] def ⎕PFKEY ⍵
[5] ⍝ ⍺ def - string wherein 'R:' 'D:' 'U:' 'E:'
[6] ⍝ replaced with 'ER' 'DC' 'UC' 'ED'
[7] ⍝ ⍵ key
[8] ⍝ ← new defn
[9] ⍝ Phil Last 2014-10-01 11:57
[10] }
∇
∇ pl←{
[1] 0∊∊⍺:(⍕⍺),(⍺≠1)⊃~∘∊⍨' '(=⊂⊢)' ',⍵
[2] (1⌽(⍵≠1)⊃~∘∊⍨{⍵⊂⍨⍵=⊃⍵}' ',⍺),⍕⍵
[3] ⍝ plural
[4] ⍝ ⍺ number | ⍺ 'this these'
[5] ⍝ ⍵ 'thing things' | ⍵ number
[6] ⍝ ← 1 thing | ← this 1
[7] ⍝ n things | these n
[8] }
∇
∇ pn←{⍺←'\/'
[1] ⍵{(⍵↓⍺)(⍵↑⍺)}-⌊/(⌽⍵)⍳⍺
[2] ⍝ file path / name ⍝ '/' being ⍺←'/\' by default
[3] ⍝ ⍵ file/path/name
[4] ⍝ ← (file/path/) (name)
[5] ⍝ path - up to and including final separator
[6] ⍝ name - beyond final separator
[7] ⍝ Phil Last ⍝ 2008-07-07 11:31
[8] }
∇
∇ pp←{
[1] len←⍴str←sz,' ',⍵
[2] word←⌈len÷+/brk←str∊' -'
[3] lines←⌈len÷⍺-word
[4] wid←⌈len÷lines
[5] pos←wid×⍳lines
[6] pos←pos ne brk/⍳len
[7] msk←(⍳len)∊pos
[8] ~∘∊⍨msk⊂1⌽str
[9] ⍝ paragraph
[10] ⍝ 4 × quicker than pa but not guaranteed to stay within width
[11] }
∇
∇ pr←{
[1] ⍺←'()'
[2] ⍺∘{1⌽(⌽⍺),⍵}ad{1}⍵
[3] ⍝ parenthesise
[4] }
∇
∇ ps←{
[1] def←'⍺⍺'(cr'')
[2] ⍺←def
[3] arg←,es ⍺
[4] fnx exc←2⍴arg,(⍴arg)↓def
[5] ⍺{
[6] ⊃,/,⍉↑{{'(',fnx,'''',⍵,''')'}¨⍵
[7] }\⊃{⍺∘{(⍵/2</0,⍵)⊂⍵/⍺
[8] }¨1 0=⊂(⍺=' '){⍵∨⍺∧⍵{⍵∊⍺/⍵}+\~⍺
[9] }{(⍺ ⍺⍺ ⍵)∧⌽(⌽⍺)⍺⍺⌽⍵}⍵
[10] }/exc ec ⍵
[11] }{⍵/⍨1+⍵=''''}'(',⍵,')'
[12] ⍝ parse
[13] ⍝ ⍺ 'fnexpr' ['exechars'] - default '⍺⍺' '(~<≤=≥>≠∨∧⍱⍲)\'
[14] ⍝ ⍵ string may contain text and executable chararacters.
[15] ⍝ use \ to escape executable chars including itself.
[16] ⍝ ← string parsed so that each substring is arg to fnexpr
[17] ⍝ (this∧~and)<that ←→ (((⍺⍺'this')∧~(⍺⍺'and'))<(⍺⍺'that'))
[18] ⍝ Phil Last ⍝ 2008-03-04 15:14
[19] }
∇
∇ px←px
[1] px←((,/2⍴⊢),2↓⊢)⎕NPARTS
[2] ⍝ 'path/name.ext' → 'path/name' '.ext'
[3] ⍝ Phil Last 2018-01-12 19.45
∇
∇ qu←{
[1] ⍺←''''
[2] ⍺,(⍵/⍨1+⍵=⍺),⍺
[3] ⍝ quote
[4] ⍝ Phil Last ⍝ 2008-01-14 17:39
[5] }
∇
∇ rc←{
[1] ⍺←1 1
[2] 22::⍬ ⍝ missing file
[3] ⍺{(⎕FUNTIE ⍵)⊢{⎕FREAD ⍺ ⍵
[4] }/⍵,⍪0~⍨⍺{⍴⍴⍺:⍵/⍨⍺⍴⍨⍴⍵ ⋄ ⍺↑⍵}⊃↓∘⍳/2⍴⎕FSIZE ⍵
[5] }⍵ ⎕FSTIE 0
[6] ⍝ read component file
[7] ⍝ ⍺ scalar - larg to ↑ on components - 3=first 3, ¯2=last 2
[8] ⍝ vector - larg to / on components used cyclically -
[9] ⍝ (1 0)=odds, (0 0 1)=every third, default - (1 1)=all
[10] ⍝ ⍵ file path/name
[11] ⍝ ← vector of file components
[12] ⍝ Phil Last ⍝ 2008-07-04 14:55
[13] }
∇
∇ rd←{
[1] ⊃(⌊0.5+⍵×⍺÷+/⍵){⍺⍺+⍵{(×⍵)×(⍳⍴⍺)∊(⍒|⍺)⍴⍨|⍵}⍺-+/⍺⍺}/⍺ ⍵
[2] ⍝ redistribute
[3] ⍝ ⍺ new scalar integer total
[4] ⍝ ⍵ simple integer list
[5] ⍝ ← list with length as (⍵), total as (⍺) and relative proportions similar
[6] ⍝ to (⍵). Recalculate proportionally; round to integer; redistribute
[7] ⍝ total error (e) as +/-1 for each of the (e) absolute largest items.
[8] }
∇
∇ re←{
[1] fi←{(⍴,⍺){⍵\⍺{⍵∊⊃⍺{⍵,⍺/⍨⍺≥⍺⍺+⌈/⍵}/⌽(-⍺),⍵}⍵/⍳⍴⍵}⍺⍷⍵} ⍝ no overlap
[2] ⊃⍺{(⍴,⍵)↓⊃,/⍵∘,¨(⍴,⍺)↓¨⍺{⍵⊂⍨⍺ fi ⍵}⍺,⍺⍺}/⍵
[3] ⍝ ⊃⍺{(⍴,⍵)↓⊃,/⍵∘,¨(⍴,⍺)↓¨⍺{⍵⊂⍨⍺ ⍷ ⍵}⍺,⍺⍺}/⍵
[4] ⍝ replace
[5] ⍝ string re old new
[6] ⍝ Phil Last ⍝ 2007-12-31 11:22
[7] }
∇
∇ rf←{
[1] ⍺←⎕DR''
[2] 22::0/' ' 0[2|⍺]
[3] ⍺{(⎕NUNTIE ⍵)⊢⎕NREAD ⍵,⍺,2↑⎕NSIZE ⍵}⍵ ⎕NTIE 0
[4] ⍝ read file
[5] ⍝ ⍺ conversion - dflt ⎕DR'' (?80?82?) - giving text
[6] ⍝ ⍵ file path/name
[7] ⍝ ← file body - type acc'g ⍺
[8] ⍝ if no file - ⍬ or '' acc'g ⍺ is odd or even
[9] ⍝ Phil Last ⍝ 2008-06-12 8:40
[10] }
∇
∇ rm←{
[1] ⍺{1↓⊃,/⍵{(¯1↓' ',(⍴⍵)⍴1↓⍺),¨⍵}(⊃⍵){⍺{(⍴⍺)↓¨⍵⊂⍨⍺⍷⍵}⍺,⍵}⍺},¨⍵
[2] ⍝ replace multiple
[3] ⍝ ⍺ text string with placeholders
[4] ⍝ ⍵ list of strings first of which is placeholder the rest being strings
[5] ⍝ to replace each placeholder, re-used cyclically if insufficient.
[6] ⍝ ← amended string
[7] ⍝ If 2=⍴⍵ this is equivalent to: ⍺ re ⍵
[8] ⍝ Phil Last ⍝ 2008-06-09 23:58
[9] }
∇
∇ rn←{⍺←⊢
[1] ⊃if(0∘=∘⍴∘⍴){⍵↑¨⍨{+/(⍵≠' ')∧2>+\'.'=⍵}↑⍵}⊂if≡⍵
[2] ⍝ ⍵ name(s) '#.a.b.c.d' '#.x.y.z'
[3] ⍝ ← rootname(s) '#.a' '#.x'
[4] ⍝ depth 1 or 2
[5] }
∇
∇ rp←{
[1] ⍵↓⍨(≢⍺)×⍺≡(≢⍺)⍴⍵
[2] ⍝ remove prefix ⍺ from ⍵
[3] ⍝ 'ABC' rp ⎕A → 'DEFGHIJKLMNOPQRSTUVWXYZ'
[4] ⍝ 'abc' rp ⎕A → 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
[5] }
∇
∇ rs←{
[1] f←⊢(/⍨)(1+1∊'#⎕'∊⊢)>(+\'.'=⊢)
[2] 0=10|⎕DR ⍵:f ⍵
[3] ⍎f⍕⍵
[4]
[5] ⍝ root space
[6] ⍝ ⍵ ref or fqn
[7] ⍝ ← ref or fqn as ⍵
[8] ⍝ if ⍵ is #, ⎕se, #.sub or ⎕SE.sub
[9] ⍝ then ⍵
[10] ⍝ else (# or ⎕SE).sub that contains ⍵
[11] ⍝ longest prefix containing less than two dots
[12] }
∇
∇ ru←{0::''
[1] 1↓⊃,/(⎕UCS 13),¨0⊃'UTF-8'⎕NGET ⍵ 1
[2] ⍝ read unicode
[3] ⍝ ⍵ filepath
[4] ⍝ read UTF-8 file with CR (U+000D)
[5] }
∇
∇ sa←{
[1] b←=∘⍵⍣(0=≡⍺)⊢⍺
[2] 1↓¨(1,b)⊂' ',⍵
[3] ⍝ split at
[4] ⍝ ⍺ scalar char or boolean length of ⍵
[5] ⍝ ⍵ string
[6] ⍝ ← ⍵ split at 1s in ⍺ or where ⍵=⍺
[7] }
∇
∇ sc←{
[1] ⍺←⊢
[2] sc←{⍺←⊢
[3] (0∊⍴r←⍺ fi ⍵):0 2⍴r
[4] r←r/⍨1=≡∘vr¨r
[5] {(+/∨\' '≠⌽⍵)↑⍵}¨↑{⍵⊂⍨{⍵∧2≥+\⍵}2</0,⍵≠' '
[6] }¨⊃,/'' '',(⊃ec ⍵)∘{⍵∘,¨⍺∘{⍵/⍨⍺∘{1∊⍺⍷⍵}¨⍵}≠∘CR pt vr ⍵}¨r
[7] }
[8] 1=≡⍵:⍺ sc ⍵
[9] ↑∪↓⊃⍪/⍺∘sc¨⍵
[10] ⍝ search & show
[11] ⍝ ⍺ & ⍵ args to fi but ⍵ has to be a simple positive search so the entire
[12] ⍝ string is to be found as is within the target. No logical wildcards.
[13] ⍝ All potential control chars to be escaped.
[14] ⍝ ← each line of each item that contains the string.
[15] }
∇
∇ se←{
[1] fac←∇{⍵≤9:2 ⋄ ⍺⍺⌈⍵*÷2}⍵
[2] res←~⍵↑1 1
[3] res/⍳⍵⊣⍵{
[4] ⊢res[⍵×⍵↓⍳⌈⍺÷⍵]←0
[5] }¨fac
[6] ⍝ sieve of Eratosthenes
[7] ⍝ was ...
[8] n←24 60 60 1000
[9] td←{(#.DateToIDN 3⍴⍵)+(n⊥3↓⍵)÷×/n}
[10] dt←{(3⍴#.IDNToDate⌊⍵),⌊n⊤(1|⍵)××/n}
[11] (dt(td ⎕TS)-(⌈/⎕AI)÷×/n)((0,n)⊤⌈/⎕AI)
[12] ⍝ session start & duration
[13] ⍝ ⍵ null
[14] ⍝ ← start: y m d h m s m, duration: d h m s m
[15] ⍝ Phil Last ⍝ 2008-02-04 18:13
[16] }
∇
∇ sf←{
[1] ⎕ML←0
[2] aA0←(~∘' ''',(/⍨∘(≠\∘(''''∘=))⍨ps ⍵),ab'')∘{⍵{⍵\⍵/⍺}⍵∊⍺}
[3] ⍺←#
[4] 0::((⊃⎕DM),' - Try escaping "',(⍵∩'(~<≤=≥>≠∨∧⍱⍲)\'),'"')⎕SIGNAL ⎕EN
[5] ('1∊⍵⍷⍨'ps ⍵){⍵/⍨⍺∘{⍺{⍎⍺}aA0,⍕⍵{
[6] (⍵∊3 4):⎕VR ⍺
[7] (⍵=2):⍎⍺
[8] (⍵=9):⎕SRC⍎⍺
[9] ''
[10] }⎕NC ⍵}¨⍵}{
[11] (''≢0⍴⍵):⍵ li 3 4 9.4
[12] ⍵ lf # li 3 4 9.4
[13] }⍺
[14] ⍝ syntax find
[15] ⍝ ⍺ ref - search all in or below
[16] ⍝ string - wildcard selection of candidates anywhere
[17] ⍝ ⍵ search string - can contain executables "(~<≤=≥>≠∨∧⍱⍲)". see ps
[18] ⍝ ← fully qualified names of arrays, fns, ops & classes where found.
[19] ⍝ Phil Last ⍝ 2008-03-12 19:30
[20] }
∇
∇ sg←{
[1] ⍵{⍵×⌊0.5+⍺÷⍵}10*-⍺-1+⌊10⍟|⍵+⍵=0
[2] ⍝ significant figures
[3] ⍝ ⍺ int(s)
[4] ⍝ ⍵ float(s)
[5] ⍝ ← (⍵) "rounded" to (⍺) sig figs
[6] ⍝ this is a scalar function
[7] ⍝ Phil Last ⍝ 2008-08-01 10:29
[8] }
∇
∇ sh←{
[1] {w}'w'⎕WC w←'OLECLIENT' 'WScript.Shell'
[2] ⍝ windows shell object
[3] ⍝ ⍵ ?
[4] ⍝ ← windows shell object
[5] }
∇
∇ si←{⍺←⊢
[1] {⍺,,('P<[>Q<]>I',⍕3+⌊10⍟1⌈⍵)⎕FMT ⍵}/1↓⍉↑⎕XSI ⎕LC
[2] ⍝
[3] ⍝ Phil Last 2017-12-05 20.15
[4] }
∇
∇ sl←sl
[1] sl←⊣(1↓¨=⊂⊢),
[2] ⍝ separated string to list without sep
[3] ⍝ nilad returning dyad
[4] ⍝ Phil Last 2017-12-19 07.35
∇
∇ sm←{⍺←⊢
[1] (ns<9<⎕NC)sp¨⊂if≡⍵
[2] ⍝ script member
[3] ⍝ Phil 2018-01-28 18.16
[4] }
∇
∇ sn←sn
[1] ns<9≤⎕NC
[2] ⍝ ⍵ fqns
[3] ⍝ ← boolean which are scripted spaces
∇
∇ so←{
[1] ⍵⊣(⎕NS'').(⎕ED&{'n'}n←⍕1 ##.ty↑n∘,¨↓'.',⍵.⎕NL 2 3 4⊣n,←'s'/⍨~n/⍨←~'['∊n←⍕s←⍵)
[2] ⍝ edit all objects in space:
[3] ⍝ Phil Last ⍝ 2008-03-12 08:32
[4] }
∇
∇ sp←sp
[1] sp←1⊃⎕NPARTS
[2] ⍝ space path
[3] ⍝ monad
[4] ⍝ '#.a.b.c' → '#.a.b'
[5] ⍝ '#.a.b' → '#.a'
[6] ⍝ '#.a' → '#'
[7] ⍝ '#' → '#'
∇
∇ sq←{
[1] ⍺←1
[2] cols←1⌈⌊0.5+{(⌈(⍺×⍵)*÷2)÷⍵}/⍺ 1×2 1×⍴⍵
[3] ↑,/⍉cols rows⍴(cols×rows←⌈(⍬⍴⍴⍵)÷cols)↑↓⍵
[4] ⍝ square
[5] ⍝ reshape text column to nearest ⍺ rectangular display
[6] ⍝ default square (1) - 2 gives 2×width
[7] }
∇
∇ su←{ft'⍝- '
[1] ⍝- :Class suicide
[2] ⍝- ∇ inst←New(fn arg)
[3] ⍝- :Access public shared
[4] ⍝- inst←(⍬⍴⎕RSI).⎕NEW ⎕THIS
[5] ⍝- ∇
[6] ⍝-
[7] ⍝- ∇ coroner
[8] ⍝- :Implements destructor
[9] ⍝- (##.⍎fn)arg
[10] ⍝- ∇
[11] ⍝- ⍝ set a destructor on an ordinary container space.
[12] ⍝- ⍝ call as: condemned.inst←suicide.New fn arg
[13] ⍝- ⍝ named fn (accessible from space calling New) will be
[14] ⍝- ⍝ applied to arg when space - condemned - is destroyed.
[15] ⍝- ⍝ Phil Last ⍝ 2013-06-29 10:31
[16] ⍝- :EndClass
[17] }
∇
∇ sv←{⍺←⊢
[1] q←⊃(⍺,⍵,q)∩q←'"'''
[2] w←⍵\⍨{~≠\⍵/⍨1+⍵}∨/¯1 0⊖(⊢(>,⍤0∧)≠\)⍵=q
[3] ~∘q¨~∘∊⍨{1↓¨⍵⊂⍨(⍵=' ')>≠\q=⍵}' ',w
[4] ⍝ blank separated string to vector of words and quoted substrings
[5] ⍝ [⍺] override quote
[6] ⍝ ⍵ string
[7] ⍝ ← list of "words" which may include quoted blanks.
[8] ⍝ quote is first encountered of '"' and "'"
[9] ⍝ unless overridden by ⍺ and all are removed.
[10] ⍝ '1 23 asd "two words"' → '1' '23' 'asd' 'two words'
[11] }
∇
∇ sw←{
[1] ⍺←#
[2] sw←{(2↓⊃,/' ','∨',¨⍺ sf' ',⍵,' ')sc ⍵}
[3] 1=≡⍵:⍺ sw ⍵
[4] ↑∪↓⊃⍪/⍺∘sw¨⍵
[5] ⍝ search word
[6] ⍝ ⍺ target ns
[7] ⍝ ⍵ target word
[8] ⍝ ← all occurrences including as a substr
[9] ⍝ in items that contain the word alone
[10] }
∇
∇ sx←{
[1] ⍺←⊢
[2] s←⊃{⍺,'∨',⍵}/⍺ fi ⍵
[3] t←{1↓¨⍵⊂⍨⍵=''''}{⍵/⍨≠\⍵=''''}ps ⍵
[4] {⍵⌿⍨~>/'⍝'=↑⊢/⍵}↑∪↓⊃⍪/s∘sc¨t
[5]
[6] ⍝ search executable (not in comments
[7] }
∇
∇ sz←{⍺←⊢
[1] c←⍺⊣' '
[2] ⍵/⍨~(2⍴c)⍷⍵
[3] ⍝ squeeze
[4] ⍝ [⍺] alternative char to blank
[5] ⍝ ⍵ string
[6] ⍝ ← ⍵ without multiple char. Single leading and trailing not removed.
[7] ⍝ Phil Last ⍝ 2008-01-13 12:22
[8] }
∇
∇ tb←{
[1] ⍵↓⍨-+/∧\' '=⌽⍵
[2] ⍵↓⍨-⊥⍨⍵=' '
[3] ⍝ remove trailing blanks
[4] ⍝ ⍵ string
[5] ⍝ ← ⍵ ~ trailing blanks
[6] ⍝ Phil Last ⍝ 2008-01-15 00:55
[7] }
∇
∇ tc←{
[1] ⍝ maj←min←+
[2] ⍝ z←'maj' 'min'{⍺ ⎕NA'I4 USER32.C32|Char',⍵,'* =0T'}¨'Upper' 'Lower'
[3] ⍝ case←{(⍴⍵)⍴⊃⌽⍺⍺⊂,⍵}
[4] maj min←1 0
[5] ⍺←2
[6] ⍺=1:min cc ⍵
[7] ⍺=2:maj cc ⍵
[8] f←{
[9] ⍺=1:min cc ⍵
[10] ⍺=2:maj cc ⍵
[11] ⍺=3:⍵{(⍴⍺)⍴(2</0,≠⌿⍵)⊖⍵}↑(1 ∇ ⍵)(2 ∇ ⍵)
[12] ⍺≠3:⍵{(⍴⍺)⍴(⍺=(⍴⍺)⍴⍵)⊖⍵}↑(1 ∇ ⍵)(2 ∇ ⍵)
[13] }
[14] 1≠≡⍵:⍺∘f¨⍵
[15] ⍺ f ⍵
[16] ⍝ type case
[17] ⍝ ⍺ 1 - convert to minuscule
[18] ⍝ ⍺ 2 - CONVERT TO MAJUSCULE - dflt
[19] ⍝ ⍺ 3 - Capitalise - convert to minuscule;
[20] ⍝ Initials To Majuscule
[21] ⍝ otherwise SWITCH case
[22] ⍝ ⍵ simple text array or depth 2 or ¯2
[23] ⍝ ← ⍵ converted according ⍺
[24] ⍝ Phil Last ⍝ 2008-01-22 21:26
[25] }
∇
∇ tl←{
[1] s←⍴⍵ ⍝ shape
[2] k←≢s ⍝ rank
[3] c←1+(-k)↑¯1+⍺ ⍝ cell
[4] ⊃{s k c←⍺ ⍝ per dim
[5] ↑(s⍴c↑1)∘(⊂[k])¨⍵ ⍝ partition
[6] }/(⌽↓s,(⍳k),⍪c),⊂⊂⍵ ⍝ fold left
[7] ⍝ tessellate
[8] ⍝ ⍺ shape of sub arrays
[9] ⍝ ⍵ multi-d array
[10] ⍝ ← nested array of ⍺ shaped subarrays of ⍵
[11] ⍝ if ⍺ is shorter than rank ⍵ it is padded at left with ones.
[12] ⍝ if any ⍺ is not a factor of the corresponding item of ⍴⍵,
[13] ⍝ trailing cells are truncated.
[14] }
∇
∇ tm←{
[1] n←1≠≡⍵
[2] d←,⊂⍣n,'...'
[3] o←⍴d
[4] f←⌽⍣(⍺<0)
[5] w←(|⍺)⌊⍴⍵
[6] t←w<⍴⍵
[7] 1:f w⍴((w-t×o)↑f ⍵),d
[8] ((|⍺)⌊⍴⍵)(⌽⍣(⍺<0)){⍺⍺ ⍺{⍺⍴(⍵⍴⍨⍺-3×⍺<⍴⍵),(⍳1=≡⍵)⊃3 2 1⍴¨'.'}⍺⍺ ⍵}⍵
[9] ⍝ truncate message or list
[10] ⍝ 10 ¯10 9 ¯9 tm¨⊂⎕D
[11] ⍝ 0123456789 0123456789 012345... ...456789
[12] ⍝ nms← 'one' 'two' 'three' 'four' 'five' 'six' 'seven' 'eight' 'nine' 'ten'
[13] ⍝ ⍪ 8 ¯8 tm¨⊂nms
[14] ⍝ one two three four five six seven ...
[15] ⍝ ... four five six seven eight nine ten
[16] }
∇
∇ tp←{
[1] ⎕THIS.tp←⍎(×⎕ML)⊃'∊' '⊃∘(⍬∘⍴)∘(0∘⍴)∘⊂'
[2] tp ⍵
[3] }
∇
∇ tr←{
[1] {(+/∧\' '=⍵)↓⍵}∘⌽⍣2⊢⍵
[2] ⍵/⍨{(∨\⍵)∧⌽∨\⌽⍵}⍵≠' '
[3] ⍝ trim leading and trailing blanks
[4] }
∇
∇ tv←{
[1] n←⎕NS''
[2] w d←ht es ⍵
[3] n.d←d
[4] {(+/∨\' '≠⌽⍵)↑¨↓⍵}n ⍺.{
[5] (⊂⍵)∊⍺.d:⍵
[6] ⍺.d,←⊂⍵
[7] f←(~∘' '¨↓(⊢(⌿⍨)3 4∊⍨⎕NC)⎕REFS ⍵)~⊂⍵
[8] ⍕⍵,⊂'|',⍕⍪∇/⍺,⍪f
[9] }w
[10] ⍝ tree view of function calls
[11] ⍝ ⍺ namespace wherein -
[12] ⍝ ⍵ function/operator-name
[13] ⍝ ← (large) nested text array
[14] }
∇
∇ ty←{
[1] ⍺←0
[2] ⍺{
[3] (dim pw)←2⍴⍺,(⍴,⍺)↓0,⎕PW
[4] sw←dim≠0
[5] len wid←⍴⍵
[6] cols←1⌈⌊|pw÷wid+2
[7] rows←⌈len÷cols
[8] len←cols×rows
[9] (⍒sw×⍳2)⍉(sw⌽rows cols)⍴↓len wid↑⍵
[10] }↑,↓↑⍵
[11] ⍝ tidy
[12] ⍝ ⍵ 2d or nested list - names - whatever
[13] ⍝ ← 2d text in columns
[14] ⍝ Phil Last ⍝ 2008-03-02 19:21
[15] }
∇
∇ uc←{
[1] 1 ll ⍵
[2] ⍝ upper case clone
[3] ⍝ ⍵ space with vars
[4] ⍝ ← space as ⍵ but all vars are upper case
[5] }
∇
∇ um←{
[1] (⍵⍳⍵)=⍳⍴⍵
[2] ⍝ unique mask
[3] ⍝ ⍵ vector
[4] }
∇
∇ ur←{
[1] fqn←⍵ li 3.1 3.2 4.1 4.2
[2] refs←{(+/∨\' '≠⌽⍵)↑¨↓⍵}∘⎕REFS¨fqn
[3] all←
[4] ⍝ unreferenced names
[5] ⍝ ⍵ space?
[6] ⍝ ← fqn ref - corresponding FQN and unref'd word
[7] ⍝ Phil Last 2017-05-18 08.40
[8] }
∇
∇ us←{⍺←⊢
[1] ('n'⎕NS ⍵)⊢n←⍎⍣(1≢⍺ 1)⊢⍺ #.⎕NS''
[2] ⍝ unscript
[3] ⍝ [⍺] optional fqn for result
[4] ⍝ ⍵ scripted space
[5] ⍝ ← [named] space containing first level members of space
[6] ⍝ Phil Last 2015-04-22
[7] }
∇
∇ uu←{
[1] ⍺←#
[2] ⍺{⍵/⍨⍵{0∊⍴⍵~⊂⍺}¨⍺ sf¨{' ',⍵,' '}∘('.'∘nn)¨⍵}(/⍨)∘(0∘<∘⎕NC)⍨⍵ li 3 4
[3] ⍝ unused
[4] ⍝ ⍺ space to search - dflt #
[5] ⍝ ⍵ space to list
[6] ⍝ ← fns & ops in (⍵) NOT called from anywhere in (⍺)
[7] }
∇
∇ vc←{⍺←CR
[1] 1↓⍺{⍵/⍨~(3⍴⍺)⍷⍵}{(,⌽∨\⌽⍵≠' ')/,⍵}⍺,⎕FMT cm⍣(1≠≡⍵)⊢⍵
[2] ⍝ varchar
[3] ⍝ ⍵ char array - more or less any
[4] ⍝ ← [newline] delimited string
[5] ⍝ no trailing blanks in substrings of which no consecutive empties
[6] }
∇
∇ vr←{
[1] 2=⎕NC ⍵:{
[2] 1 1≡(≡⍵),⍴⍴⍵:⍵
[3] 1↓⊃,/CR,⎕FMT ⍵
[4] }⍎⍵
[5] 3 4∨.=⎕NC ⍵:⎕VR ⍵
[6] 0::'∇ ','.'nn ⍵
[7] {1↓⊃,/,/CR,('P<[>Q<]>LI6'⎕FMT⍳⍴⍵),⍵}⎕SRC⍎⍵
[8] ⍝ vector representation of function/operator/class/namespace
[9] }
∇
∇ wf←{
[1] ⍺{(⎕NUNTIE ⍵)⊢⍺ ⎕NAPPEND ⍵,⎕DR ⍺}{
[2] 22::0 ⎕NRESIZE ⍵ ⎕NTIE 0
[3] ⍵ ⎕NCREATE 0
[4] }⍵
[5] ⍝ write file
[6] ⍝ ⍺ data in form it can be written as-is - char or num vec
[7] ⍝ ⍵ file path/name if exists is resized to zero first
[8] ⍝ ← bytes written
[9] ⍝ Phil Last ⍝ 2008-06-12 8:40
[10] }
∇
∇ wi←{
[1] ⎕ML←0
[2] ⊃∧/(' ',⍺,' ')∘{∨/⍵⍷⍺}¨{⍵{(⍵/⍵>¯1↓0,⍵)⊂⍵/⍺}⍵≠'*'}{⍵{(⊃⍵)⌽⍺,⍨⍵/' '}2⍴¯1⌽'*'≠⍵}tr ⍵
[3] ⍝ wild
[4] ⍝ ⍺ text table
[5] ⍝ ⍵ wild card - one of - '*' 'pre*' '*mid*' 'pre*mid*' '*end' 'pre*end' '*mid*end' 'pre*mid*end'
[6] ⍝ ← boolean per row matches
[7] ⍝ Phil Last ⍝ 2008-01-07 09:19
[8] }
∇
∇ wp←{
[1] s←0⊃'\/'{(⍵∩⍺),⍺}ws←⎕WSID
[2] (w p)←ws{(⍵↓⍺)(⍵↑⍺)}-(⌽ws)⍳s
[3] ((0∊⍴w)⊃w('.',s))((p⍳'.')↑p)
[4] ⍝ path/name of ⎕wsid
[5] ⍝ e.g.
[6] ⍝ ⎕wsid ←→ 'C:\FlipDB\Wss\Acne.DWS'
[7] ⍝ ← 'C:\FlipDB\Wss\' 'Acne'
[8] ⍝ ⎕wsid ←→ 'Acne.DWS'
[9] ⍝ ← '' 'Acne'
[10] }
∇
∇ ws←{
[1] nsn←{⊃⍵~⍨'f'∘,∘⍕¨⍳1+⍴⍵}~∘' '¨↓#.⎕NL⍳10 ⍝ named in root e.g. 'f0'
[2] cpy←⍎nsn ⎕NS'' ⍝ create it - cpy is ref
[3] sws sns←⍵ ⍝ source ws & ns
[4] z←sns{6::0 ⋄ +{}⍺ cpy.⎕CY ⍵}sws ⍝ ← populate ref
[5] rfs nss/⍨←⊂ns⊢nss←⍕¨rfs←1↓nt cpy ⍝ named non scripted ns-tree
[6] tns←(⍕⍺)∘,¨(2+⍴nsn)↓¨nss ⍝ swap to target prefix (⍺)
[7] tns←⊃rfs.{⍵ ⎕NS ⎕NL 2 3 4}tns ⍝ copy vars fns & ops for each ns
[8] {tns}#.⎕EX nsn ⍝ lose global root ns 'f0'?
[9] ⍝ wscopy
[10] ⍝ ⍺ ref of namespace in active ws (obviously)
[11] ⍝ ⍵ two strings (wspath)(nspath)
[12] ⍝ ← name of namespace being the name of the target parent (⍺)
[13] ⍝ followed by the final node of the source path
[14] ⍝ only contents of named & non-scripted nss are copied.
[15] ⍝ Items in target but not in source are kept.
[16] ⍝ e.g. '#.one.two.three' ws 'c:\wss\that' '#.AAA.BBB'
[17] ⍝ #.one.two.three.BBB
[18] }
∇
∇ wu←{
[1] ⊢⍺'UTF-8' 13 ⎕NPUT ⍵ 1
[2] ⍝ write unicode
[3] ⍝ ⍺ simple text with CR (U+000D)
[4] ⍝ ⍵ filepath
[5] ⍝ write UTF-8 file
[6] }
∇
∇ xc←{⍺←⊢
[1] char←⍬⍴⍺⊣NB
[2] {⊢/(⍵=' ')⌽char,⍪⍵}⍵{(~⊃⍵)↓⍵\⍺}{(1+⍳⌈/⍵)∊⍵}+\1+{⍵>¯1↓0,⍵}⍵∊⎕A
[3] ⍝ expand camel case name
[4] ⍝ not before capital initial
[5] ⍝ not between multiple caps
[6] ⍝ xc'MrJJSmithLivedHere'
[7] ⍝ Mr JJSmith Lived Here
[8] }
∇
∇ xn←{⍺←⊢
[1] (⎕NC,∘⊂∘↑⌸⊢)↓(df ⍵),⍤1⊢'.',⍵.⎕NL⍳11
[2] ⍝ extended namelist
[3] ⍝ fqns for each nc in space ⍵
[4] }
∇
Operators:
∇ ad←{⍺←⊢
[1] d←1≢⍺ 1 ⍝ dyadic?
[2] (|≡⍺ ⍵)>d+|⍵⍵⊣⍵:⍺ ∇¨⍵ ⍝ if dyad, juxtaposition of ⍺ ⍵ adds 1 to |≡
[3] ⍺ ⍺⍺ ⍵
[4] ⍝ at depth
[5] ⍝ ⍺ [array]
[6] ⍝ ⍵ array
[7] ⍝ ⍺⍺ function to run at ...
[8] ⍝ ⍵⍵ depth or {depth}
[9] ⍝ ← ⍺ ⍺⍺ ⍵ or ⍺(⍺⍺ ad ⍵⍵)¨⍵ if arg(s) too deeply nested
[10] ⍝ Phil Last ⍝ 2008-07-04 09:14
[11] }
∇
∇ am←{⍺←⊢
[1] W⊣W[i]←⍺ ⍺⍺⊣W[i←(⊂⍴W)|⍵⍵⊣⍳⍴W←⍵]
[2] ⍝ amend - [⍺](mod amend sel)⍵
[3] ⍝ [⍺] larg to ⍺⍺
[4] ⍝ ⍺⍺ modifier of selection of ⍵ or replacement thereof
[5] ⍝ ⍵⍵ selection function on ⍳⍴⍵ or selection thereof
[6] ⍝ ⍵ data to be amended
[7] }
∇
∇ as←{
[1] (2>0⊥⍴⍵):⍵
[2] ⌽↑⍺⍺{(⊂(⊃⍵)⍺⍺ ⍺),⍵}/⌽(⊂∘⊃¨↓⍵),↑1↓¨↓⍵
[3] ⍝ associative scan
[4] ⍝ ⍺⍺ dyad
[5] ⍝ ⍵ array
[6] ⍝ ← last dimension associative ⍺⍺ scan of ⍵
[7] ⍝ ⍺⍺ as w x y z ←→ w (w ⍺⍺ x) ((w ⍺⍺ x)⍺⍺ y) (((w ⍺⍺ x)⍺⍺ y)⍺⍺ z)
[8] ⍝ so can be calculated in a single left to right sweep
[9] ⍝ Phil Last ⍝ 2008-03-04 15:03
[10] }
∇
∇ ax←{⍺←⊢
[1] mon←1≡⍺ 1
[2] rx←mon⊃2⌽(mx lx rx)←,¨⌽3⍴⌽⍵⍵
[3] pre←{k←⍴⍴⍺
[4] ×⍴f←⍵~⌊⍵:(⍺⍴⍨1+(¯1+⍴⍺)\⍨~(⍳k+⍴f)∊⌈f)∇⌈⍵++/⍵∘.>f
[5] (×⍵)≡,¯1:⍺ ∇(⍳k)~|⍵
[6] t←⍋⍒(⌽⍵)⍳⍳k
[7] ⍺ t
[8] }
[9] post←{(⍋⍋(⍴⍴⍵)↑1+⍋⍺)⍉⍵}
[10] (ra rt)←⍵ pre rx
[11] mon:rt post ⍺⍺⍤(⍴rx)⊢rt⍉ra
[12] (la lt)←⍺ pre lx
[13] (la ra)←lt rt⍉¨la ra
[14] (lc rc)←⊃∘⍴¨lx rx
[15] (lr rr)←⊃∘⍴∘⍴¨la ra
[16] r←la ⍺⍺⍤lc rc⊢ra
[17] t←(⍳∘(⌈/)⍨lr rr)⊃lt rt
[18] t post r
[19] ⍝ axis
[20] ⍝ ⍺ optional left arg
[21] ⍝ ⍺⍺ function to apply
[22] ⍝ ⍵⍵ axes treated as ⌽3⍴⌽⍵⍵
[23] ⍝ ⍵ right arg
[24] ⍝ Each item of ⍵⍵ can be a scalar or vector of zero or more
[25] ⍝ elements. A negative scalar n represents (⍳⍴⍴arg) ~ |n.
[26] ⍝ A fractional axis f inserts a new unit dimension between
[27] ⍝ ⌊f and ⌈f in the argument's shape.
[28] ⍝ Arguments ⍺ & ⍵ are transposed to bring specified axes
[29] ⍝ within the scope of the rank operator where they define
[30] ⍝ the cells to which function ⍺⍺ will be applied.
[31] ⍝ The result is transposed in an attempt to replace the axes
[32] ⍝ in the positions they occuplied in the original argument
[33] ⍝ of the higher rank.
[34] }
∇
∇ ba←{
[1] ⍺ ⍺⍺{2⊥⍺⍺/2⊥⍣¯1⊢⍺,⍵}¨⍵
[2] 2⊥⍺⍺/2⊥⍣¯1⊢⍺,[⎕IO-0.1]⍵
[3] ⍝ binary arithmetic
[4] }
∇
∇ cf←{⍺←⊢
[1] {11::⌊/⍳0 ⋄ ÷/⍵}1(⊢∘(⍺∘⍺⍺)∘⍵){
[2] ⊃∇/⍺{
[3] (1000<+/⍵)↓(2×⍺)⍵
[4] }(⍬⍴2↓⎕AI-(⊢∘⍺⍺/⍳1+⍺)⊢⎕AI)(⍬⍴2↓⎕AI-(⊢∘⍵⍵/⍳1+⍺)⊢⎕AI)
[5] }(⊢∘(⍺∘⍵⍵)∘⍵)1
[6] ⍝ compare
[7] ⍝ a f cf g w ←→ (a f time w) ÷ a g time w
[8] ⍝ f cf g w ←→ ( f time w) ÷ g time w
[9] ⍝ Phil Last ⍝ 2007-06-23 20:07
[10] }
∇
∇ cf0←{
[1] ⍺←⊢ ⋄ a←⍺ ⋄ w←⍵ ⋄ f←⍺⍺ ⋄ g←⍵⍵
[2] (↑'⍺ ⍺⍺ ⍵' '⍺ ⍵⍵ ⍵'),0 7↓cmpx'a f w' 'a g w'
[3] }
∇
∇ cond←{⍺←⊢ ⋄ (1=⍺⊣0):⍺⍺⊣⍵ ⋄ (0=⍺⊣1):⍵⍵⊣⍵ ⋄ (1 ⍺⍺ ⍵):0 ⍺⍺ ⍵ ⋄ ⍵⍵⊣⍵}
∇
∇ cp←{
[1] ⍺←⍵
[2] ⍺∘.⍺⍺ ⍵
[3] ⍝ MUCH quicker if ⍺⍺ is not primitive even with ¨
[4] (⍉((⍴⍵),⍴⍺)⍴⍉⍺)⍺⍺((⍴⍺),⍴⍵)⍴⍵
[5] ⍝ MUCH quicker with multiple identical items and pure function ⍺⍺
[6] i j←∪∘,¨⍺ ⍵
[7] (i⍳⍺)(j⍳⍵)⌷i∘.⍺⍺ j
[8] ⍝ cartesian product
[9] ⍝ Phil Last ⍝ 2006-10-02 20:29
[10] }
∇
∇ cs←{
[1] ⍺←⍵
[2] ⍵ ⍺⍺{⍵ ⍺⍺(⍴⍵)⍴⍺}⍉(⌽(⍴⍺),⍴⍵)⍴⍉⍺
[3] ⍝ cartesian product of scalar function
[4] ⍝ Phil Last ⍝ 2007-06-17 10:33
[5] }
∇
∇ do←{
[1] (⍵⍵ if ⍺⍺)⍵
[2] ⍝ [if] antecedent [then] do consequent [else do nothing]
[3] ⍝ see if
[4] }
∇
∇ dv←{⍺←⊢
[1] ⍕{
[2] ⊃,/{
[3] 0=≡⍵:⍵
[4] 0∊⍴⍵:((''⍬ ⍵)⍳⊂⍵)⊃'''''' '⍬'⍵
[5] 1=≡⍵:'(',,∘')'⊃,/,⍵
[6] ⊃,/'(',,∘')'∇¨⍵
[7] }⍵
[8] }⎕CR(f←⍺⍺)/'f'
[9] ⍝ ⍺⍺ derv
[10] ⍝ ← executable text-string representation of ⍺⍺
[11] ⍝ sometimes adds too many parens but would need MUCH more analysis not to
[12] }
∇
∇ ea←{
[1] f←⍺⍺
[2] ⍺←(f←⊢∘⍺⍺)/0
[3] f⌿⍺,[-0.1]⍵
[4] ⍝ each
[5] ⍝ [⍺] ⍵-conformable array
[6] ⍝ ⍵ array
[7] ⍝ ⍺⍺ function to apply to each item of ⍵ or
[8] ⍝ between corresponding items of ⍺ and ⍵
[9] ⍝ but no spurious application to empties
[10] }
∇
∇ ei←{
[1] ⍺←⊢
[2] (1=≡⍵):⍺ ⍺⍺ ⍵
[3] ⍺ ⍺⍺¨⍵
[4] ⍝ each if not simple
[5] ⍝ ⍺ ?
[6] ⍝ ⍵ ?
[7] ⍝ ⍺⍺ function to run on simple ⍵
[8] ⍝ ← [⍺]⍺⍺ ⍵ or [⍺]⍺⍺¨⍵ but not recursively
[9] }
∇
∇ el←{
[1] ⍺:⍺⍺⊣⍵
[2] ⍵⍵⊣⍵
[3] ⍝ r←(proposition consequence el alternative ⊢)⍵
[4] ⍝ r←{proposition ⍵: consequence⊣⍵ ⋄ alternative⊣⍵}⍵
[5] ⍝ :If proposition ⍵ ⋄ r←consequence⊣⍵ ⋄ :Else ⋄ r←alternative⊣⍵ ⋄ :EndIf
[6] ⍝ proposition, consequence and alternative all monads on ⍵
[7] ⍝ or consequence and alternative may be arrays.
[8] ⍝ ⍵ in domain of proposition and functions consequence and alternative
[9] ⍝ ← result of consequence or alternative according proposition
[10] }
∇
∇ r←(f ep)r
[1] ⍝ en passant
[2] f r
∇
∇ et←{ ⍝ and
[1] ⍺⍺⊣⍵:⍵⍵ ⍵ ⋄ 0
[2] ⍝ f0 et f1 et f2 et ... ⍵
[3] ⍝ ⍵ any array in domain of f0
[4] ⍝ f0 f1 f2 &c. are monadic tests on ⍵, but each subsequent
[5] ⍝ test will only run if its predecessor returns true.
[6] ⍝ ← 1 | 0 - whether or not all are true
[7] ⍝ see ou
[8] }
∇
∇ eu←{
[1] (⊂u⍳⍵)⌷⊢∘⍺⍺/0,⍪u←∪⍵
[2] (⊂u⍳⍵)⌷⍺⍺¨u←∪⍵
[3] ⍵ ⍺⍺¨{(⊂⍵⍳⍺)⌷⍺⍺ ⍵}∪⍵
[4] ⍝ each unique
[5] ⍝ ⍺⍺ fn to run on each item of ⍵
[6] ⍝ ⍵ vector
[7] ⍝ ← equivalent of ⍺⍺¨⍵ ⍝ ***
[8] ⍝ but having run ⍺⍺ on only a single
[9] ⍝ instance of each unique value of ⍵
[10] ⍝ *** and not at all if none.
[11] ⍝ a fixed left arg can be composed with ⍺⍺ as in:
[12] ⍝ larg∘fn eu rarg
[13] ⍝ Phil Last 2016-10-24
[14] }
∇
∇ ff←{⍺←⊢
[1] 22::⎕SIGNAL/⌽⎕EN,⎕DM
[2] ⍺∘⍺⍺{(⎕FUNTIE⊃⍵)⊢⍺⍺ ⍵}{(⎕FSTIE∘0⊃⍵),1↓⍵}⊂if≡⍵
[3] ⍝ ⎕ffile function
[4] ⍝ ⍺ [larg] to
[5] ⍝ ⍺⍺ ⎕ffunction, ⎕FREAD, ⎕FSIZE, ...
[6] ⍝ ⍵ filename and rest of rarg to ⍺⍺ usually after tie number
[7] ⍝ thus - vector ⎕FAPPEND¨ff⊂'myfile' - appends items of vector as components
[8] ⍝ Phil Last ⍝ 2007-06-25 07:53
[9] }
∇
∇ fk←{⍺←⊢
[1] (m d)←'monadic left fork' 'dyadic left fork'
[2] m≡⍺ m:m ⍺⍺ ⍵(⍵⍵ ⍵)
[3] ⍺≡m:(⍺⍺ 0⊃⍵)⍵⍵ 1⊃⍵
[4] ⍺≡d:(⊃⍺⍺/0⊃⍵)⍵⍵ 1⊃⍵
[5] d ⍺⍺(⍺ ⍵)(⍺ ⍵⍵ ⍵)
[6] ⍝ fork
[7] ⍝ f fk g fk h ⍵ ←→ ( f ⍵)g( h ⍵)
[8] ⍝ ⍺ f fk g fk h ⍵ ←→ (⍺ f ⍵)g(⍺ h ⍵)
[9] ⍝ applies g between the results of f and h having
[10] ⍝ applied each to ⍵ or between ⍺ and ⍵
[11] ⍝ Phil Last ⍝ 2007-06-23 18:47
[12] }
∇
∇ fl←{
[1] ⊃⍺⍺⍨/⌽(⊂⍺),⍵
[2] ⍝ for loop (fold left)
[3] ⍝ a f fl w x y z ←→ ((((a f w)f x)f y)f z)
[4] ⍝ Phil Last ⍝ 2007-06-23 18:55
[5] }
∇
∇ fs←{
[1] (3=⍴⍵):(0⊃⍵)⍺⍺⊃⍵⍵/1↓⍵
[2] ⍺⍺(¯2↓⍵),⍵⍵/¯2↑⍵
[3] ⍝ function sequence
[4] ⍝ f fs g fs h ... a b c d ... ←→ a f b g c h d ...
[5] ⍝ nb. all sequenced functions are dyadic;
[6] ⍝ the derived function is monadic.
[7] ⍝ Phil Last ⍝ 2007-06-23 16:51
[8] }
∇
∇ fv←{
[1] 0::⎕SIGNAL/⌽⎕EN,⎕DM
[2] ⍺←⊢
[3] m←⍵≡⍺ ⍵
[4] (W A)←↓⍵,[-0.1]⍺⊣0
[5] t←2=⍴W
[6] m∧t:(⍺⍺ 0⊃W)(⍵⍵ 1⊃W)
[7] m:(⍺⍺ ¯1↓W),⍵⍵¨⊢/W
[8] t:((0⊃A)⍺⍺ 0⊃W)((1⊃A)⍵⍵ 1⊃W)
[9] ((¯1↓A)⍺⍺ ¯1↓W),(⊢/A)⍵⍵¨⊢/W
[10] ⍝ function vector
[11] ⍝ f fv g fv h ... x y z ... ←→ (f x)(g y)(h z) ...
[12] ⍝ a b c ... f fv g fv h ... x y z ... ←→ (a f x)(b g y)(c h z) ...
[13] ⍝ a b c ... f fv g fv h ... ⊂x ←→ (a f x)(b g x)(c h x) ...
[14] ⍝ (⊂a) f fv g fv h ... x y z ... ←→ (a f x)(a g y)(a h z) ...
[15] ⍝ requires conformity of ⍺ or ⍵ with number of fns
[16] ⍝ permits scalar extension of ⍺ xor ⍵ in dyad only
[17] ⍝ Phil Last ⍝ 2007-06-29 00:00
[18] }
∇
∇ hk←{
[1] ⍺←⍵
[2] ⍺ ⍺⍺ ⍵⍵ ⍵
[3] ⍝ hook
[4] ⍝ ⍺ f hk g ⍵ ←→ ⍺ f g ⍵
[5] ⍝ f hk g ⍵ ←→ ⍵ f g ⍵
[6] }
∇
∇ if←{
[1] 1∊⍵⍵⊣⍵:⍺⍺⊣⍵
[2] ⍵
[3] ⍝ consequent if antecedent arg else arg
[4] ⍝ ⍺⍺ any array or monad on ⍵ to return such
[5] ⍝ ⍵⍵ boolean singleton or monad on ⍵ to return such
[6] ⍝ ⍵ array (in domain of either or both of monad ⍺⍺ & ⍵⍵)
[7] ⍝ ← array ⍺⍺ or result of ⍺⍺ ⍵ or ⍵ unchanged
[8] ⍝ Phil Last ⍝ 2008-01-22 12:34
[9] }
∇
∇ in←{
[1] ≥/⍺:⍵ ⍝ no-op
[2] (¯1=-/⍺):⍵⍵⊣⍵ ⍝ n-1 of n
[3] (⍺≡0 2):⍺⍺⊣⍵ ⍝ 0 of 2
[4] (⍺-0 1)⍺⍺ ⍵ ⍝ penultimate?
[5] ⍝ index list of functions or arrays
[6] ⍝ i n(f in g in h ... n)⍵
[7] ⍝ ⍺ index length
[8] ⍝ ⍺⍺ function/array list
[9] ⍝ ⍵⍵ function or array
[10] ⍝ ⍵ arg to functions
[11] ⍝ ← result of selected function/array
[12] ⍝ Phil Last ⍝ 2007-12-23 13:51
[13] }
∇
∇ ir←{
[1] ⊃⍺⍺⌿⊂⍤¯1⊢⍵
[2] ⍝ Iverson's reduction
[3] ⍝ ⍺⍺ fn to insert
[4] ⍝ ⍵ array between whose major cells to apply ⍺⍺
[5] }
∇
∇ it←{
[1] ⍺←⊢
[2] ⍺ ⍵⍵⍣(⍬⍴⍺⍺⊣⍵)⊢⍵
[3] ⍝ r ← n iterate{f}w
[4] ⍝ r ← a{n}iterate{f}w
[5] ⍝ ⍺ [larg to ⍵⍵]
[6] ⍝ ⍺⍺ no. of iterations or fn to return it
[7] ⍝ ⍵⍵ fn to run (⍺⍺⊣⍵) times on ⍵ and successors
[8] ⍝ ⍵ arg to first if any iteration
[9] }
∇
∇ ix←{
[1] w←⍵
[2] i←⍺⍺⊣⍳⍴w
[3] ⍺←⊢
[4] 1≡⍺ 1:w[i]
[5] {w}w[i]←⍺
[6]
[7] ⍝ ⍺ source data if it is to be replaced
[8] ⍝ ⍺⍺ array of ⍵-indices whence result to be drawn or function to generate such
[9] ⍝ or
[10] ⍝ array of ⍵-indices whither ⍺ to be assigned or function to generate such
[11] ⍝ ⍵ target array
[12] ⍝ ← monad: subarray of ⍵ selected by ⍺⍺⊣⍵
[13] ⍝ dyad: ⍵ with items selected by ⍺⍺⊣⍵ replaced by ⍺
[14] }
∇
∇ jn←{⍺←⍺
[1] s←'internal left argument'
[2] ⍺≢s:s ⍺⍺ ⍺(⍵⍵ ⍵)
[3] s d←⍵
[4] (⍺⍺ s)⍵⍵ d
[5] ⍝ janus looking both ways
[6] ⍝ a f jn g jn h w ←→ (f a)g(h w)
[7] ⍝ ←→ a ((f⊣) g ⊢∘h) w
[8] ⍝ first: ⍺ ←→ a ⋄ ⍺⍺ ←→ f jn g ⋄ ⍵⍵ ←→ h ⋄ ⍵ ←→ w
[9] ⍝ second: ⍺ ←→ d ⋄ ⍺⍺ ←→ f ⋄ ⍵⍵ ←→ g ⋄ ⍵ ←→ a(h w)
[10] }
∇
∇ ky←{⍺←⊢
[1] 0::⎕SIGNAL/⌽⎕EN,⎕DM
[2] ⍵≡⍺ ⍵:⍵ ∇⍳⍬⍴⍴⍵
[3] u←∪i←⍳⍨⊂[1↓⍳⍴⍴k]⊢k←⍺
[4] f←⍺⍺
[5] ↑u{(⍺⌷k)f ⍵}¨(↓u∘.=i)⌿¨⊂⍵
[6]
[7] ⍝ key
[8] ⍝ ⍺ ⍺⍺ ky ⍵
[9] ⍝ ⍺⍺ ky ⍵ ←→ ⍵ ⍺⍺ ky ⍳⍬⍴⍴ ⍵
[10] ⍝ d: (⍬⍴⍴⍺)←→(⍬⍴⍴⍵)
[11] ⍝ ⍺ keys array (major cells)
[12] ⍝ ⍵ corresponding data array (in first dimension)
[13] ⍝ ⍺⍺ dyad applied between each unique key and the
[14] ⍝ corresponding major cells of the data as - key ⍺⍺ cells
[15] ⍝ m:
[16] ⍝ ⍺⍺ applied beteen each unique major cell of ⍵ and the corresponding
[17] ⍝ subset of ⍳⍬⍴⍴⍵
[18] ⍝ ← assembled result of applications of ⍺⍺
[19] ⍝ Phil Last ⍝ 2008-05-29 10:39
[20] }
∇
∇ lg←{
[1] ⊃(0 1 2 3=⊂⍺+⍺+⍵)∨.∧{
[2] ⊂[1+⍳⍴⍴⍵]2 2 2 2⊤⍵
[3] }⍺⍺⊣⍬
[4] ⍝ Logic - p{i}lg q
[5] ⍝ ⍺ & ⍵ - p & q are scalar conformable boolean arrays, any rank any depth.
[6] ⍝ ⍺⍺ - simple integer array or constant function to return i, scalar
[7] ⍝ conformable with p & q, whose items are zero indices into
[8] ⍝ conceptual logical scalar function vector ...
[9] ⍝ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
[10] ⍝ (0∧=) ∧ > (⊣∧⊢=⊢) < (⊢∧⊣=⊣) ≠ ∨ ⍱ = (⊢<⊣=⊣) ≥ (⊣<⊢=⊢) ≤ ⍲ (1∨=)
[11] ⍝ {i}lg is therefore a (⍴i) shaped logical function array
[12] ⍝ 0 3 5 10 12 15 are scalar eqivalents of
[13] ⍝ {0} ⊣ ⊢ (~⊢) (~⊣) {1}
[14] ⍝ Phil Last ⍝ 2007-06-25 15:00
[15] }
∇
∇ lm←{
[1] ⍵ ⍺⍺{⍺≡⍵:⍵ ⋄ ⍵ ⍺⍺ ∇∇ ⍺⍺ ⍵ ⋄ ⍵:⍵≡⍺}⍺⍺ ⍵
[2] ⍝ limit ←→ ⍣≡
[3] }
∇
∇ lt←{
[1] A B C D←112358314594370 774156178538190 998752796516730 336954932572910
[2] ⍺←A
[3] ⍺≡A:B ∇ ⍵
[4] ⍺≡B:(⊂⍣(~B∊z)⊢z←⍺⍺ ⍵),B,⊂⍵⍵ ⍵
[5]
[6] ⍺≡D:(⊂⍣(~D∊z)⊢z←D ⍺⍺ ⍺ ⍵),D,⊂⊃⍵⍵/⍵
[7] D ∇ ⍺ ⍵
[8] }
∇
∇ mf←{
[1] ⍺←⊢
[2] (⍺ ⍺⍺ ⍵)≡⍺ ⍵⍵ ⍵
[3] ⍝ match fn results
[4] ⍝ Phil Last ⍝ 2007-12-21 16:56
[5] }
∇
∇ mg←{
[1] {W}W[⍺⍺⊣⍳⍴W←⍵]←⍺
[2] ⍝ merge
[3] ⍝ ⍺ source data
[4] ⍝ ⍺⍺ a function to select from index array of (⍵) - (⍳⍴⍵)
[5] ⍝ or an array being a prior selection of those indices
[6] ⍝ ⍵ target array
[7] ⍝ ← (⍵) with data from (⍺) merged at positions specified by (⍺⍺)
[8] ⍝ {W}W[⍺⍺⊣{⊂⍬}⍣(0∊⍴⍴⍵)⍳⍴W←⍵]←⍺ ⍝ would permit scalar ⍵
[9] ⍝ Phil Last ⍝ 2008-01-23 11:06
[10] }
∇
∇ mo←{
[1] ⍺⍺ ⍵
[2] ⍝ monadic - ignore ⍺
[3] }
∇
∇ nf←{
[1] ⍺←⊢
[2] ⍺∘⍺⍺{(⎕NUNTIE⊃⍵)⊢⍺⍺ ⍵}(⎕NTIE∘0⊃⍵),1↓⍵
[3] ⍝ ⎕nfile function
[4] ⍝ ⍺ [larg] to
[5] ⍝ ⍺⍺ ⎕Nfunction, ⎕NREAD, ⎕NSIZE, ...
[6] ⍝ ⍵ filename and rest of rarg to ⍺⍺ usually after tie number
[7] ⍝ thus - ⎕NREAD nf 'myfile' 80 100 0 - reads first 100 bytes
[8] ⍝ Phil Last ⍝ 2007-06-25 07:53
[9] }
∇
∇ nl←{
[1] ⍺←⊢
[2] (⍕⍺⍺),⍤1⊢'.',⍺ ⍺⍺.⎕NL ⍵
[3] ⍝ (⍕⍺⍺),rk{1}'.',⍺ ⍺⍺.⎕NL ⍵
[4] ⍝ name list
[5] ⍝ ⍺ [chars]
[6] ⍝ ⍺⍺ space
[7] ⍝ ⍵ name class(es)
[8] ⍝ ← fully qualified namelist
[9] ⍝ ⍺(⍺⍺ nl)⍵ ←~→ ⍺ ⍺⍺.⎕NL ⍵
[10] ⍝ ⍺⍺ nl ⍵ ←~→ ⍺⍺.⎕NL ⍵
[11] ⍝ Phil Last 2017-05-04 22.33
[12] }
∇
∇ nr←{
[1] ⍺←⍵
[2] 6::⍺{⍵:⍺}1∊(2 4⍴' ⊢∧ ')⍷↑⎕DM
[3] ⊢⍺⍺ ⍵
[4] ⍝ no result
[5] ⍝ ⍺ the default result required from ⍺⍺ if none - ⍵ if not supplied
[6] ⍝ ⍺⍺ any function - if dyadic bind its left arg as - larg∘fn
[7] ⍝ ⍵ any array
[8] ⍝ ← result of (⍺⍺ ⍵) or (⍺) if none or (⍵) if none
[9] ⍝ Phil Last ⍝ 2008-03-06 12:30
[10] }
∇
∇ nv←{⍺←⊢
[1] ⍵.(⍺⍺{⍵,⍪⍺⍺¨1↓⍎¨'0',⍵}⍺∩⍨⎕NL-2.1)
[2] ⍝ namespace vars - all or those mentioned in ⍺ if supplied
[3] ⍝ ⍵ space
[4] ⍝ ← 2-col table - names values
[5] ⍝ ...
[6] ⍝ ⍺⍺ function to run on each value
[7] ⍝ ⍴nv dx'oneVec twoD scalar'((⍳1)(⍳2 3)('A'))
[8] ⍝ oneVec 1
[9] ⍝ scalar
[10] ⍝ twoD 2 3
[11] }
∇
∇ on←{
[1] ⍺←⊢
[2] ⍺⍺ ⍺ ⍵⍵ ⍵
[3] ⍝ atop
[4] ⍝ ~at= ←→ ≠
[5] ⍝ ~at∨ ←→ ⍱
[6] ⍝ ⍺ f on g ⍵ ←→ f ⍺ g ⍵
[7] ⍝ f on g ⍵ ←→ f∘g ⍵
[8] }
∇
∇ or←{
[1] ~1∊⍺:⍵ ⍝ none
[2] </⍺:⍵⍵⊣⍵ ⍝ only last
[3] 2=⍴⍺:⍺⍺⊣⍵ ⍝ first of 2
[4] (¯1↓⍺)⍺⍺ ⍵ ⍝ penultimate?
[5] ⍝ select from list of functions
[6] ⍝ i j k ... f or g or h ... w
[7] ⍝ ↑ ←→ ↓
[8] ⍝ :Select 1
[9] ⍝ :Case i ⋄ f w
[10] ⍝ :Case j ⋄ g w
[11] ⍝ :Case k ⋄ h w
[12] ⍝ ...
[13] ⍝ :Else ⋄ w
[14] ⍝ :End
[15] ⍝ Phil Last ⍝ 2007-06-22 01:30
[16] }
∇
∇ ou←{ ⍝ or
[1] ⍺⍺⊣⍵:1 ⋄ ⍵⍵ ⍵
[2] ⍝ f0 ou f1 ou f2 ou ... ⍵
[3] ⍝ ⍵ any array in domain of f0
[4] ⍝ f0 f1 f2 &c. are monadic tests on ⍵, but each subsequent
[5] ⍝ test will only run if its predecessor returns false.
[6] ⍝ ← 1 | 0 - whether or not any is true
[7] ⍝ see et
[8] }
∇
∇ pm←{⍺←⊢
[1] z←⎕PROFILE'clear'
[2] z←⎕PROFILE'start'
[3] r←⍺ ⍺⍺⍣⍵⍵⊢⍵
[4] z←⎕PROFILE'stop' ⋄ e←⍬⍴⎕LC
[5] p←e↓⍉↑(1+⍳5)⎕PROFILE'data'
[6] p[;3]←100×(⊢÷+/)p[;3]
[7] r{⍺ ⍵}p[⍒p[;3];]
[8] ⍝ profile monitor
[9] ⍝ ⍺ [larg]
[10] ⍝ ⍺⍺ fn
[11] ⍝ ⍵⍵ rop to ⍣ (fn or int)
[12] ⍝ ⍵ rarg
[13] ⍝ ← res prof
[14] ⍝ res result of: ⍺ ⍺⍺⍣⍵⍵⊢⍵
[15] ⍝ prof ⎕profile result
[16] }
∇
∇ po←{
[1] ⍺←≡
[2] (⍺⍺⍣⍺)⍵
[3] ⍝ hence is how to do it without ⍣
[4] ⍺←⊢
[5] 1≢⍺ 1:⊃⊢∘⍺⍺/(⍳⍺),⊂⍵ ⍝ ⍺ is iterations
[6] ⍵ ⍺⍺{⍺≡⍵:⍵ ⋄ ⍵ ⍺⍺ ∇∇ ⍺⍺ ⍵ ⋄ ⍵:⍵≡⍺}⍺⍺ ⍵ ⍝ 'til no change
[7] ⍝ power
[8] ⍝ Phil Last ⍝ 2008-01-07 09:18
[9] }
∇
∇ pq←{
[1] ⊃(|⍵ ⍺ 0-⊂⍺×⍵){⊃|⍺-⊃⍺⍺+.×⍺≠⍵}/1 1 0 0⊂,∘.⍺⍺⍨0 1
[2] ⍝ probability
[3] ⍝ If L is a logical function and p & q are respectively
[4] ⍝ the probabilities of the truths of propositions P & Q
[5] ⍝ p L pq q is the probability of the truth of proposition P L Q
[6] ⍝ Phil Last ⍝ 2007-06-22 22:57
[7] }
∇
∇ pt←{
[1] (⍺⍺⊣⍵){(⍺/2</0,⍺)⊂⍺/⍵}⍵
[2] ⍝ partition
[3] ⍝ ⍺⍺ boolean string or fn to return such given ⍵
[4] ⍝ ⍵ string
[5] ⍝ ← ⍵ partitioned each partition being ⍵ corresponding
[6] ⍝ to a contiguous string of 1s in ⍺⍺⊣⍵
[7] ⍝ Phil Last ⍝ 2008-02-12 07:51
[8] }
∇
∇ rk←{
[1] mlr←⌽3⍴⌽⍵⍵,⍬
[2] m←(f←⍺⍺)/0
[3] ⍺←m←(f←⊢∘⍺⍺)/1
[4] l r←-1↓r⌊|l+r×0>l←(mlr⌊r←3⍴(⍴⍴⍵),⍴⍴⍺)[⍒m×⍳3]
[5] 5::⎕SIGNAL/⌽⎕EN,⎕DM
[6] {↑⍵⍴¨⍨↓1+⌽↑-1-⌽∘⍴¨⍵}(⊂[l↑⍳⍴⍴⍺]⍺)f¨⊂[r↑⍳⍴⍴⍵]⍵
[7] ⍝ rank
[8] ⍝ f rk{m l r}
[9] ⍝ applies f to m-cells of ⍵ or between l-cells of ⍺ and r-cells of ⍵
[10] ⍝ Phil Last ⍝ 2007-06-22 22:57
[11] }
∇
∇ rx←{
[1] ⍺←⍵ ⋄ (⍺⍺ ⍺)⍵⍵ ⍵
[2] ⍝ reflex
[3] ⍝ ⍺ [array]
[4] ⍝ ⍵ array
[5] ⍝ ← apply left monad to [⍺] else ⍵ and
[6] ⍝ right dyad twixt left result and ⍵
[7] }
∇
∇ ss←{
[1] (⍴,⍵)↑1↓⌽⊃⍺⍺{⍬⍴⍵:⍵ ⋄ ⍺⍺ ⍺:1,⍵ ⋄ 0,⍵}/⌽0,⍵
[2] ⍝ stop scan
[3] ⍝ <\⍺⍺¨⍵ but ⍺⍺ runs only until a one is encountered
[4] ⍝ ⍺⍺ a potentially expensive boolean returning function
[5] ⍝ ⍵ a vector whose items are all valid arguments to ⍺⍺
[6] ⍝ ← boolean vector length of ⍵ having one or zero ones
[7] }
∇
∇ st←{
[1] 0 ⍺⍺{
[2] ⍬⍴⍺:⍺
[3] ⍬⍴r←⍺⍺ ⍵:r
[4] ⊃∇⍨/(⍵⍵ ⍵),0
[5] }⍵⍵ ⍵
[6] ⍝ search tree - return on first hit or exhaustion
[7] ⍝ ⍺⍺ test
[8] ⍝ ⍵ node (namespace, folder ...
[9] ⍝ ← boolean, other data
[10] ⍝ ⍵⍵ subtree - needs to check for recursion
[11] ⍝ ⍵ node
[12] ⍝ ← list of nodes in ⍵
[13] ⍝ ⍵ tree
[14] ⍝ ← as of last search
[15] }
∇
∇ tf←{
[1] ⍺←⊢
[2] (1=⍺⊣0):⍺⍺⊣⍵ ⍝ antecedent
[3] (0=⍺⊣1):⍵⍵⊣⍵ ⍝ consequent
[4] (1 ⍺⍺ ⍵):0 ⍺⍺ ⍵ ⍝ antecedent then consequent
[5] ⍵⍵⊣⍵ ⍝ else alternative
[6] ⍝ true false
[7] ⍝ antecedent tf consequent tf alternative
[8] ⍝ applies antecedent followed by consequent or alternative to ⍵
[9] ⍝ antecedent, consequent and alternative are arrays or monads
[10] ⍝ Phil Last ⍝ 2008-01-22 07:53
[11] }
∇
∇ ti←{⍺←⊢
[1] op←{⍺←⊢
[2] 0.001×÷/2⍴⌽1⊢∘(⊢∘(⍺∘⍺⍺)∘⍵){⍺,⊃∇/⍺{(1000<⍵)↓(2×⍺)⍵}⍺⍺{⍬⍴2↓⎕AI-(⍺⍺/⍳1+⍵)⊢⎕AI}⍺}1
[3] }
[4] (⍺ ⍺⍺ op ⍵)-⍺⊢op ⍵
[5] ⍝ time function
[6] ⍝ ⍺ larg to ⍺⍺
[7] ⍝ ⍺⍺ fn to be timed
[8] ⍝ ⍵ rarg to ⍺⍺
[9] ⍝ ← seconds per execution averaged over at least one second
[10] ⍝ Phil Last ⍝ 2007-12-21 17:01
[11] }
∇
∇ tk←{⍺←⊢
[1] ticks←⎕AI[2]'----+----|'{go ten←⍺ ⋄ prev←⍵
[2] now←⌊0.5+(⎕AI[2]-go)÷1000 ⋄ ⍞←prev↓now⍴ten
[3] ⍺ ∇ now⊣⎕DL 1}&0
[4] (⎕TKILL ticks)⊢⍺ ⍺⍺ ⍵
[5] ⍝ tick
[6] ⍝ run and return {⍺} ⍺⍺ ⍵ while displaying 1 second ticks
[7] }
∇
∇ ts←{⍺←⊢
[1] ⊃'s'mn ⍺ ⍺⍺ ti ⍵
[2] ⍝
[3] }
∇
∇ ud←{⍺←⎕SIGNAL 6
[1] (⍵⍵ ⍺)⍺⍺ ⍵⍵ ⍵
[2] ⍝ under
[3] ⍝ Phil Last 2017-12-04 08.28
[4] }
∇
∇ un←{
[1] ⍺⍺{⍵⍵ ⍵:⍵ ⋄ ∇ ⍺⍺ ⍵}⍵⍵ ⍺⍺ ⍵
[2] ∇{⊢∘⍺⍺/(1~⍵⍵ ⍵),⊂⍵}⍵⍵ ⍺⍺ ⍵
[3] ⍺⍺⍣(⊢∘⍵⍵⍨)⍵
[4] ⍺⍺⍣(⍵⍵{⍺⍺ ⍺})⍵
[5] ⍝ until
[6] ⍝ ⍺⍺ monad on ⍵ and successors displaying closure property.
[7] ⍝ ⍵⍵ boolean scalar returning monad on successors of ⍵
[8] ⍝ whose truth terminates iteration.
[9] ⍝ ⍵ array in domain of ⍺⍺
[10] ⍝ ← first result of ⍺⍺ ⍺⍺ ... ⍵ to satisfy ⍵⍵
[11] ⍝ Phil Last ⍝ 2008-12-02 10:27
[12] }
∇
∇ ut←{⍺←⊢ ⋄ f←⍺⍺ ⋄ t←⍵⍵
[1] ⍵≡⍺ ⍵:f⍣(t⊣)⍵
[2] ⍺{ ⍝ keep recursion local
[3] (⍺-1)∘∇⍣((⍺>1)>t z)⊢z←f ⍵
[4] }⍵
[5] ⍝ until
[6] ⍝ ⍺ [max]
[7] ⍝ ⍺⍺ monadic fn on arg - may be composed: (const∘function)
[8] ⍝ ⍵⍵ monadic test on arg or subsequent results
[9] ⍝ ⍵ arg
[10] ⍝ apply fn [up to max times] until test result
[11] ⍝ ← last application of fn
[12] ⍝ e.g.
[13] ⍝+-----------------------+--------------------------+
[14] ⍝| +∘1 ut (≥∘5) 0 | 10 +∘1 ut (≥∘5) 0 |
[15] ⍝| 5 | 5 |
[16] ⍝+-----------------------+--------------------------+
[17] ⍝| +∘1 ut (≥∘15) 0 | 10 +∘1 ut (≥∘15) 0 |
[18] ⍝| 15 | 10 |
[19] ⍝+-----------------------+--------------------------+
[20] }
∇
∇ wh←{
[1] f←⍺⍺ ⋄ g←⍵⍵
[2] (⍴⍵)⍴{⍵{⍵⊖⍺,[-0.1]⍵\f ⍵/⍺},g⊣⍵},⍵
[3] ⍝ where
[4] ⍝ ⍺⍺ fn applied to vector of items
[5] ⍝ selected from (⍵) where (⍵⍵)(⍵) true
[6] ⍝ ⍵⍵ (⍴⍵)⍴boolean or fn applied to (⍵) to return such
[7] ⍝ ⍵ array
[8] ⍝ ← (⍵) changed by (⍺⍺) where (⍵⍵)⍵
[9] ⍝ ⍺⍺ & ⍵⍵ expected to be scalar functions.
[10] ⍝ otherwise use (⍺⍺¨) (⍵⍵¨) as in:
[11] ⍝ (⍺⍺¨)wh(⍵⍵¨)⍵
[12] ⍝ nb. A fixed left arg can be composed with ⍺⍺ as:
[13] ⍝ larg∘⍺⍺ wh ⍵⍵ rarg
[14] ⍝ Phil Last ⍝ 2008-03-11 18:15
[15] }
∇
∇ wl←{
[1] ⍵⍵ ⍵:∇ ⍺⍺ ⍵
[2] ⍵
[3] ⍺⍺⍣(⊢∘~∘⍵⍵⍨)⍣(⍵⍵ ⍵)⊢⍵
[4] ⍺⍺⍣(⍵⍵{~⍺⍺ ⍺})⍣(⍵⍵ ⍵)⊢⍵
[5] ⊢∘∇∘⍺⍺/(1∩⍵⍵ ⍵),⊂⍵
[6] ⍝ while
[7] ⍝ ⍺⍺ fn to run repeatedly while
[8] ⍝ ⍵⍵ test on ⍵ is true
[9] ⍝ ← ⍵ or ⍺⍺ ⍵ or ⍺⍺ ⍺⍺ ... ⍵
[10] }
∇
∇ wt←{
[1] sofar inc←0 0.1
[2] wait←⊃⍵⍵,1
[3] rslt←this←⎕NS''
[4] tid←⍺⍺{6::
[5] rslt∘←⍺⍺ ⍵
[6] }&⍵
[7] {(tid∊⎕TNUMS)≤wait≤sofar:0
[8] ∇ sofar+←⎕DL inc
[9] }0:
[10] tid←⎕TKILL tid
[11] rslt≢this:rslt
[12] ⍺←⊢
[13] 1≢⍺ 1:⍺
[14] ⍝ wait
[15] ⍝ ⍺ dflt result if supplied
[16] ⍝ ⍺⍺ function - monad or (larg∘dyad)
[17] ⍝ ⍵⍵ seconds for (⍺⍺) to finish - number or {fn} to return such
[18] ⍝ ⍵ rarg to (⍺⍺)
[19] ⍝ ← If (⍺⍺) returns a result then this returns it.
[20] ⍝ Otherwise if (⍺) is supplied this returns that.
[21] ⍝ Otherwise this returns nothing.
[22] ⍝ Phil Last ⍝ 2007-06-23 18:50
[23] }
∇
∇ wt0←{
[1] ns←⎕NS''
[2] ns.(sofar inc)←0 0.1
[3] ns.wait←⊃⍵⍵,1
[4] ns.(rslt this)←⎕NS''
[5] ns.tid←⍺⍺{6::
[6] ⍵⍵.rslt∘←⍺⍺ ⍵
[7] }ns&⍵
[8] ns∘{(⍺.tid∊⎕TNUMS)≤⍺.wait≤⍺.sofar:0
[9] ∇ ⍺.sofar+←⎕DL ⍺.inc
[10] }0:
[11] ns.tid←⎕TKILL ns.tid
[12] ns.rslt≢ns.this:ns.rslt
[13] ⍺←⊢
[14] 1≢⍺ 1:⍺
[15] ⍝ wait
[16] ⍝ ⍺ dflt result if supplied
[17] ⍝ ⍺⍺ function - monad or (larg∘dyad)
[18] ⍝ ⍵⍵ seconds for (⍺⍺) to finish - number or {fn} to return such
[19] ⍝ ⍵ rarg to (⍺⍺)
[20] ⍝ ← If (⍺⍺) returns a result then this returns it.
[21] ⍝ Otherwise if (⍺) is supplied this returns that.
[22] ⍝ Otherwise this returns nothing.
[23] ⍝ Phil Last ⍝ 2007-06-23 18:50
[24] }
∇
∇ xa←{
[1] ⍺←⊢
[2] 0::⍺ ⍺⍺⊣⍵
[3] 1:⍺ ⍵⍵ ⍵
[4] ⍝ execute alternative
[5] ⍝ if error in ⍵⍵ then ⍺⍺
[6] ⍝ if ⍺ elided then functions called as monads and ⍺⍺ may be an array
[7] }
∇
∇ æ←{⍺←⍺
[1] s←'internal left argument'
[2] ⍺≢s:s ⍺⍺ ⍺(⍵⍵ ⍵)
[3] s d←⍵
[4] (⍺⍺ s)⍵⍵ d
[5] ⍝ a f æ g æ h w ←→ (f a)g(h w)
[6] ⍝ ←→ a ((f⊣) g ⊢∘h) w
[7] ⍝ first: ⍺ ←→ a ⋄ ⍺⍺ ←→ f æ g ⋄ ⍵⍵ ←→ h ⋄ ⍵ ←→ w
[8] ⍝ second: ⍺ ←→ d ⋄ ⍺⍺ ←→ f ⋄ ⍵⍵ ←→ g ⋄ ⍵ ←→ a(h w)
[9] }
∇
Name | Setting |
---|---|
backgroundColorPrint | 1 |
bookmarkCounter | 413 |
caption | acre |
cssfilename | C:\T\Projects\APL-cation\CodeBrowser\codebrowser_styles.css |
filename | D:/Temp/acre.html |
footer | |
ignore | |
ignoreEmpty | 1 |
info | |
infoIsHTML | 0 |
lang | en |
linkcssfile | 1 |
namespaces | ⎕se.acre |
printFontSize | 8 |
processFunctions | 1 |
processGuiInstances | 0 |
processOperators | 1 |
processScripts | 1 |
processVars | 1 |
recursive | 1 |
showParms | 1 |
twoSidedPrint | 0 |
version | CodeBrowser 1.0.0.2 from 2018-09-23 |
viewInBrowser | 0 |