diff options
author | fche <fche> | 2005-06-03 21:01:35 +0000 |
---|---|---|
committer | fche <fche> | 2005-06-03 21:01:35 +0000 |
commit | 553d27a587615e4b242a89bf1a7af93b71f050f0 (patch) | |
tree | 1ca4e5d35908208e5d533bb32e22b6aa567221b8 /elaborate.cxx | |
parent | 63a7c90e365874972925e886ed50941f5620bdfe (diff) | |
download | systemtap-steved-553d27a587615e4b242a89bf1a7af93b71f050f0.tar.gz systemtap-steved-553d27a587615e4b242a89bf1a7af93b71f050f0.tar.xz systemtap-steved-553d27a587615e4b242a89bf1a7af93b71f050f0.zip |
2005-06-03 Frank Ch. Eigler <fche@redhat.com>
* TODO: Removed entries already represented in bugzilla.
* elaborate.cxx: Rewrite type inference for several operators.
* main.cxx (main): For -p2 runs, print types of function/probe locals.
* parse.cxx (scan): Identify more two-character operators.
(parse_comparison): Support the whole suite.
* translate.cxx (visit_unary_expression, logical_or_expr,
logical_and_expr, comparison,ternary_expression): New support.
* testsuite/parseok/semok.stp: Clever new test.
* testsuite/transok/four.stp: New test.
* testsuite/*: Some tweaked tests for syntax changes.
Diffstat (limited to 'elaborate.cxx')
-rw-r--r-- | elaborate.cxx | 157 |
1 files changed, 89 insertions, 68 deletions
diff --git a/elaborate.cxx b/elaborate.cxx index 7a6c2359..e733132f 100644 --- a/elaborate.cxx +++ b/elaborate.cxx @@ -546,14 +546,43 @@ typeresolution_info::visit_logical_and_expr (logical_and_expr *e) void typeresolution_info::visit_comparison (comparison *e) { - visit_binary_expression (e); + if (t == pe_stats || t == pe_string) + invalid (e->tok, t); + + t = (e->right->type != pe_unknown) ? e->right->type : pe_unknown; + e->left->visit (this); + t = (e->left->type != pe_unknown) ? e->left->type : pe_unknown; + e->right->visit (this); + + if (e->left->type != pe_unknown && + e->right->type != pe_unknown && + e->left->type != e->right->type) + mismatch (e->tok, e->left->type, e->right->type); + + if (e->type == pe_unknown) + { + e->type = pe_long; + resolved (e->tok, e->type); + } } void typeresolution_info::visit_concatenation (concatenation *e) { - visit_binary_expression (e); + if (t != pe_unknown && t != pe_string) + invalid (e->tok, t); + + t = pe_string; + e->left->visit (this); + t = pe_string; + e->right->visit (this); + + if (e->type == pe_unknown) + { + e->type = pe_string; + resolved (e->tok, e->type); + } } @@ -567,89 +596,86 @@ typeresolution_info::visit_exponentiation (exponentiation *e) void typeresolution_info::visit_assignment (assignment *e) { - visit_binary_expression (e); -} - + if (t == pe_stats) + invalid (e->tok, t); -void -typeresolution_info::visit_binary_expression (binary_expression* e) -{ if (e->op == "<<<") // stats aggregation { - exp_type t1 = t; + if (t == pe_string) + invalid (e->tok, t); + t = pe_stats; e->left->visit (this); t = pe_long; e->right->visit (this); - if (t1 == pe_stats || t1 == pe_string) - invalid (e->tok, t1); - else if (e->type == pe_unknown) + if (e->type == pe_unknown) { e->type = pe_long; resolved (e->tok, e->type); } } - else if (e->op == ".") // string concatenation + else if (e->op == "+=" || // numeric only + false) { - exp_type t1 = t; - t = pe_string; - e->left->visit (this); - t = pe_string; - e->right->visit (this); - if (t1 == pe_long || t1 == pe_stats) - mismatch (e->tok, t1, pe_string); - else if (e->type == pe_unknown) - { - e->type = pe_string; - resolved (e->tok, e->type); - } - } - else if (e->op == "==" - || false) // XXX: other comparison operators - { - exp_type t1 = t; - t = pe_unknown; - e->left->visit (this); - t = pe_unknown; - e->right->visit (this); - if (t1 == pe_string || t1 == pe_stats) - mismatch (e->tok, t1, pe_long); - else if (e->type == pe_unknown) - { - e->type = pe_long; - resolved (e->tok, e->type); - } + visit_binary_expression (e); } - else // general arithmetic operators? + else // overloaded for string & numeric operands { - // propagate e->type downward + // logic similar to ternary_expression exp_type sub_type = t; - if ((sub_type == pe_unknown) && (e->type != pe_unknown)) + + // Infer types across the l/r values + if (sub_type == pe_unknown && e->type != pe_unknown) sub_type = e->type; - t = sub_type; + + t = (sub_type != pe_unknown) ? sub_type : + (e->right->type != pe_unknown) ? e->right->type : + pe_unknown; e->left->visit (this); - t = sub_type; + t = (sub_type != pe_unknown) ? sub_type : + (e->left->type != pe_unknown) ? e->left->type : + pe_unknown; e->right->visit (this); - - if ((sub_type == pe_unknown) && (e->type != pe_unknown)) - ; // already resolved - else if ((sub_type != pe_unknown) && (e->type == pe_unknown)) + + if ((sub_type != pe_unknown) && (e->type == pe_unknown)) { e->type = sub_type; resolved (e->tok, e->type); } - else if ((sub_type == pe_unknown) && (e->left->type != pe_unknown)) + if ((sub_type == pe_unknown) && (e->left->type != pe_unknown)) { e->type = e->left->type; resolved (e->tok, e->type); } - else if ((sub_type == pe_unknown) && (e->right->type != pe_unknown)) - { - e->type = e->right->type; - resolved (e->tok, e->type); - } - else if (e->type != sub_type) - mismatch (e->tok, sub_type, e->type); + + if (e->left->type != pe_unknown && + e->right->type != pe_unknown && + e->left->type != e->right->type) + mismatch (e->tok, e->left->type, e->right->type); + } +} + + +void +typeresolution_info::visit_binary_expression (binary_expression* e) +{ + if (t == pe_stats || t == pe_string) + invalid (e->tok, t); + + t = pe_long; + e->left->visit (this); + t = pe_long; + e->right->visit (this); + + if (e->left->type != pe_unknown && + e->right->type != pe_unknown && + e->left->type != e->right->type) + mismatch (e->tok, e->left->type, e->right->type); + + if (e->type == pe_unknown) + { + e->type = pe_long; + resolved (e->tok, e->type); } } @@ -671,16 +697,13 @@ typeresolution_info::visit_post_crement (post_crement *e) void typeresolution_info::visit_unary_expression (unary_expression* e) { - // all unary operators only work on numerics - exp_type t1 = t; + if (t == pe_stats || t == pe_string) + invalid (e->tok, t); + t = pe_long; e->operand->visit (this); - if (t1 == pe_unknown && e->type != pe_unknown) - ; // already resolved - else if (t1 == pe_string || t1 == pe_stats) - mismatch (e->tok, t1, pe_long); - else if (e->type == pe_unknown) + if (e->type == pe_unknown) { e->type = pe_long; resolved (e->tok, e->type); @@ -688,7 +711,6 @@ typeresolution_info::visit_unary_expression (unary_expression* e) } - void typeresolution_info::visit_ternary_expression (ternary_expression* e) { @@ -697,8 +719,7 @@ typeresolution_info::visit_ternary_expression (ternary_expression* e) t = pe_long; e->cond->visit (this); - // Match ordinary binary_expression type inference for the true/false - // arms of the ternary expression. + // Infer types across the true/false arms of the ternary expression. if (sub_type == pe_unknown && e->type != pe_unknown) sub_type = e->type; |