
On May 19, 2007, at 12:02 AM, Gottlob Frege wrote:
On 5/8/07, Maurizio Vitale <mav@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