mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 11:38:21 +02:00
Ranges (ie: for (int a in 0..<count)
for (int i in 1…10)
)
This commit is contained in:
parent
e561a26695
commit
465050b81d
11 changed files with 418 additions and 18 deletions
271
BeefLibs/corlib/src/Range.bf
Normal file
271
BeefLibs/corlib/src/Range.bf
Normal file
|
@ -0,0 +1,271 @@
|
||||||
|
using System.Collections;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
|
namespace System
|
||||||
|
{
|
||||||
|
interface RangeExpression
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Range : RangeExpression, IEnumerable<int>
|
||||||
|
{
|
||||||
|
protected int mStart;
|
||||||
|
protected int mEnd;
|
||||||
|
|
||||||
|
public this()
|
||||||
|
{
|
||||||
|
mStart = 0;
|
||||||
|
mEnd = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Inline]
|
||||||
|
public this(int start, int end)
|
||||||
|
{
|
||||||
|
Debug.Assert(end >= start);
|
||||||
|
mStart = start;
|
||||||
|
mEnd = end;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Length
|
||||||
|
{
|
||||||
|
[Inline]
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return mEnd - mStart;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Inline]
|
||||||
|
set mut
|
||||||
|
{
|
||||||
|
mEnd = mStart + value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Start
|
||||||
|
{
|
||||||
|
[Inline]
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return mStart;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Inline]
|
||||||
|
set mut
|
||||||
|
{
|
||||||
|
mStart = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int End
|
||||||
|
{
|
||||||
|
[Inline]
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return mEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
set mut
|
||||||
|
{
|
||||||
|
mEnd = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsEmpty
|
||||||
|
{
|
||||||
|
[Inline]
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return mEnd == mStart;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Contains(int idx)
|
||||||
|
{
|
||||||
|
return (idx >= mStart) && (idx < mStart);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Clear() mut
|
||||||
|
{
|
||||||
|
mStart = 0;
|
||||||
|
mEnd = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Inline]
|
||||||
|
public Enumerator GetEnumerator()
|
||||||
|
{
|
||||||
|
return Enumerator(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void ToString(String strBuffer)
|
||||||
|
{
|
||||||
|
strBuffer.AppendF($"{mStart}..<{mEnd}");
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct Enumerator : IEnumerator<int>
|
||||||
|
{
|
||||||
|
private int mEnd;
|
||||||
|
private int mIndex;
|
||||||
|
|
||||||
|
[Inline]
|
||||||
|
public this(Range range)
|
||||||
|
{
|
||||||
|
mIndex = range.mStart - 1;
|
||||||
|
mEnd = range.mEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public ref int Index
|
||||||
|
{
|
||||||
|
get mut
|
||||||
|
{
|
||||||
|
return ref mIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int End => mEnd;
|
||||||
|
|
||||||
|
[Inline]
|
||||||
|
public Result<int> GetNext() mut
|
||||||
|
{
|
||||||
|
if (mIndex + 1 >= mEnd)
|
||||||
|
return .Err;
|
||||||
|
return ++mIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ClosedRange : RangeExpression, IEnumerable<int>
|
||||||
|
{
|
||||||
|
protected int mStart;
|
||||||
|
protected int mEnd;
|
||||||
|
|
||||||
|
public this()
|
||||||
|
{
|
||||||
|
mStart = 0;
|
||||||
|
mEnd = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Inline]
|
||||||
|
public this(int start, int end)
|
||||||
|
{
|
||||||
|
Debug.Assert(end >= start);
|
||||||
|
mStart = start;
|
||||||
|
mEnd = end;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Length
|
||||||
|
{
|
||||||
|
[Inline]
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return mEnd - mStart;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Inline]
|
||||||
|
set mut
|
||||||
|
{
|
||||||
|
mEnd = mStart + value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Start
|
||||||
|
{
|
||||||
|
[Inline]
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return mStart;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Inline]
|
||||||
|
set mut
|
||||||
|
{
|
||||||
|
mStart = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int End
|
||||||
|
{
|
||||||
|
[Inline]
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return mEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
set mut
|
||||||
|
{
|
||||||
|
mEnd = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsEmpty
|
||||||
|
{
|
||||||
|
[Inline]
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return mEnd == mStart;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Contains(int idx)
|
||||||
|
{
|
||||||
|
return (idx >= mStart) && (idx < mStart);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Clear() mut
|
||||||
|
{
|
||||||
|
mStart = 0;
|
||||||
|
mEnd = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Inline]
|
||||||
|
public Enumerator GetEnumerator()
|
||||||
|
{
|
||||||
|
return Enumerator(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void ToString(String strBuffer)
|
||||||
|
{
|
||||||
|
strBuffer.AppendF($"{mStart}...{mEnd}");
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct Enumerator : IEnumerator<int>
|
||||||
|
{
|
||||||
|
private int mEnd;
|
||||||
|
private int mIndex;
|
||||||
|
|
||||||
|
[Inline]
|
||||||
|
public this(ClosedRange range)
|
||||||
|
{
|
||||||
|
mIndex = range.mStart - 1;
|
||||||
|
mEnd = range.mEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public ref int Index
|
||||||
|
{
|
||||||
|
get mut
|
||||||
|
{
|
||||||
|
return ref mIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int End => mEnd;
|
||||||
|
|
||||||
|
[Inline]
|
||||||
|
public Result<int> GetNext() mut
|
||||||
|
{
|
||||||
|
if (mIndex >= mEnd)
|
||||||
|
return .Err;
|
||||||
|
return ++mIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
43
IDE/mintest/minlib/src/System/Range.bf
Normal file
43
IDE/mintest/minlib/src/System/Range.bf
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
using System.Collections;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
|
namespace System
|
||||||
|
{
|
||||||
|
struct Range
|
||||||
|
{
|
||||||
|
protected int mStart;
|
||||||
|
protected int mEnd;
|
||||||
|
|
||||||
|
public this()
|
||||||
|
{
|
||||||
|
mStart = 0;
|
||||||
|
mEnd = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public this(int start, int end)
|
||||||
|
{
|
||||||
|
Debug.Assert(end >= start);
|
||||||
|
mStart = start;
|
||||||
|
mEnd = end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ClosedRange
|
||||||
|
{
|
||||||
|
protected int mStart;
|
||||||
|
protected int mEnd;
|
||||||
|
|
||||||
|
public this()
|
||||||
|
{
|
||||||
|
mStart = 0;
|
||||||
|
mEnd = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public this(int start, int end)
|
||||||
|
{
|
||||||
|
Debug.Assert(end >= start);
|
||||||
|
mStart = start;
|
||||||
|
mEnd = end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1545,6 +1545,8 @@ const char* Beefy::BfTokenToString(BfToken token)
|
||||||
return "..";
|
return "..";
|
||||||
case BfToken_DotDotDot:
|
case BfToken_DotDotDot:
|
||||||
return "...";
|
return "...";
|
||||||
|
case BfToken_DotDotLess:
|
||||||
|
return "..<";
|
||||||
case BfToken_QuestionDot:
|
case BfToken_QuestionDot:
|
||||||
return "?.";
|
return "?.";
|
||||||
case BfToken_QuestionLBracket:
|
case BfToken_QuestionLBracket:
|
||||||
|
@ -1639,22 +1641,24 @@ int Beefy::BfGetBinaryOpPrecendence(BfBinaryOp binOp)
|
||||||
case BfBinaryOp_OverflowMultiply:
|
case BfBinaryOp_OverflowMultiply:
|
||||||
case BfBinaryOp_Divide:
|
case BfBinaryOp_Divide:
|
||||||
case BfBinaryOp_Modulus:
|
case BfBinaryOp_Modulus:
|
||||||
return 13;
|
return 14;
|
||||||
case BfBinaryOp_Add:
|
case BfBinaryOp_Add:
|
||||||
case BfBinaryOp_Subtract:
|
case BfBinaryOp_Subtract:
|
||||||
case BfBinaryOp_OverflowAdd:
|
case BfBinaryOp_OverflowAdd:
|
||||||
case BfBinaryOp_OverflowSubtract:
|
case BfBinaryOp_OverflowSubtract:
|
||||||
return 12;
|
return 13;
|
||||||
case BfBinaryOp_LeftShift:
|
case BfBinaryOp_LeftShift:
|
||||||
case BfBinaryOp_RightShift:
|
case BfBinaryOp_RightShift:
|
||||||
return 11;
|
return 12;
|
||||||
case BfBinaryOp_BitwiseAnd:
|
case BfBinaryOp_BitwiseAnd:
|
||||||
return 10;
|
return 11;
|
||||||
case BfBinaryOp_ExclusiveOr:
|
case BfBinaryOp_ExclusiveOr:
|
||||||
return 9;
|
return 10;
|
||||||
case BfBinaryOp_BitwiseOr:
|
case BfBinaryOp_BitwiseOr:
|
||||||
|
return 9;
|
||||||
|
case BfBinaryOp_Range:
|
||||||
|
case BfBinaryOp_ClosedRange:
|
||||||
return 8;
|
return 8;
|
||||||
// "Range" inserted here if we were copying swift
|
|
||||||
case BfBinaryOp_Is:
|
case BfBinaryOp_Is:
|
||||||
case BfBinaryOp_As:
|
case BfBinaryOp_As:
|
||||||
return 7;
|
return 7;
|
||||||
|
@ -1715,6 +1719,8 @@ const char* Beefy::BfGetOpName(BfBinaryOp binOp)
|
||||||
case BfBinaryOp_NullCoalesce: return "??";
|
case BfBinaryOp_NullCoalesce: return "??";
|
||||||
case BfBinaryOp_Is: return "is";
|
case BfBinaryOp_Is: return "is";
|
||||||
case BfBinaryOp_As: return "as";
|
case BfBinaryOp_As: return "as";
|
||||||
|
case BfBinaryOp_Range: return "..<";
|
||||||
|
case BfBinaryOp_ClosedRange: return "...";
|
||||||
default: return "???";
|
default: return "???";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1740,6 +1746,9 @@ const char* Beefy::BfGetOpName(BfUnaryOp unaryOp)
|
||||||
case BfUnaryOp_Mut: return "mut";
|
case BfUnaryOp_Mut: return "mut";
|
||||||
case BfUnaryOp_Params: return "params";
|
case BfUnaryOp_Params: return "params";
|
||||||
case BfUnaryOp_Cascade: return "..";
|
case BfUnaryOp_Cascade: return "..";
|
||||||
|
case BfUnaryOp_PartialRangeUpTo: return "..<";
|
||||||
|
case BfUnaryOp_PartialRangeThrough: return "...";
|
||||||
|
case BfUnaryOp_PartialRangeFrom: return "...";
|
||||||
default: return "???";
|
default: return "???";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1798,6 +1807,10 @@ BfBinaryOp Beefy::BfTokenToBinaryOp(BfToken token)
|
||||||
return BfBinaryOp_ConditionalOr;
|
return BfBinaryOp_ConditionalOr;
|
||||||
case BfToken_DblQuestion:
|
case BfToken_DblQuestion:
|
||||||
return BfBinaryOp_NullCoalesce;
|
return BfBinaryOp_NullCoalesce;
|
||||||
|
case BfToken_DotDotLess:
|
||||||
|
return BfBinaryOp_Range;
|
||||||
|
case BfToken_DotDotDot:
|
||||||
|
return BfBinaryOp_ClosedRange;
|
||||||
default:
|
default:
|
||||||
return BfBinaryOp_None;
|
return BfBinaryOp_None;
|
||||||
}
|
}
|
||||||
|
@ -1835,6 +1848,10 @@ BfUnaryOp Beefy::BfTokenToUnaryOp(BfToken token)
|
||||||
return BfUnaryOp_Params;
|
return BfUnaryOp_Params;
|
||||||
case BfToken_DotDot:
|
case BfToken_DotDot:
|
||||||
return BfUnaryOp_Cascade;
|
return BfUnaryOp_Cascade;
|
||||||
|
case BfToken_DotDotDot:
|
||||||
|
return BfUnaryOp_PartialRangeThrough;
|
||||||
|
case BfToken_DotDotLess:
|
||||||
|
return BfUnaryOp_PartialRangeUpTo;
|
||||||
default:
|
default:
|
||||||
return BfUnaryOp_None;
|
return BfUnaryOp_None;
|
||||||
}
|
}
|
||||||
|
|
|
@ -232,6 +232,7 @@ enum BfToken : uint8
|
||||||
BfToken_Dot,
|
BfToken_Dot,
|
||||||
BfToken_DotDot,
|
BfToken_DotDot,
|
||||||
BfToken_DotDotDot,
|
BfToken_DotDotDot,
|
||||||
|
BfToken_DotDotLess,
|
||||||
BfToken_QuestionDot,
|
BfToken_QuestionDot,
|
||||||
BfToken_QuestionLBracket,
|
BfToken_QuestionLBracket,
|
||||||
BfToken_AutocompleteDot,
|
BfToken_AutocompleteDot,
|
||||||
|
@ -1821,7 +1822,9 @@ enum BfBinaryOp
|
||||||
BfBinaryOp_ConditionalOr,
|
BfBinaryOp_ConditionalOr,
|
||||||
BfBinaryOp_NullCoalesce,
|
BfBinaryOp_NullCoalesce,
|
||||||
BfBinaryOp_Is,
|
BfBinaryOp_Is,
|
||||||
BfBinaryOp_As
|
BfBinaryOp_As,
|
||||||
|
BfBinaryOp_Range,
|
||||||
|
BfBinaryOp_ClosedRange,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum BfAssignmentOp
|
enum BfAssignmentOp
|
||||||
|
@ -1859,7 +1862,10 @@ enum BfUnaryOp
|
||||||
BfUnaryOp_Out,
|
BfUnaryOp_Out,
|
||||||
BfUnaryOp_Mut,
|
BfUnaryOp_Mut,
|
||||||
BfUnaryOp_Params,
|
BfUnaryOp_Params,
|
||||||
BfUnaryOp_Cascade
|
BfUnaryOp_Cascade,
|
||||||
|
BfUnaryOp_PartialRangeUpTo,
|
||||||
|
BfUnaryOp_PartialRangeThrough,
|
||||||
|
BfUnaryOp_PartialRangeFrom,
|
||||||
};
|
};
|
||||||
|
|
||||||
class BfTokenNode : public BfAstNode
|
class BfTokenNode : public BfAstNode
|
||||||
|
|
|
@ -382,6 +382,8 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly)
|
||||||
mArray3TypeDef = NULL;
|
mArray3TypeDef = NULL;
|
||||||
mArray4TypeDef = NULL;
|
mArray4TypeDef = NULL;
|
||||||
mSpanTypeDef = NULL;
|
mSpanTypeDef = NULL;
|
||||||
|
mRangeTypeDef = NULL;
|
||||||
|
mClosedRangeTypeDef = NULL;
|
||||||
mAttributeTypeDef = NULL;
|
mAttributeTypeDef = NULL;
|
||||||
mAttributeUsageAttributeTypeDef = NULL;
|
mAttributeUsageAttributeTypeDef = NULL;
|
||||||
mClassVDataTypeDef = NULL;
|
mClassVDataTypeDef = NULL;
|
||||||
|
@ -6722,7 +6724,9 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
|
||||||
mArray2TypeDef = _GetRequiredType("System.Array2", 1);
|
mArray2TypeDef = _GetRequiredType("System.Array2", 1);
|
||||||
mArray3TypeDef = _GetRequiredType("System.Array3", 1);
|
mArray3TypeDef = _GetRequiredType("System.Array3", 1);
|
||||||
mArray4TypeDef = _GetRequiredType("System.Array4", 1);
|
mArray4TypeDef = _GetRequiredType("System.Array4", 1);
|
||||||
mSpanTypeDef = _GetRequiredType("System.Span", 1);
|
mSpanTypeDef = _GetRequiredType("System.Span", 1);
|
||||||
|
mRangeTypeDef = _GetRequiredType("System.Range");
|
||||||
|
mClosedRangeTypeDef = _GetRequiredType("System.ClosedRange");
|
||||||
mAttributeTypeDef = _GetRequiredType("System.Attribute");
|
mAttributeTypeDef = _GetRequiredType("System.Attribute");
|
||||||
mAttributeUsageAttributeTypeDef = _GetRequiredType("System.AttributeUsageAttribute");
|
mAttributeUsageAttributeTypeDef = _GetRequiredType("System.AttributeUsageAttribute");
|
||||||
mClassVDataTypeDef = _GetRequiredType("System.ClassVData");
|
mClassVDataTypeDef = _GetRequiredType("System.ClassVData");
|
||||||
|
|
|
@ -347,6 +347,8 @@ public:
|
||||||
BfTypeDef* mArray3TypeDef;
|
BfTypeDef* mArray3TypeDef;
|
||||||
BfTypeDef* mArray4TypeDef;
|
BfTypeDef* mArray4TypeDef;
|
||||||
BfTypeDef* mSpanTypeDef;
|
BfTypeDef* mSpanTypeDef;
|
||||||
|
BfTypeDef* mRangeTypeDef;
|
||||||
|
BfTypeDef* mClosedRangeTypeDef;
|
||||||
|
|
||||||
BfTypeDef* mClassVDataTypeDef;
|
BfTypeDef* mClassVDataTypeDef;
|
||||||
|
|
||||||
|
|
|
@ -20433,7 +20433,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfExpression* leftExpression, BfExp
|
||||||
}
|
}
|
||||||
if (leftValue.mType->IsRef())
|
if (leftValue.mType->IsRef())
|
||||||
leftValue.mType = leftValue.mType->GetUnderlyingType();
|
leftValue.mType = leftValue.mType->GetUnderlyingType();
|
||||||
|
|
||||||
if ((binaryOp == BfBinaryOp_ConditionalAnd) || (binaryOp == BfBinaryOp_ConditionalOr))
|
if ((binaryOp == BfBinaryOp_ConditionalAnd) || (binaryOp == BfBinaryOp_ConditionalOr))
|
||||||
{
|
{
|
||||||
if (mModule->mCurMethodState->mDeferredLocalAssignData != NULL)
|
if (mModule->mCurMethodState->mDeferredLocalAssignData != NULL)
|
||||||
|
@ -20670,7 +20670,7 @@ bool BfExprEvaluator::PerformBinaryOperation_NullCoalesce(BfTokenNode* opToken,
|
||||||
mModule->AddBasicBlock(endBB);
|
mModule->AddBasicBlock(endBB);
|
||||||
|
|
||||||
if (assignTo != NULL)
|
if (assignTo != NULL)
|
||||||
{
|
{
|
||||||
mResult = *assignTo;
|
mResult = *assignTo;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -20689,12 +20689,35 @@ bool BfExprEvaluator::PerformBinaryOperation_NullCoalesce(BfTokenNode* opToken,
|
||||||
|
|
||||||
void BfExprEvaluator::PerformBinaryOperation(BfExpression* leftExpression, BfExpression* rightExpression, BfBinaryOp binaryOp, BfTokenNode* opToken, BfBinOpFlags flags)
|
void BfExprEvaluator::PerformBinaryOperation(BfExpression* leftExpression, BfExpression* rightExpression, BfBinaryOp binaryOp, BfTokenNode* opToken, BfBinOpFlags flags)
|
||||||
{
|
{
|
||||||
|
if ((binaryOp == BfBinaryOp_Range) || (binaryOp == BfBinaryOp_ClosedRange))
|
||||||
|
{
|
||||||
|
auto intType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
|
||||||
|
|
||||||
|
auto allocType = mModule->ResolveTypeDef((binaryOp == BfBinaryOp_Range) ? mModule->mCompiler->mRangeTypeDef : mModule->mCompiler->mClosedRangeTypeDef)->ToTypeInstance();
|
||||||
|
auto alloca = mModule->CreateAlloca(allocType);
|
||||||
|
|
||||||
|
SizedArray<BfExpression*, 2> argExprs;
|
||||||
|
argExprs.Add(leftExpression);
|
||||||
|
argExprs.Add(rightExpression);
|
||||||
|
|
||||||
|
BfSizedArray<BfExpression*> args = argExprs;
|
||||||
|
|
||||||
|
BfResolvedArgs argValues;
|
||||||
|
argValues.Init(&args);
|
||||||
|
ResolveArgValues(argValues, BfResolveArgsFlag_DeferParamEval);
|
||||||
|
|
||||||
|
mResult = BfTypedValue(alloca, allocType, true);
|
||||||
|
MatchConstructor(opToken, NULL, mResult, allocType, argValues, true, false);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
BfTypedValue leftValue;
|
BfTypedValue leftValue;
|
||||||
if (leftExpression != NULL)
|
if (leftExpression != NULL)
|
||||||
{
|
{
|
||||||
leftValue = mModule->CreateValueFromExpression(leftExpression, mExpectingType, (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_NoCast | BfEvalExprFlags_AllowIntUnknown));
|
leftValue = mModule->CreateValueFromExpression(leftExpression, mExpectingType, (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_NoCast | BfEvalExprFlags_AllowIntUnknown));
|
||||||
}
|
}
|
||||||
return PerformBinaryOperation(leftExpression, rightExpression, binaryOp, opToken, flags, leftValue);
|
PerformBinaryOperation(leftExpression, rightExpression, binaryOp, opToken, flags, leftValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BfExprEvaluator::CheckConstCompare(BfBinaryOp binaryOp, BfAstNode* opToken, const BfTypedValue& leftValue, const BfTypedValue& rightValue)
|
bool BfExprEvaluator::CheckConstCompare(BfBinaryOp binaryOp, BfAstNode* opToken, const BfTypedValue& leftValue, const BfTypedValue& rightValue)
|
||||||
|
|
|
@ -2316,6 +2316,13 @@ void BfParser::NextToken(int endIdx, bool outerIsInterpolate)
|
||||||
mToken = BfToken_DotDotDot;
|
mToken = BfToken_DotDotDot;
|
||||||
mSyntaxToken = BfSyntaxToken_Token;
|
mSyntaxToken = BfSyntaxToken_Token;
|
||||||
}
|
}
|
||||||
|
else if (mSrc[mSrcIdx + 1] == '<')
|
||||||
|
{
|
||||||
|
mSrcIdx += 2;
|
||||||
|
mTokenEnd = mSrcIdx;
|
||||||
|
mToken = BfToken_DotDotLess;
|
||||||
|
mSyntaxToken = BfSyntaxToken_Token;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mSrcIdx++;
|
mSrcIdx++;
|
||||||
|
@ -2526,8 +2533,15 @@ void BfParser::NextToken(int endIdx, bool outerIsInterpolate)
|
||||||
|
|
||||||
bool endNumber = false;
|
bool endNumber = false;
|
||||||
|
|
||||||
|
bool hasDot = c == '.';
|
||||||
|
if ((hasDot) && (mSrc[mSrcIdx] == '.'))
|
||||||
|
{
|
||||||
|
// Skip float parsing if we have a double-dot `1..` case
|
||||||
|
hasDot = false;
|
||||||
|
}
|
||||||
|
|
||||||
// The 'prevIsDot' helps tuple lookups like "tuple.0.0", interpreting those as two integers rather than a float
|
// The 'prevIsDot' helps tuple lookups like "tuple.0.0", interpreting those as two integers rather than a float
|
||||||
if (((c == '.') && (!prevIsDot)) || (hasExp))
|
if (((hasDot) && (!prevIsDot)) || (hasExp))
|
||||||
{
|
{
|
||||||
// Switch to floating point mode
|
// Switch to floating point mode
|
||||||
//double dVal = val;
|
//double dVal = val;
|
||||||
|
|
|
@ -2287,7 +2287,7 @@ void BfPrinter::Visit(BfUnaryOperatorExpression* unaryOpExpr)
|
||||||
{
|
{
|
||||||
Visit(unaryOpExpr->ToBase());
|
Visit(unaryOpExpr->ToBase());
|
||||||
|
|
||||||
bool postOp = (unaryOpExpr->mOp == BfUnaryOp_PostIncrement) || (unaryOpExpr->mOp == BfUnaryOp_PostDecrement);
|
bool postOp = (unaryOpExpr->mOp == BfUnaryOp_PostIncrement) || (unaryOpExpr->mOp == BfUnaryOp_PostDecrement) || (unaryOpExpr->mOp == BfUnaryOp_PartialRangeFrom);
|
||||||
if (!postOp)
|
if (!postOp)
|
||||||
VisitChild(unaryOpExpr->mOpToken);
|
VisitChild(unaryOpExpr->mOpToken);
|
||||||
if ((unaryOpExpr->mOp == BfUnaryOp_Ref) || (unaryOpExpr->mOp == BfUnaryOp_Mut) || (unaryOpExpr->mOp == BfUnaryOp_Out) || (unaryOpExpr->mOp == BfUnaryOp_Params) || (unaryOpExpr->mOp == BfUnaryOp_Cascade))
|
if ((unaryOpExpr->mOp == BfUnaryOp_Ref) || (unaryOpExpr->mOp == BfUnaryOp_Mut) || (unaryOpExpr->mOp == BfUnaryOp_Out) || (unaryOpExpr->mOp == BfUnaryOp_Params) || (unaryOpExpr->mOp == BfUnaryOp_Cascade))
|
||||||
|
|
|
@ -2353,12 +2353,22 @@ BfExpression* BfReducer::CreateExpression(BfAstNode* node, CreateExprFlags creat
|
||||||
((token == BfToken_RChevron) || (token == BfToken_RDblChevron)))
|
((token == BfToken_RChevron) || (token == BfToken_RDblChevron)))
|
||||||
return exprLeft;
|
return exprLeft;
|
||||||
|
|
||||||
if ((token == BfToken_DblPlus) || (token == BfToken_DblMinus))
|
BfUnaryOp postUnaryOp = BfUnaryOp_None;
|
||||||
{
|
if (token == BfToken_DblPlus)
|
||||||
// Post-increment, post-decrement
|
postUnaryOp = BfUnaryOp_PostIncrement;
|
||||||
|
if (token == BfToken_DblMinus)
|
||||||
|
postUnaryOp = BfUnaryOp_PostDecrement;
|
||||||
|
|
||||||
|
if (token == BfToken_DotDotDot)
|
||||||
|
{
|
||||||
|
//TODO: Detect if this is a BfUnaryOp_PartialRangeFrom
|
||||||
|
}
|
||||||
|
|
||||||
|
if (postUnaryOp != BfUnaryOp_None)
|
||||||
|
{
|
||||||
auto unaryOpExpr = mAlloc->Alloc<BfUnaryOperatorExpression>();
|
auto unaryOpExpr = mAlloc->Alloc<BfUnaryOperatorExpression>();
|
||||||
ReplaceNode(exprLeft, unaryOpExpr);
|
ReplaceNode(exprLeft, unaryOpExpr);
|
||||||
unaryOpExpr->mOp = (token == BfToken_DblPlus) ? BfUnaryOp_PostIncrement : BfUnaryOp_PostDecrement;
|
unaryOpExpr->mOp = postUnaryOp;
|
||||||
MEMBER_SET(unaryOpExpr, mOpToken, tokenNode);
|
MEMBER_SET(unaryOpExpr, mOpToken, tokenNode);
|
||||||
MEMBER_SET(unaryOpExpr, mExpression, exprLeft);
|
MEMBER_SET(unaryOpExpr, mExpression, exprLeft);
|
||||||
exprLeft = unaryOpExpr;
|
exprLeft = unaryOpExpr;
|
||||||
|
|
|
@ -72,6 +72,16 @@ namespace Tests
|
||||||
}
|
}
|
||||||
Test.Assert(iterations == 19);
|
Test.Assert(iterations == 19);
|
||||||
Test.Assert(sGetValCount == 20);
|
Test.Assert(sGetValCount == 20);
|
||||||
|
|
||||||
|
int total = 0;
|
||||||
|
for (int i in 1..<10)
|
||||||
|
total += i;
|
||||||
|
Test.Assert(total == 1+2+3+4+5+6+7+8+9);
|
||||||
|
|
||||||
|
total = 0;
|
||||||
|
for (int i in 1...10)
|
||||||
|
total += i;
|
||||||
|
Test.Assert(total == 1+2+3+4+5+6+7+8+9+10);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void TestEnumerator1(EnumeratorTest e)
|
public static void TestEnumerator1(EnumeratorTest e)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue