Beispiel #1
0
/* Halt the process similar to op_halt but allow a return code to be specified. If no return code
 * is specified, return code 0 is used as a default (making it identical to op_halt).
 */
int m_zhalt(void)
{
	triple	*triptr;
	oprtype ot;
	int	status;
	DCL_THREADGBL_ACCESS;

	SETUP_THREADGBL_ACCESS;
	/* Let m_halt() handle the case of the missing return code */
	if ((TK_SPACE == TREF(window_token)) || (TK_EOL == TREF(window_token)))
		return m_halt();
	switch (status = expr(&ot, MUMPS_NUM))		/* NOTE assignment */
	{
		case EXPR_FAIL:
			return FALSE;
		case EXPR_GOOD:
			triptr = newtriple(OC_ZHALT);
			triptr->operand[0] = ot;
			return TRUE;
		case EXPR_INDR:
			make_commarg(&ot, indir_zhalt);
			return TRUE;
		default:
			assertpro(FALSE);
	}
	return FALSE; /* This should never get executed, added to make compiler happy */
}
Beispiel #2
0
int m_zattach(void)
{
	oprtype	x;
	triple	*triptr;
	DCL_THREADGBL_ACCESS;

	SETUP_THREADGBL_ACCESS;
	if ((TK_EOL == TREF(window_token)) || (TK_SPACE == TREF(window_token)))
	{
		triptr = newtriple(OC_ZATTACH);
		triptr->operand[0] = put_str("",0);
		return TRUE;
	}
	else
	{
		switch (expr(&x, MUMPS_STR))
		{
		case EXPR_FAIL:
			return FALSE;
		case EXPR_GOOD:
			triptr = newtriple(OC_ZATTACH);
			triptr->operand[0] = x;
			return TRUE;
		case EXPR_INDR:
			make_commarg(&x,indir_zattach);
			return TRUE;
		}
	}
	return FALSE; /* This should never get executed, added to make compiler happy */
}
Beispiel #3
0
int m_zsystem(void)
{
	oprtype	x;
	triple	*triptr;

	if (window_token == TK_EOL || window_token == TK_SPACE)
	{
		triptr = newtriple(OC_ZSYSTEM);
		triptr->operand[0] = put_str("",0);
		return TRUE;
	}
	else
	switch (strexpr(&x))
	{
	case EXPR_FAIL:
		return FALSE;
	case EXPR_GOOD:
		triptr = newtriple(OC_ZSYSTEM);
		triptr->operand[0] = x;
		return TRUE;
	case EXPR_INDR:
		make_commarg(&x,indir_zsystem);
		return TRUE;
	}

	return FALSE; /* This will never get executed, added to make compiler happy */
}
Beispiel #4
0
int m_xecute(void)
{
	oprtype *cr, x;
	triple *obp, *oldchain, *ref0, *ref1, tmpchain, *triptr;
	DCL_THREADGBL_ACCESS;

	SETUP_THREADGBL_ACCESS;
	dqinit(&tmpchain,exorder);
	oldchain = setcurtchain(&tmpchain);
	switch (expr(&x, MUMPS_STR))
	{
	case EXPR_FAIL:
		setcurtchain(oldchain);
		return FALSE;
	case EXPR_INDR:
		if (TK_COLON != TREF(window_token))
		{
			make_commarg(&x,indir_xecute);
			break;
		}
		/* caution: fall through */
	case EXPR_GOOD:
		ref0 = maketriple(OC_COMMARG);
		ref0->operand[0] = x;
		ref0->operand[1] = put_ilit(indir_linetail);
		ins_triple(ref0);
	}
	setcurtchain(oldchain);
	if (TK_COLON == TREF(window_token))
	{
		advancewindow();
		cr = (oprtype *)mcalloc(SIZEOF(oprtype));
		if (!bool_expr(FALSE, cr))
			return FALSE;
		if (TREF(expr_start) != TREF(expr_start_orig))
		{
			triptr = newtriple(OC_GVRECTARG);
			triptr->operand[0] = put_tref(TREF(expr_start));
		}
		obp = oldchain->exorder.bl;
		dqadd(obp,&tmpchain,exorder);		/* violates info hiding */
		if (TREF(expr_start) != TREF(expr_start_orig))
		{
			ref0 = newtriple(OC_JMP);
			ref1 = newtriple(OC_GVRECTARG);
			ref1->operand[0] = put_tref(TREF(expr_start));
			*cr = put_tjmp(ref1);
			tnxtarg(&ref0->operand[0]);
		} else
			tnxtarg(cr);
		return TRUE;
	}
	obp = oldchain->exorder.bl;
	dqadd(obp,&tmpchain,exorder);		/* violates info hiding */
	return TRUE;
}
Beispiel #5
0
int m_zlink(void)
{
	int	rval;
	triple	*ref;
	oprtype	file, quals;

	if (window_token == TK_EOL || window_token == TK_SPACE || window_token == TK_COLON)
	{
		ref = newtriple(OC_SVGET);
		ref->operand[0] = put_ilit(SV_ZSOURCE);
		file = put_tref(ref);
		if (window_token == TK_COLON)
		{
			advancewindow();
			if (!strexpr(&quals))
				return FALSE;
		}
		else
		{
			ref = newtriple(OC_SVGET);
			ref->operand[0] = put_ilit(SV_ZCOMPILE);
			quals = put_tref(ref);
		}
	}
	else
	{
		if (!(rval = strexpr(&file)))
			return FALSE;
		if (window_token != TK_COLON)
		{
			if (rval == EXPR_INDR)
			{
				make_commarg(&file,indir_zlink);
				return TRUE;
			}
			ref = newtriple(OC_SVGET);
			ref->operand[0] = put_ilit(SV_ZCOMPILE);
			quals = put_tref(ref);
		}
		else
		{
			advancewindow();
			if (!strexpr(&quals))
				return FALSE;
		}
	}
	ref = newtriple(OC_ZLINK);
	ref->operand[0] = file;
	ref->operand[1] = quals;
	return TRUE;
}
Beispiel #6
0
int m_quit(void)
{
	int	rval;
	triple	*triptr;
	triple	*r;
	oprtype	x;
	error_def(ERR_QUITARGUSE);
	error_def(ERR_QUITARGLST);

	if (for_stack_ptr == for_stack)
	{
		if (window_token == TK_EOL || window_token == TK_SPACE)
			newtriple((run_time) ? OC_HARDRET : OC_RET);
		else
		{
			if (!(rval = expr(&x)))
				return FALSE;
			if (EXPR_INDR == rval)
			{	/* Indirect argument */
				make_commarg(&x, indir_quit);
				return TRUE;
			}
			r = newtriple(OC_RETARG);
			r->operand[0] = x;
			if (window_token == TK_COMMA)
			{
				stx_error (ERR_QUITARGLST);
				return FALSE;
			}
		}
	} else
	{
		if (window_token == TK_EOL || window_token == TK_SPACE)
		{
			triptr = newtriple(OC_JMP);
			triptr->operand[0] = for_end_of_scope(1);
		} else
		{
			stx_error(ERR_QUITARGUSE);
			return FALSE;
		}
	}
	return TRUE;
}
Beispiel #7
0
int m_write(void)
{
	error_def(ERR_STRINGOFLOW);
	oprtype x,*oprptr;
	mval lit;
	mstr *msp;
	int  lnx;
	char *cp;
	triple *ref, *t1;
	triple *litlst[128], **llptr, **ptx, **ltop;

	llptr = litlst;
	ltop = 0;
	*llptr = 0;
	for (;;)
	{
		devctlexp = FALSE;
		switch(window_token)
		{
		case TK_ASTERISK:
			advancewindow();
			if (!intexpr(&x))
				return FALSE;
			assert(x.oprclass == TRIP_REF);
			ref = newtriple(OC_WTONE);
			ref->operand[0] = x;
			STO_LLPTR((x.oprval.tref->opcode == OC_ILIT) ? ref : 0);
			break;
		case TK_QUESTION:
		case TK_EXCLAIMATION:
		case TK_HASH:
		case TK_SLASH:
			if (!rwformat())
				return FALSE;
			STO_LLPTR(0);
			break;
		default:
			switch (strexpr(&x))
			{
			case EXPR_FAIL:
				return FALSE;
			case EXPR_GOOD:
				assert(x.oprclass == TRIP_REF);
				if (devctlexp)
				{
					ref = newtriple(OC_WRITE);
					ref->operand[0] = x;
					STO_LLPTR(0);
				} else if (x.oprval.tref->opcode == OC_CAT)
				{
					wrtcatopt(x.oprval.tref,&llptr,LITLST_TOP);
				} else
				{
					ref = newtriple(OC_WRITE);
					ref->operand[0] = x;
					STO_LLPTR((x.oprval.tref->opcode == OC_LIT) ? ref : 0);
				}
				break;
			case EXPR_INDR:
				make_commarg(&x,indir_write);
				STO_LLPTR(0);
				break;
			default:
				assert(FALSE);
			}
			break;
		}
		if (window_token != TK_COMMA)
			break;
		advancewindow();
		if (llptr >= LITLST_TOP)
		{
			*++llptr = 0;
			ltop = llptr;
			llptr = 0;
		}
	}
	STO_LLPTR(0);
	if (ltop)
		llptr = ltop;
	for (ptx = litlst ; ptx < llptr ; ptx++)
	{
		if (*ptx && *(ptx + 1))
		{
			lit.mvtype = MV_STR;
			lit.str.addr = cp = (char * ) stringpool.free;
			for (t1 = ref = *ptx++ ; ref ; ref = *ptx++)
			{
				if (ref->opcode == OC_WRITE)
				{
					msp = &(ref->operand[0].oprval.tref->operand[0].oprval.mlit->v.str);
					lnx = msp->len;
					if ( cp + lnx > (char *) stringpool.top)
					{	stx_error(ERR_STRINGOFLOW);
						return FALSE;
					}
					memcpy(cp, msp->addr, lnx);
					cp += lnx;
				}
				else
				{
					assert(ref->opcode == OC_WTONE);
					if (cp + 1 > (char *) stringpool.top)
					{	stx_error(ERR_STRINGOFLOW);
						return FALSE;
					}
					*cp++ = ref->operand[0].oprval.tref->operand[0].oprval.ilit;
				}
				ref->operand[0].oprval.tref->opcode = OC_NOOP;
				ref->opcode = OC_NOOP;
				ref->operand[0].oprval.tref->operand[0].oprclass = OC_NOOP;
				ref->operand[0].oprclass = 0;
			}
			ptx--;
			stringpool.free = (unsigned char *) cp;
			lit.str.len = INTCAST(cp - lit.str.addr);
			s2n(&lit);
			t1->opcode = OC_WRITE;
			t1->operand[0] = put_lit(&lit);
		}
	}
	return TRUE;
}
Beispiel #8
0
int m_write(void)
{
	char	*cp;
	int	lnx;
	mval	lit;
	mstr	*msp;
	oprtype	*oprptr, x;
	triple	*litlst[128], **llptr, **ltop, **ptx, *ref, *t1;
	DCL_THREADGBL_ACCESS;

	SETUP_THREADGBL_ACCESS;
	llptr = litlst;
	ltop = 0;
	*llptr = 0;
	for (;;)
	{
		devctlexp = FALSE;
		switch (TREF(window_token))
		{
		case TK_ASTERISK:
			advancewindow();
			if (EXPR_FAIL == expr(&x, MUMPS_INT))
				return FALSE;
			assert(TRIP_REF == x.oprclass);
			ref = newtriple(OC_WTONE);
			ref->operand[0] = x;
			STO_LLPTR((OC_ILIT == x.oprval.tref->opcode) ? ref : 0);
			break;
		case TK_QUESTION:
		case TK_EXCLAIMATION:
		case TK_HASH:
		case TK_SLASH:
			if (!rwformat())
				return FALSE;
			STO_LLPTR(0);
			break;
		default:
			switch (expr(&x, MUMPS_STR))
			{
			case EXPR_FAIL:
				return FALSE;
			case EXPR_GOOD:
				assert(TRIP_REF == x.oprclass);
				if (devctlexp)
				{
					ref = newtriple(OC_WRITE);
					ref->operand[0] = x;
					STO_LLPTR(0);
				} else if (x.oprval.tref->opcode == OC_CAT)
					wrtcatopt(x.oprval.tref, &llptr, LITLST_TOP);
				else
				{
					ref = newtriple(OC_WRITE);
					ref->operand[0] = x;
					STO_LLPTR((OC_LIT == x.oprval.tref->opcode) ? ref : 0);
				}
				break;
			case EXPR_INDR:
				make_commarg(&x, indir_write);
				STO_LLPTR(0);
				break;
			default:
				assert(FALSE);
			}
			break;
		}
		if (TK_COMMA != TREF(window_token))
			break;
		advancewindow();
		if (LITLST_TOP <= llptr)
		{
			*++llptr = 0;
			ltop = llptr;
			llptr = 0;
		}
	}
	STO_LLPTR(0);
	if (ltop)
		llptr = ltop;
	for (ptx = litlst ; ptx < llptr ; ptx++)
	{
		if (*ptx && *(ptx + 1))
		{
			lit.mvtype = MV_STR;
			lit.str.addr = cp = (char *)stringpool.free;
			CLEAR_MVAL_BITS(&lit);
			for (t1 = ref = *ptx++ ; ref ; ref = *ptx++)
			{
				if (OC_WRITE == ref->opcode)
				{
					msp = &(ref->operand[0].oprval.tref->operand[0].oprval.mlit->v.str);
					lnx = msp->len;
					ENSURE_STP_FREE_SPACE(lnx);
					memcpy(cp, msp->addr, lnx);
					cp += lnx;
				} else
				{
					assert(OC_WTONE == ref->opcode);
					ENSURE_STP_FREE_SPACE(1);
					*cp++ = ref->operand[0].oprval.tref->operand[0].oprval.ilit;
				}
				ref->operand[0].oprval.tref->opcode = OC_NOOP;
				ref->opcode = OC_NOOP;
				ref->operand[0].oprval.tref->operand[0].oprclass = NO_REF;
				ref->operand[0].oprclass = NO_REF;
			}
			ptx--;
			stringpool.free = (unsigned char *) cp;
			lit.str.len = INTCAST(cp - lit.str.addr);
			t1->opcode = OC_WRITE;
			t1->operand[0] = put_lit(&lit);
		}
	}
	return TRUE;
}
Beispiel #9
0
int m_zgoto(void)
{
	triple		tmpchain, *oldchain, *obp, *ref0, *ref1, *triptr;
	oprtype		*cr, quits;
	int4		rval;
	DCL_THREADGBL_ACCESS;

	SETUP_THREADGBL_ACCESS;
	dqinit(&tmpchain, exorder);
	oldchain = setcurtchain(&tmpchain);
	if ((TK_EOL == window_token) || (TK_SPACE == window_token))
	{	/* Default zgoto level is 1 */
		quits = put_ilit(1);
		rval = EXPR_GOOD;
	} else if (!(rval = intexpr(&quits)))		/* note assignment */
	{
		setcurtchain(oldchain);
		return FALSE;
	}
	if ((EXPR_INDR != rval) && ((TK_EOL == window_token) || (TK_SPACE == window_token)))
	{	/* Only level parm supplied (no entry ref) - job for op_zg1 */
		setcurtchain(oldchain);
		obp = oldchain->exorder.bl;
		dqadd(obp, &tmpchain, exorder);		/* this is a violation of info hiding */
		ref0 = newtriple(OC_ZG1);
		ref0->operand[0] = quits;
		return TRUE;
	}
	if (TK_COLON != window_token)
	{	/* First arg parsed, not ending in ":". Better have been indirect */
		setcurtchain(oldchain);
		if (EXPR_INDR != rval)
		{
			stx_error(ERR_COLON);
			return FALSE;
		}
		make_commarg(&quits, indir_zgoto);
		obp = oldchain->exorder.bl;
		dqadd(obp, &tmpchain, exorder);		/* this is a violation of info hiding */
	 	return TRUE;
	}
	advancewindow();
	if (TK_COLON != window_token)
	{
		if (!entryref(OC_NOOP, OC_PARAMETER, (mint)indir_goto, FALSE, FALSE, TRUE))
		{
			setcurtchain(oldchain);
			return FALSE;
		}
		ref0 = maketriple(OC_ZGOTO);
		ref0->operand[0] = quits;
		ref0->operand[1] = put_tref(tmpchain.exorder.bl);
		ins_triple(ref0);
		setcurtchain(oldchain);
	} else
	{
		ref0 = maketriple(OC_ZG1);
		ref0->operand[0] = quits;
		ins_triple(ref0);
		setcurtchain(oldchain);
	}
	if (TK_COLON == window_token)
	{	/* post conditional expression */
		advancewindow();
		cr = (oprtype *)mcalloc(SIZEOF(oprtype));
		if (!bool_expr((bool)FALSE, cr))
			return FALSE;
		if (TREF(expr_start) != TREF(expr_start_orig))
		{
			triptr = newtriple(OC_GVRECTARG);
			triptr->operand[0] = put_tref(TREF(expr_start));
		}
		obp = oldchain->exorder.bl;
		dqadd(obp, &tmpchain, exorder);		 /* this is a violation of info hiding */
		if (TREF(expr_start) != TREF(expr_start_orig))
		{
			ref0 = newtriple(OC_JMP);
			ref1 = newtriple(OC_GVRECTARG);
			ref1->operand[0] = put_tref(TREF(expr_start));
			*cr = put_tjmp(ref1);
			tnxtarg(&ref0->operand[0]);
		} else
			tnxtarg(cr);
		return TRUE;
	}
	obp = oldchain->exorder.bl;
	dqadd(obp, &tmpchain, exorder);			/* this is a violation of info hiding */
	return TRUE;
}