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

New compiler: Initializer functions for new #2529

Open
wants to merge 6 commits into
base: ags4
Choose a base branch
from

Conversation

fernewelten
Copy link
Contributor

@fernewelten fernewelten commented Sep 9, 2024

Please test this!
Please note that this PR relies on the PR #2528.

Managed structs can have an initializer: i.e, a struct function that must be named initialize.

  • The initializer must return void (or int so that it is possible to define it with the function keyword).
  • It can have any parameters or none, but note that we don't have overloaded functions in AGS yet, so when you define a parameter list for an initializer then you must stick with it forever.

When a struct has an initializer that the compiler knows about, the compiler will insert a call to this function directly after an object has been created with new. You must give the parameters for the function call directly after new XX, the compiler will no longer allow you to create objects of that type without any parameter ist.

On the other hand, when a struct does not have an initializer function, you can use new on it either with an empty parameter list or without any parameter list.

managed struct Stx
{
    int Payload;
    import function initialize(float f);
};

managed struct Sty
{
    short Payload;
};

function game_start()
{
    Stx *st1 = new Stx(7.0); // ← okay
    Stx *st2 = new Stx(7); // ← syntax error, parameters don't match
    Stx *st3 = new Stx(); // ← syntax error, parameter expected but not found
    Stx *st4 = new Stx; // ← syntax error, parameter list missing

    Sty *st5 = new Sty(); // ← empty list is okay, nothing will be called
    Sty *st6 = new Sty; // ← okay
    Sty *st7 = new Sty(4); // ←syntax error
}

– Call `cc_compile(input, options, scrip, message_handler)` instead of  `cc_compile(input, scrip)`
– Read the error and warning(s) that the compiler issues from the `message_handler` instead of from static variables
– Avoid `ccSetOption()`, pass the respective options directly to the compiler so that they are safe from being clobbered before the compiler can read them
– Avoid reading the static variables `currentline` and `ccCurScriptName`
Make googletests use the new compiler calling convention
use `compile(source, options, scrip, messages)`
Provide the bytes that the test should generate
@ivan-mogilko
Copy link
Contributor

ivan-mogilko commented Sep 9, 2024

This would be a great addition!, but I am bothered by the chosen hardcoded name initialize.

What was a reason to use this name?
Would it work if a classic constructor-like syntax was used instead, where the method has the same name as a struct?

@ivan-mogilko ivan-mogilko added ags 4 related to the ags4 development context: script compiler labels Sep 9, 2024
@fernewelten
Copy link
Contributor Author

fernewelten commented Sep 9, 2024

Would it work if a classic constructor-like syntax was used instead, where the method has the same name as a struct?

We could have it that way, too.

Something along the lines of the following?

managed struct Stx
{
    int Payload;
    import void Stx(float f);
};

@ivan-mogilko
Copy link
Contributor

ivan-mogilko commented Sep 9, 2024

I also propose that constructor should be enforced to be void, because there's no purpose for its return value (and no way to receive it).

I'd even say that it should be typeless, but idk if ags script can handle that now.

@fernewelten
Copy link
Contributor Author

fernewelten commented Sep 9, 2024

IIRC correctly, this started when someone (I think ericoporto Edit: no, was you @ivan-mogilko ) noted that the old compiler allowed the syntax new Strct() without doing anything with the pair of parens or the info in between.

So the first remedy was to make the new compiler accept this syntax, too, so that it could grok ‘old’ code. But I stuck a warning into it that this wasn't really implemented yet.

At that time, I brought up the idea to have an initialize function that would be called with the parameters between the parens whenever a struct would have such an initializer.

We hadn't decided on anything definite yet, and as I said, the old compiler seemingly doesn't do anything whatsoever with this syntax.

See it more as a proposal than as a definite decision on any specifics.

@fernewelten
Copy link
Contributor Author

fernewelten commented Sep 9, 2024

Edit: Here's the thread.

#2174
#2181

@ivan-mogilko
Copy link
Contributor

I tested this, and it works in principle.

But, as I mentioned previously, in my opinion, the "initializer" should rather comply to classic constructor syntax, where:

  • it must have a name identical to the struct's name;
  • it should have either strictly void type, or no declarable type at all;
  • it should not be permitted to call this function directly from script (it is possible to call it currently).

@fernewelten
Copy link
Contributor Author

Okay, thanks for testing and thanks for the feedback.

I'll take that as a “go” and implement the modifications you suggest, within this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ags 4 related to the ags4 development context: script compiler
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants