Friday, April 24, 2026

🎉 New version of BASIC Anywhere Machine

 

Changes / Enhancements

Summary

  • Rename NVL$ to FNEV
  • "EVAL" clause removed from GOTO, GOSUB and RESTORE statements
  • INPUT now allows expressions as the prompt argument

Details

Rename NVL$ to FNEV

I don't know what I was thinking.  "NVL" is a proprietary function name originating from Oracle SQL.  I've got no business, I think, calling my function that.

So, I've decided to rename NVL$ (which I was using to mean "No VaLue") to FNEV (First Non-Empty Value).

This function can be used with strings and with numbers.  (That's why the function name does not have a "$" suffix.)

For the immediate future, this function accepts two parameters.  If the first parameter is not empty ( "" is an empty string; 0 is an empty number), then the first parameter is returned.  Otherwise, the second parameter is returned.

Someday, I will change this function to allow more parameters, and set it up so that it returns the first "non-empty" value found.


"EVAL" clause removed from GOTO, GOSUB and RESTORE statements

The EVAL keyword was intended to indicate a parameter that is an expression and not a line identifier/number.

Really, parentheses are enough to indicate an expression is being provided instead of a line identifier/number.


(The syntax diagrams for GOSUB and RESTORE are the same.)

INPUT now allows expressions as the prompt argument




Saturday, April 18, 2026

🖥 Orbs

EDIT 2026-04-19

Apparently, there are many "very similar" versions of this program "out there."

I think it would be a stretch to believe that all of these programs ought to be attributed to one person.  Anybody, at any time, can have an "original thought" that is completely independent from an identical "original thought" by somebody else in a different place and a different time.

When somebody shares a program, I assume it is their original code, and any port/mod of mine will give credit to the author of the source code I ported.  I'm not going to spend time investigating the origins of any program I find on the web.  (Well, if it is easy for me to give credit to all the shoulders on which I'm standing tall, I'll do that because I do enjoy doing that.) 

Some may believe that all programs similar to this one should be attributed to Jan Vibe as author of a similar program written in BBC BASIC.  I leave it up to you:  credit Jan Vibe for my port/mod if you wish.  Regardless, it would seem Jan Vibe made some significant contributions, which you might find worth researching.


This program is a port and mod of a BazzBasic program by EkBass, shared by EkBass via the GotBASIC discord server.

Note that I've setup some random "color randomness" to each drawing cycle loop (which generates a finite number of orbs each loop to create interesting patterns because of small empty spaces with no orbs.)























Friday, April 17, 2026

📚 Some ado about DONOTHING

For whatever reason, the "NOT" keyword has always been a kind of cognitive stick in my wheels.

"IF NOT ... THEN" just annoys the daylight out of me.

So, since I'm maintaining my own version of BASIC, why on earth would I put up with that?  Life is too short to put up with irritants.

Hence "DONOTHING".

I've been mocked for adding that statement, and I've received all kinds of suggestions on how to write code in such that I can avoid adding "DONOTHING" to my version of the BASIC programming language.

Pff.  I've been hobby-programming for 38 years, and I've been programming professionally for the last 30 years.  In that time, I've cranked out enough code to figure out what works for me and what doesn't.

Very likely, I'm the only one who would ever use the statement, and that's fine.  It is there for me.

Here's an example of DONOTHING, in a very silly program that shows a few other little nuggets about BAM's BASIC implementation:

SUB OpenTheDoor()
  LET DoorIsClosed = NOT TRUE
END SUB

SUB CloseTheDoor()
  LET DoorIsClosed = TRUE
END SUB

FUNCTION StatusOfDoor$()
  StatusOfDoor$ = "The door is " + IFF( DoorIsClosed, "closed.", "open.")
END FUNCTION

SCREEN _NEWIMAGE( 320, 24, 0 )
CALL OpenTheDoor()
PRINT StatusOfDoor$()
SLEEP 1
IF DoorIsClosed THEN DONOTHING ELSE CALL CloseTheDoor()
PRINT StatusOfDoor$()

Oh sure, we would not need DONOTHING if the program had a "DoorIsOpen" perspective.  As in "is the door open" instead of "is the door closed?"  It all depends on how you like to think of things.  For me, I prefer ask a question that has the state I want the door to be in, rather than ask a question with the state I do NOT want the door to be in.

Kind of like "have you taken your medicine?" versus "have you NOT taken your medicine?":

- "Have you not taken your medicine?"
- "Yes"
- "Yes what?"
- "Yes, I have not taken my medicine"
Ugh...





🔥 Ixnay "Code Insertion" buttons, eh?

Re: 🚧 In the Works: "Code Insertion" buttons

In retrospect, having now taken a long break from enhancing BASIC Anywhere Machine, I'm finding myself not wanting to finish this particular feature.

Aside from simply losing interest in that feature, I'm realizing a few problems:

  • Less importantly (because a work-around could be built), I do not like the amount of real-estate (screen space) the feature is taking.  This is not a huge issue on a large desktop display, but it gets problematic on a smaller display (a laptop or tablet.)
    • Although I know how I could design a proper interface to handle smaller displays ("no biggie" to do), designing/programming that just does not turn my crank.
  • More importantly, it is not something I want to maintain going forward if/when I update BAM statements/functions/etc.  It just does not sound like a fun thing to do.

Wednesday, April 15, 2026

📚 About Variable Scoping in BAM

Variable Scoping describes where a variable is accessible, or available, within a program.

A BASIC Anywhere Machine program may declare (explicitly or implicitly) variables in:

  • the main part (aka at a "global" level) of a program
  • any subroutine / function  (aka at a "local" level)  in a program

Aside:

  • A variable is implicitly declared via an assignment statement (whether using the LET keyword or not)
    • examples:  "LET a = 1", or simply "a = 1"
  • A variable is explicitly declared via a DIM statement (or via the synonymous VAR statement)
    • examples: "DIM a = 1", "DIM a AS INTEGER", "VAR a = 1", "VAR a AS INTEGER"

Variables declared in the main part of the program are available to all parts of a program (i.e. the "main" part, every subroutine, and every function.)  However, if a subroutine/function declares a local variable with the same name as a variable at the global variable, that subroutine/function no longer has access to that global variable.  (BAM has no way of "qualifying" a variable name, so there is no way to tell a subroutine/function that a reference to a variable is for the global one versus the local one.)


Variables declared in a subroutine / function (again, whether explicitly or implicitly) are "local" variables.  Those variables only exist in, and are only available to, the subroutine/function in which they are declared.


However, if the main program declares (explicitly  or implicitly) a variable with the same name as the subroutine, then a subroutine / function must explicitly declare a variable with the same name for the subroutine / function to have a distinct local variable.

Implicit variable declarations in a subroutine/function cause problems:


In a subroutine/function, do make it a practice to always explicitly declare variables with a "DIM" (or with the synonymous keyword "VAR").  It is a very good practice:


Just for the giggles, notice how a subroutine/function can reference a global variable before declaring a local variable with the same name.


ASIDE: Just to nip this in the bud in case you are thinking about it.  NO, you cannot have conditional declaration of a variable in a subroutine/function.  Although you won't get an error message: the process of transpiling the BASIC program to javascript always translates a DIM statement into a declaration of a javascript variable, regardless of any conditional statement:



A problem: Now that we know how variable scoping works in BASIC Anywhere Machine, how do we go about making a main program's variable(s) private, so that it is impossible for any subroutine/function to the main program's variable(s)?

Modern programming languages have built-in mechanisms to handle the task.  For example, in QB64 Phoenix Edition, all globally declared variables are private (only available to the main program) unless they are explicitly declared as available to subroutines/functions via the "SHARED" keyword used in a "DIM" statement (click on the keywords to view related documentation in the QB64pe wiki).

In BASIC Anywhere Machine, we can simulate "private" variables by putting the main program in a subroutine, and calling that subroutine from the main program (the main program might do nothing more than call that subroutine) :








Tuesday, March 31, 2026

🖥 Modular Multiplication Circles

This BAM program is a port and mod of a PC-BASIC' program by Kurt Moerman which he shared with' the BASIC Programming Language Facebook Group via this post.



🎉 New version of BASIC Anywhere Machine

  New version of BAM Updated documentation Previous version of BAM Previous release notes Discuss:  BAM Reddit  or  BAM Discord  or BAM Café...