changeset 3484:8b1f46ac2b64

[project @ 2000-01-27 23:30:45 by jwe]
author jwe
date Thu, 27 Jan 2000 23:30:48 +0000
parents 1bb6e519a4a2
children e5d5848370c9
files src/ChangeLog src/Makefile.in src/input.cc src/lex.l src/octave.gperf src/parse.y src/pt-loop.cc src/pt-loop.h src/pt-pr-code.cc src/pt-pr-code.h src/pt-walk.h
diffstat 11 files changed, 320 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Wed Jan 26 23:37:11 2000 +0000
+++ b/src/ChangeLog	Thu Jan 27 23:30:48 2000 +0000
@@ -1,3 +1,23 @@
+2000-01-27  John W. Eaton  <jwe@bevo.che.wisc.edu>
+
+	* pt-walk.h (tree_walker::visit_do_while_command): New pure virtual.
+	(tree_walker::visit_do_until_command): Ditto.
+	* pt-pr-code.cc (tree_print_code::visit_do_while_command):
+	New function.
+	(tree_print_code::visit_do_until_command): Ditto.
+	* pt-loop.h (tree_do_while_command): New class.
+	(tree_do_until_command): Ditto.
+	(tree_while_command::expr, tree_while_command::list):
+	Now protected instead of private.
+	* parse.y (make_do_while_command): New function.
+	(make_do_until_command): Ditto.
+	(loop_command): Recognize do-while and do-until statements.
+	(DO, UNTIL): New tokens.
+	* Makefile.in (parse.cc): Expect 13 shift/reduce conflicts.
+
+	* input.cc (match_sans_spaces): Require non-blank part of test
+	string to match standard string exactly.
+
 2000-01-26  John W. Eaton  <jwe@bevo.che.wisc.edu>
 
 	* oct-stream.h (scanf_format_elt::char_class): New struct elt.
--- a/src/Makefile.in	Wed Jan 26 23:37:11 2000 +0000
+++ b/src/Makefile.in	Thu Jan 27 23:30:48 2000 +0000
@@ -437,7 +437,7 @@
 # Special rules -- these files need special things to be defined.
 
 parse.cc : parse.y
-	@echo "expect 11 shift/reduce conflicts"
+	@echo "expect 13 shift/reduce conflicts"
 	$(YACC) $(YFLAGS) $<
 	@$(top_srcdir)/move-if-change y.tab.c $(@F)
 
--- a/src/input.cc	Wed Jan 26 23:37:11 2000 +0000
+++ b/src/input.cc	Thu Jan 27 23:30:48 2000 +0000
@@ -483,7 +483,7 @@
 
       size_t len = end == NPOS ? NPOS : end - beg + 1;
 
-      return test.compare (standard, beg, len) == 0;
+      return (test.substr (beg, len) == standard);
     }
 
   return false;
--- a/src/lex.l	Wed Jan 26 23:37:11 2000 +0000
+++ b/src/lex.l	Thu Jan 27 23:30:48 2000 +0000
@@ -1020,6 +1020,7 @@
 	case otherwise_kw:
 	case return_kw:
 	case static_kw:
+	case until_kw:
 	case unwind_protect_cleanup_kw:
  	  break;
 
@@ -1055,6 +1056,7 @@
 	  yylval.tok_val = new token (token::while_end, l, c);
 	  break;
 
+	case do_kw:
 	case for_kw:
 	case while_kw:
 	  promptflag--;
--- a/src/octave.gperf	Wed Jan 26 23:37:11 2000 +0000
+++ b/src/octave.gperf	Thu Jan 27 23:30:48 2000 +0000
@@ -7,6 +7,7 @@
   case_kw,
   catch_kw,
   continue_kw,
+  do_kw,
   else_kw,
   elseif_kw,
   end_kw,
@@ -31,6 +32,7 @@
   static_kw,
   switch_kw,
   try_kw,
+  until_kw,
   unwind_protect_kw,
   unwind_protect_cleanup_kw,
   while_kw
@@ -44,6 +46,7 @@
 case, CASE, case_kw
 catch, CATCH, catch_kw
 continue, CONTINUE, continue_kw
+do, DO, do_kw
 else, ELSE, else_kw
 elseif, ELSEIF, elseif_kw
 end, END, end_kw
@@ -66,6 +69,7 @@
 static, STATIC, static_kw
 switch, SWITCH, switch_kw
 try, TRY, try_kw
+until, UNTIL, until_kw
 unwind_protect, UNWIND, unwind_protect_kw
 unwind_protect_cleanup, CLEANUP, unwind_protect_cleanup_kw
 while, WHILE, while_kw
--- a/src/parse.y	Wed Jan 26 23:37:11 2000 +0000
+++ b/src/parse.y	Thu Jan 27 23:30:48 2000 +0000
@@ -186,6 +186,16 @@
 make_while_command (token *while_tok, tree_expression *expr,
 		    tree_statement_list *body, token *end_tok);
 
+// Build a do-while command.
+static tree_command *
+make_do_while_command (token *do_tok, tree_statement_list *body,
+		       tree_expression *expr);
+
+// Build a do-until command.
+static tree_command *
+make_do_until_command (token *do_tok, tree_statement_list *body,
+		       tree_expression *expr);
+
 // Build a for command.
 static tree_command *
 make_for_command (token *for_tok, tree_argument_list *lhs,
@@ -351,7 +361,7 @@
 %token <tok_val> END
 %token <tok_val> PLOT
 %token <tok_val> TEXT STYLE AXES_TAG
-%token <tok_val> FOR WHILE
+%token <tok_val> FOR WHILE DO UNTIL
 %token <tok_val> IF ELSEIF ELSE
 %token <tok_val> SWITCH CASE OTHERWISE
 %token <tok_val> BREAK CONTINUE FUNC_RET
@@ -949,6 +959,16 @@
 		    if (! ($$ = make_while_command ($1, $2, $4, $5)))
 		      ABORT_PARSE;
 		  }
+		| DO opt_sep opt_list WHILE expression
+		  {
+		    if (! ($$ = make_do_while_command ($1, $3, $5)))
+		      ABORT_PARSE;
+		  }
+		| DO opt_sep opt_list UNTIL expression
+		  {
+		    if (! ($$ = make_do_until_command ($1, $3, $5)))
+		      ABORT_PARSE;
+		  }
 		| FOR assign_lhs '=' expression opt_sep opt_list END
 		  {
 		    if (! ($$ = make_for_command ($1, $2, $4, $6, $7)))
@@ -2072,6 +2092,48 @@
   return retval;
 }
 
+// Build a do-while command.
+
+static tree_command *
+make_do_while_command (token *do_tok, tree_statement_list *body,
+		       tree_expression *expr)
+{
+  tree_command *retval = 0;
+
+  maybe_warn_assign_as_truth_value (expr);
+
+  // We have to do this because while can also be used to begin a loop.
+  lexer_flags.looping -= 2;
+  promptflag++;
+
+  int l = do_tok->line ();
+  int c = do_tok->column ();
+
+  retval = new tree_do_while_command (expr, body, l, c);
+
+  return retval;
+}
+
+// Build a do-until command.
+
+static tree_command *
+make_do_until_command (token *do_tok, tree_statement_list *body,
+		       tree_expression *expr)
+{
+  tree_command *retval = 0;
+
+  maybe_warn_assign_as_truth_value (expr);
+
+  lexer_flags.looping--;
+
+  int l = do_tok->line ();
+  int c = do_tok->column ();
+
+  retval = new tree_do_until_command (expr, body, l, c);
+
+  return retval;
+}
+
 // Build a for command.
 
 static tree_command *
--- a/src/pt-loop.cc	Wed Jan 26 23:37:11 2000 +0000
+++ b/src/pt-loop.cc	Thu Jan 27 23:30:48 2000 +0000
@@ -115,6 +115,92 @@
   tw.visit_while_command (*this);
 }
 
+// Do-While
+
+void
+tree_do_while_command::eval (void)
+{
+  if (error_state)
+    return;
+
+  if (! expr)
+    panic_impossible ();
+
+  for (;;)
+    {
+      if (list)
+	{
+	  list->eval ();
+
+	  if (error_state)
+	    {
+	      eval_error ();
+	      return;
+	    }
+	}
+
+      if (quit_loop_now () || ! expr->is_logically_true ("do-while"))
+	break;
+    }
+}
+
+void
+tree_do_while_command::eval_error (void)
+{
+  if (error_state > 0)
+    ::error ("evaluating do-while command near line %d, column %d",
+	     line (), column ());
+}
+
+void
+tree_do_while_command::accept (tree_walker& tw)
+{
+  tw.visit_do_while_command (*this);
+}
+
+// Do-Until
+
+void
+tree_do_until_command::eval (void)
+{
+  if (error_state)
+    return;
+
+  if (! expr)
+    panic_impossible ();
+
+  for (;;)
+    {
+      if (list)
+	{
+	  list->eval ();
+
+	  if (error_state)
+	    {
+	      eval_error ();
+	      return;
+	    }
+	}
+
+      if (quit_loop_now () || expr->is_logically_true ("do-until"))
+	break;
+    }
+}
+
+void
+tree_do_until_command::eval_error (void)
+{
+  if (error_state > 0)
+    ::error ("evaluating do-until command near line %d, column %d",
+	     line (), column ());
+}
+
+void
+tree_do_until_command::accept (tree_walker& tw)
+{
+  tw.visit_do_until_command (*this);
+}
+
 // For.
 
 tree_simple_for_command::~tree_simple_for_command (void)
--- a/src/pt-loop.h	Wed Jan 26 23:37:11 2000 +0000
+++ b/src/pt-loop.h	Thu Jan 27 23:30:48 2000 +0000
@@ -67,7 +67,7 @@
 
   void accept (tree_walker& tw);
 
-private:
+protected:
 
   // Expression to test.
   tree_expression *expr;
@@ -75,6 +75,8 @@
   // List of commands to execute.
   tree_statement_list *list;
 
+private:
+
   // No copying!
 
   tree_while_command (const tree_while_command&);
@@ -82,6 +84,74 @@
   tree_while_command& operator = (const tree_while_command&);
 };
 
+// Do-While.
+
+class
+tree_do_while_command : public tree_while_command
+{
+public:
+
+  tree_do_while_command (int l = -1, int c = -1)
+    : tree_while_command (l, c) { }
+
+  tree_do_while_command (tree_expression *e, int l = -1, int c = -1)
+    : tree_while_command (e, l, c) { }
+
+  tree_do_while_command (tree_expression *e, tree_statement_list *lst,
+		      int l = -1, int c = -1)
+    : tree_while_command (e, lst, l, c) { }
+
+  ~tree_do_while_command (void) { }
+
+  void eval (void);
+
+  void eval_error (void);
+
+  void accept (tree_walker& tw);
+
+private:
+
+  // No copying!
+
+  tree_do_while_command (const tree_do_while_command&);
+
+  tree_do_while_command& operator = (const tree_do_while_command&);
+};
+
+// Do-Until.
+
+class
+tree_do_until_command : public tree_while_command
+{
+public:
+
+  tree_do_until_command (int l = -1, int c = -1)
+    : tree_while_command (l, c) { }
+
+  tree_do_until_command (tree_expression *e, int l = -1, int c = -1)
+    : tree_while_command (e, l, c) { }
+
+  tree_do_until_command (tree_expression *e, tree_statement_list *lst,
+		      int l = -1, int c = -1)
+    : tree_while_command (e, lst, l, c) { }
+
+  ~tree_do_until_command (void) { }
+
+  void eval (void);
+
+  void eval_error (void);
+
+  void accept (tree_walker& tw);
+
+private:
+
+  // No copying!
+
+  tree_do_until_command (const tree_do_until_command&);
+
+  tree_do_until_command& operator = (const tree_do_until_command&);
+};
+
 // For.
 
 class
--- a/src/pt-pr-code.cc	Wed Jan 26 23:37:11 2000 +0000
+++ b/src/pt-pr-code.cc	Thu Jan 27 23:30:48 2000 +0000
@@ -1101,6 +1101,66 @@
   os << "endwhile";
 }
 
+void
+tree_print_code::visit_do_while_command (tree_do_while_command& cmd)
+{
+  indent ();
+
+  os << "do";
+
+  newline ();
+
+  tree_statement_list *list = cmd.body ();
+
+  if (list)
+    {
+      increment_indent_level ();
+      list->accept (*this);
+      decrement_indent_level ();
+    }
+
+  indent ();
+
+  os << "while";
+
+  tree_expression *expr = cmd.condition ();
+
+  if (expr)
+    expr->accept (*this);
+
+  newline ();
+}
+
+void
+tree_print_code::visit_do_until_command (tree_do_until_command& cmd)
+{
+  indent ();
+
+  os << "do";
+
+  newline ();
+
+  tree_statement_list *list = cmd.body ();
+
+  if (list)
+    {
+      increment_indent_level ();
+      list->accept (*this);
+      decrement_indent_level ();
+    }
+
+  indent ();
+
+  os << "until";
+
+  tree_expression *expr = cmd.condition ();
+
+  if (expr)
+    expr->accept (*this);
+
+  newline ();
+}
+
 // Current indentation.
 int tree_print_code::curr_print_indent_level = 0;
 
--- a/src/pt-pr-code.h	Wed Jan 26 23:37:11 2000 +0000
+++ b/src/pt-pr-code.h	Thu Jan 27 23:30:48 2000 +0000
@@ -138,6 +138,10 @@
 
   void visit_while_command (tree_while_command&);
 
+  void visit_do_while_command (tree_do_while_command&);
+
+  void visit_do_until_command (tree_do_until_command&);
+
 private:
 
   ostream& os;
--- a/src/pt-walk.h	Wed Jan 26 23:37:11 2000 +0000
+++ b/src/pt-walk.h	Thu Jan 27 23:30:48 2000 +0000
@@ -67,6 +67,8 @@
 class tree_try_catch_command;
 class tree_unwind_protect_command;
 class tree_while_command;
+class tree_do_until_command;
+class tree_do_while_command;
 
 class
 tree_walker
@@ -205,6 +207,12 @@
   virtual void
   visit_while_command (tree_while_command&) = 0;
 
+  virtual void
+  visit_do_while_command (tree_do_while_command&) = 0;
+
+  virtual void
+  visit_do_until_command (tree_do_until_command&) = 0;
+
 protected:
 
   tree_walker (void) { }