| // 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; |
| } |
| |