Conflicts:
	moonscript/init.lua
	moonscript/init.moon
This commit is contained in:
Eloff 2014-01-05 01:33:41 -05:00
commit ea391e14db
105 changed files with 3305 additions and 2506 deletions

View File

@ -1,6 +1,6 @@
test::
moonc test2.moon && TIME=1 busted test2.lua
busted -p "_spec.moon$$"
local:
luarocks make --local moonscript-dev-1.rockspec
@ -16,4 +16,4 @@ compile_global:
moonc moon/ moonscript/
watch:
moonc -w moon/ moonscript/
moonc moon/ moonscript/ && moonc -w moon/ moonscript/

View File

@ -8,9 +8,20 @@ See <http://moonscript.org>.
Online demo/compiler at <http://moonscript.org/compiler>.
## Running Tests
Tests are written in MoonScript and use [Busted](http://olivinelabs.com/busted/).
In order to run the tests you must have MoonScript installed.
To run tests, execute from the root directory:
```bash
busted
```
## License (MIT)
Copyright (C) 2012 by Leaf Corcoran
Copyright (C) 2013 by Leaf Corcoran
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@ -1,7 +1,7 @@
#!/usr/bin/env lua
require "alt_getopt"
local moonscript = require "moonscript"
local moonscript = require "moonscript.base"
local util = require "moonscript.util"
local errors = require "moonscript.errors"
@ -15,6 +15,7 @@ local help = [=[Usage: %s [options] [script [args]]
-h Print this message
-d Disable stack trace rewriting
-c Collect and print code coverage
-v Print version
]=]
@ -70,10 +71,23 @@ end
util.getfenv(moonscript_chunk).arg = new_arg
local function run_chunk()
moonscript.insert_loader()
moonscript_chunk(unpack(new_arg))
moonscript.remove_loader()
end
if not opts.d then
local err, trace
local cov
xpcall(function() moonscript_chunk(unpack(new_arg)) end, function(_err)
if opts.c then
local coverage = require "moonscript.cmd.coverage"
cov = coverage.CodeCoverage()
cov:start()
end
xpcall(run_chunk, function(_err)
err = _err
trace = debug.traceback("", 2)
end)
@ -91,7 +105,12 @@ if not opts.d then
util.trim(trace)
}, "\n"))
end
else
if cov then
cov:stop()
cov:print_results()
end
end
else
moonscript_chunk(unpack(new_arg))
run_chunk()
end

View File

@ -9,8 +9,8 @@ local dump_tree = require"moonscript.dump".tree
local alt_getopt = require "alt_getopt"
local lfs = require "lfs"
local opts, ind = alt_getopt.get_opts(arg, "vhwt:pTXb", {
print = "p", tree = "T", version = "v", help = "h"
local opts, ind = alt_getopt.get_opts(arg, "lvhwt:pTXb", {
print = "p", tree = "T", version = "v", help = "h", lint = "l"
})
local read_stdin = arg[1] == "--"
@ -25,6 +25,7 @@ local help = [[Usage: %s [options] files...
-p Write output to standard out
-T Write parse tree instead of code (to stdout)
-X Write line rewrite map instead of code (to stdout)
-l Perform lint on the file instead of compiling
-b Dump parse and compile time (doesn't write output)
-v Print version
@ -39,9 +40,16 @@ if opts.v then
end
function print_help(err)
if err then print("Error: "..err) end
print(help:format(arg[0]))
os.exit()
local help_msg = help:format(arg[0])
if err then
io.stderr:write("Error: ".. err .. "\n")
io.stderr:write(help_msg .. "\n")
os.exit(1)
else
print(help_msg)
os.exit(0)
end
end
function mkdir(path)
@ -69,9 +77,9 @@ function convert_path(path)
return (path:gsub("%.moon$", ".lua"))
end
function msg(...)
function log_msg(...)
if not opts.p then
print(...)
io.stderr:write(table.concat({...}, " ") .. "\n")
end
end
@ -301,12 +309,12 @@ function create_watcher(files)
dirs = remove_dups(dirs)
return coroutine.wrap(function()
print(("%s with inotify [%s]"):format(msg, plural(#dirs, "dir")))
io.stderr:write(("%s with inotify [%s]"):format(msg, plural(#dirs, "dir")) .. "\n")
local wd_table = {}
local handle = inotify.init()
for _, dir in ipairs(dirs) do
local wd = handle:addwatch(dir, inotify.IN_CLOSE_WRITE)
local wd = handle:addwatch(dir, inotify.IN_CLOSE_WRITE, inotify.IN_MOVED_TO)
wd_table[wd] = dir
end
@ -328,7 +336,7 @@ function create_watcher(files)
-- poll the filesystem instead
local sleep = get_sleep_func()
return coroutine.wrap(function()
print(("%s with polling [%s]"):format(msg, plural(#files, "file")))
io.stderr:write(("%s with polling [%s]"):format(msg, plural(#files, "file")) .. "\n")
local mod_time = {}
while true do
@ -367,24 +375,36 @@ if opts.w then
local target = target_dir..convert_path(fname)
local success, err = compile_and_write(fname, target)
if not success then
print()
print("Error:", fname)
print(err)
print()
io.stderr:write(table.concat({
"",
"Error: " .. fname,
err,
"\n",
}, "\n"))
else
msg("Built:", fname, "->", target)
log_msg("Built:", fname, "->", target)
end
end
print "\nQuitting..."
io.stderr:write("\nQuitting...\n")
elseif opts.l then
for _, fname in pairs(files) do
lint = require "moonscript.cmd.lint"
local res, err = lint.lint_file(fname)
if res then
io.stderr:write(res .. "\n\n")
elseif err then
io.stderr:write(fname .. "\n" .. err.. "\n\n")
end
end
else
for _, fname in ipairs(files) do
local success, err = compile_and_write(fname, target_dir..convert_path(fname))
if not success then
print(fname, err)
io.stderr:write(fname .. "\t" .. err .. "\n")
os.exit(1)
else
msg("Built", fname)
log_msg("Built", fname)
end
end
end

View File

@ -1,6 +1,6 @@
target: reference/index
template: reference
title: MoonScript v0.2.3 - Language Guide
title: MoonScript v0.2.4 - Language Guide
short_name: lang
--
MoonScript is a programming language that compiles to
@ -8,7 +8,7 @@ MoonScript is a programming language that compiles to
familiarity with Lua. For each code snippet below, the MoonScript is on the
left and the compiled Lua is on right right.
This is the offical language reference manual, installation directions and the
This is the official language reference manual, installation directions and the
homepage are located at <http://moonscript.org>.
<div class="github-buttons">
@ -18,6 +18,21 @@ homepage are located at <http://moonscript.org>.
# The Language
## Whitespace
MoonScript is a whitespace sensitive language. This means that
instead of using `do` and `end` (or `{` and `}`) to delimit sections of code we
use line-breaks and indentation.
This means that how you indent you code is important. Luckily MoonScript
doesn't care how you do it but it's important to be consistent.
An indent must be at least 1 space or 1 tab, but you can use as many as you
like. All the code snippets on this page will use two spaces.
> Should you happen to mix tabs and spaces, a tab is equivalent to 4 spaces. I
> shouldn't be telling you this though because you should never do it.
## Assignment
Assigning to an undeclared name will cause it to be declared as a new local
@ -115,7 +130,7 @@ argument names in parentheses:
sum = (x, y) -> print "sum", x + y
```
Functions can be called by listing the arguments after the name of an expresion
Functions can be called by listing the arguments after the name of an expression
that evaluates to a function. When chaining together function calls, the
arguments are applied to the closest function to the left.
@ -541,7 +556,7 @@ for item in *items do print item
for j = 1,10,3 do print j
```
A for loop can also be used an expression. The last statement in the body of
A for loop can also be used as an expression. The last statement in the body of
the for loop is coerced into an expression and appended to an accumulating
array table.
@ -598,7 +613,7 @@ A `continue` statement can be used to skip the current iteration in a loop.
```moon
i = 0
while i < 10
continue if i % 2 ==0
continue if i % 2 == 0
print i
```
`continue` can also be used with loop expressions to prevent that iteration
@ -629,7 +644,7 @@ have_coins = false
if have_coins then print "Got coins" else print "No coins"
```
Because if statements can be used as expressions, this can able be written as:
Because if statements can be used as expressions, this can also be written as:
```moon
have_coins = false
@ -653,6 +668,17 @@ else
print message -- prints: I am very tall
```
The opposite of `if` is `unless`:
```moon
unless os.date("%A") == "Monday"
print "it is not Monday!"
```
```moon
print "You're lucky!" unless math.random! > 0.1
```
### With Assignment
`if` and `elseif` blocks can take an assignment in place of a conditional
@ -701,7 +727,7 @@ is done with the `==` operator.
name = "Dan"
switch name
when "Robert"
print "You are robert"
print "You are Robert"
when "Dan", "Daniel"
print "Your name, it's Dan"
else
@ -1413,7 +1439,7 @@ my_object = {
write: => print "the value:", @value
}
run_callback (func) ->
run_callback = (func) ->
print "running callback..."
func!
@ -1689,7 +1715,7 @@ A full list of flags can be seen by passing the `-h` or `--help` flag.
# License (MIT)
Copyright (C) 2011 by Leaf Corcoran
Copyright (C) 2013 by Leaf Corcoran
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@ -1,6 +1,6 @@
target: reference/standard_lib
template: reference
title: MoonScript v0.2.3 - Standard Library
title: MoonScript v0.2.4 - Standard Library
short_name: stdlib
--
@ -81,7 +81,7 @@ values when a missing key is looked up.
### `extend(arg1, arg2, [rest...])`
Chains together a series of tables by their metatable's `__index` property.
Overwrites the metatable of all objects exept for the last with a new table
Overwrites the metatable of all objects except for the last with a new table
whose `__index` is set to the next table.
Returns the first argument.
@ -166,7 +166,7 @@ overwritten.
### `mixin_object(obj, other_obj, method_names)`
Inserts into `obj` methods from `other_obj` whose names are listen in
Inserts into `obj` methods from `other_obj` whose names are listed in
`method_names`. The inserted methods are bound methods that will run with
`other_obj` as the receiver.

1
moon.lua Normal file
View File

@ -0,0 +1 @@
return require "moon.init"

View File

@ -1,3 +1,5 @@
moon = moon or { }
moon.inject = true
return require("moon.init")
local moon = require("moon")
for k, v in pairs(moon) do
_G[k] = v
end
return moon

View File

@ -1,8 +1,6 @@
-- insert all moon library functions into requiring scope
export moon
moon = moon or {}
moon.inject = true
require "moon.init"
-- install moon into global scope
moon = require "moon"
for k,v in pairs moon
_G[k] = v
moon

View File

@ -1,11 +1,9 @@
if not moon or not moon.inject then
module("moon", package.seeall)
end
local util = require("moonscript.util")
local lua = {
debug = debug,
type = type
}
local dump, p, is_object, type, debug, run_with_scope, bind_methods, defaultbl, extend, copy, mixin, mixin_object, mixin_table, fold
dump = util.dump
p = function(...)
return print(dump(...))
@ -110,17 +108,14 @@ extend = function(...)
return tbls[1]
end
copy = function(self)
return (function()
local _tbl_0 = { }
for key, val in pairs(self) do
_tbl_0[key] = val
end
return _tbl_0
end)()
local _tbl_0 = { }
for key, val in pairs(self) do
_tbl_0[key] = val
end
return _tbl_0
end
mixin = function(self, cls, ...)
local meta = getmetatable(cls)
for key, val in pairs(meta.__index) do
for key, val in pairs(cls.__base) do
if not key:match("^__") then
self[key] = val
end
@ -128,9 +123,8 @@ mixin = function(self, cls, ...)
return cls.__init(self, ...)
end
mixin_object = function(self, object, methods)
local _list_0 = methods
for _index_0 = 1, #_list_0 do
local name = _list_0[_index_0]
for _index_0 = 1, #methods do
local name = methods[_index_0]
self[name] = function(parent, ...)
return object[name](object, ...)
end
@ -138,9 +132,8 @@ mixin_object = function(self, object, methods)
end
mixin_table = function(self, tbl, keys)
if keys then
local _list_0 = keys
for _index_0 = 1, #_list_0 do
local key = _list_0[_index_0]
for _index_0 = 1, #keys do
local key = keys[_index_0]
self[key] = tbl[key]
end
else
@ -161,4 +154,19 @@ fold = function(items, fn)
return items[1]
end
end
return nil
return {
dump = dump,
p = p,
is_object = is_object,
type = type,
debug = debug,
run_with_scope = run_with_scope,
bind_methods = bind_methods,
defaultbl = defaultbl,
extend = extend,
copy = copy,
mixin = mixin,
mixin_object = mixin_object,
mixin_table = mixin_table,
fold = fold
}

View File

@ -1,12 +1,8 @@
if not moon or not moon.inject
module "moon", package.seeall
util = require "moonscript.util"
lua = { :debug, :type }
export *
local *
dump = util.dump
@ -104,8 +100,7 @@ copy = =>
-- mixin class properties into self, call new
mixin = (cls, ...) =>
meta = getmetatable cls
for key, val in pairs meta.__index
for key, val in pairs cls.__base
self[key] = val if not key\match"^__"
cls.__init self, ...
@ -134,4 +129,7 @@ fold = (items, fn)->
else
items[1]
nil
{
:dump, :p, :is_object, :type, :debug, :run_with_scope, :bind_methods,
:defaultbl, :extend, :copy, :mixin, :mixin_object, :mixin_table, :fold
}

View File

@ -14,7 +14,7 @@ description = {
dependencies = {
"lua >= 5.1",
"lpeg >= 0.10",
"lpeg >= 0.10, ~= 0.11",
"alt-getopt >= 0.7",
"luafilesystem >= 1.5"
}
@ -26,6 +26,8 @@ build = {
["moon.all"] = "moon/all.lua",
["moonscript"] = "moonscript/init.lua",
["moonscript.base"] = "moonscript/base.lua",
["moonscript.cmd.coverage"] = "moonscript/cmd/coverage.lua",
["moonscript.cmd.lint"] = "moonscript/cmd/lint.lua",
["moonscript.compile"] = "moonscript/compile.lua",
["moonscript.compile.statement"] = "moonscript/compile/statement.lua",
["moonscript.compile.value"] = "moonscript/compile/value.lua",

View File

@ -1,2 +1,137 @@
_G.moon_no_loader = true
return require("moonscript")
local compile = require("moonscript.compile")
local parse = require("moonscript.parse")
local concat, insert, remove
do
local _obj_0 = table
concat, insert, remove = _obj_0.concat, _obj_0.insert, _obj_0.remove
end
local split, dump, get_options, unpack
do
local _obj_0 = require("moonscript.util")
split, dump, get_options, unpack = _obj_0.split, _obj_0.dump, _obj_0.get_options, _obj_0.unpack
end
local lua = {
loadstring = loadstring,
load = load
}
local dirsep, line_tables, create_moonpath, to_lua, moon_loader, loadstring, loadfile, dofile, insert_loader, remove_loader
dirsep = "/"
line_tables = require("moonscript.line_tables")
create_moonpath = function(package_path)
local paths = split(package_path, ";")
for i, path in ipairs(paths) do
local p = path:match("^(.-)%.lua$")
if p then
paths[i] = p .. ".moon"
end
end
return concat(paths, ";")
end
to_lua = function(text, options)
if options == nil then
options = { }
end
if "string" ~= type(text) then
local t = type(text)
return nil, "expecting string (got " .. t .. ")", 2
end
local tree, err = parse.string(text)
if not tree then
return nil, err
end
local code, ltable, pos = compile.tree(tree, options)
if not code then
return nil, compile.format_error(ltable, pos, text), 2
end
return code, ltable
end
moon_loader = function(name)
local name_path = name:gsub("%.", dirsep)
local file, file_path
local _list_0 = split(package.moonpath, ";")
for _index_0 = 1, #_list_0 do
local path = _list_0[_index_0]
file_path = path:gsub("?", name_path)
file = io.open(file_path)
if file then
break
end
end
if file then
local text = file:read("*a")
file:close()
local res, err = loadstring(text, file_path)
if not res then
error(err)
end
return res
end
return nil, "Could not find moon file"
end
loadstring = function(...)
local options, str, chunk_name, mode, env = get_options(...)
chunk_name = chunk_name or "=(moonscript.loadstring)"
local code, ltable_or_err = to_lua(str, options)
if not (code) then
return nil, ltable_or_err
end
if chunk_name then
line_tables[chunk_name] = ltable_or_err
end
return (lua.loadstring or lua.load)(code, chunk_name, unpack({
mode,
env
}))
end
loadfile = function(fname, ...)
local file, err = io.open(fname)
if not (file) then
return nil, err
end
local text = assert(file:read("*a"))
file:close()
return loadstring(text, fname, ...)
end
dofile = function(...)
local f = assert(loadfile(...))
return f()
end
insert_loader = function(pos)
if pos == nil then
pos = 2
end
if not package.moonpath then
package.moonpath = create_moonpath(package.path)
end
local loaders = package.loaders or package.searchers
for _index_0 = 1, #loaders do
local loader = loaders[_index_0]
if loader == moon_loader then
return false
end
end
insert(loaders, pos, moon_loader)
return true
end
remove_loader = function()
local loaders = package.loaders or package.searchers
for i, loader in ipairs(loaders) do
if loader == moon_loader then
remove(loaders, i)
return true
end
end
return false
end
return {
_NAME = "moonscript",
insert_loader = insert_loader,
remove_loader = remove_loader,
to_lua = to_lua,
moon_chunk = moon_chunk,
moon_loader = moon_loader,
dirsep = dirsep,
dofile = dofile,
loadfile = loadfile,
loadstring = loadstring
}

View File

@ -1,2 +1,108 @@
_G.moon_no_loader = true
require "moonscript"
compile = require "moonscript.compile"
parse = require "moonscript.parse"
import concat, insert, remove from table
import split, dump, get_options, unpack from require "moonscript.util"
lua = :loadstring, :load
local *
dirsep = "/"
line_tables = require "moonscript.line_tables"
-- create moon path package from lua package path
create_moonpath = (package_path) ->
paths = split package_path, ";"
for i, path in ipairs paths
p = path\match "^(.-)%.lua$"
if p then paths[i] = p..".moon"
concat paths, ";"
to_lua = (text, options={}) ->
if "string" != type text
t = type text
return nil, "expecting string (got ".. t ..")", 2
tree, err = parse.string text
if not tree
return nil, err
code, ltable, pos = compile.tree tree, options
if not code
return nil, compile.format_error(ltable, pos, text), 2
code, ltable
moon_loader = (name) ->
name_path = name\gsub "%.", dirsep
local file, file_path
for path in *split package.moonpath, ";"
file_path = path\gsub "?", name_path
file = io.open file_path
break if file
if file
text = file\read "*a"
file\close!
res, err = loadstring text, file_path
if not res
error err
return res
return nil, "Could not find moon file"
loadstring = (...) ->
options, str, chunk_name, mode, env = get_options ...
chunk_name or= "=(moonscript.loadstring)"
code, ltable_or_err = to_lua str, options
unless code
return nil, ltable_or_err
line_tables[chunk_name] = ltable_or_err if chunk_name
-- the unpack prevents us from passing nil
(lua.loadstring or lua.load) code, chunk_name, unpack { mode, env }
loadfile = (fname, ...) ->
file, err = io.open fname
return nil, err unless file
text = assert file\read "*a"
file\close!
loadstring text, fname, ...
-- throws errros
dofile = (...) ->
f = assert loadfile ...
f!
insert_loader = (pos=2) ->
if not package.moonpath
package.moonpath = create_moonpath package.path
loaders = package.loaders or package.searchers
for loader in *loaders
return false if loader == moon_loader
insert loaders, pos, moon_loader
true
remove_loader = ->
loaders = package.loaders or package.searchers
for i, loader in ipairs loaders
if loader == moon_loader
remove loaders, i
return true
false
{
_NAME: "moonscript"
:insert_loader, :remove_loader, :to_lua, :moon_chunk, :moon_loader, :dirsep,
:dofile, :loadfile, :loadstring
}

142
moonscript/cmd/coverage.lua Normal file
View File

@ -0,0 +1,142 @@
local log
log = function(str)
if str == nil then
str = ""
end
return io.stderr:write(str .. "\n")
end
local create_counter
create_counter = function()
return setmetatable({ }, {
__index = function(self, name)
do
local tbl = setmetatable({ }, {
__index = function(self)
return 0
end
})
self[name] = tbl
return tbl
end
end
})
end
local position_to_lines
position_to_lines = function(file_content, positions)
local lines = { }
local current_pos = 0
local line_no = 1
for char in file_content:gmatch(".") do
do
local count = rawget(positions, current_pos)
if count then
lines[line_no] = count
end
end
if char == "\n" then
line_no = line_no + 1
end
current_pos = current_pos + 1
end
return lines
end
local format_file
format_file = function(fname, positions)
local file = assert(io.open(fname))
local content = file:read("*a")
file:close()
local lines = position_to_lines(content, positions)
log("------| @" .. tostring(fname))
local line_no = 1
for line in (content .. "\n"):gmatch("(.-)\n") do
local foramtted_no = ("% 5d"):format(line_no)
local sym = lines[line_no] and "*" or " "
log(tostring(sym) .. tostring(foramtted_no) .. "| " .. tostring(line))
line_no = line_no + 1
end
return log()
end
local CodeCoverage
do
local _base_0 = {
reset = function(self)
self.line_counts = create_counter()
end,
start = function(self)
return debug.sethook((function()
local _base_1 = self
local _fn_0 = _base_1.process_line
return function(...)
return _fn_0(_base_1, ...)
end
end)(), "l")
end,
stop = function(self)
return debug.sethook()
end,
print_results = function(self)
return self:format_results()
end,
process_line = function(self, _, line_no)
local debug_data = debug.getinfo(2, "S")
local source = debug_data.source
self.line_counts[source][line_no] = self.line_counts[source][line_no] + 1
end,
format_results = function(self)
local line_table = require("moonscript.line_tables")
local positions = create_counter()
for file, lines in pairs(self.line_counts) do
local _continue_0 = false
repeat
local file_table = line_table[file]
if not (file_table) then
_continue_0 = true
break
end
for line, count in pairs(lines) do
local _continue_1 = false
repeat
local position = file_table[line]
if not (position) then
_continue_1 = true
break
end
positions[file][position] = positions[file][position] + count
_continue_1 = true
until true
if not _continue_1 then
break
end
end
_continue_0 = true
until true
if not _continue_0 then
break
end
end
for file, ps in pairs(positions) do
format_file(file, ps)
end
end
}
_base_0.__index = _base_0
local _class_0 = setmetatable({
__init = function(self)
return self:reset()
end,
__base = _base_0,
__name = "CodeCoverage"
}, {
__index = _base_0,
__call = function(cls, ...)
local _self_0 = setmetatable({}, _base_0)
cls.__init(_self_0, ...)
return _self_0
end
})
_base_0.__class = _class_0
CodeCoverage = _class_0
end
return {
CodeCoverage = CodeCoverage
}

View File

@ -0,0 +1,79 @@
log = (str="") ->
io.stderr\write str .. "\n"
create_counter = ->
setmetatable {}, __index: (name) =>
with tbl = setmetatable {}, __index: => 0
@[name] = tbl
position_to_lines = (file_content, positions) ->
lines = {}
current_pos = 0
line_no = 1
for char in file_content\gmatch "."
if count = rawget positions, current_pos
lines[line_no] = count
if char == "\n"
line_no += 1
current_pos += 1
lines
format_file = (fname, positions) ->
file = assert io.open fname
content = file\read "*a"
file\close!
lines = position_to_lines content, positions
log "------| @#{fname}"
line_no = 1
for line in (content .. "\n")\gmatch "(.-)\n"
foramtted_no = "% 5d"\format(line_no)
sym = lines[line_no] and "*" or " "
log "#{sym}#{foramtted_no}| #{line}"
line_no += 1
log!
class CodeCoverage
new: =>
@reset!
reset: =>
@line_counts = create_counter!
start: =>
debug.sethook @\process_line, "l"
stop: =>
debug.sethook!
print_results: =>
@format_results!
process_line: (_, line_no) =>
debug_data = debug.getinfo 2, "S"
source = debug_data.source
@line_counts[source][line_no] += 1
format_results: =>
line_table = require "moonscript.line_tables"
positions = create_counter!
for file, lines in pairs @line_counts
file_table = line_table[file]
continue unless file_table
for line, count in pairs lines
position = file_table[line]
continue unless position
positions[file][position] += count
for file, ps in pairs positions
format_file file, ps
{ :CodeCoverage }

214
moonscript/cmd/lint.lua Normal file
View File

@ -0,0 +1,214 @@
local insert
do
local _obj_0 = table
insert = _obj_0.insert
end
local Set
do
local _obj_0 = require("moonscript.data")
Set = _obj_0.Set
end
local Block
do
local _obj_0 = require("moonscript.compile")
Block = _obj_0.Block
end
local default_whitelist = Set({
'_G',
'_VERSION',
'assert',
'bit32',
'collectgarbage',
'coroutine',
'debug',
'dofile',
'error',
'getfenv',
'getmetatable',
'io',
'ipairs',
'load',
'loadfile',
'loadstring',
'math',
'module',
'next',
'os',
'package',
'pairs',
'pcall',
'print',
'rawequal',
'rawget',
'rawlen',
'rawset',
'require',
'select',
'setfenv',
'setmetatable',
'string',
'table',
'tonumber',
'tostring',
'type',
'unpack',
'xpcall',
"nil",
"true",
"false"
})
local LinterBlock
do
local _parent_0 = Block
local _base_0 = {
block = function(self, ...)
do
local _with_0 = _parent_0.block(self, ...)
_with_0.block = self.block
_with_0.value_compilers = self.value_compilers
return _with_0
end
end
}
_base_0.__index = _base_0
setmetatable(_base_0, _parent_0.__base)
local _class_0 = setmetatable({
__init = function(self, whitelist_globals, ...)
if whitelist_globals == nil then
whitelist_globals = default_whitelist
end
_parent_0.__init(self, ...)
self.lint_errors = { }
local vc = self.value_compilers
self.value_compilers = setmetatable({
ref = function(block, val)
local name = val[2]
if not (block:has_name(name) or whitelist_globals[name] or name:match("%.")) then
insert(self.lint_errors, {
"accessing global " .. tostring(name),
val[-1]
})
end
return vc.ref(block, val)
end
}, {
__index = vc
})
end,
__base = _base_0,
__name = "LinterBlock",
__parent = _parent_0
}, {
__index = function(cls, name)
local val = rawget(_base_0, name)
if val == nil then
return _parent_0[name]
else
return val
end
end,
__call = function(cls, ...)
local _self_0 = setmetatable({}, _base_0)
cls.__init(_self_0, ...)
return _self_0
end
})
_base_0.__class = _class_0
if _parent_0.__inherited then
_parent_0.__inherited(_parent_0, _class_0)
end
LinterBlock = _class_0
end
local format_lint
format_lint = function(errors, code, header)
if not (next(errors)) then
return
end
local pos_to_line, get_line
do
local _obj_0 = require("moonscript.util")
pos_to_line, get_line = _obj_0.pos_to_line, _obj_0.get_line
end
local formatted
do
local _accum_0 = { }
local _len_0 = 1
for _index_0 = 1, #errors do
local _des_0 = errors[_index_0]
local msg, pos
msg, pos = _des_0[1], _des_0[2]
if pos then
local line = pos_to_line(code, pos)
msg = "line " .. tostring(line) .. ": " .. tostring(msg)
local line_text = "> " .. get_line(code, line)
local sep_len = math.max(#msg, #line_text)
_accum_0[_len_0] = table.concat({
msg,
("="):rep(sep_len),
line_text
}, "\n")
else
_accum_0[_len_0] = msg
end
_len_0 = _len_0 + 1
end
formatted = _accum_0
end
if header then
table.insert(formatted, 1, header)
end
return table.concat(formatted, "\n\n")
end
local whitelist_for_file
do
local lint_config
whitelist_for_file = function(fname)
if not (lint_config) then
lint_config = { }
pcall(function()
lint_config = require("lint_config")
end)
end
if not (lint_config.whitelist_globals) then
return default_whitelist
end
local final_list = { }
for pattern, list in pairs(lint_config.whitelist_globals) do
if fname:match(pattern) then
for _index_0 = 1, #list do
local item = list[_index_0]
insert(final_list, item)
end
end
end
return setmetatable(Set(final_list), {
__index = default_whitelist
})
end
end
local lint_code
lint_code = function(code, name, whitelist_globals)
if name == nil then
name = "string input"
end
local parse = require("moonscript.parse")
local tree, err = parse.string(code)
if not (tree) then
return nil, err
end
local scope = LinterBlock(whitelist_globals)
scope:stms(tree)
return format_lint(scope.lint_errors, code, name)
end
local lint_file
lint_file = function(fname)
local f, err = io.open(fname)
if not (f) then
return nil, err
end
return lint_code(f:read("*a"), fname, whitelist_for_file(fname))
end
return {
lint_code = lint_code,
lint_file = lint_file
}

138
moonscript/cmd/lint.moon Normal file
View File

@ -0,0 +1,138 @@
import insert from table
import Set from require "moonscript.data"
import Block from require "moonscript.compile"
-- globals allowed to be referenced
default_whitelist = Set {
'_G'
'_VERSION'
'assert'
'bit32'
'collectgarbage'
'coroutine'
'debug'
'dofile'
'error'
'getfenv'
'getmetatable'
'io'
'ipairs'
'load'
'loadfile'
'loadstring'
'math'
'module'
'next'
'os'
'package'
'pairs'
'pcall'
'print'
'rawequal'
'rawget'
'rawlen'
'rawset'
'require'
'select'
'setfenv'
'setmetatable'
'string'
'table'
'tonumber'
'tostring'
'type'
'unpack'
'xpcall'
"nil"
"true"
"false"
}
class LinterBlock extends Block
new: (whitelist_globals=default_whitelist, ...) =>
super ...
@lint_errors = {}
vc = @value_compilers
@value_compilers = setmetatable {
ref: (block, val) ->
name = val[2]
unless block\has_name(name) or whitelist_globals[name] or name\match "%."
insert @lint_errors, {
"accessing global #{name}"
val[-1]
}
vc.ref block, val
}, __index: vc
block: (...) =>
with super ...
.block = @block
.value_compilers = @value_compilers
format_lint = (errors, code, header) ->
return unless next errors
import pos_to_line, get_line from require "moonscript.util"
formatted = for {msg, pos} in *errors
if pos
line = pos_to_line code, pos
msg = "line #{line}: #{msg}"
line_text = "> " .. get_line code, line
sep_len = math.max #msg, #line_text
table.concat {
msg
"="\rep sep_len
line_text
}, "\n"
else
msg
table.insert formatted, 1, header if header
table.concat formatted, "\n\n"
-- {
-- whitelist_globals: {
-- ["some_file_pattern"]: {
-- "some_var", "another_var"
-- }
-- }
-- }
whitelist_for_file = do
local lint_config
(fname) ->
unless lint_config
lint_config = {}
pcall -> lint_config = require "lint_config"
return default_whitelist unless lint_config.whitelist_globals
final_list = {}
for pattern, list in pairs lint_config.whitelist_globals
if fname\match(pattern)
for item in *list
insert final_list, item
setmetatable Set(final_list), __index: default_whitelist
lint_code = (code, name="string input", whitelist_globals) ->
parse = require "moonscript.parse"
tree, err = parse.string code
return nil, err unless tree
scope = LinterBlock whitelist_globals
scope\stms tree
format_lint scope.lint_errors, code, name
lint_file = (fname) ->
f, err = io.open fname
return nil, err unless f
lint_code f\read("*a"), fname, whitelist_for_file fname
{ :lint_code, :lint_file }

View File

@ -3,36 +3,32 @@ local dump = require("moonscript.dump")
local transform = require("moonscript.transform")
local NameProxy, LocalName
do
local _table_0 = require("moonscript.transform.names")
NameProxy, LocalName = _table_0.NameProxy, _table_0.LocalName
local _obj_0 = require("moonscript.transform.names")
NameProxy, LocalName = _obj_0.NameProxy, _obj_0.LocalName
end
local Set
do
local _table_0 = require("moonscript.data")
Set = _table_0.Set
local _obj_0 = require("moonscript.data")
Set = _obj_0.Set
end
local ntype, has_value
do
local _table_0 = require("moonscript.types")
ntype, has_value = _table_0.ntype, _table_0.has_value
local _obj_0 = require("moonscript.types")
ntype, has_value = _obj_0.ntype, _obj_0.has_value
end
local statement_compilers
local statement_compilers = require("moonscript.compile.statement")
local value_compilers = require("moonscript.compile.value")
local concat, insert
do
local _table_0 = require("moonscript.compile.statement")
statement_compilers = _table_0.statement_compilers
local _obj_0 = table
concat, insert = _obj_0.concat, _obj_0.insert
end
local value_compilers
do
local _table_0 = require("moonscript.compile.value")
value_compilers = _table_0.value_compilers
end
local concat, insert = table.concat, table.insert
local pos_to_line, get_closest_line, trim, unpack = util.pos_to_line, util.get_closest_line, util.trim, util.unpack
local pos_to_line, get_closest_line, trim, unpack
pos_to_line, get_closest_line, trim, unpack = util.pos_to_line, util.get_closest_line, util.trim, util.unpack
local mtype = util.moon.type
local indent_char = " "
local Line, DelayedLine, Lines, Block, RootBlock
do
local _parent_0 = nil
local _base_0 = {
mark_pos = function(self, pos, line)
if line == nil then
@ -115,17 +111,14 @@ do
local strip
strip = function(t)
if "table" == type(t) then
return (function()
local _accum_0 = { }
local _len_0 = 1
local _list_0 = t
for _index_0 = 1, #_list_0 do
local v = _list_0[_index_0]
_accum_0[_len_0] = strip(v)
_len_0 = _len_0 + 1
end
return _accum_0
end)()
local _accum_0 = { }
local _len_0 = 1
for _index_0 = 1, #t do
local v = t[_index_0]
_accum_0[_len_0] = strip(v)
_len_0 = _len_0 + 1
end
return _accum_0
else
return t
end
@ -134,25 +127,14 @@ do
end
}
_base_0.__index = _base_0
if _parent_0 then
setmetatable(_base_0, _parent_0.__base)
end
local _class_0 = setmetatable({
__init = function(self)
self.posmap = { }
end,
__base = _base_0,
__name = "Lines",
__parent = _parent_0
__name = "Lines"
}, {
__index = function(cls, name)
local val = rawget(_base_0, name)
if val == nil and _parent_0 then
return _parent_0[name]
else
return val
end
end,
__index = _base_0,
__call = function(cls, ...)
local _self_0 = setmetatable({}, _base_0)
cls.__init(_self_0, ...)
@ -160,13 +142,9 @@ do
end
})
_base_0.__class = _class_0
if _parent_0 and _parent_0.__inherited then
_parent_0.__inherited(_parent_0, _class_0)
end
Lines = _class_0
end
do
local _parent_0 = nil
local _base_0 = {
pos = nil,
_append_single = function(self, item)
@ -174,9 +152,8 @@ do
if not (self.pos) then
self.pos = item.pos
end
local _list_0 = item
for _index_0 = 1, #_list_0 do
local value = _list_0[_index_0]
for _index_0 = 1, #item do
local value = item[_index_0]
self:_append_single(value)
end
else
@ -210,14 +187,13 @@ do
buffer:add(concat(current))
return buffer:mark_pos(self.pos)
end
local _list_0 = self
for _index_0 = 1, #_list_0 do
local chunk = _list_0[_index_0]
for _index_0 = 1, #self do
local chunk = self[_index_0]
local _exp_0 = mtype(chunk)
if Block == _exp_0 then
local _list_1 = chunk:render(Lines())
for _index_1 = 1, #_list_1 do
local block_chunk = _list_1[_index_1]
local _list_0 = chunk:render(Lines())
for _index_1 = 1, #_list_0 do
local block_chunk = _list_0[_index_1]
if "string" == type(block_chunk) then
insert(current, block_chunk)
else
@ -240,27 +216,12 @@ do
end
}
_base_0.__index = _base_0
if _parent_0 then
setmetatable(_base_0, _parent_0.__base)
end
local _class_0 = setmetatable({
__init = function(self, ...)
if _parent_0 then
return _parent_0.__init(self, ...)
end
end,
__init = function() end,
__base = _base_0,
__name = "Line",
__parent = _parent_0
__name = "Line"
}, {
__index = function(cls, name)
local val = rawget(_base_0, name)
if val == nil and _parent_0 then
return _parent_0[name]
else
return val
end
end,
__index = _base_0,
__call = function(cls, ...)
local _self_0 = setmetatable({}, _base_0)
cls.__init(_self_0, ...)
@ -268,13 +229,9 @@ do
end
})
_base_0.__class = _class_0
if _parent_0 and _parent_0.__inherited then
_parent_0.__inherited(_parent_0, _class_0)
end
Line = _class_0
end
do
local _parent_0 = nil
local _base_0 = {
prepare = function() end,
render = function(self)
@ -283,25 +240,14 @@ do
end
}
_base_0.__index = _base_0
if _parent_0 then
setmetatable(_base_0, _parent_0.__base)
end
local _class_0 = setmetatable({
__init = function(self, fn)
self.prepare = fn
end,
__base = _base_0,
__name = "DelayedLine",
__parent = _parent_0
__name = "DelayedLine"
}, {
__index = function(cls, name)
local val = rawget(_base_0, name)
if val == nil and _parent_0 then
return _parent_0[name]
else
return val
end
end,
__index = _base_0,
__call = function(cls, ...)
local _self_0 = setmetatable({}, _base_0)
cls.__init(_self_0, ...)
@ -309,18 +255,15 @@ do
end
})
_base_0.__class = _class_0
if _parent_0 and _parent_0.__inherited then
_parent_0.__inherited(_parent_0, _class_0)
end
DelayedLine = _class_0
end
do
local _parent_0 = nil
local _base_0 = {
header = "do",
footer = "end",
export_all = false,
export_proper = false,
value_compilers = value_compilers,
__tostring = function(self)
local h
if "string" == type(self.header) then
@ -354,14 +297,14 @@ do
end
end,
declare = function(self, names)
local undeclared = (function()
local undeclared
do
local _accum_0 = { }
local _len_0 = 1
local _list_0 = names
for _index_0 = 1, #_list_0 do
for _index_0 = 1, #names do
local _continue_0 = false
repeat
local name = _list_0[_index_0]
local name = names[_index_0]
local is_local = false
local real_name
local _exp_0 = mtype(name)
@ -370,6 +313,8 @@ do
real_name = name:get_name(self)
elseif NameProxy == _exp_0 then
real_name = name:get_name(self)
elseif "table" == _exp_0 then
real_name = name[1] == "ref" and name[2]
elseif "string" == _exp_0 then
real_name = name
end
@ -391,8 +336,8 @@ do
break
end
end
return _accum_0
end)()
undeclared = _accum_0
end
return undeclared
end,
whitelist_names = function(self, names)
@ -429,6 +374,21 @@ do
return yes
end
end,
is_local = function(self, node)
local t = mtype(node)
if t == "string" then
return self:has_name(node, false)
end
if t == NameProxy or t == LocalName then
return true
end
if t == "table" then
if node[1] == "ref" or (node[1] == "chain" and #node == 2) then
return self:is_local(node[2])
end
end
return false
end,
free_name = function(self, prefix, dont_put)
prefix = prefix or "moon"
local searching = true
@ -496,10 +456,14 @@ do
end,
is_value = function(self, node)
local t = ntype(node)
return value_compilers[t] ~= nil or t == "value"
return self.value_compilers[t] ~= nil or t == "value"
end,
name = function(self, node, ...)
return self:value(node, ...)
if type(node) == "string" then
return node
else
return self:value(node, ...)
end
end,
value = function(self, node, ...)
node = self.transform.value(node)
@ -509,7 +473,7 @@ do
else
action = node[1]
end
local fn = value_compilers[action]
local fn = self.value_compilers[action]
if not fn then
error("Failed to compile value: " .. dump.value(node))
end
@ -533,9 +497,8 @@ do
_with_0:append_list((function()
local _accum_0 = { }
local _len_0 = 1
local _list_0 = values
for _index_0 = 1, #_list_0 do
local v = _list_0[_index_0]
for _index_0 = 1, #values do
local v = values[_index_0]
_accum_0[_len_0] = self:value(v)
_len_0 = _len_0 + 1
end
@ -583,10 +546,7 @@ do
error("deprecated stms call, use transformer")
end
local current_stms, current_stm_i
do
local _obj_0 = self
current_stms, current_stm_i = _obj_0.current_stms, _obj_0.current_stm_i
end
current_stms, current_stm_i = self.current_stms, self.current_stm_i
self.current_stms = stms
for i = 1, #stms do
self.current_stm_i = i
@ -606,9 +566,6 @@ do
end
}
_base_0.__index = _base_0
if _parent_0 then
setmetatable(_base_0, _parent_0.__base)
end
local _class_0 = setmetatable({
__init = function(self, parent, header, footer)
self.parent, self.header, self.footer = parent, header, footer
@ -617,10 +574,9 @@ do
self._state = { }
self._listeners = { }
do
local _with_0 = transform
self.transform = {
value = _with_0.Value:bind(self),
statement = _with_0.Statement:bind(self)
value = transform.Value:bind(self),
statement = transform.Statement:bind(self)
}
end
if self.parent then
@ -637,17 +593,9 @@ do
end
end,
__base = _base_0,
__name = "Block",
__parent = _parent_0
__name = "Block"
}, {
__index = function(cls, name)
local val = rawget(_base_0, name)
if val == nil and _parent_0 then
return _parent_0[name]
else
return val
end
end,
__index = _base_0,
__call = function(cls, ...)
local _self_0 = setmetatable({}, _base_0)
cls.__init(_self_0, ...)
@ -655,9 +603,6 @@ do
end
})
_base_0.__class = _class_0
if _parent_0 and _parent_0.__inherited then
_parent_0.__inherited(_parent_0, _class_0)
end
Block = _class_0
end
do
@ -681,9 +626,7 @@ do
end
}
_base_0.__index = _base_0
if _parent_0 then
setmetatable(_base_0, _parent_0.__base)
end
setmetatable(_base_0, _parent_0.__base)
local _class_0 = setmetatable({
__init = function(self, options)
self.options = options
@ -696,7 +639,7 @@ do
}, {
__index = function(cls, name)
local val = rawget(_base_0, name)
if val == nil and _parent_0 then
if val == nil then
return _parent_0[name]
else
return val
@ -709,7 +652,7 @@ do
end
})
_base_0.__class = _class_0
if _parent_0 and _parent_0.__inherited then
if _parent_0.__inherited then
_parent_0.__inherited(_parent_0, _class_0)
end
RootBlock = _class_0
@ -769,8 +712,7 @@ tree = function(tree, options)
end
end
do
local _with_0 = require("moonscript.data")
local data = _with_0
local data = require("moonscript.data")
for name, cls in pairs({
Line = Line,
Lines = Lines,

View File

@ -7,8 +7,8 @@ import NameProxy, LocalName from require "moonscript.transform.names"
import Set from require "moonscript.data"
import ntype, has_value from require "moonscript.types"
import statement_compilers from require "moonscript.compile.statement"
import value_compilers from require "moonscript.compile.value"
statement_compilers = require "moonscript.compile.statement"
value_compilers = require "moonscript.compile.value"
import concat, insert from table
import pos_to_line, get_closest_line, trim, unpack from util
@ -161,6 +161,8 @@ class Block
export_all: false
export_proper: false
value_compilers: value_compilers
__tostring: =>
h = if "string" == type @header
@header
@ -217,7 +219,11 @@ class Block
is_local = true
name\get_name self
when NameProxy then name\get_name self
when "string" then name
when "table"
name[1] == "ref" and name[2]
when "string"
-- TODO: don't use string literal as ref
name
continue unless is_local or real_name and not @has_name real_name, true
-- put exported names so they can be assigned to in deeper scope
@ -241,6 +247,8 @@ class Block
name = name\get_name self if NameProxy == mtype name
@_names[name] = value
-- Check if a name is defined in the current or any enclosing scope
-- skip_exports: ignore names that have been exported using `export`
has_name: (name, skip_exports) =>
return true if not skip_exports and @name_exported name
@ -251,6 +259,18 @@ class Block
else
yes
is_local: (node) =>
t = mtype node
return @has_name(node, false) if t == "string"
return true if t == NameProxy or t == LocalName
if t == "table"
if node[1] == "ref" or (node[1] == "chain" and #node == 2)
return @is_local node[2]
false
free_name: (prefix, dont_put) =>
prefix = prefix or "moon"
searching = true
@ -304,10 +324,14 @@ class Block
is_value: (node) =>
t = ntype node
value_compilers[t] != nil or t == "value"
@value_compilers[t] != nil or t == "value"
-- line wise compile functions
name: (node, ...) => @value node, ...
-- compile name for assign
name: (node, ...) =>
if type(node) == "string"
node
else
@value node, ...
value: (node, ...) =>
node = @transform.value node
@ -316,7 +340,7 @@ class Block
else
node[1]
fn = value_compilers[action]
fn = @value_compilers[action]
error "Failed to compile value: "..dump.value node if not fn
out = fn self, node, ...

View File

@ -1,13 +1,18 @@
local util = require("moonscript.util")
local data = require("moonscript.data")
local reversed, unpack = util.reversed, util.unpack
local reversed, unpack
reversed, unpack = util.reversed, util.unpack
local ntype
do
local _table_0 = require("moonscript.types")
ntype = _table_0.ntype
local _obj_0 = require("moonscript.types")
ntype = _obj_0.ntype
end
local concat, insert = table.concat, table.insert
local statement_compilers = {
local concat, insert
do
local _obj_0 = table
concat, insert = _obj_0.concat, _obj_0.insert
end
return {
raw = function(self, node)
return self:add(node[2])
end,
@ -27,9 +32,8 @@ local statement_compilers = {
_with_0:append_list((function()
local _accum_0 = { }
local _len_0 = 1
local _list_0 = undeclared
for _index_0 = 1, #_list_0 do
local name = _list_0[_index_0]
for _index_0 = 1, #undeclared do
local name = undeclared[_index_0]
_accum_0[_len_0] = self:name(name)
_len_0 = _len_0 + 1
end
@ -47,9 +51,8 @@ local statement_compilers = {
_with_0:append_list((function()
local _accum_0 = { }
local _len_0 = 1
local _list_0 = names
for _index_0 = 1, #_list_0 do
local name = _list_0[_index_0]
for _index_0 = 1, #names do
local name = names[_index_0]
_accum_0[_len_0] = self:name(name)
_len_0 = _len_0 + 1
end
@ -81,9 +84,8 @@ local statement_compilers = {
_with_0:append_list((function()
local _accum_0 = { }
local _len_0 = 1
local _list_0 = names
for _index_0 = 1, #_list_0 do
local name = _list_0[_index_0]
for _index_0 = 1, #names do
local name = names[_index_0]
_accum_0[_len_0] = self:value(name)
_len_0 = _len_0 + 1
end
@ -94,9 +96,8 @@ local statement_compilers = {
_with_0:append_list((function()
local _accum_0 = { }
local _len_0 = 1
local _list_0 = values
for _index_0 = 1, #_list_0 do
local v = _list_0[_index_0]
for _index_0 = 1, #values do
local v = values[_index_0]
_accum_0[_len_0] = self:value(v)
_len_0 = _len_0 + 1
end
@ -139,9 +140,8 @@ local statement_compilers = {
current.next = next
current = next
end
local _list_0 = node
for _index_0 = 4, #_list_0 do
cond = _list_0[_index_0]
for _index_0 = 4, #node do
cond = node[_index_0]
add_clause(cond)
end
return root
@ -190,9 +190,8 @@ local statement_compilers = {
loop:append_list((function()
local _accum_0 = { }
local _len_0 = 1
local _list_0 = names
for _index_0 = 1, #_list_0 do
local name = _list_0[_index_0]
for _index_0 = 1, #names do
local name = names[_index_0]
_accum_0[_len_0] = _with_0:name(name, false)
_len_0 = _len_0 + 1
end
@ -202,9 +201,8 @@ local statement_compilers = {
loop:append_list((function()
local _accum_0 = { }
local _len_0 = 1
local _list_0 = exps
for _index_0 = 1, #_list_0 do
local exp = _list_0[_index_0]
for _index_0 = 1, #exps do
local exp = exps[_index_0]
_accum_0[_len_0] = self:value(exp)
_len_0 = _len_0 + 1
end
@ -242,8 +240,6 @@ local statement_compilers = {
_with_0:stms(node[2])
return _with_0
end
end
}
return {
statement_compilers = statement_compilers
end,
noop = function(self) end
}

View File

@ -6,7 +6,7 @@ import reversed, unpack from util
import ntype from require "moonscript.types"
import concat, insert from table
statement_compilers =
{
raw: (node) => @add node[2]
lines: (node) =>
@ -135,5 +135,5 @@ statement_compilers =
with @block!
\stms node[2]
{ :statement_compilers }
noop: => -- nothing!
}

View File

@ -2,22 +2,27 @@ local util = require("moonscript.util")
local data = require("moonscript.data")
local ntype
do
local _table_0 = require("moonscript.types")
ntype = _table_0.ntype
local _obj_0 = require("moonscript.types")
ntype = _obj_0.ntype
end
local user_error
do
local _table_0 = require("moonscript.errors")
user_error = _table_0.user_error
local _obj_0 = require("moonscript.errors")
user_error = _obj_0.user_error
end
local concat, insert = table.concat, table.insert
local unpack = util.unpack
local concat, insert
do
local _obj_0 = table
concat, insert = _obj_0.concat, _obj_0.insert
end
local unpack
unpack = util.unpack
local table_delim = ","
local string_chars = {
["\r"] = "\\r",
["\n"] = "\\n"
}
local value_compilers = {
return {
exp = function(self, node)
local _comp
_comp = function(i, value)
@ -48,9 +53,8 @@ local value_compilers = {
_with_0:append_list((function()
local _accum_0 = { }
local _len_0 = 1
local _list_0 = node
for _index_0 = 2, #_list_0 do
local v = _list_0[_index_0]
for _index_0 = 2, #node do
local v = node[_index_0]
_accum_0[_len_0] = self:value(v)
_len_0 = _len_0 + 1
end
@ -72,15 +76,20 @@ local value_compilers = {
end,
chain = function(self, node)
local callee = node[2]
local callee_type = ntype(callee)
if callee == -1 then
callee = self:get("scope_var")
if not callee then
user_error("Short-dot syntax must be called within a with block")
end
end
local sup = self:get("super")
if callee == "super" and sup then
return self:value(sup(self, node))
if callee_type == "ref" and callee[2] == "super" or callee == "super" then
do
local sup = self:get("super")
if sup then
return self:value(sup(self, node))
end
end
end
local chain_item
chain_item = function(node)
@ -96,12 +105,11 @@ local value_compilers = {
elseif t == "colon_stub" then
return user_error("Uncalled colon stub")
else
return error("Unknown chain action: " .. t)
return error("Unknown chain action: " .. tostring(t))
end
end
local t = ntype(callee)
if (t == "self" or t == "self_class") and node[3] and ntype(node[3]) == "call" then
callee[1] = t .. "_colon"
if (callee_type == "self" or callee_type == "self_class") and node[3] and ntype(node[3]) == "call" then
callee[1] = callee_type .. "_colon"
end
local callee_value = self:value(callee)
if ntype(callee) == "exp" then
@ -110,9 +118,8 @@ local value_compilers = {
local actions
do
local _with_0 = self:line()
local _list_0 = node
for _index_0 = 3, #_list_0 do
local action = _list_0[_index_0]
for _index_0 = 3, #node do
local action = node[_index_0]
_with_0:append(chain_item(action))
end
actions = _with_0
@ -123,12 +130,12 @@ local value_compilers = {
local _, args, whitelist, arrow, block = unpack(node)
local default_args = { }
local self_args = { }
local arg_names = (function()
local arg_names
do
local _accum_0 = { }
local _len_0 = 1
local _list_0 = args
for _index_0 = 1, #_list_0 do
local arg = _list_0[_index_0]
for _index_0 = 1, #args do
local arg = args[_index_0]
local name, default_value = unpack(arg)
if type(name) == "string" then
name = name
@ -145,8 +152,8 @@ local value_compilers = {
_accum_0[_len_0] = _value_0
_len_0 = _len_0 + 1
end
return _accum_0
end)()
arg_names = _accum_0
end
if arrow == "fat" then
insert(arg_names, 1, "self")
end
@ -155,14 +162,12 @@ local value_compilers = {
if #whitelist > 0 then
_with_0:whitelist_names(whitelist)
end
local _list_0 = arg_names
for _index_0 = 1, #_list_0 do
local name = _list_0[_index_0]
for _index_0 = 1, #arg_names do
local name = arg_names[_index_0]
_with_0:put_name(name)
end
local _list_1 = default_args
for _index_0 = 1, #_list_1 do
local default = _list_1[_index_0]
for _index_0 = 1, #default_args do
local default = default_args[_index_0]
local name, value = unpack(default)
if type(name) == "table" then
name = name[2]
@ -171,7 +176,10 @@ local value_compilers = {
'if',
{
'exp',
name,
{
"ref",
name
},
'==',
'nil'
},
@ -188,17 +196,17 @@ local value_compilers = {
}
})
end
local self_arg_values = (function()
local self_arg_values
do
local _accum_0 = { }
local _len_0 = 1
local _list_2 = self_args
for _index_0 = 1, #_list_2 do
local arg = _list_2[_index_0]
for _index_0 = 1, #self_args do
local arg = self_args[_index_0]
_accum_0[_len_0] = arg[2]
_len_0 = _len_0 + 1
end
return _accum_0
end)()
self_arg_values = _accum_0
end
if #self_args > 0 then
_with_0:stm({
"assign",
@ -208,17 +216,16 @@ local value_compilers = {
end
_with_0:stms(block)
if #args > #arg_names then
arg_names = (function()
do
local _accum_0 = { }
local _len_0 = 1
local _list_2 = args
for _index_0 = 1, #_list_2 do
local arg = _list_2[_index_0]
for _index_0 = 1, #args do
local arg = args[_index_0]
_accum_0[_len_0] = arg[1]
_len_0 = _len_0 + 1
end
return _accum_0
end)()
arg_names = _accum_0
end
end
_with_0.header = "function(" .. concat(arg_names, ", ") .. ")"
return _with_0
@ -282,28 +289,30 @@ local value_compilers = {
return self:line("not ", self:value(node[2]))
end,
self = function(self, node)
return "self." .. self:value(node[2])
return "self." .. self:name(node[2])
end,
self_class = function(self, node)
return "self.__class." .. self:value(node[2])
return "self.__class." .. self:name(node[2])
end,
self_colon = function(self, node)
return "self:" .. self:value(node[2])
return "self:" .. self:name(node[2])
end,
self_class_colon = function(self, node)
return "self.__class:" .. self:value(node[2])
return "self.__class:" .. self:name(node[2])
end,
ref = function(self, value)
do
local sup = value[2] == "super" and self:get("super")
if sup then
return self:value(sup(self))
end
end
return tostring(value[2])
end,
raw_value = function(self, value)
local sup = self:get("super")
if value == "super" and sup then
return self:value(sup(self))
end
if value == "..." then
self:send("varargs")
end
return tostring(value)
end
}
return {
value_compilers = value_compilers
}

View File

@ -14,7 +14,7 @@ string_chars = {
"\n": "\\n"
}
value_compilers =
{
-- list of values separated by binary operators
exp: (node) =>
_comp = (i, value) ->
@ -43,14 +43,16 @@ value_compilers =
chain: (node) =>
callee = node[2]
callee_type = ntype callee
if callee == -1
callee = @get "scope_var"
if not callee then user_error "Short-dot syntax must be called within a with block"
sup = @get "super"
if callee == "super" and sup
return @value sup self, node
-- TODO: don't use string literals as ref
if callee_type == "ref" and callee[2] == "super" or callee == "super"
if sup = @get "super"
return @value sup self, node
chain_item = (node) ->
t, arg = unpack node
@ -66,11 +68,10 @@ value_compilers =
elseif t == "colon_stub"
user_error "Uncalled colon stub"
else
error "Unknown chain action: "..t
error "Unknown chain action: #{t}"
t = ntype(callee)
if (t == "self" or t == "self_class") and node[3] and ntype(node[3]) == "call"
callee[1] = t.."_colon"
if (callee_type == "self" or callee_type == "self_class") and node[3] and ntype(node[3]) == "call"
callee[1] = callee_type.."_colon"
callee_value = @value callee
callee_value = @line "(", callee_value, ")" if ntype(callee) == "exp"
@ -109,7 +110,7 @@ value_compilers =
name, value = unpack default
name = name[2] if type(name) == "table"
\stm {
'if', {'exp', name, '==', 'nil'}, {
'if', {'exp', {"ref", name}, '==', 'nil'}, {
{'assign', {name}, {value}}
}
}
@ -172,27 +173,28 @@ value_compilers =
@line "not ", @value node[2]
self: (node) =>
"self."..@value node[2]
"self."..@name node[2]
self_class: (node) =>
"self.__class."..@value node[2]
"self.__class."..@name node[2]
self_colon: (node) =>
"self:"..@value node[2]
"self:"..@name node[2]
self_class_colon: (node) =>
"self.__class:"..@value node[2]
"self.__class:"..@name node[2]
-- a variable reference
ref: (value) =>
if sup = value[2] == "super" and @get "super"
return @value sup @
tostring value[2]
-- catch all pure string values
raw_value: (value) =>
sup = @get"super"
if value == "super" and sup
return @value sup self
if value == "..."
@send "varargs"
tostring value
{ :value_compilers }
}

View File

@ -1,17 +1,19 @@
local concat, remove, insert = table.concat, table.remove, table.insert
local concat, remove, insert
do
local _obj_0 = table
concat, remove, insert = _obj_0.concat, _obj_0.remove, _obj_0.insert
end
local Set
Set = function(items)
local self = { }
local _list_0 = items
for _index_0 = 1, #_list_0 do
local key = _list_0[_index_0]
self[key] = true
local _tbl_0 = { }
for _index_0 = 1, #items do
local k = items[_index_0]
_tbl_0[k] = true
end
return self
return _tbl_0
end
local Stack
do
local _parent_0 = nil
local _base_0 = {
__tostring = function(self)
return "<Stack {" .. concat(self, ", ") .. "}>"
@ -19,41 +21,28 @@ do
pop = function(self)
return remove(self)
end,
push = function(self, value)
push = function(self, value, ...)
insert(self, value)
return value
if ... then
return self:push(...)
else
return value
end
end,
top = function(self)
return self[#self]
end
}
_base_0.__index = _base_0
if _parent_0 then
setmetatable(_base_0, _parent_0.__base)
end
local _class_0 = setmetatable({
__init = function(self, ...)
local _list_0 = {
...
}
for _index_0 = 1, #_list_0 do
local v = _list_0[_index_0]
self:push(v)
end
self:push(...)
return nil
end,
__base = _base_0,
__name = "Stack",
__parent = _parent_0
__name = "Stack"
}, {
__index = function(cls, name)
local val = rawget(_base_0, name)
if val == nil and _parent_0 then
return _parent_0[name]
else
return val
end
end,
__index = _base_0,
__call = function(cls, ...)
local _self_0 = setmetatable({}, _base_0)
cls.__init(_self_0, ...)
@ -61,9 +50,6 @@ do
end
})
_base_0.__class = _class_0
if _parent_0 and _parent_0.__inherited then
_parent_0.__inherited(_parent_0, _class_0)
end
Stack = _class_0
end
local lua_keywords = Set({

View File

@ -2,30 +2,30 @@
import concat, remove, insert from table
Set = (items) ->
self = {}
self[key] = true for key in *items
self
Set = (items) -> {k,true for k in *items}
class Stack
__tostring: => "<Stack {"..concat(self, ", ").."}>"
new: (...) =>
@push v for v in *{...}
@push ...
nil
pop: =>
remove self
remove @
push: (value) =>
insert self, value
value
push: (value, ...) =>
insert @, value
if ...
@push ...
else
value
top: =>
self[#self]
lua_keywords = Set{
lua_keywords = Set {
'and', 'break', 'do', 'else', 'elseif',
'end', 'false', 'for', 'function', 'if',
'in', 'local', 'nil', 'not', 'or',

View File

@ -9,17 +9,17 @@ flat_value = function(op, depth)
if type(op) ~= "table" then
return tostring(op)
end
local items = (function()
local items
do
local _accum_0 = { }
local _len_0 = 1
local _list_0 = op
for _index_0 = 1, #_list_0 do
local item = _list_0[_index_0]
for _index_0 = 1, #op do
local item = op[_index_0]
_accum_0[_len_0] = flat_value(item, depth + 1)
_len_0 = _len_0 + 1
end
return _accum_0
end)()
items = _accum_0
end
local pos = op[-1]
return "{" .. (pos and "[" .. pos .. "] " or "") .. table.concat(items, ", ") .. "}"
end

View File

@ -1,7 +1,12 @@
local util = require("moonscript.util")
local lpeg = require("lpeg")
local concat, insert = table.concat, table.insert
local split, pos_to_line = util.split, util.pos_to_line
local concat, insert
do
local _obj_0 = table
concat, insert = _obj_0.concat, _obj_0.insert
end
local split, pos_to_line
split, pos_to_line = util.split, util.pos_to_line
local user_error
user_error = function(...)
return error({
@ -42,18 +47,17 @@ truncate_traceback = function(traceback, chunk_func)
end
stop = stop - 1
end
traceback = (function()
do
local _accum_0 = { }
local _len_0 = 1
local _list_0 = traceback
local _max_0 = stop
for _index_0 = 1, _max_0 < 0 and #_list_0 + _max_0 or _max_0 do
local t = _list_0[_index_0]
for _index_0 = 1, _max_0 < 0 and #traceback + _max_0 or _max_0 do
local t = traceback[_index_0]
_accum_0[_len_0] = t
_len_0 = _len_0 + 1
end
return _accum_0
end)()
traceback = _accum_0
end
local rep = "function '" .. chunk_func .. "'"
traceback[#traceback] = traceback[#traceback]:gsub(rep, "main chunk")
return concat(traceback, "\n")
@ -61,7 +65,8 @@ end
local rewrite_traceback
rewrite_traceback = function(text, err)
local line_tables = require("moonscript.line_tables")
local V, S, Ct, C = lpeg.V, lpeg.S, lpeg.Ct, lpeg.C
local V, S, Ct, C
V, S, Ct, C = lpeg.V, lpeg.S, lpeg.Ct, lpeg.C
local header_text = "stack traceback:"
local Header, Line = V("Header"), V("Line")
local Break = lpeg.S("\n")
@ -107,5 +112,6 @@ end
return {
rewrite_traceback = rewrite_traceback,
truncate_traceback = truncate_traceback,
user_error = user_error
user_error = user_error,
reverse_line_number = reverse_line_number
}

View File

@ -84,5 +84,5 @@ rewrite_traceback = (text, err) ->
}, "\n"
{ :rewrite_traceback, :truncate_traceback, :user_error }
{ :rewrite_traceback, :truncate_traceback, :user_error, :reverse_line_number }

View File

@ -1,113 +1,5 @@
local compile = require("moonscript.compile")
local parse = require("moonscript.parse")
local concat, insert = table.concat, table.insert
local split, dump, get_options, unpack
do
local _table_0 = require("moonscript.util")
split, dump, get_options, unpack = _table_0.split, _table_0.dump, _table_0.get_options, _table_0.unpack
local _with_0 = require("moonscript.base")
_with_0.insert_loader()
return _with_0
end
local lua = {
loadstring = loadstring,
load = load
}
local dirsep, line_tables, create_moonpath, to_lua, moon_loader, init_loader, loadstring, loadfile, dofile
dirsep = "/"
line_tables = require("moonscript.line_tables")
create_moonpath = function(package_path)
local paths = split(package_path, ";")
for i, path in ipairs(paths) do
local p = path:match("^(.-)%.lua$")
if p then
paths[i] = p .. ".moon"
end
end
return concat(paths, ";")
end
to_lua = function(text, options)
if options == nil then
options = { }
end
if "string" ~= type(text) then
local t = type(text)
return nil, "expecting string (got " .. t .. ")", 2
end
local tree, err = parse.string(text)
if not tree then
return nil, err
end
local code, ltable, pos = compile.tree(tree, options)
if not code then
return nil, compile.format_error(ltable, pos, text), 2
end
return code, ltable
end
moon_loader = function(name)
local name_path = name:gsub("%.", dirsep)
local file, file_path
local _list_0 = split(package.moonpath, ";")
for _index_0 = 1, #_list_0 do
local path = _list_0[_index_0]
file_path = path:gsub("?", name_path)
file = io.open(file_path)
if file then
break
end
end
if file then
local text = file:read("*a")
file:close()
local res, err = loadstring(text, file_path)
if not res then
error(err)
end
return res
end
return nil, "Could not find moon file"
end
if not package.moonpath then
package.moonpath = create_moonpath(package.path)
end
init_loader = function()
return insert(package.loaders or package.searchers, 2, moon_loader)
end
if not (_G.moon_no_loader) then
init_loader()
end
loadstring = function(...)
local options, str, chunk_name, mode, env = get_options(...)
chunk_name = chunk_name or "=(moonscript.loadstring)"
local code, ltable_or_err = to_lua(str, options)
if not (code) then
return nil, ltable_or_err
end
if chunk_name then
line_tables[chunk_name] = ltable_or_err
end
return (lua.loadstring or lua.load)(code, chunk_name, unpack({
mode,
env
}))
end
loadfile = function(fname, ...)
local file, err = io.open(fname)
if not (file) then
return nil, err
end
local text = assert(file:read("*a"))
file:close()
return loadstring(text, fname, ...)
end
dofile = function(...)
local f = assert(loadfile(...))
return f()
end
return {
_NAME = "moonscript",
to_lua = to_lua,
moon_chunk = moon_chunk,
moon_loader = moon_loader,
dirsep = dirsep,
dofile = dofile,
loadfile = loadfile,
loadstring = loadstring
}

View File

@ -1,95 +1,2 @@
compile = require "moonscript.compile"
parse = require "moonscript.parse"
import concat, insert from table
import split, dump, get_options, unpack from require "moonscript.util"
lua = :loadstring, :load
local *
dirsep = "/"
line_tables = require "moonscript.line_tables"
-- create moon path package from lua package path
create_moonpath = (package_path) ->
paths = split package_path, ";"
for i, path in ipairs paths
p = path\match "^(.-)%.lua$"
if p then paths[i] = p..".moon"
concat paths, ";"
to_lua = (text, options={}) ->
if "string" != type text
t = type text
return nil, "expecting string (got ".. t ..")", 2
tree, err = parse.string text
if not tree
return nil, err
code, ltable, pos = compile.tree tree, options
if not code
return nil, compile.format_error(ltable, pos, text), 2
code, ltable
moon_loader = (name) ->
name_path = name\gsub "%.", dirsep
local file, file_path
for path in *split package.moonpath, ";"
file_path = path\gsub "?", name_path
file = io.open file_path
break if file
if file
text = file\read "*a"
file\close!
res, err = loadstring text, file_path
if not res
error err
return res
return nil, "Could not find moon file"
if not package.moonpath
package.moonpath = create_moonpath package.path
init_loader = ->
insert package.loaders or package.searchers, 2, moon_loader
init_loader! unless _G.moon_no_loader
loadstring = (...) ->
options, str, chunk_name, mode, env = get_options ...
chunk_name or= "=(moonscript.loadstring)"
code, ltable_or_err = to_lua str, options
unless code
return nil, ltable_or_err
line_tables[chunk_name] = ltable_or_err if chunk_name
-- the unpack prevents us from passing nil
(lua.loadstring or lua.load) code, chunk_name, unpack { mode, env }
loadfile = (fname, ...) ->
file, err = io.open fname
return nil, err unless file
text = assert file\read "*a"
file\close!
loadstring text, fname, ...
-- throws errros
dofile = (...) ->
f = assert loadfile ...
f!
{
_NAME: "moonscript"
:to_lua, :moon_chunk, :moon_loader, :dirsep, :dofile, :loadfile,
:loadstring
}
with require "moonscript.base"
.insert_loader!

View File

@ -174,8 +174,12 @@ end
local _chain_assignable = { index = true, dot = true, slice = true }
local function is_assignable(node)
if node == "..." then
return false
end
local t = ntype(node)
return t == "self" or t == "value" or t == "self_class" or
return t == "ref" or t == "self" or t == "value" or t == "self_class" or
t == "chain" and _chain_assignable[ntype(node[#node])] or
t == "table"
end
@ -378,8 +382,7 @@ local build_grammar = wrap_env(function()
_Name / mark"self" + Cc"self")
local KeyName = SelfName + Space * _Name / mark"key_literal"
local Name = SelfName + Name + Space * "..." / trim
local VarArg = Space * P"..." / trim
local g = lpeg.P{
File,
@ -409,11 +412,9 @@ local build_grammar = wrap_env(function()
Local = key"local" * ((op"*" + op"^") / mark"declare_glob" + Ct(NameList) / mark"declare_with_shadows"),
Import = key"import" * Ct(ImportNameList) * key"from" * Exp / mark"import",
Import = key"import" * Ct(ImportNameList) * SpaceBreak^0 * key"from" * Exp / mark"import",
ImportName = (sym"\\" * Ct(Cc"colon_stub" * Name) + Name),
ImportNameList = ImportName * (sym"," * ImportName)^0,
NameList = Name * (sym"," * Name)^0,
ImportNameList = SpaceBreak^0 * ImportName * ((SpaceBreak^1 + sym"," * SpaceBreak^0) * ImportName)^0,
BreakLoop = Ct(key"break"/trim) + Ct(key"continue"/trim),
@ -461,8 +462,7 @@ local build_grammar = wrap_env(function()
-- we can ignore precedence for now
OtherOps = op"or" + op"and" + op"<=" + op">=" + op"~=" + op"!=" + op"==" + op".." + op"<" + op">",
Assignable = Cmt(DotChain + Chain, check_assignable) + Name,
AssignableList = Assignable * (sym"," * Assignable)^0,
Assignable = Cmt(DotChain + Chain, check_assignable) + Name + SelfName,
Exp = Ct(Value * ((OtherOps + FactorOp + TermOp) * Value)^0) / flatten_or_mark"exp",
@ -511,7 +511,7 @@ local build_grammar = wrap_env(function()
LuaStringOpen = sym"[" * P"="^0 * "[" / trim,
LuaStringClose = "]" * P"="^0 * "]",
Callable = Name + Parens / mark"parens",
Callable = pos(Name / mark"ref") + SelfName + VarArg + Parens / mark"parens",
Parens = sym"(" * Exp * sym")",
FnArgs = symx"(" * Ct(ExpList^-1) * sym")" + sym"!" * -P"=" * Ct"",
@ -575,7 +575,7 @@ local build_grammar = wrap_env(function()
op"*" + op"^" +
Ct(NameList) * (sym"=" * Ct(ExpListLow))^-1) / mark"export",
KeyValue = (sym":" * Name) / self_assign + Ct((KeyName + sym"[" * Exp * sym"]" + DoubleString + SingleString) * symx":" * (Exp + TableBlock)),
KeyValue = (sym":" * -SomeSpace * Name) / self_assign + Ct((KeyName + sym"[" * Exp * sym"]" + DoubleString + SingleString) * symx":" * (Exp + TableBlock)),
KeyValueList = KeyValue * (sym"," * KeyValue)^0,
KeyValueLine = CheckIndent * KeyValueList * sym","^-1,
@ -583,8 +583,8 @@ local build_grammar = wrap_env(function()
(key"using" * Ct(NameList + Space * "nil") + Ct"") *
sym")" + Ct"" * Ct"",
FnArgDefList = FnArgDef * (sym"," * FnArgDef)^0,
FnArgDef = Ct(Name * (sym"=" * Exp)^-1),
FnArgDefList = FnArgDef * (sym"," * FnArgDef)^0 * (sym"," * Ct(VarArg))^0 + Ct(VarArg),
FnArgDef = Ct((Name + SelfName) * (sym"=" * Exp)^-1),
FunLit = FnArgsDef *
(sym"->" * Cc"slim" + sym"=>" * Cc"fat") *

File diff suppressed because it is too large Load Diff

View File

@ -9,8 +9,9 @@ import insert from table
import NameProxy, LocalName from require "moonscript.transform.names"
destructure = require "moonscript.transform.destructure"
NOOP = {"noop"}
local implicitly_return
local *
class Run
new: (@fn) =>
@ -32,7 +33,7 @@ apply_to_last = (stms, fn) ->
return for i, stm in ipairs stms
if i == last_exp_id
fn stm
{"transform", stm, fn}
else
stm
@ -54,7 +55,11 @@ extract_declarations = (body=@current_stms, start=@current_stm_i + 1, out={}) =>
switch stm[1]
when "assign", "declare"
for name in *stm[2]
insert out, name if type(name) == "string"
if ntype(name) == "ref"
insert out, name
elseif type(name) == "string"
-- TODO: don't use string literal as ref
insert out, name
when "group"
extract_declarations @, stm[2], 1, out
out
@ -107,6 +112,16 @@ class Transformer
new: (@transformers) =>
@seen_nodes = setmetatable {}, __mode: "k"
transform_once: (scope, node, ...) =>
return node if @seen_nodes[node]
@seen_nodes[node] = true
transformer = @transformers[ntype node]
if transformer
transformer(scope, node, ...) or node
else
node
transform: (scope, node, ...) =>
return node if @seen_nodes[node]
@seen_nodes[node] = true
@ -150,15 +165,33 @@ construct_comprehension = (inner, clauses) ->
current_stms[1]
Statement = Transformer {
transform: (tuple) =>
{_, node, fn} = tuple
fn node
root_stms: (body) =>
apply_to_last body, implicitly_return @
return: (node) =>
node[2] = Value\transform_once @, node[2]
if "block_exp" == ntype node[2]
block_exp = node[2]
block_body = block_exp[2]
idx = #block_body
node[2] = block_body[idx]
block_body[idx] = node
return build.group block_body
node
declare_glob: (node) =>
names = extract_declarations @
if node[2] == "^"
names = for name in *names
continue unless name\match "^%u"
continue unless name[2]\match "^%u"
name
{"declare", names}
@ -166,8 +199,30 @@ Statement = Transformer {
assign: (node) =>
names, values = unpack node, 2
num_values = #values
num_names = #values
-- special code simplifications for single assigns
if num_names == 1 and num_values == 1
first_value = values[1]
first_name = names[1]
switch ntype first_value
when "block_exp"
block_body = first_value[2]
idx = #block_body
block_body[idx] = build.assign_one first_name, block_body[idx]
return build.group {
{"declare", {first_name}}
{"do", block_body}
}
when "comprehension", "tblcomprehension", "foreach", "for", "while"
return build.assign_one first_name, Value\transform_once @, first_value
-- bubble cascading assigns
transformed = if #values == 1
transformed = if num_values == 1
value = values[1]
t = ntype value
@ -190,9 +245,8 @@ Statement = Transformer {
node = transformed or node
if destructure.has_destructure names
return destructure.split_assign node
return destructure.split_assign @, node
-- print util.dump node
node
continue: (node) =>
@ -213,8 +267,9 @@ Statement = Transformer {
cls
}
else
-- pull out vawlues and assign them after the export
build.group {
node
{ "export", node[2] }
build.assign {
names: node[2]
values: node[3]
@ -232,33 +287,16 @@ Statement = Transformer {
import: (node) =>
_, names, source = unpack node
stubs = for name in *names
if type(name) == "table"
name
table_values = for name in *names
dest_val = if ntype(name) == "colon_stub"
name[2]
else
{"dot", name}
name
real_names = for name in *names
type(name) == "table" and name[2] or name
{{"key_literal", name}, dest_val}
if type(source) == "string"
build.assign {
names: real_names
values: [build.chain { base: source, stub} for stub in *stubs]
}
else
source_name = NameProxy "table"
build.group {
{"declare", real_names}
build["do"] {
build.assign_one source_name, source
build.assign {
names: real_names
values: [build.chain { base: source_name, stub} for stub in *stubs]
}
}
}
dest = { "table", table_values }
{ "assign", {dest}, {source}, [-1]: node[-1] }
comprehension: (node, action) =>
_, exp, clauses = unpack node
@ -287,7 +325,7 @@ Statement = Transformer {
if ntype(stm) == "assign"
wrapped = build.group {
build.declare names: [name for name in *stm[2] when type(name) == "string"]
build.declare names: [name for name in *stm[2] when ntype(name) == "ref"]
wrapped
}
@ -304,7 +342,7 @@ Statement = Transformer {
name = NameProxy "des"
body = {
destructure.build_assign assign[2][1], name
destructure.build_assign @, assign[2][1], name
build.group node[3]
}
@ -334,28 +372,44 @@ Statement = Transformer {
node
with: (node, ret) =>
_, exp, block = unpack node
exp, block = unpack node, 2
scope_name = NameProxy "with"
copy_scope = true
local scope_name, named_assign
named_assign = if ntype(exp) == "assign"
if ntype(exp) == "assign"
names, values = unpack exp, 2
assign_name = names[1]
exp = values[1]
values[1] = scope_name
{"assign", names, values}
first_name = names[1]
if ntype(first_name) == "ref"
scope_name = first_name
named_assign = exp
exp = values[1]
copy_scope = false
else
scope_name = NameProxy "with"
exp = values[1]
values[1] = scope_name
named_assign = {"assign", names, values}
elseif @is_local exp
scope_name = exp
copy_scope = false
scope_name or= NameProxy "with"
build.do {
Run => @set "scope_var", scope_name
build.assign_one scope_name, exp
build.group { named_assign }
copy_scope and build.assign_one(scope_name, exp) or NOOP
named_assign or NOOP
build.group block
if ret
ret scope_name
}
foreach: (node) =>
foreach: (node, _) =>
smart_node node
source = unpack node.iter
@ -363,7 +417,7 @@ Statement = Transformer {
node.names = for i, name in ipairs node.names
if ntype(name) == "table"
with proxy = NameProxy "des"
insert destructures, destructure.build_assign name, proxy
insert destructures, destructure.build_assign @, name, proxy
else
name
@ -375,7 +429,8 @@ Statement = Transformer {
list = source[2]
index_name = NameProxy "index"
list_name = NameProxy "list"
list_name = @is_local(list) and list or NameProxy "list"
slice_var = nil
bounds = if is_slice list
@ -383,6 +438,8 @@ Statement = Transformer {
table.remove list
table.remove slice, 1
list_name = list if @is_local list
slice[2] = if slice[2] and slice[2] != ""
max_tmp_name = NameProxy "max"
slice_var = build.assign_one max_tmp_name, slice[2]
@ -397,13 +454,13 @@ Statement = Transformer {
{1, {"length", list_name}}
return build.group {
build.assign_one list_name, list
slice_var
list_name != list and build.assign_one(list_name, list) or NOOP
slice_var or NOOP
build["for"] {
name: index_name
bounds: bounds
body: {
{"assign", node.names, {list_name\index index_name}}
{"assign", node.names, { NameProxy.index list_name, index_name }}
build.group node.body
}
}
@ -468,6 +525,7 @@ Statement = Transformer {
class: (node, ret, parent_assign) =>
_, name, parent_val, body = unpack node
parent_val = nil if parent_val == ""
-- split apart properties and statements
statements = {}
@ -499,18 +557,16 @@ Statement = Transformer {
cls_name = NameProxy "class"
unless constructor
constructor = build.fndef {
args: {{"..."}}
arrow: "fat"
body: {
build["if"] {
cond: parent_cls_name
then: {
build.chain { base: "super", {"call", {"..."}} }
}
constructor = if parent_val
build.fndef {
args: {{"..."}}
arrow: "fat"
body: {
build.chain { base: "super", {"call", {"..."}} }
}
}
}
else
build.fndef!
real_name = name or parent_assign and parent_assign[2][1]
real_name = switch ntype real_name
@ -526,34 +582,48 @@ Statement = Transformer {
when "nil"
"nil"
else
{"string", '"', real_name}
name_t = type real_name
-- TODO: don't use string literal as ref
flattened_name = if name_t == "string"
real_name
elseif name_t == "table" and real_name[1] == "ref"
real_name[2]
else
error "don't know how to extract name from #{name_t}"
{"string", '"', flattened_name}
cls = build.table {
{"__init", constructor}
{"__base", base_name}
{"__name", real_name} -- "quote the string"
{"__parent", parent_cls_name}
parent_val and {"__parent", parent_cls_name} or nil
}
-- look up a name in the class object
class_lookup = build["if"] {
cond: {"exp", "val", "==", "nil", "and", parent_cls_name}
then: {
parent_cls_name\index"name"
-- looking up a name in the class object
class_index = if parent_val
class_lookup = build["if"] {
cond: { "exp", {"ref", "val"}, "==", "nil" }
then: {
parent_cls_name\index"name"
}
}
}
insert class_lookup, {"else", {"val"}}
insert class_lookup, {"else", {"val"}}
cls_mt = build.table {
{"__index", build.fndef {
build.fndef {
args: {{"cls"}, {"name"}}
body: {
build.assign_one LocalName"val", build.chain {
base: "rawget", {"call", {base_name, "name"}}
base: "rawget", {"call", {base_name, {"ref", "name"}}}
}
class_lookup
}
}}
}
else
base_name
cls_mt = build.table {
{"__index", class_index}
{"__call", build.fndef {
args: {{"cls"}, {"..."}}
body: {
@ -617,22 +687,18 @@ Statement = Transformer {
{"declare_glob", "*"}
.assign_one parent_cls_name, parent_val == "" and "nil" or parent_val
parent_val and .assign_one(parent_cls_name, parent_val) or NOOP
.assign_one base_name, {"table", properties}
.assign_one base_name\chain"__index", base_name
.if {
cond: parent_cls_name
then: {
.chain {
base: "setmetatable"
{"call", {
base_name,
.chain { base: parent_cls_name, {"dot", "__base"}}
}}
}
}
}
parent_val and .chain({
base: "setmetatable"
{"call", {
base_name,
.chain { base: parent_cls_name, {"dot", "__base"}}
}}
}) or NOOP
.assign_one cls_name, cls
.assign_one base_name\chain"__class", cls_name
@ -643,16 +709,14 @@ Statement = Transformer {
}
-- run the inherited callback
.if {
cond: {"exp",
parent_cls_name, "and", parent_cls_name\chain "__inherited"
}
parent_val and .if({
cond: {"exp", parent_cls_name\chain "__inherited" }
then: {
parent_cls_name\chain "__inherited", {"call", {
parent_cls_name, cls_name
}}
}
}
}) or NOOP
.group if name then {
.assign_one name, cls_name
@ -676,7 +740,7 @@ Statement = Transformer {
class Accumulator
body_idx: { for: 4, while: 3, foreach: 4 }
new: =>
new: (accum_name) =>
@accum_name = NameProxy "accum"
@value_name = NameProxy "value"
@len_name = NameProxy "len"
@ -688,12 +752,12 @@ class Accumulator
@wrap node
-- wrap the node into a block_exp
wrap: (node) =>
build.block_exp {
wrap: (node, group_type="block_exp") =>
build[group_type] {
build.assign_one @accum_name, build.table!
build.assign_one @len_name, 1
node
@accum_name
group_type == "block_exp" and @accum_name or NOOP
}
-- mutates the body of a loop construct to save last value into accumulator
@ -716,7 +780,7 @@ class Accumulator
@value_name
update = {
build.assign_one @accum_name\index(@len_name), val
build.assign_one NameProxy.index(@accum_name, @len_name), val
{"update", @len_name, "+=", 1}
}
@ -742,7 +806,7 @@ implicitly_return = (scope) ->
elseif types.manual_return[t] or not types.is_value stm
-- remove blank return statement
if is_top and t == "return" and stm[2] == ""
nil
NOOP
else
stm
else
@ -857,7 +921,7 @@ Value = Transformer {
base_name = NameProxy "base"
fn_name = NameProxy "fn"
is_super = node[2] == "super"
is_super = ntype(node[2]) == "ref" and node[2][2] == "super"
@transform.value build.block_exp {
build.assign {
names: {base_name}

View File

@ -1,50 +1,52 @@
local ntype, mtype, build
do
local _table_0 = require("moonscript.types")
ntype, mtype, build = _table_0.ntype, _table_0.mtype, _table_0.build
local _obj_0 = require("moonscript.types")
ntype, mtype, build = _obj_0.ntype, _obj_0.mtype, _obj_0.build
end
local NameProxy
do
local _table_0 = require("moonscript.transform.names")
NameProxy = _table_0.NameProxy
local _obj_0 = require("moonscript.transform.names")
NameProxy = _obj_0.NameProxy
end
local insert
do
local _obj_0 = table
insert = _obj_0.insert
end
local insert = table.insert
local unpack
do
local _table_0 = require("moonscript.util")
unpack = _table_0.unpack
local _obj_0 = require("moonscript.util")
unpack = _obj_0.unpack
end
local user_error
do
local _table_0 = require("moonscript.errors")
user_error = _table_0.user_error
local _obj_0 = require("moonscript.errors")
user_error = _obj_0.user_error
end
local util = require("moonscript.util")
local join
join = function(...)
do
local _with_0 = { }
local out = _with_0
local out = { }
local i = 1
local _list_0 = {
...
}
for _index_0 = 1, #_list_0 do
local tbl = _list_0[_index_0]
local _list_1 = tbl
for _index_1 = 1, #_list_1 do
local v = _list_1[_index_1]
for _index_1 = 1, #tbl do
local v = tbl[_index_1]
out[i] = v
i = i + 1
end
end
return _with_0
return out
end
end
local has_destructure
has_destructure = function(names)
local _list_0 = names
for _index_0 = 1, #_list_0 do
local n = _list_0[_index_0]
for _index_0 = 1, #names do
local n = names[_index_0]
if ntype(n) == "table" then
return true
end
@ -78,10 +80,15 @@ extract_assign_names = function(name, accum, prefix)
local key = tuple[1]
local s
if ntype(key) == "key_literal" then
s = {
"dot",
key[2]
}
local key_name = key[2]
if ntype(key_name) == "colon_stub" then
s = key_name
else
s = {
"dot",
key_name
}
end
else
s = {
"index",
@ -93,13 +100,13 @@ extract_assign_names = function(name, accum, prefix)
suffix = join(prefix, {
suffix
})
local t = ntype(value)
if t == "value" or t == "chain" or t == "self" then
local _exp_0 = ntype(value)
if "value" == _exp_0 or "ref" == _exp_0 or "chain" == _exp_0 or "self" == _exp_0 then
insert(accum, {
value,
suffix
})
elseif t == "table" then
elseif "table" == _exp_0 then
extract_assign_names(value, accum, suffix)
else
user_error("Can't destructure value of type: " .. tostring(ntype(value)))
@ -108,7 +115,7 @@ extract_assign_names = function(name, accum, prefix)
return accum
end
local build_assign
build_assign = function(destruct_literal, receiver)
build_assign = function(scope, destruct_literal, receiver)
local extracted_names = extract_assign_names(destruct_literal)
local names = { }
local values = { }
@ -118,12 +125,11 @@ build_assign = function(destruct_literal, receiver)
values
}
local obj
if mtype(receiver) == NameProxy then
if scope:is_local(receiver) then
obj = receiver
else
do
local _with_0 = NameProxy("obj")
obj = _with_0
obj = NameProxy("obj")
inner = build["do"]({
build.assign_one(obj, receiver),
{
@ -132,14 +138,13 @@ build_assign = function(destruct_literal, receiver)
values
}
})
obj = _with_0
obj = obj
end
end
local _list_0 = extracted_names
for _index_0 = 1, #_list_0 do
local tuple = _list_0[_index_0]
for _index_0 = 1, #extracted_names do
local tuple = extracted_names[_index_0]
insert(names, tuple[1])
insert(values, obj:chain(unpack(tuple[2])))
insert(values, NameProxy.chain(obj, unpack(tuple[2])))
end
return build.group({
{
@ -150,7 +155,7 @@ build_assign = function(destruct_literal, receiver)
})
end
local split_assign
split_assign = function(assign)
split_assign = function(scope, assign)
local names, values = unpack(assign, 2)
local g = { }
local total_names = #names
@ -182,7 +187,7 @@ split_assign = function(assign)
end)()
})
end
insert(g, build_assign(n, values[i]))
insert(g, build_assign(scope, n, values[i]))
start = i + 1
end
end
@ -193,15 +198,15 @@ split_assign = function(assign)
"_"
}
else
name_slice = (function()
do
local _accum_0 = { }
local _len_0 = 1
for i = start, total_names do
_accum_0[_len_0] = names[i]
_len_0 = _len_0 + 1
end
return _accum_0
end)()
name_slice = _accum_0
end
end
local value_slice
if total_values < start then
@ -209,15 +214,15 @@ split_assign = function(assign)
"nil"
}
else
value_slice = (function()
do
local _accum_0 = { }
local _len_0 = 1
for i = start, total_values do
_accum_0[_len_0] = values[i]
_len_0 = _len_0 + 1
end
return _accum_0
end)()
value_slice = _accum_0
end
end
insert(g, {
"assign",

View File

@ -6,6 +6,8 @@ import unpack from require "moonscript.util"
import user_error from require "moonscript.errors"
util = require "moonscript.util"
join = (...) ->
with out = {}
i = 1
@ -29,7 +31,11 @@ extract_assign_names = (name, accum={}, prefix={}) ->
else
key = tuple[1]
s = if ntype(key) == "key_literal"
{"dot", key[2]}
key_name = key[2]
if ntype(key_name) == "colon_stub"
key_name
else
{"dot", key_name}
else
{"index", key}
@ -37,17 +43,17 @@ extract_assign_names = (name, accum={}, prefix={}) ->
suffix = join prefix, {suffix}
t = ntype value
if t == "value" or t == "chain" or t == "self"
insert accum, {value, suffix}
elseif t == "table"
extract_assign_names value, accum, suffix
else
user_error "Can't destructure value of type: #{ntype value}"
switch ntype value
when "value", "ref", "chain", "self"
insert accum, {value, suffix}
when "table"
extract_assign_names value, accum, suffix
else
user_error "Can't destructure value of type: #{ntype value}"
accum
build_assign = (destruct_literal, receiver) ->
build_assign = (scope, destruct_literal, receiver) ->
extracted_names = extract_assign_names destruct_literal
names = {}
@ -55,7 +61,7 @@ build_assign = (destruct_literal, receiver) ->
inner = {"assign", names, values}
obj = if mtype(receiver) == NameProxy
obj = if scope\is_local receiver
receiver
else
with obj = NameProxy "obj"
@ -66,7 +72,7 @@ build_assign = (destruct_literal, receiver) ->
for tuple in *extracted_names
insert names, tuple[1]
insert values, obj\chain unpack tuple[2]
insert values, NameProxy.chain obj, unpack tuple[2]
build.group {
{"declare", names}
@ -74,7 +80,7 @@ build_assign = (destruct_literal, receiver) ->
}
-- applies to destructuring to a assign node
split_assign = (assign) ->
split_assign = (scope, assign) ->
names, values = unpack assign, 2
g = {}
@ -96,7 +102,7 @@ split_assign = (assign) ->
values[i]
}
insert g, build_assign n, values[i]
insert g, build_assign scope, n, values[i]
start = i + 1

View File

@ -1,42 +1,30 @@
local build
do
local _table_0 = require("moonscript.types")
build = _table_0.build
local _obj_0 = require("moonscript.types")
build = _obj_0.build
end
local unpack
do
local _table_0 = require("moonscript.util")
unpack = _table_0.unpack
local _obj_0 = require("moonscript.util")
unpack = _obj_0.unpack
end
local LocalName
do
local _parent_0 = nil
local _base_0 = {
get_name = function(self)
return self.name
end
}
_base_0.__index = _base_0
if _parent_0 then
setmetatable(_base_0, _parent_0.__base)
end
local _class_0 = setmetatable({
__init = function(self, name)
self.name = name
self[1] = "temp_name"
end,
__base = _base_0,
__name = "LocalName",
__parent = _parent_0
__name = "LocalName"
}, {
__index = function(cls, name)
local val = rawget(_base_0, name)
if val == nil and _parent_0 then
return _parent_0[name]
else
return val
end
end,
__index = _base_0,
__call = function(cls, ...)
local _self_0 = setmetatable({}, _base_0)
cls.__init(_self_0, ...)
@ -44,14 +32,10 @@ do
end
})
_base_0.__class = _class_0
if _parent_0 and _parent_0.__inherited then
_parent_0.__inherited(_parent_0, _class_0)
end
LocalName = _class_0
end
local NameProxy
do
local _parent_0 = nil
local _base_0 = {
get_name = function(self, scope, dont_put)
if dont_put == nil then
@ -63,32 +47,29 @@ do
return self.name
end,
chain = function(self, ...)
local items = (function(...)
local _accum_0 = { }
local _len_0 = 1
local _list_0 = {
...
}
for _index_0 = 1, #_list_0 do
local i = _list_0[_index_0]
if type(i) == "string" then
_accum_0[_len_0] = {
"dot",
i
}
else
_accum_0[_len_0] = i
end
_len_0 = _len_0 + 1
end
return _accum_0
end)(...)
return build.chain({
local items = {
base = self,
unpack(items)
})
...
}
for k, v in ipairs(items) do
if type(v) == "string" then
items[k] = {
"dot",
v
}
else
items[k] = v
end
end
return build.chain(items)
end,
index = function(self, key)
if type(key) == "string" then
key = {
"ref",
key
}
end
return build.chain({
base = self,
{
@ -106,26 +87,15 @@ do
end
}
_base_0.__index = _base_0
if _parent_0 then
setmetatable(_base_0, _parent_0.__base)
end
local _class_0 = setmetatable({
__init = function(self, prefix)
self.prefix = prefix
self[1] = "temp_name"
end,
__base = _base_0,
__name = "NameProxy",
__parent = _parent_0
__name = "NameProxy"
}, {
__index = function(cls, name)
local val = rawget(_base_0, name)
if val == nil and _parent_0 then
return _parent_0[name]
else
return val
end
end,
__index = _base_0,
__call = function(cls, ...)
local _self_0 = setmetatable({}, _base_0)
cls.__init(_self_0, ...)
@ -133,9 +103,6 @@ do
end
})
_base_0.__class = _class_0
if _parent_0 and _parent_0.__inherited then
_parent_0.__inherited(_parent_0, _class_0)
end
NameProxy = _class_0
end
return {

View File

@ -18,18 +18,19 @@ class NameProxy
@name
chain: (...) =>
items = for i in *{...}
if type(i) == "string"
{"dot", i}
items = { base: @, ... }
for k,v in ipairs items
items[k] = if type(v) == "string"
{"dot", v}
else
i
v
build.chain {
base: self
unpack items
}
build.chain items
index: (key) =>
if type(key) == "string"
key = {"ref", key}
build.chain {
base: self, {"index", key}
}

View File

@ -1,14 +1,23 @@
local util = require("moonscript.util")
local data = require("moonscript.data")
local insert = table.insert
local unpack = util.unpack
local manual_return = data.Set({
local Set
do
local _obj_0 = require("moonscript.data")
Set = _obj_0.Set
end
local insert
do
local _obj_0 = table
insert = _obj_0.insert
end
local unpack
unpack = util.unpack
local manual_return = Set({
"foreach",
"for",
"while",
"return"
})
local cascading = data.Set({
local cascading = Set({
"if",
"unless",
"with",
@ -232,9 +241,8 @@ build = setmetatable({
if tbl == nil then
tbl = { }
end
local _list_0 = tbl
for _index_0 = 1, #_list_0 do
local tuple = _list_0[_index_0]
for _index_0 = 1, #tbl do
local tuple = tbl[_index_0]
if type(tuple[1]) == "string" then
tuple[1] = {
"key_literal",
@ -255,13 +263,18 @@ build = setmetatable({
end,
chain = function(parts)
local base = parts.base or error("expecting base property for chain")
if type(base) == "string" then
base = {
"ref",
base
}
end
local node = {
"chain",
base
}
local _list_0 = parts
for _index_0 = 1, #_list_0 do
local part = _list_0[_index_0]
for _index_0 = 1, #parts do
local part = parts[_index_0]
insert(node, part)
end
return node

View File

@ -1,17 +1,17 @@
util = require "moonscript.util"
data = require "moonscript.data"
import Set from require "moonscript.data"
import insert from table
import unpack from util
-- implicit return does not work on these statements
manual_return = data.Set{"foreach", "for", "while", "return"}
manual_return = Set{"foreach", "for", "while", "return"}
-- Assigns and returns are bubbled into their bodies.
-- All cascading statement transform functions accept a second arugment that
-- is the transformation to apply to the last statement in their body
cascading = data.Set{ "if", "unless", "with", "switch", "class", "do" }
cascading = Set{ "if", "unless", "with", "switch", "class", "do" }
-- type of node as string
ntype = (node) ->
@ -122,8 +122,10 @@ build = nil
build = setmetatable {
group: (body={}) ->
{"group", body}
do: (body) ->
{"do", body}
assign_one: (name, value) ->
build.assign {
names: {name}
@ -139,8 +141,13 @@ build = setmetatable {
{"table", tbl}
block_exp: (body) ->
{"block_exp", body}
chain: (parts) ->
base = parts.base or error"expecting base property for chain"
if type(base) == "string"
base = {"ref", base}
node = {"chain", base}
for part in *parts
insert node, part

View File

@ -1,4 +1,8 @@
local concat = table.concat
local concat
do
local _obj_0 = table
concat = _obj_0.concat
end
local unpack = unpack or table.unpack
local type = type
local moon = {
@ -73,15 +77,13 @@ split = function(str, delim)
return { }
end
str = str .. delim
return (function()
local _accum_0 = { }
local _len_0 = 1
for m in str:gmatch("(.-)" .. delim) do
_accum_0[_len_0] = m
_len_0 = _len_0 + 1
end
return _accum_0
end)()
local _accum_0 = { }
local _len_0 = 1
for m in str:gmatch("(.-)" .. delim) do
_accum_0[_len_0] = m
_len_0 = _len_0 + 1
end
return _accum_0
end
local dump
dump = function(what)
@ -100,15 +102,16 @@ dump = function(what)
end
seen[what] = true
depth = depth + 1
local lines = (function()
local lines
do
local _accum_0 = { }
local _len_0 = 1
for k, v in pairs(what) do
_accum_0[_len_0] = (" "):rep(depth * 4) .. "[" .. tostring(k) .. "] = " .. _dump(v, depth)
_len_0 = _len_0 + 1
end
return _accum_0
end)()
lines = _accum_0
end
seen[what] = false
return "{\n" .. concat(lines) .. (" "):rep((depth - 1) * 4) .. "}\n"
else
@ -119,7 +122,8 @@ dump = function(what)
end
local debug_posmap
debug_posmap = function(posmap, moon_code, lua_code)
local tuples = (function()
local tuples
do
local _accum_0 = { }
local _len_0 = 1
for k, v in pairs(posmap) do
@ -129,17 +133,17 @@ debug_posmap = function(posmap, moon_code, lua_code)
}
_len_0 = _len_0 + 1
end
return _accum_0
end)()
tuples = _accum_0
end
table.sort(tuples, function(a, b)
return a[1] < b[1]
end)
local lines = (function()
local lines
do
local _accum_0 = { }
local _len_0 = 1
local _list_0 = tuples
for _index_0 = 1, #_list_0 do
local pair = _list_0[_index_0]
for _index_0 = 1, #tuples do
local pair = tuples[_index_0]
local lua_line, pos = unpack(pair)
local moon_line = pos_to_line(moon_code, pos)
local lua_text = get_line(lua_code, lua_line)
@ -148,8 +152,8 @@ debug_posmap = function(posmap, moon_code, lua_code)
_accum_0[_len_0] = _value_0
_len_0 = _len_0 + 1
end
return _accum_0
end)()
lines = _accum_0
end
return concat(lines, "\n")
end
local setfenv = setfenv or function(fn, env)

View File

@ -1,7 +1,7 @@
module("moonscript.version", package.seeall)
version = "0.2.3-2"
version = "0.2.4"
function print_version()
print("MoonScript version "..version)
end

137
spec/class_spec.moon Normal file
View File

@ -0,0 +1,137 @@
describe "class", ->
it "should make a class with constructor", ->
class Thing
new: =>
@color = "blue"
instance = Thing!
assert.same instance, { color: "blue" }
it "should have instance methods", ->
class Thing
get_color: => @color
new: =>
@color = "blue"
instance = Thing!
assert.same instance\get_color!, "blue"
it "should have class property", ->
class Thing
color: "blue"
get_color: => @color
instance = Thing!
assert.same instance\get_color!, "blue"
assert.same Thing.color, "blue"
it "should inherit another class", ->
class Base
get_property: => @[@property]
new: (@property) =>
class Thing extends Base
color: "green"
instance = Thing "color"
assert.same instance\get_property!, "green"
it "should call super constructor", ->
class Base
new: (@property) =>
class Thing extends Base
new: (@name) =>
super "name"
instance = Thing "the_thing"
assert.same instance.property, "name"
assert.same instance.name, "the_thing"
it "should call super method", ->
class Base
_count: 111
counter: => @_count
class Thing extends Base
counter: => "%08d"\format super!
instance = Thing!
assert.same instance\counter!, "00000111"
it "should get super class", ->
class Base
class Thing extends Base
get_super: => super
instance = Thing!
assert.is_true instance\get_super! == Base
it "should get a bound method from super", ->
class Base
count: 1
get_count: => @count
class Thing extends Base
get_count: => "this is wrong"
get_method: => super\get_count
instance = Thing!
assert.same instance\get_method!!, 1
it "should have class properties", ->
class Base
class Thing extends Base
instance = Thing!
assert.same Base.__name, "Base"
assert.same Thing.__name, "Thing"
assert.is_true Thing.__parent == Base
assert.is_true instance.__class == Thing
it "should have name when assigned", ->
Thing = class
assert.same Thing.__name, "Thing"
it "should not expose class properties on instance", ->
class Thing
@height: 10
Thing.color = "blue"
instance = Thing!
assert.same instance.color, nil
assert.same instance.height, nil
it "should expose new things added to __base", ->
class Thing
instance = Thing!
Thing.__base.color = "green"
assert.same instance.color, "green"
it "should call with correct receiver", ->
local instance
class Thing
is_class: => assert.is_true @ == Thing
is_instance: => assert.is_true @ == instance
go: =>
@@is_class!
@is_instance!
instance = Thing!
instance\go!

View File

@ -0,0 +1,75 @@
describe "comprehension", ->
it "should double every number", ->
input = {1,2,3,4,5,6}
output_1 = [i * 2 for _, i in pairs input ]
output_2 = [i * 2 for i in *input ]
assert.same output_1, {2,4,6,8,10,12}
it "should create a slice", ->
input = {1,2,3,4,5,6}
slice_1 = [i for i in *input[1,3]]
slice_2 = [i for i in *input[,3]]
slice_3 = [i for i in *input[3,]]
slice_4 = [i for i in *input[,]]
slice_5 = [i for i in *input[,,2]]
slice_6 = [i for i in *input[2,,2]]
assert.same slice_1, {1,2,3}
assert.same slice_1, slice_2
assert.same slice_3, {3,4,5,6}
assert.same slice_4, input
assert.same slice_5, {1,3,5}
assert.same slice_6, {2,4,6}
it "should be able to assign to self", ->
input = {1,2,3,4}
output = input
output = [i * 2 for i in *output]
assert.same input, {1,2,3,4}
assert.same output, {2,4,6,8}
output = input
output = [i * 2 for _,i in ipairs input]
assert.same input, {1,2,3,4}
assert.same output, {2,4,6,8}
describe "table comprehension", ->
it "should copy table", ->
input = { 1,2,3, hello: "world", thing: true }
output = {k,v for k,v in pairs input }
assert.is_true input != output
assert.same input, output
it "should support when", ->
input = {
color: "red"
name: "fast"
width: 123
}
output = { k,v for k,v in pairs input when k != "color" }
assert.same output, { name: "fast", width: 123 }
it "should do unpack", ->
input = {4,9,16,25}
output = {i, math.sqrt i for i in *input}
assert.same output, { [4]: 2, [9]: 3, [16]: 4, [25]: 5 }
it "should use multiple return values", ->
input = { {"hello", "world"}, {"foo", "bar"} }
output = { unpack tuple for tuple in *input }
assert.same output, { foo: "bar", hello: "world" }

View File

@ -0,0 +1,32 @@
describe "destructure", ->
it "should unpack array", ->
input = {1,2,3}
{a,b,c} = {1,2,3}
{d,e,f} = input
assert.same a, 1
assert.same b, 2
assert.same c, 3
assert.same d, 1
assert.same e, 2
assert.same f, 3
it "should destructure", ->
futurists =
sculptor: "Umberto Boccioni"
painter: "Vladimir Burliuk"
poet:
name: "F.T. Marinetti"
address: {
"Via Roma 42R"
"Bellagio, Italy 22021"
}
{poet: {:name, address: {street, city}}} = futurists
assert.same name, "F.T. Marinetti"
assert.same street, "Via Roma 42R"
assert.same city, "Bellagio, Italy 22021"

View File

@ -1,6 +1,8 @@
hello_world = false
print = ->
if hello_world
print "sackman"
x = 5 + 5

View File

@ -1,4 +1,5 @@
print = ->
if false
true

View File

@ -1,4 +1,6 @@
print = ->
if (->
print "hello world"
print "who is this")

View File

@ -0,0 +1,30 @@
moonscript = require "moonscript.base"
errors = require "moonscript.errors"
util = require "moonscript.util"
get_rewritten_line_no = (fname) ->
fname = "spec/error_inputs/#{fname}.moon"
chunk = moonscript.loadfile fname
success, err = pcall chunk
error "`#{fname}` is supposed to have runtime error!" if success
source = tonumber err\match "]:(%d+)"
line_table = require("moonscript.line_tables")[fname]
errors.reverse_line_number fname, line_table, source, {}
-- TODO: check entire stack trace
describe "error rewriting", ->
tests = {
"first": 24
"second": 16
"third": 11
}
for name, expected_no in pairs tests
it "should rewrite line number", ->
assert.same get_rewritten_line_no(name), expected_no

26
spec/import_spec.moon Normal file
View File

@ -0,0 +1,26 @@
describe "import", ->
it "should import from table", ->
import sort, insert from table
t = { 4,2,6 }
insert t, 1
sort t
assert.same t, {1,2,4,6}
it "should import from local", ->
thing = { var: 10, hello: "world", func: => @var }
import hello, \func from thing
assert.same hello, thing.hello
assert.same func!, thing.var
it "should not call source multiple times", ->
count = 0
source = ->
count += 1
{ hello: "world", foo: "bar" }
import hello, foo from source!
assert.same count, 1

View File

@ -0,0 +1,100 @@
do
{a, b} = hello
{{a}, b, {c}} = hello
{ :hello, :world } = value
do
{ yes: no, thing } = world
{:a,:b,:c,:d} = yeah
{a} = one, two
{b}, c = one
{d}, e = one, two
x, {y} = one, two
xx, yy = 1, 2
{yy, xx} = {xx, yy}
{a, :b, c, :d, e, :f, g} = tbl
---
do
futurists =
sculptor: "Umberto Boccioni"
painter: "Vladimir Burliuk"
poet:
name: "F.T. Marinetti"
address: {
"Via Roma 42R"
"Bellagio, Italy 22021"
}
{poet: {:name, address: {street, city}}} = futurists
--
do
{ @world } = x
{ a.b, c.y, func!.z } = x
{ world: @world } = x
--
do
thing = {{1,2}, {3,4}}
for {x,y} in *thing
print x,y
--
do
with {a,b} = thing
print a, b
--
do
thing = nil
if {a} = thing
print a
else
print "nothing"
thang = {1,2}
if {a,b} = thang
print a,b
if {a,b} = thing
print a,b
elseif {c,d} = thang
print c,d
else
print "NO"
--
do
z = "yeah"
{a,b,c} = z
do
{a,b,c} = z
(z) ->
{a,b,c} = z
do
z = "oo"
(k) ->
{a,b,c} = z

View File

@ -20,3 +20,29 @@ import something from a table
if indent
import okay, \well from tables[100]
do
import a, b, c from z
do
import a,
b, c from z
do
import a
b
c from z
do
import
a
b
c from z
do
import
a
b
c
from z

View File

@ -3,8 +3,6 @@ hi = [x*2 for _, x in ipairs{1,2,3,4}]
items = {1,2,3,4,5,6}
mm = [@x for @x in ipairs items]
[z for z in ipairs items when z > 4]
rad = [{a} for a in ipairs {

View File

@ -114,3 +114,11 @@ for x=1,10
for y = 2,12
continue if y % 3 == 0
--
do
xxx = {1,2,3,4}
for thing in *xxx
print thing

98
spec/inputs/with.moon Normal file
View File

@ -0,0 +1,98 @@
do
a = ->
with something
print .hello
print hi
print "world"
do
with leaf
.world!
.world 1,2,3
g = .what.is.this
.hi 1,2,3
\hi(1,2).world 2323
\hi "yeah", "man"
.world = 200
do
zyzyzy = with something
.set_state "hello world"
do
x = 5 + with Something!
\write "hello world"
do
x = {
hello: with yeah
\okay!
}
do
with foo
\prop"something".hello
.prop\send(one)
.prop\send one
--
do
with a, b -- b is lost
print .world
mod = with _M = {}
.Thing = "hi"
-- operate on a only
with a, b = something, pooh
print .world
x = with a, b = 1, 2
print a + b
print with a, b = 1, 2
print a + b
-- assignment lhs must be evaluated in the order they appear
p = with hello!.x, world!.y = 1, 2
print a + b
--
do
x = "hello"
with x
x\upper!
do
with k = "jo"
print \upper!
do
with a,b,c = "", "", ""
print \upper!
do
a = "bunk"
with a,b,c = "", "", ""
print \upper!
do
with j
print \upper!
do
with k.j = "jo"
print \upper!

View File

@ -1,4 +1,3 @@
lfs = require "lfs"
parse = require "moonscript.parse"
@ -10,8 +9,8 @@ pattern = ...
import unpack from util
options = {
in_dir: "tests/inputs",
out_dir: "tests/outputs",
in_dir: "spec/inputs",
out_dir: "spec/outputs",
input_pattern: "(.*)%.moon$",
output_ext: ".lua"
@ -73,6 +72,7 @@ diff_str = (expected, got) ->
string_assert = (expected, got) ->
if expected != got
diff = diff_str expected, got
error "string equality assert failed" if os.getenv "HIDE_DIFF"
error "string equality assert failed:\n" .. diff
input_fname = (base) ->

9
spec/loops_spec.moon Normal file
View File

@ -0,0 +1,9 @@
describe "loops", ->
it "should continue", ->
input = {1,2,3,4,5,6}
output = for x in *input
continue if x % 2 == 1
x
assert.same output, { 2,4,6 }

116
spec/moon_spec.moon Normal file
View File

@ -0,0 +1,116 @@
-- test moon library
moon = require "moon"
describe "moon", ->
it "should determine correct type", ->
class Test
things = {
Test, Test!, 1, true, nil, "hello"
}
types = [moon.type t for t in *things]
assert.same types, { Test, Test, "number", "boolean", "nil", "string" }
it "should get upvalue", ->
fn = do
hello = "world"
-> hello
assert.same moon.debug.upvalue(fn, "hello"), "world"
it "should set upvalue", ->
fn = do
hello = "world"
-> hello
moon.debug.upvalue fn, "hello", "foobar"
assert.same fn!, "foobar"
it "should run with scope", ->
scope = hello: ->
spy.on scope, "hello"
moon.run_with_scope (-> hello!), scope
assert.spy(scope.hello).was.called!
it "should have access to old environment", ->
scope = {}
res = moon.run_with_scope (-> math), scope
assert.same res, math
it "should created bound proxy", ->
class Hello
state: 10
method: (val) => "the state: #{@state}, the val: #{val}"
hello = Hello!
bound = moon.bind_methods hello
assert.same bound.method("xxx"), "the state: 10, the val: xxx"
it "should create defaulted table", ->
fib = moon.defaultbl {[0]: 0, [1]: 1}, (i) => self[i - 1] + self[i - 2]
fib[7]
assert.same fib, { [0]: 0, 1, 1, 2, 3, 5, 8, 13 }
it "should extend", ->
t1 = { hello: "world's", cool: "shortest" }
t2 = { cool: "boots", cowboy: "hat" }
out = moon.extend t1, t2
assert.same { out.hello, out.cool, out.cowboy }, { "world's", "shortest", "hat"}
it "should make a copy", ->
x = { "hello", yeah: "man" }
y = moon.copy x
x[1] = "yikes"
x.yeah = "woman"
assert.same y, { "hello", yeah: "man" }
it "should mixin", ->
class TestModule
new: (@var) =>
show_var: => "var is: #{@var}"
class Second
new: =>
moon.mixin self, TestModule, "hi"
obj = Second!
assert.same obj\show_var!, "var is: hi"
it "should mixin object", ->
class First
val: 10
get_val: => "the val: #{@val}"
class Second
val: 20
new: =>
moon.mixin_object @, First!, { "get_val" }
obj = Second!
assert.same obj\get_val!, "the val: 10"
it "should mixin table", ->
a = { hello: "world", cat: "dog" }
b = { cat: "mouse", foo: "bar" }
moon.mixin_table a, b
assert.same a, { hello: "world", cat: "mouse", foo: "bar"}
it "should fold", ->
numbers = {4,3,5,6,7,2,3}
sum = moon.fold numbers, (a,b) -> a + b
assert.same sum, 30

View File

@ -6,19 +6,6 @@ f = function(...)
end
local dont_bubble
dont_bubble = function()
return (function()
local _accum_0 = { }
local _len_0 = 1
for x in (function(...)
return print(...)
end)("hello") do
_accum_0[_len_0] = x
_len_0 = _len_0 + 1
end
return _accum_0
end)()
end
local k = (function()
local _accum_0 = { }
local _len_0 = 1
for x in (function(...)
@ -28,8 +15,21 @@ local k = (function()
_len_0 = _len_0 + 1
end
return _accum_0
end)()
local j = (function()
end
local k
do
local _accum_0 = { }
local _len_0 = 1
for x in (function(...)
return print(...)
end)("hello") do
_accum_0[_len_0] = x
_len_0 = _len_0 + 1
end
k = _accum_0
end
local j
do
local _accum_0 = { }
local _len_0 = 1
for i = 1, 10 do
@ -38,27 +38,26 @@ local j = (function()
end
_len_0 = _len_0 + 1
end
return _accum_0
end)()
j = _accum_0
end
local m
m = function(...)
return (function(...)
local _accum_0 = { }
local _len_0 = 1
local _list_0 = {
...
}
for _index_0 = 1, #_list_0 do
local x = _list_0[_index_0]
if f(...) > 4 then
_accum_0[_len_0] = x
_len_0 = _len_0 + 1
end
local _accum_0 = { }
local _len_0 = 1
local _list_0 = {
...
}
for _index_0 = 1, #_list_0 do
local x = _list_0[_index_0]
if f(...) > 4 then
_accum_0[_len_0] = x
_len_0 = _len_0 + 1
end
return _accum_0
end)(...)
end
return _accum_0
end
local x = (function(...)
local x
do
local _accum_0 = { }
local _len_0 = 1
local _list_0 = {
@ -69,9 +68,10 @@ local x = (function(...)
_accum_0[_len_0] = i
_len_0 = _len_0 + 1
end
return _accum_0
end)(...)
local y = (function(...)
x = _accum_0
end
local y
do
local _accum_0 = { }
local _len_0 = 1
local _list_0 = {
@ -82,9 +82,10 @@ local y = (function(...)
_accum_0[_len_0] = x
_len_0 = _len_0 + 1
end
return _accum_0
end)(...)
local z = (function(...)
y = _accum_0
end
local z
do
local _accum_0 = { }
local _len_0 = 1
for x in hallo do
@ -93,18 +94,20 @@ local z = (function(...)
_len_0 = _len_0 + 1
end
end
return _accum_0
end)(...)
local a = (function(...)
z = _accum_0
end
local a
do
local _accum_0 = { }
local _len_0 = 1
for i = 1, 10 do
_accum_0[_len_0] = ...
_len_0 = _len_0 + 1
end
return _accum_0
end)(...)
local b = (function()
a = _accum_0
end
local b
do
local _accum_0 = { }
local _len_0 = 1
for i = 1, 10 do
@ -113,5 +116,5 @@ local b = (function()
end
_len_0 = _len_0 + 1
end
return _accum_0
end)()
b = _accum_0
end

View File

@ -1,6 +1,5 @@
local Hello
do
local _parent_0 = nil
local _base_0 = {
hello = function(self)
return print(self.test, self.world)
@ -10,26 +9,15 @@ do
end
}
_base_0.__index = _base_0
if _parent_0 then
setmetatable(_base_0, _parent_0.__base)
end
local _class_0 = setmetatable({
__init = function(self, test, world)
self.test, self.world = test, world
return print("creating object..")
end,
__base = _base_0,
__name = "Hello",
__parent = _parent_0
__name = "Hello"
}, {
__index = function(cls, name)
local val = rawget(_base_0, name)
if val == nil and _parent_0 then
return _parent_0[name]
else
return val
end
end,
__index = _base_0,
__call = function(cls, ...)
local _self_0 = setmetatable({}, _base_0)
cls.__init(_self_0, ...)
@ -37,9 +25,6 @@ do
end
})
_base_0.__class = _class_0
if _parent_0 and _parent_0.__inherited then
_parent_0.__inherited(_parent_0, _class_0)
end
Hello = _class_0
end
local x = Hello(1, 2)
@ -47,34 +32,18 @@ x:hello()
print(x)
local Simple
do
local _parent_0 = nil
local _base_0 = {
cool = function(self)
return print("cool")
end
}
_base_0.__index = _base_0
if _parent_0 then
setmetatable(_base_0, _parent_0.__base)
end
local _class_0 = setmetatable({
__init = function(self, ...)
if _parent_0 then
return _parent_0.__init(self, ...)
end
end,
__init = function() end,
__base = _base_0,
__name = "Simple",
__parent = _parent_0
__name = "Simple"
}, {
__index = function(cls, name)
local val = rawget(_base_0, name)
if val == nil and _parent_0 then
return _parent_0[name]
else
return val
end
end,
__index = _base_0,
__call = function(cls, ...)
local _self_0 = setmetatable({}, _base_0)
cls.__init(_self_0, ...)
@ -82,9 +51,6 @@ do
end
})
_base_0.__class = _class_0
if _parent_0 and _parent_0.__inherited then
_parent_0.__inherited(_parent_0, _class_0)
end
Simple = _class_0
end
local Yikes
@ -92,9 +58,7 @@ do
local _parent_0 = Simple
local _base_0 = { }
_base_0.__index = _base_0
if _parent_0 then
setmetatable(_base_0, _parent_0.__base)
end
setmetatable(_base_0, _parent_0.__base)
local _class_0 = setmetatable({
__init = function(self)
return print("created hello")
@ -105,7 +69,7 @@ do
}, {
__index = function(cls, name)
local val = rawget(_base_0, name)
if val == nil and _parent_0 then
if val == nil then
return _parent_0[name]
else
return val
@ -118,7 +82,7 @@ do
end
})
_base_0.__class = _class_0
if _parent_0 and _parent_0.__inherited then
if _parent_0.__inherited then
_parent_0.__inherited(_parent_0, _class_0)
end
Yikes = _class_0
@ -127,32 +91,20 @@ x = Yikes()
x:cool()
local Hi
do
local _parent_0 = nil
local _base_0 = {
cool = function(self, num)
return print("num", num)
end
}
_base_0.__index = _base_0
if _parent_0 then
setmetatable(_base_0, _parent_0.__base)
end
local _class_0 = setmetatable({
__init = function(self, arg)
return print("init arg", arg)
end,
__base = _base_0,
__name = "Hi",
__parent = _parent_0
__name = "Hi"
}, {
__index = function(cls, name)
local val = rawget(_base_0, name)
if val == nil and _parent_0 then
return _parent_0[name]
else
return val
end
end,
__index = _base_0,
__call = function(cls, ...)
local _self_0 = setmetatable({}, _base_0)
cls.__init(_self_0, ...)
@ -160,9 +112,6 @@ do
end
})
_base_0.__class = _class_0
if _parent_0 and _parent_0.__inherited then
_parent_0.__inherited(_parent_0, _class_0)
end
Hi = _class_0
end
do
@ -173,9 +122,7 @@ do
end
}
_base_0.__index = _base_0
if _parent_0 then
setmetatable(_base_0, _parent_0.__base)
end
setmetatable(_base_0, _parent_0.__base)
local _class_0 = setmetatable({
__init = function(self)
return _parent_0.__init(self, "man")
@ -186,7 +133,7 @@ do
}, {
__index = function(cls, name)
local val = rawget(_base_0, name)
if val == nil and _parent_0 then
if val == nil then
return _parent_0[name]
else
return val
@ -199,7 +146,7 @@ do
end
})
_base_0.__class = _class_0
if _parent_0 and _parent_0.__inherited then
if _parent_0.__inherited then
_parent_0.__inherited(_parent_0, _class_0)
end
Simple = _class_0
@ -209,32 +156,16 @@ x:cool()
print(x.__class == Simple)
local Okay
do
local _parent_0 = nil
local _base_0 = {
something = 20323
}
_base_0.__index = _base_0
if _parent_0 then
setmetatable(_base_0, _parent_0.__base)
end
local _class_0 = setmetatable({
__init = function(self, ...)
if _parent_0 then
return _parent_0.__init(self, ...)
end
end,
__init = function() end,
__base = _base_0,
__name = "Okay",
__parent = _parent_0
__name = "Okay"
}, {
__index = function(cls, name)
local val = rawget(_base_0, name)
if val == nil and _parent_0 then
return _parent_0[name]
else
return val
end
end,
__index = _base_0,
__call = function(cls, ...)
local _self_0 = setmetatable({}, _base_0)
cls.__init(_self_0, ...)
@ -242,9 +173,6 @@ do
end
})
_base_0.__class = _class_0
if _parent_0 and _parent_0.__inherited then
_parent_0.__inherited(_parent_0, _class_0)
end
Okay = _class_0
end
local Biggie
@ -258,14 +186,10 @@ do
end
}
_base_0.__index = _base_0
if _parent_0 then
setmetatable(_base_0, _parent_0.__base)
end
setmetatable(_base_0, _parent_0.__base)
local _class_0 = setmetatable({
__init = function(self, ...)
if _parent_0 then
return _parent_0.__init(self, ...)
end
return _parent_0.__init(self, ...)
end,
__base = _base_0,
__name = "Biggie",
@ -273,7 +197,7 @@ do
}, {
__index = function(cls, name)
local val = rawget(_base_0, name)
if val == nil and _parent_0 then
if val == nil then
return _parent_0[name]
else
return val
@ -286,41 +210,25 @@ do
end
})
_base_0.__class = _class_0
if _parent_0 and _parent_0.__inherited then
if _parent_0.__inherited then
_parent_0.__inherited(_parent_0, _class_0)
end
Biggie = _class_0
end
local Yeah
do
local _parent_0 = nil
local _base_0 = {
okay = function(self)
return _parent_0.something(self, 1, 2, 3, 4)
end
}
_base_0.__index = _base_0
if _parent_0 then
setmetatable(_base_0, _parent_0.__base)
end
local _class_0 = setmetatable({
__init = function(self, ...)
if _parent_0 then
return _parent_0.__init(self, ...)
end
end,
__init = function() end,
__base = _base_0,
__name = "Yeah",
__parent = _parent_0
__name = "Yeah"
}, {
__index = function(cls, name)
local val = rawget(_base_0, name)
if val == nil and _parent_0 then
return _parent_0[name]
else
return val
end
end,
__index = _base_0,
__call = function(cls, ...)
local _self_0 = setmetatable({}, _base_0)
cls.__init(_self_0, ...)
@ -328,41 +236,22 @@ do
end
})
_base_0.__class = _class_0
if _parent_0 and _parent_0.__inherited then
_parent_0.__inherited(_parent_0, _class_0)
end
Yeah = _class_0
end
local What
do
local _parent_0 = nil
local _base_0 = {
something = function(self)
return print("val:", self.val)
end
}
_base_0.__index = _base_0
if _parent_0 then
setmetatable(_base_0, _parent_0.__base)
end
local _class_0 = setmetatable({
__init = function(self, ...)
if _parent_0 then
return _parent_0.__init(self, ...)
end
end,
__init = function() end,
__base = _base_0,
__name = "What",
__parent = _parent_0
__name = "What"
}, {
__index = function(cls, name)
local val = rawget(_base_0, name)
if val == nil and _parent_0 then
return _parent_0[name]
else
return val
end
end,
__index = _base_0,
__call = function(cls, ...)
local _self_0 = setmetatable({}, _base_0)
cls.__init(_self_0, ...)
@ -370,9 +259,6 @@ do
end
})
_base_0.__class = _class_0
if _parent_0 and _parent_0.__inherited then
_parent_0.__inherited(_parent_0, _class_0)
end
What = _class_0
end
do
@ -390,14 +276,10 @@ do
end
}
_base_0.__index = _base_0
if _parent_0 then
setmetatable(_base_0, _parent_0.__base)
end
setmetatable(_base_0, _parent_0.__base)
local _class_0 = setmetatable({
__init = function(self, ...)
if _parent_0 then
return _parent_0.__init(self, ...)
end
return _parent_0.__init(self, ...)
end,
__base = _base_0,
__name = "Hello",
@ -405,7 +287,7 @@ do
}, {
__index = function(cls, name)
local val = rawget(_base_0, name)
if val == nil and _parent_0 then
if val == nil then
return _parent_0[name]
else
return val
@ -418,7 +300,7 @@ do
end
})
_base_0.__class = _class_0
if _parent_0 and _parent_0.__inherited then
if _parent_0.__inherited then
_parent_0.__inherited(_parent_0, _class_0)
end
Hello = _class_0
@ -431,7 +313,6 @@ do
end
local CoolSuper
do
local _parent_0 = nil
local _base_0 = {
hi = function(self)
_parent_0.hi(self, 1, 2, 3, 4)(1, 2, 3, 4)
@ -444,27 +325,12 @@ do
end
}
_base_0.__index = _base_0
if _parent_0 then
setmetatable(_base_0, _parent_0.__base)
end
local _class_0 = setmetatable({
__init = function(self, ...)
if _parent_0 then
return _parent_0.__init(self, ...)
end
end,
__init = function() end,
__base = _base_0,
__name = "CoolSuper",
__parent = _parent_0
__name = "CoolSuper"
}, {
__index = function(cls, name)
local val = rawget(_base_0, name)
if val == nil and _parent_0 then
return _parent_0[name]
else
return val
end
end,
__index = _base_0,
__call = function(cls, ...)
local _self_0 = setmetatable({}, _base_0)
cls.__init(_self_0, ...)
@ -472,9 +338,6 @@ do
end
})
_base_0.__class = _class_0
if _parent_0 and _parent_0.__inherited then
_parent_0.__inherited(_parent_0, _class_0)
end
CoolSuper = _class_0
end
x = self.hello
@ -488,33 +351,17 @@ xx = function(hello, world, cool)
end
local ClassMan
do
local _parent_0 = nil
local _base_0 = {
blue = function(self) end,
green = function(self) end
}
_base_0.__index = _base_0
if _parent_0 then
setmetatable(_base_0, _parent_0.__base)
end
local _class_0 = setmetatable({
__init = function(self, ...)
if _parent_0 then
return _parent_0.__init(self, ...)
end
end,
__init = function() end,
__base = _base_0,
__name = "ClassMan",
__parent = _parent_0
__name = "ClassMan"
}, {
__index = function(cls, name)
local val = rawget(_base_0, name)
if val == nil and _parent_0 then
return _parent_0[name]
else
return val
end
end,
__index = _base_0,
__call = function(cls, ...)
local _self_0 = setmetatable({}, _base_0)
cls.__init(_self_0, ...)
@ -527,9 +374,6 @@ do
self.hello = 3434
self.world = 23423
self.red = function(self) end
if _parent_0 and _parent_0.__inherited then
_parent_0.__inherited(_parent_0, _class_0)
end
ClassMan = _class_0
end
x = self
@ -543,30 +387,14 @@ local _ = hello[self].world
local Whacko
do
local hello
local _parent_0 = nil
local _base_0 = { }
_base_0.__index = _base_0
if _parent_0 then
setmetatable(_base_0, _parent_0.__base)
end
local _class_0 = setmetatable({
__init = function(self, ...)
if _parent_0 then
return _parent_0.__init(self, ...)
end
end,
__init = function() end,
__base = _base_0,
__name = "Whacko",
__parent = _parent_0
__name = "Whacko"
}, {
__index = function(cls, name)
local val = rawget(_base_0, name)
if val == nil and _parent_0 then
return _parent_0[name]
else
return val
end
end,
__index = _base_0,
__call = function(cls, ...)
local _self_0 = setmetatable({}, _base_0)
cls.__init(_self_0, ...)
@ -584,9 +412,6 @@ do
if something then
print("yeah")
end
if _parent_0 and _parent_0.__inherited then
_parent_0.__inherited(_parent_0, _class_0)
end
Whacko = _class_0
end
print("hello")
@ -594,30 +419,14 @@ local yyy
yyy = function()
local Cool
do
local _parent_0 = nil
local _base_0 = { }
_base_0.__index = _base_0
if _parent_0 then
setmetatable(_base_0, _parent_0.__base)
end
local _class_0 = setmetatable({
__init = function(self, ...)
if _parent_0 then
return _parent_0.__init(self, ...)
end
end,
__init = function() end,
__base = _base_0,
__name = "Cool",
__parent = _parent_0
__name = "Cool"
}, {
__index = function(cls, name)
local val = rawget(_base_0, name)
if val == nil and _parent_0 then
return _parent_0[name]
else
return val
end
end,
__index = _base_0,
__call = function(cls, ...)
local _self_0 = setmetatable({}, _base_0)
cls.__init(_self_0, ...)
@ -627,38 +436,19 @@ yyy = function()
_base_0.__class = _class_0
local self = _class_0
_ = nil
if _parent_0 and _parent_0.__inherited then
_parent_0.__inherited(_parent_0, _class_0)
end
Cool = _class_0
return _class_0
end
end
do
local _parent_0 = nil
local _base_0 = { }
_base_0.__index = _base_0
if _parent_0 then
setmetatable(_base_0, _parent_0.__base)
end
local _class_0 = setmetatable({
__init = function(self, ...)
if _parent_0 then
return _parent_0.__init(self, ...)
end
end,
__init = function() end,
__base = _base_0,
__name = "D",
__parent = _parent_0
__name = "D"
}, {
__index = function(cls, name)
local val = rawget(_base_0, name)
if val == nil and _parent_0 then
return _parent_0[name]
else
return val
end
end,
__index = _base_0,
__call = function(cls, ...)
local _self_0 = setmetatable({}, _base_0)
cls.__init(_self_0, ...)
@ -668,36 +458,17 @@ do
_base_0.__class = _class_0
local self = _class_0
_ = nil
if _parent_0 and _parent_0.__inherited then
_parent_0.__inherited(_parent_0, _class_0)
end
a.b.c.D = _class_0
end
do
local _parent_0 = nil
local _base_0 = { }
_base_0.__index = _base_0
if _parent_0 then
setmetatable(_base_0, _parent_0.__base)
end
local _class_0 = setmetatable({
__init = function(self, ...)
if _parent_0 then
return _parent_0.__init(self, ...)
end
end,
__init = function() end,
__base = _base_0,
__name = "hello",
__parent = _parent_0
__name = "hello"
}, {
__index = function(cls, name)
local val = rawget(_base_0, name)
if val == nil and _parent_0 then
return _parent_0[name]
else
return val
end
end,
__index = _base_0,
__call = function(cls, ...)
local _self_0 = setmetatable({}, _base_0)
cls.__init(_self_0, ...)
@ -707,23 +478,16 @@ do
_base_0.__class = _class_0
local self = _class_0
_ = nil
if _parent_0 and _parent_0.__inherited then
_parent_0.__inherited(_parent_0, _class_0)
end
a.b["hello"] = _class_0
end
do
local _parent_0 = Hello.World
local _base_0 = { }
_base_0.__index = _base_0
if _parent_0 then
setmetatable(_base_0, _parent_0.__base)
end
setmetatable(_base_0, _parent_0.__base)
local _class_0 = setmetatable({
__init = function(self, ...)
if _parent_0 then
return _parent_0.__init(self, ...)
end
return _parent_0.__init(self, ...)
end,
__base = _base_0,
__name = "Something",
@ -731,7 +495,7 @@ do
}, {
__index = function(cls, name)
local val = rawget(_base_0, name)
if val == nil and _parent_0 then
if val == nil then
return _parent_0[name]
else
return val
@ -746,7 +510,7 @@ do
_base_0.__class = _class_0
local self = _class_0
_ = nil
if _parent_0 and _parent_0.__inherited then
if _parent_0.__inherited then
_parent_0.__inherited(_parent_0, _class_0)
end
(function()
@ -755,30 +519,14 @@ do
end
local a
do
local _parent_0 = nil
local _base_0 = { }
_base_0.__index = _base_0
if _parent_0 then
setmetatable(_base_0, _parent_0.__base)
end
local _class_0 = setmetatable({
__init = function(self, ...)
if _parent_0 then
return _parent_0.__init(self, ...)
end
end,
__init = function() end,
__base = _base_0,
__name = "a",
__parent = _parent_0
__name = "a"
}, {
__index = function(cls, name)
local val = rawget(_base_0, name)
if val == nil and _parent_0 then
return _parent_0[name]
else
return val
end
end,
__index = _base_0,
__call = function(cls, ...)
local _self_0 = setmetatable({}, _base_0)
cls.__init(_self_0, ...)
@ -786,38 +534,19 @@ do
end
})
_base_0.__class = _class_0
if _parent_0 and _parent_0.__inherited then
_parent_0.__inherited(_parent_0, _class_0)
end
a = _class_0
end
local b
local Something
do
local _parent_0 = nil
local _base_0 = { }
_base_0.__index = _base_0
if _parent_0 then
setmetatable(_base_0, _parent_0.__base)
end
local _class_0 = setmetatable({
__init = function(self, ...)
if _parent_0 then
return _parent_0.__init(self, ...)
end
end,
__init = function() end,
__base = _base_0,
__name = "Something",
__parent = _parent_0
__name = "Something"
}, {
__index = function(cls, name)
local val = rawget(_base_0, name)
if val == nil and _parent_0 then
return _parent_0[name]
else
return val
end
end,
__index = _base_0,
__call = function(cls, ...)
local _self_0 = setmetatable({}, _base_0)
cls.__init(_self_0, ...)
@ -825,9 +554,6 @@ do
end
})
_base_0.__class = _class_0
if _parent_0 and _parent_0.__inherited then
_parent_0.__inherited(_parent_0, _class_0)
end
Something = _class_0
b = _class_0
end
@ -836,14 +562,10 @@ do
local _parent_0 = Hello
local _base_0 = { }
_base_0.__index = _base_0
if _parent_0 then
setmetatable(_base_0, _parent_0.__base)
end
setmetatable(_base_0, _parent_0.__base)
local _class_0 = setmetatable({
__init = function(self, ...)
if _parent_0 then
return _parent_0.__init(self, ...)
end
return _parent_0.__init(self, ...)
end,
__base = _base_0,
__name = "Something",
@ -851,7 +573,7 @@ do
}, {
__index = function(cls, name)
local val = rawget(_base_0, name)
if val == nil and _parent_0 then
if val == nil then
return _parent_0[name]
else
return val
@ -864,7 +586,7 @@ do
end
})
_base_0.__class = _class_0
if _parent_0 and _parent_0.__inherited then
if _parent_0.__inherited then
_parent_0.__inherited(_parent_0, _class_0)
end
Something = _class_0
@ -875,14 +597,10 @@ do
local _parent_0 = World
local _base_0 = { }
_base_0.__index = _base_0
if _parent_0 then
setmetatable(_base_0, _parent_0.__base)
end
setmetatable(_base_0, _parent_0.__base)
local _class_0 = setmetatable({
__init = function(self, ...)
if _parent_0 then
return _parent_0.__init(self, ...)
end
return _parent_0.__init(self, ...)
end,
__base = _base_0,
__name = "d",
@ -890,7 +608,7 @@ do
}, {
__index = function(cls, name)
local val = rawget(_base_0, name)
if val == nil and _parent_0 then
if val == nil then
return _parent_0[name]
else
return val
@ -903,7 +621,7 @@ do
end
})
_base_0.__class = _class_0
if _parent_0 and _parent_0.__inherited then
if _parent_0.__inherited then
_parent_0.__inherited(_parent_0, _class_0)
end
d = _class_0
@ -911,30 +629,14 @@ end
print(((function()
local WhatsUp
do
local _parent_0 = nil
local _base_0 = { }
_base_0.__index = _base_0
if _parent_0 then
setmetatable(_base_0, _parent_0.__base)
end
local _class_0 = setmetatable({
__init = function(self, ...)
if _parent_0 then
return _parent_0.__init(self, ...)
end
end,
__init = function() end,
__base = _base_0,
__name = "WhatsUp",
__parent = _parent_0
__name = "WhatsUp"
}, {
__index = function(cls, name)
local val = rawget(_base_0, name)
if val == nil and _parent_0 then
return _parent_0[name]
else
return val
end
end,
__index = _base_0,
__call = function(cls, ...)
local _self_0 = setmetatable({}, _base_0)
cls.__init(_self_0, ...)
@ -942,38 +644,19 @@ print(((function()
end
})
_base_0.__class = _class_0
if _parent_0 and _parent_0.__inherited then
_parent_0.__inherited(_parent_0, _class_0)
end
WhatsUp = _class_0
return _class_0
end
end)()).__name)
do
local _parent_0 = nil
local _base_0 = { }
_base_0.__index = _base_0
if _parent_0 then
setmetatable(_base_0, _parent_0.__base)
end
local _class_0 = setmetatable({
__init = function(self, ...)
if _parent_0 then
return _parent_0.__init(self, ...)
end
end,
__init = function() end,
__base = _base_0,
__name = "Something",
__parent = _parent_0
__name = "Something"
}, {
__index = function(cls, name)
local val = rawget(_base_0, name)
if val == nil and _parent_0 then
return _parent_0[name]
else
return val
end
end,
__index = _base_0,
__call = function(cls, ...)
local _self_0 = setmetatable({}, _base_0)
cls.__init(_self_0, ...)
@ -983,35 +666,20 @@ do
_base_0.__class = _class_0
local self = _class_0
_ = nil
if _parent_0 and _parent_0.__inherited then
_parent_0.__inherited(_parent_0, _class_0)
end
Something = _class_0
end
do
local val, insert
local _parent_0 = nil
local _base_0 = { }
_base_0.__index = _base_0
if _parent_0 then
setmetatable(_base_0, _parent_0.__base)
end
local _class_0 = setmetatable({
__init = function(self)
return print(insert, val)
end,
__base = _base_0,
__name = "Something",
__parent = _parent_0
__name = "Something"
}, {
__index = function(cls, name)
local val = rawget(_base_0, name)
if val == nil and _parent_0 then
return _parent_0[name]
else
return val
end
end,
__index = _base_0,
__call = function(cls, ...)
local _self_0 = setmetatable({}, _base_0)
cls.__init(_self_0, ...)
@ -1025,32 +693,17 @@ do
local _obj_0 = table
insert = _obj_0.insert
end
if _parent_0 and _parent_0.__inherited then
_parent_0.__inherited(_parent_0, _class_0)
end
Something = _class_0
end
do
local _parent_0 = nil
local _base_0 = { }
_base_0.__index = _base_0
if _parent_0 then
setmetatable(_base_0, _parent_0.__base)
end
local _class_0 = setmetatable({
__init = hi,
__base = _base_0,
__name = "X",
__parent = _parent_0
__name = "X"
}, {
__index = function(cls, name)
local val = rawget(_base_0, name)
if val == nil and _parent_0 then
return _parent_0[name]
else
return val
end
end,
__index = _base_0,
__call = function(cls, ...)
local _self_0 = setmetatable({}, _base_0)
cls.__init(_self_0, ...)
@ -1058,9 +711,6 @@ do
end
})
_base_0.__class = _class_0
if _parent_0 and _parent_0.__inherited then
_parent_0.__inherited(_parent_0, _class_0)
end
X = _class_0
end
return nil

View File

@ -6,35 +6,38 @@ local items = {
5,
6
}
local out = (function()
local out
do
local _tbl_0 = { }
for k in items do
_tbl_0[k] = k * 2
end
return _tbl_0
end)()
out = _tbl_0
end
local x = {
hello = "world",
okay = 2323
}
local copy = (function()
local copy
do
local _tbl_0 = { }
for k, v in pairs(x) do
if k ~= "okay" then
_tbl_0[k] = v
end
end
return _tbl_0
end)()
local _ = (function()
copy = _tbl_0
end
local _
do
local _tbl_0 = { }
for x in yes do
local _key_0, _val_0 = unpack(x)
_tbl_0[_key_0] = _val_0
end
return _tbl_0
end)()
_ = (function()
_ = _tbl_0
end
do
local _tbl_0 = { }
local _list_0 = yes
for _index_0 = 1, #_list_0 do
@ -42,17 +45,17 @@ _ = (function()
local _key_0, _val_0 = unpack(x)
_tbl_0[_key_0] = _val_0
end
return _tbl_0
end)()
_ = (function()
_ = _tbl_0
end
do
local _tbl_0 = { }
for x in yes do
local _key_0, _val_0 = xxxx
_tbl_0[_key_0] = _val_0
end
return _tbl_0
end)()
_ = (function()
_ = _tbl_0
end
do
local _tbl_0 = { }
local _list_0 = {
{
@ -77,18 +80,20 @@ _ = (function()
end)())
_tbl_0[_key_0] = _val_0
end
return _tbl_0
end)()
local n1 = (function()
_ = _tbl_0
end
local n1
do
local _accum_0 = { }
local _len_0 = 1
for i = 1, 10 do
_accum_0[_len_0] = i
_len_0 = _len_0 + 1
end
return _accum_0
end)()
local n2 = (function()
n1 = _accum_0
end
local n2
do
local _accum_0 = { }
local _len_0 = 1
for i = 1, 10 do
@ -97,9 +102,10 @@ local n2 = (function()
_len_0 = _len_0 + 1
end
end
return _accum_0
end)()
local aa = (function()
n2 = _accum_0
end
local aa
do
local _accum_0 = { }
local _len_0 = 1
for x = 1, 10 do
@ -111,9 +117,10 @@ local aa = (function()
_len_0 = _len_0 + 1
end
end
return _accum_0
end)()
local bb = (function()
aa = _accum_0
end
local bb
do
local _accum_0 = { }
local _len_0 = 1
for thing in y do
@ -122,9 +129,10 @@ local bb = (function()
_len_0 = _len_0 + 1
end
end
return _accum_0
end)()
local cc = (function()
bb = _accum_0
end
local cc
do
local _accum_0 = { }
local _len_0 = 1
for i = 1, 10 do
@ -133,9 +141,10 @@ local cc = (function()
_len_0 = _len_0 + 1
end
end
return _accum_0
end)()
local dd = (function()
cc = _accum_0
end
local dd
do
local _accum_0 = { }
local _len_0 = 1
for i = 1, 10 do
@ -150,13 +159,13 @@ local dd = (function()
end
end
end
return _accum_0
end)()
_ = (function()
dd = _accum_0
end
do
local _tbl_0 = { }
for i = 1, 10 do
_tbl_0["hello"] = "world"
end
return _tbl_0
end)()
_ = _tbl_0
end
return nil

View File

@ -0,0 +1,186 @@
do
local a, b
do
local _obj_0 = hello
a, b = _obj_0[1], _obj_0[2]
end
local c
do
local _obj_0 = hello
a, b, c = _obj_0[1][1], _obj_0[2], _obj_0[3][1]
end
local hello, world
do
local _obj_0 = value
hello, world = _obj_0.hello, _obj_0.world
end
end
do
local no, thing
do
local _obj_0 = world
no, thing = _obj_0.yes, _obj_0[1]
end
local a, b, c, d
do
local _obj_0 = yeah
a, b, c, d = _obj_0.a, _obj_0.b, _obj_0.c, _obj_0.d
end
do
local _obj_0 = one
a = _obj_0[1]
end
local _ = two
do
local _obj_0 = one
b = _obj_0[1]
end
c = nil
do
local _obj_0 = one
d = _obj_0[1]
end
local e = two
local x = one
local y
do
local _obj_0 = two
y = _obj_0[1]
end
local xx, yy = 1, 2
do
local _obj_0 = {
xx,
yy
}
yy, xx = _obj_0[1], _obj_0[2]
end
local f, g
do
local _obj_0 = tbl
a, b, c, d, e, f, g = _obj_0[1], _obj_0.b, _obj_0[2], _obj_0.d, _obj_0[3], _obj_0.f, _obj_0[4]
end
end
do
local futurists = {
sculptor = "Umberto Boccioni",
painter = "Vladimir Burliuk",
poet = {
name = "F.T. Marinetti",
address = {
"Via Roma 42R",
"Bellagio, Italy 22021"
}
}
}
local name, street, city
name, street, city = futurists.poet.name, futurists.poet.address[1], futurists.poet.address[2]
end
do
do
local _obj_0 = x
self.world = _obj_0[1]
end
do
local _obj_0 = x
a.b, c.y, func().z = _obj_0[1], _obj_0[2], _obj_0[3]
end
do
local _obj_0 = x
self.world = _obj_0.world
end
end
do
local thing = {
{
1,
2
},
{
3,
4
}
}
for _index_0 = 1, #thing do
local _des_0 = thing[_index_0]
local x, y
x, y = _des_0[1], _des_0[2]
print(x, y)
end
end
do
do
local _with_0 = thing
local a, b
a, b = _with_0[1], _with_0[2]
print(a, b)
end
end
do
local thing = nil
do
local _des_0 = thing
if _des_0 then
local a
a = _des_0[1]
print(a)
else
print("nothing")
end
end
local thang = {
1,
2
}
do
local _des_0 = thang
if _des_0 then
local a, b
a, b = _des_0[1], _des_0[2]
print(a, b)
end
end
do
local _des_0 = thing
if _des_0 then
local a, b
a, b = _des_0[1], _des_0[2]
print(a, b)
else
do
local _des_1 = thang
if _des_1 then
local c, d
c, d = _des_1[1], _des_1[2]
print(c, d)
else
print("NO")
end
end
end
end
end
do
local z = "yeah"
local a, b, c
a, b, c = z[1], z[2], z[3]
end
do
local a, b, c
do
local _obj_0 = z
a, b, c = _obj_0[1], _obj_0[2], _obj_0[3]
end
end
local _
_ = function(z)
local a, b, c
a, b, c = z[1], z[2], z[3]
end
do
local z = "oo"
return function(k)
local a, b, c
a, b, c = z[1], z[2], z[3]
end
end

View File

@ -4,32 +4,16 @@ do
end
do
do
local _parent_0 = nil
local _base_0 = {
umm = "cool"
}
_base_0.__index = _base_0
if _parent_0 then
setmetatable(_base_0, _parent_0.__base)
end
local _class_0 = setmetatable({
__init = function(self, ...)
if _parent_0 then
return _parent_0.__init(self, ...)
end
end,
__init = function() end,
__base = _base_0,
__name = "Something",
__parent = _parent_0
__name = "Something"
}, {
__index = function(cls, name)
local val = rawget(_base_0, name)
if val == nil and _parent_0 then
return _parent_0[name]
else
return val
end
end,
__index = _base_0,
__call = function(cls, ...)
local _self_0 = setmetatable({}, _base_0)
cls.__init(_self_0, ...)
@ -37,9 +21,6 @@ do
end
})
_base_0.__class = _class_0
if _parent_0 and _parent_0.__inherited then
_parent_0.__inherited(_parent_0, _class_0)
end
Something = _class_0
end
end
@ -76,7 +57,6 @@ do
local hallo = 3434
end
do
local _with_0 = tmp
local j = 2000
end
end

83
spec/outputs/import.lua Normal file
View File

@ -0,0 +1,83 @@
local hello
do
local _obj_0 = yeah
hello = _obj_0.hello
end
local world
do
local _obj_0 = table["cool"]
hello, world = _obj_0.hello, _obj_0.world
end
local a, b, c
do
local _obj_0 = items
a, b, c = _obj_0.a, (function()
local _base_0 = _obj_0
local _fn_0 = _base_0.b
return function(...)
return _fn_0(_base_0, ...)
end
end)(), _obj_0.c
end
local master, ghost
do
local _obj_0 = find("mytable")
master, ghost = _obj_0.master, (function()
local _base_0 = _obj_0
local _fn_0 = _base_0.ghost
return function(...)
return _fn_0(_base_0, ...)
end
end)()
end
local yumm
a, yumm = 3434, "hello"
local _table_0 = 232
local something
do
local _obj_0 = a(table)
something = _obj_0.something
end
if indent then
local okay, well
do
local _obj_0 = tables[100]
okay, well = _obj_0.okay, (function()
local _base_0 = _obj_0
local _fn_0 = _base_0.well
return function(...)
return _fn_0(_base_0, ...)
end
end)()
end
end
do
do
local _obj_0 = z
a, b, c = _obj_0.a, _obj_0.b, _obj_0.c
end
end
do
do
local _obj_0 = z
a, b, c = _obj_0.a, _obj_0.b, _obj_0.c
end
end
do
do
local _obj_0 = z
a, b, c = _obj_0.a, _obj_0.b, _obj_0.c
end
end
do
do
local _obj_0 = z
a, b, c = _obj_0.a, _obj_0.b, _obj_0.c
end
end
do
do
local _obj_0 = z
a, b, c = _obj_0.a, _obj_0.b, _obj_0.c
end
end

View File

@ -1,4 +1,5 @@
local hi = (function()
local hi
do
local _accum_0 = { }
local _len_0 = 1
for _, x in ipairs({
@ -10,8 +11,8 @@ local hi = (function()
_accum_0[_len_0] = x * 2
_len_0 = _len_0 + 1
end
return _accum_0
end)()
hi = _accum_0
end
local items = {
1,
2,
@ -20,21 +21,13 @@ local items = {
5,
6
}
local mm = (function()
local _accum_0 = { }
local _len_0 = 1
for self.x in ipairs(items) do
_accum_0[_len_0] = self.x
_len_0 = _len_0 + 1
end
return _accum_0
end)()
for z in ipairs(items) do
if z > 4 then
local _ = z
end
end
local rad = (function()
local rad
do
local _accum_0 = { }
local _len_0 = 1
for a in ipairs({
@ -52,8 +45,8 @@ local rad = (function()
_len_0 = _len_0 + 1
end
end
return _accum_0
end)()
rad = _accum_0
end
for z in items do
for j in list do
if z > 4 then
@ -101,7 +94,8 @@ dump((function()
end
return _accum_0
end)())
local things = (function()
local things
do
local _accum_0 = { }
local _len_0 = 1
for x in range(10) do
@ -114,8 +108,8 @@ local things = (function()
end
end
end
return _accum_0
end)()
things = _accum_0
end
for x in ipairs({
1,
2,
@ -137,15 +131,16 @@ end
for x in x do
local _ = x
end
local x = (function()
local x
do
local _accum_0 = { }
local _len_0 = 1
for x in x do
_accum_0[_len_0] = x
_len_0 = _len_0 + 1
end
return _accum_0
end)()
x = _accum_0
end
for x in ipairs({
1,
2,
@ -161,53 +156,50 @@ for x in ipairs({
end
end
end
local double = (function()
local double
do
local _accum_0 = { }
local _len_0 = 1
local _list_0 = items
for _index_0 = 1, #_list_0 do
x = _list_0[_index_0]
for _index_0 = 1, #items do
x = items[_index_0]
_accum_0[_len_0] = x * 2
_len_0 = _len_0 + 1
end
return _accum_0
end)()
local _list_0 = double
for _index_0 = 1, #_list_0 do
x = _list_0[_index_0]
double = _accum_0
end
for _index_0 = 1, #double do
x = double[_index_0]
print(x)
end
local cut = (function()
local cut
do
local _accum_0 = { }
local _len_0 = 1
local _list_1 = items
for _index_0 = 1, #_list_1 do
x = _list_1[_index_0]
for _index_0 = 1, #items do
x = items[_index_0]
if x > 3 then
_accum_0[_len_0] = x
_len_0 = _len_0 + 1
end
end
return _accum_0
end)()
local hello = (function()
cut = _accum_0
end
local hello
do
local _accum_0 = { }
local _len_0 = 1
local _list_1 = items
for _index_0 = 1, #_list_1 do
x = _list_1[_index_0]
local _list_2 = items
for _index_1 = 1, #_list_2 do
local y = _list_2[_index_1]
for _index_0 = 1, #items do
x = items[_index_0]
for _index_1 = 1, #items do
local y = items[_index_1]
_accum_0[_len_0] = x + y
_len_0 = _len_0 + 1
end
end
return _accum_0
end)()
local _list_1 = hello
for _index_0 = 1, #_list_1 do
local z = _list_1[_index_0]
hello = _accum_0
end
for _index_0 = 1, #hello do
local z = hello[_index_0]
print(z)
end
x = {
@ -219,83 +211,70 @@ x = {
6,
7
}
local _list_2 = x
local _max_0 = -5
for _index_0 = 2, _max_0 < 0 and #_list_2 + _max_0 or _max_0, 2 do
local y = _list_2[_index_0]
for _index_0 = 2, _max_0 < 0 and #x + _max_0 or _max_0, 2 do
local y = x[_index_0]
print(y)
end
local _list_3 = x
local _max_1 = 3
for _index_0 = 1, _max_1 < 0 and #_list_3 + _max_1 or _max_1 do
local y = _list_3[_index_0]
for _index_0 = 1, _max_1 < 0 and #x + _max_1 or _max_1 do
local y = x[_index_0]
print(y)
end
local _list_4 = x
for _index_0 = 2, #_list_4 do
local y = _list_4[_index_0]
for _index_0 = 2, #x do
local y = x[_index_0]
print(y)
end
local _list_5 = x
for _index_0 = 1, #_list_5, 2 do
local y = _list_5[_index_0]
for _index_0 = 1, #x, 2 do
local y = x[_index_0]
print(y)
end
local _list_6 = x
for _index_0 = 2, #_list_6, 2 do
local y = _list_6[_index_0]
for _index_0 = 2, #x, 2 do
local y = x[_index_0]
print(y)
end
local a, b, c = 1, 5, 2
local _list_7 = x
local _max_2 = b
for _index_0 = a, _max_2 < 0 and #_list_7 + _max_2 or _max_2, c do
local y = _list_7[_index_0]
for _index_0 = a, _max_2 < 0 and #x + _max_2 or _max_2, c do
local y = x[_index_0]
print(y)
end
local normal
normal = function(hello)
return (function()
local _accum_0 = { }
local _len_0 = 1
for x in yeah do
_accum_0[_len_0] = x
_len_0 = _len_0 + 1
end
return _accum_0
end)()
local _accum_0 = { }
local _len_0 = 1
for x in yeah do
_accum_0[_len_0] = x
_len_0 = _len_0 + 1
end
return _accum_0
end
local test = x(1, 2, 3, 4, 5)
local _list_8 = test
for _index_0 = 1, #_list_8 do
local thing = _list_8[_index_0]
for _index_0 = 1, #test do
local thing = test[_index_0]
print(thing)
end
local _
_ = function()
local _list_9 = rows
for _index_0 = 1, #_list_9 do
local row = _list_9[_index_0]
local _list_0 = rows
for _index_0 = 1, #_list_0 do
local row = _list_0[_index_0]
a = b
end
end
_ = function()
local _list_9 = things
for _index_0 = 1, #_list_9 do
x = _list_9[_index_0]
for _index_0 = 1, #things do
x = things[_index_0]
_ = x
end
end
return function()
return (function()
local _accum_0 = { }
local _len_0 = 1
local _list_9 = things
for _index_0 = 1, #_list_9 do
x = _list_9[_index_0]
_accum_0[_len_0] = x
_len_0 = _len_0 + 1
end
return _accum_0
end)()
local _accum_0 = { }
local _len_0 = 1
for _index_0 = 1, #things do
x = things[_index_0]
_accum_0[_len_0] = x
_len_0 = _len_0 + 1
end
return _accum_0
end

View File

@ -48,37 +48,37 @@ local hello = {
4,
5
}
x = (function()
do
local _accum_0 = { }
local _len_0 = 1
local _list_1 = hello
for _index_0 = 1, #_list_1 do
local y = _list_1[_index_0]
for _index_0 = 1, #hello do
local y = hello[_index_0]
if y % 2 == 0 then
_accum_0[_len_0] = y
end
_len_0 = _len_0 + 1
end
return _accum_0
end)()
x = _accum_0
end
x = function()
local _list_1 = hello
for _index_0 = 1, #_list_1 do
x = _list_1[_index_0]
for _index_0 = 1, #hello do
x = hello[_index_0]
local _ = y
end
end
local t = (function()
local t
do
local _accum_0 = { }
local _len_0 = 1
for i = 10, 20 do
_accum_0[_len_0] = i * 2
_len_0 = _len_0 + 1
end
return _accum_0
end)()
t = _accum_0
end
local hmm = 0
local y = (function()
local y
do
local _accum_0 = { }
local _len_0 = 1
for j = 3, 30, 8 do
@ -87,8 +87,8 @@ local y = (function()
_accum_0[_len_0] = _value_0
_len_0 = _len_0 + 1
end
return _accum_0
end)()
y = _accum_0
end
local _
_ = function()
for k = 10, 40 do
@ -118,7 +118,7 @@ while also do
_ = "okay"
end
local i = 0
x = (function()
do
local _accum_0 = { }
local _len_0 = 1
while i < 10 do
@ -127,9 +127,9 @@ x = (function()
_accum_0[_len_0] = _value_0
_len_0 = _len_0 + 1
end
return _accum_0
end)()
x = (function()
x = _accum_0
end
do
local _accum_0 = { }
local _len_0 = 1
local _list_1 = 3
@ -140,9 +140,9 @@ x = (function()
_accum_0[_len_0] = _value_0
_len_0 = _len_0 + 1
end
return _accum_0
end)()
x = (function()
x = _accum_0
end
do
local _accum_0 = { }
local _len_0 = 1
for x = 1, 2 do
@ -151,8 +151,8 @@ x = (function()
_accum_0[_len_0] = _value_0
_len_0 = _len_0 + 1
end
return _accum_0
end)()
x = _accum_0
end
while true do
local _continue_0 = false
repeat
@ -185,7 +185,8 @@ for x = 1, 10 do
break
end
end
local list = (function()
local list
do
local _accum_0 = { }
local _len_0 = 1
for x = 1, 10 do
@ -204,8 +205,8 @@ local list = (function()
break
end
end
return _accum_0
end)()
list = _accum_0
end
local _list_1 = {
1,
2,
@ -258,4 +259,16 @@ for x = 1, 10 do
if not _continue_0 then
break
end
end
do
local xxx = {
1,
2,
3,
4
}
for _index_0 = 1, #xxx do
local thing = xxx[_index_0]
print(thing)
end
end

136
spec/outputs/with.lua Normal file
View File

@ -0,0 +1,136 @@
do
local a
a = function()
do
local _with_0 = something
print(_with_0.hello)
print(hi)
print("world")
return _with_0
end
end
end
do
do
local _with_0 = leaf
_with_0.world()
_with_0.world(1, 2, 3)
local g = _with_0.what.is.this
_with_0.hi(1, 2, 3)
_with_0:hi(1, 2).world(2323)
_with_0:hi("yeah", "man")
_with_0.world = 200
end
end
do
local zyzyzy
do
local _with_0 = something
_with_0.set_state("hello world")
zyzyzy = _with_0
end
end
do
local x = 5 + (function()
do
local _with_0 = Something()
_with_0:write("hello world")
return _with_0
end
end)()
end
do
local x = {
hello = (function()
do
local _with_0 = yeah
_with_0:okay()
return _with_0
end
end)()
}
end
do
do
local _with_0 = foo
local _ = _with_0:prop("something").hello
_with_0.prop:send(one)
_with_0.prop:send(one)
end
end
do
do
local _with_0 = a, b
print(_with_0.world)
end
local mod
do
local _M = { }
_M.Thing = "hi"
mod = _M
end
do
local a, b = something, pooh
print(a.world)
end
local x
do
local a, b = 1, 2
print(a + b)
x = a
end
print((function()
do
local a, b = 1, 2
print(a + b)
return a
end
end)())
local p
do
local _with_0 = 1
hello().x, world().y = _with_0, 2
print(a + b)
p = _with_0
end
end
do
local x = "hello"
do
x:upper()
end
end
do
do
local k = "jo"
print(k:upper())
end
end
do
do
local a, b, c = "", "", ""
print(a:upper())
end
end
do
local a = "bunk"
do
local b, c
a, b, c = "", "", ""
print(a:upper())
end
end
do
do
local _with_0 = j
print(_with_0:upper())
end
end
do
do
local _with_0 = "jo"
k.j = _with_0
print(_with_0:upper())
return _with_0
end
end

192
test.lua
View File

@ -1,192 +0,0 @@
#!/usr/bin/env lua
require "lfs"
require "alt_getopt"
local gettime = nil
pcall(function()
require "socket"
gettime = socket.gettime
end)
parse = require "moonscript.parse"
compile = require "moonscript.compile"
local opts, ind = alt_getopt.get_opts(arg, "qd:", { })
local argv = {}
for i = ind, #arg do table.insert(argv, arg[i]) end
local action = table.remove(argv, 1) or "run"
local diff_tool = opts.d or "diff"
local quiet = opts.q
local opts = {
in_dir = "tests/inputs",
out_dir = "tests/outputs",
input_pattern = "(.*)%.moon$",
output_ext = ".lua"
}
local total_time = {
parse = 0,
compile = 0
}
local function format_time(sec)
return ("%.3fms"):format(sec*1000)
end
local function diff(a_fname, b_fname)
return io.popen(diff_tool.." ".. a_fname.." "..b_fname, "r"):read("*a")
end
local function input_name(name) return opts.in_dir.."/".. name end
local function output_name(name)
return opts.out_dir.."/"..name:match(opts.input_pattern)..opts.output_ext
end
local function run_file(name, benchmark)
name = input_name(name)
file_str = io.open(name):read("*a")
local start_parse
if benchmark then start_parse = gettime() end
local tree, err = parse.string(file_str)
local parse_time = 0
if benchmark then parse_time = gettime() - start_parse end
if not tree then
error("Parse error in "..name.."\n"..err)
end
local start_compile
if benchmark then start_compile = gettime() end
local code, err, pos = compile.tree(tree)
if not code then
print()
print(("Failed to compile: %s"):format(name))
print(compile.format_error(err, pos, file_str))
os.exit()
end
-- local success, code = pcall(compile.tree, tree)
-- if not success then
-- error("Compile error in"..name..":\n"..code)
-- end
if benchmark then
local compile_time = gettime() - start_compile
return code, parse_time, compile_time
end
return code
end
local function inputs(pattern)
return coroutine.wrap(function()
for file in lfs.dir(opts.in_dir) do
local body = file:match(opts.input_pattern)
if body then
if not pattern or body:match(pattern) then
coroutine.yield(file)
end
end
end
end)
end
local actions = {
build = function(pattern)
for file in inputs(pattern) do
local out_fname = output_name(file)
print("Building: ", file, out_fname)
local result = run_file(file)
if result then
io.open(out_fname, "w"):write(result)
end
end
end,
run = function(pattern)
local failed = false
local tests_run, result = 0
for file in inputs(pattern) do
tests_run = tests_run + 1
local correct_fname = output_name(file)
result, parse_time, compile_time = run_file(file, gettime)
local handle = io.open(correct_fname)
if not handle then
print("Test not built yet:", correct_fname)
else
local correct = handle:read("*a")
if result ~= correct then
print("Test", file, "failed")
local tmp_name = os.tmpname()
local tmp = io.open(tmp_name, "w")
tmp:write(result)
tmp:close()
if not quiet then
print(diff(correct_fname, tmp_name))
end
os.remove(tmp_name)
-- break
else
if parse_time then
total_time.parse = total_time.parse + parse_time
total_time.compile = total_time.compile + compile_time
parse_time = format_time(parse_time)
compile_time = format_time(compile_time)
print("Test", file, "passed", "",
("p: %s, c: %s"):format(parse_time, compile_time))
else
print("Test", file, "passed")
end
end
end
end
if gettime then
print""
print"total:"
print(" parse time", format_time(total_time.parse))
print(" compile time", format_time(total_time.compile))
end
if tests_run == 0 then
if not pattern then
print("No tests found")
else
print("No tests matching pattern:", pattern)
end
elseif tests_run == 1 then
-- print(result)
end
end,
list = function(pattern)
local count = 0
for file in inputs(pattern) do
count = count + 1
print(file)
end
if count > 0 then print("") end
print("Count:", count)
end
}
local fn = actions[action]
if fn then
fn(unpack(argv))
else
print("Unknown action:", action)
end

View File

@ -1,78 +0,0 @@
{a, b} = hello
{{a}, b, {c}} = hello
{ :hello, :world } = value
{ yes: no, thing } = world
{:a,:b,:c,:d} = yeah
{a} = one, two
{b}, c = one
{d}, e = one, two
x, {y} = one, two
xx, yy = 1, 2
{yy, xx} = {xx, yy}
{a, :b, c, :d, e, :f, g} = tbl
---
futurists =
sculptor: "Umberto Boccioni"
painter: "Vladimir Burliuk"
poet:
name: "F.T. Marinetti"
address: {
"Via Roma 42R"
"Bellagio, Italy 22021"
}
{poet: {:name, address: {street, city}}} = futurists
print name, street, city
--
{ @world } = x
{ a.b, c.y, func!.z } = x
{ world: @world } = x
--
thing = {{1,2}, {3,4}}
for {x,y} in *thing
print x,y
--
with {a,b} = thing
print a, b
--
thing = nil
if {a} = thing
print a
else
print "nothing"
thang = {1,2}
if {a,b} = thang
print a,b
if {a,b} = thing
print a,b
elseif {c,d} = thang
print c,d
else
print "NO"

View File

@ -1,64 +0,0 @@
a = ->
with something
print .hello
print hi
print "world"
with leaf
.world!
.world 1,2,3
g = .what.is.this
.hi 1,2,3
\hi(1,2).world 2323
\hi "yeah", "man"
.world = 200
zyzyzy = with something
.set_state "hello world"
x = 5 + with Something!
\write "hello world"
x = {
hello: with yeah
\okay!
}
with foo
\prop"something".hello
.prop\send(one)
.prop\send one
--
with a, b -- b is lost
print .world
mod = with _M = {}
.Thing = "hi"
-- operate on a only
with a, b = something, pooh
print .world
x = with a, b = 1, 2
print a + b
print with a, b = 1, 2
print a + b
-- assignment lhs must be evaluated in the order they appear
p = with hello!.x, world!.y = 1, 2
print a + b

Some files were not shown because too many files have changed in this diff Show More