#include #include #include #include "lib.h" #include "state.h" #include "val.h" #include "util.h" #include "mem.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"); for (int i = 0; i < nargs; i++) print_val(args[i]); return VAL_NIL; } static Val fn_say(State *S, int nargs, Val *args) { CHECK(nargs>0, "need 1 arg to say"); for (int i = 0; i < nargs; i++) println_val(args[i]); return VAL_NIL; } static uint8_t num_to_u8(Val v) { CHECK(IS_NUM(v), "can't convert non-num to u8"); return (uint8_t)AS_NUM(v); } static Val fn_writebytes(State *S, int nargs, Val *args) { CHECK(nargs == 1, "need exactly 1 arg to writebytes"); CHECK(IS_ARR(args[0]), "need array arg to writebytes"); ObjArr *a = AS_ARR(args[0]); uint8_t *buf = malloc(1 * a->len); for (int i = 0; i < a->len; i++) { buf[i] = num_to_u8(a->d[i]); } fwrite(buf, 1, a->len, stdout); 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); } // strings static Val fn_spend(State *S, int nargs, Val *args) { size_t len = 0; for (int i = 0; i < nargs; i++) { CHECK(IS_STRING(args[i]), "can only spend strings"); len += AS_STRING(args[i])->len; } char *new = NEW_ARR(S, char, len+1); char *cur = new; for (int i = 0; i < nargs; i++) { ObjString *s = AS_STRING(args[i]); memcpy(cur, s->d, s->len); cur += s->len; } return VAL_OBJ(objstring_take(S, new, len)); } typedef struct { char *name; CFunc func; } BuiltinFunc; static BuiltinFunc builtin_funcs[] = { { "clock", fn_clock }, { "say", fn_say }, { "write", fn_write }, { "writebytes", fn_writebytes }, { "arr", fn_arr }, { "append!", fn_append }, { "#", fn_len }, { ",", fn_pend }, { "s,", fn_spend }, { 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)); } }