• 🏆 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!

function foo takes nothing returns <array>

Status
Not open for further replies.
Level 10
Joined
Sep 19, 2011
Messages
527
hi, i'm trying to rebuild vjass from scratch using antlr4 (nothing serious, just for fun) and i thought that it would be cool to be able to return arrays from functions, so you can write something like:

JASS:
struct test
	private static method lower takes nothing returns integer array
		local integer array e
		
		e[0] = 4
		e[1] = 5
		e[2] = 6
		e[3] = 7
		e[4] = 8
		
		return e
	endmethod
	
	private static method higher takes nothing returns integer array
		local integer array e
		
		e[0] = 4
		e[1] = 5
		e[2] = 6
		e[3] = 7
		e[4] = 8
		e[5] = 9
		e[6] = 10
		e[7] = 11
		
		return e
	endmethod

	private static method onInit takes nothing returns nothing
		local integer array a = thistype.lower()
		local integer array b = thistype.higher()
		local integer i
		
		set i = 0
		loop
			exitwhen a[i] == 0
			call BJDebugMsg("a[" + I2S(i) + "] = " + I2S(a[i]))
			set i = i + 1
		endloop
		
		call BJDebugMsg("--------------------------------")
		
		set i = 0
		loop
			exitwhen b[i] == 0
			call BJDebugMsg("b[" + I2S(i) + "] = " + I2S(b[i]))
			set i = i + 1
		endloop
	endmethod
endstruct

and it will be translated to:

JASS:
globals
	integer array integer_r
	integer integer_r_last_index = 0
	
	// only one array for each variable type
	// unit array unit_r
	// real array real_r
	// ...
endglobals

// only one of these for each variable type
function reset_integer_r takes nothing returns nothing
	loop
		set integer_r[integer_r_last_index] = 0			
		exitwhen integer_r_last_index == 0
		set integer_r_last_index = integer_r_last_index - 1
	endloop
endfunction

// only one of these for each variable type
function set_integer_r takes integer index, integer value returns nothing
	if (index < 0) then
		// throw error -> thanks icemanbo
	endif
	
	if (index > integer_r_size) then
		set integer_r_size = index
	endif
	
	set integer_r[index] = value
endfunction

struct test
	private static method lower takes nothing returns nothing
		call reset_integer_r()
		
		call set_integer_r(0, 4)
		call set_integer_r(1, 5)
		call set_integer_r(2, 6)
		call set_integer_r(3, 7)
		call set_integer_r(4, 8)
	endmethod

	private static method higher takes nothing returns nothing
		call reset_integer_r()
	
		call set_integer_r(0, 4)
		call set_integer_r(1, 5)
		call set_integer_r(2, 6)
		call set_integer_r(3, 7)
		call set_integer_r(4, 8)
		call set_integer_r(5, 9)
		call set_integer_r(6, 10)
		call set_integer_r(7, 11)
	endmethod

	private static method onInit takes nothing returns nothing
		local integer array a
		local integer array b
		local integer i
		
		call thistype.higher()
		set i = integer_r_last_index
		
		loop
			set a[i] = integer_r[i]
			exitwhen i == 0
			set i = i - 1
		endloop
		
		call thistype.lower()
		set i = integer_r_last_index
		
		loop
			set b[i] = integer_r[i]
			exitwhen i == 0
			set i = i - 1
		endloop
		
		set i = 0
		loop
			exitwhen a[i] == 0
			call BJDebugMsg("a[" + I2S(i) + "] = " + I2S(a[i]))
			set i = i + 1
		endloop
		
		call BJDebugMsg("--------------------------------")
		
		set i = 0
		loop
			exitwhen b[i] == 0
			call BJDebugMsg("b[" + I2S(i) + "] = " + I2S(b[i]))
			set i = i + 1
		endloop
	endmethod
endstruct

is it a good way to handle it?

greetings.
 
Last edited:
Seems interesting.

Maybe also check if index >= 0 in the set_integer_r function.

JASS:
// here
...
exitwhen a[i] == 0
...
// and here
exitwhen b[i] == 0
0 may be a valid integer, but here it will just exit if the indexed integer value equals "0"?

... because now you don't stop when value equals 0, but when the whole array was worked through... so it is different to what you do here:
JASS:
call thistype.higher()
set i = integer_r_size    
   
loop
    set a[i] = integer_r[i]
    exitwhen i == 0
    set i = i - 1
endloop

And you do this:
set integer_r_size = index
... but actually when do something like:
call set_integer_r(0, 4) -> integer_r_size will be 0, but actually the array size is 1?
 
Level 10
Joined
Sep 19, 2011
Messages
527
Maybe also check if index >= 0 in the set_integer_r function.

you're right

tested and seems like jass accepts negative index, does this have any con?

0 may be a valid integer, but here it will just exit if the indexed integer value equals "0"?

it was just an example. the second one though, assigns the values so it has to iterate over the last registered index (because you can't for example integer array i = <another integer array>).

integer_r_size will be 0, but actually the array size is 1?

right, integer_r_size should be integer_r_last_index since it doesn't store the array size but the last index.
 
Last edited:
Level 29
Joined
Jul 29, 2007
Messages
5,174
No, it's not a good way to handle it.
You handle it using one array, and handling that array as if it's one array, so you have one array.

JASS:
local integer array a = thistype.lower()
local integer array b = thistype.higher()

a[0] + b[0] == a[0] * 2

The only actual safe way to take/return arrays is with hashtables. Don't want the speed penalty? then the only other way would be with arrays with defined sizes, which allow you to split N real arrays into M virtual arrays, except that the simple math calculations might not be faster than the hashtable natives.

You people should really stop trying to make Jass a modern language, you are wasting your time on nonsense.
Writing plain Jass is easier than all of these "simplified" "advanced" compilers you want to build.
 
Level 10
Joined
Sep 19, 2011
Messages
527
@ghost, didn't understand anything in your response. i think you didn't understand that higher and lower functions were just mere examples for showing how it would be.

You people should really stop trying to make Jass a modern language, you are wasting your time on nonsense.

(nothing serious, just for fun)
 
Seems to work in my head. You would have to consider some weird cases, such as when a person defines a local that points to a value of a directly after the declaration, e.g.:
JASS:
local integer array a = thistype.lower()
local integer array b = thistype.higher()
local integer i = a[5] // this line
And perhaps even for locals that reference "i" :p It gets a bit convoluted.

Too bad there isn't a way to do it without the O(n) reset (unless maybe you use hashtables). It is still neat as long as people aren't retarded with it and try to do things like set the 8191 index. But I suppose it has been that way with vJASS too...
 
Level 10
Joined
Sep 19, 2011
Messages
527
It is still neat as long as people aren't retarded with it and try to do things like set the 8191 index.

solution for retarded time:

JASS:
globals	
	integer array ui // used indexs
	integer ui_c = 0 // array length
	integer array i  // array to "copy"
endglobals

function reset_i takes nothing returns nothing
	set ui_c = ui_c - 1

	loop
		set i[ui[ui_c]] = 0
	
		exitwhen ui_c == 0
		set ui_c = ui_c - 1
	endloop
endfunction

function set_i takes integer index , integer value returns nothing
	set ui[ui_c] = index
	set ui_c = ui_c + 1
	
	set i[index] = value
endfunction

struct e
	static method onInit takes nothing returns nothing
		local integer array a
		local integer tmpa
		
		call set_i(8190, 2)
		call set_i(5100, 1)
		
		set tmpa = ui_c-1
		loop
			set a[ui[tmpa]] = i[ui[tmpa]]
			call BJDebugMsg("a[" + I2S(ui[tmpa]) + "] = " + I2S(a[ui[tmpa]])) // prints -> a[5100] = 1, a[8190] = 2
		
			exitwhen tmpa == 0
			set tmpa = tmpa - 1
		endloop
	endmethod
endstruct

this way, we only iterate over the used indexes and not at the highest one.
 
Status
Not open for further replies.
Top