// // functions.cpp - the functions for the controller // // Copyright (C) 2000-1 by Hugh Jack // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // // // Last Modified: March 30, 2001 // #ifdef __cplusplus extern "C" { #endif #include "core.h" truth_stack *truth; // keeps a stack of truth values for logic functions variable_stack *heap; // for keeping variables execution_stack *estack; // for keeping execution history int stack_pointer; memory *mem; program *prog; function_library *library; processor_status *stat; core::core(){ mem = new memory(); prog = new program(); focus_step = prog->root; communications = new queue(10); library = new function_library(); stat = new processor_status(); stack.count = -1; estack = new execution_stack[MAXIMUM_STACK_SIZE]; stack_pointer = -1; truth = new truth_stack(100); // This limit might cause complex programs -lisp like- to crash heap = new variable_stack(100); // another hard limit stat->first_scan->var->set_bit(TRUE); } core::~core(){ delete mem; delete prog; delete communications; delete truth; delete heap; delete library; delete stat; //delete estack; // there is something wrong here - it crashes when deleted } //int core::update_labels(int program){ // int error, // j, // used, type; // float value; // // error = NO_ERROR; // program_info(program, &used, &type); // if((used == USED) && (type == _IL_PROGRAM)){ // prog->label(program, LABEL_CLEAR_ALL, 0, 0, NULL); // for(j = 0; (j < 32000) && (prog->get_instruction(program, j) != ERROR); j++){ // prog->get_opcode(program, &type); // if(type == IL_LBL){ // value = get_float_from_memory(); // prog->label(program, LABEL_SET_VALUE, (int)value, j, NULL); // } // } // } else { // error_log("Error: program type in memory not recognized"); // error = ERROR; // } // // return error; //} int core::scan(char *prog_file){ int error, i; //int used, type; // timeb time_value; int first_flag; error = NO_ERROR; // This is prescan stuff that should be moved to its own // subroutine later. first_flag = stat->first_scan->var->get_bit(); if(first_flag == TRUE){ // ftime(time_now); // deal with labels later - for now hold // for(i = 0; i < prog->size(); i++){ // program_info(i, &used, &type); // if((used == USED) && (type == _IL_PROGRAM)){ // update_labels(i); // } // } // ftime(time_start); ftime(&(stat->time_now)); } else { stat->time_last.millitm = stat->time_now.millitm; stat->time_last.time = stat->time_now.time; stat->time_last.timezone = stat->time_now.timezone; stat->time_last.dstflag = stat->time_now.dstflag; ftime(&(stat->time_now)); stat->seconds = difftime(stat->time_now.time, stat->time_last.time) + (stat->time_now.millitm - stat->time_last.millitm)*0.001; // if(seconds > 0.0) printf("Time clock %f\n", seconds); // milliseconds = milliseconds + 100; } // find a starting point for execution, if there // is no main - run all the programs under the root node if(prog_file != NULL){ efocus = prog->find(prog->root->child, prog_file, 0); if(efocus != NULL) efocus = efocus->child; if(efocus == NULL){ error_log(MINOR, "ERROR: could not find requested label"); if(prog->root != NULL){ efocus = prog->root->child; } else { error_log(MINOR, "ERROR: there are no programs defined!"); } } } else { efocus = prog->root->child; } stack_pointer = 0; estack[stack_pointer].ladder_flag = 0; estack[stack_pointer].end_flag = 0; estack[stack_pointer].instruction = efocus; estack[stack_pointer].arg_count = 0; estack[stack_pointer].done_flag = 0; estack[stack_pointer].if_or_similar = 0; stack.count = -1; //printf("SECONDS %f \n", stat->seconds); stat->error->var->set_int(0); stat->core_flags->var->set_int(0); for(i = 0; (stack_pointer >= 0) && (error == NO_ERROR); i++){ efocus = estack[stack_pointer].instruction; //printf("popping:\n"); // printf("Stack scan pnt=%d efocus=%d \n", stack_pointer, efocus); if(efocus == NULL){ if(stat->core_flags->var->get_bit(FLAG_IGNORE_ERRORS) != 0){ printf("BBBB 9 \n"); if(stat->error->var->get_int() != 0){ printf("BBBB 10 \n"); error = ERROR; } stat->core_flags->var->set_bit(FLAG_IGNORE_ERRORS, 0); } stack_pointer--; estack[stack_pointer].done_flag = 1; } else if(efocus->type == _STEP_INSTRUCTION){ if(estack[stack_pointer].done_flag == 0){ //printf("instruction arg list: %s \n", efocus->func->name()); if(efocus->child == NULL){ //error = scan_step(); error = efocus->func->pre_step(); error = efocus->func->step(); estack[stack_pointer].instruction = efocus->next; } else { if(efocus->func->pre_step() == NO_ERROR){ stack_pointer++; estack[stack_pointer].ladder_flag = estack[stack_pointer-1].ladder_flag; estack[stack_pointer].end_flag = 0; estack[stack_pointer].instruction = efocus->child; estack[stack_pointer].arg_count = 0; estack[stack_pointer].done_flag = 0; estack[stack_pointer].if_or_similar = 0; } else { estack[stack_pointer].done_flag = 0; estack[stack_pointer].instruction = efocus->next; } } } else { //printf("instruction execution:2 ------ %s \n", efocus->func->name()); // error = scan_step(); error = efocus->func->step(); estack[stack_pointer].done_flag = 0; estack[stack_pointer].instruction = efocus->next; } } else if (efocus->type == _STEP_LABEL){ //printf("label:\n"); estack[stack_pointer].instruction = efocus->next; // do nothing, it is a place holder } else if (efocus->type == _STEP_VARIABLE){ //printf("adding variable:\n"); heap->push(efocus->var); estack[stack_pointer].instruction = efocus->next; estack[stack_pointer].arg_count++; } else { error_log(MINOR, "ERROR: there was a problem with an instruction tree type"); error = ERROR; } if((stat->error->var->get_int() != 0) && (stat->core_flags->var->get_bit(FLAG_IGNORE_ERRORS) == 0)){ step_t *error_handler; char *func_name; func_name = stat->error_routine->var->get_string(); //printf("BBBB 2 \n"); if(func_name != NULL){ //printf("BBBB 3 \n"); if((error_handler = prog->find(NULL, func_name, 3)) != NULL){ //printf("BBBB 4 \n"); stack_pointer++; estack[stack_pointer].ladder_flag = FALSE; estack[stack_pointer].end_flag = 0; estack[stack_pointer].instruction = error_handler->child; estack[stack_pointer].arg_count = 0; estack[stack_pointer].done_flag = 0; estack[stack_pointer].if_or_similar = 0; stat->core_flags->var->set_bit(FLAG_IGNORE_ERRORS, 1); } } } //printf("TRUTH ");truth->dump(); //printf("HEAP "); heap->dump(); } if(first_flag == TRUE) stat->first_scan->var->set_bit(FALSE); //communications->dump(); return error; } void core::dump(){ // prog->dump(prog->root); mem->dump_all(); } step_t *core::add_to_prog(int relationship, step_t *prev, int type, char *label, char *comment, function *func, variable *var){ int error; step_t *step1; error = NO_ERROR; if(prev == NULL) prev = prog->root; if(relationship == _CHILD){ step1 = prog->append_child(prev); } else if(relationship == _NEXT){ step1 = prog->append_next(prev); } else { error_log(MINOR, "relationship type unknown"); step1 = NULL; } if(step1 != NULL){ step1->type = type; if(label != NULL) step1->set_label(label); if(comment != NULL) step1->set_comment(comment); if(func != NULL) step1->func = func->clone(); if(var != NULL) step1->var = var; } return step1; } #ifdef __cplusplus } #endif