OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Вторник, 16 Апрель, 2024 13:39

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




Начать новую тему Ответить на тему  [ Сообщений: 13 ] 
Автор Сообщение
 Заголовок сообщения: Встроенная процедура-функция CAP
СообщениеДобавлено: Суббота, 04 Декабрь, 2010 21:30 
Аватара пользователя

Зарегистрирован: Вторник, 19 Сентябрь, 2006 21:54
Сообщения: 2449
Откуда: Россия, Томск
Надо быть поосторожнее с процедурой CAP. Если ей передать что-то кроме латинских символов (например, цифры), она их не игнорирует, а портит.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Воскресенье, 05 Декабрь, 2010 15:11 

Зарегистрирован: Понедельник, 30 Июль, 2007 10:53
Сообщения: 1538
Откуда: Беларусь, Минск
Александр Ильин писал(а):
Надо быть поосторожнее с процедурой CAP. Если ей передать что-то кроме латинских символов (например, цифры), она их не игнорирует, а портит.

Может, инициализацию этой процедуры нужно вынести в настройки, чтобы она преобразовывала символы в соответствии с кодировкой? Точнее, преобразовывала символ из одной последовательности в соответствующий символ из другой.

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

Хотя, что-то геморройно получается...


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 06 Декабрь, 2010 10:12 
Модератор
Аватара пользователя

Зарегистрирован: Среда, 16 Ноябрь, 2005 00:53
Сообщения: 4625
Откуда: Россия, Орёл
Александр Ильин писал(а):
Надо быть поосторожнее с процедурой CAP. Если ей передать что-то кроме латинских символов (например, цифры), она их не игнорирует, а портит.
Для КП такая тема тоже поднималась: viewtopic.php?f=29&t=2952. В КП описание CAP чуть подробнее, но суть та же.

Интересно, на что завязано умолчальное понимание этого недоразжёванного куска? Нигде не говорится, что CAP будет делать с не-буквами. Как показала практика, уже несколько человек ожидают игнорирование...


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 06 Декабрь, 2010 11:17 
Аватара пользователя

Зарегистрирован: Пятница, 25 Ноябрь, 2005 12:02
Сообщения: 8500
Откуда: Троицк, Москва
Евгений Темиргалеев писал(а):
Нигде не говорится, что CAP будет делать с не-буквами. Как показала практика, уже несколько человек ожидают игнорирование...
Нигде также не говорится, что будет при целочисленном переполнении.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 06 Декабрь, 2010 12:48 
Аватара пользователя

Зарегистрирован: Вторник, 19 Сентябрь, 2006 21:54
Сообщения: 2449
Откуда: Россия, Томск
Евгений Темиргалеев писал(а):
Интересно, на что завязано умолчальное понимание этого недоразжёванного куска? Нигде не говорится, что CAP будет делать с не-буквами. Как показала практика, уже несколько человек ожидают игнорирование...
А как же принцип "не навреди"? Если символ находится вне компетенции функции, то должен быть либо трап, либо ничего. Тем более, если в документации ничего не сказано, то и делать ничего не должна, а если она делает или хотя бы иногда может сделать что-то неожиданное, то должно быть большое предупреждение: портит данные, фигню не передавать!

Вот дана вам функция, и сказано, что она строчные символы преобразует в прописные. Вы ей даёте цифру, что ждёте в ответ? Неужели undefined behaviour? Или, может быть, какую-то заглавную букву ожидаете? В данном описании дана не область определения, и не область значений функции, а дано утверждение вида "если, то": Если (на входе строчная буква), то (на выходе соответствующая прописная буква). Таким образом, ожидается, что функция активизируется, т.е. выполняет работу по преобразованию символа, только в случае передачи ей строчного символа. В остальных случаях ожидается, что преобразования выполнено не будет.

Если мне сказано, что функция преобразует строчные символы в прописные, я ожидаю, что при выполнении её в цикле над строкой, содержащей предложение на английском языке, она изменит только буквы, а, например, знаки препинания, оставит нетронутыми.

Это всё, я считаю, от чрезмерной краткости документации. (Должно быть, но) не указано явно, что задана именно область определения функции, а не условное поведение, как ожидается при чтении. Возможно, другими читателями (математиками, например) ожидается иное. Я привык читать описания интерфейсов защищённых, т.е. соблюдающих принцип "не навреди".

Что касается конкретной реализации, то она меня вполне устраивает, если дополнительная проверка увеличила бы генерируемый код и создала неоптимальность. Так я имею возможность один раз проверить входные параметры на валидность, после чего в 10 местах вызывать CAP, не внося дополнительных проверок. Я считаю, что недостаток прежде всего в документации. Ну, и в тенденции рассматривать CAP как библиотечную функцию, а не как "особую компиляторную магию".

Приходится использовать такой вот обходной манёвр:
Код:
PROCEDURE Cap(ch: CHAR): CHAR;
BEGIN
   CASE ch OF
   | 'a'..'z': RETURN CAP(ch)
   ELSE RETURN ch
   END
END Cap;


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 06 Декабрь, 2010 13:03 

Зарегистрирован: Вторник, 11 Август, 2009 11:44
Сообщения: 516
Откуда: Бердск
А чем народ не устраивают средства ОС....
В принципе-то, должно быть дешево и сердито (например для винды): WinApi.CharUpper


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 06 Декабрь, 2010 13:17 
Аватара пользователя

Зарегистрирован: Вторник, 19 Сентябрь, 2006 21:54
Сообщения: 2449
Откуда: Россия, Томск
Galkov писал(а):
В принципе-то, должно быть дешево и сердито (например для винды): WinApi.CharUpper
Я с WinApi плохо знаком.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 06 Декабрь, 2010 13:22 
Аватара пользователя

Зарегистрирован: Вторник, 19 Сентябрь, 2006 21:54
Сообщения: 2449
Откуда: Россия, Томск
Создал тут тестовый модуль, чтобы посмотреть, что к чему в этом CAP.
Код:
MODULE CapTest;

(* CAP built-in function test. (c) Alexander Iljin, 06.12.2010. *)

   IMPORT SYSTEM, Kernel32;

   PROCEDURE OutInt(i: INTEGER);
      VAR
         pos: INTEGER;
         s: ARRAY 16 OF CHAR; (* must be bigger than MAX(INTEGER) string + 2 characters *)
   BEGIN
      IF i = 0 THEN
         Kernel32.Str('0');
      ELSIF i > 0 THEN
         pos := 2; (* leave s[0] and s[1] as buffer space for output *)
         WHILE i > 0 DO
            s[pos] := CHR(i MOD 10 + ORD('0'));
            INC(pos);
            i := i DIV 10;
         END;
         s[1] := 0X; (* use s[0] and s[1] as output buffer *)
         DEC(pos);
         WHILE pos >= 0 DO
            s[0] := s[pos];
            Kernel32.Str(s);
            DEC(pos);
         END;
      ELSE
         ASSERT(i > 0, 20); (* always FALSE *)
      END
   END OutInt;

   PROCEDURE Out8Bits(i: INTEGER);
      VAR bit: INTEGER;
   BEGIN
      FOR bit := 7 TO 0 BY -1 DO
         IF bit IN SYSTEM.VAL(SET, i) THEN
            Kernel32.Str('1');
         ELSE
            Kernel32.Str('0');
         END;
      END;
   END Out8Bits;

   PROCEDURE OutChar(ch: CHAR);
      (* If ch < ' ' then output space, otherwise output ch. Surround with '"'. *)
      VAR s: ARRAY 2 OF CHAR;
   BEGIN
      Kernel32.Str('"');
      IF ch < ' ' THEN
         Kernel32.Str(' ');
      ELSE
         s[0] := ch;
         s[1] := 0X;
         Kernel32.Str(s);
      END;
      Kernel32.Str('"');
   END OutChar;

   PROCEDURE CapCheck(i: LONGINT): BOOLEAN;
      (* If result of our SET manipulation matches CAP result, return TRUE
       * otherwise return FALSE. *)
   BEGIN
      RETURN SYSTEM.VAL(SET, i) - {7, 5} = SYSTEM.VAL(SET, LONG(ORD(CAP(CHR(i)))))
   END CapCheck;

   PROCEDURE OutBool(b: BOOLEAN);
   BEGIN
      IF b THEN
         Kernel32.Str('v');
      ELSE
         Kernel32.Str('-');
      END;
   END OutBool;

   PROCEDURE Do;
      VAR i: INTEGER;
   BEGIN
      FOR i := 0 TO 255 DO
         Out8Bits(i);
         Kernel32.Str(' ');
         Out8Bits(ORD(CAP(CHR(i))));
         Kernel32.Str(' ');
         OutChar(CHR(i));
         Kernel32.Str(' ');
         OutInt(i);
         Kernel32.Str('=>');
         OutInt(ORD(CAP(CHR(i))));
         Kernel32.Str(' ');
         OutChar(CAP(CHR(i)));
         Kernel32.Str(' ');
         OutBool(CapCheck(i));
         Kernel32.Ln();
      END;
   END Do;

BEGIN
   Do;
END CapTest.
Выполняем:
Код:
make && CapTest > 1.txt
Получаем:
Код:
00000000 00000000 " " 0=>0 " " v
00000001 00000001 " " 1=>1 " " v
00000010 00000010 " " 2=>2 " " v
00000011 00000011 " " 3=>3 " " v
00000100 00000100 " " 4=>4 " " v
00000101 00000101 " " 5=>5 " " v
00000110 00000110 " " 6=>6 " " v
00000111 00000111 " " 7=>7 " " v
00001000 00001000 " " 8=>8 " " v
00001001 00001001 " " 9=>9 " " v
00001010 00001010 " " 10=>10 " " v
00001011 00001011 " " 11=>11 " " v
00001100 00001100 " " 12=>12 " " v
00001101 00001101 " " 13=>13 " " v
00001110 00001110 " " 14=>14 " " v
00001111 00001111 " " 15=>15 " " v
00010000 00010000 " " 16=>16 " " v
00010001 00010001 " " 17=>17 " " v
00010010 00010010 " " 18=>18 " " v
00010011 00010011 " " 19=>19 " " v
00010100 00010100 " " 20=>20 " " v
00010101 00010101 " " 21=>21 " " v
00010110 00010110 " " 22=>22 " " v
00010111 00010111 " " 23=>23 " " v
00011000 00011000 " " 24=>24 " " v
00011001 00011001 " " 25=>25 " " v
00011010 00011010 " " 26=>26 " " v
00011011 00011011 " " 27=>27 " " v
00011100 00011100 " " 28=>28 " " v
00011101 00011101 " " 29=>29 " " v
00011110 00011110 " " 30=>30 " " v
00011111 00011111 " " 31=>31 " " v
00100000 00000000 " " 32=>0 " " v
00100001 00000001 "!" 33=>1 " " v
00100010 00000010 """ 34=>2 " " v
00100011 00000011 "#" 35=>3 " " v
00100100 00000100 "$" 36=>4 " " v
00100101 00000101 "%" 37=>5 " " v
00100110 00000110 "&" 38=>6 " " v
00100111 00000111 "'" 39=>7 " " v
00101000 00001000 "(" 40=>8 " " v
00101001 00001001 ")" 41=>9 " " v
00101010 00001010 "*" 42=>10 " " v
00101011 00001011 "+" 43=>11 " " v
00101100 00001100 "," 44=>12 " " v
00101101 00001101 "-" 45=>13 " " v
00101110 00001110 "." 46=>14 " " v
00101111 00001111 "/" 47=>15 " " v
00110000 00010000 "0" 48=>16 " " v
00110001 00010001 "1" 49=>17 " " v
00110010 00010010 "2" 50=>18 " " v
00110011 00010011 "3" 51=>19 " " v
00110100 00010100 "4" 52=>20 " " v
00110101 00010101 "5" 53=>21 " " v
00110110 00010110 "6" 54=>22 " " v
00110111 00010111 "7" 55=>23 " " v
00111000 00011000 "8" 56=>24 " " v
00111001 00011001 "9" 57=>25 " " v
00111010 00011010 ":" 58=>26 " " v
00111011 00011011 ";" 59=>27 " " v
00111100 00011100 "<" 60=>28 " " v
00111101 00011101 "=" 61=>29 " " v
00111110 00011110 ">" 62=>30 " " v
00111111 00011111 "?" 63=>31 " " v
01000000 01000000 "@" 64=>64 "@" v
01000001 01000001 "A" 65=>65 "A" v
01000010 01000010 "B" 66=>66 "B" v
01000011 01000011 "C" 67=>67 "C" v
01000100 01000100 "D" 68=>68 "D" v
01000101 01000101 "E" 69=>69 "E" v
01000110 01000110 "F" 70=>70 "F" v
01000111 01000111 "G" 71=>71 "G" v
01001000 01001000 "H" 72=>72 "H" v
01001001 01001001 "I" 73=>73 "I" v
01001010 01001010 "J" 74=>74 "J" v
01001011 01001011 "K" 75=>75 "K" v
01001100 01001100 "L" 76=>76 "L" v
01001101 01001101 "M" 77=>77 "M" v
01001110 01001110 "N" 78=>78 "N" v
01001111 01001111 "O" 79=>79 "O" v
01010000 01010000 "P" 80=>80 "P" v
01010001 01010001 "Q" 81=>81 "Q" v
01010010 01010010 "R" 82=>82 "R" v
01010011 01010011 "S" 83=>83 "S" v
01010100 01010100 "T" 84=>84 "T" v
01010101 01010101 "U" 85=>85 "U" v
01010110 01010110 "V" 86=>86 "V" v
01010111 01010111 "W" 87=>87 "W" v
01011000 01011000 "X" 88=>88 "X" v
01011001 01011001 "Y" 89=>89 "Y" v
01011010 01011010 "Z" 90=>90 "Z" v
01011011 01011011 "[" 91=>91 "[" v
01011100 01011100 "\" 92=>92 "\" v
01011101 01011101 "]" 93=>93 "]" v
01011110 01011110 "^" 94=>94 "^" v
01011111 01011111 "_" 95=>95 "_" v
01100000 01000000 "`" 96=>64 "@" v
01100001 01000001 "a" 97=>65 "A" v
01100010 01000010 "b" 98=>66 "B" v
01100011 01000011 "c" 99=>67 "C" v
01100100 01000100 "d" 100=>68 "D" v
01100101 01000101 "e" 101=>69 "E" v
01100110 01000110 "f" 102=>70 "F" v
01100111 01000111 "g" 103=>71 "G" v
01101000 01001000 "h" 104=>72 "H" v
01101001 01001001 "i" 105=>73 "I" v
01101010 01001010 "j" 106=>74 "J" v
01101011 01001011 "k" 107=>75 "K" v
01101100 01001100 "l" 108=>76 "L" v
01101101 01001101 "m" 109=>77 "M" v
01101110 01001110 "n" 110=>78 "N" v
01101111 01001111 "o" 111=>79 "O" v
01110000 01010000 "p" 112=>80 "P" v
01110001 01010001 "q" 113=>81 "Q" v
01110010 01010010 "r" 114=>82 "R" v
01110011 01010011 "s" 115=>83 "S" v
01110100 01010100 "t" 116=>84 "T" v
01110101 01010101 "u" 117=>85 "U" v
01110110 01010110 "v" 118=>86 "V" v
01110111 01010111 "w" 119=>87 "W" v
01111000 01011000 "x" 120=>88 "X" v
01111001 01011001 "y" 121=>89 "Y" v
01111010 01011010 "z" 122=>90 "Z" v
01111011 01011011 "{" 123=>91 "[" v
01111100 01011100 "|" 124=>92 "\" v
01111101 01011101 "}" 125=>93 "]" v
01111110 01011110 "~" 126=>94 "^" v
01111111 01011111 "" 127=>95 "_" v
10000000 00000000 "Ђ" 128=>0 " " v
10000001 00000001 "Ѓ" 129=>1 " " v
10000010 00000010 "‚" 130=>2 " " v
10000011 00000011 "ѓ" 131=>3 " " v
10000100 00000100 "„" 132=>4 " " v
10000101 00000101 "…" 133=>5 " " v
10000110 00000110 "†" 134=>6 " " v
10000111 00000111 "‡" 135=>7 " " v
10001000 00001000 "€" 136=>8 " " v
10001001 00001001 "‰" 137=>9 " " v
10001010 00001010 "Љ" 138=>10 " " v
10001011 00001011 "‹" 139=>11 " " v
10001100 00001100 "Њ" 140=>12 " " v
10001101 00001101 "Ќ" 141=>13 " " v
10001110 00001110 "Ћ" 142=>14 " " v
10001111 00001111 "Џ" 143=>15 " " v
10010000 00010000 "ђ" 144=>16 " " v
10010001 00010001 "‘" 145=>17 " " v
10010010 00010010 "’" 146=>18 " " v
10010011 00010011 "“" 147=>19 " " v
10010100 00010100 "”" 148=>20 " " v
10010101 00010101 "•" 149=>21 " " v
10010110 00010110 "–" 150=>22 " " v
10010111 00010111 "—" 151=>23 " " v
10011000 00011000 "˜" 152=>24 " " v
10011001 00011001 "™" 153=>25 " " v
10011010 00011010 "љ" 154=>26 " " v
10011011 00011011 "›" 155=>27 " " v
10011100 00011100 "њ" 156=>28 " " v
10011101 00011101 "ќ" 157=>29 " " v
10011110 00011110 "ћ" 158=>30 " " v
10011111 00011111 "џ" 159=>31 " " v
10100000 00000000 " " 160=>0 " " v
10100001 00000001 "Ў" 161=>1 " " v
10100010 00000010 "ў" 162=>2 " " v
10100011 00000011 "Ј" 163=>3 " " v
10100100 00000100 "¤" 164=>4 " " v
10100101 00000101 "Ґ" 165=>5 " " v
10100110 00000110 "¦" 166=>6 " " v
10100111 00000111 "§" 167=>7 " " v
10101000 00001000 "Ё" 168=>8 " " v
10101001 00001001 "©" 169=>9 " " v
10101010 00001010 "Є" 170=>10 " " v
10101011 00001011 "«" 171=>11 " " v
10101100 00001100 "¬" 172=>12 " " v
10101101 00001101 "­" 173=>13 " " v
10101110 00001110 "®" 174=>14 " " v
10101111 00001111 "Ї" 175=>15 " " v
10110000 00010000 "°" 176=>16 " " v
10110001 00010001 "±" 177=>17 " " v
10110010 00010010 "І" 178=>18 " " v
10110011 00010011 "і" 179=>19 " " v
10110100 00010100 "ґ" 180=>20 " " v
10110101 00010101 "µ" 181=>21 " " v
10110110 00010110 "¶" 182=>22 " " v
10110111 00010111 "·" 183=>23 " " v
10111000 00011000 "ё" 184=>24 " " v
10111001 00011001 "№" 185=>25 " " v
10111010 00011010 "є" 186=>26 " " v
10111011 00011011 "»" 187=>27 " " v
10111100 00011100 "ј" 188=>28 " " v
10111101 00011101 "Ѕ" 189=>29 " " v
10111110 00011110 "ѕ" 190=>30 " " v
10111111 00011111 "ї" 191=>31 " " v
11000000 01000000 "А" 192=>64 "@" v
11000001 01000001 "Б" 193=>65 "A" v
11000010 01000010 "В" 194=>66 "B" v
11000011 01000011 "Г" 195=>67 "C" v
11000100 01000100 "Д" 196=>68 "D" v
11000101 01000101 "Е" 197=>69 "E" v
11000110 01000110 "Ж" 198=>70 "F" v
11000111 01000111 "З" 199=>71 "G" v
11001000 01001000 "И" 200=>72 "H" v
11001001 01001001 "Й" 201=>73 "I" v
11001010 01001010 "К" 202=>74 "J" v
11001011 01001011 "Л" 203=>75 "K" v
11001100 01001100 "М" 204=>76 "L" v
11001101 01001101 "Н" 205=>77 "M" v
11001110 01001110 "О" 206=>78 "N" v
11001111 01001111 "П" 207=>79 "O" v
11010000 01010000 "Р" 208=>80 "P" v
11010001 01010001 "С" 209=>81 "Q" v
11010010 01010010 "Т" 210=>82 "R" v
11010011 01010011 "У" 211=>83 "S" v
11010100 01010100 "Ф" 212=>84 "T" v
11010101 01010101 "Х" 213=>85 "U" v
11010110 01010110 "Ц" 214=>86 "V" v
11010111 01010111 "Ч" 215=>87 "W" v
11011000 01011000 "Ш" 216=>88 "X" v
11011001 01011001 "Щ" 217=>89 "Y" v
11011010 01011010 "Ъ" 218=>90 "Z" v
11011011 01011011 "Ы" 219=>91 "[" v
11011100 01011100 "Ь" 220=>92 "\" v
11011101 01011101 "Э" 221=>93 "]" v
11011110 01011110 "Ю" 222=>94 "^" v
11011111 01011111 "Я" 223=>95 "_" v
11100000 01000000 "а" 224=>64 "@" v
11100001 01000001 "б" 225=>65 "A" v
11100010 01000010 "в" 226=>66 "B" v
11100011 01000011 "г" 227=>67 "C" v
11100100 01000100 "д" 228=>68 "D" v
11100101 01000101 "е" 229=>69 "E" v
11100110 01000110 "ж" 230=>70 "F" v
11100111 01000111 "з" 231=>71 "G" v
11101000 01001000 "и" 232=>72 "H" v
11101001 01001001 "й" 233=>73 "I" v
11101010 01001010 "к" 234=>74 "J" v
11101011 01001011 "л" 235=>75 "K" v
11101100 01001100 "м" 236=>76 "L" v
11101101 01001101 "н" 237=>77 "M" v
11101110 01001110 "о" 238=>78 "N" v
11101111 01001111 "п" 239=>79 "O" v
11110000 01010000 "р" 240=>80 "P" v
11110001 01010001 "с" 241=>81 "Q" v
11110010 01010010 "т" 242=>82 "R" v
11110011 01010011 "у" 243=>83 "S" v
11110100 01010100 "ф" 244=>84 "T" v
11110101 01010101 "х" 245=>85 "U" v
11110110 01010110 "ц" 246=>86 "V" v
11110111 01010111 "ч" 247=>87 "W" v
11111000 01011000 "ш" 248=>88 "X" v
11111001 01011001 "щ" 249=>89 "Y" v
11111010 01011010 "ъ" 250=>90 "Z" v
11111011 01011011 "ы" 251=>91 "[" v
11111100 01011100 "ь" 252=>92 "\" v
11111101 01011101 "э" 253=>93 "]" v
11111110 01011110 "ю" 254=>94 "^" v
11111111 01011111 "я" 255=>95 "_" v
Таким образом, предположение процедуры CapCheck подтверждается на всём диапазоне входных значений: CAP просто-напросто обнуляет 6й и 8й биты (если нумеровать с 0, то это будут 5й и 7й).

Результат отличается от упомянутого в теме viewtopic.php?f=29&t=2952
Интересно попробовать запустить этот код в ББ и прояснить тамошнюю реализацию CAP.
UPD: Немного доработал код, исправил опечатку.


Последний раз редактировалось Александр Ильин Понедельник, 06 Декабрь, 2010 14:11, всего редактировалось 1 раз.

Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 06 Декабрь, 2010 13:34 

Зарегистрирован: Вторник, 11 Август, 2009 11:44
Сообщения: 516
Откуда: Бердск
Дык все плохо знакомы... (более академичным будет утверждение: "тех, кто хорошо знает WinApi - не существует")
Прочитать спецфикацию-то недолго (главное - за нужное имя зацепиться)
Тут значительно полезней хорошо знать возможности Оберонов по разделению "мух и котлет"
Ну типа, чтобы платформ(енн)озависимые части находились там где им и положено... Чтобы встроенный CAP обращался куды надо. Вот куды надо в wintele - мне понятно.

Может быть для некоторой оси именно в этом месте (не знаю в каком) и должен быть тот код, который Вы привели.....

Это я не утверждал ничего, спрашивал скорее :)


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 06 Декабрь, 2010 13:50 
Аватара пользователя

Зарегистрирован: Вторник, 19 Сентябрь, 2006 21:54
Сообщения: 2449
Откуда: Россия, Томск
Аналогичная проверка для XDS:
Код:
<*+main*> (* This marks the main module of a program or library.            *)
<*heaplimit="1000000"*> (* Maximum heap size should be set in the main module,
because the changes do not take effect until the main module is recompiled. *)

MODULE Test;

(* ------------------------------------------------------------------------
 * (C) 2010 by Alexander Iljin
 * ------------------------------------------------------------------------ *)

IMPORT SYSTEM, Out;

   PROCEDURE OutInt(i: INTEGER);
      VAR
         pos: INTEGER;
         s: ARRAY 12 OF CHAR; (* bigger than MAX(INTEGER) string *)
   BEGIN
      IF i = 0 THEN
         Out.Char('0');
      ELSIF i > 0 THEN
         pos := 0;
         WHILE i > 0 DO
            s[pos] := CHR(i MOD 10 + ORD('0'));
            INC(pos);
            i := i DIV 10;
         END;
         DEC(pos);
         WHILE pos >= 0 DO
            Out.Char(s[pos]);
            DEC(pos);
         END;
      ELSE
         ASSERT(i > 0, 20); (* always FALSE *)
      END
   END OutInt;

   PROCEDURE Out8Bits(i: INTEGER);
      VAR bit: INTEGER;
   BEGIN
      FOR bit := 7 TO 0 BY -1 DO
         IF bit IN SYSTEM.VAL(SET, i) THEN
            Out.Char('1');
         ELSE
            Out.Char('0');
         END;
      END;
   END Out8Bits;

   PROCEDURE OutChar(ch: CHAR);
      (* If ch < ' ' then output space, otherwise output ch. Surround with '"'. *)
   BEGIN
      Out.Char('"');
      IF ch < ' ' THEN
         Out.Char(' ');
      ELSE
         Out.Char(ch);
      END;
      Out.Char('"');
   END OutChar;

   PROCEDURE CapCheck(i: INTEGER): BOOLEAN;
   BEGIN
      IF ('a' <= CHR(i)) & (CHR(i) <= 'z') THEN
         (* in the 'a'..'z' range => clear bit 5 *)
         RETURN CAP(CHR(i)) = CHR(SYSTEM.VAL(INTEGER, SYSTEM.VAL(SET, i) - {5}))
      ELSE
         (* not in range => do nothing *)
         RETURN CAP(CHR(i)) = CHR(i)
      END;
   END CapCheck;

   PROCEDURE OutBool(b: BOOLEAN);
   BEGIN
      IF b THEN
         Out.Char('v');
      ELSE
         Out.Char('-');
      END;
   END OutBool;

   PROCEDURE CapTest;
      VAR i: INTEGER;
   BEGIN
      FOR i := 0 TO 255 DO
         Out8Bits(i);
         Out.Char(' ');
         Out8Bits(ORD(CAP(CHR(i))));
         Out.Char(' ');
         OutChar(CHR(i));
         Out.Char(' ');
         OutInt(i);
         Out.Char('=');
         Out.Char('>');
         OutInt(ORD(CAP(CHR(i))));
         Out.Char(' ');
         OutChar(CAP(CHR(i)));
         Out.Char(' ');
         OutBool(CapCheck(i));
         Out.Ln();
      END;
   END CapTest;

BEGIN
   Out.Open;
   CapTest;
END Test.
Запускаем:
Код:
@echo off
echo !module Test.ob2>Test.prj
xc =p Test.prj && Test.exe >1.txt
del tmp.lnk Test.prj Test.obj Test.sym Test.exe errinfo.$$$ 1>nul 2>nul
Получаем:
Код:
00000000 00000000 " " 0=>0 " " v
00000001 00000001 " " 1=>1 " " v
00000010 00000010 " " 2=>2 " " v
00000011 00000011 " " 3=>3 " " v
00000100 00000100 " " 4=>4 " " v
00000101 00000101 " " 5=>5 " " v
00000110 00000110 " " 6=>6 " " v
00000111 00000111 " " 7=>7 " " v
00001000 00001000 " " 8=>8 " " v
00001001 00001001 " " 9=>9 " " v
00001010 00001010 " " 10=>10 " " v
00001011 00001011 " " 11=>11 " " v
00001100 00001100 " " 12=>12 " " v
00001101 00001101 " " 13=>13 " " v
00001110 00001110 " " 14=>14 " " v
00001111 00001111 " " 15=>15 " " v
00010000 00010000 " " 16=>16 " " v
00010001 00010001 " " 17=>17 " " v
00010010 00010010 " " 18=>18 " " v
00010011 00010011 " " 19=>19 " " v
00010100 00010100 " " 20=>20 " " v
00010101 00010101 " " 21=>21 " " v
00010110 00010110 " " 22=>22 " " v
00010111 00010111 " " 23=>23 " " v
00011000 00011000 " " 24=>24 " " v
00011001 00011001 " " 25=>25 " " v
00011010 00011010 " " 26=>26 " " v
00011011 00011011 " " 27=>27 " " v
00011100 00011100 " " 28=>28 " " v
00011101 00011101 " " 29=>29 " " v
00011110 00011110 " " 30=>30 " " v
00011111 00011111 " " 31=>31 " " v
00100000 00100000 " " 32=>32 " " v
00100001 00100001 "!" 33=>33 "!" v
00100010 00100010 """ 34=>34 """ v
00100011 00100011 "#" 35=>35 "#" v
00100100 00100100 "$" 36=>36 "$" v
00100101 00100101 "%" 37=>37 "%" v
00100110 00100110 "&" 38=>38 "&" v
00100111 00100111 "'" 39=>39 "'" v
00101000 00101000 "(" 40=>40 "(" v
00101001 00101001 ")" 41=>41 ")" v
00101010 00101010 "*" 42=>42 "*" v
00101011 00101011 "+" 43=>43 "+" v
00101100 00101100 "," 44=>44 "," v
00101101 00101101 "-" 45=>45 "-" v
00101110 00101110 "." 46=>46 "." v
00101111 00101111 "/" 47=>47 "/" v
00110000 00110000 "0" 48=>48 "0" v
00110001 00110001 "1" 49=>49 "1" v
00110010 00110010 "2" 50=>50 "2" v
00110011 00110011 "3" 51=>51 "3" v
00110100 00110100 "4" 52=>52 "4" v
00110101 00110101 "5" 53=>53 "5" v
00110110 00110110 "6" 54=>54 "6" v
00110111 00110111 "7" 55=>55 "7" v
00111000 00111000 "8" 56=>56 "8" v
00111001 00111001 "9" 57=>57 "9" v
00111010 00111010 ":" 58=>58 ":" v
00111011 00111011 ";" 59=>59 ";" v
00111100 00111100 "<" 60=>60 "<" v
00111101 00111101 "=" 61=>61 "=" v
00111110 00111110 ">" 62=>62 ">" v
00111111 00111111 "?" 63=>63 "?" v
01000000 01000000 "@" 64=>64 "@" v
01000001 01000001 "A" 65=>65 "A" v
01000010 01000010 "B" 66=>66 "B" v
01000011 01000011 "C" 67=>67 "C" v
01000100 01000100 "D" 68=>68 "D" v
01000101 01000101 "E" 69=>69 "E" v
01000110 01000110 "F" 70=>70 "F" v
01000111 01000111 "G" 71=>71 "G" v
01001000 01001000 "H" 72=>72 "H" v
01001001 01001001 "I" 73=>73 "I" v
01001010 01001010 "J" 74=>74 "J" v
01001011 01001011 "K" 75=>75 "K" v
01001100 01001100 "L" 76=>76 "L" v
01001101 01001101 "M" 77=>77 "M" v
01001110 01001110 "N" 78=>78 "N" v
01001111 01001111 "O" 79=>79 "O" v
01010000 01010000 "P" 80=>80 "P" v
01010001 01010001 "Q" 81=>81 "Q" v
01010010 01010010 "R" 82=>82 "R" v
01010011 01010011 "S" 83=>83 "S" v
01010100 01010100 "T" 84=>84 "T" v
01010101 01010101 "U" 85=>85 "U" v
01010110 01010110 "V" 86=>86 "V" v
01010111 01010111 "W" 87=>87 "W" v
01011000 01011000 "X" 88=>88 "X" v
01011001 01011001 "Y" 89=>89 "Y" v
01011010 01011010 "Z" 90=>90 "Z" v
01011011 01011011 "[" 91=>91 "[" v
01011100 01011100 "\" 92=>92 "\" v
01011101 01011101 "]" 93=>93 "]" v
01011110 01011110 "^" 94=>94 "^" v
01011111 01011111 "_" 95=>95 "_" v
01100000 01100000 "`" 96=>96 "`" v
01100001 01000001 "a" 97=>65 "A" v
01100010 01000010 "b" 98=>66 "B" v
01100011 01000011 "c" 99=>67 "C" v
01100100 01000100 "d" 100=>68 "D" v
01100101 01000101 "e" 101=>69 "E" v
01100110 01000110 "f" 102=>70 "F" v
01100111 01000111 "g" 103=>71 "G" v
01101000 01001000 "h" 104=>72 "H" v
01101001 01001001 "i" 105=>73 "I" v
01101010 01001010 "j" 106=>74 "J" v
01101011 01001011 "k" 107=>75 "K" v
01101100 01001100 "l" 108=>76 "L" v
01101101 01001101 "m" 109=>77 "M" v
01101110 01001110 "n" 110=>78 "N" v
01101111 01001111 "o" 111=>79 "O" v
01110000 01010000 "p" 112=>80 "P" v
01110001 01010001 "q" 113=>81 "Q" v
01110010 01010010 "r" 114=>82 "R" v
01110011 01010011 "s" 115=>83 "S" v
01110100 01010100 "t" 116=>84 "T" v
01110101 01010101 "u" 117=>85 "U" v
01110110 01010110 "v" 118=>86 "V" v
01110111 01010111 "w" 119=>87 "W" v
01111000 01011000 "x" 120=>88 "X" v
01111001 01011001 "y" 121=>89 "Y" v
01111010 01011010 "z" 122=>90 "Z" v
01111011 01111011 "{" 123=>123 "{" v
01111100 01111100 "|" 124=>124 "|" v
01111101 01111101 "}" 125=>125 "}" v
01111110 01111110 "~" 126=>126 "~" v
01111111 01111111 "" 127=>127 "" v
10000000 10000000 "Ђ" 128=>128 "Ђ" v
10000001 10000001 "Ѓ" 129=>129 "Ѓ" v
10000010 10000010 "‚" 130=>130 "‚" v
10000011 10000011 "ѓ" 131=>131 "ѓ" v
10000100 10000100 "„" 132=>132 "„" v
10000101 10000101 "…" 133=>133 "…" v
10000110 10000110 "†" 134=>134 "†" v
10000111 10000111 "‡" 135=>135 "‡" v
10001000 10001000 "€" 136=>136 "€" v
10001001 10001001 "‰" 137=>137 "‰" v
10001010 10001010 "Љ" 138=>138 "Љ" v
10001011 10001011 "‹" 139=>139 "‹" v
10001100 10001100 "Њ" 140=>140 "Њ" v
10001101 10001101 "Ќ" 141=>141 "Ќ" v
10001110 10001110 "Ћ" 142=>142 "Ћ" v
10001111 10001111 "Џ" 143=>143 "Џ" v
10010000 10010000 "ђ" 144=>144 "ђ" v
10010001 10010001 "‘" 145=>145 "‘" v
10010010 10010010 "’" 146=>146 "’" v
10010011 10010011 "“" 147=>147 "“" v
10010100 10010100 "”" 148=>148 "”" v
10010101 10010101 "•" 149=>149 "•" v
10010110 10010110 "–" 150=>150 "–" v
10010111 10010111 "—" 151=>151 "—" v
10011000 10011000 "˜" 152=>152 "˜" v
10011001 10011001 "™" 153=>153 "™" v
10011010 10011010 "љ" 154=>154 "љ" v
10011011 10011011 "›" 155=>155 "›" v
10011100 10011100 "њ" 156=>156 "њ" v
10011101 10011101 "ќ" 157=>157 "ќ" v
10011110 10011110 "ћ" 158=>158 "ћ" v
10011111 10011111 "џ" 159=>159 "џ" v
10100000 10100000 " " 160=>160 " " v
10100001 10100001 "Ў" 161=>161 "Ў" v
10100010 10100010 "ў" 162=>162 "ў" v
10100011 10100011 "Ј" 163=>163 "Ј" v
10100100 10100100 "¤" 164=>164 "¤" v
10100101 10100101 "Ґ" 165=>165 "Ґ" v
10100110 10100110 "¦" 166=>166 "¦" v
10100111 10100111 "§" 167=>167 "§" v
10101000 10101000 "Ё" 168=>168 "Ё" v
10101001 10101001 "©" 169=>169 "©" v
10101010 10101010 "Є" 170=>170 "Є" v
10101011 10101011 "«" 171=>171 "«" v
10101100 10101100 "¬" 172=>172 "¬" v
10101101 10101101 "­" 173=>173 "­" v
10101110 10101110 "®" 174=>174 "®" v
10101111 10101111 "Ї" 175=>175 "Ї" v
10110000 10110000 "°" 176=>176 "°" v
10110001 10110001 "±" 177=>177 "±" v
10110010 10110010 "І" 178=>178 "І" v
10110011 10110011 "і" 179=>179 "і" v
10110100 10110100 "ґ" 180=>180 "ґ" v
10110101 10110101 "µ" 181=>181 "µ" v
10110110 10110110 "¶" 182=>182 "¶" v
10110111 10110111 "·" 183=>183 "·" v
10111000 10111000 "ё" 184=>184 "ё" v
10111001 10111001 "№" 185=>185 "№" v
10111010 10111010 "є" 186=>186 "є" v
10111011 10111011 "»" 187=>187 "»" v
10111100 10111100 "ј" 188=>188 "ј" v
10111101 10111101 "Ѕ" 189=>189 "Ѕ" v
10111110 10111110 "ѕ" 190=>190 "ѕ" v
10111111 10111111 "ї" 191=>191 "ї" v
11000000 11000000 "А" 192=>192 "А" v
11000001 11000001 "Б" 193=>193 "Б" v
11000010 11000010 "В" 194=>194 "В" v
11000011 11000011 "Г" 195=>195 "Г" v
11000100 11000100 "Д" 196=>196 "Д" v
11000101 11000101 "Е" 197=>197 "Е" v
11000110 11000110 "Ж" 198=>198 "Ж" v
11000111 11000111 "З" 199=>199 "З" v
11001000 11001000 "И" 200=>200 "И" v
11001001 11001001 "Й" 201=>201 "Й" v
11001010 11001010 "К" 202=>202 "К" v
11001011 11001011 "Л" 203=>203 "Л" v
11001100 11001100 "М" 204=>204 "М" v
11001101 11001101 "Н" 205=>205 "Н" v
11001110 11001110 "О" 206=>206 "О" v
11001111 11001111 "П" 207=>207 "П" v
11010000 11010000 "Р" 208=>208 "Р" v
11010001 11010001 "С" 209=>209 "С" v
11010010 11010010 "Т" 210=>210 "Т" v
11010011 11010011 "У" 211=>211 "У" v
11010100 11010100 "Ф" 212=>212 "Ф" v
11010101 11010101 "Х" 213=>213 "Х" v
11010110 11010110 "Ц" 214=>214 "Ц" v
11010111 11010111 "Ч" 215=>215 "Ч" v
11011000 11011000 "Ш" 216=>216 "Ш" v
11011001 11011001 "Щ" 217=>217 "Щ" v
11011010 11011010 "Ъ" 218=>218 "Ъ" v
11011011 11011011 "Ы" 219=>219 "Ы" v
11011100 11011100 "Ь" 220=>220 "Ь" v
11011101 11011101 "Э" 221=>221 "Э" v
11011110 11011110 "Ю" 222=>222 "Ю" v
11011111 11011111 "Я" 223=>223 "Я" v
11100000 11100000 "а" 224=>224 "а" v
11100001 11100001 "б" 225=>225 "б" v
11100010 11100010 "в" 226=>226 "в" v
11100011 11100011 "г" 227=>227 "г" v
11100100 11100100 "д" 228=>228 "д" v
11100101 11100101 "е" 229=>229 "е" v
11100110 11100110 "ж" 230=>230 "ж" v
11100111 11100111 "з" 231=>231 "з" v
11101000 11101000 "и" 232=>232 "и" v
11101001 11101001 "й" 233=>233 "й" v
11101010 11101010 "к" 234=>234 "к" v
11101011 11101011 "л" 235=>235 "л" v
11101100 11101100 "м" 236=>236 "м" v
11101101 11101101 "н" 237=>237 "н" v
11101110 11101110 "о" 238=>238 "о" v
11101111 11101111 "п" 239=>239 "п" v
11110000 11110000 "р" 240=>240 "р" v
11110001 11110001 "с" 241=>241 "с" v
11110010 11110010 "т" 242=>242 "т" v
11110011 11110011 "у" 243=>243 "у" v
11110100 11110100 "ф" 244=>244 "ф" v
11110101 11110101 "х" 245=>245 "х" v
11110110 11110110 "ц" 246=>246 "ц" v
11110111 11110111 "ч" 247=>247 "ч" v
11111000 11111000 "ш" 248=>248 "ш" v
11111001 11111001 "щ" 249=>249 "щ" v
11111010 11111010 "ъ" 250=>250 "ъ" v
11111011 11111011 "ы" 251=>251 "ы" v
11111100 11111100 "ь" 252=>252 "ь" v
11111101 11111101 "э" 253=>253 "э" v
11111110 11111110 "ю" 254=>254 "ю" v
11111111 11111111 "я" 255=>255 "я" v
Видим, что в XDS функция CAP ведёт себя так, как ожидается, то есть не изменяет символы за пределами отведённого диапазона 'a'..'z'.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 06 Декабрь, 2010 14:36 
Модератор
Аватара пользователя

Зарегистрирован: Среда, 16 Ноябрь, 2005 00:53
Сообщения: 4625
Откуда: Россия, Орёл
Александр Ильин писал(а):
Создал тут тестовый модуль, чтобы посмотреть, что к чему в этом CAP.
CAP(x) = CHR(ORD(x) - (ORD("a") - ORD("A"))), при том раскладе что коды литер в последовательностях "A".."Z" и "a".."z" идут подряд. :)
Александр Ильин писал(а):
Видим, что в XDS функция CAP ведёт себя так, как ожидается, то есть не изменяет символы за пределами отведённого диапазона 'a'..'z'.
Как у Вас ожидается. :) А почему, например, Вы не ожидаете капитализации русских букв? Ведь ни в Оберон, ни в Оберон-2 про 'a'..'z' ничего не говорится.

P.S. я, например, не ожидал от CAP неизменности...

И вообще, на мой взгляд, эта функция избыточна.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 06 Декабрь, 2010 15:10 

Зарегистрирован: Вторник, 11 Август, 2009 11:44
Сообщения: 516
Откуда: Бердск
Вот, взгляните...
Код:
MODULE PrivTest;

IMPORT Log,W:=WinApi,S:=SYSTEM;

PROCEDURE CapThis(VAR s: ARRAY OF SHORTCHAR);
VAR i: W.PtrSTR;
BEGIN
  i := W.CharUpper(S.VAL(W.PtrSTR, S.ADR(s[0])));
END CapThis;

PROCEDURE LowThis(VAR s: ARRAY OF SHORTCHAR);
VAR i: W.PtrSTR;
BEGIN
  i := W.CharLower(S.VAL(W.PtrSTR, S.ADR(s[0])));
END LowThis;

PROCEDURE Do*;
VAR s: ARRAY 512 OF SHORTCHAR;
BEGIN
   s:='abcdefghijklmnopqrstuvwxyzабвгдеёжзийклмнопрстуфхцчшщъыьэюя';
   CapThis(s); Log.Ln; Log.String(s$);
   LowThis(s); Log.Ln; Log.String(s$);
   Log.Ln;
END Do;

END PrivTest.


Как бы все вполне ожидаемо...
А вот для юникода - фигня порлучается. Претендентов на виновники в фигне - двое. ББ и винда.
Я грешу пока на компилятор ББ (типа, принимая короткие символы из исходника -- криво переводит их в юникод)


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 06 Декабрь, 2010 15:33 
Аватара пользователя

Зарегистрирован: Вторник, 19 Сентябрь, 2006 21:54
Сообщения: 2449
Откуда: Россия, Томск
Только что проверил реализацию в ББ (скачал школьную версию). Там CAP убирает только 5й бит (при нумерации с нуля), что позволяет ей отлично работать с русскими буквами, за исключением ё/Ё. Код практически не отличается от XDS за следующими поправками:
1. IMPORT SYSTEM, Out:=Log;
2.
Код:
   PROCEDURE CapCheck(i: INTEGER): BOOLEAN;
   BEGIN
      RETURN BITS(i) - {5} = BITS(ORD(CAP(CHR(i))))
   END CapCheck;
3. удалить Out.Open.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 13 ] 

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


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

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


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

Найти:
Вся информация, размещаемая участниками на конференции (тексты сообщений, вложения и пр.) © 2005-2024, участники конференции «OberonCore», если специально не оговорено иное.
Администрация не несет ответственности за мнения, стиль и достоверность высказываний участников, равно как и за безопасность материалов, предоставляемых участниками во вложениях.
Без разрешения участников и ссылки на конференцию «OberonCore» любое воспроизведение и/или копирование высказываний полностью и/или по частям запрещено.
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB