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

     if(L->Act->rptr->tdata.type == t_EOL){
        error_call(ERR_SEM_OTHER, L);
    }
    // Nazov premennej na deklarovanie
    char *id = L->Act->tdata.lex;
    // Na ulozenie datoveho typu
    int type;
    // Zbytocna premenna
    char *data = "null";

    // pocet stringov
    int string_count = 0;
    // pocet cisel vo vyraze
    int int_count = 0;
    // pocet floatov vo vyraze
    int float_count = 0;
    // pocet identifikatorov
    //int identifier = 0;
    if(L->Act->lptr->tdata.type != t_FOR){
        if(L->Act->lptr->tdata.type != t_EOL) error_call(ERR_SEM_OTHER, L);
    }
    // ak je premenna ktoru chceme definovat uz definovana
    if(BSTSearchLocal(*node, id, &type, data)){
        error_call(ERR_SEM_UNDEF,L);
        BSTDisposeLocal(node);
    }
    // Chod na dalsi prvok teda  ->  :=
    //TDLLSucc(L);
    // Chod na koniec riadku
    while(L->Act->tdata.type != t_EOL){
        if(L->Act->tdata.type == t_GREATER){
            BSTDisposeLocal(node);
            error_call(ERR_SEM_EXCOMPAT, L);
        }else if(L->Act->tdata.type == t_GREATEROREQUAL){
            BSTDisposeLocal(node);
            error_call(ERR_SEM_EXCOMPAT, L);
        }else if(L->Act->tdata.type == t_LESS){
            BSTDisposeLocal(node);
            error_call(ERR_SEM_EXCOMPAT, L);
        }else if(L->Act->tdata.type == t_LESSOREQUAL){
            BSTDisposeLocal(node);
            error_call(ERR_SEM_EXCOMPAT, L);
        }else if(L->Act->tdata.type == t_EQUAL){
            BSTDisposeLocal(node);
            error_call(ERR_SEM_EXCOMPAT, L);
        }else if(L->Act->tdata.type == t_NOT_EQUAL){
            BSTDisposeLocal(node);
            error_call(ERR_SEM_EXCOMPAT, L);
        }

        if(!(strcmp(L->Act->tdata.lex, "/"))){
            if(L->Act->rptr->tdata.type == t_INT_ZERO){
                BSTDisposeLocal(node);
                error_call(ERR_SEM_ZERODIV, L);
            }
        }

        if(!(strcmp(L->Act->tdata.lex, "_"))){
            BSTDisposeLocal(node);
            error_call(ERR_SEM_UNDEF, L);
        }
        
        // Ak ide o integer
        if(L->Act->tdata.type == t_INT_ZERO){
            // Uloz jeho typ
            type = t_INT_ID;
            // Zapocitaj najdenie integeru
            int_count++;

        // Ak ide o float
        }else if(L->Act->tdata.type == t_INT_NON_ZERO){
            type = t_INT_ID;
            // Zapocitaj najdenie integeru
            data = "0";
            int_count++;

        }else if(L->Act->tdata.type == t_FLOAT64 || L->Act->tdata.type == t_FLOAT){

            if(!(strcmp(L->Act->tdata.lex, "0.0"))){
                if(!(strcmp(L->Act->lptr->tdata.lex, "/"))){
                    BSTDisposeLocal(node);
                    error_call(ERR_SEM_ZERODIV, L);
                }
            }
            // Uloz jeho typ
            type = t_FLOAT64;
            // zapocitaj najdenie floatu
            float_count++;

        // Ak ide o string
        }else if(L->Act->tdata.type == t_STRING){
            if(L->Act->rptr->tdata.type == t_MINUS || L->Act->rptr->tdata.type == t_DIVIDE || L->Act->rptr->tdata.type == t_MULTIPLY){
                BSTDisposeLocal(node);
                error_call(ERR_SEM_EXCOMPAT, L);
            }
            // uloz jeho typ
            type = t_STRING_ID;
            // zapocitaj najdenie stringu
            string_count++;

        // Ak ide o identifikator
        }else if(L->Act->tdata.type == t_IDENTIFIER){
            // Premenna na ulozenie typu identifikatoru v strome
            int datovytyp;
            // Nazov najdeneho identifikatoru
            char *name = L->Act->tdata.lex;
            functionData returned_data;

            if(!(strcmp(L->Act->tdata.lex, "_"))){
                BSTDisposeLocal(node);
                error_call(ERR_SEM_UNDEF, L);
            }

            if(!(strcmp(L->Act->tdata.lex, "inputs"))){
                error_call(ERR_SEM_OTHER, L);
                   
            }else if(!(strcmp(L->Act->tdata.lex, "inputi"))){
                error_call(ERR_SEM_OTHER, L);
               
            }else if(!(strcmp(L->Act->tdata.lex, "inputf"))){
                error_call(ERR_SEM_OTHER, L);
                
            }else if(!(strcmp(L->Act->tdata.lex, "int2float"))){
                assign_func_params_control(L,node, "int2float");
                type = t_FLOAT64;
                BSTInsertLocal(node, id,&type, data);
             
            }else if(!(strcmp(L->Act->tdata.lex, "float2int"))){
                assign_func_params_control(L,node, "float2int");
                type = t_INT_ID;
                BSTInsertLocal(node, id,&type, data);
               
            }else if(!(strcmp(L->Act->tdata.lex, "len"))){
                assign_func_params_control(L,node, "len");
                type = t_INT_ID;
                BSTInsertLocal(node, id,&type, data);
             
            }else if(!(strcmp(L->Act->tdata.lex, "substr"))){
                error_call(ERR_SEM_OTHER, L);
             
            }else if(!(strcmp(L->Act->tdata.lex, "ord"))){
                error_call(ERR_SEM_OTHER, L);
 
            }else if(!(strcmp(L->Act->tdata.lex, "chr"))){
                error_call(ERR_SEM_OTHER, L);

            }else if(!(strcmp(L->Act->tdata.lex, "print"))){
                error_call(ERR_SEM_EXCOMPAT, L);

            }else if(BSTSearchGlobal(functions, L->Act->tdata.lex, &returned_data)){
                if(L->Act->rptr->tdata.type == t_LEFT_BRACKET){
                    checkCallFunction(L, L->Act->tdata.lex, node);
                
                    if(returned_data.numOfReturns != 1) error_call(ERR_SEM_RETURN, L);
                    else{
                        type = returned_data.returns[0];
                        BSTInsertLocal(node, id,&type, data);
                    }
                }
            }else if (MainStackSearch(mainstack, name, &datovytyp)) {
                    type = datovytyp;
                if(datovytyp == t_INT_ID){
                    int_count++;
                }else if(datovytyp == t_STRING_ID){
                    if(L->Act->rptr->tdata.type == t_MINUS || L->Act->rptr->tdata.type == t_DIVIDE || L->Act->rptr->tdata.type == t_MULTIPLY){
                    BSTDisposeLocal(node);
                    error_call(ERR_SEM_EXCOMPAT, L);
                    }
                    string_count++;
                }else if(datovytyp == t_FLOAT64){
                    float_count++;
                }
            }
        }
        // Ak prideme vo vyraze na bodkociarku zastav, kvoli kontrole deklaracie vo for-e
        if(L->Act->tdata.type == T_SEMICOLON) break;
        // Ak najdes ciarku tzv, chce sa deklarovat viac premennych naraz chyba
        if(L->Act->tdata.type == t_COMMA){
            error_call(ERR_SEM_OTHER, L);
        }
        TDLLSucc(L);
    }

    // Ak boli na priradenie iba string
    if(string_count != 0 && int_count == 0 && float_count == 0){
        // Uloz uzol so stringom do stromu
        BSTInsertLocal(node, id,&type, data);

    // ak boli na priradenie vo vyraze iba integre
    }else if(string_count == 0 && int_count != 0 && float_count == 0){
        // uloz uzol s integerom do stromu
        BSTInsertLocal(node, id, &type, data);

    // ak boli na priradenie vo vyraze iba floaty
    }else if(string_count == 0 && int_count == 0 && float_count != 0){
        // tak uloz uzol s typom float do stromu
        BSTInsertLocal(node, id, &type, data);
    }else{
        error_call(ERR_SEM_DATATYPE, L);
    }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x2f88, %rsp           # imm = 0x2F88
movq %rsi, %rbx
movq %rdi, %r14
movq 0x8(%rdi), %rax
movq 0x18(%rax), %rcx
cmpl $0x2f, 0x8(%rcx)
jne 0x57a4
pushq $0x7
popq %rdi
movq %r14, %rsi
callq 0x3ac4
movq 0x8(%r14), %rax
movq (%rax), %rcx
movq %rcx, 0x1f60(%rsp)
movq 0x10(%rax), %rax
movl 0x8(%rax), %eax
cmpl $0x1a, %eax
je 0x57cb
cmpl $0x2f, %eax
je 0x57cb
pushq $0x7
popq %rdi
movq %r14, %rsi
callq 0x3ac4
movq (%rbx), %rdi
leaq 0x2d55(%rip), %rcx      # 0x852a
leaq 0x1f50(%rsp), %rdx
movq 0x1f60(%rsp), %rsi
movq %rcx, 0x1f68(%rsp)
callq 0x3cd1
testb %al, %al
je 0x5809
pushq $0x3
popq %rdi
movq %r14, %rsi
callq 0x3ac4
movq %rbx, %rdi
callq 0x3e46
movq %rbx, 0x1f58(%rsp)
movl $0x0, 0x1f74(%rsp)
leaq 0x2d25(%rip), %r13      # 0x8548
leaq 0x2d28(%rip), %rbx      # 0x8552
leaq 0x2d2b(%rip), %rbp      # 0x855c
xorl %r12d, %r12d
movl $0x0, 0x1f78(%rsp)
movq 0x8(%r14), %rax
movl 0x8(%rax), %eax
cmpq $0x2f, %rax
ja 0x5878
movabsq $0x3c0000006, %rcx      # imm = 0x3C0000006
btq %rax, %rcx
jae 0x5bc2
movq 0x1f58(%rsp), %rdi
callq 0x3e46
pushq $0x5
popq %rdi
movq %r14, %rsi
callq 0x3ac4
movq 0x8(%r14), %r15
movq (%r15), %rax
movb (%rax), %cl
cmpb $0x2f, %cl
jne 0x58b7
cmpb $0x0, 0x1(%rax)
jne 0x58de
movq 0x18(%r15), %rax
cmpl $0x10, 0x8(%rax)
jne 0x58de
movq 0x1f58(%rsp), %rdi
callq 0x3e46
pushq $0x9
popq %rdi
movq %r14, %rsi
callq 0x3ac4
movq 0x8(%r14), %r15
movq (%r15), %rax
movb (%rax), %cl
cmpb $0x5f, %cl
jne 0x58de
cmpb $0x0, 0x1(%rax)
jne 0x58de
movq 0x1f58(%rsp), %rdi
callq 0x3e46
pushq $0x3
popq %rdi
movq %r14, %rsi
callq 0x3ac4
movq 0x8(%r14), %r15
movl 0x8(%r15), %eax
leal -0x10(%rax), %ecx
cmpl $0x7, %ecx
ja 0x590d
leaq 0x2baf(%rip), %rdx      # 0x84a0
movslq (%rdx,%rcx,4), %rax
addq %rdx, %rax
jmpq *%rax
movl $0x18, 0x1f50(%rsp)
incl %r12d
jmp 0x5b94
cmpl $0x29, %eax
je 0x5960
cmpl $0x2b, %eax
jne 0x5b94
movq 0x18(%r15), %rax
movl 0x8(%rax), %eax
cmpl $0xb, %eax
ja 0x5949
movl $0xb00, %ecx            # imm = 0xB00
btl %eax, %ecx
jae 0x5949
movq 0x1f58(%rsp), %rdi
callq 0x3e46
pushq $0x5
popq %rdi
movq %r14, %rsi
callq 0x3ac4
movl $0x14, 0x1f50(%rsp)
incl 0x1f74(%rsp)
jmp 0x5b94
movq (%r15), %rdi
leaq 0x2bc5(%rip), %rsi      # 0x852f
callq 0x1080
testl %eax, %eax
jne 0x599d
movq 0x10(%r15), %rax
movq (%rax), %rax
cmpb $0x2f, (%rax)
jne 0x599d
cmpb $0x0, 0x1(%rax)
jne 0x599d
movq 0x1f58(%rsp), %rdi
callq 0x3e46
pushq $0x9
popq %rdi
movq %r14, %rsi
callq 0x3ac4
movl $0x17, 0x1f50(%rsp)
incl 0x1f78(%rsp)
jmp 0x5b94
movl %r12d, 0x1f54(%rsp)
movq (%r15), %r12
cmpb $0x5f, (%r12)
movq %r12, %r15
jne 0x59f3
cmpb $0x0, 0x1(%r12)
movq %r12, %r15
jne 0x59f3
movq 0x1f58(%rsp), %rdi
callq 0x3e46
pushq $0x3
popq %rdi
movq %r14, %rsi
callq 0x3ac4
movq 0x8(%r14), %rax
movq (%rax), %r15
movq %r15, %rdi
leaq 0x2b36(%rip), %rsi      # 0x8533
callq 0x1080
testl %eax, %eax
je 0x5b81
movq %r15, %rdi
leaq 0x2b26(%rip), %rsi      # 0x853a
callq 0x1080
testl %eax, %eax
je 0x5b81
movq %r15, %rdi
leaq 0x2b16(%rip), %rsi      # 0x8541
callq 0x1080
testl %eax, %eax
je 0x5b81
movq %r15, %rdi
movq %r13, %rsi
callq 0x1080
testl %eax, %eax
je 0x5bd1
movq %r15, %rdi
movq %rbx, %rsi
callq 0x1080
testl %eax, %eax
je 0x5bfb
movq %r15, %rdi
movq %rbp, %rsi
callq 0x1080
testl %eax, %eax
movq 0x1f58(%rsp), %rax
je 0x5c53
movq %r15, %rdi
leaq 0x2add(%rip), %rsi      # 0x8560
callq 0x1080
testl %eax, %eax
je 0x5b81
movq %r15, %rdi
leaq 0x2acd(%rip), %rsi      # 0x8567
callq 0x1080
testl %eax, %eax
je 0x5b81
movq %r15, %rdi
leaq 0x2aba(%rip), %rsi      # 0x856b
callq 0x1080
testl %eax, %eax
je 0x5b81
movq %r15, %rdi
leaq 0x2a57(%rip), %rsi      # 0x851f
callq 0x1080
testl %eax, %eax
je 0x5c9b
movq 0x8904(%rip), %rdi      # 0xe3e0
movq %r15, %rsi
leaq 0x1f80(%rsp), %rdx
callq 0x3b85
testb %al, %al
je 0x5ca2
movq 0x8(%r14), %rax
movq 0x18(%rax), %rcx
cmpl $0x6, 0x8(%rcx)
jne 0x5b8c
movq (%rax), %rsi
movq %r14, %rdi
movq 0x1f58(%rsp), %r15
movq %r15, %rdx
callq 0x45c5
cmpl $0x1, 0x1f84(%rsp)
movl 0x1f54(%rsp), %r12d
jne 0x5cfe
movl 0x2b88(%rsp), %eax
movl %eax, 0x1f50(%rsp)
movq %r15, %rdi
movq 0x1f60(%rsp), %rsi
leaq 0x1f50(%rsp), %rdx
movq 0x1f68(%rsp), %rcx
callq 0x3d28
jmp 0x5b94
movl $0x18, 0x1f50(%rsp)
incl %r12d
leaq 0x29ba(%rip), %rax      # 0x8531
movq %rax, 0x1f68(%rsp)
jmp 0x5b94
pushq $0x7
popq %rdi
movq %r14, %rsi
callq 0x3ac4
movl 0x1f54(%rsp), %r12d
movq 0x8(%r14), %rax
movl 0x8(%rax), %eax
cmpl $0x5, %eax
je 0x5baa
cmpl $0x38, %eax
jne 0x5bb5
jmp 0x5d55
pushq $0x7
popq %rdi
movq %r14, %rsi
callq 0x3ac4
movq %r14, %rdi
callq 0x12c2
jmp 0x583f
cmpq $0x2f, %rax
jne 0x5878
jmp 0x5d55
movq %r14, %rdi
movq 0x1f58(%rsp), %r15
movq %r15, %rsi
leaq 0x2962(%rip), %r13      # 0x8548
movq %r13, %rdx
callq 0x6316
movl $0x17, 0x1f50(%rsp)
jmp 0x5c76
movq %r14, %rdi
movq 0x1f58(%rsp), %rbx
movq %rbx, %rsi
leaq 0x2942(%rip), %r15      # 0x8552
movq %r15, %rdx
callq 0x6316
movl $0x18, 0x1f50(%rsp)
movq %rbx, %rdi
movq 0x1f60(%rsp), %rsi
leaq 0x1f50(%rsp), %rdx
movq 0x1f68(%rsp), %rcx
callq 0x3d28
movl 0x1f54(%rsp), %r12d
movq %r15, %rbx
jmp 0x5b94
movq %r14, %rdi
movq %rax, %r15
movq %rax, %rsi
leaq 0x28f9(%rip), %rbp      # 0x855c
movq %rbp, %rdx
callq 0x6316
movl $0x18, 0x1f50(%rsp)
movq %r15, %rdi
movq 0x1f60(%rsp), %rsi
leaq 0x1f50(%rsp), %rdx
movq 0x1f68(%rsp), %rcx
callq 0x3d28
jmp 0x5b8c
pushq $0x5
jmp 0x5b83
movl $0x3e9, %ecx            # imm = 0x3E9
movq %rsp, %rdi
leaq 0x67e7(%rip), %rsi      # 0xc498
rep  movsq (%rsi), %es:(%rdi)
movq %r12, %rdi
leaq 0x1f7c(%rsp), %rsi
callq 0x3eb3
testb %al, %al
je 0x5b8c
movl 0x1f7c(%rsp), %eax
movl %eax, 0x1f50(%rsp)
cmpl $0x14, %eax
je 0x5d0e
cmpl $0x17, %eax
movl 0x1f54(%rsp), %r12d
je 0x59a8
cmpl $0x18, %eax
je 0x5905
jmp 0x5b94
pushq $0x6
popq %rdi
movq %r14, %rsi
callq 0x3ac4
jmp 0x5b94
movq 0x8(%r14), %rax
movq 0x18(%rax), %rax
movl 0x8(%rax), %eax
cmpl $0xb, %eax
movl 0x1f54(%rsp), %r12d
ja 0x5954
movl $0xb00, %ecx            # imm = 0xB00
btl %eax, %ecx
jae 0x5954
movq 0x1f58(%rsp), %rdi
callq 0x3e46
pushq $0x5
popq %rdi
movq %r14, %rsi
callq 0x3ac4
jmp 0x5954
movl 0x1f74(%rsp), %edx
testl %edx, %edx
setne %al
movl %r12d, %ecx
movl 0x1f78(%rsp), %esi
orl %esi, %ecx
sete %cl
andb %al, %cl
cmpb $0x1, %cl
je 0x5d9d
testl %r12d, %r12d
setne %al
movl %edx, %ecx
orl %esi, %ecx
sete %cl
andb %al, %cl
cmpb $0x1, %cl
je 0x5d9d
orl %r12d, %edx
sete %al
testl %esi, %esi
setne %cl
andb %al, %cl
cmpb $0x1, %cl
jne 0x5dd4
leaq 0x1f50(%rsp), %rdx
movq 0x1f58(%rsp), %rdi
movq 0x1f60(%rsp), %rsi
movq 0x1f68(%rsp), %rcx
callq 0x3d28
addq $0x2f88, %rsp           # imm = 0x2F88
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
pushq $0x4
popq %rdi
movq %r14, %rsi
callq 0x3ac4
jmp 0x5dc2