summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorfche <fche>2005-03-03 21:24:24 +0000
committerfche <fche>2005-03-03 21:24:24 +0000
commit0054a7eaacba2a7183be67b28e7746ed55a8f6d1 (patch)
treeed5c0db8a2cd3bb85fd9bd24232fe01ef6576a68
parent56099f083d7a68722ace316be4d288d21caabaee (diff)
downloadsystemtap-steved-0054a7eaacba2a7183be67b28e7746ed55a8f6d1.tar.gz
systemtap-steved-0054a7eaacba2a7183be67b28e7746ed55a8f6d1.tar.xz
systemtap-steved-0054a7eaacba2a7183be67b28e7746ed55a8f6d1.zip
2005-03-03 Frank Ch. Eigler <fche@redhat.com>
* parse.cxx (parse_assignment): Assert lvalueness of left operand. * staptree.h (expression): Add is_lvalue member. * staptree.cxx (functioncall::resolve_types): Don't crash on formal-vs-actual argument count mismatch. (*): Add some is_lvalue stub functions. * testsuite/*: Some new tests.
-rw-r--r--ChangeLog10
-rw-r--r--README10
-rw-r--r--parse.cxx2
-rw-r--r--staptree.cxx28
-rw-r--r--staptree.h12
-rwxr-xr-xtestsuite/parseko/three.stp5
-rwxr-xr-xtestsuite/semko/eight.stp5
-rwxr-xr-xtestsuite/semko/five.stp10
-rwxr-xr-xtestsuite/semko/seven.stp6
-rwxr-xr-xtestsuite/semko/six.stp6
-rwxr-xr-xtestsuite/semok/five.stp7
11 files changed, 95 insertions, 6 deletions
diff --git a/ChangeLog b/ChangeLog
index cbc73eb7..a03c482b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2005-03-03 Frank Ch. Eigler <fche@redhat.com>
+
+ * parse.cxx (parse_assignment): Assert lvalueness of left
+ operand.
+ * staptree.h (expression): Add is_lvalue member.
+ * staptree.cxx (functioncall::resolve_types): Don't crash on
+ formal-vs-actual argument count mismatch.
+ (*): Add some is_lvalue stub functions.
+ * testsuite/*: Some new tests.
+
2005-03-01 Frank Ch. Eigler <fche@redhat.com>
* parse.cxx: Implement left-associativity for several types of
diff --git a/README b/README
index 6eff13fe..1bf982b0 100644
--- a/README
+++ b/README
@@ -1,10 +1,12 @@
-systemtap prototype #3
+systemtap prototype #3.1
- demonstrates partial parsing of hypothetical systemtap script
language using hand-written simpe LL(1) recursive-descent parser
and similar little lexer: parse.cxx, parse.h
-- baby grammar examples under testsuite/parseok
-- only "probe" top-level construct is parsed; "global" missing;
+- semantic analysis in stapfile.cxx, driven from semtest.cxx
+- examples under testsuite
+- "probe", "global", "function" top-level constructs parsed
no provider-oriented syntax provided yet
- use autotools-style configure; make; make check
-- to see parse tree dump, use stdin: echo 'SCRIPT FRAGMENT' | ./stap
+- to see parse tree dump, use stdin: echo 'SCRIPT FRAGMENT' | ./parsetest
+- to see type inference results, use stdin: echo 'SCRIPT FRAGMENT' | ./semtest
diff --git a/parse.cxx b/parse.cxx
index 4238f37e..41ec6fef 100644
--- a/parse.cxx
+++ b/parse.cxx
@@ -648,6 +648,8 @@ parser::parse_assignment ()
t->content == "+=" ||
false)) // XXX: add /= etc.
{
+ if (op1->is_lvalue () == 0)
+ throw parse_error ("assignment not to lvalue");
assignment* e = new assignment;
e->left = op1;
e->op = t->content;
diff --git a/staptree.cxx b/staptree.cxx
index 34a1d0d3..8a4fc148 100644
--- a/staptree.cxx
+++ b/staptree.cxx
@@ -753,7 +753,7 @@ functioncall::resolve_types (typeresolution_info& r, exp_type t)
// now resolve the function parameters
if (args.size() != referent->formal_args.size())
r.unresolved (tok);
- for (unsigned i=0; i<args.size(); i++)
+ else for (unsigned i=0; i<args.size(); i++)
{
expression* e = args[i];
exp_type& ft = referent->formal_args[i]->type;
@@ -901,3 +901,29 @@ typeresolution_info::resolved (const token* tok, exp_type t)
num_newly_resolved ++;
// cerr << "resolved " << *tok << " type " << t << endl;
}
+
+
+// ------------------------------------------------------------------------
+// semantic processing: lvalue checking
+
+bool
+pre_crement::is_lvalue ()
+{
+ return operand->is_lvalue ();
+}
+
+
+bool
+post_crement::is_lvalue ()
+{
+ return operand->is_lvalue ();
+}
+
+
+bool
+assignment::is_lvalue ()
+{
+ return left->is_lvalue ();
+}
+
+
diff --git a/staptree.h b/staptree.h
index 80bffa7e..a95d9f05 100644
--- a/staptree.h
+++ b/staptree.h
@@ -32,6 +32,7 @@ struct expression
virtual ~expression ();
virtual void resolve_symbols (symresolution_info& r) = 0;
virtual void resolve_types (typeresolution_info& r, exp_type t) = 0;
+ virtual bool is_lvalue () = 0;
};
ostream& operator << (ostream& o, expression& k);
@@ -41,6 +42,7 @@ struct literal: public expression
{
void resolve_symbols (symresolution_info& r);
void resolve_types (typeresolution_info& r, exp_type t);
+ bool is_lvalue () { return false; }
};
@@ -68,6 +70,7 @@ struct binary_expression: public expression
void print (ostream& o);
void resolve_symbols (symresolution_info& r);
void resolve_types (typeresolution_info& r, exp_type t);
+ bool is_lvalue () { return false; }
};
@@ -78,16 +81,19 @@ struct unary_expression: public expression
void print (ostream& o);
void resolve_symbols (symresolution_info& r);
void resolve_types (typeresolution_info& r, exp_type t);
+ bool is_lvalue () { return false; }
};
struct pre_crement: public unary_expression
{
+ bool is_lvalue ();
};
struct post_crement: public unary_expression
{
+ bool is_lvalue ();
void print (ostream& o);
};
@@ -130,11 +136,13 @@ struct ternary_expression: public expression
void print (ostream& o);
void resolve_symbols (symresolution_info& r);
void resolve_types (typeresolution_info& r, exp_type t);
+ bool is_lvalue () { return false; }
};
struct assignment: public binary_expression
{
+ bool is_lvalue ();
};
@@ -147,6 +155,7 @@ struct symbol: public expression
void print (ostream& o);
void resolve_symbols (symresolution_info& r);
void resolve_types (typeresolution_info& r, exp_type t);
+ bool is_lvalue () { return true; }
};
@@ -159,10 +168,10 @@ struct arrayindex: public expression
void print (ostream& o);
void resolve_symbols (symresolution_info& r);
void resolve_types (typeresolution_info& r, exp_type t);
+ bool is_lvalue () { return true; }
};
-
class functiondecl;
struct functioncall: public expression
{
@@ -173,6 +182,7 @@ struct functioncall: public expression
void print (ostream& o);
void resolve_symbols (symresolution_info& r);
void resolve_types (typeresolution_info& r, exp_type t);
+ bool is_lvalue () { return false; }
};
diff --git a/testsuite/parseko/three.stp b/testsuite/parseko/three.stp
new file mode 100755
index 00000000..4db7dd3f
--- /dev/null
+++ b/testsuite/parseko/three.stp
@@ -0,0 +1,5 @@
+#! semtest
+
+probe foo {
+ 1 + 2 = 3; # bad lvalue
+}
diff --git a/testsuite/semko/eight.stp b/testsuite/semko/eight.stp
new file mode 100755
index 00000000..1bcb344a
--- /dev/null
+++ b/testsuite/semko/eight.stp
@@ -0,0 +1,5 @@
+#! semtest
+
+probe foo {
+ stats << "string" # stats only collect numbers
+}
diff --git a/testsuite/semko/five.stp b/testsuite/semko/five.stp
new file mode 100755
index 00000000..6887fced
--- /dev/null
+++ b/testsuite/semko/five.stp
@@ -0,0 +1,10 @@
+#! semtest
+
+function bar ()
+{
+ return 0
+}
+
+probe foo {
+ bar (1, 2) # arg count mismatch
+}
diff --git a/testsuite/semko/seven.stp b/testsuite/semko/seven.stp
new file mode 100755
index 00000000..7d987f77
--- /dev/null
+++ b/testsuite/semko/seven.stp
@@ -0,0 +1,6 @@
+#! semtest
+
+probe foo {
+ baz[1] = 4;
+ baz["1"] = 5; # inconsistent index types
+}
diff --git a/testsuite/semko/six.stp b/testsuite/semko/six.stp
new file mode 100755
index 00000000..aa7d10d7
--- /dev/null
+++ b/testsuite/semko/six.stp
@@ -0,0 +1,6 @@
+#! semtest
+
+probe foo {
+ bar[1] = 2;
+ bar[1, 2] = 3; # inconsistent array dimensions
+}
diff --git a/testsuite/semok/five.stp b/testsuite/semok/five.stp
new file mode 100755
index 00000000..c8b59e73
--- /dev/null
+++ b/testsuite/semok/five.stp
@@ -0,0 +1,7 @@
+#! parsetest
+
+probe foo
+{
+ array[1] = array[2] = 3;
+ statvar << value << 4;
+}