changeset 18581:f3314c4b9266 draft

Add the do-until statement support
author LYH <lyh.kernel@gmail.com>
date Fri, 21 Mar 2014 14:59:38 -0400
parents 8f256148d82b
children c31fe3239c8b
files libinterp/corefcn/pt-jit.cc libinterp/parse-tree/pt-eval.cc
diffstat 2 files changed, 66 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/pt-jit.cc	Tue Jan 07 16:07:54 2014 -0500
+++ b/libinterp/corefcn/pt-jit.cc	Fri Mar 21 14:59:38 2014 -0400
@@ -901,9 +901,68 @@
 }
 
 void
-jit_convert::visit_do_until_command (tree_do_until_command&)
+jit_convert::visit_do_until_command (tree_do_until_command& duc)
 {
-  throw jit_fail_exception ();
+  unwind_protect prot;
+  prot.protect_var (breaks);
+  prot.protect_var (continues);
+  breaks.clear ();
+  continues.clear ();
+
+  jit_block *body = factory.create<jit_block> ("do_until_body");
+  block->append (factory.create<jit_branch> (body));
+  blocks.push_back (body);
+  block = body;
+
+  tree_statement_list *loop_body = duc.body ();
+  bool all_breaking = false;
+  if (loop_body)
+    {
+      try
+        {
+          loop_body->accept (*this);
+        }
+      catch (const jit_break_exception&)
+        {
+          all_breaking = true;
+        }
+    }
+
+  jit_block *cond_check = factory.create<jit_block> ("do_until_cond_check");
+  block->append (factory.create<jit_branch> (cond_check));
+  blocks.push_back (cond_check);
+  block = cond_check;
+
+  tree_expression *expr = duc.condition ();
+  assert (expr && "Do-Until expression can not be null");
+  jit_value *check = visit (expr);
+  check = create_checked (&jit_typeinfo::logically_true, check);
+
+  jit_block *tail = factory.create<jit_block> ("do_until_tail");
+  block->append (factory.create<jit_cond_branch> (check, tail, body));
+
+  finish_breaks (tail, breaks);
+
+#if 0
+  if (! all_breaking || continues.size ())
+    {
+      jit_block *interrupt_check
+        = factory.create<jit_block> ("interrupt_check");
+      blocks.push_back (interrupt_check);
+      finish_breaks (interrupt_check, continues);
+      if (! all_breaking)
+        block->append (factory.create<jit_branch> (interrupt_check));
+
+      block = interrupt_check;
+      jit_error_check *ec
+        = factory.create<jit_error_check> (jit_error_check::var_interrupt,
+                                           cond_check, final_block);
+      block->append (ec);
+    }
+#endif
+
+  blocks.push_back (tail);
+  block = tail;
 }
 
 void
--- a/libinterp/parse-tree/pt-eval.cc	Tue Jan 07 16:07:54 2014 -0500
+++ b/libinterp/parse-tree/pt-eval.cc	Fri Mar 21 14:59:38 2014 -0400
@@ -1122,6 +1122,11 @@
   if (error_state)
     return;
 
+#if HAVE_LLVM
+  if (tree_jit::execute (cmd))
+    return;
+#endif
+
   unwind_protect frame;
 
   frame.protect_var (in_loop_command);