This thread will show some of the enhanced language features of ScriptBasic. With VBScript being deprecated by Microsoft, ScriptBasic is the only embedded BASIC scripting language available going forward.
VariablesIn ScriptBasic, you don't declare types — the interpreter assigns and converts them automatically based on usage, making it dynamically typed but with predictable conversion rules. Variables are stored as a variant with the following internal types.
- undef - Indicates the variable hasn't been assigned a value yet.
- integer - Indicates this value is a whole number with a integer type.
- real - Indicates a real floating point type.
- string - Indicates a ScriptBasic string that can contain embedded nulls.
- stringz - Indicates a null terminated C style string.
- array - Indicates an array that could be indexed based, associative or a combination of both.
ScriptBasic string and array size is only limited to available memory. (WoW64 32 bit addressing)
These examples show how type is assigned at use. The
& symbol indicates concatenating of strings.
a = 1
b = 2
c = "3"
d = "4"
PRINT a + b
PRINT a & b
PRINT c + d
PRINT c & d
Output:
3
12
7
34
The
$ character can be used to append string variables and functions. This is optional and used mostly when converting other dialects of BASIC such as ProvideX. I rarely use the STR() and VAL() functions in ScriptBasic.
a$ = "A String"
a$ = STR$(123)
ArraysIn ScriptBasic, arrays are flexible data structures created automatically as soon as you assign a value to a subscripted variable. They do not require a formal declaration or a fixed size, and they can hold elements of any data type.
Key Characteristics
- Automatic Creation: There is no DIM statement; arrays are initialized the moment they are used.
- Dynamic Sizing: Addressable indices increase automatically as needed.
- Heterogeneous Content: A single array can store different types of data, such as integers, reals, and strings.
- Uninitialized Elements: Elements that have not been assigned a value return undef.
Standard Arrays: Use square brackets [] for numeric indices.
a[0] = "Hello"
a[1] = 123.45Multidimensional Arrays: Supported through nested brackets or comma-separated indices.
matrix[1][2] = 50
' or alternatively:
matrix[1, 2] = 50
Associative Mode: ScriptBasic allows arrays to function in an associative mode using curly braces
{}.
user{"name"} = "ScriptBasic"
user{"age"} = 26
LBOUND / UBOUND: Used to determine the upper and lower boundaries of an array. An array index traditionally starts a index zero but can begin and end at users choice. Elements between define LBOUND / UBOUND are declared undef.
a[100] = 100
PRINT LBOUND(a)
PRINT UBOUND(a)
a[50] = 50
PRINT LBOUND(a)
PRINT UBOUND(a)
Output
100
100
50
100
Array element segments can be copied to a new array. I use this feature with JSON associative arrays responses to build update requests.
The ScriptBasic
comment character
' is used as the first character of the line. Comments can't be added to the end of a line. The following example shows creating a multi-line comment. The
""" feature also works with multi-line string. I use this extensively with outputting HTML with the ScriptBasic webserver.
' This is a single line comment.
'"""
This is a
multi-line comment
"""
PRINT "Hello, World!","\n"
LabelsScriptBasic supports labels for GOTO, GOSUB and ON ERROR. I also use them to exit a FOR/NEXT loop with a GOTO.
MyLabel:
ScriptBasic also supports line numbers as a special form of label. If using line numbers from a legacy BASIC, you only need line numbers assigned for GOTO / GOSUB reference.
10 LET A$="Hello World!"
20 PRINT A$,"\n"
30 END
Note:
LET is an optional keyword and used with legacy conversions to ScriptBasic.
MODULEIn ScriptBasic, namespaces provide a mechanism to organize code and avoid variable or function name collisions, especially when using external modules. The core command for managing these is MODULE, which defines a specific namespace for subsequent code.
Key Namespace Concepts in ScriptBasic
- Module Definition: Using the MODULE name statement creates a new namespace. All global variables and functions declared after this statement belong to that namespace until the module is ended or changed.
- Accessing Members: To call a function or access a variable inside a module from the main program, you use the double colon :: syntax, such as modulename::functionname.
- The Main Namespace: Code that is not inside any MODULE block belongs to the default "main" namespace.
- External Modules: Extension modules like those for cURL, MySQL and ODBC automatically introduce their own namespaces to keep their internal functions separate from your main script.
- Nesting: ScriptBasic supports nested namespaces, which are managed internally via a namespace stack during syntax analysis.
This is the
COM extension MODULE.
' COM/OLE Automation Extension Module Import
GLOBAL CONST :CALL = 1
GLOBAL CONST :GET = 2
GLOBAL CONST :LET = 4
GLOBAL CONST :SET = 8
MODULE COM
DECLARE SUB ::CREATE ALIAS "CreateObject" LIB "com"
DECLARE SUB ::CBN ALIAS "CallByName" LIB "com"
DECLARE SUB ::RELEASE ALIAS "ReleaseObject" LIB "com"
DECLARE SUB ::GHO ALIAS "GetHostObject" LIB "com"
DECLARE SUB ::GHS ALIAS "GetHostString" LIB "com"
DECLARE SUB ::SVT ALIAS "ShowVariantType" LIB "com"
DECLARE SUB ::TN ALIAS "TypeName" LIB "com"
DECLARE SUB ::DI ALIAS "DescribeInterface" LIB "com"
DECLARE SUB ::CB ALIAS "SBCallBack" LIB "com"
END MODULE
The following ScriptBasic language functions save me a lot of time.
SPLIT
ScriptBasic only allows one statement per line. When I need to assign a group of variables, I use the SPLIT function.
SPLIT "1,2,3" BY "," TO a,b,c
SPLITA
This is a handy function for converting any delimited (including line terminators) list to an array.
SPLITA "1,2,3" BY "," TO a
LIKE
LIKE is used to parse a string and return data designated with the * wildcard character and returns the results using the JOKER() function.
eval_str = "This is an example string that will be searched by the LIKE function."
IF eval_str LIKE "*example * *" THEN
PRINT JOKER(2),"\n"
END IF
Output:
string
ScriptBasic doesn't support the SELECT keyword and uses the IF block instead. This gives better granularity in determining the value.
a = 1
IF a = 1 THEN
PRINT "a = 1\n"
ELSE IF a = 2 THEN
PRINT "a = 2\n"
ELSE
PRINT "a not in range\n"
END IF
Loop Structures
FOR / NEXT
DO / LOOP UNTIL
DO / LOOP WHILE
REPEAT / UNTIL
WHILE / WEND
FORMAT
The FORMAT function allows creating a formatted string with constants and variables. This uses the C style format stucture.
PRINT FORMAT("Today is %s %ith %i\n", "May", 16, 2026)
Output:
Today is May 16th 2026
To format a number based on a mask, the following statement can be used,
PRINT FORMAT("%~$##,##0.00-~", 1234),"\n"
Output:
$ 1,234.00
Date and Time
All time and date math is done by seconds past 1/1/1970.
NOW() returns the the current time based on timezone in seconds.
current_time = TIMEVALUE(year,month,day,hours,minutes,seconds)
PRINT TIMEVALUE(2026,5,16,18,25,0), "\n"
Output:
1778955900
GMTIME() returns the time in seconds but based on GMT time.
YEARDAY returns the day number of the year.
PRINT YEARDAY(NOW),"\n"
Output:
135
date_str = FORMATDATE("format",time)
YEAR four digit year
YY two digit year
MON three letter abbreviation of the month name
MM month
0M month with leading zero if needed
*MONTH-NAME* name of the month
DD day of the month
0D day of the month with leading zero if needed
WD week day on a single digit starting with sunday=0
WEEKDAY-NAME the name of the weekday
WDN three letter abbreviation fo the week day name
HH hours (24 hours notation)
0H hours with leading zero if needed (24 hours notation)
hh hours (12 hours notation)
0h hours with leading zero if needed (12 hours notation)
mm minutes
0m minutes with leading zero if needed
am / pm is am or pm
Any other characters in the format string will be retuened verbatim.
results = ADDDAY(NOW,7) - This adds 7 days to the current time.
There are similar functions for year, month, hour, minute and seconds.