Commits

ZyX_I  committed 3561739

@/fwc: Implemented `list' check and pipe

  • Participants
  • Parent commits 19d2246

Comments (0)

Files changed (3)

File plugin/frawor/fwc/compiler.vim

 endfunction
 "▶1 nextcond       :: [condition] + self → self + self
 function s:constructor.nextcond(...)
-    if type(self.l[-1])==type([])
-        let prevline=self.l[-2]
-    else
-        let prevline=self.l[-1]
+    if !empty(self.l)
+        if type(self.l[-1])==type([])
+            let prevline=self.l[-2]
+        else
+            let prevline=self.l[-1]
+        endif
+        let command=prevline[:(stridx(prevline, ' ')-1)]
     endif
-    let command=prevline[:(stridx(prevline, ' ')-1)]
-    if command is 'if' || command is 'elseif'
+    if exists('command') && (command is 'if' || command is 'elseif')
         if a:0
             return self.add('elseif '.a:1).deeper()
         else
     let args=copy(a:000)
     let curidx=index(args, '@#@')
     if curidx!=-1
-        let args=map(args[:(curidx-1)],'string(v:val)')+[string(self.argstr())]+
+        let args=map(args[:(curidx-1)], 'string(v:val)')+[self.argstr(1)]+
                     \args[(curidx+1):]
     endif
     return self.add('call add(@$@messages, ['.string(a:msg).', '.
 "▶1 substostr      :: [subscript] → String
 function s:F.substostr(subscripts)
     let r=''
-    for subs in a:subscripts
-        let tsubs=type(subs)
-        if tsubs==type('')
-            if subs=~#'^\w\+$'
-                let r.='.'.subs
+    for sub in a:subscripts
+        let tsub=type(sub)
+        if tsub==type('')
+            if sub=~#'^\w\+$'
+                let r.='.'.sub
             else
-                let r.='['.s:F.string(subs).']'
+                let r.='['.s:F.string(sub).']'
             endif
-        elseif tsubs==type(0)
-            let r.='['.subs.']'
-        elseif tsubs==type([])
-            let r.='['.join(subs, ':').']'
+        elseif tsub==type(0)
+            let r.='['.sub.']'
+        elseif tsub==type([])
+            let r.='['.join(sub, ':').']'
         endif
-        unlet subs
+        unlet sub
     endfor
     return r
 endfunction
     elseif a:var[0] is 'string'
         return s:F.string(a:var[1])
     elseif a:var[0] is 'argument'
-        return self.argstr(self.nargs[-1]+a:var[1]).s:F.substostr(a:var[2:])
+        return self.argstr(0, [self.subs[0]+a:var[1]]+a:var[2:])
     elseif a:var[0] is 'cur'
-        return self.argstr().s:F.substostr(self.subs[:-1-a:var[1]]+a:var[2:])
+        return self.argstr(0, self.subs[:-1-a:var[1]]+a:var[2:])
     elseif a:var[0] is 'list'
         return '['.join(map(a:var[1:], 'type(v:val)=='.type('').'?'.
                     \                       's:F.string(v:val):'.
         return self.argstr()
     endif
 endfunction
-"▶1 argstr         :: [narg] + self → String
+"▶1 argstr         :: [genString::Bool, [subscript]] + self → String
+"▶2 addargchunk    :: [chunk], chunk::String, literal::Bool → _ + chunks
+function s:F.addargchunk(chunks, chunk, literal)
+    if a:literal==(len(a:chunks)%2)
+        call add(a:chunks, a:chunk)
+    else
+        let a:chunks[-1].=a:chunk
+    endif
+endfunction
+"▲2
 function s:constructor.argstr(...)
-    return '@@@['.get(a:000, 0, self.nargs[-1]).']'.s:F.substostr(self.subs)
+    if get(a:000, 0, 0)
+        let chunks=['@@@']
+        for sub in get(a:000, 1, self.subs)
+            let tsub=type(sub)
+            if tsub==type('')
+                if sub=~#'^\w\+$'
+                    call s:F.addargchunk(chunks, '.'.sub, 0)
+                else
+                    call s:F.addargchunk(chunks, '['.s:F.string(sub).']', 0)
+                endif
+            elseif tsub==type(0)
+                call s:F.addargchunk(chunks, '['.sub.']', 0)
+            else
+                if type(sub[0])==type('')
+                    call s:F.addargchunk(chunks, '[', 0)
+                    call s:F.addargchunk(chunks, sub[0], 1)
+                    if len(sub)>1
+                        call s:F.addargchunk(chunks, ':', 0)
+                        call s:F.addargchunk(chunks, sub[1], 1)
+                    endif
+                    call s:F.addargchunk(chunks, ']', 0)
+                else
+                    call s:F.addargchunk(chunks, '['.join(sub, ':').']', 0)
+                endif
+            endif
+            unlet sub
+        endfor
+        return join(map(chunks, 'v:key%2 ? v:val : string(v:val)'), '.')
+    else
+        return '@@@'.s:F.substostr(get(a:000, 1, self.subs))
+    endif
 endfunction
 "▶1 compilemsg     :: msgcontext, _ + self → self + self
 function s:constructor.compilemsg(msg, idx)
         if msgarg[0] is 'curval'
             call add(msg, self.argstr())
         elseif msgarg[0] is 'curarg'
-            call add(msg, nargs[-1])
+            call add(msg, self.subs[0])
         else
             call add(msg, substitute(s:constructor.getvar(msgarg), '@#@',
                         \            escape(self.argstr(), '\&~'), 'g'))
             endfor
         "▶3 `list'
         elseif desc[0] is 'list'
-            " TODO
+            let conid=printf('%X', len(self.stack))
+            let largstr='@$@larg'.conid
+            let istr='@$@i'.conid
+            call self.add('let '.largstr.'=len('.curargstr.')',
+                        \ 'let '.istr.'=0',
+                        \ 'while '.istr.'<'.largstr)
+                        \.deeper()
+            call add(self.subs, [istr])
+            call self.compilepipe(desc[1], a:idx)
+            call self.add('let '.istr.'+=1')
+            call remove(self.subs, -1)
+            call self.up().close()
         "▶3 `dict'
         elseif desc[0] is 'dict'
             " TODO
                 endfor
             "▶3 `list'
             elseif desc[0] is 'list'
-                " TODO
+                call self.addtypecond([type([])], idx).close()
+                let addedcond=0
+                let conid=printf('%X', len(self.stack))
+                let largstr='@$@larg'.conid
+                let istr='@$@i'.conid
+                call self.add('let '.largstr.'=len('.curargstr.')',
+                            \ 'let '.istr.'=0',
+                            \ 'while '.istr.'<'.largstr)
+                            \.deeper()
+                call add(self.subs, [istr])
+                call self.compilecheck(desc[1], idx)
+                call self.add('let '.istr.'+=1')
+                call remove(self.subs, -1)
+                call self.up().close()
             "▶3 `dict'
             elseif desc[0] is 'dict'
                 " TODO
             \       '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)
     endif
     if !has_key(a:adescr, 'checkedfor')
-        call self.lencheck(self.nargs[-1]+a:adescr.minimum,
-                    \      self.nargs[-1]+a:adescr.maximum)
+        call self.lencheck(self.subs[0]+a:adescr.minimum,
+                    \      self.subs[0]+a:adescr.maximum)
         let a:adescr.checkedfor=1
     endif
     if has_key(a:adescr, 'arg')
                 call self.compilecheck(check, i+1-len(check))
                 call remove(check, 1, -1)
             endif
-            let self.nargs[-1]+=1
+            let self.subs=[self.subs[0]+1]
         endfor
     endif
     " TODO
                 \ 'type': a:type,
                 \'ctree': [],
                 \'stack': [],
-                \'nargs': [0],
-                \ 'subs': [],
+                \ 'subs': [0],
                 \    'l': 0,
                 \ 'vars': a:vars,
                 \ 'vids': {},

File test/fwccheck.ok

 plugin/frawor/fwc/compiler:nsfunc
 plugin/frawor/fwc/compiler:invlstlen
 plugin/frawor/fwc/compiler:typefail
+plugin/frawor/fwc/compiler:typefail
 ::: Section <Pipes/Built-in pipes/key>
 plugin/frawor/fwc/compiler:nindict
 plugin/frawor/fwc/compiler:typefail
 plugin/frawor/fwc/compiler:typefail
 plugin/frawor/fwc/compiler:ninlist
 plugin/frawor/fwc/compiler:ninlist
+plugin/frawor/fwc/compiler:typefail
+plugin/frawor/fwc/compiler:nreg
 ::: Section <Checks/Built-in checks/tuple>
 plugin/frawor/fwc/compiler:nreg
 plugin/frawor/fwc/compiler:invlstlen

File test/fwctests.dat

 ['tuple bool, bool',       'filter'], [['', 'cba']],        [[0, 1]]
 ['tuple bool, bool',       'filter'], [['abc']],            0
 ['tuple bool, bool',       'filter'], ['abc'],              0
+['list bool',              'filter'], ["['abc', 'def']"],   0
+['list bool',              'filter'], [['abc', 'def']],     [[1, 1]]
 #▶3 key
 ['key={"abc": 1}~exact',   'filter'], ['abc'],              ['abc']
 ['key={"abc": 1}',         'filter'], ['abc'],              ['abc']
 ['in =["a",0]',     'check'], ['a'],                1
 ['in =["a",0]',     'check'], ['0'],                0
 ['in =["a",0]',     'check'], [0],                  1
+['list isreg',      'check'], ["['abc']"],          0
+['list isreg',      'check'], [['abc']],            1
+['list isreg',      'check'], [['abc', '\(']],      0
 ['_',               'check'], [[[[]]]],             1
 ['any',             'check'], [[[[]]]],             1
 #▶3 tuple