mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 19:48:20 +02:00
Added @return support
This commit is contained in:
parent
f8ec709750
commit
e06949dac1
10 changed files with 88 additions and 32 deletions
|
@ -49,7 +49,7 @@ namespace System.Reflection
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (Compiler.IsComptime)
|
if (Compiler.IsComptime)
|
||||||
Type.[Friend]GetType((.)Type.[Friend]Comptime_Method_GetInfo(mNativeMethodInstance).mReturnTypeId);
|
return Type.[Friend]GetType((.)Type.[Friend]Comptime_Method_GetInfo(mNativeMethodInstance).mReturnTypeId);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -583,7 +583,7 @@ namespace System
|
||||||
{
|
{
|
||||||
if (Compiler.IsComptime)
|
if (Compiler.IsComptime)
|
||||||
{
|
{
|
||||||
return Comptime_Type_GetCustomAttribute((int32)TypeId, typeof(T).TypeId, null);
|
return Comptime_Type_GetCustomAttribute((int32)TypeId, (.)typeof(T).TypeId, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (var typeInstance = this as TypeInstance)
|
if (var typeInstance = this as TypeInstance)
|
||||||
|
@ -596,7 +596,7 @@ namespace System
|
||||||
if (Compiler.IsComptime)
|
if (Compiler.IsComptime)
|
||||||
{
|
{
|
||||||
T val = ?;
|
T val = ?;
|
||||||
if (Comptime_Type_GetCustomAttribute((int32)TypeId, typeof(T).TypeId, &val))
|
if (Comptime_Type_GetCustomAttribute((int32)TypeId, (.)typeof(T).TypeId, &val))
|
||||||
return val;
|
return val;
|
||||||
return .Err;
|
return .Err;
|
||||||
}
|
}
|
||||||
|
|
|
@ -426,6 +426,7 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly)
|
||||||
mOrderedAttributeTypeDef = NULL;
|
mOrderedAttributeTypeDef = NULL;
|
||||||
mPointerTTypeDef = NULL;
|
mPointerTTypeDef = NULL;
|
||||||
mPointerTypeDef = NULL;
|
mPointerTypeDef = NULL;
|
||||||
|
mReflectTypeIdTypeDef = NULL;
|
||||||
mReflectArrayType = NULL;
|
mReflectArrayType = NULL;
|
||||||
mReflectFieldDataDef = NULL;
|
mReflectFieldDataDef = NULL;
|
||||||
mReflectFieldSplatDataDef = NULL;
|
mReflectFieldSplatDataDef = NULL;
|
||||||
|
@ -6650,6 +6651,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
|
||||||
mOrderedAttributeTypeDef = _GetRequiredType("System.OrderedAttribute");
|
mOrderedAttributeTypeDef = _GetRequiredType("System.OrderedAttribute");
|
||||||
mPointerTTypeDef = _GetRequiredType("System.Pointer", 1);
|
mPointerTTypeDef = _GetRequiredType("System.Pointer", 1);
|
||||||
mPointerTypeDef = _GetRequiredType("System.Pointer", 0);
|
mPointerTypeDef = _GetRequiredType("System.Pointer", 0);
|
||||||
|
mReflectTypeIdTypeDef = _GetRequiredType("System.Reflection.TypeId");
|
||||||
mReflectArrayType = _GetRequiredType("System.Reflection.ArrayType");
|
mReflectArrayType = _GetRequiredType("System.Reflection.ArrayType");
|
||||||
mReflectFieldDataDef = _GetRequiredType("System.Reflection.TypeInstance.FieldData");
|
mReflectFieldDataDef = _GetRequiredType("System.Reflection.TypeInstance.FieldData");
|
||||||
mReflectFieldSplatDataDef = _GetRequiredType("System.Reflection.TypeInstance.FieldSplatData");
|
mReflectFieldSplatDataDef = _GetRequiredType("System.Reflection.TypeInstance.FieldSplatData");
|
||||||
|
|
|
@ -377,6 +377,7 @@ public:
|
||||||
|
|
||||||
BfTypeDef* mPointerTTypeDef;
|
BfTypeDef* mPointerTTypeDef;
|
||||||
BfTypeDef* mPointerTypeDef;
|
BfTypeDef* mPointerTypeDef;
|
||||||
|
BfTypeDef* mReflectTypeIdTypeDef;
|
||||||
BfTypeDef* mReflectArrayType;
|
BfTypeDef* mReflectArrayType;
|
||||||
BfTypeDef* mReflectFieldDataDef;
|
BfTypeDef* mReflectFieldDataDef;
|
||||||
BfTypeDef* mReflectFieldSplatDataDef;
|
BfTypeDef* mReflectFieldSplatDataDef;
|
||||||
|
|
|
@ -3727,7 +3727,8 @@ BfTypedValue BfExprEvaluator::LookupIdentifier(BfAstNode* refNode, const StringI
|
||||||
wantName = findName;
|
wantName = findName;
|
||||||
while (wantName.StartsWith("@"))
|
while (wantName.StartsWith("@"))
|
||||||
{
|
{
|
||||||
varSkipCount++;
|
if (wantName != "@return")
|
||||||
|
varSkipCount++;
|
||||||
wantName.Remove(0);
|
wantName.Remove(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9942,7 +9943,10 @@ bool BfExprEvaluator::LookupTypeProp(BfTypeOfExpression* typeOfExpr, BfIdentifie
|
||||||
else if (memberName == "IsSizedArray")
|
else if (memberName == "IsSizedArray")
|
||||||
_BoolResult(type->IsSizedArray());
|
_BoolResult(type->IsSizedArray());
|
||||||
else if (memberName == "TypeId")
|
else if (memberName == "TypeId")
|
||||||
|
{
|
||||||
_Int32Result(type->mTypeId);
|
_Int32Result(type->mTypeId);
|
||||||
|
mResult.mType = mModule->ResolveTypeDef(mModule->mCompiler->mReflectTypeIdTypeDef);
|
||||||
|
}
|
||||||
else if (memberName == "GenericParamCount")
|
else if (memberName == "GenericParamCount")
|
||||||
{
|
{
|
||||||
auto genericTypeInst = type->ToGenericTypeInstance();
|
auto genericTypeInst = type->ToGenericTypeInstance();
|
||||||
|
|
|
@ -2236,6 +2236,28 @@ void BfModule::LocalVariableDone(BfLocalVariable* localVar, bool isMethodExit)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BfModule::CreateRetValLocal()
|
||||||
|
{
|
||||||
|
if (mCurMethodState->mRetVal)
|
||||||
|
{
|
||||||
|
BfLocalVariable* localDef = new BfLocalVariable();
|
||||||
|
localDef->mName = "return";
|
||||||
|
localDef->mResolvedType = mCurMethodState->mRetVal.mType;
|
||||||
|
localDef->mAddr = mCurMethodState->mRetVal.mValue;
|
||||||
|
localDef->mAssignedKind = BfLocalVarAssignKind_Unconditional;
|
||||||
|
AddLocalVariableDef(localDef);
|
||||||
|
}
|
||||||
|
else if (mCurMethodState->mRetValAddr)
|
||||||
|
{
|
||||||
|
BfLocalVariable* localDef = new BfLocalVariable();
|
||||||
|
localDef->mName = "return";
|
||||||
|
localDef->mResolvedType = CreateRefType(mCurMethodInstance->mReturnType);
|
||||||
|
localDef->mAddr = mCurMethodState->mRetValAddr;
|
||||||
|
localDef->mAssignedKind = BfLocalVarAssignKind_Unconditional;
|
||||||
|
AddLocalVariableDef(localDef);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void BfModule::MarkDynStack(BfScopeData* scopeData)
|
void BfModule::MarkDynStack(BfScopeData* scopeData)
|
||||||
{
|
{
|
||||||
auto checkScope = mCurMethodState->mCurScope;
|
auto checkScope = mCurMethodState->mCurScope;
|
||||||
|
@ -5316,8 +5338,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
||||||
else
|
else
|
||||||
typeDataVar = mBfIRBuilder->CreateConstNull(mBfIRBuilder->MapType(mContext->mBfTypeType));
|
typeDataVar = mBfIRBuilder->CreateConstNull(mBfIRBuilder->MapType(mContext->mBfTypeType));
|
||||||
|
|
||||||
mTypeDataRefs[typeInstance] = typeDataVar;
|
mTypeDataRefs[type] = typeDataVar;
|
||||||
|
|
||||||
return typeDataVar;
|
return typeDataVar;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13972,7 +13993,7 @@ void BfModule::CreateDIRetVal()
|
||||||
}
|
}
|
||||||
|
|
||||||
mCurMethodState->mDIRetVal = mBfIRBuilder->DbgCreateAutoVariable(mCurMethodState->mCurScope->mDIScope,
|
mCurMethodState->mDIRetVal = mBfIRBuilder->DbgCreateAutoVariable(mCurMethodState->mCurScope->mDIScope,
|
||||||
"__return", mCurFilePosition.mFileInstance->mDIFile, mCurFilePosition.mCurLine, mBfIRBuilder->DbgGetType(dbgType));
|
"@return", mCurFilePosition.mFileInstance->mDIFile, mCurFilePosition.mCurLine, mBfIRBuilder->DbgGetType(dbgType));
|
||||||
auto declareCall = mBfIRBuilder->DbgInsertDeclare(dbgValue, mCurMethodState->mDIRetVal);
|
auto declareCall = mBfIRBuilder->DbgInsertDeclare(dbgValue, mCurMethodState->mDIRetVal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14292,6 +14313,9 @@ void BfModule::EmitDeferredScopeCalls(bool useSrcPositions, BfScopeData* scopeDa
|
||||||
{
|
{
|
||||||
if (deferredCallEntry->mDeferredBlock != NULL)
|
if (deferredCallEntry->mDeferredBlock != NULL)
|
||||||
{
|
{
|
||||||
|
if (checkScope == &mCurMethodState->mHeadScope)
|
||||||
|
CreateRetValLocal();
|
||||||
|
|
||||||
SetAndRestoreValue<BfAstNode*> prevCustomAttribute(mCurMethodState->mEmitRefNode, deferredCallEntry->mEmitRefNode);
|
SetAndRestoreValue<BfAstNode*> prevCustomAttribute(mCurMethodState->mEmitRefNode, deferredCallEntry->mEmitRefNode);
|
||||||
VisitEmbeddedStatement(deferredCallEntry->mDeferredBlock, NULL, BfEmbeddedStatementFlags_IsDeferredBlock);
|
VisitEmbeddedStatement(deferredCallEntry->mDeferredBlock, NULL, BfEmbeddedStatementFlags_IsDeferredBlock);
|
||||||
}
|
}
|
||||||
|
@ -14380,6 +14404,9 @@ void BfModule::EmitDeferredScopeCalls(bool useSrcPositions, BfScopeData* scopeDa
|
||||||
UpdateSrcPos(deferCloseNode);
|
UpdateSrcPos(deferCloseNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (checkScope == &mCurMethodState->mHeadScope)
|
||||||
|
CreateRetValLocal();
|
||||||
|
|
||||||
if (doneBlock)
|
if (doneBlock)
|
||||||
{
|
{
|
||||||
bool crossingMixin = mCurMethodState->mCurScope->mMixinDepth != checkScope->mMixinDepth;
|
bool crossingMixin = mCurMethodState->mCurScope->mMixinDepth != checkScope->mMixinDepth;
|
||||||
|
|
|
@ -1776,6 +1776,7 @@ public:
|
||||||
BfLocalVariable* AddLocalVariableDef(BfLocalVariable* localVarDef, bool addDebugInfo = false, bool doAliasValue = false, BfIRValue declareBefore = BfIRValue(), BfIRInitType initType = BfIRInitType_NotSet);
|
BfLocalVariable* AddLocalVariableDef(BfLocalVariable* localVarDef, bool addDebugInfo = false, bool doAliasValue = false, BfIRValue declareBefore = BfIRValue(), BfIRInitType initType = BfIRInitType_NotSet);
|
||||||
bool TryLocalVariableInit(BfLocalVariable* localVar);
|
bool TryLocalVariableInit(BfLocalVariable* localVar);
|
||||||
void LocalVariableDone(BfLocalVariable* localVar, bool isMethodExit);
|
void LocalVariableDone(BfLocalVariable* localVar, bool isMethodExit);
|
||||||
|
void CreateRetValLocal();
|
||||||
void CreateDIRetVal();
|
void CreateDIRetVal();
|
||||||
BfTypedValue CreateTuple(const Array<BfTypedValue>& values, const Array<String>& fieldNames);
|
BfTypedValue CreateTuple(const Array<BfTypedValue>& values, const Array<String>& fieldNames);
|
||||||
void CheckTupleVariableDeclaration(BfTupleExpression* tupleExpr, BfType* initType);
|
void CheckTupleVariableDeclaration(BfTupleExpression* tupleExpr, BfType* initType);
|
||||||
|
|
|
@ -9768,11 +9768,12 @@ void BfReducer::HandleBlock(BfBlock* block, bool allowEndingExpression)
|
||||||
flags = (CreateStmtFlags)(flags | CreateStmtFlags_AllowUnterminatedExpression);
|
flags = (CreateStmtFlags)(flags | CreateStmtFlags_AllowUnterminatedExpression);
|
||||||
|
|
||||||
auto statement = CreateStatement(node, flags);
|
auto statement = CreateStatement(node, flags);
|
||||||
if (statement == NULL)
|
if ((statement == NULL) && (mSource != NULL))
|
||||||
statement = mSource->CreateErrorNode(node);
|
statement = mSource->CreateErrorNode(node);
|
||||||
|
|
||||||
isDone = !mVisitorPos.MoveNext();
|
isDone = !mVisitorPos.MoveNext();
|
||||||
mVisitorPos.Write(statement);
|
if (statement != NULL)
|
||||||
|
mVisitorPos.Write(statement);
|
||||||
}
|
}
|
||||||
|
|
||||||
mVisitorPos.Trim();
|
mVisitorPos.Trim();
|
||||||
|
|
|
@ -2881,6 +2881,7 @@ addr_ce CeContext::GetReflectType(int typeId)
|
||||||
if (auto constant = BeValueDynCast<BeConstant>(beValue))
|
if (auto constant = BeValueDynCast<BeConstant>(beValue))
|
||||||
*addrPtr = GetConstantData(constant);
|
*addrPtr = GetConstantData(constant);
|
||||||
|
|
||||||
|
// We need to 'get' again because we might have resized
|
||||||
return *addrPtr;
|
return *addrPtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4104,8 +4105,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
||||||
int32 size = *(int32*)((uint8*)stackPtr + 4);
|
int32 size = *(int32*)((uint8*)stackPtr + 4);
|
||||||
CE_CHECKALLOC(size);
|
CE_CHECKALLOC(size);
|
||||||
uint8* ptr = CeMalloc(size);
|
uint8* ptr = CeMalloc(size);
|
||||||
addr_ce& result = *(addr_ce*)((uint8*)stackPtr + 0);
|
CeSetAddrVal(stackPtr + 0, ptr - memStart, ptrSize);
|
||||||
result = (addr_ce)(ptr - memStart);
|
|
||||||
handled = true;
|
handled = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -4185,7 +4185,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
||||||
|
|
||||||
auto reflectType = GetReflectType(typeId);
|
auto reflectType = GetReflectType(typeId);
|
||||||
_FixVariables();
|
_FixVariables();
|
||||||
*(addr_ce*)(stackPtr + 0) = reflectType;
|
CeSetAddrVal(stackPtr + 0, reflectType, ptrSize);
|
||||||
handled = true;
|
handled = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -4194,7 +4194,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
||||||
int32 typeId = *(int32*)((uint8*)stackPtr + ceModule->mSystem->mPtrSize);
|
int32 typeId = *(int32*)((uint8*)stackPtr + ceModule->mSystem->mPtrSize);
|
||||||
auto reflectType = GetReflectType(typeId);
|
auto reflectType = GetReflectType(typeId);
|
||||||
_FixVariables();
|
_FixVariables();
|
||||||
*(addr_ce*)(stackPtr + 0) = reflectType;
|
CeSetAddrVal(stackPtr + 0, reflectType, ptrSize);
|
||||||
handled = true;
|
handled = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -4209,7 +4209,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
||||||
}
|
}
|
||||||
auto reflectType = GetReflectType(typeName);
|
auto reflectType = GetReflectType(typeName);
|
||||||
_FixVariables();
|
_FixVariables();
|
||||||
*(addr_ce*)(stackPtr + 0) = reflectType;
|
CeSetAddrVal(stackPtr + 0, reflectType, ptrSize);
|
||||||
handled = true;
|
handled = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -4220,7 +4220,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
||||||
|
|
||||||
auto reflectType = GetReflectSpecializedType(typeAddr, typeSpan);
|
auto reflectType = GetReflectSpecializedType(typeAddr, typeSpan);
|
||||||
_FixVariables();
|
_FixVariables();
|
||||||
*(addr_ce*)(stackPtr + 0) = reflectType;
|
CeSetAddrVal(stackPtr + 0, reflectType, ptrSize);
|
||||||
handled = true;
|
handled = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -4348,10 +4348,11 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addr_ce stringAddr = GetString(methodInstance->GetParamName(paramIdx));
|
||||||
|
_FixVariables();
|
||||||
*(int32*)(stackPtr + 0) = methodInstance->GetParamType(paramIdx)->mTypeId;
|
*(int32*)(stackPtr + 0) = methodInstance->GetParamType(paramIdx)->mTypeId;
|
||||||
*(int16*)(stackPtr + 4) = 0; // Flags
|
*(int16*)(stackPtr + 4) = 0; // Flags
|
||||||
CeSetAddrVal(stackPtr + 4+2, GetString(methodInstance->GetParamName(paramIdx)), ptrSize);
|
CeSetAddrVal(stackPtr + 4+2, stringAddr, ptrSize);
|
||||||
_FixVariables();
|
|
||||||
handled = true;
|
handled = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,8 +48,20 @@ namespace Tests
|
||||||
String emit = scope $"LogAttribute.gLog.AppendF($\"Called {method}";
|
String emit = scope $"LogAttribute.gLog.AppendF($\"Called {method}";
|
||||||
for (var fieldIdx < method.ParamCount)
|
for (var fieldIdx < method.ParamCount)
|
||||||
emit.AppendF($" {{ {method.GetParamName(fieldIdx)} }}");
|
emit.AppendF($" {{ {method.GetParamName(fieldIdx)} }}");
|
||||||
emit.Append("\");");
|
emit.Append("\\n\");");
|
||||||
Compiler.EmitMethodEntry(method, emit);
|
Compiler.EmitMethodEntry(method, emit);
|
||||||
|
|
||||||
|
if (var genericType = method.ReturnType as SpecializedGenericType)
|
||||||
|
{
|
||||||
|
if ((genericType.UnspecializedType == typeof(Result<>)) || (genericType.UnspecializedType == typeof(Result<,>)))
|
||||||
|
{
|
||||||
|
Compiler.EmitMethodExit(method, """
|
||||||
|
if (@return case .Err)
|
||||||
|
LogAttribute.gLog.AppendF($"Error: {@return}");
|
||||||
|
""");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,10 +80,16 @@ namespace Tests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Log]
|
enum MethodAErr
|
||||||
public static void MethodA(int a, int b)
|
|
||||||
{
|
{
|
||||||
|
ErrorA,
|
||||||
|
ErrorB
|
||||||
|
}
|
||||||
|
|
||||||
|
[Log]
|
||||||
|
static Result<int, MethodAErr> MethodA(int a, int b)
|
||||||
|
{
|
||||||
|
return .Err(.ErrorB);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Type GetBiggerType(Type t)
|
static Type GetBiggerType(Type t)
|
||||||
|
@ -104,8 +122,9 @@ namespace Tests
|
||||||
Compiler.Mixin("int val = 99;");
|
Compiler.Mixin("int val = 99;");
|
||||||
Test.Assert(val == 99);
|
Test.Assert(val == 99);
|
||||||
|
|
||||||
MethodA(34, 45);
|
|
||||||
Debug.Assert(LogAttribute.gLog == "Called Tests.Comptime.MethodA(int a, int b) 34 45");
|
MethodA(34, 45).IgnoreError();
|
||||||
|
Debug.Assert(LogAttribute.gLog == "Called Tests.Comptime.MethodA(int a, int b) 34 45\nError: Err(ErrorB)");
|
||||||
|
|
||||||
var v0 = GetBigger((int8)123);
|
var v0 = GetBigger((int8)123);
|
||||||
Test.Assert(v0.GetType() == typeof(int16));
|
Test.Assert(v0.GetType() == typeof(int16));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue