Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions compiler/back_end/cpp/header_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -657,6 +657,10 @@ def _render_builtin_operation(expression, ir, field_reader, subexpressions):
return field_reader.render_existence(
expression.function.args[0], subexpressions
)
if expression.function.function == ir_data.FunctionMapping.CRC:
return field_reader.render_crc(
expression.function.args[0], subexpressions
)
args = expression.function.args
rendered_args = [
_render_expression(arg, ir, field_reader, subexpressions).rendered
Expand Down Expand Up @@ -745,6 +749,22 @@ def render_existence_with_context(self, expression, prefix, subexpressions):
prefix,
)

def render_crc_with_context(self, expression, prefix, subexpressions):
field = prefix + _render_variable(
ir_util.hashable_form_of_field_reference(expression.field_reference)
)
if subexpressions is None:
field_expression = field
else:
field_expression = subexpressions.add(field)
return (
"({0}.Ok()"
" ? {1}(::emboss::support::Crc32({0}))"
" : {1}())".format(
field_expression, _maybe_type("::std::uint32_t")
)
)


class _DirectFieldRenderer(_FieldRenderer):
"""Renderer for fields read from inside a structure's View type."""
Expand All @@ -755,6 +775,9 @@ def render_field(self, expression, ir, subexpressions):
def render_existence(self, expression, subexpressions):
return self.render_existence_with_context(expression, "", subexpressions)

def render_crc(self, expression, subexpressions):
return self.render_crc_with_context(expression, "", subexpressions)


class _VirtualViewFieldRenderer(_FieldRenderer):
"""Renderer for field reads from inside a virtual field's View."""
Expand All @@ -767,6 +790,9 @@ def render_field(self, expression, ir, subexpressions):
expression, ir, "view_.", subexpressions
)

def render_crc(self, expression, subexpressions):
return self.render_crc_with_context(expression, "view_.", subexpressions)


class _SubexpressionStore(object):
"""Holder for subexpressions to be assigned to local variables."""
Expand Down
14 changes: 14 additions & 0 deletions compiler/front_end/expression_bounds.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ def _compute_constraints_of_function(expression, ir):
ir_data.FunctionMapping.LOWER_BOUND,
):
_compute_constraints_of_bound_function(expression)
elif op == ir_data.FunctionMapping.CRC:
_compute_constraints_of_crc_function(expression)
else:
assert False, "Unknown operator {!r}".format(op)

Expand All @@ -127,6 +129,18 @@ def _compute_constraints_of_existence_function(expression, ir):
ir_data_utils.builder(expression).type.CopyFrom(field.existence_condition.type)


def _compute_constraints_of_crc_function(expression):
"""Computes the constraints of a $crc32(field) expression.

CRC32 returns a 32-bit unsigned integer, so the result is in range [0, 2^32-1].
"""
# CRC32 returns an unsigned 32-bit integer
expression.type.integer.modulus = "1"
expression.type.integer.modular_value = "0"
expression.type.integer.minimum_value = "0"
expression.type.integer.maximum_value = str(2**32 - 1)


def _compute_constraints_of_field_reference(expression, ir):
"""Computes the constraints of a reference to a structure's field."""
field_path = expression.field_reference.path[-1]
Expand Down
1 change: 1 addition & 0 deletions compiler/front_end/format_emb.py
Original file line number Diff line number Diff line change
Expand Up @@ -858,6 +858,7 @@ def _empty_string():
@_formats("equality-or-less-expression-right -> less-expression-right")
@_formats("expression -> choice-expression")
@_formats("field-body? -> field-body")
@_formats('function-name -> "$crc32"')
@_formats('function-name -> "$lower_bound"')
@_formats('function-name -> "$present"')
@_formats('function-name -> "$max"')
Expand Down
Empty file.
Loading