Динамический “игрушечный” интерпретируемый язык программирования.
Название возникло как аббревиатура TOY programming laNGuage. Toyng произносится как “toying”.
В процессе разработки: репозиторий.
Текущая версия интерпретатора: bti-170620.
a
и A
— разные имена).and
, else
, if
, let
, mod
, not
, or
, var
, xor
.Поддерживаются однострочные комментарии, открываемые символом #
.
(
и )
.;
игнорируется._
) и содержать только буквы или цифры.123
, 0xFF00
, .5
, 1.75e+12
.'abc'
, 'in "quotes"'
, 'single '' quote'
.f x
есть вызов функции f с аргументом x._
(исключая аргумент функции)._
.var
и let
), не подменяются на значения при вычислении замыкания.arg => expr arg
.Обозначения операндов: x y
— числа, a b
— строки, f g
— функции, u v
— число или строка, z w
— любые типы, n
— имя переменной.
Операция | Смысл |
---|---|
+x |
модуль x |
+a |
длина строки a |
-x |
смена знака x |
*x |
квадрат x |
*a |
строка, полученная конкатенацией a и a |
%f |
arg => f f arg |
/x |
1/x |
^x |
квадратный корень x |
not x |
отрицание: [x = 0] (0 или 1) |
not a |
проверка строки на пустоту: [a = ’’] |
let n |
определение новой константы |
var n |
определение новой переменной |
Операции | Приоритет |
---|---|
let , var |
300 |
not |
800 |
+ , - |
1000 |
* , / , % |
1100 |
^ |
1200 |
Операция | Смысл |
---|---|
z ; w |
последовательность: применить побочные эффекты z, вернуть w |
n = z |
присваивание |
n += z |
комбинированное присваивание (аналогично для - , * , / , ^ , % , mod , xor ) |
n => z |
лямбда-выражение (создание замыкания) |
x + y |
сумма |
f + g |
arg => f arg + g arg (аналогично для прочих инфиксов кроме % и сравнений) |
f + u |
arg => f arg + u (аналогично для прочих инфиксов кроме % и сравнений) |
u + f |
arg => u + f arg (аналогично для прочих инфиксов кроме % и сравнений) |
x - y |
разность |
x * y |
произведение |
a * b |
конкатенация |
a * x |
приведение числа к строковой форме и конкатенация |
x * a |
аналогично a * x |
x / y |
деление |
x / a |
выборка префикса (подстроки) длины x из a |
a / x |
выборка суффикса (подстроки) длины x из a |
x mod y |
остаток от деления (fmod) |
x ^ y |
возведение в степень |
a ^ x |
повторение строки a x раз |
z == w |
сравнение на равенство (разнотипные значения не равны) |
z != w |
сравнение на неравенство |
u < v |
сравнение на меньше |
u <= v |
сравнение на меньше или равно |
u > v |
сравнение на больше |
u >= v |
сравнение на больше или равно |
u and v |
логическое и: возвращает v, если u “истинен”, иначе u |
u or v |
логическое или: возвращает u, если u “истинен”, иначе v |
u xor v |
булевское исключающее или: то же, что (not u) != (not v) |
f % g |
композиция-продолжение: arg => g f arg |
f z |
вычисление f(z) |
x u |
то же, что x * u |
u f |
arg => u f arg |
a x |
выборка символа с номером x из строки a |
a b |
то же, что a * b |
z if w |
if-выражение |
z else w |
else-выражение, z должно быть if-выражением |
Операции | Приоритет |
---|---|
; |
100 |
= |
200R |
=> |
300R |
if , else |
400R |
or , xor |
600 |
and |
700 |
== , != , < , > , <= , >= |
900 |
+ , - |
1000 |
* , / , mod , % |
1100 |
^ |
1200R |
<
, >
и т.д. работают (фактически на данный момент “внутри” сравниваются указатели);true-expr if cond else false-expr
вычисляется следующим образом:
cond
;cond
истинно, то вычисляется true-expr
, результат есть значение if-else-выражения;false-expr
, результат есть значение if-else-выражения.a
инфикс = b
заменяется на a = a
инфикс b
: x += 2
— добавить 2 к переменной x.a b
соответствует узлу AST “применить” (a к b). В случае, когда a не является функцией (замыканием), это то же самое, что a * b
.=>
) делает терм операндом замыкания, т. е. a b => c
есть то же самое, что a => b => c
.a
сравнение b
сравнение c
есть то же, что a
сравнение b and b
сравнение c
: например, a < b <= c != d
есть то же самое, что a < b and b <= c and c != d
.let
).toyng
— версия Toyng (число). Текущая версия 900 (0.9).
inf
— условное значение “бесконечность”.
nan
— условное значение “нечисло”.
epsilon
— машинный “эпсилон” (минимальное положительное число ε такое, что 1 + ε ≠ 1).
pi
— число пи.
euler_e
— число e (константа Эйлера).
nl
— символ перевода строки.
tab
— символ горизонтальной табуляции.
squo
— символ “кавычка” '
.
dquo
— символ “двойная кавычка” "
.
exit x
— выйти из программы, вернув код x
.
rmvar a
— удалить переменную a, возвращает 1 (если переменная была удалена) или 0 (если переменная не была удалена).
eval a
— выполнить строку a
как код Toyng.
evalc a
— выполнить строку a
как код Toyng, используя временную копию контекста.
module a
— загрузить модуль (файл с исходным кодом) с именем a
в строку.
exec a
— выполнить команду интерпретатора:
'reset'
— сбросить контекст и очистить экран;'cls'
— только очистить экран;'pause'
— очистка буфера ввода и ожидание нажатия Enter.write a
— вывести значение a
в stdout.
writeln a
— вывести значение a
и перевод строки в stdout.
error a
— вывести значение a
в stderr.
readln a
— прочитать строку (все символы до перевода строки), в случае неудачи вернуть a
.
readnum a
— прочитать число, в случае неудачи вернуть a
.
readch a
— прочитать один символ, в случае неудачи вернуть a
.
ceil x
— ближайшее к x целое со стороны +inf.
floor x
— ближайшее к x целое со стороны -inf.
round x
— ближайшее к x целое.
trunc x
— целая часть x.
frac x
— дробная часть x.
abs x
— модуль x, абсолютная величина числа (также +x
).
sign x
— “знак” x, -1 или 1 (вычисляется через signbit).
sqrt x
— квадратный корень x (также ^x
).
cbrt x
— кубический корень x.
exp x
— ex.
exp2 x
— 2x.
log x
— натуральный логарифм x.
log2 x
— двоичный логарифм x.
log10 x
— десятичный логарифм x.
sin x
, cos x
, tan x
, asin x
, acos x
, atan x
— обычные тригонометрические функции аналогично стандартным C (на самом деле, и вычисляемые через них).
len a
— длина строки a (также +a
).
to_num a
— распознать префикс строки a как число (какой результат, если число не распознано?).
reverse a
— обратить порядок символов в строке a.
Все перечисленные ниже примеры корректно выполняются в текущей версии интерпретатора.
writeln 'hello, world!'
или просто
'hello, world!'
write 'What is your name? ';
name = readln ''; # read line, failure result is ''
writeln ('Hello, ' * name)
write 'input a b c: ';
a = readnum 1; # read number, failure result is 1
b = readnum 0;
c = readnum 1;
d = *b - 4*a*c;
x1 = (-b - ^d) / 2a; # * may be omitted just after a literal constant
x2 = (-b + ^d) / 2a;
writeln ('x1 = ' * x1 * ', x2 = ' * x2);
writeln ('value at x1 is ' * ((a*x1 + b)*x1 + c))
quadratic_d = a => b => c =>
*b - 4*a*c;
quadratic_left_root = a => b => c =>
(-b - ^quadratic_d a b c) / 2a;
quadratic_right_root = a => b => c =>
(-b + ^quadratic_d a b c) / 2a;
writeln (quadratic_left_root 1 (-5) 2);
writeln (quadratic_right_root 1 (-5) 2)
sgn = x =>
-1 if x < 0 else
+1 if x > 0 else
0;
sgn (-10) # --> -1
# A substring may be extracted by prefix/suffix operations.
substr = str from count =>
count / (str / (+str - from));
substr 'alphax' 2 3 # --> 'pha'
# Direct recursion, fact is just a global variable.
fact = n => 1 if n < 2 else n * fact(n - 1);
fact 10 # --> 3628800
twice = f x => f(f x);
# Brackets are important here, because
# function application is done from left to right.
inc = x => x + 1;
twice inc 2
# --> 4, inc applied to 2 twice.
# Factorial through Z combinator.
Z = f =>
(x => f(v => x x v))
(x => f(v => x x v));
f0 = f => n => 1 if n < 2 else n*f(n - 1);
fact = Z f0;
fact 10 # --> 3628800
fib_n = n a b =>
a if n < 1 else
fib_n (n - 1) b (a + b);
fib = n => fib_n n 0 1;
fib 100 # --> 3.54224848179262e+020
# List operation simulation.
end = x => x; # A tag representing the end of a list.
sum = a b =>
a if b == end else
sum (a + b);
sum 1 2 3 4 end # --> 10
for = from to action =>
0 if from == to else
(action from; 1 + for (from + 1) to action);
# Multiplication table
for 2 10 (i =>
(
for 2 10 (j => write (i*j * tab));
write nl
)
# Bisection method, solves f(x)=0, x in [a, b].
bisection = f a b =>
(
let _m = 0.5*(a + b); # the middle of [a, b]
writeln ('a = '*a*', b = '*b); # report the current bracket
_m if a == _m or b == _m else
(
let _fm = f _m;
_m if _fm == 0 else
bisection f _m b if sign _fm == sign(f a) else
bisection f a _m
)
);
bisection (x=>sin (5x) + cos x) 0 pi
# --> 1.8325957145940461
%
и %=
).;
в конце ввода.let
, var
).a b
).<->
), общее сравнение (<>
)._
?).Кувшинов Д.Р. 2017