diff --git a/lib/core.nom b/lib/core.nom index d5517f2..c31c208 100644 --- a/lib/core.nom +++ b/lib/core.nom @@ -4,4 +4,5 @@ require "lib/operators.nom" require "lib/control_flow.nom" require "lib/collections.nom" require "lib/utils2.nom" -require "lib/permissions.nom" +require "lib/scopes.nom" +lua> "nomsu.core_defs = nomsu.__class.def_number;" diff --git a/lib/metaprogramming.nom b/lib/metaprogramming.nom index 0d5e575..d1236fe 100644 --- a/lib/metaprogramming.nom +++ b/lib/metaprogramming.nom @@ -9,13 +9,16 @@ lua> ".." | local body = nomsu:typecheck(vars, "body", "Thunk"); | return ([[ |nomsu:def(%s, %s, %s) - |]]):format(nomsu:repr(signature), nomsu:tree_to_lua(body), nomsu:repr(("rule %s\\n..=%s"):format(vars.signature.src, vars.body.src))), nil; + |]]):format(nomsu:repr(signature), nomsu:tree_to_lua(body), nomsu:repr(\(__src__))), nil; |end)); # Rule to make nomsu macros: -rule [escaped parse %shorthand as %longhand] =: +rule [parse \%shorthand as \%longhand] =: lua> ".." - |local aliases = nomsu:get_stubs(nomsu:typecheck(vars, "shorthand", "List").value); + |local signature = {}; + |for i, alias in ipairs(nomsu:typecheck(vars, "shorthand", "List").value) do + | signature[i] = alias.src; + |end |local template = nomsu:typecheck(vars, "longhand", "Thunk").value; |local function parsing_as(nomsu, vars) # Single expression/statement @@ -33,36 +36,36 @@ rule [escaped parse %shorthand as %longhand] =: | end | return nil, table.concat(lua_bits, "\\n"); |end - |nomsu:defmacro(aliases, parsing_as, ("parse %s\\n..as %s"):format(vars.shorthand.src, vars.longhand.src)); -escaped parse \[parse %shorthand as %longhand] as \: escaped parse \%shorthand as \%longhand + |nomsu:defmacro(signature, parsing_as, \(__src__)); # Rule to make lua macros: -rule [escaped compile %macro_def to %body] =: +rule [compile \%macro_def to \%body] =: lua> ".." - |local aliases = nomsu:get_stubs(nomsu:typecheck(vars, "macro_def", "List").value); + |local signature = {}; + |for i, alias in ipairs(nomsu:typecheck(vars, "macro_def", "List").value) do + | signature[i] = alias.src; + |end |local body = nomsu:typecheck(vars, "body", "Thunk"); |local thunk = nomsu:tree_to_value(body); - |nomsu:defmacro(aliases, thunk, ("compile %s\\n..to %s"):format(vars.macro_def.src, body.src)); -rule [escaped compile %macro_def to code %body] =: + |nomsu:defmacro(signature, thunk, ("compile %s\\n..to %s"):format(vars.macro_def.src, body.src)); +rule [compile \%macro_def to code \%body] =: lua> ".." - |local aliases = nomsu:get_stubs(nomsu:typecheck(vars, "macro_def", "List").value); + |local signature = {}; + |for i, alias in ipairs(nomsu:typecheck(vars, "macro_def", "List").value) do + | signature[i] = alias.src; + |end |local body = nomsu:typecheck(vars, "body", "Thunk"); |local thunk = nomsu:tree_to_value(body); |local thunk_wrapper = function(nomsu, vars) return nil, thunk(nomsu, vars); end - |nomsu:defmacro(aliases, thunk_wrapper, ("compile %s\\n..to code %s"):format(vars.macro_def.src, body.src)); -parse [compile %macro_def to %body] as: escaped compile \%macro_def to \%body -parse [compile %macro_def to code %body] as: escaped compile \%macro_def to code \%body + |nomsu:defmacro(signature, thunk_wrapper, ("compile %s\\n..to code %s"):format(vars.macro_def.src, body.src)); rule [remove rule %stub] =: lua> ".." |local def = nomsu.defs[\(%stub)]; |for _, alias in ipairs(def.aliases) do - | nomsu.defs[alias] = nil; + | nomsu.defs[alias] = false; |end -rule [do %] =: - =lua "\(%)(nomsu, vars)" - rule [%tree as lua] =: =lua "nomsu:tree_to_lua(\(%tree))" rule [%tree as value] =: @@ -76,6 +79,7 @@ parse [lua do> %block] as: lua> "do" lua> %block lua> "end" + rule [%tree as lua statement] =: lua do> ".." |local _,statement = nomsu:tree_to_lua(\(%tree)); @@ -95,6 +99,9 @@ compile [nomsu] to: "nomsu" compile [nomsu's %key] to: "nomsu[\(%key as lua)]" compile [nomsu %method %args] to: "nomsu[\(%method as lua)](nomsu, unpack(\(%args as lua)))" +parse [rule %signature] as: + (nomsu's "defs")->(nomsu "get_stub" [\%signature]) + # Get the source code for a function rule [help %rule] =: lua do> ".." diff --git a/lib/scopes.nom b/lib/scopes.nom new file mode 100644 index 0000000..362a8c5 --- /dev/null +++ b/lib/scopes.nom @@ -0,0 +1,38 @@ +require "lib/metaprogramming.nom" +require "lib/operators.nom" +require "lib/control_flow.nom" + +compile [<%var> = %value] to code: ".." + |nomsu.defs['#vars'][\(repr (%var's "value"))] = \(%value as lua); + +compile [<%var>] to: "nomsu.defs['#vars'][\(repr (%var's "value"))]" + +compile [str %] to: "tostring(\(% as lua))" + +compile [scope] to: "nomsu.defs" +compile [parent scope] to: "getmetatable(nomsu.defs).__index" + +parse [using %scoped do %actions] as: + %scope = (=lua "setmetatable({['#vars']=setmetatable({}, {__index=nomsu.defs['#vars']})}, {__index=nomsu.defs})") + with (nomsu's "defs") = %scope: + do %scoped + lua> ".." + |getmetatable(nomsu.defs).__newindex = getmetatable(nomsu.defs).__index; + |getmetatable(nomsu.defs["#vars"]).__newindex = getmetatable(nomsu.defs["#vars"]).__index; + do %actions + +parse [scoped %actions] as: using %actions do {pass} + +rule [from %filename import %rules] =: + using: + require %filename + ..do: + %srcs = ((%'s "src") for %_ = % in (parent scope)) + for %src in (unique %srcs): + run %src + +parse [wrap %signature with %body] as: + using: + run ((nomsu)->*["defs",nomsu "get_stub" [\%signature->*["value",1]],"src"]) + ..do: + rule %signature = %body diff --git a/lib/utils2.nom b/lib/utils2.nom index 415f8c3..c31d5ab 100644 --- a/lib/utils2.nom +++ b/lib/utils2.nom @@ -49,4 +49,3 @@ compile [with %assignments %action] to code: |end parse [with %thing = %value %action] as: with [%thing = %value] %action - diff --git a/nomsu.moon b/nomsu.moon index 676f9b8..e957fc4 100755 --- a/nomsu.moon +++ b/nomsu.moon @@ -324,7 +324,9 @@ class NomsuCompiler @write "#{colored.bright "RUNNING MACRO"} #{colored.underscore colored.magenta(tree.stub)} " @writeln "#{colored.bright "WITH ARGS:"} #{colored.dim repr args}" insert @callstack, "#macro" + old_tree, @defs["#macro_tree"] = @defs["#macro_tree"], tree expr, statement = @call(tree.stub, tree.line_no, unpack(args)) + @defs["#macro_tree"] = old_tree remove @callstack return expr, statement @@ -808,13 +810,13 @@ end)]])\format(concat(lua_bits, "\n")) initialize_core: => -- Sets up some core functionality - nomsu_string_as_lua = (code, tree)=> + nomsu_string_as_lua = (code)=> concat_parts = {} for bit in *code.value if type(bit) == "string" insert concat_parts, bit elseif type(bit) == "table" and bit.type == "FunctionCall" and bit.src == "__src__" - insert concat_parts, repr(tree.src) + insert concat_parts, repr(@defs["#macro_tree"].src) else expr, statement = @tree_to_lua bit if statement