mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 19:48:20 +02:00
Allow Compiler.Emit during lambda capture phase
This commit is contained in:
parent
1a93660416
commit
a30e539d29
8 changed files with 82 additions and 55 deletions
|
@ -1104,28 +1104,25 @@ namespace IDE
|
||||||
sourceViewPanel.RecordHistoryLocation();
|
sourceViewPanel.RecordHistoryLocation();
|
||||||
|
|
||||||
StringView loc = cmds[2];
|
StringView loc = cmds[2];
|
||||||
int32 charIdx = int32.Parse(loc).GetValueOrDefault();
|
|
||||||
if (charIdx < 0)
|
int line = -1;
|
||||||
return;
|
int lineChar = -1;
|
||||||
var (sourceViewPanel, tabButton) = ShowSourceFile(cmds[1], null, SourceShowType.Temp);
|
|
||||||
if (sourceViewPanel == null)
|
|
||||||
return;
|
|
||||||
var editWidgetContent = sourceViewPanel.mEditWidget.mEditWidgetContent;
|
|
||||||
|
|
||||||
int colonIdx = loc.IndexOf(':');
|
int colonIdx = loc.IndexOf(':');
|
||||||
if (colonIdx != -1)
|
if (colonIdx != -1)
|
||||||
{
|
{
|
||||||
int line = int.Parse(loc.Substring(0, colonIdx)).GetValueOrDefault();
|
line = int.Parse(loc.Substring(0, colonIdx)).GetValueOrDefault();
|
||||||
int column = int.Parse(loc.Substring(colonIdx + 1)).GetValueOrDefault();
|
lineChar = int.Parse(loc.Substring(colonIdx + 1)).GetValueOrDefault();
|
||||||
charIdx = (.)editWidgetContent.GetTextIdx(line, column);
|
|
||||||
}
|
}
|
||||||
if (charIdx < 0)
|
else
|
||||||
return;
|
{
|
||||||
|
int32 charIdx = int32.Parse(loc).GetValueOrDefault();
|
||||||
int line;
|
var fileEditData = GetEditData(cmds[1]);
|
||||||
int lineChar;
|
if (fileEditData == null)
|
||||||
editWidgetContent.GetLineCharAtIdx(charIdx, out line, out lineChar);
|
break;
|
||||||
sourceViewPanel.ShowFileLocation(charIdx, .Always);
|
fileEditData.mEditWidget.mEditWidgetContent.GetLineCharAtIdx(charIdx, out line, out lineChar);
|
||||||
|
}
|
||||||
|
ShowSourceFileLocation(cmds[1], -1, -1, line, lineChar, .Smart, true);
|
||||||
case "ShowCodeAddr":
|
case "ShowCodeAddr":
|
||||||
var sourceViewPanel = GetActiveSourceViewPanel(true);
|
var sourceViewPanel = GetActiveSourceViewPanel(true);
|
||||||
if (sourceViewPanel != null)
|
if (sourceViewPanel != null)
|
||||||
|
|
|
@ -5754,8 +5754,7 @@ namespace IDE.ui
|
||||||
{
|
{
|
||||||
if (mEmbeds.GetAndRemove(entry.mAnchorLine) case .Ok(let val))
|
if (mEmbeds.GetAndRemove(entry.mAnchorLine) case .Ok(let val))
|
||||||
{
|
{
|
||||||
if (val.value is CollapseSummary)
|
delete val.value;
|
||||||
delete val.value;
|
|
||||||
}
|
}
|
||||||
@entry.Remove();
|
@entry.Remove();
|
||||||
}
|
}
|
||||||
|
|
|
@ -5622,7 +5622,7 @@ namespace IDE.ui
|
||||||
{
|
{
|
||||||
for (var moreInfo in bestError.mMoreInfo)
|
for (var moreInfo in bestError.mMoreInfo)
|
||||||
{
|
{
|
||||||
if ((moreInfo.mSrcStart == -1) && (moreInfo.mSrcStart == -1) && (moreInfo.mLine != -1))
|
if (moreInfo.mLine != -1)
|
||||||
{
|
{
|
||||||
showMouseoverString.AppendF("\n@{}\t{}:{}\t{}", moreInfo.mFilePath, moreInfo.mLine, moreInfo.mColumn, moreInfo.mError);
|
showMouseoverString.AppendF("\n@{}\t{}:{}\t{}", moreInfo.mFilePath, moreInfo.mLine, moreInfo.mColumn, moreInfo.mError);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6036,7 +6036,12 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance*
|
||||||
|
|
||||||
if ((mModule->mCurMethodState != NULL) && (mModule->mCurMethodState->mClosureState != NULL) && (mModule->mCurMethodState->mClosureState->mCapturing))
|
if ((mModule->mCurMethodState != NULL) && (mModule->mCurMethodState->mClosureState != NULL) && (mModule->mCurMethodState->mClosureState->mCapturing))
|
||||||
{
|
{
|
||||||
return _GetDefaultReturnValue();
|
if ((methodInstance->mComptimeFlags & BfComptimeFlag_ConstEval) != 0)
|
||||||
|
{
|
||||||
|
// We need to perform call such as Compiler.Mixin and String.ConstF
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return _GetDefaultReturnValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
BF_ASSERT(!methodInstance->mDisallowCalling);
|
BF_ASSERT(!methodInstance->mDisallowCalling);
|
||||||
|
|
|
@ -8265,40 +8265,27 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS
|
||||||
(constExprValueType->mValue.mTypeCode != BfTypeCode_Let) &&
|
(constExprValueType->mValue.mTypeCode != BfTypeCode_Let) &&
|
||||||
(primType->mTypeDef->mTypeCode != BfTypeCode_Let))
|
(primType->mTypeDef->mTypeCode != BfTypeCode_Let))
|
||||||
{
|
{
|
||||||
|
bool doError = true;
|
||||||
|
|
||||||
if (BfIRConstHolder::IsInt(constExprValueType->mValue.mTypeCode))
|
if (BfIRConstHolder::IsInt(constExprValueType->mValue.mTypeCode))
|
||||||
{
|
{
|
||||||
if (BfIRConstHolder::IsInt(primType->mTypeDef->mTypeCode))
|
if (BfIRConstHolder::IsInt(primType->mTypeDef->mTypeCode))
|
||||||
{
|
{
|
||||||
if (!mCompiler->mSystem->DoesLiteralFit(primType->mTypeDef->mTypeCode, constExprValueType->mValue))
|
if (mCompiler->mSystem->DoesLiteralFit(primType->mTypeDef->mTypeCode, constExprValueType->mValue))
|
||||||
{
|
doError = false;
|
||||||
if ((!ignoreErrors) && (PreFail()))
|
|
||||||
*errorOut = Fail(StrFormat("Const generic argument '%s', declared with const '%lld', does not fit into const constraint '%s' for '%s'", genericParamInst->GetName().c_str(),
|
|
||||||
constExprValueType->mValue.mInt64, _TypeToString(genericParamInst->mTypeConstraint).c_str(), GenericParamSourceToString(genericParamSource).c_str()), checkArgTypeRef);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ((!ignoreErrors) && (PreFail()))
|
|
||||||
*errorOut = Fail(StrFormat("Const generic argument '%s', declared with integer const '%lld', is not compatible with const constraint '%s' for '%s'", genericParamInst->GetName().c_str(),
|
|
||||||
constExprValueType->mValue.mInt64, _TypeToString(genericParamInst->mTypeConstraint).c_str(), GenericParamSourceToString(genericParamSource).c_str()), checkArgTypeRef);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else if ((primType->mTypeDef->mTypeCode == BfTypeCode_Float) && ((constExprValueType->mValue.mTypeCode == BfTypeCode_Double)))
|
||||||
{
|
{
|
||||||
if (BfIRConstHolder::IsInt(primType->mTypeDef->mTypeCode))
|
doError = false;
|
||||||
{
|
}
|
||||||
char valStr[64];
|
|
||||||
if (constExprValueType->mValue.mTypeCode == BfTypeCode_Double)
|
if (doError)
|
||||||
ExactMinimalDoubleToStr(constExprValueType->mValue.mDouble, valStr);
|
{
|
||||||
else
|
if ((!ignoreErrors) && (PreFail()))
|
||||||
ExactMinimalFloatToStr(constExprValueType->mValue.mSingle, valStr);
|
*errorOut = Fail(StrFormat("Const generic argument '%s', declared with '%s', is not compatible with const constraint '%s' for '%s'", genericParamInst->GetName().c_str(),
|
||||||
if ((!ignoreErrors) && (PreFail()))
|
_TypeToString(constExprValueType).c_str(), _TypeToString(genericParamInst->mTypeConstraint).c_str(), GenericParamSourceToString(genericParamSource).c_str()), checkArgTypeRef);
|
||||||
*errorOut = Fail(StrFormat("Const generic argument '%s', declared with floating point const '%s', is not compatible with const constraint '%s' for '%s'", genericParamInst->GetName().c_str(),
|
return false;
|
||||||
valStr, _TypeToString(genericParamInst->mTypeConstraint).c_str(), GenericParamSourceToString(genericParamSource).c_str()), checkArgTypeRef);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18641,10 +18628,14 @@ void BfModule::ProcessMethod_SetupParams(BfMethodInstance* methodInstance, BfTyp
|
||||||
if (checkType->IsTypedPrimitive())
|
if (checkType->IsTypedPrimitive())
|
||||||
checkType = checkType->GetUnderlyingType();
|
checkType = checkType->GetUnderlyingType();
|
||||||
|
|
||||||
if (exprEvaluator.mResult.mType == checkType)
|
auto typedVal = exprEvaluator.mResult;
|
||||||
|
if ((typedVal) && (typedVal.mType != checkType))
|
||||||
|
typedVal = Cast(NULL, typedVal, checkType, (BfCastFlags)(BfCastFlags_Explicit | BfCastFlags_SilentFail));
|
||||||
|
|
||||||
|
if ((typedVal.mType == checkType) && (typedVal.mValue.IsConst()))
|
||||||
{
|
{
|
||||||
paramVar->mResolvedType = genericParamInst->mTypeConstraint;
|
paramVar->mResolvedType = genericParamInst->mTypeConstraint;
|
||||||
paramVar->mConstValue = exprEvaluator.mResult.mValue;
|
paramVar->mConstValue = typedVal.mValue;
|
||||||
BF_ASSERT(paramVar->mConstValue.IsConst());
|
BF_ASSERT(paramVar->mConstValue.IsConst());
|
||||||
paramVar->mIsConst = true;
|
paramVar->mIsConst = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2048,8 +2048,15 @@ BfCEParseContext BfModule::CEEmitParse(BfTypeInstance* typeInstance, BfTypeDef*
|
||||||
if (ceTypeInfo->mNext != NULL)
|
if (ceTypeInfo->mNext != NULL)
|
||||||
ceTypeInfo = ceTypeInfo->mNext;
|
ceTypeInfo = ceTypeInfo->mNext;
|
||||||
BfCeTypeEmitSource* ceEmitSource = NULL;
|
BfCeTypeEmitSource* ceEmitSource = NULL;
|
||||||
ceTypeInfo->mEmitSourceMap.TryAdd(emitSourceMapKey, NULL, &ceEmitSource);
|
if ((mCurMethodState != NULL) && (mCurMethodState->mClosureState != NULL) && (mCurMethodState->mClosureState->mCapturing))
|
||||||
ceEmitSource->mKind = emitSourceKind;
|
{
|
||||||
|
// Don't create emit sources when we're in a capture phase
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ceTypeInfo->mEmitSourceMap.TryAdd(emitSourceMapKey, NULL, &ceEmitSource);
|
||||||
|
ceEmitSource->mKind = emitSourceKind;
|
||||||
|
}
|
||||||
|
|
||||||
int emitSrcStart = 0;
|
int emitSrcStart = 0;
|
||||||
|
|
||||||
|
@ -2077,6 +2084,7 @@ BfCEParseContext BfModule::CEEmitParse(BfTypeInstance* typeInstance, BfTypeDef*
|
||||||
typeName += ":";
|
typeName += ":";
|
||||||
|
|
||||||
typeName += TypeToString(typeInstance, BfTypeNameFlags_None);
|
typeName += TypeToString(typeInstance, BfTypeNameFlags_None);
|
||||||
|
|
||||||
if ((mCompiler->mResolvePassData != NULL) && (!mCompiler->mResolvePassData->mEmitEmbedEntries.IsEmpty()))
|
if ((mCompiler->mResolvePassData != NULL) && (!mCompiler->mResolvePassData->mEmitEmbedEntries.IsEmpty()))
|
||||||
mCompiler->mResolvePassData->mEmitEmbedEntries.TryGetValue(typeName, &emitEmbedEntry);
|
mCompiler->mResolvePassData->mEmitEmbedEntries.TryGetValue(typeName, &emitEmbedEntry);
|
||||||
|
|
||||||
|
@ -2141,7 +2149,11 @@ BfCEParseContext BfModule::CEEmitParse(BfTypeInstance* typeInstance, BfTypeDef*
|
||||||
emitParser->mOrigSrcLength = emitParser->mSrcLength;
|
emitParser->mOrigSrcLength = emitParser->mSrcLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ceEmitSource->mSrcStart == -1)
|
if (ceEmitSource == NULL)
|
||||||
|
{
|
||||||
|
// Ignored
|
||||||
|
}
|
||||||
|
else if (ceEmitSource->mSrcStart == -1)
|
||||||
{
|
{
|
||||||
ceEmitSource->mSrcStart = emitSrcStart;
|
ceEmitSource->mSrcStart = emitSrcStart;
|
||||||
ceEmitSource->mSrcEnd = emitParser->mSrcLength;
|
ceEmitSource->mSrcEnd = emitParser->mSrcLength;
|
||||||
|
@ -2441,6 +2453,9 @@ void BfModule::HandleCEAttributes(CeEmitContext* ceEmitContext, BfTypeInstance*
|
||||||
|
|
||||||
void BfModule::CEMixin(BfAstNode* refNode, const StringImpl& code)
|
void BfModule::CEMixin(BfAstNode* refNode, const StringImpl& code)
|
||||||
{
|
{
|
||||||
|
if (code.IsEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
auto activeTypeDef = mCurMethodInstance->mMethodDef->mDeclaringType;
|
auto activeTypeDef = mCurMethodInstance->mMethodDef->mDeclaringType;
|
||||||
//auto emitParser = activeTypeDef->mEmitParser;
|
//auto emitParser = activeTypeDef->mEmitParser;
|
||||||
|
|
||||||
|
@ -2505,7 +2520,14 @@ void BfModule::CEMixin(BfAstNode* refNode, const StringImpl& code)
|
||||||
UpdateSrcPos(emitParser->mRootNode);
|
UpdateSrcPos(emitParser->mRootNode);
|
||||||
|
|
||||||
SetIllegalSrcPos();
|
SetIllegalSrcPos();
|
||||||
|
|
||||||
|
if (emitParser->mSourceClassifier != NULL)
|
||||||
|
{
|
||||||
|
emitParser->mSourceClassifier->VisitChild(emitParser->mRootNode);
|
||||||
|
emitParser->mSourceClassifier->VisitChild(emitParser->mSidechannelRootNode);
|
||||||
|
emitParser->mSourceClassifier->VisitChild(emitParser->mErrorRootNode);
|
||||||
|
}
|
||||||
|
|
||||||
Visit(emitParser->mRootNode);
|
Visit(emitParser->mRootNode);
|
||||||
|
|
||||||
mBfIRBuilder->RestoreDebugLocation();
|
mBfIRBuilder->RestoreDebugLocation();
|
||||||
|
|
|
@ -3490,7 +3490,8 @@ void BfModule::VisitCodeBlock(BfBlock* block)
|
||||||
exprEvaluator->VisitChild(expr);
|
exprEvaluator->VisitChild(expr);
|
||||||
exprEvaluator->FinishExpressionResult();
|
exprEvaluator->FinishExpressionResult();
|
||||||
|
|
||||||
if ((exprEvaluator->mResult) && (!exprEvaluator->mResult.mType->IsValuelessType()) && (!exprEvaluator->mResult.IsAddr()) && (!exprEvaluator->mResult.mValue.IsFake()))
|
if ((exprEvaluator->mResult) && (!exprEvaluator->mResult.mType->IsValuelessType()) && (!exprEvaluator->mResult.mValue.IsConst()) &&
|
||||||
|
(!exprEvaluator->mResult.IsAddr()) && (!exprEvaluator->mResult.mValue.IsFake()))
|
||||||
{
|
{
|
||||||
if ((mCurMethodState->mCurScope != NULL) && (mCurMethodState->mCurScope->mPrevScope != NULL))
|
if ((mCurMethodState->mCurScope != NULL) && (mCurMethodState->mCurScope->mPrevScope != NULL))
|
||||||
{
|
{
|
||||||
|
|
|
@ -133,6 +133,16 @@ namespace Tests
|
||||||
return param1.Length;
|
return param1.Length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void TestEmitMixin<T>(T c, int a, String outStr)
|
||||||
|
where T : const int
|
||||||
|
{
|
||||||
|
delegate void() d = scope () =>
|
||||||
|
{
|
||||||
|
Compiler.Mixin(scope $"outStr.AppendF(\"{{}}{{}}\", {c}, a);");
|
||||||
|
};
|
||||||
|
d();
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public static void TestBasics()
|
public static void TestBasics()
|
||||||
{
|
{
|
||||||
|
@ -149,6 +159,8 @@ namespace Tests
|
||||||
Test.Assert(BigNum<const 3>.N == 3);
|
Test.Assert(BigNum<const 3>.N == 3);
|
||||||
Test.Assert(Test("test", 1, 2, 3) == 10);
|
Test.Assert(Test("test", 1, 2, 3) == 10);
|
||||||
Test.Assert(StrTest("ABCDE") == 5);
|
Test.Assert(StrTest("ABCDE") == 5);
|
||||||
|
|
||||||
|
Test.Assert(TestEmitMixin(123, 456, .. scope .()) == "123456");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue