Net Basic - a BASIC in PHP

Discuss whatever you want here--both QB and non-QB related. Anything from the DEF INT command to the meaning of life!

Moderators: Pete, Mods

Post Reply
User avatar
bongomeno
Veteran
Posts: 266
Joined: Wed Dec 10, 2008 9:08 am
Location: Arizona
Contact:

Net Basic - a BASIC in PHP

Post by bongomeno »

Image

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
Last edited by bongomeno on Wed Sep 06, 2023 3:38 pm, edited 1 time in total.
MikeHawk
Veteran
Posts: 61
Joined: Sun Jul 08, 2018 11:23 am

Re: Net Basic - a BASIC in PHP

Post by MikeHawk »

Neat. I gave that code a go:

Code: Select all

1 REM Get biggest common divisor of scrWidth and scrHeight (Euclidean Algorithm,) compute aspect ratio

10 LET scrWidth = 1024
20 LET scrHeight = 768

30 LET a = scrWidth
40 LET b = scrHeight
50 LET c = 0

100 IF (scrWidth < scrHeight) THEN 130
110 LET a = scrHeight
120 LET b = scrWidth
130 REM end if

200 REM start loop (SWAP a, b)
210 LET c = a
220 LET a = b
230 LET b = c

250 REM another loop
260 LET a = a - b
270 IF (a >= b) THEN 250

280 IF (a <> 0) THEN 200

290 PRINT "The aspect ratio of "; scrWidth; "x"; scrHeight; " is "; scrWidth / b; ":"; scrHeight / b
300 END
And the output was of course:

Code: Select all

The aspect ratio of 1024x768 is 4:3
I also tried this one:

Code: Select all

1 REM RGB (red green blue) to HSV (hue saturation value)

10 LET r = 49
20 LET g = 118
30 LET b = 197

100 REM lowest value
105 IF (r < g) AND (r < b) THEN 125
110 IF (g < r) AND (g < b) THEN 135
115 LET min = b
120 GOTO 200
125 LET min = r
130 GOTO 200
135 LET min = g

200 REM highest value
205 IF (r > g) AND (r > b) THEN 225
210 IF (g > r) AND (g > b) THEN 235
215 LET max = b
220 GOTO 300
225 LET max = r
230 GOTO 300
235 LET max = g

300 REM value
305 LET v = max / 255

400 IF (max = 0) THEN 440
410 LET delta = max - min
420 LET s = delta / max
430 GOTO 500
440 LET s = 0
450 LET h = -1
460 GOTO 1000

500 IF (r = max) THEN 540
510 IF (g = max) THEN 560
520 LET h = 4 + (r - g) / delta
530 GOTO 600
540 LET h = (h - b) / delta
550 GOTO 600
560 LET h = 2 + (b - r) / delta

600 LET h = h * 60
610 IF (h >= 0) THEN 1000
620 LET h = h + 360

1000 PRINT "RGB("; r; " "; g; " "; b;") = HSV("; INT(h);"° "; INT(s*100);"% "; INT(v*100);"%)"
1010 END
And got

Code: Select all

RGB(49 118 197) = HSV(212° 75% 77%)
Condition blocks spoiled me, it took me way too long to remember the GW-Basic way of doing things. :lol:
User avatar
bongomeno
Veteran
Posts: 266
Joined: Wed Dec 10, 2008 9:08 am
Location: Arizona
Contact:

Re: Net Basic - a BASIC in PHP

Post by bongomeno »

That made my day. :D I'm glad you were able to get the thing to work. It's scary putting stuff like this out not knowing what kind of errors people will find. Always seems like I miss things.

Your snippets are perfect for the scope of what I intended this BASIC for. Demonstrating concepts with code online.

What's funny is I set the language up to use var names a-z with 0-9 like Tiny Basics. Yet, your examples work perfectly. This is probably due to my usage of SESSION for variables. As a result, I double checked to make sure this was okay internally and updated the documentation of the page. PHP has been very different for me.

May I include your snippets in the Net Basic examples?

It really is a throwback writing IF logic with line jumps. My plan is to add FOR/TO/STEP/NEXT/BREAK first. Then GOSUB/RETURN. Eventually I plan to add ELSE/ENDIF. It will take me a while to get there.

The part I'm not so confident about is the INPUT statement. There needs to be a way to store the running program in a SESSION. I already am using SESSION for the variables, code, and code execution position. After some failed attempts, I just need more time.
MikeHawk
Veteran
Posts: 61
Joined: Sun Jul 08, 2018 11:23 am

Re: Net Basic - a BASIC in PHP

Post by MikeHawk »

bongomeno wrote: Tue Sep 05, 2023 11:08 pm May I include your snippets in the Net Basic examples?
Sure, go ahead.

IIRC, Net Basic didn't throw an error when I attempted to do:

Code: Select all

IF (r < g) AND (r < b) THEN LET min = r
It failed and after looking into the sample codes, I understood I had to jump instead. But I expected an error at least.

I also expected RND to return a value between 0 (included) and 1 (excluded) but got a very large integer instead. I assume it's an oversight, so I divided the result by 2^31. This one is a bit dirty, but it does the job:

Code: Select all

1 REM Silly egg puzzle

10 LET floors = 50
20 LET threshold = 1 + INT((RND / (2^31)) * floors)
30 LET attempts = 0
40 PRINT "How many floors can an egg drop before it cracks? Find out using two eggs."

100 REM First, try every [stride] floors.
105 LET stride = INT(SQR(floors))
110 LET throwFrom = 0
115 PRINT "The test building is "; floors; " stories high, so we'll drop the 1st egg every "; stride; " floors."
120 REM loop start
125 LET attempts = attempts + 1
130 IF (throwFrom >= threshold) THEN 150
135 PRINT "1st egg survived floor "; throwFrom; "..."
140 LET throwFrom = throwFrom + stride
145 GOTO 120
150 PRINT "1st egg cracked after being thrown from floor "; throwFrom; "!"

200 LET throwFrom = throwFrom - stride + 1
205 PRINT "Drop 2nd egg every floor, starting at "; throwFrom; "."
210 REM loop start
215 LET attempts = attempts + 1
220 IF (throwFrom >= threshold) THEN 240
225 PRINT "2nd egg survived floor "; throwFrom; "..."
230 LET throwFrom = throwFrom + 1
235 GOTO 210
240 PRINT "2nd egg cracked after being thrown from floor "; throwFrom; "!"

300 PRINT "The threshold was "; threshold; " and it was found in "; attempts ;" attempts."
305 END
Anyway, I tried designing scripting languages a few times; I usually have no issue with flow control (GOTO, GOSUB, RETURN, IF, ELSEIF, ELSE, ...) but I really can't write a proper way to evaluate stuff. The moment operators and variables get involved, it turns into some kind of Frankenstein monster of a language.
Kudos to you.
Attachments
TRASH.RAR
A side-scroller engine using a scripting language similar to Duke Nukem 3D's CON files. It's an unfinished mess I won't go back to. Source included.
(166.77 KiB) Downloaded 1554 times
User avatar
bongomeno
Veteran
Posts: 266
Joined: Wed Dec 10, 2008 9:08 am
Location: Arizona
Contact:

Re: Net Basic - a BASIC in PHP

Post by bongomeno »

IIRC, Net Basic didn't throw an error when I attempted to do:

Code: Select all

IF (r < g) AND (r < b) THEN LET min = r

It failed and after looking into the sample codes, I understood I had to jump instead. But I expected an error at least.
I have not yet figured out how to support that (haven't tried much either) or the combining of lines with a colon. I will add else/endif instead. My parser is "different" than most proper ones. It just splits the text as it goes.

I have not made any effort to implement error checking yet. My plan is to do that last by studying the errors in other Tiny BASIC implementations. For now I need to update the documentation to specify that combining statements with IF or : is not supported.
I also expected RND to return a value between 0 (included) and 1 (excluded) but got a very large integer instead. I assume it's an oversight, so I divided the result by 2^31. This one is a bit dirty, but it does the job:
This is due to my use of the PHP RND function. I need to write a custom RND function to return the same range as Qbasic.

Another issue is that PHP returns 1 for true as opposed to -1 like QBasic (I noticed YaBasic also returns a 1). I made functions return -1 and changed AND and OR to return -1 on true. The problem comes with NOT(). I don't know how to make it return the same values as QBasic. Right now it will return a 1 on true. I need to change that to make it return -1 to be consistent. Problem is Qbasic gives other values than just -1 and 1 depending on the number. Oh the decisions....
Anyway, I tried designing scripting languages a few times; I usually have no issue with flow control (GOTO, GOSUB, RETURN, IF, ELSEIF, ELSE, ...) but I really can't write a proper way to evaluate stuff. The moment operators and variables get involved, it turns into some kind of Frankenstein monster of a language.
Kudos to you.
Wow that game demo reminds me of Toki a bit. The language looks interesting I am going to study that a bit. Your code looks extremely well written and pretty advanced at a glance.

The expression evaluation stuff has always been out of my reach, so a little over a year ago I decided to dedicate my life to figuring it out and now here I am. My methods are different, but seem to work. What helped me was studying Reverse Polish Notation. You must convert infix notation to postfix, then evaluate the postfix. This wasn't too hard with just four arithmetic operators. The parenthesis are processed and removed during the infix to postfix phase. I was really stumped on things like boolean and relops. Variables weren't too hard. Functions took some creative gutsy attempts. The arrays are still a struggle too.

I'd be happy to share what I have learned about expression evaluation if needed. I can pull up some of the resources that I had studied. TBH it was a bunch of old college class assignments, calculator websites, and RPN tutorials.
User avatar
bongomeno
Veteran
Posts: 266
Joined: Wed Dec 10, 2008 9:08 am
Location: Arizona
Contact:

Re: Net Basic - a BASIC in PHP

Post by bongomeno »

I have updated Net Basic.

The three examples by MikeHawk 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.

Code: Select all

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

Code: Select all

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

Code: Select all

		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.
MikeHawk
Veteran
Posts: 61
Joined: Sun Jul 08, 2018 11:23 am

Re: Net Basic - a BASIC in PHP

Post by MikeHawk »

It seems that QB's RND() function could be emulated with:

Code: Select all

rand(0, getrandmax() - 1) / getrandmax()
That said, I think I found something that you're not going to like much. I was about to say that a good alternative to NOT() is to use XOR -1... but... after running the following code in Net BASIC:

Code: Select all

10 PRINT 255 XOR -1
It returned 255 instead of -256... I got a little worried so I tried something else:

Code: Select all

10 PRINT 16 AND 4
But it returned -1 when I expected it to return 0.

Code: Select all

10 PRINT 5 AND 4
Also returned -1 when it should have returned 4.

>Problem is Qbasic gives other values than just -1 and 1 depending on the number.
The thing is that QBasic's boolean operators are not conditional. Basically, it's the difference between "&" and "&&" in C and JavaScript (or "AND" and "ANDALSO" in FreeBASIC:) "&" is used as a boolean operator to mask bits (16 AND 16 returns 16, but 16 AND 32 returns 0,) while "&&" is a conditional logical operator that only returns TRUE if the two operands are not null. When QB evaluates something like:

Code: Select all

IF (15 AND 4) THEN PRINT (15 AND 5)
It evaluates 4 (not -1.) However:

Code: Select all

IF ((15 AND 4) <> 0) THEN PRINT ((15 AND 4) <> 0)
Evaluates -1. And in FreeBASIC:

Code: Select all

IF (15 ANDALSO 4) THEN PRINT (15 ANDALSO 4)
Would also evaluate -1.
Basically, IF only executes when the result is not null... or, it jumps to another (hidden) label and skips whatever code is supposed to happen if the evaluation is null.

I remember a long time ago I couldn't understand why this evaluation never worked:

Code: Select all

IF (flag1 AND 4) AND (flag2 AND 1) THEN...
I expected that if the value flag1 had its 3rd bit set and flag2 had its 1st bit set, then the condition would trigger. It never did because QB solved it as:

Code: Select all

IF 4 AND 1 THEN...
Which is 0.
User avatar
bongomeno
Veteran
Posts: 266
Joined: Wed Dec 10, 2008 9:08 am
Location: Arizona
Contact:

Re: Net Basic - a BASIC in PHP

Post by bongomeno »

Okay, I have been at it all day. With everything from your post in mind.

Code: Select all

rand(0, getrandmax() - 1) / getrandmax()
Changed. Works perfectly. Always greater than 0 and less than 1. I updated your egg dropping example to reflect the change.

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. 8)
User avatar
bongomeno
Veteran
Posts: 266
Joined: Wed Dec 10, 2008 9:08 am
Location: Arizona
Contact:

Re: Net Basic - a BASIC in PHP

Post by bongomeno »

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:

Code: Select all

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/?l ... E%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)
MikeHawk
Veteran
Posts: 61
Joined: Sun Jul 08, 2018 11:23 am

Re: Net Basic - a BASIC in PHP

Post by MikeHawk »

bongomeno wrote: Fri Sep 08, 2023 1:29 am Works perfectly. Always greater than 0 and less than 1. I updated your egg dropping example to reflect the change.
Neat! :D
bongomeno wrote: Fri Sep 08, 2023 5:29 am Now you may embed Net Basic apps on any site. 8)
Also neat :shock:

If you did not already: check out Ethan Winer's BASIC Techniques and Utilities Book, it explains a lot of things about BASIC code optimization, hardware, and algorithms, but it also covers compiled BASIC code early on (that is, how BASIC is converted into assembly.) It's a hefty book (475 pages) and I'm not expecting you to read it cover to cover (I did not,) but check out the 1st chapter (pages 9 to 20.) There's also a good section on bit operations (page 48 and 49.) The following page, Ethan explains control flow. He starts with DO... LOOP and how it is converted to assembly.
The reason why I think it could be beneficial is because assembly doesn't contain many instructions; once you got those tiny elemental bricks going, you can write a pseudo-compiler to execute your code. Once you got the GOTO down, you can work on conditional jumping. And once you got this, you're gravy: it unlocks the path to condition blocks (like IF... ELSEIF... ELSE... ENDIF,) and loops (like FOR... NEXT and DO... LOOP.) It's a truly amazing read.
User avatar
bongomeno
Veteran
Posts: 266
Joined: Wed Dec 10, 2008 9:08 am
Location: Arizona
Contact:

Re: Net Basic - a BASIC in PHP

Post by bongomeno »

That book may be just what I need to break out of my usual shell.

I did write a BASIC to ASM compiler called FTCBASIC, but it's very limited with only unsigned ints. It only has DO/LOOPS and ENDIF. I wouldn't mind trying to write an even better compiler or at least improving the one I already started.
User avatar
bongomeno
Veteran
Posts: 266
Joined: Wed Dec 10, 2008 9:08 am
Location: Arizona
Contact:

Re: Net Basic - a BASIC in PHP

Post by bongomeno »

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.

Code: Select all

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 ... Y%22%0D%0A

When you click the link, you will get exchange rates. Simply modify the GET variables to change the program output.
User avatar
bongomeno
Veteran
Posts: 266
Joined: Wed Dec 10, 2008 9:08 am
Location: Arizona
Contact:

Re: Net Basic - a BASIC in PHP

Post by bongomeno »

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

Code: Select all

<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>
User avatar
bongomeno
Veteran
Posts: 266
Joined: Wed Dec 10, 2008 9:08 am
Location: Arizona
Contact:

Re: Net Basic - a BASIC in PHP

Post by bongomeno »

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:

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

Code: Select all

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

Code: Select all

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

Code: Select all

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

Code: Select all

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>"
User avatar
bongomeno
Veteran
Posts: 266
Joined: Wed Dec 10, 2008 9:08 am
Location: Arizona
Contact:

Re: Net Basic - a BASIC in PHP

Post by bongomeno »

I realized that Net Basic could generate graphics by printing HTML with SVG tags. I'm still figuring out how to use SVG and what's possible, but for now I went ahead and made some SVG examples.

To use SVG in Net Basic, first call the HTML command to break from the text output area.

Code: Select all

5 PRINT "SVG sine wave"
10 HTML
20 PRINT "<svg width = '640' height = '480'>"
30 FOR i = 1 TO 360
40 PRINT "<rect x = '"; i / 360 * 320; "' y = '"; sin(i / 180 * 3.14) * 50 + 50; "' width = '1' height = '1' />"
50 NEXT i
60 PRINT "</svg>"
Program encoded URL: https://www.lucidapogee.com/netbasic/?l ... Fsvg%3E%22

Code: Select all

1 REM https://rosettacode.org/wiki/Draw_a_sphere
5 PRINT "SVG sphere"
10 HTML
20 PRINT "<svg width = '640' height = '480'>"
30 LET j = 2
40 FOR i = 221 TO 0 STEP j * -1
50 FOR k = -3.14 TO 3.14 STEP .02
60 PRINT "<rect x = '"; 221 + i * sin(k); "' y = '"; 222 + 221 * cos(k); "' width = '1' height = '1' />"
70 PRINT "<rect x = '"; 221 + 221 * sin(k); "' y = '"; 222 + (i - 1) * cos(k); "' width = '1' height = '1' />"
80 NEXT k
90 LET j = j + 1
100 NEXT i
Program encoded URL: https://www.lucidapogee.com/netbasic/?l ... %20i%0D%0A

Code: Select all

1 REM https://rosettacode.org/wiki/Barnsley_fern
5 PRINT "SVG Barnsley fern"
10 HTML
20 PRINT "<svg width = '640' height = '480' style = 'background-color:red;'>"
30 FOR i = 1 TO 10000
40 LET r = RND
50 IF NOT(r > 0 AND r < .01) THEN 80
60 LET x = .0
70 LET y = .16 * y
80 IF NOT(r > .01 AND r < .08) THEN 110
90 LET x = .22 * x - .26 * y
100 LET y = -.23 * x + .22 * y + 1.6
110 IF NOT(r > .075 AND r < .15) THEN 140
120 LET x = .15 * x + .28 * y
130 LET y = -.29 * x + .24 * y + .44
140 LET x = .85 * x + .04 * y
150 LET y = -.04 * x + .85 * y + 1.6
160 LET x1 = (x + 3) * 70
170 LET y1 = 700 - y * 70
180 PRINT "<rect x = '"; x1; "' y = '"; y1; "' width = '1' height = '1' fill = 'green' />"
190 NEXT i
200 PRINT "</svg>"
Program encoded URL: https://www.lucidapogee.com/netbasic/?l ... Fsvg%3E%22

Code: Select all

1 REM https://rosettacode.org/wiki/Archimedean_spiral
5 PRINT "SVG Archimedean spiral"
10 HTML
20 PRINT "<svg width = '640' height = '480'>"
30 LET size = 80
40 LET x = 250
50 LET y = 200
60 LET a = 1.5
70 LET b = .7
80 FOR t = 0 TO size * PI STEP .1
90 LET r = a + b * t
100 PRINT "<rect x = '"; r * cos(t) + x; "' y = '"; r * sin(t) + y; "' width = '1' height = '1' />"
110 NEXT t
120 PRINT "</svg>"
Program encoded URL: https://www.lucidapogee.com/netbasic/?l ... Fsvg%3E%22

Code: Select all

5 PRINT "SVG curlicue"
10 HTML
20 PRINT "<svg width = '640' height = '480'>"
30 FOR f = 0 TO 1000 STEP .1
40 LET x = x + SIN(f * f)
50 LET y = y + COS(f * f)
60 PRINT "<rect x = '"; x; "' y = '"; y; "' width = '1' height = '1' />"
70 NEXT f
80 PRINT "</svg>"
Program encoded URL: https://www.lucidapogee.com/netbasic/?l ... Fsvg%3E%22
Post Reply