Logo

31 января 2015 г.

Этюд 9. Группировка свойств класса

Этот этюд перекликается со вторым этюдом, где аналог типа WordRec из Delphi описывался с использованием оператора частичного применения в Канторе. Сейчас же будет рассмотрен прямой аналог вариантной записи Delphi — при помощи ключевого слова else в теле класса. Поскольку все типы в Канторе являются классами, возможность группировки свойств добавлена прямо в классы, отдельный тип «запись» отсутствует.

На Delphi

Код на Delphi полностью взят из второго этюда:
type
  WordRec = packed record
    case Byte of
      0: (Lo, Hi: Byte);
      1: (Bytes: array [0..1] of Byte);
  end;

  LongRec = packed record
    case Byte of
      0: (Lo, Hi: Word);
      1: (Words: array [0..1] of Word);
      2: (Bytes: array [0..3] of Byte);
  end;

На Канторе

Предполагается, что аналогичная возможность в Канторе будет реализована ключевым словом else в теле класса:
public class ShortRec public of
  var Core:Byte Lo, Hi;
else
  var Core:Byte Bytes[2];
end;

public class LongRec public of
  var Core:ShortWord Lo, Hi;
else
  var Core:ShortWord ShortWords[2];
else
  var Core:Byte Bytes[4];
end;
Синтаксис пока сильно экспериментальный, поэтому пример схематичен.

Особености реализации

Запланированы следующие низкоуровневые возможности:
  • Выравнивание — конструкция align by.
  • Группировка только части свойств-переменных — полный аналог union из Си — конструкция group by.
Использованная в этюде конструкция с else может считаться упрощенной записью group by или ее совмещением с телом класса. Возможна также явная форма совмещения (экспериментальный синтаксис):
public class ShortRec public group by 1 of // совмещение, выравнивание 
  var Core:Byte Lo, Hi;                    // на 1 байт
else
  var Core:Byte Bytes[2];
end;
Группировку части свойств можно показать на примере реального класса API Windows — DRIVE_LAYOUT_INFORMATION_EX:
public class DRIVE_LAYOUT_INFORMATION_EX public align by 8 of
  var Core:LongWord PartitionStyle, PartitionCount;   // ^-- для IOCtrl
  group
    var DRIVE_LAYOUT_INFORMATION_MBR Mbr;
  else
    var DRIVE_LAYOUT_INFORMATION_GPT Gpt;
  end;
  var PARTITION_INFORMATION_EX PartitionEntry[1];
end;
Точная семантика предложенных тут конструкций еще должна быть доработана.

1 января 2015 г.

Отказ от ключевого слова elsif

Синтаксис Кантора вновь подвергся небольшому пересмотру: исключено ключевое слово elsif. Спасибо коллеге Zealint за наводку. На смену elsif приходит совмещение блоков, не требующее отдельного end. Это означает, что теперь вместо elsif нужно писать else case или else if, и ничего за это не будет.

Совмещение блоков

Совмещение блоков — синтаксический механизм в языке Кантор, позволяющий совмещать идущие друг за другом или вложенные блочные операторы с целью завершения их одним end.
В данный момент совмещение работает для блочных объявлений с of, блоков where all и where any, а теперь еще и для else case и else if.

Совмещение блоков of

// Без совмещения
public class ScreenInfo of
  final of
    var Core:Word Width, Height;
    var Core:ShortWord PixelsPerInch;
  end;
end;

// Совмещение
public class ScreenInfo final of
  var Core:Word Width, Height;
  var Core:ShortWord PixelsPerInch;
end;

Совмещение блочных условий where

Синтаксис контейнерной арифметики до конца не проработан, поэтому пример схематичен:
with
  lst = {'C', 'Cantor', 'Pascal'};
return group from lst inner where all // совмещение
  row.Length == 6;
  row.First == 'C';
end;
Идущие друг за другом операторы where all и where any совмещаются принудительно, поэтому примера без совмещения нет.

Оператор case

Объединенный оператор ветвления (следования), полученный в результате приведения if к case, теперь выглядит так:
case выражение
  when значение1 then
    ветвь;
  when значение2 then
    ветвь;
  when значение3 then
    ветвь;
else
  ветвь;
end;
При этом ветвь else совмещается, если в ней находится единственный case или if:
// Совмещение else case
case выражение1
  when значение1_1 then
    ветвь;
  when значение1_2 then
    ветвь;
  when значение1_3 then
    ветвь;
else case выражение2
  when значение2_1 then
    ветвь;
  when значение2_2 then
    ветвь;
  when значение2_3 then
    ветвь;
else
  ветвь;
end;

// Совмещение else if
case выражение1
  when значение1_1 then
    ветвь;
  when значение1_2 then
    ветвь;
  when значение1_3 then
    ветвь;
else if выражение2 then
  ветвь;
else
  ветвь;
end;
Поскольку ранее предполагалось, что записи с elsif в байт-коде должны быть неотличимы от вложенных ветвлений, совмещение лишь приближает текстовую запись к байт-коду, что улучшает воплощение концепции «Кантор — высокоуровневый ассемблер».

Оператор if

Поскольку пересмотр синтаксиса затрагивает и оператор if, его тоже приходится описывать заново:

// Одиночный оператор
if условие then
  ветвь;
else
  ветвь;
end;

// Совмещение else case
if условие then
  ветвь;
else case выражение
  when значение1 then
    ветвь;
  when значение2 then
    ветвь;
  when значение3 then
    ветвь;
else
  ветвь;
end;

// Совмещение else if
if условие1 then
  ветвь;
else if условие2 then
  ветвь;
else
  ветвь;
end;
Еще в прошлой ревизии оператор if был признан синтаксическим сахаром case, поэтому предыдущий код может быть отекстован и так:
// Одиночный оператор
case условие 
  when True then
    ветвь;
else
  ветвь;
end;

// Совмещение else case
case условие 
  when True then
    ветвь;
else case выражение
  when значение1 then
    ветвь;
  when значение2 then
    ветвь;
  when значение3 then
    ветвь;
else
  ветвь;
end;

// Совмещение else if → else case
case условие1 
  when True then
    ветвь;
else case условие2 
  when True then
    ветвь;
else
  ветвь;
end;

Строчные case и if

Строчные case и if аналогичны блочным с той разницей, что на месте ветвей выполнения стоят одиночные выражения или кортежи.

Happy = 2014++;

Казалось бы, что общего между Новым годом и разработкой ОС? А я вот недавно узнал, что новогодняя (рождественская) ёлка по-немецки — Tannenbaum, про нее даже одноименная песенка есть, у немцев она вроде нашей «В лесу родилась ёлочка». Glückliches neues Jahr an alle, то есть...

Всех с Новым годом!

Пусть в наступившем 2015-м году будет еще больше открытий и достижений!