2015-02-12 18:23:17 +01:00
|
|
|
void instr()
|
|
|
|
{
|
2015-05-19 17:51:03 +02:00
|
|
|
MIN_ARGUMENTS(1);
|
2015-02-12 18:23:17 +01:00
|
|
|
|
2015-05-19 17:51:03 +02:00
|
|
|
// stringify only if not already a string
|
|
|
|
if (_stack->get_type(0) != cmd_string)
|
|
|
|
{
|
2017-04-15 19:34:01 +02:00
|
|
|
// write the object in stack(0) in a string and remove this obj
|
2017-05-24 14:09:52 +02:00
|
|
|
FILE* tmp = tmpfile();
|
|
|
|
if (tmp != NULL)
|
|
|
|
{
|
|
|
|
((object*)_stack->pop_back())->show(tmp);
|
2015-02-12 18:23:17 +01:00
|
|
|
|
2017-05-24 23:47:26 +02:00
|
|
|
// reserve the correct size on stack
|
2017-05-24 14:09:52 +02:00
|
|
|
unsigned int str_size = (unsigned int)ftell(tmp);
|
|
|
|
ostring* str = (ostring*)_stack->allocate_back(str_size+1+sizeof(ostring), cmd_string);
|
2017-05-31 22:27:39 +02:00
|
|
|
str->_len = str_size;
|
2017-04-15 19:34:01 +02:00
|
|
|
|
2017-05-24 14:09:52 +02:00
|
|
|
// fill the obj
|
2017-05-24 23:47:26 +02:00
|
|
|
rewind(tmp);
|
|
|
|
if (fread(str->_value, str_size, 1, tmp) != 1)
|
2017-05-24 14:09:52 +02:00
|
|
|
ERR_CONTEXT(ret_runtime_error);
|
2017-05-24 23:47:26 +02:00
|
|
|
str->_value[str_size] = 0;
|
2017-05-24 14:09:52 +02:00
|
|
|
fclose(tmp);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
ERR_CONTEXT(ret_runtime_error);
|
2015-05-19 17:51:03 +02:00
|
|
|
}
|
2015-02-12 18:23:17 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void strout()
|
|
|
|
{
|
2015-02-26 22:33:28 +01:00
|
|
|
MIN_ARGUMENTS(1);
|
2015-05-19 17:51:03 +02:00
|
|
|
ARG_MUST_BE_OF_TYPE(0, cmd_string);
|
2015-02-12 18:23:17 +01:00
|
|
|
|
2017-04-21 13:58:44 +02:00
|
|
|
string entry(((ostring*)_stack->pop_back())->_value);
|
2015-02-12 18:23:17 +01:00
|
|
|
|
2015-05-19 17:51:03 +02:00
|
|
|
program prog;
|
2015-02-12 18:23:17 +01:00
|
|
|
|
2015-05-19 17:51:03 +02:00
|
|
|
// make program from string in stack level 1
|
2015-03-01 23:10:45 +01:00
|
|
|
if (program::parse(entry.c_str(), prog) == ret_ok)
|
2015-05-19 17:51:03 +02:00
|
|
|
// run it
|
2017-05-28 01:32:06 +02:00
|
|
|
prog.run(*_stack, *_heap);
|
2015-02-12 18:23:17 +01:00
|
|
|
}
|
2017-05-31 18:14:02 +02:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
2017-05-31 18:25:28 +02:00
|
|
|
|
|
|
|
void strsize()
|
|
|
|
{
|
|
|
|
MIN_ARGUMENTS(1);
|
|
|
|
ARG_MUST_BE_OF_TYPE(0, cmd_string);
|
|
|
|
|
|
|
|
double len = ((ostring*)_stack->pop_back())->_len;
|
|
|
|
number* numb = (number*)_stack->allocate_back(number::calc_size(), cmd_number);
|
|
|
|
numb->_value = len;
|
|
|
|
}
|
2017-05-31 22:27:39 +02:00
|
|
|
|
|
|
|
void strpos()
|
|
|
|
{
|
|
|
|
MIN_ARGUMENTS(2);
|
|
|
|
ARG_MUST_BE_OF_TYPE(0, cmd_string);
|
|
|
|
ARG_MUST_BE_OF_TYPE(1, cmd_string);
|
|
|
|
|
|
|
|
long pos = 0;
|
|
|
|
char* src = ((ostring*)_stack->get_obj(1))->_value;
|
|
|
|
char* found = strstr(src, ((ostring*)_stack->get_obj(0))->_value);
|
|
|
|
if (found != NULL)
|
|
|
|
pos = (long)(found - src)+1L;
|
|
|
|
|
|
|
|
_stack->pop_back();
|
|
|
|
_stack->pop_back();
|
|
|
|
|
|
|
|
number* numb = (number*)_stack->allocate_back(number::calc_size(), cmd_number);
|
|
|
|
numb->_value = pos;
|
|
|
|
}
|
|
|
|
|
|
|
|
void strsub()
|
|
|
|
{
|
|
|
|
MIN_ARGUMENTS(3);
|
|
|
|
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
|
|
|
ARG_MUST_BE_OF_TYPE(1, cmd_number);
|
|
|
|
ARG_MUST_BE_OF_TYPE(2, cmd_string);
|
|
|
|
|
|
|
|
long first = long(((number*)_stack->get_obj(1))->_value) - 1;
|
|
|
|
long last = long(((number*)_stack->get_obj(0))->_value) - 1;
|
|
|
|
long len = ((ostring*)_stack->get_obj(0))->_len;
|
|
|
|
bool result_is_void = false;
|
|
|
|
|
|
|
|
_stack->pop_back();
|
|
|
|
_stack->pop_back();
|
|
|
|
|
|
|
|
if (first < 0)
|
|
|
|
first = 0;
|
|
|
|
if (last < 0)
|
|
|
|
last = 0;
|
|
|
|
if (first > len)
|
|
|
|
first = len -1;
|
|
|
|
if (last > len)
|
|
|
|
last = len -1;
|
|
|
|
if (first > last)
|
|
|
|
result_is_void=true;
|
|
|
|
|
|
|
|
if (!result_is_void)
|
|
|
|
{
|
|
|
|
unsigned int str_size = last - first + 1;
|
|
|
|
ostring* str = (ostring*)_branch_stack.allocate_back(str_size+1+sizeof(ostring), cmd_string);
|
|
|
|
str->_len = str_size;
|
|
|
|
|
|
|
|
memcpy(((ostring*)_branch_stack.back())->_value, ((ostring*)_stack->get_obj(0))->_value+first, str_size);
|
|
|
|
((ostring*)_branch_stack.back())->_value[str_size] = 0;
|
|
|
|
|
|
|
|
_stack->pop_back();
|
|
|
|
stack::copy_and_push_back(_branch_stack, _branch_stack.size()-1, *_stack);
|
|
|
|
_branch_stack.pop_back();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
_stack->pop_back();
|
|
|
|
ostring* str = (ostring*)_stack->allocate_back(1+sizeof(ostring), cmd_string);
|
|
|
|
str->_len = 0;
|
|
|
|
str->_value[0] = 0;
|
|
|
|
}
|
|
|
|
}
|