Кое-какие правки для реализации синтаксического сахара

This commit is contained in:
miks1965 2017-01-10 21:18:40 +03:00
parent 32cc3ed88f
commit 1557775799
14 changed files with 192 additions and 270 deletions

View file

@ -15,7 +15,7 @@ internal static class RevisionClass
public const string Major = "3";
public const string Minor = "2";
public const string Build = "0";
public const string Revision = "1372";
public const string Revision = "1373";
public const string MainVersion = Major + "." + Minor;
public const string FullVersion = Major + "." + Minor + "." + Build + "." + Revision;

View file

@ -1,4 +1,4 @@
%MINOR%=2
%REVISION%=1372
%COREVERSION%=0
%REVISION%=1373
%MINOR%=2
%MAJOR%=3

View file

@ -1341,12 +1341,21 @@
</Node>
<Node Name="[::]" NL="0" NG="0">
<Items>
<Node Name="visit(slice_expr" NL="0,9521484" NG="-1">
<FileName>\treeconverter\treeconversion\syntax_tree_visitor.cs</FileName>
<Text>public override void visit(SyntaxTree.slice_expr sl)</Text>
<Node ID="visit" Name="visit(slice_expr" NL="0,9521484" NG="-1">
<FileName>\TreeConverter\TreeConversion\syntax_tree_visitor.cs</FileName>
<OCtx>
<i Type="Method">public override void visit ( SyntaxTree . slice_expr sl )</i>
<i Type="ClassOrNamespace">public class syntax_tree_visitor : SyntaxTree . WalkingVisitorNew</i>
<i Type="ClassOrNamespace">public partial class syntax_tree_visitor : SyntaxTree . WalkingVisitorNew</i>
<i Type="ClassOrNamespace">namespace PascalABCCompiler . TreeConverter</i>
<i Type="CS_TreeNode">
</i>
</OCtx>
</Node>
<Node ID="visit" Name="visit(slice_expr_question" NL="0,9521484" NG="-1">
<FileName>\TreeConverter\TreeConversion\syntax_tree_visitor.cs</FileName>
<OCtx>
<i Type="Method">public override void visit ( SyntaxTree . slice_expr_question sl )</i>
<i Type="ClassOrNamespace">public partial class syntax_tree_visitor : SyntaxTree . WalkingVisitorNew</i>
<i Type="ClassOrNamespace">namespace PascalABCCompiler . TreeConverter</i>
<i Type="CS_TreeNode">
</i>

View file

@ -1 +1 @@
!define VERSION '3.2.0.1372'
!define VERSION '3.2.0.1373'

View file

@ -3612,10 +3612,6 @@ namespace PascalABCCompiler.SyntaxTree
{
DefaultVisit(_slice_expr_question);
pre_do_visit(_slice_expr_question);
visit(slice_expr_question.v);
visit(slice_expr_question.from);
visit(slice_expr_question.to);
visit(slice_expr_question.step);
post_do_visit(_slice_expr_question);
}
}

View file

@ -3841,11 +3841,7 @@ namespace PascalABCCompiler.SyntaxTree
public void read_slice_expr_question(slice_expr_question _slice_expr_question)
{
read_dereference(_slice_expr_question);
_slice_expr_question.v = _read_node() as addressed_value;
_slice_expr_question.from = _read_node() as expression;
_slice_expr_question.to = _read_node() as expression;
_slice_expr_question.step = _read_node() as expression;
read_slice_expr(_slice_expr_question);
}
}

View file

@ -6000,43 +6000,7 @@ namespace PascalABCCompiler.SyntaxTree
public void write_slice_expr_question(slice_expr_question _slice_expr_question)
{
write_dereference(_slice_expr_question);
if (_slice_expr_question.v == null)
{
bw.Write((byte)0);
}
else
{
bw.Write((byte)1);
_slice_expr_question.v.visit(this);
}
if (_slice_expr_question.from == null)
{
bw.Write((byte)0);
}
else
{
bw.Write((byte)1);
_slice_expr_question.from.visit(this);
}
if (_slice_expr_question.to == null)
{
bw.Write((byte)0);
}
else
{
bw.Write((byte)1);
_slice_expr_question.to.visit(this);
}
if (_slice_expr_question.step == null)
{
bw.Write((byte)0);
}
else
{
bw.Write((byte)1);
_slice_expr_question.step.visit(this);
}
write_slice_expr(_slice_expr_question);
}
}

View file

@ -38362,7 +38362,7 @@ namespace PascalABCCompiler.SyntaxTree
///
///</summary>
[Serializable]
public partial class slice_expr_question : dereference
public partial class slice_expr_question : slice_expr
{
///<summary>
@ -38373,28 +38373,6 @@ namespace PascalABCCompiler.SyntaxTree
}
///<summary>
///Конструктор с параметрами.
///</summary>
public slice_expr_question(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_question(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>
///Конструктор с параметрами.
@ -38420,72 +38398,6 @@ namespace PascalABCCompiler.SyntaxTree
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> Создает копию узла </summary>
public override syntax_tree_node Clone()
{

View file

@ -1621,7 +1621,6 @@ namespace PascalABCCompiler.SyntaxTree
public partial class expression
{
public object semantic_ex = null; // 3.01.17 convert_strong, вызванная первый раз, заполняет это поле, а потом только обращается к нему
public expression Plus(expression e)
{
return new bin_expr(this, e, Operators.Plus);
@ -1636,5 +1635,13 @@ namespace PascalABCCompiler.SyntaxTree
}
}
public partial class slice_expr_question
{
public slice_expr_question(addressed_value v, expression from, expression to, expression step) : base(v, from, to, step)
{ }
public slice_expr_question(addressed_value v, expression from, expression to, expression step, SourceContext sc) : base(v, from, to, step, sc)
{ }
}
}

Binary file not shown.

View file

@ -216,10 +216,10 @@ type
Predicate<T> = System.Predicate<T>;
/// Представляет функцию с двумя параметрами, возвращающую boolean
Predicate2<T1,T2> = System.Predicate<T1,T2>;
Predicate2<T1,T2> = function(x1: T1; x2: T2): boolean;
/// Представляет функцию с тремя параметрами, возвращающую boolean
Predicate3<T1,T2,T3> = System.Predicate<T1,T2,T3>;
Predicate3<T1,T2,T3> = function(x1: T1; x2: T2; x3: T3): boolean;
/// Представляет регулярное выражение
Regex = System.Text.RegularExpressions.Regex;
@ -8603,8 +8603,64 @@ begin
Result := Self;
end;
procedure CorrectFromTo(situation: integer; Len: integer; var from,&to: integer; step: integer);
begin
if step>0 then
begin
case situation of
1: from := 0;
2: &to := Len;
3: begin
from := 0;
&to := Len;
end;
end;
end
else
begin
case situation of
1: from := Len - 1;
2: &to := -1;
3: begin
from := Len - 1;
&to := -1;
end;
end;
end;
end;
///--
function CalcCountForSystemSlice(situation: integer; Len: integer; var from,&to: integer; step: integer): integer;
function CorrectFromToAndCalcCountForSystemSliceQuestion(situation: integer; Len: integer; var from,&to: integer; step: integer): integer;
begin
if step = 0 then
raise new ArgumentException(GetTranslation(PARAMETER_STEP_MUST_BE_NOT_EQUAL_0));
CorrectFromTo(situation,Len,from,&to,step);
if step>0 then
begin
if from<0 then
from += (step - from - 1) div step * step;
// from может оказаться > Len - 1
var m := min(Len,&to);
if from >= m then
Result := 0
else Result := (m - from - 1) div step + 1
end
else
begin
if from > Len - 1 then
from -= (from - Len - step) div step * step;
// from может оказаться < 0
var m := max(&to,-1);
if from <= m then
Result := 0
else Result := (from - m - 1) div (-step) + 1
end;
end;
///--
function CheckAndCorrectFromToAndCalcCountForSystemSlice(situation: integer; Len: integer; var from,&to: integer; step: integer): integer;
begin
// situation = 0 - все параметры присутствуют
// situation = 1 - from отсутствует
@ -8621,19 +8677,12 @@ begin
if (&to < -1) or (&to > Len) then
raise new ArgumentException(GetTranslation(PARAMETER_TO_OUT_OF_RANGE));
CorrectFromTo(situation,Len,from,&to,step);
var count: integer;
if step>0 then
begin
case situation of
1: from := 0;
2: &to := Len;
3: begin
from := 0;
&to := Len;
end;
end;
var cnt := &to - from;
if cnt<=0 then
count := 0
@ -8641,27 +8690,40 @@ begin
end
else
begin
case situation of
1: from := Len - 1;
2: &to := -1;
3: begin
from := Len - 1;
&to := -1;
end;
end;
var cnt := from - &to;
if cnt<=0 then
count := 0
else count := (cnt-1) div (-step) + 1;
end;
Result := count;
end;
///--
procedure CheckStepAndCorrectFromTo(situation: integer; Len: integer; var from,&to: integer; step: integer);
begin
// situation = 0 - все параметры присутствуют
// situation = 1 - from отсутствует
// situation = 2 - to отсутствует
// situation = 3 - from и to отсутствуют
if step = 0 then
raise new ArgumentException(GetTranslation(PARAMETER_STEP_MUST_BE_NOT_EQUAL_0));
{if (situation=0) or (situation=2) then
if (from < 0) or (from > Len - 1) then
raise new ArgumentException(GetTranslation(PARAMETER_FROM_OUT_OF_RANGE));
if (situation=0) or (situation=1) then
if (&to < -1) or (&to > Len) then
raise new ArgumentException(GetTranslation(PARAMETER_TO_OUT_OF_RANGE));}
CorrectFromTo(situation,Len,from,&to,step);
end;
///--
function SystemSliceListImpl<T>(Self: List<T>; situation: integer; from,&to: integer; step: integer := 1): List<T>;
begin
var count := CalcCountForSystemSlice(situation,Self.Count,from,&to,step);
var count := CheckAndCorrectFromToAndCalcCountForSystemSlice(situation,Self.Count,from,&to,step);
Result := CreateSliceFromListInternal(Self,from,step,count);
end;
@ -8678,6 +8740,25 @@ begin
Result := SystemSliceListImpl(Self,situation,from,&to,step);
end;
///--
function SystemSliceListImplQuestion<T>(Self: List<T>; situation: integer; from,&to: integer; step: integer := 1): List<T>;
begin
var count := CorrectFromToAndCalcCountForSystemSliceQuestion(situation,Self.Count,from,&to,step);
Result := CreateSliceFromListInternal(Self,from,step,count);
end;
///--
function SystemSliceQuestion<T>(Self: List<T>; situation: integer; from,&to: integer): List<T>; extensionmethod;
begin
Result := SystemSliceListImplQuestion(Self,situation,from,&to,1);
end;
///--
function SystemSliceQuestion<T>(Self: List<T>; situation: integer; from,&to,step: integer): List<T>; extensionmethod;
begin
Result := SystemSliceListImplQuestion(Self,situation,from,&to,step);
end;
// -----------------------------------------------------
//>> Методы расширения типа array [,] of T # Extension methods for array [,] of T
// -----------------------------------------------------
@ -9220,7 +9301,7 @@ end;
///--
function SystemSliceArrayImpl<T>(Self: array of T; situation: integer; from,&to: integer; step: integer := 1): array of T;
begin
var count := CalcCountForSystemSlice(situation,Self.Length,from,&to,step);
var count := CheckAndCorrectFromToAndCalcCountForSystemSlice(situation,Self.Length,from,&to,step);
Result := CreateSliceFromArrayInternal(Self,from,step,count)
end;
@ -9237,6 +9318,26 @@ begin
Result := SystemSliceArrayImpl(Self,situation,from,&to,step);
end;
///--
function SystemSliceArrayImplQuestion<T>(Self: array of T; situation: integer; from,&to: integer; step: integer := 1): array of T;
begin
var count := CorrectFromToAndCalcCountForSystemSliceQuestion(situation,Self.Length,from,&to,step);
Result := CreateSliceFromArrayInternal(Self,from,step,count);
end;
///--
function SystemSliceQuestion<T>(Self: array of T; situation: integer; from,&to: integer): array of T; extensionmethod;
begin
Result := SystemSliceArrayImplQuestion(Self,situation,from,&to,1);
end;
///--
function SystemSliceQuestion<T>(Self: array of T; situation: integer; from,&to,step: integer): array of T; extensionmethod;
begin
Result := SystemSliceArrayImplQuestion(Self,situation,from,&to,step);
end;
// -----------------------------------------------------
//>> Методы расширения типа integer # Extension methods for integer
// -----------------------------------------------------
@ -9588,7 +9689,7 @@ function SystemSliceStringImpl(Self: string; situation: integer; from,&to: integ
begin
var fromv := from-1;
var tov := &to-1;
var count := CalcCountForSystemSlice(situation,Self.Length,fromv,tov,step);
var count := CheckAndCorrectFromToAndCalcCountForSystemSlice(situation,Self.Length,fromv,tov,step);
Result := CreateSliceFromStringInternal(Self,fromv+1,step,count)
end;
@ -9605,7 +9706,28 @@ begin
Result := SystemSliceStringImpl(Self,situation,from,&to,step);
end;
///--
function SystemSliceStringImplQuestion(Self: string; situation: integer; from,&to: integer; step: integer := 1): string;
begin
var fromv := from-1;
var tov := &to-1;
var count := CorrectFromToAndCalcCountForSystemSliceQuestion(situation,Self.Length,fromv,tov,step);
Result := CreateSliceFromStringInternal(Self,fromv+1,step,count);
end;
///--
function SystemSliceQuestion(Self: string; situation: integer; from,&to: integer): string; extensionmethod;
begin
Result := SystemSliceStringImplQuestion(Self,situation,from,&to,1);
end;
///--
function SystemSliceQuestion(Self: string; situation: integer; from,&to,step: integer): string; extensionmethod;
begin
Result := SystemSliceStringImplQuestion(Self,situation,from,&to,step);
end;
//--------------------------------------------
//>> Методы расширения типа Func # Extension methods for Func
//--------------------------------------------

View file

@ -38,7 +38,7 @@ namespace PascalABCCompiler.TreeConverter
}
}*/
public class syntax_tree_visitor : SyntaxTree.WalkingVisitorNew // SSM 02.01.17 менять на визитор с другим порядком обхода можно, но бессмысленно
public partial class syntax_tree_visitor : SyntaxTree.WalkingVisitorNew // SSM 02.01.17 менять на визитор с другим порядком обхода можно, но бессмысленно
// Порядок обхода не важен поскольку все узлы visit переопределяются
// SSM 02.01.17 Использование ReplaceStatement из BaseChangeVisitor плохо изучено - что-то не работает
// Поэтому используется явный Parent и ReplaceStatement из узла statement_list
@ -19184,10 +19184,8 @@ namespace PascalABCCompiler.TreeConverter
ReplaceStatementUsingParent(assvartup, sl);
}
public override void visit(SyntaxTree.slice_expr sl)
expression_list construct_expression_list_for_slice_expr(SyntaxTree.slice_expr sl)
{
// Преобразуется в вызов a.SystemSlice(situation,from,to,step)
// Тип a должен быть array of T, List<T> или string
// situation = 0 - ничего не пропущено
// situation = 1 - пропущен from
// situation = 2 - пропущен to
@ -19195,44 +19193,6 @@ namespace PascalABCCompiler.TreeConverter
// Пропущенность кодируется тем, что в соответствующем поле - int.MaxValue
// step может просто отсутствовать - это параметр по умолчанию в SystemSlice
var semvar = convert_strong(sl.v);
if (semvar is typed_expression)
semvar = convert_typed_expression_to_function_call(semvar as typed_expression);
var t = ConvertSemanticTypeNodeToNETType(semvar.type);
var IsSlicedType = 0; // проверим, является ли semvar.type динамическим массивом, списком List или строкой
// semvar.type должен быть array of T, List<T> или string
if (t == null)
IsSlicedType = 0; // можно ничего не присваивать :)
else if (t.IsArray)
IsSlicedType = 1;
else if (t == typeof(System.String))
IsSlicedType = 2;
else if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(System.Collections.Generic.List<>))
IsSlicedType = 3;
if (IsSlicedType==0)
AddError(get_location(sl.v), "BAD_SLICE_OBJECT");
var semfrom = convert_strong(sl.from);
var b = convertion_data_and_alghoritms.can_convert_type(semfrom, SystemLibrary.SystemLibrary.integer_type);
if (!b)
AddError(get_location(sl.from), "INTEGER_VALUE_EXPECTED");
var semto = convert_strong(sl.to);
b = convertion_data_and_alghoritms.can_convert_type(semto, SystemLibrary.SystemLibrary.integer_type);
if (!b)
AddError(get_location(sl.to), "INTEGER_VALUE_EXPECTED");
if (sl.step != null)
{
var semstep = convert_strong(sl.step);
b = convertion_data_and_alghoritms.can_convert_type(semstep, SystemLibrary.SystemLibrary.integer_type);
if (!b)
AddError(get_location(sl.step), "INTEGER_VALUE_EXPECTED");
}
int situation = 0;
if ((sl.from is int32_const) && (sl.from as int32_const).val == int.MaxValue)
@ -19249,7 +19209,19 @@ namespace PascalABCCompiler.TreeConverter
if (sl.step != null)
el.Add(sl.step);
return el;
}
public override void visit(SyntaxTree.slice_expr sl)
{
// Преобразуется в вызов a.SystemSlice(situation,from,to,step)
// Тип a должен быть array of T, List<T> или string
semcheck(sl);
// Действия уровня синтаксиса. Можно вынести на синтаксический уровень как desugaring для сахарного узла
var el = construct_expression_list_for_slice_expr(sl);
var mc = new method_call(new dot_node(sl.v, new ident("SystemSlice", sl.v.source_context), sl.v.source_context), el, sl.source_context);
visit(mc);
}
@ -19257,68 +19229,11 @@ namespace PascalABCCompiler.TreeConverter
{
// Преобразуется в вызов a.SystemSlice(situation,from,to,step)
// Тип a должен быть array of T, List<T> или string
// situation = 0 - ничего не пропущено
// situation = 1 - пропущен from
// situation = 2 - пропущен to
// situation = 3 - пропущены from и to
// Пропущенность кодируется тем, что в соответствующем поле - int.MaxValue
// step может просто отсутствовать - это параметр по умолчанию в SystemSlice
var semvar = convert_strong(sl.v);
if (semvar is typed_expression)
semvar = convert_typed_expression_to_function_call(semvar as typed_expression);
var t = ConvertSemanticTypeNodeToNETType(semvar.type);
var IsSlicedType = 0; // проверим, является ли semvar.type динамическим массивом, списком List или строкой
// semvar.type должен быть array of T, List<T> или string
if (t == null)
IsSlicedType = 0; // можно ничего не присваивать :)
else if (t.IsArray)
IsSlicedType = 1;
else if (t == typeof(System.String))
IsSlicedType = 2;
else if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(System.Collections.Generic.List<>))
IsSlicedType = 3;
if (IsSlicedType == 0)
AddError(get_location(sl.v), "BAD_SLICE_OBJECT");
var semfrom = convert_strong(sl.from);
var b = convertion_data_and_alghoritms.can_convert_type(semfrom, SystemLibrary.SystemLibrary.integer_type);
if (!b)
AddError(get_location(sl.from), "INTEGER_VALUE_EXPECTED");
var semto = convert_strong(sl.to);
b = convertion_data_and_alghoritms.can_convert_type(semto, SystemLibrary.SystemLibrary.integer_type);
if (!b)
AddError(get_location(sl.to), "INTEGER_VALUE_EXPECTED");
if (sl.step != null)
{
var semstep = convert_strong(sl.step);
b = convertion_data_and_alghoritms.can_convert_type(semstep, SystemLibrary.SystemLibrary.integer_type);
if (!b)
AddError(get_location(sl.step), "INTEGER_VALUE_EXPECTED");
}
int situation = 0;
if ((sl.from is int32_const) && (sl.from as int32_const).val == int.MaxValue)
situation += 1;
if ((sl.to is int32_const) && (sl.to as int32_const).val == int.MaxValue)
situation += 2;
var el = new SyntaxTree.expression_list();
el.Add(new int32_const(situation));
el.Add(sl.from); // Это плохо - считается 2 раза. Надо делать semantic_expr_node !!!? Нет!!!
// Если там будет лямбда, то не будет работать - известно, что semantic_expr_node не работает с лямбдами
// т.к. они несколько раз обходят код.
el.Add(sl.to);
if (sl.step != null)
el.Add(sl.step);
semcheck(sl);
var el = construct_expression_list_for_slice_expr(sl);
var mc = new method_call(new dot_node(sl.v, new ident("SystemSliceQuestion", sl.v.source_context), sl.v.source_context), el, sl.source_context);
visit(mc);
}

View file

@ -167,6 +167,7 @@
<Compile Include="TreeConversion\syntax_tree_visitor.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="TreeConversion\syntax_tree_visitor_semcheck_helper.cs" />
<Compile Include="TreeConversion\type_constructor.cs" />
<Compile Include="TreeRealization\attributes.cs" />
<Compile Include="TreeRealization\events.cs" />

Binary file not shown.