Автор Тема: Раскручиваем компилятор O7  (Прочитано 40758 раз)

vlad

  • Hero Member
  • *****
  • Сообщений: 1391
    • Просмотр профиля
Re: Раскручиваем компилятор O7
« Ответ #30 : Ноябрь 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;

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re: Раскручиваем компилятор O7
« Ответ #31 : Ноябрь 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 *)

ЗЫ. Вот, кстати, яркий пример, что мало кто читает руководства по стилю кодирования. Какой смысл их писать?.. :'(
to iterate is human, to recurse, divine

Салат «рекурсия»: помидоры, огурцы, салат…

adva

  • Sr. Member
  • ****
  • Сообщений: 385
    • Просмотр профиля
Re: Раскручиваем компилятор O7
« Ответ #32 : Ноябрь 06, 2013, 07:39:05 am »
С самим циклом не разбирался, но попутно вопрос возник, разве там w не надо присваивать перед циклом?

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Re: Раскручиваем компилятор O7
« Ответ #33 : Ноябрь 06, 2013, 08:01:20 am »
С самим циклом не разбирался, но попутно вопрос возник, разве там w не надо присваивать перед циклом?
Да и i тоже :-)
Y = λf.(λx.f (x x)) (λx.f (x x))

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re: Раскручиваем компилятор O7
« Ответ #34 : Ноябрь 06, 2013, 08:17:23 am »
С самим циклом не разбирался, но попутно вопрос возник, разве там w не надо присваивать перед циклом?

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

Там же в компиляторе сделано, что всем переменным по умолчанию присваиваются нулевые значения -- числам нули, указателям nil...
to iterate is human, to recurse, divine

Салат «рекурсия»: помидоры, огурцы, салат…

adva

  • Sr. Member
  • ****
  • Сообщений: 385
    • Просмотр профиля
Re: Раскручиваем компилятор O7
« Ответ #35 : Ноябрь 06, 2013, 08:17:39 am »
С самим циклом не разбирался, но попутно вопрос возник, разве там w не надо присваивать перед циклом?
Да и i тоже :-)
Тоже не надо, или тоже надо :) ?

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Re: Раскручиваем компилятор O7
« Ответ #36 : Ноябрь 06, 2013, 08:18:28 am »
С самим циклом не разбирался, но попутно вопрос возник, разве там w не надо присваивать перед циклом?

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

Там же в компиляторе сделано, что всем переменным по умолчанию присваиваются нулевые значения -- числам нули, указателям nil...
Какая разница как именно в конкретной реализации это сделано? Язык не гарантирует, следовательно будет UB.
Y = λf.(λx.f (x x)) (λx.f (x x))

adva

  • Sr. Member
  • ****
  • Сообщений: 385
    • Просмотр профиля
Re: Раскручиваем компилятор O7
« Ответ #37 : Ноябрь 06, 2013, 08:18:57 am »
Там же в компиляторе сделано, что всем переменным по умолчанию присваиваются нулевые значения -- числам нули, указателям nil...

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

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re: Раскручиваем компилятор O7
« Ответ #38 : Ноябрь 06, 2013, 08:34:49 am »
Там же в компиляторе сделано, что всем переменным по умолчанию присваиваются нулевые значения -- числам нули, указателям nil...

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

В сообщении о языке я на эту тему ничего не нашёл -- там вообще нет ни одного вхождения слова "default".
Похоже, судя по сообщению эти значения не поределены (undefined)...
to iterate is human, to recurse, divine

Салат «рекурсия»: помидоры, огурцы, салат…

vlad

  • Hero Member
  • *****
  • Сообщений: 1391
    • Просмотр профиля
Re: Раскручиваем компилятор O7
« Ответ #39 : Ноябрь 06, 2013, 02:44:33 pm »
Ну, в данном случае проблема в том, что у операций сравнения одинаковый приоритет.

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

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

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

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

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

ЗЫ. Вот, кстати, яркий пример, что мало кто читает руководства по стилю кодирования. Какой смысл их писать?.. :'(

Я читал их в свое время. Они мне показались полностью согласующимися с моим стилем. Поэтому я даже на заметку не стал брать. Что не так?
« Последнее редактирование: Ноябрь 06, 2013, 02:47:28 pm от vlad »

vlad

  • Hero Member
  • *****
  • Сообщений: 1391
    • Просмотр профиля
Re: Раскручиваем компилятор O7
« Ответ #40 : Ноябрь 06, 2013, 03:04:14 pm »
В сообщении о языке я на эту тему ничего не нашёл -- там вообще нет ни одного вхождения слова "default".
Похоже, судя по сообщению эти значения не определены (undefined)...

В репорте сказано, что значения локальных переменных на входе в процедуру не определены (при этом, конечно, они могут иметь и нулевые значения). Т.е., да - по репорту это чистой воды UB .
С другой стороны, лично я считаю этот момент принципиальным, поэтому в своей реализации я сделал уточнение.
В ББ этот момент тоже считают принципиальным (герметичность типов, не хухры-мухры), но не до конца - там обнуляют только указатели. Их можно понять - 90-е годы, Си все еще популярен и там неопределенные переменные в порядке вещей.

Valery Solovey

  • Hero Member
  • *****
  • Сообщений: 509
    • Просмотр профиля
Re: Раскручиваем компилятор O7
« Ответ #41 : Ноябрь 06, 2013, 10:20:50 pm »
Ну так что, правильно цикл работает?

vlad

  • Hero Member
  • *****
  • Сообщений: 1391
    • Просмотр профиля
Re: Раскручиваем компилятор O7
« Ответ #42 : Ноябрь 06, 2013, 10:49:12 pm »
Ну так что, правильно цикл работает?

Тесты проходят. Но он страшный. Поэтому уверенности нет. Хотелось одобрения экспертов.

albobin

  • Full Member
  • ***
  • Сообщений: 198
    • Просмотр профиля
Re: Раскручиваем компилятор O7
« Ответ #43 : Ноябрь 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;
« Последнее редактирование: Ноябрь 07, 2013, 05:58:19 am от albobin »

albobin

  • Full Member
  • ***
  • Сообщений: 198
    • Просмотр профиля
Re: Раскручиваем компилятор O7
« Ответ #44 : Ноябрь 07, 2013, 06:00:27 am »
PS.
RETURN ok

« Последнее редактирование: Ноябрь 07, 2013, 06:03:10 am от albobin »