octave-maintainers
[Top][All Lists]
Advanced

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

[NOTES] How function calls work in Octave


From: David Grundberg
Subject: [NOTES] How function calls work in Octave
Date: Sun, 27 Feb 2011 12:32:23 +0100
User-agent: Thunderbird 2.0.0.24 (X11/20101027)

For those interested in Octave core internals, here are some brief notes
how calling user functions works.  I've written it as a help for myself
when I was reading up on this.

I will describe the overall internal mechanics of calling a user defined
function.  In other words, if you have a function file called myfunc.m
and you write:

  myfunc ("hello world");

what happens inside the GNU Octave interpreter?  This article is aimed
at people knowledgeable in C++ programming.  No knowledge of
interpreters needed.

First, octave interprets your input and constructs a tree of the input
data.  This step is called parsing.  When the parsing is done, we will
end up with:

tree_statement_list
  tree_statement
    tree_index_expression (but tree_statement only
                           sees the tree_expression interface)
      expr = tree_identifier ("myfunc")
      type = "("
      args = list of tree_argument_lists (yes, a list of lists)
         (0) = tree_argument_list
                 tree_constant
                   "hello world"

Mighty fine. Octave then calls the evaluation tree walker.  It takes
the tree and computes the actual computation the user asked for.  The
tree walker has a lot of friends, but one of the most important one is
the symbol table.  The symbol table keeps track of all variables,
builtins and functions that are currently defined.  It will come handy
soon.

So, the tree walker sees a tree_expression and knows what to do with
those.  It calls the rvalue method.  This method will return an
octave_value with the result of 'myfunc ("hello world")'.  But we will
go even deeper and figure out what happens inside the
tree_index_expression.

  Rvalues, for those not familiar with programming language theory, is
  the "right-hand value".  These are values that can not be written
  to, as opposed to "left-hand values" that can be written to.  Why
  are the referred to as right and left?  It is most likely because
  assignments like 'A = B(0)', where A is lvalue and B(0) is rvalue
  respectively.

INSIDE RVALUE

This is when things get real. A special case in rvalue determines that
the index ("hello world") isn't empty and the identifier (myfunc)
isn't a variable defined in this scope. So now we have to look at
these two and figure out what to do.  The identifier's do_lookup
function does this for us.  This is what the comment says:

  // Try to find a definition for an identifier.  Here's how:
  //
  //   * If the identifier is already defined and is a function defined
  //     in an function file that has been modified since the last time
  //     we parsed it, parse it again.
  //
  //   * If the identifier is not defined, try to find a builtin
  //     variable or an already compiled function with the same name.
  //
  //   * If the identifier is still undefined, try looking for an
  //     function file to parse.
  //
  //   * On systems that support dynamic linking, we prefer .oct files,
  //     then .mex files, then .m files.

  octave_value
  do_lookup (const octave_value_list& args = octave_value_list ())

Yes, do_lookup does all that!  This is an important member
function. That must be a very complicated function, right?  Yes doubly
so, since it turns out to be implemented with just one line.  It just
asks the symtab to figure out all this stuff, which has to wait until
it gets an article of its own.  Bottom line is, in this example,
do_lookup will return an octave_user_function (in the guise of an
octave_value, of course).

We are still in the tree_index_expression's rvalue though.  What
happens next is that the rvalue is calculated by calling
octave_user_function->subsref.  (It basically does the job of the
Octave-language subsref function.)  Looking inside subsref, it sooner
or later comes down to a tree_statement_list, and well, you know the
rest.

I hope this raises some questions and increases confusion about the
Octave interpreter.

Grundberg

Also published here:
http://blogs.fsfe.org/grundberg/2011/02/27/how-function-calls-work-in-octave/


reply via email to

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