blob: 49f68cc4abfeafc0d4e3ebcfde9968bb1eb97b6c [file] [log] [blame] [edit]
// In this example, we intentially avoid using the standard Cogent library.
// Everything is defined locally (apart from the built-in types in Cogent).
$esc:(#include <stdlib.h>)
$esc:(#include <stdio.h>)
typedef void* Heap;
#include "generated.c"
$ty:(< Failure Heap | Success (Bag, Heap) >) newBag ($ty:(Heap) heap)
{
$ty:(< Failure Heap | Success (Bag, Heap) >) ret;
$ty:(Bag) bag = malloc (sizeof (*bag));
if (!bag) {
ret.tag = TAG_ENUM_Failure;
ret.Failure = heap;
return ret;
}
bag->count = 0;
bag->sum = 0;
ret.tag = TAG_ENUM_Success;
ret.Success.p1 = bag;
ret.Success.p2 = heap;
return ret;
}
$ty:(Heap) freeBag ($ty:((Heap, Bag)) args)
{
free (args.p2); // free the Bag
return args.p1; // return the "new" Heap
}
$ty:b $id:reduce ($ty:(((List a)!, (a!, b) -> b, b)) args)
{
$ty:((List a)) list = args.p1;
$ty:b acc = args.p3; // Initial accummulator
$ty:((a!, b)) fargs;
while (list) {
fargs.p1 = list->data;
fargs.p2 = acc;
acc = (($spec:((a!, b) -> b)) args.p2) (fargs);
list = list->next;
}
return acc;
}
int main ()
{
// Create a list of a few U32 integers.
// As we don't have a function for initialising a list in Cogent,
// we cannot define a poly-function in antiquoted C. That's why here
// we only implement an instance of it, hackily.
$ty:(List U32) list = NULL;
$ty:(U32) x = 0;
while (1) {
printf("Enter a number: ");
if (scanf("%d",&x) < 0) {
break;
}
$ty:(List U32) cell = malloc (sizeof (*cell));
cell->data = x;
cell->next = list;
list = cell;
}
// Print the list
$ty:(List U32) curr;
curr = list;
printf ("\nThe list is: ");
while (curr != NULL) {
printf ("%d -> ", curr->data);
curr = curr->next;
}
printf ("NULL\n");
// Now call `average'
$ty:((Heap, (List U32)!)) avg_args;
avg_args.p1 = NULL;
avg_args.p2 = list;
$ty:((Heap, U32)) avg_ret = $exp:(average) (avg_args);
printf("The average is: %d\n", avg_ret.p2);
return 0;
}