1. ZyX_I
  2. frawor

Commits

ZyX_I  committed 6e61ce3

@/fwc/compiler: Partially removed `throw "CHECKFAILED"'

  • Participants
  • Parent commits ca673c7
  • Branches default

Comments (0)

Files changed (2)

File plugin/frawor/fwc/compiler.vim

View file
     let self.subs[-1]+=1
     return self
 endfunction
+"▶1 fail           :: &self
+function s:compiler.fail()
+    let msgstatus=self.msgs.statuses[-1]
+    if msgstatus is 'return'
+        return self[self.failcal[0]](self.failcal[1]).up()
+    else
+        return self.throw(s:cfstr)
+    endif
+endfunction
+"▶1 pushms         :: &self(msgstatus)
+function s:compiler.pushms(status)
+    call add(self.msgs.statuses, a:status)
+    return self
+endfunction
+"▶1 popms          :: &self
+function s:compiler.popms()
+    call remove(self.msgs.statuses, -1)
+    return self
+endfunction
 "▶1 addthrow       :: msg::String, msgarg, ... + self → self + self
 function s:compiler.addthrow(msg, ...)
-    let args=copy(a:000)
-    let curidx=index(args, '@#@')
+    let args=string(a:msg).', '
+    let curidx=index(a:000, '@#@')
     if curidx!=-1
-        let args=map(args[:(curidx-1)], 'string(v:val)')+[self.argstr(1)]+
-                    \args[(curidx+1):]
+        let args.=join(map(a:000[:(curidx-1)],
+                    \      'string(v:val)')+
+                    \  [self.argstr(1)]+
+                    \  a:000[(curidx+1):], ', ')
+    else
+        let args.=join(a:000, ', ')
     endif
     if !empty(self.msgs.own) && !empty(self.msgs.own[-1])
-        call self.call('add(@$@pmessages, ['.self.msgs.own[-1].'])')
+        let pargs=self.msgs.own[-1]
     endif
-    return self.call('add(@$@messages, ['.string(a:msg).', '.join(args, ', ').
-                \                     '])')
-                \.throw(s:cfstr)
+    let msgstatus=self.msgs.statuses[-1]
+    if msgstatus is 'return'
+        if exists('pargs')
+            call self.call('@%@.p._f.warn('.pargs.')')
+        endif
+        call self.call('@%@.F.warn('.args.')')
+    elseif msgstatus is 'throw'
+        if exists('pargs')
+            call self.call('add(@$@pmessages, ['.pargs.'])')
+        endif
+        call self.call('add(@$@messages, ['.args.'])')
+    elseif msgstatus is 'throwignore'
+        " Ignore and fail
+    endif
+    return self.fail()
 endfunction
 "▶1 nextthrow      :: condition::expr, throwargs + self → self + self
 function s:compiler.nextthrow(cond, ...)
             endif
             let hascheck=1
             call self.try()
+                        \.pushms('throw')
                         \.let(foundstr, 0)
                         \.witharg([keystr])
                         \.compilearg(check[1], a:idx.'.'.i.'(key)', 'check')
                         \.without()
                         \.let(foundstr, 1)
                         \.compilearg(check[2],a:idx.'.'.i.'(val)',a:default)
+                        \.popms()
                     \.up().catch(s:cfreg)
                         \.addif(foundstr)
-                            \.throw(s:cfstr)
+                            \.fail()
                         \.addrestmsgs(1)
                     \.up().addif(foundstr)
                         \.continue().up()
         "▶3 `if'
         elseif desc[0] is 'if'
             let condstr=self.getlvarid('cond')
-            call self.addsavemsgs()
-                    \.try()
+            call self.try()
+                        \.pushms('throwignore')
                         \.compilearg(desc[1], a:idx.'(cond)', 'check')
+                        \.popms()
                         \.let(condstr, 1)
                     \.up().catch(s:cfreg)
                         \.let(condstr, 0)
-                    \.up().addrestmsgs()
+                    \.up()
             if len(desc[2])>1
                 call self.addif(condstr).compilearg(desc[2],a:idx.'(if)','pipe')
                             \.up()
                         \       'exprfail', a:idx, '@#@')
         "▶3 `not'
         elseif desc[0] is 'not'
-            let msglenstr=self.getlvarid('msglen')
-            let pmsglenstr=self.getlvarid('pmsglen')
-            call self.addsavemsgs()
-                    \.try()
+            call self.try()
+                        \.pushms('throwignore')
                         \.compilearg(desc[1], a:idx.'(not)')
-                        \.throw('"NOTFAILED"')
-                    \.catch(s:cfreg)
-                        \.addrestmsgs()
-                    \.up().catch('^NOTFAILED$')
+                        \.popms()
                         \.addthrow('notfail', a:idx, '@#@')
+                    \.catch(s:cfreg).up()
         "▶3 `either'
         elseif desc[0] is 'either'
             let sucstr=self.getlvarid('succeeded')
             let msglenstr=self.getlvarid('msglen')
             let pmsglenstr=self.getlvarid('pmsglen')
-            call self.let(sucstr, 1).addsavemsgs()
+            call self.let(sucstr, 1).pushms('throw').addsavemsgs()
             if !empty(desc[1])
                 call self.try()
                             \.compilearg(desc[1][0], a:idx.'(either).0',
                         \.up()
                 let i+=1
             endfor
-            call self.addif(sucstr).addrestmsgs().up()
+            call self.addif(sucstr).addrestmsgs().up().popms()
                         \.addif().addthrow('eitherfail',a:idx,'@#@').up().up()
         "▶3 `tuple'
         elseif desc[0] is 'tuple'
     return self
 endfunction
 "▶1 compileadesc   :: adescr + self → self + self
-" XXX in order for this function to work self.argstr(self.subs[:-2]) should 
-" point to argument being checked and self.subs[-1] should be a number
 function s:compiler.compileadesc(adescr)
     if !self.o.only
         if !has_key(a:adescr, 'minimum')
                 \   'vids': {},
                 \'argbase': '@@@',
                 \  'preva': [],
-                \   'msgs': {     'own': [],
-                \            'savevars': [],},
+                \   'msgs': {'savevars': [],
+                \            'statuses': ['return'],
+                \                 'own': [],
+                \           },
+                \'failcal': [],
             \})
     let tree=s:_r.fwc_parser(a:string, a:type)[1:]
     call extend(t, s:compiler, 'error')
     let t._throw=s:_f.throw
     "▲2
+    if a:doreturn is 1
+        let t.failcal=['return', 0]
+    else
+        let t.failcal=['call', '@%@.F.throw('.a:doreturn.')']
+    endif
     call s:F.cleanup(tree)
     let t.o=remove(tree, 0)
     if t.type is 'check' || t.type is 'filter'
             call t.compileadesc(tree[0])
         else
         endif
-        call t.up().catch(s:cfreg)
+        call t.up().finally()
                     \.for('@$@targs', '@$@messages')
                         \.call('call(@%@.F.warn, @$@targs, {})').up()
                     \.for('@$@targs', '@$@pmessages')
                         \.call('call(@%@.p._f.warn, @$@targs, {})').up()
-        if a:doreturn is 1
-            call t.return(0)
-        else
-            call t.call('@%@.F.throw('.a:doreturn.')')
-        endif
-        call t.up()
+                \.up()
+                \.up()
     else
         call t.let('@@@', '[]')
     endif
     "▲2
     let vars=s:F.createvars(a:plugdict)
     let a='"FWCfail", '.s:F.string(a:fname).', '.s:F.string(a:plugdict.id)
-    let [opts, lines]=s:F.compilestr(s:vars[id], a:arg[0], a:arg[1], a)
+    let [opts, lines]=s:F.compilestr(vars, a:arg[0], a:arg[1], a)
     if opts.only
         call map(lines, 'substitute(v:val, "@@@", "@$@args", "g")')
         call insert(lines, 'let @$@d={"args": @@@}')

File test/fwccheck.ok

View file
 plugin/frawor/fwc/compiler:isdir
 plugin/frawor/fwc/compiler:nread
 ::: Section <Checks/Built-in checks/either>
+plugin/frawor/fwc/compiler:eitherfail
 plugin/frawor/fwc/compiler:nbool
 plugin/frawor/fwc/compiler:typefail
-plugin/frawor/fwc/compiler:eitherfail
 plugin/frawor/fwc/compiler:nbool
 ::: Section <Checks/Built-in checks/list>
 plugin/frawor/fwc/compiler:typefail
 plugin/frawor/fwc/compiler:exprfail
 plugin/frawor/fwc/compiler:exprfail
 ::: Section <Messages>
+Frawor:plugin/fwccheck:str:a:args[0]<
 plugin/frawor/fwc/compiler:nbool
-Frawor:plugin/fwccheck:str:a:args[0]<
+Frawor:plugin/fwccheck:str:\v(<
 plugin/frawor/fwc/compiler:nreg
-Frawor:plugin/fwccheck:str:\v(<
-plugin/frawor/fwc/compiler:nbool
 Frawor:plugin/fwccheck:str:0<
 plugin/frawor/fwc/compiler:nbool
 Frawor:plugin/fwccheck:str:1<
 plugin/frawor/fwc/compiler:nbool
 Frawor:plugin/fwccheck:str:a:args[0]<
 plugin/frawor/fwc/compiler:nbool
+plugin/frawor/fwc/compiler:nbool
 ::: Section <Option `only'>
 plugin/frawor/fwc/compiler:nreg
 plugin/frawor/fwc/compiler:typefail