shithub: femtolisp

Download patch

ref: ba070d54b831abcfc8b328baf0eaa0de7d7c7653
parent: 0bf4243ae0c8bfa68d62b67b32bacef3da486364
author: Sigrid Solveig Haflínudóttir <ftrvxmtrx@gmail.com>
date: Sun Nov 29 16:04:34 EST 2020

first working version

--- a/builtins.c
+++ b/builtins.c
@@ -2,6 +2,20 @@
   Extra femtoLisp builtin functions
 */
 
+#ifdef __plan9__
+#include <u.h>
+#include <libc.h>
+#define exit(x) exits(x ? "error" : nil)
+#define sqrtf sqrt
+#define expf exp
+#define logf log
+#define sinf sin
+#define cosf cos
+#define tanf tan
+#define asinf asin
+#define acosf acos
+#define atanf atan
+#else
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
@@ -14,6 +28,7 @@
 #include <sys/stat.h>
 #include <errno.h>
 #include <math.h>
+#endif
 #include "llt.h"
 #include "flisp.h"
 #include "random.h"
@@ -109,6 +124,7 @@
         return fixnum(llength(a));
     }
     type_error("length", "sequence", a);
+    return -1;
 }
 
 static value_t fl_f_raise(value_t *args, u_int32_t nargs)
@@ -115,6 +131,7 @@
 {
     argcount("raise", nargs, 1);
     fl_raise(args[0]);
+    return -1;
 }
 
 static value_t fl_exit(value_t *args, u_int32_t nargs)
@@ -173,7 +190,7 @@
 
 value_t fl_global_env(value_t *args, u_int32_t nargs)
 {
-    (void)args;
+    USED(args);
     argcount("environment", nargs, 0);
     value_t lst = FL_NIL;
     fl_gc_handle(&lst);
@@ -246,6 +263,7 @@
         return fixnum(conv_to_long(cp_data(cp), cp_numtype(cp)));
     }
     type_error("fixnum", "number", args[0]);
+    return -1;
 }
 
 static value_t fl_truncate(value_t *args, u_int32_t nargs)
@@ -274,6 +292,7 @@
         return return_from_int64((int64_t)d);
     }
     type_error("truncate", "number", args[0]);
+    return -1;
 }
 
 static value_t fl_vector_alloc(value_t *args, u_int32_t nargs)
@@ -299,7 +318,7 @@
 static value_t fl_time_now(value_t *args, u_int32_t nargs)
 {
     argcount("time.now", nargs, 0);
-    (void)args;
+    USED(args);
     return mk_double(clock_now());
 }
 
@@ -313,6 +332,7 @@
         return conv_to_double(cp_data(cp), nt);
     }
     type_error(fname, "number", a);
+    return -1;
 }
 
 static value_t fl_time_string(value_t *args, uint32_t nargs)
@@ -357,9 +377,16 @@
 {
     argcount("path.exists?", nargs, 1);
     char *str = tostring(args[0], "path.exists?");
+#ifdef __plan9__
+    Dir *d;
+    if ((d = dirstat(str)) == nil)
+        return FL_F;
+    free(d);
+#else
     struct stat sbuf;
     if (stat(str, &sbuf) == -1)
         return FL_F;
+#endif
     return FL_T;
 }
 
@@ -382,6 +409,8 @@
     if (args[1] == FL_F) {
 #ifdef LINUX
         result = unsetenv(name);
+#elif defined(__plan9__)
+        result = putenv(name, "");
 #else
         (void)unsetenv(name);
         result = 0;
@@ -389,7 +418,11 @@
     }
     else {
         char *val = tostring(args[1], "os.setenv");
+#ifdef __plan9__
+        result = putenv(name, val);
+#else
         result = setenv(name, val, 1);
+#endif
     }
     if (result != 0)
         lerror(ArgError, "os.setenv: invalid environment variable");
@@ -398,7 +431,7 @@
 
 static value_t fl_rand(value_t *args, u_int32_t nargs)
 {
-    (void)args; (void)nargs;
+    USED(args); USED(nargs);
     fixnum_t r;
 #ifdef BITS64
     r = ((((uint64_t)random())<<32) | random()) & 0x1fffffffffffffffLL;
@@ -409,7 +442,7 @@
 }
 static value_t fl_rand32(value_t *args, u_int32_t nargs)
 {
-    (void)args; (void)nargs;
+    USED(args); USED(nargs);
     uint32_t r = random();
 #ifdef BITS64
     return fixnum(r);
@@ -419,18 +452,18 @@
 }
 static value_t fl_rand64(value_t *args, u_int32_t nargs)
 {
-    (void)args; (void)nargs;
+    USED(args); USED(nargs);
     uint64_t r = (((uint64_t)random())<<32) | random();
     return mk_uint64(r);
 }
 static value_t fl_randd(value_t *args, u_int32_t nargs)
 {
-    (void)args; (void)nargs;
+    USED(args); USED(nargs);
     return mk_double(rand_double());
 }
 static value_t fl_randf(value_t *args, u_int32_t nargs)
 {
-    (void)args; (void)nargs;
+    USED(args); USED(nargs);
     return mk_float(rand_float());
 }
 
--- a/cvalues.c
+++ b/cvalues.c
@@ -247,8 +247,8 @@
 static int cvalue_##ctype##_init(fltype_t *type, value_t arg,   \
                                  void *dest)                    \
 {                                                               \
-    fl_##ctype##_t n=0;                                         \
-    (void)type;                                                 \
+    fl_##ctype##_t n;                                           \
+    USED(type);                                                 \
     if (isfixnum(arg)) {                                        \
         n = numval(arg);                                        \
     }                                                           \
@@ -334,7 +334,7 @@
         return conv_to_ulong(cp_data(cp), cp_numtype(cp));
     }
     type_error(fname, "number", n);
-    return 0;
+    return NIL;
 }
 
 static int cvalue_enum_init(fltype_t *ft, value_t arg, void *dest)
@@ -884,7 +884,7 @@
 {
     argcount("builtin", nargs, 1);
     symbol_t *name = tosymbol(args[0], "builtin");
-    cvalue_t *cv;
+    cvalue_t *cv = NULL;
     if (ismanaged(args[0]) || (cv=name->dlcache) == NULL) {
         lerrorf(ArgError, "builtin: function %s not found", name->name);
     }
@@ -934,10 +934,10 @@
     cv_intern(tok);set(tok##sym, cbuiltin(#tok, cvalue_##tok))
 
 #define mk_primtype(name) \
-  name##type=get_type(name##sym);name##type->init = &cvalue_##name##_init
+  name##type=get_type(name##sym);name##type->init = cvalue_##name##_init
 
 #define mk_primtype_(name,ctype) \
-  name##type=get_type(name##sym);name##type->init = &cvalue_##ctype##_init
+  name##type=get_type(name##sym);name##type->init = cvalue_##ctype##_init
 
 static void cvalues_init(void)
 {
@@ -1050,7 +1050,7 @@
     double Faccum=0;
     int32_t inexact = 0;
     uint32_t i;
-    value_t arg=NIL;
+    value_t arg;
 
     FOR_ARGS(i,0,arg,args) {
         if (isfixnum(arg)) {
@@ -1154,6 +1154,7 @@
         }
     }
     type_error("-", "number", n);
+    return NIL;
 }
 
 static value_t fl_mul_any(value_t *args, u_int32_t nargs, int64_t Saccum)
@@ -1162,7 +1163,7 @@
     double Faccum=1;
     int32_t inexact = 0;
     uint32_t i;
-    value_t arg=NIL;
+    value_t arg;
 
     FOR_ARGS(i,0,arg,args) {
         if (isfixnum(arg)) {
@@ -1346,6 +1347,7 @@
     return return_from_int64(conv_to_int64(aptr, ta) / b64);
  div_error:
     DivideByZeroError();
+    return -1;
 }
 
 static value_t fl_bitwise_op(value_t a, value_t b, int opcode, char *fname)
@@ -1487,6 +1489,7 @@
         }
     }
     type_error("lognot", "integer", a);
+    return NIL;
 }
 
 static value_t fl_ash(value_t *args, u_int32_t nargs)
--- a/equalhash.c
+++ b/equalhash.c
@@ -1,3 +1,7 @@
+#ifdef __plan9__
+#include <u.h>
+#include <libc.h>
+#else
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
@@ -4,6 +8,7 @@
 #include <assert.h>
 #include <limits.h>
 #include <setjmp.h>
+#endif
 
 #include "llt.h"
 #include "flisp.h"
--- a/flisp.c
+++ b/flisp.c
@@ -29,6 +29,15 @@
   Distributed under the BSD License
 */
 
+#ifdef __plan9__
+#include <u.h>
+#include <libc.h>
+#define vsnprintf vsnprint
+#define INT_MAX 0x7fffffff
+#define UINT_MAX 0xffffffffU
+#define INT_MIN (-INT_MAX-1)
+#pragma lib "./llt/libllt.a"
+#else
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
@@ -43,6 +52,7 @@
 #include <limits.h>
 #include <errno.h>
 #include <math.h>
+#endif
 #include "llt.h"
 #include "flisp.h"
 #include "opcodes.h"
@@ -224,6 +234,7 @@
     if (is##type(v))                                                          \
         return (ctype)cnvt(v);                                                \
     type_error(fname, #type, v);                                              \
+    return 0;                                                                 \
 }
 SAFECAST_OP(cons,  cons_t*,  ptr)
 SAFECAST_OP(symbol,symbol_t*,ptr)
@@ -298,7 +309,7 @@
 value_t fl_gensym(value_t *args, uint32_t nargs)
 {
     argcount("gensym", nargs, 0);
-    (void)args;
+    USED(args);
     gensym_t *gs = (gensym_t*)alloc_words(sizeof(gensym_t)/sizeof(void*));
     gs->id = _gensym_ctr++;
     gs->binding = UNBOUND;
@@ -622,7 +633,7 @@
 {
     value_t f = Stack[SP-n-1];
     uint32_t saveSP = SP;
-    value_t v;
+    value_t v = NIL;
     if (iscbuiltin(f)) {
         v = ((builtin_t*)ptr(f))[3](&Stack[SP-n], n);
     }
@@ -828,7 +839,7 @@
 {
     uint32_t extr = nopt+nkw;
     uint32_t ntot = nreq+extr;
-    value_t args[extr], v;
+    value_t args[64], v;
     uint32_t i, a = 0, nrestargs;
     value_t s1 = Stack[SP-1];
     value_t s2 = Stack[SP-2];
@@ -836,6 +847,8 @@
     value_t s5 = Stack[SP-5];
     if (nargs < nreq)
         lerror(ArgError, "apply: too few arguments");
+    if (extr > sizeof(args)/sizeof(args[0]))
+        lerror(ArgError, "apply: too many arguments");
     for (i=0; i < extr; i++) args[i] = UNBOUND;
     for (i=nreq; i < nargs; i++) {
         v = Stack[bp+i];
@@ -2250,7 +2263,9 @@
     int i;
 
     llt_init();
+#ifndef __plan9__
     setlocale(LC_NUMERIC, "C");
+#endif
 
     heapsize = initial_heapsize;
 
--- a/flisp.h
+++ b/flisp.h
@@ -1,8 +1,12 @@
 #ifndef FLISP_H
 #define FLISP_H
 
+#ifdef __plan9__
+#define __attribute__(...)
+#else
 #include <setjmp.h>
 #include <stdint.h>
+#endif
 
 typedef uptrint_t value_t;
 typedef int_t fixnum_t;
--- a/flmain.c
+++ b/flmain.c
@@ -1,6 +1,11 @@
+#ifdef __plan9__
+#include <u.h>
+#include <libc.h>
+#else
 #include <stdlib.h>
 #include <string.h>
 #include <assert.h>
+#endif
 #include "llt.h"
 #include "flisp.h"
 
--- a/iostream.c
+++ b/iostream.c
@@ -1,3 +1,7 @@
+#ifdef __plan9__
+#include <u.h>
+#include <libc.h>
+#else
 #include <stdlib.h>
 #include <stdio.h>
 #include <stdarg.h>
@@ -5,6 +9,7 @@
 #include <assert.h>
 #include <sys/types.h>
 #include <setjmp.h>
+#endif
 #include "llt.h"
 #include "flisp.h"
 
--- a/llt/bitvector-ops.c
+++ b/llt/bitvector-ops.c
@@ -1,6 +1,11 @@
+#ifdef __plan9__
+#include <u.h>
+#include <libc.h>
+#else
 #include <stdlib.h>
 #include <assert.h>
 #include <string.h>
+#endif
 
 #include "dtypes.h"
 #include "bitvector.h"
@@ -323,11 +328,12 @@
     index_t i;
     u_int32_t nw, tail;
     u_int32_t *temp;
+    u_int32_t a[MALLOC_CUTOFF];
 
     if (nbits == 0) return;
 
     nw = (offs+nbits+31)>>5;
-    temp = (nw > MALLOC_CUTOFF) ? malloc(nw*4) : alloca(nw*4);
+    temp = (nw > MALLOC_CUTOFF) ? malloc(nw*4) : a;
     for(i=0; i < nw/2; i++) {
         temp[i]      = bitreverse(b[nw-i-1]);
         temp[nw-i-1] = bitreverse(b[i]);
@@ -456,7 +462,8 @@
                              u_int32_t *b, u_int32_t boffs, u_int32_t nbits) \
 {                                                                            \
     u_int32_t nw = (doffs+nbits+31)>>5;                                      \
-    u_int32_t *temp = nw>MALLOC_CUTOFF ? malloc((nw+1)*4) : alloca((nw+1)*4);\
+    u_int32_t atmp[MALLOC_CUTOFF+1];                                         \
+    u_int32_t *temp = nw>MALLOC_CUTOFF ? malloc((nw+1)*4) : atmp;            \
     u_int32_t i, anw, bnw;                                                   \
     if (aoffs == boffs) {                                                    \
         anw = (aoffs+nbits+31)>>5;                                           \
--- a/llt/bitvector.c
+++ b/llt/bitvector.c
@@ -29,9 +29,14 @@
   and_to, or_to, and xor_to allow overlap.
 */
 
+#ifdef __plan9__
+#include <u.h>
+#include <libc.h>
+#else
 #include <stdlib.h>
 #include <assert.h>
 #include <string.h>
+#endif
 
 #include "dtypes.h"
 #include "bitvector.h"
--- a/llt/dirpath.c
+++ b/llt/dirpath.c
@@ -1,3 +1,7 @@
+#ifdef __plan9__
+#include <u.h>
+#include <libc.h>
+#else
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
@@ -7,9 +11,6 @@
 #include <limits.h>
 #include <sys/stat.h>
 #include <sys/types.h>
-
-#include "dtypes.h"
-
 #ifdef WIN32
 #include <malloc.h>
 #include <sys/timeb.h>
@@ -24,12 +25,16 @@
 #include <sys/poll.h>
 #include <unistd.h>
 #endif
+#endif
 
+#include "dtypes.h"
 #include "dirpath.h"
 
 void get_cwd(char *buf, size_t size)
 {
-#ifndef WIN32
+#ifdef __plan9__
+    getwd(buf, size);
+#elif !defined(WIN32)
     getcwd(buf, size);
 #else
     GetCurrentDirectory(size, buf);
@@ -60,7 +65,13 @@
     }
 }
 
-#ifdef LINUX
+#ifdef __plan9__
+char *get_exename(char *buf, size_t size)
+{
+    snprint(buf, size, "/sys/lib/flisp/flisp");
+    return buf;
+}
+#elif defined(LINUX)
 char *get_exename(char *buf, size_t size)
 {
     char linkname[64]; /* /proc/<pid>/exe */
--- a/llt/dtypes.h
+++ b/llt/dtypes.h
@@ -29,12 +29,12 @@
 #  define NETBSD
 #elif defined(_WIN32)
 #  define WIN32
-#else
+#elif !defined(__plan9__)
 #  error "unknown platform"
 #endif
 
-#if defined(OPENBSD) || defined(FREEBSD) || defined(NETBSD)
-#if defined(__x86_64__)
+#if defined(OPENBSD) || defined(FREEBSD) || defined(NETBSD) || defined(__plan9__)
+#if defined(__x86_64__) || defined(__amd64__)
 #  define __SIZEOF_POINTER__ 8
 #else
 #  define __SIZEOF_POINTER__ 4
@@ -62,6 +62,9 @@
 #  else
 #    define DLLEXPORT __declspec(dllexport)
 #  endif
+#elif defined(__plan9__)
+#define STDCALL
+#define DLLEXPORT
 #else
 #  define STDCALL
 #  define DLLEXPORT __attribute__ ((visibility("default")))
@@ -80,7 +83,7 @@
 #  define __BIG_ENDIAN     BIG_ENDIAN
 #  define __PDP_ENDIAN     PDP_ENDIAN
 #  define __BYTE_ORDER     BYTE_ORDER
-#elif defined(WIN32)
+#elif defined(WIN32) || defined(__plan9__)
 #  define __LITTLE_ENDIAN	1234
 #  define __BIG_ENDIAN	4321
 #  define __PDP_ENDIAN	3412
@@ -110,7 +113,20 @@
 
 typedef int bool_t;
 
-#if defined(__INTEL_COMPILER) && defined(WIN32)
+#if defined(__plan9__)
+#ifdef BITS64
+typedef uvlong size_t;
+typedef vlong ssize_t;
+#else
+typedef ulong size_t;
+typedef long ssize_t;
+#endif
+#define STATIC_INLINE static
+#define INLINE
+#ifndef NULL
+#define NULL nil
+#endif
+#elif defined(__INTEL_COMPILER) && defined(WIN32)
 # define STATIC_INLINE static
 # define INLINE
 # ifdef BITS64
@@ -124,7 +140,18 @@
 #endif
 
 typedef unsigned char  byte_t;   /* 1 byte */
-#if defined(WIN32)
+#if defined(__plan9__)
+typedef s8int int8_t;
+typedef s16int int16_t;
+typedef s32int int32_t;
+typedef s64int int64_t;
+typedef u64int uint64_t;
+typedef u8int u_int8_t;
+typedef u16int u_int16_t;
+typedef u32int u_int32_t;
+typedef u64int u_int64_t;
+typedef vlong off_t;
+#elif defined(WIN32)
 typedef short int16_t;
 typedef int int32_t;
 typedef long long int64_t;
@@ -131,11 +158,7 @@
 typedef unsigned char u_int8_t;
 typedef unsigned short u_int16_t;
 typedef unsigned int u_int32_t;
-#ifdef BITS64
-typedef unsigned long u_int64_t;
-#else
 typedef unsigned long long u_int64_t;
-#endif
 #ifdef __INTEL_COMPILER
 typedef signed char int8_t;
 typedef short int16_t;
@@ -148,8 +171,8 @@
 #ifdef BITS64
 #define TOP_BIT 0x8000000000000000
 #define NBITS 64
-typedef unsigned long uint_t;  // preferred int type on platform
-typedef long int_t;
+typedef uint64_t uint_t;  // preferred int type on platform
+typedef int64_t int_t;
 typedef int64_t offset_t;
 typedef u_int64_t index_t;
 typedef int64_t ptrint_t; // pointer-size int
--- a/llt/dump.c
+++ b/llt/dump.c
@@ -1,4 +1,9 @@
+#ifdef __plan9__
+#include <u.h>
+#include <libc.h>
+#else
 #include <stdlib.h>
+#endif
 #include "dtypes.h"
 #include "ios.h"
 #include "utils.h"
--- a/llt/hashing.c
+++ b/llt/hashing.c
@@ -1,9 +1,14 @@
 /*
   Hashing
 */
+#ifdef __plan9__
+#include <u.h>
+#include <libc.h>
+#else
 #include <stdlib.h>
 #include <stdio.h>
 #include <math.h>
+#endif
 #include "dtypes.h"
 #include "utils.h"
 #include "hashing.h"
--- a/llt/htable.c
+++ b/llt/htable.c
@@ -2,11 +2,16 @@
   functions common to all hash table instantiations
 */
 
+#ifdef __plan9__
+#include <u.h>
+#include <libc.h>
+#else
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
 #include <assert.h>
 #include <limits.h>
+#endif
 
 #include "dtypes.h"
 #include "htable.h"
--- a/llt/htable.inc
+++ b/llt/htable.inc
@@ -74,8 +74,6 @@
     tab = h->table;                                                     \
                                                                         \
     goto retry_bp;                                                      \
-                                                                        \
-    return NULL;                                                        \
 }                                                                       \
                                                                         \
 void HTNAME##_put(htable_t *h, void *key, void *val)                    \
--- a/llt/int2str.c
+++ b/llt/int2str.c
@@ -1,4 +1,9 @@
+#ifdef __plan9__
+#include <u.h>
+#include <libc.h>
+#else
 #include <stdlib.h>
+#endif
 #include "dtypes.h"
 #include "utils.h"
 
--- a/llt/ios.c
+++ b/llt/ios.c
@@ -1,3 +1,22 @@
+#ifdef __plan9__
+#include <u.h>
+#include <libc.h>
+static int errno;
+enum {
+	SEEK_SET,
+	SEEK_CUR,
+	SEEK_END,
+
+	STDIN_FILENO = 0,
+	STDOUT_FILENO,
+	STDERR_FILENO,
+};
+#define lseek seek
+#define O_RDWR ORDWR
+#define O_WRONLY OWRITE
+#define O_RDONLY OREAD
+#define O_TRUNC OTRUNC
+#else
 #include <stdlib.h>
 #include <stdarg.h>
 #include <string.h>
@@ -6,9 +25,6 @@
 #include <errno.h>
 #include <wchar.h>
 #include <stdio.h> // for printf
-
-#include "dtypes.h"
-
 #ifdef WIN32
 #include <malloc.h>
 #include <io.h>
@@ -21,7 +37,9 @@
 #include <sys/stat.h>
 #include <fcntl.h>
 #endif
+#endif
 
+#include "dtypes.h"
 #include "utils.h"
 #include "utf8.h"
 #include "ios.h"
@@ -31,10 +49,10 @@
 
 /* OS-level primitive wrappers */
 
-#if defined(MACOSX)
+#if defined(MACOSX) || defined(__plan9__)
 void *memrchr(const void *s, int c, size_t n)
 {
-    const unsigned char *src = s + n;
+    const unsigned char *src = (const unsigned char*)s + n;
     unsigned char uc = c;
     while (--src >= (unsigned char *) s)
         if (*src == uc)
@@ -65,8 +83,13 @@
 
 static int _enonfatal(int err)
 {
+#ifdef __plan9__
+    USED(err);
+    return 0;
+#else
     return (err == EAGAIN || err == EINPROGRESS || err == EINTR ||
             err == EWOULDBLOCK);
+#endif
 }
 
 #define SLEEP_TIME 5//ms
@@ -73,7 +96,7 @@
 
 // return error code, #bytes read in *nread
 // these wrappers retry operations until success or a fatal error
-static int _os_read(long fd, void *buf, size_t n, size_t *nread)
+static int _os_read(long fd, char *buf, size_t n, size_t *nread)
 {
     ssize_t r;
 
@@ -81,7 +104,7 @@
         r = read((int)fd, buf, n);
         if (r > -1) {
             *nread = (size_t)r;
-            return 0;
+            break;
         }
         if (!_enonfatal(errno)) {
             *nread = 0;
@@ -92,7 +115,7 @@
     return 0;
 }
 
-static int _os_read_all(long fd, void *buf, size_t n, size_t *nread)
+static int _os_read_all(long fd, char *buf, size_t n, size_t *nread)
 {
     size_t got;
 
@@ -117,7 +140,7 @@
         r = write((int)fd, buf, n);
         if (r > -1) {
             *nwritten = (size_t)r;
-            return 0;
+            break;
         }
         if (!_enonfatal(errno)) {
             *nwritten = 0;
@@ -128,7 +151,7 @@
     return 0;
 }
 
-static int _os_write_all(long fd, void *buf, size_t n, size_t *nwritten)
+static int _os_write_all(long fd, char *buf, size_t n, size_t *nwritten)
 {
     size_t wrote;
 
@@ -612,7 +635,7 @@
 int ios_setbuf(ios_t *s, char *buf, size_t size, int own)
 {
     ios_flush(s);
-    size_t nvalid=0;
+    size_t nvalid;
 
     nvalid = (size < s->size) ? size : s->size;
     if (nvalid > 0)
@@ -742,7 +765,7 @@
 
 /* stream object initializers. we do no allocation. */
 
-ios_t *ios_file(ios_t *s, char *fname, int rd, int wr, int create, int trunc)
+ios_t *ios_file(ios_t *s, char *fname, int rd, int wr, int creat, int trunc)
 {
     int fd;
     if (!(rd || wr))
@@ -749,11 +772,18 @@
         // must specify read and/or write
         goto open_file_err;
     int flags = wr ? (rd ? O_RDWR : O_WRONLY) : O_RDONLY;
-    if (create) flags |= O_CREAT;
     if (trunc)  flags |= O_TRUNC;
-    fd = open(fname, flags, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH/*644*/);
+#ifdef __plan9__
+    if (creat)
+        fd = create(fname, flags, 0644);
+    else
+        fd = open(fname, flags);
+#else
+    if (creat) flags |= O_CREAT;
+    fd = open(fname, flags, 0644);
+#endif
     s = ios_fd(s, fd, 1, 1);
-    if (fd == -1)
+    if (fd < 0)
         goto open_file_err;
     if (!wr)
         s->readonly = 1;
@@ -805,7 +835,7 @@
 ios_t *ios_stdout = NULL;
 ios_t *ios_stderr = NULL;
 
-void ios_init_stdstreams()
+void ios_init_stdstreams(void)
 {
     ios_stdin = LLT_ALLOC(sizeof(ios_t));
     ios_fd(ios_stdin, STDIN_FILENO, 0, 0);
@@ -959,8 +989,9 @@
 
 int ios_vprintf(ios_t *s, const char *format, va_list args)
 {
-    char *str=NULL;
+    char *str;
     int c;
+#ifndef __plan9__
     va_list al;
     va_copy(al, args);
 
@@ -983,6 +1014,10 @@
         }
     }
     c = vasprintf(&str, format, al);
+#else
+    str = vsmprint(format, args);
+    c = strlen(str);
+#endif
 
     if (c >= 0) {
         ios_write(s, str, c);
@@ -989,7 +1024,11 @@
 
         LLT_FREE(str);
     }
+#ifndef __plan9__
     va_end(al);
+#else
+    va_end(args);
+#endif
     return c;
 }
 
--- a/llt/ios.h
+++ b/llt/ios.h
@@ -1,7 +1,9 @@
 #ifndef __IOS_H_
 #define __IOS_H_
 
+#ifndef __plan9__
 #include <stdarg.h>
+#endif
 
 // this flag controls when data actually moves out to the underlying I/O
 // channel. memory streams are a special case of this where the data
@@ -94,7 +96,7 @@
 extern ios_t *ios_stdin;
 extern ios_t *ios_stdout;
 extern ios_t *ios_stderr;
-void ios_init_stdstreams();
+void ios_init_stdstreams(void);
 
 /* high-level functions - output */
 int ios_putnum(ios_t *s, char *data, uint32_t type);
--- a/llt/llt.h
+++ b/llt/llt.h
@@ -1,7 +1,9 @@
 #ifndef __LLT_H_
 #define __LLT_H_
 
+#ifndef __plan9__
 #include <stdarg.h>
+#endif
 #include "dtypes.h"
 #include "utils.h"
 #include "utf8.h"
@@ -14,6 +16,6 @@
 #include "dirpath.h"
 #include "random.h"
 
-void llt_init();
+void llt_init(void);
 
 #endif
--- a/llt/lltinit.c
+++ b/llt/lltinit.c
@@ -1,8 +1,13 @@
+#ifdef __plan9__
+#include <u.h>
+#include <libc.h>
+#else
 #include <stdlib.h>
 #include <stdio.h>
 #include <stdarg.h>
 #include <math.h>
 #include <locale.h>
+#endif
 #include "dtypes.h"
 #include "timefuncs.h"
 #include "ios.h"
@@ -18,12 +23,8 @@
 float  F_PINF;
 float  F_NINF;
 
-int locale_is_utf8;
-
-void llt_init()
+void llt_init(void)
 {
-    locale_is_utf8 = u8_is_locale_utf8(setlocale(LC_ALL, ""));
-
     randomize();
 
     ios_init_stdstreams();
@@ -32,8 +33,15 @@
     D_NNAN = -strtod("+NaN",NULL);
     D_PINF = strtod("+Inf",NULL);
     D_NINF = strtod("-Inf",NULL);
+#ifdef __plan9__
+    F_PNAN = D_PNAN;
+    F_NNAN = D_NNAN;
+    F_PINF = D_PINF;
+    F_NINF = D_NINF;
+#else
     F_PNAN = strtof("+NaN",NULL);
     F_NNAN = -strtof("+NaN",NULL);
     F_PINF = strtof("+Inf",NULL);
     F_NINF = strtof("-Inf",NULL);
+#endif
 }
--- a/llt/lookup3.c
+++ b/llt/lookup3.c
@@ -35,6 +35,7 @@
 */
 //#define SELF_TEST 1
 
+#ifndef __plan9__
 #include <stdio.h>      /* defines printf for tests */
 #include <time.h>       /* defines time_t for timings in the test */
 #ifndef WIN32
@@ -47,6 +48,7 @@
 #endif
 #ifdef LINUX
 # include <endian.h>    /* attempt to define endianness */
+#endif
 #endif
 
 /*
--- a/llt/mt19937ar.c
+++ b/llt/mt19937ar.c
@@ -41,7 +41,11 @@
    email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
 */
 
+#ifndef __plan9__
 #include <stdio.h>
+#endif
+
+#include "dtypes.h"
 
 /* Period parameters */  
 #define mtN 624
--- a/llt/ptrhash.c
+++ b/llt/ptrhash.c
@@ -3,11 +3,16 @@
   optimized for storing info about particular values
 */
 
+#ifdef __plan9__
+#include <u.h>
+#include <libc.h>
+#else
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
 #include <assert.h>
 #include <limits.h>
+#endif
 
 #include "dtypes.h"
 #include "ptrhash.h"
--- a/llt/random.c
+++ b/llt/random.c
@@ -1,9 +1,14 @@
 /*
   random numbers
 */
+#ifdef __plan9__
+#include <u.h>
+#include <libc.h>
+#else
 #include <stdlib.h>
 #include <stdio.h>
 #include <math.h>
+#endif
 #include "dtypes.h"
 #include "ieee754.h"
 #include "utils.h"
@@ -55,7 +60,7 @@
     return s * vim;
 }
 
-void randomize()
+void randomize(void)
 {
     u_int64_t tm = i64time();
     init_by_array((uint32_t*)&tm, 2);
--- a/llt/random.h
+++ b/llt/random.h
@@ -3,12 +3,12 @@
 
 #define random() genrand_int32()
 #define srandom(n) init_genrand(n)
-double rand_double();
-float rand_float();
-double randn();
-void randomize();
-uint32_t genrand_int32();
+double rand_double(void);
+float rand_float(void);
+double randn(void);
+void randomize(void);
+uint32_t genrand_int32(void);
 void init_genrand(uint32_t s);
-u_int64_t i64time();
+u_int64_t i64time(void);
 
 #endif
--- a/llt/socket.c
+++ b/llt/socket.c
@@ -15,7 +15,6 @@
 
 #include "socket.h"
 
-
 int mysocket(int domain, int type, int protocol)
 {
     int val;
--- a/llt/socket.h
+++ b/llt/socket.h
@@ -1,6 +1,7 @@
 #ifndef __LLTSOCKET_H_
 #define __LLTSOCKET_H_
 
+#ifndef __plan9__
 #ifdef WIN32
 #include <winsock2.h>
 #else
@@ -9,6 +10,7 @@
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <fcntl.h>
+#endif
 #endif
 
 int open_tcp_port(short portno);
--- /dev/null
+++ b/llt/socketp9.c
@@ -1,0 +1,2 @@
+#include <u.h>
+#include <libc.h>
--- a/llt/timefuncs.c
+++ b/llt/timefuncs.c
@@ -1,3 +1,7 @@
+#ifdef __plan9__
+#include <u.h>
+#include <libc.h>
+#else
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
@@ -7,9 +11,6 @@
 #include <limits.h>
 #include <sys/stat.h>
 #include <sys/types.h>
-
-#include "dtypes.h"
-
 #ifdef WIN32
 #include <malloc.h>
 #include <sys/timeb.h>
@@ -19,7 +20,9 @@
 #include <sys/poll.h>
 #include <unistd.h>
 #endif
+#endif
 
+#include "dtypes.h"
 #include "timefuncs.h"
 
 #ifdef WIN32
@@ -30,7 +33,7 @@
         (double)t->tm_sec + (double)tstruct->millitm/1.0e3;
 }
 */
-double floattime()
+double floattime(void)
 {
     struct timeb tstruct;
 
@@ -37,6 +40,11 @@
     ftime(&tstruct);
     return (double)tstruct.time + (double)tstruct.millitm/1.0e3;
 }
+#elif defined(__plan9__)
+double floattime(void)
+{
+    return (double)nsec() / 1.0e9;
+}
 #else
 double tv2float(struct timeval *tv)
 {
@@ -50,7 +58,7 @@
 #endif
 
 // return as many bits of system randomness as we can get our hands on
-u_int64_t i64time()
+u_int64_t i64time(void)
 {
     u_int64_t a;
 #ifdef WIN32
@@ -57,6 +65,8 @@
     struct timeb tstruct;
     ftime(&tstruct);
     a = (((u_int64_t)tstruct.time)<<32) + (u_int64_t)tstruct.millitm;
+#elif defined(__plan9__)
+    a = nsec();
 #else
     struct timeval now;
     gettimeofday(&now, NULL);
@@ -66,9 +76,9 @@
     return a;
 }
 
-double clock_now()
+double clock_now(void)
 {
-#ifdef WIN32
+#if defined(WIN32) || defined(__plan9__)
     return floattime();
 #else
     struct timeval now;
@@ -80,9 +90,12 @@
 
 void timestring(double seconds, char *buffer, size_t len)
 {
+#ifdef __plan9__
+    buffer[0] = 0; // FIXME
+    USED(seconds, buffer, len);
+#elif defined(LINUX) || defined(MACOSX) || defined(OPENBSD) || defined(FREEBSD) || defined(NETBSD)
     time_t tme = (time_t)seconds;
 
-#if defined(LINUX) || defined(MACOSX) || defined(OPENBSD) || defined(FREEBSD) || defined(NETBSD)
     char *fmt = "%c"; /* needed to suppress GCC warning */
     struct tm tm;
 
@@ -89,6 +102,8 @@
     localtime_r(&tme, &tm);
     strftime(buffer, len, fmt, &tm);
 #else
+    time_t tme = (time_t)seconds;
+
     static char *wdaystr[] = {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
     static char *monthstr[] = {"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug",
                                "Sep","Oct","Nov","Dec"};
@@ -126,6 +141,12 @@
     }
     return -1;
 }
+#elif defined(__plan9__)
+double parsetime(const char *str)
+{
+    USED(str);
+    return -1;
+}
 #else
 // TODO
 #endif
@@ -137,6 +158,8 @@
 
 #ifdef WIN32
     Sleep(ms);
+#elif defined(__plan9__)
+    sleep(ms);
 #else
     struct timeval timeout;
 
@@ -148,14 +171,17 @@
 
 void timeparts(int32_t *buf, double t)
 {
+#ifdef __plan9__
+    // FIXME wtf
+    USED(buf, t);
+#elif !defined(WIN32)
     time_t tme = (time_t)t;
-
-#ifndef WIN32
     struct tm tm;
     localtime_r(&tme, &tm);
     tm.tm_year += 1900;
     memcpy(buf, (char*)&tm, sizeof(struct tm));
 #else
+    time_t tme = (time_t)t;
     struct tm *tm;
 
     tm = localtime(&tme);
--- a/llt/timefuncs.h
+++ b/llt/timefuncs.h
@@ -1,8 +1,8 @@
 #ifndef __TIMEFUNCS_H_
 #define __TIMEFUNCS_H_
 
-u_int64_t i64time();
-double clock_now();
+u_int64_t i64time(void);
+double clock_now(void);
 void timestring(double seconds, char *buffer, size_t len);
 double parsetime(const char *str);
 void sleep_ms(int ms);
--- a/llt/utf8.c
+++ b/llt/utf8.c
@@ -12,6 +12,13 @@
   valid.
   A UTF-8 validation routine is included.
 */
+#ifdef __plan9__
+#include <u.h>
+#include <libc.h>
+#define snprintf snprint
+#define vsnprintf vsnprint
+#define iswprint(x) 1
+#else
 #define _XOPEN_SOURCE 700
 #include <stdlib.h>
 #include <stdio.h>
@@ -21,8 +28,6 @@
 #include <wchar.h>
 #include <wctype.h>
 
-#include "dtypes.h"
-
 #ifdef WIN32
 #include <malloc.h>
 #define snprintf _snprintf
@@ -32,7 +37,9 @@
 #endif /* __FreeBSD__ && __OpenBSD__ && __NetBSD__ */
 #endif
 #include <assert.h>
+#endif
 
+#include "dtypes.h"
 #include "utf8.h"
 
 static const u_int32_t offsetsFromUTF8[6] = {
@@ -244,7 +251,7 @@
     return count;
 }
 
-#if defined(__WIN32__)
+#if defined(__WIN32__) || defined(__plan9__)
 #include "wcwidth.c"
 #endif
 
@@ -486,7 +493,7 @@
         else {
             i0 = i;
             ch = u8_nextmemchar(src, &i);
-            if (ascii || !iswprint((wint_t)ch)) {
+            if (ascii || !iswprint(ch)) {
                 buf += u8_escape_wchar(buf, sz - (buf-start), ch);
             }
             else {
@@ -570,35 +577,14 @@
     return NULL;
 }
 
-int u8_is_locale_utf8(const char *locale)
-{
-    if (locale == NULL) return 0;
-
-    /* this code based on libutf8 */
-    const char* cp = locale;
-
-    for (; *cp != '\0' && *cp != '@' && *cp != '+' && *cp != ','; cp++) {
-        if (*cp == '.') {
-            const char* encoding = ++cp;
-            for (; *cp != '\0' && *cp != '@' && *cp != '+' && *cp != ','; cp++)
-                ;
-            if ((cp-encoding == 5 && !strncmp(encoding, "UTF-8", 5))
-                || (cp-encoding == 4 && !strncmp(encoding, "utf8", 4)))
-                return 1; /* it's UTF-8 */
-            break;
-        }
-    }
-    return 0;
-}
-
 size_t u8_vprintf(const char *fmt, va_list ap)
 {
-    size_t cnt, sz=0, nc, needfree=0;
-    char *buf;
+    size_t cnt, sz, nc, needfree=0;
+    char *buf, tmp[512];
     u_int32_t *wcs;
 
     sz = 512;
-    buf = (char*)alloca(sz);
+    buf = tmp;
     cnt = vsnprintf(buf, sz, fmt, ap);
     if ((ssize_t)cnt < 0)
         return 0;
@@ -607,10 +593,15 @@
         needfree = 1;
         vsnprintf(buf, cnt+1, fmt, ap);
     }
-    wcs = (u_int32_t*)alloca((cnt+1) * sizeof(u_int32_t));
+    wcs = (u_int32_t*)malloc((cnt+1) * sizeof(u_int32_t));
     nc = u8_toucs(wcs, cnt+1, buf, cnt);
     wcs[nc] = 0;
+#ifdef __plan9__
+    print("%S", (Rune*)wcs);
+#else
     printf("%ls", (wchar_t*)wcs);
+#endif
+    free(wcs);
     if (needfree) free(buf);
     return nc;
 }
--- a/llt/utf8.h
+++ b/llt/utf8.h
@@ -14,8 +14,6 @@
 #endif
 #endif
 
-extern int locale_is_utf8;
-
 #if defined(__WIN32__)
 extern int wcwidth(uint32_t);
 #endif
@@ -113,8 +111,6 @@
 
 /* number of columns occupied by a string */
 size_t u8_strwidth(const char *s);
-
-int u8_is_locale_utf8(const char *locale);
 
 /* printf where the format string and arguments may be in UTF-8.
    you can avoid this function and just use ordinary printf() if the current
--- a/llt/utils.h
+++ b/llt/utils.h
@@ -38,7 +38,7 @@
 #  define LEGACY_REGS "=q"
 #endif
 
-#if !defined(__INTEL_COMPILER) && (defined(ARCH_X86) || defined(ARCH_X86_64))
+#if !defined(__plan9__) && !defined(__INTEL_COMPILER) && (defined(ARCH_X86) || defined(ARCH_X86_64))
 STATIC_INLINE u_int16_t ByteSwap16(u_int16_t x)
 {
   __asm("xchgb %b0,%h0" :
--- a/llt/wcwidth.c
+++ b/llt/wcwidth.c
@@ -1,4 +1,3 @@
-#include "dtypes.h" //for DLLEXPORT
 /*
  * This is an implementation of wcwidth() and wcswidth() (defined in
  * IEEE Std 1002.1-2001) for Unicode.
@@ -62,7 +61,11 @@
  * MODIFIED TO USE uint32_t
  */
 
+#ifndef __plan9__
 #include <stdint.h>
+#include <stddef.h>
+#include "dtypes.h" //for DLLEXPORT
+#endif
 
 struct interval {
   int first;
@@ -89,7 +92,6 @@
   return 0;
 }
 
-
 /* The following two functions define the column width of an ISO 10646
  * character as follows:
  *
@@ -121,9 +123,6 @@
  * This implementation assumes that wchar_t characters are encoded
  * in ISO 10646.
  */
-
-#include <stdint.h>
-#include <stddef.h>
 
 DLLEXPORT int wcwidth(uint32_t ucs)
 {
--- a/opaque_type_template.c
+++ b/opaque_type_template.c
@@ -1,3 +1,7 @@
+#ifdef __plan9__
+#include <u.h>
+#include <libc.h>
+#else
 #include <stdlib.h>
 #include <stdio.h>
 #include <stdarg.h>
@@ -4,6 +8,7 @@
 #include <string.h>
 #include <assert.h>
 #include <sys/types.h>
+#endif
 #include "llt.h"
 #include "flisp.h"
 
--- a/operators.c
+++ b/operators.c
@@ -1,10 +1,12 @@
-#include <limits.h>
-#include <assert.h>
 #include "dtypes.h"
 #include "utils.h"
 #include "ieee754.h"
 
+#ifdef __plan9__
+#define trunc(x) floor(x)
+#else
 extern double trunc(double x);
+#endif
 
 STATIC_INLINE double fpart(double arg)
 {
--- a/print.c
+++ b/print.c
@@ -1,3 +1,8 @@
+#ifdef __plan9__
+#define isnan isNaN
+#define snprintf snprint
+#define iswprint(x) 1
+#endif
 #include "ieee754.h"
 
 extern void *memrchr(const void *s, int c, size_t n);
@@ -264,7 +269,7 @@
 static void print_pair(ios_t *f, value_t v)
 {
     value_t cd;
-    char *op = NULL;
+    char *op;
     if (iscons(cdr_(v)) && cdr_(cdr_(v)) == NIL &&
         !ptrhash_has(&printconses, (void*)cdr_(v)) &&
         (((car_(v) == QUOTE)     && (op = "'"))  ||
@@ -282,7 +287,7 @@
     int startpos = HPOS;
     outc('(', f);
     int newindent=HPOS, blk=blockindent(v);
-    int lastv, n=0, si, ind=0, est, always=0, nextsmall, thistiny;
+    int lastv, n=0, si, ind, est, always=0, nextsmall, thistiny;
     if (!blk) always = indentevery(v);
     value_t head = car_(v);
     int after3 = indentafter3(head, v);
@@ -604,8 +609,7 @@
             }
             // don't need trailing .
             if (s[sz-1] == '.') {
-                s[sz-1] = '\0';
-                sz--;
+                s[--sz] = '\0';
             }
         }
     }
@@ -813,8 +817,8 @@
         void *fptr = *(void**)data;
         label = (value_t)ptrhash_get(&reverse_dlsym_lookup_table, cv);
         if (label == (value_t)HT_NOTFOUND) {
-            HPOS += ios_printf(f, "#<builtin @0x%08zx>",
-                               (size_t)(builtin_t)fptr);
+            HPOS += ios_printf(f, "#<builtin @0x%08llux>",
+                               (uvlong)(builtin_t)fptr);
         }
         else {
             if (print_princ) {
--- a/read.c
+++ b/read.c
@@ -1,3 +1,10 @@
+#ifdef __plan9__
+#define strcasecmp cistrcmp
+#define ERANGE (-999)
+static int errno;
+#include <ctype.h>
+#endif
+
 enum {
     TOK_NONE, TOK_OPEN, TOK_CLOSE, TOK_DOT, TOK_QUOTE, TOK_SYM, TOK_NUM,
     TOK_BQ, TOK_COMMA, TOK_COMMAAT, TOK_COMMADOT,
@@ -546,7 +553,7 @@
         }
     }
     take();
-    (void)POP();
+    POP();
 }
 
 // label is the backreference we'd like to fix up with this read
--- a/string.c
+++ b/string.c
@@ -1,6 +1,13 @@
 /*
   string functions
 */
+#ifdef __plan9__
+#include <u.h>
+#include <libc.h>
+#define towupper toupperrune
+#define towlower tolowerrune
+#define iswalpha isalpharune
+#else
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
@@ -13,6 +20,7 @@
 #include <sys/types.h>
 #include <sys/time.h>
 #include <errno.h>
+#endif
 #include "llt.h"
 #include "flisp.h"
 
@@ -53,7 +61,12 @@
     if (iscprim(args[0])) {
         cprim_t *cp = (cprim_t*)ptr(args[0]);
         if (cp_class(cp) == wchartype) {
+            // FIXME plan9
+#ifdef __plan9__
+            int w = -1;
+#else
             int w = wcwidth(*(uint32_t*)cp_data(cp));
+#endif
             if (w < 0)
                 return FL_F;
             return fixnum(w);
@@ -91,6 +104,7 @@
         }
     }
     type_error("string.encode", "wchar array", args[0]);
+    return -1;
 }
 
 value_t fl_string_decode(value_t *args, u_int32_t nargs)
@@ -134,6 +148,7 @@
     set(printreadablysym, FL_F);
     set(printprettysym, FL_F);
     FOR_ARGS(i,0,arg,args) {
+        USED(arg);
         fl_print(s, args[i]);
     }
     set(printreadablysym, oldpr);
@@ -150,7 +165,7 @@
     char *delim = tostring(args[1], "string.split");
     size_t len = cv_len((cvalue_t*)ptr(args[0]));
     size_t dlen = cv_len((cvalue_t*)ptr(args[1]));
-    size_t ssz, tokend=0, tokstart=0, i=0;
+    size_t ssz, tokend, tokstart, i=0;
     value_t first=FL_NIL, c=FL_NIL, last;
     size_t junk;
     fl_gc_handle(&first);
@@ -271,7 +286,7 @@
     size_t len = cv_len((cvalue_t*)ptr(args[0]));
     if (start > len)
         bounds_error("string.find", args[0], args[2]);
-    char *needle; size_t needlesz;
+    char *needle = ""; size_t needlesz = 0;
 
     value_t v = args[1];
     cprim_t *cp = (cprim_t*)ptr(v);
@@ -362,7 +377,7 @@
         argcount("number->string", nargs, 2);
     value_t n = args[0];
     int neg = 0;
-    uint64_t num;
+    uint64_t num = 0;
     if (isfixnum(n))      num = numval(n);
     else if (!iscprim(n)) type_error("number->string", "integer", n);
     else num = conv_to_uint64(cp_data((cprim_t*)ptr(n)),
--- a/table.c
+++ b/table.c
@@ -1,3 +1,7 @@
+#ifdef __plan9__
+#include <u.h>
+#include <libc.h>
+#else
 #include <stdlib.h>
 #include <stdio.h>
 #include <stdarg.h>
@@ -5,6 +9,7 @@
 #include <assert.h>
 #include <sys/types.h>
 #include <setjmp.h>
+#endif
 #include "llt.h"
 #include "flisp.h"
 #include "equalhash.h"
@@ -100,7 +105,7 @@
     htable_t *h = (htable_t*)cv_data((cvalue_t*)ptr(nt));
     htable_new(h, cnt/2);
     uint32_t i;
-    value_t k=FL_NIL, arg=FL_NIL;
+    value_t k=FL_NIL, arg;
     FOR_ARGS(i,0,arg,args) {
         if (i&1)
             equalhash_put(h, (void*)k, (void*)arg);
--- a/types.c
+++ b/types.c
@@ -47,12 +47,12 @@
             }
             ft->elsz = eltype->size;
             ft->eltype = eltype;
-            ft->init = &cvalue_array_init;
+            ft->init = cvalue_array_init;
             //eltype->artype = ft; -- this is a bad idea since some types carry array sizes
         }
         else if (car_(t) == enumsym) {
             ft->numtype = T_INT32;
-            ft->init = &cvalue_enum_init;
+            ft->init = cvalue_enum_init;
         }
     }
     *bp = ft;