LISP
LIST Processor
Вступительный трёп
- Данная программа не является какой либо лабораторной по программированию или
заданием по работе и создана просто от нечего делать.
- Я не стремился полностью воссоздать стандарт Common Lisp-а. Я просто
приделал функции, которые подвернулись мне под руки. Поэтому в Common Lisp-е
есть функции которые у меня не реализованы. Я меня есть функции, которых нет в
базовом лиспе.
- Многие функции я просто написал, не утруждая себя их проверкой. Так что если что-то
не работает то напишите мне по почте, и оно сразу заработает. Хотя я думаю что успею проверить большую часть функций
в процессе их использования.
- Интерпретатор собран с чатичным применением посторонних текстов и имеет мягко говоря не оптимальную схему распределения
памяти. Посему у него есть два варианта развития. Либо он будет дописан, либо стёрт вместе со всей остальной программой.
Главное отличие заключается в том что этот лисп не поддерживает дробей или
чисел в плавучей запятой. Числа только целые и 32 разрядные.
Полный список
abs
assoc
add1
adjoin
and
append
aref
array
array-dimensions
asctime
aset
ash
assoc-cdr
assoc-cdr-list
assoc-filter
assoc-list
assoc-to-hash
atom
buttail
call-dll
car
case
cdr
char
chr
close
close-socket
clrhash
code-char
collect-garbage
concatenate-strings
cond
cons
copy
copy-alist
copy-file
copy-list
create-directory
decode-time
defconstant
defun
delete-directory
delete-file
delete-function
difference
digit-char-p
directory
directory-exists-p
dolist
dotted-to-ipaddr
drivers-list
dump1, dump2
dump-html
dump-tex1, dump-tex2
endp
eof-p
eq
equal
eval
explode
file-length
file-position
first
for
format
free-dll
free-space
get
get-decodet-time
get-function-by-name
get-host-byname
get-hostname
get-properties
get-time
getf
gethash
go
greaterp
halt
hash-table-hash-function"
hash-table-p
hash-table-rehash-size
hash-table-rehash-threshold
hash-table-size
hash-to-assoc
hash-to-assoc
implode
implode
intersection
ipaddr-to-dotted
last
length
length
lessp
list
list*
list-filter
list-lenght
listp
listp
load-dll
logand
logior
lognot
logtest
logxor
lookup-host-name
loop
lower-case-p
make-array
make-char
make-hash-table
make-list
make-socket
mapcar
% * *= + += - -= / /=
< <= =< => > >=
max
member
merge
min
minus
minusp
nconcatenate-strings
nintersection
not
nth
nthcdr
numberp
numberp
nunion
oddp
onep
options
or
pairlis
plus
plusp
princ
print
prog
prog1
prog2
progn
push
put
puthash
putprop
quit
quotient
random
rassoc
read
read-char
read-ini
read-ini-int
read-line
readch
reg-close-key
reg-enum-key
reg-enum-value
reg-get-value
reg-open-key
reg-set-value
remainder
remob
remove-duplicates
remprop"
rename-file
resize-hash
return
revappend
reverse
rotatef
rplaca
rplacd
second
select-drive
send-letter
set
set-char
set-difference
set-exclusive-or
set-symbol-plist
set-symbol-plist
setf
setq
shell-execute
shiftf
signum
sleep
sock-accept
sock-bind
sock-close
sock-connect
sock-receive-from
sock-recieve
sock-send
sock-send-to
sock-shutdown
sort
square
string-capitalize
string-downcase
string-find
string-left-trim
string-right-trim
string-size
string-test-mask
string-token
string-trim
string-upcase
sub1
sublis
symbol-plist
terpri
times
tree-filter
tree-filter
typeof
typep
union
unless
until
upper-case-p
when
while
write
write-ini
xor
zerop
Список по категориям
Математические функции
abs
add1
% * *= + += - -= / /=
max
min
minus
minusp
numberp
oddp
onep
plus
plusp
random
remainder
signum
sort
square
sub1
times
zerop
Бинарные операции
ash
logand
logior
lognot
logtest
logxor
Работа со списками
adjoin
car
cdr
cons
copy-list
dolist
endp
explode
first
implode
intersection
last
length
list
list*
list-lenght
listp
make-list
mapcar
member
merge
nintersection
nth
nthcdr
nunion
pairlis
push
remove-duplicates
revappend
reverse
rotatef
rplaca
rplacd
second
set-difference
set-exclusive-or
set-symbol-plist
setf
shiftf
sublis
symbol-plist
union
Ассоциативные списки
assoc
assoc-cdr
assoc-cdr-list
assoc-filter
assoc-list
assoc-to-hash
buttail
copy-alist
difference
hash-to-assoc
rassoc
Логические функции
and
append
buttail
eq
equal
greaterp
lessp
< <= =< => > >=
minusp
not
numberp
oddp
onep
or
plusp
xor
Информация о времени
asctime
decode-time
get-decodet-time
get-time
Процедуры
defun
delete-function
go
prog
prog1
prog2
progn
return
Прочая мура
collect-garbage
copy
dump1, dump2
dump-html
dump-tex1, dump-tex2
eval
halt
options
quit
quotient
sleep
Регулярные выражени
assoc-filter
list-filter
string-test-mask
tree-filter
tree-filter
Работа с типами
atom
listp
typeof
typep
zerop
Работа с массивами
aref
array
array-dimensions
aset
assoc-to-hash
hash-to-assoc
make-array
setf
Модификация значений
defconstant
remob
set
setq
Работа с DLL
call-dll
free-dll
get-function-by-name
load-dll
Управление программой
case
cond
for
lookup-host-name
loop
unless
until
when
while
Работа со строками
char
chr
code-char
concatenate-strings
digit-char-p
explode
implode
length
lower-case-p
make-char
nconcatenate-strings
set-char
string-capitalize
string-downcase
string-find
string-left-trim
string-right-trim
string-size
string-test-mask
string-token
string-trim
string-upcase
upper-case-p
Сетевые функции
Сетевая часть сделана мной чисто для отмазки (может потом пригодиться или эту потом доделаю). Все функции являютс
блокирующими. Если буду что-то дорабатывать, то первым делом сделаю асинхронный режим.
close-socket
dotted-to-ipaddr
get-host-byname
get-hostname
ipaddr-to-dotted
make-socket
send-letter
sock-accept
sock-bind
sock-close
sock-connect
sock-receive-from
sock-recieve
sock-send
sock-send-to
sock-shutdown
Файловые функции
close
copy-file
create-directory
delete-directory
delete-file
directory
directory-exists-p
drivers-list
eof-p
file-length
file-position
free-space
read-char
read-line
rename-file
select-drive
shell-execute
Ввод вывод
format
princ
print
read
read-char
read-line
readch
terpri
Хеш таблицы
clrhash
gethash
hash-table-hash-function"
hash-table-p
hash-table-rehash-size
hash-table-rehash-threshold
hash-table-size
make-hash-table
puthash
resize-hash
Реестр и .ini файлы
read-ini
read-ini-int
reg-close-key
reg-enum-key
reg-enum-value
reg-get-value
reg-open-key
reg-set-value
write
write-ini
Свойства
get
get-properties
getf
put
putprop
remprop"
set-symbol-plist
symbol-plist
Описание функций
% * *= + += - -= / /= < <= =< => > >=
Кто знает Си, тот поймёт. А мне описывать влом.
abs
Модуль числа.
acons
(acons <key> <value> <alist>)
Добавляет онвый элемент в ассоциативаный список.
add1
Берёт число. Возвращает число, большее на единцу.
adjoin
(adjoin <element> )
Если элемент присутсвует в списке, то возвращает список. Если нет,
то возвращает элемент присоеденённый к списку спереди.
and
Логическое "и" списка аргументов. При пустом списке возвращает истину.
append
Соеденяет два списка и возвращает копию.
aref
(aref <array> <index1> ...)
Доступ к элементам массива (выделяет нужный элемент из массива).
aset
(aset <array> <element> <index1> ...)
Изменяет отдельный элемент массива.
asctime
Возвращает текущее время в текстовом виде.
assoc
(assoc <element> <assoc-list>)
Возвращает пару из ассоциативного списка (поиск по первому элементу пары).
assoc-cdr
Возвращает ассоциацию для элемета из ассоциативного списка.
assoc-cdr-list
(assoc-cdr-list <list> <assoc-lis>)
Принимает список элеметов. Возвращает список найденых ассоциаций.
assoc-filter
(assoc-filter <string> <assoc-list>)
Создаёт новый ассоциативный список используя те элементы исходного ассоциативного списка,
левый элемент которых совпадает с заданным регулярным выражением. Формат регулярных выражений
описан после команды srting-test-mask.
assoc-list
(assoc-list <list> <assoc-list>)
Возвращает список найденых ассоциативных пар.
atom
Проверка элемента на атом.
buttail
(buttail <list> <number>)
Возвращает копию первых n элементов списка.
array
Тоже самое что и make-array.
array-dimensions
Возвращает список размерностей массива.
ash
(ash <number1> <number2>)
Возвращает сдвиг числа влево на указанное число бит (или вправо, если указан отрицательный сдвиг).
call-dll
(call-dll <число аргументов> <arg1> <arg2> ....)
Вызывает функцию внешней DLL. Возвращает результат ввиде числа.
free-dll, get-function-by-name, call-dll
car
Адресная часть элемента. (для тупых левая часть пары).
case
(case <expr>
(value1 <expr1>..)
(value2 <expr2>..)
...
(t <exprn>) )
Оператор выбора. Сначала оценивается выражение expr. Затем результат сравнивается со значениями value1, value2 ...
В случае совпадения выполняется соотвествующая последовательность операторов.
Поиск идёт до первого совпадения и выполняется только один из вариантов.
Последний список может начинаться с символа t и выполняется только в том случае когда других сопрадений не найдено.
cdr
Декрементная часть элемента. (для тупых правая чать пары).
char
(char )
Возвращает одиночный символ из строки. (из заданной позиции в строке).
chr
Возвращает код по символу.
close
Закрывает файловый дескриптор.
close-socket
Закрывает сетевой сокет.
clrhash
Очищает хеш таблицу.
code-char
Возвращает код символа.
collect-garbage
Прежде всего я хотел бы описать устройство памяти. В основном память состоит из
трёх видов элементов. Пары, атомы и символы. Элементы одинакового типа имеют одинаковые
размеры и хранятся в специальных массивах (банках памяти). Сами банки соеденены в линейные
списки. Если в момент выделения нового элемента в банках нет свободного места, то к списку
присоеденяется новый банк. Во время удаления элемента, соотвествующая ему запись в банке
помечается как свободная (т.е. физическое удаление элемента, а тем более удаление
банка не происходит). .процедура сборки мусора, вызываемая после каждой выполненой
программы находит элементы, которые следует пометить как свободные.
Команда collect-garbage предназначена для однократного изменения режима работы
сборщика мусора. Для того чтобы воспользоваться командой - следует указать один из
ниже описанных ключей.
- SKIP
Однократная отмена сборки мусора. То есть после очередного выполнения программы
процедура сборки мусора вызываться не будет.
- ONLYFREE
Удаление не занятых банков памяти. Я правда не представляю
что надо устроить для того чтобы целый банк памяти остался свободным.
- ONLYPACK
Удаление не занятых элементов. Достаточно сложная процедура.
Сдигает занятые записи в банках памяти так чтобы между ними не оставалось
свободных записей. Банки памяти, которые остались незанятыми целиком - удаляются.
Сама процедура требует для своей работы временного выделения дополнительной памяти.
- FREEСборка мусора с последующим удалением незанятых банков.
- PACKСборка мусора с последующим удалением элементов помеченых как свободные.
- NORMALОтменяет действие предыдущих ключей.
Вот в кратце и всё. Едиственное что следует заметить - сама команда оказалась очень
коряво сделанной. Кроме того в ней есть очень похожие фрагменты кода (разница лишь
в том что они работают с элементами разных типов). А мне никогда не нравилось делать
две похожие процедуры в одной программе. Их всегда можно заменить одной.
concatenate-strings
Соеденяет две строки в одну.
cond
(<expr1> ...)(<expr2> ...)(<expr3> ...) ...)
Проверяет по очереди выражения <expr1><expr2>... В случает если выражение равно t, выполняется соответсвующая ему последовательность операторов.
Выполняется только один из вариантов.
cons
Соеденяет два элемента в пару.
copy
Создаёт полную копию элемента. То есть это атом, то опия атома. Если это дерево,
то для каждого узла и элемента дерева создаётся отдельная копия. Ели элементы дерева пересекаютс
или зацикливаются, то создаётся копия с пересечениями и зацикливаниями.
В начале я хотел сделать так чтобы при копировании списка, процедура отслеживала
то что элементы объеденены в список и копировала последний не применяя рекурсию.
То потом на меня напал отсрый приступ лени и решил это дело отложить.
Так что для копирования списков и деревьев лучше применять соотвестующие этому процедуры.
А copy испольховать для копирования атомов или небольших структур.
copy-alist
Создаёт копию ассоциативного списка.
copy-file
(copy-file )
Создает копию файла. Возвращает t если файл скопировать не удалось.
copy-list
Создаёт копию списка.
create-directory
Создаёт директорию. Возвращает t в случае ошибки.
decode-time
Принимает вермя в числовом виде. Даёт вермя в тесктовом виде.
defconstant
Создаёт символьную константу с атрибутом READ_ONLY.
В результате получается константа. Или другими словами символ который нельзя удалить из
паряти или переопределить. По сути работает как команда setq, но результат изменять нельзя.
defun
Создаёт нечто вроде процедуры.
delete-directory
Удалаяет пустую директорию. Возвращает t учли удалить не получилось.
delete-file
Удалает файл. Возвращает t если он не удаляется.
delete-function
Удаляет функцию из памяти. (Если выражаться научным, то отрывает ей бошку, а удаляет
её сборщик мусора).
dialog
Система постоения диалогов. Позволяет просто и легко конструировать и пользоватьс
произвольно сконструированными диалогами. К сожалению я пока не стал делать
эту функцию. Ещё не решил нужна ли она мне (тем более что делать её придётся долго).
Разумеется по использованию она должна напоминать просто и элегатное построение
диалогов в mIRC скриптах.
difference
Я почему то не смог сразу найти описание этой функции, поэтому сделал её по памяти.
Если я сделал не то что она должна делать, то всё равно функция получилась полезная.
Функция берёт два списка и составляет новый, не включая в него одинаковые элементы.
digit-char-p
Возвращает t если на видит что в строке записаны только числа.
directory
Возвращает список файлов в указаной или текущей директории.
directory-exists-p
Возвращает t если указанная директория существует.
dolist
(dolist (var list) <expr1>....)
(dolist (var `(4 8 7 2 5 8 7)) (print var)) - напечатать по очереди каждый элемент списка
Функция для работы со списками (похожую я шелле для юникса видел).
Каждый элемент списка будет подставляться в указанную переменную с последующим выполнением последовательности
операторов <exp1>...
dotted-to-ipaddr
Эту функцию я подглядел в Allegro LISP 6.1 (пока на него места хватало). Они берёт IP адрес записанный в текстовом
виде и преобразует его в одно 32 битное число.
drivers-list
Создаёт список доступных дисков.
dump1, dump2
Выволит свои параметры ввиде дерева. Дерево печатается в тесктовом виде (обход инфиксный, соеденительные линии не выводяться).
Нужна лишь как мелкая отладочная функция. dump2 отличается от dump1 тем что не производит предварительную обработку
своих аргументов.
dump-html
Выводит дамб всей памяти ввиде html файла. Эта функция была сделана до того как сделаны массивы и хеш таблицы (и более
того сделана очень коряво). Так лучше всего вы бы про неё не знали.
dump-tex1, dump-tex2
Выводит копию второго своего аргумента ввиде дерева (а дерево ввиде исходника для TeX-а). Может быть я просто
когда-то был помешан на TeX-е. Но такой вывод является моим излюбленным способом отладки. К сожалению я не могу
пока что нарисовать как всё это выглядит. У меня PaintBrush подох. А переставлять Windows лень.
endp
Проверка списка на конец. Выдаёт t когда видит NIL. Абсолютно бестолковая функция.
eof-p
Проверка файла на конец.
eq
Проверка двух атомов на равенство. Обычно применяется для сравнения чисел.
equal
Проверка одиаковости двух элементов. Для деревье рекурсивно сравнимаются все листья.
eval
Оценка выражения. Включена в интерпретатор только ради того что она есть. Таже самая оценка автоматом происходит
для каждого вводимого выражения (после нажатия Enter).
explode
Берёт строку и выдаёт её буквы по одиночке ввиде списка.
file-length
Выдаёт длину файла.
file-position
Выдаёт позицию записи(чтения) в файле.
first
Первый элемент списка.
for
Команда создания цикла.
(for (i 0 10) <expr1> <exr2;> ...)
Во такой где-то синтаксис. Если он должен быть не таким, то напишите мне и он будет таким как надо.
Переменная i, начальное, конечное значение. В Allegro была более гирокая реализаци
этой команды, и эту самую реализацию я хотел скопировать. Но вот только
описание потерял. Так что не получиться.
Если конечное значение больше конечного, то отчёт будет идти в сторону уменьешния. Если вы измените значение переменной
в которой лежит значение счётчика, то отчёт будет продолжен, но вместо значения счётчика в переменной будет лежать
то что вы в неё положили. Мне не хотелось на каждом шаге цикла проверять или заново устанавливать значение символа
(жертвуя при этом памятью или скоростью).
format
По действию напоминает printf.
То есть эта команда печатает строку которую ей подпихивают. Но перед этим находит в ней буквы перед которыми
стоит ~ и подставляет вместо них параметры идущию следом по списку.
(format "x= ~D" 14)
- ~S ~s
- подставляет ввиде строки
- ~D or ~d
- подставляет число
- ~%
- перевод строки
- ~t or ~T
- табуляци
- ~~
- сама тильда
- ~x
- число в hex виде с маленькими буквами
- ~X
- число в hex виде с большими буквами
- ~B
- число в двоичном виде
- ~O
- число в восмиричном виде
fourth
Эту замечательную функцию я сделаю как только вспомню что она должна делать.
free-dll
Выгружает из памяти указаную DLL.
load-dll, get-function-by-name, call-dll
free-space
Показывает размер свободного места на указанном диске в килобайтах.
get
Запрос свойств символа.
get-decodet-time
Выдаёт текущее время в текстовом виде.
get-function-by-name
Находит функцию в загруженной внешней DLL.
get-host-byname
Определяет IP адрес хоста по имени. Возвращает список IP ввиде 32 битных чисел.
get-hostname
Определяет локальное имя компютера.
get-properties
(get-properties <list>)
Массовый запрос свойств символа. На входе список названий свойств. На выходе список
найденых свойств.
get-time
Выдаёт текущее время ввиде числа.
getf
То же что просто get.
gethash
(gethash <hash-table> <string>)
Берёт отдельный элемент и хеш таблицы.
go
Переход в пределах поцедуры.
greaterp
Сравнение чисел. >
halt
Выход из интерпретатора.
hash-table-hash-function"
Хеш функция. Берёт строку, выдаёт число.
hash-table-p
Выдаёт t , если на входе хеш таблица.
hash-table-rehash-size
Говорит на какой размер будет изменёна шех таблица в случае переполнения.
hash-table-rehash-threshold
Выдаёт коэффициент рехеширования таблицы.
hash-table-size
Выдает текущий размер таблицы.
implode
Принимает список симовлов и создаёт из них строку.
ipaddr-to-dotted
Преобразует число в текстову запись IP.
intersection
Список всех элементов присутвущих в двух списках (исключая повторы).
last
Последний элемент списка.
length
Выдаёт длину списка или строки символов.
lessp
Сравнение чисел <
list
Создаёт список элементов.
list*
Создаёт список элементов не раскрывая символы.
list-filter
(list-filter <filter> <string list>)
Создаёт новый список из тех элементов старого списка, которые подходят под заданный фильтр. См. регулярные выражения.
list-lenght
Измеряет длину списка.
listp
Проверяет является ли элемент списком. Достаточно сложным явлется вопрос - "а что же в лиспе нельзя назвать списком ?".
Даже хеш таблица по сути список из одного элемента.
В данной функции, любой элемент отличный от nil и не оканчивающийся на пару (пара это такая хреновина из двух элементов
с точкой по середине).
load-dll
(load-dll <filename>)
Загружает в память внешнюю DLL. Возвращает t если загрузить не удалось.
free-dll, get-function-by-name, call-dll
load-image
Эта функция пока что не поддерживается.
logand
Побитовое 'и' для чисел.
logior
Побитовое 'или' для чисел.
lognot
Побитовое инвертирование.
logtest
Выполняет побитовое 'и' над числами. Возвращает не t если получился не ноль.
logxor
Побитовый xor для чисел.
lookup-host-name
Определяет имя хоста по IP адресу.
loop
Замкнутый цикл без выхода.
lower-case-p
Выдаёт t если указанная строка состоит из букв в нижнем регистре (точнее если в ней нет букв в верхнем регисре.
make-array
Создаёт массив элементов.
(make-array :type 4 5 6 6)
Тип элементов, который можно не указывать. И список размерностей.
- bit - битовый тип
- bool - булевый тип
- byte - байтовый тип
- char - одиночные буквы
- word - числа 2 байта
- dword - числа 4 байта
- all - абстрактный тип
- string - текстовые строчки
- socket - сетевые соккеты
- file - файловые дескрипторы
hash-to-assoc
Преобразует хеш таблицу в ассоциативный список.
assoc-to-hash
Преобразует ассоциативный список в хеш таблицу. Ключи такие же как у make-hash-table
- :size - начальный размер таблицы.
- :rehash-size - во сколько раз число элементов может превышать размер таблицы.
make-char
Создаёт строку длиной в один символ. В качестве параметра получает строку (отрывая от ней первый символ) или код символа.
make-hash-table
Создаёт хеш таблицу. В качестве параметра можно указывать два ключа.
- :size - начальный размер таблицы.
- :rehash-size - во сколько раз число элементов может превышать размер таблицы. В случае превышения допустимого размера происходит перестройка таблицы. (значение этого ключа может быть только целым числом).
make-list
(make-list <size> [:inital-element <element>])
Создаёт список заданной длины. Если заполняющий элемент не указан, то список запоняется nil.
make-socket
Создаёт сетевой соккет. С параметром :datagram или :udp создаёт UDP соккет.
mapcar
Типа она у меня есть. Читайте мануал к лиспу.
max
Выбирает самое большое число из списка чисел.
member
(member <element> <list>)
Проверяет наличие элемета в списке. Возвращает nil или конец списка начинающийся с данного элемента.
merge
Сливает две возрастающие последовательности чисел в одну возрастающую послевательность.
В принципе если последовательности возрастают не везьде, то вcё равно сливает. За границами возрастающих
кусков не следит, поэтому применять эту функцию для сортировки слиянием не очень эффективное решение.
min
Выбирает минимальное число из списка чисел.
minus
Унарный минус. Меняет знак числа.
minusp
Возвращает t , если число отрицательно.
nconcatenate-strings
Соеденяет две строки в одну. Разрущающий вариант concatenate-strings, то есть заменяет значение первой из строчек.
nil
NIL он и есть nil.
nintersection
Добавляет к первому из списков элементы, элементы которые в нём отсутсвуют, но присутвуют во втором списке.
not
Логическое не.
nth
(nth <integer> <list>)
Выдаёт заданый элемент списка.
nthcdr
(nthcdr <integer> <list>)
Выдаёт остаток списка после заданного элемента.
null
Выдаёт истину если видит пустой список.
numberp
Выдаёт истину если получает число.
nunion
Принимает на вход два списка. К первому списку добавляет элементы которые в нём отсуствуют, но присутсвуют во втором списке.
oddp
Проверка числа на чётность.
onep
Принимает на вход число. Возвращает t если оно равно еденице.
options
(options :options time :on :verbose :off)
Доступны следующие параметры
sensitive - чуствительность интерпретатора к регистрам.
time - автоматическая оценка времени выполнения каждой команды
verbose - вывод отладочной информации
or
Логическое 'и' над списком операторов.
pairlis
(pairlis <list> <list> [<alist>])
Соденяет два списка и делает из них один ассоциативынй список.
plus
Суммирует список чисел.
plusp
Принимает на вход число. Возвращает плюс, если оно положительное.
princ
Вводит элемент на консоль, не делая в конце перевод каретки.
print
Выводит элемент на консоль и переводит каретку на следующую строчку.
prog
(prog (i) (print (* i i)))
Некое подобие процедуры. Можно задать символы в качестве параметров процедуры. можно вернуться из неё с помощью return.
prog1
Оценивает список идущих за ним операторов и возвращает на верх результат работы первого из них.
prog2
Оценивает список идущих за ним операторов и возвращает на верх результат работы второго.
progn
Оценивает список идущих за ним операторов и возвращает на верх результат работы последнего.
push
Принимает на входе элемент и список. Возвращает элемент присоеденённый к списку спереди.
put
Задаёт свойства символа.
puthash
Добавляет новый элемент в хеш таблицу.
putprop
Тоже самое что и put
quit
Выход из программы.
quotient
Деление.
random
(random [<integer>] [:init <integer>])
Выдаёт случайное число. В качестве параметром можно задать максимальный размер числа, а так же начальное значение генератора чисел.
rassoc
Поиск пары в ассоциативном списке. Поиск идёт по второму элементу пары.
read
Чтение выражения с консоли.
read-char
Чтение символа из файла.
read-ini
(read-ini <filename> <sectioname> <paramname> :default <value>)
Читает параметр из ini файла.
read-ini-int
Тоже самое что read-ini-int но с целыми числами.
read-line
Чтение текстовой линии из входного файла.
readch
Чтение символа с консоли.
reg-close-key
Закрывает дескриптор реестра.
reg-enum-key
На входе получает открытый дескрипторреестра. На выходе список всех подразделов данного ключа.
reg-enum-value
На входе открытый дескриптор реестра. На выходе список названий параметров
(видит только текстовые параметры и 32 разрядные числа).
reg-get-value
Запрос значения записи в реестре. Нужно указать дескриптор реестра, название параметра.
Значение будет получено ввиде цифры или строки.
reg-open-key
Открывает новый дескриптор реестра. Нужно указать родительскй дескриптор или один из ключей :
HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, HKEY_USERS. А также название подраздела.
Если ключ или родительский дескриптор не указанны, то по умолчанию открывается HKEY_CURRENT_USER.
reg-set-value
Модификация значения записи в реестре. Нужно указать дескриптор реестра, название параметра и значение
записи ввиде цифры или строки.
remainder
Деление по модулю.
remhash
(remhash <hash-table> <symbol>)
Удаляет одну запись их хеш таблицы.
remob
(remob <symbol>)
Удаляет один символ из LISP-а.
remove-duplicates
Удаление одинаковых элементов из списка. Возвращает копию списка, без одинаковых элементов.
remove-duplicates <list> [:start <number> :end <number>])
:start :end начало и конец фрагмента в списке.
remprop"
(remprop <symbol> <string>)
Удаляет заданное свойство символа.
rename-file
(rename-file <filename1> <filename2>)
Переименовывает файл.
resize-hash
(resize-hash <hash-table> <integer>)
Изменяет размер хеш таблицы на указанный.
return
Выход из процедуры.
revappend
Берёт два списка и присоеденяет к первому списку перевёрнутую копию второго.
reverse
Переворачивает список.
rotatef
Прокручивает список на одну позицию влево. То есть отрывает первый элемент и приделывает его к концу списка.
rplaca
Производит замену элементов. (car x) заменяет на (cdr x)
rplacd
Производит замену элементов. (cdr x) заменяет на (car x)
save-image
Запись компилированного образа. В данной версии не поддерживается.
second
Выдаёт второй элемент списка.
select-drive
Выбор диска.
send-letter
(send-letter <addres> <backaddres> [:server <name>] [:host <hostname;>] [:subject <name>] text)
Посылка письма.
set
Раскрывает символ и устанавливает новое значение.
set-char
(set-char <string> <integer> <char>)
Изменяет один символ в указанной строке.
set-difference
(set-difference <list1> <list2>)
Возвращает список элементов, которые входят в первый список и не входят во второй.
set-exclusive-or
(set-exclusive-or <list1> <list2>)
Возвращает список элементов, которые присутсвуют только в одном из списков.
set-symbol-plist
(set-symbol-plist <symbol> <list>)
Плонстью заменяет список свойств символа на указанный. Список свойств можно указывать ввиде
ассоциадивного списка (первая пара как символ), либо чередуя символы и свойства. Можно указывать
чередуя оба способа. Список обрабатывается до тех пор пока ссовтествует условиям. Элемент списка
который не удовлетворяет условиям считается концом списка (подобная мягкость присуща многим функциям интерпретатора).
setf
Установка значения некоторых функций :
(setf (car <element>) <element>)
(setf (cdr <element>) <element>)
(setf (nth <index> <list>) <element>)
(setf (aref <array> <index1> ...) <element>)
(setf (get <symbol> <symbol>) <element>)
(setf (symbol-plist <symbol>) <list>)
(setf (gethash <table> <key>) <element>)
setq
Нечто вроде присваивания. кто знает LISP тот поймёт.
shell-execute
(shell-execute <exename> [<arguments>] [:hide])
Запуск внешней программы. Ключ :hide обозначет запуск в скрытом режиме, то есть программа в процессе работы не будет
показываться на экране. Кроме имени прогаммы можно укаать список ключей из символов и цифр. Параметры будут переданы
программе в коммандной строке.
shiftf
Сдвиг элементов списка влево. Последний элемент заменяется на nil. Списки из одного элемента сдвигу не подлежат.
signum
Знак числа. -1 0 1
sleep
Задержка в микросекундах. 1000 соответствует одной секунде.
sock-accept
(sock-accept <socket> [:port <number>])
Ждёт подключения к соккету. Если подключение произошло, то возвращает новый соккет, через который можно работать
с клиентом.
sock-bind
(sock-bind :addr <addr> :port <port;>)
Привязывает сокет к определенному адресу. В качестве адреса можно указывать
32 разрядное число, IP адрес в тесктовой записи или имя сервера. Адрес можно не
указывать, тогда адрес будет равен нулю (т.е. широкому диапазону).
Порт надо указывать обязательно.
sock-close
Закрывает соккет.
sock-connect
Конектит сокет к серверу. Требуется указать порт и адрес.
sock-receive-from
(sock-receive-from [:buffer-size <number>] [:addr <addr> :port <port;>])
Принимает дейтаграмму. Если соккет не куда не привязан, то можно указать
параметры привязки (синтаксис как в sock-bind).
sock-recieve
(sock-receive [:buffer-size <number>])
Принмает TCP пакет.
sock-send
(sock-send <socket> <string>)
Посылает TCP пакет.
sock-send-to
(sock-send-to <socket> <string> :addr <addr> :port <port;>)
Посылает UDP пакет.
sock-shutdown
Насильно разрывает сокет. Известно что сокет мжно разрыват тремя способами :
- - если пользователь больше не желает читать данные
- - если данные больше не будут посылатьс
- - если данные не будут ни посылаться ни получатьс
Итак это команда может иметь два ключя - :noread :nowrite, которые соотвествуют пунктам 0 и 1. Если ключи не указанны
или указаны оба, то разрыв произойдёт по третему пункту.
sort
Сортирует ассоциативный или простой список (загоняет во временый массив и сортирует по Шеллу).
square
Квадратный корень из числа.
string-capitalize
Изменяет регистр символов строки. Первая буква большая, остальные все маленькие.
string-downcase
Переводит символы строки в нижний регистр.
string-find
(string-find <string> <substring>)
Поиск подстроки в символе. Возвращает либо позицию начиная от нуля, либо nil.
string-left-trim
Отрезает от левой части символа крайние пробелы.
string-right-trim
Отрезает от правой части символа крайние пробелы.
string-size
Выдаёт длину cимвольной строки.
string-test-mask
(string-test-mask <string> <expression;>)
Сравнивает строку с регулярным выражением.
регулярное выражение
* любая последовательность знаков (возможно нулевая)
? любой одиночный символ
[abc] любой из символов abc
[a-z0-9] любая буква или цифра
[~0-9] любая не цифра
{on|off} on или off. В фигурных допустимы вложения или применения выше указанных символов.
string-trim
Отрезает крайние символы от строки.
string-upcase
Переводит символы строки в вверхний регистр.
string-token
(string-token <string> <char> <integer>)
Выделяет одиночный токен из строки. Требует указать номер токена и символ разделитель.
sub1
Возвращает число минус единица.
sublis
(sublis <alist> <elem>)
Поиск пары в ассоциативном списке. Ищет первый элемент пары, возвращает второй.
Если элемент не найден, то возвращет сам элемент.
symbol-plist
Выдает полный список свойств символа ввиде ассоциативного списка.
terpri
Перевод каретки на консоли.
times
Перемножает список чисел.
tree-filter
(tree-filter <tree> <symbol>)
Принимает на вход дерево символов и маску. Составляет копию дерева из элементов которые попадают в маску.
typeof
Выдаёт тип элемента. Принимает следующие значения : cons integer symbol param array hash-table socket file dll dll-fn registry-key.
typep
(typep <element> <type>)
Проверка элемента на соотвествие заданному типу.
union
Принимает на вход список списков. И Создаёт новы список ислючая общие элементы.
unless
(unless <expr> ....)
Выполняет последовательность операторов, если выражение принимает лож.
until
(until <expr> ....)
Цикл с предусловием. Выполняет бесконечно последовательность операторов пока выражение равно лжи.
upper-case-p
Возвращает t если укаан символ с буквами в верхнем регистре.
when
(when <expr> ....)
Выполняет последовательность операторов, если выражение принимает истину.
while
(while <expr> ....)
Цикл с предусловием. Выполняет бесконечно последовательность операторов пока выражение равно истине.
write
Банальная запись в файл числа или символа.
write-ini
(write-ini <filename> <sectioname> <paramname> <params>)
Запись в ini файл. Как параметр для записи можн указывать число или символ.
xor
Логический xor элементов.
zerop
Проверка числа на ноль.
Внутренняя архитектура !
Память интерпретатора в основном состоит из элементов трёх типов.
- Символы. Структура символа содержит флаги символа, ссылку на имя символа, сслыку на цепочку свойств символа.
- Пара из двух элеметов. Содержит флаги и ссылку да певый и второй элемент пары.
- Простой элемент. Содержит флаги и значение элемента. Значением элемента может быть, сслыка на строку, соккет,
число, ссылка на массив и т.д.
struct symbol { // символ
char *name; // имя символа
byte flags; // флаги
union { internal ifunc; atom *property;} u; // сслыка на свойства или адрес машинной процедуры
symbol *next; // след элемент в хеш таблице
};
struct con { // структура пары
byte flags; // флаги
union{ struct {atom *car;atom *cdr;}cons;con *next;}u; // левый и правый элемент
};
struct atom { // обычный элемент
byte flags; // флаги
union{integer num;symbol *sym;atom *next; SOCKET sock; // значение элемента
FILE *file;HMODULE dll; void *fn; array *arr; // ..
HashTable *hash; char *arg;HKEY rKey;}u; // ..
};
Младшие 4 бита флага указывают на тип элемента
sCONS | только для элементов con
|
sINT | целое число
|
sSYM | символ
|
sFREE | свободный элемент
|
sPARAM | параметр
|
sARRAY | массив
|
sHASH | хеш таблица
|
sSOCKET | сетевой сокет
|
sFILE | файловый дескриптор
|
sDLL | DLL дескриптор
|
sFN | дескриптор DLL функции
|
sREG | ключ реестра
|
Интерпретатор хранит основные элементы в небольшых массивах, которые выделает по мере надобности и объеденяет в однонаправненные линейные списки.
При уничтожении элементов элементы физически не уничтожаются, а помечаются как свободные и присоеденияет с списку cвободных элеменов.
Таким образом при выделении элементов, элемент берётся из списка свободных элеменов, а если список пуст, то выделяется новый массив элементов.
В интерпретаторе есть строчка длиною 512 байт, содержащая в себе все возможные односимвольные слова. Если кто-то пытается
выделить символ длиной в один или ноль знаков, то строка со значением символа не выделается а заменяется ссылкой данную
таблицу (едиственным преимуществом данного распределителя памяти состоит в том что однаковые строчки можно не выделять
вовсе, а использовать повторно уже существующие).
Хеш таблицы
struct HashItem{char *key; atom *value; HashItem *next;};
struct HashTable{ // структура таблицы
char threshold; // во сколько количество элементов не должно превышать размера
int size; // размер таблицы
int count; // число элементов в таблице
HashItem **table; // таблица
};
Массивы
struct array {
byte type; // тип элементов массива
int all; // общее количество элементов в массиве
int dim; // число размерностей массива
int *dims; // ссылка на список размерностей массива
void *data; // ссылка на данные массива
};
Если массив имеет одну размерность, то список размерностей не создаётся. А о размере массивов можно судить только по
общему числу элементов.
типы массивов
ARRAY_BIT | битовый
|
ARRAY_BOOL | булевый
|
ARRAY_BYTE | байтовый
|
ARRAY_CHAR | символьный
|
ARRAY_WORD | двухбайтовые элементы
|
ARRAY_DWORD | четырёхбайтовые элементы
|
ARRAY_ATOM | произвольные элементы
|
ARRAY_STRING | строчки
|
Раньше ещё были были массивы из файлов и сетевых соккетов, но я их убрал.
Часть процедур
память
void GetArrayBank() | выделяет новый массив для массивов
|
void GetAtomBank() | выделяет новый массив элементов
|
void GetConsBank() | выделяет новый массив для пар
|
void GetSymBank() | выделяет новый массив символов
|
atom *GetSYM(char *s) | создаёт новый элемент с символом (на входе название)
|
symbol *GetSym() | создаёт новый символ
|
array *GetArray() | создаёт новый массив
|
atom *GetAtom(byte flags,void* arg) | создаёт новый элемент (на входе тип и значение)
|
atom *GetCons(atom *ref1,atom *ref2) | создаёт новый пару (на входе элементы пары)
|
atom *GetINT(p) | создаёт новый атом с числом (на входе значение атома)
|
atom *GetSYM(char*) | создаёт новый атом со строкой (на входе строка с которой будет снята копия)
|
void FreeArray(array *p) | удаляет массив
|
void FreeAtom(atom *p) | удаляет элемент
|
void FreeCons(con *p) | удаляет пару
|
void FreeAllAtom() | удаляет все элементы
|
void FreeSym(symbol *p) | удаляет символ
|
void FreeAllSym() | удаляет все символы
|
void InitMemory() | инициализирует распределитель
|
void CollectGarbage() | сборщик мусора
|
void CleanMemory() | удаляет банки, кот. целиком состоят из не занятых элементов.
|
Макросы для проверки атомов
isnil(p) | nil
|
iscons(p) | пара
|
issymbol(p) | символ
|
isint(p) | число
|
ispar(p) | параметр
|
хеш таблицы
unsigned int chc(char*) | расчёт контрольной суммы
|
HashItem **find(HashTable*,char*) | поиск в хеш таблице (возвращает ссылку)
|
atom *get(HashTable*,char*) | берёт элемент из таблицы
|
void add(HashTable*,char*,atom*) | добавляет элемент в таблицу
|
void del(HashTable*,char*) | удаляет элемент из таблицы
|
void clear(HashTable*) | очищает таблицу
|
void resize(HashTable*,int) | изменяет размер таблицы
|
void destroy(HashTable*) | удаляет таблицу
|
HashTable *New(int,int) | создаёт таблицу
|
Фунции языка
Все реализованные функции языка получают на вход один едиственный параметр содержащий в себе список или дерево параметров.
(list 1 2 3 4) (print 33)
\ \
C C
/ \ / \
1 C 33 NIL
/ \
2 C
/ \
3 C
/ \
4 NIL
Вспомогательные
bool REGULAR::syntax(char *test) проверка корректности регулярного выражени
bool REGULAR::test(char *txt,char *tst) проверка на совпадение с регулярным выражением
int ArrayAccess(array *arr,atom *p) вычисляет индекс для доступа к массивам
arr | - массив
|
p | - список индексов
|
-1 | не хватает индексов
|
-2 | индексы за пределами размерностей
|
bool ismember(atom *p,atom *l) проверка на принадлежность элемента списку
bool SetFileName(char *name) разворачивает наклонные палки в имени файлов в нужные стороны.
возвращает true если последним символов была слешка.
int ListSize(atom *p) измеряет длину списка
atom *CopyList(atom *p) создаёт копию списка
bool SyntaxCheck(char *s,atom *p) проверка структуры парамера
* | возврат к началу подвыражени
|
() | вложенное выражение
|
| | или
|
ad | путь (car cdr)
|
A | массив
|
f | файловый дескриптор
|
F | функция из DLL
|
D | DLL
|
p | параметрическмй ключ
|
r | символ не имещий защиты от записи (проверку на символ не делает)
|
R | ключ реестра
|
h | хеш таблица
|
с | cons
|
s | symbol
|
S | сетевой соккет
|
n | symbol & nil
|
i | integer
|
z | atom_int == 0
|
пример:
(dai)ai | два целых аргумента функции
|
n|(ac)d* | любой ассоциативынй список
|
n|(ai)d* | любой список чисел
|
atom *assoc(atom *p,atom *as) поиск пары в ассоциативном списке по первому элементу
void dump(int depth,atom *p) выводит структуру параметров на экран (мжно вставлять в процедуры для отладки).
void StartWSA() производит автоматическую инициализацию WSA (сбрабатывает только при первом запуске).
char *NameByCAR(atom *p) берёт название строки из atom_car(x) элемента
char ReadBindArg(atom *p,SOCKADDR_IN *addr) читает парамерты функции sock-bind или sock-connect
0 | - параметры прочитаны
|
1 | - параметры не верны
|
2 | - сервер не найден
|
Служебные функции
class LIST
Создание списка
void add(atom *p) добавляет новый элемент в список
atom *get() выдаёт результирующий список
class String
Строка
void reset() обнуление строки
void add(char s) добаление символа
void add(char *s) добавление строки
char *get() результат
Образцы процедур
Копирование списка
atom *i_copy_list(atom *p)
{
LIST list;
while(iscons(p)) list.add(atom_car(p)),p=atom_cdr(p);
return list.get();
} // i_copy_list
Перемножение списка чисел
atom *i_times(atom *p) {
integer s = 1;
if(Check("'times' needs a number list","(ai)d(n|(ai)d*)",p)) return 0;
while(iscons(p))
{
s*=atom_int(atom_car(p));
p=atom_cdr(p);
}
return GetINT(s);
} // i_times