// File: /workspace/github_c_makefile_star2_O1/MartinNovotny25[P]VUT-FIT-IFJ2020/semantics.c
// Function: if_control
void if_control(TDLList *L, tBSTNodePtrLocal *node, functionData params){

    if(!(strcmp(L->Act->tdata.lex, "("))){
        TDLLSucc(L);
    }
    // Ak su oba identifikatory
    if(L->Act->tdata.type == t_IDENTIFIER && L->Act->rptr->rptr->tdata.type == t_IDENTIFIER){
        int typ1;
        int typ2;
        // je prvy v strome?
        if(MainStackSearch(mainstack, L->Act->tdata.lex, &typ1)){
            if(!(strcmp(L->Act->tdata.lex, "_"))){
                error_call(ERR_SEM_EXCOMPAT, L);
                BSTDisposeLocal(node);
            }

        }else{
             error_call(ERR_SEM_UNDEF, L);
             BSTDisposeLocal(node);
        }
        
        
        if(MainStackSearch(mainstack, L->Act->rptr->rptr->tdata.lex, &typ2)){
            if(!(strcmp(L->Act->rptr->rptr->tdata.lex, "_"))){
                error_call(ERR_SEM_EXCOMPAT, L);
                BSTDisposeLocal(node);
            }

        }else{
            error_call(ERR_SEM_UNDEF, L);
            BSTDisposeLocal(node);
        }

        // Maju rovnake typy?
        if(!(typ1 == typ2)){
            error_call(ERR_SEM_EXCOMPAT, L);
            BSTDisposeLocal(node);
        }

    // ak je lavy operator identifikator
    }else if(L->Act->tdata.type == t_IDENTIFIER && L->Act->rptr->rptr->tdata.type != t_IDENTIFIER){
        int typ1;
        int typ2;
        // Je prvy id v strome?
        if(MainStackSearch(mainstack, L->Act->tdata.lex, &typ1)){
            if(!(strcmp(L->Act->tdata.lex, "_"))){
                error_call(ERR_SEM_EXCOMPAT, L);
                BSTDisposeLocal(node);
            }

        }else{
            error_call(ERR_SEM_UNDEF, L);
            BSTDisposeLocal(node);
        }
    
        // Ma id rovnaky typ ako cislo?
        if(L->Act->rptr->rptr->tdata.type == t_INT_NON_ZERO || L->Act->rptr->rptr->tdata.type == t_INT_ZERO){
            typ2 = t_INT_ID;
            if(!(typ1 == typ2)){
                error_call(ERR_SEM_EXCOMPAT, L);
                BSTDisposeLocal(node);
            }
        // ma id rovnaky typ ako float?
        }else if(L->Act->rptr->rptr->tdata.type == t_FLOAT64 || L->Act->rptr->rptr->tdata.type == t_FLOAT){
            typ2 = t_FLOAT64;
            if(!(typ1 == typ2)){
                error_call(ERR_SEM_EXCOMPAT, L);
                BSTDisposeLocal(node);
            }
        // ma id rovnaky typ ako string?
        }else if(L->Act->rptr->rptr->tdata.type == t_STRING){
            typ2 = t_STRING_ID;
            if(!(typ1 == typ2)){
                error_call(ERR_SEM_EXCOMPAT, L);
                BSTDisposeLocal(node);
            }
        }
        
    // ak je pravy operator identifikator
    }else if(L->Act->tdata.type != t_IDENTIFIER && L->Act->rptr->rptr->tdata.type == t_IDENTIFIER){
        int typ1;
        int typ2;
        // Je v strome?
        if(MainStackSearch(mainstack, L->Act->rptr->rptr->tdata.lex, &typ2)){
            if(!(strcmp(L->Act->rptr->rptr->tdata.lex, "_"))){
                error_call(ERR_SEM_EXCOMPAT, L);
                
                BSTDisposeLocal(node);
            }
        }else{
            error_call(ERR_SEM_UNDEF, L);
            BSTDisposeLocal(node);
        }

        // Ma id rovnaky typ ako cislo?
        if(L->Act->tdata.type == t_INT_NON_ZERO || L->Act->tdata.type == t_INT_ZERO){
            typ1 = t_INT_ID;
            if(!(typ1 == typ2)){
                 error_call(ERR_SEM_EXCOMPAT, L);
                   BSTDisposeLocal(node);
            }

        // ma id rovnaky typ ako float?
        }else if(L->Act->tdata.type == t_FLOAT64 || L->Act->tdata.type == t_FLOAT){
            typ1 = t_FLOAT64;
            if(!(typ1 == typ2)){
                   error_call(ERR_SEM_EXCOMPAT, L);
                   BSTDisposeLocal(node);
            }

        // ma id rovnaky typ ako string?
        }else if(L->Act->tdata.type == t_STRING){
            typ1 = t_STRING_ID;
            if(!(typ1 == typ2)){
                   error_call(ERR_SEM_EXCOMPAT, L);
                   BSTDisposeLocal(node);
            }
        }

    // Ak ani jeden nie je identifikator
    }else{
        // Ak ide o integre maju rovnake typy?
        if(L->Act->tdata.type == t_INT_ZERO || L->Act->tdata.type == t_INT_NON_ZERO){
            int typson1 = t_INT_ID;
            if(L->Act->rptr->rptr->tdata.type == t_INT_NON_ZERO || L->Act->rptr->rptr->tdata.type == t_INT_ZERO){
                int typson2 = t_INT_ID;
                if(typson1 != typson2){
                    error_call(ERR_SEM_EXCOMPAT, L);
                   BSTDisposeLocal(node);
                }

            }else{
                error_call(ERR_SEM_EXCOMPAT, L);
                BSTDisposeLocal(node);
            }
        // Ak ide o floaty maju rovnake typy?
        }else if(L->Act->tdata.type == t_FLOAT64 || L->Act->tdata.type == t_FLOAT){
            int typson1 = t_FLOAT64;
            if(L->Act->rptr->rptr->tdata.type == t_FLOAT64 || L->Act->rptr->rptr->tdata.type == t_FLOAT){
                int typson2 = t_FLOAT64;
                if(typson1 != typson2){
                    error_call(ERR_SEM_EXCOMPAT, L);
                    BSTDisposeLocal(node);
                }

            }else{
                error_call(ERR_SEM_EXCOMPAT, L);
                BSTDisposeLocal(node);
            }
        // Ak ide o stringy maju rovnake typy?
        }if(L->Act->tdata.type == t_STRING){
            int typson1 = t_STRING_ID;
            if(L->Act->rptr->rptr->tdata.type == t_STRING){
                int typson2 = t_STRING_ID;
                if(typson1 != typson2){
                    error_call(ERR_SEM_EXCOMPAT, L);
                    BSTDisposeLocal(node);
                }

            }else{
                error_call(ERR_SEM_EXCOMPAT, L);
                BSTDisposeLocal(node);
            }
        }
    }

    TDLLSucc(L);
    int real_op = 0;
   

        
    while(L->Act->tdata.type != t_BRACES_L){
        if(L->Act->tdata.type == T_SEMICOLON){
            break;
        }
        if(L->Act->tdata.type == t_GREATER){
            real_op++;
        }else if(L->Act->tdata.type == t_GREATEROREQUAL){
            real_op++;
        }else if(L->Act->tdata.type == t_LESS){
            real_op++;
        }else if(L->Act->tdata.type == t_LESSOREQUAL){
            real_op++;
        }else if(L->Act->tdata.type == t_EQUAL){
            real_op++;
        }else if(L->Act->tdata.type == t_NOT_EQUAL){
            real_op++;
        }else {
            if(L->Act->tdata.type == t_PLUS){
                error_call(ERR_SEM_EXCOMPAT, L);
                BSTDisposeLocal(node);
            }
             
            if(L->Act->tdata.type == t_MINUS){
                error_call(ERR_SEM_EXCOMPAT, L);
                BSTDisposeLocal(node);
            }
                
            if(L->Act->tdata.type == t_MULTIPLY){
                error_call(ERR_SEM_EXCOMPAT, L);
                BSTDisposeLocal(node);
            }
              
            if(L->Act->tdata.type == t_DIVIDE){
                error_call(ERR_SEM_EXCOMPAT, L);
                BSTDisposeLocal(node);
            }
               
        }

        TDLLSucc(L);
    }
     
    if(real_op != 1){
        error_call(ERR_SEM_EXCOMPAT, L);
        BSTDisposeLocal(node);
    }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
subq $0x1f58, %rsp           # imm = 0x1F58
movq %rsi, %rbx
movq %rdi, %r14
movq 0x8(%rdi), %rax
movq (%rax), %rdi
leaq 0x33d7(%rip), %rsi      # 0x8529
callq 0x1080
testl %eax, %eax
jne 0x5163
movq %r14, %rdi
callq 0x1695
movq 0x8(%r14), %rax
movl 0x8(%rax), %ecx
cmpl $0x13, %ecx
jne 0x5286
movq 0x18(%rax), %rdx
movq 0x18(%rdx), %rdx
cmpl $0x13, 0x8(%rdx)
jne 0x5266
movq (%rax), %rax
leaq 0x72f9(%rip), %rsi      # 0xc488
movl $0x3e9, %ecx            # imm = 0x3E9
movq %rsp, %rdi
rep  movsq (%rsi), %es:(%rdi)
leaq 0x1f50(%rsp), %rsi
movq %rax, %rdi
callq 0x471e
movl $0x3, %edi
testb %al, %al
je 0x51cf
movq 0x8(%r14), %rax
movq (%rax), %rdi
leaq 0x3357(%rip), %rsi      # 0x8518
callq 0x1080
testl %eax, %eax
jne 0x51df
movl $0x5, %edi
movq %r14, %rsi
callq 0x42c8
movq %rbx, %rdi
callq 0x46ab
movq 0x8(%r14), %rax
movq 0x18(%rax), %rax
movq 0x18(%rax), %rax
movq (%rax), %rax
leaq 0x7293(%rip), %rsi      # 0xc488
movl $0x3e9, %ecx            # imm = 0x3E9
movq %rsp, %rdi
rep  movsq (%rsi), %es:(%rdi)
leaq 0x1f54(%rsp), %rsi
movq %rax, %rdi
callq 0x471e
movl $0x3, %edi
testb %al, %al
je 0x523d
movq 0x8(%r14), %rax
movq 0x18(%rax), %rax
movq 0x18(%rax), %rax
movq (%rax), %rdi
leaq 0x32e9(%rip), %rsi      # 0x8518
callq 0x1080
testl %eax, %eax
jne 0x524d
movl $0x5, %edi
movq %r14, %rsi
callq 0x42c8
movq %rbx, %rdi
callq 0x46ab
movl 0x1f50(%rsp), %eax
cmpl 0x1f54(%rsp), %eax
jne 0x53b5
jmp 0x53ca
cmpl $0x13, %ecx
jne 0x5286
movq 0x18(%rax), %rdx
movq 0x18(%rdx), %rdx
cmpl $0x13, 0x8(%rdx)
jne 0x54ba
cmpl $0x13, %ecx
je 0x5325
movq 0x18(%rax), %rdx
movq 0x18(%rdx), %rdx
cmpl $0x13, 0x8(%rdx)
jne 0x5325
movq (%rdx), %rax
leaq 0x71e6(%rip), %rsi      # 0xc488
movl $0x3e9, %ecx            # imm = 0x3E9
movq %rsp, %rdi
rep  movsq (%rsi), %es:(%rdi)
leaq 0x1f50(%rsp), %rsi
movq %rax, %rdi
callq 0x471e
movl $0x3, %edi
testb %al, %al
je 0x52ea
movq 0x8(%r14), %rax
movq 0x18(%rax), %rax
movq 0x18(%rax), %rax
movq (%rax), %rdi
leaq 0x323c(%rip), %rsi      # 0x8518
callq 0x1080
testl %eax, %eax
jne 0x52fa
movl $0x5, %edi
movq %r14, %rsi
callq 0x42c8
movq %rbx, %rdi
callq 0x46ab
movq 0x8(%r14), %rax
movl 0x8(%rax), %eax
cmpl $0x28, %eax
jg 0x534e
leal -0x10(%rax), %ecx
cmpl $0x2, %ecx
jae 0x53a6
cmpl $0x18, 0x1f50(%rsp)
jne 0x53b5
jmp 0x53ca
leal -0x10(%rcx), %edx
cmpl $0x2, %edx
jb 0x5364
cmpl $0x17, %ecx
je 0x5337
cmpl $0x29, %ecx
jne 0x538c
movq 0x18(%rax), %rax
movq 0x18(%rax), %rax
movl 0x8(%rax), %eax
cmpl $0x17, %eax
je 0x538c
cmpl $0x29, %eax
je 0x538c
jmp 0x5377
cmpl $0x29, %eax
je 0x53ab
cmpl $0x2b, %eax
jne 0x53ca
cmpl $0x14, 0x1f50(%rsp)
jne 0x53b5
jmp 0x53ca
movq 0x18(%rax), %rax
movq 0x18(%rax), %rax
movl 0x8(%rax), %eax
andl $-0x2, %eax
cmpl $0x10, %eax
je 0x538c
movl $0x5, %edi
movq %r14, %rsi
callq 0x42c8
movq %rbx, %rdi
callq 0x46ab
movq 0x8(%r14), %rax
cmpl $0x2b, 0x8(%rax)
jne 0x53ca
movq 0x18(%rax), %rax
movq 0x18(%rax), %rax
cmpl $0x2b, 0x8(%rax)
jne 0x53b5
jmp 0x53ca
cmpl $0x17, %eax
jne 0x53ca
cmpl $0x17, 0x1f50(%rsp)
je 0x53ca
movl $0x5, %edi
movq %r14, %rsi
callq 0x42c8
movq %rbx, %rdi
callq 0x46ab
xorl %ebp, %ebp
leaq 0x30bd(%rip), %r15      # 0x8490
movq %r14, %rdi
callq 0x1695
movq 0x8(%r14), %rax
movl 0x8(%rax), %eax
cmpl $0x1d, %eax
jle 0x53fc
leal -0x1e(%rax), %ecx
cmpl $0x3, %ecx
ja 0x5422
movslq (%r15,%rcx,4), %rax
addq %r15, %rax
jmpq *%rax
incl %ebp
jmp 0x53d3
cmpl $0x1, %eax
je 0x53f8
cmpl $0x2, %eax
je 0x53f8
cmpl $0xa, %eax
jne 0x542c
movl $0x5, %edi
movq %r14, %rsi
callq 0x42c8
movq %rbx, %rdi
callq 0x46ab
jmp 0x542c
cmpl $0x34, %eax
je 0x5492
cmpl $0x38, %eax
je 0x5492
movq 0x8(%r14), %rax
cmpl $0xb, 0x8(%rax)
jne 0x544b
movl $0x5, %edi
movq %r14, %rsi
callq 0x42c8
movq %rbx, %rdi
callq 0x46ab
movq 0x8(%r14), %rax
cmpl $0x9, 0x8(%rax)
jne 0x546a
movl $0x5, %edi
movq %r14, %rsi
callq 0x42c8
movq %rbx, %rdi
callq 0x46ab
movq 0x8(%r14), %rax
cmpl $0x8, 0x8(%rax)
jne 0x53d3
movl $0x5, %edi
movq %r14, %rsi
callq 0x42c8
movq %rbx, %rdi
callq 0x46ab
jmp 0x53d3
cmpl $0x1, %ebp
je 0x54ac
movl $0x5, %edi
movq %r14, %rsi
callq 0x42c8
movq %rbx, %rdi
callq 0x46ab
addq $0x1f58, %rsp           # imm = 0x1F58
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
movq (%rax), %rax
leaq 0x6fc4(%rip), %rsi      # 0xc488
movl $0x3e9, %ecx            # imm = 0x3E9
movq %rsp, %rdi
rep  movsq (%rsi), %es:(%rdi)
leaq 0x1f50(%rsp), %rsi
movq %rax, %rdi
callq 0x471e
movl $0x3, %edi
testb %al, %al
je 0x5504
movq 0x8(%r14), %rax
movq (%rax), %rdi
leaq 0x3022(%rip), %rsi      # 0x8518
callq 0x1080
testl %eax, %eax
jne 0x5514
movl $0x5, %edi
movq %r14, %rsi
callq 0x42c8
movq %rbx, %rdi
callq 0x46ab
movq 0x8(%r14), %rax
movq 0x18(%rax), %rax
movq 0x18(%rax), %rax
jmp 0x52fe