Ejemplo n.º 1
0
int vm(Pu *L)
{
	int ret = 0;
	for (;;)
	{
		PuType tp = TOKEN.type;
		if (tp == FINISH)
		{
			ret = 0;
			break;
		}

		if (L->isyield)
		{
			ret = -2;
			break;
		}
		
		if (L->isquit)
		{
			ret = -1;
			break;
		}
		switch (tp)
		{
		case WHILE:
			whilet(L, &TOKEN);
			break;
		case IF:
			ift(L, &TOKEN);
			break;
		case OP:
			procop(L);
			break;
		case GOTO:
			gotot(L);
			break;
		case FUNCTION:
			regfunc(L);
			break;
		case RETURN:{
			NEXT_TOKEN;
			L->isreturn = true;
            const __pu_value *expresult = exp(L);
            if (!expresult || expresult->type() == UNKNOWN)            
            {
                QUIT_SCRIPT;
                break;
            }
			L->return_value = *expresult;
			ret = 1;
            goto END_VM;}
		case INCLUDE:
			NEXT_TOKEN;
			NEXT_TOKEN;
			break;
		case ELSE:
		case ELIF:
		case BREAK:
		case CONTINUE:
		case END:
			ret = 1;
			goto END_VM;
		default:
			exp(L);
			break;
		}
	}
END_VM:
	DO_GC;
	return ret;
}
Ejemplo n.º 2
0
/* process changes to resource file (or just list it) */
static opdef *rscproc(osfildef *fp, osfildef *fpout, opdef *oplist)
{
    char   buf[128];
    ulong  siz;
    char   datebuf[27];
    ulong  endpos;
    uchar  nambuf[40];
    uint   rsiz;
    opdef *op;
    int    copyrsc;
    ulong  startpos;
    uint   endpos_ofs;
    ulong  first_xfcn = 0;
    ulong  extcnt_pos = 0;
    int    found_user_rsc = FALSE;
    int    showed_heading = FALSE;
    int    found_htmlres = FALSE;
    char  *file_type;

    /* 
     *   if we're reading an existing file, check it header; otherwise,
     *   write out a brand new file header 
     */
    if (fp != 0)
    {
        /* 
         *   the input file exists -- check file and version headers, and
         *   get flags and timestamp 
         */
        if (osfrb(fp, buf, (int)(sizeof(FIOFILHDR) + sizeof(FIOVSNHDR) + 2)))
            listexit(fp, "error reading file header");

        /* check the file type */
        if (memcmp(buf, FIOFILHDR, sizeof(FIOFILHDR)) == 0)
            file_type = "game";
        else if (memcmp(buf, FIOFILHDRRSC, sizeof(FIOFILHDRRSC)) == 0)
            file_type = "resource";
        else
            listexit(fp, "invalid resource file header");

        /* check the version header */
        if (memcmp(buf + sizeof(FIOFILHDR), FIOVSNHDR, sizeof(FIOVSNHDR))
            && memcmp(buf + sizeof(FIOFILHDR), FIOVSNHDR2, sizeof(FIOVSNHDR2))
            && memcmp(buf + sizeof(FIOFILHDR), FIOVSNHDR3, sizeof(FIOVSNHDR3)))
            listexit(fp, "incompatible resource file version");

        /* get the timestamp */
        if (osfrb(fp, datebuf, (size_t)26))
            listexit(fp, "error reading file");
        datebuf[26] = '\0';
    }
    else
    {
        struct tm  *tblock;
        time_t      timer;

        /* construct a new file header */
        memcpy(buf, FIOFILHDRRSC, sizeof(FIOFILHDRRSC));
        memcpy(buf + sizeof(FIOFILHDR), FIOVSNHDR, sizeof(FIOVSNHDR));

        /* clear the flags */
        oswp2(buf + sizeof(FIOFILHDR) + sizeof(FIOVSNHDR), 0);

        /* construct the timestamp */
        timer = time(0);
        tblock = localtime(&timer);
        strcpy(datebuf, asctime(tblock));
    }
        
    if (fpout)
    {
        if (osfwb(fpout, buf,
                  (int)(sizeof(FIOFILHDR) + sizeof(FIOVSNHDR) + 2))
            || osfwb(fpout, datebuf, (size_t)26))
            listexit(fp, "error writing header");
    }

    /* if listing, show file creation timestamp */
    if (fpout == 0)
        rscptf("\n"
               "File type:     TADS %s file\n"
               "Date compiled: %s\n", file_type, datebuf);

    /*
     *   Process the input file, if there is one 
     */
    for ( ; fp != 0 ; )
    {
        /* assume this resource will be copied to the output */
        copyrsc = TRUE;

        startpos = osfpos(fp);
        if (osfrb(fp, buf, 1)
            || osfrb(fp, buf + 1, (int)(buf[0] + 4)))
            listexit(fp, "error reading file");

        memcpy(nambuf, buf + 1, (size_t)buf[0]);
        nambuf[buf[0]] = '\0';
        
        endpos_ofs = 1 + buf[0];
        endpos = osrp4(buf + endpos_ofs);
        siz = endpos - startpos;
        
        /* see what kind of resource we have, and do the right thing */
        if (!strcmp((char *)nambuf, "$EOF"))
        {
            /* end of file marker - quit here */
            break;
        }
        else if (!strcmp((char *)nambuf, "HTMLRES"))
        {
            /* if we've already found an HTMLRES list, it's an error */
            if (found_htmlres)
            {
                rscptf("error: multiple HTMLRES maps found in file\n"
                       " -- redundant entries have been deleted.\n");
                copyrsc = FALSE;
            }
            else
            {
                /* go process it */
                oplist = prochtmlres(fp, fpout, oplist, &copyrsc,
                                     &showed_heading, TRUE);
            }

            /* note that we've found a resource */
            found_user_rsc = TRUE;
            found_htmlres = TRUE;
        }
        else if (!strcmp((char *)nambuf, "EXTCNT"))
        {
            /* place to write start of XFCN's? */
            if (siz >= 17 && fpout)
                extcnt_pos = osfpos(fpout);
        }
        else if (!strcmp((char *)nambuf, "XFCN"))
        {
            if (osfrb(fp, buf, 3) || osfrb(fp, buf + 3, (int)buf[2]))
                listexit(fp, "error reading file");
            rsiz = osrp2(buf);
            buf[3 + buf[2]] = '\0';

            if (fpout)
            {
                /* see if this resource is in the list */
                for (op = oplist ; op ; op = op->opnxt)
                {
                    if (!(op->opflag & OPFDONE)
                        && op->oprestype == RESTYPE_XFCN
                        && !stricmp((char *)buf + 3, op->opres))
                    {
                        /* note that this resource has now been processed */
                        op->opflag |= OPFDONE;

                        /* 
                         *   if it's already here, and we're not deleting
                         *   it, warn that the old one will stay around 
                         */
                        if (!(op->opflag & OPFDEL))
                        {
                            /* warn that we're going to ignore it */
                            rscptf("warning: XFCN resource \"%s\" already in "
                                   "file\n -- the old resource will be kept "
                                   "(use -replace to replace it)\n",
                                   op->opres);

                            /* don't add it */
                            op->opflag &= ~OPFADD;
                        }
                        else
                        {
                            /* 
                             *   we're deleting this resource; if adding
                             *   it back in (i.e., replacing it), process
                             *   the add operation now 
                             */
                            if (op->opflag & OPFADD)
                            {
                                /* show what we're doing */
                                show_op("replacing", op->opres,
                                        strlen(op->opres), op->oprestype);

                                /* 
                                 *   add the external file, replacing the
                                 *   one in the input file 
                                 */
                                procop(fpout, op, &first_xfcn);
                            }
                            else
                            {
                                /* note that we're deleting it */
                                show_op("deleting", op->opres,
                                        strlen(op->opres), op->oprestype);
                            }

                            /* don't copy the one out of the file */
                            copyrsc = FALSE;
                        }
                        break;
                    }
                }
            }
            else
            {
                /* no output file - just list the resource */
                show_list_item(&showed_heading, "XFCN",
                               (ulong)rsiz, buf + 3, (size_t)buf[2]);
            }

            /* note that we've found a user resource */
            found_user_rsc = TRUE;
        }
        
        if (fpout != 0 && copyrsc)
        {
            osfseek(fp, startpos, OSFSK_SET);
            copyres(fp, fpout, siz, endpos_ofs);
        }
        
        /* skip to the next resource */
        osfseek(fp, endpos, OSFSK_SET);
    }
    
    /* add the HTML resources if we haven't already */
    if (!found_htmlres)
        oplist = prochtmlres(fp, fpout, oplist, &copyrsc,
                             &showed_heading, FALSE);

    /* now go through what's left, and add new non-HTML resources */
    if (fpout != 0)
    {
        for (op = oplist ; op != 0 ; op = op->opnxt)
        {
            if (!(op->opflag & OPFDONE) && (op->opflag & OPFADD)
                && op->oprestype != RESTYPE_HTML)
            {
                /* show what we're doing */
                show_op("adding", op->opres,
                        strlen(op->opres), op->oprestype);

                /* add the file */
                procop(fpout, op, &first_xfcn);

                /* mark the operation as completed */
                op->opflag |= OPFDONE;
            }
        }
    }

    /* if just listing, and we didn't find anything, tell the user so */
    if (fpout == 0 && !found_user_rsc)
        rscptf("No user resources found.\n");

    /* done reading the file - finish it up */
    if (fpout != 0)
    {
        /* write EOF resource */
        if (osfwb(fpout, "\004$EOF\0\0\0\0", 9))
            errexit("error writing resource", 1);

        /* write first_xfcn value to EXTCNT resource */
        if (extcnt_pos)
        {
            osfseek(fpout, extcnt_pos + 13, OSFSK_SET);
            oswp4(buf, first_xfcn);
            osfwb(fpout, buf, 4);
        }
    }

    /* 
     *   return the final oplist (it may have been changed during
     *   processing) 
     */
    return oplist;
}