Commits

ZyX_I  committed 3a7713e

@/fwc: Fixed `tuple' and `list' checks: they now accept specifications with more then one atom

  • Participants
  • Parent commits 3561739

Comments (0)

Files changed (3)

File plugin/frawor/fwc/compiler.vim

     endif
     return self.getvar(a:str)
 endfunction
-"▶1 compilepipe    :: pipecontext, idx + self → self + self
-function s:constructor.compilepipe(pipe, idx)
+"▶1 compilepipe    :: pipecontext, idx, needscheck + self → self + self
+let s:pipechecks={
+            \'substitute': ['intfunc', 'type',   [type('')]],
+            \      'take': ['intfunc', 'type',   [type('')]],
+            \       'run': ['intfunc', 'isfunc', 0         ],
+            \      'earg': ['intfunc', 'type',   [type('')]],
+            \     'tuple': ['intfunc', 'type',   [type([])]],
+            \      'list': ['intfunc', 'type',   [type([])]],
+            \      'dict': ['intfunc', 'type',   [type({})]],
+        \}
+function s:constructor.compilepipe(pipe, idx, ...)
     let curargstr=self.argstr()
     "▶2 `func' pipe
     if a:pipe[1][0] is 'func'
     "▶2 Built-in pipes
     elseif a:pipe[1][0] is 'intfunc'
         let desc=a:pipe[1][1:]
+        if a:0 && has_key(s:pipechecks, desc[0])
+            call self.compilecheck(['check', s:pipechecks[desc[0]]], a:idx)
+        endif
         "▶3 `func', `eval'
         if desc[0] is 'func' || desc[0] is 'eval'
             call self.compilepipe(desc, a:idx)
             let i=0
             for arg in desc[1]
                 call add(self.subs, i)
-                call self.compilepipe(arg, a:idx.'.'.i)
+                call self.compilearg(arg, a:idx.'.'.i)
                 call remove(self.subs, -1)
                 let i+=1
             endfor
                         \ 'while '.istr.'<'.largstr)
                         \.deeper()
             call add(self.subs, [istr])
-            call self.compilepipe(desc[1], a:idx)
+            call self.compilearg(desc[1], a:idx)
             call self.add('let '.istr.'+=1')
             call remove(self.subs, -1)
             call self.up().close()
                 let i=0
                 for arg in desc[1]
                     call add(self.subs,  i)
-                    call self.compilecheck(arg, idx.'.'.i)
+                    call self.compilearg(arg, idx.'.'.i)
                     call remove(self.subs, -1)
                     let i+=1
                 endfor
                             \ 'while '.istr.'<'.largstr)
                             \.deeper()
                 call add(self.subs, [istr])
-                call self.compilecheck(desc[1], idx)
+                call self.compilearg(desc[1], idx)
                 call self.add('let '.istr.'+=1')
                 call remove(self.subs, -1)
                 call self.up().close()
     endif
     return self
 endfunction
-"▶1 compileintfunc :: intfunccontext, idx + self → self + self
-function s:constructor.compileintfunc(intfunc, idx)
-    return self['compile'.self.type]([self.type, a:intfunc], a:idx)
+"▶1 compilearg     :: argcontext, idx[, defcomptype] + self → self + self
+function s:constructor.compilearg(argcon, idx, ...)
+    let type=get(a:000, 0, self.type)
+    if a:argcon[0] is 'arg'
+        let arg=a:argcon[1:]
+    else
+        let arg=a:argcon
+    endif
+    let check=['check']
+    let msg=[]
+    let i=0
+    let squashedlen=0
+    for proc in arg
+        if proc[0] is 'check'
+            let squashedlen+=1
+            call add(check, proc[1])
+            let i+=1
+            continue
+        elseif proc[0] is 'pipe' && proc[1][0] is 'intfunc'
+                    \&& has_key(s:pipechecks, proc[1][1])
+            call add(check, s:pipechecks[proc[1][1]])
+        elseif self.type is 'filter' && proc[0] is 'intfunc'
+                    \&& has_key(s:pipechecks, proc[1])
+            call add(check, s:pipechecks[proc[1]])
+        endif
+        if len(check)>1
+            call self.compilecheck(check, a:idx.'.'.(i+((squashedlen)?
+                        \                                   (1-squashedlen):
+                        \                                   (0))))
+            let squashedlen=0
+            call remove(check, 1, -1)
+        endif
+        let compargs=[proc, a:idx.'.'.i]
+        let comptype=proc[0]
+        if comptype is 'intfunc'
+            let comptype=type
+            let compargs[0]=[comptype, compargs[0]]
+        endif
+        call call(self['compile'.comptype], compargs, self)
+        let i+=1
+    endfor
+    if len(check)>1
+        call self.compilecheck(check, a:idx.'.'.(i+1-len(check)))
+        call remove(check, 1, -1)
+    endif
+    if type(self.subs[-1])==type(0)
+        let self.subs[-1]+=1
+    endif
+    return self
 endfunction
 "▶1 compileadesc   :: adescr + self → self + self
-let s:pipechecks={
-            \'substitute': ['intfunc', 'type',   [type('')]],
-            \      'take': ['intfunc', 'type',   [type('')]],
-            \       'run': ['intfunc', 'isfunc', 0         ],
-            \      'earg': ['intfunc', 'type',   [type('')]],
-            \     'tuple': ['intfunc', 'type',   [type([])]],
-            \      'list': ['intfunc', 'type',   [type([])]],
-            \      'dict': ['intfunc', 'type',   [type({})]],
-        \}
 function s:constructor.compileadesc(adescr)
     if !has_key(a:adescr, 'minimum')
         call s:F.getlenrange(a:adescr)
         let a:adescr.checkedfor=1
     endif
     if has_key(a:adescr, 'arg')
-        let check=['check']
-        for arg in a:adescr.arg
-            let msg=[]
-            let i=0
-            let squashedlen=0
-            for proc in arg
-                if proc[0] is 'check'
-                    let squashedlen+=1
-                    call add(check, proc[1])
-                    let i+=1
-                    continue
-                elseif proc[0] is 'pipe' && proc[1][0] is 'intfunc'
-                            \&& has_key(s:pipechecks, proc[1][1])
-                    call add(check, s:pipechecks[proc[1][1]])
-                elseif self.type is 'filter' && proc[0] is 'intfunc'
-                            \&& has_key(s:pipechecks, proc[1])
-                    call add(check, s:pipechecks[proc[1]])
-                endif
-                if len(check)>1
-                    call self.compilecheck(check, i+((squashedlen)?
-                                \                       (1-squashedlen):
-                                \                       (0)))
-                    let squashedlen=0
-                    call remove(check, 1, -1)
-                endif
-                call call(self['compile'.proc[0]], [proc, i], self)
-                let i+=1
-            endfor
-            if len(check)>1
-                call self.compilecheck(check, i+1-len(check))
-                call remove(check, 1, -1)
-            endif
-            let self.subs=[self.subs[0]+1]
-        endfor
+        call map(a:adescr.arg, 'self.compilearg(v:val, v:key)')
     endif
     " TODO
     return self

File test/fwccheck.ok

 plugin/frawor/fwc/compiler:nsfunc
 plugin/frawor/fwc/compiler:invlstlen
 plugin/frawor/fwc/compiler:typefail
+::: Section <Pipes/Built-in pipes/list>
 plugin/frawor/fwc/compiler:typefail
+plugin/frawor/fwc/compiler:typefail
+plugin/frawor/fwc/compiler:typefail
+plugin/frawor/fwc/compiler:typefail
+plugin/frawor/fwc/compiler:typefail
+plugin/frawor/fwc/compiler:nbool
 ::: Section <Pipes/Built-in pipes/key>
 plugin/frawor/fwc/compiler:nindict
 plugin/frawor/fwc/compiler:typefail

File test/fwctests.dat

 ['tuple bool, bool',       'filter'], [['', 'cba']],        [[0, 1]]
 ['tuple bool, bool',       'filter'], [['abc']],            0
 ['tuple bool, bool',       'filter'], ['abc'],              0
+['tuple (?bool |=(!@.@))', 'filter'], [[1]],                [[0]]
+#▶3 list
 ['list bool',              'filter'], ["['abc', 'def']"],   0
 ['list bool',              'filter'], [['abc', 'def']],     [[1, 1]]
+['list tuple bool, bool',  'filter'], [['ab', 'de']],       0
+['list tuple bool, bool',  'filter'], [[[1, 2], [0, 3]]],   [[[1, 1], [0, 1]]]
+['list list list ?bool',   'filter'], [1],                  0
+['list list list ?bool',   'filter'], [[1]],                0
+['list list list ?bool',   'filter'], [[[1]]],              0
+['list list list ?bool',   'filter'], [[[[1]]]],            [[[[1]]]]
+['list list list ?bool',   'filter'], [[[[[]]]]],           0
+['list list list ?bool',   'filter'], [[[[1], [0, 1]]]],    [[[[1], [0, 1]]]]
+['list (?bool |=(!@.@))',  'filter'], [[1, 0, 1]],          [[0, 1, 0]]
 #▶3 key
 ['key={"abc": 1}~exact',   'filter'], ['abc'],              ['abc']
 ['key={"abc": 1}',         'filter'], ['abc'],              ['abc']