void MyFrame::push(int stackLevel, uint64_t time, CallStackBase *base) { int pid = base->getId(); CallStackType *stack = (CallStackType *) base; #if 0 fprintf(stderr, "native push t %llu p %d s %d fid %d 0x%x %s\n", stack->getGlobalTime(time), pid, stackLevel, function->id, function->addr, function->name); #endif FunctionStack *fstack = dmtrace_stack[pid]; if (fstack == NULL) { fstack = new FunctionStack(); dmtrace_stack[pid] = fstack; } fstack->push(function); thread_time[pid] = time; dmtrace->addFunctionEntry(function->id, time, pid); }
Calc::NumberStack Calc::eval(Parser &parser) throw(std::string) { NumberStack numStack; FunctionStack funcStack; string token; while(!parser.isDone()) { token = parser.getNextToken(); if(token.length() == 0) break; // first check if token is a numeric value CalcFloat_t value; if(getNumeric(token.data(), value)) { // push numeric value onto stack numStack.push(value); } else if(token.compare("(") == 0) { // open bracket _bracketCount++; NumberStack result = eval(parser); NumberStack tempStack; // push results onto stack (need to reverse order) while(!result.empty()) { tempStack.push(result.top()); result.pop(); } while(!tempStack.empty()) { numStack.push(tempStack.top()); tempStack.pop(); } } else if(token.compare(")") == 0) { // close bracket _bracketCount--; break; } else { // find the function vector<CFunction*>::const_iterator func = findFunction(token); if(func != _funcList.end()) { if((*func)->isOperator()) { // evaluate operators while they are of equal or higher precedence while(!funcStack.empty()) { // get the top of the operator stack const CFunction &op = *funcStack.top(); // check precedence if((*func)->_order > op._order) break; // pop this operation from the stack funcStack.pop(); // check that there are enough arguments on the stack if((int)numStack.size() < op._numArgs) { // error => not enough elements on stack throwSyntaxError(parser); } else { // get the function arguments: operators always have <= 2 assert(op._numArgs <= 2 && "Invalid number of arguments"); CalcFloat_t args[2]; for(int i=0;i<op._numArgs;i++) { args[i] = (CalcFloat_t)numStack.top(); numStack.pop(); } // do the operation CalcFloat_t result = op.eval(args,op._numArgs); // push the answer onto the stack numStack.push(result); } } // push the new operation onto the stack funcStack.push(*func); } else { // next token MUST be a '(' token = parser.getNextToken(); if(token.compare("(") != 0) throwSyntaxError(parser); _bracketCount++; NumberStack argStack = eval(parser); const CFunction &op = **func; // check that there are enough arguments on the stack if((int)argStack.size() < op._numArgs) { // error => not enough elements on stack throwSyntaxError(parser); } else { assert(op._numArgs == 1 && "Invalid number of arguments"); CalcFloat_t args[1]; for(int i=0;i<op._numArgs;i++) { args[i] = (CalcFloat_t)argStack.top(); argStack.pop(); } // do the operation CalcFloat_t result = op.eval(args,op._numArgs); // push the answer onto the stack numStack.push(result); } } } else { // invalid input throw (string("Unknown token ") + token); } } } // collapse function stack // evaluate operators while they are of equal or higher precedence while(!funcStack.empty()) { // get the top of the operator stack const CFunction &op = *funcStack.top(); // pop this operation from the stack funcStack.pop(); // check that there are enough arguments on the stack if((int)numStack.size() < op._numArgs) { // error => not enough elements on stack throwSyntaxError(parser); } else { // get the function arguments: operators always have 2 assert(op._numArgs <= 2 && "Invalid number of arguments"); CalcFloat_t args[2]; for(int i=0;i<op._numArgs;i++) { args[i] = (CalcFloat_t)numStack.top(); numStack.pop(); } // do the operation CalcFloat_t result = op.eval(args,op._numArgs); // push the answer onto the stack numStack.push(result); } } // function stack should now be empty if(!funcStack.empty()) throwSyntaxError(parser); return numStack; }