#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-store.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-core.cpp
${PROJECT_SOURCE_DIR}/src/rpn-time.cpp
${PROJECT_SOURCE_DIR}/src/rpn-trig.cpp
${PROJECT_SOURCE_DIR}/linenoise-ng/src/ConvertUTF.cpp
${PROJECT_SOURCE_DIR}/linenoise-ng/src/linenoise.cpp

View file

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

View file

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

View file

@ -11,7 +11,7 @@ void program::entry_completion_generator(const char* text, linenoiseCompletions*
int text_len = strnlen(text, 6);
// propose all keywords
if (text_len == 0) {
if (text_len == 0) {
while (program::s_keywords[i].type != cmd_max) {
if (program::s_keywords[i].fn != NULL)
// 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, "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
{cmd_max, "", NULL, ""},
};
/// @brief run a program on a stack and a heap
///
///
/// @param stk the stack, storing prog result
/// @param hp the heap, storing variables
/// @return ret_value see this type
@ -305,12 +311,12 @@ ret_value program::run(stack& stk, heap& hp) {
}
/// @brief stop a program
///
///
///
void program::stop() { interrupt_now = true; }
/// @brief return whether a branch object has a given name
///
///
/// @param b the branch object
/// @param str_to_compare the name
/// @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
/// 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.
///
///
/// @return ret_value see this type
///
ret_value program::preprocess(void) {
@ -558,7 +564,7 @@ ret_value program::preprocess(void) {
}
/// @brief show the last error set
///
///
/// @return ret_value see this type
///
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
///
///
/// @param err the error to record
/// @param context a context string
/// @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
///
///
/// @param err the error to record
/// @param context a context string
/// @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
///
///
/// @param err the error to record
/// @param context a context string
/// @return ret_value see this type
@ -617,14 +623,14 @@ void program::show_syntax_error(const char* context) {
}
/// @brief return the last error set
///
///
/// @return ret_value see this type
///
ret_value program::get_err(void) { return _err; }
/// @brief show a stack (show its different objects)
/// generally a stack is associated to a running program
///
///
/// @param st the stack to show
/// @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_tan(void);
void rpn_atan(void);
// time
void rpn_time();
void rpn_date();
void rpn_ticks();
};
// 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 10-complex.txt
#include 11-base-entry.txt
#include 12-time.txt
#include 99-manual-tests.txt