/******************************************************************************* *** 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); }
/*** 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); }