bug fix #375
This commit is contained in:
parent
6e2de8da38
commit
ad4be08834
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
%COREVERSION%=0
|
||||
%REVISION%=1431
|
||||
%MINOR%=2
|
||||
%REVISION%=1436
|
||||
%COREVERSION%=0
|
||||
%MAJOR%=3
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
!define VERSION '3.2.0.1431'
|
||||
!define VERSION '3.2.0.1436'
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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<syntax_tree_node>();
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -38543,37 +38543,138 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
///<summary>
|
||||
///Конструктор с параметрами.
|
||||
///</summary>
|
||||
public semantic_check_sugared_statement_node(object _stat)
|
||||
public semantic_check_sugared_statement_node(object _typ,List<syntax_tree_node> _lst)
|
||||
{
|
||||
this._stat=_stat;
|
||||
this._typ=_typ;
|
||||
this._lst=_lst;
|
||||
}
|
||||
|
||||
///<summary>
|
||||
///Конструктор с параметрами.
|
||||
///</summary>
|
||||
public semantic_check_sugared_statement_node(object _stat,SourceContext sc)
|
||||
public semantic_check_sugared_statement_node(object _typ,List<syntax_tree_node> _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<syntax_tree_node> _lst=new List<syntax_tree_node>();
|
||||
|
||||
///<summary>
|
||||
///
|
||||
///</summary>
|
||||
public object stat
|
||||
public object typ
|
||||
{
|
||||
get
|
||||
{
|
||||
return _stat;
|
||||
return _typ;
|
||||
}
|
||||
set
|
||||
{
|
||||
_stat=value;
|
||||
_typ=value;
|
||||
}
|
||||
}
|
||||
|
||||
///<summary>
|
||||
///
|
||||
///</summary>
|
||||
public List<syntax_tree_node> 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<syntax_tree_node> 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<syntax_tree_node> 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<syntax_tree_node> 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<syntax_tree_node> newels)
|
||||
{
|
||||
var ind = FindIndexInList(el);
|
||||
lst.RemoveAt(ind);
|
||||
lst.InsertRange(ind, newels);
|
||||
}
|
||||
|
||||
public int RemoveAll(Predicate<syntax_tree_node> match)
|
||||
{
|
||||
return lst.RemoveAll(match);
|
||||
}
|
||||
|
||||
public syntax_tree_node Last()
|
||||
{
|
||||
return lst[lst.Count - 1];
|
||||
}
|
||||
|
||||
/// <summary> Создает копию узла </summary>
|
||||
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);
|
||||
}
|
||||
}
|
||||
///<summary>
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
///<summary>
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -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<syntax_tree_node> { 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<statement>();
|
||||
sl.Add(new semantic_check_sugared_statement_node(assvartup)); // Это нужно для проверок на этапе преобразования в семантику
|
||||
sl.Add(new semantic_check_sugared_statement_node(typeof(assign_tuple), new List<syntax_tree_node> { 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 - не работает!!!
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
4
TestSuite/errors/err0223.pas
Normal file
4
TestSuite/errors/err0223.pas
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
var a : integer;
|
||||
begin
|
||||
a := 'ass';
|
||||
end.
|
||||
|
|
@ -63,6 +63,11 @@ namespace TreeConverter.LambdaExpressions.Closure
|
|||
_identsReferences = new Dictionary<SubstitutionKey, List<ident>>();
|
||||
}
|
||||
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
Binary file not shown.
Loading…
Reference in a new issue