A2_API int a2_pcall(struct a2_state* state, int args){ struct a2_obj* cls_obj = a2_getcstack(state->env_p, a2_top(state)-args-1); struct a2_obj* args_obj = a2_getcstack(state->env_p, a2_top(state)-args); if(obj_t(cls_obj) !=A2_TCLOSURE) a2_error(state->env_p, e_run_error, "the type is not closure at pcall.\n"); return a2_vm_pcall(a2_envvm(state->env_p), cls_obj, args_obj, args); }
int a2_libdostring(struct a2_state* state){ int args = a2_top(state); if(args==0 || a2_type(state, 0)!=TSTRING) a2_err(state, "the arg must string type."); const char* str = a2_tostring(state, 0); int top = a2_top(state); a2_dostring(state, str, strlen(str)); return a2_top(state) - top; }
int a2_libdofile(struct a2_state* state){ int args = a2_top(state); if(args==0 || a2_type(state, 0)!=TSTRING) a2_err(state, "the arg must string type."); const char* filename = a2_tostring(state, 0); int top = a2_top(state); a2_loadfile(state, filename); return a2_top(state) - top; }
int a2_libdostring(struct a2_state* state){ int args = a2_top(state); if(args==0 || a2_type(state, 0)!=TSTRING) a2_err(state, "the arg must string type."); const char* str = a2_tostring(state, 0); if(a2_dostring(state, str, strlen(str))){ printf("%s\n", a2_tostring(state, a2_top(state)-1)); } return 0; }
int a2_libsetmeta(struct a2_state* state){ int args = a2_top(state); if(args<2) a2_err(state, "the arg error."); a2_setmeta(state); return 0; }
int a2_libsystem(struct a2_state* state) { int args = a2_top(state); if(args==0 || a2_type(state, 0)!=TSTRING) a2_err(state, "the arg must string type."); const char* str = a2_tostring(state, 0); system(str); return 0; }
// type int a2_libtype(struct a2_state* state){ int args = a2_top(state); if(args==0) a2_err(state, "the number of args is error.[exp: type(varable)]"); a2_pushstring(state, (char*)(a2_typeinfo(state, 0))); a2_setvalue(state, 0); return 1; }
int a2_liblen(struct a2_state* state){ int args = a2_top(state); if(args==0) a2_err(state, "the number of args is error.[exp: len(varable)]"); a2_len(state, 0); a2_setvalue(state, 0); return 1; }
int a2_librequire(struct a2_state* state){ int args = a2_top(state); if(args == 0 || a2_type(state, 0)!=TSTRING) a2_err(state, "the arg must string type."); a2_pushvalue(state, 0); // set key a2_require(state); return 1; }
// del int a2_libdel(struct a2_state* state){ int args = a2_top(state); if(args==2 && a2_type(state, 0)==TMAP) a2_delmap(state); else a2_err(state, "exp: del(map, key)"); return 0; }
// add array A2_API inline void a2_addarray(struct a2_state* state){ int top = a2_top(state)-1; struct a2_obj* v = a2_getcstack(state->env_p, top); struct a2_obj* array = a2_getcstack(state->env_p, top-1); check_array(array); a2_array_add(a2_gcobj2array(obj_vX(array, obj)), v); }
// set global A2_API inline void a2_setglobal(struct a2_state* state){ int top = a2_top(state)-1; struct a2_obj* v = a2_getcstack(state->env_p, top); struct a2_obj* k = a2_getcstack(state->env_p, top-1); check_key(k); a2_set_envglobal(state->env_p, k, v); a2_topset(state, top-1); }
// get global A2_API inline void a2_getglobal(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_envglobal(state->env_p, k); if(v==NULL) obj_setX(k, A2_TNIL, point, NULL); else *k = *v; }
int a2_librandom(struct a2_state* state){ int args = a2_top(state); if(args == 0){ a2_pushnumber(state, (a2_number)rand()); }else{ a2_number num = a2_tonumber(state, 0); a2_pushnumber(state, rand()%((int)num)); } return 1; }
// del key/value A2_API inline void a2_delmap(struct a2_state* state){ int top = a2_top(state)-1; struct a2_obj* k = a2_getcstack(state->env_p, top); struct a2_obj* map = a2_getcstack(state->env_p, top-1); check_map(map); check_key(k); a2_map_del(a2_gcobj2map(obj_vX(map, obj)), k); a2_pop(state, 1); }
A2_API void a2_setmeta(struct a2_state* state){ int top = a2_top(state)-1; struct a2_obj* m = a2_getcstack(state->env_p, top); struct a2_obj* v = a2_getcstack(state->env_p, top-1); if(obj_t(v)!=A2_TMAP || obj_t(m)!=A2_TMAP) a2_err(state, "the value and meta should map type."); a2_gc_setmeta(obj_vX(v, obj), obj_vX(m, obj)); a2_topset(state, top-1); }
static void _command(struct a2_state* state){ for(;;){ char* str = NULL; if( NULL != (str = readline(">")) ){ if(str[0]=='='){ size_t sz = strlen(str)+7; char tmp [sz]; sprintf(tmp , "print(%s)", str+1); tmp[sz-1] = '\0'; if(a2_dostring(state, tmp, strlen(tmp))) printf("%s", a2_tostring(state, a2_top(state)-1)); }else{ if(a2_dostring(state, str, strlen(str))) printf("%s", a2_tostring(state, a2_top(state)-1)); } add_history(str); free(str); } } }
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)); } }
// get map A2_API inline void a2_getmap(struct a2_state* state){ int top = a2_top(state)-1; struct a2_obj* k = a2_getcstack(state->env_p, top); struct a2_obj* map = a2_getcstack(state->env_p, top-1); struct a2_obj* v = NULL; check_map(map); check_key(k); v = a2_map_query(a2_gcobj2map(obj_vX(map, obj)), k); if(v==NULL) obj_setX(map, A2_TNIL, point, NULL); else *map = *v; }
// get array A2_API inline void a2_getarray(struct a2_state* state){ int top = a2_top(state)-1; struct a2_obj* k = a2_getcstack(state->env_p, top); struct a2_obj* array = a2_getcstack(state->env_p, top-1); struct a2_obj* _v = NULL; check_array(array); check_num(k); _v = a2_array_get(a2_gcobj2array(obj_vX(array, obj)), k); if(_v==NULL) obj_setX(k, A2_TNIL, point, NULL); else *k = *_v; }
// set array A2_API inline void a2_setarray(struct a2_state* state){ int top = a2_top(state)-1; struct a2_obj* v = a2_getcstack(state->env_p, top); struct a2_obj* k = a2_getcstack(state->env_p, top-1); struct a2_obj* array = a2_getcstack(state->env_p, top-2); struct a2_obj* _v = NULL; check_array(array); check_num(k); _v = a2_array_get(a2_gcobj2array(obj_vX(array, obj)), k); if(_v==NULL) a2_error(state->env_p, e_run_error, "the error index at array.\n"); else *_v = *v; a2_topset(state, top-1); }
// add int a2_libadd(struct a2_state* state){ int args = a2_top(state); if(args<2) a2_err(state, "the number of args is error."); switch(a2_type(state, 0)){ case TARRAY: if(args!=2) a2_err(state, "the number of args is error at array add.[exp: add(array, value)]"); a2_addarray(state); break; case TMAP: if(args!=3) a2_err(state, "the number of args is error at map set.[exp: add(map, key value)]"); a2_setmap(state); break; default: a2_err(state, "the varable is not container."); } return 0; }
// print int a2_libprint(struct a2_state* state){ int args = a2_top(state); int i; for(i=0; i<args; i++){ switch(a2_type(state, i)){ case TNIL: printf("nil "); break; case TNUMBER: printf("%.14g ", a2_tonumber(state, i)); break; case TSTRING: printf("%s ", a2_tostring(state, i)); break; case TBOOL: printf("%s ", (a2_tobool(state, i))?("true"):("false")); break; case TCFUNCTION: printf("cfunc:%p ", a2_tocfunction(state, i)); break; case TCLOSURE: printf("closure:%p ", a2_topoint(state, i)); break; case TARRAY: printf("array:%p ", a2_topoint(state, i)); break; case TMAP: printf("map:%p ", a2_topoint(state, i)); break; default: assert(0); } } printf("\n"); return 0; }
static inline void _load(struct a2_state* state, const char* filename){ if(a2_loadfile(state, filename)){ printf("%s\n", a2_tostring(state, a2_top(state)-1)); } }