ref: 2601e0b75a29fd1d112bc6049dee5d131dcb1d93
parent: 79bb6bfb032a4cd74bdbaf99d46a304d80506c46
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Wed Mar 15 13:43:54 EDT 2023
simplify ctypes logic a bit; remove lerror
--- a/Makefile
+++ b/Makefile
@@ -4,7 +4,7 @@
TARG=flisp
LLT=llt/libllt.a
-CFLAGS?=-O2 -pipe -g
+CFLAGS?=-O2 -g
CFLAGS+=-Wall -Wextra -falign-functions -Wno-strict-aliasing -std=c99 -D_DEFAULT_SOURCE
LDFLAGS?=
LDFLAGS+=${LLT} -lm
--- a/builtins.c
+++ b/builtins.c
@@ -275,10 +275,10 @@
fixnum_t i;
value_t f, v;
if (nargs == 0)
- lerror(ArgError, "vector.alloc: too few arguments");
+ lerrorf(ArgError, "vector.alloc: too few arguments");
i = (fixnum_t)toulong(args[0], "vector.alloc");
if (i < 0)
- lerror(ArgError, "vector.alloc: invalid size");
+ lerrorf(ArgError, "vector.alloc: invalid size");
v = alloc_vector((unsigned)i, 0);
if (nargs == 2)
f = args[1];
@@ -376,7 +376,7 @@
result = setenv(name, val, 1);
}
if (result != 0)
- lerror(ArgError, "os.setenv: invalid environment variable");
+ lerrorf(ArgError, "os.setenv: invalid environment variable");
return FL_T;
}
--- a/cvalues.c
+++ b/cvalues.c
@@ -6,8 +6,6 @@
#define NWORDS(sz) (((sz)+3)>>2)
#endif
-static int ALIGN2, ALIGN4, ALIGN8, ALIGNPTR;
-
value_t int8sym, uint8sym, int16sym, uint16sym, int32sym, uint32sym;
value_t int64sym, uint64sym;
value_t longsym, ulongsym, bytesym, wcharsym;
@@ -52,7 +50,7 @@
size_t nn = (maxfinalizers==0 ? 256 : maxfinalizers*2);
cvalue_t **temp = realloc(Finalizers, nn*sizeof(cvalue_t*));
if (temp == NULL)
- lerror(MemoryError, "out of memory");
+ lerrorf(MemoryError, "out of memory");
Finalizers = temp;
maxfinalizers = nn;
}
@@ -134,9 +132,9 @@
cvalue_t *pcv;
int str=0;
- if (valid_numtype(type->numtype)) {
+ if (valid_numtype(type->numtype))
return cprim(type, sz);
- }
+
if (type->eltype == bytetype) {
if (sz == 0)
return symbol_value(emptystringsym);
@@ -351,7 +349,7 @@
return 0;
}
}
- lerror(ArgError, "enum: invalid enum value");
+ lerrorf(ArgError, "enum: invalid enum value");
}
if (isfixnum(arg)) {
n = (int)numval(arg);
@@ -364,7 +362,7 @@
type_error("enum", "number", arg);
}
if ((unsigned)n >= vector_size(syms))
- lerror(ArgError, "enum: value out of range");
+ lerrorf(ArgError, "enum: value out of range");
*(int*)dest = n;
return 0;
}
@@ -409,7 +407,7 @@
if (iscons(cdr_(cdr_(type)))) {
size_t tc = toulong(car_(cdr_(cdr_(type))), "array");
if (tc != cnt)
- lerror(ArgError, "array: size mismatch");
+ lerrorf(ArgError, "array: size mismatch");
}
sz = elsize * cnt;
@@ -432,7 +430,7 @@
arg = cdr_(arg);
}
if (i != cnt)
- lerror(ArgError, "array: size mismatch");
+ lerrorf(ArgError, "array: size mismatch");
return 0;
}
else if (iscvalue(arg)) {
@@ -443,12 +441,12 @@
if (cv_len(cv) == sz)
memcpy(dest, cv_data(cv), sz);
else
- lerror(ArgError, "array: size mismatch");
+ lerrorf(ArgError, "array: size mismatch");
return 0;
}
else {
// TODO: initialize array from different type elements
- lerror(ArgError, "array: element type mismatch");
+ lerrorf(ArgError, "array: element type mismatch");
}
}
}
@@ -533,42 +531,23 @@
// *palign is an output argument giving the alignment required by type
size_t ctype_sizeof(value_t type, int *palign)
{
- if (type == int8sym || type == uint8sym || type == bytesym) {
- *palign = 1;
- return 1;
+ symbol_t *s;
+
+ if (issymbol(type) && (s = ptr(type)) != NULL && valid_numtype(s->numtype)) {
+ *palign = s->align;
+ return s->size;
}
- if (type == int16sym || type == uint16sym) {
- *palign = ALIGN2;
- return 2;
- }
- if (type == int32sym || type == uint32sym || type == wcharsym ||
- type == floatsym) {
- *palign = ALIGN4;
- return 4;
- }
- if (type == int64sym || type == uint64sym || type == doublesym) {
- *palign = ALIGN8;
- return 8;
- }
- if (type == longsym || type == ulongsym) {
-#if defined(ULONG64)
- *palign = ALIGN8;
- return 8;
-#else
- *palign = ALIGN4;
- return 4;
-#endif
- }
+
if (iscons(type)) {
value_t hed = car_(type);
if (hed == pointersym || hed == cfunctionsym) {
- *palign = ALIGNPTR;
+ *palign = sizeof(struct { char a; void *i; }) - sizeof(void*);
return sizeof(void*);
}
if (hed == arraysym) {
value_t t = car(cdr_(type));
if (!iscons(cdr_(cdr_(type))))
- lerror(ArgError, "sizeof: incomplete type");
+ lerrorf(ArgError, "sizeof: incomplete type");
value_t n = car_(cdr_(cdr_(type)));
size_t sz = toulong(n, "sizeof");
return sz * ctype_sizeof(t, palign);
@@ -580,11 +559,12 @@
return cvalue_union_size(type, palign);
}
else if (hed == enumsym) {
- *palign = ALIGN4;
- return 4;
+ *palign = sizeof(struct { char c; numerictype_t e; }) - sizeof(numerictype_t);
+ return sizeof(numerictype_t);
}
}
- lerror(ArgError, "sizeof: invalid c type");
+
+ lerrorf(ArgError, "sizeof: invalid c type");
return 0;
}
@@ -702,11 +682,11 @@
{
argcount("copy", nargs, 1);
if (iscons(args[0]) || isvector(args[0]))
- lerror(ArgError, "copy: argument must be a leaf atom");
+ lerrorf(ArgError, "copy: argument must be a leaf atom");
if (!iscvalue(args[0]))
return args[0];
if (!cv_isPOD((cvalue_t*)ptr(args[0])))
- lerror(ArgError, "copy: argument must be a plain-old-data type");
+ lerrorf(ArgError, "copy: argument must be a plain-old-data type");
return cvalue_copy(args[0]);
}
@@ -723,52 +703,11 @@
cvinitfunc_t f=type->init;
if (f == NULL)
- lerror(ArgError, "c-value: invalid c type");
+ lerrorf(ArgError, "c-value: invalid c type");
f(type, v, dest);
}
-static numerictype_t sym_to_numtype(value_t type)
-{
- if (type == int8sym)
- return T_INT8;
- else if (type == uint8sym || type == bytesym)
- return T_UINT8;
- else if (type == int16sym)
- return T_INT16;
- else if (type == uint16sym)
- return T_UINT16;
-#if defined(ULONG64)
- else if (type == int32sym || type == wcharsym)
-#else
- else if (type == int32sym || type == wcharsym || type == longsym)
-#endif
- return T_INT32;
-#if defined(ULONG64)
- else if (type == uint32sym)
-#else
- else if (type == uint32sym || type == ulongsym)
-#endif
- return T_UINT32;
-#if defined(ULONG64)
- else if (type == int64sym || type == longsym)
-#else
- else if (type == int64sym)
-#endif
- return T_INT64;
-#if defined(ULONG64)
- else if (type == uint64sym || type == ulongsym)
-#else
- else if (type == uint64sym)
-#endif
- return T_UINT64;
- else if (type == floatsym)
- return T_FLOAT;
- else if (type == doublesym)
- return T_DOUBLE;
- return N_NUMTYPES;
-}
-
// (new type . args)
// this provides (1) a way to allocate values with a shared type for
// efficiency, (2) a uniform interface for allocating cvalues of any
@@ -928,43 +867,58 @@
{ NULL, NULL }
};
-#define cv_intern(tok) tok##sym = symbol(#tok)
-#define ctor_cv_intern(tok) \
- cv_intern(tok);set(tok##sym, cbuiltin(#tok, cvalue_##tok))
-
-#define mk_primtype(name,ctype) \
- name##type=get_type(name##sym);name##type->init = cvalue_##ctype##_init
+#define cv_intern(tok) \
+ do{ \
+ tok##sym = symbol(#tok); \
+ }while(0)
+#define ctor_cv_intern(tok, nt, ctype) \
+ do{ \
+ symbol_t *s; \
+ cv_intern(tok); \
+ set(tok##sym, cbuiltin(#tok, cvalue_##tok)); \
+ if (valid_numtype(nt)) { \
+ s = ptr(tok##sym); \
+ s->numtype = nt; \
+ s->size = sizeof(ctype); \
+ s->align = sizeof(struct{char c; ctype x;}) - sizeof(ctype); \
+ } \
+ }while(0)
+#define mk_primtype(name, ctype) \
+ do{ \
+ name##type=get_type(name##sym); \
+ name##type->init = cvalue_##ctype##_init; \
+ }while(0)
+
static void cvalues_init(void)
{
htable_new(&TypeTable, 256);
htable_new(&reverse_dlsym_lookup_table, 256);
- // compute struct field alignment required for primitives
- ALIGN2 = sizeof(struct { char a; int16_t i; }) - 2;
- ALIGN4 = sizeof(struct { char a; int32_t i; }) - 4;
- ALIGN8 = sizeof(struct { char a; int64_t i; }) - 8;
- ALIGNPTR = sizeof(struct { char a; void *i; }) - sizeof(void*);
-
builtintype = define_opaque_type(builtinsym, sizeof(builtin_t), NULL, NULL);
- ctor_cv_intern(int8);
- ctor_cv_intern(uint8);
- ctor_cv_intern(int16);
- ctor_cv_intern(uint16);
- ctor_cv_intern(int32);
- ctor_cv_intern(uint32);
- ctor_cv_intern(int64);
- ctor_cv_intern(uint64);
- ctor_cv_intern(byte);
- ctor_cv_intern(wchar);
- ctor_cv_intern(long);
- ctor_cv_intern(ulong);
- ctor_cv_intern(float);
- ctor_cv_intern(double);
+ ctor_cv_intern(int8, T_INT8, int8_t);
+ ctor_cv_intern(uint8, T_UINT8, uint8_t);
+ ctor_cv_intern(int16, T_INT16, int16_t);
+ ctor_cv_intern(uint16, T_UINT16, uint16_t);
+ ctor_cv_intern(int32, T_INT32, int32_t);
+ ctor_cv_intern(uint32, T_UINT32, uint32_t);
+ ctor_cv_intern(int64, T_INT64, int64_t);
+ ctor_cv_intern(uint64, T_UINT64, uint64_t);
+ ctor_cv_intern(byte, T_UINT8, uint8_t);
+ ctor_cv_intern(wchar, T_INT32, int32_t);
+#if defined(ULONG64)
+ ctor_cv_intern(long, T_INT64, int64_t);
+ ctor_cv_intern(ulong, T_UINT64, uint64_t);
+#else
+ ctor_cv_intern(long, T_INT32, int32_t);
+ ctor_cv_intern(ulong, T_UINT32, uint32_t);
+#endif
+ ctor_cv_intern(float, T_FLOAT, float);
+ ctor_cv_intern(double, T_DOUBLE, double);
- ctor_cv_intern(array);
- ctor_cv_intern(enum);
+ ctor_cv_intern(array, NONNUMERIC, int);
+ ctor_cv_intern(enum, NONNUMERIC, int);
cv_intern(pointer);
cv_intern(struct);
cv_intern(union);
@@ -1270,10 +1224,10 @@
return 1;
}
-static void DivideByZeroError() __attribute__ ((__noreturn__));
+static void DivideByZeroError(void) __attribute__ ((__noreturn__));
static void DivideByZeroError(void)
{
- lerror(DivideError, "/: division by zero");
+ lerrorf(DivideError, "/: division by zero");
}
static value_t fl_div2(value_t a, value_t b)
--- a/flisp.c
+++ b/flisp.c
@@ -189,14 +189,6 @@
fl_raise(fl_list2(e, msg));
}
-void lerror(value_t e, const char *msg)
-{
- PUSH(e);
- value_t m = cvalue_static_cstring(msg);
- e = POP();
- fl_raise(fl_list2(e, m));
-}
-
void type_error(char *fname, char *expected, value_t got)
{
fl_raise(fl_listn(4, TypeError, symbol(fname), symbol(expected), got));
@@ -239,19 +231,17 @@
symbol_t *sym;
size_t len = strlen(str);
- sym = malloc(sizeof(*sym)-sizeof(void*) + len + 1);
+ sym = calloc(1, sizeof(*sym)-sizeof(void*) + len + 1);
assert(((uintptr_t)sym & 0x7) == 0); // make sure malloc aligns 8
- sym->left = sym->right = NULL;
- sym->flags = 0;
+ sym->numtype = NONNUMERIC;
if (fl_is_keyword_name(str, len)) {
value_t s = tagptr(sym, TAG_SYM);
setc(s, s);
- sym->flags |= 0x2;
+ sym->flags |= FLAG_KEYWORD;
}
else {
sym->binding = UNBOUND;
}
- sym->type = sym->dlcache = NULL;
sym->hash = memhash32(str, len)^0xAAAAAAAA;
memcpy(sym->name, str, len+1);
return sym;
@@ -396,7 +386,7 @@
void fl_gc_handle(value_t *pv)
{
if (N_GCHND >= N_GC_HANDLES)
- lerror(MemoryError, "out of gc handles");
+ lerrorf(MemoryError, "out of gc handles");
GCHandleStack[N_GCHND++] = pv;
}
@@ -603,7 +593,7 @@
size_t newsz = N_STACK + (N_STACK>>1);
value_t *ns = realloc(Stack, newsz*sizeof(value_t));
if (ns == NULL)
- lerror(MemoryError, "stack overflow");
+ lerrorf(MemoryError, "stack overflow");
Stack = ns;
N_STACK = newsz;
}
@@ -624,6 +614,8 @@
}
else if (isbuiltin(f)) {
value_t tab = symbol_value(builtins_table_sym);
+ if (ptr(tab) == NULL)
+ lerrorf(UnboundError, "builtins table");
Stack[SP-n-1] = vector_elt(tab, uintval(f));
v = apply_cl(n);
}
@@ -828,9 +820,9 @@
value_t s4 = Stack[SP-4];
value_t s5 = Stack[SP-5];
if (nargs < nreq)
- lerror(ArgError, "apply: too few arguments");
+ lerrorf(ArgError, "apply: too few arguments");
if (extr > sizeof(args)/sizeof(args[0]))
- lerror(ArgError, "apply: too many arguments");
+ lerrorf(ArgError, "apply: too many arguments");
for (i=0; i < extr; i++) args[i] = UNBOUND;
for (i=nreq; i < nargs; i++) {
v = Stack[bp+i];
@@ -870,7 +862,7 @@
no_kw:
nrestargs = nargs - i;
if (!va && nrestargs > 0)
- lerror(ArgError, "apply: too many arguments");
+ lerrorf(ArgError, "apply: too many arguments");
nargs = ntot + nrestargs;
if (nrestargs)
memmove(&Stack[bp+ntot], &Stack[bp+i], nrestargs*sizeof(value_t));
@@ -969,9 +961,9 @@
do_argc:
if (nargs != n) {
if (nargs > n)
- lerror(ArgError, "apply: too many arguments");
+ lerrorf(ArgError, "apply: too many arguments");
else
- lerror(ArgError, "apply: too few arguments");
+ lerrorf(ArgError, "apply: too few arguments");
}
NEXT_OP;
OP(OP_VARGC)
@@ -992,7 +984,7 @@
}
}
else if (s < 0) {
- lerror(ArgError, "apply: too few arguments");
+ lerrorf(ArgError, "apply: too few arguments");
}
else {
PUSH(0);
@@ -1729,10 +1721,10 @@
i = GET_INT32(ip); ip+=4;
n = GET_INT32(ip); ip+=4;
if (nargs < i)
- lerror(ArgError, "apply: too few arguments");
+ lerrorf(ArgError, "apply: too few arguments");
if ((int32_t)n > 0) {
if (nargs > n)
- lerror(ArgError, "apply: too many arguments");
+ lerrorf(ArgError, "apply: too many arguments");
}
else n = -n;
if (n > nargs) {
@@ -2030,7 +2022,7 @@
}
}
if (isgensym(fn->name))
- lerror(ArgError, "function: name should not be a gensym");
+ lerrorf(ArgError, "function: name should not be a gensym");
}
return fv;
}
@@ -2118,7 +2110,7 @@
value_t fl_map1(value_t *args, uint32_t nargs)
{
if (nargs < 2)
- lerror(ArgError, "map: too few arguments");
+ lerrorf(ArgError, "map: too few arguments");
if (!iscons(args[1])) return NIL;
value_t first, last, v;
int64_t argSP = args-Stack;
--- a/flisp.h
+++ b/flisp.h
@@ -1,12 +1,30 @@
#ifndef FLISP_H
#define FLISP_H
+/* functions needed to implement the value interface (cvtable_t) */
+typedef enum {
+ T_INT8, T_UINT8,
+ T_INT16, T_UINT16,
+ T_INT32, T_UINT32,
+ T_INT64, T_UINT64,
+ T_FLOAT,
+ T_DOUBLE,
+} numerictype_t;
+
+#define NONNUMERIC (0xff)
+#define valid_numtype(v) ((v) <= T_DOUBLE)
+
typedef uintptr_t value_t;
typedef lltint_t fixnum_t;
+
#ifdef BITS64
#define T_FIXNUM T_INT64
+#define fits_fixnum(x) (((x)>>61) == 0 || (~((x)>>61)) == 0)
+#define mk_xlong mk_int64
#else
#define T_FIXNUM T_INT32
+#define fits_fixnum(x) (((x)>>29) == 0 || (~((x)>>29)) == 0)
+#define mk_xlong mk_long
#endif
typedef struct {
@@ -15,10 +33,13 @@
} cons_t;
typedef struct _symbol_t {
- uintptr_t flags;
value_t binding; // global value binding
- struct _fltype_t *type;
uint32_t hash;
+ uint8_t numtype;
+ uint8_t size;
+ uint8_t align;
+ uint8_t flags;
+ struct _fltype_t *type;
void *dlcache; // dlsym address
// below fields are private
struct _symbol_t *left;
@@ -36,14 +57,22 @@
uint32_t id;
} gensym_t;
-#define TAG_NUM 0x0
-#define TAG_CPRIM 0x1
-#define TAG_FUNCTION 0x2
-#define TAG_VECTOR 0x3
-#define TAG_NUM1 0x4
-#define TAG_CVALUE 0x5
-#define TAG_SYM 0x6
-#define TAG_CONS 0x7
+enum {
+ TAG_NUM,
+ TAG_CPRIM,
+ TAG_FUNCTION,
+ TAG_VECTOR,
+ TAG_NUM1,
+ TAG_CVALUE,
+ TAG_SYM,
+ TAG_CONS,
+};
+
+enum {
+ FLAG_CONST = 1<<0,
+ FLAG_KEYWORD = 1<<1,
+};
+
#define UNBOUND ((value_t)0x1) // an invalid value
#define TAG_FWD UNBOUND
#define tag(x) ((x)&0x7)
@@ -51,11 +80,6 @@
#define tagptr(p,t) (((value_t)(p)) | (t))
#define fixnum(x) ((value_t)((fixnum_t)(x))<<2)
#define numval(x) (((fixnum_t)(x))>>2)
-#if defined(BITS64)
-#define fits_fixnum(x) (((x)>>61) == 0 || (~((x)>>61)) == 0)
-#else
-#define fits_fixnum(x) (((x)>>29) == 0 || (~((x)>>29)) == 0)
-#endif
#define fits_bits(x,b) (((x)>>(b-1)) == 0 || (~((x)>>(b-1))) == 0)
#define uintval(x) (((unsigned int)(x))>>3)
#define builtin(n) tagptr((((int)n)<<3), TAG_FUNCTION)
@@ -94,11 +118,12 @@
#define fn_name(f) (((value_t*)ptr(f))[3])
#define set(s, v) (((symbol_t*)ptr(s))->binding = (v))
-#define setc(s, v) do { ((symbol_t*)ptr(s))->flags |= 1; \
+#define setc(s, v) do { ((symbol_t*)ptr(s))->flags |= FLAG_CONST; \
((symbol_t*)ptr(s))->binding = (v); } while (0)
-#define isconstant(s) ((s)->flags&0x1)
-#define iskeyword(s) ((s)->flags&0x2)
+#define isconstant(s) ((s)->flags&FLAG_CONST)
+#define iskeyword(s) ((s)->flags&FLAG_KEYWORD)
#define symbol_value(s) (((symbol_t*)ptr(s))->binding)
+#define sym_to_numtype(s) (((symbol_t*)ptr(s))->numtype)
#define ismanaged(v) ((((uint8_t*)ptr(v)) >= fromspace) && \
(((uint8_t*)ptr(v)) < fromspace+heapsize))
#define isgensym(x) (issymbol(x) && ismanaged(x))
@@ -188,7 +213,6 @@
for(l__ca=1; l__ca; l__ca=0, fl_restorestate(&_ctx))
void lerrorf(value_t e, char *format, ...) __attribute__ ((__noreturn__));
-void lerror(value_t e, const char *msg) __attribute__ ((__noreturn__));
void fl_savestate(fl_exception_context_t *_ctx);
void fl_restorestate(fl_exception_context_t *_ctx);
void fl_raise(value_t e) __attribute__ ((__noreturn__));
@@ -209,12 +233,6 @@
void (*print_traverse)(value_t self);
} cvtable_t;
-/* functions needed to implement the value interface (cvtable_t) */
-typedef enum { T_INT8, T_UINT8, T_INT16, T_UINT16, T_INT32, T_UINT32,
- T_INT64, T_UINT64, T_FLOAT, T_DOUBLE } numerictype_t;
-
-#define N_NUMTYPES ((int)T_DOUBLE+1)
-
value_t relocate_lispvalue(value_t v);
void print_traverse(value_t v);
void fl_print_chr(char c, ios_t *f);
@@ -225,14 +243,14 @@
typedef struct _fltype_t {
value_t type;
- numerictype_t numtype;
- size_t size;
- size_t elsz;
cvtable_t *vtable;
struct _fltype_t *eltype; // for arrays
struct _fltype_t *artype; // (array this)
- int marked;
cvinitfunc_t init;
+ size_t size;
+ size_t elsz;
+ int marked;
+ numerictype_t numtype;
} fltype_t;
typedef struct {
@@ -278,7 +296,6 @@
#define cvalue_len(v) cv_len((cvalue_t*)ptr(v))
#define value2c(type, v) ((type)cv_data((cvalue_t*)ptr(v)))
-#define valid_numtype(v) ((v) < N_NUMTYPES)
#define cp_class(cp) ((cp)->type)
#define cp_type(cp) (cp_class(cp)->type)
#define cp_numtype(cp) (cp_class(cp)->numtype)
@@ -339,12 +356,6 @@
value_t mk_wchar(int32_t n);
value_t return_from_uint64(uint64_t Uaccum);
value_t return_from_int64(int64_t Saccum);
-
-#ifdef BITS64
-#define mk_xlong mk_int64
-#else
-#define mk_xlong mk_long
-#endif
numerictype_t effective_numerictype(double r);
double conv_to_double(void *data, numerictype_t tag);
--- a/flmain.c
+++ b/flmain.c
@@ -32,15 +32,11 @@
fl_init(512*1024);
-#if defined(INITFILE)
- snprintf(fname_buf, sizeof(fname_buf), "%s", INITFILE);
-#else
value_t str = symbol_value(symbol("*install-dir*"));
char *exedir = (str == UNBOUND ? NULL : cvalue_data(str));
snprintf(fname_buf, sizeof(fname_buf), "%s%sflisp.boot",
exedir ? exedir : "",
exedir ? PATHSEPSTRING : "");
-#endif
fl_gc_handle(&args[0]);
fl_gc_handle(&args[1]);
--- a/iostream.c
+++ b/iostream.c
@@ -94,7 +94,7 @@
value_t f = cvalue(iostreamtype, sizeof(ios_t));
ios_t *s = value2c(ios_t*, f);
if (ios_mem(s, 0) == NULL)
- lerror(MemoryError, "buffer: could not allocate stream");
+ lerrorf(MemoryError, "buffer: could not allocate stream");
return f;
}
@@ -125,7 +125,7 @@
ios_t *s = toiostream(args[0], "io.getc");
uint32_t wc;
if (ios_getutf8(s, &wc) == IOS_EOF)
- //lerror(IOError, "io.getc: end of file reached");
+ //lerrorf(IOError, "io.getc: end of file reached");
return FL_EOF;
return mk_wchar(wc);
}
@@ -158,7 +158,7 @@
type_error("io.ungetc", "wchar", args[1]);
uint32_t wc = *(uint32_t*)cp_data((cprim_t*)ptr(args[1]));
if (wc >= 0x80) {
- lerror(ArgError, "io_ungetc: unicode not yet supported");
+ lerrorf(ArgError, "io_ungetc: unicode not yet supported");
}
return fixnum(ios_ungetc((int)wc,s));
}
@@ -244,7 +244,7 @@
else {
ft = get_type(args[1]);
if (ft->eltype != NULL && !iscons(cdr_(cdr_(args[1]))))
- lerror(ArgError, "io.read: incomplete type");
+ lerrorf(ArgError, "io.read: incomplete type");
n = ft->size;
}
value_t cv = cvalue(ft, n);
@@ -253,7 +253,7 @@
else data = cp_data((cprim_t*)ptr(cv));
size_t got = ios_read(value2c(ios_t*,args[0]), data, n);
if (got < n)
- //lerror(IOError, "io.read: end of input reached");
+ //lerrorf(IOError, "io.read: end of input reached");
return FL_EOF;
return cv;
}
@@ -280,7 +280,7 @@
ios_t *s = toiostream(args[0], "io.write");
if (iscprim(args[1]) && ((cprim_t*)ptr(args[1]))->type == wchartype) {
if (nargs > 2)
- lerror(ArgError,
+ lerrorf(ArgError,
"io.write: offset argument not supported for characters");
uint32_t wc = *(uint32_t*)cp_data((cprim_t*)ptr(args[1]));
return fixnum(ios_pututf8(s, wc));
@@ -400,7 +400,7 @@
argcount("io.tostring!", nargs, 1);
ios_t *src = toiostream(args[0], "io.tostring!");
if (src->bm != bm_mem)
- lerror(ArgError, "io.tostring!: requires memory stream");
+ lerrorf(ArgError, "io.tostring!: requires memory stream");
return stream_to_string(&args[0]);
}
--- a/print.c
+++ b/print.c
@@ -207,7 +207,7 @@
// get the width of an expression if we can do so cheaply
if (issymbol(v))
return u8_strwidth(symbol_name(v));
- if (iscprim(v) && cp_class((cprim_t*)ptr(v)) == wchartype)
+ if (iscprim(v) && ptr(v) != NULL && cp_class((cprim_t*)ptr(v)) == wchartype)
return 4;
return -1;
}
@@ -611,8 +611,6 @@
// get rid of all those zeros.
}
-static numerictype_t sym_to_numtype(value_t type);
-
// 'weak' means we don't need to accurately reproduce the type, so
// for example #int32(0) can be printed as just 0. this is used
// printing in a context where a type is already implied, e.g. inside
@@ -708,15 +706,15 @@
// handle other integer prims. we know it's smaller than uint64
// at this point, so int64 is big enough to capture everything.
numerictype_t nt = sym_to_numtype(type);
- if (nt == N_NUMTYPES) {
- HPOS += ios_printf(f, "#<%s>", symbol_name(type));
- }
- else {
+ if (valid_numtype(nt)) {
int64_t i64 = conv_to_int64(data, nt);
if (weak || print_princ)
HPOS += ios_printf(f, "%"PRId64, i64);
else
HPOS += ios_printf(f, "#%s(%"PRId64")", symbol_name(type), i64);
+ }
+ else {
+ HPOS += ios_printf(f, "#<%s>", symbol_name(type));
}
}
else if (iscons(type)) {
--- a/read.c
+++ b/read.c
@@ -182,7 +182,7 @@
{
buf[(*pi)++] = c;
if (*pi >= (int)(sizeof(buf)-1))
- lerror(ParseError, "read: token too long");
+ lerrorf(ParseError, "read: token too long");
}
// return: 1 if escaped (forced to be symbol)
@@ -258,7 +258,7 @@
else if (c == '#') {
ch = ios_getc(F); c = (char)ch;
if (ch == IOS_EOF)
- lerror(ParseError, "read: invalid read macro");
+ lerrorf(ParseError, "read: invalid read macro");
if (c == '.') {
toktype = TOK_SHARPDOT;
}
@@ -268,13 +268,13 @@
else if (c == '\\') {
uint32_t cval;
if (ios_getutf8(F, &cval) == IOS_EOF)
- lerror(ParseError, "read: end of input in character constant");
+ lerrorf(ParseError, "read: end of input in character constant");
if (cval == (uint32_t)'u' || cval == (uint32_t)'U' ||
cval == (uint32_t)'x') {
read_token('u', 0);
if (buf[1] != '\0') { // not a solitary 'u','U','x'
if (!read_numtok(&buf[1], &tokval, 16))
- lerror(ParseError,
+ lerrorf(ParseError,
"read: invalid hex character constant");
cval = numval(tokval);
}
@@ -305,7 +305,7 @@
toktype = TOK_SHARPOPEN;
}
else if (c == '<') {
- lerror(ParseError, "read: unreadable object");
+ lerrorf(ParseError, "read: unreadable object");
}
else if (isdigit(c)) {
read_token(c, 1);
@@ -315,11 +315,11 @@
else if (c == '=')
toktype = TOK_LABEL;
else
- lerror(ParseError, "read: invalid label");
+ lerrorf(ParseError, "read: invalid label");
errno = 0;
x = strtoll(buf, &end, 10);
if (*end != '\0' || errno)
- lerror(ParseError, "read: invalid label");
+ lerrorf(ParseError, "read: invalid label");
tokval = fixnum(x);
}
else if (c == '!') {
@@ -336,7 +336,7 @@
ch = ios_getc(F);
hashpipe_gotc:
if (ch == IOS_EOF)
- lerror(ParseError, "read: eof within comment");
+ lerrorf(ParseError, "read: eof within comment");
if ((char)ch == '|') {
ch = ios_getc(F);
if ((char)ch == '#') {
@@ -373,7 +373,7 @@
errno = 0;
x = strtol(buf, &end, 10);
if (*end != '\0' || buf[0] == '\0' || errno)
- lerror(ParseError, "read: invalid gensym label");
+ lerrorf(ParseError, "read: invalid gensym label");
toktype = TOK_GENSYM;
tokval = fixnum(x);
}
@@ -395,7 +395,7 @@
tokval = symbol(buf);
}
else {
- lerror(ParseError, "read: unknown read macro");
+ lerrorf(ParseError, "read: unknown read macro");
}
}
else if (c == ',') {
@@ -460,7 +460,7 @@
ptrhash_put(&readstate->backrefs, (void*)label, (void*)v);
while (peek() != closer) {
if (ios_eof(F))
- lerror(ParseError, "read: unexpected end of input");
+ lerrorf(ParseError, "read: unexpected end of input");
if (i >= vector_size(v)) {
v = Stack[SP-1] = vector_grow(v);
if (label != UNBOUND)
@@ -494,7 +494,7 @@
temp = realloc(buf, sz);
if (temp == NULL) {
free(buf);
- lerror(ParseError, "read: out of memory reading string");
+ lerrorf(ParseError, "read: out of memory reading string");
}
buf = temp;
}
@@ -501,7 +501,7 @@
c = ios_getc(F);
if (c == IOS_EOF) {
free(buf);
- lerror(ParseError, "read: unexpected end of input in string");
+ lerrorf(ParseError, "read: unexpected end of input in string");
}
if (c == '"')
break;
@@ -509,7 +509,7 @@
c = ios_getc(F);
if (c == IOS_EOF) {
free(buf);
- lerror(ParseError, "read: end of input in escape sequence");
+ lerrorf(ParseError, "read: end of input in escape sequence");
}
j=0;
if (octal_digit(c)) {
@@ -536,7 +536,7 @@
if (j) wc = strtol(eseq, NULL, 16);
if (!j || wc > 0x10ffff) {
free(buf);
- lerror(ParseError, "read: invalid escape sequence");
+ lerrorf(ParseError, "read: invalid escape sequence");
}
if (ndig == 2)
buf[i++] = ((char)wc);
@@ -570,7 +570,7 @@
t = peek();
while (t != closer) {
if (ios_eof(F))
- lerror(ParseError, "read: unexpected end of input");
+ lerrorf(ParseError, "read: unexpected end of input");
c = mk_cons(); car_(c) = cdr_(c) = NIL;
if (iscons(*pc)) {
cdr_(*pc) = c;
@@ -591,7 +591,7 @@
cdr_(*pc) = c;
t = peek();
if (ios_eof(F))
- lerror(ParseError, "read: unexpected end of input");
+ lerrorf(ParseError, "read: unexpected end of input");
if (t != closer) {
take();
lerrorf(ParseError, "read: expected '%c'", closer==TOK_CLOSEB ? ']' : ')');
@@ -615,11 +615,11 @@
take();
switch (t) {
case TOK_CLOSE:
- lerror(ParseError, "read: unexpected ')'");
+ lerrorf(ParseError, "read: unexpected ')'");
case TOK_CLOSEB:
- lerror(ParseError, "read: unexpected ']'");
+ lerrorf(ParseError, "read: unexpected ']'");
case TOK_DOT:
- lerror(ParseError, "read: unexpected '.'");
+ lerrorf(ParseError, "read: unexpected '.'");
case TOK_SYM:
case TOK_NUM:
return tokval;
--- a/table.c
+++ b/table.c
@@ -79,7 +79,7 @@
{
size_t cnt = (size_t)nargs;
if (cnt & 1)
- lerror(ArgError, "table: arguments must come in pairs");
+ lerrorf(ArgError, "table: arguments must come in pairs");
value_t nt;
// prevent small tables from being added to finalizer list
if (cnt <= HT_N_INLINE) {
@@ -176,7 +176,7 @@
// reload pointer
h = (htable_t*)cv_data((cvalue_t*)ptr(t));
if (h->size != n)
- lerror(EnumerationError, "table.foldl: table modified");
+ lerrorf(EnumerationError, "table.foldl: table modified");
table = h->table;
}
}
--- a/types.c
+++ b/types.c
@@ -22,28 +22,22 @@
sz = ctype_sizeof(t, &align);
}
- ft = (fltype_t*)malloc(sizeof(fltype_t));
+ ft = calloc(1, sizeof(fltype_t));
ft->type = t;
+ ft->numtype = NONNUMERIC;
if (issymbol(t)) {
ft->numtype = sym_to_numtype(t);
+ assert(valid_numtype(ft->numtype));
((symbol_t*)ptr(t))->type = ft;
}
- else {
- ft->numtype = N_NUMTYPES;
- }
ft->size = sz;
- ft->vtable = NULL;
- ft->artype = NULL;
ft->marked = 1;
- ft->elsz = 0;
- ft->eltype = NULL;
- ft->init = NULL;
if (iscons(t)) {
if (isarray) {
fltype_t *eltype = get_type(car_(cdr_(t)));
if (eltype->size == 0) {
free(ft);
- lerror(ArgError, "invalid array element type");
+ lerrorf(ArgError, "invalid array element type");
}
ft->elsz = eltype->size;
ft->eltype = eltype;
@@ -70,14 +64,11 @@
fltype_t *define_opaque_type(value_t sym, size_t sz, cvtable_t *vtab,
cvinitfunc_t init)
{
- fltype_t *ft = (fltype_t*)malloc(sizeof(fltype_t));
+ fltype_t *ft = calloc(1, sizeof(fltype_t));
ft->type = sym;
+ ft->numtype = NONNUMERIC;
ft->size = sz;
- ft->numtype = N_NUMTYPES;
ft->vtable = vtab;
- ft->artype = NULL;
- ft->eltype = NULL;
- ft->elsz = 0;
ft->marked = 1;
ft->init = init;
return ft;