Commits

Anonymous committed 36b7b47

fixed #2. removed HybridObj from cfuncs.py

  • Participants
  • Parent commits 5b2bd9a

Comments (0)

Files changed (3)

railgun/cfuncs.py

 import re
-from railgun._helper import HybridObj, iteralt, product
+from railgun._helper import iteralt, product
 
 CJOINSTR = '_'
 
     )  # matches "int a=1" as "CDT NAME=DEFAULT"
 
 
+class _CFunctionDeclaration(object):
+    """
+    A class to sotre parsed information of C-function declaration
+
+    Attributes
+    ----------
+    ret : str or None
+        returned value
+    fname : str
+        name of function
+    choset : list of {'choices': [str], 'key': str}
+        choice set
+    args : list of {'aname': [str], 'default': obj, 'cdt': str}
+        arguments
+    fnget : (str, str, ...) -> str
+        function name getter.
+        it constructs C function name from given "choices".
+
+    """
+
+    def as_dict(self):
+        keys = ["ret", "fname", "choset", "args", "fnget"]
+        return dict((k, getattr(self, k)) for k in keys if hasattr(self, k))
+
+    @classmethod
+    def from_string(cls, cfstr):
+        cfstr = cfstr.strip()  # "'ans' func_{k|a,b,c}(int a, i i=1)"
+
+        match_func = RE_CFDEC_FUNC.match(cfstr)
+        # ret="ans", fname="func_{k|a,b,c}", args="int a, i i=1"
+        if match_func:
+            return cls.from_groupdict(**match_func.groupdict())
+        else:
+            raise ValueError(
+                "%s is invalid as c-function cdt declaration" % cfstr)
+
+    @classmethod
+    def from_groupdict(cls, ret, fname, args):
+        parsed = cls()
+        (fname, choset, fnget) = cfdec_fname_parse(fname)
+        parsed.ret = ret
+        parsed.fname = fname
+        parsed.choset = choset
+        parsed.args = cfdec_args_parse(args)
+        parsed.fnget = fnget
+        return parsed
+
+
 def cfdec_args_parse(args):
     """Parse cfdec argument like this: 'int a=1, float x=2.0'"""
     parsed = []
     return (fname, choset, fnget)
 
 
-def cfdec_parse(cfstr):
-    """
-    Parse declaration of a function
-
-    Given declaration of a function,::
-
-        ret func_{k1|x,y,z}_...(int a, ...)
-
-    this function returns dict like this::
-
-        {'args': [{'aname': 'a', 'default': None, 'cdt': 'int'},
-                  ...],
-         'choset': [{'choices': ['x', 'y', 'z'], 'key': 'k1'},
-                     ...],
-         'fname': 'func',
-         'fnget': <function fnget_func at XXXXXXXXX>
-         'ret': 'ret'}
-
-    """
-    cfstr = cfstr.strip()  # "'ans' func_{k|a,b,c}(int a, i i=1)"
-
-    match_func = RE_CFDEC_FUNC.match(cfstr)
-    if match_func:
-        parsed = HybridObj(match_func.groupdict())
-        ## ret="ans", fname="func_{k|a,b,c}", args="int a, i i=1"
-    else:
-        raise ValueError(
-            "%s is invalid as c-function cdt declaration" % cfstr)
-
-    (fname, choset, fnget) = cfdec_fname_parse(parsed.fname)
-    parsed.fname = fname
-    parsed.choset = choset
-    parsed.args = cfdec_args_parse(parsed.args)
-    parsed.fnget = fnget
-
-    return parsed
+cfdec_parse = _CFunctionDeclaration.from_string
 
 
 def choice_combinations(cfdec):
-    return product([c['choices'] for c in cfdec['choset']])
+    return product([c['choices'] for c in cfdec.choset])

railgun/simobj.py

             cf = cdll[cfuncprefix + cfname]
             cf.restype = c_int
             cf.argtypes = (
-                [struct_type_p] + map(get_arg_ct, parsed['args']))
+                [struct_type_p] + map(get_arg_ct, parsed.args))
             cfunc_loaded[cfname] = cf
     return cfunc_loaded
 

tests/test_cfuncs.py

 
 def check_cfdec_parse(cfstr, correct, fnameargslist):
     ret = cfdec_parse(cfstr)
-    dct = subdict(ret(), *list(correct))  # exclude 'fnget'
+    dct = subdict(ret.as_dict(), *list(correct))  # exclude 'fnget'
     fnget = ret.fnget
     eq_(correct, dct, 'incorrect return for "%s"' % (cfstr))
     for (fname, args) in fnameargslist: