octave-maintainers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: oct2mat script based on parse tree


From: Muthiah Annamalai
Subject: Re: oct2mat script based on parse tree
Date: Wed, 09 Jan 2008 23:59:50 -0600
User-agent: Thunderbird 2.0.0.6 (X11/20071022)

Muthiah Annamalai wrote:

John W. Eaton wrote:
On 9-Jan-2008, Muthiah Annamalai wrote:

| John W. Eaton wrote:
| > On 9-Jan-2008, Muthiah Annamalai wrote:
| >
| > | we have some
| > | issues,like I didnt have boolean expressions involving strings folded | > | over.
| >
| > I don't understand what you mean by that.
| >
| > jwe
| > | This is the boolean exp -> const , folding I was talking about.

OK. I suppose it would be useful to have an option to turn off any
optimizations that happen in the parser. It should be easy to do, and
I see that as independent of your tree walking code.

jwe

I have attached a patch to allow conditional tree folding.
It works using the global variable

bool parser_folding_and_optimization_flag;

which user must push onto unwind stack, and use
the accessor functions

parser_enable/disable_optimization()

and query by

parser_require_optimization()

I have one problem however, the various symbols are not exported,
and I think it maybe due to a clock-skew in my box, which I cannot fix.
So I hope this patch is correct. Waiting for my build to complete.
The changes are correct syntactic/semantically however.
I can confirm the patch works as expected. The clock-skew
was the culprit.
-Muthu


I have attached patches to the tree_print_code class that converts it
to a also do the job of converting to matlab code.

It changes the constructor, and uses 4 static functions to get the job done.

Please review the patch, and suggest improvements.
I am not attaching a changelog yet.

-Muthu

Index: pt-pr-code.cc
===================================================================
RCS file: /cvs/octave/src/pt-pr-code.cc,v
retrieving revision 1.54
diff -u -p -r1.54 pt-pr-code.cc
--- pt-pr-code.cc       12 Oct 2007 21:27:33 -0000      1.54
+++ pt-pr-code.cc       10 Jan 2008 05:56:20 -0000
@@ -35,6 +35,240 @@ along with Octave; see the file COPYING.
 #include "pr-output.h"
 #include "pt-all.h"
 
+
+static std::string
+matlab_unary_op_as_string (octave_value::unary_op op)
+{
+  std::string retval;
+
+  switch (op)
+    {
+    case octave_value::op_not:
+      retval = "~";
+      break;
+
+    case octave_value::op_uplus:
+      retval = "+";
+      break;
+
+    case octave_value::op_uminus:
+      retval = "-";
+      break;
+
+    case octave_value::op_transpose:
+      retval = ".'";
+      break;
+
+    case octave_value::op_hermitian:
+      retval = "'";
+      break;
+
+    case octave_value::op_incr:
+      retval = "++";
+      break;
+
+    case octave_value::op_decr:
+      retval = "--";
+      break;
+
+    default:
+      retval = "<unknown-unop>";
+    }
+
+  return retval;
+}
+
+static std::string
+matlab_binary_op_as_string (octave_value::binary_op op)
+{
+  std::string retval;
+
+  switch (op)
+    {
+    case octave_value::op_add:
+      retval = "+";
+      break;
+
+    case octave_value::op_sub:
+      retval = "-";
+      break;
+
+    case octave_value::op_mul:
+      retval = "*";
+      break;
+
+    case octave_value::op_div:
+      retval = "/";
+      break;
+
+    case octave_value::op_pow:
+      retval = "^";
+      break;
+
+    case octave_value::op_ldiv:
+      retval = "\\";
+      break;
+
+    case octave_value::op_lshift:
+      retval = "<<";
+      break;
+
+    case octave_value::op_rshift:
+      retval = ">>";
+      break;
+
+    case octave_value::op_lt:
+      retval = "<";
+      break;
+
+    case octave_value::op_le:
+      retval = "<=";
+      break;
+
+    case octave_value::op_eq:
+      retval = "==";
+      break;
+
+    case octave_value::op_ge:
+      retval = ">=";
+      break;
+
+    case octave_value::op_gt:
+      retval = ">";
+      break;
+
+    case octave_value::op_ne:
+      retval = "~=";
+      break;
+
+    case octave_value::op_el_mul:
+      retval = ".*";
+      break;
+
+    case octave_value::op_el_div:
+      retval = "./";
+      break;
+
+    case octave_value::op_el_pow:
+      retval = ".^";
+      break;
+
+    case octave_value::op_el_ldiv:
+      retval = ".\\";
+      break;
+
+    case octave_value::op_el_and:
+      retval = "&";
+      break;
+
+    case octave_value::op_el_or:
+      retval = "|";
+      break;
+
+    case octave_value::op_struct_ref:
+      retval = ".";
+      break;
+
+    default:
+      retval = "<unknown-binop>";
+    }
+
+  return retval;
+}
+
+static void 
+do_oct2mat_oper(std::ostream &os, tree_binary_expression &expr)
+{
+  std::string oprval="<unknown-binary>";
+
+  // this converts code into whatever form
+  // oct2mat requires.
+  if ( expr.is_boolean_expression() )
+    {
+      const tree_boolean_expression & tbr
+       = dynamic_cast<tree_boolean_expression &> (expr);
+
+      oprval="<unknown-bool>";
+
+      switch ( tbr.op_type() )
+       {
+       case tree_boolean_expression::bool_and:
+         oprval = "&";
+         break;
+         
+       case tree_boolean_expression::bool_or:
+         oprval = "|";
+         break;
+         
+       defualt:
+         oprval = "<unknown-bool>";
+       }
+    }
+  else 
+    {
+      oprval=matlab_binary_op_as_string(expr.op_type());
+    }
+
+  os << " " << oprval << " ";
+  return;
+}
+
+
+static void 
+do_oct2mat_oper(std::ostream &os, tree_unary_expression &expr)
+{
+  std::string oprval="<unknown-unary>";
+
+  oprval=matlab_unary_op_as_string(expr.op_type());
+  os << " " << oprval << " ";
+  return;
+}
+
+static void
+do_print_commented_code(tree_statement_list *stmt, std::ostream &os, 
std::string &prefix)
+{
+  std::ostringstream buf;
+  std::string buf_str;
+  tree_print_code omat(buf,"",true,true);
+  stmt->accept(omat);
+  buf_str = buf.str();
+  os << prefix << "%%";
+  for( int idx=0; idx< buf_str.length(); idx++ )
+    {
+      if ( buf_str[idx] == '\n' )
+       {
+         os << buf_str[idx];
+         os << prefix;
+         os << "%%";
+       }
+      else
+       os << buf_str[idx];
+    }
+}
+
+
+std::string
+tree_print_code::indent_to_string (void)
+{
+  std::ostringstream s;
+  assert (curr_print_indent_level >= 0);
+
+  s << "";
+  if (printing_newlines)
+    {
+      if (beginning_of_line)
+       {
+         s << prefix;
+
+         for (int i = 0; i < curr_print_indent_level; i++)
+           s << " ";
+
+         beginning_of_line = false;
+       }
+    }
+  return s.str();
+}
+
 void
 tree_print_code::visit_anon_fcn_handle (tree_anon_fcn_handle& afh)
 {
@@ -90,10 +324,13 @@ tree_print_code::visit_binary_expression
   if (op1)
     op1->accept (*this);
 
-  os << " " << expr.oper () << " ";
-
   tree_expression *op2 = expr.rhs ();
 
+  if ( convert_to_matlab ) 
+     do_oct2mat_oper(os,expr); 
+  else
+    os << " " << expr.oper () << " ";
+
   if (op2)
     op2->accept (*this);
 
@@ -237,7 +474,10 @@ tree_print_code::visit_simple_for_comman
 
   indent ();
 
-  os << "endfor";
+  if ( convert_to_matlab )
+     os << "end";  
+  else
+     os << "endfor";
 }
 
 void
@@ -280,7 +520,10 @@ tree_print_code::visit_complex_for_comma
 
   indent ();
 
-  os << "endfor";
+  if ( convert_to_matlab )
+     os << "end";
+  else
+     os << "endfor";
 }
 
 void
@@ -401,7 +644,10 @@ tree_print_code::visit_octave_user_funct
 
   indent ();
 
-  os << "endfunction";
+  if ( convert_to_matlab )
+     os << "%% endfunction";
+  else
+     os << "endfunction";
 
   newline ();
 }
@@ -414,7 +660,17 @@ tree_print_code::visit_identifier (tree_
   print_parens (id, "(");
 
   std::string nm = id.name ();
-  os << (nm.empty () ? std::string ("(empty)") : nm);
+
+  if ( convert_to_matlab )
+     {
+        std::map<std::string,std::string>::iterator iter= 
identifier_lut.find(nm);
+        if ( iter != identifier_lut.end() )
+           os << iter->second ;
+        else
+           os << (nm.empty () ? std::string ("(empty)") : nm);
+     }
+  else
+     os << (nm.empty () ? std::string ("(empty)") : nm);
 
   print_parens (id, ")");
 }
@@ -459,7 +715,10 @@ tree_print_code::visit_if_command (tree_
 
   indent ();
 
-  os << "endif";
+  if ( convert_to_matlab )
+     os << "end";  
+  else
+     os << "endif";
 }
 
 void
@@ -693,11 +952,75 @@ tree_print_code::visit_no_op_command (tr
 void
 tree_print_code::visit_constant (tree_constant& val)
 {
+  std::string buf_str;
+  std::ostringstream buf;
+  int idx = 0;
+  octave_value sval=val.rvalue();
   indent ();
 
   print_parens (val, "(");
 
-  val.print_raw (os, true, print_original_text);
+
+  if ( convert_to_matlab )
+    {
+      if ( sval.is_string() )
+       {
+         buf_str=sval.string_value();
+         // see if you need to escape the string stxt.
+         os << "'";
+         for( idx=0; idx < buf_str.length();  ) {
+           if ( buf_str[idx] == '"' || buf_str[idx] == '\'' ) 
+             {
+               os << "\\" ;
+               os << buf_str[idx];
+             } 
+           else if ( buf_str[idx] == '\"' ) 
+               os << "'";
+
+           else if ( buf_str[idx] == '\n' ) 
+               os << "\\n";
+
+           else if ( buf_str[idx] == '\t' ) 
+               os << "\\t";
+
+           else if ( buf_str[idx] == '\r' ) 
+               os << "\\r";
+
+           else if ( !isprint(buf_str[idx]) ) 
+               os << "\\" << std::hex <<  buf_str[idx];
+
+           else 
+               os << buf_str[idx];
+
+           idx++;
+         }
+         os << "'";
+       }
+      else 
+       {
+         val.print_raw (buf , true, print_original_text);
+         buf_str = buf.str();
+         // string-escaped sequence need to be printed out.
+         for( idx=0; idx < buf_str.length();  ) 
+           {
+             if ( buf_str[idx] == '\\' ) 
+               {
+                 os << buf_str[idx];
+                 idx++;
+                 os << buf_str[idx];
+               } 
+             else if ( buf_str[idx] == '\"' ) 
+                 os << "'";
+
+             else 
+                 os << buf_str[idx];
+
+             idx++;
+           }
+       }
+    }
+  else    
+    val.print_raw (os, true, print_original_text);
 
   print_parens (val, ")");
 }
@@ -745,7 +1068,10 @@ tree_print_code::visit_postfix_expressio
   if (e)
     e->accept (*this);
 
-  os << expr.oper ();
+  if ( convert_to_matlab )
+     do_oct2mat_oper(os,expr);
+  else
+     os << expr.oper ();
 
   print_parens (expr, ")");
 }
@@ -757,7 +1083,11 @@ tree_print_code::visit_prefix_expression
 
   print_parens (expr, "(");
 
-  os << expr.oper ();
+
+  if ( convert_to_matlab )
+     do_oct2mat_oper(os,expr);
+  else
+     os << expr.oper ();
 
   tree_expression *e = expr.operand ();
 
@@ -944,7 +1274,10 @@ tree_print_code::visit_switch_command (t
 
   indent ();
 
-  os << "endswitch";
+  if ( convert_to_matlab )
+    os << "end";
+  else
+    os << "endswitch";
 }
 
 void
@@ -992,18 +1325,30 @@ tree_print_code::visit_try_catch_command
 
   indent ();
 
-  os << "end_try_catch";
+  if ( convert_to_matlab )
+    os << "end";
+  else
+    os << "end_try_catch";
 }
 
 void
 tree_print_code::visit_unwind_protect_command
   (tree_unwind_protect_command& cmd)
 {
+  std::string s;
   print_comment_list (cmd.leading_comment ());
 
-  indent ();
+  s = indent_to_string ();
+  os << s;
 
-  os << "unwind_protect";
+  if ( convert_to_matlab )
+    {
+      os << "%% WARNING: this statement cannot be translated.\n";
+      os << s;
+      os << "%%unwind_protect  ";
+    }
+  else
+      os << "unwind_protect  ";
 
   newline ();
 
@@ -1013,7 +1358,14 @@ tree_print_code::visit_unwind_protect_co
     {
       increment_indent_level ();
 
-      unwind_protect_code->accept (*this);
+      // print a commented code.
+      if ( convert_to_matlab ) 
+       {
+         std::string ind_prfx = indent_to_string( );
+         do_print_commented_code(unwind_protect_code,os,ind_prfx);
+       }
+      else
+       unwind_protect_code->accept (*this);
 
       decrement_indent_level ();
     }
@@ -1022,7 +1374,10 @@ tree_print_code::visit_unwind_protect_co
 
   indent ();
 
-  os << "unwind_protect_cleanup";
+  if ( convert_to_matlab )
+    os << "%%unwind_protect_cleanup";
+  else
+    os << "unwind_protect_cleanup";
 
   newline ();
 
@@ -1032,7 +1387,13 @@ tree_print_code::visit_unwind_protect_co
     {
       increment_indent_level ();
 
-      cleanup_code->accept (*this);
+      if ( convert_to_matlab )
+       {
+         std::string ind_prfx = indent_to_string( );
+         do_print_commented_code(cleanup_code,os,ind_prfx);
+       }
+      else
+       cleanup_code->accept (*this);
 
       decrement_indent_level ();
     }
@@ -1041,7 +1402,10 @@ tree_print_code::visit_unwind_protect_co
 
   indent ();
 
-  os << "end_unwind_protect";
+  if ( convert_to_matlab )
+    os << "%%end_unwind_protect";
+  else
+    os << "end_unwind_protect";
 }
 
 void
@@ -1075,7 +1439,10 @@ tree_print_code::visit_while_command (tr
 
   indent ();
 
-  os << "endwhile";
+  if ( convert_to_matlab )
+    os << "end";
+  else      
+    os << "endwhile";
 }
 
 void
@@ -1192,7 +1559,10 @@ tree_print_code::print_comment_elt (cons
       if (c == '\n')
        {
          if (prev_char_was_newline)
-           os << "##";
+              if ( convert_to_matlab )
+               os << "%" ;
+              else
+               os << "##";
 
          newline ();
 
@@ -1206,7 +1576,11 @@ tree_print_code::print_comment_elt (cons
 
              indent ();
 
-             os << "##";
+
+             if ( convert_to_matlab )
+                 os << "%%";
+             else
+                os << "##";
 
              if (! (isspace (c) || c == '!'))
                os << " ";
Index: pt-pr-code.h
===================================================================
RCS file: /cvs/octave/src/pt-pr-code.h,v
retrieving revision 1.36
diff -u -p -r1.36 pt-pr-code.h
--- pt-pr-code.h        12 Oct 2007 21:27:33 -0000      1.36
+++ pt-pr-code.h        10 Jan 2008 05:56:20 -0000
@@ -26,6 +26,7 @@ along with Octave; see the file COPYING.
 
 #include <stack>
 #include <string>
+#include <map>
 
 #include "comment-list.h"
 #include "pt-walk.h"
@@ -41,14 +42,23 @@ public:
 
   tree_print_code (std::ostream& os_arg,
                   const std::string& pfx = std::string (),
-                  bool pr_orig_txt = true)
+                  bool pr_orig_txt = true, bool to_matlab = false)
     : os (os_arg), prefix (pfx), nesting (),
-      print_original_text (pr_orig_txt),
+      print_original_text (pr_orig_txt), convert_to_matlab( to_matlab ),
       curr_print_indent_level (0), beginning_of_line (true),
       printing_newlines (true)
   {
     // For "none".
     nesting.push ('n');
+    if ( convert_to_matlab )
+       {
+        identifier_lut["SEEK_CUR"]="0";
+        identifier_lut["SEEK_END"]="1";
+        identifier_lut["SEEK_SET"]="-1";
+        identifier_lut["usage"]="error";
+        identifier_lut["print_usage"]="error";
+        identifier_lut["__error_text__"]="lasterr";
+       }
   }
 
   ~tree_print_code (void) { }
@@ -147,6 +157,12 @@ private:
 
   bool print_original_text;
 
+  // flag controls if tree print code converts to Matlab.
+  bool convert_to_matlab;
+
+  // 
+  std::map<std::string, std::string> identifier_lut;
+
   // Current indentation.
   int curr_print_indent_level;
 
@@ -176,6 +192,8 @@ private:
 
   void print_indented_comment (octave_comment_list *comment_list);
 
+  std::string indent_to_string( );
+
   // Must create with an output stream!
 
   tree_print_code (void);

reply via email to

[Prev in Thread] Current Thread [Next in Thread]