Merge pull request #131 from EricRahm/use_enums_in_ir
Split out IR enums
diff --git a/compiler/back_end/cpp/header_generator.py b/compiler/back_end/cpp/header_generator.py
index a761bde..c671d6e 100644
--- a/compiler/back_end/cpp/header_generator.py
+++ b/compiler/back_end/cpp/header_generator.py
@@ -250,8 +250,8 @@
buffer_type, byte_order,
parent_addressable_unit):
"""Returns the adapted C++ type information needed to construct a view."""
- if (parent_addressable_unit == ir_pb2.TypeDefinition.BYTE and
- type_definition.addressable_unit == ir_pb2.TypeDefinition.BIT):
+ if (parent_addressable_unit == ir_pb2.AddressableUnit.BYTE and
+ type_definition.addressable_unit == ir_pb2.AddressableUnit.BIT):
assert byte_order
return _bytes_to_bits_convertor(buffer_type, byte_order, size_in_bits)
else:
@@ -374,7 +374,7 @@
element_view_parameter_types="".join(
", " + p for p in element_view_parameter_types),
element_size=element_size,
- addressable_unit_size=parent_addressable_unit,
+ addressable_unit_size=int(parent_addressable_unit),
buffer_type=buffer_type),
element_view_parameter_types,
element_view_parameters
@@ -412,19 +412,19 @@
def _builtin_function_name(function):
"""Returns the C++ operator name corresponding to an Emboss operator."""
functions = {
- ir_pb2.Function.ADDITION: "Sum",
- ir_pb2.Function.SUBTRACTION: "Difference",
- ir_pb2.Function.MULTIPLICATION: "Product",
- ir_pb2.Function.EQUALITY: "Equal",
- ir_pb2.Function.INEQUALITY: "NotEqual",
- ir_pb2.Function.AND: "And",
- ir_pb2.Function.OR: "Or",
- ir_pb2.Function.LESS: "LessThan",
- ir_pb2.Function.LESS_OR_EQUAL: "LessThanOrEqual",
- ir_pb2.Function.GREATER: "GreaterThan",
- ir_pb2.Function.GREATER_OR_EQUAL: "GreaterThanOrEqual",
- ir_pb2.Function.CHOICE: "Choice",
- ir_pb2.Function.MAXIMUM: "Maximum",
+ ir_pb2.FunctionMapping.ADDITION: "Sum",
+ ir_pb2.FunctionMapping.SUBTRACTION: "Difference",
+ ir_pb2.FunctionMapping.MULTIPLICATION: "Product",
+ ir_pb2.FunctionMapping.EQUALITY: "Equal",
+ ir_pb2.FunctionMapping.INEQUALITY: "NotEqual",
+ ir_pb2.FunctionMapping.AND: "And",
+ ir_pb2.FunctionMapping.OR: "Or",
+ ir_pb2.FunctionMapping.LESS: "LessThan",
+ ir_pb2.FunctionMapping.LESS_OR_EQUAL: "LessThanOrEqual",
+ ir_pb2.FunctionMapping.GREATER: "GreaterThan",
+ ir_pb2.FunctionMapping.GREATER_OR_EQUAL: "GreaterThanOrEqual",
+ ir_pb2.FunctionMapping.CHOICE: "Choice",
+ ir_pb2.FunctionMapping.MAXIMUM: "Maximum",
}
return functions[function]
@@ -488,9 +488,9 @@
def _render_builtin_operation(expression, ir, field_reader, subexpressions):
"""Renders a built-in operation (+, -, &&, etc.) into C++ code."""
assert expression.function.function not in (
- ir_pb2.Function.UPPER_BOUND, ir_pb2.Function.LOWER_BOUND), (
+ ir_pb2.FunctionMapping.UPPER_BOUND, ir_pb2.FunctionMapping.LOWER_BOUND), (
"UPPER_BOUND and LOWER_BOUND should be constant.")
- if expression.function.function == ir_pb2.Function.PRESENCE:
+ if expression.function.function == ir_pb2.FunctionMapping.PRESENCE:
return field_reader.render_existence(expression.function.args[0],
subexpressions)
args = expression.function.args
diff --git a/compiler/front_end/attribute_checker.py b/compiler/front_end/attribute_checker.py
index cb8db74..b621081 100644
--- a/compiler/front_end/attribute_checker.py
+++ b/compiler/front_end/attribute_checker.py
@@ -218,7 +218,7 @@
ir_util.get_base_type(field.type).atomic_type.reference.canonical_name,
ir)
assert field_type is not None
- assert field_type.addressable_unit != ir_pb2.TypeDefinition.NONE
+ assert field_type.addressable_unit != ir_pb2.AddressableUnit.NONE
return field_type.addressable_unit != type_definition.addressable_unit
@@ -279,9 +279,9 @@
size = ir_util.get_integer_attribute(type_definition.attribute,
attributes.ADDRESSABLE_UNIT_SIZE)
if size == 1:
- type_definition.addressable_unit = ir_pb2.TypeDefinition.BIT
+ type_definition.addressable_unit = ir_pb2.AddressableUnit.BIT
elif size == 8:
- type_definition.addressable_unit = ir_pb2.TypeDefinition.BYTE
+ type_definition.addressable_unit = ir_pb2.AddressableUnit.BYTE
# If the addressable_unit_size is not in (1, 8), it will be caught by
# _verify_addressable_unit_attribute_on_external, below.
diff --git a/compiler/front_end/attribute_checker_test.py b/compiler/front_end/attribute_checker_test.py
index 11a5c18..e54d277 100644
--- a/compiler/front_end/attribute_checker_test.py
+++ b/compiler/front_end/attribute_checker_test.py
@@ -550,14 +550,14 @@
external_ir = _make_ir_from_emb("external Foo:\n"
" [addressable_unit_size: 1]\n")
self.assertEqual([], attribute_checker.normalize_and_verify(external_ir))
- self.assertEqual(ir_pb2.TypeDefinition.BIT,
+ self.assertEqual(ir_pb2.AddressableUnit.BIT,
external_ir.module[0].type[0].addressable_unit)
def test_adds_byte_addressable_unit_to_external(self):
external_ir = _make_ir_from_emb("external Foo:\n"
" [addressable_unit_size: 8]\n")
self.assertEqual([], attribute_checker.normalize_and_verify(external_ir))
- self.assertEqual(ir_pb2.TypeDefinition.BYTE,
+ self.assertEqual(ir_pb2.AddressableUnit.BYTE,
external_ir.module[0].type[0].addressable_unit)
def test_rejects_requires_using_array(self):
diff --git a/compiler/front_end/constraints.py b/compiler/front_end/constraints.py
index b43ca0e..107b55e 100644
--- a/compiler/front_end/constraints.py
+++ b/compiler/front_end/constraints.py
@@ -105,7 +105,7 @@
return
base_type_size = fixed_size
if base_type_size % type_definition.addressable_unit != 0:
- assert type_definition.addressable_unit == ir_pb2.TypeDefinition.BYTE
+ assert type_definition.addressable_unit == ir_pb2.AddressableUnit.BYTE
errors.append([error.error(source_file_name,
type_ir.base_type.source_location,
"Array elements in structs must have sizes "
@@ -352,9 +352,9 @@
type_ir.atomic_type.reference, ir)
if (type_definition.addressable_unit %
referenced_type_definition.addressable_unit != 0):
- assert type_definition.addressable_unit == ir_pb2.TypeDefinition.BIT
+ assert type_definition.addressable_unit == ir_pb2.AddressableUnit.BIT
assert (referenced_type_definition.addressable_unit ==
- ir_pb2.TypeDefinition.BYTE)
+ ir_pb2.AddressableUnit.BYTE)
errors.append([
error.error(source_file_name, type_ir.source_location,
"Byte-oriented {} cannot be used in a bits field.".format(
@@ -365,7 +365,7 @@
def _check_size_of_bits(type_ir, type_definition, source_file_name, errors):
"""Checks that `bits` types are fixed size, less than 64 bits."""
del type_ir # Unused
- if type_definition.addressable_unit != ir_pb2.TypeDefinition.BIT:
+ if type_definition.addressable_unit != ir_pb2.AddressableUnit.BIT:
return
fixed_size = ir_util.get_integer_attribute(
type_definition.attribute, attributes.FIXED_SIZE)
diff --git a/compiler/front_end/expression_bounds.py b/compiler/front_end/expression_bounds.py
index 5d37e1c..2f8d969 100644
--- a/compiler/front_end/expression_bounds.py
+++ b/compiler/front_end/expression_bounds.py
@@ -85,22 +85,22 @@
for arg in expression.function.args:
compute_constraints_of_expression(arg, ir)
op = expression.function.function
- if op in (ir_pb2.Function.ADDITION, ir_pb2.Function.SUBTRACTION):
+ if op in (ir_pb2.FunctionMapping.ADDITION, ir_pb2.FunctionMapping.SUBTRACTION):
_compute_constraints_of_additive_operator(expression)
- elif op == ir_pb2.Function.MULTIPLICATION:
+ elif op == ir_pb2.FunctionMapping.MULTIPLICATION:
_compute_constraints_of_multiplicative_operator(expression)
- elif op in (ir_pb2.Function.EQUALITY, ir_pb2.Function.INEQUALITY,
- ir_pb2.Function.LESS, ir_pb2.Function.LESS_OR_EQUAL,
- ir_pb2.Function.GREATER, ir_pb2.Function.GREATER_OR_EQUAL,
- ir_pb2.Function.AND, ir_pb2.Function.OR):
+ elif op in (ir_pb2.FunctionMapping.EQUALITY, ir_pb2.FunctionMapping.INEQUALITY,
+ ir_pb2.FunctionMapping.LESS, ir_pb2.FunctionMapping.LESS_OR_EQUAL,
+ ir_pb2.FunctionMapping.GREATER, ir_pb2.FunctionMapping.GREATER_OR_EQUAL,
+ ir_pb2.FunctionMapping.AND, ir_pb2.FunctionMapping.OR):
_compute_constant_value_of_comparison_operator(expression)
- elif op == ir_pb2.Function.CHOICE:
+ elif op == ir_pb2.FunctionMapping.CHOICE:
_compute_constraints_of_choice_operator(expression)
- elif op == ir_pb2.Function.MAXIMUM:
+ elif op == ir_pb2.FunctionMapping.MAXIMUM:
_compute_constraints_of_maximum_function(expression)
- elif op == ir_pb2.Function.PRESENCE:
+ elif op == ir_pb2.FunctionMapping.PRESENCE:
_compute_constraints_of_existence_function(expression, ir)
- elif op in (ir_pb2.Function.UPPER_BOUND, ir_pb2.Function.LOWER_BOUND):
+ elif op in (ir_pb2.FunctionMapping.UPPER_BOUND, ir_pb2.FunctionMapping.LOWER_BOUND):
_compute_constraints_of_bound_function(expression)
else:
assert False, "Unknown operator {!r}".format(op)
@@ -317,8 +317,8 @@
def _compute_constraints_of_additive_operator(expression):
"""Computes the modular value of an additive expression."""
funcs = {
- ir_pb2.Function.ADDITION: _add,
- ir_pb2.Function.SUBTRACTION: _sub,
+ ir_pb2.FunctionMapping.ADDITION: _add,
+ ir_pb2.FunctionMapping.SUBTRACTION: _sub,
}
func = funcs[expression.function.function]
args = expression.function.args
@@ -337,7 +337,7 @@
new_modulus)
lmax = left.type.integer.maximum_value
lmin = left.type.integer.minimum_value
- if expression.function.function == ir_pb2.Function.SUBTRACTION:
+ if expression.function.function == ir_pb2.FunctionMapping.SUBTRACTION:
rmax = right.type.integer.minimum_value
rmin = right.type.integer.maximum_value
else:
@@ -502,14 +502,14 @@
args = expression.function.args
if all(ir_util.is_constant(arg) for arg in args):
functions = {
- ir_pb2.Function.EQUALITY: operator.eq,
- ir_pb2.Function.INEQUALITY: operator.ne,
- ir_pb2.Function.LESS: operator.lt,
- ir_pb2.Function.LESS_OR_EQUAL: operator.le,
- ir_pb2.Function.GREATER: operator.gt,
- ir_pb2.Function.GREATER_OR_EQUAL: operator.ge,
- ir_pb2.Function.AND: operator.and_,
- ir_pb2.Function.OR: operator.or_,
+ ir_pb2.FunctionMapping.EQUALITY: operator.eq,
+ ir_pb2.FunctionMapping.INEQUALITY: operator.ne,
+ ir_pb2.FunctionMapping.LESS: operator.lt,
+ ir_pb2.FunctionMapping.LESS_OR_EQUAL: operator.le,
+ ir_pb2.FunctionMapping.GREATER: operator.gt,
+ ir_pb2.FunctionMapping.GREATER_OR_EQUAL: operator.ge,
+ ir_pb2.FunctionMapping.AND: operator.and_,
+ ir_pb2.FunctionMapping.OR: operator.or_,
}
func = functions[expression.function.function]
expression.type.boolean.value = func(
@@ -518,9 +518,9 @@
def _compute_constraints_of_bound_function(expression):
"""Computes the constraints of $upper_bound or $lower_bound."""
- if expression.function.function == ir_pb2.Function.UPPER_BOUND:
+ if expression.function.function == ir_pb2.FunctionMapping.UPPER_BOUND:
value = expression.function.args[0].type.integer.maximum_value
- elif expression.function.function == ir_pb2.Function.LOWER_BOUND:
+ elif expression.function.function == ir_pb2.FunctionMapping.LOWER_BOUND:
value = expression.function.args[0].type.integer.minimum_value
else:
assert False, "Non-bound function"
diff --git a/compiler/front_end/module_ir.py b/compiler/front_end/module_ir.py
index 94b7d8b..52db843 100644
--- a/compiler/front_end/module_ir.py
+++ b/compiler/front_end/module_ir.py
@@ -192,17 +192,17 @@
def _text_to_operator(text):
"""Converts an operator's textual name to its corresponding enum."""
operations = {
- '+': ir_pb2.Function.ADDITION,
- '-': ir_pb2.Function.SUBTRACTION,
- '*': ir_pb2.Function.MULTIPLICATION,
- '==': ir_pb2.Function.EQUALITY,
- '!=': ir_pb2.Function.INEQUALITY,
- '&&': ir_pb2.Function.AND,
- '||': ir_pb2.Function.OR,
- '>': ir_pb2.Function.GREATER,
- '>=': ir_pb2.Function.GREATER_OR_EQUAL,
- '<': ir_pb2.Function.LESS,
- '<=': ir_pb2.Function.LESS_OR_EQUAL,
+ '+': ir_pb2.FunctionMapping.ADDITION,
+ '-': ir_pb2.FunctionMapping.SUBTRACTION,
+ '*': ir_pb2.FunctionMapping.MULTIPLICATION,
+ '==': ir_pb2.FunctionMapping.EQUALITY,
+ '!=': ir_pb2.FunctionMapping.INEQUALITY,
+ '&&': ir_pb2.FunctionMapping.AND,
+ '||': ir_pb2.FunctionMapping.OR,
+ '>': ir_pb2.FunctionMapping.GREATER,
+ '>=': ir_pb2.FunctionMapping.GREATER_OR_EQUAL,
+ '<': ir_pb2.FunctionMapping.LESS,
+ '<=': ir_pb2.FunctionMapping.LESS_OR_EQUAL,
}
return operations[text]
@@ -210,10 +210,10 @@
def _text_to_function(text):
"""Converts a function's textual name to its corresponding enum."""
functions = {
- '$max': ir_pb2.Function.MAXIMUM,
- '$present': ir_pb2.Function.PRESENCE,
- '$upper_bound': ir_pb2.Function.UPPER_BOUND,
- '$lower_bound': ir_pb2.Function.LOWER_BOUND,
+ '$max': ir_pb2.FunctionMapping.MAXIMUM,
+ '$present': ir_pb2.FunctionMapping.PRESENCE,
+ '$upper_bound': ir_pb2.FunctionMapping.UPPER_BOUND,
+ '$lower_bound': ir_pb2.FunctionMapping.LOWER_BOUND,
}
return functions[text]
@@ -438,7 +438,7 @@
# The function_name is a bit weird, but should suffice for any error messages
# that might need it.
return ir_pb2.Expression(
- function=ir_pb2.Function(function=ir_pb2.Function.CHOICE,
+ function=ir_pb2.Function(function=ir_pb2.FunctionMapping.CHOICE,
args=[condition, if_true, if_false],
function_name=ir_pb2.Word(
text='?:',
@@ -580,7 +580,7 @@
e.source_location.start, comparison.source_location.end)
e = ir_pb2.Expression(
function=ir_pb2.Function(
- function=ir_pb2.Function.AND,
+ function=ir_pb2.FunctionMapping.AND,
args=[e, comparison],
function_name=ir_pb2.Word(
text='&&',
@@ -840,7 +840,7 @@
def _struct_body(indent, docs, attributes, types, fields, dedent):
del indent, dedent # Unused.
return _structure_body(docs, attributes, types, fields,
- ir_pb2.TypeDefinition.BYTE)
+ ir_pb2.AddressableUnit.BYTE)
def _structure_body(docs, attributes, types, fields, addressable_unit):
@@ -941,7 +941,7 @@
def _bits_body(indent, docs, attributes, types, fields, dedent):
del indent, dedent # Unused.
return _structure_body(docs, attributes, types, fields,
- ir_pb2.TypeDefinition.BIT)
+ ir_pb2.AddressableUnit.BIT)
# Inline bits (defined as part of a field) are more restricted than standalone
@@ -951,7 +951,7 @@
def _anonymous_bits_body(indent, attributes, fields, dedent):
del indent, dedent # Unused.
return _structure_body(_List([]), attributes, _List([]), fields,
- ir_pb2.TypeDefinition.BIT)
+ ir_pb2.AddressableUnit.BIT)
# A field is:
@@ -1131,7 +1131,7 @@
enumeration=ir_pb2.Enum(value=values.list),
documentation=docs.list,
attribute=attributes.list,
- addressable_unit=ir_pb2.TypeDefinition.BIT)
+ addressable_unit=ir_pb2.AddressableUnit.BIT)
# name = value
diff --git a/compiler/front_end/synthetics.py b/compiler/front_end/synthetics.py
index 7080527..8a6f856 100644
--- a/compiler/front_end/synthetics.py
+++ b/compiler/front_end/synthetics.py
@@ -156,8 +156,8 @@
def _add_size_bound_virtuals(structure, type_definition):
"""Adds ${min,max}_size_in_{bits,bytes} virtual fields to structure."""
names = {
- ir_pb2.TypeDefinition.BIT: ("$max_size_in_bits", "$min_size_in_bits"),
- ir_pb2.TypeDefinition.BYTE: ("$max_size_in_bytes", "$min_size_in_bytes"),
+ ir_pb2.AddressableUnit.BIT: ("$max_size_in_bits", "$min_size_in_bits"),
+ ir_pb2.AddressableUnit.BYTE: ("$max_size_in_bytes", "$min_size_in_bytes"),
}
for name in names[type_definition.addressable_unit]:
bound_field = ir_pb2.Field(
@@ -184,8 +184,8 @@
def _add_size_virtuals(structure, type_definition):
"""Adds a $size_in_bits or $size_in_bytes virtual field to structure."""
names = {
- ir_pb2.TypeDefinition.BIT: "$size_in_bits",
- ir_pb2.TypeDefinition.BYTE: "$size_in_bytes",
+ ir_pb2.AddressableUnit.BIT: "$size_in_bits",
+ ir_pb2.AddressableUnit.BYTE: "$size_in_bytes",
}
size_field_name = names[type_definition.addressable_unit]
size_clauses = []
diff --git a/compiler/front_end/synthetics_test.py b/compiler/front_end/synthetics_test.py
index ceafa11..bae2759 100644
--- a/compiler/front_end/synthetics_test.py
+++ b/compiler/front_end/synthetics_test.py
@@ -88,12 +88,12 @@
alias_field.existence_condition.function.args[1].function.
args[0].field_reference.path[1].source_name[-1].text)
self.assertEqual(
- ir_pb2.Function.PRESENCE,
+ ir_pb2.FunctionMapping.PRESENCE,
alias_field.existence_condition.function.args[0].function.function)
self.assertEqual(
- ir_pb2.Function.PRESENCE,
+ ir_pb2.FunctionMapping.PRESENCE,
alias_field.existence_condition.function.args[1].function.function)
- self.assertEqual(ir_pb2.Function.AND,
+ self.assertEqual(ir_pb2.FunctionMapping.AND,
alias_field.existence_condition.function.function)
def test_adds_correct_read_transform(self):
@@ -177,15 +177,15 @@
max_size_in_bytes_field = structure.field[3]
min_size_in_bytes_field = structure.field[4]
self.assertEqual("$size_in_bytes", size_in_bytes_field.name.name.text)
- self.assertEqual(ir_pb2.Function.MAXIMUM,
+ self.assertEqual(ir_pb2.FunctionMapping.MAXIMUM,
size_in_bytes_field.read_transform.function.function)
self.assertEqual("$max_size_in_bytes",
max_size_in_bytes_field.name.name.text)
- self.assertEqual(ir_pb2.Function.UPPER_BOUND,
+ self.assertEqual(ir_pb2.FunctionMapping.UPPER_BOUND,
max_size_in_bytes_field.read_transform.function.function)
self.assertEqual("$min_size_in_bytes",
min_size_in_bytes_field.name.name.text)
- self.assertEqual(ir_pb2.Function.LOWER_BOUND,
+ self.assertEqual(ir_pb2.FunctionMapping.LOWER_BOUND,
min_size_in_bytes_field.read_transform.function.function)
# The correctness of $size_in_bytes et al are tested much further down
# stream, in tests of the generated C++ code.
@@ -200,15 +200,15 @@
max_size_in_bits_field = structure.field[3]
min_size_in_bits_field = structure.field[4]
self.assertEqual("$size_in_bits", size_in_bits_field.name.name.text)
- self.assertEqual(ir_pb2.Function.MAXIMUM,
+ self.assertEqual(ir_pb2.FunctionMapping.MAXIMUM,
size_in_bits_field.read_transform.function.function)
self.assertEqual("$max_size_in_bits",
max_size_in_bits_field.name.name.text)
- self.assertEqual(ir_pb2.Function.UPPER_BOUND,
+ self.assertEqual(ir_pb2.FunctionMapping.UPPER_BOUND,
max_size_in_bits_field.read_transform.function.function)
self.assertEqual("$min_size_in_bits",
min_size_in_bits_field.name.name.text)
- self.assertEqual(ir_pb2.Function.LOWER_BOUND,
+ self.assertEqual(ir_pb2.FunctionMapping.LOWER_BOUND,
min_size_in_bits_field.read_transform.function.function)
# The correctness of $size_in_bits et al are tested much further down
# stream, in tests of the generated C++ code.
@@ -232,7 +232,7 @@
self.assertEqual([], synthetics.desugar(ir))
offset_of_b = ir.module[0].type[0].structure.field[1].location.start
self.assertTrue(offset_of_b.HasField("function"))
- self.assertEqual(offset_of_b.function.function, ir_pb2.Function.ADDITION)
+ self.assertEqual(offset_of_b.function.function, ir_pb2.FunctionMapping.ADDITION)
self.assertEqual(offset_of_b.function.args[0].constant.value, "1")
self.assertEqual(offset_of_b.function.args[1].constant.value, "2")
offset_of_c = ir.module[0].type[0].structure.field[2].location.start
diff --git a/compiler/front_end/type_check.py b/compiler/front_end/type_check.py
index edc9d93..c15aaad 100644
--- a/compiler/front_end/type_check.py
+++ b/compiler/front_end/type_check.py
@@ -111,11 +111,11 @@
for arg in expression.function.args:
_type_check_expression(arg, source_file_name, ir, errors)
function = expression.function.function
- if function in (ir_pb2.Function.EQUALITY, ir_pb2.Function.INEQUALITY,
- ir_pb2.Function.LESS, ir_pb2.Function.LESS_OR_EQUAL,
- ir_pb2.Function.GREATER, ir_pb2.Function.GREATER_OR_EQUAL):
+ if function in (ir_pb2.FunctionMapping.EQUALITY, ir_pb2.FunctionMapping.INEQUALITY,
+ ir_pb2.FunctionMapping.LESS, ir_pb2.FunctionMapping.LESS_OR_EQUAL,
+ ir_pb2.FunctionMapping.GREATER, ir_pb2.FunctionMapping.GREATER_OR_EQUAL):
_type_check_comparison_operator(expression, source_file_name, errors)
- elif function == ir_pb2.Function.CHOICE:
+ elif function == ir_pb2.FunctionMapping.CHOICE:
_type_check_choice_operator(expression, source_file_name, errors)
else:
_type_check_monomorphic_operator(expression, source_file_name, errors)
@@ -132,21 +132,21 @@
binary = ("Left argument", "Right argument")
n_ary = ("Argument {}".format(n) for n in range(len(args)))
functions = {
- ir_pb2.Function.ADDITION: (int_result, int_args, binary, 2, 2,
+ ir_pb2.FunctionMapping.ADDITION: (int_result, int_args, binary, 2, 2,
"operator"),
- ir_pb2.Function.SUBTRACTION: (int_result, int_args, binary, 2, 2,
+ ir_pb2.FunctionMapping.SUBTRACTION: (int_result, int_args, binary, 2, 2,
"operator"),
- ir_pb2.Function.MULTIPLICATION: (int_result, int_args, binary, 2, 2,
+ ir_pb2.FunctionMapping.MULTIPLICATION: (int_result, int_args, binary, 2, 2,
"operator"),
- ir_pb2.Function.AND: (bool_result, bool_args, binary, 2, 2, "operator"),
- ir_pb2.Function.OR: (bool_result, bool_args, binary, 2, 2, "operator"),
- ir_pb2.Function.MAXIMUM: (int_result, int_args, n_ary, 1, None,
+ ir_pb2.FunctionMapping.AND: (bool_result, bool_args, binary, 2, 2, "operator"),
+ ir_pb2.FunctionMapping.OR: (bool_result, bool_args, binary, 2, 2, "operator"),
+ ir_pb2.FunctionMapping.MAXIMUM: (int_result, int_args, n_ary, 1, None,
"function"),
- ir_pb2.Function.PRESENCE: (bool_result, field_args, n_ary, 1, 1,
+ ir_pb2.FunctionMapping.PRESENCE: (bool_result, field_args, n_ary, 1, 1,
"function"),
- ir_pb2.Function.UPPER_BOUND: (int_result, int_args, n_ary, 1, 1,
+ ir_pb2.FunctionMapping.UPPER_BOUND: (int_result, int_args, n_ary, 1, 1,
"function"),
- ir_pb2.Function.LOWER_BOUND: (int_result, int_args, n_ary, 1, 1,
+ ir_pb2.FunctionMapping.LOWER_BOUND: (int_result, int_args, n_ary, 1, 1,
"function"),
}
function = expression.function.function
@@ -267,8 +267,8 @@
"""Checks the type of a comparison operator (==, !=, <, >, >=, <=)."""
# Applying less than or greater than to a boolean is likely a mistake, so
# only equality and inequality are allowed for booleans.
- if expression.function.function in (ir_pb2.Function.EQUALITY,
- ir_pb2.Function.INEQUALITY):
+ if expression.function.function in (ir_pb2.FunctionMapping.EQUALITY,
+ ir_pb2.FunctionMapping.INEQUALITY):
acceptable_types = ("integer", "boolean", "enumeration")
acceptable_types_for_humans = "an integer, boolean, or enum"
else:
diff --git a/compiler/front_end/write_inference.py b/compiler/front_end/write_inference.py
index 09501f0..bb5b1f4 100644
--- a/compiler/front_end/write_inference.py
+++ b/compiler/front_end/write_inference.py
@@ -151,10 +151,10 @@
# Note that any equation that can be solved here becomes part of Emboss's
# contract, forever, so be conservative in expanding its solving capabilities!
for index in reference_path:
- if subexpression.function.function == ir_pb2.Function.ADDITION:
+ if subexpression.function.function == ir_pb2.FunctionMapping.ADDITION:
result = ir_pb2.Expression(
function=ir_pb2.Function(
- function=ir_pb2.Function.SUBTRACTION,
+ function=ir_pb2.FunctionMapping.SUBTRACTION,
args=[
result,
subexpression.function.args[1 - index],
@@ -162,11 +162,11 @@
),
type=ir_pb2.ExpressionType(integer=ir_pb2.IntegerType())
)
- elif subexpression.function.function == ir_pb2.Function.SUBTRACTION:
+ elif subexpression.function.function == ir_pb2.FunctionMapping.SUBTRACTION:
if index == 0:
result = ir_pb2.Expression(
function=ir_pb2.Function(
- function=ir_pb2.Function.ADDITION,
+ function=ir_pb2.FunctionMapping.ADDITION,
args=[
result,
subexpression.function.args[1],
@@ -177,7 +177,7 @@
else:
result = ir_pb2.Expression(
function=ir_pb2.Function(
- function=ir_pb2.Function.SUBTRACTION,
+ function=ir_pb2.FunctionMapping.SUBTRACTION,
args=[
subexpression.function.args[0],
result,
diff --git a/compiler/front_end/write_inference_test.py b/compiler/front_end/write_inference_test.py
index 52e8c26..9915196 100644
--- a/compiler/front_end/write_inference_test.py
+++ b/compiler/front_end/write_inference_test.py
@@ -101,7 +101,7 @@
self.assertEqual(
"x",
transform.destination.path[0].canonical_name.object_path[-1])
- self.assertEqual(ir_pb2.Function.SUBTRACTION,
+ self.assertEqual(ir_pb2.FunctionMapping.SUBTRACTION,
transform.function_body.function.function)
arg0, arg1 = transform.function_body.function.args
self.assertEqual("$logical_value",
@@ -119,7 +119,7 @@
self.assertEqual(
"x",
transform.destination.path[0].canonical_name.object_path[-1])
- self.assertEqual(ir_pb2.Function.ADDITION,
+ self.assertEqual(ir_pb2.FunctionMapping.ADDITION,
transform.function_body.function.function)
arg0, arg1 = transform.function_body.function.args
self.assertEqual("$logical_value",
@@ -137,7 +137,7 @@
self.assertEqual(
"x",
transform.destination.path[0].canonical_name.object_path[-1])
- self.assertEqual(ir_pb2.Function.SUBTRACTION,
+ self.assertEqual(ir_pb2.FunctionMapping.SUBTRACTION,
transform.function_body.function.function)
arg0, arg1 = transform.function_body.function.args
self.assertEqual("$logical_value",
@@ -156,7 +156,7 @@
self.assertEqual(
"x",
transform.destination.path[0].canonical_name.object_path[-1])
- self.assertEqual(ir_pb2.Function.SUBTRACTION,
+ self.assertEqual(ir_pb2.FunctionMapping.SUBTRACTION,
transform.function_body.function.function)
arg0, arg1 = transform.function_body.function.args
self.assertEqual("50", arg0.constant.value)
@@ -174,11 +174,11 @@
self.assertEqual(
"x",
transform.destination.path[0].canonical_name.object_path[-1])
- self.assertEqual(ir_pb2.Function.SUBTRACTION,
+ self.assertEqual(ir_pb2.FunctionMapping.SUBTRACTION,
transform.function_body.function.function)
arg0, arg1 = transform.function_body.function.args
self.assertEqual("50", arg0.constant.value)
- self.assertEqual(ir_pb2.Function.SUBTRACTION, arg1.function.function)
+ self.assertEqual(ir_pb2.FunctionMapping.SUBTRACTION, arg1.function.function)
arg10, arg11 = arg1.function.args
self.assertEqual("$logical_value",
arg10.builtin_reference.canonical_name.object_path[0])
@@ -204,7 +204,7 @@
self.assertEqual(
"x",
transform.destination.path[0].canonical_name.object_path[-1])
- self.assertEqual(ir_pb2.Function.ADDITION,
+ self.assertEqual(ir_pb2.FunctionMapping.ADDITION,
transform.function_body.function.function)
args = transform.function_body.function.args
self.assertEqual("$logical_value",
diff --git a/compiler/util/attribute_util.py b/compiler/util/attribute_util.py
index d864364..8c4e2b7 100644
--- a/compiler/util/attribute_util.py
+++ b/compiler/util/attribute_util.py
@@ -167,12 +167,12 @@
def check_type_definition(type_definition, source_file_name, errors):
if type_definition.HasField("structure"):
- if type_definition.addressable_unit == ir_pb2.TypeDefinition.BYTE:
+ if type_definition.addressable_unit == ir_pb2.AddressableUnit.BYTE:
errors.extend(_check_attributes(
type_definition.attribute, types, back_end, struct_attributes,
"struct '{}'".format(
type_definition.name.name.text), source_file_name))
- elif type_definition.addressable_unit == ir_pb2.TypeDefinition.BIT:
+ elif type_definition.addressable_unit == ir_pb2.AddressableUnit.BIT:
errors.extend(_check_attributes(
type_definition.attribute, types, back_end, bits_attributes,
"bits '{}'".format(
diff --git a/compiler/util/ir_pb2.py b/compiler/util/ir_pb2.py
index d1b5dd3..6ee0b47 100644
--- a/compiler/util/ir_pb2.py
+++ b/compiler/util/ir_pb2.py
@@ -29,6 +29,7 @@
everything that touches the IR (i.e., the entire compiler).
"""
+import enum
import json
import sys
@@ -107,9 +108,12 @@
self._set_value(obj, self._type(**value))
elif isinstance(value, _Text) and self._decode_names:
self._set_value(obj, self._type(self._decode_names(value)))
+ elif isinstance(value, _Text) and issubclass(self._type, enum.Enum):
+ self._set_value(obj, getattr(self._type, value))
elif (not isinstance(value, self._type) and
not (self._type == _Int and isinstance(value, _int_types)) and
- not (self._type == _Text and isinstance(value, _text_types))):
+ not (self._type == _Text and isinstance(value, _text_types)) and
+ not (issubclass(self._type, enum.Enum) and isinstance(value, _int_types))):
raise AttributeError("Cannot set {} (type {}) for type {}".format(
value, value.__class__, self._type))
elif issubclass(self._type, Message):
@@ -427,9 +431,8 @@
source_location = Optional(Location)
-@message
-class Function(Message):
- """IR for a single function (+, -, *, ==, $max, etc.) in an expression."""
+class FunctionMapping(int, enum.Enum):
+ """Enum of supported function types"""
UNKNOWN = 0
ADDITION = 1 # +
SUBTRACTION = 2 # -
@@ -448,8 +451,13 @@
UPPER_BOUND = 15 # $upper_bound()
LOWER_BOUND = 16 # $lower_bound()
+
+@message
+class Function(Message):
+ """IR for a single function (+, -, *, ==, $max, etc.) in an expression."""
+
# pylint:disable=undefined-variable
- function = Optional(int, decode_names=lambda x: getattr(Function, x))
+ function = Optional(FunctionMapping)
args = Repeated(lambda: Expression)
function_name = Optional(Word)
source_location = Optional(Location)
@@ -952,19 +960,22 @@
source_location = Optional(Location)
-@message
-class TypeDefinition(Message):
- """Container IR for a type definition (struct, union, etc.)"""
-
- # The "addressable unit" is the size of the smallest unit that can be read
- # from the backing store that this type expects. For `struct`s, this is
- # BYTE; for `enum`s and `bits`, this is BIT, and for `external`s it depends
- # on the specific type.
+class AddressableUnit(int, enum.Enum):
+ """The "addressable unit" is the size of the smallest unit that can be read
+ from the backing store that this type expects. For `struct`s, this is
+ BYTE; for `enum`s and `bits`, this is BIT, and for `external`s it depends
+ on the specific type
+ """
NONE = 0
BIT = 1
BYTE = 8
+
+@message
+class TypeDefinition(Message):
+ """Container IR for a type definition (struct, union, etc.)"""
+
external = Optional(External, "type")
enumeration = Optional(Enum, "type")
structure = Optional(Structure, "type")
@@ -974,8 +985,7 @@
documentation = Repeated(Documentation) # Docs for the type.
# pylint:disable=undefined-variable
subtype = Repeated(lambda: TypeDefinition) # Subtypes of this type.
- addressable_unit = Optional(
- int, decode_names=lambda x: getattr(TypeDefinition, x))
+ addressable_unit = Optional(AddressableUnit)
# If the type requires parameters at runtime, these are its parameters.
# These are currently only allowed on structures, but in the future they
diff --git a/compiler/util/ir_util.py b/compiler/util/ir_util.py
index 4000e70..15a2def 100644
--- a/compiler/util/ir_util.py
+++ b/compiler/util/ir_util.py
@@ -150,21 +150,23 @@
# constant expression patterns built from non-constant subexpressions, such as
# `0 * X` or `X == X` or `3 * X == X + X + X`. I (bolms@) am not implementing
# any further special cases because I do not see any practical use for them.
- if function.function == ir_pb2.Function.AND:
+ if function.function == ir_pb2.FunctionMapping.UNKNOWN:
+ return None
+ if function.function == ir_pb2.FunctionMapping.AND:
if any(value is False for value in values):
return False
elif any(value is None for value in values):
return None
else:
return True
- elif function.function == ir_pb2.Function.OR:
+ elif function.function == ir_pb2.FunctionMapping.OR:
if any(value is True for value in values):
return True
elif any(value is None for value in values):
return None
else:
return False
- elif function.function == ir_pb2.Function.CHOICE:
+ elif function.function == ir_pb2.FunctionMapping.CHOICE:
if values[0] is None:
return None
else:
@@ -174,18 +176,18 @@
if any(value is None for value in values):
return None
functions = {
- ir_pb2.Function.ADDITION: operator.add,
- ir_pb2.Function.SUBTRACTION: operator.sub,
- ir_pb2.Function.MULTIPLICATION: operator.mul,
- ir_pb2.Function.EQUALITY: operator.eq,
- ir_pb2.Function.INEQUALITY: operator.ne,
- ir_pb2.Function.LESS: operator.lt,
- ir_pb2.Function.LESS_OR_EQUAL: operator.le,
- ir_pb2.Function.GREATER: operator.gt,
- ir_pb2.Function.GREATER_OR_EQUAL: operator.ge,
+ ir_pb2.FunctionMapping.ADDITION: operator.add,
+ ir_pb2.FunctionMapping.SUBTRACTION: operator.sub,
+ ir_pb2.FunctionMapping.MULTIPLICATION: operator.mul,
+ ir_pb2.FunctionMapping.EQUALITY: operator.eq,
+ ir_pb2.FunctionMapping.INEQUALITY: operator.ne,
+ ir_pb2.FunctionMapping.LESS: operator.lt,
+ ir_pb2.FunctionMapping.LESS_OR_EQUAL: operator.le,
+ ir_pb2.FunctionMapping.GREATER: operator.gt,
+ ir_pb2.FunctionMapping.GREATER_OR_EQUAL: operator.ge,
# Python's max([1, 2]) == 2; max(1, 2) == 2; max([1]) == 1; but max(1)
# throws a TypeError ("'int' object is not iterable").
- ir_pb2.Function.MAXIMUM: lambda *x: max(x),
+ ir_pb2.FunctionMapping.MAXIMUM: lambda *x: max(x),
}
return functions[function.function](*values)
diff --git a/compiler/util/ir_util_test.py b/compiler/util/ir_util_test.py
index 44a8063..7743c10 100644
--- a/compiler/util/ir_util_test.py
+++ b/compiler/util/ir_util_test.py
@@ -351,7 +351,7 @@
value=ir_pb2.AttributeValue(
expression=ir_pb2.Expression(
function=ir_pb2.Function(
- function=ir_pb2.Function.ADDITION,
+ function=ir_pb2.FunctionMapping.ADDITION,
args=[
ir_pb2.Expression(
constant=ir_pb2.NumericConstant(value="100"),