Oberon space
General Category => Общий раздел => Тема начата: ilovb от Декабрь 19, 2012, 04:33:33 pm
-
Думал что UTF-8. А оказалось:
PROCEDURE (wr: StdWriter) WriteChar (ch: CHAR);
VAR t: StdModel; u, un: Run; lp: LPiece; pos, spillPos: INTEGER;
fw: Files.Writer; op: EditOp; bunch: BOOLEAN;
BEGIN
IF (ch >= 20X) & (ch < 7FX)
OR (ch = tab) OR (ch = line) OR (ch = para)
OR (ch = zwspace) OR (ch = digitspace)
OR (ch = hyphen) OR (ch = nbhyphen) OR (ch >= 0A0X) & (ch < 100X) THEN
WriteSChar(wr, SHORT(ch)) (* could inline! *)
ELSIF ch = 200BX THEN wr.WriteChar(zwspace)
ELSIF ch = 2010X THEN wr.WriteChar(hyphen)
ELSIF ch = 2011X THEN wr.WriteChar(nbhyphen)
ELSIF ch >= 100X THEN
t := wr.base; pos := wr.pos;
IF t.spill.file = NIL THEN OpenSpill(t.spill) END;
fw := t.spill.writer;
fw.WriteByte(SHORT(SHORT(ORD(ch))));
fw.WriteByte(SHORT(SHORT(ORD(ch) DIV 256 - 128)));
spillPos := t.spill.len; t.spill.len := spillPos + 2;
IF (t.Domain() = NIL) OR (t.Domain().GetSequencer() = NIL) THEN
(* optimized for speed - writing to unbound text *)
InvalCache(t, pos);
IF wr.era # t.era THEN WriterReset(wr) END;
un := wr.run; u := un.prev;
IF (u.attr # NIL) & u.attr.Equals(wr.attr) & (u IS LPiece) & ~(u IS Piece) & (u(LPiece).file = t.spill.file)
& (u(LPiece).org + 2 * u.len = spillPos) THEN
INC(u.len);
IF t.pc.org >= pos THEN INC(t.pc.org) END
ELSE
NEW(lp); u.next := lp; lp.prev := u; lp.next := un; un.prev := lp;
lp.len := 1; lp.attr := wr.attr;
lp.file := t.spill.file; lp.org := spillPos;
IF t.pc.org > pos THEN INC(t.pc.org) END;
IF ~Stores.Joined(t, lp.attr) THEN
IF ~Stores.Unattached(lp.attr) THEN lp.attr := Stores.CopyOf(lp.attr)(Attributes) END;
Stores.Join(t, lp.attr)
END
END;
INC(t.era); INC(t.len);
INC(wr.era)
ELSE
GetWriteOp(t, pos, op, bunch);
IF (op.attr = NIL) OR ~op.attr.Equals(wr.attr) THEN op.attr := wr.attr END;
op.mode := writeChar; (*op.attr := wr.attr;*) op.len := spillPos;
IF bunch THEN Models.Bunch(t) ELSE Models.Do(t, "#System:Inserting", op) END
END;
wr.pos := pos + 1
END
END WriteChar;
Че эт за манипуляция?
-
Там документ разбивается на "писы" - и "пис" может быть либо в однобайтной кодировке, либо в двубайтной. Смысл -128 не разъясню с лёту.
-
Тык тут вроде не либо-либо. А именно плавающее количество байт насколько я понимаю. ???
-
Однако тут какое-то хитрожопое кодирование целых чисел.
-
Однако тут какое-то хитрожопое кодирование целых чисел.
Опять же в компайлере юзаются:
(* utf8 strings *)
PROCEDURE PutUtf8* (VAR str: ARRAY OF SHORTCHAR; val: INTEGER; VAR idx: INTEGER);
BEGIN
ASSERT((val >= 0) & (val < 65536));
IF val < 128 THEN
str[idx] := SHORT(CHR(val)); INC(idx)
ELSIF val < 2048 THEN
str[idx] := SHORT(CHR(val DIV 64 + 192)); INC(idx);
str[idx] := SHORT(CHR(val MOD 64 + 128)); INC(idx)
ELSE
str[idx] := SHORT(CHR(val DIV 4096 + 224)); INC(idx);
str[idx] := SHORT(CHR(val DIV 64 MOD 64 + 128)); INC(idx);
str[idx] := SHORT(CHR(val MOD 64 + 128)); INC(idx)
END
END PutUtf8;
PROCEDURE GetUtf8* (VAR str: ARRAY OF SHORTCHAR; VAR val, idx: INTEGER);
VAR ch: SHORTCHAR;
BEGIN
ch := str[idx]; INC(idx);
IF ch < 80X THEN
val := ORD(ch)
ELSIF ch < 0E0X THEN
val := ORD(ch) - 192;
ch := str[idx]; INC(idx); val := val * 64 + ORD(ch) - 128
ELSE
val := ORD(ch) - 224;
ch := str[idx]; INC(idx); val := val * 64 + ORD(ch) - 128;
ch := str[idx]; INC(idx); val := val * 64 + ORD(ch) - 128
END
END GetUtf8;
Ничего не понимаю...
-
И как обычно нет комментариев )))
Вот вам и эталонный код от професси-анальных оберонщегов...
-
И как обычно нет комментариев )))
Да. Удивительно как они сами свой код понимают.
-
У них есть своя внутренняя документация, которую они не публикуют.
P.S. Комментарии в коде - это плохо. Должно лежать "сбоку" пояснение по всем моментам, почему, что и как решено.
Кроме того, при разработке ограниченным кругом не ставится задача облегчить любому из N заинтересованных посторонних лиц внесения интересующего его изменения с минимальными трудозатратами.
В стиле "захотел поменять - полез в нужное место - не понимая всего, понял только его - поменял - ура".
Предполагается, что общая модель системы загружена в голову.
Когда мне понадобился Kernel, я за пару дней сложил в голове такую модель...
-
Там документ разбивается на "писы" - и "пис" может быть либо в однобайтной кодировке, либо в двубайтной. Смысл -128 не разъясню с лёту.
Действительно. В разных писах разное число байт на символ:
PROCEDURE (rd: StdReader) Read;
VAR t: StdModel; u: Run; n, pos, len: INTEGER; lc: ARRAY 2 OF BYTE;
BEGIN
t := rd.base;
n := t.id MOD cacheWidth;
IF rd.era # t.era THEN Reset(rd) END;
u := rd.run;
WITH u: Piece DO
rd.attr := u.attr;
pos := rd.pos MOD cacheLen;
IF ~((cache[n].id = t.id) & (cache[n].beg <= rd.pos) & (rd.pos < cache[n].end)) THEN
(* cache miss *)
IF cache[n].id # t.id THEN cache[n].id := t.id; cache[n].beg := 0; cache[n].end := 0 END;
len := cacheLine;
IF len > cacheLen - pos THEN len := cacheLen - pos END;
IF len > u.len - rd.off THEN len := u.len - rd.off END;
rd.reader := u.file.NewReader(rd.reader); rd.reader.SetPos(u.org + rd.off);
rd.reader.ReadBytes(cache[n].buf, pos, len);
IF rd.pos = cache[n].end THEN
cache[n].end := rd.pos + len;
(*
INC(cache[n].end, len);
*)
IF cache[n].end - cache[n].beg >= cacheLen THEN
cache[n].beg := cache[n].end - (cacheLen - 1)
END
ELSE cache[n].beg := rd.pos; cache[n].end := rd.pos + len
END
END;
rd.char := CHR(cache[n].buf[pos] MOD 256); rd.view := NIL;
INC(rd.pos); INC(rd.off);
IF rd.off = u.len THEN rd.run := u.next; rd.off := 0 END
| u: LPiece DO (* ~(u IS Piece) *)
rd.attr := u.attr;
rd.reader := u.file.NewReader(rd.reader); rd.reader.SetPos(u.org + rd.off * 2);
rd.reader.ReadBytes(lc, 0, 2);
rd.char := CHR(lc[0] MOD 256 + 256 * (lc[1] + 128)); rd.view := NIL;
IF (cache[n].id = t.id) & (rd.pos = cache[n].end) THEN
cache[n].end := cache[n].end + 1;
IF cache[n].end - cache[n].beg >= cacheLen THEN cache[n].beg := cache[n].beg + 1 END;
(*
INC(cache[n].end);
IF cache[n].end - cache[n].beg >= cacheLen THEN INC(cache[n].beg) END
*)
END;
INC(rd.pos); INC(rd.off);
IF rd.off = u.len THEN rd.run := u.next; rd.off := 0 END
| u: ViewRef DO
rd.attr := u.attr;
rd.view := u.view; rd.w := u.w; rd.h := u.h; RemapView(rd);
IF (cache[n].id = t.id) & (rd.pos = cache[n].end) THEN
cache[n].end := cache[n].end + 1;
IF cache[n].end - cache[n].beg >= cacheLen THEN cache[n].beg := cache[n].beg + 1 END;
(*
INC(cache[n].end);
IF cache[n].end - cache[n].beg >= cacheLen THEN INC(cache[n].beg) END
*)
END;
INC(rd.pos); rd.run := u.next; rd.off := 0
ELSE
rd.eot := TRUE; rd.attr := NIL; rd.char := 0X; rd.view := NIL
END
END Read;
Но суть изврата мне не ясна.
-
У них есть своя внутренняя документация, которую они не публикуют.
P.S. Комментарии в коде - это плохо. Должно лежать "сбоку" пояснение по всем моментам, почему, что и как решено.
Кроме того, при разработке ограниченным кругом не ставится задача облегчить любому из N заинтересованных посторонних лиц внесения интересующего его изменения с минимальными трудозатратами.
В стиле "захотел поменять - полез в нужное место - не понимая всего, понял только его - поменял - ура".
Предполагается, что общая модель системы загружена в голову.
Когда мне понадобился Kernel, я за пару дней сложил в голове такую модель...
Странно.... У меня и у моих коллег представления ровно наоборот.
Внешняя документация - это конечно замечательно, вот только на ее поддержку ресурсов практически никогда нет в реале. Поддерживать актуальность комментариев значительно проще. Да и написать комментарий кодеру проще. А для написания полноценной документации обычно нужен отдельный чел, у которого голова не забита текущими кодерскими задачами. Одно не исключает другое, а дополняет.
Читать код без комментариев противно. Писать код без комментариев непрофессионально.
Помнить весь свой код нереально. Я забываю иногда что вчера писал в аврале.
Кроме того, при разработке ограниченным кругом не ставится задача облегчить любому из N заинтересованных посторонних лиц внесения интересующего его изменения с минимальными трудозатратами.
А это вообще парадоксальное высказывание. На мой взгляд это самая главная задача (облегчить) при написании кода, ибо разработчики меняются даже в одной команде иногда даже чуть менее чем полностью.
-
Я не оправдываю стиль написания кода ББ-шных разработчиков. Они, видимо, попали в частый соблазн - когда хорошо спроектируешь интерфейсы, то думаешь, что "а похрен, что там и как внутри у этого кирпича будет". Не говоря про то, что идеи, бродившие в начале 90-х, были полностью "зациклены" на двоичной компонентности, при сокрытии исходного кода.
Я сам стремлюсь писать ясный и хорошо декомпонированный код, но обычно этого достигаю "расслаиванием" функционала по многим объектам-кубикам. Т.е. то, что тут уложено в один модуль TextModels, я бы расслоил слоя на три минимум.
НО: я таки однозначно придерживаюсь принципа - "найди способ выразить мысль ясно напрямую кодом без комментариев". И только самые принципиальные нюансы (почему выбран именно такой, неочевидный, алгоритм, или почему такой формат, или какая "засада" встретилась при взаимодействии с внешним миром и как она было обойдена) пояснять в документации на реализацию. Это может быть, например, один большой комментарий без привязки к конкретному куску кода. Ну или пара-тройка комментариев по критичным местам.
Читать код без комментариев противно.
Вот, поймите меня правильно, я за то, чтобы шлифовать код (и разбивать на части функциональность) до той стадии, чтобы его не было противно читать без комментариев. Это на пользу и архитектуре, и каждому куску кода.
-
Мы с вами несколько по разному смотрим на код видимо. Я считаю что без комментариев противно читать любой код, независимо от его качества. Дело в том, что восприятие у всех разное, и представления о простом коде тоже разные.
Т.е. это все субъективно.
Вот, например, 1с-никам нравятся длинные названия переменных, т.к. можно по одному названию догадаться какой у нее тип и какое назначение. У нас не принято называть переменные одним/двумя символами - это считается злом, т.к. увеличивает время распознавания чужого кода. Мне довольно тяжело читать BB-шный код, т.к. приходится смотреть где и как используется переменная, чтобы понять зачем она нужна. На чтение и понимание 500 строк из BB у меня уходит примерно столько же времени как на чтение 10000 строк из 1С. Проф деформация, да... Но с этим нужно считаться.
А вот valexey'ю 1с-ный код мозг заворачивает, ибо он привык к более лаконичному написанию.
Ну и индивидуальные различия у людей тоже и психологические и интеллектуальные, да и образование разное. То, что доктору наук кажется элементарным, для простого смертного окажется головоломкой.
Всегда нужно учитывать что есть люди тупее чем вы, как бы это странно не звучало. У всех разные способности.
Единственное, что может восприниматься более-менее одинаково - это хороший коммент.
Вот что мешает добавить в код пару слов о том, какой метод использован? Вот приписали бы разработчики BB что в данном месте символ кодируется методом JIS X 0208 к примеру, и вопросов бы не было, и я не пялился бы два дня в этот код и не гуглил бы всемирную помойку в поисках ответа.
-
Я понимаю Вашу позицию, но позволю себе с ней не согласиться :)
Нужно искать возможность выражать мысль формально кодом.
Когда пытаешься, начинаешь быть внимательным к каждой мелочи (раньше казалось всё равно, записать так или иначе - а потом начинаешь придерживаться конкретного варианта).
Когда язык строгого стиля и не особо допускает многовариантности, то в итоге происходит некий спуск к некому единому стилю выражения мысли в коде. Когда код становится состоящим из узнаваемых "образцов" (тут во мне таки говорит методист, думающий о работе с уже наученными в едином стиле программистами :) ).
Т.е. хороший код без комментариев заставляет быть внимательным к своему смыслу.
-
Вот приписали бы разработчики BB что в данном месте символ кодируется методом JIS X 0208 к примеру, и вопросов бы не было, и я не пялился бы два дня в этот код и не гуглил бы всемирную помойку в поисках ответа.
JIS X 0208 -- это какой-то японский стандарт. Блекбоксёры решили этим стандартом кодировать иероглифы всякие? а почему не взяли UTF8, например? Он был разработан в 1992 г., неужели блекбоксёры не знали про него, когда делали юникодную версию блекбокса (1.6)?
-
2 Илья
Согласен. Но не совсем. К стилю нужно привыкать, а он у каждого разработчика разный в любом случае. Т.е. в теории я с вами согласен, но на практике это сомнительно. Без комментариев придется читать код полностью чтобы понять. А зачем его полностью читать, если меня интересует только интерфейс (в широком смысле)? Почему я должен тратить на это время?
Код написанный формально, хорош для понимания логики работы в конкретном месте. Но логика работы и смысл - это не одно и то же.
Вот посмортите:
Run = POINTER TO EXTENSIBLE RECORD
prev, next: Run;
len: INTEGER;
attr: Attributes
END;
LPiece = POINTER TO EXTENSIBLE RECORD (Run)
file: Files.File;
org: INTEGER
END;
Piece = POINTER TO RECORD (LPiece) END; (* u IS Piece => CHAR run *)
ViewRef = POINTER TO RECORD (Run) (* u IS ViewRef => View run *)
w, h: INTEGER;
view: Views.View (* embedded view *)
END;Как это устроено я понимаю. Но что такое LPiece и зачем оно нужно не врубаюсь. И меня дико бесит волшебный префикс "L". Что он значит?
Представьте себе что у Piece и ViewRef тоже нет комментов. Чуйствуете сколько полезной информации сразу пропадет?
-
Вот приписали бы разработчики BB что в данном месте символ кодируется методом JIS X 0208 к примеру, и вопросов бы не было, и я не пялился бы два дня в этот код и не гуглил бы всемирную помойку в поисках ответа.
JIS X 0208 -- это какой-то японский стандарт. Блекбоксёры решили этим стандартом кодировать иероглифы всякие? а почему не взяли UTF8, например? Он был разработан в 1992 г., неужели блекбоксёры не знали про него, когда делали юникодную версию блекбокса (1.6)?
Да я просто для примера этот формат привел. :) Что там в BB я так и не понял.
-
Я понимаю Вашу позицию, но позволю себе с ней не согласиться :)
Нужно искать возможность выражать мысль формально кодом.
Когда пытаешься, начинаешь быть внимательным к каждой мелочи (раньше казалось всё равно, записать так или иначе - а потом начинаешь придерживаться конкретного варианта).
Когда язык строгого стиля и не особо допускает многовариантности, то в итоге происходит некий спуск к некому единому стилю выражения мысли в коде. Когда код становится состоящим из узнаваемых "образцов" (тут во мне таки говорит методист, думающий о работе с уже наученными в едином стиле программистами :) ).
Т.е. хороший код без комментариев заставляет быть внимательным к своему смыслу.
Обычно приходится иметь дело с несколькими языками, и стили выражения там обычно разные (иногда просто идеологически несвоместимые).
Комментарии в коде могут помочь пониманию исходного кода (если эти комментарии актуальны), так почему бы это не использовать? Зачем требовать от других понимания вашего внутрифирменного стиля?
-
JIS X 0208 -- это какой-то японский стандарт. Блекбоксёры решили этим стандартом кодировать иероглифы всякие? а почему не взяли UTF8, например? Он был разработан в 1992 г., неужели блекбоксёры не знали про него, когда делали юникодную версию блекбокса (1.6)?
Да я просто для примера этот формат привел. :) Что там в BB я так и не понял.
о_О Ну всё равно остаётся вопрос -- почему они не использовали распространённую кодировку типа UTF8 или UCS-2?..
-
Но что такое LPiece и зачем оно нужно не врубаюсь. И меня дико бесит волшебный префикс "L". Что он значит?
Ну Piece -- какой-то кусок (текста, наверное)? LPiece -- вероятно "длинный кусок" )))
-
P.S. Комментарии в коде - это плохо. Должно лежать "сбоку" пояснение по всем моментам, почему, что и как решено.
Без комментариев в коде - плохо.
Комментарии в коде - плохо.
Все плохо :-)
На самом деле степень степень подробности комментов в коде сильно зависит от того, кто код читает. Одному нужно будет по строчке комментов на строчку кода + большие шапки комментов у скажем процедур и модулей (в отдельном документе это все документировать - не вариант, в таком виде читать это не возможно, ибо нужно ОДНОВРЕМЕННО читать и код и коммент), другому же почти любой комментарий будет мусором на экране, код ему понятней. Общего универсального рецепта тут на самом деле нет.
Но осмелюсь дать несколько рекомендаций которые по крайней мере не сделают код хуже:
1) Если в коде используется какой-то известный но не тривиальный алгоритм (скажем поиск пути A*), то следует это указать - коментария будет ровно 1 строчка на много строк кода, а суть он пояснит лучше чем подробные комменты на каждой строчке.
2) Если используется какая-то кодировка/формат данных - то следует её описать: если это простой формат данных и его можно описать на двух-трех строчках кода, то это следует описать прямо в комменте, если не получается, то нужно дать в комменте ссылку на описание формата (соответственно если это известный формат, то достаточно названия этого формата).
3) Спецификация модуля должна быть отделена от реализации модуля и при этом гарантированно всегда согласована с реализацией (согласование на этапе компиляции). Соответственно комментарии в спецификации соответственно должны быть достаточно высокоуровневые (что и почему), а в реализации модуля комментарии к уже конкретной реализации (как).
4) Отдельным документом, про который компилятор не знает, писать документацию к спецификации модуля смысла не имеет - будут регулярные рассогласования между тем что есть на самом деле, и тем что будет в нем описано. Да и читабельность подобных документов обычно ниже чем читабельность комментированной спецификации модуля (исходника-спецификации).
5) А вот что нужно всегда делать отдельным коротким документом - так это документацию на общую архитектуру системы (конгломерат модулей), эдакий путеводитель по всему этому барахлу, общая идеалогия построения системы.
Кроме того, при разработке ограниченным кругом не ставится задача облегчить любому из N заинтересованных посторонних лиц внесения интересующего его изменения с минимальными трудозатратами.
В стиле "захотел поменять - полез в нужное место - не понимая всего, понял только его - поменял - ура".
Предполагается, что общая модель системы загружена в голову.
Когда мне понадобился Kernel, я за пару дней сложил в голове такую модель...
А вот это в корне не правильный подход.
-
Я не оправдываю стиль написания кода ББ-шных разработчиков. Они, видимо, попали в частый соблазн - когда хорошо спроектируешь интерфейсы, то думаешь, что "а похрен, что там и как внутри у этого кирпича будет". Не говоря про то, что идеи, бродившие в начале 90-х, были полностью "зациклены" на двоичной компонентности, при сокрытии исходного кода.
Что есть в корне не верно. Открытый компонент можно сделать на порядок проще, просто за счет того, что гибкость его обеспечивается не наворачиванием фич на все случаи жизни, а самой открытостью исходника. Кроме того, я пока не видел компонента, интерфейсы/абстракции которого не протекали бы. Ибо создатель никогда не знает в каких именно условиях это дело будут применять.
Понять что именно и как именно работает в компоненте, отладить его, намного проще когда есть исходники. Помню как сильно, в свое время, мне помогло то, что VCL поставлялся в исходниках. Компонентина поставляемая в бинарниках с любой документацией всегда проигрывает компоненте с открытыми исходниками (при прочих равных).
Я сам стремлюсь писать ясный и хорошо декомпонированный код, но обычно этого достигаю "расслаиванием" функционала по многим объектам-кубикам. Т.е. то, что тут уложено в один модуль TextModels, я бы расслоил слоя на три минимум.
Что ухудшило бы, возможно, его читабельность :-)
Как только расслаиваем, сразу появляется пачка проблем:
1) у нас появляется туча связей которые нужно выявить (тот кто смотрит в код первый раз предполагает что каждый может быть связан с каждым, ему нужно провести большую работу чтобы вычленить группы модулей которые сильнее связаны друг с другом нежели со всеми остальными).
2) возникает проблема правильного именования этих слоев (чтобы каждый понял что к чему).
3) Там где у нас раньше было 3 модуля, теперь у нас 15ть. Часто так банально не удобно работать.
НО: я таки однозначно придерживаюсь принципа - "найди способ выразить мысль ясно напрямую кодом без комментариев".
А не выйдет. То есть выйдет конечно, но только с теми читателями кода, которые на той же волне что и ты. Как только у человека читающего восприятие чуть начинает отличаться от человека пишущего, так все, мысль кодом без комментов не выражается, качество восприятия становится сильно хуже. Причем таковым человеком читающий может оказаться тот, кто был лет 5 назад человеком пишущим этот код.
Собственно комменты нужны для того, чтобы настроить читающего на нужную волну. Одна строчка комментария может помочь посмотреть на код под правильным углом и сэкономит часы и дни времени.
-
Смысл -128 не разъясню с лёту.
А что тут разъяснять? :) Чем так мучаться, лучше уж ввести полноценный BYTE с областью значений от 0 до 255. Страхи, что после этого язык станет платформозависимым, считаю не оправданными. Понятие "байт" давно уже мигрировало во многие прикладные предметные области.
-
А не выйдет. То есть выйдет конечно, но только с теми читателями кода, которые на той же волне что и ты. Как только у человека читающего восприятие чуть начинает отличаться от человека пишущего, так все, мысль кодом без комментов не выражается, качество восприятия становится сильно хуже. Причем таковым человеком читающий может оказаться тот, кто был лет 5 назад человеком пишущим этот код.
+1000
-
Когда язык строгого стиля и не особо допускает многовариантности, то в итоге происходит некий спуск к некому единому стилю выражения мысли в коде. Когда код становится состоящим из узнаваемых "образцов" (тут во мне таки говорит методист, думающий о работе с уже наученными в едином стиле программистами :) ).
Так не бывает. Ну, то есть ты и пришел к единому стилю в коде (то есть твой код пишется в том же стиле что и твой код), ну, в крайнем случае я могу себе представить небольшой коллектив (ну максимум человек 5) у которых стиль единый стал из за долгой совместной работы.
Но вот чтобы стиль выражения мысли в коде стал единым для все пишущих на данном языке... Не бывает. См. хотя бы сколько нагенерили способов получить беззнаковое значение байта :-)
Т.е. хороший код без комментариев заставляет быть внимательным к своему смыслу.
Только вот чужой код без комментариев хорошим не бывает (особенно если его много, а времени чтобы разобраться в нем наоборот, мало). :-)
-
По поводу комментариев хочу поделиться своими наблюдениями.
Когда я разбираю чужой код, то со всей утомительной подробностью вижу, ЧТО именно он делает. А вот вопрос ЗАЧЕМ часто остаётся открытым. Перед функционально единым куском кода неплохо бы видеть коротенький комментарий, который раскрывает стратегическую, так сказать, цель этого куска кода.
Ну, и классика: "однострочный комментарий должен дополнять код, а не дублировать его". Ну, это и так понятно :)
-
о_О Ну всё равно остаётся вопрос -- почему они не использовали распространённую кодировку типа UTF8 или UCS-2?..
У меня сложилось впечатление, что они просто использовали методу которая раньше юзалась для других целей, и случайно оказалась подходящей для кодирования юникода.
-
о_О Ну всё равно остаётся вопрос -- почему они не использовали распространённую кодировку типа UTF8 или UCS-2?..
У меня сложилось впечатление, что они просто использовали методу которая раньше юзалась для других целей, и случайно оказалась подходящей для кодирования юникода.
А ты уверен что там именно юникод?
-
Ну, и классика: "однострочный комментарий должен дополнять код, а не дублировать его". Ну, это и так понятно :)
Да это вообще к любому комменту относится :-) Кому нужен МНОГОСТРОЧНЫЙ комментарий дублирующий код?
-
Согласен. Многострочных комментариев я вообще стараюсь избегать. Ибо "вода" это :-)
-
Вообще прикольная логика:
1. Берем юникодный текст
2. Символы < 256 кидаем в Piece. По байту на символ.
3. Символы >= 256 перекодируем. Те же 2 байта... но другие.... И кидаем в LPiece.
При чтении все наоборот.
1. Читаем Piece и LPiece
2. Piece берем как есть. Только байты толкаем в CHAR'ы
3. LPiece декодируем и тоже толкаем в CHAR'ы
4. Собираем все это в единый текст
Может я чего не понял или пропустил, но смысл этого шаманства от меня ускользает.
Т.е. тут получается не альтернативная кодировка, а просто бесполезная трата процессорного времени.
-
Т.е. тут получается не альтернативная кодировка, а просто бесполезная трата процессорного времени.
Экономия на байтах? Собственно как и сам по себе двоичных формат документов.
-
Типа того. Только непонятно зачем они эти два байта кодируют/декодируют.
-
Вообще прикольная логика:
1. Берем юникодный текст
2. Символы < 256 кидаем в Piece. По байту на символ.
3. Символы >= 256 перекодируем. Те же 2 байта... но другие.... И кидаем в LPiece.
Стоп. Я как они тут разрешают неоднозначность которая возникает? Ведь тогда последовательность двух писов может быть неотличима от одного LPiece. Или Piece это таки не один байт, а больше и имеет какой-то заголовок?
-
Ну там вроде пишется отдельно инфа о том где какой пис начинается/кончается.
Там же еще атрибуты текста пишутся и прочая хрень. Заголовок конечно есть.
-
Ну там вроде пишется отдельно инфа о том где какой пис начинается/кончается.
Там же еще атрибуты текста пишутся и прочая хрень. Заголовок конечно есть.
С точки зрения текста - это все дикий оверкилл. Но такой механизм оправдан может быть, если там на ряду с этими писами еще какие-нибудь там вьюшки можно вставлять и прочие картинки/не текст.
-
Ну вьюшки конечно можно. Это ж составные документы.
ViewRef = POINTER TO RECORD (Run) (* u IS ViewRef => View run *)
w, h: INTEGER;
view: Views.View (* embedded view *)
END;
-
ну можно покурить доки на подсистему TEXT оригинального оберона, про кодировки там нема, а вот структура должна подробно описана
-
Или Piece это таки не один байт, а больше и имеет какой-то заголовок?
Это цепочка байт произвольной длины.
-
ну можно покурить доки на подсистему TEXT оригинального оберона, про кодировки там нема, а вот структура должна подробно описана
С пониманием структуры проблем нет. Есть проблема с пониманием того, что насвистоперделили разработчики BB. Т.е. та часть текстовой подсистемы которой нет в оригинальном Обероне.
У самого Вирта то все просто и элегантно. И с документацией проблем нет... :D
-
Как это устроено я понимаю. Но что такое LPiece и зачем оно нужно не врубаюсь. И меня дико бесит волшебный префикс "L". Что он значит?
Представьте себе что у Piece и ViewRef тоже нет комментов. Чуйствуете сколько полезной информации сразу пропадет?
Ну а если бы модуль был в три раза меньше, поделён на несколько модулей - и интерфейс каждого был бы специфицирован? Реализацию уже было бы совсем легко обозреть и загрузить в свой котёл. :)
Плюс некоторый небольшой текст мог бы быть - пояснение к реализации. Что выбрана такая-то кодировка. Какие структуры данных и роль каждого типа.
-
Но осмелюсь дать несколько рекомендаций которые по крайней мере не сделают код хуже:
В целом согласен.
Только замусоривать исходник ради того, чтобы "знал компилятор", считаю не лучшим вариантом. Пусть будет соответствие, которое знает IDE.
А вот это в корне не правильный подход.
А я выше написал, что его не оправдываю.
Но в свете "мечт" об исключительно бинарной компонентности, при разработке с закрытыми исходниками - ну и при сжатых сроках - такой подход БЫЛ понятен. Малой команде он не вредит, ну а после открытия исходников - кто ж обещал, что они будут ориентированы на массовые изменения :)
-
Смысл -128 не разъясню с лёту.
А что тут разъяснять? :) Чем так мучаться, лучше уж ввести полноценный BYTE с областью значений от 0 до 255. Страхи, что после этого язык станет платформозависимым, считаю не оправданными. Понятие "байт" давно уже мигрировало во многие прикладные предметные области.
Это не связано с беззнаковым байтом.
DIV/MOD-ам похрену на знаковость, битово одно и то же за счёт дополнительного кодирования получается.
-
Я не оправдываю стиль написания кода ББ-шных разработчиков. Они, видимо, попали в частый соблазн - когда хорошо спроектируешь интерфейсы, то думаешь, что "а похрен, что там и как внутри у этого кирпича будет". Не говоря про то, что идеи, бродившие в начале 90-х, были полностью "зациклены" на двоичной компонентности, при сокрытии исходного кода.
Что есть в корне не верно. Открытый компонент можно сделать на порядок проще, просто за счет того, что гибкость его обеспечивается не наворачиванием фич на все случаи жизни, а самой открытостью исходника. Кроме того, я пока не видел компонента, интерфейсы/абстракции которого не протекали бы. Ибо создатель никогда не знает в каких именно условиях это дело будут применять.
Понять что именно и как именно работает в компоненте, отладить его, намного проще когда есть исходники. Помню как сильно, в свое время, мне помогло то, что VCL поставлялся в исходниках. Компонентина поставляемая в бинарниках с любой документацией всегда проигрывает компоненте с открытыми исходниками (при прочих равных).
Согласен.
Работать надо так, как будто исходники read-only, но само их наличие очень полезно.
-
А я выше написал, что его не оправдываю.
Но в свете "мечт" об исключительно бинарной компонентности, при разработке с закрытыми исходниками - ну и при сжатых сроках - такой подход БЫЛ понятен. Малой команде он не вредит, ну а после открытия исходников - кто ж обещал, что они будут ориентированы на массовые изменения :)
ну , а если так , то ВСЕ ваши пропихоны... насчет совершенства кода и "профессионального" подхода... Виртодуев .. что в коровнике, что за бугром - полное.. бла бла...
-
Так не бывает. Ну, то есть ты и пришел к единому стилю в коде (то есть твой код пишется в том же стиле что и твой код), ну, в крайнем случае я могу себе представить небольшой коллектив (ну максимум человек 5) у которых стиль единый стал из за долгой совместной работы.
Но вот чтобы стиль выражения мысли в коде стал единым для все пишущих на данном языке... Не бывает. См. хотя бы сколько нагенерили способов получить беззнаковое значение байта :-)
Не единым, но приближённым - это вполне возможно.
У компактных языков "авторского характера" обычно вырабатывается общее поле идиом и т.п.
В русскоязычном сообществе КП просто этого поля пока особо нет, т.к. мало книг на русском именно про реальную работу на КП.
P.S. Вообще, я придерживаюсь принципа, что открытые исходники -это хорошо, но всё равно, кроме авторов, другим особо нехрен менять компонент. За конкретный модуль - конкретная персональная ответственность. Проекты, где стадо кодеров правит груду исходников - нах, нах...
-
ну , а если так , то ВСЕ ваши пропихоны... насчет совершенства кода и "профессионального" подхода... Виртодуев .. что в коровнике, что за бугром - полное.. бла бла...
Нет.
Удачно построить архитектуру, разбить на модули, быстро реализовать малыми силами эти модули, получить при этом отличную надёжность и долгую жизнь - чем это не положительный опыт?
При той постановке задачи, в тех условиях, в которых была Оминковская команда - это разумный подход, который можно рекомендовать в ряде случаев.
Т.е.: сделать архитектурный и интерфейсный каркас такой, чтобы реализацию можно было быстро и без ущерба для будущего захардкодить.
Я добавил бы в этот подход больше декомпозиции - и всё ок.
-
ну , а если так , то ВСЕ ваши пропихоны... насчет совершенства кода и "профессионального" подхода... Виртодуев .. что в коровнике, что за бугром - полное.. бла бла...
Нет.
Удачно построить архитектуру, разбить на модули, быстро реализовать малыми силами эти модули, получить при этом отличную надёжность и долгую жизнь - чем это не положительный опыт?
При той постановке задачи, в тех условиях, в которых была Оминковская команда - это разумный подход, который можно рекомендовать в ряде случаев.
Т.е.: сделать архитектурный и интерфейсный каркас такой, чтобы реализацию можно было быстро и без ущерба для будущего захардкодить.
Я добавил бы в этот подход больше декомпозиции - и всё ок.
ДА (Илья, прочитайте внимательно, про то что говорю я - там всего лишь высказывание на одну строчку) -
я говорил не про положительный опыт (им вполне может кодирование "Привет Мир"), а про качество (профессионализм в некоторой степени ) разработчиков и генерируемого кода, а так же получившегося приложения... А насчет команды .. и сроков.. так эта хрень делалась в течении 5-7 лет - срок не маленький
-
Ещё раз: я смело могу рекомендовать их подход как работоспособный, результативный и дающий отличный результат. Это и есть признак профессионализма, а не соответствие каким-то представлениям.
Наличие "побочных эффектов" типа того, что после открытия исходников не всё там "вкуривается" с лёту - это другой вопрос.
Можно ли сделать лучше - конечно, можно.
Можно взять их опыт и "закрыть" их слабые места - и будет вообще убойная сила :)
-
Ещё раз: я смело могу рекомендовать их подход как работоспособный, результативный и дающий отличный результат.
Наличие "побочных эффектов" типа того, что после открытия исходников не всё там "вкуривается" с лёту - это другой вопрос.
Можно ли сделать лучше - конечно, можно.
Можно взять их опыт и "закрыть" их слабые места - и будет вообще убойная сила :)
;D это точно "отличный" результат мы видим... за 5-7 лет невразумительное... работающее недоразумение..., только , лично я, могу порекомендовать его (в том виде каком оно есть) лишь врагу.. интересно, а кому его могут порекомендовать другие форумчане?
-
Ещё раз: я смело могу рекомендовать их подход как работоспособный, результативный и дающий отличный результат. Это и есть признак профессионализма, а не соответствие каким-то представлениям.
ИМХО отлично/профессионально у них только то, что слизано с оригинального оберона и ETH версии ;)
Т.е. это не их заслуга.
-
P.S. Вообще, я придерживаюсь принципа, что открытые исходники -это хорошо, но всё равно, кроме авторов, другим особо нехрен менять компонент. За конкретный модуль - конкретная персональная ответственность. Проекты, где стадо кодеров правит груду исходников - нах, нах...
То есть если автор забросит проект (как это фактически случилось с Блекбоксом), то пользователям этого проекта остаётся лишь переходить на другой проект, живой?
-
;D это точно "отличный" результат мы видим... за 5-7 лет невразумительное... работающее недоразумение..., только , лично я, могу порекомендовать его (в том виде каком оно есть) лишь врагу.. интересно, а кому его могут порекомендовать другие форумчане?
"В том виде, в каком оно есть" оно является повседневной "средой обитания" для многих, кто мечтает послать нахрен мейнстрим. Было б время для таких вещей, как компонент POP3/SMTP - и почту бы в ББ получал. За..ла нерасширяемость, непрограммируемость почтовиков.
Вы просто приписываете мне мнение, что "так можно создавать продукты, соответствующие всем общепринятым требованиям".
А моё мнение заключается в том, что это подход, как можно послать нах "обещпринятые требования", быстро получить работающее и развиваемое решение, ни от чего не зависящее.
Про 5-7 лет - это небольшой срок для продукта, который делается между "кормёжными" проектами, выращивается в несколько итераций и т.п.
Другим за такой срок только и удаётся, что сделать "ещё один редактор" или "ещё один органайзер", имеющий "товарный вида".
Здесь же была построена автономная "среда обитания".
-
То есть если автор забросит проект (как это фактически случилось с Блекбоксом), то пользователям этого проекта остаётся лишь переходить на другой проект, живой?
Пользователям-"потребителям" - может быть.
Если же подход долгосрочный, то такой пользователь наверняка уже инвестировал своё время в то, чтобы понимать, как это внутри устроено.
Итить же, Вы всерьёз думаете, что разобраться в коде на модульном строгом языке сложнее, чем в каком-нибудь наСиХреначенном OpenSSL? (вспоминаю эту хрень, потому что замучила одно время багами, пока не перешёл на другую библиотеку). Или в ядре Линукса?
Вообще, разобраться не так сложно с любым кодом на хорошем языке, если авторы - "нормальные", в том смысле, что не принимают необоснованных, неграмотных (для конкретной ситуации) решений.
-
Нда - два выше идущих - ответа Ильи, из них следует
Что ББ -
1. "для многих, кто мечтает послать нахрен мейнстрим!"
2. его следует послать нах - поскольку там содержится фактическое согласие с высказыванием Geniepro...
Если это так, Илья - я копипасчу эти выводы в соответствующую ветку.
-
Здесь же была построена автономная "среда обитания".
Хочу уточнить. "Автономная" в каком смысле ?
-
Народ, не обостряйтесь, полнолуние только через неделю :-)
-
Народ, не обостряйтесь, полнолуние только через неделю :-)
а конец света, сегодня ;)
-
Здесь же была построена автономная "среда обитания".
Хочу уточнить. "Автономная" в каком смысле ?
в прямом... есть ЯП, есть Биде, есть самодостаточное автономно существующее сообщество (коровник) с инфраструктурой и разделением ролей - усе в серьез...
-
Итить же, Вы всерьёз думаете, что разобраться в коде на модульном строгом языке сложнее, чем в каком-нибудь наСиХреначенном OpenSSL? (вспоминаю эту хрень, потому что замучила одно время багами, пока не перешёл на другую библиотеку).
У меня ощущение складывается, что ты OpenSSL пытался использовать под виндой.
-
;D это точно "отличный" результат мы видим... за 5-7 лет невразумительное... работающее недоразумение..., только , лично я, могу порекомендовать его (в том виде каком оно есть) лишь врагу.. интересно, а кому его могут порекомендовать другие форумчане?
"В том виде, в каком оно есть" оно является повседневной "средой обитания" для многих, кто мечтает послать нахрен мейнстрим. Было б время для таких вещей, как компонент POP3/SMTP - и почту бы в ББ получал. За..ла нерасширяемость, непрограммируемость почтовиков.
Гм. Мне сложно понять твои проблемы, потому как я уже несколько лет как почтовиками не пользуюсь вообще. Но в плане расширябельности... Тот же thunderbird вроде как вполне во все стороны расширяем аддонами, также как и FF. Так что не вижу принципиальных проблем (кроме той, что они пишутся таки на js и это не ББ, то есть во всю эту фигню вникать надо, и чтобы вникнуть туда столь же хорошо как в ББ, и чтобы там чувствовать себя столь же комфортно, нужно потратить не меньше времени чем ковыряние в ББ - то есть лет эдак несколько :-) ).
PS. SMTP/POP3 же достаточно простая штука. У нас вот вчерашний студент это вполне осилил реализовать.
-
Простая сама по себе, но вкупе с получением разного контента и проч...
У меня программист год делал полную реализацию "почтовой очереди" для CRM-системы на PHP (над XQuery и Sedna). Порядка 2 месяцев ушло.
2 месяца тоже найти надо, ежли без финансирования.
По поводу программируемости на других языках...
ну на кой ляд расширять Тундру, если как редактор документов и система документооборота она всё равно не сможет работать. Документность ББ позволяет плясать от него как от базиса для любого делового контента (если не рюшечки для посторонних, а себе для реальной работы с контентом).
-
2Dizer:
Удивительно, что у Вас в голове не помещается простая вещь, при том, что есть аналогии.
Возьмите, например, EMacs - с его замахом точно так же быть "расширяемой средой обитания".
Представьте, что в нём вместо достаточно своеобразного ЯП (LISP-а) вдруг "сделался" такой язык, как Оберон.
Проведите аналогии с ББ.
Даже если Вы не поддерживаете такие идеи, Вам придётся признать, что такой подход существует, а не нами выдуман тут из пальца.
-
Простая сама по себе, но вкупе с получением разного контента и проч...
У меня программист год делал полную реализацию "почтовой очереди" для CRM-системы на PHP (над XQuery и Sedna). Порядка 2 месяцев ушло.
2 месяца тоже найти надо, ежли без финансирования.
По поводу программируемости на других языках...
ну на кой ляд расширять Тундру, если как редактор документов и система документооборота она всё равно не сможет работать. Документность ББ позволяет плясать от него как от базиса для любого делового контента (если не рюшечки для посторонних, а себе для реальной работы с контентом).
Кстати, я бы на твоем месте просто взял бы и написал гейт для ББ на каком-нибудь языке. Ну, то есть на какой-нибудь жабе написал бы smtp/pop3 гейт (либы для smtp/pop3 для жабы есть и они вменяемого качества) - с одной стороны у него smtp/pop3, а с другой твой сильно упрощенный и заточенный под твои задачи протокол, за который уже цепляется ББ и спокойно это дело обрабатывает/принимает/отправляет почту. Пожалуй, я бы сделал этот протокол на базе json'a.
-
2Dizer:
Удивительно, что у Вас в голове не помещается простая вещь, при том, что есть аналогии.
Возьмите, например, EMacs - с его замахом точно так же быть "расширяемой средой обитания".
Представьте, что в нём вместо достаточно своеобразного ЯП (LISP-а) вдруг "сделался" такой язык, как Оберон.
Проведите аналогии с ББ.
Даже если Вы не поддерживаете такие идеи, Вам придётся признать, что такой подход существует, а не нами выдуман тут из пальца.
ПОЧЕМУ!!!! -как раз очень даже хорошо помещается.. я же Madzi - говорил ровно про это...
-
Смысл -128 не разъясню с лёту.
А что тут разъяснять? :) Чем так мучаться, лучше уж ввести полноценный BYTE с областью значений от 0 до 255. Страхи, что после этого язык станет платформозависимым, считаю не оправданными. Понятие "байт" давно уже мигрировало во многие прикладные предметные области.
Это не связано с беззнаковым байтом.
DIV/MOD-ам похрену на знаковость, битово одно и то же за счёт дополнительного кодирования получается.
Разве?
Вот обсуждаемый код:
PROCEDURE (wr: StdWriter) WriteChar (ch: CHAR);
VAR ... fw: Files.Writer;
BEGIN
...
fw.WriteByte(SHORT(SHORT(ORD(ch))));
fw.WriteByte(SHORT(SHORT(ORD(ch) DIV 256 - 128))); ...
END WriteChar;
Операция DIV возвращает значение от 0 до 255 типа INTEGER. Первый SHORT (правый) преобразует результат операции DIV к типу SHORTINT, второй - к типу BYTE. Если результат операции DIV оказался больше 127, то во время выполнения второго SHORT произойдёт ошибка. Для этого и понадобилось отнимать 128.
-
А, Игорь, Вы правы. Я что-то забыл, что ORD даёт беззнаковый код, а не просто побитово копирует CHAR в число. Тогда вся загадка разгадана - стыжусь, что сразу не допёр :)
-
... ORD даёт беззнаковый код ...
Это как?
-
Игорь, спасибо за разъяснение. Теперь изврат стал кристально понятен.
Files умеет писать только байты, и соответственно двухбайтовый CHAR приходится "резать". А формула "дикая" по причине знаковости оберонобайта
ps Неужели в CP нельзя это сделать более эмм....... очевидным способом?
-
ps Неужели в CP нельзя это сделать более эмм....... очевидным способом?
Скорее всего более очевидный способ будет через SYSTEM
-
Однако Игорь кажись нас обманул...
-
Без проблем:
ch := CHR(-32768);
b1 := SHORT(SHORT(ORD(ch)));
b2 := SHORT(SHORT(ORD(ch) DIV 256));
-
Прикольно что без этих -128 формула сразу становится понятной :D
-
Сдается мне, товарищи, что разработчики BB просто слегка лохонулись с этим -128. А мы тут голову ломаем.
В других местах просто тупо сдвиг используется, то бишь DIV 256
-
Сдается мне, товарищи, что разработчики BB просто слегка лохонулись с этим -128. А мы тут голову ломаем.
В других местах просто тупо сдвиг используется, то бишь DIV 256
Мне эти разборы ББшных исходников напоминают школьный урок литературы во время разбора очередного произведения. Там всегда было два фундаментальных вопроса на которые непременно надо было ответить:
1) О чем думал автор когда писал эти строки?
2) Что он этим хотел сказать?
-
Сдается мне, товарищи, что разработчики BB просто слегка лохонулись с этим -128. А мы тут голову ломаем.
В других местах просто тупо сдвиг используется, то бишь DIV 256
Мне эти разборы ББшных исходников напоминают школьный урок литературы во время разбора очередного произведения. Там всегда было два фундаментальных вопроса на которые непременно надо было ответить:
1) О чем думал автор когда писал эти строки?
2) Что он этим хотел сказать?
в таком случае я иду дальше.. меня больше волнует вопрос - нахрена это делать(разбирать это произведение)?
-
в таком случае я иду дальше.. меня больше волнует вопрос - нахрена это делать(разбирать это произведение)?
Тык just for fun же :D
У меня лично с детства непреодолимая тяга "разобрать", "заглянуть внутрь" и "понять".
-
типа зуда упомянутого Kemet\ом?
-
fw.WriteByte(SHORT(SHORT(ORD(ch) DIV 256 - 128)));
Операция DIV возвращает значение от 0 до 255 типа INTEGER.
Вот же блин... :-[
По смыслу здесь должно стоять MOD, а не DIV, вот я MOD и вижу (не веря своим глазам). :)
Прошу извинить. Значение от 0 до 255 возвращает конечно же операция x MOD 256.
Выражение ORD(ch) DIV 256 всегда гарантированно возвращает значение 0 при любом ch.
Это ошибка в коде? ;)
-
fw.WriteByte(SHORT(SHORT(ORD(ch) DIV 256 - 128)));
Операция DIV возвращает значение от 0 до 255 типа INTEGER.
Вот же блин... :-[
По смыслу здесь должно стоять MOD, а не DIV, вот я MOD и вижу (не веря своим глазам). :)
Прошу извинить. Значение от 0 до 255 возвращает конечно же операция x MOD 256.
Выражение ORD(ch) DIV 256 всегда гарантированно возвращает значение 0 при любом ch.
Это ошибка в коде? ;)
У них же char 16-битный, так что может быть больше 256...
-
У них же char 16-битный, так что может быть больше 256...
Они изменили язык? Нового репорта я пока ещё не видел (но правда и не сильно искал).
На всякий случай, цитата из репорта 2001 года:
2. CHAR символы расширенного набора ASCII (0X .. 0FFX)
-
У меня в BB 1.6:
2. SHORTCHAR литеры набора Latin1 (0X .. 0FFX)
3. CHAR литеры набора Unicode (0X .. 0FFFFX)
ps DIV 256 - это замена SHR 8 в данном случае
-
На всякий случай, цитата из репорта 2001 года:
2. CHAR символы расширенного набора ASCII (0X .. 0FFX)
Эх, не правильная цитата. По ошибке не тот документ открыл. :-[
ilovb прав. И КП с 2001 года не менялся (по крайней мере в этой части).
Вообще, я сейчас использую в основном Оберон-2 (даже не 7 или 11). Какие-то тонкости КП уже начал подзабывать. :-\
-
Однако тут какое-то хитрожопое кодирование целых чисел.
Опять же в компайлере юзаются:
(* utf8 strings *)
PROCEDURE PutUtf8* (VAR str: ARRAY OF SHORTCHAR; val: INTEGER; VAR idx: INTEGER);
BEGIN
ASSERT((val >= 0) & (val < 65536));
IF val < 128 THEN
str[idx] := SHORT(CHR(val)); INC(idx)
ELSIF val < 2048 THEN
str[idx] := SHORT(CHR(val DIV 64 + 192)); INC(idx);
str[idx] := SHORT(CHR(val MOD 64 + 128)); INC(idx)
ELSE
str[idx] := SHORT(CHR(val DIV 4096 + 224)); INC(idx);
str[idx] := SHORT(CHR(val DIV 64 MOD 64 + 128)); INC(idx);
str[idx] := SHORT(CHR(val MOD 64 + 128)); INC(idx)
END
END PutUtf8;
PROCEDURE GetUtf8* (VAR str: ARRAY OF SHORTCHAR; VAR val, idx: INTEGER);
VAR ch: SHORTCHAR;
BEGIN
ch := str[idx]; INC(idx);
IF ch < 80X THEN
val := ORD(ch)
ELSIF ch < 0E0X THEN
val := ORD(ch) - 192;
ch := str[idx]; INC(idx); val := val * 64 + ORD(ch) - 128
ELSE
val := ORD(ch) - 224;
ch := str[idx]; INC(idx); val := val * 64 + ORD(ch) - 128;
ch := str[idx]; INC(idx); val := val * 64 + ORD(ch) - 128
END
END GetUtf8;
Ничего не понимаю...
Может быть уже всё понятно, но вот эта ссылка очень наглядно поясняет код
http://ru.wikipedia.org/wiki/UTF-8 (смотреть цветные картинки там, где Принцип кодирования)
-
С пониманием этого кода проблем не было :)
-
С пониманием этого кода проблем не было :)
Значит я не въехал в фразу "ничего не понимаю" :)
Тогда , наверное, опять не к месту, по поводу 128.
Как я понял двухбайтные чары маркируются 1 в самом старшем разряде вот и вычитание/прибавление 128.
Единственная засада в том, что тогда надо исключить использование уникодов из диапазона 8000-8FFF
-
В данной теме и в следующей:
http://oberspace.dyndns.org/index.php/topic,408.0.html
уже во всем разобрались.
-128 позволяет избавиться от переполнения.
-
В данной теме и в следующей:
http://oberspace.dyndns.org/index.php/topic,408.0.html
уже во всем разобрались.
-128 позволяет избавиться от переполнения.
Пока остаюсь при своём мнении без переполнения :)
-
Переполнение возникает, при такой картине:
0000 0000 - 0000 0000 - 0000 0000 - 1000 0000
Если взять только один младший байт, то он равен -128
Но значение INTEGER = 128
Следовательно будет переполнение, т.к. SHORT делает индентичное преобразование. Т.е. INTEGER должен быть равен по значению BYTE.
Если контроль переполнения выключен, то проблемы нет, и INTEGER просто обрезается до BYTE (128 --> -128)
В противном случае вылетает исключение.
Переполнение возникает на диапазоне от:
0000 0000 - 0000 0000 - 0000 0000 - 1000 0000 = 128 (-128)
до:
0000 0000 - 0000 0000 - 0000 0000 - 1111 1111 = 255 (-1)
Не сложно догадаться, что достаточно вычесть 128 чтобы попасть в диапазон BYTE:
128 - 128 = 0
255 - 128 = 127
Значение смещается, но его можно восстановить прибавлением этих 128 при чтении.
-
Как я понял двухбайтные чары маркируются 1 в самом старшем разряде вот и вычитание/прибавление 128.
Единственная засада в том, что тогда надо исключить использование уникодов из диапазона 8000-8FFF
Как я не правильно понял :(
Но начсчёт переполнения или "переполнения" надо ещё на досуге почитать ленгвидж репорт и подумать над кодом.
Но явно этот код помогает решить проблемы в другом месте (при чтении?) :
fw.WriteByte(SHORT(SHORT(ORD(ch))));
fw.WriteByte(SHORT(SHORT(ORD(ch) DIV 256 - 128)));
Нет же проблем "переполнения" в первой строке
-
Проверка переполнения отключена по дефолту.
Включить можно так:
^Q DevCompiler.CompileThis Test+
ps Про первую строку Игорь уже говорил что они лохонулись :)
-
Проверка переполнения отключена по дефолту.
Включить можно так:
^Q DevCompiler.CompileThis Test+
В моём "интерпретаторе" оберона этого нет :)
-
Oxford Oberon-2 ?
-
-128 позволяет избавиться от переполнения.
Если бы задача была просто избавиться от переполнения, то логичнее было бы
fw.WriteByte(-SHORT(SHORT(256 - ORD(ch) DIV 256)));
-
Что будет если ch := CHR(32768) ?
-
Что будет если ch := CHR(32768) ?
Извиняюсь. На минус не обратил внимание.
-
Хы, век живи - век учись.
Как говорит Илья, век живи - век учись.
Как говорили Илья и Игорь, век живи - век учись ;D
-
Oxford Oberon-2 ?
Brain Oberon/CP/итд/итп :)
(Просто глазами с карандашом.)
-
А вот такая иерархия больше ни у кого недоумения не вызывает?
LPiece = POINTER TO EXTENSIBLE RECORD (Run)
file: Files.File;
org: INTEGER
END;
Piece = POINTER TO RECORD (LPiece) END; (* u IS Piece => CHAR run *)
На мой вкус, эстетичнее было бы что-то вроде
Piece = POINTER TO EXTENSIBLE RECORD (Run)
file: Files.File;
org: INTEGER
END;
SPiece = POINTER TO RECORD (Piece) END; (* SHORTCHAR run *)
LPiece = POINTER TO RECORD (Piece) END; (*CHAR run *)
-
trurl, не поверите, но я думал о том же. ;)
-
Ну всё равно остаётся вопрос -- почему они не использовали распространённую кодировку типа UTF8 или UCS-2?..
UTF8 тогда ещё не была распространённой, а вот почему не просто UCS-2?
Предполагаю, поддержка юникода добавлялась в традиционном стиле "надо уже вчера". И не забываем, что память в те годы приходилось экономить. На каком-то этапе возник вариант с 1/2-байтной кодировкой. Потом появились "куски" разных типов. Но это всё мои измышлизмы.
-
Ну всё равно остаётся вопрос -- почему они не использовали распространённую кодировку типа UTF8 или UCS-2?..
UTF8 тогда ещё не была распространённой, а вот почему не просто UCS-2?
Предполагаю, поддержка юникода добавлялась в традиционном стиле "надо уже вчера". И не забываем, что память в те годы приходилось экономить. На каком-то этапе возник вариант с 1/2-байтной кодировкой. Потом появились "куски" разных типов. Но это всё мои измышлизмы.
По моему, тогда и ucs-2 была не более распространенной чем utf8. UTF8 искаропки еще с 1996 года была например в BeOS. Это с одной стороны, а с другой, в макоси была вовсе однобайтовая кодировка. Да в виндузах (не NT, а NT все же была экзотикой) тоже однобайтовая. Активно и широко юникод вообще и UTF8 частности стал использоваться, пожалуй, где-то в начале 2000ных годов.
-
Может все проще?
Их вариант выигрывает у UCS-2 в экономии памяти. А у UTF-8 в скорости кодирования/декодирования.
А для собственного внутреннего формата пофиг на стандарты.
-
Может все проще?
Их вариант выигрывает у UCS-2 в экономии памяти. А у UTF-8 в скорости кодирования/декодирования.
А для собственного внутреннего формата пофиг на стандарты.
Кстати, такая кодировка только у BB 1.6, или у BB 1.5 тоже?
-
Вроде у BB 1.5 тоже.
-
Вроде у BB 1.5 тоже.
Проверил. Да, тот же самый код.
-
В обоих.
ББ 1.5 был в плане Framework уже юникодный. Под юникодизацией 1.6 понимается переписывание Host для вызова юникодных WinApi-фукнкций (чтобы с клавиатуры вводился юникод, и т.п.), а также компилятора для поддержки юникодных значений литерных констант. А ещё добавили метаинформацию о сигнатурах процедур (до этого были только фингерпринты от них).
-
В обоих.
ББ 1.5 был в плане Framework уже юникодный. Под юникодизацией 1.6 понимается переписывание Host для вызова юникодных WinApi-фукнкций (чтобы с клавиатуры вводился юникод, и т.п.), а также компилятора для поддержки юникодных значений литерных констант. А ещё добавили метаинформацию о сигнатурах процедур (до этого были только фингерпринты от них).
Гм. Тогда интересно когда они юникод в BB вшили.
-
В CP изначально. А в BB в 1.6 :)
ps некоторый задел уже в 1.5 был
-
В CP изначально. А в BB в 1.6 :)
ps некоторый задел уже в 1.5 был
Только вот BB не изначально на CP был :-)
-
Кстати, такая кодировка только у BB 1.6, или у BB 1.5 тоже?
И у 1.3, и даже у 1.2, которая ещё Oberon/F. Документами же надо обмениваться.
-
Что будет если ch := CHR(32768) ?
Извиняюсь. На минус не обратил внимание.
Однако минус не помог. Не работает.
-
Минус нужно до SHORT'ов ставить, иначе опять INTEGER получается.
И кроме того оно совсем не работает на ch < 256, ибо получается -256
-
Вот куски из кода и измышлизмы.
PROCEDURE (rd: StdReader) Read;
VAR ...; lc: ARRAY 2 OF BYTE;
BEGIN
...
rd.reader.ReadBytes(lc, 0, 2);
rd.char := CHR(lc[0] MOD 256 + 256 * (lc[1] + 128)); rd.view := NIL;
lc[0] MOD 256 - приведение байта к положительному целому с идентичным битовым представлением значимого байта
а вот для старшего байта почему то придуман "трюк" c 128 (для увода из отрицательных значений ) и тогда соответственно в коде ниже присутствует вычитание 128
PROCEDURE (wr: StdWriter) WriteChar (ch: CHAR);
...
fw.WriteByte(SHORT(SHORT(ORD(ch))));
fw.WriteByte(SHORT(SHORT(ORD(ch) DIV 256 - 128)));
М.б. есть ещё какие нюансы работы в исполняемом коде в двух случаях:
1. SHORT(SHORT(ORG(ch))
2. SHORT(SHORT( от арифм.выражения ORD(ch) DIV 256 )
И эти нюансы вынудили изощряться со 128 :)
-
Напомню по результатам обсуждения в соседней ветке, что в данном случае отнимать 128 вообще некошерно, так как это приводит к инвертированию старшего бита у целевого байта. ilovb указал, что сей факт можно учесть при чтении, но на мой взгляд это удар "под перекладину". Тот, кто будет читать не обязан помнить, что при это нужно подправить старший бит.
-
В лоб всё равно не читают.
Есть придуманный формат, и процедуры чтения/записи учитывающие его.
-
М.б. есть ещё какие нюансы работы в исполняемом коде в двух случаях:
1. SHORT(SHORT(ORG(ch))
2. SHORT(SHORT( от арифм.выражения ORD(ch) DIV 256 )
И эти нюансы вынудили изощряться со 128 :)
Единственный нюанс - оно не работает без вычитания 128. ;)
-
Кстати, а почему тут не используют SET'ы для манипулирования битиками?
-
М.б. есть ещё какие нюансы работы в исполняемом коде в двух случаях:
1. SHORT(SHORT(ORG(ch))
2. SHORT(SHORT( от арифм.выражения ORD(ch) DIV 256 )
И эти нюансы вынудили изощряться со 128 :)
Единственный нюанс - оно не работает без вычитания 128. ;)
Занудно поясню, что имел ввиду вопрошая.
вот имеем код SHORT(SHORT(ORD(ch))ch двухбайтный, ORD(ch) в диапазоне целых 80-FFFF
всё компилится и работает как, видимо, задумано, на выходе байт (в битах 80-FF)
или от -128 до 127 (как BYTE)
А вот код SHORT(SHORT(ORD(ch) DIV 256) может быть уже не хочет работать и взбрыкивается (нюансы кодогенерации) хотя ORD(ch) DIV 256 даёт значения от 0 до FF
И вот тут приходит на помощь волшебное 128 и значения загоняются в диапазон BYTE, хотя в первом случае этого не понадобилось.
-
на выходе байт (в битах 80-FF)
на выходе байт (в битах 00-FF)
-
facepalm...
1. SHORT(SHORT(ORG(ch))
2. SHORT(SHORT( от арифм.выражения ORD(ch) DIV 256 )
всё компилится и работает как, видимо, задумано, на выходе байт (в битах 80-FF)
Да не работают эти строчки. Ни первая, ни вторая.
ПЕРЕПОЛНЕНИЕ.
С отключенной проверкой ОБЕ РАБОТАЮТ
-
Кстати, а почему тут не используют SET'ы для манипулирования битиками?
С SET'ами наверно сложнее будет. IF'ы понадобятся...
-
Однако минус не помог. Не работает.
Угу. Я для >127 придумывал. :-\
-
По моему, тогда и ucs-2 была не более распространенной чем utf8.
Тогда ucs-2 называлась просто Unicode. :) А utf-8 была просто хитрой системой кодирования, придуманной для совместимости со старым софтом.
-
По моему, тогда и ucs-2 была не более распространенной чем utf8.
Тогда ucs-2 называлась просто Unicode. :) А utf-8 была просто хитрой системой кодирования, придуманной для совместимости со старым софтом.
Ну, это смотря какое "тогда" :-) Если с 1991 по 1995 год, то да. А вот если после 1995 года, то уже нет, ибо Unicode 2.0. В 1996 году был кстати придуман концептуальный костыль для обратной совместимости с подсевшими на ucs-2 -- зовется тот костыль UTF-16.
-
facepalm...
С такой аватаркой жест опасен для зрения :)
-
;D
-
Конечно надо согласиться с т. igorем. (лучше поздно, чем никогда :)
http://oberspace.dyndns.org/index.php/topic,408.msg11903.html#msg11903 (http://oberspace.dyndns.org/index.php/topic,408.msg11903.html#msg11903)
-
Вот в связи с этой темой любопытно стало, а чем плоха арифметика на CHAR'ах?
Почему бы не разрешить работать с ними как с uint16?
-
Хотя в этом случае придется пересматривать синтаксис конкатенации... или усложнять компилятор.
-
Только наткнулся случайно на odcread (http://"https://github.com/gertvv/odcread")
odcread - read ".odc" oberon compound documents
This is a library to read the "Oberon compound document" binary format used by the Black Box Component Builder, WinBUGS, and OpenBUGS.
A basic program is provided to convert the textual parts of these documents to plain text.
Насколько я понял, код написан на Objective C.
Пока внутрь не заглядывал.
-
Только наткнулся случайно на odcread (https://github.com/gertvv/odcread)
odcread - read ".odc" oberon compound documents
This is a library to read the "Oberon compound document" binary format used by the Black Box Component Builder, WinBUGS, and OpenBUGS.
A basic program is provided to convert the textual parts of these documents to plain text.
Насколько я понял, код написан на Objective C.
Пока внутрь не заглядывал.
Написано на чистом C++, следов Objective-C не обнаружил.
-
Написано на чистом C++, следов Objective-C не обнаружил.
Ошибся по невежеству. Виноват. :-\
-
Написано на чистом C++, следов Objective-C не обнаружил.
Ошибся по невежеству. Виноват. :-\
Но штука действительно интересная и полезная. Буду щупать.
-
Только наткнулся случайно на odcread (http://"https://github.com/gertvv/odcread")
Как-то сложно. Много классов, которые ничего ни делают. В BlackBox есть упрощённый читатель текстовых odc файлов в модуле Dialog. Он используется при чтении ресурсов. Исходный код довольно короткий:
PROCEDURE ReadStringFile (subsys: Files.Name; f: Files.File; VAR tab: StringTab);
VAR i, j, h, n, s, x, len, next, down, end: INTEGER; in, in1: Files.Reader;
ch: CHAR; b: BYTE; p, q: StringPtr;
PROCEDURE ReadInt (OUT x: INTEGER);
VAR b: BYTE;
BEGIN
in.ReadByte(b); x := b MOD 256;
in.ReadByte(b); x := x + (b MOD 256) * 100H;
in.ReadByte(b); x := x + (b MOD 256) * 10000H;
in.ReadByte(b); x := x + b * 1000000H
END ReadInt;
PROCEDURE ReadHead (OUT next, down, end: INTEGER);
VAR b, t: BYTE; n: INTEGER;
BEGIN
in.ReadByte(b);
REPEAT
in.ReadByte(t);
IF t = -14 THEN ReadInt(n)
ELSE
REPEAT in.ReadByte(b) UNTIL b = 0
END
UNTIL t # -15;
ReadInt(n);
ReadInt(next); next := next + in.Pos();
ReadInt(down); down := down + in.Pos();
ReadInt(end); end := end + in.Pos()
END ReadHead;
BEGIN
tab := NIL;
IF f # NIL THEN (* read text file *)
in := f.NewReader(NIL); in1 := f.NewReader(NIL);
IF (in # NIL) & (in1 # NIL) THEN
in.SetPos(8); ReadHead(next, down, end); (* document view *)
in.SetPos(down); ReadHead(next, down, end); (* document model *)
in.SetPos(down); ReadHead(next, down, end); (* text view *)
in.SetPos(down); ReadHead(next, down, end); (* text model *)
in.ReadByte(b); in.ReadByte(b); in.ReadByte(b); (* versions *)
in.ReadByte(b); in.ReadByte(b); in.ReadByte(b);
ReadInt(x); in1.SetPos(in.Pos() + x); (* text offset *)
next := down;
NEW(tab); tab.name := subsys$;
NEW(tab.data, f.Length());
n := 0; i := 0; s := 0; in.ReadByte(b);
WHILE b # -1 DO
IF next = in.Pos() THEN ReadHead(next, down, end); in.SetPos(end) END; (* skip attributes *)
ReadInt(len);
IF len > 0 THEN (* shortchar run *)
WHILE len > 0 DO
in1.ReadByte(b); ch := CHR(b MOD 256);
IF ch >= " " THEN
IF s = 0 THEN j := i; s := 1 END; (* start of left part *)
tab.data[j] := ch; INC(j)
ELSIF (s = 1) & (ch = TAB) THEN
tab.data[j] := 0X; INC(j);
s := 2 (* start of right part *)
ELSIF (s = 2) & (ch = CR) THEN
tab.data[j] := 0X; INC(j);
INC(n); i := j; s := 0 (* end of line *)
ELSE
s := 0 (* reset *)
END;
DEC(len)
END
ELSIF len < 0 THEN (* longchar run *)
WHILE len < 0 DO
in1.ReadByte(b); x := b MOD 256; in1.ReadByte(b); ch := CHR(x + 256 * (b + 128));
IF s = 0 THEN j := i; s := 1 END; (* start of left part *)
tab.data[j] := ch; INC(j);
INC(len, 2)
END
ELSE (* view *)
ReadInt(x); ReadInt(x); in1.ReadByte(b); (* ignore *)
END;
IF next = in.Pos() THEN ReadHead(next, down, end); in.SetPos(end) END; (* skip view data *)
in.ReadByte(b);
END;
IF n > 0 THEN
NEW(tab.key, n); NEW(tab.str, n); i := 0; j := 0;
WHILE j < n DO
tab.key[j] := SYSTEM.VAL(StringPtr, SYSTEM.ADR(tab.data[i]));
WHILE tab.data[i] >= " " DO INC(i) END;
INC(i);
tab.str[j] := SYSTEM.VAL(StringPtr, SYSTEM.ADR(tab.data[i]));
WHILE tab.data[i] >= " " DO INC(i) END;
INC(i); INC(j)
END;
(* sort keys (shellsort) *)
h := 1; REPEAT h := h*3 + 1 UNTIL h > n;
REPEAT h := h DIV 3; i := h;
WHILE i < n DO p := tab.key[i]; q := tab.str[i]; j := i;
WHILE (j >= h) & (tab.key[j-h]^ > p^) DO
tab.key[j] := tab.key[j-h]; tab.str[j] := tab.str[j-h]; j := j-h
END;
tab.key[j] := p; tab.str[j] := q; INC(i)
END
UNTIL h = 1
END
END
END
END ReadStringFile;
Помимо чтения odc там ешё чтение и сортировка строковых ресурсов.