diff --git a/SyntaxTree/tree/AbstractVisitor.cs b/SyntaxTree/tree/AbstractVisitor.cs
index 9847684ec..c68e43bc4 100644
--- a/SyntaxTree/tree/AbstractVisitor.cs
+++ b/SyntaxTree/tree/AbstractVisitor.cs
@@ -1098,9 +1098,14 @@ namespace PascalABCCompiler.SyntaxTree
DefaultVisit(_slice_expr_question);
}
- public virtual void visit(semantic_check_sugared_statement _semantic_check_sugared_statement)
+ public virtual void visit(semantic_check_sugared_statement_node _semantic_check_sugared_statement_node)
{
- DefaultVisit(_semantic_check_sugared_statement);
+ DefaultVisit(_semantic_check_sugared_statement_node);
+ }
+
+ public virtual void visit(sugared_expression _sugared_expression)
+ {
+ DefaultVisit(_sugared_expression);
}
}
diff --git a/SyntaxTree/tree/HierarchyVisitor.cs b/SyntaxTree/tree/HierarchyVisitor.cs
index 6ec7c9281..560d8b405 100644
--- a/SyntaxTree/tree/HierarchyVisitor.cs
+++ b/SyntaxTree/tree/HierarchyVisitor.cs
@@ -1749,11 +1749,19 @@ namespace PascalABCCompiler.SyntaxTree
{
}
- public virtual void pre_do_visit(semantic_check_sugared_statement _semantic_check_sugared_statement)
+ public virtual void pre_do_visit(semantic_check_sugared_statement_node _semantic_check_sugared_statement_node)
{
}
- public virtual void post_do_visit(semantic_check_sugared_statement _semantic_check_sugared_statement)
+ public virtual void post_do_visit(semantic_check_sugared_statement_node _semantic_check_sugared_statement_node)
+ {
+ }
+
+ public virtual void pre_do_visit(sugared_expression _sugared_expression)
+ {
+ }
+
+ public virtual void post_do_visit(sugared_expression _sugared_expression)
{
}
@@ -3623,11 +3631,19 @@ namespace PascalABCCompiler.SyntaxTree
post_do_visit(_slice_expr_question);
}
- public override void visit(semantic_check_sugared_statement _semantic_check_sugared_statement)
+ public override void visit(semantic_check_sugared_statement_node _semantic_check_sugared_statement_node)
{
- DefaultVisit(_semantic_check_sugared_statement);
- pre_do_visit(_semantic_check_sugared_statement);
- post_do_visit(_semantic_check_sugared_statement);
+ DefaultVisit(_semantic_check_sugared_statement_node);
+ pre_do_visit(_semantic_check_sugared_statement_node);
+ post_do_visit(_semantic_check_sugared_statement_node);
+ }
+
+ public override void visit(sugared_expression _sugared_expression)
+ {
+ DefaultVisit(_sugared_expression);
+ pre_do_visit(_sugared_expression);
+ visit(sugared_expression.new_expr);
+ post_do_visit(_sugared_expression);
}
}
diff --git a/SyntaxTree/tree/SyntaxTreeStreamReader.cs b/SyntaxTree/tree/SyntaxTreeStreamReader.cs
index 4da4b0b0b..845d310f1 100644
--- a/SyntaxTree/tree/SyntaxTreeStreamReader.cs
+++ b/SyntaxTree/tree/SyntaxTreeStreamReader.cs
@@ -457,7 +457,9 @@ namespace PascalABCCompiler.SyntaxTree
case 217:
return new slice_expr_question();
case 218:
- return new semantic_check_sugared_statement();
+ return new semantic_check_sugared_statement_node();
+ case 219:
+ return new sugared_expression();
}
return null;
}
@@ -3847,15 +3849,28 @@ namespace PascalABCCompiler.SyntaxTree
}
- public void visit(semantic_check_sugared_statement _semantic_check_sugared_statement)
+ public void visit(semantic_check_sugared_statement_node _semantic_check_sugared_statement_node)
{
- read_semantic_check_sugared_statement(_semantic_check_sugared_statement);
+ read_semantic_check_sugared_statement_node(_semantic_check_sugared_statement_node);
}
- public void read_semantic_check_sugared_statement(semantic_check_sugared_statement _semantic_check_sugared_statement)
+ public void read_semantic_check_sugared_statement_node(semantic_check_sugared_statement_node _semantic_check_sugared_statement_node)
{
- read_statement(_semantic_check_sugared_statement);
- _semantic_check_sugared_statement.stat = (object)br.ReadByte();
+ read_statement(_semantic_check_sugared_statement_node);
+ _semantic_check_sugared_statement_node.stat = (object)br.ReadByte();
+ }
+
+
+ public void visit(sugared_expression _sugared_expression)
+ {
+ read_sugared_expression(_sugared_expression);
+ }
+
+ public void read_sugared_expression(sugared_expression _sugared_expression)
+ {
+ read_expression(_sugared_expression);
+ _sugared_expression.sugared_expr = (object)br.ReadByte();
+ _sugared_expression.new_expr = _read_node() as expression;
}
}
diff --git a/SyntaxTree/tree/SyntaxTreeStreamWriter.cs b/SyntaxTree/tree/SyntaxTreeStreamWriter.cs
index 82bde377e..060c599c2 100644
--- a/SyntaxTree/tree/SyntaxTreeStreamWriter.cs
+++ b/SyntaxTree/tree/SyntaxTreeStreamWriter.cs
@@ -6004,16 +6004,38 @@ namespace PascalABCCompiler.SyntaxTree
}
- public void visit(semantic_check_sugared_statement _semantic_check_sugared_statement)
+ public void visit(semantic_check_sugared_statement_node _semantic_check_sugared_statement_node)
{
bw.Write((Int16)218);
- write_semantic_check_sugared_statement(_semantic_check_sugared_statement);
+ write_semantic_check_sugared_statement_node(_semantic_check_sugared_statement_node);
}
- public void write_semantic_check_sugared_statement(semantic_check_sugared_statement _semantic_check_sugared_statement)
+ public void write_semantic_check_sugared_statement_node(semantic_check_sugared_statement_node _semantic_check_sugared_statement_node)
{
- write_statement(_semantic_check_sugared_statement);
- bw.Write((byte)_semantic_check_sugared_statement.stat);
+ write_statement(_semantic_check_sugared_statement_node);
+ bw.Write((byte)_semantic_check_sugared_statement_node.stat);
+ }
+
+
+ public void visit(sugared_expression _sugared_expression)
+ {
+ bw.Write((Int16)219);
+ write_sugared_expression(_sugared_expression);
+ }
+
+ public void write_sugared_expression(sugared_expression _sugared_expression)
+ {
+ write_expression(_sugared_expression);
+ bw.Write((byte)_sugared_expression.sugared_expr);
+ if (_sugared_expression.new_expr == null)
+ {
+ bw.Write((byte)0);
+ }
+ else
+ {
+ bw.Write((byte)1);
+ _sugared_expression.new_expr.visit(this);
+ }
}
}
diff --git a/SyntaxTree/tree/Tree.cs b/SyntaxTree/tree/Tree.cs
index 76ad7534f..04fc1173d 100644
--- a/SyntaxTree/tree/Tree.cs
+++ b/SyntaxTree/tree/Tree.cs
@@ -38529,13 +38529,13 @@ namespace PascalABCCompiler.SyntaxTree
///узел, не генерирующий кода, но осуществляющий семантические проверки сахарных узлов. stat - это на самом деле statement. stat сделано типа object - чтобы оно автоматически не обходилось
///
[Serializable]
- public partial class semantic_check_sugared_statement : statement
+ public partial class semantic_check_sugared_statement_node : statement
{
///
///Конструктор без параметров.
///
- public semantic_check_sugared_statement()
+ public semantic_check_sugared_statement_node()
{
}
@@ -38543,7 +38543,7 @@ namespace PascalABCCompiler.SyntaxTree
///
///Конструктор с параметрами.
///
- public semantic_check_sugared_statement(object _stat)
+ public semantic_check_sugared_statement_node(object _stat)
{
this._stat=_stat;
}
@@ -38551,7 +38551,7 @@ namespace PascalABCCompiler.SyntaxTree
///
///Конструктор с параметрами.
///
- public semantic_check_sugared_statement(object _stat,SourceContext sc)
+ public semantic_check_sugared_statement_node(object _stat,SourceContext sc)
{
this._stat=_stat;
source_context = sc;
@@ -38577,7 +38577,7 @@ namespace PascalABCCompiler.SyntaxTree
/// Создает копию узла
public override syntax_tree_node Clone()
{
- semantic_check_sugared_statement copy = new semantic_check_sugared_statement();
+ semantic_check_sugared_statement_node copy = new semantic_check_sugared_statement_node();
copy.Parent = this.Parent;
if (source_context != null)
copy.source_context = new SourceContext(source_context);
@@ -38591,9 +38591,9 @@ namespace PascalABCCompiler.SyntaxTree
}
/// Получает копию данного узла корректного типа
- public new semantic_check_sugared_statement TypedClone()
+ public new semantic_check_sugared_statement_node TypedClone()
{
- return Clone() as semantic_check_sugared_statement;
+ return Clone() as semantic_check_sugared_statement_node;
}
///
@@ -38646,6 +38646,161 @@ namespace PascalABCCompiler.SyntaxTree
}
+ ///
+ ///
+ ///
+ [Serializable]
+ public partial class sugared_expression : expression
+ {
+
+ ///
+ ///Конструктор без параметров.
+ ///
+ public sugared_expression()
+ {
+
+ }
+
+ ///
+ ///Конструктор с параметрами.
+ ///
+ public sugared_expression(object _sugared_expr,expression _new_expr)
+ {
+ this._sugared_expr=_sugared_expr;
+ this._new_expr=_new_expr;
+ }
+
+ ///
+ ///Конструктор с параметрами.
+ ///
+ public sugared_expression(object _sugared_expr,expression _new_expr,SourceContext sc)
+ {
+ this._sugared_expr=_sugared_expr;
+ this._new_expr=_new_expr;
+ source_context = sc;
+ }
+ protected object _sugared_expr;
+ protected expression _new_expr;
+
+ ///
+ ///
+ ///
+ public object sugared_expr
+ {
+ get
+ {
+ return _sugared_expr;
+ }
+ set
+ {
+ _sugared_expr=value;
+ }
+ }
+
+ ///
+ ///
+ ///
+ public expression new_expr
+ {
+ get
+ {
+ return _new_expr;
+ }
+ set
+ {
+ _new_expr=value;
+ }
+ }
+
+
+ /// Создает копию узла
+ public override syntax_tree_node Clone()
+ {
+ sugared_expression copy = new sugared_expression();
+ 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;
+ }
+ copy.sugared_expr = sugared_expr;
+ if (new_expr != null)
+ {
+ copy.new_expr = (expression)new_expr.Clone();
+ copy.new_expr.Parent = copy;
+ }
+ return copy;
+ }
+
+ /// Получает копию данного узла корректного типа
+ public new sugared_expression TypedClone()
+ {
+ return Clone() as sugared_expression;
+ }
+
+ ///
+ ///Свойство для получения количества всех подузлов без элементов поля типа List
+ ///
+ public override Int32 subnodes_without_list_elements_count
+ {
+ get
+ {
+ return 1;
+ }
+ }
+ ///
+ ///Свойство для получения количества всех подузлов. Подузлом также считается каждый элемент поля типа List
+ ///
+ public override Int32 subnodes_count
+ {
+ get
+ {
+ return 1;
+ }
+ }
+ ///
+ ///Индексатор для получения всех подузлов
+ ///
+ 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 new_expr;
+ }
+ return null;
+ }
+ set
+ {
+ if(subnodes_count == 0 || ind < 0 || ind > subnodes_count-1)
+ throw new IndexOutOfRangeException();
+ switch(ind)
+ {
+ case 0:
+ new_expr = (expression)value;
+ break;
+ }
+ }
+ }
+ ///
+ ///Метод для обхода дерева посетителем
+ ///
+ ///Объект-посетитель.
+ ///Return value is void
+ public override void visit(IVisitor visitor)
+ {
+ visitor.visit(this);
+ }
+
+ }
+
+
}
diff --git a/SyntaxTree/tree/Visitor.cs b/SyntaxTree/tree/Visitor.cs
index e284f2f33..d41e89f83 100644
--- a/SyntaxTree/tree/Visitor.cs
+++ b/SyntaxTree/tree/Visitor.cs
@@ -1313,11 +1313,17 @@ namespace PascalABCCompiler.SyntaxTree
/// Return value is void
void visit(slice_expr_question _slice_expr_question);
///
- ///Method to visit semantic_check_sugared_statement.
+ ///Method to visit semantic_check_sugared_statement_node.
///
- ///Node to visit
+ ///Node to visit
/// Return value is void
- void visit(semantic_check_sugared_statement _semantic_check_sugared_statement);
+ void visit(semantic_check_sugared_statement_node _semantic_check_sugared_statement_node);
+ ///
+ ///Method to visit sugared_expression.
+ ///
+ ///Node to visit
+ /// Return value is void
+ void visit(sugared_expression _sugared_expression);
}
diff --git a/SyntaxTree/tree/tree.nin b/SyntaxTree/tree/tree.nin
index 38caa0a9c..7c94f8d48 100644
Binary files a/SyntaxTree/tree/tree.nin and b/SyntaxTree/tree/tree.nin differ
diff --git a/SyntaxVisitors/SugarVisitors/AssignTuplesDesugarVisitor.cs b/SyntaxVisitors/SugarVisitors/AssignTuplesDesugarVisitor.cs
index ce94d6f36..d103dd369 100644
--- a/SyntaxVisitors/SugarVisitors/AssignTuplesDesugarVisitor.cs
+++ b/SyntaxVisitors/SugarVisitors/AssignTuplesDesugarVisitor.cs
@@ -25,7 +25,7 @@ namespace SyntaxVisitors.SugarVisitors
public override void visit(assign_tuple asstup)
{
var sl = new statement_list();
- sl.Add(new semantic_check_sugared_statement(asstup)); // Это нужно для проверок на этапе преобразования в семантику
+ sl.Add(new semantic_check_sugared_statement_node(asstup)); // Это нужно для проверок на этапе преобразования в семантику
var tname = "#temp_var" + UniqueNumStr();
var tt = new var_statement(new ident(tname), asstup.expr);
@@ -48,7 +48,7 @@ namespace SyntaxVisitors.SugarVisitors
public override void visit(assign_var_tuple assvartup)
{
var sl = new List();
- sl.Add(new semantic_check_sugared_statement(assvartup)); // Это нужно для проверок на этапе преобразования в семантику
+ sl.Add(new semantic_check_sugared_statement_node(assvartup)); // Это нужно для проверок на этапе преобразования в семантику
var tname = "#temp_var" + UniqueNumStr();
var tt = new var_statement(new ident(tname), assvartup.expr); // тут для assvartup.expr внутри повторно вызывается convert_strong, это плохо, но если там лямбда, то иначе - с semantic_addr_value - не работает!!!
diff --git a/TreeConverter/TreeConversion/syntax_tree_visitor.cs b/TreeConverter/TreeConversion/syntax_tree_visitor.cs
index fe9e91961..d597c3e89 100644
--- a/TreeConverter/TreeConversion/syntax_tree_visitor.cs
+++ b/TreeConverter/TreeConversion/syntax_tree_visitor.cs
@@ -19415,19 +19415,25 @@ namespace PascalABCCompiler.TreeConverter
visit(pc);
}
- public override void visit(SyntaxTree.semantic_check_sugared_statement st)
+ public override void visit(SyntaxTree.semantic_check_sugared_statement_node st)
{
- if (st.stat is SyntaxTree.assign_var_tuple)
+ if (st.stat is SyntaxTree.assign_tuple)
{
- check_sugared(st.stat as SyntaxTree.assign_var_tuple);
+ check_sugared(st.stat as SyntaxTree.assign_tuple);
}
- else
+ else
{
-
+ AddError(get_location(st), "MISSED_SEMANTIC_CHECK_FOR_SUGARED_NODE_{0}");
}
ret.reset(); // обязательно очистить - этот узел в семантику ничего не должен приносить!
}
+ public override void visit(SyntaxTree.sugared_expression ex)
+ {
+ //semantic_check_sugared_expression(ex.sugared_expr);
+ visit(ex.new_expr);
+ }
+
/*public SyntaxTree.question_colon_expression ConvertToQCE(dot_question_node dqn)
{
// Неверно работает. Пока не используется. Доделать
diff --git a/TreeConverter/TreeConversion/syntax_tree_visitor_semcheck_helper.cs b/TreeConverter/TreeConversion/syntax_tree_visitor_semcheck_helper.cs
new file mode 100644
index 000000000..10d39bcb3
--- /dev/null
+++ b/TreeConverter/TreeConversion/syntax_tree_visitor_semcheck_helper.cs
@@ -0,0 +1,61 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using PascalABCCompiler.SyntaxTree;
+using PascalABCCompiler.TreeRealization;
+
+namespace PascalABCCompiler.TreeConverter
+{
+ public partial class syntax_tree_visitor
+ {
+ void semcheck_slice_expr_helper(SyntaxTree.slice_expr sl)
+ {
+ 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 или 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");
+ }
+ }
+ public void semcheck(SyntaxTree.slice_expr sl)
+ {
+ semcheck_slice_expr_helper(sl);
+ }
+ public void semcheck(SyntaxTree.slice_expr_question sl)
+ {
+ semcheck_slice_expr_helper(sl);
+ }
+ }
+}
diff --git a/bin/Lng/Eng/SemanticErrors_ms.dat b/bin/Lng/Eng/SemanticErrors_ms.dat
index 0dd37f785..3681c51a8 100644
--- a/bin/Lng/Eng/SemanticErrors_ms.dat
+++ b/bin/Lng/Eng/SemanticErrors_ms.dat
@@ -9,3 +9,5 @@ BAD_SLICE_OBJECT=Slices are allowed for strings, dynamic arrays and lists only
ONLY_IN_SHORT_FUNC_DEFS_RETURN_TYPE_CANBE_OMITTED=Only in short function definitions you can omit the return type
ONE_TKIDENTIFIER=Type here must be identifier
SUGARED_NODE_{0}_IN_SYNTAX_TREE_VISITOR=Sugared node {0} must not be visited in syntax_tree_visitor
+MISSED_SEMANTIC_CHECK_FOR_SUGARED_NODE_{0}=Missed semantic check for sugared node {0}
+
diff --git a/bin/Lng/Rus/SemanticErrors_ms.dat b/bin/Lng/Rus/SemanticErrors_ms.dat
index cd368059f..b6ab547d3 100644
--- a/bin/Lng/Rus/SemanticErrors_ms.dat
+++ b/bin/Lng/Rus/SemanticErrors_ms.dat
@@ -9,3 +9,4 @@ BAD_SLICE_OBJECT=Срезы допустимы только для строк,
ONLY_IN_SHORT_FUNC_DEFS_RETURN_TYPE_CANBE_OMITTED=Только в коротких определениях функций можно не указывать тип возвращаемого значения
ONE_TKIDENTIFIER=В качестве типа ожидался идентификатор
SUGARED_NODE_{0}_IN_SYNTAX_TREE_VISITOR=Сахарный узел {0} не должен обходиться в syntax_tree_visitor. Обратитесь к разработчикам PascalABC.NET
+MISSED_SEMANTIC_CHECK_FOR_SUGARED_NODE_{0}=Отсутствует семантическая проверка для сахарного узла {0}