1
0
mirror of https://github.com/janet-lang/janet synced 2024-11-28 11:09:54 +00:00

Update C API to use friendlier functions rather than macros.

Error handling is implemented with setjmp/longjmp so code
can be more concise. This required a very large but straight forward refactor for all
of the libraries.
This commit is contained in:
Calvin Rose 2019-01-05 20:09:03 -05:00
parent 5b62c8e6db
commit b60e3e302a
23 changed files with 1066 additions and 1534 deletions

View File

@ -118,135 +118,97 @@ Janet janet_array_peek(JanetArray *array) {
/* C Functions */
static int cfun_new(JanetArgs args) {
int32_t cap;
JanetArray *array;
JANET_FIXARITY(args, 1);
JANET_ARG_INTEGER(cap, args, 0);
array = janet_array(cap);
JANET_RETURN_ARRAY(args, array);
static Janet cfun_new(int32_t argc, Janet *argv) {
janet_arity(argc, 1, 1);
int32_t cap = janet_getinteger(argv, 0);
JanetArray *array = janet_array(cap);
return janet_wrap_array(array);
}
static int cfun_pop(JanetArgs args) {
JanetArray *array;
JANET_FIXARITY(args, 1);
JANET_ARG_ARRAY(array, args, 0);
JANET_RETURN(args, janet_array_pop(array));
static Janet cfun_pop(int32_t argc, Janet *argv) {
janet_arity(argc, 1, 1);
JanetArray *array = janet_getarray(argv, 0);
return janet_array_pop(array);
}
static int cfun_peek(JanetArgs args) {
JanetArray *array;
JANET_FIXARITY(args, 1);
JANET_ARG_ARRAY(array, args, 0);
JANET_RETURN(args, janet_array_peek(array));
static Janet cfun_peek(int32_t argc, Janet *argv) {
janet_arity(argc, 1, 1);
JanetArray *array = janet_getarray(argv, 0);
return janet_array_peek(array);
}
static int cfun_push(JanetArgs args) {
JanetArray *array;
int32_t newcount;
JANET_MINARITY(args, 1);
JANET_ARG_ARRAY(array, args, 0);
newcount = array->count - 1 + args.n;
static Janet cfun_push(int32_t argc, Janet *argv) {
janet_arity(argc, 1, -1);
JanetArray *array = janet_getarray(argv, 0);
int32_t newcount = array->count - 1 + argc;
janet_array_ensure(array, newcount, 2);
if (args.n > 1) memcpy(array->data + array->count, args.v + 1, (args.n - 1) * sizeof(Janet));
if (argc > 1) memcpy(array->data + array->count, argv + 1, (argc - 1) * sizeof(Janet));
array->count = newcount;
JANET_RETURN(args, args.v[0]);
return argv[0];
}
static int cfun_ensure(JanetArgs args) {
JanetArray *array;
int32_t newcount;
int32_t growth;
JANET_FIXARITY(args, 3);
JANET_ARG_ARRAY(array, args, 0);
JANET_ARG_INTEGER(newcount, args, 1);
JANET_ARG_INTEGER(growth, args, 2);
if (newcount < 0) JANET_THROW(args, "expected positive integer");
static Janet cfun_ensure(int32_t argc, Janet *argv) {
janet_arity(argc, 3, 3);
JanetArray *array = janet_getarray(argv, 0);
int32_t newcount = janet_getinteger(argv, 1);
int32_t growth = janet_getinteger(argv, 2);
if (newcount < 1) janet_panic("expected positive integer");
janet_array_ensure(array, newcount, growth);
JANET_RETURN(args, args.v[0]);
return argv[0];
}
static int cfun_slice(JanetArgs args) {
const Janet *vals;
int32_t len;
JanetArray *ret;
int32_t start, end;
JANET_MINARITY(args, 1);
JANET_MAXARITY(args, 3);
if (!janet_indexed_view(args.v[0], &vals, &len))
JANET_THROW(args, "expected array|tuple");
/* Get start */
if (args.n < 2) {
start = 0;
} else {
JANET_ARG_INTEGER(start, args, 1);
}
/* Get end */
if (args.n < 3) {
end = -1;
} else {
JANET_ARG_INTEGER(end, args, 2);
}
if (start < 0) start = len + start;
if (end < 0) end = len + end + 1;
if (end < 0 || start < 0 || end > len || start > len)
JANET_THROW(args, "slice range out of bounds");
if (end >= start) {
ret = janet_array(end - start);
memcpy(ret->data, vals + start, sizeof(Janet) * (end - start));
ret->count = end - start;
} else {
ret = janet_array(0);
}
JANET_RETURN_ARRAY(args, ret);
static Janet cfun_slice(int32_t argc, Janet *argv) {
JanetRange range = janet_getslice(argc, argv);
JanetView view = janet_getindexed(argv, 0);
JanetArray *array = janet_array(range.end - range.start);
memcpy(array->data, view.items + range.start, sizeof(Janet) * (range.end - range.start));
array->count = range.end - range.start;
return janet_wrap_array(array);
}
static int cfun_concat(JanetArgs args) {
static Janet cfun_concat(int32_t argc, Janet *argv) {
int32_t i;
JanetArray *array;
JANET_MINARITY(args, 1);
JANET_ARG_ARRAY(array, args, 0);
for (i = 1; i < args.n; i++) {
switch (janet_type(args.v[i])) {
janet_arity(argc, 1, -1);
JanetArray *array = janet_getarray(argv, 0);
for (i = 1; i < argc; i++) {
switch (janet_type(argv[i])) {
default:
janet_array_push(array, args.v[i]);
janet_array_push(array, argv[i]);
break;
case JANET_ARRAY:
case JANET_TUPLE:
{
int32_t j, len;
const Janet *vals;
janet_indexed_view(args.v[i], &vals, &len);
janet_indexed_view(argv[i], &vals, &len);
for (j = 0; j < len; j++)
janet_array_push(array, vals[j]);
}
break;
}
}
JANET_RETURN_ARRAY(args, array);
return janet_wrap_array(array);
}
static int cfun_insert(JanetArgs args) {
int32_t at;
static Janet cfun_insert(int32_t argc, Janet *argv) {
size_t chunksize, restsize;
JanetArray *array;
JANET_MINARITY(args, 2);
JANET_ARG_ARRAY(array, args, 0);
JANET_ARG_INTEGER(at, args, 1);
janet_arity(argc, 2, -1);
JanetArray *array = janet_getarray(argv, 0);
int32_t at = janet_getinteger(argv, 1);
if (at < 0) {
at = array->count + at + 1;
}
if (at < 0 || at > array->count)
JANET_THROW(args, "insertion index out of bounds");
chunksize = (args.n - 2) * sizeof(Janet);
janet_panicf("insertion index %d out of range [0,%d]", at, array->count);
chunksize = (argc - 2) * sizeof(Janet);
restsize = (array->count - at) * sizeof(Janet);
janet_array_ensure(array, array->count + args.n - 2, 2);
memmove(array->data + at + args.n - 2,
janet_array_ensure(array, array->count + argc - 2, 2);
memmove(array->data + at + argc - 2,
array->data + at,
restsize);
memcpy(array->data + at, args.v + 2, chunksize);
array->count += (args.n - 2);
JANET_RETURN_ARRAY(args, array);
memcpy(array->data + at, argv + 2, chunksize);
array->count += (argc - 2);
return janet_wrap_array(array);
}
static const JanetReg cfuns[] = {
@ -300,8 +262,6 @@ static const JanetReg cfuns[] = {
};
/* Load the array module */
int janet_lib_array(JanetArgs args) {
JanetTable *env = janet_env(args);
void janet_lib_array(JanetTable *env) {
janet_cfuns(env, NULL, cfuns);
return 0;
}

View File

@ -914,22 +914,20 @@ Janet janet_disasm(JanetFuncDef *def) {
}
/* C Function for assembly */
static int cfun_asm(JanetArgs args) {
static Janet cfun_asm(int32_t argc, Janet *argv) {
janet_arity(argc, 1, 1);
JanetAssembleResult res;
JANET_FIXARITY(args, 1);
res = janet_asm(args.v[0], 0);
if (res.status == JANET_ASSEMBLE_OK) {
JANET_RETURN_FUNCTION(args, janet_thunk(res.funcdef));
} else {
JANET_THROWV(args, janet_wrap_string(res.error));
res = janet_asm(argv[0], 0);
if (res.status != JANET_ASSEMBLE_OK) {
janet_panics(res.error);
}
return janet_wrap_function(janet_thunk(res.funcdef));
}
static int cfun_disasm(JanetArgs args) {
JanetFunction *f;
JANET_FIXARITY(args, 1);
JANET_ARG_FUNCTION(f, args, 0);
JANET_RETURN(args, janet_disasm(f->def));
static Janet cfun_disasm(int32_t argc, Janet *argv) {
janet_arity(argc, 1, 1);
JanetFunction *f = janet_getfunction(argv, 0);
return janet_disasm(f->def);
}
static const JanetReg cfuns[] = {
@ -949,10 +947,8 @@ static const JanetReg cfuns[] = {
};
/* Load the library */
int janet_lib_asm(JanetArgs args) {
JanetTable *env = janet_env(args);
void janet_lib_asm(JanetTable *env) {
janet_cfuns(env, NULL, cfuns);
return 0;
}
#endif

View File

@ -77,10 +77,10 @@ void janet_buffer_setcount(JanetBuffer *buffer, int32_t count) {
/* Adds capacity for enough extra bytes to the buffer. Ensures that the
* next n bytes pushed to the buffer will not cause a reallocation */
int janet_buffer_extra(JanetBuffer *buffer, int32_t n) {
void janet_buffer_extra(JanetBuffer *buffer, int32_t n) {
/* Check for buffer overflow */
if ((int64_t)n + buffer->count > INT32_MAX) {
return -1;
janet_panic("buffer overflow");
}
int32_t new_size = buffer->count + n;
if (new_size > buffer->capacity) {
@ -92,59 +92,54 @@ int janet_buffer_extra(JanetBuffer *buffer, int32_t n) {
buffer->data = new_data;
buffer->capacity = new_capacity;
}
return 0;
}
/* Push a cstring to buffer */
int janet_buffer_push_cstring(JanetBuffer *buffer, const char *cstring) {
void janet_buffer_push_cstring(JanetBuffer *buffer, const char *cstring) {
int32_t len = 0;
while (cstring[len]) ++len;
return janet_buffer_push_bytes(buffer, (const uint8_t *) cstring, len);
janet_buffer_push_bytes(buffer, (const uint8_t *) cstring, len);
}
/* Push multiple bytes into the buffer */
int janet_buffer_push_bytes(JanetBuffer *buffer, const uint8_t *string, int32_t length) {
if (janet_buffer_extra(buffer, length)) return -1;
void janet_buffer_push_bytes(JanetBuffer *buffer, const uint8_t *string, int32_t length) {
janet_buffer_extra(buffer, length);
memcpy(buffer->data + buffer->count, string, length);
buffer->count += length;
return 0;
}
int janet_buffer_push_string(JanetBuffer *buffer, const uint8_t *string) {
return janet_buffer_push_bytes(buffer, string, janet_string_length(string));
void janet_buffer_push_string(JanetBuffer *buffer, const uint8_t *string) {
janet_buffer_push_bytes(buffer, string, janet_string_length(string));
}
/* Push a single byte to the buffer */
int janet_buffer_push_u8(JanetBuffer *buffer, uint8_t byte) {
if (janet_buffer_extra(buffer, 1)) return -1;
void janet_buffer_push_u8(JanetBuffer *buffer, uint8_t byte) {
janet_buffer_extra(buffer, 1);
buffer->data[buffer->count] = byte;
buffer->count++;
return 0;
}
/* Push a 16 bit unsigned integer to the buffer */
int janet_buffer_push_u16(JanetBuffer *buffer, uint16_t x) {
if (janet_buffer_extra(buffer, 2)) return -1;
void janet_buffer_push_u16(JanetBuffer *buffer, uint16_t x) {
janet_buffer_extra(buffer, 2);
buffer->data[buffer->count] = x & 0xFF;
buffer->data[buffer->count + 1] = (x >> 8) & 0xFF;
buffer->count += 2;
return 0;
}
/* Push a 32 bit unsigned integer to the buffer */
int janet_buffer_push_u32(JanetBuffer *buffer, uint32_t x) {
if (janet_buffer_extra(buffer, 4)) return -1;
void janet_buffer_push_u32(JanetBuffer *buffer, uint32_t x) {
janet_buffer_extra(buffer, 4);
buffer->data[buffer->count] = x & 0xFF;
buffer->data[buffer->count + 1] = (x >> 8) & 0xFF;
buffer->data[buffer->count + 2] = (x >> 16) & 0xFF;
buffer->data[buffer->count + 3] = (x >> 24) & 0xFF;
buffer->count += 4;
return 0;
}
/* Push a 64 bit unsigned integer to the buffer */
int janet_buffer_push_u64(JanetBuffer *buffer, uint64_t x) {
if (janet_buffer_extra(buffer, 8)) return -1;
void janet_buffer_push_u64(JanetBuffer *buffer, uint64_t x) {
janet_buffer_extra(buffer, 8);
buffer->data[buffer->count] = x & 0xFF;
buffer->data[buffer->count + 1] = (x >> 8) & 0xFF;
buffer->data[buffer->count + 2] = (x >> 16) & 0xFF;
@ -154,118 +149,79 @@ int janet_buffer_push_u64(JanetBuffer *buffer, uint64_t x) {
buffer->data[buffer->count + 6] = (x >> 48) & 0xFF;
buffer->data[buffer->count + 7] = (x >> 56) & 0xFF;
buffer->count += 8;
return 0;
}
/* C functions */
static int cfun_new(JanetArgs args) {
int32_t cap;
JanetBuffer *buffer;
JANET_FIXARITY(args, 1);
JANET_ARG_INTEGER(cap, args, 0);
buffer = janet_buffer(cap);
JANET_RETURN_BUFFER(args, buffer);
static Janet cfun_new(int32_t argc, Janet *argv) {
janet_arity(argc, 1, 1);
int32_t cap = janet_getinteger(argv, 0);
JanetBuffer *buffer = janet_buffer(cap);
return janet_wrap_buffer(buffer);
}
static int cfun_u8(JanetArgs args) {
static Janet cfun_u8(int32_t argc, Janet *argv) {
int32_t i;
JanetBuffer *buffer;
JANET_MINARITY(args, 1);
JANET_ARG_BUFFER(buffer, args, 0);
for (i = 1; i < args.n; i++) {
int32_t integer;
JANET_ARG_INTEGER(integer, args, i);
if (janet_buffer_push_u8(buffer, (uint8_t) (integer & 0xFF)))
JANET_THROW(args, "buffer overflow");
janet_arity(argc, 1, -1);
JanetBuffer *buffer = janet_getbuffer(argv, 0);
for (i = 1; i < argc; i++) {
janet_buffer_push_u8(buffer, (uint8_t) (janet_getinteger(argv, i) & 0xFF));
}
JANET_RETURN(args, args.v[0]);
return argv[0];
}
static int cfun_word(JanetArgs args) {
static Janet cfun_word(int32_t argc, Janet *argv) {
int32_t i;
JanetBuffer *buffer;
JANET_MINARITY(args, 1);
JANET_ARG_BUFFER(buffer, args, 0);
for (i = 1; i < args.n; i++) {
double number;
uint32_t word;
JANET_ARG_NUMBER(number, args, i);
word = (uint32_t) number;
if (number != word) JANET_THROW(args, "cannot convert number to machine word");
if (janet_buffer_push_u32(buffer, word))
JANET_THROW(args, "buffer overflow");
janet_arity(argc, 1, -1);
JanetBuffer *buffer = janet_getbuffer(argv, 0);
for (i = 1; i < argc; i++) {
double number = janet_getnumber(argv, 0);
uint32_t word = (uint32_t) number;
if (word != number)
janet_panicf("cannot convert %v to machine word", argv[0]);
janet_buffer_push_u32(buffer, word);
}
JANET_RETURN(args, args.v[0]);
return argv[0];
}
static int cfun_chars(JanetArgs args) {
static Janet cfun_chars(int32_t argc, Janet *argv) {
int32_t i;
JanetBuffer *buffer;
JANET_MINARITY(args, 1);
JANET_ARG_BUFFER(buffer, args, 0);
for (i = 1; i < args.n; i++) {
int32_t len;
const uint8_t *str;
JANET_ARG_BYTES(str, len, args, i);
if (janet_buffer_push_bytes(buffer, str, len))
JANET_THROW(args, "buffer overflow");
janet_arity(argc, 1, -1);
JanetBuffer *buffer = janet_getbuffer(argv, 0);
for (i = 1; i < argc; i++) {
JanetByteView view = janet_getbytes(argv, i);
janet_buffer_push_bytes(buffer, view.bytes, view.len);
}
JANET_RETURN(args, args.v[0]);
return argv[0];
}
static int cfun_clear(JanetArgs args) {
JanetBuffer *buffer;
JANET_FIXARITY(args, 1);
JANET_ARG_BUFFER(buffer, args, 0);
static Janet cfun_clear(int32_t argc, Janet *argv) {
janet_arity(argc, 1, 1);
JanetBuffer *buffer = janet_getbuffer(argv, 0);
buffer->count = 0;
JANET_RETURN(args, args.v[0]);
return argv[0];
}
static int cfun_popn(JanetArgs args) {
JanetBuffer *buffer;
int32_t n;
JANET_FIXARITY(args, 2);
JANET_ARG_BUFFER(buffer, args, 0);
JANET_ARG_INTEGER(n, args, 1);
if (n < 0) JANET_THROW(args, "n must be non-negative");
static Janet cfun_popn(int32_t argc, Janet *argv) {
janet_arity(argc, 2, 2);
JanetBuffer *buffer = janet_getbuffer(argv, 0);
int32_t n = janet_getinteger(argv, 1);
if (n < 0) janet_panic("n must be non-negative");
if (buffer->count < n) {
buffer->count = 0;
} else {
buffer->count -= n;
}
JANET_RETURN(args, args.v[0]);
return argv[0];
}
static int cfun_slice(JanetArgs args) {
const uint8_t *data;
int32_t len, start, end;
JanetBuffer *ret;
JANET_ARG_BYTES(data, len, args, 0);
/* Get start */
if (args.n < 2) {
start = 0;
} else {
JANET_ARG_INTEGER(start, args, 1);
}
/* Get end */
if (args.n < 3) {
end = -1;
} else {
JANET_ARG_INTEGER(end, args, 2);
}
if (start < 0) start = len + start;
if (end < 0) end = len + end + 1;
if (end < 0 || start < 0 || end > len || start > len)
JANET_THROW(args, "slice range out of bounds");
if (end >= start) {
ret = janet_buffer(end - start);
memcpy(ret->data, data + start, end - start);
ret->count = end - start;
} else {
ret = janet_buffer(0);
}
JANET_RETURN_BUFFER(args, ret);
static Janet cfun_slice(int32_t argc, Janet *argv) {
JanetRange range = janet_getslice(argc, argv);
JanetByteView view = janet_getbytes(argv, 0);
JanetBuffer *buffer = janet_buffer(range.end - range.start);
memcpy(buffer->data, view.bytes + range.start, range.end - range.start);
buffer->count = range.end - range.start;
return janet_wrap_buffer(buffer);
}
static const JanetReg cfuns[] = {
@ -310,8 +266,6 @@ static const JanetReg cfuns[] = {
{NULL, NULL, NULL}
};
int janet_lib_buffer(JanetArgs args) {
JanetTable *env = janet_env(args);
void janet_lib_buffer(JanetTable *env) {
janet_cfuns(env, NULL, cfuns);
return 0;
}

View File

@ -43,5 +43,141 @@ void janet_panics(const uint8_t *message) {
}
void janet_panic_type(Janet x, int32_t n, int expected) {
janet_panicf("bad slot #%d, expected %T, got %t", n, expected, janet_type(x));
janet_panicf("bad slot #%d, expected %T, got %v", n, expected, x);
}
void janet_panic_abstract(Janet x, int32_t n, const JanetAbstractType *at) {
janet_panicf("bad slot #%d, expected %s, got %v", n, at->name, x);
}
void janet_arity(int32_t arity, int32_t min, int32_t max) {
if (min >= 0 && arity < min)
janet_panicf("arity mismatch, expected at least %d, got %d", min, arity);
if (max >= 0 && arity > max)
janet_panicf("arity mismatch, expected at most %d, got %d", max, arity);
}
#define DEFINE_GETTER(name, NAME, type) \
type janet_get##name(const Janet *argv, int32_t n) { \
Janet x = argv[n]; \
if (!janet_checktype(x, JANET_##NAME)) { \
janet_panic_type(x, n, JANET_TFLAG_##NAME); \
} \
return janet_unwrap_##name(x); \
}
DEFINE_GETTER(number, NUMBER, double)
DEFINE_GETTER(array, ARRAY, JanetArray *)
DEFINE_GETTER(tuple, TUPLE, const Janet *)
DEFINE_GETTER(table, TABLE, JanetTable *)
DEFINE_GETTER(struct, STRUCT, const JanetKV *)
DEFINE_GETTER(string, STRING, const uint8_t *)
DEFINE_GETTER(keyword, KEYWORD, const uint8_t *)
DEFINE_GETTER(symbol, SYMBOL, const uint8_t *)
DEFINE_GETTER(buffer, BUFFER, JanetBuffer *)
DEFINE_GETTER(fiber, FIBER, JanetFiber *)
DEFINE_GETTER(function, FUNCTION, JanetFunction *)
DEFINE_GETTER(cfunction, CFUNCTION, JanetCFunction)
int janet_getboolean(const Janet *argv, int32_t n) {
Janet x = argv[n];
if (janet_checktype(x, JANET_TRUE)) {
return 1;
} else if (!janet_checktype(x, JANET_FALSE)) {
janet_panicf("bad slot #%d, expected boolean, got %v", n, x);
}
return 0;
}
int32_t janet_getinteger(const Janet *argv, int32_t n) {
Janet x = argv[n];
if (!janet_checkint(x)) {
janet_panicf("bad slot #%d, expected integer, got %v", n, x);
}
return janet_unwrap_integer(x);
}
int64_t janet_getinteger64(const Janet *argv, int32_t n) {
Janet x = argv[n];
if (!janet_checkint64(x)) {
janet_panicf("bad slot #%d, expected 64 bit integer, got %v", n, x);
}
return (int64_t) janet_unwrap_number(x);
}
JanetView janet_getindexed(const Janet *argv, int32_t n) {
Janet x = argv[n];
JanetView view;
if (!janet_indexed_view(x, &view.items, &view.len)) {
janet_panic_type(x, n, JANET_TFLAG_INDEXED);
}
return view;
}
JanetByteView janet_getbytes(const Janet *argv, int32_t n) {
Janet x = argv[n];
JanetByteView view;
if (!janet_bytes_view(x, &view.bytes, &view.len)) {
janet_panic_type(x, n, JANET_TFLAG_BYTES);
}
return view;
}
JanetDictView janet_getdictionary(const Janet *argv, int32_t n) {
Janet x = argv[n];
JanetDictView view;
if (!janet_dictionary_view(x, &view.kvs, &view.len, &view.cap)) {
janet_panic_type(x, n, JANET_TFLAG_DICTIONARY);
}
return view;
}
void *janet_getabstract(const Janet *argv, int32_t n, const JanetAbstractType *at) {
Janet x = argv[n];
if (!janet_checktype(x, JANET_ABSTRACT)) {
janet_panic_abstract(x, n, at);
}
void *abstractx = janet_unwrap_abstract(x);
if (janet_abstract_type(abstractx) != at) {
janet_panic_abstract(x, n, at);
}
return abstractx;
}
JanetRange janet_getslice(int32_t argc, const Janet *argv) {
janet_arity(argc, 1, 3);
JanetRange range;
int32_t length = janet_length(argv[0]);
if (argc == 1) {
range.start = 0;
range.end = length;
} else if (argc == 2) {
range.start = janet_getinteger(argv, 1);
range.end = length;
if (range.start < 0) {
range.start += length + 1;
}
if (range.start < 0 || range.start > length) {
janet_panicf("slice start: index %d out of range [0,%d]", range.start, length);
}
} else if (argc == 3) {
range.start = janet_getinteger(argv, 1);
range.end = janet_getinteger(argv, 2);
if (range.start < 0) {
range.start += length + 1;
}
if (range.end < 0) {
range.end += length + 1;
}
if (range.start < 0 || range.start > length) {
janet_panicf("slice start: index %d out of range [0,%d]", range.start, length);
}
if (range.end < 0 || range.end > length) {
janet_panicf("slice end: index %d out of range [0,%d]", range.end, length);
}
if (range.end < range.start) {
range.end = range.start;
}
}
return range;
}

View File

@ -699,29 +699,25 @@ JanetCompileResult janet_compile(Janet source, JanetTable *env, const uint8_t *w
}
/* C Function for compiling */
static int cfun(JanetArgs args) {
JanetCompileResult res;
JanetTable *t;
JanetTable *env;
JANET_MINARITY(args, 2);
JANET_MAXARITY(args, 3);
JANET_ARG_TABLE(env, args, 1);
static Janet cfun(int32_t argc, Janet *argv) {
janet_arity(argc, 2, 3);
JanetTable *env = janet_gettable(argv, 1);
const uint8_t *source = NULL;
if (args.n == 3) {
JANET_ARG_STRING(source, args, 2);
if (argc == 3) {
source = janet_getstring(argv, 2);
}
res = janet_compile(args.v[0], env, source);
JanetCompileResult res = janet_compile(argv[0], env, source);
if (res.status == JANET_COMPILE_OK) {
JANET_RETURN_FUNCTION(args, janet_thunk(res.funcdef));
return janet_wrap_function(janet_thunk(res.funcdef));
} else {
t = janet_table(4);
JanetTable *t = janet_table(4);
janet_table_put(t, janet_ckeywordv("error"), janet_wrap_string(res.error));
janet_table_put(t, janet_ckeywordv("start"), janet_wrap_integer(res.error_mapping.start));
janet_table_put(t, janet_ckeywordv("end"), janet_wrap_integer(res.error_mapping.end));
if (res.macrofiber) {
janet_table_put(t, janet_ckeywordv("fiber"), janet_wrap_fiber(res.macrofiber));
}
JANET_RETURN_TABLE(args, t);
return janet_wrap_table(t);
}
}
@ -736,8 +732,6 @@ static const JanetReg cfuns[] = {
{NULL, NULL, NULL}
};
int janet_lib_compile(JanetArgs args) {
JanetTable *env = janet_env(args);
void janet_lib_compile(JanetTable *env) {
janet_cfuns(env, NULL, cfuns);
return 0;
}

View File

@ -1451,7 +1451,7 @@ value, one key will be ignored."
env)
(defn status-pp
"Pretty print a signal and asscoaited state. Can be used as the
"Pretty print a signal and associated state. Can be used as the
onsignal argument to run-context."
[sig x f source]
(def title

View File

@ -50,14 +50,14 @@ typedef void *Clib;
#define error_clib() dlerror()
#endif
JanetCFunction janet_native(const char *name, const uint8_t **error) {
JanetModule janet_native(const char *name, const uint8_t **error) {
Clib lib = load_clib(name);
JanetCFunction init;
JanetModule init;
if (!lib) {
*error = janet_cstring(error_clib());
return NULL;
}
init = (JanetCFunction) symbol_clib(lib, "_janet_init");
init = (JanetModule) symbol_clib(lib, "_janet_init");
if (!init) {
*error = janet_cstring("could not find _janet_init symbol");
return NULL;
@ -65,217 +65,205 @@ JanetCFunction janet_native(const char *name, const uint8_t **error) {
return init;
}
static int janet_core_native(JanetArgs args) {
JanetCFunction init;
static Janet janet_core_native(int32_t argc, Janet *argv) {
JanetModule init;
JanetTable *env = janet_table(0);
janet_arity(argc, 1, 1);
const uint8_t *path = janet_getstring(argv, 0);
const uint8_t *error = NULL;
const uint8_t *path = NULL;
JANET_FIXARITY(args, 1);
JANET_ARG_STRING(path, args, 0);
init = janet_native((const char *)path, &error);
if (!init) {
JANET_THROWV(args, janet_wrap_string(error));
janet_panicf("could not load native %S: %S", path, error);
}
JANET_RETURN_CFUNCTION(args, init);
init(env);
return janet_wrap_table(env);
}
static int janet_core_print(JanetArgs args) {
int32_t i;
for (i = 0; i < args.n; ++i) {
static Janet janet_core_print(int32_t argc, Janet *argv) {
for (int32_t i = 0; i < argc; ++i) {
int32_t j, len;
const uint8_t *vstr = janet_to_string(args.v[i]);
const uint8_t *vstr = janet_to_string(argv[i]);
len = janet_string_length(vstr);
for (j = 0; j < len; ++j) {
putc(vstr[j], stdout);
}
}
putc('\n', stdout);
JANET_RETURN_NIL(args);
return janet_wrap_nil();
}
static int janet_core_describe(JanetArgs args) {
int32_t i;
static Janet janet_core_describe(int32_t argc, Janet *argv) {
JanetBuffer b;
janet_buffer_init(&b, 0);
for (i = 0; i < args.n; ++i) {
for (int32_t i = 0; i < argc; ++i) {
int32_t len;
const uint8_t *str = janet_description(args.v[i]);
const uint8_t *str = janet_description(argv[i]);
len = janet_string_length(str);
janet_buffer_push_bytes(&b, str, len);
}
*args.ret = janet_stringv(b.data, b.count);
Janet ret = janet_stringv(b.data, b.count);
janet_buffer_deinit(&b);
return 0;
return ret;
}
static int janet_core_string(JanetArgs args) {
int32_t i;
static Janet janet_core_string(int32_t argc, Janet *argv) {
JanetBuffer b;
janet_buffer_init(&b, 0);
for (i = 0; i < args.n; ++i) {
for (int32_t i = 0; i < argc; ++i) {
int32_t len;
const uint8_t *str = janet_to_string(args.v[i]);
const uint8_t *str = janet_to_string(argv[i]);
len = janet_string_length(str);
janet_buffer_push_bytes(&b, str, len);
}
*args.ret = janet_stringv(b.data, b.count);
Janet ret = janet_stringv(b.data, b.count);
janet_buffer_deinit(&b);
return 0;
return ret;
}
static int janet_core_symbol(JanetArgs args) {
static Janet janet_core_symbol(int32_t argc, Janet *argv) {
int32_t i;
JanetBuffer b;
janet_buffer_init(&b, 0);
for (i = 0; i < args.n; ++i) {
for (i = 0; i < argc; ++i) {
int32_t len;
const uint8_t *str = janet_to_string(args.v[i]);
const uint8_t *str = janet_to_string(argv[i]);
len = janet_string_length(str);
janet_buffer_push_bytes(&b, str, len);
}
*args.ret = janet_symbolv(b.data, b.count);
Janet ret = janet_symbolv(b.data, b.count);
janet_buffer_deinit(&b);
return 0;
return ret;
}
static int janet_core_keyword(JanetArgs args) {
static Janet janet_core_keyword(int32_t argc, Janet *argv) {
int32_t i;
JanetBuffer b;
janet_buffer_init(&b, 0);
for (i = 0; i < args.n; ++i) {
for (i = 0; i < argc; ++i) {
int32_t len;
const uint8_t *str = janet_to_string(args.v[i]);
const uint8_t *str = janet_to_string(argv[i]);
len = janet_string_length(str);
janet_buffer_push_bytes(&b, str, len);
}
*args.ret = janet_keywordv(b.data, b.count);
Janet ret = janet_keywordv(b.data, b.count);
janet_buffer_deinit(&b);
return 0;
return ret;
}
static int janet_core_buffer(JanetArgs args) {
static Janet janet_core_buffer(int32_t argc, Janet *argv) {
int32_t i;
JanetBuffer *b = janet_buffer(0);
for (i = 0; i < args.n; ++i) {
for (i = 0; i < argc; ++i) {
int32_t len;
const uint8_t *str = janet_to_string(args.v[i]);
const uint8_t *str = janet_to_string(argv[i]);
len = janet_string_length(str);
janet_buffer_push_bytes(b, str, len);
}
JANET_RETURN_BUFFER(args, b);
return janet_wrap_buffer(b);
}
static int janet_core_is_abstract(JanetArgs args) {
JANET_FIXARITY(args, 1);
JANET_RETURN_BOOLEAN(args, janet_checktype(args.v[0], JANET_ABSTRACT));
static Janet janet_core_is_abstract(int32_t argc, Janet *argv) {
janet_arity(argc, 1, 1);
return janet_wrap_boolean(janet_checktype(argv[0], JANET_ABSTRACT));
}
static int janet_core_scannumber(JanetArgs args) {
const uint8_t *data;
double val;
int32_t len;
JANET_FIXARITY(args, 1);
JANET_ARG_BYTES(data, len, args, 0);
if (janet_scan_number(data, len, &val))
JANET_THROW(args, "failed to scan number");
JANET_RETURN_NUMBER(args, val);
static Janet janet_core_scannumber(int32_t argc, Janet *argv) {
double number;
janet_arity(argc, 1, 1);
JanetByteView view = janet_getbytes(argv, 1);
if (janet_scan_number(view.bytes, view.len, &number))
return janet_wrap_nil();
return janet_wrap_number(number);
}
static int janet_core_tuple(JanetArgs args) {
JANET_RETURN_TUPLE(args, janet_tuple_n(args.v, args.n));
static Janet janet_core_tuple(int32_t argc, Janet *argv) {
return janet_wrap_tuple(janet_tuple_n(argv, argc));
}
static int janet_core_array(JanetArgs args) {
JanetArray *array = janet_array(args.n);
array->count = args.n;
memcpy(array->data, args.v, args.n * sizeof(Janet));
JANET_RETURN_ARRAY(args, array);
static Janet janet_core_array(int32_t argc, Janet *argv) {
JanetArray *array = janet_array(argc);
array->count = argc;
memcpy(array->data, argv, argc * sizeof(Janet));
return janet_wrap_array(array);
}
static int janet_core_table(JanetArgs args) {
static Janet janet_core_table(int32_t argc, Janet *argv) {
int32_t i;
JanetTable *table = janet_table(args.n >> 1);
if (args.n & 1)
JANET_THROW(args, "expected even number of arguments");
for (i = 0; i < args.n; i += 2) {
janet_table_put(table, args.v[i], args.v[i + 1]);
if (argc & 1)
janet_panic("expected even number of arguments");
JanetTable *table = janet_table(argc >> 1);
for (i = 0; i < argc; i += 2) {
janet_table_put(table, argv[i], argv[i + 1]);
}
JANET_RETURN_TABLE(args, table);
return janet_wrap_table(table);
}
static int janet_core_struct(JanetArgs args) {
static Janet janet_core_struct(int32_t argc, Janet *argv) {
int32_t i;
JanetKV *st = janet_struct_begin(args.n >> 1);
if (args.n & 1)
JANET_THROW(args, "expected even number of arguments");
for (i = 0; i < args.n; i += 2) {
janet_struct_put(st, args.v[i], args.v[i + 1]);
if (argc & 1)
janet_panic("expected even number of arguments");
JanetKV *st = janet_struct_begin(argc >> 1);
for (i = 0; i < argc; i += 2) {
janet_struct_put(st, argv[i], argv[i + 1]);
}
JANET_RETURN_STRUCT(args, janet_struct_end(st));
return janet_wrap_struct(janet_struct_end(st));
}
static int janet_core_gensym(JanetArgs args) {
JANET_FIXARITY(args, 0);
JANET_RETURN_SYMBOL(args, janet_symbol_gen());
static Janet janet_core_gensym(int32_t argc, Janet *argv) {
(void) argv;
janet_arity(argc, 0, 0);
return janet_wrap_symbol(janet_symbol_gen());
}
static int janet_core_gccollect(JanetArgs args) {
(void) args;
static Janet janet_core_gccollect(int32_t argc, Janet *argv) {
(void) argv;
(void) argc;
janet_collect();
return 0;
return janet_wrap_nil();
}
static int janet_core_gcsetinterval(JanetArgs args) {
int32_t val;
JANET_FIXARITY(args, 1);
JANET_ARG_INTEGER(val, args, 0);
static Janet janet_core_gcsetinterval(int32_t argc, Janet *argv) {
janet_arity(argc, 1, 1);
int32_t val = janet_getinteger(argv, 0);
if (val < 0)
JANET_THROW(args, "expected non-negative integer");
janet_panic("expected non-negative integer");
janet_vm_gc_interval = val;
JANET_RETURN_NIL(args);
return janet_wrap_nil();
}
static int janet_core_gcinterval(JanetArgs args) {
JANET_FIXARITY(args, 0);
JANET_RETURN_INTEGER(args, janet_vm_gc_interval);
static Janet janet_core_gcinterval(int32_t argc, Janet *argv) {
(void) argv;
janet_arity(argc, 0, 0);
return janet_wrap_number(janet_vm_gc_interval);
}
static int janet_core_type(JanetArgs args) {
JANET_FIXARITY(args, 1);
JanetType t = janet_type(args.v[0]);
static Janet janet_core_type(int32_t argc, Janet *argv) {
janet_arity(argc, 1, 1);
JanetType t = janet_type(argv[0]);
if (t == JANET_ABSTRACT) {
JANET_RETURN(args, janet_ckeywordv(janet_abstract_type(janet_unwrap_abstract(args.v[0]))->name));
return janet_ckeywordv(janet_abstract_type(janet_unwrap_abstract(argv[0]))->name);
} else {
JANET_RETURN(args, janet_ckeywordv(janet_type_names[t]));
return janet_ckeywordv(janet_type_names[t]);
}
}
static int janet_core_next(JanetArgs args) {
Janet ds;
const JanetKV *kv;
JANET_FIXARITY(args, 2);
JANET_CHECKMANY(args, 0, JANET_TFLAG_DICTIONARY);
ds = args.v[0];
if (janet_checktype(ds, JANET_TABLE)) {
JanetTable *t = janet_unwrap_table(ds);
kv = janet_checktype(args.v[1], JANET_NIL)
? NULL
: janet_table_find(t, args.v[1]);
kv = janet_table_next(t, kv);
} else {
const JanetKV *st = janet_unwrap_struct(ds);
kv = janet_checktype(args.v[1], JANET_NIL)
? NULL
: janet_struct_find(st, args.v[1]);
kv = janet_struct_next(st, kv);
static Janet janet_core_next(int32_t argc, Janet *argv) {
janet_arity(argc, 2, 2);
JanetDictView view = janet_getdictionary(argv, 0);
const JanetKV *end = view.kvs + view.cap;
const JanetKV *kv = janet_checktype(argv[1], JANET_NIL)
? view.kvs
: janet_dict_find(view.kvs, view.cap, argv[1]) + 1;
while (kv < end) {
if (!janet_checktype(kv->key, JANET_NIL)) return kv->key;
kv++;
}
if (kv)
JANET_RETURN(args, kv->key);
JANET_RETURN_NIL(args);
return janet_wrap_nil();
}
static int janet_core_hash(JanetArgs args) {
JANET_FIXARITY(args, 1);
JANET_RETURN_INTEGER(args, janet_hash(args.v[0]));
static Janet janet_core_hash(int32_t argc, Janet *argv) {
janet_arity(argc, 1, 1);
return janet_wrap_number(janet_hash(argv[0]));
}
static const JanetReg cfuns[] = {
@ -770,28 +758,22 @@ JanetTable *janet_core_env(void) {
janet_gcroot(janet_wrap_table(env));
/* Load auxiliary envs */
{
JanetArgs args;
args.n = 1;
args.v = &ret;
args.ret = &ret;
janet_lib_io(args);
janet_lib_math(args);
janet_lib_array(args);
janet_lib_tuple(args);
janet_lib_buffer(args);
janet_lib_table(args);
janet_lib_fiber(args);
janet_lib_os(args);
janet_lib_parse(args);
janet_lib_compile(args);
janet_lib_debug(args);
janet_lib_string(args);
janet_lib_marsh(args);
janet_lib_io(env);
janet_lib_math(env);
janet_lib_array(env);
janet_lib_tuple(env);
janet_lib_buffer(env);
janet_lib_table(env);
janet_lib_fiber(env);
janet_lib_os(env);
janet_lib_parse(env);
janet_lib_compile(env);
janet_lib_debug(env);
janet_lib_string(env);
janet_lib_marsh(env);
#ifdef JANET_ASSEMBLER
janet_lib_asm(args);
janet_lib_asm(env);
#endif
}
/* Allow references to the environment */
janet_def(env, "_env", ret, "The environment table for the current scope.");

View File

@ -29,26 +29,24 @@
* out of the box. */
/* Add a break point to a function */
int janet_debug_break(JanetFuncDef *def, int32_t pc) {
void janet_debug_break(JanetFuncDef *def, int32_t pc) {
if (pc >= def->bytecode_length || pc < 0)
return 1;
janet_panic("invalid bytecode offset");
def->bytecode[pc] |= 0x80;
return 0;
}
/* Remove a break point from a function */
int janet_debug_unbreak(JanetFuncDef *def, int32_t pc) {
void janet_debug_unbreak(JanetFuncDef *def, int32_t pc) {
if (pc >= def->bytecode_length || pc < 0)
return 1;
janet_panic("invalid bytecode offset");
def->bytecode[pc] &= ~((uint32_t)0x80);
return 0;
}
/*
* Find a location for a breakpoint given a source file an
* location.
*/
int janet_debug_find(
void janet_debug_find(
JanetFuncDef **def_out, int32_t *pc_out,
const uint8_t *source, int32_t offset) {
/* Scan the heap for right func def */
@ -84,9 +82,8 @@ int janet_debug_find(
if (best_def) {
*def_out = best_def;
*pc_out = besti;
return 0;
} else {
return 1;
janet_panic("could not find breakpoint");
}
}
@ -96,86 +93,64 @@ int janet_debug_find(
/* Helper to find funcdef and bytecode offset to insert or remove breakpoints.
* Takes a source file name and byte offset. */
static int helper_find(JanetArgs args, JanetFuncDef **def, int32_t *bytecode_offset) {
const uint8_t *source;
int32_t source_offset;
JANET_FIXARITY(args, 2);
JANET_ARG_STRING(source, args, 0);
JANET_ARG_INTEGER(source_offset, args, 1);
if (janet_debug_find(
def, bytecode_offset, source, source_offset)) {
JANET_THROW(args, "could not find breakpoint");
}
JANET_RETURN_NIL(args);
static void helper_find(int32_t argc, Janet *argv, JanetFuncDef **def, int32_t *bytecode_offset) {
janet_arity(argc, 2, 2);
const uint8_t *source = janet_getstring(argv, 0);
int32_t source_offset = janet_getinteger(argv, 1);
janet_debug_find(def, bytecode_offset, source, source_offset);
}
/* Helper to find funcdef and bytecode offset to insert or remove breakpoints.
* Takes a function and byte offset*/
static int helper_find_fun(JanetArgs args, JanetFuncDef **def, int32_t *bytecode_offset) {
JanetFunction *func;
int32_t offset = 0;
JANET_MINARITY(args, 1);
JANET_MAXARITY(args, 2);
JANET_ARG_FUNCTION(func, args, 0);
if (args.n == 2) {
JANET_ARG_INTEGER(offset, args, 1);
}
static void helper_find_fun(int32_t argc, Janet *argv, JanetFuncDef **def, int32_t *bytecode_offset) {
janet_arity(argc, 1, 2);
JanetFunction *func = janet_getfunction(argv, 0);
int32_t offset = (argc == 2) ? janet_getinteger(argv, 1) : 0;
*def = func->def;
*bytecode_offset = offset;
JANET_RETURN_NIL(args);
}
static int cfun_break(JanetArgs args) {
static Janet cfun_break(int32_t argc, Janet *argv) {
JanetFuncDef *def;
int32_t offset;
int status = helper_find(args, &def, &offset);
if (status == 0) janet_debug_break(def, offset);
return status;
helper_find(argc, argv, &def, &offset);
janet_debug_break(def, offset);
return janet_wrap_nil();
}
static int cfun_unbreak(JanetArgs args) {
static Janet cfun_unbreak(int32_t argc, Janet *argv) {
JanetFuncDef *def;
int32_t offset;
int status = helper_find(args, &def, &offset);
if (status == 0) janet_debug_unbreak(def, offset);
return status;
helper_find(argc, argv, &def, &offset);
janet_debug_unbreak(def, offset);
return janet_wrap_nil();
}
static int cfun_fbreak(JanetArgs args) {
static Janet cfun_fbreak(int32_t argc, Janet *argv) {
JanetFuncDef *def;
int32_t offset;
int status = helper_find_fun(args, &def, &offset);
if (status == 0) {
if (janet_debug_break(def, offset)) {
JANET_THROW(args, "could not find breakpoint");
}
}
return status;
helper_find_fun(argc, argv, &def, &offset);
janet_debug_break(def, offset);
return janet_wrap_nil();
}
static int cfun_unfbreak(JanetArgs args) {
static Janet cfun_unfbreak(int32_t argc, Janet *argv) {
JanetFuncDef *def;
int32_t offset;
int status = helper_find_fun(args, &def, &offset);
if (status == 0) {
if (janet_debug_unbreak(def, offset)) {
JANET_THROW(args, "could not find breakpoint");
}
}
return status;
helper_find_fun(argc, argv, &def, &offset);
janet_debug_unbreak(def, offset);
return janet_wrap_nil();
}
static int cfun_lineage(JanetArgs args) {
JanetFiber *fiber;
JanetArray *array;
JANET_FIXARITY(args, 1);
JANET_ARG_FIBER(fiber, args, 0);
array = janet_array(0);
static Janet cfun_lineage(int32_t argc, Janet *argv) {
janet_arity(argc, 1, 1);
JanetFiber *fiber = janet_getfiber(argv, 0);
JanetArray *array = janet_array(0);
while (fiber) {
janet_array_push(array, janet_wrap_fiber(fiber));
fiber = fiber->child;
}
JANET_RETURN_ARRAY(args, array);
return janet_wrap_array(array);
}
/* Extract info from one stack frame */
@ -224,12 +199,10 @@ static Janet doframe(JanetStackFrame *frame) {
return janet_wrap_table(t);
}
static int cfun_stack(JanetArgs args) {
JanetFiber *fiber;
JanetArray *array;
JANET_FIXARITY(args, 1);
JANET_ARG_FIBER(fiber, args, 0);
array = janet_array(0);
static Janet cfun_stack(int32_t argc, Janet *argv) {
janet_arity(argc, 1, 1);
JanetFiber *fiber = janet_getfiber(argv, 0);
JanetArray *array = janet_array(0);
{
int32_t i = fiber->frame;
JanetStackFrame *frame;
@ -239,18 +212,16 @@ static int cfun_stack(JanetArgs args) {
i = frame->prevframe;
}
}
JANET_RETURN_ARRAY(args, array);
return janet_wrap_array(array);
}
static int cfun_argstack(JanetArgs args) {
JanetFiber *fiber;
JanetArray *array;
JANET_FIXARITY(args, 1);
JANET_ARG_FIBER(fiber, args, 0);
array = janet_array(fiber->stacktop - fiber->stackstart);
static Janet cfun_argstack(int32_t argc, Janet *argv) {
janet_arity(argc, 1, 1);
JanetFiber *fiber = janet_getfiber(argv, 0);
JanetArray *array = janet_array(fiber->stacktop - fiber->stackstart);
memcpy(array->data, fiber->data + fiber->stackstart, array->capacity * sizeof(Janet));
array->count = array->capacity;
JANET_RETURN_ARRAY(args, array);
return janet_wrap_array(array);
}
static const JanetReg cfuns[] = {
@ -306,8 +277,6 @@ static const JanetReg cfuns[] = {
};
/* Module entry point */
int janet_lib_debug(JanetArgs args) {
JanetTable *env = janet_env(args);
void janet_lib_debug(JanetTable *env) {
janet_cfuns(env, NULL, cfuns);
return 0;
}

View File

@ -292,31 +292,29 @@ void janet_fiber_popframe(JanetFiber *fiber) {
/* CFuns */
static int cfun_new(JanetArgs args) {
static Janet cfun_new(int32_t argc, Janet *argv) {
janet_arity(argc, 1, 2);
JanetFunction *func = janet_getfunction(argv, 0);
JanetFiber *fiber;
JanetFunction *func;
JANET_MINARITY(args, 1);
JANET_MAXARITY(args, 2);
JANET_ARG_FUNCTION(func, args, 0);
if (func->def->flags & JANET_FUNCDEF_FLAG_FIXARITY) {
if (func->def->arity != 0) {
JANET_THROW(args, "expected nullary function in fiber constructor");
janet_panic("expected nullary function in fiber constructor");
}
}
fiber = janet_fiber(func, 64);
if (args.n == 2) {
const uint8_t *flags;
int32_t len, i;
JANET_ARG_BYTES(flags, len, args, 1);
if (argc == 2) {
int32_t i;
JanetByteView view = janet_getbytes(argv, 1);
fiber->flags = 0;
janet_fiber_set_status(fiber, JANET_STATUS_NEW);
for (i = 0; i < len; i++) {
if (flags[i] >= '0' && flags[i] <= '9') {
fiber->flags |= JANET_FIBER_MASK_USERN(flags[i] - '0');
for (i = 0; i < view.len; i++) {
if (view.bytes[i] >= '0' && view.bytes[i] <= '9') {
fiber->flags |= JANET_FIBER_MASK_USERN(view.bytes[i] - '0');
} else {
switch (flags[i]) {
switch (view.bytes[i]) {
default:
JANET_THROW(args, "invalid flag, expected a, d, e, u, or y");
janet_panicf("invalid flag %c, expected a, d, e, u, or y", view.bytes[i]);
break;
case 'a':
fiber->flags |=
JANET_FIBER_MASK_DEBUG |
@ -340,41 +338,38 @@ static int cfun_new(JanetArgs args) {
}
}
}
JANET_RETURN_FIBER(args, fiber);
return janet_wrap_fiber(fiber);
}
static int cfun_status(JanetArgs args) {
JanetFiber *fiber;
JANET_FIXARITY(args, 1);
JANET_ARG_FIBER(fiber, args, 0);
static Janet cfun_status(int32_t argc, Janet *argv) {
janet_arity(argc, 1, 1);
JanetFiber *fiber = janet_getfiber(argv, 0);
uint32_t s = (fiber->flags & JANET_FIBER_STATUS_MASK) >>
JANET_FIBER_STATUS_OFFSET;
JANET_RETURN_CKEYWORD(args, janet_status_names[s]);
return janet_ckeywordv(janet_status_names[s]);
}
static int cfun_current(JanetArgs args) {
JANET_FIXARITY(args, 0);
JANET_RETURN_FIBER(args, janet_vm_fiber);
static Janet cfun_current(int32_t argc, Janet *argv) {
(void) argv;
janet_arity(argc, 0, 0);
return janet_wrap_fiber(janet_vm_fiber);
}
static int cfun_maxstack(JanetArgs args) {
JanetFiber *fiber;
JANET_FIXARITY(args, 1);
JANET_ARG_FIBER(fiber, args, 0);
JANET_RETURN_INTEGER(args, fiber->maxstack);
static Janet cfun_maxstack(int32_t argc, Janet *argv) {
janet_arity(argc, 1, 1);
JanetFiber *fiber = janet_getfiber(argv, 0);
return janet_wrap_integer(fiber->maxstack);
}
static int cfun_setmaxstack(JanetArgs args) {
JanetFiber *fiber;
int32_t maxs;
JANET_FIXARITY(args, 2);
JANET_ARG_FIBER(fiber, args, 0);
JANET_ARG_INTEGER(maxs, args, 1);
static Janet cfun_setmaxstack(int32_t argc, Janet *argv) {
janet_arity(argc, 2, 2);
JanetFiber *fiber = janet_getfiber(argv, 0);
int32_t maxs = janet_getinteger(argv, 1);
if (maxs < 0) {
JANET_THROW(args, "expected positive integer");
janet_panic("expected positive integer");
}
fiber->maxstack = maxs;
JANET_RETURN_FIBER(args, fiber);
return argv[0];
}
static const JanetReg cfuns[] = {
@ -425,8 +420,6 @@ static const JanetReg cfuns[] = {
};
/* Module entry point */
int janet_lib_fiber(JanetArgs args) {
JanetTable *env = janet_env(args);
void janet_lib_fiber(JanetTable *env) {
janet_cfuns(env, NULL, cfuns);
return 0;
}

View File

@ -53,13 +53,16 @@ JanetAbstractType janet_io_filetype = {
};
/* Check argupments to fopen */
static int checkflags(const uint8_t *str, int32_t len) {
static int checkflags(const uint8_t *str) {
int flags = 0;
int32_t i;
if (!len || len > 3) return -1;
int32_t len = janet_string_length(str);
if (!len || len > 3)
janet_panic("file mode must have a length between 1 and 3");
switch (*str) {
default:
return -1;
janet_panicf("invalid flag %c, expected w, a, or r", *str);
break;
case 'w':
flags |= IO_WRITE;
break;
@ -73,7 +76,8 @@ static int checkflags(const uint8_t *str, int32_t len) {
for (i = 1; i < len; i++) {
switch (str[i]) {
default:
return -1;
janet_panicf("invalid flag %c, expected + or b", str[i]);
break;
case '+':
if (flags & IO_UPDATE) return -1;
flags |= IO_UPDATE;
@ -87,41 +91,6 @@ static int checkflags(const uint8_t *str, int32_t len) {
return flags;
}
/* Check file argument */
static IOFile *checkfile(JanetArgs args, int32_t n) {
IOFile *iof;
if (n >= args.n) {
*args.ret = janet_cstringv("expected core.file");
return NULL;
}
if (!janet_checktype(args.v[n], JANET_ABSTRACT)) {
*args.ret = janet_cstringv("expected core.file");
return NULL;
}
iof = (IOFile *) janet_unwrap_abstract(args.v[n]);
if (janet_abstract_type(iof) != &janet_io_filetype) {
*args.ret = janet_cstringv("expected core.file");
return NULL;
}
return iof;
}
/* Check buffer argument */
static JanetBuffer *checkbuffer(JanetArgs args, int32_t n, int optional) {
if (optional && n == args.n) {
return janet_buffer(0);
}
if (n >= args.n) {
*args.ret = janet_cstringv("expected buffer");
return NULL;
}
if (!janet_checktype(args.v[n], JANET_BUFFER)) {
*args.ret = janet_cstringv("expected buffer");
return NULL;
}
return janet_unwrap_abstract(args.v[n]);
}
static Janet makef(FILE *f, int flags) {
IOFile *iof = (IOFile *) janet_abstract(&janet_io_filetype, sizeof(IOFile));
iof->file = f;
@ -130,97 +99,75 @@ static Janet makef(FILE *f, int flags) {
}
/* Open a process */
static int janet_io_popen(JanetArgs args) {
const uint8_t *fname, *fmode;
int32_t modelen;
FILE *f;
int flags;
JANET_MINARITY(args, 1);
JANET_MAXARITY(args, 2);
JANET_ARG_STRING(fname, args, 0);
if (args.n == 2) {
if (!janet_checktype(args.v[1], JANET_STRING) &&
!janet_checktype(args.v[1], JANET_SYMBOL))
JANET_THROW(args, "expected string mode");
fmode = janet_unwrap_string(args.v[1]);
modelen = janet_string_length(fmode);
} else {
fmode = (const uint8_t *)"r";
modelen = 1;
static Janet janet_io_popen(int32_t argc, Janet *argv) {
janet_arity(argc, 1, 2);
const uint8_t *fname = janet_getstring(argv, 0);
const uint8_t *fmode = NULL;
if (argc == 2) {
fmode = janet_getkeyword(argv, 1);
if (janet_string_length(fmode) != 1 ||
!(fmode[0] == 'r' || fmode[0] == 'w')) {
janet_panicf("invalid file mode :%S, expected :r or :w", fmode);
}
}
if (modelen != 1 || !(fmode[0] == 'r' || fmode[0] == 'w')) {
JANET_THROW(args, "invalid file mode");
}
flags = (fmode[0] == 'r') ? IO_PIPED | IO_READ : IO_PIPED | IO_WRITE;
int flags = (fmode && fmode[0] == '2')
? IO_PIPED | IO_WRITE
: IO_PIPED | IO_READ;
#ifdef JANET_WINDOWS
#define popen _popen
#endif
#ifdef __EMSCRIPTEN__
#define popen(A, B) (errno = 0, NULL)
#endif
f = popen((const char *)fname, (const char *)fmode);
FILE *f = popen((const char *)fname, (const char *)fmode);
if (!f) {
if (errno == EMFILE) {
JANET_THROW(args, "too many streams are open");
}
JANET_THROW(args, "could not open file");
return janet_wrap_nil();
}
JANET_RETURN(args, makef(f, flags));
return makef(f, flags);
}
/* Open a a file and return a userdata wrapper around the C file API. */
static int janet_io_fopen(JanetArgs args) {
const uint8_t *fname, *fmode;
int32_t modelen;
FILE *f;
static Janet janet_io_fopen(int32_t argc, Janet *argv) {
janet_arity(argc, 1, 2);
const uint8_t *fname = janet_getstring(argv, 0);
const uint8_t *fmode;
int flags;
JANET_MINARITY(args, 1);
JANET_MAXARITY(args, 2);
JANET_ARG_STRING(fname, args, 0);
if (args.n == 2) {
if (!janet_checktype(args.v[1], JANET_STRING) &&
!janet_checktype(args.v[1], JANET_SYMBOL))
JANET_THROW(args, "expected string mode");
fmode = janet_unwrap_string(args.v[1]);
modelen = janet_string_length(fmode);
if (argc == 2) {
fmode = janet_getkeyword(argv, 1);
flags = checkflags(fmode);
} else {
fmode = (const uint8_t *)"r";
modelen = 1;
flags = IO_READ;
}
if ((flags = checkflags(fmode, modelen)) < 0) {
JANET_THROW(args, "invalid file mode");
}
f = fopen((const char *)fname, (const char *)fmode);
JANET_RETURN(args, f ? makef(f, flags) : janet_wrap_nil());
FILE *f = fopen((const char *)fname, (const char *)fmode);
return f ? makef(f, flags) : janet_wrap_nil();
}
/* Read up to n bytes into buffer. Return error string if error. */
static const char *read_chunk(IOFile *iof, JanetBuffer *buffer, int32_t nBytesMax) {
static void read_chunk(IOFile *iof, JanetBuffer *buffer, int32_t nBytesMax) {
if (!(iof->flags & (IO_READ | IO_UPDATE)))
return "file is not readable";
/* Ensure buffer size */
if (janet_buffer_extra(buffer, nBytesMax))
return "buffer overflow";
janet_panic("file is not readable");
janet_buffer_extra(buffer, nBytesMax);
size_t ntoread = nBytesMax;
size_t nread = fread((char *)(buffer->data + buffer->count), 1, ntoread, iof->file);
if (nread != ntoread && ferror(iof->file))
return "could not read file";
janet_panic("could not read file");
buffer->count += (int32_t) nread;
return NULL;
}
/* Read a certain number of bytes into memory */
static int janet_io_fread(JanetArgs args) {
JanetBuffer *b;
IOFile *iof = checkfile(args, 0);
if (!iof) return 1;
if (iof->flags & IO_CLOSED)
JANET_THROW(args, "file is closed");
b = checkbuffer(args, 2, 1);
if (!b) return 1;
JANET_MINARITY(args, 2);
if (janet_checktype(args.v[1], JANET_KEYWORD)) {
const uint8_t *sym = janet_unwrap_symbol(args.v[1]);
static Janet janet_io_fread(int32_t argc, Janet *argv) {
janet_arity(argc, 2, 3);
IOFile *iof = janet_getabstract(argv, 0, &janet_io_filetype);
if (iof->flags & IO_CLOSED) janet_panic("file is closed");
JanetBuffer *buffer;
if (argc == 2) {
buffer = janet_buffer(0);
} else {
buffer = janet_getbuffer(argv, 2);
}
if (janet_checktype(argv[1], JANET_KEYWORD)) {
const uint8_t *sym = janet_unwrap_keyword(argv[1]);
if (!janet_cstrcmp(sym, "all")) {
/* Read whole file */
int status = fseek(iof->file, 0, SEEK_SET);
@ -228,71 +175,66 @@ static int janet_io_fread(JanetArgs args) {
/* backwards fseek did not work (stream like popen) */
int32_t sizeBefore;
do {
sizeBefore = b->count;
const char *maybeErr = read_chunk(iof, b, 1024);
if (maybeErr) JANET_THROW(args, maybeErr);
} while (sizeBefore < b->count);
sizeBefore = buffer->count;
read_chunk(iof, buffer, 1024);
} while (sizeBefore < buffer->count);
} else {
fseek(iof->file, 0, SEEK_END);
long fsize = ftell(iof->file);
fseek(iof->file, 0, SEEK_SET);
if (fsize > INT32_MAX) JANET_THROW(args, "buffer overflow");
const char *maybeErr = read_chunk(iof, b, (int32_t) fsize);;
if (maybeErr) JANET_THROW(args, maybeErr);
read_chunk(iof, buffer, (int32_t) fsize);
}
} else if (!janet_cstrcmp(sym, "line")) {
for (;;) {
int x = fgetc(iof->file);
if (x != EOF && janet_buffer_push_u8(b, (uint8_t)x))
JANET_THROW(args, "buffer overflow");
if (x != EOF) janet_buffer_push_u8(buffer, (uint8_t)x);
if (x == EOF || x == '\n') break;
}
} else {
JANET_THROW(args, "expected one of :all, :line");
janet_panicf("expected one of :all, :line, got %v", argv[1]);
}
} else if (!janet_checkint(args.v[1])) {
JANET_THROW(args, "expected positive integer");
} else {
int32_t len = janet_unwrap_integer(args.v[1]);
if (len < 0) JANET_THROW(args, "expected positive integer");
const char *maybeErr = read_chunk(iof, b, len);
if (maybeErr) JANET_THROW(args, maybeErr);
int32_t len = janet_getinteger(argv, 1);
if (len < 0) janet_panic("expected positive integer");
read_chunk(iof, buffer, len);
}
JANET_RETURN(args, janet_wrap_buffer(b));
return janet_wrap_buffer(buffer);
}
/* Write bytes to a file */
static int janet_io_fwrite(JanetArgs args) {
int32_t len, i;
const uint8_t *str;
IOFile *iof = checkfile(args, 0);
if (!iof) return 1;
static Janet janet_io_fwrite(int32_t argc, Janet *argv) {
janet_arity(argc, 1, -1);
IOFile *iof = janet_getabstract(argv, 0, &janet_io_filetype);
if (iof->flags & IO_CLOSED)
JANET_THROW(args, "file is closed");
janet_panic("file is closed");
if (!(iof->flags & (IO_WRITE | IO_APPEND | IO_UPDATE)))
JANET_THROW(args, "file is not writeable");
for (i = 1; i < args.n; i++) {
JANET_CHECKMANY(args, i, JANET_TFLAG_BYTES);
}
for (i = 1; i < args.n; i++) {
JANET_ARG_BYTES(str, len, args, i);
if (len) {
if (!fwrite(str, len, 1, iof->file)) JANET_THROW(args, "error writing to file");
janet_panic("file is not writeable");
int32_t i;
/* Verify all arguments before writing to file */
for (i = 1; i < argc; i++)
janet_getbytes(argv, i);
for (i = 1; i < argc; i++) {
JanetByteView view = janet_getbytes(argv, i);
if (view.len) {
if (!fwrite(view.bytes, view.len, 1, iof->file)) {
janet_panic("error writing to file");
}
}
}
JANET_RETURN(args, janet_wrap_abstract(iof));
return argv[0];
}
/* Flush the bytes in the file */
static int janet_io_fflush(JanetArgs args) {
IOFile *iof = checkfile(args, 0);
if (!iof) return 1;
static Janet janet_io_fflush(int32_t argc, Janet *argv) {
janet_arity(argc, 1, 1);
IOFile *iof = janet_getabstract(argv, 0, &janet_io_filetype);
if (iof->flags & IO_CLOSED)
JANET_THROW(args, "file is closed");
janet_panic("file is closed");
if (!(iof->flags & (IO_WRITE | IO_APPEND | IO_UPDATE)))
JANET_THROW(args, "file is not flushable");
if (fflush(iof->file)) JANET_THROW(args, "could not flush file");
JANET_RETURN(args, janet_wrap_abstract(iof));
janet_panic("file is not writeable");
if (fflush(iof->file))
janet_panic("could not flush file");
return argv[0];
}
/* Cleanup a file */
@ -306,38 +248,35 @@ static int janet_io_gc(void *p, size_t len) {
}
/* Close a file */
static int janet_io_fclose(JanetArgs args) {
IOFile *iof = checkfile(args, 0);
if (!iof) return 1;
if (iof->flags & (IO_CLOSED))
JANET_THROW(args, "file already closed");
static Janet janet_io_fclose(int32_t argc, Janet *argv) {
janet_arity(argc, 1, 1);
IOFile *iof = janet_getabstract(argv, 0, &janet_io_filetype);
if (iof->flags & IO_CLOSED)
janet_panic("file is closed");
if (iof->flags & (IO_NOT_CLOSEABLE))
JANET_THROW(args, "file not closable");
janet_panic("file not closable");
if (iof->flags & IO_PIPED) {
#ifdef JANET_WINDOWS
#define pclose _pclose
#endif
if (pclose(iof->file)) JANET_THROW(args, "could not close file");
if (pclose(iof->file)) janet_panic("could not close file");
} else {
if (fclose(iof->file)) JANET_THROW(args, "could not close file");
if (fclose(iof->file)) janet_panic("could not close file");
}
iof->flags |= IO_CLOSED;
JANET_RETURN(args, janet_wrap_abstract(iof));
return argv[0];
}
/* Seek a file */
static int janet_io_fseek(JanetArgs args) {
static Janet janet_io_fseek(int32_t argc, Janet *argv) {
janet_arity(argc, 2, 3);
IOFile *iof = janet_getabstract(argv, 0, &janet_io_filetype);
if (iof->flags & IO_CLOSED)
janet_panic("file is closed");
long int offset = 0;
int whence = SEEK_CUR;
IOFile *iof = checkfile(args, 0);
if (!iof) return 1;
if (iof->flags & IO_CLOSED)
JANET_THROW(args, "file is closed");
if (args.n >= 2) {
const uint8_t *whence_sym;
if (!janet_checktype(args.v[1], JANET_KEYWORD))
JANET_THROW(args, "expected keyword");
whence_sym = janet_unwrap_symbol(args.v[1]);
if (argc >= 2) {
const uint8_t *whence_sym = janet_getkeyword(argv, 1);
if (!janet_cstrcmp(whence_sym, "cur")) {
whence = SEEK_CUR;
} else if (!janet_cstrcmp(whence_sym, "set")) {
@ -345,17 +284,14 @@ static int janet_io_fseek(JanetArgs args) {
} else if (!janet_cstrcmp(whence_sym, "end")) {
whence = SEEK_END;
} else {
JANET_THROW(args, "expected one of :cur, :set, :end");
janet_panicf("expected one of :cur, :set, :end, got %v", argv[1]);
}
if (args.n >= 3) {
double doffset;
JANET_ARG_NUMBER(doffset, args, 2);
offset = (long int)doffset;
if (argc == 3) {
offset = janet_getinteger64(argv, 2);
}
}
if (fseek(iof->file, offset, whence))
JANET_THROW(args, "error seeking file");
JANET_RETURN(args, args.v[0]);
if (fseek(iof->file, offset, whence)) janet_panic("error seeking file");
return argv[0];
}
static const JanetReg cfuns[] = {
@ -420,25 +356,18 @@ static const JanetReg cfuns[] = {
};
/* Module entry point */
int janet_lib_io(JanetArgs args) {
JanetTable *env = janet_env(args);
void janet_lib_io(JanetTable *env) {
janet_cfuns(env, NULL, cfuns);
/* stdout */
janet_def(env, "stdout",
makef(stdout, IO_APPEND | IO_NOT_CLOSEABLE | IO_SERIALIZABLE),
"The standard output file.");
/* stderr */
janet_def(env, "stderr",
makef(stderr, IO_APPEND | IO_NOT_CLOSEABLE | IO_SERIALIZABLE),
"The standard error file.");
/* stdin */
janet_def(env, "stdin",
makef(stdin, IO_READ | IO_NOT_CLOSEABLE | IO_SERIALIZABLE),
"The standard input file.");
return 0;
}

View File

@ -21,7 +21,6 @@
*/
#include <janet/janet.h>
#include <setjmp.h>
#include "state.h"
#include "vector.h"
@ -124,7 +123,7 @@ JanetTable *janet_env_lookup(JanetTable *env) {
/* Marshal an integer onto the buffer */
static void pushint(MarshalState *st, int32_t x) {
if (x >= 0 && x < 200) {
if (janet_buffer_push_u8(st->buf, x)) longjmp(st->err, MR_OVERFLOW);
janet_buffer_push_u8(st->buf, x);
} else {
uint8_t intbuf[5];
intbuf[0] = LB_INTEGER;
@ -132,16 +131,16 @@ static void pushint(MarshalState *st, int32_t x) {
intbuf[2] = (x >> 8) & 0xFF;
intbuf[3] = (x >> 16) & 0xFF;
intbuf[4] = (x >> 24) & 0xFF;
if (janet_buffer_push_bytes(st->buf, intbuf, 5)) longjmp(st->err, MR_OVERFLOW);
janet_buffer_push_bytes(st->buf, intbuf, 5);
}
}
static void pushbyte(MarshalState *st, uint8_t b) {
if (janet_buffer_push_u8(st->buf, b)) longjmp(st->err, MR_OVERFLOW);
janet_buffer_push_u8(st->buf, b);
}
static void pushbytes(MarshalState *st, const uint8_t *bytes, int32_t len) {
if (janet_buffer_push_bytes(st->buf, bytes, len)) longjmp(st->err, MR_OVERFLOW);
janet_buffer_push_bytes(st->buf, bytes, len);
}
/* Forward declaration to enable mutual recursion. */
@ -1102,61 +1101,46 @@ int janet_unmarshal(
/* C functions */
static int cfun_env_lookup(JanetArgs args) {
JanetTable *env;
JANET_FIXARITY(args, 1);
JANET_ARG_TABLE(env, args, 0);
JANET_RETURN_TABLE(args, janet_env_lookup(env));
static Janet cfun_env_lookup(int32_t argc, Janet *argv) {
janet_arity(argc, 1, 1);
JanetTable *env = janet_gettable(argv, 0);
return janet_wrap_table(janet_env_lookup(env));
}
static int cfun_marshal(JanetArgs args) {
static Janet cfun_marshal(int32_t argc, Janet *argv) {
janet_arity(argc, 1, 2);
JanetBuffer *buffer;
JanetTable *rreg;
JanetTable *rreg = NULL;
Janet err_param = janet_wrap_nil();
int status;
JANET_MINARITY(args, 1);
JANET_MAXARITY(args, 3);
if (args.n > 1) {
/* Reverse Registry provided */
JANET_ARG_TABLE(rreg, args, 1);
} else {
rreg = NULL;
if (argc > 1) {
rreg = janet_gettable(argv, 1);
}
if (args.n > 2) {
/* Buffer provided */
JANET_ARG_BUFFER(buffer, args, 2);
if (argc > 2) {
buffer = janet_getbuffer(argv, 2);
} else {
buffer = janet_buffer(10);
}
status = janet_marshal(buffer, args.v[0], &err_param, rreg, 0);
if (status) {
const uint8_t *errstr = janet_formatc(
"%s for %V",
mr_strings[status],
err_param);
JANET_THROWV(args, janet_wrap_string(errstr));
}
JANET_RETURN_BUFFER(args, buffer);
status = janet_marshal(buffer, argv[0], &err_param, rreg, 0);
if (status)
janet_panicf("%s for %V", mr_strings[status], err_param);
return janet_wrap_buffer(buffer);
}
static int cfun_unmarshal(JanetArgs args) {
const uint8_t *bytes;
JanetTable *reg;
int32_t len;
static Janet cfun_unmarshal(int32_t argc, Janet *argv) {
janet_arity(argc, 1, 2);
JanetByteView view = janet_getbytes(argv, 0);
JanetTable *reg = NULL;
Janet ret;
int status;
JANET_MINARITY(args, 1);
JANET_MAXARITY(args, 2);
JANET_ARG_BYTES(bytes, len, args, 0);
if (args.n > 1) {
JANET_ARG_TABLE(reg, args, 1);
} else {
reg = NULL;
if (argc > 1) {
reg = janet_gettable(argv, 1);
}
status = janet_unmarshal(bytes, (size_t) len, 0, args.ret, reg, NULL);
status = janet_unmarshal(view.bytes, (size_t) view.len, 0, &ret, reg, NULL);
if (status) {
JANET_THROW(args, umr_strings[status]);
janet_panic(umr_strings[status]);
}
return JANET_SIGNAL_OK;
return ret;
}
static const JanetReg cfuns[] = {
@ -1185,8 +1169,6 @@ static const JanetReg cfuns[] = {
};
/* Module entry point */
int janet_lib_marsh(JanetArgs args) {
JanetTable *env = janet_env(args);
void janet_lib_marsh(JanetTable *env) {
janet_cfuns(env, NULL, cfuns);
return 0;
}

View File

@ -24,35 +24,33 @@
#include <math.h>
/* Get a random number */
int janet_rand(JanetArgs args) {
JANET_FIXARITY(args, 0);
Janet janet_rand(int32_t argc, Janet *argv) {
(void) argv;
janet_arity(argc, 0, 0);
double r = (rand() % RAND_MAX) / ((double) RAND_MAX);
JANET_RETURN_NUMBER(args, r);
return janet_wrap_number(r);
}
/* Seed the random number generator */
int janet_srand(JanetArgs args) {
int32_t x = 0;
JANET_FIXARITY(args, 1);
JANET_ARG_INTEGER(x, args, 0);
Janet janet_srand(int32_t argc, Janet *argv) {
janet_arity(argc, 1, 1);
int32_t x = janet_getinteger(argv, 0);
srand((unsigned) x);
return 0;
return janet_wrap_nil();
}
int janet_remainder(JanetArgs args) {
JANET_FIXARITY(args, 2);
double x, y;
JANET_ARG_NUMBER(x, args, 0);
JANET_ARG_NUMBER(y, args, 1);
JANET_RETURN_NUMBER(args, fmod(x, y));
Janet janet_remainder(int32_t argc, Janet *argv) {
janet_arity(argc, 2, 2);
double x = janet_getnumber(argv, 0);
double y = janet_getnumber(argv, 1);
return janet_wrap_number(fmod(x, y));
}
#define JANET_DEFINE_MATHOP(name, fop)\
int janet_##name(JanetArgs args) {\
double x;\
JANET_FIXARITY(args, 1);\
JANET_ARG_NUMBER(x, args, 0);\
JANET_RETURN_NUMBER(args, fop(x));\
Janet janet_##name(int32_t argc, Janet *argv) {\
janet_arity(argc, 1, 1); \
double x = janet_getnumber(argv, 0); \
return janet_wrap_number(fop(x)); \
}
JANET_DEFINE_MATHOP(acos, acos)
@ -73,20 +71,19 @@ JANET_DEFINE_MATHOP(fabs, fabs)
JANET_DEFINE_MATHOP(floor, floor)
#define JANET_DEFINE_MATH2OP(name, fop)\
int janet_##name(JanetArgs args) {\
double lhs, rhs;\
JANET_FIXARITY(args, 2);\
JANET_ARG_NUMBER(lhs, args, 0);\
JANET_ARG_NUMBER(rhs, args, 1);\
JANET_RETURN_NUMBER(args, fop(lhs, rhs));\
Janet janet_##name(int32_t argc, Janet *argv) {\
janet_arity(argc, 2, 2); \
double lhs = janet_getnumber(argv, 0); \
double rhs = janet_getnumber(argv, 1); \
return janet_wrap_number(fop(lhs, rhs)); \
}\
JANET_DEFINE_MATH2OP(atan2, atan2)
JANET_DEFINE_MATH2OP(pow, pow)
static int janet_not(JanetArgs args) {
JANET_FIXARITY(args, 1);
JANET_RETURN_BOOLEAN(args, !janet_truthy(args.v[0]));
static Janet janet_not(int32_t argc, Janet *argv) {
janet_arity(argc, 1, 1);
return janet_wrap_boolean(!janet_truthy(argv[0]));
}
static const JanetReg cfuns[] = {
@ -162,15 +159,12 @@ static const JanetReg cfuns[] = {
};
/* Module entry point */
int janet_lib_math(JanetArgs args) {
JanetTable *env = janet_env(args);
void janet_lib_math(JanetTable *env) {
janet_cfuns(env, NULL, cfuns);
janet_def(env, "math/pi", janet_wrap_number(3.1415926535897931),
"The value pi.");
janet_def(env, "math/e", janet_wrap_number(2.7182818284590451),
"The base of the natural log.");
janet_def(env, "math/inf", janet_wrap_number(INFINITY),
"The number representing positive infinity");
return 0;
}

View File

@ -40,27 +40,28 @@
#include <mach/mach.h>
#endif
static int os_which(JanetArgs args) {
static Janet os_which(int32_t argc, Janet *argv) {
janet_arity(argc, 0, 0);
(void) argv;
#ifdef JANET_WINDOWS
JANET_RETURN_CKEYWORD(args, "windows");
return janet_ckeywordv("windows");
#elif __APPLE__
JANET_RETURN_CKEYWORD(args, "macos");
return janet_ckeywordv("macos");
#elif defined(__EMSCRIPTEN__)
JANET_RETURN_CKEYWORD(args, "web");
return janet_ckeywordv("web");
#else
JANET_RETURN_CKEYWORD(args, "posix");
return janet_ckeywordv("posix");
#endif
}
#ifdef JANET_WINDOWS
static int os_execute(JanetArgs args) {
JANET_MINARITY(args, 1);
static Janet os_execute(int32_t argc, Janet *argv) {
janet_arity(argc, 1, -1);
JanetBuffer *buffer = janet_buffer(10);
for (int32_t i = 0; i < args.n; i++) {
const uint8_t *argstring;
JANET_ARG_STRING(argstring, args, i);
for (int32_t i = 0; i < argc; i++) {
const uint8_t *argstring = janet_getstring(argv, i);
janet_buffer_push_bytes(buffer, argstring, janet_string_length(argstring));
if (i != args.n - 1) {
if (i != argc - 1) {
janet_buffer_push_u8(buffer, ' ');
}
}
@ -80,7 +81,7 @@ static int os_execute(JanetArgs args) {
buffer->count);
if (nwritten == 0) {
free(sys_str);
JANET_THROW(args, "could not create process");
janet_panic("could not create process");
}
STARTUPINFO si;
@ -102,7 +103,7 @@ static int os_execute(JanetArgs args) {
&si,
&pi)) {
free(sys_str);
JANET_THROW(args, "could not create process");
janet_panic("could not create process");
}
free(sys_str);
@ -114,61 +115,57 @@ static int os_execute(JanetArgs args) {
GetExitCodeProcess(pi.hProcess, (LPDWORD)&status);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
JANET_RETURN_INTEGER(args, (int32_t)status);
return janet_wrap_integer(status);
}
#else
static int os_execute(JanetArgs args) {
JANET_MINARITY(args, 1);
const uint8_t **argv = malloc(sizeof(uint8_t *) * (args.n + 1));
if (NULL == argv) {
static Janet os_execute(int32_t argc, Janet *argv) {
janet_arity(argc, 1, -1);
const uint8_t **child_argv = malloc(sizeof(uint8_t *) * (argc + 1));
if (NULL == child_argv) {
JANET_OUT_OF_MEMORY;
}
for (int32_t i = 0; i < args.n; i++) {
JANET_ARG_STRING(argv[i], args, i);
for (int32_t i = 0; i < argc; i++) {
child_argv[i] = janet_getstring(argv, i);
}
argv[args.n] = NULL;
child_argv[argc] = NULL;
/* Fork child process */
pid_t pid = fork();
if (pid < 0) {
JANET_THROW(args, "failed to execute");
janet_panic("failed to execute");
} else if (pid == 0) {
if (-1 == execve((const char *)argv[0], (char **)argv, NULL)) {
if (-1 == execve((const char *)child_argv[0], (char **)child_argv, NULL)) {
exit(1);
}
}
int status;
waitpid(pid, &status, 0);
JANET_RETURN_INTEGER(args, status);
return janet_wrap_integer(status);
}
#endif
static int os_shell(JanetArgs args) {
int nofirstarg = (args.n < 1 || !janet_checktype(args.v[0], JANET_STRING));
const char *cmd = nofirstarg
? NULL
: (const char *) janet_unwrap_string(args.v[0]);
static Janet os_shell(int32_t argc, Janet *argv) {
janet_arity(argc, 0, 1);
const char *cmd = argc
? (const char *)janet_getstring(argv, 0)
: NULL;
int stat = system(cmd);
JANET_RETURN(args, cmd
? janet_wrap_integer(stat)
: janet_wrap_boolean(stat));
return argc
? janet_wrap_integer(stat)
: janet_wrap_boolean(stat);
}
static int os_getenv(JanetArgs args) {
const uint8_t *k;
JANET_FIXARITY(args, 1);
JANET_ARG_STRING(k, args, 0);
static Janet os_getenv(int32_t argc, Janet *argv) {
janet_arity(argc, 1, 1);
const uint8_t *k = janet_getstring(argv, 0);
const char *cstr = (const char *) k;
const char *res = getenv(cstr);
if (!res) {
JANET_RETURN_NIL(args);
}
JANET_RETURN(args, cstr
? janet_cstringv(res)
: janet_wrap_nil());
return (res && cstr)
? janet_cstringv(res)
: janet_wrap_nil();
}
static int os_setenv(JanetArgs args) {
static Janet os_setenv(int32_t argc, Janet *argv) {
#ifdef JANET_WINDOWS
#define SETENV(K,V) _putenv_s(K, V)
#define UNSETENV(K) _putenv_s(K, "")
@ -176,39 +173,35 @@ static int os_setenv(JanetArgs args) {
#define SETENV(K,V) setenv(K, V, 1)
#define UNSETENV(K) unsetenv(K)
#endif
const uint8_t *k;
const char *ks;
JANET_MAXARITY(args, 2);
JANET_MINARITY(args, 1);
JANET_ARG_STRING(k, args, 0);
ks = (const char *) k;
if (args.n == 1 || janet_checktype(args.v[1], JANET_NIL)) {
janet_arity(argc, 1, 2);
const uint8_t *k = janet_getstring(argv, 0);
const char *ks = (const char *) k;
if (argc == 1 || janet_checktype(argv[1], JANET_NIL)) {
UNSETENV(ks);
} else {
const uint8_t *v;
JANET_ARG_STRING(v, args, 1);
const char *vc = (const char *) v;
SETENV(ks, vc);
const uint8_t *v = janet_getstring(argv, 1);
SETENV(ks, (const char *)v);
}
return 0;
return janet_wrap_nil();
}
static int os_exit(JanetArgs args) {
JANET_MAXARITY(args, 1);
if (args.n == 0) {
static Janet os_exit(int32_t argc, Janet *argv) {
janet_arity(argc, 0, 1);
if (argc == 0) {
exit(EXIT_SUCCESS);
} else if (janet_checkint(args.v[0])) {
exit(janet_unwrap_integer(args.v[0]));
} else if (janet_checkint(argv[0])) {
exit(janet_unwrap_integer(argv[0]));
} else {
exit(EXIT_FAILURE);
}
return 0;
return janet_wrap_nil();
}
static int os_time(JanetArgs args) {
JANET_FIXARITY(args, 0);
static Janet os_time(int32_t argc, Janet *argv) {
janet_arity(argc, 0, 0);
(void) argv;
double dtime = (double)(time(NULL));
JANET_RETURN_NUMBER(args, dtime);
return janet_wrap_number(dtime);
}
/* Clock shims */
@ -238,22 +231,19 @@ static int gettime(struct timespec *spec) {
#define gettime(TV) clock_gettime(CLOCK_MONOTONIC, (TV))
#endif
static int os_clock(JanetArgs args) {
JANET_FIXARITY(args, 0);
static Janet os_clock(int32_t argc, Janet *argv) {
janet_arity(argc, 0, 0);
(void) argv;
struct timespec tv;
if (gettime(&tv))
JANET_THROW(args, "could not get time");
if (gettime(&tv)) janet_panic("could not get time");
double dtime = tv.tv_sec + (tv.tv_nsec / 1E9);
JANET_RETURN_NUMBER(args, dtime);
return janet_wrap_number(dtime);
}
static int os_sleep(JanetArgs args) {
double delay;
JANET_FIXARITY(args, 1);
JANET_ARG_NUMBER(delay, args, 0);
if (delay < 0) {
JANET_THROW(args, "invalid argument to sleep");
}
static Janet os_sleep(int32_t argc, Janet *argv) {
janet_arity(argc, 1, 1);
double delay = janet_getnumber(argv, 0);
if (delay < 0) janet_panic("invalid argument to sleep");
#ifdef JANET_WINDOWS
Sleep((DWORD) (delay * 1000));
#else
@ -264,11 +254,12 @@ static int os_sleep(JanetArgs args) {
: 0;
nanosleep(&ts, NULL);
#endif
return 0;
return janet_wrap_nil();
}
static int os_cwd(JanetArgs args) {
JANET_FIXARITY(args, 0);
static Janet os_cwd(int32_t argc, Janet *argv) {
janet_arity(argc, 0, 0);
(void) argv;
char buf[FILENAME_MAX];
char *ptr;
#ifdef JANET_WINDOWS
@ -276,10 +267,8 @@ static int os_cwd(JanetArgs args) {
#else
ptr = getcwd(buf, FILENAME_MAX);
#endif
if (NULL == ptr) {
JANET_THROW(args, "could not get current directory");
}
JANET_RETURN_CSTRING(args, ptr);
if (NULL == ptr) janet_panic("could not get current directory");
return janet_cstringv(ptr);
}
static const JanetReg cfuns[] = {
@ -335,8 +324,6 @@ static const JanetReg cfuns[] = {
};
/* Module entry point */
int janet_lib_os(JanetArgs args) {
JanetTable *env = janet_env(args);
void janet_lib_os(JanetTable *env) {
janet_cfuns(env, NULL, cfuns);
return 0;
}

View File

@ -620,79 +620,58 @@ static JanetAbstractType janet_parse_parsertype = {
parsermark
};
JanetParser *janet_check_parser(Janet x) {
if (!janet_checktype(x, JANET_ABSTRACT))
return NULL;
void *abstract = janet_unwrap_abstract(x);
if (janet_abstract_type(abstract) != &janet_parse_parsertype)
return NULL;
return (JanetParser *)abstract;
}
/* C Function parser */
static int cfun_parser(JanetArgs args) {
JANET_FIXARITY(args, 0);
static Janet cfun_parser(int32_t argc, Janet *argv) {
(void) argv;
janet_arity(argc, 0, 0);
JanetParser *p = janet_abstract(&janet_parse_parsertype, sizeof(JanetParser));
janet_parser_init(p);
JANET_RETURN_ABSTRACT(args, p);
return janet_wrap_abstract(p);
}
static int cfun_consume(JanetArgs args) {
const uint8_t *bytes;
int32_t len;
JanetParser *p;
int32_t i;
JANET_MINARITY(args, 2);
JANET_MAXARITY(args, 3);
JANET_CHECKABSTRACT(args, 0, &janet_parse_parsertype);
p = (JanetParser *) janet_unwrap_abstract(args.v[0]);
JANET_ARG_BYTES(bytes, len, args, 1);
if (args.n == 3) {
int32_t offset;
JANET_ARG_INTEGER(offset, args, 2);
if (offset < 0 || offset > len)
JANET_THROW(args, "invalid offset");
len -= offset;
bytes += offset;
static Janet cfun_consume(int32_t argc, Janet *argv) {
janet_arity(argc, 2, 3);
JanetParser *p = janet_getabstract(argv, 0, &janet_parse_parsertype);
JanetByteView view = janet_getbytes(argv, 1);
if (argc == 3) {
int32_t offset = janet_getinteger(argv, 2);
if (offset < 0 || offset > view.len)
janet_panicf("invalid offset %d out of range [0,%d]", offset, view.len);
view.len -= offset;
view.bytes += offset;
}
for (i = 0; i < len; i++) {
janet_parser_consume(p, bytes[i]);
int32_t i;
for (i = 0; i < view.len; i++) {
janet_parser_consume(p, view.bytes[i]);
switch (janet_parser_status(p)) {
case JANET_PARSE_ROOT:
case JANET_PARSE_PENDING:
break;
default:
JANET_RETURN_INTEGER(args, i + 1);
return janet_wrap_integer(i + 1);
}
}
JANET_RETURN_INTEGER(args, i);
return janet_wrap_integer(i);
}
static int cfun_has_more(JanetArgs args) {
JanetParser *p;
JANET_FIXARITY(args, 1);
JANET_CHECKABSTRACT(args, 0, &janet_parse_parsertype);
p = (JanetParser *) janet_unwrap_abstract(args.v[0]);
JANET_RETURN_BOOLEAN(args, janet_parser_has_more(p));
static Janet cfun_has_more(int32_t argc, Janet *argv) {
janet_arity(argc, 1, 1);
JanetParser *p = janet_getabstract(argv, 0, &janet_parse_parsertype);
return janet_wrap_boolean(janet_parser_has_more(p));
}
static int cfun_byte(JanetArgs args) {
int32_t i;
JanetParser *p;
JANET_FIXARITY(args, 2);
JANET_CHECKABSTRACT(args, 0, &janet_parse_parsertype);
p = (JanetParser *) janet_unwrap_abstract(args.v[0]);
JANET_ARG_INTEGER(i, args, 1);
static Janet cfun_byte(int32_t argc, Janet *argv) {
janet_arity(argc, 2, 2);
JanetParser *p = janet_getabstract(argv, 0, &janet_parse_parsertype);
int32_t i = janet_getinteger(argv, 1);
janet_parser_consume(p, 0xFF & i);
JANET_RETURN(args, args.v[0]);
return argv[0];
}
static int cfun_status(JanetArgs args) {
static Janet cfun_status(int32_t argc, Janet *argv) {
janet_arity(argc, 1, 1);
JanetParser *p = janet_getabstract(argv, 0, &janet_parse_parsertype);
const char *stat = NULL;
JanetParser *p;
JANET_FIXARITY(args, 1);
JANET_CHECKABSTRACT(args, 0, &janet_parse_parsertype);
p = (JanetParser *) janet_unwrap_abstract(args.v[0]);
switch (janet_parser_status(p)) {
case JANET_PARSE_PENDING:
stat = "pending";
@ -704,58 +683,42 @@ static int cfun_status(JanetArgs args) {
stat = "root";
break;
}
JANET_RETURN_CKEYWORD(args, stat);
return janet_ckeywordv(stat);
}
static int cfun_error(JanetArgs args) {
const char *err;
JanetParser *p;
JANET_FIXARITY(args, 1);
JANET_CHECKABSTRACT(args, 0, &janet_parse_parsertype);
p = (JanetParser *) janet_unwrap_abstract(args.v[0]);
err = janet_parser_error(p);
if (err) {
JANET_RETURN_CSTRING(args, err);
} else {
JANET_RETURN_NIL(args);
}
static Janet cfun_error(int32_t argc, Janet *argv) {
janet_arity(argc, 1, 1);
JanetParser *p = janet_getabstract(argv, 0, &janet_parse_parsertype);
const char *err = janet_parser_error(p);
if (err) return janet_cstringv(err);
return janet_wrap_nil();
}
static int cfun_produce(JanetArgs args) {
Janet val;
JanetParser *p;
JANET_FIXARITY(args, 1);
JANET_CHECKABSTRACT(args, 0, &janet_parse_parsertype);
p = (JanetParser *) janet_unwrap_abstract(args.v[0]);
val = janet_parser_produce(p);
JANET_RETURN(args, val);
static Janet cfun_produce(int32_t argc, Janet *argv) {
janet_arity(argc, 1, 1);
JanetParser *p = janet_getabstract(argv, 0, &janet_parse_parsertype);
return janet_parser_produce(p);
}
static int cfun_flush(JanetArgs args) {
JanetParser *p;
JANET_FIXARITY(args, 1);
JANET_CHECKABSTRACT(args, 0, &janet_parse_parsertype);
p = (JanetParser *) janet_unwrap_abstract(args.v[0]);
static Janet cfun_flush(int32_t argc, Janet *argv) {
janet_arity(argc, 1, 1);
JanetParser *p = janet_getabstract(argv, 0, &janet_parse_parsertype);
janet_parser_flush(p);
JANET_RETURN(args, args.v[0]);
return argv[0];
}
static int cfun_where(JanetArgs args) {
JanetParser *p;
JANET_FIXARITY(args, 1);
JANET_CHECKABSTRACT(args, 0, &janet_parse_parsertype);
p = (JanetParser *) janet_unwrap_abstract(args.v[0]);
JANET_RETURN_INTEGER(args, p->offset);
static Janet cfun_where(int32_t argc, Janet *argv) {
janet_arity(argc, 1, 1);
JanetParser *p = janet_getabstract(argv, 0, &janet_parse_parsertype);
return janet_wrap_integer(p->offset);
}
static int cfun_state(JanetArgs args) {
static Janet cfun_state(int32_t argc, Janet *argv) {
size_t i;
const uint8_t *str;
size_t oldcount;
JanetParser *p;
JANET_FIXARITY(args, 1);
JANET_CHECKABSTRACT(args, 0, &janet_parse_parsertype);
p = (JanetParser *) janet_unwrap_abstract(args.v[0]);
janet_arity(argc, 1, 1);
JanetParser *p = janet_getabstract(argv, 0, &janet_parse_parsertype);
oldcount = p->bufcount;
for (i = 0; i < p->statecount; i++) {
JanetParseState *s = p->states + i;
@ -776,7 +739,7 @@ static int cfun_state(JanetArgs args) {
}
str = janet_string(p->buf + oldcount, (int32_t)(p->bufcount - oldcount));
p->bufcount = oldcount;
JANET_RETURN_STRING(args, str);
return janet_wrap_string(str);
}
static const JanetReg cfuns[] = {
@ -843,8 +806,6 @@ static const JanetReg cfuns[] = {
};
/* Load the library */
int janet_lib_parse(JanetArgs args) {
JanetTable *env = janet_env(args);
void janet_lib_parse(JanetTable *env) {
janet_cfuns(env, NULL, cfuns);
return 0;
}

View File

@ -825,185 +825,125 @@ static int32_t kmp_next(struct kmp_state *state) {
/* CFuns */
static int cfun_slice(JanetArgs args) {
const uint8_t *data;
int32_t len, start, end;
const uint8_t *ret;
JANET_MINARITY(args, 1);
JANET_MAXARITY(args, 3);
JANET_ARG_BYTES(data, len, args, 0);
/* Get start */
if (args.n < 2) {
start = 0;
} else {
JANET_ARG_INTEGER(start, args, 1);
}
/* Get end */
if (args.n < 3) {
end = -1;
} else {
JANET_ARG_INTEGER(end, args, 2);
}
if (start < 0) start = len + start;
if (end < 0) end = len + end + 1;
if (end < 0 || start < 0 || end > len || start > len)
JANET_THROW(args, "slice range out of bounds");
if (end >= start) {
ret = janet_string(data + start, end - start);
} else {
ret = janet_cstring("");
}
JANET_RETURN_STRING(args, ret);
static Janet cfun_slice(int32_t argc, Janet *argv) {
JanetRange range = janet_getslice(argc, argv);
JanetByteView view = janet_getbytes(argv, 0);
return janet_stringv(view.bytes + range.start, range.end - range.start);
}
static int cfun_repeat(JanetArgs args) {
const uint8_t *data;
uint8_t *newbuf, *p, *end;
int32_t len, rep;
int64_t mulres;
JANET_FIXARITY(args, 2);
JANET_ARG_BYTES(data, len, args, 0);
JANET_ARG_INTEGER(rep, args, 1);
if (rep < 0) {
JANET_THROW(args, "expected non-negative number of repetitions");
} else if (rep == 0) {
JANET_RETURN_CSTRING(args, "");
static Janet cfun_repeat(int32_t argc, Janet *argv) {
janet_arity(argc, 2, 2);
JanetByteView view = janet_getbytes(argv, 0);
int32_t rep = janet_getinteger(argv, 1);
if (rep < 0) janet_panic("expected non-negative number of repetitions");
if (rep == 0) return janet_cstringv("");
int64_t mulres = (int64_t) rep * view.len;
if (mulres > INT32_MAX) janet_panic("result string is too long");
uint8_t *newbuf = janet_string_begin((int32_t) mulres);
uint8_t *end = newbuf + mulres;
uint8_t *p = newbuf;
for (p = newbuf; p < end; p += view.len) {
memcpy(p, view.bytes, view.len);
}
mulres = (int64_t) rep * len;
if (mulres > INT32_MAX) {
JANET_THROW(args, "result string is too long");
}
newbuf = janet_string_begin((int32_t) mulres);
end = newbuf + mulres;
for (p = newbuf; p < end; p += len) {
memcpy(p, data, len);
}
JANET_RETURN_STRING(args, janet_string_end(newbuf));
return janet_wrap_string(janet_string_end(newbuf));
}
static int cfun_bytes(JanetArgs args) {
const uint8_t *str;
int32_t strlen, i;
Janet *tup;
JANET_FIXARITY(args, 1);
JANET_ARG_BYTES(str, strlen, args, 0);
tup = janet_tuple_begin(strlen);
for (i = 0; i < strlen; i++) {
tup[i] = janet_wrap_integer((int32_t) str[i]);
}
JANET_RETURN_TUPLE(args, janet_tuple_end(tup));
}
static int cfun_frombytes(JanetArgs args) {
static Janet cfun_bytes(int32_t argc, Janet *argv) {
janet_arity(argc, 1, 1);
JanetByteView view = janet_getbytes(argv, 0);
Janet *tup = janet_tuple_begin(view.len);
int32_t i;
uint8_t *buf;
for (i = 0; i < args.n; i++) {
if (!janet_checkint(args.v[i])) {
JANET_THROW(args, "expected integer byte values");
}
for (i = 0; i < view.len; i++) {
tup[i] = janet_wrap_integer((int32_t) view.bytes[i]);
}
buf = janet_string_begin(args.n);
for (i = 0; i < args.n; i++) {
int32_t c;
JANET_ARG_INTEGER(c, args, i);
return janet_wrap_tuple(janet_tuple_end(tup));
}
static Janet cfun_frombytes(int32_t argc, Janet *argv) {
int32_t i;
uint8_t *buf = janet_string_begin(argc);
for (i = 0; i < argc; i++) {
int32_t c = janet_getinteger(argv, i);
buf[i] = c & 0xFF;
}
JANET_RETURN_STRING(args, janet_string_end(buf));
return janet_wrap_string(janet_string_end(buf));
}
static int cfun_asciilower(JanetArgs args) {
const uint8_t *str;
uint8_t *buf;
int32_t len, i;
JANET_FIXARITY(args, 1);
JANET_ARG_BYTES(str, len, args, 0);
buf = janet_string_begin(len);
for (i = 0; i < len; i++) {
uint8_t c = str[i];
static Janet cfun_asciilower(int32_t argc, Janet *argv) {
janet_arity(argc, 1, 1);
JanetByteView view = janet_getbytes(argv, 0);
uint8_t *buf = janet_string_begin(view.len);
for (int32_t i = 0; i < view.len; i++) {
uint8_t c = view.bytes[i];
if (c >= 65 && c <= 90) {
buf[i] = c + 32;
} else {
buf[i] = c;
}
}
JANET_RETURN_STRING(args, janet_string_end(buf));
return janet_wrap_string(janet_string_end(buf));
}
static int cfun_asciiupper(JanetArgs args) {
const uint8_t *str;
uint8_t *buf;
int32_t len, i;
JANET_FIXARITY(args, 1);
JANET_ARG_BYTES(str, len, args, 0);
buf = janet_string_begin(len);
for (i = 0; i < len; i++) {
uint8_t c = str[i];
static Janet cfun_asciiupper(int32_t argc, Janet *argv) {
janet_arity(argc, 1, 1);
JanetByteView view = janet_getbytes(argv, 0);
uint8_t *buf = janet_string_begin(view.len);
for (int32_t i = 0; i < view.len; i++) {
uint8_t c = view.bytes[i];
if (c >= 97 && c <= 122) {
buf[i] = c - 32;
} else {
buf[i] = c;
}
}
JANET_RETURN_STRING(args, janet_string_end(buf));
return janet_wrap_string(janet_string_end(buf));
}
static int cfun_reverse(JanetArgs args) {
const uint8_t *str;
uint8_t *buf;
int32_t len, i, j;
JANET_FIXARITY(args, 1);
JANET_ARG_BYTES(str, len, args, 0);
buf = janet_string_begin(len);
for (i = 0, j = len - 1; i < len; i++, j--) {
buf[i] = str[j];
static Janet cfun_reverse(int32_t argc, Janet *argv) {
janet_arity(argc, 1, 1);
JanetByteView view = janet_getbytes(argv, 0);
uint8_t *buf = janet_string_begin(view.len);
int32_t i, j;
for (i = 0, j = view.len - 1; i < view.len; i++, j--) {
buf[i] = view.bytes[j];
}
JANET_RETURN_STRING(args, janet_string_end(buf));
return janet_wrap_string(janet_string_end(buf));
}
static int findsetup(JanetArgs args, struct kmp_state *s, int32_t extra) {
const uint8_t *text, *pat;
int32_t textlen, patlen, start;
JANET_MINARITY(args, 2);
JANET_MAXARITY(args, 3 + extra);
JANET_ARG_BYTES(pat, patlen, args, 0);
JANET_ARG_BYTES(text, textlen, args, 1);
if (args.n >= 3) {
JANET_ARG_INTEGER(start, args, 2);
if (start < 0) {
JANET_THROW(args, "expected non-negative start index");
}
} else {
start = 0;
static void findsetup(int32_t argc, Janet *argv, struct kmp_state *s, int32_t extra) {
janet_arity(argc, 2, 3 + extra);
JanetByteView pat = janet_getbytes(argv, 0);
JanetByteView text = janet_getbytes(argv, 1);
int32_t start = 0;
if (argc >= 3) {
start = janet_getinteger(argv, 2);
if (start < 0) janet_panic("expected non-negative start index");
}
kmp_init(s, text, textlen, pat, patlen);
kmp_init(s, text.bytes, text.len, pat.bytes, pat.len);
s->i = start;
return JANET_SIGNAL_OK;
}
static int cfun_find(JanetArgs args) {
static Janet cfun_find(int32_t argc, Janet *argv) {
int32_t result;
struct kmp_state state;
int status = findsetup(args, &state, 0);
if (status) return status;
findsetup(argc, argv, &state, 0);
result = kmp_next(&state);
kmp_deinit(&state);
JANET_RETURN(args, result < 0
? janet_wrap_nil()
: janet_wrap_integer(result));
return result < 0
? janet_wrap_nil()
: janet_wrap_integer(result);
}
static int cfun_findall(JanetArgs args) {
static Janet cfun_findall(int32_t argc, Janet *argv) {
int32_t result;
JanetArray *array;
struct kmp_state state;
int status = findsetup(args, &state, 0);
if (status) return status;
array = janet_array(0);
findsetup(argc, argv, &state, 0);
JanetArray *array = janet_array(0);
while ((result = kmp_next(&state)) >= 0) {
janet_array_push(array, janet_wrap_integer(result));
}
kmp_deinit(&state);
JANET_RETURN_ARRAY(args, array);
return janet_wrap_array(array);
}
struct replace_state {
@ -1012,39 +952,31 @@ struct replace_state {
int32_t substlen;
};
static int replacesetup(JanetArgs args, struct replace_state *s) {
const uint8_t *text, *pat, *subst;
int32_t textlen, patlen, substlen, start;
JANET_MINARITY(args, 3);
JANET_MAXARITY(args, 4);
JANET_ARG_BYTES(pat, patlen, args, 0);
JANET_ARG_BYTES(subst, substlen, args, 1);
JANET_ARG_BYTES(text, textlen, args, 2);
if (args.n == 4) {
JANET_ARG_INTEGER(start, args, 3);
if (start < 0) {
JANET_THROW(args, "expected non-negative start index");
}
} else {
start = 0;
static void replacesetup(int32_t argc, Janet *argv, struct replace_state *s) {
janet_arity(argc, 3, 4);
JanetByteView pat = janet_getbytes(argv, 0);
JanetByteView subst = janet_getbytes(argv, 1);
JanetByteView text = janet_getbytes(argv, 2);
int32_t start = 0;
if (argc == 4) {
start = janet_getinteger(argv, 3);
if (start < 0) janet_panic("expected non-negative start index");
}
kmp_init(&s->kmp, text, textlen, pat, patlen);
kmp_init(&s->kmp, text.bytes, text.len, pat.bytes, pat.len);
s->kmp.i = start;
s->subst = subst;
s->substlen = substlen;
return JANET_SIGNAL_OK;
s->subst = subst.bytes;
s->substlen = subst.len;
}
static int cfun_replace(JanetArgs args) {
static Janet cfun_replace(int32_t argc, Janet *argv) {
int32_t result;
struct replace_state s;
uint8_t *buf;
int status = replacesetup(args, &s);
if (status) return status;
replacesetup(argc, argv, &s);
result = kmp_next(&s.kmp);
if (result < 0) {
kmp_deinit(&s.kmp);
JANET_RETURN_STRING(args, janet_string(s.kmp.text, s.kmp.textlen));
return janet_stringv(s.kmp.text, s.kmp.textlen);
}
buf = janet_string_begin(s.kmp.textlen - s.kmp.patlen + s.substlen);
memcpy(buf, s.kmp.text, result);
@ -1053,17 +985,15 @@ static int cfun_replace(JanetArgs args) {
s.kmp.text + result + s.kmp.patlen,
s.kmp.textlen - result - s.kmp.patlen);
kmp_deinit(&s.kmp);
JANET_RETURN_STRING(args, janet_string_end(buf));
return janet_wrap_string(janet_string_end(buf));
}
static int cfun_replaceall(JanetArgs args) {
static Janet cfun_replaceall(int32_t argc, Janet *argv) {
int32_t result;
struct replace_state s;
JanetBuffer b;
const uint8_t *ret;
int32_t lastindex = 0;
int status = replacesetup(args, &s);
if (status) return status;
replacesetup(argc, argv, &s);
janet_buffer_init(&b, s.kmp.textlen);
while ((result = kmp_next(&s.kmp)) >= 0) {
janet_buffer_push_bytes(&b, s.kmp.text + lastindex, result - lastindex);
@ -1072,22 +1002,21 @@ static int cfun_replaceall(JanetArgs args) {
kmp_seti(&s.kmp, lastindex);
}
janet_buffer_push_bytes(&b, s.kmp.text + lastindex, s.kmp.textlen - lastindex);
ret = janet_string(b.data, b.count);
const uint8_t *ret = janet_string(b.data, b.count);
janet_buffer_deinit(&b);
kmp_deinit(&s.kmp);
JANET_RETURN_STRING(args, ret);
return janet_wrap_string(ret);
}
static int cfun_split(JanetArgs args) {
static Janet cfun_split(int32_t argc, Janet *argv) {
int32_t result;
JanetArray *array;
struct kmp_state state;
int32_t limit = -1, lastindex = 0;
if (args.n == 4) {
JANET_ARG_INTEGER(limit, args, 3);
if (argc == 4) {
limit = janet_getinteger(argv, 3);
}
int status = findsetup(args, &state, 1);
if (status) return status;
findsetup(argc, argv, &state, 1);
array = janet_array(0);
while ((result = kmp_next(&state)) >= 0 && limit--) {
const uint8_t *slice = janet_string(state.text + lastindex, result - lastindex);
@ -1099,80 +1028,75 @@ static int cfun_split(JanetArgs args) {
janet_array_push(array, janet_wrap_string(slice));
}
kmp_deinit(&state);
JANET_RETURN_ARRAY(args, array);
return janet_wrap_array(array);
}
static int cfun_checkset(JanetArgs args) {
const uint8_t *set, *str;
int32_t setlen, strlen, i;
static Janet cfun_checkset(int32_t argc, Janet *argv) {
uint32_t bitset[8] = {0, 0, 0, 0, 0, 0, 0, 0};
JANET_MINARITY(args, 2);
JANET_MAXARITY(args, 3);
JANET_ARG_BYTES(set, setlen, args, 0);
JANET_ARG_BYTES(str, strlen, args, 1);
janet_arity(argc, 2, 3);
JanetByteView set = janet_getbytes(argv, 0);
JanetByteView str = janet_getbytes(argv, 1);
/* Populate set */
for (i = 0; i < setlen; i++) {
int index = set[i] >> 5;
uint32_t mask = 1 << (set[i] & 7);
for (int32_t i = 0; i < set.len; i++) {
int index = set.bytes[i] >> 5;
uint32_t mask = 1 << (set.bytes[i] & 7);
bitset[index] |= mask;
}
if (args.n == 3) {
int invert;
JANET_ARG_BOOLEAN(invert, args, 2);
if (invert) {
for (i = 0; i < 8; i++)
if (argc == 3) {
if (janet_getboolean(argv, 2)) {
for (int i = 0; i < 8; i++)
bitset[i] = ~bitset[i];
}
}
/* Check set */
for (i = 0; i < strlen; i++) {
int index = str[i] >> 5;
uint32_t mask = 1 << (str[i] & 7);
for (int32_t i = 0; i < str.len; i++) {
int index = str.bytes[i] >> 5;
uint32_t mask = 1 << (str.bytes[i] & 7);
if (!(bitset[index] & mask)) {
JANET_RETURN_FALSE(args);
return janet_wrap_false();
}
}
JANET_RETURN_TRUE(args);
return janet_wrap_true();
}
static int cfun_join(JanetArgs args) {
const Janet *parts;
const uint8_t *joiner;
uint8_t *buf, *out;
int32_t joinerlen, partslen, finallen, i;
JANET_MINARITY(args, 1);
JANET_MAXARITY(args, 2);
JANET_ARG_INDEXED(parts, partslen, args, 0);
if (args.n == 2) {
JANET_ARG_BYTES(joiner, joinerlen, args, 1);
static Janet cfun_join(int32_t argc, Janet *argv) {
janet_arity(argc, 1, 2);
JanetView parts = janet_getindexed(argv, 0);
JanetByteView joiner;
if (argc == 2) {
joiner = janet_getbytes(argv, 1);
} else {
joiner = NULL;
joinerlen = 0;
joiner.bytes = NULL;
joiner.len = 0;
}
/* Check args */
finallen = 0;
for (i = 0; i < partslen; i++) {
int32_t i;
int64_t finallen = 0;
for (i = 0; i < parts.len; i++) {
const uint8_t *chunk;
int32_t chunklen = 0;
if (!janet_bytes_view(parts[i], &chunk, &chunklen)) {
JANET_THROW(args, "expected string|symbol|buffer");
if (!janet_bytes_view(parts.items[i], &chunk, &chunklen)) {
janet_panicf("item %d of parts is not a byte sequence, got %v", i, parts.items[i]);
}
if (i) finallen += joinerlen;
if (i) finallen += joiner.len;
finallen += chunklen;
if (finallen > INT32_MAX)
janet_panic("result string too long");
}
uint8_t *buf, *out;
out = buf = janet_string_begin(finallen);
for (i = 0; i < partslen; i++) {
for (i = 0; i < parts.len; i++) {
const uint8_t *chunk = NULL;
int32_t chunklen = 0;
if (i) {
memcpy(out, joiner, joinerlen);
out += joinerlen;
memcpy(out, joiner.bytes, joiner.len);
out += joiner.len;
}
janet_bytes_view(parts[i], &chunk, &chunklen);
janet_bytes_view(parts.items[i], &chunk, &chunklen);
memcpy(out, chunk, chunklen);
out += chunklen;
}
JANET_RETURN_STRING(args, janet_string_end(buf));
return janet_wrap_string(janet_string_end(buf));
}
static struct formatter {
@ -1188,29 +1112,29 @@ static struct formatter {
{"F", "%F", "%.*F"}
};
static int cfun_number(JanetArgs args) {
static Janet cfun_number(int32_t argc, Janet *argv) {
janet_arity(argc, 1, 4);
double x = janet_getnumber(argv, 0);
struct formatter fmter = formatters[0];
char buf[100];
double x;
int formatNargs = 1;
int32_t precision = 0;
JANET_MINARITY(args, 1);
JANET_MAXARITY(args, 4);
JANET_ARG_NUMBER(x, args, 0);
if (args.n >= 2) {
const uint8_t *flag;
JANET_ARG_KEYWORD(flag, args, 1);
for (int i = 0; i < 6; i++) {
if (argc >= 2) {
const uint8_t *flag = janet_getkeyword(argv, 1);
int i;
for (i = 0; i < 6; i++) {
struct formatter fmttest = formatters[i];
if (!janet_cstrcmp(flag, fmttest.lead)) {
fmter = fmttest;
break;
}
}
if (i == 6)
janet_panicf("unsupported formatter %v", argv[1]);
}
if (args.n >= 3) {
JANET_ARG_INTEGER(precision, args, 2);
if (argc >= 3) {
precision = janet_getinteger(argv, 2);
formatNargs++;
}
@ -1220,20 +1144,19 @@ static int cfun_number(JanetArgs args) {
snprintf(buf, sizeof(buf), fmter.f2, precision, x);
}
JANET_RETURN_CSTRING(args, buf);
return janet_cstringv(buf);
}
static int cfun_pretty(JanetArgs args) {
static Janet cfun_pretty(int32_t argc, Janet *argv) {
janet_arity(argc, 1, 3);
JanetBuffer *buffer = NULL;
int32_t depth = 4;
JANET_MINARITY(args, 1);
JANET_MAXARITY(args, 3);
if (args.n > 1)
JANET_ARG_INTEGER(depth, args, 1);
if (args.n > 2)
JANET_ARG_BUFFER(buffer, args, 2);
buffer = janet_pretty(buffer, depth, args.v[0]);
JANET_RETURN_BUFFER(args, buffer);
if (argc > 1)
depth = janet_getinteger(argv, 1);
if (argc > 2)
buffer = janet_getbuffer(argv, 2);
buffer = janet_pretty(buffer, depth, argv[0]);
return janet_wrap_buffer(buffer);
}
static const JanetReg cfuns[] = {
@ -1337,8 +1260,6 @@ static const JanetReg cfuns[] = {
};
/* Module entry point */
int janet_lib_string(JanetArgs args) {
JanetTable *env = janet_env(args);
void janet_lib_string(JanetTable *env) {
janet_cfuns(env, NULL, cfuns);
return 0;
}

View File

@ -163,8 +163,7 @@ const JanetKV *janet_table_next(JanetTable *t, const JanetKV *kv) {
JanetKV *end = t->data + t->capacity;
kv = (kv == NULL) ? t->data : kv + 1;
while (kv < end) {
if (!janet_checktype(kv->key, JANET_NIL))
return kv;
if (!janet_checktype(kv->key, JANET_NIL)) return kv;
kv++;
}
return NULL;
@ -206,49 +205,41 @@ void janet_table_merge_struct(JanetTable *table, const JanetKV *other) {
/* C Functions */
static int cfun_new(JanetArgs args) {
JanetTable *t;
int32_t cap;
JANET_FIXARITY(args, 1);
JANET_ARG_INTEGER(cap, args, 0);
t = janet_table(cap);
JANET_RETURN_TABLE(args, t);
static Janet cfun_new(int32_t argc, Janet *argv) {
janet_arity(argc, 1, 1);
int32_t cap = janet_getinteger(argv, 0);
return janet_wrap_table(janet_table(cap));
}
static int cfun_getproto(JanetArgs args) {
JanetTable *t;
JANET_FIXARITY(args, 1);
JANET_ARG_TABLE(t, args, 0);
JANET_RETURN(args, t->proto
? janet_wrap_table(t->proto)
: janet_wrap_nil());
static Janet cfun_getproto(int32_t argc, Janet *argv) {
janet_arity(argc, 1, 1);
JanetTable *t = janet_gettable(argv, 0);
return t->proto
? janet_wrap_table(t->proto)
: janet_wrap_nil();
}
static int cfun_setproto(JanetArgs args) {
JanetTable *table, *proto;
JANET_FIXARITY(args, 2);
JANET_ARG_TABLE(table, args, 0);
if (janet_checktype(args.v[1], JANET_NIL)) {
proto = NULL;
} else {
JANET_ARG_TABLE(proto, args, 1);
static Janet cfun_setproto(int32_t argc, Janet *argv) {
janet_arity(argc, 2, 2);
JanetTable *table = janet_gettable(argv, 0);
JanetTable *proto = NULL;
if (!janet_checktype(argv[1], JANET_NIL)) {
proto = janet_gettable(argv, 1);
}
table->proto = proto;
JANET_RETURN_TABLE(args, table);
return argv[0];
}
static int cfun_tostruct(JanetArgs args) {
JanetTable *t;
JANET_FIXARITY(args, 1);
JANET_ARG_TABLE(t, args, 0);
JANET_RETURN_STRUCT(args, janet_table_to_struct(t));
static Janet cfun_tostruct(int32_t argc, Janet *argv) {
janet_arity(argc, 1, 1);
JanetTable *t = janet_gettable(argv, 0);
return janet_wrap_struct(janet_table_to_struct(t));
}
static int cfun_rawget(JanetArgs args) {
JanetTable *table;
JANET_FIXARITY(args, 2);
JANET_ARG_TABLE(table, args, 0);
JANET_RETURN(args, janet_table_rawget(table, args.v[1]));
static Janet cfun_rawget(int32_t argc, Janet *argv) {
janet_arity(argc, 2, 2);
JanetTable *table = janet_gettable(argv, 0);
return janet_table_rawget(table, argv[1]);
}
static const JanetReg cfuns[] = {
@ -283,10 +274,6 @@ static const JanetReg cfuns[] = {
};
/* Load the table module */
int janet_lib_table(JanetArgs args) {
JanetTable *env = janet_env(args);
void janet_lib_table(JanetTable *env) {
janet_cfuns(env, NULL, cfuns);
return 0;
}
#undef janet_maphash

View File

@ -91,64 +91,30 @@ int janet_tuple_compare(const Janet *lhs, const Janet *rhs) {
/* C Functions */
static int cfun_slice(JanetArgs args) {
const Janet *vals;
int32_t len;
Janet *ret;
int32_t start, end;
JANET_MINARITY(args, 1);
if (!janet_indexed_view(args.v[0], &vals, &len)) JANET_THROW(args, "expected array/tuple");
/* Get start */
if (args.n < 2) {
start = 0;
} else {
JANET_ARG_INTEGER(start, args, 1);
}
/* Get end */
if (args.n < 3) {
end = -1;
} else {
JANET_ARG_INTEGER(end, args, 2);
}
if (start < 0) start = len + start;
if (end < 0) end = len + end + 1;
if (end < 0 || start < 0 || end > len || start > len)
JANET_THROW(args, "slice range out of bounds");
if (end >= start) {
ret = janet_tuple_begin(end - start);
memcpy(ret, vals + start, sizeof(Janet) * (end - start));
} else {
ret = janet_tuple_begin(0);
}
JANET_RETURN_TUPLE(args, janet_tuple_end(ret));
static Janet cfun_slice(int32_t argc, Janet *argv) {
JanetRange range = janet_getslice(argc, argv);
JanetView view = janet_getindexed(argv, 0);
return janet_wrap_tuple(janet_tuple_n(view.items + range.start, range.end - range.start));
}
static int cfun_prepend(JanetArgs args) {
const Janet *t;
int32_t len, i;
Janet *n;
JANET_MINARITY(args, 1);
if (!janet_indexed_view(args.v[0], &t, &len))
JANET_THROW(args, "expected tuple/array");
n = janet_tuple_begin(len - 1 + args.n);
memcpy(n - 1 + args.n, t, sizeof(Janet) * len);
for (i = 1; i < args.n; i++) {
n[args.n - i - 1] = args.v[i];
static Janet cfun_prepend(int32_t argc, Janet *argv) {
janet_arity(argc, 1, -1);
JanetView view = janet_getindexed(argv, 0);
Janet *n = janet_tuple_begin(view.len - 1 + argc);
memcpy(n - 1 + argc, view.items, sizeof(Janet) * view.len);
for (int32_t i = 1; i < argc; i++) {
n[argc - i - 1] = argv[i];
}
JANET_RETURN_TUPLE(args, janet_tuple_end(n));
return janet_wrap_tuple(janet_tuple_end(n));
}
static int cfun_append(JanetArgs args) {
const Janet *t;
int32_t len;
Janet *n;
JANET_MINARITY(args, 1);
if (!janet_indexed_view(args.v[0], &t, &len))
JANET_THROW(args, "expected tuple/array");
n = janet_tuple_begin(len - 1 + args.n);
memcpy(n, t, sizeof(Janet) * len);
memcpy(n + len, args.v + 1, sizeof(Janet) * (args.n - 1));
JANET_RETURN_TUPLE(args, janet_tuple_end(n));
static Janet cfun_append(int32_t argc, Janet *argv) {
janet_arity(argc, 1, -1);
JanetView view = janet_getindexed(argv, 0);
Janet *n = janet_tuple_begin(view.len - 1 + argc);
memcpy(n, view.items, sizeof(Janet) * view.len);
memcpy(n + view.len, argv + 1, sizeof(Janet) * (argc - 1));
return janet_wrap_tuple(janet_tuple_end(n));
}
static const JanetReg cfuns[] = {
@ -174,8 +140,6 @@ static const JanetReg cfuns[] = {
};
/* Load the tuple module */
int janet_lib_tuple(JanetArgs args) {
JanetTable *env = janet_env(args);
void janet_lib_tuple(JanetTable *env) {
janet_cfuns(env, NULL, cfuns);
return 0;
}

View File

@ -304,18 +304,6 @@ JanetBindingType janet_resolve(JanetTable *env, const uint8_t *sym, Janet *out)
return JANET_BINDING_DEF;
}
/* Get module from the arguments passed to library */
JanetTable *janet_env(JanetArgs args) {
JanetTable *module;
if (args.n >= 1 && janet_checktype(args.v[0], JANET_TABLE)) {
module = janet_unwrap_table(args.v[0]);
} else {
module = janet_table(0);
}
*args.ret = janet_wrap_table(module);
return module;
}
/* Read both tuples and arrays as c pointers + int32_t length. Return 1 if the
* view can be constructed, 0 if an invalid type. */
int janet_indexed_view(Janet seq, const Janet **data, int32_t *len) {
@ -365,67 +353,6 @@ int janet_dictionary_view(Janet tab, const JanetKV **data, int32_t *len, int32_t
return 0;
}
/* Get actual type name of a value for debugging purposes */
static const char *typestr(JanetArgs args, int32_t n) {
JanetType actual = n < args.n ? janet_type(args.v[n]) : JANET_NIL;
return ((actual == JANET_ABSTRACT)
? janet_abstract_type(janet_unwrap_abstract(args.v[n]))->name
: janet_type_names[actual]);
}
int janet_type_err(JanetArgs args, int32_t n, JanetType expected) {
const uint8_t *message = janet_formatc(
"bad slot #%d, expected %t, got %s",
n,
expected,
typestr(args, n));
JANET_THROWV(args, janet_wrap_string(message));
}
void janet_buffer_push_types(JanetBuffer *buffer, int types) {
int first = 1;
int i = 0;
while (types) {
if (1 & types) {
if (first) {
first = 0;
} else {
janet_buffer_push_u8(buffer, '|');
}
janet_buffer_push_cstring(buffer, janet_type_names[i]);
}
i++;
types >>= 1;
}
}
int janet_typemany_err(JanetArgs args, int32_t n, int expected) {
const uint8_t *message;
JanetBuffer buf;
janet_buffer_init(&buf, 20);
janet_buffer_push_string(&buf, janet_formatc("bad slot #%d, expected ", n));
janet_buffer_push_types(&buf, expected);
janet_buffer_push_cstring(&buf, ", got ");
janet_buffer_push_cstring(&buf, typestr(args, n));
message = janet_string(buf.data, buf.count);
janet_buffer_deinit(&buf);
JANET_THROWV(args, janet_wrap_string(message));
}
int janet_arity_err(JanetArgs args, int32_t n, const char *prefix) {
JANET_THROWV(args,
janet_wrap_string(janet_formatc(
"expected %s%d argument%s, got %d",
prefix, n, n == 1 ? "" : "s", args.n)));
}
int janet_typeabstract_err(JanetArgs args, int32_t n, const JanetAbstractType *at) {
JANET_THROWV(args,
janet_wrap_string(janet_formatc(
"bad slot #%d, expected %s, got %s",
n, at->name, typestr(args, n))));
}
int janet_checkint(Janet x) {
if (!janet_checktype(x, JANET_NUMBER))
return 0;

View File

@ -44,21 +44,21 @@ const void *janet_strbinsearch(
const uint8_t *key);
/* Initialize builtin libraries */
int janet_lib_io(JanetArgs args);
int janet_lib_math(JanetArgs args);
int janet_lib_array(JanetArgs args);
int janet_lib_tuple(JanetArgs args);
int janet_lib_buffer(JanetArgs args);
int janet_lib_table(JanetArgs args);
int janet_lib_fiber(JanetArgs args);
int janet_lib_os(JanetArgs args);
int janet_lib_string(JanetArgs args);
int janet_lib_marsh(JanetArgs args);
int janet_lib_parse(JanetArgs args);
void janet_lib_io(JanetTable *env);
void janet_lib_math(JanetTable *env);
void janet_lib_array(JanetTable *env);
void janet_lib_tuple(JanetTable *env);
void janet_lib_buffer(JanetTable *env);
void janet_lib_table(JanetTable *env);
void janet_lib_fiber(JanetTable *env);
void janet_lib_os(JanetTable *env);
void janet_lib_string(JanetTable *env);
void janet_lib_marsh(JanetTable *env);
void janet_lib_parse(JanetTable *env);
#ifdef JANET_ASSEMBLER
int janet_lib_asm(JanetArgs args);
void janet_lib_asm(JanetTable *env);
#endif
int janet_lib_compile(JanetArgs args);
int janet_lib_debug(JanetArgs args);
void janet_lib_compile(JanetTable *env);
void janet_lib_debug(JanetTable *env);
#endif

View File

@ -572,18 +572,14 @@ static JanetSignal run_vm(JanetFiber *fiber, Janet in) {
pc = func->def->bytecode;
vm_checkgc_next();
} else if (janet_checktype(callee, JANET_CFUNCTION)) {
JanetArgs args;
Janet retreg = janet_wrap_nil();
vm_commit();
args.n = fiber->stacktop - fiber->stackstart;
int32_t argc = fiber->stacktop - fiber->stackstart;
janet_fiber_cframe(fiber, janet_unwrap_cfunction(callee));
args.v = fiber->data + fiber->frame;
args.ret = &retreg;
if (janet_unwrap_cfunction(callee)(args)) janet_panicv(retreg);
Janet ret = janet_unwrap_cfunction(callee)(argc, fiber->data + fiber->frame);
janet_fiber_popframe(fiber);
if (fiber->frame == 0) vm_return(JANET_SIGNAL_OK, retreg);
if (fiber->frame == 0) vm_return(JANET_SIGNAL_OK, ret);
stack = fiber->data + fiber->frame;
stack[A] = retreg;
stack[A] = ret;
vm_checkgc_pcnext();
} else {
vm_commit();
@ -606,19 +602,14 @@ static JanetSignal run_vm(JanetFiber *fiber, Janet in) {
pc = func->def->bytecode;
vm_checkgc_next();
} else {
Janet retreg = janet_wrap_nil();
Janet retreg;
vm_commit();
if (janet_checktype(callee, JANET_CFUNCTION)) {
JanetArgs args;
vm_commit();
args.n = fiber->stacktop - fiber->stackstart;
int32_t argc = fiber->stacktop - fiber->stackstart;
janet_fiber_cframe(fiber, janet_unwrap_cfunction(callee));
args.v = fiber->data + fiber->frame;
args.ret = &retreg;
if (janet_unwrap_cfunction(callee)(args))
vm_return(JANET_SIGNAL_ERROR, retreg);
retreg = janet_unwrap_cfunction(callee)(argc, fiber->data + fiber->frame);
janet_fiber_popframe(fiber);
} else {
vm_commit();
retreg = call_nonfn(fiber, callee);
}
janet_fiber_popframe(fiber);
@ -653,22 +644,27 @@ static JanetSignal run_vm(JanetFiber *fiber, Janet in) {
}
VM_OP(JOP_PUT)
vm_commit();
janet_put(stack[A], stack[B], stack[C]);
vm_checkgc_pcnext();
VM_OP(JOP_PUT_INDEX)
vm_commit();
janet_putindex(stack[A], C, stack[B]);
vm_checkgc_pcnext();
VM_OP(JOP_GET)
vm_commit();
stack[A] = janet_get(stack[B], stack[C]);
vm_pcnext();
VM_OP(JOP_GET_INDEX)
vm_commit();
stack[A] = janet_getindex(stack[B], C);
vm_pcnext();
VM_OP(JOP_LENGTH)
vm_commit();
stack[A] = janet_wrap_integer(janet_length(stack[E]));
vm_pcnext();

View File

@ -268,10 +268,13 @@ typedef struct JanetFuncEnv JanetFuncEnv;
typedef struct JanetKV JanetKV;
typedef struct JanetStackFrame JanetStackFrame;
typedef struct JanetAbstractType JanetAbstractType;
typedef struct JanetArgs JanetArgs;
typedef struct JanetReg JanetReg;
typedef struct JanetSourceMapping JanetSourceMapping;
typedef int (*JanetCFunction)(JanetArgs args);
typedef struct JanetView JanetView;
typedef struct JanetByteView JanetByteView;
typedef struct JanetDictView JanetDictView;
typedef struct JanetRange JanetRange;
typedef Janet (*JanetCFunction)(int32_t argc, Janet *argv);
/* Basic types for all Janet Values */
typedef enum JanetType {
@ -573,13 +576,6 @@ JANET_API int janet_checkint64(Janet x);
#define janet_checktypes(x, tps) ((1 << janet_type(x)) & (tps))
/* Hold components of arguments passed to JanetCFunction. */
struct JanetArgs {
Janet *v;
Janet *ret;
int32_t n;
};
/* Fiber signal masks. */
#define JANET_FIBER_MASK_ERROR 2
#define JANET_FIBER_MASK_DEBUG 4
@ -760,6 +756,27 @@ struct JanetReg {
const char *documentation;
};
struct JanetView {
const Janet *items;
int32_t len;
};
struct JanetByteView {
const uint8_t *bytes;
int32_t len;
};
struct JanetDictView {
const JanetKV *kvs;
int32_t len;
int32_t cap;
};
struct JanetRange {
int32_t start;
int32_t end;
};
/***** END SECTION TYPES *****/
/***** START SECTION OPCODES *****/
@ -926,9 +943,9 @@ JANET_API int janet_dostring(JanetTable *env, const char *str, const char *sourc
JANET_API int janet_scan_number(const uint8_t *str, int32_t len, double *out);
/* Debugging */
JANET_API int janet_debug_break(JanetFuncDef *def, int32_t pc);
JANET_API int janet_debug_unbreak(JanetFuncDef *def, int32_t pc);
JANET_API int janet_debug_find(
JANET_API void janet_debug_break(JanetFuncDef *def, int32_t pc);
JANET_API void janet_debug_unbreak(JanetFuncDef *def, int32_t pc);
JANET_API void janet_debug_find(
JanetFuncDef **def_out, int32_t *pc_out,
const uint8_t *source, int32_t offset);
@ -949,14 +966,14 @@ JANET_API JanetBuffer *janet_buffer_init(JanetBuffer *buffer, int32_t capacity);
JANET_API void janet_buffer_deinit(JanetBuffer *buffer);
JANET_API void janet_buffer_ensure(JanetBuffer *buffer, int32_t capacity, int32_t growth);
JANET_API void janet_buffer_setcount(JanetBuffer *buffer, int32_t count);
JANET_API int janet_buffer_extra(JanetBuffer *buffer, int32_t n);
JANET_API int janet_buffer_push_bytes(JanetBuffer *buffer, const uint8_t *string, int32_t len);
JANET_API int janet_buffer_push_string(JanetBuffer *buffer, const uint8_t *string);
JANET_API int janet_buffer_push_cstring(JanetBuffer *buffer, const char *cstring);
JANET_API int janet_buffer_push_u8(JanetBuffer *buffer, uint8_t x);
JANET_API int janet_buffer_push_u16(JanetBuffer *buffer, uint16_t x);
JANET_API int janet_buffer_push_u32(JanetBuffer *buffer, uint32_t x);
JANET_API int janet_buffer_push_u64(JanetBuffer *buffer, uint64_t x);
JANET_API void janet_buffer_extra(JanetBuffer *buffer, int32_t n);
JANET_API void janet_buffer_push_bytes(JanetBuffer *buffer, const uint8_t *string, int32_t len);
JANET_API void janet_buffer_push_string(JanetBuffer *buffer, const uint8_t *string);
JANET_API void janet_buffer_push_cstring(JanetBuffer *buffer, const char *cstring);
JANET_API void janet_buffer_push_u8(JanetBuffer *buffer, uint8_t x);
JANET_API void janet_buffer_push_u16(JanetBuffer *buffer, uint16_t x);
JANET_API void janet_buffer_push_u32(JanetBuffer *buffer, uint32_t x);
JANET_API void janet_buffer_push_u64(JanetBuffer *buffer, uint64_t x);
/* Tuple */
#define janet_tuple_raw(t) ((int32_t *)(t) - 4)
@ -1054,7 +1071,8 @@ JANET_API const JanetKV *janet_dictionary_next(const JanetKV *kvs, int32_t cap,
JANET_API void *janet_abstract(const JanetAbstractType *type, size_t size);
/* Native */
JANET_API JanetCFunction janet_native(const char *name, const uint8_t **error);
typedef void (*JanetModule)(JanetTable *);
JANET_API JanetModule janet_native(const char *name, const uint8_t **error);
/* Marshaling */
JANET_API int janet_marshal(
@ -1119,160 +1137,44 @@ JANET_API void janet_def(JanetTable *env, const char *name, Janet val, const cha
JANET_API void janet_var(JanetTable *env, const char *name, Janet val, const char *documentation);
JANET_API void janet_cfuns(JanetTable *env, const char *regprefix, const JanetReg *cfuns);
JANET_API JanetBindingType janet_resolve(JanetTable *env, const uint8_t *sym, Janet *out);
JANET_API JanetTable *janet_env(JanetArgs args);
JANET_API void janet_register(const char *name, JanetCFunction cfun);
/* C Function helpers */
JANET_API int janet_arity_err(JanetArgs args, int32_t n, const char *prefix);
JANET_API int janet_type_err(JanetArgs args, int32_t n, JanetType expected);
JANET_API int janet_typemany_err(JanetArgs args, int32_t n, int expected);
JANET_API int janet_typeabstract_err(JanetArgs args, int32_t n, const JanetAbstractType *at);
/* New C API */
#define JANET_MODULE_ENTRY JANET_API void _janet_init
JANET_API void janet_panicv(Janet message);
JANET_API void janet_panic(const char *message);
JANET_API void janet_panics(const uint8_t *message);
#define janet_panicf(...) janet_panics(janet_formatc(__VA_ARGS__))
#define janet_printf(...) fputs((const char *)janet_formatc(__VA_ARGS__), stdout)
JANET_API void janet_panic_type(Janet x, int32_t n, int expected);
JANET_API void janet_panic_abstract(Janet x, int32_t n, const JanetAbstractType *at);
JANET_API void janet_arity(int32_t arity, int32_t min, int32_t max);
/* Helpers for writing modules */
#define JANET_MODULE_ENTRY JANET_API int _janet_init
JANET_API double janet_getnumber(const Janet *argv, int32_t n);
JANET_API JanetArray *janet_getarray(const Janet *argv, int32_t n);
JANET_API const Janet *janet_gettuple(const Janet *argv, int32_t n);
JANET_API JanetTable *janet_gettable(const Janet *argv, int32_t n);
JANET_API const JanetKV *janet_getstruct(const Janet *argv, int32_t n);
JANET_API const uint8_t *janet_getstring(const Janet *argv, int32_t n);
JANET_API const uint8_t *janet_getsymbol(const Janet *argv, int32_t n);
JANET_API const uint8_t *janet_getkeyword(const Janet *argv, int32_t n);
JANET_API JanetBuffer *janet_getbuffer(const Janet *argv, int32_t n);
JANET_API JanetFiber *janet_getfiber(const Janet *argv, int32_t n);
JANET_API JanetFunction *janet_getfunction(const Janet *argv, int32_t n);
JANET_API JanetCFunction janet_getcfunction(const Janet *argv, int32_t n);
JANET_API int janet_getboolean(const Janet *argv, int32_t n);
JANET_API int32_t janet_getinteger(const Janet *argv, int32_t n);
JANET_API int64_t janet_getinteger64(const Janet *argv, int32_t n);
JANET_API JanetView janet_getindexed(const Janet *argv, int32_t n);
JANET_API JanetByteView janet_getbytes(const Janet *argv, int32_t n);
JANET_API JanetDictView janet_getdictionary(const Janet *argv, int32_t n);
JANET_API void *janet_getabstract(const Janet *argv, int32_t n, const JanetAbstractType *at);
JANET_API JanetRange janet_getslice(int32_t argc, const Janet *argv);
/***** END SECTION MAIN *****/
/***** START SECTION MACROS *****/
/* Macros */
#define JANET_THROW(a, e) return (*((a).ret) = janet_cstringv(e), 1)
#define JANET_THROWV(a, v) return (*((a).ret) = (v), 1)
#define JANET_RETURN(a, v) return (*((a).ret) = (v), 0)
/* Early exit macros */
#define JANET_MAXARITY(A, N) do { if ((A).n > (N))\
return janet_arity_err(A, N, "at most "); } while (0)
#define JANET_MINARITY(A, N) do { if ((A).n < (N))\
return janet_arity_err(A, N, "at least "); } while (0)
#define JANET_FIXARITY(A, N) do { if ((A).n != (N))\
return janet_arity_err(A, N, ""); } while (0)
#define JANET_CHECK(A, N, T) do {\
if ((A).n > (N)) {\
if (!janet_checktype((A).v[(N)], (T))) return janet_type_err(A, N, T);\
} else {\
if ((T) != JANET_NIL) return janet_type_err(A, N, T);\
}\
} while (0)
#define JANET_CHECKMANY(A, N, TS) do {\
if ((A).n > (N)) {\
JanetType _t_ = janet_type((A).v[(N)]);\
if (!((1 << _t_) & (TS))) return janet_typemany_err(A, N, TS);\
} else {\
if (!((TS) & JANET_NIL)) return janet_typemany_err(A, N, TS);\
}\
} while (0)
#define JANET_CHECKABSTRACT(A, N, AT) do {\
if ((A).n > (N)) {\
Janet _x_ = (A).v[(N)];\
if (!janet_checktype(_x_, JANET_ABSTRACT) ||\
janet_abstract_type(janet_unwrap_abstract(_x_)) != (AT))\
return janet_typeabstract_err(A, N, AT);\
} else {\
return janet_typeabstract_err(A, N, AT);\
}\
} while (0)
#define JANET_ARG_BOOLEAN(DEST, A, N) do { \
JANET_CHECKMANY(A, N, JANET_TFLAG_TRUE | JANET_TFLAG_FALSE);\
DEST = janet_unwrap_boolean((A).v[(N)]); \
} while (0)
#define JANET_ARG_BYTES(DESTBYTES, DESTLEN, A, N) do {\
if ((A).n <= (N)) return janet_typemany_err(A, N, JANET_TFLAG_BYTES);\
if (!janet_bytes_view((A).v[(N)], &(DESTBYTES), &(DESTLEN))) {\
return janet_typemany_err(A, N, JANET_TFLAG_BYTES);\
}\
} while (0)
#define JANET_ARG_INDEXED(DESTVALS, DESTLEN, A, N) do {\
if ((A).n <= (N)) return janet_typemany_err(A, N, JANET_TFLAG_INDEXED);\
if (!janet_indexed_view((A).v[(N)], &(DESTVALS), &(DESTLEN))) {\
return janet_typemany_err(A, N, JANET_TFLAG_INDEXED);\
}\
} while (0)
#define _JANET_ARG(TYPE, NAME, DEST, A, N) do { \
JANET_CHECK(A, N, TYPE);\
DEST = janet_unwrap_##NAME((A).v[(N)]); \
} while (0)
#define JANET_ARG_FIBER(DEST, A, N) _JANET_ARG(JANET_FIBER, fiber, DEST, A, N)
#define JANET_ARG_NUMBER(DEST, A, N) _JANET_ARG(JANET_NUMBER, number, DEST, A, N)
#define JANET_ARG_STRING(DEST, A, N) _JANET_ARG(JANET_STRING, string, DEST, A, N)
#define JANET_ARG_SYMBOL(DEST, A, N) _JANET_ARG(JANET_SYMBOL, symbol, DEST, A, N)
#define JANET_ARG_KEYWORD(DEST, A, N) _JANET_ARG(JANET_KEYWORD, keyword, DEST, A, N)
#define JANET_ARG_ARRAY(DEST, A, N) _JANET_ARG(JANET_ARRAY, array, DEST, A, N)
#define JANET_ARG_TUPLE(DEST, A, N) _JANET_ARG(JANET_TUPLE, tuple, DEST, A, N)
#define JANET_ARG_TABLE(DEST, A, N) _JANET_ARG(JANET_TABLE, table, DEST, A, N)
#define JANET_ARG_STRUCT(DEST, A, N) _JANET_ARG(JANET_STRUCT, struct, DEST, A, N)
#define JANET_ARG_BUFFER(DEST, A, N) _JANET_ARG(JANET_BUFFER, buffer, DEST, A, N)
#define JANET_ARG_FUNCTION(DEST, A, N) _JANET_ARG(JANET_FUNCTION, function, DEST, A, N)
#define JANET_ARG_CFUNCTION(DEST, A, N) _JANET_ARG(JANET_CFUNCTION, cfunction, DEST, A, N)
#define JANET_ARG_INTEGER(DEST, A, N) do { \
if ((A).n <= (N) || !janet_checktype((A).v[(N)], JANET_NUMBER)) { \
JANET_THROW(A, "expected integer"); \
} \
double _x_ = janet_unwrap_number((A).v[(N)]); \
if (janet_checkintrange(_x_)) { \
DEST = (int32_t) _x_; \
} else { \
JANET_THROW(A, "expected integer representable by 32 bits"); \
} \
} while (0)
#define JANET_ARG_INTEGER64(DEST, A, N) do { \
if ((A).n <= (N) || !janet_checktype((A).v[(N)], JANET_NUMBER)) { \
JANET_THROW(A, "expected integer"); \
} \
double _x_ = janet_unwrap_number((A).v[(N)]); \
if (janet_checkintrange64(_x_)) { \
DEST = (int64_t) _x_; \
} else { \
JANET_THROW(A, "expected integer representable by 64 bits"); \
} \
} while (0)
#define JANET_ARG_ABSTRACT(DEST, A, N, AT) do { \
JANET_CHECKABSTRACT(A, N, AT); \
DEST = janet_unwrap_abstract((A).v[(N)]); \
} while (0)
#define JANET_RETURN_NIL(A) do { return JANET_SIGNAL_OK; } while (0)
#define JANET_RETURN_FALSE(A) JANET_RETURN(A, janet_wrap_false())
#define JANET_RETURN_TRUE(A) JANET_RETURN(A, janet_wrap_true())
#define JANET_RETURN_BOOLEAN(A, X) JANET_RETURN(A, janet_wrap_boolean(X))
#define JANET_RETURN_FIBER(A, X) JANET_RETURN(A, janet_wrap_fiber(X))
#define JANET_RETURN_NUMBER(A, X) JANET_RETURN(A, janet_wrap_number(X))
#define JANET_RETURN_STRING(A, X) JANET_RETURN(A, janet_wrap_string(X))
#define JANET_RETURN_SYMBOL(A, X) JANET_RETURN(A, janet_wrap_symbol(X))
#define JANET_RETURN_KEYWORD(A, X) JANET_RETURN(A, janet_wrap_keyword(X))
#define JANET_RETURN_ARRAY(A, X) JANET_RETURN(A, janet_wrap_array(X))
#define JANET_RETURN_TUPLE(A, X) JANET_RETURN(A, janet_wrap_tuple(X))
#define JANET_RETURN_TABLE(A, X) JANET_RETURN(A, janet_wrap_table(X))
#define JANET_RETURN_STRUCT(A, X) JANET_RETURN(A, janet_wrap_struct(X))
#define JANET_RETURN_BUFFER(A, X) JANET_RETURN(A, janet_wrap_buffer(X))
#define JANET_RETURN_FUNCTION(A, X) JANET_RETURN(A, janet_wrap_function(X))
#define JANET_RETURN_CFUNCTION(A, X) JANET_RETURN(A, janet_wrap_cfunction(X))
#define JANET_RETURN_ABSTRACT(A, X) JANET_RETURN(A, janet_wrap_abstract(X))
#define JANET_RETURN_CSTRING(A, X) JANET_RETURN(A, janet_cstringv(X))
#define JANET_RETURN_CSYMBOL(A, X) JANET_RETURN(A, janet_csymbolv(X))
#define JANET_RETURN_CKEYWORD(A, X) JANET_RETURN(A, janet_ckeywordv(X))
#define JANET_RETURN_INTEGER(A, X) JANET_RETURN(A, janet_wrap_number((double) (X)))
/**** END SECTION MACROS *****/
#ifdef __cplusplus
}
#endif

View File

@ -23,14 +23,12 @@
#include "line.h"
/* Common */
int janet_line_getter(JanetArgs args) {
JANET_FIXARITY(args, 2);
JANET_CHECK(args, 0, JANET_STRING);
JANET_CHECK(args, 1, JANET_BUFFER);
janet_line_get(
janet_unwrap_string(args.v[0]),
janet_unwrap_buffer(args.v[1]));
JANET_RETURN(args, args.v[0]);
Janet janet_line_getter(int32_t argc, Janet *argv) {
janet_arity(argc, 2, 2);
const uint8_t *str = janet_getstring(argv, 0);
JanetBuffer *buf = janet_getbuffer(argv, 1);
janet_line_get(str, buf);
return argv[0];
}
static void simpleline(JanetBuffer *buffer) {

View File

@ -29,6 +29,6 @@ void janet_line_init();
void janet_line_deinit();
void janet_line_get(const uint8_t *p, JanetBuffer *buffer);
int janet_line_getter(JanetArgs args);
Janet janet_line_getter(int32_t argc, Janet *argv);
#endif