// File: /workspace/github_c_makefile_star2_O1/qpfiffer[P]lair/src/parse.c
// Function: parse_from_token
static struct _lair_ast *_parse_from_token(struct _lair_token **tokens) {
	/* "pop" the token off of the top of the stack. */
	struct _lair_token *current_token = _pop_token(tokens);

	/* Atomize the function, stick it at the head of the list. */
	struct _lair_ast _stack_ast = {
		.atom = _lair_atomize_token(current_token),
		.indent_level = current_token->indent_level
	};

	if (current_token->token_type == LR_FUNCTION_CALL ||
			current_token->token_type == LR_FUNCTION_DEF ||
			current_token->token_type == LR_CALL) {
		struct _lair_ast *list = calloc(1, sizeof(struct _lair_ast));
		memcpy(list, &_stack_ast, sizeof(struct _lair_ast));

		/* We break out of the loop when we find an EOF or a DEDENT. */
		struct _lair_ast *cur_ast_item = list;
		struct _lair_ast *prev = NULL;
		while (current_token->token_type != LR_DEDENT &&
			   current_token->token_type != LR_EOF) {
			struct _lair_ast *to_append = _parse_from_token(tokens);
			cur_ast_item->next = to_append;
			cur_ast_item->prev = prev;

			/* Get the next token in line. */
			prev = cur_ast_item;
			cur_ast_item = cur_ast_item->next;
			current_token = (*tokens);
			if (current_token == NULL) {
				/* This happens sometimes if we have a statement like the following:
				 * ! print ! return 10<EOF>
				 */
				return list;
			}
		}

		if (current_token->token_type == LR_EOF) {
			struct _lair_ast *to_append = _parse_from_token(tokens);
			cur_ast_item->next = to_append;
			cur_ast_item->prev = prev;

			prev = cur_ast_item;
			cur_ast_item = cur_ast_item->next;
			current_token = (*tokens);
		}
		return list;
	} else {
		struct _lair_ast *to_return = calloc(1, sizeof(struct _lair_ast));
		memcpy(to_return, &_stack_ast, sizeof(struct _lair_ast));
		_lair_free_token(current_token);
		return to_return;
	}

	_lair_free_tokens(current_token);

	return NULL;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rdi, %rbx
movq (%rdi), %r14
testq %r14, %r14
je 0x3540
movq 0x10(%r14), %rax
movq %rax, (%rbx)
jmp 0x3543
xorl %r14d, %r14d
movl 0xc(%r14), %r12d
movq %r14, %rdi
callq 0x3319
movl %eax, %ebp
movq %rdx, %r13
movl 0x8(%r14), %eax
cmpl $0xb, %eax
ja 0x35e1
movl $0x806, %ecx            # imm = 0x806
btl %eax, %ecx
jae 0x35e1
movl $0x1, %edi
movl $0x38, %esi
callq 0x1130
movq %rax, %r15
xorps %xmm0, %xmm0
movups %xmm0, (%rax)
movups %xmm0, 0x10(%rax)
movl %r12d, 0x20(%rax)
movl %ebp, 0x28(%rax)
movq %r13, 0x30(%rax)
xorl %r13d, %r13d
movq %rax, %rbp
movl 0x8(%r14), %eax
movl %eax, %ecx
andl $-0x2, %ecx
cmpl $0x8, %ecx
je 0x35c7
movq %rbx, %rdi
callq 0x3521
movq %rax, 0x8(%rbp)
movq %r13, (%rbp)
movq (%rbx), %r14
movq %rbp, %r13
testq %r14, %r14
cmoveq %r15, %r12
jne 0x3595
jmp 0x361a
cmpl $0x9, %eax
jne 0x35dc
movq %rbx, %rdi
callq 0x3521
movq %rax, 0x8(%rbp)
movq %r13, (%rbp)
movq %r15, %r12
jmp 0x361a
movl $0x1, %edi
movl $0x38, %esi
callq 0x1130
movl %r12d, %ecx
movq %rax, %r12
xorps %xmm0, %xmm0
movups %xmm0, (%rax)
movups %xmm0, 0x10(%rax)
movl %ecx, 0x20(%rax)
movl %ebp, 0x28(%rax)
movq %r13, 0x30(%rax)
movq (%r14), %rdi
callq 0x1030
movq %r14, %rdi
callq 0x1030
movq %r12, %rax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq