MCPcopy Create free account
hub / github.com/WheretIB/nullc / AddArrayIndexNode

Function AddArrayIndexNode

NULLC/Callbacks.cpp:1690–1760  ·  view source on GitHub ↗

Function for array indexing

Source from the content-addressed store, hash-verified

1688
1689// Function for array indexing
1690void AddArrayIndexNode(const char* pos, unsigned argumentCount)
1691{
1692 CodeInfo::lastKnownStartPos = pos;
1693
1694 if(CodeInfo::nodeList[CodeInfo::nodeList.size() - argumentCount - 1]->typeInfo->refLevel == 2)
1695 {
1696 NodeZeroOP *array = CodeInfo::nodeList[CodeInfo::nodeList.size() - argumentCount - 1];
1697 CodeInfo::nodeList.push_back(array);
1698 CodeInfo::nodeList.push_back(new NodeDereference());
1699 array = CodeInfo::nodeList.back();
1700 CodeInfo::nodeList.pop_back();
1701 CodeInfo::nodeList[CodeInfo::nodeList.size() - argumentCount - 1] = array;
1702 }
1703 // Get array type
1704 TypeInfo *currentType = CodeInfo::nodeList[CodeInfo::nodeList.size()-2]->typeInfo;
1705 // Ignore errors only if we have one index and we are indexing array or a pointer to array
1706 if(AddFunctionCallNode(CodeInfo::lastKnownStartPos, "[]", argumentCount + 1, argumentCount == 1 && (currentType->arrLevel || (currentType->subType && currentType->subType->arrLevel))))
1707 return;
1708
1709 bool unifyTwo = false;
1710 // If it's an inplace array, set it to hidden variable, and put it's address on stack
1711 if(currentType->arrLevel != 0)
1712 {
1713 NodeZeroOP *index = CodeInfo::nodeList.back();
1714 CodeInfo::nodeList.pop_back();
1715 AddInplaceVariable(pos);
1716 currentType = CodeInfo::GetReferenceType(currentType);
1717 CodeInfo::nodeList.push_back(index);
1718 unifyTwo = true;
1719 }
1720 // Current type must be a reference to an array
1721 assert(currentType->refLevel && currentType->subType->arrLevel);
1722
1723 // Get result type
1724 currentType = CodeInfo::GetDereferenceType(currentType);
1725
1726 // If it is array without explicit size (pointer to array)
1727 if(currentType->arrSize == TypeInfo::UNSIZED_ARRAY)
1728 {
1729 // Then, before indexing it, we need to get address from this variable
1730 NodeZeroOP* temp = CodeInfo::nodeList.back();
1731 CodeInfo::nodeList.pop_back();
1732 CodeInfo::nodeList.push_back(new NodeDereference());
1733 CodeInfo::nodeList.push_back(temp);
1734 }
1735#ifndef NULLC_ENABLE_C_TRANSLATION
1736 // If index is a number and previous node is an address, then indexing can be done in compile-time
1737 if(CodeInfo::nodeList.back()->nodeType == typeNodeNumber && CodeInfo::nodeList[CodeInfo::nodeList.size()-2]->nodeType == typeNodeGetAddress)
1738 {
1739 // Get shift value
1740 int shiftValue = static_cast<NodeNumber*>(CodeInfo::nodeList.back())->GetInteger();
1741
1742 // Check bounds
1743 if(shiftValue < 0)
1744 ThrowError(pos, "ERROR: array index cannot be negative");
1745 if((unsigned int)shiftValue >= currentType->arrSize)
1746 ThrowError(pos, "ERROR: array index out of bounds");
1747

Callers 2

AddArrayIteratorFunction · 0.85
ParsePostExpressionFunction · 0.85

Calls 10

AddFunctionCallNodeFunction · 0.85
AddInplaceVariableFunction · 0.85
assertFunction · 0.85
ThrowErrorFunction · 0.85
AddTwoExpressionNodeFunction · 0.85
GetIntegerMethod · 0.80
IndexArrayMethod · 0.80
sizeMethod · 0.45
push_backMethod · 0.45
pop_backMethod · 0.45

Tested by

no test coverage detected