1package.preload['moonscript.base'] = function() 2 local compile = require("moonscript.compile") 3 local parse = require("moonscript.parse") 4 local concat, insert, remove 5 do 6 local _obj_0 = table 7 concat, insert, remove = _obj_0.concat, _obj_0.insert, _obj_0.remove 8 end 9 local split, dump, get_options, unpack 10 do 11 local _obj_0 = require("moonscript.util") 12 split, dump, get_options, unpack = _obj_0.split, _obj_0.dump, _obj_0.get_options, _obj_0.unpack 13 end 14 local lua = { 15 loadstring = loadstring, 16 load = load 17 } 18 local dirsep, line_tables, create_moonpath, to_lua, moon_loader, loadstring, loadfile, dofile, insert_loader, remove_loader 19 dirsep = "/" 20 line_tables = require("moonscript.line_tables") 21 create_moonpath = function(package_path) 22 local paths = split(package_path, ";") 23 for i, path in ipairs(paths) do 24 local p = path:match("^(.-)%.lua$") 25 if p then 26 paths[i] = p .. ".moon" 27 end 28 end 29 return concat(paths, ";") 30 end 31 to_lua = function(text, options) 32 if options == nil then 33 options = { } 34 end 35 if "string" ~= type(text) then 36 local t = type(text) 37 return nil, "expecting string (got " .. t .. ")", 2 38 end 39 local tree, err = parse.string(text) 40 if not tree then 41 return nil, err 42 end 43 local code, ltable, pos = compile.tree(tree, options) 44 if not code then 45 return nil, compile.format_error(ltable, pos, text), 2 46 end 47 return code, ltable 48 end 49 loadstring = function(...) 50 local options, str, chunk_name, mode, env = get_options(...) 51 chunk_name = chunk_name or "=(moonscript.loadstring)" 52 local code, ltable_or_err = to_lua(str, options) 53 if not (code) then 54 return nil, ltable_or_err 55 end 56 if chunk_name then 57 line_tables[chunk_name] = ltable_or_err 58 end 59 return (lua.loadstring or lua.load)(code, chunk_name, unpack({ 60 mode, 61 env 62 })) 63 end 64 loadfile = function(fname, ...) 65 local file, err = io.open(fname) 66 if not (file) then 67 return nil, err 68 end 69 local text = assert(file:read("*a")) 70 file:close() 71 return loadstring(text, fname, ...) 72 end 73 dofile = function(...) 74 local f = assert(loadfile(...)) 75 return f() 76 end 77 return { 78 _NAME = "moonscript", 79 to_lua = to_lua, 80 moon_chunk = moon_chunk, 81 dirsep = dirsep, 82 dofile = dofile, 83 loadfile = loadfile, 84 loadstring = loadstring 85 } 86 87end 88package.preload['moonscript.cmd.coverage'] = function() 89 local log 90 log = function(str) 91 if str == nil then 92 str = "" 93 end 94 return io.stderr:write(str .. "\n") 95 end 96 local create_counter 97 create_counter = function() 98 return setmetatable({ }, { 99 __index = function(self, name) 100 do 101 local tbl = setmetatable({ }, { 102 __index = function(self) 103 return 0 104 end 105 }) 106 self[name] = tbl 107 return tbl 108 end 109 end 110 }) 111 end 112 local position_to_lines 113 position_to_lines = function(file_content, positions) 114 local lines = { } 115 local current_pos = 0 116 local line_no = 1 117 for char in file_content:gmatch(".") do 118 do 119 local count = rawget(positions, current_pos) 120 if count then 121 lines[line_no] = count 122 end 123 end 124 if char == "\n" then 125 line_no = line_no + 1 126 end 127 current_pos = current_pos + 1 128 end 129 return lines 130 end 131 local format_file 132 format_file = function(fname, positions) 133 local file = assert(io.open(fname)) 134 local content = file:read("*a") 135 file:close() 136 local lines = position_to_lines(content, positions) 137 log("------| @" .. tostring(fname)) 138 local line_no = 1 139 for line in (content .. "\n"):gmatch("(.-)\n") do 140 local foramtted_no = ("% 5d"):format(line_no) 141 local sym = lines[line_no] and "*" or " " 142 log(tostring(sym) .. tostring(foramtted_no) .. "| " .. tostring(line)) 143 line_no = line_no + 1 144 end 145 return log() 146 end 147 local CodeCoverage 148 do 149 local _base_0 = { 150 reset = function(self) 151 self.line_counts = create_counter() 152 end, 153 start = function(self) 154 return debug.sethook((function() 155 local _base_1 = self 156 local _fn_0 = _base_1.process_line 157 return function(...) 158 return _fn_0(_base_1, ...) 159 end 160 end)(), "l") 161 end, 162 stop = function(self) 163 return debug.sethook() 164 end, 165 print_results = function(self) 166 return self:format_results() 167 end, 168 process_line = function(self, _, line_no) 169 local debug_data = debug.getinfo(2, "S") 170 local source = debug_data.source 171 self.line_counts[source][line_no] = self.line_counts[source][line_no] + 1 172 end, 173 format_results = function(self) 174 local line_table = require("moonscript.line_tables") 175 local positions = create_counter() 176 for file, lines in pairs(self.line_counts) do 177 local _continue_0 = false 178 repeat 179 local file_table = line_table[file] 180 if not (file_table) then 181 _continue_0 = true 182 break 183 end 184 for line, count in pairs(lines) do 185 local _continue_1 = false 186 repeat 187 local position = file_table[line] 188 if not (position) then 189 _continue_1 = true 190 break 191 end 192 positions[file][position] = positions[file][position] + count 193 _continue_1 = true 194 until true 195 if not _continue_1 then 196 break 197 end 198 end 199 _continue_0 = true 200 until true 201 if not _continue_0 then 202 break 203 end 204 end 205 for file, ps in pairs(positions) do 206 format_file(file, ps) 207 end 208 end 209 } 210 _base_0.__index = _base_0 211 local _class_0 = setmetatable({ 212 __init = function(self) 213 return self:reset() 214 end, 215 __base = _base_0, 216 __name = "CodeCoverage" 217 }, { 218 __index = _base_0, 219 __call = function(cls, ...) 220 local _self_0 = setmetatable({}, _base_0) 221 cls.__init(_self_0, ...) 222 return _self_0 223 end 224 }) 225 _base_0.__class = _class_0 226 CodeCoverage = _class_0 227 end 228 return { 229 CodeCoverage = CodeCoverage 230 } 231 232end 233package.preload['moonscript.cmd.lint'] = function() 234 local insert 235 do 236 local _obj_0 = table 237 insert = _obj_0.insert 238 end 239 local Set 240 do 241 local _obj_0 = require("moonscript.data") 242 Set = _obj_0.Set 243 end 244 local Block 245 do 246 local _obj_0 = require("moonscript.compile") 247 Block = _obj_0.Block 248 end 249 local default_whitelist = Set({ 250 '_G', 251 '_VERSION', 252 'assert', 253 'bit32', 254 'collectgarbage', 255 'coroutine', 256 'debug', 257 'dofile', 258 'error', 259 'getfenv', 260 'getmetatable', 261 'io', 262 'ipairs', 263 'load', 264 'loadfile', 265 'loadstring', 266 'math', 267 'module', 268 'next', 269 'os', 270 'package', 271 'pairs', 272 'pcall', 273 'print', 274 'rawequal', 275 'rawget', 276 'rawlen', 277 'rawset', 278 'require', 279 'select', 280 'setfenv', 281 'setmetatable', 282 'string', 283 'table', 284 'tonumber', 285 'tostring', 286 'type', 287 'unpack', 288 'xpcall', 289 "nil", 290 "true", 291 "false" 292 }) 293 local LinterBlock 294 do 295 local _parent_0 = Block 296 local _base_0 = { 297 block = function(self, ...) 298 do 299 local _with_0 = _parent_0.block(self, ...) 300 _with_0.block = self.block 301 _with_0.value_compilers = self.value_compilers 302 return _with_0 303 end 304 end 305 } 306 _base_0.__index = _base_0 307 setmetatable(_base_0, _parent_0.__base) 308 local _class_0 = setmetatable({ 309 __init = function(self, whitelist_globals, ...) 310 if whitelist_globals == nil then 311 whitelist_globals = default_whitelist 312 end 313 _parent_0.__init(self, ...) 314 self.lint_errors = { } 315 local vc = self.value_compilers 316 self.value_compilers = setmetatable({ 317 ref = function(block, val) 318 local name = val[2] 319 if not (block:has_name(name) or whitelist_globals[name] or name:match("%.")) then 320 insert(self.lint_errors, { 321 "accessing global " .. tostring(name), 322 val[-1] 323 }) 324 end 325 return vc.ref(block, val) 326 end 327 }, { 328 __index = vc 329 }) 330 end, 331 __base = _base_0, 332 __name = "LinterBlock", 333 __parent = _parent_0 334 }, { 335 __index = function(cls, name) 336 local val = rawget(_base_0, name) 337 if val == nil then 338 return _parent_0[name] 339 else 340 return val 341 end 342 end, 343 __call = function(cls, ...) 344 local _self_0 = setmetatable({}, _base_0) 345 cls.__init(_self_0, ...) 346 return _self_0 347 end 348 }) 349 _base_0.__class = _class_0 350 if _parent_0.__inherited then 351 _parent_0.__inherited(_parent_0, _class_0) 352 end 353 LinterBlock = _class_0 354 end 355 local format_lint 356 format_lint = function(errors, code, header) 357 if not (next(errors)) then 358 return 359 end 360 local pos_to_line, get_line 361 do 362 local _obj_0 = require("moonscript.util") 363 pos_to_line, get_line = _obj_0.pos_to_line, _obj_0.get_line 364 end 365 local formatted 366 do 367 local _accum_0 = { } 368 local _len_0 = 1 369 for _index_0 = 1, #errors do 370 local _des_0 = errors[_index_0] 371 local msg, pos 372 msg, pos = _des_0[1], _des_0[2] 373 if pos then 374 local line = pos_to_line(code, pos) 375 msg = "line " .. tostring(line) .. ": " .. tostring(msg) 376 local line_text = "> " .. get_line(code, line) 377 local sep_len = math.max(#msg, #line_text) 378 _accum_0[_len_0] = table.concat({ 379 msg, 380 ("="):rep(sep_len), 381 line_text 382 }, "\n") 383 else 384 _accum_0[_len_0] = msg 385 end 386 _len_0 = _len_0 + 1 387 end 388 formatted = _accum_0 389 end 390 if header then 391 table.insert(formatted, 1, header) 392 end 393 return table.concat(formatted, "\n\n") 394 end 395 local whitelist_for_file 396 do 397 local lint_config 398 whitelist_for_file = function(fname) 399 if not (lint_config) then 400 lint_config = { } 401 pcall(function() 402 lint_config = require("lint_config") 403 end) 404 end 405 if not (lint_config.whitelist_globals) then 406 return default_whitelist 407 end 408 local final_list = { } 409 for pattern, list in pairs(lint_config.whitelist_globals) do 410 if fname:match(pattern) then 411 for _index_0 = 1, #list do 412 local item = list[_index_0] 413 insert(final_list, item) 414 end 415 end 416 end 417 return setmetatable(Set(final_list), { 418 __index = default_whitelist 419 }) 420 end 421 end 422 local lint_code 423 lint_code = function(code, name, whitelist_globals) 424 if name == nil then 425 name = "string input" 426 end 427 local parse = require("moonscript.parse") 428 local tree, err = parse.string(code) 429 if not (tree) then 430 return nil, err 431 end 432 local scope = LinterBlock(whitelist_globals) 433 scope:stms(tree) 434 return format_lint(scope.lint_errors, code, name) 435 end 436 local lint_file 437 lint_file = function(fname) 438 local f, err = io.open(fname) 439 if not (f) then 440 return nil, err 441 end 442 return lint_code(f:read("*a"), fname, whitelist_for_file(fname)) 443 end 444 return { 445 lint_code = lint_code, 446 lint_file = lint_file 447 } 448 449end 450package.preload['moonscript.compile.statement'] = function() 451 local util = require("moonscript.util") 452 local data = require("moonscript.data") 453 local reversed, unpack 454 reversed, unpack = util.reversed, util.unpack 455 local ntype 456 do 457 local _obj_0 = require("moonscript.types") 458 ntype = _obj_0.ntype 459 end 460 local concat, insert 461 do 462 local _obj_0 = table 463 concat, insert = _obj_0.concat, _obj_0.insert 464 end 465 return { 466 raw = function(self, node) 467 return self:add(node[2]) 468 end, 469 lines = function(self, node) 470 local _list_0 = node[2] 471 for _index_0 = 1, #_list_0 do 472 local line = _list_0[_index_0] 473 self:add(line) 474 end 475 end, 476 declare = function(self, node) 477 local names = node[2] 478 local undeclared = self:declare(names) 479 if #undeclared > 0 then 480 do 481 local _with_0 = self:line("local ") 482 _with_0:append_list((function() 483 local _accum_0 = { } 484 local _len_0 = 1 485 for _index_0 = 1, #undeclared do 486 local name = undeclared[_index_0] 487 _accum_0[_len_0] = self:name(name) 488 _len_0 = _len_0 + 1 489 end 490 return _accum_0 491 end)(), ", ") 492 return _with_0 493 end 494 end 495 end, 496 declare_with_shadows = function(self, node) 497 local names = node[2] 498 self:declare(names) 499 do 500 local _with_0 = self:line("local ") 501 _with_0:append_list((function() 502 local _accum_0 = { } 503 local _len_0 = 1 504 for _index_0 = 1, #names do 505 local name = names[_index_0] 506 _accum_0[_len_0] = self:name(name) 507 _len_0 = _len_0 + 1 508 end 509 return _accum_0 510 end)(), ", ") 511 return _with_0 512 end 513 end, 514 assign = function(self, node) 515 local _, names, values = unpack(node) 516 local undeclared = self:declare(names) 517 local declare = "local " .. concat(undeclared, ", ") 518 local has_fndef = false 519 local i = 1 520 while i <= #values do 521 if ntype(values[i]) == "fndef" then 522 has_fndef = true 523 end 524 i = i + 1 525 end 526 do 527 local _with_0 = self:line() 528 if #undeclared == #names and not has_fndef then 529 _with_0:append(declare) 530 else 531 if #undeclared > 0 then 532 self:add(declare) 533 end 534 _with_0:append_list((function() 535 local _accum_0 = { } 536 local _len_0 = 1 537 for _index_0 = 1, #names do 538 local name = names[_index_0] 539 _accum_0[_len_0] = self:value(name) 540 _len_0 = _len_0 + 1 541 end 542 return _accum_0 543 end)(), ", ") 544 end 545 _with_0:append(" = ") 546 _with_0:append_list((function() 547 local _accum_0 = { } 548 local _len_0 = 1 549 for _index_0 = 1, #values do 550 local v = values[_index_0] 551 _accum_0[_len_0] = self:value(v) 552 _len_0 = _len_0 + 1 553 end 554 return _accum_0 555 end)(), ", ") 556 return _with_0 557 end 558 end, 559 ["return"] = function(self, node) 560 return self:line("return ", (function() 561 if node[2] ~= "" then 562 return self:value(node[2]) 563 end 564 end)()) 565 end, 566 ["break"] = function(self, node) 567 return "break" 568 end, 569 ["if"] = function(self, node) 570 local cond, block = node[2], node[3] 571 local root 572 do 573 local _with_0 = self:block(self:line("if ", self:value(cond), " then")) 574 _with_0:stms(block) 575 root = _with_0 576 end 577 local current = root 578 local add_clause 579 add_clause = function(clause) 580 local type = clause[1] 581 local i = 2 582 local next 583 if type == "else" then 584 next = self:block("else") 585 else 586 i = i + 1 587 next = self:block(self:line("elseif ", self:value(clause[2]), " then")) 588 end 589 next:stms(clause[i]) 590 current.next = next 591 current = next 592 end 593 for _index_0 = 4, #node do 594 cond = node[_index_0] 595 add_clause(cond) 596 end 597 return root 598 end, 599 ["repeat"] = function(self, node) 600 local cond, block = unpack(node, 2) 601 do 602 local _with_0 = self:block("repeat", self:line("until ", self:value(cond))) 603 _with_0:stms(block) 604 return _with_0 605 end 606 end, 607 ["while"] = function(self, node) 608 local _, cond, block = unpack(node) 609 do 610 local _with_0 = self:block(self:line("while ", self:value(cond), " do")) 611 _with_0:stms(block) 612 return _with_0 613 end 614 end, 615 ["for"] = function(self, node) 616 local _, name, bounds, block = unpack(node) 617 local loop = self:line("for ", self:name(name), " = ", self:value({ 618 "explist", 619 unpack(bounds) 620 }), " do") 621 do 622 local _with_0 = self:block(loop) 623 _with_0:declare({ 624 name 625 }) 626 _with_0:stms(block) 627 return _with_0 628 end 629 end, 630 foreach = function(self, node) 631 local _, names, exps, block = unpack(node) 632 local loop 633 do 634 local _with_0 = self:line() 635 _with_0:append("for ") 636 loop = _with_0 637 end 638 do 639 local _with_0 = self:block(loop) 640 loop:append_list((function() 641 local _accum_0 = { } 642 local _len_0 = 1 643 for _index_0 = 1, #names do 644 local name = names[_index_0] 645 _accum_0[_len_0] = _with_0:name(name, false) 646 _len_0 = _len_0 + 1 647 end 648 return _accum_0 649 end)(), ", ") 650 loop:append(" in ") 651 loop:append_list((function() 652 local _accum_0 = { } 653 local _len_0 = 1 654 for _index_0 = 1, #exps do 655 local exp = exps[_index_0] 656 _accum_0[_len_0] = self:value(exp) 657 _len_0 = _len_0 + 1 658 end 659 return _accum_0 660 end)(), ",") 661 loop:append(" do") 662 _with_0:declare(names) 663 _with_0:stms(block) 664 return _with_0 665 end 666 end, 667 export = function(self, node) 668 local _, names = unpack(node) 669 if type(names) == "string" then 670 if names == "*" then 671 self.export_all = true 672 elseif names == "^" then 673 self.export_proper = true 674 end 675 else 676 self:declare(names) 677 end 678 return nil 679 end, 680 run = function(self, code) 681 code:call(self) 682 return nil 683 end, 684 group = function(self, node) 685 return self:stms(node[2]) 686 end, 687 ["do"] = function(self, node) 688 do 689 local _with_0 = self:block() 690 _with_0:stms(node[2]) 691 return _with_0 692 end 693 end, 694 noop = function(self) end 695 } 696 697end 698package.preload['moonscript.compile.value'] = function() 699 local util = require("moonscript.util") 700 local data = require("moonscript.data") 701 local ntype 702 do 703 local _obj_0 = require("moonscript.types") 704 ntype = _obj_0.ntype 705 end 706 local user_error 707 do 708 local _obj_0 = require("moonscript.errors") 709 user_error = _obj_0.user_error 710 end 711 local concat, insert 712 do 713 local _obj_0 = table 714 concat, insert = _obj_0.concat, _obj_0.insert 715 end 716 local unpack 717 unpack = util.unpack 718 local table_delim = "," 719 local string_chars = { 720 ["\r"] = "\\r", 721 ["\n"] = "\\n" 722 } 723 return { 724 exp = function(self, node) 725 local _comp 726 _comp = function(i, value) 727 if i % 2 == 1 and value == "!=" then 728 value = "~=" 729 end 730 return self:value(value) 731 end 732 do 733 local _with_0 = self:line() 734 _with_0:append_list((function() 735 local _accum_0 = { } 736 local _len_0 = 1 737 for i, v in ipairs(node) do 738 if i > 1 then 739 _accum_0[_len_0] = _comp(i, v) 740 _len_0 = _len_0 + 1 741 end 742 end 743 return _accum_0 744 end)(), " ") 745 return _with_0 746 end 747 end, 748 explist = function(self, node) 749 do 750 local _with_0 = self:line() 751 _with_0:append_list((function() 752 local _accum_0 = { } 753 local _len_0 = 1 754 for _index_0 = 2, #node do 755 local v = node[_index_0] 756 _accum_0[_len_0] = self:value(v) 757 _len_0 = _len_0 + 1 758 end 759 return _accum_0 760 end)(), ", ") 761 return _with_0 762 end 763 end, 764 parens = function(self, node) 765 return self:line("(", self:value(node[2]), ")") 766 end, 767 string = function(self, node) 768 local _, delim, inner = unpack(node) 769 local end_delim = delim:gsub("%[", "]") 770 if delim == "'" or delim == '"' then 771 inner = inner:gsub("[\r\n]", string_chars) 772 end 773 return delim .. inner .. end_delim 774 end, 775 chain = function(self, node) 776 local callee = node[2] 777 local callee_type = ntype(callee) 778 if callee == -1 then 779 callee = self:get("scope_var") 780 if not callee then 781 user_error("Short-dot syntax must be called within a with block") 782 end 783 end 784 if callee_type == "ref" and callee[2] == "super" or callee == "super" then 785 do 786 local sup = self:get("super") 787 if sup then 788 return self:value(sup(self, node)) 789 end 790 end 791 end 792 local chain_item 793 chain_item = function(node) 794 local t, arg = unpack(node) 795 if t == "call" then 796 return "(", self:values(arg), ")" 797 elseif t == "index" then 798 return "[", self:value(arg), "]" 799 elseif t == "dot" then 800 return ".", tostring(arg) 801 elseif t == "colon" then 802 return ":", arg, chain_item(node[3]) 803 elseif t == "colon_stub" then 804 return user_error("Uncalled colon stub") 805 else 806 return error("Unknown chain action: " .. tostring(t)) 807 end 808 end 809 if (callee_type == "self" or callee_type == "self_class") and node[3] and ntype(node[3]) == "call" then 810 callee[1] = callee_type .. "_colon" 811 end 812 local callee_value = self:value(callee) 813 if ntype(callee) == "exp" then 814 callee_value = self:line("(", callee_value, ")") 815 end 816 local actions 817 do 818 local _with_0 = self:line() 819 for _index_0 = 3, #node do 820 local action = node[_index_0] 821 _with_0:append(chain_item(action)) 822 end 823 actions = _with_0 824 end 825 return self:line(callee_value, actions) 826 end, 827 fndef = function(self, node) 828 local _, args, whitelist, arrow, block = unpack(node) 829 local default_args = { } 830 local self_args = { } 831 local arg_names 832 do 833 local _accum_0 = { } 834 local _len_0 = 1 835 for _index_0 = 1, #args do 836 local arg = args[_index_0] 837 local name, default_value = unpack(arg) 838 if type(name) == "string" then 839 name = name 840 else 841 if name[1] == "self" or name[1] == "self_class" then 842 insert(self_args, name) 843 end 844 name = name[2] 845 end 846 if default_value then 847 insert(default_args, arg) 848 end 849 local _value_0 = name 850 _accum_0[_len_0] = _value_0 851 _len_0 = _len_0 + 1 852 end 853 arg_names = _accum_0 854 end 855 if arrow == "fat" then 856 insert(arg_names, 1, "self") 857 end 858 do 859 local _with_0 = self:block() 860 if #whitelist > 0 then 861 _with_0:whitelist_names(whitelist) 862 end 863 for _index_0 = 1, #arg_names do 864 local name = arg_names[_index_0] 865 _with_0:put_name(name) 866 end 867 for _index_0 = 1, #default_args do 868 local default = default_args[_index_0] 869 local name, value = unpack(default) 870 if type(name) == "table" then 871 name = name[2] 872 end 873 _with_0:stm({ 874 'if', 875 { 876 'exp', 877 { 878 "ref", 879 name 880 }, 881 '==', 882 'nil' 883 }, 884 { 885 { 886 'assign', 887 { 888 name 889 }, 890 { 891 value 892 } 893 } 894 } 895 }) 896 end 897 local self_arg_values 898 do 899 local _accum_0 = { } 900 local _len_0 = 1 901 for _index_0 = 1, #self_args do 902 local arg = self_args[_index_0] 903 _accum_0[_len_0] = arg[2] 904 _len_0 = _len_0 + 1 905 end 906 self_arg_values = _accum_0 907 end 908 if #self_args > 0 then 909 _with_0:stm({ 910 "assign", 911 self_args, 912 self_arg_values 913 }) 914 end 915 _with_0:stms(block) 916 if #args > #arg_names then 917 do 918 local _accum_0 = { } 919 local _len_0 = 1 920 for _index_0 = 1, #args do 921 local arg = args[_index_0] 922 _accum_0[_len_0] = arg[1] 923 _len_0 = _len_0 + 1 924 end 925 arg_names = _accum_0 926 end 927 end 928 _with_0.header = "function(" .. concat(arg_names, ", ") .. ")" 929 return _with_0 930 end 931 end, 932 table = function(self, node) 933 local _, items = unpack(node) 934 do 935 local _with_0 = self:block("{", "}") 936 local format_line 937 format_line = function(tuple) 938 if #tuple == 2 then 939 local key, value = unpack(tuple) 940 if ntype(key) == "key_literal" and data.lua_keywords[key[2]] then 941 key = { 942 "string", 943 '"', 944 key[2] 945 } 946 end 947 local assign 948 if ntype(key) == "key_literal" then 949 assign = key[2] 950 else 951 assign = self:line("[", _with_0:value(key), "]") 952 end 953 _with_0:set("current_block", key) 954 local out = self:line(assign, " = ", _with_0:value(value)) 955 _with_0:set("current_block", nil) 956 return out 957 else 958 return self:line(_with_0:value(tuple[1])) 959 end 960 end 961 if items then 962 local count = #items 963 for i, tuple in ipairs(items) do 964 local line = format_line(tuple) 965 if not (count == i) then 966 line:append(table_delim) 967 end 968 _with_0:add(line) 969 end 970 end 971 return _with_0 972 end 973 end, 974 minus = function(self, node) 975 return self:line("-", self:value(node[2])) 976 end, 977 temp_name = function(self, node, ...) 978 return node:get_name(self, ...) 979 end, 980 number = function(self, node) 981 return node[2] 982 end, 983 length = function(self, node) 984 return self:line("#", self:value(node[2])) 985 end, 986 ["not"] = function(self, node) 987 return self:line("not ", self:value(node[2])) 988 end, 989 self = function(self, node) 990 return "self." .. self:name(node[2]) 991 end, 992 self_class = function(self, node) 993 return "self.__class." .. self:name(node[2]) 994 end, 995 self_colon = function(self, node) 996 return "self:" .. self:name(node[2]) 997 end, 998 self_class_colon = function(self, node) 999 return "self.__class:" .. self:name(node[2]) 1000 end, 1001 ref = function(self, value) 1002 do 1003 local sup = value[2] == "super" and self:get("super") 1004 if sup then 1005 return self:value(sup(self)) 1006 end 1007 end 1008 return tostring(value[2]) 1009 end, 1010 raw_value = function(self, value) 1011 if value == "..." then 1012 self:send("varargs") 1013 end 1014 return tostring(value) 1015 end 1016 } 1017 1018end 1019package.preload['moonscript.compile'] = function() 1020 local util = require("moonscript.util") 1021 local dump = require("moonscript.dump") 1022 local transform = require("moonscript.transform") 1023 local NameProxy, LocalName 1024 do 1025 local _obj_0 = require("moonscript.transform.names") 1026 NameProxy, LocalName = _obj_0.NameProxy, _obj_0.LocalName 1027 end 1028 local Set 1029 do 1030 local _obj_0 = require("moonscript.data") 1031 Set = _obj_0.Set 1032 end 1033 local ntype, has_value 1034 do 1035 local _obj_0 = require("moonscript.types") 1036 ntype, has_value = _obj_0.ntype, _obj_0.has_value 1037 end 1038 local statement_compilers = require("moonscript.compile.statement") 1039 local value_compilers = require("moonscript.compile.value") 1040 local concat, insert 1041 do 1042 local _obj_0 = table 1043 concat, insert = _obj_0.concat, _obj_0.insert 1044 end 1045 local pos_to_line, get_closest_line, trim, unpack 1046 pos_to_line, get_closest_line, trim, unpack = util.pos_to_line, util.get_closest_line, util.trim, util.unpack 1047 local mtype = util.moon.type 1048 local indent_char = " " 1049 local Line, DelayedLine, Lines, Block, RootBlock 1050 do 1051 local _base_0 = { 1052 mark_pos = function(self, pos, line) 1053 if line == nil then 1054 line = #self 1055 end 1056 if not (self.posmap[line]) then 1057 self.posmap[line] = pos 1058 end 1059 end, 1060 add = function(self, item) 1061 local _exp_0 = mtype(item) 1062 if Line == _exp_0 then 1063 item:render(self) 1064 elseif Block == _exp_0 then 1065 item:render(self) 1066 else 1067 self[#self + 1] = item 1068 end 1069 return self 1070 end, 1071 flatten_posmap = function(self, line_no, out) 1072 if line_no == nil then 1073 line_no = 0 1074 end 1075 if out == nil then 1076 out = { } 1077 end 1078 local posmap = self.posmap 1079 for i, l in ipairs(self) do 1080 local _exp_0 = mtype(l) 1081 if "string" == _exp_0 or DelayedLine == _exp_0 then 1082 line_no = line_no + 1 1083 out[line_no] = posmap[i] 1084 for _ in l:gmatch("\n") do 1085 line_no = line_no + 1 1086 end 1087 out[line_no] = posmap[i] 1088 elseif Lines == _exp_0 then 1089 local _ 1090 _, line_no = l:flatten_posmap(line_no, out) 1091 else 1092 error("Unknown item in Lines: " .. tostring(l)) 1093 end 1094 end 1095 return out, line_no 1096 end, 1097 flatten = function(self, indent, buffer) 1098 if indent == nil then 1099 indent = nil 1100 end 1101 if buffer == nil then 1102 buffer = { } 1103 end 1104 for i = 1, #self do 1105 local l = self[i] 1106 local t = mtype(l) 1107 if t == DelayedLine then 1108 l = l:render() 1109 t = "string" 1110 end 1111 local _exp_0 = t 1112 if "string" == _exp_0 then 1113 if indent then 1114 insert(buffer, indent) 1115 end 1116 insert(buffer, l) 1117 if "string" == type(self[i + 1]) then 1118 local lc = l:sub(-1) 1119 if (lc == ")" or lc == "]") and self[i + 1]:sub(1, 1) == "(" then 1120 insert(buffer, ";") 1121 end 1122 end 1123 insert(buffer, "\n") 1124 local last = l 1125 elseif Lines == _exp_0 then 1126 l:flatten(indent and indent .. indent_char or indent_char, buffer) 1127 else 1128 error("Unknown item in Lines: " .. tostring(l)) 1129 end 1130 end 1131 return buffer 1132 end, 1133 __tostring = function(self) 1134 local strip 1135 strip = function(t) 1136 if "table" == type(t) then 1137 local _accum_0 = { } 1138 local _len_0 = 1 1139 for _index_0 = 1, #t do 1140 local v = t[_index_0] 1141 _accum_0[_len_0] = strip(v) 1142 _len_0 = _len_0 + 1 1143 end 1144 return _accum_0 1145 else 1146 return t 1147 end 1148 end 1149 return "Lines<" .. tostring(util.dump(strip(self)):sub(1, -2)) .. ">" 1150 end 1151 } 1152 _base_0.__index = _base_0 1153 local _class_0 = setmetatable({ 1154 __init = function(self) 1155 self.posmap = { } 1156 end, 1157 __base = _base_0, 1158 __name = "Lines" 1159 }, { 1160 __index = _base_0, 1161 __call = function(cls, ...) 1162 local _self_0 = setmetatable({}, _base_0) 1163 cls.__init(_self_0, ...) 1164 return _self_0 1165 end 1166 }) 1167 _base_0.__class = _class_0 1168 Lines = _class_0 1169 end 1170 do 1171 local _base_0 = { 1172 pos = nil, 1173 append_list = function(self, items, delim) 1174 for i = 1, #items do 1175 self:append(items[i]) 1176 if i < #items then 1177 insert(self, delim) 1178 end 1179 end 1180 return nil 1181 end, 1182 append = function(self, first, ...) 1183 if Line == mtype(first) then 1184 if not (self.pos) then 1185 self.pos = first.pos 1186 end 1187 for _index_0 = 1, #first do 1188 local value = first[_index_0] 1189 self:append(value) 1190 end 1191 else 1192 insert(self, first) 1193 end 1194 if ... then 1195 return self:append(...) 1196 end 1197 end, 1198 render = function(self, buffer) 1199 local current = { } 1200 local add_current 1201 add_current = function() 1202 buffer:add(concat(current)) 1203 return buffer:mark_pos(self.pos) 1204 end 1205 for _index_0 = 1, #self do 1206 local chunk = self[_index_0] 1207 local _exp_0 = mtype(chunk) 1208 if Block == _exp_0 then 1209 local _list_0 = chunk:render(Lines()) 1210 for _index_1 = 1, #_list_0 do 1211 local block_chunk = _list_0[_index_1] 1212 if "string" == type(block_chunk) then 1213 insert(current, block_chunk) 1214 else 1215 add_current() 1216 buffer:add(block_chunk) 1217 current = { } 1218 end 1219 end 1220 else 1221 insert(current, chunk) 1222 end 1223 end 1224 if current[1] then 1225 add_current() 1226 end 1227 return buffer 1228 end, 1229 __tostring = function(self) 1230 return "Line<" .. tostring(util.dump(self):sub(1, -2)) .. ">" 1231 end 1232 } 1233 _base_0.__index = _base_0 1234 local _class_0 = setmetatable({ 1235 __init = function() end, 1236 __base = _base_0, 1237 __name = "Line" 1238 }, { 1239 __index = _base_0, 1240 __call = function(cls, ...) 1241 local _self_0 = setmetatable({}, _base_0) 1242 cls.__init(_self_0, ...) 1243 return _self_0 1244 end 1245 }) 1246 _base_0.__class = _class_0 1247 Line = _class_0 1248 end 1249 do 1250 local _base_0 = { 1251 prepare = function() end, 1252 render = function(self) 1253 self:prepare() 1254 return concat(self) 1255 end 1256 } 1257 _base_0.__index = _base_0 1258 local _class_0 = setmetatable({ 1259 __init = function(self, fn) 1260 self.prepare = fn 1261 end, 1262 __base = _base_0, 1263 __name = "DelayedLine" 1264 }, { 1265 __index = _base_0, 1266 __call = function(cls, ...) 1267 local _self_0 = setmetatable({}, _base_0) 1268 cls.__init(_self_0, ...) 1269 return _self_0 1270 end 1271 }) 1272 _base_0.__class = _class_0 1273 DelayedLine = _class_0 1274 end 1275 do 1276 local _base_0 = { 1277 header = "do", 1278 footer = "end", 1279 export_all = false, 1280 export_proper = false, 1281 value_compilers = value_compilers, 1282 __tostring = function(self) 1283 local h 1284 if "string" == type(self.header) then 1285 h = self.header 1286 else 1287 h = unpack(self.header:render({ })) 1288 end 1289 return "Block<" .. tostring(h) .. "> <- " .. tostring(self.parent) 1290 end, 1291 set = function(self, name, value) 1292 self._state[name] = value 1293 end, 1294 get = function(self, name) 1295 return self._state[name] 1296 end, 1297 get_current = function(self, name) 1298 return rawget(self._state, name) 1299 end, 1300 listen = function(self, name, fn) 1301 self._listeners[name] = fn 1302 end, 1303 unlisten = function(self, name) 1304 self._listeners[name] = nil 1305 end, 1306 send = function(self, name, ...) 1307 do 1308 local fn = self._listeners[name] 1309 if fn then 1310 return fn(self, ...) 1311 end 1312 end 1313 end, 1314 declare = function(self, names) 1315 local undeclared 1316 do 1317 local _accum_0 = { } 1318 local _len_0 = 1 1319 for _index_0 = 1, #names do 1320 local _continue_0 = false 1321 repeat 1322 local name = names[_index_0] 1323 local is_local = false 1324 local real_name 1325 local _exp_0 = mtype(name) 1326 if LocalName == _exp_0 then 1327 is_local = true 1328 real_name = name:get_name(self) 1329 elseif NameProxy == _exp_0 then 1330 real_name = name:get_name(self) 1331 elseif "table" == _exp_0 then 1332 real_name = name[1] == "ref" and name[2] 1333 elseif "string" == _exp_0 then 1334 real_name = name 1335 end 1336 if not (is_local or real_name and not self:has_name(real_name, true)) then 1337 _continue_0 = true 1338 break 1339 end 1340 self:put_name(real_name) 1341 if self:name_exported(real_name) then 1342 _continue_0 = true 1343 break 1344 end 1345 local _value_0 = real_name 1346 _accum_0[_len_0] = _value_0 1347 _len_0 = _len_0 + 1 1348 _continue_0 = true 1349 until true 1350 if not _continue_0 then 1351 break 1352 end 1353 end 1354 undeclared = _accum_0 1355 end 1356 return undeclared 1357 end, 1358 whitelist_names = function(self, names) 1359 self._name_whitelist = Set(names) 1360 end, 1361 name_exported = function(self, name) 1362 if self.export_all then 1363 return true 1364 end 1365 if self.export_proper and name:match("^%u") then 1366 return true 1367 end 1368 end, 1369 put_name = function(self, name, ...) 1370 local value = ... 1371 if select("#", ...) == 0 then 1372 value = true 1373 end 1374 if NameProxy == mtype(name) then 1375 name = name:get_name(self) 1376 end 1377 self._names[name] = value 1378 end, 1379 has_name = function(self, name, skip_exports) 1380 if not skip_exports and self:name_exported(name) then 1381 return true 1382 end 1383 local yes = self._names[name] 1384 if yes == nil and self.parent then 1385 if not self._name_whitelist or self._name_whitelist[name] then 1386 return self.parent:has_name(name, true) 1387 end 1388 else 1389 return yes 1390 end 1391 end, 1392 is_local = function(self, node) 1393 local t = mtype(node) 1394 if t == "string" then 1395 return self:has_name(node, false) 1396 end 1397 if t == NameProxy or t == LocalName then 1398 return true 1399 end 1400 if t == "table" then 1401 if node[1] == "ref" or (node[1] == "chain" and #node == 2) then 1402 return self:is_local(node[2]) 1403 end 1404 end 1405 return false 1406 end, 1407 free_name = function(self, prefix, dont_put) 1408 prefix = prefix or "moon" 1409 local searching = true 1410 local name, i = nil, 0 1411 while searching do 1412 name = concat({ 1413 "", 1414 prefix, 1415 i 1416 }, "_") 1417 i = i + 1 1418 searching = self:has_name(name, true) 1419 end 1420 if not dont_put then 1421 self:put_name(name) 1422 end 1423 return name 1424 end, 1425 init_free_var = function(self, prefix, value) 1426 local name = self:free_name(prefix, true) 1427 self:stm({ 1428 "assign", 1429 { 1430 name 1431 }, 1432 { 1433 value 1434 } 1435 }) 1436 return name 1437 end, 1438 add = function(self, item) 1439 self._lines:add(item) 1440 return item 1441 end, 1442 render = function(self, buffer) 1443 buffer:add(self.header) 1444 buffer:mark_pos(self.pos) 1445 if self.next then 1446 buffer:add(self._lines) 1447 self.next:render(buffer) 1448 else 1449 if #self._lines == 0 and "string" == type(buffer[#buffer]) then 1450 buffer[#buffer] = buffer[#buffer] .. (" " .. (unpack(Lines():add(self.footer)))) 1451 else 1452 buffer:add(self._lines) 1453 buffer:add(self.footer) 1454 buffer:mark_pos(self.pos) 1455 end 1456 end 1457 return buffer 1458 end, 1459 block = function(self, header, footer) 1460 return Block(self, header, footer) 1461 end, 1462 line = function(self, ...) 1463 do 1464 local _with_0 = Line() 1465 _with_0:append(...) 1466 return _with_0 1467 end 1468 end, 1469 is_stm = function(self, node) 1470 return statement_compilers[ntype(node)] ~= nil 1471 end, 1472 is_value = function(self, node) 1473 local t = ntype(node) 1474 return self.value_compilers[t] ~= nil or t == "value" 1475 end, 1476 name = function(self, node, ...) 1477 if type(node) == "string" then 1478 return node 1479 else 1480 return self:value(node, ...) 1481 end 1482 end, 1483 value = function(self, node, ...) 1484 node = self.transform.value(node) 1485 local action 1486 if type(node) ~= "table" then 1487 action = "raw_value" 1488 else 1489 action = node[1] 1490 end 1491 local fn = self.value_compilers[action] 1492 if not (fn) then 1493 error({ 1494 "compile-error", 1495 "Failed to find value compiler for: " .. dump.value(node), 1496 node[-1] 1497 }) 1498 end 1499 local out = fn(self, node, ...) 1500 if type(node) == "table" and node[-1] then 1501 if type(out) == "string" then 1502 do 1503 local _with_0 = Line() 1504 _with_0:append(out) 1505 out = _with_0 1506 end 1507 end 1508 out.pos = node[-1] 1509 end 1510 return out 1511 end, 1512 values = function(self, values, delim) 1513 delim = delim or ', ' 1514 do 1515 local _with_0 = Line() 1516 _with_0:append_list((function() 1517 local _accum_0 = { } 1518 local _len_0 = 1 1519 for _index_0 = 1, #values do 1520 local v = values[_index_0] 1521 _accum_0[_len_0] = self:value(v) 1522 _len_0 = _len_0 + 1 1523 end 1524 return _accum_0 1525 end)(), delim) 1526 return _with_0 1527 end 1528 end, 1529 stm = function(self, node, ...) 1530 if not node then 1531 return 1532 end 1533 node = self.transform.statement(node) 1534 local result 1535 do 1536 local fn = statement_compilers[ntype(node)] 1537 if fn then 1538 result = fn(self, node, ...) 1539 else 1540 if has_value(node) then 1541 result = self:stm({ 1542 "assign", 1543 { 1544 "_" 1545 }, 1546 { 1547 node 1548 } 1549 }) 1550 else 1551 result = self:value(node) 1552 end 1553 end 1554 end 1555 if result then 1556 if type(node) == "table" and type(result) == "table" and node[-1] then 1557 result.pos = node[-1] 1558 end 1559 self:add(result) 1560 end 1561 return nil 1562 end, 1563 stms = function(self, stms, ret) 1564 if ret then 1565 error("deprecated stms call, use transformer") 1566 end 1567 local current_stms, current_stm_i 1568 current_stms, current_stm_i = self.current_stms, self.current_stm_i 1569 self.current_stms = stms 1570 for i = 1, #stms do 1571 self.current_stm_i = i 1572 self:stm(stms[i]) 1573 end 1574 self.current_stms = current_stms 1575 self.current_stm_i = current_stm_i 1576 return nil 1577 end, 1578 splice = function(self, fn) 1579 local lines = { 1580 "lines", 1581 self._lines 1582 } 1583 self._lines = Lines() 1584 return self:stms(fn(lines)) 1585 end 1586 } 1587 _base_0.__index = _base_0 1588 local _class_0 = setmetatable({ 1589 __init = function(self, parent, header, footer) 1590 self.parent, self.header, self.footer = parent, header, footer 1591 self._lines = Lines() 1592 self._names = { } 1593 self._state = { } 1594 self._listeners = { } 1595 do 1596 self.transform = { 1597 value = transform.Value:bind(self), 1598 statement = transform.Statement:bind(self) 1599 } 1600 end 1601 if self.parent then 1602 self.root = self.parent.root 1603 self.indent = self.parent.indent + 1 1604 setmetatable(self._state, { 1605 __index = self.parent._state 1606 }) 1607 return setmetatable(self._listeners, { 1608 __index = self.parent._listeners 1609 }) 1610 else 1611 self.indent = 0 1612 end 1613 end, 1614 __base = _base_0, 1615 __name = "Block" 1616 }, { 1617 __index = _base_0, 1618 __call = function(cls, ...) 1619 local _self_0 = setmetatable({}, _base_0) 1620 cls.__init(_self_0, ...) 1621 return _self_0 1622 end 1623 }) 1624 _base_0.__class = _class_0 1625 Block = _class_0 1626 end 1627 do 1628 local _parent_0 = Block 1629 local _base_0 = { 1630 __tostring = function(self) 1631 return "RootBlock<>" 1632 end, 1633 root_stms = function(self, stms) 1634 if not (self.options.implicitly_return_root == false) then 1635 stms = transform.Statement.transformers.root_stms(self, stms) 1636 end 1637 return self:stms(stms) 1638 end, 1639 render = function(self) 1640 local buffer = self._lines:flatten() 1641 if buffer[#buffer] == "\n" then 1642 buffer[#buffer] = nil 1643 end 1644 return table.concat(buffer) 1645 end 1646 } 1647 _base_0.__index = _base_0 1648 setmetatable(_base_0, _parent_0.__base) 1649 local _class_0 = setmetatable({ 1650 __init = function(self, options) 1651 self.options = options 1652 self.root = self 1653 return _parent_0.__init(self) 1654 end, 1655 __base = _base_0, 1656 __name = "RootBlock", 1657 __parent = _parent_0 1658 }, { 1659 __index = function(cls, name) 1660 local val = rawget(_base_0, name) 1661 if val == nil then 1662 return _parent_0[name] 1663 else 1664 return val 1665 end 1666 end, 1667 __call = function(cls, ...) 1668 local _self_0 = setmetatable({}, _base_0) 1669 cls.__init(_self_0, ...) 1670 return _self_0 1671 end 1672 }) 1673 _base_0.__class = _class_0 1674 if _parent_0.__inherited then 1675 _parent_0.__inherited(_parent_0, _class_0) 1676 end 1677 RootBlock = _class_0 1678 end 1679 local format_error 1680 format_error = function(msg, pos, file_str) 1681 local line_message 1682 if pos then 1683 local line = pos_to_line(file_str, pos) 1684 local line_str 1685 line_str, line = get_closest_line(file_str, line) 1686 line_str = line_str or "" 1687 line_message = (" [%d] >> %s"):format(line, trim(line_str)) 1688 end 1689 return concat({ 1690 "Compile error: " .. msg, 1691 line_message 1692 }, "\n") 1693 end 1694 local value 1695 value = function(value) 1696 local out = nil 1697 do 1698 local _with_0 = RootBlock() 1699 _with_0:add(_with_0:value(value)) 1700 out = _with_0:render() 1701 end 1702 return out 1703 end 1704 local tree 1705 tree = function(tree, options) 1706 if options == nil then 1707 options = { } 1708 end 1709 assert(tree, "missing tree") 1710 local scope = (options.scope or RootBlock)(options) 1711 local runner = coroutine.create(function() 1712 return scope:root_stms(tree) 1713 end) 1714 local success, err = coroutine.resume(runner) 1715 if not (success) then 1716 local error_msg, error_pos 1717 if type(err) == "table" then 1718 local error_type = err[1] 1719 local _exp_0 = err[1] 1720 if "user-error" == _exp_0 or "compile-error" == _exp_0 then 1721 error_msg, error_pos = unpack(err, 2) 1722 else 1723 error_msg, error_pos = error("Unknown error thrown", util.dump(error_msg)) 1724 end 1725 else 1726 error_msg, error_pos = concat({ 1727 err, 1728 debug.traceback(runner) 1729 }, "\n") 1730 end 1731 return nil, error_msg, error_pos or scope.last_pos 1732 end 1733 local lua_code = scope:render() 1734 local posmap = scope._lines:flatten_posmap() 1735 return lua_code, posmap 1736 end 1737 do 1738 local data = require("moonscript.data") 1739 for name, cls in pairs({ 1740 Line = Line, 1741 Lines = Lines, 1742 DelayedLine = DelayedLine 1743 }) do 1744 data[name] = cls 1745 end 1746 end 1747 return { 1748 tree = tree, 1749 value = value, 1750 format_error = format_error, 1751 Block = Block, 1752 RootBlock = RootBlock 1753 } 1754 1755end 1756package.preload['moonscript.data'] = function() 1757 local concat, remove, insert 1758 do 1759 local _obj_0 = table 1760 concat, remove, insert = _obj_0.concat, _obj_0.remove, _obj_0.insert 1761 end 1762 local Set 1763 Set = function(items) 1764 local _tbl_0 = { } 1765 for _index_0 = 1, #items do 1766 local k = items[_index_0] 1767 _tbl_0[k] = true 1768 end 1769 return _tbl_0 1770 end 1771 local Stack 1772 do 1773 local _base_0 = { 1774 __tostring = function(self) 1775 return "<Stack {" .. concat(self, ", ") .. "}>" 1776 end, 1777 pop = function(self) 1778 return remove(self) 1779 end, 1780 push = function(self, value, ...) 1781 insert(self, value) 1782 if ... then 1783 return self:push(...) 1784 else 1785 return value 1786 end 1787 end, 1788 top = function(self) 1789 return self[#self] 1790 end 1791 } 1792 _base_0.__index = _base_0 1793 local _class_0 = setmetatable({ 1794 __init = function(self, ...) 1795 self:push(...) 1796 return nil 1797 end, 1798 __base = _base_0, 1799 __name = "Stack" 1800 }, { 1801 __index = _base_0, 1802 __call = function(cls, ...) 1803 local _self_0 = setmetatable({}, _base_0) 1804 cls.__init(_self_0, ...) 1805 return _self_0 1806 end 1807 }) 1808 _base_0.__class = _class_0 1809 Stack = _class_0 1810 end 1811 local lua_keywords = Set({ 1812 'and', 1813 'break', 1814 'do', 1815 'else', 1816 'elseif', 1817 'end', 1818 'false', 1819 'for', 1820 'function', 1821 'if', 1822 'in', 1823 'local', 1824 'nil', 1825 'not', 1826 'or', 1827 'repeat', 1828 'return', 1829 'then', 1830 'true', 1831 'until', 1832 'while' 1833 }) 1834 return { 1835 Set = Set, 1836 Stack = Stack, 1837 lua_keywords = lua_keywords 1838 } 1839 1840end 1841package.preload['moonscript.dump'] = function() 1842 local flat_value 1843 flat_value = function(op, depth) 1844 if depth == nil then 1845 depth = 1 1846 end 1847 if type(op) == "string" then 1848 return '"' .. op .. '"' 1849 end 1850 if type(op) ~= "table" then 1851 return tostring(op) 1852 end 1853 local items 1854 do 1855 local _accum_0 = { } 1856 local _len_0 = 1 1857 for _index_0 = 1, #op do 1858 local item = op[_index_0] 1859 _accum_0[_len_0] = flat_value(item, depth + 1) 1860 _len_0 = _len_0 + 1 1861 end 1862 items = _accum_0 1863 end 1864 local pos = op[-1] 1865 return "{" .. (pos and "[" .. pos .. "] " or "") .. table.concat(items, ", ") .. "}" 1866 end 1867 local value 1868 value = function(op) 1869 return flat_value(op) 1870 end 1871 local tree 1872 tree = function(block) 1873 local _list_0 = block 1874 for _index_0 = 1, #_list_0 do 1875 value = _list_0[_index_0] 1876 print(flat_value(value)) 1877 end 1878 end 1879 return { 1880 value = value, 1881 tree = tree 1882 } 1883 1884end 1885package.preload['moonscript.errors'] = function() 1886 local util = require("moonscript.util") 1887 local lpeg = require("lpeg") 1888 local concat, insert 1889 do 1890 local _obj_0 = table 1891 concat, insert = _obj_0.concat, _obj_0.insert 1892 end 1893 local split, pos_to_line 1894 split, pos_to_line = util.split, util.pos_to_line 1895 local user_error 1896 user_error = function(...) 1897 return error({ 1898 "user-error", 1899 ... 1900 }) 1901 end 1902 local lookup_line 1903 lookup_line = function(fname, pos, cache) 1904 if not cache[fname] then 1905 do 1906 local _with_0 = io.open(fname) 1907 cache[fname] = _with_0:read("*a") 1908 _with_0:close() 1909 end 1910 end 1911 return pos_to_line(cache[fname], pos) 1912 end 1913 local reverse_line_number 1914 reverse_line_number = function(fname, line_table, line_num, cache) 1915 for i = line_num, 0, -1 do 1916 if line_table[i] then 1917 return lookup_line(fname, line_table[i], cache) 1918 end 1919 end 1920 return "unknown" 1921 end 1922 local truncate_traceback 1923 truncate_traceback = function(traceback, chunk_func) 1924 if chunk_func == nil then 1925 chunk_func = "moonscript_chunk" 1926 end 1927 traceback = split(traceback, "\n") 1928 local stop = #traceback 1929 while stop > 1 do 1930 if traceback[stop]:match(chunk_func) then 1931 break 1932 end 1933 stop = stop - 1 1934 end 1935 do 1936 local _accum_0 = { } 1937 local _len_0 = 1 1938 local _max_0 = stop 1939 for _index_0 = 1, _max_0 < 0 and #traceback + _max_0 or _max_0 do 1940 local t = traceback[_index_0] 1941 _accum_0[_len_0] = t 1942 _len_0 = _len_0 + 1 1943 end 1944 traceback = _accum_0 1945 end 1946 local rep = "function '" .. chunk_func .. "'" 1947 traceback[#traceback] = traceback[#traceback]:gsub(rep, "main chunk") 1948 return concat(traceback, "\n") 1949 end 1950 local rewrite_traceback 1951 rewrite_traceback = function(text, err) 1952 local line_tables = require("moonscript.line_tables") 1953 local V, S, Ct, C 1954 V, S, Ct, C = lpeg.V, lpeg.S, lpeg.Ct, lpeg.C 1955 local header_text = "stack traceback:" 1956 local Header, Line = V("Header"), V("Line") 1957 local Break = lpeg.S("\n") 1958 local g = lpeg.P({ 1959 Header, 1960 Header = header_text * Break * Ct(Line ^ 1), 1961 Line = "\t" * C((1 - Break) ^ 0) * (Break + -1) 1962 }) 1963 local cache = { } 1964 local rewrite_single 1965 rewrite_single = function(trace) 1966 local fname, line, msg = trace:match('^%[string "(.-)"]:(%d+): (.*)$') 1967 local tbl = line_tables[fname] 1968 if fname and tbl then 1969 return concat({ 1970 fname, 1971 ":", 1972 reverse_line_number(fname, tbl, line, cache), 1973 ": ", 1974 "(", 1975 line, 1976 ") ", 1977 msg 1978 }) 1979 else 1980 return trace 1981 end 1982 end 1983 err = rewrite_single(err) 1984 local match = g:match(text) 1985 if not (match) then 1986 return nil 1987 end 1988 for i, trace in ipairs(match) do 1989 match[i] = rewrite_single(trace) 1990 end 1991 return concat({ 1992 "moon: " .. err, 1993 header_text, 1994 "\t" .. concat(match, "\n\t") 1995 }, "\n") 1996 end 1997 return { 1998 rewrite_traceback = rewrite_traceback, 1999 truncate_traceback = truncate_traceback, 2000 user_error = user_error, 2001 reverse_line_number = reverse_line_number 2002 } 2003 2004end 2005package.preload['moonscript'] = function() 2006 return require("moonscript.base") 2007end 2008package.preload['moonscript.line_tables'] = function() 2009 return { } 2010 2011end 2012package.preload['moonscript.parse'] = function() 2013 2014 local util = require"moonscript.util" 2015 2016 local lpeg = require"lpeg" 2017 2018 local debug_grammar = false 2019 2020 local data = require"moonscript.data" 2021 local types = require"moonscript.types" 2022 2023 local ntype = types.ntype 2024 2025 local dump = util.dump 2026 local trim = util.trim 2027 2028 local getfenv = util.getfenv 2029 local setfenv = util.setfenv 2030 local unpack = util.unpack 2031 2032 local Stack = data.Stack 2033 2034 local function count_indent(str) 2035 local sum = 0 2036 for v in str:gmatch("[\t ]") do 2037 if v == ' ' then sum = sum + 1 end 2038 if v == '\t' then sum = sum + 4 end 2039 end 2040 return sum 2041 end 2042 2043 local R, S, V, P = lpeg.R, lpeg.S, lpeg.V, lpeg.P 2044 local C, Ct, Cmt, Cg, Cb, Cc = lpeg.C, lpeg.Ct, lpeg.Cmt, lpeg.Cg, lpeg.Cb, lpeg.Cc 2045 2046 lpeg.setmaxstack(10000) 2047 2048 local White = S" \t\r\n"^0 2049 local _Space = S" \t"^0 2050 local Break = P"\r"^-1 * P"\n" 2051 local Stop = Break + -1 2052 local Indent = C(S"\t "^0) / count_indent 2053 2054 local Comment = P"--" * (1 - S"\r\n")^0 * #Stop 2055 local Space = _Space * Comment^-1 2056 local SomeSpace = S" \t"^1 * Comment^-1 2057 2058 local SpaceBreak = Space * Break 2059 local EmptyLine = SpaceBreak 2060 2061 local AlphaNum = R("az", "AZ", "09", "__") 2062 2063 local _Name = C(R("az", "AZ", "__") * AlphaNum^0) 2064 local Name = Space * _Name 2065 2066 local Num = P"0x" * R("09", "af", "AF")^1 * (S"uU"^-1 * S"lL"^2)^-1 + 2067 R"09"^1 * (S"uU"^-1 * S"lL"^2) + 2068 ( 2069 R"09"^1 * (P"." * R"09"^1)^-1 + 2070 P"." * R"09"^1 2071 ) * (S"eE" * P"-"^-1 * R"09"^1)^-1 2072 2073 Num = Space * (Num / function(value) return {"number", value} end) 2074 2075 local FactorOp = Space * C(S"+-") 2076 local TermOp = Space * C(S"*/%^") 2077 2078 local Shebang = P"#!" * P(1 - Stop)^0 2079 2080 -- can't have P(false) because it causes preceding patterns not to run 2081 local Cut = P(function() return false end) 2082 2083 local function ensure(patt, finally) 2084 return patt * finally + finally * Cut 2085 end 2086 2087 -- auto declare Proper variables with lpeg.V 2088 local function wrap_env(fn) 2089 local env = getfenv(fn) 2090 local wrap_name = V 2091 2092 if debug_grammar then 2093 local indent = 0 2094 local indent_char = " " 2095 2096 local function iprint(...) 2097 local args = {...} 2098 for i=1,#args do 2099 args[i] = tostring(args[i]) 2100 end 2101 2102 io.stdout:write(indent_char:rep(indent) .. table.concat(args, ", ") .. "\n") 2103 end 2104 2105 wrap_name = function(name) 2106 local v = V(name) 2107 v = Cmt("", function() 2108 iprint("* " .. name) 2109 indent = indent + 1 2110 return true 2111 end) * Cmt(v, function(str, pos, ...) 2112 iprint(name, true) 2113 indent = indent - 1 2114 return true, ... 2115 end) + Cmt("", function() 2116 iprint(name, false) 2117 indent = indent - 1 2118 return false 2119 end) 2120 return v 2121 end 2122 end 2123 2124 return setfenv(fn, setmetatable({}, { 2125 __index = function(self, name) 2126 local value = env[name] 2127 if value ~= nil then return value end 2128 2129 if name:match"^[A-Z][A-Za-z0-9]*$" then 2130 local v = wrap_name(name) 2131 rawset(self, name, v) 2132 return v 2133 end 2134 error("unknown variable referenced: "..name) 2135 end 2136 })) 2137 end 2138 2139 local function extract_line(str, start_pos) 2140 str = str:sub(start_pos) 2141 m = str:match"^(.-)\n" 2142 if m then return m end 2143 return str:match"^.-$" 2144 end 2145 2146 local function mark(name) 2147 return function(...) 2148 return {name, ...} 2149 end 2150 end 2151 2152 local function insert_pos(pos, value) 2153 if type(value) == "table" then 2154 value[-1] = pos 2155 end 2156 return value 2157 end 2158 2159 local function pos(patt) 2160 return (lpeg.Cp() * patt) / insert_pos 2161 end 2162 2163 local function got(what) 2164 return Cmt("", function(str, pos, ...) 2165 local cap = {...} 2166 print("++ got "..what, "["..extract_line(str, pos).."]") 2167 return true 2168 end) 2169 end 2170 2171 local function flatten(tbl) 2172 if #tbl == 1 then 2173 return tbl[1] 2174 end 2175 return tbl 2176 end 2177 2178 local function flatten_or_mark(name) 2179 return function(tbl) 2180 if #tbl == 1 then return tbl[1] end 2181 table.insert(tbl, 1, name) 2182 return tbl 2183 end 2184 end 2185 2186 -- makes sure the last item in a chain is an index 2187 local _chain_assignable = { index = true, dot = true, slice = true } 2188 2189 local function is_assignable(node) 2190 if node == "..." then 2191 return false 2192 end 2193 2194 local t = ntype(node) 2195 return t == "ref" or t == "self" or t == "value" or t == "self_class" or 2196 t == "chain" and _chain_assignable[ntype(node[#node])] or 2197 t == "table" 2198 end 2199 2200 local function check_assignable(str, pos, value) 2201 if is_assignable(value) then 2202 return true, value 2203 end 2204 return false 2205 end 2206 2207 local flatten_explist = flatten_or_mark"explist" 2208 local function format_assign(lhs_exps, assign) 2209 if not assign then 2210 return flatten_explist(lhs_exps) 2211 end 2212 2213 for _, assign_exp in ipairs(lhs_exps) do 2214 if not is_assignable(assign_exp) then 2215 error {assign_exp, "left hand expression is not assignable"} 2216 end 2217 end 2218 2219 local t = ntype(assign) 2220 if t == "assign" then 2221 return {"assign", lhs_exps, unpack(assign, 2)} 2222 elseif t == "update" then 2223 return {"update", lhs_exps[1], unpack(assign, 2)} 2224 end 2225 2226 error "unknown assign expression" 2227 end 2228 2229 -- the if statement only takes a single lhs, so we wrap in table to git to 2230 -- "assign" tuple format 2231 local function format_single_assign(lhs, assign) 2232 if assign then 2233 return format_assign({lhs}, assign) 2234 end 2235 return lhs 2236 end 2237 2238 local function sym(chars) 2239 return Space * chars 2240 end 2241 2242 local function symx(chars) 2243 return chars 2244 end 2245 2246 local function simple_string(delim, allow_interpolation) 2247 local inner = P('\\'..delim) + "\\\\" + (1 - P(delim)) 2248 if allow_interpolation then 2249 inter = symx"#{" * V"Exp" * sym"}" 2250 inner = (C((inner - inter)^1) + inter / mark"interpolate")^0 2251 else 2252 inner = C(inner^0) 2253 end 2254 2255 return C(symx(delim)) * 2256 inner * sym(delim) / mark"string" 2257 end 2258 2259 local function wrap_func_arg(value) 2260 return {"call", {value}} 2261 end 2262 2263 -- DOCME 2264 local function flatten_func(callee, args) 2265 if #args == 0 then return callee end 2266 2267 args = {"call", args} 2268 if ntype(callee) == "chain" then 2269 -- check for colon stub that needs arguments 2270 if ntype(callee[#callee]) == "colon_stub" then 2271 local stub = callee[#callee] 2272 stub[1] = "colon" 2273 table.insert(stub, args) 2274 else 2275 table.insert(callee, args) 2276 end 2277 2278 return callee 2279 end 2280 2281 return {"chain", callee, args} 2282 end 2283 2284 local function flatten_string_chain(str, chain, args) 2285 if not chain then return str end 2286 return flatten_func({"chain", str, unpack(chain)}, args) 2287 end 2288 2289 -- transforms a statement that has a line decorator 2290 local function wrap_decorator(stm, dec) 2291 if not dec then return stm end 2292 return { "decorated", stm, dec } 2293 end 2294 2295 -- wrap if statement if there is a conditional decorator 2296 local function wrap_if(stm, cond) 2297 if cond then 2298 local pass, fail = unpack(cond) 2299 if fail then fail = {"else", {fail}} end 2300 return {"if", cond[2], {stm}, fail} 2301 end 2302 return stm 2303 end 2304 2305 local function check_lua_string(str, pos, right, left) 2306 return #left == #right 2307 end 2308 2309 -- :name in table literal 2310 local function self_assign(name) 2311 return {{"key_literal", name}, name} 2312 end 2313 2314 local err_msg = "Failed to parse:%s\n [%d] >> %s" 2315 2316 local build_grammar = wrap_env(function() 2317 local _indent = Stack(0) -- current indent 2318 local _do_stack = Stack(0) 2319 2320 local last_pos = 0 -- used to know where to report error 2321 local function check_indent(str, pos, indent) 2322 last_pos = pos 2323 return _indent:top() == indent 2324 end 2325 2326 local function advance_indent(str, pos, indent) 2327 local top = _indent:top() 2328 if top ~= -1 and indent > _indent:top() then 2329 _indent:push(indent) 2330 return true 2331 end 2332 end 2333 2334 local function push_indent(str, pos, indent) 2335 _indent:push(indent) 2336 return true 2337 end 2338 2339 local function pop_indent(str, pos) 2340 if not _indent:pop() then error("unexpected outdent") end 2341 return true 2342 end 2343 2344 2345 local function check_do(str, pos, do_node) 2346 local top = _do_stack:top() 2347 if top == nil or top then 2348 return true, do_node 2349 end 2350 return false 2351 end 2352 2353 local function disable_do(str_pos) 2354 _do_stack:push(false) 2355 return true 2356 end 2357 2358 local function enable_do(str_pos) 2359 _do_stack:push(true) 2360 return true 2361 end 2362 2363 local function pop_do(str, pos) 2364 if nil == _do_stack:pop() then error("unexpected do pop") end 2365 return true 2366 end 2367 2368 local DisableDo = Cmt("", disable_do) 2369 local EnableDo = Cmt("", enable_do) 2370 local PopDo = Cmt("", pop_do) 2371 2372 local keywords = {} 2373 local function key(chars) 2374 keywords[chars] = true 2375 return Space * chars * -AlphaNum 2376 end 2377 2378 local function op(word) 2379 local patt = Space * C(word) 2380 if word:match("^%w*$") then 2381 keywords[word] = true 2382 patt = patt * -AlphaNum 2383 end 2384 return patt 2385 end 2386 2387 -- make sure name is not a keyword 2388 local Name = Cmt(Name, function(str, pos, name) 2389 if keywords[name] then return false end 2390 return true 2391 end) / trim 2392 2393 local SelfName = Space * "@" * ( 2394 "@" * (_Name / mark"self_class" + Cc"self.__class") + 2395 _Name / mark"self" + Cc"self") 2396 2397 local KeyName = SelfName + Space * _Name / mark"key_literal" 2398 local VarArg = Space * P"..." / trim 2399 2400 local g = lpeg.P{ 2401 File, 2402 File = Shebang^-1 * (Block + Ct""), 2403 Block = Ct(Line * (Break^1 * Line)^0), 2404 CheckIndent = Cmt(Indent, check_indent), -- validates line is in correct indent 2405 Line = (CheckIndent * Statement + Space * #Stop), 2406 2407 Statement = pos( 2408 Import + While + With + For + ForEach + Switch + Return + 2409 Local + Export + BreakLoop + 2410 Ct(ExpList) * (Update + Assign)^-1 / format_assign 2411 ) * Space * (( 2412 -- statement decorators 2413 key"if" * Exp * (key"else" * Exp)^-1 * Space / mark"if" + 2414 key"unless" * Exp / mark"unless" + 2415 CompInner / mark"comprehension" 2416 ) * Space)^-1 / wrap_decorator, 2417 2418 Body = Space^-1 * Break * EmptyLine^0 * InBlock + Ct(Statement), -- either a statement, or an indented block 2419 2420 Advance = #Cmt(Indent, advance_indent), -- Advances the indent, gives back whitespace for CheckIndent 2421 PushIndent = Cmt(Indent, push_indent), 2422 PreventIndent = Cmt(Cc(-1), push_indent), 2423 PopIndent = Cmt("", pop_indent), 2424 InBlock = Advance * Block * PopIndent, 2425 2426 Local = key"local" * ((op"*" + op"^") / mark"declare_glob" + Ct(NameList) / mark"declare_with_shadows"), 2427 2428 Import = key"import" * Ct(ImportNameList) * SpaceBreak^0 * key"from" * Exp / mark"import", 2429 ImportName = (sym"\\" * Ct(Cc"colon_stub" * Name) + Name), 2430 ImportNameList = SpaceBreak^0 * ImportName * ((SpaceBreak^1 + sym"," * SpaceBreak^0) * ImportName)^0, 2431 2432 BreakLoop = Ct(key"break"/trim) + Ct(key"continue"/trim), 2433 2434 Return = key"return" * (ExpListLow/mark"explist" + C"") / mark"return", 2435 2436 WithExp = Ct(ExpList) * Assign^-1 / format_assign, 2437 With = key"with" * DisableDo * ensure(WithExp, PopDo) * key"do"^-1 * Body / mark"with", 2438 2439 Switch = key"switch" * DisableDo * ensure(Exp, PopDo) * key"do"^-1 * Space^-1 * Break * SwitchBlock / mark"switch", 2440 2441 SwitchBlock = EmptyLine^0 * Advance * Ct(SwitchCase * (Break^1 * SwitchCase)^0 * (Break^1 * SwitchElse)^-1) * PopIndent, 2442 SwitchCase = key"when" * Ct(ExpList) * key"then"^-1 * Body / mark"case", 2443 SwitchElse = key"else" * Body / mark"else", 2444 2445 IfCond = Exp * Assign^-1 / format_single_assign, 2446 2447 If = key"if" * IfCond * key"then"^-1 * Body * 2448 ((Break * CheckIndent)^-1 * EmptyLine^0 * key"elseif" * pos(IfCond) * key"then"^-1 * Body / mark"elseif")^0 * 2449 ((Break * CheckIndent)^-1 * EmptyLine^0 * key"else" * Body / mark"else")^-1 / mark"if", 2450 2451 Unless = key"unless" * IfCond * key"then"^-1 * Body * 2452 ((Break * CheckIndent)^-1 * EmptyLine^0 * key"else" * Body / mark"else")^-1 / mark"unless", 2453 2454 While = key"while" * DisableDo * ensure(Exp, PopDo) * key"do"^-1 * Body / mark"while", 2455 2456 For = key"for" * DisableDo * ensure(Name * sym"=" * Ct(Exp * sym"," * Exp * (sym"," * Exp)^-1), PopDo) * 2457 key"do"^-1 * Body / mark"for", 2458 2459 ForEach = key"for" * Ct(AssignableNameList) * key"in" * DisableDo * ensure(Ct(sym"*" * Exp / mark"unpack" + ExpList), PopDo) * key"do"^-1 * Body / mark"foreach", 2460 2461 Do = key"do" * Body / mark"do", 2462 2463 Comprehension = sym"[" * Exp * CompInner * sym"]" / mark"comprehension", 2464 2465 TblComprehension = sym"{" * Ct(Exp * (sym"," * Exp)^-1) * CompInner * sym"}" / mark"tblcomprehension", 2466 2467 CompInner = Ct((CompForEach + CompFor) * CompClause^0), 2468 CompForEach = key"for" * Ct(NameList) * key"in" * (sym"*" * Exp / mark"unpack" + Exp) / mark"foreach", 2469 CompFor = key "for" * Name * sym"=" * Ct(Exp * sym"," * Exp * (sym"," * Exp)^-1) / mark"for", 2470 CompClause = CompFor + CompForEach + key"when" * Exp / mark"when", 2471 2472 Assign = sym"=" * (Ct(With + If + Switch) + Ct(TableBlock + ExpListLow)) / mark"assign", 2473 Update = ((sym"..=" + sym"+=" + sym"-=" + sym"*=" + sym"/=" + sym"%=" + sym"or=" + sym"and=") / trim) * Exp / mark"update", 2474 2475 -- we can ignore precedence for now 2476 OtherOps = op"or" + op"and" + op"<=" + op">=" + op"~=" + op"!=" + op"==" + op".." + op"<" + op">", 2477 2478 Assignable = Cmt(DotChain + Chain, check_assignable) + Name + SelfName, 2479 2480 Exp = Ct(Value * ((OtherOps + FactorOp + TermOp) * Value)^0) / flatten_or_mark"exp", 2481 2482 -- Exp = Ct(Factor * (OtherOps * Factor)^0) / flatten_or_mark"exp", 2483 -- Factor = Ct(Term * (FactorOp * Term)^0) / flatten_or_mark"exp", 2484 -- Term = Ct(Value * (TermOp * Value)^0) / flatten_or_mark"exp", 2485 2486 SimpleValue = 2487 If + Unless + 2488 Switch + 2489 With + 2490 ClassDecl + 2491 ForEach + For + While + 2492 Cmt(Do, check_do) + 2493 sym"-" * -SomeSpace * Exp / mark"minus" + 2494 sym"#" * Exp / mark"length" + 2495 key"not" * Exp / mark"not" + 2496 TblComprehension + 2497 TableLit + 2498 Comprehension + 2499 FunLit + 2500 Num, 2501 2502 ChainValue = -- a function call or an object access 2503 StringChain + 2504 ((Chain + DotChain + Callable) * Ct(InvokeArgs^-1)) / flatten_func, 2505 2506 Value = pos( 2507 SimpleValue + 2508 Ct(KeyValueList) / mark"table" + 2509 ChainValue), 2510 2511 SliceValue = SimpleValue + ChainValue, 2512 2513 StringChain = String * 2514 (Ct((ColonCall + ColonSuffix) * ChainTail^-1) * Ct(InvokeArgs^-1))^-1 / flatten_string_chain, 2515 2516 String = Space * DoubleString + Space * SingleString + LuaString, 2517 SingleString = simple_string("'"), 2518 DoubleString = simple_string('"', true), 2519 2520 LuaString = Cg(LuaStringOpen, "string_open") * Cb"string_open" * Break^-1 * 2521 C((1 - Cmt(C(LuaStringClose) * Cb"string_open", check_lua_string))^0) * 2522 LuaStringClose / mark"string", 2523 2524 LuaStringOpen = sym"[" * P"="^0 * "[" / trim, 2525 LuaStringClose = "]" * P"="^0 * "]", 2526 2527 Callable = pos(Name / mark"ref") + SelfName + VarArg + Parens / mark"parens", 2528 Parens = sym"(" * Exp * sym")", 2529 2530 FnArgs = symx"(" * Ct(ExpList^-1) * sym")" + sym"!" * -P"=" * Ct"", 2531 2532 ChainTail = ChainItem^1 * ColonSuffix^-1 + ColonSuffix, 2533 2534 -- a list of funcalls and indexes on a callable 2535 Chain = Callable * ChainTail / mark"chain", 2536 2537 -- shorthand dot call for use in with statement 2538 DotChain = 2539 (sym"." * Cc(-1) * (_Name / mark"dot") * ChainTail^-1) / mark"chain" + 2540 (sym"\\" * Cc(-1) * ( 2541 (_Name * Invoke / mark"colon") * ChainTail^-1 + 2542 (_Name / mark"colon_stub") 2543 )) / mark"chain", 2544 2545 ChainItem = 2546 Invoke + 2547 Slice + 2548 symx"[" * Exp/mark"index" * sym"]" + 2549 symx"." * _Name/mark"dot" + 2550 ColonCall, 2551 2552 Slice = symx"[" * (SliceValue + Cc(1)) * sym"," * (SliceValue + Cc"") * 2553 (sym"," * SliceValue)^-1 *sym"]" / mark"slice", 2554 2555 ColonCall = symx"\\" * (_Name * Invoke) / mark"colon", 2556 ColonSuffix = symx"\\" * _Name / mark"colon_stub", 2557 2558 Invoke = FnArgs/mark"call" + 2559 SingleString / wrap_func_arg + 2560 DoubleString / wrap_func_arg, 2561 2562 TableValue = KeyValue + Ct(Exp), 2563 2564 TableLit = sym"{" * Ct( 2565 TableValueList^-1 * sym","^-1 * 2566 (SpaceBreak * TableLitLine * (sym","^-1 * SpaceBreak * TableLitLine)^0 * sym","^-1)^-1 2567 ) * White * sym"}" / mark"table", 2568 2569 TableValueList = TableValue * (sym"," * TableValue)^0, 2570 TableLitLine = PushIndent * ((TableValueList * PopIndent) + (PopIndent * Cut)) + Space, 2571 2572 -- the unbounded table 2573 TableBlockInner = Ct(KeyValueLine * (SpaceBreak^1 * KeyValueLine)^0), 2574 TableBlock = SpaceBreak^1 * Advance * ensure(TableBlockInner, PopIndent) / mark"table", 2575 2576 ClassDecl = key"class" * -P":" * (Assignable + Cc(nil)) * (key"extends" * PreventIndent * ensure(Exp, PopIndent) + C"")^-1 * (ClassBlock + Ct("")) / mark"class", 2577 2578 ClassBlock = SpaceBreak^1 * Advance * 2579 Ct(ClassLine * (SpaceBreak^1 * ClassLine)^0) * PopIndent, 2580 ClassLine = CheckIndent * (( 2581 KeyValueList / mark"props" + 2582 Statement / mark"stm" + 2583 Exp / mark"stm" 2584 ) * sym","^-1), 2585 2586 Export = key"export" * ( 2587 Cc"class" * ClassDecl + 2588 op"*" + op"^" + 2589 Ct(NameList) * (sym"=" * Ct(ExpListLow))^-1) / mark"export", 2590 2591 KeyValue = (sym":" * -SomeSpace * Name) / self_assign + Ct((KeyName + sym"[" * Exp * sym"]" + DoubleString + SingleString) * symx":" * (Exp + TableBlock)), 2592 KeyValueList = KeyValue * (sym"," * KeyValue)^0, 2593 KeyValueLine = CheckIndent * KeyValueList * sym","^-1, 2594 2595 FnArgsDef = sym"(" * Ct(FnArgDefList^-1) * 2596 (key"using" * Ct(NameList + Space * "nil") + Ct"") * 2597 sym")" + Ct"" * Ct"", 2598 2599 FnArgDefList = FnArgDef * (sym"," * FnArgDef)^0 * (sym"," * Ct(VarArg))^0 + Ct(VarArg), 2600 FnArgDef = Ct((Name + SelfName) * (sym"=" * Exp)^-1), 2601 2602 FunLit = FnArgsDef * 2603 (sym"->" * Cc"slim" + sym"=>" * Cc"fat") * 2604 (Body + Ct"") / mark"fndef", 2605 2606 NameList = Name * (sym"," * Name)^0, 2607 NameOrDestructure = Name + TableLit, 2608 AssignableNameList = NameOrDestructure * (sym"," * NameOrDestructure)^0, 2609 2610 ExpList = Exp * (sym"," * Exp)^0, 2611 ExpListLow = Exp * ((sym"," + sym";") * Exp)^0, 2612 2613 InvokeArgs = -P"-" * (ExpList * (sym"," * (TableBlock + SpaceBreak * Advance * ArgBlock * TableBlock^-1) + TableBlock)^-1 + TableBlock), 2614 ArgBlock = ArgLine * (sym"," * SpaceBreak * ArgLine)^0 * PopIndent, 2615 ArgLine = CheckIndent * ExpList 2616 } 2617 2618 return { 2619 _g = White * g * White * -1, 2620 match = function(self, str, ...) 2621 2622 local pos_to_line = function(pos) 2623 return util.pos_to_line(str, pos) 2624 end 2625 2626 local get_line = function(num) 2627 return util.get_line(str, num) 2628 end 2629 2630 local tree 2631 local parse_args = {...} 2632 2633 local pass, err = xpcall(function() 2634 tree = self._g:match(str, unpack(parse_args)) 2635 end, function(err) 2636 return debug.traceback(err, 2) 2637 end) 2638 2639 -- regular error, let it bubble up 2640 if type(err) == "string" then 2641 return nil, err 2642 end 2643 2644 if not tree then 2645 local pos = last_pos 2646 local msg 2647 2648 if err then 2649 local node 2650 node, msg = unpack(err) 2651 msg = msg and " " .. msg 2652 pos = node[-1] 2653 end 2654 2655 local line_no = pos_to_line(pos) 2656 local line_str = get_line(line_no) or "" 2657 2658 return nil, err_msg:format(msg or "", line_no, trim(line_str)) 2659 end 2660 return tree 2661 end 2662 } 2663 end) 2664 2665 return { 2666 extract_line = extract_line, 2667 2668 -- parse a string 2669 -- returns tree, or nil and error message 2670 string = function (str) 2671 local g = build_grammar() 2672 return g:match(str) 2673 end 2674 } 2675 2676 2677end 2678package.preload['moonscript.transform.destructure'] = function() 2679 local ntype, mtype, build 2680 do 2681 local _obj_0 = require("moonscript.types") 2682 ntype, mtype, build = _obj_0.ntype, _obj_0.mtype, _obj_0.build 2683 end 2684 local NameProxy 2685 do 2686 local _obj_0 = require("moonscript.transform.names") 2687 NameProxy = _obj_0.NameProxy 2688 end 2689 local insert 2690 do 2691 local _obj_0 = table 2692 insert = _obj_0.insert 2693 end 2694 local unpack 2695 do 2696 local _obj_0 = require("moonscript.util") 2697 unpack = _obj_0.unpack 2698 end 2699 local user_error 2700 do 2701 local _obj_0 = require("moonscript.errors") 2702 user_error = _obj_0.user_error 2703 end 2704 local util = require("moonscript.util") 2705 local join 2706 join = function(...) 2707 do 2708 local out = { } 2709 local i = 1 2710 local _list_0 = { 2711 ... 2712 } 2713 for _index_0 = 1, #_list_0 do 2714 local tbl = _list_0[_index_0] 2715 for _index_1 = 1, #tbl do 2716 local v = tbl[_index_1] 2717 out[i] = v 2718 i = i + 1 2719 end 2720 end 2721 return out 2722 end 2723 end 2724 local has_destructure 2725 has_destructure = function(names) 2726 for _index_0 = 1, #names do 2727 local n = names[_index_0] 2728 if ntype(n) == "table" then 2729 return true 2730 end 2731 end 2732 return false 2733 end 2734 local extract_assign_names 2735 extract_assign_names = function(name, accum, prefix) 2736 if accum == nil then 2737 accum = { } 2738 end 2739 if prefix == nil then 2740 prefix = { } 2741 end 2742 local i = 1 2743 local _list_0 = name[2] 2744 for _index_0 = 1, #_list_0 do 2745 local tuple = _list_0[_index_0] 2746 local value, suffix 2747 if #tuple == 1 then 2748 local s = { 2749 "index", 2750 { 2751 "number", 2752 i 2753 } 2754 } 2755 i = i + 1 2756 value, suffix = tuple[1], s 2757 else 2758 local key = tuple[1] 2759 local s 2760 if ntype(key) == "key_literal" then 2761 local key_name = key[2] 2762 if ntype(key_name) == "colon_stub" then 2763 s = key_name 2764 else 2765 s = { 2766 "dot", 2767 key_name 2768 } 2769 end 2770 else 2771 s = { 2772 "index", 2773 key 2774 } 2775 end 2776 value, suffix = tuple[2], s 2777 end 2778 suffix = join(prefix, { 2779 suffix 2780 }) 2781 local _exp_0 = ntype(value) 2782 if "value" == _exp_0 or "ref" == _exp_0 or "chain" == _exp_0 or "self" == _exp_0 then 2783 insert(accum, { 2784 value, 2785 suffix 2786 }) 2787 elseif "table" == _exp_0 then 2788 extract_assign_names(value, accum, suffix) 2789 else 2790 user_error("Can't destructure value of type: " .. tostring(ntype(value))) 2791 end 2792 end 2793 return accum 2794 end 2795 local build_assign 2796 build_assign = function(scope, destruct_literal, receiver) 2797 local extracted_names = extract_assign_names(destruct_literal) 2798 local names = { } 2799 local values = { } 2800 local inner = { 2801 "assign", 2802 names, 2803 values 2804 } 2805 local obj 2806 if scope:is_local(receiver) then 2807 obj = receiver 2808 else 2809 do 2810 obj = NameProxy("obj") 2811 inner = build["do"]({ 2812 build.assign_one(obj, receiver), 2813 { 2814 "assign", 2815 names, 2816 values 2817 } 2818 }) 2819 obj = obj 2820 end 2821 end 2822 for _index_0 = 1, #extracted_names do 2823 local tuple = extracted_names[_index_0] 2824 insert(names, tuple[1]) 2825 insert(values, NameProxy.chain(obj, unpack(tuple[2]))) 2826 end 2827 return build.group({ 2828 { 2829 "declare", 2830 names 2831 }, 2832 inner 2833 }) 2834 end 2835 local split_assign 2836 split_assign = function(scope, assign) 2837 local names, values = unpack(assign, 2) 2838 local g = { } 2839 local total_names = #names 2840 local total_values = #values 2841 local start = 1 2842 for i, n in ipairs(names) do 2843 if ntype(n) == "table" then 2844 if i > start then 2845 local stop = i - 1 2846 insert(g, { 2847 "assign", 2848 (function() 2849 local _accum_0 = { } 2850 local _len_0 = 1 2851 for i = start, stop do 2852 _accum_0[_len_0] = names[i] 2853 _len_0 = _len_0 + 1 2854 end 2855 return _accum_0 2856 end)(), 2857 (function() 2858 local _accum_0 = { } 2859 local _len_0 = 1 2860 for i = start, stop do 2861 _accum_0[_len_0] = values[i] 2862 _len_0 = _len_0 + 1 2863 end 2864 return _accum_0 2865 end)() 2866 }) 2867 end 2868 insert(g, build_assign(scope, n, values[i])) 2869 start = i + 1 2870 end 2871 end 2872 if total_names >= start or total_values >= start then 2873 local name_slice 2874 if total_names < start then 2875 name_slice = { 2876 "_" 2877 } 2878 else 2879 do 2880 local _accum_0 = { } 2881 local _len_0 = 1 2882 for i = start, total_names do 2883 _accum_0[_len_0] = names[i] 2884 _len_0 = _len_0 + 1 2885 end 2886 name_slice = _accum_0 2887 end 2888 end 2889 local value_slice 2890 if total_values < start then 2891 value_slice = { 2892 "nil" 2893 } 2894 else 2895 do 2896 local _accum_0 = { } 2897 local _len_0 = 1 2898 for i = start, total_values do 2899 _accum_0[_len_0] = values[i] 2900 _len_0 = _len_0 + 1 2901 end 2902 value_slice = _accum_0 2903 end 2904 end 2905 insert(g, { 2906 "assign", 2907 name_slice, 2908 value_slice 2909 }) 2910 end 2911 return build.group(g) 2912 end 2913 return { 2914 has_destructure = has_destructure, 2915 split_assign = split_assign, 2916 build_assign = build_assign 2917 } 2918 2919end 2920package.preload['moonscript.transform.names'] = function() 2921 local build 2922 do 2923 local _obj_0 = require("moonscript.types") 2924 build = _obj_0.build 2925 end 2926 local unpack 2927 do 2928 local _obj_0 = require("moonscript.util") 2929 unpack = _obj_0.unpack 2930 end 2931 local LocalName 2932 do 2933 local _base_0 = { 2934 get_name = function(self) 2935 return self.name 2936 end 2937 } 2938 _base_0.__index = _base_0 2939 local _class_0 = setmetatable({ 2940 __init = function(self, name) 2941 self.name = name 2942 self[1] = "temp_name" 2943 end, 2944 __base = _base_0, 2945 __name = "LocalName" 2946 }, { 2947 __index = _base_0, 2948 __call = function(cls, ...) 2949 local _self_0 = setmetatable({}, _base_0) 2950 cls.__init(_self_0, ...) 2951 return _self_0 2952 end 2953 }) 2954 _base_0.__class = _class_0 2955 LocalName = _class_0 2956 end 2957 local NameProxy 2958 do 2959 local _base_0 = { 2960 get_name = function(self, scope, dont_put) 2961 if dont_put == nil then 2962 dont_put = true 2963 end 2964 if not self.name then 2965 self.name = scope:free_name(self.prefix, dont_put) 2966 end 2967 return self.name 2968 end, 2969 chain = function(self, ...) 2970 local items = { 2971 base = self, 2972 ... 2973 } 2974 for k, v in ipairs(items) do 2975 if type(v) == "string" then 2976 items[k] = { 2977 "dot", 2978 v 2979 } 2980 else 2981 items[k] = v 2982 end 2983 end 2984 return build.chain(items) 2985 end, 2986 index = function(self, key) 2987 if type(key) == "string" then 2988 key = { 2989 "ref", 2990 key 2991 } 2992 end 2993 return build.chain({ 2994 base = self, 2995 { 2996 "index", 2997 key 2998 } 2999 }) 3000 end, 3001 __tostring = function(self) 3002 if self.name then 3003 return ("name<%s>"):format(self.name) 3004 else 3005 return ("name<prefix(%s)>"):format(self.prefix) 3006 end 3007 end 3008 } 3009 _base_0.__index = _base_0 3010 local _class_0 = setmetatable({ 3011 __init = function(self, prefix) 3012 self.prefix = prefix 3013 self[1] = "temp_name" 3014 end, 3015 __base = _base_0, 3016 __name = "NameProxy" 3017 }, { 3018 __index = _base_0, 3019 __call = function(cls, ...) 3020 local _self_0 = setmetatable({}, _base_0) 3021 cls.__init(_self_0, ...) 3022 return _self_0 3023 end 3024 }) 3025 _base_0.__class = _class_0 3026 NameProxy = _class_0 3027 end 3028 return { 3029 NameProxy = NameProxy, 3030 LocalName = LocalName 3031 } 3032 3033end 3034package.preload['moonscript.transform'] = function() 3035 local types = require("moonscript.types") 3036 local util = require("moonscript.util") 3037 local data = require("moonscript.data") 3038 local reversed, unpack 3039 reversed, unpack = util.reversed, util.unpack 3040 local ntype, mtype, build, smart_node, is_slice, value_is_singular 3041 ntype, mtype, build, smart_node, is_slice, value_is_singular = types.ntype, types.mtype, types.build, types.smart_node, types.is_slice, types.value_is_singular 3042 local insert 3043 do 3044 local _obj_0 = table 3045 insert = _obj_0.insert 3046 end 3047 local NameProxy, LocalName 3048 do 3049 local _obj_0 = require("moonscript.transform.names") 3050 NameProxy, LocalName = _obj_0.NameProxy, _obj_0.LocalName 3051 end 3052 local destructure = require("moonscript.transform.destructure") 3053 local NOOP = { 3054 "noop" 3055 } 3056 local Run, apply_to_last, is_singular, extract_declarations, expand_elseif_assign, constructor_name, with_continue_listener, Transformer, construct_comprehension, Statement, Accumulator, default_accumulator, implicitly_return, Value 3057 do 3058 local _base_0 = { 3059 call = function(self, state) 3060 return self.fn(state) 3061 end 3062 } 3063 _base_0.__index = _base_0 3064 local _class_0 = setmetatable({ 3065 __init = function(self, fn) 3066 self.fn = fn 3067 self[1] = "run" 3068 end, 3069 __base = _base_0, 3070 __name = "Run" 3071 }, { 3072 __index = _base_0, 3073 __call = function(cls, ...) 3074 local _self_0 = setmetatable({}, _base_0) 3075 cls.__init(_self_0, ...) 3076 return _self_0 3077 end 3078 }) 3079 _base_0.__class = _class_0 3080 Run = _class_0 3081 end 3082 apply_to_last = function(stms, fn) 3083 local last_exp_id = 0 3084 for i = #stms, 1, -1 do 3085 local stm = stms[i] 3086 if stm and mtype(stm) ~= Run then 3087 last_exp_id = i 3088 break 3089 end 3090 end 3091 return (function() 3092 local _accum_0 = { } 3093 local _len_0 = 1 3094 for i, stm in ipairs(stms) do 3095 if i == last_exp_id then 3096 _accum_0[_len_0] = { 3097 "transform", 3098 stm, 3099 fn 3100 } 3101 else 3102 _accum_0[_len_0] = stm 3103 end 3104 _len_0 = _len_0 + 1 3105 end 3106 return _accum_0 3107 end)() 3108 end 3109 is_singular = function(body) 3110 if #body ~= 1 then 3111 return false 3112 end 3113 if "group" == ntype(body) then 3114 return is_singular(body[2]) 3115 else 3116 return body[1] 3117 end 3118 end 3119 extract_declarations = function(self, body, start, out) 3120 if body == nil then 3121 body = self.current_stms 3122 end 3123 if start == nil then 3124 start = self.current_stm_i + 1 3125 end 3126 if out == nil then 3127 out = { } 3128 end 3129 for i = start, #body do 3130 local _continue_0 = false 3131 repeat 3132 local stm = body[i] 3133 if stm == nil then 3134 _continue_0 = true 3135 break 3136 end 3137 stm = self.transform.statement(stm) 3138 body[i] = stm 3139 local _exp_0 = stm[1] 3140 if "assign" == _exp_0 or "declare" == _exp_0 then 3141 local _list_0 = stm[2] 3142 for _index_0 = 1, #_list_0 do 3143 local name = _list_0[_index_0] 3144 if ntype(name) == "ref" then 3145 insert(out, name) 3146 elseif type(name) == "string" then 3147 insert(out, name) 3148 end 3149 end 3150 elseif "group" == _exp_0 then 3151 extract_declarations(self, stm[2], 1, out) 3152 end 3153 _continue_0 = true 3154 until true 3155 if not _continue_0 then 3156 break 3157 end 3158 end 3159 return out 3160 end 3161 expand_elseif_assign = function(ifstm) 3162 for i = 4, #ifstm do 3163 local case = ifstm[i] 3164 if ntype(case) == "elseif" and ntype(case[2]) == "assign" then 3165 local split = { 3166 unpack(ifstm, 1, i - 1) 3167 } 3168 insert(split, { 3169 "else", 3170 { 3171 { 3172 "if", 3173 case[2], 3174 case[3], 3175 unpack(ifstm, i + 1) 3176 } 3177 } 3178 }) 3179 return split 3180 end 3181 end 3182 return ifstm 3183 end 3184 constructor_name = "new" 3185 with_continue_listener = function(body) 3186 local continue_name = nil 3187 return { 3188 Run(function(self) 3189 return self:listen("continue", function() 3190 if not (continue_name) then 3191 continue_name = NameProxy("continue") 3192 self:put_name(continue_name) 3193 end 3194 return continue_name 3195 end) 3196 end), 3197 build.group(body), 3198 Run(function(self) 3199 if not (continue_name) then 3200 return 3201 end 3202 self:put_name(continue_name, nil) 3203 return self:splice(function(lines) 3204 return { 3205 { 3206 "assign", 3207 { 3208 continue_name 3209 }, 3210 { 3211 "false" 3212 } 3213 }, 3214 { 3215 "repeat", 3216 "true", 3217 { 3218 lines, 3219 { 3220 "assign", 3221 { 3222 continue_name 3223 }, 3224 { 3225 "true" 3226 } 3227 } 3228 } 3229 }, 3230 { 3231 "if", 3232 { 3233 "not", 3234 continue_name 3235 }, 3236 { 3237 { 3238 "break" 3239 } 3240 } 3241 } 3242 } 3243 end) 3244 end) 3245 } 3246 end 3247 do 3248 local _base_0 = { 3249 transform_once = function(self, scope, node, ...) 3250 if self.seen_nodes[node] then 3251 return node 3252 end 3253 self.seen_nodes[node] = true 3254 local transformer = self.transformers[ntype(node)] 3255 if transformer then 3256 return transformer(scope, node, ...) or node 3257 else 3258 return node 3259 end 3260 end, 3261 transform = function(self, scope, node, ...) 3262 if self.seen_nodes[node] then 3263 return node 3264 end 3265 self.seen_nodes[node] = true 3266 while true do 3267 local transformer = self.transformers[ntype(node)] 3268 local res 3269 if transformer then 3270 res = transformer(scope, node, ...) or node 3271 else 3272 res = node 3273 end 3274 if res == node then 3275 return node 3276 end 3277 node = res 3278 end 3279 return node 3280 end, 3281 bind = function(self, scope) 3282 return function(...) 3283 return self:transform(scope, ...) 3284 end 3285 end, 3286 __call = function(self, ...) 3287 return self:transform(...) 3288 end, 3289 can_transform = function(self, node) 3290 return self.transformers[ntype(node)] ~= nil 3291 end 3292 } 3293 _base_0.__index = _base_0 3294 local _class_0 = setmetatable({ 3295 __init = function(self, transformers) 3296 self.transformers = transformers 3297 self.seen_nodes = setmetatable({ }, { 3298 __mode = "k" 3299 }) 3300 end, 3301 __base = _base_0, 3302 __name = "Transformer" 3303 }, { 3304 __index = _base_0, 3305 __call = function(cls, ...) 3306 local _self_0 = setmetatable({}, _base_0) 3307 cls.__init(_self_0, ...) 3308 return _self_0 3309 end 3310 }) 3311 _base_0.__class = _class_0 3312 Transformer = _class_0 3313 end 3314 construct_comprehension = function(inner, clauses) 3315 local current_stms = inner 3316 for _, clause in reversed(clauses) do 3317 local t = clause[1] 3318 local _exp_0 = t 3319 if "for" == _exp_0 then 3320 local name, bounds 3321 _, name, bounds = clause[1], clause[2], clause[3] 3322 current_stms = { 3323 "for", 3324 name, 3325 bounds, 3326 current_stms 3327 } 3328 elseif "foreach" == _exp_0 then 3329 local names, iter 3330 _, names, iter = clause[1], clause[2], clause[3] 3331 current_stms = { 3332 "foreach", 3333 names, 3334 { 3335 iter 3336 }, 3337 current_stms 3338 } 3339 elseif "when" == _exp_0 then 3340 local cond 3341 _, cond = clause[1], clause[2] 3342 current_stms = { 3343 "if", 3344 cond, 3345 current_stms 3346 } 3347 else 3348 current_stms = error("Unknown comprehension clause: " .. t) 3349 end 3350 current_stms = { 3351 current_stms 3352 } 3353 end 3354 return current_stms[1] 3355 end 3356 Statement = Transformer({ 3357 transform = function(self, tuple) 3358 local _, node, fn 3359 _, node, fn = tuple[1], tuple[2], tuple[3] 3360 return fn(node) 3361 end, 3362 root_stms = function(self, body) 3363 return apply_to_last(body, implicitly_return(self)) 3364 end, 3365 ["return"] = function(self, node) 3366 local ret_val = node[2] 3367 local ret_val_type = ntype(ret_val) 3368 if ret_val_type == "explist" and #ret_val == 2 then 3369 ret_val = ret_val[2] 3370 ret_val_type = ntype(ret_val) 3371 end 3372 if types.cascading[ret_val_type] then 3373 return implicitly_return(self)(ret_val) 3374 end 3375 if ret_val_type == "chain" or ret_val_type == "comprehension" or ret_val_type == "tblcomprehension" then 3376 ret_val = Value:transform_once(self, ret_val) 3377 if ntype(ret_val) == "block_exp" then 3378 return build.group(apply_to_last(ret_val[2], function(stm) 3379 return { 3380 "return", 3381 stm 3382 } 3383 end)) 3384 end 3385 end 3386 node[2] = ret_val 3387 return node 3388 end, 3389 declare_glob = function(self, node) 3390 local names = extract_declarations(self) 3391 if node[2] == "^" then 3392 do 3393 local _accum_0 = { } 3394 local _len_0 = 1 3395 for _index_0 = 1, #names do 3396 local _continue_0 = false 3397 repeat 3398 local name = names[_index_0] 3399 if not (name[2]:match("^%u")) then 3400 _continue_0 = true 3401 break 3402 end 3403 local _value_0 = name 3404 _accum_0[_len_0] = _value_0 3405 _len_0 = _len_0 + 1 3406 _continue_0 = true 3407 until true 3408 if not _continue_0 then 3409 break 3410 end 3411 end 3412 names = _accum_0 3413 end 3414 end 3415 return { 3416 "declare", 3417 names 3418 } 3419 end, 3420 assign = function(self, node) 3421 local names, values = unpack(node, 2) 3422 local num_values = #values 3423 local num_names = #values 3424 if num_names == 1 and num_values == 1 then 3425 local first_value = values[1] 3426 local first_name = names[1] 3427 local first_type = ntype(first_value) 3428 if first_type == "chain" then 3429 first_value = Value:transform_once(self, first_value) 3430 first_type = ntype(first_value) 3431 end 3432 local _exp_0 = ntype(first_value) 3433 if "block_exp" == _exp_0 then 3434 local block_body = first_value[2] 3435 local idx = #block_body 3436 block_body[idx] = build.assign_one(first_name, block_body[idx]) 3437 return build.group({ 3438 { 3439 "declare", 3440 { 3441 first_name 3442 } 3443 }, 3444 { 3445 "do", 3446 block_body 3447 } 3448 }) 3449 elseif "comprehension" == _exp_0 or "tblcomprehension" == _exp_0 or "foreach" == _exp_0 or "for" == _exp_0 or "while" == _exp_0 then 3450 return build.assign_one(first_name, Value:transform_once(self, first_value)) 3451 else 3452 values[1] = first_value 3453 end 3454 end 3455 local transformed 3456 if num_values == 1 then 3457 local value = values[1] 3458 local t = ntype(value) 3459 if t == "decorated" then 3460 value = self.transform.statement(value) 3461 t = ntype(value) 3462 end 3463 if types.cascading[t] then 3464 local ret 3465 ret = function(stm) 3466 if types.is_value(stm) then 3467 return { 3468 "assign", 3469 names, 3470 { 3471 stm 3472 } 3473 } 3474 else 3475 return stm 3476 end 3477 end 3478 transformed = build.group({ 3479 { 3480 "declare", 3481 names 3482 }, 3483 self.transform.statement(value, ret, node) 3484 }) 3485 end 3486 end 3487 node = transformed or node 3488 if destructure.has_destructure(names) then 3489 return destructure.split_assign(self, node) 3490 end 3491 return node 3492 end, 3493 continue = function(self, node) 3494 local continue_name = self:send("continue") 3495 if not (continue_name) then 3496 error("continue must be inside of a loop") 3497 end 3498 return build.group({ 3499 build.assign_one(continue_name, "true"), 3500 { 3501 "break" 3502 } 3503 }) 3504 end, 3505 export = function(self, node) 3506 if #node > 2 then 3507 if node[2] == "class" then 3508 local cls = smart_node(node[3]) 3509 return build.group({ 3510 { 3511 "export", 3512 { 3513 cls.name 3514 } 3515 }, 3516 cls 3517 }) 3518 else 3519 return build.group({ 3520 { 3521 "export", 3522 node[2] 3523 }, 3524 build.assign({ 3525 names = node[2], 3526 values = node[3] 3527 }) 3528 }) 3529 end 3530 else 3531 return nil 3532 end 3533 end, 3534 update = function(self, node) 3535 local _, name, op, exp = unpack(node) 3536 local op_final = op:match("^(.+)=$") 3537 if not op_final then 3538 error("Unknown op: " .. op) 3539 end 3540 if not (value_is_singular(exp)) then 3541 exp = { 3542 "parens", 3543 exp 3544 } 3545 end 3546 return build.assign_one(name, { 3547 "exp", 3548 name, 3549 op_final, 3550 exp 3551 }) 3552 end, 3553 import = function(self, node) 3554 local _, names, source = unpack(node) 3555 local table_values 3556 do 3557 local _accum_0 = { } 3558 local _len_0 = 1 3559 for _index_0 = 1, #names do 3560 local name = names[_index_0] 3561 local dest_val 3562 if ntype(name) == "colon_stub" then 3563 dest_val = name[2] 3564 else 3565 dest_val = name 3566 end 3567 local _value_0 = { 3568 { 3569 "key_literal", 3570 name 3571 }, 3572 dest_val 3573 } 3574 _accum_0[_len_0] = _value_0 3575 _len_0 = _len_0 + 1 3576 end 3577 table_values = _accum_0 3578 end 3579 local dest = { 3580 "table", 3581 table_values 3582 } 3583 return { 3584 "assign", 3585 { 3586 dest 3587 }, 3588 { 3589 source 3590 }, 3591 [-1] = node[-1] 3592 } 3593 end, 3594 comprehension = function(self, node, action) 3595 local _, exp, clauses = unpack(node) 3596 action = action or function(exp) 3597 return { 3598 exp 3599 } 3600 end 3601 return construct_comprehension(action(exp), clauses) 3602 end, 3603 ["do"] = function(self, node, ret) 3604 if ret then 3605 node[2] = apply_to_last(node[2], ret) 3606 end 3607 return node 3608 end, 3609 decorated = function(self, node) 3610 local stm, dec = unpack(node, 2) 3611 local wrapped 3612 local _exp_0 = dec[1] 3613 if "if" == _exp_0 then 3614 local cond, fail = unpack(dec, 2) 3615 if fail then 3616 fail = { 3617 "else", 3618 { 3619 fail 3620 } 3621 } 3622 end 3623 wrapped = { 3624 "if", 3625 cond, 3626 { 3627 stm 3628 }, 3629 fail 3630 } 3631 elseif "unless" == _exp_0 then 3632 wrapped = { 3633 "unless", 3634 dec[2], 3635 { 3636 stm 3637 } 3638 } 3639 elseif "comprehension" == _exp_0 then 3640 wrapped = { 3641 "comprehension", 3642 stm, 3643 dec[2] 3644 } 3645 else 3646 wrapped = error("Unknown decorator " .. dec[1]) 3647 end 3648 if ntype(stm) == "assign" then 3649 wrapped = build.group({ 3650 build.declare({ 3651 names = (function() 3652 local _accum_0 = { } 3653 local _len_0 = 1 3654 local _list_0 = stm[2] 3655 for _index_0 = 1, #_list_0 do 3656 local name = _list_0[_index_0] 3657 if ntype(name) == "ref" then 3658 _accum_0[_len_0] = name 3659 _len_0 = _len_0 + 1 3660 end 3661 end 3662 return _accum_0 3663 end)() 3664 }), 3665 wrapped 3666 }) 3667 end 3668 return wrapped 3669 end, 3670 unless = function(self, node) 3671 return { 3672 "if", 3673 { 3674 "not", 3675 { 3676 "parens", 3677 node[2] 3678 } 3679 }, 3680 unpack(node, 3) 3681 } 3682 end, 3683 ["if"] = function(self, node, ret) 3684 if ntype(node[2]) == "assign" then 3685 local _, assign, body = unpack(node) 3686 if destructure.has_destructure(assign[2]) then 3687 local name = NameProxy("des") 3688 body = { 3689 destructure.build_assign(self, assign[2][1], name), 3690 build.group(node[3]) 3691 } 3692 return build["do"]({ 3693 build.assign_one(name, assign[3][1]), 3694 { 3695 "if", 3696 name, 3697 body, 3698 unpack(node, 4) 3699 } 3700 }) 3701 else 3702 local name = assign[2][1] 3703 return build["do"]({ 3704 assign, 3705 { 3706 "if", 3707 name, 3708 unpack(node, 3) 3709 } 3710 }) 3711 end 3712 end 3713 node = expand_elseif_assign(node) 3714 if ret then 3715 smart_node(node) 3716 node['then'] = apply_to_last(node['then'], ret) 3717 for i = 4, #node do 3718 local case = node[i] 3719 local body_idx = #node[i] 3720 case[body_idx] = apply_to_last(case[body_idx], ret) 3721 end 3722 end 3723 return node 3724 end, 3725 with = function(self, node, ret) 3726 local exp, block = unpack(node, 2) 3727 local copy_scope = true 3728 local scope_name, named_assign 3729 if ntype(exp) == "assign" then 3730 local names, values = unpack(exp, 2) 3731 local first_name = names[1] 3732 if ntype(first_name) == "ref" then 3733 scope_name = first_name 3734 named_assign = exp 3735 exp = values[1] 3736 copy_scope = false 3737 else 3738 scope_name = NameProxy("with") 3739 exp = values[1] 3740 values[1] = scope_name 3741 named_assign = { 3742 "assign", 3743 names, 3744 values 3745 } 3746 end 3747 elseif self:is_local(exp) then 3748 scope_name = exp 3749 copy_scope = false 3750 end 3751 scope_name = scope_name or NameProxy("with") 3752 return build["do"]({ 3753 Run(function(self) 3754 return self:set("scope_var", scope_name) 3755 end), 3756 copy_scope and build.assign_one(scope_name, exp) or NOOP, 3757 named_assign or NOOP, 3758 build.group(block), 3759 (function() 3760 if ret then 3761 return ret(scope_name) 3762 end 3763 end)() 3764 }) 3765 end, 3766 foreach = function(self, node, _) 3767 smart_node(node) 3768 local source = unpack(node.iter) 3769 local destructures = { } 3770 do 3771 local _accum_0 = { } 3772 local _len_0 = 1 3773 for i, name in ipairs(node.names) do 3774 if ntype(name) == "table" then 3775 do 3776 local proxy = NameProxy("des") 3777 insert(destructures, destructure.build_assign(self, name, proxy)) 3778 _accum_0[_len_0] = proxy 3779 end 3780 else 3781 _accum_0[_len_0] = name 3782 end 3783 _len_0 = _len_0 + 1 3784 end 3785 node.names = _accum_0 3786 end 3787 if next(destructures) then 3788 insert(destructures, build.group(node.body)) 3789 node.body = destructures 3790 end 3791 if ntype(source) == "unpack" then 3792 local list = source[2] 3793 local index_name = NameProxy("index") 3794 local list_name = self:is_local(list) and list or NameProxy("list") 3795 local slice_var = nil 3796 local bounds 3797 if is_slice(list) then 3798 local slice = list[#list] 3799 table.remove(list) 3800 table.remove(slice, 1) 3801 if self:is_local(list) then 3802 list_name = list 3803 end 3804 if slice[2] and slice[2] ~= "" then 3805 local max_tmp_name = NameProxy("max") 3806 slice_var = build.assign_one(max_tmp_name, slice[2]) 3807 slice[2] = { 3808 "exp", 3809 max_tmp_name, 3810 "<", 3811 0, 3812 "and", 3813 { 3814 "length", 3815 list_name 3816 }, 3817 "+", 3818 max_tmp_name, 3819 "or", 3820 max_tmp_name 3821 } 3822 else 3823 slice[2] = { 3824 "length", 3825 list_name 3826 } 3827 end 3828 bounds = slice 3829 else 3830 bounds = { 3831 1, 3832 { 3833 "length", 3834 list_name 3835 } 3836 } 3837 end 3838 return build.group({ 3839 list_name ~= list and build.assign_one(list_name, list) or NOOP, 3840 slice_var or NOOP, 3841 build["for"]({ 3842 name = index_name, 3843 bounds = bounds, 3844 body = { 3845 { 3846 "assign", 3847 node.names, 3848 { 3849 NameProxy.index(list_name, index_name) 3850 } 3851 }, 3852 build.group(node.body) 3853 } 3854 }) 3855 }) 3856 end 3857 node.body = with_continue_listener(node.body) 3858 end, 3859 ["while"] = function(self, node) 3860 smart_node(node) 3861 node.body = with_continue_listener(node.body) 3862 end, 3863 ["for"] = function(self, node) 3864 smart_node(node) 3865 node.body = with_continue_listener(node.body) 3866 end, 3867 switch = function(self, node, ret) 3868 local _, exp, conds = unpack(node) 3869 local exp_name = NameProxy("exp") 3870 local convert_cond 3871 convert_cond = function(cond) 3872 local t, case_exps, body = unpack(cond) 3873 local out = { } 3874 insert(out, t == "case" and "elseif" or "else") 3875 if t ~= "else" then 3876 local cond_exp = { } 3877 for i, case in ipairs(case_exps) do 3878 if i == 1 then 3879 insert(cond_exp, "exp") 3880 else 3881 insert(cond_exp, "or") 3882 end 3883 if not (value_is_singular(case)) then 3884 case = { 3885 "parens", 3886 case 3887 } 3888 end 3889 insert(cond_exp, { 3890 "exp", 3891 case, 3892 "==", 3893 exp_name 3894 }) 3895 end 3896 insert(out, cond_exp) 3897 else 3898 body = case_exps 3899 end 3900 if ret then 3901 body = apply_to_last(body, ret) 3902 end 3903 insert(out, body) 3904 return out 3905 end 3906 local first = true 3907 local if_stm = { 3908 "if" 3909 } 3910 for _index_0 = 1, #conds do 3911 local cond = conds[_index_0] 3912 local if_cond = convert_cond(cond) 3913 if first then 3914 first = false 3915 insert(if_stm, if_cond[2]) 3916 insert(if_stm, if_cond[3]) 3917 else 3918 insert(if_stm, if_cond) 3919 end 3920 end 3921 return build.group({ 3922 build.assign_one(exp_name, exp), 3923 if_stm 3924 }) 3925 end, 3926 class = function(self, node, ret, parent_assign) 3927 local _, name, parent_val, body = unpack(node) 3928 if parent_val == "" then 3929 parent_val = nil 3930 end 3931 local statements = { } 3932 local properties = { } 3933 for _index_0 = 1, #body do 3934 local item = body[_index_0] 3935 local _exp_0 = item[1] 3936 if "stm" == _exp_0 then 3937 insert(statements, item[2]) 3938 elseif "props" == _exp_0 then 3939 for _index_1 = 2, #item do 3940 local tuple = item[_index_1] 3941 if ntype(tuple[1]) == "self" then 3942 insert(statements, build.assign_one(unpack(tuple))) 3943 else 3944 insert(properties, tuple) 3945 end 3946 end 3947 end 3948 end 3949 local constructor 3950 do 3951 local _accum_0 = { } 3952 local _len_0 = 1 3953 for _index_0 = 1, #properties do 3954 local _continue_0 = false 3955 repeat 3956 local tuple = properties[_index_0] 3957 local key = tuple[1] 3958 local _value_0 3959 if key[1] == "key_literal" and key[2] == constructor_name then 3960 constructor = tuple[2] 3961 _continue_0 = true 3962 break 3963 else 3964 _value_0 = tuple 3965 end 3966 _accum_0[_len_0] = _value_0 3967 _len_0 = _len_0 + 1 3968 _continue_0 = true 3969 until true 3970 if not _continue_0 then 3971 break 3972 end 3973 end 3974 properties = _accum_0 3975 end 3976 local parent_cls_name = NameProxy("parent") 3977 local base_name = NameProxy("base") 3978 local self_name = NameProxy("self") 3979 local cls_name = NameProxy("class") 3980 if not (constructor) then 3981 if parent_val then 3982 constructor = build.fndef({ 3983 args = { 3984 { 3985 "..." 3986 } 3987 }, 3988 arrow = "fat", 3989 body = { 3990 build.chain({ 3991 base = "super", 3992 { 3993 "call", 3994 { 3995 "..." 3996 } 3997 } 3998 }) 3999 } 4000 }) 4001 else 4002 constructor = build.fndef() 4003 end 4004 end 4005 local real_name = name or parent_assign and parent_assign[2][1] 4006 local _exp_0 = ntype(real_name) 4007 if "chain" == _exp_0 then 4008 local last = real_name[#real_name] 4009 local _exp_1 = ntype(last) 4010 if "dot" == _exp_1 then 4011 real_name = { 4012 "string", 4013 '"', 4014 last[2] 4015 } 4016 elseif "index" == _exp_1 then 4017 real_name = last[2] 4018 else 4019 real_name = "nil" 4020 end 4021 elseif "nil" == _exp_0 then 4022 real_name = "nil" 4023 else 4024 local name_t = type(real_name) 4025 local flattened_name 4026 if name_t == "string" then 4027 flattened_name = real_name 4028 elseif name_t == "table" and real_name[1] == "ref" then 4029 flattened_name = real_name[2] 4030 else 4031 flattened_name = error("don't know how to extract name from " .. tostring(name_t)) 4032 end 4033 real_name = { 4034 "string", 4035 '"', 4036 flattened_name 4037 } 4038 end 4039 local cls = build.table({ 4040 { 4041 "__init", 4042 constructor 4043 }, 4044 { 4045 "__base", 4046 base_name 4047 }, 4048 { 4049 "__name", 4050 real_name 4051 }, 4052 parent_val and { 4053 "__parent", 4054 parent_cls_name 4055 } or nil 4056 }) 4057 local class_index 4058 if parent_val then 4059 local class_lookup = build["if"]({ 4060 cond = { 4061 "exp", 4062 { 4063 "ref", 4064 "val" 4065 }, 4066 "==", 4067 "nil" 4068 }, 4069 ["then"] = { 4070 parent_cls_name:index("name") 4071 } 4072 }) 4073 insert(class_lookup, { 4074 "else", 4075 { 4076 "val" 4077 } 4078 }) 4079 class_index = build.fndef({ 4080 args = { 4081 { 4082 "cls" 4083 }, 4084 { 4085 "name" 4086 } 4087 }, 4088 body = { 4089 build.assign_one(LocalName("val"), build.chain({ 4090 base = "rawget", 4091 { 4092 "call", 4093 { 4094 base_name, 4095 { 4096 "ref", 4097 "name" 4098 } 4099 } 4100 } 4101 })), 4102 class_lookup 4103 } 4104 }) 4105 else 4106 class_index = base_name 4107 end 4108 local cls_mt = build.table({ 4109 { 4110 "__index", 4111 class_index 4112 }, 4113 { 4114 "__call", 4115 build.fndef({ 4116 args = { 4117 { 4118 "cls" 4119 }, 4120 { 4121 "..." 4122 } 4123 }, 4124 body = { 4125 build.assign_one(self_name, build.chain({ 4126 base = "setmetatable", 4127 { 4128 "call", 4129 { 4130 "{}", 4131 base_name 4132 } 4133 } 4134 })), 4135 build.chain({ 4136 base = "cls.__init", 4137 { 4138 "call", 4139 { 4140 self_name, 4141 "..." 4142 } 4143 } 4144 }), 4145 self_name 4146 } 4147 }) 4148 } 4149 }) 4150 cls = build.chain({ 4151 base = "setmetatable", 4152 { 4153 "call", 4154 { 4155 cls, 4156 cls_mt 4157 } 4158 } 4159 }) 4160 local value = nil 4161 do 4162 local out_body = { 4163 Run(function(self) 4164 if name then 4165 self:put_name(name) 4166 end 4167 return self:set("super", function(block, chain) 4168 if chain then 4169 local slice 4170 do 4171 local _accum_0 = { } 4172 local _len_0 = 1 4173 for _index_0 = 3, #chain do 4174 local item = chain[_index_0] 4175 _accum_0[_len_0] = item 4176 _len_0 = _len_0 + 1 4177 end 4178 slice = _accum_0 4179 end 4180 local new_chain = { 4181 "chain", 4182 parent_cls_name 4183 } 4184 local head = slice[1] 4185 if head == nil then 4186 return parent_cls_name 4187 end 4188 local _exp_1 = head[1] 4189 if "call" == _exp_1 then 4190 local calling_name = block:get("current_block") 4191 slice[1] = { 4192 "call", 4193 { 4194 "self", 4195 unpack(head[2]) 4196 } 4197 } 4198 if ntype(calling_name) == "key_literal" then 4199 insert(new_chain, { 4200 "dot", 4201 calling_name[2] 4202 }) 4203 else 4204 insert(new_chain, { 4205 "index", 4206 calling_name 4207 }) 4208 end 4209 elseif "colon" == _exp_1 then 4210 local call = head[3] 4211 insert(new_chain, { 4212 "dot", 4213 head[2] 4214 }) 4215 slice[1] = { 4216 "call", 4217 { 4218 "self", 4219 unpack(call[2]) 4220 } 4221 } 4222 end 4223 for _index_0 = 1, #slice do 4224 local item = slice[_index_0] 4225 insert(new_chain, item) 4226 end 4227 return new_chain 4228 else 4229 return parent_cls_name 4230 end 4231 end) 4232 end), 4233 { 4234 "declare_glob", 4235 "*" 4236 }, 4237 parent_val and build.assign_one(parent_cls_name, parent_val) or NOOP, 4238 build.assign_one(base_name, { 4239 "table", 4240 properties 4241 }), 4242 build.assign_one(base_name:chain("__index"), base_name), 4243 parent_val and build.chain({ 4244 base = "setmetatable", 4245 { 4246 "call", 4247 { 4248 base_name, 4249 build.chain({ 4250 base = parent_cls_name, 4251 { 4252 "dot", 4253 "__base" 4254 } 4255 }) 4256 } 4257 } 4258 }) or NOOP, 4259 build.assign_one(cls_name, cls), 4260 build.assign_one(base_name:chain("__class"), cls_name), 4261 build.group((function() 4262 if #statements > 0 then 4263 return { 4264 build.assign_one(LocalName("self"), cls_name), 4265 build.group(statements) 4266 } 4267 end 4268 end)()), 4269 parent_val and build["if"]({ 4270 cond = { 4271 "exp", 4272 parent_cls_name:chain("__inherited") 4273 }, 4274 ["then"] = { 4275 parent_cls_name:chain("__inherited", { 4276 "call", 4277 { 4278 parent_cls_name, 4279 cls_name 4280 } 4281 }) 4282 } 4283 }) or NOOP, 4284 build.group((function() 4285 if name then 4286 return { 4287 build.assign_one(name, cls_name) 4288 } 4289 end 4290 end)()), 4291 (function() 4292 if ret then 4293 return ret(cls_name) 4294 end 4295 end)() 4296 } 4297 value = build.group({ 4298 build.group((function() 4299 if ntype(name) == "value" then 4300 return { 4301 build.declare({ 4302 names = { 4303 name 4304 } 4305 }) 4306 } 4307 end 4308 end)()), 4309 build["do"](out_body) 4310 }) 4311 end 4312 return value 4313 end 4314 }) 4315 do 4316 local _base_0 = { 4317 body_idx = { 4318 ["for"] = 4, 4319 ["while"] = 3, 4320 foreach = 4 4321 }, 4322 convert = function(self, node) 4323 local index = self.body_idx[ntype(node)] 4324 node[index] = self:mutate_body(node[index]) 4325 return self:wrap(node) 4326 end, 4327 wrap = function(self, node, group_type) 4328 if group_type == nil then 4329 group_type = "block_exp" 4330 end 4331 return build[group_type]({ 4332 build.assign_one(self.accum_name, build.table()), 4333 build.assign_one(self.len_name, 1), 4334 node, 4335 group_type == "block_exp" and self.accum_name or NOOP 4336 }) 4337 end, 4338 mutate_body = function(self, body) 4339 local single_stm = is_singular(body) 4340 local val 4341 if single_stm and types.is_value(single_stm) then 4342 body = { } 4343 val = single_stm 4344 else 4345 body = apply_to_last(body, function(n) 4346 if types.is_value(n) then 4347 return build.assign_one(self.value_name, n) 4348 else 4349 return build.group({ 4350 { 4351 "declare", 4352 { 4353 self.value_name 4354 } 4355 }, 4356 n 4357 }) 4358 end 4359 end) 4360 val = self.value_name 4361 end 4362 local update = { 4363 build.assign_one(NameProxy.index(self.accum_name, self.len_name), val), 4364 { 4365 "update", 4366 self.len_name, 4367 "+=", 4368 1 4369 } 4370 } 4371 insert(body, build.group(update)) 4372 return body 4373 end 4374 } 4375 _base_0.__index = _base_0 4376 local _class_0 = setmetatable({ 4377 __init = function(self, accum_name) 4378 self.accum_name = NameProxy("accum") 4379 self.value_name = NameProxy("value") 4380 self.len_name = NameProxy("len") 4381 end, 4382 __base = _base_0, 4383 __name = "Accumulator" 4384 }, { 4385 __index = _base_0, 4386 __call = function(cls, ...) 4387 local _self_0 = setmetatable({}, _base_0) 4388 cls.__init(_self_0, ...) 4389 return _self_0 4390 end 4391 }) 4392 _base_0.__class = _class_0 4393 Accumulator = _class_0 4394 end 4395 default_accumulator = function(self, node) 4396 return Accumulator():convert(node) 4397 end 4398 implicitly_return = function(scope) 4399 local is_top = true 4400 local fn 4401 fn = function(stm) 4402 local t = ntype(stm) 4403 if t == "decorated" then 4404 stm = scope.transform.statement(stm) 4405 t = ntype(stm) 4406 end 4407 if types.cascading[t] then 4408 is_top = false 4409 return scope.transform.statement(stm, fn) 4410 elseif types.manual_return[t] or not types.is_value(stm) then 4411 if is_top and t == "return" and stm[2] == "" then 4412 return NOOP 4413 else 4414 return stm 4415 end 4416 else 4417 if t == "comprehension" and not types.comprehension_has_value(stm) then 4418 return stm 4419 else 4420 return { 4421 "return", 4422 stm 4423 } 4424 end 4425 end 4426 end 4427 return fn 4428 end 4429 Value = Transformer({ 4430 ["for"] = default_accumulator, 4431 ["while"] = default_accumulator, 4432 foreach = default_accumulator, 4433 ["do"] = function(self, node) 4434 return build.block_exp(node[2]) 4435 end, 4436 decorated = function(self, node) 4437 return self.transform.statement(node) 4438 end, 4439 class = function(self, node) 4440 return build.block_exp({ 4441 node 4442 }) 4443 end, 4444 string = function(self, node) 4445 local delim = node[2] 4446 local convert_part 4447 convert_part = function(part) 4448 if type(part) == "string" or part == nil then 4449 return { 4450 "string", 4451 delim, 4452 part or "" 4453 } 4454 else 4455 return build.chain({ 4456 base = "tostring", 4457 { 4458 "call", 4459 { 4460 part[2] 4461 } 4462 } 4463 }) 4464 end 4465 end 4466 if #node <= 3 then 4467 if type(node[3]) == "string" then 4468 return node 4469 else 4470 return convert_part(node[3]) 4471 end 4472 end 4473 local e = { 4474 "exp", 4475 convert_part(node[3]) 4476 } 4477 for i = 4, #node do 4478 insert(e, "..") 4479 insert(e, convert_part(node[i])) 4480 end 4481 return e 4482 end, 4483 comprehension = function(self, node) 4484 local a = Accumulator() 4485 node = self.transform.statement(node, function(exp) 4486 return a:mutate_body({ 4487 exp 4488 }) 4489 end) 4490 return a:wrap(node) 4491 end, 4492 tblcomprehension = function(self, node) 4493 local _, explist, clauses = unpack(node) 4494 local key_exp, value_exp = unpack(explist) 4495 local accum = NameProxy("tbl") 4496 local inner 4497 if value_exp then 4498 local dest = build.chain({ 4499 base = accum, 4500 { 4501 "index", 4502 key_exp 4503 } 4504 }) 4505 inner = { 4506 build.assign_one(dest, value_exp) 4507 } 4508 else 4509 local key_name, val_name = NameProxy("key"), NameProxy("val") 4510 local dest = build.chain({ 4511 base = accum, 4512 { 4513 "index", 4514 key_name 4515 } 4516 }) 4517 inner = { 4518 build.assign({ 4519 names = { 4520 key_name, 4521 val_name 4522 }, 4523 values = { 4524 key_exp 4525 } 4526 }), 4527 build.assign_one(dest, val_name) 4528 } 4529 end 4530 return build.block_exp({ 4531 build.assign_one(accum, build.table()), 4532 construct_comprehension(inner, clauses), 4533 accum 4534 }) 4535 end, 4536 fndef = function(self, node) 4537 smart_node(node) 4538 node.body = apply_to_last(node.body, implicitly_return(self)) 4539 node.body = { 4540 Run(function(self) 4541 return self:listen("varargs", function() end) 4542 end), 4543 unpack(node.body) 4544 } 4545 return node 4546 end, 4547 ["if"] = function(self, node) 4548 return build.block_exp({ 4549 node 4550 }) 4551 end, 4552 unless = function(self, node) 4553 return build.block_exp({ 4554 node 4555 }) 4556 end, 4557 with = function(self, node) 4558 return build.block_exp({ 4559 node 4560 }) 4561 end, 4562 switch = function(self, node) 4563 return build.block_exp({ 4564 node 4565 }) 4566 end, 4567 chain = function(self, node) 4568 local stub = node[#node] 4569 for i = 3, #node do 4570 local part = node[i] 4571 if ntype(part) == "dot" and data.lua_keywords[part[2]] then 4572 node[i] = { 4573 "index", 4574 { 4575 "string", 4576 '"', 4577 part[2] 4578 } 4579 } 4580 end 4581 end 4582 if ntype(node[2]) == "string" then 4583 node[2] = { 4584 "parens", 4585 node[2] 4586 } 4587 elseif type(stub) == "table" and stub[1] == "colon_stub" then 4588 table.remove(node, #node) 4589 local base_name = NameProxy("base") 4590 local fn_name = NameProxy("fn") 4591 local is_super = ntype(node[2]) == "ref" and node[2][2] == "super" 4592 return build.block_exp({ 4593 build.assign({ 4594 names = { 4595 base_name 4596 }, 4597 values = { 4598 node 4599 } 4600 }), 4601 build.assign({ 4602 names = { 4603 fn_name 4604 }, 4605 values = { 4606 build.chain({ 4607 base = base_name, 4608 { 4609 "dot", 4610 stub[2] 4611 } 4612 }) 4613 } 4614 }), 4615 build.fndef({ 4616 args = { 4617 { 4618 "..." 4619 } 4620 }, 4621 body = { 4622 build.chain({ 4623 base = fn_name, 4624 { 4625 "call", 4626 { 4627 is_super and "self" or base_name, 4628 "..." 4629 } 4630 } 4631 }) 4632 } 4633 }) 4634 }) 4635 end 4636 end, 4637 block_exp = function(self, node) 4638 local _, body = unpack(node) 4639 local fn = nil 4640 local arg_list = { } 4641 fn = smart_node(build.fndef({ 4642 body = { 4643 Run(function(self) 4644 return self:listen("varargs", function() 4645 insert(arg_list, "...") 4646 insert(fn.args, { 4647 "..." 4648 }) 4649 return self:unlisten("varargs") 4650 end) 4651 end), 4652 unpack(body) 4653 } 4654 })) 4655 return build.chain({ 4656 base = { 4657 "parens", 4658 fn 4659 }, 4660 { 4661 "call", 4662 arg_list 4663 } 4664 }) 4665 end 4666 }) 4667 return { 4668 Statement = Statement, 4669 Value = Value, 4670 Run = Run 4671 } 4672 4673end 4674package.preload['moonscript.types'] = function() 4675 local util = require("moonscript.util") 4676 local Set 4677 do 4678 local _obj_0 = require("moonscript.data") 4679 Set = _obj_0.Set 4680 end 4681 local insert 4682 do 4683 local _obj_0 = table 4684 insert = _obj_0.insert 4685 end 4686 local unpack 4687 unpack = util.unpack 4688 local manual_return = Set({ 4689 "foreach", 4690 "for", 4691 "while", 4692 "return" 4693 }) 4694 local cascading = Set({ 4695 "if", 4696 "unless", 4697 "with", 4698 "switch", 4699 "class", 4700 "do" 4701 }) 4702 local ntype 4703 ntype = function(node) 4704 local _exp_0 = type(node) 4705 if "nil" == _exp_0 then 4706 return "nil" 4707 elseif "table" == _exp_0 then 4708 return node[1] 4709 else 4710 return "value" 4711 end 4712 end 4713 local mtype 4714 do 4715 local moon_type = util.moon.type 4716 mtype = function(val) 4717 local mt = getmetatable(val) 4718 if mt and mt.smart_node then 4719 return "table" 4720 end 4721 return moon_type(val) 4722 end 4723 end 4724 local has_value 4725 has_value = function(node) 4726 if ntype(node) == "chain" then 4727 local ctype = ntype(node[#node]) 4728 return ctype ~= "call" and ctype ~= "colon" 4729 else 4730 return true 4731 end 4732 end 4733 local is_value 4734 is_value = function(stm) 4735 local compile = require("moonscript.compile") 4736 local transform = require("moonscript.transform") 4737 return compile.Block:is_value(stm) or transform.Value:can_transform(stm) 4738 end 4739 local comprehension_has_value 4740 comprehension_has_value = function(comp) 4741 return is_value(comp[2]) 4742 end 4743 local value_is_singular 4744 value_is_singular = function(node) 4745 return type(node) ~= "table" or node[1] ~= "exp" or #node == 2 4746 end 4747 local is_slice 4748 is_slice = function(node) 4749 return ntype(node) == "chain" and ntype(node[#node]) == "slice" 4750 end 4751 local t = { } 4752 local node_types = { 4753 class = { 4754 { 4755 "name", 4756 "Tmp" 4757 }, 4758 { 4759 "body", 4760 t 4761 } 4762 }, 4763 fndef = { 4764 { 4765 "args", 4766 t 4767 }, 4768 { 4769 "whitelist", 4770 t 4771 }, 4772 { 4773 "arrow", 4774 "slim" 4775 }, 4776 { 4777 "body", 4778 t 4779 } 4780 }, 4781 foreach = { 4782 { 4783 "names", 4784 t 4785 }, 4786 { 4787 "iter" 4788 }, 4789 { 4790 "body", 4791 t 4792 } 4793 }, 4794 ["for"] = { 4795 { 4796 "name" 4797 }, 4798 { 4799 "bounds", 4800 t 4801 }, 4802 { 4803 "body", 4804 t 4805 } 4806 }, 4807 ["while"] = { 4808 { 4809 "cond", 4810 t 4811 }, 4812 { 4813 "body", 4814 t 4815 } 4816 }, 4817 assign = { 4818 { 4819 "names", 4820 t 4821 }, 4822 { 4823 "values", 4824 t 4825 } 4826 }, 4827 declare = { 4828 { 4829 "names", 4830 t 4831 } 4832 }, 4833 ["if"] = { 4834 { 4835 "cond", 4836 t 4837 }, 4838 { 4839 "then", 4840 t 4841 } 4842 } 4843 } 4844 local build_table 4845 build_table = function() 4846 local key_table = { } 4847 for node_name, args in pairs(node_types) do 4848 local index = { } 4849 for i, tuple in ipairs(args) do 4850 local prop_name = tuple[1] 4851 index[prop_name] = i + 1 4852 end 4853 key_table[node_name] = index 4854 end 4855 return key_table 4856 end 4857 local key_table = build_table() 4858 local make_builder 4859 make_builder = function(name) 4860 local spec = node_types[name] 4861 if not spec then 4862 error("don't know how to build node: " .. name) 4863 end 4864 return function(props) 4865 if props == nil then 4866 props = { } 4867 end 4868 local node = { 4869 name 4870 } 4871 for i, arg in ipairs(spec) do 4872 local key, default_value = unpack(arg) 4873 local val 4874 if props[key] then 4875 val = props[key] 4876 else 4877 val = default_value 4878 end 4879 if val == t then 4880 val = { } 4881 end 4882 node[i + 1] = val 4883 end 4884 return node 4885 end 4886 end 4887 local build = nil 4888 build = setmetatable({ 4889 group = function(body) 4890 if body == nil then 4891 body = { } 4892 end 4893 return { 4894 "group", 4895 body 4896 } 4897 end, 4898 ["do"] = function(body) 4899 return { 4900 "do", 4901 body 4902 } 4903 end, 4904 assign_one = function(name, value) 4905 return build.assign({ 4906 names = { 4907 name 4908 }, 4909 values = { 4910 value 4911 } 4912 }) 4913 end, 4914 table = function(tbl) 4915 if tbl == nil then 4916 tbl = { } 4917 end 4918 for _index_0 = 1, #tbl do 4919 local tuple = tbl[_index_0] 4920 if type(tuple[1]) == "string" then 4921 tuple[1] = { 4922 "key_literal", 4923 tuple[1] 4924 } 4925 end 4926 end 4927 return { 4928 "table", 4929 tbl 4930 } 4931 end, 4932 block_exp = function(body) 4933 return { 4934 "block_exp", 4935 body 4936 } 4937 end, 4938 chain = function(parts) 4939 local base = parts.base or error("expecting base property for chain") 4940 if type(base) == "string" then 4941 base = { 4942 "ref", 4943 base 4944 } 4945 end 4946 local node = { 4947 "chain", 4948 base 4949 } 4950 for _index_0 = 1, #parts do 4951 local part = parts[_index_0] 4952 insert(node, part) 4953 end 4954 return node 4955 end 4956 }, { 4957 __index = function(self, name) 4958 self[name] = make_builder(name) 4959 return rawget(self, name) 4960 end 4961 }) 4962 local smart_node_mt = setmetatable({ }, { 4963 __index = function(self, node_type) 4964 local index = key_table[node_type] 4965 local mt = { 4966 smart_node = true, 4967 __index = function(node, key) 4968 if index[key] then 4969 return rawget(node, index[key]) 4970 elseif type(key) == "string" then 4971 return error("unknown key: `" .. key .. "` on node type: `" .. ntype(node) .. "`") 4972 end 4973 end, 4974 __newindex = function(node, key, value) 4975 if index[key] then 4976 key = index[key] 4977 end 4978 return rawset(node, key, value) 4979 end 4980 } 4981 self[node_type] = mt 4982 return mt 4983 end 4984 }) 4985 local smart_node 4986 smart_node = function(node) 4987 return setmetatable(node, smart_node_mt[ntype(node)]) 4988 end 4989 return { 4990 ntype = ntype, 4991 smart_node = smart_node, 4992 build = build, 4993 is_value = is_value, 4994 is_slice = is_slice, 4995 manual_return = manual_return, 4996 cascading = cascading, 4997 value_is_singular = value_is_singular, 4998 comprehension_has_value = comprehension_has_value, 4999 has_value = has_value, 5000 mtype = mtype 5001 } 5002 5003end 5004package.preload['moonscript.util'] = function() 5005 local concat 5006 do 5007 local _obj_0 = table 5008 concat = _obj_0.concat 5009 end 5010 local unpack = unpack or table.unpack 5011 local type = type 5012 local moon = { 5013 is_object = function(value) 5014 return type(value) == "table" and value.__class 5015 end, 5016 is_a = function(thing, t) 5017 if not (type(thing) == "table") then 5018 return false 5019 end 5020 local cls = thing.__class 5021 while cls do 5022 if cls == t then 5023 return true 5024 end 5025 cls = cls.__parent 5026 end 5027 return false 5028 end, 5029 type = function(value) 5030 local base_type = type(value) 5031 if base_type == "table" then 5032 local cls = value.__class 5033 if cls then 5034 return cls 5035 end 5036 end 5037 return base_type 5038 end 5039 } 5040 local pos_to_line 5041 pos_to_line = function(str, pos) 5042 local line = 1 5043 for _ in str:sub(1, pos):gmatch("\n") do 5044 line = line + 1 5045 end 5046 return line 5047 end 5048 local trim 5049 trim = function(str) 5050 return str:match("^%s*(.-)%s*$") 5051 end 5052 local get_line 5053 get_line = function(str, line_num) 5054 for line in str:gmatch("([^\n]*)\n?") do 5055 if line_num == 1 then 5056 return line 5057 end 5058 line_num = line_num - 1 5059 end 5060 end 5061 local get_closest_line 5062 get_closest_line = function(str, line_num) 5063 local line = get_line(str, line_num) 5064 if (not line or trim(line) == "") and line_num > 1 then 5065 return get_closest_line(str, line_num - 1) 5066 else 5067 return line, line_num 5068 end 5069 end 5070 local reversed 5071 reversed = function(seq) 5072 return coroutine.wrap(function() 5073 for i = #seq, 1, -1 do 5074 coroutine.yield(i, seq[i]) 5075 end 5076 end) 5077 end 5078 local split 5079 split = function(str, delim) 5080 if str == "" then 5081 return { } 5082 end 5083 str = str .. delim 5084 local _accum_0 = { } 5085 local _len_0 = 1 5086 for m in str:gmatch("(.-)" .. delim) do 5087 _accum_0[_len_0] = m 5088 _len_0 = _len_0 + 1 5089 end 5090 return _accum_0 5091 end 5092 local dump 5093 dump = function(what) 5094 local seen = { } 5095 local _dump 5096 _dump = function(what, depth) 5097 if depth == nil then 5098 depth = 0 5099 end 5100 local t = type(what) 5101 if t == "string" then 5102 return '"' .. what .. '"\n' 5103 elseif t == "table" then 5104 if seen[what] then 5105 return "recursion(" .. tostring(what) .. ")...\n" 5106 end 5107 seen[what] = true 5108 depth = depth + 1 5109 local lines 5110 do 5111 local _accum_0 = { } 5112 local _len_0 = 1 5113 for k, v in pairs(what) do 5114 _accum_0[_len_0] = (" "):rep(depth * 4) .. "[" .. tostring(k) .. "] = " .. _dump(v, depth) 5115 _len_0 = _len_0 + 1 5116 end 5117 lines = _accum_0 5118 end 5119 seen[what] = false 5120 return "{\n" .. concat(lines) .. (" "):rep((depth - 1) * 4) .. "}\n" 5121 else 5122 return tostring(what) .. "\n" 5123 end 5124 end 5125 return _dump(what) 5126 end 5127 local debug_posmap 5128 debug_posmap = function(posmap, moon_code, lua_code) 5129 local tuples 5130 do 5131 local _accum_0 = { } 5132 local _len_0 = 1 5133 for k, v in pairs(posmap) do 5134 _accum_0[_len_0] = { 5135 k, 5136 v 5137 } 5138 _len_0 = _len_0 + 1 5139 end 5140 tuples = _accum_0 5141 end 5142 table.sort(tuples, function(a, b) 5143 return a[1] < b[1] 5144 end) 5145 local lines 5146 do 5147 local _accum_0 = { } 5148 local _len_0 = 1 5149 for _index_0 = 1, #tuples do 5150 local pair = tuples[_index_0] 5151 local lua_line, pos = unpack(pair) 5152 local moon_line = pos_to_line(moon_code, pos) 5153 local lua_text = get_line(lua_code, lua_line) 5154 local moon_text = get_closest_line(moon_code, moon_line) 5155 local _value_0 = tostring(pos) .. "\t " .. tostring(lua_line) .. ":[ " .. tostring(trim(lua_text)) .. " ] >> " .. tostring(moon_line) .. ":[ " .. tostring(trim(moon_text)) .. " ]" 5156 _accum_0[_len_0] = _value_0 5157 _len_0 = _len_0 + 1 5158 end 5159 lines = _accum_0 5160 end 5161 return concat(lines, "\n") 5162 end 5163 local setfenv = setfenv or function(fn, env) 5164 local name 5165 local i = 1 5166 while true do 5167 name = debug.getupvalue(fn, i) 5168 if not name or name == "_ENV" then 5169 break 5170 end 5171 i = i + 1 5172 end 5173 if name then 5174 debug.upvaluejoin(fn, i, (function() 5175 return env 5176 end), 1) 5177 end 5178 return fn 5179 end 5180 local getfenv = getfenv or function(fn) 5181 local i = 1 5182 while true do 5183 local name, val = debug.getupvalue(fn, i) 5184 if not (name) then 5185 break 5186 end 5187 if name == "_ENV" then 5188 return val 5189 end 5190 i = i + 1 5191 end 5192 return nil 5193 end 5194 local get_options 5195 get_options = function(...) 5196 local count = select("#", ...) 5197 local opts = select(count, ...) 5198 if type(opts) == "table" then 5199 return opts, unpack({ 5200 ... 5201 }, nil, count - 1) 5202 else 5203 return { }, ... 5204 end 5205 end 5206 return { 5207 moon = moon, 5208 pos_to_line = pos_to_line, 5209 get_closest_line = get_closest_line, 5210 get_line = get_line, 5211 reversed = reversed, 5212 trim = trim, 5213 split = split, 5214 dump = dump, 5215 debug_posmap = debug_posmap, 5216 getfenv = getfenv, 5217 setfenv = setfenv, 5218 get_options = get_options, 5219 unpack = unpack 5220 } 5221 5222end 5223package.preload['moonscript.version'] = function() 5224 5225 module("moonscript.version", package.seeall) 5226 5227 version = "0.2.5" 5228 function print_version() 5229 print("MoonScript version "..version) 5230 end 5231 5232end 5233return package.preload["moonscript"]() 5234