Правила программирования расчетов
Текст конкретной программы начинается с пустой строки (для первой программы необязательно) и заканчивается пустой строкой. В тексте программы могут быть комментарии, которые пишутся обычным образом без знаков разметки. Однако операторы программы отмечаются так, что первым знаком, указывающим на оператор является символ #. Если нужно проводить вычисления, то после него ставится символ пробела и затем проводятся вычисления. Кроме того, программа понимает операторы простого цикла #rep и цикла по условию #case . О них будет сказано позднее. Программа может оперировать с переменными, имена которых состоят из одной буквы латинского алфавита. то есть a-z и A-Z. Большие и маленькие буквы означают разные переменные. Всего 52 переменных. Дополнительно переменные могут иметь имена, состоящие из одной буквы и одной цифры, то есть m1, N2 и так далее. Всего таких переменных 520. Также можно использовать элементы реального массива r(n), индекс массива может принимать значения от 1 до 19999. Индекс массива может содержать выражения, состоящие из чисел и переменных.
Все расчеты представляют собой совокупность операторов присваивания. Например,
# a=1; b=sin(a); c=b<2; r(5000)=a*b;
То есть два знака [# ] (пробел после решетки обязателен) открывает поле операторов присваивания с конструкцией <name>=<value>; причем пробелы между этими элементами могут быть в любом количестве, в том числе и отсутствовать. Можно все писать совсем без пробелов. Это поле заканчивается либо знаком [#], то есть началом новой команды, либо знаком [@]. Можно ставить комментарии специальной конструкции, но проще оборвать поле командой #% записать комментарий, а потом открыть новую команду. Команда #% ничего не делает и используется просто как ограничитель расчетов. Для выполнения вычислений есть все стандартные операции
+ - * / ^ ( )
записанные в обратном порядке очередности выполнения. Знак ^ означает возведение в степень. И есть стандартные функции. Последние имеют имена, состоящие из трех знаков. Список стандартных функций дополнен некоторыми специальными функциями. Он перечислен ниже:
abs() == абсолютное значение
sqr() == квадратный корень
log() == натуральный логарифм
exp() == экспонента
sin() == синус
ars() == арксинус
cos() == косинус
arc() == арккосинус
tan() == тангенс
art() == арктангенс
rnd() == случайное значение
int() == целая часть
sfi() == синус интеграл Френеля int(0,x)dt*sin((pi/2)*t^2)
cfi() == косинус интеграл Френеля int(0,x)dt*cos((pi/2)*t^2)
bj0() == функция Бесселя J[0](x)
bj1() == функция Бесселя J[1](x)
Аргумент у функций записывается в круглые скобки так же, как и индексы элементов массива. У функции rnd() аргумент не используется, но для соблюдения грамматики надо писать rnd(0). Функция int() получается отбрасыванием дробной части у числа независимо от знака. При этом положительное число становится меньше, а отрицательное -- больше. Для получения ближайшего целого к положительному числу к аргументу функции надо добавить 0.5, а к отрицательному -0.5. Числа можно писать в любом формате как с точкой, так и с запятой и в экспоненциальной форме как с [E] так и с [e]. Вот примеры правильной записи чисел:
1,23 1.23 12,3E-1 0.123E1 123e-2
Но плюс к указанным добавлены две новые операции
В результате введения операций [<] и [>] оказалось возможным упразднить все так называемые условные операторы, оставив только блок из двух команд, реализующий ветвление вариантов и дополненный двойной проверкой условия. А именно, конструкцию
#case N . . . #end
где N есть аргумент команды #case. Аргумент может быть числом, переменной или элементом массива, а многоточием обозначены все другие команды данного варианта расчетов, которые выполняются лишь в том случае, если выполняется условие N=&. Команда #end ограничивает число операторов данного варианта и проводит дополнительный анализ условия, а & - это имя специальной переменной, которая наравне с другими переменными может участвовать в расчетах. Самой простой логической операцией, которую можно реализовать с помощью этой команды является ветвление. Допустим у нас есть несколько вариантов кода, из которых надо выполнить какой то один. Это делается набором команд
# &=2; #case 1 . . . #end | #case 2 . . . #end | #case 3 . . . #end | и так далее.
В написанном коде будет выполнен второй вариант. Достаточно поменять значение переменной [&], не трогая остальной код, и будет выполнен другой вариант. Но пара команд
# i=0; &=i; #case 0 . . . . # i=i+1; &=(5-i)<0; #end
Здесь многоточие выполнится для i=0,1,2,3,4,5 и затем цикл закончится и программа будет выполнять следующие команды. В такой конструкции #case работает как простой цикл. Но для удобства для этих целей есть и простая команда
#rep N . . . #end
которая просто N раз повторяет многоточие. Команда #case реально позволяет выполнить или не выполнить что-то в зависимости от любого логического условия. Нужно только правильно определить переменную & используя операции [<] и [>] . То есть она одна заменяет и оператор if( ){ } и оператор while( ){ } и оператор switch( ){ } языка Java, а также аналогичные операторы других языков. И в то же время никаких ограничений на возможности программирования не накладывает.
Для тех, кто знаком с языками программирования, например, Java, я поясню аналогию. Например, код на Java
if( a == 1 ){ что-то сделать }
может быть записан как
# &=a; #case 1 что-то сделать #end |
Более сложный код
if( a <= 1 && b >= 2 ){ что-то сделать }
может быть записан как
# &=(a-1)>0+(2-b)>0; #case 0 что-то сделать #end |
Другое условие
(a <= 1 || b >= 2 )
эквивалентно
# &=(a-1)>0*(2-b)>0; #case 0 ...
В принципе все условия оператора if( ){ } могут быть записаны как равенство нулю некоторого выражения.
Команда #end | изменит & на значение 12345 и поэтому тело цикла будет выполнено только один раз.
Чтобы получить форму while( ){ } нужно использовать чистую команду #end и вычислять переменную &
еще раз внутри цикла. Форма switch( ){ } наиболее простая: определяете переменную & один раз
и используете много команд #case ... #end | с разными значениями аргумента, как было показано выше.
Наконец последнее: как простые так и условные циклы могут быть вложены друг в друга с числом вложений до 25. То есть можно писать так
# x=0; j=1; N=10; M=10; #rep N # y=0; #rep M # r(j)=x*y; y=y+1; j=j+1; #end # x=x+1; #end
Такой код позволяет вычислять многомерные матрицы. Вложенные условные циклы позволяют реализовать сложные логические вычисления.
Для более удобной работы с массивом дополнительно существуют еще две простые команды. Первая из них
#data N r(11) a b c*5 g ...
Имя этой команды (data) можно сократить до одной буквы, то есть писать #d . Она позволяет быстро определить значения элементов массива. Первый аргумент N определяет сколько элементов будет определено, второй указывает первый элемент массива для определения. Эта запись фактически задает первый индекс массива. Важно иметь в виду, что переменные тоже образуют массив, специальным образом упорядоченный, так что их тоже можно определять таким способом. А после идут значения, которые надо присвоить элементам массива. Это могут быть числа, переменные и элементы массива. Если после значения стоит *5, то это означает, что данное значение нужно взять 5 раз. Итак аргументы команды образуют следующую структуру: <число><начало массива><данные>. Но таких структур может быть сколько угодно, одна структура следует за другой. Окончание опять либо на знаке [#] либо на знаке [@] - все остальное трактуется как ошибка. Число N ограничено и не может быть больше 500.
Вторая команда
#pas N r(11) r(25)
позволяет быстро присвоить значения одной совокупности элементов массива другой совокупности элементов массива, то есть, как говорят, переслать значения из одной части массива в другую часть. Первым указывается массив из которого пересылаются значения, вторым - куда пересылаются. В этой команде структура не повторяется. Надо снова писать имя команды. Число N не ограничено.