From 53a9d4eae888d2b09c68fcd5dc14ae51f5d07c31 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Wed, 10 Jan 2018 20:45:03 -0800 Subject: Pretty much mostly working. --- lib/collections.nom | 28 ++++++++--------- lib/control_flow.nom | 22 +++++++------ lib/metaprogramming.nom | 82 ++++++++++++++++++++++++++----------------------- lib/operators.nom | 6 ++-- lib/scopes.nom | 2 ++ lib/utils.nom | 14 ++++----- lib/utils2.nom | 6 ++-- 7 files changed, 83 insertions(+), 77 deletions(-) (limited to 'lib') diff --git a/lib/collections.nom b/lib/collections.nom index 9939c9b..697602e 100644 --- a/lib/collections.nom +++ b/lib/collections.nom @@ -105,14 +105,13 @@ compile [%expression for %item in %iterable] to: assert ((%item's "type") == "Var") ".." List comprehension has the wrong type for the loop variable. Expected Var, but got: \(%item's "type") return ".." - (function(nomsu, vars); + (function(nomsu); local comprehension = {}; - for i,item in ipairs(\(%iterable as lua)) do; - \(%item as lua) = item; + for i,\(%item as lua) in ipairs(\(%iterable as lua)) do; comprehension[i] = \(%expression as lua); end; return comprehension; - end)(nomsu, setmetatable({}, {__index=vars})) + end)(nomsu) parse [%expression for all %iterable] as: %expression for % in %iterable compile [%expression for %key = %value in %iterable] to: @@ -121,14 +120,13 @@ compile [%expression for %key = %value in %iterable] to: assert ((%value's "type") == "Var") ".." List comprehension has the wrong type for the value loop variable. Expected Var, but got: \(%value's "type") return ".." - (function(nomsu, vars); + (function(nomsu); local comprehension = {}; - for key,value in pairs(\(%iterable as lua)) do; - \(%key as lua), \(%value as lua) = key, value; + for \(%key as lua), \(%value as lua) in pairs(\(%iterable as lua)) do; comprehension[i] = \(%expression as lua); end; return comprehension; - end)(nomsu, setmetatable({}, {__index=vars})) + end)(nomsu) rule [%items sorted] =: %copy = (% for all %items) @@ -166,14 +164,13 @@ compile [%key = %value for %item in %iterable] to: assert ((%item's "type") == "Var") ".." Dict comprehension has the wrong type for the loop variable. Expected Var, but got: \(%item's "type") return ".." - (function(nomsu, vars); + (function(nomsu); local comprehension = {}; - for i,value in ipairs(\(%iterable as lua)) do; - \(%item as lua) = value; + for i,\(%item as lua) in ipairs(\(%iterable as lua)) do; comprehension[\(%key as lua)] = \(%value as lua); end; return comprehension; - end)(nomsu, setmetatable({}, {__index=vars})) + end)(nomsu) parse [%key = %value for all %iterable] as: %key = %value for % in %iterable compile [%key = %value for %src_key = %src_value in %iterable] to: @@ -182,12 +179,11 @@ compile [%key = %value for %src_key = %src_value in %iterable] to: assert ((%src_value's "type") == "Var") ".." Dict comprehension has the wrong type for the value loop variable. Expected Var, but got: \(%src_value's "type") return ".." - (function(nomsu, vars); + (function(nomsu); local comprehension = {}; - for key,value in pairs(\(%iterable as lua)) do; - \(%src_key as lua), \(%src_value as lua) = key, value; + for \(%src_key as lua), \(%src_value as lua) in pairs(\(%iterable as lua)) do; comprehension[\(%key as lua)] = \(%value as lua); end; return comprehension; - end)(nomsu, setmetatable({}, {__index=vars})) + end)(nomsu) diff --git a/lib/control_flow.nom b/lib/control_flow.nom index 922338f..254d81d 100644 --- a/lib/control_flow.nom +++ b/lib/control_flow.nom @@ -91,6 +91,7 @@ immediately: for %var from %start to %stop by %step %body for %var from %start to %stop via %step %body ..to code: + lua> "local \%continue_labels, \%code, \%stop_labels" %continue_labels = "" if (tree %body has function call \(do next for-loop)): %continue_labels join= "\n::continue_for::;" @@ -126,6 +127,7 @@ immediately: immediately: compile [for %var in %iterable %body] to code: + lua> "local \%continue_labels, \%stop_labels, \%code, \%stop_labels" %continue_labels = "" if (tree %body has function call \(do next for-loop)): %continue_labels join= "\n::continue_for::;" @@ -143,12 +145,12 @@ immediately: %stop_labels join= "\n::stop_for::;" if (tree %body has function call (tree \(stop %) with {""=%var})): %stop_labels join= "\n::stop_\(nomsu "var_to_lua_identifier" [%var])::;" - return (..) - ".." + if %stop_labels != "": + %code = ".." do --for-loop label scope \%code\%stop_labels end --for-loop label scope - ..if %stop_labels != "" else %code + return %code parse [for all %iterable %body] as: for % in %iterable %body # Dict iteration (lua's "pairs()") @@ -186,10 +188,12 @@ immediately: # Switch statement/multi-branch if immediately: compile [when %body] to code: + lua> "local \%result, \%fallthroughs, \%first" %result = "" %fallthroughs = [] %first = (yes) for %func_call in (%body's "value"): + lua> "local \%tokens, \%star, \%condition, \%action" assert ((%func_call's "type") == "FunctionCall") ".." Invalid format for 'when' statement. Only '*' blocks are allowed. %tokens = (%func_call's "value") @@ -286,10 +290,10 @@ immediately: ..to code: ".." do local fell_through = false; - local ok, ret1, ret2 = pcall(function(nomsu, vars) + local ok, ret1, ret2 = pcall(function(nomsu) \(%action as lua statements) fell_through = true; - end, nomsu, vars); + end, nomsu); if ok then \(%success as lua statements) end @@ -313,13 +317,13 @@ immediately: compile [do %action then always %final_action] to code: ".." do local fell_through = false; - local ok, ret1, ret2 = pcall(function(nomsu, vars) + local ok, ret1, ret2 = pcall(function(nomsu) \(%action as lua statements) fell_through = true; - end, nomsu, vars); - local ok2, _ = pcall(function(nomsu, vars) + end, nomsu); + local ok2, _ = pcall(function(nomsu) \(%final_action as lua statements) - end, nomsu, vars); + end, nomsu); if not ok then nomsu:error(ret1); end if not ok2 then nomsu:error(ret2); end if not fell_through then diff --git a/lib/metaprogramming.nom b/lib/metaprogramming.nom index 1477175..4b3c615 100644 --- a/lib/metaprogramming.nom +++ b/lib/metaprogramming.nom @@ -5,53 +5,59 @@ # Rule to make macros: immediately: lua> ".." - nomsu:defmacro("compile %macro_def to %body", function(nomsu, vars) + nomsu.parse_spec = function(nomsu, spec) + local signature = {}; + for i, alias in ipairs(spec.value) do + signature[i] = alias.src; + end + local _, arg_names, _ = nomsu:get_stub(spec.value[1]); + local args = {"nomsu"}; + for i, a in ipairs(arg_names) do args[i+1] = "_"..nomsu:var_to_lua_identifier(a); end + signature, args = nomsu:repr(signature), table.concat(args, ", "); + return signature, args; + end + +immediately: + lua> ".." + nomsu:defmacro("compile %macro_def to %body", function(nomsu, \%macro_def, \%body) nomsu:assert(\%macro_def.type == "List", "Invalid type for compile definition signature. Expected List, but got: "..tostring(\%macro_def.type)); nomsu:assert(\%body.type == "Block", "Invalid type for compile definition body. Expected Block, but got: "..tostring(\%body.type)); - local signature = {}; - for i, alias in ipairs(\%macro_def.value) do - signature[i] = alias.src; - end + local signature, args = nomsu:parse_spec(\%macro_def); local body_lua = nomsu:tree_to_lua(\%body); body_lua = body_lua.statements or ("return "..body_lua.expr..";"); local lua = ([[ do - local function macro(nomsu, vars) + local function macro(%s) %s end local function macro_wrapper(...) return {expr=macro(...)}; end nomsu:defmacro(%s, macro_wrapper, %s); - end]]):format(body_lua, nomsu:repr(signature), nomsu:repr(("compile %s\\n..to code %s"):format(\%macro_def.src, \%body.src))); + end]]):format(args, body_lua, signature, nomsu:repr(("compile %s\\n..to code %s"):format(\%macro_def.src, \%body.src))); return {statements=lua}; end, \(__src__ 1)); lua> ".." - nomsu:defmacro("compile %macro_def to code %body", function(nomsu, vars) + nomsu:defmacro("compile %macro_def to code %body", function(nomsu, \%macro_def, \%body) nomsu:assert(\%macro_def.type == "List", "Invalid type for compile definition signature. Expected List, but got: "..tostring(\%macro_def.type)); nomsu:assert(\%body.type == "Block", "Invalid type for compile definition body. Expected Block, but got: "..tostring(\%body.type)); - local signature = {}; - for i, alias in ipairs(\%macro_def.value) do - signature[i] = alias.src; - end + local signature, args = nomsu:parse_spec(\%macro_def); local body_lua = nomsu:tree_to_lua(\%body); body_lua = body_lua.statements or ("return "..body_lua.expr..";"); local lua = ([[ do - local function macro(nomsu, vars) + local function macro(%s) %s end local function macro_wrapper(...) return {statements=macro(...)}; end nomsu:defmacro(%s, macro_wrapper, %s); - end]]):format(body_lua, nomsu:repr(signature), nomsu:repr(("compile %s\\n..to code %s"):format(\%macro_def.src, \%body.src))); + end]]):format(args, body_lua, signature, nomsu:repr(("compile %s\\n..to code %s"):format(\%macro_def.src, \%body.src))); return {statements=lua}; end, \(__src__ 1)); -compile [rand] to: "math.random()" - # Rule to make rules: immediately: compile [rule %signature = %body] to code: @@ -60,43 +66,41 @@ immediately: "Invalid type for rule definition signature. Expected List, but got: "..tostring(\%signature.type)); nomsu:assert(\%body.type == "Block", "Invalid type for rule definition body. Expected Block, but got: "..tostring(\%body.type)); - local signature = {}; - for i, alias in ipairs(\%signature.value) do - signature[i] = alias.src; - end + local signature, args = nomsu:parse_spec(\%signature); local body_lua = nomsu:tree_to_lua(\%body); body_lua = body_lua.statements or ("return "..body_lua.expr..";"); local src = nomsu:dedent(nomsu:source_code(0)); local def_lua = ([[ - nomsu:def(%s, function(nomsu, vars) + nomsu:def(%s, function(%s) %s - end, %s);]]):format(nomsu:repr(signature), body_lua, nomsu:repr(src)); + end, %s);]]):format(signature, args, body_lua, nomsu:repr(src)); return def_lua; # Rule to make nomsu macros: immediately: lua> ".." - nomsu:defmacro("parse %shorthand as %longhand", (function(nomsu, vars) + nomsu:defmacro("parse %shorthand as %longhand", (function(nomsu, \%shorthand, \%longhand) nomsu:assert(\%shorthand.type == "List", "Invalid type for parse definition signature. Expected List, but got: "..tostring(\%shorthand.type)); nomsu:assert(\%longhand.type == "Block", "Invalid type for parse definition body. Expected Block, but got: "..tostring(\%longhand.type)); - local signature = {}; - for i, alias in ipairs(\%shorthand.value) do - signature[i] = alias.src; - end + local signature, args = nomsu:parse_spec(\%shorthand); local template = {}; for i, line in ipairs(\%longhand.value) do template[i] = nomsu:dedent(line.src); end - signature, template = nomsu:repr(signature), nomsu:repr(table.concat(template, "\\n")); - return {expr=([[ - nomsu:defmacro(%s, (function(nomsu, vars) + template = nomsu:repr(table.concat(template, "\\n")); + local _, arg_names, _ = nomsu:get_stub(\%shorthand.value[1]); + local replacements = {}; + for i, a in ipairs(arg_names) do replacements[i] = "["..nomsu:repr(a).."]=_"..nomsu:var_to_lua_identifier(a); end + replacements = "{"..table.concat(replacements, ", ").."}"; + local lua_code = ([[ + nomsu:defmacro(%s, (function(%s) local template = nomsu:parse(%s, %s); - if #template.value == 1 then template = template.value[1]; end - local replacement = nomsu:replaced_vars(template, vars); + local replacement = nomsu:replaced_vars(template, %s); return nomsu:tree_to_lua(replacement); - end), %s)]]):format(signature, template, nomsu:repr(\%shorthand.line_no), nomsu:repr(nomsu:source_code(0)))}; + end), %s)]]):format(signature, args, template, nomsu:repr(\%shorthand:get_line_no()), replacements, nomsu:repr(nomsu:source_code(0))); + return {statements=lua_code}; end), \(__src__ 1)); rule [remove rule %stub] =: @@ -114,7 +118,7 @@ immediately: local lua = nomsu:tree_to_lua(\%tree); return lua.statements or (lua.expr..";"); rule [%tree as value] =: - =lua "nomsu:tree_to_value(\%tree, vars)" + =lua "nomsu:tree_to_value(\%tree)" compile [repr %obj] to: "nomsu:repr(\(%obj as lua))" compile [indented %obj] to: @@ -124,12 +128,14 @@ immediately: compile [type %obj, type of %obj] to: "type(\(%obj as lua))" -parse [lua do> %block] as: - lua> "do" - lua> %block - lua> "end" +immediately: + parse [lua do> %block] as: + lua> "do" + lua> %block + lua> "end" 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)))" compile [tree %tree with %replacements] to: ".." diff --git a/lib/operators.nom b/lib/operators.nom index 2f08089..1670191 100644 --- a/lib/operators.nom +++ b/lib/operators.nom @@ -20,13 +20,13 @@ compile [..] %when_false_expr unless %condition else %when_true_expr %when_false_expr unless %condition then %when_true_expr ..to: ".." - (function(nomsu, vars) - if \(%condition as lua) then + (function(nomsu, condition) + if condition then return \(%when_true_expr as lua); else return \(%when_false_expr as lua); end - end)(nomsu, vars) + end)(nomsu, \(%condition as lua)) parse [..] %true if %x == %y else %false, %true if %x == %y otherwise %false %false unless %x == %y else %true, %false unless %x == %y otherwise %true diff --git a/lib/scopes.nom b/lib/scopes.nom index 910b30e..3f6eff1 100644 --- a/lib/scopes.nom +++ b/lib/scopes.nom @@ -13,6 +13,8 @@ compile [str %] to: "tostring(\(% as lua))" compile [scope] to: "nomsu.defs" compile [parent scope] to: "getmetatable(nomsu.defs).__index" +# TODO: fix this file +return compile [using %scoped do %actions] to code: ".." do local old_scope, old_vars = nomsu.defs, vars; diff --git a/lib/utils.nom b/lib/utils.nom index ddaac8d..ce6dc9d 100644 --- a/lib/utils.nom +++ b/lib/utils.nom @@ -7,7 +7,7 @@ rule [error %msg] =: nomsu "error"[%msg] compile [assert %condition %msg] to code: ".." if not (\(%condition as lua)) then - nomsu:error(\(%msg as lua)) + nomsu:error(\(%msg as lua)); end parse [assert %condition] as: assert %condition (nil) @@ -80,19 +80,17 @@ compile [min of %items, smallest of %items, lowest of %items] to: compile [max of %items, biggest of %items, largest of %items, highest of %items] to: "nomsu.utils.max(\(%items as lua))" compile [min of %items by %value_expr] to: ".." - nomsu.utils.min(\(%items as lua), function(item) - local vars = setmetatable({['']=item}, {__index=vars}) + nomsu.utils.min(\(%items as lua), function(\(\% as lua)) return \(%value_expr as lua) end) compile [max of %items by %value_expr] to: ".." - nomsu.utils.max(\(%items as lua), function(item) - local vars = setmetatable({['']=item}, {__index=vars}) + nomsu.utils.max(\(%items as lua), function(\(\% as lua)) return \(%value_expr as lua) end) compile [sort %items] to: "table.sort(\(%items as lua))" -rule [sort %items by %key] =: =lua ".." - nomsu.utils.sort(\%items, function(x) - return (\%key)(nomsu, {['']=x}); +compile [sort %items by %key_expr] to: ".." + nomsu.utils.sort(\(%items as lua), function(\(\% as lua)) + return \(%key_expr as lua); end) # String utilities diff --git a/lib/utils2.nom b/lib/utils2.nom index 2fa29f7..8077203 100644 --- a/lib/utils2.nom +++ b/lib/utils2.nom @@ -11,7 +11,7 @@ compile [say %str] to: compile [do %action] to code: (%action as lua statements) if ((%action's "type") == "Thunk") - ..else "(\(%action as lua))(nomsu, vars);" + ..else "(\(%action as lua))(nomsu);" # With statement compile [with %assignments %action] to code: @@ -33,10 +33,10 @@ compile [with %assignments %action] to code: do \%setup local fell_through = false; - local ok, ret1, ret2 = pcall(function(nomsu, vars) + local ok, ret1, ret2 = pcall(function(nomsu) \(%action as lua statements); fell_through = true; - end, nomsu, vars); + end, nomsu); \(join ("\((%->"var") as lua) = old_value\(%->"i");" for all %data) with glue "\n ") if not ok then nomsu:error(ret1); end if not fell_through then -- cgit v1.2.3