// File: /workspace/github_cpp_makefile_star2_O2/AshOlogn[P]ash-language-interpreter/src/parser.cpp
// Function: evalPrefixCastSignNot()
AbstractExpressionNode* evalPrefixCastSignNot() {
 
  //check if prefix
  if(isPrefixStructure()) {

    Token* firstPlus = consume();
    Token* secondPlus = consume(); //consume second +

    AbstractExpressionNode* head = evalPostfixMemberAccess();
    VariableNode* varNode = dynamic_cast<VariableNode*>(head);

    //if it's not a variable, throw a syntax error
    if(!varNode) {
      throw ParseSyntaxError(firstPlus->line+1, head->endLine, getCodeLineBlock(firstPlus->line, head->endLine-1), "Prefix operator expects variable argument");
    }

    ParseDataType type = varNode->evalType;
    ParseOperatorType op = (firstPlus->type == ADD) ? PREFIX_INC_OP : PREFIX_DEC_OP;

    //if it's not a number, throw a type error
    if(!typecheckUnaryExpression(op, type)) {
      throw StaticTypeError(firstPlus->line+1, head->endLine, getCodeLineBlock(firstPlus->line, head->endLine-1), (op == PREFIX_INC_OP) ? "prefix increment" : "prefix decrement", type);
    }

    return new UnaryOperatorNode(op, varNode, symbolTable, firstPlus->line+1);

  } else if(isSignNotTokenType(peek()->type)) {

    Token* signNotToken = consume();
    ParseOperatorType op = unaryTokenConversion(signNotToken->type);
    AbstractExpressionNode* next = evalPrefixCastSignNot();

    if(typecheckUnaryExpression(op, next->evalType)) {
      return new UnaryOperatorNode(op, next, signNotToken->line+1);
    } else {
      //if type mismatch, throw error
      throw StaticTypeError(signNotToken->line+1, next->endLine+1, getCodeLineBlock(signNotToken->line, next->endLine), toWordParseOperatorType(op), next->evalType);
    }

  } else if(isCastStructure()) {   
    
    Token* leftParenToken = consume(); //consume (
		Token* typeToken = consume();
    ParseDataType finalType = typeTokenConversion(typeToken->type);
    Token* rightParenToken = consume(); //consume ')'

		//if there is no closing ')', throw error
		if(rightParenToken->type != RIGHT_PAREN) {

			uint32_t startLine = leftParenToken->line+1;
			uint32_t endLine = (rightParenToken->type == END) ? typeToken->line+1 : rightParenToken->line+1;

			if(rightParenToken->type == END) {
				throw ParseSyntaxError(startLine, endLine, getCodeLineBlock(startLine-1, endLine-1), "Expected ')' to end cast operation");
			} else {
				throw ParseSyntaxError(startLine, endLine, getCodeLineBlock(startLine-1, endLine-1), rightParenToken->lexeme, "Expected ')' to end cast operation");
			}
		}
    
    AbstractExpressionNode* next = evalPrefixCastSignNot();
    if(typecheckExplicitCastExpression(next->evalType, finalType)) {
      return new CastNode(next, finalType, leftParenToken->line+1);
    } else {
      throw StaticCastError(leftParenToken->line+1, next->endLine, getCodeLineBlock(leftParenToken->line, next->endLine-1), next->evalType, finalType, true);
    }
    
  } else {

    return evalPostfixMemberAccess();  
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
callq 0x191ed
testb %al, %al
je 0x192d8
callq 0x154a8
movq %rax, %rbx
callq 0x154a8
callq 0x18f12
leaq 0x118c6(%rip), %rsi     # 0x2ab28
leaq 0x1185f(%rip), %rdx     # 0x2aac8
movq %rax, -0x30(%rbp)
movq %rax, %rdi
xorl %ecx, %ecx
callq 0x4200
testq %rax, %rax
je 0x193c8
movq %rax, %r12
movl 0x10(%rax), %r15d
movl (%rbx), %r14d
xorl %r13d, %r13d
cmpl $0x7, %r14d
sete %r13b
xorl $0x3, %r13d
movl %r13d, %edi
movl %r15d, %esi
callq 0x13f5c
testb %al, %al
je 0x1942b
pushq $0x30
popq %rdi
callq 0x41f0
movq %rax, %r14
movq 0x11fba(%rip), %rcx     # 0x2b278
movl 0x10(%rbx), %r8d
incl %r8d
movq %rax, %rdi
movl %r13d, %esi
movq %r12, %rdx
callq 0x7a02
jmp 0x193a3
callq 0x154d4
movl (%rax), %edi
callq 0x5a6a
testb %al, %al
je 0x19337
callq 0x154a8
movq %rax, %r12
movl (%rax), %edi
callq 0x72d9
movl %eax, %r15d
callq 0x1922b
movq %rax, %rbx
movl 0x10(%rax), %esi
movl %r15d, %edi
callq 0x13f5c
testb %al, %al
je 0x194b2
pushq $0x30
popq %rdi
callq 0x41f0
movq %rax, %r14
movl 0x10(%r12), %ecx
incl %ecx
movq %rax, %rdi
movl %r15d, %esi
movq %rbx, %rdx
callq 0x79aa
jmp 0x193a3
callq 0x191b8
testb %al, %al
je 0x193b5
callq 0x154a8
movq %rax, %r15
callq 0x154a8
movq %rax, %r14
movl (%rax), %edi
callq 0x72b8
movl %eax, %ebx
callq 0x154a8
movl (%rax), %r13d
cmpl $0x1, %r13d
jne 0x19523
callq 0x1922b
movq %rax, %r12
movl 0x10(%rax), %edi
movl %ebx, %esi
callq 0x13f12
testb %al, %al
je 0x1957e
pushq $0x28
popq %rdi
callq 0x41f0
movq %rax, %r14
movl 0x10(%r15), %ecx
incl %ecx
movq %rax, %rdi
movq %r12, %rsi
movl %ebx, %edx
callq 0x7d18
movq %r14, %rax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x18f12
pushq $0x28
popq %rdi
callq 0x4110
movq %rax, %r14
movl 0x10(%rbx), %ebx
movq -0x30(%rbp), %rax
movl 0xc(%rax), %r15d
leal -0x1(%r15), %esi
movl %ebx, %edi
callq 0x15504
incl %ebx
leaq 0x111de(%rip), %rcx     # 0x2a5d0
addq $0x10, %rcx
movq %rcx, (%r14)
movq %rax, 0x8(%r14)
andq $0x0, 0x10(%r14)
leaq 0x7fba(%rip), %rax      # 0x213c3
movq %rax, 0x18(%r14)
movl %ebx, 0x20(%r14)
movl %r15d, 0x24(%r14)
leaq 0x111dc(%rip), %rsi     # 0x2a5f8
movq 0x11bb5(%rip), %rdx     # 0x2afd8
movq %r14, %rdi
callq 0x4310
movl %r15d, %r13d
pushq $0x38
popq %rdi
callq 0x4110
movq %rax, %r12
movl 0x10(%rbx), %ebx
movq -0x30(%rbp), %rax
movl 0xc(%rax), %r15d
leal -0x1(%r15), %esi
movl %ebx, %edi
callq 0x15504
incl %ebx
cmpl $0x7, %r14d
leaq 0x399a(%rip), %rcx      # 0x1cdf6
leaq 0x39a4(%rip), %rdx      # 0x1ce07
cmoveq %rcx, %rdx
leaq 0x111a2(%rip), %rcx     # 0x2a610
addq $0x10, %rcx
movq %rcx, (%r12)
andw $0x0, 0x8(%r12)
movq %rax, 0x10(%r12)
movq %rdx, 0x18(%r12)
andq $0x0, 0x20(%r12)
movl %ebx, 0x28(%r12)
movl %r15d, 0x2c(%r12)
movl %r13d, 0x30(%r12)
leaq 0x11195(%rip), %rsi     # 0x2a638
movq 0x11b2e(%rip), %rdx     # 0x2afd8
movq %r12, %rdi
callq 0x4310
pushq $0x38
popq %rdi
callq 0x4110
movq %rax, %r14
movl 0x10(%r12), %r13d
movl 0xc(%rbx), %r12d
movl %r13d, %edi
movl %r12d, %esi
callq 0x15504
movq %rax, -0x30(%rbp)
movl %r15d, %edi
callq 0x7359
incl %r12d
movl 0x10(%rbx), %ecx
leaq 0x11126(%rip), %rdx     # 0x2a610
addq $0x10, %rdx
movq %rdx, (%r14)
andw $0x0, 0x8(%r14)
movq -0x30(%rbp), %rdx
movq %rdx, 0x10(%r14)
movq %rax, 0x18(%r14)
andq $0x0, 0x20(%r14)
incl %r13d
movl %r13d, 0x28(%r14)
movl %r12d, 0x2c(%r14)
movl %ecx, 0x30(%r14)
leaq 0x1111a(%rip), %rsi     # 0x2a638
jmp 0x1941c
movq %rax, %r12
movl 0x10(%r15), %ebx
leal 0x1(%rbx), %eax
movl %eax, -0x30(%rbp)
cmpl $0x4e, %r13d
cmovneq %r12, %r14
movl 0x10(%r14), %r15d
leal 0x1(%r15), %eax
movl %eax, -0x34(%rbp)
pushq $0x28
popq %rdi
callq 0x4110
movq %rax, %r14
cmpl $0x4e, %r13d
jne 0x195de
movl %ebx, %edi
movl %r15d, %esi
callq 0x15504
leaq 0x11067(%rip), %rcx     # 0x2a5d0
addq $0x10, %rcx
movq %rcx, (%r14)
movq %rax, 0x8(%r14)
andq $0x0, 0x10(%r14)
jmp 0x19603
pushq $0x30
popq %rdi
callq 0x4110
movq %rax, %r14
movl 0x10(%r15), %r15d
movl 0xc(%r12), %r13d
leal -0x1(%r13), %esi
movl %r15d, %edi
callq 0x15504
movl 0x10(%r12), %ecx
leaq 0x110e6(%rip), %rdx     # 0x2a690
addq $0x10, %rdx
movq %rdx, (%r14)
movl %ecx, 0x8(%r14)
movl %ebx, 0xc(%r14)
movq %rax, 0x10(%r14)
andq $0x0, 0x18(%r14)
incl %r15d
movb $0x1, 0x20(%r14)
movl %r15d, 0x24(%r14)
movl %r13d, 0x28(%r14)
leaq 0x110df(%rip), %rsi     # 0x2a6b8
jmp 0x1941c
movl %ebx, %edi
movl %r15d, %esi
callq 0x15504
movq 0x18(%r12), %rcx
leaq 0x10fdc(%rip), %rdx     # 0x2a5d0
addq $0x10, %rdx
movq %rdx, (%r14)
movq %rax, 0x8(%r14)
movq %rcx, 0x10(%r14)
leaq 0x7de3(%rip), %rax      # 0x213ed
movq %rax, 0x18(%r14)
movl -0x30(%rbp), %eax
movl %eax, 0x20(%r14)
movl -0x34(%rbp), %eax
movl %eax, 0x24(%r14)
jmp 0x19415
jmp 0x19635
jmp 0x19635
jmp 0x19635
jmp 0x19642
jmp 0x19635
movq %rax, %rbx
movq %r12, %rdi
jmp 0x1963b
jmp 0x19642
movq %rax, %rbx
movq %r14, %rdi
callq 0x4180
jmp 0x1964d
movq %rax, %rbx
movq %r14, %rdi
callq 0x41d0
movq %rbx, %rdi
callq 0x4340