summaryrefslogtreecommitdiffstats
path: root/elaborate.cxx
diff options
context:
space:
mode:
authorfche <fche>2005-06-03 21:01:35 +0000
committerfche <fche>2005-06-03 21:01:35 +0000
commit553d27a587615e4b242a89bf1a7af93b71f050f0 (patch)
tree1ca4e5d35908208e5d533bb32e22b6aa567221b8 /elaborate.cxx
parent63a7c90e365874972925e886ed50941f5620bdfe (diff)
downloadsystemtap-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.cxx157
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;