C:/Users/Dennis/src/lang/russell.orig/src/stree/ststructs.m

Go to the documentation of this file.
00001 /*
00002  *  Structure declaration macros for use with streedefs.h
00003  *  and basic structure manipulation primitives.
00004  */
00005 
00006 @ include "datatypes/consnodes.h"
00007 
00008 @ define MAXFIELDS 20 /* maximum number of fields in a node */
00009  
00010 # define TOP \
00011 #   define COUNT 0 \
00012 typedef union Node {
00013 
00014 # define START(knm,snm) \
00015   struct { \
00016 @   define knm COUNT \
00017 #   incr COUNT \
00018 #   define STRUCTURENM snm
00019 
00020 # define FIELD(type, nm) \
00021    type STRUCTURENM^_^nm; \
00022 @ ifndef nm \
00023 @   define nm STRUCTURENM . STRUCTURENM^_^nm \
00024 @ endif @@
00025 
00026 /* A leading H indicates the field is hidden, and not a parameter to mknode */
00027 # define INT(fld) FIELD(int,fld)
00028 # define UNSIGNED(fld) FIELD(unsigned,fld)
00029 # define REFCNT(fld) FIELD(unsigned,fld)
00030 # define NODEKIND(fld) FIELD(int,fld)
00031 # define NODESTAR(fld) FIELD(union Node *,fld)
00032 # define HNODESTAR(fld) FIELD(union Node *,fld)
00033 # define SIG(fld) FIELD(union Node *,fld)
00034 # define HSIG(fld) FIELD(union Node *,fld)
00035 # define VLINENO(fld) UNSIGNED(fld)
00036 # define STTINDX(fld) UNSIGNED(fld)
00037 # define LISTPTR(fld) NODESTAR(fld)
00038 # define HLISTPTR(fld) NODESTAR(fld)
00039 # define LBACKREF(fld) NODESTAR(fld)
00040 # define BACKREF(fld) NODESTAR(fld)
00041 # define CNSTAR(fld) FIELD(ConsNode *,fld)
00042 # define STRPTR(fld) FIELD(char *,fld)
00043 # define HSTRPTR(fld) FIELD(char *,fld)
00044 # define BITVECTOR(fld) UNSIGNED(fld)
00045 # define NBPTR(fld) NODESTAR(fld)
00046 
00047 # define FINISH } STRUCTURENM;
00048 
00049 # define BOTTOM \
00050 # decr COUNT \
00051     char Node_dummy[10000000];  /* Make anything that relies on  */ \
00052                                 /* sizeof(NODE) break.          */ \
00053 } NODE; \
00054 @ define LASTKINDVALUE COUNT \
00055 
00056 
00057 @define NIL 0
00058 @define LIST NODE *
00059 
00060 # include "streedefs.h"
00061 
00062 /* definitions for sig_done field (used by pass 4) */
00063 @   define SIG_UNKNOWN 0
00064 @   define SIG_IN_PROGRESS 1
00065 @   define SIG_DONE 2
00066 
00067 /* definitions for fsig_special field (used for code generation) */
00068 @   define NOT_SPECIAL 0
00069 @   define PROD_NEW 1
00070 @   define PROD_ASSIGN 2
00071 @   define PROD_VALUEOF 3
00072 @   define PROD_MK 4
00073 @   define PROD_PROJ 5
00074 @   define UNION_NEW 6
00075 @   define UNION_ASSIGN 7
00076 @   define UNION_VALUEOF 8
00077 @   define UNION_INJ 9
00078 @   define UNION_PROJ 10
00079 @   define UNION_INQ 11
00080 @   define RECORD_NEW 12
00081 @   define RECORD_ASSIGN 13
00082 @   define RECORD_VALUEOF 14
00083 @   define RECORD_MK 15
00084 @   define RECORD_VAL_FIELD 16
00085 @   define RECORD_VAR_FIELD 17
00086 @   define ENUM_NEW 18
00087 @   define ENUM_ASSIGN 19
00088 @   define ENUM_VALUEOF 20
00089 @   define ENUM_EQ 21
00090 @   define ENUM_NE 22
00091 @   define ENUM_ELEMENT 23   /* Also used for First, Last */
00092 @   define ENUM_CARD 24
00093 @   define ENUM_PRED 25
00094 @   define ENUM_SUCC 26
00095 @   define IDENTITY 27        /* Used for extension, Ord and OrdInv */
00096 @   define STD_ASSIGN 28    /* Value is # of longwords to copy */
00097 @   define STD_NEW 29       /* Value is # of longwords to allocate */
00098 @   define STD_VALUEOF 30   /* Value is # of longwords to allocate */
00099 @   define STD_PUT 31   /* Not impure, put writes */
00100 @   define STD_CALLCC 32  /* Callcc, all bets are off */
00101 @   define STD_ARRAY 33   /* Behaves like builtin array function */
00102 @   define ARRAY_STD_NEW 34  /* Array New function, initialized to 0's   */
00103                              /* Value is size of Array, 0 if unknown     */
00104 @   define ARRAY_PTR_NEW 35  /* Array New function, initialized to undef */
00105 @   define ARRAY_VALUEOF 36  /* Array Valueof, components var's are ptrs */
00106                              /* to size 1 objects.                       */
00107 @   define ARRAY_SIZE 37
00108 @   define ARRAY_VAL_SUB 38
00109 @   define ARRAY_VAR_SUB 39
00110 @   define PTR_NEW 40        /* Works like PROD_NEW, etc */
00111 @   define INIT_NEW 41       /* New with an argument for initialization */
00112 @   define OTHER_BUILTIN 42  /* Known to be builtin, not PUT ot CALLCC */
00113 @   define STD_PASSIGN 43    /* Behaves like Short$+= */
00114 @   define STD_MASSIGN 44    /* Behaves like Short$-= */
00115 @   define STD_TASSIGN 45    /* Behaves like Short$*= */
00116 @   define UNDEF_CONST 46    /* Returns the value UNINIT */
00117 @   define UNION_INJ0  47    /* Union inject without argument */
00118 
00119 @   define special_tp(x)  (((unsigned long)(x)) >> 26)
00120 @   define special_val(x)  ((x) & 0x3ffffff)
00121 
00122 @   define MAX_SP_VAL 0x3ffffff
00123 
00124 @ ifdef DEBUG
00125 @   define special(tp,val)  ((val) > 0x3ffffff? \
00126                              printf("Compiler error - prod too big\n") : \
00127                              ((tp) << 26) | (val) )
00128 @ else
00129 @   define special(tp,val)  (((tp) << 26) | (val))
00130 @ endif
00131 
00132 @define is_good(l) ((l) == NIL || \
00133      ((unsigned) ((l)->kind)) <= LASTKINDVALUE) /* is l possibly meaningful ? */
00134 @define is_list(l) ((l) != NIL && \
00135                     (l)->kind == LISTHEADER)    /* is l a list? */
00136 @define is_empty(l) ((l)->lh_first == NIL)      /* is l an empty list? */
00137 @define is_singleref(v) ((v) -> refcount == 1)  /* is v only referenced once? */
00138 @define is_refd(v) ((v) -> refcount)            /* is v referenced at all? */
00139 @define first(l) ((NODE *)cn_head((l)->lh_first))       /* return first element of l */
00140 @define second(l) ((NODE *)cn_head(cn_tail((l)->lh_first)))
00141                                                 /* return second element of l */
00142 @define last(l) ((NODE *)cn_head((l)->lh_last))         /* return last element of l */
00143 @define emptylist() mknode(LISTHEADER,NIL,NIL)  /* make an empty list */
00144 @define chgfld(pp, v) (*(pp) = (v))
00145 @define initfld(pp, v) (*(pp) = (v))
00146 
00147 void maprlist();                                /* defined in mknode.c */
00148 NODE * mknode();                                                          /* defined in mknode.c */
00149 NODE * copynode();
00150 LIST mklist();
00151 LIST copylist();
00152 LIST addright();
00153 LIST addleft();
00154 LIST split();
00155 LIST conc();
00156 
00157 /* general list traversal */
00158 /* macros - use only when */
00159 /* nothing else will work */
00160 /* Assumes the list l is  */
00161 /* nonempty.              */
00162 @define DECLARE_ITER ConsNode * mL__0O
00163 @define INIT_ITER(v,l) mL__0O = (l) -> lh_first; v = (NODE *)cn_head(mL__0O)
00164 @define NEXT_ITER(v)   \
00165     mL__0O = cn_tail(mL__0O); \
00166     v = (mL__0O == NIL? NIL: (NODE *) cn_head(mL__0O))
00167 
00168 /* Run v through l executing */
00169 /* stmt for every value of l */
00170 @define maplist(v,l,stmt) \
00171 {   register NODE * v; \
00172     register ConsNode * mL__0O;  /* an unreproducible identifier */ \
00173     for(mL__0O = ((l) -> lh_first); mL__0O != NIL; mL__0O = cn_tail(mL__0O) ) {\
00174         v = (NODE *) cn_head(mL__0O); \
00175         stmt; \
00176     } \
00177 }
00178 
00179 /* identical to maplist, except that v is a pointer to the pointer */
00180 /* to the current node.  Allows easy replacement of list elements. */
00181 @define maplistp(v,l,stmt) \
00182 {   register NODE ** v; \
00183     register ConsNode * mL__0O;  /* an unreproducible identifier */ \
00184     for(mL__0O = ((l) -> lh_first); mL__0O != NIL; mL__0O = cn_tail(mL__0O) ) {\
00185         v = (NODE **)(& cn_head(mL__0O)); \
00186         stmt; \
00187     } \
00188 }
00189 
00190 /* Can be used inside the preceding macro to determine whether this is */
00191 /* the last iteration                                                  */
00192 @define LAST_ITER (cn_tail(mL__0O) == NIL)
00193 
00194                                                 /* A two part version. Needed */
00195                                                 /* since cpp chokes on long   */
00196                                                 /* arguments.                 */
00197 @define begin_maplist(v,l) \
00198 {   register NODE * v; \
00199     register ConsNode * mL__0O;  /* an unreproducible identifier */ \
00200     for(mL__0O = ((l) -> lh_first); mL__0O != NIL; mL__0O = cn_tail(mL__0O) ) {\
00201         v = (NODE *) cn_head(mL__0O);
00202 
00203 @define end_maplist \
00204     } \
00205 }
00206 
00207 
00208 
00209                                                 /* insert a new element into */
00210                                                 /* the list being traversed  */
00211                                                 /* by maplist.               */
00212                                                 /* The element is inserted   */
00213                                                 /* before the current element*/
00214                                                 /* must be used with         */
00215                                                 /* mapinslist                */
00216 @define INSERT(v) \
00217 lock(v); \
00218 if (mL__0OP == NIL) { \
00219     mL__0OL -> lh_first = mL__0OP = cn_cons(v, mL__0OL -> lh_first); \
00220 } else { \
00221     cn_settail(mL__0OP, cn_cons(v, mL__0O)); \
00222     mL__0OP = cn_tail(mL__0OP); \
00223 } \
00224 if (mL__0O == NIL) mL__0OL -> lh_last = mL__0OP;
00225 
00226 
00227                                                 /* Replace the current list  */
00228                                                 /* element by v              */
00229 @define REPLACE(v) \
00230 lock(v);  \
00231 vfree(unlock((NODE *) cn_head(mL__0O))); \
00232 cn_sethead(mL__0O, v);
00233 
00234                                                 /* delete current element    */
00235                                                 /* use with mapinslist       */
00236                                                 /* No attempt is made to free*/
00237                                                 /* cons nodes                */
00238 @ifdef DEBUG
00239 @ define DELETE \
00240     if (mL__0O == NIL) { \
00241         dbgmsg("Attempt to delete NIL\n"); \
00242         abort(); \
00243     } \
00244     vfree(unlock((NODE *) cn_head(mL__0O))); \
00245     if (mL__0OP == NIL) { \
00246         mL__0OL -> lh_first = cn_tail(mL__0O); \
00247     } else { \
00248         cn_settail(mL__0OP, cn_tail(mL__0O)); \
00249     } \
00250     if (mL__0OL -> lh_last == mL__0O) { \
00251         mL__0OL -> lh_last = mL__0OP; \
00252     } \
00253     mL__0Odeld = TRUE
00254 @else
00255 @  define DELETE \
00256     vfree(unlock((NODE *) cn_head(mL__0O))); \
00257     if (mL__0OP == NIL) { \
00258         mL__0OL -> lh_first = cn_tail(mL__0O); \
00259     } else { \
00260         cn_settail(mL__0OP, cn_tail(mL__0O)); \
00261     } \
00262     if (mL__0OL -> lh_last == mL__0O) { \
00263         mL__0OL -> lh_last = mL__0OP; \
00264     } \
00265     mL__0Odeld = TRUE
00266 @endif
00267 
00268                                                 /* Note that the following   */
00269                                                 /* loop construct is intended*/
00270                                                 /* only for insertions and   */
00271                                                 /* deletions. It             */
00272                                                 /* includes a final iteration*/
00273                                                 /* with a NIL loop variable  */
00274                                                 /* to allow insertions at the*/
00275                                                 /* end.                      */
00276 @define mapinslist(v,l,stmt) \
00277 {   register NODE * v; \
00278     register ConsNode * mL__0O;  /* an unreproducible identifier */ \
00279     NODE * mL__0OL = (l); \
00280     ConsNode * mL__0OP = NIL; \
00281     boolean mL__0Odeld = FALSE; \
00282     mL__0O = ((l) -> lh_first); \
00283     do { \
00284         if (mL__0O != NIL) v = (NODE *) cn_head(mL__0O); else v = NIL; \
00285         stmt; \
00286         if(!mL__0Odeld) {mL__0OP = mL__0O;} else {mL__0Odeld = FALSE;} \
00287         if (mL__0O != NIL) mL__0O = cn_tail(mL__0O); \
00288     } while (mL__0OP != NIL); \
00289 }
00290 
00291 @define map2lists(v1,l1,v2,l2,stmt) \
00292 {   register NODE * v1, * v2; \
00293         register ConsNode * mL__1O, * mL__2O;  /* unreproducible identifiers */ \
00294         for(mL__1O = ((l1) -> lh_first), mL__2O = ((l2) -> lh_first);\
00295                 mL__1O != NIL && mL__2O != NIL;\
00296                 mL__1O = cn_tail(mL__1O), mL__2O = cn_tail(mL__2O) ) {\
00297                 v1 = (NODE *) cn_head(mL__1O); v2 = (NODE *) cn_head(mL__2O); \
00298         stmt; \
00299     } \
00300 }
00301 
00302 @define begin_map2lists(v1,l1,v2,l2) \
00303 {   register NODE * v1, * v2; \
00304         register ConsNode * mL__1O, * mL__2O;  /* unreproducible identifiers */ \
00305         for(mL__1O = ((l1) -> lh_first), mL__2O = ((l2) -> lh_first);\
00306                 mL__1O != NIL && mL__2O != NIL;\
00307                 mL__1O = cn_tail(mL__1O), mL__2O = cn_tail(mL__2O) ) {\
00308                 v1 = (NODE *) cn_head(mL__1O); v2 = (NODE *) cn_head(mL__2O);
00309 
00310 @define end_map2lists \
00311     } \
00312 }
00313 
00314 /* check whether an identifier is declared by a given declaration node */
00315 @define is_declared_by(id_node, def_node)   \
00316     ((id_node) -> id_last_definition -> pre_num == (def_node) -> pre_num)
00317 

Generated on Fri Jan 25 10:39:48 2008 for russell by  doxygen 1.5.4