Интерпретатор языка TRAC, с исходными текстами на языке Си. Лицензия GPL.
Язык программирования TRAC был создан Келвином Муэрсом в начале 60-х. Ссылки:
В данной реализации по сравнению с описанием, приведенным в книге Ч.Уэзерелла "Этюды для программистов" изменена мнемоника, работа с бланками на внешних устройствах, трассировка, нет функций установки и чтения указателя, функция list по умолчанию использует разделитель “,”, конец файла выступает как металитера.
Интерпретатор по очереди считывает и выполняет файлы, указанные в списке параметров. Если параметров нет, считывается файл стандартного ввода. Сигнал прерывания (“^C”) приводит к прерыванию выполнения текущей цепочки и выходу на основной цикл, сигнал выхода (“^\”) - к немедленному выходу из программы.
Синтаксис выражений языка TRAC:
#( имя, пар1, ... )
- активный вызов функции (с повторным сканированием)
##( имя, пар1, ... )
- пассивный вызов функции (без повторного сканирования)
( цепочка )
- защита цепочки от выполнения
| #( add, a, b ) | арифметическое сложение |
| #( and, a, b ) | логическое “и” |
| #( basis, b1, b2, x ) | изменение основания |
| #( call, name, arg ) | вызов бланка |
| #( char, x ) | выдача символа по коду |
| #( clear ) | уничтожение всех бланков |
| #( code, x ) | выдача кода символа |
| #( define, name, body ) | определение бланка |
| #( delete, file ) | уничтожение внешних файлов |
| #( div, a, b ) | арифметическое деление |
| #( eq, a, b, T, F ) | сравнение строк |
| #( exit ) | перейти к следующей программе |
| #( find, name, line, Z) | выдача бланка name до строки line |
| #( get, name, n, Z ) | выдача строки бланка длиной n литер |
| #( getchar, name, Z ) | выдача символа из бланка |
| #( getline, name, Z ) | выдача строки бланка до метки |
| #( gt, a, b, T, F ) | сравнение строк |
| #( halt ) | выход из интерпретатора |
| #( input, Z ) | ввод строки до металитеры |
| #( inputchar, Z ) | ввод символа |
| #( length, x ) | выдача длины цепочки |
| #( list, x ) | выдача списка имен всех бланков |
| #( meta, x ) | установить металитеру |
| #( mul, a, b ) | арифметическое умножение |
| #( not, x ) | логическое дополнение |
| #( notrace ) | выключение трассировки |
| #( or, a, b ) | логическое “или” |
| #( output, x ) | вывод строки в файл вывода |
| #( print, x ) | печать бланков в файл диагностики |
| #( range, name ) | выдача максимального номера метки бланка |
| #( read, file, … ) | считывание бланков из внешних файлов |
| #( remove, name ) | уничтожение бланка |
| #( rewind, name ) | установка указателя в начало |
| #( rshift, n, x ) | циклический логический сдвиг |
| #( scan, name, arg ) | сегментация бланка |
| #( setin, file ) | подключение ввода |
| #( setout, file ) | подключение вывода |
| #( shift, n, x ) | логический сдвиг |
| #( stop ) | перейти к следующему файлу |
| #( sub, a, b ) | арифметическое вычитание |
| #( trace ) | включение трассировки |
| #( write, file, name ) | запись бланков во внешний файл |
#( define, fact,
(#( eq, A, 0, 1,
(##( mul, A, #( fact, ##( sub, A, 1 ) ) ))
))
)
#( scan, fact, A )
#( fact, 40 )
Результат:
815915283247897734345611269596115894272000000000
Вычисляем E как сумму обратных факториалов.
#( define, e, (#( eq, A, 0, B, (#( e, ##( div, A, ##( add, C, 1 ) ), ##( add, A, B ), ##( add, C, 1 ) )) )) ) #( scan, e, A, B, C ) #( e, 1 #( repeat, 10, 0000000000 ) )
Результат:
27182818284590452353602874713526624977572470936999595749669676277240766303535475945713821785251664238
Вычисляем по формуле:
причем арктангенс раскладываем в ряд:
##( define, barctg.loop, (#( eq, B, 0, A, (#( barctg.loop, ##( add, A, ##( div, B, D ) ), ##( div, B, C ), C, ##( add, D, 2 ) )) )) ) ##( scan, barctg.loop, A, B, C, D ) ##( define, barctg, (#( div, #( barctg.loop, B, ##( div, B, ##( sub, , ##( mul, A, A ) ) ), ##( sub, , ##( mul, A, A ) ), 3 ), A )) ) ##( scan, barctg, A, B ) ##( define, pi, (##( mul, 4, ##( sub, ##( mul, 4, #( barctg, 5, A ) ), #( barctg, 239, A ) ) )) ) ##( scan, pi, A ) #( pi, 1 #( repeat, 10, 0000000000 ) )
Результат:
31415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170680