2012-02-05 11:35:58 -05:00
|
|
|
/****************************************************************
|
|
|
|
* *
|
2024-07-19 11:43:27 -04:00
|
|
|
* Copyright 2001, 2013 Fidelity Information Services, Inc *
|
2012-02-05 11:35:58 -05:00
|
|
|
* *
|
|
|
|
* This source code contains the intellectual property *
|
|
|
|
* of its copyright holder(s), and is made available *
|
|
|
|
* under a license. If you do not know the terms of *
|
|
|
|
* the license, please stop and do not read further. *
|
|
|
|
* *
|
|
|
|
****************************************************************/
|
|
|
|
|
|
|
|
#include "mdef.h"
|
|
|
|
#include "compiler.h"
|
|
|
|
#include "opcode.h"
|
|
|
|
#include "toktyp.h"
|
2024-07-19 11:43:27 -04:00
|
|
|
#include "mdq.h"
|
|
|
|
#include "fullbool.h"
|
2012-02-05 11:35:58 -05:00
|
|
|
#include "advancewindow.h"
|
2024-07-19 11:43:27 -04:00
|
|
|
#include "show_source_line.h"
|
2012-02-05 11:35:58 -05:00
|
|
|
|
2024-07-19 11:43:27 -04:00
|
|
|
GBLREF boolean_t run_time;
|
|
|
|
|
|
|
|
error_def(ERR_COMMAORRPAREXP);
|
|
|
|
error_def(ERR_MAXACTARG);
|
|
|
|
error_def(ERR_NAMEEXPECTED);
|
|
|
|
error_def(ERR_SIDEEFFECTEVAL);
|
2012-02-05 11:35:58 -05:00
|
|
|
|
2012-03-24 14:06:46 -04:00
|
|
|
int actuallist (oprtype *opr)
|
2012-02-05 11:35:58 -05:00
|
|
|
{
|
2024-07-19 11:43:27 -04:00
|
|
|
boolean_t se_warn;
|
|
|
|
int i, j, mask, parmcount;
|
2012-03-24 14:06:46 -04:00
|
|
|
oprtype ot;
|
|
|
|
triple *counttrip, *masktrip, *ref0, *ref1, *ref2;
|
|
|
|
DCL_THREADGBL_ACCESS;
|
2012-02-05 11:35:58 -05:00
|
|
|
|
2012-03-24 14:06:46 -04:00
|
|
|
SETUP_THREADGBL_ACCESS;
|
|
|
|
assert(TK_LPAREN == TREF(window_token));
|
|
|
|
advancewindow();
|
|
|
|
masktrip = newtriple(OC_PARAMETER);
|
2012-02-05 11:35:58 -05:00
|
|
|
mask = 0;
|
2012-03-24 14:06:46 -04:00
|
|
|
counttrip = newtriple(OC_PARAMETER);
|
|
|
|
masktrip->operand[1] = put_tref(counttrip);
|
2012-02-05 11:35:58 -05:00
|
|
|
ref0 = counttrip;
|
2012-03-24 14:06:46 -04:00
|
|
|
if (TK_RPAREN == TREF(window_token))
|
2012-02-05 11:35:58 -05:00
|
|
|
parmcount = 0;
|
|
|
|
else
|
|
|
|
{
|
2012-03-24 14:06:46 -04:00
|
|
|
for (parmcount = 1; ; parmcount++)
|
2012-02-05 11:35:58 -05:00
|
|
|
{
|
2012-03-24 14:06:46 -04:00
|
|
|
if (MAX_ACTUALS < parmcount)
|
2012-02-05 11:35:58 -05:00
|
|
|
{
|
2012-03-24 14:06:46 -04:00
|
|
|
stx_error (ERR_MAXACTARG);
|
|
|
|
return FALSE;
|
2012-02-05 11:35:58 -05:00
|
|
|
}
|
2012-03-24 14:06:46 -04:00
|
|
|
if (TK_PERIOD == TREF(window_token))
|
2012-02-05 11:35:58 -05:00
|
|
|
{
|
2012-03-24 14:06:46 -04:00
|
|
|
advancewindow ();
|
|
|
|
if (TK_IDENT == TREF(window_token))
|
|
|
|
{
|
|
|
|
ot = put_mvar(&(TREF(window_ident)));
|
|
|
|
mask |= (1 << parmcount - 1);
|
|
|
|
advancewindow();
|
|
|
|
} else if (TK_ATSIGN == TREF(window_token))
|
|
|
|
{
|
|
|
|
if (!indirection(&ot))
|
|
|
|
return FALSE;
|
|
|
|
ref2 = newtriple(OC_INDLVNAMADR);
|
|
|
|
ref2->operand[0] = ot;
|
|
|
|
ot = put_tref(ref2);
|
|
|
|
mask |= (1 << parmcount - 1);
|
|
|
|
} else
|
|
|
|
{
|
|
|
|
stx_error(ERR_NAMEEXPECTED);
|
2012-02-05 11:35:58 -05:00
|
|
|
return FALSE;
|
2012-03-24 14:06:46 -04:00
|
|
|
}
|
|
|
|
} else if (TK_COMMA == TREF(window_token))
|
2012-02-05 11:35:58 -05:00
|
|
|
{
|
|
|
|
ref2 = newtriple(OC_NULLEXP);
|
|
|
|
ot = put_tref(ref2);
|
2012-03-24 14:06:46 -04:00
|
|
|
} else if (EXPR_FAIL == expr(&ot, MUMPS_EXPR))
|
|
|
|
return FALSE;
|
|
|
|
ref1 = newtriple(OC_PARAMETER);
|
|
|
|
ref0->operand[1] = put_tref(ref1);
|
|
|
|
ref1->operand[0] = ot;
|
|
|
|
if (TK_COMMA == TREF(window_token))
|
|
|
|
{ advancewindow ();
|
|
|
|
if (TK_RPAREN == TREF(window_token))
|
|
|
|
{ ref0 = ref1;
|
|
|
|
ref2 = newtriple(OC_NULLEXP);
|
|
|
|
ot = put_tref(ref2);
|
|
|
|
ref1 = newtriple(OC_PARAMETER);
|
|
|
|
ref0->operand[1] = put_tref(ref1);
|
|
|
|
ref1->operand[0] = ot;
|
|
|
|
parmcount++;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else if (TREF(window_token) == TK_RPAREN)
|
2012-02-05 11:35:58 -05:00
|
|
|
break;
|
2012-03-24 14:06:46 -04:00
|
|
|
else
|
|
|
|
{
|
|
|
|
stx_error (ERR_COMMAORRPAREXP);
|
|
|
|
return FALSE;
|
2012-02-05 11:35:58 -05:00
|
|
|
}
|
2012-03-24 14:06:46 -04:00
|
|
|
ref0 = ref1;
|
2012-02-05 11:35:58 -05:00
|
|
|
}
|
2024-07-19 11:43:27 -04:00
|
|
|
if ((1 < parmcount) && (TREF(side_effect_base))[TREF(expr_depth)])
|
|
|
|
{ /* at least two arguments and at least one side effect - look for lvns needing protection */
|
|
|
|
assert(OLD_SE != TREF(side_effect_handling));
|
|
|
|
se_warn = (!run_time && (SE_WARN == TREF(side_effect_handling)));
|
|
|
|
for (i = 0, j = parmcount, ref0 = counttrip->operand[1].oprval.tref; --j;
|
|
|
|
ref0 = ref0->operand[1].oprval.tref)
|
|
|
|
{ /* no need to do the last argument - can't have a side effect after it */
|
|
|
|
assert(OC_PARAMETER == ref0->opcode);
|
|
|
|
assert((TRIP_REF == ref0->operand[0].oprclass) && (TRIP_REF == ref0->operand[1].oprclass));
|
|
|
|
if (!((1 << i++) & mask) && (OC_VAR == ref0->operand[0].oprval.tref->opcode))
|
|
|
|
{ /* can only protect pass-by-value (not pass-by-reference) */
|
|
|
|
ref1 = maketriple(OC_STOTEMP);
|
|
|
|
ref1->operand[0] = put_tref(ref0->operand[0].oprval.tref);
|
|
|
|
ref0->operand[0].oprval.tref = ref1;
|
|
|
|
dqins(ref0, exorder, ref1); /* NOTE:this violates information hiding */
|
|
|
|
if (se_warn)
|
|
|
|
ISSUE_SIDEEFFECTEVAL_WARNING(ref0->src.column);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* the following asserts check we're getting only TRIP_REF or empty operands */
|
|
|
|
assert((NO_REF == ref0->operand[0].oprclass) || (TRIP_REF == ref0->operand[0].oprclass));
|
|
|
|
assert(((NO_REF == ref0->operand[0].oprclass) ? TRIP_REF : NO_REF) == ref0->operand[1].oprclass);
|
|
|
|
}
|
2012-02-05 11:35:58 -05:00
|
|
|
}
|
2012-03-24 14:06:46 -04:00
|
|
|
advancewindow();
|
|
|
|
masktrip->operand[0] = put_ilit(mask);
|
|
|
|
counttrip->operand[0] = put_ilit(parmcount);
|
2012-02-05 11:35:58 -05:00
|
|
|
parmcount += 2;
|
2012-03-24 14:06:46 -04:00
|
|
|
*opr = put_tref(masktrip);
|
2012-02-05 11:35:58 -05:00
|
|
|
return parmcount;
|
|
|
|
}
|