OSDev

для всех
Текущее время: 15 ноя 2018, 21:58

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




Начать новую тему Ответить на тему  [ Сообщений: 285 ]  На страницу Пред.  1 ... 11, 12, 13, 14, 15, 16, 17 ... 29  След.
Автор Сообщение
СообщениеДобавлено: 20 дек 2014, 21:09 
Аватара пользователя

Зарегистрирован: 28 май 2012, 23:44
Сообщения: 237
Откуда: Санкт-Петербург
Zealint писал(а):
У меня размер левого отступа определяет степень вложенности.

Мне кажется, что это другая крайность, вызванная посттравматическим синдромом от пользования тазиком. Нужно быть последовательным. Если операторы ветвления, цикла и прочие обозначаются ключевыми словами, их составное тело должно ограничиваться также ключевым словом. Скобки и символы -- только в выражениях. В этих условиях начинает работать правило "отступ -- два пробела", а синтаксис остается свободным.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 20 дек 2014, 21:37 
Аватара пользователя

Зарегистрирован: 17 фев 2013, 16:13
Сообщения: 163
[ 15 ] :: Комментарии

Символы комментариев должны быть продуманы тогда, когда синтаксис языка уже будет чётко определён, чтобы не возникало конфликтов и возможных недоразумений типа «деления на указатель /*». Поэтому сейчас трудно сказать, какие символы лучше выбрать. Но есть несколько моментов, которые следует обозначить уже сейчас. Комментарии должны быть нескольких видов.

Должны быть однострочные комментарии для коротких пояснений, распространяющиеся на всю строку (аналог // в С)

Должны быть многострочные комментарии, когда комментарием считается всё, что между парой специальных символов (аналог /* */ в C). Однако здесь есть важный момент: при вложенном комментировании завершающей скобкой (*/) должна быть НЕ ПРОСТО ПЕРВАЯ комбинация, а та, которая подходит по уровню вложенности. Например,
Код:
Код программы /* Комментарий /* ещё комментарий */ всё ещё комментарий /* опять комментарий */ бла-бла */ а здесь уже код

Почему? Потому что бесит, когда нужно закомментировать большой блок кода (например, в процессе поиска трудноуловимой ошибки бинарным поиском), а в этом блоке уже несколько десятков маленьких блоков /* */. Приходится у каждого такого блока убирать закрывающий символ или добавлять один открывающий после. Такого не должно быть НИКОГДА.

Другой вариант избежать подобной нелепости – сделать по аналогии с Pascal, когда есть два вида многострочных комментариев и можно вкладывать друг в друга эти разные виды, не порождая подобных трудностей при грамотном анализе правильность скобочных последовательностей.

Но если мы внутри комментариев по какой-то причине захотим использовать символы комментирования, то будет опять непонимание, где же его закрывать. Не знаю, можно ли вообще решить данную проблему адекватно. Например, можно вынудить препроцессор искать последнюю подходящую по смыслу закрывающую скобку соответствующего типа, идущую непосредственно перед открывающей комментарий. Например
Код:
/* Коментарий*/ */ */ */
Код
/* Ещё Коментарий*/ */ */ */

Здесь компилятору очевидно, что последняя скобка в 1-й и 3-й строке закрывающая.

Код:
/* /* Коментарий*/
Не код, а комментарий
/* Ещё Коментарий*/ */ */ */

А здесь последняя скобка во 3-й строке закрывающая. Посередине уже не код, а комментарий.

Иногда программист специально оставляет комментарий типа fixme или !!! или ??? (у каждого свой такой символ), так вот, было бы неплохо, чтобы компилятор выдавал предупреждение, если увидит такой комментарий:
Код:
if ( a > b ) {
  return c;      // fixme: разобраться! Возвращается что-то не то.
}

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

Ещё один вид комментариев, который в редких случая может пригодиться: комментарии, которые распространяются на множество строк от одной строки до другой. Например:
Код:
begin-global-comment
Тут можно писать что угодно
end-global-comment

Между begin-... и end-... можно писать что угодно, это будет восприниматься как комментарий. Можно задать вопрос: а чем это отличается от /* */ ? Да по сути ничем, кроме приоритета и гарантии того, что между этой парой лексем может быть абсолютно что угодно, даже комментарии более низкого уровня. Здесь даже не будут раскрываться команды макроподстановки (см. ниже) - аналог verbatim в LaTeX. Не уверен, что это нужная штука здесь, но сообщить о ней обязан.

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

Есть такая вещь, как генерация документации из кода. При этом комментарии становятся частью документации. Однако отладочные комментарии, когда мы закомментировали ненужную пока функцию или строку, не должны туда попадать. Более того, удобно, если редактор подсвечивает подобные отладочные комментарии как-нибудь неярко, чтобы их почти не было видно. Таким образом, для отладки лучше иметь специальный отдельный вид комментариев, которые при этом имеют наивысший приоритет (ими можно закомментировать любой кусок кода и при вложенном комментировании). Отладочными комментариями можно также закомментировать кусок не отладочного комментария, чтобы он не попал в документацию.

Отладочные комментарии могут быть как однострочными так и многострочными.

Комментарии-шапки должны иметь достаточно богатый набор макроподстановок. Например, комментируя функцию, удобно перечислить в шапке её параметры и пояснить смысл, обозначив также их свойства (входной, выходной или имеет оба смысла). Например, (утрирую)
Код:
/**
 * max – возвращает максимальный из двух элементов.
 * 1 >>> int a – первое число
 * 2 >>> int b – второе число
 * Результат: int – максимум из a и b.
*/
int max ( int a, int b ) {
   …
}

(Символ >>> у меня означает «входной параметр»)

Теперь, допустим, мне пришло в голову почему-то изменить названия переменных и вместо a и b сделать p и q. Везде в комментариях теперь менять? Не, если в этом примере всё кажется простым, то есть куда более увесистые шапки, описывающие сущность функции аж на десятки строк. Поэтому можно (типа как в JavaDoc) придумать команду макроподстановки, которая в документации подставляет имена переменных в те места, куда следует. Можно ещё дополнительно подумать, какие макрокоманды нужны в комментариях (например, принудительный переход на новую страницу, ссылка на другую функцию, метки, вставка картинки и т. д.), но суть в том, что они нужны.

[ Продолжение следует ]


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 20 дек 2014, 21:39 
Аватара пользователя

Зарегистрирован: 17 фев 2013, 16:13
Сообщения: 163
Freeman писал(а):
Мне кажется, что это другая крайность, вызванная посттравматическим синдромом от пользования тазиком.

Возможно, Вы правы. Но тогда можно дополнительно сказать, что значительная часть моих размышлений в этой теме тоже вызвана похожим синдромом.


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

Зарегистрирован: 14 мар 2011, 12:31
Сообщения: 946
Откуда: Дагоба
Zealint писал(а):
Yoda писал(а):
Код:
int136 operator + (int136 a, int136 b) {
  int128 t = a.l + b.l;
  Result.l = int64(t);
  t = a.m + b.m + t>>64;
  Result.m = int64(t);
  Result.h = a.h + b.h + t>>64;
}

Ну вот, если теперь временно закрыть глаза на смешивание знакового и беззнакового типов (int64(t) может "вдруг" стать отрицательным), то как всё-таки компилятор догадается, что мы хотим использовать ADC?

Смешивание типов в данном случае не играет никакой роли, - операции сложения и вычитания двоичных чисел тождественны для знакового и беззнакового типов.
Что касается ADC. Вот перевёл компилятор умножение в последовательность машинных инструкций. Сначала загрузки операндов, затем инструкция MUL. Вы же не переживаете, как компилятор догадается, что результат умножения хранится в регистрах DX:AX. Почему? Потому что это его святая обязанность – помнить, где находятся источники данных и куда помещаются все компоненты результата. В данном случае компилятор точно так же обязан помнить, что старшая половина результата сложения хранится в бите переноса, а значит для последующего сложения с битом переноса он легко может использовать инструкцию ADC. Я не вижу проблем (кроме, может быть, чисто технических), связанных с такой обязанностью.

Zealint писал(а):
Yoda писал(а):
либо потеряется переносимость и универсальность (если наложить запрет на табуляции).

В упор не пойму, как здесь потеряется переносимость и универсальность. Мы заявляем, что есть только два символа-разделителя: перевод строки и пробел.

Потеря переносимости и универсальности в том, что вы не можете взять произвольный plain-text редактор и писать/править исходники.

Zealint писал(а):
Yoda писал(а):
Как вариант могу предложить следующее: постулировать, что оператор остатка работает только с беззнаковыми типами по обоим операндам.

Никак нельзя. В модулярной арифметике постоянно приходится брать остаток от отрицательных чисел. Потом нужно писать условие if ( x < 0 ) x += P, чтобы прийти к положительному остатку.

Если я не ошибаюсь, в модулярной арифметике любое число, чтобы быть валидным, должно быть в диапазоне 0...P-1, то есть положительным. Откуда у вас взялись отрицательные числа?

Zealint писал(а):
Yoda писал(а):
Не получится, т.к. для адресных операций не будет использоваться символ "*" (да и комментарии я хочу заменить). Вообще, это была крайне неудачная идея создателей языка. В моём синтаксисе это символ "@", что логично даже по его смыслу и названию.

Я всё время произношу "собака" или "сволочь" на символ @. А один из моих преподавателей заставлял говорить "коммерческое эт", за что (хотя и не только за это) я перестал ходить на его лекции : )

Я не понял, – вы на этом основании возражаете против этого символа? Кстати, в английском языке не говорят "коммерческое эт" – слишком длинно для них. Обычно говорят просто "эт". Википедия утверждает, что его часто называют "атперсанд" или "штрудель". В общем, называйте, как хотите.

Zealint писал(а):
Не помню, говорил ли, но я предлагаю зарезервировать такие слова не для того, чтобы ими нельзя было пользоваться, а для того, чтобы ими можно было сделать ТОЛЬКО типы данных и определить для них ТОЛЬКО те функции и операции, которые есть для встроенных типов. Таким образом, программист может писать что угодно, но интерфейс класса обязан соблюдать. Таким образом, мы вынуждаем программистов быть адекватными, потому как если просто надеяться на это... : ) я давно перестал верить в адекватность многих людей.

Вообще говоря, невозможно сделать абсолютно защищённый язык. В данном случае я вижу как минимум две проблемы.
1. Как вы планируете наложить соответствующие ограничения? Я не вижу адекватного механизма.
2. Интерфейс в данном случае почти не важен, важна как раз реализация, а её никак ни ограничить, ни проверить.

Zealint писал(а):
Yoda писал(а):
Думается мне, что символьный тип всё же является лишним.

Он лишний. У меня его даже и нет в концепции.
...
Ещё символьные константы нельзя переводить в числовые и логические типы.

Поясните, пожалуйста, мне кажется между двумя этими фразами есть противоречие. Вы пишете, что символьный тип лишний, но его нельзя переводить в числовой. Это как?

Zealint писал(а):
Yoda писал(а):
Операция конкатенации на этапе компиляции не вызывает проблем. Какие ещё операции касательно строк необходимо отразить в синтаксисе языка, мне пока не приходит в голову.

Обращение к символу str[ i ]. Правда, не факт, что данная операция будет иметь сложность O(1)... или тогда потребуется дополнительная память для хранения смещений каждого символа, если у них размер не одинаковый.

Обращение к символу – не часть синтаксиса, а библиотечная (или на крайний случай встроенная) функция. Чтобы обращение к символу работало за постоянное время, необходимо работать с 32-битными символами, другого варианта я не вижу.

Zealint писал(а):
Yoda писал(а):
Необходима концепция безопасной функции, её главной особенностью является независимость результата от окружения.

В смысле, эта функция которая не получает на вход никакую небезопасную функцию или переменную и не обращается к глобальным по отношению к ней данным?

Безопасная функция - это функция, которая удовлетворяет следующим критериям:
1. Она не использует глобальных переменных.
2. Она не имеет статических данных.
3. Она вызывает только безопасные функции.
По сути, концепция безопасных функций лишает адептов функционального программирования почвы под ногами :).

Zealint писал(а):
Комментарии должны быть нескольких видов.

На мой взгляд, только двух видов.

Zealint писал(а):
Должны быть многострочные комментарии, когда комментарием считается всё, что между парой специальных символов (аналог /* */ в C). Однако здесь есть важный момент: при вложенном комментировании завершающей скобкой (*/) должна быть НЕ ПРОСТО ПЕРВАЯ комбинация, а та, которая подходит по уровню вложенности.

Это называется просто "вложенные комментарии". Кстати, стандартом C/C++ вложенные комментарии запрещены (это меня тоже бесит). Насколько я понимаю, это ограничение обусловлено тем, что закрывающая часть может встретиться внутри строки, типа "blah */ blah". На самом деле, аргумент нелепый. Я думаю, что подобная ситуация решается очень просто - добавлением экранирующего символа в закрывающую пару, например так: "blah *\/ blah". Ранние стандарты языка С никак не оговаривали вложенность и большинство компиляторов с древних времён решали этот вопрос как им было удобней, в т.ч. при помощи опций, указывающих, какой вариант использовать. Конечно, этот бардак должен быть прекращён, и конечно в пользу вложенных комментариев.

Zealint писал(а):
Другой вариант избежать подобной нелепости – сделать по аналогии с Pascal, когда есть два вида многострочных комментариев и можно вкладывать друг в друга эти разные виды, не порождая подобных трудностей при грамотном анализе правильность скобочных последовательностей.

Это также ошибочное решение. Оно позволяет без проблем использовать не более одного уровня вложенности и плодит сущности без необходимости.

Zealint писал(а):
Код:
/* Коментарий*/ */ */ */
Код
/* Ещё Коментарий*/ */ */ */

Здесь компилятору очевидно, что последняя скобка в 1-й и 3-й строке закрывающая.

Нет, как раз компилятору это совершенно не очевидно. Оба варианта должны трактоваться как ошибки.

Zealint писал(а):
Иногда программист специально оставляет комментарий типа fixme или !!! или ??? (у каждого свой такой символ), так вот, было бы неплохо, чтобы компилятор выдавал предупреждение, если увидит такой комментарий:
Код:
if ( a > b ) {
  return c;      // fixme: разобраться! Возвращается что-то не то.
}

Нет, не согласен. В С/С++ для замечаний предусмотрены директивы препроцессора. Комментарии для того и делаются, чтобы не вызывать никакой реакции со стороны компилятора.

Zealint писал(а):
Ещё один вид комментариев, который в редких случая может пригодиться: комментарии, которые распространяются на множество строк от одной строки до другой. Например:
Код:
begin-global-comment
Тут можно писать что угодно
end-global-comment

Между begin-... и end-... можно писать что угодно, это будет восприниматься как комментарий. Можно задать вопрос: а чем это отличается от /* */ ? Да по сути ничем, кроме приоритета и гарантии того, что между этой парой лексем может быть абсолютно что угодно, даже комментарии более низкого уровня. Здесь даже не будут раскрываться команды макроподстановки (см. ниже) - аналог verbatim в LaTeX.

Абсолютно не согласен. Это по сути аналог паскалевского подхода. Макроподстановки в комментариях и так игнорируются, а для того, чтобы внутри не воспринимались другие комментарии, надо просто соблюдать правильную вложенность.

Zealint писал(а):
Есть такая вещь, как генерация документации из кода. При этом комментарии становятся частью документации.

Тут, я думаю, стоит разделить понятия. С точки зрения компилятора комментарии документации ничем не отличаются от других комментариев. Более того, для всякого рода визуальных средств и генераторов документации внутри комментариев можно создать любую непротиворечивую структуру и соглашения. Так, вижуал студия создаёт кучи своих блоков ориентируясь на комментарии вида:
Код:
  //{{AFX_MSG(CApp)
  //}}AFX_MSG

Но с точки зрения стандарта языка подобных блоков не существует - это просто комментарии.

_________________
Yet Other Developer of Architecture.
The mistery of Yoda’s speech uncovered is:
Just an old Forth programmer Yoda was.

<<< OS Boot Tools. >>>


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

Зарегистрирован: 17 фев 2013, 16:13
Сообщения: 163
Yoda писал(а):
Потеря переносимости и универсальности в том, что вы не можете взять произвольный plain-text редактор и писать/править исходники.

Почему же не могу? Могу. Просто символ tab будет ошибкой компиляции. На клавиатуре есть символ @, однако факт возможности нажать на него в любом plain-text редакторе вне комментариев не порождает проблему переносимости и универсальности. Нажав на него, программист получит неправильную программу. Так же и с tab.

Yoda писал(а):
Если я не ошибаюсь, в модулярной арифметике любое число, чтобы быть валидным, должно быть в диапазоне 0...P-1, то есть положительным. Откуда у вас взялись отрицательные числа?

Вы не ошибаетесь, однако не принимаете во внимание минимум два момента:
1 Исходные числа, передаваемые в программу, сначала нужно привести к диапазону 0..P-1, а для этого нужно брать их по модулю, и среди них будут отрицательные.
2 Вычитание двух чисел по модулю происходит в два этапа: вычитание и взятие по модулю. Между этими двумя операциями числа могут покидать данный диапазон влево от нуля. Именно поэтому приходится делать, например, так:
Цитата:
с = a - b;
if ( c < 0 )
c += P;


Yoda писал(а):
Я не понял, – вы на этом основании возражаете против этого символа? Кстати, в английском языке не говорят "коммерческое эт" – слишком длинно для них. Обычно говорят просто "эт". Википедия утверждает, что его часто называют "атперсанд" или "штрудель". В общем, называйте, как хотите.

Не, это я так просто : ) Штрудель? Я только штрудель с яблоками знаю : ) Видимо, оттуда и название пошло (штрудель же завёрнут).

Yoda писал(а):
Вообще говоря, невозможно сделать абсолютно защищённый язык. В данном случае я вижу как минимум две проблемы.
1. Как вы планируете наложить соответствующие ограничения? Я не вижу адекватного механизма.

Почти так же как это делается в ООП. Есть класс, от которого можно унаследовать интерфейс (чисто виртуальные функции). Программист может переопределить эти функции как ему вздумается. Другие мы ему запрещаем делать в таких классах. Таким образом, чисто формально программы будут продолжать компилироваться правильно, если мы заменим, например, тип int256 на встроенный. Поэтому программисту невыгодным станет определять свой тип int256 неправильно. То есть, определить умножение как сложение и наоборот. Следуя навязанному ему интерфейсу, он пропишет необходимые функции в соответствии с их смыслом. Разумеется, какие-то функции можно отметить как необязательные к определению, но каких-то других функций определять нельзя вообще. Чем мы ограничим программиста? Тем же набором, что определён для встроенных типов: плюс, минус, помножить, поделить, взять остаток, унарные операции и т. д.

Yoda писал(а):
2. Интерфейс в данном случае почти не важен, важна как раз реализация, а её никак ни ограничить, ни проверить.

Реализация может быть любой. Если программист накосячил в реализации или решил использовать операции не по назначению, то он САМ создал себе проблемы. Программа продолжит компилироваться при замещении его типа новым встроенным, но будет работать неправильно. Человек сам виноват, если копает себе яму. А вот если он решил определить int256 и навесить ему какой-то другой оператор (если снять наш запрет), то при замещении типа на встроенный int256 программа перестанет компилироваться.

Кстати, это параллельно решает ещё одну проблему: обилие разных типов, делающих одно и то же. Сейчас можно наплодить разные реализации int128 с разными наборами функций и они будут конфликтовать друг с другом, а когда есть стандарт на интерфейс таких типов, то приживаться будут лишь те, которые адекватно этот интерфейс реализуют.

Yoda писал(а):
Цитата:
Он лишний. У меня его даже и нет в концепции.
...
Ещё символьные константы нельзя переводить в числовые и логические типы.

Поясните, пожалуйста, мне кажется между двумя этими фразами есть противоречие. Вы пишете, что символьный тип лишний, но его нельзя переводить в числовой. Это как?

Имеется в виду, что нет типа данных вроде char. Но символьные константы можно использовать при работе со строками. Например, str[i]='A' - так можно. В зависимости от типа str, компилятор преобразует 'A' в число подходящего типа, поэтому в объектном файле вместо 'A' будет, например, 65. Однако написать int8 x ='A' нельзя, так как компилятор здесь совершенно не знает, что за 'A' имеется в виду, то ли это cp1251, то ли UTF-32.

Yoda писал(а):
Обращение к символу – не часть синтаксиса, а библиотечная (или на крайний случай встроенная) функция. Чтобы обращение к символу работало за постоянное время, необходимо работать с 32-битными символами, другого варианта я не вижу.

Как же не часть синтаксиса? str[i]='A', это как раз синтаксис. Квадратные скобки здесь являются синтаксической конструкцией. Как обращаться за постоянное время я предложил: хранить смещение каждого символа строки по отношению к её началу. Дорого, но тут работает принцип, который любит часто повторять pavia: ускорение алгоритмов может потребовать дополнительных расходов памяти. Либо мы делаем два класса контейнеров для строк: с произвольным доступом и без него, в зависимости от тех алгоритмов, которые нам нужны. Например, поиск подстроки... вот блин... а есть разные алгоритмы поиска подстроки и для некоторых не нужен произвольный доступ, а для некоторых размеры символов лучше иметь одинаковыми. Тут засада : )

Yoda писал(а):
1. Она не использует глобальных переменных.

А Вам не кажется, что глобальные переменные нужно вообще запретить как недоразумение?
Yoda писал(а):
2. Она не имеет статических данных.

Здесь чего-то не хватает. Функция может получить в качестве параметра статическую переменную, и тогда станет небезопасной. Ещё она может передать сообщение другому процессу, а тот будет использовать глобальные данные и статические функции, творя беспредел. Если только передача сообщения другому процессу считается безопасной функцией.
Yoda писал(а):
3. Она вызывает только безопасные функции.

Я не помню, мы всё-таки разрешили inline-assembler? Если да, то функция явно небезопасна. Но даже если нет, всё равно следует небезопасными считать функции, написанные целиком на asm отдельным модулем.

Ещё момент: если безопасная функция получила в качестве параметра ссылку не небезопасную функцию? Или безопасные функции должны отличаться каким-то идентификатором при своём определении?

Yoda писал(а):
Zealint писал(а):
Код:
/* Коментарий*/ */ */ */
Код
/* Ещё Коментарий*/ */ */ */

Здесь компилятору очевидно, что последняя скобка в 1-й и 3-й строке закрывающая.

Нет, как раз компилятору это совершенно не очевидно. Оба варианта должны трактоваться как ошибки.

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


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

Зарегистрирован: 16 май 2007, 23:46
Сообщения: 1092
Yoda писал(а):
Zealint писал(а):
Yoda писал(а):
Код:
int136 operator + (int136 a, int136 b) {
  int128 t = a.l + b.l;
  Result.l = int64(t);
  t = a.m + b.m + t>>64;
  Result.m = int64(t);
  Result.h = a.h + b.h + t>>64;
}

Ну вот, если теперь временно закрыть глаза на смешивание знакового и беззнакового типов (int64(t) может "вдруг" стать отрицательным), то как всё-таки компилятор догадается, что мы хотим использовать ADC?

Смешивание типов в данном случае не играет никакой роли, - операции сложения и вычитания двоичных чисел тождественны для знакового и беззнакового типов.

Советую обратить внимание на LLVM и не достаки IR. У вас именно такие же.
Если запись произвольная то компилятору придётся перебирать все варианты. Что снижает время компиляции в разы. И ещё там были какие-то замечания сейчас не помню.


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

Зарегистрирован: 16 май 2007, 23:46
Сообщения: 1092
Zealint писал(а):
На самом деле очевидно. Стандартный алгоритм анализа скобочной последовательности со стеком совершенно спокойно обнаруживает при получении второй закрывающей скобки, что стек пуст, а мы хотим найти на его вершине открывающую часть. Пары нет, значит предпосмотр вперёд должен отыскать последнюю закрывающую часть И либо отрывающую часть, либо конец файла. Всё, что между ними - код.

Недосток только один требуется многопроходный компилятор. Что снижает время компиляции. В Си в этом плане это традиция. От которой нельзя отказаться иначе ошибки будут не предсказуемыми.


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

Зарегистрирован: 17 фев 2013, 16:13
Сообщения: 163
pavia писал(а):
Недосток только один требуется многопроходный компилятор. Что снижает время компиляции. В Си в этом плане это традиция. От которой нельзя отказаться иначе ошибки будут не предсказуемыми.

В данном случае дополнительная пара предварительных проходов по файлу для правильного удаления комментариев потребует малой доли времени компиляции по сравнению со всем остальным.


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

Зарегистрирован: 16 май 2007, 23:46
Сообщения: 1092
Zealint писал(а):
Yoda писал(а):
Обращение к символу – не часть синтаксиса, а библиотечная (или на крайний случай встроенная) функция. Чтобы обращение к символу работало за постоянное время, необходимо работать с 32-битными символами, другого варианта я не вижу.

Как же не часть синтаксиса? str[i]='A', это как раз синтаксис. Квадратные скобки здесь являются синтаксической конструкцией.

В первой версии компилятора лучше сделать встроенный типа. А вот потом уже можно и определить оператор [] для класса.

Zealint писал(а):
Как обращаться за постоянное время я предложил: хранить смещение каждого символа строки по отношению к её началу. Дорого, но тут работает принцип, который любит часто повторять pavia: ускорение алгоритмов может потребовать дополнительных расходов памяти. Либо мы делаем два класса контейнеров для строк: с произвольным доступом и без него, в зависимости от тех алгоритмов, которые нам нужны. Например, поиск подстроки... вот блин... а есть разные алгоритмы поиска подстроки и для некоторых не нужен произвольный доступ, а для некоторых размеры символов лучше иметь одинаковыми. Тут засада : )

В данном случае не работает. Поиск будет быстрее где меньше байт. Т.е.лучше UTF или ещё быстрее ANSI.
Но для быстрой разработки проще индексный доступ. А то с автоматами не все ладят. Даже профессионалы.


Zealint писал(а):
Yoda писал(а):
1. Она не использует глобальных переменных.

А Вам не кажется, что глобальные переменные нужно вообще запретить как недоразумение?

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


Zealint писал(а):
Yoda писал(а):
2. Она не имеет статических данных.

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

Мне статические данные никогда не мешали. Это разные парадигмы программирования и их смешивать не стоит. Есть библиотеки которые пишутся функциями и есть правила для их написания. А есть бизнес логика котораяописывается машинами состояний и эвристиками что-бы те реагировали на не предсказуемое поведение внешнего мира. Такое разделение специально делают что-бы легче было отлаживать и писать. Так как функциональный стиль можно однозначно проверить. А вот императивный не всегда. Зато тот который труднее оттестировать можно свести к минемому.


Zealint писал(а):
Yoda писал(а):
3. Она вызывает только безопасные функции.

Я не помню, мы всё-таки разрешили inline-assembler? Если да, то функция явно небезопасна. Но даже если нет, всё равно следует небезопасными считать функции, написанные целиком на asm отдельным модулем.

inline-assembler - запрещают по тому что они сбивают оптимизатор 2 и 3 уровня.

Zealint писал(а):
Ещё момент: если безопасная функция получила в качестве параметра ссылку не небезопасную функцию? Или безопасные функции должны отличаться каким-то идентификатором при своём определении?

Думаю излишне. Такое лучше всего решается приказным характером. Правильным планированием архитектуры, руководство документов о едином стиле и т.д.
У меня уже как-то слоился стиль. U,T,I - в принципе можно добавить и L(Lib) и вынести безопасные функции в библиотеку.


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

Зарегистрирован: 16 май 2007, 23:46
Сообщения: 1092
Что-то меня на философию потянуло.
Цитата:
В данном случае дополнительная пара предварительных проходов по файлу для правильного удаления комментариев потребует малой доли времени компиляции по сравнению со всем остальным.
По капельки, да по капельке - а в результате и нечего и не осталось. Парсер становиться не параллельным.

Все компиляторы рано или поздно соревнуются в скорости компиляции. Я долго не хотел уходить с BP и в последствии с Delphi. Так как "Hellow World" в BC++3 и Builder компилировались в 100 раз дольше 10-30 секунд против 0.01-0.1 разница в 100 раз!! Первые версии Fortran не любили из-за того что он был много проходным и разница с другими языками составляла до 700 раз!
А кто-то говорил от отзывчивости!

Это сейчас как появились многоядерные процессоры и сделали инкрементную компиляцию - стало можно жить.
Много проходная компиляция ещё неудобна тем что как правило её определяет язык и следовательно разработка, написание программ идёт также инкремента. Что замедляет работу программиста - и раздражает.
Разница в скорости у Паскаль против Си результирующего кода составляет 4-16 раз.
Так что не всё так хорошо как хотелось бы.
В качестве эталонного компилятора многопроходный является интересным. Он как-то по проще разрабатывается.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 285 ]  На страницу Пред.  1 ... 11, 12, 13, 14, 15, 16, 17 ... 29  След.

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


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

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


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

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