// File: /workspace/github_c_makefile_star2_O2/sharmaeklavya2[P]cerplag/driver_sub.c
// Function: main
int main(int argc, char* argv[])
{
    snprintf(usage, USAGE_SIZE, usage_template, argv[0]);
    if(argc < 2 || argc > 3)
        return cry_error();

    // open files
    FILE* ifp = fopen(argv[1], "r");
    if(ifp == NULL)
    {
        fprintf(stderr, "Couldn't open file %s:\n", argv[1]);
        perror(NULL);
        return 1;
    }
    FILE* ofp = stdout;
    if(argc == 3)
    {
        ofp = fopen(argv[2], "w");
        if(ofp == NULL)
        {
            fprintf(stderr, "Couldn't open file %s:\n", argv[2]);
            perror(NULL);
            return 1;
        }
    }

    fprintf(stderr, "Level 4: Symbol table, Type checking, Semantic rules, Assembly code generation.\n");

    fprintf(stderr, "Enter 1 to print token list.\n");
    fprintf(stderr, "Enter 2 to print parse tree in pre-order traversal.\n");
    fprintf(stderr, "Enter 3 to print AST in pre-order traversal.\n");
    fprintf(stderr, "Enter 4 to display compression percent.\n");
    fprintf(stderr, "Enter 5 to display symbol table.\n");
    fprintf(stderr, "Enter 6 to check code for semantic errors.\n");
    fprintf(stderr, "Enter 7 to produce assembly code.\n");
    int choice;
    scanf("%d",&choice);

    switch(choice){
        case 1:
            lexer_main(ifp, stdout, 0, print_token);
            break;
        case 2:
            parser_main(ifp, stdout, 0, print_tree);
            break;
        case 3:
            ast_gen_main(ifp, stdout, NULL, 0);
            break;
        case 4:
            ast_gen_main(ifp, NULL, stdout, 1);
            break;
        case 5:
            print_error_req = false;
            compiler_main(ifp, stdout, stdout, 0, 0);
            break;
        case 6:
            error_stream = stdout;
            compiler_main(ifp, stdout, NULL, 0, 0);
            break;
        case 7:
            compiler_main(ifp, ofp, NULL, 2, 0);
            break;
        default:
            fprintf(stderr, "Invalid choice!\n");
            break;
    }

    fprintf(stderr, "%d errors\n", error_count);
    if(warning_count > 0)
        fprintf(stderr, "%d warnings\n", warning_count);

    if(ifp != stdin)
        fclose(ifp);
    if(ofp != stdout && ofp != stderr)
        fclose(ofp);

    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rsi, %r15
movl %edi, %r14d
movq (%rsi), %rcx
leaq 0xd2bb(%rip), %rdi      # 0x19fe0
leaq 0x8004(%rip), %rdx      # 0x14d30
movl $0x200, %esi            # imm = 0x200
xorl %eax, %eax
callq 0x30c0
leal -0x4(%r14), %eax
cmpl $-0x3, %eax
ja 0xcd58
callq 0xcce8
pushq $0x2
popq %rax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x8(%r15), %rdi
leaq 0xaec(%rip), %rsi       # 0xd84f
callq 0x3160
testq %rax, %rax
jne 0xcd94
movq 0x7284(%rip), %rax      # 0x13ff8
movq (%rax), %rdi
movq 0x8(%r15), %rdx
leaq 0x221a(%rip), %rsi      # 0xef9c
xorl %eax, %eax
callq 0x3130
xorl %edi, %edi
callq 0x3170
pushq $0x1
jmp 0xcd48
movq %rax, %rbx
movq 0x7232(%rip), %r12      # 0x13fd0
cmpl $0x3, %r14d
jne 0xcdcc
movq 0x10(%r15), %rdi
leaq 0x2205(%rip), %rsi      # 0xefb4
callq 0x3160
movq %rax, %r14
testq %rax, %rax
jne 0xcdd0
movq 0x7235(%rip), %rax      # 0x13ff8
movq (%rax), %rdi
movq 0x10(%r15), %rdx
jmp 0xcd7b
movq (%r12), %r14
movq 0x7221(%rip), %r13      # 0x13ff8
movq (%r13), %rcx
leaq 0x21d4(%rip), %rdi      # 0xefb6
pushq $0x50
popq %rsi
pushq $0x1
popq %r15
movq %r15, %rdx
callq 0x31c0
movq (%r13), %rcx
leaq 0x220b(%rip), %rdi      # 0xf007
pushq $0x1d
popq %rsi
movq %r15, %rdx
callq 0x31c0
movq (%r13), %rcx
leaq 0x2213(%rip), %rdi      # 0xf025
pushq $0x34
popq %rsi
movq %r15, %rdx
callq 0x31c0
movq (%r13), %rcx
leaq 0x2232(%rip), %rdi      # 0xf05a
pushq $0x2d
popq %rsi
movq %r15, %rdx
callq 0x31c0
movq (%r13), %rcx
leaq 0x224a(%rip), %rdi      # 0xf088
pushq $0x28
popq %rsi
movq %r15, %rdx
callq 0x31c0
movq (%r13), %rcx
leaq 0x225d(%rip), %rdi      # 0xf0b1
pushq $0x21
popq %rsi
movq %r15, %rdx
callq 0x31c0
movq (%r13), %rcx
leaq 0x2269(%rip), %rdi      # 0xf0d3
pushq $0x2b
popq %rsi
movq %r15, %rdx
callq 0x31c0
movq (%r13), %rcx
leaq 0x227f(%rip), %rdi      # 0xf0ff
pushq $0x22
popq %rsi
movq %r15, %rdx
callq 0x31c0
leaq 0xbb6(%rip), %rdi       # 0xda48
leaq -0x2c(%rbp), %r15
movq %r15, %rsi
xorl %eax, %eax
callq 0x3190
movl (%r15), %eax
decl %eax
cmpl $0x6, %eax
ja 0xcf0a
leaq 0x20cf(%rip), %rcx      # 0xef80
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq (%r12), %rsi
leaq -0x8156(%rip), %rcx     # 0x4d6f
movq %rbx, %rdi
xorl %edx, %edx
callq 0x4e25
jmp 0xcf63
leaq 0x7bf5(%rip), %rax      # 0x14ad0
movb $0x0, (%rax)
movq (%r12), %rdx
movq %rbx, %rdi
movq %rdx, %rsi
jmp 0xcf4c
movq (%r12), %rsi
movq %rbx, %rdi
xorl %edx, %edx
xorl %ecx, %ecx
jmp 0xcf03
movq (%r12), %rdx
pushq $0x1
popq %rcx
movq %rbx, %rdi
xorl %esi, %esi
callq 0x8602
jmp 0xcf63
movq (%r13), %rcx
leaq 0x220d(%rip), %rdi      # 0xf122
pushq $0x10
popq %rsi
pushq $0x1
popq %rdx
callq 0x31c0
jmp 0xcf63
movq (%r12), %rsi
leaq -0x62d5(%rip), %rcx     # 0x6c58
movq %rbx, %rdi
xorl %edx, %edx
callq 0x6c6a
jmp 0xcf63
movq (%r12), %rsi
leaq 0xce6c(%rip), %rax      # 0x19db0
movq %rsi, (%rax)
movq %rbx, %rdi
xorl %edx, %edx
xorl %ecx, %ecx
jmp 0xcf5b
pushq $0x2
popq %rcx
movq %rbx, %rdi
movq %r14, %rsi
xorl %edx, %edx
xorl %r8d, %r8d
callq 0xad36
movq (%r13), %rdi
leaq 0xce4a(%rip), %rax      # 0x19db8
movl (%rax), %edx
leaq 0x21bc(%rip), %rsi      # 0xf133
xorl %eax, %eax
callq 0x3130
leaq 0xce37(%rip), %rax      # 0x19dbc
movl (%rax), %edx
testl %edx, %edx
jg 0xcfba
movq 0x7046(%rip), %rax      # 0x13fd8
cmpq (%rax), %rbx
je 0xcf9f
movq %rbx, %rdi
callq 0x30a0
cmpq (%r12), %r14
je 0xcfb3
cmpq (%r13), %r14
je 0xcfb3
movq %r14, %rdi
callq 0x30a0
xorl %eax, %eax
jmp 0xcd49
movq (%r13), %rdi
leaq 0x2179(%rip), %rsi      # 0xf13e
xorl %eax, %eax
callq 0x3130
jmp 0xcf8b