A2_API inline char* a2_tostring(struct a2_state* state, int idx){ struct a2_obj* obj = a2_getcstack(state->env_p, idx); if(obj_t(obj)!=A2_TSTRING) return ""; else return a2_gcobj2string(obj_vX(obj, 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; }
// 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; } }
// get data size from a2_obj size_t a2_obj_size(struct a2_obj* obj_p){ assert(obj_p); switch(obj_t(obj_p)){ case A2_TSTRING: return a2_string_len(a2_gcobj2string(obj_vX(obj_p, obj))); case A2_TNUMBER: return sizeof(a2_number); case A2_TNIL: return 0; case A2_TBOOL: return sizeof(obj_vX(obj_p, uinteger)); case _A2_TADDR: return sizeof(obj_vX(obj_p, addr)); default: assert(0); return 0; } }
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; } }
A2_API inline void a2_len(struct a2_state* state, int idx){ struct a2_obj* obj = a2_getcstack(state->env_p, idx); size_t len =0; struct a2_obj len_obj; switch(obj_t(obj)){ case A2_TMAP: len = a2_map_len(a2_gcobj2map(obj_vX(obj, obj))); break; case A2_TARRAY: len = a2_array_len(a2_gcobj2array(obj_vX(obj, obj))); break; case A2_TSTRING: len = a2_string_len(a2_gcobj2string(obj_vX(obj, obj))); break; default: a2_error(state->env_p, e_run_error, "the type is not map or array at len function."); } len_obj = a2_number2obj((a2_number)len); a2_pushstack(state->env_p, &len_obj); }
A2_API inline void a2_require(struct a2_state* state){ struct a2_obj* k = a2_getcstack(state->env_p, a2_top(state)-1); check_key(k); struct a2_obj* v = a2_get_envreg(state->env_p, k); if(v) // return obj a2_pushstack(state->env_p, v); else{ // load obj const char* name = a2_gcobj2string(obj_vX(k, obj)); int len = strlen(name); char tmp[len+8]; memcpy(tmp, name, len); memcpy(tmp+len, ".a2", 4); int top = a2_top(state); a2_loadfile(state, tmp); if(a2_top(state)>top) a2_pushvalue(state, top); else a2_pushnil(state); a2_set_envreg(state->env_p, k, a2_getcstack(state->env_p, top)); } }