Format ElfObj64

include "../include/prog.h" "../include/prog.oh"
const cond_block_size=DWORD
const brace_blocks_max=100*cond_block_size
const swapsdata_max=0x100

#multithread unsafe
dataxu flag#1
charx type#1
data compare_bool=FALSE
datax counter#1
datax blocks_mem#brace_blocks_max
wordu swapsdata_index=0
valuexu swapdsdata#swapsdata_max

char operations_base="+-*/%&|^<>?"
#                     + - * / % & | ^ < > ? ( ! = e1e2
char operations_full={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} #here can go another way but for the sack of zero safe init, even is zero init also at c, and at our language with null res pref
char parse_pack_chars={Equals,0,0,0} #but parse_pack_chars[0] is hardcoded this way, a tradeoff with c

const swapdata_max=0x400

#win32 with _
#all of these are builtin from string/stdlib
importx "strcspn" strcspn
importx "strchr" strchr
importx "memcpy" memcpy
importx "sscanf" sscanf
importx "strpbrk" strpbrk
importx "malloc" malloc #builtin
importx "free" free

^import "str_expression_at_start" str_expression_at_start 2 #full

^import "debug_code" debug_code #full return
^import "spaces" spaces 1

^import "str_expression_at_start_withEndCare" str_expression_at_start_withEndCare 2 #full

#bool
function action_parse_utilEndTypes(ss ?op,ss p_op,sd endtype1,sd endtype2)
    #when p_op is set, is to store the multiple kind of endtypes
    if p_op!=0
        set p_op# op
        if op=endtype2
            return (TRUE)
        endif
    endif
    if op=endtype1;return (TRUE);endif
    return (FALSE)
endfunction

import "is_numeric" is_numeric

#strpbrk
function action_code_membersplit(ss ac)
	char delims=".["
	callret strpbrk(ac,#delims) #pointer
endfunction

function brace_blocks_counter()
	return globalp.counter
end
function brace_blocks_counter_init()
	set globalp.counter 0
endfunction
function brace_blocks_counter_inc()
	inc globalp.counter
endfunction
function cond_blocks_noerror()
	callret cond_blocks_at_index(globalp.counter)
endfunction

function cond_blocks_at_index(sd i)
	sd blocks;set blocks #globalp.blocks_mem
	mult i (cond_block_size)
	add blocks i
	return blocks
endfunction

function for_in(sdu ?f)
	set globalp.flag f
	and globalp.flag (flag_forin1)
end
function for_in_ptr()
	return #globalp.flag
end

function ret_cont_break()
	return #globalp.type
end

function action_data()
	call brace_blocks_counter_init()
	set globalp.type (ret_cont_break_nothing)
end
function action_parse_init()
	ss a;set a #globalp.operations_full
	sdu ?operations_base_size=\globalp.operations_base-1
	call memcpy(a,#globalp.operations_base,operations_base_size)
	add a operations_base_size
	char c={Openingbracket,Exclamationmark,Equals}
	call memcpy(a,#c,3)
end

function free_a_swap()
	dec globalp.swapsdata_index
	sv pointer=:
	mult pointer globalp.swapsdata_index
	add pointer #globalp.swapdsdata
	call free(pointer#)
end
function free_all_swaps()
	while globalp.swapsdata_index!=0
		call free_a_swap()
	end
end

^import "action_code_get" action_code_get
^import "action_code_values_index" action_code_values_index #full
import "memtrail" memtrail
import "memtrailstrict" memtrailstrict
import "compat" compat
import "debug_phase_code_remove" debug_phase_code_remove
import "mem_cmp_bool" mem_cmp_bool
^import "escape_action_endcom" escape_action_endcom 1 #full return
import "swf_actionblock_get_size" swf_actionblock_get_size
import "label_add" label_add
import "swf_actionblock_get_mem_size" swf_actionblock_get_mem_size

#aftercallimport ebool

import "action_code_set" action_code_set
import "action_code_set_pointer" action_code_set_pointer
import "error" error
const add=Plus
const sub=Hyphen
const mlt=Asterisk
const div=Slash
const modulo=Percent
const and=Ampersand
const or=Verticalbar
const xor=Caret
const shl=Lessthan
const sar_shr=Greaterthan
const ifElse_sign=Questionmark
#pointer
function action_code_row(ss ac,ss ?a_block_detected)
	callret action_code_row_ex(ac,a_block_detected,-1)
endfunction
#pointer
function action_code_row_ex(ss ac,ss ?a_block_detected,sd ?else_index)
	ss p;set p action_code_row_ex_wrap(ac,a_block_detected,else_index)
	if p#=(Slash)
		inc p
		if p#=(Slash)
			set p escape_action_endcom(p) #cannot inc p because //\n ending lines will not be recognized
			return p
		end
		call error("not a right line end comment")
	end
	return p
end
import "debug_phase_parse" debug_phase_parse
#pointer
function action_code_row_ex_wrap(ss ac,ss ?a_block_detected,sd ?else_index)
    sv p_c
    setcall p_c debug_code()
    set p_c# ac
    ss atstart=NULL
    while atstart!=ac
        sd ?flags
        sd for_detected=0
        set atstart ac
        setcall ac action_parse_conditions(ac,#flags,#for_detected)
        if atstart!=ac
            if for_detected=0
                if ac#!=(Openparenthesis)
                    call error("open parenthesis sign expected")
                endif
                #using the operations function
                inc ac
				char closecompare=Closeparenthesis
                setcall ac action_code_row_parse_tool(ac,closecompare)
                #if ac#!=closecompare
                #    call error("close parenthesis expected")
                #endif
            endif
            #important settings
            if a_block_detected=(TRUE)
                or flags (consecutive_flag)
            endif
            call brace_blocks_add_parse(flags)
            set a_block_detected (TRUE)
        endif
    endwhile
	setcall ac action_code_row_parse(ac,a_block_detected,else_index)
	#around: else if(2==2){return 2;}else{return 3;}, 4 breakpoints, with \n-s,this here and not at action_code_row,1 breakpoint
	call debug_phase_parse(ac)
    return ac
endfunction

function forin(sd pointer)
	#getvar/member/enumerate is not overlapping for_three
	if globalp.flag!=(flag_forin1)
		#ActionEnumerate2 will use an object
		call action_code_take_pointer(pointer)
	else
		#enum can take ActionEnumerate(x.x[z]), x.x ... is a pattern that ActionEnumerate will recognize
		call action_code_set((ActionEnumerate))
		callg action_code_set_pointer(pointer)
	end
end


#pointer
function action_parse_conditions(ss ac,sd p_flags,sd p_for_detected)
    #if
    ss pointer
    setcall pointer str_expression_at_start(ac,"if")
    if pointer!=ac
        set p_flags# (if_marker)
        call action_code_set((ActionIf))
        return pointer
    endif
    #while
    setcall pointer str_expression_at_start(ac,"while")
	if pointer!=ac
        call action_code_set((while_marker))
        set p_flags# (while_marker)
        return pointer
	endif
    #for
        setcall pointer str_expression_at_start(ac,"for")
        if pointer=ac;return pointer;endif
        #
        call action_code_set((for))
        set p_flags# (while_marker)
        set p_for_detected# 1
        #
        if pointer#!=(Openparenthesis)
            call error("expecting Open Parenthesis at for loop")
        endif
        inc pointer
        set ac pointer
        #
        ss cursor;ss marker
        #forIn or for x;x;x
        sd pos1;setcall pos1 strcspn(pointer,")")
        sd pos2;setcall pos2 strcspn(pointer,";")
        if pos2<pos1
            #for x;x;x
            call action_code_set((for_three))
            #ac X;x;x
            set cursor pointer;add cursor pos2
            if cursor#=0
                call error("expecting ';' at for loop, first part")
            endif
                            #is for for(;x;x) the !=
            if cursor!=ac;call action_parse_pack(ac,(Semicolon));endif
                            #is for for(;x;x)
            call action_code_set((inter_for))
            inc cursor
            #pointer x;X;x
            set pointer cursor
            setcall pos2 strcspn(pointer,";")
            add cursor pos2
            if cursor#=0
                call error("expecting ';' at for loop, second part")
            endif
            #cursor x;x;X
            inc cursor
            #not let for(x;x;heatMaker), heatMaker will be ignored and violation will come
            if cursor#!=(Closeparenthesis);setcall cursor action_parse_pack(cursor,(Closeparenthesis))
            else;inc cursor;endelse
            call action_code_set((inter_for))
            call action_code_row_parse_tool(pointer,(Semicolon))
            return cursor
        endif
        #
        setcall pointer str_expression_at_start(pointer,"var")
        setcall pos1 strcspn(pointer," ")
        set cursor pointer;add cursor pos1
        if cursor#=0
            call error("expecting 'space' at for loop")
        endif
        set cursor# 0
        inc cursor;setcall cursor spaces(cursor)
        setcall marker str_expression_at_start(cursor,"in")
        if marker=cursor
            call error("expecting 'in' at for loop")
        endif
        setcall pos1 strcspn(marker,")")
        set cursor marker
        add cursor pos1
        if cursor#=0
            call error("expecting Close Parenthesis at for loop")
        endif
        set cursor# 0
        #
	call forin(marker)
        #
        if pointer!=ac
            call action_code_set((ActionDefineLocal))
            call action_code_set_pointer(pointer)
        else
            call action_parse_left_holder(pointer,(ActionSetVariable),(ActionSetMember))
        endelse
        inc cursor
        return cursor
endfunction
#pointer
function action_code_row_parse(ss ac,ss ?a_block_detected,sd ?else_index)
	if ac#=(Openingbrace)
        if a_block_detected=(FALSE)
            call brace_blocks_add_parse((normal_marker))
        endif
        inc ac
        return ac
	endif
	if ac#=(Closingbrace)
        if a_block_detected=(TRUE)
            call error("unexpected closing brace sign after code block opened")
        endif
        inc ac
		callret else_verify(ac,else_index)
	endif
	setcall ac action_code_row_parse_instrument(ac)
    if a_block_detected=(TRUE)
    #ex: if(a==b)x=3;
        setcall ac else_verify(ac,else_index)
    endif
    return ac
endfunction
#pointer
function else_verify(ss ac,sd ?else_index)
	#this condition for: else >expression< placing in else{} block will demonstrate, and don't compare unsigned, else index can go -1
	if globalp.counter>else_index
		call brace_blocks_remove_parse()
	endif
	#opened else index same with current index: return at else
	if else_index=globalp.counter
		return ac
	endif

	ss ?bool_is_elseif

	ss pointer
	!xor bool_is_elseif bool_is_elseif ##same problems with recursive vars at .o
	setcall pointer else_elseif_expression(ac,#bool_is_elseif)
	if ac=pointer
		return ac
	endif
	sd ?c_ind;set c_ind globalp.counter
	while pointer!=ac
		call action_code_set((else_marker))
		call brace_blocks_add_parse((else_marker))
		#c_ind is lower
		sd ?ind;set ind globalp.counter
		while c_ind!=ind
			ss the_new_pointer;set the_new_pointer pointer
			setcall the_new_pointer action_code_row_ex(pointer,(FALSE),ind)
			if the_new_pointer=pointer;call error("Else not closed");endif
			set pointer the_new_pointer
			#
			set c_ind globalp.counter
		endwhile
		set ac pointer
		ss ?prev_else_elseif;set prev_else_elseif bool_is_elseif
		setcall pointer else_elseif_expression(ac,#bool_is_elseif)
		if prev_else_elseif=(FALSE);if bool_is_elseif=(TRUE)
			call error("not expecting Else and then Else If")
		endif;endif
	endwhile
	call brace_blocks_remove_parse_else()
	return ac
endfunction
#next/same
function else_elseif_expression(ss ac,ss p_elseif)
    set p_elseif# (FALSE)
    ss pointer
    setcall pointer str_expression_at_start(ac,"else")
    if ac=pointer
        return ac
    endif
    setcall ac str_expression_at_start(pointer,"if")
    if pointer=ac
        return pointer
    endif
    set p_elseif# (TRUE)
    return pointer
endfunction
#pointer
function action_code_row_parse_instrument(ss ac)
    ss pointer
    setcall pointer action_code_parse_leftfunction(ac)
    if pointer!=ac
        return pointer
    endif
    setcall pointer str_expression_at_start(ac,"return")
    if pointer!=ac
        call action_code_set((ActionReturn))
		char an_end=Semicolon
		callret action_code_row_parse_tool(pointer,an_end)
    endif
    setcall pointer str_expression_at_start_withEndCare(ac,"break")
    if pointer!=ac
        call action_code_set((break_flag))
        return pointer
    endif
    setcall pointer str_expression_at_start_withEndCare(ac,"continue")
    if pointer!=ac
        call action_code_set((continue_flag))
        return pointer
    endif
    #
	callret action_parse_pack(ac,(Semicolon))
endfunction
#pointer
function action_parse_pack(ss ac,ss ?endChar)
	ss delims=1
	add delims #globalp.parse_pack_chars
	set delims# endChar
	inc delims

	ss pointer
	sd isnewvar=FALSE
	sd isdelete
	setcall pointer str_expression_at_start(ac,"var")
	if pointer!=ac
		set isnewvar (TRUE)
		set delims# (Nullchar)
	else
		set isdelete (FALSE)
		setcall pointer str_expression_at_start(ac,"delete")
		if pointer!=ac
			set isdelete (TRUE)
			set delims# (Nullchar)
		else
			set pointer spaces(pointer) #ffdec, /tests/ffdec/ff
			set delims# (Colon)
		endelse
	endelse
	set ac strcspn(pointer,#globalp.parse_pack_chars)

	ss ?op   ;#this is recursive stack for future expands, now is simple
	add ac pointer
	set op ac#
	if op=(Colon) #since goto markers, this is the label
		call label_add(pointer)
		inc ac
		return ac
	end
	ss marker;set marker ac
	if ac#!=(Nullchar)
	#	set ac# (Nullchar) let this at memtrail or at test for inc_dec
		inc ac
	end

	if isnewvar=(TRUE)
		call memtrail(marker)
		if op=(Equals)
			call action_code_set((ActionDefineLocal))
			call action_code_set_pointer(pointer)
		else
			call action_code_set((ActionDefineLocal2))
			call action_code_set_pointer(pointer)
			return ac
		endelse
	elseif isdelete=(FALSE)
		sd ?inc_dec
		sd ?mixt_action
		if op!=(Equals)
			set inc_dec 0
			ss test
			set test marker
			sub test 2
			sd another_test
			set another_test test
			sub another_test pointer
			#test for some size for ++ or --
			if another_test>0
				if test#=(Plus)
					inc test
					if test#=(Plus)
						set inc_dec (ActionIncrement)
						dec test
						set test# 0
					endif
				elseif test#=(Hyphen)
					inc test
					if test#=(Hyphen)
						set inc_dec (ActionDecrement)
						dec test
						set test# 0
					endif
				endelseif
			endif
			#if not ++ or -- return the current location (x;heatMaker;)
			if inc_dec=0
				return ac  ##here nothing for X. is ignoring
			endif
		else
			#test for += .. |= ..
			setcall mixt_action action_parse_test_mixt_equal(pointer,#marker)
			#trail pointer at marker, after mixt shift
			call memtrail(marker)
		endelse
		call action_parse_left_holder(pointer,(ActionSetVariable),(ActionSetMember))
		if op=(Equals)
			#mixt or not mixt
			if mixt_action!=0
				call action_code_set((mixt_equal))
				call action_code_set(mixt_action)
			endif
		else
			#is inc dec case
			call action_code_set(inc_dec)
			return ac
		endelse
	else
		call memtrail(marker)
		call action_parse_left_holder(pointer,(ActionDelete2),(ActionDelete))
		return ac
	endelse
	set ac spaces(ac) #ffdec
	callret action_parse_right(ac,endChar)
endfunction
function action_parse_left_holder(ss pointer,sd ac1,sd ac2)
    ss test
    setcall test action_code_membersplit(pointer)
    if test=(NULL)
        call action_code_set(ac1)
        call action_code_set_pointer(pointer)
    else
        call action_code_set(ac2)
	callg action_code_member(pointer,-1)
    endelse
endfunction
#0/action
function action_parse_test_mixt_equal(ss start,sv p_ac)
	ss ac;set ac p_ac#
	dec ac
	ss dif;set dif ac;sub dif start
	if dif<=0
		return 0
	endif
#	#is this was true? a['b']=c;for(d['e']=f;a==b;j['k']=l){}  is where action_parse_pack is and there ] is not 0, left_holder is later parsed
#	if ac#=0
#		#0 can be set(qw['z']=x will be 00x) and at strchr will not be NULL
#		return 0
#	endif
	ss ?op;set op ac#
	ss p_op;setcall p_op strchr(#globalp.operations_base,op)
	if p_op=(NULL);return 0;endif

	ss pointer;set pointer ac
	if op=(shl);vstr missing_shl="expecting value and <<"
		dec ac
		if ac=start
			call error(missing_shl)
		elseif ac#!=(shl)
			call error(missing_shl)
		endelseif
	elseif op=(sar_shr);vstr missing_sar_shr="expecting value and >>"
		dec ac
		if ac=start
			call error(missing_sar_shr)
		elseif ac#!=(sar_shr)
			call error(missing_sar_shr)
		endelseif
		dec ac
		if ac#!=(sar_shr)
			inc ac
		endif
	endelseif
	set p_ac# ac
	#this was for strings but now is memtrail()	set ac# 0
	callret action_parse_take_action(op,pointer)
endfunction
#pointer
function action_parse_right(ss ac,ss ?endChar)
    ss pointer
    #can be a function definition
    setcall pointer action_code_parse_deffunction(ac)
    if pointer!=ac
        return pointer
    endif
    #
	callret action_code_row_parse_tool(ac,endChar)
endfunction
#pointer
function action_code_row_parse_tool(ss ac,sd endtype)
	callret action_code_row_parse_tool_util(ac,0,endtype,0)
endfunction

#pointer
function action_code_row_parse_tool_util(ss ac,ss p_op,sd endtype1,sd endtype2)
    if ac#=0
        call error("expeting a number, variables operations")
    endif
    #a new object
    ss pointer
    setcall pointer str_expression_at_start(ac,"new")
    if pointer!=ac
		setcall ac action_code_parse_new_or_call(pointer,(new_action),pointer)
        sd ?bl;setcall bl action_parse_utilEndTypes(ac#,p_op,endtype1,endtype2)
        if bl=(TRUE);inc ac;endif
        return ac
    endif
    sd ifElse_bool=FALSE
    setcall ac action_parse_loop(ac,p_op,endtype1,endtype2,#ifElse_bool)
    if ifElse_bool=(FALSE)
        call action_code_set((math_end))
    endif
    return ac
endfunction
#pointer
function action_parse_loop(ss ac,ss p_op,sd endtype1,sd endtype2,sd p_ifElse_bool)
	sd ?bl
	#can be on the stack but char is low value; ends are set again when recursivity
	ss end2
	set end2 #globalp.operations_full
	add end2 \globalp.operations_full-2
	sss end=-1
	add end end2
    #
    whiletrue
		set ac spaces(ac) #ffdec
		ss ?op         ;#op can't be charx, is recursive stack variable, is cleared in two places, here and at sv p_op
		sd was_parenthesis=0
		if ac#=(Openparenthesis)
			call action_code_set((parenthesis_start))
			inc ac
			setcall ac action_code_row_parse_tool(ac,(Closeparenthesis))
			#0 is the marker after op set; used at strings; and logicalAnd logicalOr shr and sar are not needing 0 but it's faster for strings
			set ac spaces(ac) #ffdec
			set op ac#;set ac# 0
			set was_parenthesis 1
		endif
		#set end: is static variable and can be mod again inside previous function
		set end# endtype1
		set end2# endtype2
		#
		if was_parenthesis=0
			!xor op op  ##or go with sv p_op to clean inside the function but then will pe problems at .c
			setcall ac action_code_take_main(ac,#op,#globalp.operations_full)
			if op=(ifElse_sign)
				inc ac
				call action_code_set((ifElse_start))
				set p_ifElse_bool# (TRUE)
				setcall ac action_code_row_parse_tool(ac,(Colon))
				callret action_code_row_parse_tool_util(ac,p_op,endtype1,endtype2)
			endif
		endif
		#
		setcall ac action_code_extended_operations(ac,op)
		if globalp.compare_bool=(TRUE)
			set globalp.compare_bool (FALSE)
		else
			if op=0
				if p_op!=0
					set p_op# op
				endif
				return ac
			endif
			setcall bl action_parse_utilEndTypes(op,p_op,endtype1,endtype2)
			if bl=(TRUE);return ac;endif
			sd ?x;setcall x action_parse_take_action(op,ac)
			call action_code_set(x)
		endelse
    endwhile
endfunction
#action
function action_parse_take_action(ss ?op,ss ac)
	sd ?x
	if op=(add);set x (ActionAdd2)
	elseif op=(sub);set x (ActionSubtract)
	elseif op=(mlt);set x (ActionMultiply)
	elseif op=(div);set x (ActionDivide)
	elseif op=(modulo);set x (ActionModulo)
	elseif op=(and)
		dec ac
		if ac#=(and);set x (ActionAnd);else;set x (ActionBitAnd);endelse
	elseif op=(or)
		dec ac
		if ac#=(or);set x (ActionOr);else;set x (ActionBitOr);endelse
	elseif op=(xor);set x (ActionBitXor)
	elseif op=(shl);set x (ActionBitLShift)
	elseif op=(sar_shr)
		sub ac 2  #here there is already >> test
		if ac#!=(sar_shr);set x (ActionBitRShift)
		else;set x (ActionBitURShift);endelse
	else
		#at "asd"x can be x
		call error("unrecognized actionscript operation")
	endelse
	return x
endfunction
#pointer
function action_code_extended_operations(ss pointer,ss ?op)
    #comparison
    sd ?compareaction
    setcall compareaction action_compare(op,(NULL))
    if compareaction!=(NULL)
        inc pointer
        sd ?oneSign_two_or_noCompare;setcall oneSign_two_or_noCompare action_compare(pointer#,compareaction)
        dec pointer
        if oneSign_two_or_noCompare!=2
		set globalp.compare_bool (TRUE)
		add pointer oneSign_two_or_noCompare
		inc pointer
		return pointer
        endif
    endif

    #shl/shr/sar / && ||
    if op=(shl)
        inc pointer
        if pointer#!=(shl);call error("expecting <<");endif
    elseif op=(sar_shr)
        inc pointer
        if pointer#!=(sar_shr);call error("expecting >>");endif
        inc pointer
        if pointer#!=(sar_shr)
        #not >>> case
            dec pointer
        endif
    elseif op=(and)
        inc pointer;if pointer#!=(and);dec pointer;endif
    elseif op=(or)
        inc pointer;if pointer#!=(or);dec pointer;endif
    endelseif

    if op!=0
        inc pointer
    endif

    return pointer
endfunction
#pointer
function action_code_take_main(ss ac,ss p_op,ss delims)
	#a string
	ss pointer
	setcall pointer action_code_str(ac)
	if pointer!=(NULL)
		set pointer spaces(pointer) ;#ffdec _text.message = \"Angle: \" +b
		set p_op# pointer#;set pointer# 0
		return pointer
	endif

	ss ?excla
	if ac#=(Exclamationmark)
		inc ac
		set excla (TRUE)
	else
		set excla (FALSE)
	end

	set pointer ac

	char neg=Hyphen
	if pointer#=neg
		inc pointer
		set pointer spaces(pointer) #=- Math(8)
	endif

	#a function
	ss cursor;set cursor pointer
	setcall pointer action_code_parse_new_or_call(cursor,(call_action_right),ac)
	if pointer!=cursor
		if excla=(TRUE)
			call action_code_set((ActionNot))
		end
		set pointer spaces(pointer) #ffdec
		set p_op# pointer#;set pointer# 0
		return pointer
	endif

	#a variable(a.b.c[1+d])
	sd pos
	setcall pos strcspn(pointer,delims)

	#ffdec compatibility with deprecated and/or
	sd was;set was pos
	set pos compat(pointer,pos," and ","&&")
	if was=pos
		set pos compat(pointer,pos," or ","||")
	end

	add pointer pos
	while pointer#=(Openingbracket)
		setcall pointer brackets_test(pointer)
		#continue with the member
		setcall pos strcspn(pointer,delims)
		add pointer pos
	endwhile
	call memtrailstrict(pointer)
	set p_op# pointer#;set pointer# 0
	call action_code_take(ac)
	if excla=(TRUE)
		call action_code_set((ActionNot))
	end
	return pointer
endfunction
#pointer
function brackets_test(ss pointer)
	ss ?multidim=1
	while multidim=1
		sv ?openedbrackets=1 #it's not like is long but why to error here?
		while openedbrackets>0
			inc pointer
			if pointer#=(Openingbracket)
				inc openedbrackets
			elseif pointer#=(Closingbracket)
				dec openedbrackets
			elseif pointer#=0
				call error("unclosed bracket detected")
			endelseif
		endwhile
		inc pointer
		if pointer#!=(Openingbracket)
			set multidim 0
		endif
	endwhile
	return pointer
endfunction

^import "str_escape" str_escape 3 #full
#next/0
function action_code_str(ss ac)
    sd delim
	char stringdelim=Doublequotes
	char stringdelim2=Singlequote
    set delim stringdelim
    if ac#!=stringdelim
	if ac#!=stringdelim2
            return 0
	endif
            set delim stringdelim2
    endif
    ss next
    ss dest
    set dest ac
    inc dest
    setcall next str_escape(ac,dest,delim)
    call action_code_set((ap_Constant8))
    call action_code_set_pointer(dest)
    return next
endfunction
function action_code_take(ss ac)
	sd b;setcall b numeric_code_orConstruction(ac)
	if b=(TRUE)
		ret
	endif
	callg action_code_take_pointer(ac)
endfunction
function action_code_take_pointer(sd ac)
    ss test
    setcall test action_code_membersplit(ac)
    if test=0
        call action_code_set((ActionGetVariable))
        call action_code_set_pointer(ac)
    else
        call action_code_set((ActionGetMember))
		callg action_code_member(ac,-1)
    endelse
endfunction
function pointer_prefix()
	call action_code_set((ap_Integer))
	call action_code_set(0)
	call action_code_set((ActionSubtract))
end
#bool
function numeric_code_orConstruction(ss ac)
	ss pointer;set pointer ac
	char neg=Hyphen
	if pointer#=neg
		inc pointer
	endif
	ss ?bl
	setcall bl is_numeric(pointer#)
	if bl!=(TRUE)
		char i="Infinity"
		ss ?c;set c mem_cmp_bool(pointer,#i,\.i) #versus a string
		if c=(FALSE)
			char n="NaN"
			set c mem_cmp_bool(pointer,#n,\.n)
			if c=(FALSE)
				if ac=pointer
					return (FALSE)
				end
				#here is -pointer
				call pointer_prefix()
				set pointer spaces(pointer)
				call action_code_take_pointer(pointer)
				return (TRUE)
			end
			sd ?b=-1^doubleH_sign
			if ac!=pointer ##swfdump is seeing -nan , nan
				or b (doubleH_sign)
			end
			call action_code_set((ap_Double))
			call action_code_set(b)
			call action_code_set(-1)
			return (TRUE)
		end
		sd ?a=doubleH_exp
		if ac!=pointer ##negative
			or a (doubleH_sign)
		end
		call action_code_set((ap_Double))
		call action_code_set(a)
		call action_code_set(0)
		return (TRUE)
	endif
	ss decimal_symbol_test
	char dot=Period
	setcall decimal_symbol_test strchr(pointer,dot)
	if decimal_symbol_test!=(NULL)
		call action_code_set((ap_Double))
		#data value_low#1;data value_high#1 #is not c friendly
		datax values#2;vdata _values^values
		call sscanf(ac,"%lf",_values)  # e is nice but need to write to not be subtract there (ex: ...e-38), then will be "g" here
		sd p=DWORD
		add p _values
		call action_code_set(p#)
		call action_code_set(_values#)
		return (TRUE)
	endif
	call action_code_set((ap_Integer))
	#
	ss hextest
	set hextest pointer
	inc hextest
	char hex=x_low
	datax value_low#1
	if hextest#=hex
		call sscanf(ac,"%x",#value_low)
	else
		call sscanf(ac,"%u",#value_low)
	endelse
	call action_code_set(value_low)
	return (TRUE)
endfunction
function action_code_member(ss pointer,sd full)
	vstr delims=".["
	char sqbrace_start=Openingbracket
	char sqbrace_end=Closingbracket
	call action_code_set_pointer(pointer) #owner?
	sd pos
	setcall pos strcspn(pointer,delims)
	add pointer pos
	sd p_currentnr
	if full!=0
		setcall p_currentnr action_code_values_index()
		set full p_currentnr#
	end
	while pointer#!=0
		if pointer#=sqbrace_start
			set pointer# 0
			inc pointer
			call action_code_set_pointer((no_pointer)) #to compare square brackets on same field with pointers
			call action_code_set((square_bracket_start))
			setcall pointer action_code_row_parse_tool(pointer,sqbrace_end)
		else
			set pointer# 0
			inc pointer
		end
		setcall pos strcspn(pointer,delims)
		if pos!=0
		#0 is at second+ multi-dimensional arrays levels ]. or when simply want to end
			call action_code_set_pointer(pointer)
			add pointer pos
		endif
	endwhile
	if full!=0
		if p_currentnr#=full
			call error("full member required")
		end
	end
	call action_code_set_pointer((no_pointer))
	callg action_code_set((member_end)) #to compare square brackets on same field with pointers
endfunction


#condition


#firstcompare==NULL:action code/NULL;else oneSign_two_or_noCompare 0/1/2
function action_compare(ss ?value,sd firstcompare)
	#<
	if value=(Lessthan)
        if firstcompare!=(NULL)
                                           #is shl
		if firstcompare=(ActionLess2);return 2;endif
		call error("not expeting < here")
        endif
        return (ActionLess2)
	endif
	#>
	if value=(Greaterthan)
        if firstcompare!=(NULL)
                                             #is sar_shr
		if firstcompare=(ActionGreater);return 2;endif
		call error("not expeting > here")
        endif
        return (ActionGreater)
	endif
	#=
	if value=(Equals)
		if firstcompare!=(NULL)
			call action_code_set((compare_action))
		end
		if firstcompare=(ActionLess2)
			call action_code_set((ActionGreater))
			call action_code_set((ActionNot))
			return 1
		endif
		if firstcompare=(ActionGreater)
			call action_code_set((ActionLess2))
			call action_code_set((ActionNot))
			return 1
		endif
		if firstcompare=(ActionEquals2)
			call action_code_set((ActionEquals2))
			call action_code_set(0)
			return 1
		endif
		if firstcompare=(ActionNot)
			call action_code_set((ActionEquals2))
			call action_code_set((ActionNot))
			return 1
		endif
		return (ActionEquals2)
	endif
	# !
	if value=(Exclamationmark)
		if firstcompare!=(NULL)
			call error("not expecting ! here")
		endif
		return (ActionNot)
	endif
	#another char
	if firstcompare=(NULL)
		#call error("expecting a comparison")
		return (NULL)
	endif
	if firstcompare=(ActionEquals2)
		call error("expecting a == comparison")
	elseif firstcompare=(ActionNot)
		call error("expecting a != comparison")
	endelseif
	call action_code_set((compare_action))
	if firstcompare=(ActionLess2)
		call action_code_set((ActionLess2))
		call action_code_set(0)
	else
		#if firstcompare==(ActionGreater)
		call action_code_set((ActionGreater))
		call action_code_set(0)
	endelse
	return 0
endfunction

#{} blocks

function cond_blocks()
	if globalp.counter=(brace_blocks_max)
        call error("too many blocks: {}")
	endif
	callret cond_blocks_at_index(globalp.counter)
endfunction
function brace_blocks_counter_dec()
	if globalp.counter=0
        call error("unexpected end block: }")
	endif
	dec globalp.counter
endfunction
#
function brace_blocks_add_parse(sd ?type)
    sd block
    setcall block cond_blocks()
    set block# type
    call brace_blocks_counter_inc()
endfunction
function brace_blocks_remove_parse_else()
	sd p_type
	sd ?type
	#
	sd ?i
	set i globalp.counter
	dec i
	setcall p_type cond_blocks_at_index(i)
	set type p_type#
	if type=(else_marker)
		sd ?else_number=0
		while type=(else_marker)
			inc else_number
			dec globalp.counter
			if i!=0
				dec i
				setcall p_type cond_blocks_at_index(i)
				set type p_type#
			else
				set type 0
			endelse
		endwhile
		call action_code_set((block_else_end))
		callg action_code_set(else_number)
	endif
endfunction
function brace_blocks_remove_parse() #else is at brace_blocks_remove_parse_else
	sd p_type
	sd ?type
	sd consecutive=consecutive_flag
	while consecutive=(consecutive_flag)
		call brace_blocks_counter_dec()
		#
		set p_type cond_blocks_noerror()
		setcall type type_consecutive(p_type#,#consecutive)
		if type!=(normal_marker)
			if type=(while_marker) #including fors
				call action_code_set((whileblock_end))
			else #if_marker function_marker
				call action_code_set(type) #block_end
			endelse
		endif
	endwhile
endfunction
#type
function type_consecutive(sd ?type,sd p_consecutive)
	and p_consecutive# type
	and type (~consecutive_flag)
	return type
endfunction
function brace_blocks_end()
	if globalp.counter!=0
        call error("unclosed block(s): {}")
	endif
endfunction
#
function brace_blocks_add_write()
	callg brace_blocks_add_write_offset((smallbackjump),(no_flag))
endfunction
function brace_blocks_add_write_current()
	callg brace_blocks_add_write_offset(0,(no_flag))
endfunction
function brace_blocks_add_write_offset(sd offset,sd ?flag)
	sd block
	setcall block cond_blocks()
	setcall block# swf_actionblock_get_size()
	add block# offset
	or block# flag
	call brace_blocks_counter_inc()
endfunction
#
function brace_blocks_remove_write(sd skip_xlog)
	sd offset
	setcall offset brace_blocks_remove_write_offset()
	callg write_forward_offset(offset,skip_xlog)
endfunction
function brace_blocks_remove_write_ex()
	sdu ?offset
	setcall offset brace_blocks_remove_write_offset()
	sdu ?test=skip_flag
	and test offset
	if test=0
		callg write_forward_offset_jump(offset)
	end
endfunction
function write_forward_offset_cond(sdu ?offset,sd _ifs)
	if _ifs#!=0
		call write_forward_offset_base(offset,(FALSE),(xlog_jumpif))
		dec _ifs#
	else
		callg write_forward_offset_jump(offset)
	end
end
function write_forward_offset_jump(sdu ?offset)
	callg write_forward_offset_base(offset,(FALSE),(xlog_jump))
end
function write_forward_offset(sdu ?offset,ss ?skip_xlog)
	callg write_forward_offset_base(offset,skip_xlog,(xlog_jumpif))
end
import "stack_to_word_arg" stack_to_word_arg
import "debug_phase_code_add_jump_if" debug_phase_code_add_jump_if
function write_forward_offset_base(sdu ?offset,ss ?skip_xlog,ss ?xlog_j)
	sd mem
	sdu ?size
	!xor size size ## c problem
	call swf_actionblock_get_mem_size(#mem,#size)
	#
	add mem offset
	add offset (WORD)
	sub size offset
	#
	call forward_jump_check(size)
	call stack_to_word_arg(size,mem)
	if skip_xlog=(FALSE)
		callg debug_phase_code_add_jump_if(mem,xlog_j)
	end
endfunction
function forward_jump_check(sd ?size) #is short is swf<x related to totalvalues #is swu but what if is going to 0x10000 at c?
	if size>^0x7fFF
		call error("offset>(signed word size) error")
	endif
end
#offset
function brace_blocks_remove_write_offset()
    call brace_blocks_counter_dec()
    sd block
    set block cond_blocks_noerror()
    return block#
endfunction
const action_debug_break=1
const action_debug_recordlength=action_debug_comma+1+action_debug_break ;# ,2! only at actionjump, if ,10 ...  must change
function check_whilefor(sd _skip_jump,sd _ifs)
	sd start;set start cond_blocks_at_index(0)
	sd blocks;set blocks cond_blocks_noerror()
	while start!=blocks
		sub blocks (DWORD)
		if blocks#=(top_marker) #healty while/for
			sub blocks (DWORD)
			if blocks#!=(forin_marker)
				if globalp.type=(ret_cont_break_break) #jump 0 there?
					set _skip_jump# (actionrecord_jump_size)
					#also need to remove from debug
					call debug_phase_code_remove(_skip_jump#,(action_debug_recordlength))
				end
				if blocks#=(while_marker)
					set _ifs# 1
				else
					set _ifs# 0
				end
			end
			ret
		end
		inc _ifs#
	end
	callg error("x is broken")
end
function brace_blocks_remove_write_jump() #here is only from endwhile (at while and fors)
	if globalp.type=(ret_cont_break_nothing)  #skip dead code
		call add_dummy_jump()
	end
	sd ?skip_jump=0 ;#look to see top_marker and if is not forin, that has a different break than for3/while
	sd ?ifs=0 #on cond blocks
	call check_whilefor(#skip_jump,#ifs)
	sd blocks
	set blocks cond_blocks_noerror()
	dec globalp.counter
	sub blocks (DWORD)
	sd ?offset;set offset blocks#
	if offset!=(top_marker) #can be whiletrue with no breaks (a return in a branch)
		whiletrue
			dec globalp.counter
			sub blocks (DWORD)
			if blocks#=(top_marker)
				#here is last jump (loopjump or a moved break)
				break
			end
			call write_forward_offset_cond(offset,#ifs)
			set offset blocks#
		end
		#here the while was ok, last jump isn't set
		#remove type,top offset
	end

	sub globalp.counter 2
	if globalp.type=(ret_cont_break_nothing)  #skip dead code
		sub blocks (2*DWORD)
		call resolve_back_jump(blocks#)  #jump back
	elseif skip_jump!=0
		ret
	end
	if offset!=(top_marker) #can be whiletrue with no breaks (a return in a branch)
		#resolve the skipped offset
		callg write_forward_offset_cond(offset,#ifs)
	end
endfunction
import "actionrecordheader" actionrecordheader
import "swf_actionblock_add" swf_actionblock_add
function add_dummy_jump()
    call actionrecordheader((ActionJump),(actionjump_contentsize))
    sw ?dummy_size=0 #SI16
	callg swf_actionblock_add(#dummy_size,(actionjump_contentsize))
endfunction
import "debug_phase_code_add_jumpback_if" debug_phase_code_add_jumpback_if
function resolve_back_jump(sdu ?jumpoffset)  #also at continue
	ss mem
	sd ?size ;#will *-1
	!xor size size ## c problem
	call swf_actionblock_get_mem_size(#mem,#size)
	add mem size;sub mem (WORD)
	#
	sub size jumpoffset
	#call backward_jump_check(size) was moved since goto check

	call debug_phase_code_add_jumpback_if(#size)

	mult size -1
	call backward_jump_check(size)
	set mem# size
	sd byte=0x0000ff00;and byte size;div byte 0x100
	inc mem;set mem# byte
endfunction
function backward_jump_check(sd ?size) #for short same as forward check # is swu, but o/c word missmatch
	if size<^0xFFff8000
	#if size>^0x8000
		call error("offset>(signed word size) error (at jump back)")
	end
end

#function

#pointer
function action_code_parse_leftfunction(ss ac)
    #function definition
    ss pointer
    setcall pointer action_code_parse_deffunction(ac)
    if pointer!=ac
        return pointer
    endif
    #a call
	setcall ac action_code_parse_new_or_call(ac,(call_action_left),ac)
	char end=Semicolon
    if ac#=end
        inc ac
    endif
    return ac
endfunction
import "part_of_variable" part_of_variable
#pointer
function action_code_parse_new_or_call(ss ac,sd ?type,ss cursor)
	ss pointer
	set pointer ac
	ss last_dot=0
	ss ?sz
	setcall sz part_of_variable(pointer)
	while sz!=0
		add pointer sz
		setcall sz part_of_variable(pointer)
		if sz=0
			if pointer#=(Openingbracket)
				setcall pointer brackets_test(pointer)
			endif
			if pointer#=(Period)
				set last_dot pointer
				set sz 1
			elseif pointer#=(Openparenthesis)
				if ac!=cursor ##example: negative
					call pointer_prefix()
				end
				callret action_code_parse_function_detected(ac,last_dot,pointer,type)
			endelseif
		endif
	endwhile
	return ac
endfunction
#pointer
function action_code_parse_function_detected(ss start,ss last_dot,ss pointer,sd type)
    #function mark
    call action_code_set(type)
    set pointer# 0
    #member.function_name
    if last_dot!=0
        set last_dot# 0
        inc last_dot
        call action_code_set_pointer(start)
        call action_code_set_pointer(last_dot)
    else
        call action_code_set_pointer((no_pointer))
        call action_code_set_pointer(start)
    endelse
    setcall pointer action_code_parse_function_arguments(pointer)
    call action_code_set((args_end))
    return pointer
endfunction
#pointer
function action_code_parse_function_arguments(ss pointer)
    #arguments
    # this was for what? sd math_values
    # setcall math_values action_code_get()
	char comma=Comma
	char close=Closeparenthesis
    inc pointer
    if pointer#=close
        inc pointer
        return pointer
    endif
	#
	#need to swap the arguments for the call function
	sd cursor
	set cursor get_a_swap()
	sd ?all_nr=swapdata_max*:
	sd ?nr
	set nr all_nr
	add cursor nr
	sd start_data
	sd data
	setcall start_data action_code_get()
	set data start_data
	sd sizemark
	setcall sizemark action_code_values_index()
	sd ?sizepointer
	set sizepointer sizemark#
	#
	ss ?op=0
	while op!=close
        setcall pointer action_code_row_parse_tool_util(pointer,#op,comma,close)
        if op=0
            call error("close the function arguments sign expected: )")
        endif
        #
        sd ?dif
        set dif sizemark#
        sub dif sizepointer
        set sizepointer sizemark#
        mult dif (DWORD)
        #
        sub nr dif
        if nr<0
            call error("too many function arguments")
        endif
        sub cursor dif
        call memcpy(cursor,data,dif) #copy at end arguments
        add data dif
        #
	endwhile
	#
	sub all_nr nr
	call memcpy(start_data,cursor,all_nr) #copy swaped arguments
	call free_a_swap()
	#
	return pointer
endfunction

#

#pointer
function action_code_parse_deffunction(ss ac)
    ss pointer
    setcall pointer str_expression_at_start(ac,"function")
    if pointer=ac
        return ac
    endif
    call action_code_set((function_action))
    ss name_start
    set name_start pointer
	char startsign=Openparenthesis
    ss args
    setcall args strchr(pointer,startsign)
    if args=(NULL)
        call error("start sign expected at function definition: (")
    endif
    set args# 0
    call action_code_set_pointer(name_start)
    setcall pointer action_code_parse_function_defarguments(args)
    call action_code_set_pointer((no_pointer))
    #
    call brace_blocks_add_parse((function_marker))
    #loop until the function code is over
	sd ?index_atstart
	set index_atstart globalp.counter
	#
	setcall pointer action_code_row(pointer,(TRUE))
	#at start is equal, then can be lower
	while index_atstart<=^globalp.counter
		if pointer#=0
			call error("A define function was unclosed")
		endif
		setcall pointer action_code_row(pointer,(FALSE))
	endwhile
    return pointer
endfunction
#pointer
function action_code_parse_function_defarguments(ss ac)
	vstr argsdelims=",)"
	inc ac
	if ac#=(Closeparenthesis)
		inc ac
		return ac
	endif
	whiletrue
		ss end
		setcall end strpbrk(ac,argsdelims)
		if end!=(NULL)
			while ac!=end
				if ac#!=(Space)
					call action_code_set_pointer(ac)
					set ac end
					if end#=(Closeparenthesis)
						set end# (Nullchar)
						inc ac
						return ac
					end
					set end# (Nullchar)
					break
				end
				inc ac
			end
			if end#=(Nullchar)
				inc ac
				continue
			end
			call error("argument missing")
		end
		call error("close the function arguments sign expected: )")
	endwhile
endfunction

function get_a_swap()
	#will be blocked by topmost size (too many function arguments). information an a() from a(a(...)) is 0x2c(44) at .x
	if globalp.swapsdata_index<(swapsdata_max)
		sd a;set a malloc(:*swapdata_max)
		if a!=(NULL)
			sv pointer=:
			mult pointer globalp.swapsdata_index
			add pointer #globalp.swapdsdata
			set pointer# a
			inc globalp.swapsdata_index
			return a
		end
	end
	call error("error at function call arguments swap")
end

entryraw globalp()
