blob: d73ec7c02818f242a50229cce87d98a4822fd505 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2016 CEA LIST.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Created on: 7 août 2008
*
* Contributors:
* Arnault Lapitre (CEA LIST) arnault.lapitre@cea.fr
* - Initial API and implementation
******************************************************************************/
#include "BaseTypeSpecifier.h"
#include <fml/expression/BuiltinArray.h>
#include <fml/expression/ExpressionConstant.h>
#include <fml/expression/ExpressionConstructor.h>
#include <fml/type/TypeAliasSpecifier.h>
namespace sep
{
std::string BaseTypeSpecifier::TYPE_ANOMYM_ID = "type#anonym";
/**
* SETTER
* updateFullyQualifiedNameID()
*/
void BaseTypeSpecifier::updateFullyQualifiedNameID()
{
if( hasFullyQualifiedNameID() )
{
if( hasAstElement() )
{
setNameID( getAstNameID() );
}
else
{
setNameID( NamedElement::extractNameID(
getFullyQualifiedNameID() ) );
}
}
else if( hasAstElement() )
{
std::string aFullyQualifiedNameID = getAstFullyQualifiedNameID();
setAllNameID( "type" + aFullyQualifiedNameID.substr(
aFullyQualifiedNameID.find(FQN_ID_ROOT_SEPARATOR)),
getAstNameID() );
}
else
{
setAllNameID( TYPE_ANOMYM_ID , TYPE_ANOMYM_ID );
}
}
/**
* CONSTRAINT generation
* for a given parameter
*/
bool BaseTypeSpecifier::couldGenerateConstraint() const
{
switch( mSpecifierKind )
{
case TYPE_ENUM_SPECIFIER:
case TYPE_INTERVAL_SPECIFIER:
{
return( true );
}
case TYPE_INTEGER_SPECIFIER:
case TYPE_RATIONAL_SPECIFIER:
case TYPE_FLOAT_SPECIFIER:
case TYPE_REAL_SPECIFIER:
{
return( hasBitSizeConstraint() );
}
case TYPE_POS_INTEGER_SPECIFIER:
case TYPE_UINTEGER_SPECIFIER:
case TYPE_URATIONAL_SPECIFIER:
// case TYPE_CONTINUOUS_TIME_SPECIFIER:
// case TYPE_DISCRETE_TIME_SPECIFIER:
case TYPE_UFLOAT_SPECIFIER:
case TYPE_UREAL_SPECIFIER:
{
return( true );
}
default:
{
return( false );
}
}
}
inline static avm_integer_t pow2(avm_size_t n)
{
return( 1 << n );
// avm_integer_t res = 1;
// for( ; 0 < n; --n )
// {
// res *= 2;
// }
// return( res );
}
avm_integer_t BaseTypeSpecifier::minIntegerValue() const
{
const avm_size_t dim = getBitSize();
switch( mSpecifierKind )
{
case TYPE_INTEGER_SPECIFIER:
{
// if( hasBitSizeConstraint() )
if( (dim > 0) && (dim <= 64) )
{
return( - pow2(dim - 1) );
}
else
{
return( AVM_NUMERIC_MIN_INTEGER );
}
}
case TYPE_POS_INTEGER_SPECIFIER:
{
return( 1 );
}
case TYPE_UINTEGER_SPECIFIER:
case TYPE_DISCRETE_TIME_SPECIFIER:
{
return( 0 );
}
default:
{
return( AVM_NUMERIC_MIN_INTEGER );
}
}
}
avm_uinteger_t BaseTypeSpecifier::maxIntegerValue() const
{
const avm_size_t dim = getBitSize();
switch( mSpecifierKind )
{
case TYPE_INTEGER_SPECIFIER:
{
// if( hasBitSizeConstraint() )
if( (dim > 0) && (dim <= 64) )
{
return( pow2(dim - 1) - 1 );
}
else
{
return( AVM_NUMERIC_MAX_INTEGER );
}
}
case TYPE_POS_INTEGER_SPECIFIER:
case TYPE_UINTEGER_SPECIFIER:
case TYPE_DISCRETE_TIME_SPECIFIER:
{
// if( hasBitSizeConstraint() )
if( (dim > 0) && (dim <= 64) )
{
return( pow2(dim) );
}
else
{
return( AVM_NUMERIC_MAX_UINTEGER );
}
}
default:
{
return( AVM_NUMERIC_MAX_UINTEGER );
}
}
}
BF BaseTypeSpecifier::genConstraint(const BF & aParam) const
{
if( hasConstraint() )
{
AVM_OS_FATAL_ERROR_EXIT
<< "TODO << TypeSpecifier::genConstraint( "
<< aParam << " ) >> with compiled constraint:" << std::endl
<< getConstraint()
<< SEND_EXIT;
}
const avm_size_t dim = getBitSize();
switch( mSpecifierKind )
{
case TYPE_INTEGER_SPECIFIER:
case TYPE_RATIONAL_SPECIFIER:
case TYPE_FLOAT_SPECIFIER:
case TYPE_REAL_SPECIFIER:
{
// if( hasBitSizeConstraint() )
if( (dim > 0) && (dim <= 64) )
{
return( ExpressionConstructorNative::andExpr(
ExpressionConstructorNative::gteExpr(aParam,
ExpressionConstructorNative::newInteger(
(- pow2(dim - 1)))),
ExpressionConstructorNative::lteExpr(aParam,
ExpressionConstructorNative::newInteger(
pow2(dim - 1) - 1))) );
}
else
{
return( ExpressionConstant::BOOLEAN_TRUE );
}
}
case TYPE_UINTEGER_SPECIFIER:
case TYPE_URATIONAL_SPECIFIER:
case TYPE_CONTINUOUS_TIME_SPECIFIER:
case TYPE_DISCRETE_TIME_SPECIFIER:
case TYPE_UFLOAT_SPECIFIER:
case TYPE_UREAL_SPECIFIER:
{
// if( hasBitSizeConstraint() )
if( (dim > 0) && (dim <= 64) )
{
return( ExpressionConstructorNative::andExpr(
ExpressionConstructorNative::gteExpr(aParam,
ExpressionConstant::INTEGER_ZERO),
ExpressionConstructorNative::lteExpr(aParam,
ExpressionConstructorNative::newInteger(
pow2(dim)))) );
}
else
{
return( ExpressionConstructorNative::gteExpr(aParam,
ExpressionConstant::INTEGER_ZERO) );
}
}
case TYPE_POS_INTEGER_SPECIFIER:
{
// if( hasBitSizeConstraint() )
if( (dim > 0) && (dim <= 64) )
{
return( ExpressionConstructorNative::andExpr(
ExpressionConstructorNative::gtExpr(aParam,
ExpressionConstant::INTEGER_ZERO),
ExpressionConstructorNative::lteExpr(aParam,
ExpressionConstructorNative::newInteger(
pow2(dim)))) );
}
else
{
return( ExpressionConstructorNative::gtExpr(aParam,
ExpressionConstant::INTEGER_ZERO) );
}
}
default:
{
return( ExpressionConstant::BOOLEAN_TRUE );
}
}
}
/**
* GETTER
* refered (as typedef) TypeSpecifier
*/
BaseTypeSpecifier * BaseTypeSpecifier::referedTypeSpecifier()
{
return( this->isTypedAlias() ?
as< TypeAliasSpecifier >()->targetTypeSpecifier() : this );
}
/**
* Format a value w.r.t. its type
*/
void BaseTypeSpecifier::formatStream(
OutStream & out, const BF & bfValue) const
{
if( bfValue.is< ArrayBF >() )
{
formatStream(out, bfValue.as_ref< ArrayBF >());
}
else
{
out << bfValue.str();
}
}
void BaseTypeSpecifier::formatStream(
OutStream & out, const ArrayBF & arrayValue) const
{
formatStream(out, arrayValue[0]);
for( avm_size_t offset = 1 ; offset < arrayValue.size() ; ++offset )
{
out << out.VALUE_STRUCT_CSS.SEPARATOR;
formatStream(out, arrayValue[offset]);
}
}
/**
* Serialization
*/
void BaseTypeSpecifier::strHeader(OutStream & out) const
{
out << "type< " << strSpecifierKind() << " > " << getFullyQualifiedNameID();
}
void BaseTypeSpecifier::toStream(OutStream & out) const
{
if( out.preferablyFQN() )
{
out << TAB << getFullyQualifiedNameID();
AVM_DEBUG_REF_COUNTER(out);
return;
}
out << TAB << "type<base> " << getFullyQualifiedNameID()
<< " as " << strSpecifierKind() << " {" << EOL;
AVM_IF_DEBUG_FLAG( COMPILING )
if( hasAstElement() )
{
out << TAB2 << "//compiled = "
<< getAstFullyQualifiedNameID() << ";" << EOL;
}
AVM_ENDIF_DEBUG_FLAG( COMPILING )
out << TAB << "property:" << EOL
<< TAB2 << "size = " << size() << ";" << EOL
<< TAB2 << "data_size = " << getDataSize() << ";" << EOL
<< TAB2 << "bit_size = " << getBitSize() << ";" << EOL;
if( hasDefaultValue() )
{
out << TAB2 << "default = " << getDefaultValue().str() << ";" << EOL;
}
if( hasConstraint() )
{
out << TAB2 << "constraint {" << INCR2_INDENT;
getConstraint().toStream(out);
out << DECR2_INDENT_TAB << "}" << EOL;
}
out << TAB << "}" << EOL_FLUSH;
}
}