Jump to content

Recommended Posts

Hi all!

 

I was going to write a post later. But I replied to a message in the nearby discussion anyway. So... :smile:

 

I made UE3 compiler and decompiler with a handy utilities set. Part of the utilities are using UPKTools as a backend (thanks to wghost81 for a such good tool set!).

I'll release it soon. So no more problems with integers or floats, etc. anymore. :smile:

 

Example tokens:

 

float: FloatConst(("0.4059738695"))

integer: IntConst(("2325839"))

integer HEX: IntConst((09 0f 04 a0))

string: StringConst(("良いセット Ывдлфо адЦыфо у sljf aeOirJa rfjh "))

auto label: @to_label(35)

named label: @to_label("Script Ret")

 

Code between /*DESCRIPTION_BEGIN*/ and /*DESCRIPTION_END*/ tags is for a dev-helping purposes and ignored by a compiler.

 

Example of formatted code:

Divide_FloatFloat(
    IntToFloat(
        InstanceVariable(
            (IntProperty'XGAbility_Targeted.m_iHitChance')
        )
    ),
    FloatConst(
        ("27.0")
    ),
    EndFP()
)

Example mod:

 

Using this compiler I made http://www.nexusmods.com/xcom/mods/663/?. You may use it as an example.
Source code you can see and download here:

https://github.com/FI-Mihej/Realistic-Damage-Model-mod-for-Long-War

 

UCB source code files can be highlighted by https://github.com/FI-Mihej/UCB-Source-Code-highlighter

Edited by FieryIce
Link to comment
Share on other sites

Very cool! Mnemonics for complex expressions, especially complex ones like &&, || etc will be a huge time saver. I almost always forget the skip offset or put the parens in the wrong place or miss a 0x16 somewhere and spend 15 minutes scratching my head staring at the code to figure out what's wrong.

 

But it looks like you've got embedded disk/memory offsets back in there, is that right? It's late but I can't figure out what they're for, cause you still seem to have label support. Are they just tokens inserted into the decompiled code as annotations like the comments inserted by hex2pseudocode, or are they actually used for something? Going back to manually computing jump offsets isn't something I'd look forward to...

 

That aside, this is great, great stuff, thanks for sharing!

Link to comment
Share on other sites

>>Mnemonics for complex expressions, especially complex ones like &&, || etc will be a huge time saver​

 

Yes - maybe I'll do it in the future.

 

>>I almost always forget the skip offset or put the parens in the wrong place or miss a 0x16 somewhere and spend 15 minutes scratching my head staring at the code to figure out what's wrong.

 

When I forgot to end function arguments with EndFP() - I made compiler warnings subsystem. :smile: It's really helpful. Plus there is decompilation of compiled part of code - so you'll see where is an error exactly.

 

Currently there are 5 possible errors:

"Didn't found Right Quote after position {}"

"Unresolvable name reference "{}" in this expression: ({})" - for InstanceVariable((lalala_wrong_name))

"MAYBE you forgot one or more "EndFP()" tokens in this expression: ({})" - when the next expected parameter was not found

"Unknown token name "{}" in this expression: ({})" - for wrong token like IntToWrong()

"Param "{}" of Token "{}" has a Value Error "{}" in this expression: ({})" - when you'll try something like IntConst(("0.0043"))

 

As for parens: parens are just removed from the code before parsing started. In most cases, compiler uses them only to separate tokens. You may use spaces instead of parens and commas (except of HEX values). But such source code will probably lose its readability and editability: text editors are usually able to show the pair bracket for easy coding process. But I think I will experiment with Python-like style (without brackets).

 

Also I think of to get rid of the EndFP() token at all in the future. But in order to do this I will have to make noticeable changes in the process of parsing. And as result incorrect placement of the brackets will lead to errors. So I'm not sure about this yet.

 

>>disk/memory offsets

 

They are just an annotations. I made them before I made labels. Now, this annotations are really not very useful (except for debug purposes maybe). So I think, I'll remove whole Description block from the decompiled code.

 

>>That aside, this is great, great stuff, thanks for sharing!

 

​You're welcome! :smile:

Link to comment
Share on other sites

Ah, parens are ignored. That explains things. My personal preference would be for parens around directives to be meaningful, and this would also allow you to get rid of EndFP as it is then unambiguous where each subexpression ends.

 

E.g. if I could write foo().bar(a + 2, b) as something like context(virtualcall(foo), virtualcall(bar, plus_intint(local(a), intconst(2)), local(b))). EndFP can be automatically inserted into the right places for the calls and the add. Not sure if you can handle variable argument lengths or not, which are needed for the calls.

 

Aside: I work in compilers so I am happy to help if you run into parsing problems :)

Link to comment
Share on other sites

>>My personal preference would be for parens around directives to be meaningful, and this would also allow you to get rid of EndFP as it is then unambiguous where each subexpression ends.

>> E.g. if I could write​...

I thought about it​ and yes - I can get rid of EndFP in this way without making big changes to compiler and decompiler. I'll do it: indeed, it would be more convenient than Python_style + EndFP.

 

 

>>Aside: I work in compilers so I am happy to help if you run into parsing problems :smile:

 

OK, thanks! :smile:

Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...