/*Demonstrates class meta data. Basically, we make use of the compiler's data about a class. We can add to the compilers data arbitrary items, either string or or int or F64 (if you typecast). This stuff is not high performance. Don't get carried away -- it might be slow. */ U0 RankOut(I64 i) { " %z", i, "Cadet\0Ensign\0Captain\0Admiral\0President\0"; } class Test1Struct { I64 age print_str "%2d" default_val 38; I64 color default_val RED; //Accepts expressions I64 rank print_str "%1d" default_val 6/2 output_fun &RankOut; }; class Test2Struct { I64 age print_str "%2d" default_val 38 percentile 54.20; I64 rank print_str "%1d" default_val 5; I64 serial_num print_str "%6d" default_val 123456; }; U0 DumpStruct(U8 *_d, U8 *class_name=lastclass) {//lastclass is keyword. See ::/Demo/LastClass.ZC. CHashClass *tmpc = HashFind(class_name, Fs->hash_table, HTT_CLASS); U8 *print_str; I64 *q, default_val; U0 (*fp_output_fun)(I64 i); F64 percentile; if (!tmpc) return; CMemberList *ml; ml = tmpc->member_list_and_root; while (ml) { "%s:", ml->str; //All our items are I64's. If you want, you can check //the data type of the member variable. See ClassRep(). q = _d + ml->offset; if (print_str = MemberMetaData("print_str", ml)) "" print_str, *q; //This is slightly ambiguous -- if no meta is present it will return zero. if (default_val = MemberMetaData("default_val", ml)) " default:%d", default_val; //This corrects for the ambiguity, allowing zero percentile. if (MemberMetaFind("percentile", ml)) {//check if it exists //We could use the CMemberListMeta structure returned by //MemberMetaFind() and save a search. percentile = MemberMetaData("percentile", ml)(F64); " percentile: %5.2f", percentile; } if (fp_output_fun = MemberMetaData("output_fun", ml)) (*fp_output_fun)(*q); '\n'; ml = ml->next; } } Test1Struct t1; t1.age = 44; t1.rank = 3; DumpStruct(&t1); Test2Struct t2; t2.age = 22; t2.rank = 2; t2.serial_num = 55555; DumpStruct(&t2);