Commits

ZyX_I  committed 40b9ff1

@/fwc: Added `in' check, partially implemented `in' pipe

  • Participants
  • Parent commits cd60dca

Comments (0)

Files changed (4)

File plugin/frawor/fwc/compiler.vim

             \ 'evalfail': 'evaluating argument failed with exception %s',
             \   'nrange': '%s is not in range [%s, %s]',
             \  'nindict': '%s is not in dictionary',
+            \  'ninlist': 'argument is not in list',
         \}, '"Error while processing check %u for %s: ".v:val'))
 let s:_messages._types=['number', 'string', 'function reference', 'list',
             \           'dictionary']
     elseif a:var[0] is 'cur'
         return self.argstr().s:F.substostr(self.subs[:-1-a:var[1]]+a:var[2:])
     elseif a:var[0] is 'list'
-        let r='['
-        for item in a:var[1:]
-            let titem=type(item)
-            if titem==type('')
-                let r.=s:F.string(item)
-            elseif titem==type([])
-                if item[0] is 'expr'
-                    let r.=item[1]
-                elseif item[0] is 'func'
-                    let r.=self.getfunc(item)
-                else
-                    let r.=self.getvar(item)
-                endif
-            endif
-            let r.=', '
-            unlet item
-        endfor
-        let r.=']'
-        return r
+        return '['.join(map(a:var[1:], 'type(v:val)=='.type('').'?'.
+                    \                       's:F.string(v:val):'.
+                    \                       'self.getvar(v:val)'), ', ').']'
     elseif a:var[0] is 'evaluate'
         return eval(substitute(self.getvar(a:var[1]), '@%@', 'self.vars', 'g'))
     elseif a:var[0] is 'func'
                         \join(map(desc[2:], 'self.compilestring(v:val)'), ', ').
                         \')')
         elseif desc[0] is 'in'
-            " TODO
+            if len(desc)==2 || (desc[2][1][0] is 'intfunc' &&
+                        \       desc[2][1][1] is 'exact' &&
+                        \       desc[2][1][2] is 0)
+                call self.compilecheck(['check', a:pipe[1]], a:idx)
+            else
+                call self.addtypecond([type('')], idx)
+                " TODO
+            endif
         elseif desc[0] is 'key'
             if len(desc)==2 || (desc[2][1][0] is 'intfunc' &&
                         \       desc[2][1][1] is 'exact' &&
                 call self.nextthrow('!has_key('.self.getvar(desc[1]).', '.
                             \                   curargstr.')',
                             \       'nindict', idx, '@#@', curargstr)
+            "▶3 `in'
             elseif desc[0] is 'in'
-                " TODO
+                let addedcond=1
+                call self.nextthrow('index('.self.getvar(desc[1]).', '.
+                            \                curargstr.')==-1',
+                            \       'ninlist', idx, '@#@')
             "▶3 `haskey'
             elseif desc[0] is 'haskey'
                 let addedcond=1

File plugin/frawor/fwc/parser.vim

 " Replaces {argument} with the result of evaluating {expr}
 let s:args.pipe.eval=['expr']
 "▶3 pipe.run
-" Replaces {argument} with the result of calling itself with {list} as argument 
+" Replaces {argument} with the result of calling itself with {var} as argument 
 " list
-let s:args.pipe.run=['list']
+let s:args.pipe.run=['var']
 "▶3 pipe.earg
 " Replaces {argument} with the result of evaluating itself
 let s:args.pipe.earg=[]
     return self.conclose()
 endfunction
 "▶1 getlist    :: &self
-" Input: ( "$" {var} | "*" {func} | "=" {expr} | {str} | {wordchar}+ )* "]"?
-" Output: context(list, ({var}|{expr}|String)*)
+" Input: ( "$" {var} | {str} | {wordchar}+ | {var} )* "]"?
+" Output: context(list, ({var}|String)*)
 function s:parser.getlist()
     call self.addcon('list')
     while self.len
             break
         elseif c is '$'
             call self.getvar()
-        elseif c is '='
-            call self.getexpr()
-        elseif c is '*'
-            call self.getfunc()
         elseif c is '"'
             call self.add(self.readstr())
         elseif c is "'"
             call self.add(self.readsstr())
         elseif c=~#'^\w'
             call self.add(c)
+        else
+            call self.ungetc(c).getvar()
         endif
     endwhile
     return self.conclose()

File test/fwccheck.ok

 plugin/frawor/fwc/compiler:runfail
 plugin/frawor/fwc/compiler:evalfail
 plugin/frawor/fwc/compiler:nsfunc
+::: Section <Pipes/Built-in pipes/key>
 plugin/frawor/fwc/compiler:nindict
 plugin/frawor/fwc/compiler:typefail
+::: Section <Pipes/Built-in pipes/in>
+plugin/frawor/fwc/compiler:ninlist
+plugin/frawor/fwc/compiler:ninlist
 ::: Section <Pipes/Built-in pipes/Substitute>
 plugin/frawor/fwc/compiler:typefail
 ::: Section <Pipes/Built-in pipes/Bool>
 plugin/frawor/fwc/compiler:nreg
 plugin/frawor/fwc/compiler:nindict
 plugin/frawor/fwc/compiler:typefail
+plugin/frawor/fwc/compiler:ninlist
+plugin/frawor/fwc/compiler:ninlist
 ::: Section <Checks/Built-in checks/range>
 plugin/frawor/fwc/compiler:typefail
 plugin/frawor/fwc/compiler:nrange

File test/fwctests.dat

 ['func revstring',         'filter'], ['abc'],              ['cba']
 ['eval string(@.@)',       'filter'], ['abc'],              ["'abc'"]
 ['run [abc]',              'filter'], ['string'],           ["'abc'"]
-['run [abc]',              'filter'], [function("string")], ["'abc'"]
+['run [abc]',              'filter'], [function('string')], ["'abc'"]
 ['run []',                 'filter'], ['()'],               0
 ['run [$[abc def]]',       'filter'], [s:.revstring],       0
 ['earg',                   'filter'], ['string("abc")'],    ["'abc'"]
 ['earg',                   'filter'], ['('],                0
 ['isfunc',                 'filter'], [0],                  0
-['isfunc',                 'filter'], [function("tr")],     [function("tr")]
+['isfunc',                 'filter'], [function('tr')],     [function("tr")]
+#▶3 key
 ['key={"abc": 1}~exact',   'filter'], ['abc'],              ['abc']
 ['key={"abc": 1}',         'filter'], ['abc'],              ['abc']
 ['key={"abc": 1}',         'filter'], ['ab'],               0
 ['key={"abc": 1}',         'filter'], [0],                  0
+#▶3 in
+['in [abc def]',           'filter'], ['abc'],              ['abc']
+['in =["a","b"]',          'filter'], ['abc'],              0
+['in =["a",0]',            'filter'], ['a'],                ['a']
+['in =["a",0]',            'filter'], ['0'],                0
+['in =["a",0]',            'filter'], [0],                  [0]
+['in =["a",0]~exact 0',    'filter'], [0],                  [0]
 #▶3 Substitute
 :let s:regex='\v.'
 :let s:replacement='def'
 ['func ordered',    'check'], ['acb'],              0
 ['eval empty(@.@)', 'check'], ['abc'],              0
 ['eval empty(@.@)', 'check'], [''],                 1
-['bool',            'check'], [""],                 0
+['bool',            'check'], [''],                 0
 ['bool',            'check'], [0],                  1
 ['bool',            'check'], [1],                  1
 ['bool',            'check'], [2],                  0
 ['key={"abc": 1}',  'check'], ['abc'],              1
 ['key={"abc": 1}',  'check'], ['ab'],               0
 ['key={"abc": 1}',  'check'], [0],                  0
+['in [abc def]',    'check'], ['abc'],              1
+['in =["a","b"]',   'check'], ['abc'],              0
+['in =["a",0]',     'check'], ['a'],                1
+['in =["a",0]',     'check'], ['0'],                0
+['in =["a",0]',     'check'], [0],                  1
 ['_',               'check'], [[[[]]]],             1
 ['any',             'check'], [[[[]]]],             1
 #▶3 range