Polaris: ExprTable.cc Source File

ExprTable.cc

Go to the documentation of this file.
00001 ///
00002 #ifdef POLARIS_GNU_PRAGMAS
00003 #pragma implementation
00004 #endif
00005 ///
00006 #include <iostream.h>
00007 
00008 #include "BinRep.h"
00009 #include "String.h"
00010 
00011 #include "Collection/List.h"
00012 #include "Collection/Iterator.h"
00013 
00014 #include "Expression/Expression.h"
00015 #include "Expression/Expression.all.h"
00016 
00017 #include "ExprTable.h"
00018 
00019 #include "p-assert.h"
00020 
00021 /// Bounds checks if n is within the proper bounds
00022 
00023 
00024 ExprTable::~ExprTable() 
00025 {
00026 ///  boolean all_deleted = true;
00027 
00028   for (int i = 0; i<_size + 1; i++)
00029     {
00030       if (!_final[i])
00031     delete _table[i];
00032       else
00033     _table[i] = NULL;
00034     }
00035   delete [] _table;
00036   delete [] _final;
00037   _size = 0;
00038   _table = NULL;
00039   _final = NULL;
00040 }
00041 
00042 int 
00043 ExprTable::bounds(int n) const
00044 {
00045     if ((n > 0) && (n <= _size))
00046         return 1;
00047     cerr << "ExprTable: ExprTable[" 
00048          << n << "] out of range: 1.." << _size << endl;
00049 
00050     return 0;
00051 }
00052 
00053 /// get_expr_obj takes a string indicating the operator type of an expression.
00054 /// It returns the correct object for that expression type with the expr.op
00055 /// field set.  If the data-type of the expression is not immediately apparent
00056 /// it is set to a default  (usually INTEGER_TYPE)
00057 
00058 Expression     *
00059 ExprTable::get_expr_obj(const String & s)
00060 {
00061     Expression     *e;
00062 
00063     if (s == "INTEGER_CONSTANT")
00064         return (e = new IntConstExpr(0));
00065     else if (s == "REAL_CONSTANT")
00066         return (e = new RealConstExpr(REAL_TYPE,"0.0"));
00067     else if (s == "STRING_CONSTANT")
00068         return (e = new StringConstExpr(""));
00069     else if (s == "LOGICAL_CONSTANT")
00070         return (e = new LogicalConstExpr(""));
00071     else if (s == "KEY")
00072         return (e = new KeyExpr(""));
00073     else if (s == "HOLLERITH_CONSTANT")
00074         return (e = new HollerithConstExpr(""));
00075     else if (s == "COMPLEX")
00076         return (e = new ComplexExpr(new RealConstExpr(REAL_TYPE,"0.0"),
00077                                     new RealConstExpr(REAL_TYPE,"0.0")));
00078     else if (s == "ARRAY_REF")
00079         return (e = new ArrayRefExpr(INTEGER_TYPE));
00080     else if (s == "SUBSTRING")
00081         return (e = new SubStringExpr(make_type(CHARACTER_TYPE)));
00082     else if (s == "FUNCTION_CALL")
00083         return (e = new FunctionCallExpr(INTEGER_TYPE));
00084     else if (s == "INTRINSIC_CALL")
00085         return (e = new IntrinsicCallExpr(INTEGER_TYPE));
00086     else if (s == "LAMBDA_CALL")
00087         return (e = new LambdaCallExpr(INTEGER_TYPE));
00088     else if (s == "ARG#")
00089         return (e = new ArgNumberExpr(INTEGER_TYPE));
00090     else if (s == "RETURN*")
00091         return (e = new ReturnStarExpr);
00092     else if (s == "LABEL") {
00093       p_abort( "Internal Error: The conversion of a binstring to an "
00094                "Expression came across an old \"label\" op, which was "
00095                "believed to no longer be attainable outside of the "
00096                "scanner.  Please report this bug to the development "
00097                "group.  To the development group:  See the comments "
00098                "in the LabelExpr::convert() routine.");
00099       return 0;
00100     }
00101     else if (s == "IO*")
00102         return (e = new IOStarExpr);
00103     else if (s == "ID")
00104         return (e = new IDExpr(INTEGER_TYPE));
00105     else if (s == "U+")
00106         return (e = new UnaryExpr(U_PLUS_OP, INTEGER_TYPE));
00107     else if (s == "U-")
00108         return (e = new UnaryExpr(U_MINUS_OP, INTEGER_TYPE));
00109     else if (s == "()")
00110         return (e = new UnaryExpr(PAREN_OP, INTEGER_TYPE));
00111     else if (s == ".NOT.")
00112         return (e = new UnaryExpr(NOT_OP, INTEGER_TYPE));
00113     else if (s == ".EQ.")
00114         return (e = new BinaryExpr(EQ_OP, INTEGER_TYPE));
00115     else if (s == ".NE.")
00116         return (e = new BinaryExpr(NE_OP, INTEGER_TYPE));
00117     else if (s == ".LT.")
00118         return (e = new BinaryExpr(LT_OP, INTEGER_TYPE));
00119     else if (s == ".LE.")
00120         return (e = new BinaryExpr(LE_OP, INTEGER_TYPE));
00121     else if (s == ".GT.")
00122         return (e = new BinaryExpr(GT_OP, INTEGER_TYPE));
00123     else if (s == ".GE.")
00124         return (e = new BinaryExpr(GE_OP, INTEGER_TYPE));
00125     else if (s == "-")
00126         return (e = new BinaryExpr(SUB_OP, INTEGER_TYPE));
00127     else if (s == "/")
00128         return (e = new BinaryExpr(DIV_OP, INTEGER_TYPE));
00129     else if (s == "**")
00130         return (e = new BinaryExpr(EXP_OP, INTEGER_TYPE));
00131     else if (s == "/// ... ")
00132         return (e = new NonBinaryExpr(CONCAT_OP, INTEGER_TYPE));
00133     else if (s == "KEYPAIR")
00134         return (e = new BinaryExpr(KEYPAIR_OP, UNKNOWN_TYPE));
00135     else if (s == ".OR.")
00136         return (e = new NonBinaryExpr(OR_OP, INTEGER_TYPE));
00137     else if (s == ".AND.")
00138         return (e = new NonBinaryExpr(AND_OP, INTEGER_TYPE));
00139     else if (s == ".EQV.")
00140         return (e = new NonBinaryExpr(EQV_OP, INTEGER_TYPE));
00141     else if (s == ".NEQV.")
00142         return (e = new NonBinaryExpr(NEQV_OP, INTEGER_TYPE));
00143     else if (s == "+")
00144         return (e = new NonBinaryExpr(ADD_OP, INTEGER_TYPE));
00145     else if (s == "*")
00146         return (e = new NonBinaryExpr(MULT_OP, INTEGER_TYPE));
00147     else if (s == ",")
00148         return (e = new CommaExpr);
00149     else if (s == "DO")
00150         return (e = new DoExpr);
00151     else if (s == "=")
00152         return (e = new EqualExpr(INTEGER_TYPE));
00153     else if (s == ":")
00154         return (e = new NonBinaryExpr(COLON_OP, VOID_TYPE));
00155     else if (s == "REP*")
00156         return (e = new BinaryExpr(REPSTAR_OP, INTEGER_TYPE));
00157 
00158     cerr << "get_expr_obj: Unidentified op type: " << s << endl;
00159     return NULL;
00160 }
00161 
00162 
00163 
00164 /// ////////////// **** get_table **** /////////////////////////////////
00165 ///
00166 /// get_table takes a BinRep which should
00167 /// be a tuple of Expression sets.  get_table fills in the expr. table with
00168 /// the intermediate form of the expression table and returns the
00169 /// number of filled entries in exprtable.
00170 
00171 void 
00172 ExprTable::get_table(const BinRep &bs, Symtab & symtab)
00173 {
00174 
00175     int             count = 0;  /// ...  the current expression number
00176 
00177     if (! bs.is_tuple()) {
00178         cerr << "ExprTable::get_table's "
00179              << "bin-string is not a proper expression table\n";
00180         return;
00181     }
00182 
00183     /// ...  iterate through expression sets:
00184 
00185     for (Iterator<BinRep> iter = bs.to_tuple(); iter.valid(); ++iter) {
00186         BinRep & insp = iter.current();
00187 
00188         if (insp.is_omega()) { 
00189             /// ...  it is possible for an expression to be OM.
00190             _table[++count] = new OmegaExpr;
00191         }
00192         else {
00193             if (!insp.is_set()) {
00194                 cerr << "ExprTable::get_table: Set expected\n";
00195                 return;
00196             }
00197 
00198             /// ...  Get the op field
00199 
00200             BinRep data = insp["op"];
00201 
00202             if (data.is_omega()) {
00203                 cerr << "ExprTable::get_table: No op field in expression\n";
00204                 return;
00205             }
00206 
00207             String          data_string;
00208 
00209             data.to_string(data_string);
00210 
00211             Expression     *cur = get_expr_obj(data_string);    
00212             /// ...  get the correct object type
00213 
00214             cur->convert(insp, symtab); 
00215             /// ...  Fill in cur`s data values
00216 
00217             _table[++count] = cur;
00218 
00219             if (count>_size) {
00220                 p_abort( "ExprTable::get_table: "
00221                          "Too many expressions for table size" );
00222             }
00223 
00224             cur = NULL;
00225         }
00226     }
00227 }
00228 
00229 
00230 
00231 /// /////////////////// **** get_expr **** ///////////////////////
00232 ///
00233 /// get_expr takes an integer corresponding to an entry in the
00234 /// expression table, exprtable.  It returns a copy of the
00235 /// complete expression object which contains the complete
00236 /// expression for that entry.  Upon completion, exprtable[entry]
00237 /// also points to the complete expression object corresponding to that entry.
00238 /// The same is true for all of the expression\'s sub-expressions.
00239 
00240 Expression     *
00241 ExprTable::get_expr(int entry)
00242 {
00243     /// ...  if already gotten, return a copy of it
00244 
00245     if (_final[entry] != 0)
00246         return (_table[entry])->clone();
00247 
00248     Expression     *e = _table[entry];  
00249     /// ...  range should already have been checked
00250 
00251     _final[entry] = 1;
00252 
00253     if (!e) {
00254         cerr << "ExprTable::get_expr: _table[entry] not valid\n";
00255         return NULL;
00256     }
00257 
00258     OP_TYPE         op = e->op();
00259 
00260     switch (op) {
00261     /// ...  all cases where exprtable[entry] contains no sub-expresesions so
00262     /// ...  nothing needs to be done.
00263 
00264     case INTEGER_CONSTANT_OP: 
00265     case REAL_CONSTANT_OP:
00266     case STRING_CONSTANT_OP: 
00267     case HOLLERITH_CONSTANT_OP:
00268     case LOGICAL_CONSTANT_OP: 
00269     case LABEL_OP:
00270     case IO_STAR_OP: 
00271     case OMEGA_OP:
00272 
00273     case FORMAT_OP:
00274     case ARG_OP:
00275         break;
00276 
00277     case COMPLEX_OP:
00278         {
00279             Expression     *realp = get_expr(e->real_part().entry());
00280             Expression     *imagp = get_expr(e->imaginary_part().entry());
00281 
00282             e->real_part(realp);
00283             e->imaginary_part(imagp);
00284         }
00285         break;
00286 
00287     case ARRAY_REF_OP:
00288         {
00289             Expression     *ar = get_expr(e->array().entry());
00290 
00291             e->array(ar);
00292             ar = get_expr(e->subscript().entry());
00293             e->subscript(ar);
00294         }
00295         break;
00296 
00297     case SUBSTRING_OP:
00298         {
00299             Expression     *ba = get_expr(e->string().entry());
00300             Expression     *bo = get_expr(e->bound().entry());
00301 
00302             e->string(ba);
00303             e->bound(bo);
00304         }
00305         break;
00306 
00307     case FUNCTION_CALL_OP:
00308         {
00309             Expression     *fun = get_expr(e->function().entry());
00310 
00311             e->function(fun);
00312 
00313             if (e->parameters_valid()) {
00314                 fun = & e->parameters_guarded();
00315                 if (fun->op() != OMEGA_OP)
00316                     fun = get_expr(fun->entry());
00317                 e->parameters(fun);
00318             } 
00319             else {
00320                 e->parameters(new CommaExpr);
00321             }
00322         }
00323         break;
00324 
00325     case INTRINSIC_CALL_OP:
00326         {
00327             Expression     *fun = get_expr(e->intrinsic().entry());
00328 
00329             e->intrinsic(fun);
00330 
00331             if (e->parameters_valid()) {
00332                 fun = get_expr(e->parameters_guarded().entry());
00333                 e->parameters(fun);
00334             }
00335         }
00336         break;
00337 
00338     case LAMBDA_CALL_OP:
00339         {
00340             Expression     *fun = get_expr(e->lambda_expr().entry());
00341 
00342             e->lambda_expr(fun);
00343             fun = get_expr(e->parameters_guarded().entry());
00344             e->parameters(fun);
00345         }
00346         break;
00347 
00348     case RETURN_OP:
00349         {
00350             if (e->expr_valid()) {
00351                 Expression     *ar = get_expr(e->expr_guarded().entry());
00352                 e->expr(ar);
00353             }
00354             else
00355                 e->expr(NULL);
00356         }
00357         break;
00358 
00359     case ID_OP:
00360         {
00361             if (e->substituted_valid()) {
00362                 Expression *sub = get_expr(e->substituted_guarded().entry());
00363                 e->substituted(sub);
00364             }
00365             /// ...  possible values should already be in the list
00366         }
00367         break;
00368 
00369     case U_PLUS_OP:
00370     case U_MINUS_OP:
00371     case NOT_OP:
00372     case PAREN_OP:
00373         {
00374             Expression     *exp = get_expr(e->expr_guarded().entry());
00375 
00376             e->expr(exp);
00377         }
00378         break;
00379 
00380     case EQ_OP:
00381     case NE_OP:
00382     case LT_OP:
00383     case LE_OP:
00384     case GT_OP:
00385     case GE_OP:
00386     case SUB_OP:
00387     case DIV_OP:
00388     case EXP_OP:
00389     case REPSTAR_OP:
00390     case KEYPAIR_OP:
00391         {
00392             if (e->left_guarded().op() != OMEGA_OP) {
00393                 Expression     *lf = get_expr(e->left_guarded().entry());
00394                 e->left(lf);
00395             }
00396 
00397             Expression     *rt = get_expr(e->right_guarded().entry());
00398 
00399             e->right(rt);
00400         }
00401         break;
00402 
00403     case COLON_OP:
00404         {     /// ...  _left of a COLON_OP can be OM
00405 
00406             Iterator<Expression> iter = e->arg_list();
00407             Expression          *newe;  /// ...  pointer to ExprTable entry objects
00408 
00409             while (! iter.end()) {
00410                 if (iter.current().op() == TABLE_ENTRY) {
00411                     newe = get_expr(iter.current().entry());
00412                     e->arg_list().modify(iter.current(), newe);
00413                 }
00414                 iter.next();
00415             }
00416         }
00417         break;
00418 
00419     case CONCAT_OP:
00420     case OR_OP:
00421     case AND_OP:
00422     case EQV_OP:
00423     case NEQV_OP:
00424     case ADD_OP:
00425     case MULT_OP:
00426     case COMMA_OP:
00427         {
00428             Iterator<Expression> iter = e->arg_list();
00429             Expression          *newe;  /// ...  pointer to ExprTable entry objects
00430 
00431             while (! iter.end()) {
00432                 newe = get_expr(iter.current().entry());
00433                 e->arg_list().modify(iter.current(), newe);
00434                 iter.next();
00435             }
00436         }
00437         break;
00438 
00439     case DO_OP:
00440         {
00441             Expression     *io = get_expr(e->iolist().entry());
00442             Expression     *it = get_expr(e->iterator().entry());
00443 
00444             e->iolist(io);
00445             e->iterator(it);
00446         }
00447         break;
00448 
00449     case EQUAL_OP:
00450         {
00451             Expression     *in = get_expr(e->index_id().entry());
00452 
00453             e->index_id(in);
00454             in = get_expr(e->iteration_space().entry());
00455             e->iteration_space(in);
00456         }
00457         break;
00458 
00459     case TABLE_ENTRY:
00460         p_abort( "ExprTable::get_expr: called on a TableExpr");
00461         break;
00462     default: break;
00463     }
00464 
00465     return e;
00466 }
00467 
00468 
00469 
00470 Expression *
00471 convert_expr(BinRep & insp, ExprTable & etable, const char *caller)
00472 {
00473     if (!insp.is_integer()) {
00474         cerr << caller << "::convert_expr: integer expected.\n";
00475         p_abort( "(see above message)" );
00476     }
00477 
00478     return (etable[insp.to_integer()]);
00479 }
00480 
 © 1995-2005 University of Illinois, Urbana-Champaign. All rights reserved.  Fri Mar 25 23:05:52 2005