1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-10 04:22:20 +02:00

Initializer expressions

This commit is contained in:
Brian Fiete 2020-06-18 06:12:14 -07:00
parent f6e31e4976
commit 229a5aa5c5
17 changed files with 305 additions and 18 deletions

View file

@ -196,6 +196,11 @@ void BfStructuralVisitor::Visit(BfSizedArrayCreateExpression* createExpr)
Visit(createExpr->ToBase()); Visit(createExpr->ToBase());
} }
void BfStructuralVisitor::Visit(BfInitializerExpression* initExpr)
{
Visit(initExpr->ToBase());
}
void BfStructuralVisitor::Visit(BfCollectionInitializerExpression* collectionInitExpr) void BfStructuralVisitor::Visit(BfCollectionInitializerExpression* collectionInitExpr)
{ {
Visit(collectionInitExpr->ToBase()); Visit(collectionInitExpr->ToBase());

View file

@ -354,6 +354,7 @@ class BfStrideOfExpression;
class BfDefaultExpression; class BfDefaultExpression;
class BfUninitializedExpression; class BfUninitializedExpression;
class BfConditionalExpression; class BfConditionalExpression;
class BfInitializerExpression;
class BfCollectionInitializerExpression; class BfCollectionInitializerExpression;
class BfSizedArrayCreateExpression; class BfSizedArrayCreateExpression;
class BfEmptyStatement; class BfEmptyStatement;
@ -435,6 +436,7 @@ public:
virtual void Visit(BfBaseExpression* baseExpr); virtual void Visit(BfBaseExpression* baseExpr);
virtual void Visit(BfMixinExpression* thisExpr); virtual void Visit(BfMixinExpression* thisExpr);
virtual void Visit(BfSizedArrayCreateExpression* createExpr); virtual void Visit(BfSizedArrayCreateExpression* createExpr);
virtual void Visit(BfInitializerExpression* collectionInitExpr);
virtual void Visit(BfCollectionInitializerExpression* collectionInitExpr); virtual void Visit(BfCollectionInitializerExpression* collectionInitExpr);
virtual void Visit(BfTypeReference* typeRef); virtual void Visit(BfTypeReference* typeRef);
virtual void Visit(BfNamedTypeReference* typeRef); virtual void Visit(BfNamedTypeReference* typeRef);
@ -2017,6 +2019,18 @@ public:
BfVariant mValue; BfVariant mValue;
}; BF_AST_DECL(BfLiteralExpression, BfExpression); }; BF_AST_DECL(BfLiteralExpression, BfExpression);
class BfInitializerExpression : public BfExpression
{
public:
BF_AST_TYPE(BfInitializerExpression, BfExpression);
BfExpression* mTarget;
BfTokenNode* mOpenBrace;
BfSizedArray<BfExpression*> mValues;
BfSizedArray<BfTokenNode*> mCommas;
BfTokenNode* mCloseBrace;
}; BF_AST_DECL(BfInitializerExpression, BfExpression);
class BfCollectionInitializerExpression : public BfExpression class BfCollectionInitializerExpression : public BfExpression
{ {
public: public:
@ -2606,7 +2620,7 @@ public:
BfTokenNode* mOpenToken; BfTokenNode* mOpenToken;
BfTokenNode* mCloseToken; BfTokenNode* mCloseToken;
BfSizedArray<BfExpression*> mArguments; BfSizedArray<BfExpression*> mArguments;
BfSizedArray<BfTokenNode*> mCommas; BfSizedArray<BfTokenNode*> mCommas;
}; BF_AST_DECL(BfObjectCreateExpression, BfMethodBoundExpression); }; BF_AST_DECL(BfObjectCreateExpression, BfMethodBoundExpression);
class BfBoxExpression : public BfExpression class BfBoxExpression : public BfExpression

View file

@ -1920,9 +1920,13 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString)
if ((needsDefaultCtor) && (!hasDefaultCtor)) if ((needsDefaultCtor) && (!hasDefaultCtor))
{ {
BfProtection prot = hasCtor ? BfProtection_Hidden : BfProtection_Public;
if (mCurTypeDef->mName == mSystem->mEmptyAtom)
prot = BfProtection_Hidden;
// Create default constructor. If it's the only constructor then make it public, // Create default constructor. If it's the only constructor then make it public,
// otherwise make it private so we can still internally use it but the user can't // otherwise make it private so we can still internally use it but the user can't
auto methodDef = AddMethod(mCurTypeDef, BfMethodType_Ctor, hasCtor ? BfProtection_Hidden : BfProtection_Public, false, ""); auto methodDef = AddMethod(mCurTypeDef, BfMethodType_Ctor, prot, false, "");
methodDef->mIsMutating = true; methodDef->mIsMutating = true;
} }

View file

@ -244,6 +244,19 @@ void BfElementVisitor::Visit(BfSizedArrayCreateExpression* createExpr)
VisitChild(createExpr->mInitializer); VisitChild(createExpr->mInitializer);
} }
void BfElementVisitor::Visit(BfInitializerExpression* initExpr)
{
Visit(initExpr->ToBase());
VisitChild(initExpr->mTarget);
VisitChild(initExpr->mOpenBrace);
for (auto& val : initExpr->mValues)
VisitChild(val);
for (auto& val : initExpr->mCommas)
VisitChild(val);
VisitChild(initExpr->mCloseBrace);
}
void BfElementVisitor::Visit(BfCollectionInitializerExpression* collectionInitExpr) void BfElementVisitor::Visit(BfCollectionInitializerExpression* collectionInitExpr)
{ {
Visit(collectionInitExpr->ToBase()); Visit(collectionInitExpr->ToBase());

View file

@ -43,6 +43,7 @@ public:
virtual void Visit(BfBaseExpression* baseExpr); virtual void Visit(BfBaseExpression* baseExpr);
virtual void Visit(BfMixinExpression* thisExpr); virtual void Visit(BfMixinExpression* thisExpr);
virtual void Visit(BfSizedArrayCreateExpression* createExpr); virtual void Visit(BfSizedArrayCreateExpression* createExpr);
virtual void Visit(BfInitializerExpression* initExpr);
virtual void Visit(BfCollectionInitializerExpression* collectionInitExpr); virtual void Visit(BfCollectionInitializerExpression* collectionInitExpr);
virtual void Visit(BfTypeReference* typeRef); virtual void Visit(BfTypeReference* typeRef);
virtual void Visit(BfNamedTypeReference* typeRef); virtual void Visit(BfNamedTypeReference* typeRef);

View file

@ -8433,6 +8433,111 @@ void BfExprEvaluator::Visit(BfSizedArrayCreateExpression* createExpr)
InitializedSizedArray(arrayType, createExpr->mInitializer->mOpenBrace, createExpr->mInitializer->mValues, createExpr->mInitializer->mCommas, createExpr->mInitializer->mCloseBrace); InitializedSizedArray(arrayType, createExpr->mInitializer->mOpenBrace, createExpr->mInitializer->mValues, createExpr->mInitializer->mCommas, createExpr->mInitializer->mCloseBrace);
} }
void BfExprEvaluator::Visit(BfInitializerExpression* initExpr)
{
VisitChild(initExpr->mTarget);
if (!mResult)
mResult = mModule->GetDefaultTypedValue(mModule->mContext->mBfObjectType);
BfTypedValue initValue = GetResult(true);
bool isFirstAdd = true;
BfFunctionBindResult addFunctionBindResult;
addFunctionBindResult.mWantsArgs = true;
for (auto elementExpr : initExpr->mValues)
{
bool wasValidInitKind = false;
if (auto assignExpr = BfNodeDynCast<BfAssignmentExpression>(elementExpr))
{
BfTypedValue fieldResult;
if (auto identifierNode = BfNodeDynCast<BfIdentifierNode>(assignExpr->mLeft))
{
StringT<128> findName;
identifierNode->ToString(findName);
fieldResult = LookupField(identifierNode, initValue, findName, BfLookupFieldFlag_IsImplicitThis);
if (fieldResult.mKind == BfTypedValueKind_TempAddr)
fieldResult.mKind = BfTypedValueKind_Addr;
wasValidInitKind = true;
if ((fieldResult) || (mPropDef != NULL))
{
mResult = fieldResult;
PerformAssignment(assignExpr, true, BfTypedValue());
mResult = BfTypedValue();
}
else
{
mModule->Fail(StrFormat("'%s' does not contain a definition for '%s'", mModule->TypeToString(initValue.mType).c_str(),
findName.c_str()), identifierNode);
}
}
}
else
{
auto autoComplete = GetAutoComplete();
if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(elementExpr)))
{
if (auto identiferNode = BfNodeDynCast<BfIdentifierNode>(elementExpr))
{
auto typeInstance = initValue.mType->ToTypeInstance();
if (typeInstance != NULL)
{
String filter;
identiferNode->ToString(filter);
autoComplete->AddTypeMembers(typeInstance, false, true, filter, typeInstance, false, true);
}
}
}
bool wasFirstAdd = isFirstAdd;
if (isFirstAdd)
{
BfExprEvaluator exprEvaluator(mModule);
exprEvaluator.mFunctionBindResult = &addFunctionBindResult;
SizedArray<BfExpression*, 2> argExprs;
argExprs.push_back(elementExpr);
BfSizedArray<BfExpression*> sizedArgExprs(argExprs);
BfResolvedArgs argValues(&sizedArgExprs);
exprEvaluator.ResolveArgValues(argValues);
exprEvaluator.MatchMethod(elementExpr, NULL, initValue, false, false, "Add", argValues, NULL);
if (addFunctionBindResult.mMethodInstance != NULL)
CreateCall(addFunctionBindResult.mMethodInstance, addFunctionBindResult.mFunc, true, addFunctionBindResult.mIRArgs);
isFirstAdd = false;
}
else if ((addFunctionBindResult.mMethodInstance == NULL) || (addFunctionBindResult.mMethodInstance->GetParamCount() == 0))
{
mModule->CreateValueFromExpression(elementExpr);
}
else
{
auto argValue = mModule->CreateValueFromExpression(elementExpr, addFunctionBindResult.mMethodInstance->GetParamType(0));
if ((argValue) && (!mModule->mBfIRBuilder->mIgnoreWrites))
{
SizedArray<BfIRValue, 2> irArgs;
PushThis(elementExpr, initValue, addFunctionBindResult.mMethodInstance, irArgs);
PushArg(argValue, irArgs);
for (int argIdx = (int)irArgs.size(); argIdx < (int)addFunctionBindResult.mIRArgs.size(); argIdx++)
irArgs.Add(addFunctionBindResult.mIRArgs[argIdx]);
CreateCall(addFunctionBindResult.mMethodInstance, addFunctionBindResult.mFunc, true, irArgs);
}
}
wasValidInitKind = true;
}
if (!wasValidInitKind)
{
mModule->Fail("Invalid initializer member declarator", initExpr);
}
}
mResult = initValue;
}
void BfExprEvaluator::Visit(BfCollectionInitializerExpression* arrayInitExpr) void BfExprEvaluator::Visit(BfCollectionInitializerExpression* arrayInitExpr)
{ {
mModule->Fail("Collection initializer not usable here", arrayInitExpr); mModule->Fail("Collection initializer not usable here", arrayInitExpr);
@ -13369,7 +13474,6 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo
} }
curMethodState->AddScope(&scopeData); curMethodState->AddScope(&scopeData);
curMethodState->mCurScope->mMixinDepth++; curMethodState->mCurScope->mMixinDepth++;
curMethodState->mIsEmbedded = false;
// We can't flush scope state because we extend params in as arbitrary values // We can't flush scope state because we extend params in as arbitrary values
mModule->NewScopeState(true, false); mModule->NewScopeState(true, false);

View file

@ -436,6 +436,7 @@ public:
virtual void Visit(BfBaseExpression* baseExpr) override; virtual void Visit(BfBaseExpression* baseExpr) override;
virtual void Visit(BfMixinExpression* mixinExpr) override; virtual void Visit(BfMixinExpression* mixinExpr) override;
virtual void Visit(BfSizedArrayCreateExpression* createExpr) override; virtual void Visit(BfSizedArrayCreateExpression* createExpr) override;
virtual void Visit(BfInitializerExpression* initExpr) override;
virtual void Visit(BfCollectionInitializerExpression* initExpr) override; virtual void Visit(BfCollectionInitializerExpression* initExpr) override;
virtual void Visit(BfTypeOfExpression* typeOfExpr) override; virtual void Visit(BfTypeOfExpression* typeOfExpr) override;
virtual void Visit(BfSizeOfExpression* sizeOfExpr) override; virtual void Visit(BfSizeOfExpression* sizeOfExpr) override;

View file

@ -1097,7 +1097,7 @@ void BfModule::EnsureIRBuilder(bool dbgVerifyCodeGen)
// code as we walk the AST // code as we walk the AST
//mBfIRBuilder->mDbgVerifyCodeGen = true; //mBfIRBuilder->mDbgVerifyCodeGen = true;
if ( if (
(mModuleName == "-") (mModuleName == "-")
//|| (mModuleName == "Tests_FuncRefs_Class") //|| (mModuleName == "Tests_FuncRefs_Class")
//|| (mModuleName == "Tests_FuncRefs") //|| (mModuleName == "Tests_FuncRefs")
) )

View file

@ -909,8 +909,7 @@ public:
BfIRValue mDynStackRevIdx; // Increments when we restore the stack, which can invalidate dynSize for dynamic looped allocs BfIRValue mDynStackRevIdx; // Increments when we restore the stack, which can invalidate dynSize for dynamic looped allocs
BfIRBlock mIRExitBlock; BfIRBlock mIRExitBlock;
BfBreakData* mBreakData; BfBreakData* mBreakData;
int mBlockNestLevel; // 0 = top level int mBlockNestLevel; // 0 = top level
bool mIsEmbedded; // Is an embedded statement (ie: if () stmt) not wrapped in a block
bool mIgnoreObjectAccessCheck; bool mIgnoreObjectAccessCheck;
bool mDisableChecks; bool mDisableChecks;
BfMixinState* mMixinState; BfMixinState* mMixinState;
@ -969,8 +968,7 @@ public:
mBlockNestLevel = 0; mBlockNestLevel = 0;
mInPostReturn = false; mInPostReturn = false;
mCrossingMixin = false; mCrossingMixin = false;
mNoBind = false; mNoBind = false;
mIsEmbedded = false;
mIgnoreObjectAccessCheck = false; mIgnoreObjectAccessCheck = false;
mDisableChecks = false; mDisableChecks = false;
mInConditionalBlock = false; mInConditionalBlock = false;

View file

@ -1206,6 +1206,25 @@ void BfPrinter::Visit(BfSizedArrayCreateExpression* createExpr)
VisitChildWithPrecedingSpace(createExpr->mInitializer); VisitChildWithPrecedingSpace(createExpr->mInitializer);
} }
void BfPrinter::Visit(BfInitializerExpression* initExpr)
{
Visit(initExpr->ToBase());
VisitChild(initExpr->mTarget);
ExpectSpace();
VisitChild(initExpr->mOpenBrace);
for (int i = 0; i < (int)initExpr->mValues.size(); i++)
{
if (i > 0)
{
VisitChild(initExpr->mCommas[i - 1]);
ExpectSpace();
}
VisitChild(initExpr->mValues[i]);
}
VisitChild(initExpr->mCloseBrace);
}
void BfPrinter::Visit(BfCollectionInitializerExpression* initExpr) void BfPrinter::Visit(BfCollectionInitializerExpression* initExpr)
{ {
Visit(initExpr->ToBase()); Visit(initExpr->ToBase());

View file

@ -130,6 +130,7 @@ public:
virtual void Visit(BfBaseExpression* baseExpr) override; virtual void Visit(BfBaseExpression* baseExpr) override;
virtual void Visit(BfMixinExpression* mixinExpr) override; virtual void Visit(BfMixinExpression* mixinExpr) override;
virtual void Visit(BfSizedArrayCreateExpression* createExpr) override; virtual void Visit(BfSizedArrayCreateExpression* createExpr) override;
virtual void Visit(BfInitializerExpression* initExpr) override;
virtual void Visit(BfCollectionInitializerExpression* initExpr) override; virtual void Visit(BfCollectionInitializerExpression* initExpr) override;
virtual void Visit(BfTypeReference* typeRef) override; virtual void Visit(BfTypeReference* typeRef) override;
virtual void Visit(BfNamedTypeReference* typeRef) override; virtual void Visit(BfNamedTypeReference* typeRef) override;

View file

@ -1750,7 +1750,11 @@ BfExpression* BfReducer::CreateExpression(BfAstNode* node, CreateExprFlags creat
else if (isDelegateBind) else if (isDelegateBind)
exprLeft = CreateDelegateBindExpression(allocNode); exprLeft = CreateDelegateBindExpression(allocNode);
else else
{
exprLeft = CreateObjectCreateExpression(allocNode); exprLeft = CreateObjectCreateExpression(allocNode);
if (auto initExpr = TryCreateInitializerExpression(exprLeft))
exprLeft = initExpr;
}
if (token == BfToken_Append) if (token == BfToken_Append)
{ {
@ -2642,6 +2646,8 @@ BfExpression* BfReducer::CreateExpression(BfAstNode* node, CreateExprFlags creat
else if (token == BfToken_LParen) else if (token == BfToken_LParen)
{ {
exprLeft = CreateInvocationExpression(exprLeft, (CreateExprFlags)(createExprFlags & ~(CreateExprFlags_NoCast))); exprLeft = CreateInvocationExpression(exprLeft, (CreateExprFlags)(createExprFlags & ~(CreateExprFlags_NoCast)));
if (auto initExpr = TryCreateInitializerExpression(exprLeft))
exprLeft = initExpr;
} }
else if ((token == BfToken_LBracket) || (token == BfToken_QuestionLBracket)) else if ((token == BfToken_LBracket) || (token == BfToken_QuestionLBracket))
{ {
@ -6900,6 +6906,60 @@ BfInvocationExpression* BfReducer::CreateInvocationExpression(BfAstNode* target,
return invocationExpr; return invocationExpr;
} }
BfInitializerExpression * BfReducer::TryCreateInitializerExpression(BfExpression* target)
{
auto block = BfNodeDynCast<BfBlock>(mVisitorPos.GetNext());
if (block == NULL)
return NULL;
mVisitorPos.MoveNext();
auto initializerExpr = mAlloc->Alloc<BfInitializerExpression>();
ReplaceNode(target, initializerExpr);
initializerExpr->mTarget = target;
MEMBER_SET(initializerExpr, mOpenBrace, block->mOpenBrace);
SetAndRestoreValue<BfVisitorPos> prevVisitorPos(mVisitorPos, BfVisitorPos(block));
bool isDone = !mVisitorPos.MoveNext();
BfDeferredAstSizedArray<BfExpression*> values(initializerExpr->mValues, mAlloc);
BfDeferredAstSizedArray<BfTokenNode*> commas(initializerExpr->mCommas, mAlloc);
BfAstNode* nextNode = NULL;
while (!isDone)
{
BfAstNode* node = mVisitorPos.GetCurrent();
auto expr = CreateExpression(node);
isDone = !mVisitorPos.MoveNext();
if (expr != NULL)
values.Add(expr);
if (!isDone)
{
bool foundComma = false;
node = mVisitorPos.GetCurrent();
if (auto tokenNode = BfNodeDynCast<BfTokenNode>(node))
{
if (tokenNode->mToken == BfToken_Comma)
{
foundComma = true;
commas.Add(tokenNode);
mVisitorPos.MoveNext();
}
}
}
}
mVisitorPos.Trim();
MEMBER_SET(initializerExpr, mCloseBrace, block->mCloseBrace);
return initializerExpr;
}
BfDelegateBindExpression* BfReducer::CreateDelegateBindExpression(BfAstNode* allocNode) BfDelegateBindExpression* BfReducer::CreateDelegateBindExpression(BfAstNode* allocNode)
{ {
auto delegateBindExpr = mAlloc->Alloc<BfDelegateBindExpression>(); auto delegateBindExpr = mAlloc->Alloc<BfDelegateBindExpression>();
@ -7402,7 +7462,7 @@ BfObjectCreateExpression* BfReducer::CreateObjectCreateExpression(BfAstNode* all
if (tokenNode == NULL) if (tokenNode == NULL)
return objectCreateExpr; return objectCreateExpr;
MEMBER_SET(objectCreateExpr, mCloseToken, tokenNode); MEMBER_SET(objectCreateExpr, mCloseToken, tokenNode);
return objectCreateExpr; return objectCreateExpr;
} }
@ -8606,15 +8666,16 @@ BfTokenNode* BfReducer::ParseMethodParams(BfAstNode* node, SizedArrayImpl<BfPara
if (typeRef == NULL) if (typeRef == NULL)
{ {
auto typeIdentifierNode = ExpectIdentifierAfter(nameAfterNode, "parameter type"); auto nextNode = mVisitorPos.GetNext();
if (typeIdentifierNode == NULL) if (nextNode == NULL)
{ {
mVisitorPos.mReadPos = paramStartReadPos; FailAfter("Type expected", nameAfterNode);
break; break;
} }
mVisitorPos.MoveNext();
typeRef = CreateTypeRef(typeIdentifierNode); typeRef = CreateTypeRef(nextNode);
if (typeRef == NULL) if (typeRef == NULL)
{ {
mVisitorPos.mReadPos = paramStartReadPos; mVisitorPos.mReadPos = paramStartReadPos;

View file

@ -199,6 +199,7 @@ public:
BfObjectCreateExpression* CreateObjectCreateExpression(BfAstNode* allocNode); BfObjectCreateExpression* CreateObjectCreateExpression(BfAstNode* allocNode);
BfScopedInvocationTarget* CreateScopedInvocationTarget(BfAstNode*& targetRef, BfTokenNode* colonToken); BfScopedInvocationTarget* CreateScopedInvocationTarget(BfAstNode*& targetRef, BfTokenNode* colonToken);
BfInvocationExpression* CreateInvocationExpression(BfAstNode* target, CreateExprFlags createExprFlags = CreateExprFlags_None); BfInvocationExpression* CreateInvocationExpression(BfAstNode* target, CreateExprFlags createExprFlags = CreateExprFlags_None);
BfInitializerExpression* TryCreateInitializerExpression(BfExpression* target);
BfExpression* CreateIndexerExpression(BfExpression* target); BfExpression* CreateIndexerExpression(BfExpression* target);
BfMemberReferenceExpression* CreateMemberReferenceExpression(BfAstNode* target); BfMemberReferenceExpression* CreateMemberReferenceExpression(BfAstNode* target);
BfTupleExpression* CreateTupleExpression(BfTokenNode* newNode, BfExpression* innerExpr = NULL); BfTupleExpression* CreateTupleExpression(BfTokenNode* newNode, BfExpression* innerExpr = NULL);

View file

@ -3091,8 +3091,7 @@ void BfModule::VisitEmbeddedStatement(BfAstNode* stmt, BfExprEvaluator* exprEval
if (mCurMethodState != NULL) if (mCurMethodState != NULL)
{ {
bool isIgnore = mBfIRBuilder->mIgnoreWrites; bool isIgnore = mBfIRBuilder->mIgnoreWrites;
SetAndRestoreValue<bool> prevEmbedded(mCurMethodState->mIsEmbedded, block == NULL);
mCurMethodState->mInHeadScope = false; mCurMethodState->mInHeadScope = false;
BfScopeData scopeData; BfScopeData scopeData;
@ -3122,7 +3121,14 @@ void BfModule::VisitEmbeddedStatement(BfAstNode* stmt, BfExprEvaluator* exprEval
VisitCodeBlock(block); VisitCodeBlock(block);
} }
else else
{
if (auto varDecl = BfNodeDynCast<BfVariableDeclaration>(stmt))
{
Fail("Variable declarations must be wrapped in a block statement", varDecl);
}
VisitChild(stmt); VisitChild(stmt);
}
} }
if ((block != NULL) && (closeBrace != NULL)) if ((block != NULL) && (closeBrace != NULL))
@ -3720,9 +3726,6 @@ void BfModule::Visit(BfVariableDeclaration* varDecl)
UpdateSrcPos(varDecl); UpdateSrcPos(varDecl);
if (mCurMethodState->mIsEmbedded)
Fail("Variable declarations must be wrapped in a block statement", varDecl);
BfTupleExpression* tupleVariableDeclaration = BfNodeDynCast<BfTupleExpression>(varDecl->mNameNode); BfTupleExpression* tupleVariableDeclaration = BfNodeDynCast<BfTupleExpression>(varDecl->mNameNode);
if (tupleVariableDeclaration != NULL) if (tupleVariableDeclaration != NULL)
{ {

View file

@ -0,0 +1,44 @@
using System;
namespace Tests
{
class Initializers
{
struct StructA
{
public int mA = 123;
public int mB;
public int mC;
public int mD;
public int ValC
{
set mut
{
mC = value;
}
}
public void Add(float val, float? val2 = 234) mut
{
mD += (int)val;
mD += (int)val2 * 10;
}
public void Add(int val)
{
Test.FatalError("Shouldn't be called");
}
}
[Test]
public static void TestBasics()
{
StructA sa = .() { mB = 345, ValC = 456, 567.8f, 789};
Test.Assert(sa.mA == 123);
Test.Assert(sa.mB == 345);
Test.Assert(sa.mC == 456);
Test.Assert(sa.mD == 6036);
}
}
}

View file

@ -263,12 +263,21 @@ namespace Tests
const String cStr1 = "A" + "B"; const String cStr1 = "A" + "B";
const String cStr2 = cStr1 + "C" + cStrD; const String cStr2 = cStr1 + "C" + cStrD;
Test.Assert(cStr2 == "ABCD"); Test.Assert(cStr2 == "ABCD");
Test.Assert(cStr2 === "ABCD");
const char8* cStr3 = "A" + "B"; const char8* cStr3 = "A" + "B";
const char8* cStr4 = cStr1 + "C" + cStrPD; const char8* cStr4 = cStr1 + "C" + cStrPD;
Test.Assert(StringView(cStr4) == "ABCD"); Test.Assert(StringView(cStr4) == "ABCD");
TestDefaults(); TestDefaults();
String strA = scope String("ABCD");
Test.Assert(strA == cStr2);
Test.Assert(strA !== cStr1);
let strTup = (strA, strA);
Test.Assert(strTup == (cStr2, cStr2));
Test.Assert(strTup !== (cStr2, cStr2));
} }
public static TTo Convert<TFrom, TTo>(TFrom val) where TTo : operator explicit TFrom public static TTo Convert<TFrom, TTo>(TFrom val) where TTo : operator explicit TFrom

View file

@ -6,6 +6,12 @@ namespace Tests
{ {
class Tuples class Tuples
{ {
public static void Add(ref (int32, float) val)
{
val.0 += 100;
val.1 += 200;
}
[Test] [Test]
public static void TestBasic() public static void TestBasic()
{ {
@ -21,6 +27,9 @@ namespace Tests
let v0 = tVal1.0; let v0 = tVal1.0;
Test.Assert(v0 == 2); Test.Assert(v0 == 2);
Add(ref tVal1);
Test.Assert(tVal1 == (a: 102, b: 203));
} }
class ValClass class ValClass