// File: /workspace/github_c_makefile_star2_O3/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 0x60a8
movl $0x7, %edi
movq %r14, %rsi
callq 0x42d0
movq 0x8(%r14), %rax
movq (%rax), %rcx
movq %rcx, 0x1f60(%rsp)
movq 0x10(%rax), %rax
movl 0x8(%rax), %eax
cmpl $0x1a, %eax
je 0x60d1
cmpl $0x2f, %eax
je 0x60d1
movl $0x7, %edi
movq %r14, %rsi
callq 0x42d0
movq (%rbx), %rdi
leaq 0x244f(%rip), %rcx      # 0x852a
leaq 0x1f50(%rsp), %rdx
movq 0x1f60(%rsp), %rsi
movq %rcx, 0x1f68(%rsp)
callq 0x44e4
testb %al, %al
je 0x6111
movl $0x3, %edi
movq %r14, %rsi
callq 0x42d0
movq %rbx, %rdi
callq 0x4662
movq %rbx, 0x1f58(%rsp)
movl $0x0, 0x1f74(%rsp)
leaq 0x241d(%rip), %r12      # 0x8548
leaq 0x2420(%rip), %rbx      # 0x8552
leaq 0x2423(%rip), %r13      # 0x855c
xorl %ebp, %ebp
movl $0x0, 0x1f78(%rsp)
movq 0x8(%r14), %rax
movl 0x8(%rax), %eax
cmpq $0x2f, %rax
ja 0x6181
movabsq $0x3c0000006, %rcx      # imm = 0x3C0000006
btq %rax, %rcx
jae 0x64d1
movq 0x1f58(%rsp), %rdi
callq 0x4662
movl $0x5, %edi
movq %r14, %rsi
callq 0x42d0
movq 0x8(%r14), %r15
movq (%r15), %rax
movb (%rax), %cl
cmpb $0x2f, %cl
jne 0x61c2
cmpb $0x0, 0x1(%rax)
jne 0x61eb
movq 0x18(%r15), %rax
cmpl $0x10, 0x8(%rax)
jne 0x61eb
movq 0x1f58(%rsp), %rdi
callq 0x4662
movl $0x9, %edi
movq %r14, %rsi
callq 0x42d0
movq 0x8(%r14), %r15
movq (%r15), %rax
movb (%rax), %cl
cmpb $0x5f, %cl
jne 0x61eb
cmpb $0x0, 0x1(%rax)
jne 0x61eb
movq 0x1f58(%rsp), %rdi
callq 0x4662
movl $0x3, %edi
movq %r14, %rsi
callq 0x42d0
movq 0x8(%r14), %r15
movl 0x8(%r15), %eax
leal -0x10(%rax), %ecx
cmpl $0x7, %ecx
ja 0x6219
leaq 0x22a2(%rip), %rdx      # 0x84a0
movslq (%rdx,%rcx,4), %rax
addq %rdx, %rax
jmpq *%rax
movl $0x18, 0x1f50(%rsp)
incl %ebp
jmp 0x64a1
cmpl $0x29, %eax
je 0x626e
cmpl $0x2b, %eax
jne 0x64a1
movq 0x18(%r15), %rax
movl 0x8(%rax), %eax
cmpl $0xb, %eax
ja 0x6257
movl $0xb00, %ecx            # imm = 0xB00
btl %eax, %ecx
jae 0x6257
movq 0x1f58(%rsp), %rdi
callq 0x4662
movl $0x5, %edi
movq %r14, %rsi
callq 0x42d0
movl $0x14, 0x1f50(%rsp)
incl 0x1f74(%rsp)
jmp 0x64a1
movq (%r15), %rdi
leaq 0x22b7(%rip), %rsi      # 0x852f
callq 0x1080
testl %eax, %eax
jne 0x62ad
movq 0x10(%r15), %rax
movq (%rax), %rax
cmpb $0x2f, (%rax)
jne 0x62ad
cmpb $0x0, 0x1(%rax)
jne 0x62ad
movq 0x1f58(%rsp), %rdi
callq 0x4662
movl $0x9, %edi
movq %r14, %rsi
callq 0x42d0
movl $0x17, 0x1f50(%rsp)
incl 0x1f78(%rsp)
jmp 0x64a1
movl %ebp, 0x1f54(%rsp)
movq (%r15), %rbp
cmpb $0x5f, (%rbp)
movq %rbp, %r15
jne 0x6301
cmpb $0x0, 0x1(%rbp)
movq %rbp, %r15
jne 0x6301
movq 0x1f58(%rsp), %rdi
callq 0x4662
movl $0x3, %edi
movq %r14, %rsi
callq 0x42d0
movq 0x8(%r14), %rax
movq (%rax), %r15
movq %r15, %rdi
leaq 0x2228(%rip), %rsi      # 0x8533
callq 0x1080
testl %eax, %eax
je 0x648d
movq %r15, %rdi
leaq 0x2218(%rip), %rsi      # 0x853a
callq 0x1080
testl %eax, %eax
je 0x648d
movq %r15, %rdi
leaq 0x2208(%rip), %rsi      # 0x8541
callq 0x1080
testl %eax, %eax
je 0x648d
movq %r15, %rdi
movq %r12, %rsi
callq 0x1080
testl %eax, %eax
je 0x64e0
movq %r15, %rdi
movq %rbx, %rsi
callq 0x1080
testl %eax, %eax
je 0x650a
movq %r15, %rdi
movq %r13, %rsi
callq 0x1080
testl %eax, %eax
movq 0x1f58(%rsp), %rax
je 0x6561
movq %r15, %rdi
leaq 0x21cf(%rip), %rsi      # 0x8560
callq 0x1080
testl %eax, %eax
je 0x648d
movq %r15, %rdi
leaq 0x21bf(%rip), %rsi      # 0x8567
callq 0x1080
testl %eax, %eax
je 0x648d
movq %r15, %rdi
leaq 0x21ac(%rip), %rsi      # 0x856b
callq 0x1080
testl %eax, %eax
je 0x648d
movq %r15, %rdi
leaq 0x2149(%rip), %rsi      # 0x851f
callq 0x1080
testl %eax, %eax
je 0x65a9
movq 0x7fe6(%rip), %rdi      # 0xe3d0
movq %r15, %rsi
leaq 0x1f80(%rsp), %rdx
callq 0x43b0
testb %al, %al
je 0x65b3
movq 0x8(%r14), %rax
movq 0x18(%rax), %rcx
cmpl $0x6, 0x8(%rcx)
jne 0x649a
movq (%rax), %rsi
movq %r14, %rdi
movq 0x1f58(%rsp), %r15
movq %r15, %rdx
callq 0x4e01
cmpl $0x1, 0x1f84(%rsp)
movl 0x1f54(%rsp), %ebp
jne 0x660e
movl 0x2b88(%rsp), %eax
movl %eax, 0x1f50(%rsp)
movq %r15, %rdi
movq 0x1f60(%rsp), %rsi
leaq 0x1f50(%rsp), %rdx
movq 0x1f68(%rsp), %rcx
callq 0x4535
jmp 0x64a1
movl $0x18, 0x1f50(%rsp)
incl %ebp
leaq 0x20ae(%rip), %rax      # 0x8531
movq %rax, 0x1f68(%rsp)
jmp 0x64a1
movl $0x7, %edi
movq %r14, %rsi
callq 0x42d0
movl 0x1f54(%rsp), %ebp
movq 0x8(%r14), %rax
movl 0x8(%rax), %eax
cmpl $0x5, %eax
je 0x64b7
cmpl $0x38, %eax
jne 0x64c4
jmp 0x6668
movl $0x7, %edi
movq %r14, %rsi
callq 0x42d0
movq %r14, %rdi
callq 0x1691
jmp 0x6146
cmpq $0x2f, %rax
jne 0x6181
jmp 0x6668
movq %r14, %rdi
movq 0x1f58(%rsp), %r15
movq %r15, %rsi
leaq 0x2053(%rip), %r12      # 0x8548
movq %r12, %rdx
callq 0x6c22
movl $0x17, 0x1f50(%rsp)
jmp 0x6584
movq %r14, %rdi
movq 0x1f58(%rsp), %rbx
movq %rbx, %rsi
leaq 0x2033(%rip), %r15      # 0x8552
movq %r15, %rdx
callq 0x6c22
movl $0x18, 0x1f50(%rsp)
movq %rbx, %rdi
movq 0x1f60(%rsp), %rsi
leaq 0x1f50(%rsp), %rdx
movq 0x1f68(%rsp), %rcx
callq 0x4535
movl 0x1f54(%rsp), %ebp
movq %r15, %rbx
jmp 0x64a1
movq %r14, %rdi
movq %rax, %r15
movq %rax, %rsi
leaq 0x1feb(%rip), %r13      # 0x855c
movq %r13, %rdx
callq 0x6c22
movl $0x18, 0x1f50(%rsp)
movq %r15, %rdi
movq 0x1f60(%rsp), %rsi
leaq 0x1f50(%rsp), %rdx
movq 0x1f68(%rsp), %rcx
callq 0x4535
jmp 0x649a
movl $0x5, %edi
jmp 0x6492
movl $0x3e9, %ecx            # imm = 0x3E9
movq %rsp, %rdi
leaq 0x5ec6(%rip), %rsi      # 0xc488
rep  movsq (%rsi), %es:(%rdi)
movq %rbp, %rdi
leaq 0x1f7c(%rsp), %rsi
callq 0x46d5
testb %al, %al
je 0x649a
movl 0x1f7c(%rsp), %eax
movl %eax, 0x1f50(%rsp)
cmpl $0x14, %eax
je 0x6620
cmpl $0x17, %eax
movl 0x1f54(%rsp), %ebp
je 0x62b8
cmpl $0x18, %eax
je 0x6212
jmp 0x64a1
movl $0x6, %edi
movq %r14, %rsi
callq 0x42d0
jmp 0x64a1
movq 0x8(%r14), %rax
movq 0x18(%rax), %rax
movl 0x8(%rax), %eax
cmpl $0xb, %eax
movl 0x1f54(%rsp), %ebp
ja 0x6262
movl $0xb00, %ecx            # imm = 0xB00
btl %eax, %ecx
jae 0x6262
movq 0x1f58(%rsp), %rdi
callq 0x4662
movl $0x5, %edi
movq %r14, %rsi
callq 0x42d0
jmp 0x6262
movl 0x1f74(%rsp), %edx
testl %edx, %edx
setne %al
movl %ebp, %ecx
movl 0x1f78(%rsp), %esi
orl %esi, %ecx
sete %cl
andb %al, %cl
cmpb $0x1, %cl
je 0x66ad
testl %ebp, %ebp
setne %al
movl %edx, %ecx
orl %esi, %ecx
sete %cl
andb %al, %cl
cmpb $0x1, %cl
je 0x66ad
orl %ebp, %edx
sete %al
testl %esi, %esi
setne %cl
andb %al, %cl
cmpb $0x1, %cl
jne 0x66e4
leaq 0x1f50(%rsp), %rdx
movq 0x1f58(%rsp), %rdi
movq 0x1f60(%rsp), %rsi
movq 0x1f68(%rsp), %rcx
callq 0x4535
addq $0x2f88, %rsp           # imm = 0x2F88
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl $0x4, %edi
movq %r14, %rsi
callq 0x42d0
jmp 0x66d2