aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorBruce Hill <bitbucket@bruce-hill.com>2017-12-04 17:35:47 -0800
committerBruce Hill <bitbucket@bruce-hill.com>2017-12-04 17:35:47 -0800
commitb3b8c4d731b0983d5b12c56fc245a8d7c1d631f4 (patch)
tree21c1bf182440b26edb621e76cf8e730d7dc6849e /lib
parent8c0816995afaaf34cbfe903e6da68d8b6d8e8c39 (diff)
Some stuff changed to allow escaped args and some other ports from the
two_defs branch.
Diffstat (limited to 'lib')
-rw-r--r--lib/collections.nom2
-rw-r--r--lib/control_flow.nom49
-rw-r--r--lib/permissions.nom56
-rw-r--r--lib/utils.nom21
-rw-r--r--lib/utils2.nom42
5 files changed, 96 insertions, 74 deletions
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
+
+