Page 1 of 3

Express BASIC - an interpreter in C

Posted: Tue Oct 17, 2023 5:56 am
by admin
Different computer, same program

Express BASIC is a minimal BASIC dialect that is suitable for performing complex calculations. The language is inspired by Dartmouth, Palo Alto, Altair, GW BASIC, and the many dialects of Tiny BASIC.

It is written in C and is open source. I have been working nonstop on this and am finally at a point I am comfortable sharing it. The syntax is very close to Net Basic. Most programs written in Express BASIC will run in QBasic or GWBasic with little modification.

Programs may be typed directly, loaded with LOAD "filename.bas", saved with SAVE "filename.bas", cleared with NEW, listed with LIST, etc. You may pass source files through the command line, drag and drop, or association.

The interpreter features a classic style line mode editor and will run on all versions of Windows 95 and up. There's just enough commands and functions to be useful. My goal is for this language to be standard and minimal. I don't want to get crazy with the syntax like with Craft Basic and Commando Basic. This will be my "normal" BASIC along side Net Basic.

So, with Net Basic being written in PHP and Express BASIC in C, I think this will be the last language I will make for a long time hopefully.

Get it here: https://lucidapogee.com/index.php?page=expressbasic

Here's a few examples...

Code: Select all

10 REM ROCKET.BAS by Brian Tung
20 REM Modified to work with Express Basic
30 LET a = 1.032
40 LET d = 1
50 PRINT "Earth gravity in light-years per year squared: "; a
55 PRINT "Distance in light-years (0-100 million): "; d
60 IF d >= 0 AND d <= 100000000 THEN 80
70 PRINT "Distance must be between 0 and 100 million l-y"
75 END
80 LET d1 = d / 2
90 LET t = SQR(d1 * d1 + (2 * d1 / a))
100 LET x = a * t
110 LET m = 1
120 IF x >= 0 THEN 130
125 LET m = -1
130 LET s = LOG(ABS(x) + 1)
140 LET s1 = s + 1
150 LET x1 = (EXP(s) - EXP(s * -1)) / 2 - ABS(x)
160 LET s1 = x1 / (EXP(s) + EXP(s * -1)) / 2
170 LET s = s - s1
180 IF ABS(s1) > .0000001 THEN 150
190 LET t1 = 1 / a * s * m
200 LET v = a * t / SQR(1 + (a * t) * (a * t))
210 PRINT "Time on Earth: "; 2 * t; " years"
220 PRINT "Time on board: "; 2 * t1; " years"
230 SHELL "pause"

Code: Select all

1 REM MODIFIED TO WORK WITH EXPRESS BASIC
10 PRINT "HURKLE"
20 PRINT "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY"
30 PRINT
110 LET N=5
120 LET G=10
210 PRINT
220 PRINT "A HURKLE IS HIDING ON A ";G;" BY ";G;" GRID. HOMEBASE"
230 PRINT "ON THE GRID IS POINT 0,0 IN THE SOUTHWEST CORNER,"
235 PRINT "AND ANY POINT ON THE GRID IS DESIGNATED BY A"
240 PRINT "PAIR OF WHOLE NUMBERS. THE FIRST NUMBER IS"
245 PRINT "THE HORIZONTAL POSITION AND THE SECOND NUMBER"
246 PRINT "IS THE VERTICAL POSITION. YOU MUST TRY TO"
250 PRINT "GUESS THE HURKLE'S GRIDPOINT. YOU GET ";N;" TRIES."
260 PRINT "AFTER EACH TRY, I WILL TELL YOU THE APPROXIMATE"
270 PRINT "DIRECTION TO GO TO LOOK FOR THE HURKLE."
280 PRINT
285 LET A=INT(G*RND)
286 LET B=INT(G*RND)
290 LET K = 0
310 LET K = K + 1
320 PRINT "GUESS #";K
330 INPUT "X: ", X
335 INPUT "Y: ", Y
340 IF ABS(X-A)+ABS(Y-B)=0 THEN 500
350 REM PRINT INFO
360 GOSUB 610
370 PRINT
380 IF K <= N THEN 310
410 PRINT
420 PRINT "SORRY, THAT'S ";N;" GUESSES."
430 PRINT "THE HURKLE IS AT ";A;",";B
440 PRINT
450 PRINT "LET'S PLAY AGAIN, HURKLE IS HIDING."
460 PRINT
470 GOTO 285
500 REM
510 PRINT
520 PRINT "YOU FOUND HIM IN ";K;" GUESSES!"
540 GOTO 440
610 PRINT "GO ";
620 IF Y=B THEN 670
630 IF Y<B THEN 660
640 PRINT "SOUTH";
650 GOTO 670
660 PRINT "NORTH";
670 IF X=A THEN 720
680 IF X<A THEN 710
690 PRINT "WEST";
700 GOTO 720
710 PRINT "EAST";
720 PRINT
730 RETURN
999 END

Code: Select all

1 REM https://rosettacode.org/wiki/Attractive_numbers
10 FOR x = 1 TO 120
20 LET n = x
30 LET c = 0
40 IF n MOD 2 <> 0 THEN 70
50 LET n = INT(n / 2)
60 LET c = c + 1
70 IF n MOD 2 = 0 THEN 40
80 FOR i = 3 TO SQR(n) STEP 2
90 IF n MOD i <> 0 THEN 120
100 LET n = INT(n / i)
110 LET c = c + 1
120 IF n MOD i = 0 THEN 90
130 NEXT i
140 IF n <= 2 THEN 160
150 LET c = c + 1
160 IF NOT(PRIME(c)) THEN 180
170 PRINT x,
180 NEXT x
190 PRINT
200 SHELL "pause"

Code: Select all

1 REM https://rosettacode.org/wiki/Golden_ratio/Convergence
5 PRECISION 6
10 LET phi0 = 1
20 LET phi1 = 1 / phi0 + 1
30 LET d = ABS(phi1 - phi0)
40 LET phi0 = phi1
50 LET i = i + 1
60 IF d >= .00001 THEN 20
70 PRINT "result: "; phi1; " after "; i; " iterations"
80 PRINT "the error is approximately "; phi1 - (.5 * (1 + SQR(5)))
90 SHELL "pause"

Code: Select all

1 REM https://rosettacode.org/wiki/Nth_root
5 PRECISION 6
10 LET a = INT(RND * 5999) + 2
20 PRINT "nth root of "; a; "..."
30 FOR n = 1 TO 10
40 LET p = .00001
50 LET x = a
60 LET y = a / n
70 IF ABS(x - y) <= p THEN 110
80 LET x = y
90 LET y = ((n - 1) * y + a / y ^ (n - 1)) / n
100 IF ABS(x - y) > p THEN 80
110 PRINT n; " : "; y
120 NEXT n
130 SHELL "pause"

Re: Express BASIC - an interpreter in C

Posted: Tue Oct 24, 2023 7:10 pm
by admin
I have been working on trying to implement graphics and have had no luck with libraries. Ended up borrowing more BCX routines. Amazingly, you can draw to the console directly! Wow!

There's now two versions of Express Basic. Minimal and Extended Editions. The minimal contains no Windows features and should be easy enough to port to Linux while the Extended Edition depends on Windows for graphics commands.

Links on the download page are updated for the Minimal and Extended Editions.

New features in the extended edition include:

Code: Select all

PSET (x, y)
LINE (x1, y1)-(x2, y2)
CIRCLE (x, y), radius
COLOR doscolors
RGB red, green, blue
WAV "sync:filename.wav"
PSET only accepts x and y parameters.
LINE only accepts x1, y1, x2, and y2.
CIRCLE only accepts x, y, and radius
COLOR accepts 0-15
RGB accepts 0-255 for rgb values.
Expressions may be used anywhere in these commands. This includes expressions with ()-(). For example, LINE ((150/2)-(3*2),(14*5)-(6+7))-((123-44)-(5-66),(42*7)-(66+45)) will draw the same line in QBasic and Express BASIC without modification. I went out of my way to require the extra weird syntax with the ()-().
PSET and CIRCLE are similar.
WAV requires sync: or async: in the quotes to the left of the filename. I thought this was a quick and dirty solution.

The Minimal Edition does not have the following commands: ALERT, LOCATE, PSET, LINE, CIRCLE, COLOR, RGB, WAV, SOUND

I changed the TIMER and MILLISECS function to use clock() instead of GetSystemTime(). This removes the windows.h dependency from both editions for randomization seeding, TIMER, and MILLISECS. For timer, I am just using clock()/1000. Millisecs is clock(). The big difference is that now the count is from when the program starts. For the random seeding, I am using time(NULL).

I also fixed a little issue with LOCATE. It was expecting 0, 0 as the top left. Now it accepts 1, 1 like QBasic.

Here's some of the graphics examples included with the Extended Edition:

Code: Select all

1 REM https://rosettacode.org/wiki/Draw_a_sphere
5 CLS
10 LET j = 2
20 FOR i = 51 TO 0 STEP j * -1
30 FOR k = PI * -1 TO PI STEP .05
40 PSET (51 + i * sin(k), 52 + 51 * cos(k))
50 PSET (51 + 51 * sin(k), 52 + (i - 1) * cos(k))
60 NEXT k
70 LET j = j + 1
80 NEXT i
90 SHELL "pause"
Image

Code: Select all

1 REM https://rosettacode.org/wiki/Barnsley_fern
2 CLS
5 COLOR 10
10 FOR i = 1 TO 10000
20 LET r = RND
30 IF NOT(r > 0 AND r < .01) THEN 60
40 LET x = .0
50 LET y = .16 * y
60 IF NOT(r > .01 AND r < .08) THEN 90
70 LET x = .22 * x - .26 * y
80 LET y = -.23 * x + .22 * y + 1.6
90 IF NOT(r > .075 AND r < .15) THEN 120
100 LET x = .15 * x + .28 * y
110 LET y = -.29 * x + .24 * y + .44
120 LET x = .85 * x + .04 * y
130 LET y = -.04 * x + .85 * y + 1.6
140 LET x1 = (x + 3) * 20
150 LET y1 = 200 - y * 20
160 PSET (x1, y1)
170 NEXT i
180 SHELL "pause"
Image

Code: Select all

1 REM https://rosettacode.org/wiki/Mandelbrot_set
5 CLS
10 LET max = 15
20 LET w = 319
30 LET h = 199
40 LET px = 0
50 LET sy = (py - h / 2) / 150 
60 LET sx = (px - w / 2) / 150
70 LET i = 0
80 LET x = 0
90 LET y = 0
100 LET xy = x * x + y * y
110 LET xx = x * x - y * y + sx + .1
120 LET y = 2 * x * y + sy
130 LET x = xx
140 LET i = i + 1 
150 IF i < max AND xy < 1 THEN 110
160 RGB 220 + i * x, 220 + i * y, 230 + i * xy
170 PSET (px, py)
180 LET px = px + 1
190 IF px < w THEN 50
200 LET py = py + 1
210 IF py < h THEN 40
220 LOCATE 25, 1
230 SHELL "pause"
Image

Code: Select all

1 REM https://rosettacode.org/wiki/Munching_squares
5 CLS
10 LET s = 255
20 FOR y = 0 TO s
30 FOR x = 0 TO s
40 LET r = x XOR y
50 RGB r, r * 2, r * 3
60 PSET (x, y)
70 NEXT x
80 NEXT y
90 LOCATE 25, 1
100 SHELL "pause"
Image

Code: Select all

2 CLS
5 COLOR 15
10 FOR f = 0 TO 1000 STEP .1
20 LET x = x + SIN(f * f)
30 LET y = y + COS(f * f)
40 PSET (x + 200, y + 20)
50 NEXT f
60 SHELL "pause"
Image

Re: Express BASIC - an interpreter in C

Posted: Tue Oct 24, 2023 7:19 pm
by admin
There was a problem with CLS where it was clearing the console text, but not the graphics. I applied a simple "hack" to remedy that for now. This only applies to the extended edition where graphics are used.

The IF statement was missing the ability to use an expression (as opposed to a literal value) as the line number, so I fixed that to be consistent with GOTO and GOSUB.

I added the CHR$() function. This is the only string function and for now, it's solely intended to be used with PRINT. This way you may display double quotes and other special characters.

For example PRINT CHR$(34); "Hello, world!"; CHR$(34)

Re: Express BASIC - an interpreter in C

Posted: Tue Nov 14, 2023 7:47 am
by admin
Until now, the current editions of Express BASIC are compiled with Dev C++. Internally, gcc.
I had no luck getting this to work with Borland, so I tried DJGPP. A port of gcc.

Now there's a DOS and 9x Edition. The only issues are the larger exe size and dependency on DPMI server. I also need to figure out how to bind the DPMI to the application. Even better, maybe remove the dependency if possible.

So far, the DOS and 9x Edition has been tested on DOS 3.0, Free DOS, Windows 95, and Windows XP.

This is all experimental, so everything is subject to change. I plan to update the Edition names later on.

I don't have much time to work on this now. My new job had me 8 days straight and I am going back there tomorrow.

Re: Express BASIC - an interpreter in C

Posted: Mon Nov 20, 2023 5:59 pm
by admin
I made a few minor adjustments to the code of all 3 editions. Mostly just organizing.

Currently looking into implementing peek poke functionality as INP(port) and OUT port, data.

Been working overtime at my new job. Running a small kitchen solo. No lead or team. I have limited time. If you see something wrong or confusing, please let me know! I tend to miss a lot of details.

Re: Express BASIC - an interpreter in C

Posted: Sun Nov 26, 2023 4:37 am
by admin
I figured out how to remove the bind pmode13b DPMI server with eb.exe using exe2coff and copy.
Now Express BASIC DOS and 9x Edition doesn't require a DPMI TSR.
It's just one exe with a readme, source, and examples.

Still looking into implementing INP() and OUT.

Also need to attempt porting to Linux. Much to do.

Express BASIC update!

Posted: Sun Jan 14, 2024 4:24 am
by admin
We are attempting cross platform targeting. This includes Windows 11, Windows XP, Linux, or even the oldest DOS computer with an 8088 processor. Multiple compilers are involved in the development process including Borland Turbo C, Open Watcom, and DJGPP.

The way things are, there's severe memory limitations with the 8088 and DOS Editions. The Linux, Win32, and DPMI Editions do not have as much of a problem due to having access to more memory, but improvement is still needed. Our aim is to improve memory handling with the next update to allow more compatibility between the editions.

The current editions are highly experimental and possibly unstable. If you need a stable edition right now, try the DPMI Edition. DJGPP seems highly stable and the DPMI edition is compiled with it.

From this point on, the objective of Express BASIC is to be cross platform as well as the original goal of having a standard syntax.

There's now five downloads.

The Linux Edition includes an elf file and should work on all x86 distros.
The Win32 Edition works on 95 and up to 11.
The DPMI Edition works with extended memory on machines with 386 and up with DOS up to Windows XP.
The DOS Edition works on DOS and Windows up to XP.
The 8088 Edition works on machines with an 8088 processor (including the Book 8088!! - SLOOOW and LOW MEMORY, but still COOL!!) and up with DOS up to Windows XP.

The project remains in Alpha version for now. We want things to be solid before moving to beta version.
Unfortunately, the graphics commands have been temporarily removed along with some others specific to the previous Windows Edition. We will be looking more into graphics libraries now that Borland and Watcom are able to compile EB.

Express BASIC big update

Posted: Sun Feb 04, 2024 4:40 am
by admin
With the last update, we achieved cross platform compatibility. Now we have better memory handling.

This update makes line numbers independent from the line count. With this, we have combined the 8088 and DOS editions into one. Now the DOS edition may have 2500 line count with virtually unlimited line numbers. The DPMI, Win32, and Linux editions allow for 100k line count with virtually unlimited line numbers, recursion up to million, and a million array elements.

Among other improvements, an error message system has been added.

Express BASIC has been tested on various Linux distros including Tiny Core, Parted Magic, and Xandros.
It has also bewn tested on the Book 8088.

Another Express BASIC update!

Posted: Sun Feb 18, 2024 1:35 am
by admin
This update includes some bug fixes and adjustments. The goal is to make this interpreter work like classic BASIC languages.

The TAB() function has been added. Input now allows for a , or ; with the prompt or no prompt. A ? is displayed for no prompt or a prompt with a ;.

The int function now evaluates as a long int. This fixed an issue with the DOS edition where int(40000 * rnd + 20000) wasn't evaluating correctly.

While testing, I realized that expressions do allow for negation of variables. Previously I thought this wasn't working, but when I double checked the code again it looked fine and sure enough works. So no more writing -1 * var just -var.


New examples have been included to demonstrate compatibility.
A number of classic programs now run with minimal changes.

New examples in this update:

Hamurabi
AceyDucey
BombsAway
Chemist
DepthCharge
FlipFlop
Gunner
Train
Kinema
SineWave
FizzBuzz

Re: Express BASIC - an interpreter in C

Posted: Fri Feb 23, 2024 12:26 pm
by admin
I had to rush out another update as last weeks update introduced another bug with INPUT.
There's also a new error message for undefined line numbers and two new examples.

New examples:
Camel.bas
Father.bas

The Linux Edition is now distributed as a tar.gz archive as opposed to a zip.