mirror of
https://github.com/janet-lang/janet
synced 2025-01-12 16:40:27 +00:00
More work on improving errors.
This commit is contained in:
parent
96897a0d7a
commit
53f9c18669
2
Makefile
2
Makefile
@ -29,7 +29,7 @@ BINDIR=$(PREFIX)/bin
|
||||
# TODO - when api is finalized, only export public symbols instead of using rdynamic
|
||||
# which exports all symbols.
|
||||
|
||||
CFLAGS=-std=c99 -Wall -Wextra -Isrc/include -rdynamic -s -O3
|
||||
CFLAGS=-std=c99 -Wall -Wextra -Isrc/include -rdynamic -s -O2
|
||||
CLIBS=-lm -ldl
|
||||
PREFIX=/usr/local
|
||||
DST_TARGET=dst
|
||||
|
@ -23,7 +23,7 @@
|
||||
#include <dst/dst.h>
|
||||
#include "gc.h"
|
||||
|
||||
/* Iniializes an array */
|
||||
/* Initializes an array */
|
||||
DstArray *dst_array_init(DstArray *array, int32_t capacity) {
|
||||
Dst *data = NULL;
|
||||
if (capacity > 0) {
|
||||
@ -67,7 +67,7 @@ void dst_array_setcount(DstArray *array, int32_t count) {
|
||||
return;
|
||||
if (count > array->count) {
|
||||
int32_t i;
|
||||
dst_array_ensure(array, count + 1);
|
||||
dst_array_ensure(array, count);
|
||||
for (i = array->count; i < count; i++) {
|
||||
array->data[i] = dst_wrap_nil();
|
||||
}
|
||||
|
@ -62,6 +62,18 @@ void dst_buffer_ensure(DstBuffer *buffer, int32_t capacity) {
|
||||
buffer->capacity = capacity;
|
||||
}
|
||||
|
||||
/* Ensure that the buffer has enough internal capacity */
|
||||
void dst_buffer_setcount(DstBuffer *buffer, int32_t count) {
|
||||
if (count < 0)
|
||||
return;
|
||||
if (count > buffer->count) {
|
||||
int32_t oldcount = buffer->count;
|
||||
dst_buffer_ensure(buffer, count);
|
||||
memset(buffer->data + oldcount, 0, count - oldcount);
|
||||
}
|
||||
buffer->count = 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 dst_buffer_extra(DstBuffer *buffer, int32_t n) {
|
||||
@ -148,11 +160,13 @@ int dst_buffer_push_u64(DstBuffer *buffer, uint64_t x) {
|
||||
static int cfun_u8(DstArgs args) {
|
||||
int32_t i;
|
||||
DstBuffer *buffer;
|
||||
if (args.n < 1 || !dst_checktype(args.v[0], DST_BUFFER)) return dst_throw(args, "expected buffer");
|
||||
buffer = dst_unwrap_buffer(args.v[0]);
|
||||
dst_minarity(args, 1);
|
||||
dst_arg_buffer(buffer, args, 0);
|
||||
for (i = 1; i < args.n; i++) {
|
||||
if (!dst_checktype(args.v[i], DST_INTEGER)) return dst_throw(args, "expected integer");
|
||||
if (dst_buffer_push_u8(buffer, (uint8_t) (dst_unwrap_integer(args.v[i]) & 0xFF))) return dst_throw(args, "buffer overflow");
|
||||
int32_t integer;
|
||||
dst_arg_integer(integer, args, i);
|
||||
if (dst_buffer_push_u8(buffer, (uint8_t) (integer & 0xFF)))
|
||||
return dst_throw(args, "buffer overflow");
|
||||
}
|
||||
return dst_return(args, args.v[0]);
|
||||
}
|
||||
@ -160,11 +174,13 @@ static int cfun_u8(DstArgs args) {
|
||||
static int cfun_int(DstArgs args) {
|
||||
int32_t i;
|
||||
DstBuffer *buffer;
|
||||
if (args.n < 1 || !dst_checktype(args.v[0], DST_BUFFER)) return dst_throw(args, "expected buffer");
|
||||
buffer = dst_unwrap_buffer(args.v[0]);
|
||||
dst_minarity(args, 1);
|
||||
dst_arg_buffer(buffer, args, 0);
|
||||
for (i = 1; i < args.n; i++) {
|
||||
if (!dst_checktype(args.v[i], DST_INTEGER)) return dst_throw(args, "expected integer");
|
||||
if (dst_buffer_push_u32(buffer, (uint32_t) dst_unwrap_integer(args.v[i]))) return dst_throw(args, "buffer overflow");
|
||||
int32_t integer;
|
||||
dst_arg_integer(integer, args, i);
|
||||
if (dst_buffer_push_u32(buffer, (uint32_t) integer))
|
||||
return dst_throw(args, "buffer overflow");
|
||||
}
|
||||
return dst_return(args, args.v[0]);
|
||||
}
|
||||
@ -172,38 +188,37 @@ static int cfun_int(DstArgs args) {
|
||||
static int cfun_chars(DstArgs args) {
|
||||
int32_t i;
|
||||
DstBuffer *buffer;
|
||||
if (args.n < 1 || !dst_checktype(args.v[0], DST_BUFFER)) return dst_throw(args, "expected buffer");
|
||||
buffer = dst_unwrap_buffer(args.v[0]);
|
||||
dst_minarity(args, 1);
|
||||
dst_arg_buffer(buffer, args, 0);
|
||||
for (i = 1; i < args.n; i++) {
|
||||
int32_t len;
|
||||
const uint8_t *str;
|
||||
if (!dst_chararray_view(args.v[i], &str, &len)) return dst_throw(args, "expected string/buffer");
|
||||
if (dst_buffer_push_bytes(buffer, str, len)) return dst_throw(args, "buffer overflow");
|
||||
if (!dst_chararray_view(args.v[i], &str, &len))
|
||||
return dst_throw(args, "expected string|symbol|buffer");
|
||||
if (dst_buffer_push_bytes(buffer, str, len))
|
||||
return dst_throw(args, "buffer overflow");
|
||||
}
|
||||
return dst_return(args, args.v[0]);
|
||||
}
|
||||
|
||||
static int cfun_clear(DstArgs args) {
|
||||
DstBuffer *buffer;
|
||||
if (args.n < 1 || !dst_checktype(args.v[0], DST_BUFFER)) return dst_throw(args, "expected buffer");
|
||||
buffer = dst_unwrap_buffer(args.v[0]);
|
||||
dst_fixarity(args, 1);
|
||||
dst_arg_buffer(buffer, args, 0);
|
||||
buffer->count = 0;
|
||||
return dst_return(args, args.v[0]);
|
||||
}
|
||||
|
||||
static int cfun_popn(DstArgs args) {
|
||||
DstBuffer *buffer;
|
||||
int32_t i;
|
||||
if (args.n < 2
|
||||
|| !dst_checktype(args.v[0], DST_BUFFER)
|
||||
|| !dst_checktype(args.v[1], DST_INTEGER)) return dst_throw(args, "expected buffer and integer");
|
||||
buffer = dst_unwrap_buffer(args.v[0]);
|
||||
i = dst_unwrap_integer(args.v[1]);
|
||||
if (i < 0) return dst_throw(args, "expected positive integer");
|
||||
if (buffer->count < i) {
|
||||
int32_t n;
|
||||
dst_fixarity(args, 2);
|
||||
dst_arg_buffer(buffer, args, 0);
|
||||
dst_arg_integer(n, args, 1);
|
||||
if (buffer->count < n) {
|
||||
buffer->count = 0;
|
||||
} else {
|
||||
buffer->count -= i;
|
||||
buffer->count -= n;
|
||||
}
|
||||
return dst_return(args, args.v[0]);
|
||||
}
|
||||
|
@ -259,17 +259,16 @@ void dst_fiber_popframe(DstFiber *fiber) {
|
||||
|
||||
static int cfun_fiber(DstArgs args) {
|
||||
DstFiber *fiber;
|
||||
if (args.n < 1) return dst_throw(args, "expected at least 1 argument");
|
||||
if (!dst_checktype(args.v[0], DST_FUNCTION))
|
||||
return dst_throw(args, "expected a function");
|
||||
dst_fixarity(args, 1);
|
||||
dst_check(args, 0, DST_FUNCTION);
|
||||
fiber = dst_fiber(dst_unwrap_function(args.v[0]), 64);
|
||||
return dst_return(args, dst_wrap_fiber(fiber));
|
||||
}
|
||||
|
||||
static int cfun_status(DstArgs args) {
|
||||
const char *status = "";
|
||||
if (args.n != 1) return dst_throw(args, "expected 1 argument");
|
||||
if (!dst_checktype(args.v[0], DST_FIBER)) return dst_throw(args, "expected fiber");
|
||||
dst_fixarity(args, 1);
|
||||
dst_check(args, 0, DST_FIBER);
|
||||
switch(dst_unwrap_fiber(args.v[0])->status) {
|
||||
case DST_FIBER_PENDING:
|
||||
status = ":pending";
|
||||
@ -330,8 +329,8 @@ static Dst doframe(DstStackFrame *frame) {
|
||||
static int cfun_stack(DstArgs args) {
|
||||
DstFiber *fiber;
|
||||
DstArray *array;
|
||||
if (args.n != 1) return dst_throw(args, "expected 1 argument");
|
||||
if (!dst_checktype(args.v[0], DST_FIBER)) return dst_throw(args, "expected fiber");
|
||||
dst_fixarity(args, 1);
|
||||
dst_check(args, 0, DST_FIBER);
|
||||
fiber = dst_unwrap_fiber(args.v[0]);
|
||||
array = dst_array(0);
|
||||
{
|
||||
|
@ -84,16 +84,16 @@ static int checkflags(const uint8_t *str, int32_t len) {
|
||||
static IOFile *checkfile(DstArgs args, int32_t n) {
|
||||
IOFile *iof;
|
||||
if (n >= args.n) {
|
||||
*args.ret = dst_cstringv("expected core.file");
|
||||
*args.ret = dst_cstringv("expected core.file");
|
||||
return NULL;
|
||||
}
|
||||
if (!dst_checktype(args.v[n], DST_ABSTRACT)) {
|
||||
*args.ret = dst_cstringv("expected core.file");
|
||||
*args.ret = dst_cstringv("expected core.file");
|
||||
return NULL;
|
||||
}
|
||||
iof = (IOFile *) dst_unwrap_abstract(args.v[n]);
|
||||
if (dst_abstract_type(iof) != &dst_io_filetype) {
|
||||
*args.ret = dst_cstringv("expected core.file");
|
||||
*args.ret = dst_cstringv("expected core.file");
|
||||
return NULL;
|
||||
}
|
||||
return iof;
|
||||
@ -105,11 +105,11 @@ static DstBuffer *checkbuffer(DstArgs args, int32_t n, int optional) {
|
||||
return dst_buffer(0);
|
||||
}
|
||||
if (n >= args.n) {
|
||||
*args.ret = dst_cstringv("expected buffer");
|
||||
*args.ret = dst_cstringv("expected buffer");
|
||||
return NULL;
|
||||
}
|
||||
if (!dst_checktype(args.v[n], DST_BUFFER)) {
|
||||
*args.ret = dst_cstringv("expected buffer");
|
||||
*args.ret = dst_cstringv("expected buffer");
|
||||
return NULL;
|
||||
}
|
||||
return dst_unwrap_abstract(args.v[n]);
|
||||
@ -141,8 +141,9 @@ static int dst_io_fopen(DstArgs args) {
|
||||
int32_t modelen;
|
||||
FILE *f;
|
||||
int flags;
|
||||
if (args.n < 1 || args.n > 2) return dst_throw(args, "expected 1 or 2 arguments");
|
||||
if (!dst_checktype(args.v[0], DST_STRING)) return dst_throw(args, "expected string filename");
|
||||
dst_minarity(args, 1);
|
||||
dst_maxarity(args, 2);
|
||||
dst_check(args, 0, DST_STRING);
|
||||
fname = dst_unwrap_string(args.v[0]);
|
||||
if (args.n == 2) {
|
||||
if (!dst_checktype(args.v[1], DST_STRING) &&
|
||||
|
@ -206,13 +206,20 @@ int dst_hashtable_view(Dst tab, const DstKV **data, int32_t *len, int32_t *cap)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dst_type_err(DstArgs args, int32_t n, DstType expected) {
|
||||
/* Get actual type name of a value for debugging purposes */
|
||||
static const char *typestr(DstArgs args, int32_t n) {
|
||||
DstType actual = n < args.n ? dst_type(args.v[n]) : DST_NIL;
|
||||
return (actual == DST_ABSTRACT)
|
||||
? dst_abstract_type(dst_unwrap_abstract(args.v[n]))->name
|
||||
: dst_type_names[actual];
|
||||
}
|
||||
|
||||
int dst_type_err(DstArgs args, int32_t n, DstType expected) {
|
||||
const uint8_t *message = dst_formatc(
|
||||
"bad argument #%d, expected %t, got %t",
|
||||
"bad argument #%d, expected %t, got %s",
|
||||
n,
|
||||
expected,
|
||||
actual);
|
||||
typestr(args, n));
|
||||
return dst_throwv(args, dst_wrap_string(message));
|
||||
}
|
||||
|
||||
@ -220,7 +227,6 @@ int dst_typemany_err(DstArgs args, int32_t n, int expected) {
|
||||
int i;
|
||||
int first = 1;
|
||||
const uint8_t *message;
|
||||
DstType actual = n < args.n ? dst_type(args.v[n]) : DST_NIL;
|
||||
DstBuffer buf;
|
||||
dst_buffer_init(&buf, 20);
|
||||
dst_buffer_push_string(&buf, dst_formatc("bad argument #%d, expected ", n));
|
||||
@ -238,7 +244,7 @@ int dst_typemany_err(DstArgs args, int32_t n, int expected) {
|
||||
expected >>= 1;
|
||||
}
|
||||
dst_buffer_push_cstring(&buf, ", got ");
|
||||
dst_buffer_push_cstring(&buf, dst_type_names[actual] + 1);
|
||||
dst_buffer_push_cstring(&buf, typestr(args, n));
|
||||
message = dst_string(buf.data, buf.count);
|
||||
dst_buffer_deinit(&buf);
|
||||
return dst_throwv(args, dst_wrap_string(message));
|
||||
@ -250,3 +256,10 @@ int dst_arity_err(DstArgs args, int32_t n, const char *prefix) {
|
||||
"expected %s%d argument%s, got %d",
|
||||
prefix, n, n == 1 ? "" : "s", args.n)));
|
||||
}
|
||||
|
||||
int dst_typeabstract_err(DstArgs args, int32_t n, DstAbstractType *at) {
|
||||
return dst_throwv(args,
|
||||
dst_wrap_string(dst_formatc(
|
||||
"bad argument #%d, expected %t, got %s",
|
||||
n, at->name, typestr(args, n))));
|
||||
}
|
||||
|
@ -151,10 +151,8 @@ int dst_compare(Dst x, Dst y) {
|
||||
return dst_unwrap_string(x) > dst_unwrap_string(y) ? 1 : -1;
|
||||
}
|
||||
}
|
||||
} else if (dst_type(x) < dst_type(y)) {
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return (dst_type(x) < dst_type(y)) ? -1 : 1;
|
||||
}
|
||||
|
||||
/* Get a value out af an associated data structure. For invalid
|
||||
@ -200,19 +198,36 @@ Dst dst_get(Dst ds, Dst key) {
|
||||
* error message, and NULL if no error. */
|
||||
void dst_put(Dst ds, Dst key, Dst value) {
|
||||
switch (dst_type(ds)) {
|
||||
case DST_ARRAY:
|
||||
if (dst_checktype(key, DST_INTEGER) &&
|
||||
dst_unwrap_integer(key) >= 0 &&
|
||||
dst_unwrap_integer(key) < dst_unwrap_array(ds)->count)
|
||||
dst_unwrap_array(ds)->data[dst_unwrap_integer(key)] = value;
|
||||
case DST_ARRAY:
|
||||
{
|
||||
int32_t index;
|
||||
DstArray *array = dst_unwrap_array(ds);
|
||||
if (!dst_checktype(key, DST_INTEGER) || dst_unwrap_integer(key) < 0)
|
||||
return;
|
||||
index = dst_unwrap_integer(key);
|
||||
if (index == INT32_MAX) return;
|
||||
if (index >= array->count) {
|
||||
dst_array_setcount(array, index + 1);
|
||||
}
|
||||
array->data[index]= value;
|
||||
return;
|
||||
}
|
||||
case DST_BUFFER:
|
||||
if (dst_checktype(key, DST_INTEGER) &&
|
||||
dst_checktype(value, DST_INTEGER) &&
|
||||
dst_unwrap_integer(key) >= 0 &&
|
||||
dst_unwrap_integer(key) < dst_unwrap_buffer(ds)->count)
|
||||
dst_unwrap_buffer(ds)->data[dst_unwrap_integer(key)] = dst_unwrap_integer(value);
|
||||
{
|
||||
int32_t index;
|
||||
DstBuffer *buffer = dst_unwrap_buffer(ds);
|
||||
if (!dst_checktype(key, DST_INTEGER) || dst_unwrap_integer(key) < 0)
|
||||
return;
|
||||
index = dst_unwrap_integer(key);
|
||||
if (index == INT32_MAX) return;
|
||||
if (!dst_checktype(value, DST_INTEGER))
|
||||
return;
|
||||
if (index >= buffer->count) {
|
||||
dst_buffer_setcount(buffer, index + 1);
|
||||
}
|
||||
buffer->data[index] = (uint8_t) (dst_unwrap_integer(value) & 0xFF);
|
||||
return;
|
||||
}
|
||||
case DST_TABLE:
|
||||
dst_table_put(dst_unwrap_table(ds), key, value);
|
||||
return;
|
||||
|
@ -1,240 +0,0 @@
|
||||
{
|
||||
dst_array;
|
||||
dst_array_init;
|
||||
dst_array_deinit;
|
||||
dst_array_ensure;
|
||||
dst_array_setcount;
|
||||
dst_array_push;
|
||||
dst_array_pop;
|
||||
dst_array_peek;
|
||||
|
||||
dst_buffer;
|
||||
dst_buffer_init;
|
||||
dst_buffer_deinit;
|
||||
dst_buffer_ensure;
|
||||
dst_buffer_extra;
|
||||
dst_buffer_push_bytes;
|
||||
dst_buffer_push_cstring;
|
||||
dst_buffer_push_u8;
|
||||
dst_buffer_push_u16;
|
||||
dst_buffer_push_u32;
|
||||
dst_buffer_push_u64;
|
||||
|
||||
dst_tuple_begin;
|
||||
dst_tuple_end;
|
||||
dst_tuple_n;
|
||||
dst_tuple_equal;
|
||||
dst_tuple_compare;
|
||||
|
||||
dst_string_begin;
|
||||
dst_string_end;
|
||||
dst_string;
|
||||
dst_cstring;
|
||||
dst_string_compare;
|
||||
dst_string_equal;
|
||||
dst_string_equalconst;
|
||||
dst_string_unique;
|
||||
dst_cstring_unique;
|
||||
dst_description;
|
||||
dst_to_string;
|
||||
dst_to_zerostring;
|
||||
dst_formatc;
|
||||
dst_puts;
|
||||
|
||||
dst_symbol;
|
||||
dst_symbol_from_string;
|
||||
dst_csymbol;
|
||||
dst_symbol_gen;
|
||||
|
||||
dst_struct_begin;
|
||||
dst_struct_put;
|
||||
dst_struct_end;
|
||||
dst_struct_get;
|
||||
dst_struct_next;
|
||||
dst_struct_to_table;
|
||||
dst_struct_equal;
|
||||
dst_struct_compare;
|
||||
dst_struct_find;
|
||||
|
||||
dst_table;
|
||||
dst_table_init;
|
||||
dst_table_deinit;
|
||||
dst_table_get;
|
||||
dst_table_rawget;
|
||||
dst_table_remove;
|
||||
dst_table_put;
|
||||
dst_table_next;
|
||||
dst_table_to_struct;
|
||||
dst_table_merge_table;
|
||||
dst_table_merge_struct;
|
||||
dst_table_find;
|
||||
|
||||
dst_fiber;
|
||||
|
||||
dst_seq_view;
|
||||
dst_chararray_view;
|
||||
dst_hashtable_view;
|
||||
|
||||
dst_abstract;
|
||||
|
||||
dst_native;
|
||||
|
||||
dst_mark;
|
||||
dst_sweep;
|
||||
dst_collect;
|
||||
dst_clear_memory;
|
||||
dst_gcroot;
|
||||
dst_gcunroot;
|
||||
dst_gcunrootall;
|
||||
dst_gclock;
|
||||
dst_gcunlock;
|
||||
|
||||
dst_funcdef_alloc;
|
||||
dst_thunk;
|
||||
dst_verify;
|
||||
dst_quick_asm;
|
||||
|
||||
dst_equals;
|
||||
dst_hash;
|
||||
dst_compare;
|
||||
dst_get;
|
||||
dst_put;
|
||||
dst_next;
|
||||
dst_length;
|
||||
dst_getindex;
|
||||
dst_setindex;
|
||||
dst_cstrcmp;
|
||||
|
||||
dst_init;
|
||||
dst_deinit;
|
||||
dst_run;
|
||||
dst_resume;
|
||||
|
||||
dst_env_def;
|
||||
dst_env_var;
|
||||
dst_env_cfuns;
|
||||
dst_env_resolve;
|
||||
dst_env_arg;
|
||||
|
||||
dst_stl_env;
|
||||
|
||||
dst_asm;
|
||||
dst_disasm;
|
||||
dst_asm_decode_instruction;
|
||||
dst_asm_cfun;
|
||||
dst_disasm_cfun;
|
||||
|
||||
dst_lib_asm;
|
||||
|
||||
dst_compile;
|
||||
|
||||
dst_compile_cfun;
|
||||
dst_lib_compile;
|
||||
|
||||
dst_stl_env;
|
||||
|
||||
dst_dobytes;
|
||||
dst_dostring;
|
||||
|
||||
dst_core_native;
|
||||
|
||||
dst_int;
|
||||
dst_real;
|
||||
dst_add;
|
||||
dst_subtract;
|
||||
dst_multiply;
|
||||
dst_divide;
|
||||
dst_modulo;
|
||||
dst_rand;
|
||||
dst_srand;
|
||||
dst_strict_equal;
|
||||
dst_strict_notequal;
|
||||
dst_ascending;
|
||||
dst_descending;
|
||||
dst_notdescending;
|
||||
dst_notascending;
|
||||
dst_numeric_eq;
|
||||
dst_numeric_neq;
|
||||
dst_numeric_gt;
|
||||
dst_numeric_lt;
|
||||
dst_numeric_gte;
|
||||
dst_numeric_lte;
|
||||
dst_bor;
|
||||
dst_band;
|
||||
dst_bxor;
|
||||
dst_bnot;
|
||||
dst_lshift;
|
||||
dst_rshift;
|
||||
dst_lshiftu;
|
||||
dst_not;
|
||||
|
||||
dst_cos;
|
||||
dst_sin;
|
||||
dst_tan;
|
||||
dst_acos;
|
||||
dst_asin;
|
||||
dst_atan;
|
||||
dst_exp;
|
||||
dst_log;
|
||||
dst_log10;
|
||||
dst_sqrt;
|
||||
dst_floor;
|
||||
dst_ceil;
|
||||
dst_pow;
|
||||
|
||||
dst_core_print;
|
||||
dst_core_describe;
|
||||
dst_core_string;
|
||||
dst_core_symbol;
|
||||
dst_core_buffer;
|
||||
dst_core_tuple;
|
||||
dst_core_array;
|
||||
dst_core_table;
|
||||
dst_core_struct;
|
||||
dst_core_buffer;
|
||||
dst_core_gensym;
|
||||
dst_core_length;
|
||||
dst_core_get;
|
||||
dst_core_rawget;
|
||||
dst_core_getproto;
|
||||
dst_core_setproto;
|
||||
dst_core_put;
|
||||
dst_core_type;
|
||||
dst_core_next;
|
||||
dst_core_hash;
|
||||
dst_core_string_slice;
|
||||
|
||||
dst_core_gccollect;
|
||||
dst_core_gcsetinterval;
|
||||
dst_core_gcinterval;
|
||||
|
||||
dst_lib_io;
|
||||
dst_lib_math;
|
||||
dst_lib_array;
|
||||
dst_lib_tuple;
|
||||
dst_lib_buffer;
|
||||
dst_lib_table;
|
||||
dst_lib_fiber;
|
||||
dst_lib_os;
|
||||
|
||||
dst_ast_wrap;
|
||||
dst_ast_node;
|
||||
dst_ast_unwrap1;
|
||||
dst_ast_unwrap;
|
||||
|
||||
dst_scan_number;
|
||||
dst_scan_integer;
|
||||
dst_scan_real;
|
||||
|
||||
dst_parser_init;
|
||||
dst_parser_deinit;
|
||||
dst_parser_consume;
|
||||
dst_parser_status;
|
||||
dst_parser_produce;
|
||||
dst_parser_error;
|
||||
|
||||
dst_parse_cfun;
|
||||
|
||||
dst_lib_parse;
|
||||
|
||||
};
|
@ -51,6 +51,7 @@ DstBuffer *dst_buffer(int32_t capacity);
|
||||
DstBuffer *dst_buffer_init(DstBuffer *buffer, int32_t capacity);
|
||||
void dst_buffer_deinit(DstBuffer *buffer);
|
||||
void dst_buffer_ensure(DstBuffer *buffer, int32_t capacity);
|
||||
void dst_buffer_setcount(DstBuffer *buffer, int32_t count);
|
||||
int dst_buffer_extra(DstBuffer *buffer, int32_t n);
|
||||
int dst_buffer_push_bytes(DstBuffer *buffer, const uint8_t *string, int32_t len);
|
||||
int dst_buffer_push_string(DstBuffer *buffer, const uint8_t *string);
|
||||
@ -195,9 +196,12 @@ DstTable *dst_stl_env(void);
|
||||
int dst_arity_err(DstArgs args, int32_t n, const char *prefix);
|
||||
int dst_type_err(DstArgs args, int32_t n, DstType expected);
|
||||
int dst_typemany_err(DstArgs args, int32_t n, int expected);
|
||||
int dst_typeabstract_err(DstArgs args, int32_t n, DstAbstractType *at);
|
||||
#define dst_throw(a, e) (*((a).ret) = dst_cstringv(e), 1)
|
||||
#define dst_throwv(a, v) (*((a).ret) = (v), 1)
|
||||
#define dst_return(a, v) (*((a).ret) = (v), 0)
|
||||
|
||||
/* Early exit macros */
|
||||
#define dst_maxarity(A, N) do { if ((A).n > (N))\
|
||||
return dst_arity_err(A, N, "at most "); } while (0)
|
||||
#define dst_minarity(A, N) do { if ((A).n < (N))\
|
||||
@ -220,6 +224,53 @@ int dst_typemany_err(DstArgs args, int32_t n, int expected);
|
||||
}\
|
||||
} while (0)
|
||||
|
||||
#define dst_checkabstract(A, N, AT) do {\
|
||||
if ((A).n <= (N) || !dst_checktype() {\
|
||||
Dst x = (A).v[(N)];\
|
||||
if (!dst_checktype(x, DST_ABSTRACT) ||\
|
||||
dst_abstract_type(dst_unwrap_abstract(x)) != (AT))\
|
||||
return dst_typeabstract_err(A, N, AT);\
|
||||
} else {\
|
||||
return dst_typeabstract_err(A, N, AT);\
|
||||
}\
|
||||
} while (0)
|
||||
|
||||
#define dst_arg_abstract(DEST, A, N, AT) do {\
|
||||
dst_checkabstract(A, N, AT);\
|
||||
DEST = dst_unwrap_abstract((A).v[(N)]);\
|
||||
} while (0)
|
||||
|
||||
#define dst_arg_integer(DEST, A, N) do { \
|
||||
dst_check(A, N, DST_INTEGER);\
|
||||
DEST = dst_unwrap_integer((A).v[(N)]); } while (0)
|
||||
|
||||
#define dst_arg_real(DEST, A, N) do { \
|
||||
dst_check(A, N, DST_REAL);\
|
||||
DEST = dst_unwrap_real((A).v[(N)]); } while (0)
|
||||
|
||||
#define dst_arg_number(DEST, A, N) do { \
|
||||
if ((A).n <= (N)) return dst_typemany_err(A, N, DST_TFLAG_NUMBER);\
|
||||
Dst val = (A).v[(N)];\
|
||||
if (dst_checktype(val, DST_REAL)) { DEST = dst_unwrap_real(val); }\
|
||||
else if (dst_checktype(val, DST_INTEGER)) { DEST = (double) dst_unwrap_integer(val); }\
|
||||
else dst_typemany_err(A, N, DST_TFLAG_NUMBER); } while (0)
|
||||
|
||||
#define dst_arg_boolean(DEST, A, N) do { \
|
||||
dst_checkmany(A, N, DST_TFLAG_TRUE | DST_TFLAG_FALSE);\
|
||||
DEST = dst_unwrap_boolean((A).v[(N)]); } while (0)
|
||||
|
||||
#define dst_arg_string(DEST, A, N) do { \
|
||||
dst_check(A, N, DST_STRING);\
|
||||
DEST = dst_unwrap_string((A).v[(N)]); } while (0)
|
||||
|
||||
#define dst_arg_symbol(DEST, A, N) do { \
|
||||
dst_check(A, N, DST_SYMBOL);\
|
||||
DEST = dst_unwrap_string((A).v[(N)]); } while (0)
|
||||
|
||||
#define dst_arg_buffer(DEST, A, N) do { \
|
||||
dst_check(A, N, DST_BUFFER);\
|
||||
DEST = dst_unwrap_buffer((A).v[(N)]); } while (0)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user