import functools
import re
def linewise(f):
@functools.wraps(f)
def g(*args, **kwargs):
return '\n'.join(f(*args, **kwargs))
return g
def comma_sep(f):
@functools.wraps(f)
def g(*args, **kwargs):
return ', '.join(f(*args, **kwargs))
return g
def wordwise(f):
@functools.wraps(f)
def g(*args, **kwargs):
return ' '.join(f(*args, **kwargs))
return g
@comma_sep
def struct_fields(fields, suffix, bind_mode):
for f in fields:
yield '%s: %s%s%s' % (f.name, bind_mode, f.name, suffix)
@comma_sep
def tuple_fields(fields, suffix, bind_mode):
for f in fields:
yield '%s%s%s' % (bind_mode, f.name, suffix)
def struct_pattern(s, path, suffix='', bind_mode='ref '):
if not s.is_tuple:
return '%s { %s }' % (path, struct_fields(s.fields, suffix, bind_mode))
else:
if len(s.fields) == 0:
return path
else:
return '%s(%s)' % (path, tuple_fields(s.fields, suffix, bind_mode))
CAPS_RE = re.compile(r'[A-Z]')
def snake(s):
s = CAPS_RE.sub(lambda m: '_' + m.group().lower(), s)
if s.startswith('_'):
s = s[1:]
return s
def find_kind_field(s):
if 'no_kind' in s.attrs:
return None
marked_fields = []
for f in s.fields:
if 'kind' in f.attrs:
marked_fields.append(f.name)
if len(marked_fields) == 1:
return marked_fields[0]
elif len(marked_fields) > 1:
raise ValueError('struct %s has %d fields marked #[kind] (expected 0 or 1)' %
(s.name, len(marked_fields)))
for f in s.fields:
if f.name == 'kind':
return f.name
return None