• 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.
Level 3
Joined
Jun 3, 2010
Messages
47
Ugh, editing this post, firefox sucks ...

JASS:
library ObjectTrigger
	public class Trigger
		trigger t
		public triggercondition lastTriggerCondition
		public triggeraction    lastTriggerAction

		thistype addAction(code c)
			set this.lastTriggerAction=TriggerAddCondition(this.t,c)
			return this

		thistype addCondition(boolexpr e)
			set this.lastTriggerCondition=TriggerAddCondition(this.t,e)
			return this

		thistype execute()
			call TriggerExecute(this.t)
			return this

		void destroy()
			DestroyTrigger(this.t)
			this.deallocate()

		static thistype create()
			thistype this=thistype.allocate()
			this.t=CreateTrigger()
			return this

	filter SomeCondition()
		BJDebugMsg("R.I.P. //!")
		return true // I must return true in a filter or else it is false

	void SomeAction()
		BJDebugMsg("R.I.P. {}")

	init // test
		Trigger t=Trigger.create()
		t.addAction(SomeAction)
		t.addCondition(SomeCondition)
		t.execute()
		// or
		Trigger t=Trigger.create().addAction(SomeAction).addCondition(SomeCondition).execute()
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
Not sure if this code was for me or if you didn't understood (i think you had but wanted to write this code regardless my preview comment), but just to be sure : i didn't wanted mean that.

I meant typecast native functions to make "everything is an object" like trigger.create() -> TriggerCreate()
object.destroy() -> DestroyTimer() if it's a timer, RemoveUnit() if object is an unit, an so one.
 
Actually, this is smarter for constructors/destructors
JASS:
    class MyClass
        MyClass() //constructor
            thistype this = allocate();
            return this;
        ~MyClass() //destructor
            deallocate();

    module Module
        init
            print("hello world") //call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "hello world");

The new and delete keywords can then be used
MyClass class = new MyClass();
delete class;

The same syntax can also be applied to all natives.

Also, the semi colon should always be absolutely required... if you make them optional, then we go back to the stupid /* */ for line breaks.

Also can change operators and properties to c# style (I think that is the best style).
 
Level 3
Joined
Jun 3, 2010
Messages
47
JASS:
library Test
    globals
        int x = 10

    integer Return()
        x = x + 10
        return x

    init
        BJDebugMsg(I2S(Return()++++))

Displays 32?

>Oh, I don't like that idea... I think its a lot easier if we could edit the code directly on the map rather than importing it (which I guess was the case with the GE)...
Well then don't learn a real language, working in the world editor is horrible practice.
 
The semi colon should always be absolutely required... if you make them optional, then we go back to the stupid /* */ for line breaks.

Python does "\" for line breaks - Luck will have this too (I think it's important). It also makes it faster to parse because it will be O(1) to detect when lines should be joined.

I did get rid of "()" as typecasting operators because I intended "ClassName(args)" as the creator. classInstance.destroy() is fine with me, but "delete classInstance" looks nice too. I can use "new" and "delete" if enough people are fine with it.

The natives would be difficult to convert to be object-oriented like has been suggested. trigger() would obviously create a trigger, but for things that can be created with natives in multiple ways I would have to choose a bias. For example, CreateUnit, CreateUnitByName, CreateUnitAtLoc...

I don't intend "++" to be used too dynamically. I was strictly thinking loops, just to save typing a few characters. That's why I wrote: "++ and -- operators are supported to an extent". There are complications with using ++ because it doesn't fit in a high-level language like JASS where this creates a paradox: return Pair(i++, i++) (originally brought up by Vexorian when discussing cJass).

It is also not intuitive whether the "++" will increase i *before* or *after* being referenced, if I allowed it to be nested.

Tooltip, I'm thinking of getting rid of the weird "filter" type and just adding an automatic "return false" if the user forgets/omits it.

JASS:
    static boolean SomeCondition()
        BJDebugMsg("R.I.P. //!")
        return true

Also, should I get rid of libraries (everything top-sorts anyway) and just make everything object-oriented?

I'm also not sure if I should use "and" / "or" or if I should use the c-syntax operators "&" / "|" or even "&&" / "||". I think "and" / "or" are fine.
 
Level 3
Joined
Jun 3, 2010
Messages
47
Get rid of libraries but use logic to sort things out.

JASS:
class Spell
    static int SpellID = 'A000'

    filter Actions()
        KillUnit(GetTriggerUnit())
        TimerStart(NewTimer(),3.00,false,void()
            BJDebugMsg("Three seconds ago someone died after casting 'A000'")
        )

    static void onInit()
        trigger t=CreateTrigger()
        TriggerAddCondition(t,Actions)
        t=null

class TimerUtils
    timer NewTimer()
        return CreateTimer()

TU will be moved up, because it's obviously going to need to come before Spell.

I vote for complete object oriented programming, but make thistype and this required (JASSHelper tries to guess, that's really bad practice) and don't use new and delete, or at least give users the option to use methods without getting slowed down.

MAKE THINGS PRIVATE BY DEFAULT.
 
I have coded TimerUtils in Luck, please reply if you spot any irregularities or reply with comments, and ask questions if you have any.

JASS:
library TimerUtils
    
    #define
        USE_HASH_TABLE = true
        AUTO_PAUSE = true
        
        #if not USE_HASH_TABLE
            OFFSET   = 0x100000
            QUANTITY = 256
        #debug
            HELD     = -65915698
    
    globals
        timer array tT
        int tN = 0
        
        #if not USE_HASH_TABLE
            int array data
    
    #if not USE_HASH_TABLE and QUANTITY <= 0
        throw "TimerUtils QUANTITY must be greater than 0"
    
    void SetTimerData (timer t, int value)
        #if USE_HASH_TABLE
            t.data = value //handle.data uses the built-in hashtable to reference data.
        #else
            #debug
                int i = t.id - OFFSET //handle.id == GetHandleId(handle)
                if i < 0 or i > 8190
                    print "TIMER UTILS ERROR: ATTEMPT TO SET TIMER DATA OF BAD TIMER"
                    return
            data[t.id - OFFSET] = value
    
    int GetTimerData (timer t)
        #if USE_HASH_TABLE
            return t.data
        #else
            #debug
                int i = t.id - OFFSET
                if i < 0 or i > 8190
                    print "TIMER UTILS ERROR: ATTEMPT TO GET TIMER DATA OF BAD TIMER"
                    return
            return data[t.id - OFFSET]
    
    timer NewTimer()
        #if USE_HASH_TABLE
            if tN == 0
                return CreateTimer()
        #debug
            if tN == 0
                print "TIMER UTILS ERROR: EXCEEDED \"QUANTITY\" - INCREASE \"QUANTITY\" OR SET USE_HASH_TABLE TO TRUE AND ALWAYS RELEASE OLD TIMERS"
                return null
        tN--
        #debug
            SetTimerData(tT[tN], 0)
        return tT[tN]
    
    void ReleaseTimer (timer t)
        #debug
            if t == null
                print "TIMER UTILS ERROR: ATTEMPT TO RELEASE A NULL TIMER"
                return
            elseif tN == IntegerTertiaryOp(USE_HASH_TABLE, 8191, QUANTITY)
                DestroyTimer(t)
                print "TIMER UTILS ERROR: TIMER STACK IS FULL, DESTROYING TIMER $t"
                return
            elseif GetTimerData(t) == HELD
                print "TIMER UTILS ERROR: DOUBLE-FREE OF TIMER $t"
                return
            SetTimerData(t, HELD)
        #if AUTO_PAUSE
            PauseTimer(t)
        tT[tN] = t
        tN++
    
    #if not USE_HASH_TABLE
        init
            int i = QUANTITY - 1
            while i >= 0
                tT[i] = CreateTimer()
                i--
            tN = QUANTITY
            #debug
                int o = tT[0].id
                if o - OFFSET >= 0
                    o = tT[tN - 1].id
                    if o - OFFSET < 8191
                        return
                print "TIMER UTILS ERROR: OFFSET $OFFSET IS OUT-OF-BOUNDS, SET IT TO $o TO MAKE IT WORK"
 
# indicates a preprocessor flag. #if is a static-if in vJass. Static-if's are based entirely on preprocessing, so the hash # fits.

#define is what cJass uses to set up constants. Rather than creating a global constant, it just inlines the constant value into the game. Sounds weird, so here's the difference:

JASS:
//constants compile to this:
globals
    constant integer FOO = 'hfoo'
endglobals
function bar takes nothing returns nothing
    call CreateUnit(Player(0), FOO, 0, 0, 0)
endfunction
//#define compiles it to this:
function bar takes nothing returns nothing
    call CreateUnit(Player(0), 'hfoo', 0, 0, 0)
endfunction
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
Bribe said:
Also, should I get rid of libraries (everything top-sorts anyway) and just make everything object-oriented?

I'm also not sure if I should use "and" / "or" or if I should use the c-syntax operators "&" / "|" or even "&&" / "||". I think "and" / "or" are fine.

I don't really understand what you mean exactly by "top-sort", but the editor has a big flaw, it doesn't respect the relative order of trigger, until you close and re-open the map (can be used as a noob map protection, while keeping the code readable in the editor).
If i'm not enough clear (likely i suppose) i can make a demo map.

I also really prefer "and" / "or", it's not only faster and easier to write, it's also just clearer.
 
I can top-sort libraries (or classes/structs, if I decide to go all-out OOP) but it would also slow down compilation speed some because I would have to analyze every line of code to properly do the sorting. No big deal if I re-write the compiler in C I guess.

I'd rather not go all-out OOP. I like the syntax of regular functions/globals.
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
The natives would be difficult to convert to be object-oriented like has been suggested. trigger() would obviously create a trigger, but for things that can be created with natives in multiple ways I would have to choose a bias. For example, CreateUnit, CreateUnitByName, CreateUnitAtLoc...

You could still use a .create method which is the most common and then createByName(),createAtLoc(), ...

Or even just support it for only one form, the most common one.

[troll] Eh your TimerUtils is sexier just because the blue version isn't broken [/troll]

I can top-sort libraries (or classes/structs, if I decide to go all-out OOP) but it would also slow down compilation speed some because I would have to analyze every line of code to properly do the sorting. No big deal if I re-write the compiler in C I guess.

Hmm i don't really consider it as a good coding pratice thought.

I'd rather not go all-out OOP. I like the syntax of regular functions/globals.

Me too, but i still hate the jass naming convention which is so much unreliable ...
 
Level 23
Joined
Jan 1, 2009
Messages
1,617
I dont like the idea of complete OOP.

"and" and "or" increase readability imo (also for apprentices), || and && are awkward.

if #if is a static if, why does the # have to be with the "else" too?
#debug ist only compiled in debug-mode i guess?

Im fine with "new", dont know about "delete" tho, pretty used to have a .whatever method for that(but i think it looks better if creating a class and destroying it looks the same)

@TESH discussion:
TESH was outdated long time ago (for me) by Horus, and afaik the Source for Horus is also avaible, meaning that it could possibly changed/adjusted to fit Luck(or some1 just makes a new one).
 
I'm still for c# properties over method operators

Code:
class Date
    private int month = 7

    int Month
        get
            return month
        set
            if ((value > 0) && (value < 13))
                month = value

As well as c# overloaded operators (pretty much exactly what you'd be doing already)
Code:
static Complex operator +(Complex c1, Complex c2) 
      return new Complex(c1.real + c2.real, c1.imaginary + c2.imaginary)


And Bribe, there is a problem with you removing libraries... the init ; P.

Inits don't use other inits, so how will you know how to order them eh? : p
 
Level 28
Joined
Feb 2, 2006
Messages
1,631
Here's a list of some features you could add:
  • nested libraries
  • nested text macros calls
  • templates
  • drop modules (modules as they're implemented in vJass are completely useless in my opinion)
  • typedefs/aliases would be fine, too
  • add enums (type specification like class inheritance - enums of type string etc.)
  • please don't use ".evaluate" for methods by default
  • more nested declarations should be possible (nested function interfaces in classes, enums in classes etc.)
  • friends (C++ like)
  • allow overloading cast operators (C++ like)
  • drop fucking operator overloadings for member modifiers like in vJass (operator a, operator a= ...) which confuses since you can not differ between members and methods anymore
  • maybe add scope indicating keywords like local and ai in which you could only call valid synchronized or valid AI functions, for example: local (<force/player expression)
  • add foreach keyword for default container types group, force and string
  • add possibility to define custom container types which could also be used in foreach loops and for some operations (maybe []-operator)
  • if you define an instances limit for your custom type it should still be possible to implement interfaces without any limit definition (vJass bug)
  • ADD KEYWORD PROTECTED!!!!!!!!!!!!!!
  • add keyword override/new for overwriting/defining new virtual/stub methods (Java, C#, new C++ standard)
  • add dynamic type information
  • don't allow implicit cast from integer to any custom type
  • etc.

I do also prefer Python-like syntax for something like a simple game scripting language but the main problem about vJass has never been it's weird JASS-based syntax.
There has always been a lack of implementing features really usable for all kinds of situations and besides it's huge amount of useless keywords/features confuses more than it helps.

Are you going to use Bison/Flex to create your compiler?
 
Level 19
Joined
Oct 15, 2008
Messages
3,231
This sounds awesome, hmm... If Vexorian agrees to this, then maybe we could have two different expansions to JASSHelper, greatly decreasing the boundaries.
 
Level 19
Joined
Oct 15, 2008
Messages
3,231
Which scripting language or program does Vex use (Or other wc3 tool creators for that matter) to create JASSHelper or to update it?
 
The deadline is the 30th of next month to get at the worst a beta-version out to the public. That deadline will not have support for vJass, though vJass compatibility is definitely going to happen.

To write the compiler for Luck is not going to be too messy. To re-write the injectors and make this work within Jass NewGen Pack... that is going into areas I have absolutely no experience with. Any help on that subject is more than welcome.

Is this even worth doing in Jass NewGen Pack?
 
Status
Not open for further replies.
Top