Block-Structured AMR Software Framework
AMReX_IParser_Y.H
Go to the documentation of this file.
1 #ifndef AMREX_IPARSER_Y_H_
2 #define AMREX_IPARSER_Y_H_
3 #include <AMReX_Config.H>
4 
5 #include <AMReX_GpuQualifiers.H>
6 #include <AMReX_GpuPrint.H>
7 #include <AMReX_Math.H>
8 #include <AMReX_Print.H>
9 
10 #include <cstddef>
11 #include <cstdio>
12 #include <cstdlib>
13 #include <cstring>
14 #include <set>
15 #include <string>
16 #include <type_traits>
17 
18 void amrex_iparsererror (char const *s, ...);
19 
20 namespace amrex {
21 
22 enum iparser_f1_t { // Built-in functions with one argument
23  IPARSER_ABS = 1
24 };
25 
26 enum iparser_f2_t { // Built-in functions with two arguments
39 };
40 
41 enum iparser_f3_t { // functions with three arguments
43 };
44 
58  IPARSER_ADD_VP, /* types below are generated by optimization */
68 };
69 
70 /* In C, the address of the first member of a struct is the same as
71  * the address of the struct itself. Because of this, all struct iparser_*
72  * pointers can be passed around as struct iparser_node pointer and enum
73  * iparser_node_t type can be safely checked to determine their real type.
74  */
75 
76 union iparser_nvp {
77  struct iparser_node* n;
78  long long v;
79  int ip;
80 };
81 
82 struct iparser_node {
83  enum iparser_node_t type;
84  struct iparser_node* l;
85  struct iparser_node* r;
86  union iparser_nvp lvp; // After optimization, this may store left value/pointer offset.
87  int rip; // this may store right pointer offset.
88 };
89 
91  enum iparser_node_t type;
92  long long value;
93 };
94 
96  enum iparser_node_t type;
97  char* name;
98  int ip;
99 };
100 
101 struct iparser_f1 { /* Builtin functions with one argument */
102  enum iparser_node_t type;
103  struct iparser_node* l;
104  enum iparser_f1_t ftype;
105 };
106 
107 struct iparser_f2 { /* Builtin functions with two arguments */
108  enum iparser_node_t type;
109  struct iparser_node* l;
110  struct iparser_node* r;
111  enum iparser_f2_t ftype;
112 };
113 
114 struct iparser_f3 { /* Builtin functions with three arguments */
115  enum iparser_node_t type;
116  struct iparser_node* n1;
117  struct iparser_node* n2;
118  struct iparser_node* n3;
119  enum iparser_f3_t ftype;
120 };
121 
123  enum iparser_node_t type;
124  struct iparser_symbol* s;
125  struct iparser_node* v;
126 };
127 
128 static_assert(sizeof(iparser_f3) <= sizeof(iparser_node), "amrex iparser: sizeof iparser_node too small");
129 
130 /*******************************************************************/
131 
132 /* These functions are used in bison rules to generate the original AST. */
133 void iparser_defexpr (struct iparser_node* body);
134 struct iparser_symbol* iparser_makesymbol (char* name);
135 struct iparser_node* iparser_newnode (enum iparser_node_t type, struct iparser_node* l,
136  struct iparser_node* r);
137 struct iparser_node* iparser_newnumber (long long d);
138 struct iparser_node* iparser_newsymbol (struct iparser_symbol* sym);
139 struct iparser_node* iparser_newf1 (enum iparser_f1_t ftype, struct iparser_node* l);
140 struct iparser_node* iparser_newf2 (enum iparser_f2_t ftype, struct iparser_node* l,
141  struct iparser_node* r);
142 struct iparser_node* iparser_newf3 (enum iparser_f3_t ftype, struct iparser_node* n1,
143  struct iparser_node* n2, struct iparser_node* n3);
144 struct iparser_node* iparser_newassign (struct iparser_symbol* s, struct iparser_node* v);
145 struct iparser_node* iparser_newlist (struct iparser_node* nl, struct iparser_node* nr);
146 
147 /*******************************************************************/
148 
149 /* This is our struct for storing AST in a more packed way. The whole
150  * tree is stored in a contiguous chunk of memory starting from void*
151  * p_root with a size of sz_mempool.
152  */
154  void* p_root;
155  void* p_free;
156  struct iparser_node* ast;
157  std::size_t sz_mempool;
158 };
159 
161 void amrex_iparser_delete (struct amrex_iparser* iparser);
162 
163 struct amrex_iparser* iparser_dup (struct amrex_iparser* source);
164 struct iparser_node* iparser_ast_dup (struct amrex_iparser* iparser, struct iparser_node* node, int move);
165 
166 void iparser_regvar (struct amrex_iparser* iparser, char const* name, int i);
167 void iparser_setconst (struct amrex_iparser* iparser, char const* name, long long c);
168 void iparser_print (struct amrex_iparser* iparser);
169 std::set<std::string> iparser_get_symbols (struct amrex_iparser* iparser);
170 int iparser_depth (struct amrex_iparser* iparser);
171 
172 /* We need to walk the tree in these functions */
173 void iparser_ast_optimize (struct iparser_node* node);
174 std::size_t iparser_ast_size (struct iparser_node* node);
175 void iparser_ast_print (struct iparser_node* node, std::string const& space, AllPrint& printer);
176 void iparser_ast_regvar (struct iparser_node* node, char const* name, int i);
177 void iparser_ast_setconst (struct iparser_node* node, char const* name, long long c);
178 void iparser_ast_get_symbols (struct iparser_node* node, std::set<std::string>& symbols,
179  std::set<std::string>& local_symbols);
180 int iparser_ast_depth (struct iparser_node* node);
181 
182 /*******************************************************************/
183 
185 iparser_call_f1 (enum iparser_f1_t /*type*/, long long a)
186 {
188  return std::abs(a);
189 }
190 
192 iparser_call_f2 (enum iparser_f2_t type, long long a, long long b)
193 {
194  switch (type) {
195  case IPARSER_FLRDIV:
196  {
197  long long r = a/b;
198  if (r*b == a || (a < 0 && b < 0) || (a > 0 && b > 0)) {
199  return r;
200  } else {
201  return r-1;
202  }
203  }
204  case IPARSER_POW:
205  {
206  if (b < 0) {
207  return 0;
208  } else {
209  long long r = 1;
210  while (b != 0) {
211  if (b & 1) {
212  r *= a;
213  }
214  b >>= 1;
215  if (b > 0) { a *= a; } // to avoid overflow
216  }
217  return r;
218  }
219  }
220  case IPARSER_GT:
221  return (a > b) ? 1 : 0;
222  case IPARSER_LT:
223  return (a < b) ? 1 : 0;
224  case IPARSER_GEQ:
225  return (a >= b) ? 1 : 0;
226  case IPARSER_LEQ:
227  return (a <= b) ? 1 : 0;
228  case IPARSER_EQ:
229  return (a == b) ? 1 : 0;
230  case IPARSER_NEQ:
231  return (a != b) ? 1 : 0;
232  case IPARSER_AND:
233  return ((a != 0) && (b != 0)) ? 1 : 0;
234  case IPARSER_OR:
235  return ((a != 0) || (b != 0)) ? 1 : 0;
236  case IPARSER_MIN:
237  return (a < b) ? a : b;
238  case IPARSER_MAX:
239  return (a > b) ? a : b;
240  default:
241  amrex::Abort("iparser_call_f2: Unknown function");
242  return 0;
243  }
244 }
245 
247 iparser_call_f3 (enum iparser_f3_t /*type*/, long long a, long long b, long long c)
248 {
249  // There is only one type currently
250  return (a != 0) ? b : c;
251 }
252 
253 long long iparser_atoll (const char* str);
254 
255 }
256 
257 #endif
#define AMREX_FORCE_INLINE
Definition: AMReX_Extension.H:119
#define AMREX_GPU_HOST_DEVICE
Definition: AMReX_GpuQualifiers.H:20
void amrex_iparsererror(char const *s,...)
Definition: AMReX_IParser_Y.cpp:10
Print on all processors of the default communicator.
Definition: AMReX_Print.H:117
Definition: AMReX_Amr.cpp:49
struct iparser_node * iparser_newf3(enum iparser_f3_t ftype, struct iparser_node *n1, struct iparser_node *n2, struct iparser_node *n3)
Definition: AMReX_IParser_Y.cpp:90
struct iparser_node * iparser_newnumber(long long d)
Definition: AMReX_IParser_Y.cpp:54
struct iparser_node * iparser_newf2(enum iparser_f2_t ftype, struct iparser_node *l, struct iparser_node *r)
Definition: AMReX_IParser_Y.cpp:79
struct iparser_node * iparser_newf1(enum iparser_f1_t ftype, struct iparser_node *l)
Definition: AMReX_IParser_Y.cpp:69
void iparser_print(struct amrex_iparser *iparser)
Definition: AMReX_IParser_Y.cpp:1406
void iparser_ast_print(struct iparser_node *node, std::string const &space, AllPrint &printer)
Definition: AMReX_IParser_Y.cpp:1064
std::set< std::string > iparser_get_symbols(struct amrex_iparser *iparser)
Definition: AMReX_IParser_Y.cpp:1413
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE long long iparser_call_f1(enum iparser_f1_t, long long a)
Definition: AMReX_IParser_Y.H:185
long long iparser_atoll(const char *str)
Definition: AMReX_IParser_Y.cpp:1431
struct amrex_iparser * amrex_iparser_new()
Definition: AMReX_IParser_Y.cpp:129
void iparser_ast_setconst(struct iparser_node *node, char const *name, long long c)
Definition: AMReX_IParser_Y.cpp:1283
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE T abs(const GpuComplex< T > &a_z) noexcept
Return the absolute value of a complex number.
Definition: AMReX_GpuComplex.H:356
int iparser_ast_depth(struct iparser_node *node)
Definition: AMReX_IParser_Y.cpp:1162
iparser_f1_t
Definition: AMReX_IParser_Y.H:22
@ IPARSER_ABS
Definition: AMReX_IParser_Y.H:23
struct iparser_node * iparser_newnode(enum iparser_node_t type, struct iparser_node *l, struct iparser_node *r)
Definition: AMReX_IParser_Y.cpp:44
struct iparser_node * iparser_ast_dup(struct amrex_iparser *my_iparser, struct iparser_node *node, int move)
Definition: AMReX_IParser_Y.cpp:259
void amrex_iparser_delete(struct amrex_iparser *iparser)
Definition: AMReX_IParser_Y.cpp:149
void iparser_ast_optimize(struct iparser_node *node)
Definition: AMReX_IParser_Y.cpp:384
struct iparser_node * iparser_newlist(struct iparser_node *nl, struct iparser_node *nr)
Definition: AMReX_IParser_Y.cpp:113
std::size_t iparser_ast_size(struct iparser_node *node)
Definition: AMReX_IParser_Y.cpp:190
void iparser_ast_get_symbols(struct iparser_node *node, std::set< std::string > &symbols, std::set< std::string > &local_symbols)
Definition: AMReX_IParser_Y.cpp:1338
iparser_f2_t
Definition: AMReX_IParser_Y.H:26
@ IPARSER_LT
Definition: AMReX_IParser_Y.H:30
@ IPARSER_GT
Definition: AMReX_IParser_Y.H:29
@ IPARSER_POW
Definition: AMReX_IParser_Y.H:28
@ IPARSER_FLRDIV
Definition: AMReX_IParser_Y.H:27
@ IPARSER_AND
Definition: AMReX_IParser_Y.H:35
@ IPARSER_OR
Definition: AMReX_IParser_Y.H:36
@ IPARSER_MAX
Definition: AMReX_IParser_Y.H:38
@ IPARSER_EQ
Definition: AMReX_IParser_Y.H:33
@ IPARSER_MIN
Definition: AMReX_IParser_Y.H:37
@ IPARSER_GEQ
Definition: AMReX_IParser_Y.H:31
@ IPARSER_LEQ
Definition: AMReX_IParser_Y.H:32
@ IPARSER_NEQ
Definition: AMReX_IParser_Y.H:34
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE long long iparser_call_f2(enum iparser_f2_t type, long long a, long long b)
Definition: AMReX_IParser_Y.H:192
struct iparser_node * iparser_newassign(struct iparser_symbol *sym, struct iparser_node *v)
Definition: AMReX_IParser_Y.cpp:103
void iparser_regvar(struct amrex_iparser *iparser, char const *name, int i)
Definition: AMReX_IParser_Y.cpp:1393
void iparser_setconst(struct amrex_iparser *iparser, char const *name, long long c)
Definition: AMReX_IParser_Y.cpp:1399
struct iparser_symbol * iparser_makesymbol(char *name)
Definition: AMReX_IParser_Y.cpp:34
void iparser_defexpr(struct iparser_node *body)
Definition: AMReX_IParser_Y.cpp:28
void iparser_ast_regvar(struct iparser_node *node, char const *name, int i)
Definition: AMReX_IParser_Y.cpp:1219
int iparser_depth(struct amrex_iparser *iparser)
Definition: AMReX_IParser_Y.cpp:1425
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE long long iparser_call_f3(enum iparser_f3_t, long long a, long long b, long long c)
Definition: AMReX_IParser_Y.H:247
struct amrex_iparser * iparser_dup(struct amrex_iparser *source)
Definition: AMReX_IParser_Y.cpp:177
void Abort(const std::string &msg)
Print out message to cerr and exit via abort().
Definition: AMReX.cpp:225
iparser_node_t
Definition: AMReX_IParser_Y.H:45
@ IPARSER_ADD_PP
Definition: AMReX_IParser_Y.H:59
@ IPARSER_MUL_PP
Definition: AMReX_IParser_Y.H:63
@ IPARSER_NEG_P
Definition: AMReX_IParser_Y.H:67
@ IPARSER_ASSIGN
Definition: AMReX_IParser_Y.H:56
@ IPARSER_SUB
Definition: AMReX_IParser_Y.H:49
@ IPARSER_DIV_VP
Definition: AMReX_IParser_Y.H:64
@ IPARSER_DIV_PV
Definition: AMReX_IParser_Y.H:65
@ IPARSER_F1
Definition: AMReX_IParser_Y.H:53
@ IPARSER_NUMBER
Definition: AMReX_IParser_Y.H:46
@ IPARSER_ADD_VP
Definition: AMReX_IParser_Y.H:58
@ IPARSER_SUB_PP
Definition: AMReX_IParser_Y.H:61
@ IPARSER_F3
Definition: AMReX_IParser_Y.H:55
@ IPARSER_SUB_VP
Definition: AMReX_IParser_Y.H:60
@ IPARSER_LIST
Definition: AMReX_IParser_Y.H:57
@ IPARSER_NEG
Definition: AMReX_IParser_Y.H:52
@ IPARSER_ADD
Definition: AMReX_IParser_Y.H:48
@ IPARSER_DIV_PP
Definition: AMReX_IParser_Y.H:66
@ IPARSER_F2
Definition: AMReX_IParser_Y.H:54
@ IPARSER_MUL_VP
Definition: AMReX_IParser_Y.H:62
@ IPARSER_DIV
Definition: AMReX_IParser_Y.H:51
@ IPARSER_MUL
Definition: AMReX_IParser_Y.H:50
@ IPARSER_SYMBOL
Definition: AMReX_IParser_Y.H:47
struct iparser_node * iparser_newsymbol(struct iparser_symbol *symbol)
Definition: AMReX_IParser_Y.cpp:63
iparser_f3_t
Definition: AMReX_IParser_Y.H:41
@ IPARSER_IF
Definition: AMReX_IParser_Y.H:42
Definition: AMReX_IParser_Y.H:153
struct iparser_node * ast
Definition: AMReX_IParser_Y.H:156
std::size_t sz_mempool
Definition: AMReX_IParser_Y.H:157
void * p_root
Definition: AMReX_IParser_Y.H:154
void * p_free
Definition: AMReX_IParser_Y.H:155
Definition: AMReX_IParser_Y.H:122
struct iparser_node * v
Definition: AMReX_IParser_Y.H:125
enum iparser_node_t type
Definition: AMReX_IParser_Y.H:123
struct iparser_symbol * s
Definition: AMReX_IParser_Y.H:124
Definition: AMReX_IParser_Y.H:101
struct iparser_node * l
Definition: AMReX_IParser_Y.H:103
enum iparser_f1_t ftype
Definition: AMReX_IParser_Y.H:104
enum iparser_node_t type
Definition: AMReX_IParser_Y.H:102
Definition: AMReX_IParser_Y.H:107
struct iparser_node * r
Definition: AMReX_IParser_Y.H:110
struct iparser_node * l
Definition: AMReX_IParser_Y.H:109
enum iparser_node_t type
Definition: AMReX_IParser_Y.H:108
enum iparser_f2_t ftype
Definition: AMReX_IParser_Y.H:111
Definition: AMReX_IParser_Y.H:114
enum iparser_node_t type
Definition: AMReX_IParser_Y.H:115
struct iparser_node * n3
Definition: AMReX_IParser_Y.H:118
enum iparser_f3_t ftype
Definition: AMReX_IParser_Y.H:119
struct iparser_node * n1
Definition: AMReX_IParser_Y.H:116
struct iparser_node * n2
Definition: AMReX_IParser_Y.H:117
Definition: AMReX_IParser_Y.H:82
struct iparser_node * l
Definition: AMReX_IParser_Y.H:84
struct iparser_node * r
Definition: AMReX_IParser_Y.H:85
union iparser_nvp lvp
Definition: AMReX_IParser_Y.H:86
int rip
Definition: AMReX_IParser_Y.H:87
enum iparser_node_t type
Definition: AMReX_IParser_Y.H:83
Definition: AMReX_IParser_Y.H:90
long long value
Definition: AMReX_IParser_Y.H:92
enum iparser_node_t type
Definition: AMReX_IParser_Y.H:91
Definition: AMReX_IParser_Y.H:95
int ip
Definition: AMReX_IParser_Y.H:98
char * name
Definition: AMReX_IParser_Y.H:97
enum iparser_node_t type
Definition: AMReX_IParser_Y.H:96
Definition: AMReX_IParser_Y.H:76
long long v
Definition: AMReX_IParser_Y.H:78
struct iparser_node * n
Definition: AMReX_IParser_Y.H:77
int ip
Definition: AMReX_IParser_Y.H:79