#include "parser.ih"

//         version
//         offset of the string constant-area  (int32_t)
//         offset of the variable area         (int32_t)
//         offset of the strings area          (int32_t)
//         offset of the first instruction     (int32_t)
// 
//         code                                (first byte is first instruction)
//         ascii-z string constant area
//         variables
//         filenames


static int8_t opexit[] = {op_push_0, op_pop_reg, op_exit};
static int8_t opcall = op_call;

int parser_backend()
{
    msg("BEGIN");

    unsigned nErrors = rss_nErrors();

    if (nErrors)                            // backend if no errors 
    {
        printf("\n%u error(s) detected\n", nErrors);
        return 1;
    }

    register int idx;
    BinHeader     hdr;                      // rss/types.ih

    util_setString("main");

    idx = symtab_findFun();

    if (idx == -1)
    {
        util_semantic(sem_noMain);
        exit(1);
    }

    hdr.offset[3] = ftell(gp_bin);           // offset of first instruction 

    p_hiddenFunctions();                     // pmv_patchup generated hidden 
                                            // function calls 

    fseek(gp_bin, 0, SEEK_END);              // upwind to EOF again 

                                            // write global vars initializ. 
                                            // code
    msg("Global vars initialization code length: %d", svCodeLength(&gp_init));
    util_out(gp_bin, svCode(&gp_init), svCodeLength(&gp_init));

    util_out(gp_bin, &opcall, sizeof(int8_t)); // call opcode for main 

    uint16_t addr = symtab_funAddress(idx);    // get main's address   
    util_out(gp_bin, &addr, sizeof(uint16_t)); // write it out         

    util_out(gp_bin, &opexit, sizeof(opexit));

    msg("Version %s, size: %d", version, sizeof(hdr.version));
    memcpy(hdr.version, version, sizeof(hdr.version)); // set the version 

    hdr.offset[0] = ftell(gp_bin);           // here the strings start 

    msg("#strings: %d", ssSize());          // generate the strings 
    for (unsigned idx = 0, size = ssSize(); idx != size; ++idx)
        fprintf(gp_bin, "%s%c", ssStr(idx), 0);

    hdr.offset[1] = ftell(gp_bin);           // here the vars start 
    
    symtab_writeGlobals(gp_bin);             // write the global variables 

    hdr.offset[2] = ftell(gp_bin);           // here the filenames start 

    msg("Scanner filenames: %s", scanner_filenames());
    fputs(scanner_filenames(), gp_bin);

    rewind(gp_bin);                         // stdio.h

                                            // write the offset info 
    util_out(gp_bin, &hdr, sizeof(BinHeader));

    msg("END");

    return 0;
}











