summaryrefslogtreecommitdiffstats
path: root/parse.cxx
diff options
context:
space:
mode:
authorfche <fche>2005-06-05 16:35:28 +0000
committerfche <fche>2005-06-05 16:35:28 +0000
commitf3c26ea55e2f2c1d222312bf75035359c439ed21 (patch)
tree1a58dfcdebe04941002e7e0203f765b619ca9c67 /parse.cxx
parent8846477c222cdae649b02117cc96999b0be6ad40 (diff)
downloadsystemtap-steved-f3c26ea55e2f2c1d222312bf75035359c439ed21.tar.gz
systemtap-steved-f3c26ea55e2f2c1d222312bf75035359c439ed21.tar.xz
systemtap-steved-f3c26ea55e2f2c1d222312bf75035359c439ed21.zip
2005-06-05 Frank Ch. Eigler <fche@elastic.org>
Implement for/next/continue/break/while statements. * staptree.h: Declare new 0-arity statement types. Tweak for_loop. * parse.cxx: Parse them all. * translate.cxx (c_unparser): Maintain break/continue label stack. (visit_for_loop, *_statement): New implementations. * elaborate.*, staptree.cxx: Mechanical changes. * testsuite/parseok/ten.stp, semko/twelve.stp, transko/two.stp, transok/five.stp: New tests.
Diffstat (limited to 'parse.cxx')
-rw-r--r--parse.cxx158
1 files changed, 153 insertions, 5 deletions
diff --git a/parse.cxx b/parse.cxx
index 5595f359..d1c0b954 100644
--- a/parse.cxx
+++ b/parse.cxx
@@ -486,18 +486,23 @@ parser::parse_statement ()
return parse_stmt_block ();
else if (t && t->type == tok_identifier && t->content == "if")
return parse_if_statement ();
- /*
else if (t && t->type == tok_identifier && t->content == "for")
return parse_for_loop ();
- */
else if (t && t->type == tok_identifier && t->content == "foreach")
return parse_foreach_loop ();
else if (t && t->type == tok_identifier && t->content == "return")
return parse_return_statement ();
else if (t && t->type == tok_identifier && t->content == "delete")
return parse_delete_statement ();
- // XXX: other control constructs ("delete", "while", "do",
- // "break", "continue", "exit")
+ else if (t && t->type == tok_identifier && t->content == "while")
+ return parse_while_loop ();
+ else if (t && t->type == tok_identifier && t->content == "break")
+ return parse_break_statement ();
+ else if (t && t->type == tok_identifier && t->content == "continue")
+ return parse_continue_statement ();
+ else if (t && t->type == tok_identifier && t->content == "next")
+ return parse_next_statement ();
+ // XXX: "do/while" statement?
else if (t && (t->type == tok_operator || // expressions are flexible
t->type == tok_identifier ||
t->type == tok_number ||
@@ -746,10 +751,153 @@ parser::parse_delete_statement ()
}
+next_statement*
+parser::parse_next_statement ()
+{
+ const token* t = next ();
+ if (! (t->type == tok_identifier && t->content == "next"))
+ throw parse_error ("expected 'next'");
+ next_statement* s = new next_statement;
+ s->tok = t;
+ return s;
+}
+
+
+break_statement*
+parser::parse_break_statement ()
+{
+ const token* t = next ();
+ if (! (t->type == tok_identifier && t->content == "break"))
+ throw parse_error ("expected 'break'");
+ break_statement* s = new break_statement;
+ s->tok = t;
+ return s;
+}
+
+
+continue_statement*
+parser::parse_continue_statement ()
+{
+ const token* t = next ();
+ if (! (t->type == tok_identifier && t->content == "continue"))
+ throw parse_error ("expected 'continue'");
+ continue_statement* s = new continue_statement;
+ s->tok = t;
+ return s;
+}
+
+
for_loop*
parser::parse_for_loop ()
{
- throw parse_error ("not yet implemented");
+ const token* t = next ();
+ if (! (t->type == tok_identifier && t->content == "for"))
+ throw parse_error ("expected 'for'");
+ for_loop* s = new for_loop;
+ s->tok = t;
+
+ t = next ();
+ if (! (t->type == tok_operator && t->content == "("))
+ throw parse_error ("expected '('");
+
+ // initializer + ";"
+ t = peek ();
+ if (t && t->type == tok_operator && t->content == ";")
+ {
+ literal_number* l = new literal_number(0);
+ expr_statement* es = new expr_statement;
+ es->value = l;
+ s->init = es;
+ es->value->tok = es->tok = next ();
+ }
+ else
+ {
+ s->init = parse_expr_statement ();
+ t = next ();
+ if (! (t->type == tok_operator && t->content == ";"))
+ throw parse_error ("expected ';'");
+ }
+
+ // condition + ";"
+ t = peek ();
+ if (t && t->type == tok_operator && t->content == ";")
+ {
+ literal_number* l = new literal_number(1);
+ s->cond = l;
+ s->cond->tok = next ();
+ }
+ else
+ {
+ s->cond = parse_expression ();
+ t = next ();
+ if (! (t->type == tok_operator && t->content == ";"))
+ throw parse_error ("expected ';'");
+ }
+
+ // increment + ")"
+ t = peek ();
+ if (t && t->type == tok_operator && t->content == ")")
+ {
+ literal_number* l = new literal_number(2);
+ expr_statement* es = new expr_statement;
+ es->value = l;
+ s->incr = es;
+ es->value->tok = es->tok = next ();
+ }
+ else
+ {
+ s->incr = parse_expr_statement ();
+ t = next ();
+ if (! (t->type == tok_operator && t->content == ")"))
+ throw parse_error ("expected ';'");
+ }
+
+ // block
+ s->block = parse_statement ();
+
+ return s;
+}
+
+
+for_loop*
+parser::parse_while_loop ()
+{
+ const token* t = next ();
+ if (! (t->type == tok_identifier && t->content == "while"))
+ throw parse_error ("expected 'while'");
+ for_loop* s = new for_loop;
+ s->tok = t;
+
+ t = next ();
+ if (! (t->type == tok_operator && t->content == "("))
+ throw parse_error ("expected '('");
+
+ // dummy init and incr fields
+ literal_number* l = new literal_number(0);
+ expr_statement* es = new expr_statement;
+ es->value = l;
+ s->init = es;
+ es->value->tok = es->tok = t;
+
+ l = new literal_number(2);
+ es = new expr_statement;
+ es->value = l;
+ s->incr = es;
+ es->value->tok = es->tok = t;
+
+
+ // condition
+ s->cond = parse_expression ();
+
+
+ t = next ();
+ if (! (t->type == tok_operator && t->content == ")"))
+ throw parse_error ("expected ')'");
+
+ // block
+ s->block = parse_statement ();
+
+ return s;
}