This commit is contained in:
Mikhalkovich Stanislav 2020-03-12 11:07:52 +03:00
parent 28a8fc115d
commit c6186a6b9f
3 changed files with 30 additions and 3 deletions

View file

@ -380,7 +380,12 @@ namespace PascalABCCompiler.SyntaxTree
(begin_position.line_num > sc1.begin_position.line_num || (begin_position.line_num == sc1.begin_position.line_num && begin_position.column_num > sc1.begin_position.column_num)) &&
(end_position.line_num < sc2.begin_position.line_num || (end_position.line_num == sc2.begin_position.line_num && end_position.column_num < sc2.begin_position.column_num));
}
}
public bool Less(SourceContext sc)
{
return begin_position.line_num < sc.begin_position.line_num || (begin_position.line_num == sc.begin_position.line_num && begin_position.column_num < sc.begin_position.column_num);
}
}
public class Utils
{

View file

@ -114,7 +114,11 @@ namespace SyntaxVisitors.CheckingVisitors
// Имена, захваченные записью. Их мы будем искать затем во внешних контекстах
// Сюда не включаются имена во вложенных безымянных записях
// Сюда не включаются имена, являющиеся определениями (в данном случае это только определения полей)
// Есть еще одна проблема - в имена, захваченные записью, не должны включаться имена, определенные в самой записи (!!!) - #2214
public List<ident> idents = new List<ident>();
public List<ident> defIdents = new List<ident>();
public class_definition StartUnnamedRecord;
public static OneUnnamedRecordCaptureNamesVisitor New(class_definition cd)
{
@ -135,7 +139,7 @@ namespace SyntaxVisitors.CheckingVisitors
var id = q.vars.idents[0]; // это просто имя
var type = q.vars_type;
var initValue = q.inital_value;
// idents.Add(id); - вот как раз не надо добавлять определения - только использования!!!
defIdents.Add(id); // Определения надо добавлять в другой список. Потом вычитать его из определений в неглобальных контекстах
ProcessNode(type);
if (initValue != null)
ProcessNode(initValue);
@ -247,6 +251,7 @@ namespace SyntaxVisitors.CheckingVisitors
var lvi = localsvis.idents.Select(id => id.name).ToArray();
var cvi = cdvis.idents;
var cvdi = cdvis.defIdents;
// Теперь проверим пересечение
foreach (var id in cvi)
@ -254,8 +259,13 @@ namespace SyntaxVisitors.CheckingVisitors
var s = id.name;
foreach (var lname in lvi)
{
if (string.Compare(s,lname,true)==0)
var ind = cvdi.FindIndex(idd => string.Compare(idd.name, lname, true) == 0);
bool b = ind != -1;
if (b)
b = cvdi[ind].source_context.Less(id.source_context);
if (string.Compare(s,lname,true)==0 && !b)
{
// то надо еще проверить cvdi чтобы там как раз не было этих имен
throw new SyntaxVisitorError("UNNAMED_RECORD_CANNOT_CATCH_NAMES_FROM_NONGLOBAL_CONTEXT", id);
}
}

12
TestSuite/unn_rec_ex.pas Normal file
View file

@ -0,0 +1,12 @@
var
A: record
j: integer;
jlocal0: record
j: integer;
i: real := j;
end;
end;
begin
end.