From 8751c041562da72b2eb6588dd3c8a3b2043c06b1 Mon Sep 17 00:00:00 2001 From: Iustin Pop <iustin@google.com> Date: Thu, 22 Dec 2011 17:32:15 +0100 Subject: [PATCH] Improve convert-constants to handle dictionaries MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The two main drawbacks for convert-constants are the fact that it can't handle sets/frozensets (mainly due to the fact that I don't know how useful this would be to the Haskell code) and that it cannot export dictionaries. To fix the second case, the current patch changes the code to support flattening (potentially nested) dictionaries into single name space. Yes, this could generate conflicts, but they will be detected at compile time. Signed-off-by: Iustin Pop <iustin@google.com> Reviewed-by: RenΓ© Nussbaumer <rn@google.com> --- autotools/convert-constants | 70 +++++++++++++++++++++++++------------ 1 file changed, 48 insertions(+), 22 deletions(-) diff --git a/autotools/convert-constants b/autotools/convert-constants index 3f2b362d3..8dd1a1162 100755 --- a/autotools/convert-constants +++ b/autotools/convert-constants @@ -26,13 +26,14 @@ import re from ganeti import constants -CONSTANT_RE = re.compile("^[A-Z][A-Z0-9_]+$") +CONSTANT_RE = re.compile("^[A-Z][A-Z0-9_-]+$") def NameRules(name): """Converts the upper-cased Python name to Haskell camelCase. """ + name = name.replace("-", "_") elems = name.split("_") return elems[0].lower() + "".join(e.capitalize() for e in elems[1:]) @@ -46,6 +47,51 @@ def StringValueRules(value): return value +def DictKeyName(dict_name, key_name): + """Converts a dict plus key name to a full name. + + """ + return"%s_%s" % (dict_name, str(key_name).upper()) + + +def ConvertVariable(name, value): + """Converts a given variable to Haskell code. + + @param name: the Python name + @param value: the value + @return: a list of Haskell code lines + + """ + lines = [] + hs_name = NameRules(name) + if not CONSTANT_RE.match(name): + lines.append("-- Skipped %s, not constant" % name) + elif isinstance(value, basestring): + lines.append("-- | Converted from Python constant %s" % name) + lines.append("%s :: String" % hs_name) + lines.append("%s = \"%s\"" % (hs_name, StringValueRules(value))) + elif isinstance(value, int): + lines.append("-- | Converted from Python constant %s" % name) + lines.append("%s :: Int" % hs_name) + lines.append("%s = %d" % (hs_name, value)) + elif isinstance(value, long): + lines.append("-- | Converted from Python constant %s" % name) + lines.append("%s :: Integer" % hs_name) + lines.append("%s = %d" % (hs_name, value)) + elif isinstance(value, float): + lines.append("-- | Converted from Python constant %s" % name) + lines.append("%s :: Double" % hs_name) + lines.append("%s = %f" % (hs_name, value)) + elif isinstance(value, dict): + if value: + lines.append("-- Following lines come from dictionary %s" % name) + for k in sorted(value.keys()): + lines.extend(ConvertVariable(DictKeyName(name, k), value[k])) + else: + lines.append("-- Skipped %s, %s not handled" % (name, type(value))) + return lines + + def Convert(): """Converts the constants to Haskell. @@ -56,27 +102,7 @@ def Convert(): for name in all_names: value = getattr(constants, name) - hs_name = NameRules(name) - if not CONSTANT_RE.match(name): - lines.append("-- Skipped %s, not constant" % name) - elif isinstance(value, basestring): - lines.append("-- | Converted from Python constant %s" % name) - lines.append("%s :: String" % hs_name) - lines.append("%s = \"%s\"" % (hs_name, StringValueRules(value))) - elif isinstance(value, int): - lines.append("-- | Converted from Python constant %s" % name) - lines.append("%s :: Int" % hs_name) - lines.append("%s = %d" % (hs_name, value)) - elif isinstance(value, long): - lines.append("-- | Converted from Python constant %s" % name) - lines.append("%s :: Integer" % hs_name) - lines.append("%s = %d" % (hs_name, value)) - elif isinstance(value, float): - lines.append("-- | Converted from Python constant %s" % name) - lines.append("%s :: Double" % hs_name) - lines.append("%s = %f" % (hs_name, value)) - else: - lines.append("-- Skipped %s, %s not handled" % (name, type(value))) + lines.extend(ConvertVariable(name, value)) lines.append("") return "\n".join(lines) -- GitLab