#include #include "lib.h" #include "state.h" #include "val.h" #include "util.h" static Val fn_clock(State *S, int nargs, Val *args) { return VAL_NUM((double)clock() / CLOCKS_PER_SEC); } static Val fn_write(State *S, int nargs, Val *args) { CHECK(nargs>0, "need 1 arg to write"); print_val(args[0]); return VAL_NIL; } static Val fn_say(State *S, int nargs, Val *args) { CHECK(nargs>0, "need 1 arg to say"); println_val(args[0]); return VAL_NIL; } // lists static Val fn_arr(State *S, int nargs, Val *args) { CHECK(nargs == 0, "need 0 args to arr"); ObjArr *o = objarr_new(S); return VAL_OBJ(o); } static Val fn_append(State *S, int nargs, Val *args) { CHECK(nargs == 2, "need 2 args to append"); CHECK(IS_ARR(args[0]), "can only append to arr"); ObjArr *a = AS_ARR(args[0]); objarr_append(S, a, args[1]); return args[0]; } static Val fn_len(State *S, int nargs, Val *args) { CHECK(nargs == 1, "need 1 arg to len"); CHECK(IS_ARR(args[0]), "can only take length of arr"); ObjArr *a = AS_ARR(args[0]); return VAL_NUM(a->len); } static Val fn_pend(State *S, int nargs, Val *args) { CHECK(nargs > 0, "need at least 1 arg to ,"); ObjArr *a = objarr_new(S); for (int i = 0; i < nargs; i++) { Val v = args[i]; if (!IS_ARR(v)) objarr_append(S, a, v); else { ObjArr *b = AS_ARR(v); for (int j = 0; j < b->len; j++) objarr_append(S, a, b->d[j]); } } return VAL_OBJ(a); } typedef struct { char *name; CFunc func; } BuiltinFunc; static BuiltinFunc builtin_funcs[] = { { "clock", fn_clock }, { "say", fn_say }, { "write", fn_write }, { "arr", fn_arr }, { "append", fn_append }, { "len", fn_len }, { ",", fn_pend }, { 0 }, }; void load_stdlib(State *S) { for (BuiltinFunc *b = builtin_funcs; b->name != NULL; b++) { ObjString *oname = objstring_copy_cstr(S, b->name); ht_put(S, &S->globals, oname, VAL_CFUNC(b->func)); } }