Copyright (C) 1998-2007 MKTMK Moscow, Russia

http://www.mktmk.narod.ru.

e-mail: mktmk<at>narod.ru

 

This document write in WIN1251 code (Russian).

 

Пакет Open Basic.

Описание применения.

Версия 1.80.

Версия DLL 1.20.

 

                   Аннотация

 

 Open Basic (OB) представляет собой реализацию интерпретатора языка Basic.

 OB разработан для встраивания в приложения пользователя в качестве скриптового

языка.

 OB имеет возможность расширения системы команд путем подключения

пользовательских функций к исполняющей системе Open Basic.

 Пользовательские функции могут быть написаны на C/C++, ассемблере или других

языках. Пользовательские функции могут вызываться из Basic-программы, получать

параметры разных типов из Basic-программы и возвращать результаты своей работы

в Basic-программу.

 Специально разработанный интерфейс вызова пользовательских функций позволяет

на этапе исполнения определить тип и порядок следования параметров в вызове.

 OB реализует подмножество команд языка Basic. OB написан полностью на C++ и

реализован в виде класса с именем ob_obasic.

 OB поддерживает данные трех типов: с плавающей точкой, целые со знаком, строковые и массивы этих типов.

 OB имеет multithread-safe код.

 

 В документе описывается:

 - порядок работы с интерпретатором Open Basic

 - синтаксис операторов Open Basic

 - интерфейс к данным Open Basic из пользовательских функций

 - правила подключения пользовательских функций

 - типы данных Open Basic

 - возможности отладки

 

 OB не использует никаких графических библиотек.

 OB не использует никаких системных вызовов ОС в явном виде. Только ANSI-C++ конструкции.

 

Замечание

 

 Интерпретатор Open Basic написан на C++ и реализован в виде класса. Это представляет проблему при использовании интерпретатора в языках, не поддерживающих ООП (например в Visual Basic). Для такого варианта применения разработан интерфейс к интерпретатору, который включает в себя только ANSI-C функции, без ООП и исключений. Этот интерфейс оформлен в виде DLL с именем ob180_bcb60_single_thread.dll и ob180_bcb60_multi_thread.dll.

 

 В данном документе описывается интерфейс к интерпретатору Open Basic с использованием этих ANSI-C функций. С помощью них можно получить доступ ко всей функциональности интерпретатора Open Basic.

 

 Интерфейс к интерпретатору Open Basic с использованием методов класса ob_obasic описан в документах READ_RUS.HTM и READ_ENG.HTM.

 

                    Производитель

 

Copyright (C) 1998-2007 MKTMK Moscow, Russia

http://www.mktmk.narod.ru.

e-mail: mktmk<at>narod.ru

 

MKTMK Software Company. Moscow, Russia

 

                      Обратная связь

 

 Если Вы собираетесь применять интерпретатор, и хотите знать об выходе новых

версий и о возможных изменениях почтового и WWW адреса, то сообщите об этом

по e-mail.

 

 MKTMK Software Company заинтересована в опыте применения интерпретатора:

 

 - для чего Вы применяете интерпретатор

 - Ваш транслятор и номер его версии

 - найденные в программе ошибки

 - полнота документации и ошибки в ней 

 - подключали ли Вы пользовательские функции

 - какие замечания к интерфейсу пользовательских функций

 - с какой ОС Вы работаете

 - откуда Вы узнали об интерпретаторе

 

 Эти сведения помогут нам при сопровождении программы.

 

                          Гарантии

 

 Интерпретатор и документация поставляются на условиях "как есть". Фирма MKTMK

не несет ответственности за возможные убытки, понесенные из-за использования

интерпретатора.

 Мы будем признательны за все найденные в программе ошибки.

 

                           Ссылки

 

 Все упомянутые в тексте торговые марки являются собственностью их владельцев.

 

 

                    Содержание

 

Аннотация. 1

Замечание. 1

Производитель. 1

Обратная связь. 2

Гарантии. 2

Ссылки. 2

1. Описание задачи и назначение программы.. 4

2. Условия применения. 4

3. Входные и выходные данные. 4

3.1. Общие сведения. Как использовать интерпретатор. Как загрузить и запустить *.bas программу. 4

3.2. Обзор технических решений. 6

3.3. Описание функций, которые используются для загрузки и запуска *.bas программ.. 7

3.3.1. Функция obdll_create. 7

3.3.2. Функции  obdll_load и obdll_load1. 7

3.3.3. Функция obdll_run. 8

3.3.4. Описание кодов завершения функции obdll_run. 8

3.4. Описание функций, которые используются для организации отладки в интерпретаторе Open Basic  9

3.4.1. Функция obdll_setstep. 9

3.4.2. Функция obdll_getstep. 9

3.4.3. Функция obdll_loadbreakstr 9

3.4.4. Функция obdll_getinputptr 10

3.4.5. Функция obdll_setoperatorbreak. 10

3.4.6. Функция obdll_getcurrentoperatorname. 11

3.4.6  Функции obdll_setin, obdll_setout, obdll_setin1, obdll_setout1. 11

3.4.7        Функция obdll_ends. 12

3.4.8        Функции obdll_gettypenextlex и obdll_restoreinputpointer 12

3.5       Синтаксис языка Open Basic. Общие сведения. 13

3.6       Типы данных, имена и метки Open Basic. 14

3.7       Пользовательские функции в Open Basic. 15

3.7.7        Тип возвращаемого значения для пользовательской функции. 16

3.7.8        Прототипы для пользовательской функции. 16

3.7.9        Выбор Basic-имени пользовательской функции. 17

3.7.10      Подключение пользовательской функции к исполняющей системе OB.. 17

3.8       Методы и перечисления класса ob_obasic для подключения и отключения пользовательских функций. 20

3.8.7        Функции obdll_setfun1, obdll_setfun2, obdll_setfun3. 20

3.8.8        Функция obdll_delfun. 20

3.9       Назначение параметров пользовательских функций. 21

3.9.7        Общие сведения. 21

3.9.8        Параметры пользовательских функций. 21

3.10     Доступ из пользовательской функции к данным *.bas программы. 23

3.11     Методы и перечисления класса ob_obasic для доступа к данным Open Basic из пользовательских функций. 24

3.11.7      Методы и перечисления класса ob_obasic для определения типа переменных и массивов Open Basic  24

3.11.7.1       Функция obdll_typevar 24

3.11.7.2       Функция obdll_typearray. 24

3.11.8      Функции для определения длины строковых переменных и элементов строковых массивов Open Basic. 25

3.11.9      Функции для определения размеров массивов Open Basic. 27

3.11.10        Функции для записи переменных Open Basic. 27

3.11.11        Функции для чтения переменных Open Basic. 28

3.11.12        Функции для создания и удаления переменных и массивов Open Basic. 30

3.11.12.1     Функция для создания переменных Open Basic. 30

3.11.12.2     Функция для создания массивов Open Basic. 30

3.11.12.3     Функции для удаления переменных и массивов Open Basic. 30

3.12     Описание других функций библиотеки ob180_bcb60_*.dll 31

3.13     Операторы.. 31

3.13.7      Оператор PRINT. 32

3.13.8      Оператор INPUT. 32

3.13.9      Операторы FOR и NEXT. 33

3.13.10        Оператор GOTO.. 34

3.13.11        Операторы GOSUB и RETURN.. 34

3.13.12        Оператор LET. 35

3.13.13        Оператор DIM... 36

3.13.14        Операторы STOP и END.. 36

3.13.15        Оператор REM... 37

3.13.16        Операторы OPEN и CLOSE. 37

3.13.17        Оператор KILL. 38

3.13.18        Операторы READ, DATA и RESTORE. 38

3.13.19        Оператор RANDOMIZE. 39

3.13.20        Оператор IF. 40

3.14     Встроенные функции. 41

3.14.7      Функция SGN%.. 41

3.14.8      Функция ABS. 41

3.14.9      Функция INT%.. 42

3.14.10        Функции SIN, COS, ATN, SQR, EXP, LOG и LOG10. 42

3.14.11        Функция RND.. 42

3.14.12        Функция LEN%.. 43

3.14.13        Функции DAT$ и CLK$. 43

3.14.14        Функции D2STR$, D2HEXSTR$, STR2FLOAT и STR2INT%.. 43

3.15     Обработка ошибок. 44

3.16     Таблица диагностических сообщений. 44

 

 

1. Описание задачи и назначение программы

 

 Часто в пользовательских приложениях возникает необходимость в применении

простого скриптового языка. Такая задача возникает, если приложение оперирует

некоторым количеством примитивов, которые должны вызываться в разной

последовательности для разных режимов работы.

 

Например:

 

 - запросы к базе данных с разными условиями выборки данных

 - тестирование оборудования и/или программного обеспечения

 - организация связи с нестандартным оборудованием по различным каналам

 - построение графических интерфейсов и манипуляции с объектами GUI

 - входной язык в программах-терминалах  для разбора командной строки

 - входной язык оператора-технолога в задачах АСУТП

 - входной язык сложных конфигурационных файлов

 - и многое другое

 

 Графический интерфейс пользователя затрудняет возможность автоматизации

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

которые предоставляет скриптовой язык.

 

 Интерпретатор Open Basic разработан для встраивания в приложения пользователя

в качестве скриптового языка.

 Open Basic поставляется в виде библиотеки или исходных текстов.

 OB имеет возможность расширения системы команд путем подключения

пользовательских функций к исполняющей системе Open Basic.

 Пользовательские функции могут быть написаны на C/C++, ассемблере или других

языках. Пользовательские функции могут вызываться из Basic-программы, получать

параметры разных типов из Basic-программы и возвращать результаты своей работы

в Basic-программу.

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

Basic-программы, а не только передаваемым через параметры. Этот доступ

осуществляется по именам переменных и массивов.

 

2.  Условия применения

 

 Пакет Open Basic написан полностью на C++ и не использует системные вызовы

какой-либо ОС. Пакет Open Basic может использоваться совместно с любой

графической библиотекой.

 

Интерпретатор Open Basic написан на C++ и реализован в виде класса. Это представляет проблему при использовании интерпретатора в языках, не поддерживающих ООП (например в Visual Basic). Для такого варианта применения разработан интерфейс к интерпретатору, который включает в себя только ANSI-C функции, без ООП и исключений. Этот интерфейс оформлен в виде DLL с именем ob180_bcb60_*.dll.

3.   Входные и выходные данные

 

3.1. Общие сведения. Как использовать интерпретатор. Как загрузить и запустить *.bas программу.

 

 Интерпретатор Open Basic реализован в виде класса с именем ob_obasic. Для применения в языках без поддержки ООП и исключений написан набор ANSI-C функций, который обеспечивает доступ к функциональности интерпретатора Open Basic.

 Работа интерпретатора состоит в выполнении программы на языке Basic.

В данном описании эта программа называется *.bas-программой. Программа *.bas

является текстовым файлом или буфером в памяти, открытом как поток istream.

 

 Далее в описании:

 

 1. "оператор" - означает оператор языка Basic. Например PRINT, FOR и т.д.

 2. "пользовательская функция"  - означает пользовательскую функцию,

     присоединенную к исполняющей системе Open Basic

 3. "функция"  - означает функцию С++ или С

 4. "метод"    - означает метод класса ob_obasic.

 5. "*.bas-программа" - программа на языке Basic

 

 Чтобы использовать ANSI-C интерфейс к интерпретатору нужно:

 

1.    скачать со страницы http://www.mktmk.narod.ru архив, содержащий:

-          ob180_bcb60_*.dll

-          ob180_bcb60_*.lib

-          obd.h

 

 

2.    включить в проект библиотеку интерпретатора

 

3.    указать путь для подключения заголовочного файла библиотеки интерпретатора obd.h, либо вручную экспортировать функции из ob180_bcb60_*.dll с помощью LoadLibrary и GetProcAddress. При этом можно пользоваться прототипами из obd.h как образцом.

 

ВНИМАНИЕ: Библиотека ob180_bcb60_*.dll построена на Borland C++ Builder v6.0. Поэтому перед всеми экспортируемыми из нее именами функций нужно ставить знак подчеркивания “_”.

 

ВНИМАНИЕ: Для исключения конфликта имен, имена всех функций  в библиотеке ob180_bcb60_*.dll начинаются с префикса obdll_

 

ВНИМАНИЕ: Большинство функций в библиотеке ob180_bcb60_*.dll возвращают код ошибки в переменной типа unsigned int. Чтобы по коду ошибки получить текстовое сообщение с диагностикой ошибки, нужно использовать функцию obdll_getmessage.

 

4.    создать экземпляр класса ob_obasic в своей программе с помощью функции obdll_create. Эта функция возвращает хендлер интерпретатора. Хендлер используется при обращении к большинству функций интерпретатора. В качестве хендлера используется указатель void*. В языках без поддержки указателей для хранения хендлера нужно использовать переменную, в которую помещается указатель для платформы Win32. Обычно это переменная типа unsigned int.

 

5.    передать ему программу для выполнения (загрузить *.bas программу) с помощью функции obdll_load

 

6.    запустить программу на выполнение с помощью функции obdll_run

 

7.    После окончания работы с интерпретатором необходимо его удалить с помощью функции obdll_delete

 

Пример:

 

//Создание интерпретатора и запуск программы. Программа *.bas хранится

//в файле prog.bas

//Обработка кодов возврата не показана

 

obdll_type_codeerror codeerror;

obdll_handler ptr;

int te;

int res;

 

ptr=obdll_create();

 

obdll_load(ptr,"prog.bas",0);

 

codeerror=obdll_run(ptr,&te);

 

Пример:

 

//после окончания программы prog.bas загрузка и запуск программы

//prog1.bas

//Обработка кодов возврата не показана

 

obdll_load(ptr,"prog1.bas",0);

 

codeerror=obdll_run(ptr,&te);

 

Пример:

 

//после окончания программы prog1.bas загрузка и запуск программы

//prog2.bas

//Обработка кодов возврата не показана

 

obdll_load(ptr,"prog2.bas",1); /*загрузка программы в режиме OVERLAY*/

 

codeerror=obdll_run(ptr,&te);

 

Пример:

 

//после окончания программы prog2.bas удаление интерпретатора

 

codeerror=obdll_delete(ptr,&res);

3.2. Обзор технических решений

 

При проектировании интерпретатора решались следующие основные проблемы:

 

1.    Возможность хранения Basic-программы в файле на диске или в буфере памяти. Для обеспечения этой возможности созданы две функции obdll_load и obdll_load1. Первая принимает имя файла с Basic-программой, вторая – текстовый буфер с Basic-программой. Аналогично входной поток оператора INPUT и выходной поток оператора PRINT тоже могут быть буферами или файлами.

 

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

  

-          Исчерпание входного потока

-          Синтаксическая ошибка в программе

-          Символ точки останова

-          Символ конца строки при установленном флаге пошагового режима работы

-          Установленный флаг окончания до/после указанного оператора. Этот режим используется для сопряжения ввода-вывода интерпретатора с системой ввода-вывода текущей OC.

 

При окончании функция obdll_run возвращает код окончания. Анализируя этот код пользователь может узнать причину окончания функции.

Разделение выполнения программы на два этапа позволяет продолжить функцию obdll_run после окончания без повторной загрузки программы.

 

1.    Один экземпляр интерпретатора может выполнять одну программу в данный момент времени. В программе может быть несколько экземпляров интерпретатора. Интерпретатор не имеет статических членов данных (кроме доступных по чтению констант). Поэтому несколько экземпляров интерпретатора могут работать одновременно в разных нитях или потоках программы.

 

2.    Пользовательские функции в Open Basic имеют унифицированный интерфейс. Этот интерфейс позволяет проанализировать типы и порядок следования параметров в вызове пользовательской функции на этапе выполнения программы. Этот подход требует от программиста аккуратности, но зато не ограничивает возможности создания пользовательских функций с разными параметрами и позволяет при создании пользовательских функций обойтись без программы SWIG.

 

3.1. Описание функций, которые используются для загрузки и запуска *.bas программ

 

 Квалификатор OBDLL_SPEC определен  в библиотеке ob180_bcb60_*.dll как __declspec(dllimport).

3.1.1.  Функция obdll_create

 

obdll_handler OBDLL_SPEC obdll_create(void);

 

создает экземпляр интерпретатора Open Basic и функция возвращает хендлер интерпретатора. В случае ошибки возвращает ноль.

 

3.1.2. Функции  obdll_load и obdll_load1

 

загружают *.bas-программу.

 

obdll_type_codeerror OBDLL_SPEC obdll_load(obdll_handler ptr,obdll_type_char* filename,int flag);/*1-overlay 0-nooverlay*/

 

obdll_type_codeerror OBDLL_SPEC obdll_load1(obdll_handler ptr,obdll_type_char* buf,int length,int flag);

 

Параметры obdll_load:

 

1.    ptr - хендлер интерпретатора.

2.    filename - имя файла, в котором содержится *.bas-программа.

3.    flag - флаг, определяющий режим загрузки. При flag=1 производится загрузка в режиме оверлея (т.е. с сохранением таблиц переменных предыдущей программы). При flag=0 производится загрузка без сохранения таблиц переменных предыдущей программы.

 

Параметры obdll_load1:

 

1.    ptr - хендлер интерпретатора.

2.    buf - указатель на текстовый буфер, в котором содержится *.bas-программа.

3.    length - длина текстового буфера, в котором содержится *.bas-программа.

4.    flag - флаг, определяющий режим загрузки. При flag=1 производится загрузка в режиме оверлея (т.е. с сохранением таблиц переменных предыдущей программы). При flag=0 производится загрузка без сохранения таблиц переменных предыдущей программы.

 

Пояснение об использовании оверлейного режима загрузки:

 

 В процессе работы интерпретатор создает таблицы:

 

 1. таблица переменных

 2. таблица массивов

 3. таблица пользовательских функций

 4. таблица (поток) данных оператора DATA

 5. таблица меток

 6. таблица циклов операторов FOR

 7. таблица открытых файлов

 8. таблица (стек) подпрограмм GOSUB

 

 При flag=1 происходит очистка:

 

 1. таблиц меток

 2. таблицы циклов операторов FOR

 3. таблицы (стека) подпрограмм GOSUB

 

 Остальные таблицы:

 

 1. таблица переменных

 2. таблица массивов

 3. таблица пользовательских функций

 4. таблица (поток) данных оператора DATA

 5. таблица открытых файлов

 

 не очищаются и могут использоваться вновь загруженной программой.

 

 При flag=0 происходит очистка всех таблиц, кроме таблицы

пользовательских функций.

 

 Таблица пользовательских функций очищается только при вызове функции obdll_clrtablfun.

 

3.1.3. Функция obdll_run

 

obdll_type_codeerror OBDLL_SPEC obdll_run(obdll_handler ptr,int* te);

 

запускает загруженную программу. Или продолжает выполнение программы после останова с кодом завершения.

 

Параметры obdll_run:

 

1.    ptr - хендлер интерпретатора.

2.    te - код завершения (см. следующий пункт)

 

3.1.4.  Описание кодов завершения функции obdll_run

 

Коды завершения:

 

1.    te=0 - при нормальной работе никогда не возвращается функцией obdll_run. Используется для внутренних переходов.

 

2.    te=1 - функция obdll_run окончилась из-за исчерпания входного потока. Это нормальное завершение *.bas-программы.

 

3.    te=2 - функция obdll_run окончилась при обнаружении оператора END. Это нормальное завершение *.bas-программы.

 

4.    te=3 - функция obdll_run окончилась после исполнения очередной строки, т.к. с помощью функцией obdll_setstep был установлен флаг пошаговой работы.

 

5.    te=4 - функция obdll_run окончилась после считывания символа '@', который является символом точки останова для Open Basic.

 

6.    te=5 - функция obdll_run окончилась т.к. не был выполнена функция obdll_load и входной поток не открыт.

 

7.    te=6 - функция obdll_run окончилась перед выполнением какого-то оператора OB.

 

Пояснение:

 

 В OB для каждого оператора (PRINT, FOR и т.д.) имеется возможность установить

режим завершения метода run до или после выполнения этого оператора. Режим

завершения устанавливается с помощью функции:

 

obdll_type_codeerror OBDLL_SPEC

obdll_setoperatorbreak(obdll_handler ptr,obdll_type_char* name,int before,int after,int* res);

 

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

PRINT и INPUT в конкретной ОС. Если перед выводом в поток необходимо выполнить

некоторые действия (например очистить выходной поток), нужно установить режим

завершения функции obdll_run до выполнения оператора PRINT.

 Подробнее см. описание функции obdll_setoperatorbreak.

 

 

8.    te=7 - функция obdll_run окончилась после выполнения какого-то оператора OB.

 

Пояснение:

 

 Если после вывода в поток необходимо выполнить некоторые действия (например

передать выведенные оператором PRINT данные оконной системе), нужно установить

режим завершения функции obdll_run после выполнения оператора PRINT.

Подробнее см. описание функции obdll_setoperatorbreak.

 

 По умолчанию режим завершения до и после выполнения всех операторов запрещен.

 

3.2. Описание функций, которые используются для организации отладки в интерпретаторе Open Basic

 

 В OB есть два режима отладки: пошаговое выполнение *.bas-программ и назначение точек останова.

 Возможность пошагового выполнения *.bas-программ реализована с помощью функции obdll_setstep.

 Символ '@' отдельной строке в тексте *.bas-программы реализует точку останова. Точек останова в *.bas-программе может быть несколько. После внесения точек останова *.bas-программу нужно перезагрузить методом load.

 При передаче управления на строку с символом '@' произойдет останов программы. Код завершения функции obdll_run будет te=4. Для продолжения программы нужно снова запустить функцию obdll_run.

 

3.2.1. Функция obdll_setstep

 

obdll_type_codeerror OBDLL_SPEC obdll_setstep(obdll_handler ptr,int flag);/*flag: 1-set step mode 0-reset step mode*/

 

 - устанавливает или снимает режим пошагового выполнения программы. Эту Функцию можно использовать в любой момент работы интерпретатора. При установки пошагового режима функция obdll_run будет завершаться (с кодом останова te=3) после выполнения каждой строки *.bas программы. Для продолжения программы нужно снова запустить функцию obdll_run.

 

Параметры obdll_setstep:

 

1.    ptr - хендлер интерпретатора.

2.    flag - флаг пошагового режима.

 

 При flag=0 программа выполняется непрерывно.

 При flag=1 программа завершается с кодом te=3 после выполнения каждой строки программы.

 По умолчанию режим пошагового выполнения запрещен.

 

3.2.2. Функция obdll_getstep

 

 

obdll_type_codeerror OBDLL_SPEC obdll_getstep(obdll_handler ptr,int* flag);

 

- возвращает текущий режим режим пошагового выполнения программы  в параметре flag.

 

3.2.3.  Функция obdll_loadbreakstr

 

Функция

 

obdll_type_codeerror OBDLL_SPEC

obdll_loadbreakstr(

obdll_handler ptr,

obdll_type_stringsize lengthbuffers,

obdll_type_char* ptrbefore,

obdll_type_char* ptrcurrent,

obdll_type_char* ptrafter

);

 

Параметры:

 

1.    ptr - хендлер интерпретатора.

2.    lengthbuffers - длина буферов

3.    ptrbefore - буфер для строки, предшествующей текущей исполняемой

4.    ptrcurrent - буфер для текущей исполняемой строки

5.    ptrafter - буфер для строки, следующей за текущей исполняемой

 

 

 Функция obdll_loadbreakstr загружает в указанные буфера соответствующие строки

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

 

Пример:

 

//Создание интерпретатора и запуск программы в пошаговом режиме.

//с печатью выполняемых строк

 

#define obdll_maxlengthstring (4096+100)

 

obdll_type_char strcurrent[obdll_maxlengthstring];//буфер

 

obdll_type_codeerror codeerror;

obdll_handler ptr;

int te;

int res;

 

ptr=obdll_create();

 

obdll_load(ptr,"prog.bas",0);

 

obdll_setstep(ptr,1);//установка пошагового режима

 

while(1){

 

codeerror=obdll_run(ptr,&te);

 

if(te!=3) break;//запуск *.bas-программы

 

obdll_loadbreakstr(ptr,obdll_maxlengthstring,0,strcurrent,0);

printf("String current: %s",strcurrent);

}//while

 

codeerror=obdll_delete(ptr,&res);

 

3.2.4. Функция obdll_getinputptr

 

Функция

 

obdll_type_streampos OBDLL_SPEC obdll_getinputptr(obdll_handler ptr);

 

Параметры:

 

1.    ptr - хендлер интерпретатора.

 

Возвращает текущий указатель во входном потоке. Используется при организации отладки в различных оконных системах для позиционирования курсора на текущую исполняемую строку *.bas-программы. При ошибках возвращает –1.

 

3.2.5. Функция obdll_setoperatorbreak

 

 В OB для каждого оператора (PRINT, FOR и т.д.) имеется возможность установить

режим завершения функции obdll_run до или после выполнения этого оператора. Режим

завершения устанавливается с помощью метода:

 

obdll_type_codeerror OBDLL_SPEC

obdll_setoperatorbreak(obdll_handler ptr,obdll_type_char* name,int before,int after,int* res);

 

Параметры:

 

1.    ptr - хендлер интерпретатора.

2.    name - имя оператора.

 2. before - флаг завершения метода run до выполнения этого оператора (1 – есть завершение)

3.    after  - флаг завершения метода run после выполнения этого оператора (1 – есть завершение)

4.    res - возвращаемое значение:

 

1  - успешное завершение

0  - если ошибка задания имени оператора

 

 Возможность установить режим завершения функции obdll_run до или после выполнения любого оператора сделана для облегчения реализации операторов ввода и вывода PRINT и INPUT в конкретной ОС.

 

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

 

 Если после вывода в поток необходимо выполнить некоторые действия (например передать выведенные оператором PRINT данные оконной системе), нужно установить режим завершения функции obdll_run после выполнения оператора PRINT.

 

 По умолчанию режим завершения до и после выполнения всех операторов запрещен.

 

В большинстве применений функция obdll_setoperatorbreak используется совместно с функциями obdll_setout и obdll_setin для сопряжения систем ввода-вывода интерпретатора и конкретной оконной системой.

 

3.2.6.  Функция obdll_getcurrentoperatorname

 

obdll_type_char* OBDLL_SPEC obdll_getcurrentoperatorname(obdll_handler ptr);

 

Параметры:

 

1.    ptr - хендлер интерпретатора.

 

Функция позволяет узнать, какой именно оператор вызвал завершение при завершении с кодами: te=6 и te=7.

 

Функция возвращает имя оператора.

 

3.4.6  Функции obdll_setin, obdll_setout, obdll_setin1, obdll_setout1

 

 Функции позволяют переопределить входной и выходной потоки для операторов INPUT и PRINT соответственно.

 

obdll_type_codeerror OBDLL_SPEC obdll_setout(obdll_handler ptr,obdll_type_char* buf,int length);

obdll_type_codeerror OBDLL_SPEC obdll_setin(obdll_handler ptr,obdll_type_char* buf,int length);

 

obdll_type_codeerror OBDLL_SPEC obdll_setout1(obdll_handler ptr,obdll_type_char* filename);

obdll_type_codeerror OBDLL_SPEC obdll_setin1(obdll_handler ptr,obdll_type_char* filename);

 

Параметры:

 

1.    ptr - хендлер интерпретатора.

2.    buf – текстовый буфер для входного или выходного потока

3.    length – длина текстового буфера для входного или выходного потока

4.    filename – имя файла для входного или выходного потока

 

Пояснение:

 

В текущей реализации библиотеки ob180_bcb60_*.dll по умолчанию входной и выходной потоки для операторов INPUT и PRINT не определены. Для использования в *.bas-программе операторов INPUT и PRINT необходимо определить эти потоки с помощью функций obdll_setin и obdll_setout. Предполагается, что функции obdll_setin и obdll_setout используются совместно с режимом obdll_setoperatorbreak для операторов INPUT и PRINT. Пример реализации такого взаимодействия можно посмотреть в файле ob.c. В этом файле реализуется консольная версия интерпретатора с использованием библиотеки ob180_bcb60_single_thread.dll.

 

Обратите внимание, что каждый раз перед выполнением оператора PRINT входной поток переопределяется, а после выполнения данные, подготовленные оператором PRINT в буфере выводятся на консоль с помощью printf.

 

Также обратите внимание, что для завершения ввода нужно использовать функцию obdll_ends (см. следующий пункт)

3.4.7       Функция obdll_ends

 

obdll_type_codeerror OBDLL_SPEC obdll_ends(obdll_handler ptr);

 

В процессе работы оператор PRINT выводит в выходной поток, определенный функцией obdll_setout, некоторую текстовую информацию. Но он не выводит завершающего нулевого символа, который оканчивает строки в языке С. Это связано с тем, что в качестве потока вывода может быть текстовый файл, в котором эти символы не нужны. Поэтому, если в качестве выходного потока используется текстовая строка, пользователь должен сам завершать вывод с помощью функции obdll_ends.

 

Параметры:

 

1. ptr - хендлер интерпретатора.

 

3.4.8       Функции obdll_gettypenextlex и obdll_restoreinputpointer

 

Функции предназначены для облегчения реализации операторов ввода и вывода.

 

obdll_type_codeerror OBDLL_SPEC obdll_gettypenextlex(obdll_handler ptr,int* tl);

 

obdll_type_codeerror OBDLL_SPEC obdll_restoreinputpointer(obdll_handler ptr);

 

 

Параметры:

 

1.    ptr - хендлер интерпретатора.

2.    tl  - тип лексемы

 

Функция obdll_gettypenextlex

 

Возвращает следующую лексему из входного потока. Некоторые операторы (например

оператор INPUT) имеют одинаковый синтаксис для ввода из файла и с консоли.

Текущее направление ввода определяется следующей лексемой #. С помощью функции obdll_gettypenextlex можно выяснить тип следующей лексемы после останова с кодом

завершения BREAKBEFOREOPERATOR. И таким образом можно выяснить, откуда

ожидается ввод.

 

 

Функция obdll_restoreinputpointer

 

Предназначена для восстановления состояния входного потока после применения

метода obdll_gettypenextlex. После применения функции obdll_gettypenextlex всегда необходимо применять функцию obdll_restoreinputpointer.

 

Список кодов лексем:

 

PLUS,                     0

MINUS,                    1

MUL,                      2

DIV,                      3

POWER,                    4

ASSIGN,                   5

LP,                       6

RP,                       7

STRING,                   8

SEMICOLON,                9

COMMA,                    10

ENDPROGRAMM,              11

EOL,                      12

LESS,                     13

GREAT,                    14

SHARP,                    15

BREAKPOINT,               16

DECINTNUMBER,             17

HEXINTNUMBER,             18

FLOATNUMBER,              19

FUNC,                     20

OPERATOR,                 21

OLDVARIABLE,              22

OLDARRAY,                 23

NEWNAME,                  24

BAD,                      25

LABEL,                    26

 

3.5       Синтаксис языка Open Basic. Общие сведения

 

ВНИМАНИЕ! Все объекты в *.bas-программе: переменные, массивы, и

          пользовательские функции должны иметь различные имена.

 

 Интерпретатор Open Basic поддерживает подмножество операторов языка Basic.

Эти операторы описаны ниже. Имеется возможность работать с тремя типами данных:

с плавающей точкой, целыми и строками. Имеется возможность работать с массивами

из этих трех типов.

 Переменные в Open Basic не нужно описывать перед первым использованием.

Первое появление переменной в программе должно быть слева от оператора

присвоения.

 Массивы в Open Basic нужно описывать до первого использования оператором DIM.

Массивы могут быть многомерными. Данные для массивов и переменных располагаются

в свободной памяти оператором new. Общий размер массива зависит от ограничений

на оператор new в конкретной ОС.

 В Open Basic индекс массива начинается с единицы.

 В отличие от стандартного языка Basic оператор DIM в Open Basic является

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

 Допускается повторное описание массива с тем же именем в операторе DIM.

Новый массив может иметь другие размерности. Старые данные при этом теряются.

Этот механизм можно применять для освобождения памяти. После захвата большого

массива оператором DIM можно освободить память, описав массив с тем же именем

и размерностью в один элемент.

 При описании массива в операторе DIM в качестве размерностей могут

использоваться целые переменные.

 При создании числовые массивы инициализируются нулем. Строковые массивы

инициализируются пустой строкой ("").

 Диапазон представления данных с плавающей точкой и целых зависит от того, как

транслируется пакет. Обычно целые это int, а плавающие это float.

 Максимальная длина строковых переменных определяется константой

ob_maxlengthstring в файле ob.h. Для версии OB v1.80 ob_maxlengthstring=4096.

 В *.bas-программе могут быть пустые строки.

 

 Интерпретатор Open Basic поддерживает следующие операции над целыми данными и

данными с плавающей точкой:

 

 + - сложение

 - - вычитание

 * - умножение

 / - деление

 ^ - возведение в степень

 - - унарный минус

 + - унарный плюс

 = - присвоение

 <, >, =, <>, <=, >= - выражения отношения 'меньше', "больше", "равно",

 "не равно", "меньше или равно", "больше или равно". Выражения отношения

 используются в операторе IF.

 

3.6       Типы данных, имена и метки Open Basic

 

 Как и в стандартном языке Basic тип переменной или массива в Open Basic

определяется по имени. А именно:

 - если в имени последним символом является символ '%', то это переменная

   или массив целого типа.

 - если в имени последним символом является символ '$', то это переменная

   или массив строкового типа.

 - если в имени последним символом является любой другой символ, то это

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

 

 Многие типы Open Basic описаны в ob.h с помощью typedef.

Тип ob_type_flo отображается в тип float с помощью typedef.

Тип ob_type_int отображается в тип int   с помощью typedef.

В пользовательских функциях рекомендуется использовать типы ob_type_flo и

ob_type_int. При смене, например, ob_type_flo с float на double будет

обеспечена совместимость типов.

 

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

использовать любые последовательности букв и цифр. Имена должны начинаться с

буквы.

 Буквы в имени могут быть прописные или строчные. Символы подчеркивания и

символы '$' и '%' считаются буквами.

 Приведения букв к одному регистру не производится. Имена MASS, mass и Mass

являются разными именами.

 Максимальная длина имени определяется константой ob_maxlengthstring в файле

ob.h. Для версии OB v1.80 ob_maxlengthstring=4096.

 

Пример:

 

 Объявление массива и инициализация двух переменных - целой и с плавающей

точкой. Последнее измерение массива задано переменной. Тип элементов массива

mass - с плавающей точкой. Переменная counter% имеет целый тип. Переменная data

имеет тип с плавающей точкой.

 

      counter%=7

      DIM mass(2,3,10,counter%)

      data=counter%+37.77

 

Пример:

 

Объявление массива и использование его. Повторное объявление

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

 

 

 

      DIM mass(10)

 

        FOR i%=1 TO 10 STEP 1

       mass(i%)=i%+37.77

      NEXT i%

 

      counter%=7

 

      DIM mass(counter%,3)

 

        FOR i%=1 TO counter% STEP 1

       mass(i%,2)=i%+37.77

      NEXT i%

 

 Для строковых данных поддерживаются только операции сложения строк, их

сравнения и присвоения.

 Если в выражении используются данные разных типов, то производится

приведение типов.

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

результирующий тип будет с плавающей точкой.

 При присвоении тип правого выражения приводится к типу выражения слева от

знака присвоения =.

 Если слева от знака присвоения целая переменная, а справа с плавающей точкой,

то дробная часть отбрасывается.

 

 Интерпретатор Open Basic поддерживает метки в виде номеров строк. Эти номера

не обязательно должны идти подряд. Не каждая строка программы должна быть

пронумерована. Осуществить переход операторами GOTO и GOSUB можно только на

пронумерованную строку. Можно поставить метку и у пустой строки.

 

Пример:

 

   IF ii%=6 THEN GOTO 10

 

   PRINT "ii%=";ii%;

10 PRINT "ii%!=6"

 

   IF ik%=7 THEN GOSUB 11

 

   PRINT "ik%=";ik%;

   GOTO 12

11

   PRINT "ik%!=7"

   RETURN

12

   STOP

   END

 

Начиная с версии 1.80 в *.bas программе кроме меток в виде чисел (номеров строк) поддерживаются строковые метки с финальным двоеточием. Двоеточие является частью идентификатора метки и должно следовать за идентификатором метки без разделителя. В операторах GOTO и GOSUB идентификатор строковой метки пишется без финального двоеточия. В программе могут одновременно применяться метки в виде чисел (номеров строк) и строковые метки.

 

Пример:

 

  REM Test string label

 

  PRINT

  PRINT "Start--------------------------------"

 

  loop_counter%=10

 

  FOR i%=1 TO loop_counter%

 

  PRINT "-------------------------------- ";"pass=";i%

 

  GOSUB gosub_label_1

  GOSUB gosub_label_2

  GOSUB gosub_label_3

  GOSUB gosub_label_4

 

  NEXT i%

 

  PRINT "End program OK"

 

10

  STOP

  END

 

gosub_label_1:

  PRINT "gosub_label_1"

 

  a%=i%/2*2

 

  IF a%=i% THEN GOTO goto_label_1

  PRINT "do not goto detect"

  ENDIF

 

goto_label_1:

 

  RETURN

 

gosub_label_2:  PRINT "gosub_label_2"

 

                a%=i%/2*2

 

                IF a%=i% THEN GOTO goto_label_2

                PRINT "do not goto detect"

                ENDIF

 

 

                goto_label_2:RETURN

 

gosub_label_3:

  PRINT "gosub_label_3"

  RETURN

 

gosub_label_4:

  PRINT "gosub_label_4"

  RETURN

 

3.7       Пользовательские функции в Open Basic.

 

 OB имеет возможность расширения системы команд путем подключения

пользовательских функций к исполняющей системе Open Basic.

 

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

следования аргументов в вызове во время исполнения программы.

 

 Пользовательские функции подключаются к исполняющей системе Open Basic под

некоторыми именами (Basic-именами). Каждая пользовательская функция

подключается под своим Basic-именем. После подключения их можно вызывать в

тексте *.bas-программы по этим именам. Можно передавать им параметры и получать

от них результаты. Можно вызывать пользовательские функции без параметров.

 Пользовательские функции могут быть написаны на C/C++, ассемблере или других

языках.

 

 Все пользовательские функции имеют два имени:

 

 1. “Родное” (native) имя функции в составе проекта, по которому пользовательскую функцию

    можно вызывать из программы.

 2. Basic-имя функции, по которому пользовательскую функцию можно вызывать из

    *.bas-программы.

 

 Первое имя пользовательские функции получают при их написании. Второе имя

пользовательские функции получают при подключении к исполняющей системе

Open Basic с помощью функций obdll_setfun1, obdll_setfun1 и obdll_setfun3.

 

 Чтобы создать пользовательскую функцию и подключить ее к исполняющей системе

Open Basic необходимо:

 

 1. Выбрать тип возвращаемого значения для пользовательской функции.

 2. Выбрать “native” имя пользовательской функции и написать пользовательскую

    функцию по одному из трех прототипов.

 3. Выбрать Basic-имя пользовательской функции.

 4. Подключить пользовательскую функцию к исполняющей системе OB с помощью

    функций obdll_setfunXXX, используя Basic-имя и “native” имя в   качестве параметров.

 

 После этого можно использовать Basic-имя пользовательской функции в *.bas

программе.

 

3.7.7       Тип возвращаемого значения для пользовательской функции

 

 Пользовательская функция может возвращать значения трех типов:

 

 - с плавающей точкой obdll_type_flo

 - целое              obdll_type_int

 - строковое          obdll_type_char*

 

 

3.7.8       Прототипы для пользовательской функции

 

 Пользовательская функция может иметь один из трех прототипов:

 

1. Функции, возвращающие значение с плавающей точкой

 

obdll_type_flo name_flo(

obdll_handler ptr,                                       

const obdll_type_char* parstring,                       

const obdll_type_parnum *descrf,                        

const obdll_type_parnum *descri,                        

const obdll_type_parnum *descrc,                        

const obdll_type_flo* parf,                             

const obdll_type_int* pari,                             

const obdll_type_char* parc);

 

2. Функции, возвращающие целое значение

 

obdll_type_int name_int(

obdll_handler ptr,                                       

const obdll_type_char* parstring,                       

const obdll_type_parnum *descrf,                        

const obdll_type_parnum *descri,                        

const obdll_type_parnum *descrc,                        

const obdll_type_flo* parf,                             

const obdll_type_int* pari,                             

const obdll_type_char* parc);

 

3. Функции, возвращающие строку

 

obdll_type_char* name_char(

obdll_handler ptr,                                       

const obdll_type_char* parstring,                       

const obdll_type_parnum *descrf,                        

const obdll_type_parnum *descri,                        

const obdll_type_parnum *descrc,                        

const obdll_type_flo* parf,                             

const obdll_type_int* pari,                             

const obdll_type_char* parc);

 

 Эти прототипы различаются только типом возвращаемого значения.

 

 В файле obd.h содержится макрос OBDLL_DECLARE_USER_FUNCTION(name,typeret), который можно

использовать для объявления пользовательских функций. Параметр name - это “native” имя

функции, параметр typeret - это тип возвращаемого значения.

 

Пример:

 

Объявление пользовательской функции с помощью макроса OBDLL_DECLARE_USER_FUNCTION.

“native” имя пользовательской функции "myfun1".

Тип возвращаемого значения - ob_type_flo.

 

OBDLL_DECLARE_USER_FUNCTION(myfun1,ob_type_flo);

 

Пример:

 

Определение пользовательской функции с помощью макроса OBDLL_DECLARE_USER_FUNCTION.

“native” имя пользовательской функции "myfun2".

Тип возвращаемого значения - ob_type_int.

 

OBDLL_DECLARE_USER_FUNCTION(myfun2,ob_type_int){

return 365;

}

 

Пример:

 

Определение пользовательской функции с помощью макроса OB_DECLFUNAPI.

“native” имя пользовательской функции "myfun3".

Тип возвращаемого значения - ob_type_char*.

 

OBDLL_DECLARE_USER_FUNCTION(myfun3,ob_type_char*){

return "Hello world";

}

 

3.7.9       Выбор Basic-имени пользовательской функции

 

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

массивов и других пользовательских функций *.bas-программы.

 

3.7.10 Подключение пользовательской функции к исполняющей системе OB

 

 Подключение пользовательской функции к исполняющей системе OB производится с

помощью функций obdll_setfun1, obdll_setfun1 и obdll_setfun3.

 

obdll_type_codeerror OBDLL_SPEC obdll_setfun1(obdll_handler ptr,obdll_type_char* name,obdll_type_flofun f,int* res);/*res=result (logical)*/

 

obdll_type_codeerror OBDLL_SPEC obdll_setfun2(obdll_handler ptr,obdll_type_char* name,obdll_type_intfun f,int* res);

 

obdll_type_codeerror OBDLL_SPEC obdll_setfun3(obdll_handler ptr,obdll_type_char* name,obdll_type_charfun f,int flag,int* res);/*flag: 1-delete 0-not delete*/

 

 Параметры:

 

1.    ptr - хендлер интерпретатора

2.    name - Basic-имя пользовательской функции

3.    f    - указатель на пользовательскую функцию

4.    dt   - тип размещения размещения в памяти возвращаемого значения (только для функций, возвращающих строку)

5.    res  - результат работы.

 

Если функция с именем name ранее не была подключена, она подключается и возвращается res=0.

Если функция с именем name ранее была подключена, старая функция отключается, новая функция подключается и возвращается res=1.

 

Пример:

 

//подключается функция userfun1

//эта функция возвращает значение с плавающей точкой

//эта функция печатает сообщение "hello world" и возвращает значение 3.1416

//при подключении она получает Basic-имя "TEST_FUN1"

//то есть в *.bas-программах ее можно вызывать по имени "TEST_FUN1"

 

#include <stdio.h>

#include <obd.h>

 

OBDLL_DECLARE_USER_FUNCTION(userfun1,obdll_type_flo){

printf("hello world");

return 3.1416;

}

 

int main(){

 

obdll_type_codeerror codeerror;

obdll_handler ptr;

int te;

int res;

 

ptr=obdll_create();

 

obdll_load(ptr,"prog.bas",0);

 

codeerror=obdll_setfun1(ptr,"TEST_FUN1",userfun1,&res);/*подключается функция TEST_FUN1*/

 

codeerror=obdll_run(ptr,&te);/*запуск *.bas-программы*/

 

return codeerror;

}

 

Для функции, возвращающей строковый тип есть отличие в порядке подключения.

Возможно два варианта размещения в памяти возвращаемого значения:

 

 - в статической памяти    (dt=0)

 - в куче оператором new[] (dt=1)

 

В первом случае пользовательская функция подключается с параметром dt=0.

 

Во втором случае пользовательская функция подключается с параметром dt=1.

После окончания работы такой функции Open Basic освободит память оператором delete[].

 

Этот режим нужен для запуска нескольких экземпляров интерпретатора в разных нитях программы. При размещении выходного значения в куче не будет конфликта между разными экземплярами интерпретатора.

 

ВНИМАНИЕ:

 

Если пользовательская функция подключается с параметром dt=1, то для запроса буфера под возвращаемое значение при dt=1 нельзя использовать new или calloc из текущей системы программирования. Нужно использовать функцию:

 

obdll_type_char* OBDLL_SPEC obdll_new(obdll_type_stringsize size);

 

из библиотеки ob180_bcb60_*.dll, т.к. необходимо обеспечить соответствие менеджеров кучи при запросе и освобождении памяти.

 

Пример:

 

 В примере создается экземпляр интерпретатора, открывается файл с именем

EXAMPLE.BAS и загружается в интерпретатор. После этого к исполняющей системе

подключаются четыре функции TEST_FUN1-TEST_FUN4.

 

 Функция TEST_FUN1 печатает список своих параметров с плавающей точкой и

возвращает значение с плавающей точкой, равное сумме своих параметров с

плавающей точкой.

 

 Функция TEST_FUN2 печатает список своих целых параметров и возвращает целое

значение равное сумме своих целых параметров.

 Функции TEST_FUN3 и TEST_FUN4 печатают свой первый строковый параметр и

возвращают строку "This is string".

 При этом функция TEST_FUN4 располагает возвращаемое значение в статической

памяти, а функция TEST_FUN3 в свободной памяти.

 Все функции контролируют правильность типов своих параметров. В случае

отсутствия параметров нужного типа печатают сообщения.

 

#include <stdio.h>

#include <string.h>

#include <obd.h>

 

char* s="This is string";

 

OBDLL_DECLARE_USER_FUNCTION(userfun1,obdll_type_flo){

obdll_type_flo summ=0;

obdll_type_parnum i;

if(descrf[0]==0) printf("\nNot float parameters");

for(i=0;i!=descrf[0];i++){

summ+=parf[i];

printf("\nparameters[%u]=",i,parf[i]);

}

return summ;

}

 

OBDLL_DECLARE_USER_FUNCTION(userfun2,obdll_type_int){

obdll_type_int summ=0;

obdll_type_parnum i;

if(descri[0]==0) printf("\nNot int parameters");

for(i=0;i!=descri[0];i++){

summ+=pari[i];

printf("\nparameters[%u]=",i,pari[i]);

}

return summ;

}

 

OBDLL_DECLARE_USER_FUNCTION(userfun3,char*){

char* p;

if(descrc[0]==0) printf("\nNot string parameters");

printf("\n%s",parc);

p=obdll_new(strlen(s)+1);

strcpy(p,s);

return p;

}

 

OBDLL_DECLARE_USER_FUNCTION(userfun4,char*){

if(descrc[0]==0) printf("\nNot string parameters");

printf("\n%s",parc);

return s;

}

 

main(){

 

obdll_type_codeerror codeerror;

obdll_handler ptr;

int te;

int res;

 

ptr=obdll_create();/*создается экземпляр интерпретатора*/

 

obdll_load(ptr,"EXAMPLE.BAS",0);

 

codeerror=obdll_setfun1(ptr,"TEST_FUN1",userfun1,&res);/*подключается функция TEST_FUN1*/

codeerror=obdll_setfun2(ptr,"TEST_FUN2",userfun2,&res);/*подключается функция TEST_FUN2*/

codeerror=obdll_setfun3(ptr,"TEST_FUN3",userfun3,1,&res);/*подключается функция TEST_FUN3*/

codeerror=obdll_setfun3(ptr,"TEST_FUN4",userfun4,0,&res);/*подключается функция TEST_FUN4*/

 

codeerror=obdll_run(ptr,&te);/*запуск *.bas-программы*/

 

return codeerror;

}

 

При обнаружении в тексте *.bas-программы имени подключенной функции

исполняющая система Open Basic производит следующие действия:

 

 1. вычисляет все аргументы в текущем вызове *.bas-программы

 2. заполняет массивы descr*

 3. заполняет массивы par*

 4. заполняет указатель ob_obasic* ptr адресом текущего объекта Open Basic

 5. заполняет строку parstring

 6. передает управление пользовательской функции

 

 Пользовательская функция должна контролировать типы, количество и порядок следования параметров в текущем вызове.

 

3.8      Методы и перечисления класса ob_obasic для подключения и отключения пользовательских функций

 

3.8.7      Функции obdll_setfun1, obdll_setfun2, obdll_setfun3

 

obdll_type_codeerror OBDLL_SPEC obdll_setfun1(obdll_handler ptr,obdll_type_char* name,obdll_type_flofun f,int* res);/*res=result (logical)*/

 

obdll_type_codeerror OBDLL_SPEC obdll_setfun2(obdll_handler ptr,obdll_type_char* name,obdll_type_intfun f,int* res);

 

obdll_type_codeerror OBDLL_SPEC obdll_setfun3(obdll_handler ptr,obdll_type_char* name,obdll_type_charfun f,int flag,int* res);/*flag: 1-delete 0-not delete*/

 

Параметры:

 

1.    ptr - хендлер интерпретатора

2.    name - Basic-имя пользовательской функции

3.    f    - указатель на пользовательскую функцию

4.    dt   - тип размещения размещения в памяти возвращаемого значения (только для функций, возвращающих строку)

5.    res  - результат работы

 

Если функция с именем name ранее не была подключена, она подключается и возвращается res=0.

Если функция с именем name ранее была подключена, старая функция отключается, новая функция подключается и возвращается res=1.

 

новую и возвращает true.

 

Типы obdll_type_flofun, obdll_type_intfun, obdll_type_charfun это указатели на функции,

описанные в obd.h. Они отличаются типом возвращаемого значения.

 

3.8.8       Функция obdll_delfun

 

obdll_type_codeerror OBDLL_SPEC obdll_delfun(obdll_handler ptr,obdll_type_char* name,int* res);

 

Параметры:

 

1.                                                                            ptr  - хендлер интерпретатора

2.                                                                            name - Basic-имя пользовательской функции

3.                                                                            res  - результат работы

 

res=1 если функция успешно отключена

res=0 если такой функции не существует

 

3.9      Назначение параметров пользовательских функций

 

3.9.7       Общие сведения

 

 Интерфейс пользовательских функций Open Basic разработан для того, чтобы

обеспечить возможность контроля фактических параметров в вызове на этапе

исполнения программы.

 Для этого набор параметров пользовательских функций содержит две группы

массивов.

 Первая группа это три массива описаний параметров descrf, descri, descrc.

Эти массивы содержат информацию о количестве и порядке следования фактических

параметров в вызове пользовательской функции.

 Вторая группа это три массива значений параметров parf, pari, parc. Эти

массивы содержат значения фактических параметров в вызове пользовательской

функции.

 Назначение и структура массивов descr* и par* подробнее описана в следующем

разделе.

 

3.9.8      Параметры пользовательских функций

 

 Существуют три типа пользовательских функций. Все они имеют одинаковые

параметры и разный тип возвращаемого результата.

 

 Рассмотрим параметры пользовательских функций на примере Функции, возвращающей

значение с плавающей точкой.

 

obdll_type_flo name_flo(

obdll_handler ptr,                                       

const obdll_type_char* parstring,                       

const obdll_type_parnum *descrf,                        

const obdll_type_parnum *descri,                        

const obdll_type_parnum *descrc,                        

const obdll_type_flo* parf,                             

const obdll_type_int* pari,                             

const obdll_type_char* parc);

 

  Параметры:

 

1. obdll_handler ptr - хендлер интерпретатора, к которому

   подключена функция. Используется для доступа к переменным программы с

   помощью функций из библиотеки ob180_bcb60_*.dll.

 

2. const char* parstring - строковые представления параметров.

 

Пример:

 

   если в качестве параметров функции USER_FUN1 в ее вызове указано

   USER_FUN1(1.123,a_a%,1+2), то в массиве parstring будут находиться следующие

   строки: "1.123","a_a%","1+2".

   Эти строки будут лежать подряд, каждая строка будет заканчиваться нулевым

   байтом.

 

3.

   массивы описания параметров descr*:

 

   const ob_type_parnum *descrf - для параметров с плавающей точкой

   const ob_type_parnum *descri - для целых параметров

   const ob_type_parnum *descrc - для строковых параметров

 

   это массивы, описывающие количество, типы и местоположение всех параметров,

   переданных пользовательской функции из *.bas-программы. Используются для

   контроля количества, типа и порядка следования параметров в вызове

   пользовательской функции.

 

   Структура массива descrf(остальные - аналогично):

 

   descrf[0] - общее число параметров с плавающей точкой в текущем вызове

   Остальные элементы массива descrf(их количество равно descrf[0])

   это порядковые номера параметров с плавающей точкой в текущем вызове.

   Порядковые номера считаются с 1.

 

Пример:

   если в качестве параметров функции USER_FUN1 в ее

   вызове указано USER_FUN1(1.123,a_a%,1+2), то

   в массиве descrf будут находиться следующие числа:

   1,1

   в массиве descri будут находиться следующие числа:

   2,2,3

   в массиве descrc будут находиться следующие числа:

   0

 

Пример:

   если в качестве параметров функции USER_FUN1 в ее

   вызове указано USER_FUN1("str1","srt2"+"str3",1.1,1.2,1.3,1.4),

   то в массиве descrf будут находиться следующие числа:

   4,3,4,5,6

   в массиве descri будут находиться следующие числа:

   0

   в массиве descrc будут находиться следующие числа:

   2,1,2

 

4. массивы значений параметров parf, pari и parc:

 

   const ob_type_flo* parf  - для параметров с плавающей точкой

   const ob_type_int* pari  - для целых параметров

   const ob_type_char* parc - для строковых параметров

 

   это массивы, описывающие значения всех параметров соответствующих типов,

   переданных пользовательской функции в текущем вызове из *.bas-программы.

 

   Параметры лежат подряд, в массиве parc строки, как и в массиве parstring,

   отделяются нулевыми байтами.

 

Пример:

 

   (здесь и далее в описании [a_a%] это значение переменной с именем a_a%)

 

   если в качестве параметров функции USER_FUN1 в ее

   вызове указано USER_FUN1(1.123,a_a%,1+2), то

   в массиве parf будут находиться следующие числа:

   1.123

   в массиве pari будут находиться следующие числа:

   [a_a%],3

   в массиве parc не будет значений

 

Пример:

 

   если в качестве параметров функции USER_FUN1 в ее

   вызове указано USER_FUN1("str1","srt2"+"str3",1.1,1.2,1.3,1.4),

   то в массиве parf будут находиться следующие числа:

   1.1,1.2,1.3,1.4

   в массиве pari не будет значений

 

   в массиве parc будут находиться следующие строки:

   "str1","srt2str3"

 

 В файле ob.h содержится макрос OB_DECLFUNAPI(name,typeret), который можно

использовать для объявления пользовательских функций. Параметр name - это “native” имя

функции, параметр typeret - это тип возвращаемого значения.

 

 Максимальное число параметров определяется константой ob_maxnumpar в файле

ob.h.

 Для версии OB v1.80 ob_maxnumpar=64;.

 

 Используя массивы описания порядка следования параметров descr* и массивы

значений параметров par* пользователь может организовать контроль типов и

порядка следования параметров в текущем вызове пользовательской функции на

этапе выполнения программы.

 Анализ массивов descr* дает полную информацию о типах, количестве и порядке

следования параметров в текущем вызове пользовательской функции.

 

Пример:

 

 В пользовательскую функцию, вычисляющую синус передана в качестве параметра

строковая переменная.

 При этом массивы descrf, descri и descrc будут содержать значения:

 

descrf[0]=0

descri[0]=0

descrc[0]=1

 

Анализируя эту информацию, пользователь может совершить нужные ему действия,

например:

 

 1. генерировать пользовательское исключение

 2. подставить аргумент по умолчанию, например 0.

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

 4. попытаться преобразовать строку в число с помощью atof

 

 Для облегчения доступа к строковым данным Open Basic предоставляет функцию

 

const obdll_type_char*

OBDLL_SPEC obdll_getstringparam(

const obdll_type_parnum *descrc,

const obdll_type_char* parc,

const obdll_type_parnum i);

 

  Параметры:

 

  1. descrc - массив описания строковых параметров

  2. parc   - массив значений строковых параметров

  3. i      - номер строки, переданной в параметрах (нумерация с нуля)

 

 С помощью этой функции можно получить доступ к i-й строке, записанной в

строковые параметры или в имена пользовательской функции.

 Если i больше, чем descrc[0], то функция возвращает 0.

 Если descrc[0] равно нулю, то функция возвращает 0.

 

3.10Доступ из пользовательской функции к данным *.bas программы.

 

 Кроме возможности принять параметры из *.bas программы и передать в нее

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

*.bas-программы.

 Если в *.bas-программе используется переменная или массив, то пользовательская

функция может считывать и записывать эту переменную и элементы массива.

Пользовательская функция имеет средства проверки наличия переменной с заданным

именем в программе. Пользовательская функция имеет средства создания переменных

с заданным именем в таблице переменных *.bas-программы.

 Эти возможности реализованы в Open Basic с помощью методов, описанных в

следующем разделе.

 

3.11Методы и перечисления класса ob_obasic для доступа к данным Open Basic из пользовательских функций

 

 Методы этого раздела запускаются обычно в пользовательских функциях, поэтому

в примерах они запускаются с помощью указателя obdll_handler ptr. Такое имя во всех

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

 В общем случае методы этого раздела могут запускаются в любом месте пользовательской

программы, в которой используется интерпретатор. Например, после останова

*.bas-программы с помощью точки останова, можно распечатать значения переменных

и массивов. Можно перед началом работы программы создавать и инициализировать

некоторые переменные.

 

3.11.7 Методы и перечисления класса ob_obasic для определения типа переменных и массивов Open Basic

 

Для определения типа переменных и массивов Open Basic можно использовать правила имен Basic.

 

А именно:

 - если в имени последним символом является символ '%', то это переменная

   или массив целого типа.

 - если в имени последним символом является символ '$', то это переменная

   или массив строкового типа.

 - если в имени последним символом является любой другой символ, то это

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

 

Альтернативой этому методу является применение специальных функций, возвращающих код типа переменной или массива. Кроме типа переменной эти функции позволяют узнать наличие переменной или массива с заданным именем в таблицах Open Basic.

 

3.11.7.1    Функция obdll_typevar

 

Функция

 

obdll_type_codeerror OBDLL_SPEC obdll_typevar(obdll_handler ptr,obdll_type_char* name,int* ty);

 

- возвращает тип переменной с именем name.

 

Параметры:

 

1.    ptr  - хендлер интерпретатора

2.    name - имя Basic-переменной

3.    ty   – код типа переменной

 

 

ty=0 – переменная типа float

ty=1 - переменная типа int

ty=2 - переменная типа char*

ty=3 - переменная с таким именем не существует

 

3.11.7.2    Функция obdll_typearray

 

Функция

 

obdll_type_codeerror OBDLL_SPEC obdll_typearray(obdll_handler ptr,obdll_type_char* name,int* ty);

 

- возвращает тип массива с именем name.

 

Параметры:

 

1.    ptr  - хендлер интерпретатора

2.    name - имя Basic-переменной

3.    ty   – код типа массива (совпадает с кодом типа переменной)

 

ty=0 – массив переменных типа float

ty=1 - массив переменных типа int

ty=2 - массив переменных типа char*

ty=3 - массив с таким именем не существует

 

Пример: Если есть *.bas программа

 

        DIM array1%(10,10), array2$(10,10), array3(10,10)

        a%=10

        b$="string example"

        c=101.4

 

после выполнения этого участка Basic-кода применение этих функций даст следующие результаты:

 

obdll_type_codeerror codeerror;

obdll_handler ptr;

int te;

int res;

 

ptr=obdll_create();/*создается экземпляр интерпретатора*/

 

 obdll_typevar(ptr,"a%",&res);/*res=1*/

 obdll_typevar(ptr,"b$",&res);/*res=2*/

 obdll_typevar(ptr,"c",&res);/*res=0*/

 

 obdll_typearray(ptr,"array1%",&res);/*res=1*/

 obdll_typearray(ptr,"array2$",&res);/*res=2*/

 obdll_typearray(ptr,"array3",&res);/*res=0*/

 

В примере *.bas-программы нет переменной с именем VAR и массива с именем ARR.

Поэтому применение этих методов даст следующие результаты:

 

obdll_typevar(ptr," VAR ",&res);/*res=3*/

obdll_typearray(ptr," ARR ",&res);/*res=3*/

 

3.11.8 Функции для определения длины строковых переменных и элементов строковых массивов Open Basic

 

Функция

 

obdll_type_codeerror OBDLL_SPEC obdll_strlenvar(

obdll_handler ptr,

obdll_type_char* name,

obdll_type_stringsize* len,

obdll_type_arraysize* as,

int* ty);

 

определяет тип переменной и длину переменной или элемента массива с именем name.

 

 Параметры:

 

1.    ptr  - хендлер интерпретатора

2.    name - имя Basic-переменной

3.    len  - возвращаемый параметр. Для строковых переменных содержит длину строки без  завершающего нуля. Для переменных с плавающей точкой и целых содержит sizeof(obdll_type_float) и sizeof(obdll_type_int) соответственно.

4.    as   - индексы элемента массива, в случае если name имя массива.

5.    ty   – возвращаемый параметр. Содержит код типа переменной

 

Если name это имя переменной, указатель as должен быть равен нулю.

 

Функцию obdll_strlenvar можно вызывать для Basic-переменных или элементов

Basic-массивов.

 Для Basic-массивов есть 2 способа вызова функции obdll_strlenvar.

 

 1. С указанием текущих индексов в имени (параметр as=0)

 2. С указанием текущих индексов в параметре *as (параметр as!=0)

 

 Функция возвращает *ty=3 в случае ошибки задания имени, например если оно

начинается не с буквы или является именем не описанного на момент использования

массива или если переменная не существует. При нормальном завершении метод

возвращает тип переменной.

 Параметр *len для строковых переменных содержит длину строки без завершающего

нуля. Параметр *len для переменных с плавающей точкой и целых содержит

sizeof(obdll_type_float) и sizeof(obdll_type_int) соответственно.

 

Пример: Вызов функции obdll_strlenvar для элемента массива с указанием текущих

индексов в имени

 

Если есть *.bas программа:

 

        DIM array2$(10,10)

        array2$(5,5)="array string example"

 

после выполнения этого участка кода в пользовательских функциях, подключенных

к интерпретатору, применение функции obdll_strlenvar даст следующие результаты:

 

obdll_type_stringsize len;

obdll_handler ptr;

int ty;

 

ptr=obdll_create();/*создается экземпляр интерпретатора*/

 

obdll_strlenvar(ptr,"array2$(5,5)",&len,0,&ty);// ty=2 len==20

 

Пример: Вызов метода strlenvar для элемента массива с указанием текущих

индексов в параметре *as

 

Если есть *.bas программа:

 

        DIM array2$(10,10)

        array2$(5,5)="array string example"

 

после выполнения этого участка кода в пользовательских функциях, подключенных

к интерпретатору, применение метода strlenvar даст следующие результаты:

 

obdll_type_stringsize len;

obdll_handler ptr;

int ty;

obdll_type_arraysize as[]={5,5};

 

ptr=obdll_create();/*создается экземпляр интерпретатора*/

 

obdll_strlenvar(ptr,"array2$(5,5)",&len,as,&ty);/*ty=2 len==20*/

 

Пример: Вызов метода strlenvar для переменных

 

Если есть *.bas программа:

 

        DIM array1%(10,10), array3(10,10)

        a%=10

        b$="string example"

        c=101.4

 

после выполнения этого участка кода в пользовательских функциях, подключенных

к интерпретатору применение метода strlenvar даст следующие результаты:

 

obdll_type_stringsize len;

obdll_handler ptr;

int ty;

obdll_type_arraysize as[]={5,5};

 

ptr=obdll_create();/*создается экземпляр интерпретатора*/

 

obdll_strlenvar(ptr,"a%",&len,0,&ty);/* ident==OB_IDENTINT len==4*/

obdll_strlenvar(ptr,"b$",&len,0,&ty);/* ident==OB_IDENTSTR len==14*/

obdll_strlenvar(ptr,"c",&len,0,&ty); /* ident==OB_IDENTFLO len==4*/

 

3.11.9 Функции для определения размеров массивов Open Basic

 

Функция  

 

obdll_type_codeerror OBDLL_SPEC

obdll_getarraysize(obdll_handler ptr,

obdll_type_char* name,obdll_type_arraysize** as,obdll_type_arraydimension* kr);

 

Параметры:

 

1.    ptr  - хендлер интерпретатора

2.    name - имя массива

3.    as   - массив размеров каждого измерения. Он создается при описании массива оператором DIM. Этот параметр представляет собой внутренний буфер Open Basic и должен только читаться.

4.    kr  - количество измерений массива. Он заполняется методом getarraysize.

 

Пример:

 

 Массив описан оператором DIM Array_1(10,11,12).

 

Применение функции obdll_getarraysize.

 

obdll_handler ptr;

obdll_type_arraysize *sr;

obdll_type_arraydimension kr;

 

ptr=obdll_create();/*создается экземпляр интерпретатора*/

 

obdll_getarraysize(ptr,"Array_1",&sr,&kr);

 

После применения obdll_getarraysize kr=3, а указатель sr указывает на

массив {10,11,12}.

 

3.11.10           Функции для записи переменных Open Basic

 

Функции

 

obdll_type_codeerror OBDLL_SPEC

obdll_writevar1(obdll_handler ptr,obdll_type_char* name,obdll_type_flo val,obdll_type_arraysize* as,int* res);

 

obdll_type_codeerror OBDLL_SPEC

obdll_writevar2(obdll_handler ptr,obdll_type_char* name,obdll_type_int val,obdll_type_arraysize* as,int* res);

 

obdll_type_codeerror OBDLL_SPEC

obdll_writevar3(obdll_handler ptr,obdll_type_char* name,obdll_type_char* val,obdll_type_arraysize* as,int* res);

 

Параметры:

 

1.    ptr  - хендлер интерпретатора

2.    name - имя переменной или массива

3.    val  - значения, записываемые в переменные или элементы массива

4.    as   - индексы массива в случае если name имя массива и 0 в случае если name имя переменной

5.    res  -  возвращаемое значение. res=0, в случае ошибки задания имени, например если оно начинается не с буквы или является именем не описанного на момент использования массива. При нормальном завершении res=1

 

Функции obdll_writevarХХХ можно вызывать для Basic-переменных или элементов

Basic-массивов.

 

 Для Basic-массивов есть 2 способа вызова методов функций obdll_writevarХХХ.

 

 1. С указанием текущих индексов в имени (параметр as=0)

 2. С указанием текущих индексов в параметре *as (параметр as!=0)

 

 Методы записывают переменную с именем name в таблицу переменных и присваивают ей значение val.

 Если переменная не существует, то она создается.

 Производится проверка на тип имени, т.е. создается переменная соответствующая имени.

 Если тип присваиваемого значения не соответствует типу имени (например при попытке создать переменную целого типа со вторым аргументом ob_type_char* val), то функции возвращают код ошибки.

 Имя name может быть именем элемента массива. Тогда оно должно содержать индексы конкретного элемента по правилам Basic.

 Методы возвращают res=0 в случае ошибки задания имени, например если оно

начинается не с буквы или является именем не описанного на момент использования

массива. При нормальном завершении методы возвращают res=1.

 

Пример: Чтобы в пользовательской функции присвоить переменной VAR

        значение 10.4, нужно написать следующий код:

 

obdll_handler ptr;

int res;

obdll_type_codeerror codeerror;

 

ptr=obdll_create();/*создается экземпляр интерпретатора*/

 

codeerror=obdll_writevar1(ptr,"VAR",10.4,0,&res);

if(res==0) printf("\nerror in writevar");

 

Пример: Чтобы в пользовательской функции присвоить третьему элементу

        массива array_string$(10) значение "Hello world",

        нужно написать следующий код:

 

obdll_handler ptr;

int res;

obdll_type_codeerror codeerror;

 

ptr=obdll_create();/*создается экземпляр интерпретатора*/

 

codeerror=obdll_writevar3(ptr,"array_string$(3)","Hello world",0,&res);

if(res==0) printf("\nerror in writevar");

 

3.11.11           Функции для чтения переменных Open Basic

 

Функции

 

obdll_type_codeerror OBDLL_SPEC

obdll_readvar1(obdll_handler ptr,obdll_type_char* name,obdll_type_flo* val,obdll_type_arraysize* as,int* res);

 

obdll_type_codeerror OBDLL_SPEC

obdll_readvar2(obdll_handler ptr,obdll_type_char* name,obdll_type_int* val,obdll_type_arraysize* as,int* res);

 

obdll_type_codeerror OBDLL_SPEC

obdll_readvar3(obdll_handler ptr,obdll_type_char* name,obdll_type_char* val,obdll_type_arraysize* as,int* res);

 

 

 Параметры:

 

1.    ptr  - хендлер интерпретатора

2.    name - имя переменной или массива

3.    val  - значения, прочитанное из переменной или элемента массива

4.    as   - индексы массива в случае если name имя массива и 0 в случае если name имя переменной

5.    res  -  возвращаемое значение. res=0, в случае ошибки задания имени, например если оно начинается не с буквы или является именем не описанного на момент использования массива. При нормальном завершении res=1

 

 Функции obdll_readvarХХХ можно вызывать для Basic-переменных или элементов

Basic-массивов.

 Для Basic-массивов есть 2 способа вызова Функции obdll_readvarХХХ.

 

 1. С указанием текущих индексов в имени (параметр as=0)

 2. С указанием текущих индексов в параметре *as (параметр as!=0)

 

Функции считывают переменную с именем name из таблицы переменных в указатель val.

 Если переменная не существует, то она не создается.

 Имя name может быть именем элемента массива. Тогда оно должно содержать индексы конкретного элемента по правилам Basic.

 Функции возвращают res=0 в случае ошибки задания имени, например если оно начинается не с буквы или является именем не описанного на момент использования массива или переменная не существует. При нормальном завершении методы возвращают res=1.

 Если тип переменной и параметра val не совпадают (например при попытке

присвоить строковой переменной значение целого числа), функции возвращают код ошибки.

 

Пример: Чтобы в пользовательской функции считать значение переменной

        VAR1 в C++ переменную с именем val1, нужно написать следующий

        код:

 

obdll_handler ptr;

int res;

obdll_type_codeerror codeerror;

obdll_type_flo val1;

 

ptr=obdll_create();/*создается экземпляр интерпретатора*/

 

codeerror=obdll_readvar1(ptr,"VAR1",&val1,0,&res);

if(res==0) printf("\nerror in readvar");

 

Пример: Чтобы в пользовательской функции считать значение четвертого

        элемента массива array_string$(10), нужно написать следующий

        код:

 

obdll_handler ptr;

int res;

obdll_type_codeerror codeerror;

obdll_type_flo val1;

 

obdll_type_char buf[256];

obdll_type_char* pchar=buf;

 

ptr=obdll_create();/*создается экземпляр интерпретатора*/

 

codeerror=obdll_readvar3(ptr,"array_string$(4)",pchar,0,&res);

if(res==0) printf("\nerror in readvar");

 

3.11.12            Функции для создания и удаления переменных и массивов Open Basic

 

3.11.12.1  Функция для создания переменных Open Basic

 

Функция

 

obdll_type_codeerror OBDLL_SPEC obdll_createvar(obdll_handler ptr,obdll_type_char* name);

 

 

 Параметры:

 

1.    ptr  - хендлер интерпретатора

2.    name - имя Basic-переменной

 

 Создает переменную с именем name в таблице переменных интерпретатора. Тип переменной определяется по наличию в имени символов '%' и '$'.

 

3.11.12.2  Функция для создания массивов Open Basic

 

Функция

 

obdll_type_codeerror OBDLL_SPEC obdll_createarray(obdll_handler ptr,

obdll_type_char* name,obdll_type_arraydimension kr,obdll_type_arraysize* as);

 

Параметры:

 

1.    ptr  - хендлер интерпретатора

2.    name - имя Basic-массива

3.    kr   - количество измерений массива

4.    *as  - массив размеров каждого измерения

 

 Создает массив с именем name в таблице массивов интерпретатора. Если массив с

таким именем уже существует, он удаляется и создается заново с указанными

параметрами.

 Тип элементов создаваемого массива определяется по наличию в имени массива

символов '%' и '$'. Функция эквивалентна оператору DIM.

 

 Параметры аналогичны параметрам метода obdll_getarraysize.

 

Пример: Чтобы из пользовательской функции создать массив целых

        ARRAY1%(5,10,20), нужно написать следующий код:

 

obdll_handler ptr;

obdll_type_arraysize as[]={5,10,20};

obdll_type_codeerror codeerror;

 

ptr=obdll_create();/*создается экземпляр интерпретатора*/

 

codeerror=obdll_createarray(ptr,"ARRAY1%",3,as);

 

3.11.12.3  Функции для удаления переменных и массивов Open Basic

 

 Функции

 

obdll_type_codeerror OBDLL_SPEC obdll_clrtabl(obdll_handler ptr,int flag);/*1-overlay 0-nooverlay*/

 

obdll_type_codeerror OBDLL_SPEC obdll_clrtablfun(obdll_handler ptr);

 

Параметры:

 

1.    ptr  - хендлер интерпретатора

2.    flag – аналогичен режиму загрузки в функции obdll_load

 

Очищают таблицы интерпретатора.

 

Функция obdll_clrtabl имеет параметр flag, аналогичный параметру функции obdll_load.

Функция obdll_clrtabl не очищает таблицу пользовательских функций ни при каких

значениях параметра flag.

 Функция obdll_clrtablfun очищает таблицу пользовательских функций.

 

3.12Описание других функций библиотеки ob180_bcb60_*.dll

 

Функции

 

const obdll_type_char* OBDLL_SPEC obdll_about(void);

const obdll_type_char* OBDLL_SPEC obdll_aboutdll(void);

 

возвращают строку информации о программе интерпретатора и о DLL (ANSI-C надстройки над интерпретатором). Строка может содержать символы новой строки.

 

Пример:

 

printf("\n");

printf("%s",obdll_about());/*печать информации о программе*/

 

printf("\n");

printf("%s",obdll_aboutdll());/*печать информации о DLL*/

 

Функции

 

obdll_type_serialnum OBDLL_SPEC obdll_serial_number(void);

obdll_type_serialnum OBDLL_SPEC obdll_serial_numberdll(void);

 

возвращают серийный номер экземпляра программы интерпретатора и серийный номер DLL.

 

Функции

 

obdll_type_int OBDLL_SPEC obdll_version(void);

obdll_type_int OBDLL_SPEC obdll_versiondll(void);

 

возвращают номер текущей версии программы и номер текущей версии DLL, умноженные на 100. Для версии 1.80 метод возвращает 180.

 

3.13Операторы

 

 Операторы могут располагаться в одной строке и отделяться друг от друга

пробелами.

 Некоторые операторы, например DATA и PRINT должны быть единственными

операторами в строке, т.к. нужно явно ограничить список аргументов этих

операторов.

 При описании операторов символы в квадратных скобках означают необязательные

символы.

 

 Open Basic поддерживает следующие операторы:

 

3.13.7 Оператор PRINT

 

 Выводит в выводной поток, указанный при создании ob_obasic, список переменных.

 

 Формат оператора:

 

 [N] PRINT [#EXP,][LIST]

 

где

 N    - номер строки

 LIST - список элементов, представленных в виде констант, переменных, строковых

        или числовых выражений.

 EXP  - выражение, определяющее номер канала вывода, открытого оператором OPEN

 

 Оператор PRINT без списка элементов выводит символ новой строки.

 Если элементом списка является выражение, Open Basic вычисляет его и печатает

результат.

 

Пример:

 10 TT%=40

    TTT=101.3

 20 PRINT "TT%=";TT,"TTT=";TTT+0.3

 

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

 

 TT%=40       TTT=101.6

 

 Элементы списка отделяются друг от друга запятыми или точкой с запятой.

 Там, где элементы списка отделены запятыми, производится вывод символа

табуляции между элементами.

 Если в конце списка элементов стоит запятая или точка с запятой, то после

оператора PRINT не производится перевод строки.

 

3.13.8 Оператор INPUT

 

 Вводит из вводного потока, указанного при создании ob_obasic, данные.

 

 Формат оператора:

 

 [N] INPUT [#EXP,]VAR1,[VAR2,VAR3,...]

 

где

 N    - номер строки

 VAR1,[VAR2,VAR3,...] - список переменных

 EXP - выражение, определяющее номер канала ввода, открытого оператором OPEN

 

 Встретив оператор INPUT Open Basic вводит из потока данные, представленные в

числовой форме и присваивает их переменным из списка. Строковые данные в

потоке должны быть заключены в кавычки.

 

Пример:

10 TT%=40

   TTT=101.3

20 INPUT TT%,TTT

 

3.13.9 Операторы FOR и NEXT

 

 Позволяют организовать цикл так, что Open Basic автоматически проверяет

условие при каждом проходе.

 

 Формат оператора FOR:

 

 [N] FOR VAR=EXP1 TO EXP2 [STEP EXP3]

 

где

 N    - номер строки

 VAR  - управляющая переменная (индекс цикла)

 EXP1 - начальное значение индекса. Любое числовое выражение.

 EXP2 - конечное значение индекса. Любое числовое выражение.

 EXP3 - приращение величины индекса. Любое числовое выражение.

        может быть положительным или отрицательным. По

        умолчанию равен 1.

 

Управляющая переменная (индекс цикла) может быть элементом массива.

 

 Операторы FOR и NEXT используются только в паре. Оператор FOR определяет

начало цикла, оператор NEXT - конец цикла.

 

 Формат оператора NEXT:

 

 [N] NEXT VAR1

 

где

 N    - номер строки

 VAR1  - управляющая переменная, использованные в операторе FOR

 

 Если начальное значение переменной цикла больше конечного значения, то цикл

не выполняется.

 Передавать управление внутрь цикла недопустимо.

 Рекомендуется в качестве переменных цикла использовать целые переменные, во

избежании ошибок округления.

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

внешнего.

 Оператор FOR имеет некоторые особенности выполнения. Они связаны с тем, что

Open Basic это интерпретатор. При входе в цикл производится проверка условия

цикла. Если условие цикла не выполняется, цикл не будет выполнен ни разу.

В этом случае производится поиск соответствующего оператора NEXT и передача

управления ему. При этом не учитываются возможные ветвления алгоритма

операторами GOTO.

 

Пример:

 

   GOTO 30

10

   NEXT i%

   GOTO 20

 

30 FOR i%=10 TO k% STEP 1

 

   GOTO 10

 

 

20

   STOP

   END

 

Этот пример будет работать, если k% больше 10. Но если это не так, то

произойдет аварийный останов.

 

Пример:

 

 FOR i%=1 TO 3

  FOR ii%=4 TO 1 STEP -2

   PRINT "Work FOR operator","ii%=";ii%,"i%=";i%

  NEXT ii%

 NEXT i%

 

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

 

Work FOR operator       ii%=4   i%=1

Work FOR operator       ii%=2   i%=1

Work FOR operator       ii%=4   i%=2

Work FOR operator       ii%=2   i%=2

Work FOR operator       ii%=4   i%=3

Work FOR operator       ii%=2   i%=3

 

Пример:

 

FOR i%=1 TO 3

  FOR ii%=4 TO 1 STEP -2

    PRINT "Work FOR operator","ii%=";ii%,"i%=";i%

  NEXT ii%

NEXT i%

 

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

 

Work FOR operator       ii%=4   i%=1

Work FOR operator       ii%=2   i%=1

Work FOR operator       ii%=4   i%=2

Work FOR operator       ii%=2   i%=2

Work FOR operator       ii%=4   i%=3

Work FOR operator       ii%=2   i%=3

 

3.13.10            Оператор GOTO

 

 Вызывает непосредственный переход к указанной строке с нарушением

естественного порядка выполнения операторов программы.

 

 Формат оператора:

 

 [N] GOTO line_number

 

где

 N    - номер строки

 line_number - номер строки, к которой осуществляется переход

 

Пример:

20 GOTO 50

   PRINT "This operator do not work in example"

50 PRINT "Work GOTO operator"

 

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

 

Work GOTO operator

 

3.13.11            Операторы GOSUB и RETURN

 

 Осуществляют связь программы с подпрограммой.

 

 Формат оператора:

 

 [N] GOSUB line_number

 

где

 N    - номер строки

 line_number - номер строки, к которой осуществляется переход

 

 Встретив в программе оператор GOSUB, Open Basic передает управление строке,

заданной в операторе GOSUB. Программа продолжает выполняться с этой строки.

Когда встретится оператор RETURN управление передается строке, следующей за

строкой с оператором GOSUB.

 

 Операторы GOSUB и RETURN используются только в паре.

 

 Формат оператора RETURN:

 

 [N] RETURN

где

 N    - номер строки

 

 Подпрограммы можно вкладывать друг в друга.

 

Пример:

 

   GOSUB 10

   GOTO 100

 

10

   PRINT "Work GOSUB operator 1"

   GOSUB 20

   PRINT "Work GOSUB operator 2"

   RETURN

20

   PRINT "Work GOSUB operator 3"

   PRINT "Work GOSUB operator 4"

   RETURN

  

100

 

   STOP

   END

 

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

 

Work GOSUB operator 1

Work GOSUB operator 3

Work GOSUB operator 4

Work GOSUB operator 2

 

3.13.12            Оператор LET

 

 Оператор присваивает значение переменной.

 

 Формат оператора:

 

 [N] [LET] VAR=EXP

 

где

 N    - номер строки

 LET  - необязательное имя оператора

 VAR  - переменная, принимающая новое значение

 EXP  - выражение, определяющее новое значение

 

Пример:

 

 20 LET a=100.1

    PRINT "Work LET operator","a=";a

 

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

 

 Work LET operator   a=100.1

 

3.13.13            Оператор DIM

 

 Оператор резервирует место для числового или строкового массива.

 

 Формат оператора:

 

 [N] DIM LIST

 

где

 N    - номер строки

 LIST - список имен массивов, разделенный запятыми

 

 Массивы в Open Basic могут быть любой размерности и объема. В связи с тем, что

место под них резервируется оператором C++ 'new', ограничения на размер связаны

с особенностями реализации этого оператора на конкретной платформе. Например в

MS DOS 'new' не запрашивает более 64К байт. Поэтому в MS DOS Open Basic общий

размер массива не может быть больше 64К байт, при этом количество измерений

также не может превышать 64К байт.

 

 Массивы в Open Basic могут менять размерность. При повторном описании уже

описанного массива, он уничтожается и создается вновь, возможно уже с новыми

размерностями и размером.

 При создании числовые массивы инициализируются нулем. Строковые массивы

инициализируются пустой строкой.

 Тип создаваемого массива определяется по правилам определения типа переменной,

по наличию в имени символов % и $.

 

Пример:

 DIM a%(2,2,3),b(3,2,4)

 DIM a$(2,2,3,2)

 

 a$="variable string"

 a$(1,1,3,2)="array string"

 a%(2,2,3)=10

 b(1,1,1)=101.1

 

 

 PRINT a$(1,1,3,2)

 PRINT a$

 PRINT "a%=";a%

 PRINT "b=";b

 

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

 

 array string

 variable string

 a%=10

 b=101.1

 

3.13.14            Операторы STOP и END

 

 Операторы используются для завершения работы программы.

 Оператор STOP вызывает очистку всех таблиц Open Basic - переменных, массивов

и т.д.

 Оператор END также вызывает очистку всех таблиц Open Basic и дополнительно

выставляет внутренний флаг останова. Сброс этого флага производится в методе

ob_obasic::load.

 Операторы не вызывают очистку таблицы пользовательских функций.

 Если программа имеет оверлейную структуру и последующие ее части загружаются

методом load с параметром OVERLAY и используют таблицы переменных предыдущих

частей, то операторы STOP и END должны стоять только в конце последней части

программы.

 

 Формат операторов:

 

 [N] STOP

 [N] END

 

где

 N    - номер строки

 

Пример:

   PRINT "example STOP and REM operator"

10 STOP

20 END

 

3.13.15            Оператор REM

 

 Вводит комментарии в программу.

 

Формат оператора:

 

 [N] REM COMMENT

 

где

 N    - номер строки

 COMMENT - текст комментария

 

 Операторы REM и пустые строки увеличивают время выполнения программы и

занимают место в памяти.

 

Пример:

 

 10 REM this text is comment

 

3.13.16            Операторы OPEN и CLOSE

 

 Оператор OPEN открывает файл. Оператор CLOSE закрывает файл.

 

 Формат оператора OPEN:

 

[N] OPEN filename FOR INPUT  AS FILE #EXP

[N] OPEN filename FOR OUTPUT AS FILE #EXP

 

где

 N    - номер строки

 filename - имя файла

 EXP - выражение, которое вычисляется и приводится к целому типу. Обычно

       используют константы.

 AS FILE - ключевые слова

 

 Оператор OPEN FOR INPUT открывает файл для чтения.

 Оператор OPEN FOR OUTPUT открывает файл для записи.

 

 Формат оператора CLOSE:

 

 [N] CLOSE #EXP1,[#EXP1,#EXP2,...]

 

где

 N    - номер строки

 EXP - выражение, которое вычисляется и приводится к целому типу. Обычно

       используют константы.

 

Пример:

 

   k%=10

 

   OPEN "F000.TXT" FOR OUTPUT AS FILE #k%+1

   OPEN "F001.TXT" FOR OUTPUT AS FILE #k%+2

 

   FOR i%=1 TO KOL% STEP 1

     PRINT "i%=",i%

     PRINT #k%+1,i%

     f=i%+0.1

     PRINT #k%+2,f

   NEXT i%

 

   CLOSE #k%+1

   CLOSE #k%+2

 

   OPEN "F000.TXT" FOR INPUT AS FILE #k%+2

   OPEN "F001.TXT" FOR INPUT AS FILE #k%+3

 

   FOR i%=1 TO KOL% STEP 1

     INPUT #k%+2,ii%

     INPUT #k%+3,ff

     PRINT "ii%=",ii%

     f=i%+0.1

     IF ii%<>i% THEN PRINT " Error test OPEN-CLOSE command" GOTO 10

     IF ff<>f THEN PRINT " Error test OPEN-CLOSE command" GOTO 10

   NEXT i%

 

   CLOSE #k%+2

   CLOSE #k%+3

 

10 STOP

   END

 

3.13.17            Оператор KILL

 

 Удаляет файл.

 

 Формат оператора:

 

 [N] KILL STR1[,STR2,STR3,...]

 

где

 N    - номер строки

 STR1, STR2 ,STR3  - имена файлов

 

Пример:

 

 10 KILL "F000.TXT","F001.TXT"

 

3.13.18            Операторы READ, DATA и RESTORE

 

 Операторы READ и DATA используются для организации блока данных, который

считывается интерпретатором Open Basic во время выполнения программы.

 

 Формат оператора READ:

 

 [N] READ VAR1[,VAR2,VAR3,...]

 

где

 N    - номер строки

 VAR1,VAR2,VAR3 - переменные, которым присваиваются значения из списка

 оператора DATA

 

 Формат оператора DATA:

 

[N] DATA EXP1,[EXP1,EXP2,...]

 

где

 N    - номер строки

 EXP1,EXP2,EXP3, - выражение, которое вычисляется и

 присваивается переменной из списка READ. Могут быть числовыми

 или строковыми. Обычно используют константы.

 

 Формат оператора RESTORE:

 

 [N] RESTORE

 

где

 N    - номер строки

 

 Перед выполнением программы Open Basic просматривает все операторы DATA в

порядке их появления и создает блок данных. Каждый раз, когда в программе

встречается оператор READ, блок данных выдает последовательно соответствующее

значение для переменных этого оператора в том порядке, в котором они заданы

в блоке данных.

 После выполнения оператора READ положение последних считанных данных

запоминается. Следующий оператор READ начинает выбирать данные с той позиции,

которая была установлена предыдущим оператором READ.

 Open Basic осуществляет повторное чтение одних и тех же данных с помощью

оператора RESTORE.

 Оператор DATA должен быть единственным оператором в строке.

 

Пример:

 

 DATA 1.1,2,3,4,"1 string for data"

 DATA 5.1,6,7,4+4,"2 string for data"

 

 DIM z%(3)

 

 READ a2,z%(1),z%(2),z%(3),e2$

 

 READ a,b%,c%,d%,e$

 PRINT "a=";a;" b%=";b%;" c%=";c%;" d%=";d%;" e$=";e$

 READ a1,b1%,c1%,d1%,e1$

 PRINT "a1=";a1;" b1%=";b1%;" c1%=";c1%;" d1%=";d1%;" e1$=";e1$

 RESTORE

 READ a1,z%(1),z%(2),z%(3),e1$

 PRINT "a1=";a1;" z%(1)=";z%(1);" z%(2)=";z%(2);" z%(3)=";z%(3);

 PRINT " e1$=";e1$

 

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

 

 a=1.1 b%=2 c%=3 d%=4 e$=1 string for data

 a1=5.1 b1%=6 c1%=7 d1%=8 e1$=2 string for data

 a1=1.1 z%(1)=2 z%(2)=3 z%(3)=4 e1$=1 string for data

 

3.13.19            Оператор RANDOMIZE

 

 Инициализирует случайный генератор новым значением. В качестве нового значения

используется текущее системное время в секундах. Поэтому повторно оператор

RANDOMIZE нужно применять не раньше, чем через 1 секунду после его предыдущего

применения.

 

 Формат оператора:

 

[N] RANDOMIZE

 

где

 N    - номер строки

 

 Оператор RANDOMIZE помещается перед первым использованием функции случайных

чисел (функция RND). При выполнении функции RND оператор RANDOMIZE изменяет

начальное значение случайного числа таким образом, что при последующем проходе

функция RND дает другие числа.

 

Пример:

 

 10 RANDOMIZE

 

3.13.20            Оператор IF.

 

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

блочный и блочный укороченный.

 

Строковый формат оператора IF:

 

 [N] IF REL-EXP THEN operators

 

где

 N    - номер строки

 THEN - ключевое слово

 REL-EXP - проверяемое условие. Выражение отношения может быть арифметическим

или строковым.

operators - оператор или группа операторов

 

 Если условие REL-EXP истинно, то выполняются операторы в строке за ключевым

словом THEN, если условие ложно, то выполняется оператор в следующей за

оператором IF строке.

 

Пример:

   TT%=40

20 IF TT%=40 THEN GOTO 50

   PRINT "This operator do not work in example"

50 PRINT "Work IF operator","TT%=";TT%

 

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

 

 Work IF operator         TT%=40

 

Пример:

 

   TT%=40

   IF TT%=40 THEN PRINT "Work IF operator","TT%=";TT% GOTO 10

   PRINT "This operator do not work in example"

10 PRINT "Work IF operator","TT%=";TT%

 

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

 

Work IF operator         TT%=40

Work IF operator         TT%=40

 

Пример:

 

   TT%=40

   IF TT%=40 THEN a=101.1 b=102.1 c=103.1 GOTO 10

   a=1101.1 b=1102.1 c=1103.1

   PRINT "This operator do not work in example"

10 PRINT "a=";a,"b=";b,"c=";c

 

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

 

 a=101.1   b=102.1   c=103.1

 

Блочный формат оператора IF:

 

 [N] IF REL-EXP THEN

      operators1

     ELSE

      operators2

     ENDIF

 

где

 N    - номер строки

 THEN - ключевое слово

 REL-EXP - проверяемое условие. Выражение отношения может быть арифметическим

или строковым.

operators - оператор или группа операторов

 

 Если условие REL-EXP истинно, то выполняются операторы в блоке между ключевыми

словами THEN и ELSE. Если условие REL-EXP ложно, то выполняются операторы в

блоке между ключевыми словами ELSE и ENDIF.

 

Блочный укороченный формат оператора IF:

 

 [N] IF REL-EXP THEN

      operators1

     ENDIF

 

где

 N    - номер строки

 THEN - ключевое слово

 REL-EXP - проверяемое условие. Выражение отношения может быть арифметическим

или строковым.

operators - оператор или группа операторов

 

 Если условие REL-EXP истинно, то выполняются операторы в блоке между ключевыми

словами THEN и ENDIF. Если условие REL-EXP ложно, то выполняется оператор в

следующей за ключевым словом ENDIF строке.

 

3.14Встроенные функции

 

3.14.7 Функция SGN%

 

 Функция SGN% - функция знака.

 

Формат: SGN%(EXP)

 

где EXP - целое или выражение с плавающей точкой.

 

Функция возвращает +1 если EXP>0, -1 если EXP<0 и 0 если EXP=0.

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

 

Пример:

 

 PRINT "This is example SGN function"

 PRINT "<0";SGN%(-1-2);" >0";SGN%(2*3);" =0";SGN%(9+1-10)

 

3.14.8 Функция ABS

 

 Функция ABS - определяет абсолютное значение аргумента.

 

Формат: ABS(EXP)

 

где EXP - целое или выражение с плавающей точкой.

 

Функция возвращает результат с плавающей точкой, даже при целом аргументе.

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

 

Пример:

 

 PRINT "This is example ABS function"

 PRINT "abs(-20.5)=";ABS(-20.5);" abs(20.5)=";ABS(20.5)

 

3.14.9 Функция INT%

 

 Функция INT% - определяет целую часть аргумента.

 

Формат: INT%(EXP)

 

где EXP - целое выражение с плавающей точкой.

 

Функция возвращает целый результат.

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

 

Пример:

 

 PRINT "This is example INT% function"

 PRINT "int(-20.3)=";INT%(-20.3);" int(20.3)=";INT%(20.3)

 

3.14.10            Функции SIN, COS, ATN, SQR, EXP, LOG и LOG10

 

 Функции вычисляют синус, косинус, арктангенс, квадратный корень, экспоненту,

логарифм, и десятичный логарифм соответственно.

 

Форматы:

 SIN(EXP),

 COS(EXP),

 ATN(EXP),

 SQR(EXP),

 EXP(EXP),

 LOG(EXP),

 LOG10(EXP)

 

где EXP - целое или выражение с плавающей точкой.

 

Функции возвращают результат с плавающей точкой.

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

 

Пример:

 

 PRINT "This is example trigonometric function"

 a=SIN(3.14/2)

 b=COS(0)

 c=ATN(1)

 d=SQR(4.0)

 e=EXP(1)

 f=LOG(EXP(1))

 g=LOG10(10)

 PRINT "a=";a;" b=";b;" c=";c;" d=";d;" e=";e;" f=";f;" g=";g

 

3.14.11            Функция RND

 

 Функция RND - генерирует псевдослучайное число в интервале 0-1.

 

Формат: RND().

 

Функция возвращает результат с плавающей точкой.

Аргументы игнорируются.

 

Пример:

 

 PRINT "This is example RND function"

 PRINT RND(),RND(),RND(),RND();

 RANDOMIZE

 PRINT RND(),RND(),RND(),RND();

 

3.14.12            Функция LEN%

 

 Функция LEN% - определяет длину строки.

 

Формат: LEN%(EXP)

 

где EXP - строковое выражение.

 

Функция возвращает целый результат.

Если аргумент задан неверно(целый или с плавающей точкой), то генерируется

ошибка.

 

Пример:

 

 PRINT "This is example LEN function"

 STRing_this$="aaa bbb ccc ddd"

 PRINT "len=";LEN%(STRing_this$)

 

3.14.13            Функции DAT$ и CLK$

 

 Функции возвращают дату и время соответственно.

 

Форматы:

 

DAT$(),

CLK$()

 

Функции возвращает строковый результат.

Аргументы игнорируются.

 

Формат даты: day-month-year

Формат времени: hour:min:sec

 

Пример:

 

 PRINT "This is example DAT$ & CLK$."

 PRINT "data=";DAT$;" time=";CLK$

 

3.14.14            Функции D2STR$, D2HEXSTR$, STR2FLOAT и STR2INT%

 

 Функция D2STR$ - конвертирует число в строку с его десятичным представлением

 

Формат: D2STR$(EXP)

 

где EXP - целое число или число с плавающай точкой

 

Функция возвращает строковый результат.

 

 Функция D2HEXSTR$ - конвертирует целое число в строку с его шестнадцатеричным

представлением

 

Формат: D2HEXSTR$(EXP)

 

где EXP - целое число

 

Функция возвращает строковый результат.

 

 Функция STR2FLOAT - конвертирует строку в число

 

Формат: STR2FLOAT(EXP)

 

где EXP - строка

 

Функция возвращает число с плавающай точкой. Если строка не может быть

конвертирована в число, возвращается ноль.

 

 Функция STR2INT% - конвертирует строку в целое число

 

Формат: STR2INT%(EXP)

 

где EXP - строка

 

Функция возвращает целое число. Если строка не может быть конвертирована в

целое число, возвращается ноль.

 

Пример:

 

 PRINT "converter from digit to string =";D2STR$(123)

 PRINT "converter from string to float =";STR2FLOAT("1.234")

 PRINT "converter from string to int =";STR2INT%("1234")

 PRINT "converter from digit to hex string =";D2HEXSTR$(4660)

 

 

3.15Обработка ошибок

 

При обнаружении ошибки функции из библиотеки ob180_bcb60_*.dll возвращают код ошибки. Используя функцию

 

const obdll_type_char* OBDLL_SPEC obdll_getmessage(obdll_type_codeerror code);

 

пользователь может получить текстовое сообщение, соответствующее коду ошибки.

 

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

 Чтобы получить строку, в которой произошла ошибка, надо воспользоваться функцией obdll_loadbreakstr или obdll_getinputptr.

 

При нормальном завершении функции из библиотеки ob180_bcb60_*.dll возвращают ноль.

 

Более подробно обработку ошибок можно посмотреть в файле .\exampled\ob.cpp.

 

3.16Таблица диагностических сообщений

                

 Ниже приведен список диагностических сообщений:

 

"End programm OK",//0 - нормальное завершение программы

 

"Divide by zero", //1 - деление на ноль

 

"Incompatible operand for this operation",//2 - несовместимые операнды

(например строковые и числовые в арифметической операции)

 

"Sintax error",//3 - синтаксическая ошибка

 

"Missing ')'",//4 - пропущена правая скобка (возможно слишком много

аргументов в функции или размерностей в массиве)

 

"Missing primary",//5 - ожидается в этом месте программы примитив.

 

"Too long name or string",//6 - слишком длинная строка или имя переменной

 

"Use variable before definition",//7  - использование переменной

в правой части оператора присвоения до использования ее в левой части.

 

"Missing '='",//8  - ожидается в этом месте программы знак присвоения.

 

"Error read input stream",//9 - ошибка чтения из входного потока.

 

"Duplicate label in program",//10 - метка описана в программе дважды.

 

"System error. Please contact your dealer",//11 - не используется

 

"Label not present in GOTO or GOSUB",//12 - в таблице меток не найдена

метка, на которую ссылается оператор GOTO.

 

"Missing compare operator in operator IF",//13- в операторе IF

ожидается символ выражения отношения (<,>,<=, и.т.д.).

 

"Missing keyword THEN in operator IF",//14 - в операторе IF

ожидается ключевое слово THEN.

 

"System error. Please contact your dealer",//15 - не используется

 

" System error. Please contact your dealer",//16 - не используется

 

"Not GOSUB operator for this RETURN operator",//17 - при работе

программы найден оператор RETURN, однако стек входов в подпрограммы пуст.

 

"Counter parameter of FOR operator must be variable or array element",//18

 - в операторе FOR ожидается имя переменной или элемента массива в качестве

   счетчика цикла.

 

"Missing keyword TO in operator FOR",//19 - в операторе FOR

ожидается ключевое слово TO.

 

"System error. Please contact your dealer",//20 - не используется

"System error. Please contact your dealer",//21 - не используется

"System error. Please contact your dealer",//22 - не используется

 

"Error in parameters built-in function",//23  - ошибка при разборе параметров

функции.

 

"Missing name array in DIM operator",//24 - в операторе DIM

ожидается имя массива с размерностями.

 

"System error. Please contact your dealer",//25  - не используется

 

"Too many array dimension",//26 - у массива слишком много измерений.

 

"Missing ',' in DIM operator to separate value",//27 - в операторе

DIM ожидается запятая при разделении имен массивов.

 

"System error. Please contact your dealer",//28 - не используется

 

"Size of array is negative or zero",//29 - нулевой или

отрицательный размер массива.

 

"System error. Please contact your dealer",//30 - не используется

 

"Size of array is zero",//31 - нулевой размер массива.

 

"Current index of array too big",//32 - дополнительный контроль к ошибке 59

 

"Missing keyword FOR in operator OPEN",//33 - в операторе OPEN

ожидается ключевое слово FOR.

 

"Missing mode opened file in operator OPEN",//34 - в операторе OPEN

ожидаются ключевые слова режима открытия файла.

 

"Missing keyword 'AS' or 'FILE' or '#' in operator OPEN",//35   - в

операторе OPEN ожидаются ключевые слова AS FILE.

 

"System error. Please contact your dealer",//36 - не используется

"System error. Please contact your dealer",//37 - не используется

 

"File not open",//38 - файл не открыт.

 

"System error. Please contact your dealer",//39 - не используется

"System error. Please contact your dealer",//40 - не используется

 

"Too many parameters in call function",//41 - слишком много

параметров в вызове функции.

 

"System error. Please contact your dealer",//42 - не используется

"System error. Please contact your dealer",//43 - не используется

"System error. Please contact your dealer",//44 - не используется

"System error. Please contact your dealer",//45 - не используется

"System error. Please contact your dealer",//46 - не используется

"System error. Please contact your dealer",//47 - не используется

"System error. Please contact your dealer",//48 - не используется

"System error. Please contact your dealer",//49 - не используется

 

"Unary minus can not use for string type",//50 - попытка применить операцию

унарного минуса к строковой переменной

 

"Compare with zero can not use for string type",//51 - попытка применить

операцию сравнения с нулем к строковой переменной

 

"Arithmetic operator can not use for string type",//52 - попытка применить

арифметическую операцию к строковой переменной

 

"Can not compare string and digital type",//53 - попытка применить

операцию сравнения с числом к строковой переменной

 

"Error format of float number (is two point in float number)",//54 - ошибка

формата константы с плавающей точкой

 

"Error format of hex number",//55 - ошибка формата шестнадцатеричной константы

 

"Error format of number (is point and 'x' letter in hex number)",//56

 - ошибка формата шестнадцатеричной константы

 

"String do not have right quote",//57 - не найдена правая кавычка в строковой

константе

 

"Current count dimension of array is not equal that DIM operator",//58 -

количество размерностей в текущем обращении к массиву не равно количеству

размерностей в операторе DIM

 

"One or many current dimension of array is too big",//59 - попытка обратится к

элементу массива с номером большим, чем он описан в операторе DIM.

Например, DIM a%(10,20) а обращение a%(5,21).

 

"System error. Please contact your dealer",//60 - не используется

"System error. Please contact your dealer",//61 - не используется

"System error. Please contact your dealer",//62 - не используется

"System error. Please contact your dealer",//63 - не используется

 

"Do not clear left in primary (debug error)",//64 - отладочная информация.

Не должна появляться при нормальной работе

 

"Do not clear left in run user function (debug error)",//65 - отладочная

информация. Не должна появляться при нормальной работе

 

"Do not found NEXT operator for FOR operator",//66 - не найден оператор NEXT

для текущего оператора FOR

 

"System error. Please contact your dealer",//67 - не используется

"System error. Please contact your dealer",//68 - не используется

 

"Parameter of NEXT operator must be variable or array element",//69

 - в операторе NEXT ожидается имя переменной или элемента массива в качестве

   счетчика цикла.

 

"Do not found ELSE or ENDIF operator for IF operator",//70 - не найдены ключевые

слова ELSE или ENDIF для текущего оператора IF

 

"Do not found FOR operator for this NEXT operator",//71 - не найден оператор FOR

для текущего оператора NEXT

 

"Need '(' in DIM operator or array use"//72 - не найдена левая скобка после

имени массива в операторе DIM

 

"Can not cast float to string"//73 - попытка приведения числа к строке

 

"Can not cast int to string"//74 - попытка приведения числа к строке

 

"Can not cast string to float"//75 - попытка приведения строки к числу

 

"Can not cast string to int"//76 - попытка приведения строки к числу

 

"Index of array must not be zero"//77 - текущий индекс массива равен нулю

 

"Do not clear ptr in setptr for savewrapper (debug error)",//78 - отладочная

информация. Не должна появляться при нормальной работе

 

"Array dimention less than zero",//79 - текущий индекс массива меньше нуля

 

"Error file name format in OPEN operator",//80 - ошибка имени файла

(возможно пустая строка)

 

"Error wrire to output stream",//81 - ошибка записи в выходной файл в

операторе PRINT