diff options
author | fche <fche> | 2005-06-02 19:43:55 +0000 |
---|---|---|
committer | fche <fche> | 2005-06-02 19:43:55 +0000 |
commit | 69c68955b910a9f284fa25b9ebb30eff5c040e0b (patch) | |
tree | 3fa502458891d0b54150d678368f7a2dee18fa0f /elaborate.cxx | |
parent | f37b5c92191dd81aad57ade2899a4999099a3e35 (diff) | |
download | systemtap-steved-69c68955b910a9f284fa25b9ebb30eff5c040e0b.tar.gz systemtap-steved-69c68955b910a9f284fa25b9ebb30eff5c040e0b.tar.xz systemtap-steved-69c68955b910a9f284fa25b9ebb30eff5c040e0b.zip |
2005-06-02 Frank Ch. Eigler <fche@redhat.com>
Parse foreach construct. Added fuller copyright notices throughout.
* staptree.h (foreach_loop): New tree node type.
* staptree.cxx: Print it, visit it, love it, leave it.
* parse.cxx: Parse it.
(parse_stmt_block): Don't require ";" separators between statements.
(parse_array_in): Use [] as index group operator instead of ().
* elaborate.cxx (visit_foreach_loop): New code.
* translate.cxx: Slightly tighten errorcount/actioncount handling.
* main.cxx: Accept "-" as script file name standing for stdin.
(visit_arrayindex): Switch to simpler set_arity call.
* configure.ac: Generate DATE macro.
* Makefile.in, configure, config.in: Regenerated.
* testsuite/*: New/updated tests for syntax changes, foreach ().
Diffstat (limited to 'elaborate.cxx')
-rw-r--r-- | elaborate.cxx | 83 |
1 files changed, 72 insertions, 11 deletions
diff --git a/elaborate.cxx b/elaborate.cxx index 02c81a2d..7a6c2359 100644 --- a/elaborate.cxx +++ b/elaborate.cxx @@ -1,7 +1,10 @@ // elaboration functions -// Copyright 2005 Red Hat Inc. -// GPL - +// Copyright (C) 2005 Red Hat Inc. +// +// This file is part of systemtap, and is free software. You can +// redistribute it and/or modify it under the terms of the GNU General +// Public License (GPL); either version 2, or (at your option) any +// later version. #include "config.h" #include "elaborate.h" @@ -201,6 +204,25 @@ symresolution_info::visit_block (block* e) void +symresolution_info::visit_foreach_loop (foreach_loop* e) +{ + for (unsigned i=0; i<e->indexes.size(); i++) + e->indexes[i]->visit (this); + + if (e->base_referent) + return; + + vardecl* d = find_array (e->base, e->indexes.size ()); + if (d) + e->base_referent = d; + else + throw semantic_error ("unresolved global array " + e->base, e->tok); + + e->block->visit (this); +} + + +void symresolution_info::visit_symbol (symbol* e) { if (e->referent) @@ -773,14 +795,10 @@ typeresolution_info::visit_arrayindex (arrayindex* e) resolve_2types (e, e->referent, this, t); // now resolve the array indexes - if (e->referent->index_types.size() == 0) - { - // redesignate referent as array - e->referent->index_types.resize (e->indexes.size()); - for (unsigned i=0; i<e->indexes.size(); i++) - e->referent->index_types[i] = pe_unknown; - // NB: we "fall through" to for loop - } + + // if (e->referent->index_types.size() == 0) + // // redesignate referent as array + // e->referent->set_arity (e->indexes.size ()); if (e->indexes.size() != e->referent->index_types.size()) unresolved (e->tok); // symbol resolution should prevent this @@ -904,6 +922,49 @@ typeresolution_info::visit_for_loop (for_loop* e) void +typeresolution_info::visit_foreach_loop (foreach_loop* e) +{ + // See also visit_arrayindex. + // This is different in that, being a statement, we can't assign + // a type to the outer array, only propagate to/from the indexes + + // if (e->referent->index_types.size() == 0) + // // redesignate referent as array + // e->referent->set_arity (e->indexes.size ()); + + if (e->indexes.size() != e->base_referent->index_types.size()) + unresolved (e->tok); // symbol resolution should prevent this + else for (unsigned i=0; i<e->indexes.size(); i++) + { + expression* ee = e->indexes[i]; + exp_type& ft = e->base_referent->index_types [i]; + t = ft; + ee->visit (this); + exp_type at = ee->type; + + if ((at == pe_string || at == pe_long) && ft == pe_unknown) + { + // propagate to formal type + ft = at; + resolved (e->base_referent->tok, ft); + // uses array decl as there is no token for "formal type" + } + if (at == pe_stats) + invalid (ee->tok, at); + if (ft == pe_stats) + invalid (ee->tok, ft); + if (at != pe_unknown && ft != pe_unknown && ft != at) + mismatch (e->tok, at, ft); + if (at == pe_unknown) + unresolved (ee->tok); + } + + t = pe_unknown; + e->block->visit (this); +} + + +void typeresolution_info::visit_null_statement (null_statement* e) { } |