[Xcb] [PATCH libxcb 5/6 V2] generator: sumof with nested expression
Christian Linhart
chris at DemoRecorder.com
Thu Oct 30 07:12:41 PDT 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)
---
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
@@ -4,14 +4,15 @@ from os.path import basename
from functools import reduce
import getopt
import os
import sys
import errno
import time
import re
+import copy
# Jump to the bottom of this file for the main routine
# Some hacks to make the API more readable, and to keep backwards compability
_cname_re = re.compile('([A-Z0-9][a-z]+|[A-Z0-9]+(?![a-z])|[a-z]+)')
_cname_special_cases = {'DECnet':'decnet'}
@@ -1629,15 +1630,38 @@ 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 == 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;
#return 'xcb_sumof(%s, %s)' % (list_name, c_length_func)
-- 2.0.1 _______________________________________________ Xcb mailing list Xcb at lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/xcb
More information about the Xcb
mailing list