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

This commit is contained in:
RUBET Louis 2017-05-31 18:14:02 +02:00
parent 116ee0c9e0
commit 73bc66c683
6 changed files with 119 additions and 28 deletions

View file

@ -59,41 +59,41 @@ rpn>
|keyword|description| |keyword|description|
|-|-| |-|-|
|nop | no operation | |nop | no operation |
|help | (or h or ?) this help message |help | (or h or ?) this help message
|quit | (or q or exit) quit software |quit | (or q or exit) quit software
|version | show rpn version |version | show rpn version
|uname | show rpn complete identification string |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 |default | set float representation and precision to default
#### real #### real
|keyword|description| |keyword|description|
|-|-| |-|-|
|+| addition |+| addition
|-| substraction |-| substraction
|neg| negation |neg| negation
|*| multiplication |*| multiplication
|/| division |/| division
|inv| inverse |inv| inverse
|%| purcent |%| purcent
|%|CH inverse purcent |%|CH inverse purcent
|^| (or pow) power |^| (or pow) power
|sqrt| square root |sqrt| square root
|sq| (or sqr) square |sq| (or sqr) square
|mod| modulo |mod| modulo
|abs| absolute value |abs| absolute value
|dec| decimal representation |dec| decimal representation
|hex| hexadecimal 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``` |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 |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 |sign| 1 if number at stack level 1 is > 0, 0 if == 0, -1 if <= 0
|mant| mantissa of a real number |mant| mantissa of a real number
|xpon| exponant of a real number |xpon| exponant of a real number
|min| min of 2 real numbers |min| min of 2 real numbers
|max| max of 2 real numbers |max| max of 2 real numbers
#### mode #### mode
@ -107,9 +107,9 @@ rpn>
|keyword|description| |keyword|description|
|-|-| |-|-|
|>| binary operator > |>| binary operator >
|>=| binary operator >= |>=| binary operator >=
|<| binary operator < |<| binary operator <
|<=| binary operator <= |<=| binary operator <=
|!=| binary operator != (different) |!=| binary operator != (different)
|==| binary operator == (equal) |==| binary operator == (equal)
@ -134,9 +134,9 @@ rpn>
|dupn| duplicate n first stack entries |dupn| duplicate n first stack entries
|pick| push a copy of the given stack level onto the stack |pick| push a copy of the given stack level onto the stack
|depth| give stack depth |depth| give stack depth
|roll| move a stack entry to the top of 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 |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 |over| push a copy of the element in stack level 2 onto the stack
#### string #### string
@ -144,6 +144,8 @@ rpn>
|-|-| |-|-|
|->str| convert an object into a string |->str| convert an object into a string
|str->| convert a string into an object |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 #### 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; unsigned int _len;
char _value[0]; char _value[0];
}; };

View file

@ -92,6 +92,8 @@ program::keyword_t program::s_keywords[] =
{ cmd_undef, "", NULL, "\nSTRING"}, { cmd_undef, "", NULL, "\nSTRING"},
{ cmd_keyword, "->str", &program::instr, "convert an object into a string" }, { cmd_keyword, "->str", &program::instr, "convert an object into a string" },
{ cmd_keyword, "str->", &program::strout, "convert a string into an object" }, { 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 //BRANCH
{ cmd_undef, "", NULL, "\nBRANCH"}, { cmd_undef, "", NULL, "\nBRANCH"},

View file

@ -1,12 +1,35 @@
void plus() void plus()
{ {
MIN_ARGUMENTS(2); 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(); // adding strings
number* left = (number*)_stack->back(); if (_stack->get_type(0) == cmd_string && _stack->get_type(1) == cmd_string)
CHECK_MPFR(mpfr_add(left->_value.mpfr, left->_value.mpfr, right->_value.mpfr, floating_t::s_mpfr_rnd)); {
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() void minus()

View file

@ -42,3 +42,31 @@ void strout()
// run it // run it
prog.run(*_stack, *_heap); 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-> str->
-> stack should be << -> n << n >> >> -> stack should be << -> n << n >> >>
erase 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