Meet Hurdy¶

Hurdy is a scripting language that compiles to Lua. Its main features are:

  • C-style brackets to make the language less verbose by removing the need for keywords such as then, end, and do.

  • No global-by-default for variable declarations. Variables must explicitly be declared as local or global before they can be assigned to.

  • Works with Lua 5.1 and higher, as well as LuaJIT (some features only work when the compiled code is run with a more recent version of Lua).

  • Lua module to load Hurdy files and compile them on the fly, which includes a way to remap error lines to the original Hurdy code on runtime errors.

  • Outputs human-readable Lua code without creating additional unexpected Lua objects on compilation—what you mean is what you get.

  • Additional assignment operators (such as addition assignment).

  • If statements with assignment.

  • Table comprehensions.

The following Hurdy code highlights the main features of the language.

----------------
-- Hurdy code --
----------------

print("Hello, world!")

-- Python-style import statement for quickly declaring and assign
-- local variables from the entries of a table
from table import sort as tSort

-- entries of a table constructor can be separated by commas or newlines
global t = {
    1
    3
    2
}

-- method-like functions have a reserved keyword
var method sortMethod() {
    tSort(self)
}
t.sortMethod = sortMethod

-- brackets are optional for functions with a single statement
function t.sortFunction()
    tSort(t)

for i = 1, 10 {  print(i) }

-- brackets are optional for loops with a single statement
for i = 1, 10
    print(i)

while true {
    print("infinite loop!")
    break -- joking!
}

-- variables must be declared as either local (var) or global before they can be assigned to
var x = 1
global y
y = print

-- addition assignment, multiplication assignments, etc.
x += 5
x *= 7

-- default arguments can be specified on function declarations
var f = function(x, y=3) {
    print(x, y)
}

-- Hurdy includes a continue statement, but it only works in LuaJIT and Lua 5.2+
-- since it relies on Lua's goto statement
for i, v in ipairs(t) {
    if i == 2 continue
    print(i, v)
}

-- Bitwise operators are supported (code must be run with Lua 5.3+)
x = x & 2
x |= 7

-- Conditions of if statements can be assigned to a variable visible inside the
-- scope of the branches
if var x = test() {
    print(x)
}

-- Hurdy supports table comprehensions, which can be used to create both arrays and
-- hash tables
var array = {i**2 for i = 0, 10}
var hash = {k, v for k, v in ipairs(t) if k != 2}

The code above compiles to the following Lua code:

print("Hello, world!");
local tSort
do
  local _hurdytemp1 = table
  tSort = _hurdytemp1.sort
end
t = {
  1,
  3,
  2
};
local sortMethod;
sortMethod = function(self)
  tSort(self);
end;
t.sortMethod = sortMethod;
t.sortFunction = function()
  tSort(t);
end;
for i = 1, 10 do
  print(i);
end
for i = 1, 10 do
  print(i);
end
while true do
  print("infinite loop!");
  do break end;
end
local x = 1;
y = print;
x = x + (5);
x = x * (7);
local f = function(x, y)
  if y == nil then y = 3 end
  print(x, y);
end;
for i, v in ipairs(t) do
  do
    if i == 2 then
      goto continue;
    end
    print(i, v);
  end
  ::continue::;
end
x = x & 2;
x = x | (7);
do
  local x = test()
  if x then
    print(x);
  end
end
local array = (function()
  local _hurdytemp1 = {}
  local _hurdytemp2 = 0
  for i = 0, 10 do
    _hurdytemp2 = _hurdytemp2 + 1
    _hurdytemp1[_hurdytemp2] = i ^ 2
  end
  return _hurdytemp1
end)();
local hash = (function()
  local _hurdytemp1 = {}
  for k, v in ipairs(t) do
    if k ~= 2 then
      _hurdytemp1[ k ] = v
    end
  end
  return _hurdytemp1
end)();