diff --git a/Configuration/GlobalAssemblyInfo.cs b/Configuration/GlobalAssemblyInfo.cs index 4dc5ff200..8faf870b2 100644 --- a/Configuration/GlobalAssemblyInfo.cs +++ b/Configuration/GlobalAssemblyInfo.cs @@ -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 = "1431"; + public const string Revision = "1436"; public const string MainVersion = Major + "." + Minor; public const string FullVersion = Major + "." + Minor + "." + Build + "." + Revision; diff --git a/Configuration/Version.defs b/Configuration/Version.defs index 6ee1b0c1a..66f674559 100644 --- a/Configuration/Version.defs +++ b/Configuration/Version.defs @@ -1,4 +1,4 @@ -%COREVERSION%=0 -%REVISION%=1431 %MINOR%=2 +%REVISION%=1436 +%COREVERSION%=0 %MAJOR%=3 diff --git a/ReleaseGenerators/PascalABCNET_version.nsh b/ReleaseGenerators/PascalABCNET_version.nsh index 940b84ded..c3d838e62 100644 --- a/ReleaseGenerators/PascalABCNET_version.nsh +++ b/ReleaseGenerators/PascalABCNET_version.nsh @@ -1 +1 @@ -!define VERSION '3.2.0.1431' +!define VERSION '3.2.0.1436' diff --git a/SyntaxTree/tree/HierarchyVisitor.cs b/SyntaxTree/tree/HierarchyVisitor.cs index b9d6a5c69..0318a0977 100644 --- a/SyntaxTree/tree/HierarchyVisitor.cs +++ b/SyntaxTree/tree/HierarchyVisitor.cs @@ -3643,6 +3643,8 @@ namespace PascalABCCompiler.SyntaxTree { DefaultVisit(_semantic_check_sugared_statement_node); pre_do_visit(_semantic_check_sugared_statement_node); + for (int i = 0; i < lst.Count; i++) + visit(semantic_check_sugared_statement_node.lst[i]); post_do_visit(_semantic_check_sugared_statement_node); } diff --git a/SyntaxTree/tree/SyntaxTreeStreamReader.cs b/SyntaxTree/tree/SyntaxTreeStreamReader.cs index d8ecdcdd1..14784b522 100644 --- a/SyntaxTree/tree/SyntaxTreeStreamReader.cs +++ b/SyntaxTree/tree/SyntaxTreeStreamReader.cs @@ -3859,7 +3859,20 @@ namespace PascalABCCompiler.SyntaxTree public void read_semantic_check_sugared_statement_node(semantic_check_sugared_statement_node _semantic_check_sugared_statement_node) { read_statement(_semantic_check_sugared_statement_node); - _semantic_check_sugared_statement_node.stat = (object)br.ReadByte(); + _semantic_check_sugared_statement_node.typ = (object)br.ReadByte(); + if (br.ReadByte() == 0) + { + _semantic_check_sugared_statement_node.lst = null; + } + else + { + _semantic_check_sugared_statement_node.lst = new List(); + Int32 ssyy_count = br.ReadInt32(); + for(Int32 ssyy_i = 0; ssyy_i < ssyy_count; ssyy_i++) + { + _semantic_check_sugared_statement_node.lst.Add(_read_node() as syntax_tree_node); + } + } } diff --git a/SyntaxTree/tree/SyntaxTreeStreamWriter.cs b/SyntaxTree/tree/SyntaxTreeStreamWriter.cs index 3a410fb4e..a4ae36cf0 100644 --- a/SyntaxTree/tree/SyntaxTreeStreamWriter.cs +++ b/SyntaxTree/tree/SyntaxTreeStreamWriter.cs @@ -6013,7 +6013,28 @@ namespace PascalABCCompiler.SyntaxTree public void write_semantic_check_sugared_statement_node(semantic_check_sugared_statement_node _semantic_check_sugared_statement_node) { write_statement(_semantic_check_sugared_statement_node); - bw.Write((byte)_semantic_check_sugared_statement_node.stat); + bw.Write((byte)_semantic_check_sugared_statement_node.typ); + if (_semantic_check_sugared_statement_node.lst == null) + { + bw.Write((byte)0); + } + else + { + bw.Write((byte)1); + bw.Write(_semantic_check_sugared_statement_node.lst.Count); + for(Int32 ssyy_i = 0; ssyy_i < _semantic_check_sugared_statement_node.lst.Count; ssyy_i++) + { + if (_semantic_check_sugared_statement_node.lst[ssyy_i] == null) + { + bw.Write((byte)0); + } + else + { + bw.Write((byte)1); + _semantic_check_sugared_statement_node.lst[ssyy_i].visit(this); + } + } + } } diff --git a/SyntaxTree/tree/Tree.cs b/SyntaxTree/tree/Tree.cs index 8332d8599..46cddaf42 100644 --- a/SyntaxTree/tree/Tree.cs +++ b/SyntaxTree/tree/Tree.cs @@ -38543,37 +38543,138 @@ namespace PascalABCCompiler.SyntaxTree /// ///Конструктор с параметрами. /// - public semantic_check_sugared_statement_node(object _stat) + public semantic_check_sugared_statement_node(object _typ,List _lst) { - this._stat=_stat; + this._typ=_typ; + this._lst=_lst; } /// ///Конструктор с параметрами. /// - public semantic_check_sugared_statement_node(object _stat,SourceContext sc) + public semantic_check_sugared_statement_node(object _typ,List _lst,SourceContext sc) { - this._stat=_stat; + this._typ=_typ; + this._lst=_lst; source_context = sc; } - protected object _stat; + public semantic_check_sugared_statement_node(syntax_tree_node elem, SourceContext sc = null) + { + Add(elem, sc); + } + + protected object _typ; + protected List _lst=new List(); /// /// /// - public object stat + public object typ { get { - return _stat; + return _typ; } set { - _stat=value; + _typ=value; + } + } + + /// + /// + /// + public List lst + { + get + { + return _lst; + } + set + { + _lst=value; } } + public semantic_check_sugared_statement_node Add(syntax_tree_node elem, SourceContext sc = null) + { + lst.Add(elem); + if (sc != null) + source_context = sc; + return this; + } + + public void AddFirst(syntax_tree_node el) + { + lst.Insert(0, el); + } + + public void AddFirst(IEnumerable els) + { + lst.InsertRange(0, els); + } + + public void AddMany(params syntax_tree_node[] els) + { + lst.AddRange(els); + } + + private int FindIndexInList(syntax_tree_node el) + { + var ind = lst.FindIndex(x => x == el); + if (ind == -1) + throw new Exception(string.Format("У списка {0} не найден элемент {1} среди дочерних\n", this, el)); + return ind; + } + + public void InsertAfter(syntax_tree_node el, syntax_tree_node newel) + { + lst.Insert(FindIndexInList(el) + 1, newel); + } + + public void InsertAfter(syntax_tree_node el, IEnumerable newels) + { + lst.InsertRange(FindIndexInList(el) + 1, newels); + } + + public void InsertBefore(syntax_tree_node el, syntax_tree_node newel) + { + lst.Insert(FindIndexInList(el), newel); + } + + public void InsertBefore(syntax_tree_node el, IEnumerable newels) + { + lst.InsertRange(FindIndexInList(el), newels); + } + + public bool Remove(syntax_tree_node el) + { + return lst.Remove(el); + } + + public void ReplaceInList(syntax_tree_node el, syntax_tree_node newel) + { + lst[FindIndexInList(el)] = newel; + } + + public void ReplaceInList(syntax_tree_node el, IEnumerable newels) + { + var ind = FindIndexInList(el); + lst.RemoveAt(ind); + lst.InsertRange(ind, newels); + } + + public int RemoveAll(Predicate match) + { + return lst.RemoveAll(match); + } + + public syntax_tree_node Last() + { + return lst[lst.Count - 1]; + } + /// Создает копию узла public override syntax_tree_node Clone() { @@ -38586,7 +38687,20 @@ namespace PascalABCCompiler.SyntaxTree copy.attributes = (attribute_list)attributes.Clone(); copy.attributes.Parent = copy; } - copy.stat = stat; + copy.typ = typ; + if (lst != null) + { + foreach (syntax_tree_node elem in lst) + { + if (elem != null) + { + copy.Add(elem.Clone()); + copy.Last().Parent = copy; + } + else + copy.Add(null); + } + } return copy; } @@ -38613,7 +38727,7 @@ namespace PascalABCCompiler.SyntaxTree { get { - return 0; + return 0 + (lst == null ? 0 : lst.Count); } } /// @@ -38625,12 +38739,29 @@ namespace PascalABCCompiler.SyntaxTree { if(subnodes_count == 0 || ind < 0 || ind > subnodes_count-1) throw new IndexOutOfRangeException(); + Int32 index_counter=ind - 0; + if(lst != null) + { + if(index_counter < lst.Count) + { + return lst[index_counter]; + } + } return null; } set { if(subnodes_count == 0 || ind < 0 || ind > subnodes_count-1) throw new IndexOutOfRangeException(); + Int32 index_counter=ind - 0; + if(lst != null) + { + if(index_counter < lst.Count) + { + lst[index_counter]= (syntax_tree_node)value; + return; + } + } } } /// diff --git a/SyntaxTree/tree/tree.xml b/SyntaxTree/tree/tree.xml index 220983f35..dedfd5a88 100644 --- a/SyntaxTree/tree/tree.xml +++ b/SyntaxTree/tree/tree.xml @@ -2808,7 +2808,8 @@ - + + @@ -2868,8 +2869,7 @@ - - + @@ -2877,13 +2877,15 @@ - + + + @@ -2892,13 +2894,15 @@ + + - + @@ -2907,13 +2911,13 @@ - - + + - + @@ -2924,20 +2928,22 @@ + - + + - + - - + + @@ -2959,11 +2965,12 @@ + + - @@ -2971,15 +2978,13 @@ - - + - @@ -2989,16 +2994,14 @@ - - + - - + @@ -3010,56 +3013,49 @@ - - - + - + - + - + - - - - + + - - - + - - + @@ -3067,6 +3063,7 @@ + @@ -3074,29 +3071,28 @@ + - + - + - - - - + + - - + + @@ -3105,163 +3101,158 @@ - - + + - + + - - - + - - + - + - + - - + + - + - + + + + + - - + + - + - - - - + + - - - - - - - + - - - + + + - - + + - - + - + + + - + - - + - + - + + + - @@ -3275,79 +3266,79 @@ + - - + + - - - + + - + + - + + - - - + + - - - + + - + - + + - - + @@ -3355,7 +3346,9 @@ - + + + @@ -3365,7 +3358,8 @@ - + + @@ -3374,21 +3368,22 @@ + - + - + - + @@ -3398,55 +3393,55 @@ - + + - + - + - + - - + + + - + - - - + - - - + + + - + @@ -3454,36 +3449,37 @@ + - + - + + - + + - - + + - - @@ -3493,74 +3489,74 @@ - + + - + - + - + + - + - - + - + - + - - + - - + + - + @@ -3569,42 +3565,43 @@ - - - + - + - - + - + - + + - + + + + - + - + @@ -3614,43 +3611,43 @@ - - + + - - + - - - - - + + + + - - + + + + @@ -3658,68 +3655,64 @@ - + + - - - - - + + - + - + - - + + - + - + + - - - - + + + - + - - + - - - - + + + - + - + - - + + @@ -3728,9 +3721,9 @@ - + + - @@ -3741,10 +3734,11 @@ + - + @@ -3753,19 +3747,20 @@ + - + - + + - - + @@ -3776,60 +3771,62 @@ + + - - + - + - - + + - - + + - + + + - - + + + - - - - - + + + + - - + - + - + @@ -3840,40 +3837,42 @@ - + - + - - + + - - + + - - + + + - + + - - + + - + - + @@ -3882,29 +3881,33 @@ - + - + + - + + + + - + - - + + - + - + - + @@ -3913,23 +3916,22 @@ - - - + + - + - + - + - + @@ -3937,318 +3939,319 @@ - - - + + + - + - + - - - + + + - - - - + + + + - - + + - + - + - + - + - + - - + + + - + - + - - + + - + - + - + - + - + - + + - + - - + + - + - - - + - - + + - - - + + + - + + - + + - + + + - + - + - - + - - + + - + - - - - + + + - - + - + - - - + + + - + - + - - + + + - - - + - - + + - - - + + - + - + + - - + + - + - + - + - + - - + + - - + + - + + - - - + + + - - - - - - - - - + + + + + + + + - + - - - - + + + + + - + - - + + - + - + - - + + - - - - - - + + + + + - - + + + - - - - + + + + - + - + - - + + - - + + - + - - + + \ No newline at end of file diff --git a/SyntaxVisitors/SugarVisitors/AssignTuplesDesugarVisitor.cs b/SyntaxVisitors/SugarVisitors/AssignTuplesDesugarVisitor.cs index 0a36b6e8e..5e16aa2fb 100644 --- a/SyntaxVisitors/SugarVisitors/AssignTuplesDesugarVisitor.cs +++ b/SyntaxVisitors/SugarVisitors/AssignTuplesDesugarVisitor.cs @@ -26,8 +26,9 @@ namespace SyntaxVisitors.SugarVisitors public override void visit(assign_tuple asstup) { + // тут возможно ошибка более глубокая - в semantic_check_sugared_statement_node(asstup) возможно остаются во вложенных лямбдах другие assign_tuple var sl = new statement_list(); - sl.Add(new semantic_check_sugared_statement_node(asstup)); // Это нужно для проверок на этапе преобразования в семантику + sl.Add(new semantic_check_sugared_statement_node(typeof(assign_tuple), new List { asstup.vars, asstup.expr })); // Это нужно для проверок на этапе преобразования в семантику var tname = "#temp_var" + UniqueNumStr(); var tt = new var_statement(new ident(tname), asstup.expr); @@ -50,7 +51,7 @@ namespace SyntaxVisitors.SugarVisitors public override void visit(assign_var_tuple assvartup) { var sl = new List(); - sl.Add(new semantic_check_sugared_statement_node(assvartup)); // Это нужно для проверок на этапе преобразования в семантику + sl.Add(new semantic_check_sugared_statement_node(typeof(assign_tuple), new List { assvartup.vars, assvartup.expr })); // Это нужно для проверок на этапе преобразования в семантику 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/SyntaxVisitors/YieldVisitors/RenameSameBlockLocalVarsVisitor.cs b/SyntaxVisitors/YieldVisitors/RenameSameBlockLocalVarsVisitor.cs index 72e0007d6..98b1d1dc8 100644 --- a/SyntaxVisitors/YieldVisitors/RenameSameBlockLocalVarsVisitor.cs +++ b/SyntaxVisitors/YieldVisitors/RenameSameBlockLocalVarsVisitor.cs @@ -78,7 +78,9 @@ namespace SyntaxVisitors var fpids = fp.params_list.SelectMany(tp => tp.idents.idents); foreach (var v in fpids) { - BlockNamesStack[CurrentLevel].Add(v.name, "$fp_"+v.name); + var low = v.name/*.ToLower()*/; + //BlockNamesStack[CurrentLevel].Add(low, "$fp_"+ low); + BlockNamesStack[CurrentLevel][low] = "$fp_" + low; } } // DO NOTHING @@ -113,8 +115,11 @@ namespace SyntaxVisitors var newLocalNames = vs.var_def.vars.idents.Select(id => { - var newName = this.CreateNewVariableName(id.name); - BlockNamesStack[CurrentLevel].Add(id.name, newName); + var low = id.name/*.ToLower()*/; + + var newName = this.CreateNewVariableName(low); + //BlockNamesStack[CurrentLevel].Add(low, newName); + BlockNamesStack[CurrentLevel][low] = newName; return new ident(newName, id.source_context); }); @@ -145,8 +150,11 @@ namespace SyntaxVisitors { var newLocalNames = vds.vars.idents.Select(id => { - var newName = this.CreateNewVariableName(id.name); - BlockNamesStack[CurrentLevel].Add(id.name, newName); + var low = id.name/*.ToLower()*/; + + var newName = this.CreateNewVariableName(low); + //BlockNamesStack[CurrentLevel].Add(low, newName); + BlockNamesStack[CurrentLevel][low] = newName; return new ident(newName, id.source_context); }); @@ -160,8 +168,8 @@ namespace SyntaxVisitors public override void visit(ident id) { - var newName = this.GetNewVariableName(id.name); - if ((object)newName != null) + var newName = this.GetNewVariableName(id.name/*.ToLower()*/); + if (newName != null) { Replace(id, new ident(newName, id.source_context)); } diff --git a/SyntaxVisitors/YieldVisitors/ReplaceVariableNameVisitor.cs b/SyntaxVisitors/YieldVisitors/ReplaceVariableNameVisitor.cs index d84242262..d39002c8c 100644 --- a/SyntaxVisitors/YieldVisitors/ReplaceVariableNameVisitor.cs +++ b/SyntaxVisitors/YieldVisitors/ReplaceVariableNameVisitor.cs @@ -13,33 +13,40 @@ namespace SyntaxVisitors { public class ReplaceVariableNameVisitor : BaseChangeVisitor { - private ident _oldName; - private ident _newName; + private string _oldName; + private string _newName; public ReplaceVariableNameVisitor(ident oldName, ident newName) { - _oldName = oldName; - _newName = newName; + _oldName = oldName.name; + _newName = newName.name; } + // Этот алгоритм маломощный и меняет всё внутри лямбды. + // Например, если переименовывается x, то + // в записи t := y->begin var x := '4'; Result := x*2 end; + // и в записи t := x->x; + // все x будут переименованы. Но это нестрашно, хотя неэффективно + public override void visit(ident id) { - if (id.name != _oldName.name) + if (id.name != _oldName) { return; } - var upperNode = UpperNode(); - if ( - upperNode != null /*&& (upperNode as dot_node) == null*/) // Я не знаю, зачем вообще было второе условие. Видимо, это всё надо убрать - { + //var upperNode = UpperNode(); + //if ( + // upperNode != null /*&& (upperNode as dot_node) == null*/) // Я не знаю, зачем вообще было второе условие. Видимо, это всё надо убрать SSM + //{ //Replace(id, _newName); // заменяются только строки, а сами идентификаторы как объекты не меняются! - id.name = _newName.name; - } + id.name = _newName; + //} } - // frninja 11/03/16 - оно тут вообще надо??? + // SSM 29/04/17 - В записи x.x обходится (и заменяется если надо) только первое x + // Важно что в записи x.x.y всё разбивается на части так: x.x и y public override void visit(dot_node dn) { ProcessNode(dn.left); diff --git a/TestSuite/errors/err0223.pas b/TestSuite/errors/err0223.pas new file mode 100644 index 000000000..094c9e304 --- /dev/null +++ b/TestSuite/errors/err0223.pas @@ -0,0 +1,4 @@ +var a : integer; +begin +a := 'ass'; +end. \ No newline at end of file diff --git a/TreeConverter/LambdaExpressions/Closure/CapturedVariablesTreeBuilder.cs b/TreeConverter/LambdaExpressions/Closure/CapturedVariablesTreeBuilder.cs index 0fb3bd0fb..24db54593 100644 --- a/TreeConverter/LambdaExpressions/Closure/CapturedVariablesTreeBuilder.cs +++ b/TreeConverter/LambdaExpressions/Closure/CapturedVariablesTreeBuilder.cs @@ -63,6 +63,11 @@ namespace TreeConverter.LambdaExpressions.Closure _identsReferences = new Dictionary>(); } + public override void visit(semantic_check_sugared_statement_node sn) + { + // Не обходить проверочные узлы в визиторе строительства дерева - SSM 1.05.17 + } + public override void visit(var_def_statement varDefStmt) { _visitor.visit(varDefStmt); diff --git a/TreeConverter/TreeConversion/semantic_checks_for_sugar.cs b/TreeConverter/TreeConversion/semantic_checks_for_sugar.cs index 545438b77..4bebe90fb 100644 --- a/TreeConverter/TreeConversion/semantic_checks_for_sugar.cs +++ b/TreeConverter/TreeConversion/semantic_checks_for_sugar.cs @@ -10,10 +10,10 @@ namespace PascalABCCompiler.TreeConverter { public partial class syntax_tree_visitor { - public void semantic_check_assign_tuple(SyntaxTree.assign_tuple asstup) // подходит и для assign_var_tuple + public void semantic_check_assign_tuple(addressed_value_list vars, expression ex) // подходит и для assign_var_tuple { // Проверить, что справа - Tuple - var expr = convert_strong(asstup.expr); + var expr = convert_strong(ex); expr = convert_if_typed_expression_to_function_call(expr); var t = ConvertSemanticTypeNodeToNETType(expr.type); @@ -23,9 +23,9 @@ namespace PascalABCCompiler.TreeConverter if (!t.FullName.StartsWith("System.Tuple")) AddError(expr.location, "TUPLE_EXPECTED"); - var n = asstup.vars.variables.Count(); + var n = vars.variables.Count(); if (n > t.GetGenericArguments().Count()) - AddError(get_location(asstup.vars), "TOO_MANY_ELEMENTS_ON_LEFT_SIDE_OF_TUPLE_ASSIGNMRNT"); + AddError(get_location(vars), "TOO_MANY_ELEMENTS_ON_LEFT_SIDE_OF_TUPLE_ASSIGNMRNT"); } void semantic_check_method_call_as_slice_expr(SyntaxTree.method_call mc) diff --git a/TreeConverter/TreeConversion/syntax_tree_visitor.cs b/TreeConverter/TreeConversion/syntax_tree_visitor.cs index d29cae014..0d4cbb843 100644 --- a/TreeConverter/TreeConversion/syntax_tree_visitor.cs +++ b/TreeConverter/TreeConversion/syntax_tree_visitor.cs @@ -14905,11 +14905,11 @@ namespace PascalABCCompiler.TreeConverter CheckForCircuralInRecord(tn, get_location(_var_def_statement.vars_type)); if (_var_def_statement.inital_value != null) if (is_event) AddError(new NotSupportedError(get_location(_var_def_statement.inital_value))); - else - { - _var_def_statement.inital_value = get_possible_array_const(_var_def_statement.inital_value,tn); - inital_value = convert_strong_to_constant_or_function_call_for_varinit(convert_strong(_var_def_statement.inital_value), tn); - } + else + { + _var_def_statement.inital_value = get_possible_array_const(_var_def_statement.inital_value,tn); + inital_value = convert_strong_to_constant_or_function_call_for_varinit(convert_strong(_var_def_statement.inital_value), tn); + } } else { @@ -19373,9 +19373,11 @@ namespace PascalABCCompiler.TreeConverter public override void visit(SyntaxTree.semantic_check_sugared_statement_node st) { - if (st.stat is SyntaxTree.assign_tuple) + if (st.typ as System.Type == typeof(SyntaxTree.assign_tuple)) { - semantic_check_assign_tuple(st.stat as SyntaxTree.assign_tuple); + var vars = st.lst[0] as SyntaxTree.addressed_value_list; + var expr = st.lst[1] as SyntaxTree.expression; + semantic_check_assign_tuple(vars,expr); } else { diff --git a/bin/Lib/PABCRtl.dll b/bin/Lib/PABCRtl.dll index 8dad7922c..436dc3dff 100644 Binary files a/bin/Lib/PABCRtl.dll and b/bin/Lib/PABCRtl.dll differ