Пример #1
0
int buzzvm_swarm_others(buzzvm_t vm) {
   buzzvm_lnum_assert(vm, 1);
   /* Get the id of the current swarm */
   buzzvm_lload(vm, 0);
   buzzvm_pushs(vm, buzzvm_string_register(vm, "id"));
   buzzvm_tget(vm);
   uint16_t id1 = buzzvm_stack_at(vm, 1)->i.value;
   /* Get the swarm entry */
   uint8_t* x = buzzdict_get(vm->swarms, &id1, uint8_t);
   if(!x) {
      vm->state = BUZZVM_STATE_ERROR;
      vm->error = BUZZVM_ERROR_SWARM;
      return BUZZVM_STATE_ERROR;
   }
   /* Get the id of the new swarm to create */
   buzzvm_lload(vm, 1);
   buzzvm_type_assert(vm, 1, BUZZTYPE_INT);
   uint16_t id2 = buzzvm_stack_at(vm, 1)->i.value;
   /* Add a new entry for the swarm */
   uint8_t v = *x ? 0 : 1;
   buzzdict_set(vm->swarms, &id2, &v);
   /* Send update, if necessary */
   if(v)
      buzzoutmsg_queue_append_swarm_joinleave(
         vm->outmsgs, BUZZMSG_SWARM_JOIN, id2);
   /* Create a table to return */
   make_table(vm, id2);
   /* Return */
   return buzzvm_ret1(vm);
}
Пример #2
0
int buzzvm_swarm_select(buzzvm_t vm) {
   buzzvm_lnum_assert(vm, 1);
   /* Get the id */
   buzzvm_lload(vm, 0);
   buzzvm_pushs(vm, buzzvm_string_register(vm, "id"));
   buzzvm_tget(vm);
   uint16_t id = buzzvm_stack_at(vm, 1)->i.value;
   /* Get the result of the condition check */
   buzzvm_lload(vm, 1);
   buzzvm_type_assert(vm, 1, BUZZTYPE_INT);
   uint8_t in = buzzvm_stack_at(vm, 1)->i.value;
   /* Update the swarm, if known */
   if(buzzdict_exists(vm->swarms, &id)) {
      /* Store membership */
      buzzdict_set(vm->swarms, &id, &in);
      /* Send update */
      buzzoutmsg_queue_append_swarm_joinleave(
         vm->outmsgs,
         in ? BUZZMSG_SWARM_JOIN : BUZZMSG_SWARM_LEAVE,
         id);
      /* Return */
      return buzzvm_ret0(vm);
   }
   else {
      vm->state = BUZZVM_STATE_ERROR;
      vm->error = BUZZVM_ERROR_SWARM;
      return BUZZVM_STATE_ERROR;
   }
}
Пример #3
0
int buzzvm_vstig_setonconflictlost(struct buzzvm_s* vm) {
    buzzvm_lnum_assert(vm, 1);
    /* Get vstig id */
    buzzvm_lload(vm, 0);
    buzzvm_pushs(vm, buzzvm_string_register(vm, "id"));
    buzzvm_tget(vm);
    uint16_t id = buzzvm_stack_at(vm, 1)->i.value;
    /* Look for virtual stigmergy */
    buzzvstig_t* vs = buzzdict_get(vm->vstigs, &id, buzzvstig_t);
    if(vs) {
        /* Virtual stigmergy found */
        /* Get closure */
        buzzvm_lload(vm, 1);
        buzzvm_type_assert(vm, 1, BUZZTYPE_CLOSURE);
        /* Clone the closure */
        if((*vs)->onconflictlost) free((*vs)->onconflictlost);
        (*vs)->onconflictlost = buzzobj_clone(buzzvm_stack_at(vm, 1));
    }
    else {
        /* No virtual stigmergy found, just push false */
        /* If this happens, its a bug */
        buzzvm_pushnil(vm);
        fprintf(stderr, "[BUG] [ROBOT %u] Can't find virtual stigmergy %u\n", vm->robot, id);
    }
    /* Return the value found */
    return buzzvm_ret0(vm);
}
// proper way to send loooong 1D array
int BuzzSetMap(buzzvm_t vm){
      /* Make sure one parameter has been passed */
      buzzvm_lnum_assert(vm, 1);
      /* Get the parameter */
      buzzvm_lload(vm, 1);
      buzzvm_type_assert(vm, 1, BUZZTYPE_TABLE);    // matrix
      /* Get the table */
      buzzobj_t t = buzzvm_stack_at(vm, 1);
      /* Copy the values into a vector */
      std::vector<float> mat;
      for(int32_t i = 0; i < buzzdict_size(t->t.value); ++i) {
         /* Duplicate the table */
         buzzvm_dup(vm);
         /* Push the index */
         buzzvm_pushi(vm, i);
         /* Get the value */
         buzzvm_tget(vm);
         /* Store it in the vector (assume all values are float, no mistake...) */
         mat.push_back((float)buzzvm_stack_at(vm, 1)->f.value);
         /* Get rid of the value, now useless */
         buzzvm_pop(vm);
      }
      /* Get a pointer to the controller */
      buzzvm_pushs(vm, buzzvm_string_register(vm, "controller", 1));
      buzzvm_gload(vm);
      /* Copy data into the controller */
      reinterpret_cast<CBuzzControllerFootBot*>(buzzvm_stack_at(vm, 1)->u.value)->SetMapParams(mat, Sqrt(buzzdict_size(t->t.value)));
      /* Done with the function */
      return buzzvm_ret0(vm);
}
int BuzzSetPath(buzzvm_t vm){
      buzzvm_lnum_assert(vm, 1);
      /* Get the parameter */
      buzzvm_lload(vm, 1);
      buzzvm_type_assert(vm, 1, BUZZTYPE_TABLE);    // dictionary
      buzzobj_t t = buzzvm_stack_at(vm, 1);
      std::vector<CBuzzControllerFootBot::PathItem> pis;
      for(int32_t i = 0; i < buzzdict_size(t->t.value); ++i) {
         buzzvm_dup(vm);
         buzzvm_pushi(vm, i);
         buzzvm_tget(vm);
         int id = 0; int parent = 0; float x = 0.0; float y = 0.0;
        for(int32_t j = 0; j < buzzdict_size(buzzvm_stack_at(vm, 1)->t.value); ++j) {
            buzzvm_dup(vm);
           buzzvm_pushi(vm, j);
            buzzvm_tget(vm);
            if(j == 0){
              id = (float)buzzvm_stack_at(vm, 1)->i.value;
            } else if(j == 1){
              parent = (float)buzzvm_stack_at(vm, 1)->i.value;
            } else if (j == 2){
              x = (float)buzzvm_stack_at(vm, 1)->f.value;
            } else if (j == 3){
              y = (float)buzzvm_stack_at(vm, 1)->f.value;
            }
           //fprintf(stdout, "%d %f \n", j, (float)buzzvm_stack_at(vm, 1)->f.value);
           buzzvm_pop(vm);
        }
         pis.push_back(CBuzzControllerFootBot::PathItem(id, parent, x, y));

         buzzvm_pop(vm);
      }

      /* Get a pointer to the controller */
      buzzvm_pushs(vm, buzzvm_string_register(vm, "controller", 1));
      buzzvm_gload(vm);
      /* Copy data into the controller */
      reinterpret_cast<CBuzzControllerFootBot*>(buzzvm_stack_at(vm, 1)->u.value)->Done(pis);
      /* Done with the function */
      return buzzvm_ret0(vm);
}
int BuzzDrawObstacles(buzzvm_t vm){

      buzzvm_lnum_assert(vm, 1);

      buzzvm_lload(vm, 1);
      buzzvm_type_assert(vm, 1, BUZZTYPE_TABLE);    // dictionary
      buzzobj_t t = buzzvm_stack_at(vm, 1);
      std::vector<CBuzzControllerFootBot::Obstacle> obs;
      for(int32_t i = 0; i < buzzdict_size(t->t.value); ++i) {
         buzzvm_dup(vm);
         buzzvm_pushi(vm, i);
         buzzvm_tget(vm);
         float x = 0.0; float y = 0.0; float radius = 0.0;
         int type = 0;
        for(int32_t j = 0; j < buzzdict_size(buzzvm_stack_at(vm, 1)->t.value); ++j) {
            buzzvm_dup(vm);
           buzzvm_pushi(vm, j);
            buzzvm_tget(vm);
            if(j == 0){
              x = (float)buzzvm_stack_at(vm, 1)->f.value;
            } else if(j == 1){
              y = (float)buzzvm_stack_at(vm, 1)->f.value;
            } else if (j == 2){
              radius = (float)buzzvm_stack_at(vm, 1)->f.value;
            } else if (j == 3){
              type = (int) buzzvm_stack_at(vm, 1)->i.value;
            }
           //fprintf(stdout, "%d %f \n", j, (float)buzzvm_stack_at(vm, 1)->f.value);
           buzzvm_pop(vm);
        }
         obs.push_back(CBuzzControllerFootBot::Obstacle(x, y, radius, type));
         buzzvm_pop(vm);
      }

      buzzvm_pushs(vm, buzzvm_string_register(vm, "controller", 1));
      buzzvm_gload(vm);
      reinterpret_cast<CBuzzControllerFootBot*>(buzzvm_stack_at(vm, 1)->u.value)->ArgosDrawObstacles(obs);

      return buzzvm_ret0(vm);
}
Пример #7
0
int buzzneighbors_add(buzzvm_t vm,
                      uint16_t robot,
                      float distance,
                      float azimuth,
                      float elevation) {
   if(vm->state != BUZZVM_STATE_READY) return vm->state;
   /* Get "neighbors" table */
   buzzvm_pushs(vm, buzzvm_string_register(vm, "neighbors", 1));
   buzzvm_gload(vm);
   buzzvm_type_assert(vm, 1, BUZZTYPE_TABLE);
   buzzobj_t nbr = buzzvm_stack_at(vm, 1);
   /* Get "data" field */
   buzzvm_pushs(vm, buzzvm_string_register(vm, "data", 1));
   buzzvm_tget(vm);
   if(buzzvm_stack_at(vm, 1)->o.type == BUZZTYPE_NIL) {
      /* Empty data, create a new table */
      buzzvm_pop(vm);
      buzzvm_push(vm, nbr);
      buzzvm_pushs(vm, buzzvm_string_register(vm, "data", 1));
      buzzvm_pusht(vm);
      buzzobj_t data = buzzvm_stack_at(vm, 1);
      buzzvm_tput(vm);
      buzzvm_push(vm, data);
   }
   /* When we get here, the "data" table is on top of the stack */
   /* Push robot id */
   buzzvm_pushi(vm, robot);
   /* Create entry table */
   buzzobj_t entry = buzzheap_newobj(vm->heap, BUZZTYPE_TABLE);
   /* Insert distance */
   buzzvm_push(vm, entry);
   buzzvm_pushs(vm, buzzvm_string_register(vm, "distance", 1));
   buzzvm_pushf(vm, distance);
   buzzvm_tput(vm);
   /* Insert azimuth */
   buzzvm_push(vm, entry);
   buzzvm_pushs(vm, buzzvm_string_register(vm, "azimuth", 1));
   buzzvm_pushf(vm, azimuth);
   buzzvm_tput(vm);
   /* Insert elevation */
   buzzvm_push(vm, entry);
   buzzvm_pushs(vm, buzzvm_string_register(vm, "elevation", 1));
   buzzvm_pushf(vm, elevation);
   buzzvm_tput(vm);
   /* Save entry into data table */
   buzzvm_push(vm, entry);
   buzzvm_tput(vm);
   return vm->state;
}
Пример #8
0
int buzzneighbors_kin(buzzvm_t vm) {
   buzzvm_lnum_assert(vm, 0);
   /* Initialize the swarm id to 'unknown' */
   int32_t swarmid = -1;
   /* If the swarm stack is not empty, look for the swarm id */
   if(!buzzdarray_isempty(vm->swarmstack)) {
      /* Get position in swarm stack */
      uint16_t sstackpos = 1;
      if(buzzdarray_size(vm->lsyms->syms) > 1)
         sstackpos = buzzdarray_get(vm->lsyms->syms, 1, buzzobj_t)->i.value;
      /* Get swarm id */
      if(sstackpos <= buzzdarray_size(vm->swarmstack))
         swarmid = buzzdarray_get(vm->swarmstack,
                                  buzzdarray_size(vm->swarmstack) - sstackpos,
                                  uint16_t);
   }
   /* Get the self table */
   buzzvm_lload(vm, 0);
   buzzvm_type_assert(vm, 1, BUZZTYPE_TABLE);
   /* Get the data table */
   buzzvm_pushs(vm, buzzvm_string_register(vm, "data", 1));
   buzzvm_tget(vm);
   buzzobj_t data = buzzvm_stack_at(vm, 1);
   /* Create a new table as return value */
   buzzobj_t t;
   vm->state = make_table(vm, &t);
   if(vm->state != BUZZVM_STATE_READY) return vm->state;
   /* If data is available, filter it */
   if(data->o.type == BUZZTYPE_TABLE) {
      /* Create a new data table */
      buzzobj_t kindata = buzzheap_newobj(vm->heap, BUZZTYPE_TABLE);
      /* Filter the neighbors in data and add them to kindata */
      struct neighbor_filter_s fdata = { .vm = vm, .swarm_id = swarmid, .result = kindata->t.value };
      buzzdict_foreach(data->t.value, neighbor_filter_kin, &fdata);
      /* Add kindata as the "data" field in t */
      buzzvm_push(vm, t);
      buzzvm_pushs(vm, buzzvm_string_register(vm, "data", 1));
      buzzvm_push(vm, kindata);
      buzzvm_tput(vm);
   }
   /* Return the table */
   buzzvm_push(vm, t);
   return buzzvm_ret1(vm);
}
Пример #9
0
int buzzvm_swarm_in(buzzvm_t vm) {
   buzzvm_lnum_assert(vm, 0);
   /* Get the id */
   buzzvm_lload(vm, 0);
   buzzvm_pushs(vm, buzzvm_string_register(vm, "id"));
   buzzvm_tget(vm);
   uint16_t id = buzzvm_stack_at(vm, 1)->i.value;
   /* Get the swarm entry */
   uint8_t* x = buzzdict_get(vm->swarms, &id, uint8_t);
   if(!x) {
      vm->state = BUZZVM_STATE_ERROR;
      vm->error = BUZZVM_ERROR_SWARM;
      return BUZZVM_STATE_ERROR;
   }
   /* Push the return value */
   buzzvm_pushi(vm, *x);
   /* Return */
   return buzzvm_ret1(vm);
}
Пример #10
0
int buzzvm_vstig_size(buzzvm_t vm) {
    buzzvm_lnum_assert(vm, 0);
    /* Get vstig id */
    buzzvm_lload(vm, 0);
    buzzvm_pushs(vm, buzzvm_string_register(vm, "id"));
    buzzvm_tget(vm);
    uint16_t id = buzzvm_stack_at(vm, 1)->i.value;
    /* Look for virtual stigmergy */
    buzzvstig_t* vs = buzzdict_get(vm->vstigs, &id, buzzvstig_t);
    if(vs) {
        /* Virtual stigmergy found, return its size */
        buzzvm_pushi(vm, buzzdict_size((*vs)->data));
    }
    else {
        /* Virtual stigmergy not found, return 0 */
        buzzvm_pushi(vm, 0);
    }
    /* Return */
    return buzzvm_ret1(vm);
}
Пример #11
0
int buzzvm_vstig_get(buzzvm_t vm) {
    buzzvm_lnum_assert(vm, 1);
    /* Get vstig id */
    buzzvm_lload(vm, 0);
    buzzvm_pushs(vm, buzzvm_string_register(vm, "id"));
    buzzvm_tget(vm);
    uint16_t id = buzzvm_stack_at(vm, 1)->i.value;
    /* Get key */
    buzzvm_lload(vm, 1);
    buzzobj_t k = buzzvm_stack_at(vm, 1);
    /* Look for virtual stigmergy */
    buzzvstig_t* vs = buzzdict_get(vm->vstigs, &id, buzzvstig_t);
    if(vs) {
        /* Virtual stigmergy found */
        /* Look for key and push result */
        buzzvstig_elem_t* e = buzzvstig_fetch(*vs, &k);
        if(e) {
            /* Key found */
            buzzvm_push(vm, (*e)->data);
            /* Append the message to the out message queue */
            buzzoutmsg_queue_append_vstig(vm->outmsgs, BUZZMSG_VSTIG_QUERY, id, k, *e);
        }
        else {
            /* Key not found, add a new one containing nil */
            buzzvm_pushnil(vm);
            buzzvstig_elem_t x =
                buzzvstig_elem_new(buzzvm_stack_at(vm, 1),
                                   1, vm->robot);
            /* Append the message to the out message queue */
            buzzoutmsg_queue_append_vstig(vm->outmsgs, BUZZMSG_VSTIG_QUERY, id, k, x);
        }
    }
    else {
        /* No virtual stigmergy found, just push false */
        /* If this happens, its a bug */
        buzzvm_pushnil(vm);
        fprintf(stderr, "[BUG] [ROBOT %u] Can't find virtual stigmergy %u\n", vm->robot, id);
    }
    /* Return the value found */
    return buzzvm_ret1(vm);
}
Пример #12
0
int buzzvm_swarm_exec(buzzvm_t vm) {
   buzzvm_lnum_assert(vm, 1);
   /* Get the id */
   buzzvm_lload(vm, 0);
   buzzvm_pushs(vm, buzzvm_string_register(vm, "id"));
   buzzvm_tget(vm);
   uint16_t id = buzzvm_stack_at(vm, 1)->i.value;
   /* Get the swarm entry */
   uint8_t* x = buzzdict_get(vm->swarms, &id, uint8_t);
   if(!x) {
      vm->state = BUZZVM_STATE_ERROR;
      vm->error = BUZZVM_ERROR_SWARM;
      return BUZZVM_STATE_ERROR;
   }
   /* Check whether the robot is in the swarm */
   if(*x) {
      /* Get the closure */
      buzzvm_lload(vm, 1);
      buzzvm_type_assert(vm, 1, BUZZTYPE_CLOSURE);
      buzzobj_t c = buzzvm_stack_at(vm, 1);
      /* Get rid of the current call structure */
      if(buzzvm_ret0(vm) != BUZZVM_STATE_READY) return vm->state;
      /* Save the current stack depth */
      uint32_t stacks = buzzdarray_size(vm->stacks);
      /* Push the current swarm in the stack */
      buzzdarray_push(vm->swarmstack, &id);
      /* Call the closure */
      buzzvm_push(vm, c);
      int32_t numargs = 0;
      buzzvm_pushi(vm, numargs);
      buzzvm_calls(vm);
      do if(buzzvm_step(vm) != BUZZVM_STATE_READY) return vm->state;
      while(stacks < buzzdarray_size(vm->stacks));
      return vm->state;
   }
   else {
      /* Get rid of the current call structure */
      return buzzvm_ret0(vm);
   }
}
Пример #13
0
int buzzvm_vstig_put(buzzvm_t vm) {
    buzzvm_lnum_assert(vm, 2);
    /* Get vstig id */
    buzzvm_lload(vm, 0);
    buzzvm_pushs(vm, buzzvm_string_register(vm, "id"));
    buzzvm_tget(vm);
    uint16_t id = buzzvm_stack_at(vm, 1)->i.value;
    /* Get key */
    buzzvm_lload(vm, 1);
    buzzobj_t k = buzzvm_stack_at(vm, 1);
    /* Get value */
    buzzvm_lload(vm, 2);
    buzzobj_t v = buzzvm_stack_at(vm, 1);
    /* Look for virtual stigmergy */
    buzzvstig_t* vs = buzzdict_get(vm->vstigs, &id, buzzvstig_t);
    if(vs) {
        /* Look for the element */
        buzzvstig_elem_t* x = buzzvstig_fetch(*vs, &k);
        if(x) {
            /* Element found, update it */
            (*x)->data = v;
            ++((*x)->timestamp);
            (*x)->robot = vm->robot;
            /* Append a PUT message to the out message queue */
            buzzoutmsg_queue_append_vstig(vm->outmsgs, BUZZMSG_VSTIG_PUT, id, k, *x);
        }
        else {
            /* Element not found, create a new one */
            buzzvstig_elem_t y = buzzvstig_elem_new(v, 1, vm->robot);
            buzzvstig_store(*vs, &k, &y);
            /* Append a PUT message to the out message queue */
            buzzoutmsg_queue_append_vstig(vm->outmsgs, BUZZMSG_VSTIG_PUT, id, k, y);
        }
    }
    /* Return */
    return buzzvm_ret0(vm);
}
Пример #14
0
int buzzvm_swarm_leave(buzzvm_t vm) {
   buzzvm_lnum_assert(vm, 0);
   /* Get the id */
   buzzvm_lload(vm, 0);
   buzzvm_pushs(vm, buzzvm_string_register(vm, "id"));
   buzzvm_tget(vm);
   uint16_t id = buzzvm_stack_at(vm, 1)->i.value;
   /* Leave the swarm, if known */
   if(buzzdict_exists(vm->swarms, &id)) {
      /* Store membership */
      uint8_t v = 0;
      buzzdict_set(vm->swarms, &id, &v);
      /* Send update */
      buzzoutmsg_queue_append_swarm_joinleave(
         vm->outmsgs, BUZZMSG_SWARM_LEAVE, id);
      /* Return */
      return buzzvm_ret0(vm);
   }
   else {
      vm->state = BUZZVM_STATE_ERROR;
      vm->error = BUZZVM_ERROR_SWARM;
      return BUZZVM_STATE_ERROR;
   }
}
Пример #15
0
buzzvstig_elem_t buzzvm_vstig_onconflict(buzzvm_t vm,
        buzzvstig_t vs,
        buzzobj_t k,
        buzzvstig_elem_t lv,
        buzzvstig_elem_t rv) {
    /* Was a conflict manager defined? */
    if(vs->onconflict) {
        /* Push closure */
        buzzvm_push(vm, vs->onconflict);
        /* Push key */
        buzzvm_push(vm, k);
        /* Make table for local value */
        buzzvm_pusht(vm);
        buzzobj_t loc = buzzvm_stack_at(vm, 1);
        buzzvm_pushs(vm, buzzvm_string_register(vm, "robot"));
        buzzvm_pushi(vm, lv->robot);
        buzzvm_tput(vm);
        buzzvm_push(vm, loc);
        buzzvm_pushs(vm, buzzvm_string_register(vm, "data"));
        buzzvm_push(vm, lv->data);
        buzzvm_tput(vm);
        buzzvm_push(vm, loc);
        buzzvm_pushs(vm, buzzvm_string_register(vm, "timestamp"));
        buzzvm_pushi(vm, lv->timestamp);
        buzzvm_tput(vm);
        /* Make table for remote value */
        buzzvm_pusht(vm);
        buzzobj_t rem = buzzvm_stack_at(vm, 1);
        buzzvm_pushs(vm, buzzvm_string_register(vm, "robot"));
        buzzvm_pushi(vm, rv->robot);
        buzzvm_tput(vm);
        buzzvm_push(vm, rem);
        buzzvm_pushs(vm, buzzvm_string_register(vm, "data"));
        buzzvm_push(vm, rv->data);
        buzzvm_tput(vm);
        buzzvm_push(vm, rem);
        buzzvm_pushs(vm, buzzvm_string_register(vm, "timestamp"));
        buzzvm_pushi(vm, rv->timestamp);
        buzzvm_tput(vm);
        /* Call closure with 3 arguments */
        buzzvm_push(vm, loc);
        buzzvm_push(vm, rem);
        buzzvm_closure_call(vm, 3);
        /* Make new entry with return value */
        /* Make sure it's a table */
        if(buzzvm_stack_at(vm, 1)->o.type != BUZZTYPE_TABLE) {
            fprintf(stderr, "[WARNING] [ROBOT %u] Return value type is %d\n", vm->robot, buzzvm_stack_at(vm, 1)->o.type);
            return NULL;
        }
        /* Get the robot id */
        buzzobj_t ret = buzzvm_stack_at(vm, 1);
        buzzvm_pushs(vm, buzzvm_string_register(vm, "robot"));
        buzzvm_tget(vm);
        if(buzzvm_stack_at(vm, 1)->o.type != BUZZTYPE_INT)
            return NULL;
        uint16_t robot = buzzvm_stack_at(vm, 1)->i.value;
        buzzvm_pop(vm);
        /* Get the data */
        buzzvm_push(vm, ret);
        buzzvm_pushs(vm, buzzvm_string_register(vm, "data"));
        buzzvm_tget(vm);
        buzzobj_t data = buzzvm_stack_at(vm, 1);
        buzzvm_pop(vm);
        /* Make new entry */
        return buzzvstig_elem_new(data, lv->timestamp, robot);
    }
    else {
        /* No conflict manager, use default behavior */
        if(lv->robot > rv->robot) return buzzvstig_elem_clone(lv);
        else return buzzvstig_elem_clone(rv);
    }
}
Пример #16
0
buzzvstig_elem_t buzzvstig_onconflict_call(buzzvm_t vm,
                                           buzzvstig_t vs,
                                           buzzobj_t k,
                                           buzzvstig_elem_t lv,
                                           buzzvstig_elem_t rv) {
   /* Was a conflict manager defined? */
   if(vs->onconflict) {
      /* Push closure */
      buzzvm_push(vm, vs->onconflict);
      /* Push key */
      buzzvm_push(vm, k);
      /* Make table for local value */
      buzzvm_pusht(vm);
      add_field(robot, lv, pushi);
      add_field(data, lv, push);
      add_field(timestamp, lv, pushi);
      /* Make table for remote value */
      buzzvm_pusht(vm);
      add_field(robot, rv, pushi);
      add_field(data, rv, push);
      add_field(timestamp, rv, pushi);
      /* Call closure (key, lv, rv on the stack) */
      buzzvm_closure_call(vm, 3);
      /* Make new entry with return value */
      /* Make sure it's a table */
      if(buzzvm_stack_at(vm, 1)->o.type != BUZZTYPE_TABLE) {
         fprintf(stderr, "[WARNING] [ROBOT %u] virtual stigmergy onconflict(): Return value type is %s, expected table\n", vm->robot, buzztype_desc[buzzvm_stack_at(vm, 1)->o.type]);
         return NULL;
      }
      /* Get the robot id */
      buzzobj_t ret = buzzvm_stack_at(vm, 1);
      buzzvm_pushs(vm, buzzvm_string_register(vm, "robot", 1));
      buzzvm_tget(vm);
      if(buzzvm_stack_at(vm, 1)->o.type != BUZZTYPE_INT)
         return NULL;
      uint16_t robot = buzzvm_stack_at(vm, 1)->i.value;
      buzzvm_pop(vm);
      /* Get the data */
      buzzvm_push(vm, ret);
      buzzvm_pushs(vm, buzzvm_string_register(vm, "data", 1));
      buzzvm_tget(vm);
      buzzobj_t data = buzzvm_stack_at(vm, 1);
      buzzvm_pop(vm);
      /* Make new entry */
      return buzzvstig_elem_new(data, lv->timestamp, robot);
   }
   else {
      /* No conflict manager, use default behavior */
      /* If both values are not nil, keep the value of the robot with the higher id */
      if(((lv->data->o.type == BUZZTYPE_NIL) && (rv->data->o.type == BUZZTYPE_NIL)) ||
         ((lv->data->o.type != BUZZTYPE_NIL) && (rv->data->o.type != BUZZTYPE_NIL))) {
         if(lv->robot > rv->robot)
            return buzzvstig_elem_clone(vm, lv);
         else
            return buzzvstig_elem_clone(vm, rv);
      }
      /* If my value is not nil, keep mine */
      if(lv->data->o.type != BUZZTYPE_NIL)
         return buzzvstig_elem_clone(vm, lv);
      /* If the other value is not nil, keep that one */
      if(rv->data->o.type != BUZZTYPE_NIL)
         return buzzvstig_elem_clone(vm, rv);
      /* Otherwise nothing to do */
      return NULL;
   }
}
Пример #17
0
buzzvm_state buzzvm_step(buzzvm_t vm) {
   /* buzzvm_dump(vm); */
   /* Can't execute if not ready */
   if(vm->state != BUZZVM_STATE_READY) return vm->state;
   /* Execute GC */
   buzzheap_gc(vm);
   /* Fetch instruction and (potential) argument */
   uint8_t instr = vm->bcode[vm->pc];
   /* Execute instruction */
   switch(instr) {
      case BUZZVM_INSTR_NOP: {
         inc_pc();
         break;
      }
      case BUZZVM_INSTR_DONE: {
         buzzvm_done(vm);
         break;
      }
      case BUZZVM_INSTR_PUSHNIL: {
         inc_pc();
         buzzvm_pushnil(vm);
         break;
      }
      case BUZZVM_INSTR_DUP: {
         inc_pc();
         buzzvm_dup(vm);
         break;
      }
      case BUZZVM_INSTR_POP: {
         if(buzzvm_pop(vm) != BUZZVM_STATE_READY) return vm->state;
         inc_pc();
         break;
      }
      case BUZZVM_INSTR_RET0: {
         if(buzzvm_ret0(vm) != BUZZVM_STATE_READY) return vm->state;
         assert_pc(vm->pc);
         break;
      }
      case BUZZVM_INSTR_RET1: {
         if(buzzvm_ret1(vm) != BUZZVM_STATE_READY) return vm->state;
         assert_pc(vm->pc);
         break;
      }
      case BUZZVM_INSTR_ADD: {
         buzzvm_add(vm);
         inc_pc();
         break;
      }
      case BUZZVM_INSTR_SUB: {
         buzzvm_sub(vm);
         inc_pc();
         break;
      }
      case BUZZVM_INSTR_MUL: {
         buzzvm_mul(vm);
         inc_pc();
         break;
      }
      case BUZZVM_INSTR_DIV: {
         buzzvm_div(vm);
         inc_pc();
         break;
      }
      case BUZZVM_INSTR_MOD: {
         buzzvm_mod(vm);
         inc_pc();
         break;
      }
      case BUZZVM_INSTR_POW: {
         buzzvm_pow(vm);
         inc_pc();
         break;
      }
      case BUZZVM_INSTR_UNM: {
         buzzvm_unm(vm);
         inc_pc();
         break;
      }
      case BUZZVM_INSTR_AND: {
         buzzvm_and(vm);
         inc_pc();
         break;
      }
      case BUZZVM_INSTR_OR: {
         buzzvm_or(vm);
         inc_pc();
         break;
      }
      case BUZZVM_INSTR_NOT: {
         buzzvm_not(vm);
         inc_pc();
         break;
      }
      case BUZZVM_INSTR_EQ: {
         buzzvm_eq(vm);
         inc_pc();
         break;
      }
      case BUZZVM_INSTR_NEQ: {
         buzzvm_neq(vm);
         inc_pc();
         break;
      }
      case BUZZVM_INSTR_GT: {
         buzzvm_gt(vm);
         inc_pc();
         break;
      }
      case BUZZVM_INSTR_GTE: {
         buzzvm_gte(vm);
         inc_pc();
         break;
      }
      case BUZZVM_INSTR_LT: {
         buzzvm_lt(vm);
         inc_pc();
         break;
      }
      case BUZZVM_INSTR_LTE: {
         buzzvm_lte(vm);
         inc_pc();
         break;
      }
      case BUZZVM_INSTR_GLOAD: {
         inc_pc();
         buzzvm_gload(vm);
         break;
      }
      case BUZZVM_INSTR_GSTORE: {
         inc_pc();
         if(buzzvm_gstore(vm) != BUZZVM_STATE_READY) return vm->state;
         break;
      }
      case BUZZVM_INSTR_PUSHT: {
         buzzvm_pusht(vm);
         inc_pc();
         break;
      }
      case BUZZVM_INSTR_TPUT: {
         if(buzzvm_tput(vm) != BUZZVM_STATE_READY) return vm->state;
         inc_pc();
         break;
      }
      case BUZZVM_INSTR_TGET: {
         if(buzzvm_tget(vm) != BUZZVM_STATE_READY) return vm->state;
         inc_pc();
         break;
      }
      case BUZZVM_INSTR_CALLC: {
         inc_pc();
         if(buzzvm_callc(vm) != BUZZVM_STATE_READY) return vm->state;
         assert_pc(vm->pc);
         break;
      }
      case BUZZVM_INSTR_CALLS: {
         inc_pc();
         if(buzzvm_calls(vm) != BUZZVM_STATE_READY) return vm->state;
         assert_pc(vm->pc);
         break;
      }
      case BUZZVM_INSTR_PUSHF: {
         inc_pc();
         get_arg(float);
         if(buzzvm_pushf(vm, arg) != BUZZVM_STATE_READY) return vm->state;
         break;
      }
      case BUZZVM_INSTR_PUSHI: {
         inc_pc();
         get_arg(int32_t);
         if(buzzvm_pushi(vm, arg) != BUZZVM_STATE_READY) return vm->state;
         break;
      }
      case BUZZVM_INSTR_PUSHS: {
         inc_pc();
         get_arg(int32_t);
         if(buzzvm_pushs(vm, arg) != BUZZVM_STATE_READY) return vm->state;
         break;
      }
      case BUZZVM_INSTR_PUSHCN: {
         inc_pc();
         get_arg(uint32_t);
         if(buzzvm_pushcn(vm, arg) != BUZZVM_STATE_READY) return vm->state;
         break;
      }
      case BUZZVM_INSTR_PUSHCC: {
         inc_pc();
         get_arg(uint32_t);
         if(buzzvm_pushcc(vm, arg) != BUZZVM_STATE_READY) return vm->state;
         break;
      }
      case BUZZVM_INSTR_PUSHL: {
         inc_pc();
         get_arg(uint32_t);
         if(buzzvm_pushl(vm, arg) != BUZZVM_STATE_READY) return vm->state;
         break;
      }
      case BUZZVM_INSTR_LLOAD: {
         inc_pc();
         get_arg(uint32_t);
         buzzvm_lload(vm, arg);
         break;
      }
      case BUZZVM_INSTR_LSTORE: {
         inc_pc();
         get_arg(uint32_t);
         buzzvm_lstore(vm, arg);
         break;
      }
      case BUZZVM_INSTR_JUMP: {
         inc_pc();
         get_arg(uint32_t);
         vm->pc = arg;
         assert_pc(vm->pc);
         break;
      }
      case BUZZVM_INSTR_JUMPZ: {
         inc_pc();
         get_arg(uint32_t);
         buzzvm_stack_assert(vm, 1);
         if(buzzvm_stack_at(vm, 1)->o.type == BUZZTYPE_NIL ||
            (buzzvm_stack_at(vm, 1)->o.type == BUZZTYPE_INT &&
             buzzvm_stack_at(vm, 1)->i.value == 0)) {
            vm->pc = arg;
            assert_pc(vm->pc);
         }
         buzzvm_pop(vm);
         break;
      }
      case BUZZVM_INSTR_JUMPNZ: {
         inc_pc();
         get_arg(uint32_t);
         buzzvm_stack_assert(vm, 1);
         if(buzzvm_stack_at(vm, 1)->o.type != BUZZTYPE_NIL &&
            (buzzvm_stack_at(vm, 1)->o.type != BUZZTYPE_INT ||
             buzzvm_stack_at(vm, 1)->i.value != 0)) {
            vm->pc = arg;
            assert_pc(vm->pc);
         }
         buzzvm_pop(vm);
         break;
      }
      default:
         buzzvm_seterror(vm, BUZZVM_ERROR_INSTR, NULL);
         break;
   }
   return vm->state;
}