ExprTable.ccGo 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
00022
00023
00024 ExprTable::~ExprTable()
00025 {
00026
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
00054
00055
00056
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
00165
00166
00167
00168
00169
00170
00171 void
00172 ExprTable::get_table(const BinRep &bs, Symtab & symtab)
00173 {
00174
00175 int count = 0;
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
00184
00185 for (Iterator<BinRep> iter = bs.to_tuple(); iter.valid(); ++iter) {
00186 BinRep & insp = iter.current();
00187
00188 if (insp.is_omega()) {
00189
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
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
00213
00214 cur->convert(insp, symtab);
00215
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
00232
00233
00234
00235
00236
00237
00238
00239
00240 Expression *
00241 ExprTable::get_expr(int entry)
00242 {
00243
00244
00245 if (_final[entry] != 0)
00246 return (_table[entry])->clone();
00247
00248 Expression *e = _table[entry];
00249
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
00262
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
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 {
00405
00406 Iterator<Expression> iter = e->arg_list();
00407 Expression *newe;
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;
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
|