// File: /workspace/github_c_makefile_star2_O0/markdryan[P]subtilis/frontend/string_type.c
// Function: subtilis_string_type_string
subtilis_exp_t *subtilis_string_type_string(subtilis_parser_t *p,
					    subtilis_exp_t *count,
					    subtilis_exp_t *str,
					    subtilis_error_t *err)
{
	size_t buf_size;
	size_t ptr;
	const char *cstr;
	subtilis_exp_t *str_len;
	subtilis_exp_t *ret;
	subtilis_buffer_t dummy;

	switch (str->type.type) {
	case SUBTILIS_TYPE_CONST_STRING:
		buf_size = subtilis_buffer_get_size(&str->exp.str);
		if (buf_size == 1) {
			subtilis_exp_delete(count);
			return str;
		}
		if (count->type.type == SUBTILIS_TYPE_CONST_INTEGER)
			return prv_string_str_const(p, count, str, err);

		buf_size--;

		if (buf_size == 1)
			return prv_string_from_const_char(p, count, str, err);

		cstr = subtilis_buffer_get_string(&str->exp.str);
		ptr = subtilis_string_type_lca_const(p, cstr, buf_size, err);
		if (err->type != SUBTILIS_ERROR_OK)
			goto cleanup;
		str_len = subtilis_exp_new_int32(buf_size, err);
		if (err->type != SUBTILIS_ERROR_OK)
			goto cleanup;

		ret = prv_string_str_non_const_lengt1(p, count, ptr, str_len,
						      err);
		subtilis_exp_delete(str);
		return ret;
	case SUBTILIS_TYPE_STRING:
		if (count->type.type == SUBTILIS_TYPE_CONST_INTEGER) {
			if (count->exp.ir_op.integer == 1) {
				subtilis_exp_delete(count);
				return str;
			} else if (count->exp.ir_op.integer <= 1) {
				subtilis_buffer_init(&dummy, 128);
				subtilis_buffer_zero_terminate(&dummy, err);
				if (err->type != SUBTILIS_ERROR_OK) {
					subtilis_buffer_free(&dummy);
					goto cleanup;
				}
				subtilis_exp_delete(count);
				subtilis_exp_delete(str);
				str = subtilis_exp_new_str(&dummy, err);
				subtilis_buffer_free(&dummy);
				return str;
			}
			count = subtilis_type_if_exp_to_var(p, count, err);
			if (err->type != SUBTILIS_ERROR_OK)
				goto cleanup;
		}

		return prv_string_str_non_const(p, count, str, err);

	default:
		subtilis_error_set_string_expected(err, p->l->stream->name,
						   p->l->line);
		break;
	}

cleanup:

	subtilis_exp_delete(count);
	subtilis_exp_delete(str);

	return NULL;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x70, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq %rcx, -0x28(%rbp)
movq -0x20(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x64(%rbp)
subl $0x3, %eax
je 0x6a349
jmp 0x6a338
movl -0x64(%rbp), %eax
subl $0x7, %eax
je 0x6a461
jmp 0x6a548
movq -0x20(%rbp), %rdi
addq $0x148, %rdi            # imm = 0x148
callq 0x16270
movq %rax, -0x30(%rbp)
cmpq $0x1, -0x30(%rbp)
jne 0x6a37a
movq -0x18(%rbp), %rdi
callq 0x36ee0
movq -0x20(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x6a594
movq -0x18(%rbp), %rax
cmpl $0x1, (%rax)
jne 0x6a3a1
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x20(%rbp), %rdx
movq -0x28(%rbp), %rcx
callq 0x6a5a0
movq %rax, -0x8(%rbp)
jmp 0x6a594
movq -0x30(%rbp), %rax
addq $-0x1, %rax
movq %rax, -0x30(%rbp)
cmpq $0x1, -0x30(%rbp)
jne 0x6a3d2
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x20(%rbp), %rdx
movq -0x28(%rbp), %rcx
callq 0x6a750
movq %rax, -0x8(%rbp)
jmp 0x6a594
movq -0x20(%rbp), %rdi
addq $0x148, %rdi            # imm = 0x148
callq 0x16760
movq %rax, -0x40(%rbp)
movq -0x10(%rbp), %rdi
movq -0x40(%rbp), %rsi
movq -0x30(%rbp), %rdx
movq -0x28(%rbp), %rcx
callq 0x65d80
movq %rax, -0x38(%rbp)
movq -0x28(%rbp), %rax
cmpl $0x0, (%rax)
je 0x6a40d
jmp 0x6a57a
movq -0x30(%rbp), %rax
movl %eax, %edi
movq -0x28(%rbp), %rsi
callq 0x37800
movq %rax, -0x48(%rbp)
movq -0x28(%rbp), %rax
cmpl $0x0, (%rax)
je 0x6a42e
jmp 0x6a57a
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x38(%rbp), %rdx
movq -0x48(%rbp), %rcx
movq -0x28(%rbp), %r8
callq 0x6a980
movq %rax, -0x50(%rbp)
movq -0x20(%rbp), %rdi
callq 0x36ee0
movq -0x50(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x6a594
movq -0x18(%rbp), %rax
cmpl $0x1, (%rax)
jne 0x6a52d
movq -0x18(%rbp), %rax
cmpl $0x1, 0x148(%rax)
jne 0x6a491
movq -0x18(%rbp), %rdi
callq 0x36ee0
movq -0x20(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x6a594
movq -0x18(%rbp), %rax
cmpl $0x1, 0x148(%rax)
jg 0x6a509
leaq -0x60(%rbp), %rdi
movl $0x80, %esi
callq 0x15f80
movq -0x28(%rbp), %rsi
leaq -0x60(%rbp), %rdi
callq 0x16560
movq -0x28(%rbp), %rax
cmpl $0x0, (%rax)
je 0x6a4d0
leaq -0x60(%rbp), %rdi
callq 0x16650
jmp 0x6a57a
movq -0x18(%rbp), %rdi
callq 0x36ee0
movq -0x20(%rbp), %rdi
callq 0x36ee0
movq -0x28(%rbp), %rsi
leaq -0x60(%rbp), %rdi
callq 0x37900
movq %rax, -0x20(%rbp)
leaq -0x60(%rbp), %rdi
callq 0x16650
movq -0x20(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x6a594
jmp 0x6a50b
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x28(%rbp), %rdx
callq 0x47c10
movq %rax, -0x18(%rbp)
movq -0x28(%rbp), %rax
cmpl $0x0, (%rax)
je 0x6a52b
jmp 0x6a57a
jmp 0x6a52d
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x20(%rbp), %rdx
movq -0x28(%rbp), %rcx
callq 0x6aa80
movq %rax, -0x8(%rbp)
jmp 0x6a594
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 0x424ea(%rip), %r8      # 0xaca57
movl $0xd03, %r9d            # imm = 0xD03
callq 0x15930
jmp 0x6a57a
movq -0x18(%rbp), %rdi
callq 0x36ee0
movq -0x20(%rbp), %rdi
callq 0x36ee0
movq $0x0, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x70, %rsp
popq %rbp
retq
nop