예제 #1
0
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;
}
예제 #2
0
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;
    }
}
예제 #3
0
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);
}
예제 #4
0
//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;
}
예제 #5
0
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);
}
예제 #6
0
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;
}
예제 #7
0
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);
}
예제 #8
0
파일: io.c 프로젝트: IvanLogvinov/soar
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(&current_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);

}
예제 #9
0
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;
}
예제 #10
0
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);
}
예제 #11
0
파일: io.c 프로젝트: IvanLogvinov/soar
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);
    }
}
예제 #12
0
파일: symbols.cpp 프로젝트: arn-e/circa
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);
}
예제 #13
0
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;

    }
}
예제 #14
0
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;
}