Boost logo

Boost :

From: Maurizio Vitale (maurizio.vitale_at_[hidden])
Date: 2007-05-19 08:58:53


On May 19, 2007, at 12:02 AM, Gottlob Frege wrote:

> On 5/8/07, Maurizio Vitale <mav_at_cuma.polymath-solutions.lan> wrote:
>>
>> Suppose I needed a new tag for representing some high-level
>> concept that I do not want
>> to express in terms of C++ operators [it could be a get_bit(N)
>> operation that has very
>> different implementation when for my numbers the unserlyining
>> implementation is a
>> builtin type or a GMP big int]
>>
>> Here's my code for adding a binary operator my_plus:
>>
>
> For us new to proto, can you give an example of your DSEL in use where
> my_plus is used?
>
> ie is it:
>
> int a;
> int b;
>
> int c = ...my_plus....
>
> what's it look like in use?
>

Suppose you have objects that derives from proto::terminal, like
my_int in my previous posts.
Given the declarations:

        my_int<4> i=2;
        my_int<8> j=40;

You want to be able to write something like:
        i = my_plus(i,j);

Granted, you'd probably wouldn't do this for my_plus, as you have an
operator+ that looks nicer.
What I need the ability of defining new "functions" for is for things
like
sign(expr) - returns the sign of an expression
mask(expr, left, right) - return EXPR with bits outside the range
left..right zeroed.
etc.

The reason I want to represent those "high" [higher than C++
operations] concepts is that their implementation
is potentially very different. For instance extracting the sign from
a builtin type is not the same as extracting the sign from a fixed-
point number
and it is certainly not the same as extracting it from a GNU multi-
precision numbers.
Note that not necessarily a comparison w/ zero would do the right
thing: for instance in fixed point numbers
I might decide not to sign-extend after all operations
(which has a cost) and thus you have to fin the right inner bit that
gives you the sign.

In my application (a library of fixed-point numbers) I'll have two
levels where proto is used. A "concrete" level
that control the user-level expressions in the way one would expect
(similar to code I posted previously, like the example
that allows you to make all combinations containing signed numbers to
go to signed).

And then I have a meta-level where you can talk about expressions in
the concrete domain. For instance if
        proto::eval( i+j, concrete_context) gives you 42
I want:
        proto::eval(value(_2), meta_context(j, i+j)) [here
value() would be implemented as my_plus above]
to also yield 42, but:
        proto::eval(value(_2), meta_context(i, i+j))
would yield 10 [with a C-like overload management, other values are
also possible from my library].
The reason is that the value of value(EXPR) in the meta_context is
the value of EXPR given that it must be assigned to expression _1,
which in the
first case is j, an 8-bit quantity and in the second case is i, a 4-
bit quantity.
In the process of evaluating value(_2) another meta-expression will
be evaluated:
        mask(value(_2), left(_1)-left(_2))
which does the masking when needed.
The goal is to have the equivalent of the following in the assembly
code:
        R1 <- i
        R2 <- j
        R1 <- R1 + R2
        R1 <- R1 & 0xf
        i <- R1
for the first case and to skip the masking all together for the
second case.

It would take longer to go into the details of the fixed-point
application, but I hope the above gives you an idea of why I needed
something like 'my_plus'.

It takes some time and effort to understand how proto works, but if
you have an application that fits it is time well spent.

Regards,

                Maurizio


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk