コード例 #1
0
ファイル: percolation.cpp プロジェクト: nyankosama/courses
void Percolation<GIRD_NUM>::open(int row, int column){
    _gird_stat[row][column] = 1;
    add_union(row - 1, column, row, column);
    add_union(row + 1, column, row, column);
    add_union(row, column - 1, row, column);
    add_union(row, column + 1, row, column);
}
コード例 #2
0
ファイル: strictness.c プロジェクト: amirsalah/cs2007
/**
 * Recursively perform strictness analysis on an expression.
 *
 * This function does three things:
 * - Records which arguments will definitely be evaluated, assuming this expression is evaluated
 * - Marks any application nodes corresponding to an expression being passed as an argument to
 *   a supercombinator or built-in function which is strict in that argument
 * - Marks any letrec bindings used within the expression as strict
 *
 * @param sc      The supercombinator being processed
 *
 * @param c       The expression to analysed
 *
 * @param used    A (sorted) list of strings indicating the variables that are used in a strict
 *                context within the expression. This list is updated by the function if any new
 *                ones are encountered.
 *
 * @param changed A pointer to an integer that is set to true if a change was made to the
 *                strictness flag of one or more application nodes. Changes to used are not
 *                recorded here; this is the responsibility of check_strictness().
 */
static void check_strictness_r(scomb *sc, snode *c, list **used, int *changed)
{
  switch (c->type) {
  case SNODE_LETREC: {
    letrec *rec;
    list *bodyused = NULL;
    list *l;

    int again;
    do {
      again = 0;
      for (rec = c->bindings; rec; rec = rec->next)
        if (rec->strict)
          check_strictness_r(sc,rec->value,&bodyused,changed);
      check_strictness_r(sc,c->body,&bodyused,changed);

      for (rec = c->bindings; rec; rec = rec->next) {
        if (!rec->strict && list_contains_string(bodyused,rec->name)) {
          rec->strict = 1;
          again = 1;
          *changed = 1;
        }
      }
    } while (again);

    for (l = bodyused; l; l = l->next) {
      int isrec = 0;
      for (rec = c->bindings; rec && !isrec; rec = rec->next)
        if (!strcmp((char*)l->data,rec->name))
          isrec = 1;
      if (!isrec) {
        add_var(used,(char*)l->data);
      }
    }
    list_free(bodyused,NULL);
    break;
  }
  case SNODE_APPLICATION: {
    snode *fun;
    int nargs = 0;
    for (fun = c; SNODE_APPLICATION == fun->type; fun = fun->left)
      nargs++;

    /* We have discovered the item at the bottom of the spine, which is the function to be called.
       However we can only perform strictness analysis if we know statically what that function
       is - i.e. if the node is a supercombinator reference of built-in function.

       It is also possible that it could be a symbol, corresponding to a higher-order function
       passed in as an argument, but since we don't know anything about it we skip this case.

       Additionally, we will wait until we have an application to the right number of arguments
       before doing the analysis - if this is not the case yet we'll just do a recursive call
       to the next item in the application chain and handle it later. */
    if (((SNODE_SCREF == fun->type) || (SNODE_BUILTIN == fun->type)) &&
        (nargs == fun_nargs(fun))) {

      /* Follow the left branches down the tree, inspecting each argument and treating it as
         strict or not depending on what we know about the appropriate argument to the function. */
      snode *app = c;
      int argno;
      for (argno = nargs-1; 0 <= argno; argno--) {

        /* If the function is strict in this argument, mark the application node as strict.
           This will provide a hint to the bytecode compiler that it may compile the expression
           directly instead of adding MKAP instructions to create application nodes at runtime. */
        if (fun_strictin(fun,argno)) {
          *changed = (*changed || !app->strict);
          app->strict = 1;

          /* The expression will definitely need to be evaluated, i.e. it is in a strictness
             context. Perform the analysis recursively. */
          check_strictness_r(sc,app->right,used,changed);
        }

        app = app->left;
      }

      /* If statements need special treatment. The first argument (i.e. the conditional) is strict
         since this is always evaluated. But the second and third arguments (i.e. true and false)
         branches are not strict, since we don't know which will be needed until after the
         conditional is evaluated at runtime. A variable is only considered strict on the branches
         of an if in the case where it is used in a strict context in *both* branches.

         Despite the 2nd and 3rd arguments to if not being strict, we treat the *contents* of these
         expressions as being so. Whichever branch is taken will definitely need to return a value,
         so they are treated as a strict context and analysed with another recursive call to
         check_strictness_r(). This information is still relevant to the bytecode compiler due to
         the optimised way in which it compiles if statements using JFALSE and JUMP instructions.
         We also annotate application nodes within the true/false branches with strictness
         where appropriate. */
      if ((SNODE_BUILTIN == fun->type) && (B_IF == fun->bif)) {
        snode *falsebranch = c->right;
        snode *truebranch = c->left->right;

        list *trueused = NULL;
        list *falseused = NULL;

        check_strictness_r(sc,truebranch,&trueused,changed);
        check_strictness_r(sc,falsebranch,&falseused,changed);

        /* Merge the argument usage information from both branches, keeping only those arguments
           which appear in both. */
        add_union(used,trueused,falseused);
        list_free(trueused,NULL);
        list_free(falseused,NULL);
      }
      /* As with the true/false branches of an if call, we can also treat the contents of the
         second argument to seq as strict. The bytecode compiler also contains an optimisation
         for seq where it will evaluate the first argument, discard the result, and then evaluate
         the second argument. So we know that any function applications within the second argument
         will definitely be needed. However, we do not add variables within the expression to our
         used list, as we need to ensure that things referenced by the second argument are not
         evaluated until *after* the first argument (like with if). */
      if ((SNODE_BUILTIN == fun->type) && (B_SEQ == fun->bif)) {
        snode *after = c->right;
        list *afterused = NULL;
        check_strictness_r(sc,after,&afterused,changed);
        list_free(afterused,NULL);
      }
    }

    /* The expression representing the thing being called is in a strict context, as we definitely
       need the function. */
    check_strictness_r(sc,c->left,used,changed);
    break;
  }
  case SNODE_SYMBOL:
    /* We are in a strict context and have an encountered a symbol, which must correspond to
       one of the supercombinator's arguments or a letrec binding. Add the variable to the list
       to indicate that this argument will definitely be evaluated. */
    add_var(used,c->name);
    break;
  case SNODE_BUILTIN:
  case SNODE_SCREF:
  case SNODE_NIL:
  case SNODE_NUMBER:
  case SNODE_STRING:
    break;
  default:
    abort();
    break;
  }
}
コード例 #3
0
ファイル: utl_scope.cpp プロジェクト: S73417H/opensplice
AST_Decl *UTL_Scope::call_add()
{
   AST_Decl *result = NULL;
   AST_Decl *decl;

   UTL_ScopeActiveIterator *i;
   UTL_Scope *scope;

   i = new UTL_ScopeActiveIterator(this, UTL_Scope::IK_decls);

   while (!(i->is_done()))
   {
      decl = i->item();
      scope = 0;

      switch (decl->node_type())
      {

      case AST_Decl::NT_argument:
         result = add_argument(AST_Argument::narrow_from_decl(decl));
         break;

      case AST_Decl::NT_array:
         result = add_array(AST_Array::narrow_from_decl(decl));
         break;

      case AST_Decl::NT_attr:
         result = add_attribute(AST_Attribute::narrow_from_decl(decl));
         break;

      case AST_Decl::NT_const:
         result = add_constant(AST_Constant::narrow_from_decl(decl));
         break;

      case AST_Decl::NT_enum:
         scope = AST_Enum::narrow_from_decl(decl);
         result = add_enum(AST_Enum::narrow_from_decl(decl));
         break;

      case AST_Decl::NT_enum_val:
         result = add_enum_val(AST_EnumVal::narrow_from_decl(decl));
         break;

      case AST_Decl::NT_except:
         scope = AST_Exception::narrow_from_decl(decl);
         result = add_exception(AST_Exception::narrow_from_decl(decl));
         break;

      case AST_Decl::NT_field:
         result = add_field(AST_Field::narrow_from_decl(decl));
         break;

      case AST_Decl::NT_interface:
         scope = AST_Interface::narrow_from_decl(decl);
         result = add_interface(AST_Interface::narrow_from_decl(decl));
         break;

      case AST_Decl::NT_interface_fwd:
         result = add_interface_fwd(AST_InterfaceFwd::narrow_from_decl(decl));
         break;

      case AST_Decl::NT_module:
         scope = AST_Module::narrow_from_decl(decl);
         result = add_module(AST_Module::narrow_from_decl(decl));
         break;

      case AST_Decl::NT_op:
         result = add_operation(AST_Operation::narrow_from_decl(decl));
         scope = AST_Operation::narrow_from_decl(decl);
         break;

      case AST_Decl::NT_pre_defined:
         result =
         add_predefined_type(AST_PredefinedType::narrow_from_decl(decl));
         break;

      case AST_Decl::NT_sequence:
         result = add_sequence(AST_Sequence::narrow_from_decl(decl));
         break;

      case AST_Decl::NT_string:
         result = add_string(AST_String::narrow_from_decl(decl));
         break;

      case AST_Decl::NT_struct:
         result = add_structure(AST_Structure::narrow_from_decl(decl));
         scope = AST_Structure::narrow_from_decl(decl);
         break;

      case AST_Decl::NT_typedef:
         result = add_typedef(AST_Typedef::narrow_from_decl(decl));
         break;

      case AST_Decl::NT_union:
         result = add_union(AST_Union::narrow_from_decl(decl));
         scope = AST_Union::narrow_from_decl(decl);
         break;

      case AST_Decl::NT_union_branch:
         result = add_union_branch(AST_UnionBranch::narrow_from_decl(decl));
         break;
         //   case AST_Decl::NT_opaque:
         //  result = add_opaque(AST_Opaque::narrow_from_decl(decl));
         // break;

      case AST_Decl::NT_value:
         result = add_valuetype (AST_Value::narrow_from_decl (decl));
         scope = AST_Value::narrow_from_decl (decl);
         break;

      case AST_Decl::NT_value_fwd:
         result = add_valuetype_fwd(AST_ValueFwd::narrow_from_decl(decl));
         break;

      case AST_Decl::NT_state_member:
         result = add_state_member(AST_StateMember::narrow_from_decl(decl));
         break;

      default:
         return NULL;
      }

      if (scope)
         scope->call_add();

      i->next();
   }

   delete i;
   return result;
}