// File: /workspace/github_c_makefile_star2_O0/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
movq %rsp, %rbp
subq $0x80, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
leaq -0x28(%rbp), %rdi
movl $0x10, %esi
callq 0x10680
leaq -0x38(%rbp), %rdi
movl $0x10, %esi
callq 0x10680
movl $0x0, -0x3c(%rbp)
leaq 0x13623(%rip), %rax     # 0x174a4
movl (%rax), %eax
movl %eax, -0x40(%rbp)
movq $0x0, -0x48(%rbp)
movl -0x3c(%rbp), %eax
movq -0x10(%rbp), %rcx
cmpl 0x8(%rcx), %eax
jge 0x414d
movq -0x10(%rbp), %rax
movq (%rax), %rax
movslq -0x3c(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rax
addq $0x8, %rax
movq %rax, -0x48(%rbp)
movq -0x50(%rbp), %rax
cmpl $0x33, (%rax)
jne 0x3f04
movq -0x50(%rbp), %rax
movq 0x28(%rax), %rax
cmpl $0x7, (%rax)
jne 0x3eee
movq -0x50(%rbp), %rdi
addq $0x8, %rdi
leaq 0xd3c2(%rip), %rsi      # 0x112a4
movb $0x0, %al
callq 0x3880
jmp 0x413f
movq -0x50(%rbp), %rax
movq 0x20(%rax), %rsi
leaq -0x38(%rbp), %rdi
callq 0x108d0
jmp 0x413d
movq -0x50(%rbp), %rax
cmpl $0x32, (%rax)
jne 0x3f95
movq -0x10(%rbp), %rax
movq (%rax), %rax
movl -0x3c(%rbp), %ecx
addl $0x1, %ecx
movl %ecx, -0x3c(%rbp)
movslq %ecx, %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x58(%rbp)
movl -0x3c(%rbp), %eax
movq -0x10(%rbp), %rcx
cmpl 0x8(%rcx), %eax
jge 0x3f41
movq -0x58(%rbp), %rax
cmpl $0x35, (%rax)
je 0x3f5c
movq -0x50(%rbp), %rdi
addq $0x8, %rdi
leaq 0xd381(%rip), %rsi      # 0x112d1
movb $0x0, %al
callq 0x3880
jmp 0x413f
movq -0x8(%rbp), %rax
movq 0x60(%rax), %rdi
movq -0x50(%rbp), %rax
movq 0x20(%rax), %rsi
callq 0xfb60
cmpq $0x0, %rax
setne %al
andb $0x1, %al
movzbl %al, %eax
cltq
movq %rax, -0x60(%rbp)
movq -0x60(%rbp), %rsi
leaq -0x38(%rbp), %rdi
callq 0x108d0
jmp 0x413b
movq -0x50(%rbp), %rax
cmpl $0x35, (%rax)
jne 0x3fb0
leaq -0x38(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x107d0
jmp 0x4139
movq -0x50(%rbp), %rax
cmpl $0x7, (%rax)
jne 0x3fce
movq -0x50(%rbp), %rax
movslq (%rax), %rsi
leaq -0x28(%rbp), %rdi
callq 0x108d0
jmp 0x4137
movq -0x50(%rbp), %rax
cmpl $0x8, (%rax)
jne 0x4023
jmp 0x3fd9
leaq -0x28(%rbp), %rdi
callq 0x10970
cmpq $0x7, %rax
je 0x4015
cmpl $0x0, -0x20(%rbp)
jne 0x4006
movq -0x50(%rbp), %rdi
addq $0x8, %rdi
leaq 0xd2f9(%rip), %rsi      # 0x112f6
movb $0x0, %al
callq 0x3880
jmp 0x4015
leaq -0x28(%rbp), %rdi
leaq -0x38(%rbp), %rsi
callq 0x3da0
jmp 0x3fd9
leaq -0x28(%rbp), %rdi
callq 0x10900
jmp 0x4135
movq -0x50(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x64(%rbp)
movq -0x50(%rbp), %rax
movl (%rax), %edi
callq 0x3a70
movl %eax, -0x68(%rbp)
cmpl $0x0, -0x68(%rbp)
jge 0x405b
movq -0x50(%rbp), %rdi
addq $0x8, %rdi
leaq 0xd2cb(%rip), %rsi      # 0x1131a
movb $0x0, %al
callq 0x3880
jmp 0x413f
cmpl $0x0, -0x30(%rbp)
jne 0x408c
movq -0x50(%rbp), %rax
movl (%rax), %edi
callq 0x3b30
cmpl $0x0, %eax
jne 0x408c
movq -0x50(%rbp), %rdi
addq $0x8, %rdi
leaq 0xd2c4(%rip), %rsi      # 0x11344
movb $0x0, %al
callq 0x3880
jmp 0x413f
movq -0x50(%rbp), %rax
cmpl $0x2, (%rax)
jne 0x40ef
movl $0x0, -0x6c(%rbp)
movl $0x0, -0x70(%rbp)
movl -0x70(%rbp), %eax
cmpl -0x20(%rbp), %eax
jge 0x40d1
movq -0x28(%rbp), %rax
movslq -0x70(%rbp), %rcx
movq (%rax,%rcx,8), %rax
cmpq $0xf, %rax
jne 0x40c4
movl $0x1, -0x6c(%rbp)
jmp 0x40c6
movl -0x70(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x70(%rbp)
jmp 0x40a3
cmpl $0x0, -0x6c(%rbp)
jne 0x40ed
movq -0x50(%rbp), %rdi
addq $0x8, %rdi
leaq 0xd28a(%rip), %rsi      # 0x11370
movb $0x0, %al
callq 0x3880
jmp 0x413f
jmp 0x40f1
cmpl $0x1, -0x20(%rbp)
jge 0x40f9
jmp 0x4125
leaq -0x28(%rbp), %rdi
callq 0x10970
movl %eax, %edi
callq 0x3a70
movl %eax, -0x74(%rbp)
movl -0x68(%rbp), %eax
cmpl -0x74(%rbp), %eax
jl 0x4116
jmp 0x4125
leaq -0x28(%rbp), %rdi
leaq -0x38(%rbp), %rsi
callq 0x3da0
jmp 0x40f1
movq -0x50(%rbp), %rax
movslq (%rax), %rsi
leaq -0x28(%rbp), %rdi
callq 0x108d0
jmp 0x4137
jmp 0x4139
jmp 0x413b
jmp 0x413d
jmp 0x413f
movl -0x3c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3c(%rbp)
jmp 0x3e8e
jmp 0x414f
cmpl $0x0, -0x20(%rbp)
jle 0x417e
cmpl $0x1, -0x30(%rbp)
jge 0x416f
movq -0x48(%rbp), %rdi
leaq 0xd238(%rip), %rsi      # 0x1139e
movb $0x0, %al
callq 0x3880
jmp 0x417e
leaq -0x28(%rbp), %rdi
leaq -0x38(%rbp), %rsi
callq 0x3da0
jmp 0x414f
cmpl $0x1, -0x30(%rbp)
jle 0x4196
movq -0x48(%rbp), %rdi
leaq 0xd23b(%rip), %rsi      # 0x113ca
movb $0x0, %al
callq 0x3880
leaq -0x38(%rbp), %rdi
callq 0x10970
movl %eax, -0x78(%rbp)
xorl %eax, %eax
cmpl $0x0, -0x40(%rbp)
movb %al, -0x79(%rbp)
jne 0x41bd
leaq 0x132f0(%rip), %rax     # 0x174a4
cmpl $0x0, (%rax)
setne %al
movb %al, -0x79(%rbp)
movb -0x79(%rbp), %al
andb $0x1, %al
movzbl %al, %ecx
movq -0x18(%rbp), %rax
movl %ecx, (%rax)
leaq -0x28(%rbp), %rdi
callq 0x10710
leaq -0x38(%rbp), %rdi
callq 0x10710
movl -0x78(%rbp), %eax
addq $0x80, %rsp
popq %rbp
retq
nopl (%rax)