END_TEST
 

START_TEST ( test_uncertml_write_normalDistribution)
{
  const char *expected = 
    "<UncertML xmlns=\"http://www.uncertml.org/3.0\">\n"
    "  <NormalDistribution definition=\"http://www.uncertml.org/distributions/normal\">\n"
    "    <mean>\n"
    "      <var varId=\"mu\"/>\n"
    "    </mean>\n"
    "    <variance>\n"
    "      <var varId=\"sigma\"/>\n"
    "    </variance>\n"
    "  </NormalDistribution>\n"
    "</UncertML>";

  char *filename = safe_strcat(TestDataDirectory, "normalDistrib.xml");
  SBMLDocument *document = readSBMLFromFile(filename);

  fail_unless ( document->getModel() != NULL );

  FunctionDefinition * fd = document->getModel()->getFunctionDefinition(0);
  DistribFunctionDefinitionPlugin * plug = 
    static_cast<DistribFunctionDefinitionPlugin*>(fd->getPlugin("distrib"));

  const DrawFromDistribution * d = plug->getDrawFromDistribution();

  const UncertMLNode * uncert = d->getUncertML();

  std::string xml = uncert->toXMLString();

  fail_unless( equals(expected, xml.c_str()) );
}
int main(int argc, char* argv[])
{
  std::cout << "\n  Testing ActionsAndRules class\n "
            << std::string(30,'=') << std::endl;

  try
  {
    //std::queue<std::string> resultsQ;
    PrintPreproc pp;
    PreprocStatement pps;
    pps.addAction(&pp);

    FunctionDefinition fnd;
    PrintFunction prt;
    fnd.addAction(&prt);

    Toker toker("../ActionsAndRules.h");
    SemiExp se(&toker);
    Parser parser(&se);
    parser.addRule(&pps);
    parser.addRule(&fnd);
    while(se.get())
      parser.parse();
    std::cout << "\n\n";
  }
  catch(std::exception& ex)
  {
    std::cout << "\n\n  " << ex.what() << "\n\n";
  }
}
Example #3
0
void CodeGenVisitor::JIT(Expression* e) {
	StatementList* sl = new StatementList();
	sl->addStatement(new ReturnStatement(e));
	FunctionDefinition* fd = new FunctionDefinition(Type::INT, "", new ParameterList(), sl);

	value_ = 0;
	fd->accept(this);

	if (!value_) {
		delete fd;
		throw "error evaluating expression";
	}

	llvm::Function* f = dynamic_cast<llvm::Function*>(value_);

	void* fPtr = ee_->getPointerToFunction(f);

	// some casting ... because we like magic
	int (*fP)() = (int (*)())(intptr_t)fPtr;

	std::cout << "Evaluated to: " << fP() << std::endl;

	// throw it away
	f->eraseFromParent();
}
void AdaptSignatureAssistant::textChanged(KTextEditor::View* view, const KTextEditor::Range& invocationRange, const QString& removedText)
{
  reset();

  m_view = view;

  //FIXME: update signature assistant to play well with the rename assistant
  KTextEditor::Range sigAssistRange = invocationRange;
  if (!removedText.isEmpty()) {
    sigAssistRange.setRange(sigAssistRange.start(), sigAssistRange.start());
  }

  m_document = view->document()->url();

  DUChainReadLocker lock(DUChain::lock(), 300);
  if(!lock.locked()) {
    qCDebug(CPP) << "failed to lock duchain in time";
    return;
  }

  KTextEditor::Range simpleInvocationRange = KTextEditor::Range(sigAssistRange);
  Declaration* funDecl = getDeclarationAtCursor(simpleInvocationRange.start(), m_document);
  if(!funDecl || !funDecl->type<FunctionType>())
    return;

  if(QtFunctionDeclaration* classFun = dynamic_cast<QtFunctionDeclaration*>(funDecl)) {
    if (classFun->isSignal()) {
      // do not offer to change signature of a signal, as the implementation will be generated by moc
      return;
    }
  }

  Declaration* otherSide = 0;
  FunctionDefinition* definition = dynamic_cast<FunctionDefinition*>(funDecl);
  if (definition)
  {
    m_editingDefinition = true;
    otherSide = definition->declaration();
  }
  else if ((definition = FunctionDefinition::definition(funDecl)))
  {
    m_editingDefinition = false;
    otherSide = definition;
  }

  if (!otherSide)
    return;

  m_otherSideContext = DUContextPointer(DUChainUtils::getFunctionContext(otherSide));
  if (!m_otherSideContext)
    return;

  m_declarationName = funDecl->identifier();
  m_otherSideId = otherSide->id();
  m_otherSideTopContext = ReferencedTopDUContext(otherSide->topContext());
  m_oldSignature = getDeclarationSignature(otherSide, m_otherSideContext.data(), true);

  //Schedule an update, to make sure the ranges match
  DUChain::self()->updateContextForUrl(m_otherSideTopContext->url(), TopDUContext::AllDeclarationsAndContexts);
}
Example #5
0
void
MMOModel::add (const FunctionDefinition &f)
{
  string fname = f.getId ();
  MMOFunction *func = new MMOFunction (fname);
  int na = f.getNumArguments ();
  MMOMath d = MMOMath (_replace, &_functions, _prefix);
  list<string> funcArgs;
  for (int i = 0; i < na; i++)
    {
      d.parseEquation (f.getArgument (i));
      string argExp = d.getExp ();
      MMODecl *adec = new MMODecl (argExp, function_input);
      func->add (adec);
      funcArgs.push_back (argExp);
    }
  string var = MMOUtils::getInstance ()->getVar ();
  d.parseEquation (f.getBody ());
  _addAlgebraicReplacement (d);
  MMODecl *adec = new MMODecl (var, d.getExp (), function_definition);
  func->add (adec);
  _functions[fname] = pair<list<string>, ASTNode*> (
      funcArgs, new ASTNode (*f.getBody ()));
  _add (func, external_functions);
}
void 
FunctionDefinitionRecursion::addDependencies(const Model& m, 
                                         const FunctionDefinition& object)
{
  unsigned int ns;
  std::string thisId = object.getId();

  /* loop thru the list of names in the Math
    * if they refer to a FunctionDefinition add to the map
    * with the variable as key
    */
  List* variables = object.getMath()->getListOfNodes( ASTNode_isFunction );
  for (ns = 0; ns < variables->getSize(); ns++)
  {
    ASTNode* node = static_cast<ASTNode*>( variables->get(ns) );
    string   name = node->getName() ? node->getName() : "";

    if (m.getFunctionDefinition(name))
    {
      mIdMap.insert(pair<const std::string, std::string>(thisId, name));
    }
  }

  delete variables;
}
Example #7
0
CodeGen::CodeGen(AbstractSyntaxTree *tree) {
	for(unsigned i = 0; i < tree->functions.size(); ++i) {
		FunctionDefinition *fn = tree->functions[i];
		currentFn = fn;
		Value *f = fn->codegen();
	}
}
Example #8
0
bool ASTPrinter::visit(FunctionDefinition const& _node)
{
	writeLine("FunctionDefinition \"" + _node.getName() + "\"" +
			  (_node.isPublic() ? " - public" : "") +
			  (_node.isDeclaredConst() ? " - const" : ""));
	printSourcePart(_node);
	return goDeeper();
}
AbstractDeclarationNavigationContext::AbstractDeclarationNavigationContext( DeclarationPointer decl, KDevelop::TopDUContextPointer topContext, AbstractNavigationContext* previousContext)
  : AbstractNavigationContext((topContext ? topContext : TopDUContextPointer(decl ? decl->topContext() : 0)), previousContext), m_declaration(decl), m_fullBackwardSearch(false)
{
  //Jump from definition to declaration if possible
  FunctionDefinition* definition = dynamic_cast<FunctionDefinition*>(m_declaration.data());
  if(definition && definition->declaration())
    m_declaration = DeclarationPointer(definition->declaration());
}
FunctionDefinition* configureRuleForFunction(Parser* pParser, Repository* pRepo)
{
	FunctionDefinition* pFunctionDefinition = new FunctionDefinition();
	PushFunction* pPushFunction = new PushFunction(pRepo);
	AddFunctionNode* pAddFunctionNode = new AddFunctionNode(pRepo);
	pFunctionDefinition->addAction(pPushFunction);
	pFunctionDefinition->addAction(pAddFunctionNode);
	pParser->addRule(pFunctionDefinition);
	return pFunctionDefinition;
}
END_TEST


START_TEST ( test_FunctionDefinition_parent_create )
{
    Model *m = new Model(2, 4);
    FunctionDefinition *fd = m->createFunctionDefinition();

    ListOf *lo = m->getListOfFunctionDefinitions();

    fail_unless(lo == m->getFunctionDefinition(0)->getParentSBMLObject());
    fail_unless(lo == fd->getParentSBMLObject());
    fail_unless(m == lo->getParentSBMLObject());
}
END_TEST

START_TEST ( test_FunctionDefinition )
{
  FunctionDefinition* fd = new FunctionDefinition(2, 4);
  
  fail_unless (!(fd->hasRequiredAttributes()));

  fd->setId("fd");

  fail_unless (fd->hasRequiredAttributes());

  delete fd;
}
END_TEST

START_TEST ( test_FunctionDefinition )
{
  FunctionDefinition* fd = new FunctionDefinition(2, 4);
  
  fail_unless (!(fd->hasRequiredElements()));

  fd->setMath(SBML_parseFormula("fd"));

  fail_unless (fd->hasRequiredElements());

  delete fd;
}
int main(int argc, char* argv[])
{
  std::cout << "\n  Testing ActionsAndRules class\n "
            << std::string(30,'=') << std::endl;

  RelationshipAnal* p = new RelationshipAnal;
	TypeAnal* q = new TypeAnal;

  try
  {
    PrintPreproc pp;
    PreprocStatement pps;
    pps.addAction(&pp);

    FunctionDefinition fnd;
    PrintFunction prt;
    fnd.addAction(&prt);

	ClassStructEnumDefinition cls1;
	std::vector<std::string> classResult;
	PrintClass cls2(&classResult);
	cls1.addAction(&cls2);

	
	InheritanceDetection* cls3 = new InheritanceDetection; 
	InheritanceAction* cls4 = new InheritanceAction(q, p);
	cls3->addAction(cls4);


    Toker toker("../ActionsAndRules.h");
    SemiExp se(&toker);
    Parser parser(&se);
    parser.addRule(&pps);
    parser.addRule(&fnd);
	parser.addRule(&cls1);
	parser.addRule(cls3);
    while(se.get())
      parser.parse();
    std::cout << "\n\n";
  }
  catch(std::exception& ex)
  {
    std::cout << "\n\n  " << ex.what() << "\n\n";
  }
}
END_TEST


START_TEST ( test_FunctionDefinition_parent_NULL )
{
    SBMLDocument *d = new SBMLDocument();
    Model *m = d->createModel();
    FunctionDefinition *c = m->createFunctionDefinition();

    FunctionDefinition *c1 = c->clone();
    delete d;

    fail_unless(c1->getAncestorOfType(SBML_MODEL) == NULL);
    fail_unless(c1->getParentSBMLObject() == NULL);
    fail_unless (c1->getSBMLDocument() == NULL);

    delete c1;
}
int main(int argc, char* argv[])
{
  std::cout << "\n  Testing ActionsAndRules class\n "
            << std::string(30,'=') << std::endl;

  try
  {
    std::queue<std::string> resultsQ;
    PreprocToQ ppq(resultsQ);

	//Modified Pallavi
	PrintPreproc ppq;
    
	PreprocStatement pps;
    pps.addAction(&ppq);

    FunctionDefinition fnd;
	PrettyPrintToQ pprtQ(resultsQ);

	//Modified Pallavi
	PrettyPrintFunction pprtQ;
    
	fnd.addAction(&pprtQ);

    Toker toker("../ActionsAndRules.h");
    SemiExp se(&toker);
    Parser parser(&se);
    parser.addRule(&pps);
    parser.addRule(&fnd);
    while(se.get())
      parser.parse();
    size_t len = resultsQ.size();
    for(size_t i=0; i<len; ++i)
    {
      std::cout << "\n  " << resultsQ.front().c_str();
      resultsQ.pop();
    }
    std::cout << "\n\n";
  }
  catch(std::exception& ex)
  {
    std::cout << "\n\n  " << ex.what() << "\n\n";
  }
}
END_TEST


START_TEST ( test_FunctionDefinition_parent_add )
{
    FunctionDefinition *fd = new FunctionDefinition(2, 4);
    Model *m = new Model(2, 4);
    fd->setId("fd");
    fd->setMath(SBML_parseFormula("l"));

    m->addFunctionDefinition(fd);

    delete fd;

    ListOf *lo = m->getListOfFunctionDefinitions();

    fail_unless(lo == m->getFunctionDefinition(0)->getParentSBMLObject());
    fail_unless(m == lo->getParentSBMLObject());
}
eth::AssemblyItem CompilerContext::virtualFunctionEntryLabel(FunctionDefinition const& _function)
{
	// Libraries do not allow inheritance and their functions can be inlined, so we should not
	// search the inheritance hierarchy (which will be the wrong one in case the function
	// is inlined).
	if (auto scope = dynamic_cast<ContractDefinition const*>(_function.scope()))
		if (scope->isLibrary())
			return functionEntryLabel(_function);
	solAssert(!m_inheritanceHierarchy.empty(), "No inheritance hierarchy set.");
	return virtualFunctionEntryLabel(_function, m_inheritanceHierarchy.begin());
}
Example #19
0
void Compiler::appendConstructor(FunctionDefinition const& _constructor)
{
	CompilerContext::LocationSetter locationSetter(m_context, _constructor);
	// copy constructor arguments from code to memory and then to stack, they are supplied after the actual program
	if (!_constructor.getParameters().empty())
	{
		unsigned argumentSize = 0;
		for (ASTPointer<VariableDeclaration> const& var: _constructor.getParameters())
			if (var->getType()->isDynamicallySized())
			{
				argumentSize = 0;
				break;
			}
			else
				argumentSize += var->getType()->getCalldataEncodedSize();

		CompilerUtils(m_context).fetchFreeMemoryPointer();
		if (argumentSize == 0)
		{
			// argument size is dynamic, use CODESIZE to determine it
			m_context.appendProgramSize(); // program itself
			// CODESIZE is program plus manually added arguments
			m_context << eth::Instruction::CODESIZE << eth::Instruction::SUB;
		}
		else
			m_context << u256(argumentSize);
		// stack: <memptr> <argument size>
		m_context << eth::Instruction::DUP1;
		m_context.appendProgramSize();
		m_context << eth::Instruction::DUP4 << eth::Instruction::CODECOPY;
		m_context << eth::Instruction::ADD;
		CompilerUtils(m_context).storeFreeMemoryPointer();
		appendCalldataUnpacker(
			FunctionType(_constructor).getParameterTypes(),
			true,
			CompilerUtils::freeMemoryPointer + 0x20
		);
	}
	_constructor.accept(*this);
}
Example #20
0
void Compiler::appendBaseConstructor(FunctionDefinition const& _constructor)
{
	CompilerContext::LocationSetter locationSetter(m_context, _constructor);
	FunctionType constructorType(_constructor);
	if (!constructorType.getParameterTypes().empty())
	{
		solAssert(m_baseArguments.count(&_constructor), "");
		std::vector<ASTPointer<Expression>> const* arguments = m_baseArguments[&_constructor];
		solAssert(arguments, "");
		for (unsigned i = 0; i < arguments->size(); ++i)
			compileExpression(*(arguments->at(i)), constructorType.getParameterTypes()[i]);
	}
	_constructor.accept(*this);
}
void
FunctionDefinitionRecursion::logSelfRecursion ( const FunctionDefinition& fd,
                                       const string& varname )
{
  char * formula = SBML_formulaToString(fd.getMath());   
  msg = "The functionDefinition with id '";
  msg += varname;
  msg += "' refers to itself within the math formula ";
  msg += formula;
  msg += "'.";
  safe_free(formula);

  
  logFailure(fd);
}
/**
 * Checks that all variables referenced in FunctionDefinition bodies are
 * bound variables (function arguments).
 */
void
FunctionDefinitionVars::check_ (const Model& m, const FunctionDefinition& fd)
{
  if ( fd.getLevel() == 1         ) return;
  if ( !fd.isSetMath()            ) return;
  if ( fd.getBody()  == NULL      ) return;
  if (  fd.getNumArguments() == 0 ) return;


  List* variables = fd.getBody()->getListOfNodes( ASTNode_isName );


  for (unsigned int n = 0; n < variables->getSize(); ++n)
  {
    ASTNode* node = static_cast<ASTNode*>( variables->get(n) );
    string   name = node->getName() ? node->getName() : "";

    if ( fd.getArgument(name) == NULL ) 
    {
      /* if this is the csymbol time - technically it is allowed 
       * in L2v1 and L2v2
       */
      if (node->getType() == AST_NAME_TIME)
      {
        if (fd.getLevel() > 2
          || (fd.getLevel() == 2 && fd.getVersion() > 2))
        {
          logUndefined(fd, name);
        }
      }
      else
      {
        logUndefined(fd, name);
      }
    }
  }
  
  delete variables;
}
eth::AssemblyItem CompilerContext::virtualFunctionEntryLabel(
	FunctionDefinition const& _function,
	vector<ContractDefinition const*>::const_iterator _searchStart
)
{
	string name = _function.name();
	FunctionType functionType(_function);
	auto it = _searchStart;
	for (; it != m_inheritanceHierarchy.end(); ++it)
		for (FunctionDefinition const* function: (*it)->definedFunctions())
			if (
				function->name() == name &&
				!function->isConstructor() &&
				FunctionType(*function).hasEqualArgumentTypes(functionType)
			)
				return functionEntryLabel(*function);
	solAssert(false, "Super function " + name + " not found.");
	return m_asm.newTag(); // not reached
}
/**
 * Logs a message about an undefined variable in the given
 * FunctionDefinition.
 */
void
FunctionDefinitionVars::logUndefined ( const FunctionDefinition& fd,
                                       const string& varname )
{
  msg =
  msg =
    //"Inside the 'lambda' of a <functionDefinition>, if a 'ci' element is not "
    //"the first element within a MathML 'apply', then the 'ci''s value can "
    //"only be the value of a 'bvar' element declared in that 'lambda'. In "
    //"other words, all model entities referenced inside a function definition "
    //"must be passed arguments to that function. (References: L2V2 Section "
    //"4.3.2.)" 
    "The variable '";

  msg += varname;
  msg += "' is not listed as a <bvar> of FunctionDefinition '";
  msg += fd.getId();
  msg += "'.";
  
  logFailure(fd);
}
Example #25
0
void PlotFunctionRegister::registerDefaultFunctions()
{
  FunctionDefinition *def = nullptr;
  QString category;

  // Core fundamentals
  category = "general";
  add(static_cast<double (*)(double)>(&std::abs), category, "abs", "Absolute value of x.");
  add(new FunctionClean(category));
  def = add(&clipFunc, category, "clip", "Clip x to to the range [min,max]. All values are clipped to this range.", 3);
  def->setDisplayName("clip(x,min,max)");
  def = add(&clipmaxFunc, category, "clipmax", "Clip x to a maximum value. Any value above max is displayed as min.", 2);
  def->setDisplayName("clipmax(x,max)");
  def = add(&clipminFunc, category, "clipmin", "Clip x to a minimum value. Any value below min is displayed as min.", 2);
  def->setDisplayName("clipmin(x,min)");
  add(&deltaFunc, category, "delta", "Delta from the last value of x.", 1);
  add(static_cast<double (*)(double)>(&std::exp), category, "exp", "Calculate e (2.718...) to the power of x.");
  add(&isNanFunc, category, "isnan", "Test if the input value is NaN. 1 if so, zero otherwise.", 1);
  add(&isInfFunc, category, "isinf", "Test if the input value is +/- infinity. 1 if so, zero otherwise.", 1);
  add(static_cast<double(*)(double)>(&std::log), category, "log", "Natural logarithm of x.");
  add(static_cast<double(*)(double)>(&std::log10), category, "log10", "Base 10 logarithm of x.");
  add(&maxFunc, category, "max", "Most recent maximum value of x.", 1);
  add(&minFunc, category, "min", "Most recent minimum value of x.", 1);
  add(static_cast<double (*)(double)>(&std::sqrt), category, "sqrt", "Sqrt of the value of x.");
  add(&nowFunc, category, "now", "Returns the current sample time.", 0);
  add(new FunctionUnwrap(category));

  category = "rounding";
  add(static_cast<double(*)(double)>(&std::ceil), category, "ceil", "Nearest integer not less than x.");
  add(static_cast<double(*)(double)>(&std::floor), category, "floor", "Nearest integer not greater than x.");
  add(static_cast<double(*)(double)>(&std::trunc), category, "trunc", "Nearest integer not greater in magnitude than x.");
  add(static_cast<double(*)(double)>(&std::round), category, "round", "Nearest integer rounding up (in magnitude) from halfway cases.");
  add(&fmodFunc, category, "fmod", "Floating point remainder of the division x/y.", 2);
  add(&remainderFunc, category, "remainder", "Integer remainder (closest) of the division x/y. Sign may differ from fmod.", 2);
  add(&signFunc, category, "sign", "Return the sign of x. -1 if negative, 1 otherwise.", 1);

  // Statistics
  category = "statistics";
  add(&abserrFunc, category, "abserr", "Absolute error between x and y.", 2);
  add(&avgFunc, category, "avg", "Running average value of x.", 1);
  add(new FunctionMAvg(category));
  add(&maxofFunc, category, "maxof", "Maximum value of any number of graphs.", 1, true);
  add(&minofFunc, category, "minof", "Minimum value of any number of graphs.", 1, true);
  add(&relerrFunc, category, "relerr", "Relative error between x and y.", 2);
  add(&totalFunc, category, "total", "Running sum of x.", 1);

  // Trigonometry
  category = "trigonometry";
  add(static_cast<double(*)(double)>(&std::acos), category, "acos", "Trigonometric arccos function of x");
  add(static_cast<double(*)(double)>(&std::asin), category, "asin", "Trigonometric arcsin function of x");
  add(static_cast<double(*)(double)>(&std::atan), category, "atan", "Trigonometric arctan function of x");
  def = add(&atan2Func, category, "atan2", "Trigonometric arctan of y/x with quadrant selection.", 2);
  if (def)
  {
    def->setDisplayName("atan2(y,x)");
  }
  add(static_cast<double(*)(double)>(&std::cos), category, "cos", "Trigonometric cos function of x");
  add(static_cast<double(*)(double)>(&std::sin), category, "sin", "Trigonometric sin function of x");
  add(static_cast<double(*)(double)>(&std::tan), category, "tan", "Trigonometric tan function of x");
  add(static_cast<double(*)(double)>(&std::cosh), category, "cosh", "Hyperbolic cos function of x");
  add(static_cast<double(*)(double)>(&std::sinh), category, "sinh", "Hyperbolic sin function of x");
  add(static_cast<double(*)(double)>(&std::tanh), category, "tanh", "Hyperbolic tan function of x");
  add(static_cast<double(*)(double)>(&std::acosh), category, "acosh", "Hyperbolic arccos function of x");
  add(static_cast<double(*)(double)>(&std::asinh), category, "asinh", "Hyperbolic arcsin function of x");
  add(static_cast<double(*)(double)>(&std::atanh), category, "atanh", "Hyperbolic arctan function of x");
  add(&piFunc, category, "pi", "Pi constant (3.141...).", 0);
}
bool Why3Translator::visit(FunctionDefinition const& _function)
{
	if (!_function.isImplemented())
	{
		error(_function, "Unimplemented functions not supported.");
		return false;
	}
	if (_function.name().empty())
	{
		error(_function, "Fallback functions not supported.");
		return false;
	}
	if (!_function.modifiers().empty())
	{
		error(_function, "Modifiers not supported.");
		return false;
	}

	m_localVariables.clear();
	for (auto const& var: _function.parameters())
		m_localVariables[var->name()] = var.get();
	for (auto const& var: _function.returnParameters())
		m_localVariables[var->name()] = var.get();
	for (auto const& var: _function.localVariables())
		m_localVariables[var->name()] = var;

	add("let rec _" + _function.name());
	add(" (this: account)");
	for (auto const& param: _function.parameters())
	{
		string paramType;
		try
		{
			paramType = toFormalType(*param->annotation().type);
		}
		catch (NoFormalType &err)
		{
			string const* typeName = boost::get_error_info<errinfo_noFormalTypeFrom>(err);
			error(*param, "Parameter type \"" + (typeName ? *typeName : "") + "\" not supported.");
		}
		if (param->name().empty())
			error(*param, "Anonymous function parameters not supported.");
		add(" (arg_" + param->name() + ": " + paramType + ")");
	}
	add(":");

	indent();
	indent();
	string retString = "(";
	for (auto const& retParam: _function.returnParameters())
	{
		string paramType;
		try
		{
			paramType = toFormalType(*retParam->annotation().type);
		}
		catch (NoFormalType &err)
		{
			string const* typeName = boost::get_error_info<errinfo_noFormalTypeFrom>(err);
			error(*retParam, "Parameter type " + (typeName ? *typeName : "") + " not supported.");
		}
		if (retString.size() != 1)
			retString += ", ";
		retString += paramType;
	}
	add(retString + ")");
	unindent();

	addSourceFromDocStrings(_function.annotation());
	if (!m_currentContract.contract)
		error(_function, "Only functions inside contracts allowed.");
	addSourceFromDocStrings(m_currentContract.contract->annotation());

	if (_function.isDeclaredConst())
		addLine("ensures { (old this) = this }");
	else
		addLine("writes { this }");

	addLine("=");

	// store the prestate in the case we need to revert
	addLine("let prestate = {balance = this.balance; storage = " + copyOfStorage() + "} in ");

	// initialise local variables
	for (auto const& variable: _function.parameters())
		addLine("let _" + variable->name() + " = ref arg_" + variable->name() + " in");
	for (auto const& variable: _function.returnParameters())
	{
		if (variable->name().empty())
			error(*variable, "Unnamed return variables not yet supported.");
		string varType;
		try
		{
			varType = toFormalType(*variable->annotation().type);
		}
		catch (NoFormalType &err)
		{
			string const* typeNamePtr = boost::get_error_info<errinfo_noFormalTypeFrom>(err);
			error(*variable, "Type " + (typeNamePtr ? *typeNamePtr : "") + "in return parameter not yet supported.");
		}
		addLine("let _" + variable->name() + ": ref " + varType + " = ref (of_int 0) in");
	}
	for (VariableDeclaration const* variable: _function.localVariables())
	{
		if (variable->name().empty())
			error(*variable, "Unnamed variables not yet supported.");
		string varType;
		try
		{
			varType = toFormalType(*variable->annotation().type);
		}
		catch (NoFormalType &err)
		{
			string const* typeNamePtr = boost::get_error_info<errinfo_noFormalTypeFrom>(err);
			error(*variable, "Type " + (typeNamePtr ? *typeNamePtr : "") + "in variable declaration not yet supported.");
		}
		addLine("let _" + variable->name() + ": ref " + varType + " = ref (of_int 0) in");
	}
	addLine("try");

	_function.body().accept(*this);
	add(";");
	addLine("raise Return");

	string retVals;
	for (auto const& variable: _function.returnParameters())
	{
		if (!retVals.empty())
			retVals += ", ";
		retVals += "!_" + variable->name();
	}
	addLine("with Return -> (" + retVals + ") |");
	string reversion = "     Revert -> this.balance <- prestate.balance; ";
	for (auto const* variable: m_currentContract.stateVariables)
		reversion += "this.storage._" + variable->name() + " <- prestate.storage._" + variable->name() + "; ";
	//@TODO in case of reversion the return values are wrong - we need to change the
	// return type to include a bool to signify if an exception was thrown.
	reversion += "(" + retVals + ")";
	addLine(reversion);
	unindent();
	addLine("end");
	addLine("");
	return false;
}
Example #27
0
bool DocStringAnalyser::visit(FunctionDefinition const& _node)
{
	handleCallable(_node, _node, _node.annotation());
	return true;
}
/**
 *
 * Creates an SBML model represented in "7.8 Example involving function definitions"
 * in the SBML Level 2 Version 4 Specification.
 *
 */
SBMLDocument* createExampleInvolvingFunctionDefinitions()
{
  const unsigned int level   = Level;
  const unsigned int version = Version;

  //---------------------------------------------------------------------------
  //
  // Creates an SBMLDocument object 
  //
  //---------------------------------------------------------------------------

  SBMLDocument* sbmlDoc = new SBMLDocument(level,version);

  //---------------------------------------------------------------------------
  //
  // Creates a Model object inside the SBMLDocument object. 
  //
  //---------------------------------------------------------------------------

  Model* model = sbmlDoc->createModel();
  model->setId("functionExample");

  //---------------------------------------------------------------------------
  //
  // Creates a FunctionDefinition object inside the Model object. 
  //
  //---------------------------------------------------------------------------

  FunctionDefinition* fdef = model->createFunctionDefinition();
  fdef->setId("f");

  // Sets a math (ASTNode object) to the FunctionDefinition object.

  string mathXMLString = "<math xmlns=\"http://www.w3.org/1998/Math/MathML\">"
                         "  <lambda>"
                         "    <bvar>"
                         "      <ci> x </ci>"
                         "    </bvar>"
                         "    <apply>"
                         "      <times/>"
                         "      <ci> x </ci>"
                         "      <cn> 2 </cn>"
                         "    </apply>"
                         "  </lambda>"
                         "</math>";

  ASTNode* astMath = readMathMLFromString(mathXMLString.c_str());
  fdef->setMath(astMath);
  delete astMath;


  //---------------------------------------------------------------------------
  //
  // Creates a Compartment object inside the Model object. 
  //
  //---------------------------------------------------------------------------

  Compartment* comp;
  const string compName = "compartmentOne";

  // Creates a Compartment object ("compartmentOne")

  comp = model->createCompartment();
  comp->setId(compName);
 
  // Sets the "size" attribute of the Compartment object.
  //
  //   The units of this Compartment object is the default SBML 
  //   units of volume (litre), and thus we don't have to explicitly invoke 
  //   setUnits("litre") function to set the default units.
  //
  comp->setSize(1);


  //---------------------------------------------------------------------------
  //
  // Creates Species objects inside the Model object. 
  //
  //---------------------------------------------------------------------------
  
  Species* sp;

  //---------------------------------------------------------------------------
  // (Species1) Creates a Species object ("S1")
  //---------------------------------------------------------------------------

  sp = model->createSpecies();
  sp->setId("S1");

  // Sets the "compartment" attribute of the Species object to identify the 
  // compartnet in which the Species object located.

  sp->setCompartment(compName);

  // Sets the "initialConcentration" attribute of the Species object.
  //
  //  The units of this Species object is determined by two attributes of this 
  //  Species object ("substanceUnits" and "hasOnlySubstanceUnits") and the
  //  "spatialDimension" attribute of the Compartment object ("cytosol") in which 
  //  this species object located.
  //  Since the default values are used for "substanceUnits" (substance (mole)) 
  //  and "hasOnlySubstanceUnits" (false) and the value of "spatialDimension" (3) 
  //  is greater than 0, the units of this Species object is  mole/litre . 
  //

  sp->setInitialConcentration(1);

  //---------------------------------------------------------------------------
  // (Species2) Creates a Species object ("S2")
  //---------------------------------------------------------------------------

  sp = model->createSpecies();
  sp->setId("S2");
  sp->setCompartment(compName);
  sp->setInitialConcentration(0);


  //---------------------------------------------------------------------------
  //
  // Creates a global Parameter object inside the Model object. 
  //
  //---------------------------------------------------------------------------

  Parameter* para;

  // Creates a Parameter ("t")  

  para = model->createParameter();
  para->setId("t");
  para->setValue(1);
  para->setUnits("second");


  //---------------------------------------------------------------------------
  //
  // Creates Reaction objects inside the Model object. 
  //
  //---------------------------------------------------------------------------
  
  // Temporary pointers.

  Reaction* reaction;
  SpeciesReference* spr;
  KineticLaw* kl;

  //---------------------------------------------------------------------------
  // (Reaction1) Creates a Reaction object ("reaction_1").
  //---------------------------------------------------------------------------

  reaction = model->createReaction();
  reaction->setId("reaction_1");
  reaction->setReversible(false);

  //---------------------------------------------------------------------------
  // Creates Reactant objects inside the Reaction object ("reaction_1"). 
  //---------------------------------------------------------------------------

  // (Reactant1) Creates a Reactant object that references Species "S1"
  // in the model.

  spr = reaction->createReactant();
  spr->setSpecies("S1");

  //---------------------------------------------------------------------------
  // Creates a Product object inside the Reaction object ("reaction_1"). 
  //---------------------------------------------------------------------------

  // Creates a Product object that references Species "S2" in the model. 

  spr = reaction->createProduct();
  spr->setSpecies("S2");


  //---------------------------------------------------------------------------
  // Creates a KineticLaw object inside the Reaction object ("reaction_1"). 
  //---------------------------------------------------------------------------
  
  kl = reaction->createKineticLaw();

  //---------------------------------------------------------------------------
  // Sets a math (ASTNode object) to the KineticLaw object.
  //---------------------------------------------------------------------------

  mathXMLString = "<math xmlns=\"http://www.w3.org/1998/Math/MathML\">"
                  "  <apply>"
                  "  <divide/>"
                  "    <apply>"
                  "      <times/>"
                  "      <apply>"
                  "        <ci> f </ci>"
                  "        <ci> S1 </ci>"
                  "      </apply>"
                  "      <ci> compartmentOne </ci>"
                  "    </apply>"
                  "    <ci> t </ci>"
                  "  </apply>"
                  "</math>";

  astMath = readMathMLFromString(mathXMLString.c_str());
  kl->setMath(astMath);
  delete astMath;


  // Returns the created SBMLDocument object.
  // The returned object must be explicitly deleted by the caller,
  // otherwise memory leak will happen.

  return sbmlDoc;
}
QString DeclarationNavigationContext::html(bool shorten)
{
  clear();
  m_shorten = shorten;
  modifyHtml()  += "<html><body><p>" + fontSizePrefix(shorten);

  addExternalHtml(m_prefix);

  if(!m_declaration.data()) {
    modifyHtml() += i18n("<br /> lost declaration <br />");
    return currentHtml();
  }
  
  if( m_previousContext ) {
    QString link = createLink( m_previousContext->name(), m_previousContext->name(), NavigationAction(m_previousContext) );
    modifyHtml() += navigationHighlight(i18n("Back to %1<br />", link));
  }
  
  QExplicitlySharedDataPointer<IDocumentation> doc;
  
  if( !shorten ) {
    doc = ICore::self()->documentationController()->documentationForDeclaration(m_declaration.data());

    const AbstractFunctionDeclaration* function = dynamic_cast<const AbstractFunctionDeclaration*>(m_declaration.data());
    if( function ) {
      htmlFunction();
    } else if( m_declaration->isTypeAlias() || m_declaration->kind() == Declaration::Instance ) {
	
	
      if( m_declaration->isTypeAlias() )
        modifyHtml() += importantHighlight("type ");

      if(m_declaration->type<EnumeratorType>())
        modifyHtml() += i18n("enumerator ");
      
      if( !m_declaration->isTypeAlias()) 
          modifyHtml() += ' ' + identifierHighlight(declarationName(m_declaration).toHtmlEscaped(), m_declaration) + " ";

      AbstractType::Ptr useType = m_declaration->abstractType();
      if(m_declaration->isTypeAlias()) {
        //Do not show the own name as type of typedefs
        if(useType.cast<TypeAliasType>())
          useType = useType.cast<TypeAliasType>()->type();
      } 
      
      eventuallyMakeTypeLinks( useType );
      
      modifyHtml() += "<br>";

    }else{
      if( m_declaration->kind() == Declaration::Type && m_declaration->abstractType().cast<StructureType>()) {
        htmlClass();
      }
      if ( m_declaration->kind() == Declaration::Namespace ) {
        modifyHtml() += i18n("namespace %1 ", identifierHighlight(m_declaration->qualifiedIdentifier().toString().toHtmlEscaped(), m_declaration));
      }

      if(m_declaration->type<EnumerationType>()) {
        EnumerationType::Ptr enumeration = m_declaration->type<EnumerationType>();
        modifyHtml() += i18n("enumeration %1 ", identifierHighlight(m_declaration->identifier().toString().toHtmlEscaped(), m_declaration));
      }

      if(m_declaration->isForwardDeclaration()) {
        ForwardDeclaration* forwardDec = static_cast<ForwardDeclaration*>(m_declaration.data());
        Declaration* resolved = forwardDec->resolve(m_topContext.data());
        if(resolved) {
          modifyHtml() += i18n("( resolved forward-declaration: ");
          makeLink(resolved->identifier().toString(), KDevelop::DeclarationPointer(resolved), NavigationAction::NavigateDeclaration );
          modifyHtml() += i18n(") ");
        }else{
          modifyHtml() += i18n("(unresolved forward-declaration) ");
          QualifiedIdentifier id = forwardDec->qualifiedIdentifier();
          uint count;
          const IndexedDeclaration* decls;
          PersistentSymbolTable::self().declarations(id, count, decls);
          for(uint a = 0; a < count; ++a) {
            if(decls[a].isValid() && !decls[a].data()->isForwardDeclaration()) {
              modifyHtml() += "<br />";
              makeLink(i18n("possible resolution from"), KDevelop::DeclarationPointer(decls[a].data()), NavigationAction::NavigateDeclaration);
              modifyHtml() += ' ' + decls[a].data()->url().str();
            }
          }
        }
      }
      modifyHtml() += "<br />";
    }
  }else{
    AbstractType::Ptr showType = m_declaration->abstractType();
    if(showType && showType.cast<FunctionType>()) {
      showType = showType.cast<FunctionType>()->returnType();
      if(showType)
        modifyHtml() += labelHighlight(i18n("Returns: "));
    }else  if(showType) {
      modifyHtml() += labelHighlight(i18n("Type: "));
    }
    
    if(showType) {
      eventuallyMakeTypeLinks(showType);
      modifyHtml() += " ";
    }
  }
  
  QualifiedIdentifier identifier = m_declaration->qualifiedIdentifier();
  if( identifier.count() > 1 ) {
    if( m_declaration->context() && m_declaration->context()->owner() )
    {
      Declaration* decl = m_declaration->context()->owner();

      FunctionDefinition* definition = dynamic_cast<FunctionDefinition*>(decl);
      if(definition && definition->declaration())
        decl = definition->declaration();

      if(decl->abstractType().cast<EnumerationType>())
        modifyHtml() += labelHighlight(i18n("Enum: "));
      else
        modifyHtml() += labelHighlight(i18n("Container: "));

      makeLink( declarationName(DeclarationPointer(decl)), DeclarationPointer(decl), NavigationAction::NavigateDeclaration );
      modifyHtml() += " ";
    } else {
      QualifiedIdentifier parent = identifier;
      parent.pop();
      modifyHtml() += labelHighlight(i18n("Scope: %1 ", typeHighlight(parent.toString().toHtmlEscaped())));
    }
  }
  
  if( shorten && !m_declaration->comment().isEmpty() ) {
    QString comment = QString::fromUtf8(m_declaration->comment());
    if( comment.length() > 60 ) {
      comment.truncate(60);
      comment += "...";
    }
    comment.replace('\n', " ");
    comment.replace("<br />", " ");
    comment.replace("<br/>", " ");
    modifyHtml() += commentHighlight(comment.toHtmlEscaped()) + "   ";
  }
  

  QString access = stringFromAccess(m_declaration);
  if( !access.isEmpty() )
    modifyHtml() += labelHighlight(i18n("Access: %1 ", propertyHighlight(access.toHtmlEscaped())));


  ///@todo Enumerations

  QString detailsHtml;
  QStringList details = declarationDetails(m_declaration);
  if( !details.isEmpty() ) {
    bool first = true;
    foreach( const QString &str, details ) {
      if( !first )
        detailsHtml += ", ";
      first = false;
      detailsHtml += propertyHighlight(str);
    }
  }
/**
 *
 * @param function_def  function that contains function calls that will be inlined.
 *                      This means that this function will is actually the callsite
 *                      of the called functions, and that this is the place were
 *                      the code (from the inlined functions) will be written to
 * @param scope_link
 */
void InlinePhase::find_functions(FunctionDefinition function_def, ScopeLink scope_link) {
    FunctionCallsPred function_calls_pred(scope_link);
    Statement function_body = function_def.get_function_body();

    ObjectList<AST_t> list_of_calls = function_body.get_ast().depth_subtrees(function_calls_pred);

    for (ObjectList<AST_t>::iterator it = list_of_calls.begin(); it != list_of_calls.end(); it++, _callNum++) {
//        cout<<_callNum<<endl;
        AST_t element = *it;

        Expression expr(element, scope_link);

        // We already know it is a function call, no need to check again
        Expression _function_call = expr.get_called_expression();
        Expression last_function_call = _function_call;
        set_FCall(&_function_call);

//        cin.get();
        if (_function_call.is_id_expression()) {

            IdExpression id_expr = _function_call.get_id_expression();
            Symbol called_sym = id_expr.get_symbol();
            Symbol last_called_sym =  called_sym;
            set_FSym(&called_sym);
            if (called_sym.is_valid() && called_sym.is_function() && called_sym.is_defined()) {
//                cout << "\nFinding if necessary forward inline for function '" << id_expr << "' in " << element.get_locus() << "\n";
                _functionName = called_sym.get_name();
                _rowOfCall = element.get_line();
                int fnd = 0;
                for(int fN = 0; fN<_inlinedFunctions.size(); ++fN) {
                    if(_inlinedFunctions[fN].get_name().compare(std::string(_functionName))==0) {
                        fnd = 1;
                        break;
                    }
                }

                if(!fnd) {
                    _inlinedFunctions.push_back(called_sym);
//                    cout << "\nForward inline of "<<called_sym.get_name()<<" called on: "<<function_def.get_function_name().get_symbol().get_name()<<" \n";
                    ObjectList<AST_t> list_of_fun_defs = _translation_unit.depth_subtrees(_function_def_pred);
                    for (ObjectList<AST_t>::iterator it = list_of_fun_defs.begin(); it != list_of_fun_defs.end(); it++) {
                        FunctionDefinition function_defNF(*it, scope_link);
                        TL::Symbol function_sym = function_defNF.get_function_symbol();
                        if(function_sym.get_name().compare(called_sym.get_name())==0) {
                            find_functions(function_defNF,scope_link);
                            set_FCall(&last_function_call);
                            set_FSym(&last_called_sym);
                        }
                    }
                }
//                cout << "\nApplying inlining for function" << called_sym.get_name() << "\n {";
                inlineFunction(called_sym, expr);
//                cout<<"} \n";
            } else if(called_sym.is_defined()) {
                cerr << "************************************"<<
                     "\n You can not use "<<called_sym.get_name()<<"inside HMPP codelet.\n"
                     << "************************************";
                exit(-1);
            }
        }
    }
    if(list_of_calls.size()==0) {
        cout<<"No function calls in : "<<function_def.get_function_name().get_symbol().get_name()<<endl;
    } else {
        cout<<function_def.get_function_name().get_symbol().get_name()<< " finished -------------"<<endl;
    }
}