About Me‎ > ‎Projects‎ > ‎

I opened the front cover of Design Patterns...

posted Feb 10, 2011, 9:14 PM by Tim Rodriguez   [ updated Mar 26, 2011, 10:07 AM ]
    ...and wrote a prototype framework that allows for this:

#include <cake/Cake.h>

$declare_object(Rect,
    int x1,
    int x2,
    int y1,
    int y2
);
$declare_object_methods(Rect,
    (int, area,()),
    (int, perimeter,())
);
int $def_object_method(Rect, area) {
    return $abs((self->x2 - self->x1)*(self->y2 - self->y1));
}
int $def_object_method(Rect, perimeter) {
    return 2*$abs(self->x2 - self->x1) + 2*$abs(self->y2 - self->y1);
}

$main() {
    Rect my_r = $new(Rect);
 
    my_r->x1 = 0;
    my_r->x2 = 3;
    my_r->y1 = 0;
    my_r->y2 = 3;

    printf( "%d\n", $(my_r, area));
    return 0;
}

/* Output:
   9
*/

    And this:

/* In file "my_template.h" */
#ifdef MY_TPL_TYPE_1
#ifdef MY_TPL_TYPE_2
#define TEMPLATE_TYPE_1 MY_TPL_TYPE_1
#define TEMPLATE_TYPE_2 MY_TPL_TYPE_2

#include <cake/headers/utilities/template_defs.h>

#include <cake/headers/utilities/nested_template_prepare.h>
#define MY_NEST_TPL_TYPE_1 MY_TPL_TYPE_1
#include "my_nested_template.h"

#define NESTED_EXAMPLE CAKE_CONCAT_ALL(Nested_Example, MY_TPL_TYPE_1, _)
#define EXAMPLE TEMPLATE_TYPE_NAME(Example)

$declare_template_object(Example,
    NESTED_EXAMPLE a,
    MY_TPL_TYPE_2 b
);
$declare_template_methods(Example,
    (void, hello,())
);
void $def_template_method(Example, hello) {
    $cake_assert(self != NULLelse { return; }
    printf("Hello World from %s: %c!\n", $stringify(EXAMPLE), self->b);
    if (self->a) { $(self->a, hello) };
}

EXAMPLE $def_template_method(Example, init, size_t n, ...) {
    va_args args;
    va_start(args, n);
    $cake_assert(self != NULL) else { return NULL; }
    $unless(self->a != NULL) {
      self->a = $new(NESTED_EXAMPLE);
    }
    if (n == 1) {
      self->b = va_arg(args, MY_TPL_TYPE_2);
    }
    return self;
}

#include <cake/headers/utilities/template_undefs.h>

#undef NESTED_EXAMPLE
#undef EXAMPLE
#undef MY_TPL_TYPE_2
#undef MY_TPL_TYPE_1

#endif
#endif

/* In file "my_nested_template.h" */
#ifdef MY_NEST_TPL_TYPE_1
#define TEMPLATE_TYPE_1 MY_NEST_TPL_TYPE_1

#include <cake/headers/utilities/template_defs.h>

$declare_template_object(Nested_Example,
    MY_NEST_TPL_TYPE_1 a
);
$declare_template_methods(Nested_Example,
    (void, hello,())
);
void $def_template_method(Nested_Example, hello) {
    printf("Hello World from %s!\n",
           $stringify(TEMPLATE_TYPE_NAME(Nested_Example)));
}

#include <cake/headers/utilities/template_undefs.h>

#undef MY_NEST_TPL_TYPE_1

#endif

/* In file "main.c" */
#include <cake/Cake.h>

#define MY_TPL_TYPE_1 int
#define MY_TPL_TYPE_2 char
#include "my_template.h"

$main() {
    Example_int_char e = $new(Example_int_char, 'c');

    $(e, hello);

    return 0;
}

/* Output:
   Hello World from Example_int_char_: c!
   Hello World from Nested_Example_int_!
*/

    This framework won't be included in (and thus, won't delay) the initial release, v0.0.1. It is my hope to convert the code that I have written over to this framework by the full v0.1 release, so that people can create their own objects and use the preprocessing tools that I have provided. In order to get the full benefit, however, v0.2 will implement Interfaces, which will allow the developer to inform Cake of what additional preprocessor functions can be used on custom objects and templates.
Comments