-
Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
For anyone longing to use Q(uick)BASIC (or VBDOS) again:
Code:
DEFINT A-Z
DECLARE FUNCTION Escape$ (Text AS STRING)
DECLARE FUNCTION GetLoopList$ (Code AS STRING)
DECLARE FUNCTION LoadCode$ (Path AS STRING)
DECLARE FUNCTION Loops (LoopList AS STRING, InstructionP AS INTEGER, Backwards AS INTEGER)
DECLARE FUNCTION NextArgument (Arguments AS STRING)
DECLARE FUNCTION PopArgument$ (Arguments AS STRING, Argument AS STRING)
DECLARE FUNCTION Unescape$ (Text AS STRING)
DECLARE SUB Execute (Code AS STRING, InputLineBreak AS STRING, OutputLineBreak AS STRING)
DECLARE SUB Main ()
CALL Main
FUNCTION Escape$ (Text AS STRING)
DIM Character AS STRING * 1
DIM Escaped AS STRING
DIM Hexed AS STRING
DIM Position AS INTEGER
Escaped = ""
FOR Position = 1 TO LEN(Text)
Character = MID$(Text, Position, 1)
SELECT CASE Character
CASE "/"
Escaped = Escaped + "//"
CASE " " TO "~"
Escaped = Escaped + Character
CASE ELSE
Hexed = HEX$(ASC(Character))
IF LEN(Hexed) = 1 THEN Hexed = "0" + Hexed
Escaped = Escaped + "/" + Hexed
END SELECT
NEXT Position
Escape$ = Escaped
END FUNCTION
SUB Execute (Code AS STRING, InputLineBreak AS STRING, OutputLineBreak AS STRING)
DIM Character AS STRING * 1
DIM InputBuffer AS STRING
DIM InstructionP AS INTEGER
DIM LoopList AS STRING
DIM Memory AS STRING
DIM MemoryP AS INTEGER
DIM OutputBuffer AS STRING
DIM UserInput AS STRING
InstructionP = &H0
LoopList = GetLoopList$(Code)
Memory = STRING$(&H7FFF, &H0)
MemoryP = &H0
DO
SELECT CASE MID$(Code, InstructionP + &H1, &H1)
CASE ">"
IF MemoryP >= LEN(Memory) THEN MemoryP = &H0 ELSE MemoryP = MemoryP + &H1
CASE "<"
IF MemoryP = &H0 THEN MemoryP = LEN(Memory) - &H1 ELSE MemoryP = MemoryP - &H1
CASE "+"
IF ASC(MID$(Memory, MemoryP + &H1, &H1)) = &HFF THEN
MID$(Memory, MemoryP + &H1, &H1) = CHR$(&H0)
ELSE
MID$(Memory, MemoryP + &H1, &H1) = CHR$(ASC(MID$(Memory, MemoryP + &H1, &H1)) + &H1)
END IF
CASE "-"
IF ASC(MID$(Memory, MemoryP + &H1, &H1)) = &H0 THEN
MID$(Memory, MemoryP + &H1, &H1) = CHR$(&HFF)
ELSE
MID$(Memory, MemoryP + &H1, &H1) = CHR$(ASC(MID$(Memory, MemoryP + &H1, &H1)) - &H1)
END IF
CASE "."
Character = MID$(Memory, MemoryP + &H1, &H1)
IF OutputLineBreak = "" THEN
PRINT Escape$(Character);
ELSE
OutputBuffer = OutputBuffer + Character
IF NOT LEFT$(OutputLineBreak, LEN(OutputBuffer)) = OutputBuffer THEN
PRINT Escape$(OutputBuffer);
OutputBuffer = ""
ELSEIF OutputBuffer = OutputLineBreak THEN
PRINT
OutputBuffer = ""
END IF
END IF
CASE ","
IF InputBuffer = "" THEN
LINE INPUT UserInput
InputBuffer = Unescape$(UserInput) + InputBuffer + InputLineBreak
END IF
IF NOT InputBuffer = "" THEN
MID$(Memory, MemoryP + &H1, &H1) = LEFT$(InputBuffer, 1)
InputBuffer = MID$(InputBuffer, 2)
END IF
CASE "["
IF ASC(MID$(Memory, MemoryP + &H1, &H1)) = &H0 THEN
InstructionP = Loops(LoopList, InstructionP, 0)
END IF
CASE "]"
IF NOT ASC(MID$(Memory, MemoryP + &H1, &H1)) = &H0 THEN
InstructionP = Loops(LoopList, InstructionP, -1)
END IF
END SELECT
InstructionP = InstructionP + &H1
LOOP WHILE InstructionP > &H0 AND InstructionP < LEN(Code)
END SUB
FUNCTION GetLoopList$ (Code AS STRING)
DIM Character AS STRING * 1
DIM LoopList AS STRING
DIM LoopStack AS STRING
DIM Position AS INTEGER
DIM StartOfLoop AS INTEGER
LoopList = ""
LoopStack = ""
FOR Position = 1 TO LEN(Code)
Character = MID$(Code, Position, 1)
SELECT CASE Character
CASE "["
LoopStack = LoopStack + MKI$(Position - 1)
CASE "]"
IF LoopStack = "" THEN
PRINT "End of loop without start."
EXIT FOR
ELSE
StartOfLoop = CVI(MID$(LoopStack, LEN(LoopStack) - 1, 2))
LoopStack = LEFT$(LoopStack, LEN(LoopStack) - 2)
LoopList = LoopList + MKI$(StartOfLoop) + MKI$(Position - 1)
END IF
END SELECT
NEXT Position
IF NOT LoopStack = "" THEN
PRINT "Loop without end."
END IF
GetLoopList$ = LoopList
END FUNCTION
FUNCTION LoadCode$ (Path AS STRING)
DIM Code AS STRING
DIM FileH AS INTEGER
FileH = FREEFILE
OPEN Path FOR INPUT LOCK READ WRITE AS FileH
CLOSE FileH
FileH = FREEFILE
OPEN Path FOR BINARY LOCK READ WRITE AS FileH
Code = INPUT$(LOF(FileH), FileH)
CLOSE FileH
LoadCode$ = Code
END FUNCTION
FUNCTION Loops (LoopList AS STRING, InstructionP AS INTEGER, Backwards AS INTEGER)
DIM NewInstructionP AS INTEGER
DIM Position AS INTEGER
FOR Position = 1 TO LEN(LoopList) STEP 4
SELECT CASE Backwards
CASE 0
IF InstructionP = CVI(MID$(LoopList, Position, 2)) THEN
NewInstructionP = CVI(MID$(LoopList, Position + 2, 2))
EXIT FOR
END IF
CASE -1
IF InstructionP = CVI(MID$(LoopList, Position + 2, 2)) THEN
NewInstructionP = CVI(MID$(LoopList, Position, 2))
EXIT FOR
END IF
END SELECT
NEXT Position
Loops = NewInstructionP
END FUNCTION
SUB Main
DIM Arguments AS STRING
DIM InputLineBreak AS STRING
DIM OutputLineBreak AS STRING
DIM Path AS STRING
Arguments = LTRIM$(RTRIM$(COMMAND$))
InputLineBreak = CHR$(13)
OutputLineBreak = CHR$(13)
IF NOT Arguments = "" THEN
Arguments = PopArgument$(Arguments, Path)
IF NOT Arguments = "" THEN
Arguments = PopArgument$(Arguments, InputLineBreak)
IF NOT Arguments = "" THEN
Arguments = PopArgument$(Arguments, OutputLineBreak)
END IF
END IF
END IF
IF Path = "" THEN
PRINT "Brain***** Interpreter v1.00, by: Peter Swinkels, ***2023***"
PRINT
PRINT "Usage:"
PRINT "BFInterp.exe PATH LINE_BREAK_IN LINE_BREAK_OUT"
ELSE
Execute LoadCode$(Path), Unescape$(InputLineBreak), Unescape$(OutputLineBreak)
END IF
END SUB
FUNCTION NextArgument (Arguments AS STRING)
DIM Position AS INTEGER
Position = INSTR(1, Arguments, " ")
IF Position = 0 THEN Position = LEN(Arguments) + 1
IF Position = 1 THEN Position = 0
NextArgument = Position
END FUNCTION
FUNCTION PopArgument$ (Arguments AS STRING, Argument AS STRING)
DIM NextPosition AS INTEGER
Arguments = LTRIM$(RTRIM$(Arguments))
NextPosition = NextArgument(Arguments)
IF NextPosition > 0 THEN
Argument = LEFT$(Arguments, NextPosition - 1)
Arguments = MID$(Arguments, NextPosition + 1)
END IF
PopArgument$ = Arguments
END FUNCTION
FUNCTION Unescape$ (Text AS STRING)
DIM Character AS STRING * 1
DIM Position AS INTEGER
DIM Unescaped AS STRING
Position = 1
Unescaped = ""
DO UNTIL Position > LEN(Text)
Character = MID$(Text, Position, 1)
IF Character = "/" THEN
IF MID$(Text, Position + 1, 1) = "/" THEN
Unescaped = Unescaped + Character
Position = Position + 2
ELSE
Unescaped = Unescaped + CHR$(VAL("&H" + MID$(Text, Position + 1, 2) + "%"))
Position = Position + 3
END IF
ELSE
Unescaped = Unescaped + Character
Position = Position + 1
END IF
LOOP
Unescape$ = Unescaped
END FUNCTION
This is just a toy project for fun, so don't expect it to be particularly efficient! ;-)
The complete project:
https://github.com/PeterSwinkels/QB-...ck-Interpreter
-
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
I think it's really interesting QB had predeclared functions... I had been contemplating posting a request for these in tB so we could provide prototypes of callback functions like the SDK headers, but it seemed like pushing it too far into C/C++ territory. But looks like it would just be getting back to it's roots.
Must say though QB+Brain****? Sir, please stop trying to destroy planet Earth. :wave:
-
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
@Fafalone, it would make it more appealing to developers used to such functionality. Although I guess since TwinBASIC is primarily intended as a modern substitute for classic Visual Basic, it would be unnecessary for most people who might adapt to TwinBASIC.
LOL - *Attempting to combine the evils of BF and QB* "Tomorrow my evil plan to destroy the Earth will succeed! MUHAHAHA"
Seriously, anyone want to have some fun with this? It does work already, it could be made to run faster and memory usage could be improved.
-
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
Just one word - STTR1 (for those old enough to know about this)! :p
-
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
@2kaud, are you having fun with me? XP
-
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
Quote:
Originally Posted by
fafalone
Must say though QB+Brain****? Sir, please stop trying to destroy planet Earth. :wave:
That's right. You SHOULD be writing a Rockstar interpreter.
-
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
Code:
Midnight takes your heart and your soul
While your heart is as high as your soul
Put your heart without your soul into your heart
Give back your heart
Desires for yours have opened up the door
Waiting for them, you're gonna be mine
LOL - And then I should write it in low-level x86 assembly?! LOL - (Btw ChatGPT wrote that code.)
-
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
STTR1 - The original Basic Star Trek game for HP TSB from 1972. Much loved by those that had access or access to ports to other systems.
https://github.com/darkoverlordofdat...hp2k/STTR1.bas
Now that's 'Other Basic' :)
I spent hours playing this when I should have been doing other things :D
-
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
I think I will try to resolve my program's efficiency issues by porting it to VBDOS - which should be slightly more efficient than QBasic and still similar enough to meet my purpose of pulling this off in a hopelessly ancient BASIC dialect.
-
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
@2kaud: naughty naughy! :-)
I did once pull off a maze generator in MBasic running under CP/M 2 in an Altair emulator... LOL - Wasn't that from 1977 or something like that?
-
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
Ah, CP/M that amber goddess!
-
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
Quote:
@2kaud: naughty naughy! :-)
Keep this to yourself - but I still play it (i know, I know...) as I have the Windows simh HPTSB installed together with the software libraries. Also I have simh RSTS and TOP20 installed.... Ah the good old days! :thumb:
http://simh.trailing-edge.com/
http://simh.trailing-edge.com/hp/
http://simh.trailing-edge.com/software.html
-
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
Oooh, interesting! But, how can I keep this to myself when you openly posted it on this very forum? :-)
-
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
-
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
Look, I am not one to talk. I am a guy who fired up an Altair emulator just to write a maze generator in msbasic under cp/m... on an ipad! LOL - For the heck of it! :-)
-
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
Okay, the interpreter has been ported it to vbdos. Memory management has improved. However it is still slow! :-)
Link:
https://github.com/PeterSwinkels/vbd...ck_Interpreter
-
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
Well a port to PowerBASIC is up next on my list. And oh boy, pb has its own quirks! Yay! :-) But it should be much faster if it succeeds though! :-)
-
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
I only have one surviving QBASIC program and that was migrated to QB64 to take advantage of event handling
https://www.vbforums.com/images/ieimages/2024/01/11.png
-
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
Hey is that a screenshot of your QB64 progrram? Also, I tried downloading stuff from your GitHub but Windows Defender interferes when I download your *.exes directly. It probably is falsely detecting threats.
EDIT:
Windows Defender also interferes with *.zip files of your repositories...
EDIT 2:
It claims to have detected Trojan:Win32/Wacatac.B!ml in your Mars widget project.
-
2 Attachment(s)
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
Attached to this post is a very early conversion to PowerBASIC. It's not much faster than before, but PowerBASIC offers a lot of features I haven't tried implementing yet, so that may change. :-)
-
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
Quote:
Originally Posted by
Peter Swinkels
Hey is that a screenshot of your QB64 progrram? Also, I tried downloading stuff from your GitHub but Windows Defender interferes when I download your *.exes directly. It probably is falsely detecting threats.
EDIT:
Windows Defender also interferes with *.zip files of your repositories...
EDIT 2:
It claims to have detected Trojan:Win32/Wacatac.B!ml in your Mars widget project.
Yup! Good ol' Windows Defender, the setup.exe may be old, it is built using setup2go and produces an exe rather than a .msi. A/V tools won't like it. Just download the source and compile yourself. I have Avast and Malwarebytes and Defender (of course) on Windows 7/10/11 and receive no such errors/false positives. I pull/push the code using github desktop.
-
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
Quote:
Originally Posted by
Peter Swinkels
Hey is that a screenshot of your QB64 program?
Yes, that IS a screenshot of the QB64 project, complete with button objects and associated events attached. It is a replacement to the Windows RUN dialog and I operate it on all my systems. Aiming to rewrite it in VB6 in time.
-
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
Quote:
Originally Posted by
yereverluvinuncleber
Just download the source and compile yourself code using github desktop.
Vb6 is giving massive amounts of activex related object errors attempting to compile your project. To be honest I thought your Mars widget project looked interesting and wanted to give it a quick look. At the moment I don't really feel like trying to put much effort in to get it to work because of other priorities.
Anyway, thank you for giving me a glimpse of your project on GitHub, they look really amazing!
PS:
Good luck with your "Run Dialog" project. It looks amazing too! :-)
-
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
Just ensure your project references are selected as per the instructions, that you have RC5 installed and registered. I have checked and updated the instructions to ensure they are correct.
Typically, on a new machine, I clone using github, install VB6 and it just compiles straight away. Don't expect it to run without following the instructions. There are dependencies and they are essential. Without them errors will inevitably appear.
-
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
Yereverluvinuncleber, thank you for your advice, I will keep that in mind for future reference. : -)
Now, unless anyone has any other suggestions I am going to try implement a byte array instead of a string for to emulate memory, that might resolve the speed issue.
-
1 Attachment(s)
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
Okay, INCR/DECR statements have been implemented where applicable and a byte array makes the code a heck of a lot more efficient! :-) The program appears to be running slightly faster now.
And:
If anyone knows anything about dynamic arrays (REDIM PRESERVE) in PowerBASIC 3.5 for MS-DOS, please reply. PowerBASIC gave me a hard time trying to implement these as an alternative for the string I am using to keep track loop addresses. Yes, I used a string because I saw no other reasonable method of simulating a list in QuickBASIC. Anyway I tried fiddling the array's scope such as making it global instead of local to procedures and passing it around as a parameter. How exactly did PowerBASIC give me hard time? Mostly by simply freezing or throwing some error about string handles concerning a string variable that happens to be in the same procedure as the dynamic error. My guess is the stack is somehow getting trashed. I deleted the code concerning the dynamic array, but I could easily rewrite it if anyone would like to see it. Still, if anyone knows about dynamic arrays in PowerBASIC, your help would be much appreciated! :-)
-
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
Okay, seeing as FRE(-3) (the amount free of stackspace) shoots into the negatives before the program freezes while trying to resize an array it is most definitively the stack being trashed. Now I could use the $STACK directive to adjust the amount of available stack space, but this will cost me memory elsewhere. Also, I am not about to implement a complicated mechanism that attempts to dynamically adjust the stack size. In short, REDIM PRESERVE is probably useless in my case. Unless someone has any suggestions, I am going to forget about using it for my interpreter.
-
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
Unless I think of any other changes I am done here for now:
https://github.com/PeterSwinkels/Pow...rpreter/upload
-
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
Okay, I implemented user defined types and dynamic arrays in the vbdos version. It should be faster now. Link to GitHub is somewhere in this thread.
-
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
-
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
@2kaud, that's the PowerBASIC version! - LOL - I was referring to the link in post #16.
-
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
Quote:
Originally Posted by
Shaggy Hiker
That's right. You SHOULD be writing a Rockstar interpreter.
Now this I would love to see!
-
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
LOL - I would like to see myself pulling that one off without suffering a mental breakdown! I might post another tirade!
Seriously, I think a Rockstar interpreter could be done in vb.net or even vb6 but probably not in older BASICs, especially not me.
If someone thinks of a more realistic challenge, I might consider it just to prove a point and for the heck of it. :-) My only constraint is, that it should be feasible in a BASIC for Dos.
-
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
@jdelano: Amber godess eh? Hmmm, I remember my dad's first computer having an amber screen and it ran MS-DOS 3.3 or whatever, ah the memories. Can you believe getting a pc with color graphics was something amazing back then? LOL
-
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
Yeah it was. It has been a fun ride, thats for sure.
-
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
We had an original IBM PC with monochrome display and just one floppy drive (no hard drive - that came with the XT) and it used PC-dos 2.0 and not ms-dos.
-
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
Indeed, so many memories! :-)
-
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
I came across a free copy of the book "Basic - A Self-Teaching Guide 2nd Edition" tonight. Published in 1978. Good stuff.
-
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
Ah, that reminds of the times before I got to know the internet during 1995. How I had to make do with the built-in help in programs (if any), the few books in the library and bookstores about BASIC, sample programs, and what little I could gather from other people. I learned a lot through trial and error back then. Even the early internet wasn't all that great, first of all my parents had to pay for each minute I was online occupying the phoneline and there where only a few dozen personal sites with limited information. One of the better websites for BASIC used to be QBasic.com, but even there resources were limited. That site also had a pretty good forum, however there were many flamewars and users not being particularly helpful or friendly. One of the many reasons we now got forums where you have to register. And who remembers Neozones btw? And before I forget unlike today those old forums were vulnerable to HTML code injections. You could format your post or mess up the entire forum that way! :-)
Here is one of the very few 90's style BASIC programming personal websites that is still up and running: https://www.phatcode.net/ - Even the forum had some activity this month! LOL
-
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
Before moving into PC programming, I developed applications for mini-computers (Wang, Dec, DG, Systime and Pick) in various Basic dialects (and Fortran/Assembler for Dec). But when we moved to PC we developed in c, pascal and assembly (using Microsoft and Borland compilers/assemblers - I preferred Borland at the time) but not Basic. I can't really remember why but conversations around pc Basic being just for 'hobbyists' come to mind.... I then moved to C++. I think in total I've written about 3 - 4 programs in GW Basic/Qbasic which if I remember correctly were 'quick ports' of existing Basic programs from a mini-system.