QB64.org Forum

Active Forums => Programs => Topic started by: luke on July 04, 2020, 11:09:05 am

Title: The L-BASIC Interpreter
Post by: luke on July 04, 2020, 11:09:05 am
I've been fiddling away on a BASIC interpreter (because it's basically a rite of passage to write one yourself, right?) for a little while and thought I'd at least start a forum thread for it. It's primarily interactive, so you can just hit F5 in the IDE to launch it and start typing commands. You can also drag-and-drop source code files onto it (or give a command line argument) to run a file.

Latest source attached to this post. Project also at https://github.com/flukiluke/L-BASIC (https://github.com/flukiluke/L-BASIC) for the interested. There will be bugs, feel free to yell at me if you get an error with something that's on the "working" list.

What's different:

What's working:

What's not working:



Attachments Displayed Below Message Body

  lbasic-v0.1.2.bas  

Title: Re: The 65 BASIC Interpreter
Post by: bplus on July 04, 2020, 11:46:15 am
Ah this sounds interesting, I will check it out. Particularly interested in strings, are you doing or plan to do everything the QB64 way like formally Type all variables or do you have plans for some modern things like some OOPs.
Title: Re: The 65 BASIC Interpreter
Post by: luke on July 04, 2020, 12:04:48 pm
Ultimately it's still a very statically typed language, because I do want something that can eventually compile too and I don't want to make my life too hard. That said, I fully expect to have some niceties like polymorphic functions, optional arguments and returning arrays & UDTs. Don't expect proper objects - I'm trying to implement the language we know and love with just some obvious extensions along the way.
Title: Re: The 65 BASIC Interpreter
Post by: bplus on July 04, 2020, 12:11:04 pm
Well already I see it might become the Immediate Mode someone was looking for awhile back.

I don't remember if Fellippe's was doing that too?
Title: Re: The 65 BASIC Interpreter
Post by: FellippeHeitor on July 04, 2020, 12:13:43 pm
Mine is a mere toy. This is the real deal. We should all watch it as it blossoms!
Title: Re: The 65 BASIC Interpreter
Post by: Dav on July 04, 2020, 01:00:19 pm
What a great beginning!  Looking forward to watching this grow.

- Dav
Title: Re: The 65 BASIC Interpreter
Post by: Pete on July 04, 2020, 01:14:52 pm
You blew it already. 65? Binary school called, your refund check is in the mail! J/K.

Good "luke" with the project,

Pete
Title: Re: The 65 BASIC Interpreter
Post by: bplus on July 04, 2020, 01:16:00 pm
I kinda wish I saw more of the seed before it got 130+ constants and over 2000 (LOC).

I hope Luke has a little time to discuss beginnings, maybe another episode of QB64 talk show.

Yeah where does 65 come from? 1 more that 64?
Title: Re: The 65 BASIC Interpreter
Post by: luke on July 04, 2020, 01:21:09 pm
I suck at naming things and desperately need suggestions. Ideally a pun of some kind.

A lot of the constants and the DATA tables are auto-generated. See the github link for the actual sources and earlier versions.
Title: Re: The 65 BASIC Interpreter
Post by: bplus on July 04, 2020, 01:24:10 pm
65 works! It is 64 + 1! That's cool!

I will check out the earlier versions thanks for info.
Title: Re: The 65 BASIC Interpreter
Post by: +KZ on July 04, 2020, 03:26:16 pm
how when you find a BASIC Compiler and that need to be compiled with a BASIC Compiler and that need to be compiled with a BASIC Compiler and that need to be compiled with a BASIC Compiler and that need to be compiled with a BASIC Compiler and that need to be compiled with a BASIC Compiler......
Title: Re: The 65 BASIC Interpreter
Post by: SMcNeill on July 04, 2020, 03:28:03 pm
how when you find a BASIC Compiler and that need to be compiled with a BASIC Compiler and that need to be compiled with a BASIC Compiler and that need to be compiled with a BASIC Compiler and that need to be compiled with a BASIC Compiler and that need to be compiled with a BASIC Compiler......

They tend to start that way, until they mature to the point where they can self-compile.  When QB64 was first being created, it was compiled with QB45, until it matured enough to start compiling itself.  :)
Title: Re: The 65 BASIC Interpreter
Post by: luke on July 05, 2020, 01:26:41 am
Updated to now support integer division, fix operator precedence and add loops! DO LOOP, WHILE WEND and FOR NEXT all supported. This means it can now run programs like this:
Code: [Select]
const MAGIC_NUMBER = 17

print "Guess the number"
print "I'm thinking of a number, can you guess what it is?"

do
    input "Your guess: ", guess%
    if guess% > MAGIC_NUMBER then print "Nope,"; guess%; "is too high."
    if guess% < MAGIC_NUMBER then print "Nope,"; guess%; "is too low."
loop while guess% <> MAGIC_NUMBER
print "Yes, you got it!"
Title: Re: The 65 BASIC Interpreter
Post by: Aurel on July 05, 2020, 03:52:25 am
WOW man ...!
That is great ...i like it !
Title: Re: The 65 BASIC Interpreter
Post by: luke on July 05, 2020, 07:21:40 am
Progress continues apace, now supporting the colon (:) for multiple commands on one line and the use of ELSEIF. The interactions between the colon, REM and the IF statement are tricky to get right - I encourage you to give it your most fiendish IF-THEN command and see if you can break it.

Program from Terry Ritchie's tutorials we can now run:
Code: [Select]
DIM Value% 'numeric value the user supplies

INPUT "Enter a number between 1 and 100 >", Value%
IF Value% < 1 THEN
    PRINT "That number is less than one!"
ELSEIF Value% > 100 THEN
    PRINT "That number is greater than one hundred!"
ELSE
    PRINT "Thank you for helping us help you help us all."
END IF
Title: Re: The 65 BASIC Interpreter
Post by: Pete on July 05, 2020, 10:11:59 am
Name it: QB60_More. Hey your fault, you asked for a pun.

Pete
Title: Re: The 65 BASIC Interpreter
Post by: SMcNeill on July 05, 2020, 10:28:34 am
Name it: QB60_More. Hey your fault, you asked for a pun.

Pete

Asked for a pun, not a punishment...
Title: Re: The 65 BASIC Interpreter
Post by: bplus on July 05, 2020, 12:58:46 pm
WOW man ...!
That is great ...i like it !

Ha! I was wondering if shadow man would show up for this!
Title: Re: The 65 BASIC Interpreter
Post by: Pete on July 05, 2020, 01:40:05 pm
Asked for a pun, not a punishment...

Oh come on, Steve. Everyone knows you can't spell punishment without pun... unless, of course, you spell it wrong.

Why I put up with wiseacres from Green Acres, I'll never know. ;D

Pete
Title: Re: The 65 BASIC Interpreter
Post by: Pete on July 05, 2020, 01:41:16 pm
Oh, Okay. How about...

Q-Beat64. It has a nice beat, and you can debug to it.

Pete
Title: Re: The 65 BASIC Interpreter
Post by: +KZ on July 05, 2020, 02:10:42 pm
if name it "46BQ"? :P
Title: Re: The 65 BASIC Interpreter
Post by: Ashish on July 06, 2020, 03:15:57 am
Good job on this @luke
I'm liking it!
The 65 source code looks complicated. ;D
Title: Re: The 65 BASIC Interpreter
Post by: luke on July 10, 2020, 08:29:26 am
After much pain and suffering, we now support the dreaded GOTO (only line numbers for now - no labels). This doesn't really work in the interactive mode, so if you want to try it you'll need to write your program in a file. Also added are CLS and SYSTEM, to make life a little easier.

Huge thanks to Ashish for finding bugs upon bugs and pointing out my sloppy coding!
Title: Re: The 65 BASIC Interpreter
Post by: johnno56 on July 10, 2020, 09:55:44 am
How about a more 'classical' name? QBorNotQB... lol or simply: QB65
Title: Re: The 65 BASIC Interpreter
Post by: johnno56 on July 10, 2020, 10:15:17 am
In reference to GOTO, please forgive my forwardness, but why? I thought 'that' bane of spaghetti-basic had been 'put down' years ago... Just the thought of a loop performing its function and told part way through to leave the loop and probably never come back... is almost 'cringeworthy' (probably not a real word - but you get what I mean). Let's not talk about how we noobs (ok me) find it difficult to translate goto's into 'basics' that no longer use line numbers... I was just getting used to using subroutines and functions and easy to follow structured listings...

But, that's just my opinion, for what it's worth... lol

Anyway, besides what I think, I hope that you can implement both line numbers 'and' labels without too many headaches...

I need more coffee... I think I'm babbling again...
Title: Re: The 65 BASIC Interpreter
Post by: bplus on July 10, 2020, 11:05:09 am
In reference to GOTO, please forgive my forwardness, but why? I thought 'that' bane of spaghetti-basic had been 'put down' years ago... Just the thought of a loop performing its function and told part way through to leave the loop and probably never come back... is almost 'cringeworthy' (probably not a real word - but you get what I mean). Let's not talk about how we noobs (ok me) find it difficult to translate goto's into 'basics' that no longer use line numbers... I was just getting used to using subroutines and functions and easy to follow structured listings...

But, that's just my opinion, for what it's worth... lol

Anyway, besides what I think, I hope that you can implement both line numbers 'and' labels without too many headaches...

I need more coffee... I think I'm babbling again...

Ideology goes too far when it bans practicality.

The decision that branches execution flow fundamentally requires a GOTO way down in the machine level. It would be too ironic to ban such a basic thing from Basic. But just because it's not banned doesn't give license to use it in place of ELSE,  LOOP or even EXIT (ha! to Cobalt ;-)) structure because that is not practical either.
Title: Re: The 65 BASIC Interpreter
Post by: SMcNeill on July 10, 2020, 11:13:08 am
I, for one, think of GOTOs as an essential part of my coding toolkit.  For many, many things, they just make sense.

Where do you see me use them a ton??

In SUB/FUNCTIONs, as a means to clean up/restore settings before exiting.

For example, I might have a routine which tosses colored text on the screen..

FUNCTION ColoredTextAtPos (foreground, background, font, text$, xpos, ypos)

Now, the first things I want to get is:

D =_DEST: S =_SOURCE
F =_FONT
Oldx = POS(0): OldY = LOC
DC =_DEFAULTCOLOR:  BG = _BACKGROUNDCOLOR

All the current settings to affect my screen...

Then I do my main process, which might have multiple exit points...  If text$ = "", settings for SCREEN 0, 256 color graphic modes, and 32-bit color graphic modes, if the font is monospaced, unicode, or not....

Now some folks might sit down and scheme out some method to include/exclude all those various settings, but I tend to find it easiest to just handle them linearly one by one, myself.

IF text$ = "" THEN GOTO exit_point
IF xpos < 0 OR ypos < 0 THEN GOTO exit_point

I can't always just EXIT FUNCTION, as I may need to reset those initial values I captured, so a label called exit_point makes perfect sense a few lines before the END FUNCTION, so I can do those value resets afterwards.

It's not confusing.  It's not spaghetti code.  Nobody scratches their head reading it, and has a hard time understanding it.  In fact, I'd argue that with proper use of a descriptive label, like exit_point above, that it's *more* readable and self-documenting than many other ways you might write the same code.

GOTO isn't inherently bad.  It's just bad when it's used improperly, and then it's *really* bad.
Title: Re: The 65 BASIC Interpreter
Post by: Aurel on July 10, 2020, 11:23:20 am
I, for one, think of GOTOs as an essential part of my coding toolkit
...i agree
Title: Re: The 65 BASIC Interpreter
Post by: johnno56 on July 10, 2020, 07:23:10 pm
Ok. I will concede that there are pros and cons to including goto... It was not my intention to cause problems. Just voicing an opinion...

Luke. You stated, "(only line numbers for now - no labels)"... But, aren't line numbers, labels? If not what is the difference? Just curious

Title: Re: The 65 BASIC Interpreter
Post by: luke on July 10, 2020, 08:36:12 pm
For what it's worth, my implementation of GOTO is quite slow compared to the regular control flow constructs so let that be a reason to avoid it :)

There's no avoiding that it's a used statement and so needs to be implemented.

Luke. You stated, "(only line numbers for now - no labels)"... But, aren't line numbers, labels? If not what is the difference? Just curious
The difference is in recognition. Consider this code:
Code: [Select]
10 PRINT X$
lbl: PRINT Y$
It's really easy to recognise 10 as a line number - we just say if we're at the start of the line and see an integer, it's a line number.

With the label, it's just a string of characters. If, instead of "lbl" I had used "BEEP", it would have not been a label but two statements joined by a colon. So far I haven't implemented the extra logic to recognise a label from a command.
Title: Re: The 65 BASIC Interpreter
Post by: johnno56 on July 10, 2020, 11:10:58 pm
Understood. Thank you for the info.
Title: Re: The 65 BASIC Interpreter
Post by: luke on July 11, 2020, 11:10:30 pm
Nice juicy update for version 0.0.2, now supporting, amongst other things, a bunch of commands beginning with the letter C as well as SCREEN and PLAY. Means you can now draw circles in SCREEN 13 with music to your heart's content.
Title: Re: The 65 BASIC Interpreter
Post by: FellippeHeitor on July 12, 2020, 11:40:29 am
Working great on macOS now with the latest dev build of QB64.
Title: Re: The 65 BASIC Interpreter
Post by: luke on January 15, 2021, 08:56:45 am
Version 0.0.3, featuring a bunch of new commands, user-defined types and experimental support for arrays. See first post for code.

This means it can now run things like:
Code: [Select]
type t
    a as long
    b$
end type

v = 4
dim a(3, v / 2) as t
a(2, 1).a = 4
a(2, 1).b = "hello"

a(3, 2) = a(2, 1)
print a(3, 2).a; a(3, 2).b
Yep, that's a dynamically-sized multi-dimensional array of a user-defined type containing variable length strings.

Arrays are a little untested for now, and you can't resize them. You also can't have arrays in a user-defined type, but that should be coming shortly.

Big thanks again to Ashish for implementing some commands and giving it a good test all round.

Title: Re: The 65 BASIC Interpreter
Post by: Dav on January 15, 2021, 11:11:55 am
This is great, @luke !  Glad you are continuing with this.  I've got a rather large collection of interpreters written in basic languages - I think yours is one of the best.

- Dav
Title: Re: The 65 BASIC Interpreter
Post by: STxAxTIC on January 21, 2021, 04:20:32 pm
Is the make/build process linux only? I'm even having permission/path trouble with *that*, despite chmodding everything and running as admin. Which system(s) is the build process intended for? I'm trying the Linux subsystem for windows 10 and can't even finish the readme.
Title: Re: The 65 BASIC Interpreter
Post by: luke on January 21, 2021, 06:08:26 pm
Ashish managed to run the Makefile on Windows using the make that comes with QB64's C++ compiler, but I highly recommend just compiling the file attached to the first post of this thread. You just load it into a recent QB64 version and hit F5.
Title: Re: The 65 BASIC Interpreter
Post by: STxAxTIC on January 21, 2021, 06:16:46 pm
Myyyy bad, that file was subtle!
Title: Re: The 65 BASIC Interpreter
Post by: Ed Davis on January 21, 2021, 09:00:00 pm
Makefile on Windows:

For me, all I had to change was this:
From:
# This should point to your QB64 installation
QB64 := /home/luke/comp/git_qb64/qb64 -q -w

To:
# This should point to your QB64 installation
QB64 := $(USERPROFILE)/bin/bas/qb64/qb64 -q -w

And then make does the needful.
Title: Re: The 65 BASIC Interpreter
Post by: Ed Davis on January 21, 2021, 09:45:19 pm
I really like the test.bas supplied with 65.  I've been using it for some of my own unit testing, and it works great!

To get it working on Windows, I only had to make a few simple changes:

Code: QB64: [Select]
  1. 'If on Windows, get the temporary path
  2. 'Inserted after line 26
  3.   >if instr(_os$, "WINDOWS") > 0 then
  4.   >    tmpdir$ = environ$("TEMP") + "\"
  5.   >end if
  6.  
  7. 'Windows doesn't like ":" in filenames
  8. 'Changed line 68
  9.   >    filename$ = tmpdir$ + "test-" + date$ + time$ + "-" + rndhex$(4)
  10. 'To
  11.   >    t$ = time$
  12.   >    if instr(_os$, "WINDOWS") > 0 then t$ = replace_char(t$, ":", "_")
  13.   >    filename$ = tmpdir$ + "test-" + date$ + "-" + t$ + "-" + rndhex$(4)
  14.  
  15. 'Get rid of those pesky chr$(13) that Windows uses
  16. 'Inserted after line 86
  17.   >
  18.   >        actual_output$                     = remove_char$(actual_output$, chr$(13))
  19.   >        tests(active_test).expected_output = remove_char$(tests(active_test).expected_output, chr$(13))
  20.   >
  21.  
  22. 'Two simple routines - probably a better way, but these work for now
  23. 'Inserted after line 125
  24.   >
  25.   >function replace_char$(s$, c1$, c2$)
  26.   >    dim p as integer
  27.   >
  28.   >    do
  29.   >        p = instr(s$, c1$)
  30.   >        if p > 0 then mid$(s$, p, 1) = c2$ else exit do
  31.   >    loop
  32.   >    replace_char$ = s$
  33.   >
  34.   >function remove_char$(s$, c$)
  35.   >  dim s2$
  36.   >  dim i as integer
  37.   >
  38.   >  s2$ = ""
  39.   >  for i = 1 to len(s$)
  40.   >    if mid$(s$, i, 1) <> c$ then
  41.   >      s2$ = s2$ + mid$(s$, i, 1)
  42.   >    end if
  43.   >  next
  44.   >  remove_char$ = s2$

Now test.bas works for me on Windows!
Title: Re: The 65 BASIC Interpreter
Post by: Ed Davis on January 21, 2021, 10:52:32 pm
I've got a rather large collection of interpreters written in basic languages ...
- Dav

Is this something you are willing to make available?
Title: Re: The 65 BASIC Interpreter
Post by: Dav on January 21, 2021, 10:59:27 pm
Is this something you are willing to make available?

I suppose I could, Ed.  I think I have one by you (I recognize the name).  Didn't you make the Toy Interpreter? Or something named like that...

- Dav
Title: Re: The 65 BASIC Interpreter
Post by: luke on January 22, 2021, 12:00:09 am
I really like the test.bas supplied with 65.  I've been using it for some of my own unit testing, and it works great!

To get it working on Windows, I only had to make a few simple changes:

Thanks for letting me know, I'll look at adding those changes to make it cross-platform.
Title: Re: The 65 BASIC Interpreter
Post by: Ed Davis on January 22, 2021, 12:05:38 am
I suppose I could, Ed.  I think I have one by you (I recognize the name).  Didn't you make the Toy Interpreter? Or something named like that...

- Dav
Yep, I'm guilty of that one.

I also made the infamous tiny interpreter that used to be in the QB64 sample programs directory.   Someone modified it somewhat, but it still has some of my original bugs :)

You can see my original Tiny Basic post here (Feb 19, 2007, 7:16:12 AM) as part of the thread "Recommend a book on how to write a BASIC interpreter?"

https://groups.google.com/g/comp.lang.basic.misc/c/3yflBQV35M8/m/ZrPgEe8564gJ

and here:

https://narkive.com/YC5L5jHK.25

Anyway,  not trying to cause you any extra work.  If it is a pain to do, don't worry about it, I'll survive :)
Title: Re: The 65 BASIC Interpreter
Post by: Dav on January 22, 2021, 10:02:30 am
Oh yes, I remember seeing that one.  I really appreciate all the interpreters you guys shared with everyone. I used to scour the web for interpreters. Most are not in basic, but i sure felt like finding gold when coming up on one.

I got them all littered on several HD's and thumb drives.  Been meaning put them all in one place one day. Maybe now is a good time....

- Dav
Title: Re: The 65 BASIC Interpreter
Post by: Aurel on January 24, 2021, 12:39:39 pm
Dav

Your coditor ...oups code editor is great and i was using it before I
modify my own to work with qb64...
so i hope that you will show us your collection
Title: Re: The L-BASIC Interpreter
Post by: luke on January 09, 2022, 07:02:57 am
It's been a year, but I'm finally calling it 0.1.0 - see attachment. I've updated the original post with the new supported commands, but importantly this version is capable of running STxAxTIC's sxript language!

This version can create SUBs and FUNCTIONs, with the catch that if you put the SUB/FUNCTION at the bottom of your program, you'll need a DECLARE SUB or DECLARE FUNCTION line at the top. Or, just put the SUB itself at the top of your program (that's perfectly legal in L-BASIC).

You can also have optional arguments! Example:
Code: [Select]
sub s(a, option b, option c)
    print "a = "; a;
    if option(b) then print "b = "; b;
    if option(c) then print "c = "; c;
    print
end sub

s 1
s 2, 3
s 2, 3, 4
s 2, , 4

Other working features include array resizing including _preserve, and DIM SHARED support.



Attachments Displayed Below Message Body

  lbasic-0.1.0.bas  

Title: Re: The L-BASIC Interpreter
Post by: madscijr on January 14, 2022, 01:42:55 pm
@luke I would love to see TI99/4A and TRS-80 BASIC interpreters :-)
The big trick for making my old TI programs work in QB64 would be replicating the sound commands. Which leads to my wishlist item for native ADSR waveform sound commands for QB64!
Title: Re: The L-BASIC Interpreter
Post by: luke on January 16, 2022, 06:48:50 am
Version 0.1.1 (file attached)!

I'm happy to report DECLARE SUB/FUNCTION lines are no longer needed. You can arrange your code however you want, so this is fine:
Code: [Select]
Sub s1
  s2
End Sub

s1

Sub s2
  Print "Hi"
End Sub

SELECT CASE is now implemented, including CASE IS and CASE x TO y forms.

$includes are handled, but unlike QB64 they should not go in a comment. The $ is the first character on the line, like with $checking or $screenhide in QB64.

This version is actually capable of running STxAxTIC's Sanctum 3D simulator with some very minor tweaks. Unfortunately it's rather slow - but a success nonetheless.

Full list of commands in the first post.



Attachments Displayed Below Message Body

  lbasic-v0.1.1.bas  

Title: Re: The L-BASIC Interpreter
Post by: bplus on January 30, 2022, 10:53:21 am
@luke Not able to get this to work:
Code: QB64: [Select]
  1. ' test recursive sub on Luke Basic b+ 2022-01-30
  2.  
  3. recurs 1, 0, 0, 1
  4.  
  5. Sub recurs (a!, b!, c!, level%)
  6.     If level% > 10 Then
  7.         Exit Sub
  8.     Else
  9.         x! = a!
  10.         y! = b! + a!
  11.         z! = y! + c!
  12.         Print "Level:"; level%
  13.         recurs x!, y!, z!, level% + 1
  14.         Print "Level:"; level%; " x, y, z:"; x!; y!; z!
  15.     End If
  16.  
  17.  

 

Title: Re: The L-BASIC Interpreter
Post by: jack on January 30, 2022, 12:53:42 pm
hi bplus
you can make it work by changing line 11 to call recurs (x!, y!, z!, level% + 1)
but granted it's different than QB64
Title: Re: The L-BASIC Interpreter
Post by: bplus on January 30, 2022, 12:57:44 pm
Thanks @jack that got it, same output as QB64.
Title: Re: The L-BASIC Interpreter
Post by: Phlashlite on February 01, 2022, 11:00:41 pm
This is pretty amazing!
Title: Re: The L-BASIC Interpreter
Post by: luke on February 05, 2022, 08:42:42 am
Well that's a rather embarrassing mistake to have made! A small typo meant it thought Subs were Functions for the purposes of setting a return value. Here's a fixed version 0.1.2, which also includes a bunch of new commands (notably mouse support) and preliminary support for returning arrays from functions.



Attachments Displayed Below Message Body

  lbasic-v0.1.2.bas