Содержание


Язык программирования Nimrod

Часть 4. Процедуры и операторы

Comments

Серия контента:

Этот контент является частью # из серии # статей: Язык программирования Nimrod

Следите за выходом новых статей этой серии.

Этот контент является частью серии:Язык программирования Nimrod

Следите за выходом новых статей этой серии.

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

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

1. Блоки кода

В предыдущих статьях уже использовалось понятие "область видимости". Суть этого понятия состоит в том, что каждая переменная имеет определённую область своего действия, зависящую от позиции её объявления. Вне этой области переменная становится "невидимой", то есть фактически не существующей. Более наглядно область видимости переменной показана в примере, приведённом в листинге 1.

Листинг 1. Демонстрация области видимости переменной
for i in 2..10:
  var f = 1
  f = f * i
echo("Факториал числа 10 = ", $f ) # Ошибка: f вне области видимости не определена

Эта ошибка выявляется уже на стадии компиляции. Если попытаться скомпилировать код из листинга 1, то будет выведено следующее сообщение:

err_scope.nim(4, 46) Error: undeclared identifier: 'f'

Таким образом, можно сделать вывод о том, что конструкция цикла for (а также цикла while) в неявной форме создаёт блок кода с собственной внутренней областью видимости.

Блоки кода можно создавать и в явной форме, используя для этого ключевое слово block. Пример приведён в листинге 2.

Листинг 2. Явное создание блока кода с помощью ключевого слова block
block calc_factorial10:
  var f = 1
  for i in 2..10:
    f = f * i
  echo("Факториал числа 10 = ", $f ) # Работает: переменная f видима внутри блока
echo("Значение переменной f: ", $f ) # Ошибка: вне блока переменная f невидима

Метка (label) блока (в листинге 2 - calc_factorial10) необязательна, то есть после ключевого слова block может сразу следовать символ двоеточия.

2. Особенности выполнения команды break по отношению к блокам кода

В предыдущей статье было продемонстрировано применение команды break для выхода из циклов while и for. Но кроме этого, break позволяет выйти и из блока. Если несколько конструкций вложены друг в друга, то break в простейшей форме выполняет выход только из внутренней конструкции, как показано в листинге 3.

Листинг 3. Выход только из одной внутренней конструкции
block demo:
  echo("Начало блока")
  for i in 1..100:
    echo("Выполнение цикла")
    if i == 15: break    # Выход только из цикла, но не из блока
  echo("Всё ещё внутри блока...")

Если для команды break указать метку блока, то выход будет выполнен и из цикла, и из блока, как показано в листинге 4.

Листинг 4. Выход из нескольких (двух) вложенных конструкций
block demo:
  echo("Начало блока")
  for i in 1..100:
    echo("Выполнение цикла")
    if i == 15: break demo    # Выход не только из цикла, но и из блока
  echo("Всё ещё внутри блока...")
echo("Вне блока - общий выход")

3. Процедуры

Процедуры необходимы для того, чтобы предоставить пользователю возможность создавать собственные "команды", необходимые ему. В некоторых языках программирования аналогами процедур можно считать функции или методы. В Nimrod новая процедура определяется с помощью ключевого слова proc. Пример определения процедуры показан в листинге 5.

Листинг 5. Определение процедуры в Nimrod и её использование
proc yes( question: string ): bool =
  echo( question, " (д[а]|н[ет])")
  case readLine(stdin)
  of "д", "Д", "да", "Да", "ДА", "дА": return true
  else: return false

if yes("Удалить выделенные файлы?"):
  echo("Выполняется операция удаления. Восстановление невозможно.")
else:
  echo("Операция удаления отменена, так как пользователь не уверен в её необходимости.")

В листинге 5 приведено определение процедуры с именем yes, которая выводит на экран строку (вопрос), содержащуюся в переменной question, и возвращает значение true, если пользователь ответил "д" или "да" в любом варианте регистра букв, или возвращает false при любом другом варианте ответа. Команда return выполняет немедленный выход из процедуры (и, разумеется, из всех циклов и блоков, содержащихся внутри этой процедуры).

Синтаксический элемент ( question: string ): bool означает, что процедура ожидает передачи параметра question типа string (строка), а возвращает значение типа bool (логическое). Тип bool представляет собой встроенный простейший тип языка, к которому относятся только два допустимых корректных значения: true и false. В частях определения условий конструкций if и while должны содержаться выражения, дающие при вычислении значения типа bool.

3.1. Возвращаемое значение

В процедуре, возвращающей какое-либо значение, всегда присутствует неявно определённая переменная result, которая содержит это возвращаемое значение. Команда return без какого-либо выражения является просто сокращённой формой записи return result. С учётом этой особенности процедуру yes из листинга 5 можно немного изменить, тем более, что наличие в процедуре нескольких команд выхода считается дурным тоном в программировании. Новая версия процедуры приведена в листинге 6.

Листинг 6. Модифицированная версия процедуры yes
proc yes( question: string ): bool =
  echo( question, " (д[а]|н[ет])")
  case readLine(stdin)
  of "д", "Д", "да", "Да", "ДА", "дА": result = true
  else: result = false
  return

3.2. Параметры-константы и параметры-переменные

Обычные параметры в теле процедуры считаются константами, то есть их значения нельзя изменять. Это позволяет компилятору реализовать передачу параметров в процедуру наиболее эффективным способом. Если при вызове процедуры необходимо предоставить возможность изменения значения одного или нескольких параметров, то для этого предназначен специальный модификатор var, применение которого показано в листинге 7.

Листинг 7. Передача в процедуру изменяемых параметров
proc circleLenSq( r: float, length, square: var float ) =
  length = 2.0 * 3.14 * r
  square = 3.14 * r * r

var
  circLen, circSq: float
circleLenSq( 10.0, circLen, circSq )
echo( "Длина окружности = ", $circLen )
echo( "Площадь круга    = ", $circSq )

В приведённом выше примере параметры length и square являются переменными, то есть их значения могут быть изменены внутри вызываемой процедуры, и эти изменения становятся видимыми в вызывающем коде. Таким образом можно организовать возврат из процедуры нескольких значений.

3.3. Игнорирование возвращаемого значения

Иногда возникает необходимость в вызове процедуры, возвращающей значение, только для получения побочных эффектов (действий, выполняемых внутри процедуры), а результат не требуется. В таких случаях используется ключевое слово discard. Но в Nimrod нельзя просто отбросить возвращаемое значение любой процедуры. Например, для определённой в листинге 6 процедуры yes следующее выражение будет недопустимым:

discard yes("Ответ на этот вопрос не имеет значения, не так ли?")

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

Листинг 8. Объявление возможности игнорирования возвращаемого значения процедуры
proc swap( a, b: var int ): int {.discardable.} =
  var x: int
  x = a
  a = b
  b = x
  return a

var
  h = 100
  f = 500
swap( h, f ) # Здесь игнорирование возвращаемого значения допустимо
echo( "h = ", $h )
echo( "f = ", $f )

3.4. Прочие возможности процедур

При определении в заголовке процедуры можно указывать значения параметров по умолчанию, а кроме того, имеется возможность перегрузки процедур в стиле языка C++. В этом случае компилятор сам выбирает наиболее подходящую для типа передаваемого аргумента процедуру.

4. Операторы

Набор операторов в Nimrod в основном аналогичен наборам операторов в других языках программирования. Их особенность состоит в том, что большинство операторов являются перегружаемыми. Кроме того, пользователь может определять собственные операторы.

Оператор может представлять собой произвольную комбинацию следующих символов:

= + - * / < > & $ ~ @ % | ! ? ^ . : \

Операторами также являются следующие ключевые слова:

and or not xor shl shr div mod in notin is isnot of.

В любом операторе наиболее значимым символом (relevant symbol) является первый (исключениями являются операторы, начинающиеся с обратного слэша \, за которым следуют другие символы; в этом случае наиболее значимым является второй символ), по которому определяется приоритет выполнения операторов.

Наиболее высоким приоритетом обладают операторы, начинающиеся с символов $ и ^ (наиболее значимые символы). Далее, в порядке убывания приоритета:

  • * / % div mod shl shr и операторы с наиболее значимыми символами * % / \
  • = - и операторы с наиболее значимыми символами + ~ |
  • & и операторы с наиболее значимыми символами &
  • .. и операторы с наиболее значимыми символами .
  • == <= < >= > != not in notin is isnot of и операторы с наиболее значимыми символами = < > !
  • and
  • or xor
  • операторы с наиболее значимыми символами @ : ?

Самый низкий приоритет имеют операторы присваивания +=, *=, -= и т.п.

Вообще говоря, подсистема синтаксического анализа языка Nimrod позволяет использовать операторы в инфиксной форме для двух аргументов (a + b) и в префиксной форме только для одного аргумента (+ a). Постфиксная форма операторов не является допустимой.

Заключение

В данной статье рассматривались процедуры языка Nimrod, их особенности и функциональные возможности, а также был дан общий обзор операторов, используемых в данном языке.


Ресурсы для скачивания


Похожие темы


Комментарии

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

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Open source, Linux
ArticleID=856872
ArticleTitle=Язык программирования Nimrod: Часть 4. Процедуры и операторы
publish-date=01312013