blob: 780e9cee6893283fc68d96ef273d35c03a848811 [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 avr. 2011
*
* Contributors:
* Arnault Lapitre (CEA LIST) arnault.lapitre@cea.fr
* - Initial API and implementation
******************************************************************************/
#ifndef ABSTRACTAVMCODECOMPILER_H_
#define ABSTRACTAVMCODECOMPILER_H_
#include <common/AvmObject.h>
#include <builder/compiler/BaseCompilerTable.h>
#include <builder/primitive/AvmcodeCompiler.h>
#include <builder/primitive/CompilationEnvironment.h>
#include <fml/expression/AvmCode.h>
#include <fml/type/BaseTypeSpecifier.h>
namespace sep
{
class ArrayBF;
class AvmBytecode;
class BaseAvmProgram;
class Element;
class ExecutableForm;
class SymbolTable;
class AbstractAvmcodeCompiler : public AvmObject
{
public:
/**
* CONSTRUCTOR
* Default
*/
AbstractAvmcodeCompiler(AvmcodeCompiler & aCodeCompiler)
: AvmObject( ),
AVMCODE_COMPILER( aCodeCompiler )
{
//!! NOTHING
}
/**
* DESTRUCTOR
*/
virtual ~AbstractAvmcodeCompiler()
{
//!! NOTHING
}
/*
* GETTER
* theCompilerTable
*/
inline BaseCompilerTable & getCompilerTable()
{
return( AVMCODE_COMPILER.getCompilerTable() );
}
/*
* GETTER
* theSymbolTable
*/
inline SymbolTable & getSymbolTable()
{
return( AVMCODE_COMPILER.getSymbolTable() );
}
////////////////////////////////////////////////////////////////////////////
// SPECIFIC ARGUMENT COMPILATION
////////////////////////////////////////////////////////////////////////////
BF compileArgLvalue(COMPILE_CONTEXT * aCTX, const BF & arg);
BF compileArgRvalue(COMPILE_CONTEXT * aCTX,
const TypeSpecifier & aType, const BF & arg)
{
return( compileArgRvalue(aCTX->clone(aType), arg,
(aType != TypeManager::UNIVERSAL)) );
}
BF compileArgRvalue(COMPILE_CONTEXT * aCTX, const BF & arg,
bool needTypeChecking = false);
inline BF compileArgStatement(COMPILE_CONTEXT * aCTX, const BF & arg)
{
return( AVMCODE_COMPILER.decode_compileStatement(aCTX, arg) );
}
////////////////////////////////////////////////////////////////////////////
// EXPRESSION COMPILATION STEP
////////////////////////////////////////////////////////////////////////////
BFCode compileExpressionCode(COMPILE_CONTEXT * aCTX,
const BFCode & aCode);
inline virtual BF compileExpression(COMPILE_CONTEXT * aCTX,
const BFCode & aCode)
{
return( compileExpressionCode(aCTX, aCode) );
}
BFCode optimizeExpressionCode(COMPILE_CONTEXT * aCTX, const BFCode & aCode,
avm_arg_operand_t anOperand = AVM_ARG_EXPRESSION_KIND);
inline virtual BF optimizeExpression(COMPILE_CONTEXT * aCTX,
const BFCode & aCode)
{
return( optimizeExpressionCode(aCTX, aCode) );
}
inline void optimizeArgExpression(COMPILE_CONTEXT * aCTX,
const BFCode & aCode, avm_offset_t offset)
{
if( aCode->at(offset).is< AvmCode >() )
{
aCode->safe_set( offset,
AVMCODE_COMPILER.optimizeExpression(
aCTX, aCode->at(offset).bfCode()) );
}
}
inline void optimizeArgStatement(COMPILE_CONTEXT * aCTX,
const BFCode & aCode, avm_offset_t offset)
{
if( aCode->at(offset).is< AvmCode >() )
{
aCode->safe_set( offset,
AVMCODE_COMPILER.optimizeStatement(
aCTX, aCode->at(offset).bfCode()) );
}
}
inline void optimizeArgExpression(COMPILE_CONTEXT * aCTX,
BFCodeList & listOfCodes)
{
BFCodeList::iterator itCode = listOfCodes.begin();
BFCodeList::iterator endCode = listOfCodes.end();
for( ; itCode != endCode ; ++itCode )
{
(*itCode) = AVMCODE_COMPILER.optimizeExpression(aCTX, (*itCode));
}
}
inline void optimizeArgStatement(COMPILE_CONTEXT * aCTX,
BFCodeList & listOfCodes)
{
BFCodeList::iterator itCode = listOfCodes.begin();
BFCodeList::iterator endCode = listOfCodes.end();
for( ; itCode != endCode ; ++itCode )
{
(*itCode) = AVMCODE_COMPILER.optimizeStatement(aCTX, (*itCode));
}
}
////////////////////////////////////////////////////////////////////////////
// STATEMENT COMPILATION STEP
////////////////////////////////////////////////////////////////////////////
virtual BFCode compileStatementCode(COMPILE_CONTEXT * aCTX,
const BFCode & aCode);
inline virtual BFCode optimizeStatementCode(COMPILE_CONTEXT * aCTX,
const BFCode & aCode)
{
return( optimizeExpressionCode(aCTX, aCode, AVM_ARG_STATEMENT_KIND) );
}
inline virtual BFCode compileStatement(COMPILE_CONTEXT * aCTX,
const BFCode & aCode)
{
return( compileStatementCode(aCTX, aCode) );
}
inline virtual BFCode optimizeStatement(COMPILE_CONTEXT * aCTX,
const BFCode & aCode)
{
return( aCode );
// return( optimizeStatementCode(aCTX, aCode) );
}
////////////////////////////////////////////////////////////////////////////
// AVMCODE COMPILATION STEP
////////////////////////////////////////////////////////////////////////////
virtual BFCode compileAvmcode(COMPILE_CONTEXT * aCTX, const BFCode & aCode);
////////////////////////////////////////////////////////////////////////////
// AVM OPCODE COMPILATION
////////////////////////////////////////////////////////////////////////////
static bool mustBeEvaluatedArgument(const BF & arg);
static bool mustBeEvaluatedArgumentArray(ArrayBF * arrayArg);
avm_arg_operand_t operandOf(const BF & arg);
avm_arg_processor_t processorOf(BaseTypeSpecifier * aType);
avm_arg_operand_t operandOf(BaseTypeSpecifier * aType);
void setArgcodeLValue(COMPILE_CONTEXT * aCTX, AvmBytecode & argCode,
const BF & arg, bool needTypeChecking = true);
void setArgcodeLValueRef(COMPILE_CONTEXT * aCTX, AvmBytecode & argCode,
const BF & arg, bool needTypeChecking = true);
void setArgcodeLValueMacro(COMPILE_CONTEXT * aCTX, AvmBytecode & argCode,
const BF & arg, bool needTypeChecking = true);
void setArgcodeRValue(COMPILE_CONTEXT * aCTX, AvmBytecode & argCode,
BF & arg, bool needTypeChecking = true);
AvmBytecode argcodeOfExpression(COMPILE_CONTEXT * aCTX, AvmCode * aCode);
void setArgcodeRValueArray(COMPILE_CONTEXT * aCTX, AvmBytecode & argCode,
BF & arg, bool needTypeChecking = true);
void setArgcodeRValueArray(COMPILE_CONTEXT * aCTX, AvmBytecode & argCode,
ArrayBF * arg, bool needTypeChecking = true);
inline void setArgcodeParamValue(COMPILE_CONTEXT * aCTX,
AvmBytecode & argCode, BF & arg,
bool needTypeChecking = true)
{
setArgcodeRValue(aCTX, argCode, arg, needTypeChecking);
argCode.context = AVM_ARG_PARAMETER_CTX;
}
void setArgcodeContainerWValue(COMPILE_CONTEXT * aCTX,
AvmBytecode & argCode, const BF & arg);
void setArgcodeContainerRValue(COMPILE_CONTEXT * aCTX,
AvmBytecode & argCode, const BF & arg);
void setArgcodeStatement(COMPILE_CONTEXT * aCTX, AvmBytecode & argCode,
const BF & arg, bool needTypeChecking = true);
ExecutableForm * getExecutableMachine(COMPILE_CONTEXT * aCTX, const BF & arg);
void checkArgType(COMPILE_CONTEXT * aCTX,
BaseTypeSpecifier * aType, const BF & arg);
protected:
/**
* ATTRIBUTES
*/
AvmcodeCompiler & AVMCODE_COMPILER;
};
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// Macro for smart avmcode compiler declaration.
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
#define AVMCODE_BASECOMPILER_CLASS_HEADER(classname, supername) \
class classname : public supername \
{ \
public: \
classname(AvmcodeCompiler & aCompiler) \
: supername( aCompiler ) \
{ /*!! NOTHING !!*/ } \
virtual ~classname() \
{ /*!! NOTHING !!*/ }
/**
* Macro for smart avmcode compiler declaration.
*/
#define AVMCODE_COMPILER_CLASS_HEADER(classname, supername) \
AVMCODE_BASECOMPILER_CLASS_HEADER(Avmcode##classname##Compiler, supername) \
virtual BF compileExpression(COMPILE_CONTEXT * aCTX, const BFCode & aCode);\
virtual BFCode compileStatement(COMPILE_CONTEXT * aCTX, const BFCode & aCode);
#define AVMCODE_COMPILER_CLASS(classname, supername) \
AVMCODE_COMPILER_CLASS_HEADER(classname, supername) \
};
#define AVMCODE_COMPILER_EXPRESSION_CLASS_HEADER(name, classname, supername) \
AVMCODE_BASECOMPILER_CLASS_HEADER(Avmcode##classname##Compiler, supername) \
virtual BF compileExpression(COMPILE_CONTEXT * aCTX, const BFCode & aCode);\
BFCode compileStatement(COMPILE_CONTEXT * aCTX, const BFCode & aCode) \
{ \
AVM_OS_FATAL_ERROR_EXIT << "Unexpected << " << name \
<< " >> EXPRESSION as statement compilation !!!" \
<< SEND_EXIT; \
return( aCode ); \
}
#define AVMCODE_COMPILER_EXPRESSION_CLASS(name, classname, supername) \
AVMCODE_COMPILER_EXPRESSION_CLASS_HEADER(name, classname, supername) \
};
#define AVMCODE_COMPILER_STATEMENT_CLASS_HEADER(name, classname, supername) \
AVMCODE_BASECOMPILER_CLASS_HEADER(Avmcode##classname##Compiler, supername) \
BF compileExpression(COMPILE_CONTEXT * aCTX, const BFCode & aCode) \
{ \
AVM_OS_FATAL_ERROR_EXIT << "Unexpected << " << name \
<< " STATEMENT as expression compilation !!!" \
<< SEND_EXIT; \
return( aCode ); \
} \
virtual BFCode compileStatement(COMPILE_CONTEXT * aCTX, const BFCode & aCode);
#define AVMCODE_COMPILER_STATEMENT_CLASS(name, classname, supername) \
AVMCODE_COMPILER_STATEMENT_CLASS_HEADER(name, classname, supername) \
};
#define AVMCODE_COMPILER_OPTIMIZER_CLASS_HEADER(classname, supername) \
AVMCODE_BASECOMPILER_CLASS_HEADER(Avmcode##classname##Compiler, supername) \
virtual BF compileExpression(COMPILE_CONTEXT * aCTX, const BFCode & aCode);\
virtual BF optimizeExpression(COMPILE_CONTEXT * aCTX, const BFCode & aCode); \
virtual BFCode compileStatement(COMPILE_CONTEXT * aCTX, const BFCode & aCode); \
virtual BFCode optimizeStatement(COMPILE_CONTEXT * aCTX, const BFCode & aCode);
#define AVMCODE_COMPILER_OPTIMIZER_CLASS(classname, supername) \
AVMCODE_COMPILER_OPTIMIZER_CLASS_HEADER(classname, supername) \
};
#define AVMCODE_COMPILER_EXPRESSION_OPTIMIZER_CLASS_HEADER(name, classname, supername) \
AVMCODE_BASECOMPILER_CLASS_HEADER(Avmcode##classname##Compiler, supername) \
virtual BF compileExpression(COMPILE_CONTEXT * aCTX, const BFCode & aCode);\
virtual BF optimizeExpression(COMPILE_CONTEXT * aCTX, const BFCode & aCode); \
BFCode compileStatement(COMPILE_CONTEXT * aCTX, const BFCode & aCode) \
{ \
AVM_OS_FATAL_ERROR_EXIT << "Unexpected << " << name \
<< " >> EXPRESSION as statement compilation !!!" \
<< SEND_EXIT; \
return( aCode ); \
} \
BFCode optimizeStatement(COMPILE_CONTEXT * aCTX, const BFCode & aCode) \
{ \
AVM_OS_FATAL_ERROR_EXIT << "Unexpected << " << name \
<< " >> EXPRESSION as statement optimization !!!" \
<< SEND_EXIT; \
return( aCode ); \
}
#define AVMCODE_COMPILER_EXPRESSION_OPTIMIZER_CLASS(name, classname, supername) \
AVMCODE_COMPILER_EXPRESSION_OPTIMIZER_CLASS_HEADER(name, classname, supername) \
};
#define AVMCODE_COMPILER_STATEMENT_OPTIMIZER_CLASS_HEADER(name, classname, supername) \
AVMCODE_BASECOMPILER_CLASS_HEADER(Avmcode##classname##Compiler, supername) \
BF compileExpression(COMPILE_CONTEXT * aCTX, const BFCode & aCode) \
{ \
AVM_OS_FATAL_ERROR_EXIT << "Unexpected << " << name \
<< " >> STATEMENT as expression compilation !!!" \
<< SEND_EXIT; \
return( aCode ); \
} \
BF optimizeExpression(COMPILE_CONTEXT * aCTX, const BFCode & aCode) \
{ \
AVM_OS_FATAL_ERROR_EXIT << "Unexpected << " << name \
<< " >> STATEMENT as expression optimization !!!" \
<< SEND_EXIT; \
return( aCode ); \
} \
virtual BFCode compileStatement(COMPILE_CONTEXT * aCTX, const BFCode & aCode); \
virtual BFCode optimizeStatement(COMPILE_CONTEXT * aCTX, const BFCode & aCode);
#define AVMCODE_COMPILER_STATEMENT_OPTIMIZER_CLASS(name, classname, supername) \
AVMCODE_COMPILER_STATEMENT_OPTIMIZER_CLASS_HEADER(name, classname, supername) \
};
#define AVMCODE_COMPILER_NO_OPTIMIZER_CLASS_HEADER(name, classname, supername) \
AVMCODE_BASECOMPILER_CLASS_HEADER(Avmcode##classname##Compiler, supername) \
BF compileExpression(COMPILE_CONTEXT * aCTX, const BFCode & aCode); \
BF optimizeExpression(COMPILE_CONTEXT * aCTX, const BFCode & aCode) \
{ \
AVM_OS_FATAL_ERROR_EXIT << "Unexpected invoke of " << name \
<< " >> STATEMENT as expression optimization !!!" \
<< SEND_EXIT; \
return( aCode ); \
} \
virtual BFCode compileStatement(COMPILE_CONTEXT * aCTX, const BFCode & aCode); \
virtual BFCode optimizeStatement(COMPILE_CONTEXT * aCTX, const BFCode & aCode) \
{ \
AVM_OS_FATAL_ERROR_EXIT << "Unexpected invoke of " << name \
<< " >> EXPRESSION as statement optimization !!!" \
<< SEND_EXIT; \
return( aCode ); \
} \
#define AVMCODE_COMPILER_NO_OPTIMIZER_CLASS(name, classname, supername) \
AVMCODE_COMPILER_NO_OPTIMIZER_CLASS_HEADER(name, classname, supername) \
};
/**
* Macro for smart avmcode compiler declaration.
*
#define AVMCODE_COMPILER_EXPRESSION_CLASS_HEADER(classname, supername) \
AVMCODE_BASECOMPILER_CLASS_HEADER(Avmcode##classname##Compiler, supername) \
virtual BF compileExpression(COMPILE_CONTEXT * aCTX, const BFCode & aCode);
#define AVMCODE_COMPILER_EXPRESSION_CLASS(classname, supername) \
AVMCODE_COMPILER_EXPRESSION_CLASS_HEADER(classname, supername) \
};
*/
/**
* Macro for smart avmcode compiler declaration.
*
#define AVMCODE_COMPILER_STATEMENT_CLASS_HEADER(classname, supername) \
AVMCODE_BASECOMPILER_CLASS_HEADER(Avmcode##classname##Compiler, supername) \
virtual BFCode compileStatement(COMPILE_CONTEXT * aCTX, const BFCode & aCode);
#define AVMCODE_COMPILER_STATEMENT_CLASS(classname, supername) \
AVMCODE_COMPILER_STATEMENT_CLASS_HEADER(classname, supername) \
};
*/
}
#endif /* ABSTRACTAVMCODECOMPILER_H_ */