octave-maintainers
[Top][All Lists]
Advanced

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

Re: f(end) feature?


From: John W. Eaton
Subject: Re: f(end) feature?
Date: Tue, 31 Dec 2002 16:31:48 -0600

On 31-Dec-2002, Paul Kienzle <address@hidden> wrote:

| I'm impressed!  I still haven't figured out how you've done it.  Maybe
| one day I'll give up and peek at the code.

The idea is simple, but maybe not obvious.

When Octave parses "end", it either recognizes it as a keyword (in
contexts like "for ... end") or an identifier (in argument list
contexts).  This works OK because a for loop or if conditional can't
appear inside an argument list (for value indexing or function calls).

If "end" is recognized as an identifier, it is converted to __end__,
to avoid (or create?)  some confusion.

There is also a new internal __end__ function that should be called
for any reference to __end__ (it is supposed to be impossible to clear
or redefine this function).  So we just need to arrange things so that
__end__ returns the proper value when it is called.

When you evaluate an expression like

  IDENTIFIER ( ARGS )

Octave creates an "index expression" object.  When it is evaluated, it
first converts ARGS to an array of values.  The function that does
that now takes a pointer to IDENTIFIER, so __end__ can ask that object
how many rows or columns it has.  To give __end__ a pointer to
IDENTIFIER, we use a global pointer and the unwind_protect stack (to
save and restore it reliably.  We also save the index position, so we
can tell __end__ which dimension of IDENTIFIER to return.

Then when __end__ is called, it checks the global pointer, and if it
is valid, asks the object that it points to what its size is and
returns the appropriate dimension.

Since we save and restore the global pointer with the unwind protect
stack, it should work correctly for recursion to any depth.

My second patch just ensured that we don't try to save a pointer to a
function object, that way if you have an expression like

  x (1, max (3, end))

then __end__ will have a pointer to x and not max when it is called,
and

  max (3, end)

by itself will not work (because end will not point to a valid
object).

jwe



reply via email to

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