changeset 2388:4be11abb8d8c

[project @ 1996-10-12 18:53:51 by jwe]
author jwe
date Sat, 12 Oct 1996 18:54:13 +0000
parents be4616e36133
children 3db75e5cdf7c
files src/pt-exp-base.cc src/pt-exp-base.h src/pt-exp.cc src/pt-exp.h
diffstat 4 files changed, 442 insertions(+), 264 deletions(-) [+]
line wrap: on
line diff
--- a/src/pt-exp-base.cc
+++ b/src/pt-exp-base.cc
@@ -33,7 +33,7 @@
 
 #include "error.h"
 #include "pager.h"
-#include "pt-const.h"
+#include "ov.h"
 #include "pt-exp-base.h"
 
 // Expressions.
@@ -48,40 +48,7 @@
   if (! error_state)
     {
       if (t1.is_defined ())
-	{
-	  if (t1.rows () == 0 || t1.columns () == 0)
-	    {
-	      t1 = 0.0;
-	      int flag = Vpropagate_empty_matrices;
-	      if (flag < 0)
-		warning ("%s: empty matrix used in conditional expression",
-			 warn_for);
-	      else if (flag == 0)
-		{
-		  ::error ("%s: empty matrix used in conditional expression",
-			   warn_for);
-		  return expr_value;
-		}
-	    }
-	  else if (! t1.is_scalar_type ())
-	    {
-	      octave_value t2 = t1.all ();
-	      if (! error_state)
-		t1 = t2.all ();
-	    }
-
-	  if (! error_state)
-	    {
-	      if (t1.is_real_scalar ())
-		expr_value = t1.double_value () != 0.0;
-	      else if (t1.is_complex_scalar ())
-		expr_value = t1.complex_value () != 0.0;
-	      else
-		panic_impossible ();
-	    }
-	  else
-	    ::error ("%s: invalid type in conditional expression", warn_for);
-	}
+	return t1.is_true ();
       else
 	::error ("%s: undefined value used in conditional expression",
 		 warn_for);
--- a/src/pt-exp-base.h
+++ b/src/pt-exp-base.h
@@ -44,35 +44,8 @@
       assignment,
       simple_assignment,
       multi_assignment,
-      add,
-      subtract,
-      multiply,
-      el_mul,
-      divide,
-      el_div,
-      leftdiv,
-      el_leftdiv,
-      power,
-      elem_pow,
-      cmp_lt,
-      cmp_le,
-      cmp_eq,
-      cmp_ge,
-      cmp_gt,
-      cmp_ne,
-      and_and,
-      or_or,
-      and,
-      or,
-      not,
-      unot,
-      uminus,
-      hermitian,
-      transpose,
       colon,
       index,
-      increment,
-      decrement,
    };
 
   tree_expression (int l = -1, int c = -1, type et = unknown)
@@ -113,8 +86,6 @@
 
   virtual bool is_in_parens (void) { return in_parens; }
 
-  virtual type expression_type (void) { return etype; }
-
   virtual void mark_for_possible_ans_assign (void);
 
   virtual octave_value eval (bool print) = 0;
--- a/src/pt-exp.cc
+++ b/src/pt-exp.cc
@@ -38,11 +38,12 @@
 #include "input.h"
 #include "oct-obj.h"
 #include "pager.h"
-#include "pt-const.h"
+#include "ov.h"
 #include "pt-exp.h"
 #include "pt-fvc.h"
 #include "pt-misc.h"
 #include "pt-mvr.h"
+#include "pt-pr-code.h"
 #include "pt-walk.h"
 #include "utils.h"
 
@@ -69,7 +70,22 @@
 
   if (id)
     {
-      id->bump_value (etype);
+      switch (etype)
+	{
+	case increment:
+	  id->increment ();
+	  break;
+
+	case decrement:
+	  id->decrement ();
+	  break;
+
+	default:
+	  error ("prefix operator %d not implemented", etype);
+	  break;
+	}
+
+
       if (error_state)
 	eval_error ();
       else
@@ -92,11 +108,11 @@
   static char *op;
   switch (etype)
     {
-    case tree_expression::increment:
+    case increment:
       op = "++";
       break;
 
-    case tree_expression::decrement:
+    case decrement:
       op = "--";
       break;
 
@@ -143,7 +159,22 @@
   if (id)
     {
       retval = id->eval (print);
-      id->bump_value (etype);
+
+      switch (etype)
+	{
+	case increment:
+	  id->increment ();
+	  break;
+
+	case decrement:
+	  id->decrement ();
+	  break;
+
+	default:
+	  error ("postfix operator %d not implemented", etype);
+	  break;
+	}
+
       if (error_state)
 	{
 	  retval = octave_value ();
@@ -160,11 +191,11 @@
   static char *op;
   switch (etype)
     {
-    case tree_expression::increment:
+    case increment:
       op = "++";
       break;
 
-    case tree_expression::decrement:
+    case decrement:
       op = "--";
       break;
 
@@ -198,38 +229,48 @@
 octave_value
 tree_unary_expression::eval (bool /* print */)
 {
-  if (error_state)
-    return octave_value ();
-
   octave_value retval;
 
-  switch (etype)
+  if (error_state)
+    return retval;
+
+  if (op)
     {
-    case tree_expression::not:
-    case tree_expression::uminus:
-    case tree_expression::hermitian:
-    case tree_expression::transpose:
-      if (op)
+      octave_value u = op->eval (false);
+
+      if (error_state)
+	eval_error ();
+      else if (u.is_defined ())
 	{
-	  octave_value u = op->eval (false);
+	  switch (etype)
+	    {
+	    case not:
+	      retval = u.not ();
+	      break;
+
+	    case uminus:
+	      retval = u.uminus ();
+	      break;
+
+	    case transpose:
+	      retval = u.transpose ();
+	      break;
+
+	    case hermitian:
+	      retval = u.hermitian ();
+	      break;
+
+	    default:
+	      ::error ("unary operator %d not implemented", etype);
+	      break;
+	    }
+
 	  if (error_state)
-	    eval_error ();
-	  else if (u.is_defined ())
 	    {
-	      retval = do_unary_op (u, etype);
-	      if (error_state)
-		{
-		  retval = octave_value ();
-		  if (error_state)
-		    eval_error ();
-		}
+	      retval = octave_value ();
+	      eval_error ();
 	    }
 	}
-      break;
-
-    default:
-      ::error ("unary operator %d not implemented", etype);
-      break;
     }
 
   return retval;
@@ -241,20 +282,20 @@
   static char *op;
   switch (etype)
     {
-    case tree_expression::not:
+    case not:
       op = "!";
       break;
 
-    case tree_expression::uminus:
+    case uminus:
       op = "-";
       break;
 
-    case tree_expression::hermitian:
-      op = "'";
+    case transpose:
+      op = ".'";
       break;
 
-    case tree_expression::transpose:
-      op = ".'";
+    case hermitian:
+      op = "'";
       break;
 
     default:
@@ -287,118 +328,122 @@
 octave_value
 tree_binary_expression::eval (bool /* print */)
 {
-  if (error_state)
-    return octave_value ();
-
   octave_value retval;
 
-  switch (etype)
+  if (error_state)
+    return retval;
+
+  if (op_lhs)
     {
-    case tree_expression::add:
-    case tree_expression::subtract:
-    case tree_expression::multiply:
-    case tree_expression::el_mul:
-    case tree_expression::divide:
-    case tree_expression::el_div:
-    case tree_expression::leftdiv:
-    case tree_expression::el_leftdiv:
-    case tree_expression::power:
-    case tree_expression::elem_pow:
-    case tree_expression::cmp_lt:
-    case tree_expression::cmp_le:
-    case tree_expression::cmp_eq:
-    case tree_expression::cmp_ge:
-    case tree_expression::cmp_gt:
-    case tree_expression::cmp_ne:
-    case tree_expression::and:
-    case tree_expression::or:
-      if (op_lhs)
+      octave_value a = op_lhs->eval (false);
+
+      if (error_state)
+	eval_error ();
+      else if (a.is_defined () && op_rhs)
 	{
-	  octave_value a = op_lhs->eval (false);
+	  octave_value b = op_rhs->eval (false);
+
 	  if (error_state)
 	    eval_error ();
-	  else if (a.is_defined () && op_rhs)
+	  else if (b.is_defined ())
 	    {
-	      octave_value b = op_rhs->eval (false);
-	      if (error_state)
-		eval_error ();
-	      else if (b.is_defined ())
+	      octave_value::binary_op op = octave_value::unknown_binary_op;
+
+	      switch (etype)
 		{
-		  retval = do_binary_op (a, b, etype);
-		  if (error_state)
-		    {
-		      retval = octave_value ();
-		      if (error_state)
-			eval_error ();
-		    }
+		case add:
+		  op = octave_value::add;
+		  break;
+
+		case subtract:
+		  op = octave_value::sub;
+		  break;
+
+		case multiply:
+		  op = octave_value::mul;
+		  break;
+
+		case el_mul:
+		  op = octave_value::el_mul;
+		  break;
+
+		case divide:
+		  op = octave_value::div;
+		  break;
+
+		case el_div:
+		  op = octave_value::el_div;
+		  break;
+
+		case leftdiv:
+		  op = octave_value::ldiv;
+		  break;
+
+		case el_leftdiv:
+		  op = octave_value::el_ldiv;
+		  break;
+
+		case power:
+		  op = octave_value::pow;
+		  break;
+
+		case elem_pow:
+		  op = octave_value::el_pow;
+		  break;
+
+		case cmp_lt:
+		  op = octave_value::lt;
+		  break;
+
+		case cmp_le:
+		  op = octave_value::le;
+		  break;
+
+		case cmp_eq:
+		  op = octave_value::eq;
+		  break;
+
+		case cmp_ge:
+		  op = octave_value::ge;
+		  break;
+
+		case cmp_gt:
+		  op = octave_value::gt;
+		  break;
+
+		case cmp_ne:
+		  op = octave_value::ne;
+		  break;
+
+		case and:
+		  op = octave_value::el_and;
+		  break;
+
+		case or:
+		  op = octave_value::el_or;
+		  break;
+
+		default:
+		  ::error ("binary operator %d not implemented", etype);
+		  break;
+		}
+
+	      if (! error_state)
+		retval = ::do_binary_op (op, a, b);
+	      else
+		{
+		  retval = octave_value ();
+		  eval_error ();
 		}
 	    }
+	  else
+	    eval_error ();
 	}
-      break;
-
-    case tree_expression::and_and:
-    case tree_expression::or_or:
-      {
-	bool result = false;
-	if (op_lhs)
-	  {
-	    octave_value a = op_lhs->eval (false);
-	    if (error_state)
-	      {
-		eval_error ();
-		break;
-	      }
-
-	    bool a_true = a.is_true ();
-	    if (error_state)
-	      {
-		eval_error ();
-		break;
-	      }
-
-	    if (a_true)
-	      {
-		if (etype == tree_expression::or_or)
-		  {
-		    result = true;
-		    goto done;
-		  }
-	      }
-	    else
-	      {
-		if (etype == tree_expression::and_and)
-		  {
-		    result = false;
-		    goto done;
-		  }
-	      }
-
-	    if (op_rhs)
-	      {
-		octave_value b = op_rhs->eval (false);
-		if (error_state)
-		  {
-		    eval_error ();
-		    break;
-		  }
-
-		result = b.is_true ();
-		if (error_state)
-		  {
-		    eval_error ();
-		    break;
-		  }
-	      }
-	  }
-      done:
-	retval = octave_value ((double) result);
-      }
-      break;
-
-    default:
-      ::error ("binary operator %d not implemented", etype);
-      break;
+      else
+	eval_error ();
     }
+  else
+    eval_error ();
 
   return retval;
 }
@@ -409,83 +454,75 @@
   static char *op;
   switch (etype)
     {
-    case tree_expression::add:
+    case add:
       op = "+";
       break;
 
-    case tree_expression::subtract:
+    case subtract:
       op = "-";
       break;
 
-    case tree_expression::multiply:
+    case multiply:
       op = "*";
       break;
 
-    case tree_expression::el_mul:
+    case el_mul:
       op = ".*";
       break;
 
-    case tree_expression::divide:
+    case divide:
       op = "/";
       break;
 
-    case tree_expression::el_div:
+    case el_div:
       op = "./";
       break;
 
-    case tree_expression::leftdiv:
+    case leftdiv:
       op = "\\";
       break;
 
-    case tree_expression::el_leftdiv:
+    case el_leftdiv:
       op = ".\\";
       break;
 
-    case tree_expression::power:
+    case power:
       op = "^";
       break;
 
-    case tree_expression::elem_pow:
+    case elem_pow:
       op = ".^";
       break;
 
-    case tree_expression::cmp_lt:
+    case cmp_lt:
       op = "<";
       break;
 
-    case tree_expression::cmp_le:
+    case cmp_le:
       op = "<=";
       break;
 
-    case tree_expression::cmp_eq:
+    case cmp_eq:
       op = "==";
       break;
 
-    case tree_expression::cmp_ge:
+    case cmp_ge:
       op = ">=";
       break;
 
-    case tree_expression::cmp_gt:
+    case cmp_gt:
       op = ">";
       break;
 
-    case tree_expression::cmp_ne:
+    case cmp_ne:
       op = "!=";
       break;
 
-    case tree_expression::and_and:
-      op = "&&";
-      break;
-
-    case tree_expression::or_or:
-      op = "||";
-      break;
-
-    case tree_expression::and:
+    case and:
       op = "&";
       break;
 
-    case tree_expression::or:
+    case or:
       op = "|";
       break;
 
@@ -504,7 +541,7 @@
       char *op = oper ();
 
       ::error ("evaluating binary operator `%s' near line %d, column %d",
-	     op, line (), column ());
+	       op, line (), column ());
     }
 }
 
@@ -514,6 +551,97 @@
   tw.visit_binary_expression (*this);
 }
 
+// Boolean expressions.
+ 
+octave_value
+tree_boolean_expression::eval (bool /* print */)
+{
+  octave_value retval;
+
+  if (error_state)
+    return retval;
+
+  bool result = false;
+
+  if (op_lhs)
+    {
+      octave_value a = op_lhs->eval (false);
+
+      if (error_state)
+	eval_error ();
+      else
+	{
+	  bool a_true = a.is_true ();
+
+	  if (error_state)
+	    eval_error ();
+	  else
+	    {
+	      if (a_true)
+		{
+		  if (etype == or)
+		    {
+		      result = true;
+		      goto done;
+		    }
+		}
+	      else
+		{
+		  if (etype == and)
+		    goto done;
+		}
+
+	      if (op_rhs)
+		{
+		  octave_value b = op_rhs->eval (false);
+
+		  if (error_state)
+		    eval_error ();
+		  else
+		    {
+		      result = b.is_true ();
+
+		      if (error_state)
+			eval_error ();
+		    }
+		}
+	      else
+		eval_error ();
+
+	    done:
+
+	      if (! error_state)
+		retval = octave_value ((double) result);
+	    }
+	}
+    }
+  else
+    eval_error ();
+
+  return retval;
+}
+
+char *
+tree_boolean_expression::oper (void) const
+{
+  static char *op;
+  switch (etype)
+    {
+    case and:
+      op = "&&";
+      break;
+
+    case or:
+      op = "||";
+      break;
+
+    default:
+      op = "<unknown>";
+      break;
+    }
+  return op;
+}
+
 // Simple assignment expressions.
 
 tree_simple_assignment_expression::tree_simple_assignment_expression
@@ -563,6 +691,11 @@
   return lhs->ident ();
 }
 
+// ??? FIXME ??? -- should this return the value of the RHS instead?
+
+// ??? FIXME ??? -- should octave_variable_reference::assign return
+// the right thing for us to return?
+
 octave_value
 tree_simple_assignment_expression::eval (bool print)
 {
@@ -585,31 +718,43 @@
 	  error ("value on right hand side of assignment is undefined");
 	  eval_error ();
 	}
-      else if (! index)
-	{
-	  retval = lhs->assign (rhs_val);
-	  if (error_state)
-	    eval_error ();
-	}
       else
 	{
-	  // Extract the arguments into a simple vector.
-
-	  octave_value_list args = index->convert_to_const_vector ();
+	  octave_variable_reference ult (lhs);
 
 	  if (error_state)
 	    eval_error ();
 	  else
 	    {
-	      int nargin = args.length ();
+	      if (index)
+		{
+		  // Extract the arguments into a simple vector.
 
-	      if (error_state)
-		eval_error ();
-	      else if (nargin > 0)
-		{
-		  retval = lhs->assign (rhs_val, args);
+		  octave_value_list args = index->convert_to_const_vector ();
+
 		  if (error_state)
 		    eval_error ();
+		  else
+		    {
+		      int nargin = args.length ();
+
+		      if (nargin > 0)
+			{
+			  ult.assign (args, rhs_val);
+
+			  if (error_state)
+			    eval_error ();
+			  else
+			    retval = ult.value ();
+			}
+		      else
+			error ("??? invalid index list ???");
+		    }
+		}
+	      else
+		{
+		  ult.assign (rhs_val);
+		  retval = ult.value ();
 		}
 	    }
 	}
--- a/src/pt-exp.h
+++ b/src/pt-exp.h
@@ -45,12 +45,19 @@
 {
 public:
 
-  tree_prefix_expression (int l = -1, int c = -1)
-    : tree_expression (l, c), id (0) { }
+  enum type
+    {
+      unknown,
+      increment,
+      decrement
+    };
 
-  tree_prefix_expression (tree_identifier *t, tree_expression::type et,
-			  int l = -1, int c = -1)
-    : tree_expression (l, c, et), id (t) { }
+  tree_prefix_expression (int l = -1, int c = -1, type t = unknown)
+    : tree_expression (l, c), id (0), etype (t) { }
+
+  tree_prefix_expression (tree_identifier *i, int l = -1, int c = -1,
+			  type t = unknown)
+    : tree_expression (l, c), id (i), etype (t) { }
 
   ~tree_prefix_expression (void);
 
@@ -71,6 +78,9 @@
 
   // Currently, a prefix expression can only apply to an identifier.
   tree_identifier *id;
+
+  // The type of the expression.
+  type etype;
 };
 
 // Postfix expressions.
@@ -80,12 +90,19 @@
 {
 public:
 
-  tree_postfix_expression (int l = -1, int c = -1)
-    : tree_expression (l, c), id (0) { }
+  enum type
+    {
+      unknown,
+      increment,
+      decrement
+    };
 
-  tree_postfix_expression (tree_identifier *t, tree_expression::type et,
-			   int l = -1, int c = -1)
-    : tree_expression (l, c, et), id (t) { }
+  tree_postfix_expression (int l = -1, int c = -1, type t = unknown)
+    : tree_expression (l, c), id (0), etype (t) { }
+
+  tree_postfix_expression (tree_identifier *i, int l = -1, int c = -1,
+			   type t = unknown)
+    : tree_expression (l, c), id (i), etype (t) { }
 
   ~tree_postfix_expression (void);
 
@@ -103,6 +120,9 @@
 
   // Currently, a prefix expression can only apply to an identifier.
   tree_identifier *id;
+
+  // The type of the expression.
+  type etype;
 };
 
 // Unary expressions.
@@ -112,12 +132,22 @@
 {
 public:
 
-  tree_unary_expression (int l = -1, int c = -1)
-    : tree_expression (l, c), op (0) { }
+  enum type
+    {
+      unknown,
+      not,
+      unot,
+      uminus,
+      hermitian,
+      transpose
+    };
 
-  tree_unary_expression (tree_expression *a, tree_expression::type t,
-			 int l = -1, int c = -1)
-    : tree_expression (l, c, t), op (a) { }
+  tree_unary_expression (int l = -1, int c = -1, type t = unknown)
+    : tree_expression (l, c), op (0), etype (t) { }
+
+  tree_unary_expression (tree_expression *a, int l = -1, int c = -1,
+			 type t = unknown)
+    : tree_expression (l, c), op (a), etype (t) { }
 
   ~tree_unary_expression (void)
     { delete op; }
@@ -128,6 +158,8 @@
 
   char *oper (void) const;
 
+  bool is_prefix_op (void) { return (etype == not || etype == uminus); }
+
   tree_expression *operand (void) { return op; }
 
   void accept (tree_walker& tw);
@@ -136,6 +168,9 @@
 
   // The operand for the expression.
   tree_expression *op;
+
+  // The type of the expression.
+  type etype;
 };
 
 // Binary expressions.
@@ -145,12 +180,35 @@
 {
 public:
 
-  tree_binary_expression (int l = -1, int c = -1)
-    : tree_expression (l, c), op_lhs (0), op_rhs (0) { }
+  enum type
+    {
+      unknown,
+      add,
+      subtract,
+      multiply,
+      el_mul,
+      divide,
+      el_div,
+      leftdiv,
+      el_leftdiv,
+      power,
+      elem_pow,
+      cmp_lt,
+      cmp_le,
+      cmp_eq,
+      cmp_ge,
+      cmp_gt,
+      cmp_ne,
+      and,
+      or
+    };
+
+  tree_binary_expression (int l = -1, int c = -1, type t = unknown)
+    : tree_expression (l, c), op_lhs (0), op_rhs (0), etype (t) { }
 
   tree_binary_expression (tree_expression *a, tree_expression *b,
-			  tree_expression::type t, int l = -1, int c = -1)
-    : tree_expression (l, c, t), op_lhs (a), op_rhs (b) { }
+			  int l = -1, int c = -1, type t = unknown)
+    : tree_expression (l, c), op_lhs (a), op_rhs (b), etype (t) { }
 
   ~tree_binary_expression (void)
     {
@@ -169,11 +227,49 @@
 
   void accept (tree_walker& tw);
 
-private:
+protected:
 
   // The operands for the expression.
   tree_expression *op_lhs;
   tree_expression *op_rhs;
+
+private:
+
+  // The type of the expression.
+  type etype;
+};
+
+// Boolean expressions.
+
+class
+tree_boolean_expression : public tree_binary_expression
+{
+public:
+
+  enum type
+    {
+      unknown,
+      and,
+      or
+    };
+
+  tree_boolean_expression (int l = -1, int c = -1, type t)
+    : tree_binary_expression (l, c), etype (t) { }
+
+  tree_boolean_expression (tree_expression *a, tree_expression *b,
+			   int l = -1, int c = -1, type t = unknown)
+    : tree_binary_expression (a, b, l, c), etype (t) { }
+
+  ~tree_boolean_expression (void) { }
+
+  octave_value eval (bool print);
+
+  char *oper (void) const;
+
+private:
+
+  // The type of the expression.
+  type etype;
 };
 
 // Simple assignment expressions.
@@ -270,7 +366,6 @@
       preserve = plhs;
       ans_ass = ans_assign;
     }
-
 };
 
 // Colon expressions.