// File: /workspace/github_c_makefile_star2_O0/MartinNovotny25[P]VUT-FIT-IFJ2020/precanalysis.c
// Function: evaluation
void evaluation(TDLList* psa_list, TDLList* global_tokens) {
    // TOKEN dollar, zaradim na koniec vyrazu a posledny znak
    TOKEN dollar;
    alloc(3, &dollar);
    strcpy(dollar.lex, "$");
    dollar.type = t_DOLLAR;

    TDLLFirst(psa_list);
    TDLLInsertLast(psa_list, dollar);

    //Inicializacia stacku
    symstack_init(&syms_Stack);

    //Pushnutie dolara na spodok stacku ako koniec stacku
    symstack_push(&syms_Stack, T_DOLLAR); //DOLLAR NA SPODKU STACKU

    psa_symbols input_sym; //Symbol na vstupe -- VYRAZ
    tsym_stack_symbol* top_terminal; //Symbol na vrchole terminalu

    bool koniec = false; // PREMENNA pre koniec vyhodnocovania vyrazu

    do {

        input_sym = psa_tokenToSymbol(&psa_list->Act->tdata); //do input sym sa umiestni aktualny znak DLL
        top_terminal = symstack_top_t(&syms_Stack); //top terminal je vrchol stacku

        int terminal = top_terminal->symbol;
        int vstup = input_sym;

        //int test = psa_prec_table[1][1];
        //printf("Na terminale je %d, na vstupe je %d\n", terminal, vstup);

        //SPLIT premenna symbolizuje vyber pravidla
        // 1 = SHIFT
        // 2 = REDUKCIA
        // 3 = EQUAL
        // 4 = X, NEMOZNE // V PRIPADE  $ a $ USPESNY KONIEC

        int SPLIT = psa_prec_table[terminal][vstup];
        //printf("SPLIT %d\n", SPLIT);

        /* SHIFT */
        if (SPLIT == 1) {

            // Ak pride shift, pred najvrchnejsi termnal sa pushne znak pre redukciu
            symstack_push_red(&syms_Stack, T_RED);
            //Na vrch sa pusne aktualny znak na vstupe
            symstack_push(&syms_Stack, input_sym);

            //aktivita sa nastaví na dalsi znak
            psa_list->Act = psa_list->Act->rptr;

        }

        /* REDUKCIA */
        else if (SPLIT == 2) {

            //Premenna pre cyklenie cez znaky, ktore s budu nasledne popovať zo stacku po redukcii
            tsym_stack_symbol* checked_symbol;
        ///////////////// TU POZOR /////////////////////////
            //nastavenie na vrchol zasobniku
            checked_symbol = syms_Stack.top;
        /////////////////////////////////////////////////

        //cyklus
            while (checked_symbol != NULL)
            {
                // pokial sa nenajde symbol redukcie, zvysi sa count
                if (checked_symbol->symbol != T_RED)
                {
                    red_found = false;
                    count++;
                }
                // ak sa najde, cyklus sa breakne
                else if (checked_symbol->symbol == T_RED)
                {
                    red_found = true;
                    break;
                }

                checked_symbol = checked_symbol->next;
            }
////////////////////////////////////////////////////////////////////////////////////////////////////

            // Moze sa redukovat iba ak su 3 alebo 1 znak
            // napr E+E -> E, (E) -> E, i -> E
            if (count != 3 && count != 1) {
                symstack_free(&syms_Stack);
                //fprintf(stderr, "PSA - Syntax error\n");
                error_call(ERR_SYN, *(&global_tokens));
            }

            // Jeden znak
            if (count == 1 && red_found) {

                pop1_push();

            }   else if (count == 3 && red_found) {

                pop3_push();

                //3 symboly potrebne pre redukciu
               /* tsym_stack_symbol* red1;
                tsym_stack_symbol* red2;
                tsym_stack_symbol* red3;

                red3 = syms_Stack.top;
                red2 = red3->next;
                red1 = red3->next->next;

                // Apliakcia pravidla
                reduction_succ  = psa_rule_application(count, red1, red2, red3);

                //Popnutie 3 symbolob, ktore sa redukovali
                symstack_pop(&syms_Stack);
                symstack_pop(&syms_Stack);
                symstack_pop(&syms_Stack);
                symstack_pop(&syms_Stack); //popuje sa RED symbol

                // push nonterm
                symstack_push(&syms_Stack, T_NON_TERM);*/

            }

            // Ak nebolo uplatnene ziadne pravidlo -- Error
            if (reduction_succ  == false) {
                symstack_free(&syms_Stack);
                //fprintf(stderr, "PSA - Syntax error\n");
                error_call(ERR_SYN, *(&global_tokens));
                // Ak chill , nastavi sa count spat na 0
            } else {
                count = 0;
            }


        }
        /* EQUAL */
        else if (SPLIT == 3) {
        // printf("som v =\n");

            // Aktualny symbol sa pushne na stack, aktivita sa posunie
            symstack_push(&syms_Stack, input_sym);
            psa_list->Act = psa_list->Act->rptr;
        }

        else if (SPLIT == 4) {
        //printf("som v x\n");

            // Ak je na vstupe Dollar a na zasobniku Dollar, VYRAZ JE VALIDNY
            if((input_sym == T_DOLLAR && top_terminal->symbol == T_DOLLAR) != true) {
                symstack_free(&syms_Stack);
                //fprintf(stderr, "PSA SYNTAX ERROR, EXIT (2)\n");
                error_call(ERR_SYN, *(&global_tokens));
            } else
                koniec = true;
        }

    } while (koniec != true);

  //  TDLLDeleteLast(psa_list); //removnem dollar na konci listu
  // Uvolnenie stacku
    symstack_free(&syms_Stack);

}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl $0x3, %edi
leaq -0x20(%rbp), %rsi
callq 0x47c0
movq -0x20(%rbp), %rdi
leaq 0xd9d(%rip), %rsi       # 0xd626
callq 0x1040
movl $0x64, -0x18(%rbp)
movq -0x8(%rbp), %rdi
callq 0x12c0
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rsi
movl -0x18(%rbp), %edx
callq 0x1450
leaq 0x5b23(%rip), %rdi      # 0x123d8
callq 0xc250
leaq 0x5b17(%rip), %rdi      # 0x123d8
movl $0xd, %esi
callq 0xc270
movb $0x0, -0x31(%rbp)
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rdi
callq 0xc6b0
movl %eax, -0x24(%rbp)
leaq 0x5af2(%rip), %rdi      # 0x123d8
callq 0xc310
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x38(%rbp)
movl -0x24(%rbp), %eax
movl %eax, -0x3c(%rbp)
movslq -0x38(%rbp), %rcx
leaq 0x3787(%rip), %rax      # 0x10090
imulq $0x38, %rcx, %rcx
addq %rcx, %rax
movslq -0x3c(%rbp), %rcx
movl (%rax,%rcx,4), %eax
movl %eax, -0x40(%rbp)
cmpl $0x1, -0x40(%rbp)
jne 0xc959
leaq 0x5ab1(%rip), %rdi      # 0x123d8
movl $0xe, %esi
callq 0xc370
movl -0x24(%rbp), %esi
leaq 0x5a9d(%rip), %rdi      # 0x123d8
callq 0xc270
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rax
movq 0x18(%rax), %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x8(%rax)
jmp 0xcacc
cmpl $0x2, -0x40(%rbp)
jne 0xca4e
movq 0x5a6e(%rip), %rax      # 0x123d8
movq %rax, -0x48(%rbp)
cmpq $0x0, -0x48(%rbp)
je 0xc9b8
movq -0x48(%rbp), %rax
cmpl $0xe, (%rax)
je 0xc996
movb $0x0, 0x5a60(%rip)      # 0x123e5
movl 0x5a55(%rip), %eax      # 0x123e0
addl $0x1, %eax
movl %eax, 0x5a4c(%rip)      # 0x123e0
jmp 0xc9aa
movq -0x48(%rbp), %rax
cmpl $0xe, (%rax)
jne 0xc9a8
movb $0x1, 0x5a3f(%rip)      # 0x123e5
jmp 0xc9b8
jmp 0xc9aa
movq -0x48(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x48(%rbp)
jmp 0xc96e
cmpl $0x3, 0x5a21(%rip)      # 0x123e0
je 0xc9e4
cmpl $0x1, 0x5a18(%rip)      # 0x123e0
je 0xc9e4
leaq 0x5a07(%rip), %rdi      # 0x123d8
callq 0xc430
movq -0x10(%rbp), %rsi
movl $0x2, %edi
callq 0x64e0
cmpl $0x1, 0x59f5(%rip)      # 0x123e0
jne 0xc9fd
testb $0x1, 0x59f1(%rip)      # 0x123e5
je 0xc9fd
callq 0xc650
jmp 0xca16
cmpl $0x3, 0x59dc(%rip)      # 0x123e0
jne 0xca14
testb $0x1, 0x59d8(%rip)      # 0x123e5
je 0xca14
callq 0xc460
jmp 0xca16
movb 0x59c8(%rip), %al       # 0x123e4
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0xca42
leaq 0x59ab(%rip), %rdi      # 0x123d8
callq 0xc430
movq -0x10(%rbp), %rsi
movl $0x2, %edi
callq 0x64e0
jmp 0xca4c
movl $0x0, 0x5994(%rip)      # 0x123e0
jmp 0xcaca
cmpl $0x3, -0x40(%rbp)
jne 0xca79
movl -0x24(%rbp), %esi
leaq 0x597a(%rip), %rdi      # 0x123d8
callq 0xc270
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rax
movq 0x18(%rax), %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x8(%rax)
jmp 0xcac8
cmpl $0x4, -0x40(%rbp)
jne 0xcac6
xorl %eax, %eax
cmpl $0xd, -0x24(%rbp)
movb %al, -0x49(%rbp)
jne 0xca97
movq -0x30(%rbp), %rax
cmpl $0xd, (%rax)
sete %al
movb %al, -0x49(%rbp)
movb -0x49(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x1, %eax
je 0xcac0
leaq 0x592d(%rip), %rdi      # 0x123d8
callq 0xc430
movq -0x10(%rbp), %rsi
movl $0x2, %edi
callq 0x64e0
jmp 0xcac4
movb $0x1, -0x31(%rbp)
jmp 0xcac6
jmp 0xcac8
jmp 0xcaca
jmp 0xcacc
jmp 0xcace
movb -0x31(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x1, %eax
jne 0xc8cf
leaq 0x58f2(%rip), %rdi      # 0x123d8
callq 0xc430
addq $0x50, %rsp
popq %rbp
retq