Wc3C.net

Wc3C.net (http://www.wc3c.net/forums.php)
-   Warcraft Editing Tools (http://www.wc3c.net/forumdisplay.php?f=13)
-   -   JassHelper 0.A.2.B - A vJass and Zinc 2 Jass compiler (http://www.wc3c.net/showthread.php?t=88142)

Vexorian 10-14-2006 04:02 AM

JassHelper 0.A.2.B - A vJass and Zinc 2 Jass compiler
 
4 Attachment(s)
For an actual explanation of the additions and how they work well... ... You can check the readme online which explains all the things.

A quick intro: A proof of concept vJass compiler, vJass is an extension to the Jass syntax enabling a bunch of crazy things like libraries, structs and textmacros. Also adds the zinc scripting language, which is just a tweak of vJass with some small additions/more restrictions and syntax that is a little less verbose: check the zinc readme for more info.


changelog


0.A.2.B
* Fixed a bug with static ifs that made them fail when the constant boolean variable had a comment in its declaration line.
* It is now possible to use . syntax inside a global/static member declaration. However, you must notice that this will not usually work unless you are calling a static member from a place bellow its declaraton . Else you would get a Pjass error.
* Array structs no longer 'declare' unusable allocate/deallocate methods. In other words, you may now use those method names when declaring a method inside an array struct.


0.A.2.A
* Fixed a bug that allowed scope members to have invalid names and still compile.
* Manual: Fixed the getFromKey example.
* Zinc: Fixed bugs that prevented some real literals to compile.
* Zinc: while(true) does not add a useless exitwhen(false).
* Zinc: Added do{..}while(..) .

0.A.2.9
* All module initializers run before any struct initializer.
* Fixed a bug that forbade comments after then in static ifs.
* Structname.methodName.exists should work outside static ifs.
* Static ifs should now work correctly with members/methods that are explicitly public or private. Note that private members/methods will not be visible to static ifs outside the struct.
* Zinc: Fixed random compile error bugs introduced in last version.

0.A.2.8
* double import check now considers full path instead of just file name.
* static ifs can check if a method exists using .exists.
* private module destroy now works like module create (is not hidden from the implementing struct)
* Zinc: structs onInit and library onInit no longer conflict.

0.A.2.7
* Added "comment" import mode.
* Added +=,/=,-=,/=, and for(assignment; condition; assignment) to Zinc.
* Fixed a bug with import doing a double import when given the same filename twice in OSes that use / instead of \
* Fixed a crash when attempting to use special methods like allocate for function interfaces, now it gives a syntax error...
* Fixed a bug with function literals not working correctly when the function returned a custom type.
* Fixed a bug with function interfaces not working correctly when they had themselves as argument/return value.
* Fixed a bug with //! import inside //! zinc tags
* Unclosed //! zinc tags inside a file will get reported.

0.A.2.6
* externalblock now allows a $FILENAME$ argument and a extension= property.
* Fixed a bug that made /* */ comments mess up with the syntax error line number in the zinc/libraries phase when import was not used.
* Improved the library requirements error message.
* Zinc: Make [implement] cause syntax errors.

0.A.2.5
* Limit of strings in a single line raised from 27 to 61.
* Zinc: Fix not being able to parse certain real literals.

0.A.2.4
* Fixed a bug that allowed .getType() to cause jasshelper crashes.
* thistype works in static ifs. (not implicit though)
* When debug mode is on, static if phase will comment out lines instead of deleting them.
* Fixed a bug with optional requirements sometimes not working correctly.
* Zinc: jasshelper.conf's [noimplicitthis] option does not affect Zinc code.
* Fixed a bug with the shadow helper phase duplicating some comments.

0.A.2.3:
* Fixed a bug that made .exists cause obscure syntax errors.

0.A.2.2
* Fixed a bug that prevented using .evalaute/ .execute on methods.
* Fixed a bug that caused syntax errors when you used a hook for a native that takes nothing.

0.A.2.1
* .pointer has been removed from the syntax for using methods for function interfaces.
* You may now also use non-static methods for function interfaces (they are treated as functions that take an extra integer first)
* Zinc: Added anonymous methods.

0.A.2.0
* Fixed some struct member declaration syntax errors appearing in line 1.
* Fixed a bug that made method.name return wrong values when using the method implicitely (without this).
* Fixed missing syntax error messages in the structs phase.
* Static Methods can be used as function pointers. Just do struct.method.pointer to get such function pointer. Implicit casting between methods and function interfaces will come later (so you do not have to use .pointer).

0.A.0.1
* Fixed some undefined code related to implicit this in member usage. Which could have caused very odd code to get generated.
* Fixed an old bug that sometimes added indentation and comments to syntax errors.
* Zinc: Fixed a random crash related to comments.
* Zinc: Fixed a lame mistake that made all of a zinc struct's members LIBRARY-private.

0.A.0.0
* . or this. are not required anymore to use members. Note that this may cause issues if for some (incredibly weird) reason you try to use global variables from a method of a struct that has variables of the same name. To disable this feature, you can add [noimplicitthis] to jasshelper.conf.
* Improved the syntax error when you place a function inside a struct.
* Code values might get implicitly casted to boolexpr in some occasions, specifically, when using them as arguments for natives/bjfunc that take boolexpr. More cases will get added when type safety gets on its way for more stuff...
* Zinc: Added anonymous functions, but they cannot use locals from their parent (yet).
* Zinc: Fixed a crash that could happen when the zinc input is much smaller than the vJass output.
* Zinc: Fixed a couple of missing ; mistakes in the examples.

-- find complete changelog at readme --



The files

Attachment 360230.A.2.B.jasshelper.7z : Includes jasshelper.exe a command line utility that is supported by grimoire and that you can also use to manually compile your map. Also clijasshelper.exe that behaves exactly the same except it is intended for console usage.

Bug reporting /suggestion rule #1 Oct 09, 2009, 22:00 GMT
Please use vJass or zinc code for your suggestions and bug reports. Because it is confusing and if I have to learn a new language every time a person makes a post it would really suck. If you do not use either Zinc or vJass in your report, I'll not only ignore it, I will delete it. There is an exception though and it is when posting code in another language to explain a feature I should copy.

Rule #2 Nov 13th, 2009.
Report bugs in this thread, expecting me to go through links to other threads / and specifically other sites to be able to reproduce the bug is not going to be tolerated anymore.

Rule #3 Nov 21th, 209.
The easier you make to me to reproduce a bug, the more likely it will get fixed. Since I do not use NewGen Pack, sending me inputwar3map.j besides the map will seriously help a lot.


Just in case
When installing a new jasshelper version in newgen pack, replace jasshelper.exe and clijasshelper.exe in the folder called "bin" inside jass newgen pack's folder.

Vexorian 10-17-2006 07:40 PM

because of lack of a command from WEHelper it is not compressing the mpq when closing the map, so you might notice that the map gets mich bigger than before after using it, don't worry, the effect can be solved by a mpq editor and is fixed automatically if you optimize the map

Vexorian 11-12-2006 06:37 PM

Version 0.8.0 has got a new feature which complements scopes pretty well, this is a quick example:

Collapse JASS:
    //! textmacro STACK takes NAME, TYPE, TYPE2STRING
    //! scope $NAME$
    globals
        private $TYPE$ array V
        private integer N=0
    endglobals
    public function push takes $TYPE$ val returns nothing
        set V[N]=val
        set N=N+1
    endfunction

    public function pop takes nothing returns $TYPE$
        set N=N-1
        return V[N]
    endfunction

    public function print takes nothing returns nothing
     local integer a=N-1
        call BJDebugMsg("Contents of $TYPE$ stack $NAME$:")
        loop
            exitwhen a<0
            call BJDebugMsg(" "+$TYPE2STRING$(V[a]))
            set a=a-1
        endloop
    endfunction
    //! endscope
    //! endtextmacro

    //! runtextmacro STACK("StackA","integer","I2S")
    //! runtextmacro STACK("StackB","integer","I2S")
    //! runtextmacro STACK("StackC","string","")
    function Test takes nothing returns nothing
        call StackA_push(4)
        call StackA_push(5)
        call StackB_push(StackA_pop())
        call StackA_push(7)
        call StackA_print()
        call StackB_print()
        call StackC_push("A")
        call StackC_push("B")
        call StackC_push("C")
        call StackC_print()
    endfunction

Av3n 11-13-2006 04:58 AM

wow vex when i find out there is an new version i dl it then an new version pops out *sigh*

-Av3n

Vexorian 11-24-2006 09:25 PM

0.9.0 fixes bugs, adds structs, library_once and textmacro_once.

I didn't have time to document the aditions, the readme would be updated tomorrow with some luck.

this is a sample of structs:

Collapse JASS:
struct vec
    integer x = 0
    integer y=0
    integer z=0
endstruct



function vec_add takes vec A, vec B returns vec
 local vec C= vec.create()
     set C.x = A.x + B.x
     set C.y = A.y + B.y
     set C.z = A.z + B.z
 return C
endfunction

function vec_string takes vec A returns string
    return "("+I2S(A.x)+","+I2S(A.y)+","+I2S(A.z)+")"
endfunction

function Trig_Untitled_Trigger_001_Actions takes nothing returns nothing
 local vec a=vec.create()
 local vec b=vec.create()
 local vec c

    set a.x=2
    set a.y=2
    set a.z=5

    set b.x=-7
    set b.y=8
    set b.z=9


    set c=vec_add(a,b)

    call BJDebugMsg(vec_string(a)+" + "+vec_string(b) +" = "+vec_string(c))


//either works:
    call vec.destroy(c)
    call a.destroy()
    call b.destroy()

endfunction

coming soon: methods, inheritance and polymorphism.

(static attributes are currently possible, also private members, although they have no use since there are no methods)

Notice structname.create() would return 0 if the 8190 instance limit is reached, if debug mode is enabled it would show a message in game in that case.

So just be careful not to create more than 8190 instances and if there is that possibility check if the returned struct is not 0.

Vexorian 11-24-2006 10:48 PM

a quickfix version, 0.9.1

zergleb 11-26-2006 10:32 PM

So I noticed in the syntax error screen that this doesn't use gamecache like you originally planned(I saw an example of how you thought OOP could work), but instead it uses arrays, does that mean that using this should be faster than game cache?

wyrmlord 11-27-2006 12:53 AM

Arrays are, as I hear, much faster than gamecache.

BlinkBoy 11-27-2006 02:23 AM

Hmm, can structs be set as globals? if yes can them be setted as global arrays, and how would you inialize them?

Vexorian 11-27-2006 02:54 AM

hmnn, I guess that with that calculus exam floating around I forgot to make the documentation anyways. Considering we declared the vec struct type of the previous post:
Collapse JASS:

globals
     vec ouch = 0 //you can initialize an struct reference at 0 in a globals declaration

//syntax error:     vec ouch = vec.create() //you cannot do struct syntax in global declarations (because global blocks are always moved to the top of the script, before functions exist.

     vec array SOLUTIONS //yes, arrays are possible,


endglobals



function doThings takes nothing returns nothing
      set ouch=vec.create()
      set SOLUTIONS[0] = vec.create()
      set SOLUTIONS[1] = vec.create()
      set SOLUTIONS[2] = vec.create()
 //and so and so...
endfunction


Collapse JASS:
struct teststatic


    static integer N=0 //unlike 'normal' struct members these are static, they are effectively just global variables with other syntax
    static integer array V


//syntax error:    integer array X //array attributes are not allowed

endstruct


function teststatic_fun takes nothing returns nothing
    set teststatic.N=teststatic.N+1
    set teststatic.V[ teststatic.N] = 8
endfunction


PipeDream 11-28-2006 05:06 AM

Looking good. Can't wait to see methods & polymorphism.

Vexorian 11-28-2006 02:58 PM

0.9.2 grave bugs when struct compiler had to add more than 20 globals were fixed.

zergleb 11-29-2006 08:36 AM

Is there going to be private/public global variable OOP support?? what I mean is like right now to use public struct variables I must work it like this.
Collapse JASS:
function InitIncArg takes nothing returns nothing
    set KillUnit = IncType.create()//these all work fine
    set KillHero = IncType.create()
    set Construct = IncType.create()
    set TrainUnit = IncType.create()
    set Outpost = IncType.create()

    set KillUnit.Value = 1.0/10 //Not a struct name, nor a variable function of a struct type
    set ResourceSystem_KillHero.Value = 1.0/5
    set ResourceSystem_Construct.Value = 1.0/30
    set ResourceSystem_TrainUnit.Value = 1.0/20
    set ResourceSystem_Outpost.Value = 50.0
endfunction

Just a question, nothing more.

btw thanks for the fixes in version 0.9.2 I always appreciate/enjoy your work and promptness fixing problems.

Vexorian 11-29-2006 11:51 AM

I don't understand the question.

Edit: I see, it is a bug, KillUnit should work, probably I forgot to consider . a token.

Edit: All right, bug fixed.

BlinkBoy 11-29-2006 05:05 PM

Ok, i've found some things and limitations, but also found a lil bug.

Collapse JASS:
struct domin
      integer tax = 0
      player conqueror = Player(13)
      boolean sur = false
endstruct

globals
      domin array V
      force array C
endglobals

function Trig_Surrender_Settings_Actions takes nothing returns nothing
local integer f = 0
      set V[0] = domin.create()
      set V[1] = domin.create()
      set V[2] = domin.create()
      set V[3] = domin.create()
      set V[4] = domin.create()
      set V[5] = domin.create()
      set V[6] = domin.create()
      set V[7] = domin.create()
      set V[8] = domin.create()
      set V[9] = domin.create()
      set V[10] = domin.create()
      set V[11] = domin.create()
// In this way, the syntax is correct, but then if i try setting them dynamicly:
loop
     set V[f] = domin.create()
     set f = f + 1
     exitwhen f >= 12
endloop
// This will cause a syntax error
set f = 0
loop
    set C[f] = CreateForce()
    set f = f + 1
    exitwhen f >= 12
endloop
endfunction

My first Question, will you improve the system to support dynamic arrays, with structures ?

Now a lil bug, that I found. If you set a struct variable in an if statement, it will cause a syntax error.

Collapse JASS:
//..............
if d != Player(13) and V[GetPlayerId(a)].sur == false then
//..............

so i must declare a boolean variable and give it that value

Vexorian 11-29-2006 10:07 PM

I don't really understand what you mean by "support dynamic arrays"

The rest are all bugs. Let me check
---
Edit: I just tested both examples and no syntax errors, are you using latest version? Maybe there's something else involved causing the issue.

BlinkBoy 11-30-2006 01:26 AM

You right, i forgot to update to the latest version, thanks alot.

Vexorian 11-30-2006 02:01 AM

so, what did you mean by the dynamic array support?

Vexorian 12-16-2006 02:11 PM

0.9.4 is up, a lot of new features:

methods


Collapse JASS:
struct Vector
    real x=0
    real y=0
    real z=0

    // sorry, no syntax for actual constructors, you can always make dummy ones though...
    static method create_from takes real x, real y, real z returns Vector
     local Vector n=Vector.create()
        set n.x=x
        set n.y=y
        set n.z=z
     return n
    endmethod

    method magnitude takes nothing returns real
        return SquareRoot( this.x*this.x + this.y*this.y + this.z*this.z)
    endmethod

    // this is necessary, it was easier to code but it also removes ambiguousness
    // and enforces to notice that it is a whole access and not just 'normal' var usage
    method plus takes Vector B returns nothing
        set this.x=this.x+B.x
        set this.y=this.y+B.y
        set this.z=this.z+B.z
    endmethod

    // yeah, static methods...
    static method addition takes Vector A, Vector B returns Vector
     local Vector C=Vector.create()
        set C.x=A.x+B.x
        set C.y=A.y+B.y
        set C.z=A.z+B.z
     return C
    endmethod

    // onDestroy is called when .destroy() is used
    method onDestroy takes nothing returns nothing
     local code c=(function Vector.err)

        call BJDebugMsg("Funny, the vector was destroyed")
    endmethod

endstruct

//===========================================================================
function InitTrig_Untitled_Trigger_001 takes nothing returns nothing

 local Vector A=Vector.create_from(4.5,3.4,2.1)
    call BJDebugMsg(R2S(A.magnitude()))

    call Vector.destroy(A)
    call Vector.destroy(A) //double free is now prevented!

endfunction




Polymorphism (interfaces)

Collapse JASS:
function Trig_Untitled_Trigger_001_Actions takes nothing returns nothing
 local expression e= sum.createFrom( sum.createFrom( value.createFrom(8),  sum.createFrom(value.createFrom(2),value.createFrom(-1)) ) , value.createFrom(12) )
 local sum e2
 local sum e3
 local integer i=1000

    call BJDebugMsg(I2S(e.evaluate()))
    call e.destroy()
    set e2=sum.createFrom(value.createFrom(1) ,  value.createFrom(1) )
    loop
        exitwhen i==0
        set e2.a = sum.createFrom( value.createFrom(1) , e2.a)
        set i=i-1
    endloop

call TriggerSleepAction(0.)
    call BJDebugMsg(I2S(e2.evaluate()))
    call BJDebugMsg(I2S(e2))
    call e2.destroy()



endfunction

interface expression
    method evaluate takes nothing returns integer
endinterface


struct value extends expression
    integer v=0

    static method createFrom takes integer v returns value
     local value o=value.create()
        set o.v=v
     return o
    endmethod

    method evaluate takes nothing returns integer
     local value x=this
        return this.v
    endmethod
endstruct


struct sum extends expression
    expression a = 0
    expression b = 0

    static method createFrom takes expression a, expression b returns sum
     local sum o= sum.create()
        set o.a=a
        set o.b=b
     return o
    endmethod



    method evaluate takes nothing returns integer
        return this.a.evaluate() + this.b.evaluate()
    endmethod

    method onDestroy takes nothing returns nothing
        if(this.a!=0) then
            call this.a.destroy()
        endif
        if(this.b!=0) then
            call this.b.destroy()
        endif
    endmethod

endstruct



Methods are not like normal functions:
- You can call methods from every position of the script without problems
- In exchange, it is not a good idea to have waits or GetTriggeringTrigger() inside methods.


An involuntary feature is that static methods that take nothing can actually be used as code values (function class.method) !


inject


Collapse JASS:

//! inject main
     call BJDebugMsg("Look! I just replaced the map's main function")

     //! dovjassinit
     // (always required, structs and libraries need some initializing)

//! endinject



//! inject config

    // injecting config really needs to setup players and stuff really well otherwise it crashes.

//! endinject

//These things were requested by IceFrog and I kind of liked the idea...



--

The grimoire pack and the documentation for 0.9.4 features might take some time.

---
BTW you 'can' use a single . inside methods so this or classname are implicit but I don't really like this.

For example, in the above sample it could be: set .x = .x + B.y

BlinkBoy 12-16-2006 04:23 PM

Quote:

Originally Posted by Vexorian
so, what did you mean by the dynamic array support?


Nah forget it, the problem was that in my old problem, I had to declare arrays iten by iten and not use a loop that can change Ā«making a dynamic array. I think I'll explain myself.

In other languages such as in Visual Basic, there are 2 types of arrays Static and Dynamic. Static Arrays in VB have a limited amount of spaces, example:\
Code:

Dim D(8) as Double
this means that the array will be limited to store 9 variables 0 to 8. In the other hand dynamic arrays were subjected to the system limits, so you declared them by not adding any value between the (). That was why I got confused.

Anyways a good suggestion would be multidimensional arrays, It would be better for administrating your information a jass syntax example could be:

Collapse JASS:
globals
        real array dim(2) MyArray
endglobals

function MyFunction takes real b, real c, real a, real index returns nothing
set real k = SquareRoot( (b*b) - (4*a*c))
set MyArray[index,1] = (k - b) / (2*a)
set MyArray[index,2] = ((-1)*k - b) / (2*a)
// I know that I can use an sruct for this, but it would be problematic if I would like to make my code more flexible
endfunction

I'm 100% sure you already know all this, but just as a reference, It would be nice if you could add that, maybe my example is not the best one to reffer to this, but i'm sure it is usefull.

Vexorian 12-16-2006 06:12 PM

I am still limited by JASS' own limitations, in JASS all arrays take 8192 , nd arrays could happen I am not sure if after coding all the . non-sense for structs I have the intenrion of going crazy on parsing [] variations o_O

wyrmlord 12-16-2006 06:34 PM

If you wanted to create a multi-dimensional array, you'd have to put a limit on how large each index could be. For instance, if you had a limit of 90 for each index in a two dimensional array, it would work. If you had a limit of 20 for each index, you could have a 3 dimensional array. There's no "real" way to do multi-dimensional arrays in JASS.

Also, the struct idea is giving me an idea on how to make a system to store/retrieve values that would be faster than gamecache. You have a node struct, like in a linked list. That node contains 3 variables, one is an integer, representing the 'key' you store a value under, one is whatever value is being stored (I'm going to like text macros), and the third is another node. To store a value, you give the function a key (meant to be the integer version of a handle). The function would then keep going to the next node over and over again until it either found that key (from a previous use) or an empty spot, where it would then create a new node and store the information there. The only thing is, I'm wondering if this would work and not bug.

BlinkBoy 12-17-2006 03:21 AM

Hmm, yap maybe 1 array is not complecent for multidimensional needs.

Btw to wyrmlord, that system wouldn't save much processing, since you still depend of the safecasting [example: H2I], which is the function that makes processing a bit longer.

wyrmlord 12-17-2006 03:28 AM

Actually, the way that my code works, I don't need to store it as an integer, I can store it using a handle or w/e actually. If you're interested in seeing the code just ask.

Suggestion for the program: Variable array support in structs.

BlinkBoy 12-17-2006 03:53 AM

Hey I know one, how about the old Select Case? is not as confusing as having many elseif.

Collapse JASS:
globals
        constant integer NullTeam = 3
endglobals

function GetPlayerTeamIDtakes player p returns integer
select case GetPlayerID(p) // takes a value

         case  this < 7
                 return 1
         case 7 < this and this < 13
                 return 2
         case else
                 return NullTeam
endselect
endfunction

// another form, a function that identifies a pair of numbers between 1 to 10

function IsPair takes integer i returns boolean
select case i

         case  2, 4, 6, 8, 10
                 return true
         case 1, 3, 5, 7, 9
                 return false
         case else
                 return false
endselect
endfunction

struct longitud
         real value 0
         string scale = "miles"
endstruct

//Now a practical one.
function ConvLongitud takes longitud l, string newscale takes returns nothing
if l.scale = "miles" then
    select case newscale
         case  "feet"
                 set l.scale = "feet"
                 set l.value = 5280 * l.value
         case "yards"
                 set l.scale = "yards"
                 set l.value = 1760 * l.value
         case "inches"
                 set l.scale = "inches"
                 set l.value = 63360 * l.value
    endselect
elseif l.scale = "feet" then
//.... and so on and so on.
endif
endfunction      

Anyways, could you show me the code?, wyrm

BertTheJasser 12-17-2006 10:29 AM

Collapse JASS:
set k=0.03/lumen[i].fade
give s me compile errors (grimoire, JassHelper 0.9.3), where lumen is a struct.
But
Collapse JASS:
set k=lumen[i].fade
set k=0.03/k
works as supposed, wihout errors.

Vexorian 12-17-2006 12:37 PM

So have you tested in 0.9.4?.


Blinkboy: I think case would be quite useless a.k.a the code would still be as slow or even allow the user to create really slow code

Edit: A similar code in 0.9.4 doesn't seem to cause errors

Ragnarok X 12-19-2006 12:10 PM

Why always the WEHelper internal preprocessor "define" get executed after your JassHelper preprocessor even if i put the define preprocessor before your own.

The main problem is that i want to remplace public or private variables and function with the define, but i cann't, or maybe you can with another preprocessador?.

Vexorian 12-19-2006 12:14 PM

It is a necessary evil

PipeDream 12-19-2006 09:02 PM

0.9.4 has put the fun back into JASS for me. It's easy to get fancy with data structures, although you have to do everything with lists and trees. Essentially it accomplishes the dynamic allocation/array passing dream in a manner far more practical than DARY.

It would be cool to have some type safety/casting, I keep mixing up structures.

Vexorian 12-20-2006 12:37 PM

Yes I think polishing is next, I finally got the ability to get common.j and blizzard.j in WEHelper (otherwise I would create a fork) so I can parse common.j for types which will allow me to add a typecast operator and also recognize bad type usage.

PipeDream 12-21-2006 09:40 PM

static methods don't seem to work with interfaced objects (0.9.4)
Collapse JASS:
interface Ord        //Object with an ordering defined on it
    method geq takes Ord right returns boolean
endinterface

struct KVPair extends Ord
    real key
    real value
    static method Create takes real key, integer value returns KVPair
        local KVPair p = KVPair.create()
        set p.key = key
        set p.value = value
        return p
    endmethod
    method geq takes Ord right returns boolean
        local KVPair p = right
        return this.key > p.key
    endmethod
endstruct
It turns Create() into a dynamic method but doesn't define the result_integer
It's np in this case since work around is just
Collapse JASS:
interface Ord        //Object with an ordering defined on it
    method geq takes Ord right returns boolean
endinterface

struct KVPair extends Ord
    real key
    real value
    method geq takes Ord right returns boolean
        local KVPair p = right
        return this.key > p.key
    endmethod
endstruct

function KVPair_Create takes real key, integer value returns KVPair
    local KVPair p = KVPair.create()
    set p.key = key
    set p.value = value
    return p
endfunction

-----

A practical example of why JASSHelper rocks the socks:
Collapse JASS:
interface Ord        //Object with an ordering defined on it
    method geq takes Ord right returns boolean
    method to_s takes nothing returns string
endinterface

struct KVPair extends Ord
    real key
    integer value
    method geq takes Ord right returns boolean
        local KVPair p = right
        return this.key > p.key
    endmethod
    method to_s takes nothing returns string
        return R2S(this.key)
    endmethod
endstruct

function KVPair_Create takes real key, integer value returns KVPair
    local KVPair p = KVPair.create()
    set p.key = key
    set p.value = value
    return p
endfunction

struct Node
    Ord p
    Node left
    Node right
    integer n
    static method Create takes Ord p returns Node
        local Node n = Node.create()
        set n.p = p
        set n.left = 0
        set n.right = 0
        set n.n = 0
        return n
    endmethod
    //must maintain heap property
    //parent > both children
    //both children heaps
    method Insert takes Ord p returns nothing
        local Ord displaced
        //Decide whether to displace self or new pair
        if p.geq(this.p) then
            set displaced = p
        else 
            set displaced = this.p
            set this.p = p
        endif
        //Push displaced element down while maintaining balance
        //if missing a child, fill the hole left to right
        if this.left == 0 then
            set this.left = Node.Create(displaced)
        elseif this.right == 0 then
            set this.right = Node.Create(displaced)
        //have both children, so add it where there are fewer children
        elseif this.left.n > this.right.n then
            call this.left.Insert(displaced)
        else
            call this.right.Insert(displaced)
        endif
        set this.n = this.n + 1
    endmethod
    method Pop takes nothing returns Node
        set this.n = this.n - 1
        //Leaf
        if this.left == 0 and this.right == 0 then
            call Node.destroy(this)
            return 0
        elseif this.left == 0 then
            set this.p = this.right.p
            set this.right = this.right.Pop()
            return this
        elseif this.right == 0 then
            set this.p = this.left.p
            set this.left = this.left.Pop()
            return this
        //Branch
        elseif this.left.p.geq(this.right.p) then
            set this.p = this.right.p
            set this.right = this.right.Pop()
            return this
        else
            set this.p = this.left.p
            set this.left = this.left.Pop()
            return this
        endif
    endmethod
    method to_s takes nothing returns string
        if this == 0 then
            return "0"
        else
            return "("+this.left.to_s()+","+this.p.to_s()+","+this.right.to_s()+")"
        endif
    endmethod
endstruct

//Does not destroy the Ord
struct Heap    //boxed heap
    Node top
    static method Create takes nothing returns Heap
        local Heap h = Heap.create()
        set h.top = 0
        return h
    endmethod
    method Insert takes Ord p returns nothing    //Here's where templating / polymorphism would be nice
        if this.top == 0 then
            set this.top = Node.Create(p)
        else
            call this.top.Insert(p)
        endif
    endmethod
    method Peek takes nothing returns Ord
        if this.top == 0 then
            return 0
        else
            return this.top.p
        endif
    endmethod
    method Pop takes nothing returns nothing
        if this.top != 0 then
            set this.top = this.top.Pop()
        endif
    endmethod
    method Print takes nothing returns nothing
        call BJDebugMsg(this.top.to_s())
    endmethod
endstruct

function OrdToKV takes Ord o returns KVPair
    return o
endfunction

function Trig_test_Actions takes nothing returns nothing
    local Heap h = Heap.Create()
    local KVPair p 
    set p = KVPair_Create(3.0,2)
    call h.Insert(p)
    set p = KVPair_Create(5.0,7)
    call h.Insert(p)
    set p = KVPair_Create(1.0,1)
    call h.Insert(p)
    set p = KVPair_Create(8.0,3)
    call h.Insert(p)
    call h.Print()
    call BJDebugMsg(I2S(OrdToKV(h.Peek()).value))
    call h.Pop()
    call h.Print()
    call BJDebugMsg(I2S(OrdToKV(h.Peek()).value))
    call h.Pop()
    call BJDebugMsg(I2S(OrdToKV(h.Peek()).value))
    call h.Pop()
    call BJDebugMsg(I2S(OrdToKV(h.Peek()).value))
    call h.Pop()
endfunction
This is a priority queue for a generic "Ord" type that requires only a compare method implemented.
We can now implement proper abstract data types! Well, we could before, but this takes out so much manual manipulation pain, and they're actually types now.

Vexorian 12-23-2006 01:47 AM

Yes pipe, I figured that out the other day, and added a known issues section to the first post...

Vexorian 12-24-2006 01:08 PM

Added yet another bug to known issues, these got big so an update is going to be a priority but I am busy this couple of days

SFilip 12-24-2006 01:26 PM

Something like this doesn't seem to be legal (the map wont load if you add it) - the callback should be above the create method, yet JassHelper parses it with no errors.
Collapse JASS:
struct timerstruct
    timer t
    static method CreateWithCallback takes nothing returns timerstruct
        local timerstruct ts = timerstruct.create()
        set ts.t = CreateTimer()
        call TimerStart(ts.t, 10., false, function timerstruct.callback)
        return ts
    endmethod
    static method callback takes nothing returns nothing
        // some actions here
    endmethod
endstruct
Not much of a big deal, but I found it weird that JH doesn't report it so I just thought you should know about it.

Vexorian 12-24-2006 01:32 PM

It should be legal actually.

But it would create a callback that calls back. If it doesn't load then it is a PJASS problem, let me test that code either way.

Edit: It is a JASSHelper bug and a PJASS bug, JASSHelper for some reason forgets to place a linebreak in the sc version of callback and PJASS ignores the lack of linebreak and validates the code.

BlinkBoy 12-26-2006 07:13 AM

So you adding to it anything new?. I think you should add Events for Objects.

Collapse JASS:
// Just a simple example, to help encapsulation
struct data
         string dat = ""
         // Events only takes values, they don't return any message
         Event CreatedData takes  data TriggeringData
         static method Create takes string s returns data
                  local data d = data.create()
                  set d.dat = s
                  // calls a function that makes every trigger with this event to run
                  call data.RaiseEvent(CreatedData(d))
                  return d
          endmethod
endstruct

function Trig_Test2_Actions takes nothing returns nothing
         call BJDebugMsg("Someone just created a Data type with dat: " + data.TriggeringData.dat)
endfunction

//===========================================================================
function InitTrig_Test2 takes nothing returns nothing
    set gg_trg_Test2 = CreateTrigger(  )
    call data.RegisterEvent(gg_trg_Test2, CreatedData)
    call TriggerAddAction( gg_trg_Test, function Trig_Test2_Actions )
endfunction

function Trig_Test_Actions takes nothing returns nothing
local data mydat = data.Create("I just filled the string")
call mydat.destroy()
endfunction

//===========================================================================
function InitTrig_Test takes nothing returns nothing
    set gg_trg_Test = CreateTrigger(  )
    call TriggerRegisterTimerEventSingle( gg_trg_Test, 2.00 )
    call TriggerAddAction( gg_trg_Test, function Trig_Test_Actions )
endfunction
       

Vexorian 12-26-2006 02:17 PM

maybe, but certainly not with that syntax, I'll have to wonder about how to implement it a lot.

...
0.9.4.1 is up, fixing some bugs and documenting the features.

shadow1500 12-26-2006 08:16 PM

Not really Object related but still very useful:
Collapse JASS:
function DoSomething takes nothing returns nothing
      call ForGroup(aGroup, function {call KillUnit(GetEnumUnit())} )
endfunction
Compiles to:
Collapse JASS:
function DoSomething_cb_1 takes nothing returns nothing
     call KillUnit(GetEnumUnit())
endfunction
function DoSomething takes nothing returns nothing
     call ForGroup(aGroup, function DoSomething_cb_1 )
endfunction

BlinkBoy 12-27-2006 01:58 AM

Ok, maybe I'll give you some ideas on how it should compile.

Here is the code of the last time, with some syntax changes

Collapse JASS:
// Just a simple example, to help encapsulation
struct data
         string dat = ""
         // Events only takes values, they don't return any message
         Event CreatedData takes  data TriggeringData
         static method Create takes string s returns data
                  local data d = data.create()
                  set d.dat = s
                  // calls a function that makes every trigger with this event to run
                  call data.CreatedData.RaiseEvent(d)
                  return d
          endmethod
endstruct

function Trig_Test2_Actions takes nothing returns nothing
         call BJDebugMsg("Someone just created a Data type with dat: " + data.TriggeringData.dat)
endfunction

//===========================================================================
function InitTrig_Test2 takes nothing returns nothing
    set gg_trg_Test2 = CreateTrigger(  )
    call data.CreatedData.RegisterEvent(gg_trg_Test2)
    call TriggerAddAction( gg_trg_Test, function Trig_Test2_Actions )
endfunction

function Trig_Test_Actions takes nothing returns nothing
local data mydat = data.Create("I just filled the string")
call mydat.destroy()
endfunction

//===========================================================================
function InitTrig_Test takes nothing returns nothing
    set gg_trg_Test = CreateTrigger(  )
    call TriggerRegisterTimerEventSingle( gg_trg_Test, 2.00 )
    call TriggerAddAction( gg_trg_Test, function Trig_Test_Actions )
endfunction


Now compiled without structs compiled yet, would look like this.


Collapse JASS:
globals
         data ss_data_CreatedData_TriggeringData
         trigger array ss_data_CreatedData_Triggers
         integer ss_data_CreatedData_Triggers_Index
endglobals

function ss_data_CreatedData_Add takes trigger trig returns nothing
local integer this = ss_data_CreatedData_Triggers_Index
if this < 8192 and trig != null then
   set ss_data_CreatedData_Triggers[trig]
   set ss_data_CreatedData_Triggers_Index = ss_data_CreatedData_Triggers_Index + 1
endif
endfunction

function ss_data_CreatedData_Run takes data this0 returns nothing
local integer this
if ss_data_CreatedData_Triggers_Index then
   set ss_data_CreatedData_TriggeringData = this0
   loop
        exitwhen this >= ss_data_CreatedData_Triggers_Index and this < 8192
        call ConditionalTriggerExecute( ss_data_CreatedData_Triggers[this] )
        set this = this + 1
   endloop
endif
endfunction

struct data
         string dat = ""
         static method Create takes string s returns data
                  local data d = data.create()
                  set d.dat = s
                  // calls a function that makes every trigger with this event to run
                  call ss_data_CreatedData_Run(d)
                  return d
          endmethod
endstruct
////////////////////////////////////////////////////////////////////////////////////////
// If conditions have wait calls or may make the thread go to sleep, then it is needed, to save the value in a local variable and 
//reassign it before a return action, if the return action specifies false, then this won't be done
////////////////////////////////////////////////////////////////////////////////////////

function Trig_Test2_Conditions takes nothing returns boolean
local data TriggeringData_Event = ss_data_CreatedData_TriggeringData
// some if statements and other things
set ss_data_CreatedData_TriggeringData = TriggeringData_Event
    return true
endfunction

function Trig_Test2_Actions takes nothing returns nothing
local data TriggeringData_Event = ss_data_CreatedData_TriggeringData
         call BJDebugMsg("Someone just created a Data type with dat: " + TriggeringData_Event)
endfunction

//===========================================================================
function InitTrig_Test2 takes nothing returns nothing
    set gg_trg_Test2 = CreateTrigger(  )
    call ss_data_CreatedData_Add(gg_trg_Test2)
    call TriggerAddAction( gg_trg_Test, function Trig_Test2_Actions )
    call TriggerAddCondition( gg_trg_Test2, Condition( function Trig_Test2_Conditions ) )
endfunction

function Trig_Test_Actions takes nothing returns nothing
local data mydat = data.Create("I just filled the string")
call mydat.destroy()
endfunction

//===========================================================================
function InitTrig_Test takes nothing returns nothing
    set gg_trg_Test = CreateTrigger(  )
    call TriggerRegisterTimerEventSingle( gg_trg_Test, 2.00 )
    call TriggerAddAction( gg_trg_Test, function Trig_Test_Actions )
endfunction


All times are GMT. The time now is 05:07 PM.

Powered by vBulletin (Copyright ©2000 - 2020, Jelsoft Enterprises Ltd).
Hosted by www.OICcam.com
IT Support and Services provided by Executive IT Services