@@ -0,0 +1,12 @@ | |||
# Default auto detect text, and normalize EOL | |||
* text=auto eol=crlf | |||
# Specific text files needing EOL fixing | |||
*.in text eol=crlf | |||
*.c text eol=crlf | |||
*.h text eol=crlf | |||
*.bas text eol=crlf | |||
INSTALL text eol=crlf | |||
COPYING text eol=crlf | |||
README text eol=crlf | |||
/bwbasic.doc text eol=crlf |
@@ -0,0 +1,3 @@ | |||
*.o | |||
/bwbasic | |||
/renum |
@@ -0,0 +1,342 @@ | |||
GNU GENERAL PUBLIC LICENSE | |||
Version 2, June 1991 | |||
Copyright (C) 1989, 1991 Free Software Foundation, Inc. | |||
675 Mass Ave, Cambridge, MA 02139, USA | |||
Everyone is permitted to copy and distribute verbatim copies | |||
of this license document, but changing it is not allowed. | |||
Preamble | |||
The licenses for most software are designed to take away your | |||
freedom to share and change it. By contrast, the GNU General Public | |||
License is intended to guarantee your freedom to share and change free | |||
software--to make sure the software is free for all its users. This | |||
General Public License applies to most of the Free Software | |||
Foundation's software and to any other program whose authors commit to | |||
using it. (Some other Free Software Foundation software is covered by | |||
the GNU Library General Public License instead.) You can apply it to | |||
your programs, too. | |||
When we speak of free software, we are referring to freedom, not | |||
price. Our General Public Licenses are designed to make sure that you | |||
have the freedom to distribute copies of free software (and charge for | |||
this service if you wish), that you receive source code or can get it | |||
if you want it, that you can change the software or use pieces of it | |||
in new free programs; and that you know you can do these things. | |||
To protect your rights, we need to make restrictions that forbid | |||
anyone to deny you these rights or to ask you to surrender the rights. | |||
These restrictions translate to certain responsibilities for you if you | |||
distribute copies of the software, or if you modify it. | |||
For example, if you distribute copies of such a program, whether | |||
gratis or for a fee, you must give the recipients all the rights that | |||
you have. You must make sure that they, too, receive or can get the | |||
source code. And you must show them these terms so they know their | |||
rights. | |||
We protect your rights with two steps: (1) copyright the software, and | |||
(2) offer you this license which gives you legal permission to copy, | |||
distribute and/or modify the software. | |||
Also, for each author's protection and ours, we want to make certain | |||
that everyone understands that there is no warranty for this free | |||
software. If the software is modified by someone else and passed on, we | |||
want its recipients to know that what they have is not the original, so | |||
that any problems introduced by others will not reflect on the original | |||
authors' reputations. | |||
Finally, any free program is threatened constantly by software | |||
patents. We wish to avoid the danger that redistributors of a free | |||
program will individually obtain patent licenses, in effect making the | |||
program proprietary. To prevent this, we have made it clear that any | |||
patent must be licensed for everyone's free use or not licensed at all. | |||
The precise terms and conditions for copying, distribution and | |||
modification follow. | |||
GNU GENERAL PUBLIC LICENSE | |||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION | |||
0. This License applies to any program or other work which contains | |||
a notice placed by the copyright holder saying it may be distributed | |||
under the terms of this General Public License. The "Program", below, | |||
refers to any such program or work, and a "work based on the Program" | |||
means either the Program or any derivative work under copyright law: | |||
that is to say, a work containing the Program or a portion of it, | |||
either verbatim or with modifications and/or translated into another | |||
language. (Hereinafter, translation is included without limitation in | |||
the term "modification".) Each licensee is addressed as "you". | |||
Activities other than copying, distribution and modification are not | |||
covered by this License; they are outside its scope. The act of | |||
running the Program is not restricted, and the output from the Program | |||
is covered only if its contents constitute a work based on the | |||
Program (independent of having been made by running the Program). | |||
Whether that is true depends on what the Program does. | |||
1. You may copy and distribute verbatim copies of the Program's | |||
source code as you receive it, in any medium, provided that you | |||
conspicuously and appropriately publish on each copy an appropriate | |||
copyright notice and disclaimer of warranty; keep intact all the | |||
notices that refer to this License and to the absence of any warranty; | |||
and give any other recipients of the Program a copy of this License | |||
along with the Program. | |||
You may charge a fee for the physical act of transferring a copy, and | |||
you may at your option offer warranty protection in exchange for a fee. | |||
2. You may modify your copy or copies of the Program or any portion | |||
of it, thus forming a work based on the Program, and copy and | |||
distribute such modifications or work under the terms of Section 1 | |||
above, provided that you also meet all of these conditions: | |||
a) You must cause the modified files to carry prominent notices | |||
stating that you changed the files and the date of any change. | |||
b) You must cause any work that you distribute or publish, that in | |||
whole or in part contains or is derived from the Program or any | |||
part thereof, to be licensed as a whole at no charge to all third | |||
parties under the terms of this License. | |||
c) If the modified program normally reads commands interactively | |||
when run, you must cause it, when started running for such | |||
interactive use in the most ordinary way, to print or display an | |||
announcement including an appropriate copyright notice and a | |||
notice that there is no warranty (or else, saying that you provide | |||
a warranty) and that users may redistribute the program under | |||
these conditions, and telling the user how to view a copy of this | |||
License. (Exception: if the Program itself is interactive but | |||
does not normally print such an announcement, your work based on | |||
the Program is not required to print an announcement.) | |||
These requirements apply to the modified work as a whole. If | |||
identifiable sections of that work are not derived from the Program, | |||
and can be reasonably considered independent and separate works in | |||
themselves, then this License, and its terms, do not apply to those | |||
sections when you distribute them as separate works. But when you | |||
distribute the same sections as part of a whole which is a work based | |||
on the Program, the distribution of the whole must be on the terms of | |||
this License, whose permissions for other licensees extend to the | |||
entire whole, and thus to each and every part regardless of who wrote it. | |||
Thus, it is not the intent of this section to claim rights or contest | |||
your rights to work written entirely by you; rather, the intent is to | |||
exercise the right to control the distribution of derivative or | |||
collective works based on the Program. | |||
In addition, mere aggregation of another work not based on the Program | |||
with the Program (or with a work based on the Program) on a volume of | |||
a storage or distribution medium does not bring the other work under | |||
the scope of this License. | |||
3. You may copy and distribute the Program (or a work based on it, | |||
under Section 2) in object code or executable form under the terms of | |||
Sections 1 and 2 above provided that you also do one of the following: | |||
a) Accompany it with the complete corresponding machine-readable | |||
source code, which must be distributed under the terms of Sections | |||
1 and 2 above on a medium customarily used for software interchange; or, | |||
b) Accompany it with a written offer, valid for at least three | |||
years, to give any third party, for a charge no more than your | |||
cost of physically performing source distribution, a complete | |||
machine-readable copy of the corresponding source code, to be | |||
distributed under the terms of Sections 1 and 2 above on a medium | |||
customarily used for software interchange; or, | |||
c) Accompany it with the information you received as to the offer | |||
to distribute corresponding source code. (This alternative is | |||
allowed only for noncommercial distribution and only if you | |||
received the program in object code or executable form with such | |||
an offer, in accord with Subsection b above.) | |||
The source code for a work means the preferred form of the work for | |||
making modifications to it. For an executable work, complete source | |||
code means all the source code for all modules it contains, plus any | |||
associated interface definition files, plus the scripts used to | |||
control compilation and installation of the executable. However, as a | |||
special exception, the source code distributed need not include | |||
anything that is normally distributed (in either source or binary | |||
form) with the major components (compiler, kernel, and so on) of the | |||
operating system on which the executable runs, unless that component | |||
itself accompanies the executable. | |||
If distribution of executable or object code is made by offering | |||
access to copy from a designated place, then offering equivalent | |||
access to copy the source code from the same place counts as | |||
distribution of the source code, even though third parties are not | |||
compelled to copy the source along with the object code. | |||
4. You may not copy, modify, sublicense, or distribute the Program | |||
except as expressly provided under this License. Any attempt | |||
otherwise to copy, modify, sublicense or distribute the Program is | |||
void, and will automatically terminate your rights under this License. | |||
However, parties who have received copies, or rights, from you under | |||
this License will not have their licenses terminated so long as such | |||
parties remain in full compliance. | |||
5. You are not required to accept this License, since you have not | |||
signed it. However, nothing else grants you permission to modify or | |||
distribute the Program or its derivative works. These actions are | |||
prohibited by law if you do not accept this License. Therefore, by | |||
modifying or distributing the Program (or any work based on the | |||
Program), you indicate your acceptance of this License to do so, and | |||
all its terms and conditions for copying, distributing or modifying | |||
the Program or works based on it. | |||
6. Each time you redistribute the Program (or any work based on the | |||
Program), the recipient automatically receives a license from the | |||
original licensor to copy, distribute or modify the Program subject to | |||
these terms and conditions. You may not impose any further | |||
restrictions on the recipients' exercise of the rights granted herein. | |||
You are not responsible for enforcing compliance by third parties to | |||
this License. | |||
7. If, as a consequence of a court judgment or allegation of patent | |||
infringement or for any other reason (not limited to patent issues), | |||
conditions are imposed on you (whether by court order, agreement or | |||
otherwise) that contradict the conditions of this License, they do not | |||
excuse you from the conditions of this License. If you cannot | |||
distribute so as to satisfy simultaneously your obligations under this | |||
License and any other pertinent obligations, then as a consequence you | |||
may not distribute the Program at all. For example, if a patent | |||
license would not permit royalty-free redistribution of the Program by | |||
all those who receive copies directly or indirectly through you, then | |||
the only way you could satisfy both it and this License would be to | |||
refrain entirely from distribution of the Program. | |||
If any portion of this section is held invalid or unenforceable under | |||
any particular circumstance, the balance of the section is intended to | |||
apply and the section as a whole is intended to apply in other | |||
circumstances. | |||
It is not the purpose of this section to induce you to infringe any | |||
patents or other property right claims or to contest validity of any | |||
such claims; this section has the sole purpose of protecting the | |||
integrity of the free software distribution system, which is | |||
implemented by public license practices. Many people have made | |||
generous contributions to the wide range of software distributed | |||
through that system in reliance on consistent application of that | |||
system; it is up to the author/donor to decide if he or she is willing | |||
to distribute software through any other system and a licensee cannot | |||
impose that choice. | |||
This section is intended to make thoroughly clear what is believed to | |||
be a consequence of the rest of this License. | |||
8. If the distribution and/or use of the Program is restricted in | |||
certain countries either by patents or by copyrighted interfaces, the | |||
original copyright holder who places the Program under this License | |||
may add an explicit geographical distribution limitation excluding | |||
those countries, so that distribution is permitted only in or among | |||
countries not thus excluded. In such case, this License incorporates | |||
the limitation as if written in the body of this License. | |||
9. The Free Software Foundation may publish revised and/or new versions | |||
of the General Public License from time to time. Such new versions will | |||
be similar in spirit to the present version, but may differ in detail to | |||
address new problems or concerns. | |||
Each version is given a distinguishing version number. If the Program | |||
specifies a version number of this License which applies to it and "any | |||
later version", you have the option of following the terms and conditions | |||
either of that version or of any later version published by the Free | |||
Software Foundation. If the Program does not specify a version number of | |||
this License, you may choose any version ever published by the Free Software | |||
Foundation. | |||
10. If you wish to incorporate parts of the Program into other free | |||
programs whose distribution conditions are different, write to the author | |||
to ask for permission. For software which is copyrighted by the Free | |||
Software Foundation, write to the Free Software Foundation; we sometimes | |||
make exceptions for this. Our decision will be guided by the two goals | |||
of preserving the free status of all derivatives of our free software and | |||
of promoting the sharing and reuse of software generally. | |||
NO WARRANTY | |||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY | |||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN | |||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES | |||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED | |||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS | |||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE | |||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, | |||
REPAIR OR CORRECTION. | |||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING | |||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR | |||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, | |||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING | |||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED | |||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY | |||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER | |||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE | |||
POSSIBILITY OF SUCH DAMAGES. | |||
END OF TERMS AND CONDITIONS | |||
Appendix: How to Apply These Terms to Your New Programs | |||
If you develop a new program, and you want it to be of the greatest | |||
possible use to the public, the best way to achieve this is to make it | |||
free software which everyone can redistribute and change under these terms. | |||
To do so, attach the following notices to the program. It is safest | |||
to attach them to the start of each source file to most effectively | |||
convey the exclusion of warranty; and each file should have at least | |||
the "copyright" line and a pointer to where the full notice is found. | |||
<one line to give the program's name and a brief idea of what it does.> | |||
Copyright (C) 19yy <name of author> | |||
This program is free software; you can redistribute it and/or modify | |||
it under the terms of the GNU General Public License as published by | |||
the Free Software Foundation; either version 2 of the License, or | |||
(at your option) any later version. | |||
This program is distributed in the hope that it will be useful, | |||
but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
GNU General Public License for more details. | |||
You should have received a copy of the GNU General Public License | |||
along with this program; if not, write to the Free Software | |||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
Also add information on how to contact you by electronic and paper mail. | |||
If the program is interactive, make it output a short notice like this | |||
when it starts in an interactive mode: | |||
Gnomovision version 69, Copyright (C) 19yy name of author | |||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. | |||
This is free software, and you are welcome to redistribute it | |||
under certain conditions; type `show c' for details. | |||
The hypothetical commands `show w' and `show c' should show the appropriate | |||
parts of the General Public License. Of course, the commands you use may | |||
be called something other than `show w' and `show c'; they could even be | |||
mouse-clicks or menu items--whatever suits your program. | |||
You should also get your employer (if you work as a programmer) or your | |||
school, if any, to sign a "copyright disclaimer" for the program, if | |||
necessary. Here is a sample; alter the names: | |||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program | |||
`Gnomovision' (which makes passes at compilers) written by James Hacker. | |||
<signature of Ty Coon>, 1 April 1989 | |||
Ty Coon, President of Vice | |||
This General Public License does not permit incorporating your program into | |||
proprietary programs. If your program is a subroutine library, you may | |||
consider it more useful to permit linking proprietary applications with the | |||
library. If this is what you want to do, use the GNU Library General | |||
Public License instead of this License. | |||
@@ -0,0 +1,158 @@ | |||
Some Notes on Installation of the Bywater BASIC Interpreter: | |||
----------------------------------------------------------- | |||
0. Quick-Start Guide For Compiling | |||
To use the default configuration (which is reasonable for most situations): | |||
On Unix, type "configure; make". | |||
On MS-DOS using QuickC, type "nmake -f makefile.qcl". | |||
You can skip the rest of this file unless you want to customize the | |||
BASIC dialect that is supported, or something goes wrong in the | |||
above commands. | |||
1. Compiler Requirements | |||
Although earlier versions of bwBASIC would compile only with | |||
ANSI C compilers, versions 2.10 and higher can be compiled | |||
with "stock" C compilers, i.e., compilers that comply with | |||
the older Kernighan and Ritchie C standard. | |||
Section I-B of bwbasic.h allows you to specify some compiler | |||
features. If you have an ANSI C compiler, you needn't worry | |||
with this. For stock C compilers, the default configuration | |||
presumes that your compiler supports signal() and raise() | |||
with the signal.h header, supports setjmp() and longjmp() | |||
with the setjmp.h header, and has a separate string.h | |||
header. If your compiler does not have these features | |||
and the related header files, you can indicate this in | |||
section I-B by setting appropriate flags to FALSE. | |||
2. Configuration of header files | |||
You may need to examine file "bwbasic.h" to make important | |||
changes for specific hardware and compiler configurations. | |||
You may also need to change "bwx_tty.h" if you are using the | |||
TTY implementation or "bwx_iqc.h" if you are using the version | |||
for PCs with Microsoft QuickC (see below on "implementations"). | |||
If you want to redefine messages or even the BASIC command | |||
names, you will need to edit "bwb_mes.h". | |||
3. Makefiles | |||
Several makefiles are provided: "makefile.qcl" will compile | |||
the program utilizing the Microsoft QuickC (tm) line-oriented | |||
compiler on DOS-based p.c.'s, and "makefile" will compile the | |||
program on Unix-based computers utilizing either a stock C | |||
compiler or Gnu C++. I have also compiled the program utilizing | |||
Borland's Turbo C++ (tm) on DOS-based machines, although I have | |||
not supplied a makefile for Turbo C++. | |||
If you try the "IQC" implementation, you will need to alter | |||
makefile.qcl to include bwx_iqc.c (and bqx_iqc.obj) instead | |||
of bwx_tty.*. | |||
4. Implementations | |||
The present status of bwBASIC allows two major implementations | |||
controlled by the IMP_TTY and IMP_IQC flags in bwbasic.h. | |||
IMP_TTY is the base implementation and presumes a simple | |||
TTY-style environment, with all keyboard and screen input | |||
and output directed through stdin and stdout. If IMP_TTY is | |||
defined as TRUE, then the file bwx_tty.h will be included, | |||
and a makefile should include compilation of bwx_tty.c. | |||
IMP_IQC is a somewhat more elaborate implementation for | |||
the IBM PC and compatible microcomputers utilizing the | |||
Microsoft QuickC compiler. This allows some more elaborate | |||
commands (CLS and LOCATE) and the INKEY$ function, and | |||
allows greater control over output. If IMP_IQC is defined | |||
as TRUE in bwbasic.h, then bwx_iqc.h will be included and | |||
bwx_iqc.c should be compiled in the makefile. | |||
Only one of the flags IMP_TTY or IMP_IQC should be set | |||
to TRUE. | |||
5. Flags Controlling Groups of Commands and Functions | |||
There are a number of flags which control groups of commands | |||
and functions to be implemented. | |||
(core) Commands and Functions in any implementation of | |||
bwBASIC; these are the ANSI Minimal BASIC core | |||
INTERACTIVE Commands supporting the interactive programming | |||
environment | |||
COMMON_CMDS Commands beyond ANSI Minimal BASIC which are common | |||
to Full ANSI BASIC and Microsoft BASICs | |||
COMMON_FUNCS Functions beyond the ANSI Mimimal BASIC core, but | |||
common to both ANSI Full BASIC and Microsoft-style | |||
BASIC varieties | |||
UNIX_CMDS Commands which require Unix-style directory and | |||
environment routines not specified in ANSI C | |||
STRUCT_CMDS Commands related to structured programming; all | |||
of these are part of the Full ANSI BASIC standard | |||
ANSI_FUNCS Functions unique to ANSI Full BASIC | |||
MS_CMDS Commands unique to Microsoft BASICs | |||
MS_FUNCS Functions unique to Microsoft BASICs | |||
6. Configurations | |||
The file bwbasic.h includes a number of configuration options | |||
that will automatically select groups of commands and functions | |||
according to predetermined patterns. These are: | |||
CFG_ANSIMINIMAL Conforms to ANSI Minimal BASIC standard X3.60-1978. | |||
CFG_COMMON Small implementation with commands and functions | |||
common to GWBASIC (tm) and ANSI full BASIC. | |||
CFG_MSTYPE Configuration similar to Microsoft line-oriented | |||
BASICs. | |||
CFG_ANSIFULL Conforms to ANSI Full BASIC standard X3.113-1987 | |||
(subset at present). | |||
CFG_CUSTOM Custom Configuration specified by user. | |||
Only one of these flags should be set to TRUE. | |||
7. Adding Commands and Functions | |||
In order to add a new command to bwBASIC, follow the following | |||
procedure: | |||
(a) Write the command body using function bwb_null() in bwb_cmd.c | |||
as a template. The command-body function (in C) must receive a | |||
pointer to a bwb_line structure, and must pass on a pointer to | |||
a bwb_line structure. The preferred method for returning from | |||
a command-body function is: return bwb_zline( l ); this will | |||
discriminate between MULTISEG_LINES programs which advance to | |||
the next segment and those which advance to the next line. | |||
(b) Add prototypes for the command-body function in bwbasic.h; | |||
you'll need one prototype with arguments in the ANSI_C section | |||
and one prototype without arguments in the non-ANSI_C section. | |||
(c) Add the command to the command table in bwb_tbl.c in the | |||
group you have selected for it. | |||
(d) Increment the number of commands for the group in which | |||
you have placed your command. | |||
The procedure for adding a new function is parallel to this, except that | |||
you should use fnc_null() in bwb_fnc.c as the template, and the | |||
function name must be added to the function table in bwb_tbl.c. |
@@ -0,0 +1,101 @@ | |||
# Unix Makefile for Bywater BASIC Interpreter | |||
srcdir = @srcdir@ | |||
VPATH = @srcdir@ | |||
CC = @CC@ | |||
INSTALL = @INSTALL@ | |||
INSTALL_PROGRAM = @INSTALL_PROGRAM@ | |||
INSTALL_DATA = @INSTALL_DATA@ | |||
DEFS = @DEFS@ | |||
CFLAGS = -O | |||
LDFLAGS = -s | |||
prefix = /usr/local | |||
exec_prefix = $(prefix) | |||
bindir = $(exec_prefix)/bin | |||
SHELL = /bin/sh | |||
CFILES= bwbasic.c bwb_int.c bwb_tbl.c bwb_cmd.c bwb_prn.c\ | |||
bwb_exp.c bwb_var.c bwb_inp.c bwb_fnc.c bwb_cnd.c\ | |||
bwb_ops.c bwb_dio.c bwb_str.c bwb_elx.c bwb_mth.c\ | |||
bwb_stc.c bwb_par.c bwx_tty.c | |||
OFILES= bwbasic.o bwb_int.o bwb_tbl.o bwb_cmd.o bwb_prn.o\ | |||
bwb_exp.o bwb_var.o bwb_inp.o bwb_fnc.o bwb_cnd.o\ | |||
bwb_ops.o bwb_dio.o bwb_str.o bwb_elx.o bwb_mth.o\ | |||
bwb_stc.o bwb_par.o bwx_tty.o | |||
HFILES= bwbasic.h bwb_mes.h bwx_tty.h | |||
MISCFILES= COPYING INSTALL Makefile.in README bwbasic.doc\ | |||
bwbasic.mak configure.in configure makefile.qcl\ | |||
bwb_tcc.c bwx_iqc.c bwx_iqc.h | |||
TESTFILES= \ | |||
abs.bas assign.bas callfunc.bas callsub.bas chain1.bas\ | |||
chain2.bas dataread.bas deffn.bas dim.bas doloop.bas\ | |||
dowhile.bas elseif.bas end.bas err.bas fncallfn.bas\ | |||
fornext.bas function.bas gosub.bas gotolabl.bas ifline.bas\ | |||
index.txt input.bas lof.bas loopuntl.bas main.bas\ | |||
mlifthen.bas on.bas onerr.bas onerrlbl.bas ongosub.bas\ | |||
opentest.bas option.bas putget.bas random.bas selcase.bas\ | |||
snglfunc.bas stop.bas term.bas whilwend.bas width.bas\ | |||
writeinp.bas | |||
DISTFILES= $(CFILES) $(HFILES) $(MISCFILES) | |||
all: bwbasic | |||
bwbasic: $(OFILES) | |||
$(CC) $(OFILES) -lm -o $@ $(LDFLAGS) | |||
$(OFILES): $(HFILES) | |||
.c.o: | |||
$(CC) -c $(CPPFLAGS) -I$(srcdir) $(DEFS) $(CFLAGS) $< | |||
install: all | |||
$(INSTALL_PROGRAM) bwbasic $(bindir)/bwbasic | |||
uninstall: | |||
rm -f $(bindir)/bwbasic | |||
Makefile: Makefile.in config.status | |||
$(SHELL) config.status | |||
config.status: configure | |||
$(SHELL) config.status --recheck | |||
configure: configure.in | |||
cd $(srcdir); autoconf | |||
TAGS: $(CFILES) | |||
etags $(CFILES) | |||
clean: | |||
rm -f *.o bwbasic core | |||
mostlyclean: clean | |||
distclean: clean | |||
rm -f Makefile config.status | |||
realclean: distclean | |||
rm -f TAGS | |||
dist: $(DISTFILES) | |||
echo bwbasic-2.10 > .fname | |||
rm -rf `cat .fname` | |||
mkdir `cat .fname` | |||
ln $(DISTFILES) `cat .fname` | |||
mkdir `cat .fname`/bwbtest | |||
cd bwbtest; ln $(TESTFILES) ../`cat ../.fname`/bwbtest | |||
tar czhf `cat .fname`.tar.gz `cat .fname` | |||
rm -rf `cat .fname` .fname | |||
# Prevent GNU make v3 from overflowing arg limit on SysV. | |||
.NOEXPORT: | |||
@@ -0,0 +1,189 @@ | |||
Bywater Software Announces | |||
Bywater BASIC Interpreter/Shell, version 2.10 | |||
--------------------------------------------- | |||
Copyright (c) 1993, Ted A. Campbell | |||
for bwBASIC version 2.10, 11 October 1993 | |||
DESCRIPTION: | |||
The Bywater BASIC Interpreter (bwBASIC) implements a large | |||
superset of the ANSI Standard for Minimal BASIC (X3.60-1978) | |||
and a significant subset of the ANSI Standard for Full BASIC | |||
(X3.113-1987) in C. It also offers shell programming facilities | |||
as an extension of BASIC. bwBASIC seeks to be as portable | |||
as possible. | |||
This version of Bywater BASIC is released under the terms of the | |||
GNU General Public License (GPL), which is distributed with this | |||
software in the file "COPYING". The GPL specifies the terms | |||
under which users may copy and use the software in this distribution. | |||
A separate license is available for commercial distribution, | |||
for information on which you should contact the author. | |||
IMPROVEMENTS OVER PREVIOUS VERSION (1.11): | |||
* now compilable on "stock" (older K&R specification) C compilers; | |||
* implements ANSI-BASIC-style structured programming, with | |||
called subroutines, multi-line functions, multi-line IF-THEN | |||
ELSE statements, SELECT CASE statements, etc.; | |||
* new enhancements to the interactive environment, such as DO NUM | |||
and DO UNNUM to number or unnumber all program lines; | |||
* addition of some hardware-specific commands such as CLS, LOCATE, | |||
and INKEY$ (at present for IBM PC and compatibles, using the | |||
Microsoft QuickC compiler), opening the way for more hardware- | |||
specific commands and functions in the future; | |||
* general improvements to reliability and portability, including | |||
more extensive testing than previous versions; | |||
OBTAINING THE SOURCE CODE: | |||
The source code for bwBASIC 2.10 will be posted to network news | |||
groups and is available immediately by anonymous ftp. To obtain | |||
the source code, ftp to site ftp.eng.umd.edu, cd to pub/basic and | |||
get the file bwbasic-2.10.tar.gz. | |||
COMMUNICATIONS: | |||
email: tcamp@delphi.com | |||
A LIST OF BASIC COMMANDS AND FUNCTIONS IMPLEMENTED in bwBASIC 2.10: | |||
Be aware that many of these commands and functions will not be | |||
available unless you have set certain flags in the header files. | |||
ABS( number ) | |||
ASC( string$ ) | |||
ATN( number ) | |||
CALL subroutine-name | |||
CASE constant | IF partial-expression | ELSE | |||
CHAIN file-name | |||
CHDIR pathname | |||
CHR$( number ) | |||
CINT( number ) | |||
CLEAR | |||
CLOSE [[#]file-number]... | |||
CLS | |||
COMMON variable [, variable...] | |||
COS( number ) | |||
CSNG( number ) | |||
CVD( string$ ) | |||
CVI( string$ ) | |||
CVS( string$ ) | |||
DATA constant[,constant]... | |||
DATE$ | |||
DEF FNname(arg...)] = expression | |||
DEFDBL letter[-letter](, letter[-letter])... | |||
DEFINT letter[-letter](, letter[-letter])... | |||
DEFSNG letter[-letter](, letter[-letter])... | |||
DEFSTR letter[-letter](, letter[-letter])... | |||
DELETE line[-line] | |||
DIM variable(elements...)[variable(elements...)]... | |||
DO NUM|UNNUM | |||
DO [WHILE expression] | |||
EDIT (* depends on variable BWB.EDITOR$) | |||
ELSE | |||
ELSEIF | |||
END FUNCTION | IF | SELECT | SUB | |||
ENVIRON variable-string$ = string$ | |||
ENVIRON$( variable-string ) | |||
EOF( device-number ) | |||
ERASE variable[, variable]... | |||
ERL | |||
ERR | |||
ERROR number | |||
EXIT FOR|DO | |||
EXP( number ) | |||
FIELD [#] device-number, number AS string-variable [, number AS string-variable...] | |||
FILES filespec$ (* depends on variable BWB.FILES$) | |||
FOR counter = start TO finish [STEP increment] | |||
FUNCTION function-definition | |||
GET [#] device-number [, record-number] | |||
GOSUB line | label | |||
GOTO line | label | |||
HEX$( number ) | |||
IF expression THEN [statement [ELSE statement]] | |||
INKEY$ | |||
INPUT [# device-number]|[;]["prompt string";]list of variables | |||
INSTR( [start-position,] string-searched$, string-pattern$ ) | |||
INT( number ) | |||
KILL file-name | |||
LEFT$( string$, number-of-spaces ) | |||
LEN( string$ ) | |||
LET variable = expression | |||
LINE INPUT [[#] device-number,]["prompt string";] string-variable$ | |||
LIST line[-line] | |||
LOAD file-name | |||
LOC( device-number ) | |||
LOCATE | |||
LOF( device-number ) | |||
LOG( number ) | |||
LOOP [UNTIL expression] | |||
LSET string-variable$ = expression | |||
MERGE file-name | |||
MID$( string$, start-position-in-string[, number-of-spaces ] ) | |||
MKD$( number ) | |||
MKDIR pathname | |||
MKI$( number ) | |||
MKS$( number ) | |||
NAME old-file-name AS new-file-name | |||
NEW | |||
NEXT counter | |||
OCT$( number ) | |||
ON variable GOTO|GOSUB line[,line,line,...] | |||
ON ERROR GOSUB line | label | |||
OPEN O|I|R, [#]device-number, file-name [,record length] | |||
file-name FOR INPUT|OUTPUT|APPEND AS [#]device-number [LEN = record-length] | |||
OPTION BASE number | |||
POS | |||
PRINT [# device-number,][USING format-string$;] expressions... | |||
PUT [#] device-number [, record-number] | |||
RANDOMIZE number | |||
READ variable[, variable]... | |||
REM string | |||
RESTORE line | |||
RETURN | |||
RIGHT$( string$, number-of-spaces ) | |||
RMDIR pathname | |||
RND( number ) | |||
RSET string-variable$ = expression | |||
RUN [line]|[file-name] | |||
SAVE file-name | |||
SELECT CASE expression | |||
SGN( number ) | |||
SIN( number ) | |||
SPACE$( number ) | |||
SPC( number ) | |||
SQR( number ) | |||
STOP | |||
STR$( number ) | |||
STRING$( number, ascii-value|string$ ) | |||
SUB subroutine-name | |||
SWAP variable, variable | |||
SYSTEM | |||
TAB( number ) | |||
TAN( number ) | |||
TIME$ | |||
TIMER | |||
TROFF | |||
TRON | |||
VAL( string$ ) | |||
WEND | |||
WHILE expression | |||
WIDTH [# device-number,] number | |||
WRITE [# device-number,] element [, element ].... |
@@ -0,0 +1,955 @@ | |||
/***************************************************************f | |||
bwb_int.c Line Interpretation Routines | |||
for Bywater BASIC Interpreter | |||
Copyright (c) 1993, Ted A. Campbell | |||
Bywater Software | |||
email: tcamp@delphi.com | |||
Copyright and Permissions Information: | |||
All U.S. and international rights are claimed by the author, | |||
Ted A. Campbell. | |||
This software is released under the terms of the GNU General | |||
Public License (GPL), which is distributed with this software | |||
in the file "COPYING". The GPL specifies the terms under | |||
which users may copy and use the software in this distribution. | |||
A separate license is available for commercial distribution, | |||
for information on which you should contact the author. | |||
***************************************************************/ | |||
#include <stdio.h> | |||
#include <ctype.h> | |||
#include "bwbasic.h" | |||
#include "bwb_mes.h" | |||
/*************************************************************** | |||
FUNCTION: adv_element() | |||
DESCRIPTION: This function reads characters in <buffer> | |||
beginning at <pos> and advances past a | |||
line element, incrementing <pos> appropri- | |||
ately and returning the line element in | |||
<element>. | |||
***************************************************************/ | |||
#if ANSI_C | |||
int | |||
adv_element( char *buffer, int *pos, char *element ) | |||
#else | |||
int | |||
adv_element( buffer, pos, element ) | |||
char *buffer; | |||
int *pos; | |||
char *element; | |||
#endif | |||
{ | |||
int loop; /* control loop */ | |||
int e_pos; /* position in element buffer */ | |||
int str_const; /* boolean: building a string constant */ | |||
/* advance beyond any initial whitespace */ | |||
adv_ws( buffer, pos ); | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in adv_element(): receieved <%s>.", &( buffer[ *pos ] )); | |||
bwb_debug( bwb_ebuf ); | |||
#endif | |||
/* now loop while building an element and looking for an | |||
element terminator */ | |||
loop = TRUE; | |||
e_pos = 0; | |||
element[ e_pos ] = '\0'; | |||
str_const = FALSE; | |||
while ( loop == TRUE ) | |||
{ | |||
switch( buffer[ *pos ] ) | |||
{ | |||
case ',': /* element terminators */ | |||
case ';': | |||
#if MULTISEG_LINES | |||
case ':': | |||
#endif | |||
case '=': | |||
case ' ': | |||
case '\t': | |||
case '\0': | |||
case '\n': | |||
case '\r': | |||
if ( str_const == TRUE ) | |||
{ | |||
element[ e_pos ] = buffer[ *pos ]; | |||
++e_pos; | |||
++( *pos ); | |||
element[ e_pos ] = '\0'; | |||
} | |||
else | |||
{ | |||
return TRUE; | |||
} | |||
break; | |||
case '\"': /* string constant */ | |||
element[ e_pos ] = buffer[ *pos ]; | |||
++e_pos; | |||
++( *pos ); | |||
element[ e_pos ] = '\0'; | |||
if ( str_const == TRUE ) /* termination of string constant */ | |||
{ | |||
return TRUE; | |||
} | |||
else /* beginning of string constant */ | |||
{ | |||
str_const = TRUE; | |||
} | |||
break; | |||
default: | |||
element[ e_pos ] = buffer[ *pos ]; | |||
++e_pos; | |||
++( *pos ); | |||
element[ e_pos ] = '\0'; | |||
break; | |||
} | |||
} | |||
/* This should not happen */ | |||
return FALSE; | |||
} | |||
/*************************************************************** | |||
FUNCTION: adv_ws() | |||
DESCRIPTION: This function reads characters in <buffer> | |||
beginning at <pos> and advances past any | |||
whitespace, incrementing <pos> appropri- | |||
ately. | |||
***************************************************************/ | |||
#if ANSI_C | |||
int | |||
adv_ws( char *buffer, int *pos ) | |||
#else | |||
int | |||
adv_ws( buffer, pos ) | |||
char *buffer; | |||
int *pos; | |||
#endif | |||
{ | |||
int loop; | |||
loop = TRUE; | |||
while ( loop == TRUE ) | |||
{ | |||
switch( buffer[ *pos ] ) | |||
{ | |||
case ' ': | |||
case '\t': | |||
++( *pos ); | |||
break; | |||
default: | |||
return TRUE; | |||
} | |||
} | |||
/* This should not happen */ | |||
return FALSE; | |||
} | |||
/*************************************************************** | |||
FUNCTION: adv_eos() | |||
DESCRIPTION: This function reads characters in <buffer> | |||
beginning at <pos> and advances to the | |||
end of a segment delimited by ':', | |||
incrementing <pos> appropriately. | |||
***************************************************************/ | |||
#if MULTISEG_LINES | |||
#if ANSI_C | |||
int | |||
adv_eos( char *buffer, int *pos ) | |||
#else | |||
int | |||
adv_eos( buffer, pos ) | |||
char *buffer; | |||
int *pos; | |||
#endif | |||
{ | |||
int loop; | |||
loop = TRUE; | |||
while ( loop == TRUE ) | |||
{ | |||
if ( is_eol( buffer, pos ) == TRUE ) | |||
{ | |||
return FALSE; | |||
} | |||
switch( buffer[ *pos ] ) | |||
{ | |||
case ':': /* end of segment marker */ | |||
++( *pos ); | |||
return TRUE; | |||
case '\"': /* begin quoted string */ | |||
++( *pos ); | |||
while ( buffer[ *pos ] != '\"' ) | |||
{ | |||
if ( is_eol( buffer, pos ) == TRUE ) | |||
{ | |||
return FALSE; | |||
} | |||
else | |||
{ | |||
++( *pos ); | |||
} | |||
} | |||
break; | |||
default: | |||
++( *pos ); | |||
} | |||
} | |||
/* This should not happen */ | |||
return FALSE; | |||
} | |||
#endif /* MULTISEG_LINES */ | |||
/*************************************************************** | |||
FUNCTION: bwb_strtoupper() | |||
DESCRIPTION: This function converts the string in | |||
<buffer> to upper-case characters. | |||
***************************************************************/ | |||
#if ANSI_C | |||
int | |||
bwb_strtoupper( char *buffer ) | |||
#else | |||
int | |||
bwb_strtoupper( buffer ) | |||
char *buffer; | |||
#endif | |||
{ | |||
char *p; | |||
p = buffer; | |||
while ( *p != '\0' ) | |||
{ | |||
if ( islower( *p ) != FALSE ) | |||
{ | |||
*p = (char) toupper( *p ); | |||
} | |||
++p; | |||
} | |||
return TRUE; | |||
} | |||
/*************************************************************** | |||
FUNCTION: line_start() | |||
DESCRIPTION: This function reads a line buffer in | |||
<buffer> beginning at the position | |||
<pos> and attempts to determine (a) | |||
the position of the line number in the | |||
buffer (returned in <lnpos>), (b) the | |||
line number at this position (returned | |||
in <lnum>), (c) the position of the | |||
BASIC command in the buffer (returned | |||
in <cmdpos>), (d) the position of this | |||
BASIC command in the command table | |||
(returned in <cmdnum>), and (e) the | |||
position of the beginning of the rest | |||
of the line (returned in <startpos>). | |||
Although <startpos> must be returned | |||
as a positive integer, the other | |||
searches may fail, in which case FALSE | |||
will be returned in their positions. | |||
<pos> is not incremented. | |||
***************************************************************/ | |||
#if ANSI_C | |||
int | |||
line_start( char *buffer, int *pos, int *lnpos, int *lnum, int *cmdpos, | |||
int *cmdnum, int *startpos ) | |||
#else | |||
int | |||
line_start( buffer, pos, lnpos, lnum, cmdpos, cmdnum, startpos ) | |||
char *buffer; | |||
int *pos; | |||
int *lnpos; | |||
int *lnum; | |||
int *cmdpos; | |||
int *cmdnum; | |||
int *startpos; | |||
#endif | |||
{ | |||
static int position; | |||
static char *tbuf; | |||
static int init = FALSE; | |||
/* get memory for temporary buffer if necessary */ | |||
if ( init == FALSE ) | |||
{ | |||
init = TRUE; | |||
if ( ( tbuf = calloc( MAXSTRINGSIZE + 1, sizeof( char ) )) == NULL ) | |||
{ | |||
#if PROG_ERRORS | |||
bwb_error( "in line_start(): failed to get memory for tbuf" ); | |||
#else | |||
bwb_error( err_getmem ); | |||
#endif | |||
} | |||
} | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in line_start(): pos <%d> buffer <%s>", *pos, | |||
buffer ); | |||
bwb_debug( bwb_ebuf ); | |||
#endif | |||
/* set initial values */ | |||
*startpos = position = *pos; | |||
*cmdpos = *lnpos = *pos; | |||
*cmdnum = *lnum = -1; | |||
/* check for null line */ | |||
adv_ws( buffer, &position ); | |||
if ( buffer[ position ] == '\0' ) | |||
{ | |||
#if INTENSIVE_DEBUG | |||
bwb_debug( "in line_start(): found NULL line" ); | |||
#endif | |||
*cmdnum = getcmdnum( CMD_REM ); | |||
return TRUE; | |||
} | |||
/* advance beyond the first element */ | |||
*lnpos = position; | |||
scan_element( buffer, &position, tbuf ); | |||
adv_ws( buffer, &position ); | |||
/* test for a line number in the first element */ | |||
if ( is_numconst( tbuf ) == TRUE ) /* a line number */ | |||
{ | |||
*lnum = atoi( tbuf ); | |||
*startpos = position; /* temp */ | |||
*cmdpos = position; | |||
scan_element( buffer, &position, tbuf ); /* advance past next element */ | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in line_start(): new element is <%s>", tbuf ); | |||
bwb_debug( bwb_ebuf ); | |||
#endif | |||
#if STRUCT_CMDS | |||
if ( is_label( tbuf ) == TRUE ) | |||
{ | |||
*cmdnum = getcmdnum( CMD_LABEL ); | |||
adv_ws( buffer, &position ); | |||
*startpos = position; | |||
} | |||
else if ( is_cmd( tbuf, cmdnum ) == TRUE ) | |||
#else | |||
if ( is_cmd( tbuf, cmdnum ) == TRUE ) | |||
#endif | |||
{ | |||
adv_ws( buffer, &position ); | |||
*startpos = position; | |||
} | |||
else if ( is_let( &( buffer[ *cmdpos ] ), cmdnum ) == TRUE ) | |||
{ | |||
*cmdpos = -1; | |||
} | |||
else | |||
{ | |||
*cmdpos = *cmdnum = -1; | |||
} | |||
} | |||
/* not a line number */ | |||
else | |||
{ | |||
*lnum = -1; | |||
*lnpos = -1; | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in line_start(): no line number, element <%s>.", | |||
tbuf ); | |||
bwb_debug( bwb_ebuf ); | |||
#endif | |||
#if STRUCT_CMDS | |||
if ( is_label( tbuf ) == TRUE ) | |||
{ | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in line_start(): label detected <%s>.", | |||
tbuf ); | |||
bwb_debug( bwb_ebuf ); | |||
#endif | |||
*cmdnum = getcmdnum( CMD_LABEL ); | |||
adv_ws( buffer, &position ); | |||
*startpos = position; | |||
} | |||
else if ( is_cmd( tbuf, cmdnum ) == TRUE ) | |||
#else | |||
if ( is_cmd( tbuf, cmdnum ) == TRUE ) | |||
#endif | |||
{ | |||
adv_ws( buffer, &position ); | |||
*startpos = position; | |||
} | |||
else if ( is_let( &( buffer[ position ] ), cmdnum ) == TRUE ) | |||
{ | |||
adv_ws( buffer, &position ); | |||
*cmdpos = -1; | |||
} | |||
else | |||
{ | |||
*cmdpos = *cmdnum = -1; | |||
} | |||
} | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in line_start(): lnpos <%d> lnum <%d>", | |||
*lnpos, *lnum ); | |||
bwb_debug( bwb_ebuf ); | |||
sprintf( bwb_ebuf, "in line_start(): cmdpos <%d> cmdnum <%d> startpos <%d>", | |||
*cmdpos, *cmdnum, *startpos ); | |||
bwb_debug( bwb_ebuf ); | |||
#endif | |||
/* return */ | |||
return TRUE; | |||
} | |||
/*************************************************************** | |||
FUNCTION: is_cmd() | |||
DESCRIPTION: This function determines whether the | |||
string in 'buffer' is a BASIC command | |||
statement, returning TRUE or FALSE, | |||
and if TRUE returning the command number | |||
in the command lookup table in the | |||
integer pointed to by 'cmdnum'. | |||
***************************************************************/ | |||
#if ANSI_C | |||
int | |||
is_cmd( char *buffer, int *cmdnum ) | |||
#else | |||
int | |||
is_cmd( buffer, cmdnum ) | |||
char *buffer; | |||
int *cmdnum; | |||
#endif | |||
{ | |||
register int n; | |||
/* Convert the command name to upper case */ | |||
bwb_strtoupper( buffer ); | |||
/* Go through the command table and search for a match. */ | |||
for ( n = 0; n < COMMANDS; ++n ) | |||
{ | |||
if ( strcmp( bwb_cmdtable[ n ].name, buffer ) == 0 ) | |||
{ | |||
*cmdnum = n; | |||
return TRUE; | |||
} | |||
} | |||
/* No command name was found */ | |||
*cmdnum = -1; | |||
return FALSE; | |||
} | |||
/*************************************************************** | |||
FUNCTION: is_let() | |||
DESCRIPTION: This function tries to determine if the | |||
expression in <buffer> is a LET statement | |||
without the LET command specified. | |||
***************************************************************/ | |||
#if ANSI_C | |||
int | |||
is_let( char *buffer, int *cmdnum ) | |||
#else | |||
int | |||
is_let( buffer, cmdnum ) | |||
char *buffer; | |||
int *cmdnum; | |||
#endif | |||
{ | |||
register int n, i; | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in is_let(): buffer <%s>", buffer ); | |||
bwb_debug( bwb_ebuf ); | |||
#endif | |||
/* Go through the expression and search for an assignment operator. */ | |||
for ( n = 0; buffer[ n ] != '\0'; ++n ) | |||
{ | |||
switch( buffer[ n ] ) | |||
{ | |||
case '\"': /* string constant */ | |||
++n; | |||
while( buffer[ n ] != '\"' ) | |||
{ | |||
++n; | |||
if ( buffer[ n ] == '\0' ) | |||
{ | |||
#if PROG_ERRORS | |||
sprintf( bwb_ebuf, "Incomplete string constant" ); | |||
bwb_error( bwb_ebuf ); | |||
#else | |||
bwb_error( err_syntax ); | |||
#endif | |||
*cmdnum = -1; | |||
return FALSE; | |||
} | |||
} | |||
++n; | |||
break; | |||
case '=': | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in is_let(): implied LET found." ); | |||
bwb_debug( bwb_ebuf ); | |||
#endif | |||
for ( i = 0; i < COMMANDS; ++i ) | |||
{ | |||
if ( strncmp( bwb_cmdtable[ i ].name, "LET", (size_t) 3 ) == 0 ) | |||
{ | |||
*cmdnum = i; | |||
} | |||
} | |||
return TRUE; | |||
} | |||
} | |||
/* No command name was found */ | |||
*cmdnum = -1; | |||
return FALSE; | |||
} | |||
/*************************************************************** | |||
FUNCTION: bwb_stripcr() | |||
DESCRIPTION: This function strips the carriage return | |||
or line-feed from the end of a string. | |||
***************************************************************/ | |||
#if ANSI_C | |||
int | |||
bwb_stripcr( char *s ) | |||
#else | |||
int | |||
bwb_stripcr( s ) | |||
char *s; | |||
#endif | |||
{ | |||
char *p; | |||
p = s; | |||
while ( *p != 0 ) | |||
{ | |||
switch( *p ) | |||
{ | |||
case '\r': | |||
case '\n': | |||
*p = 0; | |||
return TRUE; | |||
} | |||
++p; | |||
} | |||
*p = 0; | |||
return TRUE; | |||
} | |||
/*************************************************************** | |||
FUNCTION: is_numconst() | |||
DESCRIPTION: This function reads the string in <buffer> | |||
and returns TRUE if it is a numerical | |||
constant and FALSE if it is not. At | |||
this point, only decimal (base 10) | |||
constants are detected. | |||
***************************************************************/ | |||
#if ANSI_C | |||
int | |||
is_numconst( char *buffer ) | |||
#else | |||
int | |||
is_numconst( buffer ) | |||
char *buffer; | |||
#endif | |||
{ | |||
char *p; | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in is_numconst(): received string <%s>.", buffer ); | |||
bwb_debug( bwb_ebuf ); | |||
#endif | |||
/* Return FALSE for empty buffer */ | |||
if ( buffer[ 0 ] == '\0' ) | |||
{ | |||
return FALSE; | |||
} | |||
/* else check digits */ | |||
p = buffer; | |||
while( *p != '\0' ) | |||
{ | |||
switch( *p ) | |||
{ | |||
case '0': | |||
case '1': | |||
case '2': | |||
case '3': | |||
case '4': | |||
case '5': | |||
case '6': | |||
case '7': | |||
case '8': | |||
case '9': | |||
break; | |||
default: | |||
return FALSE; | |||
} | |||
++p; | |||
} | |||
/* only numerical characters detected */ | |||
return TRUE; | |||
} | |||
/*************************************************************** | |||
FUNCTION: bwb_numseq() | |||
DESCRIPTION: This function reads in a sequence of | |||
numbers (e.g., "10-120"), returning | |||
the first and last numbers in the sequence | |||
in the integers pointed to by 'start' and | |||
'end'. | |||
***************************************************************/ | |||
#if ANSI_C | |||
int | |||
bwb_numseq( char *buffer, int *start, int *end ) | |||
#else | |||
int | |||
bwb_numseq( buffer, start, end ) | |||
char *buffer; | |||
int *start; | |||
int *end; | |||
#endif | |||
{ | |||
register int b, n; | |||
int numbers; | |||
static char *tbuf; | |||
static int init = FALSE; | |||
/* get memory for temporary buffer if necessary */ | |||
if ( init == FALSE ) | |||
{ | |||
init = TRUE; | |||
if ( ( tbuf = calloc( MAXSTRINGSIZE + 1, sizeof( char ) )) == NULL ) | |||
{ | |||
#if PROG_ERRORS | |||
bwb_error( "in bwb_numseq(): failed to find memory for tbuf" ); | |||
#else | |||
bwb_error( err_getmem ); | |||
#endif | |||
} | |||
} | |||
if ( buffer[ 0 ] == 0 ) | |||
{ | |||
*start = *end = 0; | |||
return FALSE; | |||
} | |||
numbers = n = b = 0; | |||
tbuf[ 0 ] = 0; | |||
while( TRUE ) | |||
{ | |||
switch( buffer[ b ] ) | |||
{ | |||
case 0: /* end of string */ | |||
case '\n': | |||
case '\r': | |||
if ( n > 0 ) | |||
{ | |||
if ( numbers == 0 ) | |||
{ | |||
*end = 0; | |||
*start = atoi( tbuf ); | |||
++numbers; | |||
} | |||
else | |||
{ | |||
*end = atoi( tbuf ); | |||
return TRUE; | |||
} | |||
} | |||
else | |||
{ | |||
if ( numbers == 0 ) | |||
{ | |||
*start = *end = 0; | |||
} | |||
else if ( numbers == 1 ) | |||
{ | |||
*end = 0; | |||
} | |||
else if ( ( numbers == 2 ) && ( tbuf[ 0 ] == 0 )) | |||
{ | |||
*end = 0; | |||
} | |||
} | |||
return TRUE; | |||
#ifdef ALLOWWHITESPACE | |||
case ' ': /* whitespace */ | |||
case '\t': | |||
#endif | |||
case '-': /* or skip to next number */ | |||
if ( n > 0 ) | |||
{ | |||
if ( numbers == 0 ) | |||
{ | |||
*start = atoi( tbuf ); | |||
++numbers; | |||
} | |||
else | |||
{ | |||
*end = atoi( tbuf ); | |||
return TRUE; | |||
} | |||
} | |||
++b; | |||
n = 0; | |||
break; | |||
case '0': | |||
case '1': | |||
case '2': | |||
case '3': | |||
case '4': | |||
case '5': | |||
case '6': | |||
case '7': | |||
case '8': | |||
case '9': | |||
tbuf[ n ] = buffer[ b ]; | |||
++n; | |||
tbuf[ n ] = 0; | |||
++b; | |||
break; | |||
default: | |||
#if PROG_ERRORS | |||
sprintf( bwb_ebuf, | |||
"ERROR: character <%c> unexpected in numerical sequence", | |||
buffer[ b ] ); | |||
++b; | |||
bwb_error( bwb_ebuf ); | |||
#else | |||
bwb_error( err_syntax ); | |||
#endif | |||
break; | |||
} | |||
} | |||
} | |||
/*************************************************************** | |||
FUNCTION: bwb_freeline() | |||
DESCRIPTION: This function frees memory associated | |||
with a program line in memory. | |||
***************************************************************/ | |||
#if ANSI_C | |||
int | |||
bwb_freeline( struct bwb_line *l ) | |||
#else | |||
int | |||
bwb_freeline( l ) | |||
struct bwb_line *l; | |||
#endif | |||
{ | |||
/* free arguments if there are any */ | |||
free( l ); | |||
return TRUE; | |||
} | |||
/*************************************************************** | |||
FUNCTION: int_qmdstr() | |||
DESCRIPTION: This function returns a string delimited | |||
by quotation marks. | |||
***************************************************************/ | |||
#if ANSI_C | |||
int | |||
int_qmdstr( char *buffer_a, char *buffer_b ) | |||
#else | |||
int | |||
int_qmdstr( buffer_a, buffer_b ) | |||
char *buffer_a; | |||
char *buffer_b; | |||
#endif | |||
{ | |||
char *a, *b; | |||
a = buffer_a; | |||
++a; /* advance beyond quotation mark */ | |||
b = buffer_b; | |||
while( *a != '\"' ) | |||
{ | |||
*b = *a; | |||
++a; | |||
++b; | |||
*b = '\0'; | |||
} | |||
return TRUE; | |||
} | |||
/*************************************************************** | |||
FUNCTION: is_eol() | |||
DESCRIPTION: This function determines whether the buffer | |||
is at the end of a line. | |||
***************************************************************/ | |||
#if ANSI_C | |||
extern int | |||
is_eol( char *buffer, int *position ) | |||
#else | |||
int | |||
is_eol( buffer, position ) | |||
char *buffer; | |||
int *position; | |||
#endif | |||
{ | |||
adv_ws( buffer, position ); | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in is_eol(): character is <0x%x> = <%c>", | |||
buffer[ *position ], buffer[ *position ] ); | |||
bwb_debug( bwb_ebuf ); | |||
#endif | |||
switch( buffer[ *position ] ) | |||
{ | |||
case '\0': | |||
case '\n': | |||
case '\r': | |||
#if MULTISEG_LINES | |||
case ':': | |||
#endif | |||
return TRUE; | |||
default: | |||
return FALSE; | |||
} | |||
} | |||
@@ -0,0 +1,474 @@ | |||
/*************************************************************** | |||
bwb_mes.h Header File for Natural-Language-Specific | |||
Text Messages for Bywater BASIC Interpreter | |||
Copyright (c) 1993, Ted A. Campbell | |||
Bywater Software | |||
email: tcamp@delphi.com | |||
Copyright and Permissions Information: | |||
All U.S. and international rights are claimed by the author, | |||
Ted A. Campbell. | |||
This software is released under the terms of the GNU General | |||
Public License (GPL), which is distributed with this software | |||
in the file "COPYING". The GPL specifies the terms under | |||
which users may copy and use the software in this distribution. | |||
A separate license is available for commercial distribution, | |||
for information on which you should contact the author. | |||
***************************************************************/ | |||
#ifndef TRUE | |||
#define TRUE 1 | |||
#define FALSE 0 | |||
#endif | |||
/**************************************************************** | |||
The following Latin conventions are used: | |||
LATIN ENGLISH | |||
acies datorum array (of data) | |||
crusta shell | |||
litteras (character) string | |||
memoria mutabilis RAM | |||
organum device | |||
ordo line | |||
praeceptum command | |||
praecepta program (commands) | |||
praecepta interna operating system | |||
praeceptellum function | |||
tabula file | |||
****************************************************************/ | |||
#if LATIN | |||
#define MES_SIGNON "Interpres <Super Flumina> ad linguam BASIC, versionis" | |||
#define MES_COPYRIGHT "Iure proprio scriptoris (c) 1993, Eduardi de Campobello" | |||
#define MES_LANGUAGE "Cum nuntiis latinis ab ipso E. de C." | |||
#define PROMPT "bwBASIC: " | |||
#define ERROR_HEADER "ERRANT praecepta in ordine" | |||
#define ERRD_HEADER "ERRANT praecepta" | |||
#define MATHERR_HEADER "ERRANT praecepta" | |||
#define MES_BREAK "Intermittuntur praecepta in ordine" | |||
#define ERR_OPENFILE "Non patet tabula quod <%s> vocatur" | |||
#define ERR_GETMEM "Deest memoria mutabilis" | |||
#define ERR_LINENO "Non adicitur novus ordo praeceptorum" | |||
#define ERR_LNNOTFOUND "Non invenitur ordo praeceptorum <%d>" | |||
#define ERR_LOADNOFN "LOAD requirit nomen ad tabulam" | |||
#define ERR_NOLN "Non invenitur ordo praeceptorum" | |||
#define ERR_NOFN "Non invenitur nomen ad tabulam" | |||
#define ERR_RETNOGOSUB "RETURN sine GOSUB" | |||
#define ERR_INCOMPLETE "Praeceptum imcompletum" | |||
#define ERR_ONNOGOTO "ON sine GOTO sive GOSUB" | |||
#define ERR_VALOORANGE "Numerus in praeceptis excedit fines" | |||
#define ERR_SYNTAX "Non sequunter praecepta" | |||
#define ERR_DEVNUM "Numerus ad organum invalidum est" | |||
#define ERR_DEV "Errat organum" | |||
#define ERR_OPSYS "Errant praecepta interna" | |||
#define ERR_ARGSTR "Praeceptum requirit litteras" | |||
#define ERR_DEFCHAR "ad varium definiendum" | |||
#define ERR_MISMATCH "Non congruunt typus" | |||
#define ERR_DIMNOTARRAY "Praeceptum requirit nomen ad aciem datorum" | |||
#define ERR_OD "Desunt data" | |||
#define ERR_OVERFLOW "Data excedunt fines" | |||
#define ERR_NF "NEXT sine FOR" | |||
#define ERR_UF "Non definitur praeceptellum" | |||
#define ERR_DBZ "Non licet divisio ab nihilo" | |||
#define ERR_REDIM "Non licet varium iterum definiendum" | |||
#define ERR_OBDIM "Debet OPTION BASE procedere DIM" | |||
#define ERR_UC "Praeceptum incognitum est" | |||
#define ERR_NOPROGFILE "Tabula praeceptorum non invenitur" | |||
#endif | |||
#if POL_ENGLISH | |||
#define MES_SIGNON "Bywater BASIC Interpreter/Shell, version" | |||
#define MES_COPYRIGHT "Copyright (c) 1993, Ted A. Campbell" | |||
#define MES_LANGUAGE "Polite English messages courtesy of t.a.c." | |||
#define PROMPT "How may we help you? " | |||
#define ERROR_HEADER "Very sorry. There is a problem in line" | |||
#define ERRD_HEADER "Very sorry. There is a problem" | |||
#define MATHERR_HEADER "We have a small problem" | |||
#define MES_BREAK "At your request, the program has been interrupted at line" | |||
#define ERR_OPENFILE "I'm afraid we have failed \nto open file %s." | |||
#define ERR_GETMEM "I'm afraid we have failed \nto find sufficient memory." | |||
#define ERR_LINENO "I'm afraid we have failed \nto link line number." | |||
#define ERR_LNNOTFOUND "I'm afraid that we \ncannot find line number %d." | |||
#define ERR_LOADNOFN "Could you perhaps specify \nwhich file you wish to be loaded?" | |||
#define ERR_NOLN "It would help greatly \nif there were a line number here." | |||
#define ERR_NOFN "It would help greatly \nif there were a file name here." | |||
#define ERR_RETNOGOSUB "Is it possible \nthat there is a RETURN without a GOSUB here?" | |||
#define ERR_INCOMPLETE "I'm afraid that the statement\nappears to be incomplete." | |||
#define ERR_ONNOGOTO "It appears that there is an ON \nwithout a corresponding GOTO or GOSUB statement." | |||
#define ERR_VALOORANGE "A value given here \nseems to be out of range." | |||
#define ERR_SYNTAX "Could it be \nthat there is a syntax error at this point?" | |||
#define ERR_DEVNUM "The device or file \nnumber here does not seem to be correct." | |||
#define ERR_DEV "There appears \nto have been an error addressing the file or device \nwhich you requested." | |||
#define ERR_OPSYS "A most unfortunate error \nseems to have been generated by the computer's operating system." | |||
#define ERR_ARGSTR "Could you perhaps \nsupply a string argument at this point?" | |||
#define ERR_DEFCHAR "The variable definition \nat this point appears to have an improper argument." | |||
#define ERR_MISMATCH "It would appear \nthat something in this statement is rather seriously mismatched." | |||
#define ERR_DIMNOTARRAY "Could you perhaps \nsupply an array name for the argument at this point?" | |||
#define ERR_OD "Oh dear, we seem to have no more data to read now." | |||
#define ERR_OVERFLOW "Subhuman devices \ndo have their limits, and we're afraid that at this point \nthe limits of Bywater BASIC have been exceeded." | |||
#define ERR_NF "There seems to be \na NEXT statement without a corresponding FOR statement. Could you check on it?" | |||
#define ERR_UF "It would appear \nthat the function named at this point has not been defined." | |||
#define ERR_DBZ "Unfortunately, \ndivision by zero can cause dreadful problems in a computer." | |||
#define ERR_REDIM "We're very sorry \nto say that a variable such as this cannot be redimensioned." | |||
#define ERR_OBDIM "It would be ever so helpful \nif the OPTION BASE statement were to be called prior to the DIM statement." | |||
#define ERR_UC "I'm afraid that \nwe are unable to recognize the command you have given here." | |||
#define ERR_NOPROGFILE "Very sorry, but \nwe simply must have a program file to interpret." | |||
#endif | |||
#if IMP_ENGLISH | |||
#define MES_SIGNON "Bywater BASIC Interpreter/Shell, version" | |||
#define MES_COPYRIGHT "Watch it: Copyright (c) 1993, Ted A. Campbell" | |||
#define MES_LANGUAGE "Impolite English messages courtesy of Oscar the Grouch" | |||
#define PROMPT "(*sigh) What now? " | |||
#define ERROR_HEADER "YOU SCREWED UP at line" | |||
#define ERRD_HEADER "YOU SCREWED UP" | |||
#define MATHERR_HEADER "ANOTHER SCREWUP!" | |||
#define MES_BREAK "Only a geek like you would interrupt this program at line" | |||
#define ERR_OPENFILE "Ha ha! I can't open file %s. Too bad, sucker." | |||
#define ERR_GETMEM "There isn't near enough memory \nfor this lunacy." | |||
#define ERR_LINENO "You jerk: \nyou entered a non-existent line number." | |||
#define ERR_LNNOTFOUND "You total idiot. \nLine number %d isn't there. HA!" | |||
#define ERR_LOADNOFN "Get out of here. \nNo way to load that file." | |||
#define ERR_NOLN "Dumb bozo: you need to put \na LINE NUMBER here. Hint: Can you count?" | |||
#define ERR_NOFN "Nerd of the year. \nYou forgot to enter a file name. \nWhy don't you learn BASIC and come back in a year?" | |||
#define ERR_RETNOGOSUB "Oh come on, total amateur. \nYou've got a RETURN without a GOSUB" | |||
#define ERR_INCOMPLETE "Dimwit. Why don't you \ncomplete the statement here for a change." | |||
#define ERR_ONNOGOTO "You failed again: \nON without a GOTO or GOSUB." | |||
#define ERR_VALOORANGE "Go home, beginner. \nThe value here is way out of range." | |||
#define ERR_SYNTAX "Sure sign of a fourth-rate programmer: \nThis makes no sense at all." | |||
#define ERR_DEVNUM "Way to go, space cadet. \nThe device (or file) number here is totally in orbit." | |||
#define ERR_DEV "HO! The file or device \n you requested says: DROP DEAD." | |||
#define ERR_OPSYS "You obviously don't know \nwhat this computer can or can't do." | |||
#define ERR_ARGSTR "Do you have big ears? \n(Like Dumbo?) You obviously need a string argument at this point." | |||
#define ERR_DEFCHAR "Amazing. Surely children \nknow how to form a corrent argument here." | |||
#define ERR_MISMATCH "No way, turkey. \nThe statement here is TOTALLY mismatched." | |||
#define ERR_DIMNOTARRAY "Incredible. Why don't you \nsuppy an ARRAY NAME where the prograqm calls for an ARRAY NAME? (Or just go home.)" | |||
#define ERR_OD "Have you ever studied BASIC before? \nYou've run out of data." | |||
#define ERR_OVERFLOW "Congratulations on writing a program \nthat totally exceeds all limits." | |||
#define ERR_NF "Go back to kindergarten: \nYou have a NEXT statement FOR." | |||
#define ERR_UF "Trash. Total trash. \nDefine your stupid functions before calling them." | |||
#define ERR_DBZ "Obviously, you'll never be a programmer. \nYou've tried division by zero here." | |||
#define ERR_REDIM "You just don't understand: \nyou cannot redimension this variable." | |||
#define ERR_OBDIM "Dork. You called OPTION BASE after DIM. \nLeave me alone." | |||
#define ERR_UC "What do you think this is? \nTry entering a BASIC command here." | |||
#define ERR_NOPROGFILE "Idiot. No way this will run without a program file." | |||
#endif | |||
#if STD_RUSSIAN | |||
#define MES_SIGNON "iNTERPRETATOR Bywater BASIC, WERSIQ" | |||
#define MES_COPYRIGHT "Copyright (c) 1993, Ted A. Campbell" | |||
#define MES_LANGUAGE "" | |||
#define PROMPT "gOTOWO" | |||
#define ERROR_HEADER "o{ibka W STROKE" | |||
#define MATHERR_HEADER "o{ibka" | |||
#define MES_BREAK "pROGRAMMA PRERWANA W STROKE" | |||
#define ERR_OPENFILE "nE MOGU OTKRYTX FAJL %s" | |||
#define ERR_GETMEM "mALO PAMQTI" | |||
#define ERR_LINENO "nEWERNYJ NOMER STROKI" | |||
#define ERR_LNNOTFOUND "sTROKA %d NE NAJDENA" | |||
#define ERR_LOADNOFN "LOAD: NE ZADANO IMQ FAJLA" | |||
#define ERR_NOLN "oTSUTSTWUET NOMER STROKI" | |||
#define ERR_NOFN "oTSUTSTWUET IMQ FAJLA" | |||
#define ERR_RETNOGOSUB "RETURN BEZ GOSUB" | |||
#define ERR_INCOMPLETE "nEWER[ENNYJ OPERATOR" | |||
#define ERR_ONNOGOTO "ON BEZ GOTO ILI GOSUB" | |||
#define ERR_VALOORANGE "zNA^ENIE WNE DIAPAZONA" | |||
#define ERR_SYNTAX "sINTAKSI^ESKAQ O[IBKA" | |||
#define ERR_DEVNUM "nEWERNYJ NOMER USTROJSTWA" | |||
#define ERR_DEV "o[IBKA USTROJSTWA" | |||
#define ERR_OPSYS "o[IBKA W KOMANDE OPERACIONNOJ SISTEMY" | |||
#define ERR_ARGSTR "aRGUMENT DOLVEN BYTX STROKOJ" | |||
#define ERR_DEFCHAR "nEWERNYJ ARGUMENT W OPREDELENII PEREMENNOJ" | |||
#define ERR_MISMATCH "nESOOTWETSTWIE TIPOW" | |||
#define ERR_DIMNOTARRAY "aRGUMENT NE IMQ MASSIWA" | |||
#define ERR_OD "nET DANNYH" | |||
#define ERR_OVERFLOW "pEREPOLNENIE" | |||
#define ERR_NF "NEXT BEZ FOR" | |||
#define ERR_UF "nEOPREDELENNAQ FUNKCIQ" | |||
#define ERR_DBZ "dELENIE NA NOLX" | |||
#define ERR_REDIM "nELXZQ MENQTX RAZMERNOSTX PEREMENNOJ" | |||
#define ERR_OBDIM "OPTION BASE DOLVNA BYTX WYZWANA DO DIM" | |||
#define ERR_UC "nEWERNAQ KOMANDA" | |||
#define ERR_NOPROGFILE "Program file not specified" | |||
#endif | |||
/* STD_GERMAN */ | |||
#if STD_GERMAN | |||
#define MES_SIGNON "Bywater BASIC Interpreter/Shell, version" | |||
#define MES_COPYRIGHT "Copyright (c) 1993, Ted A. Campbell" | |||
#define MES_LANGUAGE "Ausgegeben auf Deutsch von Joerg Rieger" | |||
#define PROMPT "bwBASIC: " | |||
#define ERROR_HEADER "Irrtum in Zeile" | |||
#define ERRD_HEADER "IRRTUM" | |||
#define MATHERR_HEADER "IRRTUM" | |||
#define MES_BREAK "Programm unterbrochen in Zeile" | |||
#define ERR_OPENFILE "Datei %s kann nict geoeffnet werden" | |||
#define ERR_GETMEM "Speicher kann nicht gefunden werden" | |||
#define ERR_LINENO "Zeilennummer kann nicht verbunden werden" | |||
#define ERR_LNNOTFOUND "Zeilennummer %d nicht gefunden" | |||
#define ERR_LOADNOFN "LOAD: Keine Dateiname angegeben" | |||
#define ERR_NOLN "Keine Zeilennummer" | |||
#define ERR_NOFN "Keine Dateiname" | |||
#define ERR_RETNOGOSUB "RETURN ohne GOSUB" | |||
#define ERR_INCOMPLETE "Angabe nicht vollstaendig" | |||
#define ERR_ONNOGOTO "ON ohne GOTO oder GOSUB" | |||
#define ERR_VALOORANGE "Wert is ausserhalb des Grenzbereits" | |||
#define ERR_SYNTAX "Syntax-fehler" | |||
#define ERR_DEVNUM "Ungueltige Geraetnummer" | |||
#define ERR_DEV "Geraet irrtum" | |||
#define ERR_OPSYS "Irrtum in Anwenden des System-Befehls" | |||
#define ERR_ARGSTR "Das Argument muss geradlinig sein" | |||
#define ERR_DEFCHAR "Falsches Argument fuer eine Variable Definition" | |||
#define ERR_MISMATCH "Type verwechselt" | |||
#define ERR_DIMNOTARRAY "Das Argument ist kein Feldname" | |||
#define ERR_OD "Keine Daten mehr vorhanden" | |||
#define ERR_OVERFLOW "Ueberflutung" | |||
#define ERR_NF "NEXT ohne FOR" | |||
#define ERR_UF "Funktion nicht definiert" | |||
#define ERR_DBZ "Teile durch Null" | |||
#define ERR_REDIM "Die Variable kann nicht neu dimensioniert werdern" | |||
#define ERR_OBDIM "OPTION BASE muss vor DIM aufgerufen werden" | |||
#define ERR_UC "Befehl unbekannt" | |||
#define ERR_NOPROGFILE "Programm Datei nicht angegeben" | |||
#endif | |||
/* ESPERANTO */ | |||
#if ESPERANTO | |||
#define MES_SIGNON "Bywater BASIC Tradukilo/SXelo, vario" | |||
#define MES_COPYRIGHT "Kopirajtita (c) 1993, Ted A. Campbell" | |||
#define MES_LANGUAGE "Esperanta traduko farigxi per Ricxjo Muelisto." | |||
#define PROMPT "bwBASIC: " | |||
#define ERROR_HEADER "ERARO en vico" | |||
#define ERRD_HEADER "ERARO" | |||
#define MATHERR_HEADER "ERARO" | |||
#define MES_BREAK "Programo interrompita cxe vico" | |||
#define ERR_OPENFILE "Malsukcesis malfermi dosieron %s" | |||
#define ERR_GETMEM "Malsukcesis trovi memorajxo" | |||
#define ERR_LINENO "Malsukcesis ligi vicnumero" | |||
#define ERR_LNNOTFOUND "Vicnumero %d ne trovita" | |||
#define ERR_LOADNOFN "LOAD: dosiernomo ne specifita" | |||
#define ERR_NOLN "Ne estas vicnumero" | |||
#define ERR_NOFN "Ne estas dosiernomo" | |||
#define ERR_RETNOGOSUB "RETURN sen GOSUB" | |||
#define ERR_INCOMPLETE "Necompleta deklaro" | |||
#define ERR_ONNOGOTO "ON sen GOTO aux GOSUB" | |||
#define ERR_VALOORANGE "Valorajxo estas eksteretenda" | |||
#define ERR_SYNTAX "Sintakseraro" | |||
#define ERR_DEVNUM "Nevalida aparatnumero" | |||
#define ERR_DEV "Aparateraro" | |||
#define ERR_OPSYS "Eraro en funkcisistema ordono" | |||
#define ERR_ARGSTR "Argumento devas esti serio" | |||
#define ERR_DEFCHAR "Erara argumento por varianto difinajxo" | |||
#define ERR_MISMATCH "Tipa misparo" | |||
#define ERR_DIMNOTARRAY "Argumento ne estas kolektonomo" | |||
#define ERR_OD "Ne havas pli da informoj" | |||
#define ERR_OVERFLOW "Ektroajxo" | |||
#define ERR_NF "NEXT sen FOR" | |||
#define ERR_UF "Nedifininta funkcio" | |||
#define ERR_DBZ "Dividu per nulo" | |||
#define ERR_REDIM "Varianto ne eble esti redimensigxinta" | |||
#define ERR_OBDIM "OPTION BASE devas uzigxi antaux ol DIM" | |||
#define ERR_UC "Nekonata ordono" | |||
#define ERR_NOPROGFILE "Programa dosiero ne specifita" | |||
#endif | |||
/* Standard English is taken as a default: if MES_SIGNON is not defined by | |||
this time (i.e., by some other language definition), then | |||
the following standard English definitions are utilized. */ | |||
#ifndef MES_SIGNON | |||
#define MES_SIGNON "Bywater BASIC Interpreter/Shell, version" | |||
#define MES_COPYRIGHT "Copyright (c) 1993, Ted A. Campbell" | |||
#define MES_LANGUAGE " " | |||
#define PROMPT "bwBASIC: " | |||
#define ERROR_HEADER "ERROR in line" | |||
#define ERRD_HEADER "ERROR" | |||
#define MATHERR_HEADER "ERROR" | |||
#define MES_BREAK "Program interrupted at line" | |||
#define ERR_OPENFILE "Failed to open file %s" | |||
#define ERR_GETMEM "Failed to find memory" | |||
#define ERR_LINENO "Failed to link line number" | |||
#define ERR_LNNOTFOUND "Line number %d not found" | |||
#define ERR_LOADNOFN "LOAD: no filename specified" | |||
#define ERR_NOLN "No line number" | |||
#define ERR_NOFN "No file name" | |||
#define ERR_RETNOGOSUB "RETURN without GOSUB" | |||
#define ERR_INCOMPLETE "Incomplete statement" | |||
#define ERR_ONNOGOTO "ON without GOTO or GOSUB" | |||
#define ERR_VALOORANGE "Value is out of range" | |||
#define ERR_SYNTAX "Syntax error" | |||
#define ERR_DEVNUM "Invalid device number" | |||
#define ERR_DEV "Device error" | |||
#define ERR_OPSYS "Error in operating system command" | |||
#define ERR_ARGSTR "Argument must be a string" | |||
#define ERR_DEFCHAR "Incorrect argument for variable definition" | |||
#define ERR_MISMATCH "Type mismatch" | |||
#define ERR_DIMNOTARRAY "Argument is not an array name" | |||
#define ERR_OD "Out of data" | |||
#define ERR_OVERFLOW "Overflow" | |||
#define ERR_NF "NEXT without FOR" | |||
#define ERR_UF "Undefined function" | |||
#define ERR_DBZ "Divide by zero" | |||
#define ERR_REDIM "Variable cannot be redimensioned" | |||
#define ERR_OBDIM "OPTION BASE must be called prior to DIM" | |||
#define ERR_UC "Unknown command" | |||
#define ERR_NOPROGFILE "Program file not specified" | |||
#endif | |||
/**************************************************************** | |||
BASIC Command Name Definitions | |||
The following definitions of command names are given in | |||
order to allow users to redefine BASIC command names. | |||
No alternatives are supplied. | |||
****************************************************************/ | |||
#ifndef CMD_SYSTEM | |||
#define CMD_SYSTEM "SYSTEM" | |||
#define CMD_QUIT "QUIT" | |||
#define CMD_REM "REM" | |||
#define CMD_LET "LET" | |||
#define CMD_PRINT "PRINT" | |||
#define CMD_INPUT "INPUT" | |||
#define CMD_GO "GO" | |||
#define CMD_GOTO "GOTO" | |||
#define CMD_GOSUB "GOSUB" | |||
#define CMD_RETURN "RETURN" | |||
#define CMD_ON "ON" | |||
#define CMD_IF "IF" | |||
#define CMD_WHILE "WHILE" | |||
#define CMD_WEND "WEND" | |||
#define CMD_WRITE "WRITE" | |||
#define CMD_END "END" | |||
#define CMD_FOR "FOR" | |||
#define CMD_NEXT "NEXT" | |||
#define CMD_STOP "STOP" | |||
#define CMD_DATA "DATA" | |||
#define CMD_READ "READ" | |||
#define CMD_RESTORE "RESTORE" | |||
#define CMD_DIM "DIM" | |||
#define CMD_OPTION "OPTION" | |||
#define CMD_OPEN "OPEN" | |||
#define CMD_CLOSE "CLOSE" | |||
#define CMD_GET "GET" | |||
#define CMD_PUT "PUT" | |||
#define CMD_LSET "LSET" | |||
#define CMD_RSET "RSET" | |||
#define CMD_FIELD "FIELD" | |||
#define CMD_LINE "LINE" | |||
#define CMD_DEF "DEF" | |||
#define CMD_VARS "VARS" | |||
#define CMD_CMDS "CMDS" | |||
#define CMD_FNCS "FNCS" | |||
#define CMD_CHDIR "CHDIR" | |||
#define CMD_MKDIR "MKDIR" | |||
#define CMD_RMDIR "RMDIR" | |||
#define CMD_KILL "KILL" | |||
#define CMD_ENVIRON "ENVIRON" | |||
#define CMD_LIST "LIST" | |||
#define CMD_LOAD "LOAD" | |||
#define CMD_RUN "RUN" | |||
#define CMD_SAVE "SAVE" | |||
#define CMD_DELETE "DELETE" | |||
#define CMD_NEW "NEW" | |||
#define CMD_DEFDBL "DEFDBL" | |||
#define CMD_DEFINT "DEFINT" | |||
#define CMD_DEFSNG "DEFSNG" | |||
#define CMD_DEFSTR "DEFSTR" | |||
#define CMD_CALL "CALL" | |||
#define CMD_SUB "SUB" | |||
#define CMD_FUNCTION "FUNCTION" | |||
#define CMD_LABEL "lAbEl" /* not really used: set to an unlikely combination */ | |||
#define CMD_ELSE "ELSE" | |||
#define CMD_ELSEIF "ELSEIF" | |||
#define CMD_SELECT "SELECT" | |||
#define CMD_CASE "CASE" | |||
#define CMD_MERGE "MERGE" | |||
#define CMD_CHAIN "CHAIN" | |||
#define CMD_COMMON "COMMON" | |||
#define CMD_ERROR "ERROR" | |||
#define CMD_WIDTH "WIDTH" | |||
#define CMD_TRON "TRON" | |||
#define CMD_TROFF "TROFF" | |||
#define CMD_RANDOMIZE "RANDOMIZE" | |||
#define CMD_FILES "FILES" | |||
#define CMD_EDIT "EDIT" | |||
#define CMD_ERASE "ERASE" | |||
#define CMD_SWAP "SWAP" | |||
#define CMD_NAME "NAME" | |||
#define CMD_CLEAR "CLEAR" | |||
#define CMD_THEN "THEN" | |||
#define CMD_TO "TO" | |||
#define CMD_STEP "STEP" | |||
#define CMD_DO "DO" | |||
#define CMD_LOCATE "LOCATE" | |||
#define CMD_CLS "CLS" | |||
#define CMD_COLOR "COLOR" | |||
#define CMD_LOOP "LOOP" | |||
#define CMD_EXIT "EXIT" | |||
#define CMD_XUSING "USING" | |||
#define CMD_XFOR "FOR" | |||
#define CMD_XDO "DO" | |||
#define CMD_XUNTIL "UNTIL" | |||
#define CMD_XNUM "NUM" | |||
#define CMD_XUNNUM "UNNUM" | |||
#define CMD_XSUB "SUB" | |||
#define CMD_XTO "TO" | |||
#define CMD_XERROR "ERROR" | |||
#define CMD_XSUB "SUB" | |||
#define CMD_XFUNCTION "FUNCTION" | |||
#define CMD_XIF "IF" | |||
#define CMD_XSELECT "SELECT" | |||
#endif | |||
/**************************************************************** | |||
External Definitions for Error Messages | |||
****************************************************************/ | |||
extern char err_openfile[]; | |||
extern char err_getmem[]; | |||
extern char err_noln[]; | |||
extern char err_nofn[]; | |||
extern char err_lnnotfound[]; | |||
extern char err_incomplete[]; | |||
extern char err_valoorange[]; | |||
extern char err_syntax[]; | |||
extern char err_devnum[]; | |||
extern char err_dev[]; | |||
extern char err_opsys[]; | |||
extern char err_argstr[]; | |||
extern char err_defchar[]; | |||
extern char err_mismatch[]; | |||
extern char err_dimnotarray[]; | |||
extern char err_retnogosub[]; | |||
extern char err_od[]; | |||
extern char err_overflow[]; | |||
extern char err_nf[]; | |||
extern char err_uf[]; | |||
extern char err_dbz[]; | |||
extern char err_redim[]; | |||
extern char err_obdim[]; | |||
extern char err_uc[]; | |||
extern char err_noprogfile[]; | |||
@@ -0,0 +1,110 @@ | |||
/*************************************************************** | |||
bwb_par.c Parallel Action (Multitasking) Routines | |||
for Bywater BASIC Interpreter | |||
Currently UNDER CONSTRUCTION | |||
Copyright (c) 1993, Ted A. Campbell | |||
Bywater Software | |||
email: tcamp@delphi.com | |||
Copyright and Permissions Information: | |||
All U.S. and international rights are claimed by the author, | |||
Ted A. Campbell. | |||
This software is released under the terms of the GNU General | |||
Public License (GPL), which is distributed with this software | |||
in the file "COPYING". The GPL specifies the terms under | |||
which users may copy and use the software in this distribution. | |||
A separate license is available for commercial distribution, | |||
for information on which you should contact the author. | |||
***************************************************************/ | |||
#include <stdio.h> | |||
#include "bwbasic.h" | |||
#include "bwb_mes.h" | |||
#if PARACT /* this whole file ignored if FALSE */ | |||
/*************************************************************** | |||
FUNCTION: bwb_newtask() | |||
DESCRIPTION: This C function allocates and initializes | |||
memory for a new task. | |||
***************************************************************/ | |||
#if ANSI_C | |||
int | |||
bwb_newtask( int task_requested ) | |||
#else | |||
int | |||
bwb_newtask( task_requested ) | |||
int task_requested; | |||
#endif | |||
{ | |||
static char start_buf[] = "\0"; | |||
static char end_buf[] = "\0"; | |||
register int c; | |||
/* find if requested task slot is available */ | |||
if ( bwb_tasks[ task_requested ] != NULL ) | |||
{ | |||
#if PROG_ERRORS | |||
sprintf( bwb_ebuf, "in bwb_newtask(): Slot requested is already in use" ); | |||
bwb_error( bwb_ebuf ); | |||
#else | |||
bwb_error( err_overflow ); | |||
return -1; | |||
#endif | |||
} | |||
/* get memory for task structure */ | |||
if ( ( bwb_tasks[ task_requested ] = calloc( 1, sizeof( struct bwb_task ) ) ) | |||
== NULL ) | |||
{ | |||
#if PROG_ERRORS | |||
bwb_error( "in bwb_newtask(): failed to find memory for task structure" ); | |||
#else | |||
bwb_error( err_getmem ); | |||
#endif | |||
} | |||
/* set some initial variables */ | |||
bwb_tasks[ task_requested ]->bwb_start.number = 0; | |||
bwb_tasks[ task_requested ]->bwb_start.next = &bwb_tasks[ task_requested ]->bwb_end; | |||
bwb_tasks[ task_requested ]->bwb_end.number = MAXLINENO + 1; | |||
bwb_tasks[ task_requested ]->bwb_end.next = &bwb_tasks[ task_requested ]->bwb_end; | |||
bwb_tasks[ task_requested ]->bwb_start.buffer = start_buf; | |||
bwb_tasks[ task_requested ]->bwb_end.buffer = end_buf; | |||
bwb_tasks[ task_requested ]->data_line = &bwb_tasks[ task_requested ]->bwb_start; | |||
bwb_tasks[ task_requested ]->data_pos = 0; | |||
bwb_tasks[ task_requested ]->rescan = TRUE; | |||
bwb_tasks[ task_requested ]->exsc = -1; | |||
bwb_tasks[ task_requested ]->expsc = 0; | |||
bwb_tasks[ task_requested ]->xtxtsc = 0; | |||
/* Variable and function table initializations */ | |||
var_init( task_requested ); /* initialize variable chain */ | |||
fnc_init( task_requested ); /* initialize function chain */ | |||
fslt_init( task_requested ); /* initialize funtion-sub chain */ | |||
return task_requested; | |||
} | |||
#endif | |||
@@ -0,0 +1,355 @@ | |||
/*************************************************************** | |||
bwb_str.c String-Management Routines | |||
for Bywater BASIC Interpreter | |||
Copyright (c) 1993, Ted A. Campbell | |||
Bywater Software | |||
email: tcamp@delphi.com | |||
Copyright and Permissions Information: | |||
All U.S. and international rights are claimed by the author, | |||
Ted A. Campbell. | |||
This software is released under the terms of the GNU General | |||
Public License (GPL), which is distributed with this software | |||
in the file "COPYING". The GPL specifies the terms under | |||
which users may copy and use the software in this distribution. | |||
A separate license is available for commercial distribution, | |||
for information on which you should contact the author. | |||
***************************************************************/ | |||
#include <stdio.h> | |||
#include "bwbasic.h" | |||
#include "bwb_mes.h" | |||
#if INTENSIVE_DEBUG || TEST_BSTRING | |||
static char tbuf[ MAXSTRINGSIZE + 1 ]; | |||
#endif | |||
/*************************************************************** | |||
FUNCTION: str_btob() | |||
DESCRIPTION: This C function assigns a bwBASIC string | |||
structure to another bwBASIC string | |||
structure. | |||
***************************************************************/ | |||
#if ANSI_C | |||
int | |||
str_btob( bstring *d, bstring *s ) | |||
#else | |||
int | |||
str_btob( d, s ) | |||
bstring *d; | |||
bstring *s; | |||
#endif | |||
{ | |||
char *t; | |||
register int i; | |||
#if TEST_BSTRING | |||
sprintf( tbuf, "in str_btob(): entry, source b string name is <%s>", s->name ); | |||
bwb_debug( tbuf ); | |||
sprintf( tbuf, "in str_btob(): entry, destination b string name is <%s>", d->name ); | |||
bwb_debug( tbuf ); | |||
#endif | |||
/* get memory for new buffer */ | |||
if ( ( t = (char *) calloc( s->length + 1, 1 )) == NULL ) | |||
{ | |||
#if PROG_ERRORS | |||
bwb_error( "in str_btob(): failed to get memory for new buffer" ); | |||
#else | |||
bwb_error( err_getmem ); | |||
#endif | |||
return FALSE; | |||
} | |||
/* write the c string to the b string */ | |||
t[ 0 ] = '\0'; | |||
for ( i = 0; i < (int) s->length; ++i ) | |||
{ | |||
t[ i ] = s->sbuffer[ i ]; | |||
#if INTENSIVE_DEBUG | |||
tbuf[ i ] = s->sbuffer[ i ]; | |||
tbuf[ i + 1 ] = '\0'; | |||
#endif | |||
} | |||
/* deallocate old memory */ | |||
#if INTENSIVE_DEBUG | |||
if ( d->rab == TRUE ) | |||
{ | |||
sprintf( bwb_ebuf, "in str_btob(): reallocating RAB" ); | |||
bwb_debug( bwb_ebuf ); | |||
} | |||
#endif | |||
if (( d->rab != TRUE ) && ( d->sbuffer != NULL )) | |||
{ | |||
#if INTENSIVE_DEBUG | |||
sprintf( tbuf, "in str_btob(): deallocating string memory" ); | |||
bwb_debug ( tbuf ); | |||
#endif | |||
free( d->sbuffer ); | |||
} | |||
else | |||
{ | |||
d->rab = (char) FALSE; | |||
} | |||
/* reassign buffer */ | |||
d->sbuffer = t; | |||
/* reassign length */ | |||
d->length = s->length; | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in str_btob(): exit length <%d> string <%s>", | |||
d->length, tbuf ); | |||
bwb_debug( bwb_ebuf ); | |||
#endif | |||
/* return */ | |||
return TRUE; | |||
} | |||
/*************************************************************** | |||
FUNCTION: str_ctob() | |||
DESCRIPTION: This C function assigns a null-terminated | |||
C string to a bwBASIC string structure. | |||
***************************************************************/ | |||
#if ANSI_C | |||
int | |||
str_ctob( bstring *s, char *buffer ) | |||
#else | |||
int | |||
str_ctob( s, buffer ) | |||
bstring *s; | |||
char *buffer; | |||
#endif | |||
{ | |||
char *t; | |||
register int i; | |||
#if INTENSIVE_DEBUG | |||
sprintf( tbuf, "in str_ctob(): entry, c string is <%s>", buffer ); | |||
bwb_debug( tbuf ); | |||
#endif | |||
#if TEST_BSTRING | |||
sprintf( tbuf, "in str_ctob(): entry, b string name is <%s>", s->name ); | |||
bwb_debug( tbuf ); | |||
#endif | |||
/* get memory for new buffer */ | |||
if ( ( t = (char *) calloc( strlen( buffer ) + 1, 1 )) == NULL ) | |||
{ | |||
#if PROG_ERRORS | |||
bwb_error( "in str_ctob(): failed to get memory for new buffer" ); | |||
#else | |||
bwb_error( err_getmem ); | |||
#endif | |||
return FALSE; | |||
} | |||
/* write the c string to the b string */ | |||
t[ 0 ] = '\0'; | |||
for ( i = 0; i < (int) strlen( buffer ); ++i ) | |||
{ | |||
t[ i ] = buffer[ i ]; | |||
#if INTENSIVE_DEBUG | |||
tbuf[ i ] = buffer[ i ]; | |||
tbuf[ i + 1 ] = '\0'; | |||
#endif | |||
} | |||
/* deallocate old memory */ | |||
#if INTENSIVE_DEBUG | |||
if ( s->rab == TRUE ) | |||
{ | |||
sprintf( bwb_ebuf, "in str_ctob(): reallocating RAB" ); | |||
bwb_debug( bwb_ebuf ); | |||
} | |||
#endif | |||
if (( s->rab != TRUE ) && ( s->sbuffer != NULL )) | |||
{ | |||
free( s->sbuffer ); | |||
} | |||
else | |||
{ | |||
s->rab = (char) FALSE; | |||
} | |||
/* reassign buffer */ | |||
s->sbuffer = t; | |||
/* reassign length */ | |||
s->length = (unsigned char) strlen( buffer ); | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in str_ctob(): exit length <%d> string <%s>", | |||
s->length, tbuf ); | |||
bwb_debug( bwb_ebuf ); | |||
#endif | |||
/* return */ | |||
return TRUE; | |||
} | |||
/*************************************************************** | |||
FUNCTION: str_btoc() | |||
DESCRIPTION: This C function assigns a null-terminated | |||
C string to a bwBASIC string structure. | |||
***************************************************************/ | |||
#if ANSI_C | |||
int | |||
str_btoc( char *buffer, bstring *s ) | |||
#else | |||
int | |||
str_btoc( buffer, s ) | |||
char *buffer; | |||
bstring *s; | |||
#endif | |||
{ | |||
register int i; | |||
#if INTENSIVE_DEBUG | |||
sprintf( tbuf, "in str_btoc(): entry, b string length is <%d>", | |||
s->length ); | |||
bwb_debug( tbuf ); | |||
#endif | |||
#if TEST_BSTRING | |||
sprintf( tbuf, "in str_btoc(): entry, b string name is <%s>", s->name ); | |||
bwb_debug( tbuf ); | |||
#endif | |||
/* write the b string to the c string */ | |||
buffer[ 0 ] = '\0'; | |||
for ( i = 0; i < (int) s->length; ++i ) | |||
{ | |||
buffer[ i ] = s->sbuffer[ i ]; | |||
buffer[ i + 1 ] = '\0'; | |||
if ( i >= MAXSTRINGSIZE ) | |||
{ | |||
i = s->length + 1; | |||
} | |||
} | |||
#if INTENSIVE_DEBUG | |||
sprintf( tbuf, "in str_btoc(): exit, c string is <%s>", buffer ); | |||
bwb_debug( tbuf ); | |||
#endif | |||
/* return */ | |||
return TRUE; | |||
} | |||
/*************************************************************** | |||
FUNCTION: str_cat() | |||
DESCRIPTION: This C function performs the equivalent | |||
of the C strcat() function, using BASIC | |||
strings. | |||
***************************************************************/ | |||
#if ANSI_C | |||
char * | |||
str_cat( bstring *a, bstring *b ) | |||
#else | |||
char * | |||
str_cat( a, b ) | |||
bstring *a; | |||
bstring *b; | |||
#endif | |||
{ | |||
char abuf[ MAXSTRINGSIZE + 1 ]; | |||
char bbuf[ MAXSTRINGSIZE + 1 ]; | |||
char *r; | |||
str_btoc( abuf, a ); | |||
str_btoc( bbuf, b ); | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in str_cat(): a <%s> b <%s>", abuf, bbuf ); | |||
bwb_debug( bwb_ebuf ); | |||
#endif | |||
strcat( abuf, bbuf ); | |||
str_ctob( a, abuf ); | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in str_cat(): returns <%s>", abuf ); | |||
bwb_debug( bwb_ebuf ); | |||
#endif | |||
return r; | |||
} | |||
/*************************************************************** | |||
FUNCTION: str_cmp() | |||
DESCRIPTION: This C function performs the equivalent | |||
of the C strcmp() function, using BASIC | |||
strings. | |||
***************************************************************/ | |||
#if ANSI_C | |||
int | |||
str_cmp( bstring *a, bstring *b ) | |||
#else | |||
int | |||
str_cmp( a, b ) | |||
bstring *a; | |||
bstring *b; | |||
#endif | |||
{ | |||
char abuf[ MAXSTRINGSIZE + 1 ]; | |||
char bbuf[ MAXSTRINGSIZE + 1 ]; | |||
str_btoc( abuf, a ); | |||
str_btoc( bbuf, b ); | |||
return strcmp( abuf, bbuf ); | |||
} | |||
@@ -0,0 +1,335 @@ | |||
/*************************************************************** | |||
bwb_tbl.c Command, Function, Operator, | |||
and Error-Message Tables | |||
for Bywater BASIC Interpreter | |||
Copyright (c) 1993, Ted A. Campbell | |||
Bywater Software | |||
email: tcamp@delphi.com | |||
Copyright and Permissions Information: | |||
All U.S. and international rights are claimed by the author, | |||
Ted A. Campbell. | |||
This software is released under the terms of the GNU General | |||
Public License (GPL), which is distributed with this software | |||
in the file "COPYING". The GPL specifies the terms under | |||
which users may copy and use the software in this distribution. | |||
A separate license is available for commercial distribution, | |||
for information on which you should contact the author. | |||
***************************************************************/ | |||
#include <stdio.h> | |||
#include "bwbasic.h" | |||
#include "bwb_mes.h" | |||
int err_line = 0; /* line in which error occurred */ | |||
int err_number = 0; /* number of last error */ | |||
/*************************************************************** | |||
Command Table for Bywater BASIC | |||
***************************************************************/ | |||
struct bwb_command bwb_cmdtable[ COMMANDS ] = | |||
{ | |||
#if PERMANENT_DEBUG | |||
{ CMD_VARS, bwb_vars }, | |||
{ CMD_CMDS, bwb_cmds }, | |||
{ CMD_FNCS, bwb_fncs }, | |||
#endif | |||
#if UNIX_CMDS | |||
{ CMD_CHDIR, bwb_chdir }, | |||
{ CMD_MKDIR, bwb_mkdir }, | |||
{ CMD_RMDIR, bwb_rmdir }, | |||
{ CMD_KILL, bwb_kill }, | |||
{ CMD_ENVIRON, bwb_environ }, | |||
#endif | |||
#if INTERACTIVE | |||
{ CMD_LIST, bwb_list }, | |||
{ CMD_LOAD, bwb_load }, | |||
{ CMD_RUN, bwb_run }, | |||
{ CMD_SAVE, bwb_save }, | |||
{ CMD_DELETE, bwb_delete }, | |||
{ CMD_NEW, bwb_new }, | |||
{ CMD_QUIT, bwb_system }, | |||
{ CMD_SYSTEM, bwb_system }, | |||
#endif | |||
#if MS_CMDS | |||
{ CMD_DEFDBL, bwb_ddbl }, | |||
{ CMD_DEFINT, bwb_dint }, | |||
{ CMD_DEFSNG, bwb_dsng }, | |||
{ CMD_DEFSTR, bwb_dstr }, | |||
#if IMP_CMDCLS | |||
{ CMD_CLS, bwb_cls }, | |||
#endif | |||
#if IMP_CMDCOLOR | |||
{ CMD_COLOR, bwb_color }, | |||
#endif | |||
#if IMP_CMDLOC | |||
{ CMD_LOCATE, bwb_locate }, | |||
#endif | |||
#endif | |||
#if STRUCT_CMDS | |||
{ CMD_CALL, bwb_call }, | |||
{ CMD_SUB, bwb_sub }, | |||
{ CMD_FUNCTION, bwb_function }, | |||
{ CMD_LABEL, bwb_null }, | |||
{ CMD_ELSE, bwb_else }, | |||
{ CMD_ELSEIF, bwb_elseif }, | |||
{ CMD_SELECT, bwb_select }, | |||
{ CMD_CASE, bwb_case }, | |||
{ CMD_LOOP, bwb_loop }, | |||
{ CMD_EXIT, bwb_exit }, | |||
#endif | |||
#if COMMON_CMDS | |||
{ CMD_MERGE, bwb_merge }, | |||
{ CMD_CHAIN, bwb_chain }, | |||
{ CMD_COMMON, bwb_common }, | |||
{ CMD_ERROR, bwb_lerror }, | |||
{ CMD_WIDTH, bwb_width }, | |||
{ CMD_TRON, bwb_tron }, | |||
{ CMD_TROFF, bwb_troff }, | |||
{ CMD_FILES, bwb_files }, | |||
{ CMD_EDIT, bwb_edit }, | |||
{ CMD_ERASE, bwb_erase }, | |||
{ CMD_SWAP, bwb_swap }, | |||
{ CMD_NAME, bwb_name }, | |||
{ CMD_CLEAR, bwb_clear }, | |||
{ CMD_WHILE, bwb_while }, | |||
{ CMD_WEND, bwb_wend }, | |||
{ CMD_WRITE, bwb_write }, | |||
{ CMD_OPEN, bwb_open }, | |||
{ CMD_CLOSE, bwb_close }, | |||
{ CMD_GET, bwb_get }, | |||
{ CMD_PUT, bwb_put }, | |||
{ CMD_LSET, bwb_lset }, | |||
{ CMD_RSET, bwb_rset }, | |||
{ CMD_FIELD, bwb_field }, | |||
{ CMD_LINE, bwb_line }, | |||
#endif | |||
/* The remainder are the core functions defined for ANSI Minimal BASIC */ | |||
{ CMD_DATA, bwb_data }, | |||
{ CMD_DEF, bwb_def }, | |||
{ CMD_DIM, bwb_dim }, | |||
{ CMD_END, bwb_xend }, | |||
{ CMD_FOR, bwb_for }, | |||
{ CMD_DO, bwb_do }, /* not really core but needed in two different places */ | |||
{ CMD_GO, bwb_go }, | |||
{ CMD_GOSUB, bwb_gosub }, | |||
{ CMD_GOTO, bwb_goto }, | |||
{ CMD_IF, bwb_if }, | |||
{ CMD_INPUT, bwb_input }, | |||
{ CMD_LET, bwb_let }, | |||
{ CMD_NEXT, bwb_next }, | |||
{ CMD_ON, bwb_on }, | |||
{ CMD_OPTION, bwb_option }, | |||
{ CMD_PRINT, bwb_print }, | |||
{ CMD_RANDOMIZE, bwb_randomize }, | |||
{ CMD_READ, bwb_read }, | |||
{ CMD_REM, bwb_rem }, | |||
{ CMD_RESTORE, bwb_restore }, | |||
{ CMD_RETURN, bwb_return }, | |||
{ CMD_STOP, bwb_stop } | |||
}; | |||
/*************************************************************** | |||
Predefined Function Table for Bywater BASIC | |||
***************************************************************/ | |||
struct bwb_function bwb_prefuncs[ FUNCTIONS ] = | |||
{ | |||
#if INTENSIVE_DEBUG | |||
{ "TEST", NUMBER, 2, fnc_test, (struct bwb_function *) NULL, 0 }, | |||
#endif | |||
#if MS_FUNCS /* Functions unique to Microsoft GWBASIC (tm) */ | |||
{ "ASC", NUMBER, 1, fnc_asc, (struct bwb_function *) NULL, 0 }, | |||
{ "MKD$", STRING, 1, fnc_mkd, (struct bwb_function *) NULL, 0 }, | |||
{ "MKI$", STRING, 1, fnc_mki, (struct bwb_function *) NULL, 0 }, | |||
{ "MKS$", STRING, 1, fnc_mks, (struct bwb_function *) NULL, 0 }, | |||
{ "CVD", NUMBER, 1, fnc_cvd, (struct bwb_function *) NULL, 0 }, | |||
{ "CVS", NUMBER, 1, fnc_cvs, (struct bwb_function *) NULL, 0 }, | |||
{ "CVI", NUMBER, 1, fnc_cvi, (struct bwb_function *) NULL, 0 }, | |||
{ "CINT", NUMBER, 1, fnc_cint, (struct bwb_function *) NULL, 0 }, | |||
{ "CSNG", NUMBER, 1, fnc_csng, (struct bwb_function *) NULL, 0 }, | |||
{ "ENVIRON$",STRING, 1, fnc_environ, (struct bwb_function *) NULL, 0 }, | |||
{ "ERR", NUMBER, 0, fnc_err, (struct bwb_function *) NULL, 0 }, | |||
{ "ERL", NUMBER, 0, fnc_erl, (struct bwb_function *) NULL, 0 }, | |||
{ "LOC", NUMBER, 1, fnc_loc, (struct bwb_function *) NULL, 0 }, | |||
{ "LOF", NUMBER, 1, fnc_lof, (struct bwb_function *) NULL, 0 }, | |||
{ "EOF", NUMBER, 1, fnc_eof, (struct bwb_function *) NULL, 0 }, | |||
{ "INSTR", NUMBER, 1, fnc_instr, (struct bwb_function *) NULL, 0 }, | |||
{ "SPC", STRING, 1, fnc_spc, (struct bwb_function *) NULL, 0 }, | |||
{ "SPACE$", STRING, 1, fnc_space, (struct bwb_function *) NULL, 0 }, | |||
{ "STRING$", STRING, 1, fnc_string, (struct bwb_function *) NULL, 0 }, | |||
{ "MID$", STRING, 3, fnc_mid, (struct bwb_function *) NULL, 0 }, | |||
{ "LEFT$", STRING, 2, fnc_left, (struct bwb_function *) NULL, 0 }, | |||
{ "RIGHT$", STRING, 2, fnc_right, (struct bwb_function *) NULL, 0 }, | |||
{ "TIMER", NUMBER, 0, fnc_timer, (struct bwb_function *) NULL, 0 }, | |||
{ "HEX$", STRING, 1, fnc_hex, (struct bwb_function *) NULL, 0 }, | |||
{ "OCT$", STRING, 1, fnc_oct, (struct bwb_function *) NULL, 0 }, | |||
#if IMP_FNCINKEY == 1 | |||
{ "INKEY$", STRING, 1, fnc_inkey, (struct bwb_function *) NULL, 0 }, | |||
#endif | |||
#endif | |||
#if COMMON_FUNCS /* Functions common to GWBASIC and ANSI Full BASIC */ | |||
{ "CHR$", NUMBER, 0, fnc_chr, (struct bwb_function *) NULL, 0 }, | |||
{ "LEN", NUMBER, 1, fnc_len, (struct bwb_function *) NULL, 0 }, | |||
{ "POS", NUMBER, 0, fnc_pos, (struct bwb_function *) NULL, 0 }, | |||
{ "VAL", NUMBER, 1, fnc_val, (struct bwb_function *) NULL, 0 }, | |||
{ "STR$", STRING, 1, fnc_str, (struct bwb_function *) NULL, 0 }, | |||
{ "DATE$", STRING, 0, fnc_date, (struct bwb_function *) NULL, 0 }, | |||
{ "TIME$", STRING, 0, fnc_time, (struct bwb_function *) NULL, 0 }, | |||
#endif | |||
#if ANSI_FUNCS /* Functions required for ANSI Full BASIC */ | |||
#endif | |||
/* The remainder are core functions defined for ANSI Minimal BASIC */ | |||
#if COMPRESS_FUNCS | |||
{ "ABS", NUMBER, 1, fnc_core, (struct bwb_function *) NULL, F_ABS }, | |||
{ "ATN", NUMBER, 1, fnc_core, (struct bwb_function *) NULL, F_ATN }, | |||
{ "COS", NUMBER, 1, fnc_core, (struct bwb_function *) NULL, F_COS }, | |||
{ "EXP", NUMBER, 1, fnc_core, (struct bwb_function *) NULL, F_EXP }, | |||
{ "INT", NUMBER, 1, fnc_core, (struct bwb_function *) NULL, F_INT }, | |||
{ "LOG", NUMBER, 1, fnc_core, (struct bwb_function *) NULL, F_LOG }, | |||
{ "RND", NUMBER, 0, fnc_core, (struct bwb_function *) NULL, F_RND }, | |||
{ "SGN", NUMBER, 1, fnc_core, (struct bwb_function *) NULL, F_SGN }, | |||
{ "SIN", NUMBER, 1, fnc_core, (struct bwb_function *) NULL, F_SIN }, | |||
{ "SQR", NUMBER, 1, fnc_core, (struct bwb_function *) NULL, F_SQR }, | |||
{ "TAN", NUMBER, 1, fnc_core, (struct bwb_function *) NULL, F_TAN }, | |||
#else | |||
{ "ABS", NUMBER, 1, fnc_abs, (struct bwb_function *) NULL, 0 }, | |||
{ "ATN", NUMBER, 1, fnc_atn, (struct bwb_function *) NULL, 0 }, | |||
{ "COS", NUMBER, 1, fnc_cos, (struct bwb_function *) NULL, 0 }, | |||
{ "EXP", NUMBER, 1, fnc_exp, (struct bwb_function *) NULL, 0 }, | |||
{ "INT", NUMBER, 1, fnc_int, (struct bwb_function *) NULL, 0 }, | |||
{ "LOG", NUMBER, 1, fnc_log, (struct bwb_function *) NULL, 0 }, | |||
{ "RND", NUMBER, 0, fnc_rnd, (struct bwb_function *) NULL, 0 }, | |||
{ "SGN", NUMBER, 1, fnc_sgn, (struct bwb_function *) NULL, 0 }, | |||
{ "SIN", NUMBER, 1, fnc_sin, (struct bwb_function *) NULL, 0 }, | |||
{ "SQR", NUMBER, 1, fnc_sqr, (struct bwb_function *) NULL, 0 }, | |||
{ "TAN", NUMBER, 1, fnc_tan, (struct bwb_function *) NULL, 0 }, | |||
#endif | |||
{ "TAB", STRING, 1, fnc_tab, (struct bwb_function *) NULL, 0 } | |||
}; | |||
/*************************************************************** | |||
Operator Table for Bywater BASIC | |||
***************************************************************/ | |||
struct bwb_op exp_ops[ N_OPERATORS ] = | |||
{ | |||
{ "NOT", OP_NOT, 12 }, /* multiple-character operators */ | |||
{ "AND", OP_AND, 13 }, /* should be tested first because */ | |||
{ "OR", OP_OR, 14 }, /* e.g. a ">=" would be matched */ | |||
{ "XOR", OP_XOR, 15 }, /* as "=" if the single-character */ | |||
{ "IMP", OP_IMPLIES, 16 }, /* operator came first */ | |||
{ "EQV", OP_EQUIV, 17 }, | |||
{ "MOD", OP_MODULUS, 4 }, | |||
{ "<>", OP_NOTEQUAL, 7 }, | |||
{ "<=", OP_LTEQ, 10 }, | |||
{ "=<", OP_LTEQ, 10 }, /* allow either form */ | |||
{ ">=", OP_GTEQ, 11 }, | |||
{ "=>", OP_GTEQ, 11 }, /* allow either form */ | |||
{ "<", OP_LESSTHAN, 8 }, | |||
{ ">", OP_GREATERTHAN, 9 }, | |||
{ "^", OP_EXPONENT, 0 }, | |||
{ "*", OP_MULTIPLY, 2 }, | |||
{ "/", OP_DIVIDE, 2 }, | |||
{ "\\", OP_INTDIVISION, 3 }, | |||
{ "+", OP_ADD, 5 }, | |||
{ "-", OP_SUBTRACT, 5 }, | |||
{ "=", OP_EQUALS, 6 }, | |||
{ "=", OP_ASSIGN, 6 }, /* don't worry: OP_EQUALS will be converted to OP_ASSIGN if necessary */ | |||
{ ";", OP_STRJOIN, 18 }, | |||
{ ",", OP_STRTAB, 19 } | |||
}; | |||
/* Error messages used more than once */ | |||
char err_openfile[] = ERR_OPENFILE; | |||
char err_getmem[] = ERR_GETMEM; | |||
char err_noln[] = ERR_NOLN; | |||
char err_nofn[] = ERR_NOFN; | |||
char err_lnnotfound[] = ERR_LNNOTFOUND; | |||
char err_incomplete[] = ERR_INCOMPLETE; | |||
char err_valoorange[] = ERR_VALOORANGE; | |||
char err_syntax[] = ERR_SYNTAX; | |||
char err_devnum[] = ERR_DEVNUM; | |||
char err_dev[] = ERR_DEV; | |||
char err_opsys[] = ERR_OPSYS; | |||
char err_argstr[] = ERR_ARGSTR; | |||
char err_defchar[] = ERR_DEFCHAR; | |||
char err_mismatch[] = ERR_MISMATCH; | |||
char err_dimnotarray[] =ERR_DIMNOTARRAY; | |||
char err_retnogosub[] = ERR_RETNOGOSUB; | |||
char err_od[] = ERR_OD; | |||
char err_overflow[] = ERR_OVERFLOW; | |||
char err_nf[] = ERR_NF; | |||
char err_uf[] = ERR_UF; | |||
char err_dbz[] = ERR_DBZ; | |||
char err_redim[] = ERR_REDIM; | |||
char err_obdim[] = ERR_OBDIM; | |||
char err_uc[] = ERR_UC; | |||
char err_noprogfile[] = ERR_NOPROGFILE; | |||
/*************************************************************** | |||
Error Message Table for Bywater BASIC | |||
***************************************************************/ | |||
char *err_table[ N_ERRORS ] = | |||
{ | |||
err_openfile, | |||
err_getmem, | |||
err_noln, | |||
err_nofn, | |||
err_lnnotfound, | |||
err_incomplete, | |||
err_valoorange, | |||
err_syntax, | |||
err_devnum, | |||
err_dev, | |||
err_opsys, | |||
err_argstr, | |||
err_defchar, | |||
err_mismatch, | |||
err_dimnotarray, | |||
err_od, | |||
err_overflow, | |||
err_nf, | |||
err_uf, | |||
err_dbz, | |||
err_redim, | |||
err_obdim, | |||
err_uc, | |||
err_noprogfile | |||
}; | |||
@@ -0,0 +1,5 @@ | |||
/* This is for Borland Turbo C++ only: it requests the linker to | |||
establish a larger-than-usual stack of 8192 bytes for bwBASIC */ | |||
extern unsigned _stklen = 8192U; | |||
@@ -0,0 +1,85 @@ | |||
PROJ =BWBASIC | |||
DEBUG =0 | |||
CC =qcl | |||
CFLAGS_G = /AL /W3 /Za /DMSDOS | |||
CFLAGS_D = /Zd /Gi$(PROJ).mdt /Od | |||
CFLAGS_R = /O /Ot /Gs /DNDEBUG | |||
CFLAGS =$(CFLAGS_G) $(CFLAGS_R) | |||
LFLAGS_G = /CP:0xffff /NOI /NOE /SE:0x80 /ST:0x1fa0 | |||
LFLAGS_D = /INCR | |||
LFLAGS_R = | |||
LFLAGS =$(LFLAGS_G) $(LFLAGS_R) | |||
RUNFLAGS = | |||
OBJS_EXT = | |||
LIBS_EXT = | |||
all: $(PROJ).exe | |||
bwbasic.obj: bwbasic.c | |||
bwb_cmd.obj: bwb_cmd.c | |||
bwb_cnd.obj: bwb_cnd.c | |||
bwb_dio.obj: bwb_dio.c | |||
bwb_elx.obj: bwb_elx.c | |||
bwb_exp.obj: bwb_exp.c | |||
bwb_fnc.obj: bwb_fnc.c | |||
bwb_inp.obj: bwb_inp.c | |||
bwb_int.obj: bwb_int.c | |||
bwb_mth.obj: bwb_mth.c | |||
bwb_ops.obj: bwb_ops.c | |||
bwb_par.obj: bwb_par.c | |||
bwb_prn.obj: bwb_prn.c | |||
bwb_stc.obj: bwb_stc.c | |||
bwb_str.obj: bwb_str.c | |||
bwb_tbl.obj: bwb_tbl.c | |||
bwb_var.obj: bwb_var.c | |||
bwx_tty.obj: bwx_tty.c | |||
$(PROJ).exe: bwbasic.obj bwb_cmd.obj bwb_cnd.obj bwb_dio.obj bwb_elx.obj bwb_exp.obj \ | |||
bwb_fnc.obj bwb_inp.obj bwb_int.obj bwb_mth.obj bwb_ops.obj bwb_par.obj bwb_prn.obj \ | |||
bwb_stc.obj bwb_str.obj bwb_tbl.obj bwb_var.obj bwx_tty.obj $(OBJS_EXT) | |||
echo >NUL @<<$(PROJ).crf | |||
bwbasic.obj + | |||
bwb_cmd.obj + | |||
bwb_cnd.obj + | |||
bwb_dio.obj + | |||
bwb_elx.obj + | |||
bwb_exp.obj + | |||
bwb_fnc.obj + | |||
bwb_inp.obj + | |||
bwb_int.obj + | |||
bwb_mth.obj + | |||
bwb_ops.obj + | |||
bwb_par.obj + | |||
bwb_prn.obj + | |||
bwb_stc.obj + | |||
bwb_str.obj + | |||
bwb_tbl.obj + | |||
bwb_var.obj + | |||
bwx_tty.obj + | |||
$(OBJS_EXT) | |||
$(PROJ).exe | |||
$(LIBS_EXT); | |||
<< | |||
link $(LFLAGS) @$(PROJ).crf | |||
run: $(PROJ).exe | |||
$(PROJ) $(RUNFLAGS) | |||
@@ -0,0 +1,5 @@ | |||
10 rem ABS.BAS -- Test ABS() function | |||
20 X = -1.23456789 | |||
30 ABSX = ABS( X ) | |||
40 print "The absolute value of "; X; " is"; ABSX | |||
50 print "Is that correct?" |
@@ -0,0 +1,3 @@ | |||
10 Print "TEST.BAS -- TEST" | |||
20 X=7 | |||
30 print "X is ";X |
@@ -0,0 +1,34 @@ | |||
rem ---------------------------------------------------- | |||
rem CallFunc.BAS | |||
rem ---------------------------------------------------- | |||
Print "CallFunc.BAS -- Test BASIC User-defined Function Statements" | |||
Print "The next printed line should be from the Function." | |||
testvar = 17 | |||
x = TestFnc( 5, "Hello", testvar ) | |||
Print "This is back at the main program. " | |||
Print "The value of variable <testvar> is now "; testvar | |||
Print "The returned value from the function is "; x | |||
Print "Did it work?" | |||
End | |||
rem ---------------------------------------------------- | |||
rem Subroutine TestFnc | |||
rem ---------------------------------------------------- | |||
Function TestFnc( xarg, yarg$, tvar ) | |||
Print "This is written from the Function." | |||
Print "The value of variable <xarg> is"; xarg | |||
Print "The value of variable <yarg$> is "; yarg$ | |||
Print "The value of variable <tvar> is "; tvar | |||
tvar = 99 | |||
Print "The value of variable <tvar> is reset to "; tvar | |||
TestFnc = xarg + tvar | |||
Print "The Function should return "; TestFnc | |||
End Function |
@@ -0,0 +1,32 @@ | |||
rem ---------------------------------------------------- | |||
rem CallSub.BAS | |||
rem ---------------------------------------------------- | |||
Print "CallSub.BAS -- Test BASIC Call and Sub Statements" | |||
Print "The next printed line should be from the Subroutine." | |||
testvar = 17 | |||
Call TestSub 5, "Hello", testvar | |||
Print "This is back at the main program. " | |||
Print "The value of variable <testvar> is now "; testvar | |||
Print "Did it work?" | |||
End | |||
rem ---------------------------------------------------- | |||
rem Subroutine TestSub | |||
rem ---------------------------------------------------- | |||
Sub TestSub( xarg, yarg$, tvar ) | |||
Print "This is written from the Subroutine." | |||
Print "The value of variable <xarg> is"; xarg | |||
Print "The value of variable <yarg$> is "; yarg$ | |||
Print "The value of variable <tvar> is "; tvar | |||
tvar = 99 | |||
Print "The value of variable <tvar> is reset to "; tvar | |||
End Sub | |||
@@ -0,0 +1,7 @@ | |||
REM CHAIN1.BAS | |||
print "This is program CHAIN1.BAS" | |||
X = 5.6789 | |||
common X | |||
print "The value of X is";X | |||
print "We shall no pass execution to program CHAIN2.BAS..." | |||
chain "chain2.bas" |
@@ -0,0 +1,4 @@ | |||
REM CHAIN2.BAS | |||
print "This is program CHAIN2.BAS" | |||
print "The value of X is now";X | |||
print "This concludes our CHAIN test." |
@@ -0,0 +1,14 @@ | |||
10 rem DATAREAD.BAS -- Test DATA, READ, and RESTORE Statements | |||
20 print "DATAREAD.BAS -- Test DATA, READ, and RESTORE Statements" | |||
30 DATA "Ted", 56.789 | |||
40 REM just to see if it advances correctly | |||
50 DATA "Dale", 45.678 | |||
60 READ N$, NUMBER, ANOTHER$ | |||
70 READ ANUMBER | |||
80 PRINT "Data read: ";N$;" ";NUMBER;" ";ANOTHER$;" ";ANUMBER | |||
90 RESTORE 30 | |||
100 READ ANOTHER$ | |||
110 READ ANUMBER, N$,NUMBER | |||
120 PRINT "After RESTORE:" | |||
130 PRINT "Data read: ";ANOTHER$;" ";ANUMBER;" ";N$;" ";NUMBER | |||
140 END |
@@ -0,0 +1,7 @@ | |||
10 REM ------------------------------------------ | |||
20 PRINT "DEFFN.BAS -- Test DEF FN Statement" | |||
30 DEF fnadd( x, y ) = x + y | |||
40 PRINT fnadd( 2, 3 ) | |||
50 DEF fnjoin$( a$, b$ ) = a$ + b$ | |||
60 PRINT fnjoin$( chr$( &h43 ), "orrect" ) | |||
70 END |
@@ -0,0 +1,6 @@ | |||
10 DIM n(5) | |||
20 FOR i = 0 to 5 | |||
30 LET n(i) = i + 2 | |||
40 PRINT "The value at position ";i;" is ";n(i) | |||
50 NEXT i | |||
60 END |
@@ -0,0 +1,7 @@ | |||
10 i = 0 | |||
20 do | |||
30 i = i + 1 | |||
40 print "i is";i | |||
50 if i > 12 then exit do | |||
60 loop | |||
70 print "End" |
@@ -0,0 +1,13 @@ | |||
10 REM DOWHILE.BAS -- Test DO WHILE-LOOP | |||
20 PRINT "START" | |||
30 LET X = 0 | |||
40 DO WHILE X < 25 | |||
50 PRINT "x is ";X | |||
60 LET X = X + 1 | |||
70 LET Y = 0 | |||
80 DO WHILE Y < 2 | |||
90 PRINT "y is "; Y | |||
100 LET Y = Y + 1 | |||
110 LOOP | |||
120 LOOP | |||
130 PRINT "END" |
@@ -0,0 +1,26 @@ | |||
rem ----------------------------------------------------- | |||
rem elseif.bas -- Test MultiLine IF-ELSEIF-THEN statement | |||
rem ----------------------------------------------------- | |||
Print "ELSEIF.BAS -- Test MultiLine IF-THEN-ELSE Constructions" | |||
Print "The program should detect if the number you enter is 4 or 5 or 6." | |||
Input "Please enter a number, 1-9"; x | |||
If x = 4 then | |||
Print "The number is 4." | |||
Elseif x = 5 then | |||
Print "The number is 5." | |||
Elseif x = 6 then | |||
Print "The number is 6." | |||
Else | |||
Print "The number is neither 4 nor 5 nor 6." | |||
End If | |||
Print "This concludes our test." |
@@ -0,0 +1,6 @@ | |||
10 REM END.BAS -- Test END Statement | |||
20 PRINT "END.BAS -- Test END Statement" | |||
30 PRINT "If the program ends after this line, END worked OK." | |||
40 END | |||
50 PRINT "But if this line printed, then it did not work." | |||
60 END |
@@ -0,0 +1,3 @@ | |||
10 dim n(5) | |||
20 print n(7) | |||
30 end |
@@ -0,0 +1,9 @@ | |||
10 rem FNCALLFN.BAS -- Test User-defined function called | |||
20 rem from user-defined function | |||
30 def fnabs(x) = abs(x) | |||
40 def fncmp(y) = 1.45678+fnabs(y) | |||
50 print "Test user-defined function calling user-defined function" | |||
60 print "The result should be: ";2.45678 | |||
70 q = -1.000 | |||
80 print "The result is: : "; fncmp( q ) | |||
90 end |
@@ -0,0 +1,13 @@ | |||
10 REM FORNEXT.BAS -- Test FOR-NEXT Statements | |||
20 REM | |||
30 PRINT "FORNEXT.BAS: Test FOR-NEXT Statements" | |||
40 PRINT "A FOR-NEXT Loop with STEP statement:" | |||
50 FOR i=1 to 30 step 2 | |||
60 PRINT "FOR: i is ";i | |||
70 NEXT i | |||
80 REM | |||
90 PRINT "A FOR-NEXT Loop without STEP statement:" | |||
100 FOR i = 2 to 7 | |||
110 PRINT "FOR: i is ";i | |||
120 NEXT i | |||
130 END |
@@ -0,0 +1,43 @@ | |||
1000 PRINT "ABS(-2.2): "; ABS(-2.2) | |||
1010 PRINT "DATE$: <"; DATE$; ">" | |||
1020 PRINT "TIME$: <"; TIME$; ">" | |||
1030 PRINT "ATN(-2.2): "; ATN(-2.2) | |||
1040 PRINT "COS(-2.2): "; COS(-2.2) | |||
1050 PRINT "LOG(2.2): "; LOG(2.2) | |||
1060 PRINT "SIN(-2.2): "; SIN(-2.2) | |||
1070 PRINT "SQR(2.2): "; SQR(2.2) | |||
1080 PRINT "TAN(-2.2): "; TAN(-2.2) | |||
1090 PRINT "SGN(-2.2): "; SGN(-2.2) | |||
1100 PRINT "INT(-2.2): "; INT(-2.2) | |||
1102 INPUT "Paused";X$ | |||
1110 PRINT "RND(-2.2): "; RND(-2.2) | |||
1120 PRINT "CHR$(&h60): "; CHR$(&H60) | |||
1130 PRINT "TAB(52): <"; TAB(52); ">" | |||
1140 PRINT "SPC(5): <"; SPC(5); ">" | |||
1150 PRINT "SPACE$(5): <"; SPACE$(5); ">" | |||
1160 PRINT "STRING$(5,X): <"; STRING$(5,"X"); ">" | |||
1170 PRINT "MID$(0123456789, 5, 4): <"; MID$("0123456789", 5, 4); ">" | |||
1180 PRINT "LEFT$(0123456789, 5): <"; LEFT$("0123456789", 5); ">" | |||
1190 PRINT "RIGHT$(0123456789, 5): <"; RIGHT$("0123456789", 5); ">" | |||
1200 PRINT "TIMER: "; TIMER | |||
1202 INPUT "Paused";X$ | |||
1210 PRINT "VAL(X): "; VAL("X") | |||
1230 PRINT "ERR: "; ERR | |||
1240 PRINT "ERL: "; ERL | |||
1250 PRINT "LEN(0123456789): "; LEN("0123456789") | |||
1260 PRINT "CSNG(-2.2): "; CSNG(-2.2) | |||
1270 PRINT "EXP(-2.2): "; EXP(-2.2) | |||
1280 PRINT "INSTR(0123456789, 234): "; INSTR("0123456789", "234") | |||
1290 PRINT "STR$(-2.2): <"; STR$(-2.2); ">" | |||
1300 PRINT "HEX$(27): <"; HEX$(27); ">" | |||
1302 INPUT "Paused";X$ | |||
1310 PRINT "OCT$(27): <"; OCT$(27); ">" | |||
1320 PRINT "CINT(-2.2): "; CINT(-2.2) | |||
1330 PRINT "ASC(0123456789): "; ASC("0123456789") | |||
1340 PRINT "ENVIRON$(PATH): <"; ENVIRON$("PATH"); ">" | |||
1350 PRINT "MKD$(17): <"; MKD$(17); ">" | |||
1360 PRINT "MKI$(17): <"; MKI$(17); ">" | |||
1370 PRINT "MKS$(17): <"; MKS$(17); ">" | |||
1380 PRINT "CVD(MKD$(17)): "; CVD(MKD$(17)) | |||
1390 PRINT "CVS(MKS$(17)): "; CVS(MKS$(17)) | |||
1400 PRINT "CVI(MKI$(17)): "; CVI(MKI$(17)) |
@@ -0,0 +1,54 @@ | |||
10 REM -------------------------------------------------------- | |||
20 REM GOSUB.BAS Test Bywater BASIC Interpreter GOSUB Statement | |||
30 REM -------------------------------------------------------- | |||
40 GOSUB 160 | |||
50 PRINT "Test GOSUB Statements" | |||
60 PRINT "---------------------" | |||
70 PRINT | |||
80 PRINT "1 - Run Subroutine" | |||
90 PRINT "9 - Exit to system" | |||
92 PRINT "x - Exit to BASIC" | |||
100 PRINT | |||
110 INPUT c$ | |||
120 IF c$ = "1" then gosub 430 | |||
130 IF c$ = "9" then goto 600 | |||
132 IF c$ = "x" then end | |||
134 IF c$ = "X" then end | |||
140 GOTO 10 | |||
150 END | |||
160 REM subroutine to clear screen | |||
170 PRINT | |||
180 PRINT | |||
190 PRINT | |||
200 PRINT | |||
210 PRINT | |||
220 PRINT | |||
230 PRINT | |||
240 PRINT | |||
250 PRINT | |||
260 PRINT | |||
270 PRINT | |||
280 PRINT | |||
290 PRINT | |||
300 PRINT | |||
310 PRINT | |||
320 PRINT | |||
330 PRINT | |||
340 PRINT | |||
350 PRINT | |||
360 PRINT | |||
370 PRINT | |||
380 PRINT | |||
390 PRINT | |||
400 PRINT | |||
410 PRINT | |||
420 RETURN | |||
430 REM subroutine to test branching | |||
435 GOSUB 160 | |||
440 PRINT "This is the subroutine." | |||
445 PRINT "Press any key: "; | |||
450 INPUT x$ | |||
460 RETURN | |||
600 GOSUB 160 | |||
610 PRINT "Exit from Bywater BASIC Test Program" | |||
620 SYSTEM |
@@ -0,0 +1,22 @@ | |||
Print "Hello" | |||
goto test_label | |||
Print "This should NOT print" | |||
test_label: | |||
gosub test_sub | |||
Print "Goodbye" | |||
End | |||
test_sub: | |||
Print "This is the subroutine." | |||
gosub test_subsub | |||
Return | |||
test_subsub: | |||
Print "This is the sub-subroutine." | |||
Return |
@@ -0,0 +1,6 @@ | |||
10 rem test if then followed by line number | |||
20 if 5 = 5 then 80 | |||
30 print "The statement failed" | |||
40 stop | |||
80 print "The program succeeded" | |||
90 end |
@@ -0,0 +1,43 @@ | |||
Test Programs for bwBASIC: | |||
------------------------- | |||
___ ___ ABS BAS | |||
___ ___ ASSIGN BAS | |||
___ ___ CALLFUNC BAS * STRUCT_CMDS | |||
___ ___ CALLSUB BAS * STRUCT_CMDS | |||
___ ___ CHAIN1 BAS | |||
___ ___ CHAIN2 BAS * called from CHAIN1.BAS | |||
___ ___ DATAREAD BAS | |||
___ ___ DEFFN BAS | |||
___ ___ DIM BAS | |||
___ ___ DOLOOP BAS * STRUCT_CMDS | |||
___ ___ DOWHILE BAS * STRUCT_CMDS | |||
___ ___ ELSEIF BAS * STRUCT_CMDS | |||
___ ___ END BAS | |||
___ ___ ERR BAS | |||
___ ___ FORNEXT BAS | |||
___ ___ FUNCTION BAS | |||
___ ___ GOSUB BAS | |||
___ ___ GOTOLABL BAS * STRUCT_CMDS | |||
___ ___ IFLINE BAS | |||
___ ___ INPUT BAS | |||
___ ___ LOF BAS * LOF(): IMPLEMENTATION-SPECIFIC | |||
___ ___ LOOPUNTL BAS * STRUCT_CMDS | |||
___ ___ MAIN BAS * STRUCT_CMDS | |||
___ ___ MLIFTHEN BAS * STRUCT_CMDS | |||
___ ___ ON BAS | |||
___ ___ ONERR BAS | |||
___ ___ ONERRLBL BAS * STRUCT_CMDS | |||
___ ___ ONGOSUB BAS | |||
___ ___ OPENTEST BAS | |||
___ ___ OPTION BAS | |||
___ ___ PUTGET BAS * KILL: IMPLEMENTATION-SPECIFIC | |||
___ ___ RANDOM BAS | |||
___ ___ SELCASE BAS * STRUCT_CMDS | |||
___ ___ SNGLFUNC BAS | |||
___ ___ STOP BAS | |||
___ ___ TERM BAS | |||
___ ___ WHILWEND BAS | |||
___ ___ WIDTH BAS | |||
___ ___ WRITEINP BAS | |||
@@ -0,0 +1,7 @@ | |||
10 REM INPUT.BAS -- Test INPUT Statement | |||
20 PRINT "INPUT.BAS -- Test INPUT Statement" | |||
30 REM | |||
40 INPUT "Input string, number: "; s$, n | |||
50 PRINT "The string is: ";s$ | |||
60 PRINT "The number is: ";n | |||
70 END |
@@ -0,0 +1,5 @@ | |||
10 print "Test LOF() Function" | |||
20 input "Filename";F$ | |||
30 open "i", 1, F$ | |||
40 print "Length of file ";F$;" is ";LOF(1);" bytes" | |||
50 close 1 |
@@ -0,0 +1,6 @@ | |||
10 rem LOOPUNTL.BAS | |||
20 i = 0 | |||
30 do | |||
40 i = i + 1 | |||
50 print "Value of i is";i | |||
60 loop until i > 12 |
@@ -0,0 +1,17 @@ | |||
Sub Prior | |||
Print "This is a subroutine prior to MAIN." | |||
Print "This should not print." | |||
End Sub | |||
Sub Main | |||
Print "This is the MAIN subroutine." | |||
Print "This should print." | |||
End Sub | |||
Sub Subsequent | |||
Print "This is a subroutine subsequent to MAIN." | |||
Print "This should not print." | |||
End Sub | |||
@@ -0,0 +1,16 @@ | |||
rem ------------------------------------------------- | |||
rem mlifthen.bas -- Test MultiLine IF-THEN statement | |||
rem ------------------------------------------------- | |||
Print "MLIFTHEN.BAS -- Test MultiLine IF-THEN-ELSE Constructions" | |||
If 3 = 4 then | |||
Print "The Condition is true." | |||
Print "And it still is true." | |||
Else | |||
Print "The condition is false." | |||
Print "And it still is false." | |||
End If | |||
Print "This concludes our test." |
@@ -0,0 +1,14 @@ | |||
10 print "ON.BAS -- Test ON...GOTO Statement" | |||
20 input "Enter a number 1-5:";n | |||
30 on n goto 40, 60, 80, 100, 120 | |||
40 print "You entered 1" | |||
50 goto 140 | |||
60 print "You entered 2" | |||
70 goto 140 | |||
80 print "You entered 3" | |||
90 goto 140 | |||
100 print "You entered 4" | |||
110 goto 140 | |||
120 print "You entered 5" | |||
130 goto 140 | |||
140 end |
@@ -0,0 +1,12 @@ | |||
10 rem onerr.bas -- test bwBASIC ON ERROR GOSUB statement | |||
20 print "Test bwBASIC ON ERROR GOSUB statement" | |||
30 on error gosub 100 | |||
40 print "The next line will include an error" | |||
50 if d$ = 78.98 then print "This should not print" | |||
60 print "This is the line after the error" | |||
70 end | |||
100 rem Error handler | |||
110 print "This is the error handler" | |||
120 print "The error number is ";err | |||
130 print "The error line is ";erl | |||
150 return |
@@ -0,0 +1,12 @@ | |||
rem onerrlbl.bas -- test bwBASIC ON ERROR GOSUB statement with label | |||
print "Test bwBASIC ON ERROR GOSUB statement" | |||
on error gosub handler | |||
print "The next line will include an error" | |||
if d$ = 78.98 then print "This should not print" | |||
print "This is the line after the error" | |||
end | |||
handler: | |||
print "This is the error handler" | |||
print "The error number is ";err | |||
print "The error line is ";erl | |||
return |
@@ -0,0 +1,15 @@ | |||
10 print "ONGOSUB.BAS -- Test ON..GOSUB Statement" | |||
20 input "Enter a number 1-5";n | |||
30 on n gosub 60, 80, 100, 120, 140 | |||
40 print "The End" | |||
50 end | |||
60 print "You entered 1" | |||
70 return | |||
80 print "You entered 2" | |||
90 return | |||
100 print "You entered 3" | |||
110 return | |||
120 print "You entered 4" | |||
130 return | |||
140 print "You entered 5" | |||
150 return |
@@ -0,0 +1,12 @@ | |||
10 PRINT "OPENTEST.BAS -- Test OPEN, PRINT#, LINE INPUT#, and CLOSE" | |||
20 OPEN "test.out" FOR OUTPUT AS # 1 | |||
30 PRINT #1,"This is line 1." | |||
40 PRINT #1, "This is line 2." | |||
50 CLOSE #1 | |||
60 OPEN "test.out" FOR INPUT AS #1 | |||
70 LINE INPUT #1,A$ | |||
80 LINE INPUT #1,B$ | |||
90 PRINT "Read from file:" | |||
100 PRINT ">";A$ | |||
110 PRINT ">";B$ | |||
120 CLOSE #1 |
@@ -0,0 +1,8 @@ | |||
1 PRINT "OPTION.BAS -- Test OPTION BASE Statement" | |||
5 OPTION BASE 1 | |||
10 DIM n(5) | |||
20 FOR i = 1 to 5 | |||
30 LET n(i) = i + 2 | |||
40 PRINT "The value at position ";i;" is ";n(i) | |||
50 NEXT i | |||
60 END |
@@ -0,0 +1,17 @@ | |||
100 dim pascal(14,14) | |||
110 pascal(1,1) = 1 | |||
120 for i = 2 to 14 | |||
130 pascal(i,1) = 1 | |||
140 for j = 2 to i | |||
150 pascal(i,j) = pascal(i-1,j)+pascal(i-1,j-1) | |||
160 next j | |||
170 next i | |||
180 for i = 1 to 14 | |||
190 print i-1; ": "; | |||
200 for j = 1 to i | |||
210 print pascal(i,j); | |||
220 next j | |||
230 print | |||
240 next i | |||
250 end | |||
@@ -0,0 +1,22 @@ | |||
rem PUTGET.BAS -- Test PUT and GET statements | |||
open "r", 1, "test.dat", 48 | |||
field 1, 20 as r1$, 20 as r2$, 8 as r3$ | |||
for l = 1 to 2 | |||
line input "name: "; n$ | |||
line input "address: "; m$ | |||
line input "phone: "; p$ | |||
lset r1$ = n$ | |||
lset r2$ = m$ | |||
lset r3$ = p$ | |||
put #1, l | |||
next l | |||
close #1 | |||
open "r", 1, "test.dat", 48 | |||
field 1, 20 as r1$, 20 as r2$, 8 as r3$ | |||
for l = 1 to 2 | |||
get #1, l | |||
print r1$, r2$, r3$ | |||
next l | |||
close #1 | |||
kill "test.dat" | |||
end |
@@ -0,0 +1,13 @@ | |||
100 rem RANDOM.BAS -- Test RANDOMIZE and RND | |||
110 print "This is a first sequence of three RND numbers:" | |||
120 randomize timer | |||
130 print rnd | |||
140 print rnd | |||
150 print rnd | |||
160 print "This is a second sequence of three RND numbers:" | |||
170 randomize timer + 18 | |||
180 print rnd | |||
190 print rnd | |||
200 print rnd | |||
210 print "The second sequence should have been differrent" | |||
220 print "from the first." |
@@ -0,0 +1,31 @@ | |||
rem SelCase.bas -- test SELECT CASE | |||
Sub Main | |||
Print "SelCase.bas -- test SELECT CASE statement" | |||
Input "Enter a number"; d | |||
Select Case d | |||
Case 3 to 5 | |||
Print "The number is between 3 and 5." | |||
Case 6 | |||
Print "The number you entered is 6." | |||
Case 7 to 9 | |||
Print "The number is between 7 and 9." | |||
Case If > 10 | |||
Print "The number is greater than 10" | |||
Case If < 0 | |||
Print "The number is less than 0" | |||
Case Else | |||
Print "The number is 1, 2 or 10." | |||
End Select | |||
End Sub | |||
@@ -0,0 +1,15 @@ | |||
rem ---------------------------------------------------- | |||
rem SnglFunc.BAS | |||
rem ---------------------------------------------------- | |||
Print "SnglFunc.BAS -- Test Single-Line User-defined Function Statement" | |||
Def Sum( x, y ) = x + y | |||
Print "The sum of 6 and 4 is "; Sum( 6, 4 ) | |||
Print "Did it work properly?" | |||
End |
@@ -0,0 +1,6 @@ | |||
10 REM STOP.BAS -- Test STOP Statement | |||
20 PRINT "STOP.BAS -- Test STOP Statement" | |||
30 PRINT "If the program is interrupted after this line, STOP worked OK" | |||
40 STOP | |||
50 PRINT "But if this line printed, then it did not work." | |||
60 END |
@@ -0,0 +1,10 @@ | |||
10 REM BWBASIC Program to Demonstrate Terminal-Specific Use | |||
20 REM The following definitions are for an ANSI Terminal. | |||
30 REM You may have to define different variables for your | |||
40 REM particular terminal | |||
50 REM | |||
60 LET CL$ = chr$(&h1b)+"[2J" | |||
70 PRINT CL$; | |||
80 PRINT " Bywater BASIC" | |||
90 INPUT c$ | |||
100 END |
@@ -0,0 +1,13 @@ | |||
10 REM WHILWEND.BAS -- Test WHILE-WEND Loops | |||
20 PRINT "START" | |||
30 LET X = 0 | |||
40 WHILE X < 25 | |||
50 PRINT "x is ";X | |||
60 LET X = X + 1 | |||
70 LET Y = 0 | |||
80 WHILE Y < 2 | |||
90 PRINT "y is "; Y | |||
100 LET Y = Y + 1 | |||
110 WEND | |||
120 WEND | |||
130 PRINT "END" |
@@ -0,0 +1,5 @@ | |||
10 open "o", #1, "data.tmp" | |||
20 width #1, 35 | |||
30 print #1, "123456789012345678901234567890123456789012345678901234567890" | |||
40 close #1 | |||
50 print "Check file <data.tmp> to see if the printing wrapped at col 35" |
@@ -0,0 +1,20 @@ | |||
10 rem WRITEINP.BAS -- Test WRITE # and INPUT # Statements | |||
20 print "WRITEINP.BAS -- Test WRITE # and INPUT # Statements" | |||
30 s1$ = "String 1" | |||
40 s2$ = "String 2" | |||
50 s3$ = "String 3" | |||
60 x1 = 1.1234567 | |||
70 x2 = 2.2345678 | |||
80 x3 = 3.3456789 | |||
90 open "o", #1, "data.tmp" | |||
100 write #1, s1$, x1, s2$, x2, s3$, x3 | |||
110 close #1 | |||
120 print "This is what was written:" | |||
130 write s1$, x1, s2$, x2, s3$, x3 | |||
140 open "i", #2, "data.tmp" | |||
150 input #2, b1$, n1, b2$, n2, b3$, n3 | |||
160 close #2 | |||
170 print "This is what was read:" | |||
180 write b1$, n1, b2$, n2, b3$, n3 | |||
190 print "End of WRITEINP.BAS" | |||
200 end |
@@ -0,0 +1,704 @@ | |||
/*************************************************************** | |||
bwx_iqc.c Environment-dependent implementation | |||
of Bywater BASIC Interpreter | |||
for IBM PC and Compatibles | |||
using the Microsoft QuickC (tm) Compiler | |||
Copyright (c) 1993, Ted A. Campbell | |||
Bywater Software | |||
email: tcamp@delphi.com | |||
Copyright and Permissions Information: | |||
All U.S. and international rights are claimed by the author, | |||
Ted A. Campbell. | |||
This software is released under the terms of the GNU General | |||
Public License (GPL), which is distributed with this software | |||
in the file "COPYING". The GPL specifies the terms under | |||
which users may copy and use the software in this distribution. | |||
A separate license is available for commercial distribution, | |||
for information on which you should contact the author. | |||
***************************************************************/ | |||
#include <stdio.h> | |||
#include <stdlib.h> | |||
#include <setjmp.h> | |||
#include <bios.h> | |||
#include <graph.h> | |||
#include <signal.h> | |||
#include "bwbasic.h" | |||
#include "bwb_mes.h" | |||
extern int prn_col; | |||
extern jmp_buf mark; | |||
short oldfgd; | |||
long oldbgd; | |||
int reset_mode = FALSE; | |||
static int iqc_setpos( void ); | |||
/*************************************************************** | |||
FUNCTION: main() | |||
DESCRIPTION: As in any C program, main() is the basic | |||
function from which the rest of the | |||
program is called. Some environments, | |||
however, provide their own main() functions | |||
(Microsoft Windows (tm) is an example). | |||
In these cases, the following code will | |||
have to be included in the initialization | |||
function that is called by the environment. | |||
***************************************************************/ | |||
void | |||
main( int argc, char **argv ) | |||
{ | |||
#if MS_CMDS | |||
struct videoconfig vc; | |||
short videomode; | |||
/* Save original foreground, background, and text position. */ | |||
_getvideoconfig( &vc ); | |||
oldfgd = _gettextcolor(); | |||
oldbgd = _getbkcolor(); | |||
if ( vc.mode != _TEXTC80 ) | |||
{ | |||
if ( _setvideomode( _TEXTC80 ) == 0 ) | |||
{ | |||
_getvideoconfig( &vc ); | |||
prn_xprintf( stderr, "Failed to set color video mode\n" ); | |||
} | |||
else | |||
{ | |||
reset_mode = FALSE; | |||
} | |||
} | |||
else | |||
{ | |||
reset_mode = FALSE; | |||
} | |||
#endif /* MS_CMDS */ | |||
bwb_init( argc, argv ); | |||
#if INTERACTIVE | |||
setjmp( mark ); | |||
#endif | |||
/* now set the number of colors available */ | |||
* var_findnval( co, co->array_pos ) = (bnumber) vc.numcolors; | |||
/* main program loop */ | |||
while( !feof( stdin ) ) /* condition !feof( stdin ) added in v1.11 */ | |||
{ | |||
bwb_mainloop(); | |||
} | |||
} | |||
/*************************************************************** | |||
FUNCTION: bwx_signon() | |||
DESCRIPTION: | |||
***************************************************************/ | |||
int | |||
bwx_signon( void ) | |||
{ | |||
sprintf( bwb_ebuf, "\r%s %s\n", MES_SIGNON, VERSION ); | |||
prn_xprintf( stdout, bwb_ebuf ); | |||
sprintf( bwb_ebuf, "\r%s\n", MES_COPYRIGHT ); | |||
prn_xprintf( stdout, bwb_ebuf ); | |||
#if PERMANENT_DEBUG | |||
sprintf( bwb_ebuf, "\r%s\n", "Debugging Mode" ); | |||
prn_xprintf( stdout, bwb_ebuf ); | |||
#else | |||
sprintf( bwb_ebuf, "\r%s\n", MES_LANGUAGE ); | |||
prn_xprintf( stdout, bwb_ebuf ); | |||
#endif | |||
return TRUE; | |||
} | |||
/*************************************************************** | |||
FUNCTION: bwx_message() | |||
DESCRIPTION: | |||
***************************************************************/ | |||
int | |||
bwx_message( char *m ) | |||
{ | |||
#if DEBUG | |||
_outtext( "<MES>" ); | |||
#endif | |||
_outtext( m ); | |||
return TRUE; | |||
} | |||
/*************************************************************** | |||
FUNCTION: bwx_putc() | |||
DESCRIPTION: | |||
***************************************************************/ | |||
extern int | |||
bwx_putc( char c ) | |||
{ | |||
static char tbuf[ 2 ]; | |||
tbuf[ 0 ] = c; | |||
tbuf[ 1 ] = '\0'; | |||
_outtext( tbuf ); | |||
return TRUE; | |||
} | |||
/*************************************************************** | |||
FUNCTION: bwx_error() | |||
DESCRIPTION: | |||
***************************************************************/ | |||
int | |||
bwx_errmes( char *m ) | |||
{ | |||
static char tbuf[ MAXSTRINGSIZE + 1 ]; /* this memory should be | |||
permanent in case of memory | |||
overrun errors */ | |||
if (( prn_col != 1 ) && ( errfdevice == stderr )) | |||
{ | |||
prn_xprintf( errfdevice, "\n" ); | |||
} | |||
if ( CURTASK number == 0 ) | |||
{ | |||
sprintf( tbuf, "\n%s: %s\n", ERRD_HEADER, m ); | |||
} | |||
else | |||
{ | |||
sprintf( tbuf, "\n%s %d: %s\n", ERROR_HEADER, CURTASK number, m ); | |||
} | |||
#if INTENSIVE_DEBUG | |||
prn_xprintf( stderr, "<ERR>" ); | |||
#endif | |||
prn_xprintf( errfdevice, tbuf ); | |||
return TRUE; | |||
} | |||
/*************************************************************** | |||
FUNCTION: bwx_input() | |||
DESCRIPTION: As implemented here, the input facility | |||
is a hybrid of _outtext output (which allows | |||
the color to be set) and standard output | |||
(which does not). The reason is that I've | |||
found it helpful to use the DOS facility | |||
for text entry, with its backspace-delete | |||
and recognition of the SIGINT, depite the | |||
fact that its output goes to stdout. | |||
***************************************************************/ | |||
int | |||
bwx_input( char *prompt, char *buffer ) | |||
{ | |||
#if INTENSIVE_DEBUG | |||
prn_xprintf( stdout, "<INP>" ); | |||
#endif | |||
prn_xprintf( stdout, prompt ); | |||
fgets( buffer, MAXREADLINESIZE, stdin ); | |||
prn_xprintf( stdout, "\n" ); /* let _outtext catch up */ | |||
* prn_getcol( stdout ) = 1; /* reset column */ | |||
return TRUE; | |||
} | |||
/*************************************************************** | |||
FUNCTION: bwx_terminate() | |||
DESCRIPTION: | |||
***************************************************************/ | |||
void | |||
bwx_terminate( void ) | |||
{ | |||
#if MS_CMDS | |||
if ( reset_mode == TRUE ) | |||
{ | |||
_setvideomode( _DEFAULTMODE ); | |||
/* Restore original foreground and background. */ | |||
_settextcolor( oldfgd ); | |||
_setbkcolor( oldbgd ); | |||
} | |||
#endif | |||
exit( 0 ); | |||
} | |||
/*************************************************************** | |||
FUNCTION: bwx_shell() | |||
DESCRIPTION: | |||
***************************************************************/ | |||
#if COMMAND_SHELL | |||
extern int | |||
bwx_shell( struct bwb_line *l ) | |||
{ | |||
static char *s_buffer; | |||
static int init = FALSE; | |||
static int position; | |||
/* get memory for temporary buffer if necessary */ | |||
if ( init == FALSE ) | |||
{ | |||
init = TRUE; | |||
if ( ( s_buffer = calloc( MAXSTRINGSIZE + 1, sizeof( char ) )) == NULL ) | |||
{ | |||
bwb_error( err_getmem ); | |||
return FALSE; | |||
} | |||
} | |||
/* get the first element and check for a line number */ | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in bwx_shell(): line buffer is <%s>.", l->buffer ); | |||
bwb_debug( bwb_ebuf ); | |||
#endif | |||
position = 0; | |||
adv_element( l->buffer, &position, s_buffer ); | |||
if ( is_numconst( s_buffer ) != TRUE ) /* not a line number */ | |||
{ | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in bwx_shell(): no line number, command <%s>.", | |||
l->buffer ); | |||
bwb_debug( bwb_ebuf ); | |||
#endif | |||
if ( system( l->buffer ) == 0 ) | |||
{ | |||
iqc_setpos(); | |||
return TRUE; | |||
} | |||
else | |||
{ | |||
iqc_setpos(); | |||
return FALSE; | |||
} | |||
} | |||
else /* advance past line number */ | |||
{ | |||
adv_ws( l->buffer, &position ); /* advance past whitespace */ | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in bwx_shell(): line number, command <%s>.", | |||
l->buffer ); | |||
bwb_debug( bwb_ebuf ); | |||
#endif | |||
if ( system( &( l->buffer[ position ] ) ) == 0 ) | |||
{ | |||
iqc_setpos(); | |||
return TRUE; | |||
} | |||
else | |||
{ | |||
iqc_setpos(); | |||
return FALSE; | |||
} | |||
} | |||
} | |||
#endif | |||
/*************************************************************** | |||
FUNCTION: iqc_setpos() | |||
DESCRIPTION: | |||
***************************************************************/ | |||
static int | |||
iqc_setpos( void ) | |||
{ | |||
union REGS ibm_registers; | |||
/* call the BDOS function 0x10 to read the current cursor position */ | |||
ibm_registers.h.ah = 3; | |||
ibm_registers.h.bh = (unsigned char) _getvisualpage(); | |||
int86( 0x10, &ibm_registers, &ibm_registers ); | |||
/* set text to this position */ | |||
_settextposition( ibm_registers.h.dh, ibm_registers.h.dl ); | |||
/* and move down one position */ | |||
prn_xprintf( stdout, "\n" ); | |||
return TRUE; | |||
} | |||
#if COMMON_CMDS | |||
/*************************************************************** | |||
FUNCTION: bwb_edit() | |||
DESCRIPTION: | |||
***************************************************************/ | |||
struct bwb_line * | |||
bwb_edit( struct bwb_line *l ) | |||
{ | |||
char tbuf[ MAXSTRINGSIZE + 1 ]; | |||
char edname[ MAXSTRINGSIZE + 1 ]; | |||
struct bwb_variable *ed; | |||
FILE *loadfile; | |||
ed = var_find( DEFVNAME_EDITOR ); | |||
str_btoc( edname, var_getsval( ed )); | |||
sprintf( tbuf, "%s %s", edname, CURTASK progfile ); | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in bwb_edit(): command line <%s>", tbuf ); | |||
bwb_debug( bwb_ebuf ); | |||
#else | |||
system( tbuf ); | |||
#endif | |||
/* clear current contents */ | |||
bwb_new( l ); | |||
/* open edited file for read */ | |||
if ( ( loadfile = fopen( CURTASK progfile, "r" )) == NULL ) | |||
{ | |||
sprintf( bwb_ebuf, err_openfile, CURTASK progfile ); | |||
bwb_error( bwb_ebuf ); | |||
iqc_setpos(); | |||
return bwb_zline( l ); | |||
} | |||
/* and (re)load the file into memory */ | |||
bwb_fload( loadfile ); | |||
iqc_setpos(); | |||
return bwb_zline( l ); | |||
} | |||
/*************************************************************** | |||
FUNCTION: bwb_files() | |||
DESCRIPTION: | |||
***************************************************************/ | |||
struct bwb_line * | |||
bwb_files( struct bwb_line *l ) | |||
{ | |||
char tbuf[ MAXVARNAMESIZE + 1 ]; | |||
char finame[ MAXVARNAMESIZE + 1 ]; | |||
char argument[ MAXVARNAMESIZE + 1 ]; | |||
struct bwb_variable *fi; | |||
struct exp_ese *e; | |||
fi = var_find( DEFVNAME_FILES ); | |||
str_btoc( finame, var_getsval( fi )); | |||
/* get argument */ | |||
adv_ws( l->buffer, &( l->position )); | |||
switch( l->buffer[ l->position ] ) | |||
{ | |||
case '\0': | |||
case '\r': | |||
case '\n': | |||
argument[ 0 ] = '\0'; | |||
break; | |||
default: | |||
e = bwb_exp( l->buffer, FALSE, &( l->position ) ); | |||
if ( e->type != STRING ) | |||
{ | |||
bwb_error( err_mismatch ); | |||
return bwb_zline( l ); | |||
} | |||
str_btoc( argument, exp_getsval( e ) ); | |||
break; | |||
} | |||
sprintf( tbuf, "%s %s", finame, argument ); | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in bwb_files(): command line <%s>", tbuf ); | |||
bwb_debug( bwb_ebuf ); | |||
#else | |||
system( tbuf ); | |||
#endif | |||
iqc_setpos(); | |||
return bwb_zline( l ); | |||
} | |||
#endif /* COMMON_CMDS */ | |||
#if INTERACTIVE | |||
/*************************************************************** | |||
FUNCTION: fnc_inkey() | |||
DESCRIPTION: This C function implements the BASIC INKEY$ | |||
function. It is implementation-specific. | |||
***************************************************************/ | |||
extern struct bwb_variable * | |||
fnc_inkey( int argc, struct bwb_variable *argv ) | |||
{ | |||
static struct bwb_variable nvar; | |||
char tbuf[ MAXSTRINGSIZE + 1 ]; | |||
static int init = FALSE; | |||
/* initialize the variable if necessary */ | |||
if ( init == FALSE ) | |||
{ | |||
init = TRUE; | |||
var_make( &nvar, STRING ); | |||
} | |||
/* check arguments */ | |||
#if PROG_ERRORS | |||
if ( argc > 0 ) | |||
{ | |||
sprintf( bwb_ebuf, "Two many arguments to function INKEY$()" ); | |||
bwb_error( bwb_ebuf ); | |||
return &nvar; | |||
} | |||
#else | |||
if ( fnc_checkargs( argc, argv, 0, 0 ) == FALSE ) | |||
{ | |||
return NULL; | |||
} | |||
#endif | |||
/* body of the INKEY$ function */ | |||
if ( _bios_keybrd( _KEYBRD_READY ) == 0 ) | |||
{ | |||
tbuf[ 0 ] = '\0'; | |||
} | |||
else | |||
{ | |||
tbuf[ 0 ] = (char) _bios_keybrd( _KEYBRD_READ ); | |||
tbuf[ 1 ] = '\0'; | |||
} | |||
/* assign value to nvar variable */ | |||
str_ctob( var_findsval( &nvar, nvar.array_pos ), tbuf ); | |||
/* return value contained in nvar */ | |||
return &nvar; | |||
} | |||
#endif /* INTERACTIVE */ | |||
#if MS_CMDS | |||
/*************************************************************** | |||
FUNCTION: bwb_cls() | |||
DESCRIPTION: This C function implements the BASIC CLS | |||
command. It is implementation-specific. | |||
***************************************************************/ | |||
extern struct bwb_line * | |||
bwb_cls( struct bwb_line *l ) | |||
{ | |||
_clearscreen( _GCLEARSCREEN ); | |||
return bwb_zline( l ); | |||
} | |||
/*************************************************************** | |||
FUNCTION: bwb_locate() | |||
DESCRIPTION: This C function implements the BASIC LOCATE | |||
command. It is implementation-specific. | |||
***************************************************************/ | |||
extern struct bwb_line * | |||
bwb_locate( struct bwb_line *l ) | |||
{ | |||
struct exp_ese *e; | |||
int row, column; | |||
/* get first argument */ | |||
e = bwb_exp( l->buffer, FALSE, &( l->position )); | |||
row = (int) exp_getnval( e ); | |||
/* advance past comma */ | |||
adv_ws( l->buffer, &( l->position )); | |||
if ( l->buffer[ l->position ] != ',' ) | |||
{ | |||
bwb_error( err_syntax ); | |||
return bwb_zline( l ); | |||
} | |||
++( l->position ); | |||
/* get second argument */ | |||
e = bwb_exp( l->buffer, FALSE, &( l->position )); | |||
column = (int) exp_getnval( e ); | |||
/* position the cursor */ | |||
_settextposition( row, column ); | |||
return bwb_zline( l ); | |||
} | |||
/*************************************************************** | |||
FUNCTION: bwb_color() | |||
DESCRIPTION: This C function implements the BASIC COLOR | |||
command. It is implementation-specific. | |||
***************************************************************/ | |||
extern struct bwb_line * | |||
bwb_color( struct bwb_line *l ) | |||
{ | |||
struct exp_ese *e; | |||
int color; | |||
/* get first argument */ | |||
e = bwb_exp( l->buffer, FALSE, &( l->position )); | |||
color = (int) exp_getnval( e ); | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "Setting text color to %d", color ); | |||
bwb_debug( bwb_ebuf ); | |||
#endif | |||
_settextcolor( (short) color ); | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "Set text color to %d", color ); | |||
bwb_debug( bwb_ebuf ); | |||
#endif | |||
/* advance past comma */ | |||
adv_ws( l->buffer, &( l->position )); | |||
if ( l->buffer[ l->position ] == ',' ) | |||
{ | |||
++( l->position ); | |||
/* get second argument */ | |||
e = bwb_exp( l->buffer, FALSE, &( l->position )); | |||
color = (int) exp_getnval( e ); | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "Setting background color to %d", color ); | |||
bwb_debug( bwb_ebuf ); | |||
#endif | |||
/* set the background color */ | |||
_setbkcolor( (long) color ); | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "Setting background color to %d\n", color ); | |||
bwb_debug( bwb_ebuf ); | |||
#endif | |||
} | |||
return bwb_zline( l ); | |||
} | |||
#endif /* MS_CMDS */ | |||
@@ -0,0 +1,40 @@ | |||
/*************************************************************** | |||
bwx_iqc.h Header File for IBM PC and Compatible | |||
Implementation of bwBASIC | |||
Using Microsoft QuickC (tm) Compiler | |||
Copyright (c) 1993, Ted A. Campbell | |||
Bywater Software | |||
email: tcamp@delphi.com | |||
Copyright and Permissions Information: | |||
All U.S. and international rights are claimed by the author, | |||
Ted A. Campbell. | |||
This software is released under the terms of the GNU General | |||
Public License (GPL), which is distributed with this software | |||
in the file "COPYING". The GPL specifies the terms under | |||
which users may copy and use the software in this distribution. | |||
A separate license is available for commercial distribution, | |||
for information on which you should contact the author. | |||
***************************************************************/ | |||
#define IMP_IDSTRING "IQC" /* unique ID string for this implementation */ | |||
/* Definitions indicating which commands and functions are implemented */ | |||
#define IMP_FNCINKEY 1 /* 0 if INKEY$ is not implemented, 1 if it is */ | |||
#define IMP_CMDCLS 1 /* 0 if CLS is not implemented, 1 if it is */ | |||
#define IMP_CMDLOC 1 /* 0 if LOCATE is not implemented, 1 if it is */ | |||
#define IMP_CMDCOLOR 1 /* 0 if COLOR is not implemented, 1 if it is */ | |||
#define UNIX_CMDS TRUE | |||
#define MKDIR_ONE_ARG TRUE /* TRUE if your mkdir has but one argument; | |||
FALSE if it has two */ | |||
#define PERMISSIONS 493 /* permissions to set in Unix-type system */ | |||
@@ -0,0 +1,517 @@ | |||
/*************************************************************** | |||
bwx_tty.c Environment-dependent implementation | |||
for Bywater BASIC Interpreter | |||
using simple TTY-style input/output | |||
This file should be used as a template | |||
for developing more sophisticated | |||
environment-dependent implementations | |||
Copyright (c) 1993, Ted A. Campbell | |||
Bywater Software | |||
email: tcamp@delphi.com | |||
Copyright and Permissions Information: | |||
All U.S. and international rights are claimed by the author, | |||
Ted A. Campbell. | |||
This software is released under the terms of the GNU General | |||
Public License (GPL), which is distributed with this software | |||
in the file "COPYING". The GPL specifies the terms under | |||
which users may copy and use the software in this distribution. | |||
A separate license is available for commercial distribution, | |||
for information on which you should contact the author. | |||
***************************************************************/ | |||
#include <stdio.h> | |||
#include "bwbasic.h" | |||
#include "bwb_mes.h" | |||
#if HAVE_LONGJMP | |||
#include <setjmp.h> | |||
#endif | |||
extern int prn_col; | |||
#if HAVE_LONGJMP | |||
extern jmp_buf mark; | |||
#endif | |||
/*************************************************************** | |||
FUNCTION: main() | |||
DESCRIPTION: As in any C program, main() is the basic | |||
function from which the rest of the | |||
program is called. Some environments, | |||
however, provide their own main() functions | |||
(Microsoft Windows (tm) is an example). | |||
In these cases, the following code will | |||
have to be included in the initialization | |||
function that is called by the environment. | |||
***************************************************************/ | |||
#if ANSI_C | |||
void | |||
main( int argc, char **argv ) | |||
#else | |||
main( argc, argv ) | |||
int argc; | |||
char **argv; | |||
#endif | |||
{ | |||
bwb_init( argc, argv ); | |||
#if HAVE_LONGJMP | |||
#if INTERACTIVE | |||
setjmp( mark ); | |||
#endif | |||
#endif | |||
/* main program loop */ | |||
while( !feof( stdin ) ) /* condition !feof( stdin ) added in v1.11 */ | |||
{ | |||
bwb_mainloop(); | |||
} | |||
bwx_terminate(); /* in case of ^D exit in Unix systems */ | |||
} | |||
/*************************************************************** | |||
FUNCTION: bwx_signon() | |||
DESCRIPTION: This function prints out the sign-on | |||
message for bwBASIC. | |||
***************************************************************/ | |||
#if ANSI_C | |||
int | |||
bwx_signon( void ) | |||
#else | |||
int | |||
bwx_signon() | |||
#endif | |||
{ | |||
sprintf( bwb_ebuf, "\r%s %s\n", MES_SIGNON, VERSION ); | |||
prn_xprintf( stdout, bwb_ebuf ); | |||
sprintf( bwb_ebuf, "\r%s\n", MES_COPYRIGHT ); | |||
prn_xprintf( stdout, bwb_ebuf ); | |||
#if PERMANENT_DEBUG | |||
sprintf( bwb_ebuf, "\r%s\n", "Debugging Mode" ); | |||
prn_xprintf( stdout, bwb_ebuf ); | |||
#else | |||
sprintf( bwb_ebuf, "\r%s\n", MES_LANGUAGE ); | |||
prn_xprintf( stdout, bwb_ebuf ); | |||
#endif | |||
return TRUE; | |||
} | |||
/*************************************************************** | |||
FUNCTION: bwx_message() | |||
DESCRIPTION: This function outputs a message to the | |||
default output device. | |||
***************************************************************/ | |||
#if ANSI_C | |||
int | |||
bwx_message( char *m ) | |||
#else | |||
int | |||
bwx_message( m ) | |||
char *m; | |||
#endif | |||
{ | |||
#if INTENSIVE_DEBUG | |||
fprintf( stderr, "<MES>" ); | |||
#endif | |||
prn_xprintf( stdout, m ); | |||
return TRUE; | |||
} | |||
/*************************************************************** | |||
FUNCTION: bwx_putc() | |||
DESCRIPTION: This function outputs a single character | |||
to the default output device. | |||
***************************************************************/ | |||
#if ANSI_C | |||
int | |||
bwx_putc( char c ) | |||
#else | |||
int | |||
bwx_putc( c ) | |||
char c; | |||
#endif | |||
{ | |||
return fputc( c, stdout ); | |||
} | |||
/*************************************************************** | |||
FUNCTION: bwx_error() | |||
DESCRIPTION: This function outputs a message to the | |||
default error-message device. | |||
***************************************************************/ | |||
#if ANSI_C | |||
int | |||
bwx_errmes( char *m ) | |||
#else | |||
int | |||
bwx_errmes( m ) | |||
char *m; | |||
#endif | |||
{ | |||
static char tbuf[ MAXSTRINGSIZE + 1 ]; /* this memory should be | |||
permanent in case of memory | |||
overrun errors */ | |||
if (( prn_col != 1 ) && ( errfdevice == stderr )) | |||
{ | |||
prn_xprintf( errfdevice, "\n" ); | |||
} | |||
if ( CURTASK number == 0 ) | |||
{ | |||
sprintf( tbuf, "\n%s: %s\n", ERRD_HEADER, m ); | |||
} | |||
else | |||
{ | |||
sprintf( tbuf, "\n%s %d: %s\n", ERROR_HEADER, CURTASK number, m ); | |||
} | |||
#if INTENSIVE_DEBUG | |||
fprintf( stderr, "<ERR>" ); | |||
#endif | |||
prn_xprintf( errfdevice, tbuf ); | |||
return TRUE; | |||
} | |||
/*************************************************************** | |||
FUNCTION: bwx_input() | |||
DESCRIPTION: This function outputs the string pointed | |||
to by 'prompt', then inputs a character | |||
string. | |||
***************************************************************/ | |||
#if ANSI_C | |||
int | |||
bwx_input( char *prompt, char *buffer ) | |||
#else | |||
int | |||
bwx_input( prompt, buffer ) | |||
char *prompt; | |||
char *buffer; | |||
#endif | |||
{ | |||
#if INTENSIVE_DEBUG | |||
fprintf( stderr, "<INP>" ); | |||
#endif | |||
prn_xprintf( stdout, prompt ); | |||
fgets( buffer, MAXREADLINESIZE, stdin ); | |||
* prn_getcol( stdout ) = 1; /* reset column */ | |||
return TRUE; | |||
} | |||
/*************************************************************** | |||
FUNCTION: bwx_terminate() | |||
DESCRIPTION: This function terminates program execution. | |||
***************************************************************/ | |||
#if ANSI_C | |||
void | |||
bwx_terminate( void ) | |||
#else | |||
void | |||
bwx_terminate() | |||
#endif | |||
{ | |||
#if INTENSIVE_DEBUG | |||
fprintf( stderr, "Normal Termination\n" ); | |||
#endif | |||
exit( 0 ); | |||
} | |||
/*************************************************************** | |||
FUNCTION: bwx_shell() | |||
DESCRIPTION: This function runs a shell program. | |||
***************************************************************/ | |||
#if COMMAND_SHELL | |||
#if ANSI_C | |||
extern int | |||
bwx_shell( struct bwb_line *l ) | |||
#else | |||
extern int | |||
bwx_shell( l ) | |||
struct bwb_line *l; | |||
#endif | |||
{ | |||
static char *s_buffer; | |||
static int init = FALSE; | |||
static int position; | |||
/* get memory for temporary buffer if necessary */ | |||
if ( init == FALSE ) | |||
{ | |||
init = TRUE; | |||
if ( ( s_buffer = calloc( MAXSTRINGSIZE + 1, sizeof( char ) )) == NULL ) | |||
{ | |||
bwb_error( err_getmem ); | |||
return FALSE; | |||
} | |||
} | |||
/* get the first element and check for a line number */ | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in bwx_shell(): line buffer is <%s>.", l->buffer ); | |||
bwb_debug( bwb_ebuf ); | |||
#endif | |||
position = 0; | |||
adv_element( l->buffer, &position, s_buffer ); | |||
if ( is_numconst( s_buffer ) != TRUE ) /* not a line number */ | |||
{ | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in bwx_shell(): no line number, command <%s>.", | |||
l->buffer ); | |||
bwb_debug( bwb_ebuf ); | |||
#endif | |||
if ( system( l->buffer ) == 0 ) | |||
{ | |||
return TRUE; | |||
} | |||
else | |||
{ | |||
return FALSE; | |||
} | |||
} | |||
else /* advance past line number */ | |||
{ | |||
adv_ws( l->buffer, &position ); /* advance past whitespace */ | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in bwx_shell(): line number, command <%s>.", | |||
l->buffer ); | |||
bwb_debug( bwb_ebuf ); | |||
#endif | |||
if ( system( &( l->buffer[ position ] ) ) == 0 ) | |||
{ | |||
return TRUE; | |||
} | |||
else | |||
{ | |||
return FALSE; | |||
} | |||
} | |||
} | |||
#endif | |||
/*************************************************************** | |||
FUNCTION: matherr() | |||
DESCRIPTION: This function is called to handle math | |||
errors in Bywater BASIC. It displays | |||
the error message, then calls the | |||
break_handler() routine. | |||
***************************************************************/ | |||
#if ANSI_C | |||
int | |||
matherr( struct exception *except ) | |||
#else | |||
int | |||
matherr( except ) | |||
struct exception *except; | |||
#endif | |||
{ | |||
perror( MATHERR_HEADER ); | |||
break_handler(); | |||
return FALSE; | |||
} | |||
#if COMMON_CMDS | |||
/*************************************************************** | |||
FUNCTION: bwb_edit() | |||
DESCRIPTION: This function implements the BASIC EDIT | |||
program by shelling out to a default editor | |||
specified by the variable BWB.EDITOR$. | |||
SYNTAX: EDIT | |||
***************************************************************/ | |||
#if ANSI_C | |||
struct bwb_line * | |||
bwb_edit( struct bwb_line *l ) | |||
#else | |||
struct bwb_line * | |||
bwb_edit( l ) | |||
struct bwb_line *l; | |||
#endif | |||
{ | |||
char tbuf[ MAXSTRINGSIZE + 1 ]; | |||
char edname[ MAXSTRINGSIZE + 1 ]; | |||
struct bwb_variable *ed; | |||
FILE *loadfile; | |||
ed = var_find( DEFVNAME_EDITOR ); | |||
str_btoc( edname, var_getsval( ed )); | |||
sprintf( tbuf, "%s %s", edname, CURTASK progfile ); | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in bwb_edit(): command line <%s>", tbuf ); | |||
bwb_debug( bwb_ebuf ); | |||
#else | |||
system( tbuf ); | |||
#endif | |||
/* clear current contents */ | |||
bwb_new( l ); | |||
/* open edited file for read */ | |||
if ( ( loadfile = fopen( CURTASK progfile, "r" )) == NULL ) | |||
{ | |||
sprintf( bwb_ebuf, err_openfile, CURTASK progfile ); | |||
bwb_error( bwb_ebuf ); | |||
return bwb_zline( l ); | |||
} | |||
/* and (re)load the file into memory */ | |||
bwb_fload( loadfile ); | |||
return bwb_zline( l ); | |||
} | |||
/*************************************************************** | |||
FUNCTION: bwb_files() | |||
DESCRIPTION: This function implements the BASIC FILES | |||
command, in this case by shelling out to | |||
a directory listing program or command | |||
specified in the variable BWB.FILES$. | |||
SYNTAX: FILES filespec$ | |||
***************************************************************/ | |||
#if ANSI_C | |||
struct bwb_line * | |||
bwb_files( struct bwb_line *l ) | |||
#else | |||
struct bwb_line * | |||
bwb_files( l ) | |||
struct bwb_line *l; | |||
#endif | |||
{ | |||
char tbuf[ MAXVARNAMESIZE + 1 ]; | |||
char finame[ MAXVARNAMESIZE + 1 ]; | |||
char argument[ MAXVARNAMESIZE + 1 ]; | |||
struct bwb_variable *fi; | |||
struct exp_ese *e; | |||
fi = var_find( DEFVNAME_FILES ); | |||
str_btoc( finame, var_getsval( fi )); | |||
/* get argument */ | |||
adv_ws( l->buffer, &( l->position )); | |||
switch( l->buffer[ l->position ] ) | |||
{ | |||
case '\0': | |||
case '\r': | |||
case '\n': | |||
argument[ 0 ] = '\0'; | |||
break; | |||
default: | |||
e = bwb_exp( l->buffer, FALSE, &( l->position ) ); | |||
if ( e->type != STRING ) | |||
{ | |||
bwb_error( err_mismatch ); | |||
return bwb_zline( l ); | |||
} | |||
str_btoc( argument, exp_getsval( e ) ); | |||
break; | |||
} | |||
sprintf( tbuf, "%s %s", finame, argument ); | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in bwb_files(): command line <%s>", tbuf ); | |||
bwb_debug( bwb_ebuf ); | |||
#else | |||
system( tbuf ); | |||
#endif | |||
return bwb_zline( l ); | |||
} | |||
#endif /* COMMON_CMDS */ | |||
@@ -0,0 +1,43 @@ | |||
/*************************************************************** | |||
bwx_tty.h Header file for TTY-style hardware | |||
implementation of bwBASIC | |||
This file may be used as a template | |||
for developing more sophisticated | |||
hardware implementations | |||
Copyright (c) 1993, Ted A. Campbell | |||
Bywater Software | |||
email: tcamp@delphi.com | |||
Copyright and Permissions Information: | |||
All U.S. and international rights are claimed by the author, | |||
Ted A. Campbell. | |||
This software is released under the terms of the GNU General | |||
Public License (GPL), which is distributed with this software | |||
in the file "COPYING". The GPL specifies the terms under | |||
which users may copy and use the software in this distribution. | |||
A separate license is available for commercial distribution, | |||
for information on which you should contact the author. | |||
***************************************************************/ | |||
#define IMP_IDSTRING "TTY" /* unique ID string for this implementation */ | |||
/* Definitions indicating which commands and functions are implemented */ | |||
#define IMP_FNCINKEY 0 /* 0 if INKEY$ is not implemented, 1 if it is */ | |||
#define IMP_CMDCLS 0 /* 0 if CLS is not implemented, 1 if it is */ | |||
#define IMP_CMDLOC 0 /* 0 if LOCATE is not implemented, 1 if it is */ | |||
#define IMP_CMDCOLOR 0 /* 0 if COLOR is not implemented, 1 if it is */ | |||
#define UNIX_CMDS FALSE | |||
#define MKDIR_ONE_ARG FALSE /* TRUE if your mkdir has but one argument; | |||
FALSE if it has two */ | |||
#define PERMISSIONS 493 /* permissions to set in Unix-type system */ | |||
@@ -0,0 +1,303 @@ | |||
#!/bin/sh | |||
# Guess values for system-dependent variables and create Makefiles. | |||
# Generated automatically using autoconf. | |||
# Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc. | |||
# This program is free software; you can redistribute it and/or modify | |||
# it under the terms of the GNU General Public License as published by | |||
# the Free Software Foundation; either version 2, or (at your option) | |||
# any later version. | |||
# This program is distributed in the hope that it will be useful, | |||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
# GNU General Public License for more details. | |||
# You should have received a copy of the GNU General Public License | |||
# along with this program; if not, write to the Free Software | |||
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
# Usage: configure [--srcdir=DIR] [--host=HOST] [--gas] [--nfp] [--no-create] | |||
# [--prefix=PREFIX] [--exec-prefix=PREFIX] [--with-PACKAGE] [TARGET] | |||
# Ignores all args except --srcdir, --prefix, --exec-prefix, --no-create, and | |||
# --with-PACKAGE unless this script has special code to handle it. | |||
for arg | |||
do | |||
# Handle --exec-prefix with a space before the argument. | |||
if test x$next_exec_prefix = xyes; then exec_prefix=$arg; next_exec_prefix= | |||
# Handle --host with a space before the argument. | |||
elif test x$next_host = xyes; then next_host= | |||
# Handle --prefix with a space before the argument. | |||
elif test x$next_prefix = xyes; then prefix=$arg; next_prefix= | |||
# Handle --srcdir with a space before the argument. | |||
elif test x$next_srcdir = xyes; then srcdir=$arg; next_srcdir= | |||
else | |||
case $arg in | |||
# For backward compatibility, also recognize exact --exec_prefix. | |||
-exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* | --exec=* | --exe=* | --ex=* | --e=*) | |||
exec_prefix=`echo $arg | sed 's/[-a-z_]*=//'` ;; | |||
-exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- | --exec | --exe | --ex | --e) | |||
next_exec_prefix=yes ;; | |||
-gas | --gas | --ga | --g) ;; | |||
-host=* | --host=* | --hos=* | --ho=* | --h=*) ;; | |||
-host | --host | --hos | --ho | --h) | |||
next_host=yes ;; | |||
-nfp | --nfp | --nf) ;; | |||
-no-create | --no-create | --no-creat | --no-crea | --no-cre | --no-cr | --no-c | --no- | --no) | |||
no_create=1 ;; | |||
-prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) | |||
prefix=`echo $arg | sed 's/[-a-z_]*=//'` ;; | |||
-prefix | --prefix | --prefi | --pref | --pre | --pr | --p) | |||
next_prefix=yes ;; | |||
-srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=* | --s=*) | |||
srcdir=`echo $arg | sed 's/[-a-z_]*=//'` ;; | |||
-srcdir | --srcdir | --srcdi | --srcd | --src | --sr | --s) | |||
next_srcdir=yes ;; | |||
-with-* | --with-*) | |||
package=`echo $arg|sed 's/-*with-//'` | |||
# Delete all the valid chars; see if any are left. | |||
if test -n "`echo $package|sed 's/[-a-zA-Z0-9_]*//g'`"; then | |||
echo "configure: $package: invalid package name" >&2; exit 1 | |||
fi | |||
eval "with_`echo $package|sed s/-/_/g`=1" ;; | |||
*) ;; | |||
esac | |||
fi | |||
done | |||
trap 'rm -f conftest* core; exit 1' 1 3 15 | |||
rm -f conftest* | |||
compile='${CC-cc} $DEFS conftest.c -o conftest $LIBS >/dev/null 2>&1' | |||
# A filename unique to this package, relative to the directory that | |||
# configure is in, which we can look for to find out if srcdir is correct. | |||
unique_file=bwb_cmd.c | |||
# Find the source files, if location was not specified. | |||
if test -z "$srcdir"; then | |||
srcdirdefaulted=yes | |||
# Try the directory containing this script, then `..'. | |||
prog=$0 | |||
confdir=`echo $prog|sed 's%/[^/][^/]*$%%'` | |||
test "X$confdir" = "X$prog" && confdir=. | |||
srcdir=$confdir | |||
if test ! -r $srcdir/$unique_file; then | |||
srcdir=.. | |||
fi | |||
fi | |||
if test ! -r $srcdir/$unique_file; then | |||
if test x$srcdirdefaulted = xyes; then | |||
echo "configure: Can not find sources in \`${confdir}' or \`..'." 1>&2 | |||
else | |||
echo "configure: Can not find sources in \`${srcdir}'." 1>&2 | |||
fi | |||
exit 1 | |||
fi | |||
# Preserve a srcdir of `.' to avoid automounter screwups with pwd. | |||
# But we can't avoid them for `..', to make subdirectories work. | |||
case $srcdir in | |||
.|/*|~*) ;; | |||
*) srcdir=`cd $srcdir; pwd` ;; # Make relative path absolute. | |||
esac | |||
if test -z "$CC"; then | |||
echo checking for gcc | |||
saveifs="$IFS"; IFS="${IFS}:" | |||
for dir in $PATH; do | |||
test -z "$dir" && dir=. | |||
if test -f $dir/gcc; then | |||
CC="gcc" | |||
break | |||
fi | |||
done | |||
IFS="$saveifs" | |||
fi | |||
test -z "$CC" && CC="cc" | |||
# Find out if we are using GNU C, under whatever name. | |||
cat > conftest.c <<EOF | |||
#ifdef __GNUC__ | |||
yes | |||
#endif | |||
EOF | |||
${CC-cc} -E conftest.c > conftest.out 2>&1 | |||
if egrep yes conftest.out >/dev/null 2>&1; then | |||
GCC=1 # For later tests. | |||
fi | |||
rm -f conftest* | |||
echo checking how to run the C preprocessor | |||
if test -z "$CPP"; then | |||
CPP='${CC-cc} -E' | |||
cat > conftest.c <<EOF | |||
#include <stdio.h> | |||
EOF | |||
err=`eval "$CPP $DEFS conftest.c 2>&1 >/dev/null"` | |||
if test -z "$err"; then | |||
: | |||
else | |||
CPP=/lib/cpp | |||
fi | |||
rm -f conftest* | |||
fi | |||
# Make sure to not get the incompatible SysV /etc/install and | |||
# /usr/sbin/install, which might be in PATH before a BSD-like install, | |||
# or the SunOS /usr/etc/install directory, or the AIX /bin/install, | |||
# or the AFS install, which mishandles nonexistent args. (Sigh.) | |||
if test -z "$INSTALL"; then | |||
echo checking for install | |||
saveifs="$IFS"; IFS="${IFS}:" | |||
for dir in $PATH; do | |||
test -z "$dir" && dir=. | |||
case $dir in | |||
/etc|/usr/sbin|/usr/etc|/usr/afsws/bin) ;; | |||
*) | |||
if test -f $dir/install; then | |||
if grep dspmsg $dir/install >/dev/null 2>&1; then | |||
: # AIX | |||
else | |||
INSTALL="$dir/install -c" | |||
INSTALL_PROGRAM='$(INSTALL)' | |||
INSTALL_DATA='$(INSTALL) -m 644' | |||
break | |||
fi | |||
fi | |||
;; | |||
esac | |||
done | |||
IFS="$saveifs" | |||
fi | |||
INSTALL=${INSTALL-cp} | |||
INSTALL_PROGRAM=${INSTALL_PROGRAM-'$(INSTALL)'} | |||
INSTALL_DATA=${INSTALL_DATA-'$(INSTALL)'} | |||
echo checking for size_t in sys/types.h | |||
echo '#include <sys/types.h>' > conftest.c | |||
eval "$CPP $DEFS conftest.c > conftest.out 2>&1" | |||
if egrep "size_t" conftest.out >/dev/null 2>&1; then | |||
: | |||
else | |||
DEFS="$DEFS -Dsize_t=unsigned" | |||
fi | |||
rm -f conftest* | |||
echo checking for string.h | |||
cat > conftest.c <<EOF | |||
#include <string.h> | |||
EOF | |||
err=`eval "$CPP $DEFS conftest.c 2>&1 >/dev/null"` | |||
if test -z "$err"; then | |||
DEFS="$DEFS -DHAVE_STRING=1" | |||
fi | |||
rm -f conftest* | |||
echo checking for stdlib.h | |||
cat > conftest.c <<EOF | |||
#include <stdlib.h> | |||
EOF | |||
err=`eval "$CPP $DEFS conftest.c 2>&1 >/dev/null"` | |||
if test -z "$err"; then | |||
DEFS="$DEFS -DHAVE_STDLIB=1" | |||
fi | |||
rm -f conftest* | |||
echo checking for raise | |||
cat > conftest.c <<EOF | |||
#include <sys/types.h> | |||
#include <signal.h> | |||
main() { exit(0); } | |||
t() { raise(1); } | |||
EOF | |||
if eval $compile; then | |||
DEFS="$DEFS -DHAVE_RAISE=1" | |||
fi | |||
rm -f conftest* | |||
if test -n "$prefix"; then | |||
test -z "$exec_prefix" && exec_prefix='${prefix}' | |||
prsub="s%^prefix\\([ ]*\\)=\\([ ]*\\).*$%prefix\\1=\\2$prefix%" | |||
fi | |||
if test -n "$exec_prefix"; then | |||
prsub="$prsub | |||
s%^exec_prefix\\([ ]*\\)=\\([ ]*\\).*$%\ | |||
exec_prefix\\1=\\2$exec_prefix%" | |||
fi | |||
trap 'rm -f config.status; exit 1' 1 3 15 | |||
echo creating config.status | |||
rm -f config.status | |||
cat > config.status <<EOF | |||
#!/bin/sh | |||
# Generated automatically by configure. | |||
# Run this file to recreate the current configuration. | |||
# This directory was configured as follows, | |||
# on host `(hostname || uname -n) 2>/dev/null`: | |||
# | |||
# $0 $* | |||
for arg | |||
do | |||
case "\$arg" in | |||
-recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) | |||
exec /bin/sh $0 $* ;; | |||
*) echo "Usage: config.status --recheck" 2>&1; exit 1 ;; | |||
esac | |||
done | |||
trap 'rm -f Makefile; exit 1' 1 3 15 | |||
CC='$CC' | |||
CPP='$CPP' | |||
INSTALL='$INSTALL' | |||
INSTALL_PROGRAM='$INSTALL_PROGRAM' | |||
INSTALL_DATA='$INSTALL_DATA' | |||
LIBS='$LIBS' | |||
srcdir='$srcdir' | |||
DEFS='$DEFS' | |||
prefix='$prefix' | |||
exec_prefix='$exec_prefix' | |||
prsub='$prsub' | |||
EOF | |||
cat >> config.status <<\EOF | |||
top_srcdir=$srcdir | |||
for file in .. Makefile; do if [ "x$file" != "x.." ]; then | |||
srcdir=$top_srcdir | |||
# Remove last slash and all that follows it. Not all systems have dirname. | |||
dir=`echo $file|sed 's%/[^/][^/]*$%%'` | |||
if test "$dir" != "$file"; then | |||
test "$top_srcdir" != . && srcdir=$top_srcdir/$dir | |||
test ! -d $dir && mkdir $dir | |||
fi | |||
echo creating $file | |||
rm -f $file | |||
echo "# Generated automatically from `echo $file|sed 's|.*/||'`.in by configure." > $file | |||
sed -e " | |||
$prsub | |||
s%@CC@%$CC%g | |||
s%@CPP@%$CPP%g | |||
s%@INSTALL@%$INSTALL%g | |||
s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g | |||
s%@INSTALL_DATA@%$INSTALL_DATA%g | |||
s%@LIBS@%$LIBS%g | |||
s%@srcdir@%$srcdir%g | |||
s%@DEFS@%$DEFS% | |||
" $top_srcdir/${file}.in >> $file | |||
fi; done | |||
EOF | |||
chmod +x config.status | |||
test -n "$no_create" || ./config.status | |||
@@ -0,0 +1,12 @@ | |||
dnl Process this file with autoconf to produce a configure script. | |||
AC_INIT(bwb_cmd.c) | |||
AC_PROG_CC | |||
AC_PROG_CPP | |||
AC_PROG_INSTALL | |||
AC_SIZE_T | |||
AC_HEADER_CHECK(string.h, AC_DEFINE(HAVE_STRING)) | |||
AC_HEADER_CHECK(stdlib.h, AC_DEFINE(HAVE_STDLIB)) | |||
AC_COMPILE_CHECK(raise, [#include <sys/types.h> | |||
#include <signal.h>], [raise(1);], AC_DEFINE(HAVE_RAISE)) | |||
AC_OUTPUT(Makefile) | |||
@@ -0,0 +1,63 @@ | |||
# Microsoft QuickC Makefile for Bywater BASIC Interpreter | |||
# | |||
# This makefile is for line-oriented QuickC only, not for | |||
# the QuickC integrated environment. To make the program: | |||
# type "nmake -f makefile.qcl". | |||
# | |||
# To implement the bwx_iqc implementation (using specific | |||
# features for the IBM PC and compatibles), chainge each | |||
# instance of "bwx_tty" to "bwx_iqc". | |||
# | |||
PROJ= bwbasic | |||
CC= qcl | |||
# | |||
# These are the normal flags I used to compile bwBASIC: | |||
# | |||
CFLAGS= -O -AL -W3 -Za -DMSDOS | |||
# | |||
# The following flags can be used for debugging: | |||
# | |||
#CFLAGS= -Od -AL -W3 -Za -Zr -Zi -DMSDOS | |||
LFLAGS= /NOE /ST:8192 | |||
OFILES= bwbasic.obj bwb_int.obj bwb_tbl.obj bwb_cmd.obj bwb_prn.obj\ | |||
bwb_exp.obj bwb_var.obj bwb_inp.obj bwb_fnc.obj bwb_cnd.obj\ | |||
bwb_ops.obj bwb_dio.obj bwb_str.obj bwb_elx.obj bwb_mth.obj\ | |||
bwb_stc.obj bwb_par.obj bwx_tty.obj | |||
HFILES= bwbasic.h bwb_mes.h | |||
all: $(PROJ).exe | |||
$(OFILES): $(HFILES) makefile.qcl | |||
$(PROJ).exe: $(OFILES) | |||
echo >NUL @<<$(PROJ).crf | |||
bwbasic.obj + | |||
bwb_cmd.obj + | |||
bwb_cnd.obj + | |||
bwb_fnc.obj + | |||
bwb_inp.obj + | |||
bwb_int.obj + | |||
bwb_prn.obj + | |||
bwb_tbl.obj + | |||
bwb_var.obj + | |||
bwb_exp.obj + | |||
bwb_ops.obj + | |||
bwb_dio.obj + | |||
bwb_str.obj + | |||
bwb_elx.obj + | |||
bwb_mth.obj + | |||
bwb_stc.obj + | |||
bwb_par.obj + | |||
bwx_tty.obj + | |||
$(OBJS_EXT) | |||
$(PROJ).exe | |||
$(LIBS_EXT); | |||
<< | |||
link $(LFLAGS) @$(PROJ).crf | |||
erase $(PROJ).crf | |||