Commits

ZyX_I committed 14cef93

@/fwc/compiler: added checking of fwc_compile arguments

Comments (0)

Files changed (1)

plugin/frawor/fwc/compiler.vim

             \              'when option `only'' is active',
         \}
 call extend(s:_messages, map({
+            \     'onstr': 'first argument is not a String',
+            \     'tnstr': 'second argument is not a String',
+            \  'tinvtype': 'expected second argument to be one of '.
+            \              '"check", "filter" or "complete", but got "%s"',
+            \    '3ndict': 'third argument is not a Dictionary',
+            \}, '"Error while compiling function for plugin %s: ".v:val'))
+call extend(s:_messages, map({
             \'decargnlst': 'decorator argument is not a List',
             \    'largn2': 'expected two elements in list, but got %u',
             \     '1nstr': 'first element in list is not a String',
             \   'invtype': 'expected second element to be '.
-            \              'either "check" or "filter", but got %s',
+            \              'either "check" or "filter", but got "%s"',
         \}, '"Error while creating function %s for plugin %s: ".v:val'))
 call extend(s:_messages, map({
             \  'funcfail': 'custom function returned 0',
 if has('float')
     call add(s:_messages._types, 'float')
 endif
-"▶1 cleanup        :: list::[_, {arg}*] → + list
+"▶1 cleanup         :: list::[_, {arg}*] → + list
 function s:F.cleanup(list)
     if len(a:list)>1
         let args=remove(a:list, 1, -1)
         endif
     endif
 endfunction
-"▶1 getlenrange    :: adescr → (minlen, maxlen) + adescr
+"▶1 getlenrange     :: adescr → (minlen, maxlen) + adescr
 function s:F.getlenrange(adescr)
     let minimum=0
     let maximum=0
     let a:adescr.maximum=maximum
     return [minimum, maximum]
 endfunction
-"▶1 fail           :: &self
+"▶1 fail            :: &self
 function s:compiler.fail()
     let msgstatus=self.msgs.statuses[-1]
     if msgstatus is 'return'
         return self.throw(s:cfstr)
     endif
 endfunction
-"▶1 pushms         :: &self(msgstatus)
+"▶1 pushms          :: &self(msgstatus)
 function s:compiler.pushms(status)
     call add(self.msgs.statuses, a:status)
     return self
 endfunction
-"▶1 popms          :: &self
+"▶1 popms           :: &self
 function s:compiler.popms()
     call remove(self.msgs.statuses, -1)
     return self
 endfunction
-"▶1 witharg        :: (argbase[, [subscript]]) + self → self + self
+"▶1 witharg         :: &self((argbase[, [subscript]]))
 function s:compiler.witharg(newarg)
     call add(self.preva, [self.argbase, self.subs])
     let self.argbase=a:newarg[0]
     let self.subs=get(a:newarg, 1, [])
     return self
 endfunction
-"▶1 without        :: &self
+"▶1 without         :: &self
 function s:compiler.without()
     let [self.argbase, self.subs]=remove(self.preva, -1)
     return self
 endfunction
-"▶1 incrementsub   :: subscript, incby → subscript
+"▶1 incrementsub    :: subscript, incby → subscript
 function s:F.incrementsub(sub, incby)
     if type(a:sub)==type(0)
         return a:sub+a:incby
                     \           str2nr(num)+a:incby)]
     endif
 endfunction
-"▶1 incsub         :: &self([incby])
+"▶1 incsub          :: &self([incby])
 function s:compiler.incsub(...)
     if empty(self.subs)
         return self
     endif
     return self
 endfunction
-"▶1 argstr         :: [genString::Bool, [subscript]] + self → String
-"▶2 addargchunk    :: chunks, chunk::String, literal::Bool → _ + chunks
+"▶1 argstr          :: [genString::Bool, [subscript]] + self → String
+"▶2 addargchunk     :: chunks, chunk::String, literal::Bool → _ + chunks
 function s:F.addargchunk(chunks, chunk, literal)
     if a:literal==(len(a:chunks)%2)
         call add(a:chunks, a:chunk)
         let a:chunks[-1].=a:chunk
     endif
 endfunction
-"▶2 addstrsub      :: chunks, sub, self → _ + chunks
+"▶2 addstrsub       :: chunks, sub, self → _ + chunks
 function s:F.addstrsub(chunks, sub, self)
     if type(a:sub)==type([])
         call s:F.addargchunk(a:chunks, 'string('.a:self.getvar(a:sub).')', 1)
         return self.argbase.(self.getsubs(get(a:000, 1, self.subs)))
     endif
 endfunction
-"▶1 getsub         :: subscript → string
+"▶1 getsub          :: subscript → string
 function s:compiler.getsub(subscript)
     return ((type(a:subscript)==type([]))?(a:subscript[0]):(a:subscript))
 endfunction
-"▶1 getsubs        :: [subscript] + self → String
+"▶1 getsubs         :: [subscript] + self → String
 function s:compiler.getsubs(subscripts)
     let r=''
     for sub in a:subscripts
     endfor
     return r
 endfunction
-"▶1 getfunc        :: funccontext, split[, addarg, ...] + self → String
+"▶1 getfunc         :: funccontext, split[, addarg, ...] + self → String
 function s:compiler.getfunc(func, split, ...)
     if a:split
         let r=[self.getvar(a:func[1])]
     endif
     return r
 endfunction
-"▶1 getmatcher     :: matchercontext, ldstr, strstr + self → String
+"▶1 getmatcher      :: matchercontext, ldstr, strstr + self → String
 function s:compiler.getmatcher(matcher, ldstr, strstr)
     let mname=a:matcher[1][1]
     if !has_key(s:_r.FWC_intfuncs[mname], 'matcher')
     endif
     return r
 endfunction
-"▶1 getexpr        :: exprcontext[, curstr] + self → String
+"▶1 getexpr         :: exprcontext[, curstr] + self → String
 function s:compiler.getexpr(expr, ...)
     let curargstr=self.argstr()
     let this=get(a:000, 0, curargstr)
                 \'\V@.@', escape(this,         '&~\'), 'g'),
                 \'\V@:@', escape(curargstr,    '&~\'), 'g')
 endfunction
-"▶1 getvar         :: varcontext[, splitsubs[, dotarg]] + self → String
+"▶1 getvar          :: varcontext[, splitsubs[, dotarg]] + self → String
 function s:compiler.getvar(var, ...)
     let r=[]
     let splitsubs=get(a:000, 0, 0)
     endif
     return ((splitsubs)?(r):(r[0].((len(r)>1)?(self.getsubs(r[1])):(''))))
 endfunction
-"▶1 getfunstatvar  :: varname, varinit + self → varstr + self
+"▶1 getfunstatvar   :: varname, varinit + self → varstr + self
 function s:compiler.getfunstatvar(name, init)
+    if !has_key(self.vids, a:name)
+        let self.vids[a:name]=0
+        let self.vars[a:name]={}
+    endif
     let id=printf('%x', self.vids[a:name])
     let self.vids[a:name]+=1
-    if !has_key(self.vars, a:name)
-        let self.vars[a:name]={}
-    endif
     let self.vars[a:name][id]=a:init
     return '@%@'.self.getsubs([a:name, id])
 endfunction
-"▶1 getlvarid      :: varname + self → varname
+"▶1 getlvarid       :: varname + self → varname
 function s:compiler.getlvarid(v)
     return printf('@$@%s%X', a:v, len(self.stack))
 endfunction
-"▶1 getd           :: varname + self → varname + self
+"▶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 getlargsstr    :: () + self → varname + self
+"▶1 getlargsstr     :: () + self → varname + self
 function s:compiler.getlargsstr()
     let key=string([self.argbase]+self.subs[:-2])[1:-2]
     if has_key(self.lavars, key)
         return largsstr
     endif
 endfunction
-"▶1 getstring      :: {string} + self → self + self
+"▶1 getstring       :: &self({string})
 function s:compiler.getstring(str)
     if type(a:str)==type('')
         return self.string(a:str)
     endif
     return self.getvar(a:str)
 endfunction
-"▶1 addthrow       :: msg::String, msgarg, needcurarg, ... + self → self + self
+"▶1 addthrow        :: &self(msg::String, msgarg, needcurarg, ...)
 function s:compiler.addthrow(msg, needcurarg, ...)
     let args=self.string(a:msg).', '
     if a:needcurarg
     endif
     return self.fail()
 endfunction
-"▶1 nextthrow      :: condition::expr, throwargs + self → self + self
+"▶1 nextthrow       :: &self(condition::expr, throwargs)
 function s:compiler.nextthrow(cond, ...)
     return call(self.addif(a:cond).addthrow, [a:1, 1]+a:000[1:], self)
 endfunction
-"▶1 addsavemsgs    :: &self
+"▶1 addsavemsgs     :: &self
 function s:compiler.addsavemsgs()
     if self.msgs.statuses==#['return']
         call add(self.msgs.savevars, [0, 0])
                     \.let(pmsglenstr, 'len(@$@pmessages)')
     endif
 endfunction
-"▶1 addrestmsgs    :: a:0::Bool + self → self + self
+"▶1 addrestmsgs     :: &self(a:0::Bool)
 function s:compiler.addrestmsgs(...)
     let [msglenstr, pmsglenstr]=self.msgs.savevars[-1]
     if !a:0
                     \.call('remove(@$@pmessages, '.pmsglenstr.', -1)')
                 \.endif()
 endfunction
-"▶1 addtypecond    :: types, idx + self → self + self
+"▶1 addtypecond     :: &self(types, idx)
 function s:compiler.addtypecond(types, idx)
     if self.o.onlystrings && self.argbase is '@@@'
         if index(types, type(''))==-1
     endif
     return self
 endfunction
-"▶1 addlencheck    :: minlen, maxlen + self → self + self
+"▶1 addlencheck     :: &self(minlen, maxlen)
 function s:compiler.addlencheck(minimum, maximum)
     let largsstr=self.getlargsstr()
     let minimum=self.getsub(s:F.incrementsub(self.subs[-1], a:minimum))
     endif
     return self
 endfunction
-"▶1 compilemsg     :: msgcontext, _ + self → self + self
+"▶1 compilemsg      :: &self(msgcontext, _)
 function s:compiler.compilemsg(msg, idx)
     if a:msg[1] is 0
         call add(self.msgs.own, '')
     call add(self.msgs.own, msgstr)
     return self
 endfunction
-"▶1 compilepipe    :: pipecontext, idx + self → self + self
+"▶1 compilepipe     :: &self(pipecontext, idx)
 function s:compiler.compilepipe(pipe, idx)
     let curargstr=self.argstr()
     "▶2 `func' pipe
     return self
 endfunction
 let s:compiler.compilefilter=s:compiler.compilepipe
-"▶1 compilecheck   :: checkcontext, idx + self → self + self
+"▶1 compilecheck    :: &self(checkcontext, idx)
 function s:compiler.compilecheck(check, idx)
     let curargstr=self.argstr()
     let check=a:check[1]
     endif
     return self
 endfunction
-"▶1 compadescr     :: adescr[, idx[, purgemax]] + self → self + self
+"▶1 compadescr      :: &self(adescr[, idx[, purgemax]])
 function s:compiler.compadescr(adescr, ...)
     let purgemax=get(a:000, 1, 0)
     "▶2 Length checks, lagsstr and nextsub variables
     "▲2
     return self
 endfunction
-"▶1 compstr        :: vars, String, type, doreturn → [String]
+"▶1 compstr         :: vars, String, type, doreturn → [String]
 function s:F.compstr(vars, string, type, doreturn)
     "▶2 Setup self
     let t=extend(s:_r.new_constructor(), {
                 \   'type': a:type,
                 \   'subs': [],
                 \   'vars': a:vars,
-                \   'vids': {'actions': 0, 'prefixes': 0, 'matchers': 0},
+                \   'vids': {},
                 \'argbase': '@@@',
                 \  'preva': [],
                 \   'msgs': {'savevars': [],
     endif
     return [t.o, t.tolist()]
 endfunction
-"▶1 createvars     :: gdict → id + s:lastid, s:vars
+"▶1 createvars      :: gdict → id + s:lastid, s:vars
 function s:F.createvars(gdict)
     return {
                 \ 'F': {'warn': s:_f.warn, 'throw': s:_f.throw},
                 \'os': s:_r.os,
             \}
 endfunction
-"▶1 makefunc       :: {f}, String, type[, gdict] → Fref + s:lastid, s:vars
+"▶1 makefunc        :: {f}, String, type[, gdict] → Fref + s:lastid, s:vars
 let s:lastid=0
 let s:vars={}
+let s:types=['check', 'filter', 'complete']
 function s:F.makefunc(plugdict, fdict, string, type, ...)
+    "▶2 Check arguments
+    if type(a:string)!=type('')
+        call s:_f.throw('onstr', a:plugdict.id)
+    elseif type(a:type)!=type('')
+        call s:_f.throw('tnstr', a:plugdict.id)
+    elseif index(s:types, a:type)==-1
+        call s:_f.throw('tinvtype', a:plugdict.id, a:type)
+    elseif a:0 && type(a:1)!=type({})
+        call s:_f.throw('3ndict', a:plugdict.id)
+    endif
+    "▲2
     let d={}
     let id=printf('%s%X', a:type, s:lastid)
     let s:lastid+=1
             \"endfunction"
     return d.f
 endfunction
-"▶1 delids         :: {f}
+"▶1 delids          :: {f}
 function s:F.delids(plugdict, fdict)
     call map(a:fdict.ids, 'remove(s:vars, v:val)')
 endfunction
 call s:_f.newfeature('fwc_compile', {'cons': s:F.makefunc,
             \                      'unload': s:F.delids,
             \                        'init': {'ids': []}})
-"▶1 makedec        :: plugdict, fname, arg
+"▶1 makedec         :: plugdict, fname, arg
 function s:F.makedec(plugdict, fname, arg)
     "▶2 Check arguments
     if type(a:arg)!=type([])