Срезы на запись для списков и массивов

This commit is contained in:
Александр Погорелов 2019-12-27 10:23:08 +03:00
parent 52e9e82897
commit 9223b2114f
18 changed files with 8376 additions and 2896 deletions

View file

@ -2,7 +2,7 @@
// This CSharp output file generated by Gardens Point LEX
// Version: 1.1.3.301
// Machine: DESKTOP-P4NLNB1
// DateTime: 12/8/2019 2:09:46 PM
// DateTime: 12/24/2019 6:28:32 PM
// UserName: fatco
// GPLEX input file <ABCPascal.lex>
// GPLEX frame file <embedded resource>

File diff suppressed because it is too large Load diff

View file

@ -83,9 +83,9 @@
%type <stn> enumeration_id expr_l1_list
%type <stn> enumeration_id_list
%type <ex> const_simple_expr term simple_term typed_const typed_const_plus typed_var_init_expression expr expr_with_func_decl_lambda const_expr elem range_expr const_elem array_const factor relop_expr expr_dq expr_l1 expr_l1_func_decl_lambda simple_expr range_term range_factor
%type <ex> external_directive_ident init_const_expr case_label variable var_reference /*optional_write_expr*/ optional_read_expr simple_expr_or_nothing var_question_point
%type <ex> external_directive_ident init_const_expr case_label variable var_reference /*optional_write_expr*/ optional_read_expr /*simple_expr_or_nothing*/ var_question_point
%type <ob> for_cycle_type
%type <ex> format_expr format_const_expr const_expr_or_nothing
%type <ex> format_expr format_const_expr const_expr_or_nothing simple_expr_with_deref_or_nothing simple_expr_with_deref
%type <stn> foreach_stmt
%type <stn> for_stmt loop_stmt yield_stmt yield_sequence_stmt
%type <stn> fp_list fp_sect_list
@ -2705,6 +2705,18 @@ assignment
($4 as syntax_tree_node).source_context = LexLocation.MergeAll(@1,@2,@3,@4,@5);
$$ = new assign_tuple($4 as addressed_value_list, $7, @$);
}
| variable tkQuestionSquareOpen format_expr tkSquareClose assign_operator expr
{
var fe = $3 as format_expr;
if (!parsertools.build_tree_for_formatter)
{
if (fe.expr == null)
fe.expr = new int32_const(int.MaxValue,@3);
if (fe.format1 == null)
fe.format1 = new int32_const(int.MaxValue,@3);
}
$$ = new slice_expr_question($1 as addressed_value,fe.expr,fe.format1,fe.format2,@$);
}
;
variable_list
@ -3593,7 +3605,7 @@ pattern_out_param_optional_var
}
;
simple_expr_or_nothing
/*simple_expr_or_nothing
: simple_expr
{
$$ = $1;
@ -3602,7 +3614,7 @@ simple_expr_or_nothing
{
$$ = null;
}
;
;*/
const_expr_or_nothing
: const_expr
@ -3614,23 +3626,69 @@ const_expr_or_nothing
$$ = null;
}
;
simple_expr_with_deref_or_nothing
: tkDeref simple_expr
{
$$ = new simple_expr_with_deref($2, true);
}
| simple_expr
{
$$ = new simple_expr_with_deref($1, false);
}
|
{
$$ = null;
}
;
simple_expr_with_deref
: simple_expr
{
$$ = new simple_expr_with_deref($1, false);
}
| tkDeref simple_expr
{
$$ = new simple_expr_with_deref($2, true);
}
;
format_expr
: simple_expr tkColon simple_expr_or_nothing
: simple_expr_with_deref tkColon simple_expr_with_deref_or_nothing
{
$$ = new format_expr($1, $3, null, @$);
var to_has_deref = $3 is null ? false : ($3 as simple_expr_with_deref).has_deref;
$$ = new format_expr(
($1 as simple_expr_with_deref).simple_expr,
($3 as simple_expr_with_deref)?.simple_expr,
null,
($1 as simple_expr_with_deref).has_deref, to_has_deref, @$);
}
| tkColon simple_expr_or_nothing
| tkColon simple_expr_with_deref_or_nothing
{
$$ = new format_expr(null, $2, null, @$);
var to_has_deref = $2 is null ? false : ($2 as simple_expr_with_deref).has_deref;
$$ = new format_expr(
null,
($2 as simple_expr_with_deref)?.simple_expr,
null,
false, to_has_deref, @$);
}
| simple_expr tkColon simple_expr_or_nothing tkColon simple_expr
| simple_expr_with_deref tkColon simple_expr_with_deref_or_nothing tkColon simple_expr_with_deref
{
$$ = new format_expr($1, $3, $5, @$);
var to_has_deref = $3 is null ? false : ($3 as simple_expr_with_deref).has_deref;
$$ = new format_expr(
($1 as simple_expr_with_deref).simple_expr,
($3 as simple_expr_with_deref)?.simple_expr,
($5 as simple_expr_with_deref).simple_expr,
($1 as simple_expr_with_deref).has_deref, to_has_deref, @$);
}
| tkColon simple_expr_or_nothing tkColon simple_expr
| tkColon simple_expr_with_deref_or_nothing tkColon simple_expr_with_deref
{
$$ = new format_expr(null, $2, $4, @$);
var to_has_deref = $2 is null ? false : ($2 as simple_expr_with_deref).has_deref;
$$ = new format_expr(
null,
($2 as simple_expr_with_deref)?.simple_expr,
($4 as simple_expr_with_deref).simple_expr,
false, to_has_deref, @$);
}
;
@ -3951,7 +4009,7 @@ variable
if (fe.format1 == null)
fe.format1 = new int32_const(int.MaxValue,@3);
}
$$ = new slice_expr($1 as addressed_value,fe.expr,fe.format1,fe.format2,@$);
$$ = new slice_expr($1 as addressed_value,fe.expr,fe.format1,fe.format2,fe.index_inversion_from,fe.index_inversion_to,@$);
}
else $$ = new indexer($1 as addressed_value,el, @$);
}

File diff suppressed because it is too large Load diff

View file

@ -1252,6 +1252,11 @@ namespace PascalABCCompiler.SyntaxTree
{
DefaultVisit(_recursive_tuple_parameter);
}
public virtual void visit(simple_expr_with_deref _simple_expr_with_deref)
{
DefaultVisit(_simple_expr_with_deref);
}
}

View file

@ -1997,6 +1997,14 @@ namespace PascalABCCompiler.SyntaxTree
{
}
public virtual void pre_do_visit(simple_expr_with_deref _simple_expr_with_deref)
{
}
public virtual void post_do_visit(simple_expr_with_deref _simple_expr_with_deref)
{
}
public override void visit(expression _expression)
{
DefaultVisit(_expression);
@ -4123,6 +4131,14 @@ namespace PascalABCCompiler.SyntaxTree
pre_do_visit(_recursive_tuple_parameter);
post_do_visit(_recursive_tuple_parameter);
}
public override void visit(simple_expr_with_deref _simple_expr_with_deref)
{
DefaultVisit(_simple_expr_with_deref);
pre_do_visit(_simple_expr_with_deref);
visit(simple_expr_with_deref.simple_expr);
post_do_visit(_simple_expr_with_deref);
}
}

View file

@ -518,6 +518,8 @@ namespace PascalABCCompiler.SyntaxTree
return new tuple_pattern_var_parameter();
case 248:
return new recursive_tuple_parameter();
case 249:
return new simple_expr_with_deref();
}
return null;
}
@ -2426,6 +2428,8 @@ namespace PascalABCCompiler.SyntaxTree
_format_expr.expr = _read_node() as expression;
_format_expr.format1 = _read_node() as expression;
_format_expr.format2 = _read_node() as expression;
_format_expr.index_inversion_from = br.ReadBoolean();
_format_expr.index_inversion_to = br.ReadBoolean();
}
@ -3835,6 +3839,8 @@ namespace PascalABCCompiler.SyntaxTree
_slice_expr.from = _read_node() as expression;
_slice_expr.to = _read_node() as expression;
_slice_expr.step = _read_node() as expression;
_slice_expr.index_inversion_from = br.ReadBoolean();
_slice_expr.index_inversion_to = br.ReadBoolean();
}
@ -4355,6 +4361,19 @@ namespace PascalABCCompiler.SyntaxTree
read_recursive_pattern_parameter(_recursive_tuple_parameter);
}
public void visit(simple_expr_with_deref _simple_expr_with_deref)
{
read_simple_expr_with_deref(_simple_expr_with_deref);
}
public void read_simple_expr_with_deref(simple_expr_with_deref _simple_expr_with_deref)
{
read_expression(_simple_expr_with_deref);
_simple_expr_with_deref.simple_expr = _read_node() as expression;
_simple_expr_with_deref.has_deref = br.ReadBoolean();
}
}

View file

@ -3491,6 +3491,8 @@ namespace PascalABCCompiler.SyntaxTree
bw.Write((byte)1);
_format_expr.format2.visit(this);
}
bw.Write(_format_expr.index_inversion_from);
bw.Write(_format_expr.index_inversion_to);
}
@ -5957,6 +5959,8 @@ namespace PascalABCCompiler.SyntaxTree
bw.Write((byte)1);
_slice_expr.step.visit(this);
}
bw.Write(_slice_expr.index_inversion_from);
bw.Write(_slice_expr.index_inversion_to);
}
@ -6795,6 +6799,28 @@ namespace PascalABCCompiler.SyntaxTree
write_recursive_pattern_parameter(_recursive_tuple_parameter);
}
public void visit(simple_expr_with_deref _simple_expr_with_deref)
{
bw.Write((Int16)249);
write_simple_expr_with_deref(_simple_expr_with_deref);
}
public void write_simple_expr_with_deref(simple_expr_with_deref _simple_expr_with_deref)
{
write_expression(_simple_expr_with_deref);
if (_simple_expr_with_deref.simple_expr == null)
{
bw.Write((byte)0);
}
else
{
bw.Write((byte)1);
_simple_expr_with_deref.simple_expr.visit(this);
}
bw.Write(_simple_expr_with_deref.has_deref);
}
}

View file

@ -26633,28 +26633,34 @@ namespace PascalABCCompiler.SyntaxTree
///<summary>
///Конструктор с параметрами.
///</summary>
public format_expr(expression _expr,expression _format1,expression _format2)
public format_expr(expression _expr,expression _format1,expression _format2,bool _index_inversion_from,bool _index_inversion_to)
{
this._expr=_expr;
this._format1=_format1;
this._format2=_format2;
this._index_inversion_from=_index_inversion_from;
this._index_inversion_to=_index_inversion_to;
FillParentsInDirectChilds();
}
///<summary>
///Конструктор с параметрами.
///</summary>
public format_expr(expression _expr,expression _format1,expression _format2,SourceContext sc)
public format_expr(expression _expr,expression _format1,expression _format2,bool _index_inversion_from,bool _index_inversion_to,SourceContext sc)
{
this._expr=_expr;
this._format1=_format1;
this._format2=_format2;
this._index_inversion_from=_index_inversion_from;
this._index_inversion_to=_index_inversion_to;
source_context = sc;
FillParentsInDirectChilds();
}
protected expression _expr;
protected expression _format1;
protected expression _format2;
protected bool _index_inversion_from;
protected bool _index_inversion_to;
///<summary>
///
@ -26707,6 +26713,36 @@ namespace PascalABCCompiler.SyntaxTree
}
}
///<summary>
///
///</summary>
public bool index_inversion_from
{
get
{
return _index_inversion_from;
}
set
{
_index_inversion_from=value;
}
}
///<summary>
///
///</summary>
public bool index_inversion_to
{
get
{
return _index_inversion_to;
}
set
{
_index_inversion_to=value;
}
}
/// <summary> Создает копию узла </summary>
public override syntax_tree_node Clone()
@ -26735,6 +26771,8 @@ namespace PascalABCCompiler.SyntaxTree
copy.format2 = (expression)format2.Clone();
copy.format2.Parent = copy;
}
copy.index_inversion_from = index_inversion_from;
copy.index_inversion_to = index_inversion_to;
return copy;
}
@ -45886,24 +45924,28 @@ namespace PascalABCCompiler.SyntaxTree
///<summary>
///Конструктор с параметрами.
///</summary>
public slice_expr(addressed_value _v,expression _from,expression _to,expression _step)
public slice_expr(addressed_value _v,expression _from,expression _to,expression _step,bool _index_inversion_from,bool _index_inversion_to)
{
this._v=_v;
this._from=_from;
this._to=_to;
this._step=_step;
this._index_inversion_from=_index_inversion_from;
this._index_inversion_to=_index_inversion_to;
FillParentsInDirectChilds();
}
///<summary>
///Конструктор с параметрами.
///</summary>
public slice_expr(addressed_value _v,expression _from,expression _to,expression _step,SourceContext sc)
public slice_expr(addressed_value _v,expression _from,expression _to,expression _step,bool _index_inversion_from,bool _index_inversion_to,SourceContext sc)
{
this._v=_v;
this._from=_from;
this._to=_to;
this._step=_step;
this._index_inversion_from=_index_inversion_from;
this._index_inversion_to=_index_inversion_to;
source_context = sc;
FillParentsInDirectChilds();
}
@ -45911,26 +45953,30 @@ namespace PascalABCCompiler.SyntaxTree
///<summary>
///Конструктор с параметрами.
///</summary>
public slice_expr(addressed_value _dereferencing_value,addressed_value _v,expression _from,expression _to,expression _step)
public slice_expr(addressed_value _dereferencing_value,addressed_value _v,expression _from,expression _to,expression _step,bool _index_inversion_from,bool _index_inversion_to)
{
this._dereferencing_value=_dereferencing_value;
this._v=_v;
this._from=_from;
this._to=_to;
this._step=_step;
this._index_inversion_from=_index_inversion_from;
this._index_inversion_to=_index_inversion_to;
FillParentsInDirectChilds();
}
///<summary>
///Конструктор с параметрами.
///</summary>
public slice_expr(addressed_value _dereferencing_value,addressed_value _v,expression _from,expression _to,expression _step,SourceContext sc)
public slice_expr(addressed_value _dereferencing_value,addressed_value _v,expression _from,expression _to,expression _step,bool _index_inversion_from,bool _index_inversion_to,SourceContext sc)
{
this._dereferencing_value=_dereferencing_value;
this._v=_v;
this._from=_from;
this._to=_to;
this._step=_step;
this._index_inversion_from=_index_inversion_from;
this._index_inversion_to=_index_inversion_to;
source_context = sc;
FillParentsInDirectChilds();
}
@ -45938,6 +45984,8 @@ namespace PascalABCCompiler.SyntaxTree
protected expression _from;
protected expression _to;
protected expression _step;
protected bool _index_inversion_from;
protected bool _index_inversion_to;
///<summary>
///
@ -46007,6 +46055,36 @@ namespace PascalABCCompiler.SyntaxTree
}
}
///<summary>
///
///</summary>
public bool index_inversion_from
{
get
{
return _index_inversion_from;
}
set
{
_index_inversion_from=value;
}
}
///<summary>
///
///</summary>
public bool index_inversion_to
{
get
{
return _index_inversion_to;
}
set
{
_index_inversion_to=value;
}
}
/// <summary> Создает копию узла </summary>
public override syntax_tree_node Clone()
@ -46045,6 +46123,8 @@ namespace PascalABCCompiler.SyntaxTree
copy.step = (expression)step.Clone();
copy.step.Parent = copy;
}
copy.index_inversion_from = index_inversion_from;
copy.index_inversion_to = index_inversion_to;
return copy;
}
@ -47064,26 +47144,30 @@ namespace PascalABCCompiler.SyntaxTree
///<summary>
///Конструктор с параметрами.
///</summary>
public slice_expr_question(addressed_value _dereferencing_value,addressed_value _v,expression _from,expression _to,expression _step)
public slice_expr_question(addressed_value _dereferencing_value,addressed_value _v,expression _from,expression _to,expression _step,bool _index_inversion_from,bool _index_inversion_to)
{
this._dereferencing_value=_dereferencing_value;
this._v=_v;
this._from=_from;
this._to=_to;
this._step=_step;
this._index_inversion_from=_index_inversion_from;
this._index_inversion_to=_index_inversion_to;
FillParentsInDirectChilds();
}
///<summary>
///Конструктор с параметрами.
///</summary>
public slice_expr_question(addressed_value _dereferencing_value,addressed_value _v,expression _from,expression _to,expression _step,SourceContext sc)
public slice_expr_question(addressed_value _dereferencing_value,addressed_value _v,expression _from,expression _to,expression _step,bool _index_inversion_from,bool _index_inversion_to,SourceContext sc)
{
this._dereferencing_value=_dereferencing_value;
this._v=_v;
this._from=_from;
this._to=_to;
this._step=_step;
this._index_inversion_from=_index_inversion_from;
this._index_inversion_to=_index_inversion_to;
source_context = sc;
FillParentsInDirectChilds();
}
@ -47124,6 +47208,8 @@ namespace PascalABCCompiler.SyntaxTree
copy.step = (expression)step.Clone();
copy.step.Parent = copy;
}
copy.index_inversion_from = index_inversion_from;
copy.index_inversion_to = index_inversion_to;
return copy;
}
@ -53268,6 +53354,182 @@ namespace PascalABCCompiler.SyntaxTree
}
///<summary>
///
///</summary>
[Serializable]
public partial class simple_expr_with_deref : expression
{
///<summary>
///Конструктор без параметров.
///</summary>
public simple_expr_with_deref()
{
}
///<summary>
///Конструктор с параметрами.
///</summary>
public simple_expr_with_deref(expression _simple_expr,bool _has_deref)
{
this._simple_expr=_simple_expr;
this._has_deref=_has_deref;
FillParentsInDirectChilds();
}
///<summary>
///Конструктор с параметрами.
///</summary>
public simple_expr_with_deref(expression _simple_expr,bool _has_deref,SourceContext sc)
{
this._simple_expr=_simple_expr;
this._has_deref=_has_deref;
source_context = sc;
FillParentsInDirectChilds();
}
protected expression _simple_expr;
protected bool _has_deref;
///<summary>
///
///</summary>
public expression simple_expr
{
get
{
return _simple_expr;
}
set
{
_simple_expr=value;
if (_simple_expr != null)
_simple_expr.Parent = this;
}
}
///<summary>
///
///</summary>
public bool has_deref
{
get
{
return _has_deref;
}
set
{
_has_deref=value;
}
}
/// <summary> Создает копию узла </summary>
public override syntax_tree_node Clone()
{
simple_expr_with_deref copy = new simple_expr_with_deref();
copy.Parent = this.Parent;
if (source_context != null)
copy.source_context = new SourceContext(source_context);
if (attributes != null)
{
copy.attributes = (attribute_list)attributes.Clone();
copy.attributes.Parent = copy;
}
if (simple_expr != null)
{
copy.simple_expr = (expression)simple_expr.Clone();
copy.simple_expr.Parent = copy;
}
copy.has_deref = has_deref;
return copy;
}
/// <summary> Получает копию данного узла корректного типа </summary>
public new simple_expr_with_deref TypedClone()
{
return Clone() as simple_expr_with_deref;
}
///<summary> Заполняет поля Parent в непосредственных дочерних узлах </summary>
public override void FillParentsInDirectChilds()
{
if (attributes != null)
attributes.Parent = this;
if (simple_expr != null)
simple_expr.Parent = this;
}
///<summary> Заполняет поля Parent во всем поддереве </summary>
public override void FillParentsInAllChilds()
{
FillParentsInDirectChilds();
attributes?.FillParentsInAllChilds();
simple_expr?.FillParentsInAllChilds();
}
///<summary>
///Свойство для получения количества всех подузлов без элементов поля типа List
///</summary>
public override Int32 subnodes_without_list_elements_count
{
get
{
return 1;
}
}
///<summary>
///Свойство для получения количества всех подузлов. Подузлом также считается каждый элемент поля типа List
///</summary>
public override Int32 subnodes_count
{
get
{
return 1;
}
}
///<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 simple_expr;
}
return null;
}
set
{
if(subnodes_count == 0 || ind < 0 || ind > subnodes_count-1)
throw new IndexOutOfRangeException();
switch(ind)
{
case 0:
simple_expr = (expression)value;
break;
}
}
}
///<summary>
///Метод для обхода дерева посетителем
///</summary>
///<param name="visitor">Объект-посетитель.</param>
///<returns>Return value is void</returns>
public override void visit(IVisitor visitor)
{
visitor.visit(this);
}
}
}

View file

@ -33,7 +33,14 @@ namespace PascalABCCompiler.SyntaxTree
DirectDescendants
}
public enum SemanticCheckType { MatchedExpression, MatchedExpressionAndType, MatchedExpressionAndExpression, MatchedTuple }
public enum SemanticCheckType
{
MatchedExpression,
MatchedExpressionAndType,
MatchedExpressionAndExpression,
MatchedTuple,
SliceAssignmentTypeCompatibility
}
public partial class syntax_tree_node
{
@ -63,9 +70,9 @@ namespace PascalABCCompiler.SyntaxTree
}*/
// Безопасная версия Replace - не сработает если менять foreach_node на if_node. Плохо
public void ReplaceDescendant<T,T1>(T from, T1 to, Desc d = Desc.All) where T: syntax_tree_node where T1 : T
public void ReplaceDescendant<T, T1>(T from, T1 to, Desc d = Desc.All) where T : syntax_tree_node where T1 : T
{
var ind = FindIndex(from,d);
var ind = FindIndex(from, d);
this[ind] = to;
to.Parent = from.Parent;
}
@ -120,8 +127,8 @@ namespace PascalABCCompiler.SyntaxTree
/// <returns>Коллекция узлов поддерева</returns>
/// <exception cref="NotImplementedException">Выбрасывается при отсутствии реализации для заданного обхода</exception>
public IEnumerable<syntax_tree_node> DescendantNodes(
TraversalType traversalType = TraversalType.PostOrder,
Func<syntax_tree_node, bool> descendIntoChildren = null,
TraversalType traversalType = TraversalType.PostOrder,
Func<syntax_tree_node, bool> descendIntoChildren = null,
bool includeSelf = false)
{
switch (traversalType)
@ -201,18 +208,18 @@ namespace PascalABCCompiler.SyntaxTree
// Если мы не должны посещать потомков узла или уже добавили их в список,
// то не кладем их на стек
if (!ReferenceEquals(lastReturnedNode, node.FindLast(x => x != null)))
if (descendIntoChildren == null ||
descendIntoChildren(node))
for (int childIndex = node.subnodes_count - 1; childIndex >= 0; childIndex--)
{
var child = node[childIndex];
if (descendIntoChildren == null ||
descendIntoChildren(node))
for (int childIndex = node.subnodes_count - 1; childIndex >= 0; childIndex--)
{
var child = node[childIndex];
if (child == null)
continue;
if (child == null)
continue;
stack.Push(child);
isLeafNode = false;
}
stack.Push(child);
isLeafNode = false;
}
if (isLeafNode)
{
@ -300,7 +307,7 @@ namespace PascalABCCompiler.SyntaxTree
}
//------------------------------
public partial class statement_list
public partial class statement_list
{
public statement_list(IEnumerable<statement> sts)
@ -335,7 +342,7 @@ namespace PascalABCCompiler.SyntaxTree
public override string ToString()
{
return "begin " + list.Select(st=>st is empty_statement ? "" : st.ToString()+"; ").Aggregate((s,x)=>s+x)+ "end";
return "begin " + list.Select(st => st is empty_statement ? "" : st.ToString() + "; ").Aggregate((s, x) => s + x) + "end";
}
//-- List members end
}
@ -413,11 +420,11 @@ namespace PascalABCCompiler.SyntaxTree
{
public static un_expr Not(expression ex)
{
return new un_expr(ex, Operators.LogicalNOT);
return new un_expr(ex, Operators.LogicalNOT);
}
public override string ToString()
{
return string.Format("{0} {1}", OperatorServices.ToString(operation_type, LanguageId.PascalABCNET),this.subnode);
return string.Format("{0} {1}", OperatorServices.ToString(operation_type, LanguageId.PascalABCNET), this.subnode);
}
}
@ -461,7 +468,7 @@ namespace PascalABCCompiler.SyntaxTree
{
this.names = name.Split('.').Select(s => new ident(s)).ToList();
}
public override string ToString()
{
var sb = new System.Text.StringBuilder();
@ -481,7 +488,7 @@ namespace PascalABCCompiler.SyntaxTree
public partial class template_type_reference
{
public template_type_reference(string name, template_param_list params_list): this(new named_type_reference(name), params_list)
public template_type_reference(string name, template_param_list params_list) : this(new named_type_reference(name), params_list)
{ }
public override string ToString()
{
@ -546,7 +553,7 @@ namespace PascalABCCompiler.SyntaxTree
public var_def_statement(ident id, type_definition type, SourceContext sc = null) : this(new ident_list(id), type, sc)
{ }
public var_def_statement(ident id, type_definition type, expression iv, SourceContext sc = null) : this(new ident_list(id), type, iv,sc)
public var_def_statement(ident id, type_definition type, expression iv, SourceContext sc = null) : this(new ident_list(id), type, iv, sc)
{ }
public var_def_statement(ident id, expression iv, SourceContext sc = null) : this(new ident_list(id), null, iv, sc)
@ -588,7 +595,7 @@ namespace PascalABCCompiler.SyntaxTree
{
get { return defs; }
}
public static statement_list Empty
{
get { return new statement_list(); }
@ -669,7 +676,7 @@ namespace PascalABCCompiler.SyntaxTree
public partial class label_definitions
{
public label_definitions(params ident[] ids): this(new ident_list(ids))
public label_definitions(params ident[] ids) : this(new ident_list(ids))
{
}
public override string ToString()
@ -688,9 +695,9 @@ namespace PascalABCCompiler.SyntaxTree
public partial class typed_parameters
{
public typed_parameters(ident_list idents, type_definition type): this(idents, type, parametr_kind.none, null)
public typed_parameters(ident_list idents, type_definition type) : this(idents, type, parametr_kind.none, null)
{ }
public typed_parameters(ident id, type_definition type): this(new ident_list(id), type)
public typed_parameters(ident id, type_definition type) : this(new ident_list(id), type)
{ }
public override string ToString()
{
@ -741,7 +748,7 @@ namespace PascalABCCompiler.SyntaxTree
var t = name.meth_name as template_type_name;
template_args = t.template_args;
if (name.meth_name is template_operator_name)
{
{
name.meth_name = new operator_name_ident((name.meth_name as template_operator_name).opname.operator_type, name.meth_name.source_context);
}
else
@ -789,7 +796,7 @@ namespace PascalABCCompiler.SyntaxTree
}
}
public partial class function_header
public partial class function_header
{
public function_header(formal_parameters _parameters, procedure_attributes_list _proc_attributes, method_name _name, where_definition_list _where_defs, type_definition _return_type, SourceContext sc)
: base(_parameters, _proc_attributes, _name, _where_defs, sc)
@ -820,7 +827,7 @@ namespace PascalABCCompiler.SyntaxTree
sb.Remove(0, 9);
sb.Remove(sb.Length - 1, 1);
sb.Insert(0, "function");
if (return_type!=null)
if (return_type != null)
sb.Append(": " + return_type.ToString() + ";");
return sb.ToString();
}
@ -850,8 +857,8 @@ namespace PascalABCCompiler.SyntaxTree
{
get { return new procedure_definition(new constructor(null), block.Empty, null); }
}
public procedure_definition(string name, formal_parameters fp, declarations defs, statement_list code) : this(new procedure_header(name,fp), new block(defs, code))
public procedure_definition(string name, formal_parameters fp, declarations defs, statement_list code) : this(new procedure_header(name, fp), new block(defs, code))
{ }
public procedure_definition(string name, formal_parameters fp, statement_list code) : this(new procedure_header(name, fp), new block(null, code))
@ -923,7 +930,7 @@ namespace PascalABCCompiler.SyntaxTree
{
public unit_or_namespace(string name, SourceContext sc = null)
{
this.name = new ident_list(name,sc);
this.name = new ident_list(name, sc);
}
}
@ -933,7 +940,7 @@ namespace PascalABCCompiler.SyntaxTree
{
Add(new unit_or_namespace(name), sc);
}
public uses_list AddUsesList(uses_list ul, SourceContext sc = null)
{
foreach (var un in ul.units)
@ -1097,8 +1104,8 @@ namespace PascalABCCompiler.SyntaxTree
public partial class property_accessors
{
public property_accessors(ident read_accessor, ident write_accessor, SourceContext sc = null)
: this(new read_accessor_name(read_accessor, null, null), new write_accessor_name(write_accessor, null, null),sc)
public property_accessors(ident read_accessor, ident write_accessor, SourceContext sc = null)
: this(new read_accessor_name(read_accessor, null, null), new write_accessor_name(write_accessor, null, null), sc)
{ }
}
@ -1174,7 +1181,7 @@ namespace PascalABCCompiler.SyntaxTree
public partial class procedure_call
{
public procedure_call(addressed_value _func_name, SourceContext sc=null) : this(_func_name, false, sc) { }
public procedure_call(addressed_value _func_name, SourceContext sc = null) : this(_func_name, false, sc) { }
public procedure_call(ident name)
{
@ -1313,7 +1320,7 @@ namespace PascalABCCompiler.SyntaxTree
{ }
public override string ToString()
{
return "new "+ (this.type != null ? this.type.ToString() : "NOTYPE") + "(" +(this.params_list != null ? this.params_list.ToString() : "NOPARAMS") + ")";
return "new " + (this.type != null ? this.type.ToString() : "NOTYPE") + "(" + (this.params_list != null ? this.params_list.ToString() : "NOPARAMS") + ")";
}
}
@ -1333,7 +1340,7 @@ namespace PascalABCCompiler.SyntaxTree
{
}
public var_statement(ident_list vars, type_definition type): this(new var_def_statement(vars, type))
public var_statement(ident_list vars, type_definition type) : this(new var_def_statement(vars, type))
{
}
@ -1349,11 +1356,11 @@ namespace PascalABCCompiler.SyntaxTree
{
}
public var_statement(ident id, expression iv) :this(new var_def_statement(new ident_list(id), null, iv))
public var_statement(ident id, expression iv) : this(new var_def_statement(new ident_list(id), null, iv))
{
}
public var_statement(ident id, expression iv,SourceContext sc) : this(new var_def_statement(new ident_list(id), null, iv, sc))
public var_statement(ident id, expression iv, SourceContext sc) : this(new var_def_statement(new ident_list(id), null, iv, sc))
{
}
@ -1663,7 +1670,7 @@ namespace PascalABCCompiler.SyntaxTree
}
}
public partial class array_type
public partial class array_type
{
public override string ToString()
{
@ -1671,7 +1678,7 @@ namespace PascalABCCompiler.SyntaxTree
}
}
public partial class function_lambda_definition
public partial class function_lambda_definition
{
public override string ToString()
{
@ -1679,23 +1686,23 @@ namespace PascalABCCompiler.SyntaxTree
if (_ident_list.Count != 1)
s = "(" + s + ")";
var b = this.proc_body.ToString();
return "" + s + " -> "+b;
return "" + s + " -> " + b;
}
}
public partial class nil_const
public partial class nil_const
{
public override string ToString()
{
return "nil";
}
}
public partial class access_modifer_node
public partial class access_modifer_node
{
public override string ToString()
{
return this.access_level.ToString().Replace("_modifier","");
return this.access_level.ToString().Replace("_modifier", "");
}
}
@ -1783,12 +1790,12 @@ namespace PascalABCCompiler.SyntaxTree
public partial class for_node
{
public for_node(ident loop_variable, expression init_value, expression finish_value, statement stmt, SourceContext sc):
this(loop_variable, init_value, finish_value,stmt,for_cycle_type.to, null,null,true)
public for_node(ident loop_variable, expression init_value, expression finish_value, statement stmt, SourceContext sc) :
this(loop_variable, init_value, finish_value, stmt, for_cycle_type.to, null, null, true)
{
}
public override string ToString() => "for var " + this.loop_variable.ToString() + " := " + this.initial_value.ToString() + " to " + this.finish_value.ToString()+" do \n"+this.statements.ToString();
public override string ToString() => "for var " + this.loop_variable.ToString() + " := " + this.initial_value.ToString() + " to " + this.finish_value.ToString() + " do \n" + this.statements.ToString();
}
public partial class loop_stmt
@ -1805,13 +1812,13 @@ namespace PascalABCCompiler.SyntaxTree
{
public bool HasAllExplicitTypes => variables.definitions.All(x => x.vars_type != null);
public desugared_deconstruction(List<var_def_statement> variables, expression target, SourceContext context = null)
public desugared_deconstruction(List<var_def_statement> variables, expression target, SourceContext context = null)
: this(new deconstruction_variables_definition(variables), target, context)
{ }
public var_statement[] WithTypes(type_definition[] types)
{
var_statement[] result = new var_statement[types.Length];
var_statement[] result = new var_statement[types.Length];
Debug.Assert(types.Length == variables.definitions.Count, "Inconsistent types count");
for (int i = 0; i < variables.definitions.Count; i++)
@ -1941,7 +1948,7 @@ namespace PascalABCCompiler.SyntaxTree
curr_dot_node.left = type.names[0];
}
pattern_expressions.Add(pattern_expr, type.source_context);
}
}
else if (elem is expression expr)
{
pattern_expressions.Add(expr, elem.source_context);
@ -1958,5 +1965,46 @@ namespace PascalABCCompiler.SyntaxTree
{
public override string ToString() => "<proc_type>";
}
}
public partial class format_expr : addressed_value
{
///<summary>
///Конструктор с параметрами.
///</summary>
public format_expr(expression _expr, expression _format1, expression _format2)
: this(_expr, _format1, _format2, false, false) { }
///<summary>
///Конструктор с параметрами.
///</summary>
public format_expr(expression _expr, expression _format1, expression _format2, SourceContext _sourceContext)
: this(_expr, _format1, _format2, false, false, _sourceContext) { }
}
public partial class slice_expr : dereference
{
///<summary>
///Конструктор с параметрами.
///</summary>
public slice_expr(addressed_value _v, expression _from, expression _to, expression _step)
: this(_v, _from, _to, _step, false, false) { }
///<summary>
///Конструктор с параметрами.
///</summary>
public slice_expr(addressed_value _v, expression _from, expression _to, expression _step, SourceContext sc)
: this(_v, _from, _to, _step, false, false, sc) { }
///<summary>
///Конструктор с параметрами.
///</summary>
public slice_expr(addressed_value _dereferencing_value, addressed_value _v, expression _from, expression _to, expression _step)
: this(_dereferencing_value, _v, _from, _to, _step, false, false) { }
///<summary>
///Конструктор с параметрами.
///</summary>
public slice_expr(addressed_value _dereferencing_value, addressed_value _v, expression _from, expression _to, expression _step, SourceContext sc)
: this(_dereferencing_value, _v, _from, _to, _step, false, false, sc) { }
}
}

View file

@ -1498,6 +1498,12 @@ namespace PascalABCCompiler.SyntaxTree
///<param name="_recursive_tuple_parameter">Node to visit</param>
///<returns> Return value is void </returns>
void visit(recursive_tuple_parameter _recursive_tuple_parameter);
///<summary>
///Method to visit simple_expr_with_deref.
///</summary>
///<param name="_simple_expr_with_deref">Node to visit</param>
///<returns> Return value is void </returns>
void visit(simple_expr_with_deref _simple_expr_with_deref);
}

View file

@ -1642,6 +1642,8 @@
<SyntaxField Name="expr" SyntaxType="expression" />
<SyntaxField Name="format1" SyntaxType="expression" />
<SyntaxField Name="format2" SyntaxType="expression" />
<ExtendedField Name="index_inversion_from" Type="bool" CreateVariable="false" DeleteVariable="false" />
<ExtendedField Name="index_inversion_to" Type="bool" CreateVariable="false" DeleteVariable="false" />
</Fields>
<Methods />
<Tags>
@ -2740,6 +2742,8 @@
<SyntaxField Name="from" SyntaxType="expression" />
<SyntaxField Name="to" SyntaxType="expression" />
<SyntaxField Name="step" SyntaxType="expression" />
<ExtendedField Name="index_inversion_from" Type="bool" CreateVariable="false" DeleteVariable="false" />
<ExtendedField Name="index_inversion_to" Type="bool" CreateVariable="false" DeleteVariable="false" />
</Fields>
<Methods />
<Tags>
@ -3225,6 +3229,21 @@
</TagIndices>
</Tags>
</SyntaxNode>
<SyntaxNode Name="simple_expr_with_deref" BaseName="expression">
<Fields>
<SyntaxField Name="simple_expr" SyntaxType="expression" />
<ExtendedField Name="has_deref" Type="bool" CreateVariable="false" DeleteVariable="false" />
</Fields>
<Methods />
<Tags>
<CategoryIndices>
<CategoryIndex>0</CategoryIndex>
</CategoryIndices>
<TagIndices>
<TagIndex>11</TagIndex>
</TagIndices>
</Tags>
</SyntaxNode>
</SyntaxNodes>
<Settings>
<FileName>Tree.cs</FileName>
@ -3252,6 +3271,7 @@
<Tag Name="Yield" ReferenceCount="8" />
<Tag Name="Patterns" ReferenceCount="25" />
<Tag Name="Typeclasses" ReferenceCount="13" />
<Tag Name="slice" ReferenceCount="2" />
</Tags>
</FilterCategory>
</TagCategories>
@ -3287,6 +3307,7 @@
<HelpData Key=".from" Value="" />
<HelpData Key=".guardstats" Value="" />
<HelpData Key=".handlers" Value="" />
<HelpData Key=".has_deref" Value="" />
<HelpData Key=".i" Value="" />
<HelpData Key=".item_expression" Value="" />
<HelpData Key=".left" Value="" />
@ -3310,6 +3331,7 @@
<HelpData Key=".restriction_args" Value="" />
<HelpData Key=".right" Value="" />
<HelpData Key=".sharp_consts" Value="Список символьных констант в строке вида #123#124#125" />
<HelpData Key=".simple_expr" Value="" />
<HelpData Key=".specificator" Value="" />
<HelpData Key=".stat" Value="" />
<HelpData Key=".statements" Value="" />
@ -3765,6 +3787,8 @@
<HelpData Key="format_expr.expr" Value="" />
<HelpData Key="format_expr.format1" Value="" />
<HelpData Key="format_expr.format2" Value="" />
<HelpData Key="format_expr.index_inversion_from" Value="" />
<HelpData Key="format_expr.index_inversion_to" Value="" />
<HelpData Key="forward_directive" Value="" />
<HelpData Key="forward_directr" Value="" />
<HelpData Key="fptype_and_expr" Value="" />
@ -4353,6 +4377,9 @@
<HelpData Key="simple_const_definition" Value="" />
<HelpData Key="simple_const_definition." Value="" />
<HelpData Key="simple_const_definition.simple_const_definition(ident name, expression value, SourceContext sc)" Value="" />
<HelpData Key="simple_expr_with_deref" Value="" />
<HelpData Key="simple_expr_with_deref.has_deref" Value="" />
<HelpData Key="simple_expr_with_deref.simple_expr" Value="" />
<HelpData Key="simple_property" Value="property property_name[parameter_list]:property_type index index_expression accessors; [virtual;] array_default;" />
<HelpData Key="simple_property." Value="" />
<HelpData Key="simple_property.accessors" Value="" />
@ -4375,6 +4402,8 @@
<HelpData Key="sizeof_operator.type_name" Value="" />
<HelpData Key="slice_expr" Value="" />
<HelpData Key="slice_expr.from" Value="" />
<HelpData Key="slice_expr.index_inversion_from" Value="" />
<HelpData Key="slice_expr.index_inversion_to" Value="" />
<HelpData Key="slice_expr.step" Value="" />
<HelpData Key="slice_expr.to" Value="" />
<HelpData Key="slice_expr.v" Value="" />

View file

@ -40,20 +40,38 @@ namespace SyntaxVisitors.SugarVisitors
el.Add(sl.to);
if (sl.step != null)
el.Add(sl.step);
el.Add(new bool_const(sl.index_inversion_from));
el.Add(new bool_const(sl.index_inversion_to));
return el;
}
public override void visit(slice_expr sl)
{
var el = construct_expression_list_for_slice_expr(sl);
// Проблема в том, что тут тоже надо перепрошивать Parent!
var mc = method_call.NewP(dot_node.NewP(sl.v, new ident("SystemSlice", sl.v.source_context), sl.v.source_context), el, sl.source_context);
var sug = sugared_addressed_value.NewP(sl, mc, sl.source_context);
ReplaceUsingParent(sl, sug);
visit(mc); // обойти заменённое на предмет наличия такого же синтаксического сахара
if (sl.Parent is assign parent_assign && parent_assign.to == sl)
{
el.Insert(0, parent_assign.from);
var systemSliceAssignmentCall = new procedure_call(
method_call.NewP(
dot_node.NewP(
sl.v,
new ident("SystemSliceAssignment", sl.v.source_context),
sl.v.source_context),
el, sl.source_context),
sl.source_context);
var typeCompatibilityCheck = GetAssignmentTypeCompatibilityCheck(sl.v, parent_assign.from);
var checkAndDesugaredSliceBlock = new statement_list(typeCompatibilityCheck, systemSliceAssignmentCall);
checkAndDesugaredSliceBlock.source_context = sl.source_context;
ReplaceUsingParent(parent_assign, checkAndDesugaredSliceBlock);
}
else
{
// Проблема в том, что тут тоже надо перепрошивать Parent!
var mc = method_call.NewP(dot_node.NewP(sl.v, new ident("SystemSlice", sl.v.source_context), sl.v.source_context), el, sl.source_context);
var sug = sugared_addressed_value.NewP(sl, mc, sl.source_context);
ReplaceUsingParent(sl, sug);
visit(mc); // обойти заменённое на предмет наличия такого же синтаксического сахара
}
}
public override void visit(slice_expr_question sl)
@ -67,5 +85,7 @@ namespace SyntaxVisitors.SugarVisitors
visit(mc); // обойти заменённое на предмет наличия такого же синтаксического сахара
}
private semantic_check_sugared_statement_node GetAssignmentTypeCompatibilityCheck(expression expression1, expression expression2) =>
new semantic_check_sugared_statement_node(SemanticCheckType.SliceAssignmentTypeCompatibility, new List<syntax_tree_node>() { expression1, expression2 });
}
}

View file

@ -52,7 +52,7 @@ namespace PascalABCCompiler.TreeConverter
var v = (mc.dereferencing_value as dot_node).left;
var from = mc.parameters.expressions[1];
var to = mc.parameters.expressions[2];
expression step = mc.parameters.expressions.Count > 3 ? mc.parameters.expressions[3] : null;
expression step = mc.parameters.expressions.Count > 5 ? mc.parameters.expressions[3] : null;
var semvar = convert_strong(v);
if (semvar is typed_expression)
@ -125,5 +125,18 @@ namespace PascalABCCompiler.TreeConverter
if (!b)
AddError(sem_ex.location, "INTEGER_VALUE_EXPECTED");
}
public void semantic_check_slice_assignment_types(SyntaxTree.expression expr1, SyntaxTree.expression expr2)
{
var leftValue = convert_strong(expr1);
var leftType = leftValue.type;
var rightValue = convert_strong(expr2);
var rightType = rightValue.type;
if (AreTheSameType(leftType, rightType))
return;
AddError(get_location(expr2), "EXPRESSION_OF_TYPE_{0}_CANNOT_BE_ASSIGNED_TO_SLICE_OF_TYPE_{1}", rightType.PrintableName, leftType.PrintableName);
}
}
}

View file

@ -20330,6 +20330,14 @@ namespace PascalABCCompiler.TreeConverter
CheckIfCanBeMatched(tuple, length);
}
// !Patterns
// Slices
else if (st.typ is SemanticCheckType.SliceAssignmentTypeCompatibility)
{
var to = st.lst[0] as expression;
var from = st.lst[1] as expression;
semantic_check_slice_assignment_types(to, from);
}
// !Slices
else
{
AddError(get_location(st), "MISSED_SEMANTIC_CHECK_FOR_SUGARED_NODE_{0}", (st.typ as System.Type)?.Name ?? "Unknown");

View file

@ -14,6 +14,12 @@ begin
Result := 'ru';
end;
procedure p();
begin
var s := 'sdfh';
s[1] := 'd';
end;
function GetTranslation(message: string): string;
begin
var cur_locale := GetCurrentLocale();

View file

@ -2383,6 +2383,7 @@ const
BAD_ROW_INDEX_TO = 'ToRow выходит за пределы индексов строк двумерного массива!!ToRow is out of range of 2-dim array row indexes';
BAD_COL_INDEX_FROM = 'FromCol выходит за пределы индексов строк двумерного массива!!FromCol is out of range of 2-dim array column indexes';
BAD_COL_INDEX_TO = 'ToCol выходит за пределы индексов строк двумерного массива!!ToCol is out of range of 2-dim array column indexes';
SLICE_SIZE_AND_RIGHT_VALUE_SIZE_MUST_BE_EQUAL = 'Размеры среза и присваиваемого выражения должны быть равны!!Slice size and assigned expression size must be equal';
// -----------------------------------------------------
// WINAPI
@ -9703,17 +9704,61 @@ begin
end;
///--
function SystemSlice<T>(Self: List<T>; situation: integer; from, &to: integer): List<T>; extensionmethod;
function SystemSlice<T>(Self: List<T>; situation: integer; from, &to: integer; inverseFrom, inverseTo: boolean): List<T>; extensionmethod;
begin
if inverseFrom then
from := Self.Count - from;
if inverseTo then
&to := Self.Count - &to;
Result := SystemSliceListImpl(Self, situation, from, &to, 1);
end;
///--
function SystemSlice<T>(Self: List<T>; situation: integer; from, &to, step: integer): List<T>; extensionmethod;
function SystemSlice<T>(Self: List<T>; situation: integer; from, &to, step: integer; inverseFrom, inverseTo: boolean): List<T>; extensionmethod;
begin
if inverseFrom then
from := Self.Count - from;
if inverseTo then
&to := Self.Count - &to;
Result := SystemSliceListImpl(Self, situation, from, &to, step);
end;
///--
procedure SystemSliceAssignmentListImpl<T>(Self: List<T>; rightValue: List<T>; situation: integer; from, &to: integer; step: integer := 1);
begin
var count := CheckAndCorrectFromToAndCalcCountForSystemSlice(situation, Self.Count, from, &to, step);
if count <> rightValue.Count then
raise new System.ArgumentException(GetTranslation(SLICE_SIZE_AND_RIGHT_VALUE_SIZE_MUST_BE_EQUAL));
var f := from;
var i := 0;
loop count do
begin
Self[f] := rightValue[i];
f += step;
i += 1;
end;
end;
///--
procedure SystemSliceAssignment<T>(Self: List<T>; rightValue: List<T>; situation: integer; from, &to: integer; inverseFrom, inverseTo: boolean); extensionmethod;
begin
if inverseFrom then
from := Self.Count - from;
if inverseTo then
&to := Self.Count - &to;
SystemSliceAssignmentListImpl(Self, rightValue, situation, from, &to, 1);
end;
///--
procedure SystemSliceAssignment<T>(Self: List<T>; rightValue: List<T>; situation: integer; from, &to, step: integer; inverseFrom, inverseTo: boolean); extensionmethod;
begin
if inverseFrom then
from := Self.Count - from;
if inverseTo then
&to := Self.Count - &to;
SystemSliceAssignmentListImpl(Self, rightValue, situation, from, &to, step);
end;
///--
function SystemSliceListImplQuestion<T>(Self: List<T>; situation: integer; from, &to: integer; step: integer := 1): List<T>;
begin
@ -10484,17 +10529,61 @@ begin
end;
///--
function SystemSlice<T>(Self: array of T; situation: integer; from, &to: integer): array of T; extensionmethod;
function SystemSlice<T>(Self: array of T; situation: integer; from, &to: integer; inverseFrom, inverseTo: boolean): array of T; extensionmethod;
begin
if inverseFrom then
from := Self.Length - from;
if inverseTo then
&to := Self.Length - &to;
Result := SystemSliceArrayImpl(Self, situation, from, &to, 1);
end;
///--
function SystemSlice<T>(Self: array of T; situation: integer; from, &to, step: integer): array of T; extensionmethod;
function SystemSlice<T>(Self: array of T; situation: integer; from, &to, step: integer; inverseFrom, inverseTo: boolean): array of T; extensionmethod;
begin
if inverseFrom then
from := Self.Length - from;
if inverseTo then
&to := Self.Length - &to;
Result := SystemSliceArrayImpl(Self, situation, from, &to, step);
end;
///--
procedure SystemSliceAssignmentArrayImpl<T>(Self: array of T; rightValue: array of T; situation: integer; from, &to: integer; step: integer := 1);
begin
var count := CheckAndCorrectFromToAndCalcCountForSystemSlice(situation, Self.Length, from, &to, step);
if count <> rightValue.Length then
raise new System.ArgumentException(GetTranslation(SLICE_SIZE_AND_RIGHT_VALUE_SIZE_MUST_BE_EQUAL));
var f := from;
var i := 0;
loop count do
begin
Self[f] := rightValue[i];
f += step;
i += 1;
end;
end;
///--
procedure SystemSliceAssignment<T>(Self: array of T; rightValue: array of T; situation: integer; from, &to: integer; inverseFrom, inverseTo: boolean); extensionmethod;
begin
if inverseFrom then
from := Self.Length - from;
if inverseTo then
&to := Self.Length - &to;
SystemSliceAssignmentArrayImpl(Self, rightValue, situation, from, &to, 1);
end;
///--
procedure SystemSliceAssignment<T>(Self: array of T; rightValue: array of T; situation: integer; from, &to, step: integer; inverseFrom, inverseTo: boolean); extensionmethod;
begin
if inverseFrom then
from := Self.Length - from;
if inverseTo then
&to := Self.Length - &to;
SystemSliceAssignmentArrayImpl(Self, rightValue, situation, from, &to, step);
end;
///--
function SystemSliceArrayImplQuestion<T>(Self: array of T; situation: integer; from, &to: integer; step: integer := 1): array of T;
begin
@ -10993,17 +11082,74 @@ begin
end;
///--
function SystemSlice(Self: string; situation: integer; from, &to: integer): string; extensionmethod;
function SystemSlice(Self: string; situation: integer; from, &to: integer; inverseFrom, inverseTo: boolean): string; extensionmethod;
begin
if inverseFrom then
from := Self.Length - from;
if inverseTo then
&to := Self.Length - &to;
Result := SystemSliceStringImpl(Self, situation, from, &to, 1);
end;
///--
function SystemSlice(Self: string; situation: integer; from, &to, step: integer): string; extensionmethod;
function SystemSlice(Self: string; situation: integer; from, &to, step: integer; inverseFrom, inverseTo: boolean): string; extensionmethod;
begin
if inverseFrom then
from := Self.Length - from;
if inverseTo then
&to := Self.Length - &to;
Result := SystemSliceStringImpl(Self, situation, from, &to, step);
end;
///--
procedure SystemSliceAssignmentStringImpl(Self: string; rightValue: string; situation: integer; from, &to: integer; step: integer := 1);
begin
var count := CheckAndCorrectFromToAndCalcCountForSystemSlice(situation, Self.Count, from, &to, step);
if count <> rightValue.Length then
raise new System.ArgumentException(GetTranslation(SLICE_SIZE_AND_RIGHT_VALUE_SIZE_MUST_BE_EQUAL));
var f := from;
var temp := new char[Self.Length];
for var i := 0 to Self.Length - 1 do
temp[i] := Self[i+1];
var strInd := 1;
loop count do
begin
temp[f] := rightValue[strInd];
f += step;
strInd += 1;
end;
//var res := new StringBuilder(Self.Length);
//for var i := 0 to Self.Length - 1 do
//Self[i] := temp[i];
end;
///--
procedure SystemSliceAssignment(Self: string; rightValue: string; situation: integer; from, &to: integer; inverseFrom, inverseTo: boolean); extensionmethod;
begin
if inverseFrom then
from := Self.Length - from;
if inverseTo then
&to := Self.Length - &to;
//Self[1] := 'a';
var s2 := 'string';
//s2[1] := 'a';
SystemSliceAssignmentStringImpl(Self, rightValue, situation, from, &to, 1);
end;
///--
procedure SystemSliceAssignment(Self: string; rightValue: string; situation: integer; from, &to, step: integer; inverseFrom, inverseTo: boolean); extensionmethod;
begin
if inverseFrom then
from := Self.Length - from;
if inverseTo then
&to := Self.Length - &to;
SystemSliceAssignmentStringImpl(Self, rightValue, situation, from, &to, step);
end;
///--
function SystemSliceStringImplQuestion(Self: string; situation: integer; from, &to: integer; step: integer := 1): string;
begin

View file

@ -9,4 +9,5 @@ DECONSTRUCTION_PARAMETERS_SHOULD_HAVE_VAR_MODIFIER=Параметры декон
PATTERN_MATCHING_DOESNT_SUPPORT_POINTERS=Сопоставление с образцом не поддерживает указатели в данной версии компилятора
EXPRESSION_OF_TYPE_{0}_CANNOT_BE_MATCHED_AGAINST_PATTERN_WITH_TYPE_{1}= Выражение типа {0} не может быть сопоставлено с образцом типа {1}
DECONSTRUCTOR_SHOULD_NOT_BE_STATIC=Деконструктор не может быть статическим
MATCHING_WITH_NON_CONST=Выражение для сопоставления должно иметь константное значение
MATCHING_WITH_NON_CONST=Выражение для сопоставления должно иметь константное значение
EXPRESSION_OF_TYPE_{0}_CANNOT_BE_ASSIGNED_TO_SLICE_OF_TYPE_{1}=Выражение типа {0} не может быть присвоено срезу с типом {1}