9. Создание интерактивных программ.

Язык MACS позволяет использовать переменные, операции ввода-вывода и многооконный текстовый интерфейс. В языке существует 2 вида переменных: целочисленные и строковые. Целочисленные представляют из себя 32-битное целое двоичные числа, которые можно представлять в программе в различных системах счисления как со знаком "-", так и без знака. В десятичной системе это числа в диапазоне от -2147483648 до 2147483647. В беззнаковой шестнацатеричной - от 0 до FFFFFFFF (4294967295). Строковые переменные могут содержать строки переменной длины от 0 до 32767 символов в кодировке cp866 (DOS/OEM).

9.1. Использование числовых переменных.

Числовые переменные могут быть заданы в программе как десятичные, двоичные и шестнадцатеричные, причём двоичные и шестнадцатеричные числа считаются беззнаковыми. Для записи двоичного числа используется префикс 0b, для шестнадцатеричных - 0h или 0x, например, 0b101010100 для двоичного, 0x38D3F2B7 или 0h38D3F2B7 для шестнадцатеричного.
Операция задания переменной выглядит как def <имя>, где имя - текстовая строка без пробелов, которая может содержать буквы и цифры, при этом первый символ цифрой быть не может. Регистр символов значения не имеет, то есть переменный с именами Var, var и VAR считаются одной переменной. Язык позволяет перечислить несколько переменных через запятую, а также установить начальное значение переменной оператором "=". По умолчанию начальное значение при первом объявлении переменной равно 0. Переменная, объявленная, как число, не может быть повторно объявлена, как строка.

def a,b,c          // объявление трёх переменных
def d=10           // инициализация значения переменной
def e,f=9,g,h=0x1A // объявление четырёх переменных и инициализация двух из них

Кроме того, числовые переменные могут быть объявлены повторно, при этом их значение не изменяется, если не используется оператор "=" для установки начального значения:

def var=5 // переменная var получила значение 5
def var   // переменная объявлена повторно, значение осталось равно 5
def var=7 // переменная объявлена повторно, значение изменилось на 7

В операциях инициализации также допустимо использовать арифметические выражения, в том числе с использованием объявленных ранее переменных:

def a=3,b=4,c=5,d=6
def var=a*2+c*(d+5)  // переменная var объявлена и получила вычисленное значение 61

Числовые переменные поддерживают следующий набор операций:
Приоритет операций описан в главе 1.2. руководства по инструментальной системе MACS.

9.2. Использование строковых переменных.

Строковые переменные задаются в программе в виде строки, заключённой в двойные кавычки ( " ) - далее также мы будем называть литералом. При этом, для того, чтобы задать в строке сам символ двойных кавычек, нужно поставить перед символом кавычек символ экранирования ( \ ) - \" . Для того, чтобы задать в строке сам символ экранирования, его нужно продублировать.
Операция задания переменной выглядит как string <имя>, где имя, как и у числовой переменной, - текстовая строка без пробелов, которая может содержать буквы и цифры, при этом первый символ цифрой быть не может. Регистр символов значения не имеет, то есть переменный с именами Var, var и VAR считаются одной переменной. Язык позволяет перечислить несколько переменных через запятую, а также установить начальное значение переменной оператором "=". По умолчанию начальное значение при первом объявлении переменной - пустая строка. Переменная, объявленная, как строка, не может быть повторно объявлена, как число.

string a,b,c                          // объявление трёх переменных
string d=10                           // инициализация значения переменной
string e,f="тест",g,h="ещё один тест" // объявление четырёх переменных и инициализация двух из них

string str="тест с кавычкой - \" и символом экранирования - \\"
// переменная str инициализирована строкой:
тест с кавычкой - " и символом экранирования - \

Кроме того, строковые переменные, как и числовые, могут быть объявлены повторно, при этом их значение не изменяется, если не используется оператор "=" для установки начального значения:

string var="test"        // переменная var получила значение "test"
string var               // переменная объявлена повторно, значение осталось равно "test"
string var="sample text" // переменная объявлена повторно, значение изменилось на "sample text"

В операциях инициализации также допустимо использовать строковые выражения, в том числе с использованием объявленных ранее переменных:

string a="sample",b=" ",c="text"
string var=a+b+c  // переменная var объявлена и получила значение "sample text"

Строки задаются в кодировке cp866 (DOS/OEM), допустимы любые печатные символы из этой кодировки. При помощи символа экранирования ( \ ) можно задать несколько специальных символов:
Строковые переменные поддерживают следующий набор операций:

9.3. Преобразование типов.

Строковые переменные могут быть преобразованы в числовые и обратно при помощи оператора присваивания. При этом слева от знака "=" может стоять только одна переменная числового или символьного типа. Преобразование также может проиходить неявно при использовании в выражениях смешанных типов данных. Для подобных преобразований существуют следующие правила:
Логические выражения вычисляются, сводясь к числовым со значениями "ноль / не ноль". То есть, числовое значение нуля считается ложным, число, отличное от нуля - истинным. Использование в логических выражениях строковых переменных иначе, кроме как в операциях сравнения ( "==" и "!=" ), не рекомендуется, во избежание неоднозначности интерпретации. Операции отношения ( ">", "<=", "==" и т.д.) преобразуется к целочисленному значению, равному 0, если условие не выполняется, и к значению отличному от 0, если условие выполняется.

9.4. Организация ввода-вывода.

Вывод значений числовых и символьных переменных, а также литералов производится при интерпретации имени переменной, или литерала, если переменная или литерал не участвует в арифметических или логических операциях или в других конструкциях языка:

def num=16
string str="test"
num                //вывести значение переменной num: 16
str                //вывести значение переменной str: test
"тест"             //вывести строку 'тест'

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

def var=5259
var          // десятичное значение: 5259
var(16)      // шестнадцатеричное значение 148B
var(16,8)    // шестнадцатеричное значение 0000148B

Для ввода числа используется оператор "?". Для численных переменных можно в скобках указать систему счисления.

def num,hex
string str
?num        // ввод десятичного числа
?hex(16)    // ввод шестнацатеричного числа
?str        // ввод строки

При выполнении операции ввода в текущей позиции вывода появляется курсор и вводится число или строка в одной строке. При несовпадении формата (например, недопустимые символы в числе) будет выведено сообщение об ошибке и попытка воода повторится. После завершения ввода курсор возвращается в исходное состояние (содержимое экрана, заполненное при вводе, не восстанавливается).

9.5. Управление вычислительным процессом.

Для управления вычислительном процессом в языке MACS, как и в большинстве других языков, предусмотрены условные и циклические операторы, а также команды перехода и завершения программы.

9.5.1. Условные операторы.

В языке MACS существует два условных оператора - if и ifs. Первый - классический оператор условного выполнения, второй - упрощённый. Оператор if в случае выполнения условия, указанного после ключевого слова if, выполняет программу в промежутке от if до else, либо от if до endif, если в конструкции оператор else отсутствует. В случае невыполнения условия он выполняет программу в промежутке от else до endif.
Пример использования оператора if:

def x=1, y=2
def z
if ((x==1)&&(y==2))        // проверка условия: x должно быть равно 1, а y равен 2 (логическое условие "И")
    "Условие выполнено"    // если условие выполнилось, будет выведена эта строка
    z=1                    // и переменной z будет присвоено значение 1
else                       // иначе
    "Условие не выполнено" // если условие выполнилось, будет выведена эта строка
    z=2                    // и переменной z будет присвоено значение 2
endif                      // окончание оператора if

Если в случае невыполнения оператора ничего делать не требуется, условие else можно пропустить:

def x=1, y=2
def z
if ((x==1)&&(y==2))
    "Условие выполнено"
    z=1
endif

Для проведения нескольких проверок условные операторы можно вкладывать друг в друга:

def x=1
if (x==1)
    "x равно 1"
else
    if (x==2)

        "x равно 2"
    else
        "x равно чему-то ещё"
    endif
endif

В отличие от оператора if, оператор ifs выполняет только один оператор, следующий сразу за условием.
Пример использования оператора ifs:

def x=1
ifs (x==1) "Условие выполнено. "
ifs (x!=1) "Условие не выполнено. " "Проверка окончена."

В результате выполнения будут выведена строка "Условие выполнено. Проверка окончена.", так как во второй строке вывод литерала "Проверка окончена." уже не относится к оператору ifs.

9.5.2. Организация циклов.

Для организации циклов в языке MACS существуют операторы for, while и until.
Блок условий для оператора for состоит из трёх частей - инициализации переменных, проверки условия и управляющих операций, выполняемых после цикла. Эти части разделяются запятыми, блок условий завершается ключевым словом do, любые из условий являются необязательными. Оператор выполняет циклически фрагмент программы, заключённый между ключевыми словами do и done. Возможно также использование операторов continue и break. Оператор continue продолжает выполнение фрагмента программы с начала в новом проходе цикла, операторы следующие далее за continue до ключевым словом done не выполняются. Оператор break прерывает выполнение цикла и продолжает выполнение программы уже после ключевого слово done.
Пример использования:

def x,y=1
for x=10, (x<20)&&(y<10), x=x+1 y=y+1 do
    "x=" x
    ", y=" y
    "\r\n"
done
pause


В этом примере оператор x=10 выполняется один раз перед первым входом в цикл, далее перед каждым входом в цикл выполняется проверка условия (x<20)&&(y<10), а в конце каждого цикла выполняются операторы x=x+1 и y=y+1. Внутри цикла выводятся значения x и y.
В качестве начального условия можно использовать несколько операторов:

def x,y
for x=10 y=1, (x<20)&&(y<10), x=x+1 y=y+1 do
    "x=" x ", y=" y "\r\n"
done
pause

В случае, если для начального условия используется оператор def, разделяющая запятая может быть расценена им как перечисление переменных (def, a,b). Для таких случаев первую запятую можно заменить ключевым словом to:

def y=1
for def x=10 to (x<20)&&(y<10), x=x+1 y=y+1 do
    "x=" x ", y=" y "\r\n"
done
pause

Использование def в циклах, находящихся внутри условных операторов или операторов циклов, которые могут не выполняться из-за начальных условий, не рекомендуется, так как в этом случае интерпретатор будет "просматривать" фрагмент программы, который не выполняется и проверять синтаксис с учётом уже объявленных переменных. А так как фрагмент не выполняется, переменная не будет объявлена, интерпретатор не сможет найти её в списке, и, как следствие, выдаст ошибку. Следующий фрагмент будет выполняться без ошибки только если переменная run не будет равна 0:

def run=0
if (run!=0)
    def y=1
    for def x=10 to (x<20)&&(y<10), x=x+1 y=y+1 do
        "x=" x ", y=" y "\r\n"
    done
endif
pause

Начальное условие можно пропустить как необязательный параметр:

def x=10,y=1
for ,(x<20)&&(y<10), x=x+1 y=y+1 do
    "x=" x ", y=" y "\r\n"
done
pause

Второй оператор - проверку условия выполнения тоже можно пропустить, но в этом случае нужно предусмотреть альтернативный способ выхода из цикла (например, используя break), иначе цикл станет бесконечным и остановить его можно будет только нажатием клавиши F2 (прервать выполнение программы):

def x=10,y=1
for ,, x=x+1 y=y+1 do
    ifs !((x<20)&&(y<10)) break
    "x=" x ", y=" y "\r\n"
done
pause

Последний оператор тоже можно пропустить, выполняя все операции по изменению управляющих переменных внутри цикла:

def x=10,y=1
for ,, do
    ifs !((x<20)&&(y<10)) break
    "x=" x ", y=" y "\r\n"
    x=x+1
    y=y+1
done
pause

Однако, при этом нужно помнить, изменение этих переменных может быть отменено использованием continue и выполнени цикла может пройти неправильно. Пример - пропустим вывод x, равного 15:

def x=10,y=1
for ,, x=x+1 y=y+1 do
    ifs !((x<20)&&(y<10)) break
    ifs (x==15) continue // если x равно 15, продолжаем с начала цикла
    "x=" x ", y=" y "\r\n"
done
pause

Если изменить программу так, как в предыдущем случае, после вывода числа 14 программа перейдёт в бесконечный цикл проверки x, расного 15, выйти из которого можно только по нажатию клавиши F2 (прервать выполнение программы).

def x=10,y=1
for ,, do
    ifs !((x<20)&&(y<10)) break
    ifs (x==15) continue
    "x=" x ", y=" y "\r\n"
    x=x+1
    y=y+1
done
pause

Оператор while представляет собой оператор цикла с проверкой условия, но без блоков инициализации и изменения переменных. После ключевого слова while указывается условие, а внутри цикла выполняется всё, что следует до ключевого слова done. В этом цикле также можно использовать операторы break и continue. Наличие проверки условия обязательно. Для организации бесконечного цикла с выходом по break можно указать в условии 1. Будучи преобразованным в логическое условие, число 1 будет считаться истинным логическим значением, как это описано выше в главе 9.3 (Преобразование типов).
Пример:

def x=10,y=1
while (x<20)&&(y<10)
    "x=" x ", y=" y "\r\n"
    x=x+1
    y=y+1
done
pause

Пример с break, continue и всегда истинным условием:

def x=10,y=1
while 1
    ifs !((x<20)&&(y<10)) break
    if (x==15)
        x=x+1
        y=y+1
        continue
    endif
    "x=" x ", y=" y "\r\n"
    x=x+1
    y=y+1
done
pause

Оператор until отличается от while и for тем, что условие выполнения проверяется после завершения каждого цикла, поэтому цикл всегда выполняется хотя бы один раз. Цикл начинается ключевым словом until и завершается ключевым словом done, после которого задаётся условие выполнения. В этом цикле также можно использовать операторы break и continue.
Пример:

def x=10,y=1
until
    "x=" x ", y=" y "\r\n"
    x=x+1
    y=y+1
done (x<20)&&(y<10)
pause

9.5.3. Команды перехода и завершения программы.

Для завершения программы используется одно из ключевых слов - exit или end. При интерпретации такого ключевого слова выполнение программы прекращается. Существует также конструкция "конец программы". Эта конструкция - "end." (с точкой после end!). Такое ключевое слово считается концом программы, за которым может находиться всё, что угодно - после этого слова не происходит ни выполнение программы, ни поиск меток. Это может использоваться для добавления в файл программы какой-либо документации без необходимости оформлять её как комментарий. Применение такой конструкции в условнх операторах не допускается, так как она обрывает действие условного оператора.

Для безусловного перехода используется оператор goto и метки. Метка представляет из себя такой же набор символов, как имя переменной и заканчивается двоеточием. Пример использования оператора и меток:

"Step 1\r\n"   // вывод строки
goto step2     // переход к метке step2
"No step"      // этот фрагмент не будет выполнен
step3:         // метка step3
"Step 3\r\n"
goto step4
"No step"
step2:         // метка step2
"Step 2\r\n"
goto step3
"No step"
step4:
"Step 4\r\n"

Использование оператора goto в программах не поощряется, так как в его работе есть некоторые ограничения, которые могут вызвать проблемы при последующем усложнении программ. В частности, переход из конструкции if или из цикла заставляет интерпретатор считать, что конструкция не закрыта (например отсутствует endif или done, или даже их набор), что приводит ошибки выполнения и заставляет использовать отсутствующие закрывающие конструкции в точке перехода, что усложняет чтение программы и мешает её отладке и изменению.
Пример - вывод чисел от 0 до 5, пропуская число 5:

def x=0
until
    for ,x<10,x=x+1 do
            if (x==5)
                goto last
            endif
        "x=" x "\r\n"
    done
last:
done (x<10)
"Done."
pause
exit

Такой пример выглядит правильным, однако вызывает ошибки. Для коррекции ошибок его придётся изменить следующим образом.

def x=0
until
    for ,x<10,x=x+1 do
            if (x==5)
                goto last
            endif
        "x=" x "\r\n"
    done
    goto last2
last:
endif
last2:
done (x<10)
"Done."
pause
exit

Такой пример ошибок уже не вызывает, но уже не выглядит правильным. Поэтому использованием goto злоупотреблять не стоит.

Метки также могут быть использованы как точки входа в подпрограмму. Переход к подпрограмме производится при интерпретации имени метки. Возврат к исходной точке вызова подпрограммы будет осуществлён после интерпретации ключевого слова return.
Пример:

"Step 1"
step2         // вызов подпрограммы с меткой step2
"Step 3"
pause
exit          // выход из программы

step2:        // метка - точка входа в подпрограмму
"Step 2"
return        // возврат из подпрограммы в точку вызова

9.5.4. Обзор приёмов управления вычислительным процессом.

Итак, суммируя всё описанное, для построения логики работы программы существует следующий набор операторов:

9.6. Усовершенствование пользовательского интерфейса.

Интерфейс консоли не ограничивается простым выводом символов на экран, язык MACS содержит специальные функции для работы с оконным интерфейсом, организацией меню и усовершенствованным порядком вывода текстовой информации на экран.
По умолчанию, в начале программы текстовый вывод производится жёлтым цветом на синем фоне. Для изменения текста и фона существует функция color. Эта функция получает два параметра - текст текста и цвет фона. Любой из этих параметров можно пропустить, чтобы не изменять соответствующий цвет.
В таблице приведено соответствие цветов текста и фона указанным значениям:

Значение
 Текст
Фон
0 чёрный   чёрный  
1 тёмно-синий   тёмно-синий  
2 зелёный   зелёный  
3 тёмно-бирюзовый   тёмно-бирюзовый  
4 тёмно-красный   тёмно-красный  
5 пурпурный   пурпурный  
6 оливковый   оливковый  
7 светло-серый   светло-серый  
8 серый   мигающий чёрный  
9 синий   мигающий тёмно-синий  
10 зелёный   мигающий зелёный  
11 бирюзовый   мигающий тёмно-бирюзовый  
12 красный   мигающий тёмно-красный  
13 малиновый   мигающий пурпурный  
14 жёлтый   мигающий оливковый  
15 белый   мигающий светло-серый  

Пример использовния:

"Цвет по умолчанию\r\n"
color(11)
"Бирюзовый текст\r\n"
color(10,0)
"Зелёный текст на чёрном фоне\r\n"
color(,3)
"Тёмно-бирюзовый фон\r\n"
color(11,11)
"Бирюзовый текст на мигающем тёмно-бирюзовом фоне"
pause

Результат работы программы:

 F2 - завеpшить интеpпpетацию   F10 - pежим CONSOLE   Key - пpодолжить          
Цвет по умолчанию                                                               
Бирюзовый текст                                                                 
Зелёный текст на чёрном фоне                                                    
Тёмно-бирюзовый фон                                                             
Бирюзовый текст на мигающем тёмно-бирюзовом фоне                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
 ────────────────────────────────────────────────────────────────────────────── 
                                                                                
                                                                  Mem - 1967568k

Перемещение курсора по экрану можно производить не только при помощи управляющих символов, но и при помощи функции gotoxy или goxy: обе функции принимают два параметра - координаты внутри текущего окна вывода по горизонтали и по вертикали. Любой из параметров можно пропустить, чтобы оставить его равным текущему значению.
Пример использования:

goxy(10,5)
"10:5"
goxy(15,6)
"15:6"
goxy(,8)
":8"
goxy(30)
"30:"
goxy(1,1)
"1:1"
pause

Результат работы программы:

 F2 - завеpшить интеpпpетацию   F10 - pежим CONSOLE   Key - пpодолжить          
1:1                                                                             
                                                                                
                                                                                
                                                                                
         10:5                                                                   
              15:6                                                              
                                                                                
                  :8         30:                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
 ────────────────────────────────────────────────────────────────────────────── 
                                                                                
                                                                  Mem - 1964324k

Для очистки текущего окна вывода можно воспользоваться выводаом символа "\f", либо воспользоваться функцией cls. Без параметров она работает так же, как и вывод "\f", но может принимать в качестве параметра число или строку. Если передаётся число, функция заполняет экран символом с ASCII-кодом, равным этому числу. Если указана строка - заполнение происходит этой строкой.
Примеры использования:

Результат отработки команды cls(177):
 F2 - завеpшить интеpпpетацию   F10 - pежим CONSOLE   Key - пpодолжить          
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
 ────────────────────────────────────────────────────────────────────────────── 
                                                                                
                                                                  Mem - 1964212k

Результат отработки команды cls(" -=-"):

 F2 - завеpшить интеpпpетацию   F10 - pежим CONSOLE   Key - пpодолжить          
 -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=-
 -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=-
 -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=-
 -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=-
 -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=-
 -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=-
 -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=-
 -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=-
 -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=-
 -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=-
 -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=-
 -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=-
 -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=-
 -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=-
 -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=-
 -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=-
 -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=-
 -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=-
 -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=-
 -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=-
 -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=- -=-
 ────────────────────────────────────────────────────────────────────────────── 
                                                                                
                                                                  Mem - 1964160k

Для изменения размера и положения текущего окна вывода существуют команды window и screen. Обе получают по пять параметров, любые из которых могут быть пропущены для установки значения параметра по умолчанию (1, 2, 80 и 22 соотвественно).
Первые четыре параматра - координаты верхнего и нижнего углов окна, сначала по горизонтали, потом по вертикали: x1, y1, x2, y2, где x1:y1 - координата левого верхнего угла, а x2:y2 - координата нижнего правого угла. Последний параметр (0 или 1) - логическое значение. Если оно принимает истинное значение, содержимое окна после создания очищается, если ложное - нет. По умолчанию содержимое окна стирается. Оператор close "закрывает" текущее окно и возвращается к предыдущему рабочему окну, восстанавливая координаты курсора, установленные перед открытием окна. Отличие screen от window заключается в том, что screen восстанавливает содержимое экрана, находившееся на месте открытого окна, а window - нет. Координаты окон задаются в абсолютных координатах консоли, принимающих значение от 1 до 80 по горизонтали, и от 1 до 25 по вертикали. по умолчанию программе предоставляется окно с координатами (1,2,80,22). Координаты окна определют внешний размер окна, внутренний размер зависит от типа окна - с рамкой или без рамки. окно с рамкой получит рамку внутри указанной области и область вывода будет уменьшена за счёт рамки на 2 символа по вертикали и горизонтали. Типа окна по умолчанию - с одинарной рамкой и может быть изменён командой type. Команда type принимает три параметра, любой из которых может быть пропущен. Первый параметр - тип рамки: 0 - без рамки, 1 - одинарная, 2- двойная. Если добавить к этому значению 8, рамка будет прорисована с тенью. Тень прорисовывается снаружи окна и не влияет на внутренний размер области вывода. Второй параметр - цвет рамки, третий - цвет фона окна, если пятый параметр window или screen не установлен в 0.
Примеры использования окон:

window(1,3,20,10)       // тип окна по умолчанию
"window(1,3,20,10)"

type(2)                 // двойная рамка
window(25,3,45,10)
"type(2)\r\n"
"window(25,3,45,10)"

type(0,0,3)
window(50,3,70,10)
"type(0,10,3)\r\n"
"window(50,3,70,10)"

type(10,10)             // двойная рамка с тенью
window(1,12,20,20)
"type(10,10)\r\n"
"window(1,12,20,20)"

type(8,11,2)
screen(25,12,45,22)
"type(8,11,2)\r\n"
"screen(25,12,45,22)"

type(9,15,7)
screen(35,15,75,20,0)   // не стирать фон
"type(9)\r\n"
"screen(35,15,55,18,0)"

pause

Результат работы программы:

 F2 - завеpшить интеpпpетацию   F10 - pежим CONSOLE   Key - пpодолжить          
                                                                                
┌──────────────────┐    ╔═══════════════════╗    type(0,10,3)                   
window(1,3,20,10) │    ║type(2)            ║    window(50,3,70,10)             
│                  │    ║window(25,3,45,10) ║                                   
│                  │    ║                   ║                                   
│                  │    ║                   ║                                   
│                  │    ║                   ║                                   
│                  │    ║                   ║                                   
└──────────────────┘    ╚═══════════════════╝                                   
                                                                                
╔══════════════════╗    type(8,11,2)                                            
type(10,10)       ║    screen(25,12,45,22)                                     
window(1,12,20,20)                                                            
║                  ║              ┌───────────────────────────────────────┐     
║                  ║              type(9)                                     
║                  ║              screen(35,15,55,18,0)                       
║                  ║                                                          
║                  ║                                                          
╚══════════════════╝              └───────────────────────────────────────┘     
                                                                                
                                                                                
 ────────────────────────────────────────────────────────────────────────────── 
                                                                                
                                                                  Mem - 1963492k

Работу оператора close можно понаблюдать, создав несколько разных окон и последовательно закрыв их, перемежая операторы close операторами pause:

window(1,3,20,10)
type(2)
screen(25,3,45,10)
type(0,0,3)
window(50,3,70,10)
type(10,10)
screen(1,12,20,20)
type(8,11,2)
window(25,12,45,22)
type(9,15,7)
screen(35,15,75,20,0)
pause
close pause
close pause
close pause
close pause
close pause
close pause

Экран во время отработки первой pause:

 F2 - завеpшить интеpпpетацию   F10 - pежим CONSOLE   Key - пpодолжить          
                                                                                
┌──────────────────┐    ╔═══════════════════╗                                   
│                  │    ║                   ║                                   
│                  │    ║                   ║                                   
│                  │    ║                   ║                                   
│                  │    ║                   ║                                   
│                  │    ║                   ║                                   
│                  │    ║                   ║                                   
└──────────────────┘    ╚═══════════════════╝                                   
                                                                                
╔══════════════════╗                                                            
║                  ║                                                            
║                  ║                                                            
║                  ║              ┌───────────────────────────────────────┐     
║                  ║                                                          
║                  ║                                                          
║                  ║                                                          
║                  ║                                                          
╚══════════════════╝              └───────────────────────────────────────┘     
                                                                                
                                                                                
 ────────────────────────────────────────────────────────────────────────────── 
                                                                                
                                                                  Mem - 1963348k

Экран после отработки шести pause:

 F2 - завеpшить интеpпpетацию   F10 - pежим CONSOLE   Key - пpодолжить          
                                                                                
┌──────────────────┐                                                            
│                  │                                                            
│                  │                                                            
│                  │                                                            
│                  │                                                            
│                  │                                                            
│                  │                                                            
└──────────────────┘                                                            
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
 ────────────────────────────────────────────────────────────────────────────── 
                                                                                
                                                                  Mem - 1963316k

9.7. Использование меню выбора.

Для интерактивных программ характерно использование иерархических меню выбора параметров или режимов работы. В языке MACS оператор для создания меню встроен изначально. Конструкция для создания меню выглядит следущим образом:

frame (атрибут цвета)
case "  ~Выбор 1~  " <набор операторов> continue
case "  ~Выбор 2~  " <набор операторов> continue
case "  ~Выбор 3~  " <набор операторов> continue
...
case "  ~Выход~  " <набор операторов> break
endf

В этой конструкции атрибут цвета - восьмибитное число, в котором старишие 4 бита - цвет фона, младшие - цвет подсвечиваемого фрагмента текста для выбранного пункта меню. Если атрибут не указан, цвет текста устанавливается ярко-зелёным. После ключевого слова case указывается текст, выводимый в пункте меню. Между символами "~" находится фрагмент текста, который будет подсвечиваться при выборе. Если символов "~" в тексте нет вообще, подсвечивается вся строка. Ключевое слово continue означает, что после выполнения набора операторов меню оператор продолжит работу и позволит выбрать дургой пункт. Ключевое слово break означает, что после выполнения набора операторов работа меню прекратится и программа продолжит выполнение. Оператор break не обязательно должен быть одним в конструкции и не обязан быть последним пунктом.
Пример использования оператора:

def menu=0
color(15)
frame(0b01110000)
case "Пункт ~№1~\r\n" menu=1 show continue
case "Пункт ~№2~\r\n" menu=2 show continue
case "Пункт ~№3~\r\n" menu=3 show continue
case "Пункт ~№4~\r\n" menu=4 show continue
case "Пункт ~№5~\r\n" menu=5 show continue
case "~ Выход  ~" break
endf

exit

show:
type(10,15,7)
screen(31,11,49,13)
" Выбран пункт №" menu
pause
close
return

Результат работы программы:

 F2 - завеpшить интеpпpетацию   F10 - pежим CONSOLE   Key - пpодолжить          
Пункт №1                                                                        
Пункт №2                                                                        
Пункт №3                                                                       
Пункт №4                                                                        
Пункт №5                                                                        
 Выход                                                                          
                                                                                
                                                                                
                                                                                
                              ╔═════════════════╗                               
                              ║ Выбран пункт №3 ║                               
                              ╚═════════════════╝                               
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
 ────────────────────────────────────────────────────────────────────────────── 
                                                                                
                                                                  Mem - 1962180k

Меню обычно используют внутри окна, например, так:

def menu=0
color(15,7)
type(10,15,7)
screen(5,4,16,11)
frame(0b01110000)
case " Пункт ~№1~\r\n" menu=1 show continue
case " Пункт ~№2~\r\n" menu=2 show continue
case " Пункт ~№3~\r\n" menu=3 show continue
case " Пункт ~№4~\r\n" menu=4 show continue
case " Пункт ~№5~\r\n" menu=5 show continue
case " ~ Выход  ~" break
endf
close

exit

show:
type(10,15,7)
screen(31,11,49,13)
" Выбран пункт №" menu
pause
close
return

Результат работы программы:

 F2 - завеpшить интеpпpетацию   F10 - pежим CONSOLE   Key - пpодолжить          
                                                                                
                                                                                
    ╔══════════╗                                                                
    ║ Пункт №1 ║                                                                
    ║ Пункт №2 ║                                                                
    ║ Пункт №3 ║                                                                
    ║ Пункт №4                                                                 
    ║ Пункт №5 ║                                                                
    ║  Выход   ║                                                                
    ╚══════════╝              ╔═════════════════╗                               
                              ║ Выбран пункт №4 ║                               
                              ╚═════════════════╝                               
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
 ────────────────────────────────────────────────────────────────────────────── 
                                                                                
                                                                  Mem - 1962084k

9.8. Консольный режим.

Консольный режим запускается командой cons без параметров. Он также может быть запущен в режиме ожидания при работе команды pause - для этого во время паузы нужно нажать F10 (это написано в вехней строке подсказки). Консольный режим прерывает выполнение программы и переводит интерпретатор в режим отработки команд, введённых с клавиатуры. По сути это похоже на вызов подпрограммы, только текст подпрограммы вводится с командой строки консоли. В этом режиме можно контролировать значения переменных, изменять настройки стенда или канальные настройки, можно также запустить режим логического анализатора при помощи кнопки щупа, либо перевести  щуп в режим вольтметра (команда vm). Такой режим полезен и при разработке и отладке программы и при поиске неисправности на плате.

9.9. Прочие операторы для работы с интерфейсом.

В число ещё не описаных операторов для работы с интерфейсом входят операторы delay и sound. Оператор delay задерживает выполнение программы на количество миллисекунд, указанное ему как параметр. Указывать число меньшее 20 не имеет смысла, так как минимальное значение задержки равно примерно 10-30 мс. Оператор sound подаёт на системный динамик сигнал и получает два необязательных параметра - частоту звука и его продолжительность в миллисекундах. Выполнение программы приостанавливается на время подачи сигнала.