Quirrel4.41.0

Coming from Squirrel

Quirrel is Squirrel with the ambiguous parts removed. The language grew out of Gaijin's Squirrel codebase. Nearly every change has one goal: a mistake fails at compile time, not at run time. A Squirrel file rarely compiles unchanged, but the compiler names what it rejects and usually names the replacement too.

Read what changed quietly first. The compiler reports everything else.

What the compiler rejects

SquirrelQuirrel
class B extends A { }class B(A) { }
# a comment//; # now starts a compiler directive
01230x7B or 123: leading 0 is not allowed, octal numbers are not supported
delete t.kt.$rawdelete("k"); the delete operator is off by default
a.push(v)a.append(v), and it takes several values
a.find(v), s.find(sub)a.indexof(v), s.indexof(sub)
f.getinfos()getfuncinfos, which also works on a callable table or instance
t.setdelegate(d), t.getdelegate()gone; use a class
function A::m() { }declare m in the class body, or A.m <- function() { } before the class is used
class A { </ x = 1 /> }class and member attributes are gone
local a = (1, 2)the comma operator is gone
A() { x = 1 } post-initializerset the slots in the constructor
setroottable, setconsttablegone
seterrorhandler(f)debug.seterrorhandler
rawcallgone
switch (x) { }switch is deprecated and off by default; #allow-switch-statement at the top of the file turns it back on
format("%d", n)from "string" import format first, or interpolate it as $"{n}"
f() inside a method, meaning this.f()write this.f(): there is no implicit this lookup

What changed quietly

These compile and run. Test a ported file; a build alone does not find them.

What is new

How to port a file

examples/pages/coming-from/squirrel.nut
// filter passes (value, index), which is the other way round
let heavy = [10, 20, 30].filter(@(value, index) value > 15)
println(heavy.len())

// find is indexof, and a miss answers null instead of -1
println([10, 20].indexof(20))
println([10, 20].indexof(99))

// a method reaches its own class through this
class Squad {
  size = 2
  function report() { return this.describe() }
  function describe() { return $"size {this.size}" }
}
println(Squad().report())

// delete is off; rawdelete removes a slot
let ammo = { rifle = 30 }
ammo.$rawdelete("rifle")
println(ammo.len())
Output:
2
1
null
size 2
0

See also