mirror of
https://github.com/louisrubet/rpn
synced 2025-01-05 11:01:52 +01:00
Merge branch 'c_strings'
Conflicts: src/rpn.cpp
This commit is contained in:
commit
14ea7d2b74
16 changed files with 779 additions and 320 deletions
259
README
259
README
|
@ -24,39 +24,202 @@ Language extensions will soon be included:
|
||||||
========================================================================
|
========================================================================
|
||||||
Here is a list of HP28s reserved words.
|
Here is a list of HP28s reserved words.
|
||||||
|
|
||||||
New commands (nonexistent in RPL) are tagged with (+).
|
New commands (nonexistent in RPL) are tagged with * in column new.
|
||||||
Already implemented commands are tagged with (*).
|
Already implemented commands are tagged with * in column impl.
|
||||||
|
Tested commands are tagged with * in column tested.
|
||||||
|
|
||||||
GENERAL OPERATIONS
|
category command new impl. tested
|
||||||
+(*), -(*), neg(*), *(*), /(*), inv(*)(+), %(*), %CH(*), ^(*),
|
|
||||||
sqrt(*)(+), sq(*)(+), test(*)(+)
|
|
||||||
|
|
||||||
GENERAL (some are 'CURSOR' commands)
|
GENERAL + *
|
||||||
verbose(*)(+), std(*), fix(*), sci(*), version(*)(+), uname(*)(+)
|
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
|
STACK drop *
|
||||||
drop(*), swap(*), roll, dup(*), over, dup2(*), drop2(*), rot(*),
|
STACK swap *
|
||||||
list->, rolld, pick(*), dupn, dropn, depth(*), ->list, load_stack(+),
|
STACK roll
|
||||||
save_stack(+)
|
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
|
STORE
|
||||||
sto(*), rcl(*), purge(*), sto+, sto-, sto*, sto/, sneg, sinv, sconj,
|
STORE sto *
|
||||||
erase(*)(+), vars(*)(+), include(+), load_vars(+), save_vars(+)
|
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(+)
|
PROGRAM eval *
|
||||||
eval(*), load_prog(+), save_prog(+)
|
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
|
MEMORY
|
||||||
mem, menu, order, path, home, crdir, vars, clusr
|
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
|
|
||||||
|
|
||||||
STAT
|
STAT
|
||||||
∑dat, ∑par, ∑+, ∑-, n∑, cl∑, sto∑, rcl∑, tot, mean, sdev, var, max∑,
|
∑dat, ∑par, ∑+, ∑-, n∑, cl∑, sto∑, rcl∑, tot, mean, sdev, var, max∑,
|
||||||
|
@ -65,39 +228,6 @@ STAT
|
||||||
PRINT
|
PRINT
|
||||||
pr1, prst, prvar, prlcd, cr, trac, prstc, prusr, prmd
|
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
|
SOLV
|
||||||
steq, rceq, isol, quad, show, root,
|
steq, rceq, isol, quad, show, root,
|
||||||
|
|
||||||
|
@ -105,6 +235,19 @@ PLOT
|
||||||
ppar, steq, rceq, pmin, pmax, indep, draw, res, axes, centr, *w, *h,
|
ppar, steq, rceq, pmin, pmax, indep, draw, res, axes, centr, *w, *h,
|
||||||
sto∑, rcl∑, col∑, scl∑, drw∑, cllcd, digtiz
|
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
|
CUSTOM
|
||||||
menu, custom
|
menu, custom
|
||||||
|
|
||||||
|
|
41
src/debug.h
Normal file
41
src/debug.h
Normal file
|
@ -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");
|
||||||
|
}
|
333
src/parse.h
333
src/parse.h
|
@ -1,15 +1,43 @@
|
||||||
static bool _cut(const string& entry, vector<string>& 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; (i<sizeof(_keywords)/sizeof(_keywords[0])) && (_keywords[i].type != cmd_max); i++)
|
||||||
|
{
|
||||||
|
if ((strnlen(_keywords[i].name, sizeof(_keywords[i].name))>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;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool _cut(const char* entry, vector<string>& entries)
|
||||||
{
|
{
|
||||||
string tmp;
|
string tmp;
|
||||||
|
//TODO borner
|
||||||
|
int len = strlen(entry);
|
||||||
|
|
||||||
for (int i=0; i<entry.size(); i++)
|
for (int i=0; i < len; i++)
|
||||||
{
|
{
|
||||||
switch(entry.at(i))
|
switch(entry[i])
|
||||||
{
|
{
|
||||||
//symbol
|
//symbol
|
||||||
case '\'':
|
case '\'':
|
||||||
//push prec entry if exists
|
//push prec entry if exists
|
||||||
if (tmp.size()>0)
|
if (tmp.size() > 0)
|
||||||
{
|
{
|
||||||
entries.push_back(tmp);
|
entries.push_back(tmp);
|
||||||
tmp.clear();
|
tmp.clear();
|
||||||
|
@ -17,10 +45,10 @@ static bool _cut(const string& entry, vector<string>& entries)
|
||||||
//get symbol
|
//get symbol
|
||||||
tmp='\'';
|
tmp='\'';
|
||||||
i++;
|
i++;
|
||||||
while((i<entry.size()) && (isalnum(entry.at(i)) || entry.at(i)=='_'))
|
while((i < len) && (isalnum(entry[i]) || entry[i]=='_'))
|
||||||
tmp+=entry.at(i++);
|
tmp += entry[i++];
|
||||||
if ((i<entry.size()) && entry.at(i)=='\'')
|
if ((i < len) && entry[i] == '\'')
|
||||||
tmp+='\'';
|
tmp += '\'';
|
||||||
entries.push_back(tmp);
|
entries.push_back(tmp);
|
||||||
tmp.clear();
|
tmp.clear();
|
||||||
break;
|
break;
|
||||||
|
@ -28,7 +56,7 @@ static bool _cut(const string& entry, vector<string>& entries)
|
||||||
//string
|
//string
|
||||||
case '"':
|
case '"':
|
||||||
//push prec entry if exists
|
//push prec entry if exists
|
||||||
if (tmp.size()>0)
|
if (tmp.size() > 0)
|
||||||
{
|
{
|
||||||
entries.push_back(tmp);
|
entries.push_back(tmp);
|
||||||
tmp.clear();
|
tmp.clear();
|
||||||
|
@ -36,10 +64,10 @@ static bool _cut(const string& entry, vector<string>& entries)
|
||||||
//get expression
|
//get expression
|
||||||
tmp='"';
|
tmp='"';
|
||||||
i++;
|
i++;
|
||||||
while(i<entry.size() && entry.at(i)>=' ')
|
while(i < len && entry[i] >= ' ')
|
||||||
{
|
{
|
||||||
tmp+=entry.at(i);
|
tmp += entry[i];
|
||||||
if (entry.at(i++) == '"')
|
if (entry[i++] == '"')
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
entries.push_back(tmp);
|
entries.push_back(tmp);
|
||||||
|
@ -55,35 +83,37 @@ static bool _cut(const string& entry, vector<string>& entries)
|
||||||
tmp.clear();
|
tmp.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entry.substr(i, 2) == "<<")
|
if (strncmp(&entry[i], "<<", 2) == 0)
|
||||||
{
|
{
|
||||||
int up = 1;
|
int up = 1;
|
||||||
|
|
||||||
// found a program begin
|
// found a program begin
|
||||||
i+=2;
|
i += 2;
|
||||||
tmp="<< ";
|
tmp = "<< ";
|
||||||
|
|
||||||
// trim leading spaces
|
// trim leading spaces
|
||||||
while (i<entry.size() && (entry.at(i)==' ' || entry.at(i)=='\t'))
|
while (i < len && (entry[i]==' ' || entry[i]=='\t'))
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
while(i<entry.size())
|
while(i < len)
|
||||||
{
|
{
|
||||||
if (entry.substr(i, 2) == "<<")
|
if (strncmp(&entry[i], "<<", 2) == 0)
|
||||||
{
|
{
|
||||||
up++;
|
up++;
|
||||||
i+=2;
|
i += 2;
|
||||||
tmp+=" << ";
|
tmp += " << ";
|
||||||
// trim leading spaces
|
// trim leading spaces
|
||||||
while (i<entry.size() && (entry.at(i)==' ' || entry.at(i)=='\t'))
|
while (i < len && (entry[i] == ' ' || entry[i] == '\t'))
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
else if (entry.substr(i, 2) == ">>")
|
else if (strncmp(&entry[i], ">>", 2) == 0)
|
||||||
{
|
{
|
||||||
up--;
|
up--;
|
||||||
i+=2;
|
i += 2;
|
||||||
tmp+=" >>";
|
tmp += " >>";
|
||||||
|
|
||||||
// trim trailing spaces
|
// trim trailing spaces
|
||||||
while (i<entry.size() && (entry.at(i)==' ' || entry.at(i)=='\t'))
|
while (i < len && (entry[i] == ' ' || entry[i] == '\t'))
|
||||||
i++;
|
i++;
|
||||||
// found end
|
// found end
|
||||||
if (up == 0)
|
if (up == 0)
|
||||||
|
@ -91,7 +121,7 @@ static bool _cut(const string& entry, vector<string>& entries)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
tmp+=entry[i];
|
tmp += entry[i];
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -114,9 +144,9 @@ static bool _cut(const string& entry, vector<string>& entries)
|
||||||
|
|
||||||
//other
|
//other
|
||||||
default:
|
default:
|
||||||
if (entry.at(i)!=' ' && entry.at(i)!='\t')
|
if (entry[i] != ' ' && entry[i] != '\t')
|
||||||
{
|
{
|
||||||
tmp+=entry.at(i);
|
tmp += entry[i];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -147,14 +177,18 @@ static bool get_keyword(const string& entry, object*& obj, unsigned int& obj_siz
|
||||||
{
|
{
|
||||||
if (type == cmd_keyword)
|
if (type == cmd_keyword)
|
||||||
{
|
{
|
||||||
obj = new keyword(fn, (string&)entry);
|
// allocate keyword object
|
||||||
obj_size = sizeof(keyword);
|
obj_size = sizeof(keyword)+entry.size()+1;
|
||||||
|
obj = (object*)malloc(obj_size);
|
||||||
|
((keyword*)obj)->set(fn, entry.c_str(), entry.size());
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
else if (type == cmd_branch)
|
else if (type == cmd_branch)
|
||||||
{
|
{
|
||||||
obj = new branch((branch_fn_t)fn, (string&)entry);
|
// allocate branch object
|
||||||
obj_size = sizeof(branch);
|
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;
|
ret = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -162,53 +196,147 @@ static bool get_keyword(const string& entry, object*& obj, unsigned int& obj_siz
|
||||||
return ret;
|
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;
|
bool ret = false;
|
||||||
int len = entry.size();
|
int entry_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;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool get_string(const string& entry, object*& obj)
|
if (entry_len>=1 && entry[0]=='\'')
|
||||||
{
|
|
||||||
bool ret = false;
|
|
||||||
int len = entry.size();
|
|
||||||
if (len>1 && entry[0]=='\"')
|
|
||||||
{
|
{
|
||||||
int last = entry[len-1]=='\"'?(len-2):(len-1);
|
// symbol entry, like 'toto'
|
||||||
obj = new ostring(entry.substr(1, last).c_str());
|
if (entry_len == 1)
|
||||||
ret = true;
|
{
|
||||||
}
|
// total object length
|
||||||
return ret;
|
obj_len = sizeof(symbol)+1;
|
||||||
}
|
|
||||||
|
|
||||||
static bool get_program(const string& entry, object*& obj)
|
// allocate object
|
||||||
{
|
obj = (symbol*)malloc(obj_len);
|
||||||
bool ret = false;
|
|
||||||
int len = entry.size();
|
//set it
|
||||||
if (len>=2 && entry[0]=='<' && entry[1]=='<')
|
((symbol*)obj)->set("", 0);
|
||||||
{
|
}
|
||||||
int last;
|
|
||||||
if (len>=4 && entry[len-1]=='>' && entry[len-2]=='>')
|
|
||||||
last = len-4;
|
|
||||||
else
|
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;
|
ret = true;
|
||||||
}
|
}
|
||||||
return ret;
|
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;
|
floating_t val;
|
||||||
|
stringstream token;
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|
||||||
token<<entry;
|
token<<entry;
|
||||||
|
@ -216,17 +344,22 @@ static bool get_float(const string& entry, object*& obj)
|
||||||
|
|
||||||
if ( (!token.fail()) && (!token.bad()) )
|
if ( (!token.fail()) && (!token.bad()) )
|
||||||
{
|
{
|
||||||
obj = new number(val);
|
new_number.set(val);
|
||||||
|
obj = &new_number;
|
||||||
|
obj_size = sizeof(number);
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool get_binary(const string& entry, object*& obj)
|
// care: not threadsafe
|
||||||
|
static bool get_binary(const string& entry, object*& obj, unsigned int& obj_size)
|
||||||
{
|
{
|
||||||
|
static binary new_binary;
|
||||||
integer_t val;
|
integer_t val;
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|
||||||
if ((entry.size() >= 2) && (entry[0] == '#'))
|
if ((entry.size() >= 2) && (entry[0] == '#'))
|
||||||
{
|
{
|
||||||
stringstream token;
|
stringstream token;
|
||||||
|
@ -255,7 +388,9 @@ static bool get_binary(const string& entry, object*& obj)
|
||||||
token>>val;
|
token>>val;
|
||||||
if(syntax && !token.fail())
|
if(syntax && !token.fail())
|
||||||
{
|
{
|
||||||
obj = new binary(val);
|
new_binary.set(val);
|
||||||
|
obj = &new_binary;
|
||||||
|
obj_size = sizeof(binary);
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -263,8 +398,10 @@ static bool get_binary(const string& entry, object*& obj)
|
||||||
return ret;
|
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;
|
integer_t val;
|
||||||
int len = entry.size();
|
int len = entry.size();
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
@ -281,7 +418,9 @@ static bool get_binary_bin(const string& entry, object*& obj)
|
||||||
exponent/=2;
|
exponent/=2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
obj = new binary(val);
|
new_binary.set(val);
|
||||||
|
obj = &new_binary;
|
||||||
|
obj_size = sizeof(binary);
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -292,40 +431,34 @@ static bool _obj_from_string(const string& entry, object*& obj, unsigned int& ob
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|
||||||
if (get_float(entry, obj))
|
if (get_float(entry, obj, obj_size))
|
||||||
{
|
{
|
||||||
type = cmd_number;
|
type = cmd_number;
|
||||||
obj_size = sizeof(number);
|
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
else if (get_binary(entry, obj))
|
else if (get_binary(entry, obj, obj_size))
|
||||||
{
|
{
|
||||||
type = cmd_binary;
|
type = cmd_binary;
|
||||||
obj_size = sizeof(binary);
|
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
else if (get_binary_bin(entry, obj))
|
else if (get_binary_bin(entry, obj, obj_size))
|
||||||
{
|
{
|
||||||
type = cmd_binary;
|
type = cmd_binary;
|
||||||
obj_size = sizeof(binary);
|
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
else if (get_symbol(entry, obj))
|
else if (get_symbol(entry, obj, obj_size))
|
||||||
{
|
{
|
||||||
type = cmd_symbol;
|
type = cmd_symbol;
|
||||||
obj_size = sizeof(symbol);
|
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
else if (get_string(entry, obj))
|
else if (get_string(entry, obj, obj_size))
|
||||||
{
|
{
|
||||||
type = cmd_string;
|
type = cmd_string;
|
||||||
obj_size = sizeof(ostring);
|
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
else if (get_program(entry, obj))
|
else if (get_program(entry, obj, obj_size))
|
||||||
{
|
{
|
||||||
type = cmd_program;
|
type = cmd_program;
|
||||||
obj_size = sizeof(oprogram);
|
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
else if (get_keyword(entry, obj, obj_size, type))
|
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
|
else
|
||||||
{
|
{
|
||||||
// nothing, considered as an auto-evaluated symbol
|
// nothing, considered as an auto-evaluated symbol
|
||||||
obj = new symbol((string&)entry);
|
if (get_other(entry, obj, obj_size, type))
|
||||||
((symbol*)obj)->_auto_eval = true;
|
{
|
||||||
obj_size = sizeof(symbol);
|
ret = true;
|
||||||
type = cmd_symbol;
|
}
|
||||||
ret = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
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 char* entry_completion_generator(const char* text, int state)
|
||||||
{
|
{
|
||||||
static int list_index, len, too_far;
|
static int list_index, len, too_far;
|
||||||
|
@ -386,7 +534,7 @@ static char* entry_completion_dupstr(char* s)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ret_value parse(const string& entry, program& prog)
|
static ret_value parse(const char* entry, program& prog)
|
||||||
{
|
{
|
||||||
vector<string> entries;
|
vector<string> entries;
|
||||||
ret_value ret = ret_ok;
|
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))
|
if(_obj_from_string((*it), obj, obj_size, type))
|
||||||
{
|
{
|
||||||
prog.push_back(obj, obj_size, type);
|
prog.push_back(obj, obj_size, type);
|
||||||
|
_delete_obj_from_string(obj);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -417,7 +566,7 @@ static ret_value parse(const string& entry, program& prog)
|
||||||
// interactive entry and decoding
|
// interactive entry and decoding
|
||||||
static ret_value entry(program& prog)
|
static ret_value entry(program& prog)
|
||||||
{
|
{
|
||||||
char *buf;
|
char* buf;
|
||||||
ret_value ret;
|
ret_value ret;
|
||||||
|
|
||||||
// declare completion fn (bound to '\t' by default)
|
// declare completion fn (bound to '\t' by default)
|
||||||
|
@ -427,10 +576,8 @@ static ret_value entry(program& prog)
|
||||||
buf = readline(prompt);
|
buf = readline(prompt);
|
||||||
if (buf != NULL)
|
if (buf != NULL)
|
||||||
{
|
{
|
||||||
string entry(buf);
|
|
||||||
|
|
||||||
// parse it
|
// parse it
|
||||||
ret = parse(entry, prog);
|
ret = parse(buf, prog);
|
||||||
|
|
||||||
// keep history
|
// keep history
|
||||||
if (buf[0]!=0)
|
if (buf[0]!=0)
|
||||||
|
|
|
@ -16,7 +16,9 @@ void plus()
|
||||||
//TODO really too slow
|
//TODO really too slow
|
||||||
putb(getb() + getb());
|
putb(getb() + getb());
|
||||||
}
|
}
|
||||||
// string
|
//TODO
|
||||||
|
#if 0
|
||||||
|
// string
|
||||||
else if (IS_ARG_TYPE(0, cmd_string))
|
else if (IS_ARG_TYPE(0, cmd_string))
|
||||||
{
|
{
|
||||||
ARG_MUST_BE_OF_TYPE(1, cmd_string);
|
ARG_MUST_BE_OF_TYPE(1, cmd_string);
|
||||||
|
@ -24,6 +26,7 @@ void plus()
|
||||||
_stack->pop_back();
|
_stack->pop_back();
|
||||||
*((ostring*)_stack->back())->_value += second;
|
*((ostring*)_stack->back())->_value += second;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
else
|
else
|
||||||
ERR_CONTEXT(ret_bad_operand_type);
|
ERR_CONTEXT(ret_bad_operand_type);
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,8 +23,9 @@ void rtob()
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||||
|
|
||||||
binary bin((integer_t)getf());
|
binary bin;
|
||||||
_stack->push_back(&bin, sizeof(binary), cmd_binary);
|
bin.set(((integer_t)getf()));
|
||||||
|
_stack->push_back(&bin, bin.size(), cmd_binary);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -70,8 +70,9 @@ int rpn_for(branch& myobj)
|
||||||
myobj.farg1 = getf();
|
myobj.farg1 = getf();
|
||||||
|
|
||||||
// store symbol with first value
|
// store symbol with first value
|
||||||
number num(myobj.farg1);
|
number num;
|
||||||
_heap->add(*sym->_value, &num, sizeof(number), cmd_number);
|
num.set(myobj.farg1);
|
||||||
|
_heap->add(string(sym->_value), &num, num.size(), cmd_number);
|
||||||
|
|
||||||
return myobj.arg1 + 1;
|
return myobj.arg1 + 1;
|
||||||
}
|
}
|
||||||
|
@ -98,7 +99,7 @@ int rpn_next(branch& myobj)
|
||||||
int type;
|
int type;
|
||||||
symbol* var = (symbol*)seq_obj(start_or_for->arg1);
|
symbol* var = (symbol*)seq_obj(start_or_for->arg1);
|
||||||
// check symbol variable is a number, then increase
|
// 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;
|
((number*)obj)->_value = myobj.farg1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,7 +144,7 @@ int rpn_step(branch& myobj)
|
||||||
int type;
|
int type;
|
||||||
symbol* var = (symbol*)seq_obj(start_or_for->arg1);
|
symbol* var = (symbol*)seq_obj(start_or_for->arg1);
|
||||||
// check symbol variable is a number, then increase
|
// 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;
|
((number*)obj)->_value = myobj.farg1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ void eval(void)
|
||||||
void* obj;
|
void* obj;
|
||||||
unsigned int size;
|
unsigned int size;
|
||||||
int type;
|
int type;
|
||||||
string& variable = *((symbol*)_stack->back())->_value;
|
string variable(((symbol*)_stack->back())->_value);
|
||||||
if (_heap->get(variable, obj, size, type))
|
if (_heap->get(variable, obj, size, type))
|
||||||
{
|
{
|
||||||
_stack->pop_back();
|
_stack->pop_back();
|
||||||
|
@ -20,13 +20,13 @@ void eval(void)
|
||||||
else if (IS_ARG_TYPE(0, cmd_program))
|
else if (IS_ARG_TYPE(0, cmd_program))
|
||||||
{
|
{
|
||||||
// eval a program
|
// eval a program
|
||||||
string& entry = *((oprogram*)_stack->back())->_value;
|
string entry(((oprogram*)_stack->back())->_value);
|
||||||
_stack->pop_back();
|
_stack->pop_back();
|
||||||
|
|
||||||
program prog;
|
program prog;
|
||||||
|
|
||||||
// make program from entry
|
// make program from entry
|
||||||
if (program::parse(entry, prog) == ret_ok)
|
if (program::parse(entry.c_str(), prog) == ret_ok)
|
||||||
{
|
{
|
||||||
// run it
|
// run it
|
||||||
prog.run(*_stack, *_heap);
|
prog.run(*_stack, *_heap);
|
||||||
|
@ -100,16 +100,16 @@ int inprog(branch& myobj)
|
||||||
// load variables
|
// load variables
|
||||||
for (unsigned int i = myobj.arg1 + count_symbols; i > myobj.arg1; i--)
|
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();
|
_stack->pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
// run the program
|
// 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;
|
program prog;
|
||||||
|
|
||||||
// make the program from entry
|
// make the program from entry
|
||||||
if (program::parse(entry, prog) == ret_ok)
|
if (program::parse(entry.c_str(), prog) == ret_ok)
|
||||||
{
|
{
|
||||||
// run it
|
// run it
|
||||||
prog.run(*_stack, *_heap);
|
prog.run(*_stack, *_heap);
|
||||||
|
|
|
@ -76,6 +76,7 @@ void rot(void)
|
||||||
|
|
||||||
void depth(void)
|
void depth(void)
|
||||||
{
|
{
|
||||||
number num((floating_t)_stack->size());
|
number num;
|
||||||
_stack->push_back(&num, sizeof(number), cmd_number);
|
num.set((floating_t)_stack->size());
|
||||||
|
_stack->push_back(&num, num.size(), cmd_number);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,8 @@ void sto(void)
|
||||||
MIN_ARGUMENTS(2);
|
MIN_ARGUMENTS(2);
|
||||||
ARG_MUST_BE_OF_TYPE(0, cmd_symbol);
|
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));
|
_heap->add(name, _stack->get_obj(0), _stack->get_len(0), _stack->get_type(0));
|
||||||
_stack->pop_back();
|
_stack->pop_back();
|
||||||
}
|
}
|
||||||
|
@ -18,7 +19,7 @@ void rcl(void)
|
||||||
void* obj;
|
void* obj;
|
||||||
unsigned int size;
|
unsigned int size;
|
||||||
int type;
|
int type;
|
||||||
string& variable = *((symbol*)_stack->back())->_value;
|
string variable(((symbol*)_stack->back())->_value);
|
||||||
if (_heap->get(variable, obj, size, type))
|
if (_heap->get(variable, obj, size, type))
|
||||||
{
|
{
|
||||||
_stack->pop_back();
|
_stack->pop_back();
|
||||||
|
@ -36,13 +37,13 @@ void auto_rcl(symbol* symb)
|
||||||
void* obj;
|
void* obj;
|
||||||
unsigned int size;
|
unsigned int size;
|
||||||
int type;
|
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);
|
_stack->push_back(obj, size, type);
|
||||||
else
|
else
|
||||||
_stack->push_back(symb, sizeof(symbol), cmd_symbol);
|
_stack->push_back(symb, symb->size(), cmd_symbol);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
_stack->push_back(symb, sizeof(symbol), cmd_symbol);
|
_stack->push_back(symb, symb->size(), cmd_symbol);
|
||||||
}
|
}
|
||||||
|
|
||||||
void purge(void)
|
void purge(void)
|
||||||
|
@ -50,8 +51,11 @@ void purge(void)
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
ARG_MUST_BE_OF_TYPE(0, cmd_symbol);
|
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);
|
ERR_CONTEXT(ret_unknown_variable);
|
||||||
|
else
|
||||||
|
_stack->pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
void vars(void)
|
void vars(void)
|
||||||
|
|
|
@ -9,23 +9,24 @@ void instr()
|
||||||
((object*)_stack->back())->show(out);
|
((object*)_stack->back())->show(out);
|
||||||
_stack->pop_back();
|
_stack->pop_back();
|
||||||
|
|
||||||
ostring* str = new ostring(out.str().c_str());
|
ostring str;
|
||||||
_stack->push_back(str, sizeof(ostring), cmd_string);
|
str.set(out.str().c_str(), out.str().size());
|
||||||
|
_stack->push_back(&str, str.size(), cmd_string);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void strout()
|
void strout()
|
||||||
{
|
{
|
||||||
MIN_ARGUMENTS(1);
|
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;
|
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, prog) == ret_ok)
|
if (program::parse(entry.c_str(), prog) == ret_ok)
|
||||||
{
|
{
|
||||||
// run it
|
// run it
|
||||||
prog.run(*_stack, *_heap);
|
prog.run(*_stack, *_heap);
|
||||||
|
|
|
@ -115,7 +115,7 @@ void program::test()
|
||||||
{
|
{
|
||||||
// parse entry and run line
|
// parse entry and run line
|
||||||
program prog;
|
program prog;
|
||||||
ret = program::parse(entry, prog);
|
ret = program::parse(entry.c_str(), prog);
|
||||||
if (ret == ret_ok)
|
if (ret == ret_ok)
|
||||||
{
|
{
|
||||||
// run it
|
// run it
|
||||||
|
|
|
@ -63,11 +63,14 @@ void eq(void)
|
||||||
putf(getf() == first);
|
putf(getf() == first);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
//TODO
|
||||||
|
#if 0
|
||||||
case cmd_symbol:
|
case cmd_symbol:
|
||||||
{
|
{
|
||||||
string first = getn();
|
string first = getn();
|
||||||
putf(getn() == first);
|
putf(getn() == first);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
_stack->pop_back();
|
_stack->pop_back();
|
||||||
|
|
364
src/rpn.cpp
364
src/rpn.cpp
|
@ -43,11 +43,6 @@ using namespace std;
|
||||||
|
|
||||||
#include "stack.h"
|
#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;
|
static int g_verbose = 0;
|
||||||
|
|
||||||
|
@ -106,22 +101,28 @@ typedef union
|
||||||
typedef int (program::*branch_fn_t)(branch&);
|
typedef int (program::*branch_fn_t)(branch&);
|
||||||
|
|
||||||
//
|
//
|
||||||
class object
|
struct object
|
||||||
{
|
{
|
||||||
public:
|
// object type
|
||||||
cmd_type_t _type;// object type
|
cmd_type_t _type;
|
||||||
object(cmd_type_t type = cmd_undef):_type(type) { }
|
|
||||||
|
|
||||||
|
//
|
||||||
void show(ostream& stream = cout);
|
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;
|
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 {
|
typedef enum {
|
||||||
std,
|
std,
|
||||||
fix,
|
fix,
|
||||||
|
@ -133,18 +134,24 @@ public:
|
||||||
// precision
|
// precision
|
||||||
static int s_default_precision;
|
static int s_default_precision;
|
||||||
static int s_current_precision;
|
static int s_current_precision;
|
||||||
};
|
} __attribute__((packed));
|
||||||
number::mode_enum number::s_default_mode = number::std;
|
number::mode_enum number::s_default_mode = number::std;
|
||||||
number::mode_enum number::s_mode = number::s_default_mode;
|
number::mode_enum number::s_mode = number::s_default_mode;
|
||||||
int number::s_default_precision = 20;
|
int number::s_default_precision = 20;
|
||||||
int number::s_current_precision = number::s_default_precision;
|
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;
|
integer_t _value;
|
||||||
|
|
||||||
|
//
|
||||||
|
void set(integer_t value)
|
||||||
|
{
|
||||||
|
_type = cmd_binary;
|
||||||
|
_value = value;
|
||||||
|
}
|
||||||
|
unsigned int size() { return sizeof(binary); }
|
||||||
|
|
||||||
// representation mode
|
// representation mode
|
||||||
typedef enum {
|
typedef enum {
|
||||||
dec,
|
dec,
|
||||||
|
@ -154,61 +161,190 @@ public:
|
||||||
} binary_enum;
|
} binary_enum;
|
||||||
static binary_enum s_default_mode;
|
static binary_enum s_default_mode;
|
||||||
static binary_enum s_mode;
|
static binary_enum s_mode;
|
||||||
};
|
} __attribute__((packed));
|
||||||
binary::binary_enum binary::s_default_mode = binary::dec;
|
binary::binary_enum binary::s_default_mode = binary::dec;
|
||||||
binary::binary_enum binary::s_mode = binary::s_default_mode;
|
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)
|
void set(const char* value, unsigned int len)
|
||||||
{
|
{
|
||||||
_value = new string(value);
|
_type = cmd_string;
|
||||||
}
|
if (value != NULL)
|
||||||
ostring(const char* value, cmd_type_t type = cmd_string) : object(type)
|
{
|
||||||
{
|
if (len>0)
|
||||||
_value = new string(value);
|
(void)memcpy(_value, value, len);
|
||||||
}
|
_value[len] = 0;
|
||||||
string* _value;
|
_len = len;
|
||||||
};
|
}
|
||||||
|
else
|
||||||
|
len = 0;
|
||||||
|
}
|
||||||
|
int size() { return sizeof(ostring)+_len+1; }
|
||||||
|
|
||||||
class oprogram : public ostring
|
//
|
||||||
{
|
unsigned int _len;
|
||||||
public:
|
char _value[0];
|
||||||
oprogram(string& value, cmd_type_t type = cmd_program) : ostring(value, type) { }
|
} __attribute__((packed));
|
||||||
oprogram(const char* value, cmd_type_t type = cmd_program) : ostring(value, type) { }
|
|
||||||
};
|
|
||||||
|
|
||||||
class symbol : public ostring
|
struct oprogram : public object
|
||||||
{
|
{
|
||||||
public:
|
//
|
||||||
symbol(string& value, cmd_type_t type = cmd_symbol) : ostring(value, type), _auto_eval(false) { }
|
void set(const char* value, unsigned int len)
|
||||||
symbol(const char* value, cmd_type_t type = cmd_symbol) : ostring(value, type), _auto_eval(false) { }
|
{
|
||||||
bool _auto_eval;
|
_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
|
//
|
||||||
{
|
unsigned int _len;
|
||||||
public:
|
char _value[0];
|
||||||
keyword(program_fn_t fn, string& value, cmd_type_t type = cmd_keyword) : symbol(value, type) { _fn = fn; }
|
} __attribute__((packed));
|
||||||
program_fn_t _fn;
|
|
||||||
};
|
|
||||||
|
|
||||||
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)
|
void set(const char* value, unsigned int len)
|
||||||
{
|
{
|
||||||
_type = cmd_branch;
|
_type = cmd_symbol;
|
||||||
_fn = fn;
|
_auto_eval = false;
|
||||||
}
|
if (value != NULL)
|
||||||
// branch function
|
{
|
||||||
branch_fn_t _fn;
|
if (len>0)
|
||||||
// args used by cmd_branch cmds
|
(void)memcpy(_value, value, len);
|
||||||
int arg1, arg2, arg3;
|
_value[len] = 0;
|
||||||
floating_t farg1, farg2;
|
_len = len;
|
||||||
bool arg_bool;
|
}
|
||||||
};
|
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<<std::right<<std::setw(8)<<std::dec<<((binary*)this)->_value<<" d"; break;
|
||||||
|
case binary::hex: cout<<std::right<<std::setw(16)<<std::hex<<((binary*)this)->_value<<" h"; break;
|
||||||
|
case binary::oct: cout<<std::right<<std::setw(16)<<std::oct<<((binary*)this)->_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<<std::right<<std::setw(20)<<std::oct<<mybin<<" b";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case cmd_string:
|
||||||
|
stream << "\"" << ((ostring*)this)->_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)
|
void object::show(ostream& stream)
|
||||||
{
|
{
|
||||||
|
@ -305,9 +441,9 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// could be an auto-evaluated symbol
|
// 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++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -364,7 +500,23 @@ public:
|
||||||
return ret;
|
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
|
// for if-then-else-end
|
||||||
vector<struct if_layout_t> vlayout;
|
vector<struct if_layout_t> vlayout;
|
||||||
|
@ -380,9 +532,9 @@ public:
|
||||||
if (type == cmd_keyword)
|
if (type == cmd_keyword)
|
||||||
{
|
{
|
||||||
keyword* k = (keyword*)seq_obj(i);
|
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())
|
if (next >= (int)size())
|
||||||
next = -1;
|
next = -1;
|
||||||
|
|
||||||
|
@ -410,16 +562,16 @@ public:
|
||||||
else if (type == cmd_branch)
|
else if (type == cmd_branch)
|
||||||
{
|
{
|
||||||
branch* k = (branch*)seq_obj(i);
|
branch* k = (branch*)seq_obj(i);
|
||||||
if (k->_value->compare("if") == 0)
|
if (compare_branch(k, "if", 2))
|
||||||
{
|
{
|
||||||
if_layout_t layout;
|
if_layout_t layout;
|
||||||
layout.index_if = i;
|
layout.index_if = i;
|
||||||
vlayout.push_back(layout);
|
vlayout.push_back(layout);
|
||||||
layout_index++;
|
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())
|
if (next >= (int)size())
|
||||||
next = -1;
|
next = -1;
|
||||||
|
|
||||||
|
@ -446,9 +598,9 @@ public:
|
||||||
k->arg1 = next;
|
k->arg1 = next;
|
||||||
k->arg3 = vlayout[layout_index].index_if;
|
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())
|
if (next >= (int)size())
|
||||||
next = -1;
|
next = -1;
|
||||||
|
|
||||||
|
@ -482,16 +634,16 @@ public:
|
||||||
k->arg3 = vlayout[layout_index].index_if;
|
k->arg3 = vlayout[layout_index].index_if;
|
||||||
((branch*)seq_obj(vlayout[layout_index].index_then))->arg2 = next;// fill branch2 (if was false) of 'then'
|
((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);
|
vstartindex.push_back(i);
|
||||||
}
|
}
|
||||||
else if (k->_value->compare("for") == 0)
|
else if (compare_branch(k, "for", 3))
|
||||||
{
|
{
|
||||||
vstartindex.push_back(i);
|
vstartindex.push_back(i);
|
||||||
k->arg1 = i + 1;// arg1 points on symbol variable
|
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)
|
if (vstartindex.size() == 0)
|
||||||
{
|
{
|
||||||
|
@ -502,7 +654,7 @@ public:
|
||||||
k->arg1 = vstartindex[vstartindex.size() - 1];// fill 'next' branch1 = 'start' index
|
k->arg1 = vstartindex[vstartindex.size() - 1];// fill 'next' branch1 = 'start' index
|
||||||
vstartindex.pop_back();
|
vstartindex.pop_back();
|
||||||
}
|
}
|
||||||
else if (k->_value->compare("step") == 0)
|
else if (compare_branch(k, "step", 4))
|
||||||
{
|
{
|
||||||
if (vstartindex.size() == 0)
|
if (vstartindex.size() == 0)
|
||||||
{
|
{
|
||||||
|
@ -513,7 +665,7 @@ public:
|
||||||
k->arg1 = vstartindex[vstartindex.size() - 1];// fill 'step' branch1 = 'start' index
|
k->arg1 = vstartindex[vstartindex.size() - 1];// fill 'step' branch1 = 'start' index
|
||||||
vstartindex.pop_back();
|
vstartindex.pop_back();
|
||||||
}
|
}
|
||||||
else if (k->_value->compare("->") == 0)
|
else if (compare_branch(k, "->", 2))
|
||||||
{
|
{
|
||||||
k->arg1 = i;// arg1 is '->' command index in program
|
k->arg1 = i;// arg1 is '->' command index in program
|
||||||
}
|
}
|
||||||
|
@ -558,31 +710,6 @@ public:
|
||||||
cerr<<"syntax error: "<<context<<endl;
|
cerr<<"syntax error: "<<context<<endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// keywords declaration
|
|
||||||
struct keyword_t
|
|
||||||
{
|
|
||||||
cmd_type_t type;
|
|
||||||
char name[24];
|
|
||||||
program_fn_t fn;
|
|
||||||
string comment;
|
|
||||||
};
|
|
||||||
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; (i<sizeof(_keywords)/sizeof(_keywords[0])) && (_keywords[i].type != cmd_max); i++)
|
|
||||||
{
|
|
||||||
if ((strnlen(_keywords[i].name, sizeof(_keywords[i].name))>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; }
|
ret_value get_err(void) { return _err; }
|
||||||
|
|
||||||
#include "parse.h"
|
#include "parse.h"
|
||||||
|
@ -625,8 +752,9 @@ private:
|
||||||
void putf(floating_t value)
|
void putf(floating_t value)
|
||||||
{
|
{
|
||||||
/* warning, caller must check object type before */
|
/* warning, caller must check object type before */
|
||||||
number num(value);
|
number num;
|
||||||
_stack->push_back(&num, sizeof(number), cmd_number);
|
num.set(value);
|
||||||
|
_stack->push_back(&num, num.size(), cmd_number);
|
||||||
}
|
}
|
||||||
|
|
||||||
integer_t getb()
|
integer_t getb()
|
||||||
|
@ -640,26 +768,12 @@ private:
|
||||||
void putb(integer_t value)
|
void putb(integer_t value)
|
||||||
{
|
{
|
||||||
/* warning, caller must check object type before */
|
/* warning, caller must check object type before */
|
||||||
binary num(value);
|
binary num;
|
||||||
_stack->push_back(&num, sizeof(binary), cmd_binary);
|
num.set(value);
|
||||||
|
_stack->push_back(&num, num.size(), cmd_binary);
|
||||||
}
|
}
|
||||||
|
|
||||||
string getn()
|
int stack_size()
|
||||||
{
|
|
||||||
/* 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()
|
|
||||||
{
|
{
|
||||||
return _stack->size();
|
return _stack->size();
|
||||||
}
|
}
|
||||||
|
@ -748,7 +862,7 @@ int _tmain(int argc, _TCHAR* argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
// make program
|
// make program
|
||||||
ret = program::parse(entry, prog);
|
ret = program::parse(entry.c_str(), prog);
|
||||||
if (ret == ret_ok)
|
if (ret == ret_ok)
|
||||||
{
|
{
|
||||||
string separator = "";
|
string separator = "";
|
||||||
|
|
15
src/stack.h
15
src/stack.h
|
@ -8,6 +8,8 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
#define ALLOC_BLOB (128*1024)
|
#define ALLOC_BLOB (128*1024)
|
||||||
#define LOCAL_COPY_PLACES 3
|
#define LOCAL_COPY_PLACES 3
|
||||||
#define LOCAL_COPY_SIZE 128
|
#define LOCAL_COPY_SIZE 128
|
||||||
|
@ -147,6 +149,11 @@ public:
|
||||||
push_back(&local->blob, local->length, local->type);
|
push_back(&local->blob, local->length, local->type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dump(void)
|
||||||
|
{
|
||||||
|
dump8((unsigned char*)_base, 0, (unsigned long)(_current - _base));
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
char* _base;
|
char* _base;
|
||||||
char* _current;
|
char* _current;
|
||||||
|
@ -186,13 +193,13 @@ public:
|
||||||
//TODO gerer les pbs de memoire
|
//TODO gerer les pbs de memoire
|
||||||
blob = (struct local_var*)malloc(size + sizeof(local_var));
|
blob = (struct local_var*)malloc(size + sizeof(local_var));
|
||||||
_map[name] = blob;
|
_map[name] = blob;
|
||||||
}
|
}
|
||||||
else if (size != blob->length)
|
else if (size != blob->length)
|
||||||
{
|
{
|
||||||
//TODO gerer les pbs de memoire
|
//TODO gerer les pbs de memoire
|
||||||
blob = (struct local_var*)realloc(blob, size + sizeof(local_var));
|
blob = (struct local_var*)realloc(blob, size + sizeof(local_var));
|
||||||
_map[name] = blob;
|
_map[name] = blob;
|
||||||
}
|
}
|
||||||
blob->length = size;
|
blob->length = size;
|
||||||
blob->type= type;
|
blob->type= type;
|
||||||
memcpy(&blob->blob, obj, size);
|
memcpy(&blob->blob, obj, size);
|
||||||
|
@ -244,12 +251,12 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool erase(const string name)
|
bool erase(const string& name)
|
||||||
{
|
{
|
||||||
map<string, struct local_var*>::iterator i = _map.find(name);
|
map<string, struct local_var*>::iterator i = _map.find(name);
|
||||||
if (i != _map.end())
|
if (i != _map.end())
|
||||||
{
|
{
|
||||||
free(i->second);
|
free(i->second);
|
||||||
_map.erase(i->first);
|
_map.erase(i->first);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,9 @@
|
||||||
static const char version[] = "1.4-beta";
|
static const char version[] = "1.4-beta";
|
||||||
static const char uname[] = "rpn v1.4-beta, (c) 2015 <louis@rubet.fr>";
|
static const char uname[] = "rpn v1.4-beta, (c) 2015 <louis@rubet.fr>";
|
||||||
|
|
||||||
|
static const char g_cursor[] = "> ";
|
||||||
|
static const string g_show_stack_separator = "> ";
|
||||||
|
|
||||||
// syntax
|
// syntax
|
||||||
static const char* syntax[] = {
|
static const char* syntax[] = {
|
||||||
"Reverse Polish Notation language, based on hewlett-Packard RPL",
|
"Reverse Polish Notation language, based on hewlett-Packard RPL",
|
||||||
|
|
|
@ -42,21 +42,11 @@ drop2
|
||||||
drop2
|
drop2
|
||||||
|
|
||||||
# test symbol entry 3
|
# 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 ''
|
-> stack should be ''
|
||||||
drop
|
drop
|
||||||
|
|
||||||
# test symbol entry 6
|
# test symbol entry 4
|
||||||
'
|
'
|
||||||
-> stack should be ''
|
-> stack should be ''
|
||||||
drop
|
drop
|
||||||
|
@ -216,9 +206,9 @@ drop
|
||||||
drop
|
drop
|
||||||
|
|
||||||
# if-then-else-end test 8
|
# 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 size should be 1
|
||||||
-> stack should be 'OK !'
|
-> stack should be 'OK'
|
||||||
drop
|
drop
|
||||||
|
|
||||||
# start-next-step test 1
|
# start-next-step test 1
|
||||||
|
|
Loading…
Reference in a new issue