diff options
| author | Bruce Hill <bitbucket@bruce-hill.com> | 2018-07-22 14:57:37 -0700 |
|---|---|---|
| committer | Bruce Hill <bitbucket@bruce-hill.com> | 2018-07-22 14:57:56 -0700 |
| commit | 4fa9757fa27d79a0cda399dcf3b711f4d0d60457 (patch) | |
| tree | a67d210b87912ac023822b3e69c97c406659e139 | |
| parent | 0fe94570b5c33e01472f61fcd564809f93e1b08a (diff) | |
Better handling of parsing non-filechunks text.
| -rw-r--r-- | files.lua | 10 | ||||
| -rw-r--r-- | nomsu.2.peg | 12 | ||||
| -rw-r--r-- | nomsu_compiler.lua | 7 | ||||
| -rw-r--r-- | nomsu_compiler.moon | 5 | ||||
| -rw-r--r-- | parser.lua | 17 |
5 files changed, 29 insertions, 22 deletions
@@ -229,7 +229,15 @@ Files.get_line_number = function(str, pos) end Files.get_line = function(str, line_no) local line_starts = Files.get_line_starts(str) - return str:sub(line_starts[line_no] or 1, (line_starts[line_no + 1] or 1) - 2) + local start = line_starts[line_no] + if not (start) then + return + end + local stop = line_starts[line_no + 1] + if not (stop) then + return + end + return str:sub(start, stop - 2) end local get_lines = re.compile([[ lines <- {| line (%nl line)* |} line <- {[^%nl]*} diff --git a/nomsu.2.peg b/nomsu.2.peg index c1f4f81..1f096af 100644 --- a/nomsu.2.peg +++ b/nomsu.2.peg @@ -1,8 +1,8 @@ -- Nomsu version 2 file: {:curr_indent: ' '* :} - (file_chunks / chunk / (comment? blank_lines? (inline_block / indented_block)))? - blank_lines? + (((action / expression / inline_block / indented_block) eol !.) + / file_chunks / blank_lines / '') %ws* (!! .+ -> "Parse error" !!)? shebang: "#!" (!"nomsu" [^%nl])* "nomsu" %ws+ "-V" %ws* {:version: [0-9.]+ :} [^%nl]* @@ -10,16 +10,12 @@ shebang: "#!" (!"nomsu" [^%nl])* "nomsu" %ws+ "-V" %ws* {:version: [0-9.]+ :} [^ file_chunks (FileChunks): {:curr_indent: ' '* :} shebang? comment? blank_lines? - chunk (nl_nodent section_division nl_nodent chunk)+ + (top_block (nl_nodent section_division top_block)*) blank_lines? -chunk: - top_block / (comment? blank_lines? statement) - top_block (Block): {:curr_indent: ' '* :} - shebang? comment? blank_lines? - statement (nl_nodent statement)+ + comment? blank_lines? statement (nl_nodent statement)* nodent: =curr_indent !(" ") indent: =curr_indent " " diff --git a/nomsu_compiler.lua b/nomsu_compiler.lua index 16874a3..ac33eb2 100644 --- a/nomsu_compiler.lua +++ b/nomsu_compiler.lua @@ -1062,7 +1062,7 @@ do nomsu:append("\n", pop_comments(line.source.start)) setup = false end - nomsu:append(pop_comments(line.source.start, '\n')) + nomsu:append(pop_comments(line.source.start, tostring(nomsu):match("\n\n$") and "" or "\n")) local line_nomsu = self:tree_to_nomsu(line, pop_comments) nomsu:append(line_nomsu) if line_no < #chunk then @@ -1076,6 +1076,9 @@ do setup = false end nomsu:append(pop_comments(tree.source.stop, '\n')) + if not (tostring(nomsu):match("\n$")) then + nomsu:append('\n') + end return nomsu elseif "Action" == _exp_0 then local pos, next_space = tree.source.start, '' @@ -1117,7 +1120,7 @@ do local line_nomsu = recurse(line) nomsu:append(line_nomsu) if i < #tree then - nomsu:append(line_nomsu:is_multiline() and "\n\n" or "\n") + nomsu:append(tostring(line_nomsu):match('\n[^\n]*\n') and "\n\n" or "\n") end end nomsu:append(pop_comments(tree.source.stop, '\n')) diff --git a/nomsu_compiler.moon b/nomsu_compiler.moon index afea8ae..12503f2 100644 --- a/nomsu_compiler.moon +++ b/nomsu_compiler.moon @@ -667,7 +667,7 @@ with NomsuCompiler elseif setup and not (line.type == "Action" and line.stub == "use %") nomsu\append "\n", pop_comments(line.source.start) setup = false - nomsu\append pop_comments(line.source.start, '\n') + nomsu\append pop_comments(line.source.start, tostring(nomsu)\match("\n\n$") and "" or "\n") line_nomsu = @tree_to_nomsu(line, pop_comments) nomsu\append line_nomsu nomsu\append(line_nomsu\is_multiline! and "\n\n" or "\n") if line_no < #chunk @@ -676,6 +676,7 @@ with NomsuCompiler nomsu\append recurse(chunk) setup = false nomsu\append pop_comments(tree.source.stop, '\n') + nomsu\append('\n') unless tostring(nomsu)\match("\n$") return nomsu when "Action" @@ -717,7 +718,7 @@ with NomsuCompiler line_nomsu = recurse(line) nomsu\append line_nomsu if i < #tree - nomsu\append(line_nomsu\is_multiline! and "\n\n" or "\n") + nomsu\append(tostring(line_nomsu)\match('\n[^\n]*\n') and "\n\n" or "\n") nomsu\append pop_comments(tree.source.stop, '\n') return NomsuCode(tree.source, ":\n ", nomsu) @@ -70,19 +70,21 @@ do end local err_pos = start_pos local line_no = files.get_line_number(src, err_pos) - local prev_line = line_no == 1 and "" or files.get_line(src, line_no - 1) + local prev_line = line_no == 1 and nil or files.get_line(src, line_no - 1) local err_line = files.get_line(src, line_no) local next_line = files.get_line(src, line_no + 1) local i = err_pos - files.get_line_starts(src)[line_no] local j = i + (end_pos - start_pos) local pointer = ("-"):rep(i) .. "^" err_msg = colored.bright(colored.yellow(colored.onred((err_msg or "Parse error") .. " at " .. tostring(userdata.source.filename) .. ":" .. tostring(line_no) .. ":"))) - if #prev_line > 0 then + if prev_line then err_msg = err_msg .. ("\n" .. colored.dim(prev_line)) end - err_line = colored.white(err_line:sub(1, i)) .. colored.bright(colored.red(err_line:sub(i + 1, j + 1))) .. colored.dim(err_line:sub(j + 2, -1)) - err_msg = err_msg .. "\n" .. tostring(err_line) .. "\n" .. tostring(colored.red(pointer)) - if #next_line > 0 then + if err_line then + err_line = colored.white(err_line:sub(1, i)) .. colored.bright(colored.red(err_line:sub(i + 1, j + 1))) .. colored.dim(err_line:sub(j + 2, -1)) + err_msg = err_msg .. "\n" .. tostring(err_line) .. "\n" .. tostring(colored.red(pointer)) + end + if next_line then err_msg = err_msg .. ("\n" .. colored.dim(next_line)) end seen_errors[start_pos] = err_msg @@ -160,12 +162,9 @@ Parser.parse = function(nomsu_code, source, version) comments = { } } local tree = Parser.patterns[syntax_version]:match(nomsu_code, nil, userdata) - if not (tree) then + if not tree or type(tree) == 'number' then error("In file " .. tostring(colored.blue(tostring(source or "<unknown>"))) .. " failed to parse:\n" .. tostring(colored.onyellow(colored.black(nomsu_code)))) end - if type(tree) == 'number' then - return nil - end if next(userdata.errors) then local keys do |
