Автор Тема: Oberon-07M  (Прочитано 52382 раз)

igor

  • Sr. Member
  • ****
  • Сообщений: 438
    • Просмотр профиля
Re:Oberon-07M
« Ответ #75 : Март 22, 2011, 04:00:31 pm »
Маленькое замечание по "Hello, World!".
Необходимость в импорте Memory не очевидна (формально нигде не используется).
Понятно, что хотелось продемонстрировать работу с динамическими массивами, но всё же...

(Аналогичная картина с модулем Kernel в Блэкбокс, но там хотя бы есть оговорка в доках).

valexey

  • Administrator
  • Hero Member
  • *****
  • Сообщений: 1990
    • Просмотр профиля
Re:Oberon-07M
« Ответ #76 : Март 22, 2011, 04:23:01 pm »
Маленькое замечание по "Hello, World!".
Необходимость в импорте Memory не очевидна (формально нигде не используется).
Понятно, что хотелось продемонстрировать работу с динамическими массивами, но всё же...

(Аналогичная картина с модулем Kernel в Блэкбокс, но там хотя бы есть оговорка в доках).
Думаю когда ББ был на том же этапе развития, что и данный компилятор, в его доках тоже ничего не было :-)
"но сейчас, чтобы компенсировать растущую мощность компьютеров, программисты используют фреймворки"

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re:Oberon-07M
« Ответ #77 : Март 22, 2011, 04:38:39 pm »
Например, какое внутреннее промежуточное представление Вы используете? Или Вы транслируете дерево разбора напрямую сразу в машинный код? Вообще, есть какие-нибудь особенности в реализации компилятора, или всё по науке?  :)
В принципе, в духе оберонов компилировать всё сразу в машкод, ибо однопроходный компилятор. Так завещал Вирт...
to iterate is human, to recurse, divine

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

valexey

  • Administrator
  • Hero Member
  • *****
  • Сообщений: 1990
    • Просмотр профиля
Re:Oberon-07M
« Ответ #78 : Март 22, 2011, 04:46:48 pm »
На самом деле Вирт завещал компилировать в два прохода. Судя по его книжке по конструированию компиляторов. Разделять фронтенд и бэкенд. И это правильно.
"но сейчас, чтобы компенсировать растущую мощность компьютеров, программисты используют фреймворки"

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re:Oberon-07M
« Ответ #79 : Март 22, 2011, 05:28:04 pm »
Как-то читал, как японцы сделали персоналку (80-е годы вроде), у которой входным языком был паскаль, а не бейсик там или ассемблер.
Однопроходный компилятор компилил программу по мере её ввода строка за строкой ))
to iterate is human, to recurse, divine

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

valexey

  • Administrator
  • Hero Member
  • *****
  • Сообщений: 1990
    • Просмотр профиля
Re:Oberon-07M
« Ответ #80 : Март 22, 2011, 05:42:28 pm »
Как-то читал, как японцы сделали персоналку (80-е годы вроде), у которой входным языком был паскаль, а не бейсик там или ассемблер.
Однопроходный компилятор компилил программу по мере её ввода строка за строкой ))
Дык BeOS же изначально была написана под Hobbit (http://en.wikipedia.org/wiki/AT%26T_Hobbit) который по сути и есть Си-машина. И это не япония, это вполне себе США.
"но сейчас, чтобы компенсировать растущую мощность компьютеров, программисты используют фреймворки"

Rifat

  • Jr. Member
  • **
  • Сообщений: 62
    • Просмотр профиля
Re:Oberon-07M
« Ответ #81 : Март 22, 2011, 08:05:38 pm »
Про внутреннее представление. Сначала строится дерево разбора, если компляция прошла успешно, то по дереву разбора генерируется код.
Про оптимизацию. Фактически оптимизации нет, код генерируется наиболее прямолинейным способом. В дальнейшем, возможно, будут некоторые оптимизации.
Про пример. Да было желание продемонстрировать работу с динамическими массивами. Если динамическая память не используется, то Memory можно не компилировать и удалить его из prj файла, чтобы он не включался. Более того, можно не включать файл Kernel, но если произойдет прерывание работы программы, то никакой информации не будет. А модуль Kernel производит раскрутку стека и выводит информацию о процедурах, в которых произошла ошибка, в файл error.log.

igor

  • Sr. Member
  • ****
  • Сообщений: 438
    • Просмотр профиля
Re:Oberon-07M
« Ответ #82 : Март 23, 2011, 06:02:20 am »
На самом деле Вирт завещал компилировать в два прохода. Судя по его книжке по конструированию компиляторов. Разделять фронтенд и бэкенд. И это правильно.
Нет. Разделение на front-end и back-end не увеличивает число проходов. Под проходом понимается этап компиляции, на котором производится просмотр исходного текста от начала до конца.

igor

  • Sr. Member
  • ****
  • Сообщений: 438
    • Просмотр профиля
Re:Oberon-07M
« Ответ #83 : Март 23, 2011, 06:13:25 am »
Про внутреннее представление. Сначала строится дерево разбора, если компляция прошла успешно, то по дереву разбора генерируется код.
Про оптимизацию. Фактически оптимизации нет, код генерируется наиболее прямолинейным способом. В дальнейшем, возможно, будут некоторые оптимизации.
Понятно. Кстати, если планируется в дальнейшем вводить некоторые оптимизации, то может оказаться целесообразным ввести промежуточное представление, которое удобно для проведения этих оптимизаций. С оптимизациями главное не перемудрить.  :)

Rifat

  • Jr. Member
  • **
  • Сообщений: 62
    • Просмотр профиля
Re:Oberon-07M
« Ответ #84 : Март 25, 2011, 11:14:17 am »
Поясню на всякий случай – мы тут размер не знаем ни на этапе компиляции, ни на этапе исполнения. Если после вызова функции нам оно скажет что "нишмогла, не поместилась в буфер даденого размера", то стратегия проста – удваиваем размер буфера и пробуем снова. Для удваивания буфера, как я заметил выше, массивы с размером неизвестным на этапе компиляции не нужны.
В принципе я знаю, как решается эта проблема, но насколько это решение будет красивым. Например, в какую-нибудь внешнюю функцию нужно передать указатель на непрерывный кусок памяти, допустим от 256 байт до 1 Гб.
Тогда это можно сделать следующим способом:
TYPE
r1 = RECORD a1: ARRAY 256 OF CHAR END;
p1 = POINTER TO r1;
r2 = RECORD (r1) a2: ARRAY 256 OF CHAR END;
p2 = POINTER TO r2;
r3 = RECORD (r2) a3: ARRAY 512 OF CHAR END;
p3 = POINTER TO r3;
r4 = RECORD (r3) a4: ARRAY 1024 OF CHAR END;
p4 = POINTER TO r4;
r5 = RECORD (r4) a5: ARRAY 2048 OF CHAR END;
p5 = POINTER TO p5;
p6 = RECORD (p5) a6: ARRAY 4096 OF CHAR END;
p6 = POINTER TO r6;
r7 = RECORD (r6) a7: ARRAY 8192 OF CHAR END;
p7 = POINTER TO r7;
r8 = RECORD (r7) a8: ARRAY 16384 OF CHAR END;
p8 = POINTER TO r8;
r9 = RECORD (r8) a9: ARRAY 32768 OF CHAR END;
p9 = POINTER TO r9;
r10 = RECORD (r9) a10: ARRAY 65536 OF CHAR END;
p10 = POINTER TO r10;
r11 = RECORD (r10) a11: ARRAY 131072 OF CHAR END;
p11 = POINTER TO r11;
r12 = RECORD (r11) a12: ARRAY 262144 OF CHAR END;
p12 = POINTER TO r12;
r13 = RECORD (r12) a13: ARRAY 524288 OF CHAR END;
p13 = POINTER TO r13;
r14 = RECORD (r13) a14: ARRAY 1048576 OF CHAR END;
p14 = POINTER TO r14;
r15 = RECORD (r14) a15: ARRAY 2097152 OF CHAR END;
p15 = POINTER TO r15;
r16 = RECORD (r15) a16: ARRAY 4194304 OF CHAR END;
p16 = POINTER TO r16;
r17 = RECORD (r16) a17: ARRAY 8388608 OF CHAR END;
p17 = POINTER TO r17;
r18 = RECORD (r17) a18: ARRAY 16777216 OF CHAR END;
p18 = POINTER TO r18;
r19 = RECORD (r18) a19: ARRAY 33554432 OF CHAR END;
p19 = POINTER TO r19;
r20 = RECORD (r19) a20: ARRAY 67108864 OF CHAR END;
p20 = POINTER TO r20;
r21 = RECORD (r20) a21: ARRAY 134217728 OF CHAR END;
p21 = POINTER TO r21;
r22 = RECORD (r21) a22: ARRAY 268435456 OF CHAR END;
p22 = POINTER TO r22;
r23 = RECORD (r22) a23: ARRAY 536870912 OF CHAR END;
p23 = POINTER TO r23;

(* Должна вернуть указатель на данные *)
PROCEDURE GetAnswer(VAR p: p1);
VAR t1: p1; t2: p2; t3: p3; t4: p4; t5: p5; t6: p6; t7: p7; t8: p8; t9: p9;
t10: p10; t11: p11; t12: p12; t13: p13; t14: p14; t15: p15; t16: p16; t17: p17; t18: p18; t19: p19;
t20: p20; t21: p21; t22: p22; t23: p23; t24: p24;
size: INTEGER;
BEGIN
   size := GetSize; (* Получаем размер данных *)
   IF size <= 256 THEN NEW(t1); p := t1
   ELSIF size <= 512 THEN NEW(t2); p := t2;
   ELSIF size <= 1024 THEN NEW(t3); p := t3;
   ELSIF size <= 2048 THEN NEW(t4); p := t4;
   ELSIF size <= 4096 THEN NEW(t5); p := t5;
   ELSIF size <= 8192 THEN NEW(t6); p := t6;
   ELSIF size <= 16384 THEN NEW(t7); p := t7;
   ELSIF size <= 32768 THEN NEW(t8); p := t8;
   ELSIF size <= 65536 THEN NEW(t9); p := t9;
   ELSIF size <= 131072 THEN NEW(t10); p := t10;
   ELSIF size <= 262144 THEN NEW(t11); p := t11;
   ELSIF size <= 524288 THEN NEW(t12); p := t12;
   ELSIF size <= 1048576 THEN NEW(t13); p := t13;
   ELSIF size <= 2097152 THEN NEW(t14); p := t14;
   ELSIF size <= 4194304 THEN NEW(t15); p := t15;
   ELSIF size <= 8388608 THEN NEW(t16); p := t16;
   ELSIF size <= 16777216 THEN NEW(t17); p := t17;
   ELSIF size <= 33554432 THEN NEW(t18); p := t18;
   ELSIF size <= 67108864 THEN NEW(t19); p := t19;
   ELSIF size <= 134217728 THEN NEW(t20); p := t20;
   ELSIF size <= 268435456 THEN NEW(t21); p := t21;
   ELSIF size <= 536870912 THEN NEW(t22); p := t22;
   ELSE NEW(t23); p := t23;
   END;
   (* Передаем выделенную память во внешнюю систему *)
   Answer(p^);
END GetAnswer;
(* Программу не компилировал, а просто написал, для примера *)

valexey

  • Administrator
  • Hero Member
  • *****
  • Сообщений: 1990
    • Просмотр профиля
Re:Oberon-07M
« Ответ #85 : Март 25, 2011, 11:18:15 am »
Поскольку подобные функции легко запихиваются в стандартную библиотеку, идущую, естественно, сразу с компилятором, которой потом все пользуются, это вполне красиво.
"но сейчас, чтобы компенсировать растущую мощность компьютеров, программисты используют фреймворки"

valexey

  • Administrator
  • Hero Member
  • *****
  • Сообщений: 1990
    • Просмотр профиля
Re:Oberon-07M
« Ответ #86 : Март 25, 2011, 11:22:20 am »
Но тут возможно есть засада: какая сигнатура у процедуры Answer?
"но сейчас, чтобы компенсировать растущую мощность компьютеров, программисты используют фреймворки"

Rifat

  • Jr. Member
  • **
  • Сообщений: 62
    • Просмотр профиля
Re:Oberon-07M
« Ответ #87 : Март 25, 2011, 11:33:11 am »
Насчет сигнатуры не важно, допустим это адрес записанный в переменную типа INTEGER.

Еще одноа проблема в том, что к полученным данным невозможно обращаться по индексу, допустим мне нужен байт с индексом 1000000 из этого массива, как мне его найти? Или мне для начала надо будет все эти данные сначала перегнать в какую-то коллекцию, типа VList?

valexey

  • Administrator
  • Hero Member
  • *****
  • Сообщений: 1990
    • Просмотр профиля
Re:Oberon-07M
« Ответ #88 : Март 25, 2011, 11:47:39 am »
Насчет сигнатуры не важно, допустим это адрес записанный в переменную типа INTEGER.
Эмм. Тогда с этим шматом памяти придется работать исключительно через SYSTEM. Что не удобно, и если уж сразу работать с SYSTEM, что мешает без этих массивов просто сразу напрямую у системы просить выделить памяти шмат и указатель на него? Тот же INTEGER и получится, без посредников.

Еще одноа проблема в том, что к полученным данным невозможно обращаться по индексу, допустим мне нужен байт с индексом 1000000 из этого массива, как мне его найти? Или мне для начала надо будет все эти данные сначала перегнать в какую-то коллекцию, типа VList?
Почему не возможно? Смещение + Get. Вот и все. Проблема с типами – мы создали массив вполне кошерный, конкретного типа (размера и типа элементов), но тот кто просил у нас массив не знает какого типа массив у нас получился, а указателя на массив "вообще" в обероне-07, сколь я понимаю, не бывает. Следовательно мы можем возвренуть туда только просто адрес первой ячейки. И дальше с ним обращаться соответственно (ну можно конечно это дело инкапсулировать в какой-то opaque тип данных с методами, что будет закат в ручную).

Поэтому то и я предлагал, возвращать подобное с типом ARRAY 0 OF MyCoolType, соответственно 0 это синоним any или unknown. Это позволяет делать массивы размера неизвестного на этапе компиляции без изменения языка. Ну и вышеописанная проблема отменяется.
"но сейчас, чтобы компенсировать растущую мощность компьютеров, программисты используют фреймворки"

Rifat

  • Jr. Member
  • **
  • Сообщений: 62
    • Просмотр профиля
Re:Oberon-07M
« Ответ #89 : Март 25, 2011, 12:05:07 pm »
Обсуждение пошло немного не в то русло. Попробую еще раз разъяснить что я хотел сказать.
В Обероне-07 Вирт убрал динамические массивы, есть только статические массивы и указатели на записи. Причины по которым убрали динамические массивы мне частично понятны, одна из причин в том, что компилятор становится проще без них. Но нет четкой альтернативы что использовать вместо динамических массивов, там где они раньше использовались, по крайней мере я о них не очень много знаю.
Недавно, разговаривал с одним моим другом, и я у него спросил, нужны ли динамические массивы в Обероне, его ответ меня несколько удивил, он сказал, он считает что они не нужны, что должен быть набор различных коллекций, как в Яве, типа хэш массив, еще какой-нибудь массив и т.д., а как они устроены внутри нас это не должно волновать. Допустим, мы решили идти по этому пути, реализовали коллекцию массив, которая внутри себя представляет какой-нибудь VList. Но при этом, у нас будет много избыточной вычислительной работы, которая будет скрыта внутри этого контейнера.
Так вот меня интересует мнение общественности, как они считают, динамический массив должен быть отнесен к разряду родных для языка или же статических массивов и указателей на записи вполне хватает для большинства применений, а в некоторых случаях можно просто запросить блок памяти у модуля SYSTEM и вручную с ним работать, но при этом естественно не будет контроля границ, а при работе с динамическим массивом будет.