Commits

ZyX_I committed 03271c3

@/fwc: Fixed subscripts with mixed variable/number ranges

Comments (0)

Files changed (4)

plugin/frawor/fwc/compiler.vim

         endif
     endif
 endfunction
-"▶1 substostr      :: [subscript] + self → String
-function s:compiler.substostr(subscripts)
+"▶1 getsubs        :: [subscript] + self → String
+function s:compiler.getsubs(subscripts)
     let r=''
     for sub in a:subscripts
         let tsub=type(sub)
         elseif tsub==type(0)
             let r.='['.sub.']'
         elseif tsub==type([])
-            if type(sub[0])==type([])
-                let r.='['.join(map(copy(sub), 'self.getvar(v:val)'), ':').']'
-            else
-                let r.='['.join(sub, ':').']'
-            endif
+            let r.='['.join(map(copy(sub), 'type(v:val)=='.type([]).'?'.
+                        \                       'self.getvar(v:val):'.
+                        \                       'v:val'), ':').']'
         endif
         unlet sub
     endfor
     return r
 endfunction
 "▶1 argstr         :: [genString::Bool, [subscript]] + self → String
-"▶2 addargchunk    :: [chunk], chunk::String, literal::Bool → _ + chunks
+"▶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
+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)
+    elseif type(a:sub)==type('')
+        call s:F.addargchunk(a:chunks, 'string('.a:sub.')', 1)
+    else
+        call s:F.addargchunk(a:chunks, a:sub, 0)
+    endif
+endfunction
 "▲2
 function s:compiler.argstr(...)
     if get(a:000, 0, 0)
             elseif tsub==type(0)
                 call s:F.addargchunk(chunks, '['.sub.']', 0)
             else
-                if type(sub[0])==type('')
-                    call s:F.addargchunk(chunks, '[', 0)
-                    call s:F.addargchunk(chunks, 'string('.sub[0].')', 1)
-                    if len(sub)>1
-                        call s:F.addargchunk(chunks, ':', 0)
-                        call s:F.addargchunk(chunks, sub[1], 1)
-                    endif
-                    call s:F.addargchunk(chunks, ']', 0)
-                else
-                    call s:F.addargchunk(chunks, '['.join(sub, ':').']', 0)
+                call s:F.addargchunk(chunks, '[', 0)
+                call s:F.addstrsub(chunks, sub[0], self)
+                if len(sub)>1
+                    call s:F.addargchunk(chunks, ':', 0)
+                    call s:F.addstrsub(chunks, sub[1], self)
                 endif
+                call s:F.addargchunk(chunks, ']', 0)
             endif
             unlet sub
         endfor
         return join(map(chunks, 'v:key%2 ? v:val : string(v:val)'), '.')
     else
-        return self.argbase.(self.substostr(get(a:000, 1, self.subs)))
+        return self.argbase.(self.getsubs(get(a:000, 1, self.subs)))
     endif
 endfunction
 "▶1 incsub         :: &self
 "▶1 getvar         :: varcontext + self → String
 function s:compiler.getvar(var)
     if a:var[0] is 'plugvar'
-        return '@%@.p.'.a:var[1].(self.substostr(a:var[2:]))
+        return '@%@.p.'.a:var[1].(self.getsubs(a:var[2:]))
     elseif a:var[0] is 'expr'
         return self.getexpr(a:var)
     elseif a:var[0] is 'string'

plugin/frawor/fwc/parser.vim

 "      | "=" {expr}
 "      | "[" {list}
 "      | "$" {var}
+"      | "(" {var} ")"
 "      | {str}
 " Output: context(plugvar, String, {subscr}*)
 "       | {chvar}
         call self.addcon('string', self.readstr()).conclose()
     elseif c is "'"
         call self.addcon('string', self.readsstr()).conclose()
+    elseif c is '('
+        call self.getvar()
+        if self.readc() isnot ')'
+            call self.throw('unmatchp', '(')
+        endif
     else
         call self.throw('invvar', c)
     endif
 plugin/frawor/fwc/compiler:ninlist
 plugin/frawor/fwc/compiler:ninlist
 plugin/frawor/fwc/compiler:ninlist
+plugin/frawor/fwc/compiler:ninlist
+plugin/frawor/fwc/compiler:ninlist
+plugin/frawor/fwc/compiler:ninlist
 ::: Section <Checks/Built-in checks/dict>
 plugin/frawor/fwc/compiler:keynmatch
 plugin/frawor/fwc/compiler:typefail

test/fwctests.dat

 ['in d.''list''',     'check'], [5],                0
 ['in d.$listname',    'check'], [0],                1
 ['in d.$listname',    'check'], [5],                0
+['in d.(listname)',   'check'], [0],                1
+['in d.(listname)',   'check'], [5],                0
 ['in d.list.:$ss$es', 'check'], [2],                1
 ['in d.list.:$ss$es', 'check'], [0],                0
+['in d.list.:$ss 2',  'check'], [2],                1
+['in d.list.:$ss 2',  'check'], [0],                0
+['in d.list.:1 $es',  'check'], [2],                1
+['in d.list.:1 $es',  'check'], [0],                0
 ['in d.list.:1 2',    'check'], [2],                1
 ['in d.list.:1 2',    'check'], [0],                0
 #▶3 dict