Commits

ZyX_I committed fcc9aeb

@/fwc: Added onlystrings option tests, fixed `-option' scanning

Comments (0)

Files changed (6)

 Options are used to alter behavior of FWC compiler. Currently there are only 
 two options: `only' and `onlystrings'. Prefixing option with "no" will disable 
 it.
-    {options} :: "-" ( "(" {option}* ")" | {option} )
+    {options} :: ( "-" ( "(" {option}* ")" | {option} ) )*
      {option} :: "no"? ( "only" | "onlystrings" )
 
 Option       Effect ~

plugin/frawor/fwc/compiler.vim

 endfunction
 "▶1 addtypecond     :: &self(types, idx)
 function s:compiler.addtypecond(types, idx)
-    if self.o.onlystrings && self.argbase is '@@@'
-        if index(types, type(''))==-1
+    if self.o.onlystrings && self.argbase is '@@@' && len(self.subs)==1
+        if index(a:types, type(''))==-1
             call self.nextthrow(1, 'nostrings', a:idx)
         endif
         return self
 "▶1 Register decorator
 call s:_f.adddecorator('FWC', s:F.makedec)
 "▶1
-" TODO implement recursion protection
+" TODO implement recursive structures checking
 call frawor#Lockvar(s:, 'lastid,vars')
 " vim: fmr=▶,▲ sw=4 ts=4 sts=4 et tw=80

plugin/frawor/fwc/parser.vim

 " Output: add(<self.o>)
 let s:options={'only': 0, 'recursive': 0, 'onlystrings': 0}
 function s:parser.scanopts()
-    let c=self.readc()
     let self.o=copy(s:options)
     call self.add(self.o)
-    if c is '-'
+    let hasparen=0
+    let hasdash=0
+    while self.len
         let c=self.readc()
-        if c isnot '('
-            call self.ungetc(c)
-        endif
-        while self.len
-            let c=self.readc()
-            if c is ')'
-                break
-            elseif has_key(self.o, c)     " -(option)
+        if hasdash
+            if c is '('
+                let hasparen=1
+            elseif has_key(self.o, c)
                 let self.o[c]=1
-            elseif has_key(self.o, c[2:]) " -(nooption)
+                if !hasparen
+                    let hasdash=0
+                endif
+            elseif has_key(self.o, c[2:])
                 let self.o[c[2:]]=0
+                if !hasparen
+                    let hasdash=0
+                endif
+            elseif hasparen && c is ')'
+                let hasparen=0
+                let hasdash=0
             else
                 call self.throw('uoption', c)
             endif
-        endwhile
-    else
-        call self.ungetc(c)
+        elseif c is '-'
+            let hasdash=1
+        else
+            call self.ungetc(c)
+            break
+        endif
+    endwhile
+    if hasparen
+        call self.throw('unmatchp', '(')
     endif
     return self
 endfunction
 plugin/frawor/fwc/compiler:nbool
 plugin/frawor/fwc/compiler:nreg
 plugin/frawor/fwc/compiler:isnot
+::: Section <Option `onlystrings'>
+plugin/frawor/fwc/compiler:nbool
+plugin/frawor/fwc/compiler:nbool
 ::: Section <Optional arguments>
 plugin/frawor/fwc/compiler:lennmatch
 plugin/frawor/fwc/compiler:nbool

test/fwccompletetests.dat

 \function s:.startswitha(str)
 \    return a:str[0] is 'a'
 :endfunction
+
 `(in list match /^a/)
   @+
   =filter(copy(s:list), 'v:val[0] is "a"')

test/fwctests.dat

 ['-(only) |bool is =1',                  'check'], [1],        1
 ['-(only) bool',                        'filter'], [],         0
 ['-(only) bool',                        'filter'], [1],        1
+#▶1 Option `onlystrings'
+['-onlystrings (earg ?bool)',           'filter'], ['0'],      [0]
+['-onlystrings (earg ?bool)',           'filter'], ['[]'],     0
+['-onlystrings bool',                    'check'], ['0'],      1
+['-onlystrings bool',                    'check'], ['1'],      1
+['-onlystrings bool',                    'check'], ['2'],      0
+['-onlystrings bool',                   'filter'], ['0'],      [0]
+['-onlystrings bool',                   'filter'], ['1'],      [1]
+['-onlystrings bool',                   'filter'], ['2'],      [0]
+['-onlystrings bool',                   'filter'], ['yes'],    [1]
+['-onlystrings bool',                   'filter'], ['ok'],     [1]
+['-onlystrings bool',                   'filter'], ['tRuE'],   [1]
 #▶1 Optional arguments
 ['bool [bool] [bool bool bool]',         'check'], [0, 2],       0
 ['bool [bool] [bool bool bool]',         'check'], [0, 0, 2, 0], 0