Last active
December 6, 2018 14:44
-
-
Save machuidel/d7cc099ddc4970c6ddf4 to your computer and use it in GitHub Desktop.
Option Type Macro
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#ifndef _XOPTION_TYPE_H_ | |
#define _XOPTION_TYPE_H_ | |
#ifdef __cplusplus | |
extern "C" | |
{ | |
#endif | |
#include<stdio.h> | |
#include<stdlib.h> | |
/* Option */ | |
typedef enum { | |
Option_some, | |
Option_none | |
} option_status_t; | |
#define Func_name(out_type, name, ...) name | |
#define Func_out_type(out_type, name, ...) out_type | |
#define Option(type) option ## _ ## type ## _t | |
#define Option_define(type) \ | |
typedef struct { \ | |
option_status_t status; \ | |
type value; \ | |
} Option(type) | |
#define Option_unwrap(x) (x.value) | |
#define Option_flatten(x) Option_unwrap(x) | |
#define Option_is_some(x) (x.status == Option_some) | |
#define Option_is_none(x) (x.status == Option_none) | |
#define Option_none(type) ((Option(type)){Option_none, 0}) | |
#define Option_some(type, value) ((Option(type)){Option_some, value}) | |
/* cmap can be used with stdc functions, but you need to specify the type */ | |
#define Option_cmap(type, f, x) ((Option_is_some(x)) ? Option_some(type, f(x.value)) : Option_none(type)) | |
/* fmap can only be used with an abstract X macro in which you define the type and stdc function */ | |
#define Option_fmap(f, x) Option_cmap(f(Func_out_type), f(Func_name), x) | |
/* cflatmap can be used with stdc functions, but you need to specify the type */ | |
#define Option_cflatmap(type, f, x) Option_flatten(Option_cmap(type, f, x)) | |
/* fflatmap can only be used with an abstract X macro in which you define the type and stdc function */ | |
#define Option_fflatmap(f, x) Option_cflatmap(f(Func_out_type), f(Func_name), x) | |
#ifdef __cplusplus | |
} | |
#endif | |
#endif // _XOPTION_TYPE_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include "option_type.h" | |
/* Define option */ | |
Option_define(float); | |
Option_define(Option(float)); | |
/* Define functions */ | |
float _add2(float x) { | |
return x + 2.0f; | |
} | |
#define add2(_) _(float, _add2) | |
float _mul4(float x) { | |
return x * 4.0f; | |
} | |
#define mul4(_) _(float, _mul4) | |
Option(float) _madd2(float x) { | |
return Option_some(float, x + 2.0f); | |
} | |
#define madd2(_) _(Option(float), _madd2) | |
Option(float) _mmul4(float x) { | |
return Option_some(float, x * 4.0f); | |
} | |
#define mmul4(_) _(Option(float), _mmul4) | |
/* Test routine */ | |
int main(int argc, char **argv) { | |
Option(float) result1 = Option_some(float, 2.0f); | |
Option(float) result2 = Option_fmap(mul4, Option_fmap(add2, result1)); | |
Option(float) result3 = Option_some(float, 2.0f); | |
Option(float) result4 = Option_fflatmap(mmul4, Option_fflatmap(madd2, result3)); | |
if(Option_is_some(result2)) { | |
printf("MAP: Some(%f)\n", Option_unwrap(result2)); | |
} else { | |
printf("MAP: None\n"); | |
} | |
if(Option_is_some(result4)) { | |
printf("FLATMAP: Some(%f)\n", Option_unwrap(result4)); | |
} else { | |
printf("FLATMAP: None\n"); | |
} | |
exit(EXIT_SUCCESS); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@solvingj
I noticed your comment just now after a year. Libhandler seems like an interesting project. Did you already finish the implementation / changes you mentioned? I did not continue this way I did above. My idea was to create a functional / higher order programming library in C to generate code for my game engine which I figured would be possible with a lot of C preprocessor hackery. Instead I now generate code using a code generator I wrote that reads annotation attributes from the C code using libclang and transform scripts written in Lua. Will release this and several other projects (cross platform build system using Lua etc.) as open source soon.