ACS dynamic parameter strings

Moderator: GZDoom Developers

User avatar
FDARI
Posts: 1097
Joined: Tue Nov 03, 2009 9:19 am

ACS dynamic parameter strings

Post by FDARI »

Graf Zahl (snippets) wrote:What do you need dynamic strings for?
(...)
- implementing functions returning string values (e.g. getActorClass, getCurrentWeapon etc.
- creating string parameters for functions like SpawnSpot on the fly.
(...)
store game status stuff. For this char arrays would be much more suitable. If necessary, add a function to copy a string to an array and all should be well.
The above is part of Graf Zahls response to my addition of (nigh) unlimited (and unmanaged) string support to ACS. My intention was also to provide actual automated management through an ACS-compiler, but this was (sensibly) considered an excessive effort. As Graf pointed out, we don't need real dynamic strings as anything but function input/output.

The string only needs to exist very briefly: Long enough to be consumed by a function (or transferred to an array).
Spoiler: Addition and basic idea
Spoiler: Inside details
I only downloaded the ACC-source yesterday, and I don't know how to provide a good svn-diff for it. If that, or any violations of best practice I might have made, poses a problem; let us work on it. This time I think the basic concept is simple and safe.

Side note: No new save data is introduced. The dynamic strings don't live enough to become part of the saved gamestate.
Spoiler: Draft user documentation, mark 2
EDIT: A modified version has been packaged and uploaded alongside the original submission. "ZDOOM_ACC_StrParam_implicit.zip" contains an ACC project and a ZDoom diff, as well as an overview of changes to ACC.
Spoiler: Under the hood
Edit: Replaced all versions with the latest one. String stack handling is implicit and automatic, and strparam can be called as a statement.
Attachments
ACC_ACS_StrParam_implicit.zip
This version rendered previous variants obsolete.
(78.12 KiB) Downloaded 128 times
Last edited by FDARI on Wed May 11, 2011 1:49 pm, edited 3 times in total.
Blzut3
 
 
Posts: 3144
Joined: Wed Nov 24, 2004 12:59 pm
Graphics Processor: ATI/AMD with Vulkan/Metal Support
Contact:

Re: ACS dynamic parameter strings

Post by Blzut3 »

FDARI wrote:PCD_PUSHSTRBUILDER (called before the normal print code)
PCD_SAVESTRANDPOP (called instead of the output code)
Hmm. I'll have to think about this longer, but here's my initial thoughts here: Do you actually need to manipulate the string stack directly here? All print statements (print, printbold, hudmessage, and hudmessagebold) begin with a BeginPrint instruction. At this point you logic can pretty much be "if build is not empty push to stack."  Then just modify all the end instructions to pop the stack if there is something left. It would seem this would fit better into what already exists.
User avatar
FDARI
Posts: 1097
Joined: Tue Nov 03, 2009 9:19 am

Re: ACS dynamic parameter strings

Post by FDARI »

Making the push and pop implicit might be worth the time. The easy way to do that is to push and pop on all operations (seems wasteful for all the existing output calls that don't need it). A more complex approach is to push whenever work contains data, and pop whenever stack contains stringbuilders.

Until now there has been no need to clean up the string-builder; I think it will usually contain the result of the last print-job until you call BeginPrint. BeginPrint will not be able to distinguish between residual data and in-construction data. That means that all operations might push strings to stack this way (needlessly). That means all operations will need cleanup code.

In such a scenario we could reduce the amount of push/pop-ing by having an implicit "" at the bottom of the stack. (If stack empty, assign ""; otherwise pop.)

That, coupled with cleanup after all string generations, will make sure we don't push when it isn't necessary.

EDIT: If there is already something on stack, we can't not push the empty string to stack when we start a new one, because we are going to pop it on completion (provided that the condition for pop is that there is a string on stack).
Last edited by FDARI on Wed May 11, 2011 2:40 pm, edited 1 time in total.
User avatar
FDARI
Posts: 1097
Joined: Tue Nov 03, 2009 9:19 am

Re: ACS dynamic parameter strings

Post by FDARI »

Added ZDOOM_ACC_StrParam_implicit.zip to first post. Details in edited note at the end.
Blzut3
 
 
Posts: 3144
Joined: Wed Nov 24, 2004 12:59 pm
Graphics Processor: ATI/AMD with Vulkan/Metal Support
Contact:

Re: ACS dynamic parameter strings

Post by Blzut3 »

OK, I think this should work for me. I think it should also be safe, albeit senseless, to ignore the return value from the function now. The only thing I can suggest is calling it something else, maybe strprint.
User avatar
FDARI
Posts: 1097
Joined: Tue Nov 03, 2009 9:19 am

Re: ACS dynamic parameter strings

Post by FDARI »

My strongest reason for not supporting "strparam" as a statement (unassigned function call) is that it would require an additional pcd-instruction for zdoom.exe: Add the string to the temporary library without putting the result value on the acs-value-stack. (As far as I can tell, all code that exists before this submission would exit with a stack size of 0, and I want to maintain that level of orderliness.)

I can add the instruction PCD_SAVESTRING_VOID to perform this operation.
As for the function name: Anything will to. SPRINT would be meaningful to some. I still want the name to remind you, however, that the string is not a lasting reference.
Blzut3
 
 
Posts: 3144
Joined: Wed Nov 24, 2004 12:59 pm
Graphics Processor: ATI/AMD with Vulkan/Metal Support
Contact:

Re: ACS dynamic parameter strings

Post by Blzut3 »

FDARI wrote:My strongest reason for not supporting "strparam" as a statement (unassigned function call) is that it would require an additional pcd-instruction for zdoom.exe: Add the string to the temporary library without putting the result value on the acs-value-stack. (As far as I can tell, all code that exists before this submission would exit with a stack size of 0, and I want to maintain that level of orderliness.)
Actually there exists a Drop instruction which could be called to remove the value from the stack.
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
Posts: 49067
Joined: Sat Jul 19, 2003 10:19 am
Location: Germany

Re: ACS dynamic parameter strings

Post by Graf Zahl »

... and precisely that is done for any other function with a return value that's called as a statement.
User avatar
FDARI
Posts: 1097
Joined: Tue Nov 03, 2009 9:19 am

Re: ACS dynamic parameter strings

Post by FDARI »

There, I fixed it. And this time, you don't have to download my intellisense database along with the rest of the project.

On the subject of PCD_DROP: Is it supposed to set the result value?

Code: Select all

    case PCD_DROP:
    case PCD_SETRESULTVALUE:
        resultValue = STACK(1);
        sp--;
        break;
How about doing

Code: Select all

    case PCD_SETRESULTVALUE:
        resultValue = STACK(1);
        // fall-through
    case PCD_DROP:
        sp--;
        break;
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
Posts: 49067
Joined: Sat Jul 19, 2003 10:19 am
Location: Germany

Re: ACS dynamic parameter strings

Post by Graf Zahl »

I'll leave that one to Randy. But I think you are correct. This doesn't look right.
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
Posts: 49067
Joined: Sat Jul 19, 2003 10:19 am
Location: Germany

Re: ACS dynamic parameter strings

Post by Graf Zahl »

Added.

What would be cool now is an actual strcpy function so that copying such a string to an ACS array doesn't have to do it in a loop itself.
User avatar
FDARI
Posts: 1097
Joined: Tue Nov 03, 2009 9:19 am

Re: ACS dynamic parameter strings

Post by FDARI »

That looks a little like a feature suggestion, there. I think we have all the bits and pieces required for a strcopy (one new PCD and a new token to ACC). Because it needs to reference a whole array (its last dimension) it can probably not use a standard function definition, and must be built as a token (print and strparam are tokens in ACC). ZDoom-side another PCD is required.

The hard part is (hopefully) done by now.

Let's discuss STRCPY.

Minimum information: One string (int), one array reference.
Possible information: Source start index. Destination start index. Number of characters to copy.
Required return information: None
Possible return information: Result state (failure, success, or more specific information), or number of characters copied.

Handling of special cases:
* Number of characters to copy exceeds actual number of characters. Proposition: Copy actual number of characters. Return indicates success.
* Number of characters to copy exceeds available space in destination. Proposition: Skip or Fill array. Return indicates incomplete operation/failure.

This function should probably be designed with ACC++ in mind, since ACC++ will perform much array/string work. I'm very interested in what those developers want.

Possible definition of standard ACC.EXE function/token:

bool strcpy(str sourceString, array destination [, int sourceIndex [, int destinationIndex [, int count]]]);

Return true if data is copied, false if data could not be copied.
Blzut3
 
 
Posts: 3144
Joined: Wed Nov 24, 2004 12:59 pm
Graphics Processor: ATI/AMD with Vulkan/Metal Support
Contact:

Re: ACS dynamic parameter strings

Post by Blzut3 »

Given that we have 3 pcodes for printing arrays:
printmapchararray(index, offset)
printworldchararray(index, offset)
printglobalchararray(index, offset)

We would probably need to do the same for strcpy. One thing to keep in mind is that ACS does not have multi-dimensional arrays at the VM level (as far as I can tell anyways). So with that in mind:

void strcpy(array destination, str source[, int srcoffset [, int count]])

`array destination` would actually push two values the array index and the offset. The type of array would be determined by the instruction. strcpyglobalarray, strcpyworldarray, or strcpymaparray.

I don't think a return value is needed, since it should never return a failure for global/world arrays (they are ever expanding). For map arrays it should print an error to the console (and possibly terminate the script).
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
Posts: 49067
Joined: Sat Jul 19, 2003 10:19 am
Location: Germany

Re: ACS dynamic parameter strings

Post by Graf Zahl »

Blzut3 wrote: (and possibly terminate the script).

Better not.


FraggleScript does that for any kind of error and the problems caused by such aborts are often worse than letting the script continue, even when testing.
User avatar
FDARI
Posts: 1097
Joined: Tue Nov 03, 2009 9:19 am

Re: ACS dynamic parameter strings

Post by FDARI »

Any function that can legally* fail should be able to inform the caller of the outcome. ACS offers no error management, so the only viable information path is the return value. I really do want the return value to give an unambigous message about the outcome of that function. The ACS-coder is responsible for caring and testing the outcome.

From the above, 3 pcodes seems likely. Means to specify exact starting points may already be present for all three types (as opposed to an array + an offset in two different parameters). Internally in zdoom.exe we may represent it as destination, source, srcoffset, count. To the user, however, I don't want the starting point in the array to be a part of the array-parameter, as it is confusing. I would have ACC.EXE work the offset into the array-specification.

*By legally I mean: Not caused by an actual bug in acc.exe or zdoom.exe.
Post Reply

Return to “Closed Feature Suggestions [GZDoom]”