// File: /workspace/github_c_makefile_star2_O2/mist64[P]cbm6502asm/src/express.c
// Function: evaluate
int evaluate(char *str, long *value) {
	int i;
	char c;

	expdef = TRUE; /* assume expression will be defined */
	lastval = FALSE;
	lp = str;
	osp = vsp = MAXESTK;
	opstk[--osp] = '$';
	while ((c = *lp)) {
		if (isspace(c) || c == ';') break;
		if (osp <= 0 || vsp <= 0)
			error_msg("evaluation stack overflow ", str, 4);
		if (osp > MAXESTK || vsp > MAXESTK)
			error_msg("evaluation stack underflow ", str, 4);
		lp++; /* point to next character */

		if (isalpha(c) || c == '.' ||
		    c == '_') { /* it must be a symbol */
			pushval(evalsym());
			continue;
		}
		if (c == '\"' || c == '\'') { /* it is a character constant */
			pushval(evalchar(c));
			continue;
		}
		if (isdigit(c)) { /* it is a decimal number */
			lp--;     /* point to the digit again */
			pushval(evalocal());
			continue;
		}
		if (c == RADIX2) { /* it is a binary constant */
			pushval(evalcon(2));
			continue;
		}
		if (c == RADIX8) { /* it is an octal constant */
			pushval(evalcon(8));
			continue;
		}
		if (c == RADIX16) { /* it is a hexidecimal constant */
			pushval(evalcon(16));
			continue;
		}

		if (c == '!') {           /* start of 2 character operator */
			c = toupper(*lp); /* get the rest of the operator */
			lp++;
			if (!(c == 'N' || c == '.' || c == '+' || c == 'X'))
				display_error(error = 'E');
			else {
				if (c == 'N') c = '~';
				if (c == '.') c = '&';
				if (c == '+') c = '|';
				if (c == 'X') c = '^';
				eval(c);
			}
			continue;
		}
		if (c == '*') { /* multiply or location counter */
			/* if preceded by nothing or an operator then it is the
			 * location counter */
			if (!lastval)
				pushval(loc_cntr);
			else
				/* if preceded by a constant or symbol then it
				 * is the multiply operator */
				eval(c);
			continue;
		}
		if (c == '>' || c == '<' || c == '/') {
			eval(c);
			continue;
		}
		if (c == '+') { /* unary or binary operator */
			/* if preceded by nothing or an operator then it is a
			 * unary +, ignore it */
			/* if preceded by a constant or symbol then it is a
			 * binary operator */
			if (lastval) eval(c);
			continue;
		}
		if (c == '-') { /* unary or binary operator */
			/* if preceded by nothing or an operator then it is a
			 * unary operator */
			if (!lastval) c = '_';
			/* if preceded by a constant or symbol then it is a
			 * binary operator */
			eval(c);
			continue;
		}
		if (c == '(') {
			eval(c);
			continue;
		}
		if (c == ')') {
			int more = TRUE;
			while (more)
				if (opstk[osp] == '(') {
					more = FALSE;
					osp++;
					pushval(stack[vsp++]);
				} else if (opstk[osp] == '$') {
					display_error(error = 'B');
					more = FALSE;
				} else
					do_oper();
			continue;
		}
		display_error(error = 'C'); /* no valid state if we get here */
	}
	while (opstk[osp] != '$') do_oper();
	for (i = osp; i < MAXESTK; i++)
		if (opstk[i] == '(')
			display_error(
			        error = 'B'); /* too many ( in expression */
	if (vsp != MAXESTK - 1)
		display_error(error = 'E'); /* stack was messed up */
	if (error) stack[vsp] = 0;
	*value = stack[vsp];
	return (expdef);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rsi, (%rsp)
movq %rdi, %r14
leaq 0x9631(%rip), %rax      # 0xdde8
movl $0x1, (%rax)
andl $0x0, 0x9cc4(%rip)      # 0xe488
movq %rdi, 0x9b15(%rip)      # 0xe2e0
movl $0x32, 0x9cab(%rip)     # 0xe480
movl $0x31, 0x9ca5(%rip)     # 0xe484
movb $0x24, 0x9cdb(%rip)     # 0xe4c1
pushq $0x4
popq %rbp
leaq 0x9ca0(%rip), %r12      # 0xe490
movq %rdi, %rax
movsbq (%rax), %r13
testq %r13, %r13
je 0x4a81
callq 0x1240
cmpb $0x3b, %r13b
je 0x4a81
movq %rax, %rbx
movq (%rax), %rax
movzwl (%rax,%r13,2), %eax
andl $0x2000, %eax           # imm = 0x2000
jne 0x4a81
movl 0x9c59(%rip), %ecx      # 0xe484
testl %ecx, %ecx
setle %dl
movl 0x9c4a(%rip), %eax      # 0xe480
testl %eax, %eax
setle %sil
orb %dl, %sil
cmpb $0x1, %sil
jne 0x4862
leaq 0x4d04(%rip), %rdi      # 0x9550
movq %r14, %rsi
movl %ebp, %edx
callq 0x1ddf
movl 0x9c28(%rip), %ecx      # 0xe484
movl 0x9c1e(%rip), %eax      # 0xe480
cmpl $0x32, %ecx
jg 0x486c
cmpl $0x33, %eax
jl 0x487d
leaq 0x4cf8(%rip), %rdi      # 0x956b
movq %r14, %rsi
movl %ebp, %edx
callq 0x1ddf
movq 0x9a5c(%rip), %r15      # 0xe2e0
leaq 0x1(%r15), %rax
movq %rax, 0x9a51(%rip)      # 0xe2e0
movq (%rbx), %rax
movzwl (%rax,%r13,2), %eax
btl $0xa, %eax
jb 0x48b6
cmpb $0x22, %r13b
je 0x48bd
movzbl %r13b, %ecx
cmpl $0x27, %ecx
je 0x48bd
cmpl $0x5f, %ecx
je 0x48b6
cmpl $0x2e, %ecx
jne 0x48d9
callq 0x4134
jmp 0x48c5
movl %r13d, %edi
callq 0x4421
movq %rax, %rdi
callq 0x44e6
movq 0x9a0c(%rip), %rax      # 0xe2e0
jmp 0x47f3
btl $0xb, %eax
jb 0x4998
movzbl %r13b, %eax
leal -0x21(%rax), %ecx
cmpl $0xe, %ecx
ja 0x49a9
leaq 0x4c1a(%rip), %rdx      # 0x9514
movslq (%rdx,%rcx,4), %rax
addq %rdx, %rax
jmpq *%rax
callq 0x1030
movq (%rax), %rax
movsbq 0x1(%r15), %rcx
movl (%rax,%rcx,4), %eax
addq $0x2, %r15
movq %r15, 0x99c2(%rip)      # 0xe2e0
movl %eax, %ecx
shll $0x18, %ecx
cmpl $0x2b000000, %ecx       # imm = 0x2B000000
je 0x4947
cmpl $0x2e000000, %ecx       # imm = 0x2E000000
je 0x4947
cmpl $0x4e000000, %ecx       # imm = 0x4E000000
je 0x4947
cmpl $0x58000000, %ecx       # imm = 0x58000000
jne 0x4a65
cmpl $0x4e000000, %ecx       # imm = 0x4E000000
pushq $0x7e
popq %rcx
cmovel %ecx, %eax
cmpb $0x2e, %al
pushq $0x26
popq %rcx
cmovel %ecx, %eax
cmpb $0x2b, %al
pushq $0x7c
popq %rcx
cmovel %ecx, %eax
cmpb $0x58, %al
pushq $0x5e
popq %rcx
cmovel %ecx, %eax
movsbl %al, %edi
jmp 0x4a16
movslq 0x9b0a(%rip), %rax      # 0xe484
movzbl (%rax,%r12), %ecx
cmpl $0x24, %ecx
je 0x4a48
cmpl $0x28, %ecx
je 0x4a20
callq 0x4599
jmp 0x4973
movq %r15, 0x9941(%rip)      # 0xe2e0
callq 0x42f5
jmp 0x48c5
cmpl $0x3c, %eax
je 0x49bc
cmpl $0x3e, %eax
je 0x49bc
cmpl $0x40, %eax
jne 0x49c1
pushq $0x8
jmp 0x49ff
movl %r13d, %edi
jmp 0x4a16
leaq 0x9438(%rip), %rax      # 0xde00
movb $0x43, (%rax)
pushq $0x43
jmp 0x4a71
cmpl $0x0, 0x9aaf(%rip)      # 0xe488
pushq $0x2d
popq %rdi
pushq $0x5f
popq %rax
cmovel %eax, %edi
jmp 0x4a16
pushq $0x28
jmp 0x4a15
cmpl $0x0, 0x9a99(%rip)      # 0xe488
je 0x48cd
pushq $0x2b
jmp 0x4a15
pushq $0x10
jmp 0x49ff
pushq $0x2
popq %rdi
callq 0x4272
jmp 0x48c5
cmpl $0x0, 0x9a77(%rip)      # 0xe488
je 0x4a56
pushq $0x2a
popq %rdi
callq 0x46e4
jmp 0x48cd
incl %eax
movl %eax, 0x9a5c(%rip)      # 0xe484
movslq 0x9a51(%rip), %rax      # 0xe480
leal 0x1(%rax), %ecx
movl %ecx, 0x9a48(%rip)      # 0xe480
leaq 0x98b1(%rip), %rcx      # 0xe2f0
movq (%rcx,%rax,8), %rdi
jmp 0x48c8
leaq 0x93b1(%rip), %rax      # 0xde00
movb $0x42, (%rax)
pushq $0x42
jmp 0x4a71
leaq 0x8dc3(%rip), %rax      # 0xd820
movq (%rax), %rdi
jmp 0x48c8
leaq 0x9394(%rip), %rax      # 0xde00
movb $0x45, (%rax)
pushq $0x45
popq %rdi
callq 0x1e1c
jmp 0x48cd
callq 0x4599
movslq 0x99fc(%rip), %r14      # 0xe484
cmpb $0x24, (%r14,%r12)
jne 0x4a7c
pushq $0x42
popq %rbx
leaq 0x9367(%rip), %r15      # 0xde00
cmpq $0x31, %r14
jg 0x4ab6
cmpb $0x28, (%r14,%r12)
jne 0x4ab1
movb $0x42, (%r15)
movl %ebx, %edi
callq 0x1e1c
incq %r14
jmp 0x4a99
cmpl $0x31, 0x99c3(%rip)     # 0xe480
jne 0x4ac4
pushq $0x31
popq %rax
jmp 0x4ad7
movb $0x45, (%r15)
pushq $0x45
popq %rdi
callq 0x1e1c
movslq 0x99a9(%rip), %rax      # 0xe480
cmpb $0x0, (%r15)
je 0x4aed
leaq 0x980c(%rip), %rcx      # 0xe2f0
andq $0x0, (%rcx,%rax,8)
xorl %eax, %eax
jmp 0x4af8
leaq 0x97fc(%rip), %rcx      # 0xe2f0
movq (%rcx,%rax,8), %rax
movq (%rsp), %rcx
movq %rax, (%rcx)
leaq 0x92e2(%rip), %rax      # 0xdde8
movl (%rax), %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop