• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

LuckyParser: an abandoned JASS parser concept

Should JassHelper be updated?


  • Total voters
    56
Status
Not open for further replies.
If you use procedures to write your code you can increment a global variable each time the procedure is run, and that global would more or less tell you how many times the "function" is called. During the compile-time's optimization process, there will be some scans to kill all unreferenced variables and functions. So making a bunch of function wrappers is not going to burden the map file size, they will simply inline and be deleted.
 
Level 3
Joined
Jun 3, 2010
Messages
47
Y I asked how far that will go.
vJass only supported Inlining of one lined functions.
function wrappers == any function or only functions which call other functions and not natives(whatever).

You are wrong. The point of a wrapper is a function that will call another function with little to no added computation. A wrapper can also be any other kind of programming "object" or feature that you want to wrap. i.e. an AIDS struct as a wrapper for the "missing" feature of unit structs.

Code examples are worth a million words
JASS:
struct Location
    location l
    
    static method create takes real x, real y returns thistype
        local thistype this=thistype.allocate()
        set this.l=Location(x,y)
        return this
    endmethod
endstruct
Location is a wrapping type for location. Create is a wrapping function for Location().

JASS:
struct Trigger
    static readonly integer x=0

    static method CreateTrigger takes nothing returns trigger
        set thistype.x=thistype.x+1
        return CreateTrigger()
    endmethod
endstruct
Trigger.CreateTrigger is a wrapping function for CreateTrigger.

JASS:
function CreateEvent takes nothing returns Event
    return Event.create()
endfunction

derp
 
I will add a configurable constant which allows the user to define how many lines qualify for the function to be inlined. I think an "inline" keyword is just unnecessary. By default, a function with more than "2" lines will not be inlined. Any 2-lined function that does not define any of its own local variables will potentially inline, no matter how many times its parameters are referenced, under the right conditions.

Here's an illustration pointing out the different outcomes:

This will always inline:
JASS:
public real GetTerrainZ(real x, real y):
    loc.move(x, y)
    return loc.getZ()

However this is more tricky:
JASS:
public int Mod(int a, int b):
    return a - a / b * b

The above will inline in this case:

Mod(i, j)


But will not inline in this case:

Mod(t.getEvalCount(), t.getExecCount())

The difference between the second and third illustration is the function calls. Passing arguments that include function calls will call the function dynamically in-game instead of letting it inline. However, using normal variables or array variables will allow the function to inline.

In the illustration, the "Mod" function will be inlined in one part of the script and will be called from another part of the script. So you get the best of both worlds.
 
Level 19
Joined
Oct 15, 2008
Messages
3,231
Nice, will you also be posting a changelog about the changes made?
At least there'll be some information about the Updates periodically..
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
Bribe, i think you are taking too much time for script optimisation, you can do this later, just make luck working, and you could add this stuff later when luck is getting stable.

Plus anyway someone can still make an optimizer apart from luck, and is fairly easy to add (with the JNGP at least)
 
I am in the process of writing a manual for Luck which will will go over the differences from JassHelper. To be fair the end-of-June delivery date may at first be a simple compiler that works similar to Jass Shop Pro instead of interfacing directly with the editor.

Jass NewGen Pack is not open-source yet it needs updates to function properly (like GUI hashtables) so I don't want to integrate this project with it. Having this be a standalone editor will also make it possible to work natively on Macs (which NewGen can't) and not just PCs.

In fact, I can say I will NOT be making this integrate with NewGen. Getting Mac Users into high-level modding is an overall positive thing.

There will be a GUI interface with syntax highlighting and syntax checking, so you could work on your projects even on a computer that doesn't have warcraft 3 installed. And the program would be a lot more responsive than the slow World Editor/NewGen interface.
 
At this time I'm just looking for constructive criticism, moral support and perhaps some technical advice on how to read from & write to a .w3x file because JassHelper uses a very convoluted way to do it and I am certain it doesn't involve hundreds of lines of Delphi code.

And please do not use "lol" as it's a very undefined thing.
 
Last edited:
Extracting and reinjecting wouldn't corrupt any of the files.. why would it?

and what's this about Warcraft 4?
It's just an unofficial update.. why would it be a problem..
As software, WC4 is in no way connected to WC3.

PC might implode

Actually, it would implode, causing the black hole to emerge, then radiate away ^^
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
To be fair maybe he was talking about a map which was saved with the official world editor.
I can't test it right now, but if i remember correctly there is an (attribut) or-something-like-that file which is generated each time you save the map, if you edit the map script with a mopaq browser and doesn't delete this file, the map will be considered as corrupted.
Though, you can simply delete this file and all will be fine, i think that's what jasshelper do.
Ofc in theory i suppose you could recreate this file, but i don't have a fucking idea about the algorithm needed for that.
 
I won't be making a bJass, but in its current stages I consider the parser's name to be LuckyParser.

I've been in the process of re-writing all of my scripts into Luck to find out the best possible combination of readability, easy-to-learn and easy-to-write. Some things have yet changed slightly (more Python-like I think) so I will be shortly updating the first post with a few of those changes.
 

LeP

LeP

Level 13
Joined
Feb 13, 2008
Messages
545
Since you are talking about inlining (and i hope for maybe even other optimisations) some functions under the right conditions i ask you to perform those optimisations on normal JASS and not your programming language.
This gives two benefits:
* It's possible that the generated code gets optimized
* One can use the optimizer for his own language or JassHelper-generated code.

Ofcourse if you do it that way, you have to fully parse not only your language but also normal JASS. But with such tools we could really create some nice toolchains for wc3-dev :)

___________
Another point i wanna talk about:
At first you shouldn't care about MPQ-handling and stuff. Just get the parser done. Test your compiler with a simple setup of text-editor/luck/pjass. Should be enough at first. Also please don't use any GUI for your parser. Just print the errors to stderr. One can later build a GUI for that.

e: random note: vJass stands for veryJass.
 
Last edited:
did you contact vex?

So this jass helper would be a thrid party tool that not injecting to the we?

But we still can edit the map's spell or system?

I'll look forward to this jass shop pro..

1. Of course, contacted Vex, however he does not reply to messages within four months usually.

2. Yes, meaning you can develop your map in NewGen or regular editor or something else and it will not conflict.

3. It will not erase your progress when you save the map with another editor, if that's what you mean. However, it will need to be re-saved using LuckyParser in order for the luck scripts to be re-included.

4. There is a huge surprise waiting to be unveiled to the community on top of the program itself.
 
Level 3
Joined
Jun 3, 2010
Messages
47
Maybe?

JASS:
int Add(int a, int b[, int c[, int d[, int e[, int f]]]]):
    return I2S(a+b+c+d+e+f) # takes advantage of the default value of 0 for integers

print Add(3,4)
print Add(3,5,9,2,5,1)
print Add(2,4,5,6,7,9,1) # error

Just got to shadow functions by adding in the default values for asked for types.

JASS:
# luck
lib Adder:
    int Add(int a, int b[, int c]):
        print a+b+c

    onInit:
        Add(1,2)
        Add(1,2,3)
# endluck

// * these variables should be generated by LuckyParser prior to script optimization
// so that they are destroyed automatically if unused.  Merge globals as the second
// to last process (after final vanilla syntax check) btw

globals
    integer SUPER_DEFAULT_INTEGER  = 0 // fun fact, ALL types in JASS extend these guys
    real    SUPER_DEFAULT_REAL     = 0.00
    code    SUPER_DEFAULT_CODE     = null
    handle  SUPER_DEFAULT_HANDLE   = null
    string  SUPER_DEFAULT_STRING   = ""
endglobals

// * also, globals should not be able to be prefixed by _ in Luck, as they are
// reserved for superglobals (those used by the compiler) and SUPER_ is also
// not allowed, 

// * the above luck code will become this upon compilation, and Luck should also
// do "TriggerAddCondition(_INITTRIG,Condition(Adder__3729_onInit))"

function Adder__3729_Add takes integer a, integer b, integer c returns integer
    return a+b+c
endfunction

function Adder__3729_onInit takes nothing returns boolean // I would hope you are going to use a global boolexpr for initilization functions 
    call Add(1,2,SUPER_DEFAULT_INTEGER) // a third value was not supplied so append one
    call Add(1,2,3) // a third value WAS supplied so do not append one
    return false
endfunction

EDIT The OS X editor better not be ugly.

EDITEDIT Is this correct?

JASS:
lib Example:
    int ReturnHex():
        return 0x10000 # hex is still acceptable as an integer
    
    string ReturnVex():
        return 'Vexorian' # notice the use of single quotes instead of ""

    struct X:
        members:
            int x
            int y
            int z

    int ReturnX():
        return new X
 
Last edited:
Level 17
Joined
Apr 27, 2008
Messages
2,455
One simple feature you could add is to give a default value in a global declaration if there is none, and if it's a native function then set in the main function (avoid wc3 crash like GetLocalPlayer(), or just make it work like Rect(...) )
 
I feel that initializing globals should still be done by the user. There is some efficiency to gain by not initializing those globals. That's part of the reason why GUI variables are so bad because they initialize groups and timers even if you may not want them to. And I couldn't find a way to make it NOT initialize arrays, which is silly.

Code:
lib Example:
    public:
        int ReturnHex():
            return 0x10000 # I would never remove Hex, it is too cool
        
        int ReturnOct():
            return 0o42 # Octal is written differently because 042 is bad convention.
        
        str ReturnVex():
            return 'Vexorian' # single quotes work just fine although it is treated more literally
            # the only character you need to escape is (') making it easy to c&p a model path
            # into this type of string.
    
        class X: # Class replaces struct altogether.
            public: # For readability, you need to declare the privacy of all non-local variables
                int x, y, z # You can declare things like this, too
    
        int ReturnX(): # public is required
            return X.create() # I will not be using "new" nor "delete"
 
Level 20
Joined
Jul 6, 2009
Messages
1,885
You could add an option to assign a value to globals directly upon declaring them. I know it's impossible in JASS, but it's not hard to, upon compiling, create a function that would run on init and set values of variables (or add them to an Init function that i guess already exists).
 
Status
Not open for further replies.
Top