| Polaris: Expression.cc Source File |
|
Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members
Expression.ccGo to the documentation of this file.00001 /// 00002 /// \file Expression.cc 00003 /// 00004 /// Expression - related code: Expression class and all derived classes 00005 /// 00006 /// 00007 #ifdef POLARIS_GNU_PRAGMAS 00008 #pragma implementation "expr_funcs.h" 00009 #pragma implementation "Expression.h" 00010 /// 00011 #pragma implementation "StringExpr.h" 00012 #pragma implementation "UnaryExpr.h" 00013 #pragma implementation "BinaryExpr.h" 00014 #pragma implementation "NonBinaryExpr.h" 00015 /// 00016 #pragma implementation "ArgNumberExpr.h" 00017 #pragma implementation "ArrayRefExpr.h" 00018 #pragma implementation "CommaExpr.h" 00019 #pragma implementation "ComplexExpr.h" 00020 #pragma implementation "DoExpr.h" 00021 #pragma implementation "EqualExpr.h" 00022 #pragma implementation "FormatExpr.h" 00023 #pragma implementation "FunctionCallExpr.h" 00024 #pragma implementation "HollerithConstExpr.h" 00025 #pragma implementation "IDExpr.h" 00026 #pragma implementation "IOStarExpr.h" 00027 #pragma implementation "InfinityExpr.h" 00028 #pragma implementation "IntConstExpr.h" 00029 #pragma implementation "IntrinsicCallExpr.h" 00030 #pragma implementation "KeyExpr.h" 00031 #pragma implementation "LabelExpr.h" 00032 #pragma implementation "LambdaCallExpr.h" 00033 #pragma implementation "LogicalConstExpr.h" 00034 #pragma implementation "OmegaExpr.h" 00035 #pragma implementation "GSAExpr.h" 00036 #pragma implementation "RealConstExpr.h" 00037 #pragma implementation "ReturnStarExpr.h" 00038 #pragma implementation "StmtLabelExpr.h" 00039 #pragma implementation "StringConstExpr.h" 00040 #pragma implementation "SubStringExpr.h" 00041 #pragma implementation "TableExpr.h" 00042 #pragma implementation "DistributeExpr.h" 00043 #endif 00044 /// 00045 #include <stdio.h> 00046 #include <string.h> 00047 #include <iostream.h> 00048 #include <ctype.h> 00049 #include <limits.h> 00050 #include <set> 00051 00052 /// #include <math.h> 00053 extern "C" double ceil(double); 00054 extern "C" double floor(double); 00055 00056 00057 #include "../BinRep.h" 00058 #include "../debug.h" 00059 #include "../Collection/List.h" 00060 #include "../Collection/Iterator.h" 00061 #include "../Collection/Mutator.h" 00062 #include "../Collection/RefElement.h" 00063 #include "../Collection/RefSet.h" 00064 #include "../Directive/Directive.h" 00065 #include "../Permutation.h" 00066 #include "../String.h" 00067 #include "../Statement/Statement.h" 00068 #include "../Symtab.h" 00069 #include "../Symbol/VariableSymbol.h" 00070 #include "../Symbol/FunctionSymbol.h" 00071 #include "../Symbol/SubroutineSymbol.h" 00072 #include "../Type.h" 00073 #include "../ProgramUnit.h" 00074 #include "../VDL.h" 00075 #include "../utilities/expression_util.h" 00076 #include "../utilities/string_util.h" 00077 #include "../utilities/switches_util.h" 00078 #include "../utilities/symbol_util.h" 00079 00080 #include "../p-assert.h" 00081 #include "../macros.h" 00082 #include "../rotate.h" 00083 00084 #include "expr.h" 00085 00086 #include "expr_funcs.h" 00087 #include "Expression.h" 00088 #include "replace.h" 00089 00090 #include "StringExpr.h" 00091 #include "UnaryExpr.h" 00092 #include "BinaryExpr.h" 00093 #include "NonBinaryExpr.h" 00094 00095 #include "ArgNumberExpr.h" 00096 #include "ArrayRefExpr.h" 00097 #include "CommaExpr.h" 00098 #include "ComplexExpr.h" 00099 #include "DoExpr.h" 00100 #include "EqualExpr.h" 00101 #include "FormatExpr.h" 00102 #include "FunctionCallExpr.h" 00103 #include "HollerithConstExpr.h" 00104 #include "IDExpr.h" 00105 #include "IOStarExpr.h" 00106 #include "InfinityExpr.h" 00107 #include "IntConstExpr.h" 00108 #include "IntrinsicCallExpr.h" 00109 #include "KeyExpr.h" 00110 #include "LabelExpr.h" 00111 #include "LambdaCallExpr.h" 00112 #include "LogicalConstExpr.h" 00113 #include "OmegaExpr.h" 00114 #include "GSAExpr.h" 00115 #include "RealConstExpr.h" 00116 #include "ReturnStarExpr.h" 00117 #include "StmtLabelExpr.h" 00118 #include "StringConstExpr.h" 00119 #include "SubStringExpr.h" 00120 #include "TableExpr.h" 00121 #include "DistributeExpr.h" 00122 00123 #include "../Wildcard/Wildcard.all.h" 00124 00125 #include "IntrinsicTable.h" 00126 00127 00128 static int subst_field_print = 0; 00129 00130 //------------------------------------------------------------------------ 00131 /// Expression base class code: 00132 /// 00133 00134 static char *op_string[NUM_OP_TYPES] = { 00135 "DELETED_EXPRESSION_OP", 00136 "INTEGER_CONSTANT_OP", 00137 "REAL_CONSTANT_OP", 00138 "STRING_CONSTANT_OP", 00139 "LOGICAL_CONSTANT_OP", 00140 "HOLLERITH_CONSTANT_OP", 00141 "COMPLEX_OP", 00142 "ARRAY_REF_OP", 00143 "SUBSTRING_OP", 00144 "FUNCTION_CALL_OP", 00145 "INTRINSIC_CALL_OP", 00146 "LAMBDA_CALL_OP", 00147 "ARG_OP", 00148 "RETURN_OP", 00149 "LABEL_OP", 00150 "IO_STAR_OP", 00151 "FORMAT_OP", 00152 "ID_OP", 00153 "U_PLUS_OP", 00154 "U_MINUS_OP", 00155 "NOT_OP", 00156 "EQ_OP", 00157 "NE_OP", 00158 "LT_OP", 00159 "LE_OP", 00160 "GT_OP", 00161 "GE_OP", 00162 "SUB_OP", 00163 "DIV_OP", 00164 "INTDIV_OP", 00165 "RATDIV_OP", 00166 "EXP_OP", 00167 "CONCAT_OP", 00168 "ADD_OP", 00169 "MULT_OP", 00170 "OR_OP", 00171 "AND_OP", 00172 "EQV_OP", 00173 "NEQV_OP", 00174 "DO_OP", 00175 "EQUAL_OP", 00176 "COMMA_OP", 00177 "COLON_OP", 00178 "PAREN_OP", 00179 "OMEGA_OP", 00180 "REPSTAR_OP", 00181 00182 "TABLE_ENTRY", 00183 "STMT_LABEL_OP", 00184 00185 "KEY_OP", 00186 "KEYPAIR_OP", 00187 00188 "INFINITY_OP", 00189 00190 "ALPHA_OP", 00191 "GAMMA_OP", 00192 "MU_OP", 00193 "THETA_OP", 00194 "ETA_OP", 00195 00196 "DISTRIBUTE_OP", /// ... _ 00197 00198 /// ... Wild Card Types 00199 "ANY_EXPR_SUBSET_WC", 00200 00201 "FORBOL_EXPR_WC", 00202 "FORBOL_STMT_WC", 00203 "FORBOL_EXPR_PMF_WC", 00204 "FORBOL_STMT_PMF_WC", 00205 "FORBOL_BLOCK_PMF_WC", 00206 00207 "AND_WC", 00208 "OR_WC", 00209 "NOT_WC", 00210 "CONTAINS_WC", 00211 "SUCH_THAT_WC", 00212 "ANY_WC", 00213 "ANY_EXPR_OF_TYPE_WC", 00214 "ANY_CONST_WC", 00215 "ANY_INT_CONST_WC", 00216 "ANY_HOLLERITH_CONST_WC", 00217 "ANY_LOGICAL_CONST_WC", 00218 "ANY_REAL_CONST_WC", 00219 "ANY_STRING_CONST_WC", 00220 "ANY_ARRAY_REF_WC", 00221 "ANY_BINARY_WC", 00222 "ANY_COMMA_WC", 00223 "ANY_COMPLEX_WC", 00224 "ANY_ID_WC", 00225 "ANY_FUNCTION_CALL_WC", 00226 "ANY_INTRINSIC_CALL_WC", 00227 "ANY_NON_BINARY_WC", 00228 "ANY_SUBSTRING_WC", 00229 "ANY_UNARY_WC", 00230 "ANY_INT_WC", 00231 "ANY_REAL_WC" 00232 }; 00233 00234 void set_subst_field_print() { 00235 subst_field_print = 1; 00236 } 00237 00238 Expression::~Expression() 00239 { 00240 #ifdef CLASS_INSTANCE_REGISTRY 00241 unregister_instance(EXPRESSION, this); 00242 #endif 00243 00244 if (_overflow) 00245 delete _overflow; 00246 _overflow = 0; 00247 _op = DELETED_EXPRESSION_OP; 00248 } 00249 00250 void 00251 Expression::_ref_error(const char *method) const 00252 { 00253 cerr << "***Error: Expression: undefined method called:\n" 00254 << "Expression object of type " 00255 << op_string[op()] << " (number " 00256 << op() << ") called method " << method << endl; 00257 00258 p_abort("(See above error message)"); 00259 } 00260 00261 //------------------------------------------------------------------------ 00262 00263 Boolean 00264 is_commutative(OP_TYPE op) 00265 { 00266 switch (op) { 00267 case ADD_OP: 00268 case MULT_OP: 00269 case AND_OP: 00270 case OR_OP: 00271 case EQV_OP: 00272 case NEQV_OP: 00273 return True; 00274 00275 default: 00276 return False; 00277 } 00278 } 00279 00280 Boolean 00281 is_conjunctive_op(OP_TYPE op) 00282 { 00283 switch (op) { 00284 case AND_OP: 00285 case OR_OP: 00286 case EQV_OP: 00287 case NEQV_OP: 00288 return True; 00289 00290 default: 00291 return False; 00292 } 00293 } 00294 00295 Boolean 00296 is_relational_op(OP_TYPE op) 00297 { 00298 switch (op) { 00299 case EQ_OP: 00300 case NE_OP: 00301 case LT_OP: 00302 case LE_OP: 00303 case GT_OP: 00304 case GE_OP: 00305 return True; 00306 00307 default: 00308 return False; 00309 } 00310 } 00311 00312 00313 /// Used only to act as a return value in cases where control flow cannot 00314 /// reach the end of a procedure (in order to avoid a compiler 00315 /// warning/error) 00316 00317 #define DUMMY_EXPR_REF (*(Expression *)0) 00318 00319 /// Declare the following Expression argument field as an alias to another 00320 /// field 00321 00322 #define ALIAS_ARG(class, alias, alias_to) \ 00323 void class::alias(Expression *e) { alias_to(e); } \ 00324 Expression &class::alias() const { return alias_to(); } \ 00325 Boolean class::alias ## _valid() const { return alias_to ## _valid(); } 00326 00327 00328 #define ALIAS_ARG_ASSERT(class, alias, alias_to, req_op, msg) \ 00329 void class::alias(Expression *e) { p_assert(e->op() == req_op, msg); \ 00330 alias_to(e); } \ 00331 Expression &class::alias() const { return alias_to(); } \ 00332 Boolean class::alias ## _valid() const { return alias_to ## _valid(); } 00333 00334 Boolean 00335 is_logical_false(const Expression & e) 00336 { 00337 return ((e.op() == LOGICAL_CONSTANT_OP) && (e.str_data() == ".FALSE.")); 00338 } 00339 00340 Boolean 00341 is_integer_zero(const Expression & e) 00342 { 00343 return (e.op() == INTEGER_CONSTANT_OP && e.value() == 0); 00344 } 00345 00346 Boolean 00347 is_integer_one(const Expression & e) 00348 { 00349 return (e.op() == INTEGER_CONSTANT_OP && e.value() == 1); 00350 } 00351 00352 Boolean 00353 is_integer_constant(const Expression & e) 00354 { 00355 return (e.op() == INTEGER_CONSTANT_OP); 00356 } 00357 00358 Boolean 00359 is_integer_constant(const Expression & e, int val) 00360 { 00361 return (e.op() == INTEGER_CONSTANT_OP && e.value() == val); 00362 } 00363 00364 bool 00365 is_phi_function(const Expression & e) 00366 { 00367 switch (e.op()) { 00368 case GAMMA_OP: 00369 case MU_OP: 00370 case THETA_OP: 00371 case ETA_OP: 00372 return true; 00373 default: 00374 return false; 00375 } 00376 return false; 00377 } 00378 00379 bool 00380 is_pseudo_function(const Expression & e) 00381 { 00382 switch (e.op()) { 00383 case ALPHA_OP: 00384 case GAMMA_OP: 00385 case MU_OP: 00386 case THETA_OP: 00387 case ETA_OP: 00388 return true; 00389 case FUNCTION_CALL_OP: 00390 if (!strcmp(e.function().symbol().name_ref(), "<BETA>")) 00391 return true; 00392 default: 00393 return false; 00394 } 00395 return false; 00396 } 00397 00398 /// Given a Fortran character constant enclosed in double quotes, convert 00399 /// it into a character constant enclosed in single quotes (making all 00400 /// necessary syntactic changes) 00401 /// The string returned must be deleted using 'delete []' 00402 /// Returns 0 if there was an error. (i.e. mismatched quotes, etc.) 00403 00404 //////////////////////////////////////////////////////////// 00405 00406 static char * 00407 double_to_single_quoted(const char *dbl) 00408 { 00409 int dbl_len = strlen(dbl); 00410 00411 /// ... Need a workspace of a most 2*len(dbl) size 00412 00413 char *work = new char[2*dbl_len + 1]; 00414 00415 work[0] = '\''; /// ... First single quote 00416 00417 /// ... Now go through, changing single quotes to single quote pairs, and 00418 /// ... changing double quotes pairs to double quotes 00419 00420 int work_i, dbl_i; 00421 00422 for (work_i = 1, dbl_i = 1; dbl_i < dbl_len - 1; ++work_i, ++dbl_i) { 00423 /// ... Everything between the outer quotes 00424 00425 switch (dbl[dbl_i]) { 00426 case '\'': /// ... Replace with pair 00427 work[work_i ++ ] = '\''; 00428 work[work_i] = '\''; 00429 break; 00430 00431 case '"': /// ... Replace pair with single 00432 if (dbl_i >= dbl_len - 2 || dbl[dbl_i + 1] != '"' ) { 00433 delete work; 00434 return 0; /// ... This is not a double quote pair -- error 00435 } 00436 work[work_i] = '"'; 00437 ++dbl_i; /// ... Skip the extra in the pair 00438 break; 00439 00440 default: 00441 work[work_i] = dbl[dbl_i]; 00442 break; 00443 } 00444 } 00445 00446 work[work_i] = '\''; /// ... Last single quote 00447 work[work_i + 1] = '\000'; /// ... NULL-terminate 00448 00449 return work; 00450 } 00451 00452 00453 //////////////////////////////////////////////////////////////// 00454 /// These routines are used to propogate rank information from 00455 /// the symbol table to the Types of all Expressions. These 00456 /// are called as part of the pre-pass. 00457 //////////////////////////////////////////////////////////////// 00458 00459 /// Report an error in an intrinsic parameter 00460 00461 void 00462 report_param_error( Expression & expr, char *intrin, 00463 int param_num, char *expected) 00464 { 00465 cerr << "compute_intrinsic_type: Error found in intrinsic argument" 00466 << endl; 00467 cerr << "Error found in the Expression " << expr 00468 << ". The intrinsic " << intrin << " requires " 00469 << expected << " type in parameter number " << param_num 00470 << endl; 00471 00472 p_abort("report_param_error: Parameter Error (see above)"); 00473 } 00474 00475 /// Compute the type of expr which is an IntrinsicCallExpr 00476 00477 void 00478 compute_intrinsic_type(Expression & expr) 00479 { 00480 IntrinsicTable tab; 00481 00482 String intrin = expr.intrinsic().symbol().name_ref(); 00483 00484 int index = tab.lookup_intrinsic(intrin); 00485 00486 /// ... Check if parameter has been axed (what the hell does this mean?) 00487 00488 if (tab.axed(index)) { 00489 cerr << "compute_intrinsic_type: Error in expression: " 00490 << expr << endl; 00491 p_abort("Attempt to call 'axed' intrinsic"); 00492 } 00493 00494 /// ... Make sure it does not require global special handling 00495 00496 if (!tab.special(index)) { 00497 /// ... Make sure there are some parameters 00498 00499 if (!expr.parameters_valid()) { 00500 cerr << "compute_intrinsic_type: Error in expression: " 00501 << expr << endl; 00502 cerr << "Intrinsic required to have " << tab.num_req_params(index) 00503 << " parameters" << endl; 00504 p_abort("Invalid number of parameters"); 00505 } 00506 00507 int num_params = expr.parameters_guarded().arg_list().entries(); 00508 00509 /// ... Make sure there are the correct number of parameters 00510 /// ... NOTE: if the number of paramters is listed as 0, the number 00511 /// ... is variable. 00512 00513 if ((num_params < tab.num_req_params(index)) || 00514 ((tab.num_params(index) != 0) && 00515 (num_params > tab.num_params(index)))) { 00516 00517 cerr << "compute_intrinsic_type: Error in expression: " 00518 << expr << endl; 00519 cerr << "Intrinsic required to have between " 00520 << tab.num_req_params(index) << " and " 00521 << tab.num_params(index) 00522 << " parameters" << endl; 00523 00524 p_abort("Invalid number of parameters"); 00525 } 00526 00527 /// ... Make sure the parameters are of the correct type 00528 /// ... NOTE: Should also check if they are the correct rank 00529 00530 int i = 0; 00531 00532 for (Iterator<Expression> param = expr.parameters_guarded().arg_list(); 00533 param.valid(); ++param) { 00534 if (!param.current_valid()) { 00535 cerr << "compute_intrinsic_type: Error in expression: " 00536 << expr << endl; 00537 p_abort("Invalid parameter."); 00538 } 00539 00540 EXPR_TYPE user_type = param.current().type().data_type(); 00541 EXPR_TYPE table_type = tab.param_type(index, i); 00542 00543 if (user_type != table_type) { 00544 /// ... Types don`t match--check exceptions 00545 00546 if ((table_type == INT_OR_REAL_TYPES) && 00547 ((user_type == INTEGER_TYPE) || 00548 (user_type == REAL_TYPE) || 00549 (user_type == DOUBLE_PRECISION_TYPE))) { 00550 /// ... OK, nothing to do 00551 } 00552 else if ((table_type == REAL_TYPE) && 00553 (user_type = DOUBLE_PRECISION_TYPE)) { 00554 /// ... OK, nothing to do 00555 } 00556 else if ((user_type == REAL_TYPE) && 00557 (table_type == DOUBLE_PRECISION_TYPE)) { 00558 /// ... OK, nothing to do 00559 } 00560 else if (table_type == GENERIC_TYPE) { 00561 /// ... OK, nothing to do 00562 } 00563 else { /// ... Problem! 00564 cerr << "compute_intrinsic_type: Error in " 00565 << "expression: " << expr << endl; 00566 cerr << "Type of parameter " << i 00567 << " is invalid." << endl; 00568 cerr << "Type found = " << user_type << ". Type " 00569 << "expected = " << table_type << "." << endl; 00570 00571 p_abort("Invalid parameter."); 00572 } 00573 } 00574 00575 00576 int user_rank = param.current().type().rank(); 00577 int table_rank = tab.param_req_rank(index, i); 00578 00579 if (param.current().type().rank_known() == 1) { /// ... make sure rank is known 00580 if (((table_rank == SCALAR) && (user_rank > 0)) || 00581 ((table_rank == ARRAY) && (user_rank == 0))) { 00582 cerr << "compute_intrinsic_type: Error in " 00583 << "expression: " << expr << endl; 00584 cerr << "Rank of parameter " << i 00585 << " is invalid." << endl; 00586 cerr << "Rank found = " << user_rank << ". "; 00587 00588 switch (table_rank) { 00589 case SCALAR: 00590 cerr << "scalar"; break; 00591 case ARRAY: 00592 cerr << "array"; break; 00593 case SCALAR_OR_ARRAY: 00594 cerr << "scalar or array"; break; 00595 case SPECIAL: 00596 cerr << "special"; break; 00597 } 00598 00599 cerr << " expected." << endl; 00600 00601 p_abort("Invalid parameter."); 00602 } 00603 } 00604 00605 i = (i < 3) ? i+1 : 3; /// ... if there are more than 4 params, 00606 /// ... type-check using the 4th 00607 } 00608 00609 /// ... Determine result type -- set the expr`s type. 00610 /// ... First, set the type kind 00611 00612 EXPR_TYPE table_type; 00613 00614 switch (table_type = tab.return_type(index)) { 00615 case REAL_TYPE: 00616 case INTEGER_TYPE: 00617 case COMPLEX_TYPE: 00618 case LOGICAL_TYPE: 00619 case CHARACTER_TYPE: 00620 case DOUBLE_PRECISION_TYPE: 00621 { 00622 (CASTAWAY(Type &) expr.type()).set(table_type, 00623 tab.return_length(index)); 00624 } 00625 break; 00626 00627 case INT_OR_REAL_TYPES: 00628 case GENERIC_TYPE: 00629 { 00630 /// ... The type is taken from the type of the first parameter 00631 /// ... unless the special_type flag is up, in which case it 00632 /// ... is done on a case by case basis. 00633 00634 if (!tab.return_special(index)) 00635 expr.type(expr.parameters_guarded().arg_list()[0].type()); 00636 else { 00637 if (intrin == "ABS") { 00638 /// ... 1st param type 00639 00640 const Type & param_type 00641 = expr.parameters_guarded().arg_list()[0].type(); 00642 00643 if ((param_type.data_type() == REAL_TYPE) || 00644 (param_type.data_type() == INTEGER_TYPE) || 00645 (param_type.data_type() == DOUBLE_PRECISION_TYPE)) { 00646 expr.type(param_type); 00647 } 00648 else if (param_type.data_type() == COMPLEX_TYPE) 00649 expr.type( make_type(REAL_TYPE) ); 00650 else { 00651 report_param_error(expr, "ABS", 1, 00652 "INTEGER/REAL/COMPLEX"); 00653 } 00654 } 00655 else if ((intrin == "RESHAPE") || 00656 (intrin == "TRANSFER")) { 00657 /// ... take type from 2nd argument 00658 00659 expr.type( expr.parameters_guarded().arg_list()[ 00660 1].type() ); 00661 } 00662 else if ((intrin == "MATMUL") || (intrin == "DOTPRODUCT")) { 00663 /// ... use rules from table 7.1.4 00664 00665 Type lt = 00666 expr.parameters_guarded().arg_list()[0].type(); 00667 Type rt = 00668 expr.parameters_guarded().arg_list()[1].type(); 00669 00670 int lrank = lt.rank(); 00671 int rrank = lt.rank(); 00672 00673 lt.redimension(0); /// ... make scalar to avoid 00674 rt.redimension(0); /// ... rank conflicts 00675 00676 if ((intrin == "DOTPRODUCT") && 00677 (lt.data_type() == LOGICAL_TYPE) && 00678 (rt.data_type() == LOGICAL_TYPE)) { 00679 /// ... log * log = log for dotproduct 00680 expr.type( make_type(LOGICAL_TYPE) ); 00681 } 00682 else { 00683 expr.type( expr_type(MULT_OP, lt, rt) ); 00684 } 00685 00686 lt.redimension(lrank); 00687 rt.redimension(rrank); 00688 } 00689 } 00690 } 00691 break; 00692 00693 default: 00694 { 00695 cerr << "compute_intrinsic_type: Error in " 00696 << "expression: " << expr << endl; 00697 cerr << "Type found = " << table_type << endl; 00698 00699 p_abort( "compute_intrinsic_type: unexpected result type " 00700 "found in intrinsic table." ); 00701 } 00702 break; 00703 } 00704 00705 /// ... Set the resulting type shape 00706 00707 int shape = tab.return_shape(index); 00708 00709 if (shape == SCALAR) { 00710 (CASTAWAY(Type &) expr.type()).redimension(0); 00711 } 00712 else if ((shape == ARRAY) || (shape == SCALAR_OR_ARRAY)) { 00713 /// ... Take the shape from the shape of the first argument 00714 /// ... 1st param type 00715 00716 const Type & param_type 00717 = expr.parameters_guarded().arg_list()[0].type(); 00718 00719 if (param_type.rank_known()) 00720 (CASTAWAY(Type &) expr.type()).redimension(param_type.rank()); 00721 else 00722 (CASTAWAY(Type &) expr.type()).rank_known(False); 00723 } 00724 else { 00725 /// ... shape == SPECIAL 00726 /// ... Use rules derived from keywords or match on names 00727 00728 /// ... Intrinsic type: INTRINSIC(MASK, DIM) 00729 /// ... scalar if DIM absent; else it is rank(MASK) - 1 00730 /// ... * OR * 00731 /// ... Intrinsic type: INTRINSIC(ARRAY, DIM, MASK) 00732 /// ... scalar if DIM absent 00733 /// ... otherwise rank is rank(ARRAY) - 1 00734 /// ... * HANDLED THE SAME * 00735 00736 if (((tab.param_key(index, 0) == "MASK") && 00737 (tab.param_key(index, 1) == "DIM")) 00738 || ((tab.param_key(index, 0) == "ARRAY") && 00739 (tab.param_key(index, 1) == "DIM") && 00740 (tab.param_key(index, 2) == "MASK"))) { 00741 00742 if (num_params == 1) 00743 (CASTAWAY(Type &) expr.type()).redimension(0); 00744 else { 00745 /// ... 1st param type 00746 00747 const Type & param_type 00748 = expr.parameters_guarded().arg_list()[0].type(); 00749 00750 if (param_type.rank_known()) { 00751 (CASTAWAY(Type &) expr.type()).redimension( 00752 param_type.rank() - 1); 00753 } 00754 else { 00755 (CASTAWAY(Type &) expr.type()).rank_known(False); 00756 } 00757 } 00758 } 00759 else if ((tab.param_key(index, 0) == "ARRAY") && 00760 (tab.param_key(index, 1) == "MASK")) { 00761 /// ... Intrinsic type: INTRINSIC(ARRAY, MASK) 00762 /// ... result is an array of rank 1 00763 (CASTAWAY(Type &) expr.type()).redimension(1); 00764 } 00765 else if ((tab.param_key(index, 0) == "MATRIX_A") && 00766 (tab.param_key(index, 1) == "MATRIX_B")) { 00767 /// ... MATMUL-style intrinsic 00768 00769 int rank_0 = 00770 expr.parameters_guarded().arg_list()[0].type().rank(); 00771 int rank_1 = 00772 expr.parameters_guarded().arg_list()[1].type().rank(); 00773 00774 if (((rank_0 == 1) && (rank_1 == 2)) || 00775 ((rank_0 == 2) && (rank_1 == 1))) { 00776 (CASTAWAY(Type &) expr.type()).redimension(1); 00777 } 00778 else if ((rank_0 == 2) && (rank_1 == 2)) { 00779 (CASTAWAY(Type &) expr.type()).redimension(2); 00780 } 00781 else { 00782 cerr << "compute_intrinsic_type: Error in " 00783 << "expression: " << expr << endl; 00784 00785 cerr << "First argument has rank " 00786 << rank_0 << endl; 00787 cerr << "and second argument has rank " 00788 << rank_1 << "." << endl; 00789 cerr << "Illegal combination for matrix multiplication." 00790 << endl; 00791 00792 p_abort( "compute_intrinsic_type: illegal parameters " 00793 "found in intrinsic MATMUL." ); 00794 } 00795 } 00796 else if ((intrin == "LBOUND") || (intrin == "UNBOUND")) { 00797 /// ... Intrinsic violates derived rules--handle case by case 00798 /// ... scalar if dim present, else rank 1 00799 00800 if (num_params == 2) /// ... DIM is present 00801 (CASTAWAY(Type &) expr.type()).redimension(0); 00802 else 00803 (CASTAWAY(Type &) expr.type()).redimension(1); 00804 } 00805 } 00806 } 00807 else { 00808 /// ... intrinsic _DOES_ require global special handling 00809 /// ... handle on a case by case basis 00810 } 00811 } 00812 00813 00814 /// Assuming the types of all of expr's subexpressions are complete 00815 /// (i.e. contain dimension info), determine expr's complete type. 00816 00817 void 00818 determine_root_expr_type(Expression & expr) 00819 { 00820 IntrinsicTable intrin_tab; 00821 00822 switch (expr.op()) { 00823 case COMPLEX_OP: 00824 /// ... Mark as a scalar 00825 (CASTAWAY(Type &) expr.type()).redimension(0); 00826 break; 00827 00828 case ARRAY_REF_OP: 00829 { 00830 /// ... Rank = # of COLON_OPs in the list of subscripts 00831 00832 int rank = 0; 00833 00834 for (Iterator<Expression> expr_iter = expr.subscript().arg_list(); 00835 expr_iter.valid(); ++expr_iter) { 00836 if (!expr_iter.current_valid()) { 00837 cerr << "Invalid subscript found in array: " 00838 << expr << "while determining type."; 00839 p_abort( "determine_root_expr_type: invalid expression" ); 00840 } 00841 else if (expr_iter.current().op() == COLON_OP) { 00842 rank++; 00843 } 00844 } 00845 00846 (CASTAWAY(Type &) expr.type()).redimension(rank); 00847 } 00848 break; 00849 00850 case FUNCTION_CALL_OP: 00851 { 00852 /// ... Type is the same as the first sub-expression's type 00853 00854 if (expr.function().symbol().type().rank_known()) { 00855 (CASTAWAY(Type &) expr.type()).redimension( 00856 expr.function().symbol().type().rank()); 00857 } 00858 else { 00859 (CASTAWAY(Type &) expr.type()).rank_known(False); 00860 } 00861 } 00862 break; 00863 00864 case INTRINSIC_CALL_OP: 00865 { 00866 /// ... Use the intrinsic table. 00867 00868 compute_intrinsic_type(expr); 00869 00870 /// ... (CASTAWAY(Type &) expr.type()).rank_known(False); 00871 /// ... (CASTAWAY(Type &) expr.type()).set(UNKNOWN_TYPE); 00872 } 00873 break; 00874 00875 case LAMBDA_CALL_OP: /// ... Statement functions must be scalar 00876 case ARG_OP: 00877 case RETURN_OP: 00878 { 00879 /// ... Return integer is scalar 00880 00881 (CASTAWAY(Type &) expr.type()).redimension(0); 00882 } 00883 break; 00884 00885 case U_PLUS_OP: /// ... unary operations take the type from their 00886 case U_MINUS_OP: /// ... sub-expression. 00887 case NOT_OP: 00888 case PAREN_OP: 00889 { 00890 if (expr.expr_valid()) 00891 expr.type(expr.expr_guarded().type()); 00892 else 00893 (CASTAWAY(Type &) expr.type()).rank_known(False); 00894 } 00895 break; 00896 00897 case OR_OP: 00898 case AND_OP: 00899 case EQV_OP: 00900 case NEQV_OP: 00901 case ADD_OP: 00902 case MULT_OP: 00903 case CONCAT_OP: 00904 { 00905 Iterator<Expression> xiter = expr.arg_list(); 00906 00907 while (!xiter.current_valid() && xiter.valid()) { 00908 ++xiter; 00909 00910 if (!xiter.valid()) { 00911 cerr << "NonBinary expression with no arguments: " 00912 << expr << endl; 00913 p_abort("determine_root_expr_type: fatal condition"); 00914 } 00915 } 00916 00917 Type * type_so_far = xiter.current().type_ref(); 00918 00919 for ( ++xiter; xiter.valid(); ++xiter ) { 00920 if (xiter.current_valid()) { 00921 Type new_type = expr_type( expr.op(), *type_so_far, 00922 xiter.current().type()); 00923 delete type_so_far; 00924 type_so_far = new Type(new_type); 00925 } 00926 } 00927 00928 expr.type( *type_so_far ); 00929 /// ... silvius: 00930 delete type_so_far; 00931 } 00932 break; 00933 00934 case EQ_OP: 00935 case NE_OP: 00936 case LT_OP: 00937 case LE_OP: 00938 case GT_OP: 00939 case GE_OP: 00940 case SUB_OP: 00941 case DIV_OP: 00942 case INTDIV_OP: 00943 case RATDIV_OP: 00944 case EXP_OP: 00945 case SUBSTRING_OP: 00946 case KEYPAIR_OP: 00947 { 00948 /// ... Infer ranks of BinaryExprs. Determine using type-inference 00949 /// ... routines. If a sub-expression does not exist, use the type 00950 /// ... of the existing sub-expression. 00951 00952 if (expr.left_valid()) { 00953 if (expr.right_valid()) { 00954 expr.type( expr_type(expr.op(), 00955 expr.left_guarded().type(), 00956 expr.right_guarded().type())); 00957 } 00958 else { 00959 expr.type( expr.left_guarded().type() ); 00960 } 00961 } 00962 else { 00963 if (expr.right_valid()) 00964 expr.type( expr.right_guarded().type() ); 00965 else { 00966 (CASTAWAY(Type &) expr.type()).rank_known(False); 00967 } 00968 } 00969 } 00970 break; 00971 00972 case LABEL_OP: /// ... Rank makes no sense in these contexts 00973 case IO_STAR_OP: 00974 case FORMAT_OP: 00975 case DO_OP: 00976 case EQUAL_OP: 00977 case COMMA_OP: 00978 case COLON_OP: 00979 case OMEGA_OP: 00980 case REPSTAR_OP: 00981 case TABLE_ENTRY: 00982 case STMT_LABEL_OP: 00983 case INFINITY_OP: 00984 00985 case ALPHA_OP: 00986 case GAMMA_OP: 00987 case MU_OP: 00988 case THETA_OP: 00989 case ETA_OP: 00990 00991 default: 00992 { 00993 (CASTAWAY(Type &) expr.type()).rank_known(False); 00994 } 00995 break; 00996 } 00997 } 00998 00999 /// Determine the appropriate dimensionality of 'expr' based on it's 01000 /// sub-expression's or Symbol's type. Update the Type with dimension 01001 /// data. WARNING: This routine makes heavy use of casting away 01002 /// consts in order to modify the const type expression. 01003 01004 void 01005 propagate_expr_types(Expression & expr) 01006 { 01007 if (expr.op() == ID_OP) { 01008 /// ... An IDExpr has the same dimensionality as it`s symbol 01009 expr.type( expr.symbol().type() ); 01010 } 01011 else if ((expr.op() == INTEGER_CONSTANT_OP) || 01012 (expr.op() == REAL_CONSTANT_OP) || 01013 (expr.op() == STRING_CONSTANT_OP) || 01014 (expr.op() == LOGICAL_CONSTANT_OP) || 01015 (expr.op() == HOLLERITH_CONSTANT_OP)) { 01016 /// ... mark constants as scalar (NOTE: this does not handle 01017 /// ... array constants) 01018 01019 (CASTAWAY(Type &) expr.type()).redimension(0); 01020 } 01021 else if (expr.arg_list().entries() > 0) { 01022 /// ... Determine types of the sub-expressions 01023 01024 for (Iterator<Expression> sub_expr_iter = expr.arg_list(); 01025 sub_expr_iter.valid(); ++sub_expr_iter) { 01026 if (sub_expr_iter.current_valid()) 01027 propagate_expr_types(sub_expr_iter.current()); 01028 } 01029 01030 determine_root_expr_type(expr); 01031 } 01032 } 01033 01034 //////////////////////////////////////////////////////////// 01035 //////////////////////////////////////////////////////////// 01036 01037 static Boolean 01038 is_arithmetic_type(EXPR_TYPE type) 01039 { 01040 return (type == INTEGER_TYPE) || (type == REAL_TYPE) || 01041 (type == DOUBLE_PRECISION_TYPE) || (type == COMPLEX_TYPE); 01042 } 01043 01044 static Type 01045 arithmetic_result_type(const Type & type1, const Type & type2, const int rank) 01046 { 01047 EXPR_TYPE type1_type = type1.data_type(); 01048 EXPR_TYPE type2_type = type2.data_type(); 01049 int type1_size = type1.size(); 01050 int type2_size = type2.size(); 01051 01052 p_assert(is_arithmetic_type(type1_type) && is_arithmetic_type(type2_type), 01053 "Both types must be arithmetic"); 01054 01055 if (type1_type == type2_type) 01056 return make_type(type1_type, max(type1_size, type2_size), rank); 01057 01058 switch (type1_type) { 01059 case INTEGER_TYPE: 01060 if (type2_type == INTEGER_TYPE) 01061 return make_type(type1_type, max(type1_size, type2_size), rank); 01062 else 01063 return make_type(type2_type, type2_size, rank); 01064 01065 case REAL_TYPE: 01066 if (type2_type == INTEGER_TYPE) 01067 return make_type(type1_type, type1_size, rank); 01068 else if (type2_type == REAL_TYPE) 01069 return make_type(type1_type, max(type1_size, type2_size), rank); 01070 else 01071 return make_type(type2_type, type2_size, rank); 01072 01073 case DOUBLE_PRECISION_TYPE: 01074 if ((type2_type == INTEGER_TYPE) || (type2_type == REAL_TYPE)) 01075 return make_type(type1_type, type1_size, rank); 01076 else if (type2_type == DOUBLE_PRECISION_TYPE) 01077 return make_type(type1_type, max(type1_size, type2_size), rank); 01078 else 01079 return make_type(type2_type, type2_size, rank); 01080 01081 case COMPLEX_TYPE: 01082 if ((type2_type == INTEGER_TYPE) || (type2_type == REAL_TYPE) || 01083 (type2_type == DOUBLE_PRECISION_TYPE)) 01084 return make_type(type1_type, type1_size, rank); 01085 else 01086 return make_type(type2_type, max(type1_size, type2_size), rank); 01087 default: 01088 cout << type1_type << endl; 01089 p_abort("Unknown arithmetic type"); 01090 } 01091 01092 /// ... this return should never happen 01093 return make_type(UNDEFINED_TYPE); 01094 } 01095 01096 Type 01097 string_type(const char *data_string, Boolean ignore_errors GIV(False)) 01098 { 01099 int hollerith_len_int; 01100 int string_len; 01101 int len = strlen(data_string); 01102 Boolean havdot = False; 01103 Boolean havexp = False; 01104 Boolean havdbl = False; 01105 Boolean havhol = False; 01106 Boolean error = False; 01107 01108 char *copy_string = upcase_ch(data_string); 01109 01110 if ((strcmp(copy_string, ".TRUE.") == 0) || 01111 (strcmp(copy_string, ".FALSE.") == 0)) { 01112 delete[] copy_string; 01113 01114 return make_type(LOGICAL_TYPE); 01115 } 01116 01117 if ((copy_string[0] == '\'') && 01118 (copy_string[len - 1] == '\'')) { 01119 01120 /// ... We have a string constant - count up its real length ('' == ') 01121 01122 string_len = fortran_string_length(copy_string); 01123 delete[] copy_string; 01124 01125 return make_type(CHARACTER_TYPE, string_len); 01126 } 01127 01128 if ((copy_string[0] == '\"') && 01129 (copy_string[len - 1] == '\"')) { 01130 01131 /// ... We have a string constant with double quotes - 01132 /// ... convert to single quotes, then count up its real length ('' == ') 01133 01134 char *single_quotes = double_to_single_quoted(copy_string); 01135 string_len = fortran_string_length(single_quotes); 01136 delete[] copy_string; 01137 delete[] single_quotes; 01138 01139 return make_type(CHARACTER_TYPE, string_len); 01140 } 01141 01142 for (int i = 0; i < len; ++i) { 01143 if (copy_string[i] == '.') { 01144 if (havdot) { 01145 error = True; 01146 break; 01147 } 01148 havdot = True; 01149 } 01150 else if ((copy_string[i] == 'D') || (copy_string[i] == 'E')) { 01151 if (havexp) { 01152 error = True; 01153 break; 01154 } 01155 havexp = True; 01156 01157 if (copy_string[i] == 'D') 01158 havdbl = True; 01159 } 01160 else if (copy_string[i] == 'H') { 01161 01162 /// ... If nothing but digits thus far, OK 01163 01164 if (!havdot && !havexp && !error && !havhol) { 01165 char *hollerith_len = new char[i + 1]; 01166 01167 strncpy(hollerith_len, copy_string, i); 01168 hollerith_len[i] = '\000'; 01169 sscanf(hollerith_len, "%d", &hollerith_len_int); 01170 01171 /// ... Match stated length with string length 01172 01173 if (len - (i + 1) >= hollerith_len_int) 01174 havhol = True; 01175 else 01176 error = True; 01177 } 01178 else 01179 error = True; 01180 } 01181 else if (((i == 0) || havexp) && 01182 ((copy_string[i] == '-') || 01183 (copy_string[i] == '+'))) { 01184 /// ... Fine - all is OK, keep going 01185 } 01186 else if (!isdigit(copy_string[i])) { 01187 error = True; 01188 } 01189 } 01190 01191 delete[] copy_string; 01192 01193 if (error) { 01194 if (ignore_errors) 01195 return make_type(UNDEFINED_TYPE); 01196 cout << data_string << endl; 01197 p_abort("String is not a valid Fortran constant"); 01198 } 01199 01200 if (havhol) 01201 return make_type(CHARACTER_TYPE, hollerith_len_int); 01202 01203 if (!havdot && !havexp) 01204 return make_type(INTEGER_TYPE); 01205 01206 if (havdbl) 01207 return make_type(DOUBLE_PRECISION_TYPE); 01208 else 01209 return make_type(REAL_TYPE); 01210 } 01211 01212 /// Determine the rank of an intrinsic binary operator using the 01213 /// following rule: "The shape of the result of '[x1] op x2' 01214 /// is the shape of x2 if op is unary or if x1 is scalar, and is 01215 /// the shape of x1 otherwise". (section 7.1.4.2, FORTRAN 8x spec.) 01216 /// This results in a failed polaris assertion if the types are 01217 /// not in shape conformance. Returning -1 indicates that the 01218 /// rank is not known. 01219 01220 int 01221 compute_rank(const Type & left_type, const Type & right_type, const OP_TYPE op) 01222 { 01223 if (!left_type.rank_known()) 01224 return -1; 01225 else if (!right_type.rank_known()) { 01226 if (left_type.is_scalar()) 01227 return -1; 01228 else 01229 return left_type.rank(); 01230 } 01231 else { 01232 /// ... both ranks are known 01233 01234 if (left_type.is_scalar()) 01235 return right_type.rank(); 01236 else if (right_type.is_scalar()) 01237 return left_type.rank(); 01238 else { 01239 /// ... They are both arrays 01240 01241 if (right_type.rank() != left_type.rank()) { 01242 /// ... Types not in shape conformance 01243 cerr << "Types in intrinsic operation found" 01244 << " not to be in shape conformance" << endl; 01245 cerr << "for op number " << (int) op << endl; 01246 cerr << "Left: " << left_type << endl; 01247 cerr << "Right: " << right_type << endl; 01248 01249 p_abort("compute_rank::Violation of FORTRAN standard found"); 01250 } 01251 return right_type.rank(); 01252 } 01253 } 01254 } 01255 01256 Type 01257 expr_type(const OP_TYPE op, const Type & left_type, const Type & right_type) 01258 { 01259 EXPR_TYPE left_type_type, right_type_type; 01260 int left_type_size, right_type_size; 01261 int op_rank; 01262 01263 static int promote_logicals = -1; 01264 static int promote_integers = -1; 01265 01266 if (promote_logicals < 0) 01267 promote_logicals = switch_value("prom_logical"); 01268 01269 if (promote_integers < 0) 01270 promote_integers = switch_value("prom_integer"); 01271 01272 left_type_type = left_type.data_type(); 01273 left_type_size = left_type.size(); 01274 01275 right_type_type = right_type.data_type(); 01276 right_type_size = right_type.size(); 01277 01278 op_rank = compute_rank(left_type, right_type, op); 01279 01280 if (left_type_type == UNKNOWN_TYPE || right_type_type == UNKNOWN_TYPE) 01281 return make_ranked_type(UNKNOWN_TYPE, op_rank); 01282 01283 switch (op) { 01284 case OR_OP: /// ... NonBinaryExpr operator 01285 case AND_OP: /// ... NonBinaryExpr operator 01286 case EQV_OP: /// ... NonBinaryExpr operator 01287 case NEQV_OP: /// ... NonBinaryExpr operator 01288 01289 if ((left_type_type == LOGICAL_TYPE) && 01290 (right_type_type == LOGICAL_TYPE)) 01291 return make_ranked_type(LOGICAL_TYPE, op_rank); 01292 01293 if (promote_integers > 0) { 01294 if (((left_type_type == INTEGER_TYPE) && 01295 (right_type_type == INTEGER_TYPE)) || 01296 ((left_type_type == INTEGER_TYPE) && 01297 (right_type_type == LOGICAL_TYPE)) || 01298 ((left_type_type == LOGICAL_TYPE) && 01299 (right_type_type == INTEGER_TYPE))) 01300 01301 return make_ranked_type(LOGICAL_TYPE, op_rank); 01302 } 01303 01304 cout << left_type << ' ' << op_string[op] << ' ' << right_type << endl; 01305 p_abort("Bad type combination"); 01306 01307 return make_type(UNDEFINED_TYPE); 01308 01309 case KEYPAIR_OP: /// ... BinaryExpr operator 01310 return right_type; 01311 01312 case EQ_OP: 01313 case NE_OP: 01314 case LT_OP: 01315 case LE_OP: 01316 case GT_OP: 01317 case GE_OP: 01318 01319 if ( (is_arithmetic_type(left_type_type) 01320 && is_arithmetic_type(right_type_type)) || 01321 ((left_type_type == LOGICAL_TYPE) 01322 && (right_type_type == LOGICAL_TYPE)) || 01323 (left_type_type == CHARACTER_TYPE) 01324 && (right_type_type == CHARACTER_TYPE)) 01325 return make_ranked_type(LOGICAL_TYPE, op_rank); 01326 01327 cout << left_type << ' ' << op_string[op] << ' ' << right_type << endl; 01328 p_abort("Bad type combination"); 01329 01330 return make_type(UNDEFINED_TYPE); 01331 01332 case ADD_OP: /// ... NonBinaryExpr operator 01333 case MULT_OP: /// ... NonBinaryExpr operator 01334 case SUB_OP: 01335 case DIV_OP: 01336 case INTDIV_OP: 01337 case RATDIV_OP: 01338 case EXP_OP: 01339 01340 #if 0 01341 /// ... This is only valid for F77, it is possible in F90. 01342 if (((left_type_type == COMPLEX_TYPE) && 01343 (right_type_type == DOUBLE_PRECISION_TYPE)) || 01344 ((left_type_type == DOUBLE_PRECISION_TYPE) && 01345 (right_type_type == COMPLEX_TYPE))) 01346 p_abort("DOUBLE PRECISION prohibited with COMPLEX"); 01347 #endif 01348 01349 if (is_arithmetic_type(left_type_type) && 01350 is_arithmetic_type(right_type_type)) 01351 return arithmetic_result_type(left_type, right_type, op_rank); 01352 01353 if (promote_logicals > 0) { 01354 01355 if (left_type_type == LOGICAL_TYPE) { 01356 if (right_type_type == LOGICAL_TYPE) { 01357 return make_ranked_type(INTEGER_TYPE, op_rank); 01358 } 01359 else { 01360 Type t1 = make_ranked_type(INTEGER_TYPE, left_type.rank()); 01361 return arithmetic_result_type(t1, right_type, op_rank); 01362 } 01363 } else { 01364 if (right_type_type == LOGICAL_TYPE) { 01365 Type t2 = make_ranked_type(INTEGER_TYPE, right_type.rank()); 01366 return arithmetic_result_type(left_type, t2, op_rank); 01367 } 01368 cout << left_type << ' ' << op << ' ' << right_type << endl; 01369 p_abort("Invalid type combination"); 01370 } 01371 } 01372 else { 01373 cout << left_type << ' ' << op_string[op] 01374 << ' ' << right_type << endl; 01375 p_abort("Bad type combination"); 01376 01377 return make_type(UNDEFINED_TYPE); 01378 } 01379 01380 case CONCAT_OP: 01381 if ((left_type_type == CHARACTER_TYPE) && 01382 (right_type_type == CHARACTER_TYPE)) 01383 return make_type(CHARACTER_TYPE, left_type_size + right_type_size, 01384 op_rank); 01385 01386 cout << left_type << ' ' << op_string[op] << ' ' << right_type << endl; 01387 p_abort("Bad type combination"); 01388 01389 return make_type(UNDEFINED_TYPE); 01390 01391 case COLON_OP: 01392 if (((left_type_type == INTEGER_TYPE) 01393 || (left_type_type == UNDEFINED_TYPE)) && 01394 ((right_type_type == INTEGER_TYPE) 01395 || (right_type_type == UNDEFINED_TYPE))) 01396 return make_ranked_type(INTEGER_TYPE, op_rank); 01397 01398 cout << left_type << ' ' << op_string[op] << ' ' << right_type << endl; 01399 p_abort("Bad type combination"); 01400 01401 return make_type(UNDEFINED_TYPE); 01402 01403 case COMPLEX_OP: 01404 return make_type(COMPLEX_TYPE, max(left_type_size, right_type_size), 01405 op_rank); 01406 01407 case SUBSTRING_OP: 01408 return make_type(CHARACTER_TYPE, 0, op_rank); 01409 01410 case ARRAY_REF_OP: 01411 return make_type(left_type_type, left_type_size, op_rank); 01412 01413 case ALPHA_OP: /// ... Treat these as normal operations 01414 case GAMMA_OP: /// ... but ignore OMEGA_OP arguments 01415 case MU_OP: 01416 case THETA_OP: 01417 case ETA_OP: 01418 01419 if (left_type_type == right_type_type 01420 && left_type_size == right_type_size) 01421 return Type( left_type ); 01422 else if (right_type_type == VOID_TYPE) 01423 return Type( left_type ); 01424 else if (left_type_type == VOID_TYPE) 01425 return Type( right_type); 01426 else if (is_arithmetic_type(left_type_type) && 01427 is_arithmetic_type(right_type_type)) 01428 return arithmetic_result_type(left_type, right_type, op_rank); 01429 else if ((left_type_type == CHARACTER_TYPE) && 01430 (right_type_type == CHARACTER_TYPE)) 01431 return make_type(CHARACTER_TYPE,max(left_type_size,right_type_size), 01432 op_rank); 01433 else { 01434 cout << left_type << ' ' << op_string[op] 01435 << ' ' << right_type << endl; 01436 p_abort("Bad type combination"); 01437 01438 return make_type(UNDEFINED_TYPE); 01439 } 01440 01441 default: 01442 cout << left_type << ' ' << op_string[op] << ' ' << right_type << endl; 01443 p_abort("Bad operator"); 01444 break; 01445 } 01446 01447 return make_type(UNDEFINED_TYPE); 01448 } 01449 01450 Type 01451 expr_type(const OP_TYPE op, const List<Expression>&args) 01452 { 01453 int entries = args.entries(); 01454 01455 p_assert( entries > 0, 01456 "expr_type(const OP_TYPE, const List<Expression> &): " 01457 "args list must be non-empty"); 01458 01459 Iterator<Expression> iter = args; 01460 Type type_so_far = iter.current().type(); 01461 01462 for (++iter; iter.valid(); ++iter) 01463 type_so_far = expr_type(op, type_so_far, iter.current().type()); 01464 01465 return type_so_far; 01466 } 01467 01468 List<Expression> * 01469 expr_list(Expression * expr1 GIV(0), 01470 Expression * expr2 GIV(0), 01471 Expression * expr3 GIV(0), 01472 Expression * expr4 GIV(0), 01473 Expression * expr5 GIV(0), 01474 Expression * expr6 GIV(0), 01475 Expression * expr7 GIV(0), 01476 Expression * expr8 GIV(0), 01477 Expression * expr9 GIV(0), 01478 Expression * expr10 GIV(0)) 01479 { 01480 List<Expression> * list = new List<Expression>; 01481 01482 # define LIST_EXPR_ADD(expr) if (expr) list->ins_last(expr) 01483 01484 LIST_EXPR_ADD(expr1); 01485 LIST_EXPR_ADD(expr2); 01486 LIST_EXPR_ADD(expr3); 01487 LIST_EXPR_ADD(expr4); 01488 LIST_EXPR_ADD(expr5); 01489 LIST_EXPR_ADD(expr6); 01490 LIST_EXPR_ADD(expr7); 01491 LIST_EXPR_ADD(expr8); 01492 LIST_EXPR_ADD(expr9); 01493 LIST_EXPR_ADD(expr10); 01494 01495 # undef LIST_EXPR_ADD 01496 01497 return list; 01498 } 01499 01500 Expression * 01501 constant(int value) 01502 { 01503 return new IntConstExpr((int) value); 01504 } 01505 01506 Expression * 01507 constant(const char *data_string) 01508 { 01509 Type t = string_type(data_string); 01510 EXPR_TYPE e = t.data_type(); 01511 01512 switch (e) { 01513 case LOGICAL_TYPE: 01514 return new LogicalConstExpr(data_string); 01515 01516 case CHARACTER_TYPE: 01517 if (data_string[0] == '\'') 01518 return new StringConstExpr(data_string); 01519 else if (data_string[0] == '"') { 01520 /// ... Convert to single-quoted character constant 01521 char *single = double_to_single_quoted(data_string); 01522 Expression *string_expr = new StringConstExpr(single); 01523 delete [] single; 01524 return string_expr; 01525 } 01526 else 01527 return new HollerithConstExpr(data_string); 01528 01529 case REAL_TYPE: 01530 return new RealConstExpr(REAL_TYPE, data_string); 01531 01532 case DOUBLE_PRECISION_TYPE: 01533 return new RealConstExpr(DOUBLE_PRECISION_TYPE, data_string); 01534 01535 case INTEGER_TYPE: 01536 { 01537 int value; 01538 01539 sscanf((char *) data_string, "%d", &value); 01540 return new IntConstExpr(value); 01541 } 01542 01543 default: 01544 cout << e << endl; 01545 p_abort("Unexpected type for a constant"); 01546 break; 01547 } 01548 01549 return 0; 01550 } 01551 01552 Expression * 01553 keyword(const char *data_string) 01554 { 01555 p_assert( data_string, "keyword is null" ); 01556 01557 return new KeyExpr( data_string ); 01558 } 01559 01560 Expression * 01561 complex(Expression * real, Expression * imag) 01562 { 01563 return new ComplexExpr(real, imag); 01564 } 01565 01566 Expression * 01567 array_reference(Expression * array, Expression * subscripts) 01568 { 01569 p_assert((array != NULL) && (subscripts != NULL), 01570 "arg(s) to *arrayref* must be non-NULL"); 01571 01572 Expression *expr = new ArrayRefExpr(array->type(), array, subscripts); 01573 01574 determine_root_expr_type(*expr); 01575 01576 return expr; 01577 } 01578 01579 static inline Expression * 01580 create_nonbinary(List<Expression>*args, OP_TYPE op_type, const char *func_name) 01581 { 01582 if (args->entries() <= 0) { 01583 char buf[1000]; 01584 01585 sprintf(buf, "%s(List<Expression> *): args list must be non-empty", 01586 func_name); 01587 01588 p_abort(buf); 01589 } 01590 01591 return new NonBinaryExpr(op_type, expr_type(op_type, *args), args); 01592 } 01593 01594 Expression * 01595 add(Expression * expr1, Expression * expr2) 01596 { 01597 p_assert((expr1 != NULL) && (expr2 != NULL), 01598 "arg(s) to *add* must be non-NULL"); 01599 01600 return new NonBinaryExpr(ADD_OP, 01601 expr_type(ADD_OP, expr1->type(), expr2->type()), 01602 expr1, expr2); 01603 } 01604 01605 Expression * 01606 add(List<Expression> *args) 01607 { 01608 return create_nonbinary(args, ADD_OP, "add"); 01609 } 01610 01611 Expression * 01612 sub(Expression *expr1, Expression *expr2) 01613 { 01614 p_assert((expr1 != NULL) && (expr2 != NULL), 01615 "arg(s) to *sub* must be non-NULL"); 01616 01617 return new BinaryExpr(SUB_OP, 01618 expr_type(SUB_OP, expr1->type(), expr2->type()), 01619 expr1, expr2); 01620 } 01621 01622 Expression * 01623 mul(Expression * expr1, Expression * expr2) 01624 { 01625 p_assert((expr1 != NULL) && (expr2 != NULL), 01626 "arg(s) to *mul* must be non-NULL"); 01627 01628 return new NonBinaryExpr(MULT_OP, 01629 expr_type(MULT_OP, expr1->type(), expr2->type()), 01630 expr1, expr2); 01631 } 01632 01633 Expression * 01634 mul(List<Expression>*args) 01635 { 01636 return create_nonbinary(args, MULT_OP, "mul"); 01637 } 01638 01639 Expression * 01640 div(Expression * expr1, Expression * expr2) 01641 { 01642 p_assert((expr1 != NULL) && (expr2 != NULL), 01643 "arg(s) to *div* must be non-NULL"); 01644 01645 return new BinaryExpr(DIV_OP, 01646 expr_type(DIV_OP, expr1->type(), expr2->type()), 01647 expr1, expr2); 01648 } 01649 01650 Expression * 01651 exponent(Expression * expr1, Expression * expr2) 01652 { 01653 p_assert((expr1 != NULL) && (expr2 != NULL), 01654 "arg(s) to *exp* must be non-NULL"); 01655 01656 return new BinaryExpr(EXP_OP, 01657 expr_type(EXP_OP, expr1->type(), expr2->type()), 01658 expr1, expr2); 01659 } 01660 01661 Expression * 01662 keypair(Expression * expr1, Expression * expr2) 01663 { 01664 p_assert((expr1 != NULL) && (expr2 != NULL), 01665 "arg(s) to *keypair* must be non-NULL"); 01666 01667 return new BinaryExpr(KEYPAIR_OP, make_type(VOID_TYPE), expr1, expr2); 01668 } 01669 01670 Expression * 01671 eq(Expression * expr1, Expression * expr2) 01672 { 01673 p_assert((expr1 != NULL) && (expr2 != NULL), 01674 "arg(s) to *eq* must be non-NULL"); 01675 01676 return new BinaryExpr(EQ_OP, 01677 expr_type(EQ_OP, expr1->type(), expr2->type()), 01678 expr1, expr2); 01679 } 01680 01681 Expression * 01682 ne(Expression * expr1, Expression * expr2) 01683 { 01684 p_assert((expr1 != NULL) && (expr2 != NULL), 01685 "arg(s) to *ne* must be non-NULL"); 01686 01687 return new BinaryExpr(NE_OP, 01688 expr_type(NE_OP, expr1->type(), expr2->type()), 01689 expr1, expr2); 01690 } 01691 01692 Expression * 01693 lt(Expression * expr1, Expression * expr2) 01694 { 01695 p_assert((expr1 != NULL) && (expr2 != NULL), 01696 "arg(s) to *lt* must be non-NULL"); 01697 01698 return new BinaryExpr(LT_OP, 01699 expr_type(LT_OP, expr1->type(), expr2->type()), 01700 expr1, expr2); 01701 } 01702 01703 Expression * 01704 le(Expression * expr1, Expression * expr2) 01705 { 01706 p_assert((expr1 != NULL) && (expr2 != NULL), 01707 "arg(s) to *le* must be non-NULL"); 01708 01709 return new BinaryExpr(LE_OP, 01710 expr_type(LE_OP, expr1->type(), expr2->type()), 01711 expr1, expr2); 01712 } 01713 01714 Expression * 01715 gt(Expression * expr1, Expression * expr2) 01716 { 01717 p_assert((expr1 != NULL) && (expr2 != NULL), 01718 "arg(s) to *gt* must be non-NULL"); 01719 01720 return new BinaryExpr(GT_OP, 01721 expr_type(GT_OP, expr1->type(), expr2->type()), 01722 expr1, expr2); 01723 } 01724 01725 Expression * 01726 ge(Expression * expr1, Expression * expr2) 01727 { 01728 p_assert((expr1 != NULL) && (expr2 != NULL), 01729 "arg(s) to *ge* must be non-NULL"); 01730 01731 return new BinaryExpr(GE_OP, 01732 expr_type(GE_OP, expr1->type(), expr2->type()), 01733 expr1, expr2); 01734 } 01735 01736 Expression * 01737 or(Expression * expr1, Expression * expr2) 01738 { 01739 p_assert((expr1 != NULL) && (expr2 != NULL), 01740 "args to *or* must be non-NULL"); 01741 01742 return new NonBinaryExpr(OR_OP, 01743 expr_type(OR_OP, expr1->type(), expr2->type()), 01744 expr1, expr2); 01745 } 01746 01747 Expression * 01748 or(List<Expression> *args) 01749 { 01750 return create_nonbinary(args, OR_OP, "or"); 01751 } 01752 01753 Expression * 01754 and(Expression * expr1, Expression * expr2) 01755 { 01756 p_assert((expr1 != NULL) && (expr2 != NULL), 01757 "arg(s) to *and* must be non-NULL"); 01758 01759 return new NonBinaryExpr(AND_OP, 01760 expr_type(AND_OP, expr1->type(), expr2->type()), 01761 expr1, expr2); 01762 } 01763 01764 Expression * 01765 and(List<Expression> *args) 01766 { 01767 return create_nonbinary(args, AND_OP, "and"); 01768 } 01769 01770 Expression * 01771 eqv(Expression * expr1, Expression * expr2) 01772 { 01773 p_assert((expr1 != NULL) && (expr2 != NULL), 01774 "arg(s) to *eqv* must be non-NULL"); 01775 01776 return new NonBinaryExpr(EQV_OP, 01777 expr_type(EQV_OP, expr1->type(), expr2->type()), 01778 expr1, expr2); 01779 } 01780 01781 Expression * 01782 eqv(List<Expression> *args) 01783 { 01784 return create_nonbinary(args, EQV_OP, "eqv"); 01785 } 01786 01787 Expression * 01788 neqv(Expression * expr1, Expression * expr2) 01789 { 01790 p_assert((expr1 != NULL) && (expr2 != NULL), 01791 "arg(s) to *neqv* must be non-NULL"); 01792 01793 return new NonBinaryExpr(NEQV_OP, 01794 expr_type(NEQV_OP, expr1->type(), expr2->type()), 01795 expr1, expr2); 01796 } 01797 01798 Expression * 01799 neqv(List<Expression>*args) 01800 { 01801 return create_nonbinary(args, NEQV_OP, "neqv"); 01802 } 01803 01804 Expression * 01805 function_call(Expression * expr1, Expression * expr2) 01806 { 01807 p_assert((expr1 != NULL) && (expr2 != NULL), 01808 "both args to *function_call* must be non-NULL"); 01809 01810 p_assert(expr1->symbol().intrinsic() == NOT_INTRINSIC, 01811 "the symbol argument to function_call() must not be INTRINSIC" ); 01812 01813 return new FunctionCallExpr(expr1->symbol().type(), expr1, expr2); 01814 } 01815 01816 Expression * 01817 intrinsic_call(Expression * expr1, Expression * expr2) 01818 { 01819 p_assert((expr1 != NULL) && (expr2 != NULL), 01820 "both args to *intrinsic_call* must be non-NULL"); 01821 01822 p_assert( expr1->symbol().intrinsic() == IS_INTRINSIC, 01823 "the symbol argument to intrinsic_call() must be INTRINSIC" ); 01824 01825 Expression *expr 01826 = new IntrinsicCallExpr(expr1->symbol().type(), expr1, expr2); 01827 01828 determine_root_expr_type(*expr); 01829 01830 return expr; 01831 } 01832 01833 Expression * 01834 substring(Expression * expr1, Expression * expr2) 01835 { 01836 p_assert((expr1 != NULL) && (expr2 != NULL), 01837 "both args to *substring* must be non-NULL"); 01838 01839 return new SubStringExpr(expr_type(SUBSTRING_OP, 01840 expr1->type(), 01841 expr2->type()), 01842 expr1, 01843 expr2); 01844 } 01845 01846 Expression * 01847 concat(Expression * expr1, Expression * expr2) 01848 { 01849 p_assert((expr1 != NULL) && (expr2 != NULL), 01850 "both args to *concat* must be non-NULL"); 01851 01852 return new NonBinaryExpr(CONCAT_OP, 01853 expr_type(CONCAT_OP, 01854 expr1->type(), 01855 expr2->type()), 01856 expr1, 01857 expr2); 01858 } 01859 01860 Expression * 01861 colon(Expression * expr1, Expression * expr2, Expression * expr3 GIV(0)) 01862 { 01863 p_assert((expr1 != NULL) || (expr2 != NULL), 01864 "first two args to *colon* must be non-NULL"); 01865 01866 return new NonBinaryExpr(COLON_OP, make_type(VOID_TYPE), 01867 expr1, expr2, expr3); 01868 } 01869 01870 Expression * 01871 colon(List<Expression> *args) 01872 { 01873 return create_nonbinary(args, COLON_OP, "colon"); 01874 } 01875 01876 Expression * 01877 comma (List<Expression> *args) 01878 { 01879 return new CommaExpr(args); 01880 } 01881 01882 Expression * 01883 comma(Expression *expr1, Expression *expr2, 01884 Expression *expr3 GIV(0), Expression *expr4 GIV(0), 01885 Expression *expr5 GIV(0)) 01886 { 01887 p_assert((expr1 != NULL), "arg 1 to *comma* must be non-NULL"); 01888 p_assert((expr2 != NULL), "arg 2 to *comma* must be non-NULL"); 01889 01890 return new CommaExpr(expr1, expr2, expr3, expr4, expr5); 01891 } 01892 01893 Expression * 01894 comma(Expression * expr1) 01895 { 01896 p_assert((expr1 != NULL), "arg 1 to *comma* must be non-NULL"); 01897 01898 return new CommaExpr(expr1); 01899 } 01900 01901 Expression * 01902 comma() { 01903 return new CommaExpr(); 01904 } 01905 01906 Expression * 01907 unary_plus(Expression * expr) 01908 { 01909 p_assert(expr != NULL, "arg to *uplus* must be non-NULL"); 01910 01911 return new UnaryExpr(U_PLUS_OP, expr->type(), expr); 01912 } 01913 01914 Expression * 01915 unary_minus(Expression * expr) 01916 { 01917 p_assert(expr != NULL, "arg to *uminus* must be non-NULL"); 01918 01919 return new UnaryExpr(U_MINUS_OP, expr->type(), expr); 01920 } 01921 01922 Expression * 01923 do_expression(Expression * expr1, 01924 Expression * expr2) 01925 { 01926 p_assert((expr1 != NULL) || (expr2 != NULL), 01927 "first two args to *do_expression* must be non-NULL"); 01928 01929 return new DoExpr(expr1, expr2); 01930 } 01931 01932 Expression * 01933 equal(Expression * index, 01934 Expression * iter_space) 01935 { 01936 p_assert((index != NULL) || (iter_space != NULL), 01937 "first two args to *equal* must be non-NULL"); 01938 01939 return new EqualExpr(index->type(), index, iter_space); 01940 } 01941 01942 Expression * 01943 not(Expression * expr) 01944 { 01945 p_assert(expr != NULL, "arg to *not* must be non-NULL"); 01946 01947 return new UnaryExpr(NOT_OP, expr->type(), expr); 01948 } 01949 01950 01951 Expression * 01952 paren(Expression * expr) 01953 { 01954 p_assert(expr != NULL, "arg to *par* must be non-NULL"); 01955 01956 return new UnaryExpr(PAREN_OP, expr->type(), expr); 01957 } 01958 01959 Expression * 01960 id(const char *varname, const ProgramUnit & pgm) 01961 { 01962 const Symbol *s = pgm.symtab().find_ref(varname); 01963 01964 p_assert(s, "Symbol name passed to *id* does not exist in ProgramUnit"); 01965 return new IDExpr(s->type(), *s); 01966 } 01967 01968 Expression * 01969 id(const Symbol & symbol) 01970 { 01971 return new IDExpr(symbol.type(), symbol); 01972 } 01973 01974 Expression * 01975 new_variable(const char *varname, 01976 const Type & t, 01977 ProgramUnit & pgm) 01978 { 01979 Symbol *s = new VariableSymbol(varname, t, NOT_FORMAL, NOT_SAVED); 01980 01981 pgm.symtab().ins(s); 01982 01983 return new IDExpr(s->type(), *s); 01984 } 01985 01986 Expression * 01987 new_function(const char *funname, 01988 const Type & t, 01989 ProgramUnit & pgm) 01990 { 01991 Symbol *s = new FunctionSymbol(funname, t, IS_EXTERNAL, 01992 NOT_INTRINSIC, NOT_FORMAL); 01993 pgm.symtab().ins(s); 01994 01995 return new IDExpr(s->type(), *s); 01996 } 01997 01998 Expression * 01999 new_intrinsic(const char *funname, 02000 const Type & t, 02001 ProgramUnit & pgm) 02002 { 02003 Symbol *s = new FunctionSymbol(funname, t, NOT_EXTERNAL, 02004 IS_INTRINSIC, NOT_FORMAL); 02005 pgm.symtab().ins(s); 02006 02007 return new IDExpr(s->type(), *s); 02008 } 02009 02010 Expression * 02011 new_subroutine(const char *funname, 02012 ProgramUnit & pgm) 02013 { 02014 Symbol *s = new SubroutineSymbol(funname, IS_EXTERNAL, 02015 NOT_INTRINSIC, NOT_FORMAL); 02016 pgm.symtab().ins(s); 02017 02018 return new IDExpr(s->type(), *s); 02019 } 02020 02021 Expression * 02022 new_array_variable(const char *varname, const Type & t, 02023 ProgramUnit & pgm, Expression * bounds1, 02024 Expression * bounds2 GIV(0), 02025 Expression * bounds3 GIV(0), 02026 Expression * bounds4 GIV(0), 02027 Expression * bounds5 GIV(0)) 02028 { 02029 ArrayBounds *ab2 = 0; 02030 ArrayBounds *ab3 = 0; 02031 ArrayBounds *ab4 = 0; 02032 ArrayBounds *ab5 = 0; 02033 02034 p_assert(bounds1->op() == COLON_OP, 02035 "Array bound 1 is not a COLON expression"); 02036 02037 ArrayBounds *ab1 = new ArrayBounds(bounds1->left_guarded().clone(), 02038 bounds1->right_guarded().clone()); 02039 if (bounds2) { 02040 p_assert(bounds2->op() == COLON_OP, 02041 "Array bound 2 is not a COLON expression"); 02042 02043 ab2 = new ArrayBounds(bounds2->left_guarded().clone(), 02044 bounds2->right_guarded().clone()); 02045 } 02046 02047 if (bounds3) { 02048 p_assert(bounds3->op() == COLON_OP, 02049 "Array bound 3 is not a COLON expression"); 02050 02051 ab3 = new ArrayBounds(bounds3->left_guarded().clone(), 02052 bounds3->right_guarded().clone()); 02053 } 02054 02055 if (bounds4) { 02056 p_assert(bounds4->op() == COLON_OP, 02057 "Array bound 4 is not a COLON expression"); 02058 02059 ab4 = new ArrayBounds(bounds4->left_guarded().clone(), 02060 bounds4->right_guarded().clone()); 02061 } 02062 02063 if (bounds5) { 02064 p_assert(bounds5->op() == COLON_OP, 02065 "Array bound 5 is not a COLON expression"); 02066 02067 ab5 = new ArrayBounds(bounds5->left_guarded().clone(), 02068 bounds5->right_guarded().clone()); 02069 } 02070 02071 Symbol *s = new VariableSymbol(varname, t, NOT_FORMAL, NOT_SAVED, 02072 ab1, ab2, ab3, ab4, ab5); 02073 02074 pgm.symtab().ins(s); 02075 02076 return new IDExpr(s->type(), *s); 02077 } 02078 02079 Expression * 02080 omega() 02081 { 02082 return new OmegaExpr; 02083 } 02084 02085 Expression * 02086 null_to_omega(Expression * expr) 02087 { 02088 return (expr) ? expr : omega(); 02089 } 02090 02091 Expression * 02092 infinity(int s GIV(1)) 02093 { 02094 return new InfinityExpr(s); 02095 } 02096 02097 //------------------------------------------------------------------------ 02098 02099 Expression * 02100 alpha(Expression *parameters) 02101 { 02102 p_assert(parameters, 02103 "parameters argument to *alpha* must be non-NULL"); 02104 02105 return new GSAExpr(ALPHA_OP, expr_type(ALPHA_OP, parameters->arg_list()), 02106 parameters); 02107 } 02108 02109 Expression * 02110 gamma(Expression *gate, Expression *parameters) 02111 { 02112 p_assert(parameters, 02113 "parameters (second) argument to *gamma* must be non-NULL"); 02114 02115 return new GSAExpr(GAMMA_OP, expr_type(GAMMA_OP, parameters->arg_list()), 02116 parameters, gate); 02117 } 02118 02119 Expression * 02120 mu(Expression *parameters) 02121 { 02122 p_assert(parameters, 02123 "parameter argument to *mu* must be non-NULL"); 02124 02125 return new GSAExpr(MU_OP, expr_type(MU_OP, parameters->arg_list()), 02126 parameters); 02127 } 02128 02129 Expression * 02130 theta(Expression *parameters) 02131 { 02132 p_assert(parameters, 02133 "parameter argument to *mu* must be non-NULL"); 02134 02135 return new GSAExpr(THETA_OP, expr_type(THETA_OP, parameters->arg_list()), 02136 parameters); 02137 } 02138 02139 Expression * 02140 eta(Expression *gate, Expression *parameters) 02141 { 02142 p_assert(parameters, 02143 "parameters (second) argument to *eta* must be non-NULL"); 02144 02145 return new GSAExpr(ETA_OP, expr_type(ETA_OP, parameters->arg_list()), 02146 parameters, gate); 02147 } 02148 02149 Expression * 02150 mu(Expression *parameters, Expression * gate) 02151 { 02152 p_assert(parameters, 02153 "parameter argument to *mu* must be non-NULL"); 02154 02155 return new GSAExpr(MU_OP, expr_type(MU_OP, parameters->arg_list()), 02156 parameters, gate); 02157 } 02158 02159 //------------------------------------------------------------------------ 02160 02161 static void 02162 _cannot_coerce(const Type & from, EXPR_TYPE to) 02163 { 02164 String from_str, to_str; 02165 02166 Type to_type(to); 02167 02168 from.format(from_str); 02169 to_type.format(to_str); 02170 02171 cerr << "\n\nError: coerce(): Tried to coerce from type " 02172 << from_str << " to type " << to_str << endl << endl; 02173 02174 p_abort("(See above error message)"); 02175 } 02176 02177 static void 02178 _assert_can_coerce(const Type & from, EXPR_TYPE to, 02179 EXPR_TYPE from1, 02180 EXPR_TYPE from2 = (EXPR_TYPE) (-1), 02181 EXPR_TYPE from3 = (EXPR_TYPE) (-1), 02182 EXPR_TYPE from4 = (EXPR_TYPE) (-1), 02183 EXPR_TYPE from5 = (EXPR_TYPE) (-1)) 02184 { 02185 EXPR_TYPE f = from.data_type(); 02186 02187 if (f == from1 || f == from2 || f == from3 || f == from4 || f == from5) 02188 return; 02189 02190 _cannot_coerce(from, to); 02191 } 02192 02193 static Expression * 02194 _coerce(Expression * expr, const char *intrin_name, 02195 EXPR_TYPE NOTUSED(type), ProgramUnit & pgm) 02196 { 02197 p_assert(intrin_name, "_coerce(): intrin_name is NULL"); 02198 02199 Type result_type;/// ... Select size by default 02200 Symbol *intrin_sym = pgm.symtab().find_ref(intrin_name); 02201 02202 if (intrin_sym) { 02203 p_assert(intrin_sym->intrinsic(), 02204 "_coerce(): Intrinsic name already exists in symbol " 02205 "table, but is not an intrinsic function"); 02206 } 02207 else { 02208 intrin_sym = &pgm.symtab().ins( 02209 new FunctionSymbol(intrin_name, result_type, 02210 NOT_EXTERNAL, IS_INTRINSIC, NOT_FORMAL)); 02211 } 02212 02213 return new IntrinsicCallExpr(intrin_sym->type(), 02214 new IDExpr(intrin_sym->type(), 02215 *intrin_sym), 02216 new CommaExpr(expr)); 02217 } 02218 02219 Expression * 02220 coerce(Expression * expr, EXPR_TYPE type, ProgramUnit & pgm) 02221 { 02222 if (type == expr->type().data_type()) 02223 return expr; 02224 else { 02225 /// ... const char *intrin_name = 0; 02226 02227 switch (type) { 02228 02229 case VOID_TYPE: 02230 _cannot_coerce(expr->type(), type); 02231 return 0; 02232 02233 case INTEGER_TYPE: 02234 _assert_can_coerce(expr->type(), type, 02235 INTEGER_TYPE, REAL_TYPE, DOUBLE_PRECISION_TYPE, 02236 COMPLEX_TYPE, CHARACTER_TYPE); 02237 02238 if (expr->type().data_type() == CHARACTER_TYPE) 02239 return _coerce(expr, "ICHAR", INTEGER_TYPE, pgm); 02240 else 02241 return _coerce(expr, "INT", INTEGER_TYPE, pgm); 02242 02243 case REAL_TYPE: 02244 _assert_can_coerce(expr->type(), type, 02245 INTEGER_TYPE, REAL_TYPE, DOUBLE_PRECISION_TYPE, 02246 COMPLEX_TYPE); 02247 02248 return _coerce(expr, "REAL", REAL_TYPE, pgm); 02249 02250 case DOUBLE_PRECISION_TYPE: 02251 _assert_can_coerce(expr->type(), type, 02252 INTEGER_TYPE, REAL_TYPE, DOUBLE_PRECISION_TYPE, 02253 COMPLEX_TYPE); 02254 02255 return _coerce(expr, "DBLE", DOUBLE_PRECISION_TYPE, pgm); 02256 02257 case COMPLEX_TYPE: 02258 _assert_can_coerce(expr->type(), type, 02259 INTEGER_TYPE, REAL_TYPE, DOUBLE_PRECISION_TYPE, 02260 COMPLEX_TYPE); 02261 02262 return _coerce(expr, "CMPLX", COMPLEX_TYPE, pgm); 02263 02264 case CHARACTER_TYPE: 02265 _assert_can_coerce(expr->type(), type, INTEGER_TYPE); 02266 02267 return _coerce(expr, "CHAR", CHARACTER_TYPE, pgm); 02268 02269 default: 02270 _cannot_coerce(expr->type(), type); 02271 break; 02272 } 02273 } 02274 02275 return 0; 02276 } 02277 02278 //------------------------------------------------------------------------ 02279 02280 02281 Listable * 02282 Expression::listable_clone() const 02283 { 02284 return clone(); 02285 } 02286 02287 void 02288 Expression::relink_eptrs(ProgramUnit & NOTUSED(p)) 02289 { 02290 /// ... nothing to do 02291 } 02292 02293 int 02294 Expression::compare(const Expression & ex) const 02295 { 02296 if (op() != ex.op()) 02297 return (((int) op()<(int) ex.op()) ? -1 : 1); 02298 02299 const Type & x = type(); 02300 const Type & y = ex.type(); 02301 02302 if (x.data_type() != y.data_type()) 02303 return (((int) x.data_type()<(int) y.data_type()) ? -1 : 1); 02304 02305 if (x.size() != y.size()) 02306 return ((x.size()<y.size()) ? -1 : 1); 02307 02308 return node_compare(ex); 02309 } 02310 02311 int 02312 Expression::node_compare(const Expression & ex) const 02313 { 02314 if (arg_list().entries() != ex.arg_list().entries()) 02315 if (arg_list().entries() > ex.arg_list().entries()) 02316 return 1; 02317 else 02318 return -1; 02319 else { 02320 int cmp = 0; 02321 02322 Iterator<Expression> a_iter = arg_list(); 02323 Iterator<Expression> b_iter = ex.arg_list(); 02324 02325 for (; a_iter.valid() && b_iter.valid(); ++a_iter, ++b_iter) 02326 if ((cmp = a_iter.current().compare(b_iter.current())) != 0) 02327 return cmp; 02328 } 02329 02330 return 0; 02331 } 02332 02333 const ExprSignature & 02334 Expression::update_signature() 02335 { 02336 _signature_live().clear(); 02337 02338 _signature_live().merge( (int) op() ); 02339 02340 /// ... Commented out the inclusion of the type in the signature so 02341 /// ... as to speed up update_signature(), which simplify() calls a 02342 /// ... lot. 02343 02344 /// ... _signature_live().merge( (int) type().data_type() ); 02345 /// ... _signature_live().merge( type().size() ); 02346 02347 for (Iterator<Expression> iter = arg_list(); iter.valid(); ++iter) 02348 _signature_live().merge( iter.current().signature() ); 02349 02350 return signature(); 02351 } 02352 02353 const ExprSignature & 02354 Expression::create_signature() 02355 { 02356 for (Iterator<Expression> iter = arg_list(); iter.valid(); ++iter) 02357 iter.current().create_signature(); 02358 02359 update_signature(); 02360 02361 return signature(); 02362 } 02363 02364 const ExprSignature & 02365 Expression::standardize() 02366 { 02367 for (Iterator<Expression> iter = arg_list(); iter.valid(); ++iter) 02368 iter.current().standardize(); 02369 02370 if (is_commutative(op())) 02371 _sort_expr_list(arg_list()); 02372 else if (op() == INTRINSIC_CALL_OP) { 02373 const char *intr_name = intrinsic().symbol().name_ref(); 02374 if (is_commutative_intrinsic_name(intr_name)) { 02375 _sort_expr_list(parameters_guarded().arg_list()); 02376 parameters_guarded().update_signature(); 02377 } 02378 } 02379 02380 update_signature(); 02381 02382 return signature(); 02383 } 02384 02385 const Expression & 02386 Expression::lambda_expr() const 02387 { 02388 p_abort("const Expression &lambda_expr() const called for non-LambdaCallExpr"); 02389 return DUMMY_EXPR_REF; 02390 } 02391 02392 Expression & 02393 Expression::lambda_expr() 02394 { 02395 p_abort("Expression &lambda_expr() called for non-LambdaCallExpr"); 02396 return DUMMY_EXPR_REF; 02397 } 02398 02399 void 02400 Expression::lambda_expr(Expression *) 02401 { 02402 p_abort("void lambda_expr(Expression *) called for non-LambdaCallExpr"); 02403 } 02404 02405 Boolean 02406 Expression::args_are_non_null() const 02407 { 02408 return True; 02409 } 02410 02411 const List<Expression> & 02412 Expression::arg_list() const 02413 { 02414 static List<Expression> *_empty_arg_list = 0; /// ... List of no arguments 02415 02416 if (_empty_arg_list == 0) 02417 _empty_arg_list = new List<Expression>; 02418 02419 _empty_arg_list->fix_size(); 02420 02421 return *_empty_arg_list; 02422 } 02423 02424 List<Expression> & 02425 Expression::arg_list() 02426 { 02427 static List<Expression> *_empty_arg_list = 0; /// ... List of no arguments 02428 02429 if (_empty_arg_list == 0) 02430 _empty_arg_list = new List<Expression>; 02431 02432 _empty_arg_list->fix_size(); 02433 02434 return *_empty_arg_list; 02435 } 02436 02437 const RefList<Expression> * 02438 Expression::arg_refs() const 02439 { 02440 return new RefList<Expression>; 02441 } 02442 02443 02444 02445 /// DUMMY FUNCTIONS 02446 02447 int 02448 Expression::value() const 02449 { 02450 _ref_error("int value() const"); 02451 return 0; 02452 } 02453 02454 void 02455 Expression::value(int NOTUSED(v)) 02456 { 02457 _ref_error("value(int v)"); 02458 } 02459 02460 const char * 02461 Expression::data_ref() const 02462 { 02463 return 0; 02464 } 02465 02466 const String & 02467 Expression::str_data() const 02468 { 02469 _ref_error("const String & str_data() const"); 02470 return *((String *)0); 02471 } 02472 02473 String & 02474 Expression::str_data() 02475 { 02476 _ref_error("String & str_data()"); 02477 return *((String *)0); 02478 } 02479 02480 void 02481 Expression::data(const char *NOTUSED(v)) 02482 { 02483 _ref_error("data(const char *v)"); 02484 } 02485 02486 const Expression & 02487 Expression::real_part() const 02488 { 02489 _ref_error("const Expression & real_part() const"); 02490 return DUMMY_EXPR_REF; 02491 } 02492 02493 Expression & 02494 Expression::real_part() 02495 { 02496 _ref_error("Expression & real_part()"); 02497 return DUMMY_EXPR_REF; 02498 } 02499 02500 void 02501 Expression::real_part(Expression * NOTUSED(e)) 02502 { 02503 _ref_error("real_part(Expression* e)"); 02504 } 02505 02506 const Expression & 02507 Expression::imaginary_part() const 02508 { 02509 _ref_error("const Expression & imaginary_part() const"); 02510 return DUMMY_EXPR_REF; 02511 } 02512 02513 Expression & 02514 Expression::imaginary_part() 02515 { 02516 _ref_error("Expression & imaginary_part()"); 02517 return DUMMY_EXPR_REF; 02518 } 02519 02520 void 02521 Expression::imaginary_part(Expression * NOTUSED(e)) 02522 { 02523 _ref_error("imaginary_part(Expression* e)"); 02524 } 02525 02526 const Expression & 02527 Expression::array() const 02528 { 02529 _ref_error("const Expression & array() const"); 02530 return DUMMY_EXPR_REF; 02531 } 02532 02533 Expression & 02534 Expression::array() 02535 { 02536 _ref_error("Expression & array()"); 02537 return DUMMY_EXPR_REF; 02538 } 02539 02540 void 02541 Expression::array(Expression * NOTUSED(e)) 02542 { 02543 _ref_error("array(Expression* e)"); 02544 } 02545 02546 const Expression & 02547 Expression::subscript() const 02548 { 02549 _ref_error("const Expression & subscript() const"); 02550 return DUMMY_EXPR_REF; 02551 } 02552 02553 Expression & 02554 Expression::subscript() 02555 { 02556 _ref_error("Expression & subscript()"); 02557 return DUMMY_EXPR_REF; 02558 } 02559 02560 void 02561 Expression::subscript(Expression * NOTUSED(e)) 02562 { 02563 _ref_error("subscript(Expression* e)"); 02564 } 02565 02566 const Expression & 02567 Expression::string() const 02568 { 02569 _ref_error("const Expression & string() const"); 02570 return DUMMY_EXPR_REF; 02571 } 02572 02573 Expression & 02574 Expression::string() 02575 { 02576 _ref_error("Expression & string()"); 02577 return DUMMY_EXPR_REF; 02578 } 02579 02580 void 02581 Expression::string(Expression * NOTUSED(e)) 02582 { 02583 _ref_error("string(Expression* e)"); 02584 } 02585 02586 const Expression & 02587 Expression::bound() const 02588 { 02589 _ref_error("const Expression & bound() const"); 02590 return DUMMY_EXPR_REF; 02591 } 02592 02593 Expression & 02594 Expression::bound() 02595 { 02596 _ref_error("Expression & bound()"); 02597 return DUMMY_EXPR_REF; 02598 } 02599 02600 void 02601 Expression::bound(Expression * NOTUSED(e)) 02602 { 02603 _ref_error("bound(Expression* e)"); 02604 } 02605 02606 const Expression & 02607 Expression::left_guarded() const 02608 { 02609 _ref_error("const Expression & left_guarded() const"); 02610 return DUMMY_EXPR_REF; 02611 } 02612 02613 Expression & 02614 Expression::left_guarded() 02615 { 02616 _ref_error("Expression & left_guarded()"); 02617 return DUMMY_EXPR_REF; 02618 } 02619 02620 void 02621 Expression::left(Expression * NOTUSED(e)) 02622 { 02623 _ref_error("left(Expression* e)"); 02624 } 02625 02626 Boolean 02627 Expression::left_valid() const 02628 { 02629 return False; 02630 }; 02631 02632 Expression * 02633 Expression::grab_left() 02634 { 02635 _ref_error("Expression * grab_left()"); 02636 return 0; 02637 } 02638 02639 const Expression & 02640 Expression::right_guarded() const 02641 { 02642 _ref_error("const Expression & right_guarded() const"); 02643 return DUMMY_EXPR_REF; 02644 } 02645 02646 Expression & 02647 Expression::right_guarded() 02648 { 02649 _ref_error("Expression & right_guarded()"); 02650 return DUMMY_EXPR_REF; 02651 } 02652 02653 void 02654 Expression::right(Expression * NOTUSED(e)) 02655 { 02656 _ref_error("right(Expression* e)"); 02657 } 02658 02659 Boolean 02660 Expression::right_valid() const 02661 { 02662 return False; 02663 } 02664 02665 Expression * 02666 Expression::grab_right() 02667 { 02668 _ref_error("Expression * grab_right()"); 02669 return 0; 02670 } 02671 02672 const Expression & 02673 Expression::function() const 02674 { 02675 _ref_error("const Expression & function() const"); 02676 return DUMMY_EXPR_REF; 02677 } 02678 02679 Expression & 02680 Expression::function() 02681 { 02682 _ref_error("Expression & function()"); 02683 return DUMMY_EXPR_REF; 02684 } 02685 02686 void 02687 Expression::function(Expression * NOTUSED(e)) 02688 { 02689 _ref_error("function(Expression* e)"); 02690 } 02691 02692 const Expression & 02693 Expression::parameters_guarded() const 02694 { 02695 _ref_error("const Expression & parameters_guarded() const"); 02696 return DUMMY_EXPR_REF; 02697 } 02698 02699 Expression & 02700 Expression::parameters_guarded() 02701 { 02702 _ref_error("Expression & parameters_guarded()"); 02703 return DUMMY_EXPR_REF; 02704 } 02705 02706 void 02707 Expression::parameters(Expression * NOTUSED(e)) 02708 { 02709 _ref_error("parameters(Expression* e)"); 02710 } 02711 02712 Boolean 02713 Expression::parameters_valid() const 02714 { 02715 return False; 02716 } 02717 02718 const Expression & 02719 Expression::expr_guarded() const 02720 { 02721 _ref_error("const Expression & expr_guarded() const"); 02722 return DUMMY_EXPR_REF; 02723 } 02724 02725 Expression & 02726 Expression::expr_guarded() 02727 { 02728 _ref_error("Expression & expr_guarded()"); 02729 return DUMMY_EXPR_REF; 02730 } 02731 02732 void 02733 Expression::expr(Expression * NOTUSED(e)) 02734 { 02735 _ref_error("expr(Expression* e)"); 02736 } 02737 02738 Boolean 02739 Expression::expr_valid() const 02740 { 02741 return False; 02742 } 02743 02744 Expression * 02745 Expression::grab_expr() 02746 { 02747 _ref_error("Expression * grab_expr()"); 02748 return 0; 02749 } 02750 02751 const Symbol & 02752 Expression::symbol() const 02753 { 02754 _ref_error("const Symbol & symbol() const"); 02755 return *((const Symbol *) 0); 02756 } 02757 02758 Symbol & 02759 Expression::symbol() 02760 { 02761 _ref_error("Symbol & symbol()"); 02762 return *((Symbol *) 0); 02763 } 02764 02765 void 02766 Expression::symbol(const Symbol & NOTUSED(s)) 02767 { 02768 _ref_error("symbol(Symbol & s)"); 02769 } 02770 02771 const Expression & 02772 Expression::substituted_guarded() const 02773 { 02774 _ref_error("const Expression & substituted_guarded() const"); 02775 return DUMMY_EXPR_REF; 02776 } 02777 02778 Expression & 02779 Expression::substituted_guarded() 02780 { 02781 _ref_error("Expression & substituted_guarded()"); 02782 return DUMMY_EXPR_REF; 02783 } 02784 02785 void 02786 Expression::substituted(Expression * NOTUSED(e)) 02787 { 02788 _ref_error("substituted(Expression* e)"); 02789 } 02790 02791 Boolean 02792 Expression::substituted_valid() const 02793 { 02794 return False; 02795 } 02796 02797 Expression * 02798 Expression::grab_substituted() 02799 { 02800 _ref_error("Expression * grab_substituted() const"); 02801 return 0; 02802 } 02803 02804 const Expression & 02805 Expression::iolist() const 02806 { 02807 _ref_error("const Expression & iolist() const"); 02808 return DUMMY_EXPR_REF; 02809 } 02810 02811 Expression & 02812 Expression::iolist() 02813 { 02814 _ref_error("Expression & iolist()"); 02815 return DUMMY_EXPR_REF; 02816 } 02817 02818 void 02819 Expression::iolist(Expression * NOTUSED(e)) 02820 { 02821 _ref_error("iolist(Expression* e)"); 02822 } 02823 02824 const Expression & 02825 Expression::iterator() const 02826 { 02827 _ref_error("const Expression & iterator() const"); 02828 return DUMMY_EXPR_REF; 02829 } 02830 02831 Expression & 02832 Expression::iterator() 02833 { 02834 _ref_error("Expression & iterator()"); 02835 return DUMMY_EXPR_REF; 02836 } 02837 02838 void 02839 Expression::iterator(Expression * NOTUSED(e)) 02840 { 02841 02842 _ref_error("iterator(Expression* e)"); 02843 } 02844 02845 const Expression & 02846 Expression::index_id() const 02847 { 02848 _ref_error("const Expression & index_id() const"); 02849 return DUMMY_EXPR_REF; 02850 } 02851 02852 Expression & 02853 Expression::index_id() 02854 { 02855 _ref_error("Expression & index_id()"); 02856 return DUMMY_EXPR_REF; 02857 } 02858 02859 void 02860 Expression::index_id(Expression * NOTUSED(e)) 02861 { 02862 _ref_error("index_id(Expression* e)"); 02863 } 02864 02865 const Expression & 02866 Expression::iteration_space() const 02867 { 02868 _ref_error("const Expression & iteration_space() const"); 02869 return DUMMY_EXPR_REF; 02870 } 02871 02872 Expression & 02873 Expression::iteration_space() 02874 { 02875 _ref_error("Expression & iteration_space()"); 02876 return DUMMY_EXPR_REF; 02877 } 02878 02879 void 02880 Expression::iteration_space(Expression * NOTUSED(e)) 02881 { 02882 02883 _ref_error("iteration_space(Expression* e)"); 02884 } 02885 02886 const Expression & 02887 Expression::intrinsic() const 02888 { 02889 _ref_error("const Expression & intrinsic() const"); 02890 return DUMMY_EXPR_REF; 02891 } 02892 02893 Expression & 02894 Expression::intrinsic() 02895 { 02896 _ref_error("Expression & intrinsic()"); 02897 return DUMMY_EXPR_REF; 02898 } 02899 02900 void 02901 Expression::intrinsic(Expression * NOTUSED(e)) 02902 { 02903 _ref_error("intrinsic(Expression* e)"); 02904 } 02905 02906 int 02907 Expression::entry() const 02908 { 02909 _ref_error("int entry() const"); 02910 return 0; 02911 } 02912 02913 void 02914 Expression::entry(int NOTUSED(e)) 02915 { 02916 _ref_error("entry(int e)"); 02917 } 02918 02919 const Format & 02920 Expression::format() const 02921 { 02922 _ref_error("const Format & format() const"); 02923 return *((const Format *) 0); 02924 } 02925 02926 Format & 02927 Expression::format() 02928 { 02929 _ref_error("Format & format()"); 02930 return *((Format *) 0); 02931 } 02932 02933 void 02934 Expression::format(Format & NOTUSED(format)) 02935 { 02936 _ref_error("format(Format & format)"); 02937 } 02938 02939 const Statement & 02940 Expression::stmt() const 02941 { 02942 _ref_error("const Statement & stmt() const"); 02943 return *((const Statement *) 0); 02944 } 02945 02946 Statement & 02947 Expression::stmt() 02948 { 02949 _ref_error("Statement & stmt()"); 02950 return *((Statement *) 0); 02951 } 02952 02953 void 02954 Expression::stmt(Statement & NOTUSED(stmt)) 02955 { 02956 _ref_error("stmt(Statement & stmt)"); 02957 } 02958 02959 int 02960 Expression::sign() const 02961 { 02962 _ref_error("int sign() const"); 02963 return 0; 02964 } 02965 02966 void 02967 Expression::sign(int NOTUSED(s)) 02968 { 02969 _ref_error("sign(int s)"); 02970 } 02971 02972 const Expression & 02973 Expression::gate() const 02974 { 02975 _ref_error("const Expression & gate() const"); 02976 return DUMMY_EXPR_REF; 02977 } 02978 02979 Expression & 02980 Expression::gate() 02981 { 02982 _ref_error("Expression & gate()"); 02983 return DUMMY_EXPR_REF; 02984 } 02985 02986 void 02987 Expression::gate(Expression * NOTUSED(e)) 02988 { 02989 _ref_error("gate(Expression* e)"); 02990 } 02991 02992 /// This print function is to satisfy Listable::print(...) 02993 02994 void 02995 Expression::print(ostream & o) const 02996 { 02997 print_debug(o, subst_field_print); 02998 } 02999 03000 ostream & 03001 operator << (ostream & o, const Expression & e) 03002 { 03003 e.print_debug(o, subst_field_print); 03004 03005 if (e._overflow) 03006 o << "{" << *(e._overflow) << "}"; 03007 03008 return o; 03009 } 03010 03011 /// tableEntry takes an integer and returns a pointer to an Expression 03012 /// object which represents another entry in the expression table. This 03013 /// intermediate table-entry expression object is an intermediate form 03014 /// which is only used in converting expressions from table form to 03015 /// expression object form and should not be used to represent actual 03016 /// expressions. 03017 03018 Expression * 03019 Expression::tableEntry(int n) 03020 { 03021 Expression *t = new TableExpr(n); 03022 03023 return t; 03024 } 03025 03026 /// Helper function: used to get the type field. 03027 03028 void 03029 Expression::get_type(BinRep & typebin, const char *exprname) 03030 { 03031 if (!typebin.is_string()) { 03032 cerr << exprname 03033 << "Expr::convert: type field doesn't contain string\n"; 03034 p_abort("(See above error message)"); 03035 } 03036 03037 String s; 03038 03039 typebin.to_string(s); 03040 03041 if (s == "INTEGER") 03042 type(make_type(INTEGER_TYPE)); 03043 else if (s == "REAL") 03044 type(make_type(REAL_TYPE)); 03045 else if (s == "DOUBLE PRECISION") 03046 type(make_type(DOUBLE_PRECISION_TYPE)); 03047 else if (s == "CHARACTER") 03048 type(make_type(CHARACTER_TYPE)); 03049 else if (s == "COMPLEX") 03050 type(make_type(COMPLEX_TYPE)); 03051 else if (s == "LOGICAL") 03052 type(make_type(LOGICAL_TYPE)); 03053 else if (s == "VOID") 03054 type(make_type(VOID_TYPE)); 03055 else { 03056 cerr << exprname 03057 << "Expr::convert: Unrecognized string in 'type' field: " 03058 << s << endl; 03059 p_abort("(See above error message)"); 03060 } 03061 } 03062 03063 /// Helper function: insert leftovers into the overflow 03064 03065 void 03066 Expression::make_overflow(Iterator<BinRep> & iter, const char *exname) 03067 { 03068 warn_overflow_map(exname, iter.current()); 03069 03070 if (!_overflow) { 03071 _overflow = new BinRep; 03072 Set<BinRep> *S = new Set<BinRep>; 03073 _overflow->put_set( S ); 03074 } 03075 03076 _overflow->ins(iter.current()); 03077 } 03078 03079 /// Helper function: Make sure overflow is empty 03080 03081 void 03082 Expression::empty_overflow() 03083 { 03084 if (_overflow) 03085 delete _overflow; 03086 03087 _overflow = 0; 03088 } 03089 03090 int 03091 Expression::exchange_expr( VDL & vdl ) 03092 { 03093 int index = vdl.look_up_expr( *this ); 03094 03095 if (index >= 0) 03096 return index; 03097 03098 BinRep *b = CASTAWAY(BinRep *) vdl.data_ref(); 03099 BinRep *br = new BinRep( new Set<BinRep> ); 03100 03101 List<BinRep> & L = b->find_ref( "expression" )->to_tuple(); 03102 03103 L.ins_last( br ); 03104 03105 BinRep *bs = new BinRep( new List<BinRep> ); 03106 bs->to_tuple().ins_last(new BinRep( "type" )); 03107 bs->to_tuple().ins_last(new BinRep( this->type().name_ref() )); 03108 br->to_set().ins( bs ); 03109 03110 bs->to_tuple().ins_last(new BinRep( "size" )); 03111 bs->to_tuple().ins_last(new BinRep( this->type().size() )); 03112 br->to_set().ins( bs ); 03113 03114 index = L.entries(); 03115 03116 vdl.install_expr( *this, index ); 03117 03118 return index; 03119 } 03120 03121 /// Function used for writing expressions, specifies Fortran 77 03122 /// operator-precedence 03123 03124 int 03125 operator_precedence(const OP_TYPE ot) 03126 { 03127 switch (ot) { 03128 case PAREN_OP: 03129 case LAMBDA_CALL_OP: 03130 case ARG_OP: 03131 return 0; 03132 03133 case U_PLUS_OP: 03134 case U_MINUS_OP: 03135 case SUB_OP: 03136 case ADD_OP: 03137 return 70; 03138 03139 case NOT_OP: 03140 return 40; 03141 03142 case EQ_OP: 03143 case GE_OP: 03144 case NE_OP: 03145 case LT_OP: 03146 case LE_OP: 03147 case GT_OP: 03148 return 50; 03149 03150 case DIV_OP: 03151 case INTDIV_OP: 03152 case RATDIV_OP: 03153 case MULT_OP: 03154 return 80; 03155 03156 case EXP_OP: 03157 return 90; 03158 03159 case CONCAT_OP: 03160 return 60; 03161 03162 case OR_OP: 03163 return 20; 03164 03165 case AND_OP: 03166 return 30; 03167 03168 case EQV_OP: 03169 case NEQV_OP: 03170 return 10; 03171 03172 case COMMA_OP: 03173 return 1; 03174 03175 default: 03176 return -1; 03177 } 03178 } 03179 03180 /// print the expression to \'o\', parenthesizing if the precedence 03181 /// calls for it. 03182 03183 void 03184 print_prec(OP_TYPE parent_op, const Expression * e, ostream & o) 03185 { 03186 if (!e) 03187 o << "<UNDEFINED>"; 03188 else { 03189 int e_prec = operator_precedence(e->op()); 03190 int our_prec = operator_precedence(parent_op); 03191 Boolean print_with_paren = False; 03192 03193 if (e_prec != -1 && our_prec != -1 03194 && (e_prec < our_prec 03195 || (e_prec == our_prec 03196 && (e->op() != COMMA_OP) 03197 && (1 || parent_op == EXP_OP 03198 || parent_op == U_MINUS_OP 03199 || parent_op == U_PLUS_OP)))) { 03200 print_with_paren = True; 03201 } 03202 03203 switch (e->op()) { 03204 case INTEGER_CONSTANT_OP: 03205 if (e->value()<0) 03206 print_with_paren = True; 03207 break; 03208 case REAL_CONSTANT_OP: 03209 if (e->data_ref()[0] == '-') 03210 print_with_paren = True; 03211 break; 03212 default: 03213 /// ... do nothing 03214 break; 03215 } 03216 03217 if (!print_with_paren && dbx_full_parenthesization) { 03218 /// ... Override and ADD parentheses only if the following 03219 /// ... cases hold. (Pretty much things that are leaves 03220 /// ... don't want parentheses for aesthetic and syntax reasons). 03221 03222 if (!e->is_wildcard()) { 03223 switch (e->op()) { 03224 default: 03225 /// ... DO override for anything not specifically specified 03226 print_with_paren = True; 03227 break; 03228 03229 case INTEGER_CONSTANT_OP: 03230 case REAL_CONSTANT_OP: 03231 case STRING_CONSTANT_OP: 03232 case LOGICAL_CONSTANT_OP: 03233 case HOLLERITH_CONSTANT_OP: 03234 case ARRAY_REF_OP: 03235 case SUBSTRING_OP: 03236 case FUNCTION_CALL_OP: 03237 case INTRINSIC_CALL_OP: 03238 case LAMBDA_CALL_OP: 03239 case ARG_OP: 03240 case RETURN_OP: 03241 case LABEL_OP: 03242 case IO_STAR_OP: 03243 case FORMAT_OP: 03244 case ID_OP: 03245 case KEY_OP: 03246 case KEYPAIR_OP: 03247 case DO_OP: 03248 case EQUAL_OP: 03249 case COMMA_OP: 03250 /// ... DON'T OVERRIDE FOR THESE LEAF-TYPES 03251 break; 03252 } 03253 } 03254 } 03255 03256 if (print_with_paren) 03257 o << "(" << *e << ")"; 03258 else 03259 o << *e; 03260 } 03261 } 03262 03263 /// Helper function used to print the given list, sepperating each 03264 /// element by c. ot is op_type of parent expr. 03265 03266 void 03267 print_prec_list(ostream & o, OP_TYPE optype, const List<Expression> &l, 03268 const char *c) 03269 { 03270 Iterator<Expression> iter = l; 03271 03272 if (iter.end()) { 03273 /// ... An empty COLON list is meaningful. i.e. A(:) 03274 if (optype == COLON_OP) 03275 o << c; 03276 } 03277 else { 03278 print_prec(optype, &iter.current(), o); 03279 iter.next(); 03280 03281 if (iter.end()) { 03282 /// ... An single element COLON list is meaningful. i.e. A(5:) 03283 if (optype == COLON_OP) 03284 o << c; 03285 } 03286 else { 03287 for ( ; !iter.end(); iter.next()) { 03288 o << c; 03289 print_prec(optype, &iter.current(), o); 03290 } 03291 } 03292 } 03293 } 03294 03295 //----------------------------------------------------------------------------- 03296 /// ArgNumberExpr code: 03297 /// 03298 03299 ArgNumberExpr::~ArgNumberExpr() 03300 { 03301 /// ... nothing to do 03302 } 03303 03304 ArgNumberExpr & 03305 ArgNumberExpr::operator = (const ArgNumberExpr & e) 03306 { 03307 if (this != &e) 03308 _value = e.value(); 03309 03310 return *this; 03311 } 03312 03313 Expression * 03314 ArgNumberExpr::clone() const 03315 { 03316 return new ArgNumberExpr(*this); 03317 } 03318 03319 int 03320 ArgNumberExpr::structures_OK() const 03321 { 03322 cerr << "ArgNumber::structures_OK() not implemented"; 03323 return True; 03324 } 03325 03326 int 03327 ArgNumberExpr::exchange_expr( VDL & vdl ) 03328 { 03329 int index = vdl.look_up_expr( *this ); 03330 03331 if (index >= 0) 03332 return index; 03333 03334 index = Expression::exchange_expr( vdl ); 03335 03336 BinRep *b = CASTAWAY(BinRep *) vdl.data_ref(); 03337 03338 Set<BinRep> & S = b->find_ref( "expression" )->to_tuple()[index-1].to_set(); 03339 03340 BinRep *br = new BinRep( new List<BinRep> ); 03341 br->to_tuple().ins_last(new BinRep( "op" )); 03342 br->to_tuple().ins_last(new BinRep( "ARG#" )); 03343 S.ins( br ); 03344 03345 br = new BinRep( new List<BinRep> ); 03346 br->to_tuple().ins_last(new BinRep( "data" )); 03347 br->to_tuple().ins_last(new BinRep( this->value() )); 03348 03349 return index; 03350 } 03351 03352 void 03353 ArgNumberExpr::convert(BinRep & exprSet, Symtab & NOTUSED(symtab)) 03354 { 03355 String s; 03356 BinRep second; /// ... The second argument of tuple pairs 03357 03358 empty_overflow(); 03359 03360 for (Iterator<BinRep> expr_iter = exprSet.to_set(); 03361 expr_iter.valid(); ++expr_iter) { 03362 String field; 03363 03364 expr_iter.current()[0].to_string(field); 03365 second = expr_iter.current()[1]; 03366 03367 if (field == "type") 03368 get_type(second, "ArgNumber"); 03369 else if (field == "data") { 03370 p_assert( second.is_integer(), "ArgNumber::convert: " 03371 "'data' field does not contain an int." ); 03372 _value = second.to_integer(); 03373 } 03374 else if (field != "op" && field != "size") 03375 make_overflow(expr_iter, "ArgNumber"); 03376 } 03377 } 03378 03379 void 03380 ArgNumberExpr::print_debug(ostream & o, Boolean NOTUSED(debug)) const 03381 { 03382 o << "#" << _value; 03383 } 03384 03385 //----------------------------------------------------------------------------- 03386 /// ArrayRefExpr code: 03387 /// 03388 03389 /// Note: The following data fields are aliased: 03390 /// array = left 03391 /// subscript = right 03392 03393 ArrayRefExpr::~ArrayRefExpr() 03394 { 03395 if (_arcs) 03396 delete _arcs; 03397 } 03398 03399 Expression * 03400 ArrayRefExpr::clone() const 03401 { 03402 return new ArrayRefExpr(*this); 03403 } 03404 03405 ArrayRefExpr & 03406 ArrayRefExpr::operator = (const ArrayRefExpr & e) 03407 { 03408 if (this != &e) { 03409 BinaryExpr::operator = (e); 03410 _arcs = 0; 03411 } 03412 03413 return *this; 03414 } 03415 03416 void 03417 ArrayRefExpr::array(Expression * e) 03418 { 03419 p_assert(e->op() == ID_OP, 03420 "ArrayRefExpr::array( ) expression not an IDExpr"); 03421 _left(e); 03422 } 03423 03424 void 03425 ArrayRefExpr::subscript(Expression * e) 03426 { 03427 p_assert(e->op() == COMMA_OP, 03428 "ArrayRefExpr::subscript( ) expression not an CommaExpr"); 03429 _right(e); 03430 } 03431 03432 int 03433 ArrayRefExpr::structures_OK() const 03434 { 03435 cerr << "ArrayRefExpr::structures_OK() not implemented"; 03436 return True; 03437 } 03438 03439 int 03440 ArrayRefExpr::exchange_expr( VDL & vdl ) 03441 { 03442 int index = vdl.look_up_expr( *this ); 03443 03444 if (index >= 0) 03445 return index; 03446 03447 index = Expression::exchange_expr( vdl ); 03448 03449 BinRep *b = CASTAWAY(BinRep *) vdl.data_ref(); 03450 03451 Set<BinRep> & S = b->find_ref( "expression" )->to_tuple()[index-1].to_set(); 03452 03453 BinRep *br = new BinRep( new List<BinRep> ); 03454 br->to_tuple().ins_last(new BinRep( "op" )); 03455 br->to_tuple().ins_last(new BinRep( "ARRAY_REF" )); 03456 S.ins( br ); 03457 03458 br = new BinRep( new List<BinRep> ); 03459 br->to_tuple().ins_last(new BinRep( "args" )); 03460 BinRep *bt = new BinRep(new List<BinRep>); 03461 br->to_tuple().ins_last( bt ); 03462 S.ins( br ); 03463 03464 03465 bt->to_tuple().ins_last( 03466 new BinRep( this->array().exchange_expr(vdl))); 03467 bt->to_tuple().ins_last( 03468 new BinRep( this->subscript().exchange_expr(vdl))); 03469 03470 return index; 03471 } 03472 03473 void 03474 ArrayRefExpr::convert(BinRep & exprSet, Symtab & NOTUSED(symtab)) 03475 { 03476 String s; 03477 BinRep second; /// ... The second argument of tuple pairs 03478 03479 empty_overflow(); 03480 03481 for (Iterator<BinRep> expr_iter = exprSet.to_set(); 03482 expr_iter.valid(); ++expr_iter) { 03483 String field; 03484 03485 expr_iter.current()[0].to_string(field); 03486 second = expr_iter.current()[1]; 03487 03488 if (field == "type") 03489 get_type(second, "ArrayRef"); 03490 else if (field == "size") { 03491 p_assert( second.is_integer(), "ArrayRefExpr::convert: " 03492 "'size' field contains non-int." ); 03493 _type.set(second.to_integer()); 03494 } 03495 else if (field == "args") { 03496 Iterator<BinRep> iter = second.to_tuple(); 03497 BinRep theArg = iter.current(); 03498 03499 /// ... first element of args tuple 03500 03501 Expression *e1; 03502 03503 p_assert( theArg.is_integer(), 03504 "ArrayRefExpr::convert: arg field contains non-int." ); 03505 03506 e1 = tableEntry(theArg.to_integer()); 03507 03508 ++iter; 03509 03510 theArg = iter.current(); /// ... Second element of args tuple 03511 03512 p_assert( theArg.is_integer(), 03513 "ArrayRefExpr::convert: arg field contains non-int." ); 03514 03515 Expression *e2 = tableEntry(theArg.to_integer()); 03516 03517 _left(e1); 03518 _right(e2); 03519 } 03520 else if (field != "op" && field != "size") 03521 make_overflow(expr_iter, "ArrayRefExpr"); 03522 } 03523 } 03524 03525 void 03526 ArrayRefExpr::print_debug(ostream & o, Boolean NOTUSED(debug)) const 03527 { 03528 print_prec(op(), (_left_valid() ? &_left_guarded() : 0), o); 03529 o << "("; 03530 print_prec(op(), (_right_valid() ? &_right_guarded() : 0), o); 03531 o << ")"; 03532 } 03533 03534 //----------------------------------------------------------------------------- 03535 /// BinaryExpr code: 03536 /// 03537 03538 BinaryExpr::~BinaryExpr() 03539 { 03540 /// ... nothing to do 03541 } 03542 03543 Expression * 03544 BinaryExpr::clone() const 03545 { 03546 return new BinaryExpr(*this); 03547 } 03548 03549 BinaryExpr & 03550 BinaryExpr::operator = (const BinaryExpr & e) 03551 { 03552 if (this != &e) { 03553 if (e._left_valid()) 03554 _left(e._left_guarded().clone()); 03555 else 03556 _left(0); 03557 03558 if (e._right_valid()) 03559 _right(e._right_guarded().clone()); 03560 else 03561 _right(0); 03562 } 03563 03564 return *this; 03565 } 03566 03567 const RefList<Expression>* 03568 BinaryExpr::arg_refs() const 03569 { 03570 RefList<Expression>*args = new RefList<Expression>; 03571 03572 if (_left_valid()) 03573 args->ins_last(CASTAWAY(Expression &) _left_guarded()); 03574 03575 if (_right_valid()) 03576 args->ins_last(CASTAWAY(Expression &) _right_guarded()); 03577 03578 return (const RefList<Expression> *) args; 03579 } 03580 03581 void 03582 BinaryExpr::left(Expression * e) 03583 { 03584 _left(e); 03585 } 03586 03587 const Expression & 03588 BinaryExpr::left_guarded() const 03589 { 03590 return _left_guarded(); 03591 } 03592 03593 Expression & 03594 BinaryExpr::left_guarded() 03595 { 03596 return _left_guarded(); 03597 } 03598 03599 Boolean 03600 BinaryExpr::left_valid() const 03601 { 03602 return _left_valid(); 03603 } 03604 03605 Expression * 03606 BinaryExpr::grab_left() 03607 { 03608 return _grab_left(); 03609 } 03610 03611 void 03612 BinaryExpr::right(Expression * e) 03613 { 03614 _right(e); 03615 } 03616 03617 const Expression & 03618 BinaryExpr::right_guarded() const 03619 { 03620 return _right_guarded(); 03621 } 03622 03623 Expression & 03624 BinaryExpr::right_guarded() 03625 { 03626 return _right_guarded(); 03627 } 03628 03629 Boolean 03630 BinaryExpr::right_valid() const 03631 { 03632 return _right_valid(); 03633 } 03634 03635 Expression * 03636 BinaryExpr::grab_right() 03637 { 03638 return _grab_right(); 03639 } 03640 03641 Boolean 03642 BinaryExpr::args_are_non_null() const 03643 { 03644 return _left_valid() && _right_valid(); 03645 } 03646 03647 const List<Expression> & 03648 BinaryExpr::arg_list() const 03649 { 03650 return _arg_list; 03651 } 03652 03653 List<Expression> & 03654 BinaryExpr::arg_list() 03655 { 03656 return _arg_list; 03657 } 03658 03659 int 03660 BinaryExpr::structures_OK() const 03661 { 03662 cerr << "BinaryExpr::structures_OK() not implemented"; 03663 return True; 03664 } 03665 03666 int 03667 BinaryExpr::exchange_expr( VDL & vdl ) 03668 { 03669 int index = vdl.look_up_expr( *this ); 03670 03671 if (index >= 0) 03672 return index; 03673 03674 index = Expression::exchange_expr( vdl ); 03675 03676 BinRep *b = CASTAWAY(BinRep *) vdl.data_ref(); 03677 03678 Set<BinRep> & S = b->find_ref( "expression" )->to_tuple()[index-1].to_set(); 03679 03680 String opcode; 03681 03682 switch (op()) { 03683 case EQ_OP: opcode = ".EQ."; break; 03684 case NE_OP: opcode = ".NE."; break; 03685 case LT_OP: opcode = ".LT."; break; 03686 case LE_OP: opcode = ".LE."; break; 03687 case GT_OP: opcode = ".GT."; break; 03688 case GE_OP: opcode = ".GE."; break; 03689 case SUB_OP: opcode = "-"; break; 03690 case DIV_OP: opcode = "/"; break; 03691 case INTDIV_OP: opcode = "/#"; break; 03692 case RATDIV_OP: opcode = "/%"; break; 03693 case EXP_OP: opcode = "**"; break; 03694 case CONCAT_OP: opcode = "/// ... "; break; 03695 case REPSTAR_OP: opcode = "REP*"; break; 03696 case KEYPAIR_OP: opcode = "KEYPAIR"; break; 03697 default: break; 03698 } 03699 03700 BinRep *br = new BinRep( new List<BinRep> ); 03701 br->to_tuple().ins_last(new BinRep( "op" )); 03702 br->to_tuple().ins_last(new BinRep( opcode )); 03703 S.ins( br ); 03704 03705 br = new BinRep( new List<BinRep> ); 03706 br->to_tuple().ins_last(new BinRep( "args" )); 03707 BinRep *bt = new BinRep(new List<BinRep>); 03708 br->to_tuple().ins_last( bt ); 03709 S.ins( br ); 03710 03711 bt->to_tuple().ins_last( 03712 new BinRep( this->left_guarded().exchange_expr(vdl))); 03713 bt->to_tuple().ins_last( 03714 new BinRep( this->right_guarded().exchange_expr(vdl))); 03715 03716 return index; 03717 } 03718 03719 03720 void 03721 BinaryExpr::convert(BinRep & exprSet, Symtab & NOTUSED(symtab)) 03722 { 03723 String s; 03724 BinRep second; /// ... The second argument of tuple pairs 03725 03726 empty_overflow(); 03727 03728 for (Iterator<BinRep> expr_iter = exprSet.to_set(); 03729 expr_iter.valid(); ++expr_iter) { 03730 String field; 03731 03732 expr_iter.current()[0].to_string(field); 03733 second = expr_iter.current()[1]; 03734 03735 if (field == "type") 03736 get_type(second, "Binary"); 03737 else if (field == "args") { 03738 Iterator<BinRep> iter = second.to_tuple(); 03739 BinRep theArg = iter.current(); 03740 03741 /// ... first element of args tuple 03742 03743 Expression *e1 = NULL; 03744 03745 if (theArg.is_integer()) 03746 e1 = tableEntry(theArg.to_integer()); 03747 else if (theArg.is_omega()) 03748 e1 = new OmegaExpr; 03749 else { 03750 p_abort( "BinaryExpr::convert: arg field contains non-int"); 03751 } 03752 03753 ++iter; 03754 03755 theArg = iter.current(); /// ... Second element of args tuple 03756 03757 p_assert( theArg.is_integer(), 03758 "BinaryExpr::convert: arg field contains non-int." ); 03759 03760 Expression *e2 = tableEntry(theArg.to_integer()); 03761 03762 _left(e1); 03763 _right(e2); 03764 } 03765 else if (field == "size") { 03766 p_assert( second.is_integer(), 03767 "BinaryExpr::convert: 'size' field contains non-int."); 03768 _type.set(second.to_integer()); 03769 } 03770 else if (field != "op") 03771 make_overflow(expr_iter, "BinaryExpr"); 03772 } 03773 } 03774 03775 void 03776 BinaryExpr::print_debug(ostream & o, Boolean NOTUSED(debug)) const 03777 { 03778 print_prec(op(), (_left_valid() ? &_left_guarded() : 0), o); 03779 03780 switch (op()) { 03781 case EQ_OP: 03782 o << ".EQ."; 03783 break; 03784 case NE_OP: 03785 o << ".NE."; 03786 break; 03787 case LT_OP: 03788 o << ".LT."; 03789 break; 03790 case LE_OP: 03791 o << ".LE."; 03792 break; 03793 case GT_OP: 03794 o << ".GT."; 03795 break; 03796 case GE_OP: 03797 o << ".GE."; 03798 break; 03799 case SUB_OP: 03800 o << "-"; 03801 break; 03802 case DIV_OP: 03803 o << "/"; 03804 break; 03805 case INTDIV_OP: 03806 o << "/#"; 03807 break; 03808 case RATDIV_OP: 03809 o << "/%"; 03810 break; 03811 case EXP_OP: 03812 o << "**"; 03813 break; /// ... precedence different 03814 03815 case REPSTAR_OP: 03816 o << " * "; 03817 break; 03818 03819 case KEYPAIR_OP: 03820 o << "="; 03821 break; 03822 default: 03823 break; 03824 } 03825 03826 if (_right_valid() 03827 && (op() == SUB_OP 03828 || op() == DIV_OP 03829 || op() == INTDIV_OP 03830 || op() == RATDIV_OP) 03831 && (operator_precedence(op()) == operator_precedence(_right_guarded().op()))) 03832 o << "(" << _right_guarded() << ")"; 03833 else 03834 print_prec(op(), (_right_valid() ? &_right_guarded() : 0), o); 03835 } 03836 03837 void 03838 BinaryExpr::relink_eptrs(ProgramUnit & p) 03839 { 03840 if (_left_valid()) 03841 _left_guarded().relink_eptrs(p); 03842 03843 if (_right_valid()) 03844 _right_guarded().relink_eptrs(p); 03845 } 03846 03847 //----------------------------------------------------------------------------- 03848 /// CommaExpr code: 03849 /// 03850 03851 CommaExpr::~CommaExpr() 03852 { 03853 /// ... nothing to do 03854 } 03855 03856 Expression * 03857 CommaExpr::clone() const 03858 { 03859 return new CommaExpr(*this); 03860 } 03861 03862 CommaExpr & 03863 CommaExpr::operator = (const CommaExpr & e) 03864 { 03865 NonBinaryExpr::operator = (e); 03866 03867 return *this; 03868 } 03869 03870 int 03871 CommaExpr::structures_OK() const 03872 { 03873 cerr << "CommaExpr::structures_OK() not implemented"; 03874 return True; 03875 } 03876 03877 int 03878 CommaExpr::exchange_expr( VDL & vdl ) 03879 { 03880 int index = vdl.look_up_expr( *this ); 03881 03882 if (index >= 0) 03883 return index; 03884 03885 index = Expression::exchange_expr( vdl ); 03886 03887 BinRep *b = CASTAWAY(BinRep *) vdl.data_ref(); 03888 03889 Set<BinRep> & S = b->find_ref( "expression" )->to_tuple()[index-1].to_set(); 03890 03891 BinRep *br = new BinRep( new List<BinRep> ); 03892 br->to_tuple().ins_last(new BinRep( "op" )); 03893 br->to_tuple().ins_last(new BinRep( "," )); 03894 S.ins( br ); 03895 03896 br = new BinRep( new List<BinRep> ); 03897 br->to_tuple().ins_last(new BinRep( "args" )); 03898 BinRep *bt = new BinRep(new List<BinRep>); 03899 br->to_tuple().ins_last( bt ); 03900 S.ins( br ); 03901 03902 for (Iterator<Expression> iter = _arg_list; iter.valid(); ++iter) { 03903 bt->to_tuple().ins_last( 03904 new BinRep( iter.current().exchange_expr(vdl))); 03905 } 03906 03907 return index; 03908 } 03909 03910 03911 void 03912 CommaExpr::convert(BinRep & exprSet, Symtab & NOTUSED(symtab)) 03913 { 03914 String s; 03915 BinRep second; /// ... The second argument of tuple pairs 03916 03917 empty_overflow(); 03918 03919 for (Iterator<BinRep> expr_iter = exprSet.to_set(); 03920 expr_iter.valid(); ++expr_iter) { 03921 String field; 03922 03923 expr_iter.current()[0].to_string(field); 03924 second = expr_iter.current()[1]; 03925 03926 if (field == "type") 03927 get_type(second, "Comma"); 03928 else if (field == "args") { 03929 Iterator<BinRep> iter = second.to_tuple(); 03930 03931 for (BinRep args; iter.valid(); ++iter) { 03932 args = iter.current(); 03933 03934 p_assert( args.is_integer(), "CommaExpr::convert: " 03935 "Non-Binary Op's arg field contains non-int" ); 03936 03937 Expression *thug = tableEntry(args.to_integer()); 03938 _arg_list.ins_last(thug); 03939 } 03940 } 03941 else if (field != "op" && field != "size") 03942 make_overflow(expr_iter, "CommaExpr"); 03943 } 03944 } 03945 03946 void 03947 CommaExpr::print_debug(ostream & o, Boolean NOTUSED(debug)) const 03948 { 03949 print_prec_list(o, op(), _arg_list, ", "); 03950 } 03951 03952 //----------------------------------------------------------------------------- 03953 /// ComplexExpr code: 03954 /// 03955 03956 /// Note: The following data fields are aliased: 03957 /// real_part = left 03958 /// imaginary_part = right 03959 03960 ComplexExpr::~ComplexExpr() 03961 { 03962 /// ... nothing to do 03963 } 03964 03965 Expression * 03966 ComplexExpr::clone() const 03967 { 03968 return new ComplexExpr(*this); 03969 } 03970 03971 ComplexExpr & 03972 ComplexExpr::operator = (const ComplexExpr & e) 03973 { 03974 BinaryExpr::operator = (e); 03975 03976 return *this; 03977 } 03978 03979 int 03980 ComplexExpr::structures_OK() const 03981 { 03982 cerr << "ComplexExpr::structures_OK() not implemented"; 03983 return True; 03984 } 03985 03986 int 03987 ComplexExpr::exchange_expr( VDL & vdl ) 03988 { 03989 int index = vdl.look_up_expr( *this ); 03990 03991 if (index >= 0) 03992 return index; 03993 03994 index = Expression::exchange_expr( vdl ); 03995 03996 BinRep *b = CASTAWAY(BinRep *) vdl.data_ref(); 03997 03998 Set<BinRep> & S = b->find_ref( "expression" )->to_tuple()[index-1].to_set(); 03999 04000 BinRep *br = new BinRep( new List<BinRep> ); 04001 br->to_tuple().ins_last(new BinRep( "op" )); 04002 br->to_tuple().ins_last(new BinRep( "COMPLEX" )); 04003 S.ins( br ); 04004 04005 br = new BinRep( new List<BinRep> ); 04006 br->to_tuple().ins_last(new BinRep( "args" )); 04007 BinRep *bt = new BinRep(new List<BinRep>); 04008 br->to_tuple().ins_last( bt ); 04009 S.ins( br ); 04010 04011 bt->to_tuple().ins_last( 04012 new BinRep( this->left_guarded().exchange_expr(vdl))); 04013 bt->to_tuple().ins_last( 04014 new BinRep( this->right_guarded().exchange_expr(vdl))); 04015 04016 return index; 04017 } 04018 04019 void 04020 ComplexExpr::convert(BinRep & exprSet, Symtab & NOTUSED(symtab)) 04021 { 04022 String s; 04023 BinRep second; /// ... The second argument of tuple pairs 04024 04025 empty_overflow(); 04026 04027 for (Iterator<BinRep> expr_iter = exprSet.to_set(); 04028 expr_iter.valid(); ++expr_iter) { 04029 String field; 04030 04031 expr_iter.current()[0].to_string(field); 04032 second = expr_iter.current()[1]; 04033 04034 if (field == "type") { 04035 second.to_string(s); 04036 04037 p_assert( s == "COMPLEX", 04038 "ComplexExpr::convert: type field not COMPLEX." ); 04039 _type = COMPLEX_TYPE; 04040 } 04041 else if (field == "args") { 04042 Iterator<BinRep> iter = second.to_tuple(); 04043 BinRep theArg = iter.current(); 04044 04045 /// ... first element of args tuple 04046 04047 Expression *e1; 04048 04049 p_assert( theArg.is_integer(), 04050 "ComplexExpr::convert: arg field contains non-int." ); 04051 04052 e1 = tableEntry(theArg.to_integer()); 04053 04054 ++iter; 04055 04056 theArg = iter.current(); /// ... Second element of args tuple 04057 04058 p_assert( theArg.is_integer(), 04059 "ComplexExpr::convert: arg field contains non-int." ); 04060 04061 Expression *e2 = tableEntry(theArg.to_integer()); 04062 04063 _left(e1); 04064 _right(e2); 04065 } 04066 else if (field != "op" && field != "size") 04067 make_overflow(expr_iter, "ComplexExpr"); 04068 } 04069 } 04070 04071 void 04072 ComplexExpr::print_debug(ostream & o, Boolean NOTUSED(debug)) const 04073 { o << "("; 04074 04075 if (_left_valid()) 04076 o << _left_guarded(); 04077 else 04078 o << "<UNDEFINED>"; 04079 04080 o << ", "; 04081 04082 if (_right_valid()) 04083 o << _right_guarded(); 04084 else 04085 o << "<UNDEFINED>"; 04086 04087 o << ")"; 04088 } 04089 04090 //----------------------------------------------------------------------------- 04091 /// DoExpr code: 04092 /// 04093 04094 /// Note: The following data fields are aliased: 04095 /// iolist = left 04096 /// iterator = right 04097 04098 DoExpr::~DoExpr() 04099 { 04100 /// ... nothing to do 04101 } 04102 04103 DoExpr & 04104 DoExpr::operator = (const DoExpr & e) 04105 { 04106 BinaryExpr::operator = (e); 04107 04108 return *this; 04109 } 04110 04111 Expression * 04112 DoExpr::clone() const 04113 { 04114 return new DoExpr(*this); 04115 } 04116 04117 void 04118 DoExpr::iolist(Expression * e) 04119 { 04120 p_assert(e->op() == COMMA_OP, 04121 "DoExpr:: iolist( ) not a CommaExpr"); 04122 _left(e); 04123 } 04124 04125 const Expression & 04126 DoExpr::iolist() const 04127 { 04128 return _left_guarded(); 04129 } 04130 04131 Expression & 04132 DoExpr::iolist() 04133 { 04134 return _left_guarded(); 04135 } 04136 04137 void 04138 DoExpr::iterator(Expression * e) 04139 { 04140 p_assert(e->op() == EQUAL_OP, 04141 "DoExpr:: iterator( ) not a EqualExpr"); 04142 _right(e); 04143 } 04144 04145 const Expression & 04146 DoExpr::iterator() const 04147 { 04148 return _right_guarded(); 04149 } 04150 04151 Expression & 04152 DoExpr::iterator() 04153 { 04154 return _right_guarded(); 04155 } 04156 04157 int 04158 DoExpr::structures_OK() const 04159 { 04160 cerr << "DoExpr::structures_OK() not implemented"; 04161 return True; 04162 } 04163 04164 int 04165 DoExpr::exchange_expr( VDL & vdl ) 04166 { 04167 int index = vdl.look_up_expr( *this ); 04168 04169 if (index >= 0) 04170 return index; 04171 04172 index = Expression::exchange_expr( vdl ); 04173 04174 BinRep *b = CASTAWAY(BinRep *) vdl.data_ref(); 04175 04176 Set<BinRep> & S = b->find_ref( "expression" )->to_tuple()[index-1].to_set(); 04177 04178 BinRep *br = new BinRep( new List<BinRep> ); 04179 br->to_tuple().ins_last(new BinRep( "op" )); 04180 br->to_tuple().ins_last(new BinRep( "DO" )); 04181 S.ins( br ); 04182 04183 br = new BinRep( new List<BinRep> ); 04184 br->to_tuple().ins_last(new BinRep( "args" )); 04185 BinRep *bt = new BinRep(new List<BinRep>); 04186 br->to_tuple().ins_last( bt ); 04187 S.ins( br ); 04188 04189 bt->to_tuple().ins_last( 04190 new BinRep( this->iolist().exchange_expr(vdl))); 04191 bt->to_tuple().ins_last( 04192 new BinRep( this->iterator().exchange_expr(vdl))); 04193 04194 return index; 04195 } 04196 04197 04198 void 04199 DoExpr::convert(BinRep & exprSet, Symtab & NOTUSED(symtab)) 04200 { 04201 String s; 04202 BinRep second; /// ... The second argument of tuple pairs 04203 04204 empty_overflow(); 04205 04206 for (Iterator<BinRep> expr_iter = exprSet.to_set(); 04207 expr_iter.valid(); ++expr_iter) { 04208 String field; 04209 04210 expr_iter.current()[0].to_string(field); 04211 second = expr_iter.current()[1]; 04212 04213 if (field == "type") 04214 get_type(second, "Do"); 04215 else if (field == "args") { 04216 Iterator<BinRep> iter = second.to_tuple(); 04217 BinRep theArg = iter.current(); 04218 04219 /// ... first element of args tuple 04220 04221 Expression *e1; 04222 04223 p_assert( theArg.is_integer(), 04224 "DoExpr::convert: arg field contains non-int." ); 04225 04226 e1 = tableEntry(theArg.to_integer()); 04227 04228 ++iter; 04229 04230 theArg = iter.current(); /// ... Second element of args tuple 04231 04232 p_assert( theArg.is_integer(), 04233 "DoExpr::convert: arg field contains non-int." ); 04234 04235 Expression *e2 = tableEntry(theArg.to_integer()); 04236 04237 _left(e1); 04238 _right(e2); 04239 } 04240 else if (field != "op" && field != "size") 04241 make_overflow(expr_iter, "DoExpr"); 04242 } 04243 } 04244 04245 void 04246 DoExpr::print_debug(ostream & o, Boolean NOTUSED(debug)) const 04247 { 04248 o << "("; 04249 print_prec(op(), (_left_valid() ? &_left_guarded() : 0), o); 04250 o << ", "; 04251 print_prec(op(), (_right_valid() ? &_right_guarded() : 0), o); 04252 o << ")"; 04253 } 04254 04255 //----------------------------------------------------------------------------- 04256 /// EqualExpr code: 04257 /// 04258 04259 /// Note: The following data fields are aliased: 04260 /// index_id = left 04261 /// iteration_space = right 04262 04263 EqualExpr::~EqualExpr() 04264 { 04265 /// ... nothing to do 04266 } 04267 04268 Expression * 04269 EqualExpr::clone() const 04270 { 04271 return new EqualExpr(*this); 04272 } 04273 04274 EqualExpr & 04275 EqualExpr::operator = (const EqualExpr & e) 04276 { 04277 BinaryExpr::operator = (e); 04278 04279 return *this; 04280 } 04281 04282 void 04283 EqualExpr::index_id(Expression * e) 04284 { 04285 p_assert(e->op() == ID_OP, 04286 "EqualExpr::index_id( ) not an IDExpr"); 04287 _left(e); 04288 } 04289 04290 const Expression & 04291 EqualExpr::index_id() const 04292 { 04293 return _left_guarded(); 04294 } 04295 04296 Expression & 04297 EqualExpr::index_id() 04298 { 04299 return _left_guarded(); 04300 } 04301 04302 void 04303 EqualExpr::iteration_space(Expression * e) 04304 { 04305 p_assert(e->op() == COMMA_OP, 04306 "EqualExpr::iteration_space( ) not an CommaExpr"); 04307 _right(e); 04308 } 04309 04310 const Expression & 04311 EqualExpr::iteration_space() const 04312 { 04313 return _right_guarded(); 04314 } 04315 04316 Expression & 04317 EqualExpr::iteration_space() 04318 { 04319 return _right_guarded(); 04320 } 04321 04322 int 04323 EqualExpr::structures_OK() const 04324 { 04325 cerr << "EqualExpr::structures_OK() not implemented"; 04326 return True; 04327 } 04328 04329 int 04330 EqualExpr::exchange_expr( VDL & vdl ) 04331 { 04332 int index = vdl.look_up_expr( *this ); 04333 04334 if (index >= 0) 04335 return index; 04336 04337 index = Expression::exchange_expr( vdl ); 04338 04339 BinRep *b = CASTAWAY(BinRep *) vdl.data_ref(); 04340 04341 Set<BinRep> & S = b->find_ref( "expression" )->to_tuple()[index-1].to_set(); 04342 04343 BinRep *br = new BinRep( new List<BinRep> ); 04344 br->to_tuple().ins_last(new BinRep( "op" )); 04345 br->to_tuple().ins_last(new BinRep( "=" )); 04346 S.ins( br ); 04347 04348 br = new BinRep( new List<BinRep> ); 04349 br->to_tuple().ins_last(new BinRep( "args" )); 04350 BinRep *bt = new BinRep(new List<BinRep>); 04351 br->to_tuple().ins_last( bt ); 04352 S.ins( br ); 04353 04354 bt->to_tuple().ins_last( 04355 new BinRep( this->index_id().exchange_expr(vdl))); 04356 bt->to_tuple().ins_last( 04357 new BinRep( this->iteration_space().exchange_expr(vdl))); 04358 04359 return index; 04360 } 04361 04362 04363 void 04364 EqualExpr::convert(BinRep & exprSet, Symtab & NOTUSED(symtab)) 04365 { 04366 String s; 04367 BinRep second; /// ... The second argument of tuple pairs 04368 04369 empty_overflow(); 04370 04371 for (Iterator<BinRep> expr_iter = exprSet.to_set(); 04372 expr_iter.valid(); ++expr_iter) { 04373 String field; 04374 04375 expr_iter.current()[0].to_string(field); 04376 second = expr_iter.current()[1]; 04377 04378 if (field == "type") 04379 get_type(second, "Equal"); 04380 else if (field == "args") { 04381 Iterator<BinRep> iter = second.to_tuple(); 04382 BinRep theArg = iter.current(); 04383 04384 /// ... first element of args tuple 04385 04386 p_assert( theArg.is_integer(), 04387 "EqualExpr::convert: arg field contains non-int." ); 04388 04389 Expression *e1 = tableEntry(theArg.to_integer()); 04390 04391 ++iter; 04392 04393 theArg = iter.current(); /// ... Second element of args tuple 04394 04395 p_assert( theArg.is_integer(), 04396 "EqualExpr::convert: arg field contains non-int." ); 04397 04398 Expression *e2 = tableEntry(theArg.to_integer()); 04399 04400 _left(e1); 04401 _right(e2); 04402 } 04403 else if (field != "op" && field != "size") 04404 make_overflow(expr_iter, "EqualExpr"); 04405 } 04406 } 04407 04408 void 04409 EqualExpr::print_debug(ostream & o, Boolean NOTUSED(debug)) const 04410 { 04411 print_prec(op(), (_left_valid() ? &_left_guarded() : 0), o); 04412 o << "="; 04413 print_prec(op(), (_right_valid() ? &_right_guarded() : 0), o); 04414 } 04415 04416 //----------------------------------------------------------------------------- 04417 /// FormatExpr code: 04418 /// 04419 04420 /// Note: The following data fields are aliased: 04421 /// format = data 04422 04423 FormatExpr::~FormatExpr() 04424 { 04425 /// ... nothing to do 04426 } 04427 04428 Expression * 04429 FormatExpr::clone() const 04430 { 04431 return new FormatExpr(*this); 04432 } 04433 04434 const Format & 04435 FormatExpr::format() const 04436 { 04437 return *_format_ptr; 04438 } 04439 04440 Format & 04441 FormatExpr::format() 04442 { 04443 return *_format_ptr; 04444 } 04445 04446 void 04447 FormatExpr::format(Format & format) 04448 { 04449 _format_ptr = &format; 04450 } 04451 04452 int 04453 FormatExpr::structures_OK() const 04454 { 04455 cerr << "FormatExpr::structures_OK() not implemented"; 04456 return True; 04457 } 04458 04459 int 04460 FormatExpr::exchange_expr( VDL & vdl ) 04461 { 04462 int index = vdl.look_up_expr( *this ); 04463 04464 if (index >= 0) 04465 return index; 04466 04467 index = Expression::exchange_expr( vdl ); 04468 04469 BinRep *b = CASTAWAY(BinRep *) vdl.data_ref(); 04470 04471 Set<BinRep> & S = b->find_ref( "expression" )->to_tuple()[index-1].to_set(); 04472 04473 BinRep *br = new BinRep( new List<BinRep> ); 04474 br->to_tuple().ins_last(new BinRep( "op" )); 04475 br->to_tuple().ins_last(new BinRep( "FORMAT" )); 04476 S.ins( br ); 04477 04478 return index; 04479 } 04480 04481 04482 void 04483 FormatExpr::convert(BinRep & NOTUSED(exprSet), Symtab & NOTUSED(symtab)) 04484 { 04485 /// ... Currently, doesn't exist on setl side -- no need for conversion 04486 } 04487 04488 void 04489 FormatExpr::print_debug(ostream & o, Boolean NOTUSED(debug)) const 04490 { 04491 o << _format_ptr->value(); 04492 } 04493 04494 void 04495 FormatExpr::relink_eptrs(ProgramUnit & p) 04496 { 04497 p_assert(_format_ptr, "FormatExpr has NULL pointer"); 04498 int label = _format_ptr->value(); 04499 _format_ptr = p.formats().find_ref(label); 04500 p_assert(_format_ptr, "FormatExpr has NULL pointer"); 04501 } 04502 04503 //----------------------------------------------------------------------------- 04504 /// FunctionCallExpr code: 04505 /// 04506 04507 /// Note: The following data fields are aliased: 04508 /// function = left 04509 /// parameters = right 04510 04511 FunctionCallExpr::~FunctionCallExpr() 04512 { 04513 /// ... nothing to do 04514 } 04515 04516 Expression * 04517 FunctionCallExpr::clone() const 04518 { 04519 return new FunctionCallExpr(*this); 04520 } 04521 04522 FunctionCallExpr & 04523 FunctionCallExpr::operator = (const FunctionCallExpr & e) 04524 { 04525 BinaryExpr::operator = (e); 04526 04527 return *this; 04528 } 04529 04530 void 04531 FunctionCallExpr::function(Expression * e) 04532 { 04533 p_assert(e->op() == ID_OP, 04534 "FunctionCallExpr:: function( ) not an IDExpr"); 04535 _left(e); 04536 } 04537 04538 const Expression & 04539 FunctionCallExpr::function() const 04540 { 04541 return _left_guarded(); 04542 } 04543 04544 Expression & 04545 FunctionCallExpr::function() 04546 { 04547 return _left_guarded(); 04548 } 04549 04550 void 04551 FunctionCallExpr::parameters(Expression * e) 04552 { 04553 p_assert(e->op() == COMMA_OP || e->op() == OMEGA_OP, 04554 "FunctionCallExpr:: parameters( ) not an CommaExpr or OmegaExpr"); 04555 _right(e); 04556 } 04557 04558 const Expression & 04559 FunctionCallExpr::parameters_guarded() const 04560 { 04561 return _right_guarded(); 04562 } 04563 04564 Expression & 04565 FunctionCallExpr::parameters_guarded() 04566 { 04567 return _right_guarded(); 04568 } 04569 04570 Boolean 04571 FunctionCallExpr::parameters_valid() const 04572 { 04573 return _right_valid(); 04574 } 04575 04576 int 04577 FunctionCallExpr::structures_OK() const 04578 { 04579 cerr << "FunctionCallExpr::structures_OK() not implemented"; 04580 return True; 04581 } 04582 04583 int 04584 FunctionCallExpr::exchange_expr( VDL & vdl ) 04585 { 04586 int index = vdl.look_up_expr( *this ); 04587 04588 if (index >= 0) 04589 return index; 04590 04591 index = Expression::exchange_expr( vdl ); 04592 04593 BinRep *b = CASTAWAY(BinRep *) vdl.data_ref(); 04594 04595 Set<BinRep> & S = b->find_ref( "expression" )->to_tuple()[index-1].to_set(); 04596 04597 BinRep *br = new BinRep( new List<BinRep> ); 04598 br->to_tuple().ins_last(new BinRep( "op" )); 04599 br->to_tuple().ins_last(new BinRep( "FUNCTION_CALL" )); 04600 S.ins( br ); 04601 04602 br = new BinRep( new List<BinRep> ); 04603 br->to_tuple().ins_last(new BinRep( "args" )); 04604 BinRep *bt = new BinRep(new List<BinRep>); 04605 br->to_tuple().ins_last( bt ); 04606 S.ins( br ); 04607 04608 bt->to_tuple().ins_last( 04609 new BinRep( this->function().exchange_expr(vdl))); 04610 bt->to_tuple().ins_last( 04611 new BinRep( this->parameters_guarded().exchange_expr(vdl))); 04612 04613 return index; 04614 } 04615 04616 04617 void 04618 FunctionCallExpr::convert(BinRep & exprSet, Symtab & NOTUSED(symtab)) 04619 { 04620 String s; 04621 BinRep second; /// ... The second argument of tuple pairs 04622 04623 empty_overflow(); 04624 04625 for (Iterator<BinRep> expr_iter = exprSet.to_set(); 04626 expr_iter.valid(); ++expr_iter) { 04627 String field; 04628 04629 expr_iter.current()[0].to_string(field); 04630 second = expr_iter.current()[1]; 04631 04632 if (field == "type") 04633 get_type(second, "FunctionCall"); 04634 else if (field == "args") { 04635 Iterator<BinRep> iter = second.to_tuple(); 04636 BinRep args = iter.current(); 04637 04638 p_assert( args.is_integer(), "FunctionCall::convert: " 04639 "Call's first arg field contains non-int." ); 04640 04641 Expression *e1 = tableEntry(args.to_integer()); 04642 04643 _left(e1); 04644 04645 ++iter; 04646 04647 if (iter.valid()) { 04648 args = iter.current(); 04649 04650 p_assert( args.is_integer(), "FunctionCall::convert: " 04651 "Call's second arg field contains non-int." ); 04652 04653 e1 = tableEntry(args.to_integer()); 04654 04655 _right(e1); 04656 } 04657 } 04658 else if (field == "size") { 04659 p_assert( second.is_integer(), 04660 "FunctionCallExpr::convert: 'size' field contains non-int"); 04661 _type.set(second.to_integer()); 04662 } 04663 else if (field != "op") { 04664 make_overflow(expr_iter, "FunctionCallExpr"); 04665 } 04666 } 04667 } 04668 04669 void 04670 FunctionCallExpr::print_debug(ostream & o, Boolean NOTUSED(debug)) const 04671 { 04672 print_prec(op(), (_left_valid() ? &_left_guarded() : 0), o); 04673 o << "("; 04674 print_prec(op(), (_right_valid() ? &_right_guarded() : 0), o); 04675 o << ")"; 04676 } 04677 04678 //----------------------------------------------------------------------------- 04679 /// HollerithConstExpr code: 04680 /// 04681 04682 HollerithConstExpr::~HollerithConstExpr() 04683 { 04684 /// ... nothing to do 04685 } 04686 04687 Expression * 04688 HollerithConstExpr::clone() const 04689 { 04690 return new HollerithConstExpr(*this); 04691 } 04692 04693 HollerithConstExpr & 04694 HollerithConstExpr::operator = (const HollerithConstExpr & e) 04695 { 04696 StringExpr::operator = (e); 04697 04698 return *this; 04699 } 04700 04701 int 04702 HollerithConstExpr::structures_OK() const 04703 { 04704 cerr << "HollerithConstExpr::structures_OK() not implemented"; 04705 return True; 04706 } 04707 04708 int 04709 HollerithConstExpr::exchange_expr( VDL & vdl ) 04710 { 04711 int index = vdl.look_up_expr( *this ); 04712 04713 if (index >= 0) 04714 return index; 04715 04716 index = Expression::exchange_expr( vdl ); 04717 04718 BinRep *b = CASTAWAY(BinRep *) vdl.data_ref(); 04719 04720 Set<BinRep> & S = b->find_ref( "expression" )->to_tuple()[index-1].to_set(); 04721 04722 BinRep *br = new BinRep( new List<BinRep> ); 04723 br->to_tuple().ins_last(new BinRep( "op" )); 04724 br->to_tuple().ins_last(new BinRep( "HOLLERITH_CONSTANT" )); 04725 S.ins( br ); 04726 04727 return index; 04728 } 04729 04730 04731 void 04732 HollerithConstExpr::convert(BinRep & exprSet, Symtab & NOTUSED(symtab)) 04733 { 04734 String s; 04735 BinRep second; /// ... The second argument of tuple pairs 04736 04737 empty_overflow(); 04738 04739 for (Iterator<BinRep> expr_iter = exprSet.to_set(); 04740 expr_iter.valid(); ++expr_iter) { 04741 String field; 04742 04743 expr_iter.current()[0].to_string(field); 04744 second = expr_iter.current()[1]; 04745 04746 if (field == "type") { 04747 p_assert( second.is_string(), "HollerithConstExpr::convert: " 04748 "type field doesn't contain string." ); 04749 04750 second.to_string(s); 04751 04752 p_assert( s == "CHARACTER", "HollerithConstExpr::convert: " 04753 "type field not CHARACTER" ); 04754 _type = (CHARACTER_TYPE); 04755 } 04756 else if (field == "data") { 04757 p_assert( second.is_string(), "HollerithConst::convert: " 04758 "'data' field does not contain an string." ); 04759 second.to_string(_data); 04760 } 04761 else if (field == "size") { 04762 p_assert( second.is_integer(), "HollerithConstExpr::convert: " 04763 "'size' field contains non-int." ); 04764 _type.set(second.to_integer()); 04765 } 04766 else if (field != "op") 04767 make_overflow(expr_iter, "HollerithConstExpr"); 04768 } 04769 } 04770 04771 //----------------------------------------------------------------------------- 04772 /// IDExpr code: 04773 /// 04774 04775 IDExpr::~IDExpr() 04776 { 04777 if (_substituted) 04778 delete _substituted; 04779 if (_arcs) 04780 delete _arcs; 04781 } 04782 04783 Expression * 04784 IDExpr::clone() const 04785 { 04786 return new IDExpr(*this); 04787 } 04788 04789 IDExpr & 04790 IDExpr::operator = (const IDExpr & e) 04791 { 04792 if (this != &e) { 04793 if (_substituted) 04794 delete _substituted; 04795 04796 _symbol = CASTAWAY(Symbol *) &e.symbol(); 04797 04798 if (e.substituted_valid()) 04799 _substituted = e.substituted_guarded().clone(); 04800 else 04801 _substituted = 0; 04802 04803 _arcs = 0; 04804 } 04805 04806 return *this; 04807 } 04808 04809 const Expression & 04810 IDExpr::substituted_guarded() const 04811 { 04812 p_assert(_substituted, 04813 "Guarded method called when field (_substituted) was NULL"); 04814 04815 return *_substituted; 04816 } 04817 04818 Expression & 04819 IDExpr::substituted_guarded() 04820 { 04821 p_assert(_substituted, 04822 "Guarded method called when field (_substituted) was NULL"); 04823 04824 return *_substituted; 04825 } 04826 04827 Boolean 04828 IDExpr::substituted_valid() const 04829 { 04830 if (_substituted) 04831 return True; 04832 else 04833 return False; 04834 } 04835 04836 void 04837 IDExpr::substituted(Expression * e) 04838 { 04839 if (_substituted) 04840 delete _substituted; 04841 04842 _substituted = e; 04843 } 04844 04845 Expression * 04846 IDExpr::grab_substituted() 04847 { 04848 Expression *temp = _substituted; 04849 _substituted = 0; 04850 return temp; 04851 } 04852 04853 const Symbol & 04854 IDExpr::symbol() const 04855 { 04856 return *_symbol; 04857 } 04858 04859 Symbol & 04860 IDExpr::symbol() 04861 { 04862 return *_symbol; 04863 } 04864 04865 void 04866 IDExpr::symbol(const Symbol & s) 04867 { 04868 _symbol = CASTAWAY(Symbol *)&s; 04869 } 04870 04871 int 04872 IDExpr::structures_OK() const 04873 { 04874 cerr << "ID::structures_OK() not implemented"; 04875 return True; 04876 } 04877 04878 int 04879 IDExpr::exchange_expr( VDL & vdl ) 04880 { 04881 int index = vdl.look_up_expr( *this ); 04882 04883 if (index >= 0) 04884 return index; 04885 04886 index = Expression::exchange_expr( vdl ); 04887 04888 BinRep *b = CASTAWAY(BinRep *) vdl.data_ref(); 04889 04890 Set<BinRep> & S = b->find_ref( "expression" )->to_tuple()[index-1].to_set(); 04891 04892 BinRep *br = new BinRep( new List<BinRep> ); 04893 br->to_tuple().ins_last(new BinRep( "op" )); 04894 br->to_tuple().ins_last(new BinRep( "ID" )); 04895 S.ins( br ); 04896 04897 br = new BinRep( new List<BinRep> ); 04898 br->to_tuple().ins_last(new BinRep( "name" )); 04899 br->to_tuple().ins_last(new BinRep( this->symbol().name_ref() )); 04900 S.ins( br ); 04901 04902 return index; 04903 } 04904 04905 04906 void 04907 IDExpr::convert(BinRep & exprSet, Symtab & symtab) 04908 { 04909 String s; 04910 BinRep second; /// ... The second argument of tuple pairs 04911 04912 empty_overflow(); 04913 04914 for (Iterator<BinRep> expr_iter = exprSet.to_set(); 04915 expr_iter.valid(); ++expr_iter) { 04916 String field; 04917 04918 expr_iter.current()[0].to_string(field); 04919 second = expr_iter.current()[1]; 04920 04921 if (field == "type") 04922 get_type(second, "ID"); 04923 else if (field == "size") { 04924 p_assert( second.is_integer(), "IDExpr::convert: " 04925 "'size' field contains non-int" ); 04926 _type.set(second.to_integer()); 04927 } 04928 else if (field == "name") { 04929 p_assert( second.is_string(), "IDExpr::convert: " 04930 " 'name' field contains non-string" ); 04931 04932 String idname; 04933 04934 second.to_string(idname); 04935 _symbol = symtab.find_ref(idname); 04936 04937 if (! _symbol) { 04938 cerr << "IDExpr::convert: " 04939 << "Symbol table does not contain entry for " 04940 << idname << endl; 04941 p_abort("(See above error message)"); 04942 } 04943 } 04944 else if (field == "substituted") { 04945 p_assert( second.is_integer(), 04946 "fillExpr: 'substituted' field contains non-int" ); 04947 04948 _substituted = tableEntry(second.to_integer()); 04949 } 04950 else if (field != "op" && field != "size") 04951 make_overflow(expr_iter, "IDExpr"); 04952 } 04953 } 04954 04955 void 04956 IDExpr::print_debug(ostream & o, Boolean debug) const 04957 { 04958 04959 if (! _symbol) 04960 o << "(NO SYMBOL)"; 04961 else { 04962 o << convert_case( _symbol->name_ref() ); 04963 } 04964 if (debug) { 04965 if (_substituted) 04966 o << "[" << *_substituted << "]"; 04967 } 04968 } 04969 04970 void 04971 IDExpr::relink_eptrs(ProgramUnit & p) 04972 { 04973 p_assert(_symbol, "IDExpr has NULL pointer"); 04974 _symbol = p.symtab().find_ref(_symbol->name_ref()); 04975 p_assert(_symbol, "IDExpr has NULL pointer"); 04976 } 04977 04978 //----------------------------------------------------------------------------- 04979 /// IOStarExpr code: 04980 /// 04981 04982 IOStarExpr::~IOStarExpr() 04983 { 04984 /// ... nothing to do 04985 } 04986 04987 Expression * 04988 IOStarExpr::clone() const 04989 { 04990 return new IOStarExpr(*this); 04991 } 04992 04993 IOStarExpr & 04994 IOStarExpr::operator = (const IOStarExpr & NOTUSED(e)) 04995 { 04996 return *this; 04997 } 04998 04999 int 05000 IOStarExpr::structures_OK() const 05001 { 05002 cerr << "IOStar::structures_OK() not implemented"; 05003 return True; 05004 } 05005 05006 int 05007 IOStarExpr::exchange_expr( VDL & vdl ) 05008 { 05009 int index = vdl.look_up_expr( *this ); 05010 05011 if (index >= 0) 05012 return index; 05013 05014 index = Expression::exchange_expr( vdl ); 05015 05016 BinRep *b = CASTAWAY(BinRep *) vdl.data_ref(); 05017 05018 Set<BinRep> & S = b->find_ref( "expression" )->to_tuple()[index-1].to_set(); 05019 05020 BinRep *br = new BinRep( new List<BinRep> ); 05021 br->to_tuple().ins_last(new BinRep( "op" )); 05022 br->to_tuple().ins_last(new BinRep( "IO*" )); 05023 S.ins( br ); 05024 05025 return index; 05026 } 05027 05028 05029 void 05030 IOStarExpr::convert(BinRep & exprSet, Symtab & NOTUSED(symtab)) 05031 { 05032 String s; 05033 BinRep second; /// ... The second argument of tuple pairs 05034 05035 empty_overflow(); 05036 05037 for (Iterator<BinRep> expr_iter = exprSet.to_set(); 05038 expr_iter.valid(); ++expr_iter) { 05039 String field; 05040 05041 expr_iter.current()[0].to_string(field); 05042 second = expr_iter.current()[1]; 05043 05044 if (field == "type") 05045 get_type(second, "IOStar"); 05046 else if (field != "op" && field != "size") 05047 make_overflow(expr_iter, "IOStarExpr"); 05048 } 05049 } 05050 05051 void 05052 IOStarExpr::print_debug(ostream & o, Boolean NOTUSED(debug)) const 05053 { 05054 o << "*"; 05055 } 05056 05057 //----------------------------------------------------------------------------- 05058 /// InfinityExpr code: 05059 /// 05060 05061 InfinityExpr::~InfinityExpr() 05062 { 05063 /// ... Nothing to do 05064 } 05065 05066 Expression * 05067 InfinityExpr::clone() const 05068 { 05069 return new InfinityExpr(*this); 05070 } 05071 05072 InfinityExpr & 05073 InfinityExpr::operator = (const InfinityExpr & other) 05074 { 05075 _sign = other._sign; 05076 return *this; 05077 } 05078 05079 void 05080 InfinityExpr::sign(int s) 05081 { 05082 _sign = (s >= 0) ? 1: -1; 05083 } 05084 05085 int 05086 InfinityExpr::sign() const 05087 { 05088 return _sign; 05089 } 05090 05091 int 05092 InfinityExpr::structures_OK() const 05093 { 05094 if (_sign == 0) { 05095 cerr << "InfinityExpr::structures_OK(): Expression has a zero sign.\n"; 05096 return False; 05097 } 05098 else if (type().data_type() != INTEGER_TYPE) { 05099 cerr << "InfinityExpr::structures_OK(): " 05100 << "Expression has a non-integer type.\n"; 05101 return False; 05102 } 05103 05104 return True; 05105 } 05106 05107 int 05108 InfinityExpr::exchange_expr( VDL & vdl ) 05109 { 05110 int index = vdl.look_up_expr( *this ); 05111 05112 if (index >= 0) 05113 return index; 05114 05115 index = Expression::exchange_expr( vdl ); 05116 05117 BinRep *b = CASTAWAY(BinRep *) vdl.data_ref(); 05118 05119 Set<BinRep> & S = b->find_ref( "expression" )->to_tuple()[index-1].to_set(); 05120 05121 BinRep *br = new BinRep( new List<BinRep> ); 05122 br->to_tuple().ins_last(new BinRep( "op" )); 05123 br->to_tuple().ins_last(new BinRep( "INFINITY" )); 05124 S.ins( br ); 05125 05126 return index; 05127 } 05128 05129 05130 void 05131 InfinityExpr::convert(BinRep & NOTUSED(exprSet), 05132 Symtab & NOTUSED(symtab)) 05133 { 05134 p_abort( "Cannot read a InfinityExpr object from a binstring."); 05135 } 05136 05137 void 05138 InfinityExpr::print_debug(ostream & o, Boolean NOTUSED(debug)) const 05139 { 05140 if (_sign >= 0) 05141 o << "Inf"; 05142 else 05143 o << "-Inf"; 05144 } 05145 05146 //----------------------------------------------------------------------------- 05147 /// IntConstExpr code: 05148 /// 05149 05150 IntConstExpr::~IntConstExpr() 05151 { 05152 /// ... nothing to do 05153 } 05154 05155 int 05156 IntConstExpr::value() const 05157 { 05158 return _value; 05159 } 05160 05161 void 05162 IntConstExpr::value(int v) 05163 { 05164 _value = v; 05165 } 05166 05167 Expression * 05168 IntConstExpr::clone() const 05169 { 05170 return new IntConstExpr(*this); 05171 } 05172 05173 IntConstExpr & 05174 IntConstExpr::operator = (const IntConstExpr & e) 05175 { 05176 if (this != &e) 05177 _value = e.value(); 05178 05179 return *this; 05180 } 05181 05182 int 05183 IntConstExpr::structures_OK() const 05184 { 05185 cerr << "IntConstExpr::structures_OK() not implemented"; 05186 return True; 05187 } 05188 05189 int 05190 IntConstExpr::exchange_expr( VDL & vdl ) 05191 { 05192 int index = vdl.look_up_expr( *this ); 05193 05194 if (index >= 0) 05195 return index; 05196 05197 index = Expression::exchange_expr( vdl ); 05198 05199 BinRep *b = CASTAWAY(BinRep *) vdl.data_ref(); 05200 05201 Set<BinRep> & S = b->find_ref( "expression" )->to_tuple()[index-1].to_set(); 05202 05203 BinRep *br = new BinRep( new List<BinRep> ); 05204 br->to_tuple().ins_last(new BinRep( "op" )); 05205 br->to_tuple().ins_last(new BinRep( "INTEGER_CONSTANT" )); 05206 S.ins( br ); 05207 05208 br = new BinRep( new List<BinRep> ); 05209 br->to_tuple().ins_last(new BinRep( "data" )); 05210 br->to_tuple().ins_last(new BinRep( this->value() )); 05211 S.ins( br ); 05212 05213 return index; 05214 } 05215 05216 05217 void 05218 IntConstExpr::convert(BinRep & exprSet, Symtab & NOTUSED(symtab)) 05219 { 05220 String s; 05221 BinRep second; /// ... The second argument of tuple pairs 05222 05223 empty_overflow(); 05224 05225 for (Iterator<BinRep> expr_iter = exprSet.to_set(); 05226 expr_iter.valid(); ++expr_iter) { 05227 String field; 05228 05229 expr_iter.current()[0].to_string(field); 05230 second = expr_iter.current()[1]; 05231 05232 if (field == "type") { 05233 p_assert( second.is_string(), "IntConstExpr::convert: " 05234 "type field doesn't contain string" ); 05235 05236 second.to_string(s); 05237 05238 p_assert( (s == "INTEGER"), "IntConstExpr not of INTEGER type" ); 05239 _type = INTEGER_TYPE; 05240 } 05241 else if (field == "data") { 05242 if (!second.is_integer()) { 05243 cerr << "IntConstExpr's 'data' field contains non-int in : " 05244 << exprSet << endl; 05245 p_abort("(See above error message)"); 05246 } 05247 else 05248 _value = second.to_integer(); 05249 } 05250 else if (field != "op" && field != "size") 05251 make_overflow(expr_iter, "IntConstExpr"); 05252 } 05253 } 05254 05255 void 05256 IntConstExpr::print_debug(ostream & o, Boolean NOTUSED(debug)) const 05257 { 05258 o << _value; 05259 } 05260 05261 //----------------------------------------------------------------------------- 05262 /// IntrinsicCallExpr code: 05263 /// 05264 05265 /// Note: The following data fields are aliased: 05266 /// intrinsic = left 05267 /// parameters = right 05268 05269 IntrinsicCallExpr::~IntrinsicCallExpr() 05270 { 05271 /// ... nothing to do 05272 } 05273 05274 Expression * 05275 IntrinsicCallExpr::clone() const 05276 { 05277 return new IntrinsicCallExpr(*this); 05278 } 05279 05280 IntrinsicCallExpr & IntrinsicCallExpr::operator = (const IntrinsicCallExpr & e) { 05281 BinaryExpr::operator = (e); 05282 return *this; 05283 } 05284 05285 void 05286 IntrinsicCallExpr::intrinsic(Expression * e) 05287 { 05288 p_assert(e->op() == ID_OP, 05289 "IntrinsicCallExpr::Intrinsic( ) not an IDExpr"); 05290 _left(e); 05291 } 05292 05293 const Expression & 05294 IntrinsicCallExpr::intrinsic() const 05295 { 05296 return _left_guarded(); 05297 } 05298 05299 Expression & 05300 IntrinsicCallExpr::intrinsic() 05301 { 05302 return _left_guarded(); 05303 } 05304 05305 void 05306 IntrinsicCallExpr::parameters(Expression * e) 05307 { 05308 p_assert(e->op() == COMMA_OP, 05309 "IntrinsicCallExpr::Parameters( ) not a CommaExpr"); 05310 _right(e); 05311 } 05312 05313 const Expression & 05314 IntrinsicCallExpr::parameters_guarded() const 05315 { 05316 return _right_guarded(); 05317 } 05318 05319 Expression & 05320 IntrinsicCallExpr::parameters_guarded() 05321 { 05322 return _right_guarded(); 05323 } 05324 05325 Boolean 05326 IntrinsicCallExpr::parameters_valid() const 05327 { 05328 return _right_valid(); 05329 } 05330 05331 int 05332 IntrinsicCallExpr::structures_OK() const 05333 { 05334 cerr << "IntrinsicCallExpr::structures_OK() not implemented"; 05335 return True; 05336 } 05337 05338 int 05339 IntrinsicCallExpr::exchange_expr( VDL & vdl ) 05340 { 05341 int index = vdl.look_up_expr( *this ); 05342 05343 if (index >= 0) 05344 return index; 05345 05346 index = Expression::exchange_expr( vdl ); 05347 05348 BinRep *b = CASTAWAY(BinRep *) vdl.data_ref(); 05349 05350 Set<BinRep> & S = b->find_ref( "expression" )->to_tuple()[index-1].to_set(); 05351 05352 BinRep *br = new BinRep( new List<BinRep> ); 05353 br->to_tuple().ins_last(new BinRep( "op" )); 05354 br->to_tuple().ins_last(new BinRep( "INTRINSIC_CALL" )); 05355 S.ins( br ); 05356 05357 br = new BinRep( new List<BinRep> ); 05358 br->to_tuple().ins_last(new BinRep( "args" )); 05359 BinRep *bt = new BinRep(new List<BinRep>); 05360 br->to_tuple().ins_last( bt ); 05361 S.ins( br ); 05362 05363 bt->to_tuple().ins_last( 05364 new BinRep( this->intrinsic().exchange_expr(vdl))); 05365 bt->to_tuple().ins_last( 05366 new BinRep( this->parameters_guarded().exchange_expr(vdl))); 05367 05368 return index; 05369 } 05370 05371 05372 void 05373 IntrinsicCallExpr::convert(BinRep & exprSet, Symtab & NOTUSED(symtab)) 05374 { 05375 String s; 05376 BinRep second; /// ... The second argument of tuple pairs 05377 05378 empty_overflow(); 05379 05380 for (Iterator<BinRep> expr_iter = exprSet.to_set(); 05381 expr_iter.valid(); ++expr_iter) { 05382 String field; 05383 05384 expr_iter.current()[0].to_string(field); 05385 second = expr_iter.current()[1]; 05386 05387 if (field == "type") 05388 get_type(second, "IntrinsicCall"); 05389 else if (field == "args") { 05390 Iterator<BinRep> iter = second.to_tuple(); 05391 BinRep & args = iter.current(); 05392 05393 p_assert( args.is_integer(), "IntrinsicCall::convert: " 05394 "Call's first arg field contains non-int" ); 05395 05396 Expression *e1 = tableEntry(args.to_integer()); 05397 05398 _left(e1); 05399 05400 ++iter; 05401 05402 if (iter.valid()) { 05403 args = iter.current(); 05404 05405 p_assert( (args.is_integer()), "IntrinsicCall::convert: " 05406 "Call's second arg field contains non-int" ); 05407 05408 e1 = tableEntry(args.to_integer()); 05409 05410 _right(e1); 05411 } 05412 } 05413 else if (field != "op" && field != "size") 05414 make_overflow(expr_iter, "IntrinsicCall"); 05415 } 05416 } 05417 05418 void 05419 IntrinsicCallExpr::print_debug(ostream & o, Boolean NOTUSED(debug)) const 05420 { 05421 /// ... Apply translate_special_name to the intrinsic function name, since 05422 /// ... it may have a machine-specific form 05423 05424 if (_left_valid()) { 05425 o << translate_special_name(this->intrinsic().symbol().name_ref()); 05426 } else { 05427 o << "<UNDEF>"; 05428 } 05429 05430 o << "("; 05431 print_prec(op(), (_right_valid() ? &_right_guarded() : 0), o); 05432 o << ")"; 05433 } 05434 05435 //----------------------------------------------------------------------------- 05436 /// LabelExpr code: 05437 /// 05438 /// Note: The following data fields are aliased: 05439 /// label = data 05440 05441 LabelExpr::~LabelExpr() 05442 { 05443 /// ... nothing to do 05444 } 05445 05446 LabelExpr & 05447 LabelExpr::operator = (const LabelExpr & e) 05448 { 05449 _stmt = e._stmt; 05450 return *this; 05451 } 05452 05453 Expression * 05454 LabelExpr::clone() const 05455 { 05456 return new LabelExpr(*this); 05457 } 05458 05459 const Statement & 05460 LabelExpr::stmt() const 05461 { 05462 return *_stmt; 05463 } 05464 05465 Statement & 05466 LabelExpr::stmt() 05467 { 05468 return *_stmt; 05469 } 05470 05471 void 05472 LabelExpr::stmt(Statement & stmt) 05473 { 05474 p_assert(stmt.stmt_class()==LABEL_STMT, 05475 "LabelExpr::stmt: attempt to point at non-label"); 05476 _stmt = &stmt; 05477 } 05478 05479 void 05480 LabelExpr::print_debug(ostream & o, Boolean NOTUSED(debug)) const 05481 { 05482 if (_stmt) { 05483 o << _stmt->value(); 05484 } 05485 else { 05486 o << "<UNDEFINED STMT>"; 05487 } 05488 } 05489 05490 int 05491 LabelExpr::structures_OK() const 05492 { 05493 if (!_stmt) { 05494 cerr << "LabelExpr::structures_OK(): Found NULL _stmt field\n"; 05495 cerr << "In LabelExpr:\n" << flush << *this; 05496 return False; 05497 } 05498 05499 if (!_stmt->structures_OK()) { 05500 cerr << "In context of LabelExpr:\n" << flush << *this; 05501 return False; 05502 } 05503 05504 return True; 05505 } 05506 05507 void 05508 LabelExpr::relink_eptrs(ProgramUnit & p) 05509 { 05510 p_assert(_stmt, "LabelExpr has NULL pointer"); 05511 _stmt = p.stmts().find_ref(_stmt->tag()); 05512 p_assert(_stmt, "LabelExpr has NULL pointer"); 05513 } 05514 05515 int 05516 LabelExpr::exchange_expr( VDL & vdl ) 05517 { 05518 int index = vdl.look_up_expr( *this ); 05519 05520 if (index >= 0) 05521 return index; 05522 05523 index = Expression::exchange_expr( vdl ); 05524 05525 BinRep *b = CASTAWAY(BinRep *) vdl.data_ref(); 05526 05527 Set<BinRep> & S = b->find_ref( "expression" )->to_tuple()[index-1].to_set(); 05528 05529 BinRep *br = new BinRep( new List<BinRep> ); 05530 br->to_tuple().ins_last(new BinRep( "op" )); 05531 br->to_tuple().ins_last(new BinRep( "LABEL" )); 05532 S.ins( br ); 05533 05534 return index; 05535 } 05536 05537 05538 void 05539 LabelExpr::convert(BinRep & NOTUSED(exprSet), Symtab & NOTUSED(symtab)) 05540 { 05541 p_abort( "Internal Error: The conversion of a binstring to an " 05542 "Expression came across an old \"label\" op, which was " 05543 "believed to no longer be attainable outside of the " 05544 "scanner. Please report this bug to the development " 05545 "group. To the development group: See the comments " 05546 "in the LabelExpr::convert() routine."); 05547 05548 /// ... NOTE: See also the p_assert() in ExprTable.cc's get_expr_obj() 05549 05550 /// ... The old LabelExpr class to which the "label" op used to 05551 /// ... be converted can still be used here. However, the old 05552 /// ... LabelExpr contained a string label, 05553 /// ... the new one expects a statement label, so the convert 05554 /// ... routine must simply be changed to convert the statement label 05555 /// ... string into a statement pointer. 05556 05557 #if 0 05558 String s; 05559 BinRep second; /// ... The second argument of tuple pairs 05560 05561 empty_overflow(); 05562 05563 for (Iterator<BinRep> expr_iter = exprSet.to_set(); 05564 expr_iter.valid(); ++expr_iter) { 05565 String field; 05566 05567 expr_iter.current()[0].to_string(field); 05568 second = expr_iter.current()[1]; 05569 05570 if (field == "type") 05571 get_type(second, "Label"); 05572 else if (field == "label") { 05573 p_assert( second.is_string(), "LabelExpr::convert: " 05574 "'label' field does not contain label" ); 05575 second.to_string(_data); 05576 } 05577 else if (field != "op") 05578 make_overflow(expr_iter, "LabelExpr"); 05579 } 05580 #endif 05581 } 05582 05583 //----------------------------------------------------------------------------- 05584 /// LambdaCallExpr code: 05585 /// 05586 /// Note: The following data fields are aliased: 05587 /// expr = left 05588 /// parameters = right; 05589 05590 LambdaCallExpr::~LambdaCallExpr() 05591 { 05592 /// ... nothing to do 05593 } 05594 05595 Expression * 05596 LambdaCallExpr::clone() const 05597 { 05598 return new LambdaCallExpr(*this); 05599 } 05600 05601 LambdaCallExpr & 05602 LambdaCallExpr::operator = (const LambdaCallExpr & e) 05603 { 05604 BinaryExpr::operator = (e); 05605 05606 return *this; 05607 } 05608 05609 void 05610 LambdaCallExpr::lambda_expr(Expression * e) 05611 { 05612 _left(e); 05613 } 05614 05615 const Expression & 05616 LambdaCallExpr::lambda_expr() const 05617 { 05618 return _left_guarded(); 05619 } 05620 05621 Expression & 05622 LambdaCallExpr::lambda_expr() 05623 { 05624 return _left_guarded(); 05625 } 05626 05627 void 05628 LambdaCallExpr::parameters(Expression * e) 05629 { 05630 p_assert(e->op() == COMMA_OP, 05631 "LambdaCallExpr::parameters( ) not a CommaExpr"); 05632 _right(e); 05633 } 05634 05635 const Expression & 05636 LambdaCallExpr::parameters_guarded() const 05637 { 05638 return _right_guarded(); 05639 } 05640 05641 Expression & 05642 LambdaCallExpr::parameters_guarded() 05643 { 05644 return _right_guarded(); 05645 } 05646 05647 Boolean 05648 LambdaCallExpr::parameters_valid() const 05649 { 05650 return _right_valid(); 05651 } 05652 05653 int 05654 LambdaCallExpr::structures_OK() const 05655 { 05656 cerr << "LambdaCallExpr::structures_OK() not implemented"; 05657 return True; 05658 } 05659 05660 int 05661 LambdaCallExpr::exchange_expr( VDL & vdl ) 05662 { 05663 int index = vdl.look_up_expr( *this ); 05664 05665 if (index >= 0) 05666 return index; 05667 05668 index = Expression::exchange_expr( vdl ); 05669 05670 BinRep *b = CASTAWAY(BinRep *) vdl.data_ref(); 05671 05672 Set<BinRep> & S = b->find_ref( "expression" )->to_tuple()[index-1].to_set(); 05673 05674 BinRep *br = new BinRep( new List<BinRep> ); 05675 br->to_tuple().ins_last(new BinRep( "op" )); 05676 br->to_tuple().ins_last(new BinRep( "LAMBDA_CALL" )); 05677 S.ins( br ); 05678 05679 br = new BinRep( new List<BinRep> ); 05680 br->to_tuple().ins_last(new BinRep( "args" )); 05681 BinRep *bt = new BinRep(new List<BinRep>); 05682 br->to_tuple().ins_last( bt ); 05683 S.ins( br ); 05684 05685 bt->to_tuple().ins_last( 05686 new BinRep( this->lambda_expr().exchange_expr(vdl))); 05687 bt->to_tuple().ins_last( 05688 new BinRep( this->parameters_guarded().exchange_expr(vdl))); 05689 05690 return index; 05691 } 05692 05693 05694 void 05695 LambdaCallExpr::convert(BinRep & exprSet, Symtab & NOTUSED(symtab)) 05696 { 05697 String s; 05698 BinRep second; /// ... The second argument of tuple pairs 05699 05700 empty_overflow(); 05701 05702 for (Iterator<BinRep> expr_iter = exprSet.to_set(); 05703 expr_iter.valid(); ++expr_iter) { 05704 String field; 05705 05706 expr_iter.current()[0].to_string(field); 05707 second = expr_iter.current()[1]; 05708 05709 if (field == "type") 05710 get_type(second, "LambdaCall"); 05711 else if (field == "args") { 05712 Iterator<BinRep> iter = second.to_tuple(); 05713 BinRep & args = iter.current(); 05714 05715 p_assert( args.is_integer(), "LambdaCall::convert: " 05716 "Call's first arg field contains non-int" ); 05717 05718 Expression *e1 = tableEntry(args.to_integer()); 05719 05720 _left(e1); 05721 05722 ++iter; 05723 05724 if (iter.valid()) { 05725 args = iter.current(); 05726 05727 p_assert( args.is_integer(), "LambdaCall::convert: " 05728 "Call's second arg field contains non-int" ); 05729 05730 e1 = tableEntry(args.to_integer()); 05731 05732 _right(e1); 05733 } 05734 } 05735 else if (field != "op" && field != "size") 05736 make_overflow(expr_iter, "LambdaCall"); 05737 } 05738 } 05739 05740 void 05741 LambdaCallExpr::print_debug(ostream & o, Boolean NOTUSED(debug)) const 05742 { 05743 print_prec(op(), (_left_valid() ? &_left_guarded() : 0), o); 05744 o << "("; 05745 print_prec(op(), (_right_valid() ? &_right_guarded() : 0), o); 05746 o << ")"; 05747 } 05748 05749 //----------------------------------------------------------------------------- 05750 /// LogicalConstExpr code: 05751 /// 05752 05753 LogicalConstExpr::~LogicalConstExpr() 05754 { 05755 /// ... nothing to do 05756 } 05757 05758 LogicalConstExpr & 05759 LogicalConstExpr::operator = (const LogicalConstExpr & e) 05760 { 05761 StringExpr::operator = (e); 05762 05763 return *this; 05764 } 05765 05766 Expression * 05767 LogicalConstExpr::clone() const 05768 { 05769 return new LogicalConstExpr(*this); 05770 } 05771 05772 int 05773 LogicalConstExpr::structures_OK() const 05774 { 05775 cerr << "LogicalConstExpr::structures_OK() not implemented"; 05776 return True; 05777 } 05778 05779 int 05780 LogicalConstExpr::exchange_expr( VDL & vdl ) 05781 { 05782 int index = vdl.look_up_expr( *this ); 05783 05784 if (index >= 0) 05785 return index; 05786 05787 index = Expression::exchange_expr( vdl ); 05788 05789 BinRep *b = CASTAWAY(BinRep *) vdl.data_ref(); 05790 05791 Set<BinRep> & S = b->find_ref( "expression" )->to_tuple()[index-1].to_set(); 05792 05793 BinRep *br = new BinRep( new List<BinRep> ); 05794 br->to_tuple().ins_last(new BinRep( "op" )); 05795 br->to_tuple().ins_last(new BinRep( "LOGICAL_CONSTANT" )); 05796 S.ins( br ); 05797 05798 br = new BinRep( new List<BinRep> ); 05799 br->to_tuple().ins_last(new BinRep( "data" )); 05800 br->to_tuple().ins_last(new BinRep( this->data_ref() )); 05801 S.ins( br ); 05802 05803 return index; 05804 } 05805 05806 05807 void 05808 LogicalConstExpr::convert(BinRep & exprSet, Symtab & NOTUSED(symtab)) 05809 { 05810 String s; 05811 BinRep second; /// ... The second argument of tuple pairs 05812 05813 empty_overflow(); 05814 05815 for (Iterator<BinRep> expr_iter = exprSet.to_set(); 05816 expr_iter.valid(); ++expr_iter) { 05817 String field; 05818 05819 expr_iter.current()[0].to_string(field); 05820 second = expr_iter.current()[1]; 05821 05822 if (field == "type") { 05823 p_assert( second.is_string(), "LogicalConstExpr::convert: " 05824 "type field doesn't contain string" ); 05825 second.to_string(s); 05826 05827 p_assert( (s == "LOGICAL"), 05828 "LogicalConstExpr::convert: type field not LOGICAL" ); 05829 _type = (LOGICAL_TYPE); 05830 } 05831 else if (field == "data") { 05832 p_assert( second.is_string(), "LogicalConst::convert: " 05833 "'data' field does not contain an string." ); 05834 second.to_string(_data); 05835 } 05836 else if (field != "op" && field != "size") 05837 make_overflow(expr_iter, "LogicalConstExpr"); 05838 } 05839 } 05840 05841 //----------------------------------------------------------------------------- 05842 /// KeyExpr code: 05843 /// 05844 05845 KeyExpr::~KeyExpr() 05846 { 05847 /// ... nothing to do 05848 } 05849 05850 KeyExpr & 05851 KeyExpr::operator = (const KeyExpr & e) 05852 { 05853 StringExpr::operator = (e); 05854 05855 return *this; 05856 } 05857 05858 Expression * 05859 KeyExpr::clone() const 05860 { 05861 return new KeyExpr(*this); 05862 } 05863 05864 int 05865 KeyExpr::structures_OK() const 05866 { 05867 return True; 05868 } 05869 05870 int 05871 KeyExpr::exchange_expr( VDL & vdl ) 05872 { 05873 int index = vdl.look_up_expr( *this ); 05874 05875 if (index >= 0) 05876 return index; 05877 05878 index = Expression::exchange_expr( vdl ); 05879 05880 BinRep *b = CASTAWAY(BinRep *) vdl.data_ref(); 05881 05882 Set<BinRep> & S = b->find_ref( "expression" )->to_tuple()[index-1].to_set(); 05883 05884 BinRep *br = new BinRep( new List<BinRep> ); 05885 br->to_tuple().ins_last(new BinRep( "op" )); 05886 br->to_tuple().ins_last(new BinRep( "KEY" )); 05887 S.ins( br ); 05888 05889 br = new BinRep( new List<BinRep> ); 05890 br->to_tuple().ins_last(new BinRep( "data" )); 05891 br->to_tuple().ins_last(new BinRep( this->data_ref() )); 05892 S.ins( br ); 05893 05894 return index; 05895 } 05896 05897 05898 void 05899 KeyExpr::convert(BinRep & exprSet, Symtab & NOTUSED(symtab)) 05900 { 05901 String s; 05902 BinRep second; /// ... The second argument of tuple pairs 05903 05904 empty_overflow(); 05905 05906 for (Iterator<BinRep> expr_iter = exprSet.to_set(); 05907 expr_iter.valid(); ++expr_iter) { 05908 String field; 05909 05910 expr_iter.current()[0].to_string(field); 05911 second = expr_iter.current()[1]; 05912 05913 if (field == "data") { 05914 p_assert( second.is_string(), "KeyExpr::convert: " 05915 "'data' field does not contain an string." ); 05916 second.to_string(_data); 05917 } 05918 else if (field != "op" && field != "size" && field != "type") 05919 make_overflow(expr_iter, "KeyExpr"); 05920 } 05921 } 05922 05923 //----------------------------------------------------------------------------- 05924 /// NonBinaryExpr code: 05925 /// 05926 05927 NonBinaryExpr::~NonBinaryExpr() 05928 { 05929 /// ... nothing to do 05930 } 05931 05932 Expression * 05933 NonBinaryExpr::clone() const 05934 { 05935 return new NonBinaryExpr(*this); 05936 } 05937 05938 NonBinaryExpr::NonBinaryExpr(OP_TYPE o, const Type & e, List<Expression> *list) 05939 : Expression(o, e) 05940 { 05941 for (Iterator<Expression>iter = *list; iter.valid(); ++iter) 05942 _arg_list.ins_last(list->grab(iter.current())); 05943 05944 delete list; 05945 } 05946 05947 NonBinaryExpr & 05948 NonBinaryExpr::operator = (const NonBinaryExpr & e) 05949 { 05950 if (this != &e) 05951 _arg_list = e.arg_list(); 05952 05953 return *this; 05954 } 05955 05956 const List<Expression> & 05957 NonBinaryExpr::arg_list() const 05958 { 05959 return _arg_list; 05960 } 05961 05962 List<Expression> & 05963 NonBinaryExpr::arg_list() 05964 { 05965 return _arg_list; 05966 } 05967 05968 const RefList<Expression> * 05969 NonBinaryExpr::arg_refs() const 05970 { 05971 RefList<Expression> *args = new RefList<Expression>; 05972 Iterator<Expression> iter((List<Expression>&) _arg_list); 05973 05974 for (; iter.valid(); ++iter) 05975 args->ins_last(iter.current()); 05976 05977 return args; 05978 } 05979 05980 int 05981 NonBinaryExpr::structures_OK() const 05982 { 05983 cerr << "NonBinaryExpr::structures_OK() not implemented"; 05984 return True; 05985 } 05986 05987 int 05988 NonBinaryExpr::exchange_expr( VDL & vdl ) 05989 { 05990 int index = vdl.look_up_expr( *this ); 05991 05992 if (index >= 0) 05993 return index; 05994 05995 index = Expression::exchange_expr( vdl ); 05996 05997 BinRep *b = CASTAWAY(BinRep *) vdl.data_ref(); 05998 05999 Set<BinRep> & S = b->find_ref( "expression" )->to_tuple()[index-1].to_set(); 06000 06001 String opcode; 06002 06003 switch (this->op()) { 06004 case ADD_OP: opcode = "+"; break; 06005 case MULT_OP: opcode = "*"; break; 06006 case OR_OP: opcode = ".OR."; break; 06007 case AND_OP: opcode = ".AND."; break; 06008 case EQV_OP: opcode = ".EQV."; break; 06009 case NEQV_OP: opcode = ".NEQV."; break; 06010 case COLON_OP: opcode = ":"; break; 06011 default: break; 06012 } 06013 06014 BinRep *br = new BinRep( new List<BinRep> ); 06015 br->to_tuple().ins_last(new BinRep( "op" )); 06016 br->to_tuple().ins_last(new BinRep( opcode )); 06017 S.ins( br ); 06018 06019 br = new BinRep( new List<BinRep> ); 06020 br->to_tuple().ins_last(new BinRep( "args" )); 06021 BinRep *bt = new BinRep(new List<BinRep>); 06022 br->to_tuple().ins_last( bt ); 06023 S.ins( br ); 06024 06025 for (Iterator<Expression> iter = _arg_list; iter.valid(); ++iter) { 06026 bt->to_tuple().ins_last( 06027 new BinRep( iter.current().exchange_expr(vdl))); 06028 } 06029 06030 return index; 06031 } 06032 06033 void 06034 NonBinaryExpr::convert(BinRep & exprSet, Symtab & NOTUSED(symtab)) 06035 { 06036 String s; 06037 BinRep second; /// ... The second argument of tuple pairs 06038 06039 empty_overflow(); 06040 06041 for (Iterator<BinRep> expr_iter = exprSet.to_set(); 06042 expr_iter.valid(); ++expr_iter) { 06043 String field; 06044 06045 expr_iter.current()[0].to_string(field); 06046 second = expr_iter.current()[1]; 06047 06048 if (field == "type") 06049 get_type(second, "NonBinary"); 06050 else if (field == "args") { 06051 06052 for (Iterator<BinRep> iter = second.to_tuple(); 06053 iter.valid(); ++iter) { 06054 BinRep & args = iter.current(); 06055 06056 p_assert( args.is_integer() || args.is_omega(), 06057 "NonBinaryExpr::convert: " 06058 "Non-Binary Op's arg field contains non-int or OM" ); 06059 06060 Expression *thug = 0; 06061 06062 if (args.is_integer()) 06063 thug = tableEntry(args.to_integer()); 06064 else if (args.is_omega()) 06065 thug = new OmegaExpr; 06066 06067 _arg_list.ins_last(thug); 06068 } 06069 } 06070 else if (field != "op" && field != "size") 06071 make_overflow(expr_iter, "NonBinaryExpr"); 06072 } 06073 } 06074 06075 void 06076 NonBinaryExpr::print_debug(ostream & o, Boolean NOTUSED(debug)) const 06077 { 06078 String s; 06079 06080 switch (op()) { 06081 case CONCAT_OP: 06082 s = "/// ... "; 06083 break; 06084 case COLON_OP: 06085 s = ":"; 06086 break; 06087 case OR_OP: 06088 s = ".OR."; 06089 break; 06090 case AND_OP: 06091 s = ".AND."; 06092 break; 06093 case EQV_OP: 06094 s = ".EQV."; 06095 break; 06096 case NEQV_OP: 06097 s = ".NEQV."; 06098 break; 06099 case ADD_OP: 06100 s = "+"; 06101 break; 06102 case MULT_OP: 06103 s = "*"; 06104 break; 06105 case COMMA_OP: 06106 s = ", "; 06107 break; 06108 default: 06109 p_abort("Unknown _OP"); 06110 } 06111 06112 print_prec_list( o, op(), _arg_list, s); 06113 } 06114 06115 void 06116 NonBinaryExpr::relink_eptrs(ProgramUnit & p) 06117 { 06118 Iterator<Expression>iter = _arg_list; 06119 06120 for (; iter.valid(); ++iter) 06121 iter.current().relink_eptrs(p); 06122 } 06123 06124 //----------------------------------------------------------------------------- 06125 /// OmegaExpr code: 06126 /// 06127 06128 OmegaExpr::~OmegaExpr() 06129 { 06130 /// ... nothing to do 06131 } 06132 06133 OmegaExpr & 06134 OmegaExpr::operator = (const OmegaExpr & NOTUSED(e)) 06135 { 06136 return *this; 06137 } 06138 06139 Expression * 06140 OmegaExpr::clone() const 06141 { 06142 return new OmegaExpr(*this); 06143 } 06144 06145 int 06146 OmegaExpr::structures_OK() const 06147 { 06148 cerr << "OmegaExpr::structures_OK() not implemented"; 06149 return True; 06150 } 06151 06152 int 06153 OmegaExpr::exchange_expr( VDL & vdl ) 06154 { 06155 int index = vdl.look_up_expr( *this ); 06156 06157 if (index >= 0) 06158 return index; 06159 06160 index = Expression::exchange_expr( vdl ); 06161 06162 BinRep *b = CASTAWAY(BinRep *) vdl.data_ref(); 06163 06164 Set<BinRep> & S = b->find_ref( "expression" )->to_tuple()[index-1].to_set(); 06165 06166 BinRep *br = new BinRep( new List<BinRep> ); 06167 br->to_tuple().ins_last(new BinRep( "op" )); 06168 br->to_tuple().ins_last(new BinRep( "OMEGA_EXPR" )); 06169 S.ins( br ); 06170 06171 return index; 06172 } 06173 06174 void 06175 OmegaExpr::convert(BinRep & NOTUSED(exprSet), Symtab & NOTUSED(symtab)) 06176 { 06177 /// ... nothing to do 06178 } 06179 06180 void 06181 OmegaExpr::print_debug(ostream & o, Boolean NOTUSED(debug)) const 06182 { 06183 o << ""; 06184 } 06185 06186 //----------------------------------------------------------------------------- 06187 /// GSAExpr code: 06188 /// 06189 06190 /// Note: The following data fields are aliased: 06191 /// gate = left 06192 /// parameters = right 06193 06194 GSAExpr::~GSAExpr() 06195 { 06196 /// ... nothing to do 06197 } 06198 06199 Expression * 06200 GSAExpr::clone() const 06201 { 06202 return new GSAExpr(*this); 06203 } 06204 06205 GSAExpr & 06206 GSAExpr::operator = (const GSAExpr & e) 06207 { 06208 BinaryExpr::operator = (e); 06209 06210 return *this; 06211 } 06212 06213 void 06214 GSAExpr::gate(Expression * e) 06215 { 06216 p_assert(!e || e->op() == OMEGA_OP || e->type().data_type() == LOGICAL_TYPE, 06217 "GSAExpr:: gate( ) not an OmegaExpr nor a logical expression "); 06218 _left(null_to_omega(e)); 06219 } 06220 06221 const Expression & 06222 GSAExpr::gate() const 06223 { 06224 return _left_guarded(); 06225 } 06226 06227 Expression & 06228 GSAExpr::gate() 06229 { 06230 return _left_guarded(); 06231 } 06232 06233 void 06234 GSAExpr::parameters(Expression * e) 06235 { 06236 p_assert(e->op() == COMMA_OP || e->op() == OMEGA_OP, 06237 "GSAExpr:: parameters( ) not an CommaExpr or OmegaExpr"); 06238 _right(e); 06239 } 06240 06241 const Expression & 06242 GSAExpr::parameters_guarded() const 06243 { 06244 return _right_guarded(); 06245 } 06246 06247 Expression & 06248 GSAExpr::parameters_guarded() 06249 { 06250 return _right_guarded(); 06251 } 06252 06253 Boolean 06254 GSAExpr::parameters_valid() const 06255 { 06256 return _right_valid(); 06257 } 06258 06259 int 06260 GSAExpr::structures_OK() const 06261 { 06262 cerr << "GSAExpr::structures_OK() not implemented"; 06263 return True; 06264 } 06265 06266 int 06267 GSAExpr::exchange_expr( VDL & vdl ) 06268 { 06269 int index = vdl.look_up_expr( *this ); 06270 06271 if (index >= 0) 06272 return index; 06273 06274 index = Expression::exchange_expr( vdl ); 06275 06276 BinRep *b = CASTAWAY(BinRep *) vdl.data_ref(); 06277 06278 Set<BinRep> & S = b->find_ref( "expression" )->to_tuple()[index-1].to_set(); 06279 06280 BinRep *br = new BinRep( new List<BinRep> ); 06281 br->to_tuple().ins_last(new BinRep( "op" )); 06282 br->to_tuple().ins_last(new BinRep( "GSA_EXPR" )); 06283 S.ins( br ); 06284 06285 return index; 06286 } 06287 06288 void 06289 GSAExpr::convert(BinRep & NOTUSED(exprSet), Symtab & NOTUSED(symtab)) 06290 { 06291 p_abort("GSAExpr::convert() not implemented."); 06292 } 06293 06294 void 06295 GSAExpr::print_debug(ostream & o, Boolean NOTUSED(debug)) const 06296 { 06297 switch (op()) { 06298 case ALPHA_OP: o << "ALPHA"; break; 06299 case GAMMA_OP: o << "GAMMA"; break; 06300 case MU_OP: o << "MU"; break; 06301 case THETA_OP: o << "THETA"; break; 06302 case ETA_OP: o << "ETA"; break; 06303 default: break; 06304 } 06305 06306 o << "("; 06307 06308 if (_left_valid() && _left_guarded().op() != OMEGA_OP) { 06309 print_prec(op(), &_left_guarded(), o); 06310 o << ", "; 06311 } 06312 06313 print_prec(op(), (_right_valid() ? &_right_guarded() : 0), o); 06314 o << ")"; 06315 } 06316 06317 //----------------------------------------------------------------------------- 06318 /// RealConstExpr code: 06319 /// 06320 06321 RealConstExpr::~RealConstExpr() 06322 { 06323 /// ... nothing to do 06324 } 06325 06326 RealConstExpr & 06327 RealConstExpr::operator = (const RealConstExpr & e) 06328 { 06329 StringExpr::operator = (e); 06330 06331 return *this; 06332 } 06333 06334 Expression * 06335 RealConstExpr::clone() const 06336 { 06337 return new RealConstExpr(*this); 06338 } 06339 06340 int 06341 RealConstExpr::structures_OK() const 06342 { 06343 cerr << "RealConstExpr::structures_OK() not implemented"; 06344 return True; 06345 } 06346 06347 int 06348 RealConstExpr::exchange_expr( VDL & vdl ) 06349 { 06350 int index = vdl.look_up_expr( *this ); 06351 06352 if (index >= 0) 06353 return index; 06354 06355 index = Expression::exchange_expr( vdl ); 06356 06357 BinRep *b = CASTAWAY(BinRep *) vdl.data_ref(); 06358 06359 Set<BinRep> & S = b->find_ref( "expression" )->to_tuple()[index-1].to_set(); 06360 06361 BinRep *br = new BinRep( new List<BinRep> ); 06362 br->to_tuple().ins_last(new BinRep( "op" )); 06363 br->to_tuple().ins_last(new BinRep( "REAL_CONSTANT" )); 06364 S.ins( br ); 06365 06366 br = new BinRep( new List<BinRep> ); 06367 br->to_tuple().ins_last(new BinRep( "data" )); 06368 br->to_tuple().ins_last(new BinRep( this->data_ref() )); 06369 S.ins( br ); 06370 06371 return index; 06372 } 06373 06374 void 06375 RealConstExpr::convert(BinRep & exprSet, Symtab & NOTUSED(symtab)) 06376 { 06377 String s; 06378 BinRep second; /// ... The second argument of tuple pairs 06379 06380 empty_overflow(); 06381 06382 for (Iterator<BinRep> expr_iter = exprSet.to_set(); 06383 expr_iter.valid(); ++expr_iter) { 06384 String field; 06385 06386 expr_iter.current()[0].to_string(field); 06387 second = expr_iter.current()[1]; 06388 06389 if (field == "type") { 06390 p_assert( second.is_string(), 06391 "RealConstExpr: type field doesn't contain string" ); 06392 second.to_string(s); 06393 06394 if (s == "REAL") 06395 _type = REAL_TYPE; 06396 else if (s == "DOUBLE PRECISION") 06397 _type = DOUBLE_PRECISION_TYPE; 06398 else { 06399 cerr << "RealConstExpr of unexpected type (" << s << ")\n"; 06400 p_abort("(See above error message)"); 06401 } 06402 } 06403 else if (field == "data") { 06404 p_assert( second.is_string(), "RealConstExpr::convert: " 06405 "'data' field does not contain an string" ); 06406 second.to_string(_data); 06407 } 06408 else if (field != "op" && field != "size") 06409 make_overflow(expr_iter, "RealConstExpr"); 06410 } 06411 } 06412 06413 //----------------------------------------------------------------------------- 06414 /// ReturnStarExpr code: 06415 /// 06416 06417 ReturnStarExpr::~ReturnStarExpr() 06418 { 06419 /// ... nothing to do 06420 } 06421 06422 Expression * 06423 ReturnStarExpr::clone() const 06424 { 06425 return new ReturnStarExpr(*this); 06426 } 06427 06428 ReturnStarExpr & 06429 ReturnStarExpr::operator = (const ReturnStarExpr & e) 06430 { 06431 UnaryExpr::operator = (e); 06432 return *this; 06433 } 06434 06435 int 06436 ReturnStarExpr::structures_OK() const 06437 { 06438 cerr << "ReturnStar::structures_OK() not implemented"; 06439 return True; 06440 } 06441 06442 int 06443 ReturnStarExpr::exchange_expr( VDL & vdl ) 06444 { 06445 int< |