Skip to content

Commit

Permalink
Change substitution rules for arrays (better security+optimization), …
Browse files Browse the repository at this point in the history
…add array lexical scoping
  • Loading branch information
Edd12321 committed May 29, 2023
1 parent 2ddc22a commit 8c87404
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 12 deletions.
9 changes: 6 additions & 3 deletions doc/man1/let.1
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,18 @@ let \- Use a lexical scoping block
.SH DESCRIPTION
The first argument of
.I let
must be a list representing the variables that will return to their original value after executing the second argument, which is a "code block".
must be a list representing the variables that will return to their original value after executing the second argument, which is a "code block". If a variable's name begins with `A,...`, then the utility stores a backup of the associative array of the same name.
.SH EXAMPLE
.EX
set var1 = value
set var2 = value
let {var1 var2} {
set arr(1) = x
set arr(2) = y
let {var1 var2 A,arr} {
array delete arr
set var1 = a
set var2 = b
}
#The original values were preserved!
echo $var1 $var2
echo $var1 $var2 $arr(1)
.EE
29 changes: 29 additions & 0 deletions examples/unique.zrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/usr/lib/zrc/bin/zrc
alias str string

fn unique {
let {count line A,map} {
set count = 0
until {[read line]} {
switch $map($line) {
case '' {
inc count
set map($line) = 1
}
case 1 {
inc count -1
set map($line) = 2
}
}
}
echo $count
}
}

if {$argc == 2} {
unique
} else {
for {set i = 2} {$i < $argc} {inc i} {
unique < $argv($i)
}
}
2 changes: 1 addition & 1 deletion src/config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@

static std::string errmsg = "syntax error: ";
static std::string default_prompt = "zrc% ";
static std::string ver = "zrc v0.2";
static std::string ver = "zrc v0.3";
24 changes: 18 additions & 6 deletions src/dispatch.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -493,18 +493,30 @@ Command(let) {
syntax_error("<var list> <block>");

WordList vars;
std::map<std::string, Variable> hm;
std::map<std::string, Array> a_hm_bak;
std::map<std::string, Scalar> s_hm_bak;
/* empty */ {
NullFin;
vars = tokenize(argv[1], fin);
}
for (std::string const& str : vars.wl)
hm[str] = getvar(str);
for (std::string str : vars.wl) {
if (str[0] == 'A' && str[1] == ',') {
str.erase(0, 2);
a_hm_bak[str] = a_hm[str];
} else {
s_hm_bak[str] = getvar(str);
}
}
eval(argv[2]);
for (std::string const& str : vars.wl)
setvar(str, hm[str]);
for (std::string& str : vars.wl) {
if (str[0] == 'A' && str[1] == ',') {
str.erase(0, 2);
a_hm[str] = a_hm_bak[str];
} else {
setvar(str, s_hm_bak[str]);
}
}
NoReturn;

}

/** Sourcing scripts into current session **/
Expand Down
4 changes: 2 additions & 2 deletions src/subst.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,13 +117,13 @@ str_subst(std::string& str)
tmp1 += str[i];
if (str[i] == '(') {
ITERATE_PAREN('(',')');
str_subst(tmp2);
tmp1 += tmp2+")";
arr_ok = true;
break;
}
}
str_subst(tmp1);
if (!arr_ok)
str_subst(tmp1);
res += get_var(tmp1);
if (!arr_ok)
--i;
Expand Down

0 comments on commit 8c87404

Please sign in to comment.