unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
* C++ wrap
@ 2010-02-22 14:01 Hans Aberg
  2010-02-22 19:06 ` Andy Wingo
  0 siblings, 1 reply; 3+ messages in thread
From: Hans Aberg @ 2010-02-22 14:01 UTC (permalink / raw)
  To: guile-user

I have written a bit on a C++ wrap - has this been done? I use  
templates to get a static typed style similar to that of Haskell,  
which can be overridden at need. Some example code below.

   Hans


----
#include "src/guile.hh"

#include <iostream>
#include <list>
#include <utility>


int inner_main(std::pair<int, char**>* argp) {
   for (int i = 0; i < argp->first; ++i)
     std::cout << argp->second[i] << std::endl;

   using namespace scm;

   integer x = 2567575364397498ull;
   integer y = (uint64_t)2567575364397500ull;

   out << "-x = " << -x << "\ny = " << y << newline;

   // Checking object references and mutative operations:
   object w = x;
   ++x;
   out << "w = " << w << newline;
   out << "x = " << x << newline;

   function2<integer, integer, integer> f("-");
   // Using C++ output:
   std::cout << "f(x, y) = " << (char*)string(f(x, y), 10) << std::endl;

   // Loading a module, and using a function in it:

   object("(use-modules (ice-9 pretty-print))");
   function<> pretty("pretty-print");

   const char* text =
   "'(define (foo) (lambda (x) \
   (cond ((zero? x) #t) ((negative? x) -x) (else \
   (if (= x 1) 2 (* x x x))))))";

   out << "Function:\n";
   pretty(object(text));

   list<> ks(std::list<integer>(5, 6));
   out << "std::list<integer>(5, 6) = " << ks << newline << flush;

   function1<number, number> inc("(lambda (x) (+ x 1))");
   out << "inc(integer(3)) = " << inc(integer(3)) << newline;

   return EXIT_SUCCESS;
}


int main(int argc, char **argv) {
   std::pair<int, char**> arg(argc, argv);
   return scm::with_guile<std::pair<int, char**>*, int>(inner_main) 
(&arg);
}
----
$ g++ test.cc -lguile -o test && ./test
./test

-x = -2567575364397498
y = 2567575364397500
f(x, y) = -2
Function:
(define (foo)
   (lambda (x)
     (cond ((zero? x) #t)
           ((negative? x) -x)
           (else (if (= x 1) 2 (* x x x))))))
std::list<integer>(5, 6) = (6 6 6 6 6)
inc(integer(3)) = 4
----





^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: C++ wrap
  2010-02-22 14:01 C++ wrap Hans Aberg
@ 2010-02-22 19:06 ` Andy Wingo
  2010-02-23 14:10   ` Hans Aberg
  0 siblings, 1 reply; 3+ messages in thread
From: Andy Wingo @ 2010-02-22 19:06 UTC (permalink / raw)
  To: Hans Aberg; +Cc: guile-user

On Mon 22 Feb 2010 15:01, Hans Aberg <haberg@math.su.se> writes:

> I have written a bit on a C++ wrap - has this been done? I use templates
> to get a static typed style similar to that of Haskell,  which can be
> overridden at need. Some example code below.

Looks like fun! You should throw your code up somewhere for the world to
enjoy :)

Andy
-- 
http://wingolog.org/




^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: C++ wrap
  2010-02-22 19:06 ` Andy Wingo
@ 2010-02-23 14:10   ` Hans Aberg
  0 siblings, 0 replies; 3+ messages in thread
From: Hans Aberg @ 2010-02-23 14:10 UTC (permalink / raw)
  To: guile-user

I have experimented with adding C++ exception handling to the wrap. It  
seems, using gcc, that it works fine, as long as one does not try to  
pass a C++ exception through a C function call - then it calls the  
terminate handler.

So add an exception type to Guile which can hold the thrown data, a  
pair (key . args) with a predicate
   SCM_API int scm_is_exception(SCM x);
When there is an uncaught exception in a C function returning SCM, it  
should instead return this exception type with the thrown data. (So  
there would need to be some variable present, changing the behavior of  
these C-functions.)

Then write a function (object = C++ version of SCM)
   object rethrow(const object& x) {
     if (scm_is_exception(x))
       throw (exception)x;
     else
       return x;
   }

Then just add this rethrow() to the returns that might be an exception:
   number operator/(const number& x, const number& y) { return  
rethrow(scm_divide(x, y)); }
instead of
   number operator/(const number& x, const number& y) { return  
scm_divide(x, y); }

The code should then look normal:
   try {
     integer x = 1, y = 0;
     integer z = x/y;  // exception
   catch (exception& x) {
     out << "Exception: " << x << newline;
   }

I did some code using scm_internal_catch(), but it takes a body  
function of only one argument:
   SCM body(void *data);
So I guess one has to fiddle around with passing suitable structs  
using it. - May try it later.

   Hans






^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2010-02-23 14:10 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-02-22 14:01 C++ wrap Hans Aberg
2010-02-22 19:06 ` Andy Wingo
2010-02-23 14:10   ` Hans Aberg

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).