// File: /workspace/github_c_makefile_star2_O3/markdryan[P]subtilis/frontend/parser_loops.c
// Function: subtilis_parser_for
void subtilis_parser_for(subtilis_parser_t *p, subtilis_token_t *t,
			 subtilis_error_t *err)
{
	const char *tbuf;
	subtilis_type_t var_type;
	subtilis_for_context_t for_ctx;
	char *var_name = NULL;
	subtilis_exp_t *to = NULL;
	subtilis_exp_t *step = NULL;
	bool new_local = false;
	subtilis_step_type_t step_type = SUBTILIS_STEP_MAX;

	var_type.type = SUBTILIS_TYPE_VOID;
	for_ctx.type.type = SUBTILIS_TYPE_VOID;

	subtilis_lexer_get(p->l, t, err);
	if (err->type != SUBTILIS_ERROR_OK)
		return;

	tbuf = subtilis_token_get_text_with_err(t, err);
	if (err->type != SUBTILIS_ERROR_OK)
		return;

	if (t->type == SUBTILIS_TOKEN_KEYWORD) {
		if (t->tok.keyword.type != SUBTILIS_KEYWORD_LOCAL) {
			subtilis_error_set_expected(
			    err, "LOCAL", tbuf, p->l->stream->name, p->l->line);
			return;
		}

		subtilis_lexer_get(p->l, t, err);
		if (err->type != SUBTILIS_ERROR_OK)
			return;

		new_local = true;
		tbuf = subtilis_token_get_text_with_err(t, err);
		if (err->type != SUBTILIS_ERROR_OK)
			return;
	}

	if (t->type != SUBTILIS_TOKEN_IDENTIFIER) {
		subtilis_error_set_id_expected(err, tbuf, p->l->stream->name,
					       p->l->line);
		return;
	}

	var_type = t->tok.id_type;
	if (!subtilis_type_if_is_numeric(&var_type)) {
		subtilis_error_set_numeric_expected(
		    err, tbuf, p->l->stream->name, p->l->line);
		return;
	}

	var_name = malloc(subtilis_buffer_get_size(&t->buf));
	if (!var_name) {
		subtilis_error_set_oom(err);
		return;
	}
	strcpy(var_name, tbuf);

	prv_for_assignment(p, t, &for_ctx, new_local, err);
	if (err->type != SUBTILIS_ERROR_OK)
		goto cleanup;

	if ((t->type != SUBTILIS_TOKEN_KEYWORD) ||
	    (t->tok.keyword.type != SUBTILIS_KEYWORD_TO)) {
		tbuf = subtilis_token_get_text(t);
		subtilis_error_set_expected(err, "TO", tbuf, p->l->stream->name,
					    p->l->line);
		goto cleanup;
	}

	to = prv_numeric_expression(p, t, err);
	if (err->type != SUBTILIS_ERROR_OK)
		goto cleanup;

	if ((t->type == SUBTILIS_TOKEN_KEYWORD) &&
	    (t->tok.keyword.type == SUBTILIS_KEYWORD_STEP)) {
		step = prv_numeric_expression(p, t, err);
		if (err->type != SUBTILIS_ERROR_OK)
			goto cleanup;
		step_type = prv_compute_step_type(p, step, err);
		if (err->type != SUBTILIS_ERROR_OK)
			goto cleanup;

		/* Takes ownership of to and step */

		if (step_type == SUBTILIS_STEP_VAR) {
			step = subtilis_type_if_copy_var(p, step, err);
			if (err->type != SUBTILIS_ERROR_OK)
				goto cleanup;
			if (subtilis_type_if_is_integer(&var_type))
				prv_for_step_int_var(p, t, to, step, &for_ctx,
						     err);
			else
				prv_for_step_generic_var(p, t, to, step,
							 &for_ctx, err);
		} else {
			prv_for_step_const(p, t, to, step, step_type, &for_ctx,
					   err);
		}
		step = NULL;
	} else {
		/* Takes ownership of to */

		prv_for_no_step(p, t, to, &for_ctx, err);
	}
	to = NULL;

	if (err->type != SUBTILIS_ERROR_OK)
		goto cleanup;

	subtilis_lexer_get(p->l, t, err);

cleanup:

	subtilis_type_free(&var_type);
	subtilis_type_free(&for_ctx.type);
	subtilis_exp_delete(step);
	free(var_name);
	subtilis_exp_delete(to);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x2b8, %rsp            # imm = 0x2B8
movq %rdx, %rbx
movq %rsi, %r15
movq %rdi, %r14
movl $0x8, 0x28(%rsp)
movq (%rdi), %rdi
callq 0x12edc
cmpl $0x0, (%rbx)
jne 0x21607
movq %r15, %rdi
movq %rbx, %rsi
callq 0x12b1e
cmpl $0x0, (%rbx)
je 0x21619
addq $0x2b8, %rsp            # imm = 0x2B8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %r12
movl (%r15), %ebp
cmpl $0x1, %ebp
jne 0x2165a
cmpl $0x4a, 0x8(%r15)
movq (%r14), %rdi
jne 0x217cc
movq %r15, %rsi
movq %rbx, %rdx
callq 0x12edc
cmpl $0x0, (%rbx)
jne 0x21607
movq %r15, %rdi
movq %rbx, %rsi
callq 0x12b1e
cmpl $0x0, (%rbx)
jne 0x21607
movq %rax, %r12
movl (%r15), %eax
jmp 0x2165c
movl %ebp, %eax
cmpl $0x6, %eax
jne 0x217a1
leaq 0x8(%r15), %rsi
leaq 0x170(%rsp), %r13
movl $0x148, %edx            # imm = 0x148
movq %r13, %rdi
movq %rsi, 0x8(%rsp)
callq 0x121b0
movq %r13, %rdi
callq 0x37534
testb %al, %al
je 0x21804
leaq 0x28(%rsp), %r12
xorl %r13d, %r13d
cmpl $0x1, %ebp
sete %r13b
leaq 0x158(%r15), %rdi
callq 0x14b57
leaq 0x10(%rsp), %rdx
movq %r14, %rdi
movq %r15, %rsi
movl %r13d, %ecx
movq %rbx, %r8
callq 0x218fd
cmpl $0x0, (%rbx)
jne 0x21878
cmpl $0x1, (%r15)
jne 0x2183c
movq 0x8(%rsp), %rax
cmpl $0x86, (%rax)
jne 0x2183c
movq %r14, %rdi
movq %r15, %rsi
movq %rbx, %rdx
callq 0x21ff0
movq %rax, %r13
cmpl $0x0, (%rbx)
jne 0x2187b
cmpl $0x1, (%r15)
jne 0x218a7
movq 0x8(%rsp), %rax
cmpl $0x76, (%rax)
jne 0x218a7
movq %r14, %rdi
movq %r15, %rsi
movq %rbx, %rdx
callq 0x21ff0
movq %rax, %rbp
cmpl $0x0, (%rbx)
jne 0x2187d
movq %r14, %rdi
movq %rbp, %rsi
movq %rbx, %rdx
callq 0x22065
cmpl $0x0, (%rbx)
jne 0x2187d
cmpl $0x2, %eax
jne 0x218d2
movq %r14, %rdi
movq %rbp, %rsi
movq %rbx, %rdx
callq 0x36169
movq %rax, %rbp
cmpl $0x0, (%rbx)
jne 0x2187d
leaq 0x170(%rsp), %rdi
callq 0x372bf
leaq 0x10(%rsp), %r8
movq %r14, %rdi
movq %r15, %rsi
movq %r13, %rdx
movq %rbp, %rcx
movq %rbx, %r9
testb %al, %al
je 0x218f6
callq 0x221fe
jmp 0x218bd
movq (%r14), %rax
movq 0x30(%rax), %r8
movl 0x38(%rax), %r9d
leaq 0x521d9(%rip), %rax     # 0x7398c
leaq 0x5265b(%rip), %rcx     # 0x73e15
movq %rbx, %rdi
movl $0x12, %esi
movq %r12, %rdx
pushq $0x366                  # imm = 0x366
jmp 0x217f2
movq 0x30(%rdi), %r8
movl 0x38(%rdi), %r9d
leaq 0x521b1(%rip), %rax     # 0x7398c
leaq 0x5189c(%rip), %rdx     # 0x7307e
movq %rbx, %rdi
movl $0x1d, %esi
movq %r12, %rcx
pushq $0x356                  # imm = 0x356
pushq %rax
callq 0x143da
addq $0x2c8, %rsp            # imm = 0x2C8
jmp 0x2160e
movq (%r14), %rax
movq 0x30(%rax), %r8
movl 0x38(%rax), %r9d
leaq 0x52176(%rip), %rax     # 0x7398c
leaq 0x525f8(%rip), %rcx     # 0x73e15
movq %rbx, %rdi
movl $0x2c, %esi
movq %r12, %rdx
pushq $0x36d                  # imm = 0x36D
pushq %rax
callq 0x143da
addq $0x10, %rsp
jmp 0x21607
movq %r15, %rdi
callq 0x12ad0
movq (%r14), %rcx
movq 0x30(%rcx), %r8
movl 0x38(%rcx), %r9d
leaq 0x52136(%rip), %r10     # 0x7398c
leaq 0x5194d(%rip), %rdx     # 0x731aa
movq %rbx, %rdi
movl $0x1d, %esi
movq %rax, %rcx
pushq $0x380                  # imm = 0x380
pushq %r10
callq 0x143da
addq $0x10, %rsp
xorl %r13d, %r13d
xorl %ebp, %ebp
leaq 0x170(%rsp), %rdi
callq 0x2f56e
movq %r12, %rdi
callq 0x2f56e
movq %rbp, %rdi
callq 0x2b166
movq %r13, %rdi
callq 0x2b166
jmp 0x21607
leaq 0x10(%rsp), %rcx
movq %r14, %rdi
movq %r15, %rsi
movq %r13, %rdx
movq %rbx, %r8
callq 0x229fd
cmpl $0x0, (%rbx)
jne 0x21878
movq (%r14), %rdi
movq %r15, %rsi
movq %rbx, %rdx
callq 0x12edc
jmp 0x21878
subq $0x8, %rsp
leaq 0x18(%rsp), %r9
movq %r14, %rdi
movq %r15, %rsi
movq %r13, %rdx
movq %rbp, %rcx
movl %eax, %r8d
pushq %rbx
callq 0x22903
addq $0x10, %rsp
jmp 0x218bd
callq 0x2261a
jmp 0x218bd