News:

Welcome to RetroCoders Community

Main Menu

Net Basic - a BASIC in PHP

Started by Lucidapogee, Sep 02, 2023, 01:38 AM

Previous topic - Next topic

Lucidapogee

Net Basic is a minimal BASIC dialect contained in an online programming environment that is suitable for performing complex calculations on the go.

I started the project earlier this week. It's stable and live. Try it out.

https://lucidapogee.com/netbasic

Now that I have got this off my chest a bit, I may go back to working on fixing errors in Commando Basic, Craft Basic, Tiny Craft Basic, and RPN Calc.

Good times.  8)

CharlieJV


Lucidapogee

It's minimal, but I'm not aware of another PHP BASIC for reference.
I'm hoping it will be useful where devices are internet only.
School or work computers, phones, terminals, etc.

I plan to add arrays, functions, for loops, and more print functionality. Unlike my other languages, I want this language to be as compatible with Dartmouth BASIC and GW BASIC.This way anything written in Net Basic will be directly portable with no fuss.

One thing I am about to do is overload both SQR and SQRT as the square root.

Lucidapogee

#3
I have updated the print command. It now accepts expressions and quoted literal text that may be separated by semicolons or commas. The semicolon combines output with no space. The comma adds 8 non breaking spaces to roughly simulate a tab since displaying tabs is difficult in html. A trailing semicolon causes the next print to output on the same line. A trailing comma does the same, but with the spacing.

My goal was to make this version of Basic more compatible with ISO standards. This way code will copy/paste to/from say Qbasic with even less fuss.

Right now, the only incompatibilities with Qbasic are the RND function returns different values based on the PHP rnd function. NOT(0) operator returns 1 like PHP and Yabasic unlile Qbasic, Freebasic, Craft Basic, etc. For now I made sure AND and OR return -1 on true. The usage of @() for the single one dimensional array is inspired by Palo Alto like Tiny Basic dialects and would need to be replaced with a letter to work in Qbasic.

Lucidapogee

I have updated Net Basic.

The three examples by MikeHawk (http://petesqbsite.com/phpBB3/viewtopic.php?p=39352) have been added.

Based on the issue I described in the post above, I decided to change how the NOT() works for now. Let me know if this is bad.

10 LET i = -10
20 PRINT i, NOT(i)
30 LET i = i + 1
40 IF i < 10 THEN 20

Returns

-10        9
-9        8
-8        7
-7        6
-6        5
-5        4
-4        3
-3        2
-2        1
-1        0
0        -1
1        -2
2        -3
3        -4
4        -5
5        -6
6        -7
7        -8
8        -9
9        -10
Now identical to QBasic.. except for when floating point values are used. I don't know what to do with that. I know the newer languages have a more optimal version of NOT, but I wanted this to be a classic BASIC like language.

This is what I am doing in PHP:
case "!":

			$pointer--;

			//$evalstack[$pointer] = !intval($evalstack[$pointer]);

			if ($evalstack[$pointer] == ""){ 

				$evalstack[$pointer] = "-1";

			}else{

				$evalstack[$pointer] = strval(floatval($evalstack[$pointer]) * -1 - 1);

			}

			$pointer++;

			break;

The commented out line is what I started with.

CharlieJV

Me, I think if you've got it working like QBasic, then all is good.

ZXDunny

I love seeing all these variations in BASIC. Where I come from, NOT n results in 0 if n <> 0, else 1, but that's because there is no integer type so no bits to invert :)

Lucidapogee

Quote from: CharlieJV on Sep 06, 2023, 10:35 PMMe, I think if you've got it working like QBasic, then all is good.

I've got it down to something like Dartmouth BASIC and Tiny BASIC syntax wise, but YaBasic and Just Basic logic wise. I think.

Quote from: ZXDunny on Sep 07, 2023, 08:24 AMI love seeing all these variations in BASIC. Where I come from, NOT n results in 0 if n <> 0, else 1, but that's because there is no integer type so no bits to invert :)
After much fuss I decided to revert everything back to this way.

I tried all sorts of stuff to try making it work like QBasic, but ultimately I decided it was out of the scope of what I am trying to do. I reverted everything to work like YaBasic, Just Basic, and PHP.

1 is true and 0 is false
this applies to all operator and functions

1 and 1 equals 1
not(0) equals 1
not(1) equals 0
etc..

I also had to fix some other issues. Hopefully I didn't create more in the process.

One cool new feature is the HTML command demonstrated in the prime table example. The example generates an html table showing if the numbers 1-1000 are prime or not. The purpose of this example is to demonstrate how to display text in the text output area while also generating an html display properly.

ZXDunny

I prefer 1/0 to -1/0, it makes boolean operations much simpler especially when scaling them. I suspect those old dialects (MS in particular) only used -1 due to their bitwise rather than logical approach.

Of course, using logical AND/OR etc I did have to implement separate bitwise manipulators :)

Lucidapogee

#9
I think I prefer it as well.

This type of thing never hasn't occurred to me in a long time. Making a programming language really
makes us have to think.

There was no way I was going to emulate the old MS bitwise logic. But I tried!


I just added a neat new feature to allow for "compiling" of programs. Basically, a URL is generated containing the encoding of your program. This way it may be shared, linked, bookmarked, iframed, or popped up. The URL appears whenever you RUN a program. Simply copy/paste it wherever.


For example:
1 REM Prime Table
2 PRINT "Generating table of primes below..."
5 HTML
10 PRINT "<center><table><tr>";
20 PRINT "<td style = 'border:1px solid black; background-color:yellow;'>";
30 LET i = i + 1
40 LET b = b + 1
50 PRINT i; ":<br /> "; PRIME(i)
60 PRINT "</td>";
70 IF i = 1000 THEN 120
80 IF b < 20 THEN 110
90 LET b = 0
100 PRINT "</tr><tr>";
110 IF i < 1000 THEN 20
120 PRINT "</tr></table></center>"

generates this url

https://www.lucidapogee.com/netbasic/?listing=1%20REM%20Prime%20Table%0D%0A2%20PRINT%20%22Generating%20table%20of%20primes%20below...%22%0D%0A5%20HTML%0D%0A10%20PRINT%20%22%3Ccenter%3E%3Ctable%3E%3Ctr%3E%22%3B%0D%0A20%20PRINT%20%22%3Ctd%20style%20%3D%20%27border%3A1px%20solid%20black%3B%20background-color%3Ayellow%3B%27%3E%22%3B%0D%0A30%20LET%20i%20%3D%20i%20%2B%201%0D%0A40%20LET%20b%20%3D%20b%20%2B%201%0D%0A50%20PRINT%20i%3B%20%22%3A%3Cbr%20%2F%3E%20%22%3B%20PRIME%28i%29%0D%0A60%20PRINT%20%22%3C%2Ftd%3E%22%3B%0D%0A70%20IF%20i%20%3D%201000%20THEN%20120%0D%0A80%20IF%20b%20%3C%2020%20THEN%20110%0D%0A90%20LET%20b%20%3D%200%0D%0A100%20PRINT%20%22%3C%2Ftr%3E%3Ctr%3E%22%3B%0D%0A110%20IF%20i%20%3C%201000%20THEN%2020%0D%0A120%20PRINT%20%22%3C%2Ftr%3E%3C%2Ftable%3E%3C%2Fcenter%3E%22%0D%0A

Look closely at the URL and you will see encoded BASIC. Click it to run the program. The interpreter decoded and executes these links taking the full page without displaying the editor. The URL is like an executable format for the interpreter.

Remote scripting in BASIC with GET requests... oh yeahhh..

Now you may embed Net Basic apps on any site.  8)

Lucidapogee

And now...

The GET command is an advanced feature intended to be used with URL encoded programs. The command returns the contents of a variable with the same name from the URL. Variable names must be upper case in the URL.

Take this simple program and encode it to a url using the IDE on the Net Basic page.
1 REM USD currency conversion
10 GET u
20 PRINT "$"; u; " USD ="
30 GET e
40 GET g
50 GET i
60 GET j
70 PRINT u * e;  " EUR"
80 PRINT u * g; " GBP"
90 PRINT u * i; " INR"
100 PRINT u * j; " JPY"

Once you get the url, add the variables to the url in upper case. Notice the U=25.99&E=.925881&G=.7924&I=82.628&J=145.96 part.

Here's the URL ready to go.

https://www.lucidapogee.com/netbasic/?U=25.99&E=.925881&G=.7924&I=82.628&J=145.96&listing=1%20REM%20USD%20currency%20conversion%0D%0A10%20GET%20u%0D%0A20%20PRINT%20%22%24%22%3B%20u%3B%20%22%20USD%20%3D%22%0D%0A30%20GET%20e%0D%0A40%20GET%20g%0D%0A50%20GET%20i%0D%0A60%20GET%20j%0D%0A70%20PRINT%20u%20*%20e%3B%20%20%22%20EUR%22%0D%0A80%20PRINT%20u%20*%20g%3B%20%22%20GBP%22%0D%0A90%20PRINT%20u%20*%20i%3B%20%22%20INR%22%0D%0A100%20PRINT%20u%20*%20j%3B%20%22%20JPY%22%0D%0A

When you click the link, you will get exchange rates. Simply modify the GET variables to change the program output.

Lucidapogee

Try saving this form as a .html file and open it with your browser.
You will have a currency conversion app on your screen.

<form action = "https://www.lucidapogee.com/netbasic/" target = "output" method = "get">
<p>
U<br /><input type = "text" name = "U" value = "1"><br />
E<br /><input type = "text" name = "E" value = ".925881"><br />
G<br /><input type = "text" name = "G" value = ".7924"><br />
I<br /><input type = "text" name = "I" value = "82.628"><br />
J<br /><input type = "text" name = "J" value = "145.96">
</p>
<input type = "hidden" name = "listing" value = "1%20REM%20USD%20currency%20conversion%0D%0A10%20GET%20u%0D%0A20%20PRINT%20%22%24%22%3B%20u%3B%20%22%20USD%20%3D%22%0D%0A30%20GET%20e%0D%0A40%20GET%20g%0D%0A50%20GET%20i%0D%0A60%20GET%20j%0D%0A70%20PRINT%20u%20*%20e%3B%20%20%22%20EUR%22%0D%0A80%20PRINT%20u%20*%20g%3B%20%22%20GBP%22%0D%0A90%20PRINT%20u%20*%20i%3B%20%22%20INR%22%0D%0A100%20PRINT%20u%20*%20j%3B%20%22%20JPY%22%0D%0A">
<input type = "submit">
</form>
<iframe name = "output"></iframe>

Lucidapogee

I have added the keywords FOR/TO/STEP/NEXT/BREAK.
They are detailed in the documentation.

Examples are updated to reflect the update.

A few New/updated examples:

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

1 REM https://rosettacode.org/wiki/Nth_root
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

1 REM https://rosettacode.org/wiki/Catalan_numbers
10 LET @(0) = 1
20 FOR n = 0 TO 15
30 LET p = n + 1
40 LET @(p) = 0
50 FOR i = 0 TO n
60 LET q = n - i
70 LET @(p) = @(p) + @(i) * @(q)
80 NEXT i
90 PRINT n; " "; @(n)
100 NEXT n

1 REM https://rosettacode.org/wiki/Prime_decomposition
10 LET loops = 100
20 FOR x = 1 TO loops
30 LET n = x
40 PRINT n; " : ";
50 LET c = 0
60 IF n MOD 2 > 0 THEN 110
70 LET n = INT(n / 2)
80 LET @(c) = 2
90 LET c = c + 1
100 IF n MOD 2 = 0 THEN 70
110 FOR i = 3 TO SQR(n) STEP 2
120 IF n MOD i > 0 THEN 170
130 LET n = INT(n / i)
140 LET @(c) = i
150 LET c = c + 1
160 IF n MOD i = 0 THEN 130
170 NEXT i
180 IF n <= 2 THEN 210
190 LET @(c) = n
200 LET c = c + 1
210 FOR y = 0 TO c
220 IF @(y) = 0 THEN 250
230 PRINT @(y); " ";
240 LET @(y) = 0
250 NEXT y
260 PRINT
270 NEXT x

1 REM Prime Table
10 PRINT "Generating table of primes below..."
20 HTML
30 PRINT "<center><table><tr>"
40 FOR y = 1 TO 50
50 FOR x = 1 TO 20
60 LET i = i + 1
70 PRINT "<td style = 'border:1px solid black; background-color:yellow;'>"
80 PRINT i; ":<br /> "; PRIME(i)
90 PRINT "</td>"
100 NEXT x
110 PRINT "</tr><tr>"
120 NEXT y
130 PRINT "</tr></table></center>"

CharlieJV

 Hey, it looks to me like things are progressing well !

Lucidapogee

Thanks! It's hard to find time between work, so every little improvement is exciting.

I still plan to try adding DEF FNa-z. No plans to add data/read yet.

My inspiration is between Dartmouth, Palo Alto, and maybe Altair. I think it's getting close. Although at this point it is more of a special purpose interpreter for math calculations and making html pages.