[Xcb] [PATCH libxcb 5/6] generator: sumof with nested expression
Ran Benita
ran234 at gmail.com
Sat Nov 1 03:50:14 PDT 2014
On Wed, Sep 03, 2014 at 01:22:40PM +0200, Christian Linhart wrote:
> 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);
> ---
> 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
No need for this (dict.copy() works without it).
>
> # 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:
`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
Linebreaking a bit funny. Maybe
# 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