• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[Lua][vJass] Convert vJass to Lua with NotePad++ Macro

Status
Not open for further replies.

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,464
I've just published a fairly-refined version of a vJass-to-Lua macro intended to be used with NotePad++. It's lightweight, extremely fast and reversible with a simple Ctrl+Z.


The JASS version is nearly finished (the globals block is annoying to deal with and currently requires users to manage their code somewhat if they declared globals without an initialization value).

The vJass version works fairly well. I intend to do more with enabling method operators and converting "this" to "self" in non-static methods, and also intend to support hooks and properly-comment-out native declarations. Those are on my to-do list and will get done either today or tomorrow.

Overall, it's extremely handy, lightweight and fast. I've compared it to cJass2Lua:

1) cJass2Lua is flagged as a virus upon running for the first time, whereas this is just an XML file used to direct a NotePad++ macro.
2) cJass2Lua is about 200 times slower at parsing text (regex search and replace is absolutely destroying it in terms of performance).
3) cJass2Lua will just stop working if it encounters code it doesn't like, such as modules. This tool will just ignore things it doesn't understand.
4) cJass2Lua is incredibly painful to work with (spaghetti code) and requires re-compiling each time a change needs to be made. This just requires the XML be saved and NotePad++ reloaded.
5) cJass2Lua kills several vJass behaviors such as modules, function interfaces, but doesn't know what to do with them. I intend to support every popular vJass feature and have it compiled to its Lua equivalent (using vJass-style-struct where necessary).
6) cJass2Lua first converts your vJass to cJass, then it converts it to JASS, then converts it to Lua. This keeps the syntax vJass-y by skipping those 2 middle points.
7) cJass2Lua: almost 1MB and many thousands of lines of code. Barely any comments within the code makes it hard to tell what it's doing. However, this XML file is so short and straightforward that anyone should be able to pick it up and copy/edit elements within it to do what they need.

I'm extremely proud of this thing and am surprised at how easy it was to make it work. I didn't know anything about Regex until yesterday when I started digging around, and now I have translated an entire programming language using these newly-acquired skills.

I recommend this tutorial for anyone who wants to have a go at understanding/making changes to the regex code: Regular Expression Tutorial - Learn How to Use Regular Expressions

I would be curious to know if anyone here is familiar enough with regex to know if I can do what I'm doing with functions parameters without cloning the same code repeatedly whenever a new parameter is added. I can't really determine how/if function calls are supposed to work within the NotePad++ find/replace engine.
 
Level 18
Joined
Jan 1, 2018
Messages
728
Haven't used cjass2lua so I don't know how slow it is but 200x faster sounds very impressive.
Now I'm wondering how it compares to my tool/library: Map Transpiler

I'll be honest though I don't think regex is very suitable for a task like this, it may work mostly because jass and lua are quite similar, but you'll run into issues in more complex situations, for example:
JASS:
local string s = "this is not a \\"//comment\\"" // this is a comment
Other examples are string concatenation and integer division. Depending on the types of the operands you need to transpile '+' to '..' and '/' to '//'.
For this you need to also parse common.j and Blizzard.j to know all the variable types and function return types.
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,464
Haven't used cjass2lua so I don't know how slow it is but 200x faster sounds very impressive.
Now I'm wondering how it compares to my tool/library: Map Transpiler

I'll be honest though I don't think regex is very suitable for a task like this, it may work mostly because jass and lua are quite similar, but you'll run into issues in more complex situations, for example:
JASS:
local string s = "this is not a \\"//comment\\"" // this is a comment
Other examples are string concatenation and integer division. Depending on the types of the operands you need to transpile '+' to '..' and '/' to '//'.
For this you need to also parse common.j and Blizzard.j to know all the variable types and function return types.
Honestly, the syntax similarities between Lua and vJass are precisely why regex is the most logical option at handling 99% of the workload. The same could not be said, however, at converting Lua code to vJass code. And it would be nearly impossible to convert bracket-based syntax like Zinc or cJass with using regex search/replace.

The rare situations that you mentioned will not be able to be efficiently caught with regex, but they could be captured nevertheless when just looking over the code. I have factored in concatenation which involves strings with quotation marks, but even cJass can't parse all strings despite having access to the types of all declared variables.

Additionally, it is nearly impossible for a transpiler to convert vJass textmacros into anything meaningful, so I've turned those into blockquotes.

Integer division is an important point to note. This definitely will not be able to automate those and will be noted in the documentation.

In fact, keywords within strings and comments are not currently ignored by the parser, so it will explode those as well.

I'm not sure what your map transpiler does beyond amending the war3map.w3i and switching the language file of war3map.j to .lua. Is your script currenty parsing JASS syntax into Lua, or just doing the file management part? Based on your desciption and the comments on the thread, it is unclear.

My ultimate goal here is to cut down as much as possible on time spent converting a file, but it is clear that it is not possible to dot every single i and cross every single t. I was hoping I could lean on cJass2Lua a bit for this, but the tool isn't being maintained and it's an absolute mess to try to sift through the convoluted source code behind it to try to make more vJass functions work. Not to mention, even if I got them to work, there's still the problem of everything getting compiled into cJass. I estimate it would take about 100 of my hours for getting modules and everything to not break, and then probably 500 hours of my time to make sure that everything compiles perfectly from vJass.

It made sense to start a project from scratch, and since I had already been in the habit of using find&replace on many different things in the map, I found this method to be, by far, the most convenient for most use cases. Debugging is an absolute breeze, since I can test regex searches in real time and I can apply patches just by saving the xml file, quitting and re-opening NotePad++.
 
Level 18
Joined
Jan 1, 2018
Messages
728
Honestly, the syntax similarities between Lua and vJass are precisely why regex is the most logical option at handling 99% of the workload. The same could not be said, however, at converting Lua code to vJass code. And it would be nearly impossible to convert bracket-based syntax like Zinc or cJass with using regex search/replace.
Agreed, the similarities make it very easy, but if you need a better tool for the remaining 1% you might as well use it for the full 100% of the workload (I mean I can't imagine mixing regex into the codebase of my transpiler library).
I was thinking of lua back to (v)jass as well, but even simple things like end would be a nightmare with regex because it could be endif, endloop, endfunction, etc.

The rare situations that you mentioned will not be able to be efficiently caught with regex, but they could be captured nevertheless when just looking over the code. I have factored in concatenation which involves strings with quotation marks, but even cJass can't parse all strings despite having access to the types of all declared variables.

Additionally, it is nearly impossible for a transpiler to convert vJass textmacros into anything meaningful, so I've turned those into blockquotes.

Integer division is an important point to note. This definitely will not be able to automate those and will be noted in the documentation.

In fact, keywords within strings and comments are not currently ignored by the parser, so it will explode those as well.
It's good to make note of the limitations, I can imagine solving these with regex would be difficult to say the least.

I'm not sure what your map transpiler does beyond amending the war3map.w3i and switching the language file of war3map.j to .lua. Is your script currenty parsing JASS syntax into Lua, or just doing the file management part? Based on your desciption and the comments on the thread, it is unclear.
The tool is a thin wrapper around my transpiler library which handles parsing common.j and Blizzard.j for the type information, replacing war3map.j with the transpiled war3map.lua, and updating the map's war3map.w3i to set the scriptlang to lua. The transpiler library parses the jass syntax (actually this is in a separate parser library) and transpiles it to lua, including handling the string concat and integer division cases I mentioned.
The tool only works with maps but if you wanted you could use the library directly, for example if you only want to convert a standalone jass file (there is a code example for this in the library's readme).
Also note that vjass syntax is not supported, but I'm working on a parser for that as well and then a transpiler from vjass to C#. Your threads actually motivated me to spend time on this so thanks for that.

My ultimate goal here is to cut down as much as possible on time spent converting a file, but it is clear that it is not possible to dot every single i and cross every single t. I was hoping I could lean on cJass2Lua a bit for this, but the tool isn't being maintained and it's an absolute mess to try to sift through the convoluted source code behind it to try to make more vJass functions work. Not to mention, even if I got them to work, there's still the problem of everything getting compiled into cJass. I estimate it would take about 100 of my hours for getting modules and everything to not break, and then probably 500 hours of my time to make sure that everything compiles perfectly from vJass.

It made sense to start a project from scratch, and since I had already been in the habit of using find&replace on many different things in the map, I found this method to be, by far, the most convenient for most use cases. Debugging is an absolute breeze, since I can test regex searches in real time and I can apply patches just by saving the xml file, quitting and re-opening NotePad++.
Don't want to advertise my own stuff too much in here since this thread is about your tool not mine, but if you know some C# you could check out my libraries, hopefully the source isn't as messy as cjass2lua.

IMO if you want to minimize the time needed to convert you need to cover all edge cases with the converter so no manual edits are needed, I don't think it's possible with regex but if it works for you on simpler jass scripts that's great.
 
Status
Not open for further replies.
Top