1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-09 03:52:19 +02:00

Reworked ref enumerators to support non-pointer refs

This commit is contained in:
Brian Fiete 2020-05-01 16:29:12 -07:00
parent 70d32885b1
commit d5073e810c
10 changed files with 82 additions and 24 deletions

View file

@ -13,9 +13,13 @@ namespace System.Collections
using System.Diagnostics; using System.Diagnostics;
using System.Diagnostics.Contracts; using System.Diagnostics.Contracts;
public class Dictionary<TKey, TValue> : ICollection<(TKey key, TValue value)>, IEnumerable<(TKey key, TValue value)> where TKey : IHashable public class Dictionary<TKey, TValue> :
ICollection<(TKey key, TValue value)>,
IEnumerable<(TKey key, TValue value)>,
IRefEnumerable<(TKey key, TValue* valueRef)> where TKey : IHashable
{ {
typealias KeyValuePair=(TKey key, TValue value); typealias KeyValuePair=(TKey key, TValue value);
typealias KeyRefValuePair=(TKey key, TValue* valueRef);
private struct Entry private struct Entry
{ {
@ -606,7 +610,7 @@ namespace System.Collections
return (key is TKey); return (key is TKey);
} }
public struct Enumerator : IEnumerator<KeyValuePair>//, IDictionaryEnumerator public struct Enumerator : IEnumerator<KeyValuePair>, IRefEnumerator<KeyRefValuePair>
{ {
private Dictionary<TKey, TValue> mDictionary; private Dictionary<TKey, TValue> mDictionary;
#if VERSION_DICTIONARY #if VERSION_DICTIONARY
@ -687,6 +691,11 @@ namespace System.Collections
get { return (mDictionary.mEntries[mCurrentIndex].mKey, mDictionary.mEntries[mCurrentIndex].mValue); } get { return (mDictionary.mEntries[mCurrentIndex].mKey, mDictionary.mEntries[mCurrentIndex].mValue); }
} }
public KeyRefValuePair CurrentRef
{
get { return (mDictionary.mEntries[mCurrentIndex].mKey, &mDictionary.mEntries[mCurrentIndex].mValue); }
}
public void Dispose() public void Dispose()
{ {
@ -753,9 +762,16 @@ namespace System.Collections
return .Err; return .Err;
return Current; return Current;
} }
public Result<KeyRefValuePair> GetNextRef() mut
{
if (!MoveNext())
return .Err;
return CurrentRef;
}
} }
public struct ValueEnumerator : IRefEnumerator<TValue>, IResettable public struct ValueEnumerator : IRefEnumerator<TValue*>, IEnumerator<TValue>, IResettable
{ {
private Dictionary<TKey, TValue> mDictionary; private Dictionary<TKey, TValue> mDictionary;
#if VERSION_DICTIONARY #if VERSION_DICTIONARY

View file

@ -12,13 +12,18 @@ namespace System.Collections
void Reset() mut; void Reset() mut;
} }
interface IRefEnumerator<T> : IEnumerator<T> interface IRefEnumerator<T>
{ {
Result<T*> GetNextRef() mut; Result<T> GetNextRef() mut;
} }
concrete interface IEnumerable<T> concrete interface IEnumerable<T>
{ {
concrete IEnumerator<T> GetEnumerator(); concrete IEnumerator<T> GetEnumerator();
} }
concrete interface IRefEnumerable<T>
{
concrete IRefEnumerator<T> GetEnumerator();
}
} }

View file

@ -623,7 +623,7 @@ namespace System.Collections
} }
} }
public struct Enumerator : IRefEnumerator<T>, IResettable public struct Enumerator : IRefEnumerator<T*>, IEnumerator<T>, IResettable
{ {
private List<T> mList; private List<T> mList;
private int mIndex; private int mIndex;

View file

@ -351,7 +351,7 @@ namespace System.Collections
/// Implements an enumerator for a Queue. The enumerator uses the /// Implements an enumerator for a Queue. The enumerator uses the
/// internal version number of the list to ensure that no modifications are /// internal version number of the list to ensure that no modifications are
/// made to the list while an enumeration is in progress. /// made to the list while an enumeration is in progress.
public struct Enumerator : IRefEnumerator<T> public struct Enumerator : IRefEnumerator<T*>, IEnumerator<T>
{ {
private Queue<T> mQueue; private Queue<T> mQueue;
private int32 mIndex; // -1 = not started, -2 = ended/disposed private int32 mIndex; // -1 = not started, -2 = ended/disposed

View file

@ -184,7 +184,7 @@ namespace System
return Enumerator(this); return Enumerator(this);
} }
public struct Enumerator : IEnumerator<T>, IRefEnumerator<T> public struct Enumerator : IEnumerator<T>, IRefEnumerator<T*>
{ {
private Span<T> mList; private Span<T> mList;
private int mIndex; private int mIndex;

View file

@ -2360,7 +2360,7 @@ namespace System
} }
} }
public struct RawEnumerator : IRefEnumerator<char8> public struct RawEnumerator : IRefEnumerator<char8*>, IEnumerator<char8>
{ {
char8* mPtr; char8* mPtr;
int_strsize mIdx; int_strsize mIdx;

View file

@ -12150,7 +12150,7 @@ BfModuleMethodInstance BfExprEvaluator::GetSelectedMethod(BfAstNode* targetSrc,
if ((invocationExpr != NULL) && (invocationExpr->mGenericArgs != NULL)) if ((invocationExpr != NULL) && (invocationExpr->mGenericArgs != NULL))
{ {
errorNode = invocationExpr->mGenericArgs->mGenericArgs[(int)methodDef->mGenericParams.size()]; errorNode = invocationExpr->mGenericArgs->mGenericArgs[(int)methodDef->mGenericParams.size()];
if (errorNode == NULL) if ((errorNode == NULL) && (!invocationExpr->mGenericArgs->mCommas.IsEmpty()))
errorNode = invocationExpr->mGenericArgs->mCommas[(int)methodDef->mGenericParams.size() - 1]; errorNode = invocationExpr->mGenericArgs->mCommas[(int)methodDef->mGenericParams.size() - 1];
} }
mModule->Fail(StrFormat("Too many generic arguments, expected %d fewer", genericArgCountDiff), errorNode); mModule->Fail(StrFormat("Too many generic arguments, expected %d fewer", genericArgCountDiff), errorNode);

View file

@ -906,9 +906,7 @@ bool BfModule::PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType
if (typeAliasDecl->mAliasToType != NULL) if (typeAliasDecl->mAliasToType != NULL)
aliasToType = ResolveTypeRef(typeAliasDecl->mAliasToType, BfPopulateType_IdentityNoRemapAlias); aliasToType = ResolveTypeRef(typeAliasDecl->mAliasToType, BfPopulateType_IdentityNoRemapAlias);
} }
//typeAlias->mModule = mContext->mScratchModule;
typeAlias->mTypeIncomplete = false;
typeAlias->mDefineState = BfTypeDefineState_DefinedAndMethodsSlotted;
if (aliasToType != NULL) if (aliasToType != NULL)
{ {
AddDependency(aliasToType, typeAlias, BfDependencyMap::DependencyFlag_DerivedFrom); AddDependency(aliasToType, typeAlias, BfDependencyMap::DependencyFlag_DerivedFrom);
@ -951,7 +949,7 @@ bool BfModule::PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType
resolvedTypeRef->mRebuildFlags = BfTypeRebuildFlag_None; resolvedTypeRef->mRebuildFlags = BfTypeRebuildFlag_None;
typeAlias->mCustomAttributes = GetCustomAttributes(typeDef->mTypeDeclaration->mAttributes, BfAttributeTargets_Alias); typeAlias->mCustomAttributes = GetCustomAttributes(typeDef->mTypeDeclaration->mAttributes, BfAttributeTargets_Alias);
return true; // Fall through so generic params are populated in DoPopulateType
} }
if (resolvedTypeRef->IsSizedArray()) if (resolvedTypeRef->IsSizedArray())
@ -1159,6 +1157,7 @@ bool BfModule::PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType
case BfTypeCode_Struct: case BfTypeCode_Struct:
case BfTypeCode_Interface: case BfTypeCode_Interface:
case BfTypeCode_Enum: case BfTypeCode_Enum:
case BfTypeCode_TypeAlias:
// Implemented below // Implemented below
break; break;
case BfTypeCode_Extension: case BfTypeCode_Extension:
@ -1518,6 +1517,13 @@ bool BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
BuildGenericParams(resolvedTypeRef); BuildGenericParams(resolvedTypeRef);
} }
if (resolvedTypeRef->IsTypeAlias())
{
typeInstance->mTypeIncomplete = false;
resolvedTypeRef->mDefineState = BfTypeDefineState_DefinedAndMethodsSlotted;
return true;
}
if (_CheckTypeDone()) if (_CheckTypeDone())
return true; return true;

View file

@ -3768,7 +3768,28 @@ String BfTypeUtils::TypeToString(BfTypeReference* typeRef)
} }
if (auto directStrTypeName = BfNodeDynCast<BfDirectStrTypeReference>(typeRef)) if (auto directStrTypeName = BfNodeDynCast<BfDirectStrTypeReference>(typeRef))
return directStrTypeName->mTypeName; return directStrTypeName->mTypeName;
BF_FATAL("Not implemented");
if (auto tupleTypeRef = BfNodeDynCast<BfTupleTypeRef>(typeRef))
{
String name = "(";
for (int i = 0; i < tupleTypeRef->mFieldTypes.size(); i++)
{
if (i > 0)
name += ", ";
name += TypeToString(tupleTypeRef->mFieldTypes[i]);
if ((i < tupleTypeRef->mFieldNames.size()) && (tupleTypeRef->mFieldNames[i] != NULL))
{
name += " ";
name += tupleTypeRef->mFieldNames[i]->ToString();
}
}
name += ")";
return name;
}
BF_DBG_FATAL("Not implemented");
return "???"; return "???";
} }

View file

@ -3696,6 +3696,7 @@ void BfModule::Visit(BfDeleteStatement* deleteStmt)
if (checkType->IsPointer()) if (checkType->IsPointer())
{ {
auto innerType = checkType->GetUnderlyingType(); auto innerType = checkType->GetUnderlyingType();
PopulateType(innerType);
if (innerType->IsValuelessType()) if (innerType->IsValuelessType())
mayBeSentinel = true; mayBeSentinel = true;
} }
@ -5383,7 +5384,7 @@ void BfModule::Visit(BfForStatement* forStmt)
} }
void BfModule::DoForLess(BfForEachStatement* forEachStmt) void BfModule::DoForLess(BfForEachStatement* forEachStmt)
{ {
UpdateSrcPos(forEachStmt); UpdateSrcPos(forEachStmt);
BfScopeData scopeData; BfScopeData scopeData;
@ -5714,8 +5715,7 @@ void BfModule::Visit(BfForEachStatement* forEachStmt)
{ {
if (genericItrInterface != NULL) if (genericItrInterface != NULL)
{ {
Fail(StrFormat("Type '%s' implements multiple %s<T> interfaces", TypeToString(itr.mType).c_str(), isRefExpression ? "IRefEnumerator" : "IEnumerator"), forEachStmt->mCollectionExpression); Fail(StrFormat("Type '%s' implements multiple %s<T> interfaces", TypeToString(itr.mType).c_str(), isRefExpression ? "IRefEnumerator" : "IEnumerator"), forEachStmt->mCollectionExpression);
return;
} }
itrInterface = interface; itrInterface = interface;
@ -5724,7 +5724,11 @@ void BfModule::Visit(BfForEachStatement* forEachStmt)
{ {
varType = genericItrInterface->mTypeGenericArguments[0]; varType = genericItrInterface->mTypeGenericArguments[0];
if (isRefExpression) if (isRefExpression)
varType = CreateRefType(varType); {
if (varType->IsPointer())
varType = CreateRefType(varType->GetUnderlyingType());
}
} }
} }
} }
@ -5737,7 +5741,10 @@ void BfModule::Visit(BfForEachStatement* forEachStmt)
{ {
varType = genericItrInterface->mTypeGenericArguments[0]; varType = genericItrInterface->mTypeGenericArguments[0];
if (isRefExpression) if (isRefExpression)
varType = CreateRefType(varType); {
if (varType->IsPointer())
varType = CreateRefType(varType);
}
} }
} }
} }
@ -5761,9 +5768,9 @@ void BfModule::Visit(BfForEachStatement* forEachStmt)
refItrInterface = itrInterface; refItrInterface = itrInterface;
PopulateType(refItrInterface); PopulateType(refItrInterface);
// Must IRefEnumeratorf<T> must include only IEnumerator<T> // Must IRefEnumeratorf<T> must include only IEnumerator<T>
BF_ASSERT(refItrInterface->mInterfaces.size() == 1); // BF_ASSERT(refItrInterface->mInterfaces.size() == 1);
if (refItrInterface->mInterfaces.size() == 1) // if (refItrInterface->mInterfaces.size() == 1)
itrInterface = refItrInterface->mInterfaces[0].mInterfaceType; // itrInterface = refItrInterface->mInterfaces[0].mInterfaceType;
} }
itr = MakeAddressable(itr); itr = MakeAddressable(itr);
itr = RemoveReadOnly(itr); itr = RemoveReadOnly(itr);
@ -6220,7 +6227,10 @@ void BfModule::Visit(BfForEachStatement* forEachStmt)
{ {
auto nextVal = BfTypedValue(mBfIRBuilder->CreateBitCast(nextResult.mValue, mBfIRBuilder->MapType(CreatePointerType(nextEmbeddedType))), nextEmbeddedType, true); auto nextVal = BfTypedValue(mBfIRBuilder->CreateBitCast(nextResult.mValue, mBfIRBuilder->MapType(CreatePointerType(nextEmbeddedType))), nextEmbeddedType, true);
if (isRefExpression) if (isRefExpression)
nextVal = BfTypedValue(nextVal.mValue, CreateRefType(nextVal.mType->GetUnderlyingType()), true); {
if (nextVal.mType->IsPointer())
nextVal = BfTypedValue(nextVal.mValue, CreateRefType(nextVal.mType->GetUnderlyingType()), true);
}
nextVal = Cast(forEachStmt->mCollectionExpression, nextVal, varType, BfCastFlags_Explicit); nextVal = Cast(forEachStmt->mCollectionExpression, nextVal, varType, BfCastFlags_Explicit);
nextVal = LoadValue(nextVal); nextVal = LoadValue(nextVal);
if (nextVal) if (nextVal)