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

Твердыня модульных языков
Текущее время: 02 авг 2025, 21:49

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




Начать новую тему Ответить на тему  [ Сообщений: 69 ]  На страницу Пред.  1, 2, 3, 4, 5 ... 7  След.
Автор Сообщение
 Заголовок сообщения: Re: Константные массивы
СообщениеДобавлено: 14 июл 2014, 03:06 
Не в сети
Аватара пользователя

Сообщения: 1019
Откуда: Днепропетровская обл.
Saferoll писал(а):
Как наиболее эффективно это сделать, есть ли что-то специально для этого в SYSTEM, кроме DIV, MOD и сдвигов?
Может быть так?
Код: "OBERON"
  1. TYPE
  2. ConstArray = POINTER TO EXTENSIBLE RECORD END;
  3. ConstArrayOfByte = POINTER TO RECORD(ConstArray)
  4. data*: POINTER TO ARRAY OF BYTE;
  5. END;
  6. ConstArrayOfSInt = POINTER TO RECORD(ConstArray)
  7. data*: POINTER TO ARRAY OF SHORTINT;
  8. END;
  9. ConstArrayOfInt = POINTER TO RECORD(ConstArray)
  10. data*: POINTER TO ARRAY OF INTEGER;
  11. END;
  12. ConstArrayOfLInt = POINTER TO RECORD(ConstArray)
  13. data*: POINTER TO ARRAY OF LONGINT;
  14. END;
  15. ...
  16. ConstDesc* = RECORD
  17. ext*: ConstExt; (* string or code for code proc *)
  18. intval*: INTEGER; (* constant value or adr, proc par size, text position or least case label *)
  19. intval2*: INTEGER; (* string length, proc var size or larger case label *)
  20. setval*: SET; (* constant value, procedure body present or "ELSE" present in case *)
  21. realval*: REAL; (* real or longreal constant value *)
  22. array*: ConstArray;
  23. END ;

Теперь если нужен массив типа LONGINT:
Код: "OBERON"
  1. NEW(x^.conval^.array(ConstArrayOfLInt)); NEW(x^.conval^.array(ConstArrayOfLInt).data, size);
Может быть что-то в спячке неточно написал, но идея, уверен, понятна: зарезервировать тип "указатель на пустую расширяемую запись", унаследовать от него указатели на записи с элементом "указатели нужного нам типа", и потом заводить указатель на потомка-запись именно нужного нам типа массива и присваивать её полю ConstDesc.array, делая ненужными приведения данных из массивов различных типов к массиву байтов путём DIV, MOD и сдвигов.


Вернуться к началу
 Профиль  
Ответить с цитатой  
 Заголовок сообщения: Re: Константные массивы
СообщениеДобавлено: 14 июл 2014, 19:42 
Не в сети
Администратор
Аватара пользователя

Сообщения: 273
Откуда: Россия
Zorko писал(а):

Теперь если нужен массив типа LONGINT:
Код: "OBERON"
  1. NEW(x^.conval^.array(ConstArrayOfLInt)); NEW(x^.conval^.array(ConstArrayOfLInt).data, size);
Может быть что-то в спячке неточно написал, но идея, уверен, понятна: зарезервировать тип "указатель на пустую расширяемую запись", унаследовать от него указатели на записи с элементом "указатели нужного нам типа", и потом заводить указатель на потомка-запись именно нужного нам типа массива и присваивать её полю ConstDesc.array, делая ненужными приведения данных из массивов различных типов к массиву байтов путём DIV, MOD и сдвигов.
Да, такой обероновский аналог вариантной записи подойдет. Правда не совсем так. NEW(x^.conval^.array(ConstArrayOfLInt)) выдает ошибку, если x^.conval^.array=NIL, потому что пустой указатель нельзя привести ни к какому типу, в том числе и к типу ConstArrayOfLInt. Если предварительно сделать NEW(x^.conval^.array), то тоже будет ошибка, потому что привести можно к типу-предку, а не наоборот (в то время как ConstArrayOfLInt является потомком ConstArray).

Но можно сделать так.
Код: "OBERON"
  1. VAR y: OPT.ConstArrayOfLInt;
  2. ...
  3. NEW(y); NEW(y.data,n);
  4. ...
  5. y.data[k]:=apar^.conval^.intval;
  6. ...
  7. x^.conval^.array := y; (* присвоить предку потомка можно, все поля потомка сохранятся*)
  8. ...
  9. ci := x^.conval^.array(OPT.ConstArrayOfLInt).data[i] (* потом можно вытащить любой элемент массива*)
  10.  
Однако тут есть сложность: размер типов, которые транслирует Ofront задаются переменными OPM.IntSize и т.д., в соответсвии с которыми и нужно выбрать нужный OPT.ConstArrayOf... . Пока, чтобы получить работающий вариант я буду всё хранить в типе ConstArrayOfInt. Покуда мы не ввели 64-разрядность там поместится любой целый офронтовский тип. Конечно, это может быть лишний расход памяти (в 4 раза для байта!), но пока сделаем так, а потом усовершенствуем.


Вернуться к началу
 Профиль  
Ответить с цитатой  
 Заголовок сообщения: Re: Константные массивы
СообщениеДобавлено: 15 июл 2014, 18:16 
Не в сети
Аватара пользователя

Сообщения: 1019
Откуда: Днепропетровская обл.
Saferoll писал(а):
Правда не совсем так. NEW(x^.conval^.array(ConstArrayOfLInt)) выдает ошибку, если x^.conval^.array=NIL, потому что пустой указатель нельзя привести ни к какому типу, в том числе и к типу ConstArrayOfLInt.
Ух блин, да, точно. Надо так:
Код: "OBERON"
  1. CASE elemsize OF (* Размер элементов массива в байтах (для BlackBox). *)
  2. | 1: WITH x^.conval^.arr: ConstArrOfByte DO (* BOOLEAN, CHAR, SYSTEM.BYTE (для Ofront'а) *)
  3. NEW(x^.conval^.arr); NEW(x^.conval^.arr.val, size);
  4. END;
  5. | 2: WITH x^.conval^.arr: ConstArrOfSInt DO (* типы с размером в 2 байта *)
  6. NEW(x^.conval^.arr); NEW(x^.conval^.arr.val, size);
  7. END;
  8. | 4: WITH x^.conval^.arr: ConstArrOfInt DO (* типы с размером в 4 байта *)
  9. NEW(x^.conval^.arr); NEW(x^.conval^.arr.val, size);
  10. END;
  11. | 8: WITH x^.conval^.arr: ConstArrOfLInt DO (* типы с размером в 8 байт *)
  12. NEW(x^.conval^.arr); NEW(x^.conval^.arr.val, size);
  13. END;
  14. END;
Также предлагаю остановиться на названии записи и массива не array.data, а arr.val — будет аналогично intval, setval, realval.


Вернуться к началу
 Профиль  
Ответить с цитатой  
 Заголовок сообщения: Re: Константные массивы
СообщениеДобавлено: 27 ноя 2014, 22:10 
Не в сети
Администратор
Аватара пользователя

Сообщения: 273
Откуда: Россия
Есть кое-что новое в теме о константных массивах.
Итак. Прежде всего в модуле OfrontOPT необходимо ввести новые типы:
Код: "OBERON"
  1. ConstArray* = POINTER TO EXTENSIBLE RECORD END;
  2.  
  3. ConstArrayOfByte* = POINTER TO RECORD(ConstArray)
  4. val*: POINTER TO ARRAY OF BYTE;
  5. END;
  6.  
  7. ConstArrayOfSInt*= POINTER TO RECORD(ConstArray)
  8. val*: POINTER TO ARRAY OF SHORTINT;
  9. END;
  10.  
  11. ConstArrayOfInt* = POINTER TO RECORD(ConstArray)
  12. val*: POINTER TO ARRAY OF INTEGER;
  13. END;
  14.  
  15. ConstArrayOfLInt* = POINTER TO RECORD(ConstArray)
  16. val*: POINTER TO ARRAY OF LONGINT;
  17. END;
  18.  
  19. ConstDesc* = RECORD
  20. ext*: ConstExt; (* string or code for code proc *)
  21. intval*: INTEGER; (* constant value or adr, proc par size, text position or least case label *)
  22. intval2*: INTEGER; (* string length, proc var size or larger case label *)
  23. setval*: SET; (* constant value, procedure body present or "ELSE" present in case *)
  24. realval*: REAL; (* real or longreal constant value *)
  25. arr*: ConstArray; (* для данных константного массива *)
  26. END ;
Затем в модуле OfrontOPP нужно написать новую процедуру
Код: "OBERON"
  1. PROCEDURE ConstArray (VAR x: OPT.Node);
  2. VAR apar: OPT.Node; n,size,i: INTEGER; fp: OPT.Object; y: OPT.ConstArrayOfInt;
  3. BEGIN
  4. IF x^.obj^.typ^.BaseTyp^.form IN intSet THEN (* массив из целых, позднее добавим BYTE *)
  5. n:=x^.obj^.typ^.n; (* количество элементов массива *)
  6. CheckSym(lparen); (* скобка ( *)
  7. fp := OPT.NewObj(); fp^.typ := x^.obj^.typ^.BaseTyp;
  8. fp^.mode := Var; (* fp - переменная, элемент массива *)
  9. (* тут нужно бы выделить кусок памяти для n элементов массива *)
  10. NEW(y); NEW(y.val, n);
  11. IF sym # rparen THEN
  12. i := 0;
  13. LOOP ConstExpression(apar); (* берем очередной элемент *)
  14. IF i < n THEN
  15. OPB.Param(apar,fp); (* проверим на совместимость*)
  16. (* тут нужно положить элемент в кусок памяти *)
  17. y.val[i] := apar^.conval^.intval;
  18. INC(i);
  19. ELSE err(64)
  20. END ;
  21. IF sym = comma THEN OPS.Get(sym)
  22. ELSIF (lparen <= sym) & (sym <= ident) THEN err(comma)
  23. ELSE EXIT
  24. END
  25. END
  26. END ;
  27. (* x - тип массив, y -элементы массива в памяти, *)
  28. fp := x^.obj; (* запомним тип "массив"*)
  29. x := OPB.NewIntConst(n);
  30. x^.conval^.arr := y;
  31. x^.obj := fp; (* константа с типом "массив" *)
  32. IF i # n THEN err(65) END;
  33. CheckSym(rparen);
  34. ELSE err(51)
  35. END;
  36. END ConstArray;
и изменить начало процедуры Block
Код: "OBERON"
  1. PROCEDURE Block(VAR procdec, statseq: OPT.Node);
  2. VAR typ: OPT.Struct;
  3. obj, first, last: OPT.Object;
  4. x, lastdec: OPT.Node;
  5. i: SHORTINT;
  6.  
  7. BEGIN first := NIL; last := NIL; nofFwdPtr := 0;
  8. LOOP
  9. IF sym = const THEN
  10. OPS.Get(sym);
  11. WHILE sym = ident DO
  12. OPT.Insert(OPS.name, obj); CheckMark(obj^.vis);
  13. obj^.typ := OPT.sinttyp; obj^.mode := Var; (* Var to avoid recursive definition *)
  14. IF sym = eql THEN
  15. OPS.Get(sym);
  16. IF sym = ident THEN (* если это идентификатор *)
  17. x := OPT.NewNode(Ntype); qualident(x^.obj); (* берем его как идентификатор типа *)
  18. IF (x^.obj^.mode = Typ) & (x^.obj^.typ^.form = Comp) & (x^.obj^.typ^.comp = Array)
  19. THEN ConstArray(x)
  20. ELSE ConstExpression(x) (* обрабатываем стандартным образом *)
  21. END
  22.  
  23. ELSE
  24. ConstExpression(x)
  25. END
  26. ELSIF sym = becomes THEN
  27. err(eql); OPS.Get(sym); ConstExpression(x)
  28. ELSE err(eql); x := OPB.NewIntConst(1)
  29. END ;
  30. obj^.mode := Con; obj^.typ := x^.typ; obj^.conval := x^.conval; (* ConstDesc ist not copied *)
  31. IF obj^.conval^.arr # NIL THEN
  32. obj^.mode := Var; (* как будто это переменная *)
  33. obj^.typ := x^.obj^.typ;
  34. obj^.typ^.pvused := TRUE; (* не знаю, нужно ли это *)
  35. IF last = NIL THEN OPT.topScope^.scope := obj ELSE last^.link := obj END ;
  36. last := obj;
  37. first := NIL;
  38. END;
  39. CheckSym(semicolon)
  40. END
  41. END;
  42. IF sym = type THEN
  43. ...
И, наконец, изменим в модуле OfrontOPC процедуру IdentList
Код: "OBERON"
  1. PROCEDURE IdentList (obj: OPT.Object; vis: SHORTINT);
  2. (* generate var and param lists; vis: 0 all global vars, local var, 1 exported(R) var, 2 par list, 3 scope var *)
  3. VAR base: OPT.Struct; first: BOOLEAN; lastvis: SHORTINT; i: INTEGER;
  4. BEGIN
  5. base := NIL; first := TRUE;
  6. WHILE (obj # NIL) & (obj^.mode # TProc) DO
  7. IF (vis IN {0, 2}) OR ((vis = 1) & (obj^.vis # 0)) OR ((vis = 3) & ~obj^.leaf) THEN
  8. IF (obj^.typ # base) OR (obj^.vis # lastvis) OR
  9. ((obj^.conval # NIL) & (obj^.conval^.arr # NIL)) THEN (* каждый конст.массив отдельно*)
  10. (* new variable base type definition required *)
  11. IF ~first THEN EndStat END ;
  12. first := FALSE;
  13. base := obj^.typ; lastvis := obj^.vis;
  14. BegStat;
  15. IF (vis = 1) & (obj^.vis # internal) THEN OPM.WriteString(Extern)
  16. ELSIF (obj^.mnolev = 0) & (vis = 0) THEN
  17. IF (obj^.conval # NIL) & (obj^.conval^.arr # NIL) THEN (* конст.массив *)
  18. OPM.WriteString("const ");
  19. ELSIF obj^.vis = internal THEN OPM.WriteString(Static)
  20. ELSE OPM.WriteString(Export)
  21. END
  22. END;
  23. IF (vis = 2) & (obj^.mode = Var) & (base^.form = Real) THEN OPM.WriteString("double")
  24. ELSE DeclareBase(obj)
  25. END
  26. ELSE OPM.Write(",");
  27. END;
  28. OPM.Write(Blank);
  29. IF (vis = 2) & (obj^.mode = Var) & (base^.form = Real) THEN OPM.Write("_") END ;
  30. DeclareObj(obj, vis = 3);
  31. IF obj^.typ^.comp = DynArr THEN (* declare len parameter(s) *)
  32. EndStat; BegStat;
  33. base := OPT.linttyp;
  34. OPM.WriteString("LONGINT "); LenList(obj, FALSE, TRUE)
  35. ELSIF (obj^.mode = VarPar) & (obj^.typ^.comp = Record) THEN
  36. EndStat; BegStat;
  37. OPM.WriteString("LONGINT *"); Ident(obj); OPM.WriteString(TagExt);
  38. base := NIL
  39. ELSIF ptrinit & (vis = 0) & (obj^.mnolev > 0) & (obj^.typ^.form = Pointer) THEN
  40. OPM.WriteString(" = NIL")
  41. ELSIF (obj^.conval # NIL) & (obj^.conval^.arr # NIL) THEN (* элементы конст.массива *)
  42. OPM.WriteString(" ="); OPM.WriteLn; OPM.WriteString(" {");
  43.  
  44. FOR i := 0 TO obj^.conval^.intval-2 DO
  45. OPM.WriteInt(obj^.conval^.arr(OPT.ConstArrayOfInt).val[i]);
  46. OPM.WriteString(",");
  47. IF (i+1) MOD 10 = 0 THEN OPM.WriteLn; OPM.WriteString(" ") END;
  48. END;
  49. OPM.WriteInt( obj^.conval^.arr (OPT.ConstArrayOfInt) .val[obj^.conval^.intval-1]);
  50. OPM.WriteString("}");
  51. END
  52. END;
  53. obj := obj^.link
  54. END;
  55. IF ~first THEN EndStat END
  56. END IdentList;


Вернуться к началу
 Профиль  
Ответить с цитатой  
 Заголовок сообщения: Re: Константные массивы
СообщениеДобавлено: 27 ноя 2014, 22:28 
Не в сети
Администратор
Аватара пользователя

Сообщения: 273
Откуда: Россия
В результате
Код: "OBERON"
  1. TYPE TheClocks = ARRAY 23 OF INTEGER;
  2. CONST AnimClockData = TheClocks (00400, 00070, 00000,17, 00100, 00380, 00000, 00700, 03008, 00099, 100, 00170, 00010,12, 00103, 0030, 00300, 00400, 031, 00019,1,2,3);
  3. AnimClockData1 = TheClocks(00402, 00070, 00000,17, 00100, 00380, 00000, 00700, 03008, 00990, 100, 00170, 00010,12, 00103, 0030, 00300, 00400, 031, 00019,5,6,7);
  4.  
транслируется в
Код: "C"
typedef
INTEGER Unsigned_TheClocks[23];
 
const Unsigned_TheClocks Unsigned_AnimClockData =
{400,70,0,17,100,380,0,700,3008,99,
100,170,10,12,103,30,300,400,31,19,
1,2,3};
const Unsigned_TheClocks Unsigned_AnimClockData1 =
{402,70,0,17,100,380,0,700,3008,990,
100,170,10,12,103,30,300,400,31,19,
5,6,7};

И пока, к сожалению, на этом всё. Использование константных массивов не сделано.
Честно сказать, этот результат получен в большей мере эмпирическим путём, многое в работе с типами и идентификаторами осталось непонятно. Наверняка здесь есть ошибки, неточности и что-то лишнее.
Но уже можно тестировать.


Вернуться к началу
 Профиль  
Ответить с цитатой  
 Заголовок сообщения: Re: Константные массивы
СообщениеДобавлено: 28 ноя 2014, 08:08 
Не в сети
Администратор
Аватара пользователя

Сообщения: 273
Откуда: Россия
А использование получилось само собой! :shock:
Я ничего больше не дописывал, но обнаружил, что
Код: "OBERON"
  1. MODULE Unsigned; (*$MAIN*)
  2. IMPORT SYSTEM, P := Platform, B := Basic;
  3.  
  4. TYPE TheClocks = ARRAY 23 OF INTEGER;
  5. CONST AnimClockData = TheClocks (00400, 00070, 00000,17, 00100, 00380, 00000, 00700, 03008, 00099, 100, 00170, 00010,12, 00103, 0030, 00300, 00400, 031, 00019,1,2,3);
  6. AnimClockData1 = TheClocks(00402, 00070, 00000,17, 00100, 00380, 00000, 00700, 03008, 00990, 100, 00170, 00010,12, 00103, 0030, 00300, 00400, 031, 00019,5,6,7);
  7.  
  8. VAR
  9.  
  10. i: INTEGER;
  11. BEGIN
  12. i:= AnimClockData [1];
  13. B.PRWORD(i);
  14. END Unsigned.
уже транслируется в
Код: "C"
/*  Ofront 1.2 -xtspkaem */
#include "SYSTEM.h"
#include "Basic.h"
#include "Platform.h"
 
typedef
INTEGER Unsigned_TheClocks[23];
 
 
const Unsigned_TheClocks Unsigned_AnimClockData =
{400,70,0,17,100,380,0,700,3008,99,
100,170,10,12,103,30,300,400,31,19,
1,2,3};
const Unsigned_TheClocks Unsigned_AnimClockData1 =
{402,70,0,17,100,380,0,700,3008,990,
100,170,10,12,103,30,300,400,31,19,
5,6,7};
static INTEGER Unsigned_i;
 
 
 
 
/*============================================================================*/
 
 
export main(int argc, char **argv)
{
__INIT(argc, argv);
__IMPORT(Basic__init);
__IMPORT(Platform__init);
__REGMAIN("Unsigned", 0);
/* BEGIN */
Unsigned_i = Unsigned_AnimClockData[1];
Basic_PRWORD(Unsigned_i);
__FINI;
}
Но при этом
Код: "OBERON"
  1. AnimClockData1[2] := i;
тоже допускается, т.е. похоже для Ofront это обычная переменная-массив. Необходимо где-то задать ограничение на допустимость присваивания (например, как для IN-параметра).


Вернуться к началу
 Профиль  
Ответить с цитатой  
 Заголовок сообщения: Re: Константные массивы
СообщениеДобавлено: 28 ноя 2014, 13:12 
Не в сети
Администратор
Аватара пользователя

Сообщения: 273
Откуда: Россия
Zorko писал(а):
Кстати, надо не забыть, что const - сиплюсплюсная фича, поэтому нужно будет подменить прямую генерацию const на какой-нить __CONSTARR:
Код: "C"
#ifdef __SDCC
# define __CONSTARR const // потому как без const SDCC дублирует данные массива так, что они занимают в два раза больше памяти. Я сам был в шоке.
#else
# define __CONSTARR // а здесь будет просто объявление массива без всяких const - чтобы работало в таких компиляторах как Turbo C (который не ++).
#endif
Это учесть несложно: в процедуре IdentList модуля OfrontOPC вместо OPM.WriteString("const "); пишем OPM.WriteString("__CONSTARR ");. Ну и, конечно, не забываем добавить вышеуказанные макросы препроцессора в системные библиотеки.
Для красоты листинга, возможно, еще потребуется скорректировать отступы, т.к. "__CONSTARR" занимает больше места, чем "const".


Вернуться к началу
 Профиль  
Ответить с цитатой  
 Заголовок сообщения: Re: Константные массивы
СообщениеДобавлено: 28 ноя 2014, 13:26 
Не в сети
Администратор
Аватара пользователя

Сообщения: 273
Откуда: Россия
Чтобы был возможен массив из байтов, потребуется внести изменения в процедуру ConstArray. А именно, необходимо изменить строку
Код: "OBERON"
  1. IF x^.obj^.typ^.BaseTyp^.form IN intSet THEN (* массив из целых, позднее добавим тип BYTE *)
на
Код: "OBERON"
  1. IF x^.obj^.typ^.BaseTyp^.form IN intSet THEN (* массив из целых (с типом BYTE, оказывается, тоже уже работает!) *)
:D

Изменения столь "существенны" потому, что intSet давно содержит и байтовый тип (тип перешёл из SYSTEM.BYTE просто в BYTE).

Но...это весьма странный байт:
1) он знаковый, в диапазоне -128...127
2) с ним очень мало что можно сделать - нельзя сложить или вычесть, нельзя присвоить переменной другого целого типа. Даже преобразовать при помощи LONG нельзя.
Впрочем, это проблемы не константных массивов, а самой системы целых типов.


Вернуться к началу
 Профиль  
Ответить с цитатой  
 Заголовок сообщения: Re: Константные массивы
СообщениеДобавлено: 28 ноя 2014, 16:22 
Не в сети
Аватара пользователя

Сообщения: 1019
Откуда: Днепропетровская обл.
Олежка, в первую очередь спасибо за твою реализацию константных массивов. :) Это обязательно пригодится. Прямой выход на уровень Си становится ещё менее нужным. К тому же экономится память в сравнении с Basic.DATA* (в ZXDev). И это ещё помимо общей эстетики и кроссплатформенности (в отличие от того же Basic.DATA*). :)

"Странность" типа BYTE проистекает из-за того, что он не задумывался как числовой. Вирту, а потом Темплу не нужен был 64-битный тип целых, им хватало линейки SHORTINT (8), INTEGER (16) и LONGINT (32). Числовым BYTE сделали в Обероне-07 (там он беззнаковый 0..255 и совместим с 32-битным INTEGER без всяких кастов SHORT() и LONG()), в Компонентном Паскале и даже в OO2C, что пошло типу, как мне кажется, только на пользу.

Для чего же нужен был такой нечисловой тип BYTE в Обероне изначально? А вот сейчас наверное удивлю, да я и сам удивлялся. :)

Код: "OBERON"
  1. PROCEDURE FlipBytes(VAR src, dest: ARRAY OF BYTE);
  2. ...
  3. END FlipBytes;
  4. `
  5. PROCEDURE WriteReal* (VAR R: Rider; x: REAL);
  6. VAR b: ARRAY 4 OF CHAR;
  7. BEGIN FlipBytes(x, b); ...
  8. (* ^ x: REAL, но совместим с ARRAY OF BYTE! *)
  9. (* ^ b: ARRAY OF CHAR, но совместим с ARRAY OF BYTE! *)
  10. END WriteReal;
То есть это реально системный тип, который нужен чтобы проломиться сквозь строгую типизацию.

Какой же будет наша стратегия? Я не против смягчить тип BYTE до числового, чтобы он был вписан в линейку целых типов. Уже даже сделал несколько правок, чтобы данные типа BYTE можно было бы использовать в CASE byte OF, и ещё что-то на эту тему. Но до полной реализации ещё далеко.

Что делать со знаковостью BYTE? А ничего, превращать в знаковый вычетом 256 или использовать вместо него CHAR. Кстати, переменным типа BYTE можно присваивать символы и их коды:
Код: "OBERON"
  1. VAR a: BYTE; BEGIN
  2. a := 254 - 100H;
  3. a := 0FEX;
Так работает.

Уверен, знаковость BYTE — не недостаток, это просто одна из сторон альтернативы в духе системы типов Оберона.

Норайра Чилингаряна (разработчика Vishap Oberon Compiler) после OO2C тоже смутил такой BYTE, но пока что он его не трогает, мирится.

Кстати, в GPCP наряду с типом BYTE есть также тип UBYTE. Если нам понадобится беззнаковый байтовый тип, можем сделать так же.


Вернуться к началу
 Профиль  
Ответить с цитатой  
 Заголовок сообщения: Re: Константные массивы
СообщениеДобавлено: 28 ноя 2014, 16:50 
Не в сети
Администратор
Аватара пользователя

Сообщения: 273
Откуда: Россия
Zorko писал(а):
Для чего же нужен был такой нечисловой тип BYTE в Обероне изначально? А вот сейчас наверное удивлю, да я и сам удивлялся. :)
Действительно, удивительно! Он как будто и не целочисленный тип.

Вот это меня и смущает больше, чем знаковость. Как, например, преобразовать BYTE в INTEGER или SHORTINT? Напрямую присвоить нельзя, LONG не работает, арифметические операции не действуют. Через REAL или CHAR исхитряться?

А знаковость пусть остаётся... Мне же легче будет FOR приспособить :)


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

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


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

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


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

Найти:
Перейти:  
cron
Создано на основе phpBB® Forum Software © phpBB Group
© VEDAsoft Oberon Club