void dDAGExpressionNodeVariable::CompileCIL(dCIL& cil)
{
	size_t pos =  m_name.find (D_SCOPE_PREFIX, 0, strlen (D_SCOPE_PREFIX));
	if (pos != 0) {
		bool state = RenameLocalVariable(m_name);
		if (!state) {
			DTRACE (("undefined local variable\n"));
			_ASSERTE (0);
		}
	}


	if (m_dimExpressions.GetCount()) {
		dDAGDimensionNode* const dim = m_dimExpressions.GetFirst()->GetInfo();
		dim->CompileCIL(cil);
		dCIL::dListNode* const dimInstruction = cil.NewStatement();
		dTreeAdressStmt& addressIndex = dimInstruction->GetInfo();
		addressIndex.m_instruction = dTreeAdressStmt::m_assigment;
		addressIndex.m_arg0.m_label = cil.NewTemp();
		addressIndex.m_arg1.m_label = dim->m_result; 

		string result = addressIndex.m_arg0.m_label;
		dTRACE_INTRUCTION (&addressIndex);

		for (dList<dDAGDimensionNode*>::dListNode* node = m_dimExpressions.GetFirst()->GetNext(); node; node = node->GetNext()) {
			dDAGDimensionNode* const dim = node->GetInfo();
			dim->CompileCIL(cil);
			
			dTreeAdressStmt& stmtMul = cil.NewStatement()->GetInfo();
			stmtMul.m_instruction = dTreeAdressStmt::m_assigment;
			stmtMul.m_operator = dTreeAdressStmt::m_mul;
			stmtMul.m_arg0.m_label = cil.NewTemp();
			stmtMul.m_arg1.m_label = result;
			stmtMul.m_arg2.m_label = dim->m_arraySize;

			dTRACE_INTRUCTION (&stmtMul);

			dTreeAdressStmt& stmtAdd = cil.NewStatement()->GetInfo();
			stmtAdd.m_instruction = dTreeAdressStmt::m_assigment;
			stmtAdd.m_operator = dTreeAdressStmt::m_add;
			stmtAdd.m_arg0.m_label = cil.NewTemp();
			stmtAdd.m_arg1.m_label = stmtMul.m_arg0.m_label;
			stmtAdd.m_arg2.m_label = dim->m_result;

			result = stmtAdd.m_arg0.m_label;

			dTRACE_INTRUCTION (&stmtAdd);
		}

		dTreeAdressStmt& dimSize = cil.NewStatement()->GetInfo();
		dimSize.m_instruction = dTreeAdressStmt::m_assigment;
		dimSize.m_operator = dTreeAdressStmt::m_mul;
		dimSize.m_arg0.m_label = cil.NewTemp();
		dimSize.m_arg1.m_label = result; 
		dimSize.m_arg2.m_label = "4"; 
		dTRACE_INTRUCTION (&dimSize);

		result = dimSize.m_arg0.m_label;

		_ASSERTE (m_parent);
		if (m_parent->GetTypeId() == dDAGFunctionStatementAssigment::GetRttiType()) {
			dDAGFunctionStatementAssigment* const asmt = (dDAGFunctionStatementAssigment*) m_parent;
			if (asmt->m_leftVariable == this) {
				//m_result = m_name + '[' + result + ']';
				m_result = result;
			} else {
				// emit an indirect addressing mode
				dTreeAdressStmt& tmp = cil.NewStatement()->GetInfo();
//				m_result = m_name + '[' + addressIndex.m_arg0.m_label + ']';
//				tmp.m_instruction = dTreeAdressStmt::m_assigment;
//				tmp.m_arg0.m_label = cil.NewTemp();
//				tmp.m_arg1.m_label = m_name + '[' + result + ']';
				tmp.m_instruction = dTreeAdressStmt::m_load;
				tmp.m_arg0.m_label = cil.NewTemp();
				tmp.m_arg1.m_label = m_name;
				tmp.m_arg2.m_label = result;
				dTRACE_INTRUCTION (&tmp);
				m_result = tmp.m_arg0.m_label; 
			}
			
		} else {
			// emit an indirect addressing mode
			dTreeAdressStmt& tmp = cil.NewStatement()->GetInfo();
//			m_result = m_name + '[' + addressIndex.m_arg0.m_label + ']';
//			tmp.m_instruction = dTreeAdressStmt::m_assigment;
//			tmp.m_arg0.m_label = cil.NewTemp();;
//			tmp.m_arg1.m_label = m_name + '[' + result + ']';
			tmp.m_instruction = dTreeAdressStmt::m_load;
			tmp.m_arg0.m_label = cil.NewTemp();
			tmp.m_arg1.m_label = m_name;
			tmp.m_arg2.m_label = result;
			dTRACE_INTRUCTION (&tmp);
			m_result = tmp.m_arg0.m_label; 
		}
	} else {
		m_result = m_name;
	}

}
void dDAGFunctionNode::CompileCIL(dCIL& cil)  
{
	dAssert (m_body);
	dDAGClassNode* const myClass = GetClass();

	cil.ResetTemporaries();
	dString returnVariable (cil.NewTemp());

	dString functionName (myClass->GetFunctionName (m_name, m_parameters));
	dCILInstrFunction* const function = new dCILInstrFunction (cil, functionName, m_returnType->GetArgType());
	m_functionStart = function->GetNode();

	if (!m_isStatic) {
		dAssert (0);
//		dList<dDAGParameterNode*>::dListNode* const argNode = m_parameters.GetFirst();
//		dDAGParameterNode* const arg = argNode->GetInfo();
//		m_opertatorThis = arg->m_result.m_label;
	}

	// emit the function arguments
	for (dList<dDAGParameterNode*>::dListNode* argNode = m_parameters.GetFirst(); argNode; argNode = argNode->GetNext()) {
		dDAGParameterNode* const arg = argNode->GetInfo();
		arg->m_result = function->AddParameter (arg->m_name, arg->m_type->GetArgType())->GetInfo();
	}
	function->Trace();

	dCILInstrLabel* const entryPoint = new dCILInstrLabel(cil, cil.NewLabel());
	entryPoint->Trace();

	for (dList<dDAGParameterNode*>::dListNode* argNode = m_parameters.GetFirst(); argNode; argNode = argNode->GetNext()) {
		dDAGParameterNode* const arg = argNode->GetInfo();

		dTree<dCILInstr::dArg, dString>::dTreeNode* const varNameNode = m_body->FindVariable(arg->m_name);
		dAssert (varNameNode);
		dCILInstrArgument* const localVariable = new dCILInstrArgument(cil, varNameNode->GetInfo().m_label, varNameNode->GetInfo().GetType());
		localVariable->Trace();
	}


	for (dList<dDAGParameterNode*>::dListNode* argNode = m_parameters.GetFirst(); argNode; argNode = argNode->GetNext()) {
		dDAGParameterNode* const arg = argNode->GetInfo();
		dTree<dCILInstr::dArg, dString>::dTreeNode* const varNameNode = m_body->FindVariable(arg->m_name);
		dAssert (varNameNode);
		//dCILInstrStore* const store = new dCILInstrStore(cil, varNameNode->GetInfo().m_label, varNameNode->GetInfo().GetType(), arg->m_name, arg->GetType()->GetArgType());
		dString localVariableAliasName(cil.NewTemp());
		dCILInstrMove* const store = new dCILInstrMove(cil, localVariableAliasName, arg->GetType()->GetArgType(), varNameNode->GetInfo().m_label, varNameNode->GetInfo().GetType());
		//arg->m_result =  store->GetArg0();
		varNameNode->GetInfo().m_label = localVariableAliasName;
		store->Trace();
	}


	m_body->CompileCIL(cil);
	if (!m_returnType->GetArgType().m_isPointer && (m_returnType->GetArgType().m_intrinsicType == dCILInstr::m_void)) {
		 if (!cil.GetLast()->GetInfo()->GetAsReturn()) {
			dCILInstrReturn* const ret = new dCILInstrReturn(cil, "", dCILInstr::dArgType (dCILInstr::m_void));
			ret->Trace();
		}
	}

	new dCILInstrFunctionEnd(function);
//	cil.Trace();
}
void dDAGExpressionNodeAssigment::CompileCIL(dCIL& cil)  
{
	m_expression->CompileCIL(cil); 
	if (m_leftVariable->m_dimExpressions.GetCount()) {
		
		dDAGDimensionNode* const dim = m_leftVariable->m_dimExpressions.GetFirst()->GetInfo();
		dim->CompileCIL(cil);

		dString result = dim->m_result.m_label;
		for (dList<dDAGDimensionNode*>::dListNode* node = m_leftVariable->m_dimExpressions.GetFirst()->GetNext(); node; node = node->GetNext()) {
			dAssert (0);
			dDAGDimensionNode* const dim = node->GetInfo();
			dim->CompileCIL(cil);
#if 0			
			dCILInstr& stmtMul = cil.NewStatement()->GetInfo();
			stmtMul.m_instruction = dCILInstr::m_assigment;
			stmtMul.m_operator = dCILInstr::m_mul;
			stmtMul.m_arg0.m_label = cil.NewTemp();
			stmtMul.m_arg1.m_label = result;
			stmtMul.m_arg2.m_label = dim->m_arraySize;

			DTRACE_INTRUCTION (&stmtMul);

			dCILInstr& stmtAdd = cil.NewStatement()->GetInfo();
			stmtAdd.m_instruction = dCILInstr::m_assigment;
			stmtAdd.m_operator = dCILInstr::m_add;
			stmtAdd.m_arg0.m_label = cil.NewTemp();
			stmtAdd.m_arg1.m_label = stmtMul.m_arg0.m_label;
			stmtAdd.m_arg2 = dim->m_result;

			result = stmtAdd.m_arg0.m_label;

			DTRACE_INTRUCTION (&stmtAdd);
#endif
		}

		dAssert (m_leftVariable->m_parent);
		dTree<dCILInstr::dArg, dString>::dTreeNode* const variable = dDAG::FindLocalVariable(m_leftVariable->m_name);
		dAssert (variable);

		dCILInstr::dArg arg0 (LoadLocalVariable(cil, m_expression->m_result));
		dCILInstr::dArg arg1 (LoadLocalVariable(cil, variable->GetInfo()));

		int size = arg0.GetSizeInByte();
		dCILInstrIntergerLogical* const mulOffset = new dCILInstrIntergerLogical(cil, dCILThreeArgInstr::m_mul,cil.NewTemp(), dCILInstr::dArgType(dCILInstr::m_int), result, dCILInstr::dArgType(dCILInstr::m_int), dString(size), dCILInstr::m_constInt);
		mulOffset->Trace();

		dCILInstrIntergerLogical* const address = new dCILInstrIntergerLogical(cil, dCILThreeArgInstr::m_add, cil.NewTemp(), arg1.GetType(), arg1.m_label, arg1.GetType(), mulOffset->GetArg0().m_label, mulOffset->GetArg0().GetType());
		address->Trace();

		dCILInstrStore* const store = new dCILInstrStore(cil, address->GetArg0().m_label, address->GetArg0().GetType(), arg0.m_label, arg0.GetType());
		store->Trace();
		m_result = arg0;
		
	} else {
		m_leftVariable->CompileCIL(cil); 
		dCILInstr::dArg arg1 (LoadLocalVariable(cil, m_expression->m_result));
		dCILInstrMove* const move = new dCILInstrMove (cil, m_leftVariable->m_result.m_label, m_leftVariable->m_result.GetType(), arg1.m_label, arg1.GetType());
		move->Trace();
	}
}