Commits

ZyX_I committed 96c27e1

@/fwc: Added `not' check

  • Participants
  • Parent commits 4f7b18e

Comments (0)

Files changed (4)

plugin/frawor/fwc/compiler.vim

             \ 'nexecable': '%s is not executable',
             \ 'keynmatch': 'key `%s'' does not match any specification',
             \    'nmatch': 'no matches found for %s',
+            \   'notfail': '`not'' check failed',
         \}, '"Error while processing check %s for %s: ".v:val'))
 let s:_messages._types=['number', 'string', 'function reference', 'list',
             \           'dictionary']
 function s:compiler.nextthrow(cond, ...)
     return call(self.nextcond(a:cond).addthrow, a:000, self)
 endfunction
+"▶1 addsavemsgs     :: msglenstr, pmsglenstr + self → self + self
+function s:compiler.addsavemsgs(msglenstr, pmsglenstr)
+    return self.add('let '.a:msglenstr.'=len(@$@messages)',
+                \   'let '.a:pmsglenstr.'=len(@$@pmessages)')
+endfunction
+"▶1 addrestmsgs    :: msglenstr, pmsglenstr + self → self + self
+function s:compiler.addrestmsgs(msglenstr, pmsglenstr)
+    return self.nextcond('len(@$@messages)>'.a:msglenstr)
+                       \.add('call remove(@$@messages, '.a:msglenstr.', -1)')
+               \.up().close()
+               \.nextcond('len(@$@pmessages)>'.a:pmsglenstr)
+                       \.add('call remove(@$@pmessages, '.a:pmsglenstr.', -1)')
+               \.up().close()
+endfunction
 "▶1 getfunc        :: funccontext, split[, addarg, ...] + self → String
 function s:compiler.getfunc(func, split, ...)
     if a:split
                 call self.close()
             endif
             if !hascheck
-                call self.add('let '.msglenstr. '=len(@$@messages)',
-                            \ 'let '.pmsglenstr.'=len(@$@pmessages)')
+                call self.addsavemsgs(msglenstr, pmsglenstr)
             endif
             let hascheck=1
             let savedargbase=self.argbase
                             \.nextcond(foundstr)
                                 \.add('throw "CHECKFAILED"')
                             \.up().close()
-                            \.nextcond('len(@$@messages)>'.msglenstr)
-                                    \.add('call remove(@$@messages, '.
-                                    \                  msglenstr.', -1)')
-                            \.up().close()
-                            \.nextcond('len(@$@pmessages)>'.pmsglenstr)
-                                    \.add('call remove(@$@pmessages, '.
-                                    \                  pmsglenstr.', -1)')
-                            \.up().close()
+                            \.addrestmsgs(msglenstr, pmsglenstr)
                         \.up().close()
                         \.nextcond(foundstr).add('continue').up().close()
             let addedcond=0
                 let addedcond=1
                 call self.nextthrow(self.getexpr(desc[1], curargstr).' is 0',
                             \       'exprfail', idx, '@#@')
+            "▶3 `not'
+            elseif desc[0] is 'not'
+                if addedcond
+                    call self.close()
+                    let addedcond=0
+                endif
+                let msglenstr=self.getlvarid('msglen')
+                let pmsglenstr=self.getlvarid('pmsglen')
+                call self.add('try').addsavemsgs(msglenstr, pmsglenstr).deeper()
+                                \.compilearg(desc[1], idx.'(not)')
+                                \.add('throw "NOTFAILED"').up()
+                            \.add('catch /^CHECKFAILED$/')
+                                \.deeper().addrestmsgs(msglenstr, pmsglenstr)
+                            \.add('catch /^NOTFAILED$/').deeper()
+                                \.addthrow('notfail', idx, '@#@')
+                            \.close()
             "▶3 `either'
             elseif desc[0] is 'either'
                 if addedcond
                 let sucstr=self.getlvarid('succeeded')
                 let msglenstr=self.getlvarid('msglen')
                 let pmsglenstr=self.getlvarid('pmsglen')
-                call self.add('let '.sucstr.'=1',
-                            \ 'let '.msglenstr. '=len(@$@messages)',
-                            \ 'let '.pmsglenstr.'=len(@$@pmessages)')
+                call self.add('let '.sucstr.'=1')
+                            \.addsavemsgs(msglenstr, pmsglenstr)
                 if !empty(desc[1])
                     call self.add('try').deeper()
                                 \.compilearg(desc[1][0], idx.'(either).0',
                                 \.up().close()
                     let i+=1
                 endfor
-                call self.nextcond(sucstr)
-                            \.nextcond('len(@$@messages)>'.msglenstr)
-                                    \.add('call remove(@$@messages, '.
-                                    \                  msglenstr.', -1)')
-                            \.up().close()
-                            \.nextcond('len(@$@pmessages)>'.pmsglenstr)
-                                    \.add('call remove(@$@pmessages, '.
-                                    \                  pmsglenstr.', -1)')
-                            \.up().close()
-                        \.up()
-                        \.add('else').deeper()
-                            \.addthrow('eitherfail', idx, '@#@')
-                        \.close()
+                call self.nextcond(sucstr).addrestmsgs(msglenstr, pmsglenstr)
+                            \.up()
+                            \.add('else').deeper()
+                                \.addthrow('eitherfail', idx, '@#@')
+                            \.close()
             "▶3 `tuple'
             elseif desc[0] is 'tuple'
                 call self.addtypecond([type([])], idx)

plugin/frawor/fwc/parser.vim

 "▶3 check.eval
 " Checks whether result of running eval({expr}) isnot 0
 let s:args.check.eval=['expr']
+"▶3 check.not
+let s:args.check.not=['arg']
 "▶3 check.either
 " Checks whether {argument} matches one of given specifications
 let s:args.check.either=['*arg']
     return self.conclose()
 endfunction
 "▶1 scanmsg    :: &self
-" Input: {wordchar}+ ( "(" ( "." | "%" | {var} ) ")"? )?
+" Input: {wordchar}+ ( "(" ( "." | "%" | {var} | "," ) ")"? )?
 " Output: context(msg, String, {msgarg}*)
 "         {msgarg} :: context(curval)
 "                   | context(curarg)
                     call self.addcon('curval').conclose()
                 elseif c is '%'
                     call self.addcon('curarg').conclose()
-                else
+                elseif c isnot ','
                     call self.ungetc(c).getvar()
                 endif
             endwhile
 plugin/frawor/fwc/compiler:typefail
 plugin/frawor/fwc/compiler:ninlist
 plugin/frawor/fwc/compiler:ninlist
+plugin/frawor/fwc/compiler:notfail
 ::: Section <Checks/Built-in checks/dict>
 plugin/frawor/fwc/compiler:keynmatch
 plugin/frawor/fwc/compiler:typefail

test/fwctests.dat

 ['in =["a",0]',     'check'], ['a'],                1
 ['in =["a",0]',     'check'], ['0'],                0
 ['in =["a",0]',     'check'], [0],                  1
+['not bool',        'check'], [0],                  0
+['not bool',        'check'], [2],                  1
 ['_',               'check'], [[[[]]]],             1
 ['any',             'check'], [[[[]]]],             1
 #▶3 dict