Feature - Implemented ASH main parameter parsing

Veracity

Developer
Staff member
When you invoke an ASH script from the gCLI, you can include parameters on the command line:
If myScript1 has the following:
Code:
void main(int arg1, string arg2, item arg3)
...
invoking like this:
Code:
> call myScript1 (1, abc, shadow venom)
will parse the command line and coerce the arguments into the expected data types and bind them to the function parameters.

An ASH script's main function can also have a single string parameter which receives all the arguments concatenated
Code:
void main(string parameters)
{
...
}
invoked via
Code:
call myScript2 (jump, 10, feet)
or even
Code:
call myScript2 jump 10 feet
will bind argument parameters to "jump 10 feet"

It'd be nice if in the "single string argument" case you could invoke the script with no arguments and it would call the script with an empty string. Instead, ASH considers that "parameters" is required and prompts the user to supply a string.

I have an idea for a backwards-compatible way to deal with this that uses a feature I implemented a few years ago - long after current ASH script invocation was implemented. What if we allowed the final argument of a main() function to be a vararg?
Code:
void main(string command, string... parameters)
{
}
could allow
Code:
call myScript3(jump, backwards)
to bind "command" to "jump" and "parameters" to { "backwards" }
and
Code:
call myScript3(jump, 10, feet)
binds "command" to "jump" and "parameters" to { "10", "feet" }
and even
Code:
call myScript3(jump)
binds command to "jump" and "parameters" to {} - without prompting for a "missing" second argument.

You want a script with more freeform command line?

Code:
void main(string... parameters)
{
}
allows
Code:
call myScript4
call myScript4 (abc)
call myScript4 (abc, def)
binds "parameters" to {}, {"abc"} and {"abc, "def"} with no user prompting

What about the parentheses-less invocation?

Code:
call myScript4 abc def xyz
for a main with a single "string" argument gives you a single string, but with a string... argument, it could implicitly split the command line and give you {"abc", "def", xyz"}

I think I would like it to have a fancy split, in which you could use "\ " and "\\" to embed a space or \ in the string. Maybe \s or \n.

I have quite a few scripts which could benefit from this.
Thoughts?
 

Veracity

Developer
Staff member
I've been musing about this. I'll be home tomorrow afternoon, so will be able to get to this this weekend.

I think a simpler - but not strictly backwards compatible - solution is better.

To wit, if you use the "parentheses" method of calling an ASH script with typed arguments, it works as always, but with no parenthesis, the command line is stuck into a single string - as before - and passed to your main function which has a single string parameter - as before - but if you have an empty command line, the function is given an empty string and the user is NOT prompted to enter a "string".

Considering that with the current behavior, since you can respond to the prompt with an empty string, the script has to be able to handle that anyway.

This seems simpler all around - and how it should probably have been coded initially.
 

Veracity

Developer
Staff member
I decided to go with the varargs approach. Revision 27369.

This script:
Code:
void main(string op, int... args)
{
    int result = 1;
    print("op = '" + op + "' args = " + count(args));
    foreach i, arg in args {
        switch (op) {
        case "+":
            result += arg;
            break;
        case "-":
            result -= arg;
            break;
        case "*":
            result *= arg;
            break;
        }
    }
    print("result = " + result);
}
It has a main function with a required "string" arg and an optional array of ints.
It yields:
Code:
> call vargi -

op = '-' args = 0
result = 1

> call vargi (+, 2, 4, 6)

op = '+' args = 3
result = 13

> call vargi (*, 2, 4, 6, 8, 10)

op = '*' args = 5
result = 3840
If I omit the required "op" argument it will prompt for a string.
It will never prompt for the array of ints.

Note that if you want a vararg parameter to accumulate typed arguments, you have to use the "SCRIPTNAME (ARGS)" syntax.
You have to have a space between the script name and the opening parenthesis.

That's a little weird, although it agrees with the non-parentheses calling convention, where the parameters are "whatever follows the first space".

Considering that file names can include spaces, that implies that if you want to pass parameters to such a script, you'll have to use the parentheses technique. I should probably rename "Garden Harvester.ash" to "GardenHarvester.ash", both to allow parameters (should I decide to add some) and to not conflict with the built-in "garden" CLI command. :)

This script:
Code:
void main(string... params)
{
    foreach i, param in params {
        print("param = " + param);
    }
}
has no required arguments. It yields:
Code:
> call vargi2 ten twenty thirty zero

param = ten twenty thirty zero

> call vargi2

> call vargi2 (foo, bar, baz)

param = foo
param = bar
param = baz
It will not prompt for the string array.
 
Top