Вложенные безымянные записи теперь снова разрешены, но запрещено захватывать имена из неглобального контекста
This commit is contained in:
Mikhalkovich Stanislav 2020-03-08 09:28:11 +03:00
parent c204054176
commit 8545817173
28 changed files with 58753 additions and 39314 deletions

View file

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

View file

@ -1,4 +1,4 @@
%COREVERSION%=2
%REVISION%=2368
%REVISION%=2374
%MINOR%=6
%MAJOR%=3

Binary file not shown.

View file

@ -1,9 +1,9 @@
//
// This CSharp output file generated by Gardens Point LEX
// Version: 1.1.3.301
// Machine: DESKTOP-P4NLNB1
// DateTime: 2/10/2020 2:41:45 PM
// UserName: fatco
// Machine: DESKTOP-G8V08V4
// DateTime: 07.03.2020 10:31:43
// UserName: ?????????
// GPLEX input file <ABCPascal.lex>
// GPLEX frame file <embedded resource>
//

View file

@ -1550,7 +1550,7 @@ object_type
{
var cd = NewObjectType((class_attribute)$1, $2, $3 as named_type_reference_list, $4 as where_definition_list, $5 as class_body_list, @$);
$$ = cd;
var tt = cd.DescendantNodes().OfType<class_definition>().Where(cld => cld.keyword == class_keyword.Record);
/*var tt = cd.DescendantNodes().OfType<class_definition>().Where(cld => cld.keyword == class_keyword.Record);
if (tt.Count()>0)
{
foreach (var ttt in tt)
@ -1558,7 +1558,7 @@ object_type
var sc = ttt.source_context;
parsertools.AddErrorFromResource("NESTED_RECORD_DEFINITIONS_ARE_FORBIDDEN", new LexLocation(sc.begin_position.line_num, sc.begin_position.column_num-1, sc.end_position.line_num, sc.end_position.column_num, sc.FileName));
}
}
}*/
}
;

View file

@ -1,9 +1,9 @@
// (see accompanying GPPGcopyright.rtf)
// GPPG version 1.3.6
// Machine: DESKTOP-P4NLNB1
// DateTime: 2/10/2020 2:41:46 PM
// UserName: fatco
// Machine: DESKTOP-G8V08V4
// DateTime: 07.03.2020 10:31:44
// UserName: ?????????
// Input file <ABCPascal.y>
// options: no-lines gplex
@ -3973,7 +3973,7 @@ public partial class GPPGParser: ShiftReduceParser<PascalABCSavParser.Union, Lex
{
var cd = NewObjectType((class_attribute)ValueStack[ValueStack.Depth-5].ob, ValueStack[ValueStack.Depth-4].ti, ValueStack[ValueStack.Depth-3].stn as named_type_reference_list, ValueStack[ValueStack.Depth-2].stn as where_definition_list, ValueStack[ValueStack.Depth-1].stn as class_body_list, CurrentLocationSpan);
CurrentSemanticValue.td = cd;
var tt = cd.DescendantNodes().OfType<class_definition>().Where(cld => cld.keyword == class_keyword.Record);
/*var tt = cd.DescendantNodes().OfType<class_definition>().Where(cld => cld.keyword == class_keyword.Record);
if (tt.Count()>0)
{
foreach (var ttt in tt)
@ -3981,7 +3981,7 @@ public partial class GPPGParser: ShiftReduceParser<PascalABCSavParser.Union, Lex
var sc = ttt.source_context;
parsertools.AddErrorFromResource("NESTED_RECORD_DEFINITIONS_ARE_FORBIDDEN", new LexLocation(sc.begin_position.line_num, sc.begin_position.column_num-1, sc.end_position.line_num, sc.end_position.column_num, sc.FileName));
}
}
}*/
}
break;
case 284: // record_type -> tkRecord, optional_base_classes, optional_where_section,

View file

@ -262,5 +262,6 @@ script=

View file

@ -1 +1 @@
3.6.2.2368
3.6.2.2374

View file

@ -1 +1 @@
!define VERSION '3.6.2.2368'
!define VERSION '3.6.2.2374'

View file

@ -7,6 +7,7 @@ using System.Text;
using PascalABCCompiler.SyntaxTree;
using SyntaxVisitors;
using SyntaxVisitors.SugarVisitors;
using SyntaxVisitors.CheckingVisitors;
namespace PascalABCCompiler.SyntaxTreeConverters
{
@ -22,6 +23,9 @@ namespace PascalABCCompiler.SyntaxTreeConverters
// new range - до всего! До выноса выражения с лямбдой из foreach
NewRangeDesugarVisitor.New.ProcessNode(root);
// Unnamed Records перенёс сюда
UnnamedRecordsCheckVisitor.New.ProcessNode(root);
// Выносим выражения с лямбдами из заголовка foreach
StandOutExprWithLambdaInForeachSequenceVisitor.New.ProcessNode(root);
VarNamesInMethodsWithSameNameAsClassGenericParamsReplacer.New.ProcessNode(root); // SSM bug fix #1147

View file

@ -0,0 +1,266 @@
// Copyright (c) Ivan Bondarev, Stanislav Mikhalkovich (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PascalABCCompiler.SyntaxTree;
namespace SyntaxVisitors.CheckingVisitors
{
public class CollectDefNamesFromMostUpperLocalContextVisitor : BaseEnterExitVisitor
{
public List<ident> idents = new List<ident>();
public class_definition StartUnnamedRecord; // безымянная запись, до которой и для которой будем искать имена
public static CollectDefNamesFromMostUpperLocalContextVisitor New(class_definition cd)
{
return new CollectDefNamesFromMostUpperLocalContextVisitor(cd);
}
public CollectDefNamesFromMostUpperLocalContextVisitor(class_definition cd)
{
StartUnnamedRecord = cd;
}
public void Add(ident id)
{
if (idents.FindIndex(x => string.Compare(x.name, id.name, true) == 0) == -1)
idents.Add(id);
}
public void AddIdentList(ident_list idl)
{
foreach (var id in idl.idents)
Add(id);
}
public void AddProcHeader(procedure_header h)
{
Add(h.name.meth_name);
if (h.template_args != null)
AddIdentList(h.template_args);
if (h.parameters != null)
foreach (var tp in h.parameters.params_list)
{
AddIdentList(tp.idents);
}
}
/*public override void visit(template_type_name ttn) // при определении типа
{
Add(ttn);
AddIdentList(ttn.template_args);
}*/
public override void visit(var_def_statement vds)
{
AddIdentList(vds.vars);
ProcessNode(vds.vars_type);
}
/*public override void visit(typed_parameters tp)
{
AddIdentList(tp.idents);
}*/
public override void visit(procedure_header h)
{
AddProcHeader(h);
}
public override void visit(function_header h)
{
AddProcHeader(h);
}
public override void visit(typed_const_definition cd)
{
Add(cd.const_name);
}
public override void visit(simple_const_definition cd)
{
Add(cd.const_name);
}
public override void visit(type_declaration td)
{
Add(td.type_name);
if (td.type_name is template_type_name ttn)
{
AddIdentList(ttn.template_args);
}
ProcessNode(td.type_def);
}
// var_def_statement.idents +
// typed_parameters (параметры процедуры-функции) +
// method_name +
// template_type_name +
// type_declaration.type_name
// const_definition.constant_name +
public override void visit(class_definition cd)
{
if (cd == StartUnnamedRecord)
{
//cd = cd;
// то внутри нее не искать - мы как раз с ней и проверяем пересечение имен
}
else if (StartUnnamedRecord.source_context.In(cd.source_context))
{
DefaultVisit(cd);
}
else
{
}
}
}
public class OneUnnamedRecordCaptureNamesVisitor : BaseEnterExitVisitor
{
// Имена, захваченные записью. Их мы будем искать затем во внешних контекстах
// Сюда не включаются имена во вложенных безымянных записях
// Сюда не включаются имена, являющиеся определениями (в данном случае это только определения полей)
public List<ident> idents = new List<ident>();
public class_definition StartUnnamedRecord;
public static OneUnnamedRecordCaptureNamesVisitor New(class_definition cd)
{
return new OneUnnamedRecordCaptureNamesVisitor(cd);
}
public OneUnnamedRecordCaptureNamesVisitor(class_definition cd)
{
StartUnnamedRecord = cd;
}
// Накопленные имена типов надо будет сравнивать только с именами в секции type (в процедуре) и с именами в параметрах внешних обобщений (процедур и классов)
public void CollectNames()
{
var defBlocks = StartUnnamedRecord.body.class_def_blocks;
// Теперь известно, что остался ровно один class_def_block
foreach (var member in defBlocks[0].members)
{
var q = member as var_def_statement;
var id = q.vars.idents[0]; // это просто имя
var type = q.vars_type;
var initValue = q.inital_value;
// idents.Add(id); - вот как раз не надо добавлять определения - только использования!!!
ProcessNode(type);
if (initValue != null)
ProcessNode(initValue);
}
}
public override void visit(ident id)
{
if (idents.FindIndex(x => string.Compare(x.name,id.name,true) == 0) == -1)
idents.Add(id);
}
public override void visit(named_type_reference ntr)
{
visit(ntr.names[0]);
if (ntr is template_type_reference ttr)
{
foreach (var tt in ttr.params_list.params_list)
ProcessNode(tt);
}
}
public override void visit(class_definition cd)
{
if (cd.keyword == class_keyword.Record && cd.Parent is var_def_statement) // безымянная запись
{
// то пропустить её - она вложенная, мы её уже обошли
}
else base.visit(cd);
}
}
public class UnnamedRecordsCheckVisitor : BaseEnterExitVisitor
{
public static UnnamedRecordsCheckVisitor New
{
get { return new UnnamedRecordsCheckVisitor(); }
}
public override void Exit(syntax_tree_node st)
{
var cd = st as class_definition;
if (cd == null)
return;
if (cd.keyword == class_keyword.Record && cd.Parent is var_def_statement) // безымянная запись
{
if (cd.class_parents != null && cd.class_parents.Count > 0)
throw new SyntaxVisitorError("UNNAMED_RECORD_CANNOT_IMPLEMENT_INTERFACE", cd.class_parents[0].source_context);
var defBlocks = cd.body.class_def_blocks;
if (defBlocks[0].access_mod.access_level != access_modifer.public_modifer)
{
var f = cd.body.class_def_blocks.First();
var loc = f.source_context;
if (loc == null)
loc = cd.source_context;
throw new SyntaxVisitorError("UNNAMED_RECORD_CAN_CONTAIN_ONLY_ONE_PUBLIC_VISIBILITY_SECTION", loc);
}
if (defBlocks.Count > 1)
{
var el1 = cd.body.class_def_blocks.ElementAt(1);
var loc = el1.access_mod.source_context;
if (loc == null)
loc = cd.source_context;
throw new SyntaxVisitorError("UNNAMED_RECORD_CANNOT_CONTAIN_SEVERAL_VISIBILITY_SECTIONS", loc);
}
// здесь уже известно, что defBlocks.Count = 1 - пройтись по этому блоку и проверить, нет ли методов или свойств
foreach (var d in defBlocks[0].members)
{
var pd = d as procedure_definition;
if (pd != null)
throw new SyntaxVisitorError("UNNAMED_RECORD_CANNOT_CONTAIN_METHODS", pd.source_context);
var sp = d as simple_property;
if (sp != null)
throw new SyntaxVisitorError("UNNAMED_RECORD_CANNOT_CONTAIN_PROPERTIES", sp.source_context);
}
var cdvis = OneUnnamedRecordCaptureNamesVisitor.New(cd);
cdvis.CollectNames();
// после накопления имен подниматься по внешнему контексту, пропуская эту запись, и искать переменные и типы
// Переменные - в var_def_statement. Типы - в type_definition, в типовых параметрах обобщенных процедур и в типовых параметрах имен типов
// Подняться вверх до program_module и запомнить последнюю class_definition, procedure_definition
// или class_definition или type_declaration если это именованный тип
// То есть у class_definition проверять Parent - если это type_declaration, то смотреть на имя типа, а если это var_def_statement, то смотреть на имена переменных
syntax_tree_node MostUpperNodeWithNotGlobalNames = null;
syntax_tree_node sn = cd;
while ((sn != null) && !(sn is program_module))
{
sn = sn.Parent;
if (sn is procedure_definition)
MostUpperNodeWithNotGlobalNames = sn;
if (sn is class_definition)
{
MostUpperNodeWithNotGlobalNames = sn;
sn = sn.Parent;
if (sn is type_declaration || sn is var_def_statement)
MostUpperNodeWithNotGlobalNames = sn;
}
}
var localsvis = CollectDefNamesFromMostUpperLocalContextVisitor.New(cd);
if (MostUpperNodeWithNotGlobalNames != null)
{
localsvis.ProcessNode(MostUpperNodeWithNotGlobalNames);
}
var lvi = localsvis.idents.Select(id => id.name).ToArray();
var cvi = cdvis.idents;
// Теперь проверим пересечение
foreach (var id in cvi)
{
var s = id.name;
foreach (var lname in lvi)
{
if (string.Compare(s,lname,true)==0)
{
throw new SyntaxVisitorError("UNNAMED_RECORD_CANNOT_CATCH_NAMES_FROM_NONGLOBAL_CONTEXT", id);
}
}
}
}
}
}
}

View file

@ -46,6 +46,7 @@
<Compile Include="BaseVisitors\HasStatementVisitor.cs" />
<Compile Include="BaseVisitors\SmallHelperVisitors.cs" />
<Compile Include="ChangeWhileVisitor.cs" />
<Compile Include="CheckingVisitors\UnnamedRecordsCheckErrorsVisitor.cs" />
<Compile Include="LightSymInfoVisitors\LightScopeHelperClasses.cs" />
<Compile Include="LightSymInfoVisitors\SymInfoCollect1.cs" />
<Compile Include="LightSymInfoVisitors\SymInfoCollect1Helper.cs" />
@ -116,9 +117,7 @@
<Name>YieldHelpers</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Folder Include="CheckingVisitors\" />
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.

File diff suppressed because it is too large Load diff

View file

@ -39,6 +39,9 @@ uses System.Runtime.CompilerServices;
//===================================
// Обязательно сделать до следующего пула:
//ToDo Тесты всех фич модуля
//ToDo И в каждом сделать по несколько выполнений, на случай плавающий ошибок
//===================================
// Запланированное:
@ -97,8 +100,6 @@ uses System.Runtime.CompilerServices;
//ToDo Пройтись по всем функциям OpenCL, посмотреть функционал каких не доступен из OpenCLABC
// - у Kernel.Exec несколько параметров не используются. Стоит использовать
//ToDo Тесты всех фич модуля
//===================================
//ToDo issue компилятора:
@ -137,7 +138,7 @@ type
ProgramCode = class;
DeviceTypeFlags = OpenCL.DeviceTypeFlags;
DeviceType = OpenCL.DeviceType;
{$endregion pre def}
@ -145,10 +146,11 @@ type
__NativUtils = static class
static function CopyToUnm<TRecord>(a: TRecord): ^TRecord; where TRecord: record;
static function CopyToUnm<TRecord>(a: TRecord): IntPtr; where TRecord: record;
begin
Result := pointer(Marshal.AllocHGlobal(Marshal.SizeOf&<TRecord>));
Result^ := a;
Result := Marshal.AllocHGlobal(Marshal.SizeOf&<TRecord>);
var res: ^TRecord := pointer(Result);
res^ := a;
end;
static function AsPtr<T>(p: pointer): ^T := p;
@ -156,10 +158,10 @@ type
static function GCHndAlloc(o: object) :=
CopyToUnm(GCHandle.Alloc(o));
static procedure GCHndFree(gc_hnd_ptr: pointer);
static procedure GCHndFree(gc_hnd_ptr: IntPtr);
begin
AsPtr&<GCHandle>(gc_hnd_ptr)^.Free;
Marshal.FreeHGlobal(IntPtr(gc_hnd_ptr));
AsPtr&<GCHandle>(pointer(gc_hnd_ptr))^.Free;
Marshal.FreeHGlobal(gc_hnd_ptr);
end;
end;
@ -199,14 +201,8 @@ type
public static procedure operator+=(l: __EventList; ev: __EventList);
begin
{$ifdef DebugMode}
for var i := 0 to ev.count-1 do
l += ev[i];
exit;
{$endif DebugMode}
if ev.count=0 then exit;
System.Buffer.BlockCopy( ev.evs,0, l.evs,l.count*cl_event.Size, ev.count*cl_event.Size );
l.count += ev.count;
end;
public static function operator+(l1,l2: __EventList): __EventList;
@ -231,12 +227,12 @@ type
for var i := 0 to count-1 do
cl.ReleaseEvent(evs[i]).RaiseIfError;
public static procedure AttachCallback(ev: cl_event; cb: Event_Callback);
public static procedure AttachCallback(ev: cl_event; cb: Event_Callback; tsk: CLTaskBase);
public static procedure AttachCallback(ev: cl_event; cb: EventCallback);
public static procedure AttachCallback(ev: cl_event; cb: EventCallback; tsk: CLTaskBase);
///cb должен иметь глобальный try и вызывать "state.RaiseIfError" и "__NativUtils.GCHndFree(data)",
///А "cl.ReleaseEvent" если и вызывать - то только на результате вызова AttachCallback
public function AttachCallback(cb: Event_Callback; c: Context; var cq: cl_command_queue): cl_event;
public function AttachCallback(cb: EventCallback; c: Context; var cq: cl_command_queue): cl_event;
end;
@ -255,7 +251,7 @@ type
function WaitAndGetBase: object;
function AttachCallbackBase(cb: Event_Callback; c: Context; var cq: cl_command_queue): __IQueueRes;
function AttachCallbackBase(cb: EventCallback; c: Context; var cq: cl_command_queue): __IQueueRes;
end;
__QueueRes<T> = record(__IQueueRes)
@ -306,13 +302,13 @@ type
end;
function AttachCallback(cb: Event_Callback; c: Context; var cq: cl_command_queue): __QueueRes<T>;
function AttachCallback(cb: EventCallback; c: Context; var cq: cl_command_queue): __QueueRes<T>;
begin
Result.res := self.res;
Result.res_f := self.res_f;
Result.ev := self.ev.AttachCallback(cb, c, cq);
end;
function AttachCallbackBase(cb: Event_Callback; c: Context; var cq: cl_command_queue): __IQueueRes := AttachCallback(cb, c, cq);
function AttachCallbackBase(cb: EventCallback; c: Context; var cq: cl_command_queue): __IQueueRes := AttachCallback(cb, c, cq);
end;
@ -513,7 +509,7 @@ type
if err.IS_ERROR then AddErr(new OpenCLException(err.ToString));
protected procedure AddErr(st: CommandExecutionStatus) :=
if st.IS_ERROR then AddErr(new OpenCLException(st.GetError.ToString));
if st.IS_ERROR then AddErr(new OpenCLException(ErrorCode.Create(st).ToString));
/// Возвращает True если очередь уже завершилась
protected function AddEventHandler<T>(var ev: T; cb: T): boolean; where T: Delegate;
@ -1466,24 +1462,24 @@ type
_def_cont := new Context;
except
try
_def_cont := new Context(DeviceTypeFlags.All); // если нету GPU - попытаться хотя бы для чего то инициализировать
_def_cont := new Context(DeviceType.DEVICE_TYPE_ALL); // если нету GPU - попытаться хотя бы для чего то инициализировать
except
_def_cont := nil;
end;
end;
public constructor := Create(DeviceTypeFlags.GPU);
public constructor := Create(DeviceType.DEVICE_TYPE_GPU);
public constructor(dt: DeviceTypeFlags);
public constructor(dt: DeviceType);
begin
var ec: ErrorCode;
var _platform: cl_platform_id;
cl.GetPlatformIDs(1, @_platform, nil).RaiseIfError;
cl.GetPlatformIDs(1, _platform, IntPtr.Zero).RaiseIfError;
cl.GetDeviceIDs(_platform, dt, 1, @_device, nil).RaiseIfError;
cl.GetDeviceIDs(_platform, dt, 1, _device, IntPtr.Zero).RaiseIfError;
_context := cl.CreateContext(nil, 1, @_device, nil, nil, @ec);
_context := cl.CreateContext(IntPtr.Zero, 1, _device, nil, IntPtr.Zero, ec);
ec.RaiseIfError;
need_finnalize := true;
@ -1492,7 +1488,7 @@ type
public constructor(context: cl_context);
begin
cl.GetContextInfo(context, ContextInfoType.CL_CONTEXT_DEVICES, new UIntPtr(IntPtr.Size), @_device, nil).RaiseIfError;
cl.GetContextInfo(context, ContextInfo.CONTEXT_DEVICES, new UIntPtr(IntPtr.Size), _device, IntPtr.Zero).RaiseIfError;
_context := context;
end;
@ -1533,7 +1529,7 @@ type
self._program := cl.CreateProgramWithSource(c._context, files_texts.Length, files_texts, files_texts.ConvertAll(s->new UIntPtr(s.Length)), ec);
ec.RaiseIfError;
cl.BuildProgram(self._program, 1, @c._device, nil,nil,nil).RaiseIfError;
cl.BuildProgram(self._program, 1,c._device, nil, nil,IntPtr.Zero).RaiseIfError;
end;
@ -1548,12 +1544,13 @@ type
public function GetAllKernels: Dictionary<string, Kernel>;
begin
// Можно и "cl.CreateKernelsInProgram", но тогда имена придётся получать отдельно, а они нужны
var names_char_len: UIntPtr;
cl.GetProgramInfo(_program, ProgramInfoType.NUM_KERNELS, new UIntPtr(UIntPtr.Size), @names_char_len, nil).RaiseIfError;
cl.GetProgramInfo(_program, ProgramInfo.PROGRAM_KERNEL_NAMES, UIntPtr.Zero,IntPtr.Zero, names_char_len).RaiseIfError;
var names_ptr := Marshal.AllocHGlobal(IntPtr(pointer(names_char_len))+1);
cl.GetProgramInfo(_program, ProgramInfoType.KERNEL_NAMES, names_char_len, pointer(names_ptr), nil).RaiseIfError;
var names_ptr := Marshal.AllocHGlobal(IntPtr(pointer(names_char_len)));
cl.GetProgramInfo(_program, ProgramInfo.PROGRAM_KERNEL_NAMES, names_char_len,names_ptr, IntPtr.Zero).RaiseIfError;
var names := Marshal.PtrToStringAnsi(names_ptr).Split(';');
Marshal.FreeHGlobal(names_ptr);
@ -1571,14 +1568,10 @@ type
public function Serialize: array of byte;
begin
var bytes_count: UIntPtr;
cl.GetProgramInfo(_program, ProgramInfoType.BINARY_SIZES, new UIntPtr(UIntPtr.Size), @bytes_count, nil).RaiseIfError;
cl.GetProgramInfo(_program, ProgramInfo.PROGRAM_BINARY_SIZES, new UIntPtr(UIntPtr.Size),bytes_count, IntPtr.Zero).RaiseIfError;
var bytes_mem := Marshal.AllocHGlobal(IntPtr(pointer(bytes_count)));
cl.GetProgramInfo(_program, ProgramInfoType.BINARIES, new UIntPtr(UIntPtr.Size), @bytes_mem, nil).RaiseIfError;
Result := new byte[bytes_count.ToUInt64()];
Marshal.Copy(bytes_mem,Result, 0,Result.Length);
Marshal.FreeHGlobal(bytes_mem);
Result := new byte[bytes_count.ToUInt64];
cl.GetProgramInfo(_program, ProgramInfo.PROGRAM_BINARIES, bytes_count,Result[0], IntPtr.Zero).RaiseIfError;
end;
@ -1597,17 +1590,16 @@ type
public static function Deserialize(c: Context; bin: array of byte): ProgramCode;
begin
var ec: ErrorCode;
Result := new ProgramCode;
var gchnd := GCHandle.Alloc(bin, GCHandleType.Pinned);
var bin_mem: ^byte := pointer(gchnd.AddrOfPinnedObject);
var bin_len := new UIntPtr(bin.Length);
Result._program := cl.CreateProgramWithBinary(c._context,1,@c._device, @bin_len, @bin_mem, nil, @ec);
var bin_arr: array of array of byte;
SetLength(bin_arr,1);
bin_arr[0] := bin;
var ec: ErrorCode;
Result._program := cl.CreateProgramWithBinary(c._context,1,c._device, bin_len,bin_arr, IntPtr.Zero,ec);
ec.RaiseIfError;
gchnd.Free;
end;
@ -1833,12 +1825,12 @@ end;
{$endregion CommandQueue}
static procedure __EventList.AttachCallback(ev: cl_event; cb: Event_Callback) :=
static procedure __EventList.AttachCallback(ev: cl_event; cb: EventCallback) :=
cl.SetEventCallback(ev, CommandExecutionStatus.COMPLETE, cb, __NativUtils.GCHndAlloc(cb)).RaiseIfError;
static procedure __EventList.AttachCallback(ev: cl_event; cb: Event_Callback; tsk: CLTaskBase) :=
static procedure __EventList.AttachCallback(ev: cl_event; cb: EventCallback; tsk: CLTaskBase) :=
tsk.AddErr( cl.SetEventCallback(ev, CommandExecutionStatus.COMPLETE, cb, __NativUtils.GCHndAlloc(cb)) );
function __EventList.AttachCallback(cb: Event_Callback; c: Context; var cq: cl_command_queue): cl_event;
function __EventList.AttachCallback(cb: EventCallback; c: Context; var cq: cl_command_queue): cl_event;
begin
var ev: cl_event;
@ -1848,7 +1840,7 @@ begin
if cq=cl_command_queue.Zero then
begin
var ec: ErrorCode;
cq := cl.CreateCommandQueue(c._context, c._device, CommandQueuePropertyFlags.NONE, ec);
cq := cl.CreateCommandQueueWithProperties(c._context,c._device, IntPtr.Zero, ec);
ec.RaiseIfError;
end;
@ -2851,7 +2843,7 @@ type
if cq=cl_command_queue.Zero then
begin
var ec: ErrorCode;
cq := cl.CreateCommandQueue(c._context, c._device, CommandQueuePropertyFlags.NONE, ec);
cq := cl.CreateCommandQueueWithProperties(c._context,c._device, IntPtr.Zero, ec);
ec.RaiseIfError;
end;
@ -2890,7 +2882,7 @@ type
end).Start else
begin
var set_complete: Event_Callback := (ev,st,data)->
var set_complete: EventCallback := (ev,st,data)->
begin
tsk.AddErr( st );
@ -2982,7 +2974,7 @@ type
var res_ev: cl_event;
cl.EnqueueWriteBuffer(
l_cq, b.memobj, 0,
l_cq, b.memobj, Bool.NON_BLOCKING,
new UIntPtr(offset.Get), new UIntPtr(len.Get),
ptr.Get,
prev_ev.count,prev_ev.evs,res_ev
@ -3027,10 +3019,10 @@ type
begin
cl.EnqueueWriteBuffer(
l_cq, b.memobj, 1,
l_cq, b.memobj, Bool.BLOCKING,
new UIntPtr(offset.WaitAndGet), new UIntPtr(len.WaitAndGet),
Marshal.UnsafeAddrOfPinnedArrayElement(a.WaitAndGet,0),
0,nil,nil
0,IntPtr.Zero,IntPtr.Zero
).RaiseIfError;
Result := cl_event.Zero;
@ -3053,7 +3045,7 @@ type
public constructor(val: T; offset_q: CommandQueue<integer>);
begin
self.val := new IntPtr(__NativUtils.CopyToUnm(val));
self.val := __NativUtils.CopyToUnm(val);
self.offset_q := offset_q;
end;
@ -3069,7 +3061,7 @@ type
var res_ev: cl_event;
cl.EnqueueWriteBuffer(
l_cq, b.memobj, 0,
l_cq, b.memobj, Bool.NON_BLOCKING,
new UIntPtr(offset.Get), new UIntPtr(Marshal.SizeOf&<T>),
self.val,
prev_ev.count,prev_ev.evs,res_ev
@ -3110,10 +3102,10 @@ type
Result := (b, l_c, l_cq, prev_ev)->
begin
var res_ev: cl_event;
var val_ptr := new IntPtr(__NativUtils.CopyToUnm(val.Get()));
var val_ptr := __NativUtils.CopyToUnm(val.Get());
cl.EnqueueWriteBuffer(
l_cq, b.memobj, 0,
l_cq, b.memobj, Bool.NON_BLOCKING,
new UIntPtr(offset.Get), new UIntPtr(Marshal.SizeOf&<T>),
val_ptr,
prev_ev.count,prev_ev.evs,res_ev
@ -3184,7 +3176,7 @@ type
var res_ev: cl_event;
cl.EnqueueReadBuffer(
l_cq, b.memobj, 0,
l_cq, b.memobj, Bool.NON_BLOCKING,
new UIntPtr(offset.Get), new UIntPtr(len.Get),
ptr.Get,
prev_ev.count,prev_ev.evs,res_ev
@ -3229,10 +3221,10 @@ type
begin
cl.EnqueueReadBuffer(
l_cq, b.memobj, 1,
l_cq, b.memobj, Bool.BLOCKING,
new UIntPtr(offset.WaitAndGet), new UIntPtr(len.WaitAndGet),
Marshal.UnsafeAddrOfPinnedArrayElement(a.WaitAndGet,0),
0,nil,nil
0,IntPtr.Zero,IntPtr.Zero
).RaiseIfError;
Result := cl_event.Zero;
@ -3346,8 +3338,8 @@ type
new UIntPtr(offset.WaitAndGet), new UIntPtr(len.WaitAndGet),
prev_ev.count,prev_ev.evs,res_ev
).RaiseIfError;
cl.WaitForEvents(1,@res_ev);
cl.ReleaseEvent(res_ev);
cl.WaitForEvents(1,res_ev).RaiseIfError;
cl.ReleaseEvent(res_ev).RaiseIfError;
a_hnd.Free;
Result := cl_event.Zero;
@ -3370,7 +3362,7 @@ type
public constructor(val: T; offset_q, len_q: CommandQueue<integer>);
begin
self.val := new IntPtr(__NativUtils.CopyToUnm(val));
self.val := __NativUtils.CopyToUnm(val);
self.offset_q := offset_q;
self.len_q := len_q;
end;
@ -3432,7 +3424,7 @@ type
Result := (b, l_c, l_cq, prev_ev)->
begin
var res_ev: cl_event;
var val_ptr := new IntPtr(__NativUtils.CopyToUnm(val.Get()));
var val_ptr := __NativUtils.CopyToUnm(val.Get());
cl.EnqueueFillBuffer(
l_cq, b.memobj,
@ -3704,7 +3696,7 @@ begin
if self.memobj<>cl_mem.Zero then Dispose;
GC.AddMemoryPressure(Size64);
var ec: ErrorCode;
self.memobj := cl.CreateBuffer(c._context, MemoryFlags.READ_WRITE, self.sz, IntPtr.Zero, ec);
self.memobj := cl.CreateBuffer(c._context, MemFlags.MEM_READ_WRITE, self.sz, IntPtr.Zero, ec);
ec.RaiseIfError;
end;
@ -3720,7 +3712,7 @@ begin
new UIntPtr( offset ),
new UIntPtr( size )
);
Result.memobj := cl.CreateSubBuffer(self.memobj, MemoryFlags.READ_WRITE, BufferCreateType.REGION, pointer(@reg), ec);
Result.memobj := cl.CreateSubBuffer(self.memobj, MemFlags.MEM_READ_WRITE, BufferCreateType.BUFFER_CREATE_TYPE_REGION,reg, ec);
ec.RaiseIfError;
end;

File diff suppressed because it is too large Load diff

View file

@ -252,6 +252,9 @@ type
/// Представляет результаты из набора групп при выполнении Regex.Match
RegexGroupCollection = System.Text.RegularExpressions.GroupCollection;
/// Предоставляет методы для точного измерения затраченного времени
Stopwatch = System.Diagnostics.Stopwatch;
/// Представляет тип короткой строки фиксированной длины 255 символов
ShortString = string[255];
@ -585,6 +588,146 @@ type
/// Считывает строку из бестипового файла
function ReadString: string;
end;
type
/// Тип диапазона целых
IntRange = class(IEnumerable<integer>)
private
l,h: integer;
function GetCount: integer;
begin
Result := h-l+1;
if Result<0 then
Result := 0;
end;
public
constructor(l,h: integer);
begin
Self.l := l;
Self.h := h;
end;
property Low: integer read l;
property High: integer read h;
property Count: integer read GetCount;
static function operator in(x: integer; r: IntRange): boolean := (x >= r.l) and (x <= r.h);
static function operator=(r1,r2: IntRange): boolean := (r1.l = r2.l) and (r1.h = r2.h);
function IsEmpty: boolean := l<=h;
function GetEnumerator(): IEnumerator<integer>;
function System.Collections.IEnumerable.GetEnumerator: System.Collections.IEnumerator := Self.GetEnumerator;
function ToString: string; override := $'({l},{h})';
function Equals(o: Object): boolean; override;
begin
var r2 := IntRange(o);
Result := (l = r2.l) and (h = r2.h);
end;
function GetHashCode: integer; override := l.GetHashCode xor h.GetHashCode;
function ToArray: array of integer;
begin
Result := new integer[Count];
var x := l;
for var i := 0 to Result.Length - 1 do
begin
Result[i] := x;
x += 1;
end;
end;
function ToList: List<integer>;
begin
Result := new List<integer>;
var x := l;
loop Count do
begin
Result.Add(x);
x += 1;
end;
end;
function ToLinkedList: LinkedList<integer>;
begin
Result := new LinkedList<integer>(System.Linq.Enumerable.Range(l,Count));
end;
function ToHashSet: HashSet<integer>;
begin
Result := new HashSet<integer>(System.Linq.Enumerable.Range(l,Count));
end;
function ToSortedSet: SortedSet<integer>;
begin
Result := new SortedSet<integer>(System.Linq.Enumerable.Range(l,Count));
end;
end;
/// Тип диапазона символов
CharRange = class(IEnumerable<char>)
private
l,h: char;
function GetCount: integer;
begin
Result := integer(h) - integer(l)+1;
if Result<0 then
Result := 0;
end;
public
constructor(l,h: char);
begin
Self.l := l;
Self.h := h;
end;
property Low: char read l;
property High: char read h;
property Count: integer read GetCount;
static function operator in(x: char; r: CharRange): boolean := (x >= r.l) and (x <= r.h);
static function operator=(r1,r2: CharRange): boolean := (r1.l = r2.l) and (r1.h = r2.h);
function IsEmpty: boolean := l<=h;
function GetEnumerator(): IEnumerator<char>;
function System.Collections.IEnumerable.GetEnumerator: System.Collections.IEnumerator := GetEnumerator;
function ToString: string; override := $'({l},{h})';
function Equals(o: Object): boolean; override;
begin
var r2 := CharRange(o);
Result := (l = r2.l) and (h = r2.h);
end;
function GetHashCode: integer; override := l.GetHashCode xor h.GetHashCode;
function ToArray: array of char;
begin
Result := new char[Count];
var x := l;
for var i := 0 to Result.Length - 1 do
begin
Result[i] := x;
x := char(integer(x) + 1);
end;
end;
function ToList: List<char>;
begin
Result := new List<char>;
var x := l;
loop Count do
begin
Result.Add(x);
x := char(integer(x) + 1);
end;
end;
function ToLinkedList: LinkedList<char>;
begin
Result := new LinkedList<char>(System.Linq.Enumerable.Range(integer(l),Count).Select(i -> char(i)));
end;
function ToHashSet: HashSet<char>;
begin
Result := new HashSet<char>(System.Linq.Enumerable.Range(integer(l),Count).Select(i -> char(i)));
end;
function ToSortedSet: SortedSet<char>;
begin
Result := new SortedSet<char>(System.Linq.Enumerable.Range(integer(l),Count).Select(i -> char(i)));
end;
end;
//{{{doc: Начало секции интерфейса для документации }}}
@ -1965,6 +2108,11 @@ function ReadSeqStringWhile(prompt: string; cond: string->boolean): sequence of
function Arr<T>(params a: array of T): array of T;
/// Возвращает массив, заполненный значениями из последовательнсти
function Arr<T>(a: sequence of T): array of T;
/// Возвращает массив, заполненный диапазоном значений
function Arr(a: IntRange): array of integer;
/// Возвращает массив, заполненный диапазоном значений
function Arr(a: CharRange): array of char;
/// Возвращает массив размера n, заполненный случайными целыми значениями
function ArrRandom(n: integer := 10; a: integer := 0; b: integer := 100): array of integer;
/// Возвращает массив размера n, заполненный случайными целыми значениями
@ -2054,18 +2202,39 @@ function Rec<T1, T2, T3, T4, T5, T6, T7>(x1: T1; x2: T2; x3: T3; x4: T4; x5: T5;
function Lst<T>(params a: array of T): List<T>;
/// Возвращает список, заполненный значениями из последовательности
function Lst<T>(a: sequence of T): List<T>;
/// Возвращает список, заполненный диапазоном значений
function Lst(a: IntRange): List<integer>;
/// Возвращает список, заполненный диапазоном значений
function Lst(a: CharRange): List<char>;
/// Возвращает двусвязный список, заполненный указанными значениями
function LLst<T>(params a: array of T): LinkedList<T>;
/// Возвращает двусвязный список, заполненный значениями из последовательности
function LLst<T>(a: sequence of T): LinkedList<T>;
/// Возвращает двусвязный список, заполненный диапазоном значений
function LLst(a: IntRange): LinkedList<integer>;
/// Возвращает двусвязный список, заполненный диапазоном значений
function LLst(a: CharRange): LinkedList<char>;
/// Возвращает множество на базе хеш таблицы, заполненное указанными значениями
function HSet<T>(params a: array of T): HashSet<T>;
/// Возвращает множество на базе хеш таблицы, заполненное значениями из последовательности
function HSet<T>(a: sequence of T): HashSet<T>;
/// Возвращает множество на базе хеш таблицы, заполненное диапазоном значений
function HSet(a: IntRange): HashSet<integer>;
/// Возвращает множество на базе хеш таблицы, заполненное заполненный диапазоном значений
function HSet(a: CharRange): HashSet<char>;
/// Возвращает множество на базе бинарного дерева поиска, заполненное значениями из последовательности
function SSet<T>(params a: array of T): SortedSet<T>;
/// Возвращает множество на базе бинарного дерева поиска, заполненное значениями из последовательности
function SSet<T>(a: sequence of T): SortedSet<T>;
/// Возвращает множество на базе на базе бинарного дерева поиска, заполненное диапазоном значений
function SSet(a: IntRange): SortedSet<integer>;
/// Возвращает множество на базе на базе бинарного дерева поиска, заполненное заполненный диапазоном значений
function SSet(a: CharRange): SortedSet<char>;
/// Возвращает словарь пар элементов (ключ, значение)
function Dict<TKey, TVal>(params pairs: array of KeyValuePair<TKey, TVal>): Dictionary<TKey, TVal>;
/// Возвращает словарь пар элементов (ключ, значение)
@ -2427,67 +2596,6 @@ type
end;
type
/// Тип диапазона целых
IntRange = class(IEnumerable<integer>)
private
l,h: integer;
public
constructor(l,h: integer);
begin
Self.l := l;
Self.h := h;
end;
property Low: integer read l;
property High: integer read h;
static function operator in(x: integer; r: IntRange): boolean := (x >= r.l) and (x <= r.h);
static function operator=(r1,r2: IntRange): boolean := (r1.l = r2.l) and (r1.h = r2.h);
function IsEmpty: boolean := l<=h;
function GetEnumerator(): IEnumerator<integer> := Range(l,h).GetEnumerator;
function System.Collections.IEnumerable.GetEnumerator: System.Collections.IEnumerator := Range(l,h).GetEnumerator;
function ToString: string; override := $'({l},{h})';
function Equals(o: Object): boolean; override;
begin
var r2 := IntRange(o);
Result := (l = r2.l) and (h = r2.h);
end;
function GetHashCode: integer; override := l.GetHashCode xor h.GetHashCode;
end;
/// Тип диапазона символов
CharRange = class(IEnumerable<char>)
private
l,h: char;
public
constructor(l,h: char);
begin
Self.l := l;
Self.h := h;
end;
property Low: char read l;
property High: char read h;
static function operator in(x: char; r: CharRange): boolean := (x >= r.l) and (x <= r.h);
static function operator=(r1,r2: CharRange): boolean := (r1.l = r2.l) and (r1.h = r2.h);
function IsEmpty: boolean := l<=h;
function GetEnumerator(): IEnumerator<char> := Range(l,h).GetEnumerator;
function System.Collections.IEnumerable.GetEnumerator: System.Collections.IEnumerator := Range(l,h).GetEnumerator;
function ToString: string; override := $'({l},{h})';
function Equals(o: Object): boolean; override;
begin
var r2 := CharRange(o);
Result := (l = r2.l) and (h = r2.h);
end;
function GetHashCode: integer; override := l.GetHashCode xor h.GetHashCode;
end;
///--
function InternalRange(l,r: integer): IntRange;
///--
@ -3761,6 +3869,10 @@ begin
Result := sb.ToString;
end;
function IntRange.GetEnumerator(): IEnumerator<integer> := Range(l,h).GetEnumerator;
function CharRange.GetEnumerator(): IEnumerator<char> := Range(l,h).GetEnumerator;
//------------------------------------------------------------------------------
// Операции для string и char
//------------------------------------------------------------------------------
@ -4371,6 +4483,20 @@ begin
Result := a.ToArray;
end;
function Arr(a: IntRange): array of integer := a.ToArray;
function Arr(a: CharRange): array of char;
begin
var n := integer(a.High) - integer(a.Low) + 1;
Result := new char[n];
var x := a.Low;
for var i := 0 to n-1 do
begin
Result[i] := x;
Inc(x)
end;
end;
function Seq<T>(params a: array of T): sequence of T;
begin
var res := new T[a.Length];
@ -4681,45 +4807,39 @@ function Rec<T1, T2, T3, T4, T5, T6, T7>(x1: T1; x2: T2; x3: T3; x4: T4; x5: T5;
// -----------------------------------------------------------------------------
// Функции Lst, LLst, Dict, KV, HSet, SSet
// -----------------------------------------------------------------------------
function Lst<T>(params a: array of T): List<T>;
begin
Result := new List<T>(a);
end;
function Lst<T>(params a: array of T): List<T> := new List<T>(a);
function Lst<T>(a: sequence of T): List<T>;
begin
Result := new List<T>(a);
end;
function Lst<T>(a: sequence of T): List<T> := new List<T>(a);
function LLst<T>(params a: array of T): LinkedList<T>;
begin
Result := new LinkedList<T>(a);
end;
function Lst(a: IntRange): List<integer> := a.ToList;
function LLst<T>(a: sequence of T): LinkedList<T>;
begin
Result := new LinkedList<T>(a);
end;
function Lst(a: CharRange): List<char> := a.ToList;
function HSet<T>(params a: array of T): HashSet<T>;
begin
Result := new HashSet<T>(a);
end;
function LLst<T>(params a: array of T): LinkedList<T> := new LinkedList<T>(a);
function SSet<T>(params a: array of T): SortedSet<T>;
begin
Result := new SortedSet<T>(a);
end;
function LLst<T>(a: sequence of T): LinkedList<T> := new LinkedList<T>(a);
function HSet<T>(a: sequence of T): HashSet<T>;
begin
Result := new HashSet<T>(a);
end;
function LLst(a: IntRange): LinkedList<integer> := a.ToLinkedList;
function LLst(a: CharRange): LinkedList<char> := a.ToLinkedList;
function HSet<T>(params a: array of T): HashSet<T> := new HashSet<T>(a);
function SSet<T>(params a: array of T): SortedSet<T> := new SortedSet<T>(a);
function HSet<T>(a: sequence of T): HashSet<T> := new HashSet<T>(a);
function SSet<T>(a: sequence of T): SortedSet<T> := new SortedSet<T>(a);
function HSet(a: IntRange): HashSet<integer> := a.ToHashSet&<integer>;
function HSet(a: CharRange): HashSet<char> := a.ToHashSet&<char>;
function SSet(a: IntRange): SortedSet<integer> := a.ToSortedSet;
function SSet(a: CharRange): SortedSet<char> := a.ToSortedSet;
function SSet<T>(a: sequence of T): SortedSet<T>;
begin
Result := new SortedSet<T>(a);
end;
function Dict<TKey, TVal>(params pairs: array of KeyValuePair<TKey, TVal>): Dictionary<TKey, TVal>;
begin
@ -9065,84 +9185,98 @@ type
//------------------------------------------------------------------------------
//>> Метод расширения Print для элементарных типов # Print for elementary types
//------------------------------------------------------------------------------
/// Выводит значение на экран, после чего выводит пробел
function Print(Self: integer): integer; extensionmethod;
begin
PABCSystem.Print(Self);
Result := Self;
end;
/// Выводит значение на экран, после чего выводит пробел
function Print(Self: int64): int64; extensionmethod;
begin
PABCSystem.Print(Self);
Result := Self;
end;
/// Выводит значение на экран, после чего выводит пробел
function Print(Self: real): real; extensionmethod;
begin
PABCSystem.Print(Self);
Result := Self;
end;
/// Выводит значение на экран, после чего выводит пробел
function Print(Self: char): char; extensionmethod;
begin
PABCSystem.Print(Self);
Result := Self;
end;
/// Выводит значение на экран, после чего выводит пробел
function Print(Self: boolean): boolean; extensionmethod;
begin
PABCSystem.Print(Self);
Result := Self;
end;
/// Выводит значение на экран, после чего выводит пробел
function Print(Self: BigInteger): BigInteger; extensionmethod;
begin
PABCSystem.Print(Self);
Result := Self;
end;
/// Выводит значение на экран, после чего выводит пробел
function Print(Self: string): string; extensionmethod;
begin
PABCSystem.Print(Self);
Result := Self;
end;
/// Выводит значение на экран и переходит на новую строку
function Println(Self: integer): integer; extensionmethod;
begin
PABCSystem.Println(Self);
Result := Self;
end;
/// Выводит значение на экран и переходит на новую строку
function Println(Self: int64): int64; extensionmethod;
begin
PABCSystem.Println(Self);
Result := Self;
end;
/// Выводит значение на экран и переходит на новую строку
function Println(Self: real): real; extensionmethod;
begin
PABCSystem.Println(Self);
Result := Self;
end;
/// Выводит значение на экран и переходит на новую строку
function Println(Self: char): char; extensionmethod;
begin
PABCSystem.Println(Self);
Result := Self;
end;
/// Выводит значение на экран и переходит на новую строку
function Println(Self: boolean): boolean; extensionmethod;
begin
PABCSystem.Println(Self);
Result := Self;
end;
/// Выводит значение на экран и переходит на новую строку
function Println(Self: BigInteger): BigInteger; extensionmethod;
begin
PABCSystem.Println(Self);
Result := Self;
end;
/// Выводит значение на экран и переходит на новую строку
function Println(Self: string): string; extensionmethod;
begin
PABCSystem.Println(Self);

View file

@ -0,0 +1,25 @@
var global: integer;
type int = integer;
type Class1<T,T1> = class
classfield: integer;
const cc = 2;
function p<PPT>(pa,pb: real): integer;
type int1 = integer;
var
A: record
i: array of integer := nil{cc {classfield};
jlocal1: record
j: integer := cc;
mostinternal1: set of integer := [j];
end;
klocal1: int := global {* classfield};
end;
begin
end;
end;
begin
end.

View file

@ -0,0 +1,25 @@
var global: integer;
type int = integer;
type Class1<T,T1> = class
classfield: integer;
const cc = 2;
function p<PPT>(pa,pb: real): integer;
type int1 = integer;
var
A: record
i: array of integer := nil{cc {classfield};
jlocal1: record
j: integer := classfield;
mostinternal1: set of integer := [j];
end;
klocal1: int := global {* classfield};
end;
begin
end;
end;
begin
end.

View file

@ -0,0 +1,25 @@
var global: integer;
type int = integer;
type Class1<T,T1> = class
classfield: integer;
const cc = 2;
function p<PPT>(pa,pb: real): integer;
type int1 = integer;
var
A: record
i: array of integer := nil{cc {classfield};
jlocal1: record
j: T;
mostinternal1: set of integer := [j];
end;
klocal1: int := global {* classfield};
end;
begin
end;
end;
begin
end.

View file

@ -0,0 +1,25 @@
var global: integer;
type int = integer;
type Class1<T,T1> = class
classfield: integer;
const cc = 2;
function p<PPT>(pa,pb: real): integer;
type int1 = integer;
var
A: record
i: array of integer := nil{cc {classfield};
jlocal1: record
j: integer := pa;
mostinternal1: set of integer := [j];
end;
klocal1: int := global {* classfield};
end;
begin
end;
end;
begin
end.

View file

@ -0,0 +1,25 @@
var global: integer;
type int = integer;
type Class1<T,T1> = class
classfield: integer;
const cc = 2;
function p<PPT>(pa,pb: real): integer;
type int1 = integer;
var
A: record
i: array of integer := nil{cc {classfield};
jlocal1: record
j: integer := 1;
mostinternal1: set of integer := [j];
end;
klocal1: int1 := 1 {* classfield};
end;
begin
end;
end;
begin
end.

26
TestSuite/ur1.pas Normal file
View file

@ -0,0 +1,26 @@
var global: integer;
type int = integer;
type Class1<T,T1> = class
classfield: integer;
const cc = 2;
function p<PPT>(pa,pb: real): integer;
type int1 = integer;
var
A: record
i: array of integer := nil{cc {classfield};
jlocal1: record
j: integer;
mostinternal1: set of integer := [j];
end;
klocal1: int := global {* classfield};
end;
begin
end;
end;
begin
Assert(True);
end.

17
TestSuite/ur2.pas Normal file
View file

@ -0,0 +1,17 @@
type Class1<T,T1> = class
procedure p;
var
A: record
i: integer;
jlocal0: record
i: real;
end;
end;
begin
end;
end;
begin
Assert(True)
end.

View file

@ -3579,7 +3579,8 @@ namespace PascalABCCompiler.TreeConverter
{
if (_class_definition.keyword == class_keyword.Record && _class_definition.Parent is var_def_statement) // безымянная запись
{
if (_class_definition.class_parents != null && _class_definition.class_parents.Count>0)
// SSM 27.02.12 - всё это перенес в синтаксический визитор UnnamedRecordsCheckVisitor
/*if (_class_definition.class_parents != null && _class_definition.class_parents.Count>0)
AddError(new SimpleSemanticError(get_location(_class_definition), "UNNAMED_RECORD_CANNOT_IMPLEMENT_INTERFACE"));
var pds = _class_definition.DescendantNodes().OfType<procedure_definition>();
if (pds.Count() > 0)
@ -3589,9 +3590,9 @@ namespace PascalABCCompiler.TreeConverter
if (sps.Count() > 0)
AddError(new SimpleSemanticError(get_location(sps.First()), "UNNAMED_RECORD_CANNOT_CONTAIN_PROPERTIES"));
/*var cds = _class_definition.DescendantNodes().OfType<constructor>();
var cds = _class_definition.DescendantNodes().OfType<constructor>();
if (cds.Count() > 0)
AddError(new SimpleSemanticError(get_location(cds.First()), "UNNAMED_RECORD_CANNOT_CONTAIN_CONSTRUCTORS"));*/
AddError(new SimpleSemanticError(get_location(cds.First()), "UNNAMED_RECORD_CANNOT_CONTAIN_CONSTRUCTORS"));
if (_class_definition.body.class_def_blocks.First().access_mod.access_level != access_modifer.public_modifer)
{
var f = _class_definition.body.class_def_blocks.First();
@ -3608,9 +3609,9 @@ namespace PascalABCCompiler.TreeConverter
if (loc == null)
loc = get_location(_class_definition);
AddError(new SimpleSemanticError(loc, "UNNAMED_RECORD_CANNOT_CONTAIN_SEVERAL_VISIBILITY_SECTIONS"));
}
}
}*/
}
if (_class_definition.attribute != class_attribute.None && _class_definition.body == null)
AddError(new SimpleSemanticError(get_location(_class_definition), "CLASS_ATTRIBUTE_NOT_ALLOWED_IN_CLASS_PREDEFINTIONS"));
@ -12704,7 +12705,7 @@ namespace PascalABCCompiler.TreeConverter
: null;
if (_procedure_definition.proc_header.attributes != null && context.converted_func_stack.size >= 1)
AddError(get_location(_procedure_definition.proc_header), "ATTRIBUTES_FOR_NESTED_FUNCTIONS_NOT_ALLOWED");
if (context.top_function != null && context.top_function.generic_params != null && !LambdaHelper.IsLambdaName(proc_name))
if (context.top_function != null && context.top_function.generic_params != null && !LambdaHelper.IsLambdaName(proc_name) && !(_procedure_definition.proc_header is SyntaxTree.constructor))
AddError(get_location(_procedure_definition.proc_header), "NESTED_FUNCTIONS_IN_GENERIC_FUNCTIONS_NOT_ALLOWED");
if (context.top_function != null && _procedure_definition.proc_header.template_args != null && !LambdaHelper.IsLambdaName(proc_name))
AddError(get_location(_procedure_definition.proc_header), "GENERIC_NESTED_FUNCTIONS_NOT_ALLOWED");

View file

@ -252,6 +252,9 @@ type
/// Представляет результаты из набора групп при выполнении Regex.Match
RegexGroupCollection = System.Text.RegularExpressions.GroupCollection;
/// Предоставляет методы для точного измерения затраченного времени
Stopwatch = System.Diagnostics.Stopwatch;
/// Представляет тип короткой строки фиксированной длины 255 символов
ShortString = string[255];
@ -585,6 +588,146 @@ type
/// Считывает строку из бестипового файла
function ReadString: string;
end;
type
/// Тип диапазона целых
IntRange = class(IEnumerable<integer>)
private
l,h: integer;
function GetCount: integer;
begin
Result := h-l+1;
if Result<0 then
Result := 0;
end;
public
constructor(l,h: integer);
begin
Self.l := l;
Self.h := h;
end;
property Low: integer read l;
property High: integer read h;
property Count: integer read GetCount;
static function operator in(x: integer; r: IntRange): boolean := (x >= r.l) and (x <= r.h);
static function operator=(r1,r2: IntRange): boolean := (r1.l = r2.l) and (r1.h = r2.h);
function IsEmpty: boolean := l<=h;
function GetEnumerator(): IEnumerator<integer>;
function System.Collections.IEnumerable.GetEnumerator: System.Collections.IEnumerator := Self.GetEnumerator;
function ToString: string; override := $'({l},{h})';
function Equals(o: Object): boolean; override;
begin
var r2 := IntRange(o);
Result := (l = r2.l) and (h = r2.h);
end;
function GetHashCode: integer; override := l.GetHashCode xor h.GetHashCode;
function ToArray: array of integer;
begin
Result := new integer[Count];
var x := l;
for var i := 0 to Result.Length - 1 do
begin
Result[i] := x;
x += 1;
end;
end;
function ToList: List<integer>;
begin
Result := new List<integer>;
var x := l;
loop Count do
begin
Result.Add(x);
x += 1;
end;
end;
function ToLinkedList: LinkedList<integer>;
begin
Result := new LinkedList<integer>(System.Linq.Enumerable.Range(l,Count));
end;
function ToHashSet: HashSet<integer>;
begin
Result := new HashSet<integer>(System.Linq.Enumerable.Range(l,Count));
end;
function ToSortedSet: SortedSet<integer>;
begin
Result := new SortedSet<integer>(System.Linq.Enumerable.Range(l,Count));
end;
end;
/// Тип диапазона символов
CharRange = class(IEnumerable<char>)
private
l,h: char;
function GetCount: integer;
begin
Result := integer(h) - integer(l)+1;
if Result<0 then
Result := 0;
end;
public
constructor(l,h: char);
begin
Self.l := l;
Self.h := h;
end;
property Low: char read l;
property High: char read h;
property Count: integer read GetCount;
static function operator in(x: char; r: CharRange): boolean := (x >= r.l) and (x <= r.h);
static function operator=(r1,r2: CharRange): boolean := (r1.l = r2.l) and (r1.h = r2.h);
function IsEmpty: boolean := l<=h;
function GetEnumerator(): IEnumerator<char>;
function System.Collections.IEnumerable.GetEnumerator: System.Collections.IEnumerator := GetEnumerator;
function ToString: string; override := $'({l},{h})';
function Equals(o: Object): boolean; override;
begin
var r2 := CharRange(o);
Result := (l = r2.l) and (h = r2.h);
end;
function GetHashCode: integer; override := l.GetHashCode xor h.GetHashCode;
function ToArray: array of char;
begin
Result := new char[Count];
var x := l;
for var i := 0 to Result.Length - 1 do
begin
Result[i] := x;
x := char(integer(x) + 1);
end;
end;
function ToList: List<char>;
begin
Result := new List<char>;
var x := l;
loop Count do
begin
Result.Add(x);
x := char(integer(x) + 1);
end;
end;
function ToLinkedList: LinkedList<char>;
begin
Result := new LinkedList<char>(System.Linq.Enumerable.Range(integer(l),Count).Select(i -> char(i)));
end;
function ToHashSet: HashSet<char>;
begin
Result := new HashSet<char>(System.Linq.Enumerable.Range(integer(l),Count).Select(i -> char(i)));
end;
function ToSortedSet: SortedSet<char>;
begin
Result := new SortedSet<char>(System.Linq.Enumerable.Range(integer(l),Count).Select(i -> char(i)));
end;
end;
//{{{doc: Начало секции интерфейса для документации }}}
@ -1965,6 +2108,11 @@ function ReadSeqStringWhile(prompt: string; cond: string->boolean): sequence of
function Arr<T>(params a: array of T): array of T;
/// Возвращает массив, заполненный значениями из последовательнсти
function Arr<T>(a: sequence of T): array of T;
/// Возвращает массив, заполненный диапазоном значений
function Arr(a: IntRange): array of integer;
/// Возвращает массив, заполненный диапазоном значений
function Arr(a: CharRange): array of char;
/// Возвращает массив размера n, заполненный случайными целыми значениями
function ArrRandom(n: integer := 10; a: integer := 0; b: integer := 100): array of integer;
/// Возвращает массив размера n, заполненный случайными целыми значениями
@ -2054,18 +2202,39 @@ function Rec<T1, T2, T3, T4, T5, T6, T7>(x1: T1; x2: T2; x3: T3; x4: T4; x5: T5;
function Lst<T>(params a: array of T): List<T>;
/// Возвращает список, заполненный значениями из последовательности
function Lst<T>(a: sequence of T): List<T>;
/// Возвращает список, заполненный диапазоном значений
function Lst(a: IntRange): List<integer>;
/// Возвращает список, заполненный диапазоном значений
function Lst(a: CharRange): List<char>;
/// Возвращает двусвязный список, заполненный указанными значениями
function LLst<T>(params a: array of T): LinkedList<T>;
/// Возвращает двусвязный список, заполненный значениями из последовательности
function LLst<T>(a: sequence of T): LinkedList<T>;
/// Возвращает двусвязный список, заполненный диапазоном значений
function LLst(a: IntRange): LinkedList<integer>;
/// Возвращает двусвязный список, заполненный диапазоном значений
function LLst(a: CharRange): LinkedList<char>;
/// Возвращает множество на базе хеш таблицы, заполненное указанными значениями
function HSet<T>(params a: array of T): HashSet<T>;
/// Возвращает множество на базе хеш таблицы, заполненное значениями из последовательности
function HSet<T>(a: sequence of T): HashSet<T>;
/// Возвращает множество на базе хеш таблицы, заполненное диапазоном значений
function HSet(a: IntRange): HashSet<integer>;
/// Возвращает множество на базе хеш таблицы, заполненное заполненный диапазоном значений
function HSet(a: CharRange): HashSet<char>;
/// Возвращает множество на базе бинарного дерева поиска, заполненное значениями из последовательности
function SSet<T>(params a: array of T): SortedSet<T>;
/// Возвращает множество на базе бинарного дерева поиска, заполненное значениями из последовательности
function SSet<T>(a: sequence of T): SortedSet<T>;
/// Возвращает множество на базе на базе бинарного дерева поиска, заполненное диапазоном значений
function SSet(a: IntRange): SortedSet<integer>;
/// Возвращает множество на базе на базе бинарного дерева поиска, заполненное заполненный диапазоном значений
function SSet(a: CharRange): SortedSet<char>;
/// Возвращает словарь пар элементов (ключ, значение)
function Dict<TKey, TVal>(params pairs: array of KeyValuePair<TKey, TVal>): Dictionary<TKey, TVal>;
/// Возвращает словарь пар элементов (ключ, значение)
@ -2427,67 +2596,6 @@ type
end;
type
/// Тип диапазона целых
IntRange = class(IEnumerable<integer>)
private
l,h: integer;
public
constructor(l,h: integer);
begin
Self.l := l;
Self.h := h;
end;
property Low: integer read l;
property High: integer read h;
static function operator in(x: integer; r: IntRange): boolean := (x >= r.l) and (x <= r.h);
static function operator=(r1,r2: IntRange): boolean := (r1.l = r2.l) and (r1.h = r2.h);
function IsEmpty: boolean := l<=h;
function GetEnumerator(): IEnumerator<integer> := Range(l,h).GetEnumerator;
function System.Collections.IEnumerable.GetEnumerator: System.Collections.IEnumerator := Range(l,h).GetEnumerator;
function ToString: string; override := $'({l},{h})';
function Equals(o: Object): boolean; override;
begin
var r2 := IntRange(o);
Result := (l = r2.l) and (h = r2.h);
end;
function GetHashCode: integer; override := l.GetHashCode xor h.GetHashCode;
end;
/// Тип диапазона символов
CharRange = class(IEnumerable<char>)
private
l,h: char;
public
constructor(l,h: char);
begin
Self.l := l;
Self.h := h;
end;
property Low: char read l;
property High: char read h;
static function operator in(x: char; r: CharRange): boolean := (x >= r.l) and (x <= r.h);
static function operator=(r1,r2: CharRange): boolean := (r1.l = r2.l) and (r1.h = r2.h);
function IsEmpty: boolean := l<=h;
function GetEnumerator(): IEnumerator<char> := Range(l,h).GetEnumerator;
function System.Collections.IEnumerable.GetEnumerator: System.Collections.IEnumerator := Range(l,h).GetEnumerator;
function ToString: string; override := $'({l},{h})';
function Equals(o: Object): boolean; override;
begin
var r2 := CharRange(o);
Result := (l = r2.l) and (h = r2.h);
end;
function GetHashCode: integer; override := l.GetHashCode xor h.GetHashCode;
end;
///--
function InternalRange(l,r: integer): IntRange;
///--
@ -3761,6 +3869,10 @@ begin
Result := sb.ToString;
end;
function IntRange.GetEnumerator(): IEnumerator<integer> := Range(l,h).GetEnumerator;
function CharRange.GetEnumerator(): IEnumerator<char> := Range(l,h).GetEnumerator;
//------------------------------------------------------------------------------
// Операции для string и char
//------------------------------------------------------------------------------
@ -4371,6 +4483,20 @@ begin
Result := a.ToArray;
end;
function Arr(a: IntRange): array of integer := a.ToArray;
function Arr(a: CharRange): array of char;
begin
var n := integer(a.High) - integer(a.Low) + 1;
Result := new char[n];
var x := a.Low;
for var i := 0 to n-1 do
begin
Result[i] := x;
Inc(x)
end;
end;
function Seq<T>(params a: array of T): sequence of T;
begin
var res := new T[a.Length];
@ -4681,45 +4807,39 @@ function Rec<T1, T2, T3, T4, T5, T6, T7>(x1: T1; x2: T2; x3: T3; x4: T4; x5: T5;
// -----------------------------------------------------------------------------
// Функции Lst, LLst, Dict, KV, HSet, SSet
// -----------------------------------------------------------------------------
function Lst<T>(params a: array of T): List<T>;
begin
Result := new List<T>(a);
end;
function Lst<T>(params a: array of T): List<T> := new List<T>(a);
function Lst<T>(a: sequence of T): List<T>;
begin
Result := new List<T>(a);
end;
function Lst<T>(a: sequence of T): List<T> := new List<T>(a);
function LLst<T>(params a: array of T): LinkedList<T>;
begin
Result := new LinkedList<T>(a);
end;
function Lst(a: IntRange): List<integer> := a.ToList;
function LLst<T>(a: sequence of T): LinkedList<T>;
begin
Result := new LinkedList<T>(a);
end;
function Lst(a: CharRange): List<char> := a.ToList;
function HSet<T>(params a: array of T): HashSet<T>;
begin
Result := new HashSet<T>(a);
end;
function LLst<T>(params a: array of T): LinkedList<T> := new LinkedList<T>(a);
function SSet<T>(params a: array of T): SortedSet<T>;
begin
Result := new SortedSet<T>(a);
end;
function LLst<T>(a: sequence of T): LinkedList<T> := new LinkedList<T>(a);
function HSet<T>(a: sequence of T): HashSet<T>;
begin
Result := new HashSet<T>(a);
end;
function LLst(a: IntRange): LinkedList<integer> := a.ToLinkedList;
function LLst(a: CharRange): LinkedList<char> := a.ToLinkedList;
function HSet<T>(params a: array of T): HashSet<T> := new HashSet<T>(a);
function SSet<T>(params a: array of T): SortedSet<T> := new SortedSet<T>(a);
function HSet<T>(a: sequence of T): HashSet<T> := new HashSet<T>(a);
function SSet<T>(a: sequence of T): SortedSet<T> := new SortedSet<T>(a);
function HSet(a: IntRange): HashSet<integer> := a.ToHashSet&<integer>;
function HSet(a: CharRange): HashSet<char> := a.ToHashSet&<char>;
function SSet(a: IntRange): SortedSet<integer> := a.ToSortedSet;
function SSet(a: CharRange): SortedSet<char> := a.ToSortedSet;
function SSet<T>(a: sequence of T): SortedSet<T>;
begin
Result := new SortedSet<T>(a);
end;
function Dict<TKey, TVal>(params pairs: array of KeyValuePair<TKey, TVal>): Dictionary<TKey, TVal>;
begin
@ -9065,84 +9185,98 @@ type
//------------------------------------------------------------------------------
//>> Метод расширения Print для элементарных типов # Print for elementary types
//------------------------------------------------------------------------------
/// Выводит значение на экран, после чего выводит пробел
function Print(Self: integer): integer; extensionmethod;
begin
PABCSystem.Print(Self);
Result := Self;
end;
/// Выводит значение на экран, после чего выводит пробел
function Print(Self: int64): int64; extensionmethod;
begin
PABCSystem.Print(Self);
Result := Self;
end;
/// Выводит значение на экран, после чего выводит пробел
function Print(Self: real): real; extensionmethod;
begin
PABCSystem.Print(Self);
Result := Self;
end;
/// Выводит значение на экран, после чего выводит пробел
function Print(Self: char): char; extensionmethod;
begin
PABCSystem.Print(Self);
Result := Self;
end;
/// Выводит значение на экран, после чего выводит пробел
function Print(Self: boolean): boolean; extensionmethod;
begin
PABCSystem.Print(Self);
Result := Self;
end;
/// Выводит значение на экран, после чего выводит пробел
function Print(Self: BigInteger): BigInteger; extensionmethod;
begin
PABCSystem.Print(Self);
Result := Self;
end;
/// Выводит значение на экран, после чего выводит пробел
function Print(Self: string): string; extensionmethod;
begin
PABCSystem.Print(Self);
Result := Self;
end;
/// Выводит значение на экран и переходит на новую строку
function Println(Self: integer): integer; extensionmethod;
begin
PABCSystem.Println(Self);
Result := Self;
end;
/// Выводит значение на экран и переходит на новую строку
function Println(Self: int64): int64; extensionmethod;
begin
PABCSystem.Println(Self);
Result := Self;
end;
/// Выводит значение на экран и переходит на новую строку
function Println(Self: real): real; extensionmethod;
begin
PABCSystem.Println(Self);
Result := Self;
end;
/// Выводит значение на экран и переходит на новую строку
function Println(Self: char): char; extensionmethod;
begin
PABCSystem.Println(Self);
Result := Self;
end;
/// Выводит значение на экран и переходит на новую строку
function Println(Self: boolean): boolean; extensionmethod;
begin
PABCSystem.Println(Self);
Result := Self;
end;
/// Выводит значение на экран и переходит на новую строку
function Println(Self: BigInteger): BigInteger; extensionmethod;
begin
PABCSystem.Println(Self);
Result := Self;
end;
/// Выводит значение на экран и переходит на новую строку
function Println(Self: string): string; extensionmethod;
begin
PABCSystem.Println(Self);

View file

@ -21,4 +21,15 @@ ONLY_ONE_DECONSTRUCT_ALLOWED=Only one user deconstructor is allowed
Var_{0}_is_already_defined=Variable {0} is already defined
?._CANNOT_BE_IN_THIS_CONTEXT=Operator ?. cannot be in this context
?._CANNOT_BE_IN_THIS_CONTEXT=Operator ?. cannot be in this context
INVALID_INTERFACE_MEMBER=Interfaces cannot contain fields and method implementation
INDEXED_AUTO_PROPERTY=Autoproperties cannot be indexed properties
UNNAMED_RECORD_CANNOT_IMPLEMENT_INTERFACE=Unnamed records can not implement interfaces
UNNAMED_RECORD_CANNOT_CONTAIN_METHODS=Unnamed records can not contain methods
UNNAMED_RECORD_CANNOT_CONTAIN_PROPERTIES=Unnamed records can not contain properties
UNNAMED_RECORD_CANNOT_CONTAIN_CONSTRUCTORS=Unnamed records can not contain constructors
UNNAMED_RECORD_CAN_CONTAIN_ONLY_ONE_PUBLIC_VISIBILITY_SECTION=Unnamed records can contain only one section with public visibility
UNNAMED_RECORD_CANNOT_CONTAIN_SEVERAL_VISIBILITY_SECTIONS=Unnamed records can not contain several visibility section
UNNAMED_RECORD_CANNOT_CATCH_NAMES_FROM_NONGLOBAL_CONTEXT=Unnamed records cannot catch names from nonglobal context

View file

@ -27,7 +27,7 @@ IMPOSSIBLE_TO_INFER_SET_TYPE=Нельзя вычислить тип множес
BAD_DIAPASON_IN_SET_TYPE=Границы диапазона в константе-множестве должны иметь один тип
UNNAMED_RECORD_CANNOT_IMPLEMENT_INTERFACE=Безымянные записи не могут реализовывать интерфейсы
UNNAMED_RECORD_CANNOT_CONTAIN_METHODS=Безымянные записи не могут содержать методы
UNNAMED_RECORD_CANNOT_CONTAIN_PROPERTIES=Безымянные записи не могут содержать методы
UNNAMED_RECORD_CANNOT_CONTAIN_PROPERTIES=Безымянные записи не могут содержать свойства
UNNAMED_RECORD_CANNOT_CONTAIN_CONSTRUCTORS=Безымянные записи не могут содержать конструкторы
UNNAMED_RECORD_CAN_CONTAIN_ONLY_ONE_PUBLIC_VISIBILITY_SECTION=Безымянные записи могут содержать лишь одну секцию с public-видимостью
UNNAMED_RECORD_CANNOT_CONTAIN_SEVERAL_VISIBILITY_SECTIONS=Безымянные записи не могут содержать несколько секций видимости

View file

@ -27,4 +27,12 @@ Var_{0}_is_already_defined=Переменная {0} уже определена
?._CANNOT_BE_IN_THIS_CONTEXT=Операция ?. не может располагаться в этом контексте
INVALID_INTERFACE_MEMBER=Интерфейсы не могут содержать поля и реализацию методов
INDEXED_AUTO_PROPERTY=Автосвойства не могут быть индексными
INDEXED_AUTO_PROPERTY=Автосвойства не могут быть индексными
UNNAMED_RECORD_CANNOT_IMPLEMENT_INTERFACE=Безымянные записи не могут реализовывать интерфейсы
UNNAMED_RECORD_CANNOT_CONTAIN_METHODS=Безымянные записи не могут содержать методы
UNNAMED_RECORD_CANNOT_CONTAIN_PROPERTIES=Безымянные записи не могут содержать свойства
UNNAMED_RECORD_CANNOT_CONTAIN_CONSTRUCTORS=Безымянные записи не могут содержать конструкторы
UNNAMED_RECORD_CAN_CONTAIN_ONLY_ONE_PUBLIC_VISIBILITY_SECTION=Безымянные записи могут содержать лишь одну секцию с public-видимостью
UNNAMED_RECORD_CANNOT_CONTAIN_SEVERAL_VISIBILITY_SECTIONS=Безымянные записи не могут содержать несколько секций видимости
UNNAMED_RECORD_CANNOT_CATCH_NAMES_FROM_NONGLOBAL_CONTEXT=Безымянные записи не могут захватывать имена из неглобального контекста