home *** CD-ROM | disk | FTP | other *** search
- /*
- * File: lmisc.c
- * Contents: create, keywd, limit, llist
- */
-
- #include "../h/config.h"
- #include "../h/rt.h"
- #include "rproto.h"
- #include "../h/keyword.h"
- #include "../h/version.h"
-
-
-
- /*
- * create - return an entry block for a co-expression.
- */
-
- OpBlock(create,1,"create",0)
-
- Ocreate(entryp, cargp)
- word *entryp;
- register dptr cargp;
- {
-
- #ifdef Coexpr
- register struct b_coexpr *sblkp;
- register struct b_refresh *rblkp;
- register dptr dp, ndp, dsp;
- register word *newsp;
- int na, nl, i;
- struct b_proc *cproc;
-
- /*
- * Get a new co-expression stack and initialize.
- */
- if ((sblkp = alccoexp()) == NULL)
- RunErr(0, NULL);
-
- /*
- * Icon stack starts at word after co-expression stack block. C stack
- * starts at end of stack region on machines with down-growing C stacks
- * and somewhere in the middle of the region.
- *
- * The C stack is aligned on a doubleword boundary. For upgrowing
- * stacks, the C stack starts in the middle of the stack portion
- * of the static block. For downgrowing stacks, the C stack starts
- * at the end of the static block.
- */
- newsp = (word *)((char *)sblkp + sizeof(struct b_coexpr));
-
- #ifdef UpStack
- sblkp->cstate[0] =
- ((word)((char *)sblkp + (stksize - sizeof(*sblkp))/2)
- &~(WordSize*StackAlign-1));
- #else /* UpStack */
- sblkp->cstate[0] =
- ((word)((char *)sblkp + stksize - WordSize)&~(WordSize*StackAlign-1));
- #endif /* UpStack */
-
- #ifdef CoProcesses
- sblkp->cstate[1] = 0;
- #endif
-
-
- sblkp->es_argp = (dptr )newsp;
- /*
- * Calculate number of arguments and number of local variables.
- * na is nargs + 1 to include Arg0.
- */
- na = pfp->pf_nargs + 1;
- cproc = (struct b_proc *)BlkLoc(argp[0]);
- nl = (int)cproc->ndynam;
-
- /*
- * Get a refresh block for the new co-expression.
- */
- if (blkreq((word)sizeof(struct b_refresh) +
- (na + nl) * sizeof(struct descrip)) == Error)
- RunErr(0, NULL);
- rblkp = alcrefresh(entryp, na, nl);
- sblkp->freshblk.dword = D_Refresh;
- BlkLoc(sblkp->freshblk) = (union block *) rblkp;
-
- /*
- * Copy current procedure frame marker into refresh block.
- */
- rblkp->pfmkr = *pfp;
- rblkp->pfmkr.pf_pfp = 0;
-
- /*
- * Copy arguments into refresh block and onto new stack.
- */
- dp = &argp[0];
- ndp = &rblkp->elems[0];
- dsp = (dptr)newsp;
- for (i = 1; i <= na; i++) {
- *dsp++ = *dp;
- *ndp++ = *dp++;
- }
-
- /*
- * Copy procedure frame to new stack and point dsp to word after frame.
- */
- *((struct pf_marker *)dsp) = *pfp;
- sblkp->es_pfp = (struct pf_marker *)dsp;
- sblkp->es_pfp->pf_pfp = 0;
- dsp = (dptr)((word *)dsp + Vwsizeof(*pfp));
- sblkp->es_ipc.opnd = entryp;
- sblkp->es_gfp = 0;
- sblkp->es_efp = 0;
- sblkp->es_ilevel = 0;
- sblkp->tvalloc = NULL;
-
- /*
- * Copy locals to new stack and refresh block.
- */
- dp = &(pfp->pf_locals)[0];
- for (i = 1; i <= nl; i++) {
- *dsp++ = *dp;
- *ndp++ = *dp++;
- }
- /*
- * Push two null descriptors on the stack.
- */
- *dsp++ = nulldesc;
- *dsp++ = nulldesc;
-
- sblkp->es_sp = (word *)dsp - 1;
-
- /*
- * Return the new co-expression.
- */
- Arg0.dword = D_Coexpr;
- BlkLoc(Arg0) = (union block *) sblkp;
- Return;
- #else /* Coexpr */
- RunErr(-401, NULL);
- #endif /* Coexpr */
-
- }
-
- /*
- * keywd - process keyword.
- */
-
- char *feattab[] = {
- #if AMIGA
- "Amiga",
- #endif /* AMIGA */
- #if ARM
- "Acorn Archimedes",
- #endif /* ARM */
- #if ATARI_ST
- "Atari ST",
- #endif /* ATARI_ST */
- #if VM
- "CMS",
- #endif /* VM */
- #if HIGHC_386
- "MS-DOS/386",
- #endif /* HIGHC_386 */
- #if MACINTOSH
- "Macintosh",
- #endif /* MACINTOSH */
- #if MSDOS
- "MS-DOS",
- #endif /* MSDOS */
- #if MVS
- "MVS",
- #endif /* MVS */
- #if OS2
- "OS/2",
- #endif /* OS2 */
- #if PORT
- "PORT",
- #endif /* PORT */
- #if UNIX
- "UNIX",
- #endif /* VM */
- #if VMS
- "VMS",
- #endif /* VMS */
- #if !EBCDIC
- "ASCII",
- #else /* EBCDIC */
- "EBCDIC",
- #endif /* EBCDIC */
- #ifdef IconCalling
- "calling to Icon",
- #endif /* IconCalling */
- #ifdef Coexpr
- "co-expressions",
- #endif /* Coexpr */
- #ifdef Header
- "direct execution",
- #endif /* Header */
- #ifdef EnvVars
- "environment variables",
- #endif /* EnvVars */
- #ifdef TraceBack
- "error trace back",
- #endif /* TraceBack */
- #ifdef EvalTrace
- "evaluation tracing",
- #endif /* EvalTrace */
- #ifdef ExecImages
- "executable images",
- #endif /* ExecImages */
- #ifndef FixedRegions
- "expandable regions",
- #endif /* FixedRegions */
- #ifdef ExternalFunctions
- "external functions",
- #endif /* ExternalFunctions */
- #ifdef FixedRegions
- "fixed regions",
- #endif /* FixedRegions */
- #ifdef KeyboardFncs
- "keyboard functions",
- #endif /* KeyboardFncs */
- #ifdef LargeInts
- "large integers",
- #endif /* LargeInts */
- #ifdef MathFncs
- "math functions",
- #endif /* MathFncs */
- #ifdef MemMon
- "memory monitoring",
- #endif /* MEMMON */
- #ifdef Pipes
- "pipes",
- #endif /* Pipes */
- #ifdef RecordIO
- "record I/O",
- #endif /* RecordIO */
- #ifdef StrInvoke
- "string invocation",
- #endif /* StrInvoke */
- #ifdef SystemFnc
- "system function",
- #endif /* SystemFnc */
- #ifdef DosFncs
- "MS-DOS extensions",
- #endif /* DosFncs */
- #ifdef ArmFncs
- "Archimedes extensions",
- #endif /* ArmFncs */
- ""
- };
-
- LibDcl(keywd,0,"&keywd")
- {
- register int hour;
- register word i;
- register char *merid;
- char **p;
- char sbuf[MaxCvtLen];
- extern word coll_stat, coll_str, coll_blk, coll_tot;
- long runtim;
- struct cal_time ct;
-
- #if MACINTOSH && MPW
- /* #pragma unused(nargs) */
- #endif /* MACINTOSH && MPW */
-
- /*
- * This is just plug and chug code. For whatever keyword is desired,
- * the appropriate value is dug out of the system and made into
- * a suitable Icon value.
- *
- * A few special cases are worth noting:
- * &pos, &random, &trace - built-in trapped variables are returned
- */
- switch ((int)IntVal(Arg0)) {
- case K_ASCII:
- Arg0.dword = D_Cset;
- BlkLoc(Arg0) = (union block *) &k_ascii;
- break;
- case K_CLOCK:
- if (strreq((word)8) == Error)
- RunErr(0, NULL);
- getitime(&ct);
- sprintf(sbuf,"%02d:%02d:%02d", ct.hour, ct.minute, ct.second);
- StrLen(Arg0) = 8;
- StrLoc(Arg0) = alcstr(sbuf,(word)8);
- break;
- case K_COLLECTIONS:
- MakeInt(coll_tot, &Arg0);
- Suspend;
- MakeInt(coll_stat, &Arg0);
- Suspend;
- MakeInt(coll_str, &Arg0);
- Suspend;
- MakeInt(coll_blk, &Arg0);
- Return;
-
-
- case K_CSET:
- Arg0.dword = D_Cset;
- BlkLoc(Arg0) = (union block *) &k_cset;
- break;
- case K_CURRENT:
- Arg0 = k_current;
- break;
- case K_DATE:
- if (strreq((word)10) == Error)
- RunErr(0, NULL);
- getitime(&ct);
- sprintf(sbuf, "%04d/%02d/%02d", ct.year, ct.month_no, ct.mday);
- StrLen(Arg0) = 10;
- StrLoc(Arg0) = alcstr(sbuf,(word)10);
- break;
- case K_DATELINE:
- getitime(&ct);
- if ((hour = ct.hour) >= 12) {
- merid = "pm";
- if (hour > 12)
- hour -= 12;
- }
- else {
- merid = "am";
- if (hour < 1)
- hour += 12;
- }
- sprintf(sbuf, "%s, %s %d, %d %d:%02d %s", ct.wday, ct.month_nm,
- ct.mday, ct.year, hour, ct.minute, merid);
- if (strreq(i = strlen(sbuf)) == Error)
- RunErr(0, NULL);
- StrLen(Arg0) = i;
- StrLoc(Arg0) = alcstr(sbuf, i);
- break;
- case K_DIGITS:
- Arg0.dword = D_Cset;
- BlkLoc(Arg0) = (union block *)&k_digits;
- break;
-
-
- case K_ERROR:
- Arg0.dword = D_Tvkywd;
- BlkLoc(Arg0) = (union block *)&tvky_err;
- break;
-
- case K_ERRORNUMBER:
- if (k_errornumber == 0)
- Fail;
- MakeInt((k_errornumber > 0 ? k_errornumber : -k_errornumber), &Arg0);
- break;
- case K_ERRORTEXT:
- if (k_errornumber == 0)
- Fail;
- StrLoc(Arg0) = k_errortext;
- StrLen(Arg0) = strlen(k_errortext);
- break;
- case K_ERRORVALUE:
- if (k_errornumber <= 0)
- Fail;
- Arg0 = k_errorvalue;
- break;
- case K_ERROUT:
- Arg0.dword = D_File;
- BlkLoc(Arg0) = (union block *)&k_errout;
- break;
- case K_FEATURES:
- p = feattab;
- for(;;) {
- StrLen(Arg0) = strlen(*p);
- if (StrLen(Arg0) == 0)
- Fail;
- StrLoc(Arg0) = *p;
- Suspend;
- p++;
- }
- case K_FILE:
- StrLoc(Arg0) = findfile(ipc.opnd);
- StrLen(Arg0) = strlen(StrLoc(Arg0));
- break;
-
-
- case K_HOST:
- iconhost(sbuf);
- if (strreq(i = strlen(sbuf)) == Error)
- RunErr(0, NULL);
- StrLen(Arg0) = i;
- StrLoc(Arg0) = alcstr(sbuf, i);
- break;
- case K_INPUT:
- Arg0.dword = D_File;
- BlkLoc(Arg0) = (union block *)&k_input;
- break;
- case K_LCASE:
- Arg0.dword = D_Cset;
- BlkLoc(Arg0) = (union block *)&k_lcase;
- break;
- case K_LETTERS:
- Arg0.dword = D_Cset;
- BlkLoc(Arg0) = (union block *)&k_letters;
- break;
- case K_LEVEL:
- MakeInt(k_level, &Arg0);
- break;
- case K_LINE:
- MakeInt(findline(ipc.opnd), &Arg0);
- break;
- case K_MAIN:
- Arg0 = k_main;
- break;
- case K_OUTPUT:
- Arg0.dword = D_File;
- BlkLoc(Arg0) = (union block *)&k_output;
- break;
- case K_POS:
- Arg0.dword = D_Tvkywd;
- BlkLoc(Arg0) = (union block *) &tvky_pos;
- break;
- case K_RANDOM:
- Arg0.dword = D_Tvkywd;
- BlkLoc(Arg0) = (union block *) &tvky_ran;
- break;
- case K_REGIONS:
-
- #ifdef FixedRegions
- Arg0 = zerodesc;
- #else /* FixedRegions */
- MakeInt(DiffPtrs(statend,statbase) - mstksize, &Arg0);
- #endif /* FixedRegions */
-
- Suspend;
- MakeInt(DiffPtrs(strend,strbase), &Arg0);
- Suspend;
- MakeInt(DiffPtrs(blkend,blkbase), &Arg0);
- Return;
-
- case K_SOURCE:
-
- #ifndef Coexpr
- Arg(0) = k_main;
- #else /* Coexpr */
- Arg0.dword = D_Coexpr;
- BlkLoc(Arg0) =
- (union block *)topact((struct b_coexpr *)BlkLoc(k_current));
- #endif /* Coexpr */
-
- break;
- case K_STORAGE:
-
- #ifdef FixedRegions
- Arg0 = zerodesc;
- #else /* FixedRegions */
- MakeInt(DiffPtrs(statfree,statbase) - mstksize, &Arg0);
- #endif /* FixedRegions */
-
- Suspend;
- MakeInt(DiffPtrs(strfree,strbase), &Arg0);
- Suspend;
- MakeInt(DiffPtrs(blkfree,blkbase), &Arg0);
- Return;
- case K_SUBJECT:
- Arg0.dword = D_Tvkywd;
- BlkLoc(Arg0) = (union block *) &tvky_sub;
- break;
- case K_TIME:
- runtim = millisec();
- MakeInt(runtim, &Arg0);
- break;
- case K_TRACE:
- Arg0.dword = D_Tvkywd;
- BlkLoc(Arg0) = (union block *)&tvky_trc;
- break;
- case K_UCASE:
- Arg0.dword = D_Cset;
- BlkLoc(Arg0) = (union block *)&k_ucase;
- break;
- case K_VERSION:
- if (strreq(i = strlen(Version)) == Error)
- RunErr(0, NULL);
- StrLen(Arg0) = i;
- StrLoc(Arg0) = Version;
- break;
- default:
- syserr("keyword: unknown keyword type.");
- }
- Return;
- }
-
-
- /*
- * limit - explicit limitation initialization.
- */
-
-
- #ifdef WATERLOO_C_V3_0
- struct b_iproc Blimit = {
- T_Proc,
- Vsizeof(struct b_proc),
- Olimit,
- 2,
- -1,
- 0,
- 0,
- {sizeof(BackSlash)-1,BackSlash}}; Olimit(nargs,cargp,sptr) register dptr cargp;
- #else /* WATERLOO_C_V3_0 */
- LibDcl(limit,2,BackSlash)
- #endif /* WATERLOO_C_V3_0 */
-
- {
-
- #if MACINTOSH
- #if MPW
- /* #pragma unused(nargs) */
- #endif /* MPW */
- #endif /* MACINTOSH */
-
- /*
- * The limit is both passed and returned in Arg0. The limit must
- * be an integer. If the limit is 0, the expression being evaluated
- * fails. If the limit is < 0, it is an error. Note that the
- * result produced by limit is ultimately picked up by the lsusp
- * function.
- */
- if (DeRef(Arg0) == Error)
- RunErr(0, NULL);
-
- switch (cvint(&Arg0)) {
-
- case T_Integer:
- break;
-
- default:
- RunErr(101, &Arg0);
- }
-
- if (IntVal(Arg0) < 0)
- RunErr(205, &Arg0);
- if (IntVal(Arg0) == 0)
- Fail;
- Return;
- }
-
-
- /*
- * [ ... ] - create an explicitly specified list.
- */
-
- LibDcl(llist,-1,"[...]")
- {
- register word i;
- register struct b_list *hp;
- register struct b_lelem *bp;
- word nslots;
-
- nslots = nargs;
- if (nslots == 0)
- nslots = MinListSlots;
-
- if (blkreq((word)sizeof(struct b_list) + sizeof(struct b_lelem) +
- nslots * sizeof(struct descrip)) == Error)
- RunErr(0, NULL);
-
- /*
- * Allocate the list and a list block.
- */
- hp = alclist((word)nargs);
- bp = alclstb(nslots, (word)0, (word)nargs);
-
- /*
- * Make the list block just allocated into the first and last blocks
- * for the list.
- */
- hp->listhead = hp->listtail = (union block *)bp;
- /*
- * Dereference each argument in turn and assign it to a list element.
- */
- for (i = 1; i <= nargs; i++) {
- if (DeRef(Arg(i)) == Error)
- RunErr(0, NULL);
- bp->lslots[i-1] = Arg(i);
- }
- /*
- * Point Arg0 at the new list and return it.
- */
- ArgType(0) = D_List;
- Arg(0).vword.bptr = (union block *)hp;
- Return;
- }
-