Skip to content

Commit

Permalink
expr overhaul: Replace old Shunting Yard implementation with flex/b…
Browse files Browse the repository at this point in the history
…ison (speedup), add `trunc`, `sec`, `arcsec`, `csc`, `arccsc`, fix high return values, fix ternary operator.
  • Loading branch information
Edd12321 committed Dec 1, 2023
1 parent 441aa39 commit 71206d3
Show file tree
Hide file tree
Showing 13 changed files with 290 additions and 392 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,6 @@ bin/zrc
*/*.sloc
*/*.filecount
corebuf/bin/*
src/y.tab.c
src/y.tab.h
src/lex.yy.c
16 changes: 10 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
UNAME := $(shell uname -o)
CC=$(CXX)

all:
all: expr
mkdir -p bin
g++ src/main.cpp -o bin/zrc
g++ -w src/lex.yy.c src/y.tab.c src/main.cpp -o bin/zrc
strip bin/zrc
nozledit:
nozledit: expr
mkdir -p bin
g++ src/main.cpp -o bin/zrc -DUSE_ZLINEEDIT=0
g++ -w src/lex.yy.c src/y.tab.c src/main.cpp -o bin/zrc -DUSE_ZLINEEDIT=0
strip bin/zrc
nohash:
nohash: expr
mkdir -p bin
g++ src/main.cpp -o bin/zrc -DUSE_HASHCACHE=0
g++ -w src/lex.yy.c src/y.tab.c src/main.cpp -o bin/zrc -DUSE_HASHCACHE=0
strip bin/zrc
sloc:
sloccount . | tee sloccount.txt
Expand All @@ -23,6 +24,9 @@ endif
corebuf:
cd corebuf; \
./build.zrc
expr:
bison -d src/expr.y -o src/y.tab.c
flex -o src/lex.yy.c src/expr.l
config:
[ -f $(HOME) ] || cp .zrc $(HOME)
clean:
Expand Down
4 changes: 2 additions & 2 deletions doc/man1/expr.1
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ which writes to stdout, so square brackets should be used to access it.
.RB * , / , // , % ;
.SS Precedence level 13: implicit
.SS Functions
.RB log10 , log2 , log , sqrt , sin , cos , ctg , tg , floor , ceil , abs , round;
.RB log10 , log2 , ln / log , sqrt , sin , asin / arcsin , cos , acos / arccos , ctg / cot , actg / acot / arcctg / arccot , tg / tan , atg / atan / arctg / arctan , sec , arcsec / asec , csc / cosec , acsc / acosec / arccsc / arccosec / floor , ceil , abs , round , trunc;
.SS Other words
.RB nan , false , true ;
.SS Unary operators
Expand All @@ -58,7 +58,7 @@ to not clobber files. (and other obvious reasons, like double substitution. See
echo [expr 1&&2||(1?2:0)+5&(3<<1)]
echo [expr 1 + 2/ 3 + 4]
# RPN expression
# RPN expressions used to be supported, but now they have been removed.
echo [expr -r {1 2 + 3 '*' 2 '<<'}]
echo [expr {((1+2)*3)<<2}]
Expand Down
22 changes: 11 additions & 11 deletions examples/speedtest.out
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@

Bash will always be faster:
0.10user 0.08system 0:00.19elapsed 97%CPU (0avgtext+0avgdata 7108maxresident)k
0.16user 0.13system 0:00.30elapsed 96%CPU (0avgtext+0avgdata 7072maxresident)k
0inputs+0outputs (0major+1115minor)pagefaults 0swaps

Fish is also fast, but uses more memory:
0.18user 0.11system 0:00.85elapsed 35%CPU (0avgtext+0avgdata 17140maxresident)k
2704inputs+0outputs (5major+2713minor)pagefaults 0swaps
0.26user 0.12system 0:00.87elapsed 45%CPU (0avgtext+0avgdata 17268maxresident)k
2672inputs+0outputs (5major+2675minor)pagefaults 0swaps

Csh will use more CPU power:
1.39user 3.50system 0:04.99elapsed 98%CPU (0avgtext+0avgdata 4480maxresident)k
624inputs+0outputs (5major+324082minor)pagefaults 0swaps
1.11user 2.72system 0:03.96elapsed 96%CPU (0avgtext+0avgdata 4524maxresident)k
608inputs+0outputs (46major+323466minor)pagefaults 0swaps

Zrc will also have lower memory consumption:
4.30user 10.99system 0:15.31elapsed 99%CPU (0avgtext+0avgdata 5680maxresident)k
0inputs+0outputs (3major+1260626minor)pagefaults 0swaps
4.98user 12.44system 0:17.21elapsed 101%CPU (0avgtext+0avgdata 5680maxresident)k
0inputs+0outputs (172major+1288733minor)pagefaults 0swaps

Rc is way slower compared to Zrc in terms of performance:
9.73user 23.39system 0:33.51elapsed 98%CPU (0avgtext+0avgdata 3432maxresident)k
0inputs+0outputs (0major+3888094minor)pagefaults 0swaps
10.27user 27.52system 0:38.53elapsed 98%CPU (0avgtext+0avgdata 3304maxresident)k
192inputs+0outputs (228major+3875509minor)pagefaults 0swaps

Powershell performs the worst:
39.90user 67.96system 1:46.73elapsed 101%CPU (0avgtext+0avgdata 121192maxresident)k
131992inputs+264outputs (130major+784640minor)pagefaults 0swaps
64.93user 100.87system 2:37.94elapsed 104%CPU (0avgtext+0avgdata 125964maxresident)k
124856inputs+264outputs (398major+782808minor)pagefaults 0swaps

CONCLUSION: Zrc doesn't totally suck ;) It's just very lightweight
24 changes: 15 additions & 9 deletions sloccount.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,17 @@ Have a non-directory at the top, so creating directory src_top_dir
Adding /home/edward/.dots/work/etc/zrc.git/./src/config.hpp to src_top_dir
Adding /home/edward/.dots/work/etc/zrc.git/./src/dispatch.hpp to src_top_dir
Adding /home/edward/.dots/work/etc/zrc.git/./src/exec.hpp to src_top_dir
Adding /home/edward/.dots/work/etc/zrc.git/./src/expr.cpp to src_top_dir
Adding /home/edward/.dots/work/etc/zrc.git/./src/expr.l to src_top_dir
Adding /home/edward/.dots/work/etc/zrc.git/./src/expr.y to src_top_dir
Adding /home/edward/.dots/work/etc/zrc.git/./src/global.hpp to src_top_dir
Adding /home/edward/.dots/work/etc/zrc.git/./src/lex.hpp to src_top_dir
Adding /home/edward/.dots/work/etc/zrc.git/./src/lex.yy.c to src_top_dir
Adding /home/edward/.dots/work/etc/zrc.git/./src/main.cpp to src_top_dir
Adding /home/edward/.dots/work/etc/zrc.git/./src/sighandler.hpp to src_top_dir
Adding /home/edward/.dots/work/etc/zrc.git/./src/subst.hpp to src_top_dir
Adding /home/edward/.dots/work/etc/zrc.git/./src/variable.hpp to src_top_dir
Adding /home/edward/.dots/work/etc/zrc.git/./src/y.tab.c to src_top_dir
Adding /home/edward/.dots/work/etc/zrc.git/./src/y.tab.h to src_top_dir
Adding /home/edward/.dots/work/etc/zrc.git/./src/zlineedit.hpp to src_top_dir
Categorizing files.
Finding a working MD5 command....
Expand All @@ -41,7 +45,6 @@ WARNING! File /home/edward/.dots/work/etc/zrc.git/examples/is_prime.zrc has unkn
WARNING! File /home/edward/.dots/work/etc/zrc.git/examples/lexical_scoping.zrc has unknown start: #!../bin/zrc
WARNING! File /home/edward/.dots/work/etc/zrc.git/examples/loops.zrc has unknown start: #!../bin/zrc
WARNING! File /home/edward/.dots/work/etc/zrc.git/examples/man.cgi.zrc has unknown start: #!/usr/lib/zrc/bin/zrc
WARNING! File /home/edward/.dots/work/etc/zrc.git/examples/mandelbrot.zrc has unknown start: #!../bin/zrc
WARNING! File /home/edward/.dots/work/etc/zrc.git/examples/mgcsquare.zrc has unknown start: #!../bin/zrc
WARNING! File /home/edward/.dots/work/etc/zrc.git/examples/minesweeper.zrc has unknown start: #!../bin/zrc
WARNING! File /home/edward/.dots/work/etc/zrc.git/examples/oji_arhitect.zrc has unknown start: #!../bin/zrc
Expand All @@ -62,6 +65,7 @@ WARNING! File /home/edward/.dots/work/etc/zrc.git/examples/unique.zrc has unknow
WARNING! File /home/edward/.dots/work/etc/zrc.git/examples/whereis.zrc has unknown start: #!../bin/zrc
WARNING! File /home/edward/.dots/work/etc/zrc.git/examples/windowmgrmgr.zrc has unknown start: #!/usr/bin/env zrc
WARNING! File /home/edward/.dots/work/etc/zrc.git/examples/zsms.zrc has unknown start: #!/usr/lib/zrc/bin/zrc
WARNING! File /home/edward/.dots/work/etc/zrc.git/examples/mandelbrot.zrc has unknown start: #!../bin/zrc
WARNING! File /home/edward/.dots/work/etc/zrc.git/stdlib/cfuncs.zrc has unknown start: #!/usr/lib/zrc/bin/zrc
WARNING! File /home/edward/.dots/work/etc/zrc.git/stdlib/ipc.zrc has unknown start: #!/usr/lib/zrc/bin/zrc
WARNING! File /home/edward/.dots/work/etc/zrc.git/stdlib/list.zrc has unknown start: #!/usr/lib/zrc/bin/zrc
Expand All @@ -76,7 +80,7 @@ Computing results.


SLOC Directory SLOC-by-Language (Sorted)
3034 src_top_dir cpp=3034
3022 src_top_dir cpp=2851,lex=87,yacc=84
0 bin (none)
0 corebuf (none)
0 doc (none)
Expand All @@ -87,18 +91,20 @@ SLOC Directory SLOC-by-Language (Sorted)


Totals grouped by language (dominant language first):
cpp: 3034 (100.00%)
cpp: 2851 (94.34%)
lex: 87 (2.88%)
yacc: 84 (2.78%)




Total Physical Source Lines of Code (SLOC) = 3,034
Development Effort Estimate, Person-Years (Person-Months) = 0.64 (7.70)
Total Physical Source Lines of Code (SLOC) = 3,022
Development Effort Estimate, Person-Years (Person-Months) = 0.64 (7.67)
(Basic COCOMO model, Person-Months = 2.4 * (KSLOC**1.05))
Schedule Estimate, Years (Months) = 0.45 (5.43)
Schedule Estimate, Years (Months) = 0.45 (5.42)
(Basic COCOMO model, Months = 2.5 * (person-months**0.38))
Estimated Average Number of Developers (Effort/Schedule) = 1.42
Total Estimated Cost to Develop = $ 86,648
Estimated Average Number of Developers (Effort/Schedule) = 1.41
Total Estimated Cost to Develop = $ 86,288
(average salary = $56,286/year, overhead = 2.40).
SLOCCount, Copyright (C) 2001-2004 David A. Wheeler
SLOCCount is Open Source Software/Free Software, licensed under the GNU GPL.
Expand Down
62 changes: 42 additions & 20 deletions src/dispatch.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Macro for laziness
#define FOUND_FN(X) (funcs.find(argv[X]) != funcs.end())
#define OK(X) expr(X, ExprType::INFIX)
#define OK(X) expr(X)
#define de(X) { #X, zrc_builtin_##X }
#define ce(X,Y) { #X, zrc_builtin_##Y }, { #Y, zrc_builtin_##Y }

Expand Down Expand Up @@ -92,6 +92,35 @@ class BlockHandler
}
};

/** Converts a number to a std::string object.
*
* @param void
* @return void
*/
Inline std::string
ldtos(long double x)
{
std::string str;
size_t len;
/* empty */ {
std::stringstream ss;
ss << std::fixed << x;
str = ss.str();
}
if (str.find('.') != std::string::npos) {
while (!str.empty() && str.back() == '0')
str.pop_back();
if (!str.empty() && str.back() == '.')
str.pop_back();
}
return str;
}

/** Print directory stack contents.
*
* @param {stack<Path>}sp
* @return void
*/
static inline void
prints(std::stack<Path> sp)
{
Expand All @@ -107,7 +136,7 @@ prints(std::stack<Path> sp)
#define EXIT_SESSION \
ret_val = getvar($RETURN);\
exit((is_number(ret_val) && !ret_val.empty())\
? std::stoi(ret_val)\
? expr(ret_val)\
: EXIT_SUCCESS)\


Expand All @@ -128,15 +157,8 @@ Command(string) { return string(argc, argv); }
Command(concat) { return combine(argc, argv, 1); }
/** Clear screen **/
Command(clear) { std::cout << CLRSCR; NoReturn; }

/** Evaluates an arithmetic expression **/
Command(expr) {
ExprType et = INFIX;
if (argc > 1 && !strcmp(argv[1], "-r"))
et = RPN,
--argc, ++argv;
return itoa(expr(combine(argc, argv, 1), et));
}
Command(expr) { return ldtos(expr(combine(argc, argv, 1))); }

/** Executes a block if an expression evaluates non-zero **/
Command(if) {
Expand Down Expand Up @@ -494,10 +516,10 @@ Command(read) {
case 'n':
if (d != '\n')
syntax_error(se);
n = atoi(optarg);
n = (ull)expr(optarg);
break;
case 'f':
fd = atoi(optarg);
fd = (ull)expr(optarg);
break;
case 'p':
std::cout << optarg << std::flush;
Expand Down Expand Up @@ -549,9 +571,9 @@ Command(inc) {
if (argc < 2)
syntax_error("<var> [val]");
if (argc >= 3)
val = expr(combine(argc, argv, 2));
val = combine(argc, argv, 2);
var = getvar(argv[1]);
ret_val = expr(zrc_fmt("(%s)+(%s)", var.data(), val.data()));
ret_val = ldtos(expr(zrc_fmt("(%s)+(%s)", var.data(), val.data())));
setvar(argv[1], ret_val);
NoReturn;
}
Expand All @@ -573,10 +595,10 @@ Command(set) {
size_t len = strlen(argv[i]);
if (argv[i][len-1] == '=') {
argv[i][len-1] = '\0';
setvar(argv[i-1], expr(zrc_fmt("(%s)%s(%s)",
setvar(argv[i-1], ldtos(expr(zrc_fmt("(%s)%s(%s)",
getvar(argv[i-1]).data(),
argv[i],
argv[i+1])));
argv[i+1]))));
} else syntax_error(se);
}
}
Expand All @@ -589,8 +611,8 @@ Command(chr) {
syntax_error("<o>");
std::string t;
auto ret = expr(combine(argc, argv, 1));
if (is_number(ret))
t += (char)std::stoi(ret);
if (ret != NAN)
t += (char)ret;
return t;
}
Command(ord) {
Expand Down Expand Up @@ -795,7 +817,7 @@ Command(shift) {
if (argc > 2)
syntax_error("[<n>]");
if (argc == 2)
howmuch = atoi(argv[1]);
howmuch = (ull)expr(argv[1]);

//shift to left
for (i = 0; i < len-howmuch; ++i)
Expand Down Expand Up @@ -831,7 +853,7 @@ Command(rlimit) {
if (argc != 2)
syntax_error("<n>");

rlim_t memory = std::stoull(argv[1]);
rlim_t memory = (ull)expr(argv[1]);
struct rlimit rlm;
int err;
short exp = 0;
Expand Down
Loading

0 comments on commit 71206d3

Please sign in to comment.