Commits

ZyX_I committed ba74a54

@/fwc/compiler: Started working on implementation of optional arguments

Comments (0)

Files changed (2)

plugin/frawor/fwc/compiler.vim

 endfunction
 "▶1 incsub         :: &self
 function s:compiler.incsub()
-    let self.subs[-1]+=1
+    if type(self.subs[-1])==type(0)
+        let self.subs[-1]+=1
+    else
+        let num=matchstr(self.subs[-1][0], '[+-]\d\+$')
+        let self.subs[-1][0]=self.subs[-1][0][:-1-len(num)].printf('%+i', num+1)
+    endif
     return self
 endfunction
 "▶1 fail           :: &self
 endfunction
 "▶1 addsavemsgs    :: &self
 function s:compiler.addsavemsgs()
-    let msglenstr=self.getlvarid('msglen')
-    let pmsglenstr=self.getlvarid('pmsglen')
-    call add(self.msgs.savevars, [msglenstr, pmsglenstr])
-    return   self.let(msglenstr,  'len(@$@messages)')
-                \.let(pmsglenstr, 'len(@$@pmessages)')
+    if self.msgs.statuses==#['return']
+        call add(self.msgs.savevars, [0, 0])
+        return self
+    else
+        let msglenstr=self.getlvarid('msglen')
+        let pmsglenstr=self.getlvarid('pmsglen')
+        call add(self.msgs.savevars, [msglenstr, pmsglenstr])
+        return   self.let(msglenstr,  'len(@$@messages)')
+                    \.let(pmsglenstr, 'len(@$@pmessages)')
+    endif
 endfunction
 "▶1 addrestmsgs    :: a:0::Bool + self → self + self
 function s:compiler.addrestmsgs(...)
 function s:compiler.addlencheck(minimum, maximum)
     let largsstr=self.getlvarid('largs')
     call self.let(largsstr, 'len('.self.argstr(0, self.subs[:-2]).')')
+    if type(self.subs[-1])==type([])
+        let minimum=printf('%s+%u', self.subs[-1][0], a:minimum)
+        let maximum=printf('%s+%u', self.subs[-1][0], a:maximum)
+    else
+        let minimum=self.subs[-1]+a:minimum
+        let maximum=self.subs[-1]+a:maximum
+    endif
     if a:maximum==a:minimum
-        call self.addif(largsstr.' isnot '.a:maximum)
-                    \.addthrow('invlen', 0, a:minimum, largsstr)
+        call self.addif(largsstr.' isnot '.maximum)
+                    \.addthrow('invlen', 0, minimum, largsstr)
     else
         if a:minimum>0
-            call self.addif(largsstr.'<'.a:minimum)
-                        \.addthrow('tooshort', 0, a:minimum, largsstr)
+            call self.addif(largsstr.'<'.minimum)
+                        \.addthrow('tooshort', 0, minimum, largsstr)
         endif
         if a:maximum!=-1
-            call self.addif(largsstr.'>'.a:maximum)
-                        \.addthrow('toolong', 0,  a:maximum, largsstr)
+            call self.addif(largsstr.'>'.maximum)
+                        \.addthrow('toolong', 0,  maximum, largsstr)
         endif
     endif
     return self
 endfunction
-"▶1 compileadesc   :: adescr + self → self + self
-function s:compiler.compileadesc(adescr)
+"▶1 compileadesc   :: adescr[, idx] + self → self + self
+function s:compiler.compileadesc(adescr, ...)
     if !self.o.only
         if !has_key(a:adescr, 'minimum')
             call s:F.getlenrange(a:adescr)
         endif
         if !has_key(a:adescr, 'checkedfor')
-            call self.addlencheck(self.subs[-1]+a:adescr.minimum,
-                        \      self.subs[-1]+a:adescr.maximum)
+            call self.addlencheck(a:adescr.minimum, a:adescr.maximum)
             let a:adescr.checkedfor=1
         endif
     endif
     if has_key(a:adescr, 'arg')
+        let i=0
         for arg in a:adescr.arg
-            call self.compilearg(arg, ((self.o.only)?(''):(self.subs[-1])))
+            if self.o.only
+                let idx=''
+            elseif a:0
+                let idx=a:1.'.'.i
+            elseif type(self.subs)!=type([])
+                let idx=self.subs[-1]
+            else
+                let idx=''
+            endif
+            call self.compilearg(arg, idx)
             if !self.o.only
                 call self.incsub()
             endif
+            let i+=1
         endfor
     endif
+    if self.o.only
+        return self
+    endif
+    if has_key(a:adescr, 'optional')
+        let caidxstr=self.getlvarid('caidx')
+        let caidx=[caidxstr]
+        let failstr=self.getlvarid('fail')
+        call     self.let(caidxstr, ((type(self.subs[-1])==type([]))?
+                    \                   (self.subs[-1][0]):
+                    \                   (self.subs[-1])))
+                    \.let(failstr, 0)
+        let self.subs[-1]=caidx
+        call self.addsavemsgs()
+                    \.try()
+                        \.pushms('throw')
+                        \.compileadesc(a:adescr.optional[0],
+                        \              get(a:000, 0, '').'.(optional)')
+                        \.popms()
+                        \.let(caidxstr, self.subs[-1][0])
+                        \.let(failstr, 1)
+                    \.catch(s:cfreg).up()
+                    \.addrestmsgs()
+        let self.subs[-1]=caidx
+    endif
     " TODO
     return self
 endfunction

plugin/frawor/fwc/intfuncs.vim

 let s:r.either={'args': ['*arg']}
 function s:r.either.check(desc, idx, type)
     let sucstr=self.getlvarid('succeeded')
-    call self.let(sucstr, 1).pushms('throw').addsavemsgs()
+    call self.let(sucstr, 1).addsavemsgs().pushms('throw')
     if !empty(a:desc[1])
         call self.try()
                     \.compilearg(a:desc[1][0], a:idx.'(either).0',