GNU MIX Development Kit (mdk): mixguile

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

8. mixguile, виртуальная машина на основе Scheme

Эта глава содержит описание использования mixguile и библиотеки функций Scheme, дающих доступ к виртуальной машине MIX в эмуляторах MDK (mixguile, mixvm и gmixvm). См. в 3.4 Использование mixguile учебное пошаговое введение в mixguile и использование Scheme как языка расширения виртуальных машин MIX MDK.

8.1 Вызов mixguile  Параметры командной строки.
8.2 Описание функций Scheme  


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

8.1 Вызов mixguile

При вызове mixguile без аргументов она после загрузки файла инициализации `~/.mdk/mixguile.scm' (если он существует), войдёт в Guile REPL (read-eval-print loop, цикл ввода, обработки и вывода).

mixguile принимает те же параметры командной строки, что и Guile:

 
mixguile [-s SCRIPT] [-c EXPR] [-l FILE] [-e FUNCTION] [-qhv]
         [--help] [--version]

Значение этих параметров таково:

User Option: -h
User Option: --help
Вывести краткое описание использования программы и завершить работу.

User Option: -v
User Option: --version
Вывести версию и информацию об авторских левах и завершить работу.

User Option: -s SCRIPT
Загрузить код Scheme из файла script, обработать его и завершить работу. Этот параметр может быть использован для написания исполняемых скриптов Scheme, как описано в 3.4.5 Скрипты Scheme.

User Option: -c EXPR
Вычислить заданное выражение Scheme и завершить работу.

User Option: -l FILE
Загрузить заданный файл Scheme и войти в REPL (цикл ввода, обработки и вывода).

User Option: -e FUNCTION
После чтения скрипта, вызвать заданную функцию с аргументами, указанными в командной строке. Например, вы можете написать следующий скрипт Scheme:

 
#! /usr/bin/mixguile \
-e main -s
!#

;;; выполнить заданную программу и вывести содержимое регистров.

(define main
  (lambda (args)
    ;; загрузить файл, указанный в аргументе командной строки
    (mix-load (cadr args))
    ;; выполнить его
    (mix-run)
    ;; вывести содержимое регистров
    (mix-pall)))

сохранить её в файле, скажем, `foo', сделать его исполняемым и выполнить:

 
$ ./foo hello
Такой вызов запустить вычисление функции main со списком параметров командной строки в качестве аргумента (в вышеприведённом примере ("./foo" "hello)). Заметьте, что параметры командной строки для mixguile должны находиться в отдельной строке после символа \.

User Option: -q
Не загружать пользовательский файл инициализации. При запуске mixguile она проверяет наличие файла `mixguile.scm' в каталоге конфигурации `~/.mdk' и, если он существует, загружает его. Этот параметр велит mixguile не загружать файл инициализации.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

8.2 Описание функций Scheme

Как мы указали выше, mixguile содержит встроенную виртуальную машину MIX, доступ к которой возможен через набор функций Scheme, т.е. через библиотеку Scheme. С другой стороны, mixvm и gmixvm содержат интерпретатор Guile и могут использовать ту же библиотеку Scheme, равно как и все остальные примитивы Guile/Scheme и любые определённые пользователем функции. Поэтому в вашем распоряжении находится мощный язык программирования -- Scheme -- позволяющий расширять возможности эмуляторов виртуальной машины в составе MDK (см. примеры в 3.5 Использование Scheme в mixvm и gmixvm).

Следующие подразделы описывают доступные функции библиотеки MIX/Scheme.

8.2.1 Оболочка команд mixvm  Функции, вызывающие команды mixvm.
8.2.2 Функции-ловушки  Добавление ловушек к командам mixvm.
8.2.3 Дополнительные функции ВМ  Функции доступа к виртуальной машине MIX.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

8.2.1 Оболочка команд mixvm

Каждой из команд mixvm, перечисленных в 6.2 Интерактивные команды, соответствует функция Scheme, название которой образовано добавлением к имени команды префикса mix- (например, mix-load, mix-run и т.д.). Эти оболочки команд реализованы единой функцией передачи команды:

Function: mixvm-cmd command argument
Передаёт указанную команду command и аргументы виртуальной машине MIX. И command, и argument должны быть строками. Результат будет тот же, что и выполнение "command argument" из командной строки mixvm или gmixvm.

Например, вы может вызвать команду run из приглашения mixvm тремя разными способами:

 
MIX > run hello
MIX > (mix-run "hello")
MIX > (mixvm-cmd "run" "hello")
(в приглашении mixguile или в скрипте Scheme могут быть использованы только две последние формы).

Функции mix- не вычисляют значений. Если вы хотите проверять результаты вызова команд mixvm, используйте функцию mix-last-result:

Function: mix-last-result
Возвращает #t, если последнее выполнение команды mixvm было успешным, #f в противном случае.
Используя эту функцию, мы можем усовершенствовать скрипт для запуска программы, приведённый в прошлом разделе, добавлением проверки ошибок:

 
#! /usr/bin/mixguile \
-e main -s
!#

;;; выполнить заданную программу и вывести содержимое регистров.

(define main
  (lambda (args)
    ;; загрузить файл, указанный в аргументе командной строки
    (mix-load (cadr args))
    ;; выполнить его, если команда mix-load сработала
    (if (mix-last-result) (mix-run))
    ;; вывести содержимое регистров, если вышеприведённые
    ;; команды успешно завершили работу
    (if (mix-last-result) (mix-pall))))

Список доступных команд см. в 6.2 Интерактивные команды. Там дано описание команд mixvm, соответствующие команды Scheme используются точно так же, и поэтому мы не приводим здесь полного описания этих функций. Вместо этого мы лишь укажем те оболочки, поведение которых чем-то отличается от соответсвующих команд.

Function: mix-preg [register]
Function: mix-sreg register value
Аргумент register этих функций может быть либо строкой, либо символом, представляющим регистр. Например, следующие вызовы эквивалентны:

 
(mix-preg 'I1)
(mix-preg "I1")

Function: mix-pmem from [to]
Команда pmem принимает один аргумент -- либо номер ячейки, либо диапазон в виде FROM-TO. Функция же принимает один аргумент, если запрашивается содержимое одной ячейки памяти, и два, если запрашивается диапазон. Например, следующие команды эквивалентны:

 
MIX > pmem 10-12
0010: + 00 00 00 00 00 (0000000000)
0011: + 00 00 00 00 00 (0000000000)
0012: + 00 00 00 00 00 (0000000000)
MIX > (mix-pmem 10 12)
0010: + 00 00 00 00 00 (0000000000)
0011: + 00 00 00 00 00 (0000000000)
0012: + 00 00 00 00 00 (0000000000)
MIX >

Function: mix-sover #t|#f
Команда sover принимает в качестве аргумента либо строку T, либо строку F, чтобы установить, соответственно, триггер переполнения истинным или ложным. Соответствующая функция Scheme, mix-sover, принимает в качестве аргумента логическое значение Scheme: #t (истина) или #f.

С остальными функциями достаточно принимать в расчёт, что когда аргументами команды служат числа, соответствующая функция Scheme принимает в качестве аргументов числовые литералы Scheme. В то же время, если аргументом команды служит строка, аргументом связанной с ней функции Scheme будет строка Scheme. Например, следующие вызовы попарно эквивалентны:

 
MIX > load ../samples/hello
MIX > (mix-load "../samples/hello)

MIX > next 5
MIX > (mix-next 5)


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

8.2.2 Функции-ловушки

Ловушки -- это функции, вычисляемые перед выполнением команды mixvm (или соответствующей функции-оболочки Scheme) или после него, либо после обнаружения во время выполнения программы MIX обязательной или условной точки останова. Следующие функции позволяют устанавливать ловушки:

Function: mix-add-pre-hook command hook
Добавляет функцию в список ловушек перед командой, связанных с данной командой. command -- строка, называющая соответствующую команду mixvm, а hook -- функция, принимающая в качестве единственного аргумента строку-список аргументов команды. Следующий код Scheme определяет простую ловушку и связывает её с командой run:

 
(define run-hook
  (lambda (args)
    (display "argument list: ")
    (display args)
    (newline)))
(mix-add-pre-hook "run" run-hook)

Ловушки перед командой выполняются в порядке, в котором они были добавлены, перед вызовом соответствующей команды (или связанной с ней функции-оболочки Scheme).

Function: mix-add-post-hook command hook
Добавляет функцию в список ловушек после команды, связанных с данной командой. Аргументы имеют то же значение, что и в случае mix-add-pre-hook.

Function: mix-add-global-pre-hook hook
Function: mix-add-global-post-hook hook
Глобальные ловушки перед/после команд выполняются перед/после вызова любой команды mixvm или функции-оболочки. В этом случае hook принимает два аргумента: строку с именем вызванной команды и строку-список её аргументов.

Function: mix-add-break-hook hook
Function: mix-add-cond-break hook
Добавляет функцию-ловушку, выполняемую при обнаружении в ходе выполнения программы обязательной (соответственно, условной) точки останова. hook -- функция, принимающая два аргумента: номер строки исходного текста, откуда вызывается ловушка, и текущее значение счётчика программы. Следующий код показывает пример определения и установки ловушки останова:

 
(define break-hook
  (lambda (line address)
    (display "Breakpoint at line ") (display line)
    (display " and address ") (display address)
    (newline)))
(mix-add-break-hook break-hook)

Функции-ловушки остановов реализованы в Scheme через обычные ловушки после команды для команд next и run. Если вас это удивляет, вы можете посмотреть исходный код Scheme в файле `префикс/share/mdk/mixguile-vm-stat.scm' (где префикс соответствует корневому каталогу установки, обычно /usr или /usr/local).

См. другие примеры использования функций-ловушек в 3.4.4 Функции-ловушки.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

8.2.3 Дополнительные функции ВМ

При написании нетривиальных расширений Scheme с использованием библиотеки MIX/Scheme, вам, вероятно, будет нужно определять содержимое компонентов виртуальной машины (регистры, ячейки памяти и т.д.). Например, вам может понадобиться сохранить содержимое регистра A в переменной. Функции Scheme, описанные до сих пор, не помогут -- вы можете вывести содержимое A функцией (mix-preg 'A), но не можете присвоить значение A переменной. Для решения этой проблемы библиотека MIX/Scheme предоставляет следующие дополнительные функции:

Function: mixvm-status
Function: mix-vm-status
Возвращает текущий статус виртуальной машины в виде числа (mixvm-status) или символа (mix-vm-status). Возможные возвращаемые значения:
(mixvm-status) (mix-vm-status)
0 MIX_ERROR Ошибка загрузки или выполнения
1 MIX_BREAK Обнаружена точка останова
2 MIX_COND_BREAK Условная точка останова
3 MIX_HALTED Выполнение прервано
4 MIX_RUNNING Выполнение по next остановлено
5 MIX_LOADED Программа успешно загружена
6 MIX_EMPTY Программа не загружена

Function: mix-vm-error?
Function: mix-vm-break?
Function: mix-vm-cond-break?
Function: mix-vm-halted?
Function: mix-vm-running?
Function: mix-vm-loaded?
Function: mix-vm-empty?
Предикаты, проверяющие равенство текущего статуса виртуальной машины MIX_ERROR, MIX_BREAK и т.д.

Function: mix-reg register
Function: mix-set-reg! register value
mix-reg возвращает содержимое указанного регистра в виде числа. mix-set-reg приравнивает значение указанного регистра заданному. Регистр может быть задан либо в виде строки ("A", "X" и т.д.), либо в виде символа ('A, 'X и т.д.). Например:

 
guile> (mix-reg 'A)
2341
guile> (mix-set-reg! "A" 2000)
ok
guile> (define reg-a (mix-reg 'A))
guile> (display reg-a)
2000
guile> 

Function: mix-cell cell_no
Function: mix-set-cell! cell_no value
Возвращает и устанавливает содержимое ячейки памяти номер cell_no соответственно. И cell_no, и value -- числа Scheme.

Function: mix-loc
Возвращает значение счётчика положения (т.е. адрес следующей выполняемой инструкции).

Function: mix-over
Function: mix-set-over! #t|#f
mix-over возвращает #t, если триггер переполнения установлен, и #f в противном случае. Значение триггера переполнения может быть изменено функцией mix-set-over!.

Function: mix-cmp
Function: mix-set-cmp! 'L|'E|'G
Возвращает и устанавливает флаг сравнения соответственно. Возможные значения -- символы Scheme L (меньше), E (равно) и G (больше).

Function: mix-up-time
Возвращает текущее время работы виртуальной машины.

Function: mix-lap-time
Возвращает текущее прошедшее время виртуальной машины, т.е. время, прошедшее после последней команды run или next.

Function: mix-prog-time
Возвращает общее время выполнения загруженной в данный момент программы.

Function: mix-prog-name
Возвращает строку, содержащую базовое имя (без пути) загруженной в данный момент программы MIX.

Function: mix-prog-path
Возвращает строку, содержащую полный путь к загруженной в данный момент программе MIX.

Function: mix-src-path
Возвращает строку, содержащую полный путь к исходному файлу загруженной в данный момент программы MIX.

Function: mix-src-line [lineno]
Function: mix-src-line-no
mix-src-line-no во время выполнения программы возвращает номер текущей строки исходного кода. mix-src-line возвращает строку, содержащую строку исходного файла номер lineno, а при вызове без аргументов возвращает (mix-src-line (mix-src-line-no)).

Function: mix-ddir
Возвращает строку, содержащую полный путь к текущему каталогу устройств.


[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated on June, 9 2003 using texi2html