• 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.

[Parser] JASP

Status
Not open for further replies.
Level 3
Joined
Sep 12, 2011
Messages
47
logoran.png
- small preprocessor for Jass2 that executes before vJass parser (JassHelper). Full info is available in manual, all the links are below.


 
Warning!
The declaration of variables like that is supported only for this types:
timer
group
force
region
trigger
dialog
leaderboard
multiboard
quest
texttag
camerasetup
hashtable
Idea is nice, but is this really needed.
First of all some variable types are missed.
unit for example can't be declared like this.
But at the other hand you can remove and null it with flush thing.

free and flush can be merged into 1, because you always use them both.

Dunno about others but I won't use this until you don't configure all variable types.

Multiple global variable declaration
Awesome idea, dunno why something like this wasn't included by Blizzard.

Loops 'repeat until'
Sometimes we don't want loop to happen even once if conditions aren't true.
Also your method isn't really much easier.
C/C++/C# like for loops are my choice.
Also Pascal has loops that are much similar to wc3 GUI. Maybe you can include both.

Untypified variables
Nice job, cool idea.
Can be faster for writing small systems or scripts, but again not good idea for public resources.

There is still work to be done.
 
Level 7
Joined
Apr 30, 2011
Messages
359
excuse me,
but what's Jass2 ?_?

edit: understood :)

now, that is really good :D
i'd like to see multi-type variables,
change those var things so that it can store multiple variables
parsed to multiple variables . .
and create and free, it isn't really useful (it only shorten things)
instead add something to replace pointers (can be private)
example:
JASS:
library Test
    private pointer GetTriggerUnitReal replace GetTriggerUnit
    
    // if this function is not a private one, it will show an error :D
    // since the pointer replacement is private
    private function GetTriggerUnit takes nothing returns unit
        return GetTriggerUnitReal()         // this call the native
    endfunction
    
    function Test takes nothing returns nothing
        local unit u = GetTriggerUnit()     // will call the function above
                                            // not the native
        // . . . . .
    endfunction
endlibrary

and Just Another Script Preprocessor is a good name :D
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
Cut the (v)jass verbosity is one thing, but jass is really typed, so make it "like" (in some way) php is quite weird.
Personnaly i prefer to write the type of the variable, i mean the code is clearer to read and you don't win that much anyway, as you have to declare a variable only one time and then use it multiple times.
Plus, usually, most of code is not variable declaration, it's even negligible.

My 2 cents.
 
Level 7
Joined
Apr 30, 2011
Messages
359
You can use cJass defines and macros. Example:
JASS:
define
{
    <GetTriggerUnit> = GetTriggerUnitReal
}

void test()
{
    unit u = GetTriggerUnit()
}

i'm searching for ones that don't use { }, void, define, etc . .
i search for ones in vjass way D:

and maybe more things other than call/set to come :D

other ideas:
JASS:
library Test
    
    // setreal = sets the real variable of ones taken as arguments
    
    // commands can be used like set/call
    // multitakes must only have one argument taken
    // using format:
    //      free YourVar1, YourVar2, YourVar3, . . .
    private command free multitakes var v
        if var.type == handle then
            setreal v = null
        elseif var.type == boolean then
            setreal v = false
        elseif var.type == string then
            setreal v = ""
        else
            setreal v = 0
        endif
    endcommand
    
    // using format:
    //      swap YourVar1, YourVar2     (no more, no less)
    private command swap takes var v1, var v2
        local var s = v1
        
        setreal v1 = v2
        setreal v2 = s
        
        free s
    endcommand
    
    // commandchar(s) are characters that must be inserted for a requirement of the command
    // using format:
    //      make UnitVariable = UnitId [X, Y]
    private command make takes unit u, commandchar =, integer id, commandchar [, real x, real y, commandchar ]
        setreal u = CreateUnit(Player(15), id, x, y, 270)
    endcommand
    
    // Testing function
    function Test takes unit u returns nothing
        local unit u1 = GetTriggerUnit()
        local unit u2 = GetSpellTargetUnit()
        
        swap u1, u2 // swap values
        free u1, u2 // null variables
        
        // these two will be merged above with u1 and u2
        local real x = 999
        local real y = 111
        
        make u1 = 'hpea' [x, y]
        swap x, y
        swap u1, u2
        make u1 = 'Hblm' [x, y]
        free u1, u2
        
        call RemoveUnit(u)
    endfunction
    
    returnhook CreateUnit Test  // Test will be run everytime CreateUnit is called
                                // Test must takes one argument with the same type
                                // as the hooked function returns
endlibrary
 
Here's what I like:

JASS:
integer Example(integer i, real z, unit v) {
    handle h

    GetTriggerUnit()
    h = null
}

// For encapsulation, this would seem nice:

// Exactly what vJass offers:
private function
public function
readonly integer
readonly handle


// Accessible everywhere:
function

// For globals, free declarations just like C++ would be nice.

edit
Then again, that sounds quite similar to cJass :L
 
Level 7
Joined
Apr 30, 2011
Messages
359
JASP isn't vJass expansion but is separate preprocessor. He is generally not using vJass features so I think I won't implement any vJass-expanding features.

too bad . . .
but it won't be as confusing as cJass right?
and will have about the same view as Jass or vJass?
 
not bad but the only thing I like is the one line local declaration and nullings, on the other hand I hate the global's other declaration method, seems a waste of time typing...
JASS:
globals
	hashtable hash = InitHashtable()
endglobals

JASS:
function someFunc takes nothing returns nothing
	global hashtable hash = InitHashtable()
endfunction

now which is the easiest way to see and type?...
 
Level 3
Joined
Sep 12, 2011
Messages
47
Maybe
JASS:
new global hashtable hash
;)
And, of course, you can use this outside of function / method / scope /library

//=============================================

New feature: replace functions
JASS:
    mount GetTriggerUnit to GetSpellTargetUnit
    var u = GetTriggerUnit()
    unmount GetTriggerUnit from GetSpellTargetUnit
    var us = GetTriggerUnit()
------>
JASS:
    local unit u = GetSpellTargetUnit()
    local unit us = GetTriggerUnit()
 
Level 3
Joined
Sep 12, 2011
Messages
47
Here is a simple spell written with JASP
JASS:
function Trig_Freezing_Shot_Timer takes nothing returns nothing
//===========================================================================================================================//
//                                                  Local variables                                                          //
//===========================================================================================================================//
    var t = GetExpiredTimer()
    var hid = GetHandleId(t)
    var caster = LoadUnitHandle(hash, hid, 0)
    var dist = LoadReal(hash, hid, 4)
    var count = LoadInteger(hash, hid, -1)
    var dummy, target, angle, x, y, i = 1   
//===========================================================================================================================//
//                                                   Timer actions                                                           //
//===========================================================================================================================//
    if dist <= 750. then
        repeat
            set dummy = LoadUnitHandle(hash, hid, i)
            set angle = GetUnitFacing(dummy) * .017
            set x = GetWidgetX(dummy) + 25. * Cos(angle)
            set y = GetWidgetY(dummy) +25. * Sin(angle)
            call SetUnitPosition(dummy, x, y)
            
            call GroupEnumUnitsInRange(temp, x, y, 75., null)            
            loop
                set target = FirstOfGroup(temp)
                exitwhen target == null
                if IsUnitEnemy(target, GetOwningPlayer(caster)) and not IsUnitType(target, UNIT_TYPE_STRUCTURE) and not IsUnitType(target, UNIT_TYPE_MAGIC_IMMUNE) and GetWidgetLife(target) > .405 then
                    call UnitDamageTarget(caster, target, 100., true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
                    call FastEffect("Abilities\\Weapons\\FrostWyrmMissile\\FrostWyrmMissile.mdl", x, y)
                    call DummycastToTarget(caster, target, 'A001', 852075)
                    call SaveInteger(hash, hid, -1, count - 1)
                    free dummy
                endif
                call GroupRemoveUnit(temp, target)
            endloop
            
            set i = i + 1
        until i > 3
        call SaveReal(hash, hid, 4, dist + 25.)
    elseif dist > 750. or count <= 0 then
        repeat
            free LoadUnitHandle(hash, hid, i)
            set i = i + 1
        until i > 3
        call FlushChildHashtable(hash, hid)
        call PauseTimer(t)
        free t
    endif
//===========================================================================================================================//
//                                                   Flushing variables                                                      //
//===========================================================================================================================//
    flush t, caster, dummy
endfunction

function Trig_Freezing_Shot_Actions takes nothing returns boolean
//===========================================================================================================================//
//                                                  Local variables                                                          //
//===========================================================================================================================//
    var t, caster, dummy, angle, hid, x, y, i = 1
//===========================================================================================================================//
//                                                  Trigger actions                                                          //
//===========================================================================================================================//
    if GetSpellAbilityId() == 'A000' or GetSpellAbilityId() == 'A002' then
        set t = CreateTimer()
        set hid = GetHandleId(t)
        set caster = GetTriggerUnit()
        set x = GetWidgetX(caster)
        set y = GetWidgetY(caster)
        set angle = Atan2(GetSpellTargetY() - y, GetSpellTargetX() - x) * 57.295 + 25.
        call SaveInteger(hash, hid, -1, 3)
        call SaveAgentHandle(hash, hid, 0, caster)
        call SaveReal(hash, hid, 5, angle)
        
        repeat
            set dummy = CreateDummy(GetTriggerPlayer(), "Abilities\\Spells\\Other\\FrostBolt\\FrostBoltMissile.mdl", .3, x, y, 100., angle)
            call SaveAgentHandle(hash, hid, i, dummy)
            set angle = angle - 25.
            set i = i + 1
        until i > 3
        call TimerStart(t, .04, true, function Trig_Freezing_Shot_Timer)
    endif
//===========================================================================================================================//
//                                                   Flushing variables                                                      //
//===========================================================================================================================//
    flush t, caster, dummy
    return false
endfunction

//===========================================================================================================================//
//                                                 Trigger Initialization                                                    //
//===========================================================================================================================//
function InitTrig_Freezing_Shot takes nothing returns nothing
    call FogMaskEnable(false)
    call FogEnable(false)
    set gg_trg_Freezing_Shot = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(gg_trg_Freezing_Shot, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(gg_trg_Freezing_Shot, Condition(function Trig_Freezing_Shot_Actions))
endfunction
 
At this point, you might as well infer these things too

i++
++i
i--
--i
i+=
i*=
i-=
i/=
i = i + 1

as well as
func()


then you could also include templates to sorta replace modules
struct List<T>

to instantiate
List<integer> list = new List<integer>()

which would do like c++ and create an entire new struct just to handle that type ;o. This would remove most of the need for modules.


Another great thing to do would be object type checking. Yes, they are all integers, but this shouldn't be legal.

Code:
//pardon my c++
int hi(A &a);

----------------------------
int boo = 6;
hi(boo);

While illegal in any other language, it is perfectly legal in vjass.

Then there are other things, but those other things are for cohador to deal with, like fixing polymorphism to be smart in its destruction so that it doesn't evaluate a trigger 100% of the time, even when it doesn't need to.
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
Yes, that is not like MASM is painfull to use, like any assembler language.

Adic is not 100 % compatible with vJass, and sometimes instead of showing a script error, it simply crash.
Also there is almost no right error code print (vJass ones are still far from perfect though).
Again, as said in some other post, i totally respect the work behind cJass, but i consider it way behind vJass in term of quality, even if cJass has more features, in theory.

Ofc use it what you want, but let's face it, for most users that would be jasshelper by cohadar.
 
Level 23
Joined
Jan 1, 2009
Messages
1,615
So, is this still in the works/progressing or not?
And how do you recognize type inference with something like this:
JASS:
function foo takes boolean b
    var a
    if b
        a = 1.
    else
        a = GetSpellAbilityUnit()

?

And I really, really don't like the hardcoded style.
Why do you only support a few of Jass' types?
Those free and flush keywords just add unneeded confusion.

Without cJass this seems mostly useless, and I won't run 3 Parser/compiler-units on top of each other, especially with such low benefits.
 
You should write some sort of file that defines all the functions.
Meaning, someone would see something like:

JASS:
class handle
{
    public integer getId();
}

class agent : handle
{

}

class widget : agent
{
    public real getX();
    public real getY();
    public real getLife();
    public void setLife(real value);
}

class unit : widget
{
    public unit(player p, integer id, real x, real y, real facing);
    public void remove();
    public void setX(real value);
    public void setY(real value);
    public real getX();
    public real getY();
    // etc...
}
 
Status
Not open for further replies.
Top