blob: 9170df8025c163a2360b4d524982187551bec569 [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
******************************************************************************/
#include "AvmcodeCompiler.h"
#include <iostream>
#include <builder/compiler/BaseCompiler.h>
#include <builder/compiler/BaseCompilerTable.h>
#include <builder/primitive/AbstractAvmcodeCompiler.h>
#include <builder/primitive/AvmcodeActivityCompiler.h>
#include <builder/primitive/AvmcodeAssignCompiler.h>
#include <builder/primitive/AvmcodeCommunicationCompiler.h>
#include <builder/primitive/AvmcodeContainerCompiler.h>
#include <builder/primitive/AvmcodeCtorExpressionCompiler.h>
#include <builder/primitive/AvmcodeExpressionCompiler.h>
#include <builder/primitive/AvmcodeGinacCompiler.h>
#include <builder/primitive/AvmcodeGuardCompiler.h>
#include <builder/primitive/AvmcodeInvokeCompiler.h>
#include <builder/primitive/AvmcodeIteCompiler.h>
#include <builder/primitive/AvmcodeJumpCompiler.h>
#include <builder/primitive/AvmcodeLambdaCompiler.h>
#include <builder/primitive/AvmcodeLookupExprCompiler.h>
#include <builder/primitive/AvmcodeLoopCompiler.h>
#include <builder/primitive/AvmcodeMachineStatusCompiler.h>
#include <builder/primitive/AvmcodeMathFunctionCompiler.h>
#include <builder/primitive/AvmcodeMetaStatementCompiler.h>
#include <builder/primitive/AvmcodeQueueCompiler.h>
#include <builder/primitive/AvmcodeSchedulingCompiler.h>
#include <builder/primitive/AvmcodeSequenceCompiler.h>
#include <builder/primitive/AvmcodeUfiCastExpressionCompiler.h>
#include <builder/primitive/AvmcodeVariableStatusCompiler.h>
#include <fml/common/SpecifierElement.h>
#include <fml/executable/AvmProgram.h>
#include <fml/executable/BaseAvmProgram.h>
#include <fml/executable/ExecutableForm.h>
#include <fml/executable/InstanceOfData.h>
#include <fml/executable/InstanceOfPort.h>
#include <fml/expression/AvmCode.h>
#include <fml/expression/BuiltinArray.h>
#include <fml/expression/BuiltinContainer.h>
#include <fml/expression/ExpressionConstructor.h>
#include <fml/expression/StatementFactory.h>
#include <fml/operator/Operator.h>
#include <fml/operator/OperatorManager.h>
#include <fml/type/TypeManager.h>
#include <fml/infrastructure/Buffer.h>
#include <fml/infrastructure/Connector.h>
#include <fml/infrastructure/DataType.h>
#include <fml/infrastructure/Machine.h>
#include <fml/infrastructure/Port.h>
#include <fml/infrastructure/Routine.h>
#include <fml/infrastructure/Transition.h>
#include <fml/infrastructure/Variable.h>
#include <fml/workflow/UniFormIdentifier.h>
#include <sew/Configuration.h>
namespace sep
{
#define NEW_COMPILER( OP_AC ) \
( AVMCODE_COMPILER_TABLE_FOR_DESTROY.push_back( new OP_AC( *this ) ) , \
AVMCODE_COMPILER_TABLE_FOR_DESTROY.back() )
#define OPCODE_COMPILER( OP_ID ) \
AVMCODE_COMPILER_TABLE[ OperatorManager::OPERATOR_##OP_ID->getOffset() ]
/**
* DESTRUCTOR
*/
AvmcodeCompiler::~AvmcodeCompiler()
{
AVMCODE_COMPILER_TABLE.clear();
std::vector< AbstractAvmcodeCompiler * >::iterator it =
AVMCODE_COMPILER_TABLE_FOR_DESTROY.begin();
std::vector< AbstractAvmcodeCompiler * >::iterator endIt =
AVMCODE_COMPILER_TABLE_FOR_DESTROY.end();
for( avm_size_t offset = 0 ; it != endIt ; ++it , ++offset )
{
delete( *it );
}
delete( UFI_EXPRESSION_COMPILER );
AVMCODE_COMPILER_TABLE_FOR_DESTROY.clear();
}
/*
* GETTER
* theSymbolTable
*/
SymbolTable & AvmcodeCompiler::getSymbolTable()
{
return( mCompilerTable.getSymbolTable() );
}
/**
* CONFIGURE
*/
bool AvmcodeCompiler::configure()
{
DEFAULT_AVMCODE_COMPILER =NEW_COMPILER( AbstractAvmcodeCompiler );
NOTHING_AVMCODE_COMPILER =NEW_COMPILER( AvmcodeNothingCompiler );
UNARY_ARITHMETIC_EXPRESSION_COMPILER =
NEW_COMPILER( AvmcodeUnaryArithmeticExpressionALUCompiler );
BINARY_ARITHMETIC_EXPRESSION_COMPILER =
NEW_COMPILER( AvmcodeBinaryArithmeticExpressionALUCompiler );
ASSOCIATIVE_ARITHMETIC_EXPRESSION_COMPILER =
NEW_COMPILER( AvmcodeAssociativeArithmeticExpressionALUCompiler );
UNARY_BITWISE_EXPRESSION_COMPILER =
NEW_COMPILER( AvmcodeUnaryBitwiseExpressionCompiler );
BINARY_BITWISE_EXPRESSION_COMPILER =
NEW_COMPILER( AvmcodeBinaryBitwiseExpressionCompiler );
ASSOCIATIVE_BITWISE_EXPRESSION_COMPILER =
NEW_COMPILER( AvmcodeAssociativeBitwiseExpressionCompiler );
UNARY_PREDICATE_EXPRESSION_COMPILER =
NEW_COMPILER( AvmcodeUnaryPredicateExpressionCompiler );
BINARY_PREDICATE_EXPRESSION_COMPILER =
NEW_COMPILER( AvmcodeBinaryPredicateExpressionCompiler );
ASSOCIATIVE_PREDICATE_EXPRESSION_COMPILER =
NEW_COMPILER( AvmcodeAssociativePredicateExpressionCompiler );
RELATIONAL_EXPRESSION_COMPILER =
NEW_COMPILER( AvmcodeRelationalExpressionCompiler );
UNARY_STRING_EXPRESSION_COMPILER =
NEW_COMPILER( AvmcodeUnaryStringExpressionCompiler );
BINARY_STRING_EXPRESSION_COMPILER =
NEW_COMPILER( AvmcodeBinaryStringExpressionCompiler );
ASSOCIATIVE_STRING_EXPRESSION_COMPILER =
NEW_COMPILER( AvmcodeAssociativeStringExpressionCompiler );
LOOKUP_EXPRESSION_COMPILER =
NEW_COMPILER( AvmcodeLookupExpressionCompiler );
MACHINE_STATUS_EXPRESSION_COMPILER =
NEW_COMPILER( AvmcodeMachineStatusExpressionCompiler );
MATH_FUNCTION_COMPILER =
NEW_COMPILER( AvmcodeMathFunctionCompiler );
UFI_EXPRESSION_COMPILER =
new AvmcodeUfiExpressionCompiler( *this );
VARIABLE_STATUS_EXPRESSION_COMPILER =
NEW_COMPILER( AvmcodeVariableStatusExpressionCompiler );
ACTIVITY_STATEMENT_COMPILER =
NEW_COMPILER( AvmcodeActivityStatementCompiler );
SCHEDULING_STATEMENT_COMPILER =
NEW_COMPILER( AvmcodeSchedulingCompiler );
SEQUENCE_STATEMENT_COMPILER =
NEW_COMPILER( AvmcodeSequenceCompiler );
ITE_STATEMENT_COMPILER =
NEW_COMPILER( AvmcodeIteCompiler );
UNARY_CONTAINER_STATEMENT =
NEW_COMPILER( AvmcodeUnaryContainerStatementCompiler );
UNARY_WRITE_CONTAINER_STATEMENT =
NEW_COMPILER( AvmcodeUnaryWriteContainerStatementCompiler );
BINARY_CONTAINER_STATEMENT =
NEW_COMPILER( AvmcodeBinaryContainerStatementCompiler );
BINARY_WRITE_CONTAINER_STATEMENT =
NEW_COMPILER( AvmcodeBinaryWriteContainerStatementCompiler );
//DEFAULT_AVMCODE_COMPILER);
AVMCODE_COMPILER_TABLE.resize(
OperatorManager::TABLE_OF_OPERATOR.size(),
DEFAULT_AVMCODE_COMPILER );
if( not configureOther() )
{
return( false );
}
if( not configureMeta() )
{
return( false );
}
if( not configureLambdaPrimitive() )
{
return( false );
}
if( not configureActivityPrimitive() )
{
return( false );
}
if( not configureStatusPrimitive() )
{
return( false );
}
if( not configureSchedulingPrimitive() )
{
return( false );
}
if( not configureBasicPrimitive() )
{
return( false );
}
if( not configureArithmeticPrimitive() )
{
return( false );
}
if( not configureBitwisePrimitive() )
{
return( false );
}
if( not configureLogicPrimitive() )
{
return( false );
}
if( not configureLookupPrimitive() )
{
return( false );
}
if( not configureMathematicPrimitive() )
{
return( false );
}
if( not configureStringCollectionPrimitive() )
{
return( false );
}
if( not configureIoltPrimitive() )
{
return( false );
}
return( true );
}
bool AvmcodeCompiler::configureOther()
{
////////////////////////////////////////////////////////////////////////////
// AVM UFI STATEMENT
////////////////////////////////////////////////////////////////////////////
OPCODE_COMPILER( UFI ) = UFI_EXPRESSION_COMPILER;
////////////////////////////////////////////////////////////////////////////
// AVM CAST STATEMENT
////////////////////////////////////////////////////////////////////////////
OPCODE_COMPILER( CTOR ) = NEW_COMPILER( AvmcodeCtorExpressionCompiler );
////////////////////////////////////////////////////////////////////////////
// AVM GINAC EXPRESSION & STATEMENT
////////////////////////////////////////////////////////////////////////////
// mGinacPrimitive = NEW_COMPILER( AbstractAvmcodeCompiler );
return( true );
}
bool AvmcodeCompiler::configureMeta()
{
////////////////////////////////////////////////////////////////////////////
// AVM NOP STATEMENT
////////////////////////////////////////////////////////////////////////////
OPCODE_COMPILER( NOP ) = NOTHING_AVMCODE_COMPILER;
////////////////////////////////////////////////////////////////////////////
// AVM META STATEMENT
////////////////////////////////////////////////////////////////////////////
OPCODE_COMPILER( INFORMAL ) = NEW_COMPILER( AvmcodeInformalExpressionCompiler );
OPCODE_COMPILER( TRACE ) = NEW_COMPILER( AvmcodeTraceExpressionCompiler );
OPCODE_COMPILER( DEBUG ) = NEW_COMPILER( AvmcodeDebugExpressionCompiler );
OPCODE_COMPILER( COMMENT ) = NEW_COMPILER( AvmcodeCommentExpressionCompiler );
OPCODE_COMPILER( QUOTE ) = DEFAULT_AVMCODE_COMPILER;
OPCODE_COMPILER( META_EVAL ) = NEW_COMPILER( AvmcodeMetaEvalStatementCompiler );
OPCODE_COMPILER( META_RUN ) = NEW_COMPILER( AvmcodeMetaRunStatementCompiler );
return( true );
}
bool AvmcodeCompiler::configureLambdaPrimitive()
{
////////////////////////////////////////////////////////////////////////////
// LAMBDA STATEMENT
////////////////////////////////////////////////////////////////////////////
OPCODE_COMPILER( APPLY ) = NEW_COMPILER( AvmcodeLambdaApplyCompiler );
OPCODE_COMPILER( LAMBDA ) = NEW_COMPILER( AvmcodeLambdaExprCompiler );
////////////////////////////////////////////////////////////////////////////
// LET STATEMENT
////////////////////////////////////////////////////////////////////////////
OPCODE_COMPILER( LET ) = NEW_COMPILER( AvmcodeLambdaLetCompiler );
return( true );
}
bool AvmcodeCompiler::configureActivityPrimitive()
{
////////////////////////////////////////////////////////////////////////////
// AVM MACHINE MANAGING
////////////////////////////////////////////////////////////////////////////
OPCODE_COMPILER( CONTEXT_SWITCHER ) = NEW_COMPILER( AvmcodeContextSwitcherStatementCompiler );
OPCODE_COMPILER( INIT ) = ACTIVITY_STATEMENT_COMPILER;
OPCODE_COMPILER( FINAL ) = ACTIVITY_STATEMENT_COMPILER;
OPCODE_COMPILER( DESTROY ) = ACTIVITY_STATEMENT_COMPILER;
OPCODE_COMPILER( START ) = ACTIVITY_STATEMENT_COMPILER;
OPCODE_COMPILER( RESTART ) = ACTIVITY_STATEMENT_COMPILER;
OPCODE_COMPILER( STOP ) = ACTIVITY_STATEMENT_COMPILER;
OPCODE_COMPILER( WAIT ) = ACTIVITY_STATEMENT_COMPILER;
OPCODE_COMPILER( SUSPEND ) = ACTIVITY_STATEMENT_COMPILER;
OPCODE_COMPILER( RESUME ) = ACTIVITY_STATEMENT_COMPILER;
OPCODE_COMPILER( IENABLE_INVOKE ) = NEW_COMPILER( AvmcodeIEnableStatementCompiler );
OPCODE_COMPILER( ENABLE_INVOKE ) = NEW_COMPILER( AvmcodeEnableStatementCompiler );
OPCODE_COMPILER( ENABLE_SET ) = ACTIVITY_STATEMENT_COMPILER;
OPCODE_COMPILER( IDISABLE_INVOKE ) = NEW_COMPILER( AvmcodeIDisableStatementCompiler );
OPCODE_COMPILER( DISABLE_INVOKE ) = NEW_COMPILER( AvmcodeDisableStatementCompiler );
OPCODE_COMPILER( DISABLE_SET ) = ACTIVITY_STATEMENT_COMPILER;
OPCODE_COMPILER( DISABLE_CHILD ) = NOTHING_AVMCODE_COMPILER;
OPCODE_COMPILER( DISABLE_SELF ) = NOTHING_AVMCODE_COMPILER;
OPCODE_COMPILER( DISABLE_SELVES ) = NEW_COMPILER( AvmcodeDisableSelvesStatementCompiler );
OPCODE_COMPILER( IABORT_INVOKE ) = NEW_COMPILER( AvmcodeIAbortStatementCompiler );
OPCODE_COMPILER( ABORT_INVOKE ) = NEW_COMPILER( AvmcodeAbortStatementCompiler );
OPCODE_COMPILER( ABORT_SET ) = ACTIVITY_STATEMENT_COMPILER;
OPCODE_COMPILER( ABORT_CHILD ) = NOTHING_AVMCODE_COMPILER;
OPCODE_COMPILER( ABORT_SELF ) = NOTHING_AVMCODE_COMPILER;
OPCODE_COMPILER( ABORT_SELVES ) = NEW_COMPILER( AvmcodeAbortSelvesStatementCompiler );
OPCODE_COMPILER( HISTORY_CLEAR ) = ACTIVITY_STATEMENT_COMPILER;
OPCODE_COMPILER( DEEP_HISTORY_INVOKE ) = ACTIVITY_STATEMENT_COMPILER;
OPCODE_COMPILER( SHALLOW_HISTORY_INVOKE ) = ACTIVITY_STATEMENT_COMPILER;
OPCODE_COMPILER( IRUN ) = ACTIVITY_STATEMENT_COMPILER;
OPCODE_COMPILER( RUN ) = ACTIVITY_STATEMENT_COMPILER;
OPCODE_COMPILER( RTC ) = NEW_COMPILER( AvmcodeRtcStatementCompiler );
OPCODE_COMPILER( INVOKE_NEW ) = NEW_COMPILER( AvmcodeInvokeNewCompiler );
OPCODE_COMPILER( INVOKE_ROUTINE ) = NEW_COMPILER( AvmcodeInvokeRoutineCompiler );
OPCODE_COMPILER( INVOKE_TRANSITION ) = NEW_COMPILER( AvmcodeInvokeTransitionCompiler );
OPCODE_COMPILER( INVOKE_METHOD ) = NEW_COMPILER( AvmcodeInvokeMethodCompiler );
OPCODE_COMPILER( INVOKE_PROGRAM ) = NEW_COMPILER( AvmcodeInvokeProgramCompiler );
OPCODE_COMPILER( INVOKE_FUNCTION ) = NEW_COMPILER( AvmcodeInvokeFunctionCompiler );
OPCODE_COMPILER( SCHEDULE_INVOKE ) = NEW_COMPILER( AvmcodeScheduleStatementCompiler );
OPCODE_COMPILER( SCHEDULE_GET ) = ACTIVITY_STATEMENT_COMPILER;
OPCODE_COMPILER( SCHEDULE_IN ) = NEW_COMPILER( AvmcodeScheduleInStatementCompiler );
OPCODE_COMPILER( SCHEDULE_SET ) = ACTIVITY_STATEMENT_COMPILER;
OPCODE_COMPILER( GOTO ) = NEW_COMPILER( AvmcodeGotoStatementCompiler );
OPCODE_COMPILER( FORK ) = NEW_COMPILER( AvmcodeForkStatementCompiler );
OPCODE_COMPILER( JOIN ) = NEW_COMPILER( AvmcodeJoinStatementCompiler );
OPCODE_COMPILER( INPUT_ENABLED ) = NEW_COMPILER( AvmcodeInputEnabledStatementCompiler );
OPCODE_COMPILER( RDV ) = ACTIVITY_STATEMENT_COMPILER;
OPCODE_COMPILER( SYNCHRONIZE ) = ACTIVITY_STATEMENT_COMPILER;
return( true );
}
bool AvmcodeCompiler::configureStatusPrimitive()
{
////////////////////////////////////////////////////////////////////////////
// AVM MACHINE STATUS
////////////////////////////////////////////////////////////////////////////
OPCODE_COMPILER( STATUS_WAS ) = MACHINE_STATUS_EXPRESSION_COMPILER;
OPCODE_COMPILER( STATUS_IS ) = MACHINE_STATUS_EXPRESSION_COMPILER;
OPCODE_COMPILER( STATUS_BEING ) = MACHINE_STATUS_EXPRESSION_COMPILER;
OPCODE_COMPILER( STATUS_WILL ) = MACHINE_STATUS_EXPRESSION_COMPILER;
OPCODE_COMPILER( CHANGED ) = VARIABLE_STATUS_EXPRESSION_COMPILER;
OPCODE_COMPILER( CHANGED_TO ) = VARIABLE_STATUS_EXPRESSION_COMPILER;
return( true );
}
bool AvmcodeCompiler::configureSchedulingPrimitive()
{
////////////////////////////////////////////////////////////////////////////
// AVM PROGRAM SCHEDULING
////////////////////////////////////////////////////////////////////////////
OPCODE_COMPILER( ASYNCHRONOUS ) = SCHEDULING_STATEMENT_COMPILER;
OPCODE_COMPILER( STRONG_SYNCHRONOUS ) = SCHEDULING_STATEMENT_COMPILER;
OPCODE_COMPILER( WEAK_SYNCHRONOUS ) = SCHEDULING_STATEMENT_COMPILER;
OPCODE_COMPILER( INTERLEAVING ) = SCHEDULING_STATEMENT_COMPILER;
OPCODE_COMPILER( PARALLEL ) = SCHEDULING_STATEMENT_COMPILER;
OPCODE_COMPILER( RDV_ASYNCHRONOUS ) = SCHEDULING_STATEMENT_COMPILER;
OPCODE_COMPILER( RDV_STRONG_SYNCHRONOUS ) = SCHEDULING_STATEMENT_COMPILER;
OPCODE_COMPILER( RDV_WEAK_SYNCHRONOUS ) = SCHEDULING_STATEMENT_COMPILER;
OPCODE_COMPILER( RDV_INTERLEAVING ) = SCHEDULING_STATEMENT_COMPILER;
OPCODE_COMPILER( RDV_PARALLEL ) = SCHEDULING_STATEMENT_COMPILER;
OPCODE_COMPILER( EXCLUSIVE ) = SCHEDULING_STATEMENT_COMPILER;
OPCODE_COMPILER( NONDETERMINISM ) = SCHEDULING_STATEMENT_COMPILER;
OPCODE_COMPILER( PRIOR_GT ) = SCHEDULING_STATEMENT_COMPILER;
OPCODE_COMPILER( PRIOR_LT ) = SCHEDULING_STATEMENT_COMPILER;
OPCODE_COMPILER( SCHEDULE_AND_THEN ) = SCHEDULING_STATEMENT_COMPILER;
OPCODE_COMPILER( SCHEDULE_OR_ELSE ) = SCHEDULING_STATEMENT_COMPILER;
OPCODE_COMPILER( ATOMIC_SEQUENCE ) = NEW_COMPILER( AvmcodeAtomicSequenceCompiler );
OPCODE_COMPILER( SEQUENCE ) = NEW_COMPILER( AvmcodeStrongSequenceCompiler );
OPCODE_COMPILER( SEQUENCE_SIDE ) = SEQUENCE_STATEMENT_COMPILER;
OPCODE_COMPILER( SEQUENCE_WEAK ) = SEQUENCE_STATEMENT_COMPILER;
OPCODE_COMPILER( PRODUCT ) = SCHEDULING_STATEMENT_COMPILER;
return( true );
}
bool AvmcodeCompiler::configureBasicPrimitive()
{
////////////////////////////////////////////////////////////////////////////
// AVM BUFFER MANAGING
////////////////////////////////////////////////////////////////////////////
OPCODE_COMPILER( UPDATE_BUFFER ) = DEFAULT_AVMCODE_COMPILER;
////////////////////////////////////////////////////////////////////////////
// AVM PRIMITIVE STATEMENT
////////////////////////////////////////////////////////////////////////////
OPCODE_COMPILER( ASSIGN ) = NEW_COMPILER( AvmcodeAssignCompiler );
OPCODE_COMPILER( ASSIGN_AFTER ) = NEW_COMPILER( AvmcodeAssignAfterCompiler );
OPCODE_COMPILER( ASSIGN_OP ) = NEW_COMPILER( AvmcodeAssignOpCompiler );
OPCODE_COMPILER( ASSIGN_OP_AFTER ) = NEW_COMPILER( AvmcodeAssignOpAfterCompiler );
OPCODE_COMPILER( ASSIGN_REF ) = NEW_COMPILER( AvmcodeAssignRefCompiler );
OPCODE_COMPILER( ASSIGN_MACRO ) = NEW_COMPILER( AvmcodeAssignMacroCompiler );
OPCODE_COMPILER( ASSIGN_NEWFRESH ) = NEW_COMPILER( AvmcodeAssignUnaryCompiler );
OPCODE_COMPILER( ASSIGN_RESET ) = OPCODE_COMPILER( ASSIGN_NEWFRESH );
OPCODE_COMPILER( GUARD ) = NEW_COMPILER( AvmcodeGuardCompiler );
OPCODE_COMPILER( TIMED_GUARD ) = NEW_COMPILER( AvmcodeTimedGuardCompiler );
OPCODE_COMPILER( EVENT ) = NEW_COMPILER( AvmcodeEventCompiler );
OPCODE_COMPILER( CHECK_SAT ) = NEW_COMPILER( AvmcodeChecksatCompiler );
OPCODE_COMPILER( INPUT ) = NEW_COMPILER( AvmcodeInputCompiler );
OPCODE_COMPILER( INPUT_FROM ) = NEW_COMPILER( AvmcodeInputFromCompiler );
OPCODE_COMPILER( INPUT_SAVE ) = NEW_COMPILER( AvmcodeInputSaveCompiler );
OPCODE_COMPILER( INPUT_VAR ) = NEW_COMPILER( AvmcodeInputVarCompiler );
OPCODE_COMPILER( INPUT_ENV ) = NEW_COMPILER( AvmcodeInputEnvCompiler );
OPCODE_COMPILER( OUTPUT ) = NEW_COMPILER( AvmcodeOutputCompiler );
OPCODE_COMPILER( OUTPUT_TO ) = NEW_COMPILER( AvmcodeOutputToCompiler );
OPCODE_COMPILER( OUTPUT_VAR ) = NEW_COMPILER( AvmcodeOutputVarCompiler );
OPCODE_COMPILER( OUTPUT_ENV ) = NEW_COMPILER( AvmcodeOutputEnvCompiler );
OPCODE_COMPILER( PRESENT ) = NEW_COMPILER( AvmcodeAbsentPresentCompiler );
OPCODE_COMPILER( ABSENT ) = OPCODE_COMPILER( PRESENT );
OPCODE_COMPILER( IF ) = ITE_STATEMENT_COMPILER;
OPCODE_COMPILER( IFE ) = ITE_STATEMENT_COMPILER;
OPCODE_COMPILER( FOR ) = NEW_COMPILER( AvmcodeForCompiler );
OPCODE_COMPILER( FOREACH ) = NEW_COMPILER( AvmcodeForeachCompiler );
OPCODE_COMPILER( WHILE_DO ) = NEW_COMPILER( AvmcodeWhileDoCompiler );
OPCODE_COMPILER( DO_WHILE ) = NEW_COMPILER( AvmcodeDoWhileCompiler );
OPCODE_COMPILER( BREAK ) = NEW_COMPILER( AvmcodeBreakCompiler );
OPCODE_COMPILER( CONTINUE ) = NEW_COMPILER( AvmcodeContinueCompiler );
OPCODE_COMPILER( RETURN ) = NEW_COMPILER( AvmcodeReturnCompiler );
OPCODE_COMPILER( EXIT ) = NEW_COMPILER( AvmcodeExitCompiler );
OPCODE_COMPILER( STEP_MARK ) = DEFAULT_AVMCODE_COMPILER;
return( true );
}
bool AvmcodeCompiler::configureBitwisePrimitive()
{
////////////////////////////////////////////////////////////////////////////
// AVM BITWISE EXPRESSION
////////////////////////////////////////////////////////////////////////////
OPCODE_COMPILER( BNOT ) = UNARY_BITWISE_EXPRESSION_COMPILER;
OPCODE_COMPILER( BAND ) = ASSOCIATIVE_BITWISE_EXPRESSION_COMPILER;
OPCODE_COMPILER( BOR ) = ASSOCIATIVE_BITWISE_EXPRESSION_COMPILER;
OPCODE_COMPILER( BXOR ) = BINARY_BITWISE_EXPRESSION_COMPILER;
OPCODE_COMPILER( LSHIFT ) = BINARY_BITWISE_EXPRESSION_COMPILER;
OPCODE_COMPILER( RSHIFT ) = BINARY_BITWISE_EXPRESSION_COMPILER;
return( true );
}
bool AvmcodeCompiler::configureLogicPrimitive()
{
////////////////////////////////////////////////////////////////////////////
// AVM PREDICAT EXPRESSION
////////////////////////////////////////////////////////////////////////////
OPCODE_COMPILER( NOT ) = UNARY_PREDICATE_EXPRESSION_COMPILER;
OPCODE_COMPILER( AND ) = ASSOCIATIVE_PREDICATE_EXPRESSION_COMPILER;
OPCODE_COMPILER( NAND ) = ASSOCIATIVE_PREDICATE_EXPRESSION_COMPILER;
OPCODE_COMPILER( XAND ) = BINARY_PREDICATE_EXPRESSION_COMPILER;
OPCODE_COMPILER( OR ) = ASSOCIATIVE_PREDICATE_EXPRESSION_COMPILER;
OPCODE_COMPILER( NOR ) = ASSOCIATIVE_PREDICATE_EXPRESSION_COMPILER;
OPCODE_COMPILER( XOR ) = BINARY_PREDICATE_EXPRESSION_COMPILER;
OPCODE_COMPILER( XNOR ) = BINARY_PREDICATE_EXPRESSION_COMPILER;
////////////////////////////////////////////////////////////////////////////
// AVM COMPARISON EXPRESSION
////////////////////////////////////////////////////////////////////////////
OPCODE_COMPILER( EQ ) = RELATIONAL_EXPRESSION_COMPILER;
OPCODE_COMPILER( NEQ ) = RELATIONAL_EXPRESSION_COMPILER;
OPCODE_COMPILER( SEQ ) = RELATIONAL_EXPRESSION_COMPILER;
OPCODE_COMPILER( NSEQ ) = RELATIONAL_EXPRESSION_COMPILER;
OPCODE_COMPILER( LT ) = RELATIONAL_EXPRESSION_COMPILER;
OPCODE_COMPILER( LTE ) = RELATIONAL_EXPRESSION_COMPILER;
OPCODE_COMPILER( GT ) = RELATIONAL_EXPRESSION_COMPILER;
OPCODE_COMPILER( GTE ) = RELATIONAL_EXPRESSION_COMPILER;
return( true );
}
bool AvmcodeCompiler::configureArithmeticPrimitive()
{
////////////////////////////////////////////////////////////////////////////
// AVM ARITHMETIC EXPRESSION
////////////////////////////////////////////////////////////////////////////
OPCODE_COMPILER( PLUS ) = ASSOCIATIVE_ARITHMETIC_EXPRESSION_COMPILER;
OPCODE_COMPILER( MINUS ) = BINARY_ARITHMETIC_EXPRESSION_COMPILER;
OPCODE_COMPILER( UMINUS ) = UNARY_ARITHMETIC_EXPRESSION_COMPILER;
OPCODE_COMPILER( MULT ) = ASSOCIATIVE_ARITHMETIC_EXPRESSION_COMPILER;
OPCODE_COMPILER( POW ) = BINARY_ARITHMETIC_EXPRESSION_COMPILER;
OPCODE_COMPILER( DIV ) = BINARY_ARITHMETIC_EXPRESSION_COMPILER;
OPCODE_COMPILER( MOD ) = BINARY_ARITHMETIC_EXPRESSION_COMPILER;
return( true );
}
bool AvmcodeCompiler::configureLookupPrimitive()
{
////////////////////////////////////////////////////////////////////////////
// LOOKUP STATEMENT
////////////////////////////////////////////////////////////////////////////
OPCODE_COMPILER( LOOKUP_INT ) = LOOKUP_EXPRESSION_COMPILER;
OPCODE_COMPILER( LOOKUP_INT_EXT ) = LOOKUP_EXPRESSION_COMPILER;
OPCODE_COMPILER( LOOKUP_NEAREST ) = LOOKUP_EXPRESSION_COMPILER;
OPCODE_COMPILER( LOOKUP_BELOW ) = LOOKUP_EXPRESSION_COMPILER;
OPCODE_COMPILER( LOOKUP_ABOVE ) = LOOKUP_EXPRESSION_COMPILER;
OPCODE_COMPILER( LOOKUP2D_INT_EXT ) = LOOKUP_EXPRESSION_COMPILER;
return( true );
}
bool AvmcodeCompiler::configureMathematicPrimitive()
{
////////////////////////////////////////////////////////////////////////////
// AVM MATHEMATICAL FUNCTION
////////////////////////////////////////////////////////////////////////////
// MIN - MAX
OPCODE_COMPILER( MIN ) = MATH_FUNCTION_COMPILER;
OPCODE_COMPILER( MAX ) = MATH_FUNCTION_COMPILER;
// RANDOM
OPCODE_COMPILER( RANDOM ) = MATH_FUNCTION_COMPILER;
// ABS
OPCODE_COMPILER( ABS ) = MATH_FUNCTION_COMPILER;
// ROUNDING
OPCODE_COMPILER( CEIL ) = MATH_FUNCTION_COMPILER;
OPCODE_COMPILER( FLOOR ) = MATH_FUNCTION_COMPILER;
OPCODE_COMPILER( ROUND ) = MATH_FUNCTION_COMPILER;
OPCODE_COMPILER( TRUNCATE ) = MATH_FUNCTION_COMPILER;
// EXP - LOG
OPCODE_COMPILER( SQRT ) = MATH_FUNCTION_COMPILER;
OPCODE_COMPILER( EXP ) = MATH_FUNCTION_COMPILER;
OPCODE_COMPILER( LOG ) = MATH_FUNCTION_COMPILER;
// TRIGONOMETRIC
OPCODE_COMPILER( SIN ) = MATH_FUNCTION_COMPILER;
OPCODE_COMPILER( COS ) = MATH_FUNCTION_COMPILER;
OPCODE_COMPILER( TAN ) = MATH_FUNCTION_COMPILER;
OPCODE_COMPILER( SINH ) = MATH_FUNCTION_COMPILER;
OPCODE_COMPILER( COSH ) = MATH_FUNCTION_COMPILER;
OPCODE_COMPILER( TANH ) = MATH_FUNCTION_COMPILER;
OPCODE_COMPILER( ASIN ) = MATH_FUNCTION_COMPILER;
OPCODE_COMPILER( ACOS ) = MATH_FUNCTION_COMPILER;
OPCODE_COMPILER( ATAN ) = MATH_FUNCTION_COMPILER;
OPCODE_COMPILER( ATAN2 ) = MATH_FUNCTION_COMPILER;
OPCODE_COMPILER( ASINH ) = MATH_FUNCTION_COMPILER;
OPCODE_COMPILER( ACOSH ) = MATH_FUNCTION_COMPILER;
OPCODE_COMPILER( ATANH ) = MATH_FUNCTION_COMPILER;
return( true );
}
bool AvmcodeCompiler::configureStringCollectionPrimitive()
{
////////////////////////////////////////////////////////////////////////////
// AVM STRING / COLLECTION OPERATOR
////////////////////////////////////////////////////////////////////////////
OPCODE_COMPILER( CONTAINS ) = BINARY_CONTAINER_STATEMENT;
OPCODE_COMPILER( IN ) = BINARY_CONTAINER_STATEMENT;
OPCODE_COMPILER( NOTIN ) = BINARY_CONTAINER_STATEMENT;
OPCODE_COMPILER( SUBSET ) = BINARY_CONTAINER_STATEMENT;
OPCODE_COMPILER( SUBSETEQ ) = BINARY_CONTAINER_STATEMENT;
OPCODE_COMPILER( INTERSECT ) = BINARY_CONTAINER_STATEMENT;
OPCODE_COMPILER( STARTS_WITH ) = BINARY_STRING_EXPRESSION_COMPILER;
OPCODE_COMPILER( ENDS_WITH ) = BINARY_STRING_EXPRESSION_COMPILER;
OPCODE_COMPILER( CONCAT ) = ASSOCIATIVE_STRING_EXPRESSION_COMPILER;
OPCODE_COMPILER( PUSH ) = NEW_COMPILER( AvmcodePushCompiler );
OPCODE_COMPILER( ASSIGN_TOP ) = NEW_COMPILER( AvmcodeAssignTopCompiler );
OPCODE_COMPILER( TOP ) = NEW_COMPILER( AvmcodeTopCompiler );
OPCODE_COMPILER( POP ) = NEW_COMPILER( AvmcodePopCompiler );
OPCODE_COMPILER( POP_FROM ) = NEW_COMPILER( AvmcodePopFromCompiler );
OPCODE_COMPILER( EMPTY ) = UNARY_CONTAINER_STATEMENT;
OPCODE_COMPILER( NONEMPTY ) = UNARY_CONTAINER_STATEMENT;
OPCODE_COMPILER( SINGLETON ) = UNARY_CONTAINER_STATEMENT;
OPCODE_COMPILER( POPULATED ) = UNARY_CONTAINER_STATEMENT;
OPCODE_COMPILER( FULL ) = UNARY_CONTAINER_STATEMENT;
OPCODE_COMPILER( SIZE ) = UNARY_CONTAINER_STATEMENT;
OPCODE_COMPILER( APPEND ) = BINARY_WRITE_CONTAINER_STATEMENT;
OPCODE_COMPILER( REMOVE ) = BINARY_WRITE_CONTAINER_STATEMENT;
OPCODE_COMPILER( CLEAR ) = UNARY_WRITE_CONTAINER_STATEMENT;
OPCODE_COMPILER( RESIZE ) = BINARY_WRITE_CONTAINER_STATEMENT;
return( true );
}
bool AvmcodeCompiler::configureIoltPrimitive()
{
////////////////////////////////////////////////////////////////////////////
// IOLTL BEHAVIORAL PREDICAT
////////////////////////////////////////////////////////////////////////////
OPCODE_COMPILER( GLOBALLY ) = DEFAULT_AVMCODE_COMPILER;
OPCODE_COMPILER( UNTIL ) = DEFAULT_AVMCODE_COMPILER;
OPCODE_COMPILER( NEXT ) = DEFAULT_AVMCODE_COMPILER;
OPCODE_COMPILER( EVENTUALLY ) = DEFAULT_AVMCODE_COMPILER;
OPCODE_COMPILER( RELEASES ) = DEFAULT_AVMCODE_COMPILER;
OPCODE_COMPILER( OBS ) = NEW_COMPILER( AvmcodeObsCompiler );
////////////////////////////////////////////////////////////////////////////
// IOLTL LOGICAL PREDICAT
////////////////////////////////////////////////////////////////////////////
OPCODE_COMPILER( AND_T ) = DEFAULT_AVMCODE_COMPILER;
OPCODE_COMPILER( OR_T ) = DEFAULT_AVMCODE_COMPILER;
OPCODE_COMPILER( NOT_T ) = DEFAULT_AVMCODE_COMPILER;
OPCODE_COMPILER( IMP_T ) = DEFAULT_AVMCODE_COMPILER;
return( true );
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//// the COMPILER of ARGUMENT
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
const BF & AvmcodeCompiler::postCompileSymbol(const BF & aSymbol)
{
if( aSymbol.is< InstanceOfData >() )
{
InstanceOfData * anInstance = aSymbol.to_ptr< InstanceOfData >();
if( anInstance->getModifier().hasFeatureFinal()
&& anInstance->hasValue() )
{
if( anInstance->isTypedEnum() )
{
return( aSymbol );
}
else if( anInstance->getModifier().hasNatureParameter() )
{
return( aSymbol );
}
else
{
return( anInstance->getValue() );
}
}
else
{
return( aSymbol );
}
}
else if( aSymbol.is< InstanceOfMachine >() )
{
if( aSymbol.to_ptr< InstanceOfMachine >()->hasRuntimeRID() )
{
return( aSymbol.to_ptr< InstanceOfMachine >()->getRuntimeRID() );
}
return( aSymbol );
}
else //if( aSymbol.is< UniFormIdentifier >() || aSymbol.is< AvmCode >() )
{
return( aSymbol );
}
}
BF AvmcodeCompiler::compileUFI(
COMPILE_CONTEXT * aCTX, const UniFormIdentifier & anUFI)
{
AVM_IF_DEBUG_FLAG2( COMPILING , QUALIFIED_NAME_ID )
AVM_OS_TRACE << INCR_INDENT_TAB << "<| compiling<UFI>: "
<< anUFI.str() << std::endl;
aCTX->debugContext( AVM_OS_TRACE << INCR_INDENT ) << DECR_INDENT;
AVM_ENDIF_DEBUG_FLAG2( COMPILING , QUALIFIED_NAME_ID )
BF aSymbol = UFI_EXPRESSION_COMPILER->compileUfiExpression(aCTX, anUFI);
if( aSymbol.valid() )
{
AVM_IF_DEBUG_FLAG2( COMPILING , QUALIFIED_NAME_ID )
AVM_OS_TRACE << TAB_DECR_INDENT << ">| result"
<< ((aSymbol.is< UniFormIdentifier >()) ? "<UFI>: " : ":> ")
<< str_header( aSymbol ) << std::endl;
AVM_ENDIF_DEBUG_FLAG2( COMPILING , QUALIFIED_NAME_ID )
return( postCompileSymbol(aSymbol) );
}
// ERROR REPORTING
else if( getSymbolTable().hasError() )
{
getCompilerTable().incrErrorCount();
AVM_OS_WARN << anUFI.errorLocation(aCTX->mCompileCtx->getAstElement())
<< getSymbolTable().getErrorMessage()
<< std::endl << std::endl;
return( BF::REF_NULL );
}
else
{
getCompilerTable().incrErrorCount();
AVM_OS_WARN << anUFI.errorLocation(aCTX->mCompileCtx->getAstElement())
<< "UFI compilation error : unfound symbol << "
<< anUFI.str() << " >>" << std::endl << std::endl;
return( BF::REF_NULL );
}
}
BF AvmcodeCompiler::compileFullyQualifiedNameID(
COMPILE_CONTEXT * aCTX, const std::string & aFullyQualifiedNameID)
{
AVM_IF_DEBUG_FLAG2( COMPILING , QUALIFIED_NAME_ID )
AVM_OS_TRACE << INCR_INDENT_TAB << "<| compiling<fqn>: "
<< aFullyQualifiedNameID << std::endl;
aCTX->debugContext( AVM_OS_TRACE << INCR_INDENT ) << DECR_INDENT;
AVM_ENDIF_DEBUG_FLAG2( COMPILING , QUALIFIED_NAME_ID )
BF aSymbol = getSymbolTable().searchSymbol(aCTX, aFullyQualifiedNameID);
if( aSymbol.invalid() )
{
UniFormIdentifier anUFI(aFullyQualifiedNameID);
aSymbol = getSymbolTable().searchSymbolByUFI(aCTX, anUFI);
}
if( aSymbol.valid() )
{
AVM_IF_DEBUG_FLAG2( COMPILING , QUALIFIED_NAME_ID )
AVM_OS_TRACE << TAB_DECR_INDENT << ">| result"
<< ((aSymbol.is< UniFormIdentifier >())? "<fqn>: " : ":> ")
<< str_header( aSymbol ) << std::endl;
AVM_ENDIF_DEBUG_FLAG2( COMPILING , QUALIFIED_NAME_ID )
return( postCompileSymbol(aSymbol) );
}
// ERROR REPORTING
else if( getSymbolTable().hasError() )
{
getCompilerTable().incrErrorCount();
aCTX->errorContext( AVM_OS_WARN )
<< getSymbolTable().getErrorMessage()
<< std::endl << std::endl;
return( ExpressionConstructor::
newQualifiedIdentifier(aFullyQualifiedNameID) );
}
else
{
getCompilerTable().incrErrorCount();
aCTX->errorContext( AVM_OS_WARN )
<< "FullyQualifiedNameID compilation error : unfound symbol << "
<< aFullyQualifiedNameID << " >>"
<< std::endl << std::endl;
return( ExpressionConstructor::
newQualifiedIdentifier(aFullyQualifiedNameID) );
}
}
BF AvmcodeCompiler::compileQualifiedIdentifier(
COMPILE_CONTEXT * aCTX, const BF & aQualifiedNameID)
{
AVM_IF_DEBUG_FLAG2( COMPILING , QUALIFIED_NAME_ID )
AVM_OS_TRACE << INCR_INDENT_TAB << "<| compiling<QualifiedNameID>: "
<< aQualifiedNameID.str() << std::endl;
aCTX->debugContext( AVM_OS_TRACE << INCR_INDENT ) << DECR_INDENT;
AVM_ENDIF_DEBUG_FLAG2( COMPILING , QUALIFIED_NAME_ID )
const BF & aSymbol = getSymbolTable().
searchSymbolByQualifiedNameID(aCTX, aQualifiedNameID.str());
if( aSymbol.valid() )
{
AVM_IF_DEBUG_FLAG2( COMPILING , QUALIFIED_NAME_ID )
AVM_OS_TRACE << TAB_DECR_INDENT << ">| result :> "
<< str_header( aSymbol ) << std::endl;
AVM_ENDIF_DEBUG_FLAG2( COMPILING , QUALIFIED_NAME_ID )
return( postCompileSymbol(aSymbol) );
}
// ERROR REPORTING
else if( getSymbolTable().hasError() )
{
getCompilerTable().incrErrorCount();
aCTX->errorContext( AVM_OS_WARN )
<< getSymbolTable().getErrorMessage()
<< std::endl << std::endl;
return( aQualifiedNameID );
}
else
{
getCompilerTable().incrErrorCount();
aCTX->errorContext( AVM_OS_WARN )
<< "[ [ Fully ] Qualified ] Name ID compilation error : "
"unfound symbol << " << aQualifiedNameID.str() << " >>"
<< std::endl << std::endl;
return( aQualifiedNameID );
}
}
BF AvmcodeCompiler::compileQualifiedPositionalIdentifier(
COMPILE_CONTEXT * aCTX, const BF & aQualifiedNameID)
{
AVM_IF_DEBUG_FLAG2( COMPILING , QUALIFIED_NAME_ID )
AVM_OS_TRACE << INCR_INDENT_TAB
<< "<| compiling<QualifiedPositionalIdentifier>: "
<< aQualifiedNameID.str() << std::endl
<< TAB2 << str_header( aCTX ) << std::endl;
AVM_ENDIF_DEBUG_FLAG2( COMPILING , QUALIFIED_NAME_ID )
const BF & aSymbol = getSymbolTable().
searchSymbolByQualifiedNameID(aCTX, aQualifiedNameID.str());
if( aSymbol.valid() )
{
AVM_IF_DEBUG_FLAG2( COMPILING , QUALIFIED_NAME_ID )
AVM_OS_TRACE << TAB_DECR_INDENT << ">| result"
<< ((aSymbol.is< UniFormIdentifier >())? "<qnid>: " : ":> ")
<< str_header( aSymbol ) << std::endl;
AVM_ENDIF_DEBUG_FLAG2( COMPILING , QUALIFIED_NAME_ID )
if( aSymbol.is< InstanceOfMachine >() )
{
ExecutableForm * anExec = aSymbol.to_ptr< InstanceOfMachine >()->getExecutable();
if( anExec != NULL )
{
avm_offset_t aPositionOffset = aQualifiedNameID.
to_ptr< QualifiedIdentifier >()->getPositionOffset();
if( aPositionOffset < anExec->getParamCount() )
{
return( anExec->getParam(aPositionOffset) );
}
}
return( aSymbol );
}
return( postCompileSymbol(aSymbol) );
}
// ERROR REPORTING
else if( getSymbolTable().hasError() )
{
getCompilerTable().incrErrorCount();
aCTX->errorContext( AVM_OS_WARN )
<< getSymbolTable().getErrorMessage()
<< std::endl << std::endl;
return( aQualifiedNameID );
}
else
{
getCompilerTable().incrErrorCount();
aCTX->errorContext( AVM_OS_WARN )
<< "[ [ Fully ] Qualified ] Name ID compilation error :"
" unfound symbol << " << aQualifiedNameID.str() << " >>"
<< std::endl << std::endl;
return( aQualifiedNameID );
}
}
BF AvmcodeCompiler::compileIdentifier(
COMPILE_CONTEXT * aCTX, const std::string & aNameID)
{
AVM_IF_DEBUG_FLAG2( COMPILING , QUALIFIED_NAME_ID )
AVM_OS_TRACE << INCR_INDENT_TAB << "<| compiling<name-id>: "
<< aNameID << std::endl;
aCTX->debugContext( AVM_OS_TRACE << INCR_INDENT ) << DECR_INDENT;
AVM_ENDIF_DEBUG_FLAG2( COMPILING , QUALIFIED_NAME_ID )
const BF & aSymbol = getSymbolTable().searchSymbolByNameID(aCTX, aNameID);
if( aSymbol.valid() )
{
AVM_IF_DEBUG_FLAG2( COMPILING , QUALIFIED_NAME_ID )
AVM_OS_TRACE << TAB_DECR_INDENT << ">| result"
<< ((aSymbol.is< UniFormIdentifier >())? "<name-id>: " : ":> ")
<< str_header( aSymbol ) << std::endl;
AVM_ENDIF_DEBUG_FLAG2( COMPILING , QUALIFIED_NAME_ID )
return( postCompileSymbol(aSymbol) );
}
else
{
InstanceOfData * varCtx = aCTX->mVariableCtx;
for( ; varCtx != NULL ; varCtx = varCtx->getParent() )
{
BF aFieldSymbol = getSymbolTable().searchSymbol(aCTX,
( OSS() << varCtx->getFullyQualifiedNameID()
<< '.' << aNameID ) );
if( aFieldSymbol.valid() )
{
AVM_IF_DEBUG_FLAG2( COMPILING , QUALIFIED_NAME_ID )
AVM_OS_TRACE << TAB_DECR_INDENT << ">| result:> "
<< str_header( aFieldSymbol ) << std::endl;
AVM_ENDIF_DEBUG_FLAG2( COMPILING , QUALIFIED_NAME_ID )
return( postCompileSymbol(aFieldSymbol) );
}
}
Operator * opID = OperatorManager::getOp( aNameID );
if( opID != NULL )
{
return( CONST_BF_OP( opID ) );
}
// ERROR REPORTING
else if( getSymbolTable().hasError() )
{
getCompilerTable().incrErrorCount();
aCTX->errorContext( AVM_OS_WARN )
<< getSymbolTable().getErrorMessage()
<< std::endl << std::endl;
return( ExpressionConstructor::newIdentifier(aNameID) );
}
else
{
getCompilerTable().incrErrorCount();
aCTX->errorContext( AVM_OS_WARN )
<< "Identifier compilation error : unfound symbol << "
<< aNameID << " >>" << std::endl << std::endl;
return( ExpressionConstructor::newIdentifier(aNameID) );
}
}
}
const BF & AvmcodeCompiler::compileElement(
COMPILE_CONTEXT * aCTX, const BF & anElement)
{
ObjectElement * objElement = anElement.to_ptr< ObjectElement >();
AVM_IF_DEBUG_FLAG2( COMPILING , QUALIFIED_NAME_ID )
AVM_OS_TRACE << INCR_INDENT_TAB << "<| compiling<FORM>: & "
<< objElement->getFullyQualifiedNameID() << std::endl;
aCTX->debugContext( AVM_OS_TRACE << INCR_INDENT ) << DECR_INDENT;
AVM_ENDIF_DEBUG_FLAG2( COMPILING , QUALIFIED_NAME_ID )
const BF & aSymbol = getSymbolTable().searchSymbol(aCTX, objElement);
if( aSymbol.valid() )
{
AVM_IF_DEBUG_FLAG2( COMPILING , QUALIFIED_NAME_ID )
AVM_OS_TRACE << TAB_DECR_INDENT
<< ">| result:> " << str_header( aSymbol ) << std::endl;
AVM_ENDIF_DEBUG_FLAG2( COMPILING , QUALIFIED_NAME_ID )
return( postCompileSymbol(aSymbol) );
}
// ERROR REPORTING
else if( getSymbolTable().hasError() )
{
getCompilerTable().incrErrorCount();
AVM_OS_WARN << objElement->errorLocation(
aCTX->mCompileCtx->getAstElement())
<< getSymbolTable().getErrorMessage()
<< std::endl << std::endl;
return( anElement );
}
else
{
getCompilerTable().incrErrorCount();
aCTX->errorContext( AVM_OS_WARN )
<< "Unfound data instance << & "
<< objElement->getFullyQualifiedNameID() << " >>"
<< std::endl << std::endl;
return( anElement );
}
}
const BF & AvmcodeCompiler::compileDataType(
COMPILE_CONTEXT * aCTX, const BF & aDataType)
{
DataType * pType = aDataType.to_ptr< DataType >();
AVM_IF_DEBUG_FLAG2( COMPILING , QUALIFIED_NAME_ID )
AVM_OS_TRACE << INCR_INDENT_TAB << "<| compiling<DataType>: "
<< str_header( pType ) << std::endl;
aCTX->debugContext( AVM_OS_TRACE << INCR_INDENT ) << DECR_INDENT;
AVM_ENDIF_DEBUG_FLAG2( COMPILING , QUALIFIED_NAME_ID )
const TypeSpecifier & aTypeSpecifier =
SymbolTable::searchTypeSpecifier(
getConfiguration().getExecutableSystem(), aCTX, pType);
if( aTypeSpecifier.valid() )
{
AVM_IF_DEBUG_FLAG2( COMPILING , QUALIFIED_NAME_ID )
AVM_OS_TRACE << TAB_DECR_INDENT << ">| result:> "
<< str_header( aTypeSpecifier ) << std::endl;
AVM_ENDIF_DEBUG_FLAG2( COMPILING , QUALIFIED_NAME_ID )
return( aTypeSpecifier );
}
// ERROR REPORTING
else if( getSymbolTable().hasError() )
{
getCompilerTable().incrErrorCount();
AVM_OS_WARN << pType->errorLocation(aCTX->mCompileCtx->getAstElement())
<< getSymbolTable().getErrorMessage()
<< std::endl << std::endl;
return( aDataType );
}
else
{
getCompilerTable().incrErrorCount();
aCTX->errorContext( AVM_OS_WARN )
<< "Unfound typedef << & " << str_header( pType )
<< " >>" << std::endl << std::endl;
return( aDataType );
}
}
const BF & AvmcodeCompiler::compileVariable(
COMPILE_CONTEXT * aCTX, const BF & aVariable)
{
Variable * pVariable = aVariable.to_ptr< Variable >();
AVM_IF_DEBUG_FLAG2( COMPILING , QUALIFIED_NAME_ID )
AVM_OS_TRACE << INCR_INDENT_TAB << "<| compiling<Variable>: "
<< str_header( pVariable ) << std::endl;
aCTX->debugContext( AVM_OS_TRACE << INCR_INDENT ) << DECR_INDENT;
AVM_ENDIF_DEBUG_FLAG2( COMPILING , QUALIFIED_NAME_ID )
const BF & aSymbol = getSymbolTable().searchDataInstance(aCTX, pVariable);
if( aSymbol.valid() )
{
InstanceOfData * anInstance = aSymbol.to_ptr< InstanceOfData >();
AVM_IF_DEBUG_FLAG2( COMPILING , QUALIFIED_NAME_ID )
AVM_OS_TRACE << TAB_DECR_INDENT
<< ">| result:> " << str_header( anInstance ) << std::endl;
AVM_ENDIF_DEBUG_FLAG2( COMPILING , QUALIFIED_NAME_ID )
if( anInstance->getModifier().hasFeatureFinal() )
{
if( (not anInstance->hasValue()) && pVariable->hasValue() )
{
anInstance->setValue( decode_compileExpression(
aCTX->clone(anInstance->getTypeSpecifier()),
pVariable->getValue() ) );
}
if( anInstance->hasValue() )
{
if( anInstance->isEnumSymbolPointer()
&& anInstance->getModifier().hasFeatureUnsafe() )
{
return( aSymbol );
}
else if( anInstance->getModifier().hasNatureParameter() )
{
return( aSymbol );
}
else
{
return( anInstance->getValue() );
}
}
}
return( aSymbol );
}
// ERROR REPORTING
else if( getSymbolTable().hasError() )
{
getCompilerTable().incrErrorCount();
AVM_OS_WARN << pVariable->errorLocation(
aCTX->mCompileCtx->getAstElement() )
<< getSymbolTable().getErrorMessage()
<< std::endl << std::endl;
AVM_IF_DEBUG_FLAG2( COMPILING , QUALIFIED_NAME_ID )
AVM_OS_TRACE << TAB_DECR_INDENT
<< ">| error:> " << str_header( pVariable ) << std::endl;
AVM_ENDIF_DEBUG_FLAG2( COMPILING , QUALIFIED_NAME_ID )
return( aVariable );
}
else
{
getCompilerTable().incrErrorCount();
aCTX->errorContext( AVM_OS_WARN )
<< "Unfound variable instance << "
<< pVariable->getFullyQualifiedNameID() << " >>"
<< std::endl << std::endl;
AVM_IF_DEBUG_FLAG2( COMPILING , QUALIFIED_NAME_ID )
AVM_OS_TRACE << TAB_DECR_INDENT
<< ">| error:> " << str_header( pVariable ) << std::endl;
AVM_ENDIF_DEBUG_FLAG2( COMPILING , QUALIFIED_NAME_ID )
return( aVariable );
}
}
const BF & AvmcodeCompiler::compileBuffer(
COMPILE_CONTEXT * aCTX, const BF & aBuffer)
{
Buffer * pBuffer = aBuffer.to_ptr< Buffer >();
AVM_IF_DEBUG_FLAG2( COMPILING , QUALIFIED_NAME_ID )
AVM_OS_TRACE << INCR_INDENT_TAB << "<| compiling<Buffer>: "
<< str_header( pBuffer ) << std::endl;
aCTX->debugContext( AVM_OS_TRACE << INCR_INDENT ) << DECR_INDENT;
AVM_ENDIF_DEBUG_FLAG2( COMPILING , QUALIFIED_NAME_ID )
const BF & aSymbol = getSymbolTable().searchBufferInstance(
aCTX->mCompileCtx->getExecutable(), pBuffer);
if( aSymbol.valid() )
{
AVM_IF_DEBUG_FLAG2( COMPILING , QUALIFIED_NAME_ID )
AVM_OS_TRACE << TAB_DECR_INDENT << ">| result:> "
<< str_header( aSymbol.to_ptr< InstanceOfBuffer >() ) << std::endl;
AVM_ENDIF_DEBUG_FLAG2( COMPILING , QUALIFIED_NAME_ID )
return( aSymbol );
}
// ERROR REPORTING
else if( getSymbolTable().hasError() )
{
getCompilerTable().incrErrorCount();
AVM_OS_WARN << pBuffer->errorLocation(aCTX->mCompileCtx->getAstElement())
<< getSymbolTable().getErrorMessage()
<< std::endl << std::endl;
return( aBuffer );
}
else
{
getCompilerTable().incrErrorCount();
aCTX->errorContext( AVM_OS_WARN )
<< "Unfound buffer instance << & " << str_header( pBuffer )
<< " >>" << std::endl << std::endl;
return( aBuffer );
}
}
const BF & AvmcodeCompiler::compilePort(
COMPILE_CONTEXT * aCTX, const BF & aPort)
{
Port * pPort = aPort.to_ptr< Port >();
AVM_IF_DEBUG_FLAG2( COMPILING , QUALIFIED_NAME_ID )
AVM_OS_TRACE << INCR_INDENT_TAB << "<| compiling<Port>: "
<< str_header( pPort ) << std::endl;
aCTX->debugContext( AVM_OS_TRACE << INCR_INDENT ) << DECR_INDENT;
AVM_ENDIF_DEBUG_FLAG2( COMPILING , QUALIFIED_NAME_ID )
const BF & aSymbol = getSymbolTable().
searchPortSymbolInstance(aCTX->mCompileCtx->getExecutable(), pPort);
if( aSymbol.valid() )
{
AVM_IF_DEBUG_FLAG2( COMPILING , QUALIFIED_NAME_ID )
AVM_OS_TRACE << TAB_DECR_INDENT << ">| result:> "
<< str_header( aSymbol.to_ptr< InstanceOfPort >() ) << std::endl;
AVM_ENDIF_DEBUG_FLAG2( COMPILING , QUALIFIED_NAME_ID )
return( aSymbol );
}
// ERROR REPORTING
else if( getSymbolTable().hasError() )
{
getCompilerTable().incrErrorCount();
AVM_OS_WARN << pPort->errorLocation(aCTX->mCompileCtx->getAstElement())
<< getSymbolTable().getErrorMessage()
<< std::endl << std::endl;
return( aPort );
}
else
{
getCompilerTable().incrErrorCount();
aCTX->errorContext( AVM_OS_WARN )
<< "Unfound port instance << " << str_header( pPort ) << " >>"
<< std::endl << std::endl;
return( aPort );
}
}
const BF & AvmcodeCompiler::compileConnector(
COMPILE_CONTEXT * aCTX, const BF & aConnector)
{
return( aConnector );
}
const BF & AvmcodeCompiler::compileMachine(
COMPILE_CONTEXT * aCTX, const BF & aMachine)
{
Machine * pMachine = aMachine.to_ptr< Machine >();
AVM_IF_DEBUG_FLAG2( COMPILING , QUALIFIED_NAME_ID )
AVM_OS_TRACE << INCR_INDENT_TAB << "<| compiling<Machine>: "
<< str_header( pMachine ) << std::endl;
aCTX->debugContext( AVM_OS_TRACE << INCR_INDENT ) << DECR_INDENT;
AVM_ENDIF_DEBUG_FLAG2( COMPILING , QUALIFIED_NAME_ID )
const BF & aSymbol =
getSymbolTable().searchInstanceStatic(aCTX, pMachine);
if( aSymbol.valid() )
{
InstanceOfMachine * aMachineSymbol =
aSymbol.to_ptr< InstanceOfMachine >();
AVM_IF_DEBUG_FLAG2( COMPILING , QUALIFIED_NAME_ID )
AVM_OS_TRACE << TAB_DECR_INDENT << ">| result:> "
<< str_header( aMachineSymbol ) << std::endl;
AVM_ENDIF_DEBUG_FLAG2( COMPILING , QUALIFIED_NAME_ID )
if( aMachineSymbol->hasRuntimeRID() )
{
AVM_OS_TRACE << TAB_DECR_INDENT << ">| result:> "
<< aMachineSymbol->getRuntimeRID().str() << std::endl;
return( aMachineSymbol->getRuntimeRID() );
}
return( aSymbol );
}
const BF & aSymbolModel =
getSymbolTable().searchInstanceModel(aCTX, pMachine);
if( aSymbolModel.valid() )
{
return( aSymbolModel );
}
if( pMachine->getSpecifier().isDesignInstanceDynamic() )
{
const BF & aSymbol =
getSymbolTable().searchInstanceDynamic(aCTX, pMachine);
if( aSymbol.valid() )
{
return( aSymbol );
}
}
// ERROR REPORTING
if( getSymbolTable().hasError() )
{
getCompilerTable().incrErrorCount();
AVM_OS_WARN << pMachine->errorLocation(
aCTX->mCompileCtx->getAstElement() )
<< getSymbolTable().getErrorMessage()
<< std::endl << std::endl;
return( aMachine );
}
else
{
getCompilerTable().incrErrorCount();
aCTX->errorContext( AVM_OS_WARN )
<< "Unfound machine << " << str_header( pMachine )
<< " >>" << std::endl << std::endl;
return( aMachine );
}
}
const BF & AvmcodeCompiler::compileRoutine(
COMPILE_CONTEXT * aCTX, const BF & aRoutine)
{
Routine * pRoutine = aRoutine.to_ptr< Routine >();
AVM_IF_DEBUG_FLAG2( COMPILING , QUALIFIED_NAME_ID )
AVM_OS_TRACE << INCR_INDENT_TAB << "<| compiling<Routine>: "
<< str_header( pRoutine ) << std::endl;
aCTX->debugContext( AVM_OS_TRACE << INCR_INDENT ) << DECR_INDENT;
AVM_ENDIF_DEBUG_FLAG2( COMPILING , QUALIFIED_NAME_ID )
const BF & aSymbol =
getSymbolTable().searchProgram(aCTX, pRoutine->getNameID());
if( aSymbol.valid() )
{
AVM_IF_DEBUG_FLAG2( COMPILING , QUALIFIED_NAME_ID )
AVM_OS_TRACE << TAB_DECR_INDENT
<< ">| result:> " << str_header( aSymbol ) << std::endl;
AVM_ENDIF_DEBUG_FLAG2( COMPILING , QUALIFIED_NAME_ID )
return( aSymbol );
}
// ERROR REPORTING
else if( getSymbolTable().hasError() )
{
getCompilerTable().incrErrorCount();
AVM_OS_WARN << pRoutine->errorLocation(
aCTX->mCompileCtx->getAstElement() )
<< getSymbolTable().getErrorMessage()
<< std::endl << std::endl;
return( aRoutine );
}
else
{
getCompilerTable().incrErrorCount();
aCTX->errorContext( AVM_OS_WARN )
<< "Unfound routine << & " << str_header( pRoutine )
<< " >>" << std::endl << std::endl;
return( aRoutine );
}
}
const BF & AvmcodeCompiler::compileTransition(
COMPILE_CONTEXT * aCTX, const BF & aTransition)
{
Transition * pTransition = aTransition.to_ptr< Transition >();
AVM_IF_DEBUG_FLAG2( COMPILING , QUALIFIED_NAME_ID )
AVM_OS_TRACE << INCR_INDENT_TAB << "<| compiling<Transition>: "
<< str_header( pTransition ) << std::endl;
aCTX->debugContext( AVM_OS_TRACE << INCR_INDENT ) << DECR_INDENT;
AVM_ENDIF_DEBUG_FLAG2( COMPILING , QUALIFIED_NAME_ID )
const BF & aSymbol = getSymbolTable().searchTransition(aCTX, pTransition);
if( aSymbol.valid() )
{
AVM_IF_DEBUG_FLAG2( COMPILING , QUALIFIED_NAME_ID )
AVM_OS_TRACE << TAB_DECR_INDENT
<< ">| result:> " << str_header( aSymbol ) << std::endl;
AVM_ENDIF_DEBUG_FLAG2( COMPILING , QUALIFIED_NAME_ID )
return( aSymbol );
}
// ERROR REPORTING
else if( getSymbolTable().hasError() )
{
getCompilerTable().incrErrorCount();
AVM_OS_WARN << pTransition->errorLocation(
aCTX->mCompileCtx->getAstElement() )
<< getSymbolTable().getErrorMessage()
<< std::endl << std::endl;
return( aTransition );
}
else
{
getCompilerTable().incrErrorCount();
aCTX->errorContext( AVM_OS_WARN )
<< "Unfound transition << & " << str_header( pTransition )
<< " >>" << std::endl << std::endl;
return( aTransition );
}
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//// the COMPILER of EXPRESSION
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
BF AvmcodeCompiler::compileExpression(
COMPILE_CONTEXT * aCTX, const BFCode & aCode)
{
AVM_IF_DEBUG_LEVEL_FLAG( HIGH , COMPILING )
AVM_OS_TRACE << INCR_INDENT_TAB << "in<expr>: "
<< STRIML( aCode->toString(AVM_OS_TRACE.INDENT) )
<< std::flush;
AVM_ENDIF_DEBUG_LEVEL_FLAG( HIGH , COMPILING )
BF expr = AVMCODE_COMPILER_TABLE[ aCode->getOpOffset() ]->
compileExpression(aCTX, aCode);
AVM_IF_DEBUG_LEVEL_FLAG( HIGH , COMPILING )
AVM_OS_TRACE << TAB_DECR_INDENT << "out:> "
<< STRIML( expr.toString(AVM_OS_TRACE.INDENT) )
<< std::flush;
AVM_ENDIF_DEBUG_LEVEL_FLAG( HIGH , COMPILING )
return( expr );
}
BF AvmcodeCompiler::decode_compileExpression(
COMPILE_CONTEXT * aCTX, const BF & aCode)
{
switch( aCode.classKind() )
{
case FORM_AVMCODE_KIND:
{
return( compileExpression(aCTX, aCode.bfCode()) );
}
case FORM_UFI_KIND:
{
return( compileUFI(aCTX, aCode.to_ref< UniFormIdentifier>()) );
}
case FORM_BUILTIN_QUALIFIED_IDENTIFIER_KIND:
{
if( aCode.str().find(':') != std::string::npos )
{
return( compileFullyQualifiedNameID(aCTX, aCode) );
}
else
{
return( compileQualifiedIdentifier(aCTX, aCode) );
}
}
case FORM_BUILTIN_IDENTIFIER_KIND:
{
return( compileIdentifier(aCTX, aCode) );
}
case FORM_XFSP_VARIABLE_KIND:
{
return( compileVariable(aCTX, aCode) );
}
case FORM_XFSP_DATATYPE_KIND:
{
return( compileDataType(aCTX, aCode) );
}
case FORM_XFSP_MACHINE_KIND:
case FORM_XFSP_SYSTEM_KIND:
{
return( compileMachine(aCTX, aCode) );
}
// case FORM_XFSP_INSTANCE_KIND:
// {
// return( compileInstance(aCTX, aCode) );
// }
case FORM_XFSP_BUFFER_KIND:
{
return( compileBuffer(aCTX, aCode) );
}
case FORM_XFSP_PORT_KIND:
{
return( compilePort(aCTX, aCode) );
}
case FORM_XFSP_TRANSITION_KIND:
{
return( compileTransition(aCTX, aCode) );
}
case FORM_XFSP_ROUTINE_KIND:
{
return( compileRoutine(aCTX, aCode) );
}
case FORM_XFSP_PACKAGE_KIND:
case FORM_XFSP_CHANNEL_KIND:
case FORM_XFSP_COM_POINT_KIND:
case FORM_XFSP_COM_ROUTE_KIND:
case FORM_XFSP_CONNECTOR_KIND:
case FORM_OPERATOR_KIND:
case FORM_EXECUTABLE_MACHINE_KIND:
case FORM_INSTANCE_BUFFER_KIND:
case FORM_INSTANCE_CONNECTOR_KIND:
case FORM_INSTANCE_DATA_KIND:
case FORM_INSTANCE_MACHINE_KIND:
case FORM_INSTANCE_PORT_KIND:
case FORM_BUILTIN_BOOLEAN_KIND:
case FORM_BUILTIN_CHARACTER_KIND:
case FORM_BUILTIN_INTEGER_KIND:
case FORM_BUILTIN_RATIONAL_KIND:
case FORM_BUILTIN_FLOAT_KIND:
case FORM_BUILTIN_STRING_KIND:
{
return( aCode );
}
case FORM_ARRAY_BOOLEAN_KIND:
case FORM_ARRAY_CHARACTER_KIND:
case FORM_ARRAY_INTEGER_KIND:
case FORM_ARRAY_RATIONAL_KIND:
case FORM_ARRAY_FLOAT_KIND:
case FORM_ARRAY_STRING_KIND:
{
BuiltinArray * aBuiltinArray = aCode.to_ptr< BuiltinArray >();
// Build the type specified container
if( (aCTX->mType != NULL)
&& aCTX->mType->hasTypeCollection()
&& aCTX->mType->is< ContainerTypeSpecifier >() )
{
BuiltinContainer * containerValue = BuiltinContainer::create(
aCTX->mType->as< ContainerTypeSpecifier >() );
containerValue->copy( aBuiltinArray, std::min(
containerValue->capacity(), aBuiltinArray->size()) );
return( BF( containerValue ) );
}
else
{
return( BF( aBuiltinArray->getArrayBF() ) );
}
}
case FORM_ARRAY_IDENTIFIER_KIND:
{
return( compileArrayOfIdentifier(aCTX,
aCode.to_ptr< ArrayIdentifier >()) );
}
case FORM_ARRAY_QUALIFIED_IDENTIFIER_KIND:
{
return( compileArrayOfQualifiedIdentifier(aCTX,
aCode.to_ptr< ArrayQualifiedIdentifier >()) );
}
case FORM_ARRAY_BF_KIND:
{
return( compileArrayOfBF(aCTX, aCode.to_ptr< ArrayBF >()) );
}
case FORM_CONTAINER_VECTOR_KIND:
case FORM_CONTAINER_REVERSE_VECTOR_KIND:
case FORM_CONTAINER_LIST_KIND:
case FORM_CONTAINER_SET_KIND:
case FORM_CONTAINER_BAG_KIND:
case FORM_CONTAINER_FIFO_KIND:
case FORM_CONTAINER_LIFO_KIND:
{
return( aCode );
}
default:
{ // TODO
AVM_OS_WARNING_ALERT
<< "AvmcodeCompiler is trying to decode_compileExpression"
"\n\ttypeinfo: " << aCode.raw_pointer()->classKindInfo()
<< "\n\t<< " << aCode.str() << " >> !!!"
<< SEND_ALERT;
return( BF::REF_NULL );
}
}
return( aCode );
}
BF AvmcodeCompiler::compileArrayOfIdentifier(
COMPILE_CONTEXT * aCTX, ArrayIdentifier * idArray)
{
BaseTypeSpecifier * arrayType = ( (aCTX->mType != NULL) &&
aCTX->mType->hasTypeComposite()) ? aCTX->mType :
idArray->getTypeSpecifier();
ArrayBF * compiledArray = new ArrayBF(arrayType, idArray->size());
bool isnotCompiled = false;
if( aCTX->mType != NULL )
{
COMPILE_CONTEXT * contentCTX = NULL;
if( aCTX->mType->hasTypeCollection() &&
aCTX->mType->is< ContainerTypeSpecifier >() )
{
contentCTX = aCTX->clone( aCTX->mType->
to< ContainerTypeSpecifier >()->
getContentsTypeSpecifier() );
for( avm_size_t index = 0; index < idArray->size() ; ++index )
{
compiledArray->set( index,
compileIdentifier(contentCTX, idArray->get(index)) );
}
}
else if( aCTX->mType->isTypedStructure() )
{
ClassTypeSpecifier * typeStruct =
aCTX->mType->to< ClassTypeSpecifier >();
TableOfSymbol::const_iterator itField =
typeStruct->getSymbolData().begin();
TableOfSymbol::const_iterator endField =
typeStruct->getSymbolData().end();
for( avm_size_t index = 0; (index < idArray->size()) &&
(itField != endField) ; ++index )
{
contentCTX = aCTX->clone(
(*itField).getTypeSpecifier() );
compiledArray->set( index,
compileIdentifier(contentCTX, idArray->get(index)) );
}
}
else
{
isnotCompiled = true;
}
}
if( isnotCompiled )
{
for( avm_size_t index = 0; index < idArray->size() ; ++index )
{
compiledArray->set( index,
compileIdentifier(aCTX, idArray->get(index)) );
}
}
// Build the type specified container
if( (aCTX->mType != NULL) && aCTX->mType->hasTypeCollection() &&
aCTX->mType->is< ContainerTypeSpecifier >() )
{
BuiltinContainer * containerValue = BuiltinContainer::create(
aCTX->mType->as< ContainerTypeSpecifier >() );
containerValue->copy( compiledArray, std::min(
containerValue->capacity(), compiledArray->size()) );
return( BF( containerValue ) );
}
else
{
return( BF( compiledArray ) );
}
}
BF AvmcodeCompiler::compileArrayOfQualifiedIdentifier(
COMPILE_CONTEXT * aCTX, ArrayQualifiedIdentifier * ufidArray)
{
BaseTypeSpecifier * arrayType = ( (aCTX->mType != NULL) &&
aCTX->mType->hasTypeComposite()) ? aCTX->mType :
ufidArray->getTypeSpecifier();
ArrayBF * compiledArray = new ArrayBF(arrayType, ufidArray->size());
bool isnotCompiled = false;
if( aCTX->mType != NULL )
{
COMPILE_CONTEXT * contentCTX = NULL;
if( aCTX->mType->hasTypeCollection() &&
aCTX->mType->is< ContainerTypeSpecifier >() )
{
contentCTX = aCTX->clone( aCTX->mType->
to< ContainerTypeSpecifier >()->
getContentsTypeSpecifier() );
for( avm_size_t index = 0; index < ufidArray->size() ; ++index )
{
compiledArray->set( index,
compileFullyQualifiedNameID(
contentCTX, ufidArray->get(index)) );
}
}
else if( aCTX->mType->isTypedStructure() )
{
ClassTypeSpecifier * typeStruct =
aCTX->mType->to< ClassTypeSpecifier >();
TableOfSymbol::const_iterator itField =
typeStruct->getSymbolData().begin();
TableOfSymbol::const_iterator endField =
typeStruct->getSymbolData().end();
for( avm_size_t index = 0; (index < ufidArray->size()) &&
(itField != endField) ; ++index )
{
contentCTX = aCTX->clone(
(*itField).getTypeSpecifier() );
compiledArray->set( index,
compileFullyQualifiedNameID(
contentCTX, ufidArray->get(index)) );
}
}
else
{
isnotCompiled = true;
}
}
if( isnotCompiled )
{
for( avm_size_t index = 0; index < ufidArray->size() ; ++index )
{
compiledArray->set( index,
compileFullyQualifiedNameID(aCTX, ufidArray->get(index)) );
}
}
// Build the type specified container
if( (aCTX->mType != NULL) && aCTX->mType->hasTypeCollection() &&
aCTX->mType->is< ContainerTypeSpecifier >() )
{
BuiltinContainer * containerValue = BuiltinContainer::create(
aCTX->mType->as< ContainerTypeSpecifier >() );
containerValue->copy( compiledArray, std::min(
containerValue->capacity(), compiledArray->size()) );
return( BF( containerValue ) );
}
else
{
return( BF( compiledArray ) );
}
}
BF AvmcodeCompiler::compileArrayOfBF(
COMPILE_CONTEXT * aCTX, ArrayBF * bfarray)
{
BaseTypeSpecifier * arrayType = ( (aCTX->mType != NULL) &&
aCTX->mType->hasTypeComposite() ) ?
aCTX->mType : bfarray->getTypeSpecifier();
ArrayBF * compiledArray = new ArrayBF(arrayType, bfarray->size());
BF bfCompiledArray( compiledArray );
bool isnotCompiled = false;
if( aCTX->mType != NULL )
{
COMPILE_CONTEXT * contentCTX = NULL;
if( aCTX->mType->hasTypeCollection() &&
aCTX->mType->is< ContainerTypeSpecifier >() )
{
contentCTX = aCTX->clone( aCTX->mType->
to< ContainerTypeSpecifier >()->
getContentsTypeSpecifier() );
for( avm_size_t index = 0; index < bfarray->size() ; ++index )
{
compiledArray->set( index , decode_compileExpression(
contentCTX, bfarray->at(index) ) );
}
}
else if( aCTX->mType->isTypedStructure() )
{
ClassTypeSpecifier * typeStruct =
aCTX->mType->to< ClassTypeSpecifier >();
TableOfSymbol::const_iterator itField =
typeStruct->getSymbolData().begin();
TableOfSymbol::const_iterator endField =
typeStruct->getSymbolData().end();
for( avm_size_t index = 0; (index < bfarray->size()) &&
(itField != endField) ; ++index )
{
contentCTX = aCTX->clone(
(*itField).getTypeSpecifier() );
compiledArray->set( index , decode_compileExpression(
contentCTX, bfarray->at(index) ) );
}
}
else
{
isnotCompiled = true;
}
}
if( isnotCompiled )
{
for( avm_size_t index = 0; index < bfarray->size() ; ++index )
{
compiledArray->set( index ,
decode_compileExpression(
aCTX, bfarray->at(index) ) );
}
}
// Build the type specified container
if( (aCTX->mType != NULL) && aCTX->mType->hasTypeCollection() &&
aCTX->mType->is< ContainerTypeSpecifier >() )
{
if( AbstractAvmcodeCompiler::
mustBeEvaluatedArgumentArray( compiledArray ) )
{
return( ExpressionConstructor::newCode(
OperatorManager::OPERATOR_CTOR,
INCR_BF(aCTX->mType), bfCompiledArray) );
}
else
{
BuiltinContainer * containerValue = BuiltinContainer::create(
aCTX->mType->as< ContainerTypeSpecifier >() );
containerValue->copy( compiledArray, std::min(
containerValue->capacity(), compiledArray->size()) );
return( BF( containerValue ) );
}
}
else
{
return( bfCompiledArray );
}
}
BF AvmcodeCompiler::decode_compileVariableMachine(
COMPILE_CONTEXT * aCTX, const BF & aCode)
{
BF varCode = decode_compileExpression(aCTX, aCode);
if( varCode.is< InstanceOfMachine >() )
{
if( varCode.to_ptr< InstanceOfMachine >()->hasRuntimeRID() )
{
return( varCode.to_ptr< InstanceOfMachine >()->getRuntimeRID() );
}
return( varCode );
}
else if( varCode.is< InstanceOfData >() )
{
if( varCode.to_ptr< InstanceOfData >()->isTypedMachine() )
{
return( varCode );
}
}
return( BF::REF_NULL );
}
BF AvmcodeCompiler::decode_compileVariablePort(
COMPILE_CONTEXT * aCTX, const BF & aCode)
{
BF varCode = decode_compileExpression(aCTX, aCode);
if( varCode.is< InstanceOfPort >() )
{
return( varCode );
}
else if( varCode.is< InstanceOfData >() )
{
if( varCode.to_ptr< InstanceOfData >()->isTypedPort() )
{
return( varCode );
}
}
return( BF::REF_NULL );
}
BF AvmcodeCompiler::decode_compileVariableBuffer(
COMPILE_CONTEXT * aCTX, const BF & aCode)
{
BF varCode = decode_compileExpression(aCTX, aCode);
if( varCode.is< InstanceOfBuffer >() )
{
return( varCode );
}
else if( varCode.is< InstanceOfData >() )
{
if( varCode.to_ptr< InstanceOfData >()->isTypedBuffer() )
{
return( varCode );
}
}
return( BF::REF_NULL );
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//// the OPTIMIZER of EXPRESSION
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
BF AvmcodeCompiler::optimizeExpression(
COMPILE_CONTEXT * aCTX, const BFCode & aCode)
{
if( aCode->hasInstruction() )
{
return( aCode );
}
AVM_IF_DEBUG_LEVEL_FLAG( HIGH , COMPILING )
AVM_OS_TRACE << INCR_INDENT_TAB << "in<expr>: "
<< STRIML( aCode->toString(AVM_OS_TRACE.INDENT) )
<< std::flush;
AVM_ENDIF_DEBUG_LEVEL_FLAG( HIGH , COMPILING )
BF expr = AVMCODE_COMPILER_TABLE[ aCode->getOpOffset() ]->
optimizeExpression(aCTX, aCode);
AVM_IF_DEBUG_LEVEL_FLAG( HIGH , COMPILING )
AVM_OS_TRACE << TAB_DECR_INDENT << "out:> "
<< STRIML( expr.toString(AVM_OS_TRACE.INDENT) )
<< std::flush;
AVM_ENDIF_DEBUG_LEVEL_FLAG( HIGH , COMPILING )
return( expr );
}
BF AvmcodeCompiler::decode_optimizeExpression(
COMPILE_CONTEXT * aCTX, const BF & aCode)
{
switch( aCode.classKind() )
{
case FORM_AVMCODE_KIND:
{
return( optimizeExpression(aCTX, aCode.bfCode()) );
}
case FORM_INSTANCE_DATA_KIND:
{
InstanceOfData * anInstance = aCode.to_ptr< InstanceOfData >();
if( anInstance->getModifier().hasModifierPublicFinalStatic()
&& anInstance->isTypedEnum() && anInstance->hasValue() )
{
return( anInstance->getValue() );
}
else
{
BF optExpr = aCode;
return( optExpr );
}
}
default:
{
BF optExpr = aCode;
return( optExpr );
}
}
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//// the COMPILER of STATEMENT
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
BFCode AvmcodeCompiler::compileStatement(
COMPILE_CONTEXT * aCTX, const BFCode & aCode)
{
AVM_IF_DEBUG_LEVEL_FLAG( MEDIUM , COMPILING )
AVM_OS_TRACE << INCR_INDENT_TAB << "in<stmnt>: "
<< STRIML( aCode->toString(AVM_OS_TRACE.INDENT) )
<< std::flush;
// AVM_OS_TRACE << "aCode->getOperator() :> " << aCode->getOperator()->strOp()
// << std::endl
// << "aCode->getOpOffset() :> " << aCode->getOpOffset()
// << std::endl
// << "AVMCODE_COMPILER_TABLE :> @" << &AVMCODE_COMPILER_TABLE
// << std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG( MEDIUM , COMPILING )
BFCode stmnt = AVMCODE_COMPILER_TABLE[ aCode->getOpOffset() ]->
compileStatement(aCTX, aCode);
AVM_IF_DEBUG_LEVEL_FLAG( MEDIUM , COMPILING )
AVM_OS_TRACE << TAB_DECR_INDENT << "out:> "
<< STRIML( stmnt->toString(AVM_OS_TRACE.INDENT) )
<< std::flush;
AVM_ENDIF_DEBUG_LEVEL_FLAG( MEDIUM , COMPILING )
return( stmnt );
}
BF AvmcodeCompiler::decode_compileStatement(
COMPILE_CONTEXT * aCTX, const BF & aCode)
{
switch( aCode.classKind() )
{
case FORM_AVMCODE_KIND:
{
return( compileStatement(aCTX, aCode.bfCode()) );
}
case FORM_UFI_KIND:
{
return( compileUFI(aCTX, aCode.to_ref< UniFormIdentifier>()) );
}
case FORM_BUILTIN_QUALIFIED_IDENTIFIER_KIND:
{
if( aCode.str().find(':') != std::string::npos )
{
return( compileFullyQualifiedNameID(aCTX, aCode) );
}
else
{
return( compileQualifiedIdentifier(aCTX, aCode) );
}
}
case FORM_BUILTIN_IDENTIFIER_KIND:
{
return( compileQualifiedIdentifier(aCTX, aCode) );
}
case FORM_XFSP_DATATYPE_KIND:
{
return( compileDataType(aCTX, aCode) );
}
case FORM_XFSP_VARIABLE_KIND:
{
return( compileVariable(aCTX, aCode) );
}
case FORM_XFSP_MACHINE_KIND:
case FORM_XFSP_SYSTEM_KIND:
{
return( compileMachine(aCTX, aCode) );
}
// case FORM_XFSP_INSTANCE_KIND:
// {
// return( compileInstance(aCTX, aCode) );
// }
case FORM_XFSP_BUFFER_KIND:
{
return( compileBuffer(aCTX, aCode) );
}
case FORM_XFSP_PORT_KIND:
{
return( compilePort(aCTX, aCode) );
}
case FORM_XFSP_TRANSITION_KIND:
{
return( compileTransition(aCTX, aCode) );
}
case FORM_XFSP_ROUTINE_KIND:
{
return( compileRoutine(aCTX, aCode) );
}
case FORM_XFSP_PACKAGE_KIND:
case FORM_XFSP_CHANNEL_KIND:
case FORM_XFSP_COM_POINT_KIND:
case FORM_XFSP_COM_ROUTE_KIND:
case FORM_XFSP_CONNECTOR_KIND:
case FORM_OPERATOR_KIND:
case FORM_EXECUTABLE_MACHINE_KIND:
case FORM_INSTANCE_BUFFER_KIND:
case FORM_INSTANCE_CONNECTOR_KIND:
case FORM_INSTANCE_DATA_KIND:
case FORM_INSTANCE_MACHINE_KIND:
case FORM_INSTANCE_PORT_KIND:
case FORM_BUILTIN_BOOLEAN_KIND:
case FORM_BUILTIN_CHARACTER_KIND:
case FORM_BUILTIN_INTEGER_KIND:
case FORM_BUILTIN_RATIONAL_KIND:
case FORM_BUILTIN_FLOAT_KIND:
case FORM_BUILTIN_STRING_KIND:
{
return( aCode );
}
case FORM_ARRAY_BOOLEAN_KIND:
case FORM_ARRAY_CHARACTER_KIND:
case FORM_ARRAY_INTEGER_KIND:
case FORM_ARRAY_RATIONAL_KIND:
case FORM_ARRAY_FLOAT_KIND:
case FORM_ARRAY_STRING_KIND:
{
return( aCode );
}
case FORM_ARRAY_IDENTIFIER_KIND:
{
ArrayIdentifier * idArray = aCode.to_ptr< ArrayIdentifier >();
BFVector array;
for( avm_size_t index = 0; index < idArray->size() ; ++index )
{
array.append( compileIdentifier(aCTX, idArray->get(index)) );
}
return( BuiltinArray::create(array) );
}
case FORM_ARRAY_QUALIFIED_IDENTIFIER_KIND:
{
ArrayQualifiedIdentifier * ufiArray =
aCode.to_ptr< ArrayQualifiedIdentifier >();
BFVector array;
for( avm_size_t index = 0; index < ufiArray->size() ; ++index )
{
array.append( compileFullyQualifiedNameID(
aCTX, ufiArray->get(index)) );
}
return( BuiltinArray::create(array) );
}
case FORM_ARRAY_BF_KIND:
{
ArrayBF * bfarray = aCode.to_ptr< ArrayBF >();
BFVector array;
for( avm_size_t index = 0; index < bfarray->size() ; ++index )
{
array.append( decode_compileExpression(
aCTX, bfarray->at(index) ) );
}
return( BuiltinArray::create(array) );
}
default:
{ // TODO
AVM_OS_WARNING_ALERT
<< "AvmcodeCompiler is trying to decode_compileStatement"
"\n\t<< " << aCode.str() << " >> !!!"
<< SEND_ALERT;
return( BF::REF_NULL );
}
}
return( aCode );
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//// the OPTIMIZER of << RUNTIME >> EXPRESSION
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
bool AvmcodeCompiler::optimizeEvalExpression(
COMPILE_CONTEXT * aCTX, BFCode & aCode)
{
if( aCode->hasInstruction() )
{
return( true );
}
AVM_IF_DEBUG_LEVEL_FLAG( HIGH , COMPILING )
AVM_OS_TRACE << INCR_INDENT_TAB << "in<expr>: "
<< STRIML( aCode->toString(AVM_OS_TRACE.INDENT) )
<< std::flush;
AVM_ENDIF_DEBUG_LEVEL_FLAG( HIGH , COMPILING )
BF expr = AVMCODE_COMPILER_TABLE[ aCode->getOpOffset() ]->
optimizeExpression(aCTX, aCode);
AVM_IF_DEBUG_LEVEL_FLAG( HIGH , COMPILING )
AVM_OS_TRACE << TAB_DECR_INDENT << "out:> "
<< STRIML( expr.toString(AVM_OS_TRACE.INDENT) )
<< std::flush;
AVM_ENDIF_DEBUG_LEVEL_FLAG( HIGH , COMPILING )
if( expr.is< AvmCode >() )
{
aCode = expr.bfCode();
return( true );
}
return( false );
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//// the OPTIMIZER of STATEMENT
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
BFCode AvmcodeCompiler::optimizeStatement(
COMPILE_CONTEXT * aCTX, const BFCode & aCode)
{
if( aCode->hasInstruction() )
{
return( aCode );
}
AVM_IF_DEBUG_LEVEL_FLAG( MEDIUM , COMPILING )
AVM_OS_TRACE << INCR_INDENT_TAB << "in<stmnt>: "
<< STRIML( aCode->toString(AVM_OS_TRACE.INDENT) )
<< std::flush;
// AVM_OS_TRACE << "aCode->getOperator() :> " << aCode->getOperator()->strOp()
// << std::endl
// << "aCode->getOpOffset() :> " << aCode->getOpOffset()
// << std::endl
// << "AVMCODE_COMPILER_TABLE :> @" << &AVMCODE_COMPILER_TABLE
// << std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG( MEDIUM , COMPILING )
BFCode stmnt = AVMCODE_COMPILER_TABLE[ aCode->getOpOffset() ]->
optimizeStatement(aCTX, aCode);
AVM_IF_DEBUG_LEVEL_FLAG( MEDIUM , COMPILING )
AVM_OS_TRACE << TAB_DECR_INDENT << "out:> "
<< STRIML( stmnt->toString(AVM_OS_TRACE.INDENT) )
<< std::flush;
AVM_ENDIF_DEBUG_LEVEL_FLAG( MEDIUM , COMPILING )
return( stmnt );
}
BF AvmcodeCompiler::decode_optimizeStatement(
COMPILE_CONTEXT * aCTX, const BF & aCode)
{
switch( aCode.classKind() )
{
case FORM_AVMCODE_KIND:
{
return( optimizeStatement(aCTX, aCode.bfCode()) );
}
case FORM_AVMPROGRAM_KIND:
case FORM_AVMTRANSITION_KIND:
{
optimizeProgramRoutine( aCode.to_ptr< AvmProgram >() );
return( aCode );
}
default:
{
BF optCode = aCode;
return( optCode );
}
}
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//// the COMPILER of ROUTINE
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
AvmProgram * AvmcodeCompiler::compileRoutineStructure(
BaseCompiler * aCompiler, AvmProgram * aProgramCtx, Routine * aRoutine)
{
avm_size_t paramCount = aRoutine->getParameters().size();
avm_size_t returnCount = aRoutine->getReturns().size();
avm_size_t paramReturnCount = paramCount + returnCount;
AvmProgram * aCompiledRoutine = new AvmProgram(
Specifier::SCOPE_ROUTINE_KIND,
aProgramCtx, aRoutine, paramReturnCount );
aCompiledRoutine->setParamOffsetCount(0, paramCount);
aCompiledRoutine->setReturnOffsetCount(paramCount, returnCount);
InstanceOfData * anInstance = NULL;
TypeSpecifier bfTS;
avm_size_t offset = 0;
// Parameters
BFVector::raw_iterator< Variable > itVar = aRoutine->getParameters().begin();
for( ; offset < paramCount ; ++itVar , ++offset )
{
bfTS = aCompiler->compileTypeSpecifier(aProgramCtx, itVar->getType());
if( bfTS.invalid() )
{
bfTS = TypeManager::UNIVERSAL;
// incrErrorCount();
++AVM_ERROR_COUNT;
AVM_OS_ERROR_ALERT << "AvmcodeCompiler::compileRoutine : << "
<< itVar->strTypeSpecifier() << " >> !!!"
<< SEND_ALERT;
}
anInstance = new InstanceOfData(
IPointerDataNature::POINTER_STANDARD_NATURE,
aCompiledRoutine, itVar, bfTS, offset);
aCompiledRoutine->setData(offset, anInstance);
if( itVar->hasValue() )
{
anInstance->setValue(
decode_compileExpression(
aProgramCtx, itVar->getValue()) );
}
}
// Returns
itVar = aRoutine->getReturns().begin();
for( ; offset < paramReturnCount ; ++itVar , ++offset )
{
bfTS = aCompiler->compileTypeSpecifier(aProgramCtx, itVar->getType());
if( bfTS.invalid() )
{
bfTS = TypeManager::UNIVERSAL;
// incrErrorCount();
++AVM_ERROR_COUNT;
AVM_OS_ERROR_ALERT << "AvmcodeCompiler::compileRoutine : << "
<< itVar->strTypeSpecifier() << " >> !!!"
<< SEND_ALERT;
}
anInstance = new InstanceOfData(
IPointerDataNature::POINTER_STANDARD_NATURE,
aCompiledRoutine, itVar, bfTS, offset);
aCompiledRoutine->setData(offset, anInstance);
if( itVar->hasValue() )
{
anInstance->setValue(
decode_compileExpression(aProgramCtx, itVar->getValue()) );
}
}
// Finalize compiled data
aCompiledRoutine->updateDataTable();
return( aCompiledRoutine );
}
AvmProgram * AvmcodeCompiler::compileRoutine(BaseCompiler * aCompiler,
AvmProgram * aProgramCtx, Routine * aRoutine)
{
AvmProgram * aCompiledRoutine =
compileRoutineStructure(aCompiler, aProgramCtx, aRoutine);
// Compile Routine -> Code
aCompiledRoutine->setCode(
compileStatement(aCompiledRoutine, aRoutine->getCode()) );
return( aCompiledRoutine );
}
AvmProgram * AvmcodeCompiler::compileRoutine(
BaseCompiler * aCompiler, AvmProgram * aProgramCtx,
InstanceOfData * aVarInstanceCtx, Routine * aRoutine)
{
AvmProgram * aCompiledRoutine =
compileRoutineStructure(aCompiler, aProgramCtx, aRoutine);
// Compile Routine -> Code
CompilationEnvironment compilENV(aCompiledRoutine, aVarInstanceCtx);
aCompiledRoutine->setCode(
compileStatement(compilENV.mCTX, aRoutine->getCode()) );
return( aCompiledRoutine );
}
AvmProgram * AvmcodeCompiler::compileRoutine(
BaseCompiler * aCompiler, AvmProgram * aProgramCtx,
const TypeSpecifier & aTypeSpecifierCtx, Routine * aRoutine)
{
AvmProgram * aCompiledRoutine =
compileRoutineStructure(aCompiler, aProgramCtx, aRoutine);
// Compile Routine -> Code
aCompiledRoutine->setCode(
compileStatement(aCompiledRoutine, aRoutine->getCode()) );
return( aCompiledRoutine );
}
/**
*******************************************************************************
* POST-COMPILATION OF DATA ROUTINE
*******************************************************************************
*/
void AvmcodeCompiler::optimizeDataRoutine(AvmProgram * aProgram)
{
//AVM_OS_TRACE << TAB << "<| optimizing<program>: "
// << aProgram->getFullyQualifiedNameID() << std::endl;
if( aProgram->hasConstData() )
{
TableOfInstanceOfData::const_raw_iterator itData =
aProgram->getConstData().begin();
TableOfInstanceOfData::const_raw_iterator endData =
aProgram->getConstData().end();
for( ; itData != endData ; ++itData )
{
/*
* initial macro value
*/
if( (itData)->getModifier().hasNatureMacro()
&& (itData)->hasValue()
&& (itData)->getValue().is< AvmCode >() )
{
(itData)->set