// File: /workspace/github_c_makefile_star2_O0/markdryan[P]subtilis/frontend/string_type.c
// Function: subtilis_string_type_left_exp
subtilis_exp_t *subtilis_string_type_left_exp(subtilis_parser_t *p,
					      subtilis_exp_t *str,
					      subtilis_exp_t *len,
					      subtilis_error_t *err)
{
	size_t const_str_len;
	size_t const_int_val;
	subtilis_exp_t *ret;
	bool left_const = false;

	len = subtilis_type_if_to_int(p, len, err);
	if (err->type != SUBTILIS_ERROR_OK)
		goto cleanup;

	switch (str->type.type) {
	case SUBTILIS_TYPE_CONST_STRING:
		const_str_len = subtilis_buffer_get_size(&str->exp.str) - 1;
		if (const_str_len == 0) {
			subtilis_exp_delete(len);
			return str;
		}
		if (len->type.type == SUBTILIS_TYPE_CONST_INTEGER) {
			const_int_val = len->exp.ir_op.integer;
			return prv_left_right_const_str(str, len, const_int_val,
							err);
		}
		ret = prv_left_const(p, &str->exp.str, len->exp.ir_op.reg, err);
		subtilis_exp_delete(str);
		subtilis_exp_delete(len);
		return ret;
	case SUBTILIS_TYPE_STRING:
		if (len->type.type == SUBTILIS_TYPE_CONST_INTEGER) {
			left_const = true;
			if (len->exp.ir_op.integer < 0) {
				subtilis_exp_delete(len);
				return str;
			}
			if (len->exp.ir_op.integer == 0) {
				str->type.type = SUBTILIS_TYPE_CONST_STRING;
				subtilis_buffer_init(&str->exp.str, 1);
				subtilis_buffer_zero_terminate(&str->exp.str,
							       err);
				if (err->type != SUBTILIS_ERROR_OK)
					goto cleanup;
				subtilis_exp_delete(len);
				return str;
			}
			len = subtilis_type_if_exp_to_var(p, len, err);
			if (err->type != SUBTILIS_ERROR_OK)
				goto cleanup;
		}
		ret = prv_left_non_const(p, str->exp.ir_op.reg,
					 len->exp.ir_op.reg, left_const, err);
		subtilis_exp_delete(str);
		subtilis_exp_delete(len);
		return ret;
	default:
		subtilis_error_set_string_expected(err, p->l->stream->name,
						   p->l->line);
		break;
	}

cleanup:

	subtilis_exp_delete(str);
	subtilis_exp_delete(len);

	return NULL;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq %rcx, -0x28(%rbp)
movb $0x0, -0x41(%rbp)
movq -0x10(%rbp), %rdi
movq -0x20(%rbp), %rsi
movq -0x28(%rbp), %rdx
callq 0x488b0
movq %rax, -0x20(%rbp)
movq -0x28(%rbp), %rax
cmpl $0x0, (%rax)
je 0x67c6f
jmp 0x67e78
movq -0x18(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x48(%rbp)
subl $0x3, %eax
je 0x67c90
jmp 0x67c7f
movl -0x48(%rbp), %eax
subl $0x7, %eax
je 0x67d41
jmp 0x67e46
movq -0x18(%rbp), %rdi
addq $0x148, %rdi            # imm = 0x148
callq 0x16270
subq $0x1, %rax
movq %rax, -0x30(%rbp)
cmpq $0x0, -0x30(%rbp)
jne 0x67cc5
movq -0x20(%rbp), %rdi
callq 0x36ee0
movq -0x18(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x67e92
movq -0x20(%rbp), %rax
cmpl $0x1, (%rax)
jne 0x67cfb
movq -0x20(%rbp), %rax
movslq 0x148(%rax), %rax
movq %rax, -0x38(%rbp)
movq -0x18(%rbp), %rdi
movq -0x20(%rbp), %rsi
movq -0x38(%rbp), %rdx
movq -0x28(%rbp), %rcx
callq 0x67ea0
movq %rax, -0x8(%rbp)
jmp 0x67e92
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
addq $0x148, %rsi            # imm = 0x148
movq -0x20(%rbp), %rax
movq 0x148(%rax), %rdx
movq -0x28(%rbp), %rcx
callq 0x67f70
movq %rax, -0x40(%rbp)
movq -0x18(%rbp), %rdi
callq 0x36ee0
movq -0x20(%rbp), %rdi
callq 0x36ee0
movq -0x40(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x67e92
movq -0x20(%rbp), %rax
cmpl $0x1, (%rax)
jne 0x67dfb
movb $0x1, -0x41(%rbp)
movq -0x20(%rbp), %rax
cmpl $0x0, 0x148(%rax)
jge 0x67d75
movq -0x20(%rbp), %rdi
callq 0x36ee0
movq -0x18(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x67e92
movq -0x20(%rbp), %rax
cmpl $0x0, 0x148(%rax)
jne 0x67dd9
movq -0x18(%rbp), %rax
movl $0x3, (%rax)
movq -0x18(%rbp), %rdi
addq $0x148, %rdi            # imm = 0x148
movl $0x1, %esi
callq 0x15f80
movq -0x18(%rbp), %rdi
addq $0x148, %rdi            # imm = 0x148
movq -0x28(%rbp), %rsi
callq 0x16560
movq -0x28(%rbp), %rax
cmpl $0x0, (%rax)
je 0x67dc3
jmp 0x67e78
movq -0x20(%rbp), %rdi
callq 0x36ee0
movq -0x18(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x67e92
movq -0x10(%rbp), %rdi
movq -0x20(%rbp), %rsi
movq -0x28(%rbp), %rdx
callq 0x47c10
movq %rax, -0x20(%rbp)
movq -0x28(%rbp), %rax
cmpl $0x0, (%rax)
je 0x67df9
jmp 0x67e78
jmp 0x67dfb
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rax
movq 0x148(%rax), %rsi
movq -0x20(%rbp), %rax
movq 0x148(%rax), %rdx
movb -0x41(%rbp), %al
movq -0x28(%rbp), %r8
andb $0x1, %al
movzbl %al, %ecx
callq 0x681c0
movq %rax, -0x40(%rbp)
movq -0x18(%rbp), %rdi
callq 0x36ee0
movq -0x20(%rbp), %rdi
callq 0x36ee0
movq -0x40(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x67e92
movq -0x28(%rbp), %rdi
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq 0x30(%rax), %rdx
movq -0x10(%rbp), %rax
movq (%rax), %rax
movl 0x38(%rax), %ecx
movl $0x49, %esi
leaq 0x44bec(%rip), %r8      # 0xaca57
movl $0x5b1, %r9d            # imm = 0x5B1
callq 0x15930
jmp 0x67e78
movq -0x18(%rbp), %rdi
callq 0x36ee0
movq -0x20(%rbp), %rdi
callq 0x36ee0
movq $0x0, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x50, %rsp
popq %rbp
retq
nopl (%rax)