Commits

ZyX_I committed ff13536

@frawor/fwc/constructor: Added more functions, refactoring

Comments (0)

Files changed (2)

     0.3: (intfuncs-0.3) Added -onlystrings support for |FWC-c-range|
     0.4: (intfuncs-0.4) Made |FWC-f-isfunc| transform argument to a function 
                         reference
+@/fwc/constructor:
+    0.1: Added more functions
 @/os:
     0.1: Added |frawor-r-os.path.relpath|
          Made |frawor-r-os.path.normpath| also simplify its argument

plugin/frawor/fwc/constructor.vim

 "▶1 Header
 scriptencoding utf-8
-execute frawor#Setup('0.0', {'@/resources': '0.0'}, 1)
+execute frawor#Setup('0.1', {'@/resources': '0.0'}, 1)
 let s:constructor={}
+let s:comp={}
 "▶1 string     :: a → String
 function s:constructor.string(val)
     if type(a:val)==type('') && a:val=~#"[\r\n@]"
                 \"\n",     '''."\\n".''',   'g'),
                 \"\r",     '''."\\r".''',   'g')
 endfunction
-"▶1 add        :: item, ... + self → self + self
+"▶1 getexpr
+function s:F.getexpr(expr, l)
+    if !empty(a:l)
+        return call('printf', [a:expr]+map(copy(a:l), 's:F.string(v:val)'))
+    endif
+    return ''.a:expr
+endfunction
+"▶1 getstr
+function s:F.getstr(s)
+    return a:s
+endfunction
+"▶1 _add       :: item, ... + self → self + self
 function s:constructor.add(...)
     let self.l+=a:000
     return self
 endfunction
-"▶1 up         :: &self
+"▶1 _up        :: &self
 function s:constructor.up()
     call remove(self.stack, -1)
     let self.l=self.stack[-1]
     return self
 endfunction
-"▶1 down       :: &self(list)
+"▶1 _down      :: &self(list)
 function s:constructor.down(list)
     call add(self.stack, a:list)
     let self.l=a:list
     return self
 endfunction
-"▶1 deeper     :: ()[, conelement1[, ...]] + self → self + self
+"▶1 _deeper    :: ()[, conelement1[, ...]] + self → self + self
 function s:constructor.deeper(...)
     let con=copy(a:000)
     call self.add(con)
     return self.down(con)
 endfunction
-"▶1 out        :: &self
+"▶1 _out       :: &self
 function s:constructor.out()
     if type(get(self.l, 0))==type('')
         return self.up()
     endif
     return self
 endfunction
-"▶1 toblock
+"▶1 _toblock
 function s:constructor.toblock(block)
     while get(self.l, 0) isnot a:block
         call self.up()
     endwhile
     return self
 endfunction
-"▶1 if         :: &self(condition)
-function s:constructor.if(condition)
-    return self.out().deeper('if', a:condition).deeper()
+"▶1 do: do, continue, break
+"▶2 comp.do
+function s:comp.do(r, toextend, indent, item)
+    call add(a:r, repeat(' ', &sw*a:indent).remove(a:item, 0))
 endfunction
-"▶1 else       :: &self
+"▶2 continue   :: &self
+function s:constructor.continue()
+    return self.out().deeper('do', 'continue').up()
+endfunction
+"▶2 break      :: &self
+function s:constructor.break()
+    return self.out().deeper('do', 'break').up()
+endfunction
+"▶2 do         :: &self(vimLstr)
+function s:constructor.do(str)
+    return self.out().deeper('do', a:str).up()
+endfunction
+"▶1 if block
+"▶2 comp.if
+function s:comp.if(r, toextend, indent, item)
+    call add(a:r, repeat(' ', &sw*a:indent).'if '.remove(a:item, 0))
+    if !empty(a:item)
+        call extend(a:toextend,map(remove(a:item,0),'['.(a:indent+1).',v:val]'))
+    endif
+    while !empty(a:item)
+        let type=remove(a:item, 0)
+        if type is# 'elseif'
+            call add(a:toextend, [a:indent, 'elseif '.remove(a:item, 0)])
+        elseif type is# 'else'
+            call add(a:toextend, [a:indent, 'else'])
+        elseif type is# 'endif'
+            break
+        endif
+        call extend(a:toextend,map(remove(a:item,0),'['.(a:indent+1).',v:val]'))
+    endwhile
+    call add(a:toextend, [a:indent, 'endif'])
+endfunction
+"▶2 if         :: &self(expr)
+function s:constructor.if(expr, ...)
+    return self.out().deeper('if', s:F.getexpr(a:expr, a:000)).deeper()
+endfunction
+"▶2 elseif     :: &self(expr)
+function s:constructor.elseif(expr, ...)
+    return self.toblock('if').add('elseif', s:F.getexpr(a:expr, a:000)).deeper()
+endfunction
+"▶2 else       :: &self
 function s:constructor.else()
     return self.toblock('if').add('else').deeper()
 endfunction
-"▶1 elseif     :: &self(condition)
-function s:constructor.elseif(condition)
-    return self.toblock('if').add('elseif', a:condition).deeper()
-endfunction
-"▶1 endif      :: &self
+"▶2 endif      :: &self
 function s:constructor.endif()
     return self.toblock('if').add('endif').up()
 endfunction
-"▶1 addif      :: &self(condition?)
+"▶2 addif      :: &self(expr?)
 function s:constructor.addif(...)
     if a:0
         if get(self.l, 0) is# 'if' && get(self.l, -2) isnot# 'else' &&
                     \                 get(self.l, -1) isnot# 'endif'
-            return self.elseif(a:1)
+            return call(self.elseif, a:000, self)
         else
-            return self.if(a:1)
+            return call(self.if, a:000, self)
         endif
     else
         if get(self.l, 0) is# 'if'
         endif
     endif
 endfunction
-"▶1 try        :: &self()
+"▶1 try block
+"▶2 comp.try
+function s:comp.try(r, toextend, indent, item)
+    call add(a:r, repeat(' ', &sw*a:indent).'try')
+    if !empty(a:item)
+        call extend(a:toextend,map(remove(a:item,0),'['.(a:indent+1).',v:val]'))
+    endif
+    while !empty(a:item)
+        let type=remove(a:item, 0)
+        if type is# 'catch'
+            call add(a:toextend, [a:indent, 'catch '.remove(a:item, 0)])
+        elseif type is# 'finally'
+            call add(a:toextend, [a:indent, 'finally'])
+        elseif type is# 'endtry'
+            break
+        endif
+        call extend(a:toextend,map(remove(a:item,0),'['.(a:indent+1).',v:val]'))
+    endwhile
+    call add(a:toextend, [a:indent, 'endtry'])
+endfunction
+"▶2 try        :: &self()
 function s:constructor.try()
     return self.out().deeper('try').deeper()
 endfunction
-"▶1 catch      :: &self(regex?)
+"▶2 catch      :: &self(regex?)
 function s:constructor.catch(...)
     return self.toblock('try')
-                \.add('catch', '/'.escape(get(a:000,0,'.*'), '/').'/').deeper()
+                \.add('catch', '/'.escape(get(a:000,0,'.*'),'/').'/').deeper()
 endfunction
-"▶1 finally    :: &self
+"▶2 finally    :: &self
 function s:constructor.finally()
     return self.toblock('try').add('finally').deeper()
 endfunction
-"▶1 while      :: &self(condition)
-function s:constructor.while(condition)
-    return self.out().deeper('while', a:condition).deeper()
+"▶1 cycles: while, for; continue, break
+"▶2 comp.while
+function s:comp.while(r, toextend, indent, item)
+    call add(a:r, repeat(' ', &sw*a:indent).'while '.remove(a:item, 0))
+    call extend(a:toextend, map(remove(a:item, 0), '['.(a:indent+1).', v:val]'))
+    call add(a:toextend, [a:indent, 'endwhile'])
 endfunction
-"▶1 for        :: &self(vars, list)
-function s:constructor.for(vars, list)
-    return self.out().deeper('for', a:vars, a:list).deeper()
+"▶2 while      :: &self(expr)
+function s:constructor.while(expr, ...)
+    return self.out().deeper('while', s:F.getexpr(a:expr, a:000)).deeper()
 endfunction
-"▶1 continue   :: &self
-function s:constructor.continue()
-    return self.out().deeper('continue').up()
+"▶2 comp.for
+function s:comp.for(r, toextend, indent, item)
+    call add(a:r, repeat(' ', &sw*a:indent).'for '.remove(a:item, 0).' in '.
+                \                                             remove(a:item, 0))
+    call extend(a:toextend, map(remove(a:item, 0), '['.(a:indent+1).', v:val]'))
+    call add(a:toextend, [a:indent, 'endfor'])
 endfunction
-"▶1 break      :: &self
-function s:constructor.break()
-    return self.out().deeper('break').up()
+"▶2 for        :: &self(vars, expr)
+function s:constructor.for(vars, expr, ...)
+    return self.out().deeper('for', a:vars, s:F.getexpr(a:expr, a:000)).deeper()
 endfunction
-"▶1 return     :: &self(expr)
-function s:constructor.return(expr)
-    return self.out().deeper('return', a:expr).up()
+"▶1 execute: call, throw, return
+"▶2 comp.execute
+function s:comp.execute(r, toextend, indent, item)
+    call add(a:r,repeat(' ',&sw*a:indent).remove(a:item,0).' '.remove(a:item,0))
 endfunction
-"▶1 let        :: &self(var, val)
-function s:constructor.let(var, val)
-    return self.out().deeper('let', a:var, a:val).up()
+"▶2 return, call, execute, echo, echomsg, echon
+for s:type in ['return', 'call', 'execute', 'echo', 'echomsg', 'echon']
+    execute      "function s:constructor.".s:type."(expr, ...)\n".
+                \"    return self.out()".
+                \                ".deeper('execute', ".
+                \                        "'".s:type."', ".
+                \                        "s:F.getexpr(a:expr, a:000))".
+                \                ".up()\n".
+                \"endfunction"
+endfor
+unlet s:type
+"▶2 throw      :: &self(expr)
+function s:constructor.throw(expr, ...)
+    return self.out().deeper('execute', 'throw', s:F.getexpr(a:expr, a:000))
+                \.up().up()
 endfunction
-"▶1 strappend  :: &self(var, val)
-function s:constructor.strappend(var, val)
-    return self.out().deeper('append', a:var, a:val).up()
+"▶1 let: let, strappend, increment, decrement
+"▶2 comp.let
+function s:comp.let(r, toextend, indent, item)
+    call add(a:r, repeat(' ', &sw*a:indent).'let '.remove(a:item, 0).
+                \                               remove(a:item, 0).'='.
+                \                                  remove(a:item, 0))
 endfunction
-"▶1 unlet      :: &self(var)
+"▶2 let, strappend
+for [s:type, s:s] in [['let', ''], ['strappend', '.']]
+    execute      "function s:constructor.".s:type."(var, expr, ...)\n".
+                \"    return self.out()".
+                \                ".deeper('let', a:var, '".s:s."', ".
+                \                        "s:F.getexpr(a:expr, a:000))".
+                \                ".up()\n".
+                \"endfunction"
+endfor
+unlet s:type s:s
+"▶2 increment  :: &self(var[, expr])
+function s:constructor.increment(var, ...)
+    let incval=get(a:000, 0, 1)
+    call self.out()
+    if type(incval)==type(0) && incval<0
+        call self.deeper('let', a:var, '-', ''.(-incval))
+    else
+        call self.deeper('let', a:var, '+',  s:F.getexpr(incval, a:000[1:]))
+    endif
+    return self.up()
+endfunction
+"▶2 decrement  :: &self(var[, expr])
+function s:constructor.decrement(var, ...)
+    let incval=get(a:000, 0, 1)
+    call self.out()
+    if type(incval)==type(0) && incval<0
+        call self.deeper('let', a:var, '+', ''.(-incval))
+    else
+        call self.deeper('let', a:var, '-',  s:F.getexpr(incval, a:000[1:]))
+    endif
+    return self.up()
+endfunction
+"▶1 unlet      :: &self(var|[var])
+function s:comp.unlet(r, toextend, indent, item)
+    call add(a:r, repeat(' ', &sw*a:indent).'unlet '.join(remove(a:item, 0)))
+endfunction
 function s:constructor.unlet(var)
-    return self.out().deeper('unlet', type(a:var)==type('')?[a:var]:a:var).up()
+    return self.out().deeper('unlet', type(a:var)==type('')?[a:var]:a:var)
+                \.up()
 endfunction
-"▶1 increment  :: &self(var[, val])
-function s:constructor.increment(var, ...)
-    return self.out().deeper('inc', a:var, get(a:000, 0, 1)).up()
-endfunction
-"▶1 decrement  :: &self(var, val)
-function s:constructor.decrement(var, val)
-    return self.out().deeper('dec', a:var, get(a:000, 0, 1)).up()
-endfunction
-"▶1 call       :: &self(expr)
-function s:constructor.call(expr)
-    return self.out().deeper('call', a:expr).up()
-endfunction
-"▶1 throw      :: &self(expr)
-function s:constructor.throw(expr)
-    return self.out().deeper('throw', a:expr).up().up()
-endfunction
-"▶1 do         :: &self(vimLstr)
-function s:constructor.do(str)
-    return self.out().deeper('do', a:str).up()
-endfunction
-"▶1 tolist     :: () + self → [String]
+"▶1 _tolist    :: () + self → [String]
 function s:constructor.tolist()
     let r=[]
     let items=map(deepcopy(self.tree), '[0, v:val]')
     let toextend=[]
     while !empty(items)
         let [indent, item]=remove(items, 0)
-        let istr=repeat('    ', indent)
         if type(item)==type('')
-            call add(r, istr.item)
+            call add(r, repeat(' ', &sw*indent).item)
         else
             let type=remove(item, 0)
-            if type is# 'if'
-                call add(r, istr.'if '.remove(item, 0))
-                if !empty(item)
-                    let toextend+=map(remove(item, 0),'['.(indent+1).', v:val]')
-                endif
-                while !empty(item)
-                    let type=remove(item, 0)
-                    if type is# 'elseif'
-                        call add(toextend, [indent, 'elseif '.remove(item, 0)])
-                    elseif type is# 'else'
-                        call add(toextend, [indent, 'else'])
-                    elseif type is# 'endif'
-                        break
-                    endif
-                    let toextend+=map(remove(item, 0),'['.(indent+1).', v:val]')
-                endwhile
-                call add(toextend, [indent, 'endif'])
-            elseif type is# 'try'
-                call add(r, istr.'try')
-                if !empty(item)
-                    let toextend+=map(remove(item, 0),'['.(indent+1).', v:val]')
-                endif
-                while !empty(item)
-                    let type=remove(item, 0)
-                    if type is# 'catch'
-                        call add(toextend, [indent, 'catch '.remove(item, 0)])
-                    elseif type is# 'finally'
-                        call add(toextend, [indent, 'finally'])
-                    elseif type is# 'endtry'
-                        break
-                    endif
-                    let toextend+=map(remove(item, 0),'['.(indent+1).', v:val]')
-                endwhile
-                call add(toextend, [indent, 'endtry'])
-            elseif type is# 'while'
-                call add(r, istr.'while '.remove(item, 0))
-                let toextend+=map(remove(item, 0),'['.(indent+1).', v:val]')
-                call add(toextend, [indent, 'endwhile'])
-            elseif type is# 'for'
-                call add(r, istr.'for '.remove(item, 0).' in '.remove(item, 0))
-                let toextend+=map(remove(item, 0),'['.(indent+1).', v:val]')
-                call add(toextend, [indent, 'endfor'])
-            elseif type is# 'let'
-                call add(r, istr.'let '.remove(item, 0).'='.remove(item, 0))
-            elseif type is# 'append'
-                call add(r, istr.'let '.remove(item, 0).'.='.remove(item, 0))
-            elseif type is# 'inc'
-                let lhs=remove(item, 0)
-                let assign='+='
-                let shift=remove(item, 0)
-                if type(shift)==type(0) && shift<0
-                    let assign='-='
-                    let shift=-shift
-                endif
-                call add(r, istr.'let '.lhs.assign.shift)
-            elseif type is# 'dec'
-                call add(r, istr.'let '.remove(item, 0).'-='.remove(item, 0))
-            elseif       type is# 'call'   ||
-                        \type is# 'throw'  ||
-                        \type is# 'return'
-                call add(r, istr.type.' '.remove(item, 0))
-            elseif type is# 'unlet'
-                call add(r, istr.type.' '.join(remove(item, 0)))
-            elseif type is# 'continue' || type is# 'break'
-                call add(r, istr.type)
-            elseif type is# 'do'
-                call add(r, remove(item, 0))
+            if has_key(s:comp, type)
+                call call(s:comp[type], [r, toextend, indent, item], {})
             endif
             if !empty(toextend)
                 call extend(items, remove(toextend, 0, -1), 0)