Оберон-клуб «ВЄДАsoft»

Твердыня модульных языков
Текущее время: 22 авг 2017, 20:48

Часовой пояс: UTC + 2 часа




Начать новую тему Ответить на тему  [ Сообщений: 20 ]  На страницу Пред.  1, 2
Автор Сообщение
СообщениеДобавлено: 27 авг 2016, 13:43 
Не в сети
Аватара пользователя

Сообщения: 835
Откуда: Днепропетровская обл.
Олежек, проверка в OPS.Number на макс. количество символов в шестнадцатеричном числе (OPM.MaxHDig) имеет роль предварительной. Дэвид отказался от константы OPM.MaxHDig вообще и установил в voc вычисление этого значения действительно на основе разрядности типа LONGINT, но я выяснил, что можно просто установить OPM.MaxHDig в его логический максимум (16), а дополнительные проверки всё равно делаются транслятором позднее на этапе разбора выражения, где проверяется влезает ли значение константы в указанный тип. Так что вычисление OPM.MaxHDig в динамике ничего не даёт, лишь усложняет транслятор.


Вернуться к началу
 Профиль  
Ответить с цитатой  
СообщениеДобавлено: 27 авг 2016, 15:59 
Не в сети
Администратор
Аватара пользователя

Сообщения: 237
Откуда: Россия
Действительно, можно сделать так, что сканер будет всегда читать 64-разрядную целую константу, а потом разбираться, влезает ли она в тип. Это, при обнаружении унарного минуса перед цифрой, позволит нормально обработать отрицательные константы -128, –32768 и –2147483648, но не -9223372036854775808.
Но как быть со свойством сканера "если константа задана в hex-виде 16 цифрами, то константа может быть задана в дополнительном коде". Это позволяет задать и отрицательные константы без использования знака минус. Также это можно понимать, как задание беззнаковой 64-битной константы - сканер прочитает беззнаковую константу, а уже в дальнейшем её биты будут интерпретировать как знаковые.
Это может оказаться полезным, но нужно ли здесь фиксировать именно 16 цифр? Ведь если в транслируемой программе нет 64-битного типа, то даже 9 цифр будут отвергнуты и получается, что невозможно задать прямое значение целой константы для наибольшего имеющегося типа.
Мне кажется, привязать это свойство нужно не к 64-битам, а именно к наибольшему целому типу целевой платформы.


Вернуться к началу
 Профиль  
Ответить с цитатой  
СообщениеДобавлено: 27 авг 2016, 19:55 
Не в сети
Аватара пользователя

Сообщения: 835
Откуда: Днепропетровская обл.
Возможен такой вариант, что наибольший целый тип платформы, допустим, будет 32 бита, а константы всё ещё могут быть 64-битными. При этом если использовать такую константу прямо, то сразу будет переполнение, но не в месте объявления константы, а в месте использования, что логично. Но такой константе можно найти применение для вычислений во время компиляции.

Олежек, никакой весомой роли те 16 цифр для 16-ричного числа не несут. Если максимальный целевой тип платформы меньше 64 бит, ты даже не объявишь такую константу, вот попробуй сам, если не веришь. Максимальный размер константы фиксирован и определяется разрядностью платформенного типа LONGINT.

Код: "OBERON"
  1. PROCEDURE SetIntType(node: OPT.Node);
  2. VAR v: LONGINT;
  3. BEGIN v := node^.conval^.intval;
  4. IF (-128 <= v) & (v <= 127) THEN node^.typ := OPT.bytetyp
  5. ELSIF (OPM.MinSInt <= v) & (v <= OPM.MaxSInt) THEN node^.typ := OPT.sinttyp
  6. ELSIF (OPM.MinInt <= v) & (v <= OPM.MaxInt) THEN node^.typ := OPT.inttyp
  7. ELSIF (OPM.MinLInt <= v) & (v <= OPM.MaxLInt) (*bootstrap or cross*) THEN
  8. node^.typ := OPT.linttyp
  9. ELSE err(203); node^.typ := OPT.sinttyp; node^.conval^.intval := 1
  10. END
  11. END SetIntType;
  12.  
  13. PROCEDURE NewIntConst*(intval: LONGINT): OPT.Node;
  14. VAR x: OPT.Node;
  15. BEGIN
  16. x := OPT.NewNode(Nconst); x^.conval := OPT.NewConst();
  17. x^.conval^.intval := intval; SetIntType(x); RETURN x
  18. END NewIntConst;
Здесь мы видим, что если число выходит за пределы типа LONGINT, то генерируется ошибка 203. OPS.Number делает то же самое и генерирует ту же ошибку если в hex-числе цифр больше, чем OPM.MaxHDig. То есть ошибка будет так или иначе, но одна и та же.

И такая логика работы будет до тех пор, пока мы не модифицируем транслятор для работы с физическими типами вместо абстрактных.

Что касается возможности задания отрицательного 16-ричного без ун. минуса, то не вижу в этом никаких проблем. Hex-числа вообще очень редко пишут в коде с ун. минусом. Практически во всех ЯП, начиная с ТурбоПаскаля, заканчивая Си, Дельфи, можно задавать знак числа именно так, неявно и без унарного минуса. И Оберон тоже поддерживает эту традицию. Сам смысл 16-ричных чисел в программировании — более компактное представление двоичных разрядов, то есть, как ни крути, это уже шаг к низкому уровню.


Вернуться к началу
 Профиль  
Ответить с цитатой  
СообщениеДобавлено: 28 авг 2016, 10:54 
Не в сети
Администратор
Аватара пользователя

Сообщения: 237
Откуда: Россия
Zorko писал(а):
Возможен такой вариант, что наибольший целый тип платформы, допустим, будет 32 бита, а константы всё ещё могут быть 64-битными. При этом если использовать такую константу прямо, то сразу будет переполнение, но не в месте объявления константы, а в месте использования, что логично. Но такой константе можно найти применение для вычислений во время компиляции
...
Здесь мы видим, что если число выходит за пределы типа LONGINT, то генерируется ошибка 203.
Сейчас нельзя использовать 64-битные константы даже во время компиляции, если наибольший тип целевой платформы 32 бита. Сканер сможет прочитать такую константу, но до вычислений во время компиляции парсер должен построить дерево. Засунуть константу в дерево не удастся - сработает SetIntType для узла. А там идет привязка к параметрам OPM.MinLInt/OPM.MaxLInt, а не к типам КП. В результате будет "одна и та же" ошибка 203.

И это логично - если в ЯП нет 64-битного типа, то не может быть таких переменных, операций, или констант (иначе, какого бы типа они были?). Если каким-то образом нужно написать константное выражение из 64-битных чисел, значение которого меньшей разрядности, то речь идет скорее о "представлении", о способе записи 32-разрядных или 16-разрядных констант через 64-битные. Но представлением занимается обычно сканер, поэтому его придется усложнить. А стоит ли, так ли уж часто нужно задавать константы меньшей разрядности через большие? В любом случае, без существенной переделки транслятора это не сделать.
Цитата:
Что касается возможности задания отрицательного 16-ричного без ун. минуса, то не вижу в этом никаких проблем. Hex-числа вообще очень редко пишут в коде с ун. минусом. Практически во всех ЯП, начиная с ТурбоПаскаля, заканчивая Си, Дельфи, можно задавать знак числа именно так, неявно и без унарного минуса. И Оберон тоже поддерживает эту традицию. Сам смысл 16-ричных чисел в программировании — более компактное представление двоичных разрядов, то есть, как ни крути, это уже шаг к низкому уровню.
Но Офронт, где MaxHDig всегда равно 16, не поддерживает эту традицию для 32-разрядной платформы. Ведь 64-битную константу невозможно задать - она не поместится в узел дерева из-за SetIntType. А все константы меньшей разрядности не будут рассматриваться как заданные в дополнительном коде, потому что у них старшая (шестнадцатая) цифра равна нулю. Получается, что для 32-битной платформы этот способ вообще пропадает: 64-битные константы задать нельзя, а все прочие имеют меньше 16 цифр.

Поэтому считаю, что будет полезно ориентироваться на разрядность целевой платформы - максимальное число цифр должно определяться по максимальному целому типу транслируемого ЯП. Тогда и способ задавать hex-константу будет работать на всех платформах. И достичь этого очень просто, нужно сделать OPM.MaxHDig не константой, а таким же экспортируемым readonly параметром, как MaxLInt. И вычислять OPM.MaxHDig := 2*LIntSize;


Вернуться к началу
 Профиль  
Ответить с цитатой  
СообщениеДобавлено: 28 авг 2016, 12:12 
Не в сети
Аватара пользователя

Сообщения: 835
Откуда: Днепропетровская обл.
Дай, пожалуйста, пример случая, когда число, заданное в дополнительном коде, будет интерпретироваться неверно при MaxHDig = 16 для 32-битного таргета.


Вернуться к началу
 Профиль  
Ответить с цитатой  
СообщениеДобавлено: 28 авг 2016, 17:11 
Не в сети
Администратор
Аватара пользователя

Сообщения: 237
Откуда: Россия
Zorko писал(а):
Дай, пожалуйста, пример случая, когда число, заданное в дополнительном коде, будет интерпретироваться неверно при MaxHDig = 16 для 32-битного таргета.

Код: "OBERON"
  1. MODULE TEST;
  2. VAR
  3. n: LONGINT;
  4. BEGIN
  5.  
  6. n:=0FFFFFFFFH;
  7.  
  8. END TEST.
Если платформа 32битная, то размер LONGINT равен 4 байта. В этом случае "-1" в дополнительном коде задается как 0FFFFFFFFH. Но поскольку это равно 00000000FFFFFFFF, то старшая (шестнадцатая) цифра равна 0. Поэтому это интерпретируется как 4294967295, что превышает OPM.MaxLInt.


Вернуться к началу
 Профиль  
Ответить с цитатой  
СообщениеДобавлено: 28 авг 2016, 18:42 
Не в сети
Аватара пользователя

Сообщения: 835
Откуда: Днепропетровская обл.
Сделал предложенную тобой модификацию. А ничо, что теперь присваивать хекс-числа в дополнительном коде типу LONGINT можно, а типам INTEGER и SHORTINT нельзя? (платформа: 32-16-8)

А с MaxHDig = 16 и типу LONGINT нельзя. Получается, что Ofront не принимает хекс-константы как отрицательные значения.


Вложения:
FFFFFFFF.png
FFFFFFFF.png [ 4.24 КБ | Просмотров: 3823 ]
Вернуться к началу
 Профиль  
Ответить с цитатой  
СообщениеДобавлено: 28 авг 2016, 20:18 
Не в сети
Администратор
Аватара пользователя

Сообщения: 237
Откуда: Россия
Zorko писал(а):
Сделал предложенную тобой модификацию. А ничо, что теперь присваивать хекс-числа в дополнительном коде типу LONGINT можно, а типам INTEGER и SHORTINT нельзя? (платформа: 32-16-8)

А с MaxHDig = 16 и типу LONGINT нельзя. Получается, что Ofront не принимает хекс-константы как отрицательные значения.
Да, с такой модификацией представление в допкоде работает только для максимального целого типа, который возможен на этой платформе: если это 32, то это 8 цифр, если 64 бита, то 16 цифр. В любом случае это тип LONGINT.
И это логично - при изменении разрядности набор типов меняется, меняется диапазон констант, но свойство 16-ричного представления в допкоде сохраняется для максимального целого типа.


Вернуться к началу
 Профиль  
Ответить с цитатой  
СообщениеДобавлено: 28 авг 2016, 20:27 
Не в сети
Аватара пользователя

Сообщения: 835
Откуда: Днепропетровская обл.
Вот это тонкость! И теперь у нас OPS.Number устроен проще, чем у Дэйва (voc) при том же функционале.

Да, именно поэтому в КП ввели специальный символ для обозначения 64-битных хекс. чисел (L) — чтобы точно отличать их от 32-битных (H).


Вернуться к началу
 Профиль  
Ответить с цитатой  
СообщениеДобавлено: 29 авг 2016, 08:19 
Не в сети
Администратор
Аватара пользователя

Сообщения: 237
Откуда: Россия
Я был не совсем прав, когда говорил, что при фиксированном MaxHDig = 16 вообще нельзя вводить константы в допкоде для 32-битной платформы. Оказывается можно:
Код: "OBERON"
  1. MODULE TEST;
  2. VAR
  3. n: LONGINT;
  4. BEGIN
  5.  
  6. n:=0FFFFFFFFFFFFFFFFH;
  7.  
  8. END TEST.
Вот таким образом можно задавать константу "-1". Сравните с n:=0000000000000001H;, где задается константа 1. Но ведущие нули (кроме одного перед цифрами А-F) можно опускать, ноль подразумевается по умолчанию: n:=1H; А вот единичный знаковый бит, "растащенный влево" до нужной разрядности, опускать нельзя.

Но писать всегда 16 цифр, даже на 32-битной платформе, это неестественно и неудобно. Поэтому лучше сделать OPM.MaxHDig := 2*LIntSize.

Однако, следует помнить, что при переходе от 32 битной к 64 битной платформе программа с допкодом потребует корректировки:
Код: "OBERON"
  1. MODULE TEST;
  2. VAR
  3. n: LONGINT;
  4. BEGIN
  5.  
  6. n:=0FFFFFFFFH;
  7.  
  8. END TEST.
Теперь LONGINT 64-битный и OPM.MaxHDig=16, так что n:=0FFFFFFFFH; не означает n:= -1;, это уже не допкод. Переменной будет присвоено положительное число 4294967295, которое входит в диапазон LONGINT. Впрочем, скорее всего это не единственная корректировка, которая потребуется при данном переходе.


Вернуться к началу
 Профиль  
Ответить с цитатой  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 20 ]  На страницу Пред.  1, 2

Часовой пояс: UTC + 2 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
cron
Создано на основе phpBB® Forum Software © phpBB Group
Тех.поддержка phpBB