// File: /workspace/github_cpp_makefile_star2_O2/AndrewAlbert[P]Compiler-Theory/SourceCode/codeGenerator.cpp
// Function: codeGenerator::evalExpr(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, int, int, int, int)
string codeGenerator::evalExpr( string op, int size_left, int size_right, int type_left, int type_right ){
	if( !ShouldGenerate() ) return "";
	string lhs, rhs, result;
	int i, type_result;
	bool checkBool = false;
	// Ensure sizes are at least 1 so that loops will execute for scalars
	if( size_left == 0 ) size_left++;
	if( size_right == 0 ) size_right++;
	
	/* Invalidate OUT/INOUT arguments since an expresion such as <Name> * 2 has occurred
	 * there is no return value now and so there is no location to put an OUT argument */
	if( checkArguments() ) invalidateArgument();
	
	//Select int registers or float registers to put the result in
	if( type_left != type_right ){
		if( ( type_left == TYPE_FLOAT ) || ( type_right == TYPE_FLOAT ) ){ 
			type_result = TYPE_FLOAT;
		}
		else if( ( type_left == TYPE_BOOL ) || ( type_right == TYPE_BOOL ) ){
			type_result = TYPE_BOOL;
			if( (type_left == TYPE_INTEGER ) || (type_right == TYPE_INTEGER) ) checkBool = true;
		}
		else type_result = TYPE_INTEGER;
	}
	else type_result = type_left;

	// Convert operations for bitwise or boolean comparison to the correct C operator
	if(op.compare("&") == 0){ 
		if( (type_left == TYPE_BOOL) || (type_right == TYPE_BOOL) ){
			op = "&&";
			// add runtime check for integer/bool
		}
		else op = "&";
	}
	else if(op.compare("|") == 0){ 
		if( (type_left == TYPE_BOOL) || (type_right == TYPE_BOOL) ){
			op = "||";
			// add runtime check for integer/bool
		}
		else op = "|";
	}
	else if(op.compare("NOT") == 0){
		if( (type_left == TYPE_BOOL) || (type_right == TYPE_BOOL) ){
			op = "!";
			// add runtime check for integer/bool
		}
		else op = "~";
	}

	// Push the LHS and RHS operands to their respective stacks and then result to exprStack
	if( ( size_left > 1 ) && ( size_right > 1) ){
		// If LHS and RHS are both arrays ( same size checked by parser )
		for( i = 0; i < size_right; i++ ){
			rhs = popStack('E', type_right);
			pushStack(rhs, 'R', type_right);
		}
		for( i = 0; i < size_left; i++ ){
			lhs = popStack('E', type_left);
			pushStack(lhs, 'L', type_left);
		}
		for( i = 0; i < size_left; i++ ){
			rhs = popStack('R', type_right);
			lhs = popStack('L', type_left);
			result = newRegister(type_result);
			pushStack( result, 'E', type_result );
			if(checkBool) fprintf( oFile, "   handleBoolOp( %s, %s );\n", lhs.c_str(), rhs.c_str() );
			fprintf( oFile, "   %s = %s %s %s;\n", result.c_str(), lhs.c_str(), op.c_str(), rhs.c_str() );
		}
	}
	else if( size_left > 1 ){
		// If LHS is an array and RHS is a single value
		rhs = popStack('E', type_right);
		for( i = 0; i < size_left; i++ ){
			lhs = popStack('E', type_left);
			pushStack(lhs, 'L', type_left);
		}
		for( i = 0; i < size_left; i++ ){
			lhs = popStack('L', type_left);
			result = newRegister(type_result);
			pushStack( result, 'E', type_result );
			if(checkBool) fprintf( oFile, "   handleBoolOp( %s, %s );\n", lhs.c_str(), rhs.c_str() );
			fprintf( oFile, "   %s = %s %s %s;\n", result.c_str(), lhs.c_str(), op.c_str(), rhs.c_str() );
		}
	}
	else if( size_right > 1 ){
		// If LHS is a single value and RHS is an array
		for( i = 0; i < size_right; i++ ){
			rhs = popStack('R', type_right);
			pushStack(rhs, 'R', type_right);
		}
		lhs = popStack('E', type_left);
		for( i = 0; i < size_right; i++ ){
			rhs = popStack('R', type_right);
			result = newRegister(type_result);
			pushStack( result, 'E', type_result );
			if(checkBool) fprintf( oFile, "   handleBoolOp( %s, %s );\n", lhs.c_str(), rhs.c_str() );
			fprintf( oFile, "   %s = %s %s %s;\n", result.c_str(), lhs.c_str(), op.c_str(), rhs.c_str() );
		}
	}
	else{
		// If LHS and RHS are both single values
		rhs = popStack('E', type_right);
		lhs = popStack('E', type_left);
		result = newRegister(type_result);
		pushStack( result, 'E', type_result );
		if(checkBool) fprintf( oFile, "   handleBoolOp( %s, %s );\n", lhs.c_str(), rhs.c_str() );
		fprintf( oFile, "   %s = %s %s %s;\n", result.c_str(), lhs.c_str(), op.c_str(), rhs.c_str() );
	}
	return result;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x188, %rsp            # imm = 0x188
movl %r9d, 0x8(%rsp)
movq %rdi, %rbx
cmpb $0x0, 0x330(%rsi)
je 0xcc6d
movl %r8d, %r13d
movl %ecx, %ebp
movq %rdx, %r12
movq %rsi, %r15
leaq 0x38(%rsp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
xorl %ecx, %ecx
movb %cl, (%rax)
leaq 0x58(%rsp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
movl 0x1c0(%rsp), %r14d
movb %cl, (%rax)
leaq 0x10(%rbx), %rax
movq %rax, (%rbx)
andq $0x0, 0x8(%rbx)
movq %rbx, 0x10(%rsp)
movb %cl, 0x10(%rbx)
cmpl $0x1, %ebp
adcl $0x0, %ebp
cmpl $0x1, %r8d
adcl $0x0, %r13d
cmpb $0x1, 0x2b6(%rsi)
jne 0xcc56
cmpb $0x0, 0x2b7(%r15)
jne 0xcc56
movb $0x1, 0x2b7(%r15)
movl 0x8(%rsp), %edx
cmpl %r14d, %edx
jne 0xcc86
movl $0x0, 0xc(%rsp)
movl %edx, 0x4(%rsp)
jmp 0xcce6
leaq 0x5cc9(%rip), %rsi      # 0x1293d
leaq 0x28(%rsp), %rdx
movq %rbx, %rdi
callq 0x36b8
jmp 0xd2e1
movl $0x10b, %ecx            # imm = 0x10B
cmpl %ecx, %edx
sete %al
movl $0x10b, 0x4(%rsp)       # imm = 0x10B
cmpl %ecx, %r14d
sete %cl
orb %al, %cl
jne 0xccde
movl $0x10c, %ecx            # imm = 0x10C
cmpl %ecx, %edx
setne %al
movl $0x10c, 0x4(%rsp)       # imm = 0x10C
cmpl %ecx, %r14d
setne %cl
testb %cl, %al
jne 0xccd6
movl $0x10a, %eax            # imm = 0x10A
cmpl %eax, %edx
sete %cl
cmpl %eax, %r14d
sete %al
orb %cl, %al
movl %eax, 0xc(%rsp)
jmp 0xcce6
movl $0x10a, 0x4(%rsp)       # imm = 0x10A
movl $0x0, 0xc(%rsp)
leaq 0x60e4(%rip), %rbx      # 0x12dd1
movq %r12, %rdi
movq %rbx, %rsi
callq 0x20a0
testl %eax, %eax
je 0xcd3d
leaq 0x60d1(%rip), %rbx      # 0x12dd4
movq %r12, %rdi
movq %rbx, %rsi
callq 0x20a0
testl %eax, %eax
je 0xcd4e
leaq 0x43db(%rip), %rsi      # 0x110f4
movq %r12, %rdi
callq 0x20a0
testl %eax, %eax
jne 0xcd74
movl $0x10c, %eax            # imm = 0x10C
cmpl %eax, %r14d
leaq 0x5c38(%rip), %rcx      # 0x1296c
leaq 0x609b(%rip), %rbx      # 0x12dd6
jmp 0xcd5d
movl $0x10c, %eax            # imm = 0x10C
cmpl %eax, %r14d
leaq 0x6084(%rip), %rcx      # 0x12dd0
jmp 0xcd5d
movl $0x10c, %eax            # imm = 0x10C
cmpl %eax, %r14d
leaq 0x6076(%rip), %rcx      # 0x12dd3
cmoveq %rcx, %rbx
cmpl %eax, 0x8(%rsp)
cmoveq %rcx, %rbx
movq %r12, %rdi
movq %rbx, %rsi
callq 0x2370
cmpl $0x2, %ebp
setl %al
cmpl $0x2, %r13d
setl %cl
orb %al, %cl
jne 0xce0a
movq %r12, 0x20(%rsp)
leaq 0x180(%r15), %rax
movq %rax, 0x18(%rsp)
leaq 0x68(%rsp), %r12
leaq 0x48(%rsp), %rbx
leaq 0x168(%rsp), %r14
subl $0x1, %r13d
jb 0xcebc
movq %r12, %rdi
movq %r15, %rsi
pushq $0x45
popq %rdx
movl 0x1c0(%rsp), %ecx
callq 0xc92c
movq %rbx, %rdi
movq %r12, %rsi
callq 0x2240
movq %r12, %rdi
callq 0x20f0
movq %r14, %rdi
movq %rbx, %rsi
callq 0x2270
cmpb $0x1, 0x330(%r15)
jne 0xce00
movq 0x18(%rsp), %rdi
movq %r14, %rsi
callq 0xfbc6
movq %r14, %rdi
callq 0x20f0
jmp 0xcdac
cmpl $0x2, %ebp
jl 0xd045
movq %r12, 0x20(%rsp)
leaq 0x68(%rsp), %rdi
pushq $0x45
popq %rdx
movq %r15, %rsi
movl %r14d, %ecx
callq 0xc92c
leaq 0x48(%rsp), %rdi
leaq 0x68(%rsp), %r14
movq %r14, %rsi
callq 0x2240
movq %r14, %rdi
callq 0x20f0
leaq 0x1d0(%r15), %rax
movq %rax, 0x18(%rsp)
leaq 0x28(%rsp), %r12
leaq 0x108(%rsp), %rbx
movl %ebp, %r13d
subl $0x1, %r13d
jb 0xd0d3
movq %r14, %rdi
movq %r15, %rsi
pushq $0x45
popq %rdx
movl 0x8(%rsp), %ecx
callq 0xc92c
movq %r12, %rdi
movq %r14, %rsi
callq 0x2240
movq %r14, %rdi
callq 0x20f0
movq %rbx, %rdi
movq %r12, %rsi
callq 0x2270
cmpb $0x1, 0x330(%r15)
jne 0xceb2
movq 0x18(%rsp), %rdi
movq %rbx, %rsi
callq 0xfbc6
movq %rbx, %rdi
callq 0x20f0
jmp 0xce61
leaq 0x1d0(%r15), %rax
movq %rax, 0x18(%rsp)
leaq 0x68(%rsp), %r12
leaq 0x28(%rsp), %r14
leaq 0x148(%rsp), %rbx
movl %ebp, %r13d
subl $0x1, %r13d
jb 0xcf34
movq %r12, %rdi
movq %r15, %rsi
pushq $0x45
popq %rdx
movl 0x8(%rsp), %ecx
callq 0xc92c
movq %r14, %rdi
movq %r12, %rsi
callq 0x2240
movq %r12, %rdi
callq 0x20f0
movq %rbx, %rdi
movq %r14, %rsi
callq 0x2270
cmpb $0x1, 0x330(%r15)
jne 0xcf2a
movq 0x18(%rsp), %rdi
movq %rbx, %rsi
callq 0xfbc6
movq %rbx, %rdi
callq 0x20f0
jmp 0xcedd
leaq 0x68(%rsp), %r14
leaq 0x128(%rsp), %r13
movl 0x8(%rsp), %r12d
movq 0x10(%rsp), %rbx
subl $0x1, %ebp
jb 0xd2c8
movq %r14, %rdi
movq %r15, %rsi
pushq $0x52
popq %rdx
movl 0x1c0(%rsp), %ecx
callq 0xc92c
leaq 0x48(%rsp), %rdi
movq %r14, %rsi
callq 0x2240
movq %r14, %rdi
callq 0x20f0
movq %r14, %rdi
movq %r15, %rsi
pushq $0x4c
popq %rdx
movl %r12d, %ecx
callq 0xc92c
leaq 0x28(%rsp), %rdi
movq %r14, %rsi
callq 0x2240
movq %r14, %rdi
callq 0x20f0
movq %r14, %rdi
movq %r15, %rsi
movl 0x4(%rsp), %edx
callq 0xd4fe
movq %rbx, %rdi
movq %r14, %rsi
callq 0x2240
movq %r14, %rdi
callq 0x20f0
movq %r13, %rdi
movq %rbx, %rsi
callq 0x2270
movq %r15, %rdi
movq %r13, %rsi
pushq $0x45
popq %rdx
movl 0x4(%rsp), %ecx
callq 0xc8a8
movq %r13, %rdi
callq 0x20f0
cmpb $0x0, 0xc(%rsp)
je 0xd011
movq 0x308(%r15), %rdi
movq 0x28(%rsp), %rdx
movq 0x48(%rsp), %rcx
leaq 0x5dce(%rip), %rsi      # 0x12dd8
xorl %eax, %eax
callq 0x2280
movq 0x308(%r15), %rdi
movq 0x10(%rsp), %rax
movq (%rax), %rdx
movq 0x28(%rsp), %rcx
movq 0x20(%rsp), %rax
movq (%rax), %r8
movq 0x48(%rsp), %r9
leaq 0x5dbb(%rip), %rsi      # 0x12df4
xorl %eax, %eax
callq 0x2280
jmp 0xcf4b
cmpl $0x2, %r13d
jl 0xd1ba
movq %r12, 0x20(%rsp)
leaq 0x180(%r15), %rax
movq %rax, 0x18(%rsp)
leaq 0x68(%rsp), %rbp
leaq 0x48(%rsp), %rbx
leaq 0xc8(%rsp), %r12
movl %r13d, %r14d
subl $0x1, %r14d
jb 0xd2f6
movq %rbp, %rdi
movq %r15, %rsi
pushq $0x52
popq %rdx
movl 0x1c0(%rsp), %ecx
callq 0xc92c
movq %rbx, %rdi
movq %rbp, %rsi
callq 0x2240
movq %rbp, %rdi
callq 0x20f0
movq %r12, %rdi
movq %rbx, %rsi
callq 0x2270
cmpb $0x1, 0x330(%r15)
jne 0xd0c9
movq 0x18(%rsp), %rdi
movq %r12, %rsi
callq 0xfbc6
movq %r12, %rdi
callq 0x20f0
jmp 0xd075
leaq 0x68(%rsp), %r14
leaq 0xe8(%rsp), %r13
movl 0x8(%rsp), %r12d
movq 0x10(%rsp), %rbx
subl $0x1, %ebp
jb 0xd2c8
movq %r14, %rdi
movq %r15, %rsi
pushq $0x4c
popq %rdx
movl %r12d, %ecx
callq 0xc92c
leaq 0x28(%rsp), %rdi
movq %r14, %rsi
callq 0x2240
movq %r14, %rdi
callq 0x20f0
movq %r14, %rdi
movq %r15, %rsi
movl 0x4(%rsp), %edx
callq 0xd4fe
movq %rbx, %rdi
movq %r14, %rsi
callq 0x2240
movq %r14, %rdi
callq 0x20f0
movq %r13, %rdi
movq %rbx, %rsi
callq 0x2270
movq %r15, %rdi
movq %r13, %rsi
pushq $0x45
popq %rdx
movl 0x4(%rsp), %ecx
callq 0xc8a8
movq %r13, %rdi
callq 0x20f0
cmpb $0x0, 0xc(%rsp)
je 0xd186
movq 0x308(%r15), %rdi
movq 0x28(%rsp), %rdx
movq 0x48(%rsp), %rcx
leaq 0x5c59(%rip), %rsi      # 0x12dd8
xorl %eax, %eax
callq 0x2280
movq 0x308(%r15), %rdi
movq 0x10(%rsp), %rax
movq (%rax), %rdx
movq 0x28(%rsp), %rcx
movq 0x20(%rsp), %rax
movq (%rax), %r8
movq 0x48(%rsp), %r9
leaq 0x5c46(%rip), %rsi      # 0x12df4
xorl %eax, %eax
callq 0x2280
jmp 0xd0ea
leaq 0x68(%rsp), %rdi
pushq $0x45
popq %rdx
movq %r15, %rsi
movl %r14d, %ecx
callq 0xc92c
leaq 0x48(%rsp), %rdi
leaq 0x68(%rsp), %rbx
movq %rbx, %rsi
callq 0x2240
movq %rbx, %rdi
callq 0x20f0
leaq 0x68(%rsp), %rdi
pushq $0x45
popq %rdx
movq %r15, %rsi
movl 0x8(%rsp), %ecx
callq 0xc92c
leaq 0x28(%rsp), %rdi
leaq 0x68(%rsp), %rbx
movq %rbx, %rsi
callq 0x2240
movq %rbx, %rdi
callq 0x20f0
leaq 0x68(%rsp), %rdi
movq %r15, %rsi
movl 0x4(%rsp), %edx
callq 0xd4fe
leaq 0x68(%rsp), %rbx
movq 0x10(%rsp), %r14
movq %r14, %rdi
movq %rbx, %rsi
callq 0x2240
movq %rbx, %rdi
callq 0x20f0
leaq 0x88(%rsp), %rdi
movq %r14, %rsi
callq 0x2270
leaq 0x88(%rsp), %rsi
pushq $0x45
popq %rdx
movq %r15, %rdi
movl 0x4(%rsp), %ecx
callq 0xc8a8
leaq 0x88(%rsp), %rdi
callq 0x20f0
cmpb $0x0, 0xc(%rsp)
je 0xd29d
movq 0x308(%r15), %rdi
movq 0x28(%rsp), %rdx
movq 0x48(%rsp), %rcx
leaq 0x5b42(%rip), %rsi      # 0x12dd8
xorl %eax, %eax
callq 0x2280
movq 0x308(%r15), %rdi
movq 0x10(%rsp), %rax
movq (%rax), %rdx
movq 0x28(%rsp), %rcx
movq (%r12), %r8
movq 0x48(%rsp), %r9
leaq 0x5b33(%rip), %rsi      # 0x12df4
xorl %eax, %eax
callq 0x2280
leaq 0x48(%rsp), %rdi
callq 0x20f0
leaq 0x28(%rsp), %rdi
callq 0x20f0
movq 0x10(%rsp), %rbx
movq %rbx, %rax
addq $0x188, %rsp            # imm = 0x188
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x68(%rsp), %rdi
pushq $0x45
popq %rdx
movq %r15, %rsi
movl 0x8(%rsp), %ecx
callq 0xc92c
leaq 0x28(%rsp), %rdi
leaq 0x68(%rsp), %r12
movq %r12, %rsi
callq 0x2240
movq %r12, %rdi
callq 0x20f0
leaq 0xa8(%rsp), %rbp
leaq 0x5ac1(%rip), %rbx      # 0x12df4
movq 0x10(%rsp), %r14
subl $0x1, %r13d
jb 0xd2c8
movq %r12, %rdi
movq %r15, %rsi
pushq $0x52
popq %rdx
movl 0x1c0(%rsp), %ecx
callq 0xc92c
leaq 0x48(%rsp), %rdi
movq %r12, %rsi
callq 0x2240
movq %r12, %rdi
callq 0x20f0
movq %r12, %rdi
movq %r15, %rsi
movl 0x4(%rsp), %edx
callq 0xd4fe
movq %r14, %rdi
movq %r12, %rsi
callq 0x2240
movq %r12, %rdi
callq 0x20f0
movq %rbp, %rdi
movq %r14, %rsi
callq 0x2270
movq %r15, %rdi
movq %rbp, %rsi
pushq $0x45
popq %rdx
movl 0x4(%rsp), %ecx
callq 0xc8a8
movq %rbp, %rdi
callq 0x20f0
cmpb $0x0, 0xc(%rsp)
je 0xd3d5
movq 0x308(%r15), %rdi
movq 0x28(%rsp), %rdx
movq 0x48(%rsp), %rcx
leaq 0x5a0a(%rip), %rsi      # 0x12dd8
xorl %eax, %eax
callq 0x2280
movq 0x308(%r15), %rdi
movq 0x10(%rsp), %rax
movq (%rax), %rdx
movq 0x28(%rsp), %rcx
movq 0x20(%rsp), %rax
movq (%rax), %r8
movq 0x48(%rsp), %r9
movq %rbx, %rsi
xorl %eax, %eax
callq 0x2280
jmp 0xd338
jmp 0xd4b5
movq %rax, %r14
leaq 0x88(%rsp), %rdi
jmp 0xd4a6
jmp 0xd4b5
jmp 0xd4b5
jmp 0xd4b5
jmp 0xd4b5
jmp 0xd4b5
movq %rax, %r14
leaq 0xc8(%rsp), %rdi
jmp 0xd4a6
jmp 0xd4b5
jmp 0xd4b5
jmp 0xd4b5
movq %rax, %r14
leaq 0xa8(%rsp), %rdi
jmp 0xd4a6
jmp 0xd4b5
jmp 0xd4b5
movq %rax, %r14
leaq 0x108(%rsp), %rdi
jmp 0xd4a6
jmp 0xd4b5
jmp 0xd4b5
jmp 0xd4b5
movq %rax, %r14
leaq 0xe8(%rsp), %rdi
jmp 0xd4a6
movq %rax, %r14
leaq 0x148(%rsp), %rdi
jmp 0xd4a6
jmp 0xd4b5
jmp 0xd4b5
movq %rax, %r14
leaq 0x168(%rsp), %rdi
jmp 0xd4a6
jmp 0xd4b5
jmp 0xd4b5
jmp 0xd4b5
movq %rax, %r14
leaq 0x128(%rsp), %rdi
callq 0x20f0
jmp 0xd4b8
jmp 0xd4b5
jmp 0xd4b5
jmp 0xd4b5
jmp 0xd4b5
movq %rax, %r14
movq 0x10(%rsp), %rdi
callq 0x20f0
leaq 0x48(%rsp), %rdi
callq 0x20f0
leaq 0x28(%rsp), %rdi
callq 0x20f0
movq %r14, %rdi
callq 0x2310