]]> ]]>

Icon

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

Icon — реализация языка Icon, написанная на C. Может компилировать исходный код на Icon либо в байткод (i-code) с присоединением интерпретатора, либо в исходный текст C, впрочем, второй вариант пользователям Icon требуется редко и поддерживается хуже.

Примеры:

Hello, World!:

Пример для версий iconc 9.4
procedure main ()
   write ("Hello, world!")
end

Факториал:

Пример для версий iconc 9.4

Сокращенный вариант итеративного способа вычисления факториала.

procedure main ()
   local i, j
   every write (i := 0 to 16, "! = ", { j := 1; every j *:= 1 to i; j })
end

Факториал:

Пример для версий iconc 9.4

В примере используется рекурсивное определение факториала. 0 to 16 — генератор, возвращающий все числа в интервале от 0 до 16. every позволяет получить от генератора все числа и для каждого из них выполнить действие write.

procedure factorial (n)
   if n = 0 then
      return 1
   else if n > 0 then
      return n * factorial (n - 1)
end

procedure main ()
   local i
   every i := 0 to 16 do
      write (i, "! = ", factorial (i))
end

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

Пример для версий iconc 9.4

Используется рекурсивное вычисление чисел Фибоначчи с мемоизацией промежуточных результатов

global fib_memo

procedure fib (n)
   if n >= 0 then
      return ((/fib_memo [n] := fib (n - 2) + fib (n - 1)) | fib_memo [n])
end

procedure main ()
   local i
   fib_memo := table ()
   fib_memo [0] := 0; fib_memo [1] := 1
   every i := 1 to 16 do {
      writes (fib (i) || ", ")
   }
   write("...")
end

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

Пример для версий iconc 9.4
procedure main () 
    A := read();
    if A = 0 then {
        write("Not a quadratic equation.");
        return;
    }
    B := read();
    C := read();
    D := B*B - 4*A*C;
    if D = 0 then {
        write("x = ", -B/2/A);
        return;
    }
    if D > 0 then {
        write("x1 = ", (-B+sqrt(D))/2/A);
        write("x2 = ", (-B-sqrt(D))/2/A);
    } else {
        write("x1 = (", -B/2/A, ",", sqrt(-D)/2/A, ")");
        write("x2 = (", -B/2/A, ",", -sqrt(-D)/2/A, ")");
    }
end

CamelCase:

Пример для версий iconc 9.4

Прежде всего программа читает строку для обработки в переменную text и добавляет в конец пробел (|| — оператор конкатенации). Затем переменная text сканируется (? — оператор сканирования, позволяющий привязать все операции поиска в строке к определенной переменной) следующим образом.

Команды ReFind и ReMatch из библиотеки регулярных выражений regexp находят все последовательности символов, соответствующие регулярному выражению, но ReFind возвращает индекс начала последовательности, а ReMatch — первого символа после последовательности. За одну итерацию цикла ReFind находит начало следующей последовательности не-букв. Команда tab перемещает указатель на текущую позицию в сканируемой строке на это начало и возвращает подстроку от предыдущей позиции до новой — слово. Затем слово преобразуется к нужному формату и добавляется к результату. *word — функция, возвращающая длину строки word. map заменяет символы первого аргумента, которые есть во втором, на их соответствия из третьего (в данном случае — заменяет друг на друга символы из &lcase и &ucase, встроенных переменных, содержащих алфавит в нижнем и верхнем регистре, соответственно). Наконец, еще одно обращение к tab перемещает указатель на начало следующего слова (конец последовательности не-букв).

link regexp

procedure main () 
    text := read() || " ";
    cc := "";
    text ? {
        while j := ReFind("[^a-zA-Z]+") do {
            word := tab(j);
            cc ||:= map(word[1],&lcase,&ucase) || map(word[2:*word+1],&ucase,&lcase);
            tab(ReMatch("[^a-zA-Z]+"));
        }
    }
    write (cc);
end

Комментарии

]]>

blog comments powered by Disqus

]]>

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