Muna
Convert lua to make it human-readable and remove obfuscation. Based on luaj parser and lua formatter.
Before
function L1_1(A0_2, A1_2)
local L2_2, L3_2
L2_2 = A1_2.type
L3_2 = EventType
L3_2 = L3_2.EVENT_1
if L2_2 == L3_2 then
L2_2 = A1_2.param3
if not (50 < L2_2) then
goto lbl_11
end
end
L2_2 = false
do return L2_2 end
::lbl_11::
L2_2 = ScriptLib
L2_2 = L2_2.call
L3_2 = A0_2
L2_2 = L2_2(L3_2)
if 2 < L2_2 then
L2_2 = false
return L2_2
end
L2_2 = true
return L2_2
end
condition_EVENT_1 = L1_1
after
function condition_EVENT_1(context, args)
if args.type == EventType.EVENT_1 then
if not (50 < args.param3) then goto lbl_11 end
end
do return false end
::lbl_11::
local var1 = ScriptLib.call(context)
if 2 < var1 then return false end
return true
end
Support
- assign, only one arg (don't support A,B = C)
- if-else
- goto/label/block do ... end
- func call/define
- return
TODO: loop (for - both 2 type) statement
How it works?
It assumed that the var in any assign statement is used only once, so that we can use a map to store the value and simplify almost all assign statement. When it is referred in expression and function arg, we will output its real value. Also, not all assign statement can be simplified due to grammar and idempotent.
The details below show how it handles with the code.
And you may see it will meet some problems when it faces with loop, when the var will be used more than once.
-- input
L2_2 = ScriptLib
L2_2 = L2_2.call
-- output
-- store
L2_2 : ScriptLib.call
We will set L2_2
to ScriptLib.call
and won't output both of them.
-- input
L5_2 = L1_1.challenge_id_no_record
-- output
-- store
L5_2 : L1_1.challenge_id_no_record
Since L1_1
is a global var, we won't store its value and keep the reference.
-- input
L2_2 = L2_2(L3_2)
-- output
local var1 = ScriptLib.call(context)
-- store
L2_2 : var1
We use a temporal var to hold the result of a func call due to the idempotent.
-- input
L2_2 = {}
L2_2[1] = 1
L2_2[2] = nil
L2_2[3] = 2
...
L4_2 = ScriptLib
L4_2 = L4_2.call
L5_2 = A0_2
L6_2 = {}
L7_2 = L2_2[L3_2]
L6_2.config_id = L7_2
L4_2(L5_2, L6_2)
-- output
local var2 = {1, nil, 2}
ScriptLib.call(context, {config_id = var2[var1]})
-- store
L2_2 : var2
L6_2 : {config_id = var2[var1]}
To avoid grammar error like {1, nil, 2}[var1]
, we use a temporal var to hold the table when it is indexed.
-- input
function L2_1(A0_2, A1_2)
...
end
condition_EVENT1 = L2_1
-- output
function condition_EVENT1(context, args)
...
end
-- store
func1 : Function ...
L2_1 : func1
condition_EVENT1 : func1
We use a temporal name funcN
to hold the definition of function. When the block's parser is done, we will start to output the functions & global definitions.
The first arg in func will be replaced with context
, and the second one is args
.
Can I convert to another language?
Of course. I write it out as lua, but you can customize the output language by yourself.