#8: added functions date, time, ticks

This commit is contained in:
Louis Rubet 2018-08-15 18:04:55 +02:00
parent 55da6d7bea
commit ff541e49a0
9 changed files with 159 additions and 39 deletions

View file

@ -56,8 +56,9 @@ add_executable(
${PROJECT_SOURCE_DIR}/src/rpn-stack.cpp ${PROJECT_SOURCE_DIR}/src/rpn-stack.cpp
${PROJECT_SOURCE_DIR}/src/rpn-store.cpp ${PROJECT_SOURCE_DIR}/src/rpn-store.cpp
${PROJECT_SOURCE_DIR}/src/rpn-string.cpp ${PROJECT_SOURCE_DIR}/src/rpn-string.cpp
${PROJECT_SOURCE_DIR}/src/rpn-test-core.cpp
${PROJECT_SOURCE_DIR}/src/rpn-test.cpp ${PROJECT_SOURCE_DIR}/src/rpn-test.cpp
${PROJECT_SOURCE_DIR}/src/rpn-test-core.cpp
${PROJECT_SOURCE_DIR}/src/rpn-time.cpp
${PROJECT_SOURCE_DIR}/src/rpn-trig.cpp ${PROJECT_SOURCE_DIR}/src/rpn-trig.cpp
${PROJECT_SOURCE_DIR}/linenoise-ng/src/ConvertUTF.cpp ${PROJECT_SOURCE_DIR}/linenoise-ng/src/ConvertUTF.cpp
${PROJECT_SOURCE_DIR}/linenoise-ng/src/linenoise.cpp ${PROJECT_SOURCE_DIR}/linenoise-ng/src/linenoise.cpp

View file

@ -128,8 +128,8 @@ rpn> 7b1252 dec
|keyword|description| |keyword|description|
|-|-| |-|-|
|`nop` | no operation |`nop` | no operation
|`help\|h\|?` | this help message |`help` `h` `?` | this help message
|`quit\|q\|exit` | quit software |`quit` `q` `exit` | quit software
|`version` | show rpn version |`version` | show rpn version
|`uname` | show rpn complete identification string |`uname` | show rpn complete identification string
|`history`| see commands history |`history`| see commands history
@ -140,13 +140,13 @@ rpn> 7b1252 dec
|-|-| |-|-|
|`+`| addition |`+`| addition
|`-`| substraction |`-`| substraction
|`neg\|chs`| negation |`neg` `chs`| negation
|`*`| multiplication |`*`| multiplication
|`/`| division |`/`| division
|`inv`| inverse |`inv`| inverse
|`^\|pow`| power |`^` `pow`| power
|`sqrt`| square root |`sqrt`| square root
|`sq\|sqr`| square |`sq` `sqr`| square
|`abs`| absolute value for a number or `sqrt(re*re+im*im)` for a complex |`abs`| absolute value for a number or `sqrt(re*re+im*im)` for a complex
|`dec`| decimal representation |`dec`| decimal representation
|`hex`| hexadecimal representation |`hex`| hexadecimal representation
@ -220,7 +220,7 @@ rpn> 7b1252 dec
|`drop`| drop first stack entry |`drop`| drop first stack entry
|`drop2`| drop 2 first stack entries |`drop2`| drop 2 first stack entries
|`dropn`| drop n first stack entries |`dropn`| drop n first stack entries
|`del\|erase`| drop all stack entries |`del` `erase`| drop all stack entries
|`rot`| rotate 3 first stack entries |`rot`| rotate 3 first stack entries
|`dup`| duplicate first stack entry |`dup`| duplicate first stack entry
|`dup2`| duplicate 2 first stack entries |`dup2`| duplicate 2 first stack entries
@ -258,9 +258,9 @@ rpn> 7b1252 dec
|`next`| used with start and for |`next`| used with start and for
|`step`| used with start and for |`step`| used with start and for
|`do`| do (instructions) until (condition) end |`do`| do (instructions) until (condition) end
|`until\|unti` | used with do |`until` `unti` | used with do
|`while\|whil`| while (test-instruction) repeat (loop-instructions) end |`while` `whil`| while (test-instruction) repeat (loop-instructions) end
|`repeat\|repea`| used with while |`repeat` `repea`| used with while
### store ### store
@ -305,20 +305,23 @@ rpn> 7b1252 dec
|keyword|description| |keyword|description|
|-|-| |-|-|
|`e`| Euler constant |`e`| Euler constant
|`ln\|log`| logarithm base e |`ln` `log`| logarithm base e
|`lnp1`| ln(1+x) which is useful when x is close to 0 |`lnp1`| ln(1+x) which is useful when x is close to 0
|`exp`| exponential |`exp`| exponential
|`expm`| exp(x)-1 which is useful when x is close to 0 |`expm`| exp(x)-1 which is useful when x is close to 0
|`log10`| logarithm base 10 |`log10`| logarithm base 10
|`alog10\|exp10`| exponential base 10 |`alog10` `exp10`| exponential base 10
|`log2`| logarithm base 2 |`log2`| logarithm base 2
|`alog2\|exp2`| exponential base 2 |`alog2` `exp2`| exponential base 2
|`sinh`| hyperbolic sine |`sinh`| hyperbolic sine
|`asinh`| inverse hyperbolic sine |`asinh`| inverse hyperbolic sine
|`cosh`| hyperbolic cosine |`cosh`| hyperbolic cosine
|`acosh`| inverse hyperbolic cosine |`acosh`| inverse hyperbolic cosine
|`tanh`| hyperbolic tangent |`tanh`| hyperbolic tangent
|`atanh`| inverse hyperbolic tangent |`atanh`| inverse hyperbolic tangent
|`time`| time in format HH.MMSSssssss
|`date`| date in format (M)M.DDYYYY
|`ticks`| system tick in µs
### default ### default

View file

@ -25,25 +25,31 @@ rpn> << -> x y << x y + ln >> >> 'P' sto
### and a bunch of functions ### and a bunch of functions
``` ```
rpn> rpn>
Display all 147 possibilities? (y or n) Display all 150 possibilities? (y or n)
nop chs bin min prec not depth else repeat sinv ln cosh nop pow fp >= dupn next sto* exp
help neg base max round same roll end repea eval log acosh help sqrt min < pick step sto/ expm
h * sign re default swap rolld start sto -> lnp1 tanh h sq max <= depth ift sneg log10
? / % im type drop over for rcl pi exp atanh ? sqr re != roll ifte sinv alog10
quit inv %CH conj > drop2 ->str next purge sin expm quit abs im == rolld do eval exp10
q ^ mod arg >= dropn str-> step vars asin log10 q dec conj and over until -> log2
exit pow fact c->r < del chr ift clusr cos alog10 exit hex arg or ->str unti pi alog2
test sqrt mant r->c <= erase num ifte edit acos exp10 test bin c->r xor str-> while sin exp2
version sq xpon p->r != rot size do sto+ tan log2 version base r->c not chr whil asin sinh
uname sqr floor r->p == dup pos until sto- atan alog2 uname sign p->r same num repeat cos asinh
history abs ceil std and dup2 sub unti sto* d->r exp2 history % r->p swap size repea acos cosh
+ dec ip fix or dupn if while sto/ r->d sinh + %CH std drop pos sto tan acosh
- hex fp sci xor pick then whil sneg e asinh - mod fix drop2 sub rcl atan tanh
chs fact sci dropn if purge d->r atanh
neg mant prec del then vars r->d time
* xpon round erase else clusr e date
/ floor default rot end edit ln ticks
inv ceil type dup start sto+ log
^ ip > dup2 for sto- lnp1
``` ```
## Download ## Download
deb, rpm and tgz files can be found [there](http://nvie.com/img/git-model@2x.png) deb, rpm and tgz files can be found [there](liv/)
## Manual ## Manual

View file

@ -11,7 +11,7 @@ void program::entry_completion_generator(const char* text, linenoiseCompletions*
int text_len = strnlen(text, 6); int text_len = strnlen(text, 6);
// propose all keywords // propose all keywords
if (text_len == 0) { if (text_len == 0) {
while (program::s_keywords[i].type != cmd_max) { while (program::s_keywords[i].type != cmd_max) {
if (program::s_keywords[i].fn != NULL) if (program::s_keywords[i].fn != NULL)
// add all keywords // add all keywords

View file

@ -202,12 +202,18 @@ program::keyword_t program::s_keywords[] = {
{cmd_keyword, "tanh", &program::rpn_tanh, "hyperbolic tangent"}, {cmd_keyword, "tanh", &program::rpn_tanh, "hyperbolic tangent"},
{cmd_keyword, "atanh", &program::rpn_atanh, "inverse hyperbolic tangent"}, {cmd_keyword, "atanh", &program::rpn_atanh, "inverse hyperbolic tangent"},
// TIME AND DATE
{cmd_undef, "", NULL, "\nTIME AND DATE"},
{cmd_keyword, "time", &program::rpn_time, "time in local format"},
{cmd_keyword, "date", &program::rpn_date, "date in local format"},
{cmd_keyword, "ticks", &program::rpn_ticks, "system tick in µs"},
// end // end
{cmd_max, "", NULL, ""}, {cmd_max, "", NULL, ""},
}; };
/// @brief run a program on a stack and a heap /// @brief run a program on a stack and a heap
/// ///
/// @param stk the stack, storing prog result /// @param stk the stack, storing prog result
/// @param hp the heap, storing variables /// @param hp the heap, storing variables
/// @return ret_value see this type /// @return ret_value see this type
@ -305,12 +311,12 @@ ret_value program::run(stack& stk, heap& hp) {
} }
/// @brief stop a program /// @brief stop a program
/// ///
/// ///
void program::stop() { interrupt_now = true; } void program::stop() { interrupt_now = true; }
/// @brief return whether a branch object has a given name /// @brief return whether a branch object has a given name
/// ///
/// @param b the branch object /// @param b the branch object
/// @param str_to_compare the name /// @param str_to_compare the name
/// @param len the name length /// @param len the name length
@ -328,7 +334,7 @@ bool program::compare_branch(branch* b, const char* str_to_compare, int len) {
/// this is needed before a program can be run /// this is needed before a program can be run
/// inner members of branch or keyword objects are filled by this function /// inner members of branch or keyword objects are filled by this function
/// these inner members store for example the index of the next keyword to execute etc. /// these inner members store for example the index of the next keyword to execute etc.
/// ///
/// @return ret_value see this type /// @return ret_value see this type
/// ///
ret_value program::preprocess(void) { ret_value program::preprocess(void) {
@ -558,7 +564,7 @@ ret_value program::preprocess(void) {
} }
/// @brief show the last error set /// @brief show the last error set
/// ///
/// @return ret_value see this type /// @return ret_value see this type
/// ///
ret_value program::show_error() { ret_value program::show_error() {
@ -578,7 +584,7 @@ ret_value program::show_error() {
} }
/// @brief record an error as the last error set and show it /// @brief record an error as the last error set and show it
/// ///
/// @param err the error to record /// @param err the error to record
/// @param context a context string /// @param context a context string
/// @return ret_value see this type /// @return ret_value see this type
@ -591,7 +597,7 @@ ret_value program::show_error(ret_value err, string& context) {
} }
/// @brief record an error as the last error set and show it /// @brief record an error as the last error set and show it
/// ///
/// @param err the error to record /// @param err the error to record
/// @param context a context string /// @param context a context string
/// @return ret_value see this type /// @return ret_value see this type
@ -604,7 +610,7 @@ ret_value program::show_error(ret_value err, const char* context) {
} }
/// @brief set the last error as being a syntax error and show it /// @brief set the last error as being a syntax error and show it
/// ///
/// @param err the error to record /// @param err the error to record
/// @param context a context string /// @param context a context string
/// @return ret_value see this type /// @return ret_value see this type
@ -617,14 +623,14 @@ void program::show_syntax_error(const char* context) {
} }
/// @brief return the last error set /// @brief return the last error set
/// ///
/// @return ret_value see this type /// @return ret_value see this type
/// ///
ret_value program::get_err(void) { return _err; } ret_value program::get_err(void) { return _err; }
/// @brief show a stack (show its different objects) /// @brief show a stack (show its different objects)
/// generally a stack is associated to a running program /// generally a stack is associated to a running program
/// ///
/// @param st the stack to show /// @param st the stack to show
/// @param show_separator whether to show a stack level prefix or not /// @param show_separator whether to show a stack level prefix or not
/// ///

View file

@ -273,6 +273,11 @@ class program : public stack {
void rpn_acos(void); void rpn_acos(void);
void rpn_tan(void); void rpn_tan(void);
void rpn_atan(void); void rpn_atan(void);
// time
void rpn_time();
void rpn_date();
void rpn_ticks();
}; };
// convinience macros for rpn_xx function // convinience macros for rpn_xx function

73
src/rpn-time.cpp Normal file
View file

@ -0,0 +1,73 @@
#include <time.h>
#include "program.hpp"
/// @brief time keyword implementation
///
void program::rpn_time() {
struct timespec ts;
struct tm* tm;
double date;
// get local date
clock_gettime(CLOCK_REALTIME, &ts);
time_t time = (time_t)ts.tv_sec;
tm = localtime(&time);
if (tm != NULL) {
// date format = HH.MMSSssssss
date = ((double)tm->tm_hour) * 10000000000.0 + ((double)tm->tm_min) * 100000000.0 +
((double)tm->tm_sec) * 1000000.0 + (double)(ts.tv_nsec / 1000);
// push it
number* num = (number*)_stack->allocate_back(number::calc_size(), cmd_number);
CHECK_MPFR(mpfr_set_d(num->_value.mpfr, date, floating_t::s_mpfr_rnd));
// division is done here because of real precision)
CHECK_MPFR(mpfr_div_d(num->_value.mpfr, num->_value.mpfr, 10000000000.0, floating_t::s_mpfr_rnd));
} else
ERR_CONTEXT(ret_internal);
}
/// @brief date keyword implementation
///
void program::rpn_date() {
struct timespec ts;
struct tm* tm;
double date;
// get local date
clock_gettime(CLOCK_REALTIME, &ts);
time_t time = (time_t)ts.tv_sec;
tm = localtime(&time);
if (tm != NULL) {
// date format = (M)M.DDYYYY
date = (double)(tm->tm_mon + 1) * 1000000.0 + (double)(tm->tm_mday) * 10000.0 + (double)(tm->tm_year + 1900);
// push it
number* num = (number*)_stack->allocate_back(number::calc_size(), cmd_number);
CHECK_MPFR(mpfr_set_d(num->_value.mpfr, date, floating_t::s_mpfr_rnd));
// division is done here because of real precision)
CHECK_MPFR(mpfr_div_d(num->_value.mpfr, num->_value.mpfr, 1000000.0, floating_t::s_mpfr_rnd));
} else
ERR_CONTEXT(ret_internal);
}
/// @brief ticks keyword implementation
///
void program::rpn_ticks() {
struct timespec ts;
struct tm* tm;
double date;
// get local date
clock_gettime(CLOCK_REALTIME, &ts);
time_t time = (time_t)ts.tv_sec;
tm = localtime(&time);
if (tm != NULL) {
// date in µs
date = 1000000.0 * (double)ts.tv_sec + (double)(ts.tv_nsec / 1000);
// push it
number* num = (number*)_stack->allocate_back(number::calc_size(), cmd_number);
CHECK_MPFR(mpfr_set_d(num->_value.mpfr, date, floating_t::s_mpfr_rnd));
} else
ERR_CONTEXT(ret_internal);
}

25
test/12-time.txt Normal file
View file

@ -0,0 +1,25 @@
## date and time
default del
# date
date type
-> error should be 0
-> stack should be "number"
del
# time
time type
-> error should be 0
-> stack should be "number"
del
# ticks (1)
ticks type
-> error should be 0
-> stack should be "number"
del
# ticks (2)
ticks ticks - 0 <=
-> stack should be 1
del

View file

@ -9,4 +9,5 @@
#include 09-program.txt #include 09-program.txt
#include 10-complex.txt #include 10-complex.txt
#include 11-base-entry.txt #include 11-base-entry.txt
#include 12-time.txt
#include 99-manual-tests.txt #include 99-manual-tests.txt