Beispiel #1
0
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);
   }
}
Beispiel #2
0
void buzzmsg_serialize_u32(buzzdarray_t buf,
                           uint32_t data) {
   uint32_t x = htonl(data);
   buzzdarray_push(buf, (uint8_t*)(&x));
   buzzdarray_push(buf, (uint8_t*)(&x)+1);
   buzzdarray_push(buf, (uint8_t*)(&x)+2);
   buzzdarray_push(buf, (uint8_t*)(&x)+3);
}
Beispiel #3
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;
}
Beispiel #4
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);
}
Beispiel #5
0
buzzvm_state buzzvm_pushc(buzzvm_t vm, int32_t rfrnc, int32_t nat) {
   buzzobj_t o = buzzheap_newobj(vm, BUZZTYPE_CLOSURE);
   o->c.value.isnative = nat;
   o->c.value.ref = rfrnc;
   buzzobj_t nil = buzzheap_newobj(vm, BUZZTYPE_NIL);
   buzzdarray_push(o->c.value.actrec, &nil);
   buzzvm_push(vm, o);
   return vm->state;
}
Beispiel #6
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;
}
Beispiel #7
0
buzzvm_state buzzvm_dup(buzzvm_t vm) {
   if(buzzdarray_isempty(vm->stack)) {
      buzzvm_seterror(vm, BUZZVM_ERROR_STACK, "empty stack");
      return vm->state;
   }
   else {
      buzzobj_t x = buzzvm_stack_at(vm, 1);
      buzzdarray_push(vm->stack, &x);
   }
   return vm->state;
}
Beispiel #8
0
buzzlex_t buzzlex_new(const char* fname) {
   /* The lexer corresponds to a stack of file information */
   buzzlex_t x = buzzdarray_new(10,
                                sizeof(struct buzzlex_file_s*),
                                buzzlex_file_destroy);
   /* Read file */
   buzzlex_file_t f = buzzlex_file_new(fname);
   if(!f) return NULL;
   buzzdarray_push(x, &f);
   /* Return the lexer state */
   return x;
}
Beispiel #9
0
void buzzmsg_serialize_string(buzzdarray_t buf,
                              const char* data) {
   /* Get the length of the string */
   uint16_t len = strlen(data);
   /* Push that into the buffer */
   buzzmsg_serialize_u16(buf, len);
   /* Go through the characters and push them into the buffer */
   const char* c = data;
   while(*c) {
      buzzdarray_push(buf, (uint8_t*)(c));
      ++c;
   }
}
Beispiel #10
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;
}
Beispiel #11
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);
   }
}
Beispiel #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);
   }
}
Beispiel #13
0
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;
   }
}
Beispiel #14
0
void buzzmsg_serialize_u16(buzzdarray_t buf,
                           uint16_t data) {
   uint16_t x = htons(data);
   buzzdarray_push(buf, (uint8_t*)(&x));
   buzzdarray_push(buf, (uint8_t*)(&x)+1);
}
Beispiel #15
0
void buzzmsg_serialize_u8(buzzdarray_t buf,
                          uint8_t data) {
   buzzdarray_push(buf, &data);
}
Beispiel #16
0
buzzvm_state buzzvm_push(buzzvm_t vm, buzzobj_t v) {
   buzzdarray_push(vm->stack, &v);
   return vm->state;
}
Beispiel #17
0
buzzvm_t buzzvm_new(uint16_t robot) {
   /* Create VM state. calloc() takes care of zeroing everything */
   buzzvm_t vm = (buzzvm_t)calloc(1, sizeof(struct buzzvm_s));
   /* Create stacks */
   vm->stacks = buzzdarray_new(BUZZVM_STACKS_INIT_CAPACITY,
                               sizeof(buzzdarray_t),
                               buzzvm_darray_destroy);
   vm->stack = buzzdarray_new(BUZZVM_STACK_INIT_CAPACITY,
                              sizeof(buzzobj_t),
                              NULL);
   buzzdarray_push(vm->stacks, &(vm->stack));
   /* Create local variable tables */
   vm->lsymts = buzzdarray_new(BUZZVM_LSYMTS_INIT_CAPACITY,
                               sizeof(buzzvm_lsyms_t),
                               buzzvm_lsyms_destroy);
   vm->lsyms = NULL;
   /* Create global variable tables */
   vm->gsyms = buzzdict_new(BUZZVM_SYMS_INIT_CAPACITY,
                            sizeof(int32_t),
                            sizeof(buzzobj_t),
                            buzzdict_int32keyhash,
                            buzzdict_int32keycmp,
                            NULL);
   /* Create string list */
   vm->strings = buzzstrman_new();
   /* Create heap */
   vm->heap = buzzheap_new();
   /* Create function list */
   vm->flist = buzzdarray_new(20, sizeof(buzzvm_funp), NULL);
   /* Create swarm list */
   vm->swarms = buzzdict_new(10,
                             sizeof(uint16_t),
                             sizeof(uint8_t),
                             buzzdict_uint16keyhash,
                             buzzdict_uint16keycmp,
                             NULL);
   /* Create swarm stack */
   vm->swarmstack = buzzdarray_new(10,
                                   sizeof(uint16_t),
                                   NULL);
   /* Create swarm member structure */
   vm->swarmmembers = buzzswarm_members_new();
   vm->swarmbroadcast = SWARM_BROADCAST_PERIOD;
   /* Create message queues */
   vm->inmsgs = buzzinmsg_queue_new();
   vm->outmsgs = buzzoutmsg_queue_new(robot);
   /* Create virtual stigmergy */
   vm->vstigs = buzzdict_new(10,
                             sizeof(uint16_t),
                             sizeof(buzzvstig_t),
                             buzzdict_uint16keyhash,
                             buzzdict_uint16keycmp,
                             buzzvm_vstig_destroy);
   /* Create virtual stigmergy */
   vm->listeners = buzzdict_new(10,
                                sizeof(uint16_t),
                                sizeof(buzzobj_t),
                                buzzdict_uint16keyhash,
                                buzzdict_uint16keycmp,
                                NULL);
   /* Take care of the robot id */
   vm->robot = robot;
   /* Initialize empty random number generator (buzzvm_math takes care of creating it) */
   vm->rngstate = NULL;
   vm->rngidx = 0;
   /* Return new vm */
   return vm;
}