Oberon space

General Category => Общий раздел => Тема начата: vlad от Октябрь 27, 2013, 06:36:14 am

Название: Раскручиваем компилятор O7
Отправлено: vlad от Октябрь 27, 2013, 06:36:14 am
Итак, свершилось: кусочек компилятора был переписан на обероне и скомпилирован самим компилятором. Надо сказать, что в этом что-то есть :) Типа непосредственного прикосновения к вечной проблеме курицы и яйца.

Код приведен в самом конце. Текущие впечатления от кодирования:
- В отсутствие методов запись "Stream.pos(stream)" конечно многословнее и воспринимается хуже, чем "stream.pos()".
- Дублирование в конце имени процедуры - жестокое и беспощадное. Программер должен страдать. Особенно если захочет переименовать. Смысла - 0. Если уж боремся за читабельность, то лучше запретить процедуры длиннее 10 строк...
- Точка с запятой после RETURN. Точнее требование ее отсутствия. Вот уж действительно мелочь, но вот чисто с эргономической точки зрения напрягает страшно. Удобство принесенное в жертву формализму.
- Тяжелый синтаксис. Даже если постараться не смотреть на КАПС. Т.е. я конечно в курсе незабвенного "синтаксического оверхеда", но вот в случае тривиальных процедур - обероновский код выглядит если не многословным, то многобуквенным. И даже "int" vs "INTEGER" начинает напрягать. Т.е. пока пишешь "int" в каком-нибудь С++ это кажется и не таким важным. Но вот пописав "INTGER" начинаешь ценить более короткий вариант.
MODULE Stream;
IMPORT JsString;

TYPE
    Type = POINTER TO RECORD
        s: JsString.Type;
        pos: INTEGER
    END;

    ReaderProc = PROCEDURE(c: CHAR): BOOLEAN;

PROCEDURE make*(text: JsString.Type): Type;
VAR result: Type;
BEGIN
    NEW(result);
    result.s := text;
    RETURN result
END make;

PROCEDURE eof*(self: Type): BOOLEAN;
    RETURN self.pos = JsString.len(self.s)
END eof;

PROCEDURE pos*(self: Type): INTEGER;
    RETURN self.pos
END pos;

PROCEDURE setPos*(self: Type; pos: INTEGER);
BEGIN
    ASSERT(pos <= JsString.len(self.s));
    self.pos := pos
END setPos;

PROCEDURE next*(self: Type; n: INTEGER);
BEGIN
    ASSERT(self.pos + n <= JsString.len(self.s));
    self.pos := self.pos + n;
END next;

PROCEDURE peekChar*(self: Type): CHAR;
BEGIN
    ASSERT(~eof(self));
    RETURN JsString.at(self.s, self.pos)
END peekChar;

PROCEDURE getChar*(self: Type): CHAR;
VAR result: CHAR;
BEGIN
    ASSERT(~eof(self));
    result := JsString.at(self.s, self.pos);
    INC(self.pos);
    RETURN result
END getChar;

PROCEDURE peekStr*(self: Type; len: INTEGER): JsString.Type;
VAR max: INTEGER;
BEGIN
    max := JsString.len(self.s) - self.pos;
    IF len > max THEN
        len := max;
    END
    RETURN JsString.substr(self.s, self.pos, len)
END peekStr;

PROCEDURE read*(self: Type; f: ReaderProc): BOOLEAN;
BEGIN
    WHILE ~eof(self) & f(peekChar(self)) DO
        next(self, 1);
    END
    RETURN ~eof(self)
END read;

PROCEDURE lineNumber*(self: Type): INTEGER;
VAR
    line: INTEGER;
    lastPos: INTEGER;
BEGIN
    lastPos := JsString.indexOf(self.s, 0DX);
    WHILE (lastPos # -1) & (lastPos < self.pos) DO
        INC(line);
        lastPos := JsString.indexOfFrom(self.s, 0DX, lastPos + 1);
    END;
    RETURN line + 1
END lineNumber;

END Stream.
Название: Re: Раскручиваем компилятор O7
Отправлено: kkk от Октябрь 27, 2013, 09:16:23 am
За много лет творческого пиздежа против оберона первые строчки на обероне, хо-хо-хо.
Название: Re: Раскручиваем компилятор O7
Отправлено: Geniepro от Октябрь 27, 2013, 09:18:55 am
За много лет творческого пиздежа против оберона первые строчки на обероне, хо-хо-хо.

Ну а ты обероном до сих пор не пользуешься, ва-ха-ха.
Название: Re: Раскручиваем компилятор O7
Отправлено: kkk от Октябрь 27, 2013, 09:23:19 am
Да и тут Ъ"обероном" не пахнет, всего лишь "-07".
С твоей дебильной точки зрения, С++11-лохи не могут в С++'99.
Название: Re: Раскручиваем компилятор O7
Отправлено: kkk от Октябрь 27, 2013, 09:28:18 am
Component Pascal is Oberon microsystems' refinement of the Oberon-2 language. Oberon microsystems thanks H. Mössenböck and N. Wirth for the friendly permission to use their Oberon‘2 report as basis for this document.
Component Pascal is Oberon microsystems' refinement of the Oberon-2 language. Oberon microsystems thanks H. Mössenböck and N. Wirth for the friendly permission to use their Oberon‘2 report as basis for this document.
Component Pascal is Oberon microsystems' refinement of the Oberon-2 language. Oberon microsystems thanks H. Mössenböck and N. Wirth for the friendly permission to use their Oberon‘2 report as basis for this document.
Component Pascal is Oberon microsystems' refinement of the Oberon-2 language. Oberon microsystems thanks H. Mössenböck and N. Wirth for the friendly permission to use their Oberon‘2 report as basis for this document.
Component Pascal is Oberon microsystems' refinement of the Oberon-2 language. Oberon microsystems thanks H. Mössenböck and N. Wirth for the friendly permission to use their Oberon‘2 report as basis for this document.
Component Pascal is Oberon microsystems' refinement of the Oberon-2 language. Oberon microsystems thanks H. Mössenböck and N. Wirth for the friendly permission to use their Oberon‘2 report as basis for this document.
Component Pascal is Oberon microsystems' refinement of the Oberon-2 language. Oberon microsystems thanks H. Mössenböck and N. Wirth for the friendly permission to use their Oberon‘2 report as basis for this document.
Название: Re: Раскручиваем компилятор O7
Отправлено: Geniepro от Октябрь 27, 2013, 09:30:11 am
Да и тут Ъ"обероном" не пахнет, всего лишь "-07".
С твоей дебильной точки зрения, С++11-лохи не могут в С++'99.

С++11 отличается от С++99 куда меньше, чем КП от Оберона.
Если уж сравнивать, то КП -- это аналог С++83, а Оберон -- это аналог С70...

Учи матчасть.
Название: Re: Раскручиваем компилятор O7
Отправлено: kkk от Октябрь 27, 2013, 09:31:10 am
Учи матчасть.
Иди нахуй, чучело.
В твоём первом высере ничего не было про степени отличия. На хабре такую хуйню втирай.
Название: Re: Раскручиваем компилятор O7
Отправлено: Geniepro от Октябрь 27, 2013, 09:32:05 am
Component Pascal is Oberon microsystems' refinement of the Oberon-2 language. Oberon microsystems thanks H. Mössenböck and N. Wirth for the friendly permission to use their Oberon‘2 report as basis for this document.
Вот именно что КП -- это версия Oberon-2 language, а вовсе не виртовского Оберона! Говорю же -- учи матчасть!
Название: Re: Раскручиваем компилятор O7
Отправлено: kkk от Октябрь 27, 2013, 09:34:42 am
Текущие впечатления от кодирования:
- конечно многословнее и воспринимается хуже
- жестокое и беспощадное. страдать. Если уж, то лучше...
- мелочь, но вот чисто с эргономической точки зрения напрягает страшно. Удобство принесенное в жертву формализму.
- Тяжелый синтаксис. обероновский код выглядит если не многословным, то многобуквенным. начинает напрягать. пописав "INTGER" начинаешь ценить более короткий вариант.
Эмоциональные эксперты на страже всего мейнстримного. Одни несчётные параметры. Ну этому аналезу от прафессеаналав можна вереть, дыа.
Название: Re: Раскручиваем компилятор O7
Отправлено: kkk от Октябрь 27, 2013, 09:36:44 am
Цитировать
Оберон-2 был разработан в 1991 году в Швейцарской высшей технической школе (Цюрих) Никлаусом Виртом и Ханспетером Мёссенбёком
http://www.uni-vologda.ac.ru/oberon/o2rus.htm

Всё в порядке, гони хуйню дальше, женя. Ты же вон какой профессионал ;)
Название: Re: Раскручиваем компилятор O7
Отправлено: Geniepro от Октябрь 27, 2013, 09:37:10 am
А как вообще этот код может компилироваться?
MODULE Stream;
IMPORT JsString;

TYPE
    Type = POINTER TO RECORD
        s: JsString.Type;
        pos: INTEGER
    END;
...

PROCEDURE make*(text: JsString.Type): Type;
...
Как можно экспортировать процедуру make, например, если тип Type, входящий в сигнатуру этой процедуры, неэкспортирован? о_О


- В отсутствие методов запись "Stream.pos(stream)" конечно многословнее и воспринимается хуже, чем "stream.pos()".

Это же не oberon-way. По-обероновски было бы сделать фабрику, которая кроме выделения необходимой для объекта памяти ещё и проинициализирует его методы-процедурные переменные. И тогда будет вполне привычная запись "stream.pos()"...
Название: Re: Раскручиваем компилятор O7
Отправлено: Geniepro от Октябрь 27, 2013, 09:40:25 am
Цитировать
Оберон-2 был разработан в 1991 году в Швейцарской высшей технической школе (Цюрих) Никлаусом Виртом и Ханспетером Мёссенбёком
http://www.uni-vologda.ac.ru/oberon/o2rus.htm

Мало ли что Свердлов понаписал на своём сайте. Он и про арифметику синтаксиса пургу гнал.


Всё в порядке, гони хуйню дальше, женя. Ты же вон какой профессионал ;)
петрушка, слушай лучше Стравинского, больше пользы принесёшь...
Название: Re: Раскручиваем компилятор O7
Отправлено: Geniepro от Октябрь 27, 2013, 09:44:25 am
- В отсутствие методов запись "Stream.pos(stream)" конечно многословнее и воспринимается хуже, чем "stream.pos()".

Это же не oberon-way. По-обероновски было бы сделать фабрику, которая кроме выделения необходимой для объекта памяти ещё и проинициализирует его методы-процедурные переменные. И тогда будет вполне привычная запись "stream.pos()"...

Хотя нет, выйдет примерно так: "stream.pos(stream)". Да уж, хрен редьки не слаще...
Название: Re: Раскручиваем компилятор O7
Отправлено: Geniepro от Октябрь 27, 2013, 09:51:01 am
Да и тут Ъ"обероном" не пахнет, всего лишь "-07".

Кчтати, Влад, если доведёшь компилятор до соответствия этому рапорту, можно его смело переименовывать из Oberon-07/11 в Oberon-13, или же просто в Oberon. Так будет правильнее...
Название: Re: Раскручиваем компилятор O7
Отправлено: kkk от Октябрь 27, 2013, 09:53:52 am
Цитировать
Оберон-2 был разработан в 1991 году в Швейцарской высшей технической школе (Цюрих) Никлаусом Виртом и Ханспетером Мёссенбёком
http://www.uni-vologda.ac.ru/oberon/o2rus.htm

Мало ли что Свердлов понаписал на своём сайте. Он и про арифметику синтаксиса пургу гнал.


Всё в порядке, гони хуйню дальше, женя. Ты же вон какой профессионал ;)
петрушка, слушай лучше Стравинского, больше пользы принесёшь...
Заявка на победу. То есть ты сомневаешься, что О2 был написан виртом, как развитие Оберона? Ну ты и ебанько.
Название: Re: Раскручиваем компилятор O7
Отправлено: Geniepro от Октябрь 27, 2013, 10:02:10 am
Цитировать
Оберон-2 был разработан в 1991 году в Швейцарской высшей технической школе (Цюрих) Никлаусом Виртом и Ханспетером Мёссенбёком
http://www.uni-vologda.ac.ru/oberon/o2rus.htm

Мало ли что Свердлов понаписал на своём сайте. Он и про арифметику синтаксиса пургу гнал.


Всё в порядке, гони хуйню дальше, женя. Ты же вон какой профессионал ;)
петрушка, слушай лучше Стравинского, больше пользы принесёшь...
Заявка на победу. То есть ты сомневаешься, что О2 был написан виртом, как развитие Оберона? Ну ты и ебанько.

Третий раз повторяю (а значит это истина) -- учи матчасть!

Мёссенбёк для своих нужд переделал Оберон, обозвал его Обероном-2, а Вирт подмахнул рапорт об Обероне-2. Вот и всё участие Вирта в создании Оберона-2.
Название: Re: Раскручиваем компилятор O7
Отправлено: kkk от Октябрь 27, 2013, 10:07:43 am
А ты рядом стоял, свечку держал. Вот оно что.
Какой ты. :)
Название: Re: Раскручиваем компилятор O7
Отправлено: kkk от Октябрь 27, 2013, 10:08:52 am
Сколько раз я тебя назвал уёбищем? Два, три? Может уже пора закрепить результат?
Название: Re: Раскручиваем компилятор O7
Отправлено: Berserker от Октябрь 27, 2013, 10:30:48 am
Vlad, у меня в Делфи код ещё более многословен. Это абсолютно не напрягает, если настроить такие редакторы как Notepad++ (плагин QuickText) или Sublime Text 2. Практически для всего пишешь сниппеты или их аналоги. И целые блоки и серии описаний в несколько нажатий клавиш. Например, i CTRL + ENTER = INTEGER. r =END RETURN x; Попробуйте.
Название: Re: Раскручиваем компилятор O7
Отправлено: kkk от Октябрь 27, 2013, 10:41:21 am
Дельфи это ведь моветон. Грешно вспоминать такое на форуме умных адекватных людей ;) Вот вы бы лучше вспомнили Луа, или Скала.
Название: Re: Раскручиваем компилятор O7
Отправлено: Kemet от Октябрь 27, 2013, 12:22:14 pm
Кчтати, Влад, если доведёшь компилятор до соответствия этому рапорту, можно его смело переименовывать из Oberon-07/11 в Oberon-13, или же просто в Oberon. Так будет правильнее...
Файл репорта Вирт назвал Oberon07.Report.pdf - 07, а не 13
Название: Re: Раскручиваем компилятор O7
Отправлено: vlad от Октябрь 27, 2013, 03:24:05 pm
Хотя нет, выйдет примерно так: "stream.pos(stream)". Да уж, хрен редьки не слаще...

Угу. Без расширений (методы или не знаю что) все равно ерунда будет.
Название: Re: Раскручиваем компилятор O7
Отправлено: vlad от Октябрь 27, 2013, 03:28:11 pm
Vlad, у меня в Делфи код ещё более многословен. Это абсолютно не напрягает, если настроить такие редакторы как Notepad++ (плагин QuickText) или Sublime Text 2.

Кстати, а нет ли у тебя расцветки для Сублима?
Название: Re: Раскручиваем компилятор O7
Отправлено: valexey_u от Октябрь 27, 2013, 04:16:34 pm
Гм. А что мешает сделать как-то так?

MODULE Test;
IMPORT SomeModule;

PROCEDURE LetDoIt;
VAR
   var : SomeModule.SomeType;
   process : PROCEDURE (v : SomeModule.SomeType);
BEGIN
   process := SomeModule.ProcessSomeType;
   process(var);
   (* и тут еще 100500 строк кода с испоользованием process *)
END LetDoIt;

END Test;
Название: Re: Раскручиваем компилятор O7
Отправлено: Geniepro от Октябрь 27, 2013, 04:30:21 pm
Гм. А что мешает сделать как-то так?

MODULE Test;
IMPORT SomeModule;

PROCEDURE LetDoIt;
VAR
   var : SomeModule.SomeType;
   process : PROCEDURE (v : SomeModule.SomeType);
BEGIN
   process := SomeModule.ProcessSomeType;
   process(var);
   (* и тут еще 100500 строк кода с испоользованием process *)
END LetDoIt;

END Test;

Так ещё хуже -- повышается уровень косвенности, труднее понимать, что там вообще происходит...
Название: Re: Раскручиваем компилятор O7
Отправлено: Berserker от Октябрь 27, 2013, 04:41:58 pm
Цитировать
Кстати, а нет ли у тебя расцветки для Сублима?
К сожалению, нет. Нужно брать за основу пакет Pascal. Там 5,35 кибибайта размер всего.
Название: Re: Раскручиваем компилятор O7
Отправлено: valexey_u от Октябрь 27, 2013, 04:50:08 pm
Гм. А что мешает сделать как-то так?

MODULE Test;
IMPORT SomeModule;

PROCEDURE LetDoIt;
VAR
   var : SomeModule.SomeType;
   process : PROCEDURE (v : SomeModule.SomeType);
BEGIN
   process := SomeModule.ProcessSomeType;
   process(var);
   (* и тут еще 100500 строк кода с испоользованием process *)
END LetDoIt;

END Test;

Так ещё хуже -- повышается уровень косвенности, труднее понимать, что там вообще происходит...

foo.bar() -- тоже уровень косвенности огого, особенно если bar это виртуальная функция - ведь ты даже не знаешь в каком модуле она лежит! И не узнаешь пока все исходники не перетрясешь!

А тут же - все локально и явным образом определено.
Название: Re: Раскручиваем компилятор O7
Отправлено: vlad от Октябрь 28, 2013, 12:36:32 am
А как вообще этот код может компилироваться?

Это бага. Пока прокатывает, потому что модуль потребляется из жабаскрипта  (а не из других обероновских модулей).
Название: Re: Раскручиваем компилятор O7
Отправлено: vlad от Октябрь 28, 2013, 04:37:32 am
Это бага. Пока прокатывает, потому что модуль потребляется из жабаскрипта  (а не из других обероновских модулей).

Я тут было уже фикснул, но подумал, что нет, не бага. Например вот такой случай:
MODULE test;
TYPE
    T = POINTER TO RECORD END;
    Proc* = PROCEDURE(): T;

PROCEDURE method1*(): T;
...
PROCEDURE method2*(): T;
...
PROCEDURE do*(method: Proc);
...

IMPORT test;
...
test.do(test.p1);

Возможно даже Proc не надо экспортировать. Так что пока откачу фикс.
Название: Re: Раскручиваем компилятор O7
Отправлено: Geniepro от Октябрь 28, 2013, 05:16:59 am
Это бага. Пока прокатывает, потому что модуль потребляется из жабаскрипта  (а не из других обероновских модулей).

Я тут было уже фикснул, но подумал, что нет, не бага. Например вот такой случай:
MODULE test;
TYPE
    T = POINTER TO RECORD END;
    Proc* = PROCEDURE(): T;

PROCEDURE method1*(): T;
...
PROCEDURE method2*(): T;
...
PROCEDURE do*(method: Proc);
...

IMPORT test;
...
test.do(test.p1);
Всё же я думаю, что это баг. Как можно в обероне использовать процедуры с неизвестными сигнатурами?
Возможно даже Proc не надо экспортировать. Так что пока откачу фикс.
Название: Re: Раскручиваем компилятор O7
Отправлено: vlad от Ноябрь 06, 2013, 05:54:18 am
Переписал лексер на оберон:
https://github.com/vladfolts/oberonjs/blob/master/src/oberon/Lexer.ob

Свежие впечатления:
- Оказывается операции сравнения в обероне имеют наименьший приоритет. Это приводит к тому, что все нетривиальные условия сразу обрастают скобками:
if (a != b && a != c)
===
IF (a # b) & (a # c) THEN
- Условия очень быстро становятся сложными из-за одного RETURN
- Ну и апофеоз всего: Цикл Дейкстры. Отгадайте что он делает и есть ли в нем ошибка:
PROCEDURE isReservedWorld(s: JsString.Type; words: JsString.Type): BOOLEAN;
VAR
    i, w: INTEGER;
BEGIN
    WHILE (w < JsString.len(words))
        & (i < JsString.len(s))
        & (JsString.at(words, w) = JsString.at(s, i))
        & ((i # 0) OR (w = 0) OR (JsString.at(words, w - 1) = " ")) DO
        INC(w);
        INC(i);
    ELSIF (w < JsString.len(words))
        & ((i < JsString.len(s)) OR (JsString.at(words, w) # " ")) DO
        INC(w);
        i := 0;
    END;
    RETURN i = JsString.len(s)
END isReservedWorld;
Название: Re: Раскручиваем компилятор O7
Отправлено: Geniepro от Ноябрь 06, 2013, 07:15:55 am
Переписал лексер на оберон:
https://github.com/vladfolts/oberonjs/blob/master/src/oberon/Lexer.ob

Свежие впечатления:
- Оказывается операции сравнения в обероне имеют наименьший приоритет. Это приводит к тому, что все нетривиальные условия сразу обрастают скобками:
if (a != b && a != c)
===
IF (a # b) & (a # c) THEN

Ну, в данном случае проблема в том, что у операций сравнения одинаковый приоритет.
С другой стороны, я и в сях/сишарпе часто сложные логические выражения в скобки оборачиваю -- в основном для группирования частей выражений, иногда лень вспоминать приоритеты. Сомневаешься в приоритетах -- оберни в скобки!

- Ну и апофеоз всего: Цикл Дейкстры. Отгадайте что он делает и есть ли в нем ошибка:
PROCEDURE isReservedWorld(s: JsString.Type; words: JsString.Type): BOOLEAN;
VAR
    i, w: INTEGER;
BEGIN
    WHILE (w < JsString.len(words))
        & (i < JsString.len(s))
        & (JsString.at(words, w) = JsString.at(s, i))
        & ((i # 0) OR (w = 0) OR (JsString.at(words, w - 1) = " ")) DO
        INC(w);
        INC(i);
    ELSIF (w < JsString.len(words))
        & ((i < JsString.len(s)) OR (JsString.at(words, w) # " ")) DO
        INC(w);
        i := 0;
    END;
    RETURN i = JsString.len(s)
END isReservedWorld;

Цикл, конечно, жестокий. А всё из-за неверных структур данных типа:
    reservedWords := JsString.make(
        "ARRAY IMPORT THEN BEGIN IN TO BY IS TRUE CASE MOD TYPE CONST MODULE UNTIL DIV NIL VAR DO OF WHILE ELSE OR ELSIF POINTER END PROCEDURE FALSE RECORD FOR REPEAT IF RETURN");
    jsReservedWords := JsString.make(
        "break case catch continue debugger default delete do else finally for function if in instanceof new return switch this throw try typeof var void while with Math"); (* Math is used in generated code for some functions so it is reserved word from code generator standpoint *)

ЗЫ. Вот, кстати, яркий пример, что мало кто читает руководства по стилю кодирования (http://oberspace.dyndns.org/index.php/topic,535.0.html). Какой смысл их писать?.. :'(
Название: Re: Раскручиваем компилятор O7
Отправлено: adva от Ноябрь 06, 2013, 07:39:05 am
С самим циклом не разбирался, но попутно вопрос возник, разве там w не надо присваивать перед циклом?
Название: Re: Раскручиваем компилятор O7
Отправлено: valexey_u от Ноябрь 06, 2013, 08:01:20 am
С самим циклом не разбирался, но попутно вопрос возник, разве там w не надо присваивать перед циклом?
Да и i тоже :-)
Название: Re: Раскручиваем компилятор O7
Отправлено: Geniepro от Ноябрь 06, 2013, 08:17:23 am
С самим циклом не разбирался, но попутно вопрос возник, разве там w не надо присваивать перед циклом?

С самим циклом не разбирался, но попутно вопрос возник, разве там w не надо присваивать перед циклом?
Да и i тоже :-)

Там же в компиляторе сделано, что всем переменным по умолчанию присваиваются нулевые значения -- числам нули, указателям nil...
Название: Re: Раскручиваем компилятор O7
Отправлено: adva от Ноябрь 06, 2013, 08:17:39 am
С самим циклом не разбирался, но попутно вопрос возник, разве там w не надо присваивать перед циклом?
Да и i тоже :-)
Тоже не надо, или тоже надо :) ?
Название: Re: Раскручиваем компилятор O7
Отправлено: valexey_u от Ноябрь 06, 2013, 08:18:28 am
С самим циклом не разбирался, но попутно вопрос возник, разве там w не надо присваивать перед циклом?

С самим циклом не разбирался, но попутно вопрос возник, разве там w не надо присваивать перед циклом?
Да и i тоже :-)

Там же в компиляторе сделано, что всем переменным по умолчанию присваиваются нулевые значения -- числам нули, указателям nil...
Какая разница как именно в конкретной реализации это сделано? Язык не гарантирует, следовательно будет UB.
Название: Re: Раскручиваем компилятор O7
Отправлено: adva от Ноябрь 06, 2013, 08:18:57 am
Там же в компиляторе сделано, что всем переменным по умолчанию присваиваются нулевые значения -- числам нули, указателям nil...

Это исходя из сообщения о языке сделано? Или просто так удобнее?
Название: Re: Раскручиваем компилятор O7
Отправлено: Geniepro от Ноябрь 06, 2013, 08:34:49 am
Там же в компиляторе сделано, что всем переменным по умолчанию присваиваются нулевые значения -- числам нули, указателям nil...

Это исходя из сообщения о языке сделано? Или просто так удобнее?

В сообщении о языке я на эту тему ничего не нашёл -- там вообще нет ни одного вхождения слова "default".
Похоже, судя по сообщению эти значения не поределены (undefined)...
Название: Re: Раскручиваем компилятор O7
Отправлено: vlad от Ноябрь 06, 2013, 02:44:33 pm
Ну, в данном случае проблема в том, что у операций сравнения одинаковый приоритет.

Не одинаковый, а наименьший - я ж написал :)

С другой стороны, я и в сях/сишарпе часто сложные логические выражения в скобки оборачиваю -- в основном для группирования частей выражений, иногда лень вспоминать приоритеты. Сомневаешься в приоритетах -- оберни в скобки!

Сложные - да. Простые типа "p && p->f()" обычно не оборачивают.

Цикл, конечно, жестокий. А всё из-за неверных структур данных типа:

Согласен. В оригинале на жабскрипте это был просто поиск в массиве ключевых слов. Который я ни разу не отлаживал. В обероне это превратилось в строчку с пробелами, потому что нет нормальной инициализации массивов и нет динамических массивов (даже если была бы инициализация, то пришлось бы делать все ключевые слова одинакового размера, забивая окончания нулями). Это еще как пример того, когда простота языка вылезает боком в решении на этом языке. Вообще написание Цикла Дейкстры чем-то напоминает решение кроссворда или головоломки - такая разминка для ума. Не знаю сколько их нужно написать, чтоб потом говорить о выписывании "на автомате" вот этих трехэтажных условий.

ЗЫ. Вот, кстати, яркий пример, что мало кто читает руководства по стилю кодирования (http://oberspace.dyndns.org/index.php/topic,535.0.html). Какой смысл их писать?.. :'(

Я читал их в свое время. Они мне показались полностью согласующимися с моим стилем. Поэтому я даже на заметку не стал брать. Что не так?
Название: Re: Раскручиваем компилятор O7
Отправлено: vlad от Ноябрь 06, 2013, 03:04:14 pm
В сообщении о языке я на эту тему ничего не нашёл -- там вообще нет ни одного вхождения слова "default".
Похоже, судя по сообщению эти значения не определены (undefined)...

В репорте сказано, что значения локальных переменных на входе в процедуру не определены (при этом, конечно, они могут иметь и нулевые значения). Т.е., да - по репорту это чистой воды UB .
С другой стороны, лично я считаю этот момент принципиальным, поэтому в своей реализации я сделал уточнение (https://github.com/vladfolts/oberonjs/wiki/Original-report-refinements#2-variables-default-values).
В ББ этот момент тоже считают принципиальным (герметичность типов, не хухры-мухры), но не до конца - там обнуляют только указатели. Их можно понять - 90-е годы, Си все еще популярен и там неопределенные переменные в порядке вещей.
Название: Re: Раскручиваем компилятор O7
Отправлено: Valery Solovey от Ноябрь 06, 2013, 10:20:50 pm
Ну так что, правильно цикл работает?
Название: Re: Раскручиваем компилятор O7
Отправлено: vlad от Ноябрь 06, 2013, 10:49:12 pm
Ну так что, правильно цикл работает?

Тесты проходят. Но он страшный. Поэтому уверенности нет. Хотелось одобрения экспертов.
Название: Re: Раскручиваем компилятор O7
Отправлено: albobin от Ноябрь 07, 2013, 05:56:23 am
Надо бы состояние добавить для упрощения условий.
Типа так ( обероном не проверял :)   )

PROCEDURE isReservedWorld(s: JsString.Type; words: JsString.Type): BOOLEAN;
VAR
    i, w: INTEGER;
    ok: BOOLEAN;
    i := 0 ;
    w := 0 ;
    ok := TRUE ;
 BEGIN
    WHILE ok
        & (w < JsString.len(words))
        & (i < JsString.len(s))
        & (JsString.at(words, w) = JsString.at(s, i)) DO
        INC(w);
        INC(i);
    ELSIF (w < JsString.len(words))
        & (JsString.at(words, w) # " ")) DO
        INC(w);
        i := 0;
        ok := FALSE;
    ELSIF (w < JsString.len(words))
        & (i < JsString.len(s)) DO
        INC(w);
        i := 0;
        ok := TRUE;
    END;
    RETURN (i = JsString.len(s)) & ok
END isReservedWorld;
Название: Re: Раскручиваем компилятор O7
Отправлено: albobin от Ноябрь 07, 2013, 06:00:27 am
PS.
RETURN ok

Название: Re: Раскручиваем компилятор O7
Отправлено: albobin от Ноябрь 07, 2013, 06:10:40 am
PPS.
тьфу, вот так, (  & ok  можно выкинуть)
RETURN (i = JsString.len(s))
Название: Re: Раскручиваем компилятор O7
Отправлено: Peter Almazov от Ноябрь 07, 2013, 07:44:31 am
Тесты проходят. Но он страшный. Поэтому уверенности нет. Хотелось одобрения экспертов.
Не знаю, как там эксперты, а я не одобряю.
И метод разработки (метод тыка) и результат - ужасны.
Как при таком методе получилось нечто работоспособное - для меня большая загадка.

Вот что дает осмысленное проектирование.
Кому надо, перепишет с C# на смесь JS и Оберона:
    static bool isReservedWorld(string s, string words) {
      int i = 0, w = 0;
      bool prevEq = true;
      while (true) {
        if (prevEq && (w < words.Length) && (i < s.Length) && (words[w] == s[i])) {
          w++;
          i++;
        } else if (prevEq && (w < words.Length) && (i < s.Length) && /*это избыточно*/ (words[w] != s[i])) {
          prevEq = false;
          i = 0;
        } else if (w < words.Length && !prevEq) {
          if (words[w] == ' ') {
            prevEq = true;
          }
          w++;
        } else {
          break;
        }
      }
      return i == s.Length;
    }

По поводу цикла Дейкстры - два наблюдения. Не помню, были ли они раньше.
1. Во многих случаях ЦД - это смешение разных уровней абстракций. И это плохо.
2. Во много благодаря п.1 ЦД весьма похож на реализацию конечного автомата. Только состояния здесь обычно не вводятся явно, а вычисляются из переменных на каждом шаге. Отсюда - неэффективность. Тоже плохо.

p.s. забыл отметить, что ключевые слова должны быть разделены ровно одним пробелом.
Название: Re: Раскручиваем компилятор O7
Отправлено: albobin от Ноябрь 07, 2013, 07:59:47 am
2 Peter.
В ситуации, когда
prevEq && (w < words.Length) && (i = s.Length)
но words[w] не пробел , то ошибка
Название: Re: Раскручиваем компилятор O7
Отправлено: Peter Almazov от Ноябрь 07, 2013, 11:21:51 am
Ага, прощёлкал. Сосредоточился на цикле, а возврат оставил как в оригинале.
Надо заменить:

return i == s.Length;
на
return i == s.Length && (w == words.Length || words[w] == ' ');
Название: Re: Раскручиваем компилятор O7
Отправлено: albobin от Ноябрь 07, 2013, 11:47:19 am
2 Peter
Нет, здесь в цикле недочёт.  Уходит преждевременно на break, при тех условиях, что я указал.

Название: Re: Раскручиваем компилятор O7
Отправлено: albobin от Ноябрь 07, 2013, 11:57:08 am
PS.
К примеру ищем в строке слово "ON".
Наткнулись на  "ONE" и вышли, а далее в строке может всё же есть "ON"
Название: Re: Раскручиваем компилятор O7
Отправлено: albobin от Ноябрь 07, 2013, 12:35:11 pm
PPS.
Конечно, если слова в строке отсортированы, то проблем в цикле нет.
Название: Re: Раскручиваем компилятор O7
Отправлено: Peter Almazov от Ноябрь 07, 2013, 12:45:36 pm
Я считал, что отсортированы.
Иначе на каждый чих - полный проход по всем словам.
Алгоритм и без того дурацкий.
Название: Re: Раскручиваем компилятор O7
Отправлено: Valery Solovey от Ноябрь 07, 2013, 12:50:37 pm
WHILE (i < JsString.len(s)) & (w < JsString.len(words)) DO
WHILE (w < JsString.len(words)) & (i < JsString.len(s)) & (JsString.at(words, w) = JsString.at(s, i)) DO
INC(w); INC(i)
END

IF i < JsString.len(s) THEN
i := 0;
WHILE (w < JsString.len(words)) & (JsString.at(words, w) # " ") DO
w := w + 1
END;
WHILE (w < JsString.len(words))& (JsString.at(words, w) = " ") DO
w := w + 1
END
END
END;
RETURN i = JsString.len(s)
Название: Re: Раскручиваем компилятор O7
Отправлено: vlad от Ноябрь 07, 2013, 03:35:28 pm
Тесты проходят. Но он страшный. Поэтому уверенности нет. Хотелось одобрения экспертов.
Не знаю, как там эксперты, а я не одобряю.

Да, я вот как раз ждал твоего веского слова :)

И метод разработки (метод тыка) и результат - ужасны.

Дык, ошибка-то есть? А то не очень просто делать дифф с  твоим шарповым вариантом. При том, что он в той же степени нечитаем (при том, что я не ставлю под сомнение осмысленное проектирование).

Как при таком методе получилось нечто работоспособное - для меня большая загадка.

Тесты спасают. Когда нужно получить что-то работоспособное, но непонятно как.
Название: Re: Раскручиваем компилятор O7
Отправлено: vlad от Ноябрь 07, 2013, 03:38:34 pm
PS.
К примеру ищем в строке слово "ON".
Наткнулись на  "ONE" и вышли, а далее в строке может всё же есть "ON"

Кстати, именно эту ошибку мне пришлось исправить в процессе отладки моего цикла.
Название: Re: Раскручиваем компилятор O7
Отправлено: vlad от Ноябрь 07, 2013, 03:40:00 pm
Кстати, именно эту ошибку мне пришлось исправить в процессе отладки моего цикла.

там есть IF и ELSIF
Название: Re: Раскручиваем компилятор O7
Отправлено: Peter Almazov от Ноябрь 07, 2013, 03:51:13 pm
Дык, ошибка-то есть?
Во всяком случае, я не в состоянии ее найти :)

Хотя, все зависит от того, что считать ошибкой...
Название: Re: Раскручиваем компилятор O7
Отправлено: albobin от Ноябрь 07, 2013, 05:39:51 pm
Если не зацикливаться на ЦД :)
Рефакторинг исходного кода с такими ограничениями на строку слов:
слова отсортированы,
между словами один пробел,
после последнего слова тоже стоит пробел

PROCEDURE isReservedWorld(s: JsString.Type; words: JsString.Type): BOOLEAN;
VAR
    i, w, w0: INTEGER;

BEGIN
    i := 0 ;
    w := 0 ;
    w0:= 0 ;
    WHILE (w < JsString.len(words))
        & ((i < JsString.len(s)) OR (JsString.at(words, w) # " ")) DO
        IF (i < JsString.len(s)) & (JsString.at(words, w0) = JsString.at(s, i)) THEN
          INC(w); w0 := w;
          INC(i);
        ELSIF (JsString.at(words, w) # " ") THEN
          INC(w);
        ELSE
          INC(w); w0 := w;
          i := 0;
        END;
    END;
    RETURN (w < JsString.len(words))
END isReservedWorld;

PS.
проверять лень :)
Название: Re: Раскручиваем компилятор O7
Отправлено: albobin от Ноябрь 07, 2013, 06:20:23 pm
описка:
в условии WHILE
не
... OR (JsString.at(words, w) # " ")) DOа
... OR (JsString.at(words, w0) # " ")) DO
PS.
Как же тяжко писать много букафф, вместо просто  $d(words(s)) как в МУМПСе  :)
Название: Re: Раскручиваем компилятор O7
Отправлено: vlad от Ноябрь 07, 2013, 06:26:49 pm
после последнего слова тоже стоит пробел

Кстати да, если добавить с начала и в конце пробелы - то условия упрощаются (не нужны проверки на пограничные условия - начало и конец строки).
Название: Re: Раскручиваем компилятор O7
Отправлено: vlad от Ноябрь 07, 2013, 06:29:20 pm
PS.
Как же тяжко писать много букафф, вместо просто  $d(words(s)) как в МУМПСе  :)

Хе-хе. На питоне:
s in ' '.split(words)

Типа:
- Почему в популярны языках нет Цикла Дейкстры?
- Потому что он там нинужен

:)
Название: Re: Раскручиваем компилятор O7
Отправлено: albobin от Ноябрь 07, 2013, 07:48:44 pm
Да не ниненужен, а не осилили :)
Название: Re: Раскручиваем компилятор O7
Отправлено: kkkk от Ноябрь 07, 2013, 07:50:00 pm
Решение мне не понятно. Мало узнать, является слово ключевым или нет, нужно знать какое это ключевое слово. Повторно сравнивать строки в дальнейшем будет излишеством. А если так, то таблица вместе с линейным поиском по ней, немногим лучше таблицы, встроенной в развернутый линейный поиск, которые легко реализуется на Обероне.
А вообще-то тут должна быть расстановочная таблица (хэш-массив)
Название: Re: Раскручиваем компилятор O7
Отправлено: Geniepro от Ноябрь 07, 2013, 07:51:51 pm
PS.
Как же тяжко писать много букафф, вместо просто  $d(words(s)) как в МУМПСе  :)

Хе-хе. На питоне:
s in ' '.split(words)

И в хацкеле:
s `elem` (words keywords)(words -- это в хаскелле стандартная функция, поэтому строку, содержащую ключевые слова, назовём как keywords)

Типа:
- Почему в популярны языках нет Цикла Дейкстры?
- Потому что он там нинужен

:)
Либо легко эмулируется при необходимости (как в сях тремя макросами (http://oberspace.dyndns.org/index.php/topic,39.msg1153.html#msg1153)).
#define WHILE     for(;;) if (
#define DO        ) {
#define ELSIF     ; } else if (
#define WEND      ; } else break

int gcd(int x, int y)
{
    WHILE x > y DO x = x - y
    ELSIF x < y DO y = y - x
    WEND;
    return x;
}
Название: Re: Раскручиваем компилятор O7
Отправлено: vlad от Ноябрь 07, 2013, 08:34:13 pm
Решение мне не понятно. Мало узнать, является слово ключевым или нет, нужно знать какое это ключевое слово.

Тут лексер не совсем классический. Он не просто разбирает входной поток на лексемы, а ожидает вполне конкретную лексему. В данном случае он ожидает идентификатор и ничто другое. Поэтому для того, чтобы определить удалось ли ему получить идентификатор или нет - ему не обязательно знать какое именно ключевое слово ему попалось вместо идентификатора. Повторного сравнения все равно не будет.

Повторно сравнивать строки в дальнейшем будет излишеством. А если так, то таблица вместе с линейным поиском по ней, немногим лучше таблицы, встроенной в развернутый линейный поиск, которые легко реализуется на Обероне.
А вообще-то тут должна быть расстановочная таблица (хэш-массив)

В данном случае нужно то, что нужно - определить принадлежность к списку зарезервированных слов (там на самом деле два этих списка, другой список - список жабаскриптовых зарезервированных слов). Как можно проще. Альтернативные решения приветствуются, но в рамках поставленной задачи.
Название: Re: Раскручиваем компилятор O7
Отправлено: kkkk от Ноябрь 07, 2013, 08:52:50 pm
PROCEDURE IsReservedOberonWord(s: ARRAY OF CHAR): BOOLEAN;
BEGIN
    RETURN s = "ARRAY" OR s = "IMPORT" OR s = "THEN" OR s = "BEGIN" OR s = "IN" OR s = "TO" OR s = "BY" OR
                s = "IS" OR s = "TRUE" OR s = "CASE" OR s = "MOD" OR s = "TYPE" OR s = "CONST" OR s = "MODULE" OR
                s = "UNTIL" OR s = "DIV" OR s = "NIL" OR s = "VAR" OR s = "DO" OR s = "OF" OR s = "WHILE" OR s = "ELSE" OR
                s = "OR" OR s = "ELSIF" OR s = "POINTER" OR s = "END" OR s = "PROCEDURE" OR s = "FALSE" OR
                s = "RECORD" OR s = "FOR" OR s = "REPEAT" OR s = "IF" OR s = "RETURN"
END IsReservedOberonWord;
Проще некуда. "Таблица" зарезервированных слов немного разбавлена кодом, но в в целом простота составления приблизительно на том же уровне. Не тестировал.
Название: Re: Раскручиваем компилятор O7
Отправлено: vlad от Ноябрь 07, 2013, 09:09:46 pm
Проще некуда.

Да, засчитано. Но не могу применить в текущей реализации - оно странслируется в ужос-ужос.
Название: Re: Раскручиваем компилятор O7
Отправлено: vlad от Ноябрь 07, 2013, 09:15:26 pm
    RETURN s = "ARRAY" OR s = "IMPORT" OR s = "THEN" OR s = "BEGIN" OR s = "IN" OR s = "TO" OR s = "BY"

Гы! И здесь тоже скобочки нужны! :)
Название: Re: Раскручиваем компилятор O7
Отправлено: valexey_u от Ноябрь 07, 2013, 09:20:04 pm
Проще некуда.

Да, засчитано. Но не могу применить в текущей реализации - оно странслируется в ужос-ужос.
Дак, этта.. Пофиксить надыть. Хотя вначале с этими relations надо разобраться.
Название: Re: Раскручиваем компилятор O7
Отправлено: kkkk от Ноябрь 07, 2013, 09:54:25 pm
    RETURN s = "ARRAY" OR s = "IMPORT" OR s = "THEN" OR s = "BEGIN" OR s = "IN" OR s = "TO" OR s = "BY"

Гы! И здесь тоже скобочки нужны! :)
Проглядел, хотя так:
    RETURN (s = "ARRAY") OR (s = "IMPORT") OR (s = "THEN") OR (s = "BEGIN") OR (s = "IN") OR (s = "TO") OR (s = "BY")
по-моему, читаемость только выше
Название: Re: Раскручиваем компилятор O7
Отправлено: Geniepro от Ноябрь 08, 2013, 05:12:32 am
Да уж, уныло, конечно:

PROCEDURE IsReservedOberonWord(s: ARRAY OF CHAR): BOOLEAN;
BEGIN
    RETURN (s = "ARRAY")   OR (s = "IMPORT") OR (s = "THEN")
        OR (s = "BEGIN")   OR (s = "IN")     OR (s = "TO")
        OR (s = "BY")      OR (s = "IS")     OR (s = "TRUE")
        OR (s = "CASE")    OR (s = "MOD")    OR (s = "TYPE")
        OR (s = "CONST")   OR (s = "MODULE") OR (s = "UNTIL")
        OR (s = "DIV")     OR (s = "NIL")    OR (s = "VAR")
        OR (s = "DO")      OR (s = "OF")     OR (s = "WHILE")
        OR (s = "ELSE")    OR (s = "OR")     OR (s = "ELSIF")
        OR (s = "POINTER") OR (s = "END")    OR (s = "PROCEDURE")
        OR (s = "FALSE")   OR (s = "RECORD") OR (s = "FOR")
        OR (s = "REPEAT")  OR (s = "IF")     OR (s = "RETURN")
END IsReservedOberonWord;
Название: Re: Раскручиваем компилятор O7
Отправлено: igor от Ноябрь 08, 2013, 06:09:51 am
А вот вариант, основанный на идее, подсмотренной в исходниках BB:
PROCEDURE IsReservedOberonWord(s: ARRAY OF CHAR): BOOLEAN;
VAR res: BOOLEAN
BEGIN
  CASE s[0] OF
  | 'A': res := s = "ARRAY";
  | 'B': res := (s = "BEGIN") OR (s = "BY");
  | 'C': res := (s = "CASE") OR (s = "CONST");
  | 'D': res := (s = "DIV") OR (s = "DO");
  | 'E': res := (s = "END") OR (s = "ELSE") OR (s = "ELSIF");
  | 'F': res := (s = "FALSE") OR (s = "FOR");
  | 'I': res := (s = "IMPORT") OR (s = "IN") OR (s = "IS") OR (s = "IF");
  | 'M': res := (s = "MOD") OR (s = "MODULE");
  | 'N': res := s = "NIL";
  | 'O': res := (s = "OF") OR (s = "OR");
  | 'P': res := (s = "POINTER") OR (s = "PROCEDURE");
  | 'R': res := (s = "RECORD") OR (s = "REPEAT") OR (s = "RETURN");
  | 'T': res := (s = "TO") OR (s = "THEN") OR (s = "TRUE") OR (s = "TYPE");
  | 'U': res := s = "UNTIL";
  | 'V': res := s = "VAR";
  | 'W': res := s = "WHILE";
  ELSE res := FALSE
  END;
  RETURN res
END IsReservedOberonWord;
Название: Re: Раскручиваем компилятор O7
Отправлено: valexey_u от Ноябрь 08, 2013, 07:02:26 am
А вот вариант, основанный на идее, подсмотренной в исходниках BB:
PROCEDURE IsReservedOberonWord(s: ARRAY OF CHAR): BOOLEAN;
VAR res: BOOLEAN
BEGIN
  CASE s[0] OF
  | 'A': res := s = "ARRAY";
  | 'B': res := (s = "BEGIN") OR (s = "BY");
  | 'C': res := (s = "CASE") OR (s = "CONST");
  | 'D': res := (s = "DIV") OR (s = "DO");
  | 'E': res := (s = "END") OR (s = "ELSE") OR (s = "ELSIF");
  | 'F': res := (s = "FALSE") OR (s = "FOR");
  | 'I': res := (s = "IMPORT") OR (s = "IN") OR (s = "IS") OR (s = "IF");
  | 'M': res := (s = "MOD") OR (s = "MODULE");
  | 'N': res := s = "NIL";
  | 'O': res := (s = "OF") OR (s = "OR");
  | 'P': res := (s = "POINTER") OR (s = "PROCEDURE");
  | 'R': res := (s = "RECORD") OR (s = "REPEAT") OR (s = "RETURN");
  | 'T': res := (s = "TO") OR (s = "THEN") OR (s = "TRUE") OR (s = "TYPE");
  | 'U': res := s = "UNTIL";
  | 'V': res := s = "VAR";
  | 'W': res := s = "WHILE";
  ELSE res := FALSE
  END;
  RETURN res
END IsReservedOberonWord;

Тогда уж можно и полное дерево построить :-)
Название: Re: Раскручиваем компилятор O7
Отправлено: igor от Ноябрь 08, 2013, 07:23:57 am
Тогда уж можно и полное дерево построить :-)
Это будет уже перебор.
В предложенном мной варианте компилятор сгенерирует по кэйсу очень быструю таблицу переходов, и далее потребуется не более четырёх сравнений строк.
Если, например, повторить этот трюк внутри обработки случаев 'I' и 'T', то профит будет уже не столь впечатляющим, если вообще будет.
Название: Re: Раскручиваем компилятор O7
Отправлено: Geniepro от Ноябрь 08, 2013, 07:44:45 am
А вот вариант, основанный на идее, подсмотренной в исходниках BB:
PROCEDURE IsReservedOberonWord(s: ARRAY OF CHAR): BOOLEAN;
VAR res: BOOLEAN
BEGIN
  CASE s[0] OF
  | 'A': res := s = "ARRAY";
  | 'B': res := (s = "BEGIN") OR (s = "BY");
  | 'C': res := (s = "CASE") OR (s = "CONST");
  | 'D': res := (s = "DIV") OR (s = "DO");
  | 'E': res := (s = "END") OR (s = "ELSE") OR (s = "ELSIF");
  | 'F': res := (s = "FALSE") OR (s = "FOR");
  | 'I': res := (s = "IMPORT") OR (s = "IN") OR (s = "IS") OR (s = "IF");
  | 'M': res := (s = "MOD") OR (s = "MODULE");
  | 'N': res := s = "NIL";
  | 'O': res := (s = "OF") OR (s = "OR");
  | 'P': res := (s = "POINTER") OR (s = "PROCEDURE");
  | 'R': res := (s = "RECORD") OR (s = "REPEAT") OR (s = "RETURN");
  | 'T': res := (s = "TO") OR (s = "THEN") OR (s = "TRUE") OR (s = "TYPE");
  | 'U': res := s = "UNTIL";
  | 'V': res := s = "VAR";
  | 'W': res := s = "WHILE";
  ELSE res := FALSE
  END;
  RETURN res
END IsReservedOberonWord;

Ну вот, простейшая хеш-таблица вышла )))
Название: Re: Раскручиваем компилятор O7
Отправлено: igor от Ноябрь 08, 2013, 08:03:09 am
Ну вот, простейшая хеш-таблица вышла )))
Так и есть :-)

---------
К слову сказать, этот пример иллюстрирует, что оператор CASE это всё-таки нечто большее, чем просто синтаксический сахар. В случае использования равноценного многоветочного IF компилятору пришлось бы проанализировать условия во всех ветках для того чтобы понять сможет ли он сгенерировать эффективную таблицу переходов, или придётся генерировать код как для обычного IF'а.
Название: Re: Раскручиваем компилятор O7
Отправлено: Geniepro от Ноябрь 08, 2013, 08:44:48 am
К слову сказать, этот пример иллюстрирует, что оператор CASE это всё-таки нечто большее, чем просто синтаксический сахар. В случае использования равноценного многоветочного IF компилятору пришлось бы проанализировать условия во всех ветках для того чтобы понять сможет ли он сгенерировать эффективную таблицу переходов, или придётся генерировать код как для обычного IF'а.

Так и с CASE'ом тоже самое -- придётся анализировать, в каких диапазонах находятся эти метки и диапазоны меток, сортировать их, решать, можно ли сделать всё одной таблицей переходов или же придётся делать несколько таблиц переходов, или вообще проще IF-ами всё сравнивать...
Особой разницы для автора компилятора нет...
Название: Re: Раскручиваем компилятор O7
Отправлено: igor от Ноябрь 08, 2013, 09:28:51 am
Так и с CASE'ом тоже самое -- придётся анализировать, в каких диапазонах находятся эти метки и диапазоны меток, сортировать их, решать, можно ли сделать всё одной таблицей переходов или же придётся делать несколько таблиц переходов, или вообще проще IF-ами всё сравнивать...
Особой разницы для автора компилятора нет...
Да, пожалуй. Значения меток выбора в общем случае могут быть сильно разряжены и располагаться неравномерно. С построением таблицы переходов могут возникнуть сложности:
VAR a: LONGINT;
CASE a OF
| -100500: ... ;
| 0, 1: ... ;
| 100500: ... ;
END
Название: Re: Раскручиваем компилятор O7
Отправлено: valexey_u от Ноябрь 08, 2013, 09:33:50 am
Так и с CASE'ом тоже самое -- придётся анализировать, в каких диапазонах находятся эти метки и диапазоны меток, сортировать их, решать, можно ли сделать всё одной таблицей переходов или же придётся делать несколько таблиц переходов, или вообще проще IF-ами всё сравнивать...
Особой разницы для автора компилятора нет...
Да, пожалуй. Значения меток выбора в общем случае могут быть сильно разряжены и располагаться неравномерно. С построением таблицы переходов могут возникнуть сложности:
VAR a: LONGINT;
CASE a OF
| -100500: ... ;
| 0, 1: ... ;
| 100500: ... ;
END
Не сложности, а даже невозможности :-) Идеальную хэш-функцию не построить в общем случае.

И как тут, в сосденей ветке, надавно заметили, репорт Оберона не запрещает меткам пересекаться. Что добавляет веселья компиляторщику :-)
Название: Re: Раскручиваем компилятор O7
Отправлено: igor от Ноябрь 08, 2013, 09:56:38 am
Не сложности, а даже невозможности :-) Идеальную хэш-функцию не построить в общем случае.
К счастью, в нашем случае с ключевыми словами таких проблем не возникает. Хотя, надо сказать, что нет гарантии того, что какой-либо автор компилятора у себя в коде всё сделал правильно. :-)
Название: Re: Раскручиваем компилятор O7
Отправлено: Geniepro от Ноябрь 08, 2013, 10:09:17 am
Да, пожалуй. Значения меток выбора в общем случае могут быть сильно разряжены и располагаться неравномерно. С построением таблицы переходов могут возникнуть сложности:
VAR a: LONGINT;
CASE a OF
| -100500: ... ;
| 0, 1: ... ;
| 100500: ... ;
END
Не сложности, а даже невозможности :-) Идеальную хэш-функцию не построить в общем случае.

И как тут, в сосденей ветке, надавно заметили, репорт Оберона не запрещает меткам пересекаться. Что добавляет веселья компиляторщику :-)[/quote]

А учитывая, что в качестве меток могут быть не только константы, но и переменные, а также строковые литералы, совсем весело становится с таблицей переходов )))
Название: Re: Раскручиваем компилятор O7
Отправлено: valexey_u от Ноябрь 08, 2013, 10:19:16 am
А учитывая, что в качестве меток могут быть не только константы, но и переменные, а также строковые литералы, совсем весело становится с таблицей переходов )))

Ну, это не совсем таки так:
Цитировать
The case expression must be of type INTEGER or CHAR, and all labels must be integers or single-character strings, respectively.

А вот про константность того что в label'e действительно не сказано, хотя явно же ident там оставлен для именованных констант а не для переменных.
Название: Re: Раскручиваем компилятор O7
Отправлено: adva от Ноябрь 09, 2013, 02:13:20 pm
Наверняка такая мысль высказывалась уже. Но думаю цикл дейкстры в первую очередь удобен там, где после обычного цикла надо обработать еще что-то (прямо связанное с данным циклом). Правда в этом случае удобнее было бы сделать не ELSIF DO а просто ELSE и дальше уже условия цикла не проверять.
Название: Re: Раскручиваем компилятор O7
Отправлено: Valery Solovey от Ноябрь 10, 2013, 01:01:36 pm
Не для этого нужен ЦД. Это цикл, содержащий внутри себя последовательность циклов.
Название: Re: Раскручиваем компилятор O7
Отправлено: Peter Almazov от Ноябрь 10, 2013, 06:13:24 pm
- Почему в популярны языках нет Цикла Дейкстры?
- Потому что он там нинужен

:)
Если бы Влад изначально не заморочил мозги циклом Дейкстры, то выяснилось бы, что он и в этом примере нахрен не нужен.
    static bool isReservedWorld2(string s, string words) {
      int i = 0, w = 0;
      bool prevEq = true;
      while ((w < words.Length) && (i < s.Length)) {
        if (prevEq && (words[w] == s[i])) {
          i++;
        } else if (words[w] == ' ') {
          if (prevEq) {
            i = 0;
          } else {
            prevEq = true;
          }
        } else if (prevEq) {
          prevEq = false;
          i = 0;
        }
        w++;
      }
      return i == s.Length && (w == words.Length || words[w] == ' ');
    }
Название: Re: Раскручиваем компилятор O7
Отправлено: kkkk от Ноябрь 10, 2013, 08:21:29 pm
С учетом всех тем, где упоминался цикл Дейкстры, что я наблюдал, можно прийти к выводу, что в мире современных программистов ЦД - могучий артефакт, притягивающий к себе внимание вне зависимости от его целесообразности в конкретном случае. Знай бы об этом Никлаус Вирт, вероятно, захотел бы и его исключить из языка. Но с точки зрения маркетинга такая скандалообразующая штука безусловно полезна.
Название: Re: Раскручиваем компилятор O7
Отправлено: Geniepro от Ноябрь 10, 2013, 08:42:25 pm
С учетом всех тем, где упоминался цикл Дейкстры, что я наблюдал, можно прийти к выводу, что в мире современных программистов ЦД - могучий артефакт, притягивающий к себе внимание вне зависимости от его целесообразности в конкретном случае. Знай бы об этом Никлаус Вирт, вероятно, захотел бы и его исключить из языка. Но с точки зрения маркетинга такая скандалообразующая штука безусловно полезна.

Самое смешное -- это то, что в Обероне нет цикла Дейкстры. Есть цикл, синтаксически напоминающий цикл Дейкстры, но семантически всё-таки отличающийся от него...
Впрочем, настоящего ветвления Дейкстры в Оберонах/Модулах-2 тоже нет, есть ветвление, лишь синтаксически напоминающее его.
Название: Re: Раскручиваем компилятор O7
Отправлено: valexey_u от Ноябрь 10, 2013, 08:53:43 pm
С учетом всех тем, где упоминался цикл Дейкстры, что я наблюдал, можно прийти к выводу, что в мире современных программистов ЦД - могучий артефакт, притягивающий к себе внимание вне зависимости от его целесообразности в конкретном случае. Знай бы об этом Никлаус Вирт, вероятно, захотел бы и его исключить из языка. Но с точки зрения маркетинга такая скандалообразующая штука безусловно полезна.

Самое смешное -- это то, что в Обероне нет цикла Дейкстры. Есть цикл, синтаксически напоминающий цикл Дейкстры, но семантически всё-таки отличающийся от него...
Впрочем, настоящего ветвления Дейкстры в Оберонах/Модулах-2 тоже нет, есть ветвление, лишь синтаксически напоминающее его.
Предлагаю раскрыть мысль, дабы народ сейчас не нафантазировал чего-то странного.
Название: Re: Раскручиваем компилятор O7
Отправлено: adva от Ноябрь 10, 2013, 09:54:18 pm
Не для этого нужен ЦД. Это цикл, содержащий внутри себя последовательность циклов.
Да, но мозги при этом сломаешь больше, чем с обычными циклами. Да и условий дополнительных писать
Название: Re: Раскручиваем компилятор O7
Отправлено: vlad от Ноябрь 11, 2013, 03:13:11 am
С учетом всех тем, где упоминался цикл Дейкстры, что я наблюдал, можно прийти к выводу, что в мире современных программистов ЦД - могучий артефакт, притягивающий к себе внимание вне зависимости от его целесообразности в конкретном случае.

Да не. Просто после той мощной рекламной компании, которую устроил info21 для Цикла Дейкстры, хотелось найти хоть одно осмысленное применение на практике. А тут как раз язык с непосредственной поддержкой этого чуда. Вот и теперь, даже Петр Алмазов сказал, что Цикл Дейкстры тут не нужен. Будем искать :)
Название: Re: Раскручиваем компилятор O7
Отправлено: albobin от Ноябрь 11, 2013, 04:47:14 am
Нет и мне успокоения :) 

Чуть подправлю свой последний вариант.
1. Без предположения, что слова в words отсортированы.
После последнего слова пробел обязателен.
PROCEDURE isReservedWorld(s: JsString.Type; words: JsString.Type): BOOLEAN;
VAR
    i, w, с: INTEGER;
BEGIN
    i := 0 ;
    w := 0 ;
    с := 0;
    WHILE (w < JsString.len(words))
        & ((с < JsString.len(s)) OR (i # JsString.len(s)) OR (JsString.at(words, w) # " ")) DO
        IF (i < JsString.len(s)) & (JsString.at(words, w) = JsString.at(s, i)) THEN
            INC(i);
            INC(c);
        ELSIF (JsString.at(words, w) # " ") THEN
            INC(i);
        ELSE
            i := 0;
            c := 0;
        END;
        INC(w);
    END;
    RETURN (w < JsString.len(words))
END isReservedWorld;

2. Если строка слов отсортирована, то
условие WHILE сокращается до
    WHILE (w < JsString.len(words))
        & (с < JsString.len(s)) DO
В этом случае будет выходить по первому совпадению проверяемого слова s с началом некоторого слова из words.
Возврат из функции тогда усиливается добавкой
    RETURN ((w < JsString.len(words)) & (JsString.at(words, w) = " "))
Название: Re: Раскручиваем компилятор O7
Отправлено: Geniepro от Ноябрь 11, 2013, 06:17:23 am
Самое смешное -- это то, что в Обероне нет цикла Дейкстры. Есть цикл, синтаксически напоминающий цикл Дейкстры, но семантически всё-таки отличающийся от него...
Впрочем, настоящего ветвления Дейкстры в Оберонах/Модулах-2 тоже нет, есть ветвление, лишь синтаксически напоминающее его.

Предлагаю раскрыть мысль, дабы народ сейчас не нафантазировал чего-то странного.

Ну сколько ж можно раскрывать эту простую мысль? Я об этом много раз повторял (больше трёх точно).
Вспоминаем, что Дейкстра писал в своей "Дисциплине программироания" про оператор if (и аналогичные рассуждения по поводу оператора do):

if B1 → SL1 □ B2 → SL2 □ ... □ Bn → SLn fi
do B1 → SL1 □ B2 → SL2 □ ... □ Bn → SLn do

где B1...Bn -- "предохранители", логические выражения охраняемых команд,
SL1...SLn -- списки операторов,
а B1 → SL1 -- охраняемая команда

Цитата: Эдсгар Дейкстра
1. Предполагается, что все предохранители определены; если это не так, т.е. вычисление какого-то предохранителя может привести к работе без правильного завершения, то допускается, что и вся конструкция не сможет правильно завершить свою работу.

2. Вообще говоря, наша конструкция приведёт к недетерменированности при тех начальных состояниях, для которых истинны значения более чем одного предохранителя, поскольку остаётся неопределённым, какой из соответствующих списков операторов будет тогда выбираться для запуска. Никакой недетерменированности не возникает, если все предохранители попарно исключают друг друга.

3. Если начальное состояние таково, что ни один из предохранителей не является истиной, то мы встречаемся с начальным состоянием, для которого не подходит ни один из вариантов, а следовательно, и вся конструкция в целом. Запуск при таком начальном состоянии приведёт к отказу.

Замечание. Если мы допускаем также и пустой набор охраняемых команд, то операторы "if-fi" и "do-od" семантически эквивалентны нашему прежнему оператору "Отказать".

Таким образом, для того, что бы операторы IF и WHILE в Обероне могли считаться операторами if и do Дейкстры (назовём их "Ветвлением Дейкстры" и "Циклом Дейкстры"), их предохранители быть написаны в предположении недетерменированного порядка вычисления, и если ни один из предохранителей не срабатывает, должен происходить авост (HALT).

В рапорте об Обероне же прямо сказано:
Цитата: Никлаус Вирт
The Boolean expression preceding a statement is called its guard. The guards are evaluated in sequence of occurrence, until one evaluates to TRUE, whereafter its associated statement sequence is executed. If no guard is satisfied, the statement sequence following the symbol ELSE is executed, if there is one.
...
While statements specify repetition. If any of the Boolean expressions (guards) yields TRUE, the corresponding statement sequence is executed. The expression evaluation and the statement execution are repeated until none of the Boolean expressions yields TRUE.
То есть семантика этих операторов отличается.

ЗЫ. Кстати, сам Дейкстра отнюдь не гнушался делать вложенные циклы и циклы с условиями внутри, а вовсе не всегда заморачивался с циклом своего имени. Например:
x, y, z := X, Y, 1;
do y ≠ 0 → do 2 | y → x, y := x*x, y/2 od;
           y, z := y − 1, z*x
od {R стало истинным}
илиx, y, z := X, Y, 1;
do y<>0 → if non 2|y → y, z := y − 1, z*x
           □   2|y   → пропустить fi;
          x, y := x*x, y/2
od
хотя, казалось бы, уж здесь-то самое ему (ЦД) место...
Название: Re: Раскручиваем компилятор O7
Отправлено: kkkk от Ноябрь 11, 2013, 08:57:04 am
Да не. Просто после той мощной рекламной компании, которую устроил info21 для Цикла Дейкстры, хотелось найти хоть одно осмысленное применение на практике. А тут как раз язык с непосредственной поддержкой этого чуда. Вот и теперь, даже Петр Алмазов сказал, что Цикл Дейкстры тут не нужен. Будем искать :)
Гм, я вроде бы и не ищу применимости ЦД, а тем не менее время от времени натыкаюсь на такие места, где он подходит, но никогда в работе его не использую, поскольку эмулировать его явно либо через макросы мне нравится. А в Обероне бы пошло.
Например, есть сканер, в котором работа с потоком данных ведётся с явными блоками памяти вместо абстракции посимвольного чтения над буферизированными данными. Это приводит к тому, что лексема может быть разделена между блоками. У меня чтение лексемы выглядит приблизительно так:
WHILE Suitable(buf[i]) DO
INC(i)
ELSIF buf[i] = NewPage DO
NextPage(buf, i, input)
END
Название: Re: Раскручиваем компилятор O7
Отправлено: albobin от Ноябрь 11, 2013, 09:03:40 am
Пару слов в "защиту" прав  ЦД  на жизнь :)
Мне кажется, что все сомнения в нужности ЦД, возникают из-за неучета нюансов просто циклов и циклов поиска.
Просто цикл - это когда нет бинарной интерпретации результата работы цикла, типа успешно/неуспешно и т.п.
В этом случае ЦД как обобщённый вариант вообще не должен вызывать никаких сомнений.
WHILE ~X  DO ... END     условие окончания  X=TRUE ( или просто X)
соответственно для ЦД
WHILE ~X1 DO ...
ELSIF ~X2  DO ...
...
ELSIF ~Xn DO ...
END
условие окончания X1&X2&....Xn

В цикле поиска, грубо говоря, X=TRUE может и не наступить, поэтому условие WHILE должно это учитывать.
WHILE ~E & ~X  DO ... END
условие окончания  E OR X.    Заданные условия E и X желательно должны быть таковы, что после окончания цикла выполнялось X=~E

Так вот в данном случае проблема для ЦД в том что  условие выхода X1&X2&...Xn должно быть наглядно представимо в форме E OR X

Название: Re: Раскручиваем компилятор O7
Отправлено: Peter Almazov от Ноябрь 11, 2013, 09:46:14 am
Например, есть сканер, в котором работа с потоком данных ведётся с явными блоками памяти вместо абстракции посимвольного чтения над буферизированными данными.

1. Во многих случаях ЦД - это смешение разных уровней абстракций.
Название: Re: Раскручиваем компилятор O7
Отправлено: kkkk от Ноябрь 11, 2013, 10:20:02 am
Так плохо это или хорошо?
В приведенном примере я отказался от лишнего слоя абстракции чтобы избавиться от ненужного кода и накладных расходов, связанных с ним. ЦД позволил сделать это просто. Теперь не нужно абстрагироваться над буфером, чтобы потом складывать прочитанное в другой буфер, потому что иначе неудобно.
Название: Re: Раскручиваем компилятор O7
Отправлено: Peter Almazov от Ноябрь 11, 2013, 10:25:58 am
Как говорится, it depends.
Но лозунг "Смело смешивайте разные уровни абстракции!" я бы не поддержал  :)
Название: Re: Раскручиваем компилятор O7
Отправлено: vlad от Ноябрь 11, 2013, 03:36:22 pm
Например, есть сканер, в котором работа с потоком данных ведётся с явными блоками памяти вместо абстракции посимвольного чтения над буферизированными данными.

Можно было бы отнести ЦД к разряду оптимизационных вещей (со всеми оговорками), если бы он не страдал (как правило) от пессимизации в виде многократного дублирования повторяющихся условий.
Название: Re: Раскручиваем компилятор O7
Отправлено: kkkk от Ноябрь 11, 2013, 07:03:39 pm
По сравнению с LOOP EXIT END цикл Дейкстры не несёт никаких оптимизаций, а только отсекает излишнию гибкость неструктурного цикла. Конечно, явная поддержка конструкции в языке даст оптимизирующему компилятору больше возможностей для ускорения, но такой компилятор выкинет и повторяющиеся проверки. Только это не в стиле Оберона, тем более что по моему опыту основной удар принимает первая ветка и повторные проверки не оказывают существенного влияния на время исполнения.