inline struct a2_obj* a2_array_next(struct a2_array* array_p, struct a2_obj* k){ assert(k); if(obj_t(k) == A2_TNIL){ obj_setNum(k, -1); } if( (size_t)(obj_vNum(k) + 1)>=array_p->len ) return NULL; struct a2_obj* v = &(array_p->list[(size_t)(obj_vNum(k)+1)]); a2_number number = (a2_number)((size_t)(obj_vNum(k))+1); obj_setNum(k, number); return v; }
// forloop static inline void _vm_forloop(struct a2_vm* vm_p){ struct a2_obj* _i = callinfo_sfreg(curr_ci, ir_ga(curr_ir)); struct a2_obj* _count = callinfo_sfreg(curr_ci, ir_ga(curr_ir)+1); struct a2_obj* _step = callinfo_sfreg(curr_ci, ir_ga(curr_ir)+2); if(obj_t(_i)!=A2_TNUMBER) vm_error("the index varable is must number."); assert(obj_t(_i)==A2_TNUMBER && obj_t(_count)==A2_TNUMBER && obj_t(_step)==A2_TNUMBER); obj_vNum(_i) += obj_vNum(_step); if(obj_vNum(_i) < obj_vNum(_count)) // continue for jump(ir_gbx(curr_ir)); else // for end curr_pc++; }
A2_API inline a2_number a2_tonumber(struct a2_state* state, int idx){ struct a2_obj* obj = a2_getcstack(state->env_p, idx); if(obj_t(obj)!=A2_TNUMBER) return 0.0; else return obj_vNum(obj); }
inline char* obj2str(struct a2_obj* obj, char* buf, size_t len){ assert(obj); switch(obj_t(obj)){ case A2_TNUMBER: snprintf(buf, len, "%.14g", obj_vNum(obj)); return buf; case A2_TSTRING: return a2_gcobj2string(obj_vX(obj, obj)); case A2_TBOOL: snprintf(buf, len, "%s", (obj_vX(obj, uinteger))?("true"):("false")); return buf; case A2_TNIL: return "nil"; case _A2_TADDR: _sf(buf, len, "[%zd]", obj_vX(obj, addr)); return buf; case A2_TCLOSURE: snprintf(buf, len, "closure:%p", a2_gcobj2closure(obj_vX(obj, obj))); return buf; case A2_TARRAY: snprintf(buf, len, "array:%p", a2_gcobj2array(obj_vX(obj, obj))); return buf; case A2_TMAP: snprintf(buf, len, "map:%p", a2_gcobj2map(obj_vX(obj, obj))); return buf; default: assert(0); } return NULL; }
inline struct a2_obj* a2_array_get(struct a2_array* array_p, struct a2_obj* k){ assert(obj_t(k)==A2_TNUMBER); size_t idx=(size_t)(obj_vNum(k)); if(idx>=array_p->len) return NULL; return &(array_p->list[idx]); }
// forprep static inline void _vm_forprep(struct a2_vm* vm_p){ struct a2_obj* _i = callinfo_sfreg(curr_ci, ir_ga(curr_ir)); struct a2_obj* _count = callinfo_sfreg(curr_ci, ir_ga(curr_ir)+1); struct a2_obj* _step = callinfo_sfreg(curr_ci, ir_ga(curr_ir)+2); if(obj_t(_i)!=A2_TNUMBER) vm_error("the index varable is must number."); if(obj_t(_count)!=A2_TNUMBER) vm_error("the for's count is must number."); if(obj_t(_step)!=A2_TNUMBER) vm_error("the for's step is must number."); if(obj_vNum(_i)>=obj_vNum(_count)) // for end jump(ir_gbx(curr_ir)); else // for continue curr_pc++; }
// neg static inline void _vm_neg(struct a2_vm* vm_p){ struct a2_obj* _d = callinfo_sfreg(curr_ci, ir_ga(curr_ir)); struct a2_obj* _v = _getvalue(vm_p, ir_gbx(curr_ir)); if(obj_t(_v)!=A2_TNUMBER) vm_error("the varable is not number type at set neg."); *_d = a2_number2obj(obj_vNum(_v)*(-1)); curr_pc++; }
// test obj dump void obj_dump(struct a2_obj* obj){ switch(obj_t(obj)){ case A2_TSTRING: printf("%s", a2_gcobj2string(obj_vX(obj, obj))); break; case A2_TNUMBER: printf("%.14g", obj_vNum(obj)); break; default: printf("<null>"); break; } }
byte* a2_obj_bytes(struct a2_obj* obj_p){ assert(obj_p); switch(obj_t(obj_p)){ case A2_TSTRING: return (byte*)(a2_gcobj2string(obj_vX(obj_p, obj))); case A2_TNUMBER: return (byte*)(&obj_vNum(obj_p)); case A2_TNIL: return NULL; case A2_TBOOL: return (byte*)(&obj_vX(obj_p, uinteger)); case _A2_TADDR: return (byte*)(&obj_vX(obj_p, addr)); default: assert(0); return NULL; } }