Created
December 27, 2010 17:03
-
-
Save joedavis/756293 to your computer and use it in GitHub Desktop.
"Let" special form, in C
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
/* Example usage of "let" */ | |
#include "let.h" | |
int | |
main (int argc, char *argv[]) | |
{ | |
let ((x, 42), | |
(y, 3.14159)) | |
{ | |
printf ("%d\n", x); | |
printf ("%f\n", y); | |
} | |
} |
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
#ifndef _LET_H_ | |
#define _LET_H_ | |
#if __cplusplus > 199701L | |
# define GET_TYPE_FROM_EXPR decltype | |
#else | |
# define GET_TYPE_FROM_EXPR __typeof__ | |
#endif | |
#define CONCAT(a,b) CONCAT_(a,b) | |
#define CONCAT_(a,b) a ## b | |
#define GENSYM() \ | |
CONCAT(CONCAT(_anon_variable_, __LINE__), __COUNTER__) | |
#ifdef __GNUC__ | |
# define GENSYM_LOCAL() \ | |
CONCAT(CONCAT(_$anon_$variable_$,__LINE__), __COUNTER__) | |
#else | |
# define GENSYM_LOCAL() \ | |
CONCAT(CONCAT(_anon_variable_,__LINE__), __COUNTER__) | |
#endif | |
#define DEFONCE(type, name, value) \ | |
DEFONCE_WITH_SYMS (type, name, value, GENSYM_LOCAL()) | |
#define DEFONCE_WITH_SYMS(type, name, value, test_variable) \ | |
for (int test_variable = 1; test_variable; test_variable = 0) \ | |
for (type name = value; test_variable; test_variable = 0) | |
#define EXPAND_LET(name, value) \ | |
DEFONCE(GET_TYPE_FROM_EXPR(value), name, value) | |
#define PP_NARG(...) \ | |
PP_NARG_(__VA_ARGS__,PP_RSEQ_N()) | |
#define PP_NARG_(...) \ | |
PP_ARG_N(__VA_ARGS__) | |
#define PP_ARG_N( \ | |
_1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \ | |
_11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \ | |
_21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \ | |
_31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \ | |
_41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \ | |
_51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \ | |
_61,_62,_63, N, ...) N | |
#define PP_RSEQ_N() \ | |
63,62,61,60, \ | |
59,58,57,56,55,54,53,52,51,50, \ | |
49,48,47,46,45,44,43,42,41,40, \ | |
39,38,37,36,35,34,33,32,31,30, \ | |
29,28,27,26,25,24,23,22,21,20, \ | |
19,18,17,16,15,14,13,12,11,10, \ | |
9, 8, 7, 6, 5, 4, 3, 2, 1, 0 | |
#define let(...) CONCAT(LET_, PP_NARG(__VA_ARGS__))(__VA_ARGS__) | |
#define LET_1(a) EXPAND_LET a | |
#define LET_2(a,b) EXPAND_LET a LET_1(b) | |
#define LET_3(a,b,c) EXPAND_LET a LET_2(b, c) | |
#define LET_4(a,b,c,d) EXPAND_LET a LET_3(b, c, d) | |
#define LET_5(a,b,c,d,e) EXPAND_LET a LET_4(b, c, d, e) | |
#define LET_6(a,b,c,d,e,f) EXPAND_LET a LET_5(b, c, d, e, f) | |
#define LET_7(a,b,c,d,e,f,g) EXPAND_LET a LET_6(b, c, d, e, f, g) | |
#define LET_8(a,b,c,d,e,f,g,h) EXPAND_LET a LET_7(b, c, d, e, f, g, h) | |
#endif /* _LET_H_ */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment