Автор Тема: Вопрос по биндингу ? Или что тут еще требуется?  (Прочитано 110096 раз)

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re: Вопрос по биндингу ? Или что тут еще требуется?
« Ответ #195 : Ноябрь 06, 2013, 09:50:35 am »
Имеем, функцию (которую надо биндить), возвращающий разные объекты в зависимости от строкового параметра функции), хотелось бы оставить именно в виде одной функции, но судя по всему, придется делать отдельными функциями для каждого возвращаемого объекта

Ну а в чём проблема? Расширяемые записи с этим вполне справятся...

Вот пример для акроновского компилятора оберона:
MODULE Records;
IMPORT RTL, In, Out;

TYPE
  PBaseType = POINTER TO BaseType;
  BaseType  = RECORD END;

  PIntVal   = POINTER TO IntVal;
  IntVal    = RECORD (BaseType) value: INTEGER END;

  PRealVal  = POINTER TO RealVal;
  RealVal   = RECORD (BaseType) value: REAL    END;

  PCharVal  = POINTER TO CharVal;
  CharVal   = RECORD (BaseType) value: CHAR    END;

PROCEDURE Foo(x: INTEGER) : PBaseType;
VAR
  ret : PBaseType;
  int : PIntVal;
  real: PRealVal;
  char: PCharVal;
BEGIN
  NEW(int);  int .value := -123;
  NEW(real); real.value := 3.14;
  NEW(char); char.value := "a";

  CASE x OF
  | 1: ret := int
  | 2: ret := real
  | 3: ret := char
  ELSE ret := NIL
  END
RETURN ret
END Foo;

PROCEDURE Boo(x: PBaseType);
BEGIN
  IF    x IS PIntVal THEN
    Out.String("[INTEGER] "); Out.Int (x(PIntVal) .value, 0)
  ELSIF x IS PRealVal THEN
    Out.String("[REAL] ");    Out.Real(LONG(x(PRealVal).value), 0)
  ELSIF x IS PCharVal THEN
    Out.String("[CHAR] ");    Out.Char(x(PCharVal).value)
  ELSE
    Out.String("NIL-value");
  END
END Boo;

BEGIN
  In.Open;  Out.Open;

  Out.String("x = 0, value = "); Boo(Foo(0)); Out.Ln;
  Out.String("x = 1, value = "); Boo(Foo(1)); Out.Ln;
  Out.String("x = 2, value = "); Boo(Foo(2)); Out.Ln;
  Out.String("x = 3, value = "); Boo(Foo(3)); Out.Ln;

  In.Ln
END Records.
to iterate is human, to recurse, divine

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

adva

  • Sr. Member
  • ****
  • Сообщений: 385
    • Просмотр профиля
Re: Вопрос по биндингу ? Или что тут еще требуется?
« Ответ #196 : Ноябрь 06, 2013, 10:47:48 am »
О, спасибо, за понятный пример. А что получается, что при присваивании базовому типу расширенного, ему присваиваются и расширенные поля (те которые не входят изначально в базовый тип)?

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Re: Вопрос по биндингу ? Или что тут еще требуется?
« Ответ #197 : Ноябрь 06, 2013, 11:05:45 am »
...
Вот пример для акроновского компилятора оберона:
...
  CASE x OF
  | 1: ret := int
  | 2: ret := real
  | 3: ret := char
  ELSE ret := NIL
  END
...

Замечу, что это не Оберон - в Обероне нет варианта ELSE в CASE statement. См. грамматику. Все варианты должны быть перечислены явным образом.
Y = λf.(λx.f (x x)) (λx.f (x x))

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re: Вопрос по биндингу ? Или что тут еще требуется?
« Ответ #198 : Ноябрь 06, 2013, 11:20:26 am »
О, спасибо, за понятный пример. А что получается, что при присваивании базовому типу расширенного, ему присваиваются и расширенные поля (те которые не входят изначально в базовый тип)?

Кстати да, пока речь идёт об указателях на записи -- всё понятно.
А как быть с записями-значениями?
MODULE test;
IMPORT JS;
 
TYPE
  BaseRec = RECORD END;
  Rec2    = RECORD (BaseRec) x : INTEGER END;

VAR
  br : BaseRec;
  r2 : Rec2;
 
BEGIN
  r2.x := 42;
  br := r2;
END test.
OberonJS это с удовольствием компилирует, но не происходит ли тут нарушения памяти?
to iterate is human, to recurse, divine

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

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re: Вопрос по биндингу ? Или что тут еще требуется?
« Ответ #199 : Ноябрь 06, 2013, 11:32:06 am »
...
Вот пример для акроновского компилятора оберона:
...
  CASE x OF
  | 1: ret := int
  | 2: ret := real
  | 3: ret := char
  ELSE ret := NIL
  END
...

Замечу, что это не Оберон - в Обероне нет варианта ELSE в CASE statement. См. грамматику. Все варианты должны быть перечислены явным образом.

Да, и правда, а как же быть в подобных случаях? о_О
to iterate is human, to recurse, divine

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

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re: Вопрос по биндингу ? Или что тут еще требуется?
« Ответ #200 : Ноябрь 06, 2013, 11:42:10 am »
У акроновского компилятора ещё и операция проверки типа отличается от описания последней ревизии оберона -- вторым параметром требует имя типа указателя на запись вместо имени типа записи...
Вот доработанная версия для OberonJS:
MODULE Records;
IMPORT JS;

TYPE
  PBaseType = POINTER TO BaseType;
  BaseType  = RECORD END;

  PIntVal   = POINTER TO IntVal;
  IntVal    = RECORD (BaseType) value: INTEGER END;

  PRealVal  = POINTER TO RealVal;
  RealVal   = RECORD (BaseType) value: REAL    END;

  PCharVal  = POINTER TO CharVal;
  CharVal   = RECORD (BaseType) value: CHAR    END;

PROCEDURE Foo(x: INTEGER) : PBaseType;
VAR
  ret : PBaseType;
  int : PIntVal;
  real: PRealVal;
  char: PCharVal;
BEGIN
  NEW(int);  int .value := -123;
  NEW(real); real.value := 3.14;
  NEW(char); char.value := "a";

  CASE x OF
  | 1: ret := int
  | 2: ret := real
  | 3: ret := char
  END
RETURN ret
END Foo;

PROCEDURE Boo(x: PBaseType);
BEGIN
  IF    x IS IntVal  THEN JS.alert(x(PIntVal ).value)
  ELSIF x IS RealVal THEN JS.alert(x(PRealVal).value)
  ELSIF x IS CharVal THEN JS.alert(x(PCharVal).value)
  ELSE                    JS.alert("Oops!");
  END
END Boo;

BEGIN
  Boo(Foo(0));
  Boo(Foo(1));
  Boo(Foo(2));
  Boo(Foo(3))
END Records.
to iterate is human, to recurse, divine

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

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Re: Вопрос по биндингу ? Или что тут еще требуется?
« Ответ #201 : Ноябрь 06, 2013, 11:47:44 am »
...
Вот пример для акроновского компилятора оберона:
...
  CASE x OF
  | 1: ret := int
  | 2: ret := real
  | 3: ret := char
  ELSE ret := NIL
  END
...

Замечу, что это не Оберон - в Обероне нет варианта ELSE в CASE statement. См. грамматику. Все варианты должны быть перечислены явным образом.

Да, и правда, а как же быть в подобных случаях? о_О
Или IF .. ELSEIF .. ELSE, или указывать диапазон покрывающий все остальные значения.
Y = λf.(λx.f (x x)) (λx.f (x x))

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Re: Вопрос по биндингу ? Или что тут еще требуется?
« Ответ #202 : Ноябрь 06, 2013, 12:50:06 pm »
По поводу CASE - самое смешное, что если результат expression'a не соответствует ни одному из label, то программа спокойно продолжает работать. То есть HALT'а не будет:
x := 42;
CASE x OF
    1: ret := int
  | 2: ret := real
  | 3: ret := char
END

Это абсолютно валидный рабочий код с точки зрения современного Оберона.
Y = λf.(λx.f (x x)) (λx.f (x x))

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re: Вопрос по биндингу ? Или что тут еще требуется?
« Ответ #203 : Ноябрь 06, 2013, 01:02:24 pm »
По поводу CASE - самое смешное, что если результат expression'a не соответствует ни одному из label, то программа спокойно продолжает работать. То есть HALT'а не будет:
x := 42;
CASE x OF
    1: ret := int
  | 2: ret := real
  | 3: ret := char
END

Это абсолютно валидный рабочий код с точки зрения современного Оберона.

Ну а почему здесь должен быть HALT?
Ведь раз CASE OF просто синтаксических сахар для IF-ELSIF, то этот код эквивалентен такому:
x := 42;
IF    x = 1 THEN ret := int
ELSIF x = 2 THEN ret := real
ELSIF x = 3 THEN ret := char
END
Тут же всё в порядке, ветка ELSE не является обязательной...
to iterate is human, to recurse, divine

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

akron1

  • Jr. Member
  • **
  • Сообщений: 76
    • Просмотр профиля
Re: Вопрос по биндингу ? Или что тут еще требуется?
« Ответ #204 : Ноябрь 06, 2013, 01:28:28 pm »
У акроновского компилятора ещё и операция проверки типа отличается от описания последней ревизии оберона -- вторым параметром требует имя типа указателя на запись вместо имени типа записи...
Не совсем так. В моей реализации первый и второй параметры должны соответствовать. Если первый параметр -- запись, то требуется имя типа-записи. В репорте написано:

Цитировать
v IS T stands for "v is of type T" and is called a type test. It is applicable, if
1. T is an extension of the declared type T0 of v, and if
2. v is a variable parameter of record type or v is a pointer.

Из этого не ясно, является ли тип T записью или указателем. И должен ли он соответствовать типу v.

vlad

  • Hero Member
  • *****
  • Сообщений: 1391
    • Просмотр профиля
Re: Вопрос по биндингу ? Или что тут еще требуется?
« Ответ #205 : Ноябрь 06, 2013, 03:49:10 pm »
OberonJS это с удовольствием компилирует, но не происходит ли тут нарушения памяти?

Копируется кусок объекта. Нормальная ситуация при условии понимания, что это именно то, чего ты хочешь.

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re: Вопрос по биндингу ? Или что тут еще требуется?
« Ответ #206 : Ноябрь 06, 2013, 03:57:38 pm »
OberonJS это с удовольствием компилирует, но не происходит ли тут нарушения памяти?

Копируется кусок объекта. Нормальная ситуация при условии понимания, что это именно то, чего ты хочешь.

А как же инварианты объектов? Они же вряд ли сохранятся при подобном частичном копировании...
to iterate is human, to recurse, divine

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

vlad

  • Hero Member
  • *****
  • Сообщений: 1391
    • Просмотр профиля
Re: Вопрос по биндингу ? Или что тут еще требуется?
« Ответ #207 : Ноябрь 06, 2013, 04:05:05 pm »
А как же инварианты объектов? Они же вряд ли сохранятся при подобном частичном копировании...

Они сохраняются, если ты делаешь все в рамках правильного ООП - наследники специализируют базу, т.е. накладывают дополнительные инварианты (а не снимают базовые) - ты не наследуешь прямоугольник от квадрата и т.п.

adva

  • Sr. Member
  • ****
  • Сообщений: 385
    • Просмотр профиля
Re: Вопрос по биндингу ? Или что тут еще требуется?
« Ответ #208 : Ноябрь 07, 2013, 03:01:06 am »
Вот доработанная версия для OberonJS:
MODULE Records;
...
END Records.

Ну вот, вроде был понял, еще раз огромное спасибо

adva

  • Sr. Member
  • ****
  • Сообщений: 385
    • Просмотр профиля
Re: Вопрос по биндингу ? Или что тут еще требуется?
« Ответ #209 : Ноябрь 07, 2013, 04:18:15 am »
Почему то в моем коде RTL$.typeGuard не корректно отрабатывает. Какие функции, чтобы тип переменной вывести? typeof(переменная) или как то еще?