// File: /workspace/github_cpp_makefile_star2_O2/AndrewAlbert[P]Compiler-Theory/SourceCode/parser.cpp
// Function: Parser::ExpressionPrime(int&, int&, bool, bool)
bool Parser::ExpressionPrime(int &inputType, int &inputSize, bool catchTypeError, bool catchSizeError){
	int arithOpType, arithOpSize;
	
	// Get the operator to pass to the codegenerator evaluation stack
	string op = token->ascii;
	
	if( CheckToken(T_BITWISE) ){
		CheckToken(T_NOT); //'NOT' is always optional and will be good for both integer-bitwise and boolean-boolean expressions.
		if( ArithOp(arithOpType, arithOpSize) ){
			if( catchTypeError ){
				if(inputType == TYPE_INTEGER){
					if(arithOpType != TYPE_INTEGER){
						ReportError("Only integer ArithOps can be used for bitwise operators '&' and '|'.");
						catchTypeError = false;
					}
				}
				else if(inputType == TYPE_BOOL){
					if(arithOpType != TYPE_BOOL){
						ReportError("Only boolean ArithOps can be used for boolean operators '&' and '|'.");
						catchTypeError = false;
					}
				}
				else ReportError("Only integer / boolean ArithOps can be used for bitwise / boolean operators '&' and '|'.");
			}
			if( catchSizeError ){
				//Ensure compatible sizes are used.
				if( (inputSize != arithOpSize) && (inputSize != 0) && (arithOpSize != 0) ){
					ReportError("Expected ArithOp of size " + to_string(inputSize) + ", but found one of size " + to_string(arithOpSize) + ".");
					catchSizeError = false;
				}
				//Set new inputSize if the next ArithOp's size was non-zero and inputSize was zero.
				else if(arithOpSize != 0) inputSize = arithOpSize;
			}
		}
		else{
			ReportError("Expected ArithOp after '&' or '|' operator.");
			catchTypeError = false;
			catchSizeError = false;
		}
		ExpressionPrime(inputType, inputSize, catchTypeError, catchSizeError);
		
		// GEN: Evaluate expression and push register onto the stack to pass to upper expression
		// Do not need resulting string since expression result is pushed back onto the stack
		generator->evalExpr( op, inputSize, arithOpSize, inputType, arithOpType );
		
		return true;
	}
	else return false;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x1b8, %rsp            # imm = 0x1B8
movl %r8d, %ebp
movl %ecx, %r13d
movq %rdx, %r15
movq %rsi, %r14
movq %rdi, %r12
movq 0x80(%rdi), %rsi
leaq 0x178(%rsp), %rdi
callq 0x2270
movq %r12, %rdi
movl $0x13b, %esi            # imm = 0x13B
callq 0x49b0
movl %eax, %ebx
testb %al, %al
je 0x802e
movq %r12, %rdi
movl $0x10f, %esi            # imm = 0x10F
callq 0x49b0
leaq 0x14(%rsp), %rsi
leaq 0x10(%rsp), %rdx
movq %r12, %rdi
callq 0x7d2e
testb %al, %al
je 0x7e3e
testb %r13b, %r13b
je 0x7eb6
movl (%r14), %eax
cmpl $0x10c, %eax            # imm = 0x10C
je 0x7e73
cmpl $0x10a, %eax            # imm = 0x10A
jne 0x8061
movb $0x1, %r13b
cmpl $0x10a, 0x14(%rsp)      # imm = 0x10A
je 0x7eb9
leaq 0xa479(%rip), %rsi      # 0x1228b
leaq 0x158(%rsp), %rdi
leaq 0x18(%rsp), %rdx
callq 0x36b8
leaq 0x158(%rsp), %rsi
movq %r12, %rdi
callq 0x47e0
leaq 0x158(%rsp), %rdi
jmp 0x7eb1
leaq 0xa55c(%rip), %rsi      # 0x123a1
leaq 0x58(%rsp), %rdi
leaq 0x18(%rsp), %rdx
callq 0x36b8
leaq 0x58(%rsp), %rsi
movq %r12, %rdi
callq 0x47e0
leaq 0x58(%rsp), %rdi
callq 0x20f0
xorl %r13d, %r13d
jmp 0x7fbe
movb $0x1, %r13b
cmpl $0x10c, 0x14(%rsp)      # imm = 0x10C
je 0x7eb9
leaq 0xa449(%rip), %rsi      # 0x122d0
leaq 0x138(%rsp), %rdi
leaq 0x18(%rsp), %rdx
callq 0x36b8
leaq 0x138(%rsp), %rsi
movq %r12, %rdi
callq 0x47e0
leaq 0x138(%rsp), %rdi
callq 0x20f0
xorl %r13d, %r13d
testb %bpl, %bpl
je 0x7fbe
movl (%r15), %esi
movl 0x10(%rsp), %ecx
cmpl %ecx, %esi
je 0x804f
testl %esi, %esi
sete %al
testl %ecx, %ecx
sete %dl
orb %al, %dl
jne 0x804f
leaq 0x98(%rsp), %rdi
callq 0x96b3
leaq 0xa477(%rip), %rsi      # 0x1236e
leaq 0xb8(%rsp), %rdi
leaq 0x98(%rsp), %rdx
callq 0x968f
leaq 0xa475(%rip), %rdx      # 0x12388
leaq 0xd8(%rsp), %rdi
leaq 0xb8(%rsp), %rsi
callq 0x9670
movl 0x10(%rsp), %esi
leaq 0x78(%rsp), %rdi
callq 0x96b3
leaq 0x18(%rsp), %rdi
leaq 0xd8(%rsp), %rsi
leaq 0x78(%rsp), %rdx
callq 0x9871
leaq 0xa558(%rip), %rdx      # 0x124ac
leaq 0xf8(%rsp), %rdi
leaq 0x18(%rsp), %rsi
callq 0x9670
leaq 0xf8(%rsp), %rsi
movq %r12, %rdi
callq 0x47e0
leaq 0xf8(%rsp), %rdi
callq 0x20f0
leaq 0x18(%rsp), %rdi
callq 0x20f0
leaq 0x78(%rsp), %rdi
callq 0x20f0
leaq 0xd8(%rsp), %rdi
callq 0x20f0
leaq 0xb8(%rsp), %rdi
callq 0x20f0
leaq 0x98(%rsp), %rdi
callq 0x20f0
xorl %eax, %eax
movzbl %r13b, %ecx
movzbl %al, %r8d
movq %r12, %rdi
movq %r14, %rsi
movq %r15, %rdx
callq 0x7d6a
movq 0x98(%r12), %r12
leaq 0x38(%rsp), %rdi
leaq 0x178(%rsp), %rsi
callq 0x2270
movl (%r15), %ecx
movl 0x10(%rsp), %r8d
movl (%r14), %r9d
movl 0x14(%rsp), %eax
movl %eax, (%rsp)
leaq 0x198(%rsp), %rdi
leaq 0x38(%rsp), %rdx
movq %r12, %rsi
callq 0xcbbe
leaq 0x198(%rsp), %rdi
callq 0x20f0
leaq 0x38(%rsp), %rdi
callq 0x20f0
leaq 0x178(%rsp), %rdi
callq 0x20f0
movl %ebx, %eax
addq $0x1b8, %rsp            # imm = 0x1B8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movb $0x1, %al
testl %ecx, %ecx
je 0x7fc0
movl %ecx, (%r15)
jmp 0x7fc0
leaq 0xa2ad(%rip), %rsi      # 0x12315
leaq 0x118(%rsp), %rdi
leaq 0x18(%rsp), %rdx
callq 0x36b8
leaq 0x118(%rsp), %rsi
movq %r12, %rdi
callq 0x47e0
leaq 0x118(%rsp), %rdi
callq 0x20f0
movb $0x1, %r13b
jmp 0x7eb9
movq %rax, %rbx
leaq 0x138(%rsp), %rdi
jmp 0x814f
movq %rax, %rbx
leaq 0x158(%rsp), %rdi
jmp 0x814f
jmp 0x8156
jmp 0x8156
movq %rax, %rbx
leaq 0xf8(%rsp), %rdi
callq 0x20f0
jmp 0x80de
movq %rax, %rbx
leaq 0x18(%rsp), %rdi
callq 0x20f0
jmp 0x80ed
movq %rax, %rbx
leaq 0x78(%rsp), %rdi
callq 0x20f0
jmp 0x80fc
movq %rax, %rbx
leaq 0xd8(%rsp), %rdi
callq 0x20f0
jmp 0x810e
movq %rax, %rbx
leaq 0xb8(%rsp), %rdi
callq 0x20f0
leaq 0x98(%rsp), %rdi
jmp 0x814f
movq %rax, %rbx
jmp 0x811b
jmp 0x8156
movq %rax, %rbx
leaq 0x118(%rsp), %rdi
jmp 0x814f
jmp 0x8156
movq %rax, %rbx
leaq 0x58(%rsp), %rdi
jmp 0x814f
jmp 0x8156
movq %rax, %rbx
leaq 0x38(%rsp), %rdi
callq 0x20f0
jmp 0x8159
movq %rax, %rbx
leaq 0x178(%rsp), %rdi
callq 0x20f0
movq %rbx, %rdi
callq 0x2310