Standard FreeBASIC is often less concise than other dialects like QBasic and fblite. A large part of this is that FreeBASIC requires explicit variable declaration, whereas the other dialects don't.
Print j+1 is a perfectly valid QBasic program; since
j hasn't been declared it will default to a value of 0. Both alternate dialects allow the variable suffix system to specify the type instead of using
dim, but in turn, disallow the use of
%for Integer (default for fblite)
!for Single (default for qb)
a$ = "abc" is a string variable, which has a default of an empty string.
This can be taken advantage of using BASIC's
#lang directive, which can be placed in a program to switch which dialect it uses.
#lang "qb" sets the language to QBasic;
#lang "fblite" sets it to fblite.
QBasic is often preferable to fblite because it requires less bytes in the lang directive, but QBasic lacks some functions that fblite and FreeBASIC such as
iif() (replaced by
__iif()) and some string functions need the suffix
See https://freebasic.net/wiki/CompilerDialects for more info about the differences between dialects.
QBasic also has a CGSE tips page.
If a string literal appears at the end of a line, it doesn't need a closing quotation mark.
?"Hello is perfectly valid. This also helps with the
#lang directive since it uses a string, ie.
? is a shorter alias for
Print"Hello". You can just have
? on a line to print a newline on its own. Elements can be separated by semicolons to print without newlines, or with a trailing semicolon to have no newline.
?"abc";i;"def" ' Print number in string ? ' Print just a newline ?"no newline"; ' Print string with no newline
When printing a positive signed integer, BASIC will append a space beforehand, so variables will need to be converted to unsigned or stringified.
var i=5u:?i ' Declare it to be unsigned to begin with var i=5:?i+0u ' Convert to unsigned var i=5:?""&i ' Stringify it (can't do ?i&", since that looks like a suffix) i=5:?""&i ' Use alternate dialects to avoid var (note that qb prints integers with a trailing space)
Remove spaces after numbers
Spaces can be left out after number literals. This can help in for loops (see below), and other infix operators. As a specific example, moduloing by a power of 2 can be replaced with an
and call, e.g.
x mod 2 =>
There are a few ways to loop in BASIC:
var i=0:for i=0to 99:code:next var i=0:while i<99:code:i+=1:wend var i=0:a:code:i+=1:if i<99 goto a var i=0:do:code:*ERROR*i+=1:loop ' Termination by error (details are left as an exercise to the reader)
These are useful in various contexts. The for loop is the shortest and most straightforward. The while loop is good if you're looping until a loop variable is zero or if you don't want to increment the variable. The goto is good for infinite loops, terminating on errors (e.g. going to the wrong place in memory). The goto can also be used in conjunction with other labels, using
on x goto l1,l2,l3, which doesn't jump if x is not in 1,2,3.
step, it is shorter to just add whatever to the variable in the loop:
for i=0to 99step 9:code:next for i=0to 99:code:i+=8:next
Negative steps can start with a negated start where you negate it in the loop.
for i=99to 0step-1:?i:next for i=-99to 0:?-i:next
nexts can be combined for a single byte save (or more if you manage to line up three or more)
for i=1To 10 for j=1To 2 ' ... next j,i
- Print a string conditionally with
- The data section in the qb dialect can have strings separated by commas without quotes
- Escape a string with
?!"\0abc\n". Using a string function with a null byte in it will terminate the string at the first null.
- Manipulating strings as pointers is often useful, e.g.
- You can index into raw strings by encasing them in parentheses, e.g.
- Argv is stored pretty much sequentially, both as a list of pointers to strings, and the actual args with nulls between
a mod bis the same size as
- Single line if statements with
if b then code:etc:etc