Date: prev next · Thread: first prev next last
2016 Archives by date, by thread · List index


Hi Winfried,

On Thursday, 2016-06-02 09:18:51 +0200, Winfried Donkers wrote:

I started converting the new Calc functions IFS and SWITCH to jump functions.
I experience a problem where the functions IFS and SWITCH differ from the other jump functions 
(IF, CHOOSE, IFERROR, IFNA).
The other jump functions do 1 evaluation (of the first argument) and then jump to an argument 
that is to be the output.
The new jump functions need to evaluate at least 2 arguments.
And that is where I get stuck.

I can imagine..

The first argument is on the stack, i.e. GetStackType() returns a type and ScInterpreter::sp is 1.
When I jump to the next argument to be evaluated, with aCode.Jump( pJump[ nIdx ], pJump[ pJump[ 0 
] ] ), ScInterpreter::sp is 0 afterwards.

Apart from that,  aCode.Jump( pJump[ nIdx ], pJump[ pJump[ 0 ] ] )
looks wrong to me, pJump[0] returns an offset into the RPN array, which
can't be used as an index for another pJump.

See also the description of formula::FormulaTokenIterator::Jump() in
include/formula/tokenarray.hxx

For understanding it helps to step into such Jump() and see what it does
to the counters and on the subsequent iteration of the while loop in
ScInterpreter::Interpret() step into its condition where aCode.Next() is
executed and analyze what happens to the token array and counters.

How do I get the argument I jumped to (that part works) on the stack to be evaluated?

I'm not sure at the moment. That might be a case for pushing a token
array (or rather the same token array with the corresponding jump
locations in this case) to execute a subroutine as result and then
execute the ocIfs again. Some time ago I prepared something in
interpr4.cxx Interpret(), look for ocCall, but that's not ready yet. I'd
have to further work on it. It wouldn't be too hard, right now I'm just
stuck with another thing.

Another possibility and maybe more straight forward would be to look,
for example, at IFS(x,1,a,2,b,3,c,else) as an equivalent sequence of
IF(x=1,a,IF(x=2,b,IF(x=3,c,else))). So when evaluating the IFS(x,1,...)
and that is not a match then discard the 'a', push the 'x' again and the
next code path (jump) would be IFS(x,2,b,3,c,else). I'm not sure how
feasible that is though.. it would likely mean having to calculate the
jumps such that they exclude the previous two parameters and include the
ocIfs OpCode when creating the jumps in the RPN compile step, except for
the 'else' part.

Basically both approaches would work, the latter might be even "easier"
(I know it's not easy at all) to code with what is already implemented.

But maybe I'm complicating things and you found some other approach and
it already helps to push the original 'x' token (remembered as
a FormulaTokenRef before popping the value) again and correct the
pJump[pJump[0]]?

  Eike

-- 
LibreOffice Calc developer. Number formatter stricken i18n transpositionizer.
GPG key "ID" 0x65632D3A - 2265 D7F3 A7B0 95CC 3918  630B 6A6C D5B7 6563 2D3A
Better use 64-bit 0x6A6CD5B765632D3A here is why: https://evil32.com/
Care about Free Software, support the FSFE https://fsfe.org/support/?erack

Attachment: signature.asc
Description: PGP signature


Context


Privacy Policy | Impressum (Legal Info) | Copyright information: Unless otherwise specified, all text and images on this website are licensed under the Creative Commons Attribution-Share Alike 3.0 License. This does not include the source code of LibreOffice, which is licensed under the Mozilla Public License (MPLv2). "LibreOffice" and "The Document Foundation" are registered trademarks of their corresponding registered owners or are in actual use as trademarks in one or more countries. Their respective logos and icons are also subject to international copyright laws. Use thereof is explained in our trademark policy.