Home | About | Examples | RoadmapSourceforge

Here are some examples (with $-macros) for Cake:

Array Templates
/* Define Array Type */
#define ARRAY_TYPE 
int

/* Add Extra Member Functions */
#define ARRAY_CAKE_TYPE _CAKE_INTEGRAL_TYPE

/*
 Define Array_int */

#include
 <cake/tpl/Array.h>


$main() {
  /* foo will be cleaned up @ end of scope */
  $Array(int) foo = $new(Array_int);

  /* bar will NOT be cleaned up @ end of scope */
  Array_int bar
;

  int baz[] = {0123};


  /* copy baz into foo */
  $from_c_array(foo, baz);

  /* call "foo.duplicate()" */
  bar = $(foo, duplicate);

  $print(foo);
  printf("sum = %d\n", $(foo, sum));

  /* Two ways to use "$each": */

  /* Easier to read, more overhead, can nest */
  $each(value, foo) {
    printf(
"%d ", *value);
    *value += 
1;
  }
  $print();

  /* jQuery-ish syntax, faster, can't nest */
  $each(value, foo, {
    printf("%d ", *value);
    *value += 1;
  }) /* <-- Must remember ')' */
  $print();

  $cleanup(bar); // <-- Must manually clean up

  
return 0;

}

/* Output:

   [0, 1, 2, 3]
   sum = 6
   0 1 2 3
   1 2 3 4
*/

Exceptions
/* Define Array Type */
#define ARRAY_TYPE 
int

/* Add Extra Member Functions */
#define ARRAY_CAKE_TYPE _CAKE_INTEGRAL_TYPE

/*
 Define Array_int */

#include
 <cake/tpl/Array.h>


$main() {
  /* foo will be cleaned up @ end of scope */
  $Array(
int) foo = $new(Array_int);

  int bar[] = {0123};

  /* copy bar into foo */
  $from_c_array(foo, bar);

  /* begin try block */
  $try {
    /* automatically increases foo's length */
    $(foo, push_back, 3);
    $(foo, push_back, 7);
    printf("foo[270] = %d\n", $(foo, get, 270));
  }
  /* catch exceptions */
  $except(OutOfRange) {
    $error("$len(foo) = %d.\n", $len(foo));
  }
  /* $finally must appear */
  $finally {}


  
return 0;
}

/* Output (stderr):

   exception_test.c:27:main :: $len(foo) = 6.
*/

Variadic Math Functions
#include <cake/Cake.h>

$main() {
  printf(
"%f\n", $avg(1.0368.0f))
;

  printf("%f\n", $min(-4.3994284));

  return 0;
}
/* Output:

   5.5
   -4.3
*/

Ruby-like Block Syntax for Callbacks
#include <cake/Cake.h>

/* Define my_int */

typedef struct
 {
  
int var;
} my_int;

/* Define Array Type */
#define ARRAY_TYPE my_int


/* Define Array_my_int */
#include
 <cake/tpl/Array.h>



/* Define Array Type */
#define ARRAY_TYPE 
int

/* Add Extra Member Functions */
#define ARRAY_CAKE_TYPE _CAKE_INTEGRAL_TYPE

/*
 Define Array_int */

#include
 <cake/tpl/Array.h>


$main() {
  /* foo will be cleaned up @ end of scope */
  $Array(my_int) foo = $new(Array_my_int);

  /* bar will be cleaned up @ end of scope */

  $Array(int) bar = $new(Array_int);

  
int baz[] = {0123};

  /* Two ways to use "$from_c_array": */

  /* Automatic, if array types are the same */
  $from_c_array(bar, baz);

  /* Define a lambda function to use */
  $from_c_array(foo, baz, (val), {
    my_int ret = { .var = val };
    return ret;
  }) /* <-- Remember ')' */

  /* GCC supports nested functions */
  void myprint(my_int val) {
    printf(
"%d ", val.var);
  }
  
int increment(int value) {
    return value + 1;
  }
  
int sum(int val1, my_int val2) {
    return val1 + val2.var;
  }

  /* Call myprint with each element in foo */
  $(foo, each, myprint);

  $print();

  /* The following memory leak is caught */
  $map(bar, sum, bar, foo);


  $print(bar);

  
return 0;
}

/* Output:

   0 1 2 3
   [0, 2, 4, 6]
*/

Python-like Generators
#include <stdio.h>
#include <cake/Cake_Minimal.h>

$main() {
  /* Define a python-like generator function */
  $generator(fib, intint a = 0, int b = 1)
    while (1) {
      /* return a value, and ... */
      $yield(b);
      /* execution will resume here next call */
      b = a + b;
      a = b - a;
    }
  $end /* <-- Remember $end */

  for (int i = 0; i < 10; i++) {
    printf("%d\n", fib());
  }

  return 0;
}

/* Output:

   1
   1
   2
   3
   5
   8
   13
   21
   34
   55
*/

Knuth's Coroutines (State Machines)
#include <stdio.h>
#include <cake/Cake_Minimal.h>

$main() {
  /* Declare the coroutines that will be used */
  coroutine x, y;
  char buffer[50];

  /* Define the coroutine x */
  $coroutine(x)
    while (1) {
      sprintf(buffer, "Hello ");
      $yield_to(y); /* <-- Note $yield_to() */
    }
  $end /* <-- Remember $end */

  /* Define the coroutine y */
  $coroutine(y)
    while (1) {
      printf("%s World!\n", buffer);
      $yield_to(NULL); /* <-- finish */
    }
  $end /* <-- Remember $end */

  /* This macro allows for stack-less execution.
   * Pass it the coroutine to start with and
   * it will exit when a coroutine yields to NULL
   */
  $start_with(x);

  return 0;
}

/* Output:

   Hello World!
*/

Tuples
#include <stdio.h>
#include <string.h>
#include <cake/Cake_Minimal.h>

/* Declare the tuple types globally. Be aware,
 * there will be issues (like most things in C)
 * if they are declared multiple times. */
$tuple_t(intint);
$tuple_t(intint, char);

/* A function that returns a tuple */
$tuple(intint) return2() {
  /* Important Syntax! */
  return ($tuple(intint)){ 01 };
}

$main() {
  int a, b;
  /* foo can hold a $tuple(int, int) */
  $tuple(intint) foo;
  foo = return2();

  /* You can unpack tuples into variables */
  $tuple_unpack(return2(), a, b);

  /* $tuple_len = the number of elements */
  printf("Length = %d\n", $tuple_len(foo));

  /* all tuples are statically enumerable */
  printf("(%d%d)\n", $enumerate(foo, 2));
  /* $enumerate requires an unsigned integer
   * literal.
 "$enumerate(foo, $tuple_len(foo))"
   * is invalid
 */


  int accept3 ($tuple(intintchar) t) {
    return 1;
  }

  $tuple(intintchar) bar = { 23'g' };
  printf("%d\n", accept3(bar));

  return 0;
}

/* Output:

   Length = 2
   (0, 1)
   1
*/

Named Function Parameters (non-variadic, global-scope functions only)
#include <stdio.h>
#include <cake/Cake_Minimal.h>

/* $named_prototype requires these args:
 * 1:  (comma-separated attribute list)
 * 2:  return type
 * 3:  function name
 * 4+: Each arg to the function must be a pair
 *     of (type, name) */
$named_prototype((),void,foo,(int,x),(int,y));

void fooint x, int y ) {
  printf("(%d%d)\n" x, y );
}

$main() {
  /* named call */
  $named_call(foo, y = 4, x = 5);
  /* regular call */
  foo(
45);


  return 0;
}

/* Output:

   (5, 4)
   (4, 5)
*/