Copyright
(C) 1998-2010 MKTMK
http://www.mktmk.narod.ru.
e-mail:
mktmk<at>narod.ru
Interpreter
Open Basic.
User’s
manual.
Version
1.90.
Table of contents
History of changes and bugs fixed
List of files for distribution
1. Task description and program purpose
3.1. General information. Using of interpreter. Loading and
running of *.bas programs.
3.2. Technical solutions review
3.3. Input-output system review
3.4. ob_obasic class methods and enumerations used for *.bas
programs loading and running
3.4.5. set_current_input_stream method
3.4.6. get_current_input_stream
method
3.5.5. ob_loadbreakstr function
3.6.2. setoperatorbreak and getoperatorbreak methods
3.6.3. setin and setout methods
3.6.4. ob_lex::typelex enumeration
3.6.5. gettypenextlex and restoreinputpointer methods
3.7. Open Basic language syntax. General information
3.8. Open Basic data types, names and labels
3.9. User –defined
functions in Open Basic.
3.9.1. Type of returned value for user-defined function
3.9.2. Prototypes used for user-defined function
3.9.3. User-defined functions arguments
3.9.4. Argument arrays structure
3.9.5. Choosing of Basic-name for user-defined function
3.9.6. Attaching of user-defined function to
3.10.1. ob_type_del enumeration
3.11. Access to *.bas program data from user-defined function
3.12.1.1. Enumeration ob_type_ident
3.12.3. Methods of ob_obasic class used for determining of Open
Basic arrays sizes
3.12.4. Methods of ob_obasic class used for writing of Open Basic
variables
3.12.5. Methods of ob_obasic class used for reading of Open Basic
variables
3.12.6. Methods of ob_obasic class used for creating and deleting
of Open Basic variables and arrays
3.12.6.1. Methods of ob_obasic class used for creating of Open
Basic variables
3.12.6.2. Methods of ob_obasic class used for creating of Open
Basic arrays
3.13. Description of other methods of ob_obasic class
3.14. Operators used in Open Basic
3.14.3. FOR and NEXT operators
3.14.5. GOSUB and RETURN operators
3.14.8. STOP and END operators
3.14.10. OPEN and CLOSE operators
3.14.12. READ, DATA and RESTORE operators
3.15.4. SIN, COS, ATN, SQR, EXP, LOG and LOG10 functions
3.15.7. DAT$ and CLK$ functions
3.15.8. D2STR$, D2HEXSTR$, STR2FLOAT and STR2INT% functions
3.17. Diagnostic messages table
Open
Basic (
User-defined functions can be written on
C/C++ programming language and also on assembler or other languages.
User-defined functions can be activated from Basic program, receive parameters
of different types from Basic program
and return their work results to Basic program.
The specially developed user-defined
functions calling interface allows to determine type of parameters and their
sequence during program execution.
-
floating
point data
-
signed
integer data
-
string
data
Also
The following points are described in this
document:
- using of Open Basic interpreter
- syntax of Open Basic operators
- user-defined functions interface for Open Basic data accessing
- rules for user-defined functions attaching
- Open
Basic data types
- debugging options
Copyright
(C) 1998-2010 MKTMK
http://www.mktmk.narod.ru.
E-mail:
mktmk<at>narod.ru
MKTMK
software company,
If you plan to use this interpreter and want
to receive information about release of new versions or our E-mail/web address
possible changes please contact us by E-mail.
MKTMK software company is interested in the
interpreter application experience. The following optional information provided
by you will be useful for our software product maintenance:
- tasks you use the interpreter for
- your compiler and its version number
- bugs found in the program
- documentation comprehension and mistakes
found in it
- whether you have attached user-defined
functions and your experience of this process
- your commentary on user-defined functions
interface
- operating system that you use
- information source where you found
information about our interpreter
The interpreter and its documentation are
provided on “as is”. MKTMK company is not responsible for possible damage or
loss caused by usage of the interpreter.
We will appreciate any information provided
by you about bugs and mistakes found in the program.
All trademarks mentioned in this document are
property of their respective owners.
03.jan.2010
– version 1.90 for Windows
1.
Fixed
bug with processing of REM operator
during file loading. During commenting on string label with colon the bug
caused program infinite looping during load_project
method execution.
2.
Added
option to create projects from multiple files. The option is possible due to
two new added methods - clear_project
and load_project – which allow
multiple *.bas files loading. GOTO
operators can be used for jumping between the project files and GOSUB operators can be used for calling
between the project files. All labels and variables of the project are avaiable
to any module.
3.
Added
option of GOTO and GOSUB usage for jumping to label placed
in other file.
4.
Added
restriction on maximum number of GOSUB
nested calls. The maximum number of nested calls by default is 4096. The
maximum number can be changed by using set_max_nested_gosub
or get_max_nested_gosub functions.
5.
Added
new mechanism of user code running before and after specified operator. Previously
used mechanism of user code running was based on interrupt of run method
execution. New mechanism is based on
usage of functors and allows reducing of amount of code required for
input-output process arrangement. Previously used mechanism of user code
running is now considered out-of-date and is used for compatibility with
already existing code. This mechanism will be removed from future versions of
the interpreter and therefore is not recommended for use in new development
projects. For further information please refer to setoperatorbreak and getoperatorbreak methods description in this
document.
18.feb.2007
– version 1.80 for Windows and Linux
1.
Fixed
bug in array indexing by array element.
2.
Now
file name in OPEN operator can be
set not only as string constant but also as string variable.
3.
Starting
from version 1.80 all *.bas programs, in addition to labels in the form of
number (line numbers) support, also support string labels ending with colon.
4.
Getstarttime() and getstoptime() methods are excluded from ob_obasic class as not relating to primary function of the
interpreter. User is able to easily
control run time of any interpreter method by himself.
28.aug.2005
– version 1.71 for Windows and Linux
Fixed
bug in version number return function.
21.aug.2005
– version 1.70 for Windows and Linux
Fixed
bug in working with hexadecimal numbers.
Multithread
libraries for MSVC7 are created.
23.feb.2005
– version 1.50 for Windows and Linux
1998 – first version for DOS
*.bas programs example files
.\bas
test_project1.bas
test_project2.bas
test1.bas
test2.bas
test3.bas
test4.bas
test5.bas
test6.bas
test7.bas
test8.bas
test9.bas
test10.bas
test11.bas
test12.bas
test13.bas
test14.bas
test15.bas
test16.bas
test17.bas
test18.bas
test19.bas
test20.bas
test21.bas
test22.bas
test23.bas
test24.bas
test25.bas
test26.bas
test27.bas
test28.bas
test29.bas - example files
that can be executed by ob190_msvc.exe console
application
Batch files for *.bas programs
execution
.\bat
test1.bat
test2.bat
test3.bat
test4.bat
test5.bat
test6.bat
test7.bat
test8.bat
test9.bat
test10.bat
test11.bat
test12.bat
test13.bat
test14.bat
test15.bat
test16.bat
test17.bat
test18.bat
test19.bat
test20.bat
test21.bat
test22.bat
test23.bat
test24.bat
test25.bat
test26.bat
test27.bat
test28.bat
test29.bat - example files
that run ob190_msvc.exe console
application
Source text files
.\source
ob1.bas
ob2.bas
ob3.bas
ob4.bas
ob5.bas
ob6.bas
ob7.bas
ob8.bas
ob9.bas
ob10.bas
ob11.bas
ob11.bas - source text
files
Command line handler source texts
files
.\comline
comline.cpp - functions for
command line parsing
comline.h - functions for
command line parsing
Console application source text
files
.\example
ob.cpp - main() of ob190_msvc.exe test
example, user-defined functions and examples of attaching of user-defined
functions.
Example
of Open Basic use as a console application
.\exe
ob190_msvc.exe
- Open Basic MSVS 2008 console application
It receives name of text
file with *.bas program as a parameter and executes it. When run with -? switch, it prints list of its switches. Use for .NET platform only
(WinXP and later).
Description files
.\htm
read_rus.htm - file containing Russian
version of user’s manual file
read_eng.htm - file containing
English version of user’s manual file
shortrus.htm - file containing
Russian version of brief reference book about ob_obasic class methods and enumerations
shorteng.htm - file containing English version of brief
reference book about ob_obasic class
methods and enumerations
Header files
.\include
mstore.h - data storage
policies
mvect.h - vector
mlist.h - list
mstack.h - stack
mhash.h - hash table
ob.h - Open Basic main header file
During
work in user application it is often become necessary to use simple scripting
language. Such task appears when application operates with some amount of
primitives that should be called in different sequence according to different
work modes.
Examples:
- database requests with various conditions
of data sampling
- hardware and/or software testing
- communication with nonstandard hardware
using different communication channels
- Graphical User Interface making and
manipulations with GUI objects
- terminal input language for command line
parsing
- input language for use by operator in
automated industrial control system tasks
- complex configuration files input language
- etc
Graphical User Interface makes process of
task automatization more difficult. Therefore it is often necessary to
complement Graphical User Interface with features provided by the scripting
language.
The Open
Basic interpreter is developed for embedding into user applications as
scripting language.
User-defined functions can be written on
C/C++ programming languages, assembler or other languages. User-defined
functions can be activated from Basic
program, receive parameters of different types from Basic program and return their work results to Basic program.
User-defined functions have access to all
variables and arrays of Basic program,
and not only to those transferred by using of parameters. This access is based
on names of variables and arrays.
Open
Basic is written entirely on C++ and does not use system calls of any
operation system. Open Basic can be used along with any graphical software
library.
The Open
Basic interpreter is implemented as a class with ob_obasic name. The interpreter work consists in execution of
program written on BASIC programming
language. In this user’s manual file such program is called a *.bas-program.
The *.bas-program can be either a text file or a buffer in memory opened as istream data stream.
The following definitions are further used in
user’s manual file:
1. "operator" – operator of BASIC language(for example, PRINT, FOR etc)
2. "user-defined
function" - user-defined
function attached to Open Basic
execution system
3. "function" - C++ function
4. "method" - method of ob_obasic class
5. "*.bas-program" – program written on BASIC programming language
In order to use the interpreter one should:
1.
Download
from http://www.mktmk.narod.ru archive containing:
-
interpreter
source code
-
ob.h header file
-
header
files with template containers implementation(mstore.h,mvect.h,mlist.h,mstack.h,mhash.h);
2.
Include
interpreter source code into the project;
3.
Indicate
path in the project for attaching of ob.h
interpreter header file;
4.
Indicate
path in the project for attaching of template containers header files (mstore.h,mvect.h,mlist.h,mstack.h,mhash.h);
5.
Include
ob.h header file of interpreter into
your C++ files using #include
directive;
6.
Make
declaration about usage of interpreter namespace using namespace ob_charspace;
7.
Create
ob_obasic class instance in your C++
program;
8.
If
streams used for input or output differ from standard cin or cout streams then
intercept interpreter’s input and output using setoperatorbreak, setin and setout
methods;
9.
Clear
project using clear_project method;
10.Load program for execution using load_project method;
11.Run program for execution using run method.
Example:
//loading
and running of test1.bas program
ifstream
inp1("test1.bas",ios::binary);//input stream opening
ob_obasic basic_interpreter;//creation of interpreter instance
basic_interpreter.clear_project();//project clean-up
basic_interpreter.load_project(&inp1);//loading of test1.bas using load_project
method
basic_interpreter.run();//test1.bas program running
ATTENTION!
Input stream should be opened in ios::binary
mode.
EXPLANATION:
Despite the fact that *.bas program itself is
a text file, as a stream it should be opened in ios::binary mode. This should be done due to some features of
carriage return characters and line feed processing in ios::text mode.
Example:
//loading
and running of test2.bas and test3.bas programs after test1.bas program termination
ifstream
inp2("test2.bas",ios::binary);//input stream opening
ifstream
inp3("test3.bas",ios::binary);//input stream opening
basic_interpreter.clear_project();//project clean-up
basic_interpreter.load_project(&inp2);//*.bas program loading
basic_interpreter.load_project(&inp3);//*.bas program loading
basic_interpreter.set_current_input_stream(&inp2);//setting of inp2 stream as first in run queue
basic_interpreter.run();//test2.bas program running
ATTENTION!
Input stream should be opened in ios::binary
mode.
ATTENTION!
If project consists of multiple files (streams), then last loaded file (stream)
will be first to be run. In order to set a file (stream) that should be run
first set_current_input_stream method should be used.
The
following main problems were solved during development of the interpreter:
1.
Ability
to store Basic program in file on
disc or buffer in memory. To provide this ability the interpreter receives
input program as istream* input
stream pointer. The actual stream type (file on disc or buffer in memory) is
determined by user. In the same way input stream for INPUT operator and output stream for PRINT operator can be either files or memory buffers.
2.
In
order to provide more flexible usage
-
First
stage is project clean-up using clear_project
method. During project clean-up process internal tables of the interpreter are
cleaned from previous project data (clean-up of jump labels tables, tables of
variables and array etc).
-
Second
stage is program loading using load_project
method. During the process of loading jump labels table is created and internal
variables are set up. Set of files (streams) that are simultaneously loaded in
instance of the interpreter is called a project. All variables, arrays
and labels in the project have common interaction space. Labels in all project files
(streams) must not repeat. All variables created in one file of the project are
available for all other files of the project.
-
Third
stage is program execution using run
method. During the execution process reading of program text and performing of
different actions (variables and arrays creating, calculation and value
assignment to variables, operators or functions execution) take place.
The
termination of run method happens
due to following reasons:
-
expire
of input stream
-
syntax
error in the program
-
breakpoint
character
-
end
of line character with flag of step-by-step work mode set on
On its termination run
method returns exit code. By analyzing this code user is able to know the
reason of method termination.
After its termination run
method can be continued without new loading of the program.
3.
One
instance of the interpreter is able to perform one project at the given moment
of time. The program can contain several instances of the interpreter. The
interpreter does not have static data members (except constants available for
reading). Therefore several instances of the interpreter are able to work
simultaneously in different threads.
4.
User-defined functions in Open Basic have identical
interface. This interface allows to analyse types of parameters and sequence of
parameters of user-defined functions during runtime. Such type of
approach requires careful work of developer; on the other hand, such approach
does not limit the ability of creating user-defined functions with various
parameters.
5.
The ob_obasic class itself is not a
template; therefore it can be taken out to static or dynamic library. This
action allows reducing of translating time.
There are two alternative ways of data
input-output process arrangement from/to the interpreter:
First way of input-output process arrangement.
During execution of *.bas program the
interpreter works with internal variables and arrays and also with user-defined
functions. All these objects are arranged in tables. All actions with these
objects are performed without calling of operating system services and by means
of the interpreter execution system only. But I/O operators (PRINT and INPUT)
require calling of operating system services because specific type of
input-output process and way of its realization may vary a lot depending on different
operating systems and different applications. For conjunction of the interpreter I/O subsystem and OS I/O
subsystem setoperatorbreak, setin
and setout methods
are used.
PRINT operator
sends data to output data stream. This
data stream is connected to the interpreter using setout method. Usually ostrstream
class with static buffer is used as output stream. By default cout is used as output stream.
INPUT operator
receives data from input data stream.
This input stream is connected to the interpreter using setin method. Usually istrstream
class with static buffer is used as input stream. By default cin is used as input stream.
For
conjunction of the interpreter I/O subsystem and OS I/O subsystem user should
create two functor classes that are derivatives from ob_functor_break_base class:
class ob_functor_break_base{
public:
ob_functor_break_base(){}
virtual ~ob_functor_break_base(){}
virtual void
run_before(ob_obasic* basicptr)=0;
virtual void
run_after(ob_obasic* basicptr)=0;
};
In these ob_functor_break_base
class derivatives user redefines run_before
and run_after methods. After this
user creates reference to functors in the interpreter using setoperatorbreak method.
Run_before and run_after methods are run before and after input-output operators
execution respectively. In run_before
methods user prepares input-output streams for the interpreter. In run_after methods user processes
input-output results.
Functor
instances should be in the same scope with ob_obasic
interpreter instance. If the program contains several ob_obasic interpreter instances then each of them should have its
own input-output functor instances.
Example
(from ob.cpp file)
-
creating of functor for output (for PRINT operator)
class ob_functor_break_print_def:public
ob_functor_break_base{
char printbuffer[ob_maxlengthstring];
ostrstream pr;
public:
ob_functor_break_print_def():pr(printbuffer,ob_maxlengthstring){}
virtual ~ob_functor_break_print_def(){}
void run_before(ob_obasic* basicptr){
printbuffer[0]=0;
pr.clear();
pr.seekp(0);
basicptr->setout(&pr);
}
void run_after(ob_obasic* basicptr){
if(printbuffer[0]!=0){
pr<<ends;
//-------------------------------------------------
cout<<printbuffer;//your output code place here
//-------------------------------------------------
}//if
}
};
-
creating of functor for input (for INPUT operator)
class ob_functor_break_input_def:public ob_functor_break_base{
char
inputbuffer[ob_maxlengthstring];
char
inputbuffer1[ob_maxlengthstring];
strstream pr;
public:
ob_functor_break_input_def():pr(inputbuffer1,ob_maxlengthstring){}
virtual
~ob_functor_break_input_def(){}
void run_before(ob_obasic*
basicptr){
ob_lex::typelex
tll=basicptr->gettypenextlex();
basicptr->restoreinputpointer();
if(tll!=ob_lex::SHARP){
inputbuffer[0]=0;
//-------------------------------------------------
cin>>inputbuffer;//your input code place here
//-------------------------------------------------
pr.clear();
pr.seekp(0);
pr<<inputbuffer;
pr.seekg(0);
basicptr->setin(&pr);
}//if
}
void run_after(ob_obasic*
basicptr){}
};
-
creating of functor instances
ob_functor_break_print_def
ob_functor_break_print;
ob_functor_break_input_def
ob_functor_break_input;
-
creating of references to functors in the interpreter
instance
example_basic_interpreter.setoperatorbreak("PRINT",&ob_functor_break_print);
example_basic_interpreter.setoperatorbreak("INPUT",&ob_functor_break_input);
In
example given input-output is performed from/to standard cin and cout streams.
Given examples of functors can be used in GUI-using program by replacing the
following lines
//-------------------------------------------------
cout<<printbuffer;//your output code place here
//-------------------------------------------------
//-------------------------------------------------
cin>>inputbuffer;//your input code place here
//-------------------------------------------------
by
user’s code of input-output from/to corresponding Windows window.
Second way of input-output process
arrangement.
Input-output process can be arranged
without using of PRINT and INPUT operators by using of
input-output user-defined functions. User writes his own input-output
user-defined functions, and then registers them in the interpreter so that these
input-output user-defined functions are used in *.bas program text instead of PRINT and INPUT operators.
ob_obasic(ostream* o=&cout,istream*
read=&cin);
creates
an instance of Open Basic
interpreter.
Constructor
arguments:
1. o
argument- pointer that points on output stream in which data is output by PRINT operator.
ATTENTION!
The output stream must be opened in ios::text
mode.
EXPLANATION:
The output stream itself is an ordinary text
stream in which text data is output.
2. read
argument - pointer that points on input stream from which data is read by INPUT operator.
ATTENTION!
The input stream must be opened in ios::binary
mode.
During
its work the interpreter creates following tables:
1. table of variables
2. table of arrays
3. user-defined functions table
4. DATA
operator data table (stream)
5. table of labels
6. table of FOR operators cycles
7. table of active files
8. GOSUB
subprograms table (stack)
Clear_project method clears all tables except
for user-defined functions table.
User-defined
functions table can be erased only by void
clrtablfun(); method calling.
void
load_project(istream* i) method; - this method loads *.bas program.
The
argument of this method is a pointer which points on the stream where *.bas
program is contained.
ATTENTION!
This stream must be opened in ios::binary
mode.
The
internal pointer of stream data should point on program start.
After
the interpreter finishes its work the internal pointer points on program end.
In order to run the same program one more time one should transpose the
internal pointer using seekg method
and reload the program using load_project
method.
Load_project method is able to load several
streams simultaneously. A set of simultaneously loaded streams is called a
project.
typeend run(); method - this method runs loaded program or continues program execution after program stop with returning of exit code. If the project consists of more than one stream then last loaded stream is run. In order to set stream to be run one should use set_current_input_stream method.
set_current_input_stream(ob_istreamcommon*
i) method points on
stream that should be executed first when run()
method is called. The i stream
should be loaded beforehand using load_project
method.
ob_istreamcommon* get_current_input_stream() method returns current
running stream.
Enumeration
enum typeend{
DUMMYEND,ENDFILEEND,ENDOPERATORDETECT,EOLEND,BREAKPOINTEND,NOLOADEND,
BREAKBEFOREOPERATOR,BREAKAFTEROPERATOR
};
defines
run method exit code.
Exit
codes are the following:
1. typeend=DUMMYEND
– this code is never returned by run
method during normal work and is used for internal jumps.
2. typeend=ENDFILEEND
– this code means that run method
has been terminated because of input stream expiration. This is normal
termination of *.bas-program if END
operator is not present in *.bas-program.
3. typeend=ENDOPERATORDETECT
– this code means that run method
has been terminated because of detection of END operator. This is normal termination of *.bas-program.
4. typeend=EOLEND
- this code means that run method
has been terminated after current line execution because step=STEP flag was set using setstep
method.
5. typeend=BREAKPOINTEND
- this code means that run method
has been terminated after reading of '@'
character that is used as a breakpoint character in Open Basic
6. typeend=NOLOADEND
- this code means that run method
has terminated because load_project method had not been
executed and input stream had not been opened.
7. typeend=BREAKBEFOREOPERATOR
- this code means that run method
has terminated before
8. typeend=BREAKAFTEROPERATOR - this code
means that run method has terminated
after
Step-by-step *.bas-programs execution is
implemented by setstep method.
The '@'
character placed in separate line of *.bas-program text implements a
breakpoint.
There
can be several breakpoints in *.bas-program. After all breakpoints are
specified the *.bas-program should be reloaded using load_project method.
When control is transferred to line
containing '@' character the program
halts.
In this
case exit code of run method is BREAKPOINTEND. In order to continue
program execution run(); method
should be run again.
enum
step{NOSTEP,STEP}; enumeration -
this enumeration determines step-by-step program execution mode. This
enumeration is used in setstep and getstep methods. Default value is step=NOSTEP.
If step=NOSTEP
the program is executed without interruptions.
If step=STEP
the program is terminated with typeend=EOLEND
code after each program line execution.
void
setstep(step ts) method - this
method sets step-by-step program execution mode on or off. This method can be
used at any moment of the interpreter work.
If
step-by-step program execution mode is set on then run(); method will be terminated after execution of each
*.bas-program line. In order to continue program execution run(); method should be run again.
step
getstep() method – this method returns current mode of step-by-step program
execution.
ob_modestream class will be used for processing of
UNICODE and UTF-8 files. These modes are not supported in version 1.90 of the
interpreter. The corresponding fields in functions callings are set equal to
default constructor ob_modestream().
The function is:
bool ob_loadbreakstr(
ob_istreamcommon* in1,
ob_type_stringsize lengthbuffers,
ob_type_char* ptrbefore,
ob_type_char* ptrcurrent,
ob_type_char* ptrafter,
ob_modestream ms=ob_modestream()
);
where:
istream* in1
- current input executable *.bas-file
lengthbuffers - length of ptrbefore, ptrcurrent, ptrafter buffers
ptrbefore - buffer for line that goes before current
executable line
ptrcurrent - buffer for current executable line
ptrafter - buffer for line that goes after current executable line
ob_modestream
- input file format flag. In version 1.90 of the interpreter this flag
is given by default.
Function ob_loadbreakstr
loads corresponding lines of currently running program into selected buffers.
Function ob_loadbreakstr
is not a method of ob_obasic class.
Example:
//Creating
of the interpreter and running of program in step-by-step mode
//with
printing of currently executable lines
ob_type_char
strbefore[ob_maxlengthstring];//buffer
ob_type_char
strcurrent[ob_maxlengthstring];//buffer
ob_type_char
strafter[ob_maxlengthstring];//buffer
ob_obasic basic_interpreter;//creating of the interpreter
//loading
and running of test1.bas program
//with
step-by-step program execution
//and
printing of currently executable lines
ifstream
inp1("test1.bas",ios::binary);//input stream opening
basic_interpreter.clear_project();//project clean-up
basic_interpreter.load_project(&inp1);//loading of test1.bas program
basic_interpreter.setstep(ob_obasic::STEP);//setting of step-by-step mode
while(1){
if(basic_interpreter.run()!=ob_obasic::EOLEND)
break;//running of
*.bas-program
ob_loadbreakstr(&inp1,ob_maxlengthstring,strbefore,strcurrent,strafter);
cout<<endl<<"String
current: "<<strcurrent;
}//while
During the
execution of *.bas program the interpreter works with internal variables and
arrays and user-defined functions. All these objects are arranged into tables.
All actions with these objects are performed without caling of operating system
services and by means of the interpreter execution system only. But I/O
operators (PRINT and INPUT) require calling of operating system services
because specific type of input-output process and way of its realization may
vary a lot depending on different operating systems and different applications.
For conjunction
of the interpreter I/O subsystem and OS I/O subsystem setoperatorbreak, setin and setout methods are
used.
For
each of the operators in
bool setoperatorbreak(ob_type_char*
name,ob_functor_break_base* b);
Method
arguments:
1. name
– operator name
2. ob_functor_break_base* b
– functor pointer
return
value:
true
- termination successful
false – operator name is not found
To know
more about use of setoperatorbreak
method refer to p. 3.3 “Input-output system review” of this document.
Method
bool getoperatorbreak(ob_type_char*
name,ob_functor_break_base** b);
allows to get functor pointer. If functor has not been set for specified operator then b=0. Returns false if operator name is not found. By default functors are not set for all operators.
These methods allow redefining input and
output streams previously defined in the constructor.
void setin(ob_istreamcommon*
i);
void setout(ob_ostreamcommon*
o);
ATTENTION!
Input stream must be opened in ios::binary
mode.
ATTENTION!
Output stream must be opened in ios::text
mode.
setin method redefines “rd” stream of the constructor.
setout method redefines “o” stream of the constructor.
This enumeration defines current lexical
token.
enum typelex{
PLUS,MINUS,MUL,DIV,POWER,ASSIGN,LP,RP,STRING,SEMICOLON,COMMA,ENDPROGRAMM,EOL,
LESS,GREAT,SHARP,BREAKPOINT,
DECINTNUMBER,HEXINTNUMBER,FLOATNUMBER,
FUNC,OPERATOR,
OLDVARIABLE,OLDARRAY,NEWNAME,
BAD
};
These
methods are used for simplification of input and output operators
implementation.
- ob_lex::typelex
gettypenextlex();
- void
restoreinputpointer();
Method
ob_lex::typelex gettypenextlex();
This
method returns next lexical token from input stream. Some operators (for
example, INPUT operator) have the
same syntax for input from file and console input. Current direction of input
is determined by next # lexical
token. Using gettypenextlex() method one can determine next lexical token type
and thereby determine where input is expected from.
Method
void
restoreinputpointer();
This
method is used for recovering of input stream state after use of gettypenextlex().
In example
given in p. 3.3 “Input-output system review” gettypenextlex and restoreinputpointer methods are used for input direction
determination in INPUT operator. If SHARP lexical token is detected,
console input will not be performed. PRINT
operator does not need such code because output does not block the work
process.
ATTENTION!
All objects of *.bas-program like variables, arrays, user-defined functions etc
must have different names.
The Open
Basic interpreter supports subset of Basic language operators. These
operators are described below. It is possible to work with three types of data:
floating-point, integer and string. Also it is possible to work with arrays
consisting of these data types.
Variables in Open Basic do not need to be described before their first use. The
first appearance of a variable in a program should be on the left of assignment
operator.
Arrays
in Open Basic should be described
before their first use by DIM
operator. Arrays can be multidimensional. Data for arrays and variables is
arranged in free memory by new
operator. The maximum size of array depends on new operator restrictions in each specific operating system.
In Open Basic first index of array is 1 (not
0).
Unlike DIM
operator of standard Basic language DIM
operator of Open Basic is
executable. It is executed every time the control is transferred on it.
It is possible to repeat description of array
with the same name in DIM operator.
New array can have dimensions that differ from old array dimensions. During
this process old data is lost. Such procedure can be used for memory release.
After huge array is captured by DIM
operator it is possible to release some memory by describing array with the
same name and dimension of one element.
When describing array in DIM operator integer variables can be used as dimensions.
When created numerical variables and arrays
are initialized by zero. String variables and arrays are initialized by empty
string ("").
Range of floating-point and integer data
depends on C++ compiler. Usually integer data is int and floating-point data is float.
In file ob.h types of variables are
determined using typedef:
typedef char ob_type_char;
typedef float ob_type_flo;
typedef int ob_type_int;
The maximal length of string variables is
determined by ob_maxlengthstring
constant in ob.h file. For
A *.bas-program can contain empty strings.
The Open
Basic interpreter supports the following operations with integer data and
floating-point data:
+
- addition
-
- substraction
*
- multiplication
/
- division
^
- involution
-
- unary minus
+
- unary plus
=
- assignment
relational
expressions
< - "less than"
> - "greater than"
= - "equal"
<>
- "not equal"
<=
- "less or equal"
>=
- "equal or greater"
Relational
expressions are used in IF operator.
String data supports only addition,
comparison and line assignment operations.
As with standard Basic language, type of a variable or an array in Open Basic
is
determined by its name. For example:
- if variable or array name ends with '%' character then this variable or
array is of integer type.
- if variable or array name ends with '$' character then this variable or
array is of string type.
- if variable or array name ends with any
other character then this variable or array is of floating-point type.
Many Open
Basic types are described in ob.h
using typedef.
ob_type_flo type is reflected to float type using typedef.
ob_type_int type is reflected to int type using typedef.
In
user-defined functions it is recommended to use ob_type_flo and
ob_type_int types, so that if, for example,ob_type_flo is changed from float to double, types compatibility will be supported.
It is possible to use any combinations of
letters and numbers for names of variables, arrays and user-defined functions.
The first symbol of the name must be a letter.
Letters used in a name can be upper case or
lower case. The underline symbol '_'
and '$' and '%' symbols are also considered as letters.
Letters in names are not reduced to one register.For
example, MASS, mass
and Mass are three different names.
The maximum length of a name is determined by
ob_maxlengthstring constant in ob.h file. For
Example:
Array declaration of and initialization of
two variables of integer and floating-point type. The last dimension of the
array is specified by a variable. Type of mass
array elements is floating-point. The counter%
variable is of integer type. The data
variable is of floating-point type.
counter%=7
DIM
mass(2,3,10,counter%)
data=counter%+37.77
Example:
Array
declaration and using of it. Another declaration of array with same name but
other dimension and using of it.
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%
If the
expression uses data of different types then types reduction is used.
If the expression uses data of integer type
and data of floating-point type then the resultant type will be floating-point.
During assignment operation execution the
type of expression on the right is reduced to the type of expression on the
left of = assignment sign.
If a variable of integer type is on the left
of the assignment sign and a variable of floating-point type is on the right of
it then fractional part of floating-point type variable is truncated.
The Open
Basic supports labels in the form of line numbers. These numbers do not
have to be running is succession. It is not necessary to enumerate every line
of the program. GOTO and GOSUB operators perform jump only to
enumerated line. It is also possible to create label for empty line.
Example:
ii%=6
ik%=8
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
Starting from version 1.80 all *.bas programs, in addition to
labels in the form of number (line numbers) support, also support string labels
ending with colon. The colon is a part of label identifier and should follow
label identifier without separation symbol. In GOTO and GOSUB operators
string label identifier should be written without colon on its end. Labels in
the form of number (line numbers) and string labels can be used in the program
simultaneously. String label must start
with a letter.
Example:
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
Arguments of user-defined functions allow
determining of call arguments type and their sequence during the program
execution.
User-defined functions are attached to Open Basic execution system under
certain names (so-called Basic-names). Each user-defined function is attached
under its own Basic-name. After functions are attached they can be called in
*.bas-program text using their Basic-names. It is possible to pass parameters
to user-defined functions and get results from user-defined functions.
User-defined functions can be called without parameters. User-defined functions
can be written on C/C++, assembler or other languages.
All user-defined functions have 2 names:
1. C++ function name included in project,
which name allows function calling from C++ program.
2. Basic-name function name, which name
allows function calling from *.bas-program.
The first name (C++ function name) is
obtained by user-defined functions upon their creation (writing). The second
name (Basic-name function name) is obtained by user-defined functions when they
are attached to Open Basic execution
system using setfun method.
User-defined
function can be based on one of three following prototypes:
-
Function
that returns floating-point value
-
Function
that returns integer value
-
Function
that returns string value
In order to create user-defined function and
attach it to Open Basic execution
system one should perform the following actions:
1. Choose type of returned value for
user-defined function
2. Choose C++ function name for user-defined
function
3. Create user-defined function using one of
three prototypes listed above
4. Choose Basic-name function name for
user-defined function
5. Attached user-defined function to Open Basic execution system using setfun method and using Basic-name
function name and C++ function name as parameters
After these actions are done it is possible
to use Basic-name function name in *.bas-program.
User-defined function can return values of
three following types:
- floating-point type ob_type_flo
- integer type ob_type_int
- string type ob_type_char*
User-defined function can be based on one of
three following prototypes:
1. Functions that return floating-point value
ob_type_flo name_flo(
ob_obasic* basic_ptr,
const ob_type_char* parstring,
const ob_type_parnum *descrf,
const ob_type_parnum *descri,
const ob_type_parnum *descrc,
const ob_type_flo* parf,
const ob_type_int* pari,
const ob_type_char* parc
);
2. Functions that return integer value
ob_type_int name_int(
ob_obasic* basic_ptr,
const ob_type_char* parstring,
const ob_type_parnum *descrf,
const ob_type_parnum *descri,
const ob_type_parnum *descrc,
const ob_type_flo* parf,
const ob_type_int* pari,
const ob_type_char* parc
);
3. Functions that return string value
ob_type_char* name_char(
ob_obasic* basic_ptr,
const ob_type_char* parstring,
const ob_type_parnum *descrf,
const ob_type_parnum *descri,
const ob_type_parnum *descrc,
const ob_type_flo* parf,
const ob_type_int* pari,
const ob_type_char* parc
);
All these prototypes differ only by type of
value they return.
File ob.h
contains OB_DECLARE_USER_FUNCTION(name,typeret)macro
that can be used for user-defined functions declaration. The name parameter is C++ function name, typeret parameter is type of returned
value.
Example:
Decraration
of user-defined function using OB_DECLARE_USER_FUNCTION
macro.
C++
function name is "myfun1".
Type of
returned value is ob_type_flo.
OB_DECLARE_USER_FUNCTION(myfun1,ob_type_flo);
Example:
Determination
of user-defined function using OB_DECLARE_USER_FUNCTION
macro.
C++
function name is "myfun2".
Type of
returned value is ob_type_int.
OB_DECLARE_USER_FUNCTION(myfun2,ob_type_int){
return 365;
}
Example:
Determination
of user-defined function using OB_DECLARE_USER_FUNCTION
macro.
C++
function name is "myfun3".
Type of
returned value is ob_type_char*.
OB_DECLARE_USER_FUNCTION(myfun3,ob_type_char*){
return "Hello world";
}
User-defined
functions interface in Open Basic is
specially developed to provide ability to control actual arguments in calling
during program execution.
To provide this ability the set of
user-defined functions parameters contains two sets of arrays.
First set is set of arrays containing
argument descriptions descrf, descri, descrc.
These
arrays contain information about quantity and sequence order of actual
arguments in user-defined function calling.
Second set is set of arrays containing
argument values parf, pari, parc. These arrays contain values of actual arguments in
user-defined function calling.
Purpose and structure of descr* and par* arrays
are given detailed description in next part of this document.
There are three types of user-defined
functions. All these types have same arguments and different types of returned
result.
Let us consider user-defined function
arguments by example of function that returns floating-point type value.
ob_type_flo name_flo(
ob_obasic* basic_ptr,
const ob_type_char* parstring,
const ob_type_parnum *descrf,
const ob_type_parnum *descri,
const ob_type_parnum *descrc,
const ob_type_flo* parf,
const ob_type_int* pari,
const ob_type_char* parc
);
Function arguments:
1. ob_obasic* basic_ptr – pointer on ob_obasic interpereter instance to
which the function is attached. Used for accessing program variables by using ob_obasic methods.
2. const char* parstring – string
representations of arguments.
Example:
If USER_FUN1 function is called with
arguments USER_FUN1(1.123,a_a%,1+2)
then parstring array will contain
following strings: "1.123","a_a%","1+2".
These
strings will be stored sequentially and separated by zero.
3. argument descriptions arrays descr*:
const
ob_type_parnum *descrf – for floating-point type arguments
const
ob_type_parnum *descri - for integer type arguments
const
ob_type_parnum *descrc - for string type arguments
these arrays desctibe quantity, types and
position of all arguments that were passed to user-defined function from
*.bas-program. These arrays are used to control quantity, type and sequence
order of arguments in calling of user-defined function.
Structure of descrf arrays (other arrays have same structure):
descrf[0] – count of floating-point type
arguments in current calling
Other
elements of descrf array (their
quantity is descrf[0]) are ordinal
numbers of floating-point type parameters in current calling.
Ordinal
numbers are counted starting from 1.
Example:
If USER_FUN1(1.123,a_a%,1+2) are set as USER_FUN1 function arguments in calling
of this function then
descrf array will contain following
numbers: 1,1
descri array will contain following
numbers: 2,2,3
descrc array will contain following
numbers: 0
Example:
If USER_FUN1("str1","srt2"+"str3",1.1,1.2,1.3,1.4)
are set as USER_FUN1 function
arguments
in
calling of this function then
descrf array will contain following
numbers: 4,3,4,5,6
descri array will contain following
numbers: 0
descrc array will contain following
numbers: 2,1,2
4.
argument values arrays par*:
const ob_type_flo* parf - for floating-point type
arguments
const ob_type_int* pari - for integer type
arguments
const ob_type_char* parc
- for string type arguments
these arrays describe values of all
corresponding types arguments that were passed to user-defined function in
current calling from *.bas-program.
The arguments will be in succession, strings
in parc array, as well as in parstring array, are separated by
trailing zero.
Example:
([a_a%]
is value of variable with name of a_a%)
If USER_FUN1 function is called with
arguments USER_FUN1(1.123,a_a%,1+2) then
parf array will contain following
numbers: 1.123
pari array will contain following
numbers: [a_a%],3
parc array will not contain any values
Example:
If USER_FUN1 function is called with
arguments USER_FUN1("str1","srt2"+"str3",1.1,1.2,1.3,1.4)
then
parf array will contain following
numbers: 1.1,1.2,1.3,1.4
pari array will not contain any values
parc array will contain following
strings: "str1","srt2str3"
ob.h
file contains OB_DECLARE_USER_FUNCTION(name,typeret)
macro that can be used for user-defined functions declaration. The name argument is C++ function name, typeret argument is the type of
returned value.
Maximum number of arguments is determined by ob_maxnumpar constant in ob.h file.
For
By using descr*
arguments sequence order description arrays and par* argument value arrays user can analyse types and sequence
order of arguments in current user-defined function calling during program
execution.
Analyzis of descr* arrays gives full information about types, quantity and
sequence order of arguments in current user-defined function calling.
Example:
String variable is passed as argument into
user-defined function that calculates sine. In this case descrf, descri and descrc arrays will contain following
values:
descrf[0]=0
descri[0]=0
descrc[0]=1
By
analyzing this information user is able to perform tasks he needs, for example:
1. generate user’s exception
2. substitute in default argument, for
example 0.
3. perform program halt with printing of
alert
4. try to transform string into number using atof
In order to facilitate access to string data Open Basic provides function
const ob_type_char*
ob_getstringparam(
const ob_type_parnum *descrc,
const ob_type_char* parc,
const ob_type_parnum i);
Function arguments:
1. descrc
– string arguments description array
2. parc - string arguments values array
3. i - number of line that was passed in
arguments (numeration starts from zero)
By using this function user can gain access
to i-numbered line that was written into string arguments or names of
user-defined function.
If i is greater than descrc[0], the function returns 0.
If descrc[0]
is equal to zero, the function returns 0.
Function
ob_getstringparam is not ob_obasic class method.
Basic-name for user-defined function should
differ from names of operators, variables, arrays or other user-defined
functions of *.bas-program.
Attaching of user-defined function to
bool setfun(ob_type_char*
name,ob_type_flofun f);
bool setfun(ob_type_char*
name,ob_type_intfun f);
bool setfun(ob_type_char*
name,ob_type_charfun f,ob_type_del dt);
Method arguments:
1. name
- Basic-name of user-defined function
3. dt - type of returned value allocation in
memory (only for functions that return string)
Example:
//attaching of
userfun1 user-defined function
//this
function returns floating-point type value
//this
function types "hello world" message
and returns value 3.1416
//during
its attaching the function receives "TEST_FUN1"
Basic-name
//which
means that in *.bas-programs it is possible to call this function by name "TEST_FUN1"
OB_DECLARE_USER_FUNCTION(userfun1,ob_type_flo){
cout<<endl<<"hello
world";
return (ob_type_flo)3.1416;
}
main(){
ob_obasic onebasic;//the interpreter instance is
created
onebasic.setfun("TEST_FUN1",userfun1);//TEST_FUN1 user-defined function
function is attached
ifstream
inonebasicf("EXAMPLE.BAS",ios::binary);//EXAMPLE.BAS file is opened
onebasic.clear_project();
onebasic.load_project(&inonebasicf);//EXAMPLE.BAS file is loaded into the interpreter
onebasic.run();//running of *.bas-program
}
Sequence
order of attaching of function returning string data type differs from
described above.
Returned
value has two types of memory allocation:
- in the heap (using new[] operator)
- in static memory
In the first case user-defined function is
attached with dt=OB_DELETE argument.
After
this function finishes its work Open
Basic will free memory by using delete[]
operator.
Example:
In example given the interpreter instance is
created, then file with name
EXAMPLE.BAS is opened and is loaded into the
interpreter. After this four functions TEST_FUN1-TEST_FUN4 are attached to
TEST_FUN1
function prints list of its floating-point type arguments and returns
floating-point type value that is equal to sum of floating-point type arguments
of the function.
TEST_FUN2
function prints list of its integer type arguments and returns integer type
value that is equal to sum of integer type arguments of the function.
TEST_FUN3
and TEST_FUN4 functions print their
first string type argument and return string "This is string".
During this TEST_FUN4 function allocates its returned value in static memory
and TEST_FUN3 function allocates its
returned value in free memory.
All these functions control whether types of
their arguments are correct. If arguments of required type are missing then
functions type appropriate messages.
#include <ob.h>
char* s="This is string";
OB_DECLARE_USER_FUNCTION(userfun1,ob_type_flo){
ob_type_flo summ=0;
ob_type_parnum i;
if(descrf[0]==0)
cout<<endl<<"Not float parameters";
for(i=0;i!=descrf[0];i++){
summ+=parf[i];
cout<<endl<<"parameters["<<i<<"]="<<parf[i];
}
return summ;
}
OB_DECLARE_USER_FUNCTION(userfun2,ob_type_int){
ob_type_int summ=0;
ob_type_parnum i;
if(descri[0]==0)
cout<<endl<<"Not int parameters";
for(i=0;i!=descri[0];i++){
summ+=pari[i];
cout<<endl<<"parameters["<<i<<"]="<<pari[i];
}
return summ;
}
OB_DECLARE_USER_FUNCTION(userfun3,char*){
if(descrc[0]==0)
cout<<endl<<"Not string parameters";
cout<<endl<<parc;
char* p=new char[strlen(s)+1];
strcpy(p,s);
return p;
}
OB_DECLARE_USER_FUNCTION(userfun4,char*){
if(descrc[0]==0)
cout<<endl<<"Not string parameters";
cout<<endl<<parc;
return s;
}
main(){
ob_obasic onebasic;//creating of the interpreter
instance
onebasic.setfun("TEST_FUN1",userfun1);//attaching of TEST_FUN1 function
onebasic.setfun("TEST_FUN2",userfun2);//attaching of TEST_FUN2 function
onebasic.setfun("TEST_FUN3",userfun3,OB_DELETE);//attaching of TEST_FUN3 function
onebasic.setfun("TEST_FUN4",userfun4,OB_NODELETE);//attaching of TEST_FUN4 function
ifstream
inonebasicf("EXAMPLE.BAS",ios::binary);//opening of EXAMPLE.BAS file
onebasic.clear_project();
onebasic.load_project(&inonebasicf);//loading of EXAMPLE.BAS into the interpreter
onebasic.run();//running of *.bas-program
}
The following actions are performed by Open Basic execution system when it
detects the name of attached function in *.bas-program text:
1. it calculates all arguments in current
calling of *.bas-program
2. it fills descr* arrays
3. it fills par* arrays
4. it fills ob_obasic* basic_ptr pointer with address of Open Basic current object
5. it fills parstring string
6. it transfers control to user-defined
function
User-defined function should control types,
quantity and sequence order of arguments in current calling.
Enumeration enum ob_type_del{OB_DELETE,OB_NODELETE}; - this enumeration
determines type of allocation in memory of value returned by used-defined
function. This enumeration is used in setfun
method for attaching of user-defined functions that return ob_type_char*type.
If dt=OB_DELETE
then returned value is put to free memory by new operator. After user-defined function is terminated, this value
will be deleted by delete[]
operator.
If dt=OB_NODELETE
then returned value will not be deleted by delete[]
operator.
Methods
bool setfun(ob_type_char*
name,ob_type_flofun f);
bool setfun(ob_type_char*
name,ob_type_intfun f);
bool setfun(ob_type_char*
name,ob_type_charfun f,ob_type_del dt);
These
methods attach user-defined function to Open Basic execution system.
Method arguments:
1. name
- Basic-name of user-defined function
3. dt - type of returned value allocation in
memory (only for functions that return string)
If
function with name name has not been
attached to Open Basic execution
system yet, then method attaches this function and returns false.
If
function with name name is already
attached to Open Basic execution
system, then method replaces this function with new one and returns true.
Types ob_type_flofun, ob_type_intfun and ob_type_charfun
are pointers on functions described in ob.h.
They differ by type of value they return.
Method
bool delfun(ob_type_char* name);
This
method detaches user-defined function from Open
Basic execution system.
Method arguments:
1. name
- Basic-name of user-defined function
Method delfun
returns true if function has been
successfully detached and false if
function was not found.
User-defined
function can receive arguments from *.bas-program.
User-defined
function can send its output value to *.bas-program.
User-defined
function can read and write variables of *.bas-program.
If a variable or an array is used in
*.bas-program then user-defined function is able to read and write this
variable and array elements.
User-defined
function can check presence of a variable with specified name in the program.
User-defined function can create variables with specified name in the variable
table.
These features are implemented in Open Basic
by methods described in next part of this document.
Methods described in this paragraph are
usually run in user-defined functions so in given examples these methods are
run using ob_obasic* basic_ptr pointer.
First argument of user-defined function has such name in all user-defined
functions if these functions are determined using OB_DECLARE_USER_FUNCTION macro.
Generally methods described in this paragraph
can be run in any part of C++program in which the interpreter is used. For
example, after halting *.bas-program by using breakpoint it is possible to
print values of variables and arrays. Also it is possible to create and
initialize certain variables before program start.
Enumeration
enum ob_type_ident
{OB_IDENTFLO,OB_IDENTINT,OB_IDENTSTR,OB_NOIDENT};
This
enumeration determines type of a variable or an array. This enumeration is used
in typevar and typearray methods for determining of variable or array type.
If ob_type_ident=OB_IDENTFLO then the
variable is of floating-point type.
If ob_type_ident=OB_IDENTINT then the
variable is of integer type.
If ob_type_ident=OB_IDENTSTR then the
variable is of string type.
If ob_type_ident=OB_NOIDENT then the variable was not found.
Method
ob_type_ident typevar(ob_type_char*
name); - this method returns type of a variable
with name name.
Method arguments:
1. name
– name of Basic-variable
Method
ob_type_ident
typearray(ob_type_char* name); - this method returns type of an array with name name.
Method arguments:
1. name – name of Basic-array (without brackets
or indexes)
Example:
If there a *.bas-program containing the following code
DIM
array1%(10,10), array2$(10,10), array3(10,10)
a%=10
b$="string example"
c=101.4
then,
after this part of code is executed in user-defined functions attached to the
interpreter, using of these methods will give the following results:
ob_type_ident
ident;
ident=basic_ptr->typevar("a%");// ident has the value of OB_IDENTINT
ident=basic_ptr->typevar("b$");//
ident has the value of OB_IDENTSTR
ident=basic_ptr->typevar("c");
// ident has the value of OB_IDENTFLO
ident=basic_ptr->typearray("array1%");//
ident has the value of OB_IDENTINT
ident=basic_ptr->typearray("array2$");//
ident has the value of OB_IDENTSTR
ident=basic_ptr->typearray("array3");
// ident has the value of OB_IDENTFLO
In given example basic_ptr is the first argument in user-defined functions, the
pointer on the interpreter instance.
The
given example of *.bas-does not contain a variable with VAR name and an array with ARR
name, so using of these methods will give the following results:
ident=basic_ptr->typevar("VAR");//
ident has the value of OB_NOIDENT
ident=basic_ptr->typearray("ARR");//
ident has the value of OB_NOIDENT
Method
ob_type_ident
strlenvar(
ob_type_char* name,
ob_type_stringsize* len,
ob_type_arraysize* as=OB_NULL);
This
method determines variable type and length of variable or array element with name name.
Method arguments:
1. name
– name of Basic-variable or Basic-array
2. *len
– for string type variables this argument contains string length without
trailing zero. For floating-point type or integer type variables this argument
contains sizeof(ob_type_float) or sizeof(ob_type_int) respectively.
3. *as - array indexes (if name is the name of an array)
Method strlenvar
can be called for Basic-variables or elements of Basic-arrays.
There are two ways of strlenvar method calling for Basic-arrays:
1. With specifying of current indexes in the
array name (as=OB_NULL argument)
2. With specifying of current indexes in *as argument (as!=OB_NULL argument)
This method returns OB_NOIDENT if there is name assignment error, for example if the
name does not begin with a letter or is a name of array not described yet or
there is no such variable. On normal termination this method returns type of
the variable.
Argument *len
for string type variables contains string length without trailing zero. For
floating-point type or integer type variables *len argument contains
sizeof(ob_type_float) or sizeof(ob_type_int) respectively.
Example:
Calling of strlenvar method for an
array element with specifying of current indexes in the array name
If
there a *.bas-program containing the following code:
DIM array2$(10,10)
array2$(5,5)="array string example"
then,
after this part of code is executed in user-defined functions attached to the
interpreter, using of strlenvar
method will give the following results:
ob_type_stringsize len;
ob_type_ident ident;
ident=basic_ptr->strlenvar("array2$(5,5)",&len);//
ident==OB_IDENTSTR len==20
Example:
Calling of strlenvar method for an
array element with specifying of current indexes in *as argument
If
there a *.bas-program containing the following code:
DIM array2$(10,10)
array2$(5,5)="array string example"
then,
after this part of code is executed in user-defined functions attached to the
interpreter, using of strlenvar
method will give the following results:
ob_type_stringsize len;
ob_type_ident ident;
ob_type_arraysize as[]={5,5};
ident=basic_ptr->strlenvar("array2$",&len,as);//
ident==OB_IDENTSTR len==20
Example:
Calling of strlenvar method for
variables
If
there a *.bas-program containing the following code:
DIM
array1%(10,10), array3(10,10)
a%=10
b$="string example"
c=101.4
then,
after this part of code is executed in user-defined functions attached to the
interpreter, using of strlenvar
method will give the following results:
ob_type_ident
ident;
ob_type_stringsize len;
ident=basic_ptr->strlenvar("a%",&len);// ident==OB_IDENTINT
len==4
ident=basic_ptr->strlenvar("b$",&len);//
ident==OB_IDENTSTR len==14
ident=basic_ptr->strlenvar("c",&len); //
ident==OB_IDENTFLO len==4
Method
const ob_type_arraysize*
getarraysize(
ob_type_char*
name,ob_type_arraydimension* kr); - this method returns number of array dimensions and size of each
dimension.
Method arguments:
1. name
– array name.
2. *kr - number of array dimensions. This argument is filled using getarraysize method.
The returned argument is an array of each
dimension sizes. It is created during array descripting by DIM operator. This argument is Open Basic internal buffer and
should be read-only.
Example:
The array is described by DIM Array_1(10,11,12) operator.
Using
of getarraysize method.
const ob_type_arraysize *sr;
ob_type_arraydimension kr;
sr=basic_ptr->getarraysize("Array_1",&kr);
After getarraysize is used kr=3 and sr pointer points on array {10,11,12}.
Methods
bool
writevar(ob_type_char*
name,ob_type_flo val,ob_type_arraysize* as=OB_NULL);
bool
writevar(ob_type_char*
name,ob_type_int val,ob_type_arraysize* as=OB_NULL);
bool
writevar(ob_type_char*
name,ob_type_char* val,ob_type_arraysize* as=OB_NULL);
Method arguments:
1. name
– name of Basic-variable or Basic-array
2. val - values that are being written into
variables or array elements
3. *as - arrays indexes (if name is the name of an array)
Methods writevar
can be called for Basic-variables or Basic-arrays elements.
There are two ways of writevar methods calling for Basic-arrays.
1. With specifying of current indexes in the
array name (as=OB_NULL argument)
2. With specifying of current indexes in *as argument (as!=OB_NULL argument)
Methods write a variable with name name into table of variables and assign
val value to it.
If a variable does not exist it will be
created.
The checking of name type takes place, i.e. a
variable is created that corresponds to the name.
If type of assigned value does not correspond
to name type (for example, when trying to create integer type variable with
second argument of ob_type_char* val),
then the method generates an exception.
Name name
can be a name of array element. In this case this name should contain indexes
of specific element in accordance with the Basic rules.
Methods return false if there is a name assignment error (for example, if the
first simbol of the name is not a letter or if name is a name of an array but
this array has not been described yet). Methods return true if all parameters are correct and no errors occured during
execution.
Example:
The following code should be written in user-defined function to assign value 10.4 to VAR variable:
if(basic_ptr->writevar("VAR",10.4)==false)
cout<<endl<<"error in writevar";
Example:
The following code should be written in user-defined function to assign value "Hello world" to the third
element of array_string$(10) array:
if(basic_ptr->writevar("array_string$(3)","Hello
world")==false)
cout<<endl<<"error
in writevar";
Methods
bool
readvar(ob_type_char*
name,ob_type_flo* val,ob_type_arraysize* as=OB_NULL);
bool
readvar(ob_type_char*
name,ob_type_int* val,ob_type_arraysize* as=OB_NULL);
bool
readvar(ob_type_char*
name,ob_type_char* val,ob_type_arraysize* as=OB_NULL);
Method arguments:
1. name
– name of Basic-variable or Basic-array
2. *val
– value that is read from a variable or an array element
3. *as - array indexes (if name is the name of an array)
Methods readvar
can be called for Basic-variables or Basic-arrays elements.
There are two ways of readvar methods calling for Basic-arrays.
1. With specifying of current indexes in the
array name (as=OB_NULL argument)
2. With specifying of current indexes in *as argument (as!=OB_NULL argument)
Methods read a variable with name name from table of variables into val pointer.
If a variable does not exist it will not be
created.
Name name
can be a name of array element. In this case this name should contain indexes
of specific element in accordance with the Basic rules.
Methods return false if there is a name assignment error (for example, if the
first simbol of the name is not a letter or if name is a name of an array but
this array has not been described yet or there is no such variable). Methods
return true if all parameters are
correct and no errors occured during execution.
If type of variable and type of val argument do not match (for example,
when trying to assign an integer type value to a string type variable) then the
method generates an exception.
Example:
The following code should be written in user-defined function to read the value
of variable with name VAR1 to C++
variable with name val1:
ob_type_flo val1;
if(basic_ptr->readvar("VAR1",&val1)==false)
cout<<endl<<"error name var in readvar";
Example:
The following code should be written in user-defined function to read the value
of the fourth element of array_string$(10)
array:
ob_type_char buf[256];
ob_type_char* pchar=buf;
if(basic_ptr->readvar("array_string$(4)",pchar)==false)
cout<<endl<<"error
name var in readvar";
Method
void createvar(ob_type_char* name);
Method arguments:
1. name
– name of Basic-variable or Basic-array
This method creates a variable with name name in table of variables of the
interpreter.
The variable type is determined by presence
of '%' and '$' characters in variable’s name.
Method
void createarray(
ob_type_char*
name,ob_type_arraydimension kr,ob_type_arraysize* as);
Method arguments:
1. name
– name of Basic-variable or Basic-array
2. kr - number of array dimensions
3. *as - array of each dimension sizes
This method creates an array with name name in table of arrays of the
interpreter. If the array with such name already exists then it is deleted and
created again with specified arguments.
Type of elements of array that is created is
determined by presence of '%' and
'$' characters in array’s name. The
method is equivalent to DIM
operator.
Arguments of this method are similar to
arguments of getarraysize method.
Example:
The following code should be written in user-defined function to create an
array of integers ARRAY1%(5,10,20):
ob_type_arraysize as[]={5,10,20};
basic_ptr->createarray("ARRAY1%",3,as);
~ob_obasic();
- destructor.
Method static
const ob_type_char* about()- this method returns a string of information
about the program. The string can contain LF and CR characters.
Example:
cout<<ob_obasic::about();//printing of information about the
program
Method static
const ob_type_serialnum serial_number() – this method returns serial number
of the program.
Method static
const ob_type_int version() – this method returns number of current version
of the program multiplied by 100. For version 1.90 this method returns 190.
Methods
void
set_max_nested_gosub(ob_type_countlist m);
ob_type_countlist
get_max_nested_gosub();
These
methods determine the maximum number of nested calls for GOSUB operator. Default maximum number of nested calls for GOSUB operator is 4096. When specified number of nested calls is exceeded then
exception is generated. If this value is set to 0 then check of nested calls for GOSUB operator is not performed.
Operators can be placed in same line and be
divided from each other by spaces.
Some operators like DATA or PRINT should be
the only operators in the line, because list of arguments of these operators
should be explicitly bounded.
In operators descriptions the characters in
square brackets mean optional characters.
The following operators are supported in Open
Basic:
This operator sends list of variables to
output stream that was specified during ob_obasic
creating.
Operator format:
[N]
PRINT [#EXP,][LIST]
where
N - the number of the line
LIST
– list of elements that are represented as constants, variables, string or
numerical expressions.
EXP - expression that determines number of
output channel opened by OPEN
operator
Without list of elements PRINT operator sends LF/CR characters to output stream.
If some of the list elements are expressions
then Open Basic calculates these
expressions and prints the result.
Example:
10
TT%=40
TTT=101.3
20 PRINT "TT%=";TT,"TTT=";TTT+0.3
The result of operator’s work
TT%=40 TTT=101.6
List elements are separated from each other
by commas or semicolons.
If list elements are separated by commas then
tab character is sent to output stream between list elements.
If there is a comma or a semicolon on the end
of the elements list then line feed is not performed after PRINT operator.
PRINT
operator with elements list should be the only operator in the line.
This operator inputs data from input stream
that was specified during ob_obasic
creating.
Operator format:
[N]
INPUT [#EXP,]VAR1,[VAR2,VAR3,...]
where
N - the number of the line
VAR1,[VAR2,VAR3,...]
– list of variables
EXP
– expression that
determines number of input channel opened by OPEN operator
When Open
Basic meets INPUT operator it
inputs data represented in numerical form from the stream and assigns this data
to variables from the list. Strings in the stream should be quoted.
Example:
10 TT%=40
TTT=101.3
20 INPUT TT%,TTT
These operators create cycle in such way that
Open Basic checks condition
automatically on each iteration.
FOR
operator format:
[N] FOR VAR=EXP1 TO EXP2 [STEP EXP3]
where
N - the number of the line
VAR - control variable (cycle index)
EXP1
– index initial value. Can be any numerical expression.
EXP2
– index final value. Can be any numerical expression.
EXP3
– index value increment. Can be any numerical expression. Can be positive or
negative. Default is 1.
Control
variable (cycle index) can be an array element.
FOR
and NEXT operators should be used
together only. FOR operator
determines cycle start and NEXT
operator determines cycle end.
NEXT
operator format:
[N]
NEXT VAR1
where
N - the number of the line
VAR1
- control variable used in FOR
operator
If initial value of cycle variable is greater
than its final value then cycle is not performed.
Transferring of control inside the cycle is
not allowed.
To avoid truncation errors it is recommended
to use integer variables as cycle variables.
Cycles can be nested into each other; in this
case the inner cycle must end before the outer cycle.
FOR
operator has some implementation features. They take place because Open Basic itself is an interpreter.
During entrance into the cycle checking of cycle conditional is performed. If cycle conditional is not met the cycle
will not be performed. In this case the searching of corresponding NEXT operator and control transferring
to it is performed. During these actions any possible branching of the
algorithm by GOTO operators are not
taken into account.
Example:
GOTO 30
10
NEXT i%
GOTO 20
30 FOR i%=10 TO k% STEP 1
GOTO 10
20
STOP
END
This
example will work if k% is greater
than 10. If it is not then abnormal
termination will happen.
Example:
FOR i%=1 TO 3
FOR ii%=4 TO 1 STEP -2
PRINT "Work FOR
operator","ii%=";ii%,"i%=";i%
NEXT ii%
NEXT i%
Result of operator’s work
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
Example:
FOR i%=1 TO 3
FOR ii%=4 TO 1 STEP -2
PRINT "Work FOR
operator","ii%=";ii%,"i%=";i%
NEXT ii%
NEXT i%
Result of operator’s work
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
This operator calls direct jump to specified
line.
Operator format:
[N] GOTO line_number
or
[N] GOTO label_string
where
N - the number of the line
line_number - number of the line to which the transition
is performed
label_string
– string label
Example:
20 GOTO 50
PRINT "This operator do not work in example"
50 PRINT "Work GOTO
operator"
Result of operator’s work
Work GOTO operator
Example:
20 GOTO label_1
PRINT "This operator do not work in example"
label_1: PRINT "Work GOTO
operator"
Result
of operator’s work
Work GOTO operator
These operators call subroutine.
Operator format:
[N] GOSUB line_number
or
[N] GOSUB label_string
where
N - number of the line
line_number - number of line to which the transition is
performed
label_string
– string label
When Open
Basic meets GOSUB operator it
transfers control to the line that is specified in GOSUB operator. The program then continues to run from this line.
When Open Basic meets RETURN operator the control is
transferred to line that goes after the line containing GOSUB operator.
GOSUB
and RETURN operators should be used
together only.
RETURN
operator format:
[N]
RETURN
where
N - the number of the line
Subroutines can be nested into each other.
Example:
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
Result
of operator’s work
Work GOSUB operator 1
Work GOSUB operator 3
Work GOSUB operator 4
Work GOSUB operator 2
Example:
GOSUB label_gosub_1
GOTO label_goto_1
label_gosub_1:
PRINT "Work GOSUB operator 1"
GOSUB label_gosub_2
PRINT "Work GOSUB operator 2"
RETURN
label_gosub_2:
PRINT "Work GOSUB operator 3"
PRINT "Work GOSUB operator 4"
RETURN
label_goto_1:
STOP
END
Result
of operator’s work
Work GOSUB operator 1
Work GOSUB operator 3
Work GOSUB operator 4
Work GOSUB operator 2
This operator assigns a value to a variable.
Operator format:
[N]
[LET] VAR=EXP
where
N - the number of the line
LET - optional name of the operator
VAR - variable that receives a new value
EXP - expression that determines a new value
Example:
20 LET a=100.1
PRINT "Work LET operator","a=";a
Result
of operator’s work
Work
LET operator a=100.1
This operator reserves a place for numerical
or string array.
Operator format:
[N] DIM LIST
where
N - the number of the line
LIST
– list of arrays names separated by commas
Open
Basic supports arrays of any size and dimension. Due to the fact that place
for these arrays is reserved by C++
'new' operator the restrictions on array size or dimension are caused by 'new'operator implementation features
on a specific platform. For example, in MS DOS 'new'operator does not receive more than 64K bytes of memory.
Therefore, overall size of an array in MS
DOS Open Basic cannot exceed 64K bytes and number of array dimensions also
cannot exceed 64K bytes.
Dimensions of arrays in Open Basic can be changed. During descripting of already descripted
array this array is deleted and is created again, possibly with new dimensions
and size.
During their creating numerical arrays are
initialized by zero. String arrays are initialized by empty string.
The type of the array being created is
determined by variable type identification rules and by presence of % and $ characters in array’s name.
Example:
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
Result of operator’s work
array
string
variable string
a%=10
b=101.1
These operators are used for program
termination.
STOP operator
invokes clean-up of all Open Basic
tables -tables of variables, tables of arrays etc.
END
operator also invokes clean-up of all Open
Basic tables and also sets internal halt flag. Reset of this flag is
performed in ob_obasic::load_project
method.
These operators do not invoke clean-up of
user-defined functions table.
Operators format:
[N]
STOP
[N] END
where
N - the number of the line
Example:
PRINT "example STOP and REM operator"
10 STOP
20 END
This operator sets comments to the program.
Operator
format:
[N] REM COMMENT
where
N -
the number of the line
COMMENT
– comments text
REM
operators and empty lines increase program execution time and occupy some
amount of memory.
Example:
a=1
10 REM this text is comment
PRINT "a=";a
STOP
END
If control is never transferred to REM operator then this operator does
not increase program execution time.
Example:
a=1
b=2
c=3
GOSUB label1
GOSUB label2
STOP
END
label1:
a=b+c
RETURN
REM this text is comment
REM this text is comment
REM this text is comment
REM this text is comment
REM this text is comment
label2:
b=a+c
RETURN
OPEN
operator opens file. CLOSE operator
closes file.
OPEN
operator format:
[N] OPEN filename FOR INPUT AS FILE #EXP
[N] OPEN filename FOR OUTPUT AS
FILE #EXP
where
N - the number of the line
filename
– name of the file
EXP
– expression that is calculated and
reduced to integer type. Usually constants are used.
AS
FILE – key words
OPEN
FOR INPUT operator opens a file for reading.
OPEN
FOR OUTPUT operator opens a file for writing.
CLOSE
operator format:
[N]
CLOSE #EXP1,[#EXP1,#EXP2,...]
where
N - the number of the line
EXP
- expression that is calculated and reduced to integer type. Usually constants
are used.
Example:
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%+
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
This operator deletes file\files.
Operator format:
[N]
KILL STR1[,STR2,STR3,...]
where
N - the number of the line
STR1,
STR2 ,STR3 - file names
Example:
10
KILL "F000.TXT","F001.TXT"
READ
and DATA operators are used for
arrangement of data block that is read by Open
Basic interpreter during the program execution.
READ
operator format:
[N]
READ VAR1[,VAR2,VAR3,...]
where
N - the number of the line
VAR1,VAR2,VAR3
– variables that are assigned values from list of DATA operator
DATA
operator format:
[N] DATA EXP1,[EXP1,EXP2,...]
where
N - the number of the line
EXP1,EXP2,EXP3
– expression that is calculated and assigned to a variable from READ list. Can be numerical or string.
Usually constants are used.
RESTORE
operator format:
[N]
RESTORE
where
N - the number of the line
Before executing program Open Basic browses all DATA
operators in order of their appearance and creates a data block. Each time READ operator is encountered in the
program the data block outputs sequentially matching value for variables of
this operator in the same order in which they are specified in the data block.
After READ
operator is performed the position of last read data is remembered. Next READ operator starts data read from
position specified by previous READ
operator.
Open Basic performs reload of the same data
using RESTORE operator.
DATA
operator should be the only one operator in the line.
Example:
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$
Result of operator’s work
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
This operator initializes random number
generator with a new value. Current system time in seconds is used as a new
value, therefore at least 1 second should pass before RANDOMIZE operator can be used again after its previous use.
Operator format:
[N] RANDOMIZE
where
N - the number of the line
RANDOMIZE
operator is placed before first use of random number generation function(RND function). When RND function is performed RANDOMIZE operator changes initial
value of random number in such way that RND
function gives different numbers on its next pass.
Example:
10
RANDOMIZE
This operator is used for conditional jumps
performing. It has three formats: string format, block format and short block
format.
String
format of IF operator:
[N] IF REL-EXP THEN operators
where
N - the number of the line
THEN –
key word
REL-EXP
– test condition. The relational
expression can be either arithmetic or string.
operators
– an operator or a group of operators
If REL-EXP
condition is true then operator (operators) in string after THEN key word is (are) performed. If REL-EXP condition is false then
operator in line going after line with IF
operator is performed.
Example:
TT%=40
20 IF TT%=40 THEN GOTO 50
PRINT "This operator do not work in example"
50 PRINT "Work IF
operator","TT%=";TT%
Result of operator’s work
Work
IF operator TT%=40
Example:
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%
Result of operator’s work
Work IF operator TT%=40
Work IF operator TT%=40
Example:
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
Result of operator’s work
a=101.1 b=102.1 c=103.1
Block
format of IF operator:
[N] IF REL-EXP THEN
operators1
ELSE
operators2
ENDIF
where
N - the number of the line
THEN
– key word
REL-EXP
– test condition. The relational
expression can be either arithmetic or string.
operators
- an operator or a group of operators
If REL-EXP
condition is true then operator (operators) in block between THEN and ELSE key words is (are) performed. If REL-EXP condition is false then operator (operators) in block
between ELSE and ENDIF key words is (are) performed.
Short
block format of IF operator:
[N] IF
REL-EXP THEN
operators1
ENDIF
where
N - the number of the line
THEN
– key word
REL-EXP
- test condition. The relational
expression can be either arithmetic or string.
operators
- an operator or a group of operators
If REL-EXP
condition is true then operator (operators) in block between THEN and ENDIF key words is (are) performed. If REL-EXP condition is false then operator in line going after ENDIF key word is performed.
SGN%
function is a sign function.
Function
format: SGN%(EXP)
where EXP is an integer or a floating-point
expression.
This
function returns +1 if EXP>0, -1 if EXP<0 and 0 if EXP=0.
If the
argument is specified incorrectly (of a string type) then an error is
generated.
Example:
PRINT "This is example SGN function"
PRINT "<0";SGN%(-1-2);"
>0";SGN%(2*3);" =0";SGN%(9+1-10)
ABS
function determines absolute value of the argument.
Function
format: ABS(EXP)
where EXP is an integer or a floating-point
expression.
This
function returns floating-point type result, even if the argument is of integer
type.
If the
argument is specified incorrectly (of a string type) then an error is
generated.
Example:
PRINT
"This is example ABS function"
PRINT "abs(-20.5)=";ABS(-20.5);"
abs(20.5)=";ABS(20.5)
INT%
function determines integer part of the argument.
Function
format: INT%(EXP)
where EXP is an floating-point expression.
This
function returns integer type result.
If the
argument is specified incorrectly (of a string type) then an error is
generated.
Example:
PRINT
"This is example INT% function"
PRINT "int(-20.3)=";INT%(-20.3);"
int(20.3)=";INT%(20.3)
These functions calculate sine, cosine, arc
tangent, square root, exponent, logarithm and common logarithm respectively.
Functions
formats:
SIN(EXP),
COS(EXP),
ATN(EXP),
SQR(EXP),
EXP(EXP),
LOG(EXP),
LOG10(EXP)
where EXP is an integer or a floating-point
expression.
This
functions return floating-point type result.
If the
argument is specified incorrectly (of a string type) then an error is
generated.
Example:
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
RND
function generates pseudorandom number in 0-1
interval.
Function
format: RND()
This
functions return floating-point type result.
The
arguments are ignored.
Example:
PRINT
"This is example RND function"
PRINT RND(),RND(),RND(),RND();
RANDOMIZE
PRINT RND(),RND(),RND(),RND();
LEN%
function determines string length.
Function
format: LEN%(EXP)
where EXP is a string expression.
This
function returns integer type result.
If the
argument is specified incorrectly (of an integer or a floating-point type) then
an error is generated.
Example:
PRINT
"This is example LEN function"
STRing_this$="aaa bbb ccc ddd"
PRINT "len=";LEN%(STRing_this$)
These functions return current date and time
respectively.
Functions
formats:
DAT$(),
CLK$()
These
functions return string type result.
The
arguments are ignored.
Date
format: day-month-year
Time
format: hour:min:sec
Example:
PRINT
"This is example DAT$ & CLK$."
PRINT "data=";DAT$;" time=";CLK$
D2STR$
function converts a number to a string containing its decimal notation.
Function
format: D2STR$(EXP)
where EXP is an integer number or a number
with floating point.
This
function returns string type result.
D2HEXSTR$
function converts an integer number to a string containing its hexadecimal
notation.
Function
format: D2HEXSTR$(EXP)
where EXP is an integer number.
This
function returns string type result.
STR2FLOAT
function converts a string to a number.
Function
format: STR2FLOAT(EXP)
where EXP is a string.
This
function returns a number with floating point. If a string cannot be converted
to a number then zero is returned.
STR2INT%
function converts a string to an integer number.
Function
format: STR2INT%(EXP)
where EXP is a string.
This
function returns an integer number. If a string cannot be converted to an
integer number then zero is returned.
Example:
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)
When Open
Basic encounters an error it generates an exception of ob_err type with the error code. User should intercept this
exception and handle it. ob_err
class has dedicated methods for such handling. Here is a typical scheme of
working with ob_err exceptions:
int main(int argc, char * argv[]){
int ret=0;//main return code
ifstream fi;//input stream
try{
ob_obasic
basic_interpreter(OB_NULL);//creating of the interpreter
fi.open("test1.bas",ios::binary);//opening
of input stream in binary mode
basic_interpreter.clear_project();
basic_interpreter.load_project(&fi);//loading of *.bas-program
ob_obasic::typeend
te=basic_interpreter.run();//running of *.bas-program
cout<<endl<<"Stop
by stop code";//printing of stop code
cout<<endl<<"Stop
code=";
switch(te){
case ob_obasic::ENDOPERATORDETECT
:cout<<"ENDOPERATORDETECT";break;
case ob_obasic::ENDFILEEND
:cout<<"ENDFILEEND";break;
case ob_obasic::BREAKPOINTEND
:cout<<"BREAKPOINTEND";break;
case ob_obasic::NOLOADEND
:cout<<"NOLOADEND";break;
case ob_obasic::BREAKBEFOREOPERATOR:cout<<"BREAKBEFOREOPERATOR";break;
case ob_obasic::BREAKAFTEROPERATOR
:cout<<"BREAKAFTEROPERATOR";break;
case ob_obasic::EOLEND
:cout<<"EOLEND";break;
default:cout<<"Unknown stop code";break;
}//switch
}//try
catch(ob_err& e){
cout<<endl<<"Stop
by
ret=e.getcode(); //acquiring of error
code
e.release(&cout,&ob_englmessage); //printing of text message in cout
}//OB catch
return ret;
}
ob_err class has getcode and release
methods.
virtual ob_type_codeerror
getcode();
virtual void release(ostream*
os,ob_message* currentmessage);
getcode method does not have arguments and
returns error code.
release method has two arguments: pointer
on the stream and pointer on diagnostic messages table. release release method writes to the specified stream a text
message from diagnostic messages table that corresponds to error code.
Open
Basic provides ob_englmessage
diagnostic messages table on English. User is able to create his own diagnostic
messages table on other language and use this table as release method second argument.
In order to get the string in which the error
occurred one should use ob_loadbreakstr
function.
Detailed
information about exceptions handling can be found in .\example\ob.cpp file.
Diagnostic
messages table is located in ob5.cpp
file.