summaryrefslogtreecommitdiffstats
path: root/elaborate.cxx
diff options
context:
space:
mode:
authorfche <fche>2005-06-02 19:43:55 +0000
committerfche <fche>2005-06-02 19:43:55 +0000
commit69c68955b910a9f284fa25b9ebb30eff5c040e0b (patch)
tree3fa502458891d0b54150d678368f7a2dee18fa0f /elaborate.cxx
parentf37b5c92191dd81aad57ade2899a4999099a3e35 (diff)
downloadsystemtap-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.cxx83
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)
{
}