aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xcore.moon2
-rwxr-xr-xnomic.moon34
-rw-r--r--utils.moon2
3 files changed, 13 insertions, 25 deletions
diff --git a/core.moon b/core.moon
index 4c84f66..bb4ba50 100755
--- a/core.moon
+++ b/core.moon
@@ -71,7 +71,7 @@ g\def {"restrict %fn to %whitelist"}, (vars)=>
unless self\check_permission(fn)
print "You do not have permission to restrict function: #{fn}"
continue
- @defs[fn] = whitelist
+ @defs[fn].whitelist = whitelist
g\def {"allow %whitelist to %fn"}, (vars)=>
fns = if type(vars.fn) == 'string' then {vars.fn} else vars.fn
diff --git a/nomic.moon b/nomic.moon
index f85d548..447cdf9 100755
--- a/nomic.moon
+++ b/nomic.moon
@@ -93,6 +93,8 @@ class Game
fn_info = @defs[fn_name]
if fn_info == nil
error "Attempt to call undefined function: #{fn_name}"
+ if fn_info.is_macro
+ error "Attempt to call macro at runtime: #{fn_name}"
{:fn, :arg_names} = fn_info
args = {name, select(i,...) for i,name in ipairs(arg_names)}
if @debug
@@ -119,32 +121,11 @@ class Game
else arg_names = _arg_names
return invocations, arg_names
- defmacro: (spec, fn)=>
+ defmacro: (spec, lua_gen_fn)=>
invocations,arg_names = self\get_invocations spec
- fn_info = {:fn, :arg_names, :invocations, is_macro:true}
+ fn_info = {fn:lua_gen_fn, :arg_names, :invocations, is_macro:true}
for invocation in *invocations
@defs[invocation] = fn_info
-
- simplemacro: (spec, replacement)=>
- spec = spec\gsub("\r", "")
- replacement = replacement\gsub("\r", "")
- replace_grammar = [=[
- stuff <- {~ (var / longstring / string / .)+ ~}
- var <- ("%" {%wordchar+}) -> replacer
- string <- '"' (("\" .) / [^"])* '"'
- longstring <- ('".."' %ws? %indent {(%new_line "|" [^%nl]*)+} %dedent (%new_line '..')?)
- ]=]
- fn = (vars, kind)=>
- replacer = (varname)->
- ret = vars[varname].src
- return ret
- replacement_grammar = make_parser replace_grammar, {:replacer}
- code = replacement_grammar\match(replacement)
- tree = self\parse(code)
- -- Ugh, this is magic code.
- return @tree_to_lua(tree.value.body.value[1].value.value.value, kind), true
-
- self\defmacro spec, fn
run: (text)=>
if @debug
@@ -228,6 +209,13 @@ class Game
assert tree, "Failed to parse: #{str}"
return tree
+ tree_to_value: (tree)=>
+ code = "return (function(game, vars)\nreturn #{@tree_to_lua(tree)}\nend)"
+ lua_thunk, err = loadstring(code)
+ if not lua_thunk
+ error("Failed to compile generated code:\n#{code}\n\n#{err}")
+ return (lua_thunk!)(self, {})
+
tree_to_lua: (tree, kind="Expression")=>
assert tree, "No tree provided."
indent = ""
diff --git a/utils.moon b/utils.moon
index 33e1312..a186d3c 100644
--- a/utils.moon
+++ b/utils.moon
@@ -13,7 +13,7 @@ utils = {
if utils.is_list x
"{#{table.concat([utils.repr(i, true) for i in *x], ", ")}}"
else
- "{#{table.concat(["[#{utils.repr(k, true)}]: #{utils.repr(v, true)}" for k,v in pairs x], ", ")}}"
+ "{#{table.concat(["[#{utils.repr(k, true)}]= #{utils.repr(v, true)}" for k,v in pairs x], ", ")}}"
when 'string'
if not add_quotes
x