diff --git a/.gitattributes b/.gitattributes index 4dcdb6d..d1fb670 100644 --- a/.gitattributes +++ b/.gitattributes @@ -17,6 +17,8 @@ *.BAS text eol=crlf *.bat text eol=crlf *.BAT text eol=crlf +*.cmd text eol=crlf +*.CMD text eol=crlf *.doc text eol=crlf *.DOC text eol=crlf *.txt text eol=crlf diff --git a/.gitignore b/.gitignore index 787b0b4..6eed6b3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,12 @@ -# compile artifcats +# compile artifcats *.o /bwbasic /renum - -# maintainer artifacts -editfl -editfl.bas -*.geany -*.orig -*.rej - +/autom4te.cache/ + +# maintainer artifacts +editfl +editfl.bas +*.geany +*.orig +*.rej diff --git a/BAS-EXAMPLES/abs.bas b/BAS-EXAMPLES/abs.bas new file mode 100644 index 0000000..e5267e5 --- /dev/null +++ b/BAS-EXAMPLES/abs.bas @@ -0,0 +1,5 @@ +100 rem ABS.BAS -- Test ABS() function +110 X = -1.23456789 +120 ABSX = ABS( X ) +130 print "The absolute value of "; X; " is"; ABSX +140 print "Is that correct?" diff --git a/BAS-EXAMPLES/alloff.inp b/BAS-EXAMPLES/alloff.inp new file mode 100644 index 0000000..66e4425 --- /dev/null +++ b/BAS-EXAMPLES/alloff.inp @@ -0,0 +1,2 @@ +ao +x diff --git a/BAS-EXAMPLES/allon.inp b/BAS-EXAMPLES/allon.inp new file mode 100644 index 0000000..2f448a1 --- /dev/null +++ b/BAS-EXAMPLES/allon.inp @@ -0,0 +1,9 @@ +1 +20 +1 +7 +1 +112 +1 +115 +x diff --git a/bas/assign.bas b/BAS-EXAMPLES/assign.bas similarity index 100% rename from bas/assign.bas rename to BAS-EXAMPLES/assign.bas diff --git a/BAS-EXAMPLES/bagels.bas b/BAS-EXAMPLES/bagels.bas new file mode 100644 index 0000000..3136955 --- /dev/null +++ b/BAS-EXAMPLES/bagels.bas @@ -0,0 +1,81 @@ +5 PRINT TAB(33);"BAGELS" +10 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY":PRINT:PRINT +15 REM *** BAGLES NUMBER GUESSING GAME +20 REM *** ORIGINAL SOURCE UNKNOWN BUT SUSPECTED TO BE +25 REM *** LAWRENCE HALL OF SCIENCE, U.C. BERKELY +30 DIM A1(6),A(3),B(3) +40 Y=0:T=255 +50 PRINT:PRINT:PRINT +70 INPUT "WOULD YOU LIKE THE RULES (YES OR NO)";A$ +90 IF LEFT$(A$,1)="N" THEN 150 +100 PRINT:PRINT "I AM THINKING OF A THREE-DIGIT NUMBER. TRY TO GUESS" +110 PRINT "MY NUMBER AND I WILL GIVE YOU CLUES AS FOLLOWS:" +120 PRINT " PICO - ONE DIGIT CORRECT BUT IN THE WRONG POSITION" +130 PRINT " FERMI - ONE DIGIT CORRECT AND IN THE RIGHT POSITION" +140 PRINT " BAGELS - NO DIGITS CORRECT" +150 FOR I=1 TO 3 +160 A(I)=INT(10*RND(1)) +165 IF I-1=0 THEN 200 +170 FOR J=1 TO I-1 +180 IF A(I)=A(J) THEN 160 +190 NEXT J +200 NEXT I +210 PRINT:PRINT "O.K. I HAVE A NUMBER IN MIND." +220 FOR I=1 TO 20 +230 PRINT "GUESS #";I, +240 INPUT A$ +245 IF LEN(A$)<>3 THEN 630 +250 FOR Z=1 TO 3:A1(Z)=ASC(MID$(A$,Z,1)):NEXT Z +260 FOR J=1 TO 3 +270 IF A1(J)<48 THEN 300 +280 IF A1(J)>57 THEN 300 +285 B(J)=A1(J)-48 +290 NEXT J +295 GOTO 320 +300 PRINT "WHAT?" +310 GOTO 230 +320 IF B(1)=B(2) THEN 650 +330 IF B(2)=B(3) THEN 650 +340 IF B(3)=B(1) THEN 650 +350 C=0:D=0 +360 FOR J=1 TO 2 +370 IF A(J)<>B(J+1) THEN 390 +380 C=C+1 +390 IF A(J+1)<>B(J) THEN 410 +400 C=C+1 +410 NEXT J +420 IF A(1)<>B(3) THEN 440 +430 C=C+1 +440 IF A(3)<>B(1) THEN 460 +450 C=C+1 +460 FOR J=1 TO 3 +470 IF A(J)<>B(J) THEN 490 +480 D=D+1 +490 NEXT J +500 IF D=3 THEN 680 +505 IF C=0 THEN 545 +520 FOR J=1 TO C +530 PRINT "PICO "; +540 NEXT J +545 IF D=0 THEN 580 +550 FOR J=1 TO D +560 PRINT "FERMI "; +570 NEXT J +580 IF C+D<>0 THEN 600 +590 PRINT "BAGELS"; +600 PRINT +605 NEXT I +610 PRINT "OH WELL." +615 PRINT "THAT'S TWNETY GUESSES. MY NUMBER WAS";100*A(1)+10*A(2)+A(3) +620 GOTO 700 +630 PRINT "TRY GUESSING A THREE-DIGIT NUMBER.":GOTO 230 +650 PRINT "OH, I FORGOT TO TELL YOU THAT THE NUMBER I HAVE IN MIND" +660 PRINT "HAS NO TWO DIGITS THE SAME.":GOTO 230 +680 PRINT "YOU GOT IT!!!":PRINT +690 Y=Y+1 +700 INPUT "PLAY AGAIN (YES OR NO)";A$ +720 IF LEFT$(A$,1)="YES" THEN 150 +730 IF Y=0 THEN 750 +740 PRINT:PRINT "A";Y;"POINT BAGELS BUFF!!" +750 PRINT "HOPE YOU HAD FUN. BYE." +999 END diff --git a/BAS-EXAMPLES/bin-to-dec.bas b/BAS-EXAMPLES/bin-to-dec.bas new file mode 100644 index 0000000..9d016b7 --- /dev/null +++ b/BAS-EXAMPLES/bin-to-dec.bas @@ -0,0 +1,24 @@ + 10 CALL SHELL("cls") + 100 LET P = 0 + : LET S = 0 + 110 INPUT "Enter binary number: ";N$ + 120 L = LEN (N$) + : IF L=0 GOTO 300 + 130 FOR I=1 TO L + 135 IF (N$ = "0") GOTO 1000 + 140 LET B$ = MID$(N$, L-I+1, 1) + 150 IF NOT (B$ = "0" OR B$ = "1") GOTO 300 + 160 LET K = VAL(B$) + 170 IF (K > 0) THEN + : S = S + 2 ^ P + : END IF + 180 LET P = P + 1 + 190 NEXT + 200 GOTO 310 + 300 PRINT "Error, invalid binary entered" + : GOTO 100 + 310 PRINT + 315 PRINT "Equals decimal ";S + 320 PRINT + 1000 END + diff --git a/BAS-EXAMPLES/binary.bas b/BAS-EXAMPLES/binary.bas new file mode 100644 index 0000000..3fc4a2f --- /dev/null +++ b/BAS-EXAMPLES/binary.bas @@ -0,0 +1,16 @@ + 5 REM input a number, output its binary representation + 10 CALL SHELL("cls") + 30 LET X = 0 + 40 LET P = 1 + 50 INPUT "Enter an integer from 1 to 63: ";a + 60 IF (A < 0 OR A<>INT(A)) GOTO 50 + 65 IF (A > 63) GOTO 30 + 70 LET B = A - INT (A/2) * 2 + 80 REM PRINT B + 90 LET X = B * P + X + 100 LET P = P * 10 + 110 LET A = (A - B) / 2 + 120 IF (A > 0) GOTO 70 + 130 PRINT "As binary: ";X + 140 END + diff --git a/BAS-EXAMPLES/bubble-numbers.bas b/BAS-EXAMPLES/bubble-numbers.bas new file mode 100644 index 0000000..9b1d72a --- /dev/null +++ b/BAS-EXAMPLES/bubble-numbers.bas @@ -0,0 +1,39 @@ + 10 REM BUBBLESORT NUMBERS + 80 CALL SHELL("cls") + 90 DIM A(8) + : REM ARRAY WITH MAX 8 ELEMENTS + 100 REM ASK FOR 8 NUMBERS + 105 PRINT "You will be asked for 8 numbers" + 110 FOR I = 1 TO 8 + 120 PRINT "TYPE NUMBER ";I;" : "; + 130 INPUT A (I) + 140 NEXT I + 150 REM PASS THROUGH 8 NUMBERS, TESTING BY PAIRS + 160 F = 0 + : REM RESET THE ORDER INDICATOR + 170 FOR I = 1 TO 7 + : REM NOTE THAT ENDING INDEX IS 8 MINUS 1 + 180 IF A(I) <= A(I+1) THEN + : GOTO 240 + : END IF + 190 REM SWAP A (I) AND A (I+1) + 200 T = A(I) + 210 A(I) = A(I+1) + 220 A(I+1) = T + 230 F = 1 + : REM ORDER WAS NOT PERFECT + 240 NEXT I + 250 REM F = 0 MEANS ORDER IS PERFECT + 260 IF F = 1 THEN + : GOTO 160 + : END IF + : REM TRY AGAIN + 270 PRINT + : REM PRINT EMPTY LINE + 280 REM PRINT ORDERED NUMBERS + 290 FOR I = 1 TO 8 + 300 PRINT A (I) + 310 NEXT I + 315 PRINT + 320 END + diff --git a/BAS-EXAMPLES/bubble-strings.bas b/BAS-EXAMPLES/bubble-strings.bas new file mode 100644 index 0000000..2d6bf76 --- /dev/null +++ b/BAS-EXAMPLES/bubble-strings.bas @@ -0,0 +1,37 @@ + 10 REM BUBBLESORT FOR STRINGS + 80 CALL SHELL("cls") + 90 DIM A$(8) + : REM ARRAY WITH 8 STRINGS + 100 REM ASK FOR 8 STRINGS + 105 PRINT "You will be asked for 8 strings" + 110 FOR I = 1 TO 8 + 120 PRINT "Type string ";I;" : "; + 130 INPUT A$ (I) + 140 NEXT I + 150 REM PASS THROUGH 8 STRINGS, TESTING BY PAIRS + 160 F = 0 + : REM RESET THE ORDER INDICATOR + 170 FOR I = 1 TO 7 + 180 IF A$(I) <= A$(I+1) THEN + : GOTO 240 + : END IF + 190 REM SWAP A$(I) AND A$(I+1) + 200 T$ = A$(I) + 210 A$(I) = A$(I+1) + 220 A$(I+1) = T$ + 230 F = 1 + : REM ORDER WAS NOT PERFECT + 240 NEXT I + 250 REM F = 0 MEANS ORDER IS PERFECT + 260 IF F = 1 THEN + : GOTO 160 + : END IF + : REM TRY AGAIN + 270 PRINT + : REM PRINT EMPTY LINE + 280 REM PRINT ORDERED STRINGS + 290 FOR I = 1 TO 8 + 300 PRINT A$ (I) + 310 NEXT I + 320 print + diff --git a/BAS-EXAMPLES/calendar.bas b/BAS-EXAMPLES/calendar.bas new file mode 100644 index 0000000..e6d1e41 --- /dev/null +++ b/BAS-EXAMPLES/calendar.bas @@ -0,0 +1,30 @@ +10 REM PERPETUAL GREGORIAN CALENDAR +12 REM 4-13-2020 changed line 28 IF Y<100 1900 to 2000 +14 DIM C$(42), D$(31), E(12) +16 FOR I=1 TO 31: READ D$(I): NEXT I +18 FOR I=1 TO 12: READ E(I): NEXT I +20 DATA " 1"," 2"," 3"," 4"," 5"," 6"," 7"," 8"," 9"," 10" +22 DATA " 11"," 12"," 13"," 14"," 15"," 16"," 17"," 18"," 19"," 20" +24 DATA " 21"," 22"," 23"," 24"," 25"," 26"," 27"," 28"," 29"," 30"," 31" +26 DATA 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 +28 PRINT: INPUT "MONTH, 4 DIGIT YEAR";M,Y: IF Y<100 THEN Y=Y+2000 +30 PRINT: PRINT " SU MO TU WE TH FR SA": PRINT +32 J=367*Y-INT(7*(Y+INT((M+9)/12))/4)+INT(275*M/9)+1721031 +34 K=0: IF M<=2 THEN K=-1 +36 J=J-INT(3*(INT((Y+K)/100)+1)/4) +38 K=E(M): IF M<>2 THEN 48 +40 W=INT(Y-100*INT(Y/100)): X=INT(Y-4*INT(Y/4)): Z=INT(Y-400*INT(Y/400)) +42 IF X<>0 THEN 48 +44 IF W=0 AND Z<>0 THEN 48 +46 K=29 +48 X=J-7*INT(J/7) +50 FOR I=1 TO 42: C$(I)=" ": NEXT I +52 FOR I=1 TO K: C$(I+X)=D$(I): NEXT I +54 FOR I=1 TO 6: J=7*I +56 PRINT C$(J-6);C$(J-5);C$(J-4);C$(J-3);C$(J-2);C$(J-1);C$(J) +58 NEXT I +60 PRINT: INPUT "ANOTHER";A$: IF (A$="Y" or A$="y") THEN 28 +62 END +63 REM --------------------------------------------------------------- +64 REM APPEARED IN ASTRONOMICAL COMPUTING, SKY & TELESCOPE, JULY, 1985 +65 REM --------------------------------------------------------------- diff --git a/bas/callfunc.bas b/BAS-EXAMPLES/callfunc.bas similarity index 100% rename from bas/callfunc.bas rename to BAS-EXAMPLES/callfunc.bas diff --git a/bas/callsub.bas b/BAS-EXAMPLES/callsub.bas similarity index 100% rename from bas/callsub.bas rename to BAS-EXAMPLES/callsub.bas diff --git a/bas/chain1.bas b/BAS-EXAMPLES/chain1.bas similarity index 100% rename from bas/chain1.bas rename to BAS-EXAMPLES/chain1.bas diff --git a/bas/chain2.bas b/BAS-EXAMPLES/chain2.bas similarity index 100% rename from bas/chain2.bas rename to BAS-EXAMPLES/chain2.bas diff --git a/BAS-EXAMPLES/comdiv.bas b/BAS-EXAMPLES/comdiv.bas new file mode 100644 index 0000000..2411fe3 --- /dev/null +++ b/BAS-EXAMPLES/comdiv.bas @@ -0,0 +1,18 @@ + 5 REM find greatest common divisor (Euclidean Algorithm) + 10 CALL SHELL("cls") + 20 LET A = 1071 + : LET B = 462 + 30 IF A < B THEN + : C = A + : A=B + : B=C + : END IF + 40 PRINT A,B + 50 LET C = A - INT(A/B)*B + : REM C = A MOD B (A modulo B) + 60 LET A = B + : B = C + 70 IF B > 0 GOTO 40 + 80 PRINT "GCG is ";A + 90 END + diff --git a/BAS-EXAMPLES/curve.bas b/BAS-EXAMPLES/curve.bas new file mode 100644 index 0000000..fa8aed9 --- /dev/null +++ b/BAS-EXAMPLES/curve.bas @@ -0,0 +1,12 @@ + 100 REM PLOT A NORMAL DISTRIBUTION CURVE + 120 DEF FNN(X) = EXP(-(X^2/2))/SQR(2*3.14159265) + 140 FOR X = -2 TO 2 STEP .1 + 150 LET Y = FNN(X) + 160 LET Y = INT(100*Y) + 170 FOR Z = 1 TO Y + 180 PRINT " "; + 190 NEXT Z + 200 PRINT "*" + 210 NEXT X + 220 END + diff --git a/bas/curve2.bas b/BAS-EXAMPLES/curve2.bas similarity index 94% rename from bas/curve2.bas rename to BAS-EXAMPLES/curve2.bas index cb6c78d..a65cdac 100644 --- a/bas/curve2.bas +++ b/BAS-EXAMPLES/curve2.bas @@ -1,4 +1,5 @@ 50 rem 12/13/2019 Ken curve + 60 SHELL "cls" 100 REM PLOT A NORMAL DISTRIBUTION CURVE 120 DEF FNN(X) = EXP(-(X^2/2))/SQR(2*3.14159265) 140 FOR X = -2 TO 2 STEP .1 diff --git a/BAS-EXAMPLES/data-read-new.bas b/BAS-EXAMPLES/data-read-new.bas new file mode 100644 index 0000000..bc21113 --- /dev/null +++ b/BAS-EXAMPLES/data-read-new.bas @@ -0,0 +1,30 @@ + 5 CALL SHELL("cls") + 10 ON ERROR GOSUB 80 + 20 C = 0 + : REM C will hold the number of data items + 25 PRINT "Reading data elements" + 30 READ N + 40 PRINT N + 50 C = C + 1 + 70 GOTO 30 + 80 print "Error line #, error number # ";erl;err + 90 PRINT "Read ";C;" data elements" + : INPUT "Press enter :";w + 100 DIM A(C) + : REM now we can allocate the array to hold all data + 110 RESTORE + : REM MOVE data pointer to start + 120 FOR I=1 TO C + 130 READ A(I) + 140 NEXT + 150 print + : print + 160 PRINT "Array:" + 170 FOR I=1 TO C + 180 PRINT A(I);" "; + 190 NEXT + 195 PRINT + 200 END + 1000 DATA 12,107,0,20,443,218,232,468,561 + 1010 DATA 71,187,936,436,4,50,110,320,120 + diff --git a/BAS-EXAMPLES/data-read.bas b/BAS-EXAMPLES/data-read.bas new file mode 100644 index 0000000..df3a42c --- /dev/null +++ b/BAS-EXAMPLES/data-read.bas @@ -0,0 +1,15 @@ +100 CALL SHELL("cls") +110 on error gosub 170 +120 C = 0 + : REM C will hold the number of data items +130 READ N +140 PRINT N +150 C = C + 1 +160 GOTO 130 +170 print "Error number #, line # "; err; " , ";erl +180 PRINT "Read ";C;" data elements" +185 end +190 DATA 12,107,0,20,443,218,232,468,561 +200 DATA 273,187,936,436,4,50,110,320,120 +210 DATA 45,670,87 + diff --git a/bas/dataread.bas b/BAS-EXAMPLES/dataread.bas similarity index 100% rename from bas/dataread.bas rename to BAS-EXAMPLES/dataread.bas diff --git a/BAS-EXAMPLES/dec-to-bin.bas b/BAS-EXAMPLES/dec-to-bin.bas new file mode 100644 index 0000000..deab180 --- /dev/null +++ b/BAS-EXAMPLES/dec-to-bin.bas @@ -0,0 +1,14 @@ + 5 REM input a number, output its binary representation + 10 CALL SHELL("cls") + 50 INPUT "Enter an integer greater than zero : ";A + 60 IF (A < 0 OR A<>INT(A)) GOTO 50 + 65 IF (A = 0) GOTO 140 + 70 LET B = A - INT (A/2) * 2 + 90 LET X$ = STR$(B) + X$ + 110 LET A = (A - B) / 2 + 120 IF (A > 0) GOTO 70 + 125 PRINT + 130 PRINT "As binary: ";X$ + 135 PRINT + 140 END + diff --git a/BAS-EXAMPLES/dec-to-hex.bas b/BAS-EXAMPLES/dec-to-hex.bas new file mode 100644 index 0000000..05a5ac4 --- /dev/null +++ b/BAS-EXAMPLES/dec-to-hex.bas @@ -0,0 +1,39 @@ + 10 CALL SHELL("cls") + 30 PRINT "DECIMAL","HEX" + 40 PRINT "-------","---" + 50 FOR I = 0 TO 20 + 60 LET A = I + 70 GOSUB 200 + 80 PRINT I, X$ + 90 NEXT I + 100 END + 200 LET X$ = "" + 210 LET B = A - INT (A/16) * 16 + 220 IF B < 10 THEN + : H$ = STR$(B) + : END IF + 230 IF B = 10 THEN + : H$ = " A" + : END IF + 240 IF B = 11 THEN + : H$ = " B" + : END IF + 250 IF B = 12 THEN + : H$ = " C" + : END IF + 260 IF B = 13 THEN + : H$ = " D" + : END IF + 270 IF B = 14 THEN + : H$ = " E" + : END IF + 280 IF B = 15 THEN + : H$ = " F" + : END IF + 290 LET X$ = H$ + X$ + 300 LET A = (A - B) / 16 + 310 IF (A > 0) THEN + : GOTO 210 + : END IF + 320 RETURN + diff --git a/BAS-EXAMPLES/dechex.bas b/BAS-EXAMPLES/dechex.bas new file mode 100644 index 0000000..5a2e1e2 --- /dev/null +++ b/BAS-EXAMPLES/dechex.bas @@ -0,0 +1,30 @@ + 10 REM this program prints decimal and corresponding hexadecimal numbers. + 15 REM it shows 20 numbers per page. To show the next page press any key. + 20 CALL SHELL("cls") + 30 LET S = 4095 + 50 PRINT "Decimal","Hex" + 60 PRINT "-------","---" + 70 FOR I = S to (20 + S) + 80 LET A = I + 90 GOSUB 200 + 100 PRINT I, X$ + 110 NEXT I + 130 LET S = S + 20 + 140 END + 150 END + 200 LET X$ = "" + 210 LET B = A - INT (A/16) * 16 + : REM B = A MOD 16 + 220 IF B < 10 THEN + : H$ = STR$(B) + : END IF + 230 IF (B >= 10 AND B <= 15) THEN + : H$ = " " + CHR$(65 + B - 10) + : END IF + 240 LET X$ = H$ + X$ + 250 LET A = (A - B) / 16 + 260 IF (A > 0) THEN + : GOTO 210 + : END IF + 270 RETURN + diff --git a/bas/deffn.bas b/BAS-EXAMPLES/deffn.bas similarity index 100% rename from bas/deffn.bas rename to BAS-EXAMPLES/deffn.bas diff --git a/bas/dim.bas b/BAS-EXAMPLES/dim.bas similarity index 100% rename from bas/dim.bas rename to BAS-EXAMPLES/dim.bas diff --git a/bas/doloop.bas b/BAS-EXAMPLES/doloop.bas similarity index 100% rename from bas/doloop.bas rename to BAS-EXAMPLES/doloop.bas diff --git a/bas/dowhile.bas b/BAS-EXAMPLES/dowhile.bas similarity index 100% rename from bas/dowhile.bas rename to BAS-EXAMPLES/dowhile.bas diff --git a/bas/eliza.bas b/BAS-EXAMPLES/eliza.bas similarity index 100% rename from bas/eliza.bas rename to BAS-EXAMPLES/eliza.bas diff --git a/bas/elseif.bas b/BAS-EXAMPLES/elseif.bas similarity index 100% rename from bas/elseif.bas rename to BAS-EXAMPLES/elseif.bas diff --git a/bas/end.bas b/BAS-EXAMPLES/end.bas similarity index 100% rename from bas/end.bas rename to BAS-EXAMPLES/end.bas diff --git a/bas/err.bas b/BAS-EXAMPLES/err.bas similarity index 100% rename from bas/err.bas rename to BAS-EXAMPLES/err.bas diff --git a/bas/factorials.bas b/BAS-EXAMPLES/factorials.bas similarity index 100% rename from bas/factorials.bas rename to BAS-EXAMPLES/factorials.bas diff --git a/BAS-EXAMPLES/fibonacci.bas b/BAS-EXAMPLES/fibonacci.bas new file mode 100644 index 0000000..f69ac08 --- /dev/null +++ b/BAS-EXAMPLES/fibonacci.bas @@ -0,0 +1,13 @@ + 5 REM Fibonacci numbers 4-13-2020 Ken + 7 CALL SHELL("cls") + 10 LET M = 5000 + 20 LET X = 1 : LET Y = 1 + 30 IF (X > M) GOTO 100 + 40 PRINT X + 50 X = X + Y + 60 IF (Y > M) GOTO 100 + 70 PRINT Y + 80 Y = X + Y + 90 GOTO 30 + 100 STOP + diff --git a/BAS-EXAMPLES/finance.bas b/BAS-EXAMPLES/finance.bas new file mode 100644 index 0000000..b4395ea --- /dev/null +++ b/BAS-EXAMPLES/finance.bas @@ -0,0 +1,191 @@ +10 L1=9 +20 DEF FNR(X)=INT(X*100+.5)/100 +30 CL$=CHR$(26):REM SCREEN CLEAR CHAR. +40 REM ******************************************************** +50 REM +60 PRINT CL$;"THIS PROGRAM IS A COLLECTION OF BUSINESS" +70 PRINT "APPLICATIONS. HERE IS A LIST OF THE VALUES THAT" +80 PRINT "CAN BE COMPUTED GIVEN SUPPORTING DATA:" +90 PRINT +100 PRINT "1) FUTURE VALUE OF AN INVESTMENT" +110 PRINT "2) FUTURE VALUE OF REGULAR DEPOSITS (ANNUITY)" +120 PRINT "3) REGULAR DEPOSITS" +130 PRINT "4) REGULAR DEPOSITS FROM AN INVESTMENT" +140 PRINT "5) INITIAL INVESTMENT" +150 PRINT "6) MINIMUM INVESTMENT FOR WITHDRAWALS" +160 PRINT "7) NOMINAL INTEREST RATE ON INVESTMENTS" +170 PRINT "8) EFFECTIVE INTEREST RATE ON INVESTMENTS" +180 PRINT "9) EARNED INTEREST TABLE" +190 PRINT +200 PRINT "WHICH OF THE ABOVE VALUES WOULD YOU LIKE" +210 PRINT "TO COMPUTE ( 1 TO";L1;", OR 0 TO END RUN )"; +220 INPUT X +230 PRINT CL$ +240 IF X=0 THEN 1860 +250 ON X GOSUB 270,360,470,590,690,800,910,1010,1150 +260 GOTO 90 +270 PRINT "FUTURE VALUE OF AN INVESTMENT" +280 PRINT:INPUT "INITIAL INVESTMENT (0 TO STOP) ";P:IF P=0 THEN RETURN +290 GOSUB 1130 +300 GOSUB 1140 +310 GOSUB 1110 +320 I=I/N/100 +330 T=P*(I+1)^(N*Y) +340 GOSUB 1100 +350 GOTO 280 +360 PRINT "FUTURE VALUE OF REGULAR DEPOSITS (ANNUITY)" +370 PRINT +380 INPUT "AMOUNT OF REGULAR DEPOSITS (0 TO STOP)";R +390 IF R=0 THEN RETURN +400 GOSUB 1130 +410 INPUT "NUMBER OF DEPOSITS PER YEAR";N +420 GOSUB 1110 +430 I=I/N/100 +440 T=R*((I+1)^(N*Y)-1)/I +450 GOSUB 1100 +460 GOTO 370 +470 PRINT "REGULAR DEPOSITS" +480 PRINT +490 INPUT "TOTAL VALUE AFTER Y YEARS (0 TO STOP) ";T +500 IF T=0 THEN RETURN +510 GOSUB 1130 +520 DEF FNR(X)=INT(X*100+.5)/100 +530 INPUT "NUMBER OF DEPOSITS PER YEAR";N +540 GOSUB 1110 +550 I=I/N/100 +560 R=T*I/((I+1)^(N+Y)-1) +570 PRINT "REGULAR DEPOSITS: $";INT(R*100+.5)/100 +580 GOTO 480 +590 PRINT "REGULAR WITHDRAWALS FROM AN INVESTMENT" +600 PRINT:INPUT"INITIAL INVESTMENT (0 TO STOP) ";P +610 IF P=0 THEN RETURN +620 GOSUB 1130 +630 INPUT "NUMBER OF WITHDRAWALS PER YEAR";N +640 GOSUB 1110 +650 I=I/N/100 +660 R=P*(I/((I+1)^(N*Y)-1)+I) +670 PRINT "AMOUNT OF EACH WITHDRAWAL = $";INT(R*100+.5)/100 +680 GOTO 600 +690 PRINT "INITIAL INVESTMENT" +700 PRINT +710 INPUT "TOTAL VALUE AFTER Y YEARS (0 TO STOP) ";T +720 IF T=0 THEN RETURN +730 GOSUB 1140 +740 GOSUB 1110 +750 GOSUB 1130 +760 I=I/N/100 +770 P=T/(I+1)^(N*Y) +780 PRINT "INITIAL INVESTMENT = $";INT(P*100+.5)/100 +790 GOTO 700 +800 PRINT "MINIMUM INVESTMENT FOR WITHDRAWALS" +810 PRINT +820 INPUT "AMOUNT OF WITHDRAWALS (0 TO STOP) ";R +830 IF R=0 THEN RETURN +840 GOSUB 1130 +850 INPUT "NUMBER OF WITHDRAWALS PER YEAR";N +860 GOSUB 1110 +870 I=I/100 +880 P=R*N/I*(1-1/((1+I/N)^(N*Y))) +890 PRINT "MINIMUM INVESTMENT = $";INT(100*P+.5)/100 +900 GOTO 810 +910 PRINT "NOMINAL INTEREST RATE ON INVESTMENTS" +920 PRINT +930 INPUT "PRINCIPAL (0 TO STOP)";P +940 IF P=0 THEN RETURN +950 INPUT "TOTAL VALUE";T +960 GOSUB 1110 +970 GOSUB 1140 +980 I2=N*((T/P)^(1/(N*Y))-1)*100 +990 PRINT "NOMINAL INTEREST RATE = ";I2;"%" +1000 GOTO 920 +1010 PRINT "EFFECTIVE INTEREST RATE ON INVESTMENTS" +1020 PRINT +1030 INPUT "INITIAL INVESTMENT (0 TO STOP) ";P +1040 IF P=0 THEN RETURN +1050 INPUT "TOTAL VALUE AFTER Y YEARS";T +1060 GOSUB 1110 +1070 PRINT "ANNUAL INTEREST RATE = ";((T/P)^(1/Y)-1)*100;"%" +1080 GOTO 1020 +1090 REM ******* +1100 PRINT "FUTURE VALUE = $"; INT(T*100+.5)/100:RETURN +1110 INPUT "NUMBER OF YEARS AND MONTHS (2 NUMBERS WITH A COMMA BETWEEN THEM)";Y0,M +1120 Y=(12*Y0+M)/12:RETURN +1130 INPUT "NOMINAL INTEREST RATE (0 TO 100) ";I:RETURN +1140 INPUT "NUMBER OF COMPOUNDING PERIODS PER YEAR";N:RETURN +1150 PRINT "**** EARNED INTEREST TABLE GENERATOR ***" +1160 PRINT +1170 INPUT "PRINCIPAL";P +1180 GOSUB 1130 +1190 I=I/100 +1200 INPUT "NUMBER OF DEPOSITS/WITHDRAWALS PER YEAR";N1 +1210 IF N1=0 THEN 1260 +1220 INPUT "AMOUNT OF DEPOSIT/WITHDRAWAL";R +1230 N=360 +1240 L2=N1 +1250 GOTO 1290 +1260 GOSUB 1140 +1270 N1=0 +1280 L2=4 +1290 INPUT "START WITH WHAT YEAR (WHERE 1 MEANS THE FIRST, 2 THE SECOND, ETC.) ";X +1300 INPUT "END WITH WHAT YEAR";Y +1310 X=INT(X) +1320 B0=P:I1=0:I2=0:I3=0:K=66:P1=4 +1330 FOR J0=1 TO INT(Y)+1 +1340 IF J0N1 THEN 1590 +1560 IF N2/N1>J1/N THEN 1590 +1570 B0=B0+R +1580 N2=N2+1 +1590 B2=B0*(1+I/N) +1600 I1=B2-B0 +1610 I3=I3+I1 +1620 I2=I2+I1 +1630 IF P2/P1>J1/N THEN 1670 +1640 I2=FNR(I2) +1650 B2=FNR(B2) +1660 P2=P2+1 +1670 IF J0=Y THEN 1820 +1770 NEXT J1 +1780 IF J0=R THEN 100 +150 PRINT TAB(30);"$";INT((B*1)*100)/100;TAB(45);"$";INT((R-B*I)*100)/100 +155 PRINT +160 PRINT PA+1;"LAST PAYMENT =";TAB(30);"$";INT((B*I+B)*100)/100 +170 PRINT +180 PRINT +190 PRINT +200 END diff --git a/BAS-EXAMPLES/intrate.bas b/BAS-EXAMPLES/intrate.bas new file mode 100644 index 0000000..da0c06d --- /dev/null +++ b/BAS-EXAMPLES/intrate.bas @@ -0,0 +1,60 @@ +5 REM 12/16/2919 MINOR CORRECTIONS Ken intrate +10 K=0:T0=0:T1=0 +20 INPUT "INTEREST RATE (%) ",I2 +30 J=I2/1200 +40 INPUT "TERM IN MONTHS " ,N +50 D=1-(1+J)^(-N) +60 R=1000*J/D +70 P=9.9995E-03 +80 F=R+P +90 F=(INT(F*100)/100) +100 PRINT "RATE PER $1000 = $", +110 PRINT USING "#####.##";F ' %7F2 +120 INPUT "AMOUNT OF MORTGAGE ",Z +130 INPUT "PAYMENT IF KNOWN, ELSE 0 ",B +140 IF B>0 THEN 190 +150 B=(Z/1000)*F +160 INPUT "DO YOU WANT PAYMENT IN EVEN DOLLARS ",Y$ +170 IF Y$="N" THEN 190 ' IF Y$(1,1) ="N" THEN 190 +175 IF Y$="n" THEN 190 ' IF Y$(1,1) ="n" THEN 190 +180 B=INT (B+.99) +190 PRINT "MONTHLY PAYMENT = $", +200 PRINT USING "#####.##";B ' %7F2 +210 INPUT "DO YOU WANT TO AMORTIZE THIS LOAN ",Y$ +220 IF Y$="N" THEN 10 ' IF Y$(1,1)="N" THEN 10 +225 IF Y$="n" THEN 10 ' IF Y$(1,1)="n" THEN 10 +230 INPUT "DO YOU WANT DETAIL DISPLAYED ",Y$ +240 IF Y$="N" THEN S=1 ELSE S=0 ' IF Y$(1,1) ="N" THEN S=1 ELSE S=0 +245 IF Y$="n" THEN S=1 ELSE S=0 ' IF Y$(1,1) ="n" THEN S=1 ELSE S=0 +250 IF S=1 THEN 280 +260 INPUT "DISPLAY INTERVAL ",D1 +270 INPUT "DISPLAY START PERIOD ",D2 +280 PRINT "PMT# BALANCE INT PRIN RED PER INT TOT INT" +290 I1=J*Z +300 I1=I1+5E-03:I1=(INT(I1*100)/100) +310 T0=T0+I1:T1=T1+I1 +320 P1=Z +330 Q=B-I1 +340 Z=Z-Q +350 X=P1:Y=Q:X=X-Y +360 IF X>0 THEN 380 +370 Z=0:B=P1+I1:Q=B-I1 +380 K=K+1 +390 IF S=1 THEN 460 +400 IF K<>D1+D2 THEN 420 +410 PRINT USING "###";K, ' %3I +420 IF K K THEN 460 ELSE D2=D2+D1 +440 PRINT USING "#######.##";Z,I1,Q,T0,T1 ' %9F2 +450 T0=0 +460 IF Z>0 THEN 290 +470 PRINT:PRINT "FINAL TOTALS":PRINT +480 PRINT USING "###";K, ' %3I +490 PRINT USING "#######.##";Z,I1,Q,T0,T1 ' %9F2 +500 PRINT "LAST PAYMENT = $",: PRINT USING "#####.##";B ' %7F2 +510 STOP +600 REM --------------------------------------------------- +610 REM Changed %... to PRINT USING "#" +620 REM Changed Y$(1,1) to Y$ +699 END + diff --git a/bas/lof.bas b/BAS-EXAMPLES/lof.bas similarity index 100% rename from bas/lof.bas rename to BAS-EXAMPLES/lof.bas diff --git a/bas/loopuntl.bas b/BAS-EXAMPLES/loopuntl.bas similarity index 100% rename from bas/loopuntl.bas rename to BAS-EXAMPLES/loopuntl.bas diff --git a/bas/main.bas b/BAS-EXAMPLES/main.bas similarity index 100% rename from bas/main.bas rename to BAS-EXAMPLES/main.bas diff --git a/bas/mlifthen.bas b/BAS-EXAMPLES/mlifthen.bas similarity index 100% rename from bas/mlifthen.bas rename to BAS-EXAMPLES/mlifthen.bas diff --git a/BAS-EXAMPLES/ohmslaw.bas b/BAS-EXAMPLES/ohmslaw.bas new file mode 100644 index 0000000..ac86ff7 --- /dev/null +++ b/BAS-EXAMPLES/ohmslaw.bas @@ -0,0 +1,311 @@ +5 REM - COMPACTED:6/08/84 +7 REM - Removed LPRINT references 4-13-2020 Ken +10 PRINT " -=*OHM'S LAW*=-" +40 PRINT " MENU" +50 PRINT:PRINT TAB(10);"(1) Find I, given VOLTAGE and RESISTANCE (E and R)" +70 PRINT TAB(10);"(2) Find R, given VOLTAGE and CURRENT (V and I)" +90 PRINT TAB(10);"(3) Find E, given CURRENT and RESISTANCE (I and R)" +110 PRINT TAB(10);"(4) Find P (POWER), given VOLTAGE and CURRENT (E and I)" +130 PRINT TAB(10);"(5) Find P (POWER), given CURRENT and RESISTANCE (I and R)" +150 PRINT TAB(10);"(6) Find P (POWER), given VOLTAGE and RESISTANCE (E and R)" +170 PRINT TAB(10);"(7) Find two resistances in parallel, given R1 and R2" +190 PRINT TAB(10);"(8) Find RT, given unequal R1, R2, R3, R4 in parallel" +270 PRINT TAB(10);"(9) Find RT, given R1,R2,R3,R4 in SERIES-PARALLEL" +290 PRINT TAB(10);"(10) Find TOTAL CAPACITANCE (CT), in series circuit" +310 PRINT TAB(10);"(11) Find TOTAL CAPACITANCE (CT), 2 caps, parallel circuit" +330 PRINT TAB(10);"(12) Find TOTAL CAPACITANCE (CT), 3 caps in parallel" +350 PRINT TAB(10);"(13) Find PEAK AC VOLTAGE, given RMS value" +370 PRINT TAB(10);"(14) Find RMS VOLTAGE, given PEAK value" +390 PRINT TAB(10);"(15) Find INDUCTIVE REACTANCE (XL)" +410 PRINT TAB(10);"(16) Find CAPACITIVE REACTANCE (XC)" +430 PRINT TAB(10);"(17) Find IMPEDANCE (Z) of a series circuit" +445 PRINT TAB(10);"(18) Find IMPEDANCE (Z) of a parallel circuit" +447 PRINT +450 PRINT " Select the number you require from the menu and press 'RETURN'" +485 PRINT +490 INPUT "Caps Lock ON. Enter choice from above or -1 to exit :",C +515 IF C = -1 THEN END +517 PRINT "Choice is:";C +520 IF C= 0 OR C> 18 THEN 10 +530 ON C GOTO 540,710,880,1050,1220,1380,1540,1700,1930,2190,2360,2560,2770,2930,3070,3260,3430,3680 +540 PRINT "Calculate CURRENT (I), given VOLTAGE and RESISTANCE (E and R)" +555 PRINT +560 INPUT "What is the value of E, in volts:",V +580 INPUT "Now enter the value of R, in ohms:",R +600 LET I= (V/R) +610 PRINT " I= ";(V/R);"amperes" +630 PRINT +640 PRINT " Do you wish to do this calculation again? (Y/N)":INPUT ANS$ +660 IF ANS$="Y" THEN 540 +670 PRINT "Do you wish to return to the menu? (Y/N)":INPUT ANS$ +690 IF ANS$="Y" THEN 10 +700 GOTO 10020 +710 PRINT "Calculate RESISTANCE (R), given VOLTAGE and CURRENT (E and I)" +730 PRINT:PRINT +740 INPUT "Input the value of E, in volts:",V +760 INPUT "Now enter the value of I, in amperes:",I +780 LET R=(V/I):PRINT "R= ";(V/I);"ohms" +800 PRINT +810 PRINT "Do you wish to do this calculation again? (Y/N)":INPUT ANS$ +830 IF ANS$="Y" THEN 710 +835 PRINT +840 PRINT "Do you wish to return to the menu? (Y/N)":INPUT ANS$ +860 IF ANS$="Y" THEN 10 +870 GOTO 10020 +875 PRINT +880 PRINT "Calculate VOLTAGE (E), given CURRENT and RESISTANCE (I and R)" +895 PRINT +900 INPUT "Enter the value for I, in amperes:",I +920 INPUT "Now enter the value for R, in ohms:",R +940 LET E=(I*R):PRINT "E= ";(I*R);"volts" +960 PRINT +970 PRINT "Do you wish to do this calculation again? (Y/N)":INPUT ANS$ +990 IF ANS$="Y" THEN 880 +995 PRINT +1000 PRINT "Do you wish to return to the menu? (Y/N)":INPUT ANS$ +1020 IF ANS$="Y" THEN 10 +1030 GOTO 10020 +1040 PRINT +1050 PRINT "Calculate POWER(P), given VOLTAGE(E) and CURRENT(I)" +1065 PRINT +1070 INPUT "Input the value for E, in volts:",V +1090 INPUT "Now enter the value for I, in amperes:",I +1110 LET P=V*I:PRINT "I= ";(V*I);"watts" +1130 PRINT +1140 PRINT "Do you wish to do this calculation again? (Y/N)":INPUT ANS$ +1160 IF ANS$="Y" THEN 1050 +1175 PRINT +1180 PRINT "Do you wish to return to the menu? (Y/N)":INPUT ANS$ +1200 IF ANS$="Y" THEN 10 +1210 GOTO 10020 +1220 PRINT "Calculate POWER(P), given CURRENT(I) and RESISTANCE(R)" +1235 PRINT +1240 INPUT "Enter the value for I, in amperes:",I +1260 INPUT "Now enter the value for R, in ohms:",R +1280 LET P=(I*I)*R:PRINT "P= ";(I*I)*R;"watts" +1300 PRINT +1310 PRINT "Do you wish to do this calculation again? (Y/N)":INPUT ANS$ +1330 IF ANS$="Y" THEN 1220 +1335 PRINT +1340 PRINT "Do you wish to return to the menu? (Y/N)":INPUT ANS$ +1360 IF ANS$="Y" THEN 10 +1370 GOTO 10020 +1380 PRINT "Calculate POWER(P), given VOLTAGE(E) and RESISTANCE(R)" +1385 PRINT +1400 INPUT "Enter the value for E, in volts:",V +1420 INPUT "Now enter the value for R, in ohms:",R +1440 LET P=(V*V)/(R):PRINT "P= ";(V*V)/(R);"watts" +1460 PRINT +1470 PRINT "Do you wish to do this calculation again ? (Y/N)":INPUT ANS$ +1490 IF ANS$="Y" THEN 1380 +1495 PRINT +1500 PRINT "Do you wish to return to the menu? (Y/N)":INPUT ANS$ +1520 IF ANS$="Y" THEN 10 +1530 GOTO 10020 +1535 PRINT +1540 PRINT "Calculate TOTAL RESISTANCE(RT) in parallel, given R1,R2" +1555 PRINT +1560 INPUT "Input the value for R1:",R1 +1580 INPUT "Now input the value for R2:",R2 +1600 LET RT= (R1*R2)/(R1+R2):PRINT "RT= ";(R1*R2)/(R1+R2);"ohms" +1620 PRINT +1630 PRINT "Do you wish to do this calculation again? (Y/N)":INPUT ANS$ +1650 IF ANS$="Y" THEN 1540 +1655 PRINT +1660 PRINT "Do you wish to return to the menu? (Y/N)":INPUT ANS$ +1680 IF ANS$="Y" THEN 10 +1690 GOTO 10020 +1695 PRINT +1700 PRINT "Calculate TOTAL RESISTANCE(RT), given unequal R1,R2,R3,R4 values" +1715 PRINT +1720 PRINT "Enter the values for R1,R2,R3 and R4, in ohms" +1740 INPUT "R1=",R1 +1750 INPUT "R2=",R2 +1760 INPUT "R3=",R3 +1770 INPUT "R4=",R4 +1780 PRINT "R1=";R1;"ohms" +1790 PRINT "R2=";R2;"ohms" +1800 PRINT "R3=";R3;"ohms" +1810 PRINT "R4=";R4;"ohms" +1820 LET RT=(1)/(1/R1+1/R2+1/R3+1/R4) +1830 PRINT "RT= ";(1)/(1/R1+1/R2+1/R3+1/R4);"ohms" +1850 PRINT +1860 PRINT "Do you wish to do this calculation again? (Y/N)":INPUT ANS$ +1880 IF ANS$="Y" THEN 1700 +1885 PRINT +1890 PRINT "Do you wish to return to the menu? (Y/N)":INPUT ANS$ +1910 IF ANS$="Y" THEN 10 +1920 GOTO 10020 +1925 PRINT +1930 PRINT "Calculate TOTAL RESISTANCE(RT), in series-parallel," +1940 PRINT "given R1, R2, R3 and R4" +1965 PRINT +1970 PRINT "Enter the values for R1, R2, R3 and R4" +1990 INPUT "R1=",R1 +2000 INPUT "R2=",R2 +2010 INPUT "R3=",R3 +2020 INPUT "R4=",R4 +2030 PRINT "R1=";R1;"ohms" +2040 PRINT "R2=";R2;"ohms" +2050 PRINT "R3=";R3;"ohms" +2060 PRINT "R4=";R4;"ohms" +2070 PRINT +2080 LET RT=(1)/(1/(R1+R2))+(1/(R3+R4)) +2090 PRINT "RT=";(1)/(1/(R1+R2))+(1/(R3+R4));"ohms" +2110 PRINT +2120 PRINT "Do you wish to do this calculation again? (Y/N)":INPUT ANS$ +2140 IF ANS$="Y" THEN 1930 +2145 PRINT +2150 PRINT "Do you wish to return to the menu? (Y/N)":INPUT ANS$ +2170 IF ANS$="Y" THEN 10 +2180 GOTO 10020 +2185 PRINT +2190 PRINT "Calculate TOTAL CAPACITANCE(CT), in series circuit, given C1 and C2" +2205 PRINT +2210 INPUT "Enter value for C1, in MFD:",C1 +2220 INPUT "Now enter the value for C2, in MFD:",C2 +2240 PRINT "C1=";C1;"mfd" +2250 PRINT "C2=";C2;"mfd" +2260 LET CT=(C1*C2)/(C1+C2):PRINT "CT=";(C1*C2)/(C1+C2);"mfd" +2280 PRINT +2290 PRINT "Do you wish to do this calculation again? (Y/N)":INPUT ANS$ +2310 IF ANS$="Y" THEN 2190 +2315 PRINT +2320 PRINT "Do you wish to return to the menu? (Y/N)":INPUT ANS$ +2340 IF ANS$="Y" THEN 10 +2350 GOTO 10020 +2355 PRINT +2360 PRINT "Calculate TOTAL CAPACITANCE(CT), parallel circuit, given C1 and C2" +2395 PRINT +2400 INPUT "Enter the value for C1, in mfd:",C1 +2420 INPUT "Now enter the value for C2, in mfd:",C2 +2440 PRINT "C1=";C1;"mfd" +2450 PRINT "C2=";C2;"mfd" +2460 LET CT=(C1*C2)/(C1+C2):PRINT "CT=";(C1*C2)/(C1+C2);"mfd" +2480 PRINT +2490 PRINT "Do you wish to do this calculation again? (Y/N)":INPUT ANS$ +2510 IF ANS$="Y" THEN 2360 +2515 PRINT +2520 PRINT "Do you wish to return to the menu? (Y/N)":INPUT ANS$ +2540 IF ANS$="Y" THEN 10 +2550 GOTO 10020 +2555 PRINT +2560 PRINT "Calculate TOTAL CAPACITANCE(CT) for a parallel circuit," +2570 PRINT "given C1, C2 and C3, in mfd" +2595 PRINT +2600 INPUT "C1=",C1 +2610 INPUT "C2=",C2 +2620 INPUT "C3=",C3 +2630 PRINT "C1=";C1;"mfd" +2640 PRINT "C2=";C2;"mfd" +2650 PRINT "C3=";C3;"mfd" +2660 PRINT +2670 LET CT=(C1+C2+C3):PRINT "CT=";(C1+C2+C3);"mfd" +2690 PRINT +2700 PRINT "D0 you wish to do this calculation again? (Y/N)":INPUT ANS$ +2720 IF ANS$="Y" THEN 2560 +2725 PRINT +2730 PRINT "Do you wish to return to the menu? (Y/N)":INPUT ANS$ +2750 IF ANS$="Y" THEN 10 +2760 GOTO 10020 +2765 PRINT +2770 PRINT "Calculate PEAK AC VOLTAGE, given RMS value" +2785 PRINT +2790 INPUT "Enter the RMS value, in volts:",RMS +2810 PRINT "RMS=";RMS;"volts" +2820 LET PEAK=(RMS*1.414):PRINT "PEAK=";(RMS*1.414);"volts" +2840 PRINT +2850 PRINT "Do you wish to do this calculation again? (Y/N)":INPUT ANS$ +2870 IF ANS$="Y" THEN 2770 +2875 PRINT +2880 PRINT "Do you wish to return to the menu? (Y/N)":INPUT ANS$ +2900 IF ANS$="Y" THEN 10 +2910 GOTO 10020 +2920 PRINT +2930 PRINT "Calculate RMS VOLTAGE, given a value in PEAK VOLTS" +2945 PRINT +2950 INPUT "Enter the PEAK value, in volts AC:",PEAK +2960 PRINT "PEAK VOLTS=";PEAK +2970 LET RMS=(.707*PEAK):PRINT "RMS=";(.707*PEAK);"volts AC" +3000 PRINT "Do you wish to do this calculation again? (Y/N)":INPUT ANS$ +3020 IF ANS$="Y" THEN 2930 +3025 PRINT +3030 PRINT "Do you wish to return to the menu? (Y/N)":INPUT ANS$ +3050 IF ANS$="Y" THEN 10 +3060 GOTO 10020 +3065 PRINT +3070 PRINT "Calculate INDUCTIVE REACTANCE (XL), given FREQUENCY and INDUCTANCE" +3090 PRINT +3100 INPUT "Enter FREQUENCY (F), in Hertz:",FREQ +3120 PRINT "FREQUENCY=";FREQ;"Hertz +3130 INPUT "Now enter the value for INDUCTANCE (L), in henrys:",L +3150 PRINT "INDUCTANCE=";L;"henrys" +3160 LET XL=(2*3.1416)*FREQ*L:PRINT "XL=";(2*3.1416)*FREQ*L;"ohms" +3180 PRINT +3190 PRINT "Do you wish to do this calculation again? (Y/N)":INPUT ANS$ +3210 IF ANS$="Y" THEN 3070 +3215 PRINT +3220 PRINT "Do you wish to return to the menu? (Y/N)":INPUT ANS$ +3240 IF ANS$="Y" THEN 10 +3245 GOTO 10020 +3250 PRINT +3260 PRINT "Calculate CAPACITIVE REACTANCE (XC), given FREQ(F) and CAP(C)" +3275 PRINT +3280 INPUT "Enter the value for FREQ(F), in Hertz:",F +3290 PRINT "FREQ(F)=";F;"Hertz" +3300 INPUT "Now enter the value for CAP(C), in mfd:",C +3310 PRINT "CAP(C)=";C;"mfd" +3320 PRINT +3330 LET XC=(1)/((2*3.1416)*F*C):PRINT "XC=";(1)/((2*3.1416)*F*C);"ohms" +3350 PRINT +3360 PRINT "Do you wish to do this calculation again? (Y/N)":INPUT ANS$ +3380 IF ANS$="Y" THEN 3260 +3385 PRINT +3390 PRINT "Do you wish to return to the menu? (Y/N)":INPUT ANS$ +3410 IF ANS$="Y" THEN 10 +3415 GOTO 10020 +3420 PRINT +3430 PRINT "Calculate IMPEDANCE(Z) of a series circuit, given values of" +3435 PRINT "RES(R), CAPACITIVE REACTANCE(XC) and INDUCTIVE REACTANCE(XL)" +3446 PRINT +3450 INPUT "Enter the value for RESISTANCE(R), in ohms:",R +3470 INPUT "Enter the value for CAPACITIVE REACTANCE(XC), in ohms:",XC +3490 INPUT "Enter the value for INDUCTIVE REACTANCE(XL), in ohms:",XL +3510 PRINT +3520 PRINT "RESISTANCE(R)=";R;"ohms" +3530 PRINT "CAPACITIVE REACTANCE(XC)=";XC;"ohms" +3540 PRINT "INDUCTIVE REACTANCE(XL)=";XL;"ohms" +3550 PRINT +3560 LET Z=SQR(R^2+((XL-XC)^2)) +3570 PRINT "IMPEDANCE(Z)=";SQR(R^2+((XL-XC)^2));"ohms" +3590 PRINT +3600 PRINT "Do you wish to do this calculation again? (Y/N)":INPUT ANS$ +3620 IF ANS$="Y" THEN 3430 +3625 PRINT +3630 PRINT "Do you wish to return to the menu? (Y/N)":INPUT ANS$ +3650 IF ANS$="Y" THEN 10 +3660 GOTO 10020 +3670 PRINT +3680 PRINT "Calculate IMPEDANCE (Z) of a parallel circuit" +3700 PRINT +3710 INPUT "Enter the value of L, in henrys:",L +3730 INPUT "Enter the value for FREQ (F), in Hertz:",F +3750 INPUT "Now enter the value for RESISTANCE (R) in ohms:",R +3765 PRINT "INDUCTANCE (L)=";L;"henrys" +3770 PRINT "FREQ (F)=";F;" Hertz" +3775 PRINT "RESISTANCE (R)=";R;"ohms" +3776 PRINT +3780 LET Z=((2*3.1416*F*L)^2)/(R) +3790 PRINT "IMPEDANCE (Z)=";((2*3.1416*F*L)^2)/(R);"ohms" +3810 PRINT "Do you wish to do this calculation again? (Y/N)":INPUT ANS$ +3830 IF ANS$="Y" THEN 3680 +3840 PRINT +3850 PRINT "Do you wish to return to the menu? (Y/N)":INPUT ANS$ +3870 IF ANS$="Y" THEN 10 +3880 GOTO 10020 +3890 PRINT +10020 PRINT "Glad to have been of service! BYE!! +12000 REM -------------------------------------------------------------------------- +12010 REM Change line number 0 to line number 5 +12020 REM For automated testing, added 515 IF C = -1 THEN END +12999 END diff --git a/bas/on.bas b/BAS-EXAMPLES/on.bas similarity index 100% rename from bas/on.bas rename to BAS-EXAMPLES/on.bas diff --git a/bas/onerr.bas b/BAS-EXAMPLES/onerr.bas similarity index 100% rename from bas/onerr.bas rename to BAS-EXAMPLES/onerr.bas diff --git a/bas/onerrlbl.bas b/BAS-EXAMPLES/onerrlbl.bas similarity index 100% rename from bas/onerrlbl.bas rename to BAS-EXAMPLES/onerrlbl.bas diff --git a/bas/ongosub.bas b/BAS-EXAMPLES/ongosub.bas similarity index 100% rename from bas/ongosub.bas rename to BAS-EXAMPLES/ongosub.bas diff --git a/bas/opentest.bas b/BAS-EXAMPLES/opentest.bas similarity index 100% rename from bas/opentest.bas rename to BAS-EXAMPLES/opentest.bas diff --git a/bas/option.bas b/BAS-EXAMPLES/option.bas similarity index 100% rename from bas/option.bas rename to BAS-EXAMPLES/option.bas diff --git a/bas/pascaltr.bas b/BAS-EXAMPLES/pascaltr.bas similarity index 100% rename from bas/pascaltr.bas rename to BAS-EXAMPLES/pascaltr.bas diff --git a/BAS-EXAMPLES/primes.bas b/BAS-EXAMPLES/primes.bas new file mode 100644 index 0000000..dfbdf3a --- /dev/null +++ b/BAS-EXAMPLES/primes.bas @@ -0,0 +1,11 @@ +20 PRINT "LIMIT"; +30 INPUT L +40 FOR N = 3 TO L +50 FOR D = 2 TO (N-1) +60 IF N/D=INT(N/D) THEN GOTO 100 +70 NEXT D +80 PRINT N; +90 GOTO 110 +100 PRINT "."; +110 NEXT N +120 END diff --git a/BAS-EXAMPLES/profile.bas b/BAS-EXAMPLES/profile.bas new file mode 100644 index 0000000..d5d2df0 --- /dev/null +++ b/BAS-EXAMPLES/profile.bas @@ -0,0 +1,5 @@ +OPTION TERMINAL ANSI +OPTION EDIT "nano" +OPTION DISABLE COMMAND "renum" +OPTION RENUM "" + diff --git a/bas/putget.bas b/BAS-EXAMPLES/putget.bas similarity index 100% rename from bas/putget.bas rename to BAS-EXAMPLES/putget.bas diff --git a/bas/random.bas b/BAS-EXAMPLES/random.bas similarity index 100% rename from bas/random.bas rename to BAS-EXAMPLES/random.bas diff --git a/BAS-EXAMPLES/relays.bas b/BAS-EXAMPLES/relays.bas new file mode 100644 index 0000000..d547352 --- /dev/null +++ b/BAS-EXAMPLES/relays.bas @@ -0,0 +1,250 @@ + 2 rem Relays control program in bwbasic 3.2 4-18-2020 ken.at.github@gmail.com + 3 rem 4-18-2020 Added hardware check. Error traps and help. + 4 rem As of 4-13-2020 Debian apt get install bwbasic installs an old 2.2. + 5 rem Assumes bwbasic 3.2. bwbasic 2.2 has issues see changelog. + 6 rem Download bwbasic-3.2a.tar file. Untar then cd bwbasic-3.2a then + 7 rem make then sudo make install to uninstall sudo make remove + 8 rem Set terminal to ANSI mode. Linux and Windows. Only 3.2 or newer + 10 option terminal ANSI + 11 call cls + : rem Clear screen on initial startup. Only 3.2 or newer + 12 call close + : rem Close any open files. Again 3.2 or newer. + 13 rem Trap errors + 14 on error gosub 10000 + 15 gosub 9000 + : rem Get Dogtag & Model & see if it's allowable hardware. + 16 print + : print "=== Relay games on ";DATE$;" at ";TIME$;" ===" + : print " ";d$ + 17 print " ";o$ + 18 print + 24 rem b$ = Base address as of Beaglebone Black Debian 10.3 3-26-2020 + 25 let b$="/sys/class/gpio/gpio" + 50 print "0 Off, 1 On, s State, sa State All,"; + 52 print " ao All Off, l Label, h for Help or x Exit "; + : input m$ + 60 IF m$ = "0" or m$ = "1" or m$ = "l" or m$ = "s" then + : goto 70 + : END IF + 63 IF m$ = "x" or m$ = "e" then + : system + : END IF + : rem Stop program. Exit to system. + 64 IF m$ = "sa" then + : print + : print "Currently:" + : gosub 500 + : goto 16 + : END IF + : rem State all + 65 IF m$ = "ao" then + : print + : print "Was:" + : gosub 500 + : print "Now:" + : gosub 600 + : goto 16 + : END IF + 66 IF m$ = "q" then + : print "Bye" + : stop + : END IF + : rem Stop program + 67 IF m$ = "h" then + : gosub 1000 + : goto 16 + : END IF + 68 print "Mode error. Only 0, 1, s, l, ao All Off, sa State All "; + 69 print "h Help or x allowed" + : goto 50 + 70 print "Relay # = gpio: 1 = 20, 2 = 7, 3 = 112, 4 = 115 or r to Return. "; + 71 input "Enter gpio # ";s$ + 75 IF s$ = "20" or s$ = "7" or s$ = "112" or s$ = "115" then + : goto 80 + : END IF + 76 IF s$ = "r" then + : goto 16 + : END IF + : rem Start over + 78 print "Relay gpio number error. Only 20, 7, 112, 115 or r" + : goto 70 + 80 print + 82 IF m$ = "l" then + : gosub 400 + : goto 16 + : END IF + : rem l = Label + 84 IF m$ = "s" then + : gosub 300 + : print + : goto 16 + : END IF + : rem s = State + 86 IF m$ = "0" or m$ = "1" then + : gosub 100 + : goto 16 + : END IF + : rem Change Relay state + 90 print + : print "Error. Code fall through at line 90" + : print + : stop + 100 rem Change state of a Relay. + 101 rem p$ = Complete address to gpio. b$ is the Base + gpio# + end of string + 102 let p$=b$ + s$ + "/value" + 110 call open("O",#1,p$) + : rem Open for Output and write m$ + 150 print #1,m$ + : rem Print to gpio string m$ + 160 call close(#1) + 210 call open("I",#1,p$) + : rem Open for Input + 250 read #1,x + : rem Read numeric result + 255 call close(#1) + 256 IF s$ = "20" then + : print "#1 "; + : END IF + 257 IF s$ = "7" then + : print "#2 "; + : END IF + 258 IF s$ = "112" then + : print "#3 "; + : END IF + 259 IF s$ = "115" then + : print "#4 "; + : END IF + 260 gosub 700 + 299 return + 300 rem p$ = Complete address to gpio. b$ is the Base + gpio# + end of string + 304 let p$=b$ + s$ + "/value" + 310 call open("I",#1,p$) + : rem Open for Input + 350 read #1,x + : rem Read numeric result + 355 call close(#1) + 360 gosub 700 + 396 return + : rem Start over + 400 rem p$ = Complete address to gpio. b$ is the Base + gpio# + end of string + 404 let p$=b$ + s$ + "/label" + 410 call open("I",#1,p$) + 420 read #1,l$ + 425 call close(#1) + 430 print "Label for gpio ";s$;" is ";l$ + 440 return + 500 rem Display the state of all Relays 'sa' + 510 let s$ = "20" + : print "#1 "; + : gosub 300 + 520 let s$ = "7" + : print "#2 "; + : gosub 300 + 530 let s$ = "112" + : print "#3 "; + : gosub 300 + 540 let s$ = "115" + : print "#4 "; + : gosub 300 + 550 return + 600 rem Turn all Relays off 'ao' + 612 let m$ = "0" + : rem Set mode to '0' off + 620 let s$ = "20" + : gosub 100 + 624 let s$ = "7" + : gosub 100 + 626 let s$ = "112" + : gosub 100 + 628 let s$ = "115" + : gosub 100 + 630 return + 700 rem Print relay state gathered from 'read' + 704 print "Relay gpio ";s$," state is now = ";x; + 770 IF x = 0 then + : print " Off" + : END IF + 780 IF x = 1 then + : print " On" + : END IF + 790 IF x > 1 or x < 0 then + : print " Error" + : END IF + 799 return + 1000 rem Give them some help + 1010 print + : print "Information" + : print + 1020 print "To change the state of a relay use 0 for Off or 1 for On" + 1022 print " Then enter the gpio number 20, 7, 112 or 115" + : print + 1024 print "To check the state of a single relay use s" + 1026 print " Then enter the gpio number" + : print + 1028 print "To get the associated label (header pin) use l" + 1030 print " Then enter the gpio number" + : print + 1032 print "To get the state of all relays use sa" + : print + 1034 print "To turn all relays off use ao" + : print + 1035 print "For the latest updates goto:" + 1036 print "https://github.com/kenmartin-unix/Bwbasic-3.2a-for-BeagleBone" + 1038 print "ken.at.github@gmail.com" + 1040 print + : input "Press enter ? ",h + 1099 return + 9000 rem Get Model & Dogtag d$ = Dogtag 0$ = MOdel. Check for Beaglebone 'Black' + 9002 rem If we fail here we should not. This only runs once at startup. + 9004 call open("I",#1,"/etc/dogtag") + : rem Open dogtag file + 9008 read #1,d$ + : call close(#1) + 9014 call open("I",#1,"/proc/device-tree/model") + : rem Open model info + 9018 read #1,o$ + : call close(#1) + 9020 rem Lets see if it's a 'Black' + 9025 IF (instr(1,o$,"Black") > 0) then + : return + : END IF + 9055 print + : print "Warning: It appears this is not a BeagleBone 'Black'" + : print + 9056 print "It appears to be : ";o$ + 9057 print "Running : ";d$ + 9058 system +10000 rem Trap errors here. Hopefuly you will not get here. +10020 print + : print "Error code ";err;" Error line ";erl +10040 print +10041 IF (err = 2) then + : print "A program syntax error." + : print + : system + : END IF +10042 IF (err = 5) then + : print "Trouble working with files." + : print + : system + : END IF +10043 IF (erl > 9000) then + : print "Trouble during initial setup." + : print + : system + : END IF +10044 IF (err = 62) then + : print "Reading past the end of file attempted." + : print + : END IF +10048 IF (err = 64) then + : print "Invalid path. Verify open paths." + : system + : END IF +10060 rem CLOSE will fail on 2.2 and loop but not 3.2+ +10070 call close + : rem Just in case something is open. +11100 system + : rem Stop program + diff --git a/BAS-EXAMPLES/relays.pro b/BAS-EXAMPLES/relays.pro new file mode 100644 index 0000000..9dc95b5 --- /dev/null +++ b/BAS-EXAMPLES/relays.pro @@ -0,0 +1,4 @@ +OPTION STDERR "relays-stderr.txt" +OPTION STDOUT "relays-stdout.txt" +OPTION TERMINAL NONE + diff --git a/Junk/res.bas b/BAS-EXAMPLES/res22.bas similarity index 50% rename from Junk/res.bas rename to BAS-EXAMPLES/res22.bas index c620f70..6d4c0ea 100644 --- a/Junk/res.bas +++ b/BAS-EXAMPLES/res22.bas @@ -1,7 +1,7 @@ - 100 for j = 1 to 22 + 100 for j = 1 to 20 200 print j 300 next j - 400 for j = 1 to 80 + 400 for j = 1 to 79 500 print "I"; 600 next j - + 650 print "#" diff --git a/BAS-EXAMPLES/res24.bas b/BAS-EXAMPLES/res24.bas new file mode 100644 index 0000000..9fb7727 --- /dev/null +++ b/BAS-EXAMPLES/res24.bas @@ -0,0 +1,10 @@ + 50 CALL shell("cls") + 75 print "res.bas 4-13-2020 Ken run as bwbasic res.bas" + 100 for j = 1 to 22 + 200 print j + 300 next j + 400 for j = 1 to 79 + 500 print "I"; + 600 next j + 610 print "#" + diff --git a/BAS-EXAMPLES/selcase.bas b/BAS-EXAMPLES/selcase.bas new file mode 100644 index 0000000..a223099 --- /dev/null +++ b/BAS-EXAMPLES/selcase.bas @@ -0,0 +1,21 @@ +100 rem SelCase.bas -- test SELECT CASE +110 SHELL "cls" +210 Print "SelCase.bas -- test SELECT CASE statement" +220 Input "Enter a number (0 to quit) "; d +225 If (d = 0) then end +230 Select Case d +240 Case 3 to 5 +250 Print "The number is between 3 and 5." +260 Case 6 +270 Print "The number you entered is 6." +280 Case 7 to 9 +290 Print "The number is between 7 and 9." +300 Case If > 10 +310 Print "The number is greater than 10" +320 Case If < 0 +330 Print "The number is less than 0" +340 Case Else +350 Print "The number is 1, 2 or 10." +360 End Select +365 Print +370 Goto 220 diff --git a/bas/snglfunc.bas b/BAS-EXAMPLES/snglfunc.bas similarity index 100% rename from bas/snglfunc.bas rename to BAS-EXAMPLES/snglfunc.bas diff --git a/bas/stop.bas b/BAS-EXAMPLES/stop.bas similarity index 100% rename from bas/stop.bas rename to BAS-EXAMPLES/stop.bas diff --git a/BAS-EXAMPLES/sum.bas b/BAS-EXAMPLES/sum.bas new file mode 100644 index 0000000..d3cace5 --- /dev/null +++ b/BAS-EXAMPLES/sum.bas @@ -0,0 +1,13 @@ + 10 REM compute the sum of integers from 1 to 10 with GOTO loop + 20 CALL SHELL("cls") + 30 LET N=1 + 40 LET S = S + N + 50 PRINT N,S + 60 LET N = N + 1 + 70 IF N <= 10 GOTO 40 + 80 PRINT + : REM print empty line + 90 PRINT "Final sum:";S + 95 PRINT + 100 END + diff --git a/BAS-EXAMPLES/sumfor.bas b/BAS-EXAMPLES/sumfor.bas new file mode 100644 index 0000000..7703b86 --- /dev/null +++ b/BAS-EXAMPLES/sumfor.bas @@ -0,0 +1,12 @@ + 10 REM compute the sum of numbers with FOR loop. + 20 CALL SHELL("cls") + 30 FOR N=0.5 TO 10.1 STEP 0.75 + 40 LET S = S + N + 50 PRINT N,S + 70 NEXT N + 80 PRINT + : REM print empty line + 90 PRINT "Final sum:";S + 95 PRINT + 100 END + diff --git a/BAS-EXAMPLES/sumintexit.bas b/BAS-EXAMPLES/sumintexit.bas new file mode 100644 index 0000000..0a246c2 --- /dev/null +++ b/BAS-EXAMPLES/sumintexit.bas @@ -0,0 +1,14 @@ + 10 REM compute the sum of integers with FOR loop. Early exit. + 20 CALL SHELL("cls") + 30 FOR N=1 TO 10 + 35 IF (S + N > 25) GOTO 80 + : REM exit the loop when S gets large enough + 40 LET S = S + N + 50 PRINT N,S + 70 NEXT N + 80 PRINT + : REM print empty line + 90 PRINT "Final sum:";S + 95 PRINT + 100 END + diff --git a/BAS-EXAMPLES/sumneg.bas b/BAS-EXAMPLES/sumneg.bas new file mode 100644 index 0000000..bcf9b64 --- /dev/null +++ b/BAS-EXAMPLES/sumneg.bas @@ -0,0 +1,12 @@ + 10 REM compute the sum of integers from 1 to 10 with FOR and negative STEP + 20 CALL SHELL("cls") + 30 FOR N=10 TO 1 STEP -2 + 40 LET S = S + N + 50 PRINT N,S + 70 NEXT N + 80 PRINT + : REM print empty line + 90 PRINT "Final sum:";S + 95 PRINT + 100 END + diff --git a/bas/tab.bas b/BAS-EXAMPLES/tab.bas similarity index 100% rename from bas/tab.bas rename to BAS-EXAMPLES/tab.bas diff --git a/bas/term.bas b/BAS-EXAMPLES/term.bas similarity index 100% rename from bas/term.bas rename to BAS-EXAMPLES/term.bas diff --git a/BAS-EXAMPLES/tictac.bas b/BAS-EXAMPLES/tictac.bas new file mode 100644 index 0000000..6705963 --- /dev/null +++ b/BAS-EXAMPLES/tictac.bas @@ -0,0 +1,174 @@ + 2 PRINT TAB(30);"TIC-TAC-TOE" + 4 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY" + 6 PRINT + : PRINT + : PRINT + 8 PRINT "THE BOARD IS NUMBERED:" + 10 PRINT " 1 2 3" + 12 PRINT " 4 5 6" + 14 PRINT " 7 8 9" + 16 PRINT + : PRINT + : PRINT + 20 DIM SS(9) + 50 INPUT"DO YOU WANT 'X' OR 'O'";C$ + 55 IF C$="X"THEN 475 + 57 IF C$="x" THEN 475 + 60 P$="O" + : Q$="X" + 100 G=-1 + : H=1 + : IF SS(5)<>0 THEN 103 + 102 SS(5)=-1 + : GOTO 195 + 103 IF SS(5)<>1 THEN 106 + 104 IF SS(1)<>0 THEN 110 + 105 SS(1)=-1 + : GOTO 195 + 106 IF SS(2)=1 AND SS(1)=0 THEN 181 + 107 IF SS(4)=1 AND SS(1)=0 THEN 181 + 108 IF SS(6)=1 AND SS(9)=0 THEN 189 + 109 IF SS(8)=1 AND SS(9)=0 THEN 189 + 110 IF G=1 THEN 112 + 111 GOTO 118 + 112 J=3*INT((M-1)/3)+1 + 113 IF 3*INT((M-1)/3)+1=M THEN + : K=1 + : END IF + 114 IF 3*INT((M-1)/3)+2=M THEN + : K=2 + : END IF + 115 IF 3*INT((M-1)/3)+3=M THEN + : K=3 + : END IF + 116 GOTO 120 + 118 FOR J=1 TO 7 STEP 3 + : FOR K=1 TO 3 + 120 IF SS(J)<>G THEN 130 + 122 IF SS(J+2)<>G THEN 135 + 126 IF SS(J+1)<>0 THEN 150 + 128 SS(J+1)=-1 + : GOTO 195 + 130 IF SS(J)=H THEN 150 + 131 IF SS(J+2)<>G THEN 150 + 132 IF SS(J+1)<>G THEN 150 + 133 SS(J)=-1 + : GOTO 195 + 135 IF SS(J+2)<>0 THEN 150 + 136 IF SS(J+1)<>G THEN 150 + 138 SS(J+2)=-1 + : GOTO 195 + 150 IF SS(K)<>G THEN 160 + 152 IF SS(K+6)<>G THEN 165 + 156 IF SS(K+3)<>0 THEN 170 + 158 SS(K+3)=-1 + : GOTO 195 + 160 IF SS(K)=H THEN 170 + 161 IF SS(K+6)<>G THEN 170 + 162 IF SS(K+3)<>G THEN 170 + 163 SS(K)=-1 + : GOTO 195 + 165 IF SS(K+6)<>0 THEN 170 + 166 IF SS(K+3)<>G THEN 170 + 168 SS(K+6)=-1 + : GOTO 195 + 170 GOTO 450 + 171 IF SS(3)=G AND SS(7)=0 THEN 187 + 172 IF SS(9)=G AND SS(1)=0 THEN 181 + 173 IF SS(7)=G AND SS(3)=0 THEN 183 + 174 IF SS(9)=0 AND SS(1)=G THEN 189 + 175 IF G=-1 THEN + : G=1 + : H=-1 + : GOTO 110 + : END IF + 176 IF SS(9)=1 AND SS(3)=0 THEN 182 + 177 FOR I=2 TO 9 + : IF SS(I)<>0 THEN 179 + 178 SS(I)=-1 + : GOTO 195 + 179 NEXT I + 181 SS(1)=-1 + : GOTO 195 + 182 IF SS(1)=1 THEN 177 + 183 SS(3)=-1 + : GOTO 195 + 187 SS(7)=-1 + : GOTO 195 + 189 SS(9)=-1 + 195 PRINT + : PRINT"THE COMPUTER MOVES TO..." + 202 GOSUB 1000 + 205 GOTO 500 + 450 IF G=1 THEN 465 + 455 IF J=7 AND K=3 THEN 465 + 460 NEXT K + : NEXT J + 465 IF SS(5)=G THEN 171 + 467 GOTO 175 + 475 P$="X" + : Q$="O" + 500 PRINT + : INPUT"WHERE DO YOU MOVE";M + 502 IF M=0 THEN + : PRINT"THANKS FOR THE GAME." + : GOTO 2000 + : END IF + 503 IF M>9 THEN 506 + 505 IF SS(M)=0 THEN 510 + 506 PRINT"THAT SQUARE IS OCCUPIED." + : PRINT + : PRINT + : GOTO 500 + 510 G=1 + : SS(M)=1 + 520 GOSUB 1000 + 530 GOTO 100 + 1000 PRINT + : FOR I=1 TO 9 + : PRINT" "; + : IF SS(I)<>-1 THEN 1014 + 1012 PRINT Q$;" "; + : GOTO 1020 + 1014 IF SS(I)<>0 THEN 1018 + 1016 PRINT" "; + : GOTO 1020 + 1018 PRINT P$;" "; + 1020 IF I<>3 AND I<>6 THEN 1050 + 1030 PRINT + : PRINT"---+---+---" + 1040 GOTO 1080 + 1050 IF I=9 THEN 1080 + 1060 PRINT"!"; + 1080 NEXT I + : PRINT + : PRINT + : PRINT + 1095 FOR I=1 TO 7 STEP 3 + 1100 IF SS(I)<>SS(I+1)THEN 1115 + 1105 IF SS(I)<>SS(I+2)THEN 1115 + 1110 IF SS(I)=-1 THEN 1350 + 1112 IF SS(I)=1 THEN 1200 + 1115 NEXT I + : FOR I=1 TO 3 + : IF SS(I)<>SS(I+3)THEN 1150 + 1130 IF SS(I)<>SS(I+6)THEN 1150 + 1135 IF SS(I)=-1 THEN 1350 + 1137 IF SS(I)=1 THEN 1200 + 1150 NEXT I + : FOR I=1 TO 9 + : IF SS(I)=0 THEN 1155 + 1152 NEXT I + : GOTO 1400 + 1155 IF SS(5)<>G THEN 1170 + 1160 IF SS(1)=G AND SS(9)=G THEN 1180 + 1165 IF SS(3)=G AND SS(7)=G THEN 1180 + 1170 RETURN + 1180 IF G=-1 THEN 1350 + 1200 PRINT"YOU BEAT ME!! GOOD GAME." + : GOTO 2000 + 1350 PRINT"I WIN, TURKEY!!!" + : GOTO 2000 + 1400 PRINT"IT'S A DRAW. THANK YOU." + 2000 END + diff --git a/bas/whilwend.bas b/BAS-EXAMPLES/whilwend.bas similarity index 100% rename from bas/whilwend.bas rename to BAS-EXAMPLES/whilwend.bas diff --git a/bas/width.bas b/BAS-EXAMPLES/width.bas similarity index 100% rename from bas/width.bas rename to BAS-EXAMPLES/width.bas diff --git a/bas/writeinp.bas b/BAS-EXAMPLES/writeinp.bas similarity index 100% rename from bas/writeinp.bas rename to BAS-EXAMPLES/writeinp.bas diff --git a/Bwbasic-1.1-Manual.txt b/Bwbasic-1.1-Manual.txt deleted file mode 100644 index c331447..0000000 --- a/Bwbasic-1.1-Manual.txt +++ /dev/null @@ -1,441 +0,0 @@ - - - Bywater BASIC Interpreter/Shell, version 1.10 - --------------------------------------------- - - Copyright (c) 1992, Ted A. Campbell - for bwBASIC version 1.10, 1 November 1992 - - -CONTENTS: - - 1. DESCRIPTION - 2. TERMS OF USE - 3. COMMANDS AND FUNCTIONS IMPLEMENTED - 4. SOME NOTES ON USAGE - 5. UNIMPLEMENTED COMMANDS AND FUNCTIONS - 6. SOME NOTES ON COMPILATION - 7. THE STORY OF BYWATER BASIC - 8. COMMUNICATIONS - - -1. DESCRIPTION - - The Bywater BASIC Interpreter (bwBASIC) implements a large - superset of the ANSI Standard for Minimal BASIC (X3.60-1978) - in ANSI C and offers shell program facilities as an extension - of BASIC. - - The set of BASIC commands and functions implemented is fairly - limited (see section three below), although more commands and - functions are implemented than appear in the specification - for Minimal BASIC. There are no commands that are terminal- or - hardware specific. (Seriously -- CLS may work under bwBASIC - on your DOS-based pc, but that is because bwBASIC shells - out to DOS when it does not recognize CLS and executes CLS there.) - - The interpreter is slow. Whenever faced with a choice between - conceptual clarity and speed, I have consistently chosen - the former. The interpreter is the simplest design available, - and utilizes no system of intermediate code, which would speed - up considerably its operation. As it is, each line is interpreted - afresh as the interpreter comes to it. - - bwBASIC implements one feature not available in previous BASIC - interpreters: a shell command can be entered interactively at the - bwBASIC prompt, and the interpreter will execute it under a - command shell. For instance, the command "dir *.bas" can be - entered in bwBASIC (under DOS, or "ls -l *.bas" under UNIX) and - it will be executed as from the operating system command line. - Shell commands can also be given on numbered lines in a bwBASIC - program, so that bwBASIC can be used as a shell programming - language. bwBASIC's implementation of the RMDIR, CHDIR, MKDIR, - NAME, KILL, ENVIRON, and ENVIRON$() commands and functions - offer further shell-processing capabilities. - - -2. TERMS OF USE: - - The bwBASIC source code and executables produced from it can be - used subject to the following statement which is included in - the header to all the source code files: - - All U.S. and international copyrights are claimed by the - author. The author grants permission to use this code - and software based on it under the following conditions: - (a) in general, the code and software based upon it may be - used by individuals and by non-profit organizations; (b) it - may also be utilized by governmental agencies in any country, - with the exception of military agencies; (c) the code and/or - software based upon it may not be sold for a profit without - an explicit and specific permission from the author, except - that a minimal fee may be charged for media on which it is - copied, and for copying and handling; (d) the code must be - distributed in the form in which it has been released by the - author; and (e) the code and software based upon it may not - be used for illegal activities. - - -3. BASIC COMMANDS AND FUNCTIONS IMPLEMENTED: - - ABS( number ) - ASC( string$ ) - ATN( number ) - CHAIN [MERGE] file-name [, line-number] [, ALL] - CHR$( number ) - CINT( number ) - CLEAR - CLOSE [[#]file-number]... - 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...)]... - END - ENVIRON variable-string = string - ENVIRON$( variable-string ) - EOF( device-number ) - ERASE variable[, variable]... - ERL - ERR - ERROR number - EXP( number ) - FIELD [#] device-number, number AS string-variable [, number AS string-variable...] - FOR counter = start TO finish [STEP increment] - GET [#] device-number [, record-number] - GOSUB line - GOTO line - HEX$( number ) - IF expression THEN statement [ELSE statement] - 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 ) - LOF( device-number ) - LOG( number ) - LSET string-variable$ = expression - MERGE file-name - MID$( string$, start-position-in-string[, number-of-spaces ] ) - MKD$( double-value# ) - MKI$( integer-value% ) - MKS$( single-value! ) - NAME old-file-name AS new-file-name - NEW - NEXT counter - OCT$( number ) - ON variable GOTO|GOSUB line[,line,line,...] - ON ERROR GOSUB line - 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 ) - RND( number ) - RSET string-variable$ = expression - RUN [line][file-name] - SAVE file-name - SGN( number ) - SIN( number ) - SPACE$( number ) - SPC( number ) - SQR( number ) - STOP - STR$( number ) - STRING$( number, ascii-value|string$ ) - 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 ].... - - If DIRECTORY_CMDS is set to TRUE when the program is compiled, - then the following commands will be available: - - CHDIR pathname - MKDIR pathname - RMDIR pathname - - If DEBUG is set to TRUE when the program is compiled then - the following debugging commands (unique to bwBASIC) will - be available: - - VARS (prints a list of all variables) - CMDS (prints a list of all commands) - FNCS (prints a list of all functions) - - If COMMAND_SHELL is set to TRUE when the program is compiled, - then the user may enter a shell command at the bwBASIC prompt. - - -4. SOME NOTES ON USAGE: - - An interactive environment is provided, so that a line with a - line number can be entered at the bwBASIC prompt and it will be - added to the program in memory. - - Line numbers are not strictly required, but are useful if the - interactive enviroment is used for programming. For longer - program entry one might prefer to use an ASCII text editor, and - in this case lines can be entered without numbers. In this case, - however, one will not be able to alter the numberless lines - within the interactive environment. - - Command names and function names are not case sensitive, - so that "Run" and "RUN" and "run" are equivalent and "abs()" - and "ABS()" and "Abs()" are equivalent. HOWEVER: variable - names ARE case sensitive in bwbASIC, so that "d$" and "D$" - are different variables. This differs from some BASIC - implementations where variable names are not case sensitive. - - A filename can be specified on the command line and will be - LOADed and RUN immediately, so that the command line - - bwbasic prog.bas - - will load and execute "prog.bas". - - All programs are stored as ASCII text files. - - TRUE is defined as -1 and FALSE is defined as 0 in the default - distribution of bwBASIC. These definitions can be changed by - those compiling bwBASIC (see file BWBASIC.H). - - Assignment must be made to variables. This differs from some - implementations of BASIC where assignment can be made to a - function. Implication: "INSTR( 3, x$, y$ ) = z$" will not - work under bwBASIC. - - Notes on the implementation of specific commands: - - CVI(), CVD(), CVS(), MKI$(), MKD$(), MKS$(): These functions - are implemented, but are dependent on a) the sizes for integer, - float, and double values on particular systems, and b) how - particular versions of C store these numerical values. The - implication is that data files created using these functions - on a DOS-based microcomputer may not be translated correctly - by bwBASIC running on a Unix-based computer. Similarly, data - files created by bwBASIC compiled by one version of C may not be - readable by bwBASIC compiled by another version of C (even under - the same operating system). So be careful with these. - - ENVIRON: The ENVIRON command requires BASIC strings on either - side of the equals sign. Thus: - - environ "PATH" = "/usr/bin" - - It might be noted that this differs from the implementation - of ENVIRON in some versions of BASIC, but bwBASIC's ENVIRON - allows BASIC variables to be used on either side of the equals - sign. Note that the function ENVIRON$() is different from the - command, and be aware of the fact that in some operating systems - an environment variable set within a program will not be passed - to its parent shell. - - ERR: Note that if PROG_ERRORS has been defined when bwBASIC is - compiled, the ERR variable will not be set correctly upon - errors. It only works when standard error messages are used. - - FOR and NEXT: In this implementation of bwBASIC, a NEXT - statement must appear in the first position in a program - line; it cannot appear in a line segment beyond a colon. - - INPUT: bwBASIC cannot support the optional feature of INPUT - that suppresses the carriage-return and line-feed at the end - of the input. This is because ANSI C does not provide for any - means of input other than CR-LF-terminated strings. - - -5. UNIMPLEMENTED COMMANDS AND FUNCTIONS - - There are a few items not implemented that have been so long - a part of standard BASICs that their absence will seem surprising. - In each case, though, their implementation would require opera- - ting-system-specific functions or terminal-specific functions - that ANSI C cannot provide. Some specific examples: - - CALL In some versions of BASIC, CALL is used to call a - machine language subroutine, but machine language - routines are highly system-specific. In other - BASICs (conforming to the more complete ANSI - definition of BASIC), CALL is used to call a - named subroutine. Although it's possible that - bwBASIC could develop as a numberless BASIC - with named subroutine calls, these features - are not implemented in this earliest released - version. - - CLOAD See CALL above (machine language subroutines). - - CONT See RESUME below (programmer ignorance?). - - DEF USR See CALL above (machine language subroutines). - - EDIT EDIT would be especially nice, but requires some - specific knowledge of how particular computers - handle interaction between the screen and the - keyboard. This knowledge isn't available within - the bounds of ANSI C alone ("innerhalb die Grenzen - der reinen Vernunft," with apologies to Immanuel - Kant). - - FRE() The ability to report the amount of free memory - remaining is system-specific due to varying patterns - of memory allocation and access; consequently this - ability is not present in ANSI C and this function - is not available in bwBASIC. - - FILES The FILES command requires a list of files conforming - to a specifier; ANSI C does not provide this. When - COMMAND_SHELL is defined as TRUE, users might want - to issue operating-system commands such as "DIR" - (DOS) or "ls -l" (Unix) to get a list of files. - - INKEY$ This function requires a keyboard scan to indicate - whether a key is pending. Although this facility - is easily available on microcomputers (it is part - of the minimal CP/M Operating System), it is not - easily available on some more complex systems. - Consequently, it's not part of the C standard and - bwBASIC has not implemented INKEY$. - - INPUT$() Similar to INKEY$ above, ANSI C by itself is not - able to read unechoed keyboard input, and can read - keyboard input only after a Carriage-Return has - been entered. - - INP Calls to hardware ports, like machine-language - routines, are highly system-specific and cannot - be implemented in ANSI C alone. - - LLIST See LPRINT below. - - LPOS See LPRINT below. - - LPRINT and LLIST, etc., require access to a printer device, - and this varies from one system to another. Users - might try OPENing the printer device on their own - operating system (e.g., "/dev/lp" on Unix systems, - or "PRN" under DOS) and see if printing can be done - from bwBASIC in this way. - - NULL In this case, I am convinced that NULL is no longer - necessary, since very few printers now require NULLs - at the end of lines. - - OUT See INP above (calls to hardware ports). - - PEEK() PEEK and POKE enabled earlier BASICs to address - particular memory locations. Although bwBASIC - could possibly implement this command (POKE) and - this function (PEEK()), the limitation would be - highly limited by the different systems for - memory access in different systems. - - POKE see PEEK() above. - - RENUM Since unnumbered lines can be entered and - executed under bwBASIC, it would not be - possible to implement a RENUM routine. - - RESUME Is this possible under ANSI C? If so, I - simply have failed to figure it out yet. - Mea culpa (but not maxima). - - USR See CALL and DEF USR above (machine language - subroutines). - - VARPTR See PEEK and POKE above. - - WAIT See INP and OUT above. - - -6. SOME NOTES ON COMPILATION - - bwBASIC is written in ANSI C and takes advantage of some of the - enhancements of ANSI C over the older K&R standard. The program - expects to find standard ANSI C include files (such as ). - Because there is nothing terminal- or hardware-specific about it, - I should hope that it would compile correctly under any ANSI C - compiler, but you may have to construct your own makefile. - - Two makefiles are currently provided: "makefile.qcl" will compile - the program utilizing the Microsoft QuickC (tm) line-oriented - compiler on DOS-based p.c.'s, and "makefile.gcc" will compile - the program utilizing the ANSI option of Gnu C++. I have also - compiled the program utilizing Borland's Turbo C++ (tm) on DOS- - based machines. - - No alterations to flags are necessary for varied environments, - but the beginning of file allows the user to set - some debugging flags and to control some program defaults. - The file has a number of language-specific message - sets that can be controlled by setting the appropriate language - flag. - - -7. THE STORY OF BYWATER BASIC - - This program was originally begun in 1982 by my grandmother, Mrs. - Verda Spell of Beaumont, TX. She was writing the program using - an ANSI C compiler on an Osborne I CP/M computer and although my - grandfather (Lockwood Spell) had bought an IBM PC with 256k of - RAM my grandmother would not use it, paraphrasing George Herbert - to the effect that "He who cannot in 64k program, cannot in 512k." - She had used Microsoft BASIC and although she had nothing against - it she said repeatedly that she didn't understand why Digital - Research didn't "sue the socks off of Microsoft" for version 1.0 - of MSDOS and so I reckon that she hoped to undercut Microsoft's - entire market and eventually build a new software empire on - the North End of Beaumont. Her programming efforts were cut - tragically short when she was thrown from a Beaumont to Port - Arthur commuter train in the summer of 1986. I found the source - code to bwBASIC on a single-density Osborne diskette in her knitting - bag and eventually managed to have it all copied over to a PC - diskette. I have revised it slightly prior to this release. You - should know, though, that I myself am an historian, not a programmer. - - -8. COMMUNICATIONS: - - Ted A. Campbell - Bywater Software - P.O. Box 4023 - Duke Station - Durham, NC 27706 - USA - - email: tcamp@acpub.duke.edu - - diff --git a/DMCDOS32.CMD b/DMCDOS32.CMD deleted file mode 100644 index 3be4ae8..0000000 --- a/DMCDOS32.CMD +++ /dev/null @@ -1,35 +0,0 @@ -@echo off -rem Filename: DMCDOS32.CMD -rem Purpose: Build Bywater BASIC for MS-DOS (32-bit) using Digital Mars Compiler Version 8.42n -rem Author: Howard Wulf, AF5NE -rem Date: 2015-01-29 -rem Uasage: implementation defined -rem Example: -rem cd \sdcard\Download\BASIC\bwbasic3\ -rem DMCDOS32.CMD -rem -rem This is the location of DMC.EXE -rem -set BINDIR=C:\DOS\dm\bin; -rem -rem Cleanup before compile -rem -DEL BW*.EXE 1> NUL 2> NUL -DEL BW*.OBJ 1> NUL 2> NUL -DEL BW*.MAP 1> NUL 2> NUL -rem -rem Compile -rem -set OLDPATH=%PATH% -set PATH=%BINDIR%;%PATH% -dmc.exe > DMCDOS32.TXT -dmc.exe -mx -A89 -oBWBASIC.EXE -DHAVE_MSDOS=1 bwbasic.c bwb_cmd.c bwb_cnd.c bwb_dio.c bwb_exp.c bwb_fnc.c bwb_inp.c bwb_int.c bwb_prn.c bwb_stc.c bwb_str.c bwb_tbl.c bwb_var.c bwd_cmd.c bwd_fun.c bwx_tty.c X32.LIB >> DMCDOS32.TXT -set PATH=%OLDPATH% -set OLDPATH= -set BINDIR= -rem -rem Cleanup after compile -rem -DEL BW*.OBJ 1> NUL 2> NUL -DEL BW*.MAP 1> NUL 2> NUL -rem EOF diff --git a/DMCWIN32.CMD b/DMCWIN32.CMD deleted file mode 100644 index d563a92..0000000 --- a/DMCWIN32.CMD +++ /dev/null @@ -1,35 +0,0 @@ -@echo off -rem Filename: DMCWIN32.CMD -rem Purpose: Build Bywater BASIC for MS-WINDOWS (32-bit) using Digital Mars Compiler Version 8.42n -rem Author: Howard Wulf, AF5NE -rem Date: 2015-01-29 -rem Uasage: implementation defined -rem Example: -rem cd \sdcard\Download\BASIC\bwbasic3\ -rem DMCWIN32.CMD -rem -rem This is the location of DMC.EXE -rem -set BINDIR=C:\DOS\dm\bin -rem -rem Cleanup before compile -rem -DEL BW*.EXE 1> NUL 2> NUL -DEL BW*.OBJ 1> NUL 2> NUL -DEL BW*.MAP 1> NUL 2> NUL -rem -rem Compile -rem -set OLDPATH=%PATH% -set PATH=%BINDIR%;%PATH% -dmc.exe > DMCWIN32.TXT -dmc.exe -mn -A89 -oBWBASIC.EXE -DHAVE_MSDOS=1 bwbasic.c bwb_cmd.c bwb_cnd.c bwb_dio.c bwb_exp.c bwb_fnc.c bwb_inp.c bwb_int.c bwb_prn.c bwb_stc.c bwb_str.c bwb_tbl.c bwb_var.c bwd_cmd.c bwd_fun.c bwx_tty.c >> DMCWIN32.TXT -set PATH=%OLDPATH% -set OLDPATH= -set BINDIR= -rem -rem Cleanup after compile -rem -DEL BW*.OBJ 1> NUL 2> NUL -DEL BW*.MAP 1> NUL 2> NUL -rem EOF diff --git a/Junk/bwbasic.desktop b/GUI/bwbasic.desktop old mode 100644 new mode 100755 similarity index 59% rename from Junk/bwbasic.desktop rename to GUI/bwbasic.desktop index add1fac..bfac18a --- a/Junk/bwbasic.desktop +++ b/GUI/bwbasic.desktop @@ -4,8 +4,8 @@ Encoding=UTF-8 Name=Bywater BASIC GenericName=Bywater BASIC Type=Application -Exec=bwbasic -Icon=/usr/share/pixmaps/bwbasic.png +Exec=bwbasic.sh +Icon=bwbasic.png StartupNotify=true Terminal=true Categories=Development diff --git a/bwbasic.png b/GUI/bwbasic.png old mode 100644 new mode 100755 similarity index 100% rename from bwbasic.png rename to GUI/bwbasic.png diff --git a/GUI/bwbasic.sh b/GUI/bwbasic.sh new file mode 100755 index 0000000..268b2c1 --- /dev/null +++ b/GUI/bwbasic.sh @@ -0,0 +1,7 @@ +# 12/14/2019 Ken +trap 'echo " "; echo "PROGRAM INTERRUPTED"; echo "Press Enter "; read j; exit 1' INT +cd /home/$USER/source/bwbasic-3.2a/BAS-EXAMPLES +bwbasic +# -n = no newline -e interpret special octel numbers \007 = Bell +/bin/echo -n -e "Bwbasic terminated. Press Enter \007" +read j diff --git a/Junk/Bwbasic-1.1-Manual.txt b/INFO/Bwbasic-1.1-Manual.txt similarity index 100% rename from Junk/Bwbasic-1.1-Manual.txt rename to INFO/Bwbasic-1.1-Manual.txt diff --git a/Junk/Bwbasic-2.1-Manual.txt b/INFO/Bwbasic-2.1-Manual.txt similarity index 100% rename from Junk/Bwbasic-2.1-Manual.txt rename to INFO/Bwbasic-2.1-Manual.txt diff --git a/Bwbasic-2.1-Manual.txt b/INFO/Bwbasic-2.1.doc similarity index 100% rename from Bwbasic-2.1-Manual.txt rename to INFO/Bwbasic-2.1.doc diff --git a/INFO/Bwbasic-3.2-options.txt b/INFO/Bwbasic-3.2-options.txt new file mode 100644 index 0000000..b3dae74 --- /dev/null +++ b/INFO/Bwbasic-3.2-options.txt @@ -0,0 +1,2538 @@ +============================================================ + GENERAL +============================================================ + + +OPTION VERSION "BYWATER" +REM INTERNAL ID: B15 +REM DESCRIPTION: Bywater BASIC 3 +REM REFERENCE: Bywater BASIC Interpreter, version 3.20 +REM by Ted A. Campbell, Jon B. Volkoff, Paul Edwards, et al. +REM (c) 2014-2017, Howard Wulf, AF5NE +REM http://wwww.sourceforge.net/bwbasic/ +REM bwbasic-3.20.zip +REM +OPTION STRICT OFF +OPTION ANGLE RADIANS +OPTION BUGS ON +OPTION LABELS ON +OPTION COMPARE BINARY +OPTION COVERAGE OFF +OPTION TRACE ON +OPTION ERROR GOTO +OPTION IMPLICIT +OPTION BASE 0 +OPTION RECLEN 128 +OPTION DATE "%m/%d/%Y" +OPTION TIME "%H:%M:%S" +OPTION PUNCT STRING "$" +OPTION PUNCT DOUBLE "#" +OPTION PUNCT SINGLE "!" +OPTION PUNCT CURRENCY "@" +OPTION PUNCT LONG "&" +OPTION PUNCT INTEGER "%" +OPTION PUNCT BYTE "~" +OPTION PUNCT QUOTE """ +OPTION PUNCT COMMENT "'" +OPTION PUNCT STATEMENT ":" +OPTION PUNCT PRINT "?" +OPTION PUNCT INPUT " " +OPTION PUNCT IMAGE " " +OPTION PUNCT LPAREN "(" +OPTION PUNCT RPAREN ")" +OPTION PUNCT FILENUM "#" +OPTION PUNCT AT "@" +OPTION USING DIGIT "#" +OPTION USING COMMA "," +OPTION USING PERIOD "." +OPTION USING PLUS "+" +OPTION USING MINUS "-" +OPTION USING EXRAD "^" +OPTION USING DOLLAR "$" +OPTION USING FILLER "*" +OPTION USING LITERAL "_" +OPTION USING FIRST "!" +OPTION USING ALL "&" +OPTION USING LENGTH "\" + + +============================================================ + COMMANDS +============================================================ + + +------------------------------------------------------------ + SYNTAX: APPEND filename$ +DESCRIPTION: Merges the BASIC program in filename$ into the + current BASIC program; lines in filename$ + replace any matching lines in the current + program. +------------------------------------------------------------ + SYNTAX: AS +DESCRIPTION: Syntax Error. +------------------------------------------------------------ + SYNTAX: AUTO [start [, increment]] +DESCRIPTION: Automatic line numbering for manual program + entry. If the line already exists, then an + asterisk is displayed and pressing ENTER + leaves the line as-is. If the line does not + exist, then an asterisk is not displayed and + pressing ENTER terminates AUTO mode. + Regardless whether the line exists, entering + the command MAN will terminate AUTO mode. + AUTO mode is also terminated by any ERROR or + by pressing control-C. +------------------------------------------------------------ + SYNTAX: BREAK line [, ...]] +DESCRIPTION: Diagnostic command to stop execution at the + specified line(s). BREAK only applies to + user-numbered lines. For multi-statement + lines, BREAK only applies to the first + statement. BREAK effectively inserts a + hidden STOP command immediately after the + line number. Once a BREAK occurrs on a + specified line, it is automatically removed. + To remove all existing BREAKs, execute BREAK + without any line numbers. +------------------------------------------------------------ + SYNTAX: BYE +DESCRIPTION: Exits to the operating system. +------------------------------------------------------------ + SYNTAX: CALL subname( [parameter [, ...] ] ) +DESCRIPTION: Calls a subroutine that was defined by SUB and + END SUB. +------------------------------------------------------------ + SYNTAX: CASE constant [TO constant] +DESCRIPTION: Introduces an element of a SELECT CASE + statement. Multiple tests must be seperated + a comma. For example: CASE 1, 2 TO 3, IS > + 4, IF < 5 +------------------------------------------------------------ + SYNTAX: CASE IF operator constant +DESCRIPTION: Introduces an element of a SELECT CASE + statement. Multiple tests must be seperated + a comma. For example: CASE 1, 2 TO 3, IS > + 4, IF < 5 +------------------------------------------------------------ + SYNTAX: CASE IS operator constant +DESCRIPTION: Introduces an element of a SELECT CASE + statement. Multiple tests must be seperated + a comma. For example: CASE 1, 2 TO 3, IS > + 4, IF < 5 +------------------------------------------------------------ + SYNTAX: CASE ELSE +DESCRIPTION: Introduces a default SELECT CASE element. +------------------------------------------------------------ + SYNTAX: CHAIN filename$ [, linenumber] +DESCRIPTION: Load and execute another BASIC program, + without clearing common variables. For + System/370, the syntax is CHAIN + filename$,parameter$. +------------------------------------------------------------ + SYNTAX: CHANGE A$ TO X +DESCRIPTION: Changes a string to a numeric array. +------------------------------------------------------------ + SYNTAX: CHANGE X TO A$ +DESCRIPTION: Changes a numeric array to a string. +------------------------------------------------------------ + SYNTAX: CLEAR +DESCRIPTION: Sets all numeric variables to 0, and all + string variables to empty strings. +------------------------------------------------------------ + SYNTAX: CLOAD [filename$] +DESCRIPTION: Loads an ASCII BASIC program into memory. +------------------------------------------------------------ + SYNTAX: CLOAD* arrayname +DESCRIPTION: Loads a numeric array from a file saved using + CSAVE*. +------------------------------------------------------------ + SYNTAX: CMDS +DESCRIPTION: Prints a list of all implemented BASIC + commands. +------------------------------------------------------------ + SYNTAX: COMMON variable [, ...] +DESCRIPTION: Designates variables to be passed to a CHAINed + program. +------------------------------------------------------------ + SYNTAX: CONST variable [, ...] = value +DESCRIPTION: Assigns the value to variable. Any later + assignment to the variable causus a VARIABLE + NOT DECLARED error. +------------------------------------------------------------ + SYNTAX: CONT +DESCRIPTION: Continue a BASIC program after a STOP has been + executed. Program resumes at the line after + the STOP. +------------------------------------------------------------ + SYNTAX: CSAVE [filename$] +DESCRIPTION: Saves the current program into the file + filename$ in ASCII format. +------------------------------------------------------------ + SYNTAX: CSAVE* ArrayName +DESCRIPTION: Saves a numeric array into a file for later + loading by CLOAD*. +------------------------------------------------------------ + SYNTAX: DATA constant [, ...] +DESCRIPTION: Stores numeric and string constants to be + accessed by READ. +------------------------------------------------------------ + SYNTAX: DEF FNname[( arg [,...] )] = value +DESCRIPTION: Defines a single-line function. Single-line + functions require an equal sign. +------------------------------------------------------------ + SYNTAX: DEF FNname[( arg [,...] )] +DESCRIPTION: Defines a multiline function. Multi-line DEF + functions do not have an equal sign and must + end with FNEND. +------------------------------------------------------------ + SYNTAX: DEFBYT letter[-letter] [, ...] +DESCRIPTION: Declares variables with single-letter names as + numeric variables. +------------------------------------------------------------ + SYNTAX: DEFCUR letter[-letter] [, ...] +DESCRIPTION: Declares variables with single-letter names as + numeric variables. +------------------------------------------------------------ + SYNTAX: DEFDBL letter[-letter] [, ...] +DESCRIPTION: Declares variables with single-letter names as + numeric variables. +------------------------------------------------------------ + SYNTAX: DEFINT letter[-letter] [, ...] +DESCRIPTION: Declares variables with single-letter names as + numeric variables. +------------------------------------------------------------ + SYNTAX: DEFLNG letter[-letter] [, ...] +DESCRIPTION: Declares variables with single-letter names as + numeric variables. +------------------------------------------------------------ + SYNTAX: DEFSNG letter[-letter] [, ...] +DESCRIPTION: Declares variables with single-letter names as + numeric variables. +------------------------------------------------------------ + SYNTAX: DEFSTR letter[-letter] [, ...] +DESCRIPTION: Declares variables with single-letter names as + string variables. +------------------------------------------------------------ + SYNTAX: DELETE line [- line] +DESCRIPTION: Deletes program lines indicated by the + argument(s). All program lines have a + number, which is visible with the LIST + command. If line numbers are not provided, + they are assigned beginning with 1. Deleting + a non-existing line does not cause an error. +------------------------------------------------------------ + SYNTAX: DIM [# filenum,] variable([ lower TO ] upper) +DESCRIPTION: Declares variables and specifies the + dimensions of array variables. For array + variables, if the lower bound is not + provided, then the OPTION BASE value is used. + If filenum is provided, then the variable is + virtual. +------------------------------------------------------------ + SYNTAX: DO UNTIL value +DESCRIPTION: Top of a DO - LOOP structure. Exits when + value is non-zero. +------------------------------------------------------------ + SYNTAX: DO +DESCRIPTION: Top of a DO - LOOP structure. If the loop is + not terminated by EXIT DO or LOOP UNTIL or + LOOP WHILE, then it will loop forever. +------------------------------------------------------------ + SYNTAX: DO WHILE value +DESCRIPTION: Top of a DO - LOOP structure. Exits when + value is zero. +------------------------------------------------------------ + SYNTAX: DSP variable [, ...]] +DESCRIPTION: Diagnostic command to display the value every + time the variable is assigned. To remove all + existing DSPs, execute DSP without any + variables. +------------------------------------------------------------ + SYNTAX: EDIT +DESCRIPTION: implementation defined. +------------------------------------------------------------ + SYNTAX: ELSE +DESCRIPTION: Introduces a default condition in a multi-line + IF statement. +------------------------------------------------------------ + SYNTAX: ELSEIF +DESCRIPTION: Introduces a secondary condition in a + multi-line IF statement. +------------------------------------------------------------ + SYNTAX: END +DESCRIPTION: Terminates program execution. If the BASIC + program was executed from the operating + system level, then control returns to the + operating system, oterwise control reuturns + to the BASIC prompt. +------------------------------------------------------------ + SYNTAX: END FUNCTION +DESCRIPTION: Specifies the last line of a multi-line + FUNCTION definition. +------------------------------------------------------------ + SYNTAX: END IF +DESCRIPTION: Specifies the last line of a multi-line IF + definition. +------------------------------------------------------------ + SYNTAX: END SELECT +DESCRIPTION: Specifies the last line of a multi-line SELECT + CASE definition. +------------------------------------------------------------ + SYNTAX: END SUB +DESCRIPTION: Specifies the last line of a multi-line SUB + definition. +------------------------------------------------------------ + SYNTAX: ERASE variable [, ...] +DESCRIPTION: Eliminates arrayed variables from a program. +------------------------------------------------------------ + SYNTAX: EXCHANGE variable, variable +DESCRIPTION: Swaps the values of two variables. Both + variables must be of the same type. +------------------------------------------------------------ + SYNTAX: EXIT +DESCRIPTION: Syntax Error. +------------------------------------------------------------ + SYNTAX: EXIT DO +DESCRIPTION: Immediately exits the inner-most DO-LOOP + strucure. +------------------------------------------------------------ + SYNTAX: EXIT FOR +DESCRIPTION: Immediately exits the inner-most FOR-NEXT + strucure. +------------------------------------------------------------ + SYNTAX: EXIT FUNCTION +DESCRIPTION: Immediately exits the inner-most multi-line + FUNCTION strucure. +------------------------------------------------------------ + SYNTAX: EXIT REPEAT +DESCRIPTION: Exit a REPEAT - UNTIL structure. +------------------------------------------------------------ + SYNTAX: EXIT SUB +DESCRIPTION: Immediately exits the inner-most multi-line + SUB strucure. +------------------------------------------------------------ + SYNTAX: EXIT WHILE +DESCRIPTION: Immediately exits the inner-most WHILE-END + strucure. +------------------------------------------------------------ + SYNTAX: FIELD [#] filenum, number AS variable$ [, ...] +DESCRIPTION: Assigns number bytes in the buffer of random + file filenum to the variable variable$. GET + will automatically update the variable, and + PUT will automatically use the variable. +------------------------------------------------------------ + SYNTAX: FNCS +DESCRIPTION: Prints a list of all pre-defined BASIC + functions. +------------------------------------------------------------ + SYNTAX: FNEND +DESCRIPTION: Specifies the last line of a multi-line DEF + function. +------------------------------------------------------------ + SYNTAX: FOR variable = start TO finish [STEP + increment] +DESCRIPTION: Top of a FOR - NEXT structure. The loop will + continue a fixed number of times, which is + determined by the values of start, finish, + and increment. +------------------------------------------------------------ + SYNTAX: FUNCTION [ ( parameter [, ... ] ) ] +DESCRIPTION: Top line of a multi-line FUNCTION definition. + The variable names specified are local to the + FUNCTION definition, and are initialized + BYVAL when the function is invoked by another + routine. +------------------------------------------------------------ + SYNTAX: GO +DESCRIPTION: Syntax Error. +------------------------------------------------------------ + SYNTAX: GO SUB line +DESCRIPTION: Initiates a subroutine call to the line + specified. The subroutine must end with + RETURN. The line may be a number or a label. +------------------------------------------------------------ + SYNTAX: GO TO line +DESCRIPTION: Branches program execution to the specified + line. The line may be a number or a label. +------------------------------------------------------------ + SYNTAX: GOODBYE +DESCRIPTION: Exits to the operating system. +------------------------------------------------------------ + SYNTAX: GOSUB line +DESCRIPTION: Initiates a subroutine call to the line + specified. The subroutine must end with + RETURN. The line may be a number or a label. +------------------------------------------------------------ + SYNTAX: GOTO line +DESCRIPTION: Branches program execution to the specified + line. The line may be a number or a label. +------------------------------------------------------------ + SYNTAX: HELP name +DESCRIPTION: Provides help on the specified name which is a + command name or function name. +------------------------------------------------------------ + SYNTAX: IF value THEN line1 [ELSE line2] +DESCRIPTION: Single line standard IF command. If the value + is non-zero, then branh to line1. If the + value is zero and ELSE is provided, then + branch to line2. Otherwise continue to the + next line. LABELS are not allowed. +------------------------------------------------------------ + SYNTAX: IF value THEN +DESCRIPTION: Top of a multi-line IF - END IF structure. If + the value is non-zero, then the program lines + upto the next ELSE or ELSE IF command are + executed, otherwise the program branches to + the next ELSE or ELSE IF command. +------------------------------------------------------------ + SYNTAX: INPUT "prompt string" , variable [, ...] +DESCRIPTION: Reads input from the terminal after displaying + a prompt. +------------------------------------------------------------ + SYNTAX: INPUT # filenum , variable [, ...]s +DESCRIPTION: Reads input from the file specified by + filenum. +------------------------------------------------------------ + SYNTAX: INPUT variable [, ...] +DESCRIPTION: Reads input from the terminal. +------------------------------------------------------------ + SYNTAX: INPUT LINE variable$ +DESCRIPTION: Reads entire line from the terminal into + variable$. +------------------------------------------------------------ + SYNTAX: INPUT LINE # filenum , variable$ +DESCRIPTION: Reads entire line from a file into variable$. +------------------------------------------------------------ + SYNTAX: INPUT LINE "prompt string" , variable$ +DESCRIPTION: Reads entire line from the terminal into + variable$ after displaying a prompt +------------------------------------------------------------ + SYNTAX: [LET] variable [, ...] = value +DESCRIPTION: Assigns the value to the variable. The LET + keyword is optional. +------------------------------------------------------------ + SYNTAX: LINE +DESCRIPTION: Syntax Error. +------------------------------------------------------------ + SYNTAX: LINE INPUT [[#] filenum,]["prompt string";] + variable$ +DESCRIPTION: Reads entire line from the keyboard or a file + into variable$. +------------------------------------------------------------ + SYNTAX: LIST line1 [- line2] +DESCRIPTION: Lists BASIC program lines from line1 to line2 + to the console on stdout. +------------------------------------------------------------ + SYNTAX: LISTNH line1 [- line2] +DESCRIPTION: Lists BASIC program lines from line1 to line2 + to the console on stdout. +------------------------------------------------------------ + SYNTAX: LLIST line1 [- line2] +DESCRIPTION: Lists BASIC program lines from line1 to line2 + to the printer on stderr. +------------------------------------------------------------ + SYNTAX: LOAD [filename$] +DESCRIPTION: Loads an ASCII BASIC program into memory. +------------------------------------------------------------ + SYNTAX: LOOP UNTIL value +DESCRIPTION: Bottom of a DO - LOOP structure. Exits when + value is nonz-zero. +------------------------------------------------------------ + SYNTAX: LOOP WHILE value +DESCRIPTION: Bottom of a DO - LOOP structure. Exits when + value is zero. +------------------------------------------------------------ + SYNTAX: LOOP +DESCRIPTION: Bottom of a DO - LOOP structure. If the loop + is not terminated by EXIT DO or DO UNTIL or + DO WHILE, then it will loop forever. +------------------------------------------------------------ + SYNTAX: LPRINT [USING format-string$;] value ... +DESCRIPTION: Send output to the printer (stderr). +------------------------------------------------------------ + SYNTAX: LSET variable$ = value +DESCRIPTION: Left-aligns the value into variable$. If the + length of the value is too short, then it is + padded on the right with spaces. If the + length of the value is too long, then it is + truncated on the right. This is only for use + with variables assigned to a random access + buffer with FIELD command. +------------------------------------------------------------ + SYNTAX: MAINTAINER +DESCRIPTION: This command is reserved for use by the + Bywater BASIC maintainer. It is not for the + BASIC programmer. +------------------------------------------------------------ + SYNTAX: MAINTAINER CMDS +DESCRIPTION: Syntax Error. +------------------------------------------------------------ + SYNTAX: MAINTAINER CMDS HTML +DESCRIPTION: Dump COMMAND vs VERSION as HTML table +------------------------------------------------------------ + SYNTAX: MAINTAINER CMDS ID +DESCRIPTION: Dump COMMAND #define. +------------------------------------------------------------ + SYNTAX: MAINTAINER CMDS MANUAL +DESCRIPTION: Dump COMMAND manual. +------------------------------------------------------------ + SYNTAX: MAINTAINER CMDS_SWITCH +DESCRIPTION: Dump COMMAND switch. +------------------------------------------------------------ + SYNTAX: MAINTAINER CMDS TABLE +DESCRIPTION: Dump COMMAND table. +------------------------------------------------------------ + SYNTAX: MAINTAINER DEBUG +DESCRIPTION: Syntax Error. +------------------------------------------------------------ + SYNTAX: MAINTAINER DEBUG OFF +DESCRIPTION: Disable degug tracing. +------------------------------------------------------------ + SYNTAX: MAINTAINER DEBUG ON +DESCRIPTION: Enable degug tracing. +------------------------------------------------------------ + SYNTAX: MAINTAINER FNCS +DESCRIPTION: Syntax Error. +------------------------------------------------------------ + SYNTAX: MAINTAINER FNCS HTML +DESCRIPTION: Dump FUNCTION vs VERSION as HTML table. +------------------------------------------------------------ + SYNTAX: MAINTAINER FNCS ID +DESCRIPTION: Dump FUNCTION #define. +------------------------------------------------------------ + SYNTAX: MAINTAINER FNCS MANUAL +DESCRIPTION: Dump FUNCTION manual. +------------------------------------------------------------ + SYNTAX: MAINTAINER FNCS SWITCH +DESCRIPTION: Dump FUNCTION switch. +------------------------------------------------------------ + SYNTAX: MAINTAINER FNCS TABLE +DESCRIPTION: Dump FUNCTION table. +------------------------------------------------------------ + SYNTAX: MAINTAINER MANUAL +DESCRIPTION: Dump manual for the currently selected OPTION + VERSION. +------------------------------------------------------------ + SYNTAX: MAINTAINER STACK +DESCRIPTION: Dump the BASIC stack. +------------------------------------------------------------ + SYNTAX: MARGIN # filenumber, width +DESCRIPTION: Sets the file margin for writing; filenumber + <= 0 is ignored. +------------------------------------------------------------ + SYNTAX: MERGE filename$ +DESCRIPTION: Merges the BASIC program in filename$ into the + current BASIC program. Lines in filename$ + replace any matching lines in the current + program. +------------------------------------------------------------ + SYNTAX: MID$( variable$, start [, count ] ) = value +DESCRIPTION: Replaces a subtring of variable$ with value. +------------------------------------------------------------ + SYNTAX: NAME old$ AS new$ +DESCRIPTION: Changes the name of an existing file. +------------------------------------------------------------ + SYNTAX: NEW +DESCRIPTION: Deletes the program in memory and clears all + variables. +------------------------------------------------------------ + SYNTAX: NEXT [variable] +DESCRIPTION: The bottom line of a FOR - NEXT structure. +------------------------------------------------------------ + SYNTAX: OF +DESCRIPTION: Syntax Error. +------------------------------------------------------------ + SYNTAX: ON value GOSUB line [, ...] +DESCRIPTION: Calls based on the rounded value. +------------------------------------------------------------ + SYNTAX: ON value GOTO line [, ...] +DESCRIPTION: Branches based on the rounded value. +------------------------------------------------------------ + SYNTAX: ON ERROR +DESCRIPTION: Syntax Error. +------------------------------------------------------------ + SYNTAX: ON ERROR GOSUB errline +DESCRIPTION: When a trappable error occurs, execute GOSUB + errline. The error handler must terminate + with a RETURN command. If the line number is + 0 (zerp), then use the default error handler. + Valid when OPTION ERROR GOSUB. +------------------------------------------------------------ + SYNTAX: ON ERROR GOTO errline +DESCRIPTION: When a trappable error occurs, execute GOTO + errline. The error handler must terminate + with a RESUME command. If the line number is + 0 (zerp), then use the default error handler. + Valid when OPTION ERROR GOTO. +------------------------------------------------------------ + SYNTAX: ON ERROR RESUME +DESCRIPTION: Syntax Error. +------------------------------------------------------------ + SYNTAX: ON ERROR RESUME NEXT +DESCRIPTION: When a trappable error occurs, execution + continues with the next line. Valid when + OPTION ERROR GOTO. +------------------------------------------------------------ + SYNTAX: ON ERROR RETURN +DESCRIPTION: Syntax Error. +------------------------------------------------------------ + SYNTAX: ON ERROR RETURN NEXT +DESCRIPTION: When a trappable error occurs, execution + continues with the next line. Valid when + OPTION ERROR GOSUB. +------------------------------------------------------------ + SYNTAX: ON TIMER count GOSUB line +DESCRIPTION: Specifies a line (or label) to gosub when + count seconds have elaspsed after TIMER ON is + executed. The interrupt routine should end + with a RETURN command. Timer events only + occur in running BASIC programs. The + resolution of the clock is implementation + defined. +------------------------------------------------------------ + SYNTAX: OPEN filename$ + FOR INPUT|OUTPUT|APPEND|BINARY|RANDOM|VIRTUAL + AS [#] fileenumber + [LEN [=] record-length] +DESCRIPTION: Opens a file for use. + RANDOM requires LEN. +------------------------------------------------------------ + SYNTAX: OPTION +DESCRIPTION: Syntax Error. +------------------------------------------------------------ + SYNTAX: OPTION ANGLE +DESCRIPTION: Syntax Error. +------------------------------------------------------------ + SYNTAX: OPTION ANGLE DEGREES +DESCRIPTION: Configures these math functions to accept and + return angles in degrees: ACOS, ACS, ANGLE, + ARCSIN, ASIN, ASN, ARCTAN, ATN, ATAN, COS, + COT, CSC, SEC, SIN and TAN. +------------------------------------------------------------ + SYNTAX: OPTION ANGLE GRADIANS +DESCRIPTION: Configures these math functions to accept and + return angles in gradians: ACOS, ANGLE, + ASIN, ASN, ATN, ATAN, COS, COT, CSC, SEC, SIN + and TAN. +------------------------------------------------------------ + SYNTAX: OPTION ANGLE RADIANS +DESCRIPTION: Configures these math functions to accept and + return angles in radians: ACOS, ANGLE, ASIN, + ASN, ATN, ATAN, COS, COT, CSC, SEC, SIN and + TAN. +------------------------------------------------------------ + SYNTAX: OPTION ARITHMETIC +DESCRIPTION: Syntax Error. +------------------------------------------------------------ + SYNTAX: OPTION ARITHMETIC DECIMAL +DESCRIPTION: Currently has no effect. +------------------------------------------------------------ + SYNTAX: OPTION ARITHMETIC FIXED +DESCRIPTION: Currently has no effect. +------------------------------------------------------------ + SYNTAX: OPTION ARITHMETIC NATIVE +DESCRIPTION: Currently has no effect. +------------------------------------------------------------ + SYNTAX: OPTION BASE integer +DESCRIPTION: Sets the default lowest array subscript. +------------------------------------------------------------ + SYNTAX: OPTION BUGS +DESCRIPTION: Syntax Error. +------------------------------------------------------------ + SYNTAX: OPTION BUGS BOOLEAN +DESCRIPTION: Boolean results are 1 or 0 instead of bitwise. +------------------------------------------------------------ + SYNTAX: OPTION BUGS OFF +DESCRIPTION: Disables bugs commonly found in many BASIC + dialects. +------------------------------------------------------------ + SYNTAX: OPTION BUGS ON +DESCRIPTION: Enables bugs commonly found in many BASIC + dialects. +------------------------------------------------------------ + SYNTAX: OPTION COMPARE +DESCRIPTION: Syntax Error. +------------------------------------------------------------ + SYNTAX: OPTION COMPARE BINARY +DESCRIPTION: Causes string comparisons to be + case-sensitive. +------------------------------------------------------------ + SYNTAX: OPTION COMPARE DATABASE +DESCRIPTION: Causes string comparisons to be + case-insensitive. +------------------------------------------------------------ + SYNTAX: OPTION COMPARE TEXT +DESCRIPTION: Causes string comparisons to be + case-insensitive. +------------------------------------------------------------ + SYNTAX: OPTION COVERAGE +DESCRIPTION: Syntax Error. +------------------------------------------------------------ + SYNTAX: OPTION COVERAGE OFF +DESCRIPTION: Disables BASIC code coverage recording, + displayed using the LIST command. +------------------------------------------------------------ + SYNTAX: OPTION COVERAGE ON +DESCRIPTION: Enables BASIC code coverage recording, + displayed using the LIST command. +------------------------------------------------------------ + SYNTAX: OPTION DATE format$ +DESCRIPTION: Sets the date format string used by C + strftime() for DATE$. +------------------------------------------------------------ + SYNTAX: OPTION DIGITS integer +DESCRIPTION: Sets the number of significant digits for + PRINT. Setting the value to zero restores + the default. +------------------------------------------------------------ + SYNTAX: OPTION DISABLE +DESCRIPTION: Syntax Error. +------------------------------------------------------------ + SYNTAX: OPTION DISABLE COMMAND name$ +DESCRIPTION: Disables the specified BASIC command. +------------------------------------------------------------ + SYNTAX: OPTION DISABLE FUNCTION name$ +DESCRIPTION: Disables the specified BASIC function. +------------------------------------------------------------ + SYNTAX: OPTION DISABLE OPERATOR name$ +DESCRIPTION: Disables the specified BASIC operator. +------------------------------------------------------------ + SYNTAX: OPTION EDIT string$ +DESCRIPTION: Sets the program name used by the EDIT + command. +------------------------------------------------------------ + SYNTAX: OPTION ENABLE +DESCRIPTION: Syntax Error. +------------------------------------------------------------ + SYNTAX: OPTION ENABLE COMMAND name$ +DESCRIPTION: Enables the specified BASIC command. +------------------------------------------------------------ + SYNTAX: OPTION ENABLE FUNCTION name$ +DESCRIPTION: Enables the specified BASIC function. +------------------------------------------------------------ + SYNTAX: OPTION ENABLE OPERATOR name$ +DESCRIPTION: Enables the specified BASIC operator. +------------------------------------------------------------ + SYNTAX: OPTION ERROR +DESCRIPTION: Syntax Error. +------------------------------------------------------------ + SYNTAX: OPTION ERROR GOSUB +DESCRIPTION: When an error occurs, GOSUB to the error + handler. The error handler exits with + RETURN. +------------------------------------------------------------ + SYNTAX: OPTION ERROR GOTO +DESCRIPTION: When an error occurs, GOTO to the error + handler. The error handler exits with + RESUME. +------------------------------------------------------------ + SYNTAX: OPTION EXPLICIT +DESCRIPTION: All variables must be declared using DIM. +------------------------------------------------------------ + SYNTAX: OPTION EXTENSION string$ +DESCRIPTION: Sets the BASIC filename extension, commonly + ".bas". +------------------------------------------------------------ + SYNTAX: OPTION FILES string$ +DESCRIPTION: Sets the program name used by the FILES + command. +------------------------------------------------------------ + SYNTAX: OPTION IMPLICIT +DESCRIPTION: Variables need not be declared using DIM, + provided arrays have no more that 10 + elements. This is the opposite of OPTION + EXPLICIT, and is the default for all versions + of BASIC. +------------------------------------------------------------ + SYNTAX: OPTION INDENT integer +DESCRIPTION: Sets indention level for LIST. Zero means no + indention. Default is 2. +------------------------------------------------------------ + SYNTAX: OPTION LABELS +DESCRIPTION: Syntax Error. +------------------------------------------------------------ + SYNTAX: OPTION LABELS OFF +DESCRIPTION: Disables text labels. +------------------------------------------------------------ + SYNTAX: OPTION LABELS ON +DESCRIPTION: Enables text labels. +------------------------------------------------------------ + SYNTAX: OPTION PROMPT string$ +DESCRIPTION: Sets the BASIC prompt. +------------------------------------------------------------ + SYNTAX: OPTION PUNCT +DESCRIPTION: Syntax Error. +------------------------------------------------------------ + SYNTAX: OPTION PUNCT AT char$ +DESCRIPTION: Sets the PRINT AT character, commonly "@". +------------------------------------------------------------ + SYNTAX: OPTION PUNCT BYTE char$ +DESCRIPTION: Sets the suffix character that indicates a + variable is of type BYTE, commonly "~". +------------------------------------------------------------ + SYNTAX: OPTION PUNCT COMMENT char$ +DESCRIPTION: Sets the shortcut COMMENT character. +------------------------------------------------------------ + SYNTAX: OPTION PUNCT CURRENCY char$ +DESCRIPTION: Sets the suffix character that indicates a + variable is of type CURRENCY, commonly "@". +------------------------------------------------------------ + SYNTAX: OPTION PUNCT DOUBLE char$ +DESCRIPTION: Sets the suffix character that indicates a + variable is of type DOUBLE, commonly "#". +------------------------------------------------------------ + SYNTAX: OPTION PUNCT FILENUM char$ +DESCRIPTION: Sets the FILE NUMBER prefix character, + commonly "#". +------------------------------------------------------------ + SYNTAX: OPTION PUNCT IMAGE char$ +DESCRIPTION: Sets the shortcut IMAGE character, commonly + ":". +------------------------------------------------------------ + SYNTAX: OPTION PUNCT INPUT char$ +DESCRIPTION: Sets the shortcut INPUT character, commonly + "!". +------------------------------------------------------------ + SYNTAX: OPTION PUNCT INTEGER char$ +DESCRIPTION: Sets the suffix character that indicates a + variable is of type INTEGER, commonly "%". +------------------------------------------------------------ + SYNTAX: OPTION PUNCT LONG char$ +DESCRIPTION: Sets the suffix character that indicates a + variable is of type LONG, commonly "&". +------------------------------------------------------------ + SYNTAX: OPTION PUNCT LPAREN char$ +DESCRIPTION: Sets the LEFT PARENTHESIS character, commonly + "(". +------------------------------------------------------------ + SYNTAX: OPTION PUNCT_PRINT char$ +DESCRIPTION: Sets the shortcut PRINT character, commonly + "?". +------------------------------------------------------------ + SYNTAX: OPTION PUNCT QUOTE char$ +DESCRIPTION: Sets the QUOTE character, commonly """ +------------------------------------------------------------ + SYNTAX: OPTION PUNCT RPAREN char$ +DESCRIPTION: Sets the RIGHT PARENTHESIS character, commonly + ")". +------------------------------------------------------------ + SYNTAX: OPTION PUNCT SINGLE char$ +DESCRIPTION: Sets the suffix character that indicates a + variable is of type SINGLE, commonly "!". +------------------------------------------------------------ + SYNTAX: OPTION PUNCT STATEMENT char$ +DESCRIPTION: Sets the statement seperator character, + commonly ":". +------------------------------------------------------------ + SYNTAX: OPTION PUNCT STRING char$ +DESCRIPTION: Sets the suffix character that indicates a + variable is of type STRING, commonly "$". +------------------------------------------------------------ + SYNTAX: OPTION RECLEN integer +DESCRIPTION: Sets the default RANDOM record length. +------------------------------------------------------------ + SYNTAX: OPTION RENUM string$ +DESCRIPTION: Sets the program name used by the RENUM + command. +------------------------------------------------------------ + SYNTAX: OPTION ROUND +DESCRIPTION: Syntax Error. +------------------------------------------------------------ + SYNTAX: OPTION ROUND BANK +DESCRIPTION: Round using the Banker rule. +------------------------------------------------------------ + SYNTAX: OPTION ROUND MATH +DESCRIPTION: Round using mathematical rules. +------------------------------------------------------------ + SYNTAX: OPTION ROUND TRUNCATE +DESCRIPTION: Round using truncation. +------------------------------------------------------------ + SYNTAX: OPTION SCALE integer +DESCRIPTION: Sets the number of digits to round after the + decimal point for PRINT. Setting the value + to zero disables rounding. +------------------------------------------------------------ + SYNTAX: OPTION SLEEP double +DESCRIPTION: Sets multiplier for SLEEP and WAIT. Zero + means no waiting. Default is 1. +------------------------------------------------------------ + SYNTAX: OPTION STDERR filename$ +DESCRIPTION: Sets the file used for STDERR, which is used + by LPRINT commands. +------------------------------------------------------------ + SYNTAX: OPTION STDIN filename$ +DESCRIPTION: Sets the file used for STDIN, which is used by + INPUT commands. +------------------------------------------------------------ + SYNTAX: OPTION STDOUT filename$ +DESCRIPTION: Sets the file used for STDOUT, which is used + by PRINT commands. +------------------------------------------------------------ + SYNTAX: OPTION STRICT +DESCRIPTION: Syntax Error. +------------------------------------------------------------ + SYNTAX: OPTION STRICT OFF +DESCRIPTION: Disables checking for implicit array creation + without using the DIM command. +------------------------------------------------------------ + SYNTAX: OPTION STRICT ON +DESCRIPTION: Enables checking for implicit array creation + without using the DIM command. +------------------------------------------------------------ + SYNTAX: OPTION TERMINAL +DESCRIPTION: Syntax Error. +------------------------------------------------------------ + SYNTAX: OPTION TERMINAL ADM +DESCRIPTION: Enables ADM-3A terminal control codes for CLS, + COLOR, and LOCATE. +------------------------------------------------------------ + SYNTAX: OPTION TERMINAL ANSI +DESCRIPTION: Enables ANSI terminal control codes for CLS, + COLOR, and LOCATE. +------------------------------------------------------------ + SYNTAX: OPTION TERMINAL NONE +DESCRIPTION: Disables terminal control codes for CLS, + COLOR, and LOCATE. +------------------------------------------------------------ + SYNTAX: OPTION TIME format$ +DESCRIPTION: Sets the time format string used by C + strftime() for TIME$. +------------------------------------------------------------ + SYNTAX: OPTION TRACE +DESCRIPTION: Syntax Error. +------------------------------------------------------------ + SYNTAX: OPTION TRACE OFF +DESCRIPTION: Disables displaying a stack trace when an + ERROR occurs. +------------------------------------------------------------ + SYNTAX: OPTION TRACE ON +DESCRIPTION: Enables displaying a stack trace when an ERROR + occurs. +------------------------------------------------------------ + SYNTAX: OPTION USING +DESCRIPTION: Syntax Error. +------------------------------------------------------------ + SYNTAX: OPTION USING ALL char$ +DESCRIPTION: Specifies the magic ALL character for the + PRINT USING command. A common value is "&". +------------------------------------------------------------ + SYNTAX: OPTION USING COMMA char$ +DESCRIPTION: Specifies the magic COMMA character for the + PRINT USING command. A common value is ",". +------------------------------------------------------------ + SYNTAX: OPTION USING DIGIT char$ +DESCRIPTION: Specifies the magic DIGIT character for the + PRINT USING command. A common value is "#". +------------------------------------------------------------ + SYNTAX: OPTION USING DOLLAR char$ +DESCRIPTION: Specifies the magic DOLLAR character for the + PRINT USING command. A common value is "$". +------------------------------------------------------------ + SYNTAX: OPTION USING EXRAD char$ +DESCRIPTION: Specifies the magic EXRAD character for the + PRINT USING command. A common value is "^". +------------------------------------------------------------ + SYNTAX: OPTION USING FILLER char$ +DESCRIPTION: Specifies the magic FILLER character for the + PRINT USING command. A common value is "*". +------------------------------------------------------------ + SYNTAX: OPTION USING FIRST char$ +DESCRIPTION: Specifies the magic FIRST character for the + PRINT USING command. A common value is "!". +------------------------------------------------------------ + SYNTAX: OPTION USING LENGTH char$ +DESCRIPTION: Specifies the magic LENGTH character for the + PRINT USING command. A common value is "\". +------------------------------------------------------------ + SYNTAX: OPTION USING LITERAL char$ +DESCRIPTION: Specifies the magic LITERAL character for the + PRINT USING command. A common value is "_". +------------------------------------------------------------ + SYNTAX: OPTION USING MINUS char$ +DESCRIPTION: Specifies the magic MINUS character for the + PRINT USING command. A common value is "-". +------------------------------------------------------------ + SYNTAX: OPTION USING PERIOD char$ +DESCRIPTION: Specifies the magic PERIOD character for the + PRINT USING command. A common value is ".". +------------------------------------------------------------ + SYNTAX: OPTION USING PLUS char$ +DESCRIPTION: Specifies the magic PLUS character for the + PRINT USING command. A common value is "+". +------------------------------------------------------------ + SYNTAX: OPTION VERSION version$ +DESCRIPTION: Selects a specific BASIC version, which is a + combination of OPTION settings, commands, + functions and operators. If no version is + specified, displays a list of the available + versions. +------------------------------------------------------------ + SYNTAX: OPTION ZONE integer +DESCRIPTION: Sets the PRINT zone width. Setting the value + to zero restores the default. +------------------------------------------------------------ + SYNTAX: POP +DESCRIPTION: Pops one GOSUB from the return stack. +------------------------------------------------------------ + SYNTAX: PRINT # filenum , [USING format$;] value ... +DESCRIPTION: Sends output to a file. +------------------------------------------------------------ + SYNTAX: PRINT [USING format$;] value ... +DESCRIPTION: Sends output to the screen. +------------------------------------------------------------ + SYNTAX: QUIT +DESCRIPTION: Exits to the operating system. +------------------------------------------------------------ + SYNTAX: READ variable [, ...] +DESCRIPTION: Reads values from DATA statements. +------------------------------------------------------------ + SYNTAX: RECALL ArrayName +DESCRIPTION: Loads a numeric array from a file saved using + STORE. +------------------------------------------------------------ + SYNTAX: REM ... +DESCRIPTION: Remark. +------------------------------------------------------------ + SYNTAX: RENUM +DESCRIPTION: Implementation defined. +------------------------------------------------------------ + SYNTAX: REPEAT +DESCRIPTION: Top of a REPEAT - UNTIL structure. +------------------------------------------------------------ + SYNTAX: RESTORE [line] +DESCRIPTION: Resets the line used for the next READ + statement. line may be either a number or a + label. +------------------------------------------------------------ + SYNTAX: RESUME +DESCRIPTION: Used in an error handler to specify the next + line to execute. Branch to ERL. +------------------------------------------------------------ + SYNTAX: RESUME line +DESCRIPTION: Used in an error handler to specify the next + line to execute. Branch to the specified + line. +------------------------------------------------------------ + SYNTAX: RESUME NEXT +DESCRIPTION: Used in an error handler to specify the next + line to execute. Branch to the line after + ERL. +------------------------------------------------------------ + SYNTAX: RESUME 0 +DESCRIPTION: Used in an error handler to specify the next + line to execute. Branch to ERL. +------------------------------------------------------------ + SYNTAX: RETURN +DESCRIPTION: Concludes a subroutine called by GOSUB. +------------------------------------------------------------ + SYNTAX: RSET variable$ = value +DESCRIPTION: Right-aligns the value into variable$. If the + length of the value is too short, then it is + padded on the left with spaces. If the + length of the value is too long, then it is + truncated on the right. This is only for use + with variables assigned to a random access + buffer with FIELD command. +------------------------------------------------------------ + SYNTAX: RUN filename$ +DESCRIPTION: Loads a new BAASIC program and executes the + program from the start. +------------------------------------------------------------ + SYNTAX: RUN line +DESCRIPTION: Executes the program in memory beginning at + line. +------------------------------------------------------------ + SYNTAX: RUN +DESCRIPTION: Executes the program in memory from the start. +------------------------------------------------------------ + SYNTAX: RUNNH line +DESCRIPTION: Executes the program in memory beginning at + line. +------------------------------------------------------------ + SYNTAX: RUNNH filename$ +DESCRIPTION: Loads a new BAASIC program and executes the + program from the start. +------------------------------------------------------------ + SYNTAX: RUNNH +DESCRIPTION: Executes the program in memory from the start. +------------------------------------------------------------ + SYNTAX: SAVE [filename$] +DESCRIPTION: Saves the current program into the file + filename$ in ASCII format. +------------------------------------------------------------ + SYNTAX: SELECT +DESCRIPTION: Syntax Error. +------------------------------------------------------------ + SYNTAX: SELECT CASE value +DESCRIPTION: Introduces a multi-line conditional selection + statement. +------------------------------------------------------------ + SYNTAX: STEP +DESCRIPTION: Syntax Error. +------------------------------------------------------------ + SYNTAX: STOP +DESCRIPTION: Interrupts program execution and displays the + line number of the STOP command. For use + when debugging BASIC programs. Whether STOP + issues a SIGINT signal is implementation + defined. +------------------------------------------------------------ + SYNTAX: STORE ArrayName +DESCRIPTION: Saves a numeric array into a file for later + loading by RECALL. +------------------------------------------------------------ + SYNTAX: SUB name [ ( parameter [,...] ) ] +DESCRIPTION: Top line of a multi-line SUB definition. The + variable names specified are local to the SUB + definition, and are initialized BYVAL when + the subroutine is invoked by another routine. +------------------------------------------------------------ + SYNTAX: SUBEND +DESCRIPTION: Specifies the last line of a multi-line SUB + definition. Same as END SUB. +------------------------------------------------------------ + SYNTAX: SWAP variable, variable +DESCRIPTION: Swaps the values of two variables. Both + variables must be of the same type. +------------------------------------------------------------ + SYNTAX: SYSTEM +DESCRIPTION: Exits to the operating system. +------------------------------------------------------------ + SYNTAX: THEN +DESCRIPTION: Syntax Error. +------------------------------------------------------------ + SYNTAX: TIMER +DESCRIPTION: Syntax Error. +------------------------------------------------------------ + SYNTAX: TIMER OFF +DESCRIPTION: TIMER OFF terminates the timer interrupt. +------------------------------------------------------------ + SYNTAX: TIMER ON +DESCRIPTION: TIMER ON enables the timer interrupt. When + the specified seconds have elapsed, TIMER + STOP is internaly executed before the + interrupt is taken. TIMER ON should be + executed just before the RETURN command if + you want the interrupt to occur again. +------------------------------------------------------------ + SYNTAX: TIMER STOP +DESCRIPTION: TIMER STOP disables the interrupt, but the + count continues. +------------------------------------------------------------ + SYNTAX: TLOAD [filename$] +DESCRIPTION: Loads an ASCII BASIC program into memory. +------------------------------------------------------------ + SYNTAX: TO +DESCRIPTION: Syntax Error. +------------------------------------------------------------ + SYNTAX: TSAVE [filename$] +DESCRIPTION: Saves the current program into the file + filename$ in ASCII format. +------------------------------------------------------------ + SYNTAX: UNTIL value +DESCRIPTION: Bottom of a REPEAT - UNTIL. If the value is + non-zero, then the loop is terminated. +------------------------------------------------------------ + SYNTAX: VARS +DESCRIPTION: Prints a list of all global variables. +------------------------------------------------------------ + SYNTAX: WEND +DESCRIPTION: Bottom of a WHILE - WEND structure. +------------------------------------------------------------ + SYNTAX: WHILE value +DESCRIPTION: Top of a WHILE - WEND structure. If the value + is non-zero, then the loop is terminated. +------------------------------------------------------------ + SYNTAX: WRITE # filenum, value [, .... ] +DESCRIPTION: Outputs value to a file. Strings are quoted + and each value is seperated by a omma. +------------------------------------------------------------ + SYNTAX: WRITE value [, .... ] +DESCRIPTION: Outputs value to the screen. Strings are + quoted and each value is seperated by a + comma. +------------------------------------------------------------ + + +============================================================ + FUNCTIONS +============================================================ + + +------------------------------------------------------------ + SYNTAX: N = ABS( X ) + PARAMETER: X is a number +DESCRIPTION: The absolute value of X. +------------------------------------------------------------ + SYNTAX: N = ACOS( X ) + PARAMETER: X is a number +DESCRIPTION: The arccosine of X in radians, where 0 <= + ACOS(X) <= PI. X shall be in the range -1 <= + X <= 1. +------------------------------------------------------------ + SYNTAX: N = ACS( X ) + PARAMETER: X is a number +DESCRIPTION: The arccosine of X in radians, where 0 <= + ACS(X) <= PI. X shall be in the range -1 <= + X <= 1. +------------------------------------------------------------ + SYNTAX: N = ACSD( X ) + PARAMETER: X is a number +DESCRIPTION: The arccosine of X in degrees, where 0 <= + ACSD(X) <= 180. X shall be in the range -1 + <= X <= 1. +------------------------------------------------------------ + SYNTAX: N = ACSG( X ) + PARAMETER: X is a number +DESCRIPTION: The arccosine of X in gradians, where 0 <= + ACS(X) <= 200. X shall be in the range -1 <= + X <= 1. +------------------------------------------------------------ + SYNTAX: N = ANGLE( X, Y ) + PARAMETER: X is a number + PARAMETER: Y is a number +DESCRIPTION: The angle in radians between the positive + x-axis and the vector joining the origin to + the point with coordinates (X, Y), where -PI + < ANGLE(X,Y) <= PI. X and Y must not both be + 0. Note that the counterclockwise is + positive, e.g., ANGLE(1,1) = 45 degrees. +------------------------------------------------------------ + SYNTAX: N = ARCSIN( X ) + PARAMETER: X is a number +DESCRIPTION: The arcsine of X in radians, where -PI/2 <= + ARCSIN(X) <= PI/2; X shall be in the range -1 + <= X <= 1. +------------------------------------------------------------ + SYNTAX: N = ARCTAN( X ) + PARAMETER: X is a number +DESCRIPTION: The arctangent of X in radians, i.e. the angle + whose tangent is X, where -PI/2 < ARCTAN(X) < + PI/2. +------------------------------------------------------------ + SYNTAX: N = ARGC +DESCRIPTION: The number of parameters passed to a FUNCTION + or SUB. If not in a FUNCTION or SUB, returns + -1. +------------------------------------------------------------ + SYNTAX: S$ = ARGT$( X ) + PARAMETER: X is a number, [MININT,MAXINT] +DESCRIPTION: The type of the Xth parameter to a FUNCTION or + SUB. If the Xth parameter is a string, then + return value is "$". If the Xth parameter is + a number, then return value is not "$". X in + [1,ARGC]. +------------------------------------------------------------ + SYNTAX: N = ARGV( X ) + PARAMETER: X is a number, [MININT,MAXINT] +DESCRIPTION: The numeric value of the Xth parameter to a + FUNCTION or SUB. X in [1,ARGC] and ARGT$( X + ) <> "$". +------------------------------------------------------------ + SYNTAX: S$ = ARGV$( X ) + PARAMETER: X is a number, [MININT,MAXINT] +DESCRIPTION: The string value of the Xth parameter to a + FUNCTION or SUB. X in [1,ARGC] and ARGT$( X + ) = "$". +------------------------------------------------------------ + SYNTAX: N = ASC( A$ ) + PARAMETER: A$ is a string, LEN >= 1 +DESCRIPTION: The numeric code for the first letter in A$. + For example, ASC("ABC") returns 65 on ASCII + systems. +------------------------------------------------------------ + SYNTAX: N = ASC( A$, X ) + PARAMETER: A$ is a string, LEN >= 1 + PARAMETER: X is a number, [1,MAXLEN] +DESCRIPTION: The numeric code of the Xth character in A$. + Same as ASC(MID$(A$,X)). +------------------------------------------------------------ + SYNTAX: N = ASCII( A$ ) + PARAMETER: A$ is a string, LEN >= 1 +DESCRIPTION: The numeric code for the first letter in A$. + For example, ASCII("ABC") returns 65 on ASCII + systems. +------------------------------------------------------------ + SYNTAX: N = ASIN( X ) + PARAMETER: X is a number +DESCRIPTION: The arcsine of X in radians, where -PI/2 <= + ASIN(X) <= PI/2; X shall be in the range -1 + <= X <= 1. +------------------------------------------------------------ + SYNTAX: N = ASN( X ) + PARAMETER: X is a number +DESCRIPTION: The arcsine of X in radians, where -PI/2 <= + ASN(X) <= PI/2; X shall be in the range -1 <= + X <= 1. +------------------------------------------------------------ + SYNTAX: N = ASND( X ) + PARAMETER: X is a number +DESCRIPTION: The arcsine of X in degrees, where -90 <= + ASN(X) <= 90; X shall be in the range -1 <= X + <= 1. +------------------------------------------------------------ + SYNTAX: N = ASNG( X ) + PARAMETER: X is a number +DESCRIPTION: The arcsine of X in gradians, where -100 <= + ASNG(X) <= 100; X shall be in the range -1 <= + X <= 1. +------------------------------------------------------------ + SYNTAX: N = ATAN( X ) + PARAMETER: X is a number +DESCRIPTION: The arctangent of X in radians, i.e. the angle + whose tangent is X, where -PI/2 < ATAN(X) < + PI/2. +------------------------------------------------------------ + SYNTAX: N = ATN( X ) + PARAMETER: X is a number +DESCRIPTION: The arctangent of X in radians, i.e. the angle + whose tangent is X, where -PI/2 < ATN(X) < + PI/2. +------------------------------------------------------------ + SYNTAX: N = ATND( X ) + PARAMETER: X is a number +DESCRIPTION: The arctangent of X in degrees, i.e. the angle + whose tangent is X, where -90 < ATND(X) < 90. +------------------------------------------------------------ + SYNTAX: N = ATNG( X ) + PARAMETER: X is a number +DESCRIPTION: The arctangent of X in gradians, i.e. the + angle whose tangent is X, where -100 < + ATND(X) < 100. +------------------------------------------------------------ + SYNTAX: N = BASE +DESCRIPTION: The current OPTION BASE setting. +------------------------------------------------------------ + SYNTAX: N = CCUR( X ) + PARAMETER: X is a number, [MINCUR,MAXCUR] +DESCRIPTION: The currency (64-bit) integer value of X. +------------------------------------------------------------ + SYNTAX: N = CDBL( X ) + PARAMETER: X is a number, [MINDBL,MAXDBL] +DESCRIPTION: The double-precision value of X. +------------------------------------------------------------ + SYNTAX: N = CEIL( X ) + PARAMETER: X is a number +DESCRIPTION: The smallest integer not less than X. +------------------------------------------------------------ + SYNTAX: S$ = CHAR( X, Y ) + PARAMETER: X is a number, [0,255] + PARAMETER: Y is a number, [0,MAXLEN] +DESCRIPTION: The string Y bytes long consisting of CHR$(X). + Same as STRING$(Y,X). +------------------------------------------------------------ + SYNTAX: S$ = CHAR$( X ) + PARAMETER: X is a number, [0,255] +DESCRIPTION: The one-character string with the character + corresponding to the numeric code X. On + ASCII systems, CHAR$(65) returns "A". +------------------------------------------------------------ + SYNTAX: N = CHDIR( A$ ) + PARAMETER: A$ is a string, LEN >= 1 +DESCRIPTION: Changes to the directory named to A$. +------------------------------------------------------------ + SYNTAX: S$ = CHR( X ) + PARAMETER: X is a number +DESCRIPTION: The one-character string with the character + corresponding to the numeric code X. On + ASCII systems, CHR(65) returns "A". +------------------------------------------------------------ + SYNTAX: S$ = CHR$( X ) + PARAMETER: X is a number, [0,255] +DESCRIPTION: The one-character string with the character + corresponding to the numeric code X. On + ASCII systems, CHR$(65) returns "A". +------------------------------------------------------------ + SYNTAX: N = CINT( X ) + PARAMETER: X is a number, [MININT,MAXINT] +DESCRIPTION: The short (16-bit) integer value of X. +------------------------------------------------------------ + SYNTAX: N = CLG( X ) + PARAMETER: X is a number, > 0 +DESCRIPTION: The common logarithm of X; X shall be greater + than zero. +------------------------------------------------------------ + SYNTAX: S$ = CLK( X ) + PARAMETER: X is a number +DESCRIPTION: The time of day in 24-hour notation according + to ISO 3307. For example, the value of CLK + at 11:15 AM is "11:15:00". If there is no + clock available, then the value of CLK shall + be "99:99:99". The value of TIME$ at + midnight is "00:00:00". The value of + parameter X is ignored. +------------------------------------------------------------ + SYNTAX: S$ = CLK$ +DESCRIPTION: The time of day in 24-hour notation according + to ISO 3307. For example, the value of TIME$ + at 11:15 AM is "11:15:00". If there is no + clock available, then the value of TIME$ + shall be "99:99:99". The value of TIME$ at + midnight is "00:00:00". +------------------------------------------------------------ + SYNTAX: N = CLNG( X ) + PARAMETER: X is a number, [MINLNG,MAXLNG] +DESCRIPTION: The long (32-bit) integer value of X. +------------------------------------------------------------ + SYNTAX: N = CLOG( X ) + PARAMETER: X is a number, > 0 +DESCRIPTION: The common logarithm of X; X shall be greater + than zero. +------------------------------------------------------------ + SYNTAX: N = CLOSE +DESCRIPTION: Close all open files. +------------------------------------------------------------ + SYNTAX: N = CLOSE( X ) + PARAMETER: X is a number, [MININT,MAXINT] +DESCRIPTION: Close file number X. +------------------------------------------------------------ + SYNTAX: N = CLS +DESCRIPTION: Clears the screen. Cursor is positioned at row + 1, column 1. +------------------------------------------------------------ + SYNTAX: N = CODE( A$ ) + PARAMETER: A$ is a string, LEN >= 1 +DESCRIPTION: The numeric code for the first letter in A$. + For example, CODE("ABC") returns 65 on ASCII + systems. +------------------------------------------------------------ + SYNTAX: N = COLOR( X, Y ) + PARAMETER: X is a number, [0,255] + PARAMETER: Y is a number, [0,255] +DESCRIPTION: Sets the foreground text color to X, and the + background text color to Y. +------------------------------------------------------------ + SYNTAX: S$ = COMMAND$( X ) + PARAMETER: X is a number, [0,255] +DESCRIPTION: The command line parameters. COMMAND$(0) is + the BASIC program name. COMMAND$(1) is the + first parameter after the BASIC program name, + and so on. Support for parameters varies by + operating system, compiler, and so on. X in + [0..9] +------------------------------------------------------------ + SYNTAX: N = COS( X ) + PARAMETER: X is a number +DESCRIPTION: The cosine of X, where X is in radians. +------------------------------------------------------------ + SYNTAX: N = COSD( X ) + PARAMETER: X is a number +DESCRIPTION: The cosine of X, where X is in degrees. +------------------------------------------------------------ + SYNTAX: N = COSG( X ) + PARAMETER: X is a number +DESCRIPTION: The cosine of X, where X is in gradians. +------------------------------------------------------------ + SYNTAX: N = COSH( X ) + PARAMETER: X is a number +DESCRIPTION: The hyperbolic cosine of X. +------------------------------------------------------------ + SYNTAX: N = COT( X ) + PARAMETER: X is a number +DESCRIPTION: The cotangent of X, where X is in radians. +------------------------------------------------------------ + SYNTAX: N = COUNT +DESCRIPTION: The current cursor position in the line. +------------------------------------------------------------ + SYNTAX: N = CSC( X ) + PARAMETER: X is a number +DESCRIPTION: The cosecant of X, where X is in radians. +------------------------------------------------------------ + SYNTAX: N = CSH( X ) + PARAMETER: X is a number +DESCRIPTION: The hyperbolic cosine of X. +------------------------------------------------------------ + SYNTAX: N = CSNG( X ) + PARAMETER: X is a number, [MINFLT,MAXFLT] +DESCRIPTION: The single-precision value of X. +------------------------------------------------------------ + SYNTAX: S$ = CUR( X, Y ) + PARAMETER: X is a number, [0,255] + PARAMETER: Y is a number, [0,255] +DESCRIPTION: Locates the cursor to row X, column Y. +------------------------------------------------------------ + SYNTAX: N = CVC( A$ ) + PARAMETER: A$ is a string, LEN >= sizeof(CUR) +DESCRIPTION: The currency (64-bit) integer value in A$, + which was created by MKC$. +------------------------------------------------------------ + SYNTAX: N = CVD( A$ ) + PARAMETER: A$ is a string, LEN >= sizeof(DBL) +DESCRIPTION: The double-precision value in A$, which was + created by MKD$. +------------------------------------------------------------ + SYNTAX: N = CVI( A$ ) + PARAMETER: A$ is a string, LEN >= sizeof(INT) +DESCRIPTION: The short (16-bit) integer value in A$, which + was created by MKI$. +------------------------------------------------------------ + SYNTAX: N = CVL( A$ ) + PARAMETER: A$ is a string, LEN >= sizeof(LNG) +DESCRIPTION: The long (32-bit) integer value in A$, which + was created by MKL$. +------------------------------------------------------------ + SYNTAX: N = CVS( A$ ) + PARAMETER: A$ is a string, LEN >= sizeof(FLT) +DESCRIPTION: The single-precision value in A$, which was + created by MKS$. +------------------------------------------------------------ + SYNTAX: N = DATE +DESCRIPTION: The current date in decimal form YYYDDD, where + YYY are the number of years since 1900 and + DDD is the ordinal number of the current day + of the year; e.g., the value of DATE on May + 9, 1977 was 77129. If there is no calendar + available, then the value of DATE shall be + -1. +------------------------------------------------------------ + SYNTAX: S$ = DATE$ +DESCRIPTION: The current date based on the internal clock + as a string in the format set by OPTION DATE. +------------------------------------------------------------ + SYNTAX: N = DEG +DESCRIPTION: Configures the math functions to accept and + return angles in degrees. +------------------------------------------------------------ + SYNTAX: N = DEG( X ) + PARAMETER: X is a number +DESCRIPTION: The number of degrees in X radians. +------------------------------------------------------------ + SYNTAX: N = DEGREE +DESCRIPTION: Configures the math functions to accept and + return angles in degrees. +------------------------------------------------------------ + SYNTAX: N = DEGREE( X ) + PARAMETER: X is a number +DESCRIPTION: The number of degrees in X radians. +------------------------------------------------------------ + SYNTAX: N = DET +DESCRIPTION: The determinant of the last MAT INV. Zero + means error. +------------------------------------------------------------ + SYNTAX: N = DIM( ... ) +DESCRIPTION: DIM( arrayname ). The total number of + dimensions of the array. +------------------------------------------------------------ + SYNTAX: N = ENVIRON( A$ ) + PARAMETER: A$ is a string, LEN >= 1 +DESCRIPTION: Sends the environment variable expression + contained in A$ to the host operating system. + A$ must contain the "=" character. +------------------------------------------------------------ + SYNTAX: S$ = ENVIRON$( A$ ) + PARAMETER: A$ is a string, LEN >= 1 +DESCRIPTION: The value of the environment variable named + A$. +------------------------------------------------------------ + SYNTAX: N = EOF( X ) + PARAMETER: X is a number, [MININT,MAXINT] +DESCRIPTION: If device number X is at the end-of-file, then + -1, otherwise 0. +------------------------------------------------------------ + SYNTAX: N = EPS( X ) + PARAMETER: X is a number +DESCRIPTION: The maximum of (X-X1,X2-X, sigma) where X1 and + X2 are the predecessor and successor of X and + signma is the smallest positive value + representable. If X has no predecessor the + X1=X and if X has no successor the X2=X. + Note EPS(0) is the smallest positive number + representable by the implementation, and is + therefor implementation-defined. Note also + that EPS may produce different results for + different arithmetic options (see OPTION + ARITHMETIC). +------------------------------------------------------------ + SYNTAX: N = ERL +DESCRIPTION: The line number of the most recent error. +------------------------------------------------------------ + SYNTAX: N = ERR +DESCRIPTION: The error number of the most recent error. +------------------------------------------------------------ + SYNTAX: S$ = ERR$ +DESCRIPTION: The last error message. +------------------------------------------------------------ + SYNTAX: N = ERRL +DESCRIPTION: The line number of the most recent error. +------------------------------------------------------------ + SYNTAX: N = ERRN +DESCRIPTION: The error number of the most recent error. +------------------------------------------------------------ + SYNTAX: N = ERROR( X ) + PARAMETER: X is a number, [0,255] +DESCRIPTION: Simulate the error number in X. +------------------------------------------------------------ + SYNTAX: N = ERROR( X, A$ ) + PARAMETER: X is a number, [0,255] + PARAMETER: A$ is a string, LEN >= 0 +DESCRIPTION: Simulate the error number in X, with a custom + message in A$. +------------------------------------------------------------ + SYNTAX: S$ = ERROR$ +DESCRIPTION: The last error message. +------------------------------------------------------------ + SYNTAX: N = EXP( X ) + PARAMETER: X is a number +DESCRIPTION: The exponential value of X, i.e., the value of + the base of natural logarithms (e = 2.71828) + raised to the power of X; if EXP(X) is less + that machine infinitesimal, then its value + shall be replaced with zero. +------------------------------------------------------------ + SYNTAX: N = FILEATTR( X, Y ) + PARAMETER: X is a number, [MININT,MAXINT] + PARAMETER: Y is a number, [MININT,MAXINT] +DESCRIPTION: For file X, if Y = 1 then returns open mode, + otherwise returns zero. +------------------------------------------------------------ + SYNTAX: N = FILES +DESCRIPTION: Displays all the file names. +------------------------------------------------------------ + SYNTAX: N = FILES( A$ ) + PARAMETER: A$ is a string, LEN >= 1 +DESCRIPTION: Displays all the file names matching A$. +------------------------------------------------------------ + SYNTAX: N = FIX( X ) + PARAMETER: X is a number +DESCRIPTION: The truncated integer, part of X. FIX (X) is + equivalent to SGN(X)*INT(ABS(X)). The major + difference between FIX and INT is that FIX + does not return the next lower number for + negative X. +------------------------------------------------------------ + SYNTAX: N = FLOW +DESCRIPTION: Turn tracing ON +------------------------------------------------------------ + SYNTAX: N = FP( X ) + PARAMETER: X is a number +DESCRIPTION: The fractional part of X, i.e. X - IP(X). +------------------------------------------------------------ + SYNTAX: N = FRAC( X ) + PARAMETER: X is a number +DESCRIPTION: The fractional part of X, i.e. X - IP(X). +------------------------------------------------------------ + SYNTAX: N = FRE +DESCRIPTION: The number of bytes of available memory. This + function is provided for backward + compatibility only and it always returns a + fixed value of 32000. +------------------------------------------------------------ + SYNTAX: N = FRE( A$ ) + PARAMETER: A$ is a string, LEN >= 0 +DESCRIPTION: The number of bytes of available memory. This + function is provided for backward + compatibility only and it always returns a + fixed value of 32000.The value of A$ is + ignored. +------------------------------------------------------------ + SYNTAX: N = FRE( X ) + PARAMETER: X is a number +DESCRIPTION: The number of bytes of available memory. This + function is provided for backward + compatibility only and it always returns a + fixed value of 32000. The value of X is + ignored. +------------------------------------------------------------ + SYNTAX: N = FREEFILE +DESCRIPTION: The next available file number. +------------------------------------------------------------ + SYNTAX: N = GET( X ) + PARAMETER: X is a number, [MININT,MAXINT] +DESCRIPTION: For file X, gets the next available record. +------------------------------------------------------------ + SYNTAX: N = GET( X, Y ) + PARAMETER: X is a number, [MININT,MAXINT] + PARAMETER: Y is a number, [MININT,MAXINT] +DESCRIPTION: For file X, gets record number Y. The first + record number is 1. +------------------------------------------------------------ + SYNTAX: N = GRAD +DESCRIPTION: Configures the math functions to accept and + return angles in gradians. +------------------------------------------------------------ + SYNTAX: N = GRADIAN +DESCRIPTION: Configures the math functions to accept and + return angles in gradians. +------------------------------------------------------------ + SYNTAX: S$ = HEX$( X ) + PARAMETER: X is a number, [MININT,MAXINT] +DESCRIPTION: The the hexadecimal (base 16) representation + of X. +------------------------------------------------------------ + SYNTAX: N = HOME +DESCRIPTION: Clears the screen. Cursor is positioned at row + 1, column 1. +------------------------------------------------------------ + SYNTAX: N = INDEX( A$, B$ ) + PARAMETER: A$ is a string, LEN >= 0 + PARAMETER: B$ is a string, LEN >= 0 +DESCRIPTION: The position at which B$ occurs in A$, + beginning at position 1. +------------------------------------------------------------ + SYNTAX: S$ = INKEY$ +DESCRIPTION: The keypress, if available. If a keypress is + not available, then immediately returns an + empty string. If not supported by the + platform, then always returns an empty + string, so use INPUT$(1) instead. +------------------------------------------------------------ + SYNTAX: N = INP( X ) + PARAMETER: X is a number, [0,255] +DESCRIPTION: The value read from machine port X. Causes + ERROR 73. +------------------------------------------------------------ + SYNTAX: S$ = INPUT$( X ) + PARAMETER: X is a number, [0,MAXLEN] +DESCRIPTION: The string of X characters, read from the + terminal. +------------------------------------------------------------ + SYNTAX: S$ = INPUT$( X, Y ) + PARAMETER: X is a number, [0,MAXLEN] + PARAMETER: Y is a number, [MININT,MAXINT] +DESCRIPTION: The string of X characters, read from file Y. +------------------------------------------------------------ + SYNTAX: N = INSTR( A$, B$ ) + PARAMETER: A$ is a string, LEN >= 0 + PARAMETER: B$ is a string, LEN >= 0 +DESCRIPTION: The position at which B$ occurs in A$, + beginning at position 1. +------------------------------------------------------------ + SYNTAX: N = INSTR( X, A$, B$ ) + PARAMETER: X is a number, [1,MAXLEN] + PARAMETER: A$ is a string, LEN >= 0 + PARAMETER: B$ is a string, LEN >= 0 +DESCRIPTION: The position at which B$ occurs in A$, + beginning at position X. +------------------------------------------------------------ + SYNTAX: N = INT( X ) + PARAMETER: X is a number +DESCRIPTION: The largest integer not greater than X; e.g. + INT(1.3) = 1 and INT(-1.3) = 2. +------------------------------------------------------------ + SYNTAX: N = IP( X ) + PARAMETER: X is a number +DESCRIPTION: The integer part of X, i.e., + SGN(X)*INT(ABS(X)). +------------------------------------------------------------ + SYNTAX: S$ = KEY +DESCRIPTION: The keypress, if available. If a keypress is + not available, then immediately returns an + empty string. If not supported by the + platform, then always returns an empty + string, so use INPUT$(1) instead. +------------------------------------------------------------ + SYNTAX: S$ = KEY$ +DESCRIPTION: The keypress, if available. If a keypress is + not available, then immediately returns an + empty string. If not supported by the + platform, then always returns an empty + string, so use INPUT$(1) instead. +------------------------------------------------------------ + SYNTAX: N = KILL( A$ ) + PARAMETER: A$ is a string, LEN >= 1 +DESCRIPTION: Removes the file named in A$. +------------------------------------------------------------ + SYNTAX: N = LBOUND( ... ) +DESCRIPTION: LBOUND( arrayname [, dimension] ). The lower + bound of the array. The dimension defaults + to 1. dimension in [1,DIM(arrayname)] +------------------------------------------------------------ + SYNTAX: S$ = LCASE$( A$ ) + PARAMETER: A$ is a string, LEN >= 0 +DESCRIPTION: The string of characters from the value + associatedwith A$ by replacing each + upper-case-letter in the string by its + lower-case version. +------------------------------------------------------------ + SYNTAX: S$ = LEFT$( A$, X ) + PARAMETER: A$ is a string, LEN >= 0 + PARAMETER: X is a number, [0,MAXLEN] +DESCRIPTION: The X left-most characters of A$, beginning + from postion 1. +------------------------------------------------------------ + SYNTAX: N = LEN( A$ ) + PARAMETER: A$ is a string, LEN >= 0 +DESCRIPTION: The length of A$. +------------------------------------------------------------ + SYNTAX: N = LOC( X ) + PARAMETER: X is a number, [MININT,MAXINT] +DESCRIPTION: The location of file X; the next record that + GET or PUT statements will use. +------------------------------------------------------------ + SYNTAX: N = LOCATE( X, Y ) + PARAMETER: X is a number, [0,255] + PARAMETER: Y is a number, [0,255] +DESCRIPTION: Locates the cursor to row X, column Y. +------------------------------------------------------------ + SYNTAX: N = LOF( X ) + PARAMETER: X is a number, [MININT,MAXINT] +DESCRIPTION: The length of file X. +------------------------------------------------------------ + SYNTAX: N = LOG( X ) + PARAMETER: X is a number, > 0 +DESCRIPTION: The natural logarithm of X; X shall be greater + than zero. +------------------------------------------------------------ + SYNTAX: N = LOG10( X ) + PARAMETER: X is a number, > 0 +DESCRIPTION: The common logarithm of X; X shall be greater + than zero. +------------------------------------------------------------ + SYNTAX: N = LOG2( X ) + PARAMETER: X is a number, > 0 +DESCRIPTION: The base 2 logarithm of X; X shall be greater + than zero. +------------------------------------------------------------ + SYNTAX: N = LPOS +DESCRIPTION: The current cursor position in the line for + the printer. +------------------------------------------------------------ + SYNTAX: S$ = LTRIM$( A$ ) + PARAMETER: A$ is a string, LEN >= 0 +DESCRIPTION: The string of characters resulting from the + value associated with A$ by deleting all + leading space characters. +------------------------------------------------------------ + SYNTAX: N = LWIDTH( X ) + PARAMETER: X is a number, [0,255] +DESCRIPTION: For printer, sets the line width to X. Zero + means no wrapping will occur. +------------------------------------------------------------ + SYNTAX: S$ = MAX( A$, B$ ) + PARAMETER: A$ is a string, LEN >= 0 + PARAMETER: B$ is a string, LEN >= 0 +DESCRIPTION: The larger of the parameters. +------------------------------------------------------------ + SYNTAX: N = MAX( X, Y ) + PARAMETER: X is a number + PARAMETER: Y is a number +DESCRIPTION: The larger of the parameters. +------------------------------------------------------------ + SYNTAX: N = MAXBYT +DESCRIPTION: The largest finite positive number + representable as a BYTE; + implementation-defined. +------------------------------------------------------------ + SYNTAX: N = MAXCUR +DESCRIPTION: The largest finite positive number + representable as a CURRENCY; + implementation-defined. +------------------------------------------------------------ + SYNTAX: N = MAXDBL +DESCRIPTION: The largest finite positive number + representable as a DOUBLE; + implementation-defined. +------------------------------------------------------------ + SYNTAX: N = MAXDEV +DESCRIPTION: The largest finite positive number useable as + a FILE NUMBER; implementation-defined. +------------------------------------------------------------ + SYNTAX: N = MAXINT +DESCRIPTION: The largest finite positive number + representable as an INTEGER; + implementation-defined. +------------------------------------------------------------ + SYNTAX: N = MAXLEN +DESCRIPTION: The maximum string length. +------------------------------------------------------------ + SYNTAX: N = MAXLEN( A$ ) + PARAMETER: A$ is a string, LEN >= 0 +DESCRIPTION: The maximum length associated with the + simple-string-variable A$. +------------------------------------------------------------ + SYNTAX: N = MAXLNG +DESCRIPTION: The largest finite positive number + representable as a LONG; + implementation-defined. +------------------------------------------------------------ + SYNTAX: N = MAXLVL +DESCRIPTION: The maximum stack level; + implementation-defined. +------------------------------------------------------------ + SYNTAX: N = MAXNUM +DESCRIPTION: The largest finite positive number + representable and manipulable by the + implementation; implementation-defined. + MAXNUM may represent diffent number for + different arithmetic options (see OPTION + ARITHMETIC). +------------------------------------------------------------ + SYNTAX: N = MAXSNG +DESCRIPTION: The largest finite positive number + representable as a SINGLE; + implementation-defined. +------------------------------------------------------------ + SYNTAX: S$ = MID$( A$, X ) + PARAMETER: A$ is a string, LEN >= 0 + PARAMETER: X is a number, [1,MAXLEN] +DESCRIPTION: The characters of A$, starting from postion X. +------------------------------------------------------------ + SYNTAX: S$ = MID$( A$, X, Y ) + PARAMETER: A$ is a string, LEN >= 0 + PARAMETER: X is a number, [1,MAXLEN] + PARAMETER: Y is a number, [0,MAXLEN] +DESCRIPTION: The Y characters of A$, starting from postion + X. +------------------------------------------------------------ + SYNTAX: N = MIN( X, Y ) + PARAMETER: X is a number + PARAMETER: Y is a number +DESCRIPTION: The smaller of the parameters. +------------------------------------------------------------ + SYNTAX: S$ = MIN( A$, B$ ) + PARAMETER: A$ is a string, LEN >= 0 + PARAMETER: B$ is a string, LEN >= 0 +DESCRIPTION: The smaller of the parameters. +------------------------------------------------------------ + SYNTAX: N = MINBYT +DESCRIPTION: The largest finite negative number + representable as a BYTE; + implementation-defined. +------------------------------------------------------------ + SYNTAX: N = MINCUR +DESCRIPTION: The largest finite negative number + representable as a CURRENCY; + implementation-defined. +------------------------------------------------------------ + SYNTAX: N = MINDBL +DESCRIPTION: The largest finite negative number + representable as a DOUBLE; + implementation-defined. +------------------------------------------------------------ + SYNTAX: N = MINDEV +DESCRIPTION: The largest finite negative number useable as + a FILE NUMBER; implementation-defined. +------------------------------------------------------------ + SYNTAX: N = MININT +DESCRIPTION: The largest finite negative number + representable as an INTEGER; + implementation-defined. +------------------------------------------------------------ + SYNTAX: N = MINLNG +DESCRIPTION: The largest finite negative number + representable as a LONG; + implementation-defined. +------------------------------------------------------------ + SYNTAX: N = MINNUM +DESCRIPTION: The largest finite negative number + representable and manipulable by the + implementation; implementation-defined. + MINNUM may represent diffent number for + different arithmetic options (see OPTION + ARITHMETIC). +------------------------------------------------------------ + SYNTAX: N = MINSNG +DESCRIPTION: The largest finite negative number + representable as a SINGLE; + implementation-defined. +------------------------------------------------------------ + SYNTAX: S$ = MKC$( X ) + PARAMETER: X is a number, [MINCUR,MAXCUR] +DESCRIPTION: The internal representation of the currency + (64-bit) integer X as a string. +------------------------------------------------------------ + SYNTAX: S$ = MKD$( X ) + PARAMETER: X is a number, [MINDBL,MAXDBL] +DESCRIPTION: The internal representation of X as a string. +------------------------------------------------------------ + SYNTAX: N = MKDIR( A$ ) + PARAMETER: A$ is a string, LEN >= 1 +DESCRIPTION: Makes the directory named in A$. +------------------------------------------------------------ + SYNTAX: S$ = MKI$( X ) + PARAMETER: X is a number, [MININT,MAXINT] +DESCRIPTION: The internal representation of the short + (16-bit) integer X as a string. +------------------------------------------------------------ + SYNTAX: S$ = MKL$( X ) + PARAMETER: X is a number, [MINLNG,MAXLNG] +DESCRIPTION: The internal representation of the long + (32-bit) integer X as a string. +------------------------------------------------------------ + SYNTAX: S$ = MKS$( X ) + PARAMETER: X is a number, [MINFLT,MAXFLT] +DESCRIPTION: The internal representation of X as a string. +------------------------------------------------------------ + SYNTAX: N = NAME( A$, B$ ) + PARAMETER: A$ is a string, LEN >= 1 + PARAMETER: B$ is a string, LEN >= 1 +DESCRIPTION: Rename the file named A$ into B$. +------------------------------------------------------------ + SYNTAX: N = NOFLOW +DESCRIPTION: Turn tracing OFF +------------------------------------------------------------ + SYNTAX: N = NULL( X ) + PARAMETER: X is a number, [0,255] +DESCRIPTION: Appends X null characters after each line + printed by LPRINT or LLIST. +------------------------------------------------------------ + SYNTAX: N = NUM +DESCRIPTION: The number of values processed by the last MAT + INPUT. Zero means error. +------------------------------------------------------------ + SYNTAX: N = NUM( A$ ) + PARAMETER: A$ is a string, LEN >= 0 +DESCRIPTION: The value of the numeric-constant associated + with A$, if the string associated with A$ is + a numeric-constant. Leading and trailing + spaces in the string are ignored. If the + evaluation of the numeric-constant would + result in a value which causes an underflow, + then the value returned shall be zero. For + example, NUM( " 123.5 " ) = 123.5, NUM( + "2.E-99" ) could be zero, and NUM( "MCMXVII" + ) causes an exception. +------------------------------------------------------------ + SYNTAX: S$ = NUM$( X ) + PARAMETER: X is a number +DESCRIPTION: The string generated by the print-statement as + the numeric-representation of the value + associated with X. +------------------------------------------------------------ + SYNTAX: S$ = OCT$( X ) + PARAMETER: X is a number, [MININT,MAXINT] +DESCRIPTION: The the octal (base 8) representation of X. +------------------------------------------------------------ + SYNTAX: N = OPEN( A$, X, B$ ) + PARAMETER: A$ is a string, LEN >= 1 + PARAMETER: X is a number, [MININT,MAXINT] + PARAMETER: B$ is a string, LEN >= 1 +DESCRIPTION: Open file number X. A$ is the mode: "I", "O", + "A", "R". B$ is the file name. Default the + record length. +------------------------------------------------------------ + SYNTAX: N = OPEN( A$, X, B$, Y ) + PARAMETER: A$ is a string, LEN >= 1 + PARAMETER: X is a number, [MININT,MAXINT] + PARAMETER: B$ is a string, LEN >= 1 + PARAMETER: Y is a number, [MININT,MAXINT] +DESCRIPTION: Open file number X. A$ is the mode: "I", "O", + "A", "R". B$ is the file name. Y is the + record length. +------------------------------------------------------------ + SYNTAX: N = ORD( A$ ) + PARAMETER: A$ is a string, LEN >= 1 +DESCRIPTION: The ordinal position of the character named by + the string associated with A$ in the + collating sequence of ASCII character set, + where the first member of the character set + is in position zero. The acceptable values + for the standard character set are shown in + Table 1. +------------------------------------------------------------ + SYNTAX: N = OUT( X, Y ) + PARAMETER: X is a number, [MININT,MAXINT] + PARAMETER: Y is a number, [0,255] +DESCRIPTION: Sends Y to hardware port X. Causes ERROR 73. +------------------------------------------------------------ + SYNTAX: N = PAUSE( X ) + PARAMETER: X is a number +DESCRIPTION: The program pauses for X times the value of + OPTION SLEEP seconds. If the result is zero, + negative, or more than INT_MAX then PAUSE + does nothing. The resolution is + implementation defined. +------------------------------------------------------------ + SYNTAX: N = PEEK( X ) + PARAMETER: X is a number, [MINLNG,MAXLNG] +DESCRIPTION: The value read from hardware address X. + Causes ERROR 73. +------------------------------------------------------------ + SYNTAX: N = PI +DESCRIPTION: The constant 3.14159 which is the ratio of the + circumference of a circle to its diameter. +------------------------------------------------------------ + SYNTAX: N = PI( X ) + PARAMETER: X is a number +DESCRIPTION: The constant 3.14159 which is the ratio of the + circumference of a circle to its diameter, + times X. +------------------------------------------------------------ + SYNTAX: N = POKE( X, Y ) + PARAMETER: X is a number, [MINLNG,MAXLNG] + PARAMETER: Y is a number, [0,255] +DESCRIPTION: Sends Y to hardware address X. Causes ERROR + 73. +------------------------------------------------------------ + SYNTAX: N = POS +DESCRIPTION: The current cursor position in the line. +------------------------------------------------------------ + SYNTAX: N = POS( X ) + PARAMETER: X is a number, [MININT,MAXINT] +DESCRIPTION: The current cursor position in the line for + file X. +------------------------------------------------------------ + SYNTAX: N = POS( A$, B$ ) + PARAMETER: A$ is a string, LEN >= 0 + PARAMETER: B$ is a string, LEN >= 0 +DESCRIPTION: The character position, within the value + assocated with A$, of the first character of + the first occurence of the value associated + with B$, starting at the first character of + A$. If there is not such occurence, then the + value returned is zero. +------------------------------------------------------------ + SYNTAX: N = POS( A$, B$, X ) + PARAMETER: A$ is a string, LEN >= 0 + PARAMETER: B$ is a string, LEN >= 0 + PARAMETER: X is a number, [1,MAXLEN] +DESCRIPTION: The character position, within the value + assocated with A$, of the first character of + the first occurence of the value associated + with B$, starting at the Xth character of A$. + If there is not such occurence, then the + value returned is zero. +------------------------------------------------------------ + SYNTAX: N = PUT( X ) + PARAMETER: X is a number, [MININT,MAXINT] +DESCRIPTION: For file X, puts the next available record. +------------------------------------------------------------ + SYNTAX: N = PUT( X, Y ) + PARAMETER: X is a number, [MININT,MAXINT] + PARAMETER: Y is a number, [MININT,MAXINT] +DESCRIPTION: For file X, puts record number Y. The first + record number is 1. +------------------------------------------------------------ + SYNTAX: N = RAD +DESCRIPTION: Configures the math functions to accept and + return angles in radians. +------------------------------------------------------------ + SYNTAX: N = RAD( X ) + PARAMETER: X is a number +DESCRIPTION: The number of radians in X degrees. +------------------------------------------------------------ + SYNTAX: N = RADIAN +DESCRIPTION: Configures the math functions to accept and + return angles in radians. +------------------------------------------------------------ + SYNTAX: N = RANDOMIZE +DESCRIPTION: Seeds the pseudo-random number generator with + TIME. +------------------------------------------------------------ + SYNTAX: N = RANDOMIZE( X ) + PARAMETER: X is a number +DESCRIPTION: Seeds the pseudo-random number generator with + X. +------------------------------------------------------------ + SYNTAX: N = REMAINDER( X, Y ) + PARAMETER: X is a number + PARAMETER: Y is a number, <> 0 +DESCRIPTION: The remainder function, i.e., X-Y*IP(X/Y). Y + shall not equal zero. +------------------------------------------------------------ + SYNTAX: S$ = REPEAT$( X, A$ ) + PARAMETER: X is a number, [0,MAXLEN] + PARAMETER: A$ is a string, LEN >= 1 +DESCRIPTION: The string consisting of X copies of + LEFT$(A$,1); X > 0. +------------------------------------------------------------ + SYNTAX: S$ = REPEAT$( X, Y ) + PARAMETER: X is a number, [0,MAXLEN] + PARAMETER: Y is a number, [0,255] +DESCRIPTION: The string consisting of X copies of CHR$(Y); + X > 0. +------------------------------------------------------------ + SYNTAX: N = RESET +DESCRIPTION: Close all open files. +------------------------------------------------------------ + SYNTAX: S$ = RIGHT$( A$, X ) + PARAMETER: A$ is a string, LEN >= 0 + PARAMETER: X is a number, [0,MAXLEN] +DESCRIPTION: The right-most X characters of A$. +------------------------------------------------------------ + SYNTAX: N = RMDIR( A$ ) + PARAMETER: A$ is a string, LEN >= 1 +DESCRIPTION: Removes the directory named in A$. +------------------------------------------------------------ + SYNTAX: N = RND +DESCRIPTION: The next pseudo-random number in an + implementation-defined sequence of + pseudo-random numbers uniformly distributed + in the range 0 <= RND < 1. +------------------------------------------------------------ + SYNTAX: N = RND( X ) + PARAMETER: X is a number +DESCRIPTION: Returns a pseudorandom number in the range + [0,1]. The value of X is ignored. +------------------------------------------------------------ + SYNTAX: N = ROUND( X, Y ) + PARAMETER: X is a number + PARAMETER: Y is a number, [MININT,MAXINT] +DESCRIPTION: The value of X rounded to Y decimal digits to + the right of the decimal point (or -Y digits + to the left if Y < 0); i.e., + INT(X*10^Y+.5)/10^Y. Y must be in [-32,32]. +------------------------------------------------------------ + SYNTAX: S$ = RTRIM$( A$ ) + PARAMETER: A$ is a string, LEN >= 0 +DESCRIPTION: The string of characters resulting from the + value associated with A$ by deleting all + trailing space characters. +------------------------------------------------------------ + SYNTAX: N = SEC( X ) + PARAMETER: X is a number +DESCRIPTION: The secant of X, where X is in radians. +------------------------------------------------------------ + SYNTAX: N = SEEK( X ) + PARAMETER: X is a number, [MININT,MAXINT] +DESCRIPTION: The location of file X; the next record that + GET or PUT statements will use. +------------------------------------------------------------ + SYNTAX: N = SEEK( X, Y ) + PARAMETER: X is a number, [MININT,MAXINT] + PARAMETER: Y is a number, [MININT,MAXINT] +DESCRIPTION: For file X, move to record number Y; the first + record number is 1. +------------------------------------------------------------ + SYNTAX: S$ = SEG( A$, X, Y ) + PARAMETER: A$ is a string, LEN >= 0 + PARAMETER: X is a number, [1,MAXLEN] + PARAMETER: Y is a number, [0,MAXLEN] +DESCRIPTION: The Y characters of A$, starting from postion + X. +------------------------------------------------------------ + SYNTAX: S$ = SEG$( A$, X, Y ) + PARAMETER: A$ is a string, LEN >= 0 + PARAMETER: X is a number, [1,MAXLEN] + PARAMETER: Y is a number, [0,MAXLEN] +DESCRIPTION: The Y characters of A$, starting from postion + X. +------------------------------------------------------------ + SYNTAX: N = SGN( X ) + PARAMETER: X is a number +DESCRIPTION: The sign of X: -1 if X < 0, 0 if X = 0, and +1 + if X > 0. +------------------------------------------------------------ + SYNTAX: N = SHELL( A$ ) + PARAMETER: A$ is a string, LEN >= 1 +DESCRIPTION: The exit code resulting from the execution of + an operating system command. +------------------------------------------------------------ + SYNTAX: N = SIN( X ) + PARAMETER: X is a number +DESCRIPTION: The sine of X, where X is in radians. +------------------------------------------------------------ + SYNTAX: N = SIND( X ) + PARAMETER: X is a number +DESCRIPTION: The sine of X, where X is in degrees. +------------------------------------------------------------ + SYNTAX: N = SING( X ) + PARAMETER: X is a number +DESCRIPTION: The sine of X, where X is in gradians. +------------------------------------------------------------ + SYNTAX: N = SINH( X ) + PARAMETER: X is a number +DESCRIPTION: The hyperbolic sine of X. +------------------------------------------------------------ + SYNTAX: N = SLEEP( X ) + PARAMETER: X is a number +DESCRIPTION: The program pauses for X times the value of + OPTION SLEEP seconds. If the result is zero, + negative, or more than INT_MAX then SLEEP + does nothing. The resolution is + implementation defined. +------------------------------------------------------------ + SYNTAX: N = SNH( X ) + PARAMETER: X is a number +DESCRIPTION: The hyperbolic sine of X. +------------------------------------------------------------ + SYNTAX: S$ = SPACE$( X ) + PARAMETER: X is a number, [0,MAXLEN] +DESCRIPTION: The string of X blank spaces. +------------------------------------------------------------ + SYNTAX: S$ = SPC( X ) + PARAMETER: X is a number +DESCRIPTION: The string of X spaces. Only for use within + the PRINT command. +------------------------------------------------------------ + SYNTAX: N = SQR( X ) + PARAMETER: X is a number, >= 0 +DESCRIPTION: The non-negative square root of X; X shall be + non-negative. +------------------------------------------------------------ + SYNTAX: S$ = STR( X, Y ) + PARAMETER: X is a number, [0,MAXLEN] + PARAMETER: Y is a number, [0,255] +DESCRIPTION: The string X bytes long consisting of CHR$(Y). +------------------------------------------------------------ + SYNTAX: S$ = STR$( X ) + PARAMETER: X is a number +DESCRIPTION: The string generated by the print-statement as + the numeric-representation of the value + associated with X. +------------------------------------------------------------ + SYNTAX: S$ = STRING( X, Y ) + PARAMETER: X is a number, [0,MAXLEN] + PARAMETER: Y is a number, [0,255] +DESCRIPTION: The string X bytes long consisting of CHR$(Y). +------------------------------------------------------------ + SYNTAX: S$ = STRING$( X, A$ ) + PARAMETER: X is a number, [0,MAXLEN] + PARAMETER: A$ is a string, LEN >= 1 +DESCRIPTION: The string X bytes long consisting of the + first character of A$. +------------------------------------------------------------ + SYNTAX: S$ = STRING$( X, Y ) + PARAMETER: X is a number, [0,MAXLEN] + PARAMETER: Y is a number, [0,255] +DESCRIPTION: The string X bytes long consisting of CHR$(Y). +------------------------------------------------------------ + SYNTAX: S$ = TAB( X ) + PARAMETER: X is a number +DESCRIPTION: The string required to advance to column X. + Only for use within the PRINT command. +------------------------------------------------------------ + SYNTAX: N = TAN( X ) + PARAMETER: X is a number +DESCRIPTION: The tangent of X, where X is in radians. +------------------------------------------------------------ + SYNTAX: N = TAND( X ) + PARAMETER: X is a number +DESCRIPTION: The tangent of X, where X is in degrees. +------------------------------------------------------------ + SYNTAX: N = TANG( X ) + PARAMETER: X is a number +DESCRIPTION: The tangent of X, where X is in gradians. +------------------------------------------------------------ + SYNTAX: N = TANH( X ) + PARAMETER: X is a number +DESCRIPTION: The hyperbolic tangent of X. +------------------------------------------------------------ + SYNTAX: N = TIME +DESCRIPTION: The time elapsed since the previous midnight, + expressed in seconds; e.g., the value of TIME + at 11:15 AM is 40500. If there is no clock + available, then the value of TIME shall be + -1. The value of TIME at midnight shall be + zero (not 86400). +------------------------------------------------------------ + SYNTAX: S$ = TIME$ +DESCRIPTION: The time of day in 24-hour notation according + to ISO 3307. For example, the value of TIME$ + at 11:15 AM is "11:15:00". If there is no + clock available, then the value of TIME$ + shall be "99:99:99". The value of TIME$ at + midnight is "00:00:00". +------------------------------------------------------------ + SYNTAX: S$ = TIME$( X ) + PARAMETER: X is a number +DESCRIPTION: The time of day in 24-hour notation according + to ISO 3307. For example, the value of TIME$ + at 11:15 AM is "11:15:00". If there is no + clock available, then the value of TIME$ + shall be "99:99:99". The value of TIME$ at + midnight is "00:00:00". The value of X is + ignored. +------------------------------------------------------------ + SYNTAX: N = TIMER +DESCRIPTION: The time in the system clock in seconds + elapsed since midnight. +------------------------------------------------------------ + SYNTAX: S$ = TRIM$( A$ ) + PARAMETER: A$ is a string, LEN >= 0 +DESCRIPTION: The string resulting from removing both + leading and trailing spaces from A$. +------------------------------------------------------------ + SYNTAX: N = TROFF +DESCRIPTION: Turn tracing OFF +------------------------------------------------------------ + SYNTAX: N = TRON +DESCRIPTION: Turn tracing ON +------------------------------------------------------------ + SYNTAX: N = TRUNCATE( X, Y ) + PARAMETER: X is a number + PARAMETER: Y is a number, [MININT,MAXINT] +DESCRIPTION: The value of X truncated to Y decimal digits + to the right of the decimal point (or -Y + digits to the left if Y < 0); i.e., + IP(X*10^Y)/10^Y. Y in [-32,32]. +------------------------------------------------------------ + SYNTAX: N = UBOUND( ... ) +DESCRIPTION: UBOUND( arrayname [, dimension] ). The upper + bound of the array. The dimension defaults + to 1. dimension in [1,DIM(arrayname)] +------------------------------------------------------------ + SYNTAX: S$ = UCASE$( A$ ) + PARAMETER: A$ is a string, LEN >= 0 +DESCRIPTION: The string of characters resulting from the + value associated with A$ by replacing each + lower-case-letter in the string by its + upper-case version. +------------------------------------------------------------ + SYNTAX: N = VAL( A$ ) + PARAMETER: A$ is a string, LEN >= 1 +DESCRIPTION: The value of the numeric-constant associated + with A$, if the string associated with A$ is + a numeric-constant. Leading and trailing + spaces in the string are ignored. If the + evaluation of the numeric-constant would + result in a value which causes an underflow, + then the value returned shall be zero. For + example, VAL( " 123.5 " ) = 123.5, VAL( + "2.E-99" ) could be zero, and VAL( "MCMXVII" + ) causes an exception. +------------------------------------------------------------ + SYNTAX: N = WAIT( X ) + PARAMETER: X is a number +DESCRIPTION: The program pauses for X times the value of + OPTION SLEEP seconds. If the result is zero, + negative, or more than INT_MAX then WAIT does + nothing. The resolution is implementation + defined. +------------------------------------------------------------ + SYNTAX: N = WAIT( X, Y ) + PARAMETER: X is a number, [MININT,MAXINT] + PARAMETER: Y is a number, [0,255] +DESCRIPTION: Waits for the value of (INP(X) AND Y) to + become nonzero. Causes ERROR 73. +------------------------------------------------------------ + SYNTAX: N = WAIT( X, Y, Z ) + PARAMETER: X is a number, [MININT,MAXINT] + PARAMETER: Y is a number, [0,255] + PARAMETER: Z is a number, [0,255] +DESCRIPTION: Waits for the value of ((INP(X) XOR Z) AND Y) + to become nonzero. Causes ERROR 73. +------------------------------------------------------------ + SYNTAX: N = WIDTH( X ) + PARAMETER: X is a number, [0,255] +DESCRIPTION: For console, sets the line width to X. Zero + means no wrapping will occur. +------------------------------------------------------------ + SYNTAX: N = WIDTH( X, Y ) + PARAMETER: X is a number, [MININT,MAXINT] + PARAMETER: Y is a number, [0,255] +DESCRIPTION: If X = 0, sets the console width to Y. + If X < 0, sets the printer width to Y. + If X is an open file number, sets the file + line width to Y. + Otherwise sets the console rows to X and the + line width to Y. + A value of zero for Y means no wrapping will + occur. +------------------------------------------------------------ + + +============================================================ + OPERATORS +============================================================ + + +------------------------------------------------------------ + SYNTAX: X ** Y +DESCRIPTION: Exponential + PRECEDENCE: 14 +------------------------------------------------------------ + SYNTAX: X [ Y +DESCRIPTION: Exponential + PRECEDENCE: 14 +------------------------------------------------------------ + SYNTAX: X ^ Y +DESCRIPTION: Exponential + PRECEDENCE: 14 +------------------------------------------------------------ + SYNTAX: # X +DESCRIPTION: Posation + PRECEDENCE: 13 +------------------------------------------------------------ + SYNTAX: + X +DESCRIPTION: Posation + PRECEDENCE: 13 +------------------------------------------------------------ + SYNTAX: - X +DESCRIPTION: Negation + PRECEDENCE: 13 +------------------------------------------------------------ + SYNTAX: X * Y +DESCRIPTION: Multiplication + PRECEDENCE: 12 +------------------------------------------------------------ + SYNTAX: X / Y +DESCRIPTION: Division + PRECEDENCE: 12 +------------------------------------------------------------ + SYNTAX: X \ Y +DESCRIPTION: Integer Division + PRECEDENCE: 11 +------------------------------------------------------------ + SYNTAX: X MOD Y +DESCRIPTION: Integer Modulus + PRECEDENCE: 10 +------------------------------------------------------------ + SYNTAX: X + Y +DESCRIPTION: Addition + PRECEDENCE: 9 +------------------------------------------------------------ + SYNTAX: X - Y +DESCRIPTION: Subtraction + PRECEDENCE: 9 +------------------------------------------------------------ + SYNTAX: X & Y +DESCRIPTION: Concatenation + PRECEDENCE: 8 +------------------------------------------------------------ + SYNTAX: X < Y +DESCRIPTION: Less than + PRECEDENCE: 7 +------------------------------------------------------------ + SYNTAX: X <= Y +DESCRIPTION: Less than or Equal + PRECEDENCE: 7 +------------------------------------------------------------ + SYNTAX: X <> Y +DESCRIPTION: Not Equal + PRECEDENCE: 7 +------------------------------------------------------------ + SYNTAX: X = Y +DESCRIPTION: Equal + PRECEDENCE: 7 +------------------------------------------------------------ + SYNTAX: X =< Y +DESCRIPTION: Less than or Equal + PRECEDENCE: 7 +------------------------------------------------------------ + SYNTAX: X => Y +DESCRIPTION: Greater than or Equal + PRECEDENCE: 7 +------------------------------------------------------------ + SYNTAX: X > Y +DESCRIPTION: Greater than + PRECEDENCE: 7 +------------------------------------------------------------ + SYNTAX: X >< Y +DESCRIPTION: Not Equal + PRECEDENCE: 7 +------------------------------------------------------------ + SYNTAX: X >= Y +DESCRIPTION: Greater than or Equal + PRECEDENCE: 7 +------------------------------------------------------------ + SYNTAX: A$ LIKE B$ +DESCRIPTION: Compare A$ to the pattern in B$ + PRECEDENCE: 7 +------------------------------------------------------------ + SYNTAX: NOT X +DESCRIPTION: Bitwise NOT + PRECEDENCE: 6 +------------------------------------------------------------ + SYNTAX: X AND Y +DESCRIPTION: Bitwise AND + PRECEDENCE: 5 +------------------------------------------------------------ + SYNTAX: X OR Y +DESCRIPTION: Bitwise OR + PRECEDENCE: 4 +------------------------------------------------------------ + SYNTAX: X XOR Y +DESCRIPTION: Bitwise Exclusive OR + PRECEDENCE: 3 +------------------------------------------------------------ + SYNTAX: X EQV Y +DESCRIPTION: Bitwise EQV + PRECEDENCE: 2 +------------------------------------------------------------ + SYNTAX: X IMP Y +DESCRIPTION: Bitwise IMP + PRECEDENCE: 1 +------------------------------------------------------------ + + diff --git a/INFO/Bwbasic-Doc-2.1.txt b/INFO/Bwbasic-Doc-2.1.txt new file mode 100644 index 0000000..85a1818 --- /dev/null +++ b/INFO/Bwbasic-Doc-2.1.txt @@ -0,0 +1,1872 @@ +BWBASIC(1) General Commands Manual BWBASIC(1) + +NAME + bwbasic - Bywater BASIC interpreter/shell + + Bywater BASIC Interpreter/Shell, version 2.10 + --------------------------------------------- + + Copyright (c) 1993, Ted A. Campbell + for bwBASIC version 2.10, 11 October 1993 + + CONTENTS: + + 1. DESCRIPTION + 2. TERMS OF USE + 3. QUICK REFERENCE LIST OF COMMANDS AND FUNCTIONS + 4. GENERAL NOTES ON USAGE + 5. EXPANDED REFERENCE FOR COMMANDS AND FUNCTIONS + 6. PREDEFINED VARIABLES + 7. UNIMPLEMENTED COMMANDS AND FUNCTIONS + and AGENDA FOR DEVELOPMENT + 8. THE STORY OF BYWATER BASIC + 9. COMMUNICATIONS + + The author wishes to express his thanks to Mr. David MacKenzie, + who assisted in the development Unix installation and configuration + for this version. + + 1. 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. + + bwBASIC can be configured to emulate features, commands, and + functions available on different types of BASIC interpreters; + see the file INSTALL for further installation information. + + The interpreter is fairly slow. Whenever faced with a choice + between conceptual clarity and speed, I have consistently chosen + the former. The interpreter is the simplest design available, + and utilizes no system of intermediate code, which would speed + up considerably its operation. As it is, each line is interpreted + afresh as the interpreter comes to it. + + bwBASIC implements one feature not available in previous BASIC + interpreters: a shell command can be entered interactively at the + bwBASIC prompt, and the interpreter will execute it under a + command shell. For instance, the command "dir *.bas" can be + entered in bwBASIC (under DOS, or "ls -l *.bas" under UNIX) and + it will be executed as from the operating system command line. + Shell commands can also be given on numbered lines in a bwBASIC + program, so that bwBASIC can be used as a shell programming + language. bwBASIC's implementation of the RMDIR, CHDIR, MKDIR, + NAME, KILL, ENVIRON, and ENVIRON$() commands and functions + offer further shell-processing capabilities. + + 2. TERMS OF USE: + + 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. + + 3. QUICK REFERENCE LIST OF COMMANDS AND FUNCTIONS + + Be aware that many of these commands and functions will not be + available unless you have set certain flags in the header files + (see the expanded reference section below for dependencies). + + ABS( number ) + ASC( string$ ) + ATN( number ) + CALL subroutine-name + CASE ELSE | IF partial-expression | constant + CHAIN [MERGE] file-name [, line-number] [, ALL] + 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 + ELSE + ELSEIF + END IF | FUNCTION | SELECT | SUB + ENVIRON variable-string = string + ENVIRON$( variable-string ) + EOF( device-number ) + ERASE variable[, variable]... + ERL + ERR + ERROR number + EXP( number ) + FIELD [#] device-number, number AS string-variable [, number AS string-variable...] + FILES filespec$ + FUNCTION + FOR counter = start TO finish [STEP increment] + 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 line, column + 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 + 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] + QUIT + 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 ].... + + 4. GENERAL NOTES ON USAGE: + + 4.a. Interactive Environment + + An interactive environment is provided if the flag INTERACTIVE + is defined as TRUE in bwbasic.h, so that a line with a + line number can be entered at the bwBASIC prompt and it will be + added to the program in memory. + + Line numbers are not strictly required, but are useful if the + interactive environment is used for programming. For longer + program entry one might prefer to use an ASCII text editor, and + in this case lines can be entered without numbers. One can use + DO NUM and DO UNNUM to number or unnumber lines. See also the + documentation below for the pseudo-command EDIT. + + 4.b. Naming Conventions + + Command names and function names are not case sensitive, + so that "Run" and "RUN" and "run" are equivalent and "abs()" + and "ABS()" and "Abs()" are equivalent. HOWEVER, variable + names ARE case sensitive in bwbASIC, so that "d$" and "D$" + are different variables. This differs from some BASIC + implementations where variable names are not case sensitive. + + Variable names can use any alphabetic characters, the period + and underscore characters and decimal digits (but not in the + first position). They can be terminated with '#' or '!' to + allow Microsoft-type names, even though the precision is + irrelevant to bwBASIC. + + 4.c. Numerical Constants + + Numerical constants may begin with a digit 0-9 (decimal), with + the "&H" or "&h" (hexadecimal) or the "&o" or "&O" (octal). + Decimal numbers may terminated with 'E', 'e', 'D', or 'd' + followed by an exponent number to denote exponential notation. + Decimal constants may also be terminated by the '#' or '!' + to comply with Microsoft-style precision terminators, although + the precision specified will be irrelevant to bwBASIC. + + 4.d. Command-Line Execution + + A filename can be specified on the command line and will be + LOADed and RUN immediately, so that the command line + + bwbasic prog.bas + + will load and execute "prog.bas". + + 4.e. Program Storage + + All programs are stored as ASCII text files. + + 4.f. TRUE and FALSE + + TRUE is defined as -1 and FALSE is defined as 0 in the default + distribution of bwBASIC. These definitions can be changed by + those compiling bwBASIC (see file BWBASIC.H). + + 4.g. Assignments + + Assignment must be made to variables. This differs from some + implementations of BASIC where assignment can be made to a + function. Implication: "INSTR( 3, x$, y$ ) = z$" will not + work under bwBASIC. + + 4.h. Operators and Precedence + + bwBASIC recognizes the following operators, with their level + of precedence given (1 = highest): + + ^ 1 exponentiation + * 2 multiplication + / 2 division + 3 integer division + + 5 addition + - 5 subtraction + = 6 equality or assignment + MOD 4 modulus (remainder) arithmetic + <> 7 inequality + < 8 less than + > 9 greater than + <= 10 less than or equal to + =< 10 less than or equal to + >= 11 greater than or equal to + => 11 greater than or equal to + NOT 12 negation + AND 13 conjunction + OR 14 disjunction + XOR 15 exclusive or + IMP 16 implication + EQV 17 equivalence + + 4.h. Numerical Precision (NOT) + + bwBASIC utilizes numbers with only one level of precision. If + the flag NUMBER_DOUBLE is defined as TRUE in bwbasic.h, the + precision implemented will be that of the C "double" data type; + otherwise (default) the precision will be that of the C "float" + type. At a number of points there are commands (or pseudo- + commands) that seem to recognize Microsoft-style precision + distinctions, but for the most part these are just work-around + aliases to allow Microsoft-style programs to be run. + + 5. EXPANDED REFERENCE FOR COMMANDS AND FUNCTIONS + + The "Dependencies" listed in the following reference materials + refers to flags that must be set to TRUE in bwbasic.h for the + associated command or function to be implemented. These flags + are as follows: + + (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 Minimal 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 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 + + ------------------------------------------ + + Function: ABS( number ) + + Description: ABS returns the absolute value of the argument 'number'. + + Dependencies: (core) + + ------------------------------------------ + + Function: ASC( string$ ) + + Description: ASC returns the ASCII code for the first letter in + the argument string$. + + Dependencies: MS_FUNCS + + ------------------------------------------ + + Function: ATN( number ) + + Description: ATN returns the arctangent value of the argument 'number' + in radians. + + Dependencies: (core) + + ------------------------------------------ + + Command: CALL subroutine-name + + Description: CALL calls a named subroutine (see SUB and END SUB). + + Dependencies: STRUCT_CMDS + + ------------------------------------------ + + Command: CASE ELSE | IF partial-expression | constant + + Description: CASE introduces an element of a SELECT CASE statement + (see SELECT CASE). CASE IF introduces a conditional + SELECT CASE element, and CASE ELSE introduces a + default SELECT CASE element. + + Dependencies: STRUCT_CMDS + + ------------------------------------------ + + Command: CHAIN [MERGE] file-name [, line-number] [, ALL] + + Description: CHAIN passes control to another BASIC program. + Variables declared COMMON (q.v.) will be passed + to the new program. + + Dependencies: COMMON_CMDS + + ------------------------------------------ + + Command: CHDIR pathname$ + + Description: CHDIR changes the current directory to that indicated + by the argument pathname$. + + Dependencies: UNIX_CMDS + + ------------------------------------------ + + Function: CHR$( number ) + + Description: CHR$ returns a one-character string with the character + corresponding to the ASCII code indicated by argument + 'number'. + + Dependencies: COMMON_FUNCS + + ------------------------------------------ + + Function: CINT( number ) + + Description: CINT returns the truncated integer for the argument + 'number'. + + Dependencies: MS_FUNCS + + ------------------------------------------ + + Command: CLEAR + + Description: CLEAR sets all numerical variables to 0, and all + string variables to null. + + Dependencies: COMMON_CMDS + + ------------------------------------------ + + Command: CLOSE [[#]file-number]... + + Description: CLOSE closes the file indicated by file-number + (see OPEN). + + Dependencies: COMMON_CMDS + + ------------------------------------------ + + Command: CLS + + Description: CLS clears the display screen (IBM and compatibles + only as of version 2.10). + + Dependencies: IMP_IQC and IMP_CMDLOC + + ------------------------------------------ + + Command: CMDS + + Description: CMDS is a debugging command that prints a list + of all implemented bwBASIC commands. + + Dependencies: DEBUG + + ------------------------------------------ + + Command: COMMON variable [, variable...] + + Description: COMMON designates variables to be passed to a CHAINed + program (see CHAIN). + + Dependencies: COMMON_CMDS + + ------------------------------------------ + + Function: COS( number ) + + Description: COS returns the cosine of the argument 'number' + in radians. + + Dependencies: (core) + + ------------------------------------------ + + Function: CSNG( number ) + + Description: CSNG is a pseudo-function that has no effect under + bwBASIC. It replicates a Microsoft-type command + that would convert the 'number' to single-precision. + + Dependencies: MS_FUNCS + + ------------------------------------------ + + Function: CVD( string$ ) + + Description: CVD converts the argument string$ into a bwBASIC + number (precision is irrelevant in bwBASIC since + bwBASIC numbers have only one precision). + + Implementation-Specific Notes: + + CVD(), CVI(), CVS(), MKI$(), MKD$(), MKS$(): These functions + are implemented, but are dependent on a) the sizes for integer, + float, and double values on particular systems, and b) how + particular versions of C store these numerical values. The + implication is that data files created using these functions + on a DOS-based microcomputer may not be translated correctly + by bwBASIC running on a Unix-based computer. Similarly, data + files created by bwBASIC compiled by one version of C may not be + readable by bwBASIC compiled by another version of C (even under + the same operating system). So be careful with these. + + Dependencies: MS_FUNCS + + ------------------------------------------ + + Function: CVI( string$ ) + + Description: CVI converts the argument string$ into a bwBASIC + number (precision is irrelevant in bwBASIC since + bwBASIC numbers have only one precision; see also + the note on CVD). + + Dependencies: MS_FUNCS + + ------------------------------------------ + + Function: CVS( string$ ) + + Description: CVI converts the argument string$ into a bwBASIC + number (precision is irrelevant in bwBASIC since + bwBASIC numbers have only one precision; see also + the note on CVD). + + Dependencies: MS_FUNCS + + ------------------------------------------ + + Command: DATA constant[,constant]... + + Description: DATA stores numerical and string constants to be + accessed by READ (q.v.). + + Dependencies: (core) + + ------------------------------------------ + + Function: DATE$ + + Description: DATE$ returns the current date based on the computer's + internal clock as a string in the form "YYYY-MM-DD". + As implemented under bwBASIC, DATE$ cannot be used for + assignment (i.e., to set the system date). + + Note: bwBASIC presently (v2.10) does not allow assignment + to a function. + + Dependencies: COMMON_FUNCS + + ------------------------------------------ + + Command: DEF FNname(arg...)] = expression + + Description: DEF defines a user-written function. This function + corresponds to Microsoft-type implementation, although + in bwBASIC DEF is a working equivalent of FUNCTION. + + Dependencies: (core) + + ------------------------------------------ + + Command: DEFDBL letter[-letter](, letter[-letter])... + + Description: DEFDBL declares variables with single-letter names + as numerical variables (precision is irrelevant in + bwBASIC). + + Dependencies: MS_CMDS + + ------------------------------------------ + + Command: DEFINT letter[-letter](, letter[-letter])... + + Description: DEFINT declares variables with single-letter names + as numerical variables (precision is irrelevant in + bwBASIC). + + Dependencies: MS_CMDS + + ------------------------------------------ + + Command: DEFSNG letter[-letter](, letter[-letter])... + + Description: DEFSNG declares variables with single-letter names + as numerical variables (precision is irrelevant in + bwBASIC). + + Dependencies: MS_CMDS + + ------------------------------------------ + + Command: DEFSTR letter[-letter](, letter[-letter])... + + Description: DEFSTR declares variables with single-letter names + as string variables. + + Dependencies: MS_CMDS + + ------------------------------------------ + + Command: DELETE line[-line] + + Description: DELETE deletes program lines indicated by the + argument(s). If you want to use DELETE for non- + numbered programs, first use DO NUM, then DELETE, + then DO UNNUM. + + Dependencies: INTERACTIVE + + ------------------------------------------ + + Command: DIM variable(elements...)[variable(elements...)]... + + Description: DIM specifies variables that have more than one + element in a single dimension, i.e., arrayed + variables. + + Note: As implemented under bwBASIC, DIM accepts only + parentheses as delimiters for variable fields. + (Some BASICs allow the use of square brackets.) + + Dependencies: (core) + + ------------------------------------------ + + Command: DO NUM|UNNUM + + Description: DO NUM numbers all lines in a program. The first + line is given the number 10, and subsequent lines + are numbered consecutively in multiples of 10. DO + UNNUM removes all line numbers from a program. + NOTE that these functions do nothing to line + numbers, e.g., following a GOSUB or GOTO statement; + these commands cannot be used as a replacement for + RENUM (available in some systems, but not bwBASIC). + With these commands, however, one can develop + unnumbered programs by entering new lines with numbers, + then running DO UNNUM to remove the line numbers. + Together with LOAD and SAVE (q.v.) one can use + bwBASIC as a primitive text editor. + + Dependencies: INTERACTIVE + + ------------------------------------------ + + Command: DO [WHILE expression] + + Description: DO implements a number of forms of program loops. + DO...LOOP simply loops; the only way out is by + EXIT; DO WHILE...LOOP loops while "expression" is + true (this is equivalent to the older WHILE-WEND + loop, also implemented in bwBASIC); DO...LOOP UNTIL + loops until the expression following UNTIL is true. + + Dependencies: STRUCT_CMDS + + ------------------------------------------ + + Command: EDIT + + Description: EDIT is a pseudo-command which calls the text editor + specified in the variable BWB.EDITOR$ to edit the + program in memory. After the call to the text editor, + the (edited) program is reloaded into memory. The user + normally must specific a valid path and filename in + BWB.EDITOR$ before this command will be useful. + + Dependencies: COMMON_CMDS + + ------------------------------------------ + + Command: ELSE + + Description: ELSE introduces a default condition in a multi-line IF + statement. + + Dependencies: STRUCT_CMDS + + ------------------------------------------ + + Command: ELSEIF + + Description: ELSEIF introduces a secondary condition in a multi- + line IF statement. + + Dependencies: STRUCT_CMDS + + ------------------------------------------ + + Command: END IF | FUNCTION | SELECT | SUB + + Description: END IF ends a multi-line IF statement. END FUNCTION + ends a multi-line function definition. END SELECT + ends a SELECT CASE statement. END SUB ends a multi- + line subroutine definition. + + Dependencies: STRUCT_CMDS + + ------------------------------------------ + + Command: ENVIRON variable-string$ = string$ + + Description: ENVIRON sets the environment variable identified by + variable-string$ to string$. + + It might be noted that this differs from the implementation + of ENVIRON in some versions of BASIC, but bwBASIC's ENVIRON + allows BASIC variables to be used on either side of the equals + sign. Note that the function ENVIRON$() is different from the + command, and be aware of the fact that in some operating systems + an environment variable set within a program will not be passed + to its parent shell. + + Dependencies: UNIX_CMDS + + ------------------------------------------ + + Function: ENVIRON$( variable-string$ ) + + Description: ENVIRON$ returns the environment variable associated with + the name variable-string$. + + Dependencies: MS_FUNCS + + ------------------------------------------ + + Function: EOF( device-number ) + + Description: EOF returns TRUE (-1) if the device associated with + device-number is at the end-of-file, otherwise it + returns FALSE (0). + + Dependencies: MS_FUNCS + + ------------------------------------------ + + Command: ERASE variable[, variable]... + + Description: ERASE eliminates arrayed variables from a program. + + Dependencies: COMMON_CMDS + + ------------------------------------------ + + Function: ERL + + Description: ERL returns the line number of the most recent error. + + Dependencies: MS_FUNCS + + ------------------------------------------ + + Function: ERR + + Description: ERR returns the error number of the most recent error. + + Note that if PROG_ERRORS has been defined when bwBASIC is + compiled, the ERR variable will not be set correctly upon + errors. It only works when standard error messages are used. + + Dependencies: MS_FUNCS + + ------------------------------------------ + + Command: ERROR number + + Description: ERROR simulates an error, i.e., displays the message + appropriate for that error. This command is helpful + in writing ON ERROR GOSUB routines that can identify + a few errors for special treatment and then ERROR ERR + (i.e., default handling) for all others. + + Dependencies: COMMON_CMDS + + ------------------------------------------ + + Command: EXIT [FOR] + + Description: EXIT by itself exits from a DO...LOOP loop; + EXIT FOR exits from a FOR...NEXT loop. + + Dependencies: STRUCT_CMDS + + ------------------------------------------ + + Function: EXP( number ) + + Description: EXP returns the exponential value of 'number'. + + Dependencies: (core) + + ------------------------------------------ + + Command: FIELD [#] device-number, number AS string-variable$ [, number AS string-variable$...] + + Description: FIELD allocates space in a random file buffer for device + indicated by device-number, allocating 'number' bytes + and assigning the bytes at this position to the variable + string-variable$. + + Dependencies: COMMON_CMDS + + ------------------------------------------ + + Command: FILES filespec$ + + Description: FILES is a pseudocommand that invokes the directory program + specified in the variable BWB.FILES$ with the argument + filespec$. Normally, the user must set this variable + before FILES can be used. E.g., for PC-type computers, + + BWB.FILES$ = "DIR" + + will work, for Unix machines, + + BWB.FILES$ = "ls -l" + + etc. + + Dependencies: COMMON_CMDS + + ------------------------------------------ + + Command: FNCS + + Description: CMDS is a debugging command that prints a list + of all pre-defined bwBASIC functions. + + Dependencies: DEBUG + + ------------------------------------------ + + Command: FUNCTION + + Description: FUNCTION introduces a function definition, normally + ending with END FUNCTION. In bwBASIC, FUNCTION and + DEF are working equivalents, so either can be used + with single-line function definitions or with multi- + line definitions terminated by END FUNCTION. + + Dependencies: STRUCT_CMDS + + ------------------------------------------ + + Command: FOR counter = start TO finish [STEP increment] + + Description: FOR initiates a FOR-NEXT loop with the variable + 'counter' initially set to 'start' and incrementing + in 'increment' steps (default is 1) until 'counter' + equals 'finish'. + + Dependencies: (core) + + ------------------------------------------ + + Command: GET [#] device-number [, record-number] + + Description: GET reads the next record from a random-access file + or device into the buffer associated with that file. + If record-number is specified, the GET command reads the + specified record. + + Dependencies: COMMON_CMDS + + ------------------------------------------ + + Command: GOSUB line | label + + Description: GOSUB initiates a subroutine call to the line (or label) + specified. The subroutine must end with RETURN. + + Dependencies: (core), but STRUCT_CMDS for labels + + ------------------------------------------ + + Command: GOTO line | label + + Description: GOTO branches program execution to the specified line + (or label). + + Dependencies: (core), but STRUCT_CMDS for labels + + ------------------------------------------ + + Function: HEX$( number ) + + Description: HEX$ returns a string giving the hexadecimal (base 16) + value for the 'number'. + + Dependencies: MS_FUNCS + + ------------------------------------------ + + Command: IF expression THEN [statement [ELSE statement]] + + Description: IF evaluates 'expression' and performs the THEN + statement if it is true or (optionally) the + ELSE statement if it is FALSE. If STRUCT_CMDS + is set to TRUE, bwBASIC allows multi-line IF + statements with ELSE and ELSEIF cases, ending + with END IF. + + Dependencies: (core), STRUCT_CMDS for multi-line IF statements + + ------------------------------------------ + + Function: INKEY$ + + Description: INKEY$ reads the status of the keyboard, and a single + keypress, if available. If a keypress is not available, + then INKEY$ immediately returns a null string (""). + Currently (v2.10) implemented in bwx_iqc.c only. + + Dependencies: IMP_IQC and IMP_CMDLOC + + ------------------------------------------ + + Command: INPUT [# device-number]|[;]["prompt string";]list of variables + + Description: INPUT allows input from the terminal or a device + specified by device-number. If terminal, the "prompt + string" is output, and input is assigned to the + appropriate variables specified. + + bwBASIC does not support the optional feature of INPUT + that suppresses the carriage-return and line-feed at the end + of the input. This is because C alone does not provide for any + means of input other than CR-LF-terminated strings. + + Dependencies: (core) + + ------------------------------------------ + + Function: INSTR( [start-position,] string-searched$, string-pattern$ ) + + Description: INSTR returns the position at which string-pattern$ + occurs in string-searched$, beginning at start-position. + As implemented in bwBASIC, INSTR cannot be used for + assignments. + + Note: bwBASIC presently (v2.10) does not allow assignment + to a function. + + Dependencies: MS_FUNCS + + ------------------------------------------ + + Function: INT( number ) + + Description: INT returns the largest integer less than or equal to + the argument 'number'. NOTE that this is not a "truncated" + integer function, for which see CINT. + + Dependencies: (core) + + ------------------------------------------ + + Command: KILL file-name$ + + Description: KILL deletes the file specified by file-name$. + + Dependencies: UNIX_CMDS + + ------------------------------------------ + + Function: LEFT$( string$, number-of-spaces ) + + Description: LEFT$ returns a substring a string$ with number-of-spaces + from the left (beginning) of the string). As implemented + under bwBASIC, it cannot be used for assignment. + + Dependencies: MS_FUNCS + + ------------------------------------------ + + Function: LEN( string$ ) + + Description: LEN returns the length in bytes of string$. + + Dependencies: COMMON_FUNCS + + ------------------------------------------ + + Command: LET variable = expression + + Description: LET assigns the value of 'expression' to the variable. + As currently implemented, bwBASIC supports implied LET + statements (e.g., "X = 4.5678" at the beginning of + a line or line segment, but does not support assignment + to multiple variables (e.g., "x, y, z = 3.141596"). + + Dependencies: (core) + + ------------------------------------------ + + Command: LINE INPUT [[#] device-number,]["prompt string";] string-variable$ + + Description: LINE INPUT reads entire line from the keyboard or a file + or device into string-variable$. If input is from the + keyboard (stdin), then "prompt string" will be printed + first. Unlike INPUT, LINE INPUT reads a whole line, + not stopping for comma-delimited data items. + + Dependencies: COMMON_CMDS + + ------------------------------------------ + + Command: LIST line[-line] + + Description: LIST lists program lines as specified in its argument. + + Dependencies: INTERACTIVE + + ------------------------------------------ + + Command: LOAD file-name + + Description: LOAD loads an ASCII BASIC program into memory. + + Dependencies: INTERACTIVE + + ------------------------------------------ + + Function: LOC( device-number ) + + Description: LOC returns the next record that GET or PUT statements + will use. + + Dependencies: MS_FUNCS + + ------------------------------------------ + + Command: LOCATE line, column + + Description: LOCATE addresses trhe curor to a specified line and + column. Currently (v2.10) implemented in bwx_iqc.c only. + + Dependencies: IMP_IQC and IMP_CMDLOC + + ------------------------------------------ + + Function: LOF( device-number ) + + Description: LOF returns the length of a file (specified by device-number) + in bytes. + + Dependencies: MS_FUNCS + + ------------------------------------------ + + Function: LOG( number ) + + Description: LOG returns the natural logarithm of the argument 'number'. + + Dependencies: (core) + + ------------------------------------------ + + Command: LOOP [UNTIL expression] + + Description: LOOP terminates a program loop: see DO. + + Dependencies: STRUCT_CMDS + + ------------------------------------------ + + Command: LSET string-variable$ = expression + + Description: LSET transfers data from 'expression' to the left-hand + side of a string variable or random access buffer field. + + Dependencies: COMMON_CMDS + + ------------------------------------------ + + Command: MERGE file-name + + Description: MERGE adds program lines from 'file-name' to the program + in memory. Unlike LOAD, it does not clear the program + currently in memory. + + Dependencies: COMMON_CMDS + + ------------------------------------------ + + Function: MID$( string$, start-position-in-string[, number-of-spaces ] ) + + Description: MID$ returns a substring of string$ beginning at + start-position-in-string and continuing for + number-of-spaces bytes. + + Dependencies: MS_FUNCS + + ------------------------------------------ + + Command: MKDIR pathname$ + + Description: MKDIR creates a new directory path as specified by + pathname$. + + Dependencies: UNIX_CMDS + + ------------------------------------------ + + Function: MKD$( number ) + + Description: MKD$, MKI$, and MKS$ are all equivalent in bwBASIC. + They convert the numerical value 'number' into a string + which can be stored in a more compressed form in a file + (especially for random file access). Since bwBASIC does + not recognize differences in precision, these commands + are effectively equivalent. + + Dependencies: MS_FUNCS + + ------------------------------------------ + + Function: MKI$( number ) + + Description: Equivalent to MKD$ (q.v.) + + Dependencies: MS_FUNCS + + ------------------------------------------ + + Function: MKS$( number ) + + Description: Equivalent to MKD$ (q.v.). + + Dependencies: MS_FUNCS + + ------------------------------------------ + + Command: NAME old-file-name AS new-file-name + + Description: NAME renames an existing file (old-file-name) as + new-file-name. + + Dependencies: UNIX_CMDS + + ------------------------------------------ + + Command: NEW + + Description: NEW deletes the program in memory and clears all + variables. + + Dependencies: INTERACTIVE + + ------------------------------------------ + + Command: NEXT [counter-variable] + + Description: NEXT comes at the end of a FOR-NEXT loop; see FOR. + + Dependencies: (core) + + ------------------------------------------ + + Function: OCT$( number ) + + Description: OCT$ returns a string giving the octal (base 8) + representation of 'number'. + + Dependencies: MS_FUNCS + + ------------------------------------------ + + Command: ON variable GOTO|GOSUB line[,line,line,...] + + Description: ON either branches (GOTO) or calls a subroutine + (GOSUB) based on the rounded value of variable; + if it is 1, the first line is called, if 2, the second + line is called, etc. + + Dependencies: (core) + + ------------------------------------------ + + Command: ON ERROR GOSUB line|label + + Description: ON ERROR sets up an error handling subroutine. See + also ERROR. + + Dependencies: COMMON_CMDS, STRUCT_CMDS for labels + + ------------------------------------------ + + Command: OPEN "O"|"I"|"R", [#]device-number, file-name [,record length] + file-name FOR INPUT|OUTPUT|APPEND AS [#]device-number [LEN = record-length] + + Description: OPEN allocates random access memory for access to a disk + file or other device. Note that two quite different forms + of the OPEN statement are supported. In the first form, + "O" (note that these letters must be encased in quotation + marks) denotes sequential output, "I" denotes sequential + input, and "R" denotes random-access input and output. + Once OPEN, any number of operations can be performed + on a device (see WRITE #, INPUT #, PRINT #, etc.). + + Dependencies: COMMON_CMDS + + ------------------------------------------ + + Command: OPTION BASE number + + Description: OPTION BASE sets the lowest value for array subscripts, + either 0 or 1. + + Dependencies: (core) + + ------------------------------------------ + + Function: POS + + Description: POS returns the current cursor position in the line. + + Dependencies: COMMON_FUNCS + + ------------------------------------------ + + Command: PRINT [# device-number,][USING format-string$;] expressions... + + Description: PRINT outputs text to the screen or to a file or device + specified by device-number. In the current implementation + of bwBASIC, expressions to be printed must be separated by + the comma (tabbed output), the semicolon (immediate + sequential output) or the plus sign (immediate sequential + output by string concatenation). Expressions separated + by blanks or tabs are not supported. If USING is specified, + a number of formatting marks may appear in the format + string: + + ! prints the first character of a string + + \ prints 2+x characters of a string, where x = + the number of spaces between the backslashes + + & variable-length string field + + # represents a single digit in output format for + a number + + . decimal point in a number + + + sign of a number (will output + or -) + + - trailing minus after a number + + ** fill leading spaces with asterisks + + $$ output dollar sign in front of a number + + ^^ output number in exponential format + + _ output next character literally + + As currently implemented, the exponential format + will be that used by the C compiler. + + Dependencies: (core), COMMON_FUNCS for USING + + ------------------------------------------ + + Command: PUT [#] device-number [, record-number] + + Description: PUT outputs the next available record or the record + specified by record-number to the file or device + denoted by device-number. + + Dependencies: COMMON_CMDS + + ------------------------------------------ + + Command: QUIT + + Description: QUIT is a synonym for SYSTEM; with INTERACTIVE + environment, it exits the program to the + operating system (or the calling program). + + Dependencies: INTERACTIVE + + ------------------------------------------ + + Command: RANDOMIZE number + + Description: RANDOMIZE seeds the random number generator (see RND). + Under bwBASIC, the TIMER function (q.v.) can be used + to supply a 'number' seed for the random number + generator. + + Dependencies: (core) + + ------------------------------------------ + + Command: READ variable[, variable]... + + Description: READ reads values from DATA statements and assigns these + values to the named variables. Variable types in a READ + statement must match the data types in DATA statements + as they are occurred. See also DATA and RESTORE. + + Dependencies: (core) + + ------------------------------------------ + + Command: REM string + + Description: REM allows remarks to be included in a program. As + currently implemented, the entire line following + REM is ignored by the interpreter (thus, even if + MULTISEG_LINES is set, a REM line will not be able + to find a segment delimiter (":") followed by another + line segment with command. bwBASIC does not currently + implement the Microsoft-style use of the single quotation + mark to denote remarks. + + Dependencies: (core) + + ------------------------------------------ + + Command: RESTORE line + + Description: RESTORE resets the line and position counters for DATA + and READ statements to the top of the program file or + to the beginning of the specified line. (Currently this + must be a line number.) + + Dependencies: (core) + + ------------------------------------------ + + Command: RETURN + + Description: RETURN concludes a subroutine called by GOSUB. + + Dependencies: (core) + + ------------------------------------------ + + Function: RIGHT$( string$, number-of-spaces ) + + Description: RIGHT$ returns a substring a string$ with number-of-spaces + from the right (end) of the string). As implemented + under bwBASIC, it cannot be used for assignment. + + Dependencies: MS_FUNCS + + ------------------------------------------ + + Command: RMDIR pathname + + Description: RMDIR deletes the directory path indicated by pathname. + + Dependencies: UNIX_CMDS + + ------------------------------------------ + + Function: RND( number ) + + Description: RND returns a pseudo-random number. The 'number' value + is ignored by bwBASIC if supplied. The RANDOMIZE + command (q.v.) reseeds the random-number generator. + + Dependencies: (core) + + ------------------------------------------ + + Command: RSET string-variable$ = expression + + Description: RSET transfers data from 'expression' to the right-hand + side of a string variable or random access buffer field. + + Dependencies: COMMON_CMDS + + ------------------------------------------ + + Command: RUN [line][file-name$] + + Description: RUN executes the program in memory. If a file-name$ is + supplied, then the specified file is loaded into memory + and executed. If a line number is supplied, then execution + begins at that line. + + Dependencies: INTERACTIVE + + ------------------------------------------ + + Command: SAVE file-name$ + + Description: SAVE saves the program in memory to file-name$. bwBASIC + only saves files in ASCII format. + + Dependencies: INTERACTIVE + + ------------------------------------------ + + Command: SELECT CASE expression + + Description: SELECT CASE introduces a multi-line conditional selection + statement. The expression given as the argument to SELECT + CASE will be evaluated by CASE statements following. The + SELECT CASE statement concludes with an END SELECT + statement. + + As currently implemented, CASE statements may be followed + by string values, but in this case only simple comparisons + (equals, not equals) can be performed. + + Dependencies: STRUCT_CMDS + + ------------------------------------------ + + Function: SGN( number ) + + Description: SGN returns the sign of the argument 'number', +1 + for positive numbers, 0 for 0, and -1 for negative numbers. + + Dependencies: (core) + + ------------------------------------------ + + Function: SIN( number ) + + Description: SIN returns the sine of the argument 'number' + in radians. + + Dependencies: (core) + + ------------------------------------------ + + Function: SPACE$( number ) + + Description: SPACE$ returns a string of blank spaces 'number' + bytes long. + + Dependencies: MS_FUNCS + + ------------------------------------------ + + Function: SPC( number ) + + Description: SPC returns a string of blank spaces 'number' + bytes long. + + Dependencies: MS_FUNCS + + ------------------------------------------ + + Function: SQR( number ) + + Description: SQR returns the square root of the argument 'number'. + + Dependencies: (core) + + ------------------------------------------ + + Command: STOP + + Description: STOP interrupts program execution. As implemented under + bwBASIC, STOP issues a SIGINT signal. + + Dependencies: (core) + + ------------------------------------------ + + Function: STR$( number ) + + Description: STR$ returns a string giving the decimal (base 10) + representation of the argument 'number'. + + Dependencies: COMMON_FUNCS + + ------------------------------------------ + + Function: STRING$( number, ascii-value|string$ ) + + Description: STRING$ returns a string 'number' bytes long consisting + of either the first character of string$ or the character + answering to the ASCII value ascii-value. + + Dependencies: MS_FUNCS + + ------------------------------------------ + + Command: SUB subroutine-name + + Description: SUB introduces a named, multi-line subroutine. The + subroutine is called by a CALL statement, and concludes + with an END SUB statement. + + Dependencies: STRUCT_CMDS + + ------------------------------------------ + + Command: SWAP variable, variable + + Description: SWAP swaps the values of two variables. The two variables + must be of the same type (either numerical or string). + + Dependencies: COMMON_CMDS + + ------------------------------------------ + + Command: SYSTEM + + Description: SYSTEM exits from bwBASIC to the calling program or + (more usually) the operating system. + + Dependencies: INTERACTIVE + + ------------------------------------------ + + Function: TAB( number ) + + Description: TAB outputs spaces until the column indicated by + 'number' has been reached. + + Dependencies: (core) + + ------------------------------------------ + + Function: TAN( number ) + + Description: TAN returns the tangent of the argument 'number' + in radians. + + Dependencies: (core) + + ------------------------------------------ + + Function: TIME$ + + Description: TIME$ returns the current time based on the computer's + internal clock as a string in the form "HH-MM-SS". + As implemented under bwBASIC, TIME$ cannot be used for + assignment (i.e., to set the system time). + + Note: bwBASIC presently (v2.10) does not allow assignment + to a function. + + Dependencies: COMMON_FUNCS + + ------------------------------------------ + + Function: TIMER + + Description: TIMER returns the time in the system clock in seconds + elapsed since midnight. + + Dependencies: MS_FUNCS + + ------------------------------------------ + + Command: TROFF + + Description: TROFF turns of the trace facility; see TRON. + + Dependencies: COMMON_CMDS + + ------------------------------------------ + + Command: TRON + + Description: TRON turns on the trace facility. This facility will print + each line number in square brackets as the program is + executed. This is useful in debugging programs with + line numbers. To debug an unnumbered program with + TRON, call DO NUM first, but remember to call DO UNNUM + before you save the program later. + + Dependencies: COMMON_CMDS + + ------------------------------------------ + + Function: VAL( string$ ) + + Description: VAL returns the numerical value of the string$. + + Dependencies: COMMON_FUNCS + + ------------------------------------------ + + Command: VARS + + Description: VARS is a debugging command which prints a list of + all variables defined which have global scope. + + Dependencies: DEBUG + + ------------------------------------------ + + Command: WEND + + Description: WEND concludes a WHILE-WEND loop; see WHILE. + + Dependencies: COMMON_CMDS + + ------------------------------------------ + + Command: WHILE expression + + Description: WHILE initiates a WHILE-WEND loop. The loop ends with + WEND, and execution reiterates through the loop as + long as the 'expression' is TRUE (-1). + + Dependencies: COMMON_CMDS + + ------------------------------------------ + + Command: WIDTH [# device-number,] number + + Description: WIDTH sets screen or device output to 'number' + columns. device-number specifies the device + or file for output. + + Dependencies: COMMON_CMDS + + ------------------------------------------ + + Command: WRITE [# device-number,] element [, element ].... + + Description: WRITE outputs variables to the screen or to a file + or device specified by device-number. Commas + are inserted between expressions output, and strings + are enclosed in quotation marks. + + Dependencies: COMMON_CMDS + + ------------------------------------------ + + 6. PREDEFINED VARIABLES + + BWB.EDITOR$ + BWB.FILES$ + BWB.PROMPT$ + BWB.IMPLEMENTATION$ + + The commands EDIT and FILES are pseudo-commands that launch + shell programs named in the variables BWB.EDITOR$ and BWB.FILES$, + respectively. The default values for these variables can + be changed in bwbasic.h (DEF_EDITOR and DEF_FILES), or they + can be changed on the fly by the user. An idea might be to + initialize these variables in "profile.bas" for specific + implementations; for instance, BWB.FILES$ might be defined as + "ls -l" on Unix systems or "dir" on DOS systems. + + The preset variable BWB.PROMPT$ can be used to set the prompt + string for bwBASIC. Again, it is suggested that a user- + selected prompt can be set up in a "profile.bas" to be + initialized each time bwBASIC starts. Note that special + characters can be added to the prompt string, e.g., + + BWB.PROMPT$ = "Ok"+CHR$(10) + + will give an "Ok" prompt followed by a linefeed. + + The preset variable BWB.IMPLEMENTATION$ will return "TTY" for + the bwx_tty implementation and will return "IQC" for the + IBM PC or Compatibles with QuickC (bwx_iqc) implementation. + This may be useful in determining which commands and functions + (specifically CLS, LOCATE, and INKEY$) may be available. + + 7. UNIMPLEMENTED COMMANDS AND FUNCTIONS, and AGENDA FOR DEVELOPMENT + + There are some items not implemented that have been so long + a part of standard BASICs that their absence will seem surprising. + In each case, though, their implementation would require opera- + ting-system-specific functions or terminal-specific functions + that cannot be universally provided. Some specific examples: + + CLOAD Relies on CP/M or MSDOS conventions for binary + executable files. + + CONT See RESUME below (programmer ignorance?). + + DEF USR Relies on CP/M or MSDOS conventions for binary + executable files. + + FRE() The ability to report the amount of free memory + remaining is system-specific due to varying patterns + of memory allocation and access; consequently this + ability is not present in ANSI or earlier versions + of C and this function is not available in bwBASIC. + + INPUT$() C by itself is not able to read unechoed keyboard + input, and can read keyboard input only after a + Carriage-Return has been entered. + + INP Calls to hardware ports, like machine-language + routines, are highly system-specific and cannot + be implemented in C alone. + + LLIST See LPRINT below. + + LPOS See LPRINT below. + + LPRINT and LLIST, etc., require access to a printer device, + and this varies from one system to another. Users + might try OPENing the printer device on their own + operating system (e.g., "/dev/lp" on Unix systems, + or "PRN" under DOS) and see if printing can be done + from bwBASIC in this way. + + NULL In this case, I am convinced that NULL is no longer + necessary, since very few printers now require NULLs + at the end of lines. + + OUT See INP above (calls to hardware ports). + + PEEK() PEEK and POKE enabled earlier BASICs to address + particular memory locations. Although bwBASIC + could possibly implement this command (POKE) and + this function (PEEK()), the limitation would be + highly limited by the different systems for + memory access in different systems. + + POKE see PEEK() above. + + RENUM Since unnumbered lines can be entered and + executed under bwBASIC, it would not be + possible to implement a RENUM routine. + Instead, bwBASIC uses DO NUM and DO UNNUM. + + RESUME Is this possible under C? If so, I + simply have failed to figure it out yet. + Mea culpa (but not maxima). + + USR See CALL and DEF USR above (machine language + subroutines). + + VARPTR See PEEK and POKE above. + + WAIT See INP and OUT above. + + There are other commands, functions, and implementation details + that I am working on, and which are on the agenda list for future + versions of bwBASIC. These agenda include: + + PARACT i.e., the ability to execute PARallel ACTions. This + is described in ANSI BASIC, although I have not seen it + implemented before. It will offer a rough, non- + preemptive form of multitasking within the scope + of a BASIC program. Programmers will note points at which + there are already hooks for PARACT in bwBASIC. + + XMEM PC-type computers need to be able to use extended + memory. If we could use extended memory for program + lines, variables, and function definitions, we could + write much longer programs. This would entail, + however, a fairly serious rewriting of the program + to utilize memory handles for these storage features + instead of direct memory pointers. + + Windows The addition of memory handles in addition to the + non-preemptive execution of program lines (in a + crude form, already present) will make it possible + to develop implementations for Windows and perhaps + for other graphical user interfaces. But what form + should this take? I have in mind presently a BASIC + that would run in the background, appearing only + as an icon in the GUI space, with pop-up editors + and output windows. Thus, the interpreted language + would serve a purpose something like 'cron' (a task + scheduler) under Unix systems. You may have some + reflections that would help me in this. + + Graphics Here we face fairly critical differences in different + styles and implementations of graphics, e.g., between + GWBASIC, ANSI BASIC, VisualBASIC, etc. But it's + possible that Graphics commands and functions could + be added. These would all be implementation-specific. + + The ANSI Standard for full BASIC does not specify which particular + commands or functions must be implemented, and in fact the standard + is very robust. Perhaps no implementation of BASIC would ever + include all of the items, but some ANSI commands and functions which + remain unimplemented are: + + ACCESS + ANGLE + AREA + ARITHMETIC + ARRAY + ASK + BSTR + BVAL + CEIL + CELLS + CLIP + COLLATE + CONNECT + COSH + DATUM + DEBUG + DECIMAL + DECLARE + DEGREES + DEVICE + DISCONNECT + DISPLAY + DOT + DRAW + ERASE + EVENT + EXCEPTION + GRAPH + HANDLER + IMAGE + KEY + LCASE + LINES + LOG10 + LOG2 + MAT + MIX + MULTIPOINT + OUTIN + OUTPUT + PARACT + PICTURE + PIXEL + PLOT + POINTS + RADIANS + RECEIVE + RENUMBER + REWRITE + ROTATE + ROUND + SEIZE + SEND + SHIFT + SINH + TANH + TIMEOUT + TRACE + TRANSFORM + TRUNCATE + UBOUND + UCASE + VIEWPORT + WAIT + VIEWPORT + ZONEWIDTH + + 8. THE STORY OF BYWATER BASIC + + This program was originally begun in 1982 by my grandmother, Mrs. + Verda Spell of Beaumont, TX. She was writing the program using + an ANSI C compiler on an Osborne I CP/M computer and although my + grandfather (Lockwood Spell) had bought an IBM PC with 256k of + RAM my grandmother would not use it, paraphrasing George Herbert + to the effect that "He who cannot in 64k program, cannot in 512k." + She had used Microsoft BASIC and although she had nothing against + it she said repeatedly that she didn't understand why Digital + Research didn't "sue the socks off of Microsoft" for version 1.0 + of MSDOS and so I reckon that she hoped to undercut Microsoft's + entire market and eventually build a new software empire on + the North End of Beaumont. Her programming efforts were cut + tragically short when she was thrown from a Beaumont to Port + Arthur commuter train in the summer of 1986. I found the source + code to bwBASIC on a single-density Osborne diskette in her knitting + bag and eventually managed to have it all copied over to a PC + diskette. I have revised it slightly prior to this release. You + should know, though, that I myself am an historian, not a programmer. + + 9. COMMUNICATIONS: + + email: tcamp@delphi.com + + October 11, 1993 BWBASIC(1) diff --git a/INFO/Bwbasic-changelog.txt b/INFO/Bwbasic-changelog.txt new file mode 100644 index 0000000..08a3fa3 --- /dev/null +++ b/INFO/Bwbasic-changelog.txt @@ -0,0 +1,481 @@ + + + README file for + + + Bywater BASIC Interpreter, version 3.20 + --------------------------------------------- + + Copyright (c) 1993, Ted A. Campbell + for bwBASIC version 2.10, 11 October 1993 + + Version 2.20 modifications by Jon B. Volkoff, + 25 November 1995 + + Patch level 1 release by Jon B. Volkoff, + 15 March 1996 + + Patch level 2 release by Jon B. Volkoff, + 11 October 1997 + + Version 2.30 modifications by Paul Edwards, + 5 March 2008 + + Version 2.40 modifications by Paul Edwards, + 26 Jan 2009 + + Version 2.50 modifications by Paul Edwards, + 4 June 2009 + + Version 2.60 modifications by Paul Edwards, + 6 November 2012 + + Version 2.61 modifications by Paul Edwards, + 4 August 2014 + + Version 3.00 modifications by Howard Wulf, AF5NE + 12 May 2015 + + Version 3.10 modifications by Howard Wulf, AF5NE + 27 July 2016 + + Version 3.20 modifications by Howard Wulf, AF5NE + 4 June 2017 + + + + +DESCRIPTION: + + The Bywater BASIC Interpreter (bwBASIC) implements a large + superset of the ANSI Standard for Minimal BASIC (X3.60-1978), + a significant subset of the ANSI Standard for Full BASIC + (X3.113-1987), and many classic BASIC dialects in C. 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. + + + +OBTAINING THE SOURCE CODE: + + The source code for bwBASIC is available from + http://bwbasic.sourceforge.net + + +COMMUNICATIONS: + + email: tcamp@delphi.com (for Ted Campbell) + eidetics@cerf.net (for Jon Volkoff) + mutazilah@gmail.com (for Paul Edwards) + + +A LIST OF BASIC COMMANDS AND FUNCTIONS IMPLEMENTED in bwBASIC: + + The complete list of over 500 commands, functions and operators is + in the file "ALL.txt" in the DOCS directory. Documentation for each + dialect is also in the DOCS directory. Be aware that the commands, + functions and operators available depend upon the particular BASIC + dialect selected using the OPTION VERSION command. + + +CHANGE HISTORY + +CHANGES FROM 3.10 to 3.20 + + * Implements most of the following BASIC dialects: + OPTION VERSION "BYWATER" ' Bywater BASIC 3 + OPTION VERSION "BYWATER-2" ' Bywater BASIC 2 + OPTION VERSION "CALL/360" ' SBC CALL/360 Mainframe BASIC + OPTION VERSION "CBASIC-II" ' CBASIC-II for CP/M + OPTION VERSION "DARTMOUTH" ' Dartmouth DTSS BASIC + OPTION VERSION "ECMA-55" ' ANSI Minimal BASIC + OPTION VERSION "ECMA-116" ' ANSI Full BASIC + OPTION VERSION "GCOS" ' GE 600 Mainframe BASIC + OPTION VERSION "HAARDT" ' bas 2.4 by Michael Haardt + OPTION VERSION "HANDBOOK1" ' The BASIC Handbook, 1st Edition + OPTION VERSION "HANDBOOK2" ' The BASIC Handbook, 2nd Edition + OPTION VERSION "HEATH" ' Heath Benton Harbor BASIC + OPTION VERSION "MARK-I" ' GE 265 Mainframe BASIC + OPTION VERSION "MARK-II" ' GE 435 Mainframe BASIC + OPTION VERSION "MBASIC" ' Microsoft BASIC-80 for Xenix + OPTION VERSION "PDP-8" ' DEC PDP-8 BASIC + OPTION VERSION "PDP-11" ' DEC PDP-11 BASIC + OPTION VERSION "RBASIC" ' Micronics RBASIC for 6809 FLEX + OPTION VERSION "RSTS-11" ' DEC RSTS-11 BASIC-PLUS + OPTION VERSION "SYSTEM/360" ' IBM System/360 Mainframe BASIC + OPTION VERSION "SYSTEM/370" ' IBM System/370 Mainframe BASIC + OPTION VERSION "TRS-80" ' TRS-80 Model I/III/4 LBASIC + OPTION VERSION "VINTAGE" ' Vintage BASIC 1.0.1 + OPTION VERSION "XBASIC" ' TSC XBASIC for 6800 FLEX + + * CONST variable [, ...] = value + Assigns the value to variable. + Any later assignment to the variable causus a VARIABLE NOT DECLARED error. + + * DIM now supports lower and upper bounds. + OPTION BASE 1 + DIM X( 9 ) ' lower bound is 1 + DIM Y( 5 TO 9 ) ' lower bound is 5 + + * DIM now supports virtual variables. + OPTION BASE 1 + OPEN "VIRTUAL.DAT" FOR VIRTUAL AS # 3 ' virtual data file + DIM # 3, A( 1000 ) ' array is virtual + LET A( 1000 ) = 0 ' value is written to the file + LET X = A( 1000 ) ' value is read from the file + CLOSE # 3 ' array is no longer valid + + * ERROR 27, "Bad DATA" + Occurs when the READ command detects garbage in a DATA command. + + * INPUT LINE + Same as LINE INPUT. + + * MAT now supports lower and upper bounds. + OPTION BASE 1 + MAT X( 9 ) = ZER ' lower bound is 1 + MAT Y( 5 TO 9 ) = ZER ' lower bound is 5 + MAT X = ZER( 9 ) ' lower bound is 1 + MAT Y - ZER( 5 TO 9 ) ' lower bound is 5 + + * MAXLEN() + Returns the maximum string length. + + * OPTION DIGITS integer + Sets the number of significant digits for PRINT. + Setting the value to zero restores the default. + + * OPTION EDIT string$ + Sets the program name used by the EDIT command. + Setting this to "" disables EDIT command. + + * OPTION FILES string$ + Sets the program name used by the FILES command. + Setting this to "" disables FILES command. + + * OPTION PROMPT string$ + Sets the prompt. + + * OPTION PUNCT AT char$ + Sets the PRINT AT character, commonly "@". + Setting this to "" disables PRINT AT. + Setting this to a non-punctuation character is not supported. + + * OPTION PUNCT BYTE char$ + Sets the BYTE type suffix, commonly "~". + Setting this to "" disables BYTE suffix. + Setting this to a non-punctuation character is not supported. + + * OPTION PUNCT COMMENT char$ + Sets the trailing COMMENT character, commonly "'". + Setting this to "" disables trailing comments. + Setting this to a non-punctuation character is not supported. + + * OPTION PUNCT CURRENCY char$ + Sets the CURRENCY type suffix, commonly "@". + Setting this to "" disables CURRENCY suffix. + Setting this to a non-punctuation character is not supported. + + * OPTION PUNCT DOUBLE char$ + Sets the DOUBLE type suffix, commonly "#". + Setting this to "" disables DOUBLE suffix. + Setting this to a non-punctuation character is not supported. + + * OPTION PUNCT FILENUM char$ + Sets the FILE NUMBER prefix, commonly "#". + Setting this to "" disables the FILE NUMBER prefix. + Setting this to a non-punctuation character is not supported. + + * OPTION PUNCT IMAGE char$ + Sets the shortcut IMAGE character, commonly ":". + Setting this to "" disables the shortcut IMAGE character. + Setting this to a non-punctuation character is not supported. + + * OPTION PUNCT INPUT char$ + Sets the shortcut INPUT character, commonly "!". + Setting this to "" disables the shortcut INPUT character. + Setting this to a non-punctuation character is not supported. + + * OPTION PUNCT INTEGER char$ + Sets the INTEGER type suffix, commonly "%". + Setting this to "" disables INTEGER suffix. + Setting this to a non-punctuation character is not supported. + + * OPTION PUNCT LONG char$ + Sets the LONG type suffix, commonly "&". + Setting this to "" disables LONG suffix. + Setting this to a non-punctuation character is not supported. + + * OPTION PUNCT LPAREN char$ + Sets the LEFT PARENTHESIS character, commonly "(". + Setting this to a non-punctuation character is not supported. + + * OPTION PUNCT PRINT char$ + Sets the shortcut PRINT character, commonly "?". + Setting this to "" disables the shortcut PRINT character. + Setting this to a non-punctuation character is not supported. + + * OPTION PUNCT QUOTE char$ + Sets the QUOTE character, commonly """". + Setting this to a non-punctuation character is not supported. + + * OPTION PUNCT RPAREN char$ + Sets the RIGHT PARENTHESIS character, commonly ")". + Setting this to a non-punctuation character is not supported. + + * OPTION PUNCT SINGLE char$ + Sets the SINGLE type suffix, commonly "!". + Setting this to "" disables SINGLE suffix. + Setting this to a non-punctuation character is not supported. + + * OPTION PUNCT STATEMENT char$ + Sets the shortcut STATEMENT seperator character, commonly ":". + Setting this to "" disables the STATEMENT seperator. + Setting this to a non-punctuation character is not supported. + + * OPTION PUNCT STRING char$ + Sets the STRING type suffix, commonly "$". + Setting this to "" disables STRING suffix. + Setting this to a non-punctuation character is not supported. + + * OPTION RECLEN integer + Sets the default record length for RANDOM files, commonly 128. + Setting thisto zero means there is no default RANDOM record + length, so the record length must be specified in the OPEN + statement. + With OPTION RECLEN 128: + OPEN "FILE.DAT" FOR RANDOM AS #3 + is considered to be the same as + OPEN "FILE.DAT" FOR RANDOM AS #3 LEN 128 + With OPTION RECLEN 0: + OPEN "FILE.DAT" FOR RANDOM AS #3 + causes an error. + + * OPTION RENUM string$ + Sets the program name used by the RENUM command. + Setting this to "" disables RENUM command. + + * OPTION SCALE integer + Sets the number of digits to round after the decimal point for PRINT. + Setting the value to zero disables rounding. + + * OPTION USING DIGIT + * OPTION USING COMMA + * OPTION USING PERIOD + * OPTION USING PLUS + * OPTION USING MINUS + * OPTION USING EXRAD + * OPTION USING DOLLAR + * OPTION USING FILLER + * OPTION USING LITERAL + * OPTION USING FIRST + * OPTION USING ALL + * OPTION USING LENGTH + Sets the characters recognized by PRINT USING. + Setting these to a non-punctuation character is not supported. + + * OPTION VERSION now requires a string instead of a literal. + Some version names have changed. + + * OPTION VERSION "PDP-8" + Added LPT, PTP, PTR, TTY, TTY IN and TTY OUT commands. + Added GET() and PUT() functions. + + * OPTION VERSION "CALL/360" + * OPTION VERSION "SYSTEM/360" + * OPTION VERSION "SYSTEM/370" + Added alphabet extenders. $ is a string variable. + + * OPTION ZONE integer + Sets the PRINT zone width. + Setting the value to zero restores the default. + + * REPEAT - UNTIL added + REPEAT + ... + EXIT REPEAT + ... + UNTIL expression ' exits when expression != 0 + + * SPC( X ) and TAB( X ) + No longer use control codes. + + * UNTIL - UEND removed (to add REPEAT - UNTIL) + Here is a work-around for existin code using UNTIL-UEND: + UNITL expression -->> WHILE NOT expression + ... ... + EXIT UNTIL -->> EXIT WHILE + ... ... + UEND -->> WEND + + * from Howard Wulf, AF5NE + + +CHANGES FROM 3.00 to 3.10 + + * Implements most of the following BASIC dialects: + OPTION VERSION DARTMOUTH ' Dartmouth DTSS BASIC + OPTION VERSION MARK-I ' GE 265 Mainframe BASIC + OPTION VERSION MARK-II ' GE 435 Mainframe BASIC + OPTION VERSION SYSTEM-360 ' IBM System/360 BASIC + OPTION VERSION SYSTEM-370 ' IBM System/370 BASIC + OPTION VERSION CBASIC-II ' CBASIC-II for CP/M + OPTION VERSION ECMA-55 ' ANSI Minimal BASIC + OPTION VERSION HANDBOOK1 ' The BASIC Handbook, 1st Edition + OPTION VERSION HANDBOOK2 ' The BASIC Handbook, 2nd Edition + OPTION VERSION TRS-80 ' TRS-80 Model I/III/4 LBASIC + OPTION VERSION BASIC-80 ' Microsoft BASIC-80 for Xenix + OPTION VERSION ECMA-116 ' ANSI Full BASIC + + * from Howard Wulf, AF5NE + + +CHANGES FROM 2.61 to 3.00 + + * Code redesign from Howard Wulf, AF5NE + + +CHANGES FROM 2.60 to 2.61 + + * Bug fix from Matthias Rustler + + +CHANGES FROM 2.50 to 2.60 + + * New maths functions and append mode support from Edmond Orignac + + * Bug fixes + + +CHANGES FROM 2.40 to 2.50 + + * Bug fixes + + * New compilation procedure for MVS and CMS + + +CHANGES FROM 2.30 to 2.40 + + * Bug fixes from Bill Chatfield + + * Updated documentation + + * Added support for compiling on CMS (another IBM mainframe OS) + + +CHANGES FROM 2.20pl2 to 2.30 + + * Minor bug fixes, cosmetic improvements and portability improvements + + * Added support for compiling on MVS (IBM mainframe) + + +CHANGES FROM 2.20pl1 to 2.20pl2 + +bwb_cmd.c + Fixed calling stack level logic in RETURN statement to prevent erroneous + "RETURN without GOSUB" messages. + +bwb_cnd.c +bwb_stc.c + + Changed continuation condition for WHILE, ELSEIF, and LOOP UNTIL + to be != FALSE, not == TRUE. More in line with common commercial + BASIC implementations. + +bwb_mth.c + Fixed initialization in VAL function so that old results are not later + returned as values. + +bwb_var.c + Added parenthesis level checking to dim_getparams. Using multi-level + expressions as array subscripts was causing the program to bomb. + +bwx_iqc.c +bwx_tty.c +bwb_mes.h + Added second copyright notice. + +bwb_dio.c +bwb_str.c + Added support for strings longer than 255 characters. + +bwb_prn.c + Disabled tab expansion and print width checks when not printing to a file. + +bwb_inp.c + Fixed LINE INPUT file reads to accommodate strings of length MAXSTRINGSIZE. + +bwx_ncu.h +bwx_ncu.c + New files. Code for UNIX ncurses interface, compliments of L.C. Benschop, + Eindhoven, The Netherlands. + +Makefile.ncu + New files. Sample makefile for ncurses implementation. + +bwbasic.h + Revised defines for MININTSIZE and MAXINTSIZE from 16-bit to 32-bit limits. + Revised define for MAXSTRINGSIZE from 255 to 5000 characters. + Changed string length from unsigned char to unsigned int to support strings + longer than 255 characters. + Added support for new ncurses package. + Revised VERSION define to reflect above changes. + + +CHANGES FROM 2.20 to 2.20pl1 + +bwb_cnd.c + + Moved init routine for bwb_while so that it would be initialized regardless + of expression value, not just if TRUE. This was causing some segmentation + faults in WHILE-WEND loops. + +bwb_elx.c + + Plugged gaping memory leak. Temp variable space for expression evaluation + was being allocated but not freed when done (oops!). + +bwb_fnc.c + + Added check for NULL return from getenv to prevent segmentation faults. + +bwbasic.h + Revised VERSION define to reflect above changes. + + + +CHANGES FROM 2.10 to 2.20: + + * Plugged numerous memory leaks, resolved memory overruns and allocation + difficulties. + + * General cleanup and bug fixes, too many to list in detail here. + The major problem areas addressed were: + + - RUN command with file name argument + - nested and cascaded FOR-NEXT loops + - PRINT USING + - EOF, LOF functions + - string concatenation + - operator hierarchy + - multi-level expression evaluation + - hex constant interpretation + - hex and octal constants in INPUT and DATA statements + + * Added a CLOSE all files feature (when no argument supplied). + + * Added a unary minus sign operator. + + * Added a MID$ command to complement the MID$ function. + + * Added a RENUM facility in a standalone program. + + * Added checking in configure for unistd.h (important on Sun systems). diff --git a/INFO/Bwbasic-notes.txt b/INFO/Bwbasic-notes.txt new file mode 100644 index 0000000..1332bdc --- /dev/null +++ b/INFO/Bwbasic-notes.txt @@ -0,0 +1,14 @@ +04-14-2020 Ken + +Since Linux does not have a "cls" command that Windows/DOS +does have do this once + +sudo ln /usr/bin/clear /usr/bin/cls + +Then in your bwbasic 3.20b program to clear the screen use +SHELL "cls" + +Or at the start of you bwbasic 3.20b program include +OPTION TERMINAL ANSI +then CLS will work + diff --git a/bwbasic.doc b/INFO/Bwbasic.doc similarity index 100% rename from bwbasic.doc rename to INFO/Bwbasic.doc diff --git a/INFO/Bwbasic_3.20_manual.docx b/INFO/Bwbasic_3.20_manual.docx new file mode 100644 index 0000000..dc00635 Binary files /dev/null and b/INFO/Bwbasic_3.20_manual.docx differ diff --git a/Junk/COPYING b/Junk/COPYING deleted file mode 100644 index 86cf81a..0000000 --- a/Junk/COPYING +++ /dev/null @@ -1,341 +0,0 @@ - - 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. - - - Copyright (C) 19yy - - 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. - - , 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. - diff --git a/Junk/bwb_cmd.c b/Junk/bwb_cmd.c deleted file mode 100644 index be2ba2d..0000000 --- a/Junk/bwb_cmd.c +++ /dev/null @@ -1,10219 +0,0 @@ -/*************************************************************** - - bwb_cmd.c Miscellaneous Commands - 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. - -***************************************************************/ - -/*---------------------------------------------------------------*/ -/* NOTE: Modifications marked "JBV" were made by Jon B. Volkoff, */ -/* 11/1995 (eidetics@cerf.net). */ -/* */ -/* Those additionally marked with "DD" were at the suggestion of */ -/* Dale DePriest (daled@cadence.com). */ -/* */ -/* Version 3.00 by Howard Wulf, AF5NE */ -/* */ -/* Version 3.10 by Howard Wulf, AF5NE */ -/* */ -/* Version 3.20 by Howard Wulf, AF5NE */ -/* */ -/* Version 3.20A by Ken Martin Mainly corrected fprint issues */ -/* */ -/*---------------------------------------------------------------*/ - - - -#include "bwbasic.h" - -static void bwb_copy_file (char *Source, char *Target); -static LineType *bwb_delete (LineType * l); -static void bwb_display_file (char *Source); -static LineType *bwb_load (LineType * Line, char *Prompt, int IsNew); -static void bwb_new (void); -static LineType *bwb_run_filename_or_linenumber (LineType * L); -static LineType *bwb_save (LineType * Line, char *Prompt); -static LineType *bwb_system (LineType * l); -static LineType *bwb_xlist (LineType * l, FILE * file); -static LineType *bwx_run (LineType * Line, char *ProgramName); -static void CommandOptionVersion (int n, char *OutputLine); -static void CommandUniqueID (int i, char *UniqueID); -static void CommandVector (int i, char *Vector); -static VariableType *find_variable_by_type (char *name, int dimensions, - char VariableTypeCode); -static void FixUp (char *Name); -static LineType *H14_RENAME (LineType * l); -static int line_read_matrix_redim (LineType * l, VariableType * v); -static void ProcessEscapeChars (const char *Input, char *Output); -static int xl_line (FILE * file, LineType * l); - - -/* - fprintf( file, "------------------------------------------------------------\n"); - 123456789012345678901234567890123456789012345678901234567890 - fprintf( file, " SYNTAX: %s\n", IntrinsicCommandTable[n].Syntax); - sprintf( tbuf, "DESCRIPTION: %s\n", IntrinsicCommandTable[n].Description); - fprintf( file, " " ); - fprintf( file, " [%c] %s\n", X, bwb_vertable[i].Name); - 1234567890123 -*/ -#define LEFT_LENGTH 13 -#define RIGHT_LENGTH 47 -#define TOTAL_LENGTH ( LEFT_LENGTH + RIGHT_LENGTH ) - -/* --------------------------------------------------------------------------------------------- - EDIT, RENUM, RENUMBER --------------------------------------------------------------------------------------------- -*/ - -static LineType * -bwx_run (LineType * Line, char *ProgramName) -{ - size_t n; - char *tbuf; - - assert (Line != NULL); - assert( My != NULL ); - - if (is_empty_string (ProgramName)) - { - WARN_BAD_FILE_NAME; - return (Line); - } - if (is_empty_string (My->ProgramFilename)) - { - WARN_BAD_FILE_NAME; - return (Line); - } - n = bwb_strlen (ProgramName) + 1 + bwb_strlen (My->ProgramFilename); - if ((tbuf = (char *) calloc (n + 1 /* NulChar */ , sizeof (char))) == NULL) - { - WARN_OUT_OF_MEMORY; - return (Line); - } - bwb_strcpy (tbuf, ProgramName); - bwb_strcat (tbuf, " "); - bwb_strcat (tbuf, My->ProgramFilename); - system (tbuf); - free (tbuf); - tbuf = NULL; - - /* open edited file for read */ - bwb_NEW (Line); /* Relocated by JBV (bug found by DD) */ - if (bwb_fload (NULL) == FALSE) - { - WARN_BAD_FILE_NAME; - return (Line); - } - return (Line); -} - - - -/*************************************************************** - - 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 - -***************************************************************/ - -LineType * -bwb_EDIT (LineType * Line) -{ - /* - SYNTAX: EDIT - */ - - assert (Line != NULL); - assert( My != NULL ); - - return bwx_run (Line, My->OptionEditString); -} - -/*************************************************************** - - FUNCTION: bwb_renum() - - DESCRIPTION: This function implements the BASIC RENUM - command by shelling out to a default - renumbering program called "renum". - Added by JBV 10/95 - - SYNTAX: RENUM - -***************************************************************/ - -LineType * -bwb_RENUM (LineType * Line) -{ - /* - SYNTAX: RENUM - */ - - assert (Line != NULL); - assert( My != NULL ); - - return bwx_run (Line, My->OptionRenumString); -} - -LineType * -bwb_RENUMBER (LineType * Line) -{ - /* - SYNTAX: RENUMBER - */ - - assert (Line != NULL); - assert( My != NULL ); - - return bwx_run (Line, My->OptionRenumString); -} - -/* --------------------------------------------------------------------------------------------- - REM --------------------------------------------------------------------------------------------- -*/ - -LineType * -bwb_REM (LineType * L) -{ - /* - SYNTAX: REM comment - */ - /* - This line holds BASIC comments. - */ - - assert (L != NULL); - - line_skip_eol (L); - return L; -} - -/* --------------------------------------------------------------------------------------------- - IMAGE --------------------------------------------------------------------------------------------- -*/ - -LineType * -bwb_IMAGE (LineType * L) -{ - /* - SYNTAX: IMAGE print-using-format - */ - - assert (L != NULL); - - line_skip_eol (L); - return L; -} - -/* --------------------------------------------------------------------------------------------- - LET --------------------------------------------------------------------------------------------- -*/ - - -LineType * -bwb_LET (LineType * L) -{ - /* - SYNTAX: LET variable [,...] = expression - */ - VariableType *v; - VariantType x; - VariantType *X; - - assert (L != NULL); - X = &x; - CLEAR_VARIANT (X); - /* read the list of variables */ - do - { - if ((v = line_read_scalar (L)) == NULL) - { - WARN_VARIABLE_NOT_DECLARED; - goto EXIT; - } - } - while (line_skip_seperator (L)); - - /* skip the equal sign */ - if (line_skip_EqualChar (L)) - { - /* OK */ - } - else if (line_skip_word (L, "EQ")) - { - /* OK */ - } - else if (line_skip_word (L, ".EQ.")) - { - /* OK */ - } - else - { - WARN_SYNTAX_ERROR; - goto EXIT; - } - - /* evaluate the expression */ - if (line_read_expression (L, X)) /* bwb_LET */ - { - /* save the value */ - if (line_is_eol (L) == FALSE) - { - WARN_SYNTAX_ERROR; - goto EXIT; - } - L->position = L->Startpos; - - /* for each variable, assign the value */ - do - { - /* read a variable */ - if ((v = line_read_scalar (L)) == NULL) - { - WARN_VARIABLE_NOT_DECLARED; - goto EXIT; - } - assert (v != NULL); - assert (X != NULL); - if (var_set (v, X) == FALSE) - { - WARN_TYPE_MISMATCH; - goto EXIT; - } - } - while (line_skip_seperator (L)); - - /* we are now at the equals sign */ - line_skip_eol (L); - } - else - { - WARN_SYNTAX_ERROR; - } -EXIT: - RELEASE_VARIANT (X); - return L; -} - - -LineType * -bwb_CONST (LineType * L) -{ - /* - SYNTAX: CONST variable [,...] = expression - */ - VariableType *v; - VariantType x; - VariantType *X; - - assert (L != NULL); - - X = &x; - CLEAR_VARIANT (X); - /* read the list of variables */ - do - { - if ((v = line_read_scalar (L)) == NULL) - { - WARN_VARIABLE_NOT_DECLARED; - goto EXIT; - } - } - while (line_skip_seperator (L)); - /* we are now at the equals sign */ - - /* skip the equal sign */ - if (line_skip_EqualChar (L)) - { - /* OK */ - } - else if (line_skip_word (L, "EQ")) - { - /* OK */ - } - else if (line_skip_word (L, ".EQ.")) - { - /* OK */ - } - else - { - WARN_SYNTAX_ERROR; - goto EXIT; - } - - /* evaluate the expression */ - if (line_read_expression (L, X)) /* bwb_LET */ - { - /* save the value */ - if (line_is_eol (L) == FALSE) - { - WARN_SYNTAX_ERROR; - goto EXIT; - } - - /* for each variable, assign the value */ - L->position = L->Startpos; - do - { - /* read a variable */ - if ((v = line_read_scalar (L)) == NULL) - { - WARN_VARIABLE_NOT_DECLARED; - goto EXIT; - } - assert (v != NULL); - assert (X != NULL); - if (var_set (v, X) == FALSE) - { - WARN_TYPE_MISMATCH; - goto EXIT; - } - } - while (line_skip_seperator (L)); - /* we are now at the equals sign */ - - /* for each variable, mark as constant */ - L->position = L->Startpos; - do - { - /* read a variable */ - if ((v = line_read_scalar (L)) == NULL) - { - WARN_VARIABLE_NOT_DECLARED; - goto EXIT; - } - assert (v != NULL); - v->VariableFlags |= VARIABLE_CONSTANT; - } - while (line_skip_seperator (L)); - /* we are now at the equals sign */ - - line_skip_eol (L); - } - else - { - WARN_SYNTAX_ERROR; - } -EXIT: - RELEASE_VARIANT (X); - return L; -} - -LineType * -bwb_DEC (LineType * L) -{ - /* - SYNTAX: DEC variable [,...] - */ - VariableType *v; - VariantType x; - VariantType *X; - - assert (L != NULL); - - X = &x; - CLEAR_VARIANT (X); - /* read the list of variables */ - do - { - if ((v = line_read_scalar (L)) == NULL) - { - WARN_VARIABLE_NOT_DECLARED; - goto EXIT; - } - if (v->VariableTypeCode == StringTypeCode) - { - WARN_TYPE_MISMATCH; - goto EXIT; - } - } - while (line_skip_seperator (L)); - /* we are now at the end of the line */ - - if (line_is_eol (L) == FALSE) - { - WARN_SYNTAX_ERROR; - goto EXIT; - } - L->position = L->Startpos; - - /* for each variable, assign the value */ - do - { - /* read a variable */ - if ((v = line_read_scalar (L)) == NULL) - { - WARN_VARIABLE_NOT_DECLARED; - goto EXIT; - } - assert (v != NULL); - assert (X != NULL); - if (var_get (v, X) == FALSE) - { - WARN_VARIABLE_NOT_DECLARED; - goto EXIT; - } - X->Number--; - if (var_set (v, X) == FALSE) - { - WARN_VARIABLE_NOT_DECLARED; - goto EXIT; - } - } - while (line_skip_seperator (L)); - /* we are now at the end of the line */ -EXIT: - RELEASE_VARIANT (X); - return L; -} - -LineType * -bwb_INC (LineType * L) -{ - /* - SYNTAX: INC variable [,...] - */ - VariableType *v; - VariantType x; - VariantType *X; - - assert (L != NULL); - - X = &x; - CLEAR_VARIANT (X); - /* read the list of variables */ - do - { - if ((v = line_read_scalar (L)) == NULL) - { - WARN_VARIABLE_NOT_DECLARED; - goto EXIT; - } - if (v->VariableTypeCode == StringTypeCode) - { - WARN_TYPE_MISMATCH; - goto EXIT; - } - } - while (line_skip_seperator (L)); - /* we are now at the end of the line */ - - if (line_is_eol (L) == FALSE) - { - WARN_SYNTAX_ERROR; - goto EXIT; - } - L->position = L->Startpos; - - /* for each variable, assign the value */ - do - { - /* read a variable */ - if ((v = line_read_scalar (L)) == NULL) - { - WARN_VARIABLE_NOT_DECLARED; - goto EXIT; - } - assert (v != NULL); - assert (X != NULL); - if (var_get (v, X) == FALSE) - { - WARN_VARIABLE_NOT_DECLARED; - goto EXIT; - } - X->Number++; - if (var_set (v, X) == FALSE) - { - WARN_VARIABLE_NOT_DECLARED; - goto EXIT; - } - } - while (line_skip_seperator (L)); - /* we are now at the end of the line */ -EXIT: - RELEASE_VARIANT (X); - return L; -} - - - -/* --------------------------------------------------------------------------------------------- - GO --------------------------------------------------------------------------------------------- -*/ - -LineType * -bwb_GO (LineType * L) -{ - - assert (L != NULL); - WARN_SYNTAX_ERROR; - return L; -} - -LineType * -bwb_THEN (LineType * L) -{ - - assert (L != NULL); - WARN_SYNTAX_ERROR; - return L; -} - -LineType * -bwb_TO (LineType * L) -{ - - assert (L != NULL); - WARN_SYNTAX_ERROR; - return L; -} - -LineType * -bwb_STEP (LineType * L) -{ - - assert (L != NULL); - WARN_SYNTAX_ERROR; - return L; -} - -LineType * -bwb_OF (LineType * L) -{ - - assert (L != NULL); - WARN_SYNTAX_ERROR; - return L; -} - -LineType * -bwb_AS (LineType * L) -{ - - assert (L != NULL); - WARN_SYNTAX_ERROR; - return L; -} - - -/* --------------------------------------------------------------------------------------------- - AUTO --------------------------------------------------------------------------------------------- -*/ - - -LineType * -bwb_BUILD (LineType * L) -{ - /* - SYNTAX: BUILD - SYNTAX: BUILD start - SYNTAX: BUILD start, increment - */ - - assert (L != NULL); - return bwb_AUTO (L); -} - -LineType * -bwb_AUTO (LineType * L) -{ - /* - SYNTAX: AUTO - SYNTAX: AUTO start - SYNTAX: AUTO start , increment - */ - - assert (L != NULL); - assert( My != NULL ); - - My->AutomaticLineNumber = 0; - My->AutomaticLineIncrement = 0; - - if (line_is_eol (L)) - { - /* AUTO */ - My->AutomaticLineNumber = 10; - My->AutomaticLineIncrement = 10; - return L; - } - if (line_read_line_number (L, &My->AutomaticLineNumber)) - { - /* AUTO ### ... */ - if (My->AutomaticLineNumber < MINLIN || My->AutomaticLineNumber > MAXLIN) - { - WARN_UNDEFINED_LINE; - return L; - } - if (line_is_eol (L)) - { - /* AUTO start */ - My->AutomaticLineIncrement = 10; - return L; - } - else if (line_skip_seperator (L)) - { - /* AUTO ### , ... */ - if (line_read_line_number (L, &My->AutomaticLineIncrement)) - { - /* AUTO start , increment */ - if (My->AutomaticLineIncrement < MINLIN - || My->AutomaticLineIncrement > MAXLIN) - { - WARN_UNDEFINED_LINE; - return L; - } - return L; - } - } - } - My->AutomaticLineNumber = 0; - My->AutomaticLineIncrement = 0; - WARN_SYNTAX_ERROR; - return L; -} - -/* --------------------------------------------------------------------------------------------- - BREAK --------------------------------------------------------------------------------------------- -*/ - - -LineType * -bwb_BREAK (LineType * l) -{ - /* - SYNTAX: BREAK - SYNTAX: BREAK line [,...] - SYNTAX: BREAK line - line - */ - - assert (l != NULL); - assert( My != NULL ); - assert( My->StartMarker != NULL ); - assert( My->EndMarker != NULL ); - - if (line_is_eol (l)) - { - /* BREAK */ - /* remove all line breaks */ - LineType *x; - for (x = My->StartMarker->next; x != My->EndMarker; x = x->next) - { - x->LineFlags &= ~LINE_BREAK; - } - return (l); - } - else - { - do - { - int head; - int tail; - - if (line_read_line_sequence (l, &head, &tail)) - { - /* BREAK 's' - 'e' */ - LineType *x; - if (head < MINLIN || head > MAXLIN) - { - WARN_UNDEFINED_LINE; - return (l); - } - if (tail < MINLIN || tail > MAXLIN) - { - WARN_UNDEFINED_LINE; - return (l); - } - if (head > tail) - { - WARN_SYNTAX_ERROR; - return (l); - } - /* valid range */ - /* now go through and list appropriate lines */ - for (x = My->StartMarker->next; x != My->EndMarker; x = x->next) - { - if (head <= x->number && x->number <= tail) - { - if (x->LineFlags & LINE_NUMBERED) - { - x->LineFlags |= LINE_BREAK; - } - } - } - } - else - { - WARN_SYNTAX_ERROR; - return (l); - } - } - while (line_skip_seperator (l)); - } - return (l); -} - - -/* --------------------------------------------------------------------------------------------- - DSP --------------------------------------------------------------------------------------------- -*/ - -LineType * -bwb_DSP (LineType * l) -{ - /* - SYNTAX: DSP - SYNTAX: DSP variablename [,...] - */ - VariableType *v; - - assert (l != NULL); - assert( My != NULL ); - - - if (line_is_eol (l)) - { - /* DSP */ - /* remove all variable displays */ - for (v = My->VariableHead; v != NULL; v = v->next) - { - v->VariableFlags &= ~VARIABLE_DISPLAY; /* bwb_DSP() */ - } - return (l); - } - /* DSP variablename [,...] */ - do - { - char varname[NameLengthMax + 1]; - - if (line_read_varname (l, varname)) - { - /* mark the variable */ - for (v = My->VariableHead; v != NULL; v = v->next) - { - if (bwb_stricmp (v->name, varname) == 0) - { - v->VariableFlags |= VARIABLE_DISPLAY; /* bwb_DSP() */ - } - } - } - } - while (line_skip_seperator (l)); - return (l); -} - - -/* --------------------------------------------------------------------------------------------- - GOTO --------------------------------------------------------------------------------------------- -*/ - -LineType * -bwb_GO_TO (LineType * l) -{ - - assert (l != NULL); - return bwb_GOTO (l); -} - -LineType * -bwb_GOTO (LineType * l) -{ - /* - SYNTAX: GOTO line ' standard GOTO - SYNTAX: GOTO expression ' calculated GOTO - SYNTAX: GOTO expression OF line,... ' indexed GOTO, same as ON expression GOTO line,... - SYNTAX: GOTO line [,...] ON expression ' indexed GOTO, same as ON expression GOTO line,... - */ - int Value; - int LineNumber; - LineType *x; - - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - Value = 0; - LineNumber = 0; - if (l->LineFlags & (LINE_USER)) - { - WARN_ILLEGAL_DIRECT; - return (l); - } - - if (line_is_eol (l)) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (line_read_integer_expression (l, &Value) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - - if (line_is_eol (l)) - { - /* GOTO linenumber */ - /* 'Value' is the line number */ - LineNumber = Value; - } - else if (line_skip_word (l, "OF")) - { - /* GOTO expression OF line, ... */ - /* 'Value' is an index into a list of line numbers */ - if (line_read_index_item (l, Value, &LineNumber)) - { - /* found 'LineNumber' */ - } - else if (My->CurrentVersion->OptionFlags & (OPTION_BUGS_ON) ) /* GOTO X OF ... */ - { - /* silently fall-thru to the following line */ - line_skip_eol (l); - return (l); - } - else - { - /* ERROR */ - WARN_UNDEFINED_LINE; - return (l); - } - } - else if (My->CurrentVersion->OptionVersionValue & (S70 | I70 | I73)) - { - /* GOTO line [,...] ON expression */ - while (line_skip_seperator (l)) - { - if (line_read_integer_expression (l, &Value) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - } - if (line_skip_word (l, "ON") == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (line_read_integer_expression (l, &Value) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - /* 'Value' is an index into a list of line numbers */ - l->position = l->Startpos; - if (line_read_index_item (l, Value, &LineNumber)) - { - /* found 'LineNumber' */ - } - else - { - /* silently fall-thru to the following line */ - line_skip_eol (l); - return (l); - } - line_skip_eol (l); - } - else - { - WARN_SYNTAX_ERROR; - return (l); - } - - if (LineNumber < MINLIN || LineNumber > MAXLIN) - { - WARN_UNDEFINED_LINE; - return (l); - } - /* valid range */ - x = NULL; -#if THE_PRICE_IS_RIGHT - if (l->OtherLine != NULL) - { - /* look in the cache */ - if (l->OtherLine->number == LineNumber) - { - x = l->OtherLine; /* found in cache */ - } - } -#endif /* THE_PRICE_IS_RIGHT */ - if (x == NULL) - { - x = find_line_number (LineNumber); /* not found in the cache */ - } - if (x != NULL) - { - /* FOUND */ - line_skip_eol (l); - x->position = 0; -#if THE_PRICE_IS_RIGHT - l->OtherLine = x; /* save in cache */ -#endif /* THE_PRICE_IS_RIGHT */ - return x; - } - /* NOT FOUND */ - WARN_UNDEFINED_LINE; - return (l); -} - - -/* --------------------------------------------------------------------------------------------- - GOSUB --------------------------------------------------------------------------------------------- -*/ - -LineType * -bwb_GO_SUB (LineType * l) -{ - - assert (l != NULL); - return bwb_GOSUB (l); -} - -LineType * -bwb_GOSUB (LineType * l) -{ - /* - SYNTAX: GOSUB line ' standard GOSUB - SYNTAX: GOSUB expression ' calculated GOSUB - SYNTAX: GOSUB expression OF line,... ' indexed GOSUB, same as ON expression GOSUB line,... - SYNTAX: GOSUB line [,...] ON expression ' indexed GOSUB, same as ON expression GOSUB line,... - */ - int Value; - int LineNumber; - LineType *x; - - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - Value = 0; - LineNumber = 0; - x = NULL; - if (l->LineFlags & (LINE_USER)) - { - WARN_ILLEGAL_DIRECT; - return (l); - } - - if (line_is_eol (l)) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (line_read_integer_expression (l, &Value) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - - if (line_is_eol (l)) - { - /* GOSUB linenumber */ - /* 'Value' is the line number */ - LineNumber = Value; - } - else if (line_skip_word (l, "OF")) - { - /* GOSUB linenumber [,...] OF expression */ - /* 'Value' is an index into a list of line numbers */ - if (line_read_index_item (l, Value, &LineNumber)) - { - /* found 'LineNumber' */ - } - else if (My->CurrentVersion->OptionFlags & (OPTION_BUGS_ON) ) /* GOSUB X OF ... */ - { - /* silently fall-thru to the following line */ - line_skip_eol (l); - return (l); - } - else - { - /* ERROR */ - WARN_UNDEFINED_LINE; - return (l); - } - } - else if (My->CurrentVersion->OptionVersionValue & (S70 | I70 | I73)) - { - /* GOSUB line [,...] ON expression */ - while (line_skip_seperator (l)) - { - if (line_read_integer_expression (l, &Value) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - } - if (line_skip_word (l, "ON") == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (line_read_integer_expression (l, &Value) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - /* 'Value' is an index into a list of line numbers */ - l->position = l->Startpos; - if (line_read_index_item (l, Value, &LineNumber)) - { - /* found 'LineNumber' */ - } - else - { - /* silently fall-thru to the following line */ - line_skip_eol (l); - return (l); - } - line_skip_eol (l); - } - else - { - WARN_SYNTAX_ERROR; - return (l); - } - - if (LineNumber < MINLIN || LineNumber > MAXLIN) - { - WARN_UNDEFINED_LINE; - return (l); - } - /* valid range */ - x = NULL; -#if THE_PRICE_IS_RIGHT - if (l->OtherLine != NULL) - { - /* look in the cache */ - if (l->OtherLine->number == LineNumber) - { - x = l->OtherLine; /* found in cache */ - } - } -#endif /* THE_PRICE_IS_RIGHT */ - if (x == NULL) - { - x = find_line_number (LineNumber); /* not found in the cache */ - } - if (x != NULL) - { - /* FOUND */ - line_skip_eol (l); - /* save current stack level */ - My->StackHead->line = l; - /* increment exec stack */ - if (bwb_incexec ()) - { - /* set the new position to x and return x */ - x->position = 0; - My->StackHead->line = x; - My->StackHead->ExecCode = EXEC_GOSUB; -#if THE_PRICE_IS_RIGHT - l->OtherLine = x; /* save in cache */ -#endif /* THE_PRICE_IS_RIGHT */ - return x; - } - else - { - /* ERROR */ - WARN_OUT_OF_MEMORY; - return My->EndMarker; - } - } - /* NOT FOUND */ - WARN_UNDEFINED_LINE; - return (l); -} - - - -/* --------------------------------------------------------------------------------------------- - RETURN --------------------------------------------------------------------------------------------- -*/ - -LineType * -bwb_RETURN (LineType * l) -{ - /* - SYNTAX: RETURN - */ - - assert (l != NULL); - assert (My != NULL); - assert (My->CurrentVersion != NULL); - assert (My->StackHead != NULL); - - if (My->CurrentVersion->OptionVersionValue & (S70 | I70 | I73)) - { - /* RETURN [comment] */ - line_skip_eol (l); - } - - if (My->CurrentVersion->OptionVersionValue & (C77)) - { - /* CBASIC-II: RETURN exits the first FUNCTION or GOSUB */ - - while (My->StackHead->ExecCode != EXEC_GOSUB - && My->StackHead->ExecCode != EXEC_FUNCTION) - { - bwb_decexec (); - if (My->StackHead == NULL) - { - WARN_RETURN_WITHOUT_GOSUB; - return (l); - } - if (My->StackHead->ExecCode == EXEC_NORM) /* End of the line? */ - { - WARN_RETURN_WITHOUT_GOSUB; - return (l); - } - } - } - else - { - /* RETURN exits the first GOSUB */ - - while (My->StackHead->ExecCode != EXEC_GOSUB) - { - bwb_decexec (); - if (My->StackHead == NULL) - { - WARN_RETURN_WITHOUT_GOSUB; - return (l); - } - if (My->StackHead->ExecCode == EXEC_NORM) /* End of the line? */ - { - WARN_RETURN_WITHOUT_GOSUB; - return (l); - } - } - } - - - /* decrement the EXEC stack counter */ - - bwb_decexec (); - assert (My->StackHead != NULL); - return My->StackHead->line; -} - -/* --------------------------------------------------------------------------------------------- - POP --------------------------------------------------------------------------------------------- -*/ - - -LineType * -bwb_POP (LineType * l) -{ - /* - SYNTAX: POP - */ - StackType *StackItem; - - assert (l != NULL); - assert (My != NULL); - assert (My->CurrentVersion != NULL); - assert (My->StackHead != NULL); - - StackItem = My->StackHead; - while (StackItem->ExecCode != EXEC_GOSUB) - { - StackItem = StackItem->next; - if (StackItem == NULL) - { - WARN_RETURN_WITHOUT_GOSUB; - return (l); - } - if (StackItem->ExecCode == EXEC_NORM) - { - /* End of the line */ - WARN_RETURN_WITHOUT_GOSUB; - return (l); - } - } - /* hide the GOSUB */ - StackItem->ExecCode = EXEC_POPPED; - return (l); -} - -/* --------------------------------------------------------------------------------------------- - ON --------------------------------------------------------------------------------------------- -*/ - -LineType * -bwb_ON (LineType * l) -{ - /* - SYNTAX: ON expression GOTO line,... ' expression evaluates to an index - SYNTAX: ON expression GOSUB line,... ' expression evaluates to an index - */ - int Value; - int command; - int LineNumber; - LineType *x; - - assert (l != NULL); - assert (My != NULL); - assert (My->CurrentVersion != NULL); - - Value = 0; - command = 0; - LineNumber = 0; - x = NULL; - if (l->LineFlags & (LINE_USER)) - { - WARN_ILLEGAL_DIRECT; - return (l); - } - - if (line_is_eol (l)) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (line_read_integer_expression (l, &Value) == FALSE) - { - WARN_UNDEFINED_LINE; - return (l); - } - if (line_skip_word (l, "GO")) - { - if (line_skip_word (l, "TO")) - { - command = C_GOTO; - } - else if (line_skip_word (l, "SUB")) - { - command = C_GOSUB; - } - else - { - WARN_SYNTAX_ERROR; - return (l); - } - } - else if (line_skip_word (l, "GOTO")) - { - command = C_GOTO; - } - else if (line_skip_word (l, "GOSUB")) - { - command = C_GOSUB; - } - else - { - WARN_SYNTAX_ERROR; - return (l); - } - - /* 'Value' is an index into a list of line numbers */ - if (line_read_index_item (l, Value, &LineNumber)) - { - /* found 'LineNumber' */ - } - else if (My->CurrentVersion->OptionFlags & (OPTION_BUGS_ON) ) /* ON X GOTO|GOSUB ... */ - { - /* silently fall-thru to the following line */ - line_skip_eol (l); - return (l); - } - else - { - /* ERROR */ - WARN_UNDEFINED_LINE; - return (l); - } - - if (LineNumber < MINLIN || LineNumber > MAXLIN) - { - WARN_UNDEFINED_LINE; - return (l); - } - /* valid range */ - x = NULL; -#if THE_PRICE_IS_RIGHT - if (l->OtherLine != NULL) - { - /* look in the cache */ - if (l->OtherLine->number == LineNumber) - { - x = l->OtherLine; /* found in cache */ - } - } -#endif /* THE_PRICE_IS_RIGHT */ - if (x == NULL) - { - x = find_line_number (LineNumber); /* not found in the cache */ - } - if (x != NULL) - { - /* FOUND */ - if (command == C_GOTO) - { - /* ON ... GOTO ... */ - line_skip_eol (l); - x->position = 0; -#if THE_PRICE_IS_RIGHT - l->OtherLine = x; /* save in cache */ -#endif /* THE_PRICE_IS_RIGHT */ - return x; - } - else if (command == C_GOSUB) - { - /* ON ... GOSUB ... */ - line_skip_eol (l); - /* save current stack level */ - My->StackHead->line = l; - /* increment exec stack */ - if (bwb_incexec ()) - { - /* set the new position to x and return x */ - x->position = 0; - My->StackHead->line = x; - My->StackHead->ExecCode = EXEC_GOSUB; -#if THE_PRICE_IS_RIGHT - l->OtherLine = x; /* save in cache */ -#endif /* THE_PRICE_IS_RIGHT */ - return x; - } - else - { - /* ERROR */ - WARN_OUT_OF_MEMORY; - return My->EndMarker; - } - } - else - { - /* ERROR */ - WARN_SYNTAX_ERROR; - return (l); - } - } - /* NOT FOUND */ - WARN_UNDEFINED_LINE; - return (l); -} - -/* --------------------------------------------------------------------------------------------- - PAUSE --------------------------------------------------------------------------------------------- -*/ - -LineType * -bwb_PAUSE (LineType * l) -{ - /* - SYNTAX: PAUSE - */ - char *pstring; - char *tbuf; - int tlen; - - assert (l != NULL); - assert (My != NULL); - assert (My->CurrentVersion != NULL); - assert (My->ConsoleOutput != NULL); - assert (My->ConsoleInput != NULL); - - pstring = My->ConsoleOutput; - tbuf = My->ConsoleInput; - tlen = MAX_LINE_LENGTH; - if (My->CurrentVersion->OptionVersionValue & (S70 | I70 | I73)) - { - /* PAUSE [comment] */ - line_skip_eol (l); - } - sprintf (pstring, "PAUSE AT %d\n", l->number); - bwx_input (pstring, FALSE, tbuf, tlen); - return (l); -} - - -/* --------------------------------------------------------------------------------------------- - STOP --------------------------------------------------------------------------------------------- -*/ - -LineType * -bwb_STOP (LineType * l) -{ - /* - SYNTAX: STOP - */ - - assert (l != NULL); - assert (My != NULL); - assert (My->CurrentVersion != NULL); - - if (My->CurrentVersion->OptionVersionValue & (S70 | I70 | I73)) - { - /* STOP [comment] */ - line_skip_eol (l); - } - My->ContinueLine = l->next; - bwx_STOP (TRUE); - return bwb_END (l); -} - - -/* --------------------------------------------------------------------------------------------- - END --------------------------------------------------------------------------------------------- -*/ - -LineType * -bwb_END (LineType * l) -{ - /* - SYNTAX: END - */ - - assert (l != NULL); - assert (My != NULL); - assert (My->CurrentVersion != NULL); - - if (My->CurrentVersion->OptionVersionValue & (S70 | I70 | I73)) - { - /* END [comment] */ - line_skip_eol (l); - } - My->ContinueLine = l->next; - bwx_STOP (FALSE); - return My->EndMarker; -} - -/* --------------------------------------------------------------------------------------------- - RUN --------------------------------------------------------------------------------------------- -*/ - -static LineType * -bwb_run_filename_or_linenumber (LineType * L) -{ - LineType *current = NULL; - VariantType x; - VariantType *X; - - assert (L != NULL); - assert (My != NULL); - assert (My->StartMarker != NULL); - - X = &x; - CLEAR_VARIANT (X); - if (line_read_expression (L, X) == FALSE) /* bwb_run_filename_or_linenumber */ - { - WARN_SYNTAX_ERROR; - return L; - } - if (X->VariantTypeCode == StringTypeCode) - { - /* RUN "filename" */ - /* RUN A$ */ - if (is_empty_string (X->Buffer)) - { - WARN_BAD_FILE_NAME; - return L; - } - /* open the file and execute it */ - bwb_new (); /* clear memory */ - if (My->ProgramFilename != NULL) - { - free (My->ProgramFilename); - My->ProgramFilename = NULL; - } - My->ProgramFilename = bwb_strdup (X->Buffer); - if (bwb_fload (NULL) == FALSE) - { - WARN_BAD_FILE_NAME; - return L; - } - /* - ** - ** FORCE SCAN - ** - */ - if (bwb_scan () == FALSE) - { - WARN_CANT_CONTINUE; - return L; - } - current = My->StartMarker->next; - } - else - { - /* RUN 100 */ - /* RUN N */ - /* execute the line */ - int LineNumber; - - - LineNumber = (int) bwb_rint (X->Number); - /* - ** - ** FORCE SCAN - ** - */ - if (bwb_scan () == FALSE) - { - WARN_CANT_CONTINUE; - goto EXIT; - } - current = find_line_number (LineNumber); /* RUN 100 */ - if (current == NULL) - { - WARN_CANT_CONTINUE; - return L; - } - } -EXIT: - RELEASE_VARIANT (X); - return current; -} - -LineType * -bwb_RUNNH (LineType * L) -{ - - assert (L != NULL); - return bwb_RUN (L); -} - -LineType * -bwb_RUN (LineType * L) -{ - /* - SYNTAX: RUN - SYNTAX: RUN filename$ - SYNTAX: RUN linenumber - */ - LineType *current; - - assert (L != NULL); - assert (My != NULL); - assert (My->EndMarker != NULL); - assert (My->DefaultVariableType != NULL); - - /* clear the STACK */ - bwb_clrexec (); - if (bwb_incexec ()) - { - /* OK */ - } - else - { - /* ERROR */ - WARN_OUT_OF_MEMORY; - return My->EndMarker; - } - - if (line_is_eol (L)) - { - /* RUN */ - - var_CLEAR (); - - /* if( TRUE ) */ - { - int n; - for (n = 0; n < 26; n++) - { - My->DefaultVariableType[n] = DoubleTypeCode; - } - } - /* - ** - ** FORCE SCAN - ** - */ - if (bwb_scan () == FALSE) - { - WARN_CANT_CONTINUE; - return My->EndMarker; - } - current = My->StartMarker->next; - } - else - { - /* RUN 100 : RUN filename$ */ - current = bwb_run_filename_or_linenumber (L); - if (current == NULL) - { - WARN_UNDEFINED_LINE; - return My->EndMarker; - } - } - current->position = 0; - - assert (My->StackHead != NULL); - My->StackHead->line = current; - My->StackHead->ExecCode = EXEC_NORM; - - /* RUN */ - WARN_CLEAR; /* bwb_RUN */ - My->ContinueLine = NULL; - SetOnError (0); - - /* if( TRUE ) */ - { - time_t t; - struct tm *lt; - - time (&t); - lt = localtime (&t); - My->StartTimeInteger = lt->tm_hour; - My->StartTimeInteger *= 60; - My->StartTimeInteger += lt->tm_min; - My->StartTimeInteger *= 60; - My->StartTimeInteger += lt->tm_sec; - /* number of seconds since midnight */ - } - - return current; -} - -/* --------------------------------------------------------------------------------------------- - CONT --------------------------------------------------------------------------------------------- -*/ -LineType * -bwb_CONTINUE (LineType * l) -{ - /* - SYNTAX: CONTINUE - */ - - assert (l != NULL); - return bwb_CONT (l); -} - -LineType * -bwb_CONT (LineType * l) -{ - /* - SYNTAX: CONT - */ - LineType *current; - - assert (l != NULL); - assert (My != NULL); - assert (My->EndMarker != NULL); - assert (My->StartMarker != NULL); - - current = NULL; - /* see if there is an element */ - if (line_is_eol (l)) - { - /* CONT */ - current = My->ContinueLine; - } - else - { - /* CONT 100 */ - int LineNumber; - - LineNumber = 0; - if (line_read_line_number (l, &LineNumber)) - { - current = find_line_number (LineNumber); /* CONT 100 */ - } - } - - - if (current == NULL || current == My->EndMarker) - { - /* same as RUN */ - current = My->StartMarker->next; - } - /* - ** - ** FORCE SCAN - ** - */ - if (bwb_scan () == FALSE) - { - WARN_CANT_CONTINUE; - return (l); - } - current->position = 0; - bwb_clrexec (); - if (bwb_incexec ()) - { - /* OK */ - My->StackHead->line = current; - My->StackHead->ExecCode = EXEC_NORM; - } - else - { - /* ERROR */ - WARN_OUT_OF_MEMORY; - return My->EndMarker; - } - - - /* CONT */ - My->ContinueLine = NULL; - return current; -} - - -/* --------------------------------------------------------------------------------------------- - NEW --------------------------------------------------------------------------------------------- -*/ - -void -bwb_xnew (LineType * l) -{ - LineType *current; - LineType *previous; - int wait; - - assert (l != NULL); - assert (My != NULL); - assert (My->EndMarker != NULL); - - previous = NULL; /* JBV */ - wait = TRUE; - for (current = l->next; current != My->EndMarker; current = current->next) - { - assert (current != NULL); - if (wait == FALSE) - { - free (previous); - previous = NULL; - } - wait = FALSE; - previous = current; - } - l->next = My->EndMarker; -} - -static void -bwb_new () -{ - assert (My != NULL); - assert (My->StartMarker != NULL); - assert (My->DefaultVariableType != NULL); - - - /* clear program in memory */ - bwb_xnew (My->StartMarker); - - /* clear all variables */ - var_CLEAR (); - /* if( TRUE ) */ - { - int n; - for (n = 0; n < 26; n++) - { - My->DefaultVariableType[n] = DoubleTypeCode; - } - } - - /* NEW */ - WARN_CLEAR; /* bwb_new */ - My->ContinueLine = NULL; - SetOnError (0); -} - -LineType * -bwb_NEW (LineType * l) -{ - /* - SYNTAX: NEW - */ - - assert (l != NULL); - assert (My != NULL); - assert (My->CurrentVersion != NULL); - - bwb_new (); - if (My->CurrentVersion->OptionVersionValue & (D64 | G65 | G67 | G74)) - { - if (line_is_eol (l)) - { - /* NEW */ - char *tbuf; - int tlen; - - tbuf = My->ConsoleInput; - tlen = MAX_LINE_LENGTH; - /* prompt for the program name */ - bwx_input ("NEW PROBLEM NAME:", FALSE, tbuf, tlen); - if (is_empty_string (tbuf)) - { - WARN_BAD_FILE_NAME; - return l; - } - if (My->ProgramFilename != NULL) - { - free (My->ProgramFilename); - My->ProgramFilename = NULL; - } - My->ProgramFilename = bwb_strdup (tbuf); - } - else - { - /* NEW filename$ */ - /* the parameter is the program name */ - - char *Value; - - Value = NULL; - if (line_read_string_expression (l, &Value) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (is_empty_string (Value)) - { - WARN_BAD_FILE_NAME; - return l; - } - if (My->ProgramFilename != NULL) - { - free (My->ProgramFilename); - My->ProgramFilename = NULL; - } - My->ProgramFilename = Value; - } - } - else - { - /* ignore any parameters */ - line_skip_eol (l); - } - return (l); -} - -/* --------------------------------------------------------------------------------------------- - SCRATCH --------------------------------------------------------------------------------------------- -*/ - -LineType * -bwb_SCRATCH (LineType * l) -{ - /* - SYNTAX: SCRATCH -- same as NEW - SYNTAX: SCRATCH # filenumber -- close file and re-open for output - */ - - assert (l != NULL); - - if (line_is_eol (l)) - { - /* SCRATCH */ - bwb_new (); - return (l); - } - if (line_skip_FilenumChar (l)) - { - /* SCRATCH # X */ - int FileNumber; - - if (line_read_integer_expression (l, &FileNumber) == FALSE) - { - WARN_BAD_FILE_NUMBER; - return (l); - } - if (FileNumber < 0) - { - /* SCRATCH # -1 is silently ignored */ - return (l); - } - if (FileNumber == 0) - { - /* SCRATCH # 0 is silently ignored */ - return (l); - } - My->CurrentFile = find_file_by_number (FileNumber); - if (My->CurrentFile == NULL) - { - WARN_BAD_FILE_NUMBER; - return (l); - } - if (My->CurrentFile->DevMode != DEVMODE_CLOSED) - { - My->CurrentFile->DevMode = DEVMODE_CLOSED; - } - if (My->CurrentFile->cfp != NULL) - { - bwb_fclose (My->CurrentFile->cfp); - My->CurrentFile->cfp = NULL; - } - if (My->CurrentFile->buffer != NULL) - { - free (My->CurrentFile->buffer); - My->CurrentFile->buffer = NULL; - } - My->CurrentFile->width = 0; - My->CurrentFile->col = 1; - My->CurrentFile->row = 1; - My->CurrentFile->delimit = ','; - if (is_empty_string (My->CurrentFile->FileName)) - { - WARN_BAD_FILE_NAME; - return (l); - } - if (bwb_strcmp (My->CurrentFile->FileName, "*") != 0) - { - if ((My->CurrentFile->cfp = - fopen (My->CurrentFile->FileName, "w")) == NULL) - { - WARN_BAD_FILE_NAME; - return (l); - } - My->CurrentFile->DevMode = DEVMODE_OUTPUT; - } - /* OK */ - return (l); - } - WARN_SYNTAX_ERROR; - return (l); -} - -/* -============================================================================================ - SYSTEM and so on -============================================================================================ -*/ -static LineType * -bwb_system (LineType * l) -{ - /* - SYNTAX: SYSTEM - */ - assert (l != NULL); - assert (My != NULL); - assert (My->SYSOUT != NULL); - assert (My->SYSOUT->cfp != NULL); - - fprintf (My->SYSOUT->cfp, "\n"); - fflush (My->SYSOUT->cfp); - bwx_terminate (); - return (l); /* never reached */ -} - -/* --------------------------------------------------------------------------------------------- - BYE --------------------------------------------------------------------------------------------- -*/ - -LineType * -bwb_BYE (LineType * l) -{ - /* - SYNTAX: BYE - */ - - assert (l != NULL); - return bwb_system (l); -} - -/* --------------------------------------------------------------------------------------------- - DOS --------------------------------------------------------------------------------------------- -*/ - -LineType * -bwb_DOS (LineType * l) -{ - /* - SYNTAX: DOS - */ - - assert (l != NULL); - return bwb_system (l); -} - -/* --------------------------------------------------------------------------------------------- - FLEX --------------------------------------------------------------------------------------------- -*/ - -LineType * -bwb_FLEX (LineType * l) -{ - /* - SYNTAX: FLEX - */ - - assert (l != NULL); - return bwb_system (l); -} - -/* --------------------------------------------------------------------------------------------- - GOODBYE --------------------------------------------------------------------------------------------- -*/ -LineType * -bwb_GOODBYE (LineType * l) -{ - /* - SYNTAX: GOODBYE - */ - - assert (l != NULL); - return bwb_system (l); -} - -/* --------------------------------------------------------------------------------------------- - MON --------------------------------------------------------------------------------------------- -*/ - -LineType * -bwb_MON (LineType * l) -{ - /* - SYNTAX: MON - */ - - assert (l != NULL); - return bwb_system (l); -} - -/* --------------------------------------------------------------------------------------------- - QUIT --------------------------------------------------------------------------------------------- -*/ -LineType * -bwb_QUIT (LineType * l) -{ - /* - SYNTAX: QUIT - */ - - assert (l != NULL); - return bwb_system (l); -} - -/* --------------------------------------------------------------------------------------------- - SYSTEM --------------------------------------------------------------------------------------------- -*/ -LineType * -bwb_SYSTEM (LineType * l) -{ - /* - SYNTAX: SYSTEM - */ - - assert (l != NULL); - return bwb_system (l); -} - - -/* -============================================================================================ - LOAD and so on -============================================================================================ -*/ - -static LineType * -bwb_load (LineType * Line, char *Prompt, int IsNew) -{ - /* - ** - ** load a BASIC program from a file - ** - */ - /* - SYNTAX: ... [filename$] - */ - - assert (Line != NULL); - assert (Prompt != NULL); - assert (My != NULL); - assert (My->CurrentVersion != NULL); - - if (IsNew) - { - /* TRUE == LOAD */ - bwb_new (); - } - else - { - /* FALSE == MERGE */ - if (My->ProgramFilename != NULL) - { - free (My->ProgramFilename); - My->ProgramFilename = NULL; - } - } - if (line_is_eol (Line)) - { - /* default is the last filename used by LOAD or SAVE */ - /* if( My->CurrentVersion->OptionVersionValue & (D64 | G65 | G67 | G74) ) */ - if (is_empty_string (My->ProgramFilename)) - { - /* prompt for the program name */ - char *tbuf; - int tlen; - - tbuf = My->ConsoleInput; - tlen = MAX_LINE_LENGTH; - bwx_input (Prompt, FALSE, tbuf, tlen); - if (is_empty_string (tbuf)) - { - WARN_BAD_FILE_NAME; - return (Line); - } - if (My->ProgramFilename != NULL) - { - free (My->ProgramFilename); - My->ProgramFilename = NULL; - } - My->ProgramFilename = bwb_strdup (tbuf); - } - fprintf (My->SYSOUT->cfp, "Loading %s\n", My->ProgramFilename); - ResetConsoleColumn (); - } - else - { - /* Get an argument for filename */ - char *Value; - - Value = NULL; - if (line_read_string_expression (Line, &Value) == FALSE) - { - WARN_SYNTAX_ERROR; - return (Line); - } - if (is_empty_string (Value)) - { - WARN_BAD_FILE_NAME; - return (Line); - } - if (My->ProgramFilename != NULL) - { - free (My->ProgramFilename); - My->ProgramFilename = NULL; - } - My->ProgramFilename = Value; - } - if (bwb_fload (NULL) == FALSE) - { - WARN_BAD_FILE_NAME; - return (Line); - } - if (IsNew) - { - /* TRUE == LOAD */ - } - else - { - /* FALSE == MERGE */ - if (My->ProgramFilename != NULL) - { - free (My->ProgramFilename); - My->ProgramFilename = NULL; - } - } - /* - ** - ** FORCE SCAN - ** - */ - if (bwb_scan () == FALSE) - { - WARN_CANT_CONTINUE; - } - return (Line); -} - -/* --------------------------------------------------------------------------------------------- - CLOAD --------------------------------------------------------------------------------------------- -*/ -LineType * -bwb_CLOAD (LineType * Line) -{ - /* - SYNTAX: CLOAD [filename$] - */ - - assert (Line != NULL); - return bwb_load (Line, "CLOAD FILE NAME:", TRUE); -} - -/* --------------------------------------------------------------------------------------------- - LOAD --------------------------------------------------------------------------------------------- -*/ -LineType * -bwb_LOAD (LineType * Line) -{ - /* - SYNTAX: LOAD [filename$] - */ - - assert (Line != NULL); - return bwb_load (Line, "LOAD FILE NAME:", TRUE); -} - -/* --------------------------------------------------------------------------------------------- - MERGE --------------------------------------------------------------------------------------------- -*/ -LineType * -bwb_MERGE (LineType * l) -{ - /* - SYNTAX: MERGE [filename$] - */ - - assert (l != NULL); - return bwb_load (l, "MERGE FILE NAME:", FALSE); -} - -/* --------------------------------------------------------------------------------------------- - OLD --------------------------------------------------------------------------------------------- -*/ -LineType * -bwb_OLD (LineType * Line) -{ - /* - SYNTAX: OLD [filename$] - */ - - assert (Line != NULL); - return bwb_load (Line, "OLD PROBLEM NAME:", TRUE); -} - -/* --------------------------------------------------------------------------------------------- - TLOAD --------------------------------------------------------------------------------------------- -*/ -LineType * -bwb_TLOAD (LineType * Line) -{ - /* - SYNTAX: TLOAD [filename$] - */ - - assert (Line != NULL); - return bwb_load (Line, "TLOAD FILE NAME:", TRUE); -} - - -/* --------------------------------------------------------------------------------------------- - RENAME --------------------------------------------------------------------------------------------- -*/ -static LineType * -H14_RENAME (LineType * l) -{ - /* - SYNTAX: RENAME from$ TO to$ - */ - char *From; - char *To; - - assert (l != NULL); - - From = NULL; - To = NULL; - if (line_read_string_expression (l, &From) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (is_empty_string (From)) - { - WARN_BAD_FILE_NAME; - return (l); - } - if (line_skip_word (l, "TO") == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (line_read_string_expression (l, &To) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (is_empty_string (To)) - { - WARN_BAD_FILE_NAME; - return (l); - } - if (rename (From, To)) - { - WARN_BAD_FILE_NAME; - return (l); - } - return (l); -} - -LineType * -bwb_RENAME (LineType * l) -{ - /* - SYNTAX: RENAME filename$ - */ - - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - assert( My->ConsoleInput != NULL ); - - if (My->CurrentVersion->OptionVersionValue & (H14)) - { - /* RENAME == change an exisiting file's name */ - return H14_RENAME (l); - } - /* RENAME == change the BASIC program's name for a later SAVE */ - if (line_is_eol (l)) - { - /* RENAME */ - if (My->CurrentVersion->OptionVersionValue & (D64 | G65 | G67 | G74)) - { - /* prompt for the program name */ - char *tbuf; - int tlen; - - tbuf = My->ConsoleInput; - tlen = MAX_LINE_LENGTH; - bwx_input ("RENAME PROBLEM NAME:", FALSE, tbuf, tlen); - if (is_empty_string (tbuf)) - { - WARN_BAD_FILE_NAME; - return (l); - } - if (My->ProgramFilename != NULL) - { - free (My->ProgramFilename); - My->ProgramFilename = NULL; - } - My->ProgramFilename = bwb_strdup (tbuf); - } - else - { - WARN_SYNTAX_ERROR; - return (l); - } - } - else - { - /* RENAME value$ */ - char *Value; - - Value = NULL; - if (line_read_string_expression (l, &Value) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (is_empty_string (Value)) - { - WARN_BAD_FILE_NAME; - return (l); - } - if (My->ProgramFilename != NULL) - { - free (My->ProgramFilename); - My->ProgramFilename = NULL; - } - My->ProgramFilename = Value; - } - return (l); -} - - -/* --------------------------------------------------------------------------------------------- - MAT --------------------------------------------------------------------------------------------- -*/ - -extern void -Determinant (VariableType * v) -{ - /* http://easy-learn-c-language.blogspot.com/search/label/Numerical%20Methods */ - /* Numerical Methods: Determinant of nxn matrix using C */ - - DoubleType **matrix; - DoubleType ratio; - - int i; - int j; - int k; - int n; - - assert (v != NULL); - assert( My != NULL ); - - - My->LastDeterminant = 0; /* default */ - - n = v->UBOUND[0] - v->LBOUND[0] + 1; - - if ((matrix = (DoubleType **) calloc (n, sizeof (DoubleType *))) == NULL) - { - goto EXIT; - } - assert( matrix != NULL ); - for (i = 0; i < n; i++) - { - if ((matrix[i] = (DoubleType *) calloc (n, sizeof (DoubleType))) == NULL) - { - goto EXIT; - } - assert( matrix[i] != NULL ); - } - - for (i = 0; i < n; i++) - { - for (j = 0; j < n; j++) - { - VariantType variant; - CLEAR_VARIANT (&variant); - v->VINDEX[0] = v->LBOUND[0] + i; - v->VINDEX[1] = v->LBOUND[1] + j; - if (var_get (v, &variant) == FALSE) - { - WARN_VARIABLE_NOT_DECLARED; - goto EXIT; - } - if (variant.VariantTypeCode == StringTypeCode) - { - WARN_TYPE_MISMATCH; - goto EXIT; - } - matrix[i][j] = variant.Number; - } - } - - /* Conversion of matrix to upper triangular */ - - for (i = 0; i < n; i++) - { - for (j = 0; j < n; j++) - { - if (j > i) - { - if (matrix[i][i] == 0) - { - /* - Evaluation of an expression results in division - * by zero (nonfatal, the recommended recovery - * procedure is to supply machine infinity with the - * sign of the numerator and continue) - */ - if (WARN_DIVISION_BY_ZERO) - { - /* ERROR */ - goto EXIT; - } - /* CONTINUE */ - if (matrix[j][i] < 0) - { - ratio = MINDBL; - } - else - { - ratio = MAXDBL; - } - } - else - { - ratio = matrix[j][i] / matrix[i][i]; - } - for (k = 0; k < n; k++) - { - matrix[j][k] -= ratio * matrix[i][k]; - } - } - } - } - - - My->LastDeterminant = 1; /* storage for determinant */ - - for (i = 0; i < n; i++) - { - DoubleType Value; - - Value = matrix[i][i]; - My->LastDeterminant *= Value; - } - -EXIT: - if( matrix != NULL ) - { - for (i = 0; i < n; i++) - { - if( matrix[i] != NULL ) - { - free (matrix[i]); - /* matrix[i] = NULL; */ - } - } - free (matrix); - /* matrix = NULL; */ - } -} - -int -InvertMatrix (VariableType * vOut, VariableType * vIn) -{ - /* http://easy-learn-c-language.blogspot.com/search/label/Numerical%20Methods */ - /* Numerical Methods: Inverse of nxn matrix using C */ - - int Result; - DoubleType **matrix; - DoubleType ratio; - - int i; - int j; - int k; - int n; - - assert (vOut != NULL); - assert (vIn != NULL); - - Result = FALSE; - n = vIn->UBOUND[0] - vIn->LBOUND[0] + 1; - - if ((matrix = (DoubleType **) calloc (n, sizeof (DoubleType *))) == NULL) - { - goto EXIT; - } - assert( matrix != NULL ); - - for (i = 0; i < n; i++) - { - if ((matrix[i] = - (DoubleType *) calloc (n + n, sizeof (DoubleType))) == NULL) - { - goto EXIT; - } - assert( matrix[i] != NULL ); - } - - for (i = 0; i < n; i++) - { - for (j = 0; j < n; j++) - { - VariantType variant; - CLEAR_VARIANT (&variant); - - vIn->VINDEX[0] = vIn->LBOUND[0] + i; - vIn->VINDEX[1] = vIn->LBOUND[1] + j; - if (var_get (vIn, &variant) == FALSE) - { - WARN_VARIABLE_NOT_DECLARED; - goto EXIT; - } - if (variant.VariantTypeCode == StringTypeCode) - { - WARN_TYPE_MISMATCH; - goto EXIT; - } - matrix[i][j] = variant.Number; - } - } - - for (i = 0; i < n; i++) - { - for (j = n; j < 2 * n; j++) - { - if (i == (j - n)) - { - matrix[i][j] = 1.0; - } - else - { - matrix[i][j] = 0.0; - } - } - } - - for (i = 0; i < n; i++) - { - for (j = 0; j < n; j++) - { - if (i != j) - { - if (matrix[i][i] == 0) - { - /* - Evaluation of an expression results in division - * by zero (nonfatal, the recommended recovery - * procedure is to supply machine infinity with the - * sign of the numerator and continue) - */ - if (WARN_DIVISION_BY_ZERO) - { - /* ERROR */ - goto EXIT; - } - /* CONTINUE */ - if (matrix[j][i] < 0) - { - ratio = MINDBL; - } - else - { - ratio = MAXDBL; - } - } - else - { - ratio = matrix[j][i] / matrix[i][i]; - } - for (k = 0; k < 2 * n; k++) - { - matrix[j][k] -= ratio * matrix[i][k]; - } - } - } - } - - for (i = 0; i < n; i++) - { - DoubleType a; - - a = matrix[i][i]; - if (a == 0) - { - /* - Evaluation of an expression results in division - * by zero (nonfatal, the recommended recovery - * procedure is to supply machine infinity with the - * sign of the numerator and continue) - */ - if (WARN_DIVISION_BY_ZERO) - { - /* ERROR */ - goto EXIT; - } - /* CONTINUE */ - for (j = 0; j < 2 * n; j++) - { - if (matrix[i][j] < 0) - { - matrix[i][j] = MINDBL; - } - else - { - matrix[i][j] = MAXDBL; - } - } - } - else - { - for (j = 0; j < 2 * n; j++) - { - matrix[i][j] /= a; - } - } - } - - for (i = 0; i < n; i++) - { - for (j = 0; j < n; j++) - { - VariantType variant; - CLEAR_VARIANT (&variant); - - vOut->VINDEX[0] = vOut->LBOUND[0] + i; - vOut->VINDEX[1] = vOut->LBOUND[0] + j; - variant.VariantTypeCode = vOut->VariableTypeCode; - variant.Number = matrix[i][j + n]; - if (var_set (vOut, &variant) == FALSE) - { - WARN_VARIABLE_NOT_DECLARED; - goto EXIT; - } - } - } - /* - ** - ** Everything is OK - ** - */ - Result = TRUE; - - -EXIT: - if (matrix != NULL) - { - for (i = 0; i < n; i++) - { - if (matrix[i] != NULL) - { - free (matrix[i]); - /* matrix[i] = NULL; */ - } - } - free (matrix); - /* matrix = NULL; */ - } - return Result; -} - -static int -line_read_matrix_redim (LineType * l, VariableType * v) -{ - /* get OPTIONAL parameters if the variable is dimensioned */ - - assert (l != NULL); - assert (v != NULL); - - if (line_peek_LparenChar (l)) - { - /* get requested size, which is <= original array size */ - size_t array_units; - int n; - int dimensions; - int LBOUND[MAX_DIMS]; - int UBOUND[MAX_DIMS]; - - if (line_read_array_redim (l, &dimensions, LBOUND, UBOUND) == FALSE) - { - WARN_SYNTAX_ERROR; - return FALSE; - } - /* update array dimensions */ - array_units = 1; - for (n = 0; n < dimensions; n++) - { - if (UBOUND[n] < LBOUND[n]) - { - WARN_SUBSCRIPT_OUT_OF_RANGE; - return FALSE; - } - array_units *= UBOUND[n] - LBOUND[n] + 1; - } - if (array_units > v->array_units) - { - WARN_SUBSCRIPT_OUT_OF_RANGE; - return FALSE; - } - v->dimensions = dimensions; - for (n = 0; n < dimensions; n++) - { - v->LBOUND[n] = LBOUND[n]; - v->UBOUND[n] = UBOUND[n]; - } - } - return TRUE; -} - -LineType * -bwb_MAT (LineType * l) -{ - /* - SYNTAX: MAT A = CON - SYNTAX: MAT A = IDN - SYNTAX: MAT A = ZER - SYNTAX: MAT A = INV B - SYNTAX: MAT A = TRN B - SYNTAX: MAT A = (k) * B - SYNTAX: MAT A = B - SYNTAX: MAT A = B + C - SYNTAX: MAT A = B - C - SYNTAX: MAT A = B * C - */ - VariableType *v_A; - char varname_A[NameLengthMax + 1]; - - assert (l != NULL); - - /* just a placeholder for now. this will grow. */ - - if (line_read_varname (l, varname_A) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - v_A = mat_find (varname_A); - if (v_A == NULL) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - /* variable MUST be numeric */ - if (VAR_IS_STRING (v_A)) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (line_read_matrix_redim (l, v_A) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (line_skip_EqualChar (l) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - /* MAT A = ... */ - if (line_skip_word (l, "CON")) - { - /* MAT A = CON */ - /* MAT A = CON(I) */ - /* MAT A = CON(I,J) */ - /* MAT A = CON(I,J,K) */ - /* OK */ - int i; - int j; - int k; - - if (line_read_matrix_redim (l, v_A) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - - /* both arrays are of the same size */ - switch (v_A->dimensions) - { - case 1: - for (i = v_A->LBOUND[0]; i <= v_A->UBOUND[0]; i++) - { - VariantType variant; - CLEAR_VARIANT (&variant); - - variant.VariantTypeCode = v_A->VariableTypeCode; - variant.Number = 1; - v_A->VINDEX[0] = i; - if (var_set (v_A, &variant) == FALSE) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - } - break; - case 2: - for (i = v_A->LBOUND[0]; i <= v_A->UBOUND[0]; i++) - { - for (j = v_A->LBOUND[1]; j <= v_A->UBOUND[1]; j++) - { - VariantType variant; - CLEAR_VARIANT (&variant); - - variant.VariantTypeCode = v_A->VariableTypeCode; - variant.Number = 1; - v_A->VINDEX[0] = i; - v_A->VINDEX[1] = j; - if (var_set (v_A, &variant) == FALSE) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - } - } - break; - case 3: - for (i = v_A->LBOUND[0]; i <= v_A->UBOUND[0]; i++) - { - for (j = v_A->LBOUND[1]; j <= v_A->UBOUND[1]; j++) - { - for (k = v_A->LBOUND[2]; k <= v_A->UBOUND[2]; k++) - { - VariantType variant; - CLEAR_VARIANT (&variant); - - variant.VariantTypeCode = v_A->VariableTypeCode; - variant.Number = 1; - v_A->VINDEX[0] = i; - v_A->VINDEX[1] = j; - v_A->VINDEX[2] = k; - if (var_set (v_A, &variant) == FALSE) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - } - } - } - break; - default: - WARN_SYNTAX_ERROR; - return (l); - } - } - else if (line_skip_word (l, "IDN")) - { - /* MAT A = IDN */ - /* MAT A = IDN(I,J) */ - /* OK */ - int i; - int j; - - if (line_read_matrix_redim (l, v_A) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - - if (v_A->dimensions != 2) - { - WARN_SUBSCRIPT_OUT_OF_RANGE; - return (l); - } - if (v_A->LBOUND[0] != v_A->LBOUND[1]) - { - WARN_SUBSCRIPT_OUT_OF_RANGE; - return (l); - } - if (v_A->UBOUND[0] != v_A->UBOUND[1]) - { - WARN_SUBSCRIPT_OUT_OF_RANGE; - return (l); - } - /* square matrix */ - for (i = v_A->LBOUND[0]; i <= v_A->UBOUND[0]; i++) - { - for (j = v_A->LBOUND[1]; j <= v_A->UBOUND[1]; j++) - { - VariantType variant; - CLEAR_VARIANT (&variant); - - variant.VariantTypeCode = v_A->VariableTypeCode; - if (i == j) - { - variant.Number = 1; - } - else - { - variant.Number = 0; - } - v_A->VINDEX[0] = i; - v_A->VINDEX[1] = j; - if (var_set (v_A, &variant) == FALSE) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - } - } - } - else if (line_skip_word (l, "ZER")) - { - /* MAT A = ZER */ - /* MAT A = ZER(I) */ - /* MAT A = ZER(I,J) */ - /* MAT A = ZER(I,J,K) */ - /* OK */ - int i; - int j; - int k; - - if (line_read_matrix_redim (l, v_A) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - /* both arrays are of the same size */ - switch (v_A->dimensions) - { - case 1: - for (i = v_A->LBOUND[0]; i <= v_A->UBOUND[0]; i++) - { - VariantType variant; - CLEAR_VARIANT (&variant); - - variant.VariantTypeCode = v_A->VariableTypeCode; - variant.Number = 0; - v_A->VINDEX[0] = i; - if (var_set (v_A, &variant) == FALSE) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - } - break; - case 2: - for (i = v_A->LBOUND[0]; i <= v_A->UBOUND[0]; i++) - { - for (j = v_A->LBOUND[1]; j <= v_A->UBOUND[1]; j++) - { - VariantType variant; - CLEAR_VARIANT (&variant); - - variant.VariantTypeCode = v_A->VariableTypeCode; - variant.Number = 0; - v_A->VINDEX[0] = i; - v_A->VINDEX[1] = j; - if (var_set (v_A, &variant) == FALSE) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - } - } - break; - case 3: - for (i = v_A->LBOUND[0]; i <= v_A->UBOUND[0]; i++) - { - for (j = v_A->LBOUND[1]; j <= v_A->UBOUND[1]; j++) - { - for (k = v_A->LBOUND[2]; k <= v_A->UBOUND[2]; k++) - { - VariantType variant; - CLEAR_VARIANT (&variant); - - variant.VariantTypeCode = v_A->VariableTypeCode; - variant.Number = 0; - v_A->VINDEX[0] = i; - v_A->VINDEX[1] = j; - v_A->VINDEX[2] = k; - if (var_set (v_A, &variant) == FALSE) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - } - } - } - break; - default: - WARN_SYNTAX_ERROR; - return (l); - } - } - else if (line_skip_word (l, "INV")) - { - /* MAT A = INV B */ - /* MAT A = INV( B ) */ - /* OK */ - VariableType *v_B; - char varname_B[NameLengthMax + 1]; - - if (v_A->dimensions != 2) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (v_A->LBOUND[0] != v_A->LBOUND[1] || v_A->UBOUND[0] != v_A->UBOUND[1]) - { - WARN_SUBSCRIPT_OUT_OF_RANGE; - return (l); - } - if (line_skip_LparenChar (l)) - { - /* optional */ - } - if (line_read_varname (l, varname_B) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - - if ((v_B = mat_find (varname_B)) == NULL) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - /* variable MUST be numeric */ - if (VAR_IS_STRING (v_B)) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (line_read_matrix_redim (l, v_B) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (line_skip_RparenChar (l)) - { - /* optional */ - } - if (v_B->dimensions != 2) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (v_B->LBOUND[0] != v_B->LBOUND[1] || v_B->UBOUND[0] != v_B->UBOUND[1]) - { - WARN_SUBSCRIPT_OUT_OF_RANGE; - return (l); - } - if (v_A->LBOUND[0] != v_B->LBOUND[0] || v_A->UBOUND[0] != v_B->UBOUND[0]) - { - WARN_SUBSCRIPT_OUT_OF_RANGE; - return (l); - } - /* square matrix */ - Determinant (v_B); - if (My->LastDeterminant == 0) - { - WARN_ILLEGAL_FUNCTION_CALL; - return (l); - } - if (InvertMatrix (v_A, v_B) == FALSE) - { - WARN_ILLEGAL_FUNCTION_CALL; - return (l); - } - } - else if (line_skip_word (l, "TRN")) - { - /* MAT A = TRN B */ - /* MAT A = TRN( B ) */ - /* OK */ - int i; - int j; - VariableType *v_B; - char varname_B[NameLengthMax + 1]; - - if (v_A->dimensions != 2) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (line_skip_LparenChar (l)) - { - /* optional */ - } - if (line_read_varname (l, varname_B) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - if ((v_B = mat_find (varname_B)) == NULL) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - /* variable MUST be numeric */ - if (VAR_IS_STRING (v_B)) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (line_read_matrix_redim (l, v_B) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (line_skip_RparenChar (l)) - { - /* optional */ - } - if (v_B->dimensions != 2) - { - WARN_SYNTAX_ERROR; - return (l); - } - /* MxN */ - if (v_A->LBOUND[0] != v_B->LBOUND[1] || v_A->UBOUND[0] != v_B->UBOUND[1]) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (v_A->LBOUND[1] != v_B->LBOUND[0] || v_A->UBOUND[1] != v_B->UBOUND[0]) - { - WARN_SYNTAX_ERROR; - return (l); - } - /* transpose matrix */ - for (i = v_A->LBOUND[0]; i <= v_A->UBOUND[0]; i++) - { - for (j = v_A->LBOUND[1]; j <= v_A->UBOUND[1]; j++) - { - VariantType variant; - CLEAR_VARIANT (&variant); - - v_B->VINDEX[1] = i; - v_B->VINDEX[0] = j; - if (var_get (v_B, &variant) == FALSE) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - v_A->VINDEX[0] = i; - v_A->VINDEX[1] = j; - if (var_set (v_A, &variant) == FALSE) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - } - } - } - else if (line_peek_LparenChar (l)) - { - /* MAT A = (k) * B */ - DoubleType Multiplier; - VariableType *v_B; - int i; - int j; - int k; - char *E; - int p; - char varname_B[NameLengthMax + 1]; - char *tbuf; - - tbuf = My->ConsoleInput; - bwb_strcpy (tbuf, &(l->buffer[l->position])); - E = bwb_strrchr (tbuf, '*'); - if (E == NULL) - { - WARN_SYNTAX_ERROR; - return (l); - } - *E = NulChar; - p = 0; - if (buff_read_numeric_expression (tbuf, &p, &Multiplier) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - l->position += p; - if (line_skip_StarChar (l) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (line_read_varname (l, varname_B) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - - if ((v_B = mat_find (varname_B)) == NULL) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - /* variable MUST be numeric */ - if (VAR_IS_STRING (v_B)) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (line_read_matrix_redim (l, v_B) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (v_A->dimensions != v_B->dimensions) - { - WARN_SYNTAX_ERROR; - return (l); - } - /* both arrays are of the same size */ - switch (v_A->dimensions) - { - case 1: - for (i = v_A->LBOUND[0]; i <= v_A->UBOUND[0]; i++) - { - VariantType variant; - CLEAR_VARIANT (&variant); - - v_B->VINDEX[0] = i; - if (var_get (v_B, &variant) == FALSE) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - - variant.Number *= Multiplier; - - v_A->VINDEX[0] = i; - if (var_set (v_A, &variant) == FALSE) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - } - break; - case 2: - for (i = v_A->LBOUND[0]; i <= v_A->UBOUND[0]; i++) - { - for (j = v_A->LBOUND[1]; j <= v_A->UBOUND[1]; j++) - { - VariantType variant; - CLEAR_VARIANT (&variant); - - v_B->VINDEX[0] = i; - v_B->VINDEX[1] = j; - if (var_get (v_B, &variant) == FALSE) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - - variant.Number *= Multiplier; - - v_A->VINDEX[0] = i; - v_A->VINDEX[1] = j; - if (var_set (v_A, &variant) == FALSE) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - } - } - break; - case 3: - for (i = v_A->LBOUND[0]; i <= v_A->UBOUND[0]; i++) - { - for (j = v_A->LBOUND[1]; j <= v_A->UBOUND[1]; j++) - { - for (k = v_A->LBOUND[2]; k <= v_A->UBOUND[2]; k++) - { - VariantType variant; - CLEAR_VARIANT (&variant); - - v_B->VINDEX[0] = i; - v_B->VINDEX[1] = j; - v_B->VINDEX[2] = k; - if (var_get (v_B, &variant) == FALSE) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - - variant.Number *= Multiplier; - - v_A->VINDEX[0] = i; - v_A->VINDEX[1] = j; - v_A->VINDEX[2] = k; - if (var_set (v_A, &variant) == FALSE) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - } - } - } - break; - default: - WARN_SYNTAX_ERROR; - return (l); - } - } - else - { - /* MAT A = B */ - /* MAT A = B + C */ - /* MAT A = B - C */ - /* MAT A = B * C */ - VariableType *v_B; - char varname_B[NameLengthMax + 1]; - - if (line_read_varname (l, varname_B) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - - if ((v_B = mat_find (varname_B)) == NULL) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - /* variable MUST be numeric */ - if (VAR_IS_STRING (v_B)) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (line_read_matrix_redim (l, v_B) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (line_is_eol (l)) - { - /* MAT A = B */ - /* OK */ - int i; - int j; - int k; - - if (v_A->dimensions != v_B->dimensions) - { - WARN_SYNTAX_ERROR; - return (l); - } - /* both arrays are of the same size */ - switch (v_A->dimensions) - { - case 1: - for (i = v_A->LBOUND[0]; i <= v_A->UBOUND[0]; i++) - { - VariantType variant; - CLEAR_VARIANT (&variant); - - v_B->VINDEX[0] = i; - if (var_get (v_B, &variant) == FALSE) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - - v_A->VINDEX[0] = i; - if (var_set (v_A, &variant) == FALSE) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - } - break; - case 2: - for (i = v_A->LBOUND[0]; i <= v_A->UBOUND[0]; i++) - { - for (j = v_A->LBOUND[1]; j <= v_A->UBOUND[1]; j++) - { - VariantType variant; - CLEAR_VARIANT (&variant); - - v_B->VINDEX[0] = i; - v_B->VINDEX[1] = j; - if (var_get (v_B, &variant) == FALSE) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - - v_A->VINDEX[0] = i; - v_A->VINDEX[1] = j; - if (var_set (v_A, &variant) == FALSE) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - } - } - break; - case 3: - for (i = v_A->LBOUND[0]; i <= v_A->UBOUND[0]; i++) - { - for (j = v_A->LBOUND[1]; j <= v_A->UBOUND[1]; j++) - { - for (k = v_A->LBOUND[2]; k <= v_A->UBOUND[2]; k++) - { - VariantType variant; - CLEAR_VARIANT (&variant); - - v_B->VINDEX[0] = i; - v_B->VINDEX[1] = j; - v_B->VINDEX[2] = k; - if (var_get (v_B, &variant) == FALSE) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - - v_A->VINDEX[0] = i; - v_A->VINDEX[1] = j; - v_A->VINDEX[2] = k; - if (var_set (v_A, &variant) == FALSE) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - } - } - } - break; - default: - WARN_SYNTAX_ERROR; - return (l); - } - } - else if (line_skip_PlusChar (l)) - { - /* MAT A = B + C */ - /* OK */ - int i; - int j; - int k; - VariableType *v_C; - char varname_C[NameLengthMax + 1]; - - if (v_A->dimensions != v_B->dimensions) - { - WARN_SYNTAX_ERROR; - return (l); - } - /* both arrays are of the same size */ - - if (line_read_varname (l, varname_C) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - - if ((v_C = mat_find (varname_C)) == NULL) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - /* variable MUST be numeric */ - if (VAR_IS_STRING (v_C)) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (line_read_matrix_redim (l, v_C) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (v_B->dimensions != v_C->dimensions) - { - WARN_SYNTAX_ERROR; - return (l); - } - /* both arrays are of the same size */ - switch (v_A->dimensions) - { - case 1: - for (i = v_A->LBOUND[0]; i <= v_A->UBOUND[0]; i++) - { - VariantType variant_L; - VariantType variant_R; - CLEAR_VARIANT (&variant_L); - CLEAR_VARIANT (&variant_R); - - v_B->VINDEX[0] = i; - if (var_get (v_B, &variant_L) == FALSE) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - - v_C->VINDEX[0] = i; - if (var_get (v_C, &variant_R) == FALSE) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - - variant_L.Number += variant_R.Number; - - v_A->VINDEX[0] = i; - if (var_set (v_A, &variant_L) == FALSE) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - } - break; - case 2: - for (i = v_A->LBOUND[0]; i <= v_A->UBOUND[0]; i++) - { - for (j = v_A->LBOUND[1]; j <= v_A->UBOUND[1]; j++) - { - VariantType variant_L; - VariantType variant_R; - CLEAR_VARIANT (&variant_L); - CLEAR_VARIANT (&variant_R); - - v_B->VINDEX[0] = i; - v_B->VINDEX[1] = j; - if (var_get (v_B, &variant_L) == FALSE) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - - v_C->VINDEX[0] = i; - v_C->VINDEX[1] = j; - if (var_get (v_C, &variant_R) == FALSE) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - - variant_L.Number += variant_R.Number; - - v_A->VINDEX[0] = i; - v_A->VINDEX[1] = j; - if (var_set (v_A, &variant_L) == FALSE) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - } - } - break; - case 3: - for (i = v_A->LBOUND[0]; i <= v_A->UBOUND[0]; i++) - { - for (j = v_A->LBOUND[1]; j <= v_A->UBOUND[1]; j++) - { - for (k = v_A->LBOUND[2]; k <= v_A->UBOUND[2]; k++) - { - VariantType variant_L; - VariantType variant_R; - CLEAR_VARIANT (&variant_L); - CLEAR_VARIANT (&variant_R); - - v_B->VINDEX[0] = i; - v_B->VINDEX[1] = j; - v_B->VINDEX[2] = k; - if (var_get (v_B, &variant_L) == FALSE) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - - v_C->VINDEX[0] = i; - v_C->VINDEX[1] = j; - v_C->VINDEX[2] = k; - if (var_get (v_C, &variant_R) == FALSE) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - - variant_L.Number += variant_R.Number; - - v_A->VINDEX[0] = i; - v_A->VINDEX[1] = j; - v_A->VINDEX[2] = k; - if (var_set (v_A, &variant_L) == FALSE) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - } - } - } - break; - default: - WARN_SYNTAX_ERROR; - return (l); - } - } - else if (line_skip_MinusChar (l)) - { - /* MAT A = B - C */ - /* OK */ - int i; - int j; - int k; - VariableType *v_C; - char varname_C[NameLengthMax + 1]; - - if (v_A->dimensions != v_B->dimensions) - { - WARN_SYNTAX_ERROR; - return (l); - } - /* both arrays are of the same size */ - - if (line_read_varname (l, varname_C) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - - if ((v_C = mat_find (varname_C)) == NULL) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - /* variable MUST be numeric */ - if (VAR_IS_STRING (v_C)) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (line_read_matrix_redim (l, v_C) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (v_B->dimensions != v_C->dimensions) - { - WARN_SYNTAX_ERROR; - return (l); - } - /* both arrays are of the same dimension */ - switch (v_A->dimensions) - { - case 1: - for (i = v_A->LBOUND[0]; i <= v_A->UBOUND[0]; i++) - { - VariantType variant_L; - VariantType variant_R; - CLEAR_VARIANT (&variant_L); - CLEAR_VARIANT (&variant_R); - - v_B->VINDEX[0] = i; - if (var_get (v_B, &variant_L) == FALSE) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - - v_C->VINDEX[0] = i; - if (var_get (v_C, &variant_R) == FALSE) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - - variant_L.Number -= variant_R.Number; - - v_A->VINDEX[0] = i; - if (var_set (v_A, &variant_L) == FALSE) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - } - break; - case 2: - for (i = v_A->LBOUND[0]; i <= v_A->UBOUND[0]; i++) - { - for (j = v_A->LBOUND[1]; j <= v_A->UBOUND[1]; j++) - { - VariantType variant_L; - VariantType variant_R; - CLEAR_VARIANT (&variant_L); - CLEAR_VARIANT (&variant_R); - - v_B->VINDEX[0] = i; - v_B->VINDEX[1] = j; - if (var_get (v_B, &variant_L) == FALSE) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - - v_C->VINDEX[0] = i; - v_C->VINDEX[1] = j; - if (var_get (v_C, &variant_R) == FALSE) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - - variant_L.Number -= variant_R.Number; - - v_A->VINDEX[0] = i; - v_A->VINDEX[1] = j; - if (var_set (v_A, &variant_L) == FALSE) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - } - } - break; - case 3: - for (i = v_A->LBOUND[0]; i <= v_A->UBOUND[0]; i++) - { - for (j = v_A->LBOUND[1]; j <= v_A->UBOUND[1]; j++) - { - for (k = v_A->LBOUND[2]; k <= v_A->UBOUND[2]; k++) - { - VariantType variant_L; - VariantType variant_R; - CLEAR_VARIANT (&variant_L); - CLEAR_VARIANT (&variant_R); - - v_B->VINDEX[0] = i; - v_B->VINDEX[1] = j; - v_B->VINDEX[2] = k; - if (var_get (v_B, &variant_L) == FALSE) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - - v_C->VINDEX[0] = i; - v_C->VINDEX[1] = j; - v_C->VINDEX[2] = k; - if (var_get (v_C, &variant_R) == FALSE) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - - variant_L.Number -= variant_R.Number; - - v_A->VINDEX[0] = i; - v_A->VINDEX[1] = j; - v_A->VINDEX[2] = k; - if (var_set (v_A, &variant_L) == FALSE) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - } - } - } - break; - default: - WARN_SYNTAX_ERROR; - return (l); - } - } - else if (line_skip_StarChar (l)) - { - /* MAT A = B * C */ - int i; - int j; - int k; - VariableType *v_C; - char varname_C[NameLengthMax + 1]; - - - if (v_A->dimensions != 2) - { - WARN_SUBSCRIPT_OUT_OF_RANGE; - return (l); - } - if (v_B->dimensions != 2) - { - WARN_SUBSCRIPT_OUT_OF_RANGE; - return (l); - } - if (line_read_varname (l, varname_C) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - if ((v_C = mat_find (varname_C)) == NULL) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - /* variable MUST be numeric */ - if (VAR_IS_STRING (v_C)) - { - WARN_TYPE_MISMATCH; - return (l); - } - if (line_read_matrix_redim (l, v_C) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (v_C->dimensions != 2) - { - WARN_SUBSCRIPT_OUT_OF_RANGE; - return (l); - } - if (v_A->LBOUND[0] != v_B->LBOUND[0]) - { - WARN_SUBSCRIPT_OUT_OF_RANGE; - return (l); - } - if (v_A->UBOUND[0] != v_B->UBOUND[0]) - { - WARN_SUBSCRIPT_OUT_OF_RANGE; - return (l); - } - if (v_A->LBOUND[1] != v_C->LBOUND[1]) - { - WARN_SUBSCRIPT_OUT_OF_RANGE; - return (l); - } - if (v_A->UBOUND[1] != v_C->UBOUND[1]) - { - WARN_SUBSCRIPT_OUT_OF_RANGE; - return (l); - } - if (v_B->LBOUND[1] != v_C->LBOUND[0]) - { - WARN_SUBSCRIPT_OUT_OF_RANGE; - return (l); - } - if (v_B->UBOUND[1] != v_C->UBOUND[0]) - { - WARN_SUBSCRIPT_OUT_OF_RANGE; - return (l); - } - for (i = v_A->LBOUND[0]; i <= v_A->UBOUND[0]; i++) - { - for (j = v_A->LBOUND[1]; j <= v_A->UBOUND[1]; j++) - { - VariantType variant_A; - CLEAR_VARIANT (&variant_A); - - variant_A.VariantTypeCode = v_A->VariableTypeCode; - variant_A.Number = 0; - - v_A->VINDEX[0] = i; - v_A->VINDEX[1] = j; - if (var_set (v_A, &variant_A) == FALSE) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - for (k = v_C->LBOUND[0]; k <= v_C->UBOUND[0]; k++) - { - VariantType variant_B; - VariantType variant_C; - CLEAR_VARIANT (&variant_B); - CLEAR_VARIANT (&variant_C); - - v_A->VINDEX[0] = i; - v_A->VINDEX[1] = j; - if (var_get (v_A, &variant_A) == FALSE) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - - v_B->VINDEX[0] = i; - v_B->VINDEX[1] = k; - if (var_get (v_B, &variant_B) == FALSE) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - - v_C->VINDEX[0] = k; - v_C->VINDEX[1] = j; - if (var_get (v_C, &variant_C) == FALSE) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - - variant_A.Number += variant_B.Number * variant_C.Number; - - v_A->VINDEX[0] = i; - v_A->VINDEX[1] = j; - if (var_set (v_A, &variant_A) == FALSE) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - } - } - } - } - else - { - WARN_SYNTAX_ERROR; - return (l); - } - } - return (l); -} - - - -/* --------------------------------------------------------------------------------------------- - STORE --------------------------------------------------------------------------------------------- -*/ - - -LineType * -bwb_STORE (LineType * l) -{ - /* - SYNTAX: STORE NumericArrayName - */ - - assert (l != NULL); - return bwb_CSAVE8 (l); -} - - -/* --------------------------------------------------------------------------------------------- - CSAVE* --------------------------------------------------------------------------------------------- -*/ - -#define CSAVE_VERSION_1 0x20150218L - -LineType * -bwb_CSAVE8 (LineType * l) -{ - /* - SYNTAX: CSAVE* NumericArrayName - */ - VariableType *v = NULL; - FILE *f; - unsigned long n; - size_t t; - char varname[NameLengthMax + 1]; - - assert (l != NULL); - - if (line_read_varname (l, varname) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - - v = mat_find (varname); - if (v == NULL) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - /* variable MUST be numeric */ - if (VAR_IS_STRING (v)) - { - WARN_SYNTAX_ERROR; - return (l); - } - /* variable MUST be an array */ - if (v->dimensions == 0) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (line_read_matrix_redim (l, v) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - /* variable storage is a mess, we bypass that tradition here. */ - t = v->array_units; - if (t <= 1) - { - WARN_SYNTAX_ERROR; - return (l); - } - /* open file */ - f = fopen (v->name, "w"); - if (f == NULL) - { - WARN_SYNTAX_ERROR; - return (l); - } - /* write version number */ - n = CSAVE_VERSION_1; - fwrite (&n, sizeof (long), 1, f); - /* write total number of elements */ - fwrite (&t, sizeof (long), 1, f); - /* write data */ - fwrite (v->Value.Number, sizeof (DoubleType), t, f); - /* OK */ - bwb_fclose (f); - return (l); -} - -/* --------------------------------------------------------------------------------------------- - RECALL --------------------------------------------------------------------------------------------- -*/ - -LineType * -bwb_RECALL (LineType * l) -{ - /* - SYNTAX: RECALL NumericArrayName - */ - - assert (l != NULL); - return bwb_CLOAD8 (l); -} - -/* --------------------------------------------------------------------------------------------- - CLOAD* --------------------------------------------------------------------------------------------- -*/ - - -LineType * -bwb_CLOAD8 (LineType * l) -{ - /* - SYNTAX: CLOAD* NumericArrayName - */ - VariableType *v = NULL; - FILE *f; - unsigned long n; - size_t t; - char varname[NameLengthMax + 1]; - - assert (l != NULL); - - if (line_read_varname (l, varname) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - - v = mat_find (varname); - if (v == NULL) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - - /* variable MUST be numeric */ - if (VAR_IS_STRING (v)) - { - WARN_SYNTAX_ERROR; - return (l); - } - /* variable MUST be an array */ - if (v->dimensions == 0) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (line_read_matrix_redim (l, v) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - /* variable storage is a mess, we bypass that tradition here. */ - t = v->array_units; - if (t <= 1) - { - WARN_SYNTAX_ERROR; - return (l); - } - /* open file */ - f = fopen (v->name, "r"); - if (f == NULL) - { - WARN_BAD_FILE_NAME; - return (l); - } - /* read version number */ - n = 0; - fread (&n, sizeof (long), 1, f); - if (n != CSAVE_VERSION_1) - { - bwb_fclose (f); - WARN_BAD_FILE_NAME; - return (l); - } - /* read total number of elements */ - n = 0; - fread (&n, sizeof (long), 1, f); - if (n != t) - { - bwb_fclose (f); - WARN_BAD_FILE_NAME; - return (l); - } - /* read data */ - fread (v->Value.Number, sizeof (DoubleType), t, f); - /* OK */ - bwb_fclose (f); - return (l); -} - - - - -/* -============================================================================================ - SAVE and so on -============================================================================================ -*/ - -static LineType * -bwb_save (LineType * Line, char *Prompt) -{ - /* - SYNTAX: SAVE [filename$] - */ - FILE *outfile; - - assert (Line != NULL); - assert (Prompt != NULL); - assert( My != NULL ); - assert( My->ConsoleInput != NULL ); - assert( My->SYSOUT != NULL ); - assert( My->SYSOUT->cfp != NULL ); - - - /* Get an argument for filename */ - if (line_is_eol (Line)) - { - /* default is the last filename used by LOAD or SAVE */ - if (is_empty_string (My->ProgramFilename) && Prompt != NULL) - { - /* prompt for the program name */ - char *tbuf; - int tlen; - - tbuf = My->ConsoleInput; - tlen = MAX_LINE_LENGTH; - bwx_input (Prompt, FALSE, tbuf, tlen); - if (is_empty_string (tbuf)) - { - WARN_BAD_FILE_NAME; - return (Line); - } - if (My->ProgramFilename != NULL) - { - free (My->ProgramFilename); - My->ProgramFilename = NULL; - } - My->ProgramFilename = bwb_strdup (tbuf); - } - assert( My->ProgramFilename != NULL ); - fprintf (My->SYSOUT->cfp, "Saving %s\n", My->ProgramFilename); - ResetConsoleColumn (); - } - else - { - char *Value; - - Value = NULL; - if (line_read_string_expression (Line, &Value) == FALSE) - { - WARN_SYNTAX_ERROR; - return (Line); - } - if (is_empty_string (Value)) - { - WARN_BAD_FILE_NAME; - return (Line); - } - if (My->ProgramFilename != NULL) - { - free (My->ProgramFilename); - } - My->ProgramFilename = Value; - } - assert( My->ProgramFilename != NULL ); - if ((outfile = fopen (My->ProgramFilename, "w")) == NULL) - { - WARN_BAD_FILE_NAME; - return (Line); - } - bwb_xlist (Line, outfile); - bwb_fclose (outfile); - return (Line); -} - -/* --------------------------------------------------------------------------------------------- - CSAVE --------------------------------------------------------------------------------------------- -*/ - -LineType * -bwb_CSAVE (LineType * Line) -{ - /* - SYNTAX: CSAVE [filename$] - */ - - assert (Line != NULL); - return bwb_save (Line, "CSAVE FILE NAME:"); -} - -/* --------------------------------------------------------------------------------------------- - REPLACE --------------------------------------------------------------------------------------------- -*/ -LineType * -bwb_REPLACE (LineType * Line) -{ - /* - SYNTAX: REPLACE [filename$] - */ - - assert (Line != NULL); - return bwb_save (Line, "REPLACE FILE NAME:"); -} - -/* --------------------------------------------------------------------------------------------- - SAVE --------------------------------------------------------------------------------------------- -*/ -LineType * -bwb_SAVE (LineType * l) -{ - /* - SYNTAX: SAVE [filename$] - */ - - assert (l != NULL); - return bwb_save (l, "SAVE FILE NAME:"); -} - -/* --------------------------------------------------------------------------------------------- - TSAVE --------------------------------------------------------------------------------------------- -*/ - -LineType * -bwb_TSAVE (LineType * Line) -{ - /* - SYNTAX: TSAVE [filename$] - */ - - assert (Line != NULL); - return bwb_save (Line, "TSAVE FILE NAME:"); -} - - -/* -============================================================================================ - LIST and so on -============================================================================================ -*/ -static int -xl_line (FILE * file, LineType * l) -{ - char LineExecuted; - char *C; /* start of comment text */ - char *buffer; /* 0...99999 */ - - assert (file != NULL); - assert (l != NULL); - assert( My != NULL ); - assert( My->NumLenBuffer != NULL ); - assert( My->CurrentVersion != NULL ); - assert( My->SYSOUT != NULL ); - assert( My->SYSOUT->cfp != NULL ); - assert( My->SYSPRN != NULL ); - assert( My->SYSPRN->cfp != NULL ); - - /* - ** The only difference between LIST, LLIST and SAVE is: - ** LIST and LLIST display an '*' - ** when a line has been executed - ** and OPTION COVERAGE ON is enabled. - */ - - buffer = My->NumLenBuffer; - LineExecuted = ' '; - if (My->CurrentVersion->OptionFlags & (OPTION_COVERAGE_ON)) - { - if (l->LineFlags & LINE_EXECUTED) - { - if (file == My->SYSOUT->cfp || file == My->SYSPRN->cfp) - { - /* LIST */ - /* LLIST */ - LineExecuted = '*'; - } - else - { - /* SAVE */ - /* EDIT implies SAVE */ - } - } - } - - C = l->buffer; - if (l->LineFlags & LINE_NUMBERED) - { - /* explicitly numbered */ - sprintf (buffer, "%*d", LineNumberDigits, l->number); - /* ##### xxx */ - } - else - { - /* implicitly numbered */ - if (My->LastLineNumber == l->number) - { - /* multi-statement line */ - if (l->cmdnum == C_REM - && IS_CHAR (l->buffer[0], My->CurrentVersion->OptionCommentChar)) - { - /* trailing comment */ - sprintf (buffer, "%*s%c", LineNumberDigits - 1, "", - My->CurrentVersion->OptionCommentChar); - C++; /* skip comment char */ - while (*C == ' ') - { - /* skip spaces */ - C++; - } - /* ____' xxx */ - } - else if (My->CurrentVersion->OptionStatementChar) - { - /* all other commands, add a colon */ - sprintf (buffer, "%*s%c", LineNumberDigits - 1, "", - My->CurrentVersion->OptionStatementChar); - /* ____: xxx */ - } - else - { - /* - The user is trying to list a multi-line statement - in a dialect that does NOT support multi-line statements. - This could occur when LOADing in one dialect and then SAVEing as another dialect, such as: - OPTION VERSION BASIC-80 - LOAD "TEST1.BAS" - 100 REM TEST - 110 PRINT:PRINT:PRINT - OPTION VERSION MARK-I - EDIT - 100 REM TEST - 110 PRINT - PRINT - PRINT - The only thing we can reasonably do is put spaces for the line number, - since the user will have to edit the results manually anyways. - */ - sprintf (buffer, "%*s", LineNumberDigits, ""); - /* _____ xxx */ - } - } - else - { - /* single-statement line */ - sprintf (buffer, "%*s", LineNumberDigits, ""); - /* _____ xxx */ - } - } - - fprintf (file, "%s", buffer); - fprintf (file, "%c", LineExecuted); - - /* if( TRUE ) */ - { - /* %INCLUDE */ - int i; - for (i = 0; i < l->IncludeLevel; i++) - { - fputc (' ', file); - } - } - if (My->OptionIndentInteger > 0) - { - int i; - - for (i = 0; i < l->Indention; i++) - { - int j; - for (j = 0; j < My->OptionIndentInteger; j++) - { - fputc (' ', file); - } - } - } - fprintf (file, "%s\n", C); - - My->LastLineNumber = l->number; - - return TRUE; -} - -static LineType * -bwb_xlist (LineType * l, FILE * file) -{ - - assert (l != NULL); - assert (file != NULL); - assert( My != NULL ); - assert( My->StartMarker != NULL ); - assert( My->EndMarker != NULL ); - - /* - ** - ** FORCE SCAN - ** - */ - if (bwb_scan () == FALSE) - { - /* - ** - ** we are used by bwb_SAVE and bwb_EDIT - ** - WARN_CANT_CONTINUE; - return (l); - */ - } - - if (line_is_eol (l)) - { - /* LIST */ - LineType *x; - /* now go through and list appropriate lines */ - My->LastLineNumber = -1; - for (x = My->StartMarker->next; x != My->EndMarker; x = x->next) - { - xl_line (file, x); - } - fprintf (file, "\n"); - } - else - { - do - { - int head; - int tail; - - if (line_read_line_sequence (l, &head, &tail)) - { - /* LIST 's' - 'e' */ - LineType *x; - if (head < MINLIN || head > MAXLIN) - { - WARN_UNDEFINED_LINE; - return (l); - } - if (tail < MINLIN || tail > MAXLIN) - { - WARN_UNDEFINED_LINE; - return (l); - } - if (head > tail) - { - WARN_UNDEFINED_LINE; - return (l); - } - /* valid range */ - /* now go through and list appropriate lines */ - My->LastLineNumber = -1; - for (x = My->StartMarker->next; x != My->EndMarker; x = x->next) - { - if (head <= x->number && x->number <= tail) - { - xl_line (file, x); - } - } - fprintf (file, "\n"); - } - else - { - WARN_SYNTAX_ERROR; - return (l); - } - } - while (line_skip_seperator (l)); - } - if (file == My->SYSOUT->cfp) - { - ResetConsoleColumn (); - } - return (l); -} - -/* --------------------------------------------------------------------------------------------- - LIST --------------------------------------------------------------------------------------------- -*/ -LineType * -bwb_LIST (LineType * l) -{ - /* - SYNTAX: LIST - SYNTAX: LIST line [,...] - SYNTAX: LIST line - line - */ - - assert (l != NULL); - - return bwb_xlist (l, My->SYSOUT->cfp); -} - -/* --------------------------------------------------------------------------------------------- - LISTNH --------------------------------------------------------------------------------------------- -*/ -LineType * -bwb_LISTNH (LineType * l) -{ - /* - SYNTAX: LISTNH - SYNTAX: LISTNH line [,...] - SYNTAX: LISTNH line - line - */ - - assert (l != NULL); - - return bwb_xlist (l, My->SYSOUT->cfp); -} - -/* --------------------------------------------------------------------------------------------- - LLIST --------------------------------------------------------------------------------------------- -*/ - -LineType * -bwb_LLIST (LineType * l) -{ - /* - SYNTAX: LLIST - SYNTAX: LLIST line [,...] - SYNTAX: LLIST line - line - */ - - assert (l != NULL); - - return bwb_xlist (l, My->SYSPRN->cfp); -} - - - -/* -============================================================================================ - DELETE and so on -============================================================================================ -*/ - -static LineType * -bwb_delete (LineType * l) -{ - - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - assert( My->StartMarker != NULL ); - assert( My->EndMarker != NULL ); - - if (line_is_eol (l)) - { - /* DELETE */ - WARN_SYNTAX_ERROR; - return (l); - } - else if (My->CurrentVersion->OptionVersionValue & (C77)) - { - /* - SYNTAX: DELETE filenum [,...] - */ - do - { - int FileNumber; - - FileNumber = 0; - if (line_read_integer_expression (l, &FileNumber) == FALSE) - { - WARN_BAD_FILE_NUMBER; - return (l); - } - if (FileNumber <= 0) - { - WARN_BAD_FILE_NUMBER; - return (l); - } - - My->CurrentFile = find_file_by_number (FileNumber); - if (My->CurrentFile == NULL) - { - WARN_BAD_FILE_NUMBER; - return (l); - } - if (My->CurrentFile->DevMode == DEVMODE_CLOSED) - { - WARN_BAD_FILE_NUMBER; - return (l); - } - if (My->CurrentFile->cfp != NULL) - { - bwb_fclose (My->CurrentFile->cfp); - My->CurrentFile->cfp = NULL; - } - if (My->CurrentFile->buffer != NULL) - { - free (My->CurrentFile->buffer); - My->CurrentFile->buffer = NULL; - } - My->CurrentFile->width = 0; - My->CurrentFile->col = 1; - My->CurrentFile->row = 1; - My->CurrentFile->delimit = ','; - My->CurrentFile->DevMode = DEVMODE_CLOSED; - if (My->CurrentFile->FileName == NULL) - { - WARN_BAD_FILE_NAME; - return (l); - } - remove (My->CurrentFile->FileName); - free (My->CurrentFile->FileName); - My->CurrentFile->FileName = NULL; - } - while (line_skip_seperator (l)); - /* OK */ - return (l); - } - else - { - /* - SYNTAX: DELETE line [,...] - SYNTAX: DELETE line - line - */ - - do - { - int head; - int tail; - - if (line_read_line_sequence (l, &head, &tail)) - { - /* DELETE 's' - 'e' */ - LineType *x; - LineType *previous; - if (head < MINLIN || head > MAXLIN) - { - WARN_UNDEFINED_LINE; - return (l); - } - if (tail < MINLIN || tail > MAXLIN) - { - WARN_UNDEFINED_LINE; - return (l); - } - if (head > tail) - { - WARN_UNDEFINED_LINE; - return (l); - } - /* valid range */ - - /* avoid deleting ourself */ - - if (l->LineFlags & (LINE_USER)) - { - /* console line (immediate mode) */ - } - else if (head <= l->number && l->number <= tail) - { - /* 100 DELETE 100 */ - WARN_CANT_CONTINUE; - return (l); - } - /* now go through and list appropriate lines */ - previous = My->StartMarker; - for (x = My->StartMarker->next; x != My->EndMarker;) - { - LineType *next; - - next = x->next; - if (x->number < head) - { - previous = x; - } - else if (head <= x->number && x->number <= tail) - { - if (x == l) - { - /* 100 DELETE 100 */ - WARN_CANT_CONTINUE; - return (l); - } - bwb_freeline (x); - previous->next = next; - } - x = next; - } - } - else - { - WARN_SYNTAX_ERROR; - return (l); - } - } - while (line_skip_seperator (l)); - /* - ** - ** FORCE SCAN - ** - */ - if (bwb_scan () == FALSE) - { - WARN_CANT_CONTINUE; - return (l); - } - } - return (l); -} - -/* --------------------------------------------------------------------------------------------- - DELETE --------------------------------------------------------------------------------------------- -*/ -LineType * -bwb_DELETE (LineType * l) -{ - - assert (l != NULL); - - return bwb_delete (l); -} - -/* --------------------------------------------------------------------------------------------- - PDEL --------------------------------------------------------------------------------------------- -*/ -LineType * -bwb_PDEL (LineType * l) -{ - - assert (l != NULL); - - return bwb_delete (l); -} - -#if FALSE /* keep the source to DONUM and DOUNNUM */ - -/* --------------------------------------------------------------------------------------------- - DONUM --------------------------------------------------------------------------------------------- -*/ - -LineType * -bwb_donum (LineType * l) -{ - /* - SYNTAX: DONUM - */ - LineType *current; - int lnumber; - - assert (l != NULL); - assert( My != NULL ); - assert( My->StartMarker != NULL ); - assert( My->EndMarker != NULL ); - - lnumber = 10; - for (current = My->StartMarker->next; current != My->EndMarker; - current = current->next) - { - current->number = lnumber; - - lnumber += 10; - if (lnumber > MAXLIN) - { - return (l); - } - } - - return (l); -} - -/* --------------------------------------------------------------------------------------------- - DOUNUM --------------------------------------------------------------------------------------------- -*/ - -LineType * -bwb_dounnum (LineType * l) -{ - /* - SYNTAX: DOUNNUM - */ - LineType *current; - - assert (l != NULL); - assert( My != NULL ); - assert( My->StartMarker != NULL ); - assert( My->EndMarker != NULL ); - - for (current = My->StartMarker->next; current != My->EndMarker; - current = current->next) - { - current->number = 0; - } - - return (l); -} - -#endif /* FALSE */ - - - -/* --------------------------------------------------------------------------------------------- - FILES --------------------------------------------------------------------------------------------- -*/ -LineType * -bwb_FILES (LineType * l) -{ - /* - SYNTAX: FILES A$ [, ...] - */ - /* open a list of files in READ mode */ - - assert (l != NULL); - assert( My != NULL ); - - do - { - int FileNumber; - - FileNumber = My->LastFileNumber; - FileNumber++; - if (FileNumber < 0) - { - WARN_BAD_FILE_NUMBER; - return (l); - } - if (FileNumber == 0) - { - WARN_BAD_FILE_NUMBER; - return (l); - } - My->CurrentFile = find_file_by_number (FileNumber); - if (My->CurrentFile == NULL) - { - My->CurrentFile = file_new (); - My->CurrentFile->FileNumber = FileNumber; - } - { - char *Value; - - Value = NULL; - if (line_read_string_expression (l, &Value) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (Value == NULL) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (My->CurrentFile->FileName != NULL) - { - free (My->CurrentFile->FileName); - My->CurrentFile->FileName = NULL; - } - My->CurrentFile->FileName = Value; - Value = NULL; - } - if (My->CurrentFile->DevMode != DEVMODE_CLOSED) - { - My->CurrentFile->DevMode = DEVMODE_CLOSED; - } - if (My->CurrentFile->cfp != NULL) - { - bwb_fclose (My->CurrentFile->cfp); - My->CurrentFile->cfp = NULL; - } - if (My->CurrentFile->buffer != NULL) - { - free (My->CurrentFile->buffer); - My->CurrentFile->buffer = NULL; - } - My->CurrentFile->width = 0; - My->CurrentFile->col = 1; - My->CurrentFile->row = 1; - My->CurrentFile->delimit = ','; - if (is_empty_string (My->CurrentFile->FileName)) - { - WARN_BAD_FILE_NAME; - return (l); - } - if (bwb_strcmp (My->CurrentFile->FileName, "*") != 0) - { - if ((My->CurrentFile->cfp = - fopen (My->CurrentFile->FileName, "r")) == NULL) - { - WARN_BAD_FILE_NAME; - return (l); - } - My->CurrentFile->DevMode = DEVMODE_INPUT; - } - My->LastFileNumber = FileNumber; - /* OK */ - } - while (line_skip_seperator (l)); - return (l); -} - -/* --------------------------------------------------------------------------------------------- - FILE --------------------------------------------------------------------------------------------- -*/ -LineType * -bwb_FILE (LineType * l) -{ - - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - if (My->CurrentVersion->OptionVersionValue & (C77)) - { - /* - CBASIC-II: - FILE file_name$ ' filename$ must be a simple string scalar (no arrays) - FILE file_name$ ( record_length% ) ' filename$ must be a simple string scalar (no arrays) - -- if the file exists, - then it is used, - else it is created. - -- Does not trigger IF END # - */ - do - { - int FileNumber; - VariableType *v; - char varname[NameLengthMax + 1]; - - if (line_read_varname (l, varname) == FALSE) - { - WARN_BAD_FILE_NAME; - return (l); - } - if (is_empty_string (varname)) - { - WARN_BAD_FILE_NAME; - return (l); - } - v = find_variable_by_type (varname, 0, StringTypeCode); - if (v == NULL) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - if (VAR_IS_STRING (v)) - { - /* OK */ - } - else - { - WARN_TYPE_MISMATCH; - return (l); - } - - FileNumber = My->LastFileNumber; - FileNumber++; - if (FileNumber < 0) - { - WARN_BAD_FILE_NUMBER; - return (l); - } - if (FileNumber == 0) - { - WARN_BAD_FILE_NUMBER; - return (l); - } - My->CurrentFile = find_file_by_number (FileNumber); - if (My->CurrentFile == NULL) - { - My->CurrentFile = file_new (); - My->CurrentFile->FileNumber = FileNumber; - } - if (My->CurrentFile->DevMode != DEVMODE_CLOSED) - { - My->CurrentFile->DevMode = DEVMODE_CLOSED; - } - if (My->CurrentFile->cfp != NULL) - { - bwb_fclose (My->CurrentFile->cfp); - My->CurrentFile->cfp = NULL; - } - if (My->CurrentFile->buffer != NULL) - { - free (My->CurrentFile->buffer); - My->CurrentFile->buffer = NULL; - } - My->CurrentFile->width = 0; - My->CurrentFile->col = 1; - My->CurrentFile->row = 1; - My->CurrentFile->delimit = ','; - /* OK */ - if (line_skip_LparenChar (l)) - { - /* RANDOM file */ - int RecLen; - - if (line_read_integer_expression (l, &RecLen) == FALSE) - { - WARN_FIELD_OVERFLOW; - return (l); - } - if (RecLen <= 0) - { - WARN_FIELD_OVERFLOW; - return (l); - } - if (line_skip_RparenChar (l) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - if ((My->CurrentFile->buffer = - (char *) calloc (RecLen + 1 /* NulChar */ , - sizeof (char))) == NULL) - { - WARN_OUT_OF_MEMORY; - return (l); - } - My->CurrentFile->width = RecLen; - } - - /* if( TRUE ) */ - { - VariantType variant; - CLEAR_VARIANT (&variant); - - if (var_get (v, &variant) == FALSE) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - if (variant.VariantTypeCode == StringTypeCode) - { - if (My->CurrentFile->FileName != NULL) - { - free (My->CurrentFile->FileName); - My->CurrentFile->FileName = NULL; - } - My->CurrentFile->FileName = variant.Buffer; - variant.Buffer = NULL; - } - else - { - WARN_TYPE_MISMATCH; - return (l); - } - } - if (is_empty_string (My->CurrentFile->FileName)) - { - WARN_BAD_FILE_NAME; - return (l); - } - My->CurrentFile->cfp = fopen (My->CurrentFile->FileName, "r+"); - if (My->CurrentFile->cfp == NULL) - { - My->CurrentFile->cfp = fopen (My->CurrentFile->FileName, "w"); - if (My->CurrentFile->cfp != NULL) - { - bwb_fclose (My->CurrentFile->cfp); - My->CurrentFile->cfp = fopen (My->CurrentFile->FileName, "r+"); - } - } - if (My->CurrentFile->cfp == NULL) - { - WARN_BAD_FILE_NAME; - return (l); - } - if (My->CurrentFile->width > 0) - { - /* RANDOM file */ - My->CurrentFile->DevMode = DEVMODE_RANDOM; - } - else - { - /* SERIAL file */ - My->CurrentFile->DevMode = DEVMODE_INPUT | DEVMODE_OUTPUT; - } - /* OK */ - My->LastFileNumber = FileNumber; - } - while (line_skip_seperator (l)); - /* OK */ - return (l); - } - if (line_skip_FilenumChar (l)) - { - /* - SYNTAX: FILE # X, A$ - */ - int FileNumber; - - if (line_read_integer_expression (l, &FileNumber) == FALSE) - { - WARN_BAD_FILE_NUMBER; - return (l); - } - if (line_skip_seperator (l)) - { - /* OK */ - } - else - { - WARN_SYNTAX_ERROR; - return (l); - } - if (FileNumber < 0) - { - /* "FILE # -1" is an ERROR */ - WARN_BAD_FILE_NUMBER; - return (l); - } - if (FileNumber == 0) - { - /* "FILE # 0" is an ERROR */ - WARN_BAD_FILE_NUMBER; - return (l); - } - My->CurrentFile = find_file_by_number (FileNumber); - if (My->CurrentFile == NULL) - { - My->CurrentFile = file_new (); - My->CurrentFile->FileNumber = FileNumber; - } - { - char *Value; - - Value = NULL; - if (line_read_string_expression (l, &Value) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (Value == NULL) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (My->CurrentFile->FileName != NULL) - { - free (My->CurrentFile->FileName); - My->CurrentFile->FileName = NULL; - } - My->CurrentFile->FileName = Value; - Value = NULL; - } - if (My->CurrentFile->DevMode != DEVMODE_CLOSED) - { - My->CurrentFile->DevMode = DEVMODE_CLOSED; - } - if (My->CurrentFile->cfp != NULL) - { - bwb_fclose (My->CurrentFile->cfp); - My->CurrentFile->cfp = NULL; - } - if (My->CurrentFile->buffer != NULL) - { - free (My->CurrentFile->buffer); - My->CurrentFile->buffer = NULL; - } - My->CurrentFile->width = 0; - My->CurrentFile->col = 1; - My->CurrentFile->row = 1; - My->CurrentFile->delimit = ','; - if (is_empty_string (My->CurrentFile->FileName)) - { - WARN_BAD_FILE_NAME; - return (l); - } - if (bwb_strcmp (My->CurrentFile->FileName, "*") != 0) - { - if ((My->CurrentFile->cfp = - fopen (My->CurrentFile->FileName, "r")) == NULL) - { - WARN_BAD_FILE_NAME; - return (l); - } - My->CurrentFile->DevMode = DEVMODE_INPUT; - } - /* OK */ - return (l); - } - WARN_SYNTAX_ERROR; - return (l); -} - -/* --------------------------------------------------------------------------------------------- - DELIMIT --------------------------------------------------------------------------------------------- -*/ -LineType * -bwb_DELIMIT (LineType * l) -{ - /* - SYNTAX: DELIMIT # X, A$ - */ - - assert (l != NULL); - assert( My != NULL ); - assert( My->SYSIN != NULL ); - - if (line_skip_FilenumChar (l)) - { - /* DELIMIT # */ - int FileNumber; - char delimit; - - My->CurrentFile = My->SYSIN; - - if (line_read_integer_expression (l, &FileNumber) == FALSE) - { - WARN_BAD_FILE_NUMBER; - return (l); - } - if (line_skip_seperator (l)) - { - /* OK */ - } - else - { - WARN_SYNTAX_ERROR; - return (l); - } - { - char *Value; - - Value = NULL; - if (line_read_string_expression (l, &Value) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (Value == NULL) - { - WARN_SYNTAX_ERROR; - return (l); - } - delimit = Value[0]; - free (Value); - Value = NULL; - if (bwb_ispunct (delimit)) - { - /* OK */ - } - else - { - WARN_ILLEGAL_FUNCTION_CALL; - return (l); - } - } - if (FileNumber < 0) - { - /* "DELIMIT # -1" is SYSPRN */ - My->SYSPRN->delimit = delimit; - return (l); - } - if (FileNumber == 0) - { - /* "DELIMIT # 0" is SYSOUT */ - My->SYSOUT->delimit = delimit; - return (l); - } - /* normal file */ - My->CurrentFile = find_file_by_number (FileNumber); - if (My->CurrentFile == NULL) - { - WARN_BAD_FILE_NUMBER; - return (l); - } - My->CurrentFile->delimit = delimit; - /* OK */ - return (l); - } - WARN_SYNTAX_ERROR; - return (l); -} - -/* --------------------------------------------------------------------------------------------- - MARGIN --------------------------------------------------------------------------------------------- -*/ -LineType * -bwb_MARGIN (LineType * l) -{ - /* - SYNTAX: MARGIN # X, Y - */ - /* set width for OUTPUT */ - int FileNumber; - int Value; - - assert (l != NULL); - assert( My != NULL ); - assert( My->SYSIN != NULL ); - - if (line_skip_FilenumChar (l)) - { - /* MARGIN # */ - My->CurrentFile = My->SYSIN; - - if (line_read_integer_expression (l, &FileNumber) == FALSE) - { - WARN_BAD_FILE_NUMBER; - return (l); - } - if (line_skip_seperator (l)) - { - /* OK */ - } - else - { - WARN_SYNTAX_ERROR; - return (l); - } - if (line_read_integer_expression (l, &Value) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (Value < 0) - { - WARN_ILLEGAL_FUNCTION_CALL; - return (l); - } - if (FileNumber < 0) - { - /* "MARGIN # -1" is SYSPRN */ - My->SYSPRN->width = Value; - return (l); - } - if (FileNumber == 0) - { - /* "MARGIN # 0" is SYSOUT */ - My->SYSOUT->width = Value; - return (l); - } - /* normal file */ - My->CurrentFile = find_file_by_number (FileNumber); - if (My->CurrentFile == NULL) - { - WARN_BAD_FILE_NUMBER; - return (l); - } - if ((My->CurrentFile->DevMode & DEVMODE_WRITE) == 0) - { - WARN_BAD_FILE_NUMBER; - return (l); - } - My->CurrentFile->width = Value; - /* OK */ - return (l); - } - WARN_SYNTAX_ERROR; - return (l); -} - -/* --------------------------------------------------------------------------------------------- - USE --------------------------------------------------------------------------------------------- -*/ - -LineType * -bwb_USE (LineType * l) -{ - /* - SYNTAX: USE parameter$ ' CALL/360, System/360, System/370 - */ - VariableType *v; - - assert (l != NULL); - assert( My != NULL ); - - if ((v = line_read_scalar (l)) == NULL) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (v->VariableTypeCode != StringTypeCode) - { - WARN_SYNTAX_ERROR; - return (l); - } - /* OK */ - if (My->UseParameterString) - { - VariantType variant; - CLEAR_VARIANT (&variant); - - variant.VariantTypeCode = StringTypeCode; - variant.Buffer = My->UseParameterString; - variant.Length = bwb_strlen (My->UseParameterString); - var_set (v, &variant); - } - return (l); -} - -/* --------------------------------------------------------------------------------------------- - CHAIN --------------------------------------------------------------------------------------------- -*/ - -LineType * -bwb_CHAIN (LineType * l) -{ - /* - SYNTAX: CHAIN file-name$ [, linenumber] ' most dialects - SYNTAX: CHAIN file-name$ [, parameter$] ' CALL/360, System/360, System/370 - */ - /* originally based upon bwb_load() */ - int LineNumber; - LineType *x; - - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - assert( My->StartMarker != NULL ); - assert( My->EndMarker != NULL ); - - /* Get an argument for filename */ - if (line_is_eol (l)) - { - WARN_BAD_FILE_NAME; - return (l); - } - else - { - char *Value; - - Value = NULL; - if (line_read_string_expression (l, &Value) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (is_empty_string (Value)) - { - WARN_BAD_FILE_NAME; - return (l); - } - if (My->ProgramFilename != NULL) - { - free (My->ProgramFilename); - My->ProgramFilename = NULL; - } - My->ProgramFilename = Value; - } - /* optional linenumber */ - LineNumber = 0; - if (line_skip_seperator (l)) - { - if (My->CurrentVersion->OptionVersionValue & (S70 | I70 | I73)) - { - /* CHAIN filename$, parameter$ */ - { - char *Value; - - Value = NULL; - if (line_read_string_expression (l, &Value) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (Value == NULL) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (My->UseParameterString) - { - free (My->UseParameterString); - My->UseParameterString = NULL; - } - My->UseParameterString = Value; - } - } - else - { - /* CHAIN filename$, linenumber */ - if (line_read_integer_expression (l, &LineNumber) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (LineNumber < MINLIN || LineNumber > MAXLIN) - { - WARN_UNDEFINED_LINE; - return (l); - } - } - } - - /* deallocate all variables except common ones */ - var_delcvars (); - - /* remove old program from memory */ - bwb_xnew (My->StartMarker); - - /* load new program in memory */ - if (bwb_fload (NULL) == FALSE) - { - WARN_BAD_FILE_NAME; - return (l); - } - /* FIXME */ - x = My->StartMarker; - if (MINLIN <= LineNumber && LineNumber <= MAXLIN) - { - /* search for a matching line number */ - while (x->number != LineNumber && x != My->EndMarker) - { - x = x->next; - } - if (x == My->EndMarker) - { - /* NOT FOUND */ - x = My->StartMarker; - } - } - x->position = 0; - /* - ** - ** FORCE SCAN - ** - */ - if (bwb_scan () == FALSE) - { - WARN_CANT_CONTINUE; - return (l); - } - /* reset all stack counters */ - bwb_clrexec (); - if (bwb_incexec ()) - { - /* OK */ - My->StackHead->line = x; - My->StackHead->ExecCode = EXEC_NORM; - } - else - { - /* ERROR */ - WARN_OUT_OF_MEMORY; - return My->EndMarker; - } - - /* run the program */ - - /* CHAIN */ - WARN_CLEAR; /* bwb_CHAIN */ - My->ContinueLine = NULL; - SetOnError (0); - return x; -} - -/* --------------------------------------------------------------------------------------------- - APPEND --------------------------------------------------------------------------------------------- -*/ -LineType * -bwb_APPEND (LineType * l) -{ - /* - SYNTAX: APPEND # filenumber ' Dartmouth, Mark-I, Mark-II, GCOS - SYNTAX: APPEND [filename$] ' all others - */ - - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - if (My->CurrentVersion->OptionVersionValue & (D64 | G65 | G67 | G74)) - { - if (line_skip_FilenumChar (l)) - { - /* APPEND # filenumber */ - int FileNumber; - - if (line_read_integer_expression (l, &FileNumber) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (FileNumber < 0) - { - /* "APPEND # -1" is silently ignored */ - return (l); - } - if (FileNumber == 0) - { - /* "APPEND # 0" is silently ignored */ - return (l); - } - My->CurrentFile = find_file_by_number (FileNumber); - if (My->CurrentFile == NULL) - { - WARN_BAD_FILE_NUMBER; - return (l); - } - /* normal file */ - fseek (My->CurrentFile->cfp, 0, SEEK_END); - My->CurrentFile->DevMode = DEVMODE_APPEND; - /* OK */ - return (l); - } - } - /* APPEND filename$ */ - return bwb_load (l, "APPEND FILE NAME:", FALSE); -} - - - -/* --------------------------------------------------------------------------------------------- - ON ERROR and so on --------------------------------------------------------------------------------------------- -*/ - -extern void -SetOnError (int LineNumber) -{ - /* scan the stack looking for a FUNCTION/SUB */ - StackType *StackItem; - assert( My != NULL ); - - - if (My->StackHead == NULL) - { - return; - } - - for (StackItem = My->StackHead; StackItem->next != NULL; - StackItem = StackItem->next) - { - LineType *current; - - current = StackItem->LoopTopLine; - if (current != NULL) - { - switch (current->cmdnum) - { - case C_FUNCTION: - case C_SUB: - /* FOUND */ - /* we are in a FUNCTION/SUB, so this is LOCAL */ - StackItem->OnErrorGoto = LineNumber; - return; - /* break; */ - } - } - } - /* StackItem->next == NULL */ - /* NOT FOUND */ - /* we are NOT in a FUNCTION/SUB */ - assert (StackItem != NULL); - StackItem->OnErrorGoto = LineNumber; -} - - -extern int -GetOnError (void) -{ - /* scan the stack looking for an active "ON ERROR GOTO linenumber" */ - StackType *StackItem; - assert( My != NULL ); - - - for (StackItem = My->StackHead; StackItem != NULL; - StackItem = StackItem->next) - { - if (StackItem->OnErrorGoto != 0) - { - /* FOUND */ - return StackItem->OnErrorGoto; - } - } - /* NOT FOUND */ - return 0; -} - -/* --------------------------------------------------------------------------------------------- - ON ERROR --------------------------------------------------------------------------------------------- -*/ -LineType * -bwb_ON_ERROR (LineType * l) -{ - - assert (l != NULL); - WARN_SYNTAX_ERROR; - return (l); -} - -/* --------------------------------------------------------------------------------------------- - ON ERROR GOTO --------------------------------------------------------------------------------------------- -*/ -LineType * -bwb_ON_ERROR_GOTO (LineType * l) -{ - /* ON ERROR GOTO line */ - int LineNumber; - - assert (l != NULL); - - WARN_CLEAR; /* bwb_ON_ERROR_GOTO */ - - /* get the line number */ - LineNumber = 0; - if (line_is_eol (l)) - { - /* ON ERROR GOTO */ - SetOnError (0); - return (l); - } - if (line_read_integer_expression (l, &LineNumber) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - /* ON ERORR GOTO linenumber */ - if (LineNumber == 0) - { - /* ON ERROR GOTO 0 */ - SetOnError (0); - return (l); - } - if (LineNumber < MINLIN || LineNumber > MAXLIN) - { - /* ERROR */ - WARN_UNDEFINED_LINE; - return (l); - } - /* OK */ - SetOnError (LineNumber); - return (l); -} - -/* --------------------------------------------------------------------------------------------- - ON ERROR GOSUB --------------------------------------------------------------------------------------------- -*/ -LineType * -bwb_ON_ERROR_GOSUB (LineType * l) -{ - /* ON ERROR GOSUB line */ - - assert (l != NULL); - return bwb_ON_ERROR_GOTO (l); -} - -/* --------------------------------------------------------------------------------------------- - ON ERROR RESUME --------------------------------------------------------------------------------------------- -*/ -LineType * -bwb_ON_ERROR_RESUME (LineType * l) -{ - - assert (l != NULL); - WARN_SYNTAX_ERROR; - return (l); -} - -/* --------------------------------------------------------------------------------------------- - ON ERROR RESUME NEXT --------------------------------------------------------------------------------------------- -*/ -LineType * -bwb_ON_ERROR_RESUME_NEXT (LineType * l) -{ - - assert (l != NULL); - WARN_CLEAR; /* bwb_ON_ERROR_RESUME_NEXT */ - SetOnError (-1); - return (l); -} - -/* --------------------------------------------------------------------------------------------- - ON ERROR RETURN --------------------------------------------------------------------------------------------- -*/ -LineType * -bwb_ON_ERROR_RETURN (LineType * l) -{ - - assert (l != NULL); - WARN_SYNTAX_ERROR; - return (l); -} - -/* --------------------------------------------------------------------------------------------- - ON ERROR RETURN NEXT --------------------------------------------------------------------------------------------- -*/ -LineType * -bwb_ON_ERROR_RETURN_NEXT (LineType * l) -{ - - assert (l != NULL); - return bwb_ON_ERROR_RESUME_NEXT (l); -} - -/* --------------------------------------------------------------------------------------------- - ON TIMER --------------------------------------------------------------------------------------------- -*/ -LineType * -bwb_ON_TIMER (LineType * l) -{ - /* ON TIMER(...) GOSUB ... */ - DoubleType v; - DoubleType minv; - int LineNumber; - - assert (l != NULL); - assert( My != NULL ); - - My->IsTimerOn = FALSE; /* bwb_ON_TIMER */ - My->OnTimerLineNumber = 0; - My->OnTimerCount = 0; - - - /* get the SECOMDS parameter */ - if (line_read_numeric_expression (l, &v) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - - minv = 1; - assert (CLOCKS_PER_SEC > 0); - minv /= CLOCKS_PER_SEC; - if (v < minv) - { - /* ERROR */ - WARN_ILLEGAL_FUNCTION_CALL; - return (l); - } - - /* get the GOSUB keyword */ - if (line_skip_word (l, "GOSUB") == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - /* ON TIMER(X) GOSUB line */ - if (line_read_integer_expression (l, &LineNumber) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (LineNumber < MINLIN || LineNumber > MAXLIN) - { - /* ERROR */ - WARN_UNDEFINED_LINE; - return (l); - } - /* OK */ - My->OnTimerLineNumber = LineNumber; - My->OnTimerCount = v; - return (l); -} - - -/* --------------------------------------------------------------------------------------------- - TIMER --------------------------------------------------------------------------------------------- -*/ -LineType * -bwb_TIMER (LineType * l) -{ - - assert (l != NULL); - assert( My != NULL ); - - My->IsTimerOn = FALSE; /* bwb_TIMER */ - WARN_SYNTAX_ERROR; - return (l); -} - -/* --------------------------------------------------------------------------------------------- - TIMER OFF --------------------------------------------------------------------------------------------- -*/ -LineType * -bwb_TIMER_OFF (LineType * l) -{ - - assert (l != NULL); - assert( My != NULL ); - - /* TIMER OFF */ - My->IsTimerOn = FALSE; /* bwb_TIMER_OFF */ - My->OnTimerLineNumber = 0; - My->OnTimerCount = 0; - return (l); -} - -/* --------------------------------------------------------------------------------------------- - TIMER ON --------------------------------------------------------------------------------------------- -*/ -LineType * -bwb_TIMER_ON (LineType * l) -{ - - assert (l != NULL); - assert( My != NULL ); - - My->IsTimerOn = FALSE; /* bwb_TIMER_ON */ - /* TIMER ON */ - if (My->OnTimerCount > 0 && My->OnTimerLineNumber > 0) - { - My->OnTimerExpires = bwx_TIMER (My->OnTimerCount); - My->IsTimerOn = TRUE; /* bwb_TIMER_ON */ - } - return (l); -} - -/* --------------------------------------------------------------------------------------------- - TIMER STOP --------------------------------------------------------------------------------------------- -*/ -LineType * -bwb_TIMER_STOP (LineType * l) -{ - - assert (l != NULL); - assert( My != NULL ); - - My->IsTimerOn = FALSE; /* bwb_TIMER_STOP */ - - return (l); -} - -/* --------------------------------------------------------------------------------------------- - RESUME --------------------------------------------------------------------------------------------- -*/ -LineType * -bwb_RESUME (LineType * l) -{ - int LineNumber; - LineType *x; - - assert (l != NULL); - assert( My != NULL ); - - LineNumber = 0; - x = My->ERL; /* bwb_RESUME */ - WARN_CLEAR; /* bwb_RESUME */ - - if (l->LineFlags & (LINE_USER)) - { - WARN_ILLEGAL_DIRECT; - return (l); - } - - if (x == NULL) - { - WARN_RESUME_WITHOUT_ERROR; - return (l); - } - /* Get optional argument for RESUME */ - if (line_is_eol (l)) - { - /* RESUME */ - /* - Execution resumes at the statement which caused the error - For structured commands, this is the top line of the structure. - */ - x->position = 0; - return x; - } - if (line_skip_word (l, "NEXT")) - { - /* RESUME NEXT */ - /* - Execution resumes at the statement immediately following the one which caused the error. - For structured commands, this is the bottom line of the structure. - */ - switch (x->cmdnum) - { - case C_IF8THEN: - /* skip to END_IF */ - assert (x->OtherLine != NULL); - for (x = x->OtherLine; x->cmdnum != C_END_IF; x = x->OtherLine); - break; - case C_SELECT_CASE: - /* skip to END_SELECT */ - assert (x->OtherLine != NULL); - for (x = x->OtherLine; x->cmdnum != C_END_SELECT; x = x->OtherLine); - break; - default: - x = x->next; - } - x->position = 0; - return x; - } - /* RESUME ### */ - if (line_read_integer_expression (l, &LineNumber) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (LineNumber == 0) - { - /* SPECIAL CASE */ - /* RESUME 0 */ - /* Execution resumes at the statement which caused the error */ - x->position = 0; - return x; - } - /* VERIFY LINE EXISTS */ - x = find_line_number (LineNumber); /* RESUME 100 */ - if (x != NULL) - { - /* FOUND */ - x->position = 0; - return x; - } - /* NOT FOUND */ - WARN_UNDEFINED_LINE; - return (l); -} - -/* --------------------------------------------------------------------------------------------- - CMDS --------------------------------------------------------------------------------------------- -*/ -LineType * -bwb_CMDS (LineType * l) -{ - int n; - int t; - - assert (l != NULL); - assert( My != NULL ); - assert( My->SYSOUT != NULL ); - assert( My->SYSOUT->cfp != NULL ); - - My->CurrentFile = My->SYSOUT; - fprintf (My->SYSOUT->cfp, "BWBASIC COMMANDS AVAILABLE:\n"); - - /* run through the command table and print comand names */ - - t = 0; - for (n = 0; n < NUM_COMMANDS; n++) - { - fprintf (My->SYSOUT->cfp, "%s", IntrinsicCommandTable[n].name); - if (t < 4) - { - fprintf (My->SYSOUT->cfp, "\t"); - t++; - } - else - { - fprintf (My->SYSOUT->cfp, "\n"); - t = 0; - } - } - if (t > 0) - { - fprintf (My->SYSOUT->cfp, "\n"); - } - ResetConsoleColumn (); - return (l); -} - -static void -FixUp (char *Name) -{ - char *C; - - assert (Name != NULL); - - C = Name; - while (*C) - { - if (bwb_isalnum (*C)) - { - /* OK */ - } - else - { - /* FIX */ - switch (*C) - { - case '!': - *C = '1'; - break; - case '@': - *C = '2'; - break; - case '#': - *C = '3'; - break; - case '$': - *C = '4'; - break; - case '%': - *C = '5'; - break; - case '^': - *C = '6'; - break; - case '&': - *C = '7'; - break; - case '*': - *C = '8'; - break; - case '(': - *C = '9'; - break; - case ')': - *C = '0'; - break; - default: - *C = '_'; - } - } - C++; - } -} - - -static void -CommandUniqueID (int i, char *UniqueID) -{ - - assert (UniqueID != NULL); - - bwb_strcpy (UniqueID, "C_"); - bwb_strcat (UniqueID, IntrinsicCommandTable[i].name); - FixUp (UniqueID); -} - -static void -CommandVector (int i, char *Vector) -{ - - assert (Vector != NULL); - - bwb_strcpy (Vector, "bwb_"); - bwb_strcat (Vector, IntrinsicCommandTable[i].name); - FixUp (Vector); -} - -static void -CommandOptionVersion (int n, char *OutputLine) -{ - int i; - int j; - - assert (OutputLine != NULL); - - bwb_strcpy (OutputLine, ""); - j = 0; - for (i = 0; i < NUM_VERSIONS; i++) - { - if (IntrinsicCommandTable[n].OptionVersionBitmask & bwb_vertable[i]. - OptionVersionValue) - { - if (j > 0) - { - bwb_strcat (OutputLine, " | "); - } - bwb_strcat (OutputLine, bwb_vertable[i].ID); - j++; - } - } -} - - -void -SortAllCommands (void) -{ - /* sort by name */ - int i; - assert( My != NULL ); - - - for (i = 0; i < NUM_COMMANDS - 1; i++) - { - int j; - int k; - k = i; - for (j = i + 1; j < NUM_COMMANDS; j++) - { - if (bwb_stricmp - (IntrinsicCommandTable[j].name, IntrinsicCommandTable[k].name) < 0) - { - k = j; - } - } - if (k > i) - { - CommandType t; - bwb_memcpy (&t, &(IntrinsicCommandTable[i]), sizeof (CommandType)); - bwb_memcpy (&(IntrinsicCommandTable[i]), &(IntrinsicCommandTable[k]), - sizeof (CommandType)); - bwb_memcpy (&(IntrinsicCommandTable[k]), &t, sizeof (CommandType)); - } - } -#if THE_PRICE_IS_RIGHT - for (i = 0; i < 26; i++) - { - My->CommandStart[i] = -1; - } - for (i = 0; i < NUM_COMMANDS; i++) - { - int j; - j = VarTypeIndex (IntrinsicCommandTable[i].name[0]); - if (j < 0) - { - /* non-alpha */ - } - else if (My->CommandStart[j] < 0) - { - /* this is the first command starting with this letter */ - My->CommandStart[j] = i; - } - } -#endif /* THE_PRICE_IS_RIGHT */ -} - -void -SortAllFunctions (void) -{ - /* sort by name then number of parameters */ - int i; - assert( My != NULL ); - - - for (i = 0; i < NUM_FUNCTIONS - 1; i++) - { - int j; - int k; - k = i; - for (j = i + 1; j < NUM_FUNCTIONS; j++) - { - int n; - n = - bwb_stricmp (IntrinsicFunctionTable[j].Name, - IntrinsicFunctionTable[k].Name); - if (n < 0) - { - k = j; - } - else if (n == 0) - { - if (IntrinsicFunctionTable[j].ParameterCount < - IntrinsicFunctionTable[k].ParameterCount) - { - k = j; - } - } - } - if (k > i) - { - IntrinsicFunctionType t; - bwb_memcpy (&t, &(IntrinsicFunctionTable[i]), - sizeof (IntrinsicFunctionType)); - bwb_memcpy (&(IntrinsicFunctionTable[i]), &(IntrinsicFunctionTable[k]), - sizeof (IntrinsicFunctionType)); - bwb_memcpy (&(IntrinsicFunctionTable[k]), &t, - sizeof (IntrinsicFunctionType)); - } - } -#if THE_PRICE_IS_RIGHT - for (i = 0; i < 26; i++) - { - My->IntrinsicFunctionStart[i] = -1; - } - for (i = 0; i < NUM_FUNCTIONS; i++) - { - int j; - j = VarTypeIndex (IntrinsicFunctionTable[i].Name[0]); - if (j < 0) - { - /* non-alpha */ - } - else if (My->IntrinsicFunctionStart[j] < 0) - { - /* this is the first command starting with this letter */ - My->IntrinsicFunctionStart[j] = i; - } - } -#endif /* THE_PRICE_IS_RIGHT */ -} - - -void -DumpAllCommandUniqueID (FILE * file) -{ - int i; - int j; - char LastUniqueID[NameLengthMax + 1]; - - assert (file != NULL); - - j = 0; - LastUniqueID[0] = NulChar; - - fprintf (file, "/* COMMANDS */\n"); - - /* run through the command table and print comand #define */ - - for (i = 0; i < NUM_COMMANDS; i++) - { - char UniqueID[NameLengthMax + 1]; - - CommandUniqueID (i, UniqueID); - if (bwb_stricmp (LastUniqueID, UniqueID) != 0) - { - /* not a duplicate */ - bwb_strcpy (LastUniqueID, UniqueID); - j = j + 1; - fprintf (file, "#define %-30s %3d /* %-30s */\n", UniqueID, j, - IntrinsicCommandTable[i].name); - } - } - fprintf (file, "#define NUM_COMMANDS %d\n", j); - fflush (file); -} - -static void -ProcessEscapeChars (const char *Input, char *Output) -{ - int n; - - assert (Input != NULL); - assert (Output != NULL); - - n = 0; - - while (*Input) - { - /* \a \b \f \n \r \t \v \" \\ */ - switch (*Input) - { - case '\a': - *Output = '\\'; - Output++; - *Output = 'a'; - Output++; - break; - case '\b': - *Output = '\\'; - Output++; - *Output = 'b'; - Output++; - break; - case '\f': - *Output = '\\'; - Output++; - *Output = 'f'; - Output++; - break; - case '\n': - *Output = '\\'; - Output++; - *Output = 'n'; - Output++; - break; - case '\r': - *Output = '\\'; - Output++; - *Output = 'r'; - Output++; - break; - case '\t': - *Output = '\\'; - Output++; - *Output = 't'; - Output++; - break; - case '\v': - *Output = '\\'; - Output++; - *Output = 'n'; - Output++; - break; - case '\"': - *Output = '\\'; - Output++; - *Output = '"'; - Output++; - break; - case '\\': - *Output = '\\'; - Output++; - *Output = '\\'; - Output++; - break; - default: - *Output = *Input; - Output++; - break; - } - *Output = NulChar; - n++; - if (n > 60 && *Input == ' ') - { - *Output = '\"'; - Output++; - *Output = '\n'; - Output++; - *Output = ' '; - Output++; - *Output = ' '; - Output++; - *Output = '\"'; - Output++; - *Output = NulChar; - n = 0; - } - Input++; - } -} - -void -DumpAllCommandTableDefinitions (FILE * file) -{ - /* generate bwd_cmd.c */ - - int i; - - assert (file != NULL); - - fprintf (file, "/* COMMAND TABLE */\n\n"); - fprintf (file, "#include \"bwbasic.h\"\n\n"); - fprintf (file, - "CommandType IntrinsicCommandTable[ /* NUM_COMMANDS */ ] =\n"); - fprintf (file, "{\n"); - - /* run through the command table and print comand #define */ - - for (i = 0; i < NUM_COMMANDS; i++) - { - char tbuf[MAINTAINER_BUFFER_LENGTH + 1]; /* DumpAllCommandTableDefinitions */ - - - fprintf (file, "{\n"); - - fprintf (file, " "); - CommandUniqueID (i, tbuf); - fprintf (file, "%s", tbuf); - fprintf (file, ", /* UniqueID */\n"); - - fprintf (file, " "); - fprintf (file, "\""); - ProcessEscapeChars (IntrinsicCommandTable[i].Syntax, tbuf); - fprintf (file, "%s", tbuf); - fprintf (file, "\""); - fprintf (file, ", /* Syntax */\n"); - - fprintf (file, " "); - fprintf (file, "\""); - ProcessEscapeChars (IntrinsicCommandTable[i].Description, tbuf); - fprintf (file, "%s", tbuf); - fprintf (file, "\""); - fprintf (file, ", /* Description */\n"); - - fprintf (file, " "); - fprintf (file, "\""); - fprintf (file, "%s", IntrinsicCommandTable[i].name); - fprintf (file, "\""); - fprintf (file, ", /* Name */\n"); - - fprintf (file, " "); - CommandOptionVersion (i, tbuf); - fprintf (file, "%s", tbuf); - fprintf (file, " /* OptionVersionBitmask */\n"); - - fprintf (file, "},\n"); - } - fprintf (file, "};\n"); - fprintf (file, "\n"); - fprintf (file, - "const size_t NUM_COMMANDS = sizeof( IntrinsicCommandTable ) / sizeof( CommandType );\n"); - fprintf (file, "\n"); - fflush (file); -} - -void -DumpAllCommandSwitchStatement (FILE * file) -{ - int i; - char LastUniqueID[NameLengthMax + 1]; - - assert (file != NULL); - - LastUniqueID[0] = NulChar; - - /* run through the command table and print comand #define */ - fprintf (file, "/* SWITCH */\n"); - fprintf (file, "LineType *bwb_vector( LineType *l )\n"); - fprintf (file, "{\n"); - - fprintf (file, " "); - fprintf (file, "LineType *r;\n"); - - fprintf (file, " "); - fprintf (file, "switch( l->cmdnum )\n"); - - fprintf (file, " "); - fprintf (file, "{\n"); - - for (i = 0; i < NUM_COMMANDS; i++) - { - char tbuf[NameLengthMax + 1]; - - CommandUniqueID (i, tbuf); - if (bwb_stricmp (LastUniqueID, tbuf) != 0) - { - /* not a duplicate */ - bwb_strcpy (LastUniqueID, tbuf); - - fprintf (file, " "); - fprintf (file, "case "); - CommandUniqueID (i, tbuf); - fprintf (file, "%s", tbuf); - fprintf (file, ":\n"); - - fprintf (file, " "); - fprintf (file, " "); - fprintf (file, "r = "); - CommandVector (i, tbuf); - fprintf (file, "%s", tbuf); - fprintf (file, "( l );\n"); - - fprintf (file, " "); - fprintf (file, " "); - fprintf (file, "break;\n"); - } - } - - fprintf (file, " "); - fprintf (file, "default:\n"); - - fprintf (file, " "); - fprintf (file, " "); - fprintf (file, "WARN_INTERNAL_ERROR;\n"); - - fprintf (file, " "); - fprintf (file, " "); - fprintf (file, "r = l;\n"); - - fprintf (file, " "); - fprintf (file, " "); - fprintf (file, "break;\n"); - - - fprintf (file, " "); - fprintf (file, "}\n"); - - fprintf (file, " "); - fprintf (file, "return r;\n"); - - fprintf (file, "}\n"); - - fflush (file); -} - -void -FixDescription (FILE * file, const char *left, const char *right) -{ - char buffer[MAINTAINER_BUFFER_LENGTH + 1]; /* FixDescription */ - int l; /* length of left side */ - int p; /* current position */ - int n; /* position of the last space character, zero means none yet seen */ - int i; /* number of characters since last '\n' */ - - assert (left != NULL); - assert (right != NULL); - - l = bwb_strlen (left); - p = 0; - n = 0; - i = 0; - bwb_strcpy (buffer, right); - - while (buffer[p]) - { - if (buffer[p] == '\n') - { - n = p; - i = 0; - } - if (buffer[p] == ' ') - { - n = p; - } - if (i > 45 && n > 0) - { - buffer[n] = '\n'; - i = p - n; - } - p++; - i++; - } - fputs (left, file); - p = 0; - while (buffer[p]) - { - if (buffer[p] == '\n') - { - fputc (buffer[p], file); - p++; - while (buffer[p] == ' ') - { - p++; - } - for (i = 0; i < l; i++) - { - fputc (' ', file); - } - } - else - { - fputc (buffer[p], file); - p++; - } - } - fputc ('\n', file); - -} - -void -DumpOneCommandSyntax (FILE * file, int IsXref, int n) -{ - - assert (file != NULL); - - if (n < 0 || n >= NUM_COMMANDS) - { - return; - } - /* NAME */ - { - FixDescription (file, " SYNTAX: ", IntrinsicCommandTable[n].Syntax); - } - /* DESCRIPTION */ - { - FixDescription (file, "DESCRIPTION: ", - IntrinsicCommandTable[n].Description); - } - /* COMPATIBILITY */ - if (IsXref) - { - int i; - fprintf (file, " VERSIONS:\n"); - for (i = 0; i < NUM_VERSIONS; i++) - { - char X; - if (IntrinsicCommandTable[n].OptionVersionBitmask & bwb_vertable[i]. - OptionVersionValue) - { - /* SUPPORTED */ - X = 'X'; - } - else - { - /* NOT SUPPORTED */ - X = '_'; - } - fprintf (file, " [%c] %s\n", X, bwb_vertable[i].Name); - } - } - - fflush (file); -} - -void -DumpAllCommandSyntax (FILE * file, int IsXref, - OptionVersionType OptionVersionValue) -{ - /* for the C maintainer */ - int i; - - assert (file != NULL); - - fprintf (file, - "============================================================\n"); - fprintf (file, - " COMMANDS \n"); - fprintf (file, - "============================================================\n"); - fprintf (file, "\n"); - fprintf (file, "\n"); - for (i = 0; i < NUM_COMMANDS; i++) - { - if (IntrinsicCommandTable[i].OptionVersionBitmask & OptionVersionValue) - { - fprintf (file, - "------------------------------------------------------------\n"); - DumpOneCommandSyntax (file, IsXref, i); - } - - } - fprintf (file, - "------------------------------------------------------------\n"); - - - fprintf (file, "\n"); - fprintf (file, "\n"); - fflush (file); -} - - -void -DumpAllCommandHtmlTable (FILE * file) -{ - /* generate bwd_cmd.htm */ - - int i; - int j; - - assert (file != NULL); - - - /* LEGEND */ - fprintf (file, "CMDS\n"); - fprintf (file, "

LEGEND


\n"); - fprintf (file, "\n"); - - fprintf (file, ""); - fprintf (file, ""); - fprintf (file, ""); - fprintf (file, ""); - fprintf (file, "\n"); - - for (j = 0; j < NUM_VERSIONS; j++) - { - fprintf (file, ""); - fprintf (file, ""); - fprintf (file, ""); - fprintf (file, ""); - fprintf (file, "\n"); - } - fprintf (file, "
"); - fprintf (file, ""); - fprintf (file, "ID"); - fprintf (file, ""); - fprintf (file, ""); - fprintf (file, ""); - fprintf (file, "NAME"); - fprintf (file, ""); - fprintf (file, ""); - fprintf (file, ""); - fprintf (file, "DESCRIPTION"); - fprintf (file, ""); - fprintf (file, "
"); - fprintf (file, "%s", bwb_vertable[j].ID); - fprintf (file, ""); - fprintf (file, "%s", bwb_vertable[j].Name); - fprintf (file, ""); - fprintf (file, "%s", bwb_vertable[j].Description); - fprintf (file, "
\n"); - fprintf (file, "
\n"); - - - /* DETAILS */ - fprintf (file, "

DETAILS


\n"); - fprintf (file, "\n"); - - fprintf (file, ""); - fprintf (file, ""); - for (j = 0; j < NUM_VERSIONS; j++) - { - fprintf (file, ""); - } - fprintf (file, "\n"); - - - /* run through the command table and print comand -vs- OPTION VERSION */ - - for (i = 0; i < NUM_COMMANDS; i++) - { - fprintf (file, ""); - fprintf (file, ""); - - for (j = 0; j < NUM_VERSIONS; j++) - { - fprintf (file, ""); - } - fprintf (file, "\n"); - } - fprintf (file, "
"); - fprintf (file, ""); - fprintf (file, "COMMAND"); - fprintf (file, ""); - fprintf (file, ""); - fprintf (file, ""); - fprintf (file, "%s", bwb_vertable[j].ID); - fprintf (file, ""); - fprintf (file, "
"); - fprintf (file, "%s", (char *) IntrinsicCommandTable[i].Syntax); - fprintf (file, ""); - if (IntrinsicCommandTable[i].OptionVersionBitmask & bwb_vertable[j]. - OptionVersionValue) - { - fprintf (file, "X"); - } - else - { - fprintf (file, " "); - } - fprintf (file, "
\n"); - fprintf (file, "\n"); - fprintf (file, "\n"); - - fflush (file); -} - -/* --------------------------------------------------------------------------------------------- - HELP --------------------------------------------------------------------------------------------- -*/ -LineType * -bwb_HELP (LineType * l) -{ - /* HELP ... */ - int n; - int Found; - char *C; - char *tbuf; - - assert (l != NULL); - assert( My != NULL ); - assert( My->ConsoleInput != NULL ); - assert( My->SYSOUT != NULL ); - assert( My->SYSOUT->cfp != NULL ); - - tbuf = My->ConsoleInput; - Found = FALSE; - - C = l->buffer; - C += l->position; - bwb_strcpy (tbuf, C); - - /* RTRIM$ */ - C = tbuf; - if (*C != 0) - { - /* not an empty line, so remove one (or more) trailing spaces */ - char *E; - - E = bwb_strchr (tbuf, 0); - E--; - while (E >= tbuf && *E == ' ') - { - *E = 0; - E--; - } - } - - - /* EXACT match */ - for (n = 0; n < NUM_COMMANDS; n++) - { - if (bwb_stricmp (IntrinsicCommandTable[n].name, tbuf) == 0) - { - fprintf (My->SYSOUT->cfp, - "------------------------------------------------------------\n"); - DumpOneCommandSyntax (My->SYSOUT->cfp, FALSE, n); - Found = TRUE; - } - } - - for (n = 0; n < NUM_FUNCTIONS; n++) - { - if (bwb_stricmp (IntrinsicFunctionTable[n].Name, tbuf) == 0) - { - fprintf (My->SYSOUT->cfp, - "------------------------------------------------------------\n"); - DumpOneFunctionSyntax (My->SYSOUT->cfp, FALSE, n); - Found = TRUE; - } - } - - if (Found == FALSE) - { - /* PARTIAL match */ - int Length; - Length = bwb_strlen (tbuf); - - for (n = 0; n < NUM_COMMANDS; n++) - { - if (bwb_strnicmp (IntrinsicCommandTable[n].name, tbuf, Length) == 0) - { - if (Found == FALSE) - { - fprintf (My->SYSOUT->cfp, - "The following topics are a partial match:\n"); - } - fprintf (My->SYSOUT->cfp, "%s", IntrinsicCommandTable[n].name); - fprintf (My->SYSOUT->cfp, "\t"); - Found = TRUE; - } - } - - for (n = 0; n < NUM_FUNCTIONS; n++) - { - if (bwb_strnicmp (IntrinsicFunctionTable[n].Name, tbuf, Length) == 0) - { - if (Found == FALSE) - { - fprintf (My->SYSOUT->cfp, - "The following topics are a partial match:\n"); - } - fprintf (My->SYSOUT->cfp, "%s", IntrinsicFunctionTable[n].Name); - fprintf (My->SYSOUT->cfp, "\t"); - Found = TRUE; - } - } - if (Found == TRUE) - { - /* match */ - fprintf (My->SYSOUT->cfp, "\n"); - } - } - if (Found == FALSE) - { - /* NO match */ - fprintf (My->SYSOUT->cfp, "No help found.\n"); - } - ResetConsoleColumn (); - line_skip_eol (l); - return (l); - -} - -int -NumberValueCheck (ParamTestType ParameterTests, DoubleType X) -{ - DoubleType XR; /* rounded value */ - unsigned char TestNibble; - - - - /* VerifyNumeric */ - if (isnan (X)) - { - /* INTERNAL ERROR */ - return -1; - } - if (isinf (X)) - { - /* - Evaluation of an expression results in an overflow - * (nonfatal, the recommended recovery procedure is to supply - * machine in- finity with the algebraically correct sign and - * continue). */ - if (X < 0) - { - X = MINDBL; - } - else - { - X = MAXDBL; - } - if (WARN_OVERFLOW) - { - /* ERROR */ - return -1; - } - /* CONTINUE */ - } - /* OK */ - /* VALID NUMERIC VALUE */ - XR = bwb_rint (X); - ParameterTests &= 0x0000000F; - TestNibble = (unsigned char) ParameterTests; - switch (TestNibble) - { - case P1ERR: - /* INTERNAL ERROR */ - return -1; - /* break; */ - case P1ANY: - if (X < MINDBL || X > MAXDBL) - { - /* ERROR */ - return -1; - } - /* OK */ - return 0; - /* break; */ - case P1BYT: - if (XR < MINBYT || XR > MAXBYT) - { - /* ERROR */ - return -1; - } - /* OK */ - return 0; - /* break; */ - case P1INT: - if (XR < MININT || XR > MAXINT) - { - /* ERROR */ - return -1; - } - /* OK */ - return 0; - /* break; */ - case P1LNG: - if (XR < MINLNG || XR > MAXLNG) - { - /* ERROR */ - return -1; - } - /* OK */ - return 0; - /* break; */ - case P1CUR: - if (XR < MINCUR || XR > MAXCUR) - { - /* ERROR */ - return -1; - } - /* OK */ - return 0; - /* break; */ - case P1FLT: - if (X < MINSNG || X > MAXSNG) - { - /* ERROR */ - return -1; - } - /* OK */ - return 0; - /* break; */ - case P1DBL: - if (X < MINDBL || X > MAXDBL) - { - /* ERROR */ - return -1; - } - /* OK */ - return 0; - /* break; */ - case P1DEV: - /* ERROR */ - return -1; - /* break; */ - case P1LEN: - if (XR < MINLEN || XR > MAXLEN) - { - /* ERROR */ - return -1; - } - /* OK */ - return 0; - /* break; */ - case P1POS: - if (XR < 1 || XR > MAXLEN) - { - /* ERROR */ - return -1; - } - /* OK */ - return 0; - /* break; */ - case P1COM: - /* ERROR */ - return -1; - /* break; */ - case P1LPT: - /* ERROR */ - return -1; - /* break; */ - case P1GTZ: - if (X > 0) - { - /* OK */ - return 0; - } - break; - case P1GEZ: - if (X >= 0) - { - /* OK */ - return 0; - } - break; - case P1NEZ: - if (X != 0) - { - /* OK */ - return 0; - } - break; - } - /* ERROR */ - return -1; -} - -int -StringLengthCheck (ParamTestType ParameterTests, int s) -{ - unsigned char TestNibble; - - - /* check for invalid string length */ - if (s < 0 || s > MAXLEN) - { - /* INTERNAL ERROR */ - return -1; - } - /* VALID STRING LENGTH */ - ParameterTests &= 0x0000000F; - TestNibble = (unsigned char) ParameterTests; - switch (TestNibble) - { - case P1ERR: - /* INTERNAL ERROR */ - return -1; - /* break; */ - case P1ANY: - /* OK */ - return 0; - /* break; */ - case P1BYT: - if (s >= sizeof (ByteType)) - { - /* OK */ - return 0; - } - break; - case P1INT: - if (s >= sizeof (IntegerType)) - { - /* OK */ - return 0; - } - break; - case P1LNG: - if (s >= sizeof (LongType)) - { - /* OK */ - return 0; - } - break; - case P1CUR: - if (s >= sizeof (CurrencyType)) - { - /* OK */ - return 0; - } - break; - case P1FLT: - if (s >= sizeof (SingleType)) - { - /* OK */ - return 0; - } - break; - case P1DBL: - if (s >= sizeof (DoubleType)) - { - /* OK */ - return 0; - } - break; - case P1DEV: - /* ERROR */ - return -1; - /* break; */ - case P1LEN: - /* ERROR */ - return -1; - /* break; */ - case P1POS: - /* ERROR */ - return -1; - /* break; */ - case P1GEZ: - /* ERROR */ - return -1; - /* break; */ - case P1GTZ: - /* ERROR */ - return -1; - /* break; */ - case P1NEZ: - /* ERROR */ - return -1; - /* break; */ - } - /* ERROR */ - return -1; -} - -void -IntrinsicFunctionDefinitionCheck (IntrinsicFunctionType * f) -{ - /* function definition check -- look for obvious errors */ - - assert (f != NULL); - assert( My != NULL ); - assert( My->SYSOUT != NULL ); - assert( My->SYSOUT->cfp != NULL ); - - - /* sanity check */ - if (f->ParameterCount == PNONE || f->ParameterCount == 0xFF) - { - /* function has NO explicit parameters */ - if (f->ParameterTypes == PNONE) - { - /* OK */ - } - else - { - /* oops */ - fprintf (My->SYSOUT->cfp, "invalid ParameterTypes <%s>\n", f->Name); - } - if (f->ParameterTests == PNONE) - { - /* OK */ - } - else - { - /* oops */ - fprintf (My->SYSOUT->cfp, "invalid ParameterTests <%s>\n", f->Name); - } - } - else - { - /* function HAS an explicit number of parameters */ - int i; - ParamTestType ParameterTests; - - ParameterTests = f->ParameterTests; - for (i = 0; i < f->ParameterCount; i++) - { - /* sanity check this parameter */ - ParamTestType thischeck; - thischeck = ParameterTests & 0x0000000F; - /* verify parameter check */ - if (f->ParameterTypes & (1 << i)) - { - /* STRING */ - if (thischeck >= P1ANY && thischeck <= P1DBL) - { - /* OK */ - } - else - { - /* oops */ - fprintf (My->SYSOUT->cfp, - "invalid ParameterTests <%s> parameter %d\n", f->Name, - i + 1); - } - } - else - { - /* NUMBER */ - if (thischeck >= P1ANY && thischeck <= P1NEZ) - { - /* OK */ - } - else - { - /* oops */ - fprintf (My->SYSOUT->cfp, - "invalid ParameterTests <%s> parameter %d\n", f->Name, - i + 1); - } - } - ParameterTests = ParameterTests >> 4; - } - if (ParameterTests != 0) - { - /* oops */ - fprintf (My->SYSOUT->cfp, "invalid ParameterTests <%s> parameter %d\n", - f->Name, i + 1); - } - } -} - -void -IntrinsicFunctionUniqueID (IntrinsicFunctionType * f, char *UniqueID) -{ - /* generate the function's UniqueID */ - /* manual fixup required for duplicates */ - char NumVar; - char StrVar; - - assert (f != NULL); - assert (UniqueID != NULL); - - - NumVar = 'X'; - StrVar = 'A'; - - /* F_ */ - bwb_strcpy (UniqueID, "F_"); - /* NAME */ - bwb_strcat (UniqueID, f->Name); - /* PARAMETERS */ - if (f->ParameterCount == PNONE || f->ParameterCount == 0xFF) - { - /* function has NO explicit parameters */ - } - else - { - /* function HAS explicit parameters */ - int i; - ParamBitsType ParameterTypes; - ParameterTypes = f->ParameterTypes; - for (i = 0; i < f->ParameterCount; i++) - { - char VarName[NameLengthMax + 1]; - if (ParameterTypes & 1) - { - /* STRING */ - sprintf (VarName, "_%c", StrVar); - StrVar++; - } - else - { - /* NUMBER */ - sprintf (VarName, "_%c", NumVar); - NumVar++; - } - bwb_strcat (UniqueID, VarName); - ParameterTypes = ParameterTypes >> 1; - } - } - /* RETURN TYPE */ - if (f->ReturnTypeCode == StringTypeCode) - { - bwb_strcat (UniqueID, "_S"); - } - else - { - bwb_strcat (UniqueID, "_N"); - } - /* fixup illegal characters, "DEF FN" "BLOAD:", "CLOAD*" */ - FixUp (UniqueID); -} - - -void -IntrinsicFunctionSyntax (IntrinsicFunctionType * f, char *Syntax) -{ - /* generate the function's Syntax */ - char NumVar; - char StrVar; - - assert (f != NULL); - assert (Syntax != NULL); - - - NumVar = 'X'; - StrVar = 'A'; - - /* RETURN TYPE */ - if (f->ReturnTypeCode == StringTypeCode) - { - bwb_strcpy (Syntax, "S$ = "); - } - else - { - bwb_strcpy (Syntax, "N = "); - } - /* NAME */ - bwb_strcat (Syntax, f->Name); - /* PARAMETERS */ - if (f->ParameterCount == PNONE) - { - /* function has NO explicit parameters */ - } - else if (f->ParameterCount == 0xFF) - { - /* function has a variable number of parameters */ - bwb_strcat (Syntax, "( ... )"); - } - else - { - /* function HAS explicit parameters */ - int i; - ParamBitsType ParameterTypes; - ParameterTypes = f->ParameterTypes; - - if (f->ReturnTypeCode == StringTypeCode) - { - bwb_strcat (Syntax, "( "); - } - else - { - bwb_strcat (Syntax, "( "); - } - - for (i = 0; i < f->ParameterCount; i++) - { - char VarName[NameLengthMax + 1]; - if (i > 0) - { - bwb_strcat (Syntax, ", "); - } - /* verify parameter check */ - if (ParameterTypes & 1) - { - /* STRING */ - sprintf (VarName, "%c$", StrVar); - StrVar++; - } - else - { - /* NUMBER */ - sprintf (VarName, "%c", NumVar); - NumVar++; - } - bwb_strcat (Syntax, VarName); - ParameterTypes = ParameterTypes >> 1; - } - if (f->ReturnTypeCode == StringTypeCode) - { - bwb_strcat (Syntax, " )"); - } - else - { - bwb_strcat (Syntax, " )"); - } - } -} - -void -DumpAllFunctionUniqueID (FILE * file) -{ - /* for the C maintainer */ - int i; - int j; - char LastUniqueID[NameLengthMax + 1]; - - assert (file != NULL); - - j = 0; - LastUniqueID[0] = NulChar; - - fprintf (file, "/* FUNCTIONS */\n"); - for (i = 0; i < NUM_FUNCTIONS; i++) - { - char UniqueID[NameLengthMax + 1]; - - IntrinsicFunctionUniqueID (&(IntrinsicFunctionTable[i]), UniqueID); - if (bwb_stricmp (LastUniqueID, UniqueID) != 0) - { - /* not a duplicate */ - char Syntax[NameLengthMax + 1]; - - bwb_strcpy (LastUniqueID, UniqueID); - j = j + 1; - IntrinsicFunctionSyntax (&(IntrinsicFunctionTable[i]), Syntax); - fprintf (file, "#define %-30s %3d /* %-30s */\n", UniqueID, j, Syntax); - } - } - fprintf (file, "#define NUM_FUNCTIONS %d\n", j); - fflush (file); -} - -void -DumpAllFunctionSwitch (FILE * file) -{ - /* for the C maintainer */ - int i; - - assert (file != NULL); - - - fprintf (file, "/* SWITCH */\n"); - fprintf (file, "switch( UniqueID )\n"); - fprintf (file, "{\n"); - for (i = 0; i < NUM_FUNCTIONS; i++) - { - char tbuf[MAINTAINER_BUFFER_LENGTH + 1]; /* DumpAllFunctionSwitch */ - - fprintf (file, "case "); - IntrinsicFunctionUniqueID (&(IntrinsicFunctionTable[i]), tbuf); - fprintf (file, "%s", tbuf); - fprintf (file, ":\n"); - fprintf (file, " break;\n"); - } - fprintf (file, "}\n"); - fflush (file); -} - -static const char *ParameterRangeID[16] = { - "P%dERR", - "P%dANY", - "P%dBYT", - "P%dINT", - "P%dLNG", - "P%dCUR", - "P%dFLT", - "P%dDBL", - "P%dDEV", - "P%dLEN", - "P%dPOS", - "P%dCOM", - "P%dLPT", - "P%dGTZ", - "P%dGEZ", - "P%dNEZ", -}; - -static const char *NumberVariableRange[16] = { - /* P1ERR */ " PARAMETER: %c is a number, INTERNAL ERROR", - /* P1ANY */ " PARAMETER: %c is a number", - /* P1BYT */ " PARAMETER: %c is a number, [0,255]", - /* P1INT */ " PARAMETER: %c is a number, [MININT,MAXINT]", - /* P1LNG */ " PARAMETER: %c is a number, [MINLNG,MAXLNG]", - /* P1CUR */ " PARAMETER: %c is a number, [MINCUR,MAXCUR]", - /* P1FLT */ " PARAMETER: %c is a number, [MINFLT,MAXFLT]", - /* P1DBL */ " PARAMETER: %c is a number, [MINDBL,MAXDBL]", - /* P1DEV */ " PARAMETER: %c is a number, RESERVED", - /* P1LEN */ " PARAMETER: %c is a number, [0,MAXLEN]", - /* P1POS */ " PARAMETER: %c is a number, [1,MAXLEN]", - /* P1COM */ " PARAMETER: %c is a number, RESERVED", - /* P1LPT */ " PARAMETER: %c is a number, RESERVED", - /* P1GTZ */ " PARAMETER: %c is a number, > 0", - /* P1GEZ */ " PARAMETER: %c is a number, >= 0", - /* P1NEZ */ " PARAMETER: %c is a number, <> 0", -}; - -static const char *StringVariableRange[16] = { - /* P1ERR */ " PARAMETER: %c$ is a string, INTERNAL ERROR", - /* P1ANY */ " PARAMETER: %c$ is a string, LEN >= 0", - /* P1BYT */ " PARAMETER: %c$ is a string, LEN >= 1", - /* P1INT */ " PARAMETER: %c$ is a string, LEN >= sizeof(INT)", - /* P1LNG */ " PARAMETER: %c$ is a string, LEN >= sizeof(LNG)", - /* P1CUR */ " PARAMETER: %c$ is a string, LEN >= sizeof(CUR)", - /* P1FLT */ " PARAMETER: %c$ is a string, LEN >= sizeof(FLT)", - /* P1DBL */ " PARAMETER: %c$ is a string, LEN >= sizeof(DBL)", - /* P1DEV */ " PARAMETER: %c$ is a string, RESERVED", - /* P1LEN */ " PARAMETER: %c$ is a string, RESERVED", - /* P1POS */ " PARAMETER: %c$ is a string, RESERVED", - /* P1COM */ " PARAMETER: %c$ is a string, RESERVED", - /* P1LPT */ " PARAMETER: %c$ is a string, RESERVED", - /* P1GTZ */ " PARAMETER: %c$ is a string, RESERVED", - /* P1GEZ */ " PARAMETER: %c$ is a string, RESERVED", - /* P1NEZ */ " PARAMETER: %c$ is a string, RESERVED", -}; - -void -DumpAllFuctionTableDefinitions (FILE * file) -{ - /* generate bwd_fun.c */ - int n; - - assert (file != NULL); - - - fprintf (file, "/* FUNCTION TABLE */\n"); - fprintf (file, "\n"); - fprintf (file, "#include \"bwbasic.h\"\n"); - fprintf (file, "\n"); - fprintf (file, - "IntrinsicFunctionType IntrinsicFunctionTable[ /* NUM_FUNCTIONS */ ] =\n"); - fprintf (file, "{\n"); - for (n = 0; n < NUM_FUNCTIONS; n++) - { - int i; - int j; - char tbuf[MAINTAINER_BUFFER_LENGTH + 1]; /* DumpAllFuctionTableDefinitions */ - char UniqueID[MAINTAINER_BUFFER_LENGTH + 1]; /* DumpAllFuctionTableDefinitions */ - char Syntax[MAINTAINER_BUFFER_LENGTH + 1]; /* DumpAllFuctionTableDefinitions */ - IntrinsicFunctionType *f; - - f = &(IntrinsicFunctionTable[n]); - - IntrinsicFunctionUniqueID (f, UniqueID); - IntrinsicFunctionSyntax (f, Syntax); - fprintf (file, "{\n"); - fprintf (file, " %s, /* UniqueID */\n", UniqueID); - fprintf (file, " \"%s\", /* Syntax */\n", Syntax); - fprintf (file, " "); - fprintf (file, "\""); - ProcessEscapeChars (f->Description, tbuf); - fprintf (file, "%s", tbuf); - fprintf (file, "\""); - fprintf (file, ", /* Description */\n"); - fprintf (file, " \"%s\", /* Name */\n", f->Name); - switch (f->ReturnTypeCode) - { - case ByteTypeCode: - fprintf (file, " %s, /* ReturnTypeCode */\n", "ByteTypeCode"); - break; - case IntegerTypeCode: - fprintf (file, " %s, /* ReturnTypeCode */\n", "IntegerTypeCode"); - break; - case LongTypeCode: - fprintf (file, " %s, /* ReturnTypeCode */\n", "LongTypeCode"); - break; - case CurrencyTypeCode: - fprintf (file, " %s, /* ReturnTypeCode */\n", "CurrencyTypeCode"); - break; - case SingleTypeCode: - fprintf (file, " %s, /* ReturnTypeCode */\n", "SingleTypeCode"); - break; - case DoubleTypeCode: - fprintf (file, " %s, /* ReturnTypeCode */\n", "DoubleTypeCode"); - break; - case StringTypeCode: - fprintf (file, " %s, /* ReturnTypeCode */\n", "StringTypeCode"); - break; - default: - fprintf (file, " %s, /* ReturnTypeCode */\n", "INTERNAL ERROR"); - break; - } - fprintf (file, " %d, /* ParameterCount */\n", f->ParameterCount); - if (f->ParameterCount == 0 || f->ParameterCount == 0xFF) - { - /* function has NO explicit parameters */ - fprintf (file, " %s, /* ParameterTypes */\n", "PNONE"); - fprintf (file, " %s, /* ParameterTests */\n", "PNONE"); - } - else - { - /* function has explicit parameters */ - bwb_strcpy (tbuf, " "); - for (i = 0; i < f->ParameterCount; i++) - { - ParamBitsType ParameterTypes; - ParameterTypes = f->ParameterTypes >> i; - ParameterTypes &= 0x1; - if (i > 0) - { - bwb_strcat (tbuf, " | "); - } - if (ParameterTypes) - { - sprintf (bwb_strchr (tbuf, NulChar), "P%dSTR", i + 1); - } - else - { - sprintf (bwb_strchr (tbuf, NulChar), "P%dNUM", i + 1); - } - } - bwb_strcat (tbuf, ", /* ParameterTypes */\n"); - fprintf (file, "%s", tbuf); - - - bwb_strcpy (tbuf, " "); - for (i = 0; i < f->ParameterCount; i++) - { - ParamTestType ParameterTests; - ParameterTests = f->ParameterTests >> (i * 4); - ParameterTests &= 0xF; - - if (i > 0) - { - bwb_strcat (tbuf, " | "); - } - sprintf (bwb_strchr (tbuf, 0), ParameterRangeID[ParameterTests], - i + 1); - /* Conversion may lose significant digits */ - } - bwb_strcat (tbuf, ", /* ParameterTests */\n"); - fprintf (file, "%s", tbuf); - } - bwb_strcpy (tbuf, " "); - j = 0; - for (i = 0; i < NUM_VERSIONS; i++) - { - if (f->OptionVersionBitmask & bwb_vertable[i].OptionVersionValue) - { - if (j > 0) - { - bwb_strcat (tbuf, " | "); - } - bwb_strcat (tbuf, bwb_vertable[i].ID); - j++; - } - } - bwb_strcat (tbuf, " /* OptionVersionBitmask */\n"); - fprintf (file, "%s", tbuf); - fprintf (file, "},\n"); - } - fprintf (file, "};\n"); - fprintf (file, "\n"); - fprintf (file, - "const size_t NUM_FUNCTIONS = sizeof( IntrinsicFunctionTable ) / sizeof( IntrinsicFunctionType );\n"); - fprintf (file, "\n"); - fflush (file); -} - -void -DumpOneFunctionSyntax (FILE * file, int IsXref, int n) -{ - IntrinsicFunctionType *f; - assert (file != NULL); - - - - if (n < 0 || n >= NUM_FUNCTIONS) - { - return; - } - f = &(IntrinsicFunctionTable[n]); - /* NAME */ - { - char UniqueID[MAINTAINER_BUFFER_LENGTH + 1]; /* DumpOneFunctionSyntax */ - char Syntax[MAINTAINER_BUFFER_LENGTH + 1]; /* DumpOneFunctionSyntax */ - - IntrinsicFunctionUniqueID (f, UniqueID); - IntrinsicFunctionSyntax (f, Syntax); - fprintf (file, " SYNTAX: %s\n", Syntax); - } - /* PARAMETERS */ - if (f->ParameterCount == PNONE || f->ParameterCount == 0xFF) - { - /* function has NO explicit parameters */ - } - else - { - /* function HAS explicit parameters */ - int i; - ParamBitsType ParameterTypes; - ParamTestType ParameterTests; - char NumVar; - char StrVar; - ParameterTypes = f->ParameterTypes; - ParameterTests = f->ParameterTests; - NumVar = 'X'; - StrVar = 'A'; - for (i = 0; i < f->ParameterCount; i++) - { - /* sanity check this parameter */ - unsigned long thischeck; - char tbuf[MAINTAINER_BUFFER_LENGTH + 1]; /* DumpOneFunctionSyntax */ - - thischeck = ParameterTests & 0x0000000F; - /* verify parameter check */ - if (ParameterTypes & 1) - { - /* STRING */ - sprintf (tbuf, StringVariableRange[thischeck], StrVar); - /* Conversion may lose significant digits */ - StrVar++; - } - else - { - /* NUMBER */ - sprintf (tbuf, NumberVariableRange[thischeck], NumVar); - /* Conversion may lose significant digits */ - NumVar++; - } - fprintf (file, "%s", tbuf); - fprintf (file, "\n"); - ParameterTypes = ParameterTypes >> 1; - ParameterTests = ParameterTests >> 4; - } - } - /* DESCRIPTION */ - { - FixDescription (file, "DESCRIPTION: ", f->Description); - } - /* COMPATIBILITY */ - if (IsXref) - { - int i; - fprintf (file, " VERSIONS:\n"); - for (i = 0; i < NUM_VERSIONS; i++) - { - char X; - if (f->OptionVersionBitmask & bwb_vertable[i].OptionVersionValue) - { - /* SUPPORTED */ - X = 'X'; - } - else - { - /* NOT SUPPORTED */ - X = '_'; - } - fprintf (file, " [%c] %s\n", X, bwb_vertable[i].Name); - } - } - - fflush (file); -} - -void -DumpAllFunctionSyntax (FILE * file, int IsXref, - OptionVersionType OptionVersionValue) -{ - /* for the C maintainer */ - int i; - - assert (file != NULL); - - - fprintf (file, - "============================================================\n"); - fprintf (file, - " FUNCTIONS \n"); - fprintf (file, - "============================================================\n"); - fprintf (file, "\n"); - fprintf (file, "\n"); - for (i = 0; i < NUM_FUNCTIONS; i++) - { - if (IntrinsicFunctionTable[i].OptionVersionBitmask & OptionVersionValue) - { - fprintf (file, - "------------------------------------------------------------\n"); - DumpOneFunctionSyntax (file, IsXref, i); - } - } - fprintf (file, - "------------------------------------------------------------\n"); - fprintf (file, "\n"); - fprintf (file, "\n"); - fflush (file); -} - -void -DumpAllFunctionHtmlTable (FILE * file) -{ - /* generate bwd_cmd.htm */ - int i; - int j; - - assert (file != NULL); - - - /* LEGEND */ - fprintf (file, "FNCS\n"); - fprintf (file, "

LEGEND


\n"); - fprintf (file, "\n"); - - fprintf (file, ""); - fprintf (file, ""); - fprintf (file, ""); - fprintf (file, ""); - fprintf (file, "\n"); - - for (j = 0; j < NUM_VERSIONS; j++) - { - fprintf (file, ""); - fprintf (file, ""); - fprintf (file, ""); - fprintf (file, ""); - fprintf (file, "\n"); - } - fprintf (file, "
"); - fprintf (file, ""); - fprintf (file, "ID"); - fprintf (file, ""); - fprintf (file, ""); - fprintf (file, ""); - fprintf (file, "NAME"); - fprintf (file, ""); - fprintf (file, ""); - fprintf (file, ""); - fprintf (file, "DESCRIPTION"); - fprintf (file, ""); - fprintf (file, "
"); - fprintf (file, "%s", bwb_vertable[j].ID); - fprintf (file, ""); - fprintf (file, "%s", bwb_vertable[j].Name); - fprintf (file, ""); - fprintf (file, "%s", bwb_vertable[j].Description); - fprintf (file, "
\n"); - fprintf (file, "
\n"); - - - /* DETAILS */ - fprintf (file, "

DETAILS


\n"); - fprintf (file, "\n"); - - fprintf (file, ""); - fprintf (file, ""); - for (j = 0; j < NUM_VERSIONS; j++) - { - fprintf (file, ""); - } - fprintf (file, "\n"); - - - /* run through the command table and print comand -vs- OPTION VERSION */ - - for (i = 0; i < NUM_FUNCTIONS; i++) - { - fprintf (file, ""); - fprintf (file, ""); - - for (j = 0; j < NUM_VERSIONS; j++) - { - fprintf (file, ""); - } - fprintf (file, "\n"); - } - fprintf (file, "
"); - fprintf (file, ""); - fprintf (file, "FUNCTION"); - fprintf (file, ""); - fprintf (file, ""); - fprintf (file, ""); - fprintf (file, "%s", bwb_vertable[j].ID); - fprintf (file, ""); - fprintf (file, "
"); - fprintf (file, "%s", (char *) IntrinsicFunctionTable[i].Syntax); - fprintf (file, ""); - if (IntrinsicFunctionTable[i].OptionVersionBitmask & bwb_vertable[j]. - OptionVersionValue) - { - fprintf (file, "X"); - } - else - { - fprintf (file, " "); - } - fprintf (file, "
\n"); - fprintf (file, "\n"); - fprintf (file, "\n"); - - fflush (file); -} - -/* --------------------------------------------------------------------------------------------- - FNCS --------------------------------------------------------------------------------------------- -*/ -LineType * -bwb_FNCS (LineType * l) -{ - int n; - int t; - - assert (l != NULL); - assert( My != NULL ); - assert( My->SYSOUT != NULL ); - assert( My->SYSOUT->cfp != NULL ); - - - My->CurrentFile = My->SYSOUT; - fprintf (My->SYSOUT->cfp, "BWBASIC FUNCTIONS AVAILABLE:\n"); - - /* run through the command table and print comand names */ - - t = 0; - for (n = 0; n < NUM_FUNCTIONS; n++) - { - fprintf (My->SYSOUT->cfp, "%s", IntrinsicFunctionTable[n].Name); - if (t < 4) - { - fprintf (My->SYSOUT->cfp, "\t"); - t++; - } - else - { - fprintf (My->SYSOUT->cfp, "\n"); - t = 0; - } - } - if (t > 0) - { - fprintf (My->SYSOUT->cfp, "\n"); - } - ResetConsoleColumn (); - return (l); -} - -/* --------------------------------------------------------------------------------------------- - MAINTAINER --------------------------------------------------------------------------------------------- -*/ -LineType * -bwb_MAINTAINER (LineType * l) -{ - - assert (l != NULL); - WARN_SYNTAX_ERROR; - return (l); -} - -LineType * -bwb_MAINTAINER_CMDS (LineType * l) -{ - - assert (l != NULL); - WARN_SYNTAX_ERROR; - return (l); -} - -LineType * -bwb_MAINTAINER_CMDS_HTML (LineType * l) -{ - - assert (l != NULL); - assert(My != NULL); - assert(My->SYSPRN != NULL); - assert(My->SYSPRN->cfp != NULL); - DumpAllCommandHtmlTable (My->SYSPRN->cfp); - return (l); -} - -LineType * -bwb_MAINTAINER_CMDS_ID (LineType * l) -{ - - assert (l != NULL); - assert(My != NULL); - assert(My->SYSPRN != NULL); - assert(My->SYSPRN->cfp != NULL); - DumpAllCommandUniqueID (My->SYSPRN->cfp); - return (l); -} - -LineType * -bwb_MAINTAINER_CMDS_MANUAL (LineType * l) -{ - - assert (l != NULL); - assert(My != NULL); - assert(My->SYSPRN != NULL); - assert(My->SYSPRN->cfp != NULL); - DumpAllCommandSyntax (My->SYSPRN->cfp, TRUE, (OptionVersionType)(-1)); - return (l); -} - -LineType * -bwb_MAINTAINER_CMDS_SWITCH (LineType * l) -{ - - assert (l != NULL); - assert(My != NULL); - assert(My->SYSPRN != NULL); - assert(My->SYSPRN->cfp != NULL); - DumpAllCommandSwitchStatement (My->SYSPRN->cfp); - return (l); -} - -LineType * -bwb_MAINTAINER_CMDS_TABLE (LineType * l) -{ - - assert (l != NULL); - assert(My != NULL); - assert(My->SYSPRN != NULL); - assert(My->SYSPRN->cfp != NULL); - DumpAllCommandTableDefinitions (My->SYSPRN->cfp); - return (l); -} - -LineType * -bwb_MAINTAINER_DEBUG (LineType * l) -{ - - assert (l != NULL); - WARN_SYNTAX_ERROR; - return (l); -} - -LineType * -bwb_MAINTAINER_DEBUG_ON (LineType * l) -{ - - assert (l != NULL); - return (l); -} - -LineType * -bwb_MAINTAINER_DEBUG_OFF (LineType * l) -{ - - assert (l != NULL); - return (l); -} - -LineType * -bwb_MAINTAINER_FNCS (LineType * l) -{ - - assert (l != NULL); - WARN_SYNTAX_ERROR; - return (l); -} - -LineType * -bwb_MAINTAINER_FNCS_HTML (LineType * l) -{ - - assert (l != NULL); - assert(My != NULL); - assert(My->SYSPRN != NULL); - assert(My->SYSPRN->cfp != NULL); - DumpAllFunctionHtmlTable (My->SYSPRN->cfp); - return (l); -} - -LineType * -bwb_MAINTAINER_FNCS_ID (LineType * l) -{ - - assert (l != NULL); - assert(My != NULL); - assert(My->SYSPRN != NULL); - assert(My->SYSPRN->cfp != NULL); - DumpAllFunctionUniqueID (My->SYSPRN->cfp); - return (l); -} - -LineType * -bwb_MAINTAINER_FNCS_MANUAL (LineType * l) -{ - - assert (l != NULL); - assert(My != NULL); - assert(My->SYSPRN != NULL); - assert(My->SYSPRN->cfp != NULL); - DumpAllFunctionSyntax (My->SYSPRN->cfp, TRUE, (OptionVersionType)(-1)); - DumpAllOperatorSyntax (My->SYSPRN->cfp, TRUE, (OptionVersionType)(-1)); - return (l); -} - -LineType * -bwb_MAINTAINER_FNCS_SWITCH (LineType * l) -{ - - assert (l != NULL); - assert(My != NULL); - assert(My->SYSPRN != NULL); - assert(My->SYSPRN->cfp != NULL); - DumpAllFunctionSwitch (My->SYSPRN->cfp); - return (l); -} - -LineType * -bwb_MAINTAINER_FNCS_TABLE (LineType * l) -{ - - assert (l != NULL); - assert(My != NULL); - assert(My->SYSPRN != NULL); - assert(My->SYSPRN->cfp != NULL); - DumpAllFuctionTableDefinitions (My->SYSPRN->cfp); - return (l); -} - -void -DumpHeader (FILE * file) -{ - char c; - - assert (file != NULL); - assert(My != NULL); - assert(My->CurrentVersion != NULL); - - fprintf (file, - "============================================================\n"); - fprintf (file, - " GENERAL \n"); - fprintf (file, - "============================================================\n"); - fprintf (file, "\n"); - fprintf (file, "\n"); - - fprintf (file, "OPTION VERSION \"%s\"\n", My->CurrentVersion->Name); - fprintf (file, "REM INTERNAL ID: %s\n", My->CurrentVersion->ID); - fprintf (file, "REM DESCRIPTION: %s\n", My->CurrentVersion->Description); - fprintf (file, "REM REFERENCE: %s\n", My->CurrentVersion->ReferenceTitle); - fprintf (file, "REM %s\n", - My->CurrentVersion->ReferenceAuthor); - fprintf (file, "REM %s\n", - My->CurrentVersion->ReferenceCopyright); - fprintf (file, "REM %s\n", My->CurrentVersion->ReferenceURL1); - fprintf (file, "REM %s\n", My->CurrentVersion->ReferenceURL2); - fprintf (file, "REM\n"); - - if (My->CurrentVersion->OptionFlags & (OPTION_STRICT_ON)) - { - fprintf (file, "OPTION STRICT ON\n"); - } - else - { - fprintf (file, "OPTION STRICT OFF\n"); - } - - if (My->CurrentVersion->OptionFlags & (OPTION_ANGLE_DEGREES)) - { - fprintf (file, "OPTION ANGLE DEGREES\n"); - } - else if (My->CurrentVersion->OptionFlags & (OPTION_ANGLE_GRADIANS)) - { - fprintf (file, "OPTION ANGLE GRADIANS\n"); - } - else - { - fprintf (file, "OPTION ANGLE RADIANS\n"); - } - - if (My->CurrentVersion->OptionFlags & (OPTION_BUGS_ON)) - { - fprintf (file, "OPTION BUGS ON\n"); - } - else - { - fprintf (file, "OPTION BUGS OFF\n"); - } - - if (My->CurrentVersion->OptionFlags & (OPTION_LABELS_ON)) - { - fprintf (file, "OPTION LABELS ON\n"); - } - else - { - fprintf (file, "OPTION LABELS OFF\n"); - } - - if (My->CurrentVersion->OptionFlags & (OPTION_COMPARE_TEXT)) - { - fprintf (file, "OPTION COMPARE TEXT\n"); - } - else - { - fprintf (file, "OPTION COMPARE BINARY\n"); - } - - if (My->CurrentVersion->OptionFlags & (OPTION_COVERAGE_ON)) - { - fprintf (file, "OPTION COVERAGE ON\n"); - } - else - { - fprintf (file, "OPTION COVERAGE OFF\n"); - } - - if (My->CurrentVersion->OptionFlags & (OPTION_TRACE_ON)) - { - fprintf (file, "OPTION TRACE ON\n"); - } - else - { - fprintf (file, "OPTION TRACE OFF\n"); - } - - if (My->CurrentVersion->OptionFlags & (OPTION_ERROR_GOSUB)) - { - fprintf (file, "OPTION ERROR GOSUB\n"); - } - else - { - fprintf (file, "OPTION ERROR GOTO\n"); - } - - if (My->CurrentVersion->OptionFlags & (OPTION_EXPLICIT_ON)) - { - fprintf (file, "OPTION EXPLICIT\n"); - } - else - { - fprintf (file, "OPTION IMPLICIT\n"); - } - - fprintf (file, "OPTION BASE %d\n", - My->CurrentVersion->OptionBaseInteger); - fprintf (file, "OPTION RECLEN %d\n", - My->CurrentVersion->OptionReclenInteger); - fprintf (file, "OPTION DATE \"%s\"\n", - My->CurrentVersion->OptionDateFormat); - fprintf (file, "OPTION TIME \"%s\"\n", - My->CurrentVersion->OptionTimeFormat); - - c = My->CurrentVersion->OptionStringChar; - if (!bwb_isgraph (c)) - { - c = ' '; - }; - fprintf (file, "OPTION PUNCT STRING \"%c\"\n", c); - - c = My->CurrentVersion->OptionDoubleChar; - if (!bwb_isgraph (c)) - { - c = ' '; - }; - fprintf (file, "OPTION PUNCT DOUBLE \"%c\"\n", c); - - c = My->CurrentVersion->OptionSingleChar; - if (!bwb_isgraph (c)) - { - c = ' '; - }; - fprintf (file, "OPTION PUNCT SINGLE \"%c\"\n", c); - - c = My->CurrentVersion->OptionCurrencyChar; - if (!bwb_isgraph (c)) - { - c = ' '; - }; - fprintf (file, "OPTION PUNCT CURRENCY \"%c\"\n", c); - - c = My->CurrentVersion->OptionLongChar; - if (!bwb_isgraph (c)) - { - c = ' '; - }; - fprintf (file, "OPTION PUNCT LONG \"%c\"\n", c); - - c = My->CurrentVersion->OptionIntegerChar; - if (!bwb_isgraph (c)) - { - c = ' '; - }; - fprintf (file, "OPTION PUNCT INTEGER \"%c\"\n", c); - - c = My->CurrentVersion->OptionByteChar; - if (!bwb_isgraph (c)) - { - c = ' '; - }; - fprintf (file, "OPTION PUNCT BYTE \"%c\"\n", c); - - c = My->CurrentVersion->OptionQuoteChar; - if (!bwb_isgraph (c)) - { - c = ' '; - }; - fprintf (file, "OPTION PUNCT QUOTE \"%c\"\n", c); - - c = My->CurrentVersion->OptionCommentChar; - if (!bwb_isgraph (c)) - { - c = ' '; - }; - fprintf (file, "OPTION PUNCT COMMENT \"%c\"\n", c); - - c = My->CurrentVersion->OptionStatementChar; - if (!bwb_isgraph (c)) - { - c = ' '; - }; - fprintf (file, "OPTION PUNCT STATEMENT \"%c\"\n", c); - - c = My->CurrentVersion->OptionPrintChar; - if (!bwb_isgraph (c)) - { - c = ' '; - }; - fprintf (file, "OPTION PUNCT PRINT \"%c\"\n", c); - - c = My->CurrentVersion->OptionInputChar; - if (!bwb_isgraph (c)) - { - c = ' '; - }; - fprintf (file, "OPTION PUNCT INPUT \"%c\"\n", c); - - c = My->CurrentVersion->OptionImageChar; - if (!bwb_isgraph (c)) - { - c = ' '; - }; - fprintf (file, "OPTION PUNCT IMAGE \"%c\"\n", c); - - c = My->CurrentVersion->OptionLparenChar; - if (!bwb_isgraph (c)) - { - c = ' '; - }; - fprintf (file, "OPTION PUNCT LPAREN \"%c\"\n", c); - - c = My->CurrentVersion->OptionRparenChar; - if (!bwb_isgraph (c)) - { - c = ' '; - }; - fprintf (file, "OPTION PUNCT RPAREN \"%c\"\n", c); - - c = My->CurrentVersion->OptionFilenumChar; - if (!bwb_isgraph (c)) - { - c = ' '; - }; - fprintf (file, "OPTION PUNCT FILENUM \"%c\"\n", c); - - c = My->CurrentVersion->OptionAtChar; - if (!bwb_isgraph (c)) - { - c = ' '; - }; - fprintf (file, "OPTION PUNCT AT \"%c\"\n", c); - - c = My->CurrentVersion->OptionUsingDigit; - if (!bwb_isgraph (c)) - { - c = ' '; - }; - fprintf (file, "OPTION USING DIGIT \"%c\"\n", c); - - c = My->CurrentVersion->OptionUsingComma; - if (!bwb_isgraph (c)) - { - c = ' '; - }; - fprintf (file, "OPTION USING COMMA \"%c\"\n", c); - - c = My->CurrentVersion->OptionUsingPeriod; - if (!bwb_isgraph (c)) - { - c = ' '; - }; - fprintf (file, "OPTION USING PERIOD \"%c\"\n", c); - - c = My->CurrentVersion->OptionUsingPlus; - if (!bwb_isgraph (c)) - { - c = ' '; - }; - fprintf (file, "OPTION USING PLUS \"%c\"\n", c); - - c = My->CurrentVersion->OptionUsingMinus; - if (!bwb_isgraph (c)) - { - c = ' '; - }; - fprintf (file, "OPTION USING MINUS \"%c\"\n", c); - - c = My->CurrentVersion->OptionUsingExrad; - if (!bwb_isgraph (c)) - { - c = ' '; - }; - fprintf (file, "OPTION USING EXRAD \"%c\"\n", c); - - c = My->CurrentVersion->OptionUsingDollar; - if (!bwb_isgraph (c)) - { - c = ' '; - }; - fprintf (file, "OPTION USING DOLLAR \"%c\"\n", c); - - c = My->CurrentVersion->OptionUsingFiller; - if (!bwb_isgraph (c)) - { - c = ' '; - }; - fprintf (file, "OPTION USING FILLER \"%c\"\n", c); - - c = My->CurrentVersion->OptionUsingLiteral; - if (!bwb_isgraph (c)) - { - c = ' '; - }; - fprintf (file, "OPTION USING LITERAL \"%c\"\n", c); - - c = My->CurrentVersion->OptionUsingFirst; - if (!bwb_isgraph (c)) - { - c = ' '; - }; - fprintf (file, "OPTION USING FIRST \"%c\"\n", c); - - c = My->CurrentVersion->OptionUsingAll; - if (!bwb_isgraph (c)) - { - c = ' '; - }; - fprintf (file, "OPTION USING ALL \"%c\"\n", c); - - c = My->CurrentVersion->OptionUsingLength; - if (!bwb_isgraph (c)) - { - c = ' '; - }; - fprintf (file, "OPTION USING LENGTH \"%c\"\n", c); - - fprintf (file, "\n"); - fprintf (file, "\n"); - fflush (file); -} - -LineType * -bwb_MAINTAINER_MANUAL (LineType * l) -{ - - assert (l != NULL); - - DumpHeader (My->SYSPRN->cfp); - DumpAllCommandSyntax (My->SYSPRN->cfp, FALSE, - My->CurrentVersion->OptionVersionValue); - DumpAllFunctionSyntax (My->SYSPRN->cfp, FALSE, - My->CurrentVersion->OptionVersionValue); - DumpAllOperatorSyntax (My->SYSPRN->cfp, FALSE, - My->CurrentVersion->OptionVersionValue); - return (l); -} - -LineType * -bwb_MAINTAINER_STACK (LineType * l) -{ - /* - dump the current execution stack, - Leftmost is the top, - Rigthmost is the bottom. - */ - StackType *StackItem; - - assert (l != NULL); - - for (StackItem = My->StackHead; StackItem != NULL; - StackItem = StackItem->next) - { - LineType *l; - - l = StackItem->line; - if (l != NULL) - { - fprintf (My->SYSOUT->cfp, "%d:", l->number); - } - } - fprintf (My->SYSOUT->cfp, "\n"); - ResetConsoleColumn (); - return (l); -} - - -/*************************************************************** - - FUNCTION: IntrinsicFunction_init() - - DESCRIPTION: This command initializes the function - linked list, placing all predefined functions - in the list. - -***************************************************************/ - -int -IntrinsicFunction_init (void) -{ - int n; - - - for (n = 0; n < NUM_FUNCTIONS; n++) - { - IntrinsicFunctionDefinitionCheck (&(IntrinsicFunctionTable[n])); - } - return TRUE; -} - - - -VariableType * -IntrinsicFunction_deffn (int argc, VariableType * argv, UserFunctionType * f) -{ - /* - The generic handler for user defined functions. - When called by exp_function(), f->id will be set to the line number of a specific DEF USR. - */ - VariableType *v; - VariableType *argn; - int i; - LineType *call_line; - StackType *save_elevel; - - assert (argc >= 0); - assert (argv != NULL); - assert (f != NULL); - assert(My != NULL); - - /* initialize the variable if necessary */ - - /* these errors should not occur */ - if (f == NULL) - { - WARN_INTERNAL_ERROR; - return NULL; - } - if (f->line == NULL) - { - WARN_INTERNAL_ERROR; - return NULL; - } - if (argv == NULL) - { - WARN_INTERNAL_ERROR; - return NULL; - } - if (f->ParameterCount == 0xFF) - { - /* VARIANT */ - } - else if (argc != f->ParameterCount) - { - WARN_INTERNAL_ERROR; - return NULL; - } - if (f->ParameterCount == 0xFF) - { - /* VARIANT */ - f->local_variable = argv; - } - else if (argc > 0) - { - v = f->local_variable; - argn = argv; - for (i = 0; i < argc; i++) - { - argn = argn->next; - if (v == NULL) - { - WARN_INTERNAL_ERROR; - return NULL; - } - if (argn == NULL) - { - WARN_INTERNAL_ERROR; - return NULL; - } - if (VAR_IS_STRING (v) != VAR_IS_STRING (argn)) - { - WARN_INTERNAL_ERROR; - return NULL; - } - if (is_empty_string (v->name) == FALSE) - { - int IsError; - IsError = 0; - switch (v->VariableTypeCode) - { - case ByteTypeCode: - IsError = NumberValueCheck (P1BYT, PARAM_NUMBER); - break; - case IntegerTypeCode: - IsError = NumberValueCheck (P1INT, PARAM_NUMBER); - break; - case LongTypeCode: - IsError = NumberValueCheck (P1LNG, PARAM_NUMBER); - break; - case CurrencyTypeCode: - IsError = NumberValueCheck (P1CUR, PARAM_NUMBER); - break; - case SingleTypeCode: - IsError = NumberValueCheck (P1FLT, PARAM_NUMBER); - break; - case DoubleTypeCode: - IsError = NumberValueCheck (P1DBL, PARAM_NUMBER); - break; - case StringTypeCode: - IsError = StringLengthCheck (P1ANY, PARAM_LENGTH); - break; - default: - WARN_TYPE_MISMATCH; - return NULL; - } - if (IsError != 0) - { - WARN_ILLEGAL_FUNCTION_CALL; - return argv; - } - } - v = v->next; - } - } - /* OK */ - call_line = f->line; /* line to call for function */ - call_line->position = f->startpos; - - if (call_line->cmdnum == C_DEF) - { - if (line_skip_EqualChar (call_line) == FALSE) - { - WARN_INTERNAL_ERROR; - return NULL; - } - } -/* PUSH STACK */ - - save_elevel = My->StackHead; - if (bwb_incexec ()) - { - /* OK */ - My->StackHead->line = call_line; - My->StackHead->ExecCode = EXEC_FUNCTION; - } - else - { - /* ERROR */ - WARN_OUT_OF_MEMORY; - return NULL; - } - - - /* create variable chain */ - if (f->ParameterCount == 0xFF) - { - /* VARIANT */ - } - else if (argc > 0) - { - VariableType *source = NULL; /* source variable */ - source = f->local_variable; - argn = argv; - for (i = 0; i < argc; i++) - { - argn = argn->next; - /* copy the name */ - bwb_strcpy (argn->name, source->name); - - if (VAR_IS_STRING (source)) - { - } - else - { - int IsError; - double Value; - VariantType variant; - CLEAR_VARIANT (&variant); - - if (var_get (argn, &variant) == FALSE) - { - WARN_VARIABLE_NOT_DECLARED; - return NULL; - } - if (variant.VariantTypeCode == StringTypeCode) - { - WARN_TYPE_MISMATCH; - return NULL; - } - Value = variant.Number; - IsError = 0; - switch (source->VariableTypeCode) - { - case ByteTypeCode: - IsError = NumberValueCheck (P1BYT, Value); - Value = bwb_rint (Value); - break; - case IntegerTypeCode: - IsError = NumberValueCheck (P1INT, Value); - Value = bwb_rint (Value); - break; - case LongTypeCode: - IsError = NumberValueCheck (P1LNG, Value); - Value = bwb_rint (Value); - break; - case CurrencyTypeCode: - IsError = NumberValueCheck (P1CUR, Value); - Value = bwb_rint (Value); - break; - case SingleTypeCode: - IsError = NumberValueCheck (P1FLT, Value); - break; - case DoubleTypeCode: - IsError = NumberValueCheck (P1DBL, Value); - break; - case StringTypeCode: - WARN_TYPE_MISMATCH; - return NULL; - /* break; */ - default: - WARN_TYPE_MISMATCH; - return NULL; - } - if (IsError != 0) - { - WARN_ILLEGAL_FUNCTION_CALL; - return argv; - } - variant.Number = Value; - if (var_set (argn, &variant) == FALSE) - { - WARN_VARIABLE_NOT_DECLARED; - return NULL; - } - } - source = source->next; - } - } - if (call_line->cmdnum == C_DEF) - { - VariantType x; - VariantType *X; - - X = &x; - CLEAR_VARIANT (X); - /* the function return variable is hidden */ - My->StackHead->local_variable = argv->next; - /* var_islocal() uses the LoopTopLine to find local variables */ - My->StackHead->LoopTopLine = call_line; /* FUNCTION, SUB */ - - /* evaluate the expression */ - if (line_read_expression (call_line, X) == FALSE) /* IntrinsicFunction_deffn */ - { - WARN_SYNTAX_ERROR; - goto EXIT; - } - - /* save the value */ - switch (X->VariantTypeCode) - { - case ByteTypeCode: - case IntegerTypeCode: - case LongTypeCode: - case CurrencyTypeCode: - case SingleTypeCode: - case DoubleTypeCode: - if (argv->VariableTypeCode == StringTypeCode) - { - WARN_TYPE_MISMATCH; - goto EXIT; - } - /* OK */ - { - int IsError; - double Value; - - IsError = 0; - Value = X->Number; - /* VerifyNumeric */ - if (isnan (Value)) - { - /*** FATAL - INTERNAL ERROR - SHOULD NEVER HAPPEN ***/ - WARN_INTERNAL_ERROR; - return FALSE; - } - if (isinf (Value)) - { - /* - Evaluation of an expression results in an overflow - * (nonfatal, the recommended recovery procedure is to supply - * machine in- finity with the algebraically correct sign and - * continue). */ - if (Value < 0) - { - Value = MINDBL; - } - else - { - Value = MAXDBL; - } - if (WARN_OVERFLOW) - { - /* ERROR */ - goto EXIT; - } - /* CONTINUE */ - } - /* OK */ - switch (argv->VariableTypeCode) - { - case ByteTypeCode: - IsError = NumberValueCheck (P1BYT, Value); - Value = bwb_rint (Value); - break; - case IntegerTypeCode: - IsError = NumberValueCheck (P1INT, Value); - Value = bwb_rint (Value); - break; - case LongTypeCode: - IsError = NumberValueCheck (P1LNG, Value); - Value = bwb_rint (Value); - break; - case CurrencyTypeCode: - IsError = NumberValueCheck (P1CUR, Value); - Value = bwb_rint (Value); - break; - case SingleTypeCode: - IsError = NumberValueCheck (P1FLT, Value); - break; - case DoubleTypeCode: - IsError = NumberValueCheck (P1DBL, Value); - break; - default: - WARN_TYPE_MISMATCH; - goto EXIT; - /* break; */ - } - if (IsError != 0) - { - if (WARN_OVERFLOW) - { - /* ERROR */ - goto EXIT; - } - /* CONTINUE */ - } - /* assign Value */ - RESULT_NUMBER = Value; - } - break; - case StringTypeCode: - if (argv->VariableTypeCode != StringTypeCode) - { - WARN_TYPE_MISMATCH; - goto EXIT; - } - /* OK */ - if (RESULT_BUFFER != My->MaxLenBuffer) - { - WARN_INTERNAL_ERROR; - goto EXIT; - } - if (X->Length > MAXLEN) - { - WARN_STRING_TOO_LONG; /* IntrinsicFunction_deffn */ - X->Length = MAXLEN; - } - bwb_memcpy (RESULT_BUFFER, X->Buffer, X->Length); - RESULT_LENGTH = X->Length; - break; - default: - WARN_TYPE_MISMATCH; - goto EXIT; - /* break; */ - } - EXIT: - RELEASE_VARIANT (X); - - - /* break variable chain */ - My->StackHead->local_variable = NULL; - - - -/* POP STACK */ - bwb_decexec (); - - } - else - { - /* the function return variable is visible */ - My->StackHead->local_variable = argv; - /* var_islocal() uses the LoopTopLine to find local variables */ - My->StackHead->LoopTopLine = call_line; /* FUNCTION, SUB */ - /* execute until function returns */ - while (My->StackHead != save_elevel) - { - bwb_execline (); - } - } - - if (f->ParameterCount == 0xFF) - { - /* VARIANT */ - f->local_variable = NULL; - } - - if (is_empty_string (argv->name) == FALSE) - { - int IsError; - - IsError = 0; - switch (argv->VariableTypeCode) - { - case ByteTypeCode: - IsError = NumberValueCheck (P1BYT, RESULT_NUMBER); - break; - case IntegerTypeCode: - IsError = NumberValueCheck (P1INT, RESULT_NUMBER); - break; - case LongTypeCode: - IsError = NumberValueCheck (P1LNG, RESULT_NUMBER); - break; - case CurrencyTypeCode: - IsError = NumberValueCheck (P1CUR, RESULT_NUMBER); - break; - case SingleTypeCode: - IsError = NumberValueCheck (P1FLT, RESULT_NUMBER); - break; - case DoubleTypeCode: - IsError = NumberValueCheck (P1DBL, RESULT_NUMBER); - break; - case StringTypeCode: - IsError = StringLengthCheck (P1ANY, RESULT_LENGTH); - break; - default: - /* no check */ - break; - } - if (IsError != 0) - { - if (WARN_OVERFLOW) - { - /* ERROR */ - } - /* CONTINUE */ - } - } - return argv; -} - -/*************************************************************** - - FUNCTION: IntrinsicFunction_find() - - DESCRIPTION: This C function attempts to locate - a BASIC function with the specified name. - If successful, it returns a pointer to - the C structure for the BASIC function, - if not successful, it returns NULL. - -***************************************************************/ - -extern int -IntrinsicFunction_name (char *name) -{ - /* search INTRINSIC functions */ - IntrinsicFunctionType *f; - int i; - - assert (name != NULL); - assert(My != NULL); - assert(My->CurrentVersion != NULL); - - -#if THE_PRICE_IS_RIGHT - /* start with the closest function, without going over */ - i = VarTypeIndex (name[0]); - if (i < 0) - { - /* non-alpha */ - return FALSE; - } - i = My->IntrinsicFunctionStart[i]; /* first function starting with this letter */ - if (i < 0) - { - /* NOT FOUND */ - return FALSE; - } -#else /* THE_PRICE_IS_RIGHT */ - i = 0; -#endif /* THE_PRICE_IS_RIGHT */ - for (; i < NUM_FUNCTIONS; i++) - { - f = &IntrinsicFunctionTable[i]; - if (My->CurrentVersion->OptionVersionValue & f->OptionVersionBitmask) - { - int result; - - result = bwb_stricmp (f->Name, name); - - if (result == 0) - { - /* FOUND */ - return TRUE; - } - if (result > 0 /* found > searched */ ) - { - /* NOT FOUND */ - return FALSE; - } - } - } - /* NOT FOUND */ - return FALSE; -} - - -IntrinsicFunctionType * -IntrinsicFunction_find_exact (char *name, int ParameterCount, - ParamBitsType ParameterTypes) -{ - IntrinsicFunctionType *f; - int i; - - assert (name != NULL); - assert(My != NULL); - assert(My->CurrentVersion != NULL); - - /* search INTRINSIC functions */ -#if THE_PRICE_IS_RIGHT - /* start with the closest function, without going over */ - i = VarTypeIndex (name[0]); - if (i < 0) - { - /* non-alpha */ - return NULL; - } - i = My->IntrinsicFunctionStart[i]; /* first function starting with this letter */ - if (i < 0) - { - /* NOT FOUND */ - return NULL; - } -#else /* THE_PRICE_IS_RIGHT */ - i = 0; -#endif /* THE_PRICE_IS_RIGHT */ - for (; i < NUM_FUNCTIONS; i++) - { - f = &IntrinsicFunctionTable[i]; - if (My->CurrentVersion->OptionVersionValue & f->OptionVersionBitmask) - { - if (f->ParameterCount == ParameterCount) - { - if (f->ParameterTypes == ParameterTypes) - { - int result; - - result = bwb_stricmp (f->Name, name); - - if (result == 0) - { - /* FOUND */ - return f; - } - if (result > 0 /* found > searched */ ) - { - /* NOT FOUND */ - return NULL; - } - } - } - } - } - /* NOT FOUND */ - return NULL; -} - -static VariableType * -find_variable_by_type (char *name, int dimensions, char VariableTypeCode) -{ - VariableType *v = NULL; - - assert (name != NULL); - - v = var_find (name, dimensions, FALSE); - if (v) - { - if (VAR_IS_STRING (v)) - { - if (VariableTypeCode == StringTypeCode) - { - /* found */ - return v; - } - } - else - { - if (VariableTypeCode != StringTypeCode) - { - /* found */ - return v; - } - } - } - /* not found */ - return NULL; -} - -/* --------------------------------------------------------------------------------------------- - CHANGE --------------------------------------------------------------------------------------------- -*/ - -LineType * -bwb_CHANGE (LineType * l) -{ - /* SYNTAX: CHANGE A$ TO X */ - /* SYNTAX: CHANGE X TO A$ */ - char varname[NameLengthMax + 1]; - VariableType *v; - VariableType *A; - VariableType *X; - int IsStringToArray; - - assert (l != NULL); - - v = NULL; - A = NULL; - X = NULL; - IsStringToArray = FALSE; - - /* get 1st variable */ - if (line_read_varname (l, varname) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - - v = find_variable_by_type (varname, 0, StringTypeCode); - if (v) - { - /* STRING to ARRAY */ - A = v; - IsStringToArray = TRUE; - } - else - { - /* ARRAY to STRING */ - v = find_variable_by_type (varname, 1, DoubleTypeCode); - if (v) - { - X = v; - IsStringToArray = FALSE; - } - } - if (v == NULL) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - - /* get "TO" */ - if (line_skip_word (l, "TO") == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - /* get 2nd variable */ - if (line_read_varname (l, varname) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - - if (IsStringToArray) - { - /* STRING to ARRAY */ - v = find_variable_by_type (varname, 1, DoubleTypeCode); - if (v == NULL) - { - v = var_find (varname, 1, TRUE); - } - if (v) - { - X = v; - } - } - else - { - /* ARRAY to STRING */ - v = find_variable_by_type (varname, 0, StringTypeCode); - if (v == NULL) - { - v = var_find (varname, 0, TRUE); - } - if (v) - { - A = v; - } - } - - if (v == NULL) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - assert(A != NULL); - assert(X != NULL); - if (IsStringToArray) - { - /* CHANGE A$ TO X */ - int i; - int n; - char *a; - DoubleType *x; - unsigned long t; - - if (A->Value.String == NULL) - { - WARN_INTERNAL_ERROR; - return (l); - } - if (A->Value.String->sbuffer == NULL) - { - WARN_INTERNAL_ERROR; - return (l); - } - /* variable storage is a mess, we bypass that tradition here. */ - t = 1; - for (n = 0; n < X->dimensions; n++) - { - t *= X->UBOUND[n] - X->LBOUND[n] + 1; - } - if (t <= A->Value.String->length) - { - WARN_SUBSCRIPT_OUT_OF_RANGE; - return (l); - } - n = A->Value.String->length; - a = A->Value.String->sbuffer; - x = X->Value.Number; - *x = n; - x++; - for (i = 0; i < n; i++) - { - char C; - DoubleType V; - - C = *a; - V = C; - *x = V; - x++; - a++; - } - } - else - { - /* CHANGE X TO A$ */ - int i; - int n; - char *a; - DoubleType *x; - unsigned long t; - - /* variable storage is a mess, we bypass that tradition here. */ - t = 1; - for (n = 0; n < X->dimensions; n++) - { - t *= X->UBOUND[n] - X->LBOUND[n] + 1; - } - if (t <= 1) - { - WARN_SUBSCRIPT_OUT_OF_RANGE; - return (l); - } - if (t > MAXLEN) - { - WARN_STRING_TOO_LONG; /* bwb_CHANGE */ - t = MAXLEN; - } - if (A->Value.String == NULL) - { - if ((A->Value.String = - (StringType *) calloc (1, sizeof (StringType))) == NULL) - { - WARN_OUT_OF_MEMORY; - return (l); - } - A->Value.String->sbuffer = NULL; - A->Value.String->length = 0; - } - if (A->Value.String->sbuffer != NULL) - { - free (A->Value.String->sbuffer); - A->Value.String->sbuffer = NULL; - A->Value.String->length = 0; - } - if (A->Value.String->sbuffer == NULL) - { - A->Value.String->length = 0; - if ((A->Value.String->sbuffer = - (char *) calloc (t + 1 /* NulChar */ , sizeof (char))) == NULL) - { - WARN_OUT_OF_MEMORY; - return (l); - } - } - a = A->Value.String->sbuffer; - x = X->Value.Number; - n = (int) bwb_rint (*x); - if (n > MAXLEN) - { - WARN_STRING_TOO_LONG; /* bwb_CHANGE */ - n = MAXLEN; - } - A->Value.String->length = n; - x++; - for (i = 0; i < n; i++) - { - char C; - DoubleType V; - - V = *x; - C = V; - *a = C; - x++; - a++; - } - } - return (l); -} - -/* --------------------------------------------------------------------------------------------- - CONSOLE --------------------------------------------------------------------------------------------- -*/ - -LineType * -bwb_CONSOLE (LineType * l) -{ - /* SYNTAX: CONSOLE */ - /* SYNTAX: CONSOLE WIDTH width */ - - assert (l != NULL); - assert(My != NULL); - assert(My->SYSPRN != NULL); - assert(My->SYSPRN->cfp != NULL); - assert(My->SYSOUT != NULL); - assert(My->SYSOUT->cfp != NULL); - - - if (My->IsPrinter == TRUE) - { - /* reset printer column */ - if (My->SYSPRN->col != 1) - { - fputc ('\n', My->SYSPRN->cfp); - My->SYSPRN->col = 1; - } - My->IsPrinter = FALSE; - } - if (line_skip_word (l, "WIDTH")) - { - int width; - - width = 0; - if (line_read_integer_expression (l, &width) == FALSE) - { - WARN_ILLEGAL_FUNCTION_CALL; - return (l); - } - if (width < 0) - { - WARN_ILLEGAL_FUNCTION_CALL; - return (l); - } - My->SYSOUT->width = width; - } - - return (l); -} - -/* --------------------------------------------------------------------------------------------- - LPRINTER --------------------------------------------------------------------------------------------- -*/ - - -LineType * -bwb_LPRINTER (LineType * l) -{ - /* SYNTAX: LPRINTER */ - /* SYNTAX: LPRINTER WIDTH width */ - - assert (l != NULL); - assert(My != NULL); - assert(My->SYSPRN != NULL); - assert(My->SYSPRN->cfp != NULL); - assert(My->SYSOUT != NULL); - assert(My->SYSOUT->cfp != NULL); - - - if (My->IsPrinter == FALSE) - { - /* reset console column */ - if (My->SYSOUT->col != 1) - { - fputc ('\n', My->SYSOUT->cfp); - My->SYSOUT->col = 1; - } - My->IsPrinter = TRUE; - } - if (line_skip_word (l, "WIDTH")) - { - int width; - - width = 0; - if (line_read_integer_expression (l, &width) == FALSE) - { - WARN_ILLEGAL_FUNCTION_CALL; - return (l); - } - if (width < 0) - { - WARN_ILLEGAL_FUNCTION_CALL; - return (l); - } - My->SYSPRN->width = width; - } - return (l); -} - -extern void -bwb_fclose (FILE * file) -{ - if (file == NULL) - { - /* don't close */ - } - else if (file == stdin) - { - /* don't close */ - } - else if (file == stdout) - { - /* don't close */ - } - else if (file == stderr) - { - /* don't close */ - } - else - { - fclose (file); - } -} -LineType * -bwb_LPT (LineType * l) -{ - /* SYNTAX: LPT */ - /* SYNTAX: LPT filename$ */ - FILE *file; - char *filename; - - assert (l != NULL); - assert(My != NULL); - assert(My->SYSOUT != NULL); - assert(My->SYSOUT->cfp != NULL); - - - file = NULL; - filename = NULL; - if (line_is_eol (l)) - { - /* OK */ - file = stderr; - } - else if (line_read_string_expression (l, &filename)) - { - /* OK */ - if (is_empty_string (filename)) - { - WARN_BAD_FILE_NAME; - return (l); - } - file = fopen (filename, "w"); - free (filename); - } - else - { - WARN_SYNTAX_ERROR; - return (l); - } - if (file == NULL) - { - WARN_BAD_FILE_NAME; - return (l); - } - bwb_fclose (My->SYSOUT->cfp); - My->SYSOUT->cfp = file; - return (l); -} - -LineType * -bwb_PTP (LineType * l) -{ - /* SYNTAX: PTP */ - /* SYNTAX: PTP filename$ */ - FILE *file; - char *filename; - - assert (l != NULL); - assert(My != NULL); - assert(My->SYSOUT != NULL); - assert(My->SYSOUT->cfp != NULL); - - file = NULL; - filename = NULL; - if (line_is_eol (l)) - { - /* OK */ - file = fopen ("PTP", "w"); - } - else if (line_read_string_expression (l, &filename)) - { - /* OK */ - if (is_empty_string (filename)) - { - WARN_BAD_FILE_NAME; - return (l); - } - file = fopen (filename, "w"); - free (filename); - } - else - { - WARN_SYNTAX_ERROR; - return (l); - } - if (file == NULL) - { - WARN_BAD_FILE_NAME; - return (l); - } - bwb_fclose (My->SYSOUT->cfp); - My->SYSOUT->cfp = file; - return (l); -} - -LineType * -bwb_PTR (LineType * l) -{ - /* SYNTAX: PTR */ - /* SYNTAX: PTR filename$ */ - FILE *file; - char *filename; - - assert (l != NULL); - assert(My != NULL); - assert(My->SYSIN != NULL); - assert(My->SYSIN->cfp != NULL); - - file = NULL; - filename = NULL; - if (line_is_eol (l)) - { - /* OK */ - file = fopen ("PTR", "r"); - } - else if (line_read_string_expression (l, &filename)) - { - /* OK */ - if (is_empty_string (filename)) - { - WARN_BAD_FILE_NAME; - return (l); - } - file = fopen (filename, "r"); - free (filename); - } - else - { - WARN_SYNTAX_ERROR; - return (l); - } - if (file == NULL) - { - WARN_BAD_FILE_NAME; - return (l); - } - bwb_fclose (My->SYSIN->cfp); - My->SYSIN->cfp = file; - return (l); -} - -LineType * -bwb_TTY (LineType * l) -{ - /* SYNTAX: TTY */ - assert (l != NULL); - - bwb_TTY_IN (l); - bwb_TTY_OUT (l); - return (l); -} - -LineType * -bwb_TTY_IN (LineType * l) -{ - /* SYNTAX: TTY IN */ - assert (l != NULL); - assert(My != NULL); - assert(My->SYSIN != NULL); - assert(My->SYSIN->cfp != NULL); - - bwb_fclose (My->SYSIN->cfp); - My->SYSIN->cfp = stdin; - return (l); -} - -LineType * -bwb_TTY_OUT (LineType * l) -{ - /* SYNTAX: TTY OUT */ - assert (l != NULL); - assert(My != NULL); - assert(My->SYSOUT != NULL); - assert(My->SYSOUT->cfp != NULL); - - bwb_fclose (My->SYSOUT->cfp); - My->SYSOUT->cfp = stdout; - return (l); -} - -/* --------------------------------------------------------------------------------------------- - CREATE --------------------------------------------------------------------------------------------- -*/ - -LineType * -bwb_CREATE (LineType * l) -{ - /* SYNTAX: CREATE filename$ [ RECL reclen ] AS filenum [ BUFF number ] [ RECS size ] */ - int FileNumber; - int width; - int buffnum; - int recsnum; - char *filename; - - assert (l != NULL); - assert(My != NULL); - - - FileNumber = 0; - width = 0; - buffnum = 0; - recsnum = 0; - filename = NULL; - if (line_read_string_expression (l, &filename) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (is_empty_string (filename)) - { - WARN_BAD_FILE_NAME; - return (l); - } - if (line_skip_word (l, "RECL")) - { - if (line_read_integer_expression (l, &width) == FALSE) - { - WARN_FIELD_OVERFLOW; - return (l); - } - if (width <= 0) - { - WARN_FIELD_OVERFLOW; - return (l); - } - } - if (line_skip_word (l, "AS") == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (line_read_integer_expression (l, &FileNumber) == FALSE) - { - WARN_BAD_FILE_NUMBER; - return (l); - } - if (FileNumber <= 0) - { - WARN_BAD_FILE_NUMBER; - return (l); - } - if (line_skip_word (l, "BUFF")) - { - if (line_read_integer_expression (l, &buffnum) == FALSE) - { - WARN_FIELD_OVERFLOW; - return (l); - } - if (buffnum <= 0) - { - WARN_FIELD_OVERFLOW; - return (l); - } - } - if (line_skip_word (l, "RECS")) - { - if (line_read_integer_expression (l, &recsnum) == FALSE) - { - WARN_FIELD_OVERFLOW; - return (l); - } - if (recsnum <= 0) - { - WARN_FIELD_OVERFLOW; - return (l); - } - } - /* now, we are ready to create the file */ - My->CurrentFile = find_file_by_number (FileNumber); - if (My->CurrentFile == NULL) - { - My->CurrentFile = file_new (); - My->CurrentFile->FileNumber = FileNumber; - } - if (My->CurrentFile->FileName != NULL) - { - free (My->CurrentFile->FileName); - My->CurrentFile->FileName = NULL; - } - My->CurrentFile->FileName = filename; - filename = NULL; - if (My->CurrentFile->DevMode != DEVMODE_CLOSED) - { - My->CurrentFile->DevMode = DEVMODE_CLOSED; - } - if (My->CurrentFile->cfp != NULL) - { - bwb_fclose (My->CurrentFile->cfp); - My->CurrentFile->cfp = NULL; - } - if (My->CurrentFile->buffer != NULL) - { - free (My->CurrentFile->buffer); - My->CurrentFile->buffer = NULL; - } - My->CurrentFile->width = 0; - My->CurrentFile->col = 1; - My->CurrentFile->row = 1; - My->CurrentFile->delimit = ','; - /* truncate to zero length or create text file for update (reading and writing) */ - if (is_empty_string (My->CurrentFile->FileName)) - { - WARN_BAD_FILE_NAME; - return (l); - } - if ((My->CurrentFile->cfp = - fopen (My->CurrentFile->FileName, "w+")) == NULL) - { - WARN_BAD_FILE_NAME; - return (l); - } - if (width > 0) - { - My->CurrentFile->width = width; - My->CurrentFile->DevMode = DEVMODE_RANDOM; - } - else - { - My->CurrentFile->DevMode = DEVMODE_INPUT | DEVMODE_OUTPUT; - } - return (l); -} - -/* --------------------------------------------------------------------------------------------- - COPY --------------------------------------------------------------------------------------------- -*/ - -static void -bwb_copy_file (char *Source, char *Target) -{ - FILE *source; - FILE *target; - - source = NULL; - target = NULL; - - if (is_empty_string (Source)) - { - WARN_BAD_FILE_NAME; - goto EXIT; - } - if (is_empty_string (Target)) - { - WARN_BAD_FILE_NAME; - goto EXIT; - } - source = fopen (Source, "rb"); - if (source == NULL) - { - WARN_BAD_FILE_NAME; - goto EXIT; - } - target = fopen (Target, "wb"); - if (target == NULL) - { - WARN_BAD_FILE_NAME; - goto EXIT; - } - /* OK */ - while (TRUE) - { - int C; - - C = fgetc (source); - if (C < 0 /* EOF */ || feof (source) || ferror (source)) - { - break; - } - fputc (C, target); - if (ferror (target)) - { - break; - } - } - /* DONE */ -EXIT: - if (source) - { - fclose (source); - } - if (target) - { - fclose (target); - } -} - -LineType * -bwb_COPY (LineType * Line) -{ - /* SYNTAX: COPY source$ TO target$ */ - char *Source; - char *Target; - - assert (Line != NULL); - - Source = NULL; - Target = NULL; - if (line_read_string_expression (Line, &Source) == FALSE) - { - WARN_SYNTAX_ERROR; - goto EXIT; - } - if (line_skip_word (Line, "TO") == FALSE) - { - WARN_SYNTAX_ERROR; - goto EXIT; - } - if (line_read_string_expression (Line, &Target) == FALSE) - { - WARN_SYNTAX_ERROR; - goto EXIT; - } - bwb_copy_file (Source, Target); -EXIT: - if (Source) - { - free (Source); - } - if (Target) - { - free (Target); - } - return (Line); -} - -/* --------------------------------------------------------------------------------------------- - DISPLAY --------------------------------------------------------------------------------------------- -*/ - -static void -bwb_display_file (char *Source) -{ - FILE *source; - - assert (My->SYSOUT != NULL); - assert (My->SYSOUT->cfp != NULL); - - source = NULL; - - if (is_empty_string (Source)) - { - WARN_BAD_FILE_NAME; - goto EXIT; - } - source = fopen (Source, "rb"); - if (source == NULL) - { - WARN_BAD_FILE_NAME; - goto EXIT; - } - /* OK */ - while (TRUE) - { - int C; - - C = fgetc (source); - if (C < 0 /* EOF */ || feof (source) || ferror (source)) - { - break; - } - fputc (C, My->SYSOUT->cfp); - } - /* DONE */ -EXIT: - if (source) - { - fclose (source); - } -} - -LineType * -bwb_DISPLAY (LineType * Line) -{ - /* SYNTAX: DISPLAY source$ */ - char *Source; - - assert (Line != NULL); - Source = NULL; - if (line_read_string_expression (Line, &Source) == FALSE) - { - WARN_SYNTAX_ERROR; - goto EXIT; - } - bwb_display_file (Source); -EXIT: - if (Source) - { - free (Source); - } - return (Line); -} - -/* --------------------------------------------------------------------------------------------- - EOF --------------------------------------------------------------------------------------------- -*/ - - - -/* EOF */ diff --git a/Junk/bwb_var.c b/Junk/bwb_var.c deleted file mode 100644 index 2e90020..0000000 --- a/Junk/bwb_var.c +++ /dev/null @@ -1,5068 +0,0 @@ -/*************************************************************** - - bwb_var.c Variable-Handling 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. - -***************************************************************/ - -/*---------------------------------------------------------------*/ -/* NOTE: Modifications marked "JBV" were made by Jon B. Volkoff, */ -/* 11/1995 (eidetics@cerf.net). */ -/* */ -/* Those additionally marked with "DD" were at the suggestion of */ -/* Dale DePriest (daled@cadence.com). */ -/* */ -/* Version 3.00 by Howard Wulf, AF5NE */ -/* */ -/* Version 3.10 by Howard Wulf, AF5NE */ -/* */ -/* Version 3.20 by Howard Wulf, AF5NE */ -/* */ -/*---------------------------------------------------------------*/ - - - -#include "bwbasic.h" - - -/* Prototypes for functions visible to this file only */ - -static void clear_virtual (VirtualType * Z); -static void clear_virtual_by_variable (VariableType * Variable); -static int dim_check (VariableType * variable); -static size_t dim_unit (VariableType * v, int *pp); -static LineType *dio_lrset (LineType * l, int rset); -static void field_clear (FieldType * Field); -static FieldType *field_new (void); -static VirtualType *find_virtual_by_variable (VariableType * Variable); -static LineType *internal_swap (LineType * l); -static VariableType *mat_islocal (char *buffer); -static VirtualType *new_virtual (void); -static int var_defx (LineType * l, int TypeCode); -static VariableType *var_islocal (char *buffer, int dimensions); -static void var_link_new_variable (VariableType * v); - -extern int -var_init (void) -{ - assert( My != NULL ); - - My->VariableHead = NULL; - - return TRUE; -} - -extern LineType * -bwb_COMMON (LineType * l) -{ - /* - SYNTAX: COMMON scalar - SYNTAX: COMMON matrix( dimnesions ) ' COMMON A(1), B(2), C(3) - SYNTAX: COMMON matrix( [, [,]] ) ' COMMON A(), B(,), C(,,) - */ - - assert (l != NULL); - - do - { - int dimensions; - VariableType *variable; - char varname[NameLengthMax + 1]; - - dimensions = 0; - /* get variable name and find variable */ - if (line_read_varname (l, varname) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (line_skip_LparenChar (l)) - { - line_skip_spaces (l); /* keep this */ - if (bwb_isdigit (l->buffer[l->position])) - { - /* COMMON A(3) : DIM A( 5, 10, 20 ) */ - if (line_read_integer_expression (l, &dimensions) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - } - else - { - /* COMMON A(,,) : DIM A( 5, 10, 20 ) */ - dimensions++; - while (line_skip_seperator (l)) - { - dimensions++; - } - } - if (line_skip_RparenChar (l) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - } - if ((variable = var_find (varname, dimensions, TRUE)) == NULL) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - - /* mark as COMMON */ - variable->VariableFlags |= VARIABLE_COMMON; - } - while (line_skip_seperator (l)); - - return (l); -} - -extern LineType * -bwb_ERASE (LineType * l) -{ - /* - SYNTAX: ERASE variable [, ...] ' ERASE A, B, C - */ - - assert (l != NULL); - assert( My != NULL ); - - do - { - char varname[NameLengthMax + 1]; - - /* get variable name and find variable */ - - if (line_read_varname (l, varname)) - { - /* erase all matching SCALAR and ARRAY variables */ - int dimensions; - - for (dimensions = 0; dimensions < MAX_DIMS; dimensions++) - { - VariableType *variable; - - variable = var_find (varname, dimensions, FALSE); - if (variable != NULL) - { - /* found a variable */ - VariableType *p; /* previous variable in linked list */ - - /* find then previous variable in chain */ - if (variable == My->VariableHead) - { - /* free head */ - My->VariableHead = variable->next; - variable->next = NULL; - var_free (variable); - } - else - { - /* free tail */ - for (p = My->VariableHead; p != NULL && p->next != variable; - p = p->next) - { - ; - } - if (p == NULL) - { - /* this should never happen */ - WARN_INTERNAL_ERROR; - return NULL; - } - if (p->next != variable) - { - /* this should never happen */ - WARN_INTERNAL_ERROR; - return NULL; - } - /* reassign linkage */ - p->next = variable->next; - variable->next = NULL; - var_free (variable); - } - } - } - } - } - while (line_skip_seperator (l)); - return (l); -} - -static LineType * -internal_swap (LineType * l) -{ - VariableType *lhs; - VariableType *rhs; - - assert (l != NULL); - - if (line_skip_LparenChar (l)) - { - /* optional */ - } - - /* get left variable */ - if ((lhs = line_read_scalar (l)) == NULL) - { - WARN_SYNTAX_ERROR; - return (l); - } - - /* get required comma */ - if (line_skip_seperator (l) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - - /* get right variable */ - if ((rhs = line_read_scalar (l)) == NULL) - { - WARN_SYNTAX_ERROR; - return (l); - } - - if (line_skip_RparenChar (l)) - { - /* optional */ - } - - /* check to be sure that both variables are compatible */ - if (VAR_IS_STRING (rhs) != VAR_IS_STRING (lhs)) - { - WARN_TYPE_MISMATCH; - return (l); - } - - /* swap the values */ - { - VariantType L; - VariantType R; - CLEAR_VARIANT (&L); - CLEAR_VARIANT (&R); - - if (var_get (lhs, &L) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (var_get (rhs, &R) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - - if (var_set (lhs, &R) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (var_set (rhs, &L) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - } - /* return */ - return (l); -} - -extern LineType * -bwb_EXCHANGE (LineType * l) -{ - /* - SYNTAX: EXCHANGE variable, variable - SYNTAX: EXCHANGE ( variable, variable ) - */ - - assert (l != NULL); - return internal_swap (l); -} - - - -extern LineType * -bwb_SWAP (LineType * l) -{ - /* - SYNTAX: SWAP variable, variable - SYNTAX: SWAP ( variable, variable ) - */ - - assert (l != NULL); - return internal_swap (l); -} - -extern VariableType * -var_free (VariableType * variable) -{ - /* - Release all the memory associated with a specific variable. - This function returns NULL, so you can use it like this: - variable = var_new(...); - ... - variable = var_free( variable ); - */ - - - if (variable != NULL) - { - if (variable->next != NULL) - { - /* This allows variable chains to be easily released. */ - variable->next = var_free (variable->next); - } - /* cleanup this variable */ - field_free_variable (variable); - clear_virtual_by_variable (variable); - if (VAR_IS_STRING (variable)) - { - if (variable->Value.String != NULL) - { - int j; - for (j = 0; j < variable->array_units; j++) - { - if (variable->Value.String[j].sbuffer != NULL) - { - free (variable->Value.String[j].sbuffer); - } - variable->Value.String[j].length = 0; - } - free (variable->Value.String); - variable->Value.String = NULL; - } - } - else - { - if (variable->Value.Number != NULL) - { - free (variable->Value.Number); - variable->Value.Number = NULL; - } - } - free (variable); - } - return NULL; -} - -extern void -var_CLEAR (void) -{ - /* - free all variables except PRESET - */ - VariableType *variable; - assert( My != NULL ); - - - for (variable = My->VariableHead; variable != NULL;) - { - if (variable->VariableFlags & VARIABLE_PRESET) - { - /* keep */ - variable = variable->next; - } - else if (variable == My->VariableHead) - { - /* free head */ - My->VariableHead = variable->next; - variable->next = NULL; - var_free (variable); - variable = My->VariableHead; - } - else - { - /* free tail */ - VariableType *z; - z = variable->next; - variable->next = NULL; - var_free (variable); - variable = z; - } - } -} - -extern LineType * -bwb_CLEAR (LineType * l) -{ - /* - SYNTAX: CLEAR - */ - - assert (l != NULL); - var_CLEAR (); - line_skip_eol (l); - return (l); -} - - -LineType * -bwb_CLR (LineType * l) -{ - - assert (l != NULL); - return bwb_CLEAR (l); -} - -/*********************************************************** - - FUNCTION: var_delcvars() - - DESCRIPTION: This function deletes all variables - in memory except those previously marked - as common. - -***********************************************************/ - -int -var_delcvars (void) -{ - VariableType *v; - - assert( My != NULL ); - - for (v = My->VariableHead; v != NULL;) - { - if (v->VariableFlags & VARIABLE_PRESET) - { - /* keep */ - v = v->next; - } - else if (v->VariableFlags & VARIABLE_COMMON) - { - /* keep */ - v = v->next; - } - else if (v == My->VariableHead) - { - /* free head */ - My->VariableHead = v->next; - v->next = NULL; - var_free (v); - v = My->VariableHead; - } - else - { - /* free tail */ - VariableType *z; /* next variable */ - - z = v->next; - v->next = NULL; - var_free (v); - v = z; - } - } - return TRUE; -} - -/*********************************************************** - - FUNCTION: bwb_mid() - - DESCRIPTION: This function implements the BASIC - MID$ command. - - Same as MID$ function, except it will set - the desired substring and not return its - value. Added by JBV 10/95 - - SYNTAX: MID$( string-variable$, start-position-in-string - [, number-of-spaces ] ) = expression - -***********************************************************/ - -LineType * -bwb_MID4 (LineType * l) -{ - /* MID$( target$, start% [ , length% ] ) = source$ */ - VariableType *variable; - VariantType target; - int start; - int length; - VariantType source; - int maxlen; - - assert (l != NULL); - - CLEAR_VARIANT (&source); - CLEAR_VARIANT (&target); - start = 0; - length = 0; - maxlen = 0; - if (line_skip_LparenChar (l) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - if ((variable = line_read_scalar (l)) == NULL) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (VAR_IS_STRING (variable)) - { - /* OK */ - } - else - { - /* ERROR */ - WARN_TYPE_MISMATCH; - return (l); - } - if (var_get (variable, &target) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (target.VariantTypeCode != StringTypeCode) - { - WARN_TYPE_MISMATCH; - return (l); - } - if (line_skip_seperator (l) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (line_read_integer_expression (l, &start) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (start < 1) - { - WARN_ILLEGAL_FUNCTION_CALL; - return (l); - } - if (start > target.Length) - { - WARN_ILLEGAL_FUNCTION_CALL; - return (l); - } - maxlen = 1 + target.Length - start; - if (line_skip_seperator (l)) - { - if (line_read_integer_expression (l, &length) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (length < 0) - { - WARN_ILLEGAL_FUNCTION_CALL; - return (l); - } - } - else - { - length = -1; /* MAGIC */ - } - if (line_skip_RparenChar (l) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - /* skip the equal sign */ - if (line_skip_EqualChar (l) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (line_read_expression (l, &source) == FALSE) /* bwb_MID4 */ - { - WARN_SYNTAX_ERROR; - return (l); - } - if (source.VariantTypeCode != StringTypeCode) - { - WARN_TYPE_MISMATCH; - return (l); - } - if (length == -1 /* MAGIC */ ) - { - length = source.Length; - } - length = MIN (length, maxlen); - length = MIN (length, source.Length); - if (length < 0) - { - WARN_INTERNAL_ERROR; - return (l); - } - if (length > 0) - { - int i; - - start--; /* BASIC to C */ - for (i = 0; i < length; i++) - { - target.Buffer[start + i] = source.Buffer[i]; - } - target.Buffer[target.Length] = NulChar; - if (var_set (variable, &target) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - } - RELEASE_VARIANT (&source); - RELEASE_VARIANT (&target); - return (l); -} - - -/*********************************************************** - - FUNCTION: bwb_ddbl() - - DESCRIPTION: This function implements the BASIC - DEFDBL command. - - SYNTAX: DEFDBL letter[-letter](, letter[-letter])... - -***********************************************************/ - -LineType * -bwb_DEFBYT (LineType * l) -{ - /* - DEFBYT letter[-letter](, letter[-letter])... - */ - - assert (l != NULL); - var_defx (l, ByteTypeCode); - return (l); -} - -LineType * -bwb_DEFCUR (LineType * l) -{ - /* - DEFCUR letter[-letter](, letter[-letter])... - */ - - assert (l != NULL); - var_defx (l, CurrencyTypeCode); - return (l); -} - -LineType * -bwb_DEFDBL (LineType * l) -{ - /* - DEFDBL letter[-letter](, letter[-letter])... - */ - - assert (l != NULL); - var_defx (l, DoubleTypeCode); - return (l); -} - -/*********************************************************** - - FUNCTION: bwb_dint() - - DESCRIPTION: This function implements the BASIC - DEFINT command. - - SYNTAX: DEFINT letter[-letter](, letter[-letter])... - -***********************************************************/ - -LineType * -bwb_DEFINT (LineType * l) -{ - /* - DEFINT letter[-letter](, letter[-letter])... - */ - - assert (l != NULL); - var_defx (l, IntegerTypeCode); - return (l); -} - -LineType * -bwb_DEFLNG (LineType * l) -{ - /* - DEFLNG letter[-letter](, letter[-letter])... - */ - - assert (l != NULL); - var_defx (l, LongTypeCode); - return (l); -} - -/*********************************************************** - - FUNCTION: bwb_dsng() - - DESCRIPTION: This function implements the BASIC - DEFSNG command. - - SYNTAX: DEFSNG letter[-letter](, letter[-letter])... - -***********************************************************/ - -LineType * -bwb_DEFSNG (LineType * l) -{ - /* - DEFSNG letter[-letter](, letter[-letter])... - */ - - assert (l != NULL); - var_defx (l, SingleTypeCode); - return (l); -} - -/*********************************************************** - - FUNCTION: bwb_dstr() - - DESCRIPTION: This function implements the BASIC - DEFSTR command. - - SYNTAX: DEFSTR letter[-letter](, letter[-letter])... - -***********************************************************/ - -LineType * -bwb_DEFSTR (LineType * l) -{ - /* - DEFSTR letter[-letter](, letter[-letter])... - */ - - assert (l != NULL); - var_defx (l, StringTypeCode); - return (l); -} - -LineType * -bwb_TEXT (LineType * l) -{ - /* - TEXT letter[-letter](, letter[-letter])... - */ - - assert (l != NULL); - var_defx (l, StringTypeCode); - return (l); -} - -LineType * -bwb_TRACE (LineType * l) -{ - assert (l != NULL); - - return bwb_TRACE_ON(l); -} - -LineType * -bwb_TRACE_ON (LineType * l) -{ - assert (l != NULL); - assert( My != NULL ); - assert( My->SYSOUT != NULL ); - assert( My->SYSOUT->cfp != NULL ); - - fprintf (My->SYSOUT->cfp, "Trace is ON\n"); - ResetConsoleColumn (); - My->IsTraceOn = TRUE; - - return (l); -} - -LineType * -bwb_TRACE_OFF (LineType * l) -{ - - assert (l != NULL); - assert( My != NULL ); - assert( My->SYSOUT != NULL ); - assert( My->SYSOUT->cfp != NULL ); - - fprintf (My->SYSOUT->cfp, "Trace is OFF\n"); - ResetConsoleColumn (); - My->IsTraceOn = FALSE; - - return (l); -} - -int -VarTypeIndex (char C) -{ - - switch (C) - { - case 'A': - return 0; - case 'B': - return 1; - case 'C': - return 2; - case 'D': - return 3; - case 'E': - return 4; - case 'F': - return 5; - case 'G': - return 6; - case 'H': - return 7; - case 'I': - return 8; - case 'J': - return 9; - case 'K': - return 10; - case 'L': - return 11; - case 'M': - return 12; - case 'N': - return 13; - case 'O': - return 14; - case 'P': - return 15; - case 'Q': - return 16; - case 'R': - return 17; - case 'S': - return 18; - case 'T': - return 19; - case 'U': - return 20; - case 'V': - return 21; - case 'W': - return 22; - case 'X': - return 23; - case 'Y': - return 24; - case 'Z': - return 25; - case 'a': - return 0; - case 'b': - return 1; - case 'c': - return 2; - case 'd': - return 3; - case 'e': - return 4; - case 'f': - return 5; - case 'g': - return 6; - case 'h': - return 7; - case 'i': - return 8; - case 'j': - return 9; - case 'k': - return 10; - case 'l': - return 11; - case 'm': - return 12; - case 'n': - return 13; - case 'o': - return 14; - case 'p': - return 15; - case 'q': - return 16; - case 'r': - return 17; - case 's': - return 18; - case 't': - return 19; - case 'u': - return 20; - case 'v': - return 21; - case 'w': - return 22; - case 'x': - return 23; - case 'y': - return 24; - case 'z': - return 25; - } - return -1; -} - -/*********************************************************** - - Function: var_defx() - - DESCRIPTION: This function is a generalized DEFxxx handler. - -***********************************************************/ - -static int -var_defx (LineType * l, int TypeCode) -{ - /* - DEFxxx letter[-letter](, letter[-letter])... - */ - - assert (l != NULL); - assert( My != NULL ); - assert( My->DefaultVariableType != NULL ); - - do - { - char firstc; - char lastc; - int first; - int last; - int c; - - /* find a sequence of letters for variables */ - if (line_read_letter_sequence (l, &firstc, &lastc) == FALSE) - { - /* DEFINT 0-9 */ - WARN_SYNTAX_ERROR; - return FALSE; - } - first = VarTypeIndex (firstc); - if (first < 0) - { - /* DEFINT 0-Z */ - WARN_SYNTAX_ERROR; - return FALSE; - } - last = VarTypeIndex (lastc); - if (last < 0) - { - /* DEFINT A-9 */ - WARN_SYNTAX_ERROR; - return FALSE; - } - if (first > last) - { - /* DEFINT Z-A */ - WARN_SYNTAX_ERROR; - return FALSE; - } - for (c = first; c <= last; c++) - { - My->DefaultVariableType[c] = TypeCode; /* var_defx */ - } - } - while (line_skip_seperator (l)); - - return TRUE; - -} - -/*************************************************************** - - FUNCTION: var_find() - - DESCRIPTION: This C function attempts to find a variable - name matching the argument in buffer. If - it fails to find a matching name, it - sets up a new variable with that name. - -***************************************************************/ - -VariableType * -mat_find (char *name) -{ - /* - similar to var_find, but returns the first matrix found - */ - VariableType *v; - assert( My != NULL ); - - - /* check for NULL variable name */ - if (name == NULL) - { - WARN_INTERNAL_ERROR; - return NULL; - } - if (is_empty_string (name)) - { - WARN_SYNTAX_ERROR; - return NULL; - } - /* check for a local variable at this EXEC level */ - - v = mat_islocal (name); - if (v != NULL) - { - return v; - } - /* now run through the global variable list and try to find a match */ - for (v = My->VariableHead; v != NULL; v = v->next) - { - assert( v != NULL ); - if (v->dimensions > 0) - { - if (bwb_stricmp (v->name, name) == 0) - { - return v; - } - } - } - return NULL; -} - -VariableType * -var_find (char *name, int dimensions, int IsImplicit) -{ - VariableType *v; - int n; - - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - assert( My->DefaultVariableType != NULL ); - - /* check for NULL variable name */ - if (name == NULL) - { - WARN_INTERNAL_ERROR; - return NULL; - } - if (is_empty_string (name)) - { - WARN_SYNTAX_ERROR; - return NULL; - } - if (dimensions < 0) - { - WARN_INTERNAL_ERROR; - return NULL; - } - - /* check for a local variable at this EXEC level */ - - v = var_islocal (name, dimensions); - if (v != NULL) - { - return v; - } - /* now run through the global variable list and try to find a match */ - for (v = My->VariableHead; v != NULL; v = v->next) - { - assert( v != NULL ); - if (v->dimensions == dimensions) - { - if (bwb_stricmp (v->name, name) == 0) - { - return v; - } - } - } - if (IsImplicit == FALSE) - { - return NULL; - } - if (My->CurrentVersion->OptionFlags & OPTION_EXPLICIT_ON) - { - /* NO implicit creation - all variables must be created via DIM */ - WARN_VARIABLE_NOT_DECLARED; - return NULL; - } - if (My->CurrentVersion->OptionFlags & OPTION_STRICT_ON) - { - if (dimensions > 0) - { - /* Implicit ARRAY is not allowed */ - WARN_VARIABLE_NOT_DECLARED; - return NULL; - } - } - - /* this is a IMPLICIT variable, so initialize it... */ - - /* initialize new variable */ - if ((v = (VariableType *) calloc (1, sizeof (VariableType))) == NULL) - { - WARN_OUT_OF_MEMORY; - return NULL; - } - - /* copy the name into the appropriate structure */ - - assert( v != NULL ); - bwb_strcpy (v->name, name); - - /* determine variable TypeCode */ - v->VariableTypeCode = var_nametype (name); - if (v->VariableTypeCode == NulChar) - { - /* variable name has no declared TypeCode */ - n = VarTypeIndex (name[0]); - if (n < 0) - { - v->VariableTypeCode = DoubleTypeCode; /* default */ - } - else - { - v->VariableTypeCode = My->DefaultVariableType[n]; - } - } - v->VariableFlags = 0; - v->dimensions = dimensions; - v->array_units = 1; - for (n = 0; n < v->dimensions; n++) - { - v->LBOUND[n] = My->CurrentVersion->OptionBaseInteger; /* implicit lower bound */ - v->UBOUND[n] = 10; /* implicit upper bound */ - if (v->UBOUND[n] < v->LBOUND[n]) - { - WARN_SUBSCRIPT_OUT_OF_RANGE; - return NULL; - } - v->VINDEX[n] = v->LBOUND[n]; - v->array_units *= v->UBOUND[n] - v->LBOUND[n] + 1; - } - - /* assign array memory */ - if (VAR_IS_STRING (v)) - { - if ((v->Value.String = - (StringType *) calloc (v->array_units, sizeof (StringType))) == NULL) - { - WARN_OUT_OF_MEMORY; - return NULL; - } - } - else - { - if ((v->Value.Number = - (DoubleType *) calloc (v->array_units, sizeof (DoubleType))) == NULL) - { - WARN_OUT_OF_MEMORY; - return NULL; - } - } - - /* insert variable at the beginning of the variable chain */ - v->next = My->VariableHead; - My->VariableHead = v; - return v; -} - -/*************************************************************** - - FUNCTION: var_new() - - DESCRIPTION: This function assigns memory for a new variable. - -***************************************************************/ - -VariableType * -var_new (char *name, char TypeCode) -{ - VariableType *v; - - - /* get memory for new variable */ - - if (name == NULL) - { - WARN_INTERNAL_ERROR; - return NULL; - } - if (is_empty_string (name)) - { - WARN_SYNTAX_ERROR; - return NULL; - } - if ((v = (VariableType *) calloc (1, sizeof (VariableType))) == NULL) - { - WARN_OUT_OF_MEMORY; - return NULL; - } - /* copy the name into the appropriate structure */ - - assert( v != NULL ); - bwb_strcpy (v->name, name); - - /* set memory in the new variable */ - var_make (v, TypeCode); - - /* and return */ - - return v; - -} - - -/*************************************************************** - - FUNCTION: bwb_dim() - - DESCRIPTION: This function implements the BASIC DIM - statement, allocating memory for a - dimensioned array of variables. - - SYNTAX: DIM variable(elements...)[,variable(elements...)] - -***************************************************************/ - -static void -var_link_new_variable (VariableType * v) -{ - /* - We are called by DIM, so this is an explicitly created variable. - There are only two possibilities: - 1. We are a LOCAL variable of a SUB or FUNCTION. - 2. We are a GLOBAL variable. - */ - - assert (v != NULL); - assert( My != NULL ); - - if (My->StackHead != NULL) - { - StackType *StackItem; - for (StackItem = My->StackHead; StackItem != NULL; - StackItem = StackItem->next) - { - if (StackItem->LoopTopLine != NULL) - { - switch (StackItem->LoopTopLine->cmdnum) - { - case C_FUNCTION: - case C_SUB: - /* we have found a FUNCTION or SUB boundary, must be LOCAL */ - v->next = StackItem->local_variable; - StackItem->local_variable = v; - return; - /* break; */ - } - } - } - } - /* no FUNCTION or SUB on the stack, must be GLOBAL */ - v->next = My->VariableHead; - My->VariableHead = v; -} - - -static VirtualType * -new_virtual (void) -{ - VirtualType *Z; - assert( My != NULL ); - - - /* look for an empty slot */ - for (Z = My->VirtualHead; Z != NULL; Z = Z->next) - { - if (Z->Variable == NULL) - { - /* FOUND */ - return Z; - } - } - /* NOT FOUND */ - if ((Z = (VirtualType *) calloc (1, sizeof (VirtualType))) == NULL) - { - WARN_OUT_OF_MEMORY; - return NULL; - } - Z->next = My->VirtualHead; - My->VirtualHead = Z; - return Z; -} -static void -clear_virtual (VirtualType * Z) -{ - - assert (Z != NULL); - - Z->Variable = NULL; - Z->FileNumber = 0; - Z->FileOffset = 0; - Z->FileLength = 0; -} -static void -clear_virtual_by_variable (VariableType * Variable) -{ - VirtualType *Z; - - assert (Variable != NULL); - assert( My != NULL ); - - for (Z = My->VirtualHead; Z != NULL; Z = Z->next) - { - if (Z->Variable == Variable) - { - /* FOUND */ - clear_virtual (Z); - } - } -} -extern void -clear_virtual_by_file (int FileNumber) -{ - /* called by file_clear() */ - VirtualType *Z; - - assert( My != NULL ); - - for (Z = My->VirtualHead; Z != NULL; Z = Z->next) - { - if (Z->FileNumber == FileNumber) - { - /* FOUND */ - clear_virtual (Z); - } - } -} -static VirtualType * -find_virtual_by_variable (VariableType * Variable) -{ - VirtualType *Z; - - assert (Variable != NULL); - assert( My != NULL ); - - for (Z = My->VirtualHead; Z != NULL; Z = Z->next) - { - if (Z->Variable == Variable) - { - /* FOUND */ - return Z; - } - } - /* NOT FOUND */ - return NULL; -} - -LineType * -bwb_LOCAL (LineType * l) -{ - /* only supported inside a FUNCTION or SUB */ - - assert (l != NULL); - return bwb_DIM (l); -} - -LineType * -bwb_DIM (LineType * l) -{ - int FileNumber; /* the file might not be OPEN when the variable is declared */ - size_t FileOffset; /* from beginning of file */ - int FileLength; /* sizeof( DoubleType ) or Fixed String Length */ - - assert (l != NULL); - assert( My != NULL ); - assert( My->DefaultVariableType != NULL ); - - - FileNumber = 0; - FileOffset = 0; - FileLength = 0; - if (line_skip_FilenumChar (l)) - { - /* DIM # filenum , ... */ - if (line_read_integer_expression (l, &FileNumber) == FALSE) - { - WARN_BAD_FILE_NUMBER; - return (l); - } - if (FileNumber <= 0) - { - WARN_BAD_FILE_NUMBER; - return (l); - } - if (line_skip_seperator (l) == FALSE) - { - WARN_BAD_FILE_NUMBER; - return (l); - } - FileOffset = 0; - FileLength = 0; - } - - do - { - VariableType *v; - int n; - int dimensions; - int LBOUND[MAX_DIMS]; - int UBOUND[MAX_DIMS]; - char TypeCode; - char varname[NameLengthMax + 1]; - - - /* Get variable name */ - if (line_read_varname (l, varname) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - - /* read parameters */ - dimensions = 0; - if (line_peek_LparenChar (l)) - { - if (line_read_array_redim (l, &dimensions, LBOUND, UBOUND) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - /* check array dimensions */ - for (n = 0; n < dimensions; n++) - { - if (UBOUND[n] < LBOUND[n]) - { - WARN_SUBSCRIPT_OUT_OF_RANGE; - return (l); - } - } - } - - /* determine variable TypeCode */ - TypeCode = var_nametype (varname); - if (TypeCode == NulChar) - { - /* variable has no explicit TypeCode char */ - TypeCode = line_read_type_declaration (l); /* AS DOUBLE and so on */ - if (TypeCode == NulChar) - { - /* variable has no declared TypeCode */ - int i; - i = VarTypeIndex (varname[0]); - if (i < 0) - { - TypeCode = DoubleTypeCode; /* default */ - } - else - { - TypeCode = My->DefaultVariableType[i]; - } - } - } - - switch (TypeCode) - { - case ByteTypeCode: - /* DIM # file_num , var_name AS BYTE */ - FileLength = sizeof (ByteType); - break; - case IntegerTypeCode: - /* DIM # file_num , var_name AS INTEGER */ - FileLength = sizeof (IntegerType); - break; - case LongTypeCode: - /* DIM # file_num , var_name AS LONG */ - FileLength = sizeof (LongType); - break; - case CurrencyTypeCode: - /* DIM # file_num , var_name AS CURRENCY */ - FileLength = sizeof (CurrencyType); - break; - case SingleTypeCode: - /* DIM # file_num , var_name AS SINGLE */ - FileLength = sizeof (SingleType); - break; - case DoubleTypeCode: - /* DIM # file_num , var_name AS DOUBLE */ - FileLength = sizeof (DoubleType); - break; - case StringTypeCode: - /* DIM # file_num , var_name AS STRING * fixed_length */ - - FileLength = 16; /* default */ - if (line_skip_StarChar (l) || line_skip_EqualChar (l)) - { - /* optional fixed length */ - if (line_read_integer_expression (l, &FileLength) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (FileLength <= 0) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (FileLength > MAXLEN) - { - WARN_STRING_TOO_LONG; /* bwb_DIM */ - FileLength = MAXLEN; - } - } - break; - default: - { - WARN_INTERNAL_ERROR; - return (l); - } - } - - v = var_find (varname, dimensions, FALSE); - if (v == NULL) - { - /* a new variable */ - if ((v = (VariableType *) calloc (1, sizeof (VariableType))) == NULL) - { - WARN_OUT_OF_MEMORY; - return (l); - } - bwb_strcpy (v->name, varname); - v->VariableTypeCode = TypeCode; - /* assign array dimensions */ - v->dimensions = dimensions; - for (n = 0; n < dimensions; n++) - { - v->LBOUND[n] = LBOUND[n]; - v->UBOUND[n] = UBOUND[n]; - } - /* assign initial array position */ - for (n = 0; n < dimensions; n++) - { - v->VINDEX[n] = v->LBOUND[n]; - } - /* calculate the array size */ - v->array_units = 1; - for (n = 0; n < dimensions; n++) - { - v->array_units *= v->UBOUND[n] - v->LBOUND[n] + 1; - } - /* assign array memory */ - - if (FileNumber > 0) - { - /* the new variable is VIRTUAL */ - v->VariableFlags = VARIABLE_VIRTUAL; - /* if( TRUE ) */ - { - /* OK */ - VirtualType *Z; - Z = find_virtual_by_variable (v); - if (Z == NULL) - { - Z = new_virtual (); - if (Z == NULL) - { - WARN_OUT_OF_MEMORY; - return (l); - } - Z->Variable = v; - } - /* update file information */ - Z->FileNumber = FileNumber; - Z->FileOffset = FileOffset; - Z->FileLength = FileLength; - FileOffset += FileLength * v->array_units; - } - } - else if (VAR_IS_STRING (v)) - { - if ((v->Value.String = - (StringType *) calloc (v->array_units, - sizeof (StringType))) == NULL) - { - WARN_OUT_OF_MEMORY; - return (l); - } - } - else - { - if ((v->Value.Number = - (DoubleType *) calloc (v->array_units, - sizeof (DoubleType))) == NULL) - { - WARN_OUT_OF_MEMORY; - return (l); - } - } - /* set place at beginning of variable chain */ - var_link_new_variable (v); - - /* end of conditional for new variable */ - } - else - { - /* old variable */ - if (v->VariableTypeCode != TypeCode) - { - WARN_TYPE_MISMATCH; - return (l); - } - - /* check to be sure the number of dimensions is the same */ - if (v->dimensions != dimensions) - { - WARN_REDIMENSION_ARRAY; - return (l); - } - /* check to be sure sizes for each dimension are the same */ - for (n = 0; n < dimensions; n++) - { - if (v->LBOUND[n] != LBOUND[n]) - { - WARN_REDIMENSION_ARRAY; - return (l); - } - if (v->UBOUND[n] != UBOUND[n]) - { - WARN_REDIMENSION_ARRAY; - return (l); - } - } - if (FileNumber > 0) - { - /* the existing variable MUST be Virtual */ - if (v->VariableFlags & VARIABLE_VIRTUAL) - { - /* OK */ - VirtualType *Z; - Z = find_virtual_by_variable (v); - if (Z == NULL) - { - Z = new_virtual (); - if (Z == NULL) - { - WARN_OUT_OF_MEMORY; - return (l); - } - Z->Variable = v; - } - /* update file information */ - Z->FileNumber = FileNumber; - Z->FileOffset = FileOffset; - Z->FileLength = FileLength; - FileOffset += FileLength * v->array_units; - } - else - { - /* the existing variable is NOT virtual */ - WARN_TYPE_MISMATCH; - return (l); - } - } - else - { - /* the existing variable CANNOT be Virtual */ - if (v->VariableFlags & VARIABLE_VIRTUAL) - { - /* the existing variable IS virtual */ - WARN_TYPE_MISMATCH; - return (l); - } - else - { - /* OK */ - } - } - /* end of conditional for old variable */ - } - - } - while (line_skip_seperator (l)); - - /* return */ - return (l); -} - - - - -/*************************************************************** - - FUNCTION: dim_unit() - - DESCRIPTION: This function calculates the unit - position for an array. - -***************************************************************/ - -static size_t -dim_unit (VariableType * v, int *pp) -{ - size_t r; - size_t b; - int n; - - assert (v != NULL); - assert (pp != NULL); - - /* Calculate and return the address of the dimensioned array */ - - /* Check EACH dimension for out-of-bounds, AND check correct number - * of dimensions. NBS_P076_0250 errors correctly. */ - - /* - Ux = Upper bound of dimension - Lx = Lower bound of dimension - Ix = Selected idex in dimension - - dimensions b - 0 1 - 1 b0 * ( U0 - L0 + 1 ) - 2 b1 * ( U1 - L1 + 1 ) - 3 b2 * ( U2 - L2 + 1 ) - - - dimensions r - 0 0 - 1 r0 + ( I0 - L0 ) * b0 - 2 r1 + ( I1 - L1 ) * b1 - 3 r2 + ( I2 - L2 ) * b2 - - */ - - r = 0; - b = 1; - for (n = 0; n < v->dimensions; n++) - { - if (pp[n] < v->LBOUND[n] || pp[n] > v->UBOUND[n]) - { - WARN_SUBSCRIPT_OUT_OF_RANGE; - return 0; - } - r += b * (pp[n] - v->LBOUND[n]); - b *= v->UBOUND[n] - v->LBOUND[n] + 1; - } - - - if (r > v->array_units) - { - WARN_SUBSCRIPT_OUT_OF_RANGE; - return 0; - } - return r; - -} - - -/*************************************************************** - - FUNCTION: bwb_option() - - DESCRIPTION: This function implements the BASIC OPTION - BASE statement, designating the base (1 or - 0) for addressing DIM arrays. - - SYNTAX: OPTION BASE number - -***************************************************************/ - -void -OptionVersionSet (int i) -{ - assert( i >= 0 && i < NUM_VERSIONS ); - assert( My != NULL ); - - My->CurrentVersion = &bwb_vertable[i]; -} - -LineType * -bwb_OPTION (LineType * l) -{ - assert (l != NULL); - - WARN_SYNTAX_ERROR; - return (l); -} - -LineType * -bwb_OPTION_ANGLE (LineType * l) -{ - assert (l != NULL); - - WARN_SYNTAX_ERROR; - return (l); -} - -LineType * -bwb_OPTION_ANGLE_DEGREES (LineType * l) -{ - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - /* OPTION ANGLE DEGREES */ - My->CurrentVersion->OptionFlags |= OPTION_ANGLE_DEGREES; - My->CurrentVersion->OptionFlags &= ~OPTION_ANGLE_GRADIANS; - return (l); -} - -LineType * -bwb_OPTION_ANGLE_GRADIANS (LineType * l) -{ - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - /* OPTION ANGLE GRADIANS */ - My->CurrentVersion->OptionFlags &= ~OPTION_ANGLE_DEGREES; - My->CurrentVersion->OptionFlags |= OPTION_ANGLE_GRADIANS; - return (l); -} - -LineType * -bwb_OPTION_ANGLE_RADIANS (LineType * l) -{ - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - /* OPTION ANGLE RADIANS */ - My->CurrentVersion->OptionFlags &= ~OPTION_ANGLE_DEGREES; - My->CurrentVersion->OptionFlags &= ~OPTION_ANGLE_GRADIANS; - return (l); -} - -LineType * -bwb_OPTION_ARITHMETIC (LineType * l) -{ - assert (l != NULL); - WARN_SYNTAX_ERROR; - return (l); -} - -LineType * -bwb_OPTION_ARITHMETIC_DECIMAL (LineType * l) -{ - /* OPTION ARITHMETIC DECIMAL */ - assert (l != NULL); - return (l); -} - -LineType * -bwb_OPTION_ARITHMETIC_FIXED (LineType * l) -{ - /* OPTION ARITHMETIC FIXED */ - assert (l != NULL); - return (l); -} - -LineType * -bwb_OPTION_ARITHMETIC_NATIVE (LineType * l) -{ - /* OPTION ARITHMETIC NATIVE */ - assert (l != NULL); - return (l); -} - -LineType * -bwb_OPTION_BASE (LineType * l) -{ - /* OPTION BASE integer */ - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - return bwb_option_range_integer (l, - &(My->CurrentVersion->OptionBaseInteger), - MININT, MAXINT); -} - -LineType * -bwb_OPTION_BUGS (LineType * l) -{ - assert (l != NULL); - WARN_SYNTAX_ERROR; - return (l); -} - -LineType * -bwb_OPTION_BUGS_BOOLEAN (LineType * l) -{ - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - /* OPTION BUGS BOOLEAN */ - My->CurrentVersion->OptionFlags |= OPTION_BUGS_BOOLEAN; - return (l); -} - -LineType * -bwb_OPTION_BUGS_ON (LineType * l) -{ - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - /* OPTION BUGS ON */ - My->CurrentVersion->OptionFlags |= OPTION_BUGS_ON; - return (l); -} - -LineType * -bwb_OPTION_BUGS_OFF (LineType * l) -{ - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - /* OPTION BUGS OFF */ - My->CurrentVersion->OptionFlags &= ~OPTION_BUGS_ON; - My->CurrentVersion->OptionFlags &= ~OPTION_BUGS_BOOLEAN; - return (l); -} - -LineType * -bwb_option_punct_char (LineType * l, char *c) -{ - /* OPTION ... char$ */ - - assert (l != NULL); - assert (c != NULL); - - { - char *Value; - char C; - - Value = NULL; - if (line_read_string_expression (l, &Value) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (Value == NULL) - { - WARN_SYNTAX_ERROR; - return (l); - } - C = Value[0]; - free (Value); - /* OK */ - if (bwb_ispunct (C)) - { - /* enable */ - *c = C; - } - else - { - /* disable */ - *c = NulChar; - } - } - return (l); -} - -LineType * -bwb_option_range_integer (LineType * l, int *Integer, int MinVal, int MaxVal) -{ - /* OPTION ... integer */ - - assert (l != NULL); - assert (Integer != NULL); - assert (MinVal < MaxVal); - - { - int Value; - - Value = 0; - if (line_read_integer_expression (l, &Value) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (Value < MinVal || Value > MaxVal) - { - WARN_ILLEGAL_FUNCTION_CALL; - return (l); - } - *Integer = Value; - } - return (l); -} - -LineType * -bwb_OPTION_PUNCT_COMMENT (LineType * l) -{ - /* OPTION PUNCT COMMENT char$ */ - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - return bwb_option_punct_char (l, &(My->CurrentVersion->OptionCommentChar)); -} - -LineType * -bwb_OPTION_COMPARE (LineType * l) -{ - assert (l != NULL); - WARN_SYNTAX_ERROR; - return (l); -} - -LineType * -bwb_OPTION_COMPARE_BINARY (LineType * l) -{ - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - /* OPTION COMPARE BINARY */ - My->CurrentVersion->OptionFlags &= ~OPTION_COMPARE_TEXT; - return (l); -} - -LineType * -bwb_OPTION_COMPARE_DATABASE (LineType * l) -{ - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - /* OPTION COMPARE DATABASE */ - My->CurrentVersion->OptionFlags |= OPTION_COMPARE_TEXT; - return (l); -} - -LineType * -bwb_OPTION_COMPARE_TEXT (LineType * l) -{ - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - /* OPTION COMPARE TEXT */ - My->CurrentVersion->OptionFlags |= OPTION_COMPARE_TEXT; - return (l); -} - -LineType * -bwb_OPTION_COVERAGE (LineType * l) -{ - assert (l != NULL); - WARN_SYNTAX_ERROR; - return (l); -} - -LineType * -bwb_OPTION_COVERAGE_ON (LineType * l) -{ - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - /* OPTION COVERAGE ON */ - My->CurrentVersion->OptionFlags |= OPTION_COVERAGE_ON; - return (l); -} - -LineType * -bwb_OPTION_COVERAGE_OFF (LineType * l) -{ - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - /* OPTION COVERAGE OFF */ - My->CurrentVersion->OptionFlags &= ~OPTION_COVERAGE_ON; - return (l); -} - -LineType * -bwb_OPTION_DATE (LineType * l) -{ - /* OPTION DATE format$ */ - char *Value; - - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - - Value = NULL; - if (line_read_string_expression (l, &Value) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (Value == NULL) - { - WARN_SYNTAX_ERROR; - return (l); - } - /* OK */ - My->CurrentVersion->OptionDateFormat = Value; -#if FALSE /* keep this ... */ - /* - ** Yes, this can theoretically cause a memory leak. - ** No, we are not going to fix it. - ** This command is only supported in the profile. - ** This will only execute at most once, - ** so there is no actual memory leak. - ** - */ - free (Value); -#endif - return (l); -} - -LineType * -bwb_OPTION_DIGITS (LineType * l) -{ - int Value; - - assert (l != NULL); - assert( My != NULL ); - - /* OPTION DIGITS integer */ - Value = 0; - if (line_read_integer_expression (l, &Value)) - { - /* OK */ - if (Value == 0) - { - /* default */ - Value = SIGNIFICANT_DIGITS; - } - if (Value < MINIMUM_DIGITS || Value > MAXIMUM_DIGITS) - { - WARN_ILLEGAL_FUNCTION_CALL; - return (l); - } - My->OptionDigitsInteger = Value; - } - return (l); -} - -LineType * -bwb_OPTION_DISABLE (LineType * l) -{ - assert (l != NULL); - WARN_SYNTAX_ERROR; - return (l); -} - -LineType * -bwb_OPTION_DISABLE_COMMAND (LineType * l) -{ - /* OPTION DISABLE COMMAND name$ */ - int IsFound; - char *Value; - - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - - IsFound = FALSE; - Value = NULL; - - /* Get COMMAND */ - if (line_read_string_expression (l, &Value) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (Value == NULL) - { - WARN_SYNTAX_ERROR; - return (l); - } - /* OK */ - { - /* Name */ - int i; - for (i = 0; i < NUM_COMMANDS; i++) - { - if (bwb_stricmp (Value, IntrinsicCommandTable[i].name) == 0) - { - /* FOUND */ - /* DISABLE COMMAND */ - IntrinsicCommandTable[i].OptionVersionBitmask &= - ~My->CurrentVersion->OptionVersionValue; - IsFound = TRUE; - } - } - } - free (Value); - if (IsFound == FALSE) - { - /* display warning message */ - fprintf (My->SYSOUT->cfp, "IGNORED: %s\n", l->buffer); - ResetConsoleColumn (); - } - return (l); -} - - -LineType * -bwb_OPTION_DISABLE_FUNCTION (LineType * l) -{ - /* OPTION DISABLE FUNCTION name$ */ - int IsFound; - - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - - IsFound = FALSE; - /* Get FUNCTION */ - { - char *Value; - - Value = NULL; - if (line_read_string_expression (l, &Value) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (Value == NULL) - { - WARN_SYNTAX_ERROR; - return (l); - } - /* OK */ - { - /* Name */ - int i; - for (i = 0; i < NUM_FUNCTIONS; i++) - { - if (bwb_stricmp (Value, IntrinsicFunctionTable[i].Name) == 0) - { - /* FOUND */ - /* DISABLE FUNCTION */ - IntrinsicFunctionTable[i].OptionVersionBitmask &= - ~My->CurrentVersion->OptionVersionValue; - IsFound = TRUE; - } - } - } - free (Value); - } - if (IsFound == FALSE) - { - /* display warning message */ - fprintf (My->SYSOUT->cfp, "IGNORED: %s\n", l->buffer); - ResetConsoleColumn (); - } - return (l); -} - -LineType * -bwb_OPTION_EDIT (LineType * l) -{ - /* OPTION EDIT string$ */ - char *Value; - - assert (l != NULL); - assert( My != NULL ); - - Value = NULL; - if (line_read_string_expression (l, &Value) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (Value == NULL) - { - WARN_SYNTAX_ERROR; - return (l); - } - /* OK */ - My->OptionEditString = Value; -#if FALSE /* keep this ... */ - /* - ** Yes, this can theoretically cause a memory leak. - ** No, we are not going to fix it. - ** This command is only supported in the profile. - ** This will only execute at most once, - ** so there is no actual memory leak. - ** - */ - free (Value); -#endif - return (l); -} - -LineType * -bwb_OPTION_EXTENSION (LineType * l) -{ - /* OPTION EXTENSION ext$ */ - char *Value; - - assert (l != NULL); - assert( My != NULL ); - - Value = NULL; - if (line_read_string_expression (l, &Value) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (Value == NULL) - { - WARN_SYNTAX_ERROR; - return (l); - } - /* OK */ - My->OptionExtensionString = Value; -#if FALSE /* keep this ... */ - /* - ** Yes, this can theoretically cause a memory leak. - ** No, we are not going to fix it. - ** This command is only supported in the profile. - ** This command will only execute at most once, - ** so there is no actual memory leak. - ** - */ - free (Value); -#endif - return (l); -} - -LineType * -bwb_OPTION_FILES (LineType * l) -{ - /* OPTION FILES name$ */ - char *Value; - - assert (l != NULL); - assert( My != NULL ); - - - Value = NULL; - if (line_read_string_expression (l, &Value) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (Value == NULL) - { - WARN_SYNTAX_ERROR; - return (l); - } - /* OK */ - My->OptionFilesString = Value; -#if FALSE /* keep this ... */ - /* - ** Yes, this can theoretically cause a memory leak. - ** No, we are not going to fix it. - ** This command is only supported in the profile. - ** This will only execute at most once, - ** so there is no actual memory leak. - ** - */ - free (Value); -#endif - return (l); -} - -LineType * -bwb_OPTION_PROMPT (LineType * l) -{ - /* OPTION PROMPT prompt$ */ - char *Value; - - assert (l != NULL); - assert( My != NULL ); - - - Value = NULL; - if (line_read_string_expression (l, &Value) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (Value == NULL) - { - WARN_SYNTAX_ERROR; - return (l); - } - /* OK */ - My->OptionPromptString = Value; -#if FALSE /* keep this ... */ - /* - ** Yes, this can theoretically cause a memory leak. - ** No, we are not going to fix it. - ** This command is only supported in the profile. - ** This will only execute at most once, - ** so there is no actual memory leak. - ** - */ - free (Value); -#endif - return (l); -} - -LineType * -bwb_OPTION_RENUM (LineType * l) -{ - /* OPTION RENUM name$ */ - char *Value; - - assert (l != NULL); - assert( My != NULL ); - - - Value = NULL; - if (line_read_string_expression (l, &Value) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (Value == NULL) - { - WARN_SYNTAX_ERROR; - return (l); - } - /* OK */ - My->OptionRenumString = Value; -#if FALSE /* keep this ... */ - /* - ** Yes, this can theoretically cause a memory leak. - ** No, we are not going to fix it. - ** This command is only supported in the profile. - ** This will only execute at most once, - ** so there is no actual memory leak. - ** - */ - free (Value); -#endif - return (l); -} - -LineType * -bwb_OPTION_ENABLE (LineType * l) -{ - assert (l != NULL); - WARN_SYNTAX_ERROR; - return (l); -} - -LineType * -bwb_OPTION_ENABLE_COMMAND (LineType * l) -{ - /* OPTION ENABLE COMMAND name$ */ - int IsFound; - - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - - IsFound = FALSE; - /* Get COMMAND */ - { - char *Value; - - Value = NULL; - if (line_read_string_expression (l, &Value) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (Value == NULL) - { - WARN_SYNTAX_ERROR; - return (l); - } - /* OK */ - { - /* Name */ - int i; - for (i = 0; i < NUM_COMMANDS; i++) - { - if (bwb_stricmp (Value, IntrinsicCommandTable[i].name) == 0) - { - /* FOUND */ - /* ENABLE COMMAND */ - IntrinsicCommandTable[i].OptionVersionBitmask |= - My->CurrentVersion->OptionVersionValue; - IsFound = TRUE; - } - } - } - free (Value); - } - if (IsFound == FALSE) - { - /* display warning message */ - fprintf (My->SYSOUT->cfp, "IGNORED: %s\n", l->buffer); - ResetConsoleColumn (); - } - return (l); -} - -LineType * -bwb_OPTION_ENABLE_FUNCTION (LineType * l) -{ - /* OPTION ENABLE FUNCTION name$ */ - int IsFound; - - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - - IsFound = FALSE; - /* Get FUNCTION */ - { - char *Value; - - Value = NULL; - if (line_read_string_expression (l, &Value) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (Value == NULL) - { - WARN_SYNTAX_ERROR; - return (l); - } - /* OK */ - { - /* Name */ - int i; - for (i = 0; i < NUM_FUNCTIONS; i++) - { - if (bwb_stricmp (Value, IntrinsicFunctionTable[i].Name) == 0) - { - /* FOUND */ - /* ENABLE FUNCTION */ - IntrinsicFunctionTable[i].OptionVersionBitmask |= - My->CurrentVersion->OptionVersionValue; - IsFound = TRUE; - } - } - } - free (Value); - } - if (IsFound == FALSE) - { - /* display warning message */ - fprintf (My->SYSOUT->cfp, "IGNORED: %s\n", l->buffer); - ResetConsoleColumn (); - } - return (l); -} - -LineType * -bwb_OPTION_ERROR (LineType * l) -{ - assert (l != NULL); - WARN_SYNTAX_ERROR; - return (l); -} - -LineType * -bwb_OPTION_ERROR_GOSUB (LineType * l) -{ - /* OPTION ERROR GOSUB */ - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - My->CurrentVersion->OptionFlags |= OPTION_ERROR_GOSUB; - return (l); -} - -LineType * -bwb_OPTION_ERROR_GOTO (LineType * l) -{ - /* OPTION ERROR GOTO */ - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - My->CurrentVersion->OptionFlags &= ~OPTION_ERROR_GOSUB; - return (l); -} - -LineType * -bwb_OPTION_EXPLICIT (LineType * l) -{ - /* OPTION EXPLICIT */ - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - My->CurrentVersion->OptionFlags |= OPTION_EXPLICIT_ON; - return (l); -} - - -LineType * -bwb_OPTION_PUNCT_IMAGE (LineType * l) -{ - /* OPTION PUNCT IMAGE char$ */ - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - return bwb_option_punct_char (l, &(My->CurrentVersion->OptionImageChar)); -} - -LineType * -bwb_OPTION_IMPLICIT (LineType * l) -{ - /* OPTION IMPLICIT */ - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - My->CurrentVersion->OptionFlags &= ~OPTION_EXPLICIT_ON; - return (l); -} - -LineType * -bwb_OPTION_INDENT (LineType * l) -{ - /* OPTION INDENT integer */ - assert (l != NULL); - assert( My != NULL ); - - return bwb_option_range_integer (l, &(My->OptionIndentInteger), 0, 7); -} - -LineType * -bwb_OPTION_PUNCT_INPUT (LineType * l) -{ - /* OPTION PUNCT INPUT char$ */ - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - return bwb_option_punct_char (l, &(My->CurrentVersion->OptionInputChar)); -} - -LineType * -bwb_OPTION_LABELS (LineType * l) -{ - assert (l != NULL); - WARN_SYNTAX_ERROR; - return (l); -} - -LineType * -bwb_OPTION_LABELS_ON (LineType * l) -{ - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - /* OPTION LABELS ON */ - My->CurrentVersion->OptionFlags |= OPTION_LABELS_ON; - return (l); -} - -LineType * -bwb_OPTION_LABELS_OFF (LineType * l) -{ - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - /* OPTION LABELS OFF */ - My->CurrentVersion->OptionFlags &= ~OPTION_LABELS_ON; - return (l); -} - -LineType * -bwb_OPTION_PUNCT_PRINT (LineType * l) -{ - /* OPTION PUNCT PRINT char$ */ - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - return bwb_option_punct_char (l, &(My->CurrentVersion->OptionPrintChar)); -} - -LineType * -bwb_OPTION_PUNCT_QUOTE (LineType * l) -{ - /* OPTION PUNCT QUOTE char$ */ - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - return bwb_option_punct_char (l, &(My->CurrentVersion->OptionQuoteChar)); -} - -LineType * -bwb_OPTION_ROUND (LineType * l) -{ - assert (l != NULL); - WARN_SYNTAX_ERROR; - return (l); -} - -LineType * -bwb_OPTION_ROUND_BANK (LineType * l) -{ - /* OPTION ROUND BANK */ - assert (l != NULL); - assert( My != NULL ); - - My->OptionRoundType = C_OPTION_ROUND_BANK; - return (l); -} - -LineType * -bwb_OPTION_ROUND_MATH (LineType * l) -{ - /* OPTION ROUND MATH */ - assert (l != NULL); - assert( My != NULL ); - - My->OptionRoundType = C_OPTION_ROUND_MATH; - return (l); -} - -LineType * -bwb_OPTION_ROUND_TRUNCATE (LineType * l) -{ - /* OPTION ROUND TRUNCATE */ - assert (l != NULL); - assert( My != NULL ); - - My->OptionRoundType = C_OPTION_ROUND_TRUNCATE; - return (l); -} - -LineType * -bwb_OPTION_SCALE (LineType * l) -{ - /* OPTION SCALE integer */ - assert (l != NULL); - assert( My != NULL ); - - return bwb_option_range_integer (l, &(My->OptionScaleInteger), - MINIMUM_SCALE, MAXIMUM_SCALE); -} - - -LineType * -bwb_OPTION_SLEEP (LineType * l) -{ - /* OPTION SLEEP number */ - assert (l != NULL); - assert( My != NULL ); - - if (line_read_numeric_expression (l, &My->OptionSleepDouble) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - return (l); -} - -LineType * -bwb_OPTION_STDERR (LineType * l) -{ - /* OPTION STDERR filename$ */ - - assert (l != NULL); - assert( My != NULL ); - assert( My->SYSPRN != NULL ); - assert( My->SYSPRN->cfp != NULL ); - - - if (line_is_eol (l)) - { - bwb_fclose (My->SYSPRN->cfp); - My->SYSPRN->cfp = stderr; - } - else - { - char *Value; - - Value = NULL; - if (line_read_string_expression (l, &Value) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (Value == NULL) - { - WARN_SYNTAX_ERROR; - return (l); - } - /* OK */ - if (is_empty_string (Value)) - { - bwb_fclose (My->SYSPRN->cfp); - My->SYSPRN->cfp = stderr; - } - else - { - bwb_fclose (My->SYSPRN->cfp); - My->SYSPRN->cfp = fopen (Value, "w+"); - if (My->SYSPRN->cfp == NULL) - { - /* sane default */ - My->SYSPRN->cfp = stderr; - WARN_BAD_FILE_NAME; - } - } - free (Value); - } - return (l); -} - -LineType * -bwb_OPTION_STDIN (LineType * l) -{ - /* OPTION STDIN filename$ */ - - assert (l != NULL); - assert( My != NULL ); - assert( My->SYSIN != NULL ); - assert( My->SYSIN->cfp != NULL ); - - if (line_is_eol (l)) - { - bwb_fclose (My->SYSIN->cfp); - My->SYSIN->cfp = stdin; - } - else - { - char *Value; - - Value = NULL; - if (line_read_string_expression (l, &Value) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (Value == NULL) - { - WARN_SYNTAX_ERROR; - return (l); - } - /* OK */ - if (is_empty_string (Value)) - { - bwb_fclose (My->SYSIN->cfp); - My->SYSIN->cfp = stdin; - } - else - { - bwb_fclose (My->SYSIN->cfp); - My->SYSIN->cfp = fopen (Value, "r"); - if (My->SYSIN->cfp == NULL) - { - /* sane default */ - My->SYSIN->cfp = stdin; - WARN_BAD_FILE_NAME; - } - } - free (Value); - } - return (l); -} - -LineType * -bwb_OPTION_STDOUT (LineType * l) -{ - /* OPTION STDOUT filename$ */ - - assert (l != NULL); - assert( My != NULL ); - assert( My->SYSOUT != NULL ); - assert( My->SYSOUT->cfp != NULL ); - - if (line_is_eol (l)) - { - bwb_fclose (My->SYSOUT->cfp); - My->SYSOUT->cfp = stdout; - } - else - { - char *Value; - - Value = NULL; - if (line_read_string_expression (l, &Value) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (Value == NULL) - { - WARN_SYNTAX_ERROR; - return (l); - } - /* OK */ - if (is_empty_string (Value)) - { - bwb_fclose (My->SYSOUT->cfp); - My->SYSOUT->cfp = stdout; - } - else - { - bwb_fclose (My->SYSOUT->cfp); - My->SYSOUT->cfp = fopen (Value, "w+"); - if (My->SYSOUT->cfp == NULL) - { - /* sane default */ - My->SYSOUT->cfp = stdout; - WARN_BAD_FILE_NAME; - } - } - free (Value); - } - return (l); -} - -LineType * -bwb_OPTION_PUNCT_STATEMENT (LineType * l) -{ - /* OPTION PUNCT STATEMENT char$ */ - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - return bwb_option_punct_char (l, - &(My->CurrentVersion->OptionStatementChar)); -} - -LineType * -bwb_OPTION_STRICT (LineType * l) -{ - assert (l != NULL); - WARN_SYNTAX_ERROR; - return (l); -} - -LineType * -bwb_OPTION_STRICT_ON (LineType * l) -{ - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - /* OPTION STRICT ON */ - My->CurrentVersion->OptionFlags |= OPTION_STRICT_ON; - return (l); -} - -LineType * -bwb_OPTION_STRICT_OFF (LineType * l) -{ - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - /* OPTION STRICT OFF */ - My->CurrentVersion->OptionFlags &= ~OPTION_STRICT_ON; - return (l); -} - -LineType * -bwb_OPTION_PUNCT (LineType * l) -{ - assert (l != NULL); - WARN_SYNTAX_ERROR; - return (l); -} - -LineType * -bwb_OPTION_PUNCT_STRING (LineType * l) -{ - /* OPTION PUNCT STRING char$ */ - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - return bwb_option_punct_char (l, &(My->CurrentVersion->OptionStringChar)); -} - -LineType * -bwb_OPTION_PUNCT_DOUBLE (LineType * l) -{ - /* OPTION PUNCT DOUBLE char$ */ - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - return bwb_option_punct_char (l, &(My->CurrentVersion->OptionDoubleChar)); -} - -LineType * -bwb_OPTION_PUNCT_SINGLE (LineType * l) -{ - /* OPTION PUNCT SINGLE char$ */ - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - return bwb_option_punct_char (l, &(My->CurrentVersion->OptionSingleChar)); -} - -LineType * -bwb_OPTION_PUNCT_CURRENCY (LineType * l) -{ - /* OPTION PUNCT CURRENCY char$ */ - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - return bwb_option_punct_char (l, &(My->CurrentVersion->OptionCurrencyChar)); -} - -LineType * -bwb_OPTION_PUNCT_LONG (LineType * l) -{ - /* OPTION PUNCT LONG char$ */ - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - return bwb_option_punct_char (l, &(My->CurrentVersion->OptionLongChar)); -} - -LineType * -bwb_OPTION_PUNCT_INTEGER (LineType * l) -{ - /* OPTION PUNCT INTEGER char$ */ - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - return bwb_option_punct_char (l, &(My->CurrentVersion->OptionIntegerChar)); -} - -LineType * -bwb_OPTION_PUNCT_BYTE (LineType * l) -{ - /* OPTION PUNCT BYTE char$ */ - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - return bwb_option_punct_char (l, &(My->CurrentVersion->OptionByteChar)); -} - -LineType * -bwb_OPTION_PUNCT_LPAREN (LineType * l) -{ - /* OPTION PUNCT LPAREN char$ */ - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - return bwb_option_punct_char (l, &(My->CurrentVersion->OptionLparenChar)); -} - -LineType * -bwb_OPTION_PUNCT_RPAREN (LineType * l) -{ - /* OPTION PUNCT RPAREN char$ */ - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - return bwb_option_punct_char (l, &(My->CurrentVersion->OptionRparenChar)); -} - -LineType * -bwb_OPTION_PUNCT_FILENUM (LineType * l) -{ - /* OPTION PUNCT FILENUM char$ */ - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - return bwb_option_punct_char (l, &(My->CurrentVersion->OptionFilenumChar)); -} - -LineType * -bwb_OPTION_PUNCT_AT (LineType * l) -{ - /* OPTION PUNCT AT char$ */ - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - return bwb_option_punct_char (l, &(My->CurrentVersion->OptionAtChar)); -} - -LineType * -bwb_OPTION_RECLEN (LineType * l) -{ - /* OPTION RECLEN integer */ - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - return bwb_option_range_integer (l, - &(My->CurrentVersion->OptionReclenInteger), - 0, MAXINT); -} - -LineType * -bwb_OPTION_TERMINAL (LineType * l) -{ - assert (l != NULL); - WARN_SYNTAX_ERROR; - return (l); -} - -LineType * -bwb_OPTION_TERMINAL_NONE (LineType * l) -{ - /* OPTION TERMINAL NONE */ - assert (l != NULL); - assert( My != NULL ); - - My->OptionTerminalType = C_OPTION_TERMINAL_NONE; - return (l); -} - -LineType * -bwb_OPTION_TERMINAL_ADM (LineType * l) -{ - /* OPTION TERMINAL ADM-3A */ - assert (l != NULL); - assert( My != NULL ); - - My->OptionTerminalType = C_OPTION_TERMINAL_ADM; - return (l); -} - -LineType * -bwb_OPTION_TERMINAL_ANSI (LineType * l) -{ - /* OPTION TERMINAL ANSI */ - assert (l != NULL); - assert( My != NULL ); - - My->OptionTerminalType = C_OPTION_TERMINAL_ANSI; - return (l); -} - -LineType * -bwb_OPTION_TIME (LineType * l) -{ - /* OPTION TIME format$ */ - char *Value; - - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - Value = NULL; - if (line_read_string_expression (l, &Value) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (Value == NULL) - { - WARN_SYNTAX_ERROR; - return (l); - } - /* OK */ - My->CurrentVersion->OptionTimeFormat = Value; -#if FALSE /* keep this ... */ - /* - ** Yes, this can theoretically cause a memory leak. - ** No, we are not going to fix it. - ** This command is only supported in the profile. - ** This will only execute at most once, - ** so there is no actual memory leak. - ** - */ - free (Value); -#endif - return (l); -} - -LineType * -bwb_OPTION_TRACE (LineType * l) -{ - - assert (l != NULL); - WARN_SYNTAX_ERROR; - return (l); -} - -LineType * -bwb_OPTION_TRACE_ON (LineType * l) -{ - /* OPTION TRACE ON */ - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - My->CurrentVersion->OptionFlags |= OPTION_TRACE_ON; - return (l); -} - -LineType * -bwb_OPTION_TRACE_OFF (LineType * l) -{ - /* OPTION TRACE OFF */ - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - My->CurrentVersion->OptionFlags &= ~OPTION_TRACE_ON; - return (l); -} - -LineType * -bwb_OPTION_USING (LineType * l) -{ - assert (l != NULL); - WARN_SYNTAX_ERROR; - return (l); -} - -LineType * -bwb_OPTION_USING_DIGIT (LineType * l) -{ - /* OPTION USING DIGIT char$ */ - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - return bwb_option_punct_char (l, &(My->CurrentVersion->OptionUsingDigit)); -} - -LineType * -bwb_OPTION_USING_COMMA (LineType * l) -{ - /* OPTION USING COMMA char$ */ - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - return bwb_option_punct_char (l, &(My->CurrentVersion->OptionUsingComma)); -} - -LineType * -bwb_OPTION_USING_PERIOD (LineType * l) -{ - /* OPTION USING PERIOD char$ */ - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - return bwb_option_punct_char (l, &(My->CurrentVersion->OptionUsingPeriod)); -} - -LineType * -bwb_OPTION_USING_PLUS (LineType * l) -{ - /* OPTION USING PLUS char$ */ - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - return bwb_option_punct_char (l, &(My->CurrentVersion->OptionUsingPlus)); -} - -LineType * -bwb_OPTION_USING_MINUS (LineType * l) -{ - /* OPTION USING MINUS char$ */ - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - return bwb_option_punct_char (l, &(My->CurrentVersion->OptionUsingMinus)); -} - -LineType * -bwb_OPTION_USING_EXRAD (LineType * l) -{ - /* OPTION USING EXRAD char$ */ - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - return bwb_option_punct_char (l, &(My->CurrentVersion->OptionUsingExrad)); -} - -LineType * -bwb_OPTION_USING_DOLLAR (LineType * l) -{ - /* OPTION USING DOLLAR char$ */ - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - return bwb_option_punct_char (l, &(My->CurrentVersion->OptionUsingDollar)); -} - -LineType * -bwb_OPTION_USING_FILLER (LineType * l) -{ - /* OPTION USING FILLER char$ */ - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - return bwb_option_punct_char (l, &(My->CurrentVersion->OptionUsingFiller)); -} - -LineType * -bwb_OPTION_USING_LITERAL (LineType * l) -{ - /* OPTION USING LITERAL char$ */ - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - return bwb_option_punct_char (l, &(My->CurrentVersion->OptionUsingLiteral)); -} - -LineType * -bwb_OPTION_USING_FIRST (LineType * l) -{ - /* OPTION USING FIRST char$ */ - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - return bwb_option_punct_char (l, &(My->CurrentVersion->OptionUsingFirst)); -} - -LineType * -bwb_OPTION_USING_ALL (LineType * l) -{ - /* OPTION USING ALL char$ */ - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - return bwb_option_punct_char (l, &(My->CurrentVersion->OptionUsingAll)); -} - -LineType * -bwb_OPTION_USING_LENGTH (LineType * l) -{ - /* OPTION USING LENGTH char$ */ - assert (l != NULL); - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - return bwb_option_punct_char (l, &(My->CurrentVersion->OptionUsingLength)); -} - -extern LineType * -bwb_OPTION_VERSION (LineType * l) -{ - /* OPTION VERSION [version$] */ - char *Name; - int i; - - assert (l != NULL); - assert( My != NULL ); - assert( My->SYSOUT != NULL ); - assert( My->SYSOUT->cfp != NULL ); - - - Name = NULL; - if (line_is_eol (l)) - { - /* OPTIONAL */ - } - else if (line_read_string_expression (l, &Name)) - { - if (is_empty_string (Name) == FALSE) - { - /* a version was specified */ - for (i = 0; i < NUM_VERSIONS; i++) - { - if (bwb_stricmp (Name, bwb_vertable[i].Name) == 0) - { - /* FOUND */ - OptionVersionSet (i); - return (l); - } - } - /* NOT FOUND */ - fprintf (My->SYSOUT->cfp, "OPTION VERSION \"%s\" IS INVALID\n", Name); - } - } - fprintf (My->SYSOUT->cfp, "VALID CHOICES ARE:\n"); - for (i = 0; i < NUM_VERSIONS; i++) - { - char *tbuf; - - tbuf = My->ConsoleOutput; - bwb_strcpy (tbuf, "\""); - bwb_strcat (tbuf, bwb_vertable[i].Name); - bwb_strcat (tbuf, "\""); - fprintf (My->SYSOUT->cfp, "OPTION VERSION %-16s ' %s\n", tbuf, - bwb_vertable[i].Description); - } - ResetConsoleColumn (); - line_skip_eol (l); - return (l); -} - -LineType * -bwb_OPTION_ZONE (LineType * l) -{ - /* OPTION ZONE integer */ - int Value; - - assert (l != NULL); - assert( My != NULL ); - - Value = 0; - if (line_read_integer_expression (l, &Value)) - { - /* OK */ - if (Value == 0) - { - /* default */ - Value = ZONE_WIDTH; - } - if (Value < MINIMUM_ZONE || Value > MAXIMUM_ZONE) - { - WARN_ILLEGAL_FUNCTION_CALL; - return (l); - } - My->OptionZoneInteger = Value; - } - return (l); -} - - - -int -var_get (VariableType * variable, VariantType * variant) -{ - size_t offset; - - /* check sanity */ - if (variable == NULL) - { - WARN_INTERNAL_ERROR; - return FALSE; - } - if (variant == NULL) - { - WARN_INTERNAL_ERROR; - return FALSE; - } - - /* Check subscripts */ - if (dim_check (variable) == FALSE) - { - WARN_SUBSCRIPT_OUT_OF_RANGE; - return FALSE; - } - - /* Determine offset from array base ( for scalars the offset is always zero ) */ - offset = dim_unit (variable, variable->VINDEX); - - CLEAR_VARIANT (variant); - - /* Force compatibility */ - variant->VariantTypeCode = variable->VariableTypeCode; - - if (variable->VariableTypeCode == StringTypeCode) - { - /* Variable is a STRING */ - StringType Value; - - Value.sbuffer = NULL; - Value.length = 0; - /* both STRING */ - - if (variable->VariableFlags & VARIABLE_VIRTUAL) /* var_get() */ - { - /* get file information */ - VirtualType *Z; - FileType *F; - - Z = find_virtual_by_variable (variable); - if (Z == NULL) - { - WARN_INTERNAL_ERROR; - return FALSE; - } - offset *= Z->FileLength; /* Byte offset */ - offset += Z->FileOffset; /* Beginning of this data */ - /* update file information */ - F = find_file_by_number (Z->FileNumber); - if (F == NULL) - { - WARN_BAD_FILE_MODE; - return FALSE; - } - if (F->DevMode != DEVMODE_VIRTUAL) - { - WARN_BAD_FILE_MODE; - return FALSE; - } - if (F->cfp == NULL) - { - WARN_BAD_FILE_MODE; - return FALSE; - } - if (fseek (F->cfp, offset, SEEK_SET) != 0) - { - WARN_BAD_FILE_MODE; - return FALSE; - } - Value.length = Z->FileLength; - if ((Value.sbuffer = - (char *) calloc (Value.length + 1 /* NulChar */ , - sizeof (char))) == NULL) - { - WARN_OUT_OF_MEMORY; - return FALSE; - } - if (fread (Value.sbuffer, Value.length, 1, F->cfp) != 1) - { - WARN_DISK_IO_ERROR; - return FALSE; - } - } - else - { - StringType *string; - - string = variable->Value.String; - if (string == NULL) - { - WARN_INTERNAL_ERROR; - return FALSE; - } - string += offset; - if (str_btob (&Value, string) == FALSE) - { - WARN_INTERNAL_ERROR; - return FALSE; - } - } - variant->Buffer = Value.sbuffer; - variant->Length = Value.length; - } - else - { - /* Variable is a NUMBER */ - DoubleType Value; - /* both NUMBER */ - - if (variable->VariableFlags & VARIABLE_VIRTUAL) /* var_get() */ - { - /* get file information */ - VirtualType *Z; - FileType *F; - - Z = find_virtual_by_variable (variable); - if (Z == NULL) - { - WARN_INTERNAL_ERROR; - return FALSE; - } - offset *= Z->FileLength; /* Byte offset */ - offset += Z->FileOffset; /* Beginning of this data */ - /* update file information */ - F = find_file_by_number (Z->FileNumber); - if (F == NULL) - { - WARN_BAD_FILE_MODE; - return FALSE; - } - if (F->DevMode != DEVMODE_VIRTUAL) - { - WARN_BAD_FILE_MODE; - return FALSE; - } - if (F->cfp == NULL) - { - WARN_BAD_FILE_MODE; - return FALSE; - } - if (fseek (F->cfp, offset, SEEK_SET) != 0) - { - WARN_BAD_FILE_MODE; - return FALSE; - } - switch (variable->VariableTypeCode) - { - case ByteTypeCode: - { - ByteType X; - if (fread (&X, sizeof (X), 1, F->cfp) != 1) - { - WARN_DISK_IO_ERROR; - return FALSE; - } - Value = X; - } - break; - case IntegerTypeCode: - { - IntegerType X; - if (fread (&X, sizeof (X), 1, F->cfp) != 1) - { - WARN_DISK_IO_ERROR; - return FALSE; - } - Value = X; - } - break; - case LongTypeCode: - { - LongType X; - if (fread (&X, sizeof (X), 1, F->cfp) != 1) - { - WARN_DISK_IO_ERROR; - return FALSE; - } - Value = X; - } - break; - case CurrencyTypeCode: - { - CurrencyType X; - if (fread (&X, sizeof (X), 1, F->cfp) != 1) - { - WARN_DISK_IO_ERROR; - return FALSE; - } - Value = X; - } - break; - case SingleTypeCode: - { - SingleType X; - if (fread (&X, sizeof (X), 1, F->cfp) != 1) - { - WARN_DISK_IO_ERROR; - return FALSE; - } - Value = X; - } - break; - case DoubleTypeCode: - { - DoubleType X; - if (fread (&X, sizeof (X), 1, F->cfp) != 1) - { - WARN_DISK_IO_ERROR; - return FALSE; - } - Value = X; - } - break; - case StringTypeCode: - { - WARN_INTERNAL_ERROR; - return FALSE; - } - /* break; */ - default: - { - WARN_INTERNAL_ERROR; - return FALSE; - } - } - } - else - { - DoubleType *number; - - number = variable->Value.Number; - if (number == NULL) - { - WARN_INTERNAL_ERROR; - return FALSE; - } - number += offset; - /* copy value */ - Value = *number; - } - - /* VerifyNumeric */ - if (isnan (Value)) - { - /*** FATAL - INTERNAL ERROR - SHOULD NEVER HAPPEN ***/ - WARN_INTERNAL_ERROR; - return FALSE; - } - if (isinf (Value)) - { - /* - Evaluation of an expression results in an overflow - * (nonfatal, the recommended recovery procedure is to supply - * machine in- finity with the algebraically correct sign and - * continue). */ - if (Value < 0) - { - Value = MINDBL; - } - else - { - Value = MAXDBL; - } - if (WARN_OVERFLOW) - { - /* ERROR */ - return FALSE; - } - /* CONTINUE */ - } - /* OK */ - switch (variable->VariableTypeCode) - { - case ByteTypeCode: - case IntegerTypeCode: - case LongTypeCode: - case CurrencyTypeCode: - /* integer values */ - Value = bwb_rint (Value); - break; - case SingleTypeCode: - case DoubleTypeCode: - /* float values */ - break; - default: - /* ERROR */ - WARN_INTERNAL_ERROR; - return FALSE; - /* break; */ - } - variant->Number = Value; - } - return TRUE; -} - -int -var_set (VariableType * variable, VariantType * variant) -{ - size_t offset; - - assert( My != NULL ); - assert( My->SYSOUT != NULL ); - assert( My->SYSOUT->cfp != NULL ); - - /* check sanity */ - if (variable == NULL) - { - WARN_INTERNAL_ERROR; - return FALSE; - } - if (variant == NULL) - { - WARN_INTERNAL_ERROR; - return FALSE; - } - - /* check CONST */ - if (variable->VariableFlags & (VARIABLE_CONSTANT)) - { - /* attempting to assign to a constant */ - WARN_VARIABLE_NOT_DECLARED; - return FALSE; - } - - /* Check subscripts */ - if (dim_check (variable) == FALSE) - { - WARN_SUBSCRIPT_OUT_OF_RANGE; - return FALSE; - } - - /* Determine offset from array base ( for scalars the offset is always zero ) */ - offset = dim_unit (variable, variable->VINDEX); - - /* Verify compatibility */ - if (variable->VariableTypeCode == StringTypeCode) - { - /* Variable is a STRING */ - StringType Value; - - /* Verify value is a STRING */ - if (variant->VariantTypeCode != StringTypeCode) - { - WARN_TYPE_MISMATCH; - return FALSE; - } - Value.sbuffer = variant->Buffer; - Value.length = variant->Length; - /* both STRING */ - - if (variable->VariableFlags & VARIABLE_VIRTUAL) /* var_set() */ - { - /* get file information */ - VirtualType *Z; - FileType *F; - int count; - - Z = find_virtual_by_variable (variable); - if (Z == NULL) - { - WARN_INTERNAL_ERROR; - return FALSE; - } - offset *= Z->FileLength; /* Byte offset */ - offset += Z->FileOffset; /* Beginning of this data */ - /* update file information */ - F = find_file_by_number (Z->FileNumber); - if (F == NULL) - { - WARN_BAD_FILE_MODE; - return FALSE; - } - if (F->DevMode != DEVMODE_VIRTUAL) - { - WARN_BAD_FILE_MODE; - return FALSE; - } - if (F->cfp == NULL) - { - WARN_BAD_FILE_MODE; - return FALSE; - } - if (fseek (F->cfp, offset, SEEK_SET) != 0) - { - WARN_BAD_FILE_MODE; - return FALSE; - } - count = MIN (Value.length, Z->FileLength); - if (fwrite (Value.sbuffer, sizeof (char), count, F->cfp) != count) - { - WARN_DISK_IO_ERROR; - return FALSE; - } - /* PADR */ - while (count < Z->FileLength) - { - if (fputc (' ', F->cfp) == EOF) - { - WARN_BAD_FILE_MODE; - return FALSE; - } - count++; - } - } - else - { - StringType *string; - - string = variable->Value.String; - if (string == NULL) - { - WARN_INTERNAL_ERROR; - return FALSE; - } - string += offset; - if (str_btob (string, &Value) == FALSE) - { - WARN_INTERNAL_ERROR; - return FALSE; - } - } - if (variable->VariableFlags & VARIABLE_DISPLAY) /* var_set() */ - { - if (My->ThisLine) /* var_set() */ - { - if (My->ThisLine->LineFlags & (LINE_USER)) /* var_set() */ - { - /* immediate mode */ - } - else - { - fprintf (My->SYSOUT->cfp, "#%d %s=%s\n", My->ThisLine->number, variable->name, variant->Buffer); /* var_set() */ - ResetConsoleColumn (); - } - } - } - } - else - { - /* Variable is a NUMBER */ - DoubleType Value; - - /* Verify value is a NUMBER */ - if (variant->VariantTypeCode == StringTypeCode) - { - WARN_TYPE_MISMATCH; - return FALSE; - } - - /* both NUMBER */ - - /* VerifyNumeric */ - if (isnan (variant->Number)) - { - /*** FATAL - INTERNAL ERROR - SHOULD NEVER HAPPEN ***/ - WARN_INTERNAL_ERROR; - return FALSE; - } - if (isinf (variant->Number)) - { - /* - Evaluation of an expression results in an overflow - * (nonfatal, the recommended recovery procedure is to supply - * machine in- finity with the algebraically correct sign and - * continue). */ - if (variant->Number < 0) - { - variant->Number = MINDBL; - } - else - { - variant->Number = MAXDBL; - } - if (WARN_OVERFLOW) - { - /* ERROR */ - return FALSE; - } - /* CONTINUE */ - } - /* OK */ - switch (variable->VariableTypeCode) - { - case ByteTypeCode: - variant->Number = bwb_rint (variant->Number); - if (variant->Number < MINBYT) - { - if (WARN_OVERFLOW) - { - return FALSE; - } - variant->Number = MINBYT; - } - else if (variant->Number > MAXBYT) - { - if (WARN_OVERFLOW) - { - return FALSE; - } - variant->Number = MAXBYT; - } - break; - case IntegerTypeCode: - variant->Number = bwb_rint (variant->Number); - if (variant->Number < MININT) - { - if (WARN_OVERFLOW) - { - return FALSE; - } - variant->Number = MININT; - } - else if (variant->Number > MAXINT) - { - if (WARN_OVERFLOW) - { - return FALSE; - } - variant->Number = MAXINT; - } - break; - case LongTypeCode: - variant->Number = bwb_rint (variant->Number); - if (variant->Number < MINLNG) - { - if (WARN_OVERFLOW) - { - return FALSE; - } - variant->Number = MINLNG; - } - else if (variant->Number > MAXLNG) - { - if (WARN_OVERFLOW) - { - return FALSE; - } - variant->Number = MAXLNG; - } - break; - case CurrencyTypeCode: - variant->Number = bwb_rint (variant->Number); - if (variant->Number < MINCUR) - { - if (WARN_OVERFLOW) - { - return FALSE; - } - variant->Number = MINCUR; - } - else if (variant->Number > MAXCUR) - { - if (WARN_OVERFLOW) - { - return FALSE; - } - variant->Number = MAXCUR; - } - break; - case SingleTypeCode: - if (variant->Number < MINSNG) - { - if (WARN_OVERFLOW) - { - return FALSE; - } - variant->Number = MINSNG; - } - else if (variant->Number > MAXSNG) - { - if (WARN_OVERFLOW) - { - return FALSE; - } - variant->Number = MAXSNG; - } - break; - case DoubleTypeCode: - if (variant->Number < MINDBL) - { - if (WARN_OVERFLOW) - { - return FALSE; - } - variant->Number = MINDBL; - } - else if (variant->Number > MAXDBL) - { - if (WARN_OVERFLOW) - { - return FALSE; - } - variant->Number = MAXDBL; - } - break; - default: - WARN_INTERNAL_ERROR; - return FALSE; - /* break; */ - } - Value = variant->Number; - if (variable->VariableFlags & VARIABLE_VIRTUAL) /* var_set() */ - { - /* get file information */ - VirtualType *Z; - FileType *F; - - Z = find_virtual_by_variable (variable); - if (Z == NULL) - { - WARN_INTERNAL_ERROR; - return FALSE; - } - offset *= Z->FileLength; /* Byte offset */ - offset += Z->FileOffset; /* Beginning of this data */ - /* update file information */ - F = find_file_by_number (Z->FileNumber); - if (F == NULL) - { - WARN_BAD_FILE_MODE; - return FALSE; - } - if (F->DevMode != DEVMODE_VIRTUAL) - { - WARN_BAD_FILE_MODE; - return FALSE; - } - if (F->cfp == NULL) - { - WARN_BAD_FILE_MODE; - return FALSE; - } - if (fseek (F->cfp, offset, SEEK_SET) != 0) - { - WARN_BAD_FILE_MODE; - return FALSE; - } - switch (variable->VariableTypeCode) - { - case ByteTypeCode: - { - ByteType X; - X = Value; - if (fwrite (&X, sizeof (X), 1, F->cfp) != 1) - { - WARN_DISK_IO_ERROR; - return FALSE; - } - } - break; - case IntegerTypeCode: - { - IntegerType X; - X = Value; - if (fwrite (&X, sizeof (X), 1, F->cfp) != 1) - { - WARN_DISK_IO_ERROR; - return FALSE; - } - } - break; - case LongTypeCode: - { - LongType X; - X = Value; - if (fwrite (&X, sizeof (X), 1, F->cfp) != 1) - { - WARN_DISK_IO_ERROR; - return FALSE; - } - } - break; - case CurrencyTypeCode: - { - CurrencyType X; - X = Value; - if (fwrite (&X, sizeof (X), 1, F->cfp) != 1) - { - WARN_DISK_IO_ERROR; - return FALSE; - } - } - break; - case SingleTypeCode: - { - SingleType X; - X = Value; - if (fwrite (&X, sizeof (X), 1, F->cfp) != 1) - { - WARN_DISK_IO_ERROR; - return FALSE; - } - } - break; - case DoubleTypeCode: - { - DoubleType X; - X = Value; - if (fwrite (&X, sizeof (X), 1, F->cfp) != 1) - { - WARN_DISK_IO_ERROR; - return FALSE; - } - } - break; - case StringTypeCode: - { - WARN_INTERNAL_ERROR; - return FALSE; - } - /* break; */ - default: - { - WARN_INTERNAL_ERROR; - return FALSE; - } - } - } - else - { - DoubleType *number; - number = variable->Value.Number; - if (number == NULL) - { - WARN_INTERNAL_ERROR; - return FALSE; - } - number += offset; - *number = Value; - } - if (variable->VariableFlags & VARIABLE_DISPLAY) /* var_set() */ - { - if (My->ThisLine) /* var_set() */ - { - if (My->ThisLine->LineFlags & (LINE_USER)) /* var_set() */ - { - /* immediate mode */ - } - else - { - FormatBasicNumber (Value, My->NumLenBuffer); - fprintf (My->SYSOUT->cfp, "#%d %s=%s\n", My->ThisLine->number, variable->name, My->NumLenBuffer); /* var_set() */ - ResetConsoleColumn (); - } - } - } - } - return TRUE; -} - -/*************************************************************** - - FUNCTION: dim_check() - - DESCRIPTION: This function checks subscripts of a - specific variable to be sure that they - are within the correct range. - -***************************************************************/ - -static int -dim_check (VariableType * variable) -{ - /* Check for validly allocated array */ - int n; - - assert (variable != NULL); - - - if (variable->VariableFlags & VARIABLE_VIRTUAL) /* var_set() */ - { - if (variable->Value.String != NULL) - { - WARN_INTERNAL_ERROR; - return FALSE; - } - if (variable->Value.Number != NULL) - { - WARN_INTERNAL_ERROR; - return FALSE; - } - } - else if (VAR_IS_STRING (variable)) - { - if (variable->Value.String == NULL) - { - WARN_INTERNAL_ERROR; - return FALSE; - } - } - else - { - if (variable->Value.Number == NULL) - { - WARN_INTERNAL_ERROR; - return FALSE; - } - } - /* Now check subscript values */ - for (n = 0; n < variable->dimensions; n++) - { - if (variable->VINDEX[n] < variable->LBOUND[n] - || variable->VINDEX[n] > variable->UBOUND[n]) - { - WARN_SUBSCRIPT_OUT_OF_RANGE; - return FALSE; - } - } - /* No problems found */ - return TRUE; -} - -/*************************************************************** - - FUNCTION: var_make() - - DESCRIPTION: This function initializes a variable, - allocating necessary memory for it. - -***************************************************************/ - -int -var_make (VariableType * variable, char TypeCode) -{ - /* ALL variables are created here */ - - assert (variable != NULL); - - switch (TypeCode) - { - case ByteTypeCode: - case IntegerTypeCode: - case LongTypeCode: - case CurrencyTypeCode: - case SingleTypeCode: - case DoubleTypeCode: - case StringTypeCode: - /* OK */ - break; - default: - /* ERROR */ - WARN_TYPE_MISMATCH; - return FALSE; - } - - variable->VariableTypeCode = TypeCode; - - /* get memory for array */ - - /* First cleanup the joint (JBV) */ - if (variable->Value.Number != NULL) - { - free (variable->Value.Number); - variable->Value.Number = NULL; - } - if (variable->Value.String != NULL) - { - /* Remember to deallocate those far-flung branches! (JBV) */ - StringType *sp; /* JBV */ - int n; /* JBV */ - - sp = variable->Value.String; - for (n = 0; n < (int) variable->array_units; n++) - { - if (sp[n].sbuffer != NULL) - { - free (sp[n].sbuffer); - sp[n].sbuffer = NULL; - } - sp[n].length = 0; - } - free (variable->Value.String); - variable->Value.String = NULL; - } - - variable->dimensions = 0; - variable->array_units = 1; - - if (VAR_IS_STRING (variable)) - { - if ((variable->Value.String = - calloc (variable->array_units, sizeof (StringType))) == NULL) - { - WARN_OUT_OF_MEMORY; - return FALSE; - } - } - else - { - if ((variable->Value.Number = - calloc (variable->array_units, sizeof (DoubleType))) == NULL) - { - WARN_OUT_OF_MEMORY; - return FALSE; - } - } - return TRUE; - -} - -/*************************************************************** - - FUNCTION: var_islocal() - - DESCRIPTION: This function determines whether the string - pointed to by 'buffer' has the name of - a local variable at the present EXEC stack - level. - -***************************************************************/ - -static VariableType * -mat_islocal (char *buffer) -{ - /* - similar to var_islocal, but returns first matrix found. - */ - - assert (buffer != NULL); - assert( My != NULL ); - - if (My->StackHead != NULL) - { - StackType *StackItem; - for (StackItem = My->StackHead; StackItem != NULL; - StackItem = StackItem->next) - { - if (StackItem->LoopTopLine != NULL) - { - switch (StackItem->LoopTopLine->cmdnum) - { - case C_DEF: - case C_FUNCTION: - case C_SUB: - /* we have found a FUNCTION or SUB boundary */ - { - VariableType *variable; - - for (variable = StackItem->local_variable; variable != NULL; - variable = variable->next) - { - if (variable->dimensions > 0) - { - if (bwb_stricmp (variable->name, buffer) == 0) - { - /* FOUND */ - return variable; - } - } - } - } - /* we have checked all the way to a FUNCTION or SUB boundary */ - /* NOT FOUND */ - return NULL; - /* break; */ - } - } - } - } - /* NOT FOUND */ - return NULL; -} - - -static VariableType * -var_islocal (char *buffer, int dimensions) -{ - - assert (buffer != NULL); - assert( My != NULL ); - - if (My->StackHead != NULL) - { - StackType *StackItem; - for (StackItem = My->StackHead; StackItem != NULL; - StackItem = StackItem->next) - { - if (StackItem->LoopTopLine != NULL) - { - switch (StackItem->LoopTopLine->cmdnum) - { - case C_DEF: - case C_FUNCTION: - case C_SUB: - /* we have found a FUNCTION or SUB boundary */ - { - VariableType *variable; - - for (variable = StackItem->local_variable; variable != NULL; - variable = variable->next) - { - if (variable->dimensions == dimensions) - { - if (bwb_stricmp (variable->name, buffer) == 0) - { - /* FOUND */ - return variable; - } - } - } - } - /* we have checked all the way to a FUNCTION or SUB boundary */ - /* NOT FOUND */ - return NULL; - /* break; */ - } - } - } - } - /* NOT FOUND */ - return NULL; -} - -/*************************************************************** - - FUNCTION: bwb_vars() - - DESCRIPTION: This function implements the Bywater- - specific debugging command VARS, which - gives a list of all variables defined - in memory. - -***************************************************************/ - - -LineType * -bwb_VARS (LineType * l) -{ - VariableType *variable; - - assert (l != NULL); - assert( My != NULL ); - assert( My->SYSOUT != NULL ); - assert( My->SYSOUT->cfp != NULL ); - - /* run through the variable list and print variables */ - - - fprintf (My->SYSOUT->cfp, "%-*s %-6s %-4s %s\n", NameLengthMax, "Name", - "Type", "Dims", "Value"); - - for (variable = My->VariableHead; variable != NULL; - variable = variable->next) - { - VariantType variant; - CLEAR_VARIANT (&variant); - - if (var_get (variable, &variant) == FALSE) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - if (variant.VariantTypeCode == StringTypeCode) - { - fprintf (My->SYSOUT->cfp, "%-*s %-6s %-4d %s\n", NameLengthMax, - variable->name, "STRING", variable->dimensions, - variant.Buffer); - } - else - { - FormatBasicNumber (variant.Number, My->NumLenBuffer); - fprintf (My->SYSOUT->cfp, "%-*s %-6s %-4d %s\n", NameLengthMax, - variable->name, "NUMBER", variable->dimensions, - My->NumLenBuffer); - } - RELEASE_VARIANT (&variant); - } - ResetConsoleColumn (); - return (l); -} - -/*************************************************************** - - FUNCTION: bwb_field() - - DESCRIPTION: This C function implements the BASIC - FIELD command. - -***************************************************************/ - -static void -field_clear (FieldType * Field) -{ - int i; - - assert (Field != NULL); - - Field->File = NULL; - Field->FieldOffset = 0; - Field->FieldLength = 0; - Field->Var = NULL; - for (i = 0; i < MAX_DIMS; i++) - { - Field->VINDEX[i] = 0; - } -} - -static FieldType * -field_new (void) -{ - /* search for an empty slot */ - FieldType *Field; - - assert( My != NULL ); - - for (Field = My->FieldHead; Field != NULL; Field = Field->next) - { - if (Field->File == NULL || Field->Var == NULL) - { - field_clear (Field); - return Field; - } - } - /* not found */ - if ((Field = calloc (1, sizeof (FieldType))) == NULL) - { - WARN_OUT_OF_MEMORY; - return NULL; - } - Field->next = My->FieldHead; - My->FieldHead = Field; - return Field; -} - -void -field_close_file (FileType * File) -{ - /* a CLOSE of a file is in progress, release associated fields */ - FieldType *Field; - - assert (File != NULL); - assert( My != NULL ); - - for (Field = My->FieldHead; Field != NULL; Field = Field->next) - { - if (Field->File == File) - { - Field->File = NULL; - Field->Var = NULL; - } - } -} -void -field_free_variable (VariableType * Var) -{ - /* an ERASE of a variable is in progress, release associated fields */ - FieldType *Field; - - assert (Var != NULL); - assert( My != NULL ); - - for (Field = My->FieldHead; Field != NULL; Field = Field->next) - { - if (Field->Var == Var) - { - Field->File = NULL; - Field->Var = NULL; - } - } -} - - -void -field_get (FileType * File) -{ - /* a GET of the RANDOM file is in progress, update variables from FILE buffer */ - FieldType *Field; - - assert( My != NULL ); - - if (File == NULL) - { - WARN_BAD_FILE_NUMBER; - return; - } - if (File->buffer == NULL) - { - WARN_BAD_FILE_MODE; - return; - } - for (Field = My->FieldHead; Field != NULL; Field = Field->next) - { - if (Field->File == File && Field->Var != NULL) - { - /* from file to variable */ - VariantType variant; - CLEAR_VARIANT (&variant); - - if (Field->FieldOffset < 0) - { - WARN_FIELD_OVERFLOW; - return; - } - if (Field->FieldLength <= 0) - { - WARN_FIELD_OVERFLOW; - return; - } - if ((Field->FieldOffset + Field->FieldLength) > File->width) - { - WARN_FIELD_OVERFLOW; - return; - } - variant.VariantTypeCode = StringTypeCode; - variant.Length = Field->FieldLength; - if ((variant.Buffer = - (char *) calloc (variant.Length + 1 /* NulChar */ , - sizeof (char))) == NULL) - { - WARN_OUT_OF_MEMORY; - return; - } - /* if( TRUE ) */ - { - int i; - - for (i = 0; i < Field->Var->dimensions; i++) - { - Field->Var->VINDEX[i] = Field->VINDEX[i]; - } - } - /* if( TRUE ) */ - { - int i; - char *Buffer; - - Buffer = File->buffer; - Buffer += Field->FieldOffset; - for (i = 0; i < variant.Length; i++) - { - variant.Buffer[i] = Buffer[i]; - } - variant.Buffer[variant.Length] = NulChar; - } - if (var_set (Field->Var, &variant) == FALSE) - { - WARN_VARIABLE_NOT_DECLARED; - return; - } - RELEASE_VARIANT (&variant); - } - } -} -void -field_put (FileType * File) -{ - /* a PUT of the RANDOM file is in progress, update FILE buffer from variables */ - FieldType *Field; - - assert( My != NULL ); - - if (File == NULL) - { - WARN_BAD_FILE_NUMBER; - return; - } - if (File->buffer == NULL) - { - WARN_BAD_FILE_MODE; - return; - } - for (Field = My->FieldHead; Field != NULL; Field = Field->next) - { - if (Field->File == File && Field->Var != NULL) - { - /* from variable to file */ - VariantType variant; - CLEAR_VARIANT (&variant); - - if (Field->FieldOffset < 0) - { - WARN_FIELD_OVERFLOW; - return; - } - if (Field->FieldLength <= 0) - { - WARN_FIELD_OVERFLOW; - return; - } - if ((Field->FieldOffset + Field->FieldLength) > File->width) - { - WARN_FIELD_OVERFLOW; - return; - } - /* if( TRUE ) */ - { - int i; - - for (i = 0; i < Field->Var->dimensions; i++) - { - Field->Var->VINDEX[i] = Field->VINDEX[i]; - } - } - if (var_get (Field->Var, &variant) == FALSE) - { - WARN_VARIABLE_NOT_DECLARED; - return; - } - if (variant.VariantTypeCode != StringTypeCode) - { - WARN_TYPE_MISMATCH; - return; - } - /* if( TRUE ) */ - { - int i; - int n; - char *Buffer; - - i = 0; - n = 0; - Buffer = File->buffer; - Buffer += Field->FieldOffset; - - if (variant.Buffer != NULL) - { - n = MIN (variant.Length, Field->FieldLength); - } - for (i = 0; i < n; i++) - { - Buffer[i] = variant.Buffer[i]; - } - for (i = n; i < Field->FieldLength; i++) - { - /* Pad on the right with spaces */ - Buffer[i] = ' '; - } - } - RELEASE_VARIANT (&variant); - } - } -} - - -LineType * -bwb_FIELD (LineType * l) -{ - FileType *File; - int FileNumber; - int FieldOffset; - - assert (l != NULL); - - FileNumber = 0; - FieldOffset = 0; - - /* first read device number */ - if (line_skip_FilenumChar (l)) - { - /* optional */ - } - if (line_read_integer_expression (l, &FileNumber) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (FileNumber <= 0) - { - /* FIELD # 0 is an error */ - WARN_BAD_FILE_NUMBER; - return (l); - } - File = find_file_by_number (FileNumber); - if (File == NULL) - { - WARN_BAD_FILE_NUMBER; - return (l); - } - if (File->DevMode != DEVMODE_RANDOM) - { - WARN_BAD_FILE_MODE; - return (l); - } - /* loop to read variables */ - - - /* read the comma and advance beyond it */ - while (line_skip_seperator (l)) - { - int FieldLength; - VariableType *variable; - VariantType variant; - - CLEAR_VARIANT (&variant); - - /* first find the size of the field */ - FieldLength = 0; - if (line_read_integer_expression (l, &FieldLength) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - if (FieldLength <= 0) - { - WARN_SYNTAX_ERROR; - return (l); - } - - /* read the AS */ - if (line_skip_word (l, "AS") == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - - /* read the string variable name */ - if ((variable = line_read_scalar (l)) == NULL) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - - if (VAR_IS_STRING (variable)) - { - /* OK */ - } - else - { - WARN_TYPE_MISMATCH; - return (l); - } - /* check for overflow of record length */ - if ((FieldOffset + FieldLength) > File->width) - { - WARN_FIELD_OVERFLOW; - return (l); - } - /* set buffer */ - variant.VariantTypeCode = StringTypeCode; - /* if( TRUE ) */ - { - FieldType *Field; - int i; - - Field = field_new (); - if (Field == NULL) - { - WARN_OUT_OF_MEMORY; - return (l); - } - Field->File = File; - Field->FieldOffset = FieldOffset; - Field->FieldLength = FieldLength; - Field->Var = variable; - for (i = 0; i < variable->dimensions; i++) - { - Field->VINDEX[i] = variable->VINDEX[i]; - } - variant.Length = FieldLength; - if ((variant.Buffer = - (char *) calloc (variant.Length + 1 /* NulChar */ , - sizeof (char))) == NULL) - { - WARN_OUT_OF_MEMORY; - return (l); - } - bwb_memset (variant.Buffer, ' ', variant.Length); - variant.Buffer[variant.Length] = NulChar; - } - if (var_set (variable, &variant) == FALSE) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - RELEASE_VARIANT (&variant); - FieldOffset += FieldLength; - } - /* return */ - return (l); -} - -/*************************************************************** - - FUNCTION: bwb_lset() - - DESCRIPTION: This C function implements the BASIC - LSET command. - - SYNTAX: LSET string-variable$ = expression - -***************************************************************/ - -LineType * -bwb_LSET (LineType * l) -{ - - assert (l != NULL); - return dio_lrset (l, FALSE); -} - -/*************************************************************** - - FUNCTION: bwb_rset() - - DESCRIPTION: This C function implements the BASIC - RSET command. - - SYNTAX: RSET string-variable$ = expression - -***************************************************************/ - -LineType * -bwb_RSET (LineType * l) -{ - - assert (l != NULL); - return dio_lrset (l, TRUE); -} - -/*************************************************************** - - FUNCTION: dio_lrset() - - DESCRIPTION: This C function implements the BASIC - RSET and LSET commands. - -***************************************************************/ - -static LineType * -dio_lrset (LineType * l, int rset) -{ - /* LSET and RSET */ - VariantType variant; - int n; - int i; - int startpos; - VariableType *v; - VariantType t; - VariantType *T; - - assert (l != NULL); - - T = &t; - CLEAR_VARIANT (T); - CLEAR_VARIANT (&variant); - /* get the variable */ - if ((v = line_read_scalar (l)) == NULL) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - if (VAR_IS_STRING (v) == FALSE) - { - WARN_TYPE_MISMATCH; - return (l); - } - - /* skip the equals sign */ - if (line_skip_EqualChar (l) == FALSE) - { - WARN_SYNTAX_ERROR; - return (l); - } - - /* get the value */ - if (line_read_expression (l, T) == FALSE) /* dio_lrset */ - { - WARN_SYNTAX_ERROR; - return (l); - } - if (T->VariantTypeCode != StringTypeCode) - { - WARN_TYPE_MISMATCH; - return (l); - } - if (var_get (v, &variant) == FALSE) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - /* determine starting position */ - startpos = 0; - if (rset == TRUE && T->Length < variant.Length) - { - /* - LET A$ = "123_456" ' variant.Length = 7 - LET B$ = "789" ' T->Length = 3 - RSET A$ = B$ ' startpos = 4 - PRINT "[";A$;"]" ' [123_789] - */ - startpos = variant.Length - T->Length; - } - /* write characters to new position */ - for (n = startpos, i = 0; - (n < (int) variant.Length) && (i < (int) T->Length); n++, i++) - { - variant.Buffer[n] = T->Buffer[i]; - } - if (var_set (v, &variant) == FALSE) - { - WARN_VARIABLE_NOT_DECLARED; - return (l); - } - /* OK */ - RELEASE_VARIANT (T); - RELEASE_VARIANT (&variant); - - return (l); -} - -/* EOF */ diff --git a/Junk/bwbasic.c b/Junk/bwbasic.c deleted file mode 100644 index cfd80f2..0000000 --- a/Junk/bwbasic.c +++ /dev/null @@ -1,3641 +0,0 @@ -/*************************************************************** - - bwbasic.c Main Program File - 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. - -***************************************************************/ - -/*---------------------------------------------------------------*/ -/* NOTE: Modifications marked "JBV" were made by Jon B. Volkoff, */ -/* 11/1995 (eidetics@cerf.net). */ -/* */ -/* Those additionally marked with "DD" were at the suggestion of */ -/* Dale DePriest (daled@cadence.com). */ -/* */ -/* Version 3.00 by Howard Wulf, AF5NE */ -/* */ -/* Version 3.10 by Howard Wulf, AF5NE */ -/* */ -/* Version 3.20 by Howard Wulf, AF5NE */ -/* */ -/* Version 3.20A by Ken Martin */ -/* */ -/*---------------------------------------------------------------*/ - - - -#include "bwbasic.h" - -static void break_handler (void); -static void break_mes (int x); -static int bwb_init (void); -static void bwb_initialize_warnings (void); -static void bwb_interact (void); -static int bwb_ladd (char *buffer, LineType * p, int IsUser); -static void bwb_single_step (char *buffer); -static void bwb_xtxtline (char *buffer); -static int bwx_signon (void); -static void execute_profile (char *FileName); -static void execute_program (char *FileName); -static char *FindClassicStatementEnd (char *C); -static int FixQuotes (char *tbuf); -static void ImportClassicIfThenElse (char *InBuffer); -static int is_ln (char *buffer); -static int is_numconst (char *buffer); -static void mark_preset_variables (void); -static FILE *nice_open (char *BaseName); -static void process_basic_line (char *buffer); - -GlobalType *My = NULL; - -static char *Banner[] = { - "######## ## ## ## ## ### ######## ######## ######## ", - "## ## ## ## ## ## ## ## ## ## ## ## ## ", - "## ## #### ## ## ## ## ## ## ## ## ## ", - "######## ## ## ## ## ## ## ## ###### ######## ", - "## ## ## ## ## ## ######### ## ## ## ## ", - "## ## ## ## ## ## ## ## ## ## ## ## ", - "######## ## ### ### ## ## ## ######## ## ## ", - " ", - " ######## ### ###### #### ###### ", - " ## ## ## ## ## ## ## ## ##", - " ## ## ## ## ## ## ## ", - " ######## ## ## ###### ## ## ", - " ## ## ######### ## ## ## ", - " ## ## ## ## ## ## ## ## ##", - " ######## ## ## ###### #### ###### ", - " ", - "Bywater BASIC Interpreter, version 3.20A ", - "Copyright (c) 1993, Ted A. Campbell ", - "Copyright (c) 1995-1997 , Jon B. Volkoff ", - "Copyright (c) 2014-2017 , Howard Wulf, AF5NE ", - "Copyright (c) 11/2019 , Ken Martin ", - " ", - NULL -}; - -#define NUM_WARNINGS 80 - -static char *ERROR4[NUM_WARNINGS]; - -static void -bwb_initialize_warnings (void) -{ - int i; - for (i = 0; i < NUM_WARNINGS; i++) - { - ERROR4[i] = NULL; - } - ERROR4[1] = "NEXT without FOR"; - ERROR4[2] = "Syntax error"; - ERROR4[3] = "RETURN without GOSUB"; - ERROR4[4] = "Out of DATA"; - ERROR4[5] = "Illegal function call"; - ERROR4[6] = "Overflow"; - ERROR4[7] = "Out of memory"; - ERROR4[8] = "Undefined line"; - ERROR4[9] = "Subscript out of range"; - ERROR4[10] = "Redimensioned array"; - ERROR4[11] = "Division by zero"; - ERROR4[12] = "Illegal direct"; - ERROR4[13] = "Type mismatch"; - ERROR4[14] = "Out of string space"; - ERROR4[15] = "String too long"; - ERROR4[16] = "String formula too complex"; - ERROR4[17] = "Can't continue"; - ERROR4[18] = "Undefined user function"; - ERROR4[19] = "No RESUME"; - ERROR4[20] = "RESUME without error"; - ERROR4[21] = "Unprintable error"; - ERROR4[22] = "Missing operand"; - ERROR4[23] = "Line buffer overflow"; - ERROR4[26] = "FOR without NEXT"; - ERROR4[27] = "Bad DATA"; - ERROR4[29] = "WHILE without WEND"; - ERROR4[30] = "WEND without WHILE"; - ERROR4[31] = "EXIT FUNCTION without FUNCTION"; - ERROR4[32] = "END FUNCTION without FUNCTION"; - ERROR4[33] = "EXIT SUB without SUB"; - ERROR4[34] = "END SUB without SUB"; - ERROR4[35] = "EXIT FOR without FOR"; - ERROR4[50] = "Field overflow"; - ERROR4[51] = "Internal error"; - ERROR4[52] = "Bad file number"; - ERROR4[53] = "File not found"; - ERROR4[54] = "Bad file mode"; - ERROR4[55] = "File already open"; - ERROR4[57] = "Disk I/O error"; - ERROR4[58] = "File already exists"; - ERROR4[61] = "Disk full"; - ERROR4[62] = "Input past end"; - ERROR4[63] = "Bad record number"; - ERROR4[64] = "Bad file name"; - ERROR4[66] = "Direct statement in file"; - ERROR4[67] = "Too many files"; - ERROR4[70] = "Variable Not Declared"; - ERROR4[73] = "Advanced Feature"; -} - -/*************************************************************** - - FUNCTION: bwx_terminate() - - DESCRIPTION: This function terminates program execution. - -***************************************************************/ - -void -bwx_terminate (void) -{ - - exit (0); -} - - - -/*************************************************************** - - FUNCTION: break_handler() - - DESCRIPTION: This function is called by break_mes() - and handles program interruption by break - (or by the STOP command). - -***************************************************************/ -static void -break_handler (void) -{ - /* - ** - ** - */ - assert( My != NULL ); - - My->AutomaticLineNumber = 0; - My->AutomaticLineIncrement = 0; - - if (My->IsInteractive) - { - /* INTERACTIVE: terminate program */ - - /* reset all stack counters */ - bwb_clrexec (); - SetOnError (0); - - My->ERR = -1; /* in break_handler() */ - - - /* reset the break handler */ - signal (SIGINT, break_mes); - - longjmp (My->mark, -1); - - - return; - } - /* NOT INTERACTIVE: terminate immediately */ - bwx_terminate (); -} - -/*************************************************************** - - FUNCTION: break_mes() - - DESCRIPTION: This function is called (a) by a SIGINT - signal or (b) by bwb_STOP via bwx_STOP. - It prints an error message then calls - break_handler() to terminate the program. - -***************************************************************/ - -static void -break_mes (int x /* Parameter 'x' is never used */ ) -{ - /* - ** - ** break_mes is FATAL. - ** x == SIGINT for control-C - ** x == 0 for bwx_STOP - ** - */ - assert( My != NULL ); - assert( My->SYSOUT != NULL ); - assert( My->SYSOUT->cfp != NULL ); - assert( My->CurrentVersion != NULL ); - - - if (My->ERR < 0) /* in break_mes(), do not make a bad situation worse */ - { - /* an error has already ben reported */ - } - else - { - fputc ('\n', My->SYSOUT->cfp); - ResetConsoleColumn (); - if (My->CurrentVersion->OptionVersionValue & (C77)) - { - if (is_empty_string (My->ProgramFilename) == FALSE) - { - fprintf (My->SYSOUT->cfp, "FILE:%s, ", My->ProgramFilename); - } - } - fprintf (My->SYSOUT->cfp, "Program interrupted"); - if (My->ThisLine) /* break_mes */ - { - if (My->ThisLine->LineFlags & (LINE_USER)) /* break_mes */ - { - /* don't print the line number */ - } - else - { - fprintf (My->SYSOUT->cfp, " at line %d", My->ThisLine->number); /* break_mes */ - } - } - fputc ('\n', My->SYSOUT->cfp); - ResetConsoleColumn (); - fflush (My->SYSOUT->cfp); - } - break_handler (); -} - -extern void -bwx_STOP (int IsShowMessage) -{ - - if (IsShowMessage) - { - break_mes (0); - } - else - { - break_handler (); - } -} - -static int -bwx_signon (void) -{ - /* - ** - ** Display a sign-on banner. - ** NOT called if a file is provided on the command line. - ** - */ - int i; - assert( My != NULL ); - assert( My->SYSOUT != NULL ); - assert( My->SYSOUT->cfp != NULL ); - - - for (i = 0; Banner[i] != NULL; i++) - { - fprintf (My->SYSOUT->cfp, "%s\n", Banner[i]); - } - ResetConsoleColumn (); - return TRUE; -} - - - -DoubleType -bwx_TIMER (DoubleType Seconds) -{ - /* - ** - ** Return a number representing Seconds in the future. Seconds >= 0. - ** Seconds may be non-integer, such as 0.001 or 86399.999. The - ** maximum allowed Seconds is MAXDBL. This is used two ways: - ** - ** 1) in bwb_TIMER(), the ON TIMER count (>0) is used to determine - ** the expiration time. In this case, simply return what the value - ** will be in the future. Note that ON TIMER enforces - ** Seconds > (1 / CLOCKS_PER_SEC), and - ** - ** 2) in bwb_execline(), zero (=0) is used to determine the current - ** time and compare it to #1. In this case, simply return what the - ** value is now. - ** - ** Both the resolution of the timer, and the frequency of update, - ** are implementation defined. - ** - */ - - if (Seconds < 0) - { - WARN_INTERNAL_ERROR; - return 0; - } - else - { - DoubleType Result; - Result = clock (); - assert (CLOCKS_PER_SEC > 0); - Result /= CLOCKS_PER_SEC; - if (Seconds > 0) - { - Result += Seconds; - } - return Result; - } -} - -void -CleanLine (char *buffer) -{ - /* - ** - ** cleanup the line, so it is easier to parse - ** - */ - char *newbuffer; - - - - if (is_empty_string (buffer)) - { - /* do nothing */ - return; - } - - /* remove CR/LF */ - newbuffer = bwb_strchr (buffer, '\r'); - if (newbuffer != NULL) - { - *newbuffer = NulChar; - } - newbuffer = bwb_strchr (buffer, '\n'); - if (newbuffer != NULL) - { - *newbuffer = NulChar; - } - - /* remove ALL embedded control characters */ - /* if you want a control character, then use CHR$ */ - newbuffer = buffer; - while (*newbuffer != NulChar) - { - if (bwb_isprint (*newbuffer)) - { - /* OK */ - } - else - { - *newbuffer = ' '; - } - newbuffer++; - } - /* LTRIM$ */ - newbuffer = buffer; - if (*newbuffer != NulChar) - { - /* not an empty line, so remove one (or more) leading spaces */ - while (*newbuffer == ' ') - { - newbuffer++; - } - if (newbuffer > buffer) - { - bwb_strcpy (buffer, newbuffer); - } - } - /* RTRIM$ */ - newbuffer = buffer; - if (*newbuffer != NulChar) - { - /* not an empty line, so remove one (or more) trailing spaces */ - char *E; - - E = bwb_strchr (newbuffer, NulChar); - E--; - while (E >= newbuffer && *E == ' ') - { - *E = NulChar; - E--; - } - } -} - -static int -bwb_init (void) -{ - /* - ** - ** initialize Bywater BASIC - ** - */ - int n; - static char start_buf[] = ""; - static char end_buf[] = ""; - - /* Memory allocation */ - if ((My = (GlobalType *) calloc (1, sizeof (GlobalType))) == NULL) - { - return FALSE; - } - if ((My->MaxLenBuffer = - (char *) calloc (MAXLEN + 1 /* NulChar */ , sizeof (char))) == NULL) - { - return FALSE; - } - if ((My->NumLenBuffer = - (char *) calloc (NUMLEN + 1 /* NulChar */ , sizeof (char))) == NULL) - { - return FALSE; - } - if ((My->ConsoleOutput = - (char *) calloc (MAX_LINE_LENGTH + 1 /* NulChar */ , - sizeof (char))) == NULL) - { - return FALSE; - } - if ((My->ConsoleInput = - (char *) calloc (MAX_LINE_LENGTH + 1 /* NulChar */ , - sizeof (char))) == NULL) - { - return FALSE; - } - if ((My->SYSIN = (FileType *) calloc (1, sizeof (FileType))) == NULL) - { - return FALSE; - } - if ((My->SYSOUT = (FileType *) calloc (1, sizeof (FileType))) == NULL) - { - return FALSE; - } - if ((My->SYSPRN = (FileType *) calloc (1, sizeof (FileType))) == NULL) - { - return FALSE; - } - if ((My->StartMarker = (LineType *) calloc (1, sizeof (LineType))) == NULL) - { - return FALSE; - } - if ((My->UserMarker = (LineType *) calloc (1, sizeof (LineType))) == NULL) - { - return FALSE; - } - if ((My->EndMarker = (LineType *) calloc (1, sizeof (LineType))) == NULL) - { - return FALSE; - } - if ((My->EndMarker = (LineType *) calloc (1, sizeof (LineType))) == NULL) - { - return FALSE; - } - if ((My->ERROR4 = - (char *) calloc (MAX_ERR_LENGTH + 1 /* NulChar */ , - sizeof (char))) == NULL) - { - return FALSE; - } - - My->CurrentVersion = &bwb_vertable[0]; - My->IsInteractive = TRUE; - My->OptionSleepDouble = 1; - My->OptionIndentInteger = 2; - My->OptionTerminalType = C_OPTION_TERMINAL_NONE; - My->OptionRoundType = C_OPTION_ROUND_BANK; - My->NextValidLineNumber = MINLIN; - My->IncludeLevel = 0; /* %INCLUDE */ - My->IsCommandLineFile = FALSE; - My->ExternalInputFile = NULL; /* for automated testing, --TAPE command line parameter */ - My->IsPrinter = FALSE; /* CBASIC-II: CONSOLE and LPRINTER commands */ - My->OptionPromptString = DEF_PROMPT; - My->OptionEditString = DEF_EDITOR; - My->OptionFilesString = DEF_FILES; - My->OptionRenumString = DEF_RENUM; - My->OptionExtensionString = DEF_EXTENSION; - My->OptionScaleInteger = 0; - My->OptionDigitsInteger = SIGNIFICANT_DIGITS; - My->OptionZoneInteger = ZONE_WIDTH; - My->UseParameterString = NULL; - My->ProgramFilename = NULL; - - My->StartMarker->number = MINLIN - 1; - My->StartMarker->next = My->EndMarker; - My->StartMarker->position = 0; - My->StartMarker->buffer = start_buf; - - My->EndMarker->number = MAXLIN + 1; - My->EndMarker->next = My->EndMarker; - My->EndMarker->position = 0; - My->EndMarker->buffer = end_buf; - - My->UserMarker->number = MINLIN - 1; - My->UserMarker->next = My->EndMarker; - My->UserMarker->position = 0; - My->UserMarker->buffer = NULL; - - My->DataLine = My->EndMarker; - My->DataPosition = 0; - - My->StackHead = NULL; - My->StackDepthInteger = 0; - - My->FieldHead = NULL; - - My->VirtualHead = NULL; - My->FileHead = NULL; - My->ThisLine = My->StartMarker; /* bwb_init */ - - My->SYSIN->DevMode = DEVMODE_INPUT; - My->SYSIN->width = 80; - My->SYSIN->col = 1; - My->SYSIN->row = 1; - My->SYSIN->delimit = ','; - My->SYSIN->cfp = stdin; - - My->SYSOUT->DevMode = DEVMODE_OUTPUT; - My->SYSOUT->width = 80; - My->SYSOUT->col = 1; - My->SYSOUT->row = 1; - My->SYSOUT->delimit = ','; - My->SYSOUT->cfp = stdout; - - My->SYSPRN->DevMode = DEVMODE_OUTPUT; - My->SYSPRN->width = 80; - My->SYSPRN->col = 1; - My->SYSPRN->row = 1; - My->SYSPRN->delimit = ','; - My->SYSPRN->cfp = stderr; - - My->LPRINT_NULLS = 0; - My->SCREEN_ROWS = 24; - - /* OPEN #0 is an ERROR. */ - /* CLOSE #0 is an ERROR. */ - /* WIDTH #0, 80 is the same as WIDTH 80. */ - /* LPRINT and LLIST are sent to bwx_LPRINT() */ - - /* default variable type */ - for (n = 0; n < 26; n++) - { - My->DefaultVariableType[n] = DoubleTypeCode; - } - /* default COMMAND$(0-9) */ - for (n = 0; n < 10; n++) - { - My->COMMAND4[n] = NULL; - } - - /* initialize tables of variables, functions */ - bwb_initialize_warnings (); - SortAllCommands (); - SortAllFunctions (); - SortAllOperators (); - var_init (); - IntrinsicFunction_init (); - UserFunction_init (); - OptionVersionSet (0); - /* OK */ - return TRUE; -} - -/*************************************************************** - - 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. - -***************************************************************/ - -static void -process_basic_line (char *buffer) -{ - CleanLine (buffer); - if (is_empty_string (buffer)) - { - /* empty -- do nothing */ - } - else if (is_ln (buffer) == FALSE) - { - /* If there is no line number, then execute the line as received */ - /* RUN */ - WARN_CLEAR; /* process_basic_line */ - SetOnError (0); - bwb_xtxtline (buffer); /* process_basic_line */ - } - else if (is_numconst (buffer) == TRUE) - { - /*-----------------------------------------------------------------*/ - /* Another possibility: if buffer is a numeric constant, */ - /* then delete the indicated line number (JBV) */ - /*-----------------------------------------------------------------*/ - /* 100 */ - int LineNumber; - LineNumber = atoi (buffer); - WARN_CLEAR; /* process_basic_line */ - SetOnError (0); - sprintf (buffer, "delete %d", LineNumber); - bwb_xtxtline (buffer); /* process_basic_line */ - } - else - { - /* If there is a line number, then add it to the BASIC program */ - /* 100 REM */ - bwb_ladd (buffer, My->StartMarker, FALSE); - } -} -static void -bwb_single_step (char *buffer) -{ - assert( My != NULL ); - assert (buffer != NULL); - - process_basic_line (buffer); - while (My->StackHead != NULL) - { - bwb_execline (); - } -} - -static void -mark_preset_variables (void) -{ - /* mark all existing variables as preset */ - /* this includes all variables declared in any PROFILE */ - VariableType *v; - assert( My != NULL ); - - - for (v = My->VariableHead; v != NULL; v = v->next) - { - v->VariableFlags |= VARIABLE_PRESET; - v->VariableFlags |= VARIABLE_COMMON; - } -} - - -static void -execute_profile (char *FileName) -{ - FILE *profile; - assert( My != NULL ); - assert (FileName != NULL); - - My->NextValidLineNumber = MINLIN; - profile = fopen (FileName, "r"); - if (profile == NULL) - { - /* NOT FOUND */ - /* OPTIONAL */ - return; - } - /* FOUND */ - if (My->IsInteractive) - { - /* - ** - ** set a buffer for jump: program execution returns to this point in - ** case of a jump (error, interrupt, or finish program) - ** - */ - My->program_run = 0; - signal (SIGINT, break_mes); - setjmp (My->mark); - if (My->program_run > 0) - { - /* error in PROFILE */ - exit (1); - } - My->program_run++; - } - - /* - The profile only exists to allow executing OPTION ... commands. No other use is supported. - */ - { - char *tbuf; - int tlen; - - tbuf = My->ConsoleInput; - tlen = MAX_LINE_LENGTH; - while (fgets (tbuf, tlen, profile)) /* execute_profile */ - { - tbuf[tlen] = NulChar; - bwb_single_step (tbuf); /* in execute_profile() */ - } - bwb_fclose (profile); - mark_preset_variables (); - } -} - - - -static void -execute_program (char *FileName) -{ - assert( My != NULL ); - assert( My->SYSOUT != NULL ); - assert( My->SYSOUT->cfp != NULL ); - - assert (FileName != NULL); - - My->NextValidLineNumber = MINLIN; - My->IsCommandLineFile = TRUE; - if (bwb_fload (FileName) == FALSE) - { - fprintf (My->SYSOUT->cfp, "Failed to open file %s\n", FileName); - /* the file load has failed, so do NOT run the program */ - exit (1); - } - if (My->ERR < 0 /* in execute_program(), file load failed */ ) - { - /* the file load has failed, so do NOT run the program */ - exit (1); - } - bwb_RUN (My->StartMarker); -} - -extern int -main (int argc, char **argv) -{ - int i; - assert (argc >= 0); - assert (argv != NULL); - - if (bwb_init () == FALSE) - { - /* FATAL */ - puts ("Out of memory"); - return 1; - } - assert( My != NULL ); - assert( My->SYSOUT != NULL ); - assert( My->SYSOUT->cfp != NULL ); - assert( My->SYSIN != NULL ); - assert( My->SYSIN->cfp != NULL ); - - /* Signon message banner */ - if (argc < 2) - { - /* no parameters */ - if (My->IsInteractive) - { - bwx_signon (); - } - else - { - /* if INTERACTIVE is FALSE, then we must have a program file */ - fputs ("Program file not specified\n", My->SYSOUT->cfp); - return 1; - } - } - - if (My->IsInteractive) - { - /* - ** - ** set a buffer for jump: program execution returns to this point in - ** case of a jump (error, interrupt, or finish program) - ** - */ - My->program_run = 0; - signal (SIGINT, break_mes); - setjmp (My->mark); - if (My->program_run > 0) - { - /* error in profile */ - return 1; - } - My->program_run++; - } - -#if PROFILE - execute_profile (PROFILENAME); -#endif - - /* check to see if there is a program file: but do this only the first time around! */ - for (i = 1; i < argc; i++) - { - /* - SYNTAX: bwbasic [ --profile profile.bas ] [ --tape tapefile.inp ] [ program.bas ] - */ - if (bwb_stricmp (argv[i], "--profile") == 0 - || bwb_stricmp (argv[i], "-p") == 0 - || bwb_stricmp (argv[i], "/profile") == 0 - || bwb_stricmp (argv[i], "/p") == 0) - { - i++; - if (i < argc) - { - /* --profile profile.bas */ - execute_profile (argv[i]); - } - } - else - if (bwb_stricmp (argv[i], "--tape") == 0 - || bwb_stricmp (argv[i], "-t") == 0 - || bwb_stricmp (argv[i], "/tape") == 0 - || bwb_stricmp (argv[i], "/t") == 0) - { - i++; - if (i < argc) - { - /* --tape tapefile.inp */ - My->ExternalInputFile = fopen (argv[i], "r"); - } - } - else - { - /* program.bas */ - { - int j; - int n; - - j = i; - for (n = 0; n < 10 && j < argc; n++, j++) - { - My->COMMAND4[n] = argv[j]; - } - } - execute_program (argv[i]); - break; - } - } - - if (My->IsInteractive) - { - /* - ** - ** set a buffer for jump: program execution returns to this point in - ** case of a jump (error, interrupt, or finish program) - ** - */ - My->program_run = 0; - signal (SIGINT, break_mes); - setjmp (My->mark); - if (My->program_run > 0) - { - /* error in console mode */ - } - My->program_run++; - } - - /* main program loop */ - My->NextValidLineNumber = MINLIN; - while (!feof (My->SYSIN->cfp)) /* condition !feof( My->SYSIN->cfp ) added in v1.11 */ - { - bwb_mainloop (); - } - - bwx_terminate (); /* allow ^D (Unix) exit with grace */ - - return 0; -} - - - -/*************************************************************** - - FUNCTION: bwb_interact() - - DESCRIPTION: This function gets a line from the user - and processes it. - -***************************************************************/ - -static void -bwb_interact (void) -{ - char *tbuf; - int tlen; - assert( My != NULL ); - - - tbuf = My->ConsoleInput; - tlen = MAX_LINE_LENGTH; - My->NextValidLineNumber = MINLIN; - /* take input from keyboard */ - if (My->AutomaticLineNumber > 0 && My->AutomaticLineIncrement > 0) - { - /* AUTO 100, 10 */ - char *zbuf; /* end of the prompt, start of the response */ - int zlen; /* length of the prompt */ - char LineExists; - LineType *l; - - LineExists = ' '; - for (l = My->StartMarker->next; l != My->EndMarker; l = l->next) - { - if (l->number == My->AutomaticLineNumber) - { - /* FOUND */ - LineExists = '*'; - break; - } - else if (l->number > My->AutomaticLineNumber) - { - /* NOT FOUND */ - LineExists = ' '; - break; - } - } - sprintf (tbuf, "%d%c", My->AutomaticLineNumber, LineExists); - zbuf = bwb_strchr (tbuf, NulChar); - zlen = bwb_strlen (tbuf); - bwx_input (tbuf, FALSE, zbuf, tlen - zlen); - zbuf[-1] = ' '; /* remove LineExists indicator */ - CleanLine (zbuf); /* JBV */ - if (is_empty_string (zbuf)) - { - /* empty response */ - if (LineExists == '*') - { - /* - An empty response with an existing line, - causes AUTO to continue with the next line, - leaving the current line intact. - */ - My->AutomaticLineNumber += My->AutomaticLineIncrement; - } - else - { - /* - An empty response with a non-existing line, - causes AUTO to terminate. - */ - My->AutomaticLineNumber = 0; - My->AutomaticLineIncrement = 0; - } - } - else - { - /* non-empty response */ - if (bwb_stricmp (zbuf, "MAN") == 0) - { - /* MAN terminates AUTO mode */ - My->AutomaticLineNumber = 0; - My->AutomaticLineIncrement = 0; - } - else - { - /* overwrite any existing line */ - bwb_ladd (tbuf, My->StartMarker, FALSE); - My->AutomaticLineNumber += My->AutomaticLineIncrement; - } - } - } - else - { - bwx_input (My->OptionPromptString, FALSE, tbuf, tlen); - process_basic_line (tbuf); - } -} - - - -/*************************************************************** - - FUNCTION: bwb_fload() - - DESCRIPTION: This function loads a BASIC program - file into memory given a FILE pointer. - -***************************************************************/ - -static int -FixQuotes (char *tbuf) -{ - /* fix unbalanced quotes */ - /* 'tbuf' shall be declared "char tbuf[ tlen + 1]". */ - int p; - int QuoteCount; - int tlen; - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - assert (tbuf != NULL); - - QuoteCount = 0; - tlen = MAX_LINE_LENGTH; - tbuf[tlen] = NulChar; - p = 0; - while (tbuf[p]) - { - if (tbuf[p] == My->CurrentVersion->OptionQuoteChar) - { - QuoteCount++; - } - p++; - } - if (QuoteCount & 1) - { - /* odd == missing trailing quote */ - if (p < tlen) - { - /* we have room to put the missig quote */ - tbuf[p] = My->CurrentVersion->OptionQuoteChar; - p++; - tbuf[p] = NulChar; - } - else - { - /* we cannot fix it */ - return FALSE; - } - } - /* OK */ - return TRUE; -} - -static FILE * -nice_open (char *BaseName) -{ - FILE *file; - assert( My != NULL ); - - if (BaseName == NULL) - { - BaseName = My->ProgramFilename; - } - if (is_empty_string (BaseName)) - { - WARN_BAD_FILE_NAME; - return NULL; - } - - file = fopen (BaseName, "r"); - if (file == NULL) - if (is_empty_string (My->OptionExtensionString) == FALSE) - { - char *FileName; - - FileName = bwb_strdup2 (BaseName, My->OptionExtensionString); - if (FileName == NULL) - { - WARN_OUT_OF_MEMORY; - return NULL; - } - file = fopen (FileName, "r"); - if (file == NULL) - { - free (FileName); - } - else if (BaseName == My->ProgramFilename) - { - if (My->ProgramFilename != NULL) - { - free (My->ProgramFilename); - } - My->ProgramFilename = FileName; - } - } - return file; -} - -extern int -bwb_fload (char *FileName) -{ - /* - ** - ** Load a BASIC program from the specified 'FileName'. - ** If 'FileName' is NULL, then load from My->ProgramFilename, - ** - */ - char *Magic_Word; /* SYNTAX: %INCLUDE literal.file.name */ - int Magic_Length; - FILE *file; - char *tbuf; - int tlen; - - - - - Magic_Word = "%INCLUDE "; /* SYNTAX: %INCLUDE literal.file.name */ - Magic_Length = bwb_strlen (Magic_Word); - tbuf = My->MaxLenBuffer; - tlen = MAXLEN; - - - /* - Just in case you are wondering... - Although this handles the most common cases, it does not handle all possible cases. - The correct solution is to provide the actual filename (with extension), - as it exists in the operating system. - */ - file = nice_open (FileName); - if (file == NULL) - { - WARN_BAD_FILE_NAME; - return FALSE; - } - My->NextValidLineNumber = MINLIN; - while (fgets (tbuf, tlen, file)) /* bwb_fload */ - { - tbuf[tlen] = NulChar; - CleanLine (tbuf); - if (is_empty_string (tbuf)) - { - /* ignore */ - } - else if (bwb_strnicmp (tbuf, Magic_Word, Magic_Length) == 0) - { - /* %iNCLUDE */ - int Result; - int p; - char varname[NameLengthMax + 1]; - - p = Magic_Length; - if (buff_read_varname (tbuf, &p, varname) == FALSE) - { - fprintf (My->SYSOUT->cfp, "%s Filename\n", Magic_Word); - ResetConsoleColumn (); - return FALSE; - } - My->IncludeLevel++; /* %INCLUDE */ - Result = bwb_fload (varname); - My->IncludeLevel--; /* %INCLUDE */ - if (Result == FALSE) - { - fprintf (My->SYSOUT->cfp, "%s %s Failed\n", Magic_Word, varname); - ResetConsoleColumn (); - return FALSE; - } - } - else - { - /* normal */ - bwb_ladd (tbuf, My->StartMarker, FALSE); - } - } - - /* close file stream */ - - bwb_fclose (file); /* file != NULL */ - - My->NextValidLineNumber = MINLIN; - - return TRUE; -} - - -static char * -FindClassicStatementEnd (char *C) -{ - /* - ** find the end of the current statement - */ - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - - assert (C != NULL); - - - if (My->CurrentVersion->OptionStatementChar == NulChar - && My->CurrentVersion->OptionCommentChar == NulChar) - { - /* DO NOTHING: Multi-statment lines are not possible */ - return NULL; - } - /* skip line number */ - while (bwb_isdigit (*C)) - { - C++; - } - /* skip spaces */ - while (*C == ' ') - { - C++; - } - if (IS_CHAR (*C, My->CurrentVersion->OptionCommentChar)) - { - /* The entire line is a comment */ - return NULL; - } - if (bwb_strnicmp (C, "REM", 3) == 0) - { - /* The entire line is a comment */ - return NULL; - } - if ((My->CurrentVersion->OptionFlags & OPTION_LABELS_ON) - && (My->CurrentVersion->OptionStatementChar != NulChar)) - { - /* determine if this line is a LABEL */ - int p; - char label[NameLengthMax + 1]; - - p = 0; - if (buff_read_label (C, &p, label)) - { - if (buff_skip_char (C, &p, My->CurrentVersion->OptionStatementChar)) - { - if (buff_is_eol (C, &p)) - { - /* The entire line is a label */ - /* LABEL : \0 */ - return NULL; - } - } - } - } - /* not a special case, so split on the first unquoted OptionCommentChar or OptionStatementChar */ - while (*C != NulChar) - { - if (*C == My->CurrentVersion->OptionQuoteChar) - { - /* skip leading quote */ - C++; - while (*C != NulChar && *C != My->CurrentVersion->OptionQuoteChar) - { - /* skip string constant */ - C++; - } - if (*C == My->CurrentVersion->OptionQuoteChar) - { - /* skip trailing quote */ - C++; - } - } - else if (IS_CHAR (*C, My->CurrentVersion->OptionCommentChar) /* ', ! */ ) - { - /* FOUND */ - return C; - } - else - if (IS_CHAR (*C, My->CurrentVersion->OptionStatementChar) /* :, \ */ ) - { - /* FOUND */ - return C; - } - else - { - C++; - } - } - /* NOT FOUND */ - return NULL; -} - - -static void -ImportClassicIfThenElse (char *InBuffer) -{ -/* -** -** Determine the type of IF command: -** -** a) STANDARD: -** IF x THEN line ELSE line -** -** b) CLASSIC: -** IF x THEN stmt(s) ELSE stmt(s) -** -** c) STRUCTURED: -** IF x THEN -** stmts -** ELSE -** stmts -** END IF -** -** The STANDARD and STRUCTURED forms -** are natively supported. -** -** The CLASSIC form is converted to -** the STRUCTURED form. -** -*/ - - int i; - - int nIF = 0; - int nTHEN = 0; - int nELSE = 0; - int nENDIF = 0; - -#define NO_COMMAND 0 -#define IF_COMMAND 1 -#define THEN_COMMAND 2 -#define ELSE_COMMAND 3 -#define ENDIF_COMMAND 4 - int LastCommand = NO_COMMAND; - - const char *REM = "REM "; - const char *IF = "IF "; - const char *THEN = "THEN "; - const char *THEN2 = "THEN"; - const char *ELSE = "ELSE "; - const char *ENDIF = "END IF"; - const char *GOTO = "GOTO "; - const char *DATA = "DATA "; - const char *CASE = "CASE "; - char *OutBuffer = My->ConsoleOutput; - char *Input; - char *Output; - char LastChar = My->CurrentVersion->OptionStatementChar; - - int REM_len = bwb_strlen (REM); - int IF_len = bwb_strlen (IF); - int THEN_len = bwb_strlen (THEN); - int THEN2_len = bwb_strlen (THEN2); - int ELSE_len = bwb_strlen (ELSE); - int ENDIF_len = bwb_strlen (ENDIF); - int GOTO_len = bwb_strlen (GOTO); - int DATA_len = bwb_strlen (DATA); - int CASE_len = bwb_strlen (CASE); - -#define OUTPUTCHAR( c ) { *Output = c; Output++; } -#define COPYCHAR { LastChar = *Input; *Output = *Input; Output++; Input++; } -#define COPY_LINENUMBER while( bwb_isdigit( *Input ) ) COPYCHAR; -#define COPY_SPACES while( *Input == ' ' ) COPYCHAR; -#define COPY_IF for( i = 0; i < IF_len; i++ ) COPYCHAR; -#define COPY_THEN for( i = 0; i < THEN_len; i++ ) COPYCHAR; -#define COPY_THEN2 for( i = 0; i < THEN2_len; i++ ) COPYCHAR; -#define COPY_ELSE for( i = 0; i < ELSE_len; i++ ) COPYCHAR; -#define COPY_ENDIF for( i = 0; i < ENDIF_len; i++ ) COPYCHAR; -#define FORCE_ENDIF for( i = 0; i < ENDIF_len; i++ ) OUTPUTCHAR( ENDIF[ i ] ); -#define FORCE_GOTO for( i = 0; i < GOTO_len; i++ ) OUTPUTCHAR( GOTO[ i ] ); -#define FORCE_COLON if( LastChar != My->CurrentVersion->OptionStatementChar ) OUTPUTCHAR( My->CurrentVersion->OptionStatementChar ); - - assert( My != NULL ); - assert( My->CurrentVersion != NULL ); - assert (InBuffer != NULL); - - - Input = InBuffer; - Output = OutBuffer; - - - - - - if (My->CurrentVersion->OptionStatementChar == NulChar) - { - /* DO NOTHING: All IFs must be STANDARD or STRUCTURED */ - return; - } - - - COPY_LINENUMBER; - COPY_SPACES; - LastChar = My->CurrentVersion->OptionStatementChar; - - - while (*Input != NulChar) - { - if (*Input == My->CurrentVersion->OptionCommentChar) - { - /* comment */ - break; - } - else if (*Input == My->CurrentVersion->OptionQuoteChar) - { - /* string constant */ - COPYCHAR; - while (*Input != NulChar - && *Input != My->CurrentVersion->OptionQuoteChar) - { - COPYCHAR; - } - if (*Input == My->CurrentVersion->OptionQuoteChar) - { - COPYCHAR; - } - else - { - /* add missing Quote */ - OUTPUTCHAR (My->CurrentVersion->OptionQuoteChar); - } - COPY_SPACES; - } - else if (bwb_isalnum (LastChar)) - { - /* can NOT be the start of a command */ - COPYCHAR; - } - else if (!bwb_isalpha (*Input)) - { - /* can NOT be the start of a command */ - COPYCHAR; - } - else if (bwb_strnicmp (Input, REM, REM_len) == 0) - { - break; - } - else if (bwb_strnicmp (Input, DATA, DATA_len) == 0) - { - /* DATA ... */ - break; - } - else if (bwb_strnicmp (Input, CASE, CASE_len) == 0) - { - /* CASE ... */ - break; - } - else if (bwb_strnicmp (Input, IF, IF_len) == 0) - { - /* IF */ - LastCommand = IF_COMMAND; - nIF++; - COPY_IF; - COPY_SPACES; - } - else if (bwb_strnicmp (Input, GOTO, GOTO_len) == 0 && nIF > nTHEN) - { - /* IF x GOTO line ELSE line */ - LastCommand = THEN_COMMAND; - nTHEN++; - COPY_THEN; - COPY_SPACES; - COPY_LINENUMBER; - COPY_SPACES; - if (bwb_strnicmp (Input, ELSE, ELSE_len) == 0) - { - /* ELSE line */ - COPY_ELSE; - COPY_SPACES; - COPY_LINENUMBER; - COPY_SPACES; - } - /* IS STANDARD, NOT CLASSIC */ - nENDIF++; - LastCommand = ENDIF_COMMAND; - } - else if (bwb_strnicmp (Input, THEN, THEN_len) == 0) - { - /* THEN */ - LastCommand = THEN_COMMAND; - nTHEN++; - COPY_THEN; - COPY_SPACES; - if (bwb_isdigit (*Input)) - { - /* STANDARD: IF x THEN line ELSE line */ - char *SavedInput; - char *SavedOutput; - SavedInput = Input; - SavedOutput = Output; - - COPY_LINENUMBER; - COPY_SPACES; - if (bwb_strnicmp (Input, ELSE, ELSE_len) == 0) - { - /* ELSE line */ - COPY_ELSE; - COPY_SPACES; - if (bwb_isdigit (*Input)) - { - COPY_LINENUMBER; - COPY_SPACES; - /* IS STANDARD, NOT CLASSIC */ - nENDIF++; - LastCommand = ENDIF_COMMAND; - } - else - { - /* IF x THEN line ELSE stmts */ - Input = SavedInput; - Output = SavedOutput; - FORCE_COLON; - FORCE_GOTO; - COPY_LINENUMBER; - COPY_SPACES; - } - } - else - { - /* IS STANDARD, NOT CLASSIC */ - nENDIF++; - LastCommand = ENDIF_COMMAND; - } - } - else - if (*Input == My->CurrentVersion->OptionCommentChar - || *Input == NulChar) - { - /* IS STRUCTURED, NOT CLASSIC */ - nENDIF++; - LastCommand = ENDIF_COMMAND; - } - else - { - /* CLASSIC: IF x THEN stmts ELSE stmts */ - } - FORCE_COLON; - } - else if (bwb_strnicmp (Input, THEN2, THEN2_len) == 0) - { - /* trailing THEN ? */ - char *PeekInput; - - PeekInput = Input; - PeekInput += THEN2_len; - while (*PeekInput == ' ') - { - PeekInput++; - } - if (*PeekInput == My->CurrentVersion->OptionCommentChar - || *PeekInput == NulChar) - { - /* IS STRUCTURED, NOT CLASSIC */ - nTHEN++; - COPY_THEN2; - nENDIF++; - LastCommand = ENDIF_COMMAND; - FORCE_COLON; - } - else - { - /* THEN line */ - } - } - else if (bwb_strnicmp (Input, ELSE, ELSE_len) == 0) - { - /* ELSE */ - if (LastCommand == ELSE_COMMAND) - { - /* we need an ENDIF here */ - FORCE_COLON; - FORCE_ENDIF; - FORCE_COLON; - nENDIF++; - } - LastCommand = ELSE_COMMAND; - nELSE++; - FORCE_COLON; - COPY_ELSE; - FORCE_COLON; - COPY_SPACES; - if (bwb_isdigit (*Input)) - { - /* IF x THEN stmts ELSE line */ - FORCE_GOTO; - COPY_LINENUMBER; - COPY_SPACES; - } - FORCE_COLON; - } - else if (bwb_strnicmp (Input, ENDIF, ENDIF_len) == 0) - { - /* ENDIF */ - LastCommand = ENDIF_COMMAND; - nENDIF++; - COPY_ENDIF; - FORCE_COLON; - } - else - { - /* was NOT the start of a command */ - COPYCHAR; - } - } - /* end of input */ - if (nENDIF < nIF) - { - while (nENDIF < nIF) - { - /* we need trailing ENDIF's */ - nENDIF++; - FORCE_COLON; - FORCE_ENDIF; - } - } - /* fixup trailing REMark command */ - if (bwb_strnicmp (Input, REM, REM_len) == 0) - { - /* REMark */ - /* 100 A=1 REMark */ - /* 100 A=1:REMark */ - /* 100 A=1'REMark */ - FORCE_COLON; - } - /* copy the comments */ - while (*Input != NulChar) - { - COPYCHAR; - /* cppcheck: (style) Variable 'LastChar' is assigned a value that is never used. */ - } - OUTPUTCHAR (NulChar); - bwb_strcpy (InBuffer, OutBuffer); -} - - -/*************************************************************** - - FUNCTION: bwb_ladd() - - DESCRIPTION: This function adds a new line (in the - buffer) to the program in memory. - -***************************************************************/ -static int -bwb_ladd (char *buffer, LineType * p, int IsUser) -{ - LineType *l; - LineType *previous; - char *newbuffer; - char *NextStatement; - char *ThisStatement; - int Replace; - char BreakChar; - - assert( My != NULL ); - assert( My->SYSOUT != NULL ); - assert( My->SYSOUT->cfp != NULL ); - assert( My->CurrentVersion != NULL ); - assert (buffer != NULL); - assert (p != NULL); - - - Replace = TRUE; - BreakChar = NulChar; - CleanLine (buffer); - if (is_empty_string (buffer)) - { - /* silengtly ignore blank lines */ - return FALSE; - } - /* - from here, the line WILL be added so the user can EDIT it, - we just complain and refuse to run if any error is detected. - */ - My->IsScanRequired = TRUE; /* program needs to be scanned again */ - - /* AUTO-FIX UNBALANCED QUOTES */ - if (FixQuotes (buffer) == FALSE) - { - /* ERROR */ - fprintf (My->SYSOUT->cfp, "UNBALANCED QUOTES: %s\n", buffer); - ResetConsoleColumn (); - My->ERR = -1; /* bwb_ladd, UNBALANCED QUOTES */ - } - - if (IS_CHAR (*buffer, My->CurrentVersion->OptionStatementChar)) - { - /* part of a multi-statement line */ - } - else if (IS_CHAR (*buffer, My->CurrentVersion->OptionCommentChar)) - { - /* part of a multi-statement line */ - } - else - { - ImportClassicIfThenElse (buffer); - } - ThisStatement = buffer; - NextStatement = NULL; - BreakChar = NulChar; - - do - { - if (BreakChar == NulChar) - { - /* first pass thru the do{} while loop, do nothing */ - } - else if (IS_CHAR (BreakChar, My->CurrentVersion->OptionCommentChar)) - { - /* ThisStatment will turn out to be the last */ - *ThisStatement = My->CurrentVersion->OptionCommentChar; - } - else if (IS_CHAR (BreakChar, My->CurrentVersion->OptionStatementChar)) - { - /* we are NOT the last statement, skip over the OptionStatementChar */ - ThisStatement++; - } - else - { - /* Internal Error */ - } - - if (BreakChar == NulChar - && IS_CHAR (*buffer, My->CurrentVersion->OptionStatementChar)) - { - /* first pass thru and line begins with colon */ - /* part of a multi-statement line */ - NextStatement = NULL; - if (My->NextValidLineNumber > 1) - { - My->NextValidLineNumber--; - } - Replace = FALSE; - } - else - if (BreakChar == NulChar - && IS_CHAR (*buffer, My->CurrentVersion->OptionCommentChar)) - { - /* first pass thru and line begins with apostrophe */ - /* part of a multi-statement line */ - NextStatement = NULL; - if (My->NextValidLineNumber > 1) - { - My->NextValidLineNumber--; - } - Replace = FALSE; - } - else - { - NextStatement = FindClassicStatementEnd (ThisStatement); - } - - if (NextStatement == NULL) - { - /* we are the last statement */ - } - else - { - /* another statement follows */ - BreakChar = *NextStatement; - *NextStatement = NulChar; - } - CleanLine (ThisStatement); - if (is_empty_string (ThisStatement) == FALSE) - { - - /* get memory for this line */ - if ((l = (LineType *) calloc (1, sizeof (LineType))) == NULL) - { - /* ERROR */ - fprintf (My->SYSOUT->cfp, "Out of memory\n"); - ResetConsoleColumn (); - My->ERR = -1; /* bwb_ladd, Out of memory */ - return FALSE; - } - - /* this line has not been executed or numbered */ - l->LineFlags = 0; - if (IsUser) - { - l->LineFlags |= LINE_USER; - } - l->IncludeLevel = My->IncludeLevel; /* %INCLUDE */ - l->position = 0; - - /* - ** - ** ALL lines have a line number. - ** If a line number is not provided, - ** then the next available line number is assigned. - ** - */ - newbuffer = ThisStatement; - l->number = My->NextValidLineNumber; - - if (buff_read_line_number (newbuffer, &(l->position), &l->number)) - { - if (l->number < My->NextValidLineNumber) - { - /* ERROR */ - fprintf (My->SYSOUT->cfp, "%d < %d - LINE OUT OF ORDER: %s\n", - l->number, My->NextValidLineNumber, buffer); - ResetConsoleColumn (); - My->ERR = -1; /* bwb_ladd, LINE OUT OF ORDER */ - l->number = My->NextValidLineNumber; /* sane default */ - } - else if (l->number < MINLIN || l->number > MAXLIN) - { - /* ERROR */ - fprintf (My->SYSOUT->cfp, "INVALID LINE NUMBER: %s\n", buffer); - ResetConsoleColumn (); - My->ERR = -1; /* bwb_ladd, INVALID LINE NUMBER */ - l->number = My->NextValidLineNumber; /* sane default */ - } - else - { - /* OK */ - My->NextValidLineNumber = l->number; - l->LineFlags |= LINE_NUMBERED; /* line was manually numbered */ - } - /* A SPACE IS REQUIRED AFTER THE LINE NUMBER -- NO EXCEPTIONS */ - if (newbuffer[l->position] != ' ') - { - /* ERROR */ - fprintf (My->SYSOUT->cfp, "MISSING SPACE AFTER LINE NUMBER: %s\n", - buffer); - ResetConsoleColumn (); - My->ERR = -1; /* bwb_ladd, MISSING SPACE AFTER LINE NUMBER */ - } - /* newuffer does NOT contain the line number */ - newbuffer += l->position; - } - /* the next valid line number is this line number plus one */ - CleanLine (newbuffer); - if (*newbuffer != NulChar - && *newbuffer == My->CurrentVersion->OptionStatementChar) - { - /* this is part of a multi-statement line */ - newbuffer++; - CleanLine (newbuffer); - } - /* - ** - ** copy into the line buffer - ** - */ - if (l->buffer != NULL) - { - free (l->buffer); - l->buffer = NULL; /* JBV */ - } - if ((l->buffer = - (char *) calloc (bwb_strlen (newbuffer) + 1 /* NulChar */ , - sizeof (char))) == NULL) - { - /* ERROR */ - fprintf (My->SYSOUT->cfp, "Out of memory\n"); - ResetConsoleColumn (); - My->ERR = -1; /* bwb_ladd, Out of memory */ - return FALSE; /* we cannot determine the command */ - } - bwb_strcpy (l->buffer, newbuffer); - /* - ** - ** determine command - ** - */ - line_start (l); - if (l->cmdnum) - { - /* OK */ - } - else - { - /* ERROR */ - fprintf (My->SYSOUT->cfp, - "ILLEGAL COMMAND AFTER LINE NUMBER: %d %s\n", l->number, - l->buffer); - ResetConsoleColumn (); - My->ERR = -1; /* bwb_ladd, ILLEGAL COMMAND AFTER LINE NUMBER */ - } - /* - ** - ** add the line to the linked-list of lines - ** - */ - for (previous = p; previous != My->EndMarker; previous = previous->next) - { - if (previous->number == l->number) - { - if (Replace == TRUE) - { - /* REPLACE 'previous' */ - while (previous->number == l->number) - { - LineType *z; - - z = previous; - previous = previous->next; - bwb_freeline (z); - } - l->next = previous; - p->next = l; - - } - else - { - /* APPEND after 'previous' */ - while (previous->next->number == l->number) - { - previous = previous->next; - } - l->next = previous->next; - previous->next = l; - } - break; - } - else - if (previous->number < l->number - && l->number < previous->next->number) - { - /* INSERT BETWEEN 'previous' AND 'previous->next' */ - l->next = previous->next; - previous->next = l; - break; - } - p = previous; - } - - } - /* another statement may follow */ - ThisStatement = NextStatement; - Replace = FALSE; - } - while (ThisStatement != NULL); - My->NextValidLineNumber++; - return TRUE; -} - -/*************************************************************** - - FUNCTION: bwb_xtxtline() - - DESCRIPTION: This function executes a text line, i.e., - places it in memory and then relinquishes - control. - -***************************************************************/ - -static void -bwb_xtxtline (char *buffer) -{ - assert( My != NULL ); - assert (buffer != NULL); - - /* remove old program from memory */ - bwb_xnew (My->UserMarker); - - CleanLine (buffer); - if (is_empty_string (buffer)) - { - /* silengtly ignore blank lines */ - return; - } - - /* add to the user line list */ - bwb_ladd (buffer, My->UserMarker, TRUE); - - /* execute the line as BASIC command line */ - if (bwb_incexec ()) - { - My->StackHead->line = My->UserMarker->next; /* and set current line in it */ - My->StackHead->ExecCode = EXEC_NORM; - } -} - -/*************************************************************** - - FUNCTION: bwb_incexec() - - DESCRIPTION: This function increments the EXEC - stack counter. - -***************************************************************/ - -int -bwb_incexec (void) -{ - StackType *StackItem; - assert( My != NULL ); - - - if (My->StackDepthInteger >= EXECLEVELS) - { - WARN_OUT_OF_MEMORY; - return FALSE; - } - if ((StackItem = (StackType *) calloc (1, sizeof (StackType))) == NULL) - { - WARN_OUT_OF_MEMORY; - return FALSE; - } - StackItem->ExecCode = EXEC_NORM; /* sane default */ - StackItem->line = My->ThisLine; /* bwb_incexec */ - StackItem->LoopTopLine = NULL; - StackItem->local_variable = NULL; - StackItem->OnErrorGoto = 0; - StackItem->next = My->StackHead; - My->StackHead = StackItem; - My->StackDepthInteger++; - return TRUE; -} - -/*************************************************************** - - FUNCTION: bwb_decexec() - - DESCRIPTION: This function decrements the EXEC - stack counter. - -***************************************************************/ -void -bwb_clrexec (void) -{ - assert( My != NULL ); - - while (My->StackHead != NULL) - { - bwb_decexec (); - } -} - -void -bwb_decexec (void) -{ - StackType *StackItem; - assert( My != NULL ); - - - if (My->StackHead == NULL) - { - WARN_RETURN_WITHOUT_GOSUB; - return; - } - StackItem = My->StackHead; - My->StackHead = StackItem->next; - free (StackItem); - My->StackDepthInteger--; -} - -/*************************************************************** - - FUNCTION: bwb_mainloop() - - DESCRIPTION: This C function performs one iteration - of the interpreter. In a non-preemptive - scheduler, this function should be called - by the scheduler, not by bwBASIC code. - -***************************************************************/ - -void -bwb_mainloop (void) -{ - assert( My != NULL ); - - - if (My->StackHead) - { - /* BASIC program running */ - bwb_execline (); /* execute one line of program */ - return; - } - /* BASIC program completed */ - - if (My->ExternalInputFile != NULL) - { - /* for automated testing, --TAPE command line parameter */ - if (bwb_is_eof (My->ExternalInputFile) == FALSE) - { - /* --TAPE command line parameter is active */ - bwb_interact (); /* get user interaction */ - return; - } - } - /* TAPE command inactive or completed */ - - if (My->IsCommandLineFile) - { - /* BASIC program was started from command line */ - bwx_terminate (); - return; - } - /* BASIC program was not started from command line */ - - if (My->IsInteractive) - { - /* interactive */ - bwb_interact (); /* get user interaction */ - return; - } - /* non-interactive */ - - bwx_terminate (); -} - -/*************************************************************** - - FUNCTION: bwb_execline() - - DESCRIPTION: This function executes a single line of - a program in memory. This function is - called by bwb_mainloop(). - -***************************************************************/ - -extern int -bwx_Error (int ERR, char *ErrorMessage) -{ - /* - ERR is the error number - ErrorMessage is used to override the default error message, and is usually NULL - */ - assert( My != NULL ); - - switch (ERR) - { - case 0: - /* - ** - ** Clear any existing error - ** - */ - My->IsErrorPending = FALSE; /* bwx_Error, ERR == 0 */ - My->ERR = 0; /* bwx_Error, ERR == 0 */ - My->ERL = NULL; /* bwx_Error, ERR == 0 */ - bwb_strcpy (My->ERROR4, ""); /* bwx_Error, ERR == 0 */ - return FALSE; - case 6: /* WARN_OVERFLOW */ - case 11: /* WARN_DIVISION_BY_ZERO */ - case 15: /* WARN_STRING_TOO_LONG */ - /* - ** - ** Behavior depends upon whether an Error handler is active. - ** - */ - if (GetOnError () == 0) - { - /* - ** - ** Error handler is NOT active. - ** Do NOT set ERL, ERR, and ERROR$. - ** Continue processing. - ** - */ - if (ErrorMessage == NULL) - { - /* use the default error message */ - if (ERR > 0 && ERR < NUM_WARNINGS) - { - ErrorMessage = ERROR4[ERR]; - } - } - if (ErrorMessage != NULL) - { - if (bwb_strlen (ErrorMessage) > 0) - { - fprintf (My->SYSOUT->cfp, "%s\n", ErrorMessage); - ResetConsoleColumn (); - } - } - return FALSE; /* continue processing */ - } - /* - ** - ** Error handler IS active. - ** Fall-thru to set ERL, ERR, and ERROR$. - ** Abort processing. - ** - */ - } - if (My->IsErrorPending == FALSE) /* no errors pending */ - { - /* - ** - ** only keep the first pending error to occur - ** - */ - My->IsErrorPending = TRUE; /* bwx_Error, ERR != 0 */ - My->ERR = ERR; /* bwx_Error, ERR != 0 */ - My->ERL = NULL; /* bwx_Error, ERR != 0 */ - bwb_strcpy (My->ERROR4, ""); /* bwx_Error, ERR != 0 */ - if (My->StackHead) - { - My->ERL = My->StackHead->line; - } - if (ErrorMessage == NULL) - { - /* use the default error message */ - if (ERR > 0 && ERR < NUM_WARNINGS) - { - ErrorMessage = ERROR4[ERR]; - } - } - if (ErrorMessage != NULL) - { - if (bwb_strlen (ErrorMessage) > MAX_ERR_LENGTH) - { - ErrorMessage[MAX_ERR_LENGTH] = NulChar; - } - bwb_strcpy (My->ERROR4, ErrorMessage); - } - } - return TRUE; /* abort processing */ -} - -void -bwb_execline (void) -{ - LineType *r, *l; - assert( My != NULL ); - assert( My->SYSOUT != NULL ); - assert( My->SYSOUT->cfp != NULL ); - assert( My->CurrentVersion != NULL ); - - if (My->StackHead == NULL) /* in bwb_execline(), FATAL ERROR PENDING */ - { - return; - } - - l = My->StackHead->line; - - /* if the line is My->EndMarker, then break out of EXEC loops */ - if (l == NULL || l == My->EndMarker || My->ERR < 0) /* in bwb_execline(), FATAL ERROR PENDING */ - { - bwb_clrexec (); - return; - } - - My->ThisLine = l; /* bwb_execline */ - - /* Print line number if trace is on */ - if (My->IsTraceOn == TRUE) - { - if (l->LineFlags & (LINE_USER)) - { - /* USER line in console */ - } - else if (l->number > 0) - { - fprintf (My->SYSOUT->cfp, "[ %d %s ]", l->number, l->buffer); - } - } - l->position = l->Startpos; - - /* if there is a BASIC command in the line, execute it here */ - if (l->cmdnum) - { - /* OK */ - } - else - { - WARN_ILLEGAL_DIRECT; - l->cmdnum = C_REM; - } - /* l->cmdnum != 0 */ - - if (l->LineFlags & LINE_BREAK) - { - /* BREAK line */ - l->LineFlags &= ~LINE_BREAK; - My->ContinueLine = l; - bwx_STOP (TRUE); - return; - } - - /* advance beyond whitespace */ - line_skip_spaces (l); /* keep this */ - - /* execute the command vector */ - if (My->CurrentVersion->OptionFlags & (OPTION_COVERAGE_ON)) - { - /* We do this here so "END" and "STOP" are marked */ - if (l->cmdnum == C_DATA) - { - /* DATA lines are marked when they are READ */ - } - else - { - /* this line was executed */ - l->LineFlags |= LINE_EXECUTED; - } - } - r = bwb_vector (l); - if (r == NULL) - { - WARN_INTERNAL_ERROR; - return; - } - assert (r != NULL); - - if (My->ERR < 0) /* in bwb_execline(), FATAL ERROR PENDING */ - { - /* FATAL */ - bwb_clrexec (); - return; - } - - if (My->IsErrorPending /* Keep This */ ) - { - /* we are probably not at the end-of-the-line */ - } - else if (r == l) - { - /* we should be at the end-of-the-line */ - if (line_is_eol (l)) - { - /* OK */ - } - else - { - WARN_SYNTAX_ERROR; - return; - } - } - else - { - /* we are probably not at the end-of-the-line */ - } - - if (My->IsErrorPending /* Keep This */ ) - { - /* - ** - ** a NON-FATAL ERROR has occurred. ERR, ERL, and ERROR$ were - ** already set using bwb_warning(ERR,ERROR$) - ** - */ - int err_gotol; - My->IsErrorPending = FALSE; /* Error Recognized */ - err_gotol = GetOnError (); - if (l->LineFlags & (LINE_USER)) - { - /* - ** - ** ------------------------------------------------------------------------- - ** USER line in console - ** ------------------------------------------------------------------------- - ** - ** fall thru to the DEFAULT ERROR HANDLER - ** - */ - } - else if (l->number == 0) - { - /* fall thru to the DEFAULT ERROR HANDLER */ - } - else if (My->ERL == NULL) - { - /* fall thru to the DEFAULT ERROR HANDLER */ - } - else if (My->ERL->number == 0) - { - /* fall thru to the DEFAULT ERROR HANDLER */ - } - else if (err_gotol == -1) - { - /* - ** - ** ------------------------------------------------------------------------- - ** ON ERROR RESUME NEXT - ** ------------------------------------------------------------------------- - ** - */ - assert (r != NULL); - assert (r->next != NULL); - - r->next->position = 0; - assert (My->StackHead != NULL); - My->StackHead->line = r->next; - return; - } - else if (err_gotol == 0) - { - /* - ** - ** ------------------------------------------------------------------------- - ** ON ERROR GOTO 0 - ** ------------------------------------------------------------------------- - ** - ** fall thru to the DEFAULT ERROR HANDLER - ** - */ - } - else if (err_gotol == My->ERL->number) - { - /* - ** - ** ------------------------------------------------------------------------- - ** RECURSION - ** ------------------------------------------------------------------------- - ** - ** For example: - ** 10 ON ERROR GOTO 20 - ** 20 ERROR 1 - ** - ** fall thru to the DEFAULT ERROR HANDLER - ** - */ - } - else - { - /* USER ERROR HANDLER SPECIFIED */ - /* find the user-specified error handler and jump there */ - LineType *x; - for (x = My->StartMarker->next; x != My->EndMarker; x = x->next) - { - if (x->number == err_gotol) - { - /* FOUND */ - if (My->CurrentVersion->OptionFlags & (OPTION_ERROR_GOSUB)) - { - /* - ** - ** ------------------------------------------------------------------------- - ** OPTION ERROR GOSUB - ** ------------------------------------------------------------------------- - ** - ** RETURN should act like RESUME NEXT... - ** Execution resumes at the statement immediately following the one which caused the error. - ** For structured commands, this is the bottom line of the structure. - ** - */ - switch (l->cmdnum) - { - case C_IF8THEN: - /* skip to END_IF */ - assert (l->OtherLine != NULL); - for (l = l->OtherLine; l->cmdnum != C_END_IF; l = l->OtherLine); - break; - case C_SELECT_CASE: - /* skip to END_SELECT */ - assert (l->OtherLine != NULL); - for (l = l->OtherLine; l->cmdnum != C_END_SELECT; - l = l->OtherLine); - break; - default: - l = l->next; - } - l->position = 0; - My->StackHead->line = l; - if (bwb_incexec ()) - { - x->position = 0; - assert (My->StackHead != NULL); - My->StackHead->line = x; - My->StackHead->ExecCode = EXEC_GOSUB; - } - else - { - /* ERROR -- OUT OF MEMORY */ - assert (My->StackHead != NULL); - My->StackHead->line = My->EndMarker; - } - } - else - { - /* - ** - ** ------------------------------------------------------------------------- - ** OPTION ERROR GOTO - ** ------------------------------------------------------------------------- - ** - */ - x->position = 0; /* start of line */ - assert (My->StackHead != NULL); - My->StackHead->line = x; - } - return; - } - } - /* NOT FOUND */ - /* fall thru to the DEFAULT ERROR HANDLER */ - } - /* - ** - ** ------------------------------------------------------------------------- - ** DEFAULT ERROR HANDLER (FATAL) - ** ------------------------------------------------------------------------- - ** - */ - /* - ** - ** display error message - ** - */ - if (l->LineFlags & (LINE_USER) || l->number <= 0) - { - /* USER line in console */ - fprintf (My->SYSOUT->cfp, "\nERROR: %s\n", My->ERROR4); - ResetConsoleColumn (); - } - else - { - /* BASIC program line */ - fprintf (My->SYSOUT->cfp, "\nERROR in line %d: %s\n", l->number, - My->ERROR4); - ResetConsoleColumn (); - /* - ** - ** display stack trace - ** - */ - if (My->CurrentVersion->OptionFlags & (OPTION_TRACE_ON)) - { - /* - ** Dump the BASIC stack trace when a FATAL error occurs. - ** First line is the TOP of the stack. - ** Last line is the BOTTOM of the stack. - */ - StackType *StackItem; - fprintf (My->SYSOUT->cfp, "\nSTACK TRACE:\n"); - for (StackItem = My->StackHead; StackItem != NULL; - StackItem = StackItem->next) - { - LineType *l; - - l = StackItem->line; - if (l != NULL) - { - if (MINLIN <= l->number && l->number <= MAXLIN) - { - /* BASIC program line */ - if (l->buffer == NULL) - { - fprintf (My->SYSOUT->cfp, "%d\n", l->number); - } - else - { - fprintf (My->SYSOUT->cfp, "%d:%s\n", l->number, l->buffer); - } - } - } - } - ResetConsoleColumn (); - } - } - - My->AutomaticLineNumber = 0; - My->AutomaticLineIncrement = 0; - - if (My->IsInteractive) - { - /* INTERACTIVE: terminate program */ - - /* reset all stack counters */ - bwb_clrexec (); - SetOnError (0); - - My->ERR = -1; /* in bwb_execline(), default error handler */ - - - /* reset the break handler */ - signal (SIGINT, break_mes); - - - return; - } - /* NOT INTERACTIVE: terminate immediately */ - bwx_terminate (); - return; /* never reached */ - } - if (l->number > 0) - { - /* These events only occur in running programs */ - if (My->IsTimerOn) - { - /* TIMER ON */ - if (My->OnTimerCount > 0) - { - if (bwx_TIMER (0) > My->OnTimerExpires) - { - My->IsTimerOn = FALSE; - if (My->OnTimerLineNumber > 0) - { - /* ON TIMER( My->OnTimerCount ) GOSUB My->OnTimerLineNumber */ - LineType *x; - - for (x = My->StartMarker->next; x != My->EndMarker; x = x->next) - { - if (x->number == My->OnTimerLineNumber) - { - /* FOUND */ - /* save current stack level */ - assert (My->StackHead != NULL); - My->StackHead->line = r; - /* increment exec stack */ - if (bwb_incexec ()) - { - /* set the new position to x and return x */ - x->position = 0; - assert (My->StackHead != NULL); - My->StackHead->line = x; - My->StackHead->ExecCode = EXEC_GOSUB; - } - else - { - /* ERROR */ - assert (My->StackHead != NULL); - My->StackHead->line = My->EndMarker; - } - return; - } - } - /* NOT FOUND */ - } - } - } - } - } - /* check for end of line: if so, advance to next line and return */ - if (r == l) - { - /* advance to the next line */ - l->next->position = 0; - r = l->next; - } - else if (line_is_eol (r)) - { - /* we could be at the end-of-the-line, added for RETURN */ - /* advance to the next line */ - r->next->position = 0; - r = r->next; - } - /* else reset with the value in r */ - assert (My->StackHead != NULL); - My->StackHead->line = r; -} - -/*************************************************************** - - FUNCTION: is_ln() - - DESCRIPTION: This function determines whether a program - line (in buffer) begins with a line number. - -***************************************************************/ - -static int -is_ln (char *buffer) -{ - int position; - - assert (buffer != NULL); - - position = 0; - buff_skip_spaces (buffer, &position); /* keep this */ - if (bwb_isdigit (buffer[position])) - { - return TRUE; - } - return FALSE; -} - -/*************************************************************** - - FUNCTION: is_numconst() - - DESCRIPTION: This function reads the string in - 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. - -***************************************************************/ - -static int -is_numconst (char *buffer) -{ - char *p; - - assert (buffer != NULL); - - /* Return FALSE for empty buffer */ - - if (buffer[0] == NulChar) - { - return FALSE; - } - /* else check digits */ - - p = buffer; - while (*p != NulChar) - { - 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; - -} - -/* SWITCH */ -LineType * -bwb_vector( LineType *l ) -{ - LineType *r; - assert (l != NULL); - switch( l->cmdnum ) - { - case C_DEF8LBL: - r = bwb_DEF8LBL( l ); - break; - case C_APPEND: - r = bwb_APPEND( l ); - break; - case C_AS: - r = bwb_AS( l ); - break; - case C_AUTO: - r = bwb_AUTO( l ); - break; - case C_BACKSPACE: - r = bwb_BACKSPACE( l ); - break; - case C_BREAK: - r = bwb_BREAK( l ); - break; - case C_BUILD: - r = bwb_BUILD( l ); - break; - case C_BYE: - r = bwb_BYE( l ); - break; - case C_CALL: - r = bwb_CALL( l ); - break; - case C_CASE: - r = bwb_CASE( l ); - break; - case C_CASE_ELSE: - r = bwb_CASE_ELSE( l ); - break; - case C_CHAIN: - r = bwb_CHAIN( l ); - break; - case C_CHANGE: - r = bwb_CHANGE( l ); - break; - case C_CLEAR: - r = bwb_CLEAR( l ); - break; - case C_CLOAD: - r = bwb_CLOAD( l ); - break; - case C_CLOAD8: - r = bwb_CLOAD8( l ); - break; - case C_CLOSE: - r = bwb_CLOSE( l ); - break; - case C_CLR: - r = bwb_CLR( l ); - break; - case C_CMDS: - r = bwb_CMDS( l ); - break; - case C_COMMON: - r = bwb_COMMON( l ); - break; - case C_CONSOLE: - r = bwb_CONSOLE( l ); - break; - case C_CONST: - r = bwb_CONST( l ); - break; - case C_CONT: - r = bwb_CONT( l ); - break; - case C_CONTINUE: - r = bwb_CONTINUE( l ); - break; - case C_COPY: - r = bwb_COPY( l ); - break; - case C_CREATE: - r = bwb_CREATE( l ); - break; - case C_CSAVE: - r = bwb_CSAVE( l ); - break; - case C_CSAVE8: - r = bwb_CSAVE8( l ); - break; - case C_DATA: - r = bwb_DATA( l ); - break; - case C_DEC: - r = bwb_DEC( l ); - break; - case C_DEF: - r = bwb_DEF( l ); - break; - case C_DEFBYT: - r = bwb_DEFBYT( l ); - break; - case C_DEFCUR: - r = bwb_DEFCUR( l ); - break; - case C_DEFDBL: - r = bwb_DEFDBL( l ); - break; - case C_DEFINT: - r = bwb_DEFINT( l ); - break; - case C_DEFLNG: - r = bwb_DEFLNG( l ); - break; - case C_DEFSNG: - r = bwb_DEFSNG( l ); - break; - case C_DEFSTR: - r = bwb_DEFSTR( l ); - break; - case C_DELETE: - r = bwb_DELETE( l ); - break; - case C_DELIMIT: - r = bwb_DELIMIT( l ); - break; - case C_DIM: - r = bwb_DIM( l ); - break; - case C_DISPLAY: - r = bwb_DISPLAY( l ); - break; - case C_DO: - r = bwb_DO( l ); - break; - case C_DOS: - r = bwb_DOS( l ); - break; - case C_DSP: - r = bwb_DSP( l ); - break; - case C_EDIT: - r = bwb_EDIT( l ); - break; - case C_ELSE: - r = bwb_ELSE( l ); - break; - case C_ELSEIF: - r = bwb_ELSEIF( l ); - break; - case C_END: - r = bwb_END( l ); - break; - case C_END_FUNCTION: - r = bwb_END_FUNCTION( l ); - break; - case C_END_IF: - r = bwb_END_IF( l ); - break; - case C_END_SELECT: - r = bwb_END_SELECT( l ); - break; - case C_END_SUB: - r = bwb_END_SUB( l ); - break; - case C_ERASE: - r = bwb_ERASE( l ); - break; - case C_EXCHANGE: - r = bwb_EXCHANGE( l ); - break; - case C_EXIT: - r = bwb_EXIT( l ); - break; - case C_EXIT_DO: - r = bwb_EXIT_DO( l ); - break; - case C_EXIT_FOR: - r = bwb_EXIT_FOR( l ); - break; - case C_EXIT_FUNCTION: - r = bwb_EXIT_FUNCTION( l ); - break; - case C_EXIT_REPEAT: - r = bwb_EXIT_REPEAT( l ); - break; - case C_EXIT_SUB: - r = bwb_EXIT_SUB( l ); - break; - case C_EXIT_WHILE: - r = bwb_EXIT_WHILE( l ); - break; - case C_FEND: - r = bwb_FEND( l ); - break; - case C_FIELD: - r = bwb_FIELD( l ); - break; - case C_FILE: - r = bwb_FILE( l ); - break; - case C_FILES: - r = bwb_FILES( l ); - break; - case C_FLEX: - r = bwb_FLEX( l ); - break; - case C_FNCS: - r = bwb_FNCS( l ); - break; - case C_FNEND: - r = bwb_FNEND( l ); - break; - case C_FOR: - r = bwb_FOR( l ); - break; - case C_FUNCTION: - r = bwb_FUNCTION( l ); - break; - case C_GET: - r = bwb_GET( l ); - break; - case C_GO: - r = bwb_GO( l ); - break; - case C_GO_SUB: - r = bwb_GO_SUB( l ); - break; - case C_GO_TO: - r = bwb_GO_TO( l ); - break; - case C_GOODBYE: - r = bwb_GOODBYE( l ); - break; - case C_GOSUB: - r = bwb_GOSUB( l ); - break; - case C_GOTO: - r = bwb_GOTO( l ); - break; - case C_HELP: - r = bwb_HELP( l ); - break; - case C_IF: - r = bwb_IF( l ); - break; - case C_IF_END: - r = bwb_IF_END( l ); - break; - case C_IF_MORE: - r = bwb_IF_MORE( l ); - break; - case C_IF8THEN: - r = bwb_IF8THEN( l ); - break; - case C_IMAGE: - r = bwb_IMAGE( l ); - break; - case C_INC: - r = bwb_INC( l ); - break; - case C_INPUT: - r = bwb_INPUT( l ); - break; - case C_INPUT_LINE: - r = bwb_INPUT_LINE( l ); - break; - case C_LET: - r = bwb_LET( l ); - break; - case C_LINE: - r = bwb_LINE( l ); - break; - case C_LINE_INPUT: - r = bwb_LINE_INPUT( l ); - break; - case C_LIST: - r = bwb_LIST( l ); - break; - case C_LISTNH: - r = bwb_LISTNH( l ); - break; - case C_LLIST: - r = bwb_LLIST( l ); - break; - case C_LOAD: - r = bwb_LOAD( l ); - break; - case C_LOCAL: - r = bwb_LOCAL( l ); - break; - case C_LOOP: - r = bwb_LOOP( l ); - break; - case C_LPRINT: - r = bwb_LPRINT( l ); - break; - case C_LPRINTER: - r = bwb_LPRINTER( l ); - break; - case C_LPT: - r = bwb_LPT( l ); - break; - case C_LSET: - r = bwb_LSET( l ); - break; - case C_MAINTAINER: - r = bwb_MAINTAINER( l ); - break; - case C_MAINTAINER_CMDS: - r = bwb_MAINTAINER_CMDS( l ); - break; - case C_MAINTAINER_CMDS_HTML: - r = bwb_MAINTAINER_CMDS_HTML( l ); - break; - case C_MAINTAINER_CMDS_ID: - r = bwb_MAINTAINER_CMDS_ID( l ); - break; - case C_MAINTAINER_CMDS_MANUAL: - r = bwb_MAINTAINER_CMDS_MANUAL( l ); - break; - case C_MAINTAINER_CMDS_SWITCH: - r = bwb_MAINTAINER_CMDS_SWITCH( l ); - break; - case C_MAINTAINER_CMDS_TABLE: - r = bwb_MAINTAINER_CMDS_TABLE( l ); - break; - case C_MAINTAINER_DEBUG: - r = bwb_MAINTAINER_DEBUG( l ); - break; - case C_MAINTAINER_DEBUG_OFF: - r = bwb_MAINTAINER_DEBUG_OFF( l ); - break; - case C_MAINTAINER_DEBUG_ON: - r = bwb_MAINTAINER_DEBUG_ON( l ); - break; - case C_MAINTAINER_FNCS: - r = bwb_MAINTAINER_FNCS( l ); - break; - case C_MAINTAINER_FNCS_HTML: - r = bwb_MAINTAINER_FNCS_HTML( l ); - break; - case C_MAINTAINER_FNCS_ID: - r = bwb_MAINTAINER_FNCS_ID( l ); - break; - case C_MAINTAINER_FNCS_MANUAL: - r = bwb_MAINTAINER_FNCS_MANUAL( l ); - break; - case C_MAINTAINER_FNCS_SWITCH: - r = bwb_MAINTAINER_FNCS_SWITCH( l ); - break; - case C_MAINTAINER_FNCS_TABLE: - r = bwb_MAINTAINER_FNCS_TABLE( l ); - break; - case C_MAINTAINER_MANUAL: - r = bwb_MAINTAINER_MANUAL( l ); - break; - case C_MAINTAINER_STACK: - r = bwb_MAINTAINER_STACK( l ); - break; - case C_MARGIN: - r = bwb_MARGIN( l ); - break; - case C_MAT: - r = bwb_MAT( l ); - break; - case C_MAT_GET: - r = bwb_MAT_GET( l ); - break; - case C_MAT_INPUT: - r = bwb_MAT_INPUT( l ); - break; - case C_MAT_PRINT: - r = bwb_MAT_PRINT( l ); - break; - case C_MAT_PUT: - r = bwb_MAT_PUT( l ); - break; - case C_MAT_READ: - r = bwb_MAT_READ( l ); - break; - case C_MAT_WRITE: - r = bwb_MAT_WRITE( l ); - break; - case C_MERGE: - r = bwb_MERGE( l ); - break; - case C_MID4: - r = bwb_MID4( l ); - break; - case C_MON: - r = bwb_MON( l ); - break; - case C_NAME: - r = bwb_NAME( l ); - break; - case C_NEW: - r = bwb_NEW( l ); - break; - case C_NEXT: - r = bwb_NEXT( l ); - break; - case C_OF: - r = bwb_OF( l ); - break; - case C_OLD: - r = bwb_OLD( l ); - break; - case C_ON: - r = bwb_ON( l ); - break; - case C_ON_ERROR: - r = bwb_ON_ERROR( l ); - break; - case C_ON_ERROR_GOSUB: - r = bwb_ON_ERROR_GOSUB( l ); - break; - case C_ON_ERROR_GOTO: - r = bwb_ON_ERROR_GOTO( l ); - break; - case C_ON_ERROR_RESUME: - r = bwb_ON_ERROR_RESUME( l ); - break; - case C_ON_ERROR_RESUME_NEXT: - r = bwb_ON_ERROR_RESUME_NEXT( l ); - break; - case C_ON_ERROR_RETURN: - r = bwb_ON_ERROR_RETURN( l ); - break; - case C_ON_ERROR_RETURN_NEXT: - r = bwb_ON_ERROR_RETURN_NEXT( l ); - break; - case C_ON_TIMER: - r = bwb_ON_TIMER( l ); - break; - case C_OPEN: - r = bwb_OPEN( l ); - break; - case C_OPTION: - r = bwb_OPTION( l ); - break; - case C_OPTION_ANGLE: - r = bwb_OPTION_ANGLE( l ); - break; - case C_OPTION_ANGLE_DEGREES: - r = bwb_OPTION_ANGLE_DEGREES( l ); - break; - case C_OPTION_ANGLE_GRADIANS: - r = bwb_OPTION_ANGLE_GRADIANS( l ); - break; - case C_OPTION_ANGLE_RADIANS: - r = bwb_OPTION_ANGLE_RADIANS( l ); - break; - case C_OPTION_ARITHMETIC: - r = bwb_OPTION_ARITHMETIC( l ); - break; - case C_OPTION_ARITHMETIC_DECIMAL: - r = bwb_OPTION_ARITHMETIC_DECIMAL( l ); - break; - case C_OPTION_ARITHMETIC_FIXED: - r = bwb_OPTION_ARITHMETIC_FIXED( l ); - break; - case C_OPTION_ARITHMETIC_NATIVE: - r = bwb_OPTION_ARITHMETIC_NATIVE( l ); - break; - case C_OPTION_BASE: - r = bwb_OPTION_BASE( l ); - break; - case C_OPTION_BUGS: - r = bwb_OPTION_BUGS( l ); - break; - case C_OPTION_BUGS_BOOLEAN: - r = bwb_OPTION_BUGS_BOOLEAN( l ); - break; - case C_OPTION_BUGS_OFF: - r = bwb_OPTION_BUGS_OFF( l ); - break; - case C_OPTION_BUGS_ON: - r = bwb_OPTION_BUGS_ON( l ); - break; - case C_OPTION_COMPARE: - r = bwb_OPTION_COMPARE( l ); - break; - case C_OPTION_COMPARE_BINARY: - r = bwb_OPTION_COMPARE_BINARY( l ); - break; - case C_OPTION_COMPARE_DATABASE: - r = bwb_OPTION_COMPARE_DATABASE( l ); - break; - case C_OPTION_COMPARE_TEXT: - r = bwb_OPTION_COMPARE_TEXT( l ); - break; - case C_OPTION_COVERAGE: - r = bwb_OPTION_COVERAGE( l ); - break; - case C_OPTION_COVERAGE_OFF: - r = bwb_OPTION_COVERAGE_OFF( l ); - break; - case C_OPTION_COVERAGE_ON: - r = bwb_OPTION_COVERAGE_ON( l ); - break; - case C_OPTION_DATE: - r = bwb_OPTION_DATE( l ); - break; - case C_OPTION_DIGITS: - r = bwb_OPTION_DIGITS( l ); - break; - case C_OPTION_DISABLE: - r = bwb_OPTION_DISABLE( l ); - break; - case C_OPTION_DISABLE_COMMAND: - r = bwb_OPTION_DISABLE_COMMAND( l ); - break; - case C_OPTION_DISABLE_FUNCTION: - r = bwb_OPTION_DISABLE_FUNCTION( l ); - break; - case C_OPTION_DISABLE_OPERATOR: - r = bwb_OPTION_DISABLE_OPERATOR( l ); - break; - case C_OPTION_EDIT: - r = bwb_OPTION_EDIT( l ); - break; - case C_OPTION_ENABLE: - r = bwb_OPTION_ENABLE( l ); - break; - case C_OPTION_ENABLE_COMMAND: - r = bwb_OPTION_ENABLE_COMMAND( l ); - break; - case C_OPTION_ENABLE_FUNCTION: - r = bwb_OPTION_ENABLE_FUNCTION( l ); - break; - case C_OPTION_ENABLE_OPERATOR: - r = bwb_OPTION_ENABLE_OPERATOR( l ); - break; - case C_OPTION_ERROR: - r = bwb_OPTION_ERROR( l ); - break; - case C_OPTION_ERROR_GOSUB: - r = bwb_OPTION_ERROR_GOSUB( l ); - break; - case C_OPTION_ERROR_GOTO: - r = bwb_OPTION_ERROR_GOTO( l ); - break; - case C_OPTION_EXPLICIT: - r = bwb_OPTION_EXPLICIT( l ); - break; - case C_OPTION_EXTENSION: - r = bwb_OPTION_EXTENSION( l ); - break; - case C_OPTION_FILES: - r = bwb_OPTION_FILES( l ); - break; - case C_OPTION_IMPLICIT: - r = bwb_OPTION_IMPLICIT( l ); - break; - case C_OPTION_INDENT: - r = bwb_OPTION_INDENT( l ); - break; - case C_OPTION_LABELS: - r = bwb_OPTION_LABELS( l ); - break; - case C_OPTION_LABELS_OFF: - r = bwb_OPTION_LABELS_OFF( l ); - break; - case C_OPTION_LABELS_ON: - r = bwb_OPTION_LABELS_ON( l ); - break; - case C_OPTION_PROMPT: - r = bwb_OPTION_PROMPT( l ); - break; - case C_OPTION_PUNCT: - r = bwb_OPTION_PUNCT( l ); - break; - case C_OPTION_PUNCT_AT: - r = bwb_OPTION_PUNCT_AT( l ); - break; - case C_OPTION_PUNCT_BYTE: - r = bwb_OPTION_PUNCT_BYTE( l ); - break; - case C_OPTION_PUNCT_COMMENT: - r = bwb_OPTION_PUNCT_COMMENT( l ); - break; - case C_OPTION_PUNCT_CURRENCY: - r = bwb_OPTION_PUNCT_CURRENCY( l ); - break; - case C_OPTION_PUNCT_DOUBLE: - r = bwb_OPTION_PUNCT_DOUBLE( l ); - break; - case C_OPTION_PUNCT_FILENUM: - r = bwb_OPTION_PUNCT_FILENUM( l ); - break; - case C_OPTION_PUNCT_IMAGE: - r = bwb_OPTION_PUNCT_IMAGE( l ); - break; - case C_OPTION_PUNCT_INPUT: - r = bwb_OPTION_PUNCT_INPUT( l ); - break; - case C_OPTION_PUNCT_INTEGER: - r = bwb_OPTION_PUNCT_INTEGER( l ); - break; - case C_OPTION_PUNCT_LONG: - r = bwb_OPTION_PUNCT_LONG( l ); - break; - case C_OPTION_PUNCT_LPAREN: - r = bwb_OPTION_PUNCT_LPAREN( l ); - break; - case C_OPTION_PUNCT_PRINT: - r = bwb_OPTION_PUNCT_PRINT( l ); - break; - case C_OPTION_PUNCT_QUOTE: - r = bwb_OPTION_PUNCT_QUOTE( l ); - break; - case C_OPTION_PUNCT_RPAREN: - r = bwb_OPTION_PUNCT_RPAREN( l ); - break; - case C_OPTION_PUNCT_SINGLE: - r = bwb_OPTION_PUNCT_SINGLE( l ); - break; - case C_OPTION_PUNCT_STATEMENT: - r = bwb_OPTION_PUNCT_STATEMENT( l ); - break; - case C_OPTION_PUNCT_STRING: - r = bwb_OPTION_PUNCT_STRING( l ); - break; - case C_OPTION_RECLEN: - r = bwb_OPTION_RECLEN( l ); - break; - case C_OPTION_RENUM: - r = bwb_OPTION_RENUM( l ); - break; - case C_OPTION_ROUND: - r = bwb_OPTION_ROUND( l ); - break; - case C_OPTION_ROUND_BANK: - r = bwb_OPTION_ROUND_BANK( l ); - break; - case C_OPTION_ROUND_MATH: - r = bwb_OPTION_ROUND_MATH( l ); - break; - case C_OPTION_ROUND_TRUNCATE: - r = bwb_OPTION_ROUND_TRUNCATE( l ); - break; - case C_OPTION_SCALE: - r = bwb_OPTION_SCALE( l ); - break; - case C_OPTION_SLEEP: - r = bwb_OPTION_SLEEP( l ); - break; - case C_OPTION_STDERR: - r = bwb_OPTION_STDERR( l ); - break; - case C_OPTION_STDIN: - r = bwb_OPTION_STDIN( l ); - break; - case C_OPTION_STDOUT: - r = bwb_OPTION_STDOUT( l ); - break; - case C_OPTION_STRICT: - r = bwb_OPTION_STRICT( l ); - break; - case C_OPTION_STRICT_OFF: - r = bwb_OPTION_STRICT_OFF( l ); - break; - case C_OPTION_STRICT_ON: - r = bwb_OPTION_STRICT_ON( l ); - break; - case C_OPTION_TERMINAL: - r = bwb_OPTION_TERMINAL( l ); - break; - case C_OPTION_TERMINAL_ADM: - r = bwb_OPTION_TERMINAL_ADM( l ); - break; - case C_OPTION_TERMINAL_ANSI: - r = bwb_OPTION_TERMINAL_ANSI( l ); - break; - case C_OPTION_TERMINAL_NONE: - r = bwb_OPTION_TERMINAL_NONE( l ); - break; - case C_OPTION_TIME: - r = bwb_OPTION_TIME( l ); - break; - case C_OPTION_TRACE: - r = bwb_OPTION_TRACE( l ); - break; - case C_OPTION_TRACE_OFF: - r = bwb_OPTION_TRACE_OFF( l ); - break; - case C_OPTION_TRACE_ON: - r = bwb_OPTION_TRACE_ON( l ); - break; - case C_OPTION_USING: - r = bwb_OPTION_USING( l ); - break; - case C_OPTION_USING_ALL: - r = bwb_OPTION_USING_ALL( l ); - break; - case C_OPTION_USING_COMMA: - r = bwb_OPTION_USING_COMMA( l ); - break; - case C_OPTION_USING_DIGIT: - r = bwb_OPTION_USING_DIGIT( l ); - break; - case C_OPTION_USING_DOLLAR: - r = bwb_OPTION_USING_DOLLAR( l ); - break; - case C_OPTION_USING_EXRAD: - r = bwb_OPTION_USING_EXRAD( l ); - break; - case C_OPTION_USING_FILLER: - r = bwb_OPTION_USING_FILLER( l ); - break; - case C_OPTION_USING_FIRST: - r = bwb_OPTION_USING_FIRST( l ); - break; - case C_OPTION_USING_LENGTH: - r = bwb_OPTION_USING_LENGTH( l ); - break; - case C_OPTION_USING_LITERAL: - r = bwb_OPTION_USING_LITERAL( l ); - break; - case C_OPTION_USING_MINUS: - r = bwb_OPTION_USING_MINUS( l ); - break; - case C_OPTION_USING_PERIOD: - r = bwb_OPTION_USING_PERIOD( l ); - break; - case C_OPTION_USING_PLUS: - r = bwb_OPTION_USING_PLUS( l ); - break; - case C_OPTION_VERSION: - r = bwb_OPTION_VERSION( l ); - break; - case C_OPTION_ZONE: - r = bwb_OPTION_ZONE( l ); - break; - case C_PAUSE: - r = bwb_PAUSE( l ); - break; - case C_PDEL: - r = bwb_PDEL( l ); - break; - case C_POP: - r = bwb_POP( l ); - break; - case C_PRINT: - r = bwb_PRINT( l ); - break; - case C_PTP: - r = bwb_PTP( l ); - break; - case C_PTR: - r = bwb_PTR( l ); - break; - case C_PUT: - r = bwb_PUT( l ); - break; - case C_QUIT: - r = bwb_QUIT( l ); - break; - case C_READ: - r = bwb_READ( l ); - break; - case C_RECALL: - r = bwb_RECALL( l ); - break; - case C_REM: - r = bwb_REM( l ); - break; - case C_RENAME: - r = bwb_RENAME( l ); - break; - case C_RENUM: - r = bwb_RENUM( l ); - break; - case C_RENUMBER: - r = bwb_RENUMBER( l ); - break; - case C_REPEAT: - r = bwb_REPEAT( l ); - break; - case C_REPLACE: - r = bwb_REPLACE( l ); - break; - case C_RESET: - r = bwb_RESET( l ); - break; - case C_RESTORE: - r = bwb_RESTORE( l ); - break; - case C_RESUME: - r = bwb_RESUME( l ); - break; - case C_RETURN: - r = bwb_RETURN( l ); - break; - case C_RSET: - r = bwb_RSET( l ); - break; - case C_RUN: - r = bwb_RUN( l ); - break; - case C_RUNNH: - r = bwb_RUNNH( l ); - break; - case C_SAVE: - r = bwb_SAVE( l ); - break; - case C_SCRATCH: - r = bwb_SCRATCH( l ); - break; - case C_SELECT: - r = bwb_SELECT( l ); - break; - case C_SELECT_CASE: - r = bwb_SELECT_CASE( l ); - break; - case C_STEP: - r = bwb_STEP( l ); - break; - case C_STOP: - r = bwb_STOP( l ); - break; - case C_STORE: - r = bwb_STORE( l ); - break; - case C_SUB: - r = bwb_SUB( l ); - break; - case C_SUB_END: - r = bwb_SUB_END( l ); - break; - case C_SUB_EXIT: - r = bwb_SUB_EXIT( l ); - break; - case C_SUBEND: - r = bwb_SUBEND( l ); - break; - case C_SUBEXIT: - r = bwb_SUBEXIT( l ); - break; - case C_SWAP: - r = bwb_SWAP( l ); - break; - case C_SYSTEM: - r = bwb_SYSTEM( l ); - break; - case C_TEXT: - r = bwb_TEXT( l ); - break; - case C_THEN: - r = bwb_THEN( l ); - break; - case C_TIMER: - r = bwb_TIMER( l ); - break; - case C_TIMER_OFF: - r = bwb_TIMER_OFF( l ); - break; - case C_TIMER_ON: - r = bwb_TIMER_ON( l ); - break; - case C_TIMER_STOP: - r = bwb_TIMER_STOP( l ); - break; - case C_TLOAD: - r = bwb_TLOAD( l ); - break; - case C_TO: - r = bwb_TO( l ); - break; - case C_TRACE: - r = bwb_TRACE( l ); - break; - case C_TRACE_OFF: - r = bwb_TRACE_OFF( l ); - break; - case C_TRACE_ON: - r = bwb_TRACE_ON( l ); - break; - case C_TSAVE: - r = bwb_TSAVE( l ); - break; - case C_TTY: - r = bwb_TTY( l ); - break; - case C_TTY_IN: - r = bwb_TTY_IN( l ); - break; - case C_TTY_OUT: - r = bwb_TTY_OUT( l ); - break; - case C_UNTIL: - r = bwb_UNTIL( l ); - break; - case C_USE: - r = bwb_USE( l ); - break; - case C_VARS: - r = bwb_VARS( l ); - break; - case C_WEND: - r = bwb_WEND( l ); - break; - case C_WHILE: - r = bwb_WHILE( l ); - break; - case C_WRITE: - r = bwb_WRITE( l ); - break; - default: - WARN_INTERNAL_ERROR; - r = l; - break; - } - return r; -} - -/* EOF */ diff --git a/Junk/bwbasic.doc b/Junk/bwbasic.doc deleted file mode 100644 index 2c37ba9..0000000 --- a/Junk/bwbasic.doc +++ /dev/null @@ -1,1156 +0,0 @@ - - Bywater BASIC Interpreter, version 3.20 - --------------------------------------------- - - Copyright (c) 1993, Ted A. Campbell - for bwBASIC version 2.10, 11 October 1993 - - Copyright (c) 2014-2015, Howatd Wulf, AF5NE - for bwBASIC version 3.00, 12 May 2015 - - Copyright (c) 2015-2016, Howatd Wulf, AF5NE - for bwBASIC version 3.10, 27 July 2016 - - Copyright (c) 2016-2017, Howatd Wulf, AF5NE - for bwBASIC version 3.20, 4 June 2017 - -CONTENTS: - - - 1. DESCRIPTION - 2. TERMS OF USE - 3. QUICK REFERENCE LIST OF COMMANDS, FUNCTIONS AND OPERATORS - 4. GENERAL NOTES ON USAGE - 5. PREDEFINED VARIABLES - 6. UNIMPLEMENTED COMMANDS AND FUNCTIONS - and AGENDA FOR DEVELOPMENT - 7. THE STORY OF Bywater BASIC - 8. COMMUNICATIONS - 9. EXPANDED REFERENCE FOR COMMANDS, FUNCTIONS AND OPERATORS - - The author wishes to express his thanks to Mr. David MacKenzie, - who assisted in the development Unix installation and configuration - for this version. - -1. 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), and many - classic BASIC dialects in C. - - bwBASIC can be configured to enable commands, functions, operators - and punctuation characters available in many classic dialects of BASIC; - these are controlled by various OPTION commands. bwBASIC does not attempt - bug-level compatibility with any particular BASIC dialect nor does it - currently support graphics. bwBASIC seeks to be as portable as possible. - - The interpreter is fairly slow. Whenever faced with a choice - between conceptual clarity and speed, I have consistently chosen the - former. The interpreter is the simplest design available, and - utilizes no system of intermediate code, which could speed up - considerably its operation. As it is, each line has only one - command. Multi-statement lines are internally broken into distinct - lines as they are loaded. - - -2. TERMS OF USE: - - - 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. - - -3. QUICK REFERENCE LIST OF COMMANDS, FUNCTIONS AND OPERATORS - - - The complete list of over 500 commands, functions and operators is - in the file "ALL.txt" in the DOCS directory. Documentation for each - BASIC dialect is in the other text files in the DOCS directory. - - A BASIC dialect is a selection of commands, functions, operators, - punctuation characters and other behaviors. The OPTION VERSION - command is used to choose a specific BASIC dialect. Additional - OPTION commands are available to fine-tune the behavior. - - In bwBASIC, any function can be executed as a command. For example, - the function "OUT(X, Y)" can be executed as the command "OUT X, Y". - You can overload functions by parameter signature (the number - and types of parameters), and user defined functions can replace - any instrinsic function, including INP, OUT, PEEK, POKE, and WAIT. - - -4. GENERAL NOTES ON USAGE: - - - 4.a. Interactive Environment - - - An interactive environment is provided if the flag INTERACTIVE - is defined as TRUE in bwBASIC.h, so that a line with a - line number can be entered at the bwBASIC prompt and it will be - added to the program in memory. - - Line numbers are not strictly required, but are useful if the - interactive enviroment is used for programming. For longer - program entry one might prefer to use an ASCII text editor, and - in this case lines can be entered without numbers. See also the - documentation below for the pseudo-command EDIT, in section 5. - - - 4.b. Naming Conventions - - - Command, function, label, and variable names are not case sensitive, - so that "Run" and "RUN" and "run" are equivalent. - - The characters allowed in variable names depends upon the specific - BASIC dialect selected with the OPTION VERSION command. Usually, - variable names can use any alphabetic characters, the period - and underscore characters and decimal digits (but not in the - first position) and they can be terminated with the various numeric - type characters (!,@,#,%,&,~) or the string type character ($). - - - 4.c. Numerical Constants - - - Numerical constants may begin with a digit 0-9 (decimal), with - the "&H" or "&h" (hexadecimal) or the "&o" or "&O" (octal). - Numerical constants may include 'E' or 'e' followed by an - exponent number to denote exponential notation. Numerical - constants may also be terminated by the various numeric type - characters (!,@,#,%,&,~). - - - 4.d. Command-Line Execution - - - A filename can be specified on the command line and will be - loaded and executed immediately, so that the command line - - bwBASIC prog.bas - - will load and execute "prog.bas". If a program is executed - from the command line, control is returned to the operating - system when the program terminates. - - - 4.e. Program Storage - - - All programs are stored as ASCII text files. - - - 4.f. TRUE and FALSE - - - TRUE is defined as -1 and FALSE is defined as 0 in the default - distribution of bwBASIC. Alhtough these definitions can be changed - by those compiling bwBASIC (see file bwBASIC.h), any other values - are not supported. - - - 4.g. Assignments - - - Assignment must be made to variables. This differs from some - implementations of BASIC where assignment can be made to a - function. Implication: "INSTR( 3, x$, y$ ) = z$" will not - work under bwBASIC. The command "MID$(X$,...) = ..." is - implemented and should be used instead. - - Some BASIC dialects allow the multiple variable assignments, - such as: - 100 LET A = B = C = 0 - In bwBASIC, only the first '=' is considered an assignment. - All other '=' are considered comparison operators. To resolve - this issue, use commas to seperate the variables, such as: - 100 LET A, B, C = 0 - If these statements are only used to initialize the variable - values, then they may not needed in bwBASIC, since all numeric - variables are initialized to zero (0) and all string variables - are initialized to the empty string (""). - - - 4.h. Operators and Precedence - - - The available operators are determined by the OPTION VERSION - setting. bwBASIC recognizes many operators, with their level of - precedence fixed. The precedence levels chosen for the various - operators in bwBASIC were selected to be compatible with many - dialects of BASIC. If your application requires a specific order - of evaluation, then use parentheses. - - The collating sequence (ASCII, EBCDIC, and so on) is determined - by the C compiler. As a consequenece, the results of string - comparisons may vary. A simple check for collating sequence is - shown in the following example: - - 100 REM Purpose: Verify collating sequence (sort order) - 110 REM Author: Howard Wulf, AF5NE - 120 REM Date: 2015-11-28 - 130 REM - 200 IF "1" < "A" THEN 300 - 210 PRINT "EBCDIC" - 220 GOTO 999 - 300 PRINT "ASCII" - 999 END - - - 4.i. Numerical Precision (NOT) - - - bwBASIC utilizes numbers with only one level of precision. - All numbers are internally represented using a C double. - - The various numeric type suffix characters (!,@,#,%,&,~), - just like the string type suffix character ($), are part - of the variable name. - - This version also supports type declarations, such as: - 100 DIM X AS INTEGER - 110 FUNCTION ABC( X AS INTEGER ) AS INTEGER - 120 LET ABC = X * 2 - 130 END FUNCTION - - For each type character there is an equivalent type declaration. - Type Equivalent - Char declaration - ==== =========== - $ STRING - # DOUBLE - ! SINGLE - @ CURRENCY - & LONG - % INTEGER - ~ BYTE - - However, combining both a type suffix character and a type - declaration in the same statement is not supported. - 100 DIM A$ AS INTEGER ' this is not supported - - The type of a variable is used to range-check the values. - This allows many programs to run correctly, but does not - handle all possible cases. The current implementation is not - complete for all possible uses of numeric type declarations. - - In the current version, the type of numeric values is used - to select the appropriate operation. As a consequence, - integer division is used when dividing two integer values. - The MOD and \ operators use the rounded integer values of - their parameters and return a rounded integer result. - - Within an expression, the result of an operation is promoted - to the greater of: - the type of the left parameter, - the type of the right parameter, and - the type required to hold the result. - - In bwBASIC, numeric constants are DOUBLE by default. If you - wish to coerce a numeric constant, then add the appropriate - numeric type character immediately after the numeric digits. - Many BASIC dialects that allow numeric constants to have a - numeric type character adopt this convention. - - - 4.j. OPTION VERSION and so on - - - OPTION commands change how a BASIC program is parsed. All OPTION commands - should be in "profile.bas" so they are effective when a BASIC program - is loaded. The first OPTION command should be OPTION VERSION to select a - specific BASIC dialect. Additional OPTION commands fine-tune the available - commands, functions, operators, punctuation characters and so on to support - programs written in many different BASIC dialects. All other OPTION commands - must follow the OPTION VERSION command. Conflicting and pathological OPTION - combinations are not supported. - - The OPTION VERSION command selects a specific BASIC dialect. - OPTION VERSION "BYWATER" ' Bywater BASIC 3 - OPTION VERSION "BYWATER-2" ' Bywater BASIC 2 - OPTION VERSION "CALL/360" ' SBC CALL/360 Mainframe BASIC - OPTION VERSION "CBASIC-II" ' CBASIC-II for CP/M - OPTION VERSION "DARTMOUTH" ' Dartmouth DTSS BASIC - OPTION VERSION "ECMA-55" ' ANSI Minimal BASIC - OPTION VERSION "ECMA-116" ' ANSI Full BASIC - OPTION VERSION "GCOS" ' GE 600 Mainframe BASIC - OPTION VERSION "HAARDT" ' bas 2.4 by Michael Haardt - OPTION VERSION "HANDBOOK1" ' The BASIC Handbook, 1st Edition - OPTION VERSION "HANDBOOK2" ' The BASIC Handbook, 2nd Edition - OPTION VERSION "HEATH" ' Heath Benton Harbor BASIC - OPTION VERSION "MARK-I" ' GE 265 Mainframe BASIC - OPTION VERSION "MARK-II" ' GE 435 Mainframe BASIC - OPTION VERSION "MBASIC" ' Microsoft BASIC-80 for Xenix - OPTION VERSION "PDP-8" ' DEC PDP-8 BASIC - OPTION VERSION "PDP-11" ' DEC PDP-11 BASIC - OPTION VERSION "RBASIC" ' Micronics RBASIC for 6809 FLEX - OPTION VERSION "RSTS-11" ' DEC RSTS-11 BASIC-PLUS - OPTION VERSION "SYSTEM/360" ' IBM System/360 Mainframe BASIC - OPTION VERSION "SYSTEM/370" ' IBM System/370 Mainframe BASIC - OPTION VERSION "TRS-80" ' TRS-80 Model I/III/4 LBASIC - OPTION VERSION "VINTAGE" ' Vintage BASIC 1.0.1 - OPTION VERSION "XBASIC" ' TSC XBASIC for 6800 FLEX - - For example, MOD is a function in OPTION VERSION "ECMA-116", - MOD is an operator in OPTION VERSION "MBASIC", and - MOD is a valid variable name in OPTION VERSION "CALL/360". - - The OPTION VERSION command also sets the following OPTION commands: - OPTION STRICT ON | OFF - OPTION ANGLE DEGREES | RADIANS | GRADIANS - OPTION BUGS ON | OFF - OPTION LABELS ON | OFF - OPTION COMPARE BINARY | DATABASE | TEXT - OPTION BASE integer - OPTION RECLEN integer - OPTION COVERAGE ON | OFF - OPTION TRACE ON | OFF - OPTION ERROR GOTO | GOSUB - OPTION DATE "format" - OPTION TIME "format" - OPTION PUNCT COMMENT "char" - OPTION PUNCT STATEMENT "char" - OPTION PUNCT PRINT "char" - OPTION PUNCT IMAGE "char" - OPTION PUNCT INPUT "char" - OPTION USING DIGIT "char" - OPTION USING COMMA "char" - OPTION USING PERIOD "char" - OPTION USING PLUS "char" - OPTION USING MINUS "char" - OPTION USING EXRAD "char" - OPTION USING DOLLAR "char" - OPTION USING FILLER "char" - OPTION USING LITERAL "char" - OPTION USING FIRST "char" - OPTION USING ALL "char" - OPTION USING LENGTH "char" - OPTION PUNCT QUOTE "char" - OPTION PUNCT STRING "char" - OPTION PUNCT DOUBLE "char" - OPTION PUNCT SINGLE "char" - OPTION PUNCT CURRENCY "char" - OPTION PUNCT LONG "char" - OPTION PUNCT INTEGER "char" - OPTION PUNCT BYTE "char" - OPTION PUNCT LPAREN "char" - OPTION PUNCT RPAREN "char" - OPTION PUNCT FILENUM "char" - OPTION PUNCT AT "char" - - The commands, functions, operators and settings for each BASIC dialect - is documented in the text files in the DOCS directory. - - OPTION DISABLE COMMAND - Disable a specific command. - - OPTION DISABLE FUNCTION - Disable a specific function. - - OPTION DISABLE OPERATOR - Disable a specific operator. - - OPTION ENABLE COMMAND - Enable a specific command. - - OPTION ENABLE FUNCTION - Enable a specific function. - - OPTION ENABLE OPERATOR - Enable a specific operator. - - OPTION ERROR GOSUB - The program will GOSUB to the error handler. - The error handler exits with the RETURN command. - - OPTION ERROR GOTO - The program will GOTO to the error handler. - The error handler exits with the RESUME command. - - OPTION LABELS OFF - Disables textual labels. - - OPTION LABELS ON - Enables textual labels. - - Regardless of the OPTION LABELS setting, statements of the form - IF x THEN label - are not allowed, instead use the form - IF x THEN GOTO label - The reason for this rule is because - IF x THEN y - is considered to be the same as - IF x THEN - y - END IF - where "y" is a command, function, or subroutine. Many BASIC dialects - that allow textual labels adopt this convention. - - OPTION ROUND controls how floating point values are converted to - whole number values. OPTION ROUNG MATH rounds toward the nearest - whole number, with halves rounding up to the next larger whole number, - as commonly expected by many scientific applications. OPTION ROUND - BANK rounds halves to the even whole numbers, as commonly expected - by many financial applications. OPTION ROUND TRUNCATE truncates to - the next smaller whole number, as commonly expected by many - applications written for an integer BASIC. The selected rounding - method is used whenever a whole number is required, including: - a) selection value for ON ... GOTO and ON ... GOSUB - b) any function parameter requiring a whole number - c) array subscripts and dimensions - d) string positions and lengths - e) CINT() and similar - The OPTION ROUND command does not change the results of INT() or FIX(). - The default rounding method is OPTION ROUND BANK. - - A comparison of the different OPTION ROUND settings upon the results of CINT() - - BANK MATH TRUNCATE - X int(X) fix(X) cint(X) cint(X) cint(X) - -2.0 -2 -2 -2 -2 -2 - -1.6 -2 -1 -2 -2 -1 - -1.5 -2 -1 -2 -2 -1 - -1.4 -2 -1 -1 -1 -1 - -1.0 -1 -1 -1 -1 -1 - -0.6 -1 0 -1 -1 0 - -0.5 -1 0 0 -1 0 - -0.4 -1 0 0 0 0 - 0.0 0 0 0 0 0 - 0.4 0 0 0 0 0 - 0.5 0 0 0 1 0 - 0.6 0 0 1 1 0 - 1.0 1 1 1 1 1 - 1.4 1 1 1 1 1 - 1.5 1 1 2 2 1 - 1.6 1 1 2 2 1 - 2.0 2 2 2 2 2 - - The OPTION BUGS command determines the behavior of a number of BASIC keywords. - BASIC programs which rely on these behaviors are non-portable and non-standard. - I have considered several different names for this command, but have not yet - thought of a better short name. - - OPTION BUGS ON disables the ANSI/ECMA/ISO standard behavior: - - FOR ... ' values are evaluated left-to-right - GOTO X OF ... ' an invalid value for X falls thru without ERROR - GOSUB X OF ... ' an invalid value for X falls thru without ERROR - ON X GOTO ... ' an invalid value for X falls thru without ERROR - ON X GOSUB ... ' an invalid value for X falls thru without ERROR - X = VAL("X") ' returns zero without ERROR - INPUT X ' empty string returns zero without ERROR - INPUT X$ ' empty string returns "" without ERROR - INPUT X$ ' allows unquoted character strings - variable names ' period and underscore are allowed - variable types ' the type characters #!@&% are allowed - PRINT "a" X ' string concatenation is implied - 1.2% is 1 ' the type characters #!@&% are allowed - 1D1 is ERROR ' 'D' is not allowed as exponent seperator - - OPTION BUGS OFF enables the ANSI/ECMA/ISO standard behavior: - - FOR ... ' values are evaluated according to standard - GOTO X OF ... ' an invalid value for X is an ERROR - GOSUB X OF ... ' an invalid value for X is an ERROR - ON X GOTO ... ' an invalid value for X is an ERROR - ON X GOSUB ... ' an invalid value for X is an ERROR - X = VAL("X") ' raises an illegal function call (ERROR 5) - INPUT X ' empty string retries input - INPUT X$ ' empty string retries input - INPUT X$ ' unquoted character strings retries input - variable names ' period and underscore are not allowed - variable types ' the type characters #!@&% are not allowed - PRINT "a";X ' string concatenation is not implied - 1.2% is ERROR ' the type characters #!@&% are not allowed - 1D1 is ERROR ' 'D' is not allowed as exponent seperator - - - 4.k. ERROR handling - - - bwBASIC implements a simplified error handling strategy. - Errors are seperated into two categories: - - a) Fatal errors. These errors include: - - Unknown command - - FOR without NEXT - - NEXT without FOR - - WHILE without WEND - - WEND without WHILE - - and so on. - The program is scanned prior to running and if any of these errors is - detected, then the program is not allowed to run. If these errors - occur as the result of a DELETE or MERGE in a running program, then the - program is terminated. - - b) Non-fatal errors. If an error handler exists, then it is executed, - otherwise the default behaivor is performed. The correct action to - take in an error handler depends upon the specific application. - - Overflow (ERROR 6) - - the default behavior is to display a warning message. - - Division by zero (ERROR 11) - - the default behavior is to display a warning message. - - String too long (ERROR 15) - - the default behavior is to display a warning message. - - All other non-fatal errors - - the default behavior is to terminate the program. - - bwBASIC 2.61 used ON ERROR GOSUB for error trapping. - This version defaults to ON ERROR GOTO instead. - - - 4.l. Implementation rules for functions and commands - - - In many BASIC dialects, keywords are seperated into three distinct groups: - Commands, Statements, and Functions. In bwBASIC, keywords are seperated - into only two groups: Commands and Functions. A keyword documented as a - Command or Statament in a specific BASIC dialect may have been implemented - in bwBASIC as a Function. This is merely an implementation decision, which - may change in the future. Each keyword should only be used as described in - the reference document. The following rules are considered when deciding - whether a BASIC keyword is implemented as a command or a function: - - a) If the keyword requires significant parsing, - then it is implemented as a command. An example is "PRINT". - - b) If the keyword requires access to variables BYREF, - then it is implemented as a command. An example is "SWAP". - - c) If the keyword changes the flow of control, - then it is implemented as a command. An example is "GOTO". - - d) A function may be used as though it were a command, - but a command cannot be used as though it were a function. - - e) The BASIC program can redefine a function, - but the BASIC program cannot redefine a command. - - f) The BASIC program can overload a function, - but the BASIC program cannot overload a command. - - g) Other than semantics, there is no practical difference - between a BASIC function and a BASIC subroutine. The - return value of a BASIC subroutine, when called as a - function, is zero. Calling a BASIC function as if it - were a subroutine simply discards the return value. - - These rules were chosen to maintain compatibility with - many BASIC dialects. - - An example of the results of the above rules is "OUT". - Since "OUT" is implemented as a function, you may: - a) call it as a subroutine like this: - 100 OUT X, Y - b) call it as a function like this: - 100 LET N = OUT( X, Y ) ' N = 0 - c) redefine it as a subroutine like this: - SUB OUT( X, Y ) - REM ... - END SUB - d) redefine it as a function like this: - FUNCTION OUT( X, Y ) - REM ... - END FUNCTION - e) overload it using subroutines like these: - SUB OUT( X, Y ) - REM ... - END SUB - SUB OUT( X, A$ ) - REM ... - END SUB - SUB OUT( A$, X ) - REM ... - END SUB - SUB OUT( A$, B$ ) - REM ... - END SUB - f) overload it using functions like these: - FUNCTION OUT( X, Y ) - REM ... - END FUNCTION - FUNCTION OUT( X, A$ ) - REM ... - END FUNCTION - FUNCTION OUT( A$, X ) - REM ... - END FUNCTION - FUNCTION OUT( A$, B$ ) - REM ... - END FUNCTION - - - 4.m. Reference documentation - - - bwBASIC is preconfigured to support a number of specific BASIC dialects which were - implemented using the following references, however bwBASIC does not attempt to be - bug-level compatible and does not implement non-portable design choices. A manual - for each dialect is in the DOCS directory to make you aware that a specific keyword - is implemented, however you should refer to the reference document for a proper - understanding of how to use each keyword. There are many other good books which - describe these BASIC dialects in detail. - - OPTION VERSION "BYWATER" ' Bywater BASIC 3 - MANUAL: - BYWATER.TXT - - OPTION VERSION "BYWATER-2" ' Bywater BASIC 2 - MANUAL: - BYWATER-2.TXT - NOT IMPLEMENTED: - DO NUM, DO UNNUM - NOTES: - SUB MAIN is not automatically called. - CALL requires parentheses around the function/subroutine parameters, - so instead of - CALL abc 1, 2, 3 - use - CALL abc( 1, 2, 3 ) - - OPTION VERSION "CALL/360" ' SBC CALL/360 Mainframe BASIC - MANUAL: - CALL-360.TXT - NOT IMPLEMENTED: - MAT PRINT USING. - NOTES: - The APPENDIXES are implementation specific and are not supported. - - OPTION VERSION "CBASIC-II" ' CBASIC-II for CP/M - MANUAL: - CBASIC-II.TXT - ADDITIONAL INFORMATION: - "CBASIC Language Reference Manual, 2nd Edition" - by Diigital Research - (c) 1982, Diigital Research - http://bitsavers.trailing-edge.com/pdf/digitalResearch/cb80/ - CBASIC_Language_Reference_Manual_Oct82.pdf - NOT IMPLEMENTED: - CONSTAT%, CONCHAR% and compiler directives. - NOTES: - The APPENDIXES are implementation specific and are not supported. - The %INCLUDE directive is implemented, but only supports literal - unquoted filesnames without drive or directory, such as: - %INCLUDE LIBRARY.BAS - Note that the %INCLUDE directive is executed as a file is being loaded, - and as a result the %INCLUDE does not appear in the resulting listing. - Machine language functions and commands are not supported. - The parsing of command line parameters is implementation defined. - The specification of an array in a COMMON statement is the same as - the specification in a DIM statement. - The SIZE() function assumes 1024 bytes and does not support wild-cards; - if the file does not exist then SIZE() returns zero, otherwise SIZE() - returns the number of 1024 bytes blocks required to contain the file; - an existing file of zero bytes returns a value of 1. - - OPTION VERSION "DARTMOUTH" ' Dartmouth DTSS BASIC - MANUAL: - DARTMOUTH.TXT - NOTES: - The APPENDICES are implementation specific and are not supported. - Sections 4.2 and 4.3 are implementation specific and are not supported. - Lines containing data to be READ must have a line number and a DATA command. - NOT IMPLEMENTED: - Card punch codes are not supported, use a comma or semicolon instead. - - OPTION VERSION "ECMA-55" ' ANSI Minimal BASIC - MANUAL: - ECMA-55.TXT - NOTES: - The APPENDICES are implementation specific and are not supported. - DIM is an executed statement in bwBASIC. - This is a design decision to support the following example. - 100 INPUT "How many?"; N - 110 DIM A$(N) - - OPTION VERSION "ECMA-116" ' ANSI Full BASIC - MANUAL: - ECMA-116.TXT - NOT IMPLEMENTED: - Graphic commands, chapters 11 thru 15. - NOTES: - The APPENDICES are implementation specific and are not supported. - WORK-IN-PROGRESS. - - OPTION VERSION "GCOS" ' GE 600 Mainframe BASIC - MANUAL: - GCOS.TXT - NOT IMPLEMENTED: - HPS, LIN, RESTORE*, RESTORE$, VPS and binary files. - NOTES: - The APPENDIXES are implementation specific and are not supported. - Local variables in a multiline DEF are declared using DIM. - Line numbers are not written to, nor read from, data files. - FILES does not support passwords. - Literal values for file names are not supported, use string values instead. - This is a design decision to support the following: - 100 INPUT "Which files?"; A$, B$, C$ - 110 FILES A$, B$, C$ - - OPTION VERSION "HAARDT" ' bas 2.4 by Michael Haardt - MANUAL: - HAARDT.TXT - NOT IMPLEMENTED: - BBC syntax, use ANSI syntax instead. - ON ERROR statement(s) is not supported, use ON ERROR GOTO instead. - ON ERROR OFF, use ON ERROR GOTO 0 instead. - MAT REDIM, OPTION RUN, OPTION STOP, TRUNCATE, UNNUM and XREF. - DEC$(X,A$), ENVIRON$(X), FIND$(A$[,X]) and INSTR(A$,B$,X,Y). - NOTES: - POS and TAB are 1-based instead of 0-based. - ON ERROR GOTO 0 does not cause any error to occur, instead - ON ERROR GOTO 0 removes the current error handler and clears - ERL, ERR and ERROR$. - - OPTION VERSION "HANDBOOK1" ' The BASIC Handbook, 1st Edition - MANUAL: - HANDBOOK1.TXT - NOT IMPLEMENTED: - Abbreviated commands (such as A.) and graphic commands. - NOTES: - The APPENDICES are implementation specific and are not supported. - The ERR function returns different values. - - OPTION VERSION "HANDBOOK2" ' The BASIC Handbook, 2nd Edition - MANUAL: - HANDBOOK2.TXT - NOT IMPLEMENTED: - Abbreviated commands (such as A.) and graphic commands. - NOTES: - The APPENDICES are implementation specific and are not supported. - The ERR function returns different values. - - OPTION VERSION "HEATH" ' Heath Benton Harbor BASIC - NOT IMPLEMENTED: - FREEZE, UNFREEZE, LOCK, UNLOCK, STEP - NOTES: - The APPENDICES are implementation specific and are not supported. - PRINT #-1 is sent to the printer. - INPUT #-1 is an ERROR. - - OPTION VERSION "MARK-I" ' GE 265 Mainframe BASIC - MANUAL: - MARK-I.TXT - ADDITIONAL REFERENCE: - "Time-Sharing Service BASIC LANGUAGE EXTENSIONS Reference Manual" - by Time-Sharing Service, Information Service Department, General Electric - (c) 1968, General Electric Company and Trustees of Dartmouth College - http://www.bitsavers.org/pdf/ge/MarkI_Timesharing/ - 802207A_Time-SharingServiceBASICLanguageExtensionsReferenceManual_Feb1968.pdf - NOTES: - The APPENDIXES are implementation specific and are not supported. - NOT IMPLEMENTED: - A series of variables seperated by equal signs is not supported, - use a series of variables seperated by commas instead. - Literal values for file names are not supported, use string values instead. - This is a design decision to support the following: - 100 INPUT "Which files?"; A$, B$, C$ - 110 FILES A$, B$, C$ - CALL, to execute another compiled program, is not supported, use SHELL instead. - - OPTION VERSION "MARK-II" ' GE 435 Mainframe BASIC - MANUAL: - MARK-II.TXT - ADDITIONAL INFORMATION: - "Basic Software Library" (Volumes 1 to 8) - by R. W. Brown - (c) 1977, Scientific Research Inst. - NOT IMPLEMENTED: - HPS, LIN, RESTORE*, RESTORE$, VPS and binary files. - NOTES: - The APPENDIXES are implementation specific and are not supported. - Local variables in a multiline DEF are declared using DIM. - Line numbers are not written to, nor read from, data files. - Literal values for file names are not supported, use string values instead. - This is a design decision to support the following: - 100 INPUT "Which files?"; A$, B$, C$ - 110 FILES A$, B$, C$ - FILES does not support passwords. - - OPTION VERSION "MBASIC" ' Microsoft BASIC-80 for Xenix - MANUAL: - MBASIC.TXT - NOTES: - The APPENDICES are implementation specific and are not supported. - The ERR function returns different values. - Specifying "D" in the exponent is not supported, instead use "E". - - OPTION VERSION "PDP-8" ' DEC PDP-8 BASIC - MANUAL: - PDP-8.TXT - NOT IMPLEMENTED: - NO RUBOUTS, RUBOUTS - NOTES: - The APPENDICES are implementation specific and are not supported. - - OPTION VERSION "PDP-11" ' DEC PDP-11 BASIC - MANUAL: - PDP-11.TXT - NOTES: - The APPENDICES are implementation specific and are not supported. - - OPTION VERSION "RBASIC" ' Micronics RBASIC for 6809 FLEX - MANUAL: - RBASIC.TXT - NOT IMPLEMENTED: - "+" command, COMPILE, CVT$, CVTF$, CVT$%, CVT$F - NOTES: - The APPENDICES are implementation specific and are not supported. - The ERR function returns different values. - - OPTION VERSION "RSTS-11" ' DEC RSTS-11 BASIC-PLUS - MANUAL: - RSTS-11.TXT - ADDITIONAL INFORMATION: - "BASIC-PLUS Language Manual : for use with RSTS-11 (PDP-11 Resource Time-Sharing System)" - by Digital Equipment Corporation - (c) 1972, Digital Equipment Corporation - http://bitsavers.trailing-edge.com/pdf/dec/pdp11/rsts/V04/ - DEC-11-ORBPA-A-D_BASIC-PLUS_LangMan_Oct72.pdf - ADDITIONAL INFORMATION: - "PDP-11 : BASIC-PLUS Language Manual" - by Digital Equipment Corporation - (c) 1975, Digital Equipment Corporation - http://bitsavers.trailing-edge.com/pdf/dec/pdp11/rsts/V06/ - DEC-11-ORBPB-A-D_BASIC-PLUS_LangMan_Jul75.pdf - NOT IMPLEMENTED: - HELLO, RENAME, REPLACE, COMPILE, LENGTH, TAPE, KEY, ASSIGN, DEASSIGN. - FOR ... WHILE, FOR ... UNTIL, statement modifiers. - NOTES: - The APPENDIXES are implementation specific and are not supported. - The ERR function returns different values. - The statemnet NAME ... AS does not support the specifier. - - OPTION VERSION "SYSTEM/360" ' IBM System/360 Mainframe BASIC - MANUAL: - SYSTEM-360.TXT - ADDITIONAL INFORMATION: - "IBM System/360 0S(TS0) ITF:BASIC Terminal User's Guide" - by International Business Machines Corporation - (c) 1971, International Business Machines Corporation - http://bitsavers.org/pdf/ibm/360/os/tso/ - SC28-6840-0_TSO_ITF_BASIC_Terminal_UG_Apr71.pdf - NOT IMPLEMENTED: - MAT PRINT USING. - NOTES: - The APPENDIXES are implementation specific and are not supported. - - OPTION VERSION "SYSTEM/370" ' IBM System/370 Mainframe BASIC - MANUAL: - SYSTEM-370.TXT - NOT IMPLEMENTED: - MAT PRINT USING. - NOTES: - The APPENDIXES are implementation specific and are not supported. - - OPTION VERSION "TRS-80" ' TRS-80 Model I/III/4 LBASIC - MANUAL: - TRS-80.TXT - NOT IMPLEMENTED: - CMD, SET EOF, cassette I/O. - NOTES: - The APPENDICES are implementation specific and are not supported. - The ERR function returns different values. - For the TRS-80 Model I use "WIDTH 16,64" in "profile.bas". - For the TRS-80 Model III use "WIDTH 16,64" in "profile.bas". - For the TRS-80 Model 4 use "WIDTH 24,80" in "profile.bas". - bwBASIC requires a space around all keywords, so the LINEINPUT - command must be written as LINE INPUT, and so on. - PRINT #-1 is sent to the printer. - INPUT #-1 is an ERROR. - - OPTION VERSION "VINTAGE" ' Vintage BASIC 1.0.1 - MANUAL: - VINTAGE.TXT - NOTES: - The APPENDICES are implementation specific and are not supported. - - OPTION VERSION "XBASIC" ' TSC XBASIC for 6800 FLEX - MANUAL: - XBASIC.TXT - NOT IMPLEMENTED: - "+" command, COMPILE, CVT$, CVTF$, CVT$%, CVT$F - NOTES: - The APPENDICES are implementation specific and are not supported. - The ERR function returns different values. - - -5. PREDEFINED VARIABLES - no longer exist - - - BWB.EDITOR$ - BWB.FILES$ - BWB.PROMPT$ - BWB.IMPLEMENTATION$ - - These preset variables no longer exist in bwBASIC. They have - been replaced with OPTION EDIT, OPTION FILES and OPTION PROMPT - commands. - - The commands EDIT and FILES are pseudo-commands that launch - shell programs set by OPTION EDIT and OPTION FILES commands, - respectively. The default values for these commands can - be changed in bwBASIC.h (DEF_EDITOR and DEF_FILES), and they - can be changed on the fly by the user. It is expected that - the user will add the appropriate commands to "profile.bas" - for their specific implementation; OPTION FILES "ls -l" on Unix - systems and OPTION FILES "dir" on DOS systems. - - The command OPTION PROMPT can be used to set the prompt - string for bwBASIC. Again, it is suggested that a user- - selected prompt can be set up in a "profile.bas" to be - initialized each time bwBASIC starts. Note that special - characters can be added to the prompt string, e.g., - - OPTION PROMPT "Ok"+CHR$(10) - - will give an "Ok" prompt followed by a linefeed. - - In previous versions, the preset variable BWB.IMPLEMENTATION$ - would return "TTY" (IMP_IDSTRING) for the bwx_tty implementation. - In previous versions of bwBASIC, the existance of the keywords CLS, - COLOR and LOCATE were determined at compile and BWB.IMPLEMENTATION$ - was used at runtime to determine whether these keywords existed. - In the current version, these keywords always exist and are now - controlled at runtime using the OPTION TERMINAL commands. With - OPTION TERMINAL NONE these keywords output nothing. - - -6. UNIMPLEMENTED COMMANDS AND FUNCTIONS, and AGENDA FOR DEVELOPMENT - - - There are some items not implemented that have been so long - a part of some BASIC dialects that their absence may seem surprising. - In each case, though, their implementation would require - operating-system-specific functions or terminal-specific functions - that cannot be universally provided. Some specific examples are - detailed below. - - - INP reads a value from a hardware port. In the current version, - using INP() will generate ERROR 73. It is expected that you will - provide a suitable implementation for your specific application. - For example: - FUNCTION INP( X ) - REM Return whatever value your application requires - INP = 0 - END FUNCTION - - - OUT writes a value to a hardware port. In the current version, - using OUT() will generate ERROR 73. It is expected that you will - provide a suitable implementation for your specific application. - For example: - SUB OUT( X, Y ) - REM do whatever your application requires - END SUB - - - PEEK reads a value from a memory location. In the current version, - using PEEK() will generate ERROR 73. It is expected that you will - provide a suitable implementation for your specific application. - For example: - FUNCTION PEEK( X ) - REM Return whatever value your application requires - PEEK = 0 - END FUNCTION - - - POKE writes a value to a memory location. In the current version, - using POKE() will generate ERROR 73. It is expected that you will - provide a suitable implementation for your specific application. - For example: - SUB POKE( X, Y ) - REM do whatever your application requires - END SUB - - - WAIT reads a value from a hardware port. In the current version, - using WAIT() will generate ERROR 73. It is expected that you will - provide a suitable implementation for your specific application. - For example: - SUB WAIT( X, Y ) - REM do whatever your application requires - END SUB - SUB WAIT( X, Y, Z ) - REM do whatever your application requires - END SUB - - - USR executes a machine code routine. In the current version, - using USR() will generate ERROR 73. It is expected that you will - provide a suitable implementation for your specific application. - For example: - FUNCTION USR( ... ) - REM Return whatever value your application requires - USR = 0 - END FUNCTION - - - VARPTR reads a value from a memory location. In the current version, - using VARPTR() will generate ERROR 73. It is expected that you will - provide a suitable implementation for your specific application. - For example: - FUNCTION VARPTR( ... ) - REM Return whatever value your application requires - VARPTR = 0 - END FUNCTION - - - There are other commands, functions, and implementation details - that I am working on, and which are on the agenda list for future - versions of bwBASIC. These agenda include: - - - PARACT i.e., the ability to execute PARallel ACTions. This - is described in ANSI BASIC, although I have not seen it - implemented before. It will offer a rough, non-preemptive - form of multitasking within the scope of a BASIC program. - Programmers will note that the global My pointer provides - one possible hook mechanism for PARACT in bwBASIC. In the - interim, you might use the "ON TIMER" command to implement - a simple multitasking BASIC program. - - - XMEM PC-type computers usually are able to use extended - memory. If we could use extended memory for program - lines, variables, and function defitions, we could - write much longer programs. This would entail, - however, a fairly serious rewriting of the program - to utilize memory handles for these storage features - instead of direct memory pointers. In the interim, - you might use a "DOS Extender" which hooks calloc() - and free() to enable transparent access to EMS or XMS - memory. - - - Windows The addition of memory handles in addition to the - non-preemptive execution of program lines (in a - crude form, already present) will make it possible - to develop implementations for Windows and perhaps - for other graphical user interfaces. But what form - should this take? I have in mind presently a BASIC - that would run in the background, appearing only - as an icon in the GUI space, with pop-up editors - and output windows. Thus, the interpreted language - would serve a purpose something like 'cron' (a task - scheduler) under Unix systems. You may have some - reflections that would help me in this. - - - Graphics Here we face fairly critical differences in different - styles and implementations of graphics, e.g., between - GWBASIC, ANSI BASIC, VisualBASIC, etc. But it's - possible that Graphics commands and functions could - be added. These would all be OPTION VERSION specific. - In the interim, you might consider using ReGIS or Tektronix - graphics (ESC codes) with xterm. - - - The ANSI Standard for full BASIC does not specify which particular - commands or functions must be implemented, and in fact the standard - is very robust. Perhaps no implementation of BASIC would ever - include all of the items, but some ANSI commands and functions which - remain unimplemented are: - - ACCESS - AREA - ARRAY - ASK - BSTR - BVAL - CELLS - CLIP - COLLATE - CONNECT - DATUM - DEBUG - DECLARE - DEVICE - DISCONNECT - DISPLAY - DOT - DRAW - ERASE - EVENT - EXCEPTION - GRAPH - HANDLER - IMAGE - KEY - LINES - MIX - MULTIPOINT - OUTIN - OUTPUT - PARACT - PICTURE - PIXEL - PLOT - POINTS - RECEIVE - RENUMBER - REWRITE - ROTATE - SEIZE - SEND - SHIFT - TIMEOUT - TRACE - TRANSFORM - VIEWPORT - WAIT - VIEWPORT - ZONEWIDTH - - -7. THE STORY OF Bywater BASIC - - - This program was originally begun in 1982 by my grandmother, Mrs. - Verda Spell of Beaumont, TX. She was writing the program using - an ANSI C compiler on an Osborne I CP/M computer and although my - grandfather (Lockwood Spell) had bought an IBM PC with 256k of - RAM my grandmother would not use it, paraphrasing George Herbert - to the effect that "He who cannot in 64k program, cannot in 512k." - She had used Microsoft BASIC and although she had nothing against - it she said repeatedly that she didn't understand why Digital - Research didn't "sue the socks off of Microsoft" for version 1.0 - of MSDOS and so I reckon that she hoped to undercut Microsoft's - entire market and eventually build a new software empire on - the North End of Beaumont. Her programming efforts were cut - tragically short when she was thrown from a Beaumont to Port - Arthur commuter train in the summer of 1986. I found the source - code to bwBASIC on a single-density Osborne diskette in her knitting - bag and eventually managed to have it all copied over to a PC - diskette. I have revised it slightly prior to this release. You - should know, though, that I myself am an historian, not a programmer. - - -8. COMMUNICATIONS: - - - email: tcamp@delphi.com - - -9. EXPANDED REFERENCE FOR COMMANDS, FUNCTIONS AND OPERATORS - - - bwBASIC provides a simple "HELP" command to refresh your memory - regarding the appropriate syntax for a specific command or function. - In the DOCS directory are text files which provide brief descriptions - of every intrinsic command, function and operator available in BASIC - dialect available in bwBASIC; these files are not intented to be an - authoritative or exhaustive reference. Refer to the reference document - for each dialect for details regarding each keyword. - - -THE END diff --git a/Junk/bwbasic.png b/Junk/bwbasic.png deleted file mode 100644 index 9745723..0000000 Binary files a/Junk/bwbasic.png and /dev/null differ diff --git a/Junk/cms.bas b/Junk/cms.bas deleted file mode 100644 index 2dd98f3..0000000 --- a/Junk/cms.bas +++ /dev/null @@ -1,117 +0,0 @@ -rem Purpose: re-define externals to only 6 characters for CMS -rem Author: Howard Wulf, AF5NE -rem Date: 2015-02-10 -rem Usage: implementation defined -rem Example: -rem ~/bwbasic cms.bas -rem -rem ------------------------------------------------------------------------------- -rem File File Name IN/OUT Description -rem #1 "bwbasic.h" INPUT read looking for "extern" statements -rem #2 "cms.h" OUTPUT written with "#define" statements -rem ------------------------------------------------------------------------------- -rem Variable Description -rem N The number of "extern" statements so far processed -rem E$ The constant value "extern " -rem E The length of E$ -rem L$ The input line read from "bwbasic.h" -rem M$ The next line from "bwbasic.h" when L$ does not contain a semicolon -rem X The location of special characters in L$ -rem H$ The hexadecimal value of N -rem T Read count -rem ------------------------------------------------------------------------------- -rem -let N = 0 -let E$ = "extern " -let E = len( E$ ) -open "bwbasic.h" for input as #1 -open "cms.txt" for output as #2 -T = 0 -while not eof( #1 ) - T = T + 1 - line input #1, L$ - L$ = trim$( L$ ) - if left$( L$, E ) = E$ then - rem extern .... - while instr( L$, ";" ) = 0 - ' read more lines until we get a semicolon - line input #1, M$ - M$ = trim$( M$ ) - L$ = L$ + " " + M$ - wend - rem extern ...; - L$ = trim$(mid$( L$, E + 1 )) - ' truncate trailing semicolon - X = instr( L$, ";" ) - if X > 0 then - L$ = trim$(left$( L$, X - 1 )) - end if - ' truncate trailing parenthesis - X = instr( L$, "(" ) - if X > 0 then - L$ = trim$(left$( L$, X - 1 )) - end if - ' truncate trailing bracket - X = instr( L$, "[" ) - if X > 0 then - L$ = trim$(left$( L$, X - 1 )) - end if - ' find the last word - X = instr(L$, " " ) - while X > 0 - L$ = trim$(mid$( L$, X + 1 )) - X = instr(L$, " " ) - wend - ' skip leading asterick - while left$( L$, 1 ) = "*" - L$ = trim$(mid$( L$, 2 )) - wend - if L$ = "main" or L$ = "putenv" or L$="sleep" then - ' ignore magic function name - else - ' pad for alignment - REM L$ = L$ + space$(32) - REM L$ = left$( L$, 32 ) - REM H$ = "00000" + hex$(N) - REM H$ = right$( H$, 5 ) - REM print #2, "#define ";L$;" X";H$ - REM N = N + 1 - if len( L$ ) > 0 then - print #2, L$ - end if - end if - end if -wend -print "Lines read from bwbasic.h :"; T -close #2 -close #1 -REM sort before assigning value -print "Sorting" -if shell( "sort < cms.txt > cms.out" ) = 0 then - N = 0 - open "cms.out" for input as #1 - open "cms.h" for output as #2 - T = 0 - while not eof(#1) - T = T + 1 - line input #1, L$ - L$ = trim$(L$) - if len(L$) then - ' pad for alignment - L$ = L$ + space$(32) - L$ = left$( L$, 32 ) - H$ = "00000" + hex$(N) - H$ = right$( H$, 5 ) - print #2, "#define ";L$;" X";H$ - N = N + 1 - end if - wend - print "Lines read from cms.out : "; T - close #2 - close #1 - rem Cleanup temporary files -print "Output in cms.h" -kill "cms.txt" -kill "cms.out" -end if -end diff --git a/Junk/compile b/Junk/compile deleted file mode 100755 index 1227be2..0000000 --- a/Junk/compile +++ /dev/null @@ -1,35 +0,0 @@ -echo "12/13/2019 Ken. Works under Ubuntu Linux 18.04, 19.10" -echo "Ubuntu Mate 20.04 Debian 10 and Ubuntu under Windows WSL." -echo " " -rm -f bwbasic renum -echo "Compile in progress..." -gcc -ansi -o bwbasic bw*.c -lm -gcc -ansi -o renum renum.c -lm -dir -l bwbasic renum -echo " " -echo -e "Be sure you are NOT running this as root. You are ($USER).\a" -echo -e -n "Results look OK?? If yes press ENTER otherwise press Ctrl/c: \a" -read j -echo " " -echo "Copying in progress" -sudo cp bwbasic /usr/local/bin/bwbasic -sudo cp bwbasic.png /usr/share/pixmaps/bwbasic.png -sudo cp renum /usr/local/bin/renum -echo "Setting up mode and ownership to root." -sudo chmod 755 /usr/local/bin/bwbasic -sudo chown root /usr/local/bin/bwbasic -sudo chmod 755 /usr/local/bin/renum -sudo chown root /usr/local/bin/renum -echo "Copying Desktop entry and icon for bwbasic on a GUI." -echo "Entry should appear on the Desktop for $USER" -sudo cp bwbasic.desktop /home/$USER/Desktop/. -echo "Setting up mode and ownership for desktop entry for $USER" -sudo chmod 777 /home/$USER/Desktop/bwbasic.desktop -sudo chown $USER /home/$USER/Desktop/bwbasic.desktop -echo "Copying completed" -echo " " -echo "You should now be able to run bwbasic from the command line or desktop." -echo "And use renum (renumbering tool) from the command line." -echo " " -echo -e "-- Done --\a" - diff --git a/Junk/compile.bat b/Junk/compile.bat deleted file mode 100644 index 38791bc..0000000 --- a/Junk/compile.bat +++ /dev/null @@ -1,51 +0,0 @@ -@echo off -echo 12/13/2019 Ken. bwbasic. Works under Windows 10 using gcc 7.4.0 -echo and gcc 8.1.0 64 bit -echo Wait -echo. - -if exist *.o del *.o -if exist bwbasic.exe del bwbasic.exe -if exist renum.exe del renum.exe - -call stdcomp bwbasic.c -call stdcomp bwb_int.c -call stdcomp bwb_tbl.c -call stdcomp bwb_cmd.c -call stdcomp bwb_prn.c -call stdcomp bwb_exp.c -call stdcomp bwb_var.c -call stdcomp bwb_inp.c -call stdcomp bwb_fnc.c -call stdcomp bwb_cnd.c -call stdcomp bwb_dio.c -call stdcomp bwb_str.c -call stdcomp bwb_stc.c -call stdcomp bwx_tty.c -call stdcomp bwd_cmd.c -call stdcomp bwd_fun.c - -gcc -s -ansi -o bwbasic.exe bwb_cmd.o bwb_cnd.o bwb_dio.o bwb_exp.o bwb_fnc.o bwb_inp.o bwb_int.o bwb_prn.o bwb_stc.o bwb_str.o bwb_tbl.o bwb_var.o bwbasic.o bwd_cmd.o bwd_fun.o bwx_tty.o - -gcc -s -ansi -DMSDOS -o renum.exe renum.c - -if exist "renum.exe" ( - echo. - echo Compile suceeded for renum.exe. -) else ( - echo. - echo Compile FAILED for renum.exe. -) - -if exist "bwbasic.exe" ( - echo. - echo Compile suceeded for bwbasic.exe. -) else ( - echo. - echo Compile FAILED. Bwbasic.exe was not created. -) - -echo. -echo --Done-- -echo. -@echo on diff --git a/Junk/factorials.bas b/Junk/factorials.bas deleted file mode 100644 index 3f59829..0000000 --- a/Junk/factorials.bas +++ /dev/null @@ -1,6 +0,0 @@ -100 f = 1 -200 FOR i = 0 TO 16 -300 PRINT i; "! ="; f -400 f = f * (i + 1) -500 NEXT i - diff --git a/Junk/renum.c b/Junk/renum.c deleted file mode 100644 index bb34a9c..0000000 --- a/Junk/renum.c +++ /dev/null @@ -1,608 +0,0 @@ -/*-------------------------------------------------------------------*/ -/* renum.c -- Renumbers a BASIC program in an ASCII file. */ -/* Originally written in HP 2000 BASIC by David Lance Robinson, 1977 */ -/* Adapted to MS BASIC and translated to C 4/1995 by Jon B. Volkoff */ -/* (eidetics@cerf.net) */ -/*-------------------------------------------------------------------*/ - -#include -#include -#include - -#define MAX_LINE_LENGTH 255 -#define MAX_LINE_COUNT 1500 - -int instr(); -char *midstr1(); -char *midstr2(); -void binary_search(void); - -int f2, l2, n, x; -int sidx[MAX_LINE_COUNT][2]; -char rstr[MAX_LINE_LENGTH]; - -int main(argc, argv) - int argc; - char *argv[]; -{ - int f, d, s, p, s1, t, l, g; - int c, f1, c1, i, f8, r, l1, l3; - int v1, f6, l6, b, f9, x9, b1, p8, p9, a, d9; - char pstr[MAX_LINE_LENGTH]; - char sstr[MAX_LINE_LENGTH]; - char f9str[MAX_LINE_LENGTH]; - char s9str[MAX_LINE_LENGTH]; - char tempstr[MAX_LINE_LENGTH + 64]; - FILE *fdin; - FILE *fdout; - int skip, bp, temp, getout, disp_msg; - - f = 1; - - printf("Version 12/13/2019\n"); - - if (argc > 1) strcpy(pstr, argv[1]); - else - { - printf("Program in file? "); - fgets(pstr,MAX_LINE_LENGTH, stdin); - if (strchr(pstr, '\n') != NULL) - { - pstr[strlen(pstr)-1] = '\0'; - } - - } - if (strlen(pstr) == 0) strcpy(pstr, "0.doc"); - - fdin = fopen(pstr, "r"); - if (fdin == NULL) - { - printf("Unable to open input file\n"); - exit(1); - } - strcpy(f9str, pstr); - -#if defined(__MVS__) || defined(__CMS__) - strcpy(pstr, "dd:editfl"); -#else - strcpy(pstr, "editfl"); -#endif - - fdout = fopen(pstr, "w"); - if (fdout == NULL) - { - printf("Unable to open temporary file editfl for output\n"); - exit(1); - } - - /* Main program begins here */ - s = 0; l2 = 0; d = 0; - f2 = 10000; - printf ("PLEASE WAIT A FEW SECONDS!\n"); - while (fgets(pstr, MAX_LINE_LENGTH, fdin) != NULL) - { - pstr[strlen(pstr) - 1] = '\0'; - p = instr(pstr, " "); - if (p != 0 && p <= 5) - { - n = atoi(midstr2(pstr, 1, p)); - if (n != 0) - { - s++; - if( s < MAX_LINE_COUNT ) - { - /* OK */ - } - else - { - printf("Too many lines\n"); - exit(1); - } - sidx[s][0] = n; - s1 = s; - while (s1 >= 2) - { - s1--; - if (sidx[s1][0] < sidx[s1 + 1][0]) break; - if (sidx[s1][0] == sidx[s1 + 1][0]) - { - printf("ERROR !!! MORE THAN ONE STATEMENT FOR A "); - printf("STATEMENT NUMBER\n"); - exit(1); - } - - t = sidx[s1][0]; - sidx[s1][0] = sidx[s1 + 1][0]; - sidx[s1 + 1][0] = t; - } - } - } - } - fclose(fdin); - - strcpy(pstr, ""); - - if (s == 0) - { - printf("NO PROGRAM IS IN THE FILE!\n"); - exit(1); - } - - for (l = 1; l <= s; l++) - sidx[l][1] = sidx[l][0]; - g = 1; - disp_msg = 1; - - /*------------------------------------------------------------------------*/ - /* Find out how and what to renumber (using HP BASIC renumber parameters) */ - /* MS BASIC renumber is: RENUM (newnum) (,(oldnum) (,increment)) */ - /*------------------------------------------------------------------------*/ - - while(1) - { - if (disp_msg == 1) - { - printf("RENUMBER (-starting number (,interval (,first statement "); - printf("(,last))))\n"); - disp_msg = 0; - } - - skip = 0; - bp = 0; - printf("RENUMBER-"); - fgets(pstr,MAX_LINE_LENGTH,stdin); - p = strlen(pstr); - - if (g == 0) - { - if (strlen(pstr) == 0) break; - if (p == 0) skip = 1; - else - { - t = atoi(midstr2(pstr, 1, 1)); - if (t == 0) break; - } - } - - if (strlen(pstr) == 0) skip = 1; - - if (skip == 0) - { - c = instr(pstr, ","); - temp = 0; if (c != 0) temp = -1; - f1 = atoi(midstr2(pstr, 1, p + temp*(p - c + 1))); - if (f1 == 0) bp = 1; - if (c == 0) skip = 2; - } - - if (skip == 0 && bp == 0) - { - c1 = instr(midstr1(pstr, c + 1), ",") + c; - temp = 0; if (c1 != c) temp = -1; - i = atoi(midstr2(pstr, c + 1, p + temp*(p - c1 + 1) - c)); - if (i == 0) bp = 1; - if (c1 == c) skip = 3; - } - - if (skip == 0 && bp == 0) - { - c = instr(midstr1(pstr, c1 + 1), ",") + c1; - temp = 0; if (c != c1) temp = -1; - f8 = atoi(midstr2(pstr, c1 + 1, p + temp*(p - c + 1) - c1)); - if (f8 == 0) bp = 1; - if (c == c1) skip = 4; - } - - if (skip == 0 && bp == 0) - { - l = atoi(midstr1(pstr, c + 1)); - if (l == 0) bp = 1; - } - - if (bp == 0) switch (skip) - { - case 1: - f1 = 10; - i = 10; - f8 = 1; - l = 99999; - break; - - case 2: - i = 10; - f8 = 1; - l = 99999; - break; - - case 3: - f8 = 1; - l = 99999; - break; - - case 4: - l = 99999; - break; - } - - if (f1 < 1 || i == 0 || f8 < 1 || l < 1) bp = 1; - - if (f1 > 99999 || i > 99999 || f8 > 99999 || l > 99999 || f8 > l) - bp = 1; - - c = 0; - for (r = 1; r <= s; r++) - if (sidx[r][0] >= f8 && sidx[r][0] <= l) c = c + 1; - if (c == 0) - { - printf("There is nothing to renumber !!\n"); - disp_msg = 1; - } - - /*------------------------------------*/ - /* Make list of new statement numbers */ - /*------------------------------------*/ - - l1 = f1 + (c - 1)*i; - if (l1 < 1 || l1 > 99999) bp = 1; - - x = 0; c = 0; - if (bp == 0 && disp_msg == 0) for (r = 1; r <= s; r++) - { - if (sidx[r][0] < f8 || sidx[r][0] > l) - if (sidx[r][1] >= f1 && sidx[r][1] <= l1) - { - printf("SEQUENCE NUMBER OVERLAP\n"); - exit(1); - } - else {} - else - { - if (sidx[r][0] != f1 + c*i) - { - if (x == 0) - { - if (r < f2) f2 = r; - x = 1; - } - - if (r > l2) l2 = r; - } - - sidx[r][1] = f1 + c*i; - c++; - l3 = r; - } - } - - if (bp == 0 && disp_msg == 0) g = 0; - - if (bp == 1) printf("BAD PARAMETER\n"); - } - - /*-------------------*/ - /* Start renumbering */ - /*-------------------*/ - - if (l2 == 0) - { - printf("NOTHING RENUMBERED!\n"); - exit(1); - } - - printf("RENUMBERING\n"); - -/* - for (r = 1; r <= s; r ++) - printf("%d -> %d\n", sidx[r][0], sidx[r][1]); - */ - - printf("VERIFY? N or n cancels:"); - fgets(pstr,MAX_LINE_LENGTH,stdin); - v1 = 0; - if (strcmp(midstr2(pstr, 1, 1), "N") == 0) v1 = 1; - if (strcmp(midstr2(pstr, 1, 1), "n") == 0) v1 = 1; - - if (v1 == 1) { - printf("Operation cancelled\n"); - exit(1); - } - - fdin = fopen(f9str, "r"); - if (fdin == NULL) - { - printf("Unable to open input file\n"); - exit(1); - } - - f6 = sidx[f2][0]; - l6 = sidx[l2][0]; - - while (fgets(pstr, MAX_LINE_LENGTH, fdin) != NULL) - { - pstr[strlen(pstr) - 1] = '\0'; - b = instr(pstr, " "); - if (b != 0) - { - n = atoi(midstr2(pstr, 1, b)); - if (n != 0) - { - if (n >= f6 && n <= l6) - { - binary_search(); - if (x == 0) - { - strcat(rstr, midstr1(pstr, b)); - strcpy(pstr, rstr); - b = instr(pstr, " "); - } - } - b++; - - /*-------------------------------------------------------------*/ - /* There are differences, of course, between processing for HP */ - /* BASIC and MS BASIC. */ - /* */ - /* CONVERT, PRINT USING, and MAT PRINT USING changes are not */ - /* applicable in MS BASIC. */ - /* */ - /* Had to also add capability for multiple statements here. */ - /*-------------------------------------------------------------*/ - - while(1) - { - if (strcmp(midstr2(pstr, b, 3), "REM") == 0 || - strcmp(midstr2(pstr, b, 1), "'") == 0) break; - - f9 = 0; - skip = 0; - for (x9 = b; x9 <= strlen(pstr); x9++) - { - if ((char)(*midstr2(pstr, x9, 1)) == 34) - { - if (f9 == 0) - f9 = 1; - else - f9 = 0; - } - else if (strcmp(midstr2(pstr, x9, 1), ":") == 0 && - f9 == 0) - { - b1 = x9 - 1; - skip = 1; - break; - } - } - if (skip == 0) b1 = strlen(pstr); - - t = instr("GOSGOTIF ON RESRET", midstr2(pstr, b, 3)); - - temp = (t + 5)/3; - if (temp != 1) - { - if (temp == 2 || temp == 3 || temp == 4 || temp == 6 || - temp == 7) - { - /*-------------------------------------------------*/ - /* Change GOSUB, GOTO, IF, RESTORE, RESUME, RETURN */ - /* routine. */ - /* Go word by word through the statement. */ - /*-------------------------------------------------*/ - getout = 0; - p8 = b; - strcpy(s9str, " "); - } - else if (temp == 5) - { - /*---------------------------------------------------*/ - /* Change ON event/expression GOSUB/GOTO routine. */ - /* Find starting point appropriate to this statement */ - /* type. */ - /*---------------------------------------------------*/ - getout = 1; - for (x9 = b1; x9 >= b; x9--) - { - if (strcmp(midstr2(pstr, x9, 1), " ") == 0) - { - p8 = x9 + 1; - getout = 0; - break; - } - } - - if (getout == 0) strcpy(s9str, ","); - } - - /* Start looping here */ - if (getout == 0) while(1) - { - f9 = 0; - skip = 0; - for (x9 = p8; x9 <= b1; x9++) - { - if ((char)(*midstr2(pstr, x9, 1)) == 34) - { - if (f9 == 0) - f9 = 1; - else - f9 = 0; - } - else if (strcmp(midstr2(pstr, x9, 1), s9str) == 0 && - f9 == 0) - { - p9 = x9 - 1; - skip = 1; - break; - } - } - if (skip == 0) p9 = b1; - - skip = 0; - for (x9 = p8; x9 <= p9; x9++) - { - a = (char)(*midstr2(pstr, x9, 1)); - if (a < 48 || a > 57) - { - skip = 1; - break; - } - } - - if (skip == 0) - { - /*---------------------*/ - /* Found a line number */ - /*---------------------*/ - n = atoi(midstr2(pstr, p8, p9 - p8 + 1)); - if (n != 0) - { - if (n >= f6 && n <= l6) - { - binary_search(); - if (x == 0) - { - if (p9 == strlen(pstr)) - { - strcpy(tempstr, midstr2(pstr, 1, p8 - 1)); - strcat(tempstr, rstr); - strcpy(pstr, tempstr); - } - else - { - strcpy(tempstr, midstr2(pstr, 1, p8 - 1)); - strcat(tempstr, rstr); - strcat(tempstr, midstr1(pstr, p9 + 1)); - strcpy(pstr, tempstr); - } - - /*-----------------------------------*/ - /* Adjust indices to account for new */ - /* substring length, if any. */ - /*-----------------------------------*/ - d9 = strlen(rstr) - (p9 - p8 + 1); - p9 = p9 + d9; - b1 = b1 + d9; - } - } - } - } - - p8 = p9 + 2; - if (p8 > b1) break; - } - } - - /*--------------------------------------------------*/ - /* No more words to process in the statement, go to */ - /* next statement. */ - /*--------------------------------------------------*/ - if (b1 == strlen(pstr)) break; - b = b1 + 2; - } - } - } - - fprintf(fdout, "%s\n", pstr); - if (v1 == 0) printf("%s\n", pstr); - } - - fclose(fdin); - fclose(fdout); - -#if !defined(__MVS__) && !defined(__CMS__) && !defined(MSDOS) - tempstr[strlen(tempstr)] = '\0'; - sprintf(tempstr, "cp editfl %s", f9str); - system(tempstr); -#endif -#if defined(MSDOS) - tempstr[strlen(tempstr)] = '\0'; - sprintf(tempstr, "copy editfl %s", f9str); - system(tempstr); -#endif - - return (0); -} - - -int instr(astr, bstr) - char *astr, *bstr; -{ - char *p; - int q; - - p = strstr(astr, bstr); - if (p == NULL) - { - q = 0; - } - else - { - q = (p - astr) + 1; - } - return q; -} - - -char *midstr1(astr, start) - char *astr; - int start; -{ - static char tempstr[MAX_LINE_LENGTH]; - char *startptr; - - strcpy(tempstr, astr); - startptr = (char *)((long)(tempstr) + start - 1); - - return startptr; -} - - -char *midstr2(astr, start, len) - char *astr; - int start, len; -{ - static char tempstr[MAX_LINE_LENGTH]; - char *startptr, *endptr; - - strcpy(tempstr, astr); - startptr = (char *)((long)(tempstr) + start - 1); - endptr = (char *)((long)(tempstr) + start + len - 1); - strcpy(endptr, "\0"); - - return startptr; -} - - -void binary_search(void) -{ - int f5, l5; - - f5 = f2; - l5 = l2 + 1; - - while(1) - { - int m; - - m = (f5 + l5)/2; - - if (sidx[m][0] == n) - { - rstr[strlen(rstr)] = '\0'; - sprintf(rstr, "%d", sidx[m][1]); - x = 0; - return; - } - - if (m == f5 || m == l5) - { - x = 1; - return; - } - - if (sidx[m][0] < n) - f5 = m; - else - l5 = m; - } -} - diff --git a/Junk/stdcomp.bat b/Junk/stdcomp.bat deleted file mode 100644 index 3df173b..0000000 --- a/Junk/stdcomp.bat +++ /dev/null @@ -1 +0,0 @@ -gcc -w -c -ansi -I . %1 %2 %3 %4 %5 %6 %7 %8 %9 diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..9656a06 --- /dev/null +++ b/Makefile @@ -0,0 +1,48 @@ +# +# Makefile for bwbasic on Linux 4-30-2020 +# Now version bwbasic-3.20b +# +# Tested on Ubuntu 18.04 Had to fix compatabily issues +# Ubuntu 20.04 Had to fix compatabily issues +# Debian 10 Buster +# Beaglebone Black with Debian 10 +# Raspberry Pi running Debian 10 Buster +# Linux Mint LMDE4 +# Linux Lite 4.8 +# +# ken.at.github@gmail.com +# +CC=gcc +# If running on a Beaglebone you might want to replace +# CFLAGS=-s -ansi with CFLAGS=-Os -ansi +# to have a smaller runtime size +CFLAGS=-s -ansi +LIB=-lm +DEST=/usr/local/bin + +bwbasic: + $(CC) $(CFLAGS) -o bwbasic bw*.c $(LIB) + $(CC) $(CFLAGS) -o renum renum.c $(LIB) + ls -l bwbasic renum + +# bwbasic and renum runtime. editfl temp file created by renum +clean: + rm -f *.o bwbasic renum editfl + +install: + ls -l bwbasic renum + cp bwbasic renum $(DEST)/. + ls -l $(DEST)/bwbasic $(DEST)/renum + +remove: + rm $(DEST)/bwbasic $(DEST)/renum + +uninstall: + rm $(DEST)/bwbasic $(DEST)/renum + +run: + $(DEST)/bwbasic + +runlocal: + ./bwbasic + diff --git a/README b/README index b11ecc4..47f062a 100644 --- a/README +++ b/README @@ -42,6 +42,9 @@ Version 3.20 modifications by Howard Wulf, AF5NE 4 June 2017 + Version 3.20b modifications by Ken Martin + Nov. 2019 Apr. 2020 + @@ -65,7 +68,10 @@ DESCRIPTION: OBTAINING THE SOURCE CODE: - The source code for bwBASIC is available from + The source code for bwbasic-3.20b is available from + https://github.com/kenmartin-unix/Bwbasic-3.20b + + The source code for older versions bwBASIC is available from http://bwbasic.sourceforge.net @@ -74,6 +80,7 @@ COMMUNICATIONS: email: tcamp@delphi.com (for Ted Campbell) eidetics@cerf.net (for Jon Volkoff) mutazilah@gmail.com (for Paul Edwards) + ken.at.github@gmail.com (for Ken Martin) A LIST OF BASIC COMMANDS AND FUNCTIONS IMPLEMENTED in bwBASIC: @@ -87,6 +94,10 @@ A LIST OF BASIC COMMANDS AND FUNCTIONS IMPLEMENTED in bwBASIC: CHANGE HISTORY +CHANGES FROM 3.20 to 3.20b + + * General cleanup and bug fixes. + CHANGES FROM 3.10 to 3.20 * Implements most of the following BASIC dialects: @@ -480,6 +491,3 @@ CHANGES FROM 2.10 to 2.20: * Added checking in configure for unistd.h (important on Sun systems). - - - diff --git a/READMEFIRST b/READMEFIRST new file mode 100644 index 0000000..17d3516 --- /dev/null +++ b/READMEFIRST @@ -0,0 +1,119 @@ +4-16-2020 Updated 4-30-2020 3.20b + +Bwbasic has been around since the early 1990's +in one form or another and actually quite powerfull. + +This should work under most any Linux and Linux under +WSL (Ubuntu, Debian) for windows at the command prompt. + +If running this under Linux you will need 'gcc' compiler. +To see if it's installed type in gcc --version if OK +then simply do the following: + +tar -xf bwbasic-3.20b.tar + +cd + +To make 'cls' work as it does in DOS perform once + +sudo ln /usr/bin/clear /usr/bin/cls + +Tip: Now linking to clear within a bwbasic program you + can clear the screen using command SHELL "cls" + This can be embedded in you program. You can also + use OPTION TERMINAL ANSI then use command CLS + +Now lets build bwbasic and renum + +(1) make +To test before installing (2) make runlocal +Then to install (3) sudo make install +To remove installed programs (4) sudo make remove +To remove compiled programs and recompile (5) make clean + +That's it. + +bwbasic and renum will be in /usr/local/bin + +If you want bwbasic to work from a GUI cd GUI +(1) copy bwbasic.sh to a suitable location + and make sure to chmod 755 bwbasic.sh + so it's executable. +(2) copy bwbasic.png to a suitable location +(3) edit bwbasic.desktop and change references + for File Location and png location then + cp bwbasic.desktop to ~/Desktop/. + and it should work from the desktop. + +Doing the above should allow you to click on the icon +on your desktop and start bwbasic. + +If running under Windows 10 you will need 'gcc' compiler. +To see if it's installed type in gcc --version if you +think you have gcc installed verify your 'PATH' by entering +at the command prompt echo %PATH% to see if it's there. +If OK then at the command prompt + +cd + +compile.bat + +Read prompts + +That's it. + +Move bwbasic.exe and renum.exe to locations in your PATH. + +There are many, many examples in BAS-EXAMPLES and +available information in INFO. + +All should work fine. But as usual no guarentee is implied. + +Any references below to relays pertain to the BeagleBone Black. + +I have included some runtime files and sample input files. +Place profile.bas in your current working directory and +relays.pro and allon.inp and alloff.inp. The file examples +will let you to by example turn off all relays alloff.inp. +To do this you would enter at the command line: + +bwbasic --profile relays.pro --tape alloff.inp relays.bas + +To turn all relays on: + +bwbasic --profile relays.pro --tape allon.inp relays.bas + +To work interactive you would: + +bwbasic relays.bas + +Once you get a handle on relays.bas commands you can +create you own .inp files and reference them by + +bwbasic --profile relays.pro --tape relays.bas + +All the above can placed into a simple script file. + +The purpose of relays.pro is to redirect standard and error +outputs to files relays-stdout.txt and relays-error.txt and +to turn off ANSI so the output is easily readable without +escape codes. Using relays.pro then gives you a quiet display +suitable when scripts via .inp is executed. + +The purpose of profile.bas which is used by default is to +enable ANSI control sequences so the command 'cls' works +and to set the normal editor to nano which if desired can +bet set to vi. The editor comes into play when creating +or changing a .bas file. To use while running bwbasic you +would issue the command edit. + +As a simple example try the guessing game with + +bwbasic guess.bas + +If you come up with some ideas or enhancements or have a +problem drop me a message keeping in mind my main goal +is to do maintenance updates where necessary. + +ken.at.github@gmail.com + diff --git a/abs.bas b/abs.bas index ebc2813..e5267e5 100644 --- a/abs.bas +++ b/abs.bas @@ -1,5 +1,5 @@ -500 rem ABS.BAS -- Test ABS() function -505 X = -1.23456789 -510 ABSX = ABS( X ) -515 print "The absolute value of "; X; " is"; ABSX -520 print "Is that correct?" +100 rem ABS.BAS -- Test ABS() function +110 X = -1.23456789 +120 ABSX = ABS( X ) +130 print "The absolute value of "; X; " is"; ABSX +140 print "Is that correct?" diff --git a/bas/abs.bas b/bas/abs.bas deleted file mode 100644 index 8ff3889..0000000 --- a/bas/abs.bas +++ /dev/null @@ -1,5 +0,0 @@ -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?" diff --git a/bas/fibonacci.bas b/bas/fibonacci.bas deleted file mode 100644 index 8a5adfe..0000000 --- a/bas/fibonacci.bas +++ /dev/null @@ -1,14 +0,0 @@ - 10 rem 12/13/2019 Ken Fibonacci - 100 DIM F(16) - 150 F(1) = 1 - 200 F(2) = 1 - 250 FOR i = 3 TO 16 - 260 F(i) = F(i - 1) + F(i - 2) - 270 NEXT i - 280 S$ = "" - 290 FOR i = 1 TO 16 - 300 S$ = S$ + STR$(F(i)) + "," - 350 NEXT i - 400 S$ = S$ + " ..." - 500 PRINT S$ - diff --git a/bas/selcase.bas b/bas/selcase.bas deleted file mode 100644 index 8fca268..0000000 --- a/bas/selcase.bas +++ /dev/null @@ -1,31 +0,0 @@ -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 - - diff --git a/bin-to-dec.bas b/bin-to-dec.bas new file mode 100644 index 0000000..9d016b7 --- /dev/null +++ b/bin-to-dec.bas @@ -0,0 +1,24 @@ + 10 CALL SHELL("cls") + 100 LET P = 0 + : LET S = 0 + 110 INPUT "Enter binary number: ";N$ + 120 L = LEN (N$) + : IF L=0 GOTO 300 + 130 FOR I=1 TO L + 135 IF (N$ = "0") GOTO 1000 + 140 LET B$ = MID$(N$, L-I+1, 1) + 150 IF NOT (B$ = "0" OR B$ = "1") GOTO 300 + 160 LET K = VAL(B$) + 170 IF (K > 0) THEN + : S = S + 2 ^ P + : END IF + 180 LET P = P + 1 + 190 NEXT + 200 GOTO 310 + 300 PRINT "Error, invalid binary entered" + : GOTO 100 + 310 PRINT + 315 PRINT "Equals decimal ";S + 320 PRINT + 1000 END + diff --git a/bwb_cmd.c b/bwb_cmd.c index be2ba2d..8a74c0d 100644 --- a/bwb_cmd.c +++ b/bwb_cmd.c @@ -36,7 +36,8 @@ /* */ /* Version 3.20 by Howard Wulf, AF5NE */ /* */ -/* Version 3.20A by Ken Martin Mainly corrected fprint issues */ +/* Version 3.20b by Ken Martin Mainly corrected fprint and */ +/* fread and fgets to work in Ubuntu */ /* */ /*---------------------------------------------------------------*/ @@ -90,6 +91,7 @@ bwx_run (LineType * Line, char *ProgramName) { size_t n; char *tbuf; + int retn; assert (Line != NULL); assert( My != NULL ); @@ -113,7 +115,7 @@ bwx_run (LineType * Line, char *ProgramName) bwb_strcpy (tbuf, ProgramName); bwb_strcat (tbuf, " "); bwb_strcat (tbuf, My->ProgramFilename); - system (tbuf); + retn=system (tbuf); free (tbuf); tbuf = NULL; @@ -2501,7 +2503,7 @@ bwb_RENAME (LineType * l) extern void Determinant (VariableType * v) { - /* http://easy-learn-c-language.blogspot.com/search/label/Numerical%20Methods */ + /* http://easy-learn-c-language.blogspot.com/search/label/Numerical Methods */ /* Numerical Methods: Determinant of nxn matrix using C */ DoubleType **matrix; @@ -2628,7 +2630,7 @@ EXIT: int InvertMatrix (VariableType * vOut, VariableType * vIn) { - /* http://easy-learn-c-language.blogspot.com/search/label/Numerical%20Methods */ + /* http://easy-learn-c-language.blogspot.com/search/label/Numerical Methods */ /* Numerical Methods: Inverse of nxn matrix using C */ int Result; @@ -4200,6 +4202,7 @@ bwb_CLOAD8 (LineType * l) unsigned long n; size_t t; char varname[NameLengthMax + 1]; + int myfget; assert (l != NULL); @@ -4249,7 +4252,7 @@ bwb_CLOAD8 (LineType * l) } /* read version number */ n = 0; - fread (&n, sizeof (long), 1, f); + myfget=fread (&n, sizeof (long), 1, f); if (n != CSAVE_VERSION_1) { bwb_fclose (f); @@ -4258,7 +4261,7 @@ bwb_CLOAD8 (LineType * l) } /* read total number of elements */ n = 0; - fread (&n, sizeof (long), 1, f); + myfget=fread (&n, sizeof (long), 1, f); if (n != t) { bwb_fclose (f); @@ -4266,7 +4269,7 @@ bwb_CLOAD8 (LineType * l) return (l); } /* read data */ - fread (v->Value.Number, sizeof (DoubleType), t, f); + myfget=fread (v->Value.Number, sizeof (DoubleType), t, f); /* OK */ bwb_fclose (f); return (l); @@ -6247,7 +6250,8 @@ LineType * bwb_CMDS (LineType * l) { int n; - int t; + int lmtch; + int lcnt; assert (l != NULL); assert( My != NULL ); @@ -6255,29 +6259,21 @@ bwb_CMDS (LineType * l) assert( My->SYSOUT->cfp != NULL ); My->CurrentFile = My->SYSOUT; - fprintf (My->SYSOUT->cfp, "BWBASIC COMMANDS AVAILABLE:\n"); + fprintf (My->SYSOUT->cfp, "\nBWBASIC COMMANDS AVAILABLE:\n\n"); - /* run through the command table and print comand names */ + /* run through the command table and print command names */ - t = 0; - for (n = 0; n < NUM_COMMANDS; n++) + lcnt = 0; + + for (n = 0; n < NUM_COMMANDS; n++) /* Loop through table Ken 4-2020 */ { - fprintf (My->SYSOUT->cfp, "%s", IntrinsicCommandTable[n].name); - if (t < 4) - { - fprintf (My->SYSOUT->cfp, "\t"); - t++; - } - else - { - fprintf (My->SYSOUT->cfp, "\n"); - t = 0; - } + lmtch = strcmp(IntrinsicCommandTable[n].name,IntrinsicCommandTable[n+1].name); + if (lmtch != 0) { /* If duplicate don't print */ + fprintf (My->SYSOUT->cfp, "%s\n", IntrinsicCommandTable[n].name); + lcnt = lcnt + 1; } - if (t > 0) - { - fprintf (My->SYSOUT->cfp, "\n"); } + fprintf (My->SYSOUT->cfp, "\nTotal Commands %d\n\n",lcnt); ResetConsoleColumn (); return (l); } diff --git a/bwbasic.c b/bwbasic.c index cfd80f2..b674f27 100644 --- a/bwbasic.c +++ b/bwbasic.c @@ -36,7 +36,7 @@ /* */ /* Version 3.20 by Howard Wulf, AF5NE */ /* */ -/* Version 3.20A by Ken Martin */ +/* Version 3.20b by Ken Martin */ /* */ /*---------------------------------------------------------------*/ @@ -83,11 +83,11 @@ static char *Banner[] = { " ## ## ## ## ## ## ## ## ##", " ######## ## ## ###### #### ###### ", " ", - "Bywater BASIC Interpreter, version 3.20A ", + "Bywater BASIC Interpreter, version 3.20b ", "Copyright (c) 1993, Ted A. Campbell ", "Copyright (c) 1995-1997 , Jon B. Volkoff ", "Copyright (c) 2014-2017 , Howard Wulf, AF5NE ", - "Copyright (c) 11/2019 , Ken Martin ", + " 2019-2020 , Ken Martin ", " ", NULL }; @@ -104,6 +104,7 @@ bwb_initialize_warnings (void) { ERROR4[i] = NULL; } + /* Error code tree */ ERROR4[1] = "NEXT without FOR"; ERROR4[2] = "Syntax error"; ERROR4[3] = "RETURN without GOSUB"; diff --git a/bwbasic.desktop b/bwbasic.desktop deleted file mode 100644 index add1fac..0000000 --- a/bwbasic.desktop +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env xdg-open -[Desktop Entry] -Encoding=UTF-8 -Name=Bywater BASIC -GenericName=Bywater BASIC -Type=Application -Exec=bwbasic -Icon=/usr/share/pixmaps/bwbasic.png -StartupNotify=true -Terminal=true -Categories=Development diff --git a/cms.bas b/cms.bas deleted file mode 100644 index 2dd98f3..0000000 --- a/cms.bas +++ /dev/null @@ -1,117 +0,0 @@ -rem Purpose: re-define externals to only 6 characters for CMS -rem Author: Howard Wulf, AF5NE -rem Date: 2015-02-10 -rem Usage: implementation defined -rem Example: -rem ~/bwbasic cms.bas -rem -rem ------------------------------------------------------------------------------- -rem File File Name IN/OUT Description -rem #1 "bwbasic.h" INPUT read looking for "extern" statements -rem #2 "cms.h" OUTPUT written with "#define" statements -rem ------------------------------------------------------------------------------- -rem Variable Description -rem N The number of "extern" statements so far processed -rem E$ The constant value "extern " -rem E The length of E$ -rem L$ The input line read from "bwbasic.h" -rem M$ The next line from "bwbasic.h" when L$ does not contain a semicolon -rem X The location of special characters in L$ -rem H$ The hexadecimal value of N -rem T Read count -rem ------------------------------------------------------------------------------- -rem -let N = 0 -let E$ = "extern " -let E = len( E$ ) -open "bwbasic.h" for input as #1 -open "cms.txt" for output as #2 -T = 0 -while not eof( #1 ) - T = T + 1 - line input #1, L$ - L$ = trim$( L$ ) - if left$( L$, E ) = E$ then - rem extern .... - while instr( L$, ";" ) = 0 - ' read more lines until we get a semicolon - line input #1, M$ - M$ = trim$( M$ ) - L$ = L$ + " " + M$ - wend - rem extern ...; - L$ = trim$(mid$( L$, E + 1 )) - ' truncate trailing semicolon - X = instr( L$, ";" ) - if X > 0 then - L$ = trim$(left$( L$, X - 1 )) - end if - ' truncate trailing parenthesis - X = instr( L$, "(" ) - if X > 0 then - L$ = trim$(left$( L$, X - 1 )) - end if - ' truncate trailing bracket - X = instr( L$, "[" ) - if X > 0 then - L$ = trim$(left$( L$, X - 1 )) - end if - ' find the last word - X = instr(L$, " " ) - while X > 0 - L$ = trim$(mid$( L$, X + 1 )) - X = instr(L$, " " ) - wend - ' skip leading asterick - while left$( L$, 1 ) = "*" - L$ = trim$(mid$( L$, 2 )) - wend - if L$ = "main" or L$ = "putenv" or L$="sleep" then - ' ignore magic function name - else - ' pad for alignment - REM L$ = L$ + space$(32) - REM L$ = left$( L$, 32 ) - REM H$ = "00000" + hex$(N) - REM H$ = right$( H$, 5 ) - REM print #2, "#define ";L$;" X";H$ - REM N = N + 1 - if len( L$ ) > 0 then - print #2, L$ - end if - end if - end if -wend -print "Lines read from bwbasic.h :"; T -close #2 -close #1 -REM sort before assigning value -print "Sorting" -if shell( "sort < cms.txt > cms.out" ) = 0 then - N = 0 - open "cms.out" for input as #1 - open "cms.h" for output as #2 - T = 0 - while not eof(#1) - T = T + 1 - line input #1, L$ - L$ = trim$(L$) - if len(L$) then - ' pad for alignment - L$ = L$ + space$(32) - L$ = left$( L$, 32 ) - H$ = "00000" + hex$(N) - H$ = right$( H$, 5 ) - print #2, "#define ";L$;" X";H$ - N = N + 1 - end if - wend - print "Lines read from cms.out : "; T - close #2 - close #1 - rem Cleanup temporary files -print "Output in cms.h" -kill "cms.txt" -kill "cms.out" -end if -end diff --git a/compile b/compile deleted file mode 100755 index 1227be2..0000000 --- a/compile +++ /dev/null @@ -1,35 +0,0 @@ -echo "12/13/2019 Ken. Works under Ubuntu Linux 18.04, 19.10" -echo "Ubuntu Mate 20.04 Debian 10 and Ubuntu under Windows WSL." -echo " " -rm -f bwbasic renum -echo "Compile in progress..." -gcc -ansi -o bwbasic bw*.c -lm -gcc -ansi -o renum renum.c -lm -dir -l bwbasic renum -echo " " -echo -e "Be sure you are NOT running this as root. You are ($USER).\a" -echo -e -n "Results look OK?? If yes press ENTER otherwise press Ctrl/c: \a" -read j -echo " " -echo "Copying in progress" -sudo cp bwbasic /usr/local/bin/bwbasic -sudo cp bwbasic.png /usr/share/pixmaps/bwbasic.png -sudo cp renum /usr/local/bin/renum -echo "Setting up mode and ownership to root." -sudo chmod 755 /usr/local/bin/bwbasic -sudo chown root /usr/local/bin/bwbasic -sudo chmod 755 /usr/local/bin/renum -sudo chown root /usr/local/bin/renum -echo "Copying Desktop entry and icon for bwbasic on a GUI." -echo "Entry should appear on the Desktop for $USER" -sudo cp bwbasic.desktop /home/$USER/Desktop/. -echo "Setting up mode and ownership for desktop entry for $USER" -sudo chmod 777 /home/$USER/Desktop/bwbasic.desktop -sudo chown $USER /home/$USER/Desktop/bwbasic.desktop -echo "Copying completed" -echo " " -echo "You should now be able to run bwbasic from the command line or desktop." -echo "And use renum (renumbering tool) from the command line." -echo " " -echo -e "-- Done --\a" - diff --git a/configure b/configure deleted file mode 100755 index 6e35d2f..0000000 --- a/configure +++ /dev/null @@ -1,317 +0,0 @@ -#!/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. - -##---------------------------------------------------------------## -## NOTE: Modifications marked "JBV" were made by Jon B. Volkoff, ## -## 11/1995 (eidetics@cerf.net). ## -##---------------------------------------------------------------## - -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 < 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 -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 ' > 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 -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 -err=`eval "$CPP $DEFS conftest.c 2>&1 >/dev/null"` -if test -z "$err"; then - DEFS="$DEFS -DHAVE_STDLIB=1" -fi -rm -f conftest* - -# unistd.h checking added by JBV -echo checking for unistd.h -cat > conftest.c < -EOF -err=`eval "$CPP $DEFS conftest.c 2>&1 >/dev/null"` -if test -z "$err"; then - DEFS="$DEFS -DHAVE_UNISTD=1" -fi -rm -f conftest* - -echo checking for raise -cat > conftest.c < -#include -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 </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 - diff --git a/configure.in b/configure.in deleted file mode 100644 index c20c4db..0000000 --- a/configure.in +++ /dev/null @@ -1,12 +0,0 @@ -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_HEADER_CHECK(unistd.h, AC_DEFINE(HAVE_UNISTD)) -AC_COMPILE_CHECK(raise, [#include -#include ], [raise(1);], AC_DEFINE(HAVE_RAISE)) -AC_OUTPUT(Makefile) diff --git a/crap.bas b/crap.bas deleted file mode 100644 index 3db4765..0000000 --- a/crap.bas +++ /dev/null @@ -1,5 +0,0 @@ -500 rem ABS.BAS -- Test ABS() function -510 X = -1.23456789 -520 ABSX = ABS( X ) -530 print "The absolute value of "; X; " is"; ABSX -540 print "Is that correct?" diff --git a/curve.bas b/curve.bas new file mode 100644 index 0000000..a65cdac --- /dev/null +++ b/curve.bas @@ -0,0 +1,14 @@ + 50 rem 12/13/2019 Ken curve + 60 SHELL "cls" + 100 REM PLOT A NORMAL DISTRIBUTION CURVE + 120 DEF FNN(X) = EXP(-(X^2/2))/SQR(2*3.14159265) + 140 FOR X = -2 TO 2 STEP .1 + 150 LET Y = FNN(X) + 160 LET Y = INT(100*Y) + 170 FOR Z = 1 TO Y + 180 PRINT " "; + 190 NEXT Z + 200 PRINT "*" + 210 NEXT X + 220 END + diff --git a/dec-to-bin.bas b/dec-to-bin.bas new file mode 100644 index 0000000..deab180 --- /dev/null +++ b/dec-to-bin.bas @@ -0,0 +1,14 @@ + 5 REM input a number, output its binary representation + 10 CALL SHELL("cls") + 50 INPUT "Enter an integer greater than zero : ";A + 60 IF (A < 0 OR A<>INT(A)) GOTO 50 + 65 IF (A = 0) GOTO 140 + 70 LET B = A - INT (A/2) * 2 + 90 LET X$ = STR$(B) + X$ + 110 LET A = (A - B) / 2 + 120 IF (A > 0) GOTO 70 + 125 PRINT + 130 PRINT "As binary: ";X$ + 135 PRINT + 140 END + diff --git a/example.bas b/example.bas deleted file mode 100644 index 981fe13..0000000 --- a/example.bas +++ /dev/null @@ -1,6 +0,0 @@ - x = 1 - print "hello, world",x - x = 2 - print "hello, world",x - end - diff --git a/factorials.bas b/factorials.bas deleted file mode 100644 index 3f59829..0000000 --- a/factorials.bas +++ /dev/null @@ -1,6 +0,0 @@ -100 f = 1 -200 FOR i = 0 TO 16 -300 PRINT i; "! ="; f -400 f = f * (i + 1) -500 NEXT i - diff --git a/guess.bas b/guess.bas new file mode 100644 index 0000000..763ad8f --- /dev/null +++ b/guess.bas @@ -0,0 +1,22 @@ + 10 rem 12/13/2019 Ken guess a number game + 100 REM GUESSING GAME + 110 SHELL "cls" + 120 PRINT "GUESS THE NUMBER BETWEEN 1 AND 100." + 140 LET X = INT(100*RND(0)+1) + 150 LET N = 0 + 160 PRINT "YOUR GUESS"; + 170 INPUT G + 180 LET N = N+1 + 190 IF G = X THEN 300 + 200 IF G < X THEN 250 + 210 PRINT "TOO LARGE, GUESS AGAIN" + 220 GOTO 160 + 250 PRINT "TOO SMALL, GUESS AGAIN" + 260 GOTO 160 + 300 PRINT "YOU GUESSED IT, IN"; N; "TRIES" + 310 PRINT "ANOTHER GAME (YES = 1, NO = 0)"; + 320 INPUT A + 330 IF A = 1 THEN 140 + 340 PRINT "THANKS FOR PLAYING" + 350 END + diff --git a/ohmslaw.bas b/ohmslaw.bas new file mode 100644 index 0000000..ac86ff7 --- /dev/null +++ b/ohmslaw.bas @@ -0,0 +1,311 @@ +5 REM - COMPACTED:6/08/84 +7 REM - Removed LPRINT references 4-13-2020 Ken +10 PRINT " -=*OHM'S LAW*=-" +40 PRINT " MENU" +50 PRINT:PRINT TAB(10);"(1) Find I, given VOLTAGE and RESISTANCE (E and R)" +70 PRINT TAB(10);"(2) Find R, given VOLTAGE and CURRENT (V and I)" +90 PRINT TAB(10);"(3) Find E, given CURRENT and RESISTANCE (I and R)" +110 PRINT TAB(10);"(4) Find P (POWER), given VOLTAGE and CURRENT (E and I)" +130 PRINT TAB(10);"(5) Find P (POWER), given CURRENT and RESISTANCE (I and R)" +150 PRINT TAB(10);"(6) Find P (POWER), given VOLTAGE and RESISTANCE (E and R)" +170 PRINT TAB(10);"(7) Find two resistances in parallel, given R1 and R2" +190 PRINT TAB(10);"(8) Find RT, given unequal R1, R2, R3, R4 in parallel" +270 PRINT TAB(10);"(9) Find RT, given R1,R2,R3,R4 in SERIES-PARALLEL" +290 PRINT TAB(10);"(10) Find TOTAL CAPACITANCE (CT), in series circuit" +310 PRINT TAB(10);"(11) Find TOTAL CAPACITANCE (CT), 2 caps, parallel circuit" +330 PRINT TAB(10);"(12) Find TOTAL CAPACITANCE (CT), 3 caps in parallel" +350 PRINT TAB(10);"(13) Find PEAK AC VOLTAGE, given RMS value" +370 PRINT TAB(10);"(14) Find RMS VOLTAGE, given PEAK value" +390 PRINT TAB(10);"(15) Find INDUCTIVE REACTANCE (XL)" +410 PRINT TAB(10);"(16) Find CAPACITIVE REACTANCE (XC)" +430 PRINT TAB(10);"(17) Find IMPEDANCE (Z) of a series circuit" +445 PRINT TAB(10);"(18) Find IMPEDANCE (Z) of a parallel circuit" +447 PRINT +450 PRINT " Select the number you require from the menu and press 'RETURN'" +485 PRINT +490 INPUT "Caps Lock ON. Enter choice from above or -1 to exit :",C +515 IF C = -1 THEN END +517 PRINT "Choice is:";C +520 IF C= 0 OR C> 18 THEN 10 +530 ON C GOTO 540,710,880,1050,1220,1380,1540,1700,1930,2190,2360,2560,2770,2930,3070,3260,3430,3680 +540 PRINT "Calculate CURRENT (I), given VOLTAGE and RESISTANCE (E and R)" +555 PRINT +560 INPUT "What is the value of E, in volts:",V +580 INPUT "Now enter the value of R, in ohms:",R +600 LET I= (V/R) +610 PRINT " I= ";(V/R);"amperes" +630 PRINT +640 PRINT " Do you wish to do this calculation again? (Y/N)":INPUT ANS$ +660 IF ANS$="Y" THEN 540 +670 PRINT "Do you wish to return to the menu? (Y/N)":INPUT ANS$ +690 IF ANS$="Y" THEN 10 +700 GOTO 10020 +710 PRINT "Calculate RESISTANCE (R), given VOLTAGE and CURRENT (E and I)" +730 PRINT:PRINT +740 INPUT "Input the value of E, in volts:",V +760 INPUT "Now enter the value of I, in amperes:",I +780 LET R=(V/I):PRINT "R= ";(V/I);"ohms" +800 PRINT +810 PRINT "Do you wish to do this calculation again? (Y/N)":INPUT ANS$ +830 IF ANS$="Y" THEN 710 +835 PRINT +840 PRINT "Do you wish to return to the menu? (Y/N)":INPUT ANS$ +860 IF ANS$="Y" THEN 10 +870 GOTO 10020 +875 PRINT +880 PRINT "Calculate VOLTAGE (E), given CURRENT and RESISTANCE (I and R)" +895 PRINT +900 INPUT "Enter the value for I, in amperes:",I +920 INPUT "Now enter the value for R, in ohms:",R +940 LET E=(I*R):PRINT "E= ";(I*R);"volts" +960 PRINT +970 PRINT "Do you wish to do this calculation again? (Y/N)":INPUT ANS$ +990 IF ANS$="Y" THEN 880 +995 PRINT +1000 PRINT "Do you wish to return to the menu? (Y/N)":INPUT ANS$ +1020 IF ANS$="Y" THEN 10 +1030 GOTO 10020 +1040 PRINT +1050 PRINT "Calculate POWER(P), given VOLTAGE(E) and CURRENT(I)" +1065 PRINT +1070 INPUT "Input the value for E, in volts:",V +1090 INPUT "Now enter the value for I, in amperes:",I +1110 LET P=V*I:PRINT "I= ";(V*I);"watts" +1130 PRINT +1140 PRINT "Do you wish to do this calculation again? (Y/N)":INPUT ANS$ +1160 IF ANS$="Y" THEN 1050 +1175 PRINT +1180 PRINT "Do you wish to return to the menu? (Y/N)":INPUT ANS$ +1200 IF ANS$="Y" THEN 10 +1210 GOTO 10020 +1220 PRINT "Calculate POWER(P), given CURRENT(I) and RESISTANCE(R)" +1235 PRINT +1240 INPUT "Enter the value for I, in amperes:",I +1260 INPUT "Now enter the value for R, in ohms:",R +1280 LET P=(I*I)*R:PRINT "P= ";(I*I)*R;"watts" +1300 PRINT +1310 PRINT "Do you wish to do this calculation again? (Y/N)":INPUT ANS$ +1330 IF ANS$="Y" THEN 1220 +1335 PRINT +1340 PRINT "Do you wish to return to the menu? (Y/N)":INPUT ANS$ +1360 IF ANS$="Y" THEN 10 +1370 GOTO 10020 +1380 PRINT "Calculate POWER(P), given VOLTAGE(E) and RESISTANCE(R)" +1385 PRINT +1400 INPUT "Enter the value for E, in volts:",V +1420 INPUT "Now enter the value for R, in ohms:",R +1440 LET P=(V*V)/(R):PRINT "P= ";(V*V)/(R);"watts" +1460 PRINT +1470 PRINT "Do you wish to do this calculation again ? (Y/N)":INPUT ANS$ +1490 IF ANS$="Y" THEN 1380 +1495 PRINT +1500 PRINT "Do you wish to return to the menu? (Y/N)":INPUT ANS$ +1520 IF ANS$="Y" THEN 10 +1530 GOTO 10020 +1535 PRINT +1540 PRINT "Calculate TOTAL RESISTANCE(RT) in parallel, given R1,R2" +1555 PRINT +1560 INPUT "Input the value for R1:",R1 +1580 INPUT "Now input the value for R2:",R2 +1600 LET RT= (R1*R2)/(R1+R2):PRINT "RT= ";(R1*R2)/(R1+R2);"ohms" +1620 PRINT +1630 PRINT "Do you wish to do this calculation again? (Y/N)":INPUT ANS$ +1650 IF ANS$="Y" THEN 1540 +1655 PRINT +1660 PRINT "Do you wish to return to the menu? (Y/N)":INPUT ANS$ +1680 IF ANS$="Y" THEN 10 +1690 GOTO 10020 +1695 PRINT +1700 PRINT "Calculate TOTAL RESISTANCE(RT), given unequal R1,R2,R3,R4 values" +1715 PRINT +1720 PRINT "Enter the values for R1,R2,R3 and R4, in ohms" +1740 INPUT "R1=",R1 +1750 INPUT "R2=",R2 +1760 INPUT "R3=",R3 +1770 INPUT "R4=",R4 +1780 PRINT "R1=";R1;"ohms" +1790 PRINT "R2=";R2;"ohms" +1800 PRINT "R3=";R3;"ohms" +1810 PRINT "R4=";R4;"ohms" +1820 LET RT=(1)/(1/R1+1/R2+1/R3+1/R4) +1830 PRINT "RT= ";(1)/(1/R1+1/R2+1/R3+1/R4);"ohms" +1850 PRINT +1860 PRINT "Do you wish to do this calculation again? (Y/N)":INPUT ANS$ +1880 IF ANS$="Y" THEN 1700 +1885 PRINT +1890 PRINT "Do you wish to return to the menu? (Y/N)":INPUT ANS$ +1910 IF ANS$="Y" THEN 10 +1920 GOTO 10020 +1925 PRINT +1930 PRINT "Calculate TOTAL RESISTANCE(RT), in series-parallel," +1940 PRINT "given R1, R2, R3 and R4" +1965 PRINT +1970 PRINT "Enter the values for R1, R2, R3 and R4" +1990 INPUT "R1=",R1 +2000 INPUT "R2=",R2 +2010 INPUT "R3=",R3 +2020 INPUT "R4=",R4 +2030 PRINT "R1=";R1;"ohms" +2040 PRINT "R2=";R2;"ohms" +2050 PRINT "R3=";R3;"ohms" +2060 PRINT "R4=";R4;"ohms" +2070 PRINT +2080 LET RT=(1)/(1/(R1+R2))+(1/(R3+R4)) +2090 PRINT "RT=";(1)/(1/(R1+R2))+(1/(R3+R4));"ohms" +2110 PRINT +2120 PRINT "Do you wish to do this calculation again? (Y/N)":INPUT ANS$ +2140 IF ANS$="Y" THEN 1930 +2145 PRINT +2150 PRINT "Do you wish to return to the menu? (Y/N)":INPUT ANS$ +2170 IF ANS$="Y" THEN 10 +2180 GOTO 10020 +2185 PRINT +2190 PRINT "Calculate TOTAL CAPACITANCE(CT), in series circuit, given C1 and C2" +2205 PRINT +2210 INPUT "Enter value for C1, in MFD:",C1 +2220 INPUT "Now enter the value for C2, in MFD:",C2 +2240 PRINT "C1=";C1;"mfd" +2250 PRINT "C2=";C2;"mfd" +2260 LET CT=(C1*C2)/(C1+C2):PRINT "CT=";(C1*C2)/(C1+C2);"mfd" +2280 PRINT +2290 PRINT "Do you wish to do this calculation again? (Y/N)":INPUT ANS$ +2310 IF ANS$="Y" THEN 2190 +2315 PRINT +2320 PRINT "Do you wish to return to the menu? (Y/N)":INPUT ANS$ +2340 IF ANS$="Y" THEN 10 +2350 GOTO 10020 +2355 PRINT +2360 PRINT "Calculate TOTAL CAPACITANCE(CT), parallel circuit, given C1 and C2" +2395 PRINT +2400 INPUT "Enter the value for C1, in mfd:",C1 +2420 INPUT "Now enter the value for C2, in mfd:",C2 +2440 PRINT "C1=";C1;"mfd" +2450 PRINT "C2=";C2;"mfd" +2460 LET CT=(C1*C2)/(C1+C2):PRINT "CT=";(C1*C2)/(C1+C2);"mfd" +2480 PRINT +2490 PRINT "Do you wish to do this calculation again? (Y/N)":INPUT ANS$ +2510 IF ANS$="Y" THEN 2360 +2515 PRINT +2520 PRINT "Do you wish to return to the menu? (Y/N)":INPUT ANS$ +2540 IF ANS$="Y" THEN 10 +2550 GOTO 10020 +2555 PRINT +2560 PRINT "Calculate TOTAL CAPACITANCE(CT) for a parallel circuit," +2570 PRINT "given C1, C2 and C3, in mfd" +2595 PRINT +2600 INPUT "C1=",C1 +2610 INPUT "C2=",C2 +2620 INPUT "C3=",C3 +2630 PRINT "C1=";C1;"mfd" +2640 PRINT "C2=";C2;"mfd" +2650 PRINT "C3=";C3;"mfd" +2660 PRINT +2670 LET CT=(C1+C2+C3):PRINT "CT=";(C1+C2+C3);"mfd" +2690 PRINT +2700 PRINT "D0 you wish to do this calculation again? (Y/N)":INPUT ANS$ +2720 IF ANS$="Y" THEN 2560 +2725 PRINT +2730 PRINT "Do you wish to return to the menu? (Y/N)":INPUT ANS$ +2750 IF ANS$="Y" THEN 10 +2760 GOTO 10020 +2765 PRINT +2770 PRINT "Calculate PEAK AC VOLTAGE, given RMS value" +2785 PRINT +2790 INPUT "Enter the RMS value, in volts:",RMS +2810 PRINT "RMS=";RMS;"volts" +2820 LET PEAK=(RMS*1.414):PRINT "PEAK=";(RMS*1.414);"volts" +2840 PRINT +2850 PRINT "Do you wish to do this calculation again? (Y/N)":INPUT ANS$ +2870 IF ANS$="Y" THEN 2770 +2875 PRINT +2880 PRINT "Do you wish to return to the menu? (Y/N)":INPUT ANS$ +2900 IF ANS$="Y" THEN 10 +2910 GOTO 10020 +2920 PRINT +2930 PRINT "Calculate RMS VOLTAGE, given a value in PEAK VOLTS" +2945 PRINT +2950 INPUT "Enter the PEAK value, in volts AC:",PEAK +2960 PRINT "PEAK VOLTS=";PEAK +2970 LET RMS=(.707*PEAK):PRINT "RMS=";(.707*PEAK);"volts AC" +3000 PRINT "Do you wish to do this calculation again? (Y/N)":INPUT ANS$ +3020 IF ANS$="Y" THEN 2930 +3025 PRINT +3030 PRINT "Do you wish to return to the menu? (Y/N)":INPUT ANS$ +3050 IF ANS$="Y" THEN 10 +3060 GOTO 10020 +3065 PRINT +3070 PRINT "Calculate INDUCTIVE REACTANCE (XL), given FREQUENCY and INDUCTANCE" +3090 PRINT +3100 INPUT "Enter FREQUENCY (F), in Hertz:",FREQ +3120 PRINT "FREQUENCY=";FREQ;"Hertz +3130 INPUT "Now enter the value for INDUCTANCE (L), in henrys:",L +3150 PRINT "INDUCTANCE=";L;"henrys" +3160 LET XL=(2*3.1416)*FREQ*L:PRINT "XL=";(2*3.1416)*FREQ*L;"ohms" +3180 PRINT +3190 PRINT "Do you wish to do this calculation again? (Y/N)":INPUT ANS$ +3210 IF ANS$="Y" THEN 3070 +3215 PRINT +3220 PRINT "Do you wish to return to the menu? (Y/N)":INPUT ANS$ +3240 IF ANS$="Y" THEN 10 +3245 GOTO 10020 +3250 PRINT +3260 PRINT "Calculate CAPACITIVE REACTANCE (XC), given FREQ(F) and CAP(C)" +3275 PRINT +3280 INPUT "Enter the value for FREQ(F), in Hertz:",F +3290 PRINT "FREQ(F)=";F;"Hertz" +3300 INPUT "Now enter the value for CAP(C), in mfd:",C +3310 PRINT "CAP(C)=";C;"mfd" +3320 PRINT +3330 LET XC=(1)/((2*3.1416)*F*C):PRINT "XC=";(1)/((2*3.1416)*F*C);"ohms" +3350 PRINT +3360 PRINT "Do you wish to do this calculation again? (Y/N)":INPUT ANS$ +3380 IF ANS$="Y" THEN 3260 +3385 PRINT +3390 PRINT "Do you wish to return to the menu? (Y/N)":INPUT ANS$ +3410 IF ANS$="Y" THEN 10 +3415 GOTO 10020 +3420 PRINT +3430 PRINT "Calculate IMPEDANCE(Z) of a series circuit, given values of" +3435 PRINT "RES(R), CAPACITIVE REACTANCE(XC) and INDUCTIVE REACTANCE(XL)" +3446 PRINT +3450 INPUT "Enter the value for RESISTANCE(R), in ohms:",R +3470 INPUT "Enter the value for CAPACITIVE REACTANCE(XC), in ohms:",XC +3490 INPUT "Enter the value for INDUCTIVE REACTANCE(XL), in ohms:",XL +3510 PRINT +3520 PRINT "RESISTANCE(R)=";R;"ohms" +3530 PRINT "CAPACITIVE REACTANCE(XC)=";XC;"ohms" +3540 PRINT "INDUCTIVE REACTANCE(XL)=";XL;"ohms" +3550 PRINT +3560 LET Z=SQR(R^2+((XL-XC)^2)) +3570 PRINT "IMPEDANCE(Z)=";SQR(R^2+((XL-XC)^2));"ohms" +3590 PRINT +3600 PRINT "Do you wish to do this calculation again? (Y/N)":INPUT ANS$ +3620 IF ANS$="Y" THEN 3430 +3625 PRINT +3630 PRINT "Do you wish to return to the menu? (Y/N)":INPUT ANS$ +3650 IF ANS$="Y" THEN 10 +3660 GOTO 10020 +3670 PRINT +3680 PRINT "Calculate IMPEDANCE (Z) of a parallel circuit" +3700 PRINT +3710 INPUT "Enter the value of L, in henrys:",L +3730 INPUT "Enter the value for FREQ (F), in Hertz:",F +3750 INPUT "Now enter the value for RESISTANCE (R) in ohms:",R +3765 PRINT "INDUCTANCE (L)=";L;"henrys" +3770 PRINT "FREQ (F)=";F;" Hertz" +3775 PRINT "RESISTANCE (R)=";R;"ohms" +3776 PRINT +3780 LET Z=((2*3.1416*F*L)^2)/(R) +3790 PRINT "IMPEDANCE (Z)=";((2*3.1416*F*L)^2)/(R);"ohms" +3810 PRINT "Do you wish to do this calculation again? (Y/N)":INPUT ANS$ +3830 IF ANS$="Y" THEN 3680 +3840 PRINT +3850 PRINT "Do you wish to return to the menu? (Y/N)":INPUT ANS$ +3870 IF ANS$="Y" THEN 10 +3880 GOTO 10020 +3890 PRINT +10020 PRINT "Glad to have been of service! BYE!! +12000 REM -------------------------------------------------------------------------- +12010 REM Change line number 0 to line number 5 +12020 REM For automated testing, added 515 IF C = -1 THEN END +12999 END diff --git a/profile.bas b/profile.bas deleted file mode 100644 index 88c07bb..0000000 --- a/profile.bas +++ /dev/null @@ -1 +0,0 @@ -option version "bywater" diff --git a/renum.c b/renum.c index bb34a9c..4e1a8e7 100644 --- a/renum.c +++ b/renum.c @@ -3,6 +3,10 @@ /* Originally written in HP 2000 BASIC by David Lance Robinson, 1977 */ /* Adapted to MS BASIC and translated to C 4/1995 by Jon B. Volkoff */ /* (eidetics@cerf.net) */ +/* */ +/* Some changes 04-2020 Ken. Re cp or copy and input terminator */ +/* when compiling under DOS use -DMSDOS */ +/* And fgets under Ubuntu. */ /*-------------------------------------------------------------------*/ #include @@ -15,10 +19,12 @@ int instr(); char *midstr1(); char *midstr2(); +char *myfget; void binary_search(void); int f2, l2, n, x; int sidx[MAX_LINE_COUNT][2]; +int myretn; char rstr[MAX_LINE_LENGTH]; int main(argc, argv) @@ -39,16 +45,16 @@ int main(argc, argv) f = 1; - printf("Version 12/13/2019\n"); + printf("Version 04/30/2020\n"); if (argc > 1) strcpy(pstr, argv[1]); else { printf("Program in file? "); - fgets(pstr,MAX_LINE_LENGTH, stdin); + myfget=fgets(pstr,MAX_LINE_LENGTH, stdin); if (strchr(pstr, '\n') != NULL) { - pstr[strlen(pstr)-1] = '\0'; + pstr[strlen(pstr)-1] = '\0'; /* NULL terminate input. Ken */ } } @@ -69,6 +75,7 @@ int main(argc, argv) #endif fdout = fopen(pstr, "w"); + /* After editfl is created it is left behind. Ken */ if (fdout == NULL) { printf("Unable to open temporary file editfl for output\n"); @@ -95,7 +102,7 @@ int main(argc, argv) } else { - printf("Too many lines\n"); + printf("Too many lines. Over %d\n",MAX_LINE_COUNT); exit(1); } sidx[s][0] = n; @@ -120,14 +127,15 @@ int main(argc, argv) } fclose(fdin); - strcpy(pstr, ""); - if (s == 0) { + printf("Programs must start with a number in column 1\n"); printf("NO PROGRAM IS IN THE FILE!\n"); exit(1); } + strcpy(pstr, ""); + for (l = 1; l <= s; l++) sidx[l][1] = sidx[l][0]; g = 1; @@ -150,7 +158,7 @@ int main(argc, argv) skip = 0; bp = 0; printf("RENUMBER-"); - fgets(pstr,MAX_LINE_LENGTH,stdin); + myfget=fgets(pstr,MAX_LINE_LENGTH,stdin); p = strlen(pstr); if (g == 0) @@ -297,9 +305,9 @@ int main(argc, argv) */ printf("VERIFY? N or n cancels:"); - fgets(pstr,MAX_LINE_LENGTH,stdin); + myfget=fgets(pstr,MAX_LINE_LENGTH,stdin); v1 = 0; - if (strcmp(midstr2(pstr, 1, 1), "N") == 0) v1 = 1; + if (strcmp(midstr2(pstr, 1, 1), "N") == 0) v1 = 1; /* Except n or N. Ken */ if (strcmp(midstr2(pstr, 1, 1), "n") == 0) v1 = 1; if (v1 == 1) { @@ -374,6 +382,7 @@ int main(argc, argv) } if (skip == 0) b1 = strlen(pstr); + /* GOSub , GOTo , IF. Ken */ t = instr("GOSGOTIF ON RESRET", midstr2(pstr, b, 3)); temp = (t + 5)/3; @@ -508,15 +517,16 @@ int main(argc, argv) fclose(fdin); fclose(fdout); +/* 11-2019 Ken */ #if !defined(__MVS__) && !defined(__CMS__) && !defined(MSDOS) tempstr[strlen(tempstr)] = '\0'; - sprintf(tempstr, "cp editfl %s", f9str); - system(tempstr); + sprintf(tempstr, "cp editfl %s", f9str); /* Linux type systems use cp. Ken */ + myretn=system(tempstr); #endif #if defined(MSDOS) tempstr[strlen(tempstr)] = '\0'; - sprintf(tempstr, "copy editfl %s", f9str); - system(tempstr); + sprintf(tempstr, "copy editfl %s", f9str); /* MSDOS no cp command. Ken */ + myretn=system(tempstr); #endif return (0); diff --git a/res b/res new file mode 100755 index 0000000..60a97a9 --- /dev/null +++ b/res @@ -0,0 +1,17 @@ +#!/bin/bash +# 4-2020 Ken +# Draw current set rows and columns to see if it's as expected +# +clear +row=0 ; rowc=0 ; col=0 ; colc=0 ; ccnt=0 +row=`stty -a | cut -d" " -f5 | sed -e "1s/;//p" -e "1,\\$d"` +col=`stty -a | cut -d" " -f7 | sed -e "1s/;//p" -e "1,\\$d"` +rowc=`expr $row - 2` ; colc=`expr $col - 1` +seq $rowc +while [ $ccnt -lt $colc ] + do + echo -n "x" + ccnt=`expr $ccnt + 1` + done +echo "#" + diff --git a/res.bas b/res.bas deleted file mode 100644 index c620f70..0000000 --- a/res.bas +++ /dev/null @@ -1,7 +0,0 @@ - 100 for j = 1 to 22 - 200 print j - 300 next j - 400 for j = 1 to 80 - 500 print "I"; - 600 next j - diff --git a/rmvspcs b/rmvspcs new file mode 100755 index 0000000..c2375ec --- /dev/null +++ b/rmvspcs @@ -0,0 +1,24 @@ +#!/bin/bash +# 4-2020 Ken +echo "Input file to clean leading spaces " +read infile +if [ -r $infile ] +then + echo "Wait, copying original input file to $infile.cpy" + cp $infile $infile.cpy +else + echo "Input file is unreadable" + exit 1 +fi +# Sucessively delete leading spaces +ed $infile <0 THEN 103 + 102 SS(5)=-1 + : GOTO 195 + 103 IF SS(5)<>1 THEN 106 + 104 IF SS(1)<>0 THEN 110 + 105 SS(1)=-1 + : GOTO 195 + 106 IF SS(2)=1 AND SS(1)=0 THEN 181 + 107 IF SS(4)=1 AND SS(1)=0 THEN 181 + 108 IF SS(6)=1 AND SS(9)=0 THEN 189 + 109 IF SS(8)=1 AND SS(9)=0 THEN 189 + 110 IF G=1 THEN 112 + 111 GOTO 118 + 112 J=3*INT((M-1)/3)+1 + 113 IF 3*INT((M-1)/3)+1=M THEN + : K=1 + : END IF + 114 IF 3*INT((M-1)/3)+2=M THEN + : K=2 + : END IF + 115 IF 3*INT((M-1)/3)+3=M THEN + : K=3 + : END IF + 116 GOTO 120 + 118 FOR J=1 TO 7 STEP 3 + : FOR K=1 TO 3 + 120 IF SS(J)<>G THEN 130 + 122 IF SS(J+2)<>G THEN 135 + 126 IF SS(J+1)<>0 THEN 150 + 128 SS(J+1)=-1 + : GOTO 195 + 130 IF SS(J)=H THEN 150 + 131 IF SS(J+2)<>G THEN 150 + 132 IF SS(J+1)<>G THEN 150 + 133 SS(J)=-1 + : GOTO 195 + 135 IF SS(J+2)<>0 THEN 150 + 136 IF SS(J+1)<>G THEN 150 + 138 SS(J+2)=-1 + : GOTO 195 + 150 IF SS(K)<>G THEN 160 + 152 IF SS(K+6)<>G THEN 165 + 156 IF SS(K+3)<>0 THEN 170 + 158 SS(K+3)=-1 + : GOTO 195 + 160 IF SS(K)=H THEN 170 + 161 IF SS(K+6)<>G THEN 170 + 162 IF SS(K+3)<>G THEN 170 + 163 SS(K)=-1 + : GOTO 195 + 165 IF SS(K+6)<>0 THEN 170 + 166 IF SS(K+3)<>G THEN 170 + 168 SS(K+6)=-1 + : GOTO 195 + 170 GOTO 450 + 171 IF SS(3)=G AND SS(7)=0 THEN 187 + 172 IF SS(9)=G AND SS(1)=0 THEN 181 + 173 IF SS(7)=G AND SS(3)=0 THEN 183 + 174 IF SS(9)=0 AND SS(1)=G THEN 189 + 175 IF G=-1 THEN + : G=1 + : H=-1 + : GOTO 110 + : END IF + 176 IF SS(9)=1 AND SS(3)=0 THEN 182 + 177 FOR I=2 TO 9 + : IF SS(I)<>0 THEN 179 + 178 SS(I)=-1 + : GOTO 195 + 179 NEXT I + 181 SS(1)=-1 + : GOTO 195 + 182 IF SS(1)=1 THEN 177 + 183 SS(3)=-1 + : GOTO 195 + 187 SS(7)=-1 + : GOTO 195 + 189 SS(9)=-1 + 195 PRINT + : PRINT"THE COMPUTER MOVES TO..." + 202 GOSUB 1000 + 205 GOTO 500 + 450 IF G=1 THEN 465 + 455 IF J=7 AND K=3 THEN 465 + 460 NEXT K + : NEXT J + 465 IF SS(5)=G THEN 171 + 467 GOTO 175 + 475 P$="X" + : Q$="O" + 500 PRINT + : INPUT"WHERE DO YOU MOVE";M + 502 IF M=0 THEN + : PRINT"THANKS FOR THE GAME." + : GOTO 2000 + : END IF + 503 IF M>9 THEN 506 + 505 IF SS(M)=0 THEN 510 + 506 PRINT"THAT SQUARE IS OCCUPIED." + : PRINT + : PRINT + : GOTO 500 + 510 G=1 + : SS(M)=1 + 520 GOSUB 1000 + 530 GOTO 100 + 1000 PRINT + : FOR I=1 TO 9 + : PRINT" "; + : IF SS(I)<>-1 THEN 1014 + 1012 PRINT Q$;" "; + : GOTO 1020 + 1014 IF SS(I)<>0 THEN 1018 + 1016 PRINT" "; + : GOTO 1020 + 1018 PRINT P$;" "; + 1020 IF I<>3 AND I<>6 THEN 1050 + 1030 PRINT + : PRINT"---+---+---" + 1040 GOTO 1080 + 1050 IF I=9 THEN 1080 + 1060 PRINT"!"; + 1080 NEXT I + : PRINT + : PRINT + : PRINT + 1095 FOR I=1 TO 7 STEP 3 + 1100 IF SS(I)<>SS(I+1)THEN 1115 + 1105 IF SS(I)<>SS(I+2)THEN 1115 + 1110 IF SS(I)=-1 THEN 1350 + 1112 IF SS(I)=1 THEN 1200 + 1115 NEXT I + : FOR I=1 TO 3 + : IF SS(I)<>SS(I+3)THEN 1150 + 1130 IF SS(I)<>SS(I+6)THEN 1150 + 1135 IF SS(I)=-1 THEN 1350 + 1137 IF SS(I)=1 THEN 1200 + 1150 NEXT I + : FOR I=1 TO 9 + : IF SS(I)=0 THEN 1155 + 1152 NEXT I + : GOTO 1400 + 1155 IF SS(5)<>G THEN 1170 + 1160 IF SS(1)=G AND SS(9)=G THEN 1180 + 1165 IF SS(3)=G AND SS(7)=G THEN 1180 + 1170 RETURN + 1180 IF G=-1 THEN 1350 + 1200 PRINT"YOU BEAT ME!! GOOD GAME." + : GOTO 2000 + 1350 PRINT"I WIN, TURKEY!!!" + : GOTO 2000 + 1400 PRINT"IT'S A DRAW. THANK YOU." + 2000 END +