interp/call_fsm wip
oword sub, python oword sub runtests ok remap TBD
This commit is contained in:
parent
5e71ed5ef6
commit
de556674f3
2 changed files with 252 additions and 80 deletions
|
|
@ -142,9 +142,7 @@ enum SPINDLE_MODE { CONSTANT_RPM, CONSTANT_SURFACE };
|
||||||
#define O_return 13
|
#define O_return 13
|
||||||
#define O_repeat 14
|
#define O_repeat 14
|
||||||
#define O_endrepeat 15
|
#define O_endrepeat 15
|
||||||
#define O_remap 16 // not a keyword - just indicates a remap call in progress
|
#define O_continue_call 16 // signal Python handler reexecution
|
||||||
#define O_pycall 17 // like O_call, but o_name is a Python callable
|
|
||||||
#define O_continue_call 18 // signal Python handler reexecution
|
|
||||||
|
|
||||||
// G Codes are symbolic to be dialect-independent in source code
|
// G Codes are symbolic to be dialect-independent in source code
|
||||||
#define G_0 0
|
#define G_0 0
|
||||||
|
|
@ -473,18 +471,20 @@ typedef struct block_struct
|
||||||
int phase; // current remap execution phase
|
int phase; // current remap execution phase
|
||||||
}
|
}
|
||||||
block;
|
block;
|
||||||
|
|
||||||
enum call_states {
|
enum call_states {
|
||||||
CS_START,
|
CS_START,
|
||||||
CS_CALL_PROLOG,
|
CS_CALL_PROLOG,
|
||||||
CS_CONTINUE_PROLOG,
|
CS_CONTINUE_PROLOG,
|
||||||
CS_CALL_BODY,
|
CS_CALL_BODY,
|
||||||
CS_CONTINUE_BODY,
|
CS_EXECUTING_BODY,
|
||||||
CS_CALL_EPILOG,
|
CS_CALL_EPILOG,
|
||||||
CS_CONTINUE_EPILOG,
|
CS_CONTINUE_EPILOG,
|
||||||
CS_CALL_PYBODY,
|
CS_CALL_PYBODY,
|
||||||
CS_CONTINUE_PYBODY,
|
CS_CONTINUE_PYBODY,
|
||||||
CS_CALL_PY_OSUB,
|
CS_CALL_PY_OSUB,
|
||||||
CS_CONTINUE_PY_OSUB,
|
CS_CONTINUE_PY_OSUB,
|
||||||
|
CS_CALL_REMAP,
|
||||||
CS_DONE
|
CS_DONE
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -85,30 +85,29 @@ int Interp::findFile( // ARGUMENTS
|
||||||
int Interp::control_save_offset(block_pointer block, /* pointer to a block of RS274/NGC instructions */
|
int Interp::control_save_offset(block_pointer block, /* pointer to a block of RS274/NGC instructions */
|
||||||
setup_pointer settings) /* pointer to machine settings */
|
setup_pointer settings) /* pointer to machine settings */
|
||||||
{
|
{
|
||||||
static char name[] = "control_save_offset";
|
static char name[] = "control_save_offset";
|
||||||
offset_pointer op = NULL;
|
offset_pointer op = NULL;
|
||||||
|
|
||||||
logOword("Entered:%s for o_name:|%s|", name, block->o_name);
|
logOword("Entered:%s for o_name:|%s|", name, block->o_name);
|
||||||
|
|
||||||
if (control_find_oword(block, settings, &op) == INTERP_OK) {
|
if (control_find_oword(block, settings, &op) == INTERP_OK) {
|
||||||
// already exists
|
// already exists
|
||||||
ERS(_("File:%s line:%d redefining sub: o|%s| already defined in file:%s"),
|
ERS(_("File:%s line:%d redefining sub: o|%s| already defined in file:%s"),
|
||||||
settings->filename, settings->sequence_number,
|
settings->filename, settings->sequence_number,
|
||||||
block->o_name,
|
block->o_name,
|
||||||
op->filename);
|
op->filename);
|
||||||
}
|
}
|
||||||
offset new_offset;
|
offset new_offset;
|
||||||
|
|
||||||
new_offset.type = block->o_type;
|
new_offset.type = block->o_type;
|
||||||
new_offset.offset = block->offset;
|
new_offset.offset = block->offset;
|
||||||
new_offset.filename = strstore(settings->filename);
|
new_offset.filename = strstore(settings->filename);
|
||||||
new_offset.repeat_count = -1;
|
new_offset.repeat_count = -1;
|
||||||
// the sequence number has already been bumped, so save
|
// the sequence number has already been bumped, so save
|
||||||
// the proper value
|
// the proper value
|
||||||
new_offset.sequence_number = settings->sequence_number - 1;
|
new_offset.sequence_number = settings->sequence_number - 1;
|
||||||
settings->offset_map[block->o_name] = new_offset;
|
settings->offset_map[block->o_name] = new_offset;
|
||||||
|
return INTERP_OK;
|
||||||
return INTERP_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -382,7 +381,7 @@ int Interp::execute_call(setup_pointer settings, int what)
|
||||||
} // end case
|
} // end case
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
int Interp::execute_return(setup_pointer settings, int what) // pointer to machine settings
|
int Interp::execute_return(setup_pointer settings, int what) // pointer to machine settings
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
@ -419,37 +418,37 @@ int Interp::execute_return(setup_pointer settings, int what) // pointer to mac
|
||||||
// we call the epilog handler while the current frame is still alive
|
// we call the epilog handler while the current frame is still alive
|
||||||
// so we can inspect it from the epilog
|
// so we can inspect it from the epilog
|
||||||
|
|
||||||
if (HAS_PYTHON_EPILOG(cblock->executing_remap)) {
|
// if (HAS_PYTHON_EPILOG(cblock->executing_remap)) {
|
||||||
// FIXME not necessarily an NGC remap!
|
// // FIXME not necessarily an NGC remap!
|
||||||
logRemap("O_endsub/return: epilog %s for NGC remap %s cl=%d rl=%d",
|
// logRemap("O_endsub/return: epilog %s for NGC remap %s cl=%d rl=%d",
|
||||||
cblock->executing_remap->epilog_func,
|
// cblock->executing_remap->epilog_func,
|
||||||
cblock->executing_remap->remap_ngc,settings->call_level,
|
// cblock->executing_remap->remap_ngc,settings->call_level,
|
||||||
settings->remap_level);
|
// settings->remap_level);
|
||||||
status = pycall(settings,leaving_frame,
|
// status = pycall(settings,leaving_frame,
|
||||||
REMAP_MODULE,
|
// REMAP_MODULE,
|
||||||
cblock->executing_remap->epilog_func,
|
// cblock->executing_remap->epilog_func,
|
||||||
PY_EPILOG);
|
// PY_EPILOG);
|
||||||
if (status > INTERP_MIN_ERROR) {
|
// if (status > INTERP_MIN_ERROR) {
|
||||||
logRemap("O_endsub/return: epilog %s failed, unwinding",
|
// logRemap("O_endsub/return: epilog %s failed, unwinding",
|
||||||
cblock->executing_remap->epilog_func);
|
// cblock->executing_remap->epilog_func);
|
||||||
ERP(status);
|
// ERP(status);
|
||||||
}
|
// }
|
||||||
if (status == INTERP_EXECUTE_FINISH) {
|
// if (status == INTERP_EXECUTE_FINISH) {
|
||||||
leaving_frame->call_phase = FINISH_EPILOG;
|
// leaving_frame->call_phase = FINISH_EPILOG;
|
||||||
logRemap("O_endsub/return: epilog %s INTERP_EXECUTE_FINISH, mark for restart, cl=%d rl=%d",
|
// logRemap("O_endsub/return: epilog %s INTERP_EXECUTE_FINISH, mark for restart, cl=%d rl=%d",
|
||||||
cblock->executing_remap->epilog_func,
|
// cblock->executing_remap->epilog_func,
|
||||||
settings->call_level,settings->remap_level);
|
// settings->call_level,settings->remap_level);
|
||||||
return INTERP_EXECUTE_FINISH;
|
// return INTERP_EXECUTE_FINISH;
|
||||||
}
|
// }
|
||||||
if (status == INTERP_OK) {
|
// if (status == INTERP_OK) {
|
||||||
if (leaving_frame->call_phase == FINISH_EPILOG) {
|
// if (leaving_frame->call_phase == FINISH_EPILOG) {
|
||||||
leaving_frame->call_phase = NONE;
|
// leaving_frame->call_phase = NONE;
|
||||||
logRemap("O_call: epilog %s done after restart cl=%d rl=%d",
|
// logRemap("O_call: epilog %s done after restart cl=%d rl=%d",
|
||||||
cblock->executing_remap->epilog_func,
|
// cblock->executing_remap->epilog_func,
|
||||||
settings->call_level,settings->remap_level);
|
// settings->call_level,settings->remap_level);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
// free local variables
|
// free local variables
|
||||||
free_named_parameters(leaving_frame);
|
free_named_parameters(leaving_frame);
|
||||||
|
|
@ -508,7 +507,7 @@ int Interp::execute_return(setup_pointer settings, int what) // pointer to mac
|
||||||
} else {
|
} else {
|
||||||
settings->sub_name = NULL;
|
settings->sub_name = NULL;
|
||||||
}
|
}
|
||||||
} else {
|
} else { // call_level == 0
|
||||||
// a definition
|
// a definition
|
||||||
if (eblock->o_type == O_endsub) {
|
if (eblock->o_type == O_endsub) {
|
||||||
CHKS((settings->defining_sub != 1), NCE_NOT_IN_SUBROUTINE_DEFN);
|
CHKS((settings->defining_sub != 1), NCE_NOT_IN_SUBROUTINE_DEFN);
|
||||||
|
|
@ -525,7 +524,6 @@ int Interp::execute_return(setup_pointer settings, int what) // pointer to mac
|
||||||
} // end case
|
} // end case
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// TESTME!!! MORE THOROUGHLY !!!KL
|
// TESTME!!! MORE THOROUGHLY !!!KL
|
||||||
|
|
@ -625,8 +623,6 @@ static const char *o_ops[] = {
|
||||||
"O_return",
|
"O_return",
|
||||||
"O_repeat",
|
"O_repeat",
|
||||||
"O_endrepeat",
|
"O_endrepeat",
|
||||||
"O_remap",
|
|
||||||
"O_pycall",
|
|
||||||
"O_continue_call",
|
"O_continue_call",
|
||||||
};
|
};
|
||||||
static const char *call_phases[] = {
|
static const char *call_phases[] = {
|
||||||
|
|
@ -634,13 +630,14 @@ static const char *call_phases[] = {
|
||||||
"CS_CALL_PROLOG",
|
"CS_CALL_PROLOG",
|
||||||
"CS_CONTINUE_PROLOG",
|
"CS_CONTINUE_PROLOG",
|
||||||
"CS_CALL_BODY",
|
"CS_CALL_BODY",
|
||||||
"CS_CONTINUE_BODY",
|
"CS_EXECUTING_BODY",
|
||||||
"CS_CALL_EPILOG",
|
"CS_CALL_EPILOG",
|
||||||
"CS_CONTINUE_EPILOG",
|
"CS_CONTINUE_EPILOG",
|
||||||
"CS_CALL_PYBODY",
|
"CS_CALL_PYBODY",
|
||||||
"CS_CONTINUE_PYBODY",
|
"CS_CONTINUE_PYBODY",
|
||||||
"CS_CALL_PY_OSUB",
|
"CS_CALL_PY_OSUB",
|
||||||
"CS_CONTINUE_PY_OSUB"
|
"CS_CONTINUE_PY_OSUB",
|
||||||
|
"CS_CALL_REMAP",
|
||||||
"CS_DONE"
|
"CS_DONE"
|
||||||
};
|
};
|
||||||
// Propagate an error up the stack as with ERP if the result of 'call' is not
|
// Propagate an error up the stack as with ERP if the result of 'call' is not
|
||||||
|
|
@ -653,6 +650,9 @@ static const char *call_phases[] = {
|
||||||
} \
|
} \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
|
#define INVALID_EVENT(cond) CHKS(cond,"call_fsm: invalid event=%s in state=%s cl=%d rl=%d", \
|
||||||
|
o_ops[event], call_phases[active_frame->state], \
|
||||||
|
settings->call_level, settings->remap_level);
|
||||||
|
|
||||||
// call handling FSM.
|
// call handling FSM.
|
||||||
// when called, call frame is already established
|
// when called, call frame is already established
|
||||||
|
|
@ -667,14 +667,14 @@ int Interp::call_fsm(setup_pointer settings, int event)
|
||||||
bp::list plist;
|
bp::list plist;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
logOword("call_fsm event=%s state=%s cl=%d rl=%d",
|
logOword("call_fsm: event=%s state=%s cl=%d rl=%d status=%s",
|
||||||
o_ops[event], call_phases[active_frame->state],
|
o_ops[event], call_phases[active_frame->state],
|
||||||
settings->call_level, settings->remap_level);
|
settings->call_level, settings->remap_level, interp_status(status));
|
||||||
|
|
||||||
switch (active_frame->state) {
|
switch (active_frame->state) {
|
||||||
|
|
||||||
case CS_CALL_PY_OSUB: // first time around
|
case CS_CALL_PY_OSUB: // first time around
|
||||||
CHKS(event != O_pycall,"baaad..");
|
INVALID_EVENT(event != O_call);
|
||||||
settings->return_value = 0.0;
|
settings->return_value = 0.0;
|
||||||
settings->value_returned = 0;
|
settings->value_returned = 0;
|
||||||
plist.append(settings->pythis); // self
|
plist.append(settings->pythis); // self
|
||||||
|
|
@ -699,7 +699,7 @@ int Interp::call_fsm(setup_pointer settings, int event)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CS_CONTINUE_PY_OSUB: // continuation post synch()
|
case CS_CONTINUE_PY_OSUB: // continuation post synch()
|
||||||
CHKS(event != O_continue_call,"baaad..");
|
INVALID_EVENT(event != O_continue_call);
|
||||||
CHP(read_inputs(settings)); // update toolchange/input/probe data
|
CHP(read_inputs(settings)); // update toolchange/input/probe data
|
||||||
CHP(pycall(settings, active_frame, OWORD_MODULE,
|
CHP(pycall(settings, active_frame, OWORD_MODULE,
|
||||||
active_frame->subName, PY_FINISH_OWORDCALL));
|
active_frame->subName, PY_FINISH_OWORDCALL));
|
||||||
|
|
@ -714,13 +714,185 @@ int Interp::call_fsm(setup_pointer settings, int event)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CS_CALL_BODY: // NGC oword procedure
|
||||||
|
INVALID_EVENT(event != O_call);
|
||||||
|
// copy parameters from context
|
||||||
|
// save old values of parameters
|
||||||
|
// save current file position in context
|
||||||
|
// if we were skipping, no longer
|
||||||
|
if (settings->skipping_o) {
|
||||||
|
logOword("case O_call -- no longer skipping to:|%s|",
|
||||||
|
settings->skipping_o);
|
||||||
|
settings->skipping_o = NULL;
|
||||||
|
}
|
||||||
|
for(int i = 0; i < INTERP_SUB_PARAMS; i++) {
|
||||||
|
previous_frame->saved_params[i] =
|
||||||
|
settings->parameters[i + INTERP_FIRST_SUBROUTINE_PARAM];
|
||||||
|
settings->parameters[i + INTERP_FIRST_SUBROUTINE_PARAM] =
|
||||||
|
eblock->params[i];
|
||||||
|
}
|
||||||
|
// if the previous file was NULL, mark positon as -1 so as not to
|
||||||
|
// reopen it on return.
|
||||||
|
if (settings->file_pointer == NULL) {
|
||||||
|
previous_frame->position = -1;
|
||||||
|
} else {
|
||||||
|
previous_frame->position = ftell(settings->file_pointer);
|
||||||
|
}
|
||||||
|
// save return location
|
||||||
|
previous_frame->filename = strstore(settings->filename);
|
||||||
|
previous_frame->sequence_number = settings->sequence_number;
|
||||||
|
logOword("return location: %s:%d offset=%ld cl=%d",
|
||||||
|
previous_frame->filename,
|
||||||
|
previous_frame->sequence_number,
|
||||||
|
previous_frame->position,
|
||||||
|
settings->call_level);
|
||||||
|
|
||||||
|
|
||||||
|
// set the new subName
|
||||||
|
active_frame->subName = eblock->o_name;
|
||||||
|
// let any Oword sub know the number of parameters
|
||||||
|
CHP(add_named_param("n_args", PA_READONLY));
|
||||||
|
CHP(store_named_param(settings, "n_args",
|
||||||
|
(double )eblock->param_cnt,
|
||||||
|
OVERRIDE_READONLY));
|
||||||
|
|
||||||
|
if (control_back_to(eblock, settings) == INTERP_ERROR) {
|
||||||
|
settings->call_level--; //FIXTHIS - leave_context
|
||||||
|
ERS(NCE_UNABLE_TO_OPEN_FILE,eblock->o_name);
|
||||||
|
status = INTERP_ERROR;
|
||||||
|
}
|
||||||
|
active_frame->state = CS_EXECUTING_BODY;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CS_EXECUTING_BODY: // NGC oword procedure
|
||||||
|
INVALID_EVENT((event != O_return) && (event != O_endsub));
|
||||||
|
if (settings->skipping_o) {
|
||||||
|
logOword("case O_%s -- no longer skipping to:|%s|",
|
||||||
|
(eblock->o_type == O_endsub) ? "endsub" : "return",
|
||||||
|
settings->skipping_o);
|
||||||
|
settings->skipping_o = NULL;
|
||||||
|
}
|
||||||
|
if (settings->call_level != 0) {
|
||||||
|
int context_status = active_frame->context_status; // leave_context wipes this
|
||||||
|
CHP(leave_context(settings, false));
|
||||||
|
|
||||||
|
// free_named_parameters(active_frame); // free local variables
|
||||||
|
// leaving_frame->subName = NULL;
|
||||||
|
// drop one call level.
|
||||||
|
// settings->call_level--;
|
||||||
|
|
||||||
|
// restore subroutine parameters.
|
||||||
|
for(int i = 0; i < INTERP_SUB_PARAMS; i++) {
|
||||||
|
settings->parameters[i+INTERP_FIRST_SUBROUTINE_PARAM] =
|
||||||
|
previous_frame->saved_params[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// file at this level was marked as closed, so dont reopen.
|
||||||
|
if (previous_frame->position == -1) {
|
||||||
|
settings->file_pointer = NULL;
|
||||||
|
strcpy(settings->filename, "");
|
||||||
|
} else {
|
||||||
|
logOword("seeking to: %ld", previous_frame->position);
|
||||||
|
if(settings->file_pointer == NULL) {
|
||||||
|
ERS(NCE_FILE_NOT_OPEN);
|
||||||
|
}
|
||||||
|
//!!!KL must open the new file, if changed
|
||||||
|
if (0 != strcmp(settings->filename, previous_frame->filename)) {
|
||||||
|
fclose(settings->file_pointer);
|
||||||
|
settings->file_pointer = fopen(previous_frame->filename, "r");
|
||||||
|
strcpy(settings->filename, previous_frame->filename);
|
||||||
|
}
|
||||||
|
fseek(settings->file_pointer, previous_frame->position, SEEK_SET);
|
||||||
|
settings->sequence_number = previous_frame->sequence_number;
|
||||||
|
|
||||||
|
// cleanups on return:
|
||||||
|
#ifdef NOTYET
|
||||||
|
// if this was a remap we're done
|
||||||
|
if (cblock->executing_remap)
|
||||||
|
ERP(remap_finished(-cblock->phase));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// a valid previous context was marked by an M73 as auto-restore
|
||||||
|
if ((context_status &
|
||||||
|
(CONTEXT_RESTORE_ON_RETURN|CONTEXT_VALID)) ==
|
||||||
|
(CONTEXT_RESTORE_ON_RETURN|CONTEXT_VALID)) {
|
||||||
|
// NB: this means an M71 invalidate context will prevent an
|
||||||
|
// auto-restore on return/endsub
|
||||||
|
restore_settings(settings, settings->call_level + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// always invalidate on leaving a context so we dont accidentially
|
||||||
|
// 'run into' a valid context when growing the stack upwards again
|
||||||
|
active_frame->context_status &= ~CONTEXT_VALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
settings->sub_name = 0;
|
||||||
|
if (previous_frame->subName) {
|
||||||
|
settings->sub_name = previous_frame->subName;
|
||||||
|
} else {
|
||||||
|
settings->sub_name = NULL;
|
||||||
|
}
|
||||||
|
} else { // call_level == 0
|
||||||
|
|
||||||
|
logDebug("UNEXPECTED state %s: unhandled event=%s cl=%d rl=%d",
|
||||||
|
call_phases[active_frame->state], o_ops[event],
|
||||||
|
settings->call_level, settings->remap_level);
|
||||||
|
status = INTERP_ERROR;
|
||||||
|
// // a definition
|
||||||
|
// if (eblock->o_type == O_endsub) {
|
||||||
|
// CHKS((settings->defining_sub != 1), NCE_NOT_IN_SUBROUTINE_DEFN);
|
||||||
|
// // no longer skipping or defining
|
||||||
|
// if (settings->skipping_o) {
|
||||||
|
// logOword("case O_endsub in defn -- no longer skipping to:|%s|",
|
||||||
|
// settings->skipping_o);
|
||||||
|
// settings->skipping_o = NULL;
|
||||||
|
// }
|
||||||
|
// settings->defining_sub = NULL;
|
||||||
|
// settings->sub_name = NULL;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
case CS_START: // not in a call
|
||||||
|
switch (event) {
|
||||||
|
case O_return:
|
||||||
|
case O_endsub:
|
||||||
|
// a definition
|
||||||
|
if (eblock->o_type == O_endsub) {
|
||||||
|
CHKS((settings->defining_sub != 1), NCE_NOT_IN_SUBROUTINE_DEFN);
|
||||||
|
// no longer skipping or defining
|
||||||
|
if (settings->skipping_o) {
|
||||||
|
logOword("case O_endsub in defn -- no longer skipping to:|%s|",
|
||||||
|
settings->skipping_o);
|
||||||
|
settings->skipping_o = NULL;
|
||||||
|
}
|
||||||
|
settings->defining_sub = NULL;
|
||||||
|
settings->sub_name = NULL;
|
||||||
|
}
|
||||||
|
active_frame->state = CS_DONE;
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
logDebug("state %s: unhandled event=%s cl=%d rl=%d",
|
||||||
|
call_phases[active_frame->state], o_ops[event],
|
||||||
|
settings->call_level, settings->remap_level);
|
||||||
|
status = INTERP_ERROR;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
logDebug("unhandled state %s event %s cl=%d rl=%d",
|
logDebug("state %s unhandled, event=%s cl=%d rl=%d",
|
||||||
o_ops[event], call_phases[active_frame->state],
|
call_phases[active_frame->state], o_ops[event],
|
||||||
settings->call_level, settings->remap_level);
|
settings->call_level, settings->remap_level);
|
||||||
status = INTERP_ERROR;
|
status = INTERP_ERROR;
|
||||||
}
|
}
|
||||||
} while ((status == INTERP_OK) && (active_frame->state != CS_DONE));
|
} while ((status == INTERP_OK) &&
|
||||||
|
(active_frame->state != CS_DONE) &&
|
||||||
|
(active_frame->state != CS_EXECUTING_BODY));
|
||||||
|
|
||||||
|
if (active_frame->state == CS_DONE)
|
||||||
|
active_frame->state = CS_START; // rewind fsm
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
@ -1047,7 +1219,7 @@ Returned Value: int (INTERP_OK)
|
||||||
Side effects:
|
Side effects:
|
||||||
Changes the flow of control.
|
Changes the flow of control.
|
||||||
|
|
||||||
Called by: execute_block
|
Called by: execute
|
||||||
|
|
||||||
Calls: control_skip_to
|
Calls: control_skip_to
|
||||||
control_back_to
|
control_back_to
|
||||||
|
|
@ -1076,6 +1248,9 @@ int Interp::convert_control_functions(block_pointer block, // pointer to a block
|
||||||
return INTERP_OK;
|
return INTERP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if skipping_o was set, we are now on a line which contains that O-word.
|
||||||
|
// if skipping_to_sub was set, we are now on the 'O-name sub' definition line.
|
||||||
|
|
||||||
switch (block->o_type) {
|
switch (block->o_type) {
|
||||||
|
|
||||||
case O_none:
|
case O_none:
|
||||||
|
|
@ -1089,12 +1264,8 @@ int Interp::convert_control_functions(block_pointer block, // pointer to a block
|
||||||
// if we were skipping, no longer
|
// if we were skipping, no longer
|
||||||
if (settings->skipping_o) {
|
if (settings->skipping_o) {
|
||||||
logOword("sub(o_|%s|) was skipping to here", settings->skipping_o);
|
logOword("sub(o_|%s|) was skipping to here", settings->skipping_o);
|
||||||
|
|
||||||
// skipping to a sub means that we must define this now
|
// skipping to a sub means that we must define this now
|
||||||
CHP(control_save_offset( block, settings));
|
CHP(control_save_offset( block, settings));
|
||||||
}
|
|
||||||
|
|
||||||
if (settings->skipping_o) {
|
|
||||||
logOword("no longer skipping to:|%s|", settings->skipping_o);
|
logOword("no longer skipping to:|%s|", settings->skipping_o);
|
||||||
settings->skipping_o = NULL; // this IS our block number
|
settings->skipping_o = NULL; // this IS our block number
|
||||||
}
|
}
|
||||||
|
|
@ -1106,12 +1277,13 @@ int Interp::convert_control_functions(block_pointer block, // pointer to a block
|
||||||
settings->parameters[2],
|
settings->parameters[2],
|
||||||
settings->parameters[3]);
|
settings->parameters[3]);
|
||||||
} else {
|
} else {
|
||||||
logOword("started a subroutine defn: %s",block->o_name);
|
// a definition. We're on the O<name> sub line.
|
||||||
// a definition
|
logOword("started a subroutine defn: %s",block->o_name);
|
||||||
CHKS((settings->defining_sub == 1), NCE_NESTED_SUBROUTINE_DEFN);
|
CHKS((settings->defining_sub == 1), NCE_NESTED_SUBROUTINE_DEFN);
|
||||||
CHP(control_save_offset( block, settings));
|
CHP(control_save_offset( block, settings));
|
||||||
|
|
||||||
settings->skipping_o = block->o_name; // start skipping
|
// start skipping to the corresponding ensub.
|
||||||
|
settings->skipping_o = block->o_name;
|
||||||
settings->skipping_start = settings->sequence_number;
|
settings->skipping_start = settings->sequence_number;
|
||||||
settings->defining_sub = 1;
|
settings->defining_sub = 1;
|
||||||
settings->sub_name = block->o_name;
|
settings->sub_name = block->o_name;
|
||||||
|
|
@ -1121,8 +1293,8 @@ int Interp::convert_control_functions(block_pointer block, // pointer to a block
|
||||||
|
|
||||||
case O_endsub:
|
case O_endsub:
|
||||||
case O_return:
|
case O_return:
|
||||||
// this will also leave_context() including appropriate actions
|
|
||||||
CHP(call_fsm(settings, block->o_type));
|
CHP(call_fsm(settings, block->o_type));
|
||||||
|
// CHP(execute_return(settings, NORMAL_RETURN)); same thing
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case O_call:
|
case O_call:
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue