octave-maintainers
[Top][All Lists]
Advanced

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

Re: TRACING


From: JD Cole
Subject: Re: TRACING
Date: Fri, 20 Feb 2004 22:32:32 -0800
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.5) Gecko/20031007

Sorry, forgot to add the compile.cc attachment.

JD
#include <octave/oct.h>

#include <pt-all.h>
#include <pt-emit-cplusplus.h>
#include <parse.h>

using namespace std;

DEFUN_DLD(compile, args, , "compile")
{
  // Make sure that the argument passed exists and is a string
  if(args.length() > 0 
     && args(0).is_string())
    {
      // Lookup this name in the symbol tables, this will either find
      // the name or cause Octave to load the similarly named .m (or .oct)
      symbol_record *s = lookup_by_name(args(0).string_value(),false);
      
      // Make sure the file was found and it's a function
      if (s && s->is_function())
        {
          // Create a tree_walker structure
          tree_emit_cplusplus tpc(cout);

          // Print out the numbered debug info
          tpc.set_debug_mode ();

          // Get a pointer to the function
          octave_user_function *f = 
(octave_user_function*)s->def().function_value();
          
          // The body of the function is the main portion we want to convert,
          // bodies are composed of a singe statement list...this is effectively
          // the top of the parse tree for the body of the function
          tree_statement_list *bd = f->body();
          

          // Throw in the apropriate header information
          cout << "#include <octave/oct.h>\n\n";

          // And start the function call
          cout 
            << "extern void\n"
            << f->function_name()<<" (";

          // A list of the parameters passed IN to the function
          tree_parameter_list *pl = f->parameter_list ();

          // A ist of the parameters passed OUT of the function
          tree_parameter_list *rl = f->return_list ();
          
          // Find matching parameter variables
          // I match the parameter values here so that they can be used
          // as "INOUT" variable in the function header, i.e. if a variable 
          // is used as both input and output. The values which are only 
          // passed in are labeled "const"

          // =================== sTart the parameter matching stuff ===========
          // This is ugly code and really not too necessary to get compiler
          // stuff rolling, probably more energy should be put into the
          // actual code converting
          int pl_len = 0;
          int rl_len = 0;

          if(pl)
              pl_len = pl->length();

          if (rl)
            rl_len = rl->length();

          bool pl_match[pl_len];
          bool rl_match[rl_len];
          int pl_index = 0;

          // Set up a table which indicates which parameters have
          // been matched so far
          if (pl)
            {
              for (unsigned int i = 0; i< pl->length(); i++)
              pl_match[i] = false;
            }
          if (rl)
            {
              for (unsigned int i = 0; i< rl->length(); i++)
                rl_match[i] = false;
            }

          // If there are inputs and outputs, then continue, if not
          // we don't have to worry about matching
          if (pl && rl)
            {
              // We're going to iterate through the parameter list
              tree_parameter_list::iterator plp = pl->begin();

              // Until the end
              while (plp != pl->end())
                {
                  // Check this parameter name
                  tree_identifier *pid = *plp;

                  plp++;

                  // This is "clean" code, make sure the parameter 
                  // identifier exists
                  if (pid)
                    {
                      // Now iterate through the return list to find
                      // potential matches
                      tree_parameter_list::iterator rlp = rl->begin();
                      int rl_index = 0;

                      while (rlp != rl->end())
                        {
                          tree_identifier *rid = *rlp;
                          
                          rlp++;

                          if (rid)
                            {
                              // Basically these lines just plug in true or
                              // false if a name has been matched, they use
                              // bitwise OR (logically identical to logical OR)
                              // because we don't want to over write a 
previously
                              // determined true with a false 
                              pl_match[pl_index] |= (pid->name() == 
rid->name());
                              rl_match[rl_index] |= (pid->name() == 
rid->name());
                            }
                          // Check the next return item
                          rl_index++;
                        }
                    }
                  // check the next parameter
                  pl_index++;
                }
            }

          // now it's time to print them out, we're going to start with
          // the parameter list (they go on the first line in the output
          // immediately following the function name)
          if(pl)
            {
              // This should be familiar...think iteration
              tree_parameter_list::iterator p = pl->begin ();
              pl_index = 0;

              if(p != pl->end ())
                {
                  tree_identifier *elt = *p;
          
                  while (p != pl->end ())
                    {
                      p++;

                      if(elt)
                        {
                          // If a matched entry was found, don't
                          // use const
                          if(pl_match[pl_index])
                            cout << "octave_value& ";
                          else
                            cout << "const octave_value& ";

                          cout << elt->name();

                          // In the symbol list (which will be used later)
                          // mark all the parameters as existing/true
                          tpc.symbol_used (elt->name(), true);
                        }

                      if(p == pl->end ())
                        break;
                      elt = *p;
              
                      if (elt)
                        cout<< ", ";
                      
                      pl_index++;
                    }
                }
            }
          
          // Now print out the remaining return list items, that is, those
          // that didn't have matches to parameters
          if(rl)
            {
              // These is just pretty indenting for a second line of values
              if (pl)
                {
                  cout<<",\n";
                  for (unsigned int i= 0;i< f->function_name().length();i++)
                    cout<<" ";

                  cout<<"  ";
                }

              // Let's iterate
              tree_parameter_list::iterator p = rl->begin ();
              int rl_index = 0;

              if(p != rl->end ())
                {
                  tree_identifier *elt = *p;
          
                  while (p != rl->end ())
                    {
                      p++;

                      if(elt)
                        {
                          // Only print if there was no match
                          if(!rl_match[rl_index])
                            {
                              cout << "octave_value& ";

                              cout << elt->name();
                              tpc.symbol_used (elt->name(), true);
                            }
                        }

                      if(p == rl->end ())
                        break;
                      elt = *p;
              
                      // Don't put a comma on the last one
                      if (elt && rl_match[rl_index])
                        cout<< ", ";
                      
                      rl_index++;
                    }
                }
            }
          
          // complete the function preamble and start the body
          cout<<")\n{\n";
          // ====================== End the paremeter matching stuff ========
          // It's pretty ugly code and probably isn't that relevant to the
          // initial compiler work.

          // Start the pt_emit_cplusplus on the body of the loop, this will
          // "emit" C++ to  standard output (stdout or cout)
          bd->accept(tpc);

          // end the function body
          cout<<"}"<<endl;
        }
    }

  return octave_value();
}

reply via email to

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