Bug - Fixed ASH cannot use anonymous record values from RuntimeLibrary functions

Veracity

Developer
Staff member
Records are useful. Scripts declare and use them like this:
Code:
record MyRec
{
    int x;
    int y;
};

MyRec my_func(int x, int y)
    return new MyRec(x, y);
}

MyRec my_var = my_func(10, 20);
print("x = " + my_var.x + " y = " + my_var.y);

// prints "x = 10 y = 20"

ASH also allows you to declare "anonymous" records by omitting the name.
Code:
record
{
    int x;
    int y;
} my_var;
You can similarly declare function return types and function parameters like that.

That is completely useless, since there is no way for an ASH script to actually CREATE such an object.
Frankly, I do not understand why we allow the syntax. Perhaps I should remove it.

The only potential use that I see is because there are a handful of RuntimeLibrary functions that return an anonymous record.

For example:

Code:
record
{
    string display;
    string command;
    float score,
    effect effect,
    item item,
    skill skill;
};
Notice that that is not even a legal record; the last three field names are reserved-word type names.
The 5-parameter version of maximize() returns an array of those.

This one is legal:
Code:
record
{
    string url;
    string branch;
    string commit;
    string last_changed_author;
    string last_changed_date;
};
That is returned by git_info(string script);

Now, a script can access the maximizer results by iterating over the return value using foreach.
Code:
foreach n, result in maximize(arg1, arg2, arg3, arg4, arg5) {
    result.command, result.score, etc. can be used.
    can result.effect, result.item, and result.skill?
}

But there is no way to call git_info("script") and actually store the result in a variable.
You CAN do git_info("script").url, say to access one field at a time.

One might think you could do this:

Code:
record GitInfo
{
    string url;
    string branch;
    string commit;
    string last_changed_author;
    string last_changed_date;
};

GitInfo info = git_info("script");
// Use info.url, info.branch, ...

ASH does not allow that, today, because "record GitInfo { FIELDS }" is not the same as "record { FIELDS }", even if FIELDS are identical.

I'd like to allow that. My new ping() functions return an anonymous record with 8 fields - and you can't use the "call it 8 times to get one field at a time" trick since those functions actually run a new ping test each time you call them; you won't be able to fetch the 8 fields from a single test without being able to save the record in a variable.

I can make two records which have the same fields (type and name) in the same order be considered to be "the same type" for the purpose of assigning the return values of RuntimeLibrary functions.

(That would also work if you actually coded multiple records in ASH that are identical except for name. That is useless; if you "import" another ASH script, you have access to the named records of that script and don't need to declare duplicate records with different names to store the return values of imported functions. But, whatever.)

The MaximizerResult record would not benefit from this fix, since you can't (I hope!) declare fields with names that are a reserved type name.
We could handle that with a "var" type (which is essentially what foreach iteration variables have).
That will be a different PR.
 

Veracity

Developer
Staff member
I’ve been pondering the MaximizerResult record issue.

To wit, it has three field names that are reserved word type names - effect, item, skill.

I wonder if there’s any downside to allowing records to declare fields like that? The only time you reference them is in a record field reference - var.field - and that is not a place where we are syntactically looking for a type name. Ergo, no parsing ambiguity.

(I was also thinking about this in the context of record literals - see recent Feature Request - and there, too, it would not be an issue, since we’d not be looking for type names there.)

Now that ping testing is essentially done, time to move back to ASH improvements and bug fixes. 😀
 

Veracity

Developer
Staff member
Here are all the RuntimeLibrary functions that return a record.

Code:
record ItemDrop
{
    item drop;
    float rate;
    string type;
};

ItemDrop[] item_drops_array();
ItemDrop[] item_drops_array(monster);

record MaximizerResult
{
    string display;
    string command;
    float score;
    effect effect;
    item item;
    skill skill;
};

MaximizerResult[] maximizer(sting, int, int, boolean, boolean);

record svnInfo
{
    string url;
    int revision;
    string last_changed;
    int last_changed_rev;
    string last_changed_data;
};

svnInfo svn_Info(string);

record gitInfo
{
    string url;
    string branch;
    string commit;
    string last_changed_author;
    string last_changed_date;
};

gitInfo git_info(string);

record pingTest
{
    string page;
    int count;
    int low;
    int high;
    int total;
    int bytes;
    int average;
    int bps;
};

pingTest ping();
pingTest ping(string);
pingTest ping(int, string);

record stackTrace
{
    string file;
    string name;
    int line;
};

stackTrace[] get_stack_trace();

This is done.
 
Top