Commits

ZyX_I committed c0980a2

@/checks: Removed some error messages, added more functions' descriptions, made .scan accept {opt}, {pref} and {act} only at toplevel or inside context(actions)

Comments (0)

Files changed (1)

plugin/frawor/checks.vim

             \  'invvar': 'invalid variable description: %s',
             \ 'invpref': 'invalid prefix description: %s',
             \  'invact': 'invalid action description: %s',
-            \'noadescr': 'action description is missing',
             \'invssubs': 'invalid subscript in slice expression: %s',
             \ 'uoption': 'unknown option: %s',
             \  'argmis': 'missing arguments to %s',
-            \ 'funcmis': 'missing %s function',
             \ 'subsmis': 'subscript range missing',
             \   'nonum': 'number expected',
-            \  'varmis': 'missing variable description',
-            \ 'pipemis': 'missing pipe description',
-            \  'msgmis': 'missing message description',
             \ 'prefmis': 'missing prefixes description',
             \  'actmis': 'missing arguments description',
             \ 'typemis': 'missing type description',
 " Output: context(intfunc, {funcname}[, contexts])
 function s:F.scan.intfunc()
     let type=self.stack[-1][0]
-    if self.eos "▶3
-        call self.throw('funcmis', type)
-    endif       "▲3
     let c=self.readc()
     let func=s:F.getmatch(s:args[type], c)
     if func is 0 "▶3
     endif
     return self
 endfunction
+"▶2 scan.getsubscr  :: &self!
+" Input: ( "." ( "."? ( ":" {n} {n} | {subscript} ) )* )
+"        {subscript} :: {str}
+"                     | [0-9] {wordchar}*
+"                     | {wordchar}+
+"                {n} :: "-"? {wordchar}+
+" Output: add((String|Number|context(Number, Number))*)
+function s:F.scan.getsubscr()
+    while !self.eos
+        let c=self.readc()
+        if c is '"'
+            call self.add(self.readstr())
+        elseif c=~#'^\d'
+            call self.add(+c)
+        elseif c=~#'^\w'
+            call self.add(c)
+        elseif c is ':'
+            call self.addcon()
+            " Start and end subscripts
+            for i in range(0, 1)
+                if self.eos
+                    call self.throw('subsmis')
+                endif
+                let v=self.readc()
+                if v is '-'
+                    if self.eos
+                        call self.throw('nonum')
+                    endif
+                    let v.=self.readc()
+                endif
+                call self.add(+v)
+            endfor
+            call self.conclose()
+        elseif c isnot '.'
+            call self.ungetc(c)
+            break
+        endif
+    endwhile
+    return self
+endfunction
 "▶2 scan.getddescr  :: &self
 " Gets dictionary description:
 " Input: "{" ({keydescr} {arg})* "}"
 function s:F.scan.getexpr()
     return self.addcon('expr', self.readexpr()).conclose()
 endfunction
-"▶2 scan.getsubscr  :: &self
-" Input: ( "." ( "."? ( ":" {n} {n} | {subscript} ) )* )
-"        {subscript} :: {str}
-"                     | [0-9] {wordchar}*
-"                     | {wordchar}+
-"                {n} :: "-"? {wordchar}+
-" Output: context(subscript, (String|Number|context(Number, Number))*)
-function s:F.scan.getsubscr()
-    call self.addcon('subscript')
-    while !self.eos
-        let c=self.readc()
-        if c is '"'
-            call self.add(self.readstr())
-        elseif c=~#'^\d'
-            call self.add(+c)
-        elseif c=~#'^\w'
-            call self.add(c)
-        elseif c is ':'
-            call self.addcon()
-            " Start and end subscripts
-            for i in range(0, 1)
-                if self.eos
-                    call self.throw('subsmis')
-                endif
-                let v=self.readc()
-                if v is '-'
-                    if self.eos
-                        call self.throw('nonum')
-                    endif
-                    let v.=self.readc()
-                endif
-                call self.add(+v)
-            endfor
-            call self.conclose()
-        elseif c isnot '.'
-            call self.ungetc(c)
-            break
-        endif
-    endwhile
-    return self.conclose()
-endfunction
 "▶2 scan.getchvar   :: &self
 " Input: "<"* {subscr}?
 " Output: context(this, Number, {subscr}?)
     return self.conclose()
 endfunction
 "▶2 scan.getvar     :: &self
+" Input: {wordchar}+ {subscr}*
+"      | "@" {chvar}
+"      | "=" {expr}
+"      | "[" {list}
+"      | {str}
+" Output: context(plugvar, String, {subscr}*)
+"       | {chvar}
+"       | {expr}
+"       | {list}
 function s:F.scan.getvar()
-    if self.eos
-        call self.throw('varmis')
-    endif
     let c=self.readc()
     if c=~#'^\w'
         call self.addcon('plugvar', c).getsubscr().conclose()
     return self
 endfunction
 "▶2 scan.getfunc    :: &self
+" Input: {var} ( "(" ( "$" {var} | "*" {func} | {wordchar}+ ) ")"? )?
+" Output: context(func, {var}, ({var}|{func}|context(string, String))*)
 function s:F.scan.getfunc()
-    call self.addcon('func')
-    if self.eos
-        call self.throw('funcmis', 'external')
-    endif
-    call self.getvar()
+    call self.addcon('func').getvar()
     if !self.eos
         let c=self.readc()
         if c is '('
     return self.conclose()
 endfunction
 "▶2 scan.getmatcher :: &self
+" Input: {intfunc}
+" Output: context(matcher, {intfunc})
 function s:F.scan.getmatcher()
     return self.addcon('matcher').intfunc().conclose()
 endfunction
 "▶2 scan.scanpipe   :: &self
+" Input: {intfunc}
+"      | "*" {func}
+" Output: context(pipe, {intfunc}|{func})
 function s:F.scan.scanpipe()
-    if self.eos
-        call self.throw('pipemis')
-    endif
     call self.addcon('pipe')
     let c=self.readc()
     if c is '*'
     return self.conclose()
 endfunction
 "▶2 scan.scanmsg    :: &self
+" Input: {wordchar}+ ( "(" ( "." | "%" | {var} ) ")"? )?
+" Output: context(msg, String, {msgarg}*)
+"         {msgarg} :: context(curval)
+"                   | context(curarg)
+"                   | {var}
 function s:F.scan.scanmsg()
-    if self.eos
-        call self.throw('msgmis')
-    endif
     call self.addcon('msg', self.readc())
     if !self.eos
         let c=self.readc()
     return self.conclose()
 endfunction
 "▶2 scan.scanopt    :: &self
+" Input: {arg}* "]"?
+" Output: context(optional, {arg}*)
 function s:F.scan.scanopt()
     call self.addcon('optional')
     while !self.eos
     return self.conclose()
 endfunction
 "▶2 scan.scanpref   :: &self
+" Input: ({prefdescr} {arg})* "}"?
+"        {prefdescr} :: ( "?" | "*" )* ( "=" {var} )? ({str} | {wordchar}+)
+" Output: context(prefixes, context(String, {prefopts}[, {var}], {arg}))
+"         {prefopts} :: { "alt": Bool, "list": Bool }
+let s:defprefopts={"alt": 0, "list": 0}
 function s:F.scan.scanpref()
     call self.addcon('prefixes')
     if self.eos
         let c=self.readc()
         if !exists('pref')
             if !exists('prefopts')
-                let prefopts={}
+                let prefopts=copy(s:defprefopts)
             endif
             if c is '"'
                 let c=self.readstr()
                 call self.throw('invpref', c)
             endif
         else
-            call self.ungetc(c).addcon(pref, prefopts).scan().conclose()
+            call self.addcon(pref, prefopts)
+            if c is '='
+                call self.getvar()
+            else
+                call self.ungetc(c)
+            endif
+            call self.scan().conclose()
             unlet pref prefopts
         endif
     endwhile
     return self.conclose()
 endfunction
 "▶2 scan.scanact    :: &self
+" Input: "~" {matcher} ( {actdescr} ( "(" {arg}* ")"? | {arg} ) )* ">"?
+"        {actdescr} :: {str}
+"                    | {wordchar}+
+" Output: context(actions[, {matcher}], (context(String, {arg}+))*)
 function s:F.scan.scanact()
     let p={}
     call self.addcon('actions', p)
                 call self.throw('invact', c)
             endif
         else
+            call self.addcon(action)
+            unlet action
             if c is '('
-                call self.addcon(action)
-                unlet action
                 while !self.eos
                     let c=self.readc()
                     if c is ')'
                 endwhile
                 call self.conclose()
             else
-                call self.throw('noadescr')
+                call self.ungetc(c).scan()
             endif
         endif
     endwhile
     return self.conclose()
 endfunction
 "▶2 scan.scan       :: &self
+" Input: "[" {opt}  ⎫
+"      | "{" {pref} ⎬ (only at toplevel or in context(actions))
+"      | "<" {act}  ⎭
+"      | "(" ( "|" {pipe} | "#" {msg} | {intfunc} )* ")"?
+"      | ( "|" {pipe} | "#" {msg} )* {intfunc}?
+" Output: {opt}
+"       | {pref}
+"       | {act}
+"       | context(<self.type>, ({pipe}|{msg}|{intfunc})*)
 function s:F.scan.scan()
     let c=self.readc()
-    if c is '['
-        return self.scanopt()
-    elseif c is '{'
-        return self.scanpref()
-    elseif c is '<'
-        return self.scanact()
+    let type=self.stack[-1][0]
+    if type is self.o || type is "actions"
+        if c is '['
+            return self.scanopt()
+        elseif c is '{'
+            return self.scanpref()
+        elseif c is '<'
+            return self.scanact()
+        endif
     endif
     call self.addcon(self.type)
     let hasparen=0
             let hastext=1
             call self.ungetc(c).intfunc()
         elseif hasparen && c is ')'
-            let hasparen=0
             break
         else
             call self.ungetc(c)
             break
         endif
     endwhile
-    if hasparen
-        call self.throw('unmatchp', '(')
-    endif
     return self.conclose()
 endfunction
 "▶2 scan.scanopts   :: &self
+" Input: "-" "("? ( "no"? ( "only" ) )* ")"
 let s:options={'only': 0,}
 function s:F.scan.scanopts()
     let c=self.readc()
+    let self.o=copy(s:options)
+    call self.add(self.o)
     if c is '-'
-        call self.readc()  " Here must be a parenthesis
+        let c=self.readc()
+        if c isnot '('
+            call self.ungetc(c)
+        endif
         while !self.eos
             let c=self.readc()
             if c is ')'
                 \    'l': 0,
                 \  'eos': 0,
                 \ 'type': 'check',
-                \    'o': copy(s:options),
                 \}
     call extend(s, s:F.scan, 'error')
     " FIXME Redefine this function with more verbose one
     let s.throw=s:_f.throw
     call add(s.stack, s.tree)
     let s.l=s.stack[-1]
-    call s.scanopts().add(s.o)
+    call s.scanopts()
     let prevlen=0
     while !s.eos && len(s.s)!=prevlen
         call s.scan()
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.