C++ Mathematical Expression Toolkit (ExprTk) release
Loading...
Searching...
No Matches
exprtk_repl.cpp
Go to the documentation of this file.
1/*
2 **************************************************************
3 * C++ Mathematical Expression Toolkit Library *
4 * *
5 * ExprTk REPL (Read Evaluate Print Loop) Interface *
6 * Author: Arash Partow (1999-2024) *
7 * URL: https://www.partow.net/programming/exprtk/index.html *
8 * *
9 * Copyright notice: *
10 * Free use of the Mathematical Expression Toolkit Library is *
11 * permitted under the guidelines and in accordance with the *
12 * most current version of the MIT License. *
13 * https://www.opensource.org/licenses/MIT *
14 * SPDX-License-Identifier: MIT *
15 * *
16 **************************************************************
17*/
18
19
20#include <algorithm>
21#include <cstdio>
22#include <deque>
23#include <fstream>
24#include <iostream>
25#include <numeric>
26#include <string>
27
28#include "exprtk.hpp"
29
30
31template <typename T>
32struct putch : public exprtk::ifunction<T>
33{
34 using exprtk::ifunction<T>::operator();
35
36 putch() : exprtk::ifunction<T>(1) {}
37
38 inline T operator()(const T& v)
39 {
40 printf("%c",static_cast<int>(v));
41 return T(0);
42 }
43};
44
45template <typename T>
46struct putint : public exprtk::ifunction<T>
47{
48 using exprtk::ifunction<T>::operator();
49
50 putint() : exprtk::ifunction<T>(1) {}
51
52 inline T operator()(const T& v)
53 {
54 printf("%d",static_cast<int>(v));
55 return T(0);
56 }
57};
58
59template <typename T>
60struct rnd_01 : public exprtk::ifunction<T>
61{
62 using exprtk::ifunction<T>::operator();
63
65 { ::srand(static_cast<unsigned int>(time(NULL))); }
66
67 inline T operator()()
68 {
69 // Note: Do not use this in production
70 // Result is in the interval [0,1)
71 return T(::rand() / T(RAND_MAX + 1.0));
72 }
73};
74
75template <typename T>
77{
78public:
79
88
89 typedef typename parser_t::dependent_entity_collector::symbol_t symbol_t;
90 typedef std::vector<symbol_t> symbol_list_t;
91
93 : persist_symbol_table_ (false)
94 , symbol_dump_ (false)
95 , assignment_dump_ (false)
96 , display_total_time_ (false)
98 , enable_usr_ (false)
99 , disable_local_vardef_ (false)
100 , batch_runs_cnt_ (0 )
102 #ifdef exprtk_enable_repl_variables
103 , s0_("abcdefghijk")
104 , s1_("abcdefghijk0123456789")
105 , s2_("012345678901234567890123456789")
106 , v0_({ 1, 1, 1 })
107 , v1_({ 2, 2, 2, 2, 2})
108 , v2_({ 3, 3, 3, 3, 3, 3, 3})
109 , v3_({ 4, 4, 4, 4, 4, 4, 4, 4})
110 , vv_(exprtk::make_vector_view(v2_,v2_.size()))
111 #endif
112 {
114
121
134
135 #ifdef exprtk_enable_repl_variables
136 symbol_table_.add_stringvar("s0", s0_);
137 symbol_table_.add_stringvar("s1", s1_);
138 symbol_table_.add_stringvar("s2", s2_);
139 symbol_table_.add_vector ("v0", v0_);
140 symbol_table_.add_vector ("v1", v1_);
141 symbol_table_.add_vector ("v2", v2_);
142 symbol_table_.add_vector ("v3", v3_);
143
144 vv_ = exprtk::make_vector_view(v2_,v2_.size());
145 symbol_table_.add_vector ("vv", vv_);
146 #endif
147
149
156
163
172
174 }
175
180
182 {
184 }
185
187 {
188 return symbol_dump_;
189 }
190
192 {
193 return assignment_dump_;
194 }
195
197 {
198 return display_total_time_;
199 }
200
205
207 {
208 return enable_usr_;
209 }
210
212 {
214 }
215
225
226 void process(std::string program)
227 {
228 program = trim_whitespace(program);
229
230 if (program.empty())
231 return;
232
234
235 expression_t expression;
238
239 exprtk::timer compile_timer;
240 compile_timer.start();
241
242 if (enable_usr_)
244 else
246
249 else
251
254
256
257 if (!parser_.compile(program,expression))
258 {
259 printf("Error: %s\tExpression:%c%s\n",
260 parser_.error().c_str(),
261 ((std::string::npos != program.find_first_of('\n')) ? '\n' : ' '),
262 ((program.size() < 200) ? program.c_str() : "....."));
263
264 for (std::size_t i = 0; i < parser_.error_count(); ++i)
265 {
266 error_t error = parser_.get_error(i);
267
268 printf("Err No.: %02d Pos: %02d Type: [%14s] Msg: %s\n",
269 static_cast<unsigned int>(i),
270 static_cast<unsigned int>(error.token.position),
271 exprtk::parser_error::to_str(error.mode).c_str(),
272 error.diagnostic.c_str());
273
274 if (
275 (0 == i) &&
277 )
278 {
279 printf("Error (line: %d column: %d)\n",
280 static_cast<unsigned int>(error.line_no),
281 static_cast<unsigned int>(error.column_no));
282
283 printf("%s \n",error.error_line.c_str());
284 printf("%s^\n",std::string(error.column_no,'~').c_str());
285 }
286 }
287
288 return;
289 }
290
291 compile_timer.stop();
292
294 {
295 printf("\nCompile time: %6.3fms\n",compile_timer.time() * 1000.0);
296 }
297
298 if (batch_runs_cnt_)
299 {
300 std::vector<double> timings(batch_runs_cnt_,0.0);
301
302 exprtk::timer total_timer;
303 exprtk::timer timer;
304
305 T result = T(0);
306
307 total_timer.start();
308
309 for (std::size_t i = 0; i < batch_runs_cnt_; ++i)
310 {
311 timer.start();
312
313 result = expression.value();
314
315 timer.stop();
316
317 timings[i] = timer.time() * 1000.0;
318 }
319
320 total_timer.stop();
321
322 printf("\nResult: %15.9f\n",result);
323
324 std::sort(timings.begin(),timings.end());
325
326 printf("\nRuns: %4d Time min: %7.3fms max: %7.3fms avg: %7.3fms tot: %7.3fms 90%%:%7.3fms\n",
327 static_cast<unsigned int>(batch_runs_cnt_),
328 timings.front(),
329 timings.back (),
330 std::accumulate(timings.begin(),timings.end(),0.0) / timings.size(),
331 total_timer.time() * 1000.0,
332 timings[static_cast<int>(timings.size() * 0.90)]);
333
334 return;
335 }
336
337 exprtk::timer timer;
338 timer.start();
339
340 const T result = expression.value();
341
342 timer.stop();
343
344 if (expression.results().count())
345 {
346 print_results(expression.results());
347 }
348
349 printf("\nResult: %15.9f\n",result);
350
352 {
353 printf("\nTotal time: %6.3fms\n",timer.time() * 1000.0);
354 }
355
356 if (symbol_dump_)
357 {
358 symbol_list_t symbol_list;
359
360 parser_.dec().symbols(symbol_list);
361
362 printf("------ Symbols ------\n");
363 perform_symbol_dump(symbol_list);
364 printf("---------------------\n");
365 }
366
368 {
369 symbol_list_t assignment_list;
370
371 parser_.dec().assignment_symbols(assignment_list);
372
373 printf("---- Assignments ----\n");
374 perform_symbol_dump(assignment_list);
375 printf("---------------------\n");
376 }
377 }
378
379 void process_from_file(const std::string& file_name)
380 {
381 if (file_name.empty())
382 return;
383
384 std::ifstream stream(file_name.c_str());
385
386 if (!stream)
387 {
388 printf("ERROR: Failed to open file: %s\n\n",file_name.c_str());
389 return;
390 }
391
392 std::string program(
393 (std::istreambuf_iterator<char>(stream)),
394 (std::istreambuf_iterator<char>())
395 );
396
397 process_function_definition(program,false);
398 }
399
400 void process_directive(std::string expression)
401 {
402 expression = trim_whitespace(expression);
403
404 if ('$' != expression[0])
405 return;
406 else if ("$enable_cache" == expression)
407 persist_symbol_table() = true;
408 else if ("$disable_cache" == expression)
409 persist_symbol_table() = false;
410 else if ("$enable_symbol_dump" == expression)
411 symbol_dump() = true;
412 else if ("$disable_symbol_dump" == expression)
413 symbol_dump() = false;
414 else if ("$enable_assignment_dump" == expression)
415 assignment_dump() = true;
416 else if ("$disable_assignment_dump" == expression)
417 assignment_dump() = false;
418 else if ("$enable_timer" == expression)
419 display_total_time() = true;
420 else if ("$enable_compile_timer" == expression)
422 else if ("$disable_timer" == expression)
423 display_total_time() = false;
424 else if ("$disable_compile_timer" == expression)
426 else if ("$enable_usr" == expression)
427 enable_usr() = true;
428 else if ("$disable_usr" == expression)
429 enable_usr() = false;
430 else if ("$enable_local_vardef" == expression)
431 disable_local_vardef() = false;
432 else if ("$disable_local_vardef" == expression)
433 disable_local_vardef() = true;
434 else if ("$list_vars" == expression)
435 list_symbols();
436 else if ("$clear_functions" == expression)
438 else if ((0 == expression.find("$batch_run ")) && (expression.size() >= 12))
439 process_batch_run(expression.substr(11,expression.size() - 11));
440 else if ((0 == expression.find("$load ")) && (expression.size() > 7))
441 process_from_file(expression.substr(6,expression.size() - 6));
442 else if ((0 == expression.find("$disable arithmetic ")) && (expression.size() >= 21))
443 process_disable_arithmetic(expression.substr(20,expression.size() - 20));
444 else if ((0 == expression.find("$disable assignment ")) && (expression.size() >= 21))
445 process_disable_assignment(expression.substr(20,expression.size() - 20));
446 else if ((0 == expression.find("$disable inequality ")) && (expression.size() >= 21))
447 process_disable_inequality(expression.substr(20,expression.size() - 20));
448 else if ((0 == expression.find("$enable arithmetic ")) && (expression.size() >= 20))
449 process_enable_arithmetic(expression.substr(19,expression.size() - 19));
450 else if ((0 == expression.find("$enable assignment ")) && (expression.size() >= 20))
451 process_enable_assignment(expression.substr(19,expression.size() - 19));
452 else if ((0 == expression.find("$enable inequality ")) && (expression.size() >= 20))
453 process_enable_inequality(expression.substr(19,expression.size() - 19));
454 else if ("$begin" == expression)
456 else if (0 == expression.find("$function"))
457 process_function_definition(expression);
458 else
459 printf("\nERROR - Invalid directive: %s\n",expression.c_str());
460 }
461
462private:
463
465 {
466 typedef exprtk::results_context<T> results_context_t;
467 typedef typename results_context_t::type_store_t type_t;
468 typedef typename type_t::scalar_view scalar_t;
469 typedef typename type_t::vector_view vector_t;
470 typedef typename type_t::string_view string_t;
471
473
474 printf("%s\n",std::string(10,'-').c_str());
475 printf("Return Results (#%d)\n",static_cast<int>(results.count()));
476
477 for (std::size_t i = 0; i < results.count(); ++i)
478 {
479 printf("[%02d] ",static_cast<int>(i));
480
481 type_t t = results[i];
482
483 switch (t.type)
484 {
485 case type_t::e_scalar : printf("Scalar\t");
486 exprtk::rtl::io::details::print_type("%10.5f",scalar_t(t)(),num_type);
487 break;
488
489 case type_t::e_vector : {
490 printf("Vector\t");
491 vector_t vector(t);
492
493 for (std::size_t x = 0; x < vector.size(); ++x)
494 {
495 exprtk::rtl::io::details::print_type("%10.5f",vector[x],num_type);
496
497 if ((x + 1) < vector.size())
498 printf(" ");
499 }
500 }
501 break;
502
503 case type_t::e_string : printf("String\t");
504 printf("%s",to_str(string_t(t)).c_str());
505 break;
506
507 default : continue;
508 }
509
510 printf("\n");
511 }
512
513 printf("%s\n",std::string(10,'-').c_str());
514 }
515
516 void perform_symbol_dump(const symbol_list_t& variable_list) const
517 {
518 for (std::size_t i = 0; i < variable_list.size(); ++i)
519 {
520 const symbol_t& symbol = variable_list[i];
521
522 switch (symbol.second)
523 {
524 case parser_t::e_st_variable : printf("[%02d] Variable %s\n",
525 static_cast<int>(i),symbol.first.c_str());
526 break;
527
528 case parser_t::e_st_vector : printf("[%02d] Vector %s\n",
529 static_cast<int>(i),symbol.first.c_str());
530 break;
531
532 case parser_t::e_st_string : printf("[%02d] String %s\n",
533 static_cast<int>(i),symbol.first.c_str());
534 break;
535
536 case parser_t::e_st_function : printf("[%02d] Function %s\n",
537 static_cast<int>(i),symbol.first.c_str());
538 break;
539
541 : printf("[%02d] LocalVar %s\n",
542 static_cast<int>(i),symbol.first.c_str());
543 break;
544
546 : printf("[%02d] LocalVec %s\n",
547 static_cast<int>(i),symbol.first.c_str());
548 break;
549
551 : printf("[%02d] LocalStr %s\n",
552 static_cast<int>(i),symbol.first.c_str());
553 break;
554
555 default : break;
556 }
557 }
558 }
559
560 void process_batch_run(const std::string& batch_runs_cnt)
561 {
562 batch_runs_cnt_ = atoi(batch_runs_cnt.c_str());
563 }
564
566 {
567 std::string program;
568
569 for ( ; ; )
570 {
571 std::string line;
572
573 std::cout << ">> ";
574 std::getline(std::cin,line);
575
576 line = trim_whitespace(line);
577
578 if (line.empty())
579 continue;
580 else if ("$end" == line)
581 break;
582 else
583 program += (line + "\n");
584 }
585
586 process(program);
587 }
588
589 struct function_definition
590 {
591 std::string name;
592 std::string body;
593 std::vector<std::string> var_list;
594
595 void clear()
596 {
597 name .clear();
598 body .clear();
599 var_list.clear();
600 }
601 };
602
604 {
605 e_parse_unknown = 0,
606 e_parse_success = 1,
607 e_parse_partial = 2,
608 e_parse_lexfail = 4,
610 };
611
612 struct parse_function_definition_impl : public exprtk::lexer::parser_helper
613 {
615 {
616 if (!init(func_def))
617 return e_parse_lexfail;
618
619 if (!token_is(token_t::e_symbol,"function"))
620 return e_parse_notfunc;
621
623 return e_parse_partial;
624
625 fd.name = current_token().value;
626
627 next_token();
628
630 return e_parse_partial;
631
633 {
634 std::vector<std::string> var_list;
635
636 for ( ; ; )
637 {
638 // (x,y,z,....w)
640 return e_parse_partial;
641
642 var_list.push_back(current_token().value);
643
644 next_token();
645
647 break;
648
650 return e_parse_partial;
651 }
652
653 var_list.swap(fd.var_list);
654 }
655
656 const std::size_t body_begin = current_token().position;
657 std::size_t body_end = current_token().position;
658
659 int bracket_stack = 0;
660
662 return e_parse_partial;
663
664 for ( ; ; )
665 {
666 body_end = current_token().position;
667
669 bracket_stack++;
671 {
672 if (0 == --bracket_stack)
673 break;
674 }
675 else
676 {
677 if (lexer().finished())
678 return e_parse_partial;
679
680 next_token();
681 }
682 }
683
684 const std::size_t size = body_end - body_begin + 1;
685
686 fd.body = func_def.substr(body_begin,size);
687
688 const std::size_t index = body_begin + size;
689
690 if (index < func_def.size())
691 func_def = func_def.substr(index,func_def.size() - index);
692 else
693 func_def = "";
694
695 return e_parse_success;
696 }
697 };
698
700 {
702 return parser.process(func_def,cf);
703 }
704
705 std::string read_from_stdin()
706 {
707 std::string input;
708
709 for ( ; ; )
710 {
711 std::string line;
712
713 std::cout << ">> ";
714 std::getline(std::cin,line);
715
716 if (line.empty())
717 continue;
718 else if ("$end" == line)
719 break;
720 else
721 input += (line + "\n");
722 }
723
724 if (!input.empty())
725 input.erase(input.end() - 1);
726
727 return input;
728 }
729
730 void process_function_definition(const std::string& func_def_header, bool read_stdin = true)
731 {
732 std::string func_def = func_def_header;
733
734 if (read_stdin)
735 {
736 func_def += read_from_stdin();
737
738 if (!func_def.empty() && ('$' == func_def[0]))
739 func_def.erase(func_def.begin());
740 }
741
742 do
743 {
745
746 func_parse_result fp_result = parse_function_definition(func_def,fd);
747
748 if (e_parse_success == fp_result)
749 {
750 std::string vars;
751
752 for (std::size_t i = 0; i < fd.var_list.size(); ++i)
753 {
754 vars += fd.var_list[i] + ((i < fd.var_list.size() - 1) ? "," : "");
755 }
756
757 function_t f(fd.name);
758
759 for (std::size_t i = 0; i < fd.var_list.size(); ++i)
760 {
761 f.var(fd.var_list[i]);
762 }
763
764 f.expression(fd.body);
765
767 {
769
770 for (std::size_t i = 0; i < func_def_list_.size(); ++i)
771 {
772 if (exprtk::details::imatch(fd.name, func_def_list_[i].name))
773 {
774 func_def_list_.erase(func_def_list_.begin() + i);
775
776 break;
777 }
778 }
779 }
780
781 if (!compositor_.add(f,true))
782 {
784
785 printf("Error - Failed to add function: %s\n",fd.name.c_str());
786
787 return;
788 }
789
790 printf("Function[%02d]\n",static_cast<int>(func_def_list_.size()));
791 printf("Name: %s \n",fd.name.c_str() );
792 printf("Vars: (%s) \n",vars.c_str() );
793 printf("------------------------------------------------------\n");
794
795 func_def_list_.push_back(fd);
796 }
797 else if (e_parse_notfunc != fp_result)
798 {
799 printf("Error - Critical parsing error - partial parse occurred\n");
800 return;
801 }
802 else
803 break;
804 }
805 while (!func_def.empty());
806
807 if (!func_def.empty())
808 {
809 process(func_def);
810 }
811 }
812
814 {
815 std::deque<std::pair<std::string,T> > variable_list;
816 symbol_table_.get_variable_list(variable_list);
817
818 std::size_t max_varname_length = 0;
819
820 for (std::size_t i = 0; i < variable_list.size(); ++i)
821 {
822 max_varname_length = std::max(max_varname_length,variable_list[i].first.size());
823 }
824
825 for (std::size_t i = 0; i < variable_list.size(); ++i)
826 {
827 int pad_length = 0;
828
829 if (max_varname_length > variable_list[i].first.size())
830 {
831 pad_length = static_cast<int>(max_varname_length - variable_list[i].first.size());
832 }
833
834 printf("%02d %s%*.*s %25.10f\n",
835 static_cast<unsigned int>(i),
836 variable_list[i].first.c_str(),
837 pad_length,
838 pad_length,
839 std::string(max_varname_length,' ').c_str(),
840 variable_list[i].second);
841 }
842 }
843
845 {
846 func_def_list_.clear();
848 }
849
850 std::string trim_whitespace(std::string s)
851 {
852 static const std::string whitespace(" \n\r\t\b\v\f");
853
854 if (!s.empty())
855 {
856 s.erase(0,s.find_first_not_of(whitespace));
857
858 if (!s.empty())
859 {
860 std::size_t index = s.find_last_not_of(whitespace);
861
862 if (std::string::npos != index)
863 s.erase(index + 1);
864 else
865 s.clear();
866 }
867 }
868
869 return s;
870 }
871
872 void process_disable_arithmetic(const std::string& arithmetic)
873 {
874 typename std::map<std::string,typename settings_store_t::settings_arithmetic_opr>::iterator itr;
875
876 if (arith_opr_.end() != (itr = arith_opr_.find(arithmetic)))
877 {
879 .disable_arithmetic_operation(itr->second);
880 }
881 }
882
883 void process_disable_assignment(const std::string& assignment)
884 {
885 typename std::map<std::string,typename settings_store_t::settings_assignment_opr>::iterator itr;
886
887 if (assign_opr_.end() != (itr = assign_opr_.find(assignment)))
888 {
890 .disable_assignment_operation(itr->second);
891 }
892 }
893
894 void process_disable_inequality(const std::string& inequality)
895 {
896 typename std::map<std::string,typename settings_store_t::settings_inequality_opr>::iterator itr;
897
898 if (inequality_opr_.end() != (itr = inequality_opr_.find(inequality)))
899 {
901 .disable_inequality_operation(itr->second);
902 }
903 }
904
905 void process_enable_arithmetic(const std::string& arithmetic)
906 {
907 typename std::map<std::string,typename settings_store_t::settings_arithmetic_opr>::iterator itr;
908
909 if (arith_opr_.end() != (itr = arith_opr_.find(arithmetic)))
910 {
912 .enable_arithmetic_operation(itr->second);
913 }
914 }
915
916 void process_enable_assignment(const std::string& assignment)
917 {
918 typename std::map<std::string,typename settings_store_t::settings_assignment_opr>::iterator itr;
919
920 if (assign_opr_.end() != (itr = assign_opr_.find(assignment)))
921 {
923 .enable_assignment_operation(itr->second);
924 }
925 }
926
927 void process_enable_inequality(const std::string& inequality)
928 {
929 typename std::map<std::string,typename settings_store_t::settings_inequality_opr>::iterator itr;
930
931 if (inequality_opr_.end() != (itr = inequality_opr_.find(inequality)))
932 {
934 .enable_inequality_operation(itr->second);
935 }
936 }
937
938
939private:
940
942 bool symbol_dump_;
943 bool assignment_dump_;
946 bool enable_usr_;
948 std::size_t batch_runs_cnt_;
949
954
955 putch <T> putch_;
956 putint <T> putint_;
957 rnd_01 <T> rnd_01_;
961
974
975 std::vector<function_definition> func_def_list_;
976
977 std::map<std::string,typename settings_store_t::settings_arithmetic_opr> arith_opr_;
978 std::map<std::string,typename settings_store_t::settings_assignment_opr> assign_opr_;
979 std::map<std::string,typename settings_store_t::settings_inequality_opr> inequality_opr_;
980
981 #ifdef exprtk_enable_repl_variables
982 std::string s0_;
983 std::string s1_;
984 std::string s2_;
985 std::vector<T> v0_;
986 std::vector<T> v1_;
987 std::vector<T> v2_;
988 std::vector<T> v3_;
990 #endif
991};
992
993template <typename T>
994void repl(int argc, char* argv[])
995{
996 expression_processor<T> processor;
997
998 if (argc > 1)
999 {
1000 for (int i = 1; i < argc; ++i)
1001 {
1002 processor.process_from_file(argv[i]);
1003 }
1004 }
1005 else
1006 {
1007 for ( ; ; )
1008 {
1009 std::string expression;
1010
1011 std::cout << ">> ";
1012 std::getline(std::cin,expression);
1013
1014 if (expression.empty())
1015 continue;
1016 else if ("exit" == expression)
1017 break;
1018 else if ("quit" == expression)
1019 break;
1020 else if ('$' == expression[0])
1021 processor.process_directive(expression);
1022 else
1023 processor.process(expression);
1024 }
1025 }
1026}
1027
1028int main(int argc, char* argv[])
1029{
1030 repl<double>(argc,argv);
1031 return 0;
1032}
1033
1034
1035/*
1036
1037REPL commands:
1038
1039 $enable_cache/$disable_cache
1040 Enable or disable caching of variables.
1041
1042 $enable_symbol_dump/$disable_symbol_dump
1043 Enable or disable dumping of symbols found in expression during
1044 compilation process.
1045
1046 $enable_assignment_dump/$disable_assignment_dump
1047 Enable or disable dumping of symbols that undergo assignment in
1048 expression.
1049
1050 $enable_timer/$disable_timer
1051 Enable or disable expression evaluation timer.
1052
1053 $enable_compile_timer/$disable_compile_timer
1054 Enable or disable compilation timer
1055
1056 $enable_usr/$disable_usr
1057 Enable or disable unknown symbol resolver.
1058
1059 $list_vars
1060 List variables found in the global symbol table.
1061
1062 $clear_functions
1063 Clear all functions found in the global function symbol table.
1064
1065 $load <program file name>
1066 Load the file as a complete program and execute.
1067
1068 $begin/$end
1069 Pre/post-ambles for multiline expressions.
1070
1071
1072Example REPL Instructions:
1073 Step 1.1 Enter: var x := 3; var y := 4; var z := x + y; println(z / 2);
1074 Step 1.2 Enter: var x := 3; var y := 4; var z := x - y; putint(z / 2);
1075
1076
1077 Step 2.Enter the following multi-line program:
1078 --- snip ---
1079
1080$begin
1081var x := 3;
1082var y := 4;
1083var z := sin(x / pi) * cos(y * pi);
1084println(z / 2);
1085$end
1086
1087 --- snip ---
1088
1089
1090 Step 3.1 Create a new file called mandelbrot.txt
1091 Step 3.2 Copy the contents between the snip lines into the file
1092 Step 3.3 Execute: ./exprtk_repl mandelbrot.txt
1093
1094
1095 Step 4.1 Execute: ./exprtk_repl
1096 Step 4.2 Enter: $load mandelbrot.txt
1097
1098---- snip ----
1099
1100var width := 118;
1101var height := 41;
1102var imag_max := +1;
1103var imag_min := -1;
1104var real_max := +1;
1105var real_min := -2.5;
1106var x_step := (real_max - real_min) / width;
1107var y_step := (imag_max - imag_min) / height;
1108
1109for (var y := 0; y < height; y += 1)
1110{
1111 var imag := imag_min + (y_step * y);
1112
1113 for (var x := 0; x < width; x += 1)
1114 {
1115 var real := real_min + x_step * x;
1116 var z_real := real;
1117 var z_imag := imag;
1118 var plot_value := 0;
1119
1120 for (var n := 0; n < 30; n += 1)
1121 {
1122 var a := z_real^2;
1123 var b := z_imag^2;
1124
1125 plot_value := n;
1126
1127 if ((a + b) < 4)
1128 {
1129 z_imag := 2 * z_real * z_imag + imag;
1130 z_real := a - b + real;
1131 }
1132 else
1133 break;
1134 };
1135
1136 putch(61 - plot_value);
1137
1138 };
1139
1140 println()
1141}
1142
1143---- snip ----
1144
1145
1146 Step 5.1 Copy into the REPL the contents of the snippet below:
1147---- snip ----
1148$function is_prime(x)
1149{
1150 if (x == 1)
1151 return [false];
1152 else if (x == 2)
1153 return [true];
1154 else if ((x % 2) == 0)
1155 return [false];
1156
1157 var upper_bound := sqrt(x) + 1;
1158
1159 for (var i := 3; i <= upper_bound; i += 2)
1160 {
1161 if (0 == (x % i))
1162 {
1163 return[false];
1164 }
1165 };
1166
1167 return [true];
1168}
1169$end
1170
1171$begin
1172for (var i := 1; i < 50; i += 1)
1173{
1174 if (is_prime(i))
1175 {
1176 println(i);
1177 }
1178}
1179$end
1180
1181---- snip ----
1182
1183
1184 Step 6.1 Copy into the REPL the contents of the snippet below:
1185---- snip ----
1186
1187$begin
1188var s := 'abcdefghijkl';
1189for (var i := 0; i < (s[] / 2); i+= 1)
1190{
1191 var j := s[] - i - 1;
1192 s[i:i + 1] <=> s[j:j + 1];
1193};
1194
1195println(s)
1196$end
1197
1198---- snip ----
1199
1200
1201 Step 7.1 Copy into the REPL the contents of the snippet below:
1202---- snip ----
1203$begin
1204var vec[11] := { -1, -2, 3, 5, 6, -2, -1, 4, -4, 2, -1 };
1205var zero := 0;
1206var max_sum := 0;
1207var max_start := 0;
1208var max_end := 0;
1209var curr_sum := 0;
1210var curr_start := 0;
1211
1212for (var i := 0; i < vec[]; i += 1)
1213{
1214 curr_sum += vec[i];
1215
1216 if (curr_sum < zero)
1217 {
1218 curr_sum := 0;
1219 curr_start := i + 1;
1220 }
1221 else if (curr_sum > max_sum)
1222 {
1223 max_sum := curr_sum;
1224 max_start := curr_start;
1225 max_end := i;
1226 }
1227}
1228
1229println('vec: ',vec);
1230
1231println('Max sum: ', max_sum );
1232println('Start index: ', max_start);
1233println('End index: ', max_end );
1234
1235for (var i := max_start; i <= max_end; i += 1)
1236{
1237 print(vec[i],' ');
1238}
1239$end
1240
1241---- snip ----
1242
1243
1244 Step 8.1 Copy into the REPL the contents of the snippet below:
1245---- snip ----
1246
1247$function is_prime(x)
1248{
1249 if (x <= 0)
1250 return [false];
1251 else if (frac(x) != 0)
1252 return [false];
1253 else
1254 {
1255 switch
1256 {
1257 case 1 == x : return [false];
1258 case 2 == x : return [true ];
1259 default :
1260 {
1261 var prime_lut[160] :=
1262 {
1263 2, 3, 5, 7, 11, 13, 17, 19, 23, 29,
1264 31, 37, 41, 43, 47, 53, 59, 61, 67, 71,
1265 73, 79, 83, 89, 97, 101, 103, 107, 109, 113,
1266 127, 131, 137, 139, 149, 151, 157, 163, 167, 173,
1267 179, 181, 191, 193, 197, 199, 211, 223, 227, 229,
1268 233, 239, 241, 251, 257, 263, 269, 271, 277, 281,
1269 283, 293, 307, 311, 313, 317, 331, 337, 347, 349,
1270 353, 359, 367, 373, 379, 383, 389, 397, 401, 409,
1271 419, 421, 431, 433, 439, 443, 449, 457, 461, 463,
1272 467, 479, 487, 491, 499, 503, 509, 521, 523, 541,
1273 547, 557, 563, 569, 571, 577, 587, 593, 599, 601,
1274 607, 613, 617, 619, 631, 641, 643, 647, 653, 659,
1275 661, 673, 677, 683, 691, 701, 709, 719, 727, 733,
1276 739, 743, 751, 757, 761, 769, 773, 787, 797, 809,
1277 811, 821, 823, 827, 829, 839, 853, 857, 859, 863,
1278 877, 881, 883, 887, 907, 911, 919, 929, 937, 941
1279 };
1280
1281 var upper_bound := min(x - 1,trunc(sqrt(x)) + 1);
1282
1283 for (var i := 0; i < prime_lut[]; i += 1)
1284 {
1285 if (prime_lut[i] >= upper_bound)
1286 return [true];
1287 else if ((x % prime_lut[i]) == 0)
1288 return [false];
1289 };
1290
1291 var lower_bound := prime_lut[prime_lut[] - 1] + 2;
1292
1293 for (var i := lower_bound; i < upper_bound; i += 2)
1294 {
1295 if ((x % i) == 0)
1296 {
1297 return [false];
1298 }
1299 }
1300 };
1301 }
1302 };
1303
1304 return [true];
1305}
1306
1307var prime_count := 0;
1308
1309for (var i := 1; i < 10^6; i += 1)
1310{
1311 if (is_prime(i))
1312 {
1313 prime_count += 1;
1314 }
1315};
1316
1317prime_count
1318$end
1319---- snip ----
1320
1321
1322Step 9.1 Copy into the REPL the contents of the snippet below:
1323---- snip ----
1324$begin
1325var file := open('file.txt','w');
1326var s := 'Hello world...\n';
1327
1328for (var i := 0; i < 10; i += 1)
1329{
1330 write(file,s);
1331};
1332
1333close(file);
1334
1335println('~~~~~~~~~~~~~~~~~~~~~~');
1336
1337file := open('file.txt','r');
1338var i := 0;
1339
1340while (not(eof(file)))
1341{
1342 s := getline(file);
1343
1344 if (s[] > 0)
1345 {
1346 println('[',i+=1,'] - ',s);
1347 }
1348};
1349
1350close(file);
1351$end
1352---- snip ----
1353
1354
1355Step 10.1 Copy into the REPL the contents of the snippet below:
1356---- snip ----
1357$begin
1358var v0[1000] := [rnd_01];
1359var v1[1000] := [0];
1360
1361~{
1362 var file := open('data.dat','w');
1363
1364 if (not(write(file,v0)))
1365 {
1366 println('failed to write vector 0\n');
1367 return [false];
1368 };
1369
1370 close(file);
1371 };
1372
1373~{
1374 var file := open('data.dat','r');
1375
1376 if (not(read(file,v1)))
1377 {
1378 println('failed to read vector 1\n');
1379 return [false];
1380 };
1381
1382 close(file);
1383 };
1384
1385if (sum(v0 != v1) > 0)
1386 println('error: v0 != v1');
1387else
1388{
1389 println('success: v0 == v1');
1390 println('sum(v0) = ',sum(v0),' avg(v0) = ',avg(v0));
1391 println('sum(v1) = ',sum(v1),' avg(v1) = ',avg(v1));
1392}
1393$end
1394---- snip ----
1395
1396
1397Step 11.1 Copy into the REPL the contents of the snippet below:
1398---- snip ----
1399$function fibonacci(x)
1400{
1401 switch
1402 {
1403 case x == 0 : 0;
1404 case x == 1 : 1;
1405 default :
1406 {
1407 var prev := 0;
1408 var curr := 1;
1409 while ((x -= 1) > 0)
1410 {
1411 curr += (curr <=> prev);
1412 };
1413 };
1414 }
1415}
1416
1417for (var i := 0; i < 20; i += 1)
1418{
1419 println(i, ' = ', fibonacci(i));
1420};
1421
1422$end
1423---- snip ----
1424
1425*/
void print_results(const exprtk::results_context< T > &results)
exprtk::rtl::io::file::package< T > fileio_package_
exprtk::polynomial< T, 6 > poly06_
void process_enable_inequality(const std::string &inequality)
exprtk::expression< T > expression_t
exprtk::polynomial< T, 5 > poly05_
std::vector< function_definition > func_def_list_
void process_disable_inequality(const std::string &inequality)
std::map< std::string, typename settings_store_t::settings_arithmetic_opr > arith_opr_
parser_t::dependent_entity_collector::symbol_t symbol_t
exprtk::polynomial< T, 7 > poly07_
exprtk::rtl::vecops::package< T > vecops_package_
void process_enable_assignment(const std::string &assignment)
exprtk::polynomial< T, 4 > poly04_
exprtk::polynomial< T, 8 > poly08_
parser_t::settings_store settings_store_t
void perform_symbol_dump(const symbol_list_t &variable_list) const
void process_batch_run(const std::string &batch_runs_cnt)
std::vector< symbol_t > symbol_list_t
std::map< std::string, typename settings_store_t::settings_assignment_opr > assign_opr_
void process_disable_arithmetic(const std::string &arithmetic)
func_parse_result parse_function_definition(std::string &func_def, function_definition &cf)
exprtk::polynomial< T, 3 > poly03_
compositor_t::function function_t
exprtk::polynomial< T, 9 > poly09_
std::string trim_whitespace(std::string s)
exprtk::parser_error::type error_t
exprtk::symbol_table< T > symbol_table_t
void process_disable_assignment(const std::string &assignment)
exprtk::function_compositor< T > compositor_t
exprtk::lexer::parser_helper prsrhlpr_t
std::map< std::string, typename settings_store_t::settings_inequality_opr > inequality_opr_
exprtk::polynomial< T, 2 > poly02_
exprtk::parser< T > parser_t
void process_function_definition(const std::string &func_def_header, bool read_stdin=true)
exprtk::polynomial< T, 12 > poly12_
symbol_table_t function_symbol_table_
exprtk::rtl::io::package< T > io_package_
exprtk::polynomial< T, 11 > poly11_
std::string read_from_stdin()
exprtk::polynomial< T, 10 > poly10_
bool & display_total_compile_time()
exprtk::polynomial< T, 1 > poly01_
void process_from_file(const std::string &file_name)
void process_directive(std::string expression)
void process(std::string program)
void process_enable_arithmetic(const std::string &arithmetic)
bool register_symbol_table(symbol_table< T > &st)
Definition exprtk.hpp:21726
const results_context_t & results() const
Definition exprtk.hpp:21757
void add_auxiliary_symtab(symbol_table_t &symtab)
Definition exprtk.hpp:43103
bool add(const std::string &name, const std::string &expression, const Sequence< std::string, Allocator > &var_list, const bool override=false)
Definition exprtk.hpp:43032
ifunction(const std::size_t &pc)
Definition exprtk.hpp:19545
bool init(const std::string &str)
Definition exprtk.hpp:4353
const token_t & current_token() const
Definition exprtk.hpp:4394
bool token_is(const token_t::token_type &ttype, const token_advance_mode mode=e_advance)
Definition exprtk.hpp:4418
std::size_t assignment_symbols(Sequence< symbol_t, Allocator > &assignment_list)
Definition exprtk.hpp:23539
std::size_t symbols(Sequence< symbol_t, Allocator > &symbols_list)
Definition exprtk.hpp:23513
settings_store & enable_arithmetic_operation(const settings_arithmetic_opr arithmetic)
Definition exprtk.hpp:24145
settings_store & disable_arithmetic_operation(const settings_arithmetic_opr arithmetic)
Definition exprtk.hpp:24052
settings_store & disable_assignment_operation(const settings_assignment_opr assignment)
Definition exprtk.hpp:24065
settings_store & enable_assignment_operation(const settings_assignment_opr assignment)
Definition exprtk.hpp:24163
settings_store & disable_local_vardef()
Definition exprtk.hpp:23870
settings_store & disable_inequality_operation(const settings_inequality_opr inequality)
Definition exprtk.hpp:24078
settings_store & enable_local_vardef()
Definition exprtk.hpp:23798
settings_store & enable_inequality_operation(const settings_inequality_opr inequality)
Definition exprtk.hpp:24181
bool compile(const std::string &expression_string, expression< T > &expr)
Definition exprtk.hpp:24443
void enable_unknown_symbol_resolver(unknown_symbol_resolver *usr=reinterpret_cast< unknown_symbol_resolver * >(0))
Definition exprtk.hpp:24762
dependent_entity_collector & dec()
Definition exprtk.hpp:24737
parser_error::type get_error(const std::size_t &index) const
Definition exprtk.hpp:24712
std::string error() const
Definition exprtk.hpp:24722
std::size_t error_count() const
Definition exprtk.hpp:24732
void disable_unknown_symbol_resolver()
Definition exprtk.hpp:24777
settings_store & settings()
Definition exprtk.hpp:24707
std::size_t count() const
Definition exprtk.hpp:4896
bool add_package(Package &package)
Definition exprtk.hpp:21098
bool add_constant(const std::string &constant_name, const T &value)
Definition exprtk.hpp:20782
void clear_variables(const bool delete_node=true)
Definition exprtk.hpp:20508
bool add_function(const std::string &function_name, function_t &function)
Definition exprtk.hpp:20811
function_ptr get_function(const std::string &function_name) const
Definition exprtk.hpp:20628
std::size_t get_variable_list(Sequence< std::pair< std::string, T >, Allocator > &vlist) const
Definition exprtk.hpp:21105
bool add_vector(const std::string &vector_name, T(&v)[N])
Definition exprtk.hpp:20974
bool add_stringvar(const std::string &stringvar_name, std::string &s, const bool is_constant=false)
Definition exprtk.hpp:20798
bool remove_function(const std::string &function_name)
Definition exprtk.hpp:21047
double time() const
Definition exprtk.hpp:43502
void repl(int argc, char *argv[])
bool imatch(const char_t c1, const char_t c2)
Definition exprtk.hpp:190
bool update_error(type &error, const std::string &expression)
Definition exprtk.hpp:22114
std::string to_str(error_mode mode)
Definition exprtk.hpp:22098
void print_type(const std::string &fmt, const T v, exprtk::details::numeric::details::real_type_tag)
Definition exprtk.hpp:43547
vector_view< T > make_vector_view(T *data, const std::size_t size, const std::size_t offset=0)
Definition exprtk.hpp:4660
func_parse_result process(std::string &func_def, function_definition &fd)
function & expression(const std::string &e)
Definition exprtk.hpp:42516
function & var(const std::string &v)
Definition exprtk.hpp:42522
std::size_t position
Definition exprtk.hpp:2400
std::string value
Definition exprtk.hpp:2399
T operator()(const T &v)
T operator()(const T &v)
T operator()()