예제 #1
0
	Node* AssignmentNode::expandToAsebaTree(std::wostream *dump, unsigned int index)
	{
		assert(children.size() == 2);

		MemoryVectorNode* leftVector = dynamic_cast<MemoryVectorNode*>(children[0]);
		if (!leftVector)
			throw TranslatableError(sourcePos, ERROR_INCORRECT_LEFT_VALUE).arg(children[0]->toNodeName());
		leftVector->setWrite(true);
		Node* rightVector = children[1];

		std::auto_ptr<BlockNode> block(new BlockNode(sourcePos));
		for (unsigned int i = 0; i < leftVector->getVectorSize(); i++)
		{
			// expand to left[i] = right[i]
			std::auto_ptr<AssignmentNode> assignment(new AssignmentNode(sourcePos));
			assignment->children.push_back(leftVector->expandToAsebaTree(dump, i));
			assignment->children.push_back(rightVector->expandToAsebaTree(dump, i));
			block->children.push_back(assignment.release());
		}

		delete this;
		return block.release();
	}
예제 #2
0
	//! Assignment between vectors is expanded into multiple scalar assignments
	Node* AssignmentNode::expandVectorialNodes(std::wostream *dump, Compiler* compiler, unsigned int index)
	{
		assert(children.size() == 2);

		// left vector should reference a memory location
		MemoryVectorNode* leftVector = dynamic_cast<MemoryVectorNode*>(children[0]);
		if (!leftVector)
			throw TranslatableError(sourcePos, ERROR_INCORRECT_LEFT_VALUE).arg(children[0]->toNodeName());
		leftVector->setWrite(true);

		// right vector can be anything
		Node* rightVector = children[1];

		// check if the left vector appears somewhere on the right side
		if (matchNameInMemoryVector(rightVector, leftVector->arrayName) && leftVector->getVectorSize() > 1)
		{
			// in such case, there is a risk of involuntary overwriting the content
			// we need to throw in a temporary variable to avoid this risk
			std::auto_ptr<BlockNode> tempBlock(new BlockNode(sourcePos));

			// tempVar = rightVector
			std::auto_ptr<AssignmentNode> temp(compiler->allocateTemporaryVariable(sourcePos, rightVector->deepCopy()));
			MemoryVectorNode* tempVar = dynamic_cast<MemoryVectorNode*>(temp->children[0]);
			assert(tempVar);
			tempBlock->children.push_back(temp.release());

			// leftVector = tempVar
			temp.reset(new AssignmentNode(sourcePos, leftVector->deepCopy(), tempVar->deepCopy()));
			tempBlock->children.push_back(temp.release());

			return tempBlock->expandVectorialNodes(dump, compiler); // tempBlock will be reclaimed
		}
		// else

		std::auto_ptr<BlockNode> block(new BlockNode(sourcePos)); // top-level block

		for (unsigned int i = 0; i < leftVector->getVectorSize(); i++)
		{
			// expand to left[i] = right[i]
			block->children.push_back(new AssignmentNode(sourcePos,
								      leftVector->expandVectorialNodes(dump, compiler, i),
								      rightVector->expandVectorialNodes(dump, compiler, i)));
		}

		return block.release();
	}