2015-02-24 14:51:39 +01:00
|
|
|
//
|
|
|
|
void eval(void)
|
|
|
|
{
|
2015-03-03 11:43:12 +01:00
|
|
|
bool run_prog = false;
|
|
|
|
string prog_text;
|
|
|
|
|
|
|
|
MIN_ARGUMENTS(1);
|
2015-05-19 17:51:03 +02:00
|
|
|
if (IS_ARG_TYPE(0, cmd_symbol))
|
|
|
|
{
|
|
|
|
// recall a variable
|
|
|
|
void* obj;
|
|
|
|
unsigned int size;
|
|
|
|
int type;
|
2015-02-26 22:33:28 +01:00
|
|
|
string variable(((symbol*)_stack->back())->_value);
|
2015-03-04 17:01:30 +01:00
|
|
|
|
|
|
|
// mind the order of heaps
|
|
|
|
if (_local_heap.get(variable, obj, size, type)
|
|
|
|
|| ((_parent_local_heap != NULL) && _parent_local_heap->get(variable, obj, size, type))
|
|
|
|
|| _global_heap->get(variable, obj, size, type))
|
2015-05-19 17:51:03 +02:00
|
|
|
{
|
2015-03-03 11:43:12 +01:00
|
|
|
// if variable holds a program, run this program
|
|
|
|
if (type == cmd_program)
|
|
|
|
{
|
|
|
|
prog_text = ((oprogram*)obj)->_value;
|
|
|
|
_stack->pop_back();
|
|
|
|
run_prog = true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// else recall variable (i.e. stack its content)
|
|
|
|
_stack->pop_back();
|
|
|
|
_stack->push_back(obj, size, type);
|
|
|
|
}
|
2015-05-19 17:51:03 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
ERR_CONTEXT(ret_unknown_variable);
|
|
|
|
}
|
|
|
|
else if (IS_ARG_TYPE(0, cmd_program))
|
|
|
|
{
|
|
|
|
// eval a program
|
2015-03-03 11:43:12 +01:00
|
|
|
prog_text = ((oprogram*)_stack->back())->_value;
|
2015-05-19 17:51:03 +02:00
|
|
|
_stack->pop_back();
|
2015-03-03 11:43:12 +01:00
|
|
|
run_prog = true;
|
2015-05-19 17:51:03 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
ERR_CONTEXT(ret_bad_operand_type);
|
2015-03-03 11:43:12 +01:00
|
|
|
|
|
|
|
// run prog if any
|
|
|
|
if (run_prog)
|
|
|
|
{
|
|
|
|
program prog;
|
|
|
|
|
|
|
|
// make program from entry
|
|
|
|
if (program::parse(prog_text.c_str(), prog) == ret_ok)
|
|
|
|
{
|
|
|
|
// run it
|
2015-03-04 17:01:30 +01:00
|
|
|
prog.run(*_stack, *_global_heap, &_local_heap);
|
2015-03-03 11:43:12 +01:00
|
|
|
}
|
|
|
|
}
|
2015-02-24 14:51:39 +01:00
|
|
|
}
|
2015-02-25 15:39:27 +01:00
|
|
|
|
|
|
|
// carefull, this not a command but a branch
|
|
|
|
int inprog(branch& myobj)
|
|
|
|
{
|
|
|
|
string context("->");// for showing errors
|
|
|
|
int count_symbols = 0;
|
|
|
|
bool prog_found = false;
|
|
|
|
|
|
|
|
if (myobj.arg1 == -1)
|
|
|
|
{
|
|
|
|
ERR_CONTEXT(ret_unknown_err);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// syntax must be
|
|
|
|
// -> <auto evaluated symbol #1> ... <auto evaluated symbol #n> <oprogram>
|
|
|
|
|
|
|
|
// find next oprogram object
|
|
|
|
for (unsigned int i = myobj.arg1 + 1; i < size(); i++)
|
|
|
|
{
|
|
|
|
// count symbol
|
|
|
|
if (seq_type(i) == cmd_symbol)
|
|
|
|
count_symbols++;
|
|
|
|
// stop if prog
|
|
|
|
else if (seq_type(i) == cmd_program)
|
|
|
|
{
|
|
|
|
prog_found = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
// found something other than symbol
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ERR_CONTEXT(ret_bad_operand_type);
|
|
|
|
show_error(_err, context);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// found 0 symbols
|
|
|
|
if (count_symbols == 0)
|
|
|
|
{
|
|
|
|
ERR_CONTEXT(ret_syntax);
|
|
|
|
show_error(_err, context);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// <oprogram> is missing
|
|
|
|
if (! prog_found)
|
|
|
|
{
|
|
|
|
ERR_CONTEXT(ret_syntax);
|
|
|
|
show_error(_err, context);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// check symbols number vs stack size
|
|
|
|
if (stack_size() < count_symbols)
|
|
|
|
{
|
|
|
|
ERR_CONTEXT(ret_missing_operand);
|
|
|
|
show_error(_err, context);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// load variables
|
2015-03-03 18:16:56 +01:00
|
|
|
heap local_heap;
|
2015-02-25 15:39:27 +01:00
|
|
|
for (unsigned int i = myobj.arg1 + count_symbols; i > myobj.arg1; i--)
|
|
|
|
{
|
2015-03-03 18:16:56 +01:00
|
|
|
local_heap.add(string(((symbol*)seq_obj(i))->_value), _stack->get_obj(0), _stack->get_len(0), _stack->get_type(0));
|
2015-02-25 15:39:27 +01:00
|
|
|
_stack->pop_back();
|
|
|
|
}
|
|
|
|
|
|
|
|
// run the program
|
2015-02-26 22:33:28 +01:00
|
|
|
string entry(((oprogram*)seq_obj(myobj.arg1 + count_symbols + 1))->_value);
|
2015-02-25 15:39:27 +01:00
|
|
|
program prog;
|
|
|
|
|
|
|
|
// make the program from entry
|
2015-02-26 22:33:28 +01:00
|
|
|
if (program::parse(entry.c_str(), prog) == ret_ok)
|
2015-02-25 15:39:27 +01:00
|
|
|
{
|
|
|
|
// run it
|
2015-03-03 18:16:56 +01:00
|
|
|
prog.run(*_stack, *_global_heap, &local_heap);
|
2015-02-25 15:39:27 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// point on next command
|
|
|
|
return myobj.arg1 + count_symbols + 2;
|
|
|
|
}
|