[Xcb] [PATCH libxcb 5/9 V3] generator: sumof with nested expression

Christian Linhart chris at DemoRecorder.com
Sun Nov 2 04:46:16 PST 2014


Support sumof with a nested expression.
The nested expression is computed for every list-element
and the result of the computation is added to the sum.

This way, sumof can be applied to a list of structs,
and, e.g., compute the sum of a specific field of that struct.

example:
<struct name="SumofTest_Element">
   <field type="CARD16" name="foo" />
   <field type="CARD16" name="bar" />
</struct>

<struct name="SumofTest_FieldAccess">
   <field type="CARD32" name="len" />
   <list type="SumofTest_Element" name="mylist1">
	   <fieldref>len</fieldref>
   </list>
   <list type="CARD16" name="mylist2">
	<sumof ref="mylist1">
		<fieldref>bar</fieldref>
	</sumof>
   </list>
</struct>

generated tmpvar:
    int xcb_pre_tmp_1; /* sumof length */
    int xcb_pre_tmp_2; /* sumof loop counter */
    int64_t xcb_pre_tmp_3; /* sumof sum */
    const xcb_input_sumof_test_element_t* xcb_pre_tmp_4; /* sumof list ptr */

generated code:
    /* mylist2 */
    /* sumof start */
    xcb_pre_tmp_1 = _aux->len;
    xcb_pre_tmp_3 = 0;
    xcb_pre_tmp_4 = xcb_input_sumof_test_field_access_mylist_1(_aux);
    for ( xcb_pre_tmp_2 = 0; xcb_pre_tmp_2 < xcb_pre_tmp_1; xcb_pre_tmp_2++) {
        xcb_pre_tmp_3 += xcb_pre_tmp_4->bar;
        xcb_pre_tmp_4++;
    }
    /* sumof end. Result is in xcb_pre_tmp_3 */
    xcb_block_len += xcb_pre_tmp_3 * sizeof(uint16_t);


changes for V2 of this patch:
* explicitely set the member access operator in the prefix-tuple
  passed to function _c_helper_field_mapping.
  This enables us to simplify function "_c_helper_absolute_name"
  (which will be renamed "_c_helper_fieldaccess_expr" soon)

V3: Changed style and formatting according to suggestions from Ran Benita

Signed-off-by: Christian Linhart <chris at DemoRecorder.com>
Reviewed-by: Ran Benita <ran234 at gmail.com>

---
 src/c_client.py | 26 +++++++++++++++++++++++++-
 1 file changed, 25 insertions(+), 1 deletion(-)

diff --git a/src/c_client.py b/src/c_client.py
index 6b694d5..6169175 100644
--- a/src/c_client.py
+++ b/src/c_client.py
@@ -1644,13 +1644,36 @@ def _c_accessor_get_expr(expr, field_mapping):
         _c_pre.code("%s = %s;", lengthvar, c_length_func)
         _c_pre.code("%s = 0;", sumvar)
         _c_pre.code("%s = %s;", listvar, list_name)
         _c_pre.code("for (%s = 0; %s < %s; %s++) {", loopvar, loopvar, lengthvar, loopvar)
         _c_pre.indent()
-        _c_pre.code("%s += *%s;", sumvar, listvar)
+
+        if expr.rhs is None:
+            _c_pre.code("%s += *%s;", sumvar, listvar)
+        else:
+            # sumof has a nested expression which has to be evaluated in
+            # the context of this list element
+
+            # field mapping for the subexpression needs to include
+            # the fields of the list-member type
+            scoped_field_mapping = field_mapping.copy()
+            scoped_field_mapping.update(
+                _c_helper_field_mapping(
+                    field.type.member,
+                    [(listvar, '->', field.type.member)]))
+
+            # cause pre-code of the subexpression be added right here
+            _c_pre.end()
+            # compute the subexpression
+            rhs_expr_str = _c_accessor_get_expr(expr.rhs, scoped_field_mapping)
+            # resume with our code
+            _c_pre.start()
+            # output the summation expression
+            _c_pre.code("%s += %s;", sumvar, rhs_expr_str)
+
         _c_pre.code("%s++;", listvar)
         _c_pre.pop_indent()
         _c_pre.code("}")
         _c_pre.code("/* sumof end. Result is in %s */", sumvar)
         _c_pre.end()
         return sumvar
     elif expr.op != None:
-- 
2.0.1



More information about the Xcb mailing list