Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Misc cleanups #496

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 4 additions & 4 deletions cmp/PS.apl
Expand Up @@ -20,8 +20,8 @@ PS←{
'Non-Z top-level node'assert t[⍸p=⍳≢p]=Z:

⍝ Wrap all function expression bodies as Z nodes
_←p[i]{end[⍺]←end[⊃⌽⍵] ⋄ gz¨⍵⊂⍨1,¯1↓t[⍵]=Z}⌸i←⍸(t[p]∊T F)∧~t=L
'Non-Z/L dfns body node'assert t[⍸t[p]=F]∊Z L:
_←p[i]{end[⍺]←end[⊃⌽⍵] ⋄ gz¨⍵⊂⍨1,¯1↓t[⍵]=Z}⌸i←⍸(t=L)<t[p]∊T F
'Non-Z/L fn body node'assert t[⍸t[p]∊T F]∊Z L:

⍝ Parse the first line of a trad-fn as an H node
t[⍸(≠p)∧t[p]=T]←H
Expand All @@ -34,7 +34,7 @@ PS←{
0=≢i:0
nt←'←(){};V'['←(){};'⍳⊃¨sym[|n[⍵]]] ⋄ k[⍵⌿⍨nt≠'V']←¯99
k[⍺]←0 ⋄ n[⍺]←0
~∧⌿msk←(nt↓⍨x←nt⍳';')∊'V;':'BAD LOCAL DECLARATION'SIGNAL SELECT msk⌿x↓⍵
⌿msk←2=⌿0⍪⍨';V'⍳nt↓⍨x←nt⍳';':'BAD LOCAL DECLARATION'SIGNAL SELECT msk⌿x↓⍵
⊃⌽+⍀('('=nt)-')'=nt←x↑nt:'UNBALANCED HEADER'SIGNAL SELECT (≢nt)↑⍵
ti←p[⍺] ⋄ ki←ti,⍺,(≢nt)↑⍵ ⋄ zt st←¯2↑(⊂''),'←'(≠⊆⊢)nt
0=≢st:'EMPTY SIGNATURE'SIGNAL SELECT (≢nt)↑⍵
Expand Down Expand Up @@ -86,7 +86,7 @@ PS←{
t[⍺]←G ⋄ p[ti←gz⊃tx cq←2↑(⊂⍬)⍪⍨⍵⊂⍨1,¯1↓m]←⍺ ⋄ k[ti]←1
ci←≢p ⋄ p,←⍺ ⋄ t k pos end⍪←0 ⋄ n,←0 ⋄ k[gz cq,ci]←1
0}⌸i←⍸t[p[p]]=F

⍝ Delete keywords we can't handle
t k n pos end⌿⍨←⊂msk←t≠K ⋄ p←(⍸~msk)(⊢-1+⍸)msk⌿p

Expand Down
34 changes: 17 additions & 17 deletions cmp/TK.apl
Expand Up @@ -47,7 +47,7 @@ TK←{⍺←⊢
t[⍸'⋄'=IN[pos]]←Z

⍝ Remove insignificant whitespace
t pos end⌿⍨←⊂~(t=0)(⊢∧1⌽⊢)IN[pos]∊WS
t pos end⌿⍨←⊂(t=0)(⊢∧1⌽⊢)IN[pos]∊WS
t pos end⌿⍨←⊂(t≠0)∨(~IN[pos]∊WS)∨⊃¯1 1∧.⌽⊂IN[pos]∊alp,num,'¯⍺⍵⎕.:'

⍝ Verify all open characters are valid
Expand All @@ -65,9 +65,9 @@ TK←{⍺←⊢
∨⌿msk←1<+⌿¨dm⊆'¯'=x:'MULTIPLE ¯ IN NUMBER'SIGNAL ∊msk⌿dm⊆pos
∨⌿msk←('¯'=x)∧~dm:'ORPHANED ¯'SIGNAL msk⌿pos
dm∨←(msk←x∊'Ee')∧(¯1⌽dm)∧1⌽dm
dm←dm⍀∊{¯1↓1@(⊃⍸⍵)~⍵⍪0}¨dm⊆msk
dm⍀←∊{¯1↓1@(⊃⍸⍵)~⍵⍪0}¨dm⊆msk
dm∨←(msk←x∊'Jj')∧(¯1⌽dm)∧1⌽dm
dm←dm⍀∊{¯1↓1@(⊃⍸⍵)~⍵⍪0}¨dm⊆msk
dm⍀←∊{¯1↓1@(⊃⍸⍵)~⍵⍪0}¨dm⊆msk
(msk⌿dm)←∊∧⍀¨(msk←x∊alp,num)⊆dm
dm[⍸dm∧(x='.')∧(¯1⌽dm)⍱1⌽dm]←0
msk←∨⌿¨dm⊆dm∧(x='.')∧¯1⌽(~dm)∧x∊num
Expand All @@ -77,18 +77,18 @@ TK←{⍺←⊢
t[i←⍸2<⌿0⍪dm]←N ⋄ end[i]←end⌿⍨2>⌿dm⍪0

⍝ Tokenize variables
msk←(~dm)∧(t=0)∧x∊alp,num ⋄ t[i←⍸2<⌿0⍪msk]←V ⋄ end[i]←end⌿⍨2>⌿msk⍪0
msk←dm<(t=0)∧x∊alp,num ⋄ t[i←⍸2<⌿0⍪msk]←V ⋄ end[i]←end⌿⍨2>⌿msk⍪0

⍝ Tokenize dfns formals
msk←3≤≢¨grp←(pos⊆⍨'⍺'=x),pos⊆⍨'⍵'=x
∨⌿msk:'AMBIGUOUS FORMALS'SIGNAL ∊msk⌿grp
msk←('⍺⍺'⍷x)∨'⍵⍵'⍷x ⋄ t[i←⍸msk]←P ⋄ end[i]+←1
t[⍸(~msk¯1⌽msk)x∊'⍺⍵']←A
t[⍸msk<(¯1⌽msk)<x∊'⍺⍵']←A

⍝ Tokenize primitives and atoms
t[⍸x∊syna]←A ⋄ t[⍸(~dm)∧x∊prms,'←']←P
msk←(x∊'⌶∇')∨msk∨¯1⌽msk←(~dm)∧⊃'⍠←' '∘←' '∘.'∨.⍷⊂x
end[⍸m2←2<⌿0⍪msk]←end⌿⍨2>⌿msk⍪0 ⋄ t[⍸msk∧~m2]←0
t[⍸x∊syna]←A ⋄ t[⍸dm<x∊prms,'←']←P
msk←(x∊'⌶∇')∨msk∨¯1⌽msk←dm<⊃'⍠←' '∘←' '∘.'∨.⍷⊂x
end[⍸m2←2<⌿0⍪msk]←end⌿⍨2>⌿msk⍪0 ⋄ t[⍸m2<msk]←0
∨⌿msk←2<end[i]-pos[i←⍸msk∧x='∇']:{
'AMBIGUOUS ∇ CLUSTER'SIGNAL SELECT msk⌿i
}⍬
Expand All @@ -109,20 +109,20 @@ TK←{⍺←⊢
0≠⊃tm←¯1⌽≠⍀tm:'UNBALANCED TRAD-FNS'SIGNAL lineof pos[⊃⌽⍸2<⌿0⍪tm]
msk←Z≠t⌿⍨⊃1 ¯1∨.⌽⊂(2>⌿tm)⍪0
∨⌿msk:'TRAD-FNS END LINE MUST CONTAIN ∇ ALONE'SIGNAL lineof msk⌿pos

⍝ Flatten trad-fns headers
d[⍸msk←∊∨⍀¨(t=Z)⊂2<⌿tm⍪0]←0 ⋄ t[⍸msk∧x∊'{}']←P

⍝ Parse trad-fns into T type
t[⍸msk←2<⌿tm⍪0]←T ⋄ d+←tm∧~msk
t[⍸msk←2<⌿tm⍪0]←T ⋄ d+←msk<tm

⍝ Identify colons belonging to Labels
t[⍸tm∧(d=1)∧∊0,¨(<⍀∧∘~⊃)¨':'=1↓¨(t=Z)⊂x]←L

⍝ Tokenize Keywords
∨⌿msk←3∧⌿(':'=x)∧t=0:'TOO MANY COLONS'SIGNAL SELECT ⍸msk
t[⍸(':'=x)∧t=0]←K
ki←⍸(t=K)∧((1⌽t=K)∧~msk)∨(1⌽t=V)∧msk←(d=0)∨tm∧d=1
ki←⍸(t=K)∧(msk<1⌽t=K)∨(1⌽t=V)∧msk←(d=0)∨tm∧d=1
end[ki]←end[1+ki] ⋄ t[ki+1]←0

⍝ Tokenize system variables
Expand All @@ -142,12 +142,12 @@ TK←{⍺←⊢
msk vals←⎕VFI ⍕n[i←⍸t=N]
~∧⌿msk:'CANNOT REPRESENT NUMBER'SIGNAL SELECT ⍸(t=N)⍀~msk
n[i]←vals

⍝ Split inheritance reference if necessary
msk←(t=K)∧¯1⌽(t=V)∧¯1⌽(t=K)∧n∊⊂':class'
tm d t n pos end msk⌿⍨←⊂1+msk ⋄ i←⍸2<⌿0⍪msk
t[i+1]←V ⋄ n[i]←1↑¨n[i] ⋄ n[i+1]←1↓¨n[i+1] ⋄ end[i]←pos[i+1]←pos[i]+1
t[i+1]←V ⋄ n[i]←1↑¨n[i] ⋄ n[i+1]←1↓¨n[i+1] ⋄ end[i]←pos[i+1]←pos[i]+1

⍝ Check that all keywords are valid
KW←'NAMESPACE' 'ENDNAMESPACE' 'END' 'IF' 'ELSEIF' 'ANDIF' 'ORIF' 'ENDIF'
KW,←'WHILE' 'ENDWHILE' 'UNTIL' 'REPEAT' 'ENDREPEAT' 'LEAVE' 'FOR' 'ENDFOR'
Expand Down Expand Up @@ -207,6 +207,6 @@ TK←{⍺←⊢
⍝ Convert n field to symbols and add a symbol table
sym←∪('')(,'⍵')(,'⍺')'⍺⍺' '⍵⍵'(,'∇')'∇∇'⍬(,';'),n
n←-sym⍳n

(d t k n pos end)sym IN
}
}
64 changes: 32 additions & 32 deletions cmp/util.apl
Expand Up @@ -12,38 +12,38 @@ assert←{

∇ {Z}←{MSG}SIGNAL N;CR;LF;linestarts;lineof;mkdm;quotelines;en;msg;dmx
CR LF←⎕UCS 13 10
linestarts←⍸1⍪IN∊CR LF
lineof←{∊b+⍳¨linestarts[l+1]-b←linestarts[l←linestarts⍸⍵]}
mkdm←{⍺←2
line←linestarts⍸⍵
no←'[',(⍕1+line),'] '
beg←linestarts[line]
i←(~IN[i]∊CR LF)⌿i←beg+⍳linestarts[line+1]-beg
(⎕EM ⍺)(no,IN[i])(' ^'[i∊⍵],⍨' '⍴⍨≢no)
}
tabify←{1 8[⍺]⌿' '@(⍺⍨)⍵}
quotelines←{
lines←∪linestarts⍸,⍵
nos←(1 0⍴⍨2×≢lines)⍀'[',(⍕⍪1+lines),⍤1⊢'] '
beg←linestarts[lines] ⋄ end←linestarts[lines+1]
m←∊∘⍵¨i←beg+⍳¨end-beg ⋄ t←(⎕UCS 9)=txt←IN∘I¨i
¯1↓∊nos,(~∘CR LF¨⍪,(t tabify¨txt),⍪t tabify¨' ▔'∘I¨m),CR
}
→HAS_MSG⌿⍨0≠⎕NC'MSG' ⋄ MSG←2 ''
HAS_MSG:en msg←¯2↑2,⊆MSG
⎕THIS.EN←en ⋄ ⎕THIS.DM←en mkdm ⊃N
dmx←('EN' en)('Category' 'Compiler')('Vendor' 'Co-dfns')
dmx,←⊂'Message'((⊢↑⍨(2*20)⌊≢)msg,CR,quotelines N)
⎕SIGNAL ⊂dmx
Z←0
CR LF←⎕UCS 13 10
linestarts←⍸1⍪IN∊CR LF

lineof←{∊b+⍳¨linestarts[l+1]-b←linestarts[l←linestarts⍸⍵]}

mkdm←{⍺←2
line←linestarts⍸⍵
no←'[',(⍕1+line),'] '
beg←linestarts[line]
i←(~IN[i]∊CR LF)⌿i←beg+⍳linestarts[line+1]-beg
(⎕EM ⍺)(no,IN[i])(' ^'[i∊⍵],⍨' '⍴⍨≢no)
}

tabify←{1 8[⍺]⌿' '@(⍺⍨)⍵}

quotelines←{
lines←∪linestarts⍸,⍵
nos←(1 0⍴⍨2×≢lines)⍀'[',(⍕⍪1+lines),⍤1⊢'] '
beg←linestarts[lines] ⋄ end←linestarts[lines+1]
m←∊∘⍵¨i←beg+⍳¨end-beg ⋄ t←(⎕UCS 9)=txt←IN∘I¨i
¯1↓∊nos,(~∘CR LF¨⍪,(t tabify¨txt),⍪t tabify¨' ▔'∘I¨m),CR
}

→HAS_MSG⌿⍨0≠⎕NC'MSG' ⋄ MSG←2 ''

HAS_MSG:en msg←¯2↑2,⊆MSG

⎕THIS.EN←en ⋄ ⎕THIS.DM←en mkdm ⊃N
dmx←('EN' en)('Category' 'Compiler')('Vendor' 'Co-dfns')
dmx,←⊂'Message'((⊢↑⍨(2*20)⌊≢)msg,CR,quotelines N)
⎕SIGNAL ⊂dmx
Z←0

D2P←{0=≢⍵:⍬ ⋄ p⊣2{p[⍵]←⍺[⍺⍸⍵]}⌿⊢∘⊂⌸⍵⊣p←⍳≢⍵}
Expand Down
55 changes: 29 additions & 26 deletions tests/t0099_parsing.apln
Expand Up @@ -21,9 +21,9 @@ ERRS←{⍺←⊢ ⋄ ⍵⍵::1 ⋄ 0⊣⍺ ⍺⍺ ⍵}

∇{Z}←TEST;src;p;d;t;k;n;lx;pos;end;xn;xt;sym;IN;CD
Z←⍪⍬

CD←##.codfns

TAP PARSE NS '∇FN' '∇'
TAP t=CD.(F T H)
TAP p d=(0 0 1)(0 1 2)
Expand All @@ -33,7 +33,7 @@ ERRS←{⍺←⊢ ⋄ ⍵⍵::1 ⋄ 0⊣⍺ ⍺⍺ ⍵}
TAP pos end=(0 11 12)(30 16 14)
TAP xn xt≡¨(,⊂'FN')(,1)
⎕←''

TAP PARSE NS '∇FN X' '∇'
TAP t=CD.(F T H V)
TAP p d=(0 0 1 2)(0 1 2 3)
Expand All @@ -43,7 +43,7 @@ ERRS←{⍺←⊢ ⋄ ⍵⍵::1 ⋄ 0⊣⍺ ⍺⍺ ⍵}
TAP pos end=(0 11 12 15)(32 18 16 16)
TAP xn xt≡¨(,⊂'FN')(,2)
⎕←''

TAP PARSE NS '∇X FN Y' '∇'
TAP t=CD.(F T H V V)
TAP p d=(0 0 1 2 2)(0 1 2 3 3)
Expand All @@ -53,7 +53,7 @@ ERRS←{⍺←⊢ ⋄ ⍵⍵::1 ⋄ 0⊣⍺ ⍺⍺ ⍵}
TAP pos end=(0 11 12 12 17)(34 20 18 13 18)
TAP xn xt≡¨(,⊂'FN')(,2)
⎕←''

TAP PARSE NS '∇Z←FN' '∇'
TAP t=CD.(F T H V)
TAP p d=(0 0 1 2)(0 1 2 3)
Expand All @@ -63,7 +63,7 @@ ERRS←{⍺←⊢ ⋄ ⍵⍵::1 ⋄ 0⊣⍺ ⍺⍺ ⍵}
TAP pos end=(0 11 12 12)(32 18 16 13)
TAP xn xt≡¨(,⊂'FN')(,1)
⎕←''

TAP PARSE NS '∇Z←FN X' '∇'
TAP t=CD.(F T H V V)
TAP p d=(0 0 1 2 2)(0 1 2 3 3)
Expand All @@ -73,7 +73,7 @@ ERRS←{⍺←⊢ ⋄ ⍵⍵::1 ⋄ 0⊣⍺ ⍺⍺ ⍵}
TAP pos end=(0 11 12 12 17)(34 20 18 13 18)
TAP xn xt≡¨(,⊂'FN')(,2)
⎕←''

TAP PARSE NS '∇Z←X FN Y' '∇'
TAP t=CD.(F T H V V V)
TAP p d=(0 0 1 2 2 2)(0 1 2 3 3 3)
Expand Down Expand Up @@ -143,12 +143,12 @@ ERRS←{⍺←⊢ ⋄ ⍵⍵::1 ⋄ 0⊣⍺ ⍺⍺ ⍵}
TAP pos end=(0 11 12 12 14 16 21 23)(40 26 24 13 15 17 22 24)
TAP xn xt≡¨(,⊂'FN')(,4)
⎕←''

TAP TOKENIZE ':Class blah :X' ':EndClass'
TAP TOKENIZE ':Class Blah:X' ':EndClass'
TAP TOKENIZE ':Class Blah : X' ':EndClass'
⎕←''

TAP PARSE NS '∇{X} FN Y' '∇'
TAP t=CD.(F T H V V)
TAP p d=(0 0 1 2 2)(0 1 2 3 3)
Expand All @@ -158,7 +158,7 @@ ERRS←{⍺←⊢ ⋄ ⍵⍵::1 ⋄ 0⊣⍺ ⍺⍺ ⍵}
TAP pos end=(0 11 12 13 19)(36 22 20 14 20)
TAP xn xt≡¨(,⊂'FN')(,2)
⎕←''

TAP PARSE NS '∇Z←{X}FN Y' '∇'
TAP t=CD.(F T H V V V)
TAP p d=(0 0 1 2 2 2)(0 1 2 3 3 3)
Expand Down Expand Up @@ -208,7 +208,7 @@ ERRS←{⍺←⊢ ⋄ ⍵⍵::1 ⋄ 0⊣⍺ ⍺⍺ ⍵}
TAP pos end=(0 11 12 12 15 18 23 25)(42 28 26 13 16 19 24 26)
TAP xn xt≡¨(,⊂'FN')(,4)
⎕←''

TAP PARSE NS '∇{Z}←FN' '∇'
TAP t=CD.(F T H V)
TAP p d=(0 0 1 2)(0 1 2 3)
Expand All @@ -218,7 +218,7 @@ ERRS←{⍺←⊢ ⋄ ⍵⍵::1 ⋄ 0⊣⍺ ⍺⍺ ⍵}
TAP pos end=(0 11 12 13)(34 20 18 14)
TAP xn xt≡¨(,⊂'FN')(,1)
⎕←''

TAP PARSE NS '∇{Z}←FN X' '∇'
TAP t=CD.(F T H V V)
TAP p d=(0 0 1 2 2)(0 1 2 3 3)
Expand All @@ -228,7 +228,7 @@ ERRS←{⍺←⊢ ⋄ ⍵⍵::1 ⋄ 0⊣⍺ ⍺⍺ ⍵}
TAP pos end=(0 11 12 13 19)(36 22 20 14 20)
TAP xn xt≡¨(,⊂'FN')(,2)
⎕←''

TAP PARSE NS '∇{Z}←X FN Y' '∇'
TAP t=CD.(F T H V V V)
TAP p d=(0 0 1 2 2 2)(0 1 2 3 3 3)
Expand Down Expand Up @@ -258,7 +258,7 @@ ERRS←{⍺←⊢ ⋄ ⍵⍵::1 ⋄ 0⊣⍺ ⍺⍺ ⍵}
TAP pos end=(0 11 12 13 16 18 23 25)(42 28 26 14 17 19 24 26)
TAP xn xt≡¨(,⊂'FN')(,4)
⎕←''

TAP PARSE NS '∇{Z}←{X}FN Y' '∇'
TAP t=CD.(F T H V V V)
TAP p d=(0 0 1 2 2 2)(0 1 2 3 3 3)
Expand Down Expand Up @@ -288,7 +288,7 @@ ERRS←{⍺←⊢ ⋄ ⍵⍵::1 ⋄ 0⊣⍺ ⍺⍺ ⍵}
TAP pos end=(0 11 12 13 17 20 25 27)(44 30 28 14 18 21 26 28)
TAP xn xt≡¨(,⊂'FN')(,4)
⎕←''

TAP PARSE NS '∇FN;blah;X;Y;nothing' '∇'
TAP t=CD.(F T H V V V V)
TAP p d=(0 0 1 2 2 2 2)(0 1 2 3 3 3 3)
Expand All @@ -298,7 +298,7 @@ ERRS←{⍺←⊢ ⋄ ⍵⍵::1 ⋄ 0⊣⍺ ⍺⍺ ⍵}
TAP pos end=(0 11 12 15 20 22 24)(47 33 31 19 21 23 31)
TAP xn xt≡¨(,⊂'FN')(,1)
⎕←''

TAP PARSE NS '∇FN(X Y Z)' '∇'
TAP t=CD.(F T H V V V)
TAP p d=(0 0 1 2 2 2)(0 1 2 3 3 3)
Expand All @@ -308,7 +308,7 @@ ERRS←{⍺←⊢ ⋄ ⍵⍵::1 ⋄ 0⊣⍺ ⍺⍺ ⍵}
TAP pos end=(0 11 12 15 17 19)(37 23 21 16 18 20)
TAP xn xt≡¨(,⊂'FN')(,2)
⎕←''

TAP PARSE NS '∇(Z1 Z2 Z3)←FN' '∇'
TAP t=CD.(F T H V V V)
TAP p d=(0 0 1 2 2 2)(0 1 2 3 3 3)
Expand Down Expand Up @@ -368,7 +368,7 @@ ERRS←{⍺←⊢ ⋄ ⍵⍵::1 ⋄ 0⊣⍺ ⍺⍺ ⍵}
TAP pos end=(0 11 12 14 17 20 26 29 34 37 39 41)(59 45 43 16 19 22 27 30 35 38 40 42)
TAP xn xt≡¨(,⊂'FN')(,4)
⎕←''

TAP PARSE NS '∇FN' 'L1:' '∇'
TAP t=CD.(F T H L)
TAP p d=(0 0 1 1)(0 1 2 2)
Expand All @@ -377,29 +377,32 @@ ERRS←{⍺←⊢ ⋄ ⍵⍵::1 ⋄ 0⊣⍺ ⍺⍺ ⍵}
TAP lx=4 0 0 0
TAP pos end=(0 11 12 15)(34 20 14 17)
⎕←''

TAP PARSE NS '∇FN' ':If 0' ':EndIf' '∇'
⎕←''
TAP (,⊂'⎕SOUND')(,⊂2)TOKENIZE NS '∇FN' '⎕SOUND 5' '∇'

TAP (,⊂'⎕SOUND')(,⊂2)TOKENIZE NS '∇FN' '⎕SOUND 5' '∇'
TAP PARSE NS '('':namespace'')' ''
TAP PARSE NS '∇FN;⎕IO' '∇'
TAP TOKENIZE NS'∇FN' '{5:6}⍬' '∇'
TAP TOKENIZE ,⊂'1 ¯2'
TAP TOKENIZE ERRS 2 ,⊂'1¯2'
TAP TOKENIZE ERRS 2 ,⊂'1.¯2'
⎕←''

TAP PARSE NS 'FN←{0:5}' ''
TAP t=CD.(F B V C F G A A F G A A)
TAP p d=(0 0 1 1 3 4 5 5 3 8 9 9)(0 1 2 2 3 4 5 5 3 4 5 5)
TAP k=0 2 2 2 2 0 1 1 3 0 1 1
⎕←''

TAP PARSE NS 'FN←{0::5}' ''
TAP t=CD.(F B V C F G A A F G A A)
⎕←''

⎕←''

TAP PARSE ERRS 2 NS '∇FN;' '∇'
TAP PARSE ERRS 2 NS '∇FN;A B' '∇'


:EndNamespace
:EndNamespace