home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-11-03 | 59.4 KB | 2,180 lines |
- Newsgroups: comp.sources.misc
- From: tcamp@acpub.duke.edu (Ted A. Campbell)
- Subject: v33i037: bwbasic - Bywater BASIC interpreter version 1.10, Part01/11
- Message-ID: <csm-v33i037=bwbasic.214446@sparky.IMD.Sterling.COM>
- X-Md4-Signature: 607d3ea8135051cc3b32a8ed4fa483ae
- Date: Thu, 5 Nov 1992 03:46:11 GMT
- Approved: kent@sparky.imd.sterling.com
-
- Submitted-by: tcamp@acpub.duke.edu (Ted A. Campbell)
- Posting-number: Volume 33, Issue 37
- Archive-name: bwbasic/part01
- Environment: ANSI-C
-
- Bywater Software Announces
- the First Public Release of
-
- Bywater BASIC Interpreter/Shell, version 1.10
- ---------------------------------------------
-
- Copyright (c) 1992, Ted A. Campbell
- for bwBASIC version 1.10, 1 November 1992
-
- DESCRIPTION:
-
- The Bywater BASIC Interpreter (bwBASIC) implements a large
- superset of the ANSI Standard for Minimal BASIC (X3.60-1978)
- implemented in ANSI C, and offers a simple interactive environ-
- ment including some shell program facilities as an extension of
- BASIC. The interpreter has been compiled successfully on a range
- of ANSI C compilers on varying platforms with no alterations
- to source code necessary.
-
-
- OBTAINING THE SOURCE CODE:
-
- The source code for bwBASIC 1.10 will be posted to network news
- groups and is available immediately by anonymous ftp. To obtain
- the source code, ftp to site duke.cs.duke.edu, cd to /pub/bywater
- and get the appropriate files. These are as follows:
-
- bwb110.zip Source code in ZIP compressed format, with text lines
- concluded with CR-LF. This is the appropriate version
- for DOS-based computers.
-
- bwb110.tar.Z Tar'd and compressed source code with text lines con-
- cluded with LF only. This is the appropriate version
- for Unix-based computers.
-
- See the READ.ME for more information.
-
- COMMUNICATIONS:
-
- Ted A. Campbell
- Bywater Software
- P.O. Box 4023
- Duke Station
- Durham, NC 27706
- USA
-
- email: tcamp@acpub.duke.edu
- ------------------------------------
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then feed it
- # into a shell via "sh file" or similar. To overwrite existing files,
- # type "sh file -c".
- # Contents: READ.ME bwb_fnc.c
- # Wrapped by kent@sparky on Wed Nov 4 21:34:21 1992
- PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
- echo If this archive is complete, you will see the following message:
- echo ' "shar: End of archive 1 (of 11)."'
- if test -f 'READ.ME' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'READ.ME'\"
- else
- echo shar: Extracting \"'READ.ME'\" \(4568 characters\)
- sed "s/^X//" >'READ.ME' <<'END_OF_FILE'
- X
- X
- X Bywater Software Announces
- X the First Public Release of
- X
- X
- X Bywater BASIC Interpreter/Shell, version 1.10
- X ---------------------------------------------
- X
- X Copyright (c) 1992, Ted A. Campbell
- X for bwBASIC version 1.10, 1 November 1992
- X
- X
- X
- XDESCRIPTION:
- X
- X The Bywater BASIC Interpreter (bwBASIC) implements a large
- X superset of the ANSI Standard for Minimal BASIC (X3.60-1978)
- X implemented in ANSI C, and offers a simple interactive environ-
- X ment including some shell program facilities as an extension of
- X BASIC. The interpreter has been compiled successfully on a range
- X of ANSI C compilers on varying platforms with no alterations
- X to source code necessary.
- X
- X
- XOBTAINING THE SOURCE CODE:
- X
- X The source code for bwBASIC 1.10 will be posted to network news
- X groups and is available immediately by anonymous ftp. To obtain
- X the source code, ftp to site duke.cs.duke.edu, cd to /pub/bywater
- X and get the appropriate files. These are as follows:
- X
- X bwb110.zip Source code in ZIP compressed format, with text lines
- X concluded with CR-LF. This is the appropriate version
- X for DOS-based computers.
- X
- X bwb110.tar.Z Tar'd and compressed source code with text lines con-
- X cluded with LF only. This is the appropriate version
- X for Unix-based computers.
- X
- X
- XCOMMUNICATIONS:
- X
- X Ted A. Campbell
- X Bywater Software
- X P.O. Box 4023
- X Duke Station
- X Durham, NC 27706
- X USA
- X
- X email: tcamp@acpub.duke.edu
- X
- X
- XA LIST OF BASIC COMMANDS AND FUNCTIONS IMPLEMENTED in bwBASIC 1.10:
- X
- X ABS( number )
- X ASC( string$ )
- X ATN( number )
- X CHAIN [MERGE] file-name [, line-number] [, ALL]
- X CHR$( number )
- X CINT( number )
- X CLEAR
- X CLOSE [[#]file-number]...
- X COMMON variable [, variable...]
- X COS( number )
- X CSNG( number )
- X CVD( string$ )
- X CVI( string$ )
- X CVS( string$ )
- X DATA constant[,constant]...
- X DATE$
- X DEF FNname(arg...)] = expression
- X DEFDBL letter[-letter](, letter[-letter])...
- X DEFINT letter[-letter](, letter[-letter])...
- X DEFSNG letter[-letter](, letter[-letter])...
- X DEFSTR letter[-letter](, letter[-letter])...
- X DELETE line[-line]
- X DIM variable(elements...)[variable(elements...)]...
- X END
- X ENVIRON variable-string = string
- X ENVIRON$( variable-string )
- X EOF( device-number )
- X ERASE variable[, variable]...
- X ERL
- X ERR
- X ERROR number
- X EXP( number )
- X FIELD [#] device-number, number AS string-variable [, number AS string-variable...]
- X FOR counter = start TO finish [STEP increment]
- X GET [#] device-number [, record-number]
- X GOSUB line
- X GOTO line
- X HEX$( number )
- X IF expression THEN statement [ELSE statement]
- X INPUT [# device-number]|[;]["prompt string";]list of variables
- X INSTR( [start-position,] string-searched$, string-pattern$ )
- X INT( number )
- X KILL file-name
- X LEFT$( string$, number-of-spaces )
- X LEN( string$ )
- X LET variable = expression
- X LINE INPUT [[#] device-number,]["prompt string";] string-variable$
- X LIST line[-line]
- X LOAD file-name
- X LOC( device-number )
- X LOF( device-number )
- X LOG( number )
- X LSET string-variable$ = expression
- X MERGE file-name
- X MID$( string$, start-position-in-string[, number-of-spaces ] )
- X MKD$( double-value# )
- X MKI$( integer-value% )
- X MKS$( single-value! )
- X NAME old-file-name AS new-file-name
- X NEW
- X NEXT counter
- X OCT$( number )
- X ON variable GOTO|GOSUB line[,line,line,...]
- X ON ERROR GOSUB line
- X OPEN O|I|R, [#]device-number, file-name [,record length]
- X file-name FOR INPUT|OUTPUT|APPEND AS [#]device-number [LEN = record-length]
- X OPTION BASE number
- X POS
- X PRINT [# device-number,][USING format-string$;] expressions...
- X PUT [#] device-number [, record-number]
- X RANDOMIZE number
- X READ variable[, variable]...
- X REM string
- X RESTORE line
- X RETURN
- X RIGHT$( string$, number-of-spaces )
- X RND( number )
- X RSET string-variable$ = expression
- X RUN [line][file-name]
- X SAVE file-name
- X SGN( number )
- X SIN( number )
- X SPACE$( number )
- X SPC( number )
- X SQR( number )
- X STOP
- X STR$( number )
- X STRING$( number, ascii-value|string$ )
- X SWAP variable, variable
- X SYSTEM
- X TAB( number )
- X TAN( number )
- X TIME$
- X TIMER
- X TROFF
- X TRON
- X VAL( string$ )
- X WEND
- X WHILE expression
- X WIDTH [# device-number,] number
- X WRITE [# device-number,] element [, element ]....
- X
- X If DIRECTORY_CMDS is set to TRUE when the program is compiled,
- X then the following commands will be available:
- X
- X CHDIR pathname
- X MKDIR pathname
- X RMDIR pathname
- X
- X
- END_OF_FILE
- if test 4568 -ne `wc -c <'READ.ME'`; then
- echo shar: \"'READ.ME'\" unpacked with wrong size!
- fi
- # end of 'READ.ME'
- fi
- if test -f 'bwb_fnc.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'bwb_fnc.c'\"
- else
- echo shar: Extracting \"'bwb_fnc.c'\" \(50459 characters\)
- sed "s/^X//" >'bwb_fnc.c' <<'END_OF_FILE'
- X/****************************************************************
- X
- X bwb_fnc.c Function Interpretation Routines
- X for Bywater BASIC Interpreter
- X
- X Copyright (c) 1992, Ted A. Campbell
- X
- X Bywater Software
- X P. O. Box 4023
- X Duke Station
- X Durham, NC 27706
- X
- X email: tcamp@acpub.duke.edu
- X
- X Copyright and Permissions Information:
- X
- X All U.S. and international copyrights are claimed by the
- X author. The author grants permission to use this code
- X and software based on it under the following conditions:
- X (a) in general, the code and software based upon it may be
- X used by individuals and by non-profit organizations; (b) it
- X may also be utilized by governmental agencies in any country,
- X with the exception of military agencies; (c) the code and/or
- X software based upon it may not be sold for a profit without
- X an explicit and specific permission from the author, except
- X that a minimal fee may be charged for media on which it is
- X copied, and for copying and handling; (d) the code must be
- X distributed in the form in which it has been released by the
- X author; and (e) the code and software based upon it may not
- X be used for illegal activities.
- X
- X****************************************************************/
- X
- X#define FSTACKSIZE 32
- X
- X#include <stdio.h>
- X#include <stdlib.h>
- X#include <ctype.h>
- X#include <string.h>
- X#include <math.h>
- X#include <time.h>
- X#include "bwbasic.h"
- X#include "bwb_mes.h"
- X
- Xstatic time_t t;
- Xstatic struct tm *lt;
- X
- Xstruct bwb_function fnc_start, fnc_end;
- X
- Xint ufsc = -1; /* user function stack counter */
- X
- Xstruct bwb_function bwb_prefuncs[ FUNCTIONS ] =
- X {
- X { "ABS", DOUBLE, 1, (struct user_fnc *) NULL, fnc_abs, (struct bwb_function *) NULL },
- X { "DATE$", STRING, 0, (struct user_fnc *) NULL, fnc_date, (struct bwb_function *) NULL },
- X { "TIME$", STRING, 0, (struct user_fnc *) NULL, fnc_time, (struct bwb_function *) NULL },
- X { "ATN", DOUBLE, 1, (struct user_fnc *) NULL, fnc_atn, (struct bwb_function *) NULL },
- X { "COS", DOUBLE, 1, (struct user_fnc *) NULL, fnc_cos, (struct bwb_function *) NULL },
- X { "LOG", DOUBLE, 1, (struct user_fnc *) NULL, fnc_log, (struct bwb_function *) NULL },
- X { "SIN", DOUBLE, 1, (struct user_fnc *) NULL, fnc_sin, (struct bwb_function *) NULL },
- X { "SQR", DOUBLE, 1, (struct user_fnc *) NULL, fnc_sqr, (struct bwb_function *) NULL },
- X { "TAN", DOUBLE, 1, (struct user_fnc *) NULL, fnc_tan, (struct bwb_function *) NULL },
- X { "SGN", DOUBLE, 1, (struct user_fnc *) NULL, fnc_sgn, (struct bwb_function *) NULL },
- X { "INT", DOUBLE, 1, (struct user_fnc *) NULL, fnc_int, (struct bwb_function *) NULL },
- X { "RND", DOUBLE, 0, (struct user_fnc *) NULL, fnc_rnd, (struct bwb_function *) NULL },
- X { "CHR$", DOUBLE, 0, (struct user_fnc *) NULL, fnc_chr, (struct bwb_function *) NULL },
- X { "TAB", STRING, 1, (struct user_fnc *) NULL, fnc_tab, (struct bwb_function *) NULL },
- X { "SPC", STRING, 1, (struct user_fnc *) NULL, fnc_spc, (struct bwb_function *) NULL },
- X { "SPACE$", STRING, 1, (struct user_fnc *) NULL, fnc_space, (struct bwb_function *) NULL },
- X { "STRING$", STRING, 1, (struct user_fnc *) NULL, fnc_string, (struct bwb_function *) NULL },
- X { "MID$", STRING, 3, (struct user_fnc *) NULL, fnc_mid, (struct bwb_function *) NULL },
- X { "LEFT$", STRING, 2, (struct user_fnc *) NULL, fnc_left, (struct bwb_function *) NULL },
- X { "RIGHT$", STRING, 2, (struct user_fnc *) NULL, fnc_right, (struct bwb_function *) NULL },
- X { "TIMER", SINGLE, 0, (struct user_fnc *) NULL, fnc_timer, (struct bwb_function *) NULL },
- X { "VAL", INTEGER, 1, (struct user_fnc *) NULL, fnc_val, (struct bwb_function *) NULL },
- X { "POS", INTEGER, 0, (struct user_fnc *) NULL, fnc_pos, (struct bwb_function *) NULL },
- X { "ERR", INTEGER, 0, (struct user_fnc *) NULL, fnc_err, (struct bwb_function *) NULL },
- X { "ERL", INTEGER, 0, (struct user_fnc *) NULL, fnc_erl, (struct bwb_function *) NULL },
- X { "LEN", INTEGER, 1, (struct user_fnc *) NULL, fnc_len, (struct bwb_function *) NULL },
- X { "LOC", INTEGER, 1, (struct user_fnc *) NULL, fnc_loc, (struct bwb_function *) NULL },
- X { "LOF", DOUBLE, 1, (struct user_fnc *) NULL, fnc_lof, (struct bwb_function *) NULL },
- X { "EOF", DOUBLE, 1, (struct user_fnc *) NULL, fnc_eof, (struct bwb_function *) NULL },
- X { "CSNG", SINGLE, 1, (struct user_fnc *) NULL, fnc_csng, (struct bwb_function *) NULL },
- X { "EXP", SINGLE, 1, (struct user_fnc *) NULL, fnc_exp, (struct bwb_function *) NULL },
- X { "INSTR", INTEGER, 1, (struct user_fnc *) NULL, fnc_instr, (struct bwb_function *) NULL },
- X { "STR$", STRING, 1, (struct user_fnc *) NULL, fnc_str, (struct bwb_function *) NULL },
- X { "HEX$", STRING, 1, (struct user_fnc *) NULL, fnc_hex, (struct bwb_function *) NULL },
- X { "OCT$", STRING, 1, (struct user_fnc *) NULL, fnc_oct, (struct bwb_function *) NULL },
- X { "CINT", SINGLE, 1, (struct user_fnc *) NULL, fnc_cint, (struct bwb_function *) NULL },
- X { "ASC", SINGLE, 1, (struct user_fnc *) NULL, fnc_asc, (struct bwb_function *) NULL },
- X { "ENVIRON$",STRING, 1, (struct user_fnc *) NULL, fnc_environ, (struct bwb_function *) NULL },
- X #if INTENSIVE_DEBUG
- X { "TEST", DOUBLE, 2, (struct user_fnc *) NULL, fnc_test, (struct bwb_function *) NULL },
- X #endif
- X { "MKD$", STRING, 1, (struct user_fnc *) NULL, fnc_mkd, (struct bwb_function *) NULL },
- X { "MKI$", STRING, 1, (struct user_fnc *) NULL, fnc_mki, (struct bwb_function *) NULL },
- X { "MKS$", STRING, 1, (struct user_fnc *) NULL, fnc_mks, (struct bwb_function *) NULL },
- X { "CVD", DOUBLE, 1, (struct user_fnc *) NULL, fnc_cvd, (struct bwb_function *) NULL },
- X { "CVS", SINGLE, 1, (struct user_fnc *) NULL, fnc_cvs, (struct bwb_function *) NULL },
- X { "CVI", INTEGER, 1, (struct user_fnc *) NULL, fnc_cvi, (struct bwb_function *) NULL }
- X };
- X
- X/***************************************************************
- X
- X FUNCTION: fnc_init()
- X
- X DESCRIPTION: This command initializes the function
- X linked list, placing all predefined functions
- X in the list.
- X
- X***************************************************************/
- X
- Xint
- Xfnc_init()
- X {
- X register int n;
- X struct bwb_function *f;
- X
- X strcpy( fnc_start.name, "FNC_START" );
- X fnc_start.type = 'X';
- X fnc_start.vector = fnc_null;
- X strcpy( fnc_end.name, "FNC_END" );
- X fnc_end.type = 'x';
- X fnc_end.vector = fnc_null;
- X fnc_end.next = &fnc_end;
- X
- X f = &fnc_start;
- X
- X /* now go through each of the preestablished functions and set up
- X links between them; from this point the program address the functions
- X only as a linked list (not as an array) */
- X
- X for ( n = 0; n < FUNCTIONS; ++n )
- X {
- X f->next = &( bwb_prefuncs[ n ] );
- X f = f->next;
- X }
- X
- X /* link the last pointer to the end; this completes the list */
- X
- X f->next = &fnc_end;
- X
- X return TRUE;
- X }
- X
- X/***************************************************************
- X
- X FUNCTION: fnc_find()
- X
- X DESCRIPTION: This C function attempts to locate
- X a BASIC function with the specified name.
- X If successful, it returns a pointer to
- X the C structure for the BASIC function,
- X if not successful, it returns NULL.
- X
- X***************************************************************/
- X
- Xstruct bwb_function *
- Xfnc_find( char *buffer )
- X {
- X struct bwb_function * f;
- X register int n;
- X static char *tbuf;
- X static int init = FALSE;
- X
- X /* get memory for temporary buffer if necessary */
- X
- X if ( init == FALSE )
- X {
- X init = TRUE;
- X if ( ( tbuf = calloc( MAXSTRINGSIZE + 1, sizeof( char ) )) == NULL )
- X {
- X bwb_error( err_getmem );
- X }
- X }
- X
- X #if INTENSIVE_DEBUG
- X sprintf( bwb_ebuf, "in fnc_find(): called for <%s> ", buffer );
- X bwb_debug( bwb_ebuf );
- X #endif
- X
- X for ( n = 0; buffer[ n ] != 0; ++n )
- X {
- X if ( islower( buffer[ n ] ) )
- X {
- X tbuf[ n ] = toupper( buffer[ n ] );
- X }
- X else
- X {
- X tbuf[ n ] = buffer[ n ];
- X }
- X }
- X tbuf[ n ] = 0;
- X
- X for ( f = fnc_start.next; f != &fnc_end; f = f->next )
- X {
- X if ( strcmp( f->name, tbuf ) == 0 )
- X {
- X #if INTENSIVE_DEBUG
- X sprintf( bwb_ebuf, "in fnc_find(): found <%s> ", f->name );
- X bwb_debug( bwb_ebuf );
- X #endif
- X return f;
- X }
- X }
- X
- X /* search has failed: return NULL */
- X
- X return NULL;
- X
- X }
- X
- X/***************************************************************
- X
- X FUNCTION: bwb_deffn()
- X
- X DESCRIPTION: This C function implements the BASIC
- X DEF FNxx statement.
- X
- X***************************************************************/
- X
- Xstruct bwb_line *
- Xbwb_deffn( struct bwb_line *l )
- X {
- X register int n;
- X int loop, arguments, p;
- X struct bwb_function *f, *fncpos;
- X static char *tbuf;
- X static int init = FALSE;
- X
- X /* get memory for temporary buffer if necessary */
- X
- X if ( init == FALSE )
- X {
- X init = TRUE;
- X if ( ( tbuf = calloc( MAXSTRINGSIZE + 1, sizeof( char ) )) == NULL )
- X {
- X bwb_error( err_getmem );
- X }
- X }
- X
- X #if INTENSIVE_DEBUG
- X sprintf( bwb_ebuf, "in bwb_deffn(): entered function." );
- X bwb_debug( bwb_ebuf );
- X #endif
- X
- X /* test for appropriate function name */
- X
- X exp_getvfname( &( l->buffer[ l->startpos ] ), tbuf ); /* name in tbuf */
- X
- X for ( n = 0; tbuf[ n ] != '\0'; ++n )
- X {
- X if ( islower( tbuf[ n ] ) != FALSE )
- X {
- X tbuf[ n ] = toupper( tbuf[ n ] );
- X }
- X }
- X
- X if ( strncmp( tbuf, "FN", (size_t) 2 ) != 0 )
- X {
- X #if PROG_ERRORS
- X sprintf( bwb_ebuf, "at line %d: User-defined function name must begin with FN.",
- X l->number );
- X bwb_error( bwb_ebuf );
- X #else
- X bwb_error( err_syntax );
- X #endif
- X l->next->position = 0;
- X return l->next;
- X }
- X
- X #if INTENSIVE_DEBUG
- X sprintf( bwb_ebuf, "in bwb_deffn(): function name is <%s>", tbuf );
- X bwb_debug( bwb_ebuf );
- X #endif
- X
- X /* Allocate memory for a new function structure */
- X
- X if ( ( f = (struct bwb_function *) calloc( (size_t) 1, sizeof( struct bwb_function ) )) == NULL )
- X {
- X #if PROG_ERRORS
- X sprintf( bwb_ebuf, "Failed to find memory for function structure." );
- X bwb_error( bwb_ebuf );
- X #else
- X bwb_error( err_getmem );
- X #endif
- X l->next->position = 0;
- X return l->next;
- X }
- X
- X /* Allocate memory for a user function structure */
- X
- X if ( ( f->ufnc = (struct user_fnc *) calloc( (size_t) 1, sizeof( struct user_fnc ) )) == NULL )
- X {
- X #if PROG_ERRORS
- X sprintf( bwb_ebuf, "Failed to find memory for function structure." );
- X bwb_error( bwb_ebuf );
- X #else
- X bwb_error( err_getmem );
- X #endif
- X l->next->position = 0;
- X return l->next;
- X }
- X
- X /* Set some values for the new function */
- X
- X strncpy( f->name, tbuf, (size_t) MAXVARNAMESIZE );
- X
- X switch( f->name[ strlen( f->name ) - 1 ] )
- X {
- X case STRING:
- X case DOUBLE:
- X case INTEGER:
- X f->type = f->name[ strlen( f->name ) - 1 ];
- X break;
- X default:
- X f->type = SINGLE;
- X break;
- X }
- X
- X f->vector = NULL;
- X f->arguments = 0;
- X
- X /* determine if there are arguments */
- X
- X loop = TRUE;
- X arguments = FALSE;
- X l->position += strlen( f->name );
- X while( loop == TRUE )
- X {
- X
- X switch( l->buffer[ l->position ] )
- X {
- X case ' ': /* whitespace */
- X case '\t':
- X ++l->position;
- X break;
- X case '(': /* begin parenthesis = arguments */
- X ++l->position;
- X loop = FALSE;
- X arguments = TRUE;
- X break;
- X case '\n': /* unexpected end of line */
- X case '\r':
- X case '\0':
- X #if PROG_ERRORS
- X sprintf( bwb_ebuf, "at line %d: Unexpected end of line", l->number );
- X bwb_error( bwb_ebuf );
- X #else
- X bwb_error( err_syntax );
- X #endif
- X l->next->position = 0;
- X return l->next;
- X default: /* any other character = no arguments */
- X loop = FALSE;
- X break;
- X }
- X
- X }
- X
- X /* identify arguments */
- X
- X if ( arguments == TRUE )
- X {
- X
- X loop = TRUE;
- X f->arguments = 0; /* use as counter */
- X p = 0;
- X f->ufnc->user_vns[ f->arguments ][ 0 ] = '\0';
- X while ( loop == TRUE )
- X {
- X switch( l->buffer[ l->position ] )
- X {
- X case ' ': /* whitespace */
- X case '\t':
- X ++l->position;
- X break;
- X case '\0': /* unexpected end of line */
- X case '\n':
- X case '\r':
- X #if PROG_ERRORS
- X sprintf( bwb_ebuf, "at line %d: Unexpected end of line.",
- X l->number );
- X bwb_error( bwb_ebuf );
- X #else
- X bwb_error( err_syntax );
- X #endif
- X l->next->position = 0;
- X return l->next;
- X case ')': /* end of argument list */
- X ++f->arguments; /* returns total number of arguments */
- X ++l->position; /* advance beyond parenthesis */
- X loop = FALSE;
- X break;
- X
- X case ',': /* end of one argument */
- X
- X ++f->arguments;
- X ++l->position;
- X p = 0;
- X f->ufnc->user_vns[ f->arguments ][ 0 ] = '\0';
- X break;
- X default:
- X
- X f->ufnc->user_vns[ f->arguments ][ p ] = l->buffer[ l->position ];
- X ++l->position;
- X ++p;
- X f->ufnc->user_vns[ f->arguments ][ p ] = '\0';
- X break;
- X }
- X }
- X
- X }
- X
- X /* else no arguments were found */
- X
- X else
- X {
- X f->arguments = 0;
- X }
- X
- X #if INTENSIVE_DEBUG
- X for ( n = 0; n < f->arguments; ++n )
- X {
- X sprintf( bwb_ebuf, "in bwb_deffn(): argument <%d> name <%s>.",
- X n, f->ufnc->user_vns[ n ] );
- X bwb_debug( bwb_ebuf );
- X }
- X #endif
- X
- X /* find the string to be interpreted */
- X
- X loop = TRUE;
- X arguments = FALSE;
- X while( loop == TRUE )
- X {
- X switch( l->buffer[ l->position ] )
- X {
- X case '\0': /* unexpected end of line */
- X case '\n':
- X case '\r':
- X #if PROG_ERRORS
- X sprintf( bwb_ebuf, "at line %d: Unexpected end of line.",
- X l->number );
- X bwb_error( bwb_ebuf );
- X #else
- X bwb_error( err_syntax );
- X #endif
- X l->next->position = 0;
- X return l->next;
- X case ' ': /* whitespace */
- X case '\t':
- X ++l->position;
- X break;
- X
- X case '=':
- X ++l->position;
- X arguments = TRUE;
- X break;
- X default:
- X loop = FALSE;
- X break;
- X }
- X }
- X
- X /* if the equals sign was not detected, return error */
- X
- X if ( arguments == FALSE )
- X {
- X #if PROG_ERRORS
- X sprintf( bwb_ebuf, "at line %d: Assignment operator (=) not found.",
- X l->number );
- X bwb_error( bwb_ebuf );
- X #else
- X bwb_error( err_syntax );
- X #endif
- X l->next->position = 0;
- X return l->next;
- X }
- X
- X /* write the string to be interpreted to the user function structure */
- X
- X strncpy( f->ufnc->int_line, &( l->buffer[ l->position ] ),
- X (size_t) MAXSTRINGSIZE );
- X
- X #if INTENSIVE_DEBUG
- X sprintf( bwb_ebuf, "in bwb_deffn(): line <%s>", f->ufnc->int_line );
- X bwb_debug( bwb_ebuf );
- X #endif
- X
- X /* Place the new function in the function linked list */
- X
- X for ( fncpos = &fnc_start; fncpos->next != &fnc_end; fncpos = fncpos->next )
- X {
- X ;
- X }
- X fncpos->next = f;
- X f->next = &fnc_end;
- X
- X /* return */
- X
- X l->next->position = 0;
- X return l->next;
- X
- X }
- X
- X/***************************************************************
- X
- X FUNCTION: fnc_intufnc()
- X
- X DESCRIPTION: This C function interprets a user-defined
- X BASIC function.
- X
- X***************************************************************/
- X
- Xstruct bwb_variable *
- Xfnc_intufnc( int argc, struct bwb_variable *argv, struct bwb_function *f )
- X {
- X register int n;
- X int l_position, f_position;
- X int written;
- X bstring *b;
- X struct exp_ese *e;
- X static struct bwb_variable nvar;
- X
- X #if INTENSIVE_DEBUG
- X sprintf( nvar.name, "intufnc variable" );
- X #endif
- X
- X /* increment the user function stack counter */
- X
- X if ( ufsc >= UFNCSTACKSIZE )
- X {
- X #if PROG_ERRORS
- X sprintf( bwb_ebuf, "exceeded user-defined function stack, level <%d>",
- X ufsc );
- X bwb_error( bwb_ebuf );
- X #else
- X bwb_error( err_overflow );
- X #endif
- X }
- X
- X ++ufsc;
- X
- X #if INTENSIVE_DEBUG
- X sprintf( bwb_ebuf, "in fnc_intufnc(): interpreting user function <%s>",
- X f->name );
- X bwb_debug( bwb_ebuf );
- X #endif
- X
- X /* print arguments to strings */
- X
- X for ( n = 1; n <= argc; ++n )
- X {
- X switch( argv[ n - 1 ].type )
- X {
- X case DOUBLE:
- X sprintf( ufs[ ufsc ].args[ n - 1 ], "(%f)",
- X var_getdval( &( argv[ n - 1 ] ) ));
- X break;
- X case SINGLE:
- X sprintf( ufs[ ufsc ].args[ n - 1 ], "(%f)",
- X var_getfval( &( argv[ n - 1 ] ) ));
- X break;
- X case INTEGER:
- X sprintf( ufs[ ufsc ].args[ n - 1 ], "(%d)",
- X var_getival( &( argv[ n - 1 ] ) ));
- X break;
- X case STRING:
- X b = var_getsval( &( argv[ n - 1 ] ) );
- X str_btoc( bwb_ebuf, b );
- X sprintf( ufs[ ufsc ].args[ n - 1 ], "\"%s\"",
- X bwb_ebuf );
- X break;
- X default:
- X #if PROG_ERRORS
- X sprintf( bwb_ebuf, "Unidentified variable type in argument to user function." );
- X bwb_error( bwb_ebuf );
- X #else
- X bwb_error( err_mismatch );
- X #endif
- X return &nvar;
- X }
- X }
- X
- X #if INTENSIVE_DEBUG
- X for ( n = 1; n <= argc; ++n )
- X {
- X sprintf( bwb_ebuf, "in fnc_intufnc(): arg string %d: <%s>.",
- X n - 1, ufs[ ufsc ].args[ n - 1 ] );
- X bwb_debug ( bwb_ebuf );
- X }
- X #endif
- X
- X /* copy the interpreted line to the buffer, substituting variable ufs[ ufsc ].args */
- X
- X ufs[ ufsc ].l_buffer[ 0 ] = '\0';
- X l_position = 0;
- X for ( f_position = 0; f->ufnc->int_line[ f_position ] != '\0'; ++f_position )
- X {
- X written = FALSE;
- X for ( n = 0; n < argc; ++n )
- X {
- X if ( strncmp( &( f->ufnc->int_line[ f_position ] ), f->ufnc->user_vns[ n ],
- X (size_t) strlen( f->ufnc->user_vns[ n ] ) ) == 0 )
- X {
- X strcat( ufs[ ufsc ].l_buffer, ufs[ ufsc ].args[ n ] );
- X written = TRUE;
- X f_position += strlen( f->ufnc->user_vns[ n ] + 1 );
- X l_position += strlen( ufs[ ufsc ].args[ n ] );
- X }
- X
- X }
- X if ( written == FALSE )
- X {
- X ufs[ ufsc ].l_buffer[ l_position ] = f->ufnc->int_line[ f_position ];
- X ++l_position;
- X ufs[ ufsc ].l_buffer[ l_position ] = '\0';
- X }
- X }
- X
- X #if INTENSIVE_DEBUG
- X sprintf( bwb_ebuf, "in fnc_intufnc(): reconstructed line: <%s>",
- X ufs[ ufsc ].l_buffer );
- X bwb_debug( bwb_ebuf );
- X #endif
- X
- X /* parse */
- X
- X ufs[ ufsc ].position = 0;
- X e = bwb_exp( ufs[ ufsc ].l_buffer, FALSE,
- X &( ufs[ ufsc ].position ) );
- X
- X var_make( &nvar, e->type );
- X
- X switch( e->type )
- X {
- X case DOUBLE:
- X * var_finddval( &nvar, nvar.array_pos ) = exp_getdval( e );
- X break;
- X case INTEGER:
- X * var_findival( &nvar, nvar.array_pos ) = exp_getival( e );
- X break;
- X case STRING:
- X str_btob( var_findsval( &nvar, nvar.array_pos ),
- X exp_getsval( e ) );
- X break;
- X default:
- X * var_findfval( &nvar, nvar.array_pos ) = exp_getfval( e );
- X break;
- X }
- X
- X /* decrement the user function stack counter */
- X
- X --ufsc;
- X
- X return &nvar;
- X
- X }
- X
- X/***************************************************************
- X
- X FUNCTION: fnc_null()
- X
- X DESCRIPTION: This is a null function that can be used
- X to fill in a required function-structure
- X pointer when needed.
- X
- X***************************************************************/
- X
- Xstruct bwb_variable *
- Xfnc_null( int argc, struct bwb_variable *argv )
- X {
- X static struct bwb_variable nvar;
- X static int init = FALSE;
- X
- X /* initialize the variable if necessary */
- X
- X if ( init == FALSE )
- X {
- X init = TRUE;
- X var_make( &nvar, INTEGER );
- X }
- X
- X return &nvar;
- X }
- X
- X/***************************************************************
- X
- X
- X FUNCTION: fnc_date()
- X
- X DESCRIPTION: This C function implements the BASIC
- X predefined DATE$ function, returning
- X a string containing the year, month,
- X and day of the month.
- X
- X***************************************************************/
- X
- Xstruct bwb_variable *
- Xfnc_date( int argc, struct bwb_variable *argv )
- X {
- X static struct bwb_variable nvar;
- X static int init = FALSE;
- X static char *tbuf;
- X
- X /* initialize the variable if necessary */
- X
- X if ( init == FALSE )
- X {
- X init = TRUE;
- X var_make( &nvar, STRING );
- X if ( ( tbuf = calloc( MAXSTRINGSIZE + 1, sizeof( char ) )) == NULL )
- X {
- X bwb_error( err_getmem );
- X }
- X }
- X
- X time( &t );
- X lt = localtime( &t );
- X
- X sprintf( tbuf, "%02d-%02d-%04d", lt->tm_mon + 1, lt->tm_mday,
- X 1900 + lt->tm_year );
- X str_ctob( var_findsval( &nvar, nvar.array_pos ), tbuf );
- X
- X return &nvar;
- X }
- X
- X/***************************************************************
- X
- X FUNCTION: fnc_time()
- X
- X DESCRIPTION: This C function implements the BASIC
- X predefined TIME$ function, returning a
- X string containing the hour, minute, and
- X second count.
- X
- X***************************************************************/
- X
- Xstruct bwb_variable *
- Xfnc_time( int argc, struct bwb_variable *argv )
- X {
- X static struct bwb_variable nvar;
- X static char *tbuf;
- X static int init = FALSE;
- X
- X /* initialize the variable if necessary */
- X
- X if ( init == FALSE )
- X {
- X init = TRUE;
- X var_make( &nvar, STRING );
- X if ( ( tbuf = calloc( MAXSTRINGSIZE + 1, sizeof( char ) )) == NULL )
- X {
- X bwb_error( err_getmem );
- X }
- X }
- X
- X time( &t );
- X lt = localtime( &t );
- X
- X sprintf( tbuf, "%02d:%02d:%02d", lt->tm_hour, lt->tm_min,
- X lt->tm_sec );
- X str_ctob( var_findsval( &nvar, nvar.array_pos ), tbuf );
- X
- X return &nvar;
- X }
- X
- X/***************************************************************
- X
- X FUNCTION: fnc_test()
- X
- X DESCRIPTION: This is a test function, developed in
- X order to test argument passing to
- X BASIC functions.
- X
- X***************************************************************/
- X
- X#if INTENSIVE_DEBUG
- Xstruct bwb_variable *
- Xfnc_test( int argc, struct bwb_variable *argv )
- X {
- X register int c;
- X static struct bwb_variable rvar;
- X static char *tbuf;
- X static int init = FALSE;
- X
- X /* initialize the variable if necessary */
- X
- X if ( init == FALSE )
- X {
- X init = TRUE;
- X var_make( &rvar, SINGLE );
- X if ( ( tbuf = calloc( MAXSTRINGSIZE + 1, sizeof( char ) )) == NULL )
- X {
- X bwb_error( err_getmem );
- X }
- X }
- X
- X fprintf( stdout, "TEST function: received %d arguments: \n", argc );
- X
- X for ( c = 0; c < argc; ++c )
- X {
- X str_btoc( tbuf, var_getsval( &argv[ c ] ) );
- X fprintf( stdout, " arg %d (%c): <%s> \n", c,
- X argv[ c ].type, tbuf );
- X }
- X
- X return &rvar;
- X
- X }
- X#endif
- X
- X/***************************************************************
- X
- X FUNCTION: fnc_rnd()
- X
- X DESCRIPTION: This C function implements the BASIC
- X predefined RND function, returning a
- X pseudo-random number in the range
- X 0 to 1. It is affected by the RANDOMIZE
- X command statement.
- X
- X***************************************************************/
- X
- Xstruct bwb_variable *
- Xfnc_rnd( int argc, struct bwb_variable *argv )
- X {
- X static struct bwb_variable nvar;
- X static int init = FALSE;
- X
- X /* initialize the variable if necessary */
- X
- X if ( init == FALSE )
- X {
- X init = TRUE;
- X var_make( &nvar, SINGLE );
- X }
- X
- X * var_findfval( &nvar, nvar.array_pos ) = (float) rand() / RAND_MAX;
- X
- X return &nvar;
- X }
- X
- X/***************************************************************
- X
- X FUNCTION: fnc_chr()
- X
- X DESCRIPTION: This C function implements the BASIC
- X predefined CHR$ function, returning a
- X string containing the single character
- X whose ASCII value is the argument to
- X this function.
- X
- X***************************************************************/
- X
- Xstruct bwb_variable *
- Xfnc_chr( int argc, struct bwb_variable *argv )
- X {
- X static struct bwb_variable nvar;
- X char tbuf[ MAXSTRINGSIZE + 1 ];
- X static int init = FALSE;
- X #if TEST_BSTRING
- X bstring *b;
- X #endif
- X
- X #if INTENSIVE_DEBUG
- X sprintf( bwb_ebuf, "in fnc_chr(): entered function, argc <%d>",
- X argc );
- X bwb_debug( bwb_ebuf );
- X #endif
- X
- X /* initialize the variable if necessary */
- X
- X if ( init == FALSE )
- X {
- X init = TRUE;
- X var_make( &nvar, STRING );
- X #if INTENSIVE_DEBUG
- X sprintf( bwb_ebuf, "in fnc_chr(): entered function, initialized nvar" );
- X bwb_debug( bwb_ebuf );
- X #endif
- X }
- X
- X /* check arguments */
- X
- X #if PROG_ERRORS
- X if ( argc < 1 )
- X {
- X sprintf( bwb_ebuf, "Not enough arguments to function CHR$()" );
- X bwb_error( bwb_ebuf );
- X return NULL;
- X }
- X else if ( argc > 1 )
- X {
- X sprintf( bwb_ebuf, "Too many parameters (%d) to function CHR$().",
- X argc );
- X bwb_error( bwb_ebuf );
- X return NULL;
- X }
- X #else
- X if ( fnc_checkargs( argc, argv, 1, 1 ) == FALSE )
- X {
- X return NULL;
- X }
- X #endif
- X
- X #if INTENSIVE_DEBUG
- X sprintf( bwb_ebuf, "in fnc_chr(): entered function, checkargs ok" );
- X bwb_debug( bwb_ebuf );
- X #endif
- X
- X tbuf[ 0 ] = (char) var_getival( &( argv[ 0 ] ) );
- X tbuf[ 1 ] = '\0';
- X str_ctob( var_findsval( &nvar, nvar.array_pos ), tbuf );
- X
- X #if TEST_BSTRING
- X b = var_findsval( &nvar, nvar.array_pos );
- X sprintf( bwb_ebuf, "in fnc_chr(): bstring name is <%s>", b->name );
- X bwb_debug( bwb_ebuf );
- X #endif
- X #if INTENSIVE_DEBUG
- X sprintf( bwb_ebuf, "in fnc_chr(): tbuf[ 0 ] is <%c>", tbuf[ 0 ] );
- X bwb_debug( bwb_ebuf );
- X #endif
- X
- X return &nvar;
- X }
- X
- X/***************************************************************
- X
- X FUNCTION: fnc_mid()
- X
- X DESCRIPTION: This C function implements the BASIC
- X predefined MID$ function
- X
- X***************************************************************/
- X
- Xstruct bwb_variable *
- Xfnc_mid( int argc, struct bwb_variable *argv )
- X {
- X static struct bwb_variable nvar;
- X register int c;
- X char target_string[ MAXSTRINGSIZE + 1 ];
- X int target_counter, num_spaces;
- X char tbuf[ MAXSTRINGSIZE + 1 ];
- X static int init = FALSE;
- X
- X /* initialize the variable if necessary */
- X
- X if ( init == FALSE )
- X {
- X init = TRUE;
- X var_make( &nvar, STRING );
- X }
- X
- X /* check arguments */
- X
- X #if PROG_ERRORS
- X if ( argc < 2 )
- X {
- X sprintf( bwb_ebuf, "Not enough arguments to function MID$()" );
- X bwb_error( bwb_ebuf );
- X return &nvar;
- X }
- X
- X if ( argc > 3 )
- X {
- X sprintf( bwb_ebuf, "Two many arguments to function MID$()" );
- X bwb_error( bwb_ebuf );
- X return &nvar;
- X }
- X
- X #else
- X if ( fnc_checkargs( argc, argv, 2, 3 ) == FALSE )
- X {
- X return NULL;
- X }
- X #endif
- X
- X /* get arguments */
- X
- X str_btoc( target_string, var_getsval( &( argv[ 0 ] ) ));
- X target_counter = var_getival( &( argv[ 1 ] ) ) - 1;
- X if ( target_counter > strlen( target_string ))
- X {
- X tbuf[ 0 ] = '\0';
- X str_ctob( var_findsval( &nvar, nvar.array_pos ), tbuf );
- X return &nvar;
- X }
- X
- X if ( argc == 3 )
- X {
- X num_spaces = var_getival( &( argv[ 2 ] ));
- X }
- X else
- X {
- X num_spaces = MAXSTRINGSIZE;
- X }
- X
- X #if INTENSIVE_DEBUG
- X sprintf( bwb_ebuf, "in fnc_mid() string <%s> startpos <%d> spaces <%d>",
- X target_string, target_counter, num_spaces );
- X bwb_debug( bwb_ebuf );
- X #endif
- X
- X c = 0;
- X tbuf[ c ] = '\0';
- X while ( ( c < num_spaces ) && ( target_string[ target_counter ] != '\0' ))
- X {
- X tbuf[ c ] = target_string[ target_counter ];
- X ++c;
- X tbuf[ c ] = '\0';
- X ++target_counter;
- X }
- X str_ctob( var_findsval( &nvar, nvar.array_pos ), tbuf );
- X
- X return &nvar;
- X }
- X
- X/***************************************************************
- X
- X FUNCTION: fnc_left()
- X
- X DESCRIPTION: This C function implements the BASIC
- X predefined LEFT$ function
- X
- X***************************************************************/
- X
- Xstruct bwb_variable *
- Xfnc_left( int argc, struct bwb_variable *argv )
- X {
- X static struct bwb_variable nvar;
- X register int c;
- X char target_string[ MAXSTRINGSIZE + 1 ];
- X int target_counter, num_spaces;
- X char tbuf[ MAXSTRINGSIZE + 1 ];
- X static int init = FALSE;
- X
- X /* initialize the variable if necessary */
- X
- X if ( init == FALSE )
- X {
- X init = TRUE;
- X var_make( &nvar, STRING );
- X }
- X
- X /* check arguments */
- X
- X #if PROG_ERRORS
- X if ( argc < 2 )
- X {
- X sprintf( bwb_ebuf, "Not enough arguments to function LEFT$()" );
- X bwb_error( bwb_ebuf );
- X return &nvar;
- X }
- X
- X if ( argc > 2 )
- X {
- X sprintf( bwb_ebuf, "Two many arguments to function LEFT$()" );
- X bwb_error( bwb_ebuf );
- X return &nvar;
- X }
- X
- X #else
- X if ( fnc_checkargs( argc, argv, 2, 2 ) == FALSE )
- X {
- X return NULL;
- X }
- X #endif
- X
- X /* get arguments */
- X
- X str_btoc( tbuf, var_getsval( &( argv[ 0 ] ) ));
- X target_counter = 0;
- X num_spaces = var_getival( &( argv[ 1 ] ));
- X
- X #if INTENSIVE_DEBUG
- X sprintf( bwb_ebuf, "in fnc_left() string <%s> startpos <%d> spaces <%d>",
- X tbuf, target_counter, num_spaces );
- X bwb_debug( bwb_ebuf );
- X #endif
- X
- X c = 0;
- X target_string[ 0 ] = '\0';
- X while (( c < num_spaces ) && ( tbuf[ c ] != '\0' ))
- X {
- X target_string[ target_counter ] = tbuf[ c ];
- X ++target_counter;
- X target_string[ target_counter ] = '\0';
- X ++c;
- X }
- X str_ctob( var_findsval( &nvar, nvar.array_pos ), target_string );
- X
- X return &nvar;
- X }
- X
- X/***************************************************************
- X
- X FUNCTION: fnc_right()
- X
- X DESCRIPTION: This C function implements the BASIC
- X predefined RIGHT$ function
- X
- X***************************************************************/
- X
- Xstruct bwb_variable *
- Xfnc_right( int argc, struct bwb_variable *argv )
- X {
- X static struct bwb_variable nvar;
- X register int c;
- X char target_string[ MAXSTRINGSIZE + 1 ];
- X int target_counter, num_spaces;
- X char tbuf[ MAXSTRINGSIZE + 1 ];
- X static int init = FALSE;
- X
- X /* initialize the variable if necessary */
- X
- X if ( init == FALSE )
- X {
- X init = TRUE;
- X var_make( &nvar, STRING );
- X }
- X
- X /* check arguments */
- X
- X #if PROG_ERRORS
- X if ( argc < 2 )
- X {
- X sprintf( bwb_ebuf, "Not enough arguments to function RIGHT$()" );
- X bwb_error( bwb_ebuf );
- X return &nvar;
- X }
- X
- X if ( argc > 2 )
- X {
- X sprintf( bwb_ebuf, "Two many arguments to function RIGHT$()" );
- X bwb_error( bwb_ebuf );
- X return &nvar;
- X }
- X
- X #else
- X if ( fnc_checkargs( argc, argv, 2, 2 ) == FALSE )
- X {
- X return NULL;
- X }
- X #endif
- X
- X /* get arguments */
- X
- X str_btoc( target_string, var_getsval( &( argv[ 0 ] ) ));
- X target_counter = strlen( target_string ) - var_getival( &( argv[ 1 ] ));
- X num_spaces = MAXSTRINGSIZE;
- X
- X #if INTENSIVE_DEBUG
- X sprintf( bwb_ebuf, "in fnc_right() string <%s> startpos <%d> spaces <%d>",
- X target_string, target_counter, num_spaces );
- X bwb_debug( bwb_ebuf );
- X #endif
- X
- X c = 0;
- X tbuf[ c ] = '\0';
- X while ( ( c < num_spaces ) && ( target_string[ target_counter ] != '\0' ))
- X {
- X tbuf[ c ] = target_string[ target_counter ];
- X ++c;
- X tbuf[ c ] = '\0';
- X ++target_counter;
- X }
- X str_ctob( var_findsval( &nvar, nvar.array_pos ), tbuf );
- X
- X return &nvar;
- X }
- X
- X/***************************************************************
- X
- X FUNCTION: fnc_timer()
- X
- X DESCRIPTION: This C function implements the BASIC
- X predefined TIMER function
- X
- X***************************************************************/
- X
- Xstruct bwb_variable *
- Xfnc_timer( int argc, struct bwb_variable *argv )
- X {
- X static struct bwb_variable nvar;
- X static time_t now;
- X static int init = FALSE;
- X
- X /* initialize the variable if necessary */
- X
- X if ( init == FALSE )
- X {
- X init = TRUE;
- X var_make( &nvar, SINGLE );
- X }
- X
- X time( &now );
- X * var_findfval( &nvar, nvar.array_pos )
- X = (float) fmod( (double) now, (double) (60*60*24));
- X
- X return &nvar;
- X }
- X
- X/***************************************************************
- X
- X FUNCTION: fnc_val()
- X
- X DESCRIPTION:
- X
- X***************************************************************/
- X
- Xstruct bwb_variable *
- Xfnc_val( int argc, struct bwb_variable *argv )
- X {
- X static struct bwb_variable nvar;
- X static char *tbuf;
- X static int init = FALSE;
- X
- X /* initialize the variable if necessary */
- X
- X if ( init == FALSE )
- X {
- X init = TRUE;
- X var_make( &nvar, SINGLE );
- X if ( ( tbuf = calloc( MAXSTRINGSIZE + 1, sizeof( char ) )) == NULL )
- X {
- X bwb_error( err_getmem );
- X }
- X }
- X
- X /* check arguments */
- X
- X #if PROG_ERRORS
- X if ( argc < 1 )
- X {
- X sprintf( bwb_ebuf, "Not enough arguments to function VAL()" );
- X bwb_error( bwb_ebuf );
- X return NULL;
- X }
- X else if ( argc > 1 )
- X {
- X sprintf( bwb_ebuf, "Too many parameters (%d) to function VAL().",
- X argc );
- X bwb_error( bwb_ebuf );
- X return NULL;
- X }
- X
- X #else
- X if ( fnc_checkargs( argc, argv, 1, 1 ) == FALSE )
- X {
- X return NULL;
- X }
- X #endif
- X
- X else if ( argv[ 0 ].type != STRING )
- X {
- X #if PROG_ERRORS
- X sprintf( bwb_ebuf, "Argument to function VAL() must be a string.",
- X argc );
- X bwb_error( bwb_ebuf );
- X #else
- X bwb_error( err_mismatch );
- X #endif
- X return NULL;
- X }
- X
- X /* read the value */
- X
- X str_btoc( tbuf, var_getsval( &( argv[ 0 ] ) ));
- X sscanf( tbuf, "%f",
- X var_findfval( &nvar, nvar.array_pos ) );
- X
- X return &nvar;
- X }
- X
- X/***************************************************************
- X
- X FUNCTION: fnc_len()
- X
- X DESCRIPTION:
- X
- X***************************************************************/
- X
- Xstruct bwb_variable *
- Xfnc_len( int argc, struct bwb_variable *argv )
- X {
- X static struct bwb_variable nvar;
- X static int init = FALSE;
- X static char *tbuf;
- X
- X /* initialize the variable if necessary */
- X
- X if ( init == FALSE )
- X {
- X init = TRUE;
- X var_make( &nvar, INTEGER );
- X if ( ( tbuf = calloc( MAXSTRINGSIZE + 1, sizeof( char ) )) == NULL )
- X {
- X bwb_error( err_getmem );
- X }
- X }
- X
- X /* check parameters */
- X
- X #if PROG_ERRORS
- X if ( argc < 1 )
- X {
- X sprintf( bwb_ebuf, "Not enough parameters (%d) to function LEN().",
- X argc );
- X bwb_error( bwb_ebuf );
- X return NULL;
- X }
- X else if ( argc > 1 )
- X {
- X sprintf( bwb_ebuf, "Too many parameters (%d) to function LEN().",
- X argc );
- X bwb_error( bwb_ebuf );
- X return NULL;
- X }
- X #else
- X if ( fnc_checkargs( argc, argv, 1, 1 ) == FALSE )
- X {
- X return NULL;
- X }
- X #endif
- X
- X /* return length as an integer */
- X
- X str_btoc( tbuf, var_getsval( &( argv[ 0 ] )) );
- X * var_findival( &nvar, nvar.array_pos )
- X = strlen( tbuf );
- X
- X return &nvar;
- X }
- X
- X/***************************************************************
- X
- X FUNCTION: fnc_hex()
- X
- X DESCRIPTION:
- X
- X***************************************************************/
- X
- Xstruct bwb_variable *
- Xfnc_hex( int argc, struct bwb_variable *argv )
- X {
- X static struct bwb_variable nvar;
- X static char *tbuf;
- X static int init = FALSE;
- X
- X /* initialize the variable if necessary */
- X
- X if ( init == FALSE )
- X {
- X init = TRUE;
- X var_make( &nvar, STRING );
- X if ( ( tbuf = calloc( MAXSTRINGSIZE + 1, sizeof( char ) )) == NULL )
- X {
- X bwb_error( err_getmem );
- X }
- X }
- X
- X /* check parameters */
- X
- X #if PROG_ERRORS
- X if ( argc < 1 )
- X {
- X sprintf( bwb_ebuf, "Not enough parameters (%d) to function HEX$().",
- X argc );
- X bwb_error( bwb_ebuf );
- X return NULL;
- X }
- X else if ( argc > 1 )
- X {
- X sprintf( bwb_ebuf, "Too many parameters (%d) to function HEX$().",
- X argc );
- X bwb_error( bwb_ebuf );
- X return NULL;
- X }
- X #else
- X if ( fnc_checkargs( argc, argv, 1, 1 ) == FALSE )
- X {
- X return NULL;
- X }
- X #endif
- X
- X /* format as hex integer */
- X
- X sprintf( tbuf, "%X", (int) trnc_int( (double) var_getfval( &( argv[ 0 ] )) ) );
- X str_ctob( var_findsval( &nvar, nvar.array_pos ), tbuf );
- X return &nvar;
- X }
- X
- X/***************************************************************
- X
- X FUNCTION: fnc_oct()
- X
- X DESCRIPTION: This C function implements the BASIC
- X OCT$() function.
- X
- X***************************************************************/
- X
- Xstruct bwb_variable *
- Xfnc_oct( int argc, struct bwb_variable *argv )
- X {
- X static struct bwb_variable nvar;
- X static char *tbuf;
- X static int init = FALSE;
- X
- X /* initialize the variable if necessary */
- X
- X if ( init == FALSE )
- X {
- X init = TRUE;
- X var_make( &nvar, STRING );
- X if ( ( tbuf = calloc( MAXSTRINGSIZE + 1, sizeof( char ) )) == NULL )
- X {
- X bwb_error( err_getmem );
- X }
- X }
- X
- X /* check parameters */
- X
- X #if PROG_ERRORS
- X if ( argc < 1 )
- X {
- X sprintf( bwb_ebuf, "Not enough parameters (%d) to function OCT$().",
- X argc );
- X bwb_error( bwb_ebuf );
- X return NULL;
- X }
- X else if ( argc > 1 )
- X {
- X sprintf( bwb_ebuf, "Too many parameters (%d) to function OCT$().",
- X argc );
- X bwb_error( bwb_ebuf );
- X return NULL;
- X }
- X #else
- X if ( fnc_checkargs( argc, argv, 1, 1 ) == FALSE )
- X {
- X return NULL;
- X }
- X #endif
- X
- X /* format as octal integer */
- X
- X sprintf( tbuf, "%o", var_getival( &( argv[ 0 ] ) ) );
- X str_ctob( var_findsval( &nvar, nvar.array_pos ), tbuf );
- X return &nvar;
- X }
- X
- X/***************************************************************
- X
- X FUNCTION: fnc_asc()
- X
- X DESCRIPTION: This function implements the predefined
- X BASIC ASC() function.
- X
- X***************************************************************/
- X
- Xstruct bwb_variable *
- Xfnc_asc( int argc, struct bwb_variable *argv )
- X {
- X static struct bwb_variable nvar;
- X static char *tbuf;
- X static int init = FALSE;
- X
- X /* initialize the variable if necessary */
- X
- X if ( init == FALSE )
- X {
- X init = TRUE;
- X var_make( &nvar, INTEGER );
- X if ( ( tbuf = calloc( MAXSTRINGSIZE + 1, sizeof( char ) )) == NULL )
- X {
- X bwb_error( err_getmem );
- X }
- X }
- X
- X /* check parameters */
- X
- X #if PROG_ERRORS
- X if ( argc < 1 )
- X {
- X sprintf( bwb_ebuf, "Not enough parameters (%d) to function ASC().",
- X argc );
- X bwb_error( bwb_ebuf );
- X return NULL;
- X }
- X else if ( argc > 1 )
- X {
- X sprintf( bwb_ebuf, "Too many parameters (%d) to function ASC().",
- X argc );
- X bwb_error( bwb_ebuf );
- X return NULL;
- X }
- X #else
- X if ( fnc_checkargs( argc, argv, 1, 1 ) == FALSE )
- X {
- X return NULL;
- X }
- X #endif
- X
- X if ( argv[ 0 ].type != STRING )
- X {
- X #if PROG_ERRORS
- X sprintf( bwb_ebuf, "Argument to function ASC() must be a string.",
- X argc );
- X bwb_error( bwb_ebuf );
- X #else
- X bwb_error( err_mismatch );
- X #endif
- X return NULL;
- X }
- X
- X /* assign ASCII value of first character in the buffer */
- X
- X str_btoc( tbuf, var_findsval( &( argv[ 0 ] ), argv[ 0 ].array_pos ) );
- X * var_findival( &nvar, nvar.array_pos ) = (int) tbuf[ 0 ];
- X
- X #if INTENSIVE_DEBUG
- X sprintf( bwb_ebuf, "in fnc_asc(): string is <%s>",
- X tbuf );
- X bwb_debug( bwb_ebuf );
- X #endif
- X
- X return &nvar;
- X }
- X
- X/***************************************************************
- X
- X FUNCTION: fnc_string()
- X
- X DESCRIPTION: This C function implements the BASIC
- X STRING$() function.
- X
- X***************************************************************/
- X
- Xstruct bwb_variable *
- Xfnc_string( int argc, struct bwb_variable *argv )
- X {
- X static struct bwb_variable nvar;
- X int length;
- X register int i;
- X char c;
- X struct bwb_variable *v;
- X static char *tbuf;
- X static int init = FALSE;
- X
- X /* initialize the variable if necessary */
- X
- X if ( init == FALSE )
- X {
- X init = TRUE;
- X var_make( &nvar, STRING );
- X if ( ( tbuf = calloc( MAXSTRINGSIZE + 1, sizeof( char ) )) == NULL )
- X {
- X bwb_error( err_getmem );
- X }
- X }
- X
- X /* check for correct number of parameters */
- X
- X #if PROG_ERRORS
- X if ( argc < 2 )
- X {
- X sprintf( bwb_ebuf, "Not enough parameters (%d) to function STRING$().",
- X argc );
- X bwb_error( bwb_ebuf );
- X return NULL;
- X }
- X else if ( argc > 2 )
- X {
- X sprintf( bwb_ebuf, "Too many parameters (%d) to function STRING$().",
- X argc );
- X bwb_error( bwb_ebuf );
- X return NULL;
- X }
- X #else
- X if ( fnc_checkargs( argc, argv, 2, 2 ) == FALSE )
- X {
- X return NULL;
- X }
- X #endif
- X
- X strcpy( nvar.name, "(string$)!" );
- X nvar.type = STRING;
- X tbuf[ 0 ] = '\0';
- X length = var_getival( &( argv[ 0 ] ));
- X
- X if ( argv[ 1 ].type == STRING )
- X {
- X str_btoc( tbuf, var_getsval( &( argv[ 1 ] )));
- X c = tbuf[ 0 ];
- X }
- X else
- X {
- X c = (char) var_getival( &( argv[ 1 ] ) );
- X }
- X
- X #if INTENSIVE_DEBUG
- X sprintf( bwb_ebuf, "in fnc_string(): argument <%s> arg type <%c>, length <%d>",
- X argv[ 1 ].string, argv[ 1 ].type, length );
- X bwb_debug( bwb_ebuf );
- X sprintf( bwb_ebuf, "in fnc_string(): type <%c>, c <0x%x>=<%c>",
- X argv[ 1 ].type, c, c );
- X bwb_debug( bwb_ebuf );
- X #endif
- X
- X /* add characters to the string */
- X
- X for ( i = 0; i < length; ++i )
- X {
- X tbuf[ i ] = c;
- X tbuf[ i + 1 ] = '\0';
- X }
- X str_ctob( var_findsval( &nvar, nvar.array_pos ), tbuf );
- X
- X return &nvar;
- X }
- X
- X/***************************************************************
- X
- X FUNCTION: fnc_environ()
- X
- X DESCRIPTION: This C function implements the BASIC
- X ENVIRON$() function.
- X
- X***************************************************************/
- X
- Xstruct bwb_variable *
- Xfnc_environ( int argc, struct bwb_variable *argv )
- X {
- X char tbuf[ MAXSTRINGSIZE + 1 ];
- X char tmp[ MAXSTRINGSIZE + 1 ];
- X static struct bwb_variable nvar;
- X static int init = FALSE;
- X
- X /* initialize the variable if necessary */
- X
- X if ( init == FALSE )
- X {
- X init = TRUE;
- X var_make( &nvar, STRING );
- X }
- X
- X /* check for correct number of parameters */
- X
- X #if PROG_ERRORS
- X if ( argc < 1 )
- X {
- X sprintf( bwb_ebuf, "Not enough parameters (%d) to function ENVIRON$().",
- X argc );
- X bwb_error( bwb_ebuf );
- X return NULL;
- X }
- X else if ( argc > 1 )
- X {
- X sprintf( bwb_ebuf, "Too many parameters (%d) to function ENVIRON$().",
- X argc );
- X bwb_error( bwb_ebuf );
- X return NULL;
- X }
- X #else
- X if ( fnc_checkargs( argc, argv, 1, 1 ) == FALSE )
- X {
- X return NULL;
- X }
- X #endif
- X
- X /* resolve the argument and place string value in tbuf */
- X
- X str_btoc( tbuf, var_getsval( &( argv[ 0 ] )));
- X
- X /* call getenv() then write value to string */
- X
- X strcpy( tmp, getenv( tbuf ));
- X str_ctob( var_findsval( &nvar, nvar.array_pos ), tmp );
- X
- X /* return address of nvar */
- X
- X return &nvar;
- X
- X }
- X
- X/***************************************************************
- X
- X FUNCTION: fnc_instr()
- X
- X DESCRIPTION:
- X
- X***************************************************************/
- X
- Xstruct bwb_variable *
- Xfnc_instr( int argc, struct bwb_variable *argv )
- X {
- X static struct bwb_variable nvar;
- X static int init = FALSE;
- X int n_pos, x_pos, y_pos;
- X int start_pos;
- X register int n;
- X char xbuf[ MAXSTRINGSIZE + 1 ];
- X char ybuf[ MAXSTRINGSIZE + 1 ];
- X
- X /* initialize the variable if necessary */
- X
- X if ( init == FALSE )
- X {
- X init = TRUE;
- X var_make( &nvar, INTEGER );
- X }
- X
- X /* check for correct number of parameters */
- X
- X #if PROG_ERRORS
- X if ( argc < 2 )
- X {
- X sprintf( bwb_ebuf, "Not enough parameters (%d) to function INSTR().",
- X argc );
- X bwb_error( bwb_ebuf );
- X return NULL;
- X }
- X else if ( argc > 3 )
- X {
- X sprintf( bwb_ebuf, "Too many parameters (%d) to function INSTR().",
- X argc );
- X bwb_error( bwb_ebuf );
- X return NULL;
- X }
- X #else
- X if ( fnc_checkargs( argc, argv, 2, 3 ) == FALSE )
- X {
- X return NULL;
- X }
- X #endif
- X
- X /* determine argument positions */
- X
- X if ( argc == 3 )
- X {
- X n_pos = 0;
- X x_pos = 1;
- X y_pos = 2;
- X }
- X else
- X {
- X n_pos = -1;
- X x_pos = 0;
- X y_pos = 1;
- X }
- X
- X /* determine starting position */
- X
- X if ( n_pos == 0 )
- X {
- X start_pos = var_getival( &( argv[ n_pos ] ) ) - 1;
- X }
- X else
- X {
- X start_pos = 0;
- X }
- X
- X /* get x and y strings */
- X
- X str_btoc( xbuf, var_getsval( &( argv[ x_pos ] ) ) );
- X str_btoc( ybuf, var_getsval( &( argv[ y_pos ] ) ) );
- X
- X /* now search for match */
- X
- X for ( n = start_pos; n < strlen( xbuf ); ++n )
- X {
- X if ( strncmp( &( xbuf[ n ] ), ybuf, strlen( ybuf ) ) == 0 )
- X {
- X * var_findival( &nvar, nvar.array_pos ) = n + 1;
- X return &nvar;
- X }
- X }
- X
- X /* match not found */
- X
- X * var_findival( &nvar, nvar.array_pos ) = 0;
- X return &nvar;
- X
- X }
- X
- X/***************************************************************
- X
- X FUNCTION: fnc_str()
- X
- X DESCRIPTION:
- X
- X***************************************************************/
- X
- Xstruct bwb_variable *
- Xfnc_str( int argc, struct bwb_variable *argv )
- X {
- X static struct bwb_variable nvar;
- X static char *tbuf;
- X static int init = FALSE;
- X
- X /* initialize the variable if necessary */
- X
- X if ( init == FALSE )
- X {
- X init = TRUE;
- X var_make( &nvar, STRING );
- X if ( ( tbuf = calloc( MAXSTRINGSIZE + 1, sizeof( char ) )) == NULL )
- X {
- X bwb_error( err_getmem );
- X }
- X }
- X
- X /* check parameters */
- X
- X #if PROG_ERRORS
- X if ( argc < 1 )
- X {
- X sprintf( bwb_ebuf, "Not enough parameters (%d) to function STR$().",
- X argc );
- X bwb_error( bwb_ebuf );
- X return NULL;
- X }
- X else if ( argc > 1 )
- X {
- X sprintf( bwb_ebuf, "Too many parameters (%d) to function STR$().",
- X argc );
- X bwb_error( bwb_ebuf );
- X return NULL;
- X }
- X #else
- X if ( fnc_checkargs( argc, argv, 1, 1 ) == FALSE )
- X {
- X return NULL;
- X }
- X #endif
- X
- X /* format as decimal number */
- X
- X sprintf( tbuf, " %.*f", prn_precision( &( argv[ 0 ] ) ),
- X var_getfval( &( argv[ 0 ] ) ) );
- X str_ctob( var_findsval( &nvar, nvar.array_pos ), tbuf );
- X
- X return &nvar;
- X }
- X
- X/***************************************************************
- X
- X FUNCTION: fnc_checkargs()
- X
- X DESCRIPTION: This C function checks the arguments to
- X functions.
- X
- X***************************************************************/
- X
- X#if PROG_ERRORS
- X#else
- Xint
- Xfnc_checkargs( int argc, struct bwb_variable *argv, int min, int max )
- X {
- X
- X if ( argc < min )
- X {
- X bwb_error( err_syntax );
- X return FALSE;
- X }
- X if ( argc > max )
- X {
- X bwb_error( err_syntax );
- X return FALSE;
- X }
- X
- X return TRUE;
- X
- X }
- X#endif
- X
- X/***************************************************************
- X
- X FUNCTION: fnc_fncs()
- X
- X DESCRIPTION: This C function is used for debugging
- X purposes; it prints a list of all defined
- X functions.
- X
- X***************************************************************/
- X
- X#if PERMANENT_DEBUG
- Xstruct bwb_line *
- Xbwb_fncs( struct bwb_line *l )
- X {
- X struct bwb_function *f;
- X
- X for ( f = fnc_start.next; f != &fnc_end; f = f->next )
- X {
- X fprintf( stdout, "%s\t%c \n", f->name, f->type );
- X }
- X
- X l->next->position = 0;
- X return l->next;
- X
- X }
- X#endif
- END_OF_FILE
- if test 50459 -ne `wc -c <'bwb_fnc.c'`; then
- echo shar: \"'bwb_fnc.c'\" unpacked with wrong size!
- fi
- # end of 'bwb_fnc.c'
- fi
- echo shar: End of archive 1 \(of 11\).
- cp /dev/null ark1isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 11 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still must unpack the following archives:
- echo " " ${MISSING}
- fi
- exit 0
- exit 0 # Just in case...
-