mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 11:38:21 +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
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -583,7 +583,7 @@ namespace System
|
|||
{
|
||||
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)
|
||||
|
@ -596,7 +596,7 @@ namespace System
|
|||
if (Compiler.IsComptime)
|
||||
{
|
||||
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 .Err;
|
||||
}
|
||||
|
|
|
@ -426,6 +426,7 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly)
|
|||
mOrderedAttributeTypeDef = NULL;
|
||||
mPointerTTypeDef = NULL;
|
||||
mPointerTypeDef = NULL;
|
||||
mReflectTypeIdTypeDef = NULL;
|
||||
mReflectArrayType = NULL;
|
||||
mReflectFieldDataDef = NULL;
|
||||
mReflectFieldSplatDataDef = NULL;
|
||||
|
@ -6650,6 +6651,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
|
|||
mOrderedAttributeTypeDef = _GetRequiredType("System.OrderedAttribute");
|
||||
mPointerTTypeDef = _GetRequiredType("System.Pointer", 1);
|
||||
mPointerTypeDef = _GetRequiredType("System.Pointer", 0);
|
||||
mReflectTypeIdTypeDef = _GetRequiredType("System.Reflection.TypeId");
|
||||
mReflectArrayType = _GetRequiredType("System.Reflection.ArrayType");
|
||||
mReflectFieldDataDef = _GetRequiredType("System.Reflection.TypeInstance.FieldData");
|
||||
mReflectFieldSplatDataDef = _GetRequiredType("System.Reflection.TypeInstance.FieldSplatData");
|
||||
|
|
|
@ -377,6 +377,7 @@ public:
|
|||
|
||||
BfTypeDef* mPointerTTypeDef;
|
||||
BfTypeDef* mPointerTypeDef;
|
||||
BfTypeDef* mReflectTypeIdTypeDef;
|
||||
BfTypeDef* mReflectArrayType;
|
||||
BfTypeDef* mReflectFieldDataDef;
|
||||
BfTypeDef* mReflectFieldSplatDataDef;
|
||||
|
|
|
@ -3727,6 +3727,7 @@ BfTypedValue BfExprEvaluator::LookupIdentifier(BfAstNode* refNode, const StringI
|
|||
wantName = findName;
|
||||
while (wantName.StartsWith("@"))
|
||||
{
|
||||
if (wantName != "@return")
|
||||
varSkipCount++;
|
||||
wantName.Remove(0);
|
||||
}
|
||||
|
@ -9942,7 +9943,10 @@ bool BfExprEvaluator::LookupTypeProp(BfTypeOfExpression* typeOfExpr, BfIdentifie
|
|||
else if (memberName == "IsSizedArray")
|
||||
_BoolResult(type->IsSizedArray());
|
||||
else if (memberName == "TypeId")
|
||||
{
|
||||
_Int32Result(type->mTypeId);
|
||||
mResult.mType = mModule->ResolveTypeDef(mModule->mCompiler->mReflectTypeIdTypeDef);
|
||||
}
|
||||
else if (memberName == "GenericParamCount")
|
||||
{
|
||||
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)
|
||||
{
|
||||
auto checkScope = mCurMethodState->mCurScope;
|
||||
|
@ -5316,8 +5338,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
|||
else
|
||||
typeDataVar = mBfIRBuilder->CreateConstNull(mBfIRBuilder->MapType(mContext->mBfTypeType));
|
||||
|
||||
mTypeDataRefs[typeInstance] = typeDataVar;
|
||||
|
||||
mTypeDataRefs[type] = typeDataVar;
|
||||
return typeDataVar;
|
||||
}
|
||||
|
||||
|
@ -13972,7 +13993,7 @@ void BfModule::CreateDIRetVal()
|
|||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -14292,6 +14313,9 @@ void BfModule::EmitDeferredScopeCalls(bool useSrcPositions, BfScopeData* scopeDa
|
|||
{
|
||||
if (deferredCallEntry->mDeferredBlock != NULL)
|
||||
{
|
||||
if (checkScope == &mCurMethodState->mHeadScope)
|
||||
CreateRetValLocal();
|
||||
|
||||
SetAndRestoreValue<BfAstNode*> prevCustomAttribute(mCurMethodState->mEmitRefNode, deferredCallEntry->mEmitRefNode);
|
||||
VisitEmbeddedStatement(deferredCallEntry->mDeferredBlock, NULL, BfEmbeddedStatementFlags_IsDeferredBlock);
|
||||
}
|
||||
|
@ -14380,6 +14404,9 @@ void BfModule::EmitDeferredScopeCalls(bool useSrcPositions, BfScopeData* scopeDa
|
|||
UpdateSrcPos(deferCloseNode);
|
||||
}
|
||||
|
||||
if (checkScope == &mCurMethodState->mHeadScope)
|
||||
CreateRetValLocal();
|
||||
|
||||
if (doneBlock)
|
||||
{
|
||||
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);
|
||||
bool TryLocalVariableInit(BfLocalVariable* localVar);
|
||||
void LocalVariableDone(BfLocalVariable* localVar, bool isMethodExit);
|
||||
void CreateRetValLocal();
|
||||
void CreateDIRetVal();
|
||||
BfTypedValue CreateTuple(const Array<BfTypedValue>& values, const Array<String>& fieldNames);
|
||||
void CheckTupleVariableDeclaration(BfTupleExpression* tupleExpr, BfType* initType);
|
||||
|
|
|
@ -9768,10 +9768,11 @@ void BfReducer::HandleBlock(BfBlock* block, bool allowEndingExpression)
|
|||
flags = (CreateStmtFlags)(flags | CreateStmtFlags_AllowUnterminatedExpression);
|
||||
|
||||
auto statement = CreateStatement(node, flags);
|
||||
if (statement == NULL)
|
||||
if ((statement == NULL) && (mSource != NULL))
|
||||
statement = mSource->CreateErrorNode(node);
|
||||
|
||||
isDone = !mVisitorPos.MoveNext();
|
||||
if (statement != NULL)
|
||||
mVisitorPos.Write(statement);
|
||||
}
|
||||
|
||||
|
|
|
@ -2881,6 +2881,7 @@ addr_ce CeContext::GetReflectType(int typeId)
|
|||
if (auto constant = BeValueDynCast<BeConstant>(beValue))
|
||||
*addrPtr = GetConstantData(constant);
|
||||
|
||||
// We need to 'get' again because we might have resized
|
||||
return *addrPtr;
|
||||
}
|
||||
|
||||
|
@ -4104,8 +4105,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
|||
int32 size = *(int32*)((uint8*)stackPtr + 4);
|
||||
CE_CHECKALLOC(size);
|
||||
uint8* ptr = CeMalloc(size);
|
||||
addr_ce& result = *(addr_ce*)((uint8*)stackPtr + 0);
|
||||
result = (addr_ce)(ptr - memStart);
|
||||
CeSetAddrVal(stackPtr + 0, ptr - memStart, ptrSize);
|
||||
handled = true;
|
||||
return true;
|
||||
}
|
||||
|
@ -4185,7 +4185,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
|||
|
||||
auto reflectType = GetReflectType(typeId);
|
||||
_FixVariables();
|
||||
*(addr_ce*)(stackPtr + 0) = reflectType;
|
||||
CeSetAddrVal(stackPtr + 0, reflectType, ptrSize);
|
||||
handled = true;
|
||||
return true;
|
||||
}
|
||||
|
@ -4194,7 +4194,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
|||
int32 typeId = *(int32*)((uint8*)stackPtr + ceModule->mSystem->mPtrSize);
|
||||
auto reflectType = GetReflectType(typeId);
|
||||
_FixVariables();
|
||||
*(addr_ce*)(stackPtr + 0) = reflectType;
|
||||
CeSetAddrVal(stackPtr + 0, reflectType, ptrSize);
|
||||
handled = true;
|
||||
return true;
|
||||
}
|
||||
|
@ -4209,7 +4209,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
|||
}
|
||||
auto reflectType = GetReflectType(typeName);
|
||||
_FixVariables();
|
||||
*(addr_ce*)(stackPtr + 0) = reflectType;
|
||||
CeSetAddrVal(stackPtr + 0, reflectType, ptrSize);
|
||||
handled = true;
|
||||
return true;
|
||||
}
|
||||
|
@ -4220,7 +4220,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
|||
|
||||
auto reflectType = GetReflectSpecializedType(typeAddr, typeSpan);
|
||||
_FixVariables();
|
||||
*(addr_ce*)(stackPtr + 0) = reflectType;
|
||||
CeSetAddrVal(stackPtr + 0, reflectType, ptrSize);
|
||||
handled = true;
|
||||
return true;
|
||||
}
|
||||
|
@ -4348,10 +4348,11 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
|||
return false;
|
||||
}
|
||||
|
||||
addr_ce stringAddr = GetString(methodInstance->GetParamName(paramIdx));
|
||||
_FixVariables();
|
||||
*(int32*)(stackPtr + 0) = methodInstance->GetParamType(paramIdx)->mTypeId;
|
||||
*(int16*)(stackPtr + 4) = 0; // Flags
|
||||
CeSetAddrVal(stackPtr + 4+2, GetString(methodInstance->GetParamName(paramIdx)), ptrSize);
|
||||
_FixVariables();
|
||||
CeSetAddrVal(stackPtr + 4+2, stringAddr, ptrSize);
|
||||
handled = true;
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -48,8 +48,20 @@ namespace Tests
|
|||
String emit = scope $"LogAttribute.gLog.AppendF($\"Called {method}";
|
||||
for (var fieldIdx < method.ParamCount)
|
||||
emit.AppendF($" {{ {method.GetParamName(fieldIdx)} }}");
|
||||
emit.Append("\");");
|
||||
emit.Append("\\n\");");
|
||||
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]
|
||||
public static void MethodA(int a, int b)
|
||||
enum MethodAErr
|
||||
{
|
||||
ErrorA,
|
||||
ErrorB
|
||||
}
|
||||
|
||||
[Log]
|
||||
static Result<int, MethodAErr> MethodA(int a, int b)
|
||||
{
|
||||
return .Err(.ErrorB);
|
||||
}
|
||||
|
||||
static Type GetBiggerType(Type t)
|
||||
|
@ -104,8 +122,9 @@ namespace Tests
|
|||
Compiler.Mixin("int 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);
|
||||
Test.Assert(v0.GetType() == typeof(int16));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue