Автор Тема: [Oberon7] "Man or Boy test" by Donald Knuth  (Прочитано 47014 раз)

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Re: [Oberon7] "Man or Boy test" by Donald Knuth
« Ответ #45 : Июль 08, 2013, 02:24:40 pm »
Народ, правильно ли я понял, что сий замечательный тест Кнута позволил выявить странный баг в компиляторе АО? То есть тест оказался таки полезным для одного из потомков Алгола-60?
Пока неясно, может проблема связана с выравниванием в процессорах AMD, надо на интеле проверять
Наврятли это баг процессора. Так что, опять таки, даже если это из за специфического выравнивания, то это баг компилятора.
Y = λf.(λx.f (x x)) (λx.f (x x))

vlad

  • Hero Member
  • *****
  • Сообщений: 1391
    • Просмотр профиля
Re: [Oberon7] "Man or Boy test" by Donald Knuth
« Ответ #46 : Июль 08, 2013, 03:49:00 pm »
Совершенно правильное ограничение.... дабы отсекать сами попытки ваять такую замудрённую и двусмысленную чушь, как протаскивание контекстов процедур и т.п.

Ну будет у тебя оформлено замыкание в виде кошерного объекта (хотя я ни разу не согласен, что это всегда нагляднее). Конкретно данный алгоритм все равно требует NEW, потому что в обероне нельзя получить указатель/ссылку на локальную RECORD. Или я что-то пропустил? Вообще хотелось бы увидеть решение на обероне - у меня с наскоку не получилось - слишком много кода получается и страшно. Можно начать с решения для ББ, потому что в О7 с "оформлением в виде объекта" возникает ненужный мусор.

В том же JS "эти ваши замыкания" используются направо и налево от отсутствия модульности и удобного "не-ассемблерного" ООП

Ой, только не надо начинать про жабаскрипт...

Kemet

  • Hero Member
  • *****
  • Сообщений: 587
    • Просмотр профиля
Re: [Oberon7] "Man or Boy test" by Donald Knuth
« Ответ #47 : Июль 08, 2013, 03:59:11 pm »
Наврятли это баг процессора. Так что, опять таки, даже если это из за специфического выравнивания, то это баг компилятора.
Ну код-то не самомодифицирующийся ) он на протяжении всех 100 вызовов один и тот же и на всем протяжении стек опускается правильно - на 32 и 12 байт соответственно, и только на 5-м вызове B он вместо 12 байт опускается на 8 (и BP соответственно)

Kemet

  • Hero Member
  • *****
  • Сообщений: 587
    • Просмотр профиля
Re: [Oberon7] "Man or Boy test" by Donald Knuth
« Ответ #48 : Июль 08, 2013, 04:16:27 pm »
вот как это выглядит:
TestMR@763 - процедура A
TestMR@497 - процедура B
TestMR@1652:currentSP= 67502080; (currentSP DIV 1024)= 65920;

TestMR@763:ADDRESSOF(k)= 0405FF38H; currentSP= 67501852; (prevSP - currentSP)= 32;
TestMR@497:ADDRESSOF(k)= 0405FF38H; currentSP= 67501840; (prevSP - currentSP)= 12;
TestMR@763:ADDRESSOF(k)= 0405FF0CH; currentSP= 67501808; (prevSP - currentSP)= 32;
TestMR@497:ADDRESSOF(k)= 0405FF0CH; currentSP= 67501796; (prevSP - currentSP)= 12;
TestMR@763:ADDRESSOF(k)= 0405FEE0H; currentSP= 67501764; (prevSP - currentSP)= 32;
TestMR@497:ADDRESSOF(k)= 0405FEE0H; currentSP= 67501752; (prevSP - currentSP)= 12;
TestMR@763:ADDRESSOF(k)= 0405FEB4H; currentSP= 67501720; (prevSP - currentSP)= 32;
TestMR@497:ADDRESSOF(k)= 0405FEB4H; currentSP= 67501708; (prevSP - currentSP)= 12;
TestMR@763:ADDRESSOF(k)= 0405FE88H; currentSP= 67501676; (prevSP - currentSP)= 32;
TestMR@497:ADDRESSOF(k)= 0405FEA8H; currentSP= 67501668; (prevSP - currentSP)= 8;
TestMR@763:ADDRESSOF(k)= 0405FE60H; currentSP= 67501636; (prevSP - currentSP)= 32;
TestMR@497:ADDRESSOF(k)= 0405FE60H; currentSP= 67501624; (prevSP - currentSP)= 12;
TestMR@763:ADDRESSOF(k)= 0405FE34H; currentSP= 67501592; (prevSP - currentSP)= 32;
TestMR@497:ADDRESSOF(k)= 0405FE34H; currentSP= 67501580; (prevSP - currentSP)= 12;
TestMR@763:ADDRESSOF(k)= 0405FE08H; currentSP= 67501548; (prevSP - currentSP)= 32;
TestMR@497:ADDRESSOF(k)= 0405FE08H; currentSP= 67501536; (prevSP - currentSP)= 12;
TestMR@763:ADDRESSOF(k)= 0405FDDCH; currentSP= 67501504; (prevSP - currentSP)= 32;
TestMR@497:ADDRESSOF(k)= 0405FDDCH; currentSP= 67501492; (prevSP - currentSP)= 12;
TestMR@763:ADDRESSOF(k)= 0405FDB0H; currentSP= 67501460; (prevSP - currentSP)= 32;
TestMR@497:ADDRESSOF(k)= 0405FDB0H; currentSP= 67501448; (prevSP - currentSP)= 12;
TestMR@763:ADDRESSOF(k)= 0405FD84H; currentSP= 67501416; (prevSP - currentSP)= 32;
TestMR@497:ADDRESSOF(k)= 0405FD84H; currentSP= 67501404; (prevSP - currentSP)= 12;
TestMR@763:ADDRESSOF(k)= 0405FD58H; currentSP= 67501372; (prevSP - currentSP)= 32;
TestMR@497:ADDRESSOF(k)= 0405FD58H; currentSP= 67501360; (prevSP - currentSP)= 12;
TestMR@763:ADDRESSOF(k)= 0405FD2CH; currentSP= 67501328; (prevSP - currentSP)= 32;
TestMR@497:ADDRESSOF(k)= 0405FD2CH; currentSP= 67501316; (prevSP - currentSP)= 12;
TestMR@763:ADDRESSOF(k)= 0405FD00H; currentSP= 67501284; (prevSP - currentSP)= 32;
TestMR@497:ADDRESSOF(k)= 0405FD00H; currentSP= 67501272; (prevSP - currentSP)= 12;
TestMR@763:ADDRESSOF(k)= 0405FCD4H; currentSP= 67501240; (prevSP - currentSP)= 32;
TestMR@497:ADDRESSOF(k)= 0405FCD4H; currentSP= 67501228; (prevSP - currentSP)= 12;
...

Kemet

  • Hero Member
  • *****
  • Сообщений: 587
    • Просмотр профиля
Re: [Oberon7] "Man or Boy test" by Donald Knuth
« Ответ #49 : Июль 08, 2013, 04:59:52 pm »
блин, тормоз, там, где стек опустился на 8-м - k стало равно 0, поэтому вызова B небыло.

Kemet

  • Hero Member
  • *****
  • Сообщений: 587
    • Просмотр профиля
Re: [Oberon7] "Man or Boy test" by Donald Knuth
« Ответ #50 : Июль 08, 2013, 05:03:11 pm »
ыыыы, целые в Оберонах = знаковые, вот тут она проблема и вылезла, твою мать

Kemet

  • Hero Member
  • *****
  • Сообщений: 587
    • Просмотр профиля
Re: [Oberon7] "Man or Boy test" by Donald Knuth
« Ответ #51 : Июль 08, 2013, 05:21:09 pm »
хотя, не, это я не подумавши

Kemet

  • Hero Member
  • *****
  • Сообщений: 587
    • Просмотр профиля
Re: [Oberon7] "Man or Boy test" by Donald Knuth
« Ответ #52 : Июль 09, 2013, 05:24:53 pm »
Но можешь WinAos попробовать.
Я как раз WinAOS и пробовал...
Перезалил полное дерево исходников А2 на на GitHub. Это точно работает, ибо это одна из моих рабочих копий. Основана на ревизии 5348 (текущая 5355).
По сравнению с оригиналом поправлено 4 файла(поправлены сигнатуры нескольких процедур в UDP.Mod для синхронизации с изменениями интерфейса, в оригинале изменения внести видимо забыли, поправлен мелкий баг в FoxCompiler.Mod - перепутан порядок следования параметров, убрана зависимость от Streams в FATVolumes и заменен pci.ids на свежий). Эти изменения не затрагивают WinAos.
Ну и полностью пересобраны модули WinAos.

vlad

  • Hero Member
  • *****
  • Сообщений: 1391
    • Просмотр профиля
Re: [Oberon7] "Man or Boy test" by Donald Knuth
« Ответ #53 : Июль 10, 2013, 06:34:37 am »
Итак, работающее решение на O7. Обратите внимание на приседание с дополнительной процедурной переменной pB - из-за невозможности предварительно задекларировать B. Может кто-нибудь предложит более элегантное решение, ибо текущее просто ужасно.
MODULE test;
IMPORT JS;

TYPE
    PState = POINTER TO State;
    Function = PROCEDURE(s: PState): INTEGER;
    State = RECORD
        f: Function;
        k: INTEGER;
        x1, x2, x3, x4, x5: PState
    END;

VAR
    pB: Function;
    init: PState;

PROCEDURE call(s: PState): INTEGER;
    RETURN s.f(s)
END call;

PROCEDURE makeEmptyState(f: Function): PState;
VAR
    result: PState;
BEGIN
    NEW(result);
    result.f := f;
    RETURN result
END makeEmptyState;

PROCEDURE makeState(f: Function; k: INTEGER; x1, x2, x3, x4, x5: PState): PState;
VAR
    result: PState;
BEGIN
    result := makeEmptyState(f);
    result.k := k;
    result.x1 := x1;
    result.x2 := x2;
    result.x3 := x3;
    result.x4 := x4;
    result.x5 := x5;
    RETURN result
END makeState;

PROCEDURE F0(s: PState):  INTEGER; BEGIN RETURN  0 END F0;
PROCEDURE F1(s: PState):  INTEGER; BEGIN RETURN  1 END F1;
PROCEDURE Fn1(s: PState): INTEGER; BEGIN RETURN -1 END Fn1;

PROCEDURE A(s: PState): INTEGER;
VAR
    res: INTEGER;
BEGIN
  IF s.k <= 0 THEN
    res := call(s.x4) + call(s.x5);
  ELSE
    res := call(makeState(pB, s.k, s.x1, s.x2, s.x3, s.x4, s.x5));
  END;
  RETURN res
END A;

PROCEDURE B(s: PState): INTEGER;
BEGIN
    DEC(s.k);
    RETURN call(makeState(A, s.k, s, s.x1, s.x2, s.x3, s.x4))
END B;

BEGIN
    pB := B;
    JS.alert(call(makeState(
        A,
        10,
        makeEmptyState(F1),
        makeEmptyState(Fn1),
        makeEmptyState(Fn1),
        makeEmptyState(F1),
        makeEmptyState(F0))))
END test.

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re: [Oberon7] "Man or Boy test" by Donald Knuth
« Ответ #54 : Июль 10, 2013, 07:56:52 am »
Итак, работающее решение на O7. Обратите внимание на приседание с дополнительной процедурной переменной pB - из-за невозможности предварительно задекларировать B.

А что, Вирт убрал из Оберона forward declarations? о_О
to iterate is human, to recurse, divine

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

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Re: [Oberon7] "Man or Boy test" by Donald Knuth
« Ответ #55 : Июль 10, 2013, 09:01:20 am »
Итак, работающее решение на O7. Обратите внимание на приседание с дополнительной процедурной переменной pB - из-за невозможности предварительно задекларировать B.

А что, Вирт убрал из Оберона forward declarations? о_О
Да. Как лишнюю сущность, которая дублирует уже имеющиеся процедурные типы.
Y = λf.(λx.f (x x)) (λx.f (x x))

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re: [Oberon7] "Man or Boy test" by Donald Knuth
« Ответ #56 : Июль 10, 2013, 10:06:18 am »
Итак, работающее решение на O7. Обратите внимание на приседание с дополнительной процедурной переменной pB - из-за невозможности предварительно задекларировать B.

А что, Вирт убрал из Оберона forward declarations? о_О
Да. Как лишнюю сущность, которая дублирует уже имеющиеся процедурные типы.

Я понимаю там в хаскелле/сишарпе forward declarations не нужны -- весь модуль/класс просматривается при поиске нужной процедуры, переменной или типа , но в обероне...
Жестокое упрощение языка...
to iterate is human, to recurse, divine

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

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Re: [Oberon7] "Man or Boy test" by Donald Knuth
« Ответ #57 : Июль 10, 2013, 10:48:58 am »
Итак, работающее решение на O7. Обратите внимание на приседание с дополнительной процедурной переменной pB - из-за невозможности предварительно задекларировать B.

А что, Вирт убрал из Оберона forward declarations? о_О
Да. Как лишнюю сущность, которая дублирует уже имеющиеся процедурные типы.

Я понимаю там в хаскелле/сишарпе forward declarations не нужны -- весь модуль/класс просматривается при поиске нужной процедуры, переменной или типа , но в обероне...
Жестокое упрощение языка...
Дык лишняя сущность же!

Ну, на самом деле, если ослабить вот это требование: "The scope extends textually from the point of the declaration to the end of the block (procedure or module) to which the declaration belongs and hence to which the object is local." до "whole block (procedure or module)", то получится язык поприятнее для кодописателя (и чуть менее приятный для компилятороклепателя, хотя и тут выигрыш таки в итоге будет, ибо компилятор железно перестает быть однопроходным).
Y = λf.(λx.f (x x)) (λx.f (x x))

vlad

  • Hero Member
  • *****
  • Сообщений: 1391
    • Просмотр профиля
Re: [Oberon7] "Man or Boy test" by Donald Knuth
« Ответ #58 : Июль 10, 2013, 01:17:45 pm »
Да. Как лишнюю сущность, которая дублирует уже имеющиеся процедурные типы.

Лишняя сущность - это дополнительная переменная. Вобщем да, O7 это уже за гранью "но не проще".

P.S. Конечно же я ее забыл проинитить сначала.
P.S.S. Да, надо просто ослабить требование и искать во всем блоке.

vlad

  • Hero Member
  • *****
  • Сообщений: 1391
    • Просмотр профиля
Re: [Oberon7] "Man or Boy test" by Donald Knuth
« Ответ #59 : Июль 10, 2013, 04:54:05 pm »
- Вводится маркер для параметра процедуры (по аналогии с VAR), что этот параметр процедурного типа может быть локальной процедурой из процедуры выше по стеку. Например некий LOCAL:

Можно расширить эту идею и на указатели. Т.е., локальная переменная может быть приведена к LOCAL POINTER TO с теми же ограничениями и совместимостями. Тогда оригинальная задача тоже быть решена без обращения к куче и GC.