SmallBASIC has a number of new features intended to broaden its appeal as a general purpose scripting language.
Local variable declaration and assignment
You can now declare and assign a local variable on the same line
local foo = "foo"
Program defined window geometry
The FLTK and SDL versions now allow the window geometry to be set from your program.
option predef grmode 200x300
User defined structures
User defined structures in SmallBASIC are a form of compound variable allowing individual elements to be referenced.
The following example loads the system password table and prints the contents:
tload "/etc/passwd", buffer for row in buffer split row, ":", fields() if (len(fields) > 0) then local user user.name = fields(0) user.passwd = fields(1) user.userId = fields(2) user.groupId = fields(3) users << user fi next row ? users
Regular SmallBASIC arrays are indexed by integers within the upper and lower bounds of the array. Associative arrays take a string as the array index and like plain SmallBASIC variables, come into existence when ever they are referenced.
The following example loads the system password table then prints the groupID value of the "mail" user account:
tload "/etc/passwd", buffer dim users for row in buffer split row, ":", fields() if (len(fields) > 0) then local user user.name = fields(0) user.passwd = fields(1) user.userId = fields(2) user.groupId = fields(3) users(user.name) = user fi next row ? users("mail").userId
Unit name pathing
Units now have the ability to include a path component in a unit name.
import other.something.foo ? foo.my_var
Then in the foo.bas file:
Unit other.something.Foo export my_var
The unit file would be saved in $UNITPATH/other/something. If not defined, $UNITPATH is inferred from the host program directory.
When applied to arrays the IN operator now returns the 1 based index position, for example:
a << "cat" a << "dog" ? "dog" in a 'prints 2
Logical expression short-circuit evaluation
In the code fragment below, if A and B are both func's and the A func returns TRUE, then the B func is not called since the expression outcome will still be the same, the expression will evaluate to TRUE.
if (A OR B) ...
In the next code fragment, if C and D are both func's and the C func returns FALSE, then the D func is not called since the expression outcome will still be the same, the expression will evaluate to FALSE.
if (C AND D) ...
The @ operator can be used to obtain the address of a sub or func. The call statement is then used to invoke the sub or func pointed to by the pointer variable.
func foo(s) foo="foo!"+s end sub bar ? "in bar" end p = @foo ? call(@foo, "#") ? call(p, "%") pb = @bar call pb call @bar
The chain command can now take a string or array of strings as the argument in lieu of a file name. After calling chain, the calling program now successfully resumes.
tload list, code chain code
Strings are normally defined using double quote characters. If the closing quote character is not present then the end of line marker is used to terminate the string definition, for example:
a = "this is a string b = " and this is another string ? a;b
BASIC traditionally uses a single equals symbol for assignment and comparison, for example:
a = "cat" if (a = "cat"): print "cat": endif
SmallBASIC now allows you to use double equals to avoid a clash of programming habits with other languages you may happen to use.
a = "cat" if (a == "cat"): print "cat": endif