aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--code_obj.lua22
-rw-r--r--code_obj.moon19
-rw-r--r--nomsu.lua15
-rwxr-xr-xnomsu.moon13
-rw-r--r--nomsu.peg34
-rw-r--r--nomsu_tree.lua7
-rw-r--r--nomsu_tree.moon4
7 files changed, 50 insertions, 64 deletions
diff --git a/code_obj.lua b/code_obj.lua
index d84744e..e8e86fa 100644
--- a/code_obj.lua
+++ b/code_obj.lua
@@ -20,6 +20,13 @@ Source = immutable({
end
return filename, start, stop
end,
+ from_string = function(self, str)
+ local filename, start, stop = str:match("^(.-)%[(%d+):(%d+)%]$")
+ if not (filename) then
+ filename, start = str:match("^(.-)%[(%d+)%]$")
+ end
+ return Source(filename or str, tonumber(start or 1), tonumber(stop))
+ end,
__tostring = function(self)
if self.stop then
return "\"" .. tostring(self.filename) .. "[" .. tostring(self.start) .. ":" .. tostring(self.stop) .. "]\""
@@ -94,11 +101,6 @@ local Code
do
local _class_0
local _base_0 = {
- sub = function(self, start, stop)
- local str = tostring(self):sub(start, stop)
- local cls = self.__class
- return cls(self.source:sub(start, stop), str)
- end,
append = function(self, ...)
local n = select("#", ...)
local bits, indents = self.bits, self.indents
@@ -156,15 +158,7 @@ do
self.bits, self.indents, self.current_indent = { }, { }, 0
self:append(...)
if type(self.source) == 'string' then
- local filename, start, stop = self.source:match("^(.-)%[(%d+):(%d+)%]$")
- if not (filename) then
- filename, start = self.source:match("^(.-)%[(%d+)%]$")
- end
- if start or stop then
- self.source = Source(filename, tonumber(start), tonumber(stop))
- else
- self.source = Source(self.source, 1, #tostring(self) + 1)
- end
+ self.source = Source:from_string(self.source)
end
return assert(self.source)
end,
diff --git a/code_obj.moon b/code_obj.moon
index 3f9e37a..14bc74a 100644
--- a/code_obj.moon
+++ b/code_obj.moon
@@ -10,6 +10,11 @@ Source = immutable {"filename","start","stop"}, {
start, stop = 1, #FILE_CACHE[filename]
if stop then assert(start <= stop+1, "Invalid range: #{start}, #{stop}")
return filename, start, stop
+ from_string: (str)=>
+ filename,start,stop = str\match("^(.-)%[(%d+):(%d+)%]$")
+ unless filename
+ filename,start = str\match("^(.-)%[(%d+)%]$")
+ return Source(filename or str, tonumber(start or 1), tonumber(stop))
__tostring: =>
if @stop
"\"#{@filename}[#{@start}:#{@stop}]\""
@@ -65,21 +70,9 @@ class Code
@bits, @indents, @current_indent = {}, {}, 0
@append(...)
if type(@source) == 'string'
- filename,start,stop = @source\match("^(.-)%[(%d+):(%d+)%]$")
- unless filename
- filename,start = @source\match("^(.-)%[(%d+)%]$")
- if start or stop
- @source = Source(filename, tonumber(start), tonumber(stop))
- else
- @source = Source(@source, 1, #tostring(self)+1)
+ @source = Source\from_string(@source)
assert(@source)
- sub: (start,stop)=>
- -- TODO: implement this better
- str = tostring(self)\sub(start,stop)
- cls = @__class
- return cls(@source\sub(start,stop), str)
-
append: (...)=>
n = select("#",...)
bits, indents = @bits, @indents
diff --git a/nomsu.lua b/nomsu.lua
index d035611..4841a7e 100644
--- a/nomsu.lua
+++ b/nomsu.lua
@@ -211,14 +211,14 @@ do
return true
end
local err_pos = start_pos
- local text_loc = lpeg.userdata.source_code.source:sub(err_pos, err_pos)
+ local text_loc = lpeg.userdata.source:sub(err_pos, err_pos)
local line_no = text_loc:get_line_number()
src = FILE_CACHE[text_loc.filename]
local prev_line = line_no == 1 and "" or src:sub(LINE_STARTS[src][line_no - 1] or 1, LINE_STARTS[src][line_no] - 2)
local err_line = src:sub(LINE_STARTS[src][line_no], (LINE_STARTS[src][line_no + 1] or 0) - 2)
local next_line = src:sub(LINE_STARTS[src][line_no + 1] or -1, (LINE_STARTS[src][line_no + 2] or 0) - 2)
local pointer = ("-"):rep(err_pos - LINE_STARTS[src][line_no]) .. "^"
- err_msg = (err_msg or "Parse error") .. " at " .. tostring(lpeg.userdata.source_code.source.filename) .. ":" .. tostring(line_no) .. ":\n"
+ err_msg = (err_msg or "Parse error") .. " at " .. tostring(lpeg.userdata.source.filename) .. ":" .. tostring(line_no) .. ":\n"
if #prev_line > 0 then
err_msg = err_msg .. ("\n" .. prev_line)
end
@@ -234,18 +234,13 @@ end
setmetatable(NOMSU_DEFS, {
__index = function(self, key)
local make_node
- make_node = function(start, ...)
- local args = {
- ...
- }
- local stop = args[#args]
+ make_node = function(start, value, stop)
local source = lpeg.userdata.source:sub(start, stop)
- args[#args] = nil
local tree
if Types[key].is_multi then
- tree = Types[key](Tuple(unpack(args)), source)
+ tree = Types[key](Tuple(unpack(value)), source)
else
- tree = Types[key](args[1], source)
+ tree = Types[key](value, source)
end
return tree
end
diff --git a/nomsu.moon b/nomsu.moon
index cd542b0..ff5ec47 100755
--- a/nomsu.moon
+++ b/nomsu.moon
@@ -184,14 +184,14 @@ NOMSU_DEFS = with {}
err_pos = start_pos
--if src\sub(err_pos,err_pos)\match("[\r\n]")
-- err_pos += #src\match("[ \t\n\r]*", err_pos)
- text_loc = lpeg.userdata.source_code.source\sub(err_pos,err_pos)
+ text_loc = lpeg.userdata.source\sub(err_pos,err_pos)
line_no = text_loc\get_line_number!
src = FILE_CACHE[text_loc.filename]
prev_line = line_no == 1 and "" or src\sub(LINE_STARTS[src][line_no-1] or 1, LINE_STARTS[src][line_no]-2)
err_line = src\sub(LINE_STARTS[src][line_no], (LINE_STARTS[src][line_no+1] or 0)-2)
next_line = src\sub(LINE_STARTS[src][line_no+1] or -1, (LINE_STARTS[src][line_no+2] or 0)-2)
pointer = ("-")\rep(err_pos-LINE_STARTS[src][line_no]) .. "^"
- err_msg = (err_msg or "Parse error").." at #{lpeg.userdata.source_code.source.filename}:#{line_no}:\n"
+ err_msg = (err_msg or "Parse error").." at #{lpeg.userdata.source.filename}:#{line_no}:\n"
if #prev_line > 0 then err_msg ..= "\n"..prev_line
err_msg ..= "\n#{err_line}\n#{pointer}"
if #next_line > 0 then err_msg ..= "\n"..next_line
@@ -200,14 +200,11 @@ NOMSU_DEFS = with {}
return true
setmetatable(NOMSU_DEFS, {__index:(key)=>
- make_node = (start, ...)->
- args = {...}
- stop = args[#args]
+ make_node = (start, value, stop)->
source = lpeg.userdata.source\sub(start, stop)
- args[#args] = nil
tree = if Types[key].is_multi
- Types[key](Tuple(unpack(args)), source)
- else Types[key](args[1], source)
+ Types[key](Tuple(unpack(value)), source)
+ else Types[key](value, source)
return tree
self[key] = make_node
return make_node
diff --git a/nomsu.peg b/nomsu.peg
index 459eb32..a3fbac1 100644
--- a/nomsu.peg
+++ b/nomsu.peg
@@ -8,9 +8,9 @@ file:
shebang: "#!" [^%nl]* (!. / %nl)
inline_block (Block):
- inline_statement (%ws* ";" %ws* inline_statement)+
+ {| inline_statement (%ws* ";" %ws* inline_statement)+ |}
block (Block):
- statement (nodent (statement / (({} ([^%nl]* -> "Error while parsing block line")) => error)))+
+ {| statement (nodent (statement / (({} ([^%nl]* -> "Error while parsing block line")) => error)))+ |}
statement: (action / expression) (eol / (({} ([^%nl]* -> "Error while parsing line")) => error))
inline_statement: inline_action / inline_expression
@@ -35,19 +35,21 @@ indented_expression:
expression:
inline_expression / (":" %ws* (inline_block / inline_action / inline_expression) eol) / indented_expression
-inline_nomsu (EscapedNomsu): "\" inline_expression
+inline_nomsu (EscapedNomsu): "\" {| inline_expression |}
indented_nomsu (EscapedNomsu):
- "\" (noindex_inline_expression / (":" %ws* (inline_block / inline_action / inline_expression) eol) / indented_expression)
+ "\" {| (noindex_inline_expression / (":" %ws* (inline_block / inline_action / inline_expression) eol) / indented_expression) |}
index_chain (IndexChain):
- noindex_inline_expression ("." (text_word / noindex_inline_expression))+
+ {| noindex_inline_expression ("." (text_word / noindex_inline_expression))+ |}
-- Actions need at least one word in them
inline_action (Action):
+ {|
(inline_expression %ws*)* word (%ws* (inline_expression / word))*
(%ws* ":" %ws* (inline_block / inline_action / inline_expression))?
+ |}
action (Action):
- (expression (dotdot? %ws*))* word ((dotdot? %ws*) (expression / word))*
+ {| (expression (dotdot? %ws*))* word ((dotdot? %ws*) (expression / word))* |}
word: { %operator / (!number plain_word) }
@@ -55,19 +57,19 @@ text_word (Text): {%operator / (!number plain_word)}
inline_text (Text):
!('".."' eol)
- '"' (
+ '"' {|
({~ (('\"' -> '"') / ('\\' -> '\') / %escaped_char / [^%nl\"])+ ~}
/ inline_text_interpolation)*
- ) ('"' / (({} ([^%nl]*->'Failed to find a closing " mark on the same line')) => error))
+ |} ('"' / (({} ([^%nl]*->'Failed to find a closing " mark on the same line')) => error))
-- Have to use "%indent" instead of "indent" etc. to avoid messing up text lines that start with "#"
indented_text (Text):
- '".."' eol %nl (
+ '".."' eol %nl {|
{~ (%nl*) (%indent -> "") ~}
({~
(("\\" -> "\") / (("\" nodent "..") -> "")/ (%nl+ {~ %nodent -> "" ~}) / [^%nl\] / (!text_interpolation "\"))+
~} / text_interpolation)*
- ) (((!.) &%dedent) / (&(%nl %dedent)) / (({} (non_dedent_error -> "Error while parsing Text")) => error))
+ |} (((!.) &%dedent) / (&(%nl %dedent)) / (({} (non_dedent_error -> "Error while parsing Text")) => error))
inline_text_interpolation:
"\" (
variable / inline_list / inline_dict / inline_text
@@ -90,11 +92,11 @@ variable (Var): "%" { ((!"'" %operator) / plain_word)* }
inline_list (List):
!('[..]')
- "[" %ws* (inline_list_item (comma inline_list_item)* comma?)? %ws*
+ "[" %ws* {| (inline_list_item (comma inline_list_item)* comma?)? |} %ws*
("]" / (({} ([^%nl]*->"Failed to find a closing ] on the same line")) => error))
indented_list (List):
"[..]" indent
- list_line (nodent list_line)*
+ {| list_line (nodent list_line)* |}
(dedent / (({} (non_dedent_error -> "Error while parsing list")) => error))
list_line:
((action / expression) !comma)
@@ -103,20 +105,20 @@ inline_list_item: inline_block / inline_action / inline_expression
inline_dict (Dict):
!('{..}')
- "{" %ws* (inline_dict_entry (comma inline_dict_entry)*)? %ws*
+ "{" %ws* {| (inline_dict_entry (comma inline_dict_entry)*)? |} %ws*
("}"
/ (({} (%ws* comma? (!. / &%nl)->"Failed to find a closing } on the same line")) => error)
/ (({} ([^%nl]*->"Error while parsing dictionary")) => error))
indented_dict (Dict):
"{..}" indent
- dict_line (nodent dict_line)*
+ {| dict_line (nodent dict_line)* |}
(dedent / (({} (non_dedent_error -> "Error while parsing dict")) => error))
dict_line:
(dict_entry !comma) / (inline_dict_entry (comma dict_line?)?)
dict_entry(DictEntry):
- dict_key %ws* ":" %ws* (action / expression)
+ {| dict_key %ws* ":" %ws* (action / expression) |}
inline_dict_entry(DictEntry):
- dict_key %ws* (":" %ws* (inline_block / inline_action / inline_expression)?)
+ {| dict_key %ws* (":" %ws* (inline_block / inline_action / inline_expression)?) |}
dict_key:
text_word / inline_expression
diff --git a/nomsu_tree.lua b/nomsu_tree.lua
index ccbc34a..5b7a463 100644
--- a/nomsu_tree.lua
+++ b/nomsu_tree.lua
@@ -7,10 +7,10 @@ do
local _obj_0 = table
insert, remove, concat = _obj_0.insert, _obj_0.remove, _obj_0.concat
end
-local Lua, Nomsu, Location
+local Lua, Nomsu, Source
do
local _obj_0 = require("code_obj")
- Lua, Nomsu, Location = _obj_0.Lua, _obj_0.Nomsu, _obj_0.Location
+ Lua, Nomsu, Source = _obj_0.Lua, _obj_0.Nomsu, _obj_0.Source
end
local MAX_LINE = 80
local Types = { }
@@ -27,6 +27,9 @@ Tree = function(name, kind, methods)
methods.name = name
methods.__new = function(self, value, source)
assert(source)
+ if type(source) == 'string' then
+ source = Source:from_string(source)
+ end
return value, source
end
methods.is_multi = is_multi
diff --git a/nomsu_tree.moon b/nomsu_tree.moon
index ac82cc0..2d30486 100644
--- a/nomsu_tree.moon
+++ b/nomsu_tree.moon
@@ -4,7 +4,7 @@ utils = require 'utils'
{:repr, :stringify, :min, :max, :equivalent, :set, :is_list, :sum} = utils
immutable = require 'immutable'
{:insert, :remove, :concat} = table
-{:Lua, :Nomsu, :Location} = require "code_obj"
+{:Lua, :Nomsu, :Source} = require "code_obj"
MAX_LINE = 80 -- For beautification purposes, try not to make lines much longer than this value
@@ -22,6 +22,8 @@ Tree = (name, kind, methods)->
.name = name
.__new = (value, source)=>
assert source
+ if type(source) == 'string'
+ source = Source\from_string(source)
return value, source
.is_multi = is_multi
.map = (fn)=>