Tac *tac_assign(Symbol *symbol, Expression *expression) { debug("TAC-Assign %s to %s Type: %d", symbol_to_string(symbol), symbol_to_string(expression->result), symbol->type->code); Tac *code; //debug("TAC-Assign: %s TYPE: %d to %s TYPE: %d", symbol->name, symbol->type->code, expression->result->name, expression->result->type->code); //if (symbol->type->is_variable != TRUE) // die("Symbol isn't a variable"); //if ((symbol->type->code == TYPE_INTEGER) && (expression->result->type->code == TYPE_NATURAL)) // goto do_tac; //if (symbol->type->code == expression->result->type->code) // goto do_tac; //goto do_tac;//We'll check types...never.... //die("Symbol isn't same type as expression"); do_tac: code = make_tac(TAC_COPY, symbol, expression->result, NULL); code->prev = expression->tac; free(expression); return code; }
void tac_dump(Tac *tac) { if (tac == NULL) return;//Nothing to do here int reverse = tac->prev != NULL; Tac *current = tac; while (current != NULL) { printf("Current %d Op: %d ", current, current->op); //if (current->op == TAC_CALL) // printf("Location: %d Return: %s\n", current->location, symbol_to_string(current->condition)); if ((current->op == TAC_GOTO) || (current->op == TAC_IFZ) || (current->op == TAC_IFNZ)) printf("Location: %d Condition: %s\n", current->location, symbol_to_string(current->condition)); else printf("Result: %s (%d) Operand1: %s Operand2: %s\n", symbol_to_string(current->result), current->result, symbol_to_string(current->operand1), symbol_to_string(current->operand2)); if (reverse) current = current->prev; else current = current->next; } }
Expression *expression_call(Symbol *function, Expression *arguments) { debug("Creating expression call for %s Type: %d", symbol_to_string(function), function->type->code); if ((function->type->code != TYPE_FUNCTION) && (function->type->code != TYPE_PROCEDURE)) die("Symbol %s isn't a function or procedure", symbol_to_string(function)); Expression *alt; Symbol *result = NULL;//If this is a function, it returns a value Tac *code; Tac *temp; if ((function->type->code == TYPE_FUNCTION) && (function->external == NULL)) { //Create symbol for result, and declare variable result = make_temp(); code = make_tac(TAC_VARIABLE, result, NULL, NULL); } else { code = make_tac(TAC_NOP, NULL, NULL, NULL); } //Connect up rest of arguments alt = arguments; while (alt != NULL) { code = join_tac(code, alt->tac); alt = alt->next; } //Generate argument instructions while (arguments != NULL) { temp = make_tac(TAC_ARG, arguments->result, NULL, NULL); temp->prev = code; code = temp; alt = arguments->next; free(arguments); arguments = alt; } //temp = make_label_tac(TAC_CALL, function->label, result); temp = make_tac(TAC_CALL, result, function, NULL); temp->prev = code; code = temp; return make_expression(NULL, result, code); }
//the main idea here is to create a new Tac for an array //The first argument we will have as the array symbol itself //The second argument will be the symbol from the expression //And we will join the tacs, so the array tac is AFTER the index tac Expression *expression_array(Symbol *array, Expression *index) { debug("Creating expression %s[%s]", symbol_to_string(array), symbol_to_string(index->result)); if (array->type->is_array != TRUE) die("Symbol %s isn't an array", symbol_to_string(array)); Symbol *proxy = make_array_symbol(array, index->result); debug("Created proxy symbol %s", symbol_to_string(proxy)); //Repurpose index index->result = proxy; return index; }
void code_begin_function(FILE *file, Symbol *symbol) { debug("Setting Scope to %s from %s", symbol_to_string(symbol), symbol_to_string(current_scope)); //Set our scope current_scope = symbol; //print label fprintf(file, "%s:\n", symbol->name); //print our function header code_instruction(file, PUSH, EBP, NULL); code_instruction(file, MOVE, ESP, EBP); if (symbol->symbols->nested == 1) { //this is main code_instruction(file, MOVE, make_integer(0), CURRENT_STATIC_LINK); } //Get the last offset, and adjust stack pointer //FIX 5-19-2011 //int offset = -4; int offset = -8; int i; SymbolTable *table = symbol->symbols; Symbol *current; for (i = 0; i < HASHSIZE; i++) { current = table->entries[i]; while (current != NULL) { if (current->offset < offset) offset = current->offset; current = current->next; } } //Set esp to point to the next location after our variables, make it positive so we subtract int esp_fix = -offset; code_instruction(file, SUBTRACT, make_integer(esp_fix), ESP); }
Expression *make_expression(Expression *next, Symbol *res, Tac *tac) { Expression *exp = (Expression*)safe_malloc(sizeof(Expression)); exp->result = res; exp->tac = tac; exp->next = next; debug("Expression for %s", symbol_to_string(res)); return exp; }
void code_arg(FILE *file, RegDesc *registers, Symbol *result) { arg_count++; debug("Code_Arg - Symbol: %s, Arg Count: %d", symbol_to_string(result), arg_count); code_spill_all(file, registers); clear_registers(registers); if (result->type->code == TYPE_NATURAL) code_instruction(file, PUSH, make_integer(result->value.integer), NULL); else code_instruction(file, PUSH, get_location(file, registers, result), NULL); }
void update_for_top_state_wme_addition(wme * w) { output_link *ol; soar_callback *cb; char link_name[LINK_NAME_SIZE]; /* --- check whether the attribute is an output function --- */ symbol_to_string(w->attr, FALSE, link_name, LINK_NAME_SIZE); cb = soar_exists_callback_id(soar_agent, OUTPUT_PHASE_CALLBACK, link_name); if (!cb) return; /* --- create new output link structure --- */ allocate_with_pool(¤t_agent(output_link_pool), &ol); insert_at_head_of_dll(current_agent(existing_output_links), ol, next, prev); ol->status = NEW_OL_STATUS; ol->link_wme = w; wme_add_ref(w); ol->ids_in_tc = NIL; ol->cb = cb; /* --- make wme point to the structure --- */ w->output_link = ol; /* SW 07 10 2003 previously, this wouldn't be done until the first OUTPUT phase. However, if we add an output command in the 1st decision cycle, Soar seems to ignore it. There may be two things going on, the first having to do with the tc calculation, which may get done too late, in such a way that the initial calculation includes the command. The other thing appears to be that some data structures are not initialized until the first output phase. Namely, id->associated_output_links does not seem reflect the current output links until the first output-phase. To get past these issues, we fake a transitive closure calculation with the knowledge that the only thing on the output link at this point is the output-link identifier itself. This way, we capture a snapshot of the empty output link, so Soar can detect any changes that might occur before the first output_phase. */ current_agent(output_link_tc_num) = get_new_tc_number(); ol->link_wme->value->id.tc_num = current_agent(output_link_tc_num); current_agent(output_link_for_tc) = ol; /* --- add output_link to id's list --- */ push(current_agent(output_link_for_tc), ol->link_wme->value->id.associated_output_links); }
Symbol *int_rhs_function_code (agent* thisAgent, list *args, void* /*user_data*/) { Symbol * sym; if (!args) { print (thisAgent, "Error: 'int' function called with no arguments.\n"); return NIL; } if (args->rest) { print (thisAgent, "Error: 'int' takes exactly 1 argument.\n"); return NIL; } sym = static_cast<Symbol *>(args->first); if (sym->common.symbol_type == VARIABLE_SYMBOL_TYPE) { print_with_symbols (thisAgent, "Error: variable (%y) passed to 'int' RHS function.\n", sym); return NIL; } else if (sym->common.symbol_type == IDENTIFIER_SYMBOL_TYPE) { print_with_symbols (thisAgent, "Error: identifier (%y) passed to 'int' RHS function.\n", sym); return NIL; } else if (sym->common.symbol_type == SYM_CONSTANT_SYMBOL_TYPE) { int64_t int_val; errno = 0; int_val = strtol(symbol_to_string (thisAgent, sym, FALSE, NIL, 0), NULL, 10); if (errno) { print (thisAgent, "Error: bad integer (%y) given to 'int' RHS function\n", sym); return NIL; } return make_int_constant (thisAgent, int_val); } else if (sym->common.symbol_type == INT_CONSTANT_SYMBOL_TYPE) { symbol_add_ref(sym) ; return sym; } else if (sym->common.symbol_type == FLOAT_CONSTANT_SYMBOL_TYPE) { double int_part; modf(sym->fc.value, &int_part); return make_int_constant(thisAgent, static_cast<int64_t>(int_part) ); } print (thisAgent, "Error: unknown symbol type (%y) given to 'int' RHS function\n", sym); return NIL; }
void code_jump(FILE *file, RegDesc *registers, char *op, Symbol *location, Symbol *condition) { debug("Code_Jump - Op: %s Location: %s Condition: %s", op, symbol_to_string(location), symbol_to_string(condition)); code_spill_all(file, registers); clear_registers(registers); //If there is a condition, compare it to 1 if (condition != NULL) { int dest_reg = get_result_register(file, registers, condition); int source_reg = get_argument_register(file, registers, symbol_one, dest_reg); debug("Dest %d Source %d", dest_reg, source_reg); //code_instruction(file, COMPARE, registers[source_reg].name, registers[dest_reg].name); code_instruction(file, COMPARE, registers[dest_reg].name, registers[source_reg].name); } code_flush_all(file, registers); //Output jump instruction code_instruction(file, op, location->name, NULL); }
void inform_output_module_of_wm_changes(list * wmes_being_added, list * wmes_being_removed) { cons *c; wme *w; /* if wmes are added, set flag so can stop when running til output */ for (c = wmes_being_added; c != NIL; c = c->rest) { w = c->first; if (w->id == current_agent(io_header)) { update_for_top_state_wme_addition(w); current_agent(output_link_changed) = TRUE; /* KJC 11/23/98 */ } if (w->id->id.associated_output_links) { update_for_io_wme_change(w); current_agent(output_link_changed) = TRUE; /* KJC 11/23/98 */ } #if DEBUG_RTO else { char id[100]; symbol_to_string(w->id, FALSE, id); if (!strcmp(id, "I3")) { print("--> Added to I3, but doesn't register as an OL change!"); } } #endif } for (c = wmes_being_removed; c != NIL; c = c->rest) { w = c->first; if (w->id == current_agent(io_header)) update_for_top_state_wme_removal(w); if (w->id->id.associated_output_links) update_for_io_wme_change(w); } }
static void format_source(caValue* source, Term* term) { std::string s = symbol_to_string(term_value(term)); append_phrase(source, s.c_str(), term, tok_ColonString); }
void code_tac(FILE *file, RegDesc *registers, Tac *current) { switch (current->op) { case TAC_BEGINPROGRAM: code_main(file); code_begin_function(file, current->result); break; case TAC_BEGINFUNCTION: code_begin_function(file, current->result); break; case TAC_ENDFUNCTION: code_end_function(file, registers); break; case TAC_RETURN: code_return(file, registers, current->result); break; case TAC_ENDPROGRAM: code_end_function(file, registers); break; case TAC_GOTO: code_jump(file, registers, JUMP, current->location->result, NULL); break; case TAC_IFZ: code_jump(file, registers, JUMP_NE, current->location->result, current->condition); break; case TAC_IFNZ: code_jump(file, registers, JUMP_E, current->location->result, current->condition); break; case TAC_ADD: code_binary(file, registers, ADD, current->result, current->operand1, current->operand2); break; case TAC_SUBTRACT: code_binary(file, registers, SUBTRACT, current->result, current->operand1, current->operand2); break; case TAC_MULTIPLY: code_binary(file, registers, MULTIPLY, current->result, current->operand1, current->operand2); break; case TAC_DIVIDE: code_binary(file, registers, DIVIDE, current->result, current->operand1, current->operand2); break; case TAC_NOT: //FIX 5-19-2011 - INVERT is not what we want - thats a bit wise invert //Since we are using booleans, just xor them //code_unary(file, registers, INVERT, current->result, current->operand1); code_binary(file, registers, LOGIC_XOR, current->result, current->operand1, symbol_one); break; case TAC_NEGATIVE: code_unary(file, registers, NEGATE, current->result, current->operand1); break; case TAC_AND: code_binary(file, registers, LOGIC_AND, current->result, current->operand1, current->operand2); break; case TAC_OR: code_binary(file, registers, LOGIC_OR, current->result, current->operand1, current->operand2); break; case TAC_MOD: code_binary(file, registers, ATT_MOD, current->result, current->operand1, current->operand2); break; case TAC_COPY: code_copy(file, registers, current->result, current->operand1); break; case TAC_ARG: code_arg(file, registers, current->result); break; case TAC_CALL://On a TAC call, the function is the operand, and the return is the result code_call(file, registers, current->operand1, current->result); break; case TAC_LABEL: debug("Code_Label - Symbol: %s", symbol_to_string(current->result)); code_flush_all(file, registers); fprintf(file, "%s:\n", current->result->name); break; case TAC_GT: code_compare(file, registers, IS_GREATER, current->result, current->operand1, current->operand2); break; case TAC_LT: code_compare(file, registers, IS_LESS, current->result, current->operand1, current->operand2); break; case TAC_GTE: code_compare(file, registers, IS_GREATER_EQUAL, current->result, current->operand1, current->operand2); break; case TAC_LTE: code_compare(file, registers, IS_LESS_EQUAL, current->result, current->operand1, current->operand2); break; case TAC_EQUAL: code_compare(file, registers, IS_EQUAL, current->result, current->operand1, current->operand2); break; case TAC_NOTEQUAL: code_compare(file, registers, IS_NOT_EQUAL, current->result, current->operand1, current->operand2); break; case TAC_VARIABLE: //do nothing break; case TAC_NOP: //Do nothing break; default: die("Unrecognized TAC: %d", current->op); break; } }
list *collect_root_variables (agent* thisAgent, condition *cond_list, tc_number tc, /* for vars bound outside */ Bool allow_printing_warnings) { list *new_vars_from_value_slot; list *new_vars_from_id_slot; cons *c; condition *cond; Bool found_goal_impasse_test; /* --- find everthing that's in the value slot of some condition --- */ new_vars_from_value_slot = NIL; for (cond=cond_list; cond!=NIL; cond=cond->next) if (cond->type==POSITIVE_CONDITION) add_bound_variables_in_test (thisAgent, cond->data.tests.value_test, tc, &new_vars_from_value_slot); /* --- now see what else we can add by throwing in the id slot --- */ new_vars_from_id_slot = NIL; for (cond=cond_list; cond!=NIL; cond=cond->next) if (cond->type==POSITIVE_CONDITION) add_bound_variables_in_test (thisAgent, cond->data.tests.id_test, tc, &new_vars_from_id_slot); /* --- unmark everything we just marked --- */ unmark_variables_and_free_list (thisAgent, new_vars_from_value_slot); for (c=new_vars_from_id_slot; c!=NIL; c=c->rest) static_cast<Symbol *>(c->first)->var.tc_num = 0; /* --- make sure each root var has some condition with goal/impasse --- */ if (allow_printing_warnings && thisAgent->sysparams[PRINT_WARNINGS_SYSPARAM]) { for (c=new_vars_from_id_slot; c!=NIL; c=c->rest) { found_goal_impasse_test = FALSE; for (cond=cond_list; cond!=NIL; cond=cond->next) { if (cond->type!=POSITIVE_CONDITION) continue; if (test_includes_equality_test_for_symbol (cond->data.tests.id_test, static_cast<symbol_union *>(c->first))) if (test_includes_goal_or_impasse_id_test (cond->data.tests.id_test, TRUE, TRUE)) { found_goal_impasse_test = TRUE; break; } } if (! found_goal_impasse_test) { print (thisAgent, "\nWarning: On the LHS of production %s, identifier ", thisAgent->name_of_production_being_reordered); print_with_symbols (thisAgent, "%y is not connected to any goal or impasse.\n", static_cast<Symbol *>(c->first)); // XML geneneration growable_string gs = make_blank_growable_string(thisAgent); add_to_growable_string(thisAgent, &gs, "Warning: On the LHS of production "); add_to_growable_string(thisAgent, &gs, thisAgent->name_of_production_being_reordered); add_to_growable_string(thisAgent, &gs, ", identifier "); add_to_growable_string(thisAgent, &gs, symbol_to_string (thisAgent, static_cast<Symbol *>(c->first), true, 0, 0)); add_to_growable_string(thisAgent, &gs, " is not connected to any goal or impasse."); xml_generate_warning(thisAgent, text_of_growable_string(gs)); free_growable_string(thisAgent, gs); } } } return new_vars_from_id_slot; }