- Joined
- Jul 20, 2018
- Messages
- 177
Yes, it's only one case fixed. I have ideas on how to generalize it but that needs a bigger rewrite of the grammar so dunno if/when i will do it.
> ls
common.j mapscript.j phonyup.j
> jj run phonyup.j -- common.j
processing file 'common.j'... done (3.14159 seconds)
> ls
common.j mapscript.j phonyup.j phony_common.j
> jj check mapscript.j phony_common.j
mapscript.j:2:10: error: undeclared function 'BJDebugMsg'
function f1 takes nothing returns nothing
return
endfunction
function f2 takes nothing returns integer
return 0
endfunction
function f3 takes nothing returns real
return 0.0
endfunction
function f4 takes nothing returns boolean
return false
endfunction
function f5 takes nothing returns string
return ""
endfunction
function f6 takes nothing returns code
return null
endfunction
function f7 takes nothing returns handle
return null
endfunction
function main takes nothing returns nothing
local code x1 = function f1
local code x2 = function f2
local code x3 = function f3
local code x4 = function f4
local code x5 = function f5
local code x6 = function f6
local code x7 = function f7
endfunction
+ not in pjass.exeWe solved this, and the problem was in in pjass.exe.
Yes it is.The 'code' type is rather strange
If pjass says it's correct and it doesn't work ingame that's a bug. I assume it works though? Can't really test it, so feel free to report itOne can assign to a variable of type 'code' a function that returns anything (any type) and nothing (void type). pjass doesn't seem to complain (ignoring the '+filter' flag and the ('Filter', 'Condition') natives) and the game is probably fine with this "loophole" in the type system?
Code:function f1 takes nothing returns nothing return endfunction function f2 takes nothing returns integer return 0 endfunction function f3 takes nothing returns real return 0.0 endfunction function f4 takes nothing returns boolean return false endfunction function f5 takes nothing returns string return "" endfunction function f6 takes nothing returns code return null endfunction function f7 takes nothing returns handle return null endfunction function main takes nothing returns nothing local code x1 = function f1 local code x2 = function f2 local code x3 = function f3 local code x4 = function f4 local code x5 = function f5 local code x6 = function f6 local code x7 = function f7 endfunction
function writeln takes string s returns nothing
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0.0, 0.0, 10.0, s)
endfunction
function unitNew takes integer id returns unit
return CreateUnit(Player(0), id, 0.0, 0.0, 270.0)
endfunction
function f1 takes nothing returns nothing
call writeln("f1")
// return
// there is an implicit return 0 (in the bytecode)
endfunction
function f2 takes nothing returns integer
call writeln("f2")
return 1
// return 0
endfunction
function f3 takes nothing returns real
call writeln("f3")
return 1.0
// return 0.0
endfunction
function f4 takes nothing returns boolean
call writeln("f4")
return true
// return false
endfunction
function f5 takes nothing returns string
call writeln("f5")
return ""
// return null
endfunction
function f6 takes nothing returns code
local code codeNil = null
call writeln("f6")
return function DoNothing
// return codeNil // why can't we just return null?
endfunction
function f7 takes nothing returns handle
call writeln("f7")
return Location(0.0, 0.0)
// return null
endfunction
function testCondition takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerAddCondition(t, Condition(function f7))
if TriggerEvaluate(t) then
call writeln("true")
else
call writeln("false")
endif
endfunction
function testFilter takes nothing returns nothing
local group g
local unit u
set g = CreateGroup()
call GroupAddUnit(g,unitNew('hpea'))
call GroupAddUnit(g,unitNew('hfoo'))
call GroupAddUnit(g,unitNew('hrif'))
call GroupAddUnit(g,unitNew('hkni'))
call GroupEnumUnitsInRect(g, GetWorldBounds(), Filter(function f7))
call writeln("g.size: "+I2S(BlzGroupGetSize(g)))
loop
set u = FirstOfGroup(g)
exitwhen null == u
call GroupRemoveUnit(g, u)
call writeln(GetUnitName(u))
endloop
endfunction
returning code function DoNothing is true, null is false (note: "return null" in a function that returns code doesn't compile?)
return null
used to work for a function returning code but it was changed in one of the recent patches. I think i was hestiant to change pjass but if it's still forbidden i might need to add a flag to let the user chose if it is allowed or not depending on their patch :/Fixed.+ not in pjass.exe
Yes it works as @Aniki said. You can pass any function with no arguments and with any return type toCan't really test it, so feel free to report it
TriggerAddAction
, Filter
, Condition
, etc. Basically, this is why vJass works. Inside vJass all functions for calling methods/funcs before their declaration return true
and then they passed to TriggerAddAction
and TriggerAddCondition
for .execute()
and .evaluate()
. These funcs return boolean because original pjass complains when you pass a function with not a boolean return to Filter
or Condition
. Actually, this is not required at all. I intentionally pass void functions to Filter
since all necessary actions a filter function does and no true
return is required.function Y takes nothing returns nothing
local A a = A.create.evaluate(1)
call a.m.evaluate(2)
endfunction
struct A
readonly integer info
static method create takes integer b returns thistype
local thistype this = allocate()
set info = b
return this
endmethod
method m takes integer a returns real
set info = info + a
return I2R(info)
endmethod
method onDestroy takes nothing returns nothing
set info = 1
endmethod
endstruct
globals
//JASSHelper struct globals:
constant integer si__A=1
integer si__A_F=0
integer si__A_I=0
integer array si__A_V
integer array s__A_info
trigger st__A_create
trigger st__A_m
trigger st__A_onDestroy
trigger array st___prototype2
integer f__result_integer
integer f__arg_integer1
integer f__arg_this
real f__result_real
endglobals
//Generated method caller for A.create
function sc__A_create takes integer b returns integer
set f__arg_integer1=b
call TriggerEvaluate(st__A_create)
return f__result_integer
endfunction
//Generated method caller for A.m
function sc__A_m takes integer this,integer a returns real
set s__A_info[this]=s__A_info[this] + a
return I2R(s__A_info[this])
endfunction
//Generated method caller for A.onDestroy
function sc__A_onDestroy takes integer this returns nothing
set s__A_info[this]=1
endfunction
//Generated allocator of A
function s__A__allocate takes nothing returns integer
local integer this=si__A_F
if (this!=0) then
set si__A_F=si__A_V[this]
else
set si__A_I=si__A_I+1
set this=si__A_I
endif
if (this>8190) then
call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Unable to allocate id for an object of type: A")
return 0
endif
set si__A_V[this]=-1
return this
endfunction
//Generated destructor of A
function sc__A_deallocate takes integer this returns nothing
if this==null then
call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Attempt to destroy a null struct of type: A")
return
elseif (si__A_V[this]!=-1) then
call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Double free of type: A")
return
endif
set f__arg_this=this
call TriggerEvaluate(st__A_onDestroy)
set si__A_V[this]=si__A_F
set si__A_F=this
endfunction
function sc___prototype2_execute takes integer i,integer a1 returns nothing
set f__arg_integer1=a1
call TriggerExecute(st___prototype2[i])
endfunction
function sc___prototype2_evaluate takes integer i,integer a1 returns integer
set f__arg_integer1=a1
call TriggerEvaluate(st___prototype2[i])
return f__result_integer
endfunction
function Y takes nothing returns nothing
local integer a= sc__A_create(1)
call sc__A_m(a,2)
endfunction
function s__A_create takes integer b returns integer
local integer this= s__A__allocate()
set s__A_info[this]=b
return this
endfunction
function s__A_m takes integer this,integer a returns real
set s__A_info[this]=s__A_info[this] + a
return I2R(s__A_info[this])
endfunction
function s__A_onDestroy takes integer this returns nothing
set s__A_info[this]=1
endfunction
//Generated destructor of A
function s__A_deallocate takes integer this returns nothing
if this==null then
call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Attempt to destroy a null struct of type: A")
return
elseif (si__A_V[this]!=-1) then
call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Double free of type: A")
return
endif
call s__A_onDestroy(this)
set si__A_V[this]=si__A_F
set si__A_F=this
endfunction
//Struct method generated initializers/callers:
function sa__A_create takes nothing returns boolean
local integer b=f__arg_integer1
local integer this= s__A__allocate()
set s__A_info[this]=b
set f__result_integer= this
return true
endfunction
function sa__A_m takes nothing returns boolean
local integer this=f__arg_this
local integer a=f__arg_integer1
set s__A_info[this]=s__A_info[this] + a
set f__result_real= I2R(s__A_info[this])
return true
endfunction
function sa__A_onDestroy takes nothing returns boolean
local integer this=f__arg_this
set s__A_info[this]=1
return true
endfunction
function sa___prototype2_s__A_create takes nothing returns boolean
local integer b=f__arg_integer1
local integer this= s__A__allocate()
set s__A_info[this]=b
set f__result_integer= this
return true
endfunction
function jasshelper__initstructs13218656 takes nothing returns nothing
set st__A_create=CreateTrigger()
call TriggerAddCondition(st__A_create,Condition( function sa__A_create))
set st__A_m=CreateTrigger()
call TriggerAddCondition(st__A_m,Condition( function sa__A_m))
set st__A_onDestroy=CreateTrigger()
call TriggerAddCondition(st__A_onDestroy,Condition( function sa__A_onDestroy))
set st___prototype2[1]=CreateTrigger()
call TriggerAddAction(st___prototype2[1],function sa___prototype2_s__A_create)
call TriggerAddCondition(st___prototype2[1],Condition(function sa___prototype2_s__A_create))
endfunction
jasshelper__initstructs13218656
and sa___prototype2_s__A_create
.False is returned only when all bits of a return value are 0. Such values are
- returning nothing is false (probably because of the implicit return 0 in the bytecode)
- returning integer 1 is true, 0 is false
- returning real 1.0 is true, 0.0 is false
- returning boolean true is true, false is false :^)
- returning string "" is true, null is false ("" has a non-zero id in the string table?)
- returning code function DoNothing is true, null is false (note: "return null" in a function that returns code doesn't compile?)
- returning handle Location(0, 0) is true, null is false
false
, 0
, 0.
, null
. Any other value is not 32 zeros; so, they are true. Also, maybe -0.
is also true because the first bit is 1.Yeah that's stuff in the Lexer that has been there forever.I want to report a bug, line 17 got error but pjass did not recognize the error @LeP
edit: I used ENG VI keyboard, when u press number or shift-number it will generate some strange characters. It cause no error in pjass syntax checker but unplayable
Since i've been doing work on jhcr recently pjass threw this at me as i heavily make usage of function literals.Thanks for testing. Indeed the fix is very easy but it's not pjass' domain to do so.
Here is a fresh pjass version which reports this.
Code:$ cat tests/should-fail/native-as-code.j native TriggerSyncStart takes nothing returns nothing function foo takes nothing returns nothing local code bla = function TriggerSyncStart endfunction $ ./pjass tests/should-fail/native-as-code.j tests/should-fail/native-as-code.j:4: Cannot use native 'TriggerSyncStart' as code tests/should-fail/native-as-code.j failed with 1 error Parse failed: 1 error total
function A takes nothing returns code
return function TriggerSyncStart
endfunction
function B takes nothing returns nothing
local code c = function TriggerSyncStart
endfunction
function C takes nothing returns code
return null
endfunction
No. As for adding them: when i looked into it prior it didn't seem very straightforward. Which doesn't have to mean that it's difficult to do. But in the end it was too much work for too little gain to me. YMMVHi,
is it possible to show the columns in addition to the lines for syntax errors?
This works on 1.26. When I tried to launch map on the latest patch, lobby reported an error.Also can anybody test if using null still fails?
Map crashes without printing anything right after loading on both 1.26 and the latest.Can anyone confirm or deny that you can or cannot use natives as code literals in the latest patch?
Thank you very much. It still feels very bad to work on pjass w/o having a recent wc3 setup. I might have set it up again...This works on 1.26. When I tried to launch map on the latest patch, lobby reported an error.
Map crashes without printing anything right after loading on both 1.26 and the latest.