aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2018-10-29 13:00:08 -0700
committerBruce Hill <bruce@bruce-hill.com>2018-10-29 13:00:30 -0700
commit23abab4f809e8d4b825746580082292db700036b (patch)
tree8eb95a3b781547abedadd08705a6e6291662737c
parentbe1df7ccd3fb5352ca666129aee93c56b5b27b40 (diff)
Some cleanups and fixes, made the parser more permissive of prematurely
terminated files.
-rw-r--r--containers.lua7
-rw-r--r--containers.moon4
-rw-r--r--core/control_flow.nom4
-rw-r--r--core/metaprogramming.nom2
-rw-r--r--core/operators.nom2
-rw-r--r--lib/object.nom23
-rw-r--r--nomnom/decompile.nom6
-rw-r--r--nomsu.4.peg16
-rw-r--r--nomsu_compiler.lua28
-rw-r--r--nomsu_compiler.moon20
-rwxr-xr-xtools/find_action.nom4
11 files changed, 69 insertions, 47 deletions
diff --git a/containers.lua b/containers.lua
index ab8647e..8ab6c80 100644
--- a/containers.lua
+++ b/containers.lua
@@ -186,6 +186,13 @@ local _list_mt = {
end
return false
end,
+ remove_1 = function(self, item)
+ for i, x in ipairs(self) do
+ if x == item then
+ remove(self, i)
+ end
+ end
+ end,
index_of_1 = function(self, item)
for i, x in ipairs(self) do
if x == item then
diff --git a/containers.moon b/containers.moon
index 1b0e650..30dcfc8 100644
--- a/containers.moon
+++ b/containers.moon
@@ -73,6 +73,10 @@ _list_mt =
if x == item
return true
return false
+ remove_1: (item)=>
+ for i,x in ipairs @
+ if x == item
+ remove(@, i)
index_of_1: (item)=>
for i,x in ipairs @
if x == item
diff --git a/core/control_flow.nom b/core/control_flow.nom
index 48b9c85..37b2b9c 100644
--- a/core/control_flow.nom
+++ b/core/control_flow.nom
@@ -53,7 +53,7 @@ compile [..]
%when_true_expr if %condition otherwise %when_false_expr
%when_false_expr unless %condition else %when_true_expr
%when_false_expr unless %condition then %when_true_expr
-..to (..)
+..to:
# If %when_true_expr is guaranteed to be truthy, we can use Lua's idiomatic
equivalent of a conditional expression: (cond and if_true or if_false)
if {Text:yes, List:yes, Dict:yes, Number:yes}.(%when_true_expr.type):
@@ -541,7 +541,7 @@ test:
assume (sorted %flat) == [1, 2, 3, 4, 5, 6]
# Recurion control flow
-compile [for %var in recursive %structure %body] to (..)
+compile [for %var in recursive %structure %body] to:
with local compile actions:
define mangler
compile [recurse %v on %x] to (..)
diff --git a/core/metaprogramming.nom b/core/metaprogramming.nom
index 6a457d9..d85c1ad 100644
--- a/core/metaprogramming.nom
+++ b/core/metaprogramming.nom
@@ -231,7 +231,7 @@ compile [%tree as nomsu] to (..)
Lua value "nomsu:tree_to_nomsu(\(%tree as lua expr))"
compile [%tree as inline nomsu] to (..)
- Lua value "nomsu:tree_to_nomsu(\(%tree as lua expr), true)"
+ Lua value "nomsu:tree_to_inline_nomsu(\(%tree as lua expr), true)"
action [%var as lua identifier, %var as lua id] (..)
lua> "\
diff --git a/core/operators.nom b/core/operators.nom
index 960440e..55756bb 100644
--- a/core/operators.nom
+++ b/core/operators.nom
@@ -157,7 +157,7 @@ compile [with %assignments %body] to:
test:
assume ((5 wrapped around 2) == 1) or barf "mod not working"
compile [%x wrapped around %y, %x mod %y] to (..)
- Lua value "(\(%x as lua expr) % \(%y as lua expr))"
+ Lua value "((\(%x as lua expr)) % (\(%y as lua expr)))"
# 3-part chained comparisons
# (uses a lambda to avoid re-evaluating middle value, while still being an expression)
diff --git a/lib/object.nom b/lib/object.nom
index 25ff644..bbc6e06 100644
--- a/lib/object.nom
+++ b/lib/object.nom
@@ -2,6 +2,15 @@
#
This file contains the implementation of an Object-Oriented programming system.
+%globals.METAMETHOD_MAP = {..}
+ "as text": "__tostring", "clean up": "__gc",
+ "+ 1": "__add", "- 1": "__sub", "* 1": "__mul", "/ 1": "__div",
+ "-": "__unm", "// 1": "__idiv", "mod 1": "__mod", "^ 1": "__pow",
+ "& 1": "__band", "| 1": "__bor", "~ 1": "__bxor", "~": "__bnot",
+ "<< 1": "__bshl", ">> 1": "__bshr", "== 1": "__eq", "< 1": "__lt",
+ "<= 1": "__le", "set 1 = 2": "__newindex", "size": "__len",
+ "iterate": "__ipairs", "iterate all": "__pairs",
+
test:
object (Dog):
(Dog).genus = "Canus"
@@ -86,9 +95,7 @@ compile [object %classname extends %parent %class_body] to:
__tostring=function(cls) return cls.name end,
__call=function(cls, inst)
inst = setmetatable(inst or {}, cls)
- if inst.set_up then
- inst:set_up()
- end
+ if inst.set_up then inst:set_up() end
return inst
end,
})
@@ -100,15 +107,7 @@ compile [object %classname extends %parent %class_body] to:
return inst.name..getmetatable(_Dict{}).__tostring(inst)
end
\(%class_body as lua statements)
- local metamethod_map = {["as text"]="__tostring", ["clean up"]="__gc",
- ["+ 1"]="__add", ["- 1"]="__sub", ["* 1"]="__mul", ["/ 1"]="__div",
- ["-"]="__unm", ["// 1"]="__idiv", ["mod 1"]="__mod", ["^ 1"]="__pow",
- ["& 1"]="__band", ["| 1"]="__bor", ["~ 1"]="__bxor", ["~"]="__bnot",
- ["<< 1"]="__bshl", [">> 1"]="__bshr", ["== 1"]="__eq", ["< 1"]="__lt",
- ["<= 1"]="__le", ["set 1 = 2"]="__newindex", ["size"]="__len",
- ["iterate"]="__ipairs", ["iterate all"]="__pairs",
- }
- for stub,metamethod in pairs(metamethod_map) do
+ for stub,metamethod in pairs(globals.METAMETHOD_MAP) do
class[metamethod] = class[stub:as_lua_id()]
end
end"
diff --git a/nomnom/decompile.nom b/nomnom/decompile.nom
index 54afb08..fb64f7c 100644
--- a/nomnom/decompile.nom
+++ b/nomnom/decompile.nom
@@ -52,7 +52,7 @@ action [%tree decompiled inline]:
return %nomsu
"Text":
- %nomsu = (Nomsu Code from %tree ["\""])
+ %nomsu = (Nomsu Code from %tree [])
for %text in recursive %tree:
for %bit in %text at %i:
if (%bit is text):
@@ -87,14 +87,14 @@ action [%tree decompiled inline]:
"DictEntry":
set {%key:%tree.1, %value:%tree.2}
if (all of [%key.type == "Text", (size of %key) == 1, %key.1 is a nomsu identifier]):
- %nomsu = (Nomsu Code from %key [key.1])
+ %nomsu = (Nomsu Code from %key [%key.1])
..else:
%nomsu = (%key decompiled inline)
if (%key.type == "Action"):
%nomsu::parenthesize
- %nomsu::add ":"
if %value:
+ %nomsu::add ":"
%nomsu::add (%value decompiled inline)
return %nomsu
diff --git a/nomsu.4.peg b/nomsu.4.peg
index 32a170f..06bfead 100644
--- a/nomsu.4.peg
+++ b/nomsu.4.peg
@@ -8,6 +8,8 @@ file:
shebang: "#!" (!"nomsu" [^%nl])* "nomsu" ws+ "-V" ws* {:version: [0-9.]+ :} [^%nl]*
+eof: !.
+
file_chunks (FileChunks):
{:curr_indent: ' '* :}
shebang? comment? blank_lines?
@@ -71,7 +73,7 @@ tab_error (Error):
section_division: ("~")^+3 eol
inline_block:
- "(" ws* inline_block ws* ")" / raw_inline_block
+ "(" ws* inline_block ws* (eof / ")") / raw_inline_block
raw_inline_block (Block):
(!"::") ":" ws* ((inline_statement (ws* ";" ws* inline_statement)*) / !(eol nl_indent))
indented_block (Block):
@@ -89,7 +91,7 @@ noindex_inline_expression:
/ ( "("
ws* (inline_action / inline_expression) ws*
(ws* ',' ws* (inline_action / inline_expression) ws*)*
- (")" / missing_paren_err / unexpected_code)
+ (")" / eof / missing_paren_err / unexpected_code)
)
inline_expression: index_chain / noindex_inline_expression
indented_expression:
@@ -130,7 +132,7 @@ text_word (Text): word
inline_text (Text):
!(indented_text)
- '"' _inline_text* ('"' / missing_quote_err / unexpected_code)
+ '"' _inline_text* ('"' / eof / missing_quote_err / unexpected_code)
_inline_text:
{~ (('\"' -> '"') / ('\\' -> '\') / escaped_char / text_char+)+ ~}
/ inline_text_interpolation / illegal_char
@@ -140,7 +142,7 @@ inline_text_interpolation:
/ ("("
ws* (inline_action / inline_expression) ws*
(ws* ',' ws* (inline_action / inline_expression) ws*)*
- (")" / missing_paren_err / unexpected_code))
+ (")" / eof / missing_paren_err / unexpected_code))
)
text_char: %utf8_char / !["\] %print / %tab
@@ -156,7 +158,7 @@ indented_text (Text):
(('\' %nl+ {:curr_indent: indent :} ('..')?)
/ disallowed_interpolation? {%nl+} {:curr_indent: indent :})
(indented_plain_text / text_interpolation / illegal_char / {~ %nl+ (=curr_indent -> "") ~})*
- ('"' eol / missing_quote_err)
+ ('"' eol / eof / missing_quote_err)
{:curr_indent: %nil :}
-- Tracking text-lines-within-indented-text as separate objects allows for better debugging line info
indented_plain_text (Text):
@@ -180,7 +182,7 @@ inline_list (List):
!('[..]')
"[" ws*
(inline_list_item (ws* ',' ws* inline_list_item)* (ws* ',')?)? ws*
- ("]" / (","? (missing_bracket_error / unexpected_code)))
+ ("]" / eof / (","? (missing_bracket_error / unexpected_code)))
indented_list (List):
"[..]" eol nl_indent
list_line (nl_nodent list_line)*
@@ -195,7 +197,7 @@ inline_dict (Dict):
!('{..}')
"{" ws*
(inline_dict_entry (ws* ',' ws* inline_dict_entry)*)? ws*
- ("}" / (","? (missing_brace_error / unexpected_code)))
+ ("}" / eof / (","? (missing_brace_error / unexpected_code)))
indented_dict (Dict):
"{..}" eol nl_indent
dict_line (nl_nodent dict_line)*
diff --git a/nomsu_compiler.lua b/nomsu_compiler.lua
index ff923ab..3d0580a 100644
--- a/nomsu_compiler.lua
+++ b/nomsu_compiler.lua
@@ -129,17 +129,21 @@ make_tree = function(tree, userdata)
return tree
end
local Parsers = { }
-local max_parser_version = 0
-for version = 1, 999 do
- do
- local peg_contents = Files.read("nomsu." .. tostring(version) .. ".peg")
- if peg_contents then
- max_parser_version = version
- Parsers[version] = make_parser(peg_contents, make_tree)
- else
- break
+local max_parser_version = 4
+for version = 1, max_parser_version do
+ local peg_file = io.open("nomsu." .. tostring(version) .. ".peg")
+ if not peg_file and package.nomsupath then
+ for path in package.nomsupath:gmatch("[^;]+") do
+ peg_file = io.open(path .. "/nomsu." .. tostring(version) .. ".peg")
+ if peg_file then
+ break
+ end
end
end
+ assert(peg_file, "could not find nomsu .peg file")
+ local peg_contents = peg_file:read('*a')
+ peg_file:close()
+ Parsers[version] = make_parser(peg_contents, make_tree)
end
local MAX_LINE = 80
local NomsuCompiler = setmetatable({ }, {
@@ -199,9 +203,8 @@ do
re = re,
Files = Files,
AST = AST,
- TESTS = Dict({ }, {
- globals = Dict({ })
- }),
+ TESTS = Dict({ }),
+ globals = Dict({ }),
LuaCode = LuaCode,
NomsuCode = NomsuCode,
Source = Source,
@@ -209,6 +212,7 @@ do
__imported = Dict({ }),
__parent = nil
}
+ assert(NomsuCompiler.environment.globals)
setmetatable(NomsuCompiler.environment, {
__index = function(self, key)
do
diff --git a/nomsu_compiler.moon b/nomsu_compiler.moon
index e91db80..83cba68 100644
--- a/nomsu_compiler.moon
+++ b/nomsu_compiler.moon
@@ -77,12 +77,17 @@ make_tree = (tree, userdata)->
return tree
Parsers = {}
-max_parser_version = 0
-for version=1,999
- if peg_contents = Files.read("nomsu.#{version}.peg")
- max_parser_version = version
- Parsers[version] = make_parser(peg_contents, make_tree)
- else break
+max_parser_version = 4
+for version=1,max_parser_version
+ peg_file = io.open("nomsu.#{version}.peg")
+ if not peg_file and package.nomsupath
+ for path in package.nomsupath\gmatch("[^;]+")
+ peg_file = io.open(path.."/nomsu.#{version}.peg")
+ break if peg_file
+ assert(peg_file, "could not find nomsu .peg file")
+ peg_contents = peg_file\read('*a')
+ peg_file\close!
+ Parsers[version] = make_parser(peg_contents, make_tree)
MAX_LINE = 80 -- For beautification purposes, try not to make lines much longer than this value
NomsuCompiler = setmetatable {}, {__tostring: => "Nomsu"}
@@ -105,12 +110,13 @@ with NomsuCompiler
_List:List, _Dict:Dict,
-- Utilities and misc.
stringify:stringify, utils:utils, lpeg:lpeg, re:re, Files:Files,
- :AST, TESTS: Dict{}, globals: Dict{}
+ :AST, TESTS: Dict({}), globals: Dict({}),
:LuaCode, :NomsuCode, :Source
nomsu:NomsuCompiler
__imported: Dict{}
__parent: nil
}
+ assert .environment.globals
setmetatable(.environment, {
__index: (key)=>
if imported = rawget(@, "__imported")
diff --git a/tools/find_action.nom b/tools/find_action.nom
index 8381855..e30f155 100755
--- a/tools/find_action.nom
+++ b/tools/find_action.nom
@@ -23,8 +23,8 @@ for %path in %files:
%results::add {..}
line: %line_num
text: "\
- ..\(blue "\%filename:\%line_num:")
- \(yellow (source lines of %t))"
+ ..\(blue "\%filename:\%line_num:")
+ \(yellow (source lines of %t))"
if (%t is syntax tree):
for %sub in %t: recurse %t on %sub