Skip to content
Sean Barag edited this page Oct 26, 2018 · 5 revisions

The BrightScript language has a whole bunch of quirks. This page attempts to capture them as I find them. In general, a quirk listed here is supported in the brs project's interpreter.

Maximum Number of Arguments in a Function Signature

BrightScript functions and subs can accept 63 arguments, and the brs project matches that. Including a 64th argument results in early argument types getting "forgotten". This typically presents as a Type mismatch error where the first few arguments have type ?, e.g.:

sub tooMany(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, aa, ab, ac, ad, ae, af, ag, ah, ai, aj, ak, al, am, an, ao, ap, aq, ar, as, at, au, av, aw, ax, ay, az, ba, bb, bc, bd, be, bf, bg, bh, bi, bj, bk, bl)
    print "BrightScript supports at most 63 arguments"
end sub

tooMany(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)
Current Function:                                                                                                      
005:* sub tooMany(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, aa, ab, ac, ad, ae, af, ag, ah, ai, aj, ak, al, am, an, ao, ap, aq, ar, as, at, au, av, aw, ax, ay, az, ba, bb                                 
006:      ' , ca, cb, cc, cd, ce, cf, cg, ch, ci, cj, ck, cl, cm, cn, co, cp, cq, cr, cs, ct, cu)                      
007:      print "BrightScript supports at most 64 arguments"                                                           
008:  end sub                                                                                                          
Type Mismatch. (runtime error &h18) in pkg:/testfiles/function-max-arg-length.brs(5)                                   
005: sub tooMany(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, aa, ab, ac, ad, ae, af, ag, ah, ai, aj, ak, al, am, an, ao, ap, aq, ar, as, at, au, av, aw, ax, ay, az, ba, bb                                  
Backtrace:                                                                                                             
#1  Function toomany(a As ?, b As Dynamic, c As Dynamic, d As Dynamic, e As Dynamic, f As Dynamic, g As Dynamic, h As Dynamic, i As Dynamic, j As Dynamic, k As Dynamic, l As Dynamic, m As Dynamic, n As Dynamic, o As Dynamic, p As Dynamic, 
q As Dynamic, r As Dynamic, s As Dynamic, t As Dynamic, u As Dynamic, v As Dynamic, w As Dynamic, x As Dynamic, y As Dynamic, z As Dynamic, aa As Dynamic, ab As Dynamic, ac As Dynamic, ad As Dynamic, ae As Dynamic, af As Dynamic, ag As Dyn
amic, ah As Dynamic, ai As Dynamic, aj As Dynamic, ak As Dynamic, al As Dynamic, am As Dynamic, an As Dynamic, ao As Dynamic, ap As Dynamic, aq As Dynamic, ar As Dynamic, as As Dynamic, at As Dynamic, au As Dynamic, av As Dynamic, aw As Dy
namic, ax As Dynamic, ay As Dynamic, az As Dynamic, ba As Dynamic, bb As Dynamic, bc As Dynamic, bd As Dynamic, be As Dynamic, bf As Dynamic, bg As Dynamic, bh As Dynamic, bi As Dynamic, bj As Dynamic, bk As Dynamic, bl As Dynamic) As Void

Unlike the official interpreter, including a 64th argument in brs will result in a clear runtime error. Including many more arguments is likely to crash a Roku device, causing a sudden reboot. brs doesn't shell out to shutdown -r because that'd be really annoying. You'll just get an error message.

Inconsistency between exitwhile and exitfor

BrightScript typically allows a two-word version and a one-word version of language-level statements, e.g. end if and endif are equivalent. It's possible to exit a while loop early with either exitwhile or exit while:

i = 0
while i < 10
    if i = 3 then exitwhile ' or `exit while`
end while

However, exitfor is not a reserved word and can be used for any arbitrary variable. It does not exit for loops early:

exitfor = false

for i = 0 to 10
    if i = 3 then
        exitfor = true
        exit for
    end if
end for

print "exited early?"
print exitfor

Loop counters stay in-scope after loop exit

In most languages, the counter variable used in a for ... to loop is in-scope only in the body of that loop, e.g. in JavaScript:

for (let i = 0; i < 10; i++) {
    // do something with i
}

console.log(i); // ReferenceError: i is not defined

In BrightScript, however, the for ... to loop counter remains in-scope and is incremented once more after the loop exits, e.g.:

for i = 0 to 10
    ' do something with i
end for

print i ' i is now 11

Print Helper Function Scoping

BrightScript's documentation describes two functions that exist to make print statements easier to format:

  • Pos(dummy), which returns the current output cursor position
  • Tab(position), which "moves the cursor to the specified position on the current line"

Pos seems to always be in scope. For instance, this is perfectly valid:

position = pos(0)
print "position = " position

' or use it inline
print "current position is " pos(0)

Tab is only in scope when evaluating a print statement, so this results in a syntax error on Roku devices:

print tab(8) "this is indented eight characters"

indent = tab(8) ' <<< syntax error here!
print indent "this is indented eight characters"

Non-reserved Keywords

Some keywords (so far, only as and in have been found) are not actually reserved, and can thus be used as valid variable names. This leads to some hilariously opaque-but-valid code, e.g.:

function a(as as string) as string
    in = [ as, as ]

    for each in in in
        print in
    end for

    return as
end function


function Main()
    a("silly") ' prints "silly" twice
end function