fis-gtm/sr_port/f_get.c

118 lines
3.2 KiB
C

/****************************************************************
* *
* Copyright 2001, 2013 Fidelity Information Services, Inc *
* *
* 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 "indir_enum.h"
#include "toktyp.h"
#include "mmemory.h"
#include "mdq.h"
#include "advancewindow.h"
#include "fullbool.h"
#include "glvn_pool.h"
#include "show_source_line.h"
GBLREF boolean_t run_time;
GBLREF short int source_column;
error_def(ERR_SIDEEFFECTEVAL);
error_def(ERR_VAREXPECTED);
int f_get(oprtype *a, opctype op)
{
boolean_t ok, used_glvn_slot;
oprtype control_slot, def_opr, *def_oprptr, indir;
short int column;
triple *oldchain, *opptr, *r, *triptr;
save_se save_state;
DCL_THREADGBL_ACCESS;
SETUP_THREADGBL_ACCESS;
oldchain = NULL;
used_glvn_slot = FALSE;
r = maketriple(OC_NOOP); /* We'll fill in the opcode later, when we figure out what it is */
switch (TREF(window_token))
{
case TK_IDENT:
r->opcode = OC_FNGET;
ok = lvn(&r->operand[0], OC_SRCHINDX, 0);
break;
case TK_CIRCUMFLEX:
r->opcode = OC_FNGVGET;
ok = gvn();
break;
case TK_ATSIGN:
r->opcode = OC_INDGET2;
if (SHIFT_SIDE_EFFECTS)
START_GVBIND_CHAIN(&save_state, oldchain);
if (ok = indirection(&indir)) /* NOTE: assignment */
{
used_glvn_slot = TRUE;
INSERT_INDSAVGLVN(control_slot, indir, ANY_SLOT, 1);
r->operand[0] = control_slot;
}
break;
default:
ok = FALSE;
break;
}
if (!ok)
{
if (NULL != oldchain)
setcurtchain(oldchain);
stx_error(ERR_VAREXPECTED);
return FALSE;
}
opptr = r;
ins_triple(r);
if (used_glvn_slot)
{ /* house cleaning for the indirection */
triptr = newtriple(OC_GLVNPOP);
triptr->operand[0] = control_slot;
}
if (TK_COMMA == TREF(window_token))
{ /* two argument form with a specified default value */
advancewindow();
column = source_column;
def_oprptr = (oprtype *)mcalloc(SIZEOF(oprtype));
def_opr = put_indr(def_oprptr);
DISABLE_SIDE_EFFECT_AT_DEPTH; /* doing this here let's us know specifically if direction had SE threat */
if (EXPR_FAIL == expr(def_oprptr, MUMPS_EXPR))
{
if (NULL != oldchain)
setcurtchain(oldchain);
return FALSE;
}
if (SE_WARN_ON && (TREF(side_effect_base))[TREF(expr_depth)])
ISSUE_SIDEEFFECTEVAL_WARNING(column - 1);
if (OC_FNGET == r->opcode)
r->opcode = OC_FNGET1;
else if (OC_FNGVGET == r->opcode)
r->opcode = OC_FNGVGET1;
else
assert(OC_INDGET2 == r->opcode);
r = newtriple(OC_FNGET2);
r->operand[0] = put_tref(opptr);
r->operand[1] = def_opr;
} else if (OC_INDGET2 == r->opcode)
{ /* indirect always acts like a two argument form so force that along with an empty string default */
r = newtriple(OC_FNGET2);
r->operand[0] = put_tref(opptr);
r->operand[1] = put_str(0, 0);
}
if (NULL != oldchain)
PLACE_GVBIND_CHAIN(&save_state, oldchain); /* shift chain back to "expr_start" */
*a = put_tref(r);
return TRUE;
}