Commits

ZyX_I committed 4054278

@/fwc/compiler: Added FWC decorator

Comments (0)

Files changed (2)

plugin/frawor/fwc/compiler.vim

     finish
 endif
 execute frawor#Setup('0.0', {'@/fwc/parser'     : '0.0',
+            \                '@/fwc/constructor': '0.0',
             \                '@/os'             : '0.0',
-            \                '@/fwc/constructor': '0.0'}, 1)
+            \                '@/decorators'     : '0.0'}, 1)
 let s:compiler={}
 "▶1 Messages
 let s:_messages={
             \   'toolong': 'Argument list is too long: '.
             \              'expected at most %u, but got %u',
             \    'invlen': 'Invalid arguments length: expected %u, but got %u',
+            \   'FWCfail': 'Error while processing arguments of function %s '.
+            \              'for plugin %s',
         \}
 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',
+        \}, '"Error while creating function %s for plugin %s: ".v:val'))
+call extend(s:_messages, map({
             \  'funcfail': 'custom function returned 0',
             \  'exprfail': 'custom expression returned 0',
             \ 'typesfail': 'invalid type: expected one of %s, but got %s',
             let hascheck=1
             call self.add('try').deeper()
                             \.add('let '.foundstr.'=0')
-                            \.witharg([keystr, []])
+                            \.witharg([keystr])
                             \.compilearg(check[1], a:idx.'.'.i.'(key)', 'check')
                             \.without()
                             \.add('let '.foundstr.'=1')
     " TODO
     return self
 endfunction
-"▶1 compilestr     :: String, type → [String]
-function s:F.compilestr(vars, string, type)
+"▶1 compilestr     :: vars, String, type, doreturn → [String]
+function s:F.compilestr(vars, string, type, doreturn)
     "▶2 Setup self
     let t=extend(s:_r.new_constructor(), {
                 \   'tree': s:_r.fwc_parser(a:string, a:type)[1:],
                 \.add('for @$@targs in @$@pmessages')
                   \.deeper('call call(@%@.p._f.warn, @$@targs, {})')
                 \.up().close()
-                \.add('return 0')
+                \.add((a:doreturn is 1)?('return 0'):
+                \                       ('call @%@.F.throw('.a:doreturn.')'))
               \.up().close()
     else
         call t.add('let @@@=[]')
     endif
-    if t.type is 'check'
-        call t.add('return 1')
-    elseif t.type is 'filter'
-        call t.add('return @@@')
-    else
-        call t.add('return @@@')
+    if a:doreturn is 1
+        if t.type is 'check'
+            call t.add('return 1')
+        elseif t.type is 'filter'
+            call t.add('return @@@')
+        else
+            call t.add('return @@@')
+        endif
     endif
     return t.tolstofstr()
 endfunction
 "▶1 createvars     :: plugdict → id + s:lastid, s:vars
 function s:F.createvars(plugdict)
     return {
-                \ 'F': {'warn': s:_f.warn, 'matchers': s:F.matchers},
+                \ 'F': {'warn': s:_f.warn, 'throw': s:_f.throw,
+                \       'matchers': s:F.matchers},
                 \ 'p': a:plugdict.g,
                 \ 'm': {'types': s:_messages._types},
                 \'os': s:_r.os,
     call add(a:fdict.ids, id)
     execute "function d.f(args)\n    ".
                 \substitute(substitute(substitute(
-                \join(s:F.compilestr(s:vars[id], a:string, a:type), "\n    "),
+                \join(s:F.compilestr(s:vars[id], a:string, a:type, 1),"\n    "),
                 \'@@@', ((a:type is 'complete')?
                 \           ('variants'):
                 \           ('a:args')), 'g'),
 call s:_f.newfeature('fwc_compile', {'cons': s:F.makefunc,
             \                      'unload': s:F.delids,
             \                        'init': {'ids': []}})
+"▶1 makedec        :: plugdict, fname, arg
+function s:F.makedec(plugdict, fname, arg)
+    "▶2 Check arguments
+    if type(a:arg)!=type([])
+        call s:_f.throw('decargnstr', a:fname, a:plugdict.id)
+    elseif len(a:arg)!=2
+        call s:_f.throw('largn2', a:fname, a:plugdict.id, len(a:arg))
+    elseif type(a:arg[0])!=type('')
+        call s:_f.throw('1nstr', a:fname, a:plugdict.id)
+    elseif index(['check', 'filter'], a:arg[1])
+        call s:_f.throw('invtype', a:fname, a:plugdict.id, string(a:arg))
+    endif
+    "▲2
+    let vars=s:F.createvars(a:plugdict)
+    let a='"FWCfail", '.s:F.string(a:fname).', '.s:F.string(a:plugdict.id)
+    return [128, '@@@', vars, s:F.compilestr(vars, a:arg[0], a:arg[1], a), [],0]
+endfunction
+"▶1 Register decorator
+call s:_f.adddecorator('FWC', s:F.makedec)
 "▶1
 " TODO implement recursion protection
 " TODO implement onlystrings option (disables type checks)

test/reload-frawor.ok

 unloadpre: plugin/writefile-feature
 unloadpre: plugin/frawor/decorators/altervars
 unloadpre: plugin/frawor/checks
-unloadpre: plugin/frawor/decorators
 unloadpre: plugin/frawor/fwc/compiler
 unloadpre: plugin/frawor/fwc/constructor
 unloadpre: plugin/frawor/fwc/parser
+unloadpre: plugin/frawor/decorators
 unloadpre: plugin/frawor/os
 unloadpre: plugin/frawor/resources
 unloadpre: plugin/frawor