00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #ifndef PLINT_PARSE_STACK_H
00028 #define PLINT_PARSE_STACK_H
00029
00030 #ifndef PLINT_PLINT_H
00031 #error Malpractice.
00032 #endif
00033
00039 #include "prog/type.h"
00040 #include "prog/action.h"
00041 #include "prog/iterate.h"
00042 #include "prog/index.h"
00043
00046 typedef struct _plint_pse * plint_pse_t;
00047
00048
00049
00051 typedef enum
00052 {
00053
00054 PLINT_PST_var,
00055 PLINT_PST_ref,
00056 PLINT_PST_mem,
00057 PLINT_PST_asg,
00058 PLINT_PST_iix,
00059 PLINT_PST_idx,
00061 PLINT_PST_str,
00062 PLINT_PST_tab,
00063 PLINT_PST_hsh,
00065 PLINT_PST_val,
00067 PLINT_PST_range,
00069 PLINT_PST_cal,
00071 PLINT_PST_act,
00073 PLINT_PST_ite,
00075 PLINT_PST_yyc,
00076 PLINT_PST_ope,
00078 PLINT_PST_ptr,
00079 PLINT_PST_own,
00081 PLINT_PST_pst,
00083 } plint_pst_type_t;
00084
00085
00087 typedef struct _plint_pst
00088 {
00089
00090 plint_pst_type_t type;
00091 plint_pse_t head;
00092 size_t n;
00093 plint_pse_t _p;
00095 #define PLINT_STACK_SIZE(__stack__) (plint->stack.__stack__##s.n)
00096 #define PLINT_STACK_EMPTY(__stack__) (!PLINT_STACK_SIZE(__stack__))
00097 #define PLINT_STACK_TOP(__stack__) (plint->stack.__stack__##s).head->data.__stack__
00098
00099 #define PLINT_STACK_START(__stack__) plint->stack.__stack__##s._p = plint->stack.__stack__##s.head
00100 #define PLINT_STACK_DONE(__stack__) !plint->stack.__stack__##s._p
00101 #define PLINT_STACK_NEXT(__stack__) plint->stack.__stack__##s._p = plint->stack.__stack__##s._p->link
00102 #define PLINT_STACK_DATA(__stack__) plint->stack.__stack__##s._p->data.__stack__
00103
00104 #define PLINT_STACK_PUSH(__stack__, __value__...) \
00105 ({ \
00106 plint_pse_t __p1; \
00107 typeof(__p1->data.__stack__) __temp = __value__; \
00108 NEW(__p1)->data.__stack__ = __temp; \
00109 __p1->link = plint->stack.__stack__##s.head; \
00110 plint->stack.__stack__##s.head = __p1; \
00111 ++plint->stack.__stack__##s.n; \
00112 plint->stack.__stack__##s; \
00113 }) \
00114
00115
00116 #define PLINT_STACK_POP(__stack__) \
00117 ({ \
00118 plint_pse_t __p2 = plint->stack.__stack__##s.head; \
00119 plint->stack.__stack__##s.head = __p2->link; \
00120 --plint->stack.__stack__##s.n; \
00121 FREE(__p2); \
00122 plint->stack.__stack__##s; \
00123 }) \
00124
00125
00126 #define PLINT_STACK_SAVE(__stack__) \
00127 ({ \
00128 plint_pst_t __s1 = plint->stack.__stack__##s; \
00129 PLINT_STACK_PUSH(pst, __s1); \
00130 plint_stacks_clean(&plint->stack.__stack__##s); \
00131 plint->stack.__stack__##s; \
00132 }) \
00133
00134
00135 #define PLINT_STACK_REST(__stack__) \
00136 ({ \
00137 plint_pst_t __s2 = PLINT_STACK_TOP(pst); \
00138 PLINT_STACK_POP(pst); \
00139 assert(plint->stack.__stack__##s.n == 0); \
00140 assert(__s2.type == PLINT_PST_##__stack__); \
00141 plint->stack.__stack__##s = __s2; \
00142 plint->stack.__stack__##s; \
00143 }) \
00144
00145
00146 #define PLINT_STACK_REVERSE(__stack__) \
00147 ({ \
00148 plint_pst_t __s3 = plint->stack.__stack__##s; \
00149 plint_stacks_clean(&plint->stack.__stack__##s); \
00150 while (__s3.head) \
00151 { \
00152 plint_pse_t __p3 = __s3.head; \
00153 PLINT_STACK_PUSH(__stack__, __p3->data.__stack__); \
00154 __s3.head = __p3->link; \
00155 free(__p3); \
00156 } \
00157 plint->stack.__stack__##s; \
00158 }) \
00159
00160 #define PLINT_STACK_FREE(__stack__) plint_stacks_free(&plint->stack.__stack__##s)
00161 #define PLINT_STACK_CLEAN(__stack__) plint_stacks_clean(&plint->stack.__stack__##s)
00162
00163 } plint_pst_t;
00164
00165
00257 struct _plint_pse
00258 {
00260 union
00261 {
00262
00263 plint_var_t var;
00264 plint_ref_t ref;
00265 plint_mem_t mem;
00266 plint_easg_t asg;
00267 struct
00268 {
00269 plint_str_t id;
00270 struct _plint_pst idxs;
00271 } iix;
00272 plint_idxqueue_t idx;
00274 plint_str_t str;
00275 plint_tab_t tab;
00276 plint_hsh_t hsh;
00278 struct
00279 {
00280 plint_typ_t typ;
00281 plint_val_t val;
00282 } val;
00284 plint_range_t range;
00286 int cal;
00288 plint_act_t act;
00289 int yyc;
00291 struct {
00292 int dir;
00293 int op;
00294 } ope;
00295 struct {
00296 plint_itesw_t sw;
00297 plint_ite_t ite;
00298 } ite;
00300 void * ptr;
00301 struct {
00302 void * data;
00303 freefunc_t free;
00304 } own;
00306 plint_pst_t pst;
00308 } data;
00310 plint_pse_t link;
00312 };
00313
00314 __BEGIN_DECLS
00315
00316 void plint_stacks_init();
00317 void plint_stacks_finish();
00318
00319 void plint_stacks_clean(plint_pst_t * st);
00320 void plint_stacks_free(plint_pst_t * st);
00321
00322 __END_DECLS
00323
00326 #endif