Распаковка KeyValuePair| И в foreach

This commit is contained in:
Mikhalkovich Stanislav 2025-05-24 21:36:36 +03:00
parent fbb5dec9a9
commit 5fec52615a
15 changed files with 186 additions and 192 deletions

View file

@ -15,7 +15,7 @@ internal static class RevisionClass
public const string Major = "3";
public const string Minor = "10";
public const string Build = "3";
public const string Revision = "3627";
public const string Revision = "3632";
public const string MainVersion = Major + "." + Minor;
public const string FullVersion = Major + "." + Minor + "." + Build + "." + Revision;

View file

@ -1,4 +1,4 @@
%MINOR%=10
%REVISION%=3627
%COREVERSION%=3
%REVISION%=3632
%MINOR%=10
%MAJOR%=3

View file

@ -1 +1 @@
3.10.3.3627
3.10.3.3632

View file

@ -1 +1 @@
!define VERSION '3.10.3.3627'
!define VERSION '3.10.3.3632'

View file

@ -2334,8 +2334,10 @@ function Pred(x: uint64): uint64;
///--
function Pred(x: boolean): boolean;
/// Возвращает True, если значение val находится между a и b включительно (a ≤ val ≤ b)
/// Возвращает True, если значение val находится между a и b включительно
function InRange<T>(val, a, b: T): boolean; where T: IComparable<T>;
/// Возвращает True, если значение val находится между a и b (включительно) независимо от порядка a и b
function Between<T>(val, a, b: T): boolean; where T: IComparable<T>;
/// Меняет местами значения двух переменных
procedure Swap<T>(var a, b: T);
/// Возвращает True, если достигнут конец строки
@ -3166,43 +3168,44 @@ var
const
WRITELN_IN_BINARYFILE_ERROR_MESSAGE = 'Операция Writeln не применима к бинарным файлам!!Writeln is not applicable to binary files';
InternalNullBasedArrayName = 'NullBasedArray';
FILE_NOT_ASSIGNED = 'Для файловой переменной не вызвана процедура Assign!!File is not assigned';
FILE_NOT_OPENED = 'Файл не открыт!!File is not opened';
FILE_NOT_OPENED_FOR_READING = 'Файл не открыт на чтение!!File is not opened for reading';
FILE_NOT_OPENED_FOR_WRITING = 'Файл не открыт на запись!!File is not opened for writing';
READ_LEXEM_AFTER_END_OF_TEXT_FILE = 'Попытка считывания за концом текстового файла!!Read after end of text file';
READ_LEXEM_AFTER_END_OF_INPUT_STREAM = 'Попытка считывания за концом потока ввода!!Read after end of input stream';
RANGE_ERROR_MESSAGE = 'Выход за границы диапазона!!Out of range';
EOF_FOR_TEXT_WRITEOPENED = 'Функция Eof не может быть вызвана для текстового файла, открытого на запись!!Eof function can''t be called for file, opened on writing';
EOLN_FOR_TEXT_WRITEOPENED = 'Функция Eoln не может быть вызвана для текстового файла, открытого на запись!!Eoln function can''t be called for file, opened on writing';
SEEKEOF_FOR_TEXT_WRITEOPENED = 'Функция SeekEof не может быть вызвана для текстового файла, открытого на запись!!SeekEof function can''t be called for file, opened on writing';
SEEKEOLN_FOR_TEXT_WRITEOPENED = 'Функция SeekEoln не может быть вызвана для текстового файла, открытого на запись!!SeekEoln function can''t be called for file, opened on writing';
BAD_TYPE_IN_RUNTIMESIZEOF = 'Для типизированных файлов нельзя указывать тип элементов, являющийся ссылочным или содержащий ссылочные поля!!Bad Type in RunTimeSizeOf';
FILE_NOT_ASSIGNED = 'Для файловой переменной не вызвана процедура Assign!!File variable was not assigned using Assign';
FILE_NOT_OPENED = 'Файл не открыт!!File is not open';
FILE_NOT_OPENED_FOR_READING = 'Файл не открыт на чтение!!File is not open for reading';
FILE_NOT_OPENED_FOR_WRITING = 'Файл не открыт на запись!!File is not open for writing';
READ_LEXEM_AFTER_END_OF_TEXT_FILE = 'Попытка считывания за концом текстового файла!!Attempt to read beyond end of text file';
READ_LEXEM_AFTER_END_OF_INPUT_STREAM = 'Попытка считывания за концом потока ввода!!Attempt to read beyond end of input stream';
RANGE_ERROR_MESSAGE = 'Выход за пределы допустимого диапазона!!Out of range';
EOF_FOR_TEXT_WRITEOPENED = 'Функция Eof не может быть вызвана для текстового файла, открытого на запись!!Eof function cannot be called on a text file opened for writing';
EOLN_FOR_TEXT_WRITEOPENED = 'Функция Eoln не может быть вызвана для текстового файла, открытого на запись!!Eoln function cannot be called on a text file opened for writing';
SEEKEOF_FOR_TEXT_WRITEOPENED = 'Функция SeekEof не может быть вызвана для текстового файла, открытого на запись!!SeekEof function cannot be called on a text file opened for writing';
SEEKEOLN_FOR_TEXT_WRITEOPENED = 'Функция SeekEoln не может быть вызвана для текстового файла, открытого на запись!!SeekEoln function cannot be called on a text file opened for writing';
BAD_TYPE_IN_RUNTIMESIZEOF = 'Типизированный файл не может содержать ссылочный тип или тип со ссылочными полями!!Typed file cannot contain a reference type or a type with reference fields';
PARAMETER_MUST_BE_GREATER_EQUAL_0 = 'Параметр должен быть >= 0!!Parameter must be >= 0';
PARAMETER_MUST_BE_GREATER_0 = 'Параметр должен быть > 0!!Parameter must be > 0';
PARAMETER_MUST_BE_GREATER_1 = 'Параметр должен быть > 1!!Parameter must be > 1';
PARAMETER_STEP_MUST_BE_NOT_EQUAL_0 = 'Параметр step не может быть равен 0!!The step parameter must be not equal to 0';
PARAMETER_STEP_MUST_BE_GREATER_0 = 'Параметр step должен быть > 0!!The step parameter must be not greater than 0';
PARAMETER_FROM_OUT_OF_RANGE = 'Параметр from за пределами диапазона!!The from parameter out of bounds';
PARAMETER_TO_OUT_OF_RANGE = 'Параметр to за пределами диапазона!!The to parameter out of bounds';
ARR_LENGTH_MUST_BE_MATCH_TO_MATR_SIZE = 'Размер одномерного массива не согласован с размером двумерного массива!!The 1-dim array length does not match 2-dim array size';
INITELEM_COUNT_MUST_BE_EQUAL_TO_MATRIX_ELEMS_COUNT = 'Количество инициализирующих элементов не совпадает с количеством элементов матрицы!!The number of elements in init list must be equal to the number of elements in matrix';
TYPED_FILE_CANBE_OPENED_IN_SINGLEBYTE_ENCODING_ONLY = 'При открытии типизированного файла можно указывать только однобайтную кодировку!!Typed file can be opened in single byte encoding only';
BAD_ROW_INDEX = 'Один из элементов массива RowIndex выходит за пределы индексов строк двумерного массива!!One of the elements of RowIndex array is out of range of 2-dim array row indexes';
BAD_COL_INDEX = 'Один из элементов массива ColIndex выходит за пределы индексов столбцов двумерного массива!!One of the elements of ColIndex array is out of range of 2-dim array column indexes';
BAD_ROW_INDEX_FROM = 'FromRow выходит за пределы индексов строк двумерного массива!!FromRow is out of range of 2-dim array row indexes';
BAD_ROW_INDEX_TO = 'ToRow выходит за пределы индексов строк двумерного массива!!ToRow is out of range of 2-dim array row indexes';
BAD_COL_INDEX_FROM = 'FromCol выходит за пределы индексов строк двумерного массива!!FromCol is out of range of 2-dim array column indexes';
BAD_COL_INDEX_TO = 'ToCol выходит за пределы индексов строк двумерного массива!!ToCol is out of range of 2-dim array column indexes';
SLICE_SIZE_AND_RIGHT_VALUE_SIZE_MUST_BE_EQUAL = 'Размеры среза и присваиваемого выражения должны быть равны!!Slice size and assigned expression size must be equal';
PARAMETER_MUST_BE_GREATER_0 = 'Параметр должен быть больше 0!!Parameter must be > 0';
PARAMETER_MUST_BE_GREATER_1 = 'Параметр должен быть больше 1!!Parameter must be > 1';
PARAMETER_STEP_MUST_BE_NOT_EQUAL_0 = 'Параметр step не может быть равен 0!!Step parameter must not be equal to 0';
PARAMETER_STEP_MUST_BE_GREATER_0 = 'Параметр step должен быть > 0!!Step parameter must be greater than 0';
PARAMETER_FROM_OUT_OF_RANGE = 'Параметр from за пределами диапазона!!From parameter is out of range';
PARAMETER_TO_OUT_OF_RANGE = 'Параметр to за пределами диапазона!!To parameter is out of range';
ARR_LENGTH_MUST_BE_MATCH_TO_MATR_SIZE = 'Размер одномерного массива не согласован с размером двумерного массива!!The length of the 1D array must match the size of the 2D array';
INITELEM_COUNT_MUST_BE_EQUAL_TO_MATRIX_ELEMS_COUNT = 'Количество инициализирующих элементов не совпадает с количеством элементов матрицы!!The number of initializer elements must equal the number of elements in the matrix';
TYPED_FILE_CANBE_OPENED_IN_SINGLEBYTE_ENCODING_ONLY = 'При открытии типизированного файла можно указывать только однобайтную кодировку!!Typed files can only be opened with single-byte encodings';
BAD_ROW_INDEX = 'Один из элементов массива RowIndex выходит за пределы индексов строк двумерного массива!!An element in the RowIndex array is out of range for the matrix row indices';
BAD_COL_INDEX = 'Один из элементов массива ColIndex выходит за пределы индексов столбцов двумерного массива!!An element in the ColIndex array is out of range for the matrix column indices';
BAD_ROW_INDEX_FROM = 'FromRow выходит за пределы индексов строк двумерного массива!!FromRow is out of range for the matrix row indices';
BAD_ROW_INDEX_TO = 'ToRow выходит за пределы индексов строк двумерного массива!!ToRow is out of range for the matrix row indices';
BAD_COL_INDEX_FROM = 'FromCol выходит за пределы индексов строк двумерного массива!!FromCol is out of range for the matrix column indices';
BAD_COL_INDEX_TO = 'ToCol выходит за пределы индексов строк двумерного массива!!ToCol is out of range for the matrix column indices';
SLICE_SIZE_AND_RIGHT_VALUE_SIZE_MUST_BE_EQUAL = 'Размеры среза и присваиваемого выражения должны быть равны!!Slice size must match the size of the assigned expression';
MATR_DIMENSIONS_MUST_BE_EQUAL = 'Размеры матриц должны совпадать!!Matrix dimensions must be equal';
COUNT_PARAMS_MAXFUN_MUSTBE_GREATER1 = 'Количество параметров функции Max должно быть > 1!!The number of parameters of the Max function must be > 1';
COUNT_PARAMS_MINFUN_MUSTBE_GREATER1 = 'Количество параметров функции Min должно быть > 1!!The number of parameters of the Min function must be > 1';
Format_InvalidString = 'Входная строка имела неверный формат!!Input string was not in a correct format';
COUNT_PARAMS_MAXFUN_MUSTBE_GREATER1 = 'Количество параметров функции Max должно быть > 1!!Max function must have more than one parameter';
COUNT_PARAMS_MINFUN_MUSTBE_GREATER1 = 'Количество параметров функции Min должно быть > 1!!Min function must have more than one parameter';
Format_InvalidString = 'Входная строка имела неверный формат!!Input string was not in a valid format';
Overflow_Int32 = 'Целочисленное переполнение!!Integer overflow';
FOR_STEP_CANNOT_BE_EQUAL0 = 'Шаг цикла for не может быт равен 0!!Step of the for loop cannot be equal to 0';
FOR_STEP_CANNOT_BE_EQUAL0 = 'Шаг цикла for не может быт равен 0!!The step of a for loop cannot be 0';
SEQUENCE_CANNOT_BE_EMPTY = 'Последовательность не может быть пустой!!Sequence cannot be empty';
ARRAY_CANNOT_BE_EMPTY = 'Массив не может быть пустым!!Array cannot be empty';
MIN_CANNOT_BE_GREATER_THAN_MAX = 'CLamp: min не может быть больше чем max!!CLamp: min cannot be greater than max';
// -----------------------------------------------------
// WINAPI
// -----------------------------------------------------
@ -10684,12 +10687,21 @@ begin
Result := char(integer(x)-n);
end;
/// Возвращает True, если значение val находится между a и b включительно (a ≤ val ≤ b)
/// Возвращает True, если значение val находится между a и b включительно
function InRange<T>(val, a, b: T): boolean; where T: IComparable<T>;
begin
Result := (val.CompareTo(a) >= 0) and (val.CompareTo(b) <= 0);
end;
/// Возвращает True, если значение val находится между a и b (включительно) независимо от порядка a и b
function Between<T>(val, a, b: T): boolean; where T: IComparable<T>;
begin
if a.CompareTo(b) > 0 then
Result := (val.CompareTo(b) >= 0) and (val.CompareTo(a) <= 0)
else
Result := (val.CompareTo(a) >= 0) and (val.CompareTo(b) <= 0);
end;
procedure Swap<T>(var a, b: T);
begin
var v := a;
@ -14267,29 +14279,15 @@ begin
Result := Range(0, Self - 1);
end;
/// Возвращает число, ограниченное диапазоном от bottom до top включительно
function Clamp(Self: integer; bottom,top: integer): integer; extensionmethod;
/// Возвращает число, ограниченное диапазоном от min до max включительно
function Clamp(Self: integer; min,max: integer): integer; extensionmethod;
begin
if Self < bottom then
Result := bottom
else if Self > top then
Result := top
else Result := Self;
end;
/// Возвращает число, ограниченное величиной top сверху
function ClampTop(Self: integer; top: integer): integer; extensionmethod;
begin
if Self > top then
Result := top
else Result := Self;
end;
/// Возвращает число, ограниченное величиной bottom снизу
function ClampBottom(Self: integer; bottom: integer): integer; extensionmethod;
begin
if Self < bottom then
Result := bottom
if min > max then
raise new System.ArgumentException(GetTranslation(MIN_CANNOT_BE_GREATER_THAN_MAX));
if Self < min then
Result := min
else if Self > max then
Result := max
else Result := Self;
end;
@ -14384,33 +14382,18 @@ begin
Result := Format('{0:f' + frac + '}', Self)
end;
/// Возвращает число, ограниченное диапазоном от bottom до top включительно
function Clamp(Self: real; bottom,top: real): real; extensionmethod;
/// Возвращает число, ограниченное диапазоном от min до max включительно
function Clamp(Self: real; min,max: real): real; extensionmethod;
begin
if Self < bottom then
Result := bottom
else if Self > top then
Result := top
if min > max then
raise new System.ArgumentException(GetTranslation(MIN_CANNOT_BE_GREATER_THAN_MAX));
if Self < min then
Result := min
else if Self > max then
Result := max
else Result := Self;
end;
/// Возвращает число, ограниченное величиной top сверху
function ClampTop(Self: real; top: real): real; extensionmethod;
begin
if Self > top then
Result := top
else Result := Self;
end;
/// Возвращает число, ограниченное величиной bottom снизу
function ClampBottom(Self: real; bottom: real): real; extensionmethod;
begin
if Self < bottom then
Result := bottom
else Result := Self;
end;
//------------------------------------------------------------------------------
//>> Методы расширения типа char # Extension methods for char
//------------------------------------------------------------------------------
@ -14487,7 +14470,7 @@ begin
Result := Self.Split(|oldStr|, count+1, System.StringSplitOptions.None).JoinToString(newStr);
end;
/// Возвращает True если значение находится между двумя другими
/// Возвращает True если строка находится между двумя другими (лексикографическое сравнение)
function Between(Self: string; a, b: string): boolean; extensionmethod;
begin
Result := (a <= Self) and (Self <= b) or (b <= Self) and (Self <= a);

View file

@ -827,7 +827,7 @@ end;
/// Первые k простых чисел
function FirstPrimes(k: integer): List<integer>;
begin
k := k.ClampTop(integer.MaxValue); // на всякий случай
// k := Min(k,integer.MaxValue); // на всякий случай
if k <= nPrimeDivs then Result := LPrimes[:k]
else
begin

View file

@ -4263,7 +4263,7 @@ function BillboardText(p: Point3D; Text: string; Fontsize: real) := BillboardTex
function CoordinateSystem(ArrowsLength, Diameter: real): CoordinateSystemT := Inv(()->CoordinateSystemT.Create(0, 0, 0, arrowslength, diameter));
function CoordinateSystem(ArrowsLength: real) := CoordinateSystem(arrowslength, (arrowslength / 10).ClampTop(0.18));
function CoordinateSystem(ArrowsLength: real) := CoordinateSystem(arrowslength, Min(arrowslength / 10, 0.18));
function Text3D(x, y, z: real; Text: string; Height: real; fontname: string; c: Color): TextT := Inv(()->TextT.Create(x, y, z, text, height, fontname, c));

View file

@ -4,6 +4,7 @@ using PascalABCCompiler.TreeRealization;
using TreeConverter.LambdaExpressions;
using System.Linq;
using for_node = PascalABCCompiler.SyntaxTree.for_node;
using System.Collections.Generic;
namespace PascalABCCompiler.TreeConverter
{
@ -108,9 +109,10 @@ namespace PascalABCCompiler.TreeConverter
var IsTuple = IsTupleType(t);
var IsSequence = !IsTuple && IsSequenceType(t);
var IsKeyValuePair = !IsTuple && IsKeyValuePairType(t);
var IsSequence = !IsTuple && !IsKeyValuePair && IsSequenceType(t);
if (!IsTuple && !IsSequence)
if (!IsTuple && !IsSequence && !IsKeyValuePair)
{
AddError(inwhatloc, "TUPLE_OR_SEQUENCE_EXPECTED_FOREACH");
}
@ -119,7 +121,13 @@ namespace PascalABCCompiler.TreeConverter
{
var n = vars.idents.Count();
if (n > t.GetGenericArguments().Count())
AddError(get_location(vars), "TOO_MANY_ELEMENTS_ON_LEFT_SIDE_OF_TUPLE_ASSIGNMRNT");
AddError(get_location(vars), "TOO_MANY_ELEMENTS_ON_LEFT_SIDE_OF_TUPLE_ASSIGNMENT");
}
if (IsKeyValuePair)
{
var n = vars.idents.Count();
if (n > 2)
AddError(get_location(vars), "TOO_MANY_ELEMENTS_ON_LEFT_SIDE_OF_KEYVALUEPAIR_ASSIGNMENT");
}
}

View file

@ -21,9 +21,10 @@ namespace PascalABCCompiler.TreeConverter
AddError(expr.location, "TUPLE_OR_SEQUENCE_EXPECTED");
var IsTuple = IsTupleType(t);
var IsKeyValuePair = !IsTuple && IsKeyValuePairType(t);
var IsSequence = !IsTuple && IsSequenceType(t);
if (!IsTuple && !IsSequence)
if (!IsTuple && !IsKeyValuePair && !IsSequence)
{
AddError(expr.location, "TUPLE_OR_SEQUENCE_EXPECTED");
}
@ -32,7 +33,13 @@ namespace PascalABCCompiler.TreeConverter
{
var n = vars.variables.Count();
if (n > t.GetGenericArguments().Count())
AddError(get_location(vars), "TOO_MANY_ELEMENTS_ON_LEFT_SIDE_OF_TUPLE_ASSIGNMRNT");
AddError(get_location(vars), "TOO_MANY_ELEMENTS_ON_LEFT_SIDE_OF_TUPLE_ASSIGNMENT");
}
if (IsKeyValuePair)
{
var n = vars.variables.Count();
if (n > 2)
AddError(get_location(vars), "TOO_MANY_ELEMENTS_ON_LEFT_SIDE_OF_KEYVALUEPAIR_ASSIGNMENT");
}
}
@ -52,12 +59,13 @@ namespace PascalABCCompiler.TreeConverter
AddError(expr.location, "TUPLE_OR_SEQUENCE_EXPECTED");
return;
}
var IsTuple = IsTupleType(t);
var IsSequence = !IsTuple && IsSequenceType(t);
var IsKeyValuePair = !IsTuple && IsKeyValuePairType(t);
var IsSequence = !IsTuple && !IsKeyValuePair && IsSequenceType(t);
if (!IsTuple && !IsSequence)
if (!IsTuple && !IsKeyValuePair && !IsSequence)
{
AddError(expr.location, "TUPLE_OR_SEQUENCE_EXPECTED");
}
@ -66,7 +74,13 @@ namespace PascalABCCompiler.TreeConverter
{
var n = vars.idents.Count();
if (n > t.GetGenericArguments().Count())
AddError(get_location(vars), "TOO_MANY_ELEMENTS_ON_LEFT_SIDE_OF_TUPLE_ASSIGNMRNT");
AddError(get_location(vars), "TOO_MANY_ELEMENTS_ON_LEFT_SIDE_OF_TUPLE_ASSIGNMENT");
}
if (IsKeyValuePair)
{
var n = vars.idents.Count();
if (n > 2)
AddError(get_location(vars), "TOO_MANY_ELEMENTS_ON_LEFT_SIDE_OF_KEYVALUEPAIR_ASSIGNMENT");
}
}

View file

@ -19004,9 +19004,9 @@ namespace PascalABCCompiler.TreeConverter
// выбираем IEnumerable<T>
if (genericInterfaceCount == 1)
return filteredInterfaces.First(item => item.is_generic_type_instance);
// явно реализует IEnumerable
// явно реализует IEnumerable - странно - заменил на null - SSM 23.05.25
else
return IEnumType;
return null; // IEnumType;
case 1:
var method = methods[0];
@ -22183,12 +22183,17 @@ namespace PascalABCCompiler.TreeConverter
return !t.IsArray && (t.FullName.StartsWith("System.Tuple") || t.FullName.StartsWith("System.ValueTuple"));
}
public bool IsKeyValuePairType(Type t)
{
return t.FullName.StartsWith("System.Collections.Generic.KeyValuePair`2");
}
public bool IsSequenceType(Type t)
{
return t.Name.Equals("IEnumerable`1") || t.GetInterface("IEnumerable`1") != null;
}
private void CheckUnpacking(expression ex, out expression_node sem_ex, out bool IsTuple, out bool IsSequence, int countvars, syntax_tree_node stn)
/*private void CheckUnpacking(expression ex, out expression_node sem_ex, out bool IsTuple, out bool IsSequence, int countvars, syntax_tree_node stn)
{
sem_ex = convert_strong(ex);
sem_ex = convert_if_typed_expression_to_function_call(sem_ex);
@ -22206,7 +22211,7 @@ namespace PascalABCCompiler.TreeConverter
if (IsTuple)
{
if (countvars > t.GetGenericArguments().Count())
AddError(get_location(stn), "TOO_MANY_ELEMENTS_ON_LEFT_SIDE_OF_TUPLE_ASSIGNMRNT");
AddError(get_location(stn), "TOO_MANY_ELEMENTS_ON_LEFT_SIDE_OF_TUPLE_ASSIGNMENT");
}
}
@ -22223,7 +22228,7 @@ namespace PascalABCCompiler.TreeConverter
dn = new method_call(dn, pars);
}
return dn;
}
}*/
public override void visit(SyntaxTree.assign_tuple asstup) // сахарный узел
{
@ -22286,7 +22291,7 @@ namespace PascalABCCompiler.TreeConverter
{
var nn = assvartup.idents.idents.Count();
if (nn > t.GetGenericArguments().Count())
AddError(get_location(assvartup.idents), "TOO_MANY_ELEMENTS_ON_LEFT_SIDE_OF_TUPLE_ASSIGNMRNT");
AddError(get_location(assvartup.idents), "TOO_MANY_ELEMENTS_ON_LEFT_SIDE_OF_TUPLE_ASSIGNMENT");
}*/
@ -22331,6 +22336,7 @@ namespace PascalABCCompiler.TreeConverter
{
var IsSequence = false;
var IsTuple = false;
var IsKeyValuePair = false;
var sem_ex = convert_strong(ith.id);
sem_ex = convert_if_typed_expression_to_function_call(sem_ex);
var t = ConvertSemanticTypeNodeToNETType(sem_ex.type);
@ -22340,19 +22346,22 @@ namespace PascalABCCompiler.TreeConverter
type_node elem_type = null;
var b = FindIEnumerableElementType(sem_ex.type, ref elem_type, out bb);
if (b)
// Не очень понятно, зачем это нужно. И это точно не срабатывает
IsSequence = true;
else
AddError(sem_ex.location, "TUPLE_OR_SEQUENCE_EXPECTED");
}
if (t != null)
IsTuple = IsTupleType(t);
if (t != null)
IsSequence = !IsTuple && IsSequenceType(t);
if (!IsTuple && !IsSequence)
if (t != null)
IsKeyValuePair = !IsTuple && IsKeyValuePairType(t);
if (t != null)
IsSequence = !IsTuple && !IsKeyValuePair && IsSequenceType(t);
if (!IsTuple && !IsSequence && !IsKeyValuePair)
{
AddError(sem_ex.location, "TUPLE_OR_SEQUENCE_EXPECTED");
}
@ -22373,9 +22382,15 @@ namespace PascalABCCompiler.TreeConverter
ReplaceUsingParent(ith, mc);
visit(mc);
}
else if (IsKeyValuePair)
{
var meth_name = i == 0 ? "Key" : "Value";
var dn = new dot_node(ith.id.TypedClone(), new ident(meth_name));
ReplaceUsingParent(ith, dn);
visit(dn);
}
}
public override void visit(var_tuple_def_statement vtd)
{
AddError(get_location(vtd), "SUGARED_NODE_{0}_IN_SYNTAX_TREE_VISITOR", vtd.GetType().Name);

View file

@ -4263,7 +4263,7 @@ function BillboardText(p: Point3D; Text: string; Fontsize: real) := BillboardTex
function CoordinateSystem(ArrowsLength, Diameter: real): CoordinateSystemT := Inv(()->CoordinateSystemT.Create(0, 0, 0, arrowslength, diameter));
function CoordinateSystem(ArrowsLength: real) := CoordinateSystem(arrowslength, (arrowslength / 10).ClampTop(0.18));
function CoordinateSystem(ArrowsLength: real) := CoordinateSystem(arrowslength, Min(arrowslength / 10, 0.18));
function Text3D(x, y, z: real; Text: string; Height: real; fontname: string; c: Color): TextT := Inv(()->TextT.Create(x, y, z, text, height, fontname, c));

View file

@ -3168,43 +3168,44 @@ var
const
WRITELN_IN_BINARYFILE_ERROR_MESSAGE = 'Операция Writeln не применима к бинарным файлам!!Writeln is not applicable to binary files';
InternalNullBasedArrayName = 'NullBasedArray';
FILE_NOT_ASSIGNED = 'Для файловой переменной не вызвана процедура Assign!!File is not assigned';
FILE_NOT_OPENED = 'Файл не открыт!!File is not opened';
FILE_NOT_OPENED_FOR_READING = 'Файл не открыт на чтение!!File is not opened for reading';
FILE_NOT_OPENED_FOR_WRITING = 'Файл не открыт на запись!!File is not opened for writing';
READ_LEXEM_AFTER_END_OF_TEXT_FILE = 'Попытка считывания за концом текстового файла!!Read after end of text file';
READ_LEXEM_AFTER_END_OF_INPUT_STREAM = 'Попытка считывания за концом потока ввода!!Read after end of input stream';
RANGE_ERROR_MESSAGE = 'Выход за границы диапазона!!Out of range';
EOF_FOR_TEXT_WRITEOPENED = 'Функция Eof не может быть вызвана для текстового файла, открытого на запись!!Eof function can''t be called for file, opened on writing';
EOLN_FOR_TEXT_WRITEOPENED = 'Функция Eoln не может быть вызвана для текстового файла, открытого на запись!!Eoln function can''t be called for file, opened on writing';
SEEKEOF_FOR_TEXT_WRITEOPENED = 'Функция SeekEof не может быть вызвана для текстового файла, открытого на запись!!SeekEof function can''t be called for file, opened on writing';
SEEKEOLN_FOR_TEXT_WRITEOPENED = 'Функция SeekEoln не может быть вызвана для текстового файла, открытого на запись!!SeekEoln function can''t be called for file, opened on writing';
BAD_TYPE_IN_RUNTIMESIZEOF = 'Для типизированных файлов нельзя указывать тип элементов, являющийся ссылочным или содержащий ссылочные поля!!Bad Type in RunTimeSizeOf';
FILE_NOT_ASSIGNED = 'Для файловой переменной не вызвана процедура Assign!!File variable was not assigned using Assign';
FILE_NOT_OPENED = 'Файл не открыт!!File is not open';
FILE_NOT_OPENED_FOR_READING = 'Файл не открыт на чтение!!File is not open for reading';
FILE_NOT_OPENED_FOR_WRITING = 'Файл не открыт на запись!!File is not open for writing';
READ_LEXEM_AFTER_END_OF_TEXT_FILE = 'Попытка считывания за концом текстового файла!!Attempt to read beyond end of text file';
READ_LEXEM_AFTER_END_OF_INPUT_STREAM = 'Попытка считывания за концом потока ввода!!Attempt to read beyond end of input stream';
RANGE_ERROR_MESSAGE = 'Выход за пределы допустимого диапазона!!Out of range';
EOF_FOR_TEXT_WRITEOPENED = 'Функция Eof не может быть вызвана для текстового файла, открытого на запись!!Eof function cannot be called on a text file opened for writing';
EOLN_FOR_TEXT_WRITEOPENED = 'Функция Eoln не может быть вызвана для текстового файла, открытого на запись!!Eoln function cannot be called on a text file opened for writing';
SEEKEOF_FOR_TEXT_WRITEOPENED = 'Функция SeekEof не может быть вызвана для текстового файла, открытого на запись!!SeekEof function cannot be called on a text file opened for writing';
SEEKEOLN_FOR_TEXT_WRITEOPENED = 'Функция SeekEoln не может быть вызвана для текстового файла, открытого на запись!!SeekEoln function cannot be called on a text file opened for writing';
BAD_TYPE_IN_RUNTIMESIZEOF = 'Типизированный файл не может содержать ссылочный тип или тип со ссылочными полями!!Typed file cannot contain a reference type or a type with reference fields';
PARAMETER_MUST_BE_GREATER_EQUAL_0 = 'Параметр должен быть >= 0!!Parameter must be >= 0';
PARAMETER_MUST_BE_GREATER_0 = 'Параметр должен быть > 0!!Parameter must be > 0';
PARAMETER_MUST_BE_GREATER_1 = 'Параметр должен быть > 1!!Parameter must be > 1';
PARAMETER_STEP_MUST_BE_NOT_EQUAL_0 = 'Параметр step не может быть равен 0!!The step parameter must be not equal to 0';
PARAMETER_STEP_MUST_BE_GREATER_0 = 'Параметр step должен быть > 0!!The step parameter must be not greater than 0';
PARAMETER_FROM_OUT_OF_RANGE = 'Параметр from за пределами диапазона!!The from parameter out of bounds';
PARAMETER_TO_OUT_OF_RANGE = 'Параметр to за пределами диапазона!!The to parameter out of bounds';
ARR_LENGTH_MUST_BE_MATCH_TO_MATR_SIZE = 'Размер одномерного массива не согласован с размером двумерного массива!!The 1-dim array length does not match 2-dim array size';
INITELEM_COUNT_MUST_BE_EQUAL_TO_MATRIX_ELEMS_COUNT = 'Количество инициализирующих элементов не совпадает с количеством элементов матрицы!!The number of elements in init list must be equal to the number of elements in matrix';
TYPED_FILE_CANBE_OPENED_IN_SINGLEBYTE_ENCODING_ONLY = 'При открытии типизированного файла можно указывать только однобайтную кодировку!!Typed file can be opened in single byte encoding only';
BAD_ROW_INDEX = 'Один из элементов массива RowIndex выходит за пределы индексов строк двумерного массива!!One of the elements of RowIndex array is out of range of 2-dim array row indexes';
BAD_COL_INDEX = 'Один из элементов массива ColIndex выходит за пределы индексов столбцов двумерного массива!!One of the elements of ColIndex array is out of range of 2-dim array column indexes';
BAD_ROW_INDEX_FROM = 'FromRow выходит за пределы индексов строк двумерного массива!!FromRow is out of range of 2-dim array row indexes';
BAD_ROW_INDEX_TO = 'ToRow выходит за пределы индексов строк двумерного массива!!ToRow is out of range of 2-dim array row indexes';
BAD_COL_INDEX_FROM = 'FromCol выходит за пределы индексов строк двумерного массива!!FromCol is out of range of 2-dim array column indexes';
BAD_COL_INDEX_TO = 'ToCol выходит за пределы индексов строк двумерного массива!!ToCol is out of range of 2-dim array column indexes';
SLICE_SIZE_AND_RIGHT_VALUE_SIZE_MUST_BE_EQUAL = 'Размеры среза и присваиваемого выражения должны быть равны!!Slice size and assigned expression size must be equal';
PARAMETER_MUST_BE_GREATER_0 = 'Параметр должен быть больше 0!!Parameter must be > 0';
PARAMETER_MUST_BE_GREATER_1 = 'Параметр должен быть больше 1!!Parameter must be > 1';
PARAMETER_STEP_MUST_BE_NOT_EQUAL_0 = 'Параметр step не может быть равен 0!!Step parameter must not be equal to 0';
PARAMETER_STEP_MUST_BE_GREATER_0 = 'Параметр step должен быть > 0!!Step parameter must be greater than 0';
PARAMETER_FROM_OUT_OF_RANGE = 'Параметр from за пределами диапазона!!From parameter is out of range';
PARAMETER_TO_OUT_OF_RANGE = 'Параметр to за пределами диапазона!!To parameter is out of range';
ARR_LENGTH_MUST_BE_MATCH_TO_MATR_SIZE = 'Размер одномерного массива не согласован с размером двумерного массива!!The length of the 1D array must match the size of the 2D array';
INITELEM_COUNT_MUST_BE_EQUAL_TO_MATRIX_ELEMS_COUNT = 'Количество инициализирующих элементов не совпадает с количеством элементов матрицы!!The number of initializer elements must equal the number of elements in the matrix';
TYPED_FILE_CANBE_OPENED_IN_SINGLEBYTE_ENCODING_ONLY = 'При открытии типизированного файла можно указывать только однобайтную кодировку!!Typed files can only be opened with single-byte encodings';
BAD_ROW_INDEX = 'Один из элементов массива RowIndex выходит за пределы индексов строк двумерного массива!!An element in the RowIndex array is out of range for the matrix row indices';
BAD_COL_INDEX = 'Один из элементов массива ColIndex выходит за пределы индексов столбцов двумерного массива!!An element in the ColIndex array is out of range for the matrix column indices';
BAD_ROW_INDEX_FROM = 'FromRow выходит за пределы индексов строк двумерного массива!!FromRow is out of range for the matrix row indices';
BAD_ROW_INDEX_TO = 'ToRow выходит за пределы индексов строк двумерного массива!!ToRow is out of range for the matrix row indices';
BAD_COL_INDEX_FROM = 'FromCol выходит за пределы индексов строк двумерного массива!!FromCol is out of range for the matrix column indices';
BAD_COL_INDEX_TO = 'ToCol выходит за пределы индексов строк двумерного массива!!ToCol is out of range for the matrix column indices';
SLICE_SIZE_AND_RIGHT_VALUE_SIZE_MUST_BE_EQUAL = 'Размеры среза и присваиваемого выражения должны быть равны!!Slice size must match the size of the assigned expression';
MATR_DIMENSIONS_MUST_BE_EQUAL = 'Размеры матриц должны совпадать!!Matrix dimensions must be equal';
COUNT_PARAMS_MAXFUN_MUSTBE_GREATER1 = 'Количество параметров функции Max должно быть > 1!!The number of parameters of the Max function must be > 1';
COUNT_PARAMS_MINFUN_MUSTBE_GREATER1 = 'Количество параметров функции Min должно быть > 1!!The number of parameters of the Min function must be > 1';
Format_InvalidString = 'Входная строка имела неверный формат!!Input string was not in a correct format';
COUNT_PARAMS_MAXFUN_MUSTBE_GREATER1 = 'Количество параметров функции Max должно быть > 1!!Max function must have more than one parameter';
COUNT_PARAMS_MINFUN_MUSTBE_GREATER1 = 'Количество параметров функции Min должно быть > 1!!Min function must have more than one parameter';
Format_InvalidString = 'Входная строка имела неверный формат!!Input string was not in a valid format';
Overflow_Int32 = 'Целочисленное переполнение!!Integer overflow';
FOR_STEP_CANNOT_BE_EQUAL0 = 'Шаг цикла for не может быт равен 0!!Step of the for loop cannot be equal to 0';
FOR_STEP_CANNOT_BE_EQUAL0 = 'Шаг цикла for не может быт равен 0!!The step of a for loop cannot be 0';
SEQUENCE_CANNOT_BE_EMPTY = 'Последовательность не может быть пустой!!Sequence cannot be empty';
ARRAY_CANNOT_BE_EMPTY = 'Массив не может быть пустым!!Array cannot be empty';
MIN_CANNOT_BE_GREATER_THAN_MAX = 'CLamp: min не может быть больше чем max!!CLamp: min cannot be greater than max';
// -----------------------------------------------------
// WINAPI
// -----------------------------------------------------
@ -14278,29 +14279,15 @@ begin
Result := Range(0, Self - 1);
end;
/// Возвращает число, ограниченное диапазоном от bottom до top включительно
function Clamp(Self: integer; bottom,top: integer): integer; extensionmethod;
/// Возвращает число, ограниченное диапазоном от min до max включительно
function Clamp(Self: integer; min,max: integer): integer; extensionmethod;
begin
if Self < bottom then
Result := bottom
else if Self > top then
Result := top
else Result := Self;
end;
/// Возвращает число, ограниченное величиной top сверху
function ClampTop(Self: integer; top: integer): integer; extensionmethod;
begin
if Self > top then
Result := top
else Result := Self;
end;
/// Возвращает число, ограниченное величиной bottom снизу
function ClampBottom(Self: integer; bottom: integer): integer; extensionmethod;
begin
if Self < bottom then
Result := bottom
if min > max then
raise new System.ArgumentException(GetTranslation(MIN_CANNOT_BE_GREATER_THAN_MAX));
if Self < min then
Result := min
else if Self > max then
Result := max
else Result := Self;
end;
@ -14395,33 +14382,18 @@ begin
Result := Format('{0:f' + frac + '}', Self)
end;
/// Возвращает число, ограниченное диапазоном от bottom до top включительно
function Clamp(Self: real; bottom,top: real): real; extensionmethod;
/// Возвращает число, ограниченное диапазоном от min до max включительно
function Clamp(Self: real; min,max: real): real; extensionmethod;
begin
if Self < bottom then
Result := bottom
else if Self > top then
Result := top
if min > max then
raise new System.ArgumentException(GetTranslation(MIN_CANNOT_BE_GREATER_THAN_MAX));
if Self < min then
Result := min
else if Self > max then
Result := max
else Result := Self;
end;
/// Возвращает число, ограниченное величиной top сверху
function ClampTop(Self: real; top: real): real; extensionmethod;
begin
if Self > top then
Result := top
else Result := Self;
end;
/// Возвращает число, ограниченное величиной bottom снизу
function ClampBottom(Self: real; bottom: real): real; extensionmethod;
begin
if Self < bottom then
Result := bottom
else Result := Self;
end;
//------------------------------------------------------------------------------
//>> Методы расширения типа char # Extension methods for char
//------------------------------------------------------------------------------

View file

@ -827,7 +827,7 @@ end;
/// Первые k простых чисел
function FirstPrimes(k: integer): List<integer>;
begin
k := k.ClampTop(integer.MaxValue); // на всякий случай
// k := Min(k,integer.MaxValue); // на всякий случай
if k <= nPrimeDivs then Result := LPrimes[:k]
else
begin

View file

@ -3,7 +3,8 @@ CAN_NOT_READ=Can not read data of this type
TUPLE_EXPECTED=Tuple expected
TUPLE_OR_SEQUENCE_EXPECTED=Tuple or sequence expected
TUPLE_OR_SEQUENCE_EXPECTED_FOREACH=Sequence of tuple or sequence expected
TOO_MANY_ELEMENTS_ON_LEFT_SIDE_OF_TUPLE_ASSIGNMRNT=Too many elements on the left side of tuple assignment
TOO_MANY_ELEMENTS_ON_LEFT_SIDE_OF_TUPLE_ASSIGNMENT=Too many elements on the left side of tuple assignment
TOO_MANY_ELEMENTS_ON_LEFT_SIDE_OF_KEYVALUEPAIR_ASSIGNMENT=Too many elements on the left side of KeyValuePair assignment
ONLY_BASE_ASSIGNMENT_FOR_TUPLE=Tuple allows only base assignment :=
TUPLE_TYPE_ERROR=Bad element in Tuple type
INTEGER_VALUE_EXPECTED=Integer value expected

View file

@ -1,9 +1,10 @@
%PREFIX%=SEMANTICERROR_
CAN_NOT_READ=Нельзя считывать данные этого типа
TUPLE_EXPECTED=Ожидался кортеж
TUPLE_OR_SEQUENCE_EXPECTED=Ожидался кортеж или последовательность
TUPLE_OR_SEQUENCE_EXPECTED_FOREACH=Ожидалась последовательность кортежей или последовательностей
TOO_MANY_ELEMENTS_ON_LEFT_SIDE_OF_TUPLE_ASSIGNMRNT=Слишком много переменных при распаковке кортежа
TUPLE_OR_SEQUENCE_EXPECTED=Ожидался кортеж или последовательность или пара (ключ,значение)
TUPLE_OR_SEQUENCE_EXPECTED_FOREACH=Ожидалась последовательность кортежей или последовательностей или пар (ключ,значение)
TOO_MANY_ELEMENTS_ON_LEFT_SIDE_OF_TUPLE_ASSIGNMENT=Слишком много переменных при распаковке кортежа
TOO_MANY_ELEMENTS_ON_LEFT_SIDE_OF_KEYVALUEPAIR_ASSIGNMENT=Слишком много переменных при распаковке пары (ключ,значение)
ONLY_BASE_ASSIGNMENT_FOR_TUPLE=Для кортежа допустимо только обычное присваивание :=
TUPLE_TYPE_ERROR=Ошибочная конструкция при построении типа кортежа
INTEGER_VALUE_EXPECTED=Ожидалось значение целого типа