Adding support for coroutines, and cleaning up comment syntax.
This commit is contained in:
parent
28cd9ae0b7
commit
01aa199f7a
@ -74,11 +74,9 @@ immediately
|
|||||||
compile [%tree has subtree %subtree where %condition] to
|
compile [%tree has subtree %subtree where %condition] to
|
||||||
Lua value ".."
|
Lua value ".."
|
||||||
(function()
|
(function()
|
||||||
for \(%subtree as lua expr) in coroutine.wrap(function() nomsu:walk_tree(\(%tree as lua expr)) end) do
|
for \(%subtree as lua expr) in coroutine.wrap(function() \(%tree as lua expr):map(coroutine.yield) end) do
|
||||||
if Types.is_node(\(%subtree as lua expr)) then
|
if \(%condition as lua expr) then
|
||||||
if \(%condition as lua expr) then
|
return true;
|
||||||
return true;
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return false;
|
return false;
|
||||||
@ -431,3 +429,13 @@ immediately
|
|||||||
\(%body as lua statements)
|
\(%body as lua statements)
|
||||||
end)()
|
end)()
|
||||||
|
|
||||||
|
# Coroutines:
|
||||||
|
immediately
|
||||||
|
compile [values %body, coroutine %body, generator %body] to
|
||||||
|
Lua value ".."
|
||||||
|
(function()
|
||||||
|
\(%body as lua statements)
|
||||||
|
end)
|
||||||
|
compile [->] to: Lua "coroutine.yield(true);"
|
||||||
|
compile [-> %] to: Lua "coroutine.yield(true, \(% as lua expr));"
|
||||||
|
compile [-> %k = %v] to: Lua "coroutine.yield(\(%k as lua expr), \(%v as lua expr));"
|
||||||
|
@ -95,7 +95,7 @@ immediately
|
|||||||
replacements = "{"..table.concat(replacements, ", ").."}";
|
replacements = "{"..table.concat(replacements, ", ").."}";
|
||||||
lua:append([[)
|
lua:append([[)
|
||||||
local template = nomsu:parse(Nomsu(]]..repr(tree.source)..[[, ]]..template..[[));
|
local template = nomsu:parse(Nomsu(]]..repr(tree.source)..[[, ]]..template..[[));
|
||||||
local replacement = nomsu:tree_with_replaced_vars(template, ]]..replacements..[[);
|
local replacement = nomsu:tree_with_replacements(template, ]]..replacements..[[);
|
||||||
return replacement:as_lua(nomsu);
|
return replacement:as_lua(nomsu);
|
||||||
end);]]);
|
end);]]);
|
||||||
return lua;
|
return lua;
|
||||||
@ -125,7 +125,7 @@ immediately
|
|||||||
=lua "\%tree:as_lua(nomsu):as_statements()"
|
=lua "\%tree:as_lua(nomsu):as_statements()"
|
||||||
|
|
||||||
action [%tree with vars %vars]
|
action [%tree with vars %vars]
|
||||||
=lua "nomsu:tree_with_replaced_vars(\%tree, \%vars)"
|
=lua "nomsu:tree_with_replacements(\%tree, \%vars)"
|
||||||
|
|
||||||
compile [declare locals in %code] to
|
compile [declare locals in %code] to
|
||||||
Lua value "\(%code as lua expr):declare_locals()"
|
Lua value "\(%code as lua expr):declare_locals()"
|
||||||
|
@ -271,8 +271,10 @@ immediately
|
|||||||
\(%body as lua statements)
|
\(%body as lua statements)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Constants can be defined as macros (but they need to be parenthesized when invoked)
|
# Constants can be defined as macros
|
||||||
parse [TWENTY] as: 20
|
parse [TWENTY] as: 20
|
||||||
|
# When they're invoked, they'll need parentheses just like a function call
|
||||||
|
parse [TWENTY ONE] as: 21
|
||||||
|
|
||||||
if (1 > (TWENTY)) is untrue
|
if (1 > (TWENTY)) is untrue
|
||||||
say "Nomsu parsing macros work!"
|
say "Nomsu parsing macros work!"
|
||||||
|
40
nomsu.lua
40
nomsu.lua
@ -1,7 +1,7 @@
|
|||||||
|
local _pairs, _ipairs = pairs, ipairs
|
||||||
if jit then
|
if jit then
|
||||||
package.cpath = "./luajit_lpeg/?.so;" .. package.cpath
|
package.cpath = "./luajit_lpeg/?.so;" .. package.cpath
|
||||||
bit32 = require('bit')
|
bit32 = require('bit')
|
||||||
local _pairs, _ipairs = pairs, ipairs
|
|
||||||
pairs = function(x)
|
pairs = function(x)
|
||||||
do
|
do
|
||||||
local mt = getmetatable(x)
|
local mt = getmetatable(x)
|
||||||
@ -486,7 +486,7 @@ do
|
|||||||
end
|
end
|
||||||
return nil
|
return nil
|
||||||
end,
|
end,
|
||||||
tree_with_replaced_vars = function(self, tree, replacements)
|
tree_with_replacements = function(self, tree, replacements)
|
||||||
if not (next(replacements)) then
|
if not (next(replacements)) then
|
||||||
return tree
|
return tree
|
||||||
end
|
end
|
||||||
@ -669,6 +669,42 @@ do
|
|||||||
return #x
|
return #x
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
self.environment.ipairs = function(x)
|
||||||
|
if type(x) == 'function' then
|
||||||
|
return coroutine.wrap(x)
|
||||||
|
elseif type(x) == 'thread' then
|
||||||
|
return coroutine.resume, x, nil
|
||||||
|
else
|
||||||
|
do
|
||||||
|
local mt = getmetatable(x)
|
||||||
|
if mt then
|
||||||
|
if mt.__ipairs then
|
||||||
|
return mt.__ipairs(x)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
return _ipairs(x)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
self.environment.pairs = function(x)
|
||||||
|
if type(x) == 'function' then
|
||||||
|
return coroutine.wrap(x)
|
||||||
|
elseif type(x) == 'thread' then
|
||||||
|
return coroutine.resume, x, nil
|
||||||
|
else
|
||||||
|
do
|
||||||
|
local mt = getmetatable(x)
|
||||||
|
if mt then
|
||||||
|
if mt.__pairs then
|
||||||
|
return mt.__pairs(x)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
return _pairs(x)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
for k, v in pairs(Types) do
|
for k, v in pairs(Types) do
|
||||||
self.environment[k] = v
|
self.environment[k] = v
|
||||||
end
|
end
|
||||||
|
22
nomsu.moon
22
nomsu.moon
@ -11,13 +11,13 @@
|
|||||||
-- Or from the command line:
|
-- Or from the command line:
|
||||||
-- lua nomsu.lua [input_file [output_file or -]]
|
-- lua nomsu.lua [input_file [output_file or -]]
|
||||||
export lpeg, re
|
export lpeg, re
|
||||||
|
_pairs, _ipairs = pairs, ipairs
|
||||||
if jit
|
if jit
|
||||||
package.cpath = "./luajit_lpeg/?.so;"..package.cpath
|
package.cpath = "./luajit_lpeg/?.so;"..package.cpath
|
||||||
|
|
||||||
export bit32
|
export bit32
|
||||||
bit32 = require('bit')
|
bit32 = require('bit')
|
||||||
|
|
||||||
_pairs, _ipairs = pairs, ipairs
|
|
||||||
export pairs, ipairs
|
export pairs, ipairs
|
||||||
pairs = (x)->
|
pairs = (x)->
|
||||||
if mt = getmetatable(x)
|
if mt = getmetatable(x)
|
||||||
@ -259,6 +259,24 @@ class NomsuCompiler
|
|||||||
return mt.__len(x)
|
return mt.__len(x)
|
||||||
return #x
|
return #x
|
||||||
else ((x) -> #x)
|
else ((x) -> #x)
|
||||||
|
@environment.ipairs = (x)->
|
||||||
|
if type(x) == 'function'
|
||||||
|
return coroutine.wrap(x)
|
||||||
|
elseif type(x) == 'thread'
|
||||||
|
return coroutine.resume, x, nil
|
||||||
|
elseif mt = getmetatable(x)
|
||||||
|
if mt.__ipairs
|
||||||
|
return mt.__ipairs(x)
|
||||||
|
else return _ipairs(x)
|
||||||
|
@environment.pairs = (x)->
|
||||||
|
if type(x) == 'function'
|
||||||
|
return coroutine.wrap(x)
|
||||||
|
elseif type(x) == 'thread'
|
||||||
|
return coroutine.resume, x, nil
|
||||||
|
elseif mt = getmetatable(x)
|
||||||
|
if mt.__pairs
|
||||||
|
return mt.__pairs(x)
|
||||||
|
else return _pairs(x)
|
||||||
for k,v in pairs(Types) do @environment[k] = v
|
for k,v in pairs(Types) do @environment[k] = v
|
||||||
@environment.Tuple = Tuple
|
@environment.Tuple = Tuple
|
||||||
@environment.Lua = Lua
|
@environment.Lua = Lua
|
||||||
@ -422,7 +440,7 @@ class NomsuCompiler
|
|||||||
else @walk_tree(tree.value, depth+1)
|
else @walk_tree(tree.value, depth+1)
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
tree_with_replaced_vars: (tree, replacements)=>
|
tree_with_replacements: (tree, replacements)=>
|
||||||
return tree unless next(replacements)
|
return tree unless next(replacements)
|
||||||
if next(replacements).type == "Var"
|
if next(replacements).type == "Var"
|
||||||
replacements = {tostring(k\as_lua(@)),v for k,v in pairs(replacements)}
|
replacements = {tostring(k\as_lua(@)),v for k,v in pairs(replacements)}
|
||||||
|
10
nomsu.peg
10
nomsu.peg
@ -124,12 +124,12 @@ inline_dict_item:
|
|||||||
dict_key:
|
dict_key:
|
||||||
text_word / inline_expression
|
text_word / inline_expression
|
||||||
|
|
||||||
block_comment: "#.." [^%nl]* (%nl+ %indent [^%nl]* (%nl+ %nodent [^%nl]*)* %dedent)?
|
comment: "#" [^%nl]* (%nl+ %indent [^%nl]* (%nl+ %nodent [^%nl]*)* %dedent)?
|
||||||
line_comment: "#" [^%nl]*
|
eol_comment: "#" [^%nl]*
|
||||||
|
|
||||||
eol: %ws* line_comment? (!. / &%nl)
|
eol: %ws* eol_comment? (!. / &%nl)
|
||||||
ignored_line: (%nodent (block_comment / line_comment)) / (%ws* (!. / &%nl))
|
ignored_line: (%nodent comment) / (%ws* (!. / &%nl))
|
||||||
indent: eol (%nl ignored_line)* %nl %indent ((block_comment/line_comment) (%nl ignored_line)* nodent)?
|
indent: eol (%nl ignored_line)* %nl %indent (comment (%nl ignored_line)* nodent)?
|
||||||
nodent: eol (%nl ignored_line)* %nl %nodent
|
nodent: eol (%nl ignored_line)* %nl %nodent
|
||||||
dedent: eol (%nl ignored_line)* (((!.) &%dedent) / (&(%nl %dedent)))
|
dedent: eol (%nl ignored_line)* (((!.) &%dedent) / (&(%nl %dedent)))
|
||||||
non_dedent_error: (!dedent .)* eol (%nl ignored_line)* (!. / &%nl)
|
non_dedent_error: (!dedent .)* eol (%nl ignored_line)* (!. / &%nl)
|
||||||
|
@ -200,3 +200,15 @@ assume
|
|||||||
for all [1,2,3]: %n +<- %
|
for all [1,2,3]: %n +<- %
|
||||||
return %n
|
return %n
|
||||||
..= 6
|
..= 6
|
||||||
|
|
||||||
|
%nums <- []
|
||||||
|
for all
|
||||||
|
values
|
||||||
|
-> 4
|
||||||
|
-> 5
|
||||||
|
-> 6
|
||||||
|
..
|
||||||
|
add % to %nums
|
||||||
|
|
||||||
|
assume (%nums = [4,5,6]) or barf "Coroutine iteration failed"
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user