Войти
ФлеймФорумПрограммирование

[C++SNO] Safe Navigation Operator (3 стр)

Страницы: 1 2 3 4 Следующая »
#30
15:24, 19 дек. 2013

Pushkoff

int baz_v1(foo*p){
  int y=5;
  int z=p?->x:LABEL1;
  printf("abc");
  y=z;  <<<------- хорошо подумай над этой строчкой
LABEL1:
  return y;
}

#31
16:01, 19 дек. 2013

TarasB

int z=p?->x:LABEL1;
Что это? У меня не компилируется, не с SNO ни без него.

а всё понял, это типа такой feature request? типа указывать метку куда прыгать если p == nullprt
:lol:

#32
16:02, 19 дек. 2013

Adler
> с SNO
Что, уже есть такие компиляторы?
Или ты компилировал шарпиком?
Кстати, в нём я тоже не вруаюсь в конструкцию, особенно где стоит ??

#33
16:20, 19 дек. 2013

Pushkoff
> но как компилятор должен узнать что bar не должен вызываться?
должно быть вот это "bar(p?->x)" в терминах AST представляеться как-то вот так: t_call_expr
и состоит из:

struct t_call_expr:i_expr{
  // 
  string func_name;
  // (
  vector<unique_ptr<i_expr>> params;
  // )
};

//ещё нам пригодиться вот это:
struct t_if_stat:i_statement{
  // if (
  unique_ptr<i_expr> expr;
  // )
  unique_ptr<i_statement> before_else;
  // else
  unique_ptr<i_statement> after_else;
  // ;
};
//и ещё вот это:
struct t_expr_stat:i_statement{
  //
  unique_ptr<i_expr> expr;
  // ;
};
//и ещё вот это:
struct t_block_stat:i_statement{
  // {
  vector<unique_ptr<i_statament>> arr;
  // }
};
ну так вот, компилятор берёт unique_ptr<i_statement> залезает внутрь его и смотрит есть там t_call_expr или нет.
затем если он нашёл там t_call_expr, то для каждого из них он смотрит все выражения в t_call_expr::params и ищет есть там вызов SNO.
короче, компилятор должен найти наследника i_statement внутри которого есть хотя бы один вызов SNO, если нашёл, то тогда он должен...

короче, всё это дело он должен проделывать, когда конвертирует исходное AST с SNO в новое AST без SNO.
тоесть он должен развернуть все SNO за один проход по AST или бросить ошибку.

ну так вот, значит, конвертим мы исходно AST в другое AST без SNO и нашли в исходном AST такого наследника i_statement`а внутри которого есть SNO.
ну мы типа не растерялись и дали ему имя X.
затем сразу нашли t_block_stat внутри которого лежит нашь X. ну как нашли? мы когда по дерву спускались нужно было его просто не забыть (:
ну вот, а потом типа хоп и обернули пачку наследников i_statement из t_block_stat::arr начиная с нашего X и до самого конца блока.
обернули значит их в t_if_stat. ну как обернули? да засунили просто в новый t_block_stat, а новый t_block_stat засунули в t_if_stat::before_else.
так, теперь надо t_if_stat::expr задать.
это можно сделать глядя на SNO из исходного AST.
теперь надо нашь t_if_stat выплюнуть в AST без SNO. ну выплюнули и вот, вроде и всё, я ничего не забыл?
> но как компилятор должен узнать что bar не должен вызываться?
а что есть какие-то проблемы?

#34
16:40, 19 дек. 2013

Adler
if (foo(bar(baz(p?->i == 10)))) printf("");
что не должно вызываться?

#35
16:55, 19 дек. 2013

что-то как-то не так, не проще ли сделать так что если проверка не проходит то возвращается 0 ?
например это

int Val = SomeVal?->x;
Foo(SomeVal?->x);
превратится в
int Val = SomeVal ? SomeVal->x : 0;

Foo(SomeVal ? SomeVal->x : 0);
ещё бы дополнительно прикрутить оператор ?? было бы классно

#36
16:58, 19 дек. 2013

Chaos_Optima
> ещё бы дополнительно прикрутить оператор ?? было бы классно
а что он делает?

#37
17:01, 19 дек. 2013

Chaos_Optima
> не проще ли сделать так что если проверка не проходит то возвращается 0 ?
тогда p?->x = 10; не будет работать.


Предлагаю разрешить объявлять любые последовательности знаков препинания оператором. А над их реализацией пусть пользователи думают.

#38
17:15, 19 дек. 2013

TarasB
> а что он делает?
В С# он проверяет если левая сторона == null то подставляет правую

SomeClass* obj = 0;
SomeClass* obj2 = new SomeClass();
....
auto val = obj ?? obj2; // равносильно auto val = obj ? obj : obj2;

kipar
> тогда p?->x = 10; не будет работать.
Так и не должен, насколько я понял в Groovy он сделан именно для возвращения значения на подобии тернарного оператора.
ИМХО это само разумное применение.

#39
17:19, 19 дек. 2013

Chaos_Optima
> auto val = obj ?? obj2; // равносильно auto val = obj ? obj : obj2;
нужно подправить && чтоб возвращало не bool а один из объектов который потом бы приводился к bool

#40
17:25, 19 дек. 2013

Pushkoff
> нужно подправить && чтоб возвращало не bool а один из объектов который потом бы
> приводился к bool
А что тогда с bool типами делать? ))  false && true в даннов случае вернёт true.
не лучше добавить новый оператора в дополнении к тернарному. Правда он получится контекстно зависимым ((

#41
17:31, 19 дек. 2013

Chaos_Optima
> false && true в даннов случае вернёт true.
Я думаю Пушков имел в виду ||. В руби это стандартная идиома, в питоне возможно тоже.

#42
17:56, 19 дек. 2013

Pushkoff
> if (foo(bar(baz(p?->i == 10)))) printf("");
> что не должно вызываться?
у этого кода t_if_stat непонятно где находится, а алгоритм который конвертирует "AST с SNO" в "AST без SNO" вроде как требует, чтобы сверху над t_if_stat был t_block_stat.
ну хотябы вот так надо сделать:

{if (foo(bar(baz(p?->i == 10)))) printf("");}
вот, теперь можно искать в t_if_stat::expr выражение с SNO:
+ Показать

если нашли, то тогда ищем t_block_stat внутри которого всё это хозяйство лежит:
+ где-то тут

и заменяем его в новом AST без SNO:
+ на вот это

>что не должно вызываться?
давай я просто покажу код который эквивалентен полученному AST без SNO:
{if(p)if(foo(bar(baz(p->i==10))))printf("");}
#43
18:11, 19 дек. 2013

kipar
> Я думаю Пушков имел в виду ||.
да.
я вспомнил про or die() из PHP.

Adler
> давай я просто покажу код который эквивалентен полученному AST без SNO:
а если у нас ?-> встречается 2 раза?

#44
18:13, 19 дек. 2013

Adler
к стати наличие скобок убивает компактность

{if (foo(bar(baz(p?->i == 10)))) printf("");}

оно же

if (p&&foo(bar(baz(p->i == 10)))) printf("");

Страницы: 1 2 3 4 Следующая »
ФлеймФорумПрограммирование

Тема в архиве.