From b3b8c4d731b0983d5b12c56fc245a8d7c1d631f4 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Mon, 4 Dec 2017 17:35:47 -0800 Subject: Some stuff changed to allow escaped args and some other ports from the two_defs branch. --- lib/collections.nom | 2 +- lib/control_flow.nom | 49 +++++++++++++++++++++++++++++++++++++++------ lib/permissions.nom | 56 ++++++++++------------------------------------------ lib/utils.nom | 21 -------------------- lib/utils2.nom | 42 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 96 insertions(+), 74 deletions(-) (limited to 'lib') diff --git a/lib/collections.nom b/lib/collections.nom index c58d2f7..02729c5 100644 --- a/lib/collections.nom +++ b/lib/collections.nom @@ -93,7 +93,7 @@ rule [dict from entries %items] =: %dict -> (%pair -> 1) = (%pair -> 2) %dict -compile [dict %items] to: +compile [dict %items, d %items] to: if ((%items's "type") == "Thunk"): %item_codes = [] for %func_call in (%items's "value"): diff --git a/lib/control_flow.nom b/lib/control_flow.nom index aeb63ef..2d1a6a4 100644 --- a/lib/control_flow.nom +++ b/lib/control_flow.nom @@ -218,11 +218,48 @@ compile [when %branch_value == ? %body] to code: |end --when == ? %result -# With statement -compile [with %thing = %value %action] to code: ".." +# Try/except +compile [..] + try %action and if it succeeds %success or if it fails %fallback + try %action and if it fails %fallback or if it succeeds %success +..to code: ".." |do - | local old_value = \(%thing as lua); - | \(%thing as lua) = \(%value as lua); - | \(%action as lua statements); - | \(%thing as lua) = old_value; + | local fell_through = false; + | local ok, ret1, ret2 = pcall(function(nomsu, vars) + | \(%action as lua statements) + | fell_through = true; + | end, nomsu, vars); + | if ok then + | \(%success as lua statements) + | end + | if not ok then + | \(%fallback as lua statements) + | elseif not fell_through then + | return ret1, ret2; + | end |end +parse [try %action] as: + try %action and if it succeeds {pass} or if it fails {pass} +parse [try %action and if it fails %fallback] as: + try %action and if it succeeds {pass} or if it fails %fallback +parse [try %action and if it succeeds %success] as: + try %action and if it succeeds %success or if it fails {pass} + +# Do/finally: +compile [do %action then always %final_action] to code: ".." + |do + | local fell_through = false; + | local ok, ret1, ret2 = pcall(function(nomsu, vars) + | \(%action as lua statements) + | fell_through = true; + | end, nomsu, vars); + | local ok2, _ = pcall(function(nomsu, vars) + | \(%final_action as lua statements) + | end, nomsu, vars); + | if not ok then nomsu:error(ret1); end + | if not ok2 then nomsu:error(ret2); end + | if not fell_through then + | return ret1, ret2; + | end + |end + diff --git a/lib/permissions.nom b/lib/permissions.nom index 887f4fa..1811ee8 100644 --- a/lib/permissions.nom +++ b/lib/permissions.nom @@ -3,52 +3,16 @@ require "lib/control_flow.nom" require "lib/operators.nom" require "lib/collections.nom" -# Permission functions -rule [standardize rules %rules] =: - if ((type of %rules) == "string"): %rules = [%rules] - %stubs = (nomsu "get_stubs" [%rules]) - %result = [] - for %stub in %stubs: - %def = ((nomsu's "defs")->%stub) - if %def: - %aliases = (%def's "aliases") - for all %aliases: add % to %result - ..else: add %def to %result - unique %result +rule [called by %whitelist] =: + if ((%whitelist's "type") != "List"): %whitelist = [%whitelist] + %defs = (..) + dict ([(nomsu's "defs")->(nomsu "get_stub" [%]), yes] for all %whitelist) + for %caller in (nomsu's "callstack"): + if (%caller == "#macro"): do next %caller + if (%defs -> (nomsu "get_stub" [%caller's 1])): return (yes) + return (no) -rule [restrict %rules to within %elite_rules] =: - %rules = (standardize rules %rules) - %elite_rules = (standardize rules %elite_rules) - for all (flatten [%elite_rules, %rules]): - assert ((nomsu's "defs") has key %) "Undefined function: \(%)" - for %rule in %rules: - assert (nomsu "check_permission" [%]) ".." - |You do not have permission to restrict permissions for function: \(%) - ((nomsu) ->* ["defs",%rule,"whiteset"]) = (..) - dict ([%, yes] for all %elite_rules) +parse [fail unless called by %whitelist] as: + unless (called by %whitelist): error "Failed to find \(%whitelist) in callstack." -rule [allow %elite_rules to use %rules] =: - %rules = (standardize rules %rules) - %elite_rules = (standardize rules %elite_rules) - for all (flatten [%elite_rules, %rules]): - assert ((nomsu's "defs") has key %) "Undefined function: \(%)" - for %rule in %rules: - assert (nomsu "check_permission" [%rule]) ".." - |You do not have permission to grant permissions for function: \(%rule) - %whiteset = ((nomsu) ->* ["defs",%rule,"whiteset"]) - if (not %whiteset): go to next %rule - for all %elite_rules: %whiteset -> % = (yes) -rule [forbid %pleb_rules to use %rules] =: - %rules = (standardize rules %rules) - %pleb_rules = (standardize rules %pleb_rules) - for all (flatten [%pleb_rules, %used]): - assert ((nomsu's "defs") has key %) "Undefined function: \(%)" - for all %rules: - assert (nomsu "check_permission" [%]) ".." - |You do not have permission to grant permissions for function: \(%) - %whiteset = ((nomsu) ->* ["defs",%,"whiteset"]) - assert %whiteset ".." - |Cannot individually restrict permissions for \(%) because it is currently - |available to everyone. Perhaps you meant to use "restrict % to within %" instead? - for all %pleb_rules: %whiteset's % = (nil) diff --git a/lib/utils.nom b/lib/utils.nom index 965d338..ef0e61e 100644 --- a/lib/utils.nom +++ b/lib/utils.nom @@ -130,24 +130,3 @@ lua> ".." | end; |end; -compile [try %action and if it fails %fallback] to code: ".." - |do - | local _write_err = nomsu.write_err - | nomsu.write_err = function() end; - | local had_return = true; - | local ok, ret1, ret2 = pcall(function(nomsu, vars) - | local ret - | \(%action as lua statements) - | had_return = false; - | return ret; - | end, nomsu, vars); - | nomsu.write_err = _write_err; - | if not ok then - | \(%fallback as lua statements) - | elseif had_return then - | return ret1, ret2; - | else - | ret = ret1; - | end - |end - diff --git a/lib/utils2.nom b/lib/utils2.nom index 2562471..415f8c3 100644 --- a/lib/utils2.nom +++ b/lib/utils2.nom @@ -2,9 +2,51 @@ require "lib/metaprogramming.nom" require "lib/utils.nom" require "lib/control_flow.nom" require "lib/operators.nom" +require "lib/collections.nom" + compile [say %str] to: if ((%str's "type") == "String"): "nomsu:writeln(\(%str as lua))" ..else: "nomsu:writeln(nomsu:stringify(\(%str as lua)))" + +compile [do %action] to code: + if ((%action's "type") == "Thunk"): + %action as lua statements + ..else: + "(\(%action as lua))(nomsu, vars);" + +# With statement +compile [with %assignments %action] to code: + %data = [] + for %i = %assignment in (%assignments' "value"): + %tokens = (%assignment's "value") + %var = (%tokens -> 1) + %eq = (%tokens -> 2) + assert (=lua "vars.eq and vars.eq.type == 'Word' and vars.eq.value == '='") ".." + |Invalid format for 'with' statement. List entries must have the form %var = (value) + %value = (%tokens -> 3) + add (d{i=%i; var=%var; value=%value}) to %data + %foo = (..) + join (..) + "local old_value\(%->"i") = \((%->"var") as lua); \((%->"var") as lua) = \((%->"value") as lua);" + ..for all %data + ..with glue "\n " + ".." + |do + | \(%foo) + | local fell_through = false; + | local ok, ret1, ret2 = pcall(function(nomsu, vars) + | \(%action as lua statements); + | fell_through = true; + | end, nomsu, vars); + | \(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 + | return ret1, ret2; + | end + |end +parse [with %thing = %value %action] as: with [%thing = %value] %action + + -- cgit v1.2.3