[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