Commits

ZyX_I committed 8012474

@/fwc: Fixed prefixes+(next or actions) composition

Comments (0)

Files changed (4)

plugin/frawor/fwc/compiler.vim

             \   'notfail': '`not'' check failed',
             \     'isnot': 'expected %s, but got %s',
             \       'anf': '`%s'' is not a valid action',
-            \       'pnf': 'prefix not found',
+            \       'pnf': '`%s'' is not a valid prefix',
         \}, '"Error while processing check %s for %s: ".v:val'))
 let s:_messages._types=['number', 'string', 'function reference', 'list',
             \           'dictionary']
     endif
     return self
 endfunction
+"▶1 getd           :: varname + self → varname + self
+function s:compiler.getd(var)
+    if !has_key(self.o, 'requiresd')
+        let self.o.requiresd=1
+    endif
+    return self.getlvarid('d.'.a:var)
+endfunction
 "▶1 getfunstatvar  :: varname, varinit + self → varstr + self
 function s:compiler.getfunstatvar(name, init)
     let id=printf('%x', self.vids[a:name])
     let self.vars[a:name][id]=a:init
     return '@%@'.self.getsubs([a:name, id])
 endfunction
-"▶1 addprefix
+"▶1 addprefix      :: preflist, prefix → _ + preflist
 function s:compiler.addprefix(preflist, prefix)
     if index(a:preflist, a:prefix)!=-1
         call self._throw('ambprefix', a:prefix)
                     \                           s:prefdefmatcher), plstr,
                     \                       self.argstr()))
         let removestr='remove('.base.', '.caidxstr.')'
+        if addtry
+            let argorigstr=self.getd('argorig')
+        endif
         if haslist
             call self.up().else().let(astr, 0).up().endif()
-                        \.if(astr.' isnot 0').call(removestr).up().endif()
+                        \.if(astr.' isnot 0')
         else
-            call self.call(removestr).nextthrow(astr.' is 0', 'pnf', idx)
+            call self.nextthrow(astr.' is 0', 'pnf', idx, self.argstr())
+        endif
+        if addtry
+            call self.let(argorigstr, removestr)
+        else
+            call self.call(removestr)
+        endif
+        if haslist
+            call self.up().endif()
         endif
         "▲3
         for [prefix, prefopts; args] in a:adescr.prefixes
             endif
             "▲3
         endfor
-        call self.up().up()
+        call self.up()
         if addtry
-            call self.addrestmsgs(1).catch(s:cfreg).popms()
-                        \.if('exists('.string(astr).')')
-                            \.call('insert('.base.', '.astr.')')
-                        \.up().up()
+            call self.unlet(argorigstr).up().up().addrestmsgs(1).popms()
+                \.catch(s:cfreg)
+                    \.if('exists('.string(argorigstr).')')
+                        \.call('insert('.base.', '.argorigstr.', '.caidxstr.')')
+                    \.up()
+                \.up()
+        else
+            call self.up()
         endif
     endif
     "▶2 `next' key
     let [opts, lines]=s:F.compilestr(s:vars[id], a:string, a:type, 1)
     if opts.only
         call insert(lines, 'let d={"arg": a:args}')
+    elseif has_key(opts, 'requiresd')
+        call insert(lines, 'let d={}')
     endif
     execute "function d.f(args)\n    ".
                 \substitute(substitute(substitute(
     if opts.only
         call map(lines, 'substitute(v:val, "@@@", "@$@args", "g")')
         call insert(lines, 'let @$@d={"args": @@@}')
+    elseif has_key(opts, 'requiresd')
+        call insert(lines, 'let @$@d={}')
     endif
     return [128, ((opts.only)?('@$@d.args'):('@@@')), vars, lines, [], 0]
 endfunction

plugin/frawor/fwc/constructor.vim

 function s:constructor.let(var, val)
     return self.out().deeper('let', a:var, a:val).up()
 endfunction
+"▶1 unlet      :: &self(var)
+function s:constructor.unlet(var)
+    return self.out().deeper('unlet', a:var).up()
+endfunction
 "▶1 increment  :: &self(var[, val])
 function s:constructor.increment(var, ...)
     return self.out().deeper('inc', a:var, get(a:000, 0, 1)).up()
                 call add(r, istr.'let '.remove(item, 0).'='.remove(item, 0))
             elseif type is 'inc'
                 call add(r, istr.'let '.remove(item, 0).'+='.remove(item, 0))
-            elseif type is 'call' || type is 'throw' || type is 'return'
+            elseif       type is 'call'   ||
+                        \type is 'throw'  ||
+                        \type is 'return' ||
+                        \type is 'unlet'
                 call add(r, istr.type.' '.remove(item, 0))
             elseif type is 'continue' || type is 'break'
                 call add(r, istr.type)
 plugin/frawor/fwc/compiler:pnf
 plugin/frawor/fwc/compiler:nreg
 plugin/frawor/fwc/compiler:pnf
+::: Section <Required, optional, actions, prefixes and next composition>
+plugin/frawor/fwc/compiler:tooshort
 <<< messages

test/fwctests.dat

 ['{!abc !abd}',                   'filter'], ['a', 'a'],  0
 ['{*b isreg !?a}', 'filter'], ['b', 'n', 'n'], [{'b': ['n'], 'a': 0}]
 ['{*b isreg !?a}', 'filter'], ['b', 'n', 'c'], [{'b': ['n', 'c']}]
+#▶1 Required, optional, actions, prefixes and next composition
+['{ab bool ?de bool} <gh ->', 'filter'], ['a', 0],          0
+['{ab bool ?de bool} <gh ->', 'filter'], ['a', 0, 'g'],     [{'ab': 0}, 'gh']
+['{ab bool ?de bool} <gh ->', 'filter'], ['a',0,'d',2,'g'], [{'ab': 0,'de': 1}, 'gh']
+['{?ab isreg} <cd bool>',     'filter'], ['c', '\v('],      [{}, 'cd', 1]
+['{?ab isreg} <ab bool>',     'filter'], ['a', '\v('],      [{}, 'ab', 1]
+['{?ab isreg} + type string', 'filter'], ['a', '\v('],      [{}, 'a', '\v(']
+['{?ab isreg} + type string', 'filter'], ['a', '\v'],       [{'ab': '\v'}]
+['type "" [type -0] {ab isreg} + type [] <cd bool>', 'filter'], ['', 0, 'a', '-', [1], 'c', {}], ['', 0, {'ab': '-'}, [1], 'cd', 0]
 # vim: cms=#%s fmr=▶,▲