Syntax

Comments

Like in Lua, line comments start with -- and end at the end of the line.

-- this is a comment

Block comments start with -* and end with *-.

-* this is a block comment
spanning multiple
lines *-

Block comments cannot (currently) be nested.

Comments are ignored during compilation and do not appear in the compiled Lua code.

Keywords

Hurdy keywords

Hurdy reserves the following keywords

and as break continue else elseif false for
function from global if import in method nil
or return repeat true until var while

as well as _hurdytemp followed by a number (e.g., _hurdytemp1, _hurdytemp568)—these are used internally by the transpiler.

Reserved Hurdy keywords cannot be used a variable names, but can be used as keys to index objects:

global = 5 -- this is not allowed
x.global = 5 -- this is ok

Lua keywords

Lua keywords that are not Hurdy keywords are also reserved and cannot be used as identifiers, but can be used as keys to index objects:

do end local not then goto
local = 5 -- this is not allowed
x.local = 5 -- this is ok

Identifiers

Identifiers in Hurdy are case-sensitive, start with a letter or underscore, and can contain letters, numbers, or onderscores. Only ASCII letters are allowed in identifiers.

Strings

Strings follow the same syntax as Lua (for both short and long strings).

"This is a short string"

[[ This is a level 0 long string ]]

[===[ This is a level 3 long string ]===]

The Hurdy compiler processes some of the Lua escape sequences during compilations (only inside short strings), allowing them to be used in versions of Lua that don’t support them.

\z escape sequence

The \z escape sequence ((introduced in Lua 5.2)) is processed during compilation to remove all following whitespace (including newlines), so the resulting code can be run on Lua 5.1:

"example \z


   of escape sequence"

is equivalent to

"example of escape sequence"

\x escape sequence

The hexadecimal escape sequence x (introduced in Lua 5.2) is processed during compilation to convert it to a decimal escape sequence representing the same byte, so the resulting code can be run on Lua 5.1:

"\xFF"

is equivalent to

"\255"

\u escape sequence

The UTF-8 escape sequence u (introduced in Lua 5.3) is processed during compilation to convert it to one or more decimal escape sequences representing the character code point, so the resulting code can be run on Lua 5.1 and 5.2:

"\u{a9}"

is equivalent to

"\194\169"

Newlines

Statements in Hurdy are sperated using newlines (\n). To allow for freedom of formatting and to split lines that are too long, newlines are ignored after a token that cannot end a statemet.

print(
  1, 2,
  3
)

and

print(1, 2, 3)

produce the same result.

Operators

All of Lua’s operators are supported and have the same precedence and associativity rules as in Lua, although in some cases (exponentiation, logical NOT, bitwise XOR, inequality) Hurdy uses a different symbol. Refer to the tables below for the correct symbols.

Additionally, Hurdy has extra assignment operators, such as addition assignment.

Arithmetic operators

Hurdy operator

Lua operator

Description

Notes

+

+

Addition

-

-

Subtraction

*

*

Multiplication

/

/

Float division

//

//

Floor division

Requires Lua 5.3+

%

%

Modulo

**

^

Exponentiation

Different than Lua

-

-

Unary minus

Logical operators

Hurdy operator

Lua operator

Description

Notes

and

and

Logical AND

or

or

Logical OR

!

not

Logical NOT

Different than Lua

Bitwise operators

Bitwise operators are supported, but the compiled code must be run with Lua 5.3+.

Hurdy operator

Lua operator

Description

Notes

&

&

Bitwise AND

|

|

Bitwise OR

^

~

Bitwise XOR

Different than Lua

>>

>>

Bitwise right shift

<<

<<

Bitwise left shift

~

~

Bitwise NOT

Relational operators

Hurdy operator

Lua operator

Description

Notes

==

==

Equality

!=

~=

Inequality

Different than Lua

<

<

Less than

>

>

Greater than

<=

<=

Less or equal

>=

>=

Greater or equal

Additional operators

Hurdy operator

Lua operator

Description

..

..

Concatenation

#

#

Length

Assignment operators

Hurdy operator

Lua operator

Description

Notes

=

=

Assignment

+=

Addition assignment

-=

Subtraction assignment

*=

Multiplication assignment

/=

Float division assignment

//=

Floor division assignment

Requires Lua 5.3+

and=

Logical AND assignment

or=

Logical OR assignment

&=

Bitwise AND assignment

Requires Lua 5.3+

|=

Bitwise OR assignment

Requires Lua 5.3+

^=

Bitwise XOR assignment

Requires Lua 5.3+

>>=

Bitwise right shift assignment

Requires Lua 5.3+

<<=

Bitwise left shift assignment

Requires Lua 5.3+

The regular assignment operator works just as in Lua, and in particular it can be used with multiple identifiers on the left and/or multiple values on the right:

x = 3
y = nil, 2

x, y = 3, 2

Operation assignments

All the extra assignment operators which are unique to Hurdy (i.e., the “operation assignments” associated to binary operators) work in the same way, and can only be used with one identifier on the left and one variable on the right. For example for addition assignment

-- note that target is a variable
x += 1 + 2 / 3

translates to

x = x + ( 1 + 2 / 3)

The right-hand-side is always wrapped in parentheses to avoid unexpected results due to operator precedence.

Moreover, operation assignments avoid multiple evaluations when the target is a table/object access by caching the parent expression and possibly the key. For example

-- note that target is a . or [] access
t.x += 2
t[f()] -= 8
a.b["c"].x *= 7

translates to

do
  local _hurdytemp1 = t
  _hurdytemp1.x = _hurdytemp1.x + (2)
end


do
  local _hurdytemp1 = t
  local _hurdytemp2 = f()
  _hurdytemp1[ _hurdytemp2 ] = _hurdytemp1[ _hurdytemp2 ] - (8)
end

do
  local _hurdytemp1 = a.b["c"]
  _hurdytemp1.x = _hurdytemp1.x * (7)
end

Note

The key is cached only in the case of [] access, and only if the key is not a literal (i.e. a number, a string, a boolean).