/*******************************************************************************
 ***  FUNCTION FACTOR()
 *******************************************************************************
 ***  DESCRIPTION  :  Processes FACTOR grammar rule.
 ***
 ***  FACTOR ->   idt        |
 ***              numt       |
 ***            ( EXPR )
 ***
 ******************************************************************************/
void RecursiveParser::FACTOR(TableEntry & tplace)
{
   TableEntry rplace;
   string code;

   if (global->Token == Global::idt)
   {
      EntryPtr peek = symtab->lookup(global->Lexeme);

      if (peek->depth == depth || peek->depth == 1)
      {
         tplace = symtab->lookupT(global->Lexeme);
         match(Global::idt);
      }
      else
      {
         cout << "ERROR: Undefined variable: " << global->Lexeme << " at line " << lex->line_num << endl;
         raise(SIGINT);
      }
   }
   else if (global->Token == Global::numt)
   {
      TableEntry temp = tempVar();

      if (temp.depth <= 1)
         code += temp.Lexeme;

      else
      {
         code += "[bp-";
         code += NumberToString(temp.var.Offset);
         code += "]";
      }

      code += " = ";

      if (lex->isFloat)
         code += NumberToString(global->ValueR);

      else
         code += NumberToString(global->Value);

      tplace = temp;
      emit(code);

      match(Global::numt);
   }
   else if (global->Token == Global::lparent)
   {
      match(Global::lparent);
      EXPR(rplace);
      match(Global::rparent);

      tplace = rplace;
   }
   else
   {
      cout << "ERROR: Unexpected symbol " << global->Lexeme << " at line " << lex->line_num << endl;
      raise(SIGINT);
   }
}
float fsimplefun(float x) {
    return EXPR(x);
}
Exemple #3
0
/*** hntVerifyHints() - verify a given presentation hints structure against
 *** a data value and data type.  Returns 0 on success, -1 on failure to
 *** verify, and sets 'msg' equal to a static error message string as to
 *** the reason for any failure.  'msg' is unset on success.  If 'objlist'
 *** is provided (not NULL), it contains object(s) that can be referenced
 *** by the four hint expressions (constraint, default, min, max).  This
 *** should *only* be called if the value was modified.
 ***/
int
hntVerifyHints(pObjPresentationHints ph, pTObjData ptod, char** msg, pParamObjects objlist, pObjSession session_ctx)
    {
    pParamObjects our_objlist = NULL;
    int rval = 0;
    int cmp;
    int found;
    int was_empty_string;
    int i;

	/** Init our parameter object list for constraint eval; the proper
	 ** way for the new value to be referenced is :new:value
	 **/
	if (!objlist) 
	    our_objlist = expCreateParamList();
	else
	    our_objlist = objlist;
	if (!our_objlist) { *msg="ERR: out of memory"; return -1; }
	expAddParamToList(our_objlist, "new", (pObject)ptod, 0);
	expSetParamFunctions(our_objlist, "new", hnt_internal_GetAttrType,
		hnt_internal_GetAttrValue, hnt_internal_SetAttrValue);
	if (!objlist)
	    our_objlist->Session = session_ctx;

	/** If readonly, fail right away. **/
	if (ph->Style & OBJ_PH_STYLE_READONLY)
	    {
	    rval = -1;
	    *msg = "Value is readonly";
	    }

	/** Check default **/
	if (rval == 0 && (ptod->Flags & DATA_TF_NULL) && ph->DefaultExpr)
	    {
	    if (expEvalTree(ph->DefaultExpr, our_objlist) < 0)
		{
		rval = -1;
		*msg = "ERR: default eval failed";
		}
	    else
		{
		if (EXPR(ph->DefaultExpr)->DataType != ptod->DataType && ptod->DataType != DATA_T_UNAVAILABLE)
		    {
		    rval = -1;
		    *msg = "ERR: type mismatch on default value expression";
		    }
		else
		    {
		    ptod->DataType = EXPR(ph->DefaultExpr)->DataType;
		    ptod->Flags &= ~DATA_TF_NULL;
		    if (EXPR(ph->DefaultExpr)->Flags & EXPR_F_NULL) 
			{
			ptod->Flags |= DATA_TF_NULL;
			}
		    else
			{
			/** Copy expr data to ptod **/
			switch(ptod->DataType)
			    {
			    case DATA_T_INTEGER:
				ptod->Data.Integer = EXPR(ph->DefaultExpr)->Integer;
				break;
			    case DATA_T_DOUBLE:
				ptod->Data.Double = EXPR(ph->DefaultExpr)->Types.Double;
				break;
			    case DATA_T_STRING:
				/** FIXME: dangerous to set string ptr directly like this **/
				ptod->Data.String = nmSysStrdup(EXPR(ph->DefaultExpr)->String);
				break;
			    default:
				rval = -1;
				*msg = "ERR: unsupported type for default value";
				break;
			    }
			}
		    }
		}
	    }

	/** Test null values / empty strings **/
	was_empty_string = 0;
	if (rval == 0 && !(ptod->Flags & DATA_TF_NULL) && ptod->DataType == DATA_T_STRING && ptod->Data.String[0] == '\0' && (ph->Style & OBJ_PH_STYLE_STRNULL))
	    {
	    was_empty_string = 1;
	    ptod->Flags |= DATA_TF_NULL;
	    }
	if (rval == 0 && (ptod->Flags & DATA_TF_NULL) && (ph->Style & OBJ_PH_STYLE_NOTNULL))
	    {
	    rval = -1;
	    if (was_empty_string)
		*msg = "Empty strings not permitted";
	    else
		*msg = "Null values not permitted";
	    }

	/** Test constraint **/
	if (ph->Constraint)
	    {
	    if (expEvalTree(ph->Constraint, our_objlist) < 0)
		{
		rval = -1;
		*msg = "ERR: constraint eval failed";
		}
	    else
		{
		if (EXPR(ph->Constraint)->DataType != DATA_T_INTEGER || (EXPR(ph->Constraint)->Flags & EXPR_F_NULL))
		    {
		    rval = -1;
		    *msg = "ERR: constraint result was NULL or not an integer";
		    }
		else
		    {
		    if (EXPR(ph->Constraint)->Integer == 0)
			{
			rval = -1;
			*msg = "Constraint test failed";
			}
		    }
		}
	    }

	/** Max/Min expression **/
	if (ph->MinValue)
	    {
	    if (expEvalTree(ph->MinValue, our_objlist) < 0)
		{
		rval = -1;
		*msg = "ERR: min value eval failed";
		}
	    else
		{
		if (EXPR(ph->MinValue)->DataType != ptod->DataType)
		    {
		    rval = -1;
		    *msg = "ERR: type mismatch checking min value";
		    }
		else if (EXPR(ph->MinValue)->Flags & EXPR_F_NULL)
		    {
		    rval = -1;
		    *msg = "ERR: min value is null";
		    }
		}
	    }
	if (ph->MaxValue)
	    {
	    if (expEvalTree(ph->MaxValue, our_objlist) < 0)
		{
		rval = -1;
		*msg = "ERR: max value eval failed";
		}
	    else
		{
		if (EXPR(ph->MaxValue)->DataType != ptod->DataType)
		    {
		    rval = -1;
		    *msg = "ERR: type mismatch checking max value";
		    }
		else if (EXPR(ph->MaxValue)->Flags & EXPR_F_NULL)
		    {
		    rval = -1;
		    *msg = "ERR: max value is null";
		    }
		}
	    }
	if ((ph->MinValue || ph->MaxValue) && rval == 0)
	    {
	    if (ptod->Flags & DATA_TF_NULL)
		{
		rval = -1;
		*msg = "Min/Max specified but new value is NULL";
		}
	    else
		{
		cmp = 1;
		switch(ptod->DataType)
		    {
		    case DATA_T_INTEGER:
			cmp &= (!ph->MinValue || EXPR(ph->MinValue)->Integer <= ptod->Data.Integer);
			cmp &= (!ph->MaxValue || EXPR(ph->MaxValue)->Integer >= ptod->Data.Integer);
			break;
		    case DATA_T_DOUBLE:
			cmp &= (!ph->MinValue || EXPR(ph->MinValue)->Types.Double <= ptod->Data.Double);
			cmp &= (!ph->MaxValue || EXPR(ph->MaxValue)->Types.Double >= ptod->Data.Double);
			break;
		    case DATA_T_STRING:
			cmp &= (!ph->MinValue || strcmp(EXPR(ph->MinValue)->String, ptod->Data.String) >= 0);
			cmp &= (!ph->MaxValue || strcmp(EXPR(ph->MaxValue)->String, ptod->Data.String) <= 0);
			break;
		    default:
			rval = -1;
			*msg = "ERR: unsupported type for min/max expression(s)";
			break;
		    }
		if (!cmp)
		    {
		    rval = -1;
		    *msg = "Min/Max test failed";
		    }
		}
	    }

	/** BadChars/AllowChars **/
	if ((ph->BadChars || ph->AllowChars) && ptod->DataType != DATA_T_STRING)
	    {
	    rval = -1;
	    *msg = "ERR: badchars/allowchars set but type is not a string";
	    }
	if (ph->BadChars)
	    {
	    if (!(ptod->Flags & DATA_TF_NULL) && strpbrk(ptod->Data.String, ph->BadChars))
		{
		rval = -1;
		*msg = "String value contains an excluded character";
		}
	    }
	if (ph->AllowChars)
	    {
	    if (!(ptod->Flags & DATA_TF_NULL) && strspn(ptod->Data.String, ph->AllowChars) < strlen(ptod->Data.String))
		{
		rval = -1;
		*msg = "String value contains a non-allowed character";
		}
	    }

	/** Enumlist? **/
	if (ph->EnumList.nItems)
	    {
	    if (ptod->Flags & DATA_TF_NULL)
		{
		rval = -1;
		*msg = "Enum list supplied but new value is NULL";
		}
	    else
		{
		if (ptod->DataType != DATA_T_INTEGER && ptod->DataType != DATA_T_STRING)
		    {
		    rval = -1;
		    *msg = "ERR: type mismatch with enum list";
		    }
		else
		    {
		    found = 0;
		    for(i=0;i<ph->EnumList.nItems;i++)
			{
			if (ptod->DataType == DATA_T_INTEGER)
			    found = (ptod->Data.Integer == strtoi(ph->EnumList.Items[i], NULL, 10));
			else
			    found = !strcmp(ptod->Data.String, ph->EnumList.Items[i]);
			if (found) break;
			}
		    if (!found)
			{
			rval = -1;
			*msg = "Value not found in the list of acceptable values";
			}
		    }
		}
	    }

	/** FIXME: Enumquery to be added later (MQ efficiency issue) **/

	/** Free the parameter object list **/
	expRemoveParamFromList(our_objlist, "new");
	if (!objlist) expFreeParamList(our_objlist);

    return rval;
    }
/* $begin 530-simplefun-c */
double simplefun(double x) {
    return EXPR(x);
}