diff --git a/README b/README index ef444ed..5b530c7 100644 --- a/README +++ b/README @@ -24,39 +24,202 @@ Language extensions will soon be included: ======================================================================== Here is a list of HP28s reserved words. -New commands (nonexistent in RPL) are tagged with (+). -Already implemented commands are tagged with (*). +New commands (nonexistent in RPL) are tagged with * in column new. +Already implemented commands are tagged with * in column impl. +Tested commands are tagged with * in column tested. -GENERAL OPERATIONS - +(*), -(*), neg(*), *(*), /(*), inv(*)(+), %(*), %CH(*), ^(*), - sqrt(*)(+), sq(*)(+), test(*)(+) +category command new impl. tested -GENERAL (some are 'CURSOR' commands) - verbose(*)(+), std(*), fix(*), sci(*), version(*)(+), uname(*)(+) +GENERAL + * +GENERAL - * +GENERAL neg * +GENERAL * * +GENERAL / * +GENERAL inv * +GENERAL % * +GENERAL %CH * +GENERAL ^ * +GENERAL sqrt * * +GENERAL sq * * +GENERAL test * * +GENERAL verbose * * +GENERAL std * +GENERAL fix * +GENERAL sci * +GENERAL version * * +GENERAL uname * * -STACK - drop(*), swap(*), roll, dup(*), over, dup2(*), drop2(*), rot(*), - list->, rolld, pick(*), dupn, dropn, depth(*), ->list, load_stack(+), - save_stack(+) +STACK drop * +STACK swap * +STACK roll +STACK dup * +STACK over +STACK dup2 * +STACK drop2 * +STACK rot * +STACK list-> +STACK rolld +STACK pick * +STACK dupn +STACK dropn +STACK depth * +STACK ->list +STACK load_stack * * +STACK save_stack * * STORE - sto(*), rcl(*), purge(*), sto+, sto-, sto*, sto/, sneg, sinv, sconj, - erase(*)(+), vars(*)(+), include(+), load_vars(+), save_vars(+) +STORE sto * +STORE rcl * +STORE purge * +STORE sto+ +STORE sto- +STORE sto* +STORE sto/ +STORE sneg +STORE sinv +STORE sconj +STORE erase * * +STORE vars * * +STORE include * +STORE load_vars * +STORE save_vars * -PROGRAM(+) - eval(*), load_prog(+), save_prog(+) +PROGRAM eval * +PROGRAM load_prog * +PROGRAM save_prog * + +ALGEBRA neg * * +ALGEBRA colct +ALGEBRA expan +ALGEBRA size +ALGEBRA form +ALGEBRA obsub +ALGEBRA exsub +ALGEBRA taylr +ALGEBRA isol +ALGEBRA quad, +ALGEBRA show +ALGEBRA obget +ALGEBRA exget + +BINARY + * +BINARY - * +BINARY * * +BINARY / * +BINARY dec * +BINARY hex * +BINARY oct * +BINARY bin * +BINARY stws +BINARY rcws +BINARY rl +BINARY rr +BINARY rlb +BINARY rrb +BINARY r->b * +BINARY b->r * +BINARY sl +BINARY sr +BINARY slb +BINARY srb +BINARY asr +BINARY and +BINARY or +BINARY xor +BINARY not + +STRING + * +STRING ->str * +STRING str-> * +STRING chr +STRING num +STRING ->lcd +STRING lcd-> +STRING pos +STRING sub +STRING size +STRING disp + +BRANCH +BRANCH if * +BRANCH then * +BRANCH else * +BRANCH end * +BRANCH start * +BRANCH for * +BRANCH next * +BRANCH step * +BRANCH ift +BRANCH ifte +BRANCH do +BRANCH until +BRANCH end +BRANCH while +BRANCH repeat +BRANCH end + +TEST +TEST != * +TEST > * +TEST >= * +TEST < * +TEST <= * +TEST sf +TEST cf +TEST fs? +TEST fc? +TEST fs?c +TEST fc?c +TEST and * +TEST or * +TEST xor * +TEST not * +TEST same * +TEST == * +TEST stof +TEST rclf +TEST type + +TRIG +TRIG pi * * +TRIG sin * +TRIG asin * +TRIG cos * +TRIG acos * +TRIG tan * +TRIG atan * +TRIG p→r +TRIG r→p +TRIG r→c +TRIG c→r +TRIG arg +TRIG →hms +TRIG hms→ +TRIG hms+ +TRIG hms- +TRIG d→r * +TRIG r→d * + +LOGS +LOGS log * +LOGS alog * +LOGS ln * +LOGS exp * +LOGS lnp1 +LOGS expm +LOGS sinh * +LOGS asinh * +LOGS cosh * +LOGS acosh * +LOGS tanh * +LOGS atanh * + + +Not yet +======= MEMORY - mem, menu, order, path, home, crdir, vars, clusr - -ALGEBRA - neg(*)(+), colct, expan, size, form, obsub, exsub, taylr, isol, quad, - show, obget, exget - -BINARY - +(*), -(*), *(*), /(*), dec(*), hex(*), oct(*), bin(*), stws, rcws, - rl, rr, rlb, rrb, r->b(*), b->r(*), sl, sr, slb, srb, asr, and, or, - xor, not + mem, menu, order, path, home, crdir, vars, clusr, STAT ∑dat, ∑par, ∑+, ∑-, n∑, cl∑, sto∑, rcl∑, tot, mean, sdev, var, max∑, @@ -65,39 +228,6 @@ STAT PRINT pr1, prst, prvar, prlcd, cr, trac, prstc, prusr, prmd -STRING - +(*), ->str, str->, chr, num, ->lcd, lcd->, pos, sub, size, disp - -CONTRL - sst, halt, abort, kill, wait, key, bepp, cllcd, disp, clmf, errn, - errm - -BRANCH - if(*), iferr, then(*), else(*), end(*), start(*), for(*), next(*), - step(*), ift, ifte, do, until, end, while, repeat, end - -TEST - !=(*), >(*), >=(*), <(*), <=(*), sf, cf, fs?, fc?, fs?c, fc?c, and(*), - or(*), xor(*), not(*), same(*), ==(*), stof, rclf, type - -CATALOG - next, prev, scan, use, fetch, quit - -UNITS - convert - -CURSOR (some of these functions can be found in GENERAL) - ins, del, ← → ↑ ↓, std, fix, sci, eng, deg, rad, cmd, undo, last, ml, - rdx, prmd - -TRIG - pi(*)(+), sin(*), asin(*), cos(*), acos(*), tan(*), atan(*), p→r, r→p, - r→c, c→r, arg, →hms, hms→, hms+, hms-, (*)d→r, (*)r→d - -LOGS - log(*), alog(*), ln(*), exp(*), lnp1, expm, sinh(*), asinh(*), cosh(*), - acosh(*), tanh(*), atanh(*) - SOLV steq, rceq, isol, quad, show, root, @@ -105,6 +235,19 @@ PLOT ppar, steq, rceq, pmin, pmax, indep, draw, res, axes, centr, *w, *h, sto∑, rcl∑, col∑, scl∑, drw∑, cllcd, digtiz +CURSOR + ins, del, ← → ↑ ↓, cmd, undo, last, ml, rdx, prmd + +CONTRL + sst, halt, abort, kill, wait, key, bepp, cllcd, disp, clmf, errn, + errm + +CATALOG + next, prev, scan, use, fetch, quit + +UNITS + convert + CUSTOM menu, custom diff --git a/src/debug.h b/src/debug.h new file mode 100644 index 0000000..4268da1 --- /dev/null +++ b/src/debug.h @@ -0,0 +1,41 @@ +static void dump8(unsigned char* to_dump, unsigned long offset, + unsigned long size) +{ + const int block_size = 1; + const int block_per_line = 16; + int max_line = size / block_size; + unsigned char mychar; + int i; + int j; + for (i = 0; i < max_line; i++) + { + if ((i % block_per_line) == 0) + { + if (i > 0) + { + printf(" "); + for (j = i - block_per_line; j < i; j++) + { + mychar = *(to_dump + j); + if ((mychar < 32) || (mychar >= 127)) + mychar = '.'; + printf("%c", mychar); + } + } + printf("\n%08lX:", offset + i * block_size); + } + printf(" %02hhX", *(to_dump + i)); + } + if (i > 0) + { + printf(" "); + for (j = (i >= block_per_line) ? (i - block_per_line) : 0; j < i; j++) + { + mychar = *(to_dump + j); + if ((mychar < 32) || (mychar >= 127)) + mychar = '.'; + printf("%c", mychar); + } + } + printf("\n"); +} diff --git a/src/parse.h b/src/parse.h index 1b7f02c..0ed304c 100644 --- a/src/parse.h +++ b/src/parse.h @@ -1,15 +1,43 @@ -static bool _cut(const string& entry, vector& entries) +// keywords declaration +struct keyword_t +{ + cmd_type_t type; + char name[24]; + program_fn_t fn; + string comment; +}; +static const int g_max_commands = 128; +static keyword_t _keywords[g_max_commands]; + +static ret_value get_fn(const char* fn_name, program_fn_t& fn, cmd_type_t& type) +{ + for(unsigned int i=0; (i0) + && (strncmp(fn_name, _keywords[i].name, sizeof(_keywords[i].name)) == 0)) + { + fn = _keywords[i].fn; + type = _keywords[i].type; + return ret_ok; + } + } + return ret_unknown_err; +} + +static bool _cut(const char* entry, vector& entries) { string tmp; + //TODO borner + int len = strlen(entry); - for (int i=0; i0) + if (tmp.size() > 0) { entries.push_back(tmp); tmp.clear(); @@ -17,10 +45,10 @@ static bool _cut(const string& entry, vector& entries) //get symbol tmp='\''; i++; - while((i& entries) //string case '"': //push prec entry if exists - if (tmp.size()>0) + if (tmp.size() > 0) { entries.push_back(tmp); tmp.clear(); @@ -36,10 +64,10 @@ static bool _cut(const string& entry, vector& entries) //get expression tmp='"'; i++; - while(i=' ') + while(i < len && entry[i] >= ' ') { - tmp+=entry.at(i); - if (entry.at(i++) == '"') + tmp += entry[i]; + if (entry[i++] == '"') break; } entries.push_back(tmp); @@ -55,35 +83,37 @@ static bool _cut(const string& entry, vector& entries) tmp.clear(); } - if (entry.substr(i, 2) == "<<") + if (strncmp(&entry[i], "<<", 2) == 0) { int up = 1; // found a program begin - i+=2; - tmp="<< "; + i += 2; + tmp = "<< "; + // trim leading spaces - while (i>") + else if (strncmp(&entry[i], ">>", 2) == 0) { up--; - i+=2; - tmp+=" >>"; + i += 2; + tmp += " >>"; + // trim trailing spaces - while (i& entries) } else { - tmp+=entry[i]; + tmp += entry[i]; i++; } } @@ -114,9 +144,9 @@ static bool _cut(const string& entry, vector& entries) //other default: - if (entry.at(i)!=' ' && entry.at(i)!='\t') + if (entry[i] != ' ' && entry[i] != '\t') { - tmp+=entry.at(i); + tmp += entry[i]; } else { @@ -147,14 +177,18 @@ static bool get_keyword(const string& entry, object*& obj, unsigned int& obj_siz { if (type == cmd_keyword) { - obj = new keyword(fn, (string&)entry); - obj_size = sizeof(keyword); + // allocate keyword object + obj_size = sizeof(keyword)+entry.size()+1; + obj = (object*)malloc(obj_size); + ((keyword*)obj)->set(fn, entry.c_str(), entry.size()); ret = true; } else if (type == cmd_branch) { - obj = new branch((branch_fn_t)fn, (string&)entry); - obj_size = sizeof(branch); + // allocate branch object + obj_size = sizeof(branch)+entry.size()+1; + obj = (object*)malloc(obj_size); + ((branch*)obj)->set((branch_fn_t)fn, entry.c_str(), entry.size()); ret = true; } } @@ -162,53 +196,147 @@ static bool get_keyword(const string& entry, object*& obj, unsigned int& obj_siz return ret; } -static bool get_symbol(const string& entry, object*& obj) +static bool get_symbol(const string& entry, object*& obj, unsigned int& obj_len) { bool ret = false; - int len = entry.size(); - if (len>1 && entry[0]=='\'') - { - int last = entry[len-1]=='\''?(len-2):(len-1); - obj = new symbol(entry.substr(1, last).c_str()); - ret = true; - } - return ret; -} + int entry_len = entry.size(); -static bool get_string(const string& entry, object*& obj) -{ - bool ret = false; - int len = entry.size(); - if (len>1 && entry[0]=='\"') + if (entry_len>=1 && entry[0]=='\'') { - int last = entry[len-1]=='\"'?(len-2):(len-1); - obj = new ostring(entry.substr(1, last).c_str()); - ret = true; - } - return ret; -} + // symbol entry, like 'toto' + if (entry_len == 1) + { + // total object length + obj_len = sizeof(symbol)+1; -static bool get_program(const string& entry, object*& obj) -{ - bool ret = false; - int len = entry.size(); - if (len>=2 && entry[0]=='<' && entry[1]=='<') - { - int last; - if (len>=4 && entry[len-1]=='>' && entry[len-2]=='>') - last = len-4; + // allocate object + obj = (symbol*)malloc(obj_len); + + //set it + ((symbol*)obj)->set("", 0); + } else - last = len-2; - obj = new oprogram(entry.substr(2, last).c_str()); + { + int naked_entry_len; + + // entry length without prefix / postfix + naked_entry_len = entry[entry_len-1]=='\''?(entry_len-2):(entry_len-1); + // total object length + obj_len = sizeof(symbol)+naked_entry_len+1; + + // allocate object + obj = (symbol*)malloc(obj_len); + + // set it + ((symbol*)obj)->set(entry.substr(1, naked_entry_len).c_str(), naked_entry_len); + } + ret = true; + } + + return ret; +} + +static bool get_other(const string& entry, object*& obj, unsigned int& obj_len, cmd_type_t& type) +{ + bool ret = false; + int entry_len = entry.size(); + + if (entry_len>=1) + { + // entry which is nothing is considered as an auto-evaluated symbol + int naked_entry_len; + + // entry length without prefix / postfix + naked_entry_len = entry[entry_len-1]=='\''?(entry_len-1):(entry_len); + // total object length + obj_len = sizeof(symbol)+naked_entry_len+1; + + // allocate object + obj = (symbol*)malloc(obj_len); + + // set it + ((symbol*)obj)->set(entry.c_str(), naked_entry_len); + ((symbol*)obj)->_auto_eval = true; + type = cmd_symbol; + ret = true; + } + + return ret; +} + +static bool get_string(const string& entry, object*& obj, unsigned int& obj_len) +{ + bool ret = false; + int entry_len = entry.size(); + if (entry_len>=1 && entry[0]=='"') + { + if (entry_len == 1) + { + // total object length + obj_len = sizeof(ostring)+1; + + // allocate object + obj = (ostring*)malloc(obj_len); + + //set it + ((ostring*)obj)->set("", 0); + } + else + { + int naked_entry_len; + + // entry length without prefix / postfix + naked_entry_len = entry[entry_len-1]=='"'?(entry_len-2):(entry_len-1); + + // total object length + obj_len = sizeof(ostring)+naked_entry_len+1; + + // allocate object + obj = (ostring*)malloc(obj_len); + + // set it + ((ostring*)obj)->set(entry.substr(1, naked_entry_len).c_str(), naked_entry_len); + } + ret = true; + } + + return ret; +} + +static bool get_program(const string& entry, object*& obj, unsigned int& obj_len) +{ + bool ret = false; + int entry_len = entry.size(); + if (entry_len>=2 && entry[0]=='<' && entry[1]=='<') + { + int naked_entry_len; + + // entry length without prefix / postfix + if (entry_len>=4 && entry[entry_len-1]=='>' && entry[entry_len-2]=='>') + naked_entry_len = entry_len-4; + else + naked_entry_len = entry_len-2; + + // total object length + obj_len = sizeof(oprogram)+naked_entry_len+1; + + // allocate object + obj = (object*)malloc(obj_len); + + // set it + ((oprogram*)obj)->set(&entry[2], naked_entry_len); + ret = true; } return ret; } -static bool get_float(const string& entry, object*& obj) +// care: not threadsafe +static bool get_float(const string& entry, object*& obj, unsigned int& obj_size) { - stringstream token; + static number new_number; floating_t val; + stringstream token; bool ret = false; token<= 2) && (entry[0] == '#')) { stringstream token; @@ -255,7 +388,9 @@ static bool get_binary(const string& entry, object*& obj) token>>val; if(syntax && !token.fail()) { - obj = new binary(val); + new_binary.set(val); + obj = &new_binary; + obj_size = sizeof(binary); ret = true; } } @@ -263,8 +398,10 @@ static bool get_binary(const string& entry, object*& obj) return ret; } -static bool get_binary_bin(const string& entry, object*& obj) +// care: not threadsafe +static bool get_binary_bin(const string& entry, object*& obj, unsigned int& obj_size) { + static binary new_binary; integer_t val; int len = entry.size(); bool ret = false; @@ -281,7 +418,9 @@ static bool get_binary_bin(const string& entry, object*& obj) exponent/=2; } } - obj = new binary(val); + new_binary.set(val); + obj = &new_binary; + obj_size = sizeof(binary); ret = true; } @@ -292,40 +431,34 @@ static bool _obj_from_string(const string& entry, object*& obj, unsigned int& ob { bool ret = false; - if (get_float(entry, obj)) + if (get_float(entry, obj, obj_size)) { type = cmd_number; - obj_size = sizeof(number); ret = true; } - else if (get_binary(entry, obj)) + else if (get_binary(entry, obj, obj_size)) { type = cmd_binary; - obj_size = sizeof(binary); ret = true; } - else if (get_binary_bin(entry, obj)) + else if (get_binary_bin(entry, obj, obj_size)) { type = cmd_binary; - obj_size = sizeof(binary); ret = true; } - else if (get_symbol(entry, obj)) + else if (get_symbol(entry, obj, obj_size)) { type = cmd_symbol; - obj_size = sizeof(symbol); ret = true; } - else if (get_string(entry, obj)) + else if (get_string(entry, obj, obj_size)) { type = cmd_string; - obj_size = sizeof(ostring); ret = true; } - else if (get_program(entry, obj)) + else if (get_program(entry, obj, obj_size)) { type = cmd_program; - obj_size = sizeof(oprogram); ret = true; } else if (get_keyword(entry, obj, obj_size, type)) @@ -335,16 +468,31 @@ static bool _obj_from_string(const string& entry, object*& obj, unsigned int& ob else { // nothing, considered as an auto-evaluated symbol - obj = new symbol((string&)entry); - ((symbol*)obj)->_auto_eval = true; - obj_size = sizeof(symbol); - type = cmd_symbol; - ret = true; + if (get_other(entry, obj, obj_size, type)) + { + ret = true; + } } return ret; } +static void _delete_obj_from_string(object* obj) +{ + if (obj != NULL) + { + switch (obj->_type) + { + case cmd_number: + case cmd_binary: + break; + default: + free(obj); + break; + } + } +} + static char* entry_completion_generator(const char* text, int state) { static int list_index, len, too_far; @@ -386,7 +534,7 @@ static char* entry_completion_dupstr(char* s) return r; } -static ret_value parse(const string& entry, program& prog) +static ret_value parse(const char* entry, program& prog) { vector entries; ret_value ret = ret_ok; @@ -403,6 +551,7 @@ static ret_value parse(const string& entry, program& prog) if(_obj_from_string((*it), obj, obj_size, type)) { prog.push_back(obj, obj_size, type); + _delete_obj_from_string(obj); } else { @@ -417,7 +566,7 @@ static ret_value parse(const string& entry, program& prog) // interactive entry and decoding static ret_value entry(program& prog) { - char *buf; + char* buf; ret_value ret; // declare completion fn (bound to '\t' by default) @@ -427,10 +576,8 @@ static ret_value entry(program& prog) buf = readline(prompt); if (buf != NULL) { - string entry(buf); - // parse it - ret = parse(entry, prog); + ret = parse(buf, prog); // keep history if (buf[0]!=0) diff --git a/src/rpn-algebra.h b/src/rpn-algebra.h index 2542899..f60b3f7 100644 --- a/src/rpn-algebra.h +++ b/src/rpn-algebra.h @@ -16,7 +16,9 @@ void plus() //TODO really too slow putb(getb() + getb()); } - // string + //TODO +#if 0 + // string else if (IS_ARG_TYPE(0, cmd_string)) { ARG_MUST_BE_OF_TYPE(1, cmd_string); @@ -24,6 +26,7 @@ void plus() _stack->pop_back(); *((ostring*)_stack->back())->_value += second; } +#endif else ERR_CONTEXT(ret_bad_operand_type); } diff --git a/src/rpn-binary.h b/src/rpn-binary.h index d106ac7..bec0a77 100644 --- a/src/rpn-binary.h +++ b/src/rpn-binary.h @@ -23,8 +23,9 @@ void rtob() MIN_ARGUMENTS(1); ARG_MUST_BE_OF_TYPE(0, cmd_number); - binary bin((integer_t)getf()); - _stack->push_back(&bin, sizeof(binary), cmd_binary); + binary bin; + bin.set(((integer_t)getf())); + _stack->push_back(&bin, bin.size(), cmd_binary); } diff --git a/src/rpn-branch.h b/src/rpn-branch.h index 54730c5..4610000 100644 --- a/src/rpn-branch.h +++ b/src/rpn-branch.h @@ -70,8 +70,9 @@ int rpn_for(branch& myobj) myobj.farg1 = getf(); // store symbol with first value - number num(myobj.farg1); - _heap->add(*sym->_value, &num, sizeof(number), cmd_number); + number num; + num.set(myobj.farg1); + _heap->add(string(sym->_value), &num, num.size(), cmd_number); return myobj.arg1 + 1; } @@ -98,7 +99,7 @@ int rpn_next(branch& myobj) int type; symbol* var = (symbol*)seq_obj(start_or_for->arg1); // check symbol variable is a number, then increase - if (_heap->get(*var->_value, obj, size, type) && (type == cmd_number)) + if (_heap->get(string(var->_value), obj, size, type) && (type == cmd_number)) ((number*)obj)->_value = myobj.farg1; } @@ -143,7 +144,7 @@ int rpn_step(branch& myobj) int type; symbol* var = (symbol*)seq_obj(start_or_for->arg1); // check symbol variable is a number, then increase - if (_heap->get(*var->_value, obj, size, type) && (type == cmd_number)) + if (_heap->get(string(var->_value), obj, size, type) && (type == cmd_number)) ((number*)obj)->_value = myobj.farg1; } diff --git a/src/rpn-program.h b/src/rpn-program.h index 095da44..dd15675 100644 --- a/src/rpn-program.h +++ b/src/rpn-program.h @@ -8,7 +8,7 @@ void eval(void) void* obj; unsigned int size; int type; - string& variable = *((symbol*)_stack->back())->_value; + string variable(((symbol*)_stack->back())->_value); if (_heap->get(variable, obj, size, type)) { _stack->pop_back(); @@ -20,13 +20,13 @@ void eval(void) else if (IS_ARG_TYPE(0, cmd_program)) { // eval a program - string& entry = *((oprogram*)_stack->back())->_value; + string entry(((oprogram*)_stack->back())->_value); _stack->pop_back(); program prog; // make program from entry - if (program::parse(entry, prog) == ret_ok) + if (program::parse(entry.c_str(), prog) == ret_ok) { // run it prog.run(*_stack, *_heap); @@ -100,16 +100,16 @@ int inprog(branch& myobj) // load variables for (unsigned int i = myobj.arg1 + count_symbols; i > myobj.arg1; i--) { - _heap->add(*((symbol*)seq_obj(i))->_value, _stack->get_obj(0), _stack->get_len(0), _stack->get_type(0)); + _heap->add(string(((symbol*)seq_obj(i))->_value), _stack->get_obj(0), _stack->get_len(0), _stack->get_type(0)); _stack->pop_back(); } // run the program - string& entry = *((oprogram*)seq_obj(myobj.arg1 + count_symbols + 1))->_value; + string entry(((oprogram*)seq_obj(myobj.arg1 + count_symbols + 1))->_value); program prog; // make the program from entry - if (program::parse(entry, prog) == ret_ok) + if (program::parse(entry.c_str(), prog) == ret_ok) { // run it prog.run(*_stack, *_heap); diff --git a/src/rpn-stack.h b/src/rpn-stack.h index 6ac05a2..cddea0b 100644 --- a/src/rpn-stack.h +++ b/src/rpn-stack.h @@ -76,6 +76,7 @@ void rot(void) void depth(void) { - number num((floating_t)_stack->size()); - _stack->push_back(&num, sizeof(number), cmd_number); + number num; + num.set((floating_t)_stack->size()); + _stack->push_back(&num, num.size(), cmd_number); } diff --git a/src/rpn-store.h b/src/rpn-store.h index 363a96f..7cdf7e6 100644 --- a/src/rpn-store.h +++ b/src/rpn-store.h @@ -4,7 +4,8 @@ void sto(void) MIN_ARGUMENTS(2); ARG_MUST_BE_OF_TYPE(0, cmd_symbol); - string name = getn(); + string name(((symbol*)_stack->get_obj(0))->_value); + _stack->pop_back(); _heap->add(name, _stack->get_obj(0), _stack->get_len(0), _stack->get_type(0)); _stack->pop_back(); } @@ -18,7 +19,7 @@ void rcl(void) void* obj; unsigned int size; int type; - string& variable = *((symbol*)_stack->back())->_value; + string variable(((symbol*)_stack->back())->_value); if (_heap->get(variable, obj, size, type)) { _stack->pop_back(); @@ -36,13 +37,13 @@ void auto_rcl(symbol* symb) void* obj; unsigned int size; int type; - if (_heap->get(*symb->_value, obj, size, type)) + if (_heap->get(string(symb->_value), obj, size, type)) _stack->push_back(obj, size, type); else - _stack->push_back(symb, sizeof(symbol), cmd_symbol); + _stack->push_back(symb, symb->size(), cmd_symbol); } else - _stack->push_back(symb, sizeof(symbol), cmd_symbol); + _stack->push_back(symb, symb->size(), cmd_symbol); } void purge(void) @@ -50,8 +51,11 @@ void purge(void) MIN_ARGUMENTS(1); ARG_MUST_BE_OF_TYPE(0, cmd_symbol); - if (!_heap->erase(getn())) + string name(((symbol*)_stack->back())->_value); + if (!_heap->erase(name)) ERR_CONTEXT(ret_unknown_variable); + else + _stack->pop_back(); } void vars(void) diff --git a/src/rpn-string.h b/src/rpn-string.h index c514789..7305402 100644 --- a/src/rpn-string.h +++ b/src/rpn-string.h @@ -9,23 +9,24 @@ void instr() ((object*)_stack->back())->show(out); _stack->pop_back(); - ostring* str = new ostring(out.str().c_str()); - _stack->push_back(str, sizeof(ostring), cmd_string); + ostring str; + str.set(out.str().c_str(), out.str().size()); + _stack->push_back(&str, str.size(), cmd_string); } } void strout() { - MIN_ARGUMENTS(1); + MIN_ARGUMENTS(1); ARG_MUST_BE_OF_TYPE(0, cmd_string); - string& entry = *((ostring*)_stack->back())->_value; + string entry(((ostring*)_stack->back())->_value); _stack->pop_back(); program prog; // make program from string in stack level 1 - if (program::parse(entry, prog) == ret_ok) + if (program::parse(entry.c_str(), prog) == ret_ok) { // run it prog.run(*_stack, *_heap); diff --git a/src/rpn-test-core.h b/src/rpn-test-core.h index a9ffbe5..cf19345 100644 --- a/src/rpn-test-core.h +++ b/src/rpn-test-core.h @@ -115,7 +115,7 @@ void program::test() { // parse entry and run line program prog; - ret = program::parse(entry, prog); + ret = program::parse(entry.c_str(), prog); if (ret == ret_ok) { // run it diff --git a/src/rpn-test.h b/src/rpn-test.h index 537cd04..3484af0 100644 --- a/src/rpn-test.h +++ b/src/rpn-test.h @@ -63,11 +63,14 @@ void eq(void) putf(getf() == first); } break; + //TODO +#if 0 case cmd_symbol: { string first = getn(); putf(getn() == first); } +#endif break; default: _stack->pop_back(); diff --git a/src/rpn.cpp b/src/rpn.cpp index a6bf2d4..7573d42 100644 --- a/src/rpn.cpp +++ b/src/rpn.cpp @@ -43,11 +43,6 @@ using namespace std; #include "stack.h" -//TODO faut-il que ces variables soient globales ? -static const char g_cursor[] = "> "; -static const string g_show_stack_separator = ":\t"; -static const int g_max_commands = 128; - // static int g_verbose = 0; @@ -106,22 +101,28 @@ typedef union typedef int (program::*branch_fn_t)(branch&); // -class object +struct object { -public: - cmd_type_t _type;// object type - object(cmd_type_t type = cmd_undef):_type(type) { } + // object type + cmd_type_t _type; + // void show(ostream& stream = cout); -}; +} __attribute__((packed)); -class number : public object +struct number : public object { -public: - number(floating_t value) : object(cmd_number) { _value = value; } floating_t _value; - // representation mode + // + void set(floating_t value) + { + _type = cmd_number; + _value = value; + } + unsigned int size() { return sizeof(number); } + + // representation mode typedef enum { std, fix, @@ -133,18 +134,24 @@ public: // 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; int number::s_default_precision = 20; int number::s_current_precision = number::s_default_precision; -class binary : public object +struct binary : public object { -public: - binary(integer_t value) : object(cmd_binary) { _value = value; } integer_t _value; + // + void set(integer_t value) + { + _type = cmd_binary; + _value = value; + } + unsigned int size() { return sizeof(binary); } + // representation mode typedef enum { dec, @@ -154,61 +161,190 @@ public: } 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; -class ostring : public object +struct ostring : public object { -public: - ostring(string& value, cmd_type_t type = cmd_string) : object(type) - { - _value = new string(value); - } - ostring(const char* value, cmd_type_t type = cmd_string) : object(type) - { - _value = new string(value); - } - string* _value; -}; + // + void set(const char* value, unsigned int len) + { + _type = cmd_string; + if (value != NULL) + { + if (len>0) + (void)memcpy(_value, value, len); + _value[len] = 0; + _len = len; + } + else + len = 0; + } + int size() { return sizeof(ostring)+_len+1; } -class oprogram : public ostring -{ -public: - oprogram(string& value, cmd_type_t type = cmd_program) : ostring(value, type) { } - oprogram(const char* value, cmd_type_t type = cmd_program) : ostring(value, type) { } -}; + // + unsigned int _len; + char _value[0]; +} __attribute__((packed)); -class symbol : public ostring +struct oprogram : public object { -public: - symbol(string& value, cmd_type_t type = cmd_symbol) : ostring(value, type), _auto_eval(false) { } - symbol(const char* value, cmd_type_t type = cmd_symbol) : ostring(value, type), _auto_eval(false) { } - bool _auto_eval; -}; + // + void set(const char* value, unsigned int len) + { + _type = cmd_program; + if (value != NULL) + { + if (len>0) + (void)memcpy(_value, value, len); + _value[len] = 0; + _len = len; + } + else + len = 0; + } + int size() { return sizeof(oprogram)+_len+1; } -class keyword : public symbol -{ -public: - keyword(program_fn_t fn, string& value, cmd_type_t type = cmd_keyword) : symbol(value, type) { _fn = fn; } - program_fn_t _fn; -}; + // + unsigned int _len; + char _value[0]; +} __attribute__((packed)); -class branch : public keyword +struct symbol : public object { -public: - branch(branch_fn_t fn, string& value) : keyword(NULL, value, cmd_branch), arg1(-1), arg2(-1), arg3(-1), arg_bool(false) - { - _type = cmd_branch; - _fn = fn; - } - // branch function - branch_fn_t _fn; - // args used by cmd_branch cmds - int arg1, arg2, arg3; - floating_t farg1, farg2; - bool arg_bool; -}; + // + void set(const char* value, unsigned int len) + { + _type = cmd_symbol; + _auto_eval = false; + if (value != NULL) + { + if (len>0) + (void)memcpy(_value, value, len); + _value[len] = 0; + _len = len; + } + else + len = 0; + } + int size() { return sizeof(symbol)+_len+1; } + + // + bool _auto_eval; + unsigned int _len; + char _value[0]; +} __attribute__((packed)); + +struct keyword : public object +{ + // + void set(program_fn_t fn, const char* value, unsigned int len) + { + _type = cmd_keyword; + _fn = fn; + if (value != NULL) + { + if (len>0) + (void)memcpy(_value, value, len); + _value[len] = 0; + _len = len; + } + else + len = 0; + } + int size() { return sizeof(keyword)+_len+1; } + + // + program_fn_t _fn; + unsigned int _len; + char _value[0]; +} __attribute__((packed)); + +struct branch : public object +{ + // + void set(branch_fn_t fn, const char* value, unsigned int len) + { + _type = cmd_branch; + _fn = fn; + arg1 = -1; + arg2 = -1; + arg3 = -1; + farg1 = 0; + farg2 = 0; + arg_bool = 0; + if (value != NULL) + { + if (len>0) + (void)memcpy(_value, value, len); + _value[len] = 0; + _len = len; + } + else + len = 0; + } + int size() { return sizeof(branch)+_len+1; } + + // branch function + branch_fn_t _fn; + // args used by cmd_branch cmds + int arg1, arg2, arg3; + floating_t farg1, farg2; + bool arg_bool; + unsigned int _len; + char _value[0]; +} __attribute__((packed)); + +void object::show(ostream& stream) +{ + switch(_type) + { + case cmd_number: + stream << ((number*)this)->_value; + break; + case cmd_binary: + { + cout << "# "; + switch(((binary*)this)->s_mode) + { + case binary::dec: cout<_value<<" d"; break; + case binary::hex: cout<_value<<" h"; break; + case binary::oct: cout<_value<<" o"; break; + case binary::bin: + { + string mybin; + for (int i = (int)(log((floating_t)((binary*)this)->_value) / log(2.)); i>=0; i--) + { + if (((binary*)this)->_value & (1 << i)) + mybin+='1'; + else + mybin+='0'; + } + cout<_value << "\""; + break; + case cmd_program: + stream << "<< " << ((oprogram*)this)->_value << " >>"; + break; + case cmd_symbol: + stream << "'" << ((symbol*)this)->_value << "'"; + break; + case cmd_keyword: + case cmd_branch: + stream << ((keyword*)this)->_value; + break; + default: + stream << "< unknown object representation >"; + break; + } +} void object::show(ostream& stream) { @@ -305,9 +441,9 @@ public: } // could be an auto-evaluated symbol - if (type == cmd_symbol) + if (type == cmd_symbol) { - auto_rcl((symbol*)seq_obj(i)); + auto_rcl((symbol*)seq_obj(i)); i++; } @@ -364,7 +500,23 @@ public: return ret; } - ret_value preprocess(void) + bool compare_keyword(keyword* k, const char* str_to_compare, int len) + { + if (k->_len >= len) + return strncmp(k->_value, str_to_compare, len) == 0; + else + return false; + } + + bool compare_branch(branch* b, const char* str_to_compare, int len) + { + if (b->_len >= len) + return strncmp(b->_value, str_to_compare, len) == 0; + else + return false; + } + + ret_value preprocess(void) { // for if-then-else-end vector vlayout; @@ -380,9 +532,9 @@ public: if (type == cmd_keyword) { keyword* k = (keyword*)seq_obj(i); - if (k->_value->compare("end") == 0) + if (compare_keyword(k, "end", 3)) { - int next = i + 1; + int next = i + 1; if (next >= (int)size()) next = -1; @@ -410,16 +562,16 @@ public: else if (type == cmd_branch) { branch* k = (branch*)seq_obj(i); - if (k->_value->compare("if") == 0) + if (compare_branch(k, "if", 2)) { if_layout_t layout; - layout.index_if = i; + layout.index_if = i; vlayout.push_back(layout); layout_index++; } - else if (k->_value->compare("then") == 0) + else if (compare_branch(k, "then", 4)) { - int next = i + 1; + int next = i + 1; if (next >= (int)size()) next = -1; @@ -446,9 +598,9 @@ public: k->arg1 = next; k->arg3 = vlayout[layout_index].index_if; } - else if (k->_value->compare("else") == 0) + else if (compare_branch(k, "else", 4)) { - int next = i + 1; + int next = i + 1; if (next >= (int)size()) next = -1; @@ -482,16 +634,16 @@ public: 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 (k->_value->compare("start") == 0) + else if (compare_branch(k, "start", 5)) { vstartindex.push_back(i); } - else if (k->_value->compare("for") == 0) + else if (compare_branch(k, "for", 3)) { vstartindex.push_back(i); k->arg1 = i + 1;// arg1 points on symbol variable } - else if(k->_value->compare("next") == 0) + else if(compare_branch(k, "next", 4)) { if (vstartindex.size() == 0) { @@ -502,7 +654,7 @@ public: k->arg1 = vstartindex[vstartindex.size() - 1];// fill 'next' branch1 = 'start' index vstartindex.pop_back(); } - else if (k->_value->compare("step") == 0) + else if (compare_branch(k, "step", 4)) { if (vstartindex.size() == 0) { @@ -513,7 +665,7 @@ public: k->arg1 = vstartindex[vstartindex.size() - 1];// fill 'step' branch1 = 'start' index vstartindex.pop_back(); } - else if (k->_value->compare("->") == 0) + else if (compare_branch(k, "->", 2)) { k->arg1 = i;// arg1 is '->' command index in program } @@ -558,31 +710,6 @@ public: cerr<<"syntax error: "<0) - && (strncmp(fn_name, _keywords[i].name, sizeof(_keywords[i].name)) == 0)) - { - fn = _keywords[i].fn; - type = _keywords[i].type; - return ret_ok; - } - } - return ret_unknown_err; - } - ret_value get_err(void) { return _err; } #include "parse.h" @@ -625,8 +752,9 @@ private: void putf(floating_t value) { /* warning, caller must check object type before */ - number num(value); - _stack->push_back(&num, sizeof(number), cmd_number); + number num; + num.set(value); + _stack->push_back(&num, num.size(), cmd_number); } integer_t getb() @@ -640,26 +768,12 @@ private: void putb(integer_t value) { /* warning, caller must check object type before */ - binary num(value); - _stack->push_back(&num, sizeof(binary), cmd_binary); + binary num; + num.set(value); + _stack->push_back(&num, num.size(), cmd_binary); } - string getn() - { - /* warning, caller must check object type before */ - string* a = ((symbol*)_stack->back())->_value; - _stack->pop_back(); - return *a; - } - - void putn(string& a) - { - /* warning, caller must check object type before */ - symbol sym(a); - _stack->push_back(&sym, sizeof(symbol), cmd_symbol); - } - - int stack_size() + int stack_size() { return _stack->size(); } @@ -748,7 +862,7 @@ int _tmain(int argc, _TCHAR* argv[]) } // make program - ret = program::parse(entry, prog); + ret = program::parse(entry.c_str(), prog); if (ret == ret_ok) { string separator = ""; diff --git a/src/stack.h b/src/stack.h index 239c795..8b03ff3 100644 --- a/src/stack.h +++ b/src/stack.h @@ -8,6 +8,8 @@ #include using namespace std; +#include "debug.h" + #define ALLOC_BLOB (128*1024) #define LOCAL_COPY_PLACES 3 #define LOCAL_COPY_SIZE 128 @@ -147,6 +149,11 @@ public: push_back(&local->blob, local->length, local->type); } + void dump(void) + { + dump8((unsigned char*)_base, 0, (unsigned long)(_current - _base)); + } + private: char* _base; char* _current; @@ -186,13 +193,13 @@ public: //TODO gerer les pbs de memoire blob = (struct local_var*)malloc(size + sizeof(local_var)); _map[name] = blob; - } + } 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->length = size; blob->type= type; memcpy(&blob->blob, obj, size); @@ -244,12 +251,12 @@ public: return false; } - bool erase(const string name) + bool erase(const string& name) { map::iterator i = _map.find(name); if (i != _map.end()) { - free(i->second); + free(i->second); _map.erase(i->first); return true; } diff --git a/src/version.h b/src/version.h index 8393d30..6e55b75 100644 --- a/src/version.h +++ b/src/version.h @@ -2,6 +2,9 @@ static const char version[] = "1.4-beta"; static const char uname[] = "rpn v1.4-beta, (c) 2015 "; +static const char g_cursor[] = "> "; +static const string g_show_stack_separator = "> "; + // syntax static const char* syntax[] = { "Reverse Polish Notation language, based on hewlett-Packard RPL", diff --git a/test/test.txt b/test/test.txt index 9255d8b..9928d71 100644 --- a/test/test.txt +++ b/test/test.txt @@ -42,21 +42,11 @@ drop2 drop2 # test symbol entry 3 -'2 3' --> stack should be '2 3' -drop - -# test symbol entry 4 -'2 3 --> stack should be '2 3' -drop - -# test symbol entry 5 '' -> stack should be '' drop -# test symbol entry 6 +# test symbol entry 4 ' -> stack should be '' drop @@ -216,9 +206,9 @@ drop drop # if-then-else-end test 8 -0 if then 0 if then 'ok' else 0 end else 'OK !' end +0 if then 0 if then 'ok' else 0 end else 'OK' end -> stack size should be 1 --> stack should be 'OK !' +-> stack should be 'OK' drop # start-next-step test 1