ProolScript — Прулепедия

ProolScript

Материал из Прулепедии
Перейти к: навигация, поиск

Язык программирования ProolSkript для ОС Proolix

Название языка: английское ProolSkript (именно в таком написании, с буквой K) русское Прульскрипт

Статус проекта: язык реализован как основной язык скриптов для ОС Proolix. Также собран интерпретатор языка в виде консольного приложения Linux. (Еще не собрано, но должно собраться без проблем в Windows/cygwin)

Язык интерпретируемый (то есть я пока написал интерпретатор и всё), стековый, типа сильно усеченного языка Форт (Forth)

Размер стека фиксирован и составляет MAXSTACK (пока это 10 8-байтных ячеек).

Написанный интерпретатор может интерпретировать программу из файла или из стандартного ввода (естественно, при интерактивной интепретации не все операторы допустимы)

Целью создания языка было быстро и легко сделать для моей операционной системы Proolix свой функционально полный язык. Именно потому, что я поставил своей целью сделать как можно быстрее и как можно проще, я сделал на первых порах только интерпретатор, притом языка с простейшим синтаксисом (в качестве кандидатов я рассматривал Forth и LISP)

Допускается размещение как одного оператора в строке, так и нескольких (как и в Forth):

То есть возможны как конструкции типа

1 2 + .

допустимые в Форте, так и

1

2

+

.

тоже допустимые в Форте.

Строка, начинающаяся с # является комментарием и игнорируется интерпретатором (пробел после диеза не обязателен, в отличие от Форта)

Операторы

Строка, начинающаяся с символа ! является оператором вывода строки на консоль. Выводится строка, непосредственно идущая после восклицательного знака. После вывода строки перевод строки не осуществляется. Для перевода строки используется оператор newline

Цифровая константа, расположенная в отдельной строке, помещается на вершину стека (как в Форте). Допустимы десятичные или 16-ричные константы. Оператор dec переводит и ввод и вывод в десятичный режим (вначале по умолчанию установлен десятичный режим)

Кстати, операторы регистрозависимы и пишутся строчными (маленькими) буквами

Оператор hex переводит систему в 16-ричный режим (16-ричные константы должны начинаться с десятичной цифры, например с нуля. То есть константа FFF0 является некорректной, а 0FFF0 корректной)

Оператор mode выводит на консоль сообщение, какой режим включен

Оператор inputstring вводит строку с консоли во внутренний буфер строки. (Концом ввода строки считается нажатая клавиша Enter)

Оператор outputstring выводит строку из внутреннего буфера на консоль

Оператор push помещает на вершину стека цифровую интерпретацию строки из буфера (то есть интерпретацию, как в сишной функции atoi)

Операторы swap, dup, drop делают то же самое, что и в Форте

Арифметические операторы + - / * % делают то же самое, что и в Форте (оператор % вычисляет остаток от деления. Вообще, знаки операций я взял из C)

Оператор . (точка) делает то же самое, что и в Форте, то есть выводит значение с вершины стека, удаляя его

Оператор .b выводит значение младшего байта слова, расположенного на вершине стека, удаляя его

Операторы обращения к ОЗУ

peek берет 8-байтный адрес с вершины стека, а вместо этого помещает на вершину стека 4-байтное значение, находящееся в ОЗУ по этому адресу

peek2 берет из стека два числа - сегмент и смещение (числа рассматриваются как 4 байтные, то есть старшая часть игнорируется) и возвращает на вершину стека 4-байтную величину, находящуются по этому адресу

Операторы ветвления

Оператор label

Оператор берет с вершины стека число (затем удаляя его), которое рассматривается как номер метки. В таблице меток под этим номером запоминается текущее место программы. (Таблица меток имеет фиксированный размер MAXLABEL, пока это 10) Оператор бессмысленно использовать в интерактивном режиме. Перед оператором обычно ставится константа, однако это не обязательно. (Для чего в операторе label может использоваться не контстанта, а результат неких вычислений, я еще не придумал. Возможно, в этом смысла нет)

Оператор безусловного перехода goto

Оператор берет с вершины стека число (затем удаляя его), которое рассматривается как номер метки. И переходит на эту метку. (Если такой метки нет, происходит переход на следующий оператор, при этом выдается сообщение об ошибке)

Оператор условного перехода ifgoto

Оператор берет с вершины стека число (затем удаляя его из стека). Если число не равно нулю, из стека берется номер метки, на который происходит переход. (Если число равно нулю, переход не происходит, но число-номер метки из стека удаляется в любом случае)

Оператор организации цикла loop

Конечно, цикл можно организовать при помощт ifgoto, но оператор loop облегчает эту работу. Отчасти он похож на команду LOOP процессоров Intel.

Оператор loop извлекает из стека два параметра - номер метки и счетчик цикла. Значение счетчика цикла уменьшается на 1 и если полученное значение не равно нулю, оно помещается на вершину стека и происходит переход на метку. А если полученное значение равно нулю, происходит переход в следующему оператору (и на вершину стека ничего не помещается)

Таким образом цикл на языке Прульскрипт организовывается примерно так

! aaa

! помещаем в стек число повторений

10

! это метка возврата

1

label

! здесь тело цикла

! ...

! ...

! а это конец цикла и оператор loop с номером метки возврата (обратите внимание, что в данный момент на вершине стека лежит счетчик цикла)

1

loop

! сюда мы вышли по окончании цикла

! bbb

Состояние стека в строках, помеченных как aaa и bbb одинаковое. Тело цикла должно быть написано так, чтобы не менять состояние стека, в частности, не портить лежащий на вершине стека счетчик повторений

Операторы сравнения

== != < > <= >=

Берут из стека два параметра, производят сравнение и возвращают в стек величину 1 или 0 в зависимости от истинности или неистинности сравнения (написание операторов взято из языка С)

quit - выход из интерактивного режима или выход из режима интерпретации файла. (По концу файла с текстом скрипта выход происходит и так и писать в конце quit не обязательно)

Всё! Больше ничего нет. Определения новых слов, как в Форте, пока нет

Примеры

1. Ввод двух чисел и вывод их суммы

# summa skript

!Enter A

inputstring

newline

push

!Enter B

inputstring

newline

push

+

!Summa =

.

newline


2. Вывод 22 первых векторов прерываний

# loop

22

1

label

!Interrupt

dup

22

swap

-

hex

#begin vectorskript

dup

.b

!

4

*

dup

2

+

0

swap

peek2

.

!:

0

swap

peek2

.

!

#end

newline

1

loop

!press any key

inputstring

Личные инструменты
Пространства имён
Варианты
Действия
Навигация
Инструменты