- Switched from alt_getopt to argparse - Both
moonandmooncnow use argparse for argument parsing, providing better help messages via--helpand more robust option handling - Added
-e/--executeflag tomoon- Execute MoonScript code directly from the command line:moon -e "print 'Hello World'" - New
--transformoption formoonc- Allows custom AST transformations before compilation by specifying a module that receives and returns the syntax tree - Improved
-(stdin) handling - Now properly enforces that-must be the only argument
-wis now also available as--watch-lis now also available as--lint-tis now also available as--output-to
- moon-tags - New script for generating ctags-compatible tag files for MoonScript, with support for:
- Class definitions
- Class methods
- Top-level function definitions (exported via
{:func}pattern) - Lapis route detection (
--lapisflag) - Optional line numbers (
--include-lineflag) - Optionally skip header (
--no-headerflag)
moon.p()now prints multiple arguments - Pass multiple values and each will be dumpedutil.dumpshows class names - When dumping objects, the class name is displayed (e.g.,<MyClass>{...})
- Lua keyword property access on self - Properties with Lua keyword names (like
@thenor@@then) now compile correctly using bracket notation instead of invalidself.then
- Fixed ambiguous Lua generation after
import- Semicolons are now correctly inserted when the next line starts with(, preventing parsing ambiguity - Fixed update operators with complex chain indexes - Expressions like
a[func()].x += 1now correctly lift the index expression to avoid double evaluation - Exit with proper error code -
moonnow exits with code 1 when the executed script fails - Fixed
moonc -- Reading from stdin now works correctly - Removed accidental debug print - Removed stray
print file, timein watcher code dump.treereturns string - Now returns the string instead of printing directly- Removed noisy "Built" message - Single file compilation no longer prints "Built" to stderr
- Migrated CI from Travis to GitHub Actions
- Added comprehensive compiler and transform specs
- Improved binary building workflow for Windows and Linux
- Better error messages for invalid destructure assignments
- Updated
splat.moonto use argparse, added--strip-prefixoption
Function calls with parentheses can now have free whitespace around the arguments. Additionally, a line break may be used in place of a comma:
my_func(
"first arg"
=>
print "some func"
"third arg", "fourth arg"
)Just like the function all update, function argument definitions have no whitespace restrictions between arguments, and line breaks can be used to separate arguments:
some_func = (
name
type
action="print"
) =>
print name, type, actionelseifcan be used part of anunlessblock (nymphium)unlessconditional expression can contain an assignment like anifstatement (#251)- Lua 5.3 bitwise operator support (nymphium) (Kawahara Satoru)
- Makefile is Lua version agnostic (nymphium)
- Lint flag can be used with
mooncwatch mode (ChickenNuggers) - Lint exits with status 1 if there was a problem detected (ChickenNuggers)
- Compiler can be used with lulpeg
- Slice boundaries can be full expressions (#233)
- Destructure works when used as loop variable in comprehension (#236)
- Proper name local hoisting works for classes again (#287)
- Quoted table key literals can now be parsed when table declaration is in single line (#286)
- Fix an issue where
elsecould get attached to wrongifstatement (#276) - Loop variables will no longer overwrite variables of the same name in the same scope (egonSchiele)
- A file being deleted will not crash polling watch mode (ChickenNuggers)
- The compiler will not try to compile a directory ending in
.moon(Gskartwii) - alt_getopt import works with modern version (Jon Allen)
- Code coverage not being able to find file from chunk name
super now looks up the parent method via the class reference, instead of a
(fixed) closure to the parent class.
Given the following code:
class MyThing extends OtherThing
the_method: =>
super!In the past super would compile to something like this:
_parent_0.the_method(self)Where _parent_0 was an internal local variable that contains a reference to
the parent class. Because the reference to parent is an internal local
variable, you could never swap out the parent unless resorting to the debug
library.
This version will compile to:
_class_0.__parent.__base.the_method(self)Where _class_0 is an internal local variable that contains the current class (MyThing).
Another difference is that the instance method is looked up on __base instead
of the class. The old variation would trigger the metamethod for looking up on
the instance, but a class method of the same name could conflict, take
precedence, and be retuned instead. By referencing __base directly we avoid
this issue.
super can now be used on class methods. It works exactly as you would expect.
class MyThing extends OtherThing
@static_method: =>
print super!Calling super will compile to:
_class_0.__parent.static_method(self)The scoping of super is more intelligent. You can warp your methods in other
code and super will still generate correctly. For example, syntax like this
will now work as expected:
class Sub extends Base
value: if debugging
=> super! + 100
else
=> super! + 10
other_value: some_decorator {
the_func: =>
super!
}super will refer to the lexically closest class declaration to find the name
of the method it should call on the parent.
- Nested
withblocks used incorrect ref (#214 by @geomaster) - Lua quote string literals had wrong precedence (#200 by @nonchip)
- Returning from
withblock would generate tworeturnstatements (#208) - Including
returnorbreakin acontinuewrapped block would generate invalid code (#215 #190 #183)
- Refactor transformer out into multiple files
mooncommand line script rewritten in MoonScriptmoonscript.parse.build_grammarfunction for getting new instance of parser grammar- Chain AST updated to be simpler
package.moonpathgeneator does not use paths that don't end inlua
- Fixed a bug where an error from a previous compile would prevent the compiler from running again
- New unused assignment linter finds assignments that are never referenced after being defined.
Whitespace parsing has been relaxed in a handful of locations:
- You can put unrestricted whitespace/newlines after operator in a binary operator before writing the right hand side. The following are now valid:
x = really_long_function! +
2304
big_math = 123 /
12 -
43 * 17
bool_exp = nice_shirt and cool_shoes or
skateboard and shades- You can put unrestricted whitespace/newlines immediately after an opening parenthesis, and immediately before closing parenthesis. The following are now valid:
hello = 100 + (
var * 0.23
) - 15
funcall(
"height", "age", "weight"
)
takes_two_functions (->
print "hello"
), ->
print "world"- You can put unrestricted whitespace/newlines immediately after a
:when defining a table literal. The following is now valid:
x = {
hello:
call_a_function "football", "hut"
}- Single value
import/destructurecompiles directly into single assignment
- Some
moonccommand line flags were being ignored - Linter would not report global reference when inside self assign in table
- Fixed an issue where parser would crash in Lpeg 0.12 when compiling hundreds of times per process
- MoonScript parser now written in MoonScript
- Fixes to posmap generation for multi-line mappings and variable declarations
- Prefix file name with
@when loading code so stack traces tread it as file - Fix bug where
moonccouldn't work with absolute paths - Improve target file path generation for
moonc
- New code coverage tool built into
moonc - New linting tool built into
moonc, identifies global variable references that don't pass whitelist - Numbers can have
LLandULLsuffixes for LuaJIT
- Error messages from
mooncare written to standard error - Moonloader correctly throws error when moon file can't be parsed, instead of skipping the module
- Line number rewriting is no longer incorrectly offset due to multiline strings
Bound functions will avoid creating an anonymous function unless necessary.
x = hello\worldBefore:
local x = (function()
local _base_0 = hello
local _fn_0 = _base_0.world
return function(...)
return _fn_0(_base_0, ...)
end
end)()After:
local x
do
local _base_0 = hello
local _fn_0 = _base_0.world
x = function(...)
return _fn_0(_base_0, ...)
end
endExplicit return statement now avoids creating anonymous function for statements where return can be cascaded into the body.
->
if test1
return [x for x in *y]
if test2
return if true
"yes"
else
"no"
falseBefore:
local _
_ = function()
if test1 then
return (function()
local _accum_0 = { }
local _len_0 = 1
local _list_0 = y
for _index_0 = 1, #_list_0 do
local x = _list_0[_index_0]
_accum_0[_len_0] = x
_len_0 = _len_0 + 1
end
return _accum_0
end)()
end
if test2 then
return (function()
if true then
return "yes"
else
return "no"
end
end)()
end
return false
endAfter:
local _
_ = function()
if test1 then
local _accum_0 = { }
local _len_0 = 1
local _list_0 = y
for _index_0 = 1, #_list_0 do
local x = _list_0[_index_0]
_accum_0[_len_0] = x
_len_0 = _len_0 + 1
end
return _accum_0
end
if test2 then
if true then
return "yes"
else
return "no"
end
end
return false
end- The way the subtraction operator works has changed. There was always a little confusion as to the rules regarding whitespace around it and it was recommended to always add whitespace around the operator when doing subtraction. Not anymore. Hopefully it now works how you would expect. (
a-bcompiles toa - band nota(-b)anymore). - The
moonlibrary is no longer sets a global variable and instead returns the module. Your code should now be:
moon = require "moon"- Generated code will reuse local variables when appropriate. Local variables are guaranteed to not have side effects when being accessed as opposed to expressions and global variables. MoonScript will now take advantage of this and reuse those variable without creating and copying to a temporary name.
- Reduced the creation of anonymous functions that are called immediately. MoonScript uses this technique to convert a series of statements into a single expression. It's inefficient because it allocates a new function object and has to do a function call. It also obfuscates stack traces. MoonScript will flatten these functions into the current scope in a lot of situations now.
- Reduced the amount of code generated for classes. Parent class code it left out if there is no parent.
- You can now put line breaks inside of string literals. It will be replaced with
\nin the generated code.
x = "hello
world"- Added
moonscript.basemodule. It's a way of including themoonscriptmodule without automatically installing the moonloader. - You are free to use any whitespace around the name list in an import statement. It has the same rules as an array table, meaning you can delimit names with line breaks.
import a, b
c, d from z- Added significantly better tests. Previously the testing suite would only verify that code compiled to an expected string. Now there are unit tests that execute the code as well. This will make it easier to change the generated output while still guaranteeing the semantics are the same.
bis not longer treated as self assign in{ a : b }- load functions will return
nilinstead of throwing error, as described in documentation - fixed an issue with
moon.mixinwhere it did not work as described
Fixed bug with moonloader not loading anything
- For loops when used as expressions will no longer discard nil values when accumulating into an array table. This is a backwards incompatible change. Instead you should use the
continuekeyword to filter out iterations you don't want to keep. Read more here. - The
moonscriptmodule no longer sets a global value formoonscriptand instead returns it. You should update your code:
moonscript = require "moonscript"- Lua 5.2 Support. The compiler can now run in either Lua 5.2 and 5.1
- A switch
whenclause can take multiple values, comma separated. - Added destructuring assignment.
- Added
local *(andlocal ^) for hoisting variable declarations in the current scope - List comprehensions and line decorators now support numeric loop syntax
- Numbers that start with a dot, like
.03, are correctly parsed - Fixed typo in
foldlibrary function - Fix declaration hoisting inside of class body, works the same as
local *now
MoonScript has made its way into GitHub. .moon files should start to be recognized in the near future.
- Compiled files will now implicitly return their last statement. Be careful, this might change what
requirereturns.
- Added
continuekeyword for skipping the current iteration in a loop. - Added string interpolation.
- Added
doexpression and block. - Added
unlessas a block and line decorator. Is the inverse ofif. - Assignment can be used in an
ifstatement's expression. - Added
or=andand=operators. @@can be prefixed in front of a name to access that name withinself.__class@and@@can be used as values to referenceselfandself.__class.- In class declarations it's possible to assign to the class object instead of the instance metatable by prefixing the key with
@. - Class methods can access locals defined within the body of the class declaration.
- Super classes are notified when they are extended from with an
__inheritedcallback. - Classes can now implicitly return and be expressions.
localkeyword returns, can be used for forward declaration or shadowing a variable.- String literals can be used as keys in table literals.
- Call methods on string literals without wrapping in parentheses:
"hello"\upper! - Table comprehensions can return a single value that is unpacked into the key and value.
- The expression in a
withstatement can now be an assignment, to give a name to the expression that is being operated on.
- The
loadfunctions can take an optional last argument of options.
- The online compiler now runs through a web service instead of emscripten, should work reliably on any computer now.
- Windows binaries have been updated.
- Significantly improved the line number rewriter. It should now accurately report all line numbers.
- Generic
forloops correctly parse for multiple values as defined in Lua. - Update expressions don't fail with certain combinations of precedence.
- All statements/expressions are allowed in a class body, not just some.
x = "hello" if somethingwill extract the declaration ofxif it's not in scope yet. Preventing an impossible to access variable from being created.- varargs,
..., correctly bubble up through automatically generated anonymous functions. - Compiler doesn't crash if you try to assign something that isn't assignable.
- Numerous other small fixes. See commit log.
,is used instead of:for delimiting table slice parts.- Class objects store the metatable of their instances in
__base.__baseis also used in inheritance when chaining metatables.
- Added key-value table comprehensions.
- Added a
switchstatement. - The body of a class can contain arbitrary expressions in addition to assigning properties.
selfin this scope refers to the class itself. - Class objects themselves support accessing the properties of the superclass they extend (like instances).
- Class objects store their name as a string in the
__nameproperty. - Enhanced the
superkeyword in instance methods. - Bound methods can be created for an object by using
object\function_nameas a value. Called function stubs. - Added
export *statement to export all assigned names following the statement. - Added
export ^statement to export all assigning names that begin with a capital letter following the statement. exportcan be used before any assignment or class declaration to export just that assignment (or class declaration).- Argument lists can be broken up over several lines with trailing comma.
:hellois short hand forhello: helloinside of table literal.- Added
..=for string concatenation. table.insertno longer used to build accumlated values in comprehensions.
- Added
loadfile,loadstring, anddofilefunctions tomoonscriptmodule to load/run MoonScript code. - Added
to_luafunction tomoonscriptmodule to convert a MoonScript code string to Lua string.
- Created prebuilt MoonScript Windows executables.
- Wrote a Textmate/Sublime Text bundle.
- Wrote a SciTE syntax highlighter with scintillua.
- Created a SciTE package for Windows that has everything configured.
- Created an online compiler and snippet site using emscripten.
- Watch mode works on all platforms now. Uses polling if
inotifyis not available.
I'm now including a small set of useful functions in a single module called moon:
require "moon"Documentation is available here.
- Windows line endings don't break the parser.
- Fixed issues when using
...within comprehensions when the compiled code uses an intermediate function in the output. - Names whose first characters happen to be a keyword don't break parser.
- Return statement can have no arguments
- argument names prefixed with
@in function definitions work outside of classes work with default values. - Fixed parse issues with the shorthand values within a
withblock. - Numerous other small fixes. See commit log.
Since the first release, I've written one other project in MoonScript (other than the compiler). It's a static site generator called sitegen. It's what I now use to generate all of my project pages and this blog.
Initial release