convert enum values to integers
Previously the enum values given to the backends were strings of C code.
Luckily the code was simple enough that it was also valid Python. Moving the
conversion to the frontend makes it easier to move enum definitions into the
input files, and cleans up some pyloxi code.
diff --git a/loxi_front_end/identifiers.py b/loxi_front_end/identifiers.py
index 62759d7..0f35dc6 100644
--- a/loxi_front_end/identifiers.py
+++ b/loxi_front_end/identifiers.py
@@ -56,6 +56,7 @@
version, all_idents, idents_by_group)
def add_identifier(name, ofp_name, ofp_group, value, version, all_idents, idents_by_group):
+ assert(isinstance(value, int))
if name in all_idents:
all_idents[name]["values_by_version"][version] = value
if ((all_idents[name]["ofp_name"] != ofp_name or
diff --git a/loxi_front_end/of_h_utils.py b/loxi_front_end/of_h_utils.py
index 26dbac1..ed70a55 100644
--- a/loxi_front_end/of_h_utils.py
+++ b/loxi_front_end/of_h_utils.py
@@ -101,9 +101,9 @@
for enum in enum_list:
(name, values) = c_parse_utils.extract_enum_vals(enum)
for (ident, value) in values:
- full_ident_list[ident] = str(value).strip()
+ full_ident_list[ident] = value
for ident, value in defines_list:
- full_ident_list[ident] = str(value).strip()
+ full_ident_list[ident] = value
# Process enum idents
for enum in enum_list:
@@ -123,7 +123,7 @@
rv_list[loxi_name] = py_utils.DotDict(dict(
ofp_name = ident,
ofp_group = name,
- value = value_str))
+ value = eval(value_str)))
for ident, value in defines_list:
loxi_name = translation.loxi_name(ident)
@@ -133,7 +133,7 @@
value_str = fixup_values(ident, value, version, full_ident_list)
if loxi_name in rv_list:
- if value_str != rv_list[loxi_name].value:
+ if eval(value_str) != rv_list[loxi_name].value:
sys.stderr.write("""
ERROR: IDENT COLLISION. Version %s, LOXI Ident %s.
New ofp_name %s, value %s.
@@ -148,7 +148,7 @@
rv_list[loxi_name] = py_utils.DotDict(dict(
ofp_name = ident,
ofp_group = "macro_definitions",
- value = value_str))
+ value = eval(value_str)))
return rv_list
diff --git a/loxi_front_end/parser.py b/loxi_front_end/parser.py
index 974e6cf..d79dd3c 100644
--- a/loxi_front_end/parser.py
+++ b/loxi_front_end/parser.py
@@ -36,6 +36,10 @@
tag = lambda name: P.Empty().setParseAction(P.replaceWith(name))
word = P.Word(P.alphanums + '_')
+integer = (
+ P.Combine('0x' - P.Word('0123456789abcdefABCDEF') |
+ P.Word('0123456789'))
+ ).setParseAction(lambda x: int(x[0], 0))
identifier = word.copy().setName("identifier")
@@ -52,7 +56,7 @@
s('}') - s(';')
# Enums
-enum_member = P.Group(identifier + s('=') + P.Word(P.alphanums + '_'))
+enum_member = P.Group(identifier + s('=') + integer)
enum_list = P.Forward()
enum_list << enum_member + P.Optional(s(',') + P.Optional(enum_list))
enum = kw('enum') - identifier - s('{') + \
diff --git a/py_gen/templates/const.py b/py_gen/templates/const.py
index 93418a1..ef09585 100644
--- a/py_gen/templates/const.py
+++ b/py_gen/templates/const.py
@@ -37,12 +37,12 @@
OFP_VERSION = ${version}
:: for (group, idents) in sorted(groups.items()):
-:: idents.sort(key=lambda (ident, value): eval(value) if value != 'OFPVID_NONE' else 0)
+:: idents.sort(key=lambda (ident, value): value)
# Identifiers from group ${group}
:: for (ident, value) in idents:
:: if version == 1 and ident.startswith('OFPP_'):
:: # HACK loxi converts these to 32-bit
-${ident} = ${"%#x" % (int(value, 16) & 0xffff)}
+${ident} = ${"%#x" % (value & 0xffff)}
:: else:
${ident} = ${value}
:: #endif
@@ -55,7 +55,7 @@
:: pass
:: elif version == 1 and ident.startswith('OFPP_'):
:: # HACK loxi converts these to 32-bit
- ${"%#x" % (int(value, 16) & 0xffff)}: ${repr(ident)},
+ ${"%#x" % (value & 0xffff)}: ${repr(ident)},
:: else:
${value}: ${repr(ident)},
:: #endif
diff --git a/py_gen/util.py b/py_gen/util.py
index fbb2825..068a234 100644
--- a/py_gen/util.py
+++ b/py_gen/util.py
@@ -76,4 +76,4 @@
def constant_for_value(version, group, value):
return (["const." + v["ofp_name"] for k, v in of_g.identifiers.items()
if k in of_g.identifiers_by_group[group] and
- eval(v["values_by_version"].get(version, "None")) == value] or [value])[0]
+ v["values_by_version"].get(version, None) == value] or [value])[0]
diff --git a/utest/test_parser.py b/utest/test_parser.py
index 91100ab..33ba545 100755
--- a/utest/test_parser.py
+++ b/utest/test_parser.py
@@ -99,7 +99,7 @@
};
"""
ast = parser.parse(src)
- self.assertEquals(ast.asList(), [['enum', 'foo', [['BAR', '1']]]])
+ self.assertEquals(ast.asList(), [['enum', 'foo', [['BAR', 1]]]])
def test_multiple(self):
src = """\
@@ -110,7 +110,7 @@
};
"""
ast = parser.parse(src)
- self.assertEquals(ast.asList(), [['enum', 'foo', [['OFP_A', '1'], ['OFP_B', '2'], ['OFP_C', '3']]]])
+ self.assertEquals(ast.asList(), [['enum', 'foo', [['OFP_A', 1], ['OFP_B', 2], ['OFP_C', 3]]]])
def test_trailing_comma(self):
src = """\
@@ -121,7 +121,7 @@
};
"""
ast = parser.parse(src)
- self.assertEquals(ast.asList(), [['enum', 'foo', [['OFP_A', '1'], ['OFP_B', '2'], ['OFP_C', '3']]]])
+ self.assertEquals(ast.asList(), [['enum', 'foo', [['OFP_A', 1], ['OFP_B', 2], ['OFP_C', 3]]]])
class TestMetadata(unittest.TestCase):
def test_version(self):