void CBuzzControllerFootBot::UpdateSensors() { /* * Update generic sensors */ CBuzzController::UpdateSensors(); /* * Update proximity sensor table */ if(m_pcProximity != NULL) { /* Create empty proximity table */ buzzvm_pushs(m_tBuzzVM, buzzvm_string_register(m_tBuzzVM, "proximity", 1)); buzzvm_pusht(m_tBuzzVM); buzzobj_t tProxTable = buzzvm_stack_at(m_tBuzzVM, 1); buzzvm_gstore(m_tBuzzVM); /* Get proximity readings */ const CCI_FootBotProximitySensor::TReadings& tProxReads = m_pcProximity->GetReadings(); /* Fill into the proximity table */ buzzobj_t tProxRead; for(size_t i = 0; i < tProxReads.size(); ++i) { /* Create table for i-th read */ buzzvm_pusht(m_tBuzzVM); tProxRead = buzzvm_stack_at(m_tBuzzVM, 1); buzzvm_pop(m_tBuzzVM); /* Fill in the read */ TablePut(tProxRead, "value", tProxReads[i].Value); TablePut(tProxRead, "angle", tProxReads[i].Angle); /* Store read table in the proximity table */ TablePut(tProxTable, i, tProxRead); } } }
void CBuzzControllerFootBot::UpdateSensors() { /* * Update generic sensors */ CBuzzController::UpdateSensors(); /* * Update proximity sensor table */ if(m_pcProximity != NULL) { /* Create empty proximity table */ buzzvm_pushs(m_tBuzzVM, buzzvm_string_register(m_tBuzzVM, "proximity", 1)); buzzvm_pusht(m_tBuzzVM); buzzobj_t tProxTable = buzzvm_stack_at(m_tBuzzVM, 1); buzzvm_gstore(m_tBuzzVM); /* Get proximity readings */ const CCI_FootBotProximitySensor::TReadings& tProxReads = m_pcProximity->GetReadings(); /* Fill into the proximity table */ buzzobj_t tProxRead; for(size_t i = 0; i < tProxReads.size(); ++i) { /* Create table for i-th read */ buzzvm_pusht(m_tBuzzVM); tProxRead = buzzvm_stack_at(m_tBuzzVM, 1); buzzvm_pop(m_tBuzzVM); /* Fill in the read */ TablePut(tProxRead, "value", tProxReads[i].Value); TablePut(tProxRead, "angle", tProxReads[i].Angle); /* Store read table in the proximity table */ TablePut(tProxTable, i, tProxRead); } } /* * Camera */ if(m_pcCamera) { buzzvm_pushs(m_tBuzzVM, buzzvm_string_register(m_tBuzzVM, "blobs", 1)); buzzvm_pusht(m_tBuzzVM); buzzobj_t tBlobs = buzzvm_stack_at(m_tBuzzVM, 1); buzzvm_gstore(m_tBuzzVM); const CCI_ColoredBlobOmnidirectionalCameraSensor::SReadings& sBlobs = m_pcCamera->GetReadings(); for(size_t i = 0; i < sBlobs.BlobList.size(); ++i) { buzzvm_pusht(m_tBuzzVM); buzzobj_t tEntry = buzzvm_stack_at(m_tBuzzVM, 1); buzzvm_pop(m_tBuzzVM); TablePut(tBlobs, i, tEntry); TablePut(tEntry, "distance", sBlobs.BlobList[i]->Distance); TablePut(tEntry, "angle", sBlobs.BlobList[i]->Angle); TablePut(tEntry, "color", sBlobs.BlobList[i]->Color); } } }
void buzzvm_vstig_onconflictlost(buzzvm_t vm, buzzvstig_t vs, buzzobj_t k, buzzvstig_elem_t lv) { /* Was a conflict manager defined? */ if(vs->onconflictlost) { /* Push closure */ buzzvm_push(vm, vs->onconflictlost); /* 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); /* Call closure with 2 arguments */ buzzvm_push(vm, loc); buzzvm_closure_call(vm, 2); } }
int buzzvstig_create(buzzvm_t vm) { buzzvm_lnum_assert(vm, 1); /* Get vstig id */ buzzvm_lload(vm, 1); buzzvm_type_assert(vm, 1, BUZZTYPE_INT); uint16_t id = buzzvm_stack_at(vm, 1)->i.value; buzzvm_pop(vm); /* Look for virtual stigmergy */ const buzzvstig_t* vs = buzzdict_get(vm->vstigs, &id, buzzvstig_t); if(vs) { /* Found, destroy it */ buzzdict_remove(vm->vstigs, &id); } /* Create a new virtual stigmergy */ buzzvstig_t nvs = buzzvstig_new(); buzzdict_set(vm->vstigs, &id, &nvs); /* Create a table */ buzzvm_pusht(vm); /* Add data and methods */ buzzvm_dup(vm); buzzvm_pushs(vm, buzzvm_string_register(vm, "id", 1)); buzzvm_pushi(vm, id); buzzvm_tput(vm); function_register(foreach); function_register(size); function_register(put); function_register(get); function_register(onconflict); function_register(onconflictlost); /* Return the table */ return buzzvm_ret1(vm); }
buzzvm_state CBuzzController::Register(const std::string& str_key, const CColor& c_color) { buzzvm_pushs(m_tBuzzVM, buzzvm_string_register(m_tBuzzVM, str_key.c_str(), 1)); buzzvm_pusht(m_tBuzzVM); buzzobj_t tColorTable = buzzvm_stack_at(m_tBuzzVM, 1); buzzvm_gstore(m_tBuzzVM); TablePut(tColorTable, "red", c_color.GetRed()); TablePut(tColorTable, "green", c_color.GetGreen()); TablePut(tColorTable, "blue", c_color.GetBlue()); return m_tBuzzVM->state; }
buzzvm_state CBuzzController::Register(const std::string& str_key, const CVector3& c_vec) { buzzvm_pushs(m_tBuzzVM, buzzvm_string_register(m_tBuzzVM, str_key.c_str(), 1)); buzzvm_pusht(m_tBuzzVM); buzzobj_t tVecTable = buzzvm_stack_at(m_tBuzzVM, 1); buzzvm_gstore(m_tBuzzVM); TablePut(tVecTable, "x", c_vec.GetX()); TablePut(tVecTable, "y", c_vec.GetY()); TablePut(tVecTable, "z", c_vec.GetZ()); return m_tBuzzVM->state; }
buzzvm_state CBuzzController::Register(const std::string& str_key, const CQuaternion& c_quat) { buzzvm_pushs(m_tBuzzVM, buzzvm_string_register(m_tBuzzVM, str_key.c_str(), 1)); buzzvm_pusht(m_tBuzzVM); buzzobj_t tQuatTable = buzzvm_stack_at(m_tBuzzVM, 1); buzzvm_gstore(m_tBuzzVM); CRadians cYaw, cPitch, cRoll; c_quat.ToEulerAngles(cYaw, cPitch, cRoll); TablePut(tQuatTable, "yaw", cYaw); TablePut(tQuatTable, "pitch", cPitch); TablePut(tQuatTable, "roll", cRoll); return m_tBuzzVM->state; }
int buzzvstig_register(struct buzzvm_s* vm) { /* Push 'stigmergy' table */ buzzvm_pushs(vm, buzzvm_string_register(vm, "stigmergy", 1)); buzzvm_pusht(vm); /* Add 'create' function */ buzzvm_dup(vm); buzzvm_pushs(vm, buzzvm_string_register(vm, "create", 1)); buzzvm_pushcc(vm, buzzvm_function_register(vm, buzzvstig_create)); buzzvm_tput(vm); /* Register the 'stigmergy' table */ buzzvm_gstore(vm); return vm->state; }
buzzvm_state CBuzzController::TablePut(buzzobj_t t_table, SInt32 n_idx, const CColor& c_color) { buzzvm_push(m_tBuzzVM, t_table); buzzvm_pushi(m_tBuzzVM, n_idx); buzzvm_pusht(m_tBuzzVM); buzzobj_t tColorTable = buzzvm_stack_at(m_tBuzzVM, 1); buzzvm_tput(m_tBuzzVM); TablePut(tColorTable, "red", c_color.GetRed()); TablePut(tColorTable, "green", c_color.GetGreen()); TablePut(tColorTable, "blue", c_color.GetBlue()); return m_tBuzzVM->state; }
buzzvm_state CBuzzController::TablePut(buzzobj_t t_table, SInt32 n_idx, const CVector3& c_vec) { buzzvm_push(m_tBuzzVM, t_table); buzzvm_pushi(m_tBuzzVM, n_idx); buzzvm_pusht(m_tBuzzVM); buzzobj_t tVecTable = buzzvm_stack_at(m_tBuzzVM, 1); buzzvm_tput(m_tBuzzVM); TablePut(tVecTable, "x", c_vec.GetX()); TablePut(tVecTable, "y", c_vec.GetY()); TablePut(tVecTable, "z", c_vec.GetZ()); return m_tBuzzVM->state; }
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; }
buzzvm_state CBuzzController::TablePut(buzzobj_t t_table, SInt32 n_idx, const CQuaternion& c_quat) { buzzvm_push(m_tBuzzVM, t_table); buzzvm_pushi(m_tBuzzVM, n_idx); buzzvm_pusht(m_tBuzzVM); buzzobj_t tQuatTable = buzzvm_stack_at(m_tBuzzVM, 1); buzzvm_tput(m_tBuzzVM); CRadians cYaw, cPitch, cRoll; c_quat.ToEulerAngles(cYaw, cPitch, cRoll); TablePut(tQuatTable, "yaw", cYaw); TablePut(tQuatTable, "pitch", cPitch); TablePut(tQuatTable, "roll", cRoll); return m_tBuzzVM->state; }
void CBuzzControllerSpiri::UpdateSensors() { /* Positioning */ if(m_pcPosition) { Register("position", m_pcPosition->GetReading().Position); Register("orientation", m_pcPosition->GetReading().Orientation); } /* Camera */ if(m_pcCamera) { buzzvm_pushs(m_tBuzzVM, buzzvm_string_register(m_tBuzzVM, "blobs", 1)); buzzvm_pusht(m_tBuzzVM); buzzobj_t tBlobs = buzzvm_stack_at(m_tBuzzVM, 1); buzzvm_gstore(m_tBuzzVM); const CCI_ColoredBlobPerspectiveCameraSensor::SReadings& sBlobs = m_pcCamera->GetReadings(); for(size_t i = 0; i < sBlobs.BlobList.size(); ++i) { buzzvm_pusht(m_tBuzzVM); buzzobj_t tEntry = buzzvm_stack_at(m_tBuzzVM, 1); buzzvm_pop(m_tBuzzVM); TablePut(tBlobs, i, tEntry); TablePut(tEntry, "px", sBlobs.BlobList[i]->X); TablePut(tEntry, "py", sBlobs.BlobList[i]->Y); TablePut(tEntry, "color", sBlobs.BlobList[i]->Color); } } }
void buzzvstig_onconflictlost_call(buzzvm_t vm, buzzvstig_t vs, buzzobj_t k, buzzvstig_elem_t lv) { /* Was a conflict manager defined? */ if(vs->onconflictlost) { /* Push closure */ buzzvm_push(vm, vs->onconflictlost); /* 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); /* Call closure (key and table are on the stack) */ buzzvm_closure_call(vm, 2); } }
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); } }
buzzvm_state CBuzzController::RegisterFunctions() { /* * Pointer to this controller */ buzzvm_pushs(m_tBuzzVM, buzzvm_string_register(m_tBuzzVM, "controller", 1)); buzzvm_pushu(m_tBuzzVM, this); buzzvm_gstore(m_tBuzzVM); /* * BuzzLOG */ buzzvm_pushs(m_tBuzzVM, buzzvm_string_register(m_tBuzzVM, "log", 1)); buzzvm_pushcc(m_tBuzzVM, buzzvm_function_register(m_tBuzzVM, BuzzLOG)); buzzvm_gstore(m_tBuzzVM); /* * Buzz debug facilities */ /* Initialize debug table */ buzzvm_pushs(m_tBuzzVM, buzzvm_string_register(m_tBuzzVM, "debug", 1)); buzzvm_pusht(m_tBuzzVM); /* debug.print() */ buzzvm_dup(m_tBuzzVM); buzzvm_pushs(m_tBuzzVM, buzzvm_string_register(m_tBuzzVM, "print", 1)); buzzvm_pushcc(m_tBuzzVM, buzzvm_function_register(m_tBuzzVM, BuzzDebugPrint)); buzzvm_tput(m_tBuzzVM); /* Initialize debug.rays table */ buzzvm_dup(m_tBuzzVM); buzzvm_pushs(m_tBuzzVM, buzzvm_string_register(m_tBuzzVM, "rays", 1)); buzzvm_pusht(m_tBuzzVM); /* debug.rays.add() */ buzzvm_dup(m_tBuzzVM); buzzvm_pushs(m_tBuzzVM, buzzvm_string_register(m_tBuzzVM, "add", 1)); buzzvm_pushcc(m_tBuzzVM, buzzvm_function_register(m_tBuzzVM, BuzzDebugRayAdd)); buzzvm_tput(m_tBuzzVM); /* debug.rays.clear() */ buzzvm_dup(m_tBuzzVM); buzzvm_pushs(m_tBuzzVM, buzzvm_string_register(m_tBuzzVM, "clear", 1)); buzzvm_pushcc(m_tBuzzVM, buzzvm_function_register(m_tBuzzVM, BuzzDebugRayClear)); buzzvm_tput(m_tBuzzVM); /* Finalize debug.rays table */ buzzvm_tput(m_tBuzzVM); if(m_pcPos != NULL) { /* Initialize debug.trajectory table */ buzzvm_dup(m_tBuzzVM); buzzvm_pushs(m_tBuzzVM, buzzvm_string_register(m_tBuzzVM, "trajectory", 1)); buzzvm_pusht(m_tBuzzVM); /* debug.trajectory.enable() */ buzzvm_dup(m_tBuzzVM); buzzvm_pushs(m_tBuzzVM, buzzvm_string_register(m_tBuzzVM, "enable", 1)); buzzvm_pushcc(m_tBuzzVM, buzzvm_function_register(m_tBuzzVM, BuzzDebugTrajectoryEnable)); buzzvm_tput(m_tBuzzVM); /* debug.trajectory.disable() */ buzzvm_dup(m_tBuzzVM); buzzvm_pushs(m_tBuzzVM, buzzvm_string_register(m_tBuzzVM, "disable", 1)); buzzvm_pushcc(m_tBuzzVM, buzzvm_function_register(m_tBuzzVM, BuzzDebugTrajectoryDisable)); buzzvm_tput(m_tBuzzVM); /* debug.trajectory.clear() */ buzzvm_dup(m_tBuzzVM); buzzvm_pushs(m_tBuzzVM, buzzvm_string_register(m_tBuzzVM, "clear", 1)); buzzvm_pushcc(m_tBuzzVM, buzzvm_function_register(m_tBuzzVM, BuzzDebugTrajectoryClear)); buzzvm_tput(m_tBuzzVM); /* Finalize debug.trajectory table */ buzzvm_tput(m_tBuzzVM); } /* Finalize debug table */ buzzvm_gstore(m_tBuzzVM); return m_tBuzzVM->state; }
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; } }
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; }