Skip to content

Instantly share code, notes, and snippets.

@joedavis
Created December 27, 2010 17:03
Show Gist options
  • Save joedavis/756293 to your computer and use it in GitHub Desktop.
Save joedavis/756293 to your computer and use it in GitHub Desktop.
"Let" special form, in C
/* 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);
}
}
#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