// File: /workspace/github_c_makefile_star2_O1/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), %rax
cmpl $0x2f, 0x8(%rax)
jne 0x614d
movl $0x7, %edi
movq %r14, %rsi
callq 0x42c8
movq 0x8(%r14), %rax
movq (%rax), %rcx
movq %rcx, 0x1f58(%rsp)
movq 0x10(%rax), %rax
movl 0x8(%rax), %eax
cmpl $0x1a, %eax
je 0x617a
cmpl $0x2f, %eax
je 0x617a
movl $0x7, %edi
movq %r14, %rsi
callq 0x42c8
movq (%rbx), %rdi
leaq 0x23ac(%rip), %rcx      # 0x8530
leaq 0x1f50(%rsp), %rdx
movq 0x1f58(%rsp), %rsi
movq %rcx, 0x1f60(%rsp)
callq 0x452f
testb %al, %al
je 0x61ba
movl $0x3, %edi
movq %r14, %rsi
callq 0x42c8
movq %rbx, %rdi
callq 0x46ab
movl $0x0, 0x1f6c(%rsp)
leaq 0x22d4(%rip), %rbp      # 0x84a0
leaq 0x237d(%rip), %r13      # 0x8550
movl $0x0, 0x1f54(%rsp)
movl $0x0, 0x1f70(%rsp)
movq 0x8(%r14), %rax
movl 0x8(%rax), %eax
cmpq $0x2f, %rax
ja 0x621f
movabsq $0x3c0000006, %rcx      # imm = 0x3C0000006
btq %rax, %rcx
jae 0x6548
movq %rbx, %rdi
callq 0x46ab
movl $0x5, %edi
movq %r14, %rsi
callq 0x42c8
movq 0x8(%r14), %r15
movq (%r15), %rdi
leaq 0x2308(%rip), %rsi      # 0x8535
callq 0x1080
testl %eax, %eax
jne 0x6255
movq 0x18(%r15), %rax
cmpl $0x10, 0x8(%rax)
jne 0x6255
movq %rbx, %rdi
callq 0x46ab
movl $0x9, %edi
movq %r14, %rsi
callq 0x42c8
movq %r13, %r15
movq 0x8(%r14), %rax
movq (%rax), %rdi
leaq 0x22b2(%rip), %rsi      # 0x8518
callq 0x1080
testl %eax, %eax
jne 0x6284
movq %rbx, %rdi
callq 0x46ab
movl $0x3, %edi
movq %r14, %rsi
callq 0x42c8
movq 0x8(%r14), %r12
movl 0x8(%r12), %eax
leal -0x10(%rax), %ecx
cmpl $0x7, %ecx
ja 0x62b6
movslq (%rbp,%rcx,4), %rax
addq %rbp, %rax
jmpq *%rax
movl $0x18, 0x1f50(%rsp)
incl 0x1f54(%rsp)
jmp 0x6515
cmpl $0x29, %eax
je 0x6307
cmpl $0x2b, %eax
jne 0x6515
movq 0x18(%r12), %rax
movl 0x8(%rax), %eax
cmpl $0xb, %eax
ja 0x62f0
movl $0xb00, %ecx            # imm = 0xB00
btl %eax, %ecx
jae 0x62f0
movq %rbx, %rdi
callq 0x46ab
movl $0x5, %edi
movq %r14, %rsi
callq 0x42c8
movl $0x14, 0x1f50(%rsp)
incl 0x1f6c(%rsp)
jmp 0x6515
movq (%r12), %rdi
leaq 0x2225(%rip), %rsi      # 0x8537
callq 0x1080
testl %eax, %eax
jne 0x6348
movq 0x10(%r12), %rax
movq (%rax), %rdi
leaq 0x220b(%rip), %rsi      # 0x8535
callq 0x1080
testl %eax, %eax
jne 0x6348
movq %rbx, %rdi
callq 0x46ab
movl $0x9, %edi
movq %r14, %rsi
callq 0x42c8
movl $0x17, 0x1f50(%rsp)
incl 0x1f70(%rsp)
jmp 0x6515
movq (%r12), %r13
movq (%r12), %rdi
leaq 0x21aa(%rip), %rsi      # 0x8518
callq 0x1080
testl %eax, %eax
jne 0x638c
movq %rbx, %rdi
callq 0x46ab
movl $0x3, %edi
movq %r14, %rsi
callq 0x42c8
movq 0x8(%r14), %rax
movq (%rax), %r12
movq %r12, %rdi
leaq 0x219e(%rip), %rsi      # 0x853b
callq 0x1080
testl %eax, %eax
je 0x6508
movq %r12, %rdi
leaq 0x218e(%rip), %rsi      # 0x8542
callq 0x1080
testl %eax, %eax
je 0x6508
movq %r12, %rdi
leaq 0x217e(%rip), %rsi      # 0x8549
callq 0x1080
testl %eax, %eax
je 0x6508
movq %r13, 0x1f78(%rsp)
movq %r12, %rdi
movq %r15, %r13
movq %r15, %rsi
callq 0x1080
testl %eax, %eax
je 0x6592
movq %r12, %rdi
leaq 0x215a(%rip), %r13      # 0x855a
movq %r13, %rsi
callq 0x1080
testl %eax, %eax
je 0x6557
movq %r12, %rdi
leaq 0x214a(%rip), %r13      # 0x8564
movq %r13, %rsi
callq 0x1080
testl %eax, %eax
je 0x6557
movq %r12, %rdi
leaq 0x2134(%rip), %rsi      # 0x8568
callq 0x1080
testl %eax, %eax
je 0x6508
movq %r12, %rdi
leaq 0x2124(%rip), %rsi      # 0x856f
callq 0x1080
testl %eax, %eax
je 0x6508
movq %r12, %rdi
leaq 0x2111(%rip), %rsi      # 0x8573
callq 0x1080
testl %eax, %eax
je 0x6508
movq %r12, %rdi
leaq 0x20a8(%rip), %rsi      # 0x8521
callq 0x1080
testl %eax, %eax
je 0x65d0
movq 0x7f43(%rip), %rdi      # 0xe3d0
movq %r12, %rsi
leaq 0x1f80(%rsp), %rdx
callq 0x43a8
testb %al, %al
je 0x65da
movq 0x8(%r14), %rax
movq 0x18(%rax), %rcx
cmpl $0x6, 0x8(%rcx)
movq %r15, %r13
jne 0x6518
movq (%rax), %rsi
movq %r14, %rdi
movq %rbx, %rdx
callq 0x4e67
cmpl $0x1, 0x1f84(%rsp)
jne 0x6639
movl 0x2b88(%rsp), %eax
movl %eax, 0x1f50(%rsp)
jmp 0x65ab
movl $0x18, 0x1f50(%rsp)
incl 0x1f54(%rsp)
leaq 0x203b(%rip), %rax      # 0x8539
movq %rax, 0x1f60(%rsp)
jmp 0x6515
movl $0x7, %edi
movq %r14, %rsi
callq 0x42c8
movq %r15, %r13
movq 0x8(%r14), %rax
movl 0x8(%rax), %eax
cmpl $0x5, %eax
je 0x652e
cmpl $0x38, %eax
jne 0x653b
jmp 0x6692
movl $0x7, %edi
movq %r14, %rsi
callq 0x42c8
movq %r14, %rdi
callq 0x1695
jmp 0x61e9
cmpq $0x2f, %rax
jne 0x621f
jmp 0x6692
movq %r14, %rdi
movq %rbx, %rsi
movq %r13, %rdx
callq 0x6c38
movl $0x18, 0x1f50(%rsp)
movq %rbx, %rdi
movq 0x1f58(%rsp), %rsi
leaq 0x1f50(%rsp), %rdx
movq 0x1f60(%rsp), %rcx
callq 0x4576
jmp 0x6515
movq %r14, %rdi
movq %rbx, %rsi
movq %r13, %rdx
callq 0x6c38
movl $0x17, 0x1f50(%rsp)
movq %rbx, %rdi
movq 0x1f58(%rsp), %rsi
leaq 0x1f50(%rsp), %rdx
movq 0x1f60(%rsp), %rcx
callq 0x4576
jmp 0x6518
movl $0x5, %edi
jmp 0x650d
movl $0x3e9, %ecx            # imm = 0x3E9
movq %rsp, %rdi
leaq 0x5e9f(%rip), %rsi      # 0xc488
rep  movsq (%rsi), %es:(%rdi)
movq 0x1f78(%rsp), %rdi
leaq 0x1f74(%rsp), %rsi
callq 0x471e
testb %al, %al
movq %r15, %r13
je 0x6518
movl 0x1f74(%rsp), %eax
movl %eax, 0x1f50(%rsp)
cmpl $0x14, %eax
je 0x6657
cmpl $0x17, %eax
je 0x664b
cmpl $0x18, %eax
jne 0x6518
incl 0x1f54(%rsp)
jmp 0x6518
movl $0x6, %edi
movq %r14, %rsi
callq 0x42c8
jmp 0x6518
incl 0x1f70(%rsp)
jmp 0x6518
movq 0x8(%r14), %rax
movq 0x18(%rax), %rax
movl 0x8(%rax), %eax
cmpl $0xb, %eax
ja 0x6686
movl $0xb00, %ecx            # imm = 0xB00
btl %eax, %ecx
jae 0x6686
movq %rbx, %rdi
callq 0x46ab
movl $0x5, %edi
movq %r14, %rsi
callq 0x42c8
incl 0x1f6c(%rsp)
jmp 0x6518
movl 0x1f6c(%rsp), %edx
testl %edx, %edx
setne %al
movl 0x1f54(%rsp), %edi
movl %edi, %ecx
movl 0x1f70(%rsp), %esi
orl %esi, %ecx
sete %cl
andb %al, %cl
cmpb $0x1, %cl
je 0x66de
testl %edi, %edi
setne %al
movl %edx, %ecx
orl %esi, %ecx
sete %cl
andb %al, %cl
cmpb $0x1, %cl
je 0x66de
orl %edi, %edx
sete %al
testl %esi, %esi
setne %cl
andb %al, %cl
cmpb $0x1, %cl
jne 0x6710
leaq 0x1f50(%rsp), %rdx
movq %rbx, %rdi
movq 0x1f58(%rsp), %rsi
movq 0x1f60(%rsp), %rcx
callq 0x4576
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 0x42c8
jmp 0x66fe