Слайсы
This commit is contained in:
parent
bbe2b15590
commit
01c82f5863
|
|
@ -2,7 +2,7 @@
|
|||
// This CSharp output file generated by Gardens Point LEX
|
||||
// Version: 1.1.3.301
|
||||
// Machine: SSM
|
||||
// DateTime: 09.03.2016 23:53:13
|
||||
// DateTime: 10.03.2016 0:57:37
|
||||
// UserName: ?????????
|
||||
// GPLEX input file <ABCPascal.lex>
|
||||
// GPLEX frame file <embedded resource>
|
||||
|
|
|
|||
|
|
@ -3001,7 +3001,13 @@ variable
|
|||
}
|
||||
| variable tkSquareOpen expr_list tkSquareClose
|
||||
{
|
||||
$$ = new indexer($1 as addressed_value,$3 as expression_list, @$);
|
||||
var el = $3 as expression_list; // SSM 10/03/16
|
||||
if (el.expressions.Count==1 && el.expressions[0] is format_expr)
|
||||
{
|
||||
var fe = el.expressions[0] as format_expr;
|
||||
$$ = new slice_expr($1 as addressed_value,fe.expr,fe.format1,fe.format2,fe.source_context);
|
||||
}
|
||||
else $$ = new indexer($1 as addressed_value,el, @$);
|
||||
}
|
||||
| variable tkRoundOpen optional_expr_list tkRoundClose
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
// GPPG version 1.3.6
|
||||
// Machine: SSM
|
||||
// DateTime: 09.03.2016 23:53:14
|
||||
// DateTime: 10.03.2016 0:57:38
|
||||
// UserName: ?????????
|
||||
// Input file <D:\PascalABC.NET\!PABC_Git\Parsers\PascalABCParserNewSaushkin\ABCPascal.y>
|
||||
|
||||
|
|
@ -4873,7 +4873,13 @@ public partial class GPPGParser: ShiftReduceParser<PascalABCSavParser.Union, Lex
|
|||
break;
|
||||
case 609: // variable -> variable, tkSquareOpen, expr_list, tkSquareClose
|
||||
{
|
||||
CurrentSemanticValue.ex = new indexer(ValueStack[ValueStack.Depth-4].ex as addressed_value,ValueStack[ValueStack.Depth-2].stn as expression_list, CurrentLocationSpan);
|
||||
var el = ValueStack[ValueStack.Depth-2].stn as expression_list; // SSM 10/03/16
|
||||
if (el.expressions.Count==1 && el.expressions[0] is format_expr)
|
||||
{
|
||||
var fe = el.expressions[0] as format_expr;
|
||||
CurrentSemanticValue.ex = new slice_expr(ValueStack[ValueStack.Depth-4].ex as addressed_value,fe.expr,fe.format1,fe.format2,fe.source_context);
|
||||
}
|
||||
else CurrentSemanticValue.ex = new indexer(ValueStack[ValueStack.Depth-4].ex as addressed_value,el, CurrentLocationSpan);
|
||||
}
|
||||
break;
|
||||
case 610: // variable -> variable, tkRoundOpen, optional_expr_list, tkRoundClose
|
||||
|
|
|
|||
|
|
@ -1057,6 +1057,11 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
{
|
||||
DefaultVisit(_dot_question_node);
|
||||
}
|
||||
|
||||
public virtual void visit(slice_expr _slice_expr)
|
||||
{
|
||||
DefaultVisit(_slice_expr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1685,6 +1685,14 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
{
|
||||
}
|
||||
|
||||
public virtual void pre_do_visit(slice_expr _slice_expr)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void post_do_visit(slice_expr _slice_expr)
|
||||
{
|
||||
}
|
||||
|
||||
public override void visit(syntax_tree_node _syntax_tree_node)
|
||||
{
|
||||
DefaultVisit(_syntax_tree_node);
|
||||
|
|
@ -3489,6 +3497,17 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
visit(dot_question_node.right);
|
||||
post_do_visit(_dot_question_node);
|
||||
}
|
||||
|
||||
public override void visit(slice_expr _slice_expr)
|
||||
{
|
||||
DefaultVisit(_slice_expr);
|
||||
pre_do_visit(_slice_expr);
|
||||
visit(slice_expr.v);
|
||||
visit(slice_expr.from);
|
||||
visit(slice_expr.to);
|
||||
visit(slice_expr.step);
|
||||
post_do_visit(_slice_expr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -440,6 +440,8 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
return new uses_closure();
|
||||
case 209:
|
||||
return new dot_question_node();
|
||||
case 210:
|
||||
return new slice_expr();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
@ -2335,7 +2337,7 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
|
||||
public void read_format_expr(format_expr _format_expr)
|
||||
{
|
||||
read_addressed_value(_format_expr);
|
||||
read_expression(_format_expr);
|
||||
_format_expr.expr = _read_node() as expression;
|
||||
_format_expr.format1 = _read_node() as expression;
|
||||
_format_expr.format2 = _read_node() as expression;
|
||||
|
|
@ -3733,6 +3735,21 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
_dot_question_node.right = _read_node() as addressed_value;
|
||||
}
|
||||
|
||||
|
||||
public void visit(slice_expr _slice_expr)
|
||||
{
|
||||
read_slice_expr(_slice_expr);
|
||||
}
|
||||
|
||||
public void read_slice_expr(slice_expr _slice_expr)
|
||||
{
|
||||
read_dereference(_slice_expr);
|
||||
_slice_expr.v = _read_node() as addressed_value;
|
||||
_slice_expr.from = _read_node() as expression;
|
||||
_slice_expr.to = _read_node() as expression;
|
||||
_slice_expr.step = _read_node() as expression;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -3414,7 +3414,7 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
|
||||
public void write_format_expr(format_expr _format_expr)
|
||||
{
|
||||
write_addressed_value(_format_expr);
|
||||
write_expression(_format_expr);
|
||||
if (_format_expr.expr == null)
|
||||
{
|
||||
bw.Write((byte)0);
|
||||
|
|
@ -5860,6 +5860,54 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public void visit(slice_expr _slice_expr)
|
||||
{
|
||||
bw.Write((Int16)210);
|
||||
write_slice_expr(_slice_expr);
|
||||
}
|
||||
|
||||
public void write_slice_expr(slice_expr _slice_expr)
|
||||
{
|
||||
write_dereference(_slice_expr);
|
||||
if (_slice_expr.v == null)
|
||||
{
|
||||
bw.Write((byte)0);
|
||||
}
|
||||
else
|
||||
{
|
||||
bw.Write((byte)1);
|
||||
_slice_expr.v.visit(this);
|
||||
}
|
||||
if (_slice_expr.from == null)
|
||||
{
|
||||
bw.Write((byte)0);
|
||||
}
|
||||
else
|
||||
{
|
||||
bw.Write((byte)1);
|
||||
_slice_expr.from.visit(this);
|
||||
}
|
||||
if (_slice_expr.to == null)
|
||||
{
|
||||
bw.Write((byte)0);
|
||||
}
|
||||
else
|
||||
{
|
||||
bw.Write((byte)1);
|
||||
_slice_expr.to.visit(this);
|
||||
}
|
||||
if (_slice_expr.step == null)
|
||||
{
|
||||
bw.Write((byte)0);
|
||||
}
|
||||
else
|
||||
{
|
||||
bw.Write((byte)1);
|
||||
_slice_expr.step.visit(this);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -16026,7 +16026,7 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
///expr:1:2
|
||||
///</summary>
|
||||
[Serializable]
|
||||
public partial class format_expr : addressed_value
|
||||
public partial class format_expr : expression
|
||||
{
|
||||
|
||||
///<summary>
|
||||
|
|
@ -27675,6 +27675,216 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
}
|
||||
|
||||
|
||||
///<summary>
|
||||
///
|
||||
///</summary>
|
||||
[Serializable]
|
||||
public partial class slice_expr : dereference
|
||||
{
|
||||
|
||||
///<summary>
|
||||
///Конструктор без параметров.
|
||||
///</summary>
|
||||
public slice_expr()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
///<summary>
|
||||
///Конструктор с параметрами.
|
||||
///</summary>
|
||||
public slice_expr(addressed_value _v,expression _from,expression _to,expression _step)
|
||||
{
|
||||
this._v=_v;
|
||||
this._from=_from;
|
||||
this._to=_to;
|
||||
this._step=_step;
|
||||
}
|
||||
|
||||
///<summary>
|
||||
///Конструктор с параметрами.
|
||||
///</summary>
|
||||
public slice_expr(addressed_value _v,expression _from,expression _to,expression _step,SourceContext sc)
|
||||
{
|
||||
this._v=_v;
|
||||
this._from=_from;
|
||||
this._to=_to;
|
||||
this._step=_step;
|
||||
source_context = sc;
|
||||
}
|
||||
|
||||
///<summary>
|
||||
///Конструктор с параметрами.
|
||||
///</summary>
|
||||
public slice_expr(addressed_value _dereferencing_value,addressed_value _v,expression _from,expression _to,expression _step)
|
||||
{
|
||||
this._dereferencing_value=_dereferencing_value;
|
||||
this._v=_v;
|
||||
this._from=_from;
|
||||
this._to=_to;
|
||||
this._step=_step;
|
||||
}
|
||||
|
||||
///<summary>
|
||||
///Конструктор с параметрами.
|
||||
///</summary>
|
||||
public slice_expr(addressed_value _dereferencing_value,addressed_value _v,expression _from,expression _to,expression _step,SourceContext sc)
|
||||
{
|
||||
this._dereferencing_value=_dereferencing_value;
|
||||
this._v=_v;
|
||||
this._from=_from;
|
||||
this._to=_to;
|
||||
this._step=_step;
|
||||
source_context = sc;
|
||||
}
|
||||
|
||||
protected addressed_value _v;
|
||||
protected expression _from;
|
||||
protected expression _to;
|
||||
protected expression _step;
|
||||
|
||||
///<summary>
|
||||
///
|
||||
///</summary>
|
||||
public addressed_value v
|
||||
{
|
||||
get
|
||||
{
|
||||
return _v;
|
||||
}
|
||||
set
|
||||
{
|
||||
_v=value;
|
||||
}
|
||||
}
|
||||
|
||||
///<summary>
|
||||
///
|
||||
///</summary>
|
||||
public expression from
|
||||
{
|
||||
get
|
||||
{
|
||||
return _from;
|
||||
}
|
||||
set
|
||||
{
|
||||
_from=value;
|
||||
}
|
||||
}
|
||||
|
||||
///<summary>
|
||||
///
|
||||
///</summary>
|
||||
public expression to
|
||||
{
|
||||
get
|
||||
{
|
||||
return _to;
|
||||
}
|
||||
set
|
||||
{
|
||||
_to=value;
|
||||
}
|
||||
}
|
||||
|
||||
///<summary>
|
||||
///
|
||||
///</summary>
|
||||
public expression step
|
||||
{
|
||||
get
|
||||
{
|
||||
return _step;
|
||||
}
|
||||
set
|
||||
{
|
||||
_step=value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///<summary>
|
||||
///Свойство для получения количества всех подузлов без элементов поля типа List
|
||||
///</summary>
|
||||
public override Int32 subnodes_without_list_elements_count
|
||||
{
|
||||
get
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
}
|
||||
///<summary>
|
||||
///Свойство для получения количества всех подузлов. Подузлом также считается каждый элемент поля типа List
|
||||
///</summary>
|
||||
public override Int32 subnodes_count
|
||||
{
|
||||
get
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
}
|
||||
///<summary>
|
||||
///Индексатор для получения всех подузлов
|
||||
///</summary>
|
||||
public override syntax_tree_node this[Int32 ind]
|
||||
{
|
||||
get
|
||||
{
|
||||
if(subnodes_count == 0 || ind < 0 || ind > subnodes_count-1)
|
||||
throw new IndexOutOfRangeException();
|
||||
switch(ind)
|
||||
{
|
||||
case 0:
|
||||
return dereferencing_value;
|
||||
case 1:
|
||||
return v;
|
||||
case 2:
|
||||
return from;
|
||||
case 3:
|
||||
return to;
|
||||
case 4:
|
||||
return step;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
set
|
||||
{
|
||||
if(subnodes_count == 0 || ind < 0 || ind > subnodes_count-1)
|
||||
throw new IndexOutOfRangeException();
|
||||
switch(ind)
|
||||
{
|
||||
case 0:
|
||||
dereferencing_value = (addressed_value)value;
|
||||
break;
|
||||
case 1:
|
||||
v = (addressed_value)value;
|
||||
break;
|
||||
case 2:
|
||||
from = (expression)value;
|
||||
break;
|
||||
case 3:
|
||||
to = (expression)value;
|
||||
break;
|
||||
case 4:
|
||||
step = (expression)value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
///<summary>
|
||||
///Метод для обхода дерева посетителем
|
||||
///</summary>
|
||||
///<param name="visitor">Объект-посетитель.</param>
|
||||
///<returns>Return value is void</returns>
|
||||
public override void visit(IVisitor visitor)
|
||||
{
|
||||
visitor.visit(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1264,6 +1264,12 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
///<param name="_dot_question_node">Node to visit</param>
|
||||
///<returns> Return value is void </returns>
|
||||
void visit(dot_question_node _dot_question_node);
|
||||
///<summary>
|
||||
///Method to visit slice_expr.
|
||||
///</summary>
|
||||
///<param name="_slice_expr">Node to visit</param>
|
||||
///<returns> Return value is void </returns>
|
||||
void visit(slice_expr _slice_expr);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -15598,7 +15598,22 @@ namespace PascalABCCompiler.TreeConverter
|
|||
AddError(new CanNotAssignToReadOnlyElement(to.location,node_type));
|
||||
}
|
||||
|
||||
expression_node from = convert_strong(_assign.from);
|
||||
//expression_node from = convert_strong(_assign.from);
|
||||
/// SSM исправление Саушкина 10.03.16
|
||||
expression_node from;
|
||||
var fromAsLambda = _assign.from as function_lambda_definition;
|
||||
if (fromAsLambda != null)
|
||||
{
|
||||
var lambdaVisitMode = fromAsLambda.lambda_visit_mode;
|
||||
fromAsLambda.lambda_visit_mode = LambdaVisitMode.VisitForAdvancedMethodCallProcessing;
|
||||
from = convert_strong(_assign.from);
|
||||
fromAsLambda.lambda_visit_mode = lambdaVisitMode;
|
||||
}
|
||||
else
|
||||
{
|
||||
from = convert_strong(_assign.from);
|
||||
}
|
||||
/// end
|
||||
|
||||
if (stflambda.Count>0) // мы находимся внутри лямбды - возможно, вложенной
|
||||
{
|
||||
|
|
@ -18836,7 +18851,94 @@ namespace PascalABCCompiler.TreeConverter
|
|||
visit(st);
|
||||
}
|
||||
|
||||
/*public SyntaxTree.question_colon_expression ConvertToQCE(dot_question_node dqn)
|
||||
public override void visit(SyntaxTree.slice_expr sl)
|
||||
{
|
||||
var semvar = convert_strong(sl.v);
|
||||
var semvartype = semvar.type;
|
||||
|
||||
var IsOrImplementsIEnumerableT = false; // проверим, является ли semvartype интерфейсом IEnumerable<T> или реализует его
|
||||
|
||||
var ct = semvartype as compiled_type_node;
|
||||
if (ct != null && ct.compiled_type.IsGenericType && ct.compiled_type.GetGenericTypeDefinition() == typeof(System.Collections.Generic.IEnumerable<>)) // это он и есть
|
||||
IsOrImplementsIEnumerableT = true;
|
||||
|
||||
if (!IsOrImplementsIEnumerableT)
|
||||
foreach (SemanticTree.ITypeNode itn in semvartype.ImplementingInterfaces) // Ищем интерфейс IEnumerable<T>
|
||||
{
|
||||
if (itn is compiled_generic_instance_type_node)
|
||||
{
|
||||
var itnc = (itn as compiled_generic_instance_type_node);
|
||||
var tt = (itnc.original_generic as compiled_type_node).compiled_type;
|
||||
|
||||
if (tt == typeof(System.Collections.Generic.IEnumerable<>))
|
||||
{
|
||||
IsOrImplementsIEnumerableT = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (itn is compiled_type_node)
|
||||
{
|
||||
var itnc = (itn as compiled_type_node);
|
||||
var tt = itnc.compiled_type;
|
||||
if (!tt.IsGenericType)
|
||||
continue;
|
||||
var tt1 = tt.GetGenericTypeDefinition();
|
||||
|
||||
if (tt1 == typeof(System.Collections.Generic.IEnumerable<>))
|
||||
{
|
||||
IsOrImplementsIEnumerableT = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!IsOrImplementsIEnumerableT)
|
||||
AddError(get_location(sl.v), "BAD_SLICE_OBJECT");
|
||||
|
||||
var semfrom = convert_strong(sl.from);
|
||||
convertion_data_and_alghoritms.check_convert_type(semfrom, SystemLibrary.SystemLibrary.integer_type, get_location(sl.from));
|
||||
var synfrom = new SyntaxTree.semantic_addr_value(semfrom);
|
||||
|
||||
var int1 = new int32_const(1);
|
||||
var el = new SyntaxTree.expression_list();
|
||||
|
||||
if (semvartype == SystemLibrary.SystemLibrary.string_type) // Сдвинуть from на 1
|
||||
el.Add(new bin_expr(synfrom, int1, Operators.Minus));
|
||||
else el.Add(synfrom);
|
||||
|
||||
SyntaxTree.expression synstep;
|
||||
if (sl.step != null)
|
||||
{
|
||||
var semstep = convert_strong(sl.step);
|
||||
convertion_data_and_alghoritms.check_convert_type(semstep, SystemLibrary.SystemLibrary.integer_type, get_location(sl.step));
|
||||
synstep = new SyntaxTree.semantic_addr_value(semstep);
|
||||
}
|
||||
else
|
||||
{
|
||||
synstep = int1;
|
||||
}
|
||||
el.Add(synstep);
|
||||
|
||||
var semto = convert_strong(sl.to);
|
||||
convertion_data_and_alghoritms.check_convert_type(semto, SystemLibrary.SystemLibrary.integer_type, get_location(sl.to));
|
||||
var synto = new SyntaxTree.semantic_addr_value(semto);
|
||||
|
||||
// count = (abs(to-from)-1) div abs(step) + 1 - нет
|
||||
// count = (to-from+step-1) div step
|
||||
SyntaxTree.expression ex = new bin_expr(synto, synfrom, Operators.Minus);
|
||||
//ex = new method_call(new ident("abs"), new expression_list(ex));
|
||||
//ex = new bin_expr(ex, absstep, Operators.IntegerDivision);
|
||||
SyntaxTree.expression signstep = new method_call(new ident("sign"), new expression_list(synstep));
|
||||
ex = new bin_expr(ex, synstep, Operators.Plus);
|
||||
ex = new bin_expr(ex, signstep, Operators.Minus);
|
||||
ex = new bin_expr(ex, synstep, Operators.IntegerDivision);
|
||||
|
||||
el.Add(ex);
|
||||
var mc = new method_call(new dot_node(sl.v, new ident("Slice", sl.v.source_context), sl.v.source_context), el, sl.source_context);
|
||||
visit(mc);
|
||||
}
|
||||
|
||||
/*public SyntaxTree.question_colon_expression ConvertToQCE(dot_question_node dqn)
|
||||
{
|
||||
// Неверно работает. Пока не используется. Доделать
|
||||
addressed_value left = dqn.left;
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -2497,6 +2497,15 @@
|
|||
<i Type="ClassMethod">procedure Reset ( )</i>
|
||||
</ICtx>
|
||||
</Node>
|
||||
<Node Name="Slice<T>(Self: sequence of T">
|
||||
<FileName>\PABCSystem.pas</FileName>
|
||||
<Text>function Slice<T>(Self: sequence of T; from,step: integer): sequence of T; extensionmethod;</Text>
|
||||
<OCtx>
|
||||
<i Type="Method">function Slice < T > ( Self : sequence of T ; from , step : integer ) : sequence of T extensionmethod</i>
|
||||
<i Type="PAS_TreeNode">
|
||||
</i>
|
||||
</OCtx>
|
||||
</Node>
|
||||
</Items>
|
||||
</Node>
|
||||
</AspectFile>
|
||||
|
|
@ -1868,6 +1868,7 @@ const
|
|||
BAD_TYPE_IN_RUNTIMESIZEOF = 'Bad Type in RunTimeSizeOf';
|
||||
PARAMETER_COUNT_MUST_BE_GREATER_0 = 'Параметр count должен быть > 0!!Parameter count must be > 0';
|
||||
PARAMETER_COUNT_MUST_BE_GREATER_1 = 'Параметр count должен быть > 1!!Parameter count must be > 1';
|
||||
PARAMETER_COUNT_MUST_BE_NOT_EQUAL_0 = 'Параметр step не может быть равен 0!!The step parameter must be not equal to 0';
|
||||
|
||||
// -----------------------------------------------------
|
||||
// WINAPI
|
||||
|
|
@ -8046,13 +8047,52 @@ end;
|
|||
/// Возвращает срез последовательности от номера from с шагом step
|
||||
function Slice<T>(Self: sequence of T; from,step: integer): sequence of T; extensionmethod;
|
||||
begin
|
||||
Result := Self.Skip(from).Where((x,i)->i mod step = 0);
|
||||
if step=0 then
|
||||
raise new ArgumentException(GetTranslation(PARAMETER_COUNT_MUST_BE_NOT_EQUAL_0));
|
||||
if step<0 then
|
||||
begin
|
||||
if from<0 then
|
||||
Result := Self.Take(0)
|
||||
else
|
||||
begin
|
||||
step := -step;
|
||||
var bb := from mod step;
|
||||
Result := Self.Skip(bb).Where((x,i)->(i mod step = 0) and (i<=from-bb)).Reverse;
|
||||
end;
|
||||
end
|
||||
else
|
||||
if from<=0 then
|
||||
Result := Self.Where((x,i)->(i-from) mod step = 0)
|
||||
else Result := Self.Skip(from).Where((x,i)->i mod step = 0);
|
||||
end;
|
||||
|
||||
/// Возвращает срез последовательности от номера from с шагом step длины не более count
|
||||
function Slice<T>(Self: sequence of T; from,step,count: integer): sequence of T; extensionmethod;
|
||||
begin
|
||||
Result := Self.Skip(from).Where((x,i)->i mod step = 0).Take(count);
|
||||
if step=0 then
|
||||
raise new ArgumentException(GetTranslation(PARAMETER_COUNT_MUST_BE_NOT_EQUAL_0));
|
||||
if step<0 then
|
||||
begin
|
||||
if from<0 then
|
||||
Result := Self.Take(0)
|
||||
else
|
||||
begin
|
||||
step := -step;
|
||||
var bb := from - (count - 1)*step;
|
||||
if bb<0 then
|
||||
bb := bb mod step;
|
||||
if bb < 0 then
|
||||
bb += step;
|
||||
Result := Self.Skip(bb).Where((x,i)->(i mod step = 0) and (i<=from-bb)).Reverse;
|
||||
end;
|
||||
end
|
||||
else
|
||||
if from<0 then
|
||||
begin
|
||||
count -= abs(from+1) div step + 1;
|
||||
Result := Self.Where((x,i)->(i-from) mod step = 0).Take(count)
|
||||
end
|
||||
else Result := Self.Skip(from).Where((x,i)->i mod step = 0).Take(count);
|
||||
end;
|
||||
|
||||
// -----------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -3,4 +3,6 @@ CAN_NOT_READ=Can not read data of this type
|
|||
TUPLE_EXPECTED=Tuple expected
|
||||
TOO_MANY_ELEMENTS_ON_LEFT_SIDE_OF_TUPLE_ASSIGNMRNT=Too many elements on the left side of tuple assignment
|
||||
ONLY_BASE_ASSIGNMENT_FOR_TUPLE=Tuple allows only base assignment :=
|
||||
TUPLE_TYPE_ERROR=Bad element in Tuple type
|
||||
TUPLE_TYPE_ERROR=Bad element in Tuple type
|
||||
INTEGER_VALUE_EXPECTED=Integer value expected
|
||||
BAD_SLICE_OBJECT=Slices are allowed for strings, dynamic arrays, lists and sequences only
|
||||
|
|
|
|||
|
|
@ -3,4 +3,6 @@ CAN_NOT_READ=
|
|||
TUPLE_EXPECTED=Ожидался кортеж
|
||||
TOO_MANY_ELEMENTS_ON_LEFT_SIDE_OF_TUPLE_ASSIGNMRNT=Слишком много элементов в левой части при присваивании кортежа
|
||||
ONLY_BASE_ASSIGNMENT_FOR_TUPLE=Для кортежа допустимо только обычное присваивание :=
|
||||
TUPLE_TYPE_ERROR=Ошибочная конструкция при построении типа кортежа
|
||||
TUPLE_TYPE_ERROR=Ошибочная конструкция при построении типа кортежа
|
||||
INTEGER_VALUE_EXPECTED=Ожидалось значение целого типа
|
||||
BAD_SLICE_OBJECT=Срезы допустимы только для строк, динамических массивов, списков и последовательностей
|
||||
|
|
|
|||
Loading…
Reference in a new issue