Logo

21 ноября 2014 г.

Этюд 1. WideParamStr — итераторы с охраной

Замена циклов на итераторы с охраной принята окончательно и находит постепенное воплощение в коде. В этом этюде сделана попытка переписать на Кантор функцию WideParamStr из CoreUtils.

На Delphi

type
  TWideParamRec = record
    NextParam, Param: PWideChar;
    Length: Integer;
    Quoted: Boolean;
  end;

function WideParamStr(CommandLine: PWideChar): TWideParamRec;
var
  P: PWideChar;
  L: Integer;
begin
  if CommandLine <> nil then
  begin
    while (CommandLine^ = WideChar(32)) or (CommandLine^ = WideChar(9)) do
      Inc(CommandLine);
    if CommandLine^ = WideChar('"') then
    begin
      Inc(CommandLine);
      L := WideStrLen(CommandLine);
      P := WideStrScan(CommandLine, L, CoreChar('"'));
      if P <> nil then
        L := P - CommandLine;
      Result.Quoted := True;
    end
    else
    begin
      P := CommandLine;
      while (P^ <> WideChar(32)) and (P^ <> WideChar(9)) and (P^ <> WideChar(0)) do
        Inc(P);
      L := P - CommandLine;
      Result.Quoted := False;
    end;
    with Result do
    begin
      NextParam := CommandLine + L + Byte(Quoted);
      if NextParam^ <> WideChar(0) then
        Inc(NextParam);
      Param := CommandLine;
      Length := L;
    end;
  end
  else
    FillChar(Result, SizeOf(Result), 0);
end;

На Канторе

Код не является буквальным эквивалентом собрата на Delphi: работа с локальными переменными заменена функцией-замыканием, чтобы сделать код более функциональным. Также введено ключевое слово outside для операции невхождения в набор (раньше она условно обозначалась сочетанием not in).
final class WideParamRec public of
  var ref Unsafe:WideChar NextParam, Param;
  var Integer Length;
  var Boolean Quoted;
end;

WideParamRec WideParamStr[ref Unsafe:WideChar commandLine] of
  if commandLine! then
    var ref cmdLine = commandLine;

    result[Integer len; Boolean quot] of // замыкание
      nxt = cmdLine + len + quot.AsByte;
      return new of
        NextParam = nxt + ?nxt.First{#quot, 1};
        Param = cmdLine;
        Length = len;
        Quoted = quot;
      end;
    end;

    cmdLine++ where cmdLine.First in {9, 32};
    if cmdLine.First = #quot.AsShortWord then
      cmdLine++;
      with
        len = cmdLine.StrLen;
        ptr = cmdLine.StrScan(#quot, len);
      return
        result[?ptr!{ptr - cmdLine, len}, True];
      end;
    else
      var ref ptr = cmdLine;
      ptr++ where ptr.First outside {32, 9, 0};
      return result[ptr - cmdLine, False];
    end;
  else
    return new from null;
  end;
end;
Планируется, что смысл where будет аналогичен SQL:
Упоминание членов охраняемого выражения обозначает итерации, а внешние по отношению к охране условия — немедленный выход, аналогичный оператору break.

Подсветка синтаксиса

Подсветки синтаксиса в блоге пока нет, а с ней этюд выглядит гораздо приятней.
Добавлена подсветка синтаксиса, скриншоты удалены.

Комментариев нет :

Отправить комментарий

Выбрав в выпадающем списке пункт «Имя/URL», можно оставить комментарий от своего имени без предварительной регистрации.