Вверх ↑
Пакеты 
Кодогенерация 
FTCG - Особенности работы

Особенности работы
Введение
   В данной статье будут рассмотренны некоторые особенности работы скриптового языка кодогенератора, которые не являются характерными для языков подобного рода в целом. Большинство этих особенностей обусловлено средой работы скрипта и теми задачами, выполнение которых на него возложено.
Массивы
   В FTCG, как и в любом другом скриптовом языке, есть такое понятие как массив - линейный набор данных, каждый элемент которых характеризуется своим порядковым номером или индексом. Оператора создания массива в FTCG как такового нет. Чтобы сделать переменную массивного типа нужно использовать оператор конкатенации & или &&. Например:
  fvar(a)
a = "item 1" & "item 2"
этот код создаст массив из двух элементов "item 1" и "item 2" и скопирует его в переменную a. В настоящий момент удалить из массива элементы нельзя, однако добавить их можно. Для этого применяются все теже операторы конкатенации:
  a &= "item 3"
   Обращение к элементу массива и запись в него производится с использованием оператора [] - т.е. так же, ка кв большинстве скриптовых языков:
  a[0] = "item 111" // запись
trace(a[0]) // чтение
   Поскольку в FTCG генерация кода целевого языка всегда построена на базе добавления элементов в массив, то для эмуляции работы с ним как с обычной переменной был введен механизм "прозрачного" чтения. Это значит, что если чтение из массива производится без указания непосредственного индекса элемента, то читаются все элементы сразу и возвращаются ввиде одной большой строки, например:
  trace(a)
Выполнение этого кода приведет к печати в окне отладки следующей строчки:
Debug писал(а):
item 111item 2item 3


   При присваивание переменной массивного типа другой переменной происходит полное копирование массива со всеми его элементами. Это значит, что в таком коде:
  fvar(s)
s = a
s[0] = "none"
trace(a[0])
в окне отладки вы увидите строку: "item 111"

   Многомерные массивы формируются так же как и одномерные - через операторы конкатенации & и &&. Например, код ниже создает матрицу размером 2х2:
  fvar(a)
a = " " & " "
a[0] = "1.1 " & "1.2 "
a[1] = "2.1 " & "2.2 "
Если вы попробуете вывести эту матрицу на экран путем вызова trace(a), то увидите следующий результат:
Debug писал(а):
1.1 1.2 2.1 2.2

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

   И наконец последней особенностью работы с массивом является то, что при начальном формирование вы не должны в качестве первого элемента указывать пустую строку. Например, после выполнения кода:
  a = "" & "" & ""
будет создан массив из двух элементов, а не из трех, как ожидалось. Такое поведение сложилось исторически и связано оно с некоторой спецификой использования массивного типа. Рассмотрим следующий достаточно часто встречающийся кусок кода:
  fvar(p)
p &= "n" & "m"
...
p &= "k"
Вспомним тот факт, что при объявление переменной она автоматически инициализируется пустой строкой. Поэтому использование оператора &= в случае канонического поведения всегда создавало бы пустой первый элемент. Избежать этого можно только путем дополнительных проверок.
Вызовы методов
   Основная масса вызовов методов скрипта приходится на вызовы соответствующих функций Work и Var точек, которые могут принимать данные из потока. С учетом этой особенности был добавлен упрощенный метод доступа к данным из потока из тела текущего метода. Этот доступ осуществляется через переменную _data_. Данная переменная, как следует из спецификации на язык является встроенной и представляет из себя обычный указатель на первый аргумент функции. Если вспомнить тот факт, что вызов метода для точки элемента производится как правило с передачей двух параметров - данных из потока и индекса точки, то окажется, что в таком коде:
func doWork(data, index)
//...
end
переменная _data_ будет всегда тождественна первому аргументу, т.е. _data_ и будет являться контейнером для данных из потока. Однако следует не забывать эту особенность и помнить, что объявление метода без параметров:
func doWork()
//...
end
приведет к отсутствию доступа к днным из потока и чтение из _data_ будет возвращать пустую строку не зависимо ни от чего.

   Язык не ограничивает специальным образом доступ с переменной _data_ из функций, не являющихся методами соответствующих точек. Поэтому в случае необходимости вы можете использовать её в вашем коде, например:
func myFunc(Text)
trace("arg 1 = " + _data_)
end

func doWork()
myFunc("Hello world!")
event(onEvent)
end

выполнение этого скрипта отобразит в окне отладки строку: arg 1 = Hello world!
BB-code статьи для вставки
Всего комментариев: 0
(комментарии к статье еще не добавлены)
Комментарий
...