// File: /workspace/github_cpp_makefile_star2_O3/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 0x1bc22
testb %al, %al
je 0x1bd13
callq 0x177cc
movq %rax, %rbx
callq 0x177cc
callq 0x1b8ef
leaq 0xfe8d(%rip), %rsi      # 0x2bb28
leaq 0xfe26(%rip), %rdx      # 0x2bac8
movq %rax, -0x30(%rbp)
movq %rax, %rdi
xorl %ecx, %ecx
callq 0x4230
testq %rax, %rax
je 0x1be07
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 0x16090
testb %al, %al
je 0x1be6f
movl $0x30, %edi
callq 0x4210
movq %rax, %r14
movq 0x10597(%rip), %rcx     # 0x2c290
movl 0x10(%rbx), %r8d
incl %r8d
movq %rax, %rdi
movl %r13d, %esi
movq %r12, %rdx
callq 0x8b7a
jmp 0x1bde2
callq 0x1781b
movl (%rax), %edi
callq 0x6399
testb %al, %al
je 0x1bd74
callq 0x177cc
movq %rax, %r12
movl (%rax), %edi
callq 0x8149
movl %eax, %r15d
callq 0x1bc64
movq %rax, %rbx
movl 0x10(%rax), %esi
movl %r15d, %edi
callq 0x16090
testb %al, %al
je 0x1befc
movl $0x30, %edi
callq 0x4210
movq %rax, %r14
movl 0x10(%r12), %ecx
incl %ecx
movq %rax, %rdi
movl %r15d, %esi
movq %rbx, %rdx
callq 0x8b22
jmp 0x1bde2
callq 0x1bbe9
testb %al, %al
je 0x1bdf4
callq 0x177cc
movq %rax, %r15
callq 0x177cc
movq %rax, %r14
movl (%rax), %edi
callq 0x812a
movl %eax, %ebx
callq 0x177cc
movl (%rax), %r13d
cmpl $0x1, %r13d
jne 0x1bf73
callq 0x1bc64
movq %rax, %r12
movl 0x10(%rax), %edi
movl %ebx, %esi
callq 0x16046
testb %al, %al
je 0x1bfd3
movl $0x28, %edi
callq 0x4210
movq %rax, %r14
movl 0x10(%r15), %ecx
incl %ecx
movq %rax, %rdi
movq %r12, %rsi
movl %ebx, %edx
callq 0x8efa
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 0x1b8ef
movl $0x28, %edi
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 0x17891
incl %ebx
leaq 0xf79d(%rip), %rcx      # 0x2b5d0
addq $0x10, %rcx
movq %rcx, (%r14)
movq %rax, 0x8(%r14)
movq $0x0, 0x10(%r14)
leaq 0x7576(%rip), %rax      # 0x233c3
movq %rax, 0x18(%r14)
movl %ebx, 0x20(%r14)
movl %r15d, 0x24(%r14)
leaq 0xf798(%rip), %rsi      # 0x2b5f8
movq 0x10171(%rip), %rdx     # 0x2bfd8
movq %r14, %rdi
callq 0x4350
movl %r15d, %r13d
movl $0x38, %edi
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 0x17891
incl %ebx
cmpl $0x7, %r14d
leaq 0x2f74(%rip), %rcx      # 0x1ee16
leaq 0x2f7e(%rip), %rdx      # 0x1ee27
cmoveq %rcx, %rdx
leaq 0xf75c(%rip), %rcx      # 0x2b610
addq $0x10, %rcx
movq %rcx, (%r12)
movw $0x0, 0x8(%r12)
movq %rax, 0x10(%r12)
movq %rdx, 0x18(%r12)
movq $0x0, 0x20(%r12)
movl %ebx, 0x28(%r12)
movl %r15d, 0x2c(%r12)
movl %r13d, 0x30(%r12)
leaq 0xf74b(%rip), %rsi      # 0x2b638
movq 0x100e4(%rip), %rdx     # 0x2bfd8
movq %r12, %rdi
callq 0x4350
movl $0x38, %edi
callq 0x4110
movq %rax, %r14
movl 0x10(%r12), %r13d
movl 0xc(%rbx), %r12d
movl %r13d, %edi
movl %r12d, %esi
callq 0x17891
movq %rax, -0x30(%rbp)
movl %r15d, %edi
callq 0x81c7
incl %r12d
incl %r13d
movl 0x10(%rbx), %ecx
leaq 0xf6d7(%rip), %rdx      # 0x2b610
addq $0x10, %rdx
movq %rdx, (%r14)
movw $0x0, 0x8(%r14)
movq -0x30(%rbp), %rdx
movq %rdx, 0x10(%r14)
movq %rax, 0x18(%r14)
movq $0x0, 0x20(%r14)
movl %r13d, 0x28(%r14)
movl %r12d, 0x2c(%r14)
movl %ecx, 0x30(%r14)
leaq 0xf6ca(%rip), %rsi      # 0x2b638
jmp 0x1be60
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)
movl $0x28, %edi
callq 0x4110
movq %rax, %r14
cmpl $0x4e, %r13d
jne 0x1c038
movl %ebx, %edi
movl %r15d, %esi
callq 0x17891
leaq 0xf615(%rip), %rcx      # 0x2b5d0
addq $0x10, %rcx
movq %rcx, (%r14)
movq %rax, 0x8(%r14)
movq $0x0, 0x10(%r14)
jmp 0x1c05d
movl $0x30, %edi
callq 0x4110
movq %rax, %r14
movl 0x10(%r15), %r15d
movl 0xc(%r12), %r13d
leal -0x1(%r13), %esi
movl %r15d, %edi
callq 0x17891
incl %r15d
movl 0x10(%r12), %ecx
leaq 0xf68c(%rip), %rdx      # 0x2b690
addq $0x10, %rdx
movq %rdx, (%r14)
movl %ecx, 0x8(%r14)
movl %ebx, 0xc(%r14)
movq %rax, 0x10(%r14)
movq $0x0, 0x18(%r14)
movb $0x1, 0x20(%r14)
movl %r15d, 0x24(%r14)
movl %r13d, 0x28(%r14)
leaq 0xf685(%rip), %rsi      # 0x2b6b8
jmp 0x1be60
movl %ebx, %edi
movl %r15d, %esi
callq 0x17891
movq 0x18(%r12), %rcx
leaq 0xf582(%rip), %rdx      # 0x2b5d0
addq $0x10, %rdx
movq %rdx, (%r14)
movq %rax, 0x8(%r14)
movq %rcx, 0x10(%r14)
leaq 0x7389(%rip), %rax      # 0x233ed
movq %rax, 0x18(%r14)
movl -0x30(%rbp), %eax
movl %eax, 0x20(%r14)
movl -0x34(%rbp), %eax
movl %eax, 0x24(%r14)
jmp 0x1be59
jmp 0x1c08f
jmp 0x1c08f
jmp 0x1c08f
jmp 0x1c09c
jmp 0x1c08f
movq %rax, %rbx
movq %r12, %rdi
jmp 0x1c095
jmp 0x1c09c
movq %rax, %rbx
movq %r14, %rdi
callq 0x4190
jmp 0x1c0a7
movq %rax, %rbx
movq %r14, %rdi
callq 0x41e0
movq %rbx, %rdi
callq 0x4380