True 'AnyType' in C++

Started by
28 comments, last by Extrarius 20 years, 3 months ago
"Game Scripting Mastery" describes the implementation of a
typeless scripting language, which sounds like is what you''re
doing here.

The basic idea is already mentioned -- to use a type flag.
Then provide some auxiliary functions like GetValueAsInt(),
GetValueAsString(), GetValueAsBoolean()...etc.

Those functions attempt to convert from whatever internally
stored value to whatever format is requested.



Kami no Itte ga ore ni zettai naru!
神はサイコロを振らない!
Advertisement
Thanks for hosting that, Fruny. It looks like it'll be what I end up using.

[edited by - extrarius on January 5, 2004 11:28:50 PM]
"Walk not the trodden path, for it has borne it's burden." -John, Flying Monk
quote:Since I plan on adding lots of types to my scripting language, I''d rather not have to do something like variant where you list the types you want {because I''m not sure the number of types I''ll have in the end is less than the maximum it lets you specify).

You shouldn''t be planning anything of the sort. You should add a few base types (perhaps, integers, floating point, strings, arrays, lists) and everything else should be built up within the scripting language itself.
char a[99999],*p=a;int main(int c,char**V){char*v=c>0?1[V]:(char*)V;if(c>=0)for(;*v&&93!=*v;){62==*v&&++p||60==*v&&--p||43==*v&&++*p||45==*v&&--*p||44==*v&&(*p=getchar())||46==*v&&putchar(*p)||91==*v&&(*p&&main(0,(char**)(--v+2))||(v=(char*)main(-1,(char**)++v)-1));++v;}else for(c=1;c;c+=(91==*v)-(93==*v),++v);return(int)v;}  /*** drpizza@battleaxe.net ***/
quote:Original post by DrPizza
quote:Since I plan on adding lots of types to my scripting language, I''d rather not have to do something like variant where you list the types you want {because I''m not sure the number of types I''ll have in the end is less than the maximum it lets you specify).

You shouldn''t be planning anything of the sort. You should add a few base types (perhaps, integers, floating point, strings, arrays, lists) and everything else should be built up within the scripting language itself.
Right now I''m planning on integers, floating point, strings, arrays, lists, streams, functions, hash tables, characters, read-tables, and several others. I''ll probably add more as I go along to make my language more complete. I''m making a Common Lisp-based scripting language.
"Walk not the trodden path, for it has borne it's burden." -John, Flying Monk
Another solution is to use interfaces.. Although it isn''t the best because it requires you to create classes to hold all your basic types.

class ISomeType{     void * GetObject(string vType) = 0;}; 


You could have all your types implement that interface and whenever you want to convert it to a type just call GetObject with the name of the object.
I would do something like this:

struct var
{
char Value [8];
int Type;
};

Then to set the integer Health to 100, you''d say:

*(int*)&Health = 100;
Health.Type = TYPE_INTEGER;

That code sets the first four bytes of the Value array to the 32-bit integer 100 and ignores the other four. Similarly, for a bool, you''d do:

*(bool*)&Health = true;

...which sets only Value[0]. For a pointer:

*(void**)&Health = new object;

and so on.

~CGameProgrammer( );

-- Post screenshots of your projects. 100+ posts already in the archives.
~CGameProgrammer( );Developer Image Exchange -- New Features: Upload screenshots of your games (size is unlimited) and upload the game itself (up to 10MB). Free. No registration needed.
In practice the only solution is to have a ''container'' object (CGameProgrammer uses a 64 bit buffer) to convert to/from other objects.
The conversion can be implemented using an identifier or virtual methods (this solution is more object oriented).
Yeah, it seems that boost::any and any_ccast are the cleanest solutions available in C++. I''m kind of dissapointed though, with all the template and polymorphism hacking out there I figured somebody would have a better solution.
"Walk not the trodden path, for it has borne it's burden." -John, Flying Monk
quote:Original post by Extrarius
Yeah, it seems that boost::any and any_ccast are the cleanest solutions available in C++. I''m kind of dissapointed though, with all the template and polymorphism hacking out there I figured somebody would have a better solution.

No, because template hacking only provides for early-bound decisions, whereas you need late-bound decisions. The only mechanism C++ provides for that is dynamic despatch, but that alone does not provide enough flexibility to do what you need. Ultimately, you cannot make the C++ type-system do what you want, so you must move it out of the way. You then maintain type-safety via discriminated unions and manually-enforced conventions. See Greenspun''s Tenth.
"Better" in what way? It''s arguably better than the solution used in most other dynamically typed language implementations (discriminated unions).

Just what exactly are you hoping a solution to offer?

char a[99999],*p=a;int main(int c,char**V){char*v=c>0?1[V]:(char*)V;if(c>=0)for(;*v&&93!=*v;){62==*v&&++p||60==*v&&--p||43==*v&&++*p||45==*v&&--*p||44==*v&&(*p=getchar())||46==*v&&putchar(*p)||91==*v&&(*p&&main(0,(char**)(--v+2))||(v=(char*)main(-1,(char**)++v)-1));++v;}else for(c=1;c;c+=(91==*v)-(93==*v),++v);return(int)v;}  /*** drpizza@battleaxe.net ***/

This topic is closed to new replies.

Advertisement