示例#1
0
int buzzvm_swarm_id(struct buzzvm_s* vm) {
   /* Is the swarm stack empty? */
   if(buzzdarray_isempty(vm->swarmstack)) {
      /* Yes, no swarm to push, push nil instead */
      buzzvm_pushnil(vm);
   }
   else {
      /* Take the stack top by default */
      uint16_t stackpos = 1;
      /* Do we have an argument? */
      if(buzzvm_lnum(vm) > 1) {
         buzzvm_lload(vm, 1);
         buzzvm_type_assert(vm, 1, BUZZTYPE_INT);
         stackpos = buzzvm_stack_at(vm, 1)->i.value;
      }
      /* Limit stackpos value to avoid out-of-bounds operations */
      if(stackpos > buzzdarray_size(vm->swarmstack))
         stackpos = buzzdarray_size(vm->swarmstack);
      /* Push the swarm id located at stackpos */
      buzzvm_pushi(vm,
                   buzzdarray_get(
                      vm->swarmstack,
                      buzzdarray_size(vm->swarmstack) - stackpos,
                      uint16_t));
   }
   /* Return the value */
   return buzzvm_ret1(vm);
}
示例#2
0
buzzvm_state buzzvm_call(buzzvm_t vm, int isswrm) {
   /* Get argument number and pop it */
   buzzvm_stack_assert(vm, 1);
   buzzvm_type_assert(vm, 1, BUZZTYPE_INT);
   int32_t argn = buzzvm_stack_at(vm, 1)->i.value;
   buzzvm_pop(vm);
   /* Make sure the stack has enough elements */
   buzzvm_stack_assert(vm, argn+1);
   /* Make sure the closure is where expected */
   buzzvm_type_assert(vm, argn+1, BUZZTYPE_CLOSURE);
   buzzobj_t c = buzzvm_stack_at(vm, argn+1);
   /* Make sure that that data about C closures is correct */
   if((!c->c.value.isnative) &&
      ((c->c.value.ref) >= buzzdarray_size(vm->flist))) {
      buzzvm_seterror(vm, BUZZVM_ERROR_FLIST, NULL);
      return vm->state;
   }
   /* Create a new local symbol list copying the parent's */
   vm->lsyms =
      buzzvm_lsyms_new(isswrm,
                       buzzdarray_clone(c->c.value.actrec));
   buzzdarray_push(vm->lsymts, &(vm->lsyms));
   /* Add function arguments to the local symbols */
   int32_t i;
   for(i = argn; i > 0; --i)
      buzzdarray_push(vm->lsyms->syms,
                      &buzzdarray_get(vm->stack,
                                      buzzdarray_size(vm->stack) - i,
                                      buzzobj_t));
   /* Get rid of the function arguments */
   for(i = argn+1; i > 0; --i)
      buzzdarray_pop(vm->stack);
   /* Pop unused self table */
   buzzdarray_pop(vm->stack);
   /* Push return address */
   buzzvm_pushi((vm), vm->pc);
   /* Make a new stack for the function */
   vm->stack = buzzdarray_new(1, sizeof(buzzobj_t), NULL);
   buzzdarray_push(vm->stacks, &(vm->stack));
   /* Jump to/execute the function */
   if(c->c.value.isnative) {
      vm->oldpc = vm->pc;
      vm->pc = c->c.value.ref;
   }
   else buzzdarray_get(vm->flist,
                       c->c.value.ref,
                       buzzvm_funp)(vm);
   return vm->state;
}
示例#3
0
文件: buzzdict.c 项目: MISTLab/Buzz
void buzzdict_set(buzzdict_t dt,
                  const void* key,
                  const void* data) {
   /* Hash the key */
   uint32_t h = dt->hashf(key) % dt->num_buckets;
   /* Is the bucket empty? */
   if(!dt->buckets[h]) {
      /* Create new entry list */
      dt->buckets[h] = buzzdarray_new(1, sizeof(struct buzzdict_entry_s), NULL);
      /* Add entry */
      buzzdict_entry_new(dt, e, key, data);
      buzzdarray_push(dt->buckets[h], &e);
      /* Increase size */
      ++(dt->size);
   }
   else {
      /* Bucket not empty - is the entry present? */
      uint32_t i;
      for(i = 0; i < buzzdarray_size(dt->buckets[h]); ++i) {
         const struct buzzdict_entry_s* e = &buzzdarray_get(dt->buckets[h], i, struct buzzdict_entry_s);
         if(dt->keycmpf(key, e->key) == 0) {
            /* Yes, destroy the entry */
            dt->dstryf(e->key, e->data, dt);
            buzzdarray_remove(dt->buckets[h], i);
            --(dt->size);
            break;
         }
      }
      /* Add new entry */
      buzzdict_entry_new(dt, e, key, data);
      buzzdarray_push(dt->buckets[h], &e);
      /* Increase size */
      ++(dt->size);
   }
}
示例#4
0
文件: buzzmsg.c 项目: MISTLab/Buzz
int64_t buzzmsg_deserialize_u8(uint8_t* data,
                               buzzdarray_t buf,
                               uint32_t pos) {
   if(pos + sizeof(uint8_t) > buzzdarray_size(buf)) return -1;
   *data = buzzdarray_get(buf, pos, uint8_t);
   return pos + sizeof(uint8_t);
}
示例#5
0
文件: buzzdict.c 项目: MISTLab/Buzz
int buzzdict_remove(buzzdict_t dt,
                    const void* key) {
   /* Hash the key */
   uint32_t h = dt->hashf(key) % dt->num_buckets, i;
   /* Is the bucket empty? */
   if(!dt->buckets[h]) return 0;
   /* Bucket not empty - is the entry present? */
   for(i = 0; i < buzzdarray_size(dt->buckets[h]); ++i) {
      const struct buzzdict_entry_s* e = &buzzdarray_get(dt->buckets[h], i, struct buzzdict_entry_s);
      if(dt->keycmpf(key, e->key) == 0) {
         /* Entry found - remove it */
         dt->dstryf(e->key, e->data, dt);
         buzzdarray_remove(dt->buckets[h], i);
         /* Is the entry list empty? If so, free the memory */
         if(buzzdarray_isempty(dt->buckets[h]))
            buzzdarray_destroy(&(dt->buckets[h]));
         /* Increase size */
         --(dt->size);
         /* Done */
         return 1;
      }
   }
   /* Entry not found, nothing to do */
   return 0;
}
示例#6
0
void CBuzzController::ControlStep() {
   /* Update debugging information */
   m_sDebug.Clear();
   if(m_sDebug.Trajectory.Tracking) {
      const CCI_PositioningSensor::SReading& sPosRead = m_pcPos->GetReading();
      m_sDebug.TrajectoryAdd(sPosRead.Position);
   }
   /* Take care of the rest */
   if(m_tBuzzVM && m_tBuzzVM->state == BUZZVM_STATE_READY) {
      ProcessInMsgs();
      UpdateSensors();
      if(buzzvm_function_call(m_tBuzzVM, "step", 0) != BUZZVM_STATE_READY) {
         fprintf(stderr, "[ROBOT %u] %s: execution terminated abnormally: %s\n\n",
                 m_tBuzzVM->robot,
                 m_strBytecodeFName.c_str(),
                 ErrorInfo().c_str());
         for(UInt32 i = 1; i <= buzzdarray_size(m_tBuzzVM->stacks); ++i) {
            buzzdebug_stack_dump(m_tBuzzVM, i, stdout);
         }
         return;
      }
      ProcessOutMsgs();
   }
   else {
      fprintf(stderr, "[ROBOT %s] Robot is not ready to execute Buzz script.\n\n",
              GetId().c_str());
   }
}
示例#7
0
文件: buzzmsg.c 项目: MISTLab/Buzz
int64_t buzzmsg_deserialize_float(float* data,
                                  buzzdarray_t buf,
                                  uint32_t pos) {
   /* Make sure enough bytes are left to read */
   if(pos + 2*sizeof(uint32_t) > buzzdarray_size(buf)) return -1;
   /* Read the mantissa and the exponent */
   int32_t mant;
   int32_t exp;
   pos = buzzmsg_deserialize_u32((uint32_t*)(&mant), buf, pos);
   pos = buzzmsg_deserialize_u32((uint32_t*)(&exp), buf, pos);
   /* A zero mantissa corresponds to a zero float */
   if(mant == 0) {
      *data = 0;
   }
   else {
      /* We must calculate the float
       *
       * Idea: use the function ldexpf(), which is the opposite of frexpf()
       * For this, we need to transform the mantissa into a normalized
       * fraction in the range [0.5,1)
       *
       * 1. Take the absolute value of the mantissa, which is in [1, MAX_MANTISSA+1]
       * 2. Subtract 1, so it's in [0, MAX_MANTISSA]
       * 3. divide by MAX_MANTISSA, so it's in [0,1)
       * 4. divide by 2, so it's in [0,0.5)
       * 5. Add 0.5, so it's in [0.5,1)
       */
      *data = (float)(abs(mant) - 1) / (2.0f * MAX_MANTISSA) + 0.5f;
      /* Now use ldexpf() to calculate the absolute value */
      *data = ldexpf(*data, exp);
      /* Finally take care of the sign */
      if(mant < 0) *data = -*data;
   }
   return pos;
}
示例#8
0
buzzvm_state buzzvm_function_call(buzzvm_t vm,
                                  const char* fname,
                                  uint32_t argc) {
   /* Reset the VM state if it's DONE */
   if(vm->state == BUZZVM_STATE_DONE)
      vm->state = BUZZVM_STATE_READY;
   /* Don't continue if the VM has an error */
   if(vm->state != BUZZVM_STATE_READY)
      return vm->state;
   /* Push the function name (return with error if not found) */
   buzzvm_pushs(vm, buzzvm_string_register(vm, fname, 0));
   /* Get associated symbol */
   buzzvm_gload(vm);
   /* Make sure it's a closure */
   buzzvm_type_assert(vm, 1, BUZZTYPE_CLOSURE);
   /* Move closure before arguments */
   if(argc > 0) {
      buzzdarray_insert(vm->stack,
                        buzzdarray_size(vm->stack) - argc - 1,
                        buzzvm_stack_at(vm, 1));
      buzzvm_pop(vm);
   }
   /* Call the closure */
   return buzzvm_closure_call(vm, argc);
}
示例#9
0
buzzvm_state buzzvm_closure_call(buzzvm_t vm,
                                 uint32_t argc) {
   /* Insert the self table right before the closure */
   buzzdarray_insert(vm->stack,
                     buzzdarray_size(vm->stack) - argc - 1,
                     buzzheap_newobj(vm, BUZZTYPE_NIL));
   /* Push the argument count */
   buzzvm_pushi(vm, argc);
   /* Save the current stack depth */
   uint32_t stacks = buzzdarray_size(vm->stacks);
   /* Call the closure and keep stepping until
    * the stack count is back to the saved value */
   buzzvm_callc(vm);
   do if(buzzvm_step(vm) != BUZZVM_STATE_READY) return vm->state;
   while(stacks < buzzdarray_size(vm->stacks));
   return vm->state;
}
示例#10
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);
}
示例#11
0
文件: buzzmsg.c 项目: MISTLab/Buzz
int64_t buzzmsg_deserialize_u16(uint16_t* data,
                                buzzdarray_t buf,
                                uint32_t pos) {
   if(pos + sizeof(uint16_t) > buzzdarray_size(buf)) return -1;
   *data =
      buzzdarray_get(buf, pos,   uint8_t)       +
      (buzzdarray_get(buf, pos+1, uint8_t) << 8);
   *data = ntohs(*data);
   return pos + sizeof(uint16_t);
}
示例#12
0
文件: buzzmsg.c 项目: MISTLab/Buzz
int64_t buzzmsg_deserialize_string(char** data,
                                   buzzdarray_t buf,
                                   uint32_t pos) {
   /* Make sure there are enough bytes to read the string length */
   if(pos + sizeof(uint16_t) > buzzdarray_size(buf)) return -1;
   /* Read the string length */
   uint16_t len;
   pos = buzzmsg_deserialize_u16(&len, buf, pos);
   /* Make sure there are enough bytes to read the string itself */   
   if(pos + len > buzzdarray_size(buf)) return -1;
   /* Create a buffer for the string */
   *data = (char*)malloc(len * sizeof(char) + 1);
   /* Read the string characters */
   memcpy(*data, (uint8_t*)buf->data + pos, len * sizeof(char));
   /* Set the termination character */
   *(*data + len) = 0;
   /* Return new position */
   return pos + len;
}
示例#13
0
uint32_t buzzvm_function_register(buzzvm_t vm,
                                  buzzvm_funp funp) {
   /* Look for function pointer to avoid duplicates */
   uint32_t fpos = buzzdarray_find(vm->flist, buzzvm_function_cmp, funp);
   if(fpos == buzzdarray_size(vm->flist)) {
      /* Add function to the list */
      buzzdarray_push(vm->flist, &funp);
   }
   return fpos;
}
示例#14
0
void buzzvm_dump(buzzvm_t vm) {
   int64_t i, j;
   fprintf(stderr, "============================================================\n");
   fprintf(stderr, "state: %d\terror: %d\n", vm->state, vm->error);
   fprintf(stderr, "code size: %u\tpc: %d\n", vm->bcode_size, vm->pc);
   fprintf(stderr, "stacks: %" PRId64 "\tcur elem: %" PRId64 " (size %" PRId64 ")\n", buzzdarray_size(vm->stacks), buzzvm_stack_top(vm), buzzvm_stack_top(vm));
   for(i = buzzdarray_size(vm->stacks)-1; i >= 0 ; --i) {
      fprintf(stderr, "===== stack: %" PRId64 " =====\n", i);
      for(j = buzzdarray_size(buzzdarray_get(vm->stacks, i, buzzdarray_t)) - 1; j >= 0; --j) {
         fprintf(stderr, "\t%" PRId64 "\t", j);
         buzzobj_t o = buzzdarray_get(buzzdarray_get(vm->stacks, i, buzzdarray_t), j, buzzobj_t);
         switch(o->o.type) {
            case BUZZTYPE_NIL:
               fprintf(stderr, "[nil]\n");
               break;
            case BUZZTYPE_INT:
               fprintf(stderr, "[int] %d\n", o->i.value);
               break;
            case BUZZTYPE_FLOAT:
               fprintf(stderr, "[float] %f\n", o->f.value);
               break;
            case BUZZTYPE_TABLE:
               fprintf(stderr, "[table] %d elements\n", buzzdict_size(o->t.value));
               break;
            case BUZZTYPE_CLOSURE:
               if(o->c.value.isnative) {
                  fprintf(stderr, "[n-closure] %d\n", o->c.value.ref);
               }
               else {
                  fprintf(stderr, "[c-closure] %d\n", o->c.value.ref);
               }
               break;
            case BUZZTYPE_STRING:
               fprintf(stderr, "[string] %d:'%s'\n", o->s.value.sid, o->s.value.str);
               break;
            default:
               fprintf(stderr, "[TODO] type = %d\n", o->o.type);
         }
      }
   }
   fprintf(stderr, "============================================================\n\n");
}
示例#15
0
void print_swarm_elem(const void* key, void* data, void* params) {
   uint32_t i;
   buzzswarm_elem_t e = *(buzzswarm_elem_t*)data;
   fprintf(stdout, "ROBOT %u -> R%u:", *(uint16_t*)params, *(uint16_t*)key);
   for(i = 0; i < buzzdarray_size(e->swarms); ++i) {
      fprintf(stdout,
              " %u",
              buzzdarray_get(e->swarms, i, uint16_t));
   }
   fprintf(stdout, "\n");
}
示例#16
0
文件: buzzmsg.c 项目: MISTLab/Buzz
int64_t buzzmsg_deserialize_u32(uint32_t* data,
                                buzzdarray_t buf,
                                uint32_t pos) {
   if(pos + sizeof(uint32_t) > buzzdarray_size(buf)) return -1;
   *data =
      buzzdarray_get(buf, pos,   uint8_t)         +
      (buzzdarray_get(buf, pos+1, uint8_t) << 8)  +
      (buzzdarray_get(buf, pos+2, uint8_t) << 16) +
      (buzzdarray_get(buf, pos+3, uint8_t) << 24);
   *data = ntohl(*data);
   return pos + sizeof(uint32_t);
}
示例#17
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);
   }
}
示例#18
0
void buzzswarm_members_leave(buzzswarm_members_t m,
                             uint16_t robot,
                             uint16_t swarm) {
   /* Is an entry for the passed robot present? */
   buzzswarm_elem_t* e = buzzdict_get(m, &robot, buzzswarm_elem_t);
   if(e) {
      /* Yes, update it */
      (*e)->age = 0;
      /* Search for the passed id */
      uint32_t i;
      for(i = 0; i < buzzdarray_size((*e)->swarms); ++i) {
         if(buzzdarray_get((*e)->swarms, i, uint16_t) == swarm) break;
      }
      /* If the element was found, remove it */
      if(i < buzzdarray_size((*e)->swarms))
         buzzdarray_remove((*e)->swarms, i);
      /* If no swarm id is known for this robot, remove the entry altogether */
      if(buzzdarray_isempty((*e)->swarms))
         buzzdict_remove(m, &robot);
   }
   /* Nothing to do if you get a 'leave' message for someone you don't know */
}
示例#19
0
文件: buzzdict.c 项目: MISTLab/Buzz
void* buzzdict_rawget(buzzdict_t dt,
                      const void* key) {
   /* Hash the key */
   uint32_t h = dt->hashf(key) % dt->num_buckets, i;
   /* Is the bucket empty? */
   if(!dt->buckets[h]) return NULL;
   /* Bucket not empty - is the entry present? */
   for(i = 0; i < buzzdarray_size(dt->buckets[h]); ++i) {
      const struct buzzdict_entry_s* e = &buzzdarray_get(dt->buckets[h], i, struct buzzdict_entry_s);
      if(dt->keycmpf(key, e->key) == 0)
         return e->data;
   }
   /* Entry not found */
   return NULL;
}
示例#20
0
文件: buzzdict.c 项目: MISTLab/Buzz
void buzzdict_foreach(buzzdict_t dt,
                      buzzdict_elem_funp fun,
                      void* params) {
   /* Go through buckets */
   uint32_t i, j;
   for(i = 0; i < dt->num_buckets; ++i) {
      /* Is the bucket used? */
      if(dt->buckets[i] != NULL) {
         /* Go through elements in the bucket */
         for(j = 0; j < buzzdarray_size(dt->buckets[i]); ++j) {
            const struct buzzdict_entry_s* e = &buzzdarray_get(dt->buckets[i], j, struct buzzdict_entry_s);
            fun(e->key, e->data, params);
         }
      }
   }
}
示例#21
0
int buzzswarm_members_isrobotin(buzzswarm_members_t m,
                                uint16_t robot,
                                uint16_t swarm) {
   /* Is an entry for the passed robot present?
    * If not, return false */
   buzzswarm_elem_t* e = buzzdict_get(m, &robot, buzzswarm_elem_t);
   if(!e) return 0;
   /* If we get here, an entry is present
    * Does it contain the passed swarm id? */
   uint32_t i;
   for(i = 0; i < buzzdarray_size((*e)->swarms); ++i) {
      if(buzzdarray_get((*e)->swarms, i, uint16_t) == swarm) return 1;
   }
   /* If we get here, it's because we couldn't find the id */
   return 0;
}
示例#22
0
buzzvm_state buzzvm_pushl(buzzvm_t vm, int32_t addr) {
   buzzobj_t o = buzzheap_newobj(vm, BUZZTYPE_CLOSURE);
   o->c.value.isnative = 1;
   o->c.value.ref = addr;
   if(vm->lsyms) {
      int i;
      for(i = 0; i < buzzdarray_size(vm->lsyms->syms); ++i)
         buzzdarray_push(o->c.value.actrec,
                         &buzzdarray_get(vm->lsyms->syms,
                                         i, buzzobj_t));
   }
   else {
      buzzobj_t nil = buzzheap_newobj(vm, BUZZTYPE_NIL);
      buzzdarray_push(o->c.value.actrec,
                      &nil);
   }
   return buzzvm_push(vm, o);
}
示例#23
0
int BuzzDebugPrint(buzzvm_t vm) {
   /* Get pointer to controller user data */
   buzzvm_pushs(vm, buzzvm_string_register(vm, "controller", 1));
   buzzvm_gload(vm);
   buzzvm_type_assert(vm, 1, BUZZTYPE_USERDATA);
   CBuzzController& cContr = *reinterpret_cast<CBuzzController*>(buzzvm_stack_at(vm, 1)->u.value);
   /* Fill message */
   std::ostringstream oss;
   for(UInt32 i = 1; i < buzzdarray_size(vm->lsyms->syms); ++i) {
      buzzvm_lload(vm, i);
      buzzobj_t o = buzzvm_stack_at(vm, 1);
      buzzvm_pop(vm);
      switch(o->o.type) {
         case BUZZTYPE_NIL:
            oss << "[nil]";
            break;
         case BUZZTYPE_INT:
            oss << o->i.value;
            break;
         case BUZZTYPE_FLOAT:
            oss << o->f.value;
            break;
         case BUZZTYPE_TABLE:
            oss << "[table with " << (buzzdict_size(o->t.value)) << " elems]";
            break;
         case BUZZTYPE_CLOSURE:
            if(o->c.value.isnative)
               oss << "[n-closure @" << o->c.value.ref << "]";
            else
               oss << "[c-closure @" << o->c.value.ref << "]";
            break;
         case BUZZTYPE_STRING:
            oss << o->s.value.str;
            break;
         case BUZZTYPE_USERDATA:
            oss << "[userdata @" << o->u.value << "]";
            break;
         default:
            break;
      }
   }
   cContr.GetARGoSDebugInfo().Msg = oss.str();
   return buzzvm_ret0(vm);
}
示例#24
0
文件: buzzdict.c 项目: MISTLab/Buzz
void buzzdict_destroy(buzzdict_t* dt) {
   /* Destroy buckets */
   uint32_t i, j;
   for(i = 0; i < (*dt)->num_buckets; ++i) {
      /* Is the bucket used? */
      if((*dt)->buckets[i] != NULL) {
         /* Destroy elements in the bucket */
         for(j = 0; j < buzzdarray_size((*dt)->buckets[i]); ++j) {
            const struct buzzdict_entry_s* e = &buzzdarray_get((*dt)->buckets[i], j, struct buzzdict_entry_s);
            (*dt)->dstryf(e->key, e->data, *dt);
         }
         /* Destroy bucket */
         buzzdarray_destroy(&((*dt)->buckets[i]));
      }
   }
   free((*dt)->buckets);
   /* Destroy the rest */
   free(*dt);
   *dt = NULL;
}
示例#25
0
int BuzzLOG (buzzvm_t vm) {
   LOG << "BUZZ: ";
   for(UInt32 i = 1; i < buzzdarray_size(vm->lsyms->syms); ++i) {
      buzzvm_lload(vm, i);
      buzzobj_t o = buzzvm_stack_at(vm, 1);
      buzzvm_pop(vm);
      switch(o->o.type) {
         case BUZZTYPE_NIL:
            LOG << "[nil]";
            break;
         case BUZZTYPE_INT:
            LOG << o->i.value;
            break;
         case BUZZTYPE_FLOAT:
            LOG << o->f.value;
            break;
         case BUZZTYPE_TABLE:
            LOG << "[table with " << (buzzdict_size(o->t.value)) << " elems]";
            break;
         case BUZZTYPE_CLOSURE:
            if(o->c.value.isnative)
               LOG << "[n-closure @" << o->c.value.ref << "]";
            else
               LOG << "[c-closure @" << o->c.value.ref << "]";
            break;
         case BUZZTYPE_STRING:
            LOG << o->s.value.str;
            break;
         case BUZZTYPE_USERDATA:
            LOG << "[userdata @" << o->u.value << "]";
            break;
         default:
            break;
      }
   }
   LOG << std::endl;
   LOG.Flush();
   return buzzvm_ret0(vm);
}
示例#26
0
buzzvm_state buzzvm_tput(buzzvm_t vm) {
   buzzvm_stack_assert(vm, 3);
   buzzvm_type_assert(vm, 3, BUZZTYPE_TABLE);
   buzzobj_t v = buzzvm_stack_at(vm, 1);
   buzzobj_t k = buzzvm_stack_at(vm, 2);
   buzzobj_t t = buzzvm_stack_at(vm, 3);
   buzzvm_pop(vm);
   buzzvm_pop(vm);
   buzzvm_pop(vm);
   if(k->o.type != BUZZTYPE_INT &&
      k->o.type != BUZZTYPE_FLOAT &&
      k->o.type != BUZZTYPE_STRING) {
      buzzvm_seterror(vm, BUZZVM_ERROR_TYPE, "a %s value can't be used as table key", buzztype_desc[k->o.type]);
      return vm->state;
   }
   if(v->o.type == BUZZTYPE_NIL) {
      /* Nil, erase entry */
      buzzdict_remove(t->t.value, &k);
   }
   else if(v->o.type == BUZZTYPE_CLOSURE) {
      /* Method call */
      int i;
      buzzobj_t o = buzzheap_newobj(vm, BUZZTYPE_CLOSURE);
      o->c.value.isnative = v->c.value.isnative;
      o->c.value.ref = v->c.value.ref;
      buzzdarray_push(o->c.value.actrec, &t);
      for(i = 1; i < buzzdarray_size(v->c.value.actrec); ++i)
         buzzdarray_push(o->c.value.actrec,
                         &buzzdarray_get(v->c.value.actrec,
                                         i, buzzobj_t));
      buzzdict_set(t->t.value, &k, &o);
   }
   else {
      buzzdict_set(t->t.value, &k, &v);
   }
   return BUZZVM_STATE_READY;
}
示例#27
0
文件: buzzrun.c 项目: MISTLab/Buzz
int print(buzzvm_t vm) {
   for(int i = 1; i < buzzdarray_size(vm->lsyms->syms); ++i) {
      buzzvm_lload(vm, i);
      buzzobj_t o = buzzvm_stack_at(vm, 1);
      buzzvm_pop(vm);
      switch(o->o.type) {
         case BUZZTYPE_NIL:
            fprintf(stdout, "[nil]");
            break;
         case BUZZTYPE_INT:
            fprintf(stdout, "%d", o->i.value);
            break;
         case BUZZTYPE_FLOAT:
            fprintf(stdout, "%f", o->f.value);
            break;
         case BUZZTYPE_TABLE:
            fprintf(stdout, "[table with %d elems]", (buzzdict_size(o->t.value)));
            break;
         case BUZZTYPE_CLOSURE:
            if(o->c.value.isnative)
               fprintf(stdout, "[n-closure @%d]", o->c.value.ref);
            else
               fprintf(stdout, "[c-closure @%d]", o->c.value.ref);
            break;
         case BUZZTYPE_STRING:
            fprintf(stdout, "%s", o->s.value.str);
            break;
         case BUZZTYPE_USERDATA:
            fprintf(stdout, "[userdata @%p]", o->u.value);
            break;
         default:
            break;
      }
   }
   fprintf(stdout, "\n");
   return buzzvm_ret0(vm);
}
示例#28
0
void buzzswarm_members_join(buzzswarm_members_t m,
                            uint16_t robot,
                            uint16_t swarm) {
   /* Is an entry for the passed robot already present? */
   buzzswarm_elem_t* e = buzzdict_get(m, &robot, buzzswarm_elem_t);
   if(e) {
      /* Yes, update it */
      (*e)->age = 0;
      /* Search for the passed id; if found, nothing to do */
      uint32_t i;
      for(i = 0; i < buzzdarray_size((*e)->swarms); ++i) {
         if(buzzdarray_get((*e)->swarms, i, uint16_t) == swarm) return;
      }
      /* If we get here, it's because we got new information - add it */
      buzzdarray_push((*e)->swarms, &swarm);
   }
   else {
      /* No, create it */
      buzzswarm_elem_t ne = buzzswarm_elem_new();
      buzzdarray_push(ne->swarms, &swarm);
      /* Add it to the structure */
      buzzdict_set(m, &robot, &ne);
   }
}
示例#29
0
文件: buzzlex.c 项目: MISTLab/Buzz
buzztok_t buzzlex_nexttok(buzzlex_t lex) {
   buzzlex_file_t lexf = buzzlex_getfile(lex);
   do {
      /* Look for a non-space character */
      do {
         /* Keep reading until you find a non-space character or end of stream */
         while(lexf->cur_c < lexf->buf_size &&
               buzzlex_isspace(lexf->buf[lexf->cur_c])) {
            nextchar();
         }
         /* End of stream? */
         if(lexf->cur_c >= lexf->buf_size) {
            /* Done with current file, go back to previous */
            buzzdarray_pop(lex);
            if(buzzdarray_isempty(lex))
               /* No file to go back to, done parsing */
               return NULL;
            lexf = buzzlex_getfile(lex);
         }
         else
            /* Non-space character found */
            break;
      } while(1);
      /* Non-space character found */
      /* If the current character is a '#' ignore the rest of the line */
      if(lexf->buf[lexf->cur_c] == '#') {
         do {
            nextchar();
         }
         while(lexf->cur_c < lexf->buf_size &&
               lexf->buf[lexf->cur_c] != '\n');
         /* End of stream? */
         if(lexf->cur_c >= lexf->buf_size) {
            /* Done with current file, go back to previous */
            buzzdarray_pop(lex);
            if(buzzdarray_isempty(lex))
               /* No file to go back to, done parsing */
               return NULL;
            lexf = buzzlex_getfile(lex);
         }
         else {
            /* New line and carry on */
            ++lexf->cur_line;
            lexf->cur_col = 0;
            ++lexf->cur_c;
         }
      }
      else if(strncmp(lexf->buf + lexf->cur_c, "include", 7) == 0) {
         /* Manage file inclusion */
         lexf->cur_c += 7;
         lexf->cur_col += 7;
         /* Skip whitespace */
         while(lexf->cur_c < lexf->buf_size &&
               buzzlex_isspace(lexf->buf[lexf->cur_c])) {
            nextchar();
         }
         /* End of file or not-string opening -> syntax error */
         if(lexf->cur_c >= lexf->buf_size ||
            !buzzlex_isquote(lexf->buf[lexf->cur_c])) {
            fprintf(stderr,
                    "%s:%" PRIu64 ":%" PRIu64 ": Syntax error: expected string after include\n",
                    lexf->fname,
                    lexf->cur_line,
                    lexf->cur_col);
            return NULL;
         }
         /* Read string */
         char quote = lexf->buf[lexf->cur_c];
         size_t start = lexf->cur_c + 1;
         nextchar();
         while(lexf->cur_c < lexf->buf_size &&
               lexf->buf[lexf->cur_c] != quote &&
               lexf->buf[lexf->cur_c] != '\n') {
            nextchar();
         }
         /* End of file or newline -> syntax error */
         if(lexf->cur_c >= lexf->buf_size ||
            lexf->buf[lexf->cur_c] == '\n') {
            fprintf(stderr,
                    "%s:%" PRIu64 ":%" PRIu64 ": Syntax error: expected end of string\n",
                    lexf->fname,
                    lexf->cur_line,
                    lexf->cur_col);
            return NULL;
         }
         /* Copy data into a new string */
         char* fname = (char*)malloc(lexf->cur_c - start + 1);
         strncpy(fname, lexf->buf + start, lexf->cur_c - start);
         fname[lexf->cur_c - start] = '\0';
         /* Get to next character in this file */
         nextchar();
         /* Create new file structure */
         buzzlex_file_t f = buzzlex_file_new(fname);
         if(!f) {
            fprintf(stderr,
                    "%s:%" PRIu64 ":%" PRIu64 ": Can't read '%s'\n",
                    lexf->fname,
                    lexf->cur_line,
                    lexf->cur_col,
                    fname);
            free(fname);
            return NULL;
         }
         free(fname);
         /* Make sure the file hasn't been already included */
         if(buzzdarray_find(lex, buzzlex_file_cmp, &f) < buzzdarray_size(lex)) {
            buzzlex_file_destroy(0, &f, NULL);
         }
         else {
            /* Push file structure */
            buzzdarray_push(lex, &f);
            lexf = buzzlex_getfile(lex);
         }
      }
      else
         /* The character must be parsed */
         break;
   }
   while(1);
   /* If we get here it's because we read potential token character */
   uint64_t tokstart = lexf->cur_col - 1;
   char c = lexf->buf[lexf->cur_c];
   nextchar();
   /* Consider the 1-char non-alphanumeric cases first */
   switch(c) {
      case '\n': {
         buzztok_t tok = buzzlex_newtok(BUZZTOK_STATEND,
                                        NULL,
                                        lexf->cur_line,
                                        tokstart,
                                        lexf->fname);
         ++lexf->cur_line;
         lexf->cur_col = 0;
         return tok;
      }
      casetokchar(';', BUZZTOK_STATEND);
      casetokchar('{', BUZZTOK_BLOCKOPEN);
      casetokchar('}', BUZZTOK_BLOCKCLOSE);
      casetokchar('(', BUZZTOK_PAROPEN);
      casetokchar(')', BUZZTOK_PARCLOSE);
      casetokchar('[', BUZZTOK_IDXOPEN);
      casetokchar(']', BUZZTOK_IDXCLOSE);
      casetokchar(',', BUZZTOK_LISTSEP);
      casetokchar('.', BUZZTOK_DOT);
   }
   /* If we get here, it's because we found either a constant, an
    * identifier, a keyword, an assignment, a comparison operator,
    * an arithmetic operator, or an unexpected character */
   if(isdigit(c)) {
      /* It's a constant */
      readval(buzzlex_isnumber);
      return buzzlex_newtok(BUZZTOK_CONST,
                            val,
                            lexf->cur_line,
                            tokstart,
                            lexf->fname);
   }
   else if(isalpha(c)) {
      /* It's either a keyword or an identifier */
      readval(buzzlex_isid);
      /* Go through the possible keywords */
      checkkeyword("var",      BUZZTOK_VAR);
      checkkeyword("if",       BUZZTOK_IF);
      checkkeyword("else",     BUZZTOK_ELSE);
      checkkeyword("function", BUZZTOK_FUN);
      checkkeyword("return",   BUZZTOK_RETURN);
      checkkeyword("for",      BUZZTOK_FOR);
      checkkeyword("while",    BUZZTOK_WHILE);
      checkkeyword("and",      BUZZTOK_ANDOR);
      checkkeyword("or",       BUZZTOK_ANDOR);
      checkkeyword("not",      BUZZTOK_NOT);
      checkkeyword("nil",      BUZZTOK_NIL);
      /* No keyword found, consider it an id */
      return buzzlex_newtok(BUZZTOK_ID,
                            val,
                            lexf->cur_line,
                            tokstart,
                            lexf->fname);
   }
   else if(c == '=') {
      /* Either an assignment or a comparison */
      if(lexf->cur_c < lexf->buf_size &&
         lexf->buf[lexf->cur_c] == '=') {
         /* It's a comparison */
         nextchar();
         return buzzlex_newtok(BUZZTOK_CMP,
                               strdup("=="),
                               lexf->cur_line,
                               tokstart,
                               lexf->fname);
      }
      else {
         /* It's an assignment */
         return buzzlex_newtok(BUZZTOK_ASSIGN,
                               NULL,
                               lexf->cur_line,
                               tokstart,
                               lexf->fname);
      }
   }
   else if(c == '!') {
      /* Comparison operator? */
      if(lexf->cur_c < lexf->buf_size &&
         lexf->buf[lexf->cur_c] == '=') {
         /* It's a comparison */
         nextchar();
         return buzzlex_newtok(BUZZTOK_CMP,
                               strdup("!="),
                               lexf->cur_line,
                               tokstart,
                               lexf->fname);
      }
      else {
         /* Syntax error */
         fprintf(stderr,
                 "%s:%" PRIu64 ":%" PRIu64 ": Syntax error: expected '=' after '!'\n",
                 lexf->fname,
                 lexf->cur_line,
                 tokstart);
         return NULL;
      }
   }
   else if((c == '<') || (c == '>')) {
      /* It's a comparison operator */
      size_t start = lexf->cur_c - 1;
      /* Include the '=' if present */
      if(lexf->cur_c < lexf->buf_size &&
         lexf->buf[lexf->cur_c] == '=') {
         nextchar();
      }
      char* val = (char*)malloc(lexf->cur_c - start + 1);
      strncpy(val, lexf->buf + start, lexf->cur_c - start);
      val[lexf->cur_c - start] = 0;
      return buzzlex_newtok(BUZZTOK_CMP,
                            val,
                            lexf->cur_line,
                            tokstart,
                            lexf->fname);
   }
   else if(buzzlex_isarith(c)) {
      /* Arithmetic operator */
      char* val = (char*)malloc(2);
      strncpy(val, lexf->buf + lexf->cur_c - 1, 1);
      val[1] = 0;
      switch(c) {
         case '+': case '-': {
            return buzzlex_newtok(BUZZTOK_ADDSUB,
                                  val,
                                  lexf->cur_line,
                                  tokstart,
                                  lexf->fname);
         }
         case '*': case '/': {
            return buzzlex_newtok(BUZZTOK_MULDIV,
                                  val,
                                  lexf->cur_line,
                                  tokstart,
                                  lexf->fname);
         }
         case '%': {
            return buzzlex_newtok(BUZZTOK_MOD,
                                  val,
                                  lexf->cur_line,
                                  tokstart,
                                  lexf->fname);
         }
         case '^': {
            return buzzlex_newtok(BUZZTOK_POW,
                                  val,
                                  lexf->cur_line,
                                  tokstart,
                                  lexf->fname);
         }
         default:
            return NULL;
      }
   }
   else if(buzzlex_isquote(c)) {
      /* String - eat any character until you find the next matching quote */
      size_t start = lexf->cur_c;
      char last1 = 0, last2 = 0;
      while(lexf->cur_c < lexf->buf_size &&    /* Not end of stream */
            ((lexf->buf[lexf->cur_c] != c) ||  /* Matching quote not found */
             (lexf->buf[lexf->cur_c] == c &&   /* Matching quote found, but preceded by \ and not \\ */
              last1 == '\\' && last2 != '\\'))) {
         /* Remember the last two characters read */
         last2 = last1;
         last1 = lexf->buf[lexf->cur_c];
         /* Keep parsing the string */
         if(lexf->buf[lexf->cur_c] != '\n') {
            nextchar();
         }
         else {
            fprintf(stderr,
                    "%s:%" PRIu64 ":%" PRIu64 ": Syntax error: string closing quote not found\n",
                    lexf->fname,
                    lexf->cur_line,
                    tokstart);
            return NULL;
         }
      }
      /* End of stream? Syntax error */
      if(lexf->cur_c >= lexf->buf_size) {
         fprintf(stderr,
                 "%s:%" PRIu64 ":%" PRIu64 ": Syntax error: string closing quote not found\n",
                 lexf->fname,
                 lexf->cur_line,
                 tokstart);
         return NULL;
      }
      /* We have a valid string */
      char* val = buzzlex_newstring(lexf->buf + start,
                                    lexf->cur_c - start);
      nextchar();
      return buzzlex_newtok(BUZZTOK_STRING,
                            val,
                            lexf->cur_line,
                            tokstart,
                            lexf->fname);
   }
   else {
      /* Unknown character */
      fprintf(stderr,
              "%s:%" PRIu64 ":%" PRIu64 ": Syntax error: unknown character '%c' (octal: %o; hex: %x)\n",
              lexf->fname,
              lexf->cur_line,
              tokstart,
              c, c, c);
      return NULL;
   }
}