
%if 0

lDebug IF commands (conditional control flow)

Copyright (C) 2008-2026 E. C. Masloch

Usage of the works is permitted provided that this
instrument is retained with the works, so that any entity
that uses the works is notified of this instrument.

DISCLAIMER: THE WORKS ARE WITHOUT WARRANTY.

%endif


%if _INPUT_FILE_HANDLES || _INPUT_FILE_BOOT
if_exists_check:
	push ss
	pop es
	mov di, word [if_exists_si]
	mov cx, word [if_exists_length]
	mov si, word [if_exists_sp]
	rep movsb
	mov cx, word [if_exists_length]
	inc cx
	and cl, ~1

	mov si, word [if_exists_then_address]
	test si, si
	jz .error
	dec si
	mov dx, msg.then
	call isstring?
	jne .error
	retn

.error:
	mov ax, 0149h
	call setrc
	jmp error

if_exists_not_found:
	call if_exists_check
%if _EXTENSIONS
	call close_ext
%endif
	testopt [internalflags3], dif3_if_not
	jnz if_exists_condition_met
if_exists_condition_not_met:
	jmp cmd3

%if _EXTENSIONS
if_exists_found_ext_open:
	push ss
	pop es
	call close_ext
	jmp @F
%endif

if_exists_found_open:
	push ss
	pop es
	call getline_close_file

@@:
if_exists_found_closed:
	call if_exists_check
	testopt [internalflags3], dif3_if_not
	jnz if_exists_condition_not_met
if_exists_condition_met:
	mov sp, word [if_exists_sp]
	add sp, cx
.numeric:
	call skipcomma
	pop dx				; discard near return address
	clropt [internalflags3], dif3_in_if | dif3_auxbuff_guarded_1
	dec si
	push si
	xor cx, cx
@@:
	inc cx
	lodsb
	call iseol?.notsemicolon
	jne @B				; cx = length including CR
	pop si
	mov di, line_in + 1
	mov al, cl
	dec ax				; al = length excluding CR
	stosb				; store
%if _EXTENSIONS && _EXT_PUTS_GETLINE
	mov bl, 6
	xchg ax, cx
		; INP:	bl = 6
		;	byte [line_in + 1] = length
		;	es:di -> line_in + 2
		;	ds:si -> higher in line_in
		;	ax = length of data to move down (includes CR)
		; CHG:	cx, bh, dx
		; STT:	ds = es = ss
		;	UP, EI
	call transfer_to_ext_puts_getline
	xchg ax, cx
%endif
	rep movsb			; move down
	mov si, line_in + 2
	lodsb				; al = first text byte
	jmp cmd3_injected
%endif


		; IF command -- conditional
ii:
	mov dx, si
	push ax
	mov ax, [si - 2]
	and ax, TOUPPER_W
	cmp ax, "IF"
	pop ax
	jne .not_if

	call skipcomma
	nearcall isoperator?
	jne .if
	mov bx, cx
	add bx, bx			; bh = 0 !
	push ax
	nearcall ..@call_operator_dispatchers
	pop ax
	test bx, bx
	jnz .not_if
	call skipcomma
.if:
	clropt [internalflags3], dif3_if_not
	dec si
	mov dx, msg.not
	call isstring?
	lodsb
	jne @F
	call skipcomm0
	setopt [internalflags3], dif3_if_not

@@:
%if _INPUT_FILE_HANDLES || _INPUT_FILE_BOOT
	dec si
	mov dx, msg.exists
	call isstring?
	lodsb
	jne .if_numeric
	call skipcomm0
	dec si
	mov dx, msg.r
	call isstring?
	je .is_variable
	mov byte [yy_is_script], 0
%if _EXTENSIONS
	mov dx, msg.ext
	call isstring?
	je .is_ext
%endif
	not byte [yy_is_script]
	mov dx, msg.y
	call isstring?
	jne error
.is_ext:
	call skipcomma

	dec si
	mov word [if_exists_si], si
	mov bx, si
@@:
	lodsb
	call iseol?.notsemicolon
	jne @B
	mov cx, si		; -> after EOL byte
	sub cx, bx		; = length including EOL
	mov word [if_exists_length], cx
	inc cx			; round up
	and cl, ~1		; make even
	sub sp, cx
	mov word [if_exists_sp], sp
	mov di, sp
	mov si, bx
	shr cx, 1
	rep movsw

	mov si, bx
	lodsb
	and word [if_exists_then_address], 0
	setopt [internalflags3], dif3_in_if
	rol byte [yy_is_script], 1
	jnc @F
	call guard_re
@@:
	call yy_or_ext_no_guard_re
	jmp error
%endif

.if_numeric:
	nearcall getexpression
	nearcall toboolean
	call skipcomm0
	mov bx, dx
.if_bx:
 	mov dx, msg.then
	dec si
	call isstring?
	jne error
.if_bx_after_then:
	testopt [internalflags3], dif3_if_not
	jz @F
	xor bl, 1
@@:
	test bx, bx
	jz .if_false
	jmp if_exists_condition_met.numeric

.if_false:
	jmp resetrc


.is_variable:
	call skipcomma
	push si
	nearcall isvariable?
	pop di			; - 1 -> start of candidate variable name
	jc .skipvariablename	; not valid, go to skip --> (si unchanged)

	mov bx, 1		; prepare valid variable return
	dec si
	call skipcomma
 	mov dx, msg.then
	dec si
	call isstring?		; keyword as expected ?
	je .if_bx_after_then	; yes, handle THEN command -->
	mov si, di		; reset - 1 -> start of name

.skipvariablename:
	dec si			; -> start of name
@@:
	lodsb
	cmp al, 32		; end of name ?
	je @F
	cmp al, 9
	je @F
	cmp al, ','
	je @F
	call iseol?
	je @F			; yes -->
	cmp al, '('		; parens (index expression) ?
	jne @B			; no, loop -->
	call skipwhite
	nearcall getexpression	; parse index expression (must be valid)
	cmp al, ')'		; closing parens ?
	jne error		; no, error -->
	jmp @B			; loop -->

@@:
	xor bx, bx		; prepare invalid variable return
.if_bx_comma:
	dec si
	call skipcomma
	jmp .if_bx		; check for the THEN keyword -->
