A big thank you as usual for this snappy release, played briefly with ERROR$, CAPTURE and SOUNDGROUP(), all is working well so far (including 2^3^4 :-)), excellent work!
FrenchBear
Recent community posts
Totally impressed by the extent of the sound support, it's a far cry from the original GW-BASIC "PLAY string" and "SOUND freq, duration"...
As usual thanks for all the small updates making (my) programmer's life easier :-) [though I've noticed that TB ^ operator is still right-associative contrary to all Microsoft Basic versions up to VB.Net]
Call me totally impressed -- Calculation of 10000 decimals of Pi went from about 30s on version 2.4.1 to 8.2s in 2.5.4, that's no simple optimization -- especially considering that before the JIT, the same code was running for about 240s (4min 20s).
And thanks for all other fixes, top notch reactive service, as usual!
Thanks for all the fixes in this interim release. Now keyboard keys beyond ASCII enter correct CP437 characters, the "é" key on a French keyboard now produces a é and not a θ anymore, much better !
A microsopic detail -- You should check for modifiers keys (at least on Windows) when testing Insert key to toggle insert/overwrite mode: Shift+Ins is an oooooold windows Shortcut equivalent to Ctrl+V/Paste. It's actually useful in some terminal emulators such as Putty or Home Assistant terminal which doesn't interpret Ctrl+V as a paste operation but just consider it as a control character, while Shift+Ins does paste clipboard, but in TB, Shift+Ins is processed as Ins
*Very* impressive performance gains with release with 2.5! I've noticed that on pure integer calculations (ex: find 10000 decimals of pi using an integer-only algorithm) the speed gain is 7-8x, but definitely impressive! I'll reconsider the option of a JIT for my own interpreters!
I've also noticed that NeonDescent example uses SPRITEOFF statement that is not documented, unless I missed it... Other secret statements ? ;-)
Thanks for release 2.4.1, with many useful improvements for development, as usual! I intend to test/play with it on Monday, will keep you posted.
XREF and PROFILE commands are fantastic and totally useful!
And I like the CTRL+L as a quick shortcut to clear the screen, thanks!
One little thingy I've noticed, GW-Basic allowed & as a variant for &0 for octal numbers, not ThoreauBASIC. Not that we really use octal numbers anymore...
Hi
I've a problem with WHILE stack (I've not tested but it's likely the same issue with FOR stack) when exiting prematurely a WHILE..WEND loop using a branching statement that transfers execution outside the loop (GOTO, RETURN, possibly RESUME), that is, not going explicitly through WEND statement. It appears that current WHILE frame is not popped from the stack and remain active, and that could cause a WHILE stack overflow quickly (WHILE stack size is currently 64 slots).
Here is a simplified example of my case, I've a subroutine in line 100 that will skip lines in file until an empty line has been found:
5 OPEN "data.txt" FOR INPUT AS #1
10 FOR i=1 to 100
20 GOSUB 100 ' Read file up to next empty line
30 NEXT
40 END
100 WHILE NOT EOF(1)
110 LINE INPUT #1, l$
120 IF L$="" THEN RETURN ' Found
130 WEND
140 PRINT "EOF reached, no empty line found!"
150 STOP
When running this on a file containing more than 100 empty lines, it ends with "Out of memory in 100", and looking at interpreter state in Thoreau machine explorer:
Stacks: GOSUB 1, FOR 1, WHILE 64, handlers 0, IF 0
Since there is no "EXIT WHILE" or similar statement in legacy basic to provide a clean way to exit prematurely, a forced transfer of execution outside the loop is more or less the only way to quit the loop...
Thanks for all the fixes and improvements in 2.3.1, great! I really like to power of selective-evaluation with IIF, it really make user functions more useful as indexes or range guards. (looking at the strings in ThoreauBASIC.exe I've noticed a "Too many DEF FN" message, so don't abuse of good things!)
I've just noticed a feature I only used a few times in GW-BASIC, it's a semicolon just after INPUT statement, as in:
10 INPUT ;"A=",A
20 PRINT "^2="; A*A
the semicolon after input keeps the cursor location on Enter and does not move to next line. Nothing very important though.
And another missing feature that I can leave without is the possibility to list multiple variables in NEXT statement, as in NEXT K,J,I but for some reason I never liked it.
A wish, if I may -- A stop statement should print line number, such as "Break in 9760" rather than just "Break", similar to "Breakpoint in 9760" with Break command. When debugging complex code, I use Stop statements and breakpoints, and now knowing which Stop has been reached is annoying. Ok, I can run it with Tron, but it's not always convenient...
Alternately, if Thoreau Machine Explorer had a way to display current call stack and break location in break mode, that would also be convenient!
While on this topic, breakpoints list is not cleared when loading a new program. At first I'd called that a "bug", but repeatedly loading the same program edited in an external editor during a debug session and keeping the list of breakpoints is convenient... I'd now call that a "feature" :-)
I've started playing with complex variables (I'm more used to matrix transformations of coordinates than using quaternions or octonions, but I'll definitely try it), and I've noticed than ATN doesn't wot work with complex, that's a bit too bad, I was ready to implement complex ASN and others using atn:
DEF FNASN@(z@) = ATN(z@/SQR(1-z@*z@))
Ideally I would prefer a simple direct calculation and avoid Taylor/McLaurin series in Basic, Newton iterations (I wrote several implementations of CORDIC algorithm, but complex generalization is not simple, and I want to avoid iterations if possible)
---- forget it, searching on the Web how to compute ascsine without arctangent, I've found I can use complex log: arcsin(z) = -i.ln(i.z + √(1 - z²))
DEF FNASN@(z@)=CPLX(0,-1)*LOG(CPLX(0,1)*z@+sqr(1-z@*z@))
and it works, so it's Ok without complex ATN (and it avoids the problem of z=+/-1 with ATN formula)
I've noted an inconsistent management of ' char to introduce a comment. For instance, in the program:
10 a=0 ' Zero
20 print "_"; ' Empty cell
The comment on line 10 is accepted, but the one on line 20 causes "Syntax error in 20"...
While on the parser topic, I wrote by mistake "while nor eof(1)" , and nor not being declared is 0, so the loop is skipped silently, while I would have preferred a "Syntax error".
Ok, I'm never happy, when I get a Syntax Error, I don't want it, and when I don't get one, I want it :-)
Hi! A suggestion (nothing urgent or important): accept tab characters CHR$(9) in source code while loading, and either replace them with spaces (historically a tab every 8 columns, modern version is rather 4 columns).
Currently list shows tab as a small circle which is not great visually
I use external text/source code editors to edit large source files, and they tend to insert tabs (Ok, I can reconfigure them, but I'd prefer keep tabs in the general case)
Hey! Another wish if I may -- I was trying to revive some old Basic games, and I noticed that on Windows, INKEY$ returns a CHR$(0) for all 4 direction keys. I know I can use alphabetical keys for directions, games diamond or vi movement keys hjkl (yes, I'm that old...) but it would be nice to get different codes for the arrows to use them too!
I've tried some old GWBasic code of mine dating back to the early eighties, and I ran in a problem related to string memory garbage collection. My program itself computes decimal development of fractions, nothing really interesting there, but when running extended tests, I got an "Out of string space" error, while at any point in time my code never actually stores more than few strings with less than 1000 characters.
Here is an ultra simplified variant showing the issue:
Thoreau BASIC v2.
16,642,736,128 bytes free.
Ready.
load "outofmem
Ready.
list
10 for n=1 to 1000000
20 s$=""
30 for i=1 to 100
40 s$=s$+"12345678"
50 next
60 next
Ready.
run
Out of string space in 40
Ready.
? n, fre(0)
205975 480
Ready.
It repeatedly build a 800-char string by accumulation, then clear the string and loop.
I don't know how dynamic memory is managed internally (reference counting or dynamic reference exploration) but I would have expected that freed string memory would be reclaimed/recycled at some point.
It's not critical since it's just stress testing/performance testing part of my code that's impacted, just wanted you to know.
If I may express a wish, at some point it would be great to have the counterpart of LOADBMP to save current graphic screen (or graphic window?) into a BMP file. Since we've direct access to FrameBuffer memory, I can write the code that'll generate a BMP header and its image payload, but that's pretty dirty code, a ready-to-use SAVEBMP would be nice :-)
I've seen that, that's reactive, thanks!
Reading the doc 2.1 right now, TXTWINDOW example is "TXTWINDOW 0,20,79,29" but this causes "Illegal function call" error, since cols/rows are base 1, I guess it should be "TXTWINDOW 1,21,80,30". And on Windows, Files,W/Dir,W adds an extra new line at the end of each line (and I've learned it's not a good idea to run DIR,S on the root folder of a drive containing several hundred thousands of files since it can't be interrupted...)
Playing with V2, I've noted a small difference with GWBasic for the command AUTO. In GWBasic, if the generated line number is already used, I think there was a star displayed after the number, and hitting enter preserved existing line.
In TB, there is no visual hint that the generated line number is already used, and hitting Enter erases this line.
Thanks for the documentation and the Web site!
A detail: in GWBasic, RUN command can be followed by a line number (or a filename), in current TB implementation, RUN line ignores line and starts program from the beginning (but GOTO line works, so no problem).
I've tried to speed up Mandelbrot example with little changes (it's symmetric about X axis, divides calculations by 2, and quickly eliminate points in the main/secondary bulb to drop lots of useless calculations):
Shared
Great! I've been using GWBasic a lot and its variants since the early 1980's, this brings back lots of memories... At least a modern, 64-bit version of Basic, compatible with original GWBasic, without drama or weird new extensions. I've been able to load an execute old GWBasic programs without loading a VM running a 32-bit Windows able to run 16-bit code, and they worked on first run, fantastic! My only problem is old habits, I used to type LOAD "Program without closing quote not specifying .bas suffix, I have now to type LOAD "Program.bas", but I'll adapt.