tabs to spaces

This commit is contained in:
Louis 2015-05-19 17:51:03 +02:00
parent f62805cfd3
commit 311d00906d
16 changed files with 1385 additions and 1385 deletions

View file

@ -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);
}

View file

@ -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());
}

View file

@ -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;
}
}

View file

@ -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, "" },
};

View file

@ -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()

View file

@ -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;
}

View file

@ -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)

View file

@ -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)

View file

@ -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++)
{

View file

@ -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);
}
}
}

View file

@ -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;
}

View file

@ -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();
}

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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__

View file

@ -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 "> ";