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

Compiler struct support #1518

Merged
merged 14 commits into from
Jun 2, 2024
Merged

Conversation

CST1229
Copy link
Contributor

@CST1229 CST1229 commented Nov 12, 2023

Resolves #1084

Description

Adds support for GMS2.3+ structs in the compiler, cherrypicked from UndertaleModTool Community Edition with some additional minor changes.

UndertaleModTool_ZKdJpFd2rT.mp4

Also fixes a bug where an empty struct definition would cause all assignments after to also be struct-styled, causing syntax errors when recompiling.
a = {}; b: 123

Caveats

___struct___ can no longer be used at the start of a function definition name, as parts of the compiler and decompiler assume that the ___struct___ prefix means a struct.

Notes

I've only tested this on one GMS2022.9 game (Pizza Tower), but it seems to work there. You may want to squash this PR if you don't like some of my ridiculous commit names. (Also, I'm not super experienced with C# or this project's code style so there probably are some things that need to be looked at.)

just need to add support for passing arguments into structs and stuff
This commit adds variable leaking for structs (basically, it lets you use other variables in structs). It also fixes compiled structs crashing the game.
Removes some extraneous whitespace,
removes some unnecessary comments and adds a few
- Remove the fit-into-my-window-size linebreak in one of the comments
- Remove braces from one of the if statements I modified
Copy link
Contributor

@Miepee Miepee left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i dont have any experience with that part of the codebase at all, so just a few cents

UndertaleModLib/Compiler/Compiler.cs Outdated Show resolved Hide resolved
UndertaleModLib/Compiler/Compiler.cs Outdated Show resolved Hide resolved
UndertaleModLib/Compiler/Parser.cs Outdated Show resolved Hide resolved
UndertaleModLib/Compiler/Parser.cs Outdated Show resolved Hide resolved
- Code formatting
- Use `is not null`
- Add TODO
@Miepee
Copy link
Contributor

Miepee commented Nov 12, 2023

Also can you add fixes #1399 to the inital PR description please?

@CST1229
Copy link
Contributor Author

CST1229 commented Nov 12, 2023

Also can you add fixes #1399 to the inital PR description please?

That issue seems more like it's about struct.func() calls, which this PR does not resolve. This just deals with struct definitions ({}).

Comment on lines +66 to +75
Data.Scripts.Remove(scriptObj);
UndertaleCode codeObj = Data.Code.ByName(scriptName);
if (codeObj is not null)
{
Data.Code.Remove(codeObj);
OriginalCode.ChildEntries.Remove(codeObj);
}
UndertaleFunction functionObj = Data.Functions.ByName(scriptName);
if (functionObj is not null)
Data.Functions.Remove(functionObj);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these instances of Data.X.Remove() safe?

Copy link
Contributor Author

@CST1229 CST1229 Nov 12, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be if you're just normally adding and removing struct definitions, as each struct definition gets its own function, the compiler currently won't let you create ___struct___ functions and I'm fairly sure code, script and function references are all passed by reference instead of ID. But I'm not sure.
(If we don't remove unused struct functions, then adding then removing a struct definition would cause an Unable to find function error when launching the game.)

foreach (UndertaleCode child in context.OriginalCode.ChildEntries)
{
if (child.Name.Content.StartsWith("gml_Script____struct___"))
usableStructNames.Enqueue(child.Name.Content["gml_Script_".Length..]);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this entirely exhaustive? Depending on case, structs may not start with this, i.e. if embedded inside an anonymous function (anon part comes first in those cases). Although, I'm unsure if anonymous functions are supported by this compiler right now anyway.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Depending on case, structs may not start with this, i.e. if embedded inside an anonymous function (anon part comes first in those cases).

At least from my tests in GMS2022.9, that does not seem to be the case (although it might be different in earlier or later versions).
image

Although, I'm unsure if anonymous functions are supported by this compiler right now anyway.

Sort of, but they don't work that well.
image
image

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIK there's an open issue somewhere about anonymous functions, to my understanding their status essentially boils down to "unsupported/not working"

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK so I further investigated this, and I found out that the code entries I saw were just anonymous functions declared inside of structs, which aren't themselves structs, so this check is fine!

This is a workaround for deeper-down issues with local variables which UTMTCE fixes, but is probably better off being left for another PR
@colinator27
Copy link
Member

I temporarily ported these changes over to my new decompiler fork (almost verbatim), and it seems to work great there!

@colinator27 colinator27 merged commit 36104b1 into UnderminersTeam:master Jun 2, 2024
5 checks passed
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

Successfully merging this pull request may close these issues.

GameMaker struct type compiler support
4 participants