]]> ]]>

Factor

Реализация языка программирования Factor

Авторская реализация Factor. Написана на C и Factor. Включает в себя:

  • два компилятора (простой и оптимизирующий),
  • кросс-платформенный пакет для разработки графического интерфейса пользователя, использующий OpenGL,
  • привязки к нескольким базам данных, в т.ч. PostgreSQL и SQLite,
  • HTTP-сервер и клиент,
  • интерфейс для взаимодействия с программами на C, Objective-C и Fortran.

Распространяется под BSD-лицензией.

Примеры:

Hello, World!:

Пример для версий Factor 0.94

Первая строка импортирует библиотеку io, содержащую слово print. Вторая строка добавляет на стек строку-сообщение и затем вызывает слово print, которое выводит верхний элемент стека на печать.

USE: io 

"Hello, World!" print

Факториал:

Пример для версий Factor 0.94

В первой строке перечисляются необходимые библиотеки: formatting (printf), kernel (dup), math (арифметические действия) и sequences (iota). Во второй строке объявляется имя текущего словаря — это необходимо для определения новых слов.

Затем определяется слово factorial, которое заменяет на стеке целое число n на его факториал. Для этого оно строит массив чисел от 0 до n — 1 с помощью слова iota и сворачивает его с единицей цитатой [ 1 + * ] (прибавление 1 и перемножение двух чисел) и комбинатором reduce.

Слово main генерирует массив чисел от 0 до 16 и комбинатором each применяет к ним цитату, которая вычисляет факториалы чисел и выводит их на печать.

В стандартном словаре math.combinatorics присутствует слово factorial, определенное указанным в примере образом.

USING: formatting kernel math sequences ;
IN: factorial-example

: factorial ( n -- n! )
    iota 1 [ 1 + * ] reduce ;

17 iota
[ dup factorial "%d! = %d\n" printf ] each

Числа Фибоначчи:

Пример для версий Factor 0.94

В этом примере используется рекурсивное вычисление чисел Фибоначчи. Слово fib вычисляет n-ое число Фибоначчи: если аргумент не больше 1, он остается на стеке в качестве возвращаемого значения, иначе заменяется на сумму предыдущих чисел Фибоначчи. Слово bi является сокращенной формой комбинатора cleave и позволяет применить две цитаты (в данном случае вызовы слова fib для меньших аргументов) к одному элементу стека (n).

USING: formatting kernel math sequences ;
IN: fibonacci-example

: fib ( n -- fib(n) )
    dup
    1 >
    [ [ 1 - fib ] [ 2 - fib ] bi + ]
    when ;

16 iota [ 1 + fib "%d, " printf ] each 
"...\n" printf

Факториал:

Пример для версий Factor 0.94

В этом примере используется чисто рекурсивное вычисление факториала. Слово factorial заменяет на стеке n на n! с побочным эффектом: выводом всех значений факториалов от 0 до n. После выполнения комбинатора if на стеке остаются значения n и n!, которые словами swap и over заменяются на n!, n, n!; два последних значения используются при выводе, первое остается на стеке в качестве возвращенного.

В основной части программы main приходится добавить drop значения 16!, чтобы сигнатура программы оставалась ( -- ).

USING: formatting kernel math ;
IN: factorial-example

: factorial ( n -- n! )
    dup
    0 =
    [ 1 ]
    [ dup dup 1 - factorial * ]
    if
    swap over "%d! = %d\n" printf ;

16 factorial
drop

Квадратное уравнение:

Пример для версий Factor 0.94

Слово quadratic-equation принимает на вход коэффициенты квадратного уравнения и выводит результаты его решения на печать, ничего не возвращая. Обратим внимание на то, что это слово определено не через токен :, как обычные слова, а через :: — это означает, что в нем будут использоваться именованные переменные с лексической областью видимости, в данном случае именованные параметры a, b и c и локальные переменные d, x0 и sd (определенные оператором :>). Такие переменные можно загружать на стек по их имени. Слова для работы с именованными переменными доступны в словаре locals.

В Factor есть встроенный тип данных для комплексных чисел; если дискриминант отрицателен, корень из него sd автоматически примет тип complex. В этом случае для вывода корней на печать используются слова real-part и imaginary-part, извлекающие действительную и мнимую части комплексного числа, соответственно.

readln читает строку из потока ввода, а string>number (словарь math.parser) преобразует строку в действительное число.

USING: formatting io kernel locals math math.functions math.parser ;
IN: quadratic-example

:: quadratic-equation ( a b c -- )
    a 0 =
    [ "Not a quadratic equation." printf ]
    [ b sq a c * 4 * - :> d 
      b neg a 2 * / :> x0
      d sqrt a 2 * / :> sd
      d 0 =
      [ x0 "x = %f\n" printf ]
      [ d 0 >
        [ x0 sd + x0 sd - "x1 = %f\nx2 = %f\n" printf ]
        [ x0 sd + [ real-part ] [ imaginary-part ] bi "x1 = (%f, %f)\n" printf
          x0 sd - [ real-part ] [ imaginary-part ] bi "x2 = (%f, %f)\n" printf ]
        if
      ]
      if
    ]
    if ;

readln string>number
readln string>number
readln string>number
quadratic-equation

CamelCase:

Пример для версий Factor 0.94

В этом примере используются регулярные выражения. Слово re-split (словарь regexp) разбивает строку на массив подстрок, разделенных заданным регулярным выражением. Затем комбинатор map применяет к каждому элементу массива слово >title (unicode.case), которое переводит первый символ строки в верхний регистр, а остальные — в нижний. Наконец, join (sequences) конкатенирует строки массива в одну с разделителем “”.

USING: kernel io regexp sequences unicode.case ;

readln R/ [^a-zA-Z]+/ re-split
[ >title ] map
"" join print

Факториал:

Пример для версий Factor 0.94

В этом примере используется встроенное слово factorial, определенное в библиотеке math.combinatorics.

USING: formatting kernel math.combinatorics sequences ;

17 iota [ dup factorial "%d! = %d\n" printf ] each

Комментарии

]]>

blog comments powered by Disqus

]]>

Работа программистам