Browse Source

v2.10

tags/v2.10
Jon Foster 2 years ago
commit
266be03f43
77 changed files with 32778 additions and 0 deletions
  1. +12
    -0
      .gitattributes
  2. +3
    -0
      .gitignore
  3. +342
    -0
      COPYING
  4. +158
    -0
      INSTALL
  5. +101
    -0
      Makefile.in
  6. +189
    -0
      README
  7. +2217
    -0
      bwb_cmd.c
  8. +2409
    -0
      bwb_cnd.c
  9. +1807
    -0
      bwb_dio.c
  10. +1199
    -0
      bwb_elx.c
  11. +1469
    -0
      bwb_exp.c
  12. +1910
    -0
      bwb_fnc.c
  13. +1440
    -0
      bwb_inp.c
  14. +955
    -0
      bwb_int.c
  15. +474
    -0
      bwb_mes.h
  16. +2017
    -0
      bwb_mth.c
  17. +1932
    -0
      bwb_ops.c
  18. +110
    -0
      bwb_par.c
  19. +1703
    -0
      bwb_prn.c
  20. +2278
    -0
      bwb_stc.c
  21. +355
    -0
      bwb_str.c
  22. +335
    -0
      bwb_tbl.c
  23. +5
    -0
      bwb_tcc.c
  24. +2236
    -0
      bwb_var.c
  25. +1450
    -0
      bwbasic.c
  26. +1880
    -0
      bwbasic.doc
  27. +1392
    -0
      bwbasic.h
  28. +85
    -0
      bwbasic.mak
  29. +5
    -0
      bwbtest/abs.bas
  30. +3
    -0
      bwbtest/assign.bas
  31. +34
    -0
      bwbtest/callfunc.bas
  32. +32
    -0
      bwbtest/callsub.bas
  33. +7
    -0
      bwbtest/chain1.bas
  34. +4
    -0
      bwbtest/chain2.bas
  35. +14
    -0
      bwbtest/dataread.bas
  36. +7
    -0
      bwbtest/deffn.bas
  37. +6
    -0
      bwbtest/dim.bas
  38. +7
    -0
      bwbtest/doloop.bas
  39. +13
    -0
      bwbtest/dowhile.bas
  40. +26
    -0
      bwbtest/elseif.bas
  41. +6
    -0
      bwbtest/end.bas
  42. +3
    -0
      bwbtest/err.bas
  43. +9
    -0
      bwbtest/fncallfn.bas
  44. +13
    -0
      bwbtest/fornext.bas
  45. +43
    -0
      bwbtest/function.bas
  46. +54
    -0
      bwbtest/gosub.bas
  47. +22
    -0
      bwbtest/gotolabl.bas
  48. +6
    -0
      bwbtest/ifline.bas
  49. +43
    -0
      bwbtest/index.txt
  50. +7
    -0
      bwbtest/input.bas
  51. +5
    -0
      bwbtest/lof.bas
  52. +6
    -0
      bwbtest/loopuntl.bas
  53. +17
    -0
      bwbtest/main.bas
  54. +16
    -0
      bwbtest/mlifthen.bas
  55. +14
    -0
      bwbtest/on.bas
  56. +12
    -0
      bwbtest/onerr.bas
  57. +12
    -0
      bwbtest/onerrlbl.bas
  58. +15
    -0
      bwbtest/ongosub.bas
  59. +12
    -0
      bwbtest/opentest.bas
  60. +8
    -0
      bwbtest/option.bas
  61. +17
    -0
      bwbtest/pascaltr.bas
  62. +22
    -0
      bwbtest/putget.bas
  63. +13
    -0
      bwbtest/random.bas
  64. +31
    -0
      bwbtest/selcase.bas
  65. +15
    -0
      bwbtest/snglfunc.bas
  66. +6
    -0
      bwbtest/stop.bas
  67. +10
    -0
      bwbtest/term.bas
  68. +13
    -0
      bwbtest/whilwend.bas
  69. +5
    -0
      bwbtest/width.bas
  70. +20
    -0
      bwbtest/writeinp.bas
  71. +704
    -0
      bwx_iqc.c
  72. +40
    -0
      bwx_iqc.h
  73. +517
    -0
      bwx_tty.c
  74. +43
    -0
      bwx_tty.h
  75. +303
    -0
      configur
  76. +12
    -0
      configur.in
  77. +63
    -0
      makefile.qcl

+ 12
- 0
.gitattributes View File

@@ -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

+ 3
- 0
.gitignore View File

@@ -0,0 +1,3 @@
*.o
/bwbasic
/renum

+ 342
- 0
COPYING View File

@@ -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.



+ 158
- 0
INSTALL View File

@@ -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.

+ 101
- 0
Makefile.in View File

@@ -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:


+ 189
- 0
README View File

@@ -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 ]....

+ 2217
- 0
bwb_cmd.c
File diff suppressed because it is too large
View File


+ 2409
- 0
bwb_cnd.c
File diff suppressed because it is too large
View File


+ 1807
- 0
bwb_dio.c
File diff suppressed because it is too large
View File


+ 1199
- 0
bwb_elx.c
File diff suppressed because it is too large
View File


+ 1469
- 0
bwb_exp.c
File diff suppressed because it is too large
View File


+ 1910
- 0
bwb_fnc.c
File diff suppressed because it is too large
View File


+ 1440
- 0
bwb_inp.c
File diff suppressed because it is too large
View File


+ 955
- 0
bwb_int.c View File

@@ -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;
}

}



+ 474
- 0
bwb_mes.h View File

@@ -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[];





+ 2017
- 0
bwb_mth.c
File diff suppressed because it is too large
View File


+ 1932
- 0
bwb_ops.c
File diff suppressed because it is too large
View File


+ 110
- 0
bwb_par.c View File

@@ -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




+ 1703
- 0
bwb_prn.c
File diff suppressed because it is too large
View File


+ 2278
- 0
bwb_stc.c
File diff suppressed because it is too large
View File


+ 355
- 0
bwb_str.c View File

@@ -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 );
}





+ 335
- 0
bwb_tbl.c View File

@@ -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
};




+ 5
- 0
bwb_tcc.c View File

@@ -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;


+ 2236
- 0
bwb_var.c
File diff suppressed because it is too large
View File


+ 1450
- 0
bwbasic.c
File diff suppressed because it is too large
View File


+ 1880
- 0
bwbasic.doc
File diff suppressed because it is too large
View File


+ 1392
- 0
bwbasic.h
File diff suppressed because it is too large
View File


+ 85
- 0
bwbasic.mak View File

@@ -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)


+ 5
- 0
bwbtest/abs.bas View File

@@ -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?"

+ 3
- 0
bwbtest/assign.bas View File

@@ -0,0 +1,3 @@
10 Print "TEST.BAS -- TEST"
20 X=7
30 print "X is ";X

+ 34
- 0
bwbtest/callfunc.bas View File

@@ -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."
Print
testvar = 17

x = TestFnc( 5, "Hello", testvar )

Print
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

+ 32
- 0
bwbtest/callsub.bas View File

@@ -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."
Print
testvar = 17

Call TestSub 5, "Hello", testvar

Print
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


+ 7
- 0
bwbtest/chain1.bas View File

@@ -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"

+ 4
- 0
bwbtest/chain2.bas View File

@@ -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."

+ 14
- 0
bwbtest/dataread.bas View File

@@ -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

+ 7
- 0
bwbtest/deffn.bas View File

@@ -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

+ 6
- 0
bwbtest/dim.bas View File

@@ -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

+ 7
- 0
bwbtest/doloop.bas View File

@@ -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"

+ 13
- 0
bwbtest/dowhile.bas View File

@@ -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"

+ 26
- 0
bwbtest/elseif.bas View File

@@ -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
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."

+ 6
- 0
bwbtest/end.bas View File

@@ -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

+ 3
- 0
bwbtest/err.bas View File

@@ -0,0 +1,3 @@
10 dim n(5)
20 print n(7)
30 end

+ 9
- 0
bwbtest/fncallfn.bas View File

@@ -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

+ 13
- 0
bwbtest/fornext.bas View File

@@ -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

+ 43
- 0
bwbtest/function.bas View File

@@ -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))

+ 54
- 0
bwbtest/gosub.bas View File

@@ -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

+ 22
- 0
bwbtest/gotolabl.bas View File

@@ -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

+ 6
- 0
bwbtest/ifline.bas View File

@@ -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

+ 43
- 0
bwbtest/index.txt View File

@@ -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


+ 7
- 0
bwbtest/input.bas View File

@@ -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

+ 5
- 0
bwbtest/lof.bas View File

@@ -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

+ 6
- 0
bwbtest/loopuntl.bas View File

@@ -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

+ 17
- 0
bwbtest/main.bas View File

@@ -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



+ 16
- 0
bwbtest/mlifthen.bas View File

@@ -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."

+ 14
- 0
bwbtest/on.bas View File

@@ -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

+ 12
- 0
bwbtest/onerr.bas View File

@@ -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

+ 12
- 0
bwbtest/onerrlbl.bas View File

@@ -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

+ 15
- 0
bwbtest/ongosub.bas View File

@@ -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

+ 12
- 0
bwbtest/opentest.bas View File

@@ -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

+ 8
- 0
bwbtest/option.bas View File

@@ -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

+ 17
- 0
bwbtest/pascaltr.bas View File

@@ -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


+ 22
- 0
bwbtest/putget.bas View File

@@ -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

+ 13
- 0
bwbtest/random.bas View File

@@ -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."

+ 31
- 0
bwbtest/selcase.bas View File

@@ -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



+ 15
- 0
bwbtest/snglfunc.bas View File

@@ -0,0 +1,15 @@

rem ----------------------------------------------------
rem SnglFunc.BAS
rem ----------------------------------------------------

Print "SnglFunc.BAS -- Test Single-Line User-defined Function Statement"
Print

Def Sum( x, y ) = x + y

Print
Print "The sum of 6 and 4 is "; Sum( 6, 4 )

Print "Did it work properly?"
End

+ 6
- 0
bwbtest/stop.bas View File

@@ -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

+ 10
- 0
bwbtest/term.bas View File

@@ -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

+ 13
- 0
bwbtest/whilwend.bas View File

@@ -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"

+ 5
- 0
bwbtest/width.bas View File

@@ -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"

+ 20
- 0
bwbtest/writeinp.bas View File

@@ -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

+ 704
- 0
bwx_iqc.c View File

@@ -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 */


+ 40
- 0
bwx_iqc.h View File

@@ -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 */


+ 517
- 0
bwx_tty.c View File

@@ -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 */


+ 43
- 0
bwx_tty.h View File

@@ -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 */


+ 303
- 0
configur View File

@@ -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



+ 12
- 0
configur.in View File

@@ -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)


+ 63
- 0
makefile.qcl View File

@@ -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


Loading…
Cancel
Save