Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get Function Args #24

Open
bakman23 opened this issue Jun 26, 2020 · 1 comment
Open

Get Function Args #24

bakman23 opened this issue Jun 26, 2020 · 1 comment

Comments

@bakman23
Copy link

Hello,
is it possible to get a function arg by index ?

I would like create an IF function like excel.

IFELSE( [condition] , [if true action] , [if false action] )

the problem is, if I use GetFunctionArgs all args will be interpreted and this exemple "IFELSE( 1 != 1 , 1 / 0 , "ok")" the divided by zero will be catch.

the must will be to test fisrt param, if it return 0 the second param will not be interpreted only the third
Exemple
`

        //get condition
        var arg = script.GetFunctionArgByIndex(indexParam: 0);
        var condition = Utils.GetSafeString(arg, 0);
        if (condition == "1")
        {
            arg = script.GetFunctionArgsIndex(indexParam: 1);
            string actionIfTrue = Utils.GetSafeString(arg, 0);
            return new Variable(actionIfTrue);
        }
        else
        {
            arg = script.GetFunctionArgsIndex(indexParam: 2);
            string actionIfFalse = Utils.GetSafeString(arg, 0);
            return new Variable(actionIfFalse);
        }

`
I tried to create the GetFunctionArgsIndex and it work with this IFELSE( 1 != 1 , 1 / 0 , "ok") but not with that
IFELESE ( functA(x) * functB(y) != 0 , 3 - 10 * Round( 1 / 0 ) , Ceil(0.4))

`

public static List GetFunctionArgsIndex(ParsingScript script,
char start, char end, Action outList, int indexParam )
{
List args = new List();
bool isList = script.StillValid() && script.Current == Constants.START_GROUP;

        if (!script.StillValid() || script.Current == Constants.END_STATEMENT)
        {
            return args;
        }

        ParsingScript tempScript = script.GetTempScript(script.String, script.Pointer);

        if (script.Current != start && script.TryPrev() != start &&
           (script.Current == ' ' || script.TryPrev() == ' '))
        { // Allow functions with space separated arguments
            start = ' ';
            end = Constants.END_STATEMENT;
        }

        // ScriptingEngine - body is unsed (used in Debugging) but GetBodyBetween has sideeffects			

#pragma warning disable 219
string body = Utils.GetBodyBetween(tempScript, start, end);
#pragma warning restore 219
// After the statement above tempScript.Parent will point to the last
// character belonging to the body between start and end characters.

        int index = 0;

        while (script.Pointer < tempScript.Pointer)
        {

            if (index == indexParam)
            {

                Variable item = Utils.GetItem(script, false);
                args.Add(item);
                break;
            }
            else
            {
                Parser.Split(script, Constants.NEXT_OR_END_ARRAY);
            }
            
            if (script.Pointer < tempScript.Pointer)
            {
                script.MoveForwardIf(Constants.END_GROUP);
                script.MoveForwardIf(Constants.NEXT_ARG);
            }
            else if (script.Pointer > tempScript.Pointer)
            {
                script.MoveForwardIf(Constants.NEXT_ARG);
            }
            if (script.Pointer == tempScript.Pointer - 1)
            {
                script.MoveForwardIf(Constants.END_ARG, Constants.END_GROUP);
            }
            index++;
        }

        if (script.Pointer <= tempScript.Pointer)
        {
            // Eat closing parenthesis, if there is one, but only if it closes
            // the current argument list, not one after it. 
            script.MoveForwardIf(Constants.END_ARG, end);
        }

        script.MoveForwardIf(Constants.SPACE);
        //script.MoveForwardIf(Constants.SPACE, Constants.END_STATEMENT);
        outList(isList);
        return args;
    }

`

Can you help me, please ?

@vassilych
Copy link
Owner

Hi,

What you can do is to use Utils.GetToken() function instead of GetFunctionArgs(). Here is an example:

string funcName = Utils.GetToken(script, Constants.NEXT_OR_END_ARRAY);

This function doesn't execute the parameters, i.e. it treats them as strings. So you will get next string in the list.
Unfortunately you have to call this function multiple times if you want to extract multiple parameters.
I am going to create a convenience method to get a list of all args.

Let me know if calling GetToken() multiple times can solve the issue for you. Note that as a separation token you can also use a space if needed.

Best, Vassili

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants