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

Fixed string interpolation scoping, {{ }} escaping

This commit is contained in:
Brian Fiete 2021-01-04 06:33:39 -08:00
parent f9b9b15214
commit 2ac2fe70fb
7 changed files with 67 additions and 31 deletions

View file

@ -651,6 +651,11 @@ void BfStructuralVisitor::Visit(BfBlock* block)
Visit(block->ToBase()); Visit(block->ToBase());
} }
void BfStructuralVisitor::Visit(BfUnscopedBlock* block)
{
Visit(block->ToBase());
}
void BfStructuralVisitor::Visit(BfBlockExtension* block) void BfStructuralVisitor::Visit(BfBlockExtension* block)
{ {
BF_ASSERT("Shouldn't see this block, BfBlock::Iterator not being used?"); BF_ASSERT("Shouldn't see this block, BfBlock::Iterator not being used?");

View file

@ -266,6 +266,7 @@ class BfAttributedStatement;
class BfLiteralExpression; class BfLiteralExpression;
class BfStringInterpolationExpression; class BfStringInterpolationExpression;
class BfBlock; class BfBlock;
class BfUnscopedBlock;
class BfBlockExtension; class BfBlockExtension;
class BfRootNode; class BfRootNode;
class BfErrorNode; class BfErrorNode;
@ -545,6 +546,7 @@ public:
virtual void Visit(BfUsingModDirective* usingDirective); virtual void Visit(BfUsingModDirective* usingDirective);
virtual void Visit(BfNamespaceDeclaration* namespaceDeclaration); virtual void Visit(BfNamespaceDeclaration* namespaceDeclaration);
virtual void Visit(BfBlock* block); virtual void Visit(BfBlock* block);
virtual void Visit(BfUnscopedBlock* block);
virtual void Visit(BfBlockExtension* block); virtual void Visit(BfBlockExtension* block);
virtual void Visit(BfRootNode* rootNode); virtual void Visit(BfRootNode* rootNode);
virtual void Visit(BfInlineAsmStatement* asmStmt); virtual void Visit(BfInlineAsmStatement* asmStmt);
@ -1721,6 +1723,12 @@ public:
} }
}; BF_AST_DECL(BfBlock, BfExpression); }; BF_AST_DECL(BfBlock, BfExpression);
class BfUnscopedBlock : public BfBlock
{
public:
BF_AST_TYPE(BfUnscopedBlock, BfBlock);
}; BF_AST_DECL(BfUnscopedBlock, BfBlock);
class BfTypedValueExpression : public BfExpression class BfTypedValueExpression : public BfExpression
{ {
public: public:

View file

@ -2856,7 +2856,7 @@ void BfExprEvaluator::Visit(BfBlock* blockExpr)
if (!lastExpr->IsMissingSemicolon()) if (!lastExpr->IsMissingSemicolon())
mModule->Fail("Expression blocks must end in an expression which is missing its terminating semicolon", lastExpr->mTrailingSemicolon); mModule->Fail("Expression blocks must end in an expression which is missing its terminating semicolon", lastExpr->mTrailingSemicolon);
} }
else if (auto lastExpr = BfNodeDynCast<BfExpression>(blockExpr->mChildArr.GetLast())) else if (blockExpr->mChildArr.GetLast()->IsExpression())
{ {
// Expression // Expression
} }
@ -2865,7 +2865,7 @@ void BfExprEvaluator::Visit(BfBlock* blockExpr)
mModule->Fail("Expression blocks must end with an expression", blockExpr); mModule->Fail("Expression blocks must end with an expression", blockExpr);
} }
mModule->VisitEmbeddedStatement(blockExpr, this); mModule->VisitEmbeddedStatement(blockExpr, this, BfNodeIsA<BfUnscopedBlock>(blockExpr) ? BfEmbeddedStatementFlags_Unscoped : BfEmbeddedStatementFlags_None);
} }
bool BfExprEvaluator::CheckVariableDeclaration(BfAstNode* checkNode, bool requireSimpleIfExpr, bool exprMustBeTrue, bool silentFail) bool BfExprEvaluator::CheckVariableDeclaration(BfAstNode* checkNode, bool requireSimpleIfExpr, bool exprMustBeTrue, bool silentFail)

View file

@ -121,7 +121,8 @@ enum BfEmbeddedStatementFlags
{ {
BfEmbeddedStatementFlags_None = 0, BfEmbeddedStatementFlags_None = 0,
BfEmbeddedStatementFlags_IsConditional = 1, BfEmbeddedStatementFlags_IsConditional = 1,
BfEmbeddedStatementFlags_IsDeferredBlock = 2 BfEmbeddedStatementFlags_IsDeferredBlock = 2,
BfEmbeddedStatementFlags_Unscoped = 4
}; };
enum BfLocalVarAssignKind enum BfLocalVarAssignKind
@ -1653,6 +1654,7 @@ public:
virtual void Visit(BfForEachStatement* forEachStmt) override; virtual void Visit(BfForEachStatement* forEachStmt) override;
virtual void Visit(BfDeferStatement* deferStmt) override; virtual void Visit(BfDeferStatement* deferStmt) override;
virtual void Visit(BfBlock* block) override; virtual void Visit(BfBlock* block) override;
virtual void Visit(BfUnscopedBlock* block) override;
virtual void Visit(BfLabeledBlock* labeledBlock) override; virtual void Visit(BfLabeledBlock* labeledBlock) override;
virtual void Visit(BfRootNode* rootNode) override; virtual void Visit(BfRootNode* rootNode) override;
virtual void Visit(BfInlineAsmStatement* asmStmt) override; virtual void Visit(BfInlineAsmStatement* asmStmt) override;

View file

@ -1707,7 +1707,7 @@ void BfParser::NextToken(int endIdx, bool outerIsInterpolate)
case '"': case '"':
case '\'': case '\'':
{ {
SizedArray<BfBlock*, 4> interpolateExpressions; SizedArray<BfUnscopedBlock*, 4> interpolateExpressions;
String lineHeader; String lineHeader;
String strLiteral; String strLiteral;
@ -2013,31 +2013,44 @@ void BfParser::NextToken(int endIdx, bool outerIsInterpolate)
{ {
if (c == '{') if (c == '{')
{ {
BfBlock* newBlock = mAlloc->Alloc<BfBlock>(); if (mSrc[mSrcIdx] == '{')
mTokenStart = mSrcIdx - 1;
mTriviaStart = mTokenStart;
mTokenEnd = mTokenStart + 1;
mToken = BfToken_LBrace;
newBlock->mOpenBrace = (BfTokenNode*)CreateNode();
newBlock->Init(this);
ParseBlock(newBlock, 1, true);
if (mToken == BfToken_RBrace)
{ {
newBlock->mCloseBrace = (BfTokenNode*)CreateNode(); strLiteral += '{';
newBlock->SetSrcEnd(mSrcIdx); mSrcIdx++;
strLiteral += "}";
} }
else if ((mSyntaxToken == BfSyntaxToken_EOF) || (mSyntaxToken == BfSyntaxToken_StringQuote)) else
{ {
mSrcIdx--; BfUnscopedBlock* newBlock = mAlloc->Alloc<BfUnscopedBlock>();
mPassInstance->FailAfterAt("Expected '}'", mSourceData, newBlock->GetSrcEnd() - 1); mTokenStart = mSrcIdx - 1;
} mTriviaStart = mTokenStart;
mInAsmBlock = false; mTokenEnd = mTokenStart + 1;
interpolateExpressions.Add(newBlock); mToken = BfToken_LBrace;
newBlock->mOpenBrace = (BfTokenNode*)CreateNode();
newBlock->Init(this);
ParseBlock(newBlock, 1, true);
if (mToken == BfToken_RBrace)
{
newBlock->mCloseBrace = (BfTokenNode*)CreateNode();
newBlock->SetSrcEnd(mSrcIdx);
strLiteral += "}";
}
else if ((mSyntaxToken == BfSyntaxToken_EOF) || (mSyntaxToken == BfSyntaxToken_StringQuote))
{
mSrcIdx--;
mPassInstance->FailAfterAt("Expected '}'", mSourceData, newBlock->GetSrcEnd() - 1);
}
mInAsmBlock = false;
interpolateExpressions.Add(newBlock);
}
} }
else if (c == '}') else if (c == '}')
{ {
if (!interpolateExpressions.IsEmpty()) if (mSrc[mSrcIdx] == '}')
{
strLiteral += '}';
mSrcIdx++;
}
else if (!interpolateExpressions.IsEmpty())
{ {
auto block = interpolateExpressions.back(); auto block = interpolateExpressions.back();
if (block->mCloseBrace == NULL) if (block->mCloseBrace == NULL)

View file

@ -3090,15 +3090,23 @@ void BfModule::VisitEmbeddedStatement(BfAstNode* stmt, BfExprEvaluator* exprEval
if ((block != NULL) && (openBrace != NULL)) if ((block != NULL) && (openBrace != NULL))
UpdateSrcPos(openBrace); UpdateSrcPos(openBrace);
if (mCurMethodState != NULL)
if ((flags & BfEmbeddedStatementFlags_Unscoped) != 0)
{ {
bool isIgnore = mBfIRBuilder->mIgnoreWrites; SetAndRestoreValue<BfExprEvaluator*> prevExprEvaluator(mCurMethodState->mCurScope->mExprEvaluator, exprEvaluator);
VisitCodeBlock(block);
}
else if (mCurMethodState != NULL)
{
bool isIgnore = mBfIRBuilder->mIgnoreWrites;
mCurMethodState->mInHeadScope = false; mCurMethodState->mInHeadScope = false;
BfScopeData scopeData; BfScopeData scopeData;
if (IsTargetingBeefBackend()) if (IsTargetingBeefBackend())
scopeData.mValueScopeStart = mBfIRBuilder->CreateValueScopeStart(); scopeData.mValueScopeStart = mBfIRBuilder->CreateValueScopeStart();
mCurMethodState->AddScope(&scopeData); mCurMethodState->AddScope(&scopeData);
if (block != NULL) if (block != NULL)
{ {
@ -3391,7 +3399,7 @@ void BfModule::VisitCodeBlock(BfBlock* block)
} }
else else
{ {
FailAfter("Expression block cannot be used here. Consider adding semicolon if a statement was intended.", expr); FailAfter("Expression block cannot be used here. Consider adding semicolon if a statement was intended.", expr);
} }
} }
} }
@ -6843,6 +6851,11 @@ void BfModule::Visit(BfBlock* block)
VisitEmbeddedStatement(block); VisitEmbeddedStatement(block);
} }
void BfModule::Visit(BfUnscopedBlock* block)
{
VisitEmbeddedStatement(block, NULL, BfEmbeddedStatementFlags_Unscoped);
}
void BfModule::Visit(BfLabeledBlock* labeledBlock) void BfModule::Visit(BfLabeledBlock* labeledBlock)
{ {
VisitEmbeddedStatement(labeledBlock); VisitEmbeddedStatement(labeledBlock);

View file

@ -3012,11 +3012,6 @@ void BfSystem::FinishCompositePartial(BfTypeDef* compositeTypeDef)
// methodDef->mIsMutating = true; // methodDef->mIsMutating = true;
// } // }
if (compositeTypeDef->mName->ToString() == "Core")
{
NOP;
}
// Static ctor // Static ctor
if ((allHasMethods[0][1].mCtor == 0) && (allHasMethods[1][1].mCtor > 1)) if ((allHasMethods[0][1].mCtor == 0) && (allHasMethods[1][1].mCtor > 1))
{ {