#106: added string keywords: +, chr, num

This commit is contained in:
Louis Rubet 2017-05-31 18:14:02 +02:00
parent 38349a6404
commit 39ffbcddbe
6 changed files with 119 additions and 28 deletions

View file

@ -59,41 +59,41 @@ rpn>
|keyword|description|
|-|-|
|nop | no operation |
|help | (or h or ?) this help message
|quit | (or q or exit) quit software
|nop | no operation |
|help | (or h or ?) this help message
|quit | (or q or exit) quit software
|version | show rpn version
|uname | show rpn complete identification string
|type | show type of stack first entry
|type | show type of stack first entry
|default | set float representation and precision to default
#### real
|keyword|description|
|-|-|
|+| addition
|-| substraction
|+| addition
|-| substraction
|neg| negation
|*| multiplication
|/| division
|*| multiplication
|/| division
|inv| inverse
|%| purcent
|%| purcent
|%|CH inverse purcent
|^| (or pow) power
|^| (or pow) power
|sqrt| square root
|sq| (or sqr) square
|mod| modulo
|abs| absolute value
|dec| decimal representation
|hex| hexadecimal representation
|prec | get float precision in bits when first stack is not a number, set float precision in bits when first stack entry is a number. ex: ```256 prec```
|prec| get float precision in bits when first stack is not a number, set float precision in bits when first stack entry is a number. ex: ```256 prec```
|round| set float rounding mode. Authoerized values are: ```["nearest", "toward zero", "toward +inf", "toward -inf", "away from zero"] round```. ex: ```"nearest" round```
|fact| n! for integer n or Gamma(x+1) for fractional x
|sign| 1 if number at stack level 1 is > 0, 0 if == 0, -1 if <= 0
|mant| mantissa of a real number
|xpon| exponant of a real number
|min| min of 2 real numbers
|max| max of 2 real numbers
|fact| n! for integer n or Gamma(x+1) for fractional x
|sign| 1 if number at stack level 1 is > 0, 0 if == 0, -1 if <= 0
|mant| mantissa of a real number
|xpon| exponant of a real number
|min| min of 2 real numbers
|max| max of 2 real numbers
#### mode
@ -107,9 +107,9 @@ rpn>
|keyword|description|
|-|-|
|>| binary operator >
|>| binary operator >
|>=| binary operator >=
|<| binary operator <
|<| binary operator <
|<=| binary operator <=
|!=| binary operator != (different)
|==| binary operator == (equal)
@ -134,9 +134,9 @@ rpn>
|dupn| duplicate n first stack entries
|pick| push a copy of the given stack level onto the stack
|depth| give stack depth
|roll| move a stack entry to the top of the stack
|rolld| move the element on top of the stack to a higher stack position
|over| push a copy of the element in stack level 2 onto the stack
|roll| move a stack entry to the top of the stack
|rolld| move the element on top of the stack to a higher stack position
|over| push a copy of the element in stack level 2 onto the stack
#### string
@ -144,6 +144,8 @@ rpn>
|-|-|
|->str| convert an object into a string
|str->| convert a string into an object
|chr| convert ASCII character code in stack level 1 into a string
|num| return ASCII code of the first character of the string in stack level 1 as a real number
#### branch

View file

@ -184,7 +184,7 @@ struct ostring : public object
}
}
// length of _value, not includiong the terminal '\0'
// length of _value, not including the terminal '\0'
unsigned int _len;
char _value[0];
};

View file

@ -92,6 +92,8 @@ program::keyword_t program::s_keywords[] =
{ cmd_undef, "", NULL, "\nSTRING"},
{ cmd_keyword, "->str", &program::instr, "convert an object into a string" },
{ cmd_keyword, "str->", &program::strout, "convert a string into an object" },
{ cmd_keyword, "chr", &program::chr, "convert ASCII character code in stack level 1 into a string" },
{ cmd_keyword, "num", &program::num, "return ASCII code of the first character of the string in stack level 1 as a real number" },
//BRANCH
{ cmd_undef, "", NULL, "\nBRANCH"},

View file

@ -1,12 +1,35 @@
void plus()
{
MIN_ARGUMENTS(2);
ARG_MUST_BE_OF_TYPE(0, cmd_number);
ARG_MUST_BE_OF_TYPE(1, cmd_number);
number* right = (number*)_stack->pop_back();
number* left = (number*)_stack->back();
CHECK_MPFR(mpfr_add(left->_value.mpfr, left->_value.mpfr, right->_value.mpfr, floating_t::s_mpfr_rnd));
// adding strings
if (_stack->get_type(0) == cmd_string && _stack->get_type(1) == cmd_string)
{
unsigned int left_str_size = ((ostring*)_stack->get_obj(1))->_len;
unsigned int right_str_size = ((ostring*)_stack->get_obj(0))->_len;
stack::copy_and_push_back(*_stack, _stack->size()-2, _branch_stack);
stack::copy_and_push_back(*_stack, _stack->size()-1, _branch_stack);
(void)_stack->pop_back();
(void)_stack->pop_back();
ostring* str = (ostring*)_stack->allocate_back(left_str_size+right_str_size+1+sizeof(ostring), cmd_string);
str->_len = left_str_size+right_str_size;
strncpy(str->_value, ((ostring*)_branch_stack.get_obj(1))->_value, left_str_size);
strncat(str->_value, ((ostring*)_branch_stack.get_obj(0))->_value, right_str_size);
_branch_stack.pop_back();
_branch_stack.pop_back();
}
// adding numbers
else
{
ARG_MUST_BE_OF_TYPE(0, cmd_number);
ARG_MUST_BE_OF_TYPE(1, cmd_number);
number* right = (number*)_stack->pop_back();
number* left = (number*)_stack->back();
CHECK_MPFR(mpfr_add(left->_value.mpfr, left->_value.mpfr, right->_value.mpfr, floating_t::s_mpfr_rnd));
}
}
void minus()

View file

@ -42,3 +42,31 @@ void strout()
// run it
prog.run(*_stack, *_heap);
}
void chr()
{
MIN_ARGUMENTS(1);
ARG_MUST_BE_OF_TYPE(0, cmd_number);
// get arg as number % 256
char the_chr = (char)mpfr_get_d(((number*)_stack->pop_back())->_value.mpfr, floating_t::s_mpfr_rnd);
if (the_chr<32 || the_chr>126)
the_chr = '.';
// reserve the correct size on stack (1 char)
unsigned int str_size = 1;
ostring* str = (ostring*)_stack->allocate_back(str_size+1+sizeof(ostring), cmd_string);
str->_len = str_size;
str->_value[0] = the_chr;
str->_value[1] = 0;
}
void num()
{
MIN_ARGUMENTS(1);
ARG_MUST_BE_OF_TYPE(0, cmd_string);
double the_chr = (double)((ostring*)_stack->pop_back())->_value[0];
number* numb = (number*)_stack->allocate_back(number::calc_size(), cmd_number);
numb->_value = the_chr;
}

View file

@ -106,3 +106,39 @@ erase
str->
-> stack should be << -> n << n >> >>
erase
# add (1)
12 34 "one" "two" +
-> stack should be 12, 34, "onetwo"
erase
# add (2)
"" "one" + "two" "" +
-> stack should be "one", "two"
erase
# add (3)
"one" +
-> stack size should be 1
-> error should be 2
erase
# chr (1)
"" 33 40 for i i chr + next
-> stack should be "!"#$%&'("
erase
# chr (2)
-223 chr 0 chr
-> stack should be "!", "."
erase
# num (1)
"!wait" num
-> stack should be 33
erase
# num (2)
"" num
-> stack should be 0
erase