-
Notifications
You must be signed in to change notification settings - Fork 2
/
xmacros.h
139 lines (100 loc) · 4.29 KB
/
xmacros.h
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
// ================================================================== //
// XMACROS_H
// ================================================================== //
#ifndef _XMACROS_H_
#define _XMACROS_H_
#ifdef __cplusplus
extern "C" {
#endif
// https://codecraft.co/2014/11/25/variadic-macros-tricks/
#define _GET_NTH_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, N, ...) N
#define COUNT_VARARGS(...) _GET_NTH_ARG(__VA_ARGS__, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
fw_call doprintstate();
/* #define XT(n) (fcell_xt) xt_ ## n */
#define XT(n) (fcell_xt) & xt_ ## n
#define XCELLS(n) (fcell_xt)(n * WORD_PTR_SZ)
#define XTV(n) (fcell_xt) &xt_ ## var_ ## n
#ifdef __cplusplus
}
#endif
#endif // _XMACROS_H_
#ifdef forth_primitive
#undef forth_primitive
#endif
#ifdef forth_core
#undef forth_core
#endif
#ifdef forth_variable
#undef forth_variable
#endif
#ifdef forth_word
#undef forth_word
#endif
#ifdef forth_docall
#undef forth_docall
#endif
// ================================================================== //
// FORTH_DEFINE_PRIMITIVES
// ================================================================== //
#ifdef FORTH_DEFINE_PRIMITIVES
// implement the basic definition primitive
#define forth_primitive(_name_str, _name_len, mask, func, _comt, BLOCK) \
fw_call func(FORTH_REGISTERS) BLOCK \
fcell_xt xt_ ## func = (fcell_xt)&func
#define forth_core(_name_str, _name_len, mask, func, _comt, BLOCK) \
fw_call func(FORTH_REGISTERS) BLOCK \
fcell_xt xt_ ## func = (fcell_xt)&func; \
fword_info_t xw_ ## func = { &xt_ ## func, mask, _name_len, _name_str };
// must be init'ed at bootstrap
#define forth_word(name_str, name_len, mask, lbl, _comt, WORDS...) \
fcell_xt xt_ ## lbl[ COUNT_VARARGS(WORDS) ];
#define forth_docall(name_str, name_len, mask, func, comment, lbl) \
forth_core(name_str, name_len, mask, func, comment, { \
calc_addr_off(x, __label(lbl)); \
call(call00); \
jump(next); \
})
#define forth_variable(name, _name_len, struct_name, member_name) \
void *get_var_ ## struct_name ## member_name () { return &struct_name->member_name; } \
forth_core( #name, _name_len, F_NORMAL, var_ ## name, _comment, { \
call( get_var_ ## struct_name ## member_name ); \
copy_reg(s1, xresult); \
pushd(1); \
jump(next); \
})
#endif // FORTH_DEFINE_PRIMITIVES
// ================================================================== //
// FORTH_DEFINE_DICT_ENTRIES
// ================================================================== //
#ifdef FORTH_DEFINE_DICT_ENTRIES
#define forth_primitive(name_str, name_len, mask, func, _comment, _BLOCK)
#define forth_core(name_str, name_len, mask, func, _comment, _BLOCK) \
dict_add(&xw_ ## func)
#define forth_variable(name, name_len, struct_name, member_name) \
dict_add(&xw_var_ ## name)
#define forth_word(name_str, name_len, mask, lbl, _comt, WORDS...) \
fcell_xt fw_ ## lbl[ COUNT_VARARGS(WORDS) + 1 ] = { (fcell_xt)xt_docolon, WORDS }; \
memcpy(xt_ ## lbl, fw_ ## lbl, sizeof(xt_ ## lbl)); \
dict_create(F_WORD | mask, name_len, name_str, (fcell_xt*)xt_ ## lbl)
#define forth_docall(name_str, name_len, mask, func, comment, lbl) \
dict_add(&xw_ ## func)
#endif // FORTH_DEFINE_DICT_ENTRIES
// ================================================================== //
// FORTH_DEFINE_HEADERS
// ================================================================== //
#ifdef FORTH_DEFINE_HEADERS
#define forth_primitive(name_str, name_len, mask, func, _comment, _BLOCK) \
extern fcell_xt xt_ ## func
#define forth_core(name_str, name_len, mask, func, _comment, _BLOCK) \
extern fcell_xt xt_ ## func
#define forth_variable(name, name_len, struct_name, member_name)
#define forth_word(name_str, name_len, mask, lbl, _comt, WORDS...) \
extern fcell_xt xt_ ## lbl[ COUNT_VARARGS(WORDS) ]
#define forth_docall(name_str, name_len, mask, func, comment, lbl)
#endif // FORTH_DEFINE_HEADERS
// ================================================================== //
// Forth Stack Primitives
// ================================================================== //
#ifndef FORTH_STACK_PRIMS
#define FORTH_STACK_PRIMS
#endif // FORTH_STACK_PRIMS