aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--code_obj.lua7
-rw-r--r--code_obj.moon6
-rw-r--r--compatibility/2.4.nom2
-rw-r--r--compatibility/2.nom2
-rw-r--r--core/collections.nom15
-rw-r--r--core/control_flow.nom20
-rw-r--r--core/errors.nom4
-rw-r--r--core/metaprogramming.nom116
-rw-r--r--core/text.nom2
-rw-r--r--lib/object.nom77
-rw-r--r--lib/os.nom1
-rw-r--r--nomsu.2.peg2
-rw-r--r--nomsu_compiler.lua53
-rw-r--r--nomsu_compiler.moon41
-rw-r--r--syntax_tree.lua12
-rw-r--r--syntax_tree.moon6
-rwxr-xr-xtools/find_action.nom2
-rwxr-xr-xtools/upgrade.nom1
19 files changed, 227 insertions, 144 deletions
diff --git a/README.md b/README.md
index 46e62e8..9d0f569 100644
--- a/README.md
+++ b/README.md
@@ -46,7 +46,7 @@ All `.moon` files have been precompiled into corresponding `.lua` files, so you
* `nomsu` - A shell script that selects between different installed versions of Nomsu (using the `-V` flag). You can use this script to, for example, run `nomsu -V 1.2 your_script.nom` to run with the latest version of Nomsu that matches `1.2.?.?`. All flags and arguments are passed along to whichever Nomsu compiler is chosen.
* `nomsu.moon` - The source code for the Nomsu command line runner. This handles launching the compiler and running the REPL.
-* `nomsu.peg` - The [Parsing Expression Grammar](https://en.wikipedia.org/wiki/Parsing_expression_grammar) used to define Nomsu's syntax. The format of this file is a slightly modified version of the format accepted by LPEG's `re` module.
+* `nomsu.*.peg` - The [Parsing Expression Grammar](https://en.wikipedia.org/wiki/Parsing_expression_grammar) used to define each version of Nomsu's syntax. The format of this file is a slightly modified version of the format accepted by LPEG's `re` module.
* `nomsu_compiler.moon` - **The actual Nomsu compiler**. This file can be imported and used without going through the regular command line interface (e.g. for applications that want to embed the compiler).
* `parser.moon` - The Nomsu parser. This file can also be imported and used directly for applications that only need to *parse* Nomsu, not compile it.
* `syntax_tree.moon` - Datastructures used for Nomsu Abstract Syntax Trees.
diff --git a/code_obj.lua b/code_obj.lua
index 11f78b2..686cc7f 100644
--- a/code_obj.lua
+++ b/code_obj.lua
@@ -132,13 +132,13 @@ do
_continue_0 = true
break
end
- bits[#bits + 1] = b
if b.is_code then
b.dirty = error
end
if type(b) ~= 'string' and not (type(b) == 'table' and b.is_code) then
b = repr(b)
end
+ bits[#bits + 1] = b
_continue_0 = true
until true
if not _continue_0 then
@@ -210,10 +210,13 @@ do
end
for i = 1, n do
local b = select(i, ...)
- bits[i] = b
if b.is_code then
b.dirty = error
end
+ if type(b) ~= 'string' and not (type(b) == 'table' and b.is_code) then
+ b = repr(b)
+ end
+ bits[i] = b
end
return self:dirty()
end,
diff --git a/code_obj.moon b/code_obj.moon
index 996a228..7752de6 100644
--- a/code_obj.moon
+++ b/code_obj.moon
@@ -86,10 +86,10 @@ class Code
assert(b, "code bit is nil")
assert(not Source\is_instance(b), "code bit is a Source")
if b == '' then continue
- bits[#bits+1] = b
b.dirty = error if b.is_code
if type(b) != 'string' and not (type(b) == 'table' and b.is_code)
b = repr(b)
+ bits[#bits+1] = b
@dirty!
trailing_line_len: =>
@@ -141,8 +141,10 @@ class Code
bits[i] = bits[i-n]
for i=1,n
b = select(i, ...)
- bits[i] = b
b.dirty = error if b.is_code
+ if type(b) != 'string' and not (type(b) == 'table' and b.is_code)
+ b = repr(b)
+ bits[i] = b
@dirty!
parenthesize: =>
diff --git a/compatibility/2.4.nom b/compatibility/2.4.nom
index 2c5cc8e..088e320 100644
--- a/compatibility/2.4.nom
+++ b/compatibility/2.4.nom
@@ -55,7 +55,7 @@ upgrade %tree to "2.4" as:
add %line.2 to %values
%action = %line.3
unless (%action is "Block" syntax tree):
- %action = (=lua "Block(\%action.source, \%action)")
+ %action = \(: %action)
add %action to %values
add (=lua "Action(\%values[1].source, unpack(\%values))") to %new_lines
%values = []
diff --git a/compatibility/2.nom b/compatibility/2.nom
index 399d485..53d9988 100644
--- a/compatibility/2.nom
+++ b/compatibility/2.nom
@@ -9,7 +9,7 @@ upgrade %tree to "2" as:
if (%tree.stub is "if % % else %"):
%true_body = (%tree.3 upgraded)
unless (%true_body is "Block" syntax tree):
- %true_body = (=lua "Block(\%true_body.source, \%true_body)")
+ %true_body = \(: %true_body)
%false_body = (%tree.5 upgraded)
unless (%false_body is "Block" syntax tree):
%false_body = (=lua "Block(\%false_body.source, \%false_body)")
diff --git a/core/collections.nom b/core/collections.nom
index 8553d66..8270f62 100644
--- a/core/collections.nom
+++ b/core/collections.nom
@@ -191,11 +191,16 @@ test:
assume (({} with fallback % -> (% + 1)).10 == 11)
compile [%dict with fallback %key -> %value] to (..)
Lua value ".."
- setmetatable(\(%dict as lua expr), {__index=function(self, \(%key as lua expr))
- local value = \(%value as lua expr)
- self[\(%key as lua expr)] = value
- return value
- end})
+ (function(d)
+ local mt = {}
+ for k,v in pairs(getmetatable(d) or {}) do mt[k] = v end
+ mt.__index = function(self, \(%key as lua expr))
+ local value = \(%value as lua expr)
+ self[\(%key as lua expr)] = value
+ return value
+ end
+ return setmetatable(d, mt)
+ end)(\(%dict as lua expr))
# Sorting
test:
diff --git a/core/control_flow.nom b/core/control_flow.nom
index 703c438..5210519 100644
--- a/core/control_flow.nom
+++ b/core/control_flow.nom
@@ -206,10 +206,10 @@ compile [..]
if (%body has subtree \(do next)):
to %lua write "\n ::continue::"
- if (%body has subtree (\(do next %v) with vars {v:%var})):
+ if (%body has subtree \(do next %var)):
to %lua write "\n \(compile as (===next %var ===))"
to %lua write "\nend --numeric for-loop"
- if (%body has subtree (\(stop %v) with vars {v:%var})):
+ if (%body has subtree \(stop %var)):
%lua = (..)
Lua ".."
do -- scope for stopping for-loop
@@ -249,10 +249,10 @@ compile [for %var in %iterable %body] to:
if (%body has subtree \(do next)):
to %lua write "\n ::continue::"
- if (%body has subtree (\(do next %v) with vars {v:%var})):
+ if (%body has subtree \(do next %var)):
to %lua write (Lua "\n\(compile as (===next %var ===))")
to %lua write "\nend --foreach-loop"
- if (%body has subtree (\(stop %v) with vars {v:%var})):
+ if (%body has subtree \(stop %var)):
%lua = (..)
Lua ".."
do -- scope for stopping for-loop
@@ -290,15 +290,15 @@ compile [..]
if (%body has subtree \(do next)):
to %lua write "\n ::continue::"
- if (%body has subtree (\(do next %v) with vars {v:%key})):
+ if (%body has subtree \(do next %key)):
to %lua write (Lua "\n\(compile as (===next %key ===))")
- if (%body has subtree (\(do next %v) with vars {v:%value})):
+ if (%body has subtree \(do next %value)):
to %lua write (Lua "\n\(compile as (===next %value ===))")
to %lua write "\nend --foreach-loop"
%stop_labels = (Lua "")
- if (%body has subtree (\(stop %v) with vars {v:%key})):
+ if (%body has subtree \(stop %key)):
to %stop_labels write "\n\(compile as (===stop %key ===))"
- if (%body has subtree (\(stop %v) with vars {v:%value})):
+ if (%body has subtree \(stop %value)):
to %stop_labels write "\n\(compile as (===stop %value ===))"
if ((length of "\%stop_labels") > 0):
%lua = (..)
@@ -505,10 +505,10 @@ compile [for %var in recursive %structure %body] to (..)
if (%body has subtree \(do next)):
to %lua write "\n ::continue::"
- if (%body has subtree (\(do next %v) with vars {v:%var})):
+ if (%body has subtree \(do next %var)):
to %lua write "\n \(compile as (===next %var ===))"
to %lua write "\n end -- Recursive loop"
- if (%body has subtree (\(stop %v) with vars {v:%var})):
+ if (%body has subtree \(stop %var)):
to %lua write "\n \(compile as (===stop %var ===))"
to %lua write "\nend -- Recursive scope"
return %lua
diff --git a/core/errors.nom b/core/errors.nom
index d8c23b8..899b30b 100644
--- a/core/errors.nom
+++ b/core/errors.nom
@@ -7,11 +7,11 @@ use "core/metaprogramming.nom"
compile [barf] to (Lua "error(nil, 0);")
compile [barf %msg] to (Lua "error(\(%msg as lua expr), 0);")
compile [compile error at %source %msg] to (..)
- Lua "nomsu:compile_error(\(%source as lua expr), \(%msg as lua expr))"
+ Lua "_ENV:compile_error(\(%source as lua expr), \(%msg as lua expr))"
compile [assume %condition] to:
lua> ".."
- local \%assumption = 'Assumption failed: '..tostring(nomsu:tree_to_nomsu(\%condition))
+ local \%assumption = 'Assumption failed: '..tostring(_ENV:tree_to_nomsu(\%condition))
return (..)
Lua ".."
if not \(%condition as lua expr) then
diff --git a/core/metaprogramming.nom b/core/metaprogramming.nom
index 153a0bf..968ed39 100644
--- a/core/metaprogramming.nom
+++ b/core/metaprogramming.nom
@@ -5,12 +5,12 @@
lua> "NOMSU_CORE_VERSION = 5"
lua> ".."
- nomsu.COMPILE_ACTIONS["% -> %"] = function(nomsu, tree, \%args, \%body)
+ COMPILE_ACTIONS["% -> %"] = function(nomsu, tree, \%args, \%body)
local lua = LuaCode.Value(tree.source, "(function(")
if AST.is_syntax_tree(\%args, "Action") then \%args = \%args:get_args() end
- local lua_args = table.map(\%args, function(a) return AST.is_syntax_tree(a) and tostring(nomsu:compile(a)) or a end)
+ local lua_args = table.map(\%args, function(a) return AST.is_syntax_tree(a) and tostring(_ENV:compile(a)) or a end)
lua:concat_append(lua_args, ", ")
- local body_lua = AST.is_syntax_tree(\%body) and nomsu:compile(\%body):as_statements("return ") or \%body
+ local body_lua = AST.is_syntax_tree(\%body) and _ENV:compile(\%body):as_statements("return ") or \%body
body_lua:remove_free_vars(lua_args)
body_lua:declare_locals()
lua:append(")\\n ", body_lua, "\\nend)")
@@ -18,9 +18,9 @@ lua> ".."
end
lua> ".."
- nomsu.COMPILE_ACTIONS["compile as %"] = function(nomsu, tree, \%action)
- local lua = LuaCode.Value(tree.source, "nomsu.COMPILE_ACTIONS[", repr(\%action.stub), "](")
- local lua_args = table.map(\%action:get_args(), function(a) return nomsu:compile(a) end)
+ COMPILE_ACTIONS["compile as %"] = function(nomsu, tree, \%action)
+ local lua = LuaCode.Value(tree.source, "COMPILE_ACTIONS[", repr(\%action.stub), "](")
+ local lua_args = table.map(\%action:get_args(), function(a) return _ENV:compile(a) end)
table.insert(lua_args, 1, "nomsu")
table.insert(lua_args, 2, "tree")
lua:concat_append(lua_args, ", ")
@@ -48,22 +48,22 @@ test:
asdf
assume (%tmp is (nil)) or barf "compile to is leaking variables"
lua> ".."
- nomsu.COMPILE_ACTIONS["compile % to %"] = function(nomsu, tree, \%actions, \%body)
- local \%args = {"nomsu", "tree", unpack(table.map(\%actions[1]:get_args(), function(a) return tostring(nomsu:compile(\
+ COMPILE_ACTIONS["compile % to %"] = function(nomsu, tree, \%actions, \%body)
+ local \%args = {"nomsu", "tree", unpack(table.map(\%actions[1]:get_args(), function(a) return tostring(_ENV:compile(\
..a)) end))}
- local lua = LuaCode(tree.source, "nomsu.COMPILE_ACTIONS[", repr(\%actions[1].stub),
+ local lua = LuaCode(tree.source, "COMPILE_ACTIONS[", repr(\%actions[1].stub),
"] = ", \(compile as (%args -> %body)))
for i=2,#\%actions do
local alias = \%actions[i]
- local \%alias_args = {"nomsu", "tree", unpack(table.map(alias:get_args(), function(a) return tostring(nomsu:compile(\
+ local \%alias_args = {"nomsu", "tree", unpack(table.map(alias:get_args(), function(a) return tostring(_ENV:compile(\
..a)) end))}
- lua:append("\\nnomsu.COMPILE_ACTIONS[", repr(alias.stub), "] = ")
+ lua:append("\\nCOMPILE_ACTIONS[", repr(alias.stub), "] = ")
if utils.equivalent(\%args, \%alias_args) then
- lua:append("nomsu.COMPILE_ACTIONS[", repr(\%actions[1].stub), "]")
+ lua:append("COMPILE_ACTIONS[", repr(\%actions[1].stub), "]")
else
lua:append("function(")
lua:concat_append(\%alias_args, ", ")
- lua:append(")\\n return nomsu.COMPILE_ACTIONS[", repr(\%actions[1].stub), "](")
+ lua:append(")\\n return COMPILE_ACTIONS[", repr(\%actions[1].stub), "](")
lua:concat_append(\%args, ", ")
lua:append(")\\nend")
end
@@ -75,8 +75,8 @@ lua> ".."
compile [call %fn with %args] to (..)
lua> ".."
- local lua = LuaCode.Value(tree.source, nomsu:compile(\%fn), "(")
- lua:concat_append(table.map(\%args, function(a) return nomsu:compile(a) end), ", ")
+ local lua = LuaCode.Value(tree.source, _ENV:compile(\%fn), "(")
+ lua:concat_append(table.map(\%args, function(a) return _ENV:compile(a) end), ", ")
lua:append(")")
return lua
@@ -95,14 +95,14 @@ test:
compile [local action %actions %body] to (..)
lua> ".."
local fn_name = "A"..string.as_lua_id(\%actions[1].stub)
- local \%args = table.map(\%actions[1]:get_args(), function(a) return tostring(nomsu:compile(a)) end)
+ local \%args = table.map(\%actions[1]:get_args(), function(a) return tostring(_ENV:compile(a)) end)
local lua = LuaCode(tree.source, fn_name, " = ", \(compile as (%args -> %body)))
lua:add_free_vars({fn_name})
for i=2,#\%actions do
local alias = \%actions[i]
local alias_name = "A"..string.as_lua_id(alias.stub)
lua:add_free_vars({alias_name})
- local \%alias_args = table.map(alias:get_args(), function(a) return tostring(nomsu:compile(a)) end)
+ local \%alias_args = table.map(alias:get_args(), function(a) return tostring(_ENV:compile(a)) end)
lua:append("\\n", alias_name, " = ")
if utils.equivalent(\%args, \%alias_args) then
lua:append(fn_name)
@@ -151,7 +151,7 @@ compile [parse %actions as %body] to (..)
lua> ".."
local replacements = {}
for i,arg in ipairs(\%actions[1]:get_args()) do
- replacements[arg[1]] = tostring(nomsu:compile(arg))
+ replacements[arg[1]] = tostring(_ENV:compile(arg))
end
local function make_tree(t)
if not AST.is_syntax_tree(t) then
@@ -168,7 +168,7 @@ compile [parse %actions as %body] to (..)
local \%new_body = LuaCode(\%body.source,
"__MANGLE_INDEX = (__MANGLE_INDEX or 0) + 1",
"\\nlocal tree = ", make_tree(\%body),
- "\\nlocal lua = nomsu:compile(tree); return lua")
+ "\\nlocal lua = _ENV:compile(tree); return lua")
local ret = \(compile as (compile %actions to %new_body))
return ret
@@ -176,33 +176,33 @@ compile [parse %actions as %body] to (..)
action [%tree as lua expr]:
lua> ".."
- \%tree_lua = nomsu:compile(\%tree)
+ \%tree_lua = _ENV:compile(\%tree)
if not \%tree_lua.is_value then
- nomsu:compile_error(\%tree.source, "Could not convert %s to a Lua expression",
- nomsu:tree_to_nomsu(\%tree))
+ _ENV:compile_error(\%tree.source, "Could not convert %s to a Lua expression",
+ _ENV:tree_to_nomsu(\%tree))
end
return \%tree_lua
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-compile [%tree as lua] to (Lua value "nomsu:compile(\(%tree as lua expr))")
+compile [%tree as lua] to (Lua value "_ENV:compile(\(%tree as lua expr))")
compile [%tree as lua statements] to (..)
- Lua value "nomsu:compile(\(%tree as lua expr)):as_statements()"
+ Lua value "_ENV:compile(\(%tree as lua expr)):as_statements()"
compile [%tree as lua return] to (..)
- Lua value "nomsu:compile(\(%tree as lua expr)):as_statements('return ')"
+ Lua value "_ENV:compile(\(%tree as lua expr)):as_statements('return ')"
compile [remove action %action] to (..)
Lua "A\(=lua "string.as_lua_id(\(%action.stub))") = nil"
test:
- assume ("\(\(foo %x) as nomsu)" == "foo %x") or barf ".."
+ assume ("\(\(foo \%x) as nomsu)" == "foo %x") or barf ".."
action source code failed.
compile [%tree as nomsu] to (..)
- Lua value "nomsu:tree_to_nomsu(\(%tree as lua expr))"
+ Lua value "_ENV: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 "_ENV:tree_to_nomsu(\(%tree as lua expr), true)"
action [%var as lua identifier, %var as lua id] (..)
lua> ".."
@@ -231,6 +231,14 @@ action [%tree with vars %replacements] (..)
end
end)
+compile [tree %tree with vars %replacements] to (..)
+ Lua value ".."
+ \(=lua "repr(\%tree)"):map(function(t)
+ if t.type == "Var" then
+ return \(%replacements as lua expr)[t[1]]
+ end
+ end)
+
compile [%tree has subtree %match_tree] to (..)
Lua value ".."
(function()
@@ -240,6 +248,39 @@ compile [%tree has subtree %match_tree] to (..)
end
end)()
+action [match %tree with %patt]:
+ lua> ".."
+ if \%patt.type == "Var" then return dict{[\%patt[1]]=\%tree} end
+ if \%patt.type == "Action" and \%patt.stub ~= \%tree.stub then return nil end
+ if #\%patt ~= #\%tree then return nil end
+ local matches = dict{}
+ for \%i=1,#\%patt do
+ if AST.is_syntax_tree(\%tree[\%i]) then
+ local submatch = \(match %tree.%i with %patt.%i)
+ if not submatch then return nil end
+ for k,v in pairs(submatch) do
+ if matches[k] and matches[k] ~= v then return nil end
+ matches[k] = v
+ end
+ end
+ end
+ return matches
+
+action [%tree with %patt ~> %replacement]:
+ lua> ".."
+ return \%tree:map(function(\%t)
+ local \%vars = \(match %t with %patt)
+ if not \%vars then return nil end
+ for \%k,\%v in pairs(\%vars) do
+ \%vars[\%k] = \(%v with %patt ~> %replacement)
+ end
+ return \%replacement:map(function(\%t)
+ if \%t.type == "Var" then
+ return \%vars[\%t[1]]
+ end
+ end)
+ end)
+
compile [declare locals in %code] to (..)
Lua value "\(%code as lua expr):declare_locals()"
@@ -275,11 +316,12 @@ compile [type of %obj] to (Lua value "type(\(%obj as lua expr))")
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test:
- assume ((parse "foo %") == \(foo %))
-compile [parse %text] to (Lua value "nomsu:parse(\(%text as lua expr))")
+ assume ((parse "foo %") == \(foo \%))
+ assume ((parse "\\1") == \\1)
+compile [parse %text] to (Lua value "_ENV:parse(\(%text as lua expr))")
compile [parse %text from %filename] to (..)
Lua value ".."
- nomsu:parse(NomsuCode(Source(\(%filename as lua expr), 1, #\(%text as lua expr)), \(..)
+ _ENV:parse(NomsuCode(Source(\(%filename as lua expr), 1, #\(%text as lua expr)), \(..)
%text as lua expr
..))
@@ -287,19 +329,19 @@ test:
assume ((run "return (2 + 99)") == 101)
external %passed = (no)
run \:
- external %passed = (yes)
+ \(external \%passed = \(yes))
assume %passed
compile [run %nomsu_code] to (..)
Lua value ".."
- nomsu:run(\(%nomsu_code as lua expr), \(..)
+ _ENV:run(\(%nomsu_code as lua expr), \(..)
=lua "repr(tostring(\(%nomsu_code.source)))"
..)
test:
- assume ((\(5 + 5) as value) == 10) or barf "%tree as value failed."
-action [run tree %tree, %tree as value] (lua> "return nomsu:run(\%tree)")
+ assume ((\(\5 + \5) as value) == 10) or barf "%tree as value failed."
+action [run tree %tree, %tree as value] (lua> "return _ENV:run(\%tree)")
compile [compile %block, compiled %block, %block compiled] to (..)
- Lua value "nomsu:compile(\(%block as lua))"
+ Lua value "_ENV:compile(\(%block as lua))"
# Return statement is wrapped in a do..end block because Lua is unhappy if you
put code after a return statement, unless you wrap it in a block.
@@ -322,7 +364,7 @@ compile [command line args] to (Lua value "arg")
compile [with local compile actions %body] to (..)
Lua ".."
do
- local nomsu = table.fork(nomsu, {COMPILE_ACTIONS=table.fork(nomsu.COMPILE_ACTIONS)})
+ local nomsu = table.fork(nomsu, {COMPILE_ACTIONS=table.fork(COMPILE_ACTIONS)})
\(%body as lua statements)
end
diff --git a/core/text.nom b/core/text.nom
index 701b1cd..a82e9df 100644
--- a/core/text.nom
+++ b/core/text.nom
@@ -124,7 +124,7 @@ lua> ".."
};
for name, e in pairs(escapes) do
local lua = "'"..e.."'"
- nomsu.COMPILE_ACTIONS[name] = function(nomsu, tree)
+ COMPILE_ACTIONS[name] = function(nomsu, tree)
return LuaCode.Value(tree.source, lua)
end
end
diff --git a/lib/object.nom b/lib/object.nom
index dd99109..ddbb2b5 100644
--- a/lib/object.nom
+++ b/lib/object.nom
@@ -35,23 +35,34 @@ test:
assume ((me).barks == 101) or barf ".."
Error in nested 'as % %' failed to properly reset 'self'
- object "Corgi" extends (class Dog) (method [sploot] "splooted")
+ object "Corgi" extends (class Dog):
+ method [sploot] "splooted"
+ method [bark, woof]:
+ %barks = ("Yip!" for % in 1 to (me).barks)
+ return (%barks joined with " ")
+
%corg = (new Corgi)
assume (%corg.barks == 0)
as (new Corgi {barks:1}):
assume ((sploot) == "splooted") or barf "subclass method failed"
- assume ((bark) == "Bark!") or barf "inheritance failed"
- assume ((woof) == "Bark!")
+ assume ((bark) == "Yip!") or barf "inheritance failed"
+ assume ((woof) == "Yip!")
+
+ as (new Dog {barks:2}):
+ assume ((bark) == "Bark! Bark!")
+
compile [@, me] to (Lua value "self")
compile [method %actions %body] to:
- %lua = (compile as (local action %actions %body))
+ %lua = (\(local action \[%actions.1] %body) as lua)
+ declare locals in %lua
for % in %actions:
- to %lua write "\nclass.\(% as lua id) = \(% as lua id)"
- return (..)
+ to %lua write "\n\(\%class as lua id).\(% as lua id) = \(%actions.1 as lua id)"
+ %lua = (..)
Lua ".."
do -- Method: \(%actions.(1).stub)
\%lua
end
+ return %lua
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -64,33 +75,35 @@ parse [as %instance %body] as (..)
barf %msg
..or if it succeeds: (me) = %old_self
-compile [object %classname extends %parent %class_body] to (..)
- Lua ".."
- do
- local class = {name=\(%classname as lua expr)}
- setmetatable(class, {
- __index=\(%parent as lua expr),
- __tostring=function(cls) return cls.name end,
- __call=function(cls, inst)
- inst = setmetatable(inst or {}, cls)
- if cls.A_initialize_1 then
- cls.A_initialize_1(inst)
- end
- return inst
- end,
- })
- _ENV["A"..string.as_lua_id("new "..class.name)] = class
- _ENV["A"..string.as_lua_id("new "..class.name.." 1")] = class
- _ENV["A"..string.as_lua_id("class "..class.name)] = function() return class end
- class.__index = class
- class.class = class
-
- \(%class_body as lua statements)
-
- class.__tostring = class["A"..string.as_lua_id("as text")] or function(inst)
- return inst.name..getmetatable(dict{}).__tostring(inst)
+compile [object %classname extends %parent %class_body] to:
+ %class = (\%class as lua id)
+ return (..)
+ Lua ".."
+ do
+ local \%class = {name=\(%classname as lua expr)}
+ setmetatable(\%class, {
+ __index=\(%parent as lua expr),
+ __tostring=function(cls) return cls.name end,
+ __call=function(cls, inst)
+ inst = setmetatable(inst or {}, cls)
+ if cls.A_initialize_1 then
+ cls.A_initialize_1(inst)
+ end
+ return inst
+ end,
+ })
+ _ENV["A"..string.as_lua_id("new "..\%class.name)] = \%class
+ _ENV["A"..string.as_lua_id("new "..\%class.name.." 1")] = \%class
+ _ENV["A"..string.as_lua_id("class "..\%class.name)] = function() return \%class end
+ \%class.__index = \%class
+ \%class.class = \%class
+
+ \(%class_body as lua statements)
+
+ \%class.__tostring = \%class["A"..string.as_lua_id("as text")] or function(inst)
+ return inst.name..getmetatable(dict{}).__tostring(inst)
+ end
end
- end
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/lib/os.nom b/lib/os.nom
index 8bbc7c5..03d9657 100644
--- a/lib/os.nom
+++ b/lib/os.nom
@@ -43,6 +43,7 @@ action [..]
write to file %filename %text, to file %filename write %text
write %text to file %filename
..:
+ assume (%filename != "stdin") or barf "Cannot write to stdin"
lua> ".."
local file = io.open(\%filename, 'w')
file:write(\%text)
diff --git a/nomsu.2.peg b/nomsu.2.peg
index 4f9c4c4..ce4d2d7 100644
--- a/nomsu.2.peg
+++ b/nomsu.2.peg
@@ -5,7 +5,7 @@ file:
/ file_chunks / empty_block)
%ws* (!! .+ -> "Parse error" !!)?
-shebang: "#!" (!"nomsu" [^%nl])* "nomsu" %ws+ "-V" %ws* {:version: [0-9.]+ :} [^%nl]*
+shebang: {:shebang: "#!" (!"nomsu" [^%nl])* "nomsu" %ws+ "-V" %ws* {:version: [0-9.]+ :} [^%nl]* :}
file_chunks (FileChunks):
{:curr_indent: ' '* :}
diff --git a/nomsu_compiler.lua b/nomsu_compiler.lua
index 6692fe3..c3c21af 100644
--- a/nomsu_compiler.lua
+++ b/nomsu_compiler.lua
@@ -145,7 +145,9 @@ dict = function(t)
return setmetatable(t, _dict_mt)
end
local MAX_LINE = 80
-local NomsuCompiler = setmetatable({ }, {
+local NomsuCompiler = setmetatable({
+ name = "Nomsu"
+}, {
__index = function(self, k)
do
local _self = rawget(self, "self")
@@ -155,13 +157,14 @@ local NomsuCompiler = setmetatable({ }, {
return nil
end
end
+ end,
+ __tostring = function(self)
+ return self.name
end
})
do
NomsuCompiler.NOMSU_COMPILER_VERSION = 5
NomsuCompiler.NOMSU_SYNTAX_VERSION = Parser.version
- NomsuCompiler._ENV = NomsuCompiler
- NomsuCompiler.nomsu = NomsuCompiler
NomsuCompiler.parse = function(self, ...)
return Parser.parse(...)
end
@@ -226,9 +229,6 @@ do
NomsuCompiler.LuaCode = LuaCode
NomsuCompiler.NomsuCode = NomsuCode
NomsuCompiler.Source = Source
- NomsuCompiler.ALIASES = setmetatable({ }, {
- __mode = "k"
- })
NomsuCompiler.LOADED = { }
NomsuCompiler.TESTS = { }
NomsuCompiler.AST = AST
@@ -335,13 +335,13 @@ do
end,
["lua > %"] = function(self, tree, _code)
if _code.type ~= "Text" then
- return LuaCode(tree.source, "nomsu:run_lua(", self:compile(_code), ");")
+ return LuaCode(tree.source, "_ENV:run_lua(", self:compile(_code), ");")
end
return add_lua_bits(self, "statements", _code)
end,
["= lua %"] = function(self, tree, _code)
if _code.type ~= "Text" then
- return LuaCode.Value(tree.source, "nomsu:run_lua(", self:compile(_code), ":as_statements('return '))")
+ return LuaCode.Value(tree.source, "_ENV:run_lua(", self:compile(_code), ":as_statements('return '))")
end
return add_lua_bits(self, "value", _code)
end,
@@ -352,7 +352,7 @@ do
self:run_file(f)
end
end
- return LuaCode(tree.source, "for i,f in Files.walk(", self:compile(_path), ") do nomsu:run_file(f) end")
+ return LuaCode(tree.source, "for i,f in Files.walk(", self:compile(_path), ") do _ENV:run_file(f) end")
end,
["tests"] = function(self, tree)
return LuaCode.Value(tree.source, "TESTS")
@@ -581,7 +581,11 @@ do
end
local arg_lua = self:compile(tok)
if not (arg_lua.is_value) then
- self:compile_error(tok.source, "Cannot use:\n%s\nas an argument to %s, since it's not an expression, it produces: %s", stub, repr(arg_lua))
+ if tok.type == "Block" then
+ self:compile_error(tok.source, ("Cannot compile action '" .. tostring(stub) .. "' with a Block as an argument.\n" .. "Maybe there should be a compile-time action with that name that isn't being found?"))
+ else
+ self:compile_error(tok.source, "Cannot use:\n%s\nas an argument to '%s', since it's not an expression, it produces: %s", stub, repr(arg_lua))
+ end
end
insert(args, arg_lua)
_continue_0 = true
@@ -594,26 +598,29 @@ do
lua:append(")")
return lua
elseif "EscapedNomsu" == _exp_0 then
- local make_tree
- make_tree = function(t)
- if not (AST.is_syntax_tree(t)) then
- return repr(t)
- end
- local bits
+ local lua = LuaCode.Value(tree.source, tree[1].type, "(")
+ local bits
+ if tree[1].type == "EscapedNomsu" then
+ bits = {
+ self:compile(tree[1])
+ }
+ else
do
local _accum_0 = { }
local _len_0 = 1
- for _index_0 = 1, #t do
- local bit = t[_index_0]
- _accum_0[_len_0] = make_tree(bit)
+ local _list_0 = tree[1]
+ for _index_0 = 1, #_list_0 do
+ local bit = _list_0[_index_0]
+ _accum_0[_len_0] = AST.is_syntax_tree(bit) and self:compile(bit) or repr(bit)
_len_0 = _len_0 + 1
end
bits = _accum_0
end
- insert(bits, 1, repr(tostring(t.source)))
- return t.type .. "(" .. concat(bits, ", ") .. ")"
end
- return LuaCode.Value(tree.source, make_tree(tree[1]))
+ insert(bits, 1, repr(tostring(tree[1].source)))
+ lua:concat_append(bits, ", ")
+ lua:append(")")
+ return lua
elseif "Block" == _exp_0 then
local lua = LuaCode(tree.source)
lua:concat_append((function()
@@ -647,7 +654,7 @@ do
end
local bit_lua = self:compile(bit)
if not (bit_lua.is_value) then
- local src = ' ' .. gsub(tostring(recurse(bit)), '\n', '\n ')
+ local src = ' ' .. gsub(tostring(self:compile(bit)), '\n', '\n ')
local line = tostring(bit.source.filename) .. ":" .. tostring(Files.get_line_number(Files.read(bit.source.filename), bit.source.start))
self:compile_error(bit.source, "Cannot use:\n%s\nas a string interpolation value, since it's not an expression.")
end
diff --git a/nomsu_compiler.moon b/nomsu_compiler.moon
index 0b3ae7c..dada050 100644
--- a/nomsu_compiler.moon
+++ b/nomsu_compiler.moon
@@ -93,12 +93,12 @@ _dict_mt =
dict = (t)-> setmetatable(t, _dict_mt)
MAX_LINE = 80 -- For beautification purposes, try not to make lines much longer than this value
-NomsuCompiler = setmetatable({}, {__index: (k)=> if _self = rawget(@, "self") then _self[k] else nil})
+NomsuCompiler = setmetatable {name:"Nomsu"},
+ __index: (k)=> if _self = rawget(@, "self") then _self[k] else nil
+ __tostring: => @name
with NomsuCompiler
.NOMSU_COMPILER_VERSION = 5
.NOMSU_SYNTAX_VERSION = Parser.version
- ._ENV = NomsuCompiler
- .nomsu = NomsuCompiler
.parse = (...)=> Parser.parse(...)
.can_optimize = -> false
@@ -121,7 +121,6 @@ with NomsuCompiler
.LuaCode = LuaCode
.NomsuCode = NomsuCode
.Source = Source
- .ALIASES = setmetatable({}, {__mode:"k"})
.LOADED = {}
.TESTS = {}
.AST = AST
@@ -213,12 +212,12 @@ with NomsuCompiler
["lua > %"]: (tree, _code)=>
if _code.type != "Text"
- return LuaCode tree.source, "nomsu:run_lua(", @compile(_code), ");"
+ return LuaCode tree.source, "_ENV:run_lua(", @compile(_code), ");"
return add_lua_bits(@, "statements", _code)
["= lua %"]: (tree, _code)=>
if _code.type != "Text"
- return LuaCode.Value tree.source, "nomsu:run_lua(", @compile(_code), ":as_statements('return '))"
+ return LuaCode.Value tree.source, "_ENV:run_lua(", @compile(_code), ":as_statements('return '))"
return add_lua_bits(@, "value", _code)
["use %"]: (tree, _path)=>
@@ -226,7 +225,7 @@ with NomsuCompiler
path = _path[1]
for _,f in Files.walk(path)
@run_file(f)
- return LuaCode(tree.source, "for i,f in Files.walk(", @compile(_path), ") do nomsu:run_file(f) end")
+ return LuaCode(tree.source, "for i,f in Files.walk(", @compile(_path), ") do _ENV:run_file(f) end")
["tests"]: (tree)=> LuaCode.Value(tree.source, "TESTS")
["test %"]: (tree, _body)=>
@@ -362,22 +361,28 @@ with NomsuCompiler
if type(tok) == "string" then continue
arg_lua = @compile(tok)
unless arg_lua.is_value
- @compile_error tok.source,
- "Cannot use:\n%s\nas an argument to %s, since it's not an expression, it produces: %s",
- stub, repr arg_lua
+ if tok.type == "Block"
+ @compile_error tok.source,
+ ("Cannot compile action '#{stub}' with a Block as an argument.\n"..
+ "Maybe there should be a compile-time action with that name that isn't being found?")
+
+ else
+ @compile_error tok.source,
+ "Cannot use:\n%s\nas an argument to '%s', since it's not an expression, it produces: %s",
+ stub, repr arg_lua
insert args, arg_lua
lua\concat_append args, ", "
lua\append ")"
return lua
when "EscapedNomsu"
- make_tree = (t)->
- unless AST.is_syntax_tree(t)
- return repr(t)
- bits = [make_tree(bit) for bit in *t]
- insert bits, 1, repr(tostring t.source)
- return t.type.."("..concat(bits, ", ")..")"
- return LuaCode.Value tree.source, make_tree(tree[1])
+ lua = LuaCode.Value tree.source, tree[1].type, "("
+ bits = if tree[1].type == "EscapedNomsu" then {@compile(tree[1])}
+ else [AST.is_syntax_tree(bit) and @compile(bit) or repr(bit) for bit in *tree[1]]
+ insert bits, 1, repr(tostring tree[1].source)
+ lua\concat_append bits, ", "
+ lua\append ")"
+ return lua
when "Block"
lua = LuaCode(tree.source)
@@ -397,7 +402,7 @@ with NomsuCompiler
string_buffer = ""
bit_lua = @compile(bit)
unless bit_lua.is_value
- src = ' '..gsub(tostring(recurse(bit)), '\n','\n ')
+ src = ' '..gsub(tostring(@compile(bit)), '\n','\n ')
line = "#{bit.source.filename}:#{Files.get_line_number(Files.read(bit.source.filename), bit.source.start)}"
@compile_error bit.source,
"Cannot use:\n%s\nas a string interpolation value, since it's not an expression."
diff --git a/syntax_tree.lua b/syntax_tree.lua
index 64b4efc..9b47123 100644
--- a/syntax_tree.lua
+++ b/syntax_tree.lua
@@ -40,11 +40,15 @@ for _index_0 = 1, #types do
return getmetatable(x) == self
end
cls.__tostring = function(self)
- return tostring(self.type) .. "(" .. tostring(repr(tostring(self.source))) .. ", " .. tostring(concat((function()
+ local args = {
+ tostring(self.source),
+ unpack(self)
+ }
+ return tostring(self.type) .. "(" .. tostring(concat((function()
local _accum_0 = { }
local _len_0 = 1
- for _index_1 = 1, #self do
- local v = self[_index_1]
+ for _index_1 = 1, #args do
+ local v = args[_index_1]
_accum_0[_len_0] = repr(v)
_len_0 = _len_0 + 1
end
@@ -114,7 +118,7 @@ for _index_0 = 1, #types do
end
AST[name] = setmetatable(cls, {
__tostring = function(self)
- return self.name
+ return self.__name
end,
__call = function(self, source, ...)
if type(source) == 'string' then
diff --git a/syntax_tree.moon b/syntax_tree.moon
index 885892f..7132c64 100644
--- a/syntax_tree.moon
+++ b/syntax_tree.moon
@@ -19,7 +19,9 @@ for name in *types
.__name = name
.type = name
.is_instance = (x)=> getmetatable(x) == @
- .__tostring = => "#{@type}(#{repr tostring(@source)}, #{concat([repr(v) for v in *@], ', ')})"
+ .__tostring = =>
+ args = {tostring(@source), unpack(@)}
+ "#{@type}(#{concat([repr(v) for v in *args], ', ')})"
.map = (fn)=>
replacement = fn(@)
if replacement == false then return nil
@@ -47,7 +49,7 @@ for name in *types
return true
AST[name] = setmetatable cls,
- __tostring: => @name
+ __tostring: => @__name
__call: (source, ...)=>
if type(source) == 'string'
source = Source\from_string(source)
diff --git a/tools/find_action.nom b/tools/find_action.nom
index 2ddc89f..720899b 100755
--- a/tools/find_action.nom
+++ b/tools/find_action.nom
@@ -16,7 +16,7 @@ for %path in %files:
%file = (read file %filename)
%tree = (parse %file from %filename)
for %t in recursive %tree:
- if (%t is "Action" syntax tree) (..)
+ if (%t is "Action" syntax tree):
if (%t.stub is %stub):
%line_num = (line number of %t.source.start in %file)
say (blue "\%filename:\%line_num:")
diff --git a/tools/upgrade.nom b/tools/upgrade.nom
index 490a58e..6cc2d2c 100755
--- a/tools/upgrade.nom
+++ b/tools/upgrade.nom
@@ -20,7 +20,6 @@ if (%args.1 is "-t"):
remove index 1 from %args
for %path in %args:
- if (%path is "-i"): %inplace = (yes)
for file %filename in %path:
unless (%filename matches "%.nom$"): do next %filename
%tree = (parse (read file %filename) from %filename)