After creating Craft Basic (a direct interpreter) and FTCBASIC (a BASIC to fasm compiler), I had theories of how to create a tokenized interpreter. With the need for speed in mind, I decided to try.
The first successful test run was at my local truck stop (middle of nowhere AZ). Making good use of the free power, air conditioning, and cheap all beef gas station hot dogs with extra bbq sauce, Commando Basic was born. It's not as fast as Just Basic or Yabasic, but it's much faster than Craft Basic.
I've been working on this for a while with much help from my wife. The two of us are a team that makes Lucid Apogee.
This alpha version release includes an IDE, tokenizer, interpreter, chm help file, and 96 examples.
There's still much to be done with this project, but I felt it was time to share it and hope for feedback.
https://www.lucidapogee.com/index.php?page=commandobasic
Haha I can eat bbq sauce hotdogs for breakfast, lunch, or dinner.
:D
BAM has GWBasic like syntax right? My languages are more like tiny basic with some extra features. It's definitely BASIC, but done differently. RPN expression evaluation is the main feature. The infix is translated to postfix during tokenization to produce fairly fast executing scripts.
Link to 'installer' and 'portable' versions of 'commando' do not seem to work. Displayed an 'advertise' page instead.
Attached is a screenshot of the page you're referring to. There's an ad served with my download. I do this with a script I wrote in php. It allows me to record date, time, ip, and other info about downloads while simultaneously serving a first party ad from my own server.
The result is I get statistics about how my products are doing while also funding my site. As a bonus, the script works as an anti adblocker. Adblock must be disabled for the download to start.
If adblock is disabled and it still doesn't start automatically, select the "If the download doesn't start in a few seconds, click here."
It's very similar to other sites with download management systems. The way it works is when you click the download, it points to page with two frames. One frame tracks and starts the download while the other displays the ad. The one that displays the frame uses another frame to start the download.
I have added another download mirror to itch.io for an ad free download experience (although this one will nag for a donation).
https://lucidapogee.itch.io/commando-basic/purchase
This link offers both the installer and portable version.
Meanwhile... I just fixed a small bug while working on completing a Rosetta Code task.
The problem was the prime function was returning 0 and 1, rather than 0 and -1. This prevented it from playing nicely with not(). I got it working now and have already uploaded the update including the new example. I will have to go back and add this fix to Craft Basic as well. Seriously an amateur mistake, I know... lol
New example, based from Rosetta Code task:
'https://rosettacode.org/wiki/Circular_primes
let p = 2
let s = 1
do
let n = int(log(p) / log(10))
let m = 10 ^ n
let q = p
let r = 1
for i = 0 to n
if q < p or not(prime(q)) then
let r = 0
break i
endif
let q = (q mod m) * 10 + int(q / m)
next i
if r then
print p, " ",
let l = l + 1
endif
let p = p + s
let s = 2
loop l < 19
pause
Quote from: Lucidapogee on Aug 24, 2023, 07:36 PMAdblock must be disabled for the download to start.
Thanks for the itch link. It'll be a very, very cold day in hell before I disable adblock on today's internet for
anyone. I value my online safety too much for that.
Looking forward to testing this.
Yep. Adblocker stopped it... Used another browser and it downloaded just fine.
"Took it out for a spin." and it runs quite well. The only issue so far is that I cannot hear any sound or music. Probably because I use Linux and must run Commando using Wine.
Quote from: ZXDunny on Aug 25, 2023, 09:29 AMQuote from: Lucidapogee on Aug 24, 2023, 07:36 PMAdblock must be disabled for the download to start.
Thanks for the itch link. It'll be a very, very cold day in hell before I disable adblock on today's internet for anyone. I value my online safety too much for that.
Looking forward to testing this.
I understand what you mean. For my security, I use NoScript on Seamonkey. Online advertising and marketing is a funny business to be in. In one way, I love coding ad tech, but in another way it gets a bad reputation. I gotta do my best to keep on doing what I am good at. I have run several ad networks in the past, so it's a natural part of how I do things.
Quote from: johnno56 on Aug 25, 2023, 01:37 PMYep. Adblocker stopped it... Used another browser and it downloaded just fine.
"Took it out for a spin." and it runs quite well. The only issue so far is that I cannot hear any sound or music. Probably because I use Linux and must run Commando using Wine.
Awesome. I didn't know it would run under Wine. That's good to know. The sound is just a TONE command using the BEEP from windows api. Maybe that's not supported under Wine.
I really need to add more sound support to Commando Basic. I plan to add wav file support by the time version one is released.
Quote from: CharlieJV on Aug 25, 2023, 01:57 PMYeah, my mind is like an unleashed puppy: "johnno56 goes Commando".
My kind of product advertising: "If one goes commando, one should be armed with the right BASIC!"
Yeah, my dirty sense o' haha, I get honestly...
I was wondering if anyone would make Commando jokes. There's hope left for the world. ;D
This alpha version release still has much work to be done. I was up late last night working on strings.
Commando Basic has minimal string handling, but it's non standard to other BASIC languages. Still, I want it to be capable of getting things done. The way it works is string parsing is done with commands instead of functions. The commands accept various parameters. Some of the commands will accept either literal strings or string variables interchangeably.
I went through and double checked everything. Found and fixed some mistakes. Also updated the keywords to be a bit more readable.
The reason I have chosen this path for string handling is that like Craft Basic, Commando Basic is essentially a minimal Tiny Basic interpreter. My languages are true to traditional BASIC syntax up to a certain point. Everything else is bonus features.
As a result, I see Commando Basic as like a modern ASIC (modern as it will run on newer machines).
I will be updating the download links shortly to include the changes I am making. A new example game will be included. It's an interactive fiction game I am using to test the string handling.
I have updated the download links with the stuff I mentioned above.
A new game has been included with the download. It's called Desert of Skulls Adventure. The game is interactive fiction and demonstrates the rudimentary string handling routines of Commando Basic.
'Desert of Skulls Adventure
'by Gemino Smothers 2023
'www.lucidapogee.com
define areax = 4, areay = 5
define lastareax = 4, lastareay = 4
define areasx = 8, areasy = 8
define hydration = 15, gourdfull, locked = 1, outlaw = 1
define keys, rope, gourd, bullets, derringer, temp, boulder
define space, character, characters, check, shortcheck, errorflag
define cmdline$, command$, parameters$, cmpstr$
gosub intro
do
gosub parser
gosub commands
loop hydration >= 1
print "You are too thirsty and unable to continue... Game over!"
tone 100, 1000
pause
end
sub intro
cls
print "Desert of Skulls Adventure _____"
print "by Gemino Smothers 2023 / \"
print "www.lucidapogee.com | () () |"
print " \ ^ /"
print "Type help at any time. |||||"
print " ||||| "
print "Press any key to begin..."
pause
cls
print "You suddenly awaken to the sound of coyotes yapping."
print "How did you get here? Last you remember", comma, " you were in a small town."
print "You were travelling in search for a new home and decided to rest there."
print "Unfortunately", comma, " the town was full of outlaws and you were knocked out."
print "Now you must find your way and continue your adventure..."
gosub areadescription
return
sub parser
do
loopuntil key <> 13
print "What would you like to do? ",
gosub getinput
print
find space, cmdline$, " "
if space then
let character = space - 1
cut command$, cmdline$, 1, character
let character = space + 1
length characters, cmdline$
cut parameters$, cmdline$, space + 1, characters - space + 1
else
copy command$, cmdline$
endif
return
sub commands
let lastareax = areax
let lastareay = areay
let errorflag = 1
gosub lookcommand
gosub northcommand
gosub eastcommand
gosub southcommand
gosub westcommand
gosub examinecommand
gosub takecommand
gosub usecommand
gosub talkcommand
gosub inventorycommand
gosub helpcommand
gosub byecommand
if errorflag then
print "Invalid command.", newline
endif
return
sub areadescription
print newline, "(hydration: ", hydration, ")"
let boulder = 1
if areax = 4 and areay = 1 then
gosub sands
endif
if areax = 5 and areay = 1 then
gosub sands
endif
if areax = 6 and areay = 1 then
gosub skeleton
endif
if areax = 2 and areay = 2 then
gosub barn
endif
if areax = 3 and areay = 2 then
gosub house
endif
if areax = 4 and areay = 2 then
gosub roads
endif
if areax = 5 and areay = 2 then
gosub sands
endif
if areax = 6 and areay = 2 then
gosub sands
endif
if areax = 8 and areay = 2 then
gosub sands
endif
if areax = 2 and areay = 3 then
gosub crops
endif
if areax = 3 and areay = 3 then
gosub crops
endif
if areax = 4 and areay = 3 then
gosub roads
endif
if areax = 5 and areay = 3 then
gosub sands
endif
if areax = 6 and areay = 3 then
gosub sands
endif
if areax = 8 and areay = 3 then
gosub sands
endif
if areax = 2 and areay = 4 then
gosub crops
endif
if areax = 3 and areay = 4 then
gosub crops
endif
if areax = 4 and areay = 4 then
gosub roads
endif
if areax = 5 and areay = 4 then
gosub roads
endif
if areax = 6 and areay = 4 then
gosub sands
endif
if areax = 8 and areay = 4 then
gosub sands
endif
if areax = 2 and areay = 5 then
gosub roads
endif
if areax = 3 and areay = 5 then
gosub roads
endif
if areax = 4 and areay = 5 then
gosub crossroad
endif
if areax = 5 and areay = 5 then
gosub sands
endif
if areax = 6 and areay = 5 then
gosub sands
endif
if areax = 8 and areay = 5 then
gosub sands
endif
if areax = 4 and areay = 6 then
gosub roads
endif
if areax = 5 and areay = 6 then
gosub sands
endif
if areax = 6 and areay = 6 then
gosub pileofskulls
endif
if areax = 7 and areay = 6 then
if outlaw = 0 then
gosub sands
else
gosub robbery
endif
endif
if areax = 8 and areay = 6 then
gosub sands
endif
if areax = 1 and areay = 7 then
gosub spring
endif
if areax = 2 and areay = 7 then
gosub cliff
endif
if areax = 3 and areay = 7 then
gosub sands
endif
if areax = 4 and areay = 7 then
gosub roads
endif
if areax = 5 and areay = 7 then
gosub sands
endif
if areax = 6 and areay = 7 then
gosub sands
endif
if areax = 8 and areay = 7 then
gosub sands
endif
if areax = 4 and areay = 8 then
gosub traveller
endif
if areax = 5 and areay = 8 then
gosub sands
endif
if areax = 6 and areay = 8 then
gosub sands
endif
if areax = 8 and areay = 8 then
gosub greatlake
endif
if boulder then
gosub boulders
endif
print
return
sub lookcommand
compare check, command$, "LOOK"
compare shortcheck, command$, "L"
if check or shortcheck then
let errorflag = 0
gosub look
endif
return
sub northcommand
compare check, command$, "NORTH"
compare shortcheck, command$, "N"
if check or shortcheck then
let errorflag = 0
if areay > 1 then
let areay = areay - 1
print "You travel North."
else
print "You are unable to travel North."
endif
gosub areadescription
endif
return
sub eastcommand
compare check, command$, "EAST"
compare shortcheck, command$, "E"
if check or shortcheck then
let errorflag = 0
if areax + 1 <= areasx then
let areax = areax + 1
print "You travel East."
else
print "You are unable to travel East."
endif
gosub areadescription
endif
return
sub southcommand
compare check, command$, "SOUTH"
compare shortcheck, command$, "S"
if check or shortcheck then
let errorflag = 0
if areay + 1 <= areasy then
let areay = areay + 1
print "You travel South."
else
print "You are unable to travel South."
endif
gosub areadescription
endif
return
sub westcommand
compare check, command$, "WEST"
compare shortcheck, command$, "W"
if check or shortcheck then
let errorflag = 0
if areax > 1 then
let areax = areax - 1
print "You travel West."
else
print "You are unable to travel West."
endif
gosub areadescription
endif
return
sub examinecommand
compare check, command$, "EXAMINE"
compare shortcheck, command$, "EX"
if check or shortcheck then
let errorflag = 0
if areax = 2 and areay = 2 then
gosub examinebaleofhay
endif
if areax = 3 and areay = 2 and locked = 0 then
gosub examinerange
gosub examinebed
gosub examineshelf
endif
if areax = 2 and areay = 3 then
gosub examinecrops
endif
if areax = 3 and areay = 3 then
gosub examinecrops
endif
if areax = 2 and areay = 4 then
gosub examinecrops
endif
if areax = 3 and areay = 4 then
gosub examinecrops
endif
if areax = 6 and areay = 1 then
gosub examineskeleton
endif
if areax = 6 and areay = 6 then
gosub examinepileofskulls
endif
print
endif
return
sub examinebaleofhay
compare check, parameters$, "BALE OF HAY"
if not(check) then
compare check, parameters$, "BALE"
endif
if not(check) then
compare check, parameters$, "HAY"
endif
endif
if check then
if keys then
print "There's nothing of interest."
else
print "There's a rusty old key in the hay."
endif
endif
return
sub examinerange
compare check, parameters$, "RANGE"
if check then
print "The range hasn't been used recently."
endif
return
sub examinebed
compare check, parameters$, "BED"
if check then
print "The bed is old", comma, " yet looks cozy."
endif
return
sub examineshelf
compare check, parameters$, "SHELF"
if check then
print "The shelf contains the following items..."
if not(rope) then
print "rope"
endif
if not(gourd) then
print "gourd"
endif
endif
return
sub examinecrops
compare check, parameters$, "CROP"
if check then
print "There's doesn't appear to be anything useful here."
endif
return
sub examineskeleton
compare check, parameters$, "SKELETON"
if check then
if derringer then
print "There's only bones and tatters."
else
print "A dirty", comma," rusty", comma, " old derringer is in the skeleton's hand."
endif
endif
return
sub examinepileofskulls
compare check, parameters$, "PILE OF SKULLS"
if not(check) then
compare check, parameters$, "SKULLS"
endif
if check then
print "The stench is terrible."
print "Ravens circle the area."
print "There's nothing of interest."
endif
return
sub takecommand
compare check, command$, "TAKE"
compare shortcheck, command$, "T"
if check or shortcheck then
let errorflag = 0
if areax = 2 and areay = 2 and keys = 0 then
gosub takekey
endif
if areax = 3 and areay = 2 and locked = 0 and rope = 0 then
gosub takerope
endif
if areax = 3 and areay = 2 and locked = 0 and gourd = 0 then
gosub takegourd
endif
if areax = 6 and areay = 1 and derringer = 0 then
gosub takederringer
endif
endif
return
sub takekey
compare check, parameters$, "KEY"
if check then
let keys = 1
print "You take the key.", newline
endif
return
sub takerope
compare check, parameters$, "ROPE"
if check then
let rope = 1
print "You take the rope.", newline
endif
return
sub takegourd
compare check, parameters$, "GOURD"
if check then
let gourd = 1
print "You take the gourd.", newline
endif
return
sub takederringer
compare check, parameters$, "DERRINGER"
if check then
let derringer = 1
print "You take the derringer.", newline
endif
return
sub usecommand
compare check, command$, "USE"
compare shortcheck, command$, "U"
if check or shortcheck then
let errorflag = 0
if gourd then
gosub usegourd
endif
if areax = 3 and areay = 2 and keys and locked then
gosub usekey
endif
endif
return
sub usegourd
if gourdfull then
let hydration = hydration + 5
print "You drink the water from your gourd."
print "It's warm", comma, " but you still feel refreshed.", newline
let gourdfull = 0
else
print "The gourd is empty. You have no water!", newline
endif
return
sub usekey
let locked = 0
print "After a short struggle", comma, " you manage to unlock the door.", newline
return
sub talkcommand
compare check, command$, "TALK"
compare shortcheck, command$, "TA"
if check or shortcheck then
let errorflag = 0
if areax = 4 and areay = 8 and bullets = 0 and gourd and gourdfull then
gosub talktotraveller
endif
endif
return
sub talktotraveller
print "Traveller:"
print "Hello, may you please share some water with me."
print "I am so very thirsty and cannot go on without a drink.", newline
print "Will you offer the traveller a drink of water?"
print "Yes or no? ", newline
gosub getinput
compare check, cmdline$, "YES"
compare shortcheck, cmdline$, "Y"
if check or shortcheck then
let gourdfull = 0
let bullets = 1
print "You share the water from the gourd with the traveller.", newline
print "Traveller:"
print "Thank you for helping me. I thought my life was over!"
print "Here's some bullets. They are of no use to me and are"
print "all that I have to repay you."
endif
print
return
sub inventorycommand
compare check, command$, "INVENTORY"
compare shortcheck, command$, "I"
if check or shortcheck then
let errorflag = 0
print "You are carrying the following items..."
if keys then
print "key"
endif
if rope then
print "rope"
endif
if gourd then
if gourdfull then
print "full gourd"
else
print "empty gourd"
endif
endif
if bullets then
print "bullets"
endif
if derringer then
print "derringer"
endif
print
endif
return
sub helpcommand
compare check, command$, "HELP"
compare shortcheck, command$, "H"
if not(shortcheck) then
compare shortcheck, command$ , "?"
endif
if check or shortcheck then
let errorflag = 0
cls
print "Help:", newline
print "(l)ook"
print "(n)orth"
print "(e)ast"
print "(s)outh"
print "(w)est"
print "(ex)amine (object)"
print "(t)ake (object)"
print "(u)se (object)"
print "(ta)lk"
print "(i)nventory"
print "(h)elp"
print "(q)uit", newline
print "Press any key to continue..."
pause
cls
gosub look
endif
return
sub byecommand
compare check, command$, "BYE"
if not(check) then
compare check, command$, "END"
endif
if not(check) then
compare check, command$, "QUIT"
endif
if not(check) then
compare check, command$, "EXIT"
endif
compare shortcheck, command$, "Q"
if check or shortcheck then
end
endif
return
sub boulders
print "The boulders here are much too steep. You'll have to go another way."
let areax = lastareax
let areay = lastareay
return
sub sands
let boulder = 0
print "There's nothing", comma, " but sand here."
print "The sand is hot and the air is dry."
print "Your thirst intensifies."
let hydration = hydration - 1
return
sub roads
let boulder = 0
print "You find yourself wandering an old road."
print "There's nothing for miles."
print "The long walk is making you thirsty."
let hydration = hydration - 1
return
sub crossroad
let boulder = 0
print "You are at a crossroad."
print "The signpost is faded and unreadable."
let hydration = hydration - 1
return
sub crops
let boulder = 0
print "You are surrounded by the remains of an old crop."
print "Nothing has grown here for a long time."
return
sub barn
let boulder = 0
print "There's an old barn here."
print "The place is falling apart."
print "A single bale of hay remains inside."
return
sub house
let boulder = 0
if locked then
print "You are outside of an old house."
print "The door is locked and the windows are boarded."
else
print "You are inside of an old house."
print "There's a range and a bed."
print "Above the range is a shelf."
endif
return
sub cliff
let boulder = 0
if rope then
print "You are at the edge of a cliff."
print "The rope you found at the old house helps you to climb safely."
else
print "You are at the edge of a cliff."
print "Maybe you can find somethig to help climb down safely."
let areax = lastareax
let areay = lastareay
endif
return
sub spring
let boulder = 0
print "You are in a valley between the cliffs. It's beautiful."
print "The bushes are a vibrant green."
print "Water from the surrounding areas collect here."
print "There's a small spring of fresh water."
print "You take a good drink and fill your gourd."
print "There's berries growing here as well. Delicious!"
let hydration = 15
let gourdfull = 1
return
sub traveller
let boulder = 0
if bullets then
gosub roads
else
if gourd and gourdfull then
print "You encounter a lone traveller."
print "It looks like he wants to talk with you."
else
gosub roads
endif
endif
return
sub skeleton
let boulder = 0
print "You have been walking for a very long time."
print "There's a skeleton lying here in the sand."
print "Your thirst intensifies."
let hydration = hydration - 1
return
sub pileofskulls
let boulder = 0
print "There's a pile of skulls in the sand."
print "Something terrible happened here."
print "Whatever it was", comma, " that was long ago."
print "Your thirst intensifies."
let hydration = hydration - 1
return
sub robbery
let boulder = 0
print "You find a passage between the steep boulders."
print "Suddenly", comma, " an outlaw appears and confronts you.", newline
print "Outlaw:"
print "Give me your possessions or die!", newline
print "Will you defend yourself or run?"
print "Defend or Run? ",
gosub getinput
compare check, cmdline$, "DEFEND"
compare shortcheck, cmdline$, "D"
if check or shortcheck then
if derringer and bullets then
print "The outlaw attempts to draw his gun and shoot you."
print "You produce your gun and shoot him just in time."
print "The outlaw is dead."
let outlaw = 0
else
print "You attempt to defend yourself", comma, " but are shot in the process."
print "Never bring your fists to a gun fight... Game over."
tone 100, 1000
pause
end
endif
else
print "You narrowly manage to escape the outlaw robber."
let areax = lastareax
let areay = lastareay
endif
return
sub greatlake
print "After a long adventure", comma, " you have found something spectacular."
print "A great lake full of life and beauty. This place is your calling."
print "It's time for you to settle down and build your home here."
print "You win the game!"
tone 400, 1000
pause
end
return
sub getinput
input cmdline$
trim cmdline$, cmdline$
upper cmdline$, cmdline$
return
sub look
let temp = hydration
let hydration = hydration + 1
gosub areadescription
let hydration = temp
return