Skip to content

Commit

Permalink
Add regexp (still a trivial implementation), add pattern matching t…
Browse files Browse the repository at this point in the history
…o `switch` statements
  • Loading branch information
Edd12321 committed Apr 22, 2023
1 parent a9e7377 commit 3e715bc
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 6 deletions.
32 changes: 30 additions & 2 deletions .zrc
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,38 @@ fn rot13 {

# Go up N Times
fn up {
for {set i = 0} {$i < $argv(1)} {inc i}\
cd\ ..
for {set i = 0} {$i < $argv(1)} {inc i} ..
}

# Extract an archive
# (because it's hard to memorize tar commands)
fn extract {
if [test -f $argv(1)] {
echo '$argv(1): file not found!' >(1=2)
return 1
} else {
let s {
set s = $argv(1)
switch $s {
reg {.\.tar.bz2$} { tar xjf $s }
reg {.\.tar.gz$} { tar xzf $s }
reg {.\.bz2$} { bunzip2 $s }
reg {.\.rar$} { unrar e $s }
reg {.\.gz$} { gunzip $s }
reg {.\.tar$} { tar xf $s }
reg {.\.tbz2$} { tar xjf $s }
reg {.\.tgz$} { tar xzf $s }
reg {.\.zip$} { unzip $s }
reg {.\.Z$} { uncompress $s }
reg {.\.7z$} { 7z x $s }
default {
echo '$s could not be extracted!' >(1=2)
return 1
}
}
}
}
}

# Custom tools
# https://github.com/Edd12321/{cstop,evct,zrc}
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ Zrc is almost half of 1mb in size because its implementation is to the point and
- [X] Line editor
- [X] Tab completion
- [ ] Syntax highlighting

## Inspirations:

* [Tcl](https://www.tcl.tk)
Expand Down
20 changes: 20 additions & 0 deletions doc/man1/regexp.1
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
.TH REGEXP 1
.SH NAME
regexp \- Check regular expressions
.SH SYNOPSIS
.B regexp
<reg> <txt> <var1> <var2...>
.SH DESCRIPTION
This builin checks
.I txt
against the POSIX regular expression
.IR reg ,
and stores the matches in the variables named by the rest of the arguments. If less than 3 args are given to the command, it returns 1. If no matches are found, it returns 2, otherwise it returns 0.
.SH SEE ALSO
.BR grep (1) ,
.BR sed (1) ,
.BR regex (7)
.SH EXAMPLE
.EX
.EE
6 changes: 5 additions & 1 deletion doc/man1/switch.1
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
switch \- Evaluate one of several scripts, depending on the value given as a first argument.
.SH SYNOPSIS
.B switch
<value> {case <c> <cmd>|default...>}
<value> {<case <c> cmd|reg <r>|<default> <block>...}
.SH DESCRIPTION
The
.I switch
Expand All @@ -18,6 +18,10 @@ If the word is
then the utility checks if the word right next to it is the same as the first argument given to the procedure. If it is, it short-circuits, executes the block next to the word, and closes the command, preserving the return value of the block.
.PP
If the word is
.BR reg ,
then the utility verifies the given string against the regular expression next to 'reg'. If it matches, it executes the code block.
.PP
If the word is
.BR default ,
then the utility changes the default fallback compound block to the one found next to the
.B default
Expand Down
35 changes: 33 additions & 2 deletions src/dispatch.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -187,18 +187,30 @@ Command(switch) {
WordList args;
std::ifstream fin("/dev/null");
if (argc != 3)
syntax_error("<value> {<case <c> cmd|default...>}");
syntax_error("<value> {<case <c> cmd|reg <r>|<default> <block>...}");

args = tokenize(argv[2], fin);
fin.close();
std::for_each(args.wl.begin(), args.wl.end(), &str_subst);
for (int i = 0, argc = args.size(); i < argc; i += 3) {
if (args.wl[i] == "case") {
if (i >= argc-2)
syntax_error("`case` ends too early");
if (args.wl[i+1] == argv[1]) {
eval(args.wl[i+2]);
NoReturn;
}
} else if (args.wl[i] == "reg") {
if (i >= argc-2)
syntax_error("`reg` ends too early");
std::regex sr(args.wl[i+1]);
if (std::regex_search(argv[1], sr)) {
eval(args.wl[i+2]);
NoReturn;
}
} else if (args.wl[i] == "default") {
if (i >= argc-1)
syntax_error("`default` ends too early");
def_cmd = args.wl[1+i--];
} else {
syntax_error("Expected `case`/`default`");
Expand Down Expand Up @@ -588,6 +600,25 @@ Command(popd) {
return "0";
}

Command(regexp) {
if (argc < 4)
syntax_error("<reg> <txt> <var1> <var2...>");
int k = 3;
std::regex rexp(argv[1]);
std::smatch res;
std::string txt = argv[2];
std::string::const_iterator it(txt.cbegin());
ret_val = "2";
while (std::regex_search(it, txt.cend(), res, rexp)) {
ret_val = "0";
if (k >= argc)
NoReturn;
setvar(argv[k++], res[0]);
it = res.suffix().first;
}
NoReturn;
}

Command(help);

DispatchTable<std::string, std::function<std::string(int, char**)>> dispatch_table = {
Expand All @@ -596,7 +627,7 @@ DispatchTable<std::string, std::function<std::string(int, char**)>> dispatch_tab
de(while), de(for), de(foreach), de(do), de(switch), de(set), de(inc),
de(array), de(string), de(read), de(chr), de(ord), de(alias), de(unalias),
de(let), de(until), de(source), de(unset), de(help), ce(!,not), de(bg),
de(fg), de(pushd), de(popd)
de(fg), de(pushd), de(popd), de(regexp)
};

/** Show a list of all BuiltIns **/
Expand Down
2 changes: 1 addition & 1 deletion src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
#include <iomanip>
#include <limits.h>
#include <map>
//#include <regex>
#include <regex>
#include <sstream>
#include <stack>
#include <string>
Expand Down

0 comments on commit 3e715bc

Please sign in to comment.