/* Determine if the value of a string is a known numerical value */ bool IsNumericValue (const string& o_formula) { bool result = true; string formula = StripParens (o_formula); list<string> operands = SeparateOperands (formula); // one operand only if (operands.size() == 1) { ///////////////////////////// Literal if (IsNumber (operands.front() )) { return true; } /* if */ ///////////////////////////// Value Identifier ///////////////////////////// Function Call if (IsFunctionCall (operands.front ())) { return false; bool bresult = IsNumericValue (SeparateArguments (GetArguments (operands.front())) ) ; return bresult; } /* if */ return false; } /* if */ // multiple operands else { for (list<string>::iterator o = operands.begin(); o != operands.end(); ) { if (!IsNumericValue (*o)) { return false; } /* if */ o++; if (o != operands.end()) o++; } /* for */ return true; } /* else */ } /* IsNumericValue */
/* Determine if a the value of a string is constantly known (symbolic or numeric) */ bool ValueKnown (const string& o_formula) { bool result = true; string formula = StripParens (o_formula); list<string> operands = SeparateOperands (formula); // one operand only if (operands.size() == 1) { ///////////////////////////// Literal if (IsNumber (operands.front())) return true; ///////////////////////////// Literal if (IsSymbol (operands.front())) return true; ///////////////////////////// Value Request ///////////////////////////// Function Call if (IsFunctionCall (operands.front())) return ValueKnown (SeparateArguments (GetArguments (operands.front()))); return false; } /* if */ // multiple operands else { operands = OperandsOnly (operands); for (list<string>::iterator o = operands.begin(); o != operands.end(); o++) { if (!ValueKnown (*o)) return false; } /* for */ return true; } /* else */ } /* circuit_t::ValueKnown */
asCScriptNode *asCParser::ParseExprValue() { asCScriptNode *node = new asCScriptNode(snExprValue); sToken t1; GetToken(&t1); RewindTo(&t1); if( t1.type == ttIdentifier || IsRealType(t1.type) ) { if( IsFunctionCall() ) node->AddChildLast(ParseFunctionCall()); else node->AddChildLast(ParseIdentifier()); } else if( t1.type == ttCast ) node->AddChildLast(ParseCast()); else if( IsConstant(t1.type) ) node->AddChildLast(ParseConstant()); else if( t1.type == ttOpenParanthesis ) { GetToken(&t1); node->UpdateSourcePos(t1.pos, t1.length); node->AddChildLast(ParseAssignment()); if( isSyntaxError ) return node; GetToken(&t1); if( t1.type != ttCloseParanthesis ) Error(ExpectedToken(")").AddressOf(), &t1); node->UpdateSourcePos(t1.pos, t1.length); } else Error(TXT_EXPECTED_EXPRESSION_VALUE, &t1); return node; }
string Eval (const string& o_operation) { string operation = OperatorsToFunctionCalls (o_operation); //really redundant operation = StripWhitespaceBE (operation); operation = StripParens (operation); //auto operands = SeparateOperands (operation); operand count has to be one at this point list <string> operands = SeparateOperands (operation); if (operands.size() == 1) { // literal value if (IsNumericValue (operation)) return tostr (NumEval (operation)); //maybe return operation directly function_t fcode; string function_name = GetFunctionName(operation); //function if (IsFunctionCall (operation)) { SeparateArguments (StripB (function_name, operation)); return run_function (function_name, SeparateArguments (StripB (function_name, operation))); } // if // only one operand at this point, which is a variable if (IsVariable (operation)) return GetVariable (operands.front())-> Value (); // check for Literals // TODO: OperationType does so many unncessasry checks (for variables, waveforms, etc) // its better to figure out some way to skip those checks type_t optype = OperationType (operation); if (optype == TYPE_TEXT or optype == TYPE_NUM) return operation; // NaV: Not a value if (operation == "NaV") error ("operation did not return a valid value"); // Unknown object error ("object `" + operation + "' is unsupported."); } // if else { string result = ""; for (list<string>::iterator o = operands.begin(); o != operands.end(); o++) { if (IsOperator (*o)) { result += *o; } /* if */ else { result += Eval (*o); } /* else */ } /* for */ return StripE (" ", result); } /* else */ } /* eval */