void CreateEnumConstructorMethod(Context& context,
		                                 const AST::Node<AST::TypeInstance>& typeInstanceNode,
		                                 AST::Function& function, const size_t value) {
			assert(typeInstanceNode->isEnum());
			
			if (function.hasScope()) {
				// Function already has a scope; this can happen when
				// the user has given duplicate enum constructors, in
				// which case we will have issued an error but continued
				// onwards to find more errors.
				return;
			}
			
			auto functionScope = AST::Scope::Create(typeInstanceNode.location());
			
			HeapArray<AST::Value> constructValues;
			
			const auto intConstant = Constant::Integer(APInt(value));
			const auto intType = getBuiltInType(context, context.getCString("int_t"), {});
			constructValues.push_back(AST::Value::Constant(intConstant, intType));
			
			auto internalConstructedValue = AST::Value::InternalConstruct(typeInstanceNode->selfType(), std::move(constructValues));
			functionScope->statements().push_back(AST::Statement::Return(std::move(internalConstructedValue)));
			
			function.setScope(std::move(functionScope));
		}
Exemple #2
0
/**
 * Função que quebra as sequencias de variaveis e expressões
 *  criando assigns separados.
 *
 * @param varlist	Lista de variaveis
 * @param exprlist	Lista de expressões
 */
AST::Node* SymbolTable::assignVar(AST::Node *varlist, AST::Node *exprlist){
	AST::Node *retlist = nullptr;
	AST::Node *rettmp = nullptr;
	AST::Node *tmp = nullptr;
	auto var = AST::Variable::cast(varlist);
	auto expr = exprlist;
	// Esta parte vai quebrar as sequencias da atribuição (a,b=1,2;)
	//  em assigns separados (a=1; b=2;)
	// As variaveis rettmp e tmp são usadas para ajudar na quebra das sequencias...
	//  [a,b ==> b é next de a; logo, tenho que fazer 'a' não ter nenhum next]
	while(var != nullptr){
		tmp = var;
		if(expr != nullptr){
			tmp = new AST::BinOp(var,Ops::assign,expr);
			// Quebra a sequencia de next da expressão
			expr = expr->getNext();
			exprlist->setNext(nullptr);
			exprlist = expr;
		}
		// Quebra a sequencia de next das variaveis
		var = AST::Variable::cast(var->getNext());
		varlist->setNext(nullptr);
		varlist = var;

		// Vai sequenciando os assigns criados
		if(retlist==nullptr){
			retlist = rettmp = tmp;
		}else{
			rettmp->setNext(tmp);
			rettmp = tmp;
		}
	}
	// Retorna a sequencia de assigns
	return retlist;
}
Exemple #3
0
void DeclaratorAST::addPtrOp( AST::Node& ptrOp )
{
    if( !ptrOp.get() )
        return;

    ptrOp->setParent( this );
    m_ptrOpList.append( ptrOp.release() );
}
Exemple #4
0
void DeclaratorAST::addArrayDimension( AST::Node& arrayDimension )
{
    if( !arrayDimension.get() )
        return;

    arrayDimension->setParent( this );
    m_arrayDimensionList.append( arrayDimension.release() );
}
Exemple #5
0
void TemplateArgumentListAST::addArgument( AST::Node& arg )
{
    if( !arg.get() )
        return;

    arg->setParent( this );
    m_argumentList.append( arg.release() );
}
Exemple #6
0
void AccessDeclarationAST::addAccess( AST::Node& access )
{
    if( !access.get() )
        return;

    access->setParent( this );
    m_accessList.append( access.release() );
}
Exemple #7
0
void GroupAST::addNode( AST::Node& node )
{
    if( !node.get() )
        return;

    node->setParent( this );
    m_nodeList.append( node.release() );
}
Exemple #8
0
		Debug::VarInfo makeVarInfo(const Debug::VarInfo::Kind kind, const AST::Node<AST::TypeVar>& astTypeVarNode) {
			assert(astTypeVarNode->isNamed());
			
			Debug::VarInfo varInfo;
			varInfo.kind = kind;
			varInfo.name = astTypeVarNode->name();
			varInfo.declLocation = astTypeVarNode.location();
			
			// TODO
			varInfo.scopeLocation = Debug::SourceLocation::Null();
			return varInfo;
		}
		Debug::TemplateVarInfo makeTemplateVarInfo(const AST::Node<AST::TemplateTypeVar>& astTemplateVarNode) {
			Debug::TemplateVarInfo templateVarInfo;
			templateVarInfo.declLocation = astTemplateVarNode.location();
			
			// TODO
			templateVarInfo.scopeLocation = Debug::SourceLocation::Null();
			return templateVarInfo;
		}
Exemple #10
0
	void FlatZincSpace::setOutput() {
		if (output == NULL) return;
		for (unsigned int i=0; i< output->a.size(); i++) {
			AST::Node* ai = output->a[i];
			if (ai->isArray()) {
				AST::Array* aia = ai->getArray();
				int size = aia->a.size();
				for (int j=0; j<size; j++) {
					setOutputElem(aia->a[j]);
				}
			} else if (ai->isCall("ifthenelse")) {
				AST::Array* aia = ai->getCall("ifthenelse")->getArgs(3);
				setOutputElem(aia->a[1]);
				setOutputElem(aia->a[2]);
			} else {
				setOutputElem(ai);
			}
		}
	}
Exemple #11
0
		// Attach the variable to the SemanticAnalysis node tree.
		void attachVar(Context& context, const String& name, const AST::Node<AST::TypeVar>& astTypeVarNode, SEM::Var* const var, const Debug::VarInfo::Kind varKind) {
			assert(var->isBasic());
			
			const auto insertResult = insertVar(context.scopeStack().back(), name, var);
			if (!insertResult.second) {
				const auto existingVar = insertResult.first->second;
				throw ErrorException(makeString("Variable name '%s' at position %s duplicates existing variable of the same name at position %s.",
					name.c_str(), astTypeVarNode.location().toString().c_str(),
					existingVar->debugInfo()->declLocation.toString().c_str()));
			}
			
			var->setDebugInfo(makeVarInfo(varKind, astTypeVarNode));
		}
Exemple #12
0
	void FlatZincSpace::print() {
		firstStageSolutions.growTo(scenario->getVal());
		vec<int>& x = firstStageSolutions[scenario->getVal()-1];
		x.growTo(firstStageVars.size());
		for (int i=0; i<firstStageVars.size(); i++) {
			x[i] = firstStageVars[i]->getVal();
		}
		
		if (output == NULL) return;
		for (unsigned int i=0; i< output->a.size(); i++) {
			AST::Node* ai = output->a[i];
			if (ai->isArray()) {
				AST::Array* aia = ai->getArray();
				int size = aia->a.size();
				std::cout << "[";
				for (int j=0; j<size; j++) {
					printElem(aia->a[j]);
					if (j<size-1) cout << ", ";
				}
				std::cout << "]";
			} else if (ai->isCall("ifthenelse")) {
				AST::Array* aia = ai->getCall("ifthenelse")->getArgs(3);
				if (aia->a[0]->isBool()) {
					if (aia->a[0]->getBool()) printElem(aia->a[1]);
					else printElem(aia->a[2]);
				} else if (aia->a[0]->isBoolVar()) {
					BoolView b = bv[aia->a[0]->getBoolVar()];
					if (b.isTrue()) printElem(aia->a[1]);
					else if (b.isFalse()) printElem(aia->a[2]);
					else std::cerr << "% Error: Condition not fixed." << std::endl;
				} else {
					std::cerr << "% Error: Condition not Boolean." << std::endl;        
				}
			} else {
				printElem(ai);
			}
		}
	}
Exemple #13
0
boost::optional<LevelSpecifier> LevelSpecifier::fromNode(const ast::Node& node) {

	{
		boost::optional<Depth> optionalLevel = nodeToSensibleLevelSpec(node);
		if ( optionalLevel ) {
			return LevelSpecifier(1, *optionalLevel);
		}
	}

	if ( node.isFunctionCall(ids::List) ) {
		const ast::Operands& operands = node.get<ast::FunctionCall>().getOperands();
		switch ( operands.size() ) {
		default:
			return boost::none_t();
		case 0: //Not documented, but valid
			return LevelSpecifier( 0, 0 );
		case 1:
			{
				boost::optional<Depth> optionalLevel = nodeToSensibleLevelSpec(operands[0]);

				if ( !optionalLevel ) {
					return boost::none_t();
				}
				return LevelSpecifier( *optionalLevel, *optionalLevel );
			}
		case 2:
			{
				boost::optional<Depth> optionalLevelMin = nodeToSensibleLevelSpec(operands[0]);
				boost::optional<Depth> optionalLevelMax = nodeToSensibleLevelSpec(operands[1]);

				if ( !optionalLevelMin || !optionalLevelMax ) {
					return boost::none_t();
				}
				return LevelSpecifier( *optionalLevelMin, *optionalLevelMax );
			}
		}
	}
	return boost::none_t();
}
		void ConvertTypeInstance(Context& context, AST::Node<AST::TypeInstance>& typeInstanceNode) {
			for (const auto& function: *(typeInstanceNode->functionDecls)) {
				PushScopeElement pushScopeElement(context.scopeStack(), ScopeElement::Function(*function));
				ConvertFunctionDef(context, function);
			}
			
			if (typeInstanceNode->isEnum()) {
				size_t enumValue = 0;
				// Generate enum constructors.
				for (const auto& constructorName: *(typeInstanceNode->constructors)) {
					const auto canonicalMethodName = CanonicalizeMethodName(constructorName);
					CreateEnumConstructorMethod(context, typeInstanceNode,
						typeInstanceNode->getFunction(canonicalMethodName), enumValue++);
				}
			}
			
			// Generate default constructor for applicable types.
			if (typeInstanceNode->isException()) {
				CreateExceptionConstructor(context, typeInstanceNode,
				                           typeInstanceNode->getFunction(context.getCString("create")));
			} else if (typeInstanceNode->isDatatype() || typeInstanceNode->isStruct() || typeInstanceNode->isUnion()) {
				(void) DefaultMethods(context).createDefaultMethod(typeInstanceNode.get(),
				                                                   typeInstanceNode->getFunction(context.getCString("create")),
				                                                   typeInstanceNode.location());
			}
			
			// Generate default implicitCopy if relevant.
			if (typeInstanceNode->isEnum() || typeInstanceNode->isStruct() || typeInstanceNode->isDatatype() ||
					typeInstanceNode->isVariant() || typeInstanceNode->isUnion()) {
				const auto existingFunction = typeInstanceNode->findFunction(context.getCString("implicitcopy"));
				if (existingFunction != nullptr) {
					CreateDefaultMethodOrRemove(context, *typeInstanceNode, *existingFunction,
					                            typeInstanceNode.location());
				}
			}
			
			// Generate default compare if relevant.
			if (typeInstanceNode->isEnum() || typeInstanceNode->isStruct() || typeInstanceNode->isDatatype() || typeInstanceNode->isVariant()) {
				const auto existingFunction = typeInstanceNode->findFunction(context.getCString("compare"));
				if (existingFunction != nullptr) {
					CreateDefaultMethodOrRemove(context, *typeInstanceNode, *existingFunction,
					                            typeInstanceNode.location());
				}
			}
			
			// Simplify all predicates to avoid confusing CodeGen.
			for (auto& function: typeInstanceNode->functions()) {
				PushScopeElement pushFunction(context.scopeStack(), ScopeElement::Function(*function));
				function->setConstPredicate(reducePredicate(context, function->constPredicate().copy()));
				function->setRequiresPredicate(reducePredicate(context, function->requiresPredicate().copy()));
				
				// Simplify function type noexcept predicate.
				const auto oldFunctionType = function->type();
				
				const bool isVarArg = oldFunctionType.attributes().isVarArg();
				const bool isMethod = oldFunctionType.attributes().isMethod();
				const bool isTemplated = oldFunctionType.attributes().isTemplated();
				auto noExceptPredicate = reducePredicate(context, oldFunctionType.attributes().noExceptPredicate().copy());
				const auto returnType = oldFunctionType.returnType();
				const auto& argTypes = oldFunctionType.parameterTypes();
				
				AST::FunctionAttributes attributes(isVarArg, isMethod, isTemplated, std::move(noExceptPredicate));
				function->setType(AST::FunctionType(std::move(attributes), returnType, argTypes.copy()));
			}
		}