diff --git a/compatibility/4.11.nom b/compatibility/4.11.nom index fdf6660..05edfea 100644 --- a/compatibility/4.11.nom +++ b/compatibility/4.11.nom @@ -28,6 +28,12 @@ upgrade action "set" to "4.11" via (..) %rhs.%i = %entry.2 return (SyntaxTree {type: "Action", source: %tree.source, 1: %lhs, 2: "=", 3: %rhs}) +# Changing filesystem API: +upgrade action (for file %f in %path %body) to "4.11" as (for %f in (files for %path) %body) +upgrade action (%expr for file %f in %path) to "4.11" as [: for %f in (files for %path): add %expr] +upgrade action (line %n in %text) to "4.11" as (%text::line %n) +upgrade action (line number of %pos in %text) to "4.11" as (%text::line number at %pos) + # Deprecating shorthand functions: upgrade action [if all of %items %body, if all of %items then %body] to "4.11" as (..) if (all of %items) %body diff --git a/containers.lua b/containers.lua index 6417f2e..69eda94 100644 --- a/containers.lua +++ b/containers.lua @@ -488,7 +488,7 @@ do break end i = tmp[1] - result[#result + 1] = tmp + result[#result + 1] = (#tmp == 1) and tmp[1] or tmp end return List(result) end, diff --git a/containers.moon b/containers.moon index 0c881cd..3804237 100644 --- a/containers.moon +++ b/containers.moon @@ -194,7 +194,7 @@ do tmp = List{stepper(x,i)} break if #tmp == 0 i = tmp[1] - result[#result+1] = tmp + result[#result+1] = (#tmp == 1) and tmp[1] or tmp return List(result) from_1_to: sub, from: sub, character: (i)=> sub(@, i, i) diff --git a/core/metaprogramming.nom b/core/metaprogramming.nom index 165a814..fe97527 100644 --- a/core/metaprogramming.nom +++ b/core/metaprogramming.nom @@ -118,7 +118,7 @@ lua> "\ test: (foo %x) means "outer" - with local [(foo %)'s meaning]: + with {((foo %)'s meaning)}: (foo %x) means: %y = (%x + 1) return %y diff --git a/core/operators.nom b/core/operators.nom index a7cb116..2f79b8f 100644 --- a/core/operators.nom +++ b/core/operators.nom @@ -99,7 +99,8 @@ test: test: [%x, %y] = [1, 2] - with {%z: nil, %x: 999}: + with {%z, %x: 999}: + assume %z == (nil) %z = 999 assume (%z == 999) or barf "'with' failed." assume (%x == 999) or barf "'with' assignment failed." @@ -113,20 +114,19 @@ test: local vars = {} for i, item in ipairs(\%assignments) do local \%target, \%value = item[1], item[2] - if not \%target.type == "Var" then - error("Invalid target for 'with' assignment: "..tostring(\%target)) - end local target_lua = \(%target as lua) - local value_lua = \(%value as lua) + if not target_lua:text():is_lua_id() then + compile_error_at(\%target, "Invalid target for 'with' scope assignment.", + "This should be either a variable or an action's meaning.") + end + local value_lua = \%value and \(%value as lua) or "nil" if i > 1 then lhs:append(", ") rhs:append(", ") end lhs:append(target_lua) rhs:append(value_lua) - if \%target.type == "Var" then - vars[i] = target_lua:text() - end + vars[i] = target_lua:text() end \%lua:remove_free_vars(vars) \%lua:prepend("local ", lhs, " = ", rhs, ";\\n")" diff --git a/core/scopes.nom b/core/scopes.nom deleted file mode 100644 index 009728b..0000000 --- a/core/scopes.nom +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/env nomsu -V4.10.12.7 -# - This file contains definitions pertaining to variable scoping - -use "core/metaprogramming.nom" -use "core/operators.nom" -use "core/collections.nom" -use "core/control_flow.nom" - -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -test: - %x = "outer" - with local %x: - %x = "inner" - assume (%x == "inner") - assume (%x == "outer") - externally (foo) means "outer foo" - with local [(foo)'s meaning]: - externally (foo) means "inner foo" - assume ((foo) == "inner foo") - assume ((foo) == "outer foo") - -[with local %locals %body, with local %locals do %body] all compile to: - %body_lua = (%body as lua) - if %locals.type is: - "Dict": - %body_lua = (Lua "\(what (<- %locals) compiles to)\n\%body_lua") - %body_lua::declare locals [: for % in %locals: add "\(%.1 as lua)"] - - "List": - %body_lua::declare locals [: for % in %locals: add "\(% as lua)"] - - "Var" "Action": - %body_lua::declare locals ["\(%locals as lua)"] - - else: - compile error at %locals "Unexpected local value" - return (Lua "do\n \%body_lua\nend") diff --git a/files.lua b/files.lua index 272002b..abc9d95 100644 --- a/files.lua +++ b/files.lua @@ -1,7 +1,6 @@ local lpeg = require('lpeg') local re = require('re') local Files = { } -assert(package.nomsupath, "No package.nomsupath was found") local run_cmd run_cmd = function(cmd) local f = io.popen(cmd) @@ -78,18 +77,12 @@ Files.exists = function(path) if run_cmd("ls " .. tostring(sanitize(path))) then return true end - for nomsupath in package.nomsupath:gmatch("[^;]+") do - if run_cmd("ls " .. tostring(nomsupath) .. "/" .. tostring(sanitize(path))) then - return true - end - end return false end -local browse -browse = function(path) +Files.list = function(path) if not (_BROWSE_CACHE[path]) then local files - if _SPOOFED_FILES[path] then + if _SPOOFED_FILES[path] or path == 'stdin' then _BROWSE_CACHE[path] = { path } @@ -117,36 +110,31 @@ if ok then if path == 'stdin' or raw_file_exists(path) then return true end - for nomsupath in package.nomsupath:gmatch("[^;]+") do - if raw_file_exists(nomsupath .. "/" .. path) then - return true - end - end return false end - browse = function(filename) - if not (_BROWSE_CACHE[filename]) then - if _SPOOFED_FILES[filename] or filename == 'stdin' then - _BROWSE_CACHE[filename] = { - filename + Files.list = function(path) + if not (_BROWSE_CACHE[path]) then + if _SPOOFED_FILES[path] or path == 'stdin' then + _BROWSE_CACHE[path] = { + path } else - local file_type, err = lfs.attributes(filename, 'mode') + local file_type, err = lfs.attributes(path, 'mode') local _exp_0 = file_type if "file" == _exp_0 or "char device" == _exp_0 then - _BROWSE_CACHE[filename] = { - filename + _BROWSE_CACHE[path] = { + path } elseif "directory" == _exp_0 or "link" == _exp_0 then local files = { } - for subfile in lfs.dir(filename) do + for subfile in lfs.dir(path) do local _continue_0 = false repeat if subfile == "." or subfile == ".." then _continue_0 = true break end - local _list_0 = (browse(filename .. "/" .. subfile) or { }) + local _list_0 = (Files.list(path .. "/" .. subfile) or { }) for _index_0 = 1, #_list_0 do local f = _list_0[_index_0] files[#files + 1] = f @@ -157,13 +145,20 @@ if ok then break end end - _BROWSE_CACHE[filename] = files + _BROWSE_CACHE[path] = files else - _BROWSE_CACHE[filename] = false + _BROWSE_CACHE[path] = false + end + end + if _BROWSE_CACHE[path] then + for i, f in ipairs(_BROWSE_CACHE[path]) do + if f:match("^%./") then + _BROWSE_CACHE[path][i] = f:sub(3) + end end end end - return _BROWSE_CACHE[filename] + return _BROWSE_CACHE[path] end else if not (run_cmd('find . -maxdepth 0')) then @@ -176,43 +171,6 @@ else error("Could not find 'luafilesystem' module and couldn't run system command `find` (this might happen on Windows). Please install `luafilesystem` (which can be found at: " .. tostring(url) .. " or `luarocks install luafilesystem`)", 0) end end -Files.walk = function(path, flush_cache) - if flush_cache == nil then - flush_cache = false - end - if flush_cache then - _BROWSE_CACHE = { } - end - local files - if path == 'stdin' or _SPOOFED_FILES[path] then - files = { - path - } - elseif path:match("^[~/]") or path:match("^%./") or path:match("^%.%./") then - files = browse(path) - else - for nomsupath in package.nomsupath:gmatch("[^;]+") do - do - files = browse(nomsupath .. "/" .. path) - if files then - break - end - end - end - end - files = files or { } - do - local _accum_0 = { } - local _len_0 = 1 - for _index_0 = 1, #files do - local f = files[_index_0] - _accum_0[_len_0] = gsub(f, "^%./", "") - _len_0 = _len_0 + 1 - end - files = _accum_0 - end - return ipairs(files) -end local line_counter = re.compile([[ lines <- {| line (%nl line)* |} line <- {} (!%nl .)* ]], { diff --git a/files.moon b/files.moon index 118b660..93a7342 100644 --- a/files.moon +++ b/files.moon @@ -2,7 +2,6 @@ lpeg = require 'lpeg' re = require 're' Files = {} -assert package.nomsupath, "No package.nomsupath was found" run_cmd = (cmd)-> f = io.popen(cmd) @@ -10,7 +9,6 @@ run_cmd = (cmd)-> return nil unless f\close! return lines - _SPOOFED_FILES = {} _FILE_CACHE = setmetatable {}, __index:_SPOOFED_FILES _BROWSE_CACHE = {} @@ -24,7 +22,7 @@ Files.spoof = (filename, contents)-> _SPOOFED_FILES[filename] = contents return filename --- Read a file's contents (searching first locally, then in the nomsupath) +-- Read a file's contents Files.read = (filename)-> if file_contents = _FILE_CACHE[filename] return file_contents @@ -53,14 +51,12 @@ Files.exists = (path)-> return true if _SPOOFED_FILES[path] return true if path == 'stdin' return true if run_cmd("ls #{sanitize(path)}") - for nomsupath in package.nomsupath\gmatch("[^;]+") - return true if run_cmd("ls #{nomsupath}/#{sanitize(path)}") return false -browse = (path)-> +Files.list = (path)-> unless _BROWSE_CACHE[path] local files - _BROWSE_CACHE[path] = if _SPOOFED_FILES[path] + _BROWSE_CACHE[path] = if _SPOOFED_FILES[path] or path == 'stdin' {path} else run_cmd('find -L "'..path..'" -not -path "*/\\.*" -type f') or false return _BROWSE_CACHE[path] @@ -73,29 +69,30 @@ if ok Files.exists = (path)-> return true if _SPOOFED_FILES[path] return true if path == 'stdin' or raw_file_exists(path) - for nomsupath in package.nomsupath\gmatch("[^;]+") - return true if raw_file_exists(nomsupath.."/"..path) return false - export browse - browse = (filename)-> - unless _BROWSE_CACHE[filename] - _BROWSE_CACHE[filename] = if _SPOOFED_FILES[filename] or filename == 'stdin' - {filename} + Files.list = (path)-> + unless _BROWSE_CACHE[path] + _BROWSE_CACHE[path] = if _SPOOFED_FILES[path] or path == 'stdin' + {path} else - file_type, err = lfs.attributes(filename, 'mode') + file_type, err = lfs.attributes(path, 'mode') switch file_type when "file", "char device" - {filename} + {path} when "directory", "link" files = {} - for subfile in lfs.dir(filename) + for subfile in lfs.dir(path) continue if subfile == "." or subfile == ".." - for f in *(browse(filename.."/"..subfile) or {}) + for f in *(Files.list(path.."/"..subfile) or {}) files[#files+1] = f files else false - return _BROWSE_CACHE[filename] + -- Filter out any "./" prefix to standardize + if _BROWSE_CACHE[path] + for i,f in ipairs(_BROWSE_CACHE[path]) + if f\match("^%./") then _BROWSE_CACHE[path][i] = f\sub(3) + return _BROWSE_CACHE[path] else unless run_cmd('find . -maxdepth 0') url = if jit @@ -103,22 +100,6 @@ else else 'https://github.com/keplerproject/luafilesystem' error "Could not find 'luafilesystem' module and couldn't run system command `find` (this might happen on Windows). Please install `luafilesystem` (which can be found at: #{url} or `luarocks install luafilesystem`)", 0 -Files.walk = (path, flush_cache=false)-> - if flush_cache - export _BROWSE_CACHE - _BROWSE_CACHE = {} - local files - if path == 'stdin' or _SPOOFED_FILES[path] - files = {path} - elseif path\match("^[~/]") or path\match("^%./") or path\match("^%.%./") - files = browse(path) - else - for nomsupath in package.nomsupath\gmatch("[^;]+") - if files = browse(nomsupath.."/"..path) then break - files or= {} - files = [gsub(f, "^%./", "") for f in *files] - return ipairs(files) - line_counter = re.compile([[ lines <- {| line (%nl line)* |} line <- {} (!%nl .)* diff --git a/lib/os.nom b/lib/os.nom index c165e5a..5fb2a1f 100644 --- a/lib/os.nom +++ b/lib/os.nom @@ -3,11 +3,17 @@ This file defines some actions that interact with the operating system and filesystem. test: - path of Nomsu file "lib/os.nom" + assume (nomsu files for "core") -externally (path of Nomsu file %filename) means: - lua> "for i,f in Files.walk(\%filename) do return f end" - barf "Could not find file: \%filename" +externally (files for %path) means: + %files = (=lua "Files.list(\%path)") + if %files: %files = (List %files) + return %files + +externally (nomsu files for %path) means: + for %nomsupath in (%package.nomsupath::all matches of "[^;]+"): + %files = (files for "\%nomsupath/\%path") + if %files: return %files externally (sh> %cmd) means: lua> "\ @@ -23,14 +29,10 @@ externally (read file %filename) means (=lua "Files.read(\%filename)") test: for file %f in "core": do nothing -(for file %f in %path %body) compiles to "\ - ..for i,\(%f as lua expr) in Files.walk(\(%path as lua expr)) do - \(%body as lua) - \(what (===next %f ===) compiles to) - end - \(what (===stop %f ===) compiles to)" +(for file %f in %path %body) parses as (for %f in (nomsu files for %path) %body) -(%expr for file %f in %path) compiles to "\ +# TODO: deprecate +#(%expr for file %f in %path) compiles to "\ ..(function() local ret = List{} for i,\(%f as lua expr) in Files.walk(\(%path as lua expr)) do @@ -49,21 +51,6 @@ externally [..] file:write(\%text) file:close()" -test: - assume (line number of 3 in "x\ny") == 2 - -externally (line number of %pos in %str) means (..) - =lua "Files.get_line_number(\%str, \%pos)" - -test: - assume (line 2 in "one\ntwo\nthree") == "two" - -externally (line %line_num in %str) means (..) - =lua "Files.get_line(\%str, \%line_num)" - -test: - assume (source lines of \(this)) - externally (source lines of %tree) means: %source = (%tree.source if (%tree is syntax tree) else %tree) %file = (read file %source.filename) diff --git a/lib/training_wheels.nom b/lib/training_wheels.nom deleted file mode 100644 index 00ad64b..0000000 --- a/lib/training_wheels.nom +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env nomsu -V4.10.12.7 -# - This file contains a set of definitions that bring some familiar language features - from other languages into nomsu (e.g. "||" and "continue") - -(%a === %b) parses as ((%a's id) is (%b's id)) -(%a !== %b) parses as ((%a's id) is not (%b's id)) -[function %names %body, def %names %body] all parse as (..) - externally %names means %body -(switch %branch_value %body) parses as (if %branch_value is %body) -[None, Null] all parse as (nil) -[True, true] all parse as (yes) -[False, false] all parse as (no) -(pass) parses as (do nothing) -(%a || %b) parses as (%a or %b) -(%a && %b) parses as (%a and %b) -(continue) parses as (do next) -(break) parses as (stop) -(let %thing = %value in %action) parses as (with local {%thing: %value}) -[print %, println %] all parse as (say %) -[error!, panic!, fail!, abort!] all parse as (barf!) -[error %, panic %, fail %, abort %] all parse as (barf %) -(assert %condition) parses as (assume %condition) -(assert %condition %message) parses as (assume %condition or barf %message) -(%cond ? %if_true %if_false) parses as (%if_true if %cond else %if_false) -(lambda %args %body) parses as (%args -> %body) -(function %name %args %body) parses as (%name = (%args -> %body)) diff --git a/nomsu.lua b/nomsu.lua index b4e031b..415be51 100644 --- a/nomsu.lua +++ b/nomsu.lua @@ -157,7 +157,9 @@ run = function() if not (Files.exists(f)) then error("Could not find: '" .. tostring(f) .. "'") end - for _, filename in Files.walk(f) do + local _list_0 = Files.list(f) + for _index_1 = 1, #_list_0 do + local filename = _list_0[_index_1] input_files[filename] = true end _continue_0 = true @@ -170,72 +172,70 @@ run = function() nomsu_environment.run_file_1_in('core', nomsu_environment, nomsu_environment.OPTIMIZATION) end for _index_0 = 1, #file_queue do - local f = file_queue[_index_0] - for _, filename in Files.walk(f) do - local _continue_0 = false - repeat - if not (filename == "stdin" or filename:match("%.nom$")) then - _continue_0 = true - break - end - if args.check_syntax then - local code = Files.read(filename) - local source = Source(filename, 1, #code) - nomsu_environment._1_parsed(NomsuCode:from(source, code)) - print("Parse succeeded: " .. tostring(filename)) - elseif args.compile then - local output - if filename == 'stdin' then - output = io.output() - else - output = io.open(filename:gsub("%.nom$", ".lua"), "w") - end - local code = Files.read(filename) - local source = Source(filename, 1, #code) - code = NomsuCode:from(source, code) - local tree = nomsu_environment._1_parsed(code) - if not (tree.type == 'FileChunks') then - tree = { - tree - } - end - for chunk_no, chunk in ipairs(tree) do - local lua = nomsu_environment.compile(chunk) - lua:declare_locals() - lua:prepend((chunk_no > 1) and '\n' or '', "-- File " .. tostring(filename) .. " chunk #" .. tostring(chunk_no) .. "\n") - if args.verbose then - print(lua:text()) - end - nomsu_environment.run_1_in(chunk, nomsu_environment) - output:write(lua:text(), "\n") - end - print(("Compiled %-25s -> %s"):format(filename, filename:gsub("%.nom$", ".lua"))) - output:close() - elseif args.verbose then - local code = Files.read(filename) - local source = Source(filename, 1, #code) - code = NomsuCode:from(source, code) - local tree = nomsu_environment._1_parsed(code) - if not (tree.type == 'FileChunks') then - tree = { - tree - } - end - for chunk_no, chunk in ipairs(tree) do - local lua = nomsu_environment.compile(chunk) - lua:declare_locals() - lua:prepend((chunk_no > 1) and '\n' or '', "-- File " .. tostring(filename) .. " chunk #" .. tostring(chunk_no) .. "\n") - print(lua:text()) - nomsu_environment.run_1_in(lua, nomsu_environment) - end - else - nomsu_environment.run_file_1_in(filename, nomsu_environment, 0) - end + local _continue_0 = false + repeat + local filename = file_queue[_index_0] + if not (filename == "stdin" or filename:match("%.nom$")) then _continue_0 = true - until true - if not _continue_0 then break end + if args.check_syntax then + local code = Files.read(filename) + local source = Source(filename, 1, #code) + nomsu_environment._1_parsed(NomsuCode:from(source, code)) + print("Parse succeeded: " .. tostring(filename)) + elseif args.compile then + local output + if filename == 'stdin' then + output = io.output() + else + output = io.open(filename:gsub("%.nom$", ".lua"), "w") + end + local code = Files.read(filename) + local source = Source(filename, 1, #code) + code = NomsuCode:from(source, code) + local tree = nomsu_environment._1_parsed(code) + if not (tree.type == 'FileChunks') then + tree = { + tree + } + end + for chunk_no, chunk in ipairs(tree) do + local lua = nomsu_environment.compile(chunk) + lua:declare_locals() + lua:prepend((chunk_no > 1) and '\n' or '', "-- File " .. tostring(filename) .. " chunk #" .. tostring(chunk_no) .. "\n") + if args.verbose then + print(lua:text()) + end + nomsu_environment.run_1_in(chunk, nomsu_environment) + output:write(lua:text(), "\n") + end + print(("Compiled %-25s -> %s"):format(filename, filename:gsub("%.nom$", ".lua"))) + output:close() + elseif args.verbose then + local code = Files.read(filename) + local source = Source(filename, 1, #code) + code = NomsuCode:from(source, code) + local tree = nomsu_environment._1_parsed(code) + if not (tree.type == 'FileChunks') then + tree = { + tree + } + end + for chunk_no, chunk in ipairs(tree) do + local lua = nomsu_environment.compile(chunk) + lua:declare_locals() + lua:prepend((chunk_no > 1) and '\n' or '', "-- File " .. tostring(filename) .. " chunk #" .. tostring(chunk_no) .. "\n") + print(lua:text()) + nomsu_environment.run_1_in(lua, nomsu_environment) + end + else + nomsu_environment.run_file_1_in(filename, nomsu_environment, 0) + end + _continue_0 = true + until true + if not _continue_0 then + break end end if not (args.primary_file or args.exec_strings) then diff --git a/nomsu.moon b/nomsu.moon index 62deada..aaa3dfb 100755 --- a/nomsu.moon +++ b/nomsu.moon @@ -104,54 +104,53 @@ run = -> continue unless Files.exists(f) error("Could not find: '#{f}'") - for _,filename in Files.walk(f) + for filename in *Files.list(f) input_files[filename] = true unless args.no_core nomsu_environment.run_file_1_in 'core', nomsu_environment, nomsu_environment.OPTIMIZATION - for f in *file_queue - for _,filename in Files.walk(f) - continue unless filename == "stdin" or filename\match("%.nom$") - if args.check_syntax - -- Check syntax - code = Files.read(filename) - source = Source(filename, 1, #code) - nomsu_environment._1_parsed(NomsuCode\from(source, code)) - print("Parse succeeded: #{filename}") - elseif args.compile - -- Compile .nom files into .lua - output = if filename == 'stdin' then io.output() - else io.open(filename\gsub("%.nom$", ".lua"), "w") - code = Files.read(filename) - source = Source(filename, 1, #code) - code = NomsuCode\from(source, code) - tree = nomsu_environment._1_parsed(code) - tree = {tree} unless tree.type == 'FileChunks' - for chunk_no, chunk in ipairs tree - lua = nomsu_environment.compile(chunk) - lua\declare_locals! - lua\prepend((chunk_no > 1) and '\n' or '', "-- File #{filename} chunk ##{chunk_no}\n") - if args.verbose then print(lua\text!) - nomsu_environment.run_1_in(chunk, nomsu_environment) - output\write(lua\text!, "\n") - print ("Compiled %-25s -> %s")\format(filename, filename\gsub("%.nom$", ".lua")) - output\close! - elseif args.verbose - code = Files.read(filename) - source = Source(filename, 1, #code) - code = NomsuCode\from(source, code) - tree = nomsu_environment._1_parsed(code) - tree = {tree} unless tree.type == 'FileChunks' - for chunk_no, chunk in ipairs tree - lua = nomsu_environment.compile(chunk) - lua\declare_locals! - lua\prepend((chunk_no > 1) and '\n' or '', "-- File #{filename} chunk ##{chunk_no}\n") - print(lua\text!) - nomsu_environment.run_1_in(lua, nomsu_environment) - else - -- Just run the file - nomsu_environment.run_file_1_in(filename, nomsu_environment, 0) + for filename in *file_queue + continue unless filename == "stdin" or filename\match("%.nom$") + if args.check_syntax + -- Check syntax + code = Files.read(filename) + source = Source(filename, 1, #code) + nomsu_environment._1_parsed(NomsuCode\from(source, code)) + print("Parse succeeded: #{filename}") + elseif args.compile + -- Compile .nom files into .lua + output = if filename == 'stdin' then io.output() + else io.open(filename\gsub("%.nom$", ".lua"), "w") + code = Files.read(filename) + source = Source(filename, 1, #code) + code = NomsuCode\from(source, code) + tree = nomsu_environment._1_parsed(code) + tree = {tree} unless tree.type == 'FileChunks' + for chunk_no, chunk in ipairs tree + lua = nomsu_environment.compile(chunk) + lua\declare_locals! + lua\prepend((chunk_no > 1) and '\n' or '', "-- File #{filename} chunk ##{chunk_no}\n") + if args.verbose then print(lua\text!) + nomsu_environment.run_1_in(chunk, nomsu_environment) + output\write(lua\text!, "\n") + print ("Compiled %-25s -> %s")\format(filename, filename\gsub("%.nom$", ".lua")) + output\close! + elseif args.verbose + code = Files.read(filename) + source = Source(filename, 1, #code) + code = NomsuCode\from(source, code) + tree = nomsu_environment._1_parsed(code) + tree = {tree} unless tree.type == 'FileChunks' + for chunk_no, chunk in ipairs tree + lua = nomsu_environment.compile(chunk) + lua\declare_locals! + lua\prepend((chunk_no > 1) and '\n' or '', "-- File #{filename} chunk ##{chunk_no}\n") + print(lua\text!) + nomsu_environment.run_1_in(lua, nomsu_environment) + else + -- Just run the file + nomsu_environment.run_file_1_in(filename, nomsu_environment, 0) unless args.primary_file or args.exec_strings nomsu_environment.run_file_1_in("tools/repl.nom", nomsu_environment, nomsu_environment.OPTIMIZATION) diff --git a/nomsu_compiler.lua b/nomsu_compiler.lua index a1eadd8..a83f4ec 100644 --- a/nomsu_compiler.lua +++ b/nomsu_compiler.lua @@ -95,6 +95,9 @@ local compile = setmetatable({ return lua end, ["Lua"] = function(compile, code) + if not code then + return LuaCode("LuaCode()") + end if code.type ~= "Text" then return LuaCode("LuaCode:from(", tostring(code.source):as_lua(), ", ", compile(code), ")") end diff --git a/nomsu_compiler.moon b/nomsu_compiler.moon index 3ddf74b..794d87b 100644 --- a/nomsu_compiler.moon +++ b/nomsu_compiler.moon @@ -65,6 +65,8 @@ compile = setmetatable({ return lua ["Lua"]: (compile, code)-> + if not code + return LuaCode("LuaCode()") if code.type != "Text" return LuaCode("LuaCode:from(", tostring(code.source)\as_lua!, ", ", compile(code), ")") add_bit_lua = (lua, bit_lua)-> diff --git a/nomsu_environment.lua b/nomsu_environment.lua index 74a5bc1..7b26852 100644 --- a/nomsu_environment.lua +++ b/nomsu_environment.lua @@ -296,23 +296,41 @@ local nomsu_environment = Importer({ end _currently_running_files:add(path) local mod = _1_forked(environment) - for _, filename in Files.walk(path) do + for nomsupath in package.nomsupath:gmatch("[^;]+") do local _continue_0 = false repeat - if not (filename == "stdin" or filename:match("%.nom$")) then - _continue_0 = true + do + local files = Files.list(nomsupath .. "/" .. path) + if not (files) then + _continue_0 = true + break + end + for _index_0 = 1, #files do + local _continue_1 = false + repeat + local filename = files[_index_0] + if not (filename == "stdin" or filename:match("%.nom$")) then + _continue_1 = true + break + end + local lua_filename = filename:gsub("%.nom$", ".lua") + local code + if optimization ~= 0 and Files.read(lua_filename) then + local file = Files.read(lua_filename) + code = LuaCode:from(Source(filename, 1, #file), file) + else + local file = Files.read(filename) + code = NomsuCode:from(Source(filename, 1, #file), file) + end + environment.run_1_in(code, mod) + _continue_1 = true + until true + if not _continue_1 then + break + end + end break end - local lua_filename = filename:gsub("%.nom$", ".lua") - local code - if optimization ~= 0 and Files.read(lua_filename) then - local file = Files.read(lua_filename) - code = LuaCode:from(Source(filename, 1, #file), file) - else - local file = Files.read(filename) - code = NomsuCode:from(Source(filename, 1, #file), file) - end - environment.run_1_in(code, mod) _continue_0 = true until true if not _continue_0 then diff --git a/nomsu_environment.moon b/nomsu_environment.moon index cfcb15f..9dab5e9 100644 --- a/nomsu_environment.moon +++ b/nomsu_environment.moon @@ -168,17 +168,22 @@ nomsu_environment = Importer{ error("Circular import detected:\n "..circle\joined_with("\n..imports ")) _currently_running_files\add path mod = _1_forked(environment) - for _,filename in Files.walk(path) - continue unless filename == "stdin" or filename\match("%.nom$") - lua_filename = filename\gsub("%.nom$", ".lua") - -- TODO: don't automatically use precompiled version? - code = if optimization != 0 and Files.read(lua_filename) - file = Files.read(lua_filename) - LuaCode\from(Source(filename, 1, #file), file) - else - file = Files.read(filename) - NomsuCode\from(Source(filename, 1, #file), file) - environment.run_1_in(code, mod) + + for nomsupath in package.nomsupath\gmatch("[^;]+") + files = Files.list(nomsupath.."/"..path) + continue unless files + for filename in *files + continue unless filename == "stdin" or filename\match("%.nom$") + lua_filename = filename\gsub("%.nom$", ".lua") + -- TODO: don't automatically use precompiled version? + code = if optimization != 0 and Files.read(lua_filename) + file = Files.read(lua_filename) + LuaCode\from(Source(filename, 1, #file), file) + else + file = Files.read(filename) + NomsuCode\from(Source(filename, 1, #file), file) + environment.run_1_in(code, mod) + break import_to_1_from(environment, mod, prefix) environment.FILE_CACHE[path] = mod _currently_running_files\remove! diff --git a/tools/find_action.nom b/tools/find_action.nom index c51a144..1b7c4e1 100755 --- a/tools/find_action.nom +++ b/tools/find_action.nom @@ -11,10 +11,11 @@ use "lib/consolecolor.nom" %stub = (command line args).1 say "Looking for stub: \%stub..." -%files = [: for % in 2 to (size of (command line args)): add (command line args).%] -for %path in %files: - for file %filename in %path: - unless (%filename::matches "%.nom$"): do next %filename +for % in 2 to (size of (command line args)): + for %filename in (files for (command line args).%): + if (%filename == "-"): %filename = "stdin" + unless ((%filename == "stdin") or (%filename::matches "%.nom$")): + do next %filename %file = (read file %filename) %code = (NomsuCode from (%Source %filename 1 (size of %file)) %file) try: diff --git a/tools/parse.nom b/tools/parse.nom index 6f88179..10d4dde 100755 --- a/tools/parse.nom +++ b/tools/parse.nom @@ -35,7 +35,12 @@ externally (print tree %t at indent %indent) means: else: say "\%indent \(quote %arg)" -for %path in (=lua "arg"): - for file %filename in %path: - unless (%filename::matches "%.nom$"): do next %filename - print tree (parse (read file %filename) from %filename) at indent "" +for %path in (command line args): + for %filename in (files for %path): + if (%filename == "-"): %filename = "stdin" + unless ((%filename == "stdin") or (%filename::matches "%.nom$")): + do next %filename + %text = (read file %filename) + %nomsu = (NomsuCode from (Source %filename 1 (size of %text)) %text) + %tree = (%nomsu parsed) + print tree %tree at indent "" diff --git a/tools/test.nom b/tools/test.nom index f9ed2cb..32c9b7a 100755 --- a/tools/test.nom +++ b/tools/test.nom @@ -13,30 +13,32 @@ if (%args.1 == "-v"): %args::remove index 1 %verbose = (yes) +%to_run = [..] + : + for %path in (command line args): + for %filename in (files for %path): + if (%filename == "-"): %filename = "stdin" + if ((%filename::matches "%.nom$") or (%filename == "stdin")): + add %filename # Make sure all the files get run -for %path in (command line args): - for file %filename in %path: - if (%filename::matches "%.nom$"): use %filename -for %path in (command line args): use %path +for %filename in %to_run: use %filename %tests = {: for %s = %t in (tests): add (=lua "Source:from_string(\%s)") = %t} -for %path in (command line args): - for file %filename in %path: - unless (%filename::matches "%.nom$"): do next %filename - %file_tests = [] - for %src = %test in %tests: - if (%src.filename == %filename): - %file_tests::add {test: %test, source: %src} - - unless (%file_tests is empty): - sort %file_tests by % -> %.source - lua> "io.write('[ .. ] ', \%filename); io.flush()" - if %verbose: say "" - for % in %file_tests: - if %verbose: - say " \(yellow (%.test::with "\n" -> "\n "))" - run %.test - +for %filename in %to_run: + %file_tests = [] + for %src = %test in %tests: + if (%src.filename == %filename): + %file_tests::add {test: %test, source: %src} + + unless (%file_tests is empty): + sort %file_tests by % -> %.source + lua> "io.write('[ .. ] ', \%filename); io.flush()" + if %verbose: say "" + for % in %file_tests: if %verbose: - say (green "PASS") - ..else: - say "\r[\(green "PASS")" + say " \(yellow (%.test::with "\n" -> "\n "))" + run %.test + + if %verbose: + say (green "PASS") + ..else: + say "\r[\(green "PASS")"