コード例 #1
0
ファイル: rhs.cpp プロジェクト: emamanto/Soar
rhs_value create_RHS_value(agent* thisAgent,
                           rhs_value rv,
                           condition* cond,
                           char first_letter,
                           ExplainTraceType ebcTraceType)
{
    cons* c, *new_c, *prev_new_c;
    cons* fl, *new_fl;
    Symbol* sym;
    int64_t index;
    char prefix[2];
	test t;//, original_t;
    uint64_t lO_id = 0;


    /* (1) Reteloc identifiers or constants originally bound to variables
     * (2) unbound_vars for unbound vars of course
     * (3) rhs_symbols for literal constants, including those in RHS functions */

    if (rhs_value_is_reteloc(rv))
    {
        /* Symbol pointed to by a rete location
         * This case seems to only be for identifiers or constants originally bound to variables */

        t = var_test_bound_in_reconstructed_conds(thisAgent, cond,
                rhs_value_to_reteloc_field_num(rv),
                rhs_value_to_reteloc_levels_up(rv));
        return allocate_rhs_value_for_symbol(thisAgent, t->data.referent, t->inst_identity, 0, t->identity);
    }

    if (rhs_value_is_unboundvar(rv))
    {
        /* Unbound variable */
        index = static_cast<int64_t>(rhs_value_to_unboundvar(rv));
        if (! *(thisAgent->rhs_variable_bindings + index))
        {
            prefix[0] = first_letter;
            prefix[1] = 0;

            sym = thisAgent->symbolManager->generate_new_variable(prefix);
            *(thisAgent->rhs_variable_bindings + index) = sym;

            if (thisAgent->highest_rhs_unboundvar_index < index)
            {
                thisAgent->highest_rhs_unboundvar_index = index;
            }
            if (ebcTraceType == Explanation_Trace)
            {
                lO_id = thisAgent->explanationBasedChunker->get_or_create_inst_identity_for_sym(sym);
            }
            /* generate will increment the refcount on the new variable, so don't need to do it here. */
            return allocate_rhs_value_for_symbol_no_refcount(thisAgent, sym, lO_id, 0, NULL, true);
        }
        else
        {
            /* unbound variable was already created in previous rhs action */
            sym = *(thisAgent->rhs_variable_bindings + index);
        }
        if (ebcTraceType == Explanation_Trace)
        {
            lO_id = thisAgent->explanationBasedChunker->get_or_create_inst_identity_for_sym(sym);
        }

        return allocate_rhs_value_for_symbol(thisAgent, sym, lO_id, 0, NULL, true);
    }

    if (rhs_value_is_funcall(rv))
    {
        fl = rhs_value_to_funcall_list(rv);
        allocate_cons(thisAgent, &new_fl);
        new_fl->first = fl->first;
        prev_new_c = new_fl;
        for (c = fl->rest; c != NIL; c = c->rest)
        {
            allocate_cons(thisAgent, &new_c);
            new_c->first = create_RHS_value(thisAgent,
                                            static_cast<char*>(c->first),
                                            cond,
                                            first_letter,
                                            ebcTraceType);
            prev_new_c->rest = new_c;
            prev_new_c = new_c;
        }
        prev_new_c->rest = NIL;
        return funcall_list_to_rhs_value(new_fl);
    }
    else
    {
        /* Literal values including those in function calls. */
        rhs_symbol rs = rhs_value_to_rhs_symbol(rv);
        if (ebcTraceType == Explanation_Trace)
            return allocate_rhs_value_for_symbol(thisAgent, rs->referent, rs->inst_identity, rs->cv_id, rs->identity, rs->was_unbound_var);
        else
            return allocate_rhs_value_for_symbol(thisAgent, rs->referent, LITERAL_VALUE, 0, NULL, rs->was_unbound_var);
    }
}
コード例 #2
0
ファイル: recmem.c プロジェクト: IvanLogvinov/soar
Symbol *instantiate_rhs_value (rhs_value rv, goal_stack_level new_id_level,
                               char new_id_letter,
                               struct token_struct *tok, wme *w) {
  list *fl;
  list *arglist;
  cons *c, *prev_c, *arg_cons;
  rhs_function *rf;
  Symbol *result;
  bool nil_arg_found;
  
  if (rhs_value_is_symbol(rv)) {
    result = rhs_value_to_symbol(rv);
    symbol_add_ref (result);
    return result;
  }

  if (rhs_value_is_unboundvar(rv)) {
    long index;
    Symbol *sym;

    index = rhs_value_to_unboundvar(rv);
    if (firer_highest_rhs_unboundvar_index < index)
      firer_highest_rhs_unboundvar_index = index;
    sym = *(current_agent(rhs_variable_bindings)+index);

    if (!sym) {
      sym = make_new_identifier (new_id_letter, new_id_level);
      *(current_agent(rhs_variable_bindings)+index) = sym;
      return sym;
    } else if (sym->common.symbol_type==VARIABLE_SYMBOL_TYPE) {
      new_id_letter = *(sym->var.name + 1);
      sym = make_new_identifier (new_id_letter, new_id_level);
      *(current_agent(rhs_variable_bindings)+index) = sym;
      return sym;
    } else {
      symbol_add_ref (sym);
      return sym;
    }
  }

  if (rhs_value_is_reteloc(rv)) {
    result = get_symbol_from_rete_loc ((unsigned short) rhs_value_to_reteloc_levels_up(rv),
                                       (byte)rhs_value_to_reteloc_field_num(rv),
                                       tok, w);
    symbol_add_ref (result);
    return result;
  }

  fl = rhs_value_to_funcall_list(rv);
  rf = fl->first;

  /* --- build up a list of the argument values --- */
  prev_c = NIL;
  nil_arg_found = FALSE;
  arglist = NIL; /* unnecessary, but gcc -Wall warns without it */
  for (arg_cons=fl->rest; arg_cons!=NIL; arg_cons=arg_cons->rest) {
    allocate_cons (&c);
    c->first = instantiate_rhs_value (arg_cons->first, new_id_level,
                                      new_id_letter, tok, w);
    if (! c->first) nil_arg_found = TRUE;
    if (prev_c) prev_c->rest = c; else arglist = c;
    prev_c = c;
  }
  if (prev_c) prev_c->rest = NIL; else arglist = NIL;

  /* --- if all args were ok, call the function --- */
  if (!nil_arg_found)
    result = (*(rf->f))(arglist);
  else
    result = NIL;

  /* --- scan through arglist, dereference symbols and deallocate conses --- */
  for (c=arglist; c!=NIL; c=c->rest)
    if (c->first) symbol_remove_ref ((Symbol *)(c->first));
  free_list (arglist);

  return result;
}