Jump to content
  • Advertisement
Sign in to follow this  
cypherx

Help with C/C++ interface for my language

This topic is 4602 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I've been writing a lisp-derivative scripting language. I'm quite happy with the features (first-class closures, partial function evaluation, a class-based object system, other goofy stuff I wanted to try implementing). The C/C++ interface however is really unfriendly. Every lisp function accepts an argument list (an s-expression) and returns another s-expression. So right now the only functions I can bind in C++ must have the signature Expr* (*func) (Expr*). This is a hassle since I have to write wrapper functions around any existing function I want to bind. Any ideas on how to make a better interface? (it currently works like this)
Expr* plus_one(Expr* args)
{
   double val = first(args)->getValue();
   val += 1.0;
   return new Number(val);
}

int main()
{
   LispMachine lisp;
   lisp.BindFunction("++", &plus_one);
   Expr* result = lisp.run("(++ 2)");
   cout << result;
}

Thanks, Alex

Share this post


Link to post
Share on other sites
Advertisement
For your returns, you could provide automatic conversions from C++ Datatypes to your expressions. Your example would become


double plus_one(Expr* args)
{
double val = first(args)->getValue();
return val += 1.0;
}


You will need several versions of the "bind" method, one for every return type plus one for the "Expr*". Then you can put the user function in a wrapper.

Share this post


Link to post
Share on other sites
It might be way more than you want, but you should take some time and write a swig module for your language and create wrappers through it.

www.swig.org

It's not particulary difficult(there are already like 10 other modules to look at). I believe it will be time well spent.

Share this post


Link to post
Share on other sites
Gorg,
Thanks for directing me to SWIG. For now I want to spend most of my time adding language features. Once those are conrete I will probably make a swig module.

Steadtler,
I like the idea of automatic type conversions, since I already implement them internally within the language (expr->getValue(), expr->toString()). Thanks for the idea.

-Alex

Share this post


Link to post
Share on other sites
I'm posting this for the benefit of anyone else struggling to make a good C++ interface to a scripting language. I finally made something that allows most C++ functions to be hooked in to my lispish language with minimal effort.

Example:

int f1(int x, int y) { return x + y; }
string f2 (float num) { num += 0.9; return lexical_cast<string>(num); }

int main()
{
LispMachine lisp;
lisp.BindFunction("adder", f1);
lisp.BindFunction("other-func", f2);

Expr result = lisp.RunString("(other-func (adder 2 3))");
print(result); //prints "5.9"
return 0;
}



The trick to binding different C++ data types to wrap the function pointer in an ExternalFunction class, which does type conversion from standard C++ types to my language's types. To cover all the possible types and different numbers of arguments requires really ugly gobs of partial template specialization...but it works, and the end-user never has to see the ugly insides.

-Alex

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!