Main Page   Modules   Alphabetical List   Data Structures   File List   Data Fields   Globals  

stack.h

00001  /*
00002   * plint/parse/stack.h: parsing stack -  because on errors / exceptions i don't
00003   * have access to bison's parser stack and cannot `destroy' accumulated data
00004   * (in the case of an unexpected event that let's me go on to next input file)
00005   * 
00006   * Time-stamp: <2002-12-21 14:40:03 gseba>
00007   * 
00008   * Copyright (C) Sebastian Glita, email: gseba@users.sourceforge.net
00009   * 
00010   * This file is part of plint.
00011   * 
00012   * plint is free software; you can  redistribute it and/or modify it under the
00013   * terms of the  GNU General Public License as published  by the Free Software
00014   * Foundation; either version 2, or (at your option) any later version.
00015   *
00016   * plint  is distributed  in the  hope  that it  will be  useful, but  WITHOUT
00017   * ANY  WARRANTY; without  even  the implied  warranty  of MERCHANTABILITY  or
00018   * FITNESS FOR A  PARTICULAR PURPOSE.  See the GNU  General Public License for
00019   * more details.
00020   * 
00021   * You should  have received a  copy of the  GNU General Public  License along
00022   * with  plint; see  the file  COPYING.  If  not, write  to the  Free Software
00023   * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA USA.
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; /* forward */
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

Generated on Thu Jan 9 19:02:39 2003 for plint by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002