// File: /workspace/github_c_makefile_star2_O1/Yamsman[P]scc/src/eval.c
// Function: eval_constexpr
int eval_constexpr(lexer *lx, vector *input, int *err) {
	//Initialize stacks
	vector ops, vals;
	vector_init(&ops, VECTOR_DEFAULT);
	vector_init(&vals, VECTOR_DEFAULT);

	//Process input token by token
	int i = 0;
	int eflag_prev = c_errflag;
	s_pos *last_loc = NULL;
	for (; i<input->len; i++) {
		token *t = input->table[i];
		last_loc = &t->loc;
		if (t->type == TOK_CONST) {
			//Ensure the constant is an integer
			if (t->dtype->kind == TYPE_FLOAT) {
				c_error(&t->loc, "Floating point value in constant expression\n");
				continue;
			}

			//Push the operand
			vector_push(&vals, (void*)t->dat.ival);
		} else if (t->type == TOK_DEFINED) {
			//Move to the next token and check for an identifier
			token *ident = input->table[++i];
			if (i >= input->len || ident->type != TOK_IDENT) {
				c_error(&t->loc, "Expected identifier after 'defined'\n");
				continue;
			}

			//Search the symbol table to check if the identifier is defined
			long long res = (symtable_search(lx->stb, t->dat.sval) != NULL);
			vector_push(&vals, (void*)res);
		} else if (t->type == TOK_IDENT) {
			vector_add(&vals, (void*)0);
		} else if (t->type == TOK_LPR) {
			//Push a left parentheses
			vector_push(&ops, (void*)(long long)t->type);
		} else if (t->type == TOK_RPR) {
			//Perform calculations until a right parentheses is reached
			while ((long long)vector_top(&ops) != TOK_LPR) {
				if (ops.len == 0) {
					c_error(&t->loc, "Missing '(' in constant expression\n");
					break;
				}
				do_calc(&ops, &vals);
			}
			vector_pop(&ops);
		} else {
			//Check if the operator is valid
			int op = t->type;
			int prec = rankof(t->type);
			if (prec < 0) {
				c_error(&t->loc, "Invalid operation in constant expression\n");
				continue;
			}

			//Error for no LHS
			if (vals.len == 0 && !is_unary(t->type)) {
				c_error(&t->loc, "Operator in constant expression has no LHS\n");
				continue;
			}

			//Handle special case for ternary operator
			if (t->type == TOK_COL) {
				int has_qmk = 0;
				for (int j=0; j<ops.len; j++)
					if ((long long)(ops.table[j]) == TOK_QMK) has_qmk = 1;
				if (!has_qmk)
					c_error(&t->loc, "Missing '?' before ':' in "
							"constant expresion\n");
				continue;
			}

			//Repeat until the current operation's precedence is less than
			//the precedence of the operator at the top of the stack
			for (;;) {
				if (ops.len < 1) break;
				int top_prec = rankof((long long)vector_top(&ops));
				if (prec >= top_prec) break;
				do_calc(&ops, &vals);
			}
			vector_push(&ops, (void*)(long long)t->type);
		}
	}

	//Finish calculations if the condition has ended
	while (ops.len > 0) {
		if (vals.len < 1) {
			c_error(last_loc, "Operator in constant expression has no RHS\n");
			break;
		}
		do_calc(&ops, &vals);
	}
	if (vals.len > 1) {
		c_error(last_loc, "Missing operator in constant expression\n");
	}

	//Get result
	int res = (long long)vector_top(&vals);
	*err = !eflag_prev && c_errflag;
	vector_close(&ops);
	vector_close(&vals);

	return res;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x48, %rsp
movq %rdx, 0x40(%rsp)
movq %rsi, %r15
movq %rdi, 0x38(%rsp)
leaq 0x18(%rsp), %rdi
movl $0x10, %esi
callq 0xc964
leaq 0x8(%rsp), %rdi
movl $0x10, %esi
callq 0xc964
leaq 0x10a73(%rip), %rax     # 0x14474
movl (%rax), %eax
movl %eax, 0x34(%rsp)
movl 0x8(%r15), %eax
testl %eax, %eax
jle 0x3c33
leaq 0x18(%rsp), %r13
xorl %ebp, %ebp
movq (%r15), %rcx
movslq %ebp, %rdx
movq (%rcx,%rdx,8), %r14
leaq 0x8(%r14), %rbx
movl (%r14), %r12d
cmpl $0x31, %r12d
jle 0x3a5c
cmpl $0x32, %r12d
je 0x3a9c
cmpl $0x33, %r12d
je 0x3ad6
cmpl $0x35, %r12d
jne 0x3afc
leaq 0x8(%rsp), %rdi
xorl %esi, %esi
callq 0xc9fa
jmp 0x3c0f
cmpl $0x7, %r12d
je 0x3af2
cmpl $0x8, %r12d
jne 0x3afc
movq %r13, %rdi
callq 0xcabb
cmpq $0x7, %rax
je 0x3bad
cmpl $0x0, 0x20(%rsp)
je 0x3b9c
movq %r13, %rdi
leaq 0x8(%rsp), %rsi
callq 0x3942
jmp 0x3a70
incl %ebp
cmpl %eax, %ebp
jge 0x3b65
movslq %ebp, %rax
movq (%rcx,%rax,8), %rax
cmpl $0x35, (%rax)
jne 0x3b65
movq 0x38(%rsp), %rax
movq 0x60(%rax), %rdi
movq 0x20(%r14), %rsi
callq 0xc219
xorl %esi, %esi
testq %rax, %rax
setne %sil
jmp 0x3b75
movq 0x28(%r14), %rax
cmpl $0x7, (%rax)
jne 0x3b71
movq %rbx, %rdi
leaq 0x97b7(%rip), %rsi      # 0xd2a4
jmp 0x3b93
movl $0x7, %esi
movq %r13, %rdi
jmp 0x3b7a
movq %rbx, 0x28(%rsp)
movl %r12d, %edi
callq 0x3838
testl %eax, %eax
js 0x3b84
movl %eax, %ebx
cmpl $0x0, 0x10(%rsp)
je 0x3bb7
cmpl $0x2, %r12d
jne 0x3bd0
movslq 0x20(%rsp), %rax
testq %rax, %rax
movq 0x28(%rsp), %rbx
movl $0x1, %edi
jle 0x3b59
xorl %ecx, %ecx
movq 0x18(%rsp), %rdx
xorl %esi, %esi
cmpq $0xf, (%rdx,%rcx,8)
cmovel %edi, %esi
incq %rcx
cmpq %rcx, %rax
jne 0x3b41
testl %esi, %esi
jne 0x3c0f
movq %rbx, %rdi
leaq 0x980d(%rip), %rsi      # 0xd370
jmp 0x3b93
movq %rbx, %rdi
leaq 0x9762(%rip), %rsi      # 0xd2d1
jmp 0x3b93
movq 0x20(%r14), %rsi
leaq 0x8(%rsp), %rdi
callq 0xca91
jmp 0x3c0f
movq 0x28(%rsp), %rbx
movq %rbx, %rdi
leaq 0x9787(%rip), %rsi      # 0xd31a
xorl %eax, %eax
callq 0x3250
jmp 0x3c0f
movq %rbx, %rdi
leaq 0x9750(%rip), %rsi      # 0xd2f6
xorl %eax, %eax
callq 0x3250
movq %r13, %rdi
callq 0xca96
jmp 0x3c0f
cmpl $0x32, %r12d
ja 0x3c1f
movl %r12d, %eax
movabsq $0x4000201000000, %rcx  # imm = 0x4000201000000
btq %rax, %rcx
jae 0x3c1f
cmpl $0x0, 0x20(%rsp)
jle 0x3bff
movq %r13, %rdi
callq 0xcabb
movl %eax, %edi
callq 0x3838
movl %eax, %r12d
cmpl %eax, %ebx
jge 0x3bfa
movq %r13, %rdi
leaq 0x8(%rsp), %rsi
callq 0x3942
cmpl %r12d, %ebx
jl 0x3bd0
movslq (%r14), %rsi
movq %r13, %rdi
callq 0xca91
movq 0x28(%rsp), %rbx
incl %ebp
movl 0x8(%r15), %eax
cmpl %eax, %ebp
jl 0x3a1a
jmp 0x3c35
movq 0x28(%rsp), %rbx
movq %rbx, %rdi
leaq 0x9716(%rip), %rsi      # 0xd344
jmp 0x3b93
xorl %ebx, %ebx
movq %rbx, %r14
cmpl $0x0, 0x20(%rsp)
jle 0x3c75
leaq 0x18(%rsp), %rbx
leaq 0x8(%rsp), %r15
cmpl $0x0, 0x10(%rsp)
jle 0x3c64
movq %rbx, %rdi
movq %r15, %rsi
callq 0x3942
cmpl $0x0, 0x20(%rsp)
jg 0x3c49
jmp 0x3c75
leaq 0x9733(%rip), %rsi      # 0xd39e
movq %r14, %rdi
xorl %eax, %eax
callq 0x3250
cmpl $0x2, 0x10(%rsp)
jl 0x3c8d
leaq 0x9747(%rip), %rsi      # 0xd3ca
movq %r14, %rdi
xorl %eax, %eax
callq 0x3250
leaq 0x8(%rsp), %rbx
movq %rbx, %rdi
callq 0xcabb
movq %rax, %r14
cmpl $0x0, 0x34(%rsp)
sete %al
leaq 0x107c8(%rip), %rcx     # 0x14474
cmpl $0x0, (%rcx)
setne %cl
andb %al, %cl
movzbl %cl, %eax
movq 0x40(%rsp), %rcx
movl %eax, (%rcx)
leaq 0x18(%rsp), %rdi
callq 0xc9b1
movq %rbx, %rdi
callq 0xc9b1
movl %r14d, %eax
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq