mirror of
https://github.com/leafo/moonscript.git
synced 2025-01-09 00:04:22 +00:00
start moving moonc code to moonscript
This commit is contained in:
parent
a4585f8b1c
commit
c60d83c546
128
bin/moonc
128
bin/moonc
@ -55,62 +55,19 @@ function print_help(err)
|
||||
end
|
||||
end
|
||||
|
||||
function mkdir(path)
|
||||
local chunks = util.split(path, dirsep)
|
||||
local accum
|
||||
|
||||
for _, dir in ipairs(chunks) do
|
||||
accum = accum and accum.. dirsep ..dir or dir
|
||||
lfs.mkdir(accum)
|
||||
end
|
||||
|
||||
return lfs.attributes(path, "mode")
|
||||
end
|
||||
|
||||
function normalize(path)
|
||||
return path:match("^(.-)" .. dirsep .. "*$")..dirsep
|
||||
end
|
||||
|
||||
function parse_dir(fname)
|
||||
return fname:match("^(.-)[^" .. dirsep .. "]*$")
|
||||
end
|
||||
|
||||
function parse_file(fname)
|
||||
return fname:match("^.-([^" .. dirsep .. "]*)$")
|
||||
end
|
||||
|
||||
|
||||
-- convert .moon to .lua
|
||||
function convert_path(path)
|
||||
local new_path = path:gsub("%.moon$", ".lua")
|
||||
if new_path == path then
|
||||
new_path = path .. ".lua"
|
||||
end
|
||||
return new_path
|
||||
end
|
||||
|
||||
function log_msg(...)
|
||||
if not opts.p then
|
||||
io.stderr:write(table.concat({...}, " ") .. "\n")
|
||||
end
|
||||
end
|
||||
|
||||
local gettime = nil
|
||||
if opts.b then
|
||||
pcall(function()
|
||||
require "socket"
|
||||
gettime = socket.gettime
|
||||
end)
|
||||
|
||||
function format_time(time)
|
||||
return ("%.3fms"):format(time*1000)
|
||||
end
|
||||
if not gettime then
|
||||
print_help"LuaSocket needed for benchmark"
|
||||
end
|
||||
else
|
||||
gettime = function() return 0 end
|
||||
end
|
||||
local moonc = require("moonscript.cmd.moonc")
|
||||
local mkdir = moonc.mkdir
|
||||
local normalize_dir = moonc.normalize_dir
|
||||
local parse_dir = moonc.parse_dir
|
||||
local parse_file = moonc.parse_file
|
||||
local convert_path = moonc.convert_path
|
||||
local compile_file_text = moonc.compile_file_text
|
||||
|
||||
function write_file(fname, code)
|
||||
if opts.p then
|
||||
@ -125,50 +82,8 @@ function write_file(fname, code)
|
||||
out_f:write(code.."\n")
|
||||
out_f:close()
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function compile_file(text, fname)
|
||||
local parse_time = gettime()
|
||||
local tree, err = parse.string(text)
|
||||
parse_time = gettime() - parse_time
|
||||
|
||||
if not tree then
|
||||
return nil, err
|
||||
end
|
||||
|
||||
if opts.T then
|
||||
opts.p = true
|
||||
dump_tree(tree)
|
||||
return ""
|
||||
else
|
||||
local compile_time = gettime()
|
||||
local code, posmap_or_err, err_pos = compile.tree(tree)
|
||||
compile_time = gettime() - compile_time
|
||||
|
||||
if not code then
|
||||
return nil, compile.format_error(posmap_or_err, err_pos, text)
|
||||
end
|
||||
|
||||
if opts.X then
|
||||
opts.p = true
|
||||
print("Pos", "Lua", ">>", "Moon")
|
||||
print(util.debug_posmap(posmap_or_err, text, code))
|
||||
return ""
|
||||
end
|
||||
|
||||
if opts.b then
|
||||
opts.p = true
|
||||
return table.concat({
|
||||
fname,
|
||||
"Parse time \t" .. format_time(parse_time),
|
||||
"Compile time\t" .. format_time(compile_time),
|
||||
""
|
||||
}, "\n")
|
||||
end
|
||||
|
||||
return code
|
||||
end
|
||||
return "built"
|
||||
end
|
||||
|
||||
function compile_and_write(from, to)
|
||||
@ -178,16 +93,25 @@ function compile_and_write(from, to)
|
||||
end
|
||||
local text = f:read("*a")
|
||||
|
||||
local code, err = compile_file(text, from)
|
||||
if not code then
|
||||
local code, err = compile_file_text(text, from, {
|
||||
benchmark = opts.b,
|
||||
show_posmap = opts.X,
|
||||
show_parse_tree = opts.T,
|
||||
})
|
||||
|
||||
if not code and err then
|
||||
return nil, err
|
||||
end
|
||||
|
||||
if not code then
|
||||
return true
|
||||
end
|
||||
|
||||
return write_file(to, code)
|
||||
end
|
||||
|
||||
function scan_directory(root, collected)
|
||||
root = normalize(root)
|
||||
root = normalize_dir(root)
|
||||
collected = collected or {}
|
||||
|
||||
for fname in lfs.dir(root) do
|
||||
@ -247,7 +171,7 @@ function get_files(fname, files)
|
||||
end
|
||||
end
|
||||
|
||||
target_fname = normalize(opts.t) .. target_fname
|
||||
target_fname = normalize_dir(opts.t) .. target_fname
|
||||
end
|
||||
|
||||
table.insert(files, {sub_fname, target_fname})
|
||||
@ -255,7 +179,7 @@ function get_files(fname, files)
|
||||
else
|
||||
local target_fname = convert_path(fname)
|
||||
if opts.t then
|
||||
local prefix = normalize(opts.t)
|
||||
local prefix = normalize_dir(opts.t)
|
||||
|
||||
if is_abs_path(target_fname) then
|
||||
target_fname = parse_file(target_fname)
|
||||
@ -426,8 +350,8 @@ if opts.w then
|
||||
err,
|
||||
"\n",
|
||||
}, "\n"))
|
||||
else
|
||||
log_msg("Built:", fname, "->", target)
|
||||
elseif success == "build" then
|
||||
log_msg("Built", fname, "->", target)
|
||||
end
|
||||
end
|
||||
|
||||
@ -450,8 +374,8 @@ else
|
||||
if not success then
|
||||
io.stderr:write(fname .. "\t" .. err .. "\n")
|
||||
os.exit(1)
|
||||
else
|
||||
log_msg("Built", fname, "->", target)
|
||||
elseif success == "build" then
|
||||
log_msg("Built", fname)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -28,6 +28,7 @@ build = {
|
||||
["moonscript.base"] = "moonscript/base.lua",
|
||||
["moonscript.cmd.coverage"] = "moonscript/cmd/coverage.lua",
|
||||
["moonscript.cmd.lint"] = "moonscript/cmd/lint.lua",
|
||||
["moonscript.cmd.moonc"] = "moonscript/cmd/moonc.lua",
|
||||
["moonscript.compile"] = "moonscript/compile.lua",
|
||||
["moonscript.compile.statement"] = "moonscript/compile/statement.lua",
|
||||
["moonscript.compile.value"] = "moonscript/compile/value.lua",
|
||||
|
134
moonscript/cmd/moonc.lua
Normal file
134
moonscript/cmd/moonc.lua
Normal file
@ -0,0 +1,134 @@
|
||||
local lfs = require("lfs")
|
||||
local split
|
||||
do
|
||||
local _obj_0 = require("moonscript.util")
|
||||
split = _obj_0.split
|
||||
end
|
||||
local dirsep = package.config:sub(1, 1)
|
||||
local dirsep_chars
|
||||
if dirsep == "\\" then
|
||||
dirsep_chars = "\\/"
|
||||
else
|
||||
dirsep_chars = dirsep
|
||||
end
|
||||
local mkdir
|
||||
mkdir = function(path)
|
||||
local chunks = split(path, dirsep)
|
||||
local accum
|
||||
for _index_0 = 1, #chunks do
|
||||
local dir = chunks[_index_0]
|
||||
accum = accum and tostring(accum) .. tostring(dirsep) .. tostring(dir) or dir
|
||||
lfs.mkdir(accum)
|
||||
end
|
||||
return lfs.attributes(path, "mode")
|
||||
end
|
||||
local normalize_dir
|
||||
normalize_dir = function(path)
|
||||
return path:match("^(.-)[" .. tostring(dirsep_chars) .. "]*$") .. dirsep
|
||||
end
|
||||
local parse_dir
|
||||
parse_dir = function(path)
|
||||
return (path:match("^(.-)[^" .. tostring(dirsep_chars) .. "]*$"))
|
||||
end
|
||||
local parse_file
|
||||
parse_file = function(path)
|
||||
return (path:match("^.-([^" .. tostring(dirsep_chars) .. "]*)$"))
|
||||
end
|
||||
local convert_path
|
||||
convert_path = function(path)
|
||||
local new_path = path:gsub("%.moon$", ".lua")
|
||||
if new_path == path then
|
||||
new_path = path .. ".lua"
|
||||
end
|
||||
return new_path
|
||||
end
|
||||
local format_time
|
||||
format_time = function(time)
|
||||
return ("%.3fms"):format(time * 1000)
|
||||
end
|
||||
local gettime
|
||||
do
|
||||
local socket
|
||||
gettime = function()
|
||||
if socket == nil then
|
||||
pcall(function()
|
||||
socket = require("socket")
|
||||
end)
|
||||
if not (socket) then
|
||||
socket = false
|
||||
end
|
||||
end
|
||||
if socket then
|
||||
return socket.gettime()
|
||||
else
|
||||
return nil, "LuaSocket needed for benchmark"
|
||||
end
|
||||
end
|
||||
end
|
||||
local compile_file_text
|
||||
compile_file_text = function(text, fname, opts)
|
||||
if opts == nil then
|
||||
opts = { }
|
||||
end
|
||||
local parse = require("moonscript.parse")
|
||||
local compile = require("moonscript.compile")
|
||||
local parse_time
|
||||
if opts.benchmark then
|
||||
parse_time = assert(gettime())
|
||||
end
|
||||
local tree, err = parse.string(text)
|
||||
if not (tree) then
|
||||
return nil, err
|
||||
end
|
||||
if parse_time then
|
||||
parse_time = gettime() - parse_time
|
||||
end
|
||||
if opts.show_parse_tree then
|
||||
local dump = require("moonscript.dump")
|
||||
dump.tree(tree)
|
||||
return nil
|
||||
end
|
||||
local compile_time
|
||||
if opts.benchmark then
|
||||
compile_time = gettime()
|
||||
end
|
||||
local code, posmap_or_err, err_pos = compile.tree(tree)
|
||||
if not (code) then
|
||||
return nil, compile.format_error(posmap_or_err, err_pos, text)
|
||||
end
|
||||
if compile_time then
|
||||
compile_time = gettime() - compile_time
|
||||
end
|
||||
if opts.show_posmap then
|
||||
local debug_posmap
|
||||
do
|
||||
local _obj_0 = require("moonscript.util")
|
||||
debug_posmap = _obj_0.debug_posmap
|
||||
end
|
||||
print("Pos", "Lua", ">>", "Moon")
|
||||
print(debug_posmap(posmap_or_err, text, code))
|
||||
return nil
|
||||
end
|
||||
if opts.benchmark then
|
||||
print(table.concat({
|
||||
fname,
|
||||
"Parse time \t" .. format_time(parse_time),
|
||||
"Compile time\t" .. format_time(compile_time),
|
||||
""
|
||||
}, "\n"))
|
||||
return nil
|
||||
end
|
||||
return code
|
||||
end
|
||||
return {
|
||||
dirsep = dirsep,
|
||||
mkdir = mkdir,
|
||||
normalize_dir = normalize_dir,
|
||||
parse_dir = parse_dir,
|
||||
parse_file = parse_file,
|
||||
new_path = new_path,
|
||||
convert_path = convert_path,
|
||||
gettime = gettime,
|
||||
format_time = format_time,
|
||||
compile_file_text = compile_file_text
|
||||
}
|
122
moonscript/cmd/moonc.moon
Normal file
122
moonscript/cmd/moonc.moon
Normal file
@ -0,0 +1,122 @@
|
||||
-- assorted utilities for moonc command line tool
|
||||
|
||||
lfs = require "lfs"
|
||||
|
||||
import split from require "moonscript.util"
|
||||
|
||||
dirsep = package.config\sub 1,1
|
||||
dirsep_chars = if dirsep == "\\"
|
||||
"\\/" -- windows
|
||||
else
|
||||
dirsep
|
||||
|
||||
|
||||
-- similar to mkdir -p
|
||||
mkdir = (path) ->
|
||||
chunks = split path, dirsep
|
||||
|
||||
local accum
|
||||
for dir in *chunks
|
||||
accum = accum and "#{accum}#{dirsep}#{dir}" or dir
|
||||
lfs.mkdir accum
|
||||
|
||||
lfs.attributes path, "mode"
|
||||
|
||||
-- strips excess / and ensures path ends with /
|
||||
normalize_dir = (path) ->
|
||||
path\match("^(.-)[#{dirsep_chars}]*$") .. dirsep
|
||||
|
||||
-- parse the directory out of a path
|
||||
parse_dir = (path) ->
|
||||
(path\match "^(.-)[^#{dirsep_chars}]*$")
|
||||
|
||||
-- parse the filename out of a path
|
||||
parse_file = (path) ->
|
||||
(path\match "^.-([^#{dirsep_chars}]*)$")
|
||||
|
||||
-- converts .moon to a .lua path for calcuating compile target
|
||||
convert_path = (path) ->
|
||||
new_path = path\gsub "%.moon$", ".lua"
|
||||
if new_path == path
|
||||
new_path = path .. ".lua"
|
||||
new_path
|
||||
|
||||
format_time = (time) ->
|
||||
"%.3fms"\format time*1000
|
||||
|
||||
gettime = do
|
||||
local socket
|
||||
->
|
||||
if socket == nil
|
||||
pcall ->
|
||||
socket = require "socket"
|
||||
|
||||
unless socket
|
||||
socket = false
|
||||
|
||||
if socket
|
||||
socket.gettime()
|
||||
else
|
||||
nil, "LuaSocket needed for benchmark"
|
||||
|
||||
-- compiles file to lua
|
||||
-- returns nil, error on error
|
||||
-- returns just nil if some option handled the output instead
|
||||
compile_file_text = (text, fname, opts={}) ->
|
||||
parse = require "moonscript.parse"
|
||||
compile = require "moonscript.compile"
|
||||
|
||||
parse_time = if opts.benchmark
|
||||
assert gettime!
|
||||
|
||||
tree, err = parse.string text
|
||||
return nil, err unless tree
|
||||
|
||||
if parse_time
|
||||
parse_time = gettime! - parse_time
|
||||
|
||||
if opts.show_parse_tree
|
||||
dump = require "moonscript.dump"
|
||||
dump.tree tree
|
||||
return nil
|
||||
|
||||
compile_time = if opts.benchmark
|
||||
gettime!
|
||||
|
||||
code, posmap_or_err, err_pos = compile.tree tree
|
||||
|
||||
unless code
|
||||
return nil, compile.format_error posmap_or_err, err_pos, text
|
||||
|
||||
if compile_time
|
||||
compile_time = gettime() - compile_time
|
||||
|
||||
if opts.show_posmap
|
||||
import debug_posmap from require "moonscript.util"
|
||||
print "Pos", "Lua", ">>", "Moon"
|
||||
print debug_posmap posmap_or_err, text, code
|
||||
return nil
|
||||
|
||||
if opts.benchmark
|
||||
print table.concat {
|
||||
fname,
|
||||
"Parse time \t" .. format_time(parse_time),
|
||||
"Compile time\t" .. format_time(compile_time),
|
||||
""
|
||||
}, "\n"
|
||||
return nil
|
||||
|
||||
code
|
||||
|
||||
{
|
||||
:dirsep
|
||||
:mkdir
|
||||
:normalize_dir
|
||||
:parse_dir
|
||||
:parse_file
|
||||
:new_path
|
||||
:convert_path
|
||||
:gettime
|
||||
:format_time
|
||||
:compile_file_text
|
||||
}
|
68
spec/cmd_spec.moon
Normal file
68
spec/cmd_spec.moon
Normal file
@ -0,0 +1,68 @@
|
||||
|
||||
moonc = require "moonscript.cmd.moonc"
|
||||
|
||||
-- TODO: add specs for windows equivalents
|
||||
|
||||
describe "moonc", ->
|
||||
same = (fn, a, b)->
|
||||
assert.same b, fn a
|
||||
|
||||
it "should normalize dir", ->
|
||||
same moonc.normalize_dir, "hello/world/", "hello/world/"
|
||||
same moonc.normalize_dir, "hello/world//", "hello/world/"
|
||||
same moonc.normalize_dir, "", "/" -- wrong
|
||||
same moonc.normalize_dir, "hello", "hello/"
|
||||
|
||||
|
||||
it "should parse dir", ->
|
||||
same moonc.parse_dir, "/hello/world/file", "/hello/world/"
|
||||
same moonc.parse_dir, "/hello/world/", "/hello/world/"
|
||||
same moonc.parse_dir, "world", ""
|
||||
same moonc.parse_dir, "", ""
|
||||
|
||||
it "should parse file", ->
|
||||
same moonc.parse_file, "/hello/world/file", "file"
|
||||
same moonc.parse_file, "/hello/world/", ""
|
||||
same moonc.parse_file, "world", "world"
|
||||
same moonc.parse_file, "", ""
|
||||
|
||||
it "convert path", ->
|
||||
same moonc.convert_path, "test.moon", "test.lua"
|
||||
same moonc.convert_path, "/hello/file.moon", "/hello/file.lua"
|
||||
same moonc.convert_path, "/hello/world/file", "/hello/world/file.lua"
|
||||
|
||||
it "chould compile file text", ->
|
||||
assert.same {
|
||||
[[return print('hello')]]
|
||||
}, {
|
||||
moonc.compile_file_text "print'hello'", "test.moon"
|
||||
}
|
||||
|
||||
describe "stubbed lfs", ->
|
||||
local dirs
|
||||
|
||||
before_each ->
|
||||
dirs = {}
|
||||
package.loaded.lfs = nil
|
||||
package.loaded["moonscript.cmd.moonc"] = nil
|
||||
|
||||
package.loaded.lfs = {
|
||||
mkdir: (dir) -> table.insert dirs, dir
|
||||
attributes: -> "directory"
|
||||
}
|
||||
|
||||
moonc = require "moonscript.cmd.moonc"
|
||||
|
||||
after_each ->
|
||||
package.loaded.lfs = nil
|
||||
package.loaded["moonscript.cmd.moonc"] = nil
|
||||
moonc = require "moonscript.cmd.moonc"
|
||||
|
||||
it "should make directory", ->
|
||||
moonc.mkdir "hello/world/directory"
|
||||
assert.same {
|
||||
"hello"
|
||||
"hello/world"
|
||||
"hello/world/directory"
|
||||
}, dirs
|
||||
|
Loading…
Reference in New Issue
Block a user