mirror of
https://github.com/louisrubet/rpn
synced 2025-01-01 18:20:06 +01:00
tabs to spaces
This commit is contained in:
parent
f62805cfd3
commit
311d00906d
16 changed files with 1385 additions and 1385 deletions
|
@ -1,181 +1,181 @@
|
|||
void plus()
|
||||
{
|
||||
MIN_ARGUMENTS(2);
|
||||
MIN_ARGUMENTS(2);
|
||||
|
||||
// float
|
||||
if (IS_ARG_TYPE(0, cmd_number))
|
||||
{
|
||||
ARG_MUST_BE_OF_TYPE(1, cmd_number);
|
||||
//TODO really too slow
|
||||
putf(getf() + getf());
|
||||
}
|
||||
// binary
|
||||
else if (IS_ARG_TYPE(0, cmd_binary))
|
||||
{
|
||||
ARG_MUST_BE_OF_TYPE(1, cmd_binary);
|
||||
//TODO really too slow
|
||||
putb(getb() + getb());
|
||||
}
|
||||
// float
|
||||
if (IS_ARG_TYPE(0, cmd_number))
|
||||
{
|
||||
ARG_MUST_BE_OF_TYPE(1, cmd_number);
|
||||
//TODO really too slow
|
||||
putf(getf() + getf());
|
||||
}
|
||||
// binary
|
||||
else if (IS_ARG_TYPE(0, cmd_binary))
|
||||
{
|
||||
ARG_MUST_BE_OF_TYPE(1, cmd_binary);
|
||||
//TODO really too slow
|
||||
putb(getb() + getb());
|
||||
}
|
||||
//TODO
|
||||
#if 0
|
||||
// string
|
||||
else if (IS_ARG_TYPE(0, cmd_string))
|
||||
{
|
||||
ARG_MUST_BE_OF_TYPE(1, cmd_string);
|
||||
string& second = *((ostring*)_stack->back())->_value;
|
||||
_stack->pop_back();
|
||||
*((ostring*)_stack->back())->_value += second;
|
||||
}
|
||||
else if (IS_ARG_TYPE(0, cmd_string))
|
||||
{
|
||||
ARG_MUST_BE_OF_TYPE(1, cmd_string);
|
||||
string& second = *((ostring*)_stack->back())->_value;
|
||||
_stack->pop_back();
|
||||
*((ostring*)_stack->back())->_value += second;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
ERR_CONTEXT(ret_bad_operand_type);
|
||||
else
|
||||
ERR_CONTEXT(ret_bad_operand_type);
|
||||
}
|
||||
|
||||
void minus()
|
||||
{
|
||||
MIN_ARGUMENTS(2);
|
||||
MIN_ARGUMENTS(2);
|
||||
|
||||
// float
|
||||
if (IS_ARG_TYPE(0, cmd_number))
|
||||
{
|
||||
ARG_MUST_BE_OF_TYPE(1, cmd_number);
|
||||
//TODO really too slow
|
||||
floating_t first = getf();
|
||||
putf(getf() - first);
|
||||
}
|
||||
// binary
|
||||
else if (IS_ARG_TYPE(0, cmd_binary))
|
||||
{
|
||||
ARG_MUST_BE_OF_TYPE(1, cmd_binary);
|
||||
//TODO really too slow
|
||||
integer_t first = getb();
|
||||
putb(getb() - first);
|
||||
}
|
||||
else
|
||||
ERR_CONTEXT(ret_bad_operand_type);
|
||||
// float
|
||||
if (IS_ARG_TYPE(0, cmd_number))
|
||||
{
|
||||
ARG_MUST_BE_OF_TYPE(1, cmd_number);
|
||||
//TODO really too slow
|
||||
floating_t first = getf();
|
||||
putf(getf() - first);
|
||||
}
|
||||
// binary
|
||||
else if (IS_ARG_TYPE(0, cmd_binary))
|
||||
{
|
||||
ARG_MUST_BE_OF_TYPE(1, cmd_binary);
|
||||
//TODO really too slow
|
||||
integer_t first = getb();
|
||||
putb(getb() - first);
|
||||
}
|
||||
else
|
||||
ERR_CONTEXT(ret_bad_operand_type);
|
||||
}
|
||||
|
||||
void mul()
|
||||
{
|
||||
// float
|
||||
if (IS_ARG_TYPE(0, cmd_number))
|
||||
{
|
||||
ARG_MUST_BE_OF_TYPE(1, cmd_number);
|
||||
//TODO really too slow
|
||||
putf(getf() * getf());
|
||||
}
|
||||
// binary
|
||||
else if (IS_ARG_TYPE(0, cmd_binary))
|
||||
{
|
||||
ARG_MUST_BE_OF_TYPE(1, cmd_binary);
|
||||
//TODO really too slow
|
||||
putb(getb() * getb());
|
||||
}
|
||||
else
|
||||
ERR_CONTEXT(ret_bad_operand_type);
|
||||
// float
|
||||
if (IS_ARG_TYPE(0, cmd_number))
|
||||
{
|
||||
ARG_MUST_BE_OF_TYPE(1, cmd_number);
|
||||
//TODO really too slow
|
||||
putf(getf() * getf());
|
||||
}
|
||||
// binary
|
||||
else if (IS_ARG_TYPE(0, cmd_binary))
|
||||
{
|
||||
ARG_MUST_BE_OF_TYPE(1, cmd_binary);
|
||||
//TODO really too slow
|
||||
putb(getb() * getb());
|
||||
}
|
||||
else
|
||||
ERR_CONTEXT(ret_bad_operand_type);
|
||||
}
|
||||
|
||||
void div()
|
||||
{
|
||||
MIN_ARGUMENTS(2);
|
||||
MIN_ARGUMENTS(2);
|
||||
|
||||
// float
|
||||
if (IS_ARG_TYPE(0, cmd_number))
|
||||
{
|
||||
ARG_MUST_BE_OF_TYPE(1, cmd_number);
|
||||
//TODO really too slow
|
||||
// float
|
||||
if (IS_ARG_TYPE(0, cmd_number))
|
||||
{
|
||||
ARG_MUST_BE_OF_TYPE(1, cmd_number);
|
||||
//TODO really too slow
|
||||
|
||||
floating_t first = getf();
|
||||
// arithmetic faults are managed by c++
|
||||
putf(getf() / first);
|
||||
}
|
||||
// binary
|
||||
else if (IS_ARG_TYPE(0, cmd_binary))
|
||||
{
|
||||
ARG_MUST_BE_OF_TYPE(1, cmd_binary);
|
||||
if (((binary*)_stack->get_obj(0))->_value == 0)
|
||||
{
|
||||
ERR_CONTEXT(ret_div_by_zero);
|
||||
}
|
||||
else
|
||||
{
|
||||
//TODO really too slow
|
||||
integer_t first = getb();
|
||||
putb(getb() / first);
|
||||
}
|
||||
}
|
||||
else
|
||||
ERR_CONTEXT(ret_bad_operand_type);
|
||||
floating_t first = getf();
|
||||
// arithmetic faults are managed by c++
|
||||
putf(getf() / first);
|
||||
}
|
||||
// binary
|
||||
else if (IS_ARG_TYPE(0, cmd_binary))
|
||||
{
|
||||
ARG_MUST_BE_OF_TYPE(1, cmd_binary);
|
||||
if (((binary*)_stack->get_obj(0))->_value == 0)
|
||||
{
|
||||
ERR_CONTEXT(ret_div_by_zero);
|
||||
}
|
||||
else
|
||||
{
|
||||
//TODO really too slow
|
||||
integer_t first = getb();
|
||||
putb(getb() / first);
|
||||
}
|
||||
}
|
||||
else
|
||||
ERR_CONTEXT(ret_bad_operand_type);
|
||||
}
|
||||
|
||||
void neg()
|
||||
{
|
||||
MIN_ARGUMENTS(1);
|
||||
MIN_ARGUMENTS(1);
|
||||
|
||||
// float
|
||||
if (IS_ARG_TYPE(0, cmd_number))
|
||||
putf(-getf());
|
||||
// binary
|
||||
else if (IS_ARG_TYPE(0, cmd_binary))
|
||||
putb(-getb());
|
||||
else
|
||||
ERR_CONTEXT(ret_bad_operand_type);
|
||||
// float
|
||||
if (IS_ARG_TYPE(0, cmd_number))
|
||||
putf(-getf());
|
||||
// binary
|
||||
else if (IS_ARG_TYPE(0, cmd_binary))
|
||||
putb(-getb());
|
||||
else
|
||||
ERR_CONTEXT(ret_bad_operand_type);
|
||||
}
|
||||
|
||||
void inv()
|
||||
{
|
||||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
|
||||
// arithmetic faults are managed by c++
|
||||
putf(1 / getf());
|
||||
// arithmetic faults are managed by c++
|
||||
putf(1 / getf());
|
||||
}
|
||||
|
||||
void purcent()
|
||||
{
|
||||
MIN_ARGUMENTS(2);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
ARG_MUST_BE_OF_TYPE(1, cmd_number);
|
||||
MIN_ARGUMENTS(2);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
ARG_MUST_BE_OF_TYPE(1, cmd_number);
|
||||
|
||||
putf((getf() * getf()) / 100);
|
||||
putf((getf() * getf()) / 100);
|
||||
}
|
||||
|
||||
void purcentCH()
|
||||
{
|
||||
MIN_ARGUMENTS(2);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
ARG_MUST_BE_OF_TYPE(1, cmd_number);
|
||||
MIN_ARGUMENTS(2);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
ARG_MUST_BE_OF_TYPE(1, cmd_number);
|
||||
|
||||
// arithmetic faults are managed by c++
|
||||
floating_t first = getf();
|
||||
putf((100 * first) / getf());
|
||||
// arithmetic faults are managed by c++
|
||||
floating_t first = getf();
|
||||
putf((100 * first) / getf());
|
||||
}
|
||||
|
||||
void power()
|
||||
{
|
||||
MIN_ARGUMENTS(2);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
ARG_MUST_BE_OF_TYPE(1, cmd_number);
|
||||
MIN_ARGUMENTS(2);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
ARG_MUST_BE_OF_TYPE(1, cmd_number);
|
||||
|
||||
// arithmetic faults are managed by c++
|
||||
floating_t first = getf();
|
||||
putf(powl(getf(), first));
|
||||
// arithmetic faults are managed by c++
|
||||
floating_t first = getf();
|
||||
putf(powl(getf(), first));
|
||||
}
|
||||
|
||||
void squareroot()
|
||||
{
|
||||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
|
||||
// arithmetic faults are managed by c++
|
||||
putf(sqrtl(getf()));
|
||||
// arithmetic faults are managed by c++
|
||||
putf(sqrtl(getf()));
|
||||
}
|
||||
|
||||
void square()
|
||||
{
|
||||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
|
||||
floating_t first = getf();
|
||||
putf(first * first);
|
||||
floating_t first = getf();
|
||||
putf(first * first);
|
||||
}
|
||||
|
|
|
@ -1,27 +1,27 @@
|
|||
void dec()
|
||||
{
|
||||
binary::s_mode = binary::dec;
|
||||
binary::s_mode = binary::dec;
|
||||
}
|
||||
|
||||
void hex()
|
||||
{
|
||||
binary::s_mode = binary::hex;
|
||||
binary::s_mode = binary::hex;
|
||||
}
|
||||
|
||||
void oct()
|
||||
{
|
||||
binary::s_mode = binary::oct;
|
||||
binary::s_mode = binary::oct;
|
||||
}
|
||||
|
||||
void bin()
|
||||
{
|
||||
binary::s_mode = binary::bin;
|
||||
binary::s_mode = binary::bin;
|
||||
}
|
||||
|
||||
void rtob()
|
||||
{
|
||||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
|
||||
binary bin;
|
||||
bin.set(((integer_t)getf()));
|
||||
|
@ -31,8 +31,8 @@ void rtob()
|
|||
|
||||
void btor()
|
||||
{
|
||||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_binary);
|
||||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_binary);
|
||||
|
||||
putf((floating_t)getb());
|
||||
putf((floating_t)getb());
|
||||
}
|
||||
|
|
238
src/rpn-branch.h
238
src/rpn-branch.h
|
@ -2,167 +2,167 @@
|
|||
//
|
||||
int rpn_if(branch& myobj)
|
||||
{
|
||||
// myobj.arg1 = 'if' condition evaluation value
|
||||
MIN_ARGUMENTS_RET(1, -1);
|
||||
ARG_MUST_BE_OF_TYPE_RET(0, cmd_number, -1);
|
||||
myobj.arg1 = ((getf() != 0) ? 1 : 0);
|
||||
return -1;
|
||||
// myobj.arg1 = 'if' condition evaluation value
|
||||
MIN_ARGUMENTS_RET(1, -1);
|
||||
ARG_MUST_BE_OF_TYPE_RET(0, cmd_number, -1);
|
||||
myobj.arg1 = ((getf() != 0) ? 1 : 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int rpn_then(branch& myobj)
|
||||
{
|
||||
// myobj.arg1 = index of then + 1
|
||||
// myobj.arg2 = index of else + 1 or end + 1
|
||||
// myobj.arg3 = index of if
|
||||
// if condition is true -> arg1 (= jump to then + 1)
|
||||
// else -> arg2 (= jump to else + 1 or end + 1)
|
||||
branch* if_cmd = (branch*)seq_obj(myobj.arg3);
|
||||
if (if_cmd->arg1 == 1)
|
||||
return myobj.arg1;
|
||||
else
|
||||
return myobj.arg2;
|
||||
// myobj.arg1 = index of then + 1
|
||||
// myobj.arg2 = index of else + 1 or end + 1
|
||||
// myobj.arg3 = index of if
|
||||
// if condition is true -> arg1 (= jump to then + 1)
|
||||
// else -> arg2 (= jump to else + 1 or end + 1)
|
||||
branch* if_cmd = (branch*)seq_obj(myobj.arg3);
|
||||
if (if_cmd->arg1 == 1)
|
||||
return myobj.arg1;
|
||||
else
|
||||
return myobj.arg2;
|
||||
}
|
||||
|
||||
int rpn_else(branch& myobj)
|
||||
{
|
||||
// myobj.arg1 = index of else + 1
|
||||
// myobj.arg2 = index of end + 1
|
||||
// myobj.arg3 = index of if
|
||||
// if condition was false -> arg1 (= jump to else + 1)
|
||||
// if condition was true -> arg2 (= jump to end + 1)
|
||||
branch* if_cmd = (branch*)seq_obj(myobj.arg3);
|
||||
if (if_cmd->arg1 == 1)
|
||||
return myobj.arg2;
|
||||
else
|
||||
return myobj.arg1;
|
||||
// myobj.arg1 = index of else + 1
|
||||
// myobj.arg2 = index of end + 1
|
||||
// myobj.arg3 = index of if
|
||||
// if condition was false -> arg1 (= jump to else + 1)
|
||||
// if condition was true -> arg2 (= jump to end + 1)
|
||||
branch* if_cmd = (branch*)seq_obj(myobj.arg3);
|
||||
if (if_cmd->arg1 == 1)
|
||||
return myobj.arg2;
|
||||
else
|
||||
return myobj.arg1;
|
||||
}
|
||||
|
||||
void rpn_end(void)
|
||||
{
|
||||
// nothing
|
||||
// nothing
|
||||
}
|
||||
|
||||
int rpn_start(branch& myobj)
|
||||
{
|
||||
MIN_ARGUMENTS_RET(2, 1);
|
||||
ARG_MUST_BE_OF_TYPE_RET(0, cmd_number, -1);
|
||||
ARG_MUST_BE_OF_TYPE_RET(1, cmd_number, -1);
|
||||
MIN_ARGUMENTS_RET(2, 1);
|
||||
ARG_MUST_BE_OF_TYPE_RET(0, cmd_number, -1);
|
||||
ARG_MUST_BE_OF_TYPE_RET(1, cmd_number, -1);
|
||||
|
||||
// farg1 = first value of start command
|
||||
// farg2 = last value of start command
|
||||
myobj.farg2 = getf();
|
||||
myobj.farg1 = getf();
|
||||
return -1;
|
||||
// farg1 = first value of start command
|
||||
// farg2 = last value of start command
|
||||
myobj.farg2 = getf();
|
||||
myobj.farg1 = getf();
|
||||
return -1;
|
||||
}
|
||||
|
||||
int rpn_for(branch& myobj)
|
||||
{
|
||||
MIN_ARGUMENTS_RET(2, 1);
|
||||
ARG_MUST_BE_OF_TYPE_RET(0, cmd_number, -1);
|
||||
ARG_MUST_BE_OF_TYPE_RET(1, cmd_number, -1);
|
||||
MIN_ARGUMENTS_RET(2, 1);
|
||||
ARG_MUST_BE_OF_TYPE_RET(0, cmd_number, -1);
|
||||
ARG_MUST_BE_OF_TYPE_RET(1, cmd_number, -1);
|
||||
|
||||
symbol* sym = ((symbol*)seq_obj(myobj.arg1));
|
||||
symbol* sym = ((symbol*)seq_obj(myobj.arg1));
|
||||
|
||||
// farg1 = first value of for command
|
||||
// farg2 = last value of for command
|
||||
// arg1 = index of symbol to increase
|
||||
myobj.farg2 = getf();
|
||||
myobj.farg1 = getf();
|
||||
// farg1 = first value of for command
|
||||
// farg2 = last value of for command
|
||||
// arg1 = index of symbol to increase
|
||||
myobj.farg2 = getf();
|
||||
myobj.farg1 = getf();
|
||||
|
||||
// store symbol with first value
|
||||
// store symbol with first value
|
||||
number num;
|
||||
num.set(myobj.farg1);
|
||||
_local_heap.add(string(sym->_value), &num, num.size(), cmd_number);
|
||||
|
||||
return myobj.arg1 + 1;
|
||||
return myobj.arg1 + 1;
|
||||
}
|
||||
|
||||
int rpn_next(branch& myobj)
|
||||
{
|
||||
// arg1 = index of start or for command in program
|
||||
// farg1 = current count
|
||||
branch* start_or_for = (branch*)seq_obj(myobj.arg1);
|
||||
if (! myobj.arg_bool)
|
||||
{
|
||||
myobj.arg_bool = true;
|
||||
myobj.farg1 = start_or_for->farg1;
|
||||
}
|
||||
// arg1 = index of start or for command in program
|
||||
// farg1 = current count
|
||||
branch* start_or_for = (branch*)seq_obj(myobj.arg1);
|
||||
if (! myobj.arg_bool)
|
||||
{
|
||||
myobj.arg_bool = true;
|
||||
myobj.farg1 = start_or_for->farg1;
|
||||
}
|
||||
|
||||
// increment then test
|
||||
myobj.farg1++;
|
||||
// increment then test
|
||||
myobj.farg1++;
|
||||
|
||||
// for command: increment symbol too
|
||||
if (start_or_for->arg1 != -1)
|
||||
{
|
||||
void* obj;
|
||||
unsigned int size;
|
||||
int type;
|
||||
symbol* var = (symbol*)seq_obj(start_or_for->arg1);
|
||||
// check symbol variable is a number, then increase
|
||||
// for command: increment symbol too
|
||||
if (start_or_for->arg1 != -1)
|
||||
{
|
||||
void* obj;
|
||||
unsigned int size;
|
||||
int type;
|
||||
symbol* var = (symbol*)seq_obj(start_or_for->arg1);
|
||||
// check symbol variable is a number, then increase
|
||||
if (_local_heap.get(string(var->_value), obj, size, type) && (type == cmd_number))
|
||||
((number*)obj)->_value = myobj.farg1;
|
||||
}
|
||||
((number*)obj)->_value = myobj.farg1;
|
||||
}
|
||||
|
||||
//test value
|
||||
if (myobj.farg1 > start_or_for->farg2)
|
||||
{
|
||||
// end of loop
|
||||
myobj.arg_bool = false;// init again next time
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// for command: next instruction will be after symbol variable
|
||||
if (start_or_for->arg1 != -1)
|
||||
return start_or_for->arg1 + 1;
|
||||
// start command: next instruction will be after start command
|
||||
else
|
||||
return myobj.arg1 + 1;
|
||||
}
|
||||
//test value
|
||||
if (myobj.farg1 > start_or_for->farg2)
|
||||
{
|
||||
// end of loop
|
||||
myobj.arg_bool = false;// init again next time
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// for command: next instruction will be after symbol variable
|
||||
if (start_or_for->arg1 != -1)
|
||||
return start_or_for->arg1 + 1;
|
||||
// start command: next instruction will be after start command
|
||||
else
|
||||
return myobj.arg1 + 1;
|
||||
}
|
||||
}
|
||||
|
||||
int rpn_step(branch& myobj)
|
||||
{
|
||||
// arg1 = index of start or for command in program
|
||||
// farg1 = current count
|
||||
floating_t step = getf();
|
||||
branch* start_or_for = (branch*)seq_obj(myobj.arg1);
|
||||
if (! myobj.arg_bool)
|
||||
{
|
||||
myobj.arg_bool = true;
|
||||
myobj.farg1 = start_or_for->farg1;
|
||||
}
|
||||
// arg1 = index of start or for command in program
|
||||
// farg1 = current count
|
||||
floating_t step = getf();
|
||||
branch* start_or_for = (branch*)seq_obj(myobj.arg1);
|
||||
if (! myobj.arg_bool)
|
||||
{
|
||||
myobj.arg_bool = true;
|
||||
myobj.farg1 = start_or_for->farg1;
|
||||
}
|
||||
|
||||
// increment then test
|
||||
myobj.farg1 += step;
|
||||
// increment then test
|
||||
myobj.farg1 += step;
|
||||
|
||||
// for command: increment symbol too
|
||||
if (start_or_for->arg1 != -1)
|
||||
{
|
||||
void* obj;
|
||||
unsigned int size;
|
||||
int type;
|
||||
symbol* var = (symbol*)seq_obj(start_or_for->arg1);
|
||||
// check symbol variable is a number, then increase
|
||||
// for command: increment symbol too
|
||||
if (start_or_for->arg1 != -1)
|
||||
{
|
||||
void* obj;
|
||||
unsigned int size;
|
||||
int type;
|
||||
symbol* var = (symbol*)seq_obj(start_or_for->arg1);
|
||||
// check symbol variable is a number, then increase
|
||||
if (_local_heap.get(string(var->_value), obj, size, type) && (type == cmd_number))
|
||||
((number*)obj)->_value = myobj.farg1;
|
||||
}
|
||||
((number*)obj)->_value = myobj.farg1;
|
||||
}
|
||||
|
||||
//test value
|
||||
if (((step>0) && (myobj.farg1 > start_or_for->farg2))
|
||||
|| ((step<0) && (myobj.farg1 < start_or_for->farg2)))
|
||||
{
|
||||
// end of loop
|
||||
myobj.arg_bool = false;// init again next time
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// for command: next instruction will be after symbol variable
|
||||
if (start_or_for->arg1 != -1)
|
||||
return start_or_for->arg1 + 1;
|
||||
// start command: next instruction will be after start command
|
||||
else
|
||||
return myobj.arg1 + 1;
|
||||
}
|
||||
//test value
|
||||
if (((step>0) && (myobj.farg1 > start_or_for->farg2))
|
||||
|| ((step<0) && (myobj.farg1 < start_or_for->farg2)))
|
||||
{
|
||||
// end of loop
|
||||
myobj.arg_bool = false;// init again next time
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// for command: next instruction will be after symbol variable
|
||||
if (start_or_for->arg1 != -1)
|
||||
return start_or_for->arg1 + 1;
|
||||
// start command: next instruction will be after start command
|
||||
else
|
||||
return myobj.arg1 + 1;
|
||||
}
|
||||
}
|
||||
|
|
198
src/rpn-cmd.h
198
src/rpn-cmd.h
|
@ -11,116 +11,116 @@ program::keyword_t program::_keywords[] =
|
|||
{ cmd_keyword, "exit", &program::good_bye, "" },
|
||||
{ cmd_keyword, "test", &program::test, "" }, //not seen by user
|
||||
{ cmd_keyword, "verbose", &program::verbose, "set verbosity, from 0 (not verbose) to > 0" },
|
||||
{ cmd_keyword, "std", &program::std, "standard floating numbers representation. ex: [25] std" },
|
||||
{ cmd_keyword, "fix", &program::fix, "fixed point representation. ex: 6 fix" },
|
||||
{ cmd_keyword, "sci", &program::sci, "scientific floating point representation. ex: 20 sci" },
|
||||
{ cmd_keyword, "version", &program::rpn_version, "show rpn version" },
|
||||
{ cmd_keyword, "uname", &program::rpn_uname, "show rpn complete identification string" },
|
||||
{ cmd_keyword, "std", &program::std, "standard floating numbers representation. ex: [25] std" },
|
||||
{ cmd_keyword, "fix", &program::fix, "fixed point representation. ex: 6 fix" },
|
||||
{ cmd_keyword, "sci", &program::sci, "scientific floating point representation. ex: 20 sci" },
|
||||
{ cmd_keyword, "version", &program::rpn_version, "show rpn version" },
|
||||
{ cmd_keyword, "uname", &program::rpn_uname, "show rpn complete identification string" },
|
||||
|
||||
//ALGEBRA
|
||||
{ cmd_undef, "", NULL, "\nALGEBRA"},
|
||||
{ cmd_keyword, "+", &program::plus, "binary operator +" },
|
||||
{ cmd_keyword, "-", &program::minus, "binary operator -" },
|
||||
{ cmd_keyword, "neg", &program::neg , "unary operator - (negation)" },
|
||||
{ cmd_keyword, "*", &program::mul, "binary operator *" },
|
||||
{ cmd_keyword, "/", &program::div, "binary operator /" },
|
||||
{ cmd_keyword, "inv", &program::inv, "unarity operator inverse (1/)" },
|
||||
{ cmd_keyword, "%", &program::purcent, "binary operator purcent" },
|
||||
{ cmd_keyword, "%CH", &program::purcentCH, "binary operator inverse purcent" },
|
||||
{ cmd_keyword, "^", &program::power, "binary operator power" },
|
||||
{ cmd_keyword, "sqrt", &program::squareroot, "unarity operator square root" },
|
||||
{ cmd_keyword, "sq", &program::square, "unarity operator square" },
|
||||
//ALGEBRA
|
||||
{ cmd_undef, "", NULL, "\nALGEBRA"},
|
||||
{ cmd_keyword, "+", &program::plus, "binary operator +" },
|
||||
{ cmd_keyword, "-", &program::minus, "binary operator -" },
|
||||
{ cmd_keyword, "neg", &program::neg , "unary operator - (negation)" },
|
||||
{ cmd_keyword, "*", &program::mul, "binary operator *" },
|
||||
{ cmd_keyword, "/", &program::div, "binary operator /" },
|
||||
{ cmd_keyword, "inv", &program::inv, "unarity operator inverse (1/)" },
|
||||
{ cmd_keyword, "%", &program::purcent, "binary operator purcent" },
|
||||
{ cmd_keyword, "%CH", &program::purcentCH, "binary operator inverse purcent" },
|
||||
{ cmd_keyword, "^", &program::power, "binary operator power" },
|
||||
{ cmd_keyword, "sqrt", &program::squareroot, "unarity operator square root" },
|
||||
{ cmd_keyword, "sq", &program::square, "unarity operator square" },
|
||||
|
||||
//BINARY
|
||||
{ cmd_undef, "", NULL, "\nBINARY"},
|
||||
{ cmd_keyword, "dec", &program::dec, "decimal representation for binaries" },
|
||||
{ cmd_keyword, "hex", &program::hex, "hexadecimal representation for binaries" },
|
||||
{ cmd_keyword, "oct", &program::oct, "octal representation for binaries" },
|
||||
{ cmd_keyword, "bin", &program::bin, "binary representation for binaries" },
|
||||
{ cmd_keyword, "r->b", &program::rtob, "real to binary" },
|
||||
{ cmd_keyword, "b->r", &program::btor, "binary to real" },
|
||||
//BINARY
|
||||
{ cmd_undef, "", NULL, "\nBINARY"},
|
||||
{ cmd_keyword, "dec", &program::dec, "decimal representation for binaries" },
|
||||
{ cmd_keyword, "hex", &program::hex, "hexadecimal representation for binaries" },
|
||||
{ cmd_keyword, "oct", &program::oct, "octal representation for binaries" },
|
||||
{ cmd_keyword, "bin", &program::bin, "binary representation for binaries" },
|
||||
{ cmd_keyword, "r->b", &program::rtob, "real to binary" },
|
||||
{ cmd_keyword, "b->r", &program::btor, "binary to real" },
|
||||
|
||||
//TEST
|
||||
{ cmd_undef, "", NULL, "\nTEST"},
|
||||
{ cmd_keyword, ">", &program::sup, "binary operator >" },
|
||||
{ cmd_keyword, ">=", &program::sup_eq, "binary operator >=" },
|
||||
{ cmd_keyword, "<", &program::inf, "binary operator <" },
|
||||
{ cmd_keyword, "<=", &program::inf_eq, "binary operator <=" },
|
||||
{ cmd_keyword, "!=", &program::diff, "binary operator != (different)" },
|
||||
{ cmd_keyword, "==", &program::eq , "binary operator == (equal)" },
|
||||
{ cmd_keyword, "and", &program::test_and , "boolean operator and" },
|
||||
{ cmd_keyword, "or", &program::test_or , "boolean operator or" },
|
||||
{ cmd_keyword, "xor", &program::test_xor , "boolean operator xor" },
|
||||
{ cmd_keyword, "not", &program::test_not , "boolean operator not" },
|
||||
{ cmd_keyword, "same", &program::same , "boolean operator same (equal)" },
|
||||
//TEST
|
||||
{ cmd_undef, "", NULL, "\nTEST"},
|
||||
{ cmd_keyword, ">", &program::sup, "binary operator >" },
|
||||
{ cmd_keyword, ">=", &program::sup_eq, "binary operator >=" },
|
||||
{ cmd_keyword, "<", &program::inf, "binary operator <" },
|
||||
{ cmd_keyword, "<=", &program::inf_eq, "binary operator <=" },
|
||||
{ cmd_keyword, "!=", &program::diff, "binary operator != (different)" },
|
||||
{ cmd_keyword, "==", &program::eq , "binary operator == (equal)" },
|
||||
{ cmd_keyword, "and", &program::test_and , "boolean operator and" },
|
||||
{ cmd_keyword, "or", &program::test_or , "boolean operator or" },
|
||||
{ cmd_keyword, "xor", &program::test_xor , "boolean operator xor" },
|
||||
{ cmd_keyword, "not", &program::test_not , "boolean operator not" },
|
||||
{ cmd_keyword, "same", &program::same , "boolean operator same (equal)" },
|
||||
|
||||
//STACK
|
||||
{ cmd_undef, "", NULL, "\nSTACK"},
|
||||
{ cmd_keyword, "swap", &program::swap, "swap 2 first stack entries" },
|
||||
{ cmd_keyword, "drop", &program::drop, "drop first stack entry" },
|
||||
{ cmd_keyword, "drop2", &program::drop2, "drop 2 first stack entries" },
|
||||
{ cmd_keyword, "erase", &program::erase, "drop all stack entries" },
|
||||
{ cmd_keyword, "rot", &program::rot, "rotate 3 first stack entries" },
|
||||
{ cmd_keyword, "dup", &program::dup, "duplicate first stack entry" },
|
||||
{ cmd_keyword, "dup2", &program::dup2, "duplicate 2 first stack entries" },
|
||||
{ cmd_keyword, "pick", &program::pick, "push a copy of the given stack level onto the stack" },
|
||||
{ cmd_keyword, "depth", &program::depth, "give stack depth" },
|
||||
//STACK
|
||||
{ cmd_undef, "", NULL, "\nSTACK"},
|
||||
{ cmd_keyword, "swap", &program::swap, "swap 2 first stack entries" },
|
||||
{ cmd_keyword, "drop", &program::drop, "drop first stack entry" },
|
||||
{ cmd_keyword, "drop2", &program::drop2, "drop 2 first stack entries" },
|
||||
{ cmd_keyword, "erase", &program::erase, "drop all stack entries" },
|
||||
{ cmd_keyword, "rot", &program::rot, "rotate 3 first stack entries" },
|
||||
{ cmd_keyword, "dup", &program::dup, "duplicate first stack entry" },
|
||||
{ cmd_keyword, "dup2", &program::dup2, "duplicate 2 first stack entries" },
|
||||
{ cmd_keyword, "pick", &program::pick, "push a copy of the given stack level onto the stack" },
|
||||
{ cmd_keyword, "depth", &program::depth, "give stack depth" },
|
||||
|
||||
//STRING
|
||||
{ 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" },
|
||||
//STRING
|
||||
{ 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" },
|
||||
|
||||
//BRANCH
|
||||
{ cmd_undef, "", NULL, "\nBRANCH"},
|
||||
{ cmd_branch, "if", (program_fn_t)&program::rpn_if, "<test-instructions>" },
|
||||
{ cmd_branch, "then", (program_fn_t)&program::rpn_then, "<true-instructions>" },
|
||||
{ cmd_branch, "else", (program_fn_t)&program::rpn_else, "<false-instructions>" },
|
||||
{ cmd_keyword, "end", &program::rpn_end, "(end of if structure)" },
|
||||
{ cmd_branch, "start", (program_fn_t)&program::rpn_start, "repeat instructions several times" },
|
||||
{ cmd_branch, "for", (program_fn_t)&program::rpn_for, "repeat instructions several times with variable" },
|
||||
{ cmd_branch, "next", (program_fn_t)&program::rpn_next, "ex: 1 10 start <instructions> next" },
|
||||
{ cmd_branch, "step", (program_fn_t)&program::rpn_step, "ex: 1 100 start <instructions> 4 step" },
|
||||
//BRANCH
|
||||
{ cmd_undef, "", NULL, "\nBRANCH"},
|
||||
{ cmd_branch, "if", (program_fn_t)&program::rpn_if, "<test-instructions>" },
|
||||
{ cmd_branch, "then", (program_fn_t)&program::rpn_then, "<true-instructions>" },
|
||||
{ cmd_branch, "else", (program_fn_t)&program::rpn_else, "<false-instructions>" },
|
||||
{ cmd_keyword, "end", &program::rpn_end, "(end of if structure)" },
|
||||
{ cmd_branch, "start", (program_fn_t)&program::rpn_start, "repeat instructions several times" },
|
||||
{ cmd_branch, "for", (program_fn_t)&program::rpn_for, "repeat instructions several times with variable" },
|
||||
{ cmd_branch, "next", (program_fn_t)&program::rpn_next, "ex: 1 10 start <instructions> next" },
|
||||
{ cmd_branch, "step", (program_fn_t)&program::rpn_step, "ex: 1 100 start <instructions> 4 step" },
|
||||
|
||||
//STORE
|
||||
{ cmd_undef, "", NULL, "\nSTORE"},
|
||||
{ cmd_keyword, "sto", &program::sto, "store a variable. ex: 1 'name' sto" },
|
||||
{ cmd_keyword, "rcl", &program::rcl, "recall a variable. ex: 'name' rcl" },
|
||||
{ cmd_keyword, "purge", &program::purge, "delete a variable. ex: 'name' purge" },
|
||||
{ cmd_keyword, "vars", &program::vars, "list all variables" },
|
||||
//STORE
|
||||
{ cmd_undef, "", NULL, "\nSTORE"},
|
||||
{ cmd_keyword, "sto", &program::sto, "store a variable. ex: 1 'name' sto" },
|
||||
{ cmd_keyword, "rcl", &program::rcl, "recall a variable. ex: 'name' rcl" },
|
||||
{ cmd_keyword, "purge", &program::purge, "delete a variable. ex: 'name' purge" },
|
||||
{ cmd_keyword, "vars", &program::vars, "list all variables" },
|
||||
{ cmd_keyword, "edit", &program::edit, "edit a vriable content" },
|
||||
|
||||
//PROGRAM
|
||||
{ cmd_undef, "", NULL, "\nPROGRAM"},
|
||||
{ cmd_keyword, "eval", &program::eval, "evaluate (run) a program, or recall a variable. ex: 'my_prog' eval" },
|
||||
//PROGRAM
|
||||
{ cmd_undef, "", NULL, "\nPROGRAM"},
|
||||
{ cmd_keyword, "eval", &program::eval, "evaluate (run) a program, or recall a variable. ex: 'my_prog' eval" },
|
||||
{ cmd_branch, "->", (program_fn_t)&program::inprog, "load program local variables. ex: << -> n m << 0 n m for i i + next >> >>" },
|
||||
|
||||
//TRIG
|
||||
{ cmd_undef, "", NULL, "\nTRIG"},
|
||||
{ cmd_keyword, "pi", &program::pi, "PI constant" },
|
||||
{ cmd_keyword, "sin", &program::rpn_sin, "sinus" },
|
||||
{ cmd_keyword, "asin", &program::rpn_asin, "arg sinus" },
|
||||
{ cmd_keyword, "cos", &program::rpn_cos , "cosinus" },
|
||||
{ cmd_keyword, "acos", &program::rpn_acos, "arg cosinus" },
|
||||
{ cmd_keyword, "tan", &program::rpn_tan, "tangent" },
|
||||
{ cmd_keyword, "atan", &program::rpn_atan, "arg tangent" },
|
||||
{ cmd_keyword, "d->r", &program::d2r, "convert degrees to radians" },
|
||||
{ cmd_keyword, "r->d", &program::r2d, "convert radians to degrees" },
|
||||
//TRIG
|
||||
{ cmd_undef, "", NULL, "\nTRIG"},
|
||||
{ cmd_keyword, "pi", &program::pi, "PI constant" },
|
||||
{ cmd_keyword, "sin", &program::rpn_sin, "sinus" },
|
||||
{ cmd_keyword, "asin", &program::rpn_asin, "arg sinus" },
|
||||
{ cmd_keyword, "cos", &program::rpn_cos , "cosinus" },
|
||||
{ cmd_keyword, "acos", &program::rpn_acos, "arg cosinus" },
|
||||
{ cmd_keyword, "tan", &program::rpn_tan, "tangent" },
|
||||
{ cmd_keyword, "atan", &program::rpn_atan, "arg tangent" },
|
||||
{ cmd_keyword, "d->r", &program::d2r, "convert degrees to radians" },
|
||||
{ cmd_keyword, "r->d", &program::r2d, "convert radians to degrees" },
|
||||
|
||||
//LOGS
|
||||
{ cmd_undef, "", NULL, "\nLOGS"},
|
||||
{ cmd_keyword, "e", &program::rpn_e, "exp(0) constant" },
|
||||
{ cmd_keyword, "log", &program::rpn_log, "logarithm base 10" },
|
||||
{ cmd_keyword, "alog", &program::rpn_alog, "exponential base 10" },
|
||||
{ cmd_keyword, "ln", &program::rpn_ln, "logarithm base e" },
|
||||
{ cmd_keyword, "exp", &program::rpn_exp, "exponential" },
|
||||
{ cmd_keyword, "sinh", &program::rpn_sinh, "hyperbolic sine" },
|
||||
{ cmd_keyword, "asinh", &program::rpn_asinh, "inverse hyperbolic sine" },
|
||||
{ cmd_keyword, "cosh", &program::rpn_sinh, "hyperbolic cosine" },
|
||||
{ cmd_keyword, "acosh", &program::rpn_acosh, "inverse hyperbolic cosine" },
|
||||
{ cmd_keyword, "tanh", &program::rpn_tanh, "hyperbolic tangent" },
|
||||
{ cmd_keyword, "atanh", &program::rpn_atanh, "inverse hyperbolic tangent" },
|
||||
//LOGS
|
||||
{ cmd_undef, "", NULL, "\nLOGS"},
|
||||
{ cmd_keyword, "e", &program::rpn_e, "exp(0) constant" },
|
||||
{ cmd_keyword, "log", &program::rpn_log, "logarithm base 10" },
|
||||
{ cmd_keyword, "alog", &program::rpn_alog, "exponential base 10" },
|
||||
{ cmd_keyword, "ln", &program::rpn_ln, "logarithm base e" },
|
||||
{ cmd_keyword, "exp", &program::rpn_exp, "exponential" },
|
||||
{ cmd_keyword, "sinh", &program::rpn_sinh, "hyperbolic sine" },
|
||||
{ cmd_keyword, "asinh", &program::rpn_asinh, "inverse hyperbolic sine" },
|
||||
{ cmd_keyword, "cosh", &program::rpn_sinh, "hyperbolic cosine" },
|
||||
{ cmd_keyword, "acosh", &program::rpn_acosh, "inverse hyperbolic cosine" },
|
||||
{ cmd_keyword, "tanh", &program::rpn_tanh, "hyperbolic tangent" },
|
||||
{ cmd_keyword, "atanh", &program::rpn_atanh, "inverse hyperbolic tangent" },
|
||||
|
||||
// end
|
||||
{ cmd_max, "", NULL, "" },
|
||||
// end
|
||||
{ cmd_max, "", NULL, "" },
|
||||
};
|
||||
|
|
|
@ -3,97 +3,97 @@ void test();
|
|||
//
|
||||
void nop()
|
||||
{
|
||||
// nop
|
||||
// nop
|
||||
}
|
||||
|
||||
void good_bye()
|
||||
{
|
||||
ERR_CONTEXT(ret_good_bye);
|
||||
ERR_CONTEXT(ret_good_bye);
|
||||
}
|
||||
|
||||
void verbose()
|
||||
{
|
||||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
g_verbose = (int)getf();
|
||||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
g_verbose = (int)getf();
|
||||
}
|
||||
|
||||
void help()
|
||||
{
|
||||
cout<<endl;
|
||||
cout<<endl;
|
||||
cout<<ATTR_BOLD<<uname<<ATTR_OFF<<endl;
|
||||
cout<<endl;
|
||||
cout<<endl;
|
||||
|
||||
// syntax
|
||||
for (int i = 0; syntax[i] != NULL; i++)
|
||||
cout<<syntax[i]<<endl;
|
||||
// syntax
|
||||
for (int i = 0; syntax[i] != NULL; i++)
|
||||
cout<<syntax[i]<<endl;
|
||||
|
||||
// keywords
|
||||
for(unsigned int i=0; i<sizeof(_keywords)/sizeof(_keywords[0]); i++)
|
||||
if (_keywords[i].comment.size() != 0)
|
||||
cout<<_keywords[i].name<<"\t"<<_keywords[i].comment<<endl;
|
||||
cout<<endl;
|
||||
if (_keywords[i].comment.size() != 0)
|
||||
cout<<_keywords[i].name<<"\t"<<_keywords[i].comment<<endl;
|
||||
cout<<endl;
|
||||
|
||||
// different modes
|
||||
cout<<"Current verbosity is "<<g_verbose<<endl;
|
||||
// different modes
|
||||
cout<<"Current verbosity is "<<g_verbose<<endl;
|
||||
|
||||
cout<<"Current float mode is ";
|
||||
switch(number::s_mode)
|
||||
{
|
||||
case number::std: cout << "'std'"; break;
|
||||
case number::fix: cout << "'fix'"; break;
|
||||
case number::sci: cout << "'sci'"; break;
|
||||
default: cout << "unknown"; break;
|
||||
}
|
||||
cout<<"Current float mode is ";
|
||||
switch(number::s_mode)
|
||||
{
|
||||
case number::std: cout << "'std'"; break;
|
||||
case number::fix: cout << "'fix'"; break;
|
||||
case number::sci: cout << "'sci'"; break;
|
||||
default: cout << "unknown"; break;
|
||||
}
|
||||
|
||||
cout<<endl<<"Current float precision is "<<number::s_current_precision<<endl;
|
||||
cout<<endl<<"Current float precision is "<<number::s_current_precision<<endl;
|
||||
|
||||
cout<<"Current binary mode is ";
|
||||
switch(binary::s_mode)
|
||||
{
|
||||
case binary::dec: cout << "'dec'"; break;
|
||||
case binary::hex: cout << "'hex'"; break;
|
||||
case binary::oct: cout << "'oct'"; break;
|
||||
case binary::bin: cout << "'bin'"; break;
|
||||
default: cout << "unknown"; break;
|
||||
}
|
||||
cout<<endl<<endl;
|
||||
cout<<"Current binary mode is ";
|
||||
switch(binary::s_mode)
|
||||
{
|
||||
case binary::dec: cout << "'dec'"; break;
|
||||
case binary::hex: cout << "'hex'"; break;
|
||||
case binary::oct: cout << "'oct'"; break;
|
||||
case binary::bin: cout << "'bin'"; break;
|
||||
default: cout << "unknown"; break;
|
||||
}
|
||||
cout<<endl<<endl;
|
||||
}
|
||||
|
||||
void std()
|
||||
{
|
||||
if (stack_size()>=1)
|
||||
{
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
number::s_default_precision = (int)getf();
|
||||
}
|
||||
number::s_current_precision = number::s_default_precision;
|
||||
number::s_mode = number::std;
|
||||
if (stack_size()>=1)
|
||||
{
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
number::s_default_precision = (int)getf();
|
||||
}
|
||||
number::s_current_precision = number::s_default_precision;
|
||||
number::s_mode = number::std;
|
||||
|
||||
cout.precision(number::s_current_precision);
|
||||
cout.unsetf(ios_base::floatfield);
|
||||
cout.precision(number::s_current_precision);
|
||||
cout.unsetf(ios_base::floatfield);
|
||||
}
|
||||
|
||||
void fix()
|
||||
{
|
||||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
|
||||
number::s_current_precision = (int)getf();
|
||||
number::s_mode = number::fix;
|
||||
number::s_current_precision = (int)getf();
|
||||
number::s_mode = number::fix;
|
||||
|
||||
cout << setprecision(number::s_current_precision) << fixed;
|
||||
cout << setprecision(number::s_current_precision) << fixed;
|
||||
}
|
||||
|
||||
void sci()
|
||||
{
|
||||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
|
||||
number::s_current_precision = (int)getf();
|
||||
number::s_mode = number::sci;
|
||||
number::s_current_precision = (int)getf();
|
||||
number::s_mode = number::sci;
|
||||
|
||||
cout << setprecision(number::s_current_precision) << scientific;
|
||||
cout << setprecision(number::s_current_precision) << scientific;
|
||||
}
|
||||
|
||||
void rpn_version()
|
||||
|
|
|
@ -3,92 +3,92 @@
|
|||
//
|
||||
void rpn_e(void)
|
||||
{
|
||||
putf(M_E);
|
||||
putf(M_E);
|
||||
}
|
||||
|
||||
void rpn_log()
|
||||
{
|
||||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
((number*)_stack->get_obj(0))->_value = log10(((number*)_stack->get_obj(0))->_value);
|
||||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
((number*)_stack->get_obj(0))->_value = log10(((number*)_stack->get_obj(0))->_value);
|
||||
}
|
||||
|
||||
void rpn_alog()
|
||||
{
|
||||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
((number*)_stack->get_obj(0))->_value = pow(((number*)_stack->get_obj(0))->_value, 10);
|
||||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
((number*)_stack->get_obj(0))->_value = pow(((number*)_stack->get_obj(0))->_value, 10);
|
||||
}
|
||||
|
||||
void rpn_ln()
|
||||
{
|
||||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
((number*)_stack->get_obj(0))->_value = log(((number*)_stack->get_obj(0))->_value);
|
||||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
((number*)_stack->get_obj(0))->_value = log(((number*)_stack->get_obj(0))->_value);
|
||||
}
|
||||
|
||||
void rpn_exp()
|
||||
{
|
||||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
((number*)_stack->get_obj(0))->_value = exp(((number*)_stack->get_obj(0))->_value);
|
||||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
((number*)_stack->get_obj(0))->_value = exp(((number*)_stack->get_obj(0))->_value);
|
||||
}
|
||||
|
||||
void rpn_sinh()
|
||||
{
|
||||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
((number*)_stack->get_obj(0))->_value = sinh(((number*)_stack->get_obj(0))->_value);
|
||||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
((number*)_stack->get_obj(0))->_value = sinh(((number*)_stack->get_obj(0))->_value);
|
||||
}
|
||||
|
||||
void rpn_asinh()
|
||||
{
|
||||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
|
||||
floating_t value = ((number*)_stack->get_obj(0))->_value;
|
||||
if(value>0)
|
||||
value = log(value + sqrt(value * value + 1));
|
||||
else
|
||||
value = -log(-value + sqrt(value * value + 1));
|
||||
floating_t value = ((number*)_stack->get_obj(0))->_value;
|
||||
if(value>0)
|
||||
value = log(value + sqrt(value * value + 1));
|
||||
else
|
||||
value = -log(-value + sqrt(value * value + 1));
|
||||
|
||||
((number*)_stack->get_obj(0))->_value = value;
|
||||
((number*)_stack->get_obj(0))->_value = value;
|
||||
}
|
||||
|
||||
void rpn_cosh()
|
||||
{
|
||||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
((number*)_stack->get_obj(0))->_value = cosh(((number*)_stack->get_obj(0))->_value);
|
||||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
((number*)_stack->get_obj(0))->_value = cosh(((number*)_stack->get_obj(0))->_value);
|
||||
}
|
||||
|
||||
void rpn_acosh()
|
||||
{
|
||||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
|
||||
floating_t value = ((number*)_stack->get_obj(0))->_value;
|
||||
if(value>0)
|
||||
value = log(value + sqrt(value * value - 1));
|
||||
else
|
||||
value = -log(-value + sqrt(value * value - 1));
|
||||
floating_t value = ((number*)_stack->get_obj(0))->_value;
|
||||
if(value>0)
|
||||
value = log(value + sqrt(value * value - 1));
|
||||
else
|
||||
value = -log(-value + sqrt(value * value - 1));
|
||||
|
||||
((number*)_stack->get_obj(0))->_value = value;
|
||||
((number*)_stack->get_obj(0))->_value = value;
|
||||
}
|
||||
|
||||
void rpn_tanh()
|
||||
{
|
||||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
((number*)_stack->get_obj(0))->_value = tanh(((number*)_stack->get_obj(0))->_value);
|
||||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
((number*)_stack->get_obj(0))->_value = tanh(((number*)_stack->get_obj(0))->_value);
|
||||
}
|
||||
|
||||
void rpn_atanh()
|
||||
{
|
||||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
|
||||
floating_t value = ((number*)_stack->get_obj(0))->_value;
|
||||
value = (log(1 + value) - log(1 - value)) / 2;
|
||||
((number*)_stack->get_obj(0))->_value = value;
|
||||
floating_t value = ((number*)_stack->get_obj(0))->_value;
|
||||
value = (log(1 + value) - log(1 - value)) / 2;
|
||||
((number*)_stack->get_obj(0))->_value = value;
|
||||
}
|
||||
|
|
|
@ -5,19 +5,19 @@ void eval(void)
|
|||
string prog_text;
|
||||
|
||||
MIN_ARGUMENTS(1);
|
||||
if (IS_ARG_TYPE(0, cmd_symbol))
|
||||
{
|
||||
// recall a variable
|
||||
void* obj;
|
||||
unsigned int size;
|
||||
int type;
|
||||
if (IS_ARG_TYPE(0, cmd_symbol))
|
||||
{
|
||||
// recall a variable
|
||||
void* obj;
|
||||
unsigned int size;
|
||||
int type;
|
||||
string variable(((symbol*)_stack->back())->_value);
|
||||
|
||||
// mind the order of heaps
|
||||
if (_local_heap.get(variable, obj, size, type)
|
||||
|| ((_parent_local_heap != NULL) && _parent_local_heap->get(variable, obj, size, type))
|
||||
|| _global_heap->get(variable, obj, size, type))
|
||||
{
|
||||
{
|
||||
// if variable holds a program, run this program
|
||||
if (type == cmd_program)
|
||||
{
|
||||
|
@ -31,19 +31,19 @@ void eval(void)
|
|||
_stack->pop_back();
|
||||
_stack->push_back(obj, size, type);
|
||||
}
|
||||
}
|
||||
else
|
||||
ERR_CONTEXT(ret_unknown_variable);
|
||||
}
|
||||
else if (IS_ARG_TYPE(0, cmd_program))
|
||||
{
|
||||
// eval a program
|
||||
}
|
||||
else
|
||||
ERR_CONTEXT(ret_unknown_variable);
|
||||
}
|
||||
else if (IS_ARG_TYPE(0, cmd_program))
|
||||
{
|
||||
// eval a program
|
||||
prog_text = ((oprogram*)_stack->back())->_value;
|
||||
_stack->pop_back();
|
||||
_stack->pop_back();
|
||||
run_prog = true;
|
||||
}
|
||||
else
|
||||
ERR_CONTEXT(ret_bad_operand_type);
|
||||
}
|
||||
else
|
||||
ERR_CONTEXT(ret_bad_operand_type);
|
||||
|
||||
// run prog if any
|
||||
if (run_prog)
|
||||
|
|
|
@ -1,77 +1,77 @@
|
|||
//
|
||||
void swap(void)
|
||||
{
|
||||
MIN_ARGUMENTS(2);
|
||||
_stack->copy_obj_to_local(0, 0);
|
||||
_stack->copy_obj_to_local(1, 1);
|
||||
_stack->pop_back();
|
||||
_stack->pop_back();
|
||||
_stack->push_obj_from_local(0);
|
||||
_stack->push_obj_from_local(1);
|
||||
MIN_ARGUMENTS(2);
|
||||
_stack->copy_obj_to_local(0, 0);
|
||||
_stack->copy_obj_to_local(1, 1);
|
||||
_stack->pop_back();
|
||||
_stack->pop_back();
|
||||
_stack->push_obj_from_local(0);
|
||||
_stack->push_obj_from_local(1);
|
||||
}
|
||||
|
||||
void drop(void)
|
||||
{
|
||||
MIN_ARGUMENTS(1);
|
||||
_stack->pop_back();
|
||||
MIN_ARGUMENTS(1);
|
||||
_stack->pop_back();
|
||||
}
|
||||
|
||||
void drop2(void)
|
||||
{
|
||||
MIN_ARGUMENTS(2);
|
||||
_stack->pop_back();
|
||||
_stack->pop_back();
|
||||
MIN_ARGUMENTS(2);
|
||||
_stack->pop_back();
|
||||
_stack->pop_back();
|
||||
}
|
||||
|
||||
void erase(void)
|
||||
{
|
||||
while(_stack->size()>0)
|
||||
_stack->pop_back();
|
||||
while(_stack->size()>0)
|
||||
_stack->pop_back();
|
||||
}
|
||||
|
||||
void dup(void)
|
||||
{
|
||||
MIN_ARGUMENTS(1);
|
||||
_stack->copy_obj_to_local(0, 0);
|
||||
_stack->push_obj_from_local(0);
|
||||
MIN_ARGUMENTS(1);
|
||||
_stack->copy_obj_to_local(0, 0);
|
||||
_stack->push_obj_from_local(0);
|
||||
}
|
||||
|
||||
void dup2(void)
|
||||
{
|
||||
MIN_ARGUMENTS(2);
|
||||
_stack->copy_obj_to_local(0, 0);
|
||||
_stack->copy_obj_to_local(1, 1);
|
||||
_stack->push_obj_from_local(1);
|
||||
_stack->push_obj_from_local(0);
|
||||
MIN_ARGUMENTS(2);
|
||||
_stack->copy_obj_to_local(0, 0);
|
||||
_stack->copy_obj_to_local(1, 1);
|
||||
_stack->push_obj_from_local(1);
|
||||
_stack->push_obj_from_local(0);
|
||||
}
|
||||
|
||||
void pick(void)
|
||||
{
|
||||
MIN_ARGUMENTS(1);
|
||||
unsigned int to_pick = (unsigned int)getf();
|
||||
MIN_ARGUMENTS(1);
|
||||
unsigned int to_pick = (unsigned int)getf();
|
||||
|
||||
// treat stack depth errors
|
||||
if ((to_pick == 0) || (to_pick > _stack->size()))
|
||||
{
|
||||
ERR_CONTEXT(ret_missing_operand);
|
||||
return;
|
||||
}
|
||||
_stack->copy_obj_to_local(to_pick - 1, 0);
|
||||
_stack->push_obj_from_local(0);
|
||||
// treat stack depth errors
|
||||
if ((to_pick == 0) || (to_pick > _stack->size()))
|
||||
{
|
||||
ERR_CONTEXT(ret_missing_operand);
|
||||
return;
|
||||
}
|
||||
_stack->copy_obj_to_local(to_pick - 1, 0);
|
||||
_stack->push_obj_from_local(0);
|
||||
}
|
||||
|
||||
void rot(void)
|
||||
{
|
||||
MIN_ARGUMENTS(3);
|
||||
_stack->copy_obj_to_local(0, 0);
|
||||
_stack->copy_obj_to_local(1, 1);
|
||||
_stack->copy_obj_to_local(2, 2);
|
||||
_stack->pop_back();
|
||||
_stack->pop_back();
|
||||
_stack->pop_back();
|
||||
_stack->push_obj_from_local(1);
|
||||
_stack->push_obj_from_local(0);
|
||||
_stack->push_obj_from_local(2);
|
||||
MIN_ARGUMENTS(3);
|
||||
_stack->copy_obj_to_local(0, 0);
|
||||
_stack->copy_obj_to_local(1, 1);
|
||||
_stack->copy_obj_to_local(2, 2);
|
||||
_stack->pop_back();
|
||||
_stack->pop_back();
|
||||
_stack->pop_back();
|
||||
_stack->push_obj_from_local(1);
|
||||
_stack->push_obj_from_local(0);
|
||||
_stack->push_obj_from_local(2);
|
||||
}
|
||||
|
||||
void depth(void)
|
||||
|
|
|
@ -1,36 +1,36 @@
|
|||
//
|
||||
void sto(void)
|
||||
{
|
||||
MIN_ARGUMENTS(2);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_symbol);
|
||||
MIN_ARGUMENTS(2);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_symbol);
|
||||
|
||||
string name(((symbol*)_stack->get_obj(0))->_value);
|
||||
_stack->pop_back();
|
||||
_global_heap->add(name, _stack->get_obj(0), _stack->get_len(0), _stack->get_type(0));
|
||||
_stack->pop_back();
|
||||
_stack->pop_back();
|
||||
}
|
||||
|
||||
void rcl(void)
|
||||
{
|
||||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_symbol);
|
||||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_symbol);
|
||||
|
||||
// recall a variable
|
||||
void* obj;
|
||||
unsigned int size;
|
||||
int type;
|
||||
// recall a variable
|
||||
void* obj;
|
||||
unsigned int size;
|
||||
int type;
|
||||
string variable(((symbol*)_stack->back())->_value);
|
||||
|
||||
// mind the order of heaps
|
||||
if (_local_heap.get(variable, obj, size, type)
|
||||
|| ((_parent_local_heap != NULL) && (_parent_local_heap->get(variable, obj, size, type)))
|
||||
|| _global_heap->get(variable, obj, size, type))
|
||||
{
|
||||
_stack->pop_back();
|
||||
_stack->push_back(obj, size, type);
|
||||
}
|
||||
else
|
||||
ERR_CONTEXT(ret_unknown_variable);
|
||||
{
|
||||
_stack->pop_back();
|
||||
_stack->push_back(obj, size, type);
|
||||
}
|
||||
else
|
||||
ERR_CONTEXT(ret_unknown_variable);
|
||||
}
|
||||
|
||||
void edit(void)
|
||||
|
@ -70,11 +70,11 @@ void edit(void)
|
|||
// carefull : this is not a langage command
|
||||
void auto_rcl(symbol* symb)
|
||||
{
|
||||
if (symb->_auto_eval)
|
||||
{
|
||||
void* obj;
|
||||
unsigned int size;
|
||||
int type;
|
||||
if (symb->_auto_eval)
|
||||
{
|
||||
void* obj;
|
||||
unsigned int size;
|
||||
int type;
|
||||
string variable(symb->_value);
|
||||
|
||||
// mind the order of heaps
|
||||
|
@ -88,17 +88,17 @@ void auto_rcl(symbol* symb)
|
|||
eval();
|
||||
}
|
||||
}
|
||||
else
|
||||
else
|
||||
_stack->push_back(symb, symb->size(), cmd_symbol);
|
||||
}
|
||||
else
|
||||
}
|
||||
else
|
||||
_stack->push_back(symb, symb->size(), cmd_symbol);
|
||||
}
|
||||
|
||||
void purge(void)
|
||||
{
|
||||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_symbol);
|
||||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_symbol);
|
||||
|
||||
string name(((symbol*)_stack->back())->_value);
|
||||
|
||||
|
@ -121,10 +121,10 @@ void purge(void)
|
|||
|
||||
void vars(void)
|
||||
{
|
||||
object* obj;
|
||||
unsigned int size;
|
||||
int type;
|
||||
string name;
|
||||
object* obj;
|
||||
unsigned int size;
|
||||
int type;
|
||||
string name;
|
||||
|
||||
for (int i=0; i<(int)_global_heap->size(); i++)
|
||||
{
|
||||
|
|
|
@ -1,34 +1,34 @@
|
|||
void instr()
|
||||
{
|
||||
MIN_ARGUMENTS(1);
|
||||
MIN_ARGUMENTS(1);
|
||||
|
||||
// stringify only if not already a string
|
||||
if (_stack->get_type(0) != cmd_string)
|
||||
{
|
||||
stringstream out;
|
||||
((object*)_stack->back())->show(out);
|
||||
_stack->pop_back();
|
||||
// stringify only if not already a string
|
||||
if (_stack->get_type(0) != cmd_string)
|
||||
{
|
||||
stringstream out;
|
||||
((object*)_stack->back())->show(out);
|
||||
_stack->pop_back();
|
||||
|
||||
ostring str;
|
||||
str.set(out.str().c_str(), out.str().size());
|
||||
_stack->push_back(&str, str.size(), cmd_string);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void strout()
|
||||
{
|
||||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_string);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_string);
|
||||
|
||||
string entry(((ostring*)_stack->back())->_value);
|
||||
_stack->pop_back();
|
||||
_stack->pop_back();
|
||||
|
||||
program prog;
|
||||
program prog;
|
||||
|
||||
// make program from string in stack level 1
|
||||
// make program from string in stack level 1
|
||||
if (program::parse(entry.c_str(), prog) == ret_ok)
|
||||
{
|
||||
// run it
|
||||
{
|
||||
// run it
|
||||
prog.run(*_stack, *_global_heap, &_local_heap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,137 +1,137 @@
|
|||
void program::test()
|
||||
{
|
||||
const string test_filename = "test.txt";
|
||||
const string stack_size("-> stack size should be ");
|
||||
const string stack_value("-> stack should be ");
|
||||
const string cmd_error("-> error should be ");
|
||||
const string cmd_exit("exit test");
|
||||
ifstream test_file(test_filename.c_str());
|
||||
const string test_filename = "test.txt";
|
||||
const string stack_size("-> stack size should be ");
|
||||
const string stack_value("-> stack should be ");
|
||||
const string cmd_error("-> error should be ");
|
||||
const string cmd_exit("exit test");
|
||||
ifstream test_file(test_filename.c_str());
|
||||
|
||||
if (test_file.is_open())
|
||||
{
|
||||
string test_title;
|
||||
string entry;
|
||||
ret_value ret;
|
||||
stack stk;
|
||||
heap hp;
|
||||
bool indicate_passed = false;
|
||||
bool failed = false;
|
||||
int count_tests = 0;
|
||||
int last_err;
|
||||
stringstream cerr_buffer;
|
||||
streambuf* cerr_old_buffer;
|
||||
if (test_file.is_open())
|
||||
{
|
||||
string test_title;
|
||||
string entry;
|
||||
ret_value ret;
|
||||
stack stk;
|
||||
heap hp;
|
||||
bool indicate_passed = false;
|
||||
bool failed = false;
|
||||
int count_tests = 0;
|
||||
int last_err;
|
||||
stringstream cerr_buffer;
|
||||
streambuf* cerr_old_buffer;
|
||||
|
||||
// redirect cerr
|
||||
cerr_old_buffer = cerr.rdbuf(cerr_buffer.rdbuf());
|
||||
// redirect cerr
|
||||
cerr_old_buffer = cerr.rdbuf(cerr_buffer.rdbuf());
|
||||
|
||||
while ((!failed) && (!test_file.eof()))
|
||||
{
|
||||
getline(test_file, entry);
|
||||
if (entry.substr(0,2)=="##")
|
||||
{
|
||||
// read a test section
|
||||
if (indicate_passed)
|
||||
{
|
||||
if (g_verbose > 0)
|
||||
cout << "\t";
|
||||
cout << "passed " << count_tests << " tests"<< endl;
|
||||
}
|
||||
cout << entry;
|
||||
if (g_verbose == 0)
|
||||
cout << " .. ";
|
||||
else
|
||||
cout << endl;
|
||||
indicate_passed = true;
|
||||
count_tests = 0;
|
||||
}
|
||||
else if (entry.substr(0,1)=="#")
|
||||
{
|
||||
// read a test title
|
||||
test_title = entry;
|
||||
if (g_verbose > 0)
|
||||
cout << "\t" << test_title << endl;
|
||||
count_tests++;
|
||||
}
|
||||
else if (entry.find(stack_size, 0) == 0)
|
||||
{
|
||||
// check current stack size
|
||||
istringstream isub;
|
||||
int size;
|
||||
while ((!failed) && (!test_file.eof()))
|
||||
{
|
||||
getline(test_file, entry);
|
||||
if (entry.substr(0,2)=="##")
|
||||
{
|
||||
// read a test section
|
||||
if (indicate_passed)
|
||||
{
|
||||
if (g_verbose > 0)
|
||||
cout << "\t";
|
||||
cout << "passed " << count_tests << " tests"<< endl;
|
||||
}
|
||||
cout << entry;
|
||||
if (g_verbose == 0)
|
||||
cout << " .. ";
|
||||
else
|
||||
cout << endl;
|
||||
indicate_passed = true;
|
||||
count_tests = 0;
|
||||
}
|
||||
else if (entry.substr(0,1)=="#")
|
||||
{
|
||||
// read a test title
|
||||
test_title = entry;
|
||||
if (g_verbose > 0)
|
||||
cout << "\t" << test_title << endl;
|
||||
count_tests++;
|
||||
}
|
||||
else if (entry.find(stack_size, 0) == 0)
|
||||
{
|
||||
// check current stack size
|
||||
istringstream isub;
|
||||
int size;
|
||||
|
||||
isub.str(entry.substr(stack_size.size()));
|
||||
isub>>size;
|
||||
if (size != (int)stk.size())
|
||||
{
|
||||
cout<<endl<<endl<<test_title<<endl<<entry<<endl<<"FAIL, ";
|
||||
cout<<"stack size is "<<stk.size()<<endl;
|
||||
failed = true;
|
||||
indicate_passed = false;
|
||||
}
|
||||
}
|
||||
else if (entry.find(stack_value, 0) == 0)
|
||||
{
|
||||
// check current stack value
|
||||
string stack_should_be = entry.substr(stack_value.size());
|
||||
string stack_is;
|
||||
string tmp;
|
||||
for (int i = (int)stk.size() - 1; i >= 0; i--)
|
||||
{
|
||||
stringstream os;
|
||||
if (i < (int)(stk.size() - 1))
|
||||
stack_is += ", ";
|
||||
((object*)stk.seq_obj(i))->show(os);
|
||||
getline(os, tmp);
|
||||
stack_is += tmp;
|
||||
}
|
||||
if (stack_is != stack_should_be)
|
||||
{
|
||||
cout<<endl<<endl<<test_title<<endl<<entry<<endl<<"FAIL, ";
|
||||
cout<<"real stack is '"<<stack_is<<endl;
|
||||
failed = true;
|
||||
indicate_passed = false;
|
||||
}
|
||||
}
|
||||
else if (entry.find(cmd_error, 0) == 0)
|
||||
{
|
||||
// check current error
|
||||
istringstream isub;
|
||||
int err_should_be;
|
||||
isub.str(entry.substr(cmd_error.size()));
|
||||
isub>>err_should_be;
|
||||
if (err_should_be != last_err)
|
||||
{
|
||||
cout<<endl<<endl<<test_title<<endl<<entry<<endl<<"FAIL, ";
|
||||
cout<<"last error is "<<last_err<<endl;
|
||||
failed = true;
|
||||
indicate_passed = false;
|
||||
}
|
||||
}
|
||||
else if (entry.find(cmd_exit, 0) == 0)
|
||||
{
|
||||
// forced test end
|
||||
break;
|
||||
}
|
||||
else if (entry.size() > 0)
|
||||
{
|
||||
// parse entry and run line
|
||||
program prog;
|
||||
isub.str(entry.substr(stack_size.size()));
|
||||
isub>>size;
|
||||
if (size != (int)stk.size())
|
||||
{
|
||||
cout<<endl<<endl<<test_title<<endl<<entry<<endl<<"FAIL, ";
|
||||
cout<<"stack size is "<<stk.size()<<endl;
|
||||
failed = true;
|
||||
indicate_passed = false;
|
||||
}
|
||||
}
|
||||
else if (entry.find(stack_value, 0) == 0)
|
||||
{
|
||||
// check current stack value
|
||||
string stack_should_be = entry.substr(stack_value.size());
|
||||
string stack_is;
|
||||
string tmp;
|
||||
for (int i = (int)stk.size() - 1; i >= 0; i--)
|
||||
{
|
||||
stringstream os;
|
||||
if (i < (int)(stk.size() - 1))
|
||||
stack_is += ", ";
|
||||
((object*)stk.seq_obj(i))->show(os);
|
||||
getline(os, tmp);
|
||||
stack_is += tmp;
|
||||
}
|
||||
if (stack_is != stack_should_be)
|
||||
{
|
||||
cout<<endl<<endl<<test_title<<endl<<entry<<endl<<"FAIL, ";
|
||||
cout<<"real stack is '"<<stack_is<<endl;
|
||||
failed = true;
|
||||
indicate_passed = false;
|
||||
}
|
||||
}
|
||||
else if (entry.find(cmd_error, 0) == 0)
|
||||
{
|
||||
// check current error
|
||||
istringstream isub;
|
||||
int err_should_be;
|
||||
isub.str(entry.substr(cmd_error.size()));
|
||||
isub>>err_should_be;
|
||||
if (err_should_be != last_err)
|
||||
{
|
||||
cout<<endl<<endl<<test_title<<endl<<entry<<endl<<"FAIL, ";
|
||||
cout<<"last error is "<<last_err<<endl;
|
||||
failed = true;
|
||||
indicate_passed = false;
|
||||
}
|
||||
}
|
||||
else if (entry.find(cmd_exit, 0) == 0)
|
||||
{
|
||||
// forced test end
|
||||
break;
|
||||
}
|
||||
else if (entry.size() > 0)
|
||||
{
|
||||
// parse entry and run line
|
||||
program prog;
|
||||
ret = program::parse(entry.c_str(), prog);
|
||||
if (ret == ret_ok)
|
||||
{
|
||||
// run it
|
||||
(void)prog.run(stk, hp);
|
||||
last_err = (int)prog.get_err();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (indicate_passed)
|
||||
cout << "passed " << count_tests << " tests"<< endl;
|
||||
if (! failed)
|
||||
cout << "test file '"<<test_filename<<"' has passed" << endl;
|
||||
if (ret == ret_ok)
|
||||
{
|
||||
// run it
|
||||
(void)prog.run(stk, hp);
|
||||
last_err = (int)prog.get_err();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (indicate_passed)
|
||||
cout << "passed " << count_tests << " tests"<< endl;
|
||||
if (! failed)
|
||||
cout << "test file '"<<test_filename<<"' has passed" << endl;
|
||||
|
||||
// cerr back
|
||||
cerr.rdbuf(cerr_old_buffer);
|
||||
}
|
||||
else
|
||||
cerr << "test file '"<<test_filename<<"' not found" << endl;
|
||||
// cerr back
|
||||
cerr.rdbuf(cerr_old_buffer);
|
||||
}
|
||||
else
|
||||
cerr << "test file '"<<test_filename<<"' not found" << endl;
|
||||
}
|
||||
|
|
158
src/rpn-test.h
158
src/rpn-test.h
|
@ -1,135 +1,135 @@
|
|||
void sup(void)
|
||||
{
|
||||
MIN_ARGUMENTS(2);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
ARG_MUST_BE_OF_TYPE(1, cmd_number);
|
||||
MIN_ARGUMENTS(2);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
ARG_MUST_BE_OF_TYPE(1, cmd_number);
|
||||
|
||||
floating_t first = getf();
|
||||
putf(getf() > first);
|
||||
floating_t first = getf();
|
||||
putf(getf() > first);
|
||||
}
|
||||
|
||||
void sup_eq(void)
|
||||
{
|
||||
MIN_ARGUMENTS(2);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
ARG_MUST_BE_OF_TYPE(1, cmd_number);
|
||||
MIN_ARGUMENTS(2);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
ARG_MUST_BE_OF_TYPE(1, cmd_number);
|
||||
|
||||
floating_t first = getf();
|
||||
putf(getf() >= first);
|
||||
floating_t first = getf();
|
||||
putf(getf() >= first);
|
||||
}
|
||||
|
||||
void inf(void)
|
||||
{
|
||||
MIN_ARGUMENTS(2);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
ARG_MUST_BE_OF_TYPE(1, cmd_number);
|
||||
MIN_ARGUMENTS(2);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
ARG_MUST_BE_OF_TYPE(1, cmd_number);
|
||||
|
||||
floating_t first = getf();
|
||||
putf(getf() < first);
|
||||
floating_t first = getf();
|
||||
putf(getf() < first);
|
||||
}
|
||||
|
||||
void inf_eq(void)
|
||||
{
|
||||
MIN_ARGUMENTS(2);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
ARG_MUST_BE_OF_TYPE(1, cmd_number);
|
||||
MIN_ARGUMENTS(2);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
ARG_MUST_BE_OF_TYPE(1, cmd_number);
|
||||
|
||||
floating_t first = getf();
|
||||
putf(getf() <= first);
|
||||
floating_t first = getf();
|
||||
putf(getf() <= first);
|
||||
}
|
||||
|
||||
void diff(void)
|
||||
{
|
||||
MIN_ARGUMENTS(2);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
ARG_MUST_BE_OF_TYPE(1, cmd_number);
|
||||
MIN_ARGUMENTS(2);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
ARG_MUST_BE_OF_TYPE(1, cmd_number);
|
||||
|
||||
floating_t first = getf();
|
||||
putf(getf() != first);
|
||||
floating_t first = getf();
|
||||
putf(getf() != first);
|
||||
}
|
||||
|
||||
void eq(void)
|
||||
{
|
||||
MIN_ARGUMENTS(2);
|
||||
int type = _stack->get_type(0);
|
||||
MIN_ARGUMENTS(2);
|
||||
int type = _stack->get_type(0);
|
||||
|
||||
if (_stack->get_type(1) == type)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case cmd_number:
|
||||
{
|
||||
floating_t first = getf();
|
||||
putf(getf() == first);
|
||||
}
|
||||
break;
|
||||
if (_stack->get_type(1) == type)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case cmd_number:
|
||||
{
|
||||
floating_t first = getf();
|
||||
putf(getf() == first);
|
||||
}
|
||||
break;
|
||||
//TODO
|
||||
#if 0
|
||||
case cmd_symbol:
|
||||
{
|
||||
string first = getn();
|
||||
putf(getn() == first);
|
||||
}
|
||||
case cmd_symbol:
|
||||
{
|
||||
string first = getn();
|
||||
putf(getn() == first);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
_stack->pop_back();
|
||||
_stack->pop_back();
|
||||
putf(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_stack->pop_back();
|
||||
_stack->pop_back();
|
||||
putf(0);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
_stack->pop_back();
|
||||
_stack->pop_back();
|
||||
putf(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_stack->pop_back();
|
||||
_stack->pop_back();
|
||||
putf(0);
|
||||
}
|
||||
}
|
||||
|
||||
void test_and(void)
|
||||
{
|
||||
MIN_ARGUMENTS(2);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
ARG_MUST_BE_OF_TYPE(1, cmd_number);
|
||||
MIN_ARGUMENTS(2);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
ARG_MUST_BE_OF_TYPE(1, cmd_number);
|
||||
|
||||
floating_t first = getf();
|
||||
floating_t second = getf();
|
||||
putf((first != 0) && (second != 0));
|
||||
floating_t first = getf();
|
||||
floating_t second = getf();
|
||||
putf((first != 0) && (second != 0));
|
||||
}
|
||||
|
||||
void test_or(void)
|
||||
{
|
||||
MIN_ARGUMENTS(2);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
ARG_MUST_BE_OF_TYPE(1, cmd_number);
|
||||
MIN_ARGUMENTS(2);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
ARG_MUST_BE_OF_TYPE(1, cmd_number);
|
||||
|
||||
floating_t first = getf();
|
||||
floating_t second = getf();
|
||||
putf((first != 0) || (second != 0));
|
||||
floating_t first = getf();
|
||||
floating_t second = getf();
|
||||
putf((first != 0) || (second != 0));
|
||||
}
|
||||
|
||||
void test_xor(void)
|
||||
{
|
||||
MIN_ARGUMENTS(2);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
ARG_MUST_BE_OF_TYPE(1, cmd_number);
|
||||
MIN_ARGUMENTS(2);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
ARG_MUST_BE_OF_TYPE(1, cmd_number);
|
||||
|
||||
floating_t first = getf();
|
||||
floating_t second = getf();
|
||||
putf(((first == 0) && (second != 0)) || ((first != 0) && (second == 0)));
|
||||
floating_t first = getf();
|
||||
floating_t second = getf();
|
||||
putf(((first == 0) && (second != 0)) || ((first != 0) && (second == 0)));
|
||||
}
|
||||
|
||||
void test_not(void)
|
||||
{
|
||||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
|
||||
floating_t first = getf();
|
||||
putf((first == 0) ? 1 : 0);
|
||||
floating_t first = getf();
|
||||
putf((first == 0) ? 1 : 0);
|
||||
}
|
||||
|
||||
void same(void)
|
||||
{
|
||||
eq();
|
||||
eq();
|
||||
}
|
||||
|
|
|
@ -3,61 +3,61 @@
|
|||
//
|
||||
void pi(void)
|
||||
{
|
||||
putf(M_PI);
|
||||
putf(M_PI);
|
||||
}
|
||||
|
||||
void d2r(void)
|
||||
{
|
||||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
((number*)_stack->get_obj(0))->_value *= M_PI / 360;
|
||||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
((number*)_stack->get_obj(0))->_value *= M_PI / 360;
|
||||
}
|
||||
|
||||
void r2d(void)
|
||||
{
|
||||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
((number*)_stack->get_obj(0))->_value *= 360 / M_PI;
|
||||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
((number*)_stack->get_obj(0))->_value *= 360 / M_PI;
|
||||
}
|
||||
|
||||
void rpn_sin(void)
|
||||
{
|
||||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
((number*)_stack->get_obj(0))->_value = sin(((number*)_stack->get_obj(0))->_value);
|
||||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
((number*)_stack->get_obj(0))->_value = sin(((number*)_stack->get_obj(0))->_value);
|
||||
}
|
||||
|
||||
void rpn_asin(void)
|
||||
{
|
||||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
((number*)_stack->get_obj(0))->_value = asin(((number*)_stack->get_obj(0))->_value);
|
||||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
((number*)_stack->get_obj(0))->_value = asin(((number*)_stack->get_obj(0))->_value);
|
||||
}
|
||||
|
||||
void rpn_cos(void)
|
||||
{
|
||||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
((number*)_stack->get_obj(0))->_value = cos(((number*)_stack->get_obj(0))->_value);
|
||||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
((number*)_stack->get_obj(0))->_value = cos(((number*)_stack->get_obj(0))->_value);
|
||||
}
|
||||
|
||||
void rpn_acos(void)
|
||||
{
|
||||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
((number*)_stack->get_obj(0))->_value = acos(((number*)_stack->get_obj(0))->_value);
|
||||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
((number*)_stack->get_obj(0))->_value = acos(((number*)_stack->get_obj(0))->_value);
|
||||
}
|
||||
|
||||
void rpn_tan(void)
|
||||
{
|
||||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
((number*)_stack->get_obj(0))->_value = tan(((number*)_stack->get_obj(0))->_value);
|
||||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
((number*)_stack->get_obj(0))->_value = tan(((number*)_stack->get_obj(0))->_value);
|
||||
}
|
||||
|
||||
void rpn_atan(void)
|
||||
{
|
||||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
((number*)_stack->get_obj(0))->_value = atan(((number*)_stack->get_obj(0))->_value);
|
||||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
((number*)_stack->get_obj(0))->_value = atan(((number*)_stack->get_obj(0))->_value);
|
||||
}
|
||||
|
|
798
src/rpn.cpp
798
src/rpn.cpp
|
@ -45,36 +45,36 @@ static int g_verbose = 0;
|
|||
#include "version.h"
|
||||
|
||||
typedef enum {
|
||||
ret_ok,
|
||||
ret_unknown_err,
|
||||
ret_missing_operand,
|
||||
ret_bad_operand_type,
|
||||
ret_unknown_variable,
|
||||
ret_internal,
|
||||
ret_deadly,
|
||||
ret_good_bye,
|
||||
ret_not_impl,
|
||||
ret_nop,
|
||||
ret_syntax,
|
||||
ret_div_by_zero,
|
||||
ret_max
|
||||
ret_ok,
|
||||
ret_unknown_err,
|
||||
ret_missing_operand,
|
||||
ret_bad_operand_type,
|
||||
ret_unknown_variable,
|
||||
ret_internal,
|
||||
ret_deadly,
|
||||
ret_good_bye,
|
||||
ret_not_impl,
|
||||
ret_nop,
|
||||
ret_syntax,
|
||||
ret_div_by_zero,
|
||||
ret_max
|
||||
} ret_value;
|
||||
|
||||
const char* ret_value_string[ret_max] = {
|
||||
"ok", "unknown command", "missing operand", "bad operand type", "unknown variable", "internal error, aborting",
|
||||
"deadly", "goodbye", "not implemented", "no operation", "syntax", "division by zero"
|
||||
"ok", "unknown command", "missing operand", "bad operand type", "unknown variable", "internal error, aborting",
|
||||
"deadly", "goodbye", "not implemented", "no operation", "syntax", "division by zero"
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
cmd_undef,
|
||||
cmd_number,/* floating value to put in stack */
|
||||
cmd_binary,/* binary (integer) value to put in stack */
|
||||
cmd_string,/* string value to put in stack */
|
||||
cmd_symbol,/* symbol value to put in stack */
|
||||
cmd_program,/* program */
|
||||
cmd_keyword,/* langage keyword */
|
||||
cmd_branch,/* langage branch keyword */
|
||||
cmd_max
|
||||
cmd_undef,
|
||||
cmd_number,/* floating value to put in stack */
|
||||
cmd_binary,/* binary (integer) value to put in stack */
|
||||
cmd_string,/* string value to put in stack */
|
||||
cmd_symbol,/* symbol value to put in stack */
|
||||
cmd_program,/* program */
|
||||
cmd_keyword,/* langage keyword */
|
||||
cmd_branch,/* langage branch keyword */
|
||||
cmd_max
|
||||
} cmd_type_t;
|
||||
|
||||
const char* cmd_type_string[cmd_max] = {
|
||||
|
@ -90,7 +90,7 @@ class branch;
|
|||
typedef void (program::*program_fn_t)(void);
|
||||
typedef union
|
||||
{
|
||||
program_fn_t _fn;
|
||||
program_fn_t _fn;
|
||||
} operand;
|
||||
typedef int (program::*branch_fn_t)(branch&);
|
||||
|
||||
|
@ -106,7 +106,7 @@ struct object
|
|||
|
||||
struct number : public object
|
||||
{
|
||||
floating_t _value;
|
||||
floating_t _value;
|
||||
|
||||
//
|
||||
void set(floating_t value)
|
||||
|
@ -117,17 +117,17 @@ struct number : public object
|
|||
unsigned int size() { return sizeof(number); }
|
||||
|
||||
// representation mode
|
||||
typedef enum {
|
||||
std,
|
||||
fix,
|
||||
sci
|
||||
} mode_enum;
|
||||
static mode_enum s_default_mode;
|
||||
static mode_enum s_mode;
|
||||
|
||||
// precision
|
||||
static int s_default_precision;
|
||||
static int s_current_precision;
|
||||
typedef enum {
|
||||
std,
|
||||
fix,
|
||||
sci
|
||||
} mode_enum;
|
||||
static mode_enum s_default_mode;
|
||||
static mode_enum s_mode;
|
||||
|
||||
// precision
|
||||
static int s_default_precision;
|
||||
static int s_current_precision;
|
||||
} __attribute__((packed));
|
||||
number::mode_enum number::s_default_mode = number::std;
|
||||
number::mode_enum number::s_mode = number::s_default_mode;
|
||||
|
@ -136,8 +136,8 @@ int number::s_current_precision = number::s_default_precision;
|
|||
|
||||
struct binary : public object
|
||||
{
|
||||
integer_t _value;
|
||||
|
||||
integer_t _value;
|
||||
|
||||
//
|
||||
void set(integer_t value)
|
||||
{
|
||||
|
@ -146,15 +146,15 @@ struct binary : public object
|
|||
}
|
||||
unsigned int size() { return sizeof(binary); }
|
||||
|
||||
// representation mode
|
||||
typedef enum {
|
||||
dec,
|
||||
hex,
|
||||
oct,
|
||||
bin,
|
||||
} binary_enum;
|
||||
static binary_enum s_default_mode;
|
||||
static binary_enum s_mode;
|
||||
// representation mode
|
||||
typedef enum {
|
||||
dec,
|
||||
hex,
|
||||
oct,
|
||||
bin,
|
||||
} binary_enum;
|
||||
static binary_enum s_default_mode;
|
||||
static binary_enum s_mode;
|
||||
} __attribute__((packed));
|
||||
binary::binary_enum binary::s_default_mode = binary::dec;
|
||||
binary::binary_enum binary::s_mode = binary::s_default_mode;
|
||||
|
@ -352,14 +352,14 @@ struct if_layout_t
|
|||
class program : public stack
|
||||
{
|
||||
public:
|
||||
program() { }
|
||||
program() { }
|
||||
|
||||
// run this program
|
||||
// run this program
|
||||
ret_value run(stack& stk, heap& hp, heap* parent_local_hp = NULL)
|
||||
{
|
||||
{
|
||||
bool go_out = false;
|
||||
ret_value ret = ret_ok;
|
||||
cmd_type_t type;
|
||||
ret_value ret = ret_ok;
|
||||
cmd_type_t type;
|
||||
|
||||
// stack comes from outside
|
||||
_stack = &stk;
|
||||
|
@ -373,83 +373,83 @@ public:
|
|||
_err = ret_ok;
|
||||
_err_context = "";
|
||||
|
||||
// branches for 'if'
|
||||
ret = preprocess();
|
||||
if (ret != ret_ok)
|
||||
return ret;
|
||||
// branches for 'if'
|
||||
ret = preprocess();
|
||||
if (ret != ret_ok)
|
||||
return ret;
|
||||
|
||||
// iterate commands
|
||||
for(int i = 0; (go_out==false) && (i<(int)size());)
|
||||
{
|
||||
type = (cmd_type_t)seq_type(i);
|
||||
// iterate commands
|
||||
for(int i = 0; (go_out==false) && (i<(int)size());)
|
||||
{
|
||||
type = (cmd_type_t)seq_type(i);
|
||||
|
||||
//
|
||||
if (g_verbose >= 2)
|
||||
{
|
||||
cout << "(" << i << ") ";
|
||||
((object*)seq_obj(i))->show();
|
||||
cout << endl;
|
||||
}
|
||||
//
|
||||
if (g_verbose >= 2)
|
||||
{
|
||||
cout << "(" << i << ") ";
|
||||
((object*)seq_obj(i))->show();
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
// could be an auto-evaluated symbol
|
||||
// could be an auto-evaluated symbol
|
||||
if (type == cmd_symbol)
|
||||
{
|
||||
{
|
||||
auto_rcl((symbol*)seq_obj(i));
|
||||
i++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
// a keyword
|
||||
else if (type == cmd_keyword)
|
||||
{
|
||||
keyword* k = (keyword*)seq_obj(i);
|
||||
// call matching function
|
||||
(this->*(k->_fn))();
|
||||
switch(_err)
|
||||
{
|
||||
// no pb -> go on
|
||||
case ret_ok:
|
||||
break;
|
||||
// explicit go out software
|
||||
case ret_good_bye:
|
||||
go_out = true;
|
||||
ret = ret_good_bye;
|
||||
break;
|
||||
default:
|
||||
// error: abort prog
|
||||
go_out = true;
|
||||
// a keyword
|
||||
else if (type == cmd_keyword)
|
||||
{
|
||||
keyword* k = (keyword*)seq_obj(i);
|
||||
// call matching function
|
||||
(this->*(k->_fn))();
|
||||
switch(_err)
|
||||
{
|
||||
// no pb -> go on
|
||||
case ret_ok:
|
||||
break;
|
||||
// explicit go out software
|
||||
case ret_good_bye:
|
||||
go_out = true;
|
||||
ret = ret_good_bye;
|
||||
break;
|
||||
default:
|
||||
// error: abort prog
|
||||
go_out = true;
|
||||
|
||||
// error: show it
|
||||
// error: show it
|
||||
if (show_error(_err, _err_context) == ret_deadly)
|
||||
{
|
||||
// pb showing error -> go out software
|
||||
ret = ret_good_bye;
|
||||
}
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
{
|
||||
// pb showing error -> go out software
|
||||
ret = ret_good_bye;
|
||||
}
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
// a branch keyword
|
||||
else if (type == cmd_branch)
|
||||
{
|
||||
// call matching function
|
||||
branch* b = (branch*)seq_obj(i);
|
||||
int tmp = (this->*(b->_fn))(*b);
|
||||
if (tmp == -1)
|
||||
i++;
|
||||
else
|
||||
i = tmp;
|
||||
}
|
||||
// a branch keyword
|
||||
else if (type == cmd_branch)
|
||||
{
|
||||
// call matching function
|
||||
branch* b = (branch*)seq_obj(i);
|
||||
int tmp = (this->*(b->_fn))(*b);
|
||||
if (tmp == -1)
|
||||
i++;
|
||||
else
|
||||
i = tmp;
|
||||
}
|
||||
|
||||
// not a command, but a stack entry, manage it
|
||||
else
|
||||
{
|
||||
stk.push_back(seq_obj(i), seq_len(i), type);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
// not a command, but a stack entry, manage it
|
||||
else
|
||||
{
|
||||
stk.push_back(seq_obj(i), seq_len(i), type);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool compare_keyword(keyword* k, const char* str_to_compare, int len)
|
||||
{
|
||||
|
@ -468,226 +468,226 @@ public:
|
|||
}
|
||||
|
||||
ret_value preprocess(void)
|
||||
{
|
||||
// for if-then-else-end
|
||||
vector<struct if_layout_t> vlayout;
|
||||
{
|
||||
// for if-then-else-end
|
||||
vector<struct if_layout_t> vlayout;
|
||||
int layout_index=-1;// TODO remplacable par vlayout.size()-1
|
||||
// for start-end-step
|
||||
vector<int> vstartindex;
|
||||
vector<int> vstartindex;
|
||||
|
||||
// analyse if-then-else-end branches
|
||||
// analyse start-{next, step} branches
|
||||
for(int i=0; i<(int)size(); i++)
|
||||
{
|
||||
int type = seq_type(i);
|
||||
if (type == cmd_keyword)
|
||||
{
|
||||
keyword* k = (keyword*)seq_obj(i);
|
||||
// analyse if-then-else-end branches
|
||||
// analyse start-{next, step} branches
|
||||
for(int i=0; i<(int)size(); i++)
|
||||
{
|
||||
int type = seq_type(i);
|
||||
if (type == cmd_keyword)
|
||||
{
|
||||
keyword* k = (keyword*)seq_obj(i);
|
||||
if (compare_keyword(k, "end", 3))
|
||||
{
|
||||
{
|
||||
int next = i + 1;
|
||||
if (next >= (int)size())
|
||||
next = -1;
|
||||
if (next >= (int)size())
|
||||
next = -1;
|
||||
|
||||
if (layout_index<0)
|
||||
{
|
||||
// error: show it
|
||||
show_syntax_error("missing if before end");
|
||||
return ret_syntax;
|
||||
}
|
||||
if (vlayout[layout_index].index_end != -1)
|
||||
{
|
||||
// error: show it
|
||||
show_syntax_error("duplicate end");
|
||||
return ret_syntax;
|
||||
}
|
||||
if (vlayout[layout_index].index_else != -1)
|
||||
//fill 'end' branch of 'else'
|
||||
((branch*)seq_obj(vlayout[layout_index].index_else))->arg2 = i;
|
||||
else
|
||||
//fill 'end' branch of 'then'
|
||||
((branch*)seq_obj(vlayout[layout_index].index_then))->arg2 = i;
|
||||
layout_index--;
|
||||
}
|
||||
}
|
||||
else if (type == cmd_branch)
|
||||
{
|
||||
branch* k = (branch*)seq_obj(i);
|
||||
if (layout_index<0)
|
||||
{
|
||||
// error: show it
|
||||
show_syntax_error("missing if before end");
|
||||
return ret_syntax;
|
||||
}
|
||||
if (vlayout[layout_index].index_end != -1)
|
||||
{
|
||||
// error: show it
|
||||
show_syntax_error("duplicate end");
|
||||
return ret_syntax;
|
||||
}
|
||||
if (vlayout[layout_index].index_else != -1)
|
||||
//fill 'end' branch of 'else'
|
||||
((branch*)seq_obj(vlayout[layout_index].index_else))->arg2 = i;
|
||||
else
|
||||
//fill 'end' branch of 'then'
|
||||
((branch*)seq_obj(vlayout[layout_index].index_then))->arg2 = i;
|
||||
layout_index--;
|
||||
}
|
||||
}
|
||||
else if (type == cmd_branch)
|
||||
{
|
||||
branch* k = (branch*)seq_obj(i);
|
||||
if (compare_branch(k, "if", 2))
|
||||
{
|
||||
if_layout_t layout;
|
||||
{
|
||||
if_layout_t layout;
|
||||
layout.index_if = i;
|
||||
vlayout.push_back(layout);
|
||||
layout_index++;
|
||||
}
|
||||
vlayout.push_back(layout);
|
||||
layout_index++;
|
||||
}
|
||||
else if (compare_branch(k, "then", 4))
|
||||
{
|
||||
{
|
||||
int next = i + 1;
|
||||
if (next >= (int)size())
|
||||
next = -1;
|
||||
if (next >= (int)size())
|
||||
next = -1;
|
||||
|
||||
// nothing after 'then' -> error
|
||||
if (next == -1)
|
||||
{
|
||||
// error: show it
|
||||
show_syntax_error("missing end after then");
|
||||
return ret_syntax;
|
||||
}
|
||||
if (layout_index<0)
|
||||
{
|
||||
// error: show it
|
||||
show_syntax_error("missing if before then");
|
||||
return ret_syntax;
|
||||
}
|
||||
if (vlayout[layout_index].index_then != -1)
|
||||
{
|
||||
// error: show it
|
||||
show_syntax_error("duplicate then");
|
||||
return ret_syntax;
|
||||
}
|
||||
vlayout[layout_index].index_then = i;
|
||||
k->arg1 = next;
|
||||
k->arg3 = vlayout[layout_index].index_if;
|
||||
}
|
||||
// nothing after 'then' -> error
|
||||
if (next == -1)
|
||||
{
|
||||
// error: show it
|
||||
show_syntax_error("missing end after then");
|
||||
return ret_syntax;
|
||||
}
|
||||
if (layout_index<0)
|
||||
{
|
||||
// error: show it
|
||||
show_syntax_error("missing if before then");
|
||||
return ret_syntax;
|
||||
}
|
||||
if (vlayout[layout_index].index_then != -1)
|
||||
{
|
||||
// error: show it
|
||||
show_syntax_error("duplicate then");
|
||||
return ret_syntax;
|
||||
}
|
||||
vlayout[layout_index].index_then = i;
|
||||
k->arg1 = next;
|
||||
k->arg3 = vlayout[layout_index].index_if;
|
||||
}
|
||||
else if (compare_branch(k, "else", 4))
|
||||
{
|
||||
{
|
||||
int next = i + 1;
|
||||
if (next >= (int)size())
|
||||
next = -1;
|
||||
if (next >= (int)size())
|
||||
next = -1;
|
||||
|
||||
// nothing after 'else' -> error
|
||||
if (next == -1)
|
||||
{
|
||||
// error: show it
|
||||
show_syntax_error("missing end after else");
|
||||
return ret_syntax;
|
||||
}
|
||||
if (layout_index<0)
|
||||
{
|
||||
// error: show it
|
||||
show_syntax_error("missing if before else");
|
||||
return ret_syntax;
|
||||
}
|
||||
if (vlayout[layout_index].index_then == -1)
|
||||
{
|
||||
// error: show it
|
||||
show_syntax_error("missing then before else");
|
||||
return ret_syntax;
|
||||
}
|
||||
if (vlayout[layout_index].index_else != -1)
|
||||
{
|
||||
// error: show it
|
||||
show_syntax_error("duplicate else");
|
||||
return ret_syntax;
|
||||
}
|
||||
vlayout[layout_index].index_else = i;
|
||||
k->arg1 = next;// fill branch1 (if was false) of 'else'
|
||||
k->arg3 = vlayout[layout_index].index_if;
|
||||
((branch*)seq_obj(vlayout[layout_index].index_then))->arg2 = next;// fill branch2 (if was false) of 'then'
|
||||
}
|
||||
// nothing after 'else' -> error
|
||||
if (next == -1)
|
||||
{
|
||||
// error: show it
|
||||
show_syntax_error("missing end after else");
|
||||
return ret_syntax;
|
||||
}
|
||||
if (layout_index<0)
|
||||
{
|
||||
// error: show it
|
||||
show_syntax_error("missing if before else");
|
||||
return ret_syntax;
|
||||
}
|
||||
if (vlayout[layout_index].index_then == -1)
|
||||
{
|
||||
// error: show it
|
||||
show_syntax_error("missing then before else");
|
||||
return ret_syntax;
|
||||
}
|
||||
if (vlayout[layout_index].index_else != -1)
|
||||
{
|
||||
// error: show it
|
||||
show_syntax_error("duplicate else");
|
||||
return ret_syntax;
|
||||
}
|
||||
vlayout[layout_index].index_else = i;
|
||||
k->arg1 = next;// fill branch1 (if was false) of 'else'
|
||||
k->arg3 = vlayout[layout_index].index_if;
|
||||
((branch*)seq_obj(vlayout[layout_index].index_then))->arg2 = next;// fill branch2 (if was false) of 'then'
|
||||
}
|
||||
else if (compare_branch(k, "start", 5))
|
||||
{
|
||||
vstartindex.push_back(i);
|
||||
}
|
||||
{
|
||||
vstartindex.push_back(i);
|
||||
}
|
||||
else if (compare_branch(k, "for", 3))
|
||||
{
|
||||
vstartindex.push_back(i);
|
||||
k->arg1 = i + 1;// arg1 points on symbol variable
|
||||
}
|
||||
{
|
||||
vstartindex.push_back(i);
|
||||
k->arg1 = i + 1;// arg1 points on symbol variable
|
||||
}
|
||||
else if(compare_branch(k, "next", 4))
|
||||
{
|
||||
if (vstartindex.size() == 0)
|
||||
{
|
||||
// error: show it
|
||||
show_syntax_error("missing start or for before next");
|
||||
return ret_syntax;
|
||||
}
|
||||
k->arg1 = vstartindex[vstartindex.size() - 1];// fill 'next' branch1 = 'start' index
|
||||
vstartindex.pop_back();
|
||||
}
|
||||
{
|
||||
if (vstartindex.size() == 0)
|
||||
{
|
||||
// error: show it
|
||||
show_syntax_error("missing start or for before next");
|
||||
return ret_syntax;
|
||||
}
|
||||
k->arg1 = vstartindex[vstartindex.size() - 1];// fill 'next' branch1 = 'start' index
|
||||
vstartindex.pop_back();
|
||||
}
|
||||
else if (compare_branch(k, "step", 4))
|
||||
{
|
||||
if (vstartindex.size() == 0)
|
||||
{
|
||||
// error: show it
|
||||
show_syntax_error("missing start or for before step");
|
||||
return ret_syntax;
|
||||
}
|
||||
k->arg1 = vstartindex[vstartindex.size() - 1];// fill 'step' branch1 = 'start' index
|
||||
vstartindex.pop_back();
|
||||
}
|
||||
{
|
||||
if (vstartindex.size() == 0)
|
||||
{
|
||||
// error: show it
|
||||
show_syntax_error("missing start or for before step");
|
||||
return ret_syntax;
|
||||
}
|
||||
k->arg1 = vstartindex[vstartindex.size() - 1];// fill 'step' branch1 = 'start' index
|
||||
vstartindex.pop_back();
|
||||
}
|
||||
else if (compare_branch(k, "->", 2))
|
||||
{
|
||||
k->arg1 = i;// arg1 is '->' command index in program
|
||||
}
|
||||
}
|
||||
}
|
||||
if (layout_index >= 0)
|
||||
{
|
||||
// error: show it
|
||||
show_syntax_error("missing end");
|
||||
return ret_syntax;
|
||||
}
|
||||
if (vstartindex.size() > 0)
|
||||
{
|
||||
// error: show it
|
||||
show_syntax_error("missing next or step after for or start");
|
||||
return ret_syntax;
|
||||
}
|
||||
return ret_ok;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (layout_index >= 0)
|
||||
{
|
||||
// error: show it
|
||||
show_syntax_error("missing end");
|
||||
return ret_syntax;
|
||||
}
|
||||
if (vstartindex.size() > 0)
|
||||
{
|
||||
// error: show it
|
||||
show_syntax_error("missing next or step after for or start");
|
||||
return ret_syntax;
|
||||
}
|
||||
return ret_ok;
|
||||
}
|
||||
|
||||
static ret_value show_error(ret_value err, string& context)
|
||||
{
|
||||
cerr<<context<<": "<<ret_value_string[err]<<endl;
|
||||
switch(err)
|
||||
{
|
||||
case ret_internal:
|
||||
case ret_deadly:
|
||||
return ret_deadly;
|
||||
default:
|
||||
return ret_ok;
|
||||
}
|
||||
}
|
||||
static ret_value show_error(ret_value err, string& context)
|
||||
{
|
||||
cerr<<context<<": "<<ret_value_string[err]<<endl;
|
||||
switch(err)
|
||||
{
|
||||
case ret_internal:
|
||||
case ret_deadly:
|
||||
return ret_deadly;
|
||||
default:
|
||||
return ret_ok;
|
||||
}
|
||||
}
|
||||
|
||||
static ret_value show_error(ret_value err, char* context)
|
||||
{
|
||||
string context_string(context);
|
||||
return show_error(err, context_string);
|
||||
}
|
||||
static ret_value show_error(ret_value err, char* context)
|
||||
{
|
||||
string context_string(context);
|
||||
return show_error(err, context_string);
|
||||
}
|
||||
|
||||
static void show_syntax_error(const char* context)
|
||||
{
|
||||
cerr<<"syntax error: "<<context<<endl;
|
||||
}
|
||||
static void show_syntax_error(const char* context)
|
||||
{
|
||||
cerr<<"syntax error: "<<context<<endl;
|
||||
}
|
||||
|
||||
ret_value get_err(void) { return _err; }
|
||||
ret_value get_err(void) { return _err; }
|
||||
|
||||
#include "parse.h"
|
||||
|
||||
static void show_stack(stack& st, const string& separator = g_show_stack_separator)
|
||||
{
|
||||
if (st.size() == 1)
|
||||
{
|
||||
((object*)st.back())->show();
|
||||
cout<<endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
bool show_sep = (! separator.empty());
|
||||
for (int i = st.size()-1; i>=0; i--)
|
||||
{
|
||||
if (show_sep)
|
||||
cout<<i+1<<separator;
|
||||
((object*)st[i])->show();
|
||||
cout<<endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
static void show_stack(stack& st, const string& separator = g_show_stack_separator)
|
||||
{
|
||||
if (st.size() == 1)
|
||||
{
|
||||
((object*)st.back())->show();
|
||||
cout<<endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
bool show_sep = (! separator.empty());
|
||||
for (int i = st.size()-1; i>=0; i--)
|
||||
{
|
||||
if (show_sep)
|
||||
cout<<i+1<<separator;
|
||||
((object*)st[i])->show();
|
||||
cout<<endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
ret_value _err;
|
||||
string _err_context;
|
||||
ret_value _err;
|
||||
string _err_context;
|
||||
|
||||
stack* _stack;
|
||||
|
||||
|
@ -695,65 +695,65 @@ private:
|
|||
heap _local_heap;
|
||||
heap* _parent_local_heap;
|
||||
|
||||
// helpers for keywords implementation
|
||||
floating_t getf()
|
||||
{
|
||||
/* warning, caller must check object type before */
|
||||
floating_t a = ((number*)_stack->back())->_value;
|
||||
_stack->pop_back();
|
||||
return a;
|
||||
}
|
||||
// helpers for keywords implementation
|
||||
floating_t getf()
|
||||
{
|
||||
/* warning, caller must check object type before */
|
||||
floating_t a = ((number*)_stack->back())->_value;
|
||||
_stack->pop_back();
|
||||
return a;
|
||||
}
|
||||
|
||||
void putf(floating_t value)
|
||||
{
|
||||
/* warning, caller must check object type before */
|
||||
void putf(floating_t value)
|
||||
{
|
||||
/* warning, caller must check object type before */
|
||||
number num;
|
||||
num.set(value);
|
||||
_stack->push_back(&num, num.size(), cmd_number);
|
||||
}
|
||||
}
|
||||
|
||||
integer_t getb()
|
||||
{
|
||||
/* warning, caller must check object type before */
|
||||
integer_t a = ((binary*)_stack->back())->_value;
|
||||
_stack->pop_back();
|
||||
return a;
|
||||
}
|
||||
integer_t getb()
|
||||
{
|
||||
/* warning, caller must check object type before */
|
||||
integer_t a = ((binary*)_stack->back())->_value;
|
||||
_stack->pop_back();
|
||||
return a;
|
||||
}
|
||||
|
||||
void putb(integer_t value)
|
||||
{
|
||||
/* warning, caller must check object type before */
|
||||
void putb(integer_t value)
|
||||
{
|
||||
/* warning, caller must check object type before */
|
||||
binary num;
|
||||
num.set(value);
|
||||
_stack->push_back(&num, num.size(), cmd_binary);
|
||||
}
|
||||
}
|
||||
|
||||
int stack_size()
|
||||
{
|
||||
return _stack->size();
|
||||
}
|
||||
{
|
||||
return _stack->size();
|
||||
}
|
||||
|
||||
private:
|
||||
// carefull : some of these macros modify program flow
|
||||
#define ERR_CONTEXT(err) do { _err = (err); _err_context = __FUNCTION__; } while(0)
|
||||
#define MIN_ARGUMENTS(num) do { if (stack_size()<(num)) { ERR_CONTEXT(ret_missing_operand); return; } } while(0)
|
||||
#define MIN_ARGUMENTS_RET(num, ret) do { if (stack_size()<(num)) { ERR_CONTEXT(ret_missing_operand); return (ret); } } while(0)
|
||||
#define ARG_MUST_BE_OF_TYPE(num, type) do { if (_stack->get_type(num) != (type)) { ERR_CONTEXT(ret_bad_operand_type); return; } } while(0)
|
||||
#define ARG_MUST_BE_OF_TYPE_RET(num, type, ret) do { if (_stack->get_type(num) != (type)) { ERR_CONTEXT(ret_bad_operand_type); return (ret); } } while(0)
|
||||
#define IS_ARG_TYPE(num, type) (_stack->get_type(num) == (type))
|
||||
// carefull : some of these macros modify program flow
|
||||
#define ERR_CONTEXT(err) do { _err = (err); _err_context = __FUNCTION__; } while(0)
|
||||
#define MIN_ARGUMENTS(num) do { if (stack_size()<(num)) { ERR_CONTEXT(ret_missing_operand); return; } } while(0)
|
||||
#define MIN_ARGUMENTS_RET(num, ret) do { if (stack_size()<(num)) { ERR_CONTEXT(ret_missing_operand); return (ret); } } while(0)
|
||||
#define ARG_MUST_BE_OF_TYPE(num, type) do { if (_stack->get_type(num) != (type)) { ERR_CONTEXT(ret_bad_operand_type); return; } } while(0)
|
||||
#define ARG_MUST_BE_OF_TYPE_RET(num, type, ret) do { if (_stack->get_type(num) != (type)) { ERR_CONTEXT(ret_bad_operand_type); return (ret); } } while(0)
|
||||
#define IS_ARG_TYPE(num, type) (_stack->get_type(num) == (type))
|
||||
|
||||
// keywords implementation
|
||||
#include "rpn-general.h"
|
||||
#include "rpn-algebra.h"
|
||||
#include "rpn-binary.h"
|
||||
#include "rpn-test.h"
|
||||
#include "rpn-stack.h"
|
||||
#include "rpn-string.h"
|
||||
#include "rpn-branch.h"
|
||||
#include "rpn-store.h"
|
||||
#include "rpn-program.h"
|
||||
#include "rpn-trig.h"
|
||||
#include "rpn-logs.h"
|
||||
// keywords implementation
|
||||
#include "rpn-general.h"
|
||||
#include "rpn-algebra.h"
|
||||
#include "rpn-binary.h"
|
||||
#include "rpn-test.h"
|
||||
#include "rpn-stack.h"
|
||||
#include "rpn-string.h"
|
||||
#include "rpn-branch.h"
|
||||
#include "rpn-store.h"
|
||||
#include "rpn-program.h"
|
||||
#include "rpn-trig.h"
|
||||
#include "rpn-logs.h"
|
||||
};
|
||||
|
||||
//keywords declaration
|
||||
|
@ -764,12 +764,12 @@ private:
|
|||
//
|
||||
static void apply_default(void)
|
||||
{
|
||||
//default precision
|
||||
cout << setprecision(number::s_default_precision);
|
||||
number::s_mode = number::s_default_mode;
|
||||
//default precision
|
||||
cout << setprecision(number::s_default_precision);
|
||||
number::s_mode = number::s_default_mode;
|
||||
|
||||
//default binary mode
|
||||
binary::s_mode = binary::s_default_mode;
|
||||
//default binary mode
|
||||
binary::s_mode = binary::s_default_mode;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -777,56 +777,56 @@ int main(int argc, char* argv[])
|
|||
{
|
||||
heap global_heap;
|
||||
stack global_stack;
|
||||
int ret = 0;
|
||||
int ret = 0;
|
||||
|
||||
// apply default configuration
|
||||
apply_default();
|
||||
// apply default configuration
|
||||
apply_default();
|
||||
|
||||
// run with interactive prompt
|
||||
if (argc == 1)
|
||||
{
|
||||
//
|
||||
for (;;)
|
||||
{
|
||||
// make program from interactive entry
|
||||
program prog;
|
||||
if (program::entry(prog) == ret_good_bye)
|
||||
break;
|
||||
else
|
||||
{
|
||||
// run it
|
||||
if (argc == 1)
|
||||
{
|
||||
//
|
||||
for (;;)
|
||||
{
|
||||
// make program from interactive entry
|
||||
program prog;
|
||||
if (program::entry(prog) == ret_good_bye)
|
||||
break;
|
||||
else
|
||||
{
|
||||
// run it
|
||||
if (prog.run(global_stack, global_heap) == ret_good_bye)
|
||||
break;
|
||||
else
|
||||
break;
|
||||
else
|
||||
program::show_stack(global_stack);
|
||||
}
|
||||
}
|
||||
}
|
||||
// run with cmd line arguments
|
||||
else
|
||||
{
|
||||
program prog;
|
||||
string entry;
|
||||
int i;
|
||||
}
|
||||
}
|
||||
}
|
||||
// run with cmd line arguments
|
||||
else
|
||||
{
|
||||
program prog;
|
||||
string entry;
|
||||
int i;
|
||||
|
||||
// make one string from entry
|
||||
for (i=1; i<argc; i++)
|
||||
{
|
||||
entry += argv[i];
|
||||
entry += ' ';
|
||||
}
|
||||
// make one string from entry
|
||||
for (i=1; i<argc; i++)
|
||||
{
|
||||
entry += argv[i];
|
||||
entry += ' ';
|
||||
}
|
||||
|
||||
// make program
|
||||
// make program
|
||||
ret = program::parse(entry.c_str(), prog);
|
||||
if (ret == ret_ok)
|
||||
{
|
||||
string separator = "";
|
||||
if (ret == ret_ok)
|
||||
{
|
||||
string separator = "";
|
||||
|
||||
// run it
|
||||
// run it
|
||||
ret = prog.run(global_stack, global_heap);
|
||||
program::show_stack(global_stack, separator);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
|
400
src/stack.h
400
src/stack.h
|
@ -18,136 +18,136 @@ using namespace std;
|
|||
class stack
|
||||
{
|
||||
private:
|
||||
struct local_copy
|
||||
{
|
||||
unsigned int length;
|
||||
int type;
|
||||
int blob;
|
||||
};
|
||||
struct local_copy
|
||||
{
|
||||
unsigned int length;
|
||||
int type;
|
||||
int blob;
|
||||
};
|
||||
|
||||
public:
|
||||
stack()
|
||||
{
|
||||
_base = (char*)malloc(ALLOC_BLOB);
|
||||
_total_size = ALLOC_BLOB;
|
||||
_current = _base;
|
||||
_count = 0;
|
||||
}
|
||||
virtual ~stack() { free(_base); }
|
||||
stack()
|
||||
{
|
||||
_base = (char*)malloc(ALLOC_BLOB);
|
||||
_total_size = ALLOC_BLOB;
|
||||
_current = _base;
|
||||
_count = 0;
|
||||
}
|
||||
virtual ~stack() { free(_base); }
|
||||
|
||||
void push_back(void* obj, unsigned int size, int type = 0)
|
||||
{
|
||||
if (_current + size > _base + _total_size)
|
||||
{
|
||||
void push_back(void* obj, unsigned int size, int type = 0)
|
||||
{
|
||||
if (_current + size > _base + _total_size)
|
||||
{
|
||||
//TODO gerer les pbs de memoire
|
||||
_total_size += ALLOC_BLOB;
|
||||
_base = (char*)realloc(_base, _total_size);
|
||||
}
|
||||
_total_size += ALLOC_BLOB;
|
||||
_base = (char*)realloc(_base, _total_size);
|
||||
}
|
||||
|
||||
memcpy(_current, obj, size);
|
||||
_vlen.push_back(size);
|
||||
_vpointer.push_back(_current);
|
||||
_vtype.push_back(type);
|
||||
_count++;
|
||||
_current += size;
|
||||
}
|
||||
memcpy(_current, obj, size);
|
||||
_vlen.push_back(size);
|
||||
_vpointer.push_back(_current);
|
||||
_vtype.push_back(type);
|
||||
_count++;
|
||||
_current += size;
|
||||
}
|
||||
|
||||
void pop_back()
|
||||
{
|
||||
if (_count > 0)
|
||||
{
|
||||
_current = _vpointer[_count - 1];
|
||||
_vlen.pop_back();
|
||||
_vpointer.pop_back();
|
||||
_vtype.pop_back();
|
||||
_count--;
|
||||
}
|
||||
}
|
||||
void pop_back()
|
||||
{
|
||||
if (_count > 0)
|
||||
{
|
||||
_current = _vpointer[_count - 1];
|
||||
_vlen.pop_back();
|
||||
_vpointer.pop_back();
|
||||
_vtype.pop_back();
|
||||
_count--;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int size()
|
||||
{
|
||||
return _count;
|
||||
}
|
||||
unsigned int size()
|
||||
{
|
||||
return _count;
|
||||
}
|
||||
|
||||
// stack access (index is counted from back)
|
||||
void* get_obj(unsigned int index)
|
||||
{
|
||||
if (index<_count)
|
||||
return _vpointer[_count-index-1];
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
// stack access (index is counted from back)
|
||||
void* get_obj(unsigned int index)
|
||||
{
|
||||
if (index<_count)
|
||||
return _vpointer[_count-index-1];
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void* operator[](unsigned int index)
|
||||
{
|
||||
return get_obj(index);
|
||||
}
|
||||
|
||||
void* back()
|
||||
{
|
||||
if (_count>0)
|
||||
return _vpointer[_count-1];
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
void* operator[](unsigned int index)
|
||||
{
|
||||
return get_obj(index);
|
||||
}
|
||||
|
||||
void* back()
|
||||
{
|
||||
if (_count>0)
|
||||
return _vpointer[_count-1];
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
unsigned int get_len(unsigned int index)
|
||||
{
|
||||
if (index<_count)
|
||||
return _vlen[_count-index-1];
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
unsigned int get_len(unsigned int index)
|
||||
{
|
||||
if (index<_count)
|
||||
return _vlen[_count-index-1];
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
int get_type(unsigned int index)
|
||||
{
|
||||
if (index<_count)
|
||||
return _vtype[_count-index-1];
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
int get_type(unsigned int index)
|
||||
{
|
||||
if (index<_count)
|
||||
return _vtype[_count-index-1];
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
// sequential access (index is counted from front)
|
||||
void* seq_obj(unsigned int index)
|
||||
{
|
||||
if (index<_count)
|
||||
return _vpointer[index];
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
// sequential access (index is counted from front)
|
||||
void* seq_obj(unsigned int index)
|
||||
{
|
||||
if (index<_count)
|
||||
return _vpointer[index];
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
unsigned int seq_len(unsigned int index)
|
||||
{
|
||||
if (index<_count)
|
||||
return _vlen[index];
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
unsigned int seq_len(unsigned int index)
|
||||
{
|
||||
if (index<_count)
|
||||
return _vlen[index];
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
int seq_type(unsigned int index)
|
||||
{
|
||||
if (index<_count)
|
||||
return _vtype[index];
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
int seq_type(unsigned int index)
|
||||
{
|
||||
if (index<_count)
|
||||
return _vtype[index];
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
// local objects copy
|
||||
void copy_obj_to_local(unsigned int index, unsigned int to_place)
|
||||
{
|
||||
assert(to_place < LOCAL_COPY_PLACES);
|
||||
struct local_copy* local = (struct local_copy*)_places[to_place];
|
||||
local->length = get_len(index);
|
||||
local->type= get_type(index);
|
||||
memcpy(&local->blob, get_obj(index), local->length);
|
||||
}
|
||||
// local objects copy
|
||||
void copy_obj_to_local(unsigned int index, unsigned int to_place)
|
||||
{
|
||||
assert(to_place < LOCAL_COPY_PLACES);
|
||||
struct local_copy* local = (struct local_copy*)_places[to_place];
|
||||
local->length = get_len(index);
|
||||
local->type= get_type(index);
|
||||
memcpy(&local->blob, get_obj(index), local->length);
|
||||
}
|
||||
|
||||
void push_obj_from_local(unsigned int from_place)
|
||||
{
|
||||
assert(from_place < LOCAL_COPY_PLACES);
|
||||
struct local_copy* local = (struct local_copy*)_places[from_place];
|
||||
push_back(&local->blob, local->length, local->type);
|
||||
}
|
||||
void push_obj_from_local(unsigned int from_place)
|
||||
{
|
||||
assert(from_place < LOCAL_COPY_PLACES);
|
||||
struct local_copy* local = (struct local_copy*)_places[from_place];
|
||||
push_back(&local->blob, local->length, local->type);
|
||||
}
|
||||
|
||||
void dump(void)
|
||||
{
|
||||
|
@ -155,118 +155,118 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
char* _base;
|
||||
char* _current;
|
||||
vector<unsigned int> _vlen;// size of each entry in bytes
|
||||
vector<char*> _vpointer;//pointer on each entry
|
||||
vector<int> _vtype;//type of each entry
|
||||
unsigned int _count;// =_vlen.size()=_vpointer.size()=_vtype.size()
|
||||
unsigned int _total_size;//total allocated size in bytes
|
||||
char* _base;
|
||||
char* _current;
|
||||
vector<unsigned int> _vlen;// size of each entry in bytes
|
||||
vector<char*> _vpointer;//pointer on each entry
|
||||
vector<int> _vtype;//type of each entry
|
||||
unsigned int _count;// =_vlen.size()=_vpointer.size()=_vtype.size()
|
||||
unsigned int _total_size;//total allocated size in bytes
|
||||
|
||||
char _places[LOCAL_COPY_PLACES][LOCAL_COPY_SIZE];
|
||||
char _places[LOCAL_COPY_PLACES][LOCAL_COPY_SIZE];
|
||||
};
|
||||
|
||||
//
|
||||
class heap
|
||||
{
|
||||
private:
|
||||
struct local_var
|
||||
{
|
||||
unsigned int length;
|
||||
int type;
|
||||
int blob;
|
||||
};
|
||||
struct local_var
|
||||
{
|
||||
unsigned int length;
|
||||
int type;
|
||||
int blob;
|
||||
};
|
||||
|
||||
public:
|
||||
heap() { }
|
||||
virtual ~heap()
|
||||
{
|
||||
for(map<string, struct local_var*>::iterator i=_map.begin(); i!=_map.end(); i++)
|
||||
free(i->second);
|
||||
}
|
||||
heap() { }
|
||||
virtual ~heap()
|
||||
{
|
||||
for(map<string, struct local_var*>::iterator i=_map.begin(); i!=_map.end(); i++)
|
||||
free(i->second);
|
||||
}
|
||||
|
||||
void add(const string name, void* obj, unsigned int size, int type = 0)
|
||||
{
|
||||
struct local_var* blob = _map[name];
|
||||
if (blob == NULL)
|
||||
{
|
||||
void add(const string name, void* obj, unsigned int size, int type = 0)
|
||||
{
|
||||
struct local_var* blob = _map[name];
|
||||
if (blob == NULL)
|
||||
{
|
||||
//TODO gerer les pbs de memoire
|
||||
blob = (struct local_var*)malloc(size + sizeof(local_var));
|
||||
_map[name] = blob;
|
||||
blob = (struct local_var*)malloc(size + sizeof(local_var));
|
||||
_map[name] = blob;
|
||||
}
|
||||
else if (size != blob->length)
|
||||
{
|
||||
else if (size != blob->length)
|
||||
{
|
||||
//TODO gerer les pbs de memoire
|
||||
blob = (struct local_var*)realloc(blob, size + sizeof(local_var));
|
||||
_map[name] = blob;
|
||||
blob = (struct local_var*)realloc(blob, size + sizeof(local_var));
|
||||
_map[name] = blob;
|
||||
}
|
||||
blob->length = size;
|
||||
blob->type= type;
|
||||
memcpy(&blob->blob, obj, size);
|
||||
}
|
||||
blob->length = size;
|
||||
blob->type= type;
|
||||
memcpy(&blob->blob, obj, size);
|
||||
}
|
||||
|
||||
bool get(const string name, void*& obj, unsigned int& size, int& type)
|
||||
{
|
||||
map<string, struct local_var*>::iterator i = _map.find(name);
|
||||
if (i != _map.end())
|
||||
{
|
||||
if (i->second != NULL)
|
||||
{
|
||||
obj = &i->second->blob;
|
||||
size = i->second->length;
|
||||
type = i->second->type;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
bool get(const string name, void*& obj, unsigned int& size, int& type)
|
||||
{
|
||||
map<string, struct local_var*>::iterator i = _map.find(name);
|
||||
if (i != _map.end())
|
||||
{
|
||||
if (i->second != NULL)
|
||||
{
|
||||
obj = &i->second->blob;
|
||||
size = i->second->length;
|
||||
type = i->second->type;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool exist(const string name)
|
||||
{
|
||||
return (_map.find(name) != _map.end());
|
||||
}
|
||||
bool exist(const string name)
|
||||
{
|
||||
return (_map.find(name) != _map.end());
|
||||
}
|
||||
|
||||
bool get_by_index(int num, string& name, void*& obj, unsigned int& size, int& type)
|
||||
{
|
||||
if (num>=0 && num<(int)_map.size())
|
||||
{
|
||||
struct local_var* blob;
|
||||
map<string, struct local_var*>::iterator i=_map.begin();
|
||||
bool get_by_index(int num, string& name, void*& obj, unsigned int& size, int& type)
|
||||
{
|
||||
if (num>=0 && num<(int)_map.size())
|
||||
{
|
||||
struct local_var* blob;
|
||||
map<string, struct local_var*>::iterator i=_map.begin();
|
||||
|
||||
//TODO moche moche moche
|
||||
for(int j=0;j<num;j++)
|
||||
i++;
|
||||
//TODO moche moche moche
|
||||
for(int j=0;j<num;j++)
|
||||
i++;
|
||||
|
||||
blob = (struct local_var*)i->second;
|
||||
assert(blob != NULL);
|
||||
blob = (struct local_var*)i->second;
|
||||
assert(blob != NULL);
|
||||
|
||||
name = i->first;
|
||||
obj = &blob->blob;
|
||||
size = blob->length;
|
||||
type = blob->type;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
name = i->first;
|
||||
obj = &blob->blob;
|
||||
size = blob->length;
|
||||
type = blob->type;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool erase(const string& name)
|
||||
{
|
||||
map<string, struct local_var*>::iterator i = _map.find(name);
|
||||
if (i != _map.end())
|
||||
{
|
||||
{
|
||||
map<string, struct local_var*>::iterator i = _map.find(name);
|
||||
if (i != _map.end())
|
||||
{
|
||||
free(i->second);
|
||||
_map.erase(i->first);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
_map.erase(i->first);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int size() { return _map.size(); }
|
||||
unsigned int size() { return _map.size(); }
|
||||
|
||||
private:
|
||||
map<string, struct local_var*> _map;
|
||||
map<string, struct local_var*> _map;
|
||||
};
|
||||
|
||||
#endif // __stack_h__
|
||||
|
|
|
@ -7,10 +7,10 @@ static const string g_show_stack_separator = "> ";
|
|||
|
||||
// syntax
|
||||
static const char* syntax[] = {
|
||||
"Reverse Polish Notation language, based on hewlett-Packard RPL",
|
||||
"Syntax: rpn [command]",
|
||||
"with optional command = list of commands",
|
||||
NULL
|
||||
"Reverse Polish Notation language, based on hewlett-Packard RPL",
|
||||
"Syntax: rpn [command]",
|
||||
"with optional command = list of commands",
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char prompt[] = ATTR_BOLD "rpn" ATTR_OFF "> ";
|
||||
|
|
Loading…
Reference in a new issue