blob: 6c1c8c9c18ea72f8e18b9d5b62f5a23f6fc046d7 [file] [log] [blame] [edit]
$esc:(#include <stdlib.h>)
$esc:(#include <stdio.h>)
/*
* The environment is an opaque type known only to the C implementation.
*
* It is actually empty but is needed by the cogent to demonstrate that
* there is some value that is being changed by the operations on things
* outside of the code itself.
*
* It essentially represents 'the world' to the program.
*/
typedef void *Env;
/*
* This is how we embed the code generated by the cogent compiler.
*
* The makefile is configured to ensure the cogent output is produced as
* 'generated.c'.
*/
#include "generated.c"
/*
* Our implementation of show_u32 just prints the value using printf.
* We need to pass the environment back afterwards which was 'mutated'
* by the act of printing to standard output.
*/
$ty:(Env) show_u32 ($ty:((Env, U32)) args) {
printf("%d", args.p2);
return args.p1;
}
/*
* As above but for strings being printed directly.
*/
$ty:(Env) show_string ($ty:((Env, String)) args) {
fputs(args.p2, stdout);
return args.p1;
}
/*
* This implementation of iterate is fairly straightforward. The
* iterator is just a starting value, a condition function, and the loop
* body. We just plug all of the sections into the appropriate parts of
* a while loop and let it run.
*/
$ty:(a) $id:iterate ($ty:(Iterator a) iter) {
$ty:(a) curr = iter.curr;
$ty:(<Continue | Stop>) proceed;
proceed = (($spec:(IterCondition a)) iter.condition) (curr);
while (proceed.tag == TAG_ENUM_Continue) {
curr = (($spec:(IterStep a)) iter.step) (curr);
proceed = (($spec:(IterCondition a)) iter.condition) (curr);
}
/*
* We need to return the final value of the loop. This is especially
* important if it is or contains any heap values that would
* otherwise be leaked but this also contains all of the information
* for what has actually occurred in the loop.
*/
return curr;
}
/*
* Main here just creates 'the world' and passes it to the cogent
* program. The cogent program mutates it and we get the result.
*/
int main(void) {
$ty:(Env) env = NULL;
env = $esc:prog(env);
return EXIT_SUCCESS;
}