// File: /workspace/github_cpp_makefile_star2_O1/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 0x1bc5f
testb %al, %al
je 0x1bd50
callq 0x1789c
movq %rax, %rbx
callq 0x1789c
callq 0x1b929
leaq 0xfe50(%rip), %rsi      # 0x2bb28
leaq 0xfde9(%rip), %rdx      # 0x2bac8
movq %rax, -0x30(%rbp)
movq %rax, %rdi
xorl %ecx, %ecx
callq 0x4230
testq %rax, %rax
je 0x1be44
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 0x16118
testb %al, %al
je 0x1beac
movl $0x30, %edi
callq 0x4210
movq %rax, %r14
movq 0x1055a(%rip), %rcx     # 0x2c290
movl 0x10(%rbx), %r8d
incl %r8d
movq %rax, %rdi
movl %r13d, %esi
movq %r12, %rdx
callq 0x8cbe
jmp 0x1be1f
callq 0x178eb
movl (%rax), %edi
callq 0x63cb
testb %al, %al
je 0x1bdb1
callq 0x1789c
movq %rax, %r12
movl (%rax), %edi
callq 0x8275
movl %eax, %r15d
callq 0x1bca1
movq %rax, %rbx
movl 0x10(%rax), %esi
movl %r15d, %edi
callq 0x16118
testb %al, %al
je 0x1bf39
movl $0x30, %edi
callq 0x4210
movq %rax, %r14
movl 0x10(%r12), %ecx
incl %ecx
movq %rax, %rdi
movl %r15d, %esi
movq %rbx, %rdx
callq 0x8c66
jmp 0x1be1f
callq 0x1bc26
testb %al, %al
je 0x1be31
callq 0x1789c
movq %rax, %r15
callq 0x1789c
movq %rax, %r14
movl (%rax), %edi
callq 0x8256
movl %eax, %ebx
callq 0x1789c
movl (%rax), %r13d
cmpl $0x1, %r13d
jne 0x1bfb0
callq 0x1bca1
movq %rax, %r12
movl 0x10(%rax), %edi
movl %ebx, %esi
callq 0x160ce
testb %al, %al
je 0x1c010
movl $0x28, %edi
callq 0x4210
movq %rax, %r14
movl 0x10(%r15), %ecx
incl %ecx
movq %rax, %rdi
movq %r12, %rsi
movl %ebx, %edx
callq 0x903e
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 0x1b929
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 0x17961
incl %ebx
leaq 0xf760(%rip), %rcx      # 0x2b5d0
addq $0x10, %rcx
movq %rcx, (%r14)
movq %rax, 0x8(%r14)
movq $0x0, 0x10(%r14)
leaq 0x7545(%rip), %rax      # 0x233cf
movq %rax, 0x18(%r14)
movl %ebx, 0x20(%r14)
movl %r15d, 0x24(%r14)
leaq 0xf75b(%rip), %rsi      # 0x2b5f8
movq 0x10134(%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 0x17961
incl %ebx
cmpl $0x7, %r14d
leaq 0x2f57(%rip), %rcx      # 0x1ee36
leaq 0x2f61(%rip), %rdx      # 0x1ee47
cmoveq %rcx, %rdx
leaq 0xf71f(%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 0xf70e(%rip), %rsi      # 0x2b638
movq 0x100a7(%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 0x17961
movq %rax, -0x30(%rbp)
movl %r15d, %edi
callq 0x82f3
incl %r12d
incl %r13d
movl 0x10(%rbx), %ecx
leaq 0xf69a(%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 0xf68d(%rip), %rsi      # 0x2b638
jmp 0x1be9d
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 0x1c075
movl %ebx, %edi
movl %r15d, %esi
callq 0x17961
leaq 0xf5d8(%rip), %rcx      # 0x2b5d0
addq $0x10, %rcx
movq %rcx, (%r14)
movq %rax, 0x8(%r14)
movq $0x0, 0x10(%r14)
jmp 0x1c09a
movl $0x30, %edi
callq 0x4110
movq %rax, %r14
movl 0x10(%r15), %r15d
movl 0xc(%r12), %r13d
leal -0x1(%r13), %esi
movl %r15d, %edi
callq 0x17961
incl %r15d
movl 0x10(%r12), %ecx
leaq 0xf64f(%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 0xf648(%rip), %rsi      # 0x2b6b8
jmp 0x1be9d
movl %ebx, %edi
movl %r15d, %esi
callq 0x17961
movq 0x18(%r12), %rcx
leaq 0xf545(%rip), %rdx      # 0x2b5d0
addq $0x10, %rdx
movq %rdx, (%r14)
movq %rax, 0x8(%r14)
movq %rcx, 0x10(%r14)
leaq 0x7358(%rip), %rax      # 0x233f9
movq %rax, 0x18(%r14)
movl -0x30(%rbp), %eax
movl %eax, 0x20(%r14)
movl -0x34(%rbp), %eax
movl %eax, 0x24(%r14)
jmp 0x1be96
jmp 0x1c0cc
jmp 0x1c0cc
jmp 0x1c0cc
jmp 0x1c0d9
jmp 0x1c0cc
movq %rax, %rbx
movq %r12, %rdi
jmp 0x1c0d2
jmp 0x1c0d9
movq %rax, %rbx
movq %r14, %rdi
callq 0x4190
jmp 0x1c0e4
movq %rax, %rbx
movq %r14, %rdi
callq 0x41e0
movq %rbx, %rdi
callq 0x4380